From be7c760fb513d18fa2c6fad3c89c06f2f3894d93 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 2 Feb 2012 16:13:47 +0200 Subject: [PATCH 001/406] Enable basic gesture support for WEC7. This commit adds basic gesture support to WEC7 Qt builds, which enables developer to create custom gesture recognizers based on mouse events. Note that QTouchEvents are not yet generated in WEC7 Qt builds, so recognizers based on those cannot be created. Task-number: QTBUG-22517 Change-Id: Ic6218500b28b78ca8edec3edebd00d84c308a182 Reviewed-by: Joerg Bornemann --- mkspecs/wince70embedded-armv4i-msvc2008/qmake.conf | 2 +- mkspecs/wince70embedded-x86-msvc2008/qmake.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/wince70embedded-armv4i-msvc2008/qmake.conf b/mkspecs/wince70embedded-armv4i-msvc2008/qmake.conf index 1cda0cf32f6..c9ca7188126 100644 --- a/mkspecs/wince70embedded-armv4i-msvc2008/qmake.conf +++ b/mkspecs/wince70embedded-armv4i-msvc2008/qmake.conf @@ -8,7 +8,7 @@ include(../common/wince/qmake.conf) CE_SDK = WEC7_SDK_NAME # replace with actual SDK name CE_ARCH = armv4i -DEFINES += QT_NO_GESTURES QT_NOSTANDARDSHELL_UI_MODEL _CRT_SECURE_NO_DEPRECATE _WIN32_WCE=0x700 $$CE_ARCH _AMRV7_ armv7 _ARM_ +DEFINES += QT_NO_NATIVE_GESTURES QT_NOSTANDARDSHELL_UI_MODEL _CRT_SECURE_NO_DEPRECATE _WIN32_WCE=0x700 $$CE_ARCH _AMRV7_ armv7 _ARM_ QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:WINDOWSCE,7.00 /MACHINE:THUMB /ENTRY:mainACRTStartup QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWSCE,7.00 /MACHINE:THUMB diff --git a/mkspecs/wince70embedded-x86-msvc2008/qmake.conf b/mkspecs/wince70embedded-x86-msvc2008/qmake.conf index febd1835214..89d912a3476 100644 --- a/mkspecs/wince70embedded-x86-msvc2008/qmake.conf +++ b/mkspecs/wince70embedded-x86-msvc2008/qmake.conf @@ -7,7 +7,7 @@ include(../common/wince/qmake.conf) CE_SDK = Platform Builder CE_ARCH = _TGTCPU -DEFINES += QT_NO_GESTURES QT_NOSTANDARDSHELL_UI_MODEL _CRT_SECURE_NO_DEPRECATE _WIN32_WCE=0x700 $$CE_ARCH _X86_ _M_IX86 +DEFINES += QT_NO_NATIVE_GESTURES QT_NOSTANDARDSHELL_UI_MODEL _CRT_SECURE_NO_DEPRECATE _WIN32_WCE=0x700 $$CE_ARCH _X86_ _M_IX86 QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:WINDOWSCE,7.00 /MACHINE:X86 /ENTRY:mainACRTStartup QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWSCE,7.00 /MACHINE:X86 From c051d3350e4f227f71921e7db7e52d02525cc8fc Mon Sep 17 00:00:00 2001 From: Rafael Roquetto Date: Wed, 1 Feb 2012 18:09:44 +0100 Subject: [PATCH 002/406] Use available geometry when maximized. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the available geometry as a maximized window would fit on the desktop in the available area (some space is used up by task bar, system menu, etc.) as opposed to the fullscreen geometry which would be the entire screen. Change-Id: Ifa7046c5b13e162727a9b3a54178690c631cc969 Reviewed-by: David Faure Reviewed-by: Andreas Holzammer Reviewed-by: Anselmo L. S. Melo Reviewed-by: Samuel Rødal --- src/widgets/kernel/qwidget_qpa.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp index 289b332a133..c0dbf0497e1 100644 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ b/src/widgets/kernel/qwidget_qpa.cpp @@ -483,7 +483,15 @@ void QWidgetPrivate::hide_sys() void QWidgetPrivate::setMaxWindowState_helper() { - setFullScreenSize_helper(); //### decoration size + Q_Q(QWidget); + + const uint old_state = data.in_set_window_state; + data.in_set_window_state = 1; + + const QRect desktop = qApp->desktop()->availableGeometry(qApp->desktop()->screenNumber(q)); + q->setGeometry(desktop); + + data.in_set_window_state = old_state; } void QWidgetPrivate::setFullScreenSize_helper() From fdf9ee12916651c708dcd63d557e11e36ec7eb4e Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Sat, 21 Jan 2012 20:27:07 +0100 Subject: [PATCH 003/406] Add accessible role Terminal. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Forward ported from Qt 4. This is used to mark the role of VTs, terminal emulators. Needed in order to know about the special editing behavior. In order to make for example KDE's Konsole accessible this is required. reviewed-by: jan-arve sæther (cherry picked from commit 8ca33c6f1643ab5e89699fbf8b80bfaae108b1e5) Change-Id: Ic7beb2ae2ee70f2c526c7ec5bf982bec7ba9feda Reviewed-by: Jan-Arve Sæther --- src/gui/accessible/qaccessible.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index dc74ac18147..202791caca7 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -291,6 +291,7 @@ public: Splitter = 0x0000003E, // Additional Qt roles where enum value does not map directly to MSAA: LayeredPane = 0x0000003F, + Terminal = 0x00000040, UserRole = 0x0000ffff }; From 1d18fd01645e3b9efcd1a2c5dd030a5fc0f5892a Mon Sep 17 00:00:00 2001 From: Jan-Arve Saether Date: Thu, 19 Jan 2012 14:20:54 +0100 Subject: [PATCH 004/406] Remove QAccessible::FocusChild, add focusChild() Also cleanup (reduce) all implementations of navigate() in order to make the final removal of navigate smoother. Change-Id: I2c216db8f5b2e40afcce8f859fc775053adc2fe3 Reviewed-by: Frederik Gladhorn --- src/gui/accessible/qaccessible.cpp | 18 +++++++ src/gui/accessible/qaccessible.h | 4 +- src/gui/accessible/qaccessibleobject.cpp | 25 ++------- src/gui/accessible/qaccessibleobject.h | 2 +- .../accessible/widgets/complexwidgets.cpp | 7 --- src/plugins/accessible/widgets/itemviews.cpp | 52 ------------------- src/plugins/accessible/widgets/itemviews.h | 10 ---- .../accessible/widgets/qaccessiblemenu.cpp | 8 --- .../accessible/widgets/qaccessiblemenu.h | 1 - .../accessible/widgets/qaccessiblewidgets.cpp | 28 ---------- .../accessible/widgets/qaccessiblewidgets.h | 1 - .../windows/qwindowsaccessibility.cpp | 33 ++++-------- src/widgets/accessible/qaccessiblewidget.cpp | 41 +++++---------- src/widgets/accessible/qaccessiblewidget.h | 1 + 14 files changed, 52 insertions(+), 179 deletions(-) diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 8610ef726d4..b45c7e8d845 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -909,6 +909,16 @@ QVector > QAccessibleInterfa return QVector >(); } +/*! + Returns the object that has the keyboard focus. + + The object returned can be any descendant, including itself. +*/ +QAccessibleInterface *QAccessibleInterface::focusChild() const +{ + return 0; +} + /*! \fn QAccessibleInterface *QAccessibleInterface::childAt(int x, int y) const @@ -991,6 +1001,14 @@ QVector > QAccessibleInterfa \sa relationTo(), childCount(), parent(), child() */ +int QAccessibleInterface::navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const +{ + Q_UNUSED(entry); + Q_UNUSED(relation); + *target = 0; + return -1; +} + /*! \fn QString QAccessibleInterface::text(QAccessible::Text t) const diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index 202791caca7..214ec20f9ca 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -307,7 +307,6 @@ public: enum RelationFlag { Unrelated = 0x00000000, - FocusChild = 0x00010000, Label = 0x00020000, Labelled = 0x00040000, Controller = 0x00080000, @@ -382,6 +381,7 @@ public: // relations virtual QAccessible::Relation relationTo(const QAccessibleInterface *other) const; virtual QVector > relations() const; + virtual QAccessibleInterface *focusChild() const; virtual QAccessibleInterface *childAt(int x, int y) const = 0; @@ -390,7 +390,7 @@ public: virtual QAccessibleInterface *child(int index) const = 0; virtual int childCount() const = 0; virtual int indexOfChild(const QAccessibleInterface *) const = 0; - virtual int navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const = 0; + virtual int navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const; // properties and state virtual QString text(QAccessible::Text t) const = 0; diff --git a/src/gui/accessible/qaccessibleobject.cpp b/src/gui/accessible/qaccessibleobject.cpp index b9e0ac388b4..d277f39c431 100644 --- a/src/gui/accessible/qaccessibleobject.cpp +++ b/src/gui/accessible/qaccessibleobject.cpp @@ -237,28 +237,13 @@ QAccessibleInterface *QAccessibleApplication::child(int index) const return 0; } + /*! \reimp */ -int QAccessibleApplication::navigate(QAccessible::RelationFlag relation, int, - QAccessibleInterface **target) const +QAccessibleInterface *QAccessibleApplication::focusChild() const { - if (!target) - return -1; - - *target = 0; - QObject *targetObject = 0; - - switch (relation) { - case QAccessible::FocusChild: - if (QWindow *window = QGuiApplication::activeWindow()) { - *target = window->accessibleRoot(); - return 0; - } - break; - default: - break; - } - *target = QAccessible::queryAccessibleInterface(targetObject); - return *target ? 0 : -1; + if (QWindow *window = QGuiApplication::activeWindow()) + return window->accessibleRoot(); + return 0; } /*! \reimp */ diff --git a/src/gui/accessible/qaccessibleobject.h b/src/gui/accessible/qaccessibleobject.h index 2372e82f890..d035f17b1db 100644 --- a/src/gui/accessible/qaccessibleobject.h +++ b/src/gui/accessible/qaccessibleobject.h @@ -85,11 +85,11 @@ public: // relations int childCount() const; int indexOfChild(const QAccessibleInterface*) const; + QAccessibleInterface *focusChild() const; // navigation QAccessibleInterface *parent() const; QAccessibleInterface *child(int index) const; - int navigate(QAccessible::RelationFlag, int, QAccessibleInterface **) const; // properties and state QString text(QAccessible::Text t) const; diff --git a/src/plugins/accessible/widgets/complexwidgets.cpp b/src/plugins/accessible/widgets/complexwidgets.cpp index 50e0cd7b655..e4b10670ae2 100644 --- a/src/plugins/accessible/widgets/complexwidgets.cpp +++ b/src/plugins/accessible/widgets/complexwidgets.cpp @@ -122,13 +122,6 @@ public: return QAccessible::queryAccessibleInterface(m_parent); } QAccessibleInterface *child(int) const { return 0; } - int navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const - { - Q_UNUSED(relation); - Q_UNUSED(index); - Q_UNUSED(iface); - return -1; - } // action interface QStringList actionNames() const { diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp index a85c79918f7..a9f3a858d24 100644 --- a/src/plugins/accessible/widgets/itemviews.cpp +++ b/src/plugins/accessible/widgets/itemviews.cpp @@ -442,14 +442,6 @@ QAccessibleInterface *QAccessibleTable::child(int index) const return childFromLogical(index + 1); } -int QAccessibleTable::navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const -{ - Q_UNUSED(relation); - Q_UNUSED(index); - *iface = 0; - return -1; -} - void *QAccessibleTable::interface_cast(QAccessible::InterfaceType t) { if (t == QAccessible::TableInterface) @@ -780,41 +772,6 @@ QAccessibleInterface *QAccessibleTableCell::child(int) const return 0; } -int QAccessibleTableCell::navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const -{ - Q_UNUSED(index); - Q_UNUSED(relation); - -// switch (relation) { -// From table1 implementation: -// case Up: -// case Down: -// case Left: -// case Right: { -// // This is in the "not so nice" category. In order to find out which item -// // is geometrically around, we have to set the current index, navigate -// // and restore the index as well as the old selection -// view->setUpdatesEnabled(false); -// const QModelIndex oldIdx = view->currentIndex(); -// QList kids = children(); -// const QModelIndex currentIndex = index ? kids.at(index - 1) : QModelIndex(row); -// const QItemSelection oldSelection = view->selectionModel()->selection(); -// view->setCurrentIndex(currentIndex); -// const QModelIndex idx = view->moveCursor(toCursorAction(relation), Qt::NoModifier); -// view->setCurrentIndex(oldIdx); -// view->selectionModel()->select(oldSelection, QItemSelectionModel::ClearAndSelect); -// view->setUpdatesEnabled(true); -// if (!idx.isValid()) -// return -1; - -// if (idx.parent() != row.parent() || idx.row() != row.row()) -// *iface = cell(idx); -// return index ? kids.indexOf(idx) + 1 : 0; } -// } - *iface = 0; - return -1; -} - QAccessibleTableHeaderCell::QAccessibleTableHeaderCell(QAbstractItemView *view_, int index_, Qt::Orientation orientation_) : view(view_), index(index_), orientation(orientation_) { @@ -905,15 +862,6 @@ QAccessibleInterface *QAccessibleTableHeaderCell::child(int) const return 0; } -int QAccessibleTableHeaderCell::navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const -{ - Q_UNUSED(relation); - Q_UNUSED(index); - Q_UNUSED(iface); - - return -1; -} - #endif // QT_NO_ITEMVIEWS QT_END_NAMESPACE diff --git a/src/plugins/accessible/widgets/itemviews.h b/src/plugins/accessible/widgets/itemviews.h index 35a9f83a9e5..3d852a23773 100644 --- a/src/plugins/accessible/widgets/itemviews.h +++ b/src/plugins/accessible/widgets/itemviews.h @@ -77,7 +77,6 @@ public: QAccessibleInterface *parent() const; QAccessibleInterface *child(int index) const; - int navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const; void *interface_cast(QAccessible::InterfaceType t); @@ -190,7 +189,6 @@ public: QAccessibleInterface *parent() const; QAccessibleInterface *child(int) const; - int navigate(QAccessible::RelationFlag relation, int m_index, QAccessibleInterface **iface) const; // cell interface virtual int columnExtent() const; @@ -236,7 +234,6 @@ public: QAccessibleInterface *parent() const; QAccessibleInterface *child(int index) const; - int navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const; private: QAbstractItemView *view; @@ -276,13 +273,6 @@ public: QAccessibleInterface *child(int) const { return 0; } - int navigate(QAccessible::RelationFlag relation, int, QAccessibleInterface **iface) const - { - Q_UNUSED(relation); - Q_UNUSED(iface); - return -1; - } - private: QAbstractItemView *view; }; diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.cpp b/src/plugins/accessible/widgets/qaccessiblemenu.cpp index 49cf550b76a..d3ca1629bd0 100644 --- a/src/plugins/accessible/widgets/qaccessiblemenu.cpp +++ b/src/plugins/accessible/widgets/qaccessiblemenu.cpp @@ -204,14 +204,6 @@ QAccessibleInterface *QAccessibleMenuItem::child(int index) const return 0; } -int QAccessibleMenuItem::navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const -{ - Q_UNUSED(relation); - Q_UNUSED(entry); - *target = 0; - return -1; -} - void *QAccessibleMenuItem::interface_cast(QAccessible::InterfaceType t) { if (t == QAccessible::ActionInterface) diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.h b/src/plugins/accessible/widgets/qaccessiblemenu.h index e926dc708ad..af934e2de75 100644 --- a/src/plugins/accessible/widgets/qaccessiblemenu.h +++ b/src/plugins/accessible/widgets/qaccessiblemenu.h @@ -103,7 +103,6 @@ public: QAccessibleInterface *parent() const; QAccessibleInterface *child(int index) const; - int navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface ** target) const; QObject * object() const; QRect rect() const; QAccessible::Role role() const; diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp index 12a415a5b1f..94101efa670 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp @@ -965,34 +965,6 @@ QAccessibleInterface *QAccessibleTitleBar::child(int index) const return 0; } -int QAccessibleTitleBar::navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **iface) const -{ - switch (relation) { - case QAccessible::FocusChild: - // ### - if (entry >= 1) { - QDockWidgetLayout *layout = dockWidgetLayout(); - int index = 1; - int role; - for (role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) { - QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role); - if (!w->isVisible()) - continue; - if (index == entry) - break; - ++index; - } - *iface = 0; - return role > QDockWidgetLayout::FloatButton ? -1 : index; - } - break; - default: - break; - } - *iface = 0; - return -1; -} - int QAccessibleTitleBar::indexOfChild(const QAccessibleInterface * /*child*/) const { return -1; diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.h b/src/plugins/accessible/widgets/qaccessiblewidgets.h index c19f1f49fdc..147ea91a412 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.h +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.h @@ -248,7 +248,6 @@ public: QAccessibleInterface *parent() const; QAccessibleInterface *child(int index) const; - int navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **iface) const; int indexOfChild(const QAccessibleInterface *child) const; int childCount() const; QAccessibleInterface *childAt(int x, int y) const; diff --git a/src/plugins/platforms/windows/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/qwindowsaccessibility.cpp index 2678fd7f23c..8d117454106 100644 --- a/src/plugins/platforms/windows/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/qwindowsaccessibility.cpp @@ -1189,29 +1189,18 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accFocus(VARIANT *pvarID) if (!accessible->isValid()) return E_FAIL; - QAccessibleInterface *acc = 0; - int control = accessible->navigate(QAccessible::FocusChild, 1, &acc); - if (control == -1) { - (*pvarID).vt = VT_EMPTY; - return S_FALSE; + if (QAccessibleInterface *acc = accessible->focusChild()) { + QWindowsAccessible* wacc = new QWindowsAccessible(acc); + IDispatch *iface = 0; + wacc->QueryInterface(IID_IDispatch, (void**)&iface); + if (iface) { + (*pvarID).vt = VT_DISPATCH; + (*pvarID).pdispVal = iface; + return S_OK; + } else { + delete wacc; + } } - if (!acc || control == 0) { - (*pvarID).vt = VT_I4; - (*pvarID).lVal = control ? control : CHILDID_SELF; - return S_OK; - } - - QWindowsAccessible* wacc = new QWindowsAccessible(acc); - IDispatch *iface = 0; - wacc->QueryInterface(IID_IDispatch, (void**)&iface); - if (iface) { - (*pvarID).vt = VT_DISPATCH; - (*pvarID).pdispVal = iface; - return S_OK; - } else { - delete wacc; - } - (*pvarID).vt = VT_EMPTY; return S_FALSE; } diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index a4a86e5d31a..be579fecf87 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -339,10 +339,6 @@ QAccessible::Relation QAccessibleWidget::relationTo(const QAccessibleInterface * if (!o) return relation; - QWidget *focus = widget()->focusWidget(); - if (object() == focus && isAncestor(o, focus)) - relation |= QAccessible::FocusChild; - QACConnectionObject *connectionObject = (QACConnectionObject*)object(); for (int sig = 0; sig < d->primarySignals.count(); ++sig) { if (connectionObject->isSender(o, d->primarySignals.at(sig).toAscii())) { @@ -382,6 +378,20 @@ QAccessibleInterface *QAccessibleWidget::child(int index) const return 0; } +/*! \reimp */ +QAccessibleInterface *QAccessibleWidget::focusChild() const +{ + if (widget()->hasFocus()) + return QAccessible::queryAccessibleInterface(object()); + + QWidget *fw = widget()->focusWidget(); + if (!fw) + return 0; + + if (isAncestor(widget(), fw) || fw == widget()) + return QAccessible::queryAccessibleInterface(fw); +} + /*! \reimp */ int QAccessibleWidget::navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const @@ -394,29 +404,6 @@ int QAccessibleWidget::navigate(QAccessible::RelationFlag relation, int entry, switch (relation) { // Logical - case QAccessible::FocusChild: - { - if (widget()->hasFocus()) { - targetObject = object(); - break; - } - - QWidget *fw = widget()->focusWidget(); - if (!fw) - return -1; - - if (isAncestor(widget(), fw) || fw == widget()) - targetObject = fw; - /* ### - QWidget *parent = fw; - while (parent && !targetObject) { - parent = parent->parentWidget(); - if (parent == widget()) - targetObject = fw; - } - */ - } - break; case QAccessible::Label: if (entry > 0) { QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject()); diff --git a/src/widgets/accessible/qaccessiblewidget.h b/src/widgets/accessible/qaccessiblewidget.h index f96d298f90e..d34d852e277 100644 --- a/src/widgets/accessible/qaccessiblewidget.h +++ b/src/widgets/accessible/qaccessiblewidget.h @@ -62,6 +62,7 @@ public: int childCount() const; int indexOfChild(const QAccessibleInterface *child) const; QAccessible::Relation relationTo(const QAccessibleInterface *other) const; + QAccessibleInterface *focusChild() const; QRect rect() const; From 3282b060d19f73ade5b7370983dbea75c130166b Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 6 Feb 2012 09:38:48 +0100 Subject: [PATCH 005/406] Windows XP style: Fix warnings wrt retrieving HANDLE from 0-window. Exclude invisible top level dialogs for whom a native dialog is being shown from top-level search. Change-Id: Ia94599905457d81d342c14d09ad0b0fc89ec4ab1 Reviewed-by: Friedemann Kleint --- src/widgets/styles/qwindowsxpstyle.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp index 63d275a3914..a24f42c5f1f 100644 --- a/src/widgets/styles/qwindowsxpstyle.cpp +++ b/src/widgets/styles/qwindowsxpstyle.cpp @@ -337,10 +337,11 @@ HWND QWindowsXPStylePrivate::winId(const QWidget *widget) if (const HWND hwnd = QApplicationPrivate::getHWNDForWidget(const_cast(widget))) return hwnd; - const QWidgetList toplevels = QApplication::topLevelWidgets(); - if (!toplevels.isEmpty()) - if (const HWND topLevelHwnd = QApplicationPrivate::getHWNDForWidget(toplevels.front())) - return topLevelHwnd; + // Find top level with native window (there might be dialogs that do not have one). + foreach (const QWidget *toplevel, QApplication::topLevelWidgets()) + if (toplevel->windowHandle()) + if (const HWND topLevelHwnd = QApplicationPrivate::getHWNDForWidget(toplevel)) + return topLevelHwnd; if (QDesktopWidget *desktop = qApp->desktop()) if (const HWND desktopHwnd = QApplicationPrivate::getHWNDForWidget(desktop)) From ba3dc5f3b56d1fab6fe37fe7ae08096d7dc68bcb Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 3 Feb 2012 20:26:24 +0100 Subject: [PATCH 006/406] Move operating system detection from qglobal.h to a separate header qsystemdetection.h is included from qglobal.h, and does all Q_OS_* detection A side-effect of this change is that QT_BEGIN_HEADER and QT_END_HEADER started being defined on Mac OS X, which ends up breaking the build in some cases. Since QT_BEGIN_HEADER and QT_END_HEADER have been defined to nothing in the past, even on Mac OS X, change these 2 to be unconditionally defined to nothing. Change-Id: Ibc8a0aa2207664741c25627d7621e006c2ce80d3 Reviewed-by: Thiago Macieira --- src/corelib/global/global.pri | 1 + src/corelib/global/qglobal.h | 170 +------------------- src/corelib/global/qsystemdetection.h | 222 ++++++++++++++++++++++++++ 3 files changed, 225 insertions(+), 168 deletions(-) create mode 100644 src/corelib/global/qsystemdetection.h diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index fca9969db09..ded3e4db572 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -2,6 +2,7 @@ HEADERS += \ global/qglobal.h \ + global/qsystemdetection.h \ global/qnamespace.h \ global/qendian.h \ global/qnumeric_p.h \ diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index c92336f95c8..6cb3cc2f44f 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -62,6 +62,8 @@ #include #endif +#include + #ifdef __cplusplus #ifndef QT_NO_STL @@ -140,181 +142,13 @@ namespace QT_NAMESPACE {} #endif /* __cplusplus */ -#if defined(Q_OS_MAC) && !defined(Q_CC_INTEL) -#define QT_BEGIN_HEADER extern "C++" { -#define QT_END_HEADER } -#else #define QT_BEGIN_HEADER #define QT_END_HEADER -#endif - -/* - The operating system, must be one of: (Q_OS_x) - - DARWIN - Darwin OS (synonym for Q_OS_MAC) - MSDOS - MS-DOS and Windows - OS2 - OS/2 - OS2EMX - XFree86 on OS/2 (not PM) - WIN32 - Win32 (Windows 2000/XP/Vista/7 and Windows Server 2003/2008) - WINCE - WinCE (Windows CE 5.0) - CYGWIN - Cygwin - SOLARIS - Sun Solaris - HPUX - HP-UX - ULTRIX - DEC Ultrix - LINUX - Linux - FREEBSD - FreeBSD - NETBSD - NetBSD - OPENBSD - OpenBSD - BSDI - BSD/OS - IRIX - SGI Irix - OSF - HP Tru64 UNIX - SCO - SCO OpenServer 5 - UNIXWARE - UnixWare 7, Open UNIX 8 - AIX - AIX - HURD - GNU Hurd - DGUX - DG/UX - RELIANT - Reliant UNIX - DYNIX - DYNIX/ptx - QNX - QNX - QNX6 - QNX RTP 6.1 - LYNX - LynxOS - BSD4 - Any BSD 4.4 system - UNIX - Any UNIX BSD/SYSV system -*/ - -#if defined(__APPLE__) && (defined(__GNUC__) || defined(__xlC__) || defined(__xlc__)) -# define Q_OS_DARWIN -# define Q_OS_BSD4 -# ifdef __LP64__ -# define Q_OS_DARWIN64 -# else -# define Q_OS_DARWIN32 -# endif -#elif defined(__CYGWIN__) -# define Q_OS_CYGWIN -#elif !defined(SAG_COM) && (defined(WIN64) || defined(_WIN64) || defined(__WIN64__)) -# define Q_OS_WIN32 -# define Q_OS_WIN64 -#elif !defined(SAG_COM) && (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)) -# if defined(WINCE) || defined(_WIN32_WCE) -# define Q_OS_WINCE -# else -# define Q_OS_WIN32 -# endif -#elif defined(__sun) || defined(sun) -# define Q_OS_SOLARIS -#elif defined(hpux) || defined(__hpux) -# define Q_OS_HPUX -#elif defined(__ultrix) || defined(ultrix) -# define Q_OS_ULTRIX -#elif defined(sinix) -# define Q_OS_RELIANT -#elif defined(__native_client__) -# define Q_OS_NACL -#elif defined(__linux__) || defined(__linux) -# define Q_OS_LINUX -#elif defined(__FreeBSD__) || defined(__DragonFly__) -# define Q_OS_FREEBSD -# define Q_OS_BSD4 -#elif defined(__NetBSD__) -# define Q_OS_NETBSD -# define Q_OS_BSD4 -#elif defined(__OpenBSD__) -# define Q_OS_OPENBSD -# define Q_OS_BSD4 -#elif defined(__bsdi__) -# define Q_OS_BSDI -# define Q_OS_BSD4 -#elif defined(__sgi) -# define Q_OS_IRIX -#elif defined(__osf__) -# define Q_OS_OSF -#elif defined(_AIX) -# define Q_OS_AIX -#elif defined(__Lynx__) -# define Q_OS_LYNX -#elif defined(__GNU__) -# define Q_OS_HURD -#elif defined(__DGUX__) -# define Q_OS_DGUX -#elif defined(__QNXNTO__) -# define Q_OS_QNX -#elif defined(_SEQUENT_) -# define Q_OS_DYNIX -#elif defined(_SCO_DS) /* SCO OpenServer 5 + GCC */ -# define Q_OS_SCO -#elif defined(__USLC__) /* all SCO platforms + UDK or OUDK */ -# define Q_OS_UNIXWARE -#elif defined(__svr4__) && defined(i386) /* Open UNIX 8 + GCC */ -# define Q_OS_UNIXWARE -#elif defined(__INTEGRITY) -# define Q_OS_INTEGRITY -#elif defined(VXWORKS) /* there is no "real" VxWorks define - this has to be set in the mkspec! */ -# define Q_OS_VXWORKS -#elif defined(__MAKEDEPEND__) -#else -# error "Qt has not been ported to this OS - see http://www.qt-project.org/" -#endif - -#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) || defined(Q_OS_WINCE) -# define Q_OS_WIN -#endif - -#if defined(Q_OS_DARWIN) -# define Q_OS_MAC -# define Q_OS_MACX /* Q_OS_MACX is only for compatibility.*/ -# if defined(Q_OS_DARWIN64) -# define Q_OS_MAC64 -# elif defined(Q_OS_DARWIN32) -# define Q_OS_MAC32 -# endif -#endif - -#if defined(Q_OS_WIN) -# undef Q_OS_UNIX -#elif !defined(Q_OS_UNIX) -# define Q_OS_UNIX -#endif #if defined(Q_OS_DARWIN) && !defined(QT_LARGEFILE_SUPPORT) # define QT_LARGEFILE_SUPPORT 64 #endif -#ifdef Q_OS_DARWIN -# ifdef MAC_OS_X_VERSION_MIN_REQUIRED -# undef MAC_OS_X_VERSION_MIN_REQUIRED -# endif -# define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_4 -# include -# if !defined(MAC_OS_X_VERSION_10_3) -# define MAC_OS_X_VERSION_10_3 MAC_OS_X_VERSION_10_2 + 1 -# endif -# if !defined(MAC_OS_X_VERSION_10_4) -# define MAC_OS_X_VERSION_10_4 MAC_OS_X_VERSION_10_3 + 1 -# endif -# if !defined(MAC_OS_X_VERSION_10_5) -# define MAC_OS_X_VERSION_10_5 MAC_OS_X_VERSION_10_4 + 1 -# endif -# if !defined(MAC_OS_X_VERSION_10_6) -# define MAC_OS_X_VERSION_10_6 MAC_OS_X_VERSION_10_5 + 1 -# endif -# if !defined(MAC_OS_X_VERSION_10_7) -# define MAC_OS_X_VERSION_10_7 MAC_OS_X_VERSION_10_6 + 1 -# endif -# if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_7) -# warning "This version of Mac OS X is unsupported" -# endif -#endif - -#ifdef __LSB_VERSION__ -# if __LSB_VERSION__ < 40 -# error "This version of the Linux Standard Base is unsupported" -# endif -#ifndef QT_LINUXBASE -# define QT_LINUXBASE -#endif -#endif - /* The compiler, must be one of: (Q_CC_x) diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h new file mode 100644 index 00000000000..11df62bcef4 --- /dev/null +++ b/src/corelib/global/qsystemdetection.h @@ -0,0 +1,222 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 QSYSTEMDETECTION_H +#define QSYSTEMDETECTION_H + +#if 0 +// header is automatically included in qglobal.h +#pragma qt_no_master_include + +// silence syncqt warnings (QT_* macros are not yet defined) +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +QT_END_NAMESPACE +QT_END_HEADER + +#pragma qt_sync_stop_processing +#endif + +/* + The operating system, must be one of: (Q_OS_x) + + DARWIN - Darwin OS (synonym for Q_OS_MAC) + MSDOS - MS-DOS and Windows + OS2 - OS/2 + OS2EMX - XFree86 on OS/2 (not PM) + WIN32 - Win32 (Windows 2000/XP/Vista/7 and Windows Server 2003/2008) + WINCE - WinCE (Windows CE 5.0) + CYGWIN - Cygwin + SOLARIS - Sun Solaris + HPUX - HP-UX + ULTRIX - DEC Ultrix + LINUX - Linux + FREEBSD - FreeBSD + NETBSD - NetBSD + OPENBSD - OpenBSD + BSDI - BSD/OS + IRIX - SGI Irix + OSF - HP Tru64 UNIX + SCO - SCO OpenServer 5 + UNIXWARE - UnixWare 7, Open UNIX 8 + AIX - AIX + HURD - GNU Hurd + DGUX - DG/UX + RELIANT - Reliant UNIX + DYNIX - DYNIX/ptx + QNX - QNX + QNX6 - QNX RTP 6.1 + LYNX - LynxOS + BSD4 - Any BSD 4.4 system + UNIX - Any UNIX BSD/SYSV system +*/ + +#if defined(__APPLE__) && (defined(__GNUC__) || defined(__xlC__) || defined(__xlc__)) +# define Q_OS_DARWIN +# define Q_OS_BSD4 +# ifdef __LP64__ +# define Q_OS_DARWIN64 +# else +# define Q_OS_DARWIN32 +# endif +#elif defined(__CYGWIN__) +# define Q_OS_CYGWIN +#elif !defined(SAG_COM) && (defined(WIN64) || defined(_WIN64) || defined(__WIN64__)) +# define Q_OS_WIN32 +# define Q_OS_WIN64 +#elif !defined(SAG_COM) && (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)) +# if defined(WINCE) || defined(_WIN32_WCE) +# define Q_OS_WINCE +# else +# define Q_OS_WIN32 +# endif +#elif defined(__sun) || defined(sun) +# define Q_OS_SOLARIS +#elif defined(hpux) || defined(__hpux) +# define Q_OS_HPUX +#elif defined(__ultrix) || defined(ultrix) +# define Q_OS_ULTRIX +#elif defined(sinix) +# define Q_OS_RELIANT +#elif defined(__native_client__) +# define Q_OS_NACL +#elif defined(__linux__) || defined(__linux) +# define Q_OS_LINUX +#elif defined(__FreeBSD__) || defined(__DragonFly__) +# define Q_OS_FREEBSD +# define Q_OS_BSD4 +#elif defined(__NetBSD__) +# define Q_OS_NETBSD +# define Q_OS_BSD4 +#elif defined(__OpenBSD__) +# define Q_OS_OPENBSD +# define Q_OS_BSD4 +#elif defined(__bsdi__) +# define Q_OS_BSDI +# define Q_OS_BSD4 +#elif defined(__sgi) +# define Q_OS_IRIX +#elif defined(__osf__) +# define Q_OS_OSF +#elif defined(_AIX) +# define Q_OS_AIX +#elif defined(__Lynx__) +# define Q_OS_LYNX +#elif defined(__GNU__) +# define Q_OS_HURD +#elif defined(__DGUX__) +# define Q_OS_DGUX +#elif defined(__QNXNTO__) +# define Q_OS_QNX +#elif defined(_SEQUENT_) +# define Q_OS_DYNIX +#elif defined(_SCO_DS) /* SCO OpenServer 5 + GCC */ +# define Q_OS_SCO +#elif defined(__USLC__) /* all SCO platforms + UDK or OUDK */ +# define Q_OS_UNIXWARE +#elif defined(__svr4__) && defined(i386) /* Open UNIX 8 + GCC */ +# define Q_OS_UNIXWARE +#elif defined(__INTEGRITY) +# define Q_OS_INTEGRITY +#elif defined(VXWORKS) /* there is no "real" VxWorks define - this has to be set in the mkspec! */ +# define Q_OS_VXWORKS +#elif defined(__MAKEDEPEND__) +#else +# error "Qt has not been ported to this OS - see http://www.qt-project.org/" +#endif + +#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) || defined(Q_OS_WINCE) +# define Q_OS_WIN +#endif + +#if defined(Q_OS_DARWIN) +# define Q_OS_MAC +# define Q_OS_MACX /* Q_OS_MACX is only for compatibility.*/ +# if defined(Q_OS_DARWIN64) +# define Q_OS_MAC64 +# elif defined(Q_OS_DARWIN32) +# define Q_OS_MAC32 +# endif +#endif + +#if defined(Q_OS_WIN) +# undef Q_OS_UNIX +#elif !defined(Q_OS_UNIX) +# define Q_OS_UNIX +#endif + +#ifdef Q_OS_DARWIN +# ifdef MAC_OS_X_VERSION_MIN_REQUIRED +# undef MAC_OS_X_VERSION_MIN_REQUIRED +# endif +# define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_4 +# include +# if !defined(MAC_OS_X_VERSION_10_3) +# define MAC_OS_X_VERSION_10_3 MAC_OS_X_VERSION_10_2 + 1 +# endif +# if !defined(MAC_OS_X_VERSION_10_4) +# define MAC_OS_X_VERSION_10_4 MAC_OS_X_VERSION_10_3 + 1 +# endif +# if !defined(MAC_OS_X_VERSION_10_5) +# define MAC_OS_X_VERSION_10_5 MAC_OS_X_VERSION_10_4 + 1 +# endif +# if !defined(MAC_OS_X_VERSION_10_6) +# define MAC_OS_X_VERSION_10_6 MAC_OS_X_VERSION_10_5 + 1 +# endif +# if !defined(MAC_OS_X_VERSION_10_7) +# define MAC_OS_X_VERSION_10_7 MAC_OS_X_VERSION_10_6 + 1 +# endif +# if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_7) +# warning "This version of Mac OS X is unsupported" +# endif +#endif + +#ifdef __LSB_VERSION__ +# if __LSB_VERSION__ < 40 +# error "This version of the Linux Standard Base is unsupported" +# endif +#ifndef QT_LINUXBASE +# define QT_LINUXBASE +#endif +#endif + +#endif // QSYSTEMDETECTION_H From 475cef58f96d1d274e5c7b448df7231415783af0 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Sat, 4 Feb 2012 14:20:32 +0100 Subject: [PATCH 007/406] Move compiler detection from qglobal.h to a separate header qcompilerdetection.h is included from qglobal.h, and does all Q_CC_* and compiler feature detection. Change-Id: Idd06054e172ef6fa73774e26fa38753996c4161b Reviewed-by: Thiago Macieira --- src/corelib/global/global.pri | 1 + src/corelib/global/qcompilerdetection.h | 551 ++++++++++++++++++++++++ src/corelib/global/qglobal.h | 493 +-------------------- 3 files changed, 553 insertions(+), 492 deletions(-) create mode 100644 src/corelib/global/qcompilerdetection.h diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index ded3e4db572..e00917c805f 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -3,6 +3,7 @@ HEADERS += \ global/qglobal.h \ global/qsystemdetection.h \ + global/qcompilerdetection.h \ global/qnamespace.h \ global/qendian.h \ global/qnumeric_p.h \ diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h new file mode 100644 index 00000000000..7621b76f545 --- /dev/null +++ b/src/corelib/global/qcompilerdetection.h @@ -0,0 +1,551 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 QCOMPILERDETECTION_H +#define QCOMPILERDETECTION_H + +#if 0 +// header is automatically included in qglobal.h +#pragma qt_no_master_include + +// silence syncqt warnings (QT_* macros are not yet defined) +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +QT_END_NAMESPACE +QT_END_HEADER + +#pragma qt_sync_stop_processing +#endif + +/* + The compiler, must be one of: (Q_CC_x) + + SYM - Digital Mars C/C++ (used to be Symantec C++) + MSVC - Microsoft Visual C/C++, Intel C++ for Windows + BOR - Borland/Turbo C++ + WAT - Watcom C++ + GNU - GNU C++ + COMEAU - Comeau C++ + EDG - Edison Design Group C++ + OC - CenterLine C++ + SUN - Forte Developer, or Sun Studio C++ + MIPS - MIPSpro C++ + DEC - DEC C++ + HPACC - HP aC++ + USLC - SCO OUDK and UDK + CDS - Reliant C++ + KAI - KAI C++ + INTEL - Intel C++ for Linux, Intel C++ for Windows + HIGHC - MetaWare High C/C++ + PGI - Portland Group C++ + GHS - Green Hills Optimizing C++ Compilers + RVCT - ARM Realview Compiler Suite + CLANG - C++ front-end for the LLVM compiler + + + Should be sorted most to least authoritative. +*/ + +/* Symantec C++ is now Digital Mars */ +#if defined(__DMC__) || defined(__SC__) +# define Q_CC_SYM +/* "explicit" semantics implemented in 8.1e but keyword recognized since 7.5 */ +# if defined(__SC__) && __SC__ < 0x750 +# define Q_NO_EXPLICIT_KEYWORD +# endif +# define Q_NO_USING_KEYWORD + +#elif defined(_MSC_VER) +# define Q_CC_MSVC +# define Q_CC_MSVC_NET +# define Q_CANNOT_DELETE_CONSTANT +# define Q_OUTOFLINE_TEMPLATE inline +# define Q_NO_TEMPLATE_FRIENDS +# define Q_ALIGNOF(type) __alignof(type) +# define Q_DECL_ALIGN(n) __declspec(align(n)) +/* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */ +# if defined(__INTEL_COMPILER) +# define Q_CC_INTEL +# endif +/* MSVC does not support SSE/MMX on x64 */ +# if (defined(Q_CC_MSVC) && defined(_M_X64)) +# undef QT_HAVE_SSE +# undef QT_HAVE_MMX +# undef QT_HAVE_3DNOW +# endif + +#if defined(Q_CC_MSVC) && _MSC_VER >= 1600 +# define Q_COMPILER_RVALUE_REFS +# define Q_COMPILER_AUTO_TYPE +# define Q_COMPILER_LAMBDA +# define Q_COMPILER_DECLTYPE +# define Q_COMPILER_STATIC_ASSERT +// MSCV has std::initilizer_list, but do not support the braces initialization +//# define Q_COMPILER_INITIALIZER_LISTS +# endif + + +#elif defined(__BORLANDC__) || defined(__TURBOC__) +# define Q_CC_BOR +# define Q_INLINE_TEMPLATE +# if __BORLANDC__ < 0x502 +# define Q_NO_BOOL_TYPE +# define Q_NO_EXPLICIT_KEYWORD +# endif +# define Q_NO_USING_KEYWORD + +#elif defined(__WATCOMC__) +# define Q_CC_WAT + +/* ARM Realview Compiler Suite + RVCT compiler also defines __EDG__ and __GNUC__ (if --gnu flag is given), + so check for it before that */ +#elif defined(__ARMCC__) || defined(__CC_ARM) +# define Q_CC_RVCT +# if __TARGET_ARCH_ARM >= 6 +# define QT_HAVE_ARMV6 +# endif +/* work-around for missing compiler intrinsics */ +# define __is_empty(X) false +# define __is_pod(X) false +#elif defined(__GNUC__) +# define Q_CC_GNU +# define Q_C_CALLBACKS +# if defined(__MINGW32__) +# define Q_CC_MINGW +# endif +# if defined(__INTEL_COMPILER) +/* Intel C++ also masquerades as GCC 3.2.0 */ +# define Q_CC_INTEL +# endif +# if defined(__clang__) +/* Clang also masquerades as GCC 4.2.1 */ +# define Q_CC_CLANG +# endif +# ifdef __APPLE__ +# define Q_NO_DEPRECATED_CONSTRUCTORS +# endif +# if __GNUC__ == 2 && __GNUC_MINOR__ <= 7 +# define Q_FULL_TEMPLATE_INSTANTIATION +# endif +/* GCC 2.95 knows "using" but does not support it correctly */ +# if __GNUC__ == 2 && __GNUC_MINOR__ <= 95 +# define Q_NO_USING_KEYWORD +# endif +# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +# define Q_ALIGNOF(type) __alignof__(type) +# define Q_TYPEOF(expr) __typeof__(expr) +# define Q_DECL_ALIGN(n) __attribute__((__aligned__(n))) +# endif +# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) +# define Q_LIKELY(expr) __builtin_expect(!!(expr), true) +# define Q_UNLIKELY(expr) __builtin_expect(!!(expr), false) +# endif +/* GCC 3.1 and GCC 3.2 wrongly define _SB_CTYPE_MACROS on HP-UX */ +# if defined(Q_OS_HPUX) && __GNUC__ == 3 && __GNUC_MINOR__ >= 1 +# define Q_WRONG_SB_CTYPE_MACROS +# endif +/* GCC <= 3.3 cannot handle template friends */ +# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ <= 3) +# define Q_NO_TEMPLATE_FRIENDS +# endif +/* Apple's GCC 3.1 chokes on our streaming qDebug() */ +# if defined(Q_OS_DARWIN) && __GNUC__ == 3 && (__GNUC_MINOR__ >= 1 && __GNUC_MINOR__ < 3) +# define Q_BROKEN_DEBUG_STREAM +# endif +# if (defined(Q_CC_GNU) || defined(Q_CC_INTEL)) && !defined(QT_MOC_CPP) +# define Q_PACKED __attribute__ ((__packed__)) +# define Q_NO_PACKED_REFERENCE +# ifndef __ARM_EABI__ +# define QT_NO_ARM_EABI +# endif +# endif +# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403 +# define Q_ALLOC_SIZE(x) __attribute__((alloc_size(x))) +# endif +# if defined(__GXX_EXPERIMENTAL_CXX0X__) && !defined(__clang__) /* clang C++11 enablers are found below, don't do them here */ +# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403 + /* C++0x features supported in GCC 4.3: */ +# define Q_COMPILER_VARIADIC_MACROS +# define Q_COMPILER_RVALUE_REFS +# define Q_COMPILER_DECLTYPE +# define Q_COMPILER_STATIC_ASSERT +# endif +# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 + /* C++0x features supported in GCC 4.4: */ +# define Q_COMPILER_UNICODE_STRINGS +# define Q_COMPILER_VARIADIC_TEMPLATES +# define Q_COMPILER_AUTO_TYPE +# define Q_COMPILER_EXTERN_TEMPLATES +# define Q_COMPILER_DEFAULT_DELETE_MEMBERS +# define Q_COMPILER_CLASS_ENUM +# define Q_COMPILER_INITIALIZER_LISTS +# define Q_COMPILER_ATOMICS +# endif +# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405 + /* C++0x features supported in GCC 4.5: */ +# define Q_COMPILER_LAMBDA +# endif +# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 + /* C++0x features supported in GCC 4.6: */ +# define Q_COMPILER_NULLPTR +# define Q_COMPILER_CONSTEXPR +# define Q_COMPILER_UNRESTRICTED_UNIONS +# define Q_COMPILER_RANGE_FOR +# endif +# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 + /* C++0x features supported in GCC 4.7: */ +# define Q_COMPILER_EXPLICIT_OVERRIDES +# endif + +# endif + +/* IBM compiler versions are a bit messy. There are actually two products: + the C product, and the C++ product. The C++ compiler is always packaged + with the latest version of the C compiler. Version numbers do not always + match. This little table (I'm not sure it's accurate) should be helpful: + + C++ product C product + + C Set 3.1 C Compiler 3.0 + ... ... + C++ Compiler 3.6.6 C Compiler 4.3 + ... ... + Visual Age C++ 4.0 ... + ... ... + Visual Age C++ 5.0 C Compiler 5.0 + ... ... + Visual Age C++ 6.0 C Compiler 6.0 + + Now: + __xlC__ is the version of the C compiler in hexadecimal notation + is only an approximation of the C++ compiler version + __IBMCPP__ is the version of the C++ compiler in decimal notation + but it is not defined on older compilers like C Set 3.1 */ +#elif defined(__xlC__) +# define Q_CC_XLC +# define Q_FULL_TEMPLATE_INSTANTIATION +# if __xlC__ < 0x400 +# define Q_NO_BOOL_TYPE +# define Q_NO_EXPLICIT_KEYWORD +# define Q_NO_USING_KEYWORD +# define Q_OUTOFLINE_TEMPLATE inline +# define Q_BROKEN_TEMPLATE_SPECIALIZATION +# define Q_CANNOT_DELETE_CONSTANT +# elif __xlC__ >= 0x0600 +# define Q_ALIGNOF(type) __alignof__(type) +# define Q_TYPEOF(expr) __typeof__(expr) +# define Q_DECL_ALIGN(n) __attribute__((__aligned__(n))) +# define Q_PACKED __attribute__((__packed__)) +# endif + +/* Older versions of DEC C++ do not define __EDG__ or __EDG - observed + on DEC C++ V5.5-004. New versions do define __EDG__ - observed on + Compaq C++ V6.3-002. + This compiler is different enough from other EDG compilers to handle + it separately anyway. */ +#elif defined(__DECCXX) || defined(__DECC) +# define Q_CC_DEC +/* Compaq C++ V6 compilers are EDG-based but I'm not sure about older + DEC C++ V5 compilers. */ +# if defined(__EDG__) +# define Q_CC_EDG +# endif +/* Compaq have disabled EDG's _BOOL macro and use _BOOL_EXISTS instead + - observed on Compaq C++ V6.3-002. + In any case versions prior to Compaq C++ V6.0-005 do not have bool. */ +# if !defined(_BOOL_EXISTS) +# define Q_NO_BOOL_TYPE +# endif +/* Spurious (?) error messages observed on Compaq C++ V6.5-014. */ +# define Q_NO_USING_KEYWORD +/* Apply to all versions prior to Compaq C++ V6.0-000 - observed on + DEC C++ V5.5-004. */ +# if __DECCXX_VER < 60060000 +# define Q_BROKEN_TEMPLATE_SPECIALIZATION +# define Q_CANNOT_DELETE_CONSTANT +# endif +/* avoid undefined symbol problems with out-of-line template members */ +# define Q_OUTOFLINE_TEMPLATE inline + +/* The Portland Group C++ compiler is based on EDG and does define __EDG__ + but the C compiler does not */ +#elif defined(__PGI) +# define Q_CC_PGI +# if defined(__EDG__) +# define Q_CC_EDG +# endif + +/* Compilers with EDG front end are similar. To detect them we test: + __EDG documented by SGI, observed on MIPSpro 7.3.1.1 and KAI C++ 4.0b + __EDG__ documented in EDG online docs, observed on Compaq C++ V6.3-002 + and PGI C++ 5.2-4 */ +#elif !defined(Q_OS_HPUX) && (defined(__EDG) || defined(__EDG__)) +# define Q_CC_EDG +/* From the EDG documentation (does not seem to apply to Compaq C++): + _BOOL + Defined in C++ mode when bool is a keyword. The name of this + predefined macro is specified by a configuration flag. _BOOL + is the default. + __BOOL_DEFINED + Defined in Microsoft C++ mode when bool is a keyword. */ +# if !defined(_BOOL) && !defined(__BOOL_DEFINED) +# define Q_NO_BOOL_TYPE +# endif + +/* The Comeau compiler is based on EDG and does define __EDG__ */ +# if defined(__COMO__) +# define Q_CC_COMEAU +# define Q_C_CALLBACKS + +/* The `using' keyword was introduced to avoid KAI C++ warnings + but it's now causing KAI C++ errors instead. The standard is + unclear about the use of this keyword, and in practice every + compiler is using its own set of rules. Forget it. */ +# elif defined(__KCC) +# define Q_CC_KAI +# define Q_NO_USING_KEYWORD + +/* Using the `using' keyword avoids Intel C++ for Linux warnings */ +# elif defined(__INTEL_COMPILER) +# define Q_CC_INTEL + +/* Uses CFront, make sure to read the manual how to tweak templates. */ +# elif defined(__ghs) +# define Q_CC_GHS + +# elif defined(__DCC__) +# define Q_CC_DIAB +# undef Q_NO_BOOL_TYPE +# if !defined(__bool) +# define Q_NO_BOOL_TYPE +# endif + +/* The UnixWare 7 UDK compiler is based on EDG and does define __EDG__ */ +# elif defined(__USLC__) && defined(__SCO_VERSION__) +# define Q_CC_USLC +/* The latest UDK 7.1.1b does not need this, but previous versions do */ +# if !defined(__SCO_VERSION__) || (__SCO_VERSION__ < 302200010) +# define Q_OUTOFLINE_TEMPLATE inline +# endif +# define Q_NO_USING_KEYWORD /* ### check "using" status */ + +/* Never tested! */ +# elif defined(CENTERLINE_CLPP) || defined(OBJECTCENTER) +# define Q_CC_OC +# define Q_NO_USING_KEYWORD + +/* CDS++ defines __EDG__ although this is not documented in the Reliant + documentation. It also follows conventions like _BOOL and this documented */ +# elif defined(sinix) +# define Q_CC_CDS +# define Q_NO_USING_KEYWORD + +/* The MIPSpro compiler defines __EDG */ +# elif defined(__sgi) +# define Q_CC_MIPS +# define Q_NO_USING_KEYWORD /* ### check "using" status */ +# define Q_NO_TEMPLATE_FRIENDS +# if defined(_COMPILER_VERSION) && (_COMPILER_VERSION >= 740) +# define Q_OUTOFLINE_TEMPLATE inline +# pragma set woff 3624,3625,3649 /* turn off some harmless warnings */ +# endif +# endif + +/* VxWorks' DIAB toolchain has an additional EDG type C++ compiler + (see __DCC__ above). This one is for C mode files (__EDG is not defined) */ +#elif defined(_DIAB_TOOL) +# define Q_CC_DIAB + +/* Never tested! */ +#elif defined(__HIGHC__) +# define Q_CC_HIGHC + +#elif defined(__SUNPRO_CC) || defined(__SUNPRO_C) +# define Q_CC_SUN +/* 5.0 compiler or better + 'bool' is enabled by default but can be disabled using -features=nobool + in which case _BOOL is not defined + this is the default in 4.2 compatibility mode triggered by -compat=4 */ +# if __SUNPRO_CC >= 0x500 +# define QT_NO_TEMPLATE_TEMPLATE_PARAMETERS + /* see http://developers.sun.com/sunstudio/support/Ccompare.html */ +# if __SUNPRO_CC >= 0x590 +# define Q_ALIGNOF(type) __alignof__(type) +# define Q_TYPEOF(expr) __typeof__(expr) +# define Q_DECL_ALIGN(n) __attribute__((__aligned__(n))) +# endif +# if __SUNPRO_CC >= 0x550 +# define Q_DECL_EXPORT __global +# endif +# if __SUNPRO_CC < 0x5a0 +# define Q_NO_TEMPLATE_FRIENDS +# endif +# if !defined(_BOOL) +# define Q_NO_BOOL_TYPE +# endif +# if defined(__SUNPRO_CC_COMPAT) && (__SUNPRO_CC_COMPAT <= 4) +# define Q_NO_USING_KEYWORD +# endif +# define Q_C_CALLBACKS +/* 4.2 compiler or older */ +# else +# define Q_NO_BOOL_TYPE +# define Q_NO_EXPLICIT_KEYWORD +# define Q_NO_USING_KEYWORD +# endif + +/* CDS++ does not seem to define __EDG__ or __EDG according to Reliant + documentation but nevertheless uses EDG conventions like _BOOL */ +#elif defined(sinix) +# define Q_CC_EDG +# define Q_CC_CDS +# if !defined(_BOOL) +# define Q_NO_BOOL_TYPE +# endif +# define Q_BROKEN_TEMPLATE_SPECIALIZATION + +#elif defined(Q_OS_HPUX) +/* __HP_aCC was not defined in first aCC releases */ +# if defined(__HP_aCC) || __cplusplus >= 199707L +# define Q_NO_TEMPLATE_FRIENDS +# define Q_CC_HPACC +# if __HP_aCC-0 < 060000 +# define QT_NO_TEMPLATE_TEMPLATE_PARAMETERS +# define Q_DECL_EXPORT __declspec(dllexport) +# define Q_DECL_IMPORT __declspec(dllimport) +# endif +# if __HP_aCC-0 >= 061200 +# define Q_DECL_ALIGN(n) __attribute__((aligned(n))) +# endif +# if __HP_aCC-0 >= 062000 +# define Q_DECL_EXPORT __attribute__((visibility("default"))) +# define Q_DECL_HIDDEN __attribute__((visibility("hidden"))) +# define Q_DECL_IMPORT Q_DECL_EXPORT +# endif +# else +# define Q_CC_HP +# define Q_NO_BOOL_TYPE +# define Q_FULL_TEMPLATE_INSTANTIATION +# define Q_BROKEN_TEMPLATE_SPECIALIZATION +# define Q_NO_EXPLICIT_KEYWORD +# endif +# define Q_NO_USING_KEYWORD /* ### check "using" status */ + +#else +# error "Qt has not been tested with this compiler - see http://www.qt-project.org/" +#endif + + +#ifdef Q_CC_INTEL +# if __INTEL_COMPILER < 1200 +# define Q_NO_TEMPLATE_FRIENDS +# endif +# if defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__GXX_EXPERIMENTAL_CPP0X__) +# if __INTEL_COMPILER >= 1200 +# define Q_COMPILER_RVALUE_REFS +# define Q_COMPILER_EXTERN_TEMPLATES +# define Q_COMPILER_DECLTYPE +# define Q_COMPILER_VARIADIC_TEMPLATES +# define Q_COMPILER_AUTO_TYPE +# define Q_COMPILER_DEFAULT_DELETE_MEMBERS +# define Q_COMPILER_CLASS_ENUM +# define Q_COMPILER_LAMBDA +# define Q_COMPILER_STATIC_ASSERT +# endif +# endif +#endif + +#ifdef Q_CC_CLANG +/* General C++ features */ +# if !__has_feature(cxx_exceptions) +# define QT_NO_EXCEPTIONS +# endif +# if !__has_feature(cxx_rtti) +# define QT_NO_RTTI +# endif +/* C++11 features, see http://clang.llvm.org/cxx_status.html */ +# if __cplusplus >= 201103L || __GXX_EXPERIMENTAL_CXX0X__ +# if ((__clang_major__ * 100) + __clang_minor__) >= 209 /* since clang 2.9 */ +# define Q_COMPILER_AUTO_TYPE +# define Q_COMPILER_DECLTYPE +# define Q_COMPILER_EXTERN_TEMPLATES +# define Q_COMPILER_RVALUE_REFS +# define Q_COMPILER_STATIC_ASSERT +# define Q_COMPILER_VARIADIC_MACROS +# define Q_COMPILER_VARIADIC_TEMPLATES +# endif +# if ((__clang_major__ * 100) + __clang_minor__) >= 300 /* since clang 3.0 */ +# define Q_COMPILER_CLASS_ENUM + /* defaulted members in 3.0, deleted members in 2.9 */ +# define Q_COMPILER_DEFAULT_DELETE_MEMBERS +# define Q_COMPILER_EXPLICIT_OVERRIDES +# define Q_COMPILER_NULLPTR +# define Q_COMPILER_RANGE_FOR +# define Q_COMPILER_UNICODE_STRINGS +# endif + /* not implemented in clang yet */ +# if __has_feature(cxx_constexpr) +# define Q_COMPILER_CONSTEXPR +# endif +# if __has_feature(cxx_lambdas) +# define Q_COMPILER_LAMBDA +# endif +# if __has_feature(cxx_generalized_initializers) +# define Q_COMPILER_INITIALIZER_LISTS +# endif +# if __has_feature(cxx_unrestricted_unions) +# define Q_COMPILER_UNRESTRICTED_UNIONS +# endif +# if 0 +# define Q_COMPILER_ATOMICS +# endif +# endif +#endif // Q_CC_CLANG + +#ifndef Q_COMPILER_MANGLES_RETURN_TYPE +# if defined(Q_CC_MSVC) +# define Q_COMPILER_MANGLES_RETURN_TYPE +# endif +#endif + +#endif // QCOMPILERDETECTION_H diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 6cb3cc2f44f..dea96b297e1 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -63,6 +63,7 @@ #endif #include +#include #ifdef __cplusplus @@ -149,492 +150,6 @@ namespace QT_NAMESPACE {} # define QT_LARGEFILE_SUPPORT 64 #endif -/* - The compiler, must be one of: (Q_CC_x) - - SYM - Digital Mars C/C++ (used to be Symantec C++) - MSVC - Microsoft Visual C/C++, Intel C++ for Windows - BOR - Borland/Turbo C++ - WAT - Watcom C++ - GNU - GNU C++ - COMEAU - Comeau C++ - EDG - Edison Design Group C++ - OC - CenterLine C++ - SUN - Forte Developer, or Sun Studio C++ - MIPS - MIPSpro C++ - DEC - DEC C++ - HPACC - HP aC++ - USLC - SCO OUDK and UDK - CDS - Reliant C++ - KAI - KAI C++ - INTEL - Intel C++ for Linux, Intel C++ for Windows - HIGHC - MetaWare High C/C++ - PGI - Portland Group C++ - GHS - Green Hills Optimizing C++ Compilers - RVCT - ARM Realview Compiler Suite - CLANG - C++ front-end for the LLVM compiler - - - Should be sorted most to least authoritative. -*/ - -/* Symantec C++ is now Digital Mars */ -#if defined(__DMC__) || defined(__SC__) -# define Q_CC_SYM -/* "explicit" semantics implemented in 8.1e but keyword recognized since 7.5 */ -# if defined(__SC__) && __SC__ < 0x750 -# define Q_NO_EXPLICIT_KEYWORD -# endif -# define Q_NO_USING_KEYWORD - -#elif defined(_MSC_VER) -# define Q_CC_MSVC -# define Q_CC_MSVC_NET -# define Q_CANNOT_DELETE_CONSTANT -# define Q_OUTOFLINE_TEMPLATE inline -# define Q_NO_TEMPLATE_FRIENDS -# define Q_ALIGNOF(type) __alignof(type) -# define Q_DECL_ALIGN(n) __declspec(align(n)) -/* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */ -# if defined(__INTEL_COMPILER) -# define Q_CC_INTEL -# endif -/* MSVC does not support SSE/MMX on x64 */ -# if (defined(Q_CC_MSVC) && defined(_M_X64)) -# undef QT_HAVE_SSE -# undef QT_HAVE_MMX -# undef QT_HAVE_3DNOW -# endif - -#if defined(Q_CC_MSVC) && _MSC_VER >= 1600 -# define Q_COMPILER_RVALUE_REFS -# define Q_COMPILER_AUTO_TYPE -# define Q_COMPILER_LAMBDA -# define Q_COMPILER_DECLTYPE -# define Q_COMPILER_STATIC_ASSERT -// MSCV has std::initilizer_list, but do not support the braces initialization -//# define Q_COMPILER_INITIALIZER_LISTS -# endif - - -#elif defined(__BORLANDC__) || defined(__TURBOC__) -# define Q_CC_BOR -# define Q_INLINE_TEMPLATE -# if __BORLANDC__ < 0x502 -# define Q_NO_BOOL_TYPE -# define Q_NO_EXPLICIT_KEYWORD -# endif -# define Q_NO_USING_KEYWORD - -#elif defined(__WATCOMC__) -# define Q_CC_WAT - -/* ARM Realview Compiler Suite - RVCT compiler also defines __EDG__ and __GNUC__ (if --gnu flag is given), - so check for it before that */ -#elif defined(__ARMCC__) || defined(__CC_ARM) -# define Q_CC_RVCT -# if __TARGET_ARCH_ARM >= 6 -# define QT_HAVE_ARMV6 -# endif -/* work-around for missing compiler intrinsics */ -# define __is_empty(X) false -# define __is_pod(X) false -#elif defined(__GNUC__) -# define Q_CC_GNU -# define Q_C_CALLBACKS -# if defined(__MINGW32__) -# define Q_CC_MINGW -# endif -# if defined(__INTEL_COMPILER) -/* Intel C++ also masquerades as GCC 3.2.0 */ -# define Q_CC_INTEL -# endif -# if defined(__clang__) -/* Clang also masquerades as GCC 4.2.1 */ -# define Q_CC_CLANG -# endif -# ifdef __APPLE__ -# define Q_NO_DEPRECATED_CONSTRUCTORS -# endif -# if __GNUC__ == 2 && __GNUC_MINOR__ <= 7 -# define Q_FULL_TEMPLATE_INSTANTIATION -# endif -/* GCC 2.95 knows "using" but does not support it correctly */ -# if __GNUC__ == 2 && __GNUC_MINOR__ <= 95 -# define Q_NO_USING_KEYWORD -# endif -# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) -# define Q_ALIGNOF(type) __alignof__(type) -# define Q_TYPEOF(expr) __typeof__(expr) -# define Q_DECL_ALIGN(n) __attribute__((__aligned__(n))) -# endif -# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) -# define Q_LIKELY(expr) __builtin_expect(!!(expr), true) -# define Q_UNLIKELY(expr) __builtin_expect(!!(expr), false) -# endif -/* GCC 3.1 and GCC 3.2 wrongly define _SB_CTYPE_MACROS on HP-UX */ -# if defined(Q_OS_HPUX) && __GNUC__ == 3 && __GNUC_MINOR__ >= 1 -# define Q_WRONG_SB_CTYPE_MACROS -# endif -/* GCC <= 3.3 cannot handle template friends */ -# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ <= 3) -# define Q_NO_TEMPLATE_FRIENDS -# endif -/* Apple's GCC 3.1 chokes on our streaming qDebug() */ -# if defined(Q_OS_DARWIN) && __GNUC__ == 3 && (__GNUC_MINOR__ >= 1 && __GNUC_MINOR__ < 3) -# define Q_BROKEN_DEBUG_STREAM -# endif -# if (defined(Q_CC_GNU) || defined(Q_CC_INTEL)) && !defined(QT_MOC_CPP) -# define Q_PACKED __attribute__ ((__packed__)) -# define Q_NO_PACKED_REFERENCE -# ifndef __ARM_EABI__ -# define QT_NO_ARM_EABI -# endif -# endif -# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403 -# define Q_ALLOC_SIZE(x) __attribute__((alloc_size(x))) -# endif -# if defined(__GXX_EXPERIMENTAL_CXX0X__) && !defined(__clang__) /* clang C++11 enablers are found below, don't do them here */ -# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403 - /* C++0x features supported in GCC 4.3: */ -# define Q_COMPILER_VARIADIC_MACROS -# define Q_COMPILER_RVALUE_REFS -# define Q_COMPILER_DECLTYPE -# define Q_COMPILER_STATIC_ASSERT -# endif -# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 - /* C++0x features supported in GCC 4.4: */ -# define Q_COMPILER_UNICODE_STRINGS -# define Q_COMPILER_VARIADIC_TEMPLATES -# define Q_COMPILER_AUTO_TYPE -# define Q_COMPILER_EXTERN_TEMPLATES -# define Q_COMPILER_DEFAULT_DELETE_MEMBERS -# define Q_COMPILER_CLASS_ENUM -# define Q_COMPILER_INITIALIZER_LISTS -# define Q_COMPILER_ATOMICS -# endif -# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405 - /* C++0x features supported in GCC 4.5: */ -# define Q_COMPILER_LAMBDA -# endif -# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 - /* C++0x features supported in GCC 4.6: */ -# define Q_COMPILER_NULLPTR -# define Q_COMPILER_CONSTEXPR -# define Q_COMPILER_UNRESTRICTED_UNIONS -# define Q_COMPILER_RANGE_FOR -# endif -# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 - /* C++0x features supported in GCC 4.7: */ -# define Q_COMPILER_EXPLICIT_OVERRIDES -# endif - -# endif - -/* IBM compiler versions are a bit messy. There are actually two products: - the C product, and the C++ product. The C++ compiler is always packaged - with the latest version of the C compiler. Version numbers do not always - match. This little table (I'm not sure it's accurate) should be helpful: - - C++ product C product - - C Set 3.1 C Compiler 3.0 - ... ... - C++ Compiler 3.6.6 C Compiler 4.3 - ... ... - Visual Age C++ 4.0 ... - ... ... - Visual Age C++ 5.0 C Compiler 5.0 - ... ... - Visual Age C++ 6.0 C Compiler 6.0 - - Now: - __xlC__ is the version of the C compiler in hexadecimal notation - is only an approximation of the C++ compiler version - __IBMCPP__ is the version of the C++ compiler in decimal notation - but it is not defined on older compilers like C Set 3.1 */ -#elif defined(__xlC__) -# define Q_CC_XLC -# define Q_FULL_TEMPLATE_INSTANTIATION -# if __xlC__ < 0x400 -# define Q_NO_BOOL_TYPE -# define Q_NO_EXPLICIT_KEYWORD -# define Q_NO_USING_KEYWORD -# define Q_OUTOFLINE_TEMPLATE inline -# define Q_BROKEN_TEMPLATE_SPECIALIZATION -# define Q_CANNOT_DELETE_CONSTANT -# elif __xlC__ >= 0x0600 -# define Q_ALIGNOF(type) __alignof__(type) -# define Q_TYPEOF(expr) __typeof__(expr) -# define Q_DECL_ALIGN(n) __attribute__((__aligned__(n))) -# define Q_PACKED __attribute__((__packed__)) -# endif - -/* Older versions of DEC C++ do not define __EDG__ or __EDG - observed - on DEC C++ V5.5-004. New versions do define __EDG__ - observed on - Compaq C++ V6.3-002. - This compiler is different enough from other EDG compilers to handle - it separately anyway. */ -#elif defined(__DECCXX) || defined(__DECC) -# define Q_CC_DEC -/* Compaq C++ V6 compilers are EDG-based but I'm not sure about older - DEC C++ V5 compilers. */ -# if defined(__EDG__) -# define Q_CC_EDG -# endif -/* Compaq have disabled EDG's _BOOL macro and use _BOOL_EXISTS instead - - observed on Compaq C++ V6.3-002. - In any case versions prior to Compaq C++ V6.0-005 do not have bool. */ -# if !defined(_BOOL_EXISTS) -# define Q_NO_BOOL_TYPE -# endif -/* Spurious (?) error messages observed on Compaq C++ V6.5-014. */ -# define Q_NO_USING_KEYWORD -/* Apply to all versions prior to Compaq C++ V6.0-000 - observed on - DEC C++ V5.5-004. */ -# if __DECCXX_VER < 60060000 -# define Q_BROKEN_TEMPLATE_SPECIALIZATION -# define Q_CANNOT_DELETE_CONSTANT -# endif -/* avoid undefined symbol problems with out-of-line template members */ -# define Q_OUTOFLINE_TEMPLATE inline - -/* The Portland Group C++ compiler is based on EDG and does define __EDG__ - but the C compiler does not */ -#elif defined(__PGI) -# define Q_CC_PGI -# if defined(__EDG__) -# define Q_CC_EDG -# endif - -/* Compilers with EDG front end are similar. To detect them we test: - __EDG documented by SGI, observed on MIPSpro 7.3.1.1 and KAI C++ 4.0b - __EDG__ documented in EDG online docs, observed on Compaq C++ V6.3-002 - and PGI C++ 5.2-4 */ -#elif !defined(Q_OS_HPUX) && (defined(__EDG) || defined(__EDG__)) -# define Q_CC_EDG -/* From the EDG documentation (does not seem to apply to Compaq C++): - _BOOL - Defined in C++ mode when bool is a keyword. The name of this - predefined macro is specified by a configuration flag. _BOOL - is the default. - __BOOL_DEFINED - Defined in Microsoft C++ mode when bool is a keyword. */ -# if !defined(_BOOL) && !defined(__BOOL_DEFINED) -# define Q_NO_BOOL_TYPE -# endif - -/* The Comeau compiler is based on EDG and does define __EDG__ */ -# if defined(__COMO__) -# define Q_CC_COMEAU -# define Q_C_CALLBACKS - -/* The `using' keyword was introduced to avoid KAI C++ warnings - but it's now causing KAI C++ errors instead. The standard is - unclear about the use of this keyword, and in practice every - compiler is using its own set of rules. Forget it. */ -# elif defined(__KCC) -# define Q_CC_KAI -# define Q_NO_USING_KEYWORD - -/* Using the `using' keyword avoids Intel C++ for Linux warnings */ -# elif defined(__INTEL_COMPILER) -# define Q_CC_INTEL - -/* Uses CFront, make sure to read the manual how to tweak templates. */ -# elif defined(__ghs) -# define Q_CC_GHS - -# elif defined(__DCC__) -# define Q_CC_DIAB -# undef Q_NO_BOOL_TYPE -# if !defined(__bool) -# define Q_NO_BOOL_TYPE -# endif - -/* The UnixWare 7 UDK compiler is based on EDG and does define __EDG__ */ -# elif defined(__USLC__) && defined(__SCO_VERSION__) -# define Q_CC_USLC -/* The latest UDK 7.1.1b does not need this, but previous versions do */ -# if !defined(__SCO_VERSION__) || (__SCO_VERSION__ < 302200010) -# define Q_OUTOFLINE_TEMPLATE inline -# endif -# define Q_NO_USING_KEYWORD /* ### check "using" status */ - -/* Never tested! */ -# elif defined(CENTERLINE_CLPP) || defined(OBJECTCENTER) -# define Q_CC_OC -# define Q_NO_USING_KEYWORD - -/* CDS++ defines __EDG__ although this is not documented in the Reliant - documentation. It also follows conventions like _BOOL and this documented */ -# elif defined(sinix) -# define Q_CC_CDS -# define Q_NO_USING_KEYWORD - -/* The MIPSpro compiler defines __EDG */ -# elif defined(__sgi) -# define Q_CC_MIPS -# define Q_NO_USING_KEYWORD /* ### check "using" status */ -# define Q_NO_TEMPLATE_FRIENDS -# if defined(_COMPILER_VERSION) && (_COMPILER_VERSION >= 740) -# define Q_OUTOFLINE_TEMPLATE inline -# pragma set woff 3624,3625,3649 /* turn off some harmless warnings */ -# endif -# endif - -/* VxWorks' DIAB toolchain has an additional EDG type C++ compiler - (see __DCC__ above). This one is for C mode files (__EDG is not defined) */ -#elif defined(_DIAB_TOOL) -# define Q_CC_DIAB - -/* Never tested! */ -#elif defined(__HIGHC__) -# define Q_CC_HIGHC - -#elif defined(__SUNPRO_CC) || defined(__SUNPRO_C) -# define Q_CC_SUN -/* 5.0 compiler or better - 'bool' is enabled by default but can be disabled using -features=nobool - in which case _BOOL is not defined - this is the default in 4.2 compatibility mode triggered by -compat=4 */ -# if __SUNPRO_CC >= 0x500 -# define QT_NO_TEMPLATE_TEMPLATE_PARAMETERS - /* see http://developers.sun.com/sunstudio/support/Ccompare.html */ -# if __SUNPRO_CC >= 0x590 -# define Q_ALIGNOF(type) __alignof__(type) -# define Q_TYPEOF(expr) __typeof__(expr) -# define Q_DECL_ALIGN(n) __attribute__((__aligned__(n))) -# endif -# if __SUNPRO_CC >= 0x550 -# define Q_DECL_EXPORT __global -# endif -# if __SUNPRO_CC < 0x5a0 -# define Q_NO_TEMPLATE_FRIENDS -# endif -# if !defined(_BOOL) -# define Q_NO_BOOL_TYPE -# endif -# if defined(__SUNPRO_CC_COMPAT) && (__SUNPRO_CC_COMPAT <= 4) -# define Q_NO_USING_KEYWORD -# endif -# define Q_C_CALLBACKS -/* 4.2 compiler or older */ -# else -# define Q_NO_BOOL_TYPE -# define Q_NO_EXPLICIT_KEYWORD -# define Q_NO_USING_KEYWORD -# endif - -/* CDS++ does not seem to define __EDG__ or __EDG according to Reliant - documentation but nevertheless uses EDG conventions like _BOOL */ -#elif defined(sinix) -# define Q_CC_EDG -# define Q_CC_CDS -# if !defined(_BOOL) -# define Q_NO_BOOL_TYPE -# endif -# define Q_BROKEN_TEMPLATE_SPECIALIZATION - -#elif defined(Q_OS_HPUX) -/* __HP_aCC was not defined in first aCC releases */ -# if defined(__HP_aCC) || __cplusplus >= 199707L -# define Q_NO_TEMPLATE_FRIENDS -# define Q_CC_HPACC -# if __HP_aCC-0 < 060000 -# define QT_NO_TEMPLATE_TEMPLATE_PARAMETERS -# define Q_DECL_EXPORT __declspec(dllexport) -# define Q_DECL_IMPORT __declspec(dllimport) -# endif -# if __HP_aCC-0 >= 061200 -# define Q_DECL_ALIGN(n) __attribute__((aligned(n))) -# endif -# if __HP_aCC-0 >= 062000 -# define Q_DECL_EXPORT __attribute__((visibility("default"))) -# define Q_DECL_HIDDEN __attribute__((visibility("hidden"))) -# define Q_DECL_IMPORT Q_DECL_EXPORT -# endif -# else -# define Q_CC_HP -# define Q_NO_BOOL_TYPE -# define Q_FULL_TEMPLATE_INSTANTIATION -# define Q_BROKEN_TEMPLATE_SPECIALIZATION -# define Q_NO_EXPLICIT_KEYWORD -# endif -# define Q_NO_USING_KEYWORD /* ### check "using" status */ - -#else -# error "Qt has not been tested with this compiler - see http://www.qt-project.org/" -#endif - - -#ifdef Q_CC_INTEL -# if __INTEL_COMPILER < 1200 -# define Q_NO_TEMPLATE_FRIENDS -# endif -# if defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__GXX_EXPERIMENTAL_CPP0X__) -# if __INTEL_COMPILER >= 1200 -# define Q_COMPILER_RVALUE_REFS -# define Q_COMPILER_EXTERN_TEMPLATES -# define Q_COMPILER_DECLTYPE -# define Q_COMPILER_VARIADIC_TEMPLATES -# define Q_COMPILER_AUTO_TYPE -# define Q_COMPILER_DEFAULT_DELETE_MEMBERS -# define Q_COMPILER_CLASS_ENUM -# define Q_COMPILER_LAMBDA -# define Q_COMPILER_STATIC_ASSERT -# endif -# endif -#endif - -#ifdef Q_CC_CLANG -/* General C++ features */ -# if !__has_feature(cxx_exceptions) -# define QT_NO_EXCEPTIONS -# endif -# if !__has_feature(cxx_rtti) -# define QT_NO_RTTI -# endif -/* C++11 features, see http://clang.llvm.org/cxx_status.html */ -# if __cplusplus >= 201103L || __GXX_EXPERIMENTAL_CXX0X__ -# if ((__clang_major__ * 100) + __clang_minor__) >= 209 /* since clang 2.9 */ -# define Q_COMPILER_AUTO_TYPE -# define Q_COMPILER_DECLTYPE -# define Q_COMPILER_EXTERN_TEMPLATES -# define Q_COMPILER_RVALUE_REFS -# define Q_COMPILER_STATIC_ASSERT -# define Q_COMPILER_VARIADIC_MACROS -# define Q_COMPILER_VARIADIC_TEMPLATES -# endif -# if ((__clang_major__ * 100) + __clang_minor__) >= 300 /* since clang 3.0 */ -# define Q_COMPILER_CLASS_ENUM - /* defaulted members in 3.0, deleted members in 2.9 */ -# define Q_COMPILER_DEFAULT_DELETE_MEMBERS -# define Q_COMPILER_EXPLICIT_OVERRIDES -# define Q_COMPILER_NULLPTR -# define Q_COMPILER_RANGE_FOR -# define Q_COMPILER_UNICODE_STRINGS -# endif - /* not implemented in clang yet */ -# if __has_feature(cxx_constexpr) -# define Q_COMPILER_CONSTEXPR -# endif -# if __has_feature(cxx_lambdas) -# define Q_COMPILER_LAMBDA -# endif -# if __has_feature(cxx_generalized_initializers) -# define Q_COMPILER_INITIALIZER_LISTS -# endif -# if __has_feature(cxx_unrestricted_unions) -# define Q_COMPILER_UNRESTRICTED_UNIONS -# endif -# if 0 -# define Q_COMPILER_ATOMICS -# endif -# endif -#endif // Q_CC_CLANG - #ifndef Q_PACKED # define Q_PACKED # undef Q_NO_PACKED_REFERENCE @@ -681,12 +196,6 @@ namespace QT_NAMESPACE {} # endif #endif -#ifndef Q_COMPILER_MANGLES_RETURN_TYPE -# if defined(Q_CC_MSVC) -# define Q_COMPILER_MANGLES_RETURN_TYPE -# endif -#endif - QT_BEGIN_HEADER QT_BEGIN_NAMESPACE From 73e8ba9aff63e72c000d804c48aedacc9a8ee071 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Mon, 6 Feb 2012 11:31:12 +0100 Subject: [PATCH 008/406] Change #include "qlogging.h" to in qglobal.h This silences the warning from syncqt: QtCore: WARNING: qtbase/src/corelib/global/qglobal.h includes qlogging.h when it should include QtCore/qlogging.h Change-Id: I64bd92898190031eb0d3d1dfa5ba5bc56db01c00 Reviewed-by: Thiago Macieira --- src/corelib/global/qglobal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index dea96b297e1..7ac212be6b1 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1792,7 +1792,7 @@ QT_END_NAMESPACE QT_END_HEADER // qDebug and friends -#include "qlogging.h" +#include #endif /* __cplusplus */ From 86ee853f47ebe9d9705434ab4311caf20c1db7d6 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Mon, 6 Feb 2012 11:42:27 +0100 Subject: [PATCH 009/406] Silence syncqt warnings for atomic implementation headers Most of these headers are either forwarding headers, or we explicitly stop syncqt so that it doesn't generate class includes for the atomic implementation. Either way, syncqt doesn't see the QT_END_* (and sometimes not QT_BEGIN_*), which this commit fixes. Change-Id: Icc8da6f384f38b1ff4eb265c731ce2f2ed92a1a3 Reviewed-by: Thiago Macieira --- src/corelib/arch/qatomic_arm.h | 9 +++++++++ src/corelib/arch/qatomic_armv5.h | 4 ++++ src/corelib/arch/qatomic_armv6.h | 4 ++++ src/corelib/arch/qatomic_armv7.h | 9 +++++++++ src/corelib/arch/qatomic_bootstrap.h | 4 ++++ src/corelib/arch/qatomic_cxx11.h | 4 ++++ src/corelib/arch/qatomic_gcc.h | 4 ++++ src/corelib/arch/qatomic_i386.h | 4 ++++ src/corelib/arch/qatomic_ia64.h | 4 ++++ src/corelib/arch/qatomic_mips.h | 4 ++++ src/corelib/arch/qatomic_msvc.h | 4 ++++ src/corelib/arch/qatomic_x86_64.h | 4 ++++ src/corelib/thread/qbasicatomic.h | 4 ++++ src/corelib/thread/qgenericatomic.h | 4 ++++ src/corelib/thread/qoldbasicatomic.h | 4 ++++ 15 files changed, 70 insertions(+) diff --git a/src/corelib/arch/qatomic_arm.h b/src/corelib/arch/qatomic_arm.h index 3852bbb9e2c..4394765d456 100644 --- a/src/corelib/arch/qatomic_arm.h +++ b/src/corelib/arch/qatomic_arm.h @@ -63,4 +63,13 @@ # include "QtCore/qatomic_armv5.h" #endif +#if 0 +// silence syncqt warnings +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +QT_END_NAMESPACE +QT_END_HEADER +#endif + #endif // QATOMIC_ARM_H diff --git a/src/corelib/arch/qatomic_armv5.h b/src/corelib/arch/qatomic_armv5.h index 95ad73b7136..b3136fe5759 100644 --- a/src/corelib/arch/qatomic_armv5.h +++ b/src/corelib/arch/qatomic_armv5.h @@ -50,6 +50,10 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE #if 0 +// silence syncqt warnings +QT_END_NAMESPACE +QT_END_HEADER + #pragma qt_sync_stop_processing #endif diff --git a/src/corelib/arch/qatomic_armv6.h b/src/corelib/arch/qatomic_armv6.h index 7095d13d9bb..41f145ad0d3 100644 --- a/src/corelib/arch/qatomic_armv6.h +++ b/src/corelib/arch/qatomic_armv6.h @@ -50,6 +50,10 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE #if 0 +// silence syncqt warnings +QT_END_NAMESPACE +QT_END_HEADER + #pragma qt_sync_stop_processing #endif diff --git a/src/corelib/arch/qatomic_armv7.h b/src/corelib/arch/qatomic_armv7.h index 5b36708ad60..43ea8ca9739 100644 --- a/src/corelib/arch/qatomic_armv7.h +++ b/src/corelib/arch/qatomic_armv7.h @@ -52,4 +52,13 @@ // ... but the implementation is otherwise identical to that for ARMv6 #include "QtCore/qatomic_armv6.h" +#if 0 +// silence syncqt warnings +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +QT_END_NAMESPACE +QT_END_HEADER +#endif + #endif // QATOMIC_ARMV7_H diff --git a/src/corelib/arch/qatomic_bootstrap.h b/src/corelib/arch/qatomic_bootstrap.h index 10cdc888f6d..75f328b7c78 100644 --- a/src/corelib/arch/qatomic_bootstrap.h +++ b/src/corelib/arch/qatomic_bootstrap.h @@ -50,6 +50,10 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE #if 0 +// silence syncqt warnings +QT_END_NAMESPACE +QT_END_HEADER + #pragma qt_sync_stop_processing #endif diff --git a/src/corelib/arch/qatomic_cxx11.h b/src/corelib/arch/qatomic_cxx11.h index c2df59fd547..27e0acda64f 100644 --- a/src/corelib/arch/qatomic_cxx11.h +++ b/src/corelib/arch/qatomic_cxx11.h @@ -49,6 +49,10 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE #if 0 +// silence syncqt warnings +QT_END_NAMESPACE +QT_END_HEADER + #pragma qt_sync_stop_processing #endif diff --git a/src/corelib/arch/qatomic_gcc.h b/src/corelib/arch/qatomic_gcc.h index b5244429e65..225a7809eb0 100644 --- a/src/corelib/arch/qatomic_gcc.h +++ b/src/corelib/arch/qatomic_gcc.h @@ -48,6 +48,10 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE #if 0 +// silence syncqt warnings +QT_END_NAMESPACE +QT_END_HEADER + #pragma qt_sync_stop_processing #endif diff --git a/src/corelib/arch/qatomic_i386.h b/src/corelib/arch/qatomic_i386.h index 6fec561177e..4d9d8103181 100644 --- a/src/corelib/arch/qatomic_i386.h +++ b/src/corelib/arch/qatomic_i386.h @@ -49,6 +49,10 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE #if 0 +// silence syncqt warnings +QT_END_NAMESPACE +QT_END_HEADER + #pragma qt_sync_stop_processing #endif diff --git a/src/corelib/arch/qatomic_ia64.h b/src/corelib/arch/qatomic_ia64.h index b5cd9f75452..d82ad122232 100644 --- a/src/corelib/arch/qatomic_ia64.h +++ b/src/corelib/arch/qatomic_ia64.h @@ -50,6 +50,10 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE #if 0 +// silence syncqt warnings +QT_END_NAMESPACE +QT_END_HEADER + #pragma qt_sync_stop_processing #endif diff --git a/src/corelib/arch/qatomic_mips.h b/src/corelib/arch/qatomic_mips.h index 04015c9d197..af6e93d06ee 100644 --- a/src/corelib/arch/qatomic_mips.h +++ b/src/corelib/arch/qatomic_mips.h @@ -50,6 +50,10 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE #if 0 +// silence syncqt warnings +QT_END_NAMESPACE +QT_END_HEADER + #pragma qt_sync_stop_processing #endif diff --git a/src/corelib/arch/qatomic_msvc.h b/src/corelib/arch/qatomic_msvc.h index eeb37dba89a..c5d7848734a 100644 --- a/src/corelib/arch/qatomic_msvc.h +++ b/src/corelib/arch/qatomic_msvc.h @@ -48,6 +48,10 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE #if 0 +// silence syncqt warnings +QT_END_NAMESPACE +QT_END_HEADER + #pragma qt_sync_stop_processing #endif diff --git a/src/corelib/arch/qatomic_x86_64.h b/src/corelib/arch/qatomic_x86_64.h index f2fa8ce5f40..33427ebf33e 100644 --- a/src/corelib/arch/qatomic_x86_64.h +++ b/src/corelib/arch/qatomic_x86_64.h @@ -50,6 +50,10 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE #if 0 +// silence syncqt warnings +QT_END_NAMESPACE +QT_END_HEADER + #pragma qt_sync_stop_processing #endif diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h index 47d690c13f7..527031bbd14 100644 --- a/src/corelib/thread/qbasicatomic.h +++ b/src/corelib/thread/qbasicatomic.h @@ -78,6 +78,10 @@ QT_BEGIN_NAMESPACE QT_MODULE(Core) #if 0 +// silence syncqt warnings +QT_END_NAMESPACE +QT_END_HEADER + #pragma qt_no_master_include #pragma qt_sync_stop_processing #endif diff --git a/src/corelib/thread/qgenericatomic.h b/src/corelib/thread/qgenericatomic.h index 984ebed47b8..f4d5e2f8d93 100644 --- a/src/corelib/thread/qgenericatomic.h +++ b/src/corelib/thread/qgenericatomic.h @@ -48,6 +48,10 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE #if 0 +// silence syncqt warnings +QT_END_NAMESPACE +QT_END_HEADER + #pragma qt_sync_stop_processing #endif diff --git a/src/corelib/thread/qoldbasicatomic.h b/src/corelib/thread/qoldbasicatomic.h index a1985793ed1..4697da63019 100644 --- a/src/corelib/thread/qoldbasicatomic.h +++ b/src/corelib/thread/qoldbasicatomic.h @@ -50,6 +50,10 @@ QT_BEGIN_NAMESPACE #if 0 +// silence syncqt warnings +QT_END_NAMESPACE +QT_END_HEADER + #pragma qt_no_master_include #pragma qt_sync_stop_processing #endif From 8cb26f85119e6f11da613c95790c1b2c19f01dbd Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 6 Feb 2012 13:45:03 +0100 Subject: [PATCH 010/406] Complete split of QtConcurrent. - Fix exports. - Fix tests. Acked-by: Thiago Macieira Change-Id: I2df923ba74b468f5ee09b3a48ae3d09920751365 Reviewed-by: Friedemann Kleint --- src/concurrent/qfutureinterface.h | 2 +- src/concurrent/qfuturewatcher.h | 2 +- src/concurrent/qtconcurrentexception.h | 8 ++++---- src/concurrent/qtconcurrentiteratekernel.h | 2 +- src/concurrent/qtconcurrentresultstore.h | 4 ++-- src/concurrent/qtconcurrentthreadengine.h | 2 +- tests/auto/concurrent/qfuture/qfuture.pro | 2 +- tests/auto/concurrent/qfuturewatcher/qfuturewatcher.pro | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/concurrent/qfutureinterface.h b/src/concurrent/qfutureinterface.h index f64623ae587..3f05466cc69 100644 --- a/src/concurrent/qfutureinterface.h +++ b/src/concurrent/qfutureinterface.h @@ -60,7 +60,7 @@ class QFutureInterfaceBasePrivate; class QFutureWatcherBase; class QFutureWatcherBasePrivate; -class Q_CORE_EXPORT QFutureInterfaceBase +class Q_CONCURRENT_EXPORT QFutureInterfaceBase { public: enum State { diff --git a/src/concurrent/qfuturewatcher.h b/src/concurrent/qfuturewatcher.h index 0e94863d129..6b4b9416218 100644 --- a/src/concurrent/qfuturewatcher.h +++ b/src/concurrent/qfuturewatcher.h @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE class QEvent; class QFutureWatcherBasePrivate; -class Q_CORE_EXPORT QFutureWatcherBase : public QObject +class Q_CONCURRENT_EXPORT QFutureWatcherBase : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QFutureWatcherBase) diff --git a/src/concurrent/qtconcurrentexception.h b/src/concurrent/qtconcurrentexception.h index b04e1f2a04a..2021e7787c1 100644 --- a/src/concurrent/qtconcurrentexception.h +++ b/src/concurrent/qtconcurrentexception.h @@ -62,14 +62,14 @@ namespace QtConcurrent #ifndef QT_NO_EXCEPTIONS -class Q_CORE_EXPORT Exception : public std::exception +class Q_CONCURRENT_EXPORT Exception : public std::exception { public: virtual void raise() const; virtual Exception *clone() const; }; -class Q_CORE_EXPORT UnhandledException : public Exception +class Q_CONCURRENT_EXPORT UnhandledException : public Exception { public: void raise() const; @@ -90,7 +90,7 @@ public: QExplicitlySharedDataPointer base; }; -class Q_CORE_EXPORT ExceptionStore +class Q_CONCURRENT_EXPORT ExceptionStore { public: void setException(const Exception &e); @@ -107,7 +107,7 @@ public: namespace internal { -class Q_CORE_EXPORT ExceptionStore +class Q_CONCURRENT_EXPORT ExceptionStore { public: ExceptionStore() { } diff --git a/src/concurrent/qtconcurrentiteratekernel.h b/src/concurrent/qtconcurrentiteratekernel.h index a28bc31a645..48580537524 100644 --- a/src/concurrent/qtconcurrentiteratekernel.h +++ b/src/concurrent/qtconcurrentiteratekernel.h @@ -80,7 +80,7 @@ namespace QtConcurrent { management is done on the basis of the median of several timing measuremens, and it is done induvidualy for each thread. */ -class Q_CORE_EXPORT BlockSizeManager +class Q_CONCURRENT_EXPORT BlockSizeManager { public: BlockSizeManager(int iterationCount); diff --git a/src/concurrent/qtconcurrentresultstore.h b/src/concurrent/qtconcurrentresultstore.h index d39a45bba33..4be3c20d486 100644 --- a/src/concurrent/qtconcurrentresultstore.h +++ b/src/concurrent/qtconcurrentresultstore.h @@ -78,7 +78,7 @@ public: const void *result; // if count is 0 it's a result, otherwise it's a vector. }; -class Q_CORE_EXPORT ResultIteratorBase +class Q_CONCURRENT_EXPORT ResultIteratorBase { public: ResultIteratorBase(); @@ -119,7 +119,7 @@ public: } }; -class Q_CORE_EXPORT ResultStoreBase +class Q_CONCURRENT_EXPORT ResultStoreBase { public: ResultStoreBase(); diff --git a/src/concurrent/qtconcurrentthreadengine.h b/src/concurrent/qtconcurrentthreadengine.h index 20e86f59b6d..679496ce408 100644 --- a/src/concurrent/qtconcurrentthreadengine.h +++ b/src/concurrent/qtconcurrentthreadengine.h @@ -93,7 +93,7 @@ enum ThreadFunctionResult { ThrottleThread, ThreadFinished }; // Can be run in three modes: single threaded, multi-threaded blocking // and multi-threaded asynchronous. // The code for the single threaded mode is -class Q_CORE_EXPORT ThreadEngineBase: public QRunnable +class Q_CONCURRENT_EXPORT ThreadEngineBase: public QRunnable { public: // Public API: diff --git a/tests/auto/concurrent/qfuture/qfuture.pro b/tests/auto/concurrent/qfuture/qfuture.pro index a4c706129d9..c0fe7ec5a3b 100644 --- a/tests/auto/concurrent/qfuture/qfuture.pro +++ b/tests/auto/concurrent/qfuture/qfuture.pro @@ -1,5 +1,5 @@ CONFIG += testcase parallel_test TARGET = tst_qfuture -QT = concurrent-private testlib concurrent +QT = core concurrent-private testlib concurrent SOURCES = tst_qfuture.cpp DEFINES += QT_STRICT_ITERATORS diff --git a/tests/auto/concurrent/qfuturewatcher/qfuturewatcher.pro b/tests/auto/concurrent/qfuturewatcher/qfuturewatcher.pro index 3b8ebda4a4f..e9caf5494ac 100644 --- a/tests/auto/concurrent/qfuturewatcher/qfuturewatcher.pro +++ b/tests/auto/concurrent/qfuturewatcher/qfuturewatcher.pro @@ -1,4 +1,4 @@ CONFIG += testcase parallel_test TARGET = tst_qfuturewatcher -QT = concurrent-private testlib concurrent +QT = core concurrent-private testlib concurrent SOURCES = tst_qfuturewatcher.cpp From a3566649d1c22df0639efde0987edfc0596e99d9 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Mon, 6 Feb 2012 14:07:35 +0100 Subject: [PATCH 011/406] Add distance field generation functions from Scenegraph Since we may use distance field text rendering in raster, these functions need to be moved from declarative to QtGui. Change-Id: I158bc3bae02b5590ae812f06ad7a78a5914bcb9e Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/painting/painting.pri | 6 +- src/gui/painting/qpathsimplifier.cpp | 1673 ++++++++++++++++++++++++++ src/gui/painting/qpathsimplifier_p.h | 68 ++ src/gui/text/qdistancefield.cpp | 762 ++++++++++++ src/gui/text/qdistancefield_p.h | 85 ++ src/gui/text/text.pri | 6 +- 6 files changed, 2596 insertions(+), 4 deletions(-) create mode 100644 src/gui/painting/qpathsimplifier.cpp create mode 100644 src/gui/painting/qpathsimplifier_p.h create mode 100644 src/gui/text/qdistancefield.cpp create mode 100644 src/gui/text/qdistancefield_p.h diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 61a25e9ac86..4cd2351b23c 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -34,7 +34,8 @@ HEADERS += \ painting/qtextureglyphcache_p.h \ painting/qtransform.h \ painting/qplatformbackingstore_qpa.h \ - painting/qpaintbuffer_p.h + painting/qpaintbuffer_p.h \ + painting/qpathsimplifier_p.h SOURCES += \ @@ -68,7 +69,8 @@ SOURCES += \ painting/qtextureglyphcache.cpp \ painting/qtransform.cpp \ painting/qplatformbackingstore_qpa.cpp \ - painting/qpaintbuffer.cpp + painting/qpaintbuffer.cpp \ + painting/qpathsimplifier.cpp SOURCES += \ painting/qpaintengine_raster.cpp \ diff --git a/src/gui/painting/qpathsimplifier.cpp b/src/gui/painting/qpathsimplifier.cpp new file mode 100644 index 00000000000..fc3ce6361b2 --- /dev/null +++ b/src/gui/painting/qpathsimplifier.cpp @@ -0,0 +1,1673 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtDeclarative 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 "qpathsimplifier_p.h" + +#include +#include +#include +#include + +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +#define Q_FIXED_POINT_SCALE 256 +#define Q_TRIANGULATE_END_OF_POLYGON quint32(-1) + + +namespace { + +//============================================================================// +// QPoint // +//============================================================================// + +inline bool operator < (const QPoint &a, const QPoint &b) +{ + return a.y() < b.y() || (a.y() == b.y() && a.x() < b.x()); +} + +inline bool operator > (const QPoint &a, const QPoint &b) +{ + return b < a; +} + +inline bool operator <= (const QPoint &a, const QPoint &b) +{ + return !(a > b); +} + +inline bool operator >= (const QPoint &a, const QPoint &b) +{ + return !(a < b); +} + +inline int cross(const QPoint &u, const QPoint &v) +{ + return u.x() * v.y() - u.y() * v.x(); +} + +inline int dot(const QPoint &u, const QPoint &v) +{ + return u.x() * v.x() + u.y() * v.y(); +} + +//============================================================================// +// Fraction // +//============================================================================// + +// Fraction must be in the range [0, 1) +struct Fraction +{ + bool isValid() const { return denominator != 0; } + + // numerator and denominator must not have common denominators. + unsigned int numerator, denominator; +}; + +inline unsigned int gcd(unsigned int x, unsigned int y) +{ + while (y != 0) { + unsigned int z = y; + y = x % y; + x = z; + } + return x; +} + +// Fraction must be in the range [0, 1) +// Assume input is valid. +Fraction fraction(unsigned int n, unsigned int d) { + Fraction result; + if (n == 0) { + result.numerator = 0; + result.denominator = 1; + } else { + unsigned int g = gcd(n, d); + result.numerator = n / g; + result.denominator = d / g; + } + return result; +} + +//============================================================================// +// Rational // +//============================================================================// + +struct Rational +{ + bool isValid() const { return fraction.isValid(); } + int integer; + Fraction fraction; +}; + +//============================================================================// +// IntersectionPoint // +//============================================================================// + +struct IntersectionPoint +{ + bool isValid() const { return x.fraction.isValid() && y.fraction.isValid(); } + QPoint round() const; + bool isAccurate() const { return x.fraction.numerator == 0 && y.fraction.numerator == 0; } + + Rational x; // 8:8 signed, 32/32 + Rational y; // 8:8 signed, 32/32 +}; + +QPoint IntersectionPoint::round() const +{ + QPoint result(x.integer, y.integer); + if (2 * x.fraction.numerator >= x.fraction.denominator) + ++result.rx(); + if (2 * y.fraction.numerator >= y.fraction.denominator) + ++result.ry(); + return result; +} + +// Return positive value if 'p' is to the right of the line 'v1'->'v2', negative if left of the +// line and zero if exactly on the line. +// The returned value is the z-component of the qCross product between 'v2-v1' and 'p-v1', +// which is twice the signed area of the triangle 'p'->'v1'->'v2' (positive for CW order). +inline int pointDistanceFromLine(const QPoint &p, const QPoint &v1, const QPoint &v2) +{ + return cross(v2 - v1, p - v1); +} + +IntersectionPoint intersectionPoint(const QPoint &u1, const QPoint &u2, + const QPoint &v1, const QPoint &v2) +{ + IntersectionPoint result = {{0, {0, 0}}, {0, {0, 0}}}; + + QPoint u = u2 - u1; + QPoint v = v2 - v1; + int d1 = cross(u, v1 - u1); + int d2 = cross(u, v2 - u1); + int det = d2 - d1; + int d3 = cross(v, u1 - v1); + int d4 = d3 - det; //qCross(v, u2 - v1); + + // Check that the math is correct. + Q_ASSERT(d4 == cross(v, u2 - v1)); + + // The intersection point can be expressed as: + // v1 - v * d1/det + // v2 - v * d2/det + // u1 + u * d3/det + // u2 + u * d4/det + + // I'm only interested in lines that are crossing, so ignore parallel lines even if they overlap. + if (det == 0) + return result; + + if (det < 0) { + det = -det; + d1 = -d1; + d2 = -d2; + d3 = -d3; + d4 = -d4; + } + + // I'm only interested in lines intersecting at their interior, not at their end points. + // The lines intersect at their interior if and only if 'd1 < 0', 'd2 > 0', 'd3 < 0' and 'd4 > 0'. + if (d1 >= 0 || d2 <= 0 || d3 <= 0 || d4 >= 0) + return result; + + // Calculate the intersection point as follows: + // v1 - v * d1/det | v1 <= v2 (component-wise) + // v2 - v * d2/det | v2 < v1 (component-wise) + + // Assuming 16 bits per vector component. + if (v.x() >= 0) { + result.x.integer = v1.x() + int(qint64(-v.x()) * d1 / det); + result.x.fraction = fraction((unsigned int)(qint64(-v.x()) * d1 % det), (unsigned int)det); + } else { + result.x.integer = v2.x() + int(qint64(-v.x()) * d2 / det); + result.x.fraction = fraction((unsigned int)(qint64(-v.x()) * d2 % det), (unsigned int)det); + } + + if (v.y() >= 0) { + result.y.integer = v1.y() + int(qint64(-v.y()) * d1 / det); + result.y.fraction = fraction((unsigned int)(qint64(-v.y()) * d1 % det), (unsigned int)det); + } else { + result.y.integer = v2.y() + int(qint64(-v.y()) * d2 / det); + result.y.fraction = fraction((unsigned int)(qint64(-v.y()) * d2 % det), (unsigned int)det); + } + + Q_ASSERT(result.x.fraction.isValid()); + Q_ASSERT(result.y.fraction.isValid()); + return result; +} + +//============================================================================// +// PathSimplifier // +//============================================================================// + +class PathSimplifier +{ +public: + PathSimplifier(const QVectorPath &path, QDataBuffer &vertices, + QDataBuffer &indices, const QTransform &matrix); + +private: + struct Element; + + class BoundingVolumeHierarchy + { + public: + struct Node + { + enum Type + { + Leaf, + Split + }; + Type type; + QPoint minimum; + QPoint maximum; + union { + Element *element; // type == Leaf + Node *left; // type == Split + }; + Node *right; + }; + + BoundingVolumeHierarchy(); + ~BoundingVolumeHierarchy(); + void allocate(int nodeCount); + void free(); + Node *newNode(); + + Node *root; + private: + void freeNode(Node *n); + + Node *nodeBlock; + int blockSize; + int firstFree; + }; + + struct Element + { + enum Degree + { + Line = 1, + Quadratic = 2, + Cubic = 3 + }; + + quint32 &upperIndex() { return indices[pointingUp ? degree : 0]; } + quint32 &lowerIndex() { return indices[pointingUp ? 0 : degree]; } + quint32 upperIndex() const { return indices[pointingUp ? degree : 0]; } + quint32 lowerIndex() const { return indices[pointingUp ? 0 : degree]; } + void flip(); + + QPoint middle; + quint32 indices[4]; // index to points + Element *next, *previous; // used in connectElements() + int winding; // used in connectElements() + union { + QRBTree::Node *edgeNode; // used in connectElements() + BoundingVolumeHierarchy::Node *bvhNode; + }; + Degree degree : 8; + uint processed : 1; // initially false, true when the element has been checked for intersections. + uint pointingUp : 1; // used in connectElements() + uint originallyPointingUp : 1; // used in connectElements() + }; + + class ElementAllocator + { + public: + ElementAllocator(); + ~ElementAllocator(); + void allocate(int count); + Element *newElement(); + private: + struct ElementBlock + { + ElementBlock *next; + int blockSize; + int firstFree; + Element elements[1]; + } *blocks; + }; + + struct Event + { + enum Type { Upper, Lower }; + bool operator < (const Event &other) const; + + QPoint point; + Type type; + Element *element; + }; + + typedef QRBTree::Node RBNode; + typedef BoundingVolumeHierarchy::Node BVHNode; + + void initElements(const QVectorPath &path, const QTransform &matrix); + void removeIntersections(); + void connectElements(); + void fillIndices(); + BVHNode *buildTree(Element **elements, int elementCount); + bool intersectNodes(QDataBuffer &elements, BVHNode *elementNode, BVHNode *treeNode); + bool equalElements(const Element *e1, const Element *e2); + bool splitLineAt(QDataBuffer &elements, BVHNode *node, quint32 pointIndex, bool processAgain); + void appendSeparatingAxes(QVarLengthArray &axes, Element *element); + QPair calculateSeparatingAxisRange(const QPoint &axis, Element *element); + void splitCurve(QDataBuffer &elements, BVHNode *node); + bool setElementToQuadratic(Element *element, quint32 pointIndex1, const QPoint &ctrl, quint32 pointIndex2); + bool setElementToCubic(Element *element, quint32 pointIndex1, const QPoint &ctrl1, const QPoint &ctrl2, quint32 pointIndex2); + void setElementToCubicAndSimplify(Element *element, quint32 pointIndex1, const QPoint &ctrl1, const QPoint &ctrl2, quint32 pointIndex2); + RBNode *findElementLeftOf(const Element *element, const QPair &bounds); + bool elementIsLeftOf(const Element *left, const Element *right); + QPair outerBounds(const QPoint &point); + static bool flattenQuadratic(const QPoint &u, const QPoint &v, const QPoint &w); + static bool flattenCubic(const QPoint &u, const QPoint &v, const QPoint &w, const QPoint &q); + static bool splitQuadratic(const QPoint &u, const QPoint &v, const QPoint &w, QPoint *result); + static bool splitCubic(const QPoint &u, const QPoint &v, const QPoint &w, const QPoint &q, QPoint *result); + void subDivQuadratic(const QPoint &u, const QPoint &v, const QPoint &w); + void subDivCubic(const QPoint &u, const QPoint &v, const QPoint &w, const QPoint &q); + static void sortEvents(Event *events, int count); + + ElementAllocator m_elementAllocator; + QDataBuffer m_elements; + QDataBuffer *m_points; + BoundingVolumeHierarchy m_bvh; + QDataBuffer *m_indices; + QRBTree m_elementList; + uint m_hints; +}; + +inline PathSimplifier::BoundingVolumeHierarchy::BoundingVolumeHierarchy() + : root(0) + , nodeBlock(0) + , blockSize(0) + , firstFree(0) +{ +} + +inline PathSimplifier::BoundingVolumeHierarchy::~BoundingVolumeHierarchy() +{ + free(); +} + +inline void PathSimplifier::BoundingVolumeHierarchy::allocate(int nodeCount) +{ + Q_ASSERT(nodeBlock == 0); + Q_ASSERT(firstFree == 0); + nodeBlock = new Node[blockSize = nodeCount]; +} + +inline void PathSimplifier::BoundingVolumeHierarchy::free() +{ + freeNode(root); + delete[] nodeBlock; + nodeBlock = 0; + firstFree = blockSize = 0; + root = 0; +} + +inline PathSimplifier::BVHNode *PathSimplifier::BoundingVolumeHierarchy::newNode() +{ + if (firstFree < blockSize) + return &nodeBlock[firstFree++]; + return new Node; +} + +inline void PathSimplifier::BoundingVolumeHierarchy::freeNode(Node *n) +{ + if (!n) + return; + Q_ASSERT(n->type == Node::Split || n->type == Node::Leaf); + if (n->type == Node::Split) { + freeNode(n->left); + freeNode(n->right); + } + if (!(n >= nodeBlock && n < nodeBlock + blockSize)) + delete n; +} + +inline PathSimplifier::ElementAllocator::ElementAllocator() + : blocks(0) +{ +} + +inline PathSimplifier::ElementAllocator::~ElementAllocator() +{ + while (blocks) { + ElementBlock *block = blocks; + blocks = blocks->next; + free(block); + } +} + +inline void PathSimplifier::ElementAllocator::allocate(int count) +{ + Q_ASSERT(blocks == 0); + Q_ASSERT(count > 0); + blocks = (ElementBlock *)malloc(sizeof(ElementBlock) + (count - 1) * sizeof(Element)); + blocks->blockSize = count; + blocks->next = 0; + blocks->firstFree = 0; +} + +inline PathSimplifier::Element *PathSimplifier::ElementAllocator::newElement() +{ + Q_ASSERT(blocks); + if (blocks->firstFree < blocks->blockSize) + return &blocks->elements[blocks->firstFree++]; + ElementBlock *oldBlock = blocks; + blocks = (ElementBlock *)malloc(sizeof(ElementBlock) + (oldBlock->blockSize - 1) * sizeof(Element)); + blocks->blockSize = oldBlock->blockSize; + blocks->next = oldBlock; + blocks->firstFree = 0; + return &blocks->elements[blocks->firstFree++]; +} + + +inline bool PathSimplifier::Event::operator < (const Event &other) const +{ + if (point == other.point) + return type < other.type; + return other.point < point; +} + +inline void PathSimplifier::Element::flip() +{ + for (int i = 0; i < (degree + 1) >> 1; ++i) { + Q_ASSERT(degree >= Line && degree <= Cubic); + Q_ASSERT(i >= 0 && i < degree); + qSwap(indices[i], indices[degree - i]); + } + pointingUp = !pointingUp; + Q_ASSERT(next == 0 && previous == 0); +} + +PathSimplifier::PathSimplifier(const QVectorPath &path, QDataBuffer &vertices, + QDataBuffer &indices, const QTransform &matrix) + : m_elements(0) + , m_points(&vertices) + , m_indices(&indices) +{ + m_points->reset(); + m_indices->reset(); + initElements(path, matrix); + if (!m_elements.isEmpty()) { + removeIntersections(); + connectElements(); + fillIndices(); + } +} + +void PathSimplifier::initElements(const QVectorPath &path, const QTransform &matrix) +{ + m_hints = path.hints(); + int pathElementCount = path.elementCount(); + if (pathElementCount == 0) + return; + m_elements.reserve(2 * pathElementCount); + m_elementAllocator.allocate(2 * pathElementCount); + m_points->reserve(2 * pathElementCount); + const QPainterPath::ElementType *e = path.elements(); + const qreal *p = path.points(); + if (e) { + qreal x, y; + quint32 moveToIndex = 0; + quint32 previousIndex = 0; + for (int i = 0; i < pathElementCount; ++i, ++e, p += 2) { + switch (*e) { + case QPainterPath::MoveToElement: + { + if (!m_points->isEmpty()) { + const QPoint &from = m_points->at(previousIndex); + const QPoint &to = m_points->at(moveToIndex); + if (from != to) { + Element *element = m_elementAllocator.newElement(); + element->degree = Element::Line; + element->indices[0] = previousIndex; + element->indices[1] = moveToIndex; + element->middle.rx() = (from.x() + to.x()) >> 1; + element->middle.ry() = (from.y() + to.y()) >> 1; + m_elements.add(element); + } + } + previousIndex = moveToIndex = m_points->size(); + matrix.map(p[0], p[1], &x, &y); + QPoint to(qRound(x * Q_FIXED_POINT_SCALE), qRound(y * Q_FIXED_POINT_SCALE)); + m_points->add(to); + } + break; + case QPainterPath::LineToElement: + Q_ASSERT(!m_points->isEmpty()); + { + matrix.map(p[0], p[1], &x, &y); + QPoint to(qRound(x * Q_FIXED_POINT_SCALE), qRound(y * Q_FIXED_POINT_SCALE)); + const QPoint &from = m_points->last(); + if (to != from) { + Element *element = m_elementAllocator.newElement(); + element->degree = Element::Line; + element->indices[0] = previousIndex; + element->indices[1] = quint32(m_points->size()); + element->middle.rx() = (from.x() + to.x()) >> 1; + element->middle.ry() = (from.y() + to.y()) >> 1; + m_elements.add(element); + previousIndex = m_points->size(); + m_points->add(to); + } + } + break; + case QPainterPath::CurveToElement: + Q_ASSERT(i + 2 < pathElementCount); + Q_ASSERT(!m_points->isEmpty()); + Q_ASSERT(e[1] == QPainterPath::CurveToDataElement); + Q_ASSERT(e[2] == QPainterPath::CurveToDataElement); + { + quint32 startPointIndex = previousIndex; + matrix.map(p[4], p[5], &x, &y); + QPoint end(qRound(x * Q_FIXED_POINT_SCALE), qRound(y * Q_FIXED_POINT_SCALE)); + previousIndex = m_points->size(); + m_points->add(end); + + // See if this cubic bezier is really quadratic. + qreal x1 = p[-2] + qreal(1.5) * (p[0] - p[-2]); + qreal y1 = p[-1] + qreal(1.5) * (p[1] - p[-1]); + qreal x2 = p[4] + qreal(1.5) * (p[2] - p[4]); + qreal y2 = p[5] + qreal(1.5) * (p[3] - p[5]); + + Element *element = m_elementAllocator.newElement(); + if (qAbs(x1 - x2) < qreal(1e-3) && qAbs(y1 - y2) < qreal(1e-3)) { + // The bezier curve is quadratic. + matrix.map(x1, y1, &x, &y); + QPoint ctrl(qRound(x * Q_FIXED_POINT_SCALE), + qRound(y * Q_FIXED_POINT_SCALE)); + setElementToQuadratic(element, startPointIndex, ctrl, previousIndex); + } else { + // The bezier curve is cubic. + matrix.map(p[0], p[1], &x, &y); + QPoint ctrl1(qRound(x * Q_FIXED_POINT_SCALE), + qRound(y * Q_FIXED_POINT_SCALE)); + matrix.map(p[2], p[3], &x, &y); + QPoint ctrl2(qRound(x * Q_FIXED_POINT_SCALE), + qRound(y * Q_FIXED_POINT_SCALE)); + setElementToCubicAndSimplify(element, startPointIndex, ctrl1, ctrl2, + previousIndex); + } + m_elements.add(element); + } + i += 2; + e += 2; + p += 4; + + break; + default: + Q_ASSERT_X(0, "QSGPathSimplifier::initialize", "Unexpected element type."); + break; + } + } + if (!m_points->isEmpty()) { + const QPoint &from = m_points->at(previousIndex); + const QPoint &to = m_points->at(moveToIndex); + if (from != to) { + Element *element = m_elementAllocator.newElement(); + element->degree = Element::Line; + element->indices[0] = previousIndex; + element->indices[1] = moveToIndex; + element->middle.rx() = (from.x() + to.x()) >> 1; + element->middle.ry() = (from.y() + to.y()) >> 1; + m_elements.add(element); + } + } + } else { + qreal x, y; + + for (int i = 0; i < pathElementCount; ++i, p += 2) { + matrix.map(p[0], p[1], &x, &y); + QPoint to(qRound(x * Q_FIXED_POINT_SCALE), qRound(y * Q_FIXED_POINT_SCALE)); + if (to != m_points->last()) + m_points->add(to); + } + + while (!m_points->isEmpty() && m_points->last() == m_points->first()) + m_points->pop_back(); + + if (m_points->isEmpty()) + return; + + quint32 prev = quint32(m_points->size() - 1); + for (int i = 0; i < m_points->size(); ++i) { + QPoint &to = m_points->at(i); + QPoint &from = m_points->at(prev); + Element *element = m_elementAllocator.newElement(); + element->degree = Element::Line; + element->indices[0] = prev; + element->indices[1] = quint32(i); + element->middle.rx() = (from.x() + to.x()) >> 1; + element->middle.ry() = (from.y() + to.y()) >> 1; + m_elements.add(element); + prev = i; + } + } + + for (int i = 0; i < m_elements.size(); ++i) + m_elements.at(i)->processed = false; +} + +void PathSimplifier::removeIntersections() +{ + Q_ASSERT(!m_elements.isEmpty()); + QDataBuffer elements(m_elements.size()); + for (int i = 0; i < m_elements.size(); ++i) + elements.add(m_elements.at(i)); + m_bvh.allocate(2 * m_elements.size()); + m_bvh.root = buildTree(elements.data(), elements.size()); + + elements.reset(); + for (int i = 0; i < m_elements.size(); ++i) + elements.add(m_elements.at(i)); + + while (!elements.isEmpty()) { + Element *element = elements.last(); + elements.pop_back(); + BVHNode *node = element->bvhNode; + Q_ASSERT(node->type == BVHNode::Leaf); + Q_ASSERT(node->element == element); + if (!element->processed) { + if (!intersectNodes(elements, node, m_bvh.root)) + element->processed = true; + } + } + + m_bvh.free(); // The bounding volume hierarchy is not needed anymore. +} + +void PathSimplifier::connectElements() +{ + Q_ASSERT(!m_elements.isEmpty()); + QDataBuffer events(m_elements.size() * 2); + for (int i = 0; i < m_elements.size(); ++i) { + Element *element = m_elements.at(i); + element->next = element->previous = 0; + element->winding = 0; + element->edgeNode = 0; + const QPoint &u = m_points->at(element->indices[0]); + const QPoint &v = m_points->at(element->indices[element->degree]); + if (u != v) { + element->pointingUp = element->originallyPointingUp = v < u; + + Event event; + event.element = element; + event.point = u; + event.type = element->pointingUp ? Event::Lower : Event::Upper; + events.add(event); + event.point = v; + event.type = element->pointingUp ? Event::Upper : Event::Lower; + events.add(event); + } + } + QVarLengthArray orderedElements; + if (!events.isEmpty()) + sortEvents(events.data(), events.size()); + while (!events.isEmpty()) { + const Event *event = &events.last(); + QPoint eventPoint = event->point; + + // Find all elements passing through the event point. + QPair bounds = outerBounds(eventPoint); + + // Special case: single element above and single element below event point. + int eventCount = events.size(); + if (event->type == Event::Lower && eventCount > 2) { + QPair range; + range.first = bounds.first ? m_elementList.next(bounds.first) + : m_elementList.front(m_elementList.root); + range.second = bounds.second ? m_elementList.previous(bounds.second) + : m_elementList.back(m_elementList.root); + + const Event *event2 = &events.at(eventCount - 2); + const Event *event3 = &events.at(eventCount - 3); + Q_ASSERT(event2->point == eventPoint); // There are always at least two events at a point. + if (range.first == range.second && event2->type == Event::Upper && event3->point != eventPoint) { + Element *element = event->element; + Element *element2 = event2->element; + element->edgeNode->data = event2->element; + element2->edgeNode = element->edgeNode; + element->edgeNode = 0; + + events.pop_back(); + events.pop_back(); + + if (element2->pointingUp != element->pointingUp) + element2->flip(); + element2->winding = element->winding; + int winding = element->winding; + if (element->originallyPointingUp) + ++winding; + if (winding == 0 || winding == 1) { + if (element->pointingUp) { + element->previous = event2->element; + element2->next = event->element; + } else { + element->next = event2->element; + element2->previous = event->element; + } + } + continue; + } + } + orderedElements.clear(); + + // First, find the ones above the event point. + if (m_elementList.root) { + RBNode *current = bounds.first ? m_elementList.next(bounds.first) + : m_elementList.front(m_elementList.root); + while (current != bounds.second) { + Element *element = current->data; + Q_ASSERT(element->edgeNode == current); + int winding = element->winding; + if (element->originallyPointingUp) + ++winding; + const QPoint &lower = m_points->at(element->lowerIndex()); + if (lower == eventPoint) { + if (winding == 0 || winding == 1) + orderedElements.append(current->data); + } else { + // The element is passing through 'event.point'. + Q_ASSERT(m_points->at(element->upperIndex()) != eventPoint); + Q_ASSERT(element->degree == Element::Line); + // Split the line. + Element *eventElement = event->element; + int indexIndex = (event->type == Event::Upper) == eventElement->pointingUp + ? eventElement->degree : 0; + quint32 pointIndex = eventElement->indices[indexIndex]; + Q_ASSERT(eventPoint == m_points->at(pointIndex)); + + Element *upperElement = m_elementAllocator.newElement(); + *upperElement = *element; + upperElement->lowerIndex() = element->upperIndex() = pointIndex; + upperElement->edgeNode = 0; + element->next = element->previous = 0; + if (upperElement->next) + upperElement->next->previous = upperElement; + else if (upperElement->previous) + upperElement->previous->next = upperElement; + if (element->pointingUp != element->originallyPointingUp) + element->flip(); + if (winding == 0 || winding == 1) + orderedElements.append(upperElement); + m_elements.add(upperElement); + } + current = m_elementList.next(current); + } + } + while (!events.isEmpty() && events.last().point == eventPoint) { + event = &events.last(); + if (event->type == Event::Upper) { + Q_ASSERT(event->point == m_points->at(event->element->upperIndex())); + RBNode *left = findElementLeftOf(event->element, bounds); + RBNode *node = m_elementList.newNode(); + node->data = event->element; + Q_ASSERT(event->element->edgeNode == 0); + event->element->edgeNode = node; + m_elementList.attachAfter(left, node); + } else { + Q_ASSERT(event->type == Event::Lower); + Q_ASSERT(event->point == m_points->at(event->element->lowerIndex())); + Element *element = event->element; + Q_ASSERT(element->edgeNode); + m_elementList.deleteNode(element->edgeNode); + Q_ASSERT(element->edgeNode == 0); + } + events.pop_back(); + } + + if (m_elementList.root) { + RBNode *current = bounds.first ? m_elementList.next(bounds.first) + : m_elementList.front(m_elementList.root); + int winding = bounds.first ? bounds.first->data->winding : 0; + + // Calculate winding numbers and flip elements if necessary. + while (current != bounds.second) { + Element *element = current->data; + Q_ASSERT(element->edgeNode == current); + int ccw = winding & 1; + Q_ASSERT(element->pointingUp == element->originallyPointingUp); + if (element->originallyPointingUp) { + --winding; + } else { + ++winding; + ccw ^= 1; + } + element->winding = winding; + if (ccw == 0) + element->flip(); + current = m_elementList.next(current); + } + + // Pick elements with correct winding number. + current = bounds.second ? m_elementList.previous(bounds.second) + : m_elementList.back(m_elementList.root); + while (current != bounds.first) { + Element *element = current->data; + Q_ASSERT(element->edgeNode == current); + Q_ASSERT(m_points->at(element->upperIndex()) == eventPoint); + int winding = element->winding; + if (element->originallyPointingUp) + ++winding; + if (winding == 0 || winding == 1) + orderedElements.append(current->data); + current = m_elementList.previous(current); + } + } + + if (!orderedElements.isEmpty()) { + Q_ASSERT((orderedElements.size() & 1) == 0); + int i = 0; + Element *firstElement = orderedElements.at(0); + if (m_points->at(firstElement->indices[0]) != eventPoint) { + orderedElements.append(firstElement); + i = 1; + } + for (; i < orderedElements.size(); i += 2) { + Q_ASSERT(i + 1 < orderedElements.size()); + Element *next = orderedElements.at(i); + Element *previous = orderedElements.at(i + 1); + Q_ASSERT(next->previous == 0); + Q_ASSERT(previous->next == 0); + next->previous = previous; + previous->next = next; + } + } + } +#ifndef QT_NO_DEBUG + for (int i = 0; i < m_elements.size(); ++i) { + const Element *element = m_elements.at(i); + Q_ASSERT(element->next == 0 || element->next->previous == element); + Q_ASSERT(element->previous == 0 || element->previous->next == element); + Q_ASSERT((element->next == 0) == (element->previous == 0)); + } +#endif +} + +void PathSimplifier::fillIndices() +{ + for (int i = 0; i < m_elements.size(); ++i) + m_elements.at(i)->processed = false; + for (int i = 0; i < m_elements.size(); ++i) { + Element *element = m_elements.at(i); + if (element->processed || element->next == 0) + continue; + do { + m_indices->add(element->indices[0]); + switch (element->degree) { + case Element::Quadratic: + { + QPoint pts[] = { + m_points->at(element->indices[0]), + m_points->at(element->indices[1]), + m_points->at(element->indices[2]) + }; + subDivQuadratic(pts[0], pts[1], pts[2]); + } + break; + case Element::Cubic: + { + QPoint pts[] = { + m_points->at(element->indices[0]), + m_points->at(element->indices[1]), + m_points->at(element->indices[2]), + m_points->at(element->indices[3]) + }; + subDivCubic(pts[0], pts[1], pts[2], pts[3]); + } + break; + default: + break; + } + Q_ASSERT(element->next); + element->processed = true; + element = element->next; + } while (element != m_elements.at(i)); + m_indices->add(Q_TRIANGULATE_END_OF_POLYGON); + } +} + +PathSimplifier::BVHNode *PathSimplifier::buildTree(Element **elements, int elementCount) +{ + Q_ASSERT(elementCount > 0); + BVHNode *node = m_bvh.newNode(); + if (elementCount == 1) { + Element *element = *elements; + element->bvhNode = node; + node->type = BVHNode::Leaf; + node->element = element; + node->minimum = node->maximum = m_points->at(element->indices[0]); + for (int i = 1; i <= element->degree; ++i) { + const QPoint &p = m_points->at(element->indices[i]); + node->minimum.rx() = qMin(node->minimum.x(), p.x()); + node->minimum.ry() = qMin(node->minimum.y(), p.y()); + node->maximum.rx() = qMax(node->maximum.x(), p.x()); + node->maximum.ry() = qMax(node->maximum.y(), p.y()); + } + return node; + } + + node->type = BVHNode::Split; + + QPoint minimum, maximum; + minimum = maximum = elements[0]->middle; + + for (int i = 1; i < elementCount; ++i) { + const QPoint &p = elements[i]->middle; + minimum.rx() = qMin(minimum.x(), p.x()); + minimum.ry() = qMin(minimum.y(), p.y()); + maximum.rx() = qMax(maximum.x(), p.x()); + maximum.ry() = qMax(maximum.y(), p.y()); + } + + int comp, pivot; + if (maximum.x() - minimum.x() > maximum.y() - minimum.y()) { + comp = 0; + pivot = (maximum.x() + minimum.x()) >> 1; + } else { + comp = 1; + pivot = (maximum.y() + minimum.y()) >> 1; + } + + int lo = 0; + int hi = elementCount - 1; + while (lo < hi) { + while (lo < hi && (&elements[lo]->middle.rx())[comp] <= pivot) + ++lo; + while (lo < hi && (&elements[hi]->middle.rx())[comp] > pivot) + --hi; + if (lo < hi) + qSwap(elements[lo], elements[hi]); + } + + if (lo == elementCount) { + // All points are the same. + Q_ASSERT(minimum.x() == maximum.x() && minimum.y() == maximum.y()); + lo = elementCount >> 1; + } + + node->left = buildTree(elements, lo); + node->right = buildTree(elements + lo, elementCount - lo); + + const BVHNode *left = node->left; + const BVHNode *right = node->right; + node->minimum.rx() = qMin(left->minimum.x(), right->minimum.x()); + node->minimum.ry() = qMin(left->minimum.y(), right->minimum.y()); + node->maximum.rx() = qMax(left->maximum.x(), right->maximum.x()); + node->maximum.ry() = qMax(left->maximum.y(), right->maximum.y()); + + return node; +} + +bool PathSimplifier::intersectNodes(QDataBuffer &elements, BVHNode *elementNode, + BVHNode *treeNode) +{ + if (elementNode->minimum.x() >= treeNode->maximum.x() + || elementNode->minimum.y() >= treeNode->maximum.y() + || elementNode->maximum.x() <= treeNode->minimum.x() + || elementNode->maximum.y() <= treeNode->minimum.y()) + { + return false; + } + + Q_ASSERT(elementNode->type == BVHNode::Leaf); + Element *element = elementNode->element; + Q_ASSERT(!element->processed); + + if (treeNode->type == BVHNode::Leaf) { + Element *nodeElement = treeNode->element; + if (!nodeElement->processed) + return false; + + if (treeNode->element == elementNode->element) + return false; + + if (equalElements(treeNode->element, elementNode->element)) + return false; // element doesn't split itself. + + if (element->degree == Element::Line && nodeElement->degree == Element::Line) { + const QPoint &u1 = m_points->at(element->indices[0]); + const QPoint &u2 = m_points->at(element->indices[1]); + const QPoint &v1 = m_points->at(nodeElement->indices[0]); + const QPoint &v2 = m_points->at(nodeElement->indices[1]); + IntersectionPoint intersection = intersectionPoint(u1, u2, v1, v2); + if (!intersection.isValid()) + return false; + + Q_ASSERT(intersection.x.integer >= qMin(u1.x(), u2.x())); + Q_ASSERT(intersection.y.integer >= qMin(u1.y(), u2.y())); + Q_ASSERT(intersection.x.integer >= qMin(v1.x(), v2.x())); + Q_ASSERT(intersection.y.integer >= qMin(v1.y(), v2.y())); + + Q_ASSERT(intersection.x.integer <= qMax(u1.x(), u2.x())); + Q_ASSERT(intersection.y.integer <= qMax(u1.y(), u2.y())); + Q_ASSERT(intersection.x.integer <= qMax(v1.x(), v2.x())); + Q_ASSERT(intersection.y.integer <= qMax(v1.y(), v2.y())); + + m_points->add(intersection.round()); + splitLineAt(elements, treeNode, m_points->size() - 1, !intersection.isAccurate()); + return splitLineAt(elements, elementNode, m_points->size() - 1, false); + } else { + QVarLengthArray axes; + appendSeparatingAxes(axes, elementNode->element); + appendSeparatingAxes(axes, treeNode->element); + for (int i = 0; i < axes.size(); ++i) { + QPair range1 = calculateSeparatingAxisRange(axes.at(i), elementNode->element); + QPair range2 = calculateSeparatingAxisRange(axes.at(i), treeNode->element); + if (range1.first >= range2.second || range1.second <= range2.first) { + return false; // Separating axis found. + } + } + // Bounding areas overlap. + if (nodeElement->degree > Element::Line) + splitCurve(elements, treeNode); + if (element->degree > Element::Line) { + splitCurve(elements, elementNode); + } else { + // The element was not split, so it can be processed further. + if (intersectNodes(elements, elementNode, treeNode->left)) + return true; + if (intersectNodes(elements, elementNode, treeNode->right)) + return true; + return false; + } + return true; + } + } else { + if (intersectNodes(elements, elementNode, treeNode->left)) + return true; + if (intersectNodes(elements, elementNode, treeNode->right)) + return true; + return false; + } +} + +bool PathSimplifier::equalElements(const Element *e1, const Element *e2) +{ + Q_ASSERT(e1 != e2); + if (e1->degree != e2->degree) + return false; + + // Possibly equal and in the same direction. + bool equalSame = true; + for (int i = 0; i <= e1->degree; ++i) + equalSame &= m_points->at(e1->indices[i]) == m_points->at(e2->indices[i]); + + // Possibly equal and in opposite directions. + bool equalOpposite = true; + for (int i = 0; i <= e1->degree; ++i) + equalOpposite &= m_points->at(e1->indices[e1->degree - i]) == m_points->at(e2->indices[i]); + + return equalSame || equalOpposite; +} + +bool PathSimplifier::splitLineAt(QDataBuffer &elements, BVHNode *node, + quint32 pointIndex, bool processAgain) +{ + Q_ASSERT(node->type == BVHNode::Leaf); + Element *element = node->element; + Q_ASSERT(element->degree == Element::Line); + const QPoint &u = m_points->at(element->indices[0]); + const QPoint &v = m_points->at(element->indices[1]); + const QPoint &p = m_points->at(pointIndex); + if (u == p || v == p) + return false; // No split needed. + + if (processAgain) + element->processed = false; // Needs to be processed again. + + Element *first = node->element; + Element *second = m_elementAllocator.newElement(); + *second = *first; + first->indices[1] = second->indices[0] = pointIndex; + first->middle.rx() = (u.x() + p.x()) >> 1; + first->middle.ry() = (u.y() + p.y()) >> 1; + second->middle.rx() = (v.x() + p.x()) >> 1; + second->middle.ry() = (v.y() + p.y()) >> 1; + m_elements.add(second); + + BVHNode *left = m_bvh.newNode(); + BVHNode *right = m_bvh.newNode(); + left->type = right->type = BVHNode::Leaf; + left->element = first; + right->element = second; + left->minimum = right->minimum = node->minimum; + left->maximum = right->maximum = node->maximum; + if (u.x() < v.x()) + left->maximum.rx() = right->minimum.rx() = p.x(); + else + left->minimum.rx() = right->maximum.rx() = p.x(); + if (u.y() < v.y()) + left->maximum.ry() = right->minimum.ry() = p.y(); + else + left->minimum.ry() = right->maximum.ry() = p.y(); + left->element->bvhNode = left; + right->element->bvhNode = right; + + node->type = BVHNode::Split; + node->left = left; + node->right = right; + + if (!first->processed) { + elements.add(left->element); + elements.add(right->element); + } + return true; +} + +void PathSimplifier::appendSeparatingAxes(QVarLengthArray &axes, Element *element) +{ + switch (element->degree) { + case Element::Cubic: + { + const QPoint &u = m_points->at(element->indices[0]); + const QPoint &v = m_points->at(element->indices[1]); + const QPoint &w = m_points->at(element->indices[2]); + const QPoint &q = m_points->at(element->indices[3]); + QPoint ns[] = { + QPoint(u.y() - v.y(), v.x() - u.x()), + QPoint(v.y() - w.y(), w.x() - v.x()), + QPoint(w.y() - q.y(), q.x() - w.x()), + QPoint(q.y() - u.y(), u.x() - q.x()), + QPoint(u.y() - w.y(), w.x() - u.x()), + QPoint(v.y() - q.y(), q.x() - v.x()) + }; + for (int i = 0; i < 6; ++i) { + if (ns[i].x() || ns[i].y()) + axes.append(ns[i]); + } + } + break; + case Element::Quadratic: + { + const QPoint &u = m_points->at(element->indices[0]); + const QPoint &v = m_points->at(element->indices[1]); + const QPoint &w = m_points->at(element->indices[2]); + QPoint ns[] = { + QPoint(u.y() - v.y(), v.x() - u.x()), + QPoint(v.y() - w.y(), w.x() - v.x()), + QPoint(w.y() - u.y(), u.x() - w.x()) + }; + for (int i = 0; i < 3; ++i) { + if (ns[i].x() || ns[i].y()) + axes.append(ns[i]); + } + } + break; + case Element::Line: + { + const QPoint &u = m_points->at(element->indices[0]); + const QPoint &v = m_points->at(element->indices[1]); + QPoint n(u.y() - v.y(), v.x() - u.x()); + if (n.x() || n.y()) + axes.append(n); + } + break; + default: + Q_ASSERT_X(0, "QSGPathSimplifier::appendSeparatingAxes", "Unexpected element type."); + break; + } +} + +QPair PathSimplifier::calculateSeparatingAxisRange(const QPoint &axis, Element *element) +{ + QPair range(0x7fffffff, -0x7fffffff); + for (int i = 0; i <= element->degree; ++i) { + const QPoint &p = m_points->at(element->indices[i]); + int dist = dot(axis, p); + range.first = qMin(range.first, dist); + range.second = qMax(range.second, dist); + } + return range; +} + +void PathSimplifier::splitCurve(QDataBuffer &elements, BVHNode *node) +{ + Q_ASSERT(node->type == BVHNode::Leaf); + + Element *first = node->element; + Element *second = m_elementAllocator.newElement(); + *second = *first; + m_elements.add(second); + Q_ASSERT(first->degree > Element::Line); + + bool accurate = true; + const QPoint &u = m_points->at(first->indices[0]); + const QPoint &v = m_points->at(first->indices[1]); + const QPoint &w = m_points->at(first->indices[2]); + + if (first->degree == Element::Quadratic) { + QPoint pts[3]; + accurate = splitQuadratic(u, v, w, pts); + int pointIndex = m_points->size(); + m_points->add(pts[1]); + accurate &= setElementToQuadratic(first, first->indices[0], pts[0], pointIndex); + accurate &= setElementToQuadratic(second, pointIndex, pts[2], second->indices[2]); + } else { + Q_ASSERT(first->degree == Element::Cubic); + const QPoint &q = m_points->at(first->indices[3]); + QPoint pts[5]; + accurate = splitCubic(u, v, w, q, pts); + int pointIndex = m_points->size(); + m_points->add(pts[2]); + accurate &= setElementToCubic(first, first->indices[0], pts[0], pts[1], pointIndex); + accurate &= setElementToCubic(second, pointIndex, pts[3], pts[4], second->indices[3]); + } + + if (!accurate) + first->processed = second->processed = false; // Needs to be processed again. + + BVHNode *left = m_bvh.newNode(); + BVHNode *right = m_bvh.newNode(); + left->type = right->type = BVHNode::Leaf; + left->element = first; + right->element = second; + + left->minimum.rx() = left->minimum.ry() = right->minimum.rx() = right->minimum.ry() = INT_MAX; + left->maximum.rx() = left->maximum.ry() = right->maximum.rx() = right->maximum.ry() = INT_MIN; + + for (int i = 0; i <= first->degree; ++i) { + QPoint &p = m_points->at(first->indices[i]); + left->minimum.rx() = qMin(left->minimum.x(), p.x()); + left->minimum.ry() = qMin(left->minimum.y(), p.y()); + left->maximum.rx() = qMax(left->maximum.x(), p.x()); + left->maximum.ry() = qMax(left->maximum.y(), p.y()); + } + for (int i = 0; i <= second->degree; ++i) { + QPoint &p = m_points->at(second->indices[i]); + right->minimum.rx() = qMin(right->minimum.x(), p.x()); + right->minimum.ry() = qMin(right->minimum.y(), p.y()); + right->maximum.rx() = qMax(right->maximum.x(), p.x()); + right->maximum.ry() = qMax(right->maximum.y(), p.y()); + } + left->element->bvhNode = left; + right->element->bvhNode = right; + + node->type = BVHNode::Split; + node->left = left; + node->right = right; + + if (!first->processed) { + elements.add(left->element); + elements.add(right->element); + } +} + +bool PathSimplifier::setElementToQuadratic(Element *element, quint32 pointIndex1, + const QPoint &ctrl, quint32 pointIndex2) +{ + const QPoint &p1 = m_points->at(pointIndex1); + const QPoint &p2 = m_points->at(pointIndex2); + if (flattenQuadratic(p1, ctrl, p2)) { + // Insert line. + element->degree = Element::Line; + element->indices[0] = pointIndex1; + element->indices[1] = pointIndex2; + element->middle.rx() = (p1.x() + p2.x()) >> 1; + element->middle.ry() = (p1.y() + p2.y()) >> 1; + return false; + } else { + // Insert bezier. + element->degree = Element::Quadratic; + element->indices[0] = pointIndex1; + element->indices[1] = m_points->size(); + element->indices[2] = pointIndex2; + element->middle.rx() = (p1.x() + ctrl.x() + p2.x()) / 3; + element->middle.ry() = (p1.y() + ctrl.y() + p2.y()) / 3; + m_points->add(ctrl); + return true; + } +} + +bool PathSimplifier::setElementToCubic(Element *element, quint32 pointIndex1, const QPoint &v, + const QPoint &w, quint32 pointIndex2) +{ + const QPoint &u = m_points->at(pointIndex1); + const QPoint &q = m_points->at(pointIndex2); + if (flattenCubic(u, v, w, q)) { + // Insert line. + element->degree = Element::Line; + element->indices[0] = pointIndex1; + element->indices[1] = pointIndex2; + element->middle.rx() = (u.x() + q.x()) >> 1; + element->middle.ry() = (u.y() + q.y()) >> 1; + return false; + } else { + // Insert bezier. + element->degree = Element::Cubic; + element->indices[0] = pointIndex1; + element->indices[1] = m_points->size(); + element->indices[2] = m_points->size() + 1; + element->indices[3] = pointIndex2; + element->middle.rx() = (u.x() + v.x() + w.x() + q.x()) >> 2; + element->middle.ry() = (u.y() + v.y() + w.y() + q.y()) >> 2; + m_points->add(v); + m_points->add(w); + return true; + } +} + +void PathSimplifier::setElementToCubicAndSimplify(Element *element, quint32 pointIndex1, + const QPoint &v, const QPoint &w, + quint32 pointIndex2) +{ + const QPoint &u = m_points->at(pointIndex1); + const QPoint &q = m_points->at(pointIndex2); + if (flattenCubic(u, v, w, q)) { + // Insert line. + element->degree = Element::Line; + element->indices[0] = pointIndex1; + element->indices[1] = pointIndex2; + element->middle.rx() = (u.x() + q.x()) >> 1; + element->middle.ry() = (u.y() + q.y()) >> 1; + return; + } + + bool intersecting = (u == q) || intersectionPoint(u, v, w, q).isValid(); + if (!intersecting) { + // Insert bezier. + element->degree = Element::Cubic; + element->indices[0] = pointIndex1; + element->indices[1] = m_points->size(); + element->indices[2] = m_points->size() + 1; + element->indices[3] = pointIndex2; + element->middle.rx() = (u.x() + v.x() + w.x() + q.x()) >> 2; + element->middle.ry() = (u.y() + v.y() + w.y() + q.y()) >> 2; + m_points->add(v); + m_points->add(w); + return; + } + + QPoint pts[5]; + splitCubic(u, v, w, q, pts); + int pointIndex = m_points->size(); + m_points->add(pts[2]); + Element *element2 = m_elementAllocator.newElement(); + m_elements.add(element2); + setElementToCubicAndSimplify(element, pointIndex1, pts[0], pts[1], pointIndex); + setElementToCubicAndSimplify(element2, pointIndex, pts[3], pts[4], pointIndex2); +} + +PathSimplifier::RBNode *PathSimplifier::findElementLeftOf(const Element *element, + const QPair &bounds) +{ + if (!m_elementList.root) + return 0; + RBNode *current = bounds.first; + Q_ASSERT(!current || !elementIsLeftOf(element, current->data)); + if (!current) + current = m_elementList.front(m_elementList.root); + Q_ASSERT(current); + RBNode *result = 0; + while (current != bounds.second && !elementIsLeftOf(element, current->data)) { + result = current; + current = m_elementList.next(current); + } + return result; +} + +bool PathSimplifier::elementIsLeftOf(const Element *left, const Element *right) +{ + const QPoint &leftU = m_points->at(left->upperIndex()); + const QPoint &leftL = m_points->at(left->lowerIndex()); + const QPoint &rightU = m_points->at(right->upperIndex()); + const QPoint &rightL = m_points->at(right->lowerIndex()); + Q_ASSERT(leftL >= rightU && rightL >= leftU); + if (leftU.x() < qMin(rightL.x(), rightU.x())) + return true; + if (leftU.x() > qMax(rightL.x(), rightU.x())) + return false; + int d = pointDistanceFromLine(leftU, rightL, rightU); + // d < 0: left, d > 0: right, d == 0: on top + if (d == 0) { + d = pointDistanceFromLine(leftL, rightL, rightU); + if (d == 0) { + if (right->degree > Element::Line) { + d = pointDistanceFromLine(leftL, rightL, m_points->at(right->indices[1])); + if (d == 0) + d = pointDistanceFromLine(leftL, rightL, m_points->at(right->indices[2])); + } else if (left->degree > Element::Line) { + d = pointDistanceFromLine(m_points->at(left->indices[1]), rightL, rightU); + if (d == 0) + d = pointDistanceFromLine(m_points->at(left->indices[2]), rightL, rightU); + } + } + } + return d < 0; +} + +QPair PathSimplifier::outerBounds(const QPoint &point) +{ + RBNode *current = m_elementList.root; + QPair result(0, 0); + + while (current) { + const Element *element = current->data; + Q_ASSERT(element->edgeNode == current); + const QPoint &v1 = m_points->at(element->lowerIndex()); + const QPoint &v2 = m_points->at(element->upperIndex()); + Q_ASSERT(point >= v2 && point <= v1); + if (point == v1 || point == v2) + break; + int d = pointDistanceFromLine(point, v1, v2); + if (d == 0) { + if (element->degree == Element::Line) + break; + d = pointDistanceFromLine(point, v1, m_points->at(element->indices[1])); + if (d == 0) + d = pointDistanceFromLine(point, v1, m_points->at(element->indices[2])); + Q_ASSERT(d != 0); + } + if (d < 0) { + result.second = current; + current = current->left; + } else { + result.first = current; + current = current->right; + } + } + + if (!current) + return result; + + RBNode *mid = current; + + current = mid->left; + while (current) { + const Element *element = current->data; + Q_ASSERT(element->edgeNode == current); + const QPoint &v1 = m_points->at(element->lowerIndex()); + const QPoint &v2 = m_points->at(element->upperIndex()); + Q_ASSERT(point >= v2 && point <= v1); + bool equal = (point == v1 || point == v2); + if (!equal) { + int d = pointDistanceFromLine(point, v1, v2); + Q_ASSERT(d >= 0); + equal = (d == 0 && element->degree == Element::Line); + } + if (equal) { + current = current->left; + } else { + result.first = current; + current = current->right; + } + } + + current = mid->right; + while (current) { + const Element *element = current->data; + Q_ASSERT(element->edgeNode == current); + const QPoint &v1 = m_points->at(element->lowerIndex()); + const QPoint &v2 = m_points->at(element->upperIndex()); + Q_ASSERT(point >= v2 && point <= v1); + bool equal = (point == v1 || point == v2); + if (!equal) { + int d = pointDistanceFromLine(point, v1, v2); + Q_ASSERT(d <= 0); + equal = (d == 0 && element->degree == Element::Line); + } + if (equal) { + current = current->right; + } else { + result.second = current; + current = current->left; + } + } + + return result; +} + +inline bool PathSimplifier::flattenQuadratic(const QPoint &u, const QPoint &v, const QPoint &w) +{ + QPoint deltas[2] = { v - u, w - v }; + int d = qAbs(cross(deltas[0], deltas[1])); + int l = qAbs(deltas[0].x()) + qAbs(deltas[0].y()) + qAbs(deltas[1].x()) + qAbs(deltas[1].y()); + return d < (Q_FIXED_POINT_SCALE * Q_FIXED_POINT_SCALE * 3 / 2) || l <= Q_FIXED_POINT_SCALE * 2; +} + +inline bool PathSimplifier::flattenCubic(const QPoint &u, const QPoint &v, + const QPoint &w, const QPoint &q) +{ + QPoint deltas[] = { v - u, w - v, q - w, q - u }; + int d = qAbs(cross(deltas[0], deltas[1])) + qAbs(cross(deltas[1], deltas[2])) + + qAbs(cross(deltas[0], deltas[3])) + qAbs(cross(deltas[3], deltas[2])); + int l = qAbs(deltas[0].x()) + qAbs(deltas[0].y()) + qAbs(deltas[1].x()) + qAbs(deltas[1].y()) + + qAbs(deltas[2].x()) + qAbs(deltas[2].y()); + return d < (Q_FIXED_POINT_SCALE * Q_FIXED_POINT_SCALE * 3) || l <= Q_FIXED_POINT_SCALE * 2; +} + +inline bool PathSimplifier::splitQuadratic(const QPoint &u, const QPoint &v, + const QPoint &w, QPoint *result) +{ + result[0] = u + v; + result[2] = v + w; + result[1] = result[0] + result[2]; + bool accurate = ((result[0].x() | result[0].y() | result[2].x() | result[2].y()) & 1) == 0 + && ((result[1].x() | result[1].y()) & 3) == 0; + result[0].rx() >>= 1; + result[0].ry() >>= 1; + result[1].rx() >>= 2; + result[1].ry() >>= 2; + result[2].rx() >>= 1; + result[2].ry() >>= 1; + return accurate; +} + +inline bool PathSimplifier::splitCubic(const QPoint &u, const QPoint &v, + const QPoint &w, const QPoint &q, QPoint *result) +{ + result[0] = u + v; + result[2] = v + w; + result[4] = w + q; + result[1] = result[0] + result[2]; + result[3] = result[2] + result[4]; + result[2] = result[1] + result[3]; + bool accurate = ((result[0].x() | result[0].y() | result[4].x() | result[4].y()) & 1) == 0 + && ((result[1].x() | result[1].y() | result[3].x() | result[3].y()) & 3) == 0 + && ((result[2].x() | result[2].y()) & 7) == 0; + result[0].rx() >>= 1; + result[0].ry() >>= 1; + result[1].rx() >>= 2; + result[1].ry() >>= 2; + result[2].rx() >>= 3; + result[2].ry() >>= 3; + result[3].rx() >>= 2; + result[3].ry() >>= 2; + result[4].rx() >>= 1; + result[4].ry() >>= 1; + return accurate; +} + +inline void PathSimplifier::subDivQuadratic(const QPoint &u, const QPoint &v, const QPoint &w) +{ + if (flattenQuadratic(u, v, w)) + return; + QPoint pts[3]; + splitQuadratic(u, v, w, pts); + subDivQuadratic(u, pts[0], pts[1]); + m_indices->add(m_points->size()); + m_points->add(pts[1]); + subDivQuadratic(pts[1], pts[2], w); +} + +inline void PathSimplifier::subDivCubic(const QPoint &u, const QPoint &v, + const QPoint &w, const QPoint &q) +{ + if (flattenCubic(u, v, w, q)) + return; + QPoint pts[5]; + splitCubic(u, v, w, q, pts); + subDivCubic(u, pts[0], pts[1], pts[2]); + m_indices->add(m_points->size()); + m_points->add(pts[2]); + subDivCubic(pts[2], pts[3], pts[4], q); +} + +void PathSimplifier::sortEvents(Event *events, int count) +{ + // Bucket sort + insertion sort. + Q_ASSERT(count > 0); + QDataBuffer buffer(count); + buffer.resize(count); + QScopedArrayPointer bins(new int[count]); + int counts[0x101]; + memset(counts, 0, sizeof(counts)); + + int minimum, maximum; + minimum = maximum = events[0].point.y(); + for (int i = 1; i < count; ++i) { + minimum = qMin(minimum, events[i].point.y()); + maximum = qMax(maximum, events[i].point.y()); + } + + for (int i = 0; i < count; ++i) { + bins[i] = ((maximum - events[i].point.y()) << 8) / (maximum - minimum + 1); + Q_ASSERT(bins[i] >= 0 && bins[i] < 0x100); + ++counts[bins[i]]; + } + + for (int i = 1; i < 0x100; ++i) + counts[i] += counts[i - 1]; + counts[0x100] = counts[0xff]; + Q_ASSERT(counts[0x100] == count); + + for (int i = 0; i < count; ++i) + buffer.at(--counts[bins[i]]) = events[i]; + + int j = 0; + for (int i = 0; i < 0x100; ++i) { + for (; j < counts[i + 1]; ++j) { + int k = j; + while (k > 0 && (buffer.at(j) < events[k - 1])) { + events[k] = events[k - 1]; + --k; + } + events[k] = buffer.at(j); + } + } +} + +} // end anonymous namespace + + +void qSimplifyPath(const QVectorPath &path, QDataBuffer &vertices, + QDataBuffer &indices, const QTransform &matrix) +{ + PathSimplifier(path, vertices, indices, matrix); +} + +void qSimplifyPath(const QPainterPath &path, QDataBuffer &vertices, + QDataBuffer &indices, const QTransform &matrix) +{ + qSimplifyPath(qtVectorPathForPath(path), vertices, indices, matrix); +} + + +QT_END_NAMESPACE diff --git a/src/gui/painting/qpathsimplifier_p.h b/src/gui/painting/qpathsimplifier_p.h new file mode 100644 index 00000000000..9941bd21f21 --- /dev/null +++ b/src/gui/painting/qpathsimplifier_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtDeclarative 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 QPATHSIMPLIFIER_P_H +#define QPATHSIMPLIFIER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +// The returned vertices are in 8:8 fixed point format. The path is assumed to be in the range (-128, 128)x(-128, 128). +void qSimplifyPath(const QVectorPath &path, QDataBuffer &vertices, QDataBuffer &indices, const QTransform &matrix = QTransform()); +void qSimplifyPath(const QPainterPath &path, QDataBuffer &vertices, QDataBuffer &indices, const QTransform &matrix = QTransform()); + +QT_END_NAMESPACE + +#endif diff --git a/src/gui/text/qdistancefield.cpp b/src/gui/text/qdistancefield.cpp new file mode 100644 index 00000000000..fb06a26c8f1 --- /dev/null +++ b/src/gui/text/qdistancefield.cpp @@ -0,0 +1,762 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtDeclarative 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 "qdistancefield_p.h" +#include +#include +#include + +QT_BEGIN_NAMESPACE + +namespace +{ + enum FillHDir + { + LeftToRight, + RightToLeft + }; + + enum FillVDir + { + TopDown, + BottomUp + }; + + enum FillClip + { + NoClip, + Clip + }; +} + +template +inline void fillLine(qint32 *, int, int, int, qint32, qint32) +{ +} + +template <> +inline void fillLine(qint32 *line, int width, int lx, int rx, qint32 d, qint32 dd) +{ + int fromX = qMax(0, lx >> 8); + int toX = qMin(width, rx >> 8); + int x = toX - fromX; + if (x <= 0) + return; + qint32 val = d + (((fromX << 8) + 0xff - lx) * dd >> 8); + line += fromX; + do { + *line = abs(val) < abs(*line) ? val : *line; + val += dd; + ++line; + } while (--x); +} + +template <> +inline void fillLine(qint32 *line, int width, int lx, int rx, qint32 d, qint32 dd) +{ + int fromX = qMax(0, lx >> 8); + int toX = qMin(width, rx >> 8); + int x = toX - fromX; + if (x <= 0) + return; + qint32 val = d + (((toX << 8) + 0xff - rx) * dd >> 8); + line += toX; + do { + val -= dd; + --line; + *line = abs(val) < abs(*line) ? val : *line; + } while (--x); +} + +template <> +inline void fillLine(qint32 *line, int, int lx, int rx, qint32 d, qint32 dd) +{ + int fromX = lx >> 8; + int toX = rx >> 8; + int x = toX - fromX; + if (x <= 0) + return; + qint32 val = d + ((~lx & 0xff) * dd >> 8); + line += fromX; + do { + *line = abs(val) < abs(*line) ? val : *line; + val += dd; + ++line; + } while (--x); +} + +template <> +inline void fillLine(qint32 *line, int, int lx, int rx, qint32 d, qint32 dd) +{ + int fromX = lx >> 8; + int toX = rx >> 8; + int x = toX - fromX; + if (x <= 0) + return; + qint32 val = d + ((~rx & 0xff) * dd >> 8); + line += toX; + do { + val -= dd; + --line; + *line = abs(val) < abs(*line) ? val : *line; + } while (--x); +} + +template +inline void fillLines(qint32 *bits, int width, int height, int upperY, int lowerY, + int &lx, int ldx, int &rx, int rdx, qint32 &d, qint32 ddy, qint32 ddx) +{ + Q_UNUSED(height); + Q_ASSERT(upperY < lowerY); + int y = lowerY - upperY; + if (vDir == TopDown) { + qint32 *line = bits + upperY * width; + do { + fillLine(line, width, lx, rx, d, ddx); + lx += ldx; + d += ddy; + rx += rdx; + line += width; + } while (--y); + } else { + qint32 *line = bits + lowerY * width; + do { + lx -= ldx; + d -= ddy; + rx -= rdx; + line -= width; + fillLine(line, width, lx, rx, d, ddx); + } while (--y); + } +} + +template +void drawTriangle(qint32 *bits, int width, int height, const QPoint *center, + const QPoint *v1, const QPoint *v2, qint32 value) +{ + const int y1 = clip == Clip ? qBound(0, v1->y() >> 8, height) : v1->y() >> 8; + const int y2 = clip == Clip ? qBound(0, v2->y() >> 8, height) : v2->y() >> 8; + const int yC = clip == Clip ? qBound(0, center->y() >> 8, height) : center->y() >> 8; + + const int v1Frac = clip == Clip ? (y1 << 8) + 0xff - v1->y() : ~v2->y() & 0xff; + const int v2Frac = clip == Clip ? (y2 << 8) + 0xff - v2->y() : ~v1->y() & 0xff; + const int centerFrac = clip == Clip ? (yC << 8) + 0xff - center->y() : ~center->y() & 0xff; + + int dx1 = 0, x1 = 0, dx2 = 0, x2 = 0; + qint32 dd1, d1, dd2, d2; + if (v1->y() != center->y()) { + dx1 = ((v1->x() - center->x()) << 8) / (v1->y() - center->y()); + x1 = center->x() + centerFrac * (v1->x() - center->x()) / (v1->y() - center->y()); + } + if (v2->y() != center->y()) { + dx2 = ((v2->x() - center->x()) << 8) / (v2->y() - center->y()); + x2 = center->x() + centerFrac * (v2->x() - center->x()) / (v2->y() - center->y()); + } + + const qint32 div = (v2->x() - center->x()) * (v1->y() - center->y()) + - (v2->y() - center->y()) * (v1->x() - center->x()); + const qint32 dd = div ? qint32((qint64(value * (v1->y() - v2->y())) << 8) / div) : 0; + + if (y2 < yC) { + if (y1 < yC) { + // Center at the bottom. + if (y2 < y1) { + // y2 < y1 < yC + // Long right edge. + d1 = centerFrac * value / (v1->y() - center->y()); + dd1 = ((value << 8) / (v1->y() - center->y())); + fillLines(bits, width, height, y1, yC, x1, dx1, + x2, dx2, d1, dd1, dd); + dx1 = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y()); + x1 = v1->x() + v1Frac * (v1->x() - v2->x()) / (v1->y() - v2->y()); + fillLines(bits, width, height, y2, y1, x1, dx1, + x2, dx2, value, 0, dd); + } else { + // y1 <= y2 < yC + // Long left edge. + d2 = centerFrac * value / (v2->y() - center->y()); + dd2 = ((value << 8) / (v2->y() - center->y())); + fillLines(bits, width, height, y2, yC, x1, dx1, + x2, dx2, d2, dd2, dd); + if (y1 != y2) { + dx2 = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y()); + x2 = v2->x() + v2Frac * (v1->x() - v2->x()) / (v1->y() - v2->y()); + fillLines(bits, width, height, y1, y2, x1, dx1, + x2, dx2, value, 0, dd); + } + } + } else { + // y2 < yC <= y1 + // Center to the right. + int dx = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y()); + int xUp, xDn; + xUp = xDn = v2->x() + (clip == Clip ? (yC << 8) + 0xff - v2->y() + : (center->y() | 0xff) - v2->y()) + * (v1->x() - v2->x()) / (v1->y() - v2->y()); + fillLines(bits, width, height, y2, yC, xUp, dx, + x2, dx2, value, 0, dd); + if (yC != y1) + fillLines(bits, width, height, yC, y1, xDn, dx, + x1, dx1, value, 0, dd); + } + } else { + if (y1 < yC) { + // y1 < yC <= y2 + // Center to the left. + int dx = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y()); + int xUp, xDn; + xUp = xDn = v1->x() + (clip == Clip ? (yC << 8) + 0xff - v1->y() + : (center->y() | 0xff) - v1->y()) + * (v1->x() - v2->x()) / (v1->y() - v2->y()); + fillLines(bits, width, height, y1, yC, x1, dx1, + xUp, dx, value, 0, dd); + if (yC != y2) + fillLines(bits, width, height, yC, y2, x2, dx2, + xDn, dx, value, 0, dd); + } else { + // Center at the top. + if (y2 < y1) { + // yC <= y2 < y1 + // Long right edge. + if (yC != y2) { + d2 = centerFrac * value / (v2->y() - center->y()); + dd2 = ((value << 8) / (v2->y() - center->y())); + fillLines(bits, width, height, yC, y2, x2, dx2, + x1, dx1, d2, dd2, dd); + } + dx2 = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y()); + x2 = v2->x() + v2Frac * (v1->x() - v2->x()) / (v1->y() - v2->y()); + fillLines(bits, width, height, y2, y1, x2, dx2, + x1, dx1, value, 0, dd); + } else { + // Long left edge. + // yC <= y1 <= y2 + if (yC != y1) { + d1 = centerFrac * value / (v1->y() - center->y()); + dd1 = ((value << 8) / (v1->y() - center->y())); + fillLines(bits, width, height, yC, y1, x2, dx2, + x1, dx1, d1, dd1, dd); + } + if (y1 != y2) { + dx1 = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y()); + x1 = v1->x() + v1Frac * (v1->x() - v2->x()) / (v1->y() - v2->y()); + fillLines(bits, width, height, y1, y2, x2, dx2, + x1, dx1, value, 0, dd); + } + } + } + } +} + +template +void drawRectangle(qint32 *bits, int width, int height, + const QPoint *int1, const QPoint *center1, const QPoint *ext1, + const QPoint *int2, const QPoint *center2, const QPoint *ext2, + qint32 extValue) +{ + if (center1->y() > center2->y()) { + qSwap(center1, center2); + qSwap(int1, ext2); + qSwap(ext1, int2); + extValue = -extValue; + } + + Q_ASSERT(ext1->x() - center1->x() == center1->x() - int1->x()); + Q_ASSERT(ext1->y() - center1->y() == center1->y() - int1->y()); + Q_ASSERT(ext2->x() - center2->x() == center2->x() - int2->x()); + Q_ASSERT(ext2->y() - center2->y() == center2->y() - int2->y()); + + const int yc1 = clip == Clip ? qBound(0, center1->y() >> 8, height) : center1->y() >> 8; + const int yc2 = clip == Clip ? qBound(0, center2->y() >> 8, height) : center2->y() >> 8; + const int yi1 = clip == Clip ? qBound(0, int1->y() >> 8, height) : int1->y() >> 8; + const int yi2 = clip == Clip ? qBound(0, int2->y() >> 8, height) : int2->y() >> 8; + const int ye1 = clip == Clip ? qBound(0, ext1->y() >> 8, height) : ext1->y() >> 8; + const int ye2 = clip == Clip ? qBound(0, ext2->y() >> 8, height) : ext2->y() >> 8; + + const int center1Frac = clip == Clip ? (yc1 << 8) + 0xff - center1->y() : ~center1->y() & 0xff; + const int center2Frac = clip == Clip ? (yc2 << 8) + 0xff - center2->y() : ~center2->y() & 0xff; + const int int1Frac = clip == Clip ? (yi1 << 8) + 0xff - int1->y() : ~int1->y() & 0xff; + const int ext1Frac = clip == Clip ? (ye1 << 8) + 0xff - ext1->y() : ~ext1->y() & 0xff; + + int dxC = 0, dxE = 0; // cap slope, edge slope + qint32 ddC = 0; + if (ext1->y() != int1->y()) { + dxC = ((ext1->x() - int1->x()) << 8) / (ext1->y() - int1->y()); + ddC = (extValue << 9) / (ext1->y() - int1->y()); + } + if (ext1->y() != ext2->y()) + dxE = ((ext1->x() - ext2->x()) << 8) / (ext1->y() - ext2->y()); + + const qint32 div = (ext1->x() - int1->x()) * (ext2->y() - int1->y()) + - (ext1->y() - int1->y()) * (ext2->x() - int1->x()); + const qint32 dd = div ? qint32((qint64(extValue * (ext2->y() - ext1->y())) << 9) / div) : 0; + + int xe1, xe2, xc1, xc2; + qint32 d; + + qint32 intValue = -extValue; + + if (center2->x() < center1->x()) { + // Leaning to the right. '/' + if (int1->y() < ext2->y()) { + // Mostly vertical. + Q_ASSERT(ext1->y() != ext2->y()); + xe1 = ext1->x() + ext1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y()); + xe2 = int1->x() + int1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y()); + if (ye1 != yi1) { + xc2 = center1->x() + center1Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y()); + xc2 += (ye1 - yc1) * dxC; + fillLines(bits, width, height, ye1, yi1, xe1, dxE, + xc2, dxC, extValue, 0, dd); + } + if (yi1 != ye2) + fillLines(bits, width, height, yi1, ye2, xe1, dxE, + xe2, dxE, extValue, 0, dd); + if (ye2 != yi2) { + xc1 = center2->x() + center2Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y()); + xc1 += (ye2 - yc2) * dxC; + fillLines(bits, width, height, ye2, yi2, xc1, dxC, + xe2, dxE, intValue, 0, dd); + } + } else { + // Mostly horizontal. + Q_ASSERT(ext1->y() != int1->y()); + xc1 = center2->x() + center2Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y()); + xc2 = center1->x() + center1Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y()); + xc1 += (ye2 - yc2) * dxC; + xc2 += (ye1 - yc1) * dxC; + if (ye1 != ye2) { + xe1 = ext1->x() + ext1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y()); + fillLines(bits, width, height, ye1, ye2, xe1, dxE, + xc2, dxC, extValue, 0, dd); + } + if (ye2 != yi1) { + d = (clip == Clip ? (ye2 << 8) + 0xff - center2->y() + : (ext2->y() | 0xff) - center2->y()) + * 2 * extValue / (ext1->y() - int1->y()); + fillLines(bits, width, height, ye2, yi1, xc1, dxC, + xc2, dxC, d, ddC, dd); + } + if (yi1 != yi2) { + xe2 = int1->x() + int1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y()); + fillLines(bits, width, height, yi1, yi2, xc1, dxC, + xe2, dxE, intValue, 0, dd); + } + } + } else { + // Leaning to the left. '\' + if (ext1->y() < int2->y()) { + // Mostly vertical. + Q_ASSERT(ext1->y() != ext2->y()); + xe1 = ext1->x() + ext1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y()); + xe2 = int1->x() + int1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y()); + if (yi1 != ye1) { + xc1 = center1->x() + center1Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y()); + xc1 += (yi1 - yc1) * dxC; + fillLines(bits, width, height, yi1, ye1, xc1, dxC, + xe2, dxE, intValue, 0, dd); + } + if (ye1 != yi2) + fillLines(bits, width, height, ye1, yi2, xe1, dxE, + xe2, dxE, intValue, 0, dd); + if (yi2 != ye2) { + xc2 = center2->x() + center2Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y()); + xc2 += (yi2 - yc2) * dxC; + fillLines(bits, width, height, yi2, ye2, xe1, dxE, + xc2, dxC, extValue, 0, dd); + } + } else { + // Mostly horizontal. + Q_ASSERT(ext1->y() != int1->y()); + xc1 = center1->x() + center1Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y()); + xc2 = center2->x() + center2Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y()); + xc1 += (yi1 - yc1) * dxC; + xc2 += (yi2 - yc2) * dxC; + if (yi1 != yi2) { + xe2 = int1->x() + int1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y()); + fillLines(bits, width, height, yi1, yi2, xc1, dxC, + xe2, dxE, intValue, 0, dd); + } + if (yi2 != ye1) { + d = (clip == Clip ? (yi2 << 8) + 0xff - center2->y() + : (int2->y() | 0xff) - center2->y()) + * 2 * extValue / (ext1->y() - int1->y()); + fillLines(bits, width, height, yi2, ye1, xc1, dxC, + xc2, dxC, d, ddC, dd); + } + if (ye1 != ye2) { + xe1 = ext1->x() + ext1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y()); + fillLines(bits, width, height, ye1, ye2, xe1, dxE, + xc2, dxC, extValue, 0, dd); + } + } + } +} + +static void drawPolygons(qint32 *bits, int width, int height, const QPoint *vertices, + const quint32 *indices, int indexCount, qint32 value) +{ + Q_ASSERT(indexCount != 0); + Q_ASSERT(height <= 128); + QVarLengthArray scans[128]; + int first = 0; + for (int i = 1; i < indexCount; ++i) { + quint32 idx1 = indices[i - 1]; + quint32 idx2 = indices[i]; + Q_ASSERT(idx1 != quint32(-1)); + if (idx2 == quint32(-1)) { + idx2 = indices[first]; + Q_ASSERT(idx2 != quint32(-1)); + first = ++i; + } + const QPoint *v1 = &vertices[idx1]; + const QPoint *v2 = &vertices[idx2]; + if (v2->y() < v1->y()) + qSwap(v1, v2); + int fromY = qMax(0, v1->y() >> 8); + int toY = qMin(height, v2->y() >> 8); + if (fromY >= toY) + continue; + int dx = ((v2->x() - v1->x()) << 8) / (v2->y() - v1->y()); + int x = v1->x() + ((fromY << 8) + 0xff - v1->y()) * (v2->x() - v1->x()) / (v2->y() - v1->y()); + for (int y = fromY; y < toY; ++y) { + quint32 c = quint32(x >> 8); + if (c < quint32(width)) + scans[y].append(quint8(c)); + x += dx; + } + } + for (int i = 0; i < height; ++i) { + quint8 *scanline = scans[i].data(); + int size = scans[i].size(); + for (int j = 1; j < size; ++j) { + int k = j; + quint8 value = scanline[k]; + for (; k != 0 && value < scanline[k - 1]; --k) + scanline[k] = scanline[k - 1]; + scanline[k] = value; + } + qint32 *line = bits + i * width; + int j = 0; + for (; j + 1 < size; j += 2) { + for (quint8 x = scanline[j]; x < scanline[j + 1]; ++x) + line[x] = value; + } + if (j < size) { + for (int x = scanline[j]; x < width; ++x) + line[x] = value; + } + } +} + +static QImage makeDistanceField(int imgSize, const QPainterPath &path, int dfScale, int offs) +{ + QImage image(imgSize, imgSize, QImage::Format_Indexed8); + + if (path.isEmpty()) { + image.fill(0); + return image; + } + + QTransform transform; + transform.translate(offs, offs); + transform.scale(qreal(1) / dfScale, qreal(1) / dfScale); + + QDataBuffer pathIndices(0); + QDataBuffer pathVertices(0); + qSimplifyPath(path, pathVertices, pathIndices, transform); + + const qint32 interiorColor = -0x7f80; // 8:8 signed format, -127.5 + const qint32 exteriorColor = 0x7f80; // 8:8 signed format, 127.5 + + QScopedArrayPointer bits(new qint32[imgSize * imgSize]); + for (int i = 0; i < imgSize * imgSize; ++i) + bits[i] = exteriorColor; + + const qreal angleStep = qreal(15 * 3.141592653589793238 / 180); + const QPoint rotation(qRound(cos(angleStep) * 0x4000), + qRound(sin(angleStep) * 0x4000)); // 2:14 signed + + const quint32 *indices = pathIndices.data(); + QVarLengthArray normals; + QVarLengthArray vertices; + QVarLengthArray isConvex; + QVarLengthArray needsClipping; + + drawPolygons(bits.data(), imgSize, imgSize, pathVertices.data(), indices, pathIndices.size(), + interiorColor); + + int index = 0; + + while (index < pathIndices.size()) { + normals.clear(); + vertices.clear(); + needsClipping.clear(); + + // Find end of polygon. + int end = index; + while (indices[end] != quint32(-1)) + ++end; + + // Calculate vertex normals. + for (int next = index, prev = end - 1; next < end; prev = next++) { + quint32 fromVertexIndex = indices[prev]; + quint32 toVertexIndex = indices[next]; + + const QPoint &from = pathVertices.at(fromVertexIndex); + const QPoint &to = pathVertices.at(toVertexIndex); + + QPoint n(to.y() - from.y(), from.x() - to.x()); + if (n.x() == 0 && n.y() == 0) + continue; + int scale = qRound((offs << 16) / sqrt(qreal(n.x() * n.x() + n.y() * n.y()))); // 8:16 + n.rx() = n.x() * scale >> 8; + n.ry() = n.y() * scale >> 8; + normals.append(n); + QPoint v(to.x() + 0x7f, to.y() + 0x7f); + vertices.append(v); + needsClipping.append((to.x() < offs << 8) || (to.x() >= (imgSize - offs) << 8) + || (to.y() < offs << 8) || (to.y() >= (imgSize - offs) << 8)); + } + + isConvex.resize(normals.count()); + for (int next = 0, prev = normals.count() - 1; next < normals.count(); prev = next++) { + isConvex[prev] = normals.at(prev).x() * normals.at(next).y() + - normals.at(prev).y() * normals.at(next).x() < 0; + } + + // Draw quads. + for (int next = 0, prev = normals.count() - 1; next < normals.count(); prev = next++) { + QPoint n = normals.at(next); + QPoint intPrev = vertices.at(prev); + QPoint extPrev = vertices.at(prev); + QPoint intNext = vertices.at(next); + QPoint extNext = vertices.at(next); + + extPrev.rx() -= n.x(); + extPrev.ry() -= n.y(); + intPrev.rx() += n.x(); + intPrev.ry() += n.y(); + extNext.rx() -= n.x(); + extNext.ry() -= n.y(); + intNext.rx() += n.x(); + intNext.ry() += n.y(); + + if (needsClipping[prev] || needsClipping[next]) { + drawRectangle(bits.data(), imgSize, imgSize, + &intPrev, &vertices.at(prev), &extPrev, + &intNext, &vertices.at(next), &extNext, + exteriorColor); + } else { + drawRectangle(bits.data(), imgSize, imgSize, + &intPrev, &vertices.at(prev), &extPrev, + &intNext, &vertices.at(next), &extNext, + exteriorColor); + } + + if (isConvex.at(prev)) { + QPoint p = extPrev; + if (needsClipping[prev]) { + for (;;) { + QPoint rn((n.x() * rotation.x() - n.y() * rotation.y()) >> 14, + (n.y() * rotation.x() + n.x() * rotation.y()) >> 14); + n = rn; + if (n.x() * normals.at(prev).y() - n.y() * normals.at(prev).x() <= 0) { + p.rx() = vertices.at(prev).x() - normals.at(prev).x(); + p.ry() = vertices.at(prev).y() - normals.at(prev).y(); + drawTriangle(bits.data(), imgSize, imgSize, &vertices.at(prev), + &extPrev, &p, exteriorColor); + break; + } + + p.rx() = vertices.at(prev).x() - n.x(); + p.ry() = vertices.at(prev).y() - n.y(); + drawTriangle(bits.data(), imgSize, imgSize, &vertices.at(prev), + &extPrev, &p, exteriorColor); + extPrev = p; + } + } else { + for (;;) { + QPoint rn((n.x() * rotation.x() - n.y() * rotation.y()) >> 14, + (n.y() * rotation.x() + n.x() * rotation.y()) >> 14); + n = rn; + if (n.x() * normals.at(prev).y() - n.y() * normals.at(prev).x() <= 0) { + p.rx() = vertices.at(prev).x() - normals.at(prev).x(); + p.ry() = vertices.at(prev).y() - normals.at(prev).y(); + drawTriangle(bits.data(), imgSize, imgSize, &vertices.at(prev), + &extPrev, &p, exteriorColor); + break; + } + + p.rx() = vertices.at(prev).x() - n.x(); + p.ry() = vertices.at(prev).y() - n.y(); + drawTriangle(bits.data(), imgSize, imgSize, &vertices.at(prev), + &extPrev, &p, exteriorColor); + extPrev = p; + } + } + } else { + QPoint p = intPrev; + if (needsClipping[prev]) { + for (;;) { + QPoint rn((n.x() * rotation.x() + n.y() * rotation.y()) >> 14, + (n.y() * rotation.x() - n.x() * rotation.y()) >> 14); + n = rn; + if (n.x() * normals.at(prev).y() - n.y() * normals.at(prev).x() >= 0) { + p.rx() = vertices.at(prev).x() + normals.at(prev).x(); + p.ry() = vertices.at(prev).y() + normals.at(prev).y(); + drawTriangle(bits.data(), imgSize, imgSize, &vertices.at(prev), + &p, &intPrev, interiorColor); + break; + } + + p.rx() = vertices.at(prev).x() + n.x(); + p.ry() = vertices.at(prev).y() + n.y(); + drawTriangle(bits.data(), imgSize, imgSize, &vertices.at(prev), + &p, &intPrev, interiorColor); + intPrev = p; + } + } else { + for (;;) { + QPoint rn((n.x() * rotation.x() + n.y() * rotation.y()) >> 14, + (n.y() * rotation.x() - n.x() * rotation.y()) >> 14); + n = rn; + if (n.x() * normals.at(prev).y() - n.y() * normals.at(prev).x() >= 0) { + p.rx() = vertices.at(prev).x() + normals.at(prev).x(); + p.ry() = vertices.at(prev).y() + normals.at(prev).y(); + drawTriangle(bits.data(), imgSize, imgSize, &vertices.at(prev), + &p, &intPrev, interiorColor); + break; + } + + p.rx() = vertices.at(prev).x() + n.x(); + p.ry() = vertices.at(prev).y() + n.y(); + drawTriangle(bits.data(), imgSize, imgSize, &vertices.at(prev), + &p, &intPrev, interiorColor); + intPrev = p; + } + } + } + } + + index = end + 1; + } + + const qint32 *inLine = bits.data(); + uchar *outLine = image.bits(); + int padding = image.bytesPerLine() - image.width(); + for (int y = 0; y < imgSize; ++y) { + for (int x = 0; x < imgSize; ++x, ++inLine, ++outLine) + *outLine = uchar((0x7f80 - *inLine) >> 8); + outLine += padding; + } + + return image; +} + +bool qt_fontHasNarrowOutlines(const QRawFont &f) +{ + QRawFont font = f; + font.setPixelSize(QT_DISTANCEFIELD_DEFAULT_BASEFONTSIZE); + Q_ASSERT(font.isValid()); + + QVector glyphIndices = font.glyphIndexesForString(QLatin1String("O")); + if (glyphIndices.size() < 1) + return false; + + QImage im = font.alphaMapForGlyph(glyphIndices.at(0), QRawFont::PixelAntialiasing); + if (im.isNull()) + return false; + + int minHThick = 999; + int minVThick = 999; + + int thick = 0; + bool in = false; + int y = (im.height() + 1) / 2; + for (int x = 0; x < im.width(); ++x) { + int a = qAlpha(im.pixel(x, y)); + if (a > 127) { + in = true; + ++thick; + } else if (in) { + in = false; + minHThick = qMin(minHThick, thick); + thick = 0; + } + } + + thick = 0; + in = false; + int x = (im.width() + 1) / 2; + for (int y = 0; y < im.height(); ++y) { + int a = qAlpha(im.pixel(x, y)); + if (a > 127) { + in = true; + ++thick; + } else if (in) { + in = false; + minVThick = qMin(minVThick, thick); + thick = 0; + } + } + + return minHThick == 1 || minVThick == 1; +} + +QImage qt_renderDistanceFieldGlyph(const QRawFont &font, glyph_t glyph, bool doubleResolution) +{ + QRawFont renderFont = font; + renderFont.setPixelSize(QT_DISTANCEFIELD_BASEFONTSIZE(doubleResolution) * QT_DISTANCEFIELD_SCALE(doubleResolution)); + + QPainterPath path = renderFont.pathForGlyph(glyph); + path.translate(-path.boundingRect().topLeft()); + path.setFillRule(Qt::WindingFill); + + QImage im = makeDistanceField(QT_DISTANCEFIELD_TILESIZE(doubleResolution), + path, + QT_DISTANCEFIELD_SCALE(doubleResolution), + QT_DISTANCEFIELD_RADIUS(doubleResolution) / QT_DISTANCEFIELD_SCALE(doubleResolution)); + return im; +} + +QT_END_NAMESPACE + diff --git a/src/gui/text/qdistancefield_p.h b/src/gui/text/qdistancefield_p.h new file mode 100644 index 00000000000..486d291b782 --- /dev/null +++ b/src/gui/text/qdistancefield_p.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtDeclarative 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 QDISTANCEFIELD_H +#define QDISTANCEFIELD_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +QT_BEGIN_NAMESPACE + +#define QT_DISTANCEFIELD_DEFAULT_BASEFONTSIZE 54 +#define QT_DISTANCEFIELD_DEFAULT_TILESIZE 64 +#define QT_DISTANCEFIELD_DEFAULT_SCALE 16 +#define QT_DISTANCEFIELD_DEFAULT_RADIUS 80 +#define QT_DISTANCEFIELD_HIGHGLYPHCOUNT 2000 + +#define QT_DISTANCEFIELD_BASEFONTSIZE(NarrowOutlineFont) \ + (NarrowOutlineFont ? QT_DISTANCEFIELD_DEFAULT_BASEFONTSIZE * 2 : \ + QT_DISTANCEFIELD_DEFAULT_BASEFONTSIZE) +#define QT_DISTANCEFIELD_TILESIZE(NarrowOutlineFont) \ + (NarrowOutlineFont ? QT_DISTANCEFIELD_DEFAULT_TILESIZE * 2 : \ + QT_DISTANCEFIELD_DEFAULT_TILESIZE) +#define QT_DISTANCEFIELD_SCALE(NarrowOutlineFont) \ + (NarrowOutlineFont ? QT_DISTANCEFIELD_DEFAULT_SCALE / 2 : \ + QT_DISTANCEFIELD_DEFAULT_SCALE) +#define QT_DISTANCEFIELD_RADIUS(NarrowOutlineFont) \ + (NarrowOutlineFont ? QT_DISTANCEFIELD_DEFAULT_RADIUS / 2 : \ + QT_DISTANCEFIELD_DEFAULT_RADIUS) + +bool Q_GUI_EXPORT qt_fontHasNarrowOutlines(const QRawFont &f); +QImage Q_GUI_EXPORT qt_renderDistanceFieldGlyph(const QRawFont &font, glyph_t glyph, bool doubleResolution); + +QT_END_NAMESPACE + +#endif // QDISTANCEFIELD_H diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index 63a731f116b..6587769712b 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -42,7 +42,8 @@ HEADERS += \ text/qrawfont_p.h \ text/qglyphrun.h \ text/qglyphrun_p.h \ - text/qharfbuzz_copy_p.h + text/qharfbuzz_copy_p.h \ + text/qdistancefield_p.h SOURCES += \ text/qfont.cpp \ @@ -73,7 +74,8 @@ SOURCES += \ text/qtextodfwriter.cpp \ text/qstatictext.cpp \ text/qrawfont.cpp \ - text/qglyphrun.cpp + text/qglyphrun.cpp \ + text/qdistancefield.cpp contains(QT_CONFIG, directwrite) { LIBS_PRIVATE += -ldwrite From 1bc8af96c9ae7a2f0e8df2deeae09f5e342bb5e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Fri, 3 Feb 2012 17:00:38 +0100 Subject: [PATCH 012/406] Add missing header in kernel.pri qobject_impl.h file was missing. Change-Id: I1701808595933c2462cbc8151961cf9bf9791b64 Reviewed-by: Oswald Buddenhagen --- src/corelib/kernel/kernel.pri | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 6ebc62614bc..4b81087e2f4 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -12,6 +12,7 @@ HEADERS += \ kernel/qmetatype.h \ kernel/qmimedata.h \ kernel/qobject.h \ + kernel/qobject_impl.h \ kernel/qobjectdefs.h \ kernel/qsignalmapper.h \ kernel/qsocketnotifier.h \ From effbc9edc57fd8a2e40729a76004fe4f5fafcf49 Mon Sep 17 00:00:00 2001 From: jian liang Date: Sun, 5 Feb 2012 23:09:36 +0800 Subject: [PATCH 013/406] Fix memory leak of QFontEngineBox object Delete QFontEngineBox object in QFontDatabase::load() if the object can not be used. Change-Id: Ifb055809703fb6be92f41fd56658198df30837fd Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontdatabase_qpa.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp index 16777d593c0..c57fe4b3435 100644 --- a/src/gui/text/qfontdatabase_qpa.cpp +++ b/src/gui/text/qfontdatabase_qpa.cpp @@ -377,8 +377,12 @@ void QFontDatabase::load(const QFontPrivate *d, int script) req.family = *it; fe = QFontDatabase::findFont(script, d, req, multi); - if (fe && (fe->type()==QFontEngine::Box) && !req.family.isEmpty()) + if (fe && (fe->type()==QFontEngine::Box) && !req.family.isEmpty()) { + if (fe->ref.load() == 0) + delete fe; + fe = 0; + } } if (fe->symbol || (d->request.styleStrategy & QFont::NoFontMerging)) { From eeb9861a91bcb5b5122e26012587bbcd619da2d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Sun, 5 Feb 2012 00:46:08 +0100 Subject: [PATCH 014/406] Inline information about FS case sensitivity As far as Qt is concerned, this information is static and depends only on the platform. By moving the definition to the header we allow the information to be directly used by the compiler, forgoing the need to export the function to interested users. Change-Id: I43de585391d41204d3c3560ac6e65e5a88aee11c Reviewed-by: Jonas Gastal Reviewed-by: Shane Kearns --- src/corelib/io/qfilesystemengine_p.h | 9 ++++++++- src/corelib/io/qfilesystemengine_unix.cpp | 5 ----- src/corelib/io/qfilesystemengine_win.cpp | 5 ----- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index 6d60d77c337..17413d9c76b 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -63,7 +63,14 @@ QT_BEGIN_NAMESPACE class QFileSystemEngine { public: - static bool isCaseSensitive(); + static bool isCaseSensitive() + { +#ifndef Q_OS_WIN + return true; +#else + return false; +#endif + } static QFileSystemEntry getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data); static QFileSystemEntry canonicalName(const QFileSystemEntry &entry, QFileSystemMetaData &data); diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 52621eb23ff..23a6b81a581 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -87,11 +87,6 @@ static inline bool _q_isMacHidden(const char *nativePath) } #endif -bool QFileSystemEngine::isCaseSensitive() -{ - return true; -} - //static QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data) { diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 6ebaadad7ed..b04018ca0ff 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -472,11 +472,6 @@ void QFileSystemEngine::clearWinStatData(QFileSystemMetaData &data) data.lastWriteTime_ = FILETIME(); } -bool QFileSystemEngine::isCaseSensitive() -{ - return false; -} - //static QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data) From 5d255789cdd6f1d301c161e25151595ca06db436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Sun, 5 Feb 2012 00:50:25 +0100 Subject: [PATCH 015/406] Remove dependency on QFSFileEngine The code was hard-wired to use QFSFileEngine to determine platform preference for file system case sensitivity. In this case it is cheaper to use private API and directly access the information in QFileSystemEngine. This change is also necessary because file engines are being dropped from the public API. Change-Id: I5015d5fdb3979af9ff2d114084053ad06220d834 Reviewed-by: Shane Kearns --- src/widgets/dialogs/qfileinfogatherer_p.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/widgets/dialogs/qfileinfogatherer_p.h b/src/widgets/dialogs/qfileinfogatherer_p.h index 3e5d1be384c..c07c908a556 100644 --- a/src/widgets/dialogs/qfileinfogatherer_p.h +++ b/src/widgets/dialogs/qfileinfogatherer_p.h @@ -58,13 +58,14 @@ #include #include #include -#include #include #include #include #include #include +#include + QT_BEGIN_NAMESPACE class QExtendedInformation { @@ -86,8 +87,7 @@ public: #ifndef QT_NO_FSFILEENGINE bool isCaseSensitive() const { - QFSFileEngine fe(mFileInfo.absoluteFilePath()); - return fe.caseSensitive(); + return QFileSystemEngine::isCaseSensitive(); } #endif From 16c4224568b7969591120f163dc81ba61cd1e6f8 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 6 Feb 2012 16:58:15 +0200 Subject: [PATCH 016/406] Destroy the QWindow children in destroy() instead of close() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When closing a window, destroy() ensures a setVisible(false) call only for the window itself, not for other windows parented to it. With the new quit lock ref feature this breaks code that creates a fake root window parented to the main, visible window. (for example the xcomposite backends of qtwayland do this) Such apps do not anymore exit after closing their window because the children do not receive a deref due to setVisible not getting called. (At that point. It would get called after exiting the event loop but that never happens due to the refcounting) Change-Id: I124737c80ad59600ddc79261100f3904af0f410d Reviewed-by: Samuel Rødal --- src/gui/kernel/qwindow.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 4436884359c..b451a6ee331 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -731,6 +731,15 @@ void QWindow::setWindowIcon(const QImage &icon) const void QWindow::destroy() { Q_D(QWindow); + QObjectList childrenWindows = children(); + for (int i = 0; i < childrenWindows.size(); i++) { + QObject *object = childrenWindows.at(i); + if (object->isWindowType()) { + QWindow *w = static_cast(object); + QGuiApplicationPrivate::window_list.removeAll(w); + w->destroy(); + } + } setVisible(false); delete d->platformWindow; d->platformWindow = 0; @@ -881,16 +890,6 @@ bool QWindow::close() if (QGuiApplicationPrivate::focus_window == this) QGuiApplicationPrivate::focus_window = 0; - QObjectList childrenWindows = children(); - for (int i = 0; i < childrenWindows.size(); i++) { - QObject *object = childrenWindows.at(i); - if (object->isWindowType()) { - QWindow *w = static_cast(object); - QGuiApplicationPrivate::window_list.removeAll(w); - w->destroy(); - } - } - QGuiApplicationPrivate::window_list.removeAll(this); destroy(); d->maybeQuitOnLastWindowClosed(); From dbe89db6862fb2134e5e9c9e7f04aae003ac7271 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 6 Feb 2012 16:43:39 +0100 Subject: [PATCH 017/406] Fixed typo in QOpenGLContext warning message. Change-Id: I967279f4b4875ae80ce45744d559fc7380bc0125 Reviewed-by: Kim M. Kalland --- src/gui/kernel/qopenglcontext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 1b6d1d34c4a..debfbe212ba 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -289,7 +289,7 @@ bool QOpenGLContext::makeCurrent(QSurface *surface) return false; if (surface->surfaceType() != QSurface::OpenGLSurface) { - qWarning() << "QOpenGLContext::makeBuffers() called with non-opengl surface"; + qWarning() << "QOpenGLContext::makeCurrent() called with non-opengl surface"; return false; } From 1564b393fe75219b8d6e311b9becd5f5021ff628 Mon Sep 17 00:00:00 2001 From: Jan-Arve Saether Date: Mon, 6 Feb 2012 11:07:56 +0100 Subject: [PATCH 018/406] Compile MSVC2008 Change-Id: Ie89ec4095e8865dbc4781bff0db70f35d239664e Reviewed-by: Friedemann Kleint --- src/corelib/tools/qdatetime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 3da7a370667..70efb5db222 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -924,7 +924,7 @@ QDate QDate::addDays(qint64 ndays) const else diff = jd - minJd(); - if (abs(ndays) <= diff) + if ((quint64)qAbs(ndays) <= diff) d.jd = jd + ndays; return d; From 4a1f1b9be003ecaa06a5410a9b7c4a66641f7f03 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Mon, 6 Feb 2012 16:31:52 +0100 Subject: [PATCH 019/406] Make syncqt ignore qsystemdetection.h and qcompilerdetection.h Remove the #if 0'd blocks and instead add these headers to sync.profile's @ignore_for_include_check, as documented at http://wiki.qt-project.org/Creating_a_new_module_or_tool_for_Qt#other_fields Change-Id: I3bd6e8cb21eca139fdca10fe970eeaf2e4e77c24 Reviewed-by: Oswald Buddenhagen --- src/corelib/global/qcompilerdetection.h | 14 -------------- src/corelib/global/qsystemdetection.h | 14 -------------- sync.profile | 2 +- 3 files changed, 1 insertion(+), 29 deletions(-) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 7621b76f545..5ab79092d20 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -42,20 +42,6 @@ #ifndef QCOMPILERDETECTION_H #define QCOMPILERDETECTION_H -#if 0 -// header is automatically included in qglobal.h -#pragma qt_no_master_include - -// silence syncqt warnings (QT_* macros are not yet defined) -QT_BEGIN_HEADER -QT_BEGIN_NAMESPACE - -QT_END_NAMESPACE -QT_END_HEADER - -#pragma qt_sync_stop_processing -#endif - /* The compiler, must be one of: (Q_CC_x) diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h index 11df62bcef4..0228bc9404a 100644 --- a/src/corelib/global/qsystemdetection.h +++ b/src/corelib/global/qsystemdetection.h @@ -42,20 +42,6 @@ #ifndef QSYSTEMDETECTION_H #define QSYSTEMDETECTION_H -#if 0 -// header is automatically included in qglobal.h -#pragma qt_no_master_include - -// silence syncqt warnings (QT_* macros are not yet defined) -QT_BEGIN_HEADER -QT_BEGIN_NAMESPACE - -QT_END_NAMESPACE -QT_END_HEADER - -#pragma qt_sync_stop_processing -#endif - /* The operating system, must be one of: (Q_OS_x) diff --git a/sync.profile b/sync.profile index 446f8f40fa2..4f01b7cf730 100644 --- a/sync.profile +++ b/sync.profile @@ -77,7 +77,7 @@ ); @ignore_for_master_contents = ( "qt.h", "qpaintdevicedefs.h" ); -@ignore_for_include_check = ( "qatomic.h" ); +@ignore_for_include_check = ( "qsystemdetection.h", "qcompilerdetection.h" ); @ignore_for_qt_begin_header_check = ( "qiconset.h", "qconfig.h", "qconfig-dist.h", "qconfig-large.h", "qconfig-medium.h", "qconfig-minimal.h", "qconfig-small.h", "qfeatures.h", "qt_windows.h" ); @ignore_for_qt_begin_namespace_check = ( "qconfig.h", "qconfig-dist.h", "qconfig-large.h", "qconfig-medium.h", "qconfig-minimal.h", "qconfig-small.h", "qfeatures.h", "qatomic_arch.h", "qatomic_windowsce.h", "qt_windows.h", "qatomic_macosx.h" ); @ignore_for_qt_module_check = ( "$modules{QtCore}/arch", "$modules{QtCore}/global", "$modules{QtTest}", "$modules{QtDBus}" ); From cfd8a9a4486cf5ca4bf8e0a87459ad5d2c3ca3dd Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 7 Feb 2012 14:16:21 +1000 Subject: [PATCH 020/406] Fix error in qcssparser autotest. QTest::ignoreMessage() cannot be called when creating test data rows, but rather must be called when executing a row. Change-Id: Ifceaff4c5a7f1b6408ec57196298e3f3038910c9 Reviewed-by: Rohan McGovern --- tests/auto/gui/text/qcssparser/tst_qcssparser.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp index 7eda35efb8a..7e0a60c8596 100644 --- a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp +++ b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp @@ -344,7 +344,6 @@ void tst_QCssParser::term_data() val.variant = QVariant(QColor("#ffbb00")); QTest::newRow("hexcolor2") << true << "#fb0" << val; - QTest::ignoreMessage(QtWarningMsg, "QCssParser::parseHexColor: Unknown color name '#cafebabe'"); QTest::newRow("hexcolor_failure") << false << "#cafebabe" << val; val.type = QCss::Value::Uri; @@ -368,6 +367,9 @@ void tst_QCssParser::term() QFETCH(QString, css); QFETCH(QCss::Value, expectedValue); + if (strcmp(QTest::currentDataTag(), "hexcolor_failure") == 0) + QTest::ignoreMessage(QtWarningMsg, "QCssParser::parseHexColor: Unknown color name '#cafebabe'"); + QCss::Parser parser(css); QCss::Value val; QVERIFY(parser.testTerm()); From 9221757cde0bbfa2f45c43c8686a8b954027fdbf Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 7 Feb 2012 14:09:10 +1000 Subject: [PATCH 021/406] Fix error in qgraphicsanchorlayout1 autotest. QTest::ignoreMessage() cannot be called when creating test data rows, but rather must be called when executing a row. Change-Id: Ic958c4e5c15dd53a48479099b6b07803af6cb789 Reviewed-by: Rohan McGovern --- .../tst_qgraphicsanchorlayout1.cpp | 44 +++++++++++-------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp index 3a8e109d805..97feb642dc2 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp @@ -1835,15 +1835,6 @@ void tst_QGraphicsAnchorLayout1::testCenterAnchors_data() theResult << BasicResult(0, QRectF(5, 5, 10, 10) ); - QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations"); - QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations"); - QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations"); - QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); - QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); - QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); - QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); - QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); - QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); QTest::newRow("center, basic with invalid") << QSizeF(20, 20) << theData << theResult; } @@ -1975,9 +1966,6 @@ void tst_QGraphicsAnchorLayout1::testCenterAnchors_data() << BasicResult(1, QRectF(20, 0, 30, 10)) << BasicResult(2, QRectF(60, 15, 40, 10)); - QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); - QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); - QTest::newRow("center, three") << QSizeF(100, 50) << theData << theResult; } @@ -2062,6 +2050,21 @@ void tst_QGraphicsAnchorLayout1::testCenterAnchors_data() void tst_QGraphicsAnchorLayout1::testCenterAnchors() { + if (strcmp(QTest::currentDataTag(), "center, basic with invalid") == 0) { + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + } else if (strcmp(QTest::currentDataTag(), "center, three") == 0) { + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + } + // use the same frame testBasicLayout(); } @@ -2144,11 +2147,6 @@ void tst_QGraphicsAnchorLayout1::testRemoveCenterAnchor_data() << BasicResult(1, QRectF(20, 0, 30, 10)) << BasicResult(2, QRectF(60, 15, 40, 10)); - QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); - QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); - QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); - QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); - QTest::newRow("remove, center, three") << QSizeF(100, 50) << theData << theRemoveData << theResult; } @@ -2183,8 +2181,6 @@ void tst_QGraphicsAnchorLayout1::testRemoveCenterAnchor_data() theResult << BasicResult(0, QRectF(5, 5, 10, 10) ); - QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); - QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); QTest::newRow("remove, center, basic 2") << QSizeF(20, 20) << theData << theRemoveData << theResult; } @@ -2193,6 +2189,16 @@ void tst_QGraphicsAnchorLayout1::testRemoveCenterAnchor_data() void tst_QGraphicsAnchorLayout1::testRemoveCenterAnchor() { + if (strcmp(QTest::currentDataTag(), "remove, center, three") == 0) { + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + } else if (strcmp(QTest::currentDataTag(), "remove, center, basic 2") == 0) { + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + } + QFETCH(QSizeF, size); QFETCH(BasicLayoutTestDataList, data); QFETCH(BasicLayoutTestDataList, removeData); From a6505007295c7363ef1b0ee4aa81d15a2b470a7e Mon Sep 17 00:00:00 2001 From: Martin Petersson Date: Mon, 6 Feb 2012 15:42:19 +0100 Subject: [PATCH 022/406] tst_qnetworkreply: remove no such signal warnings The QNetworkReply finished signal does not have a bool parameter. Change-Id: I87bd0410545f7a2fc2ab63cca90548f0585bf7a0 Reviewed-by: Shane Kearns Reviewed-by: Jonas Gastal --- tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 959250acb42..44cafe4de90 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -1860,7 +1860,7 @@ void tst_QNetworkReply::putToFtp() QObject::connect(r, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); QTestEventLoop::instance().enterLoop(10); - QObject::disconnect(r, SIGNAL(finished(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QObject::disconnect(r, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); QByteArray uploaded = r->readAll(); QCOMPARE(uploaded.size(), data.size()); @@ -3911,7 +3911,7 @@ void tst_QNetworkReply::ioPutToFtpFromFile() QObject::connect(r, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); QTestEventLoop::instance().enterLoop(3); - QObject::disconnect(r, SIGNAL(finished(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QObject::disconnect(r, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); QByteArray uploaded = r->readAll(); QCOMPARE(qint64(uploaded.size()), sourceFile.size()); From 56265031b763736163f1a229a7e7e6b7aaec8a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Mon, 30 Jan 2012 12:21:43 +0100 Subject: [PATCH 023/406] Align QVariant::UserType and QMetaType::User MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no point in keeping separate values which should mean the same. QVariant::UserType was used also to construct a valid, null QVariant, containing an instance of unknown custom type. The concept was strange and useless as there was no operation that could be done on such QVariant. Therefore it was dropped. Please note that the patch slightly changes behavior of different functions accepting a type id as parameter. Before QVariant::UserType was an invalid type from QMetaType perspective (id 127 was not assigned to any built-in type), but QMetaType::User points to the first registered custom type. Change-Id: I5c7d541a9affdcdacf53a4eda2272bdafaa87b71 Reviewed-by: Kent Hansen Reviewed-by: Lars Knoll Reviewed-by: João Abecasis Reviewed-by: Andrew Stanley-Jones Reviewed-by: Aaron Kennedy --- dist/changes-5.0.0 | 7 +++++++ src/corelib/kernel/qmetaobject.cpp | 5 ++--- src/corelib/kernel/qvariant.cpp | 12 ++++++++---- src/corelib/kernel/qvariant.h | 2 +- src/corelib/kernel/qvariant_p.h | 15 +-------------- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 2 ++ .../auto/corelib/kernel/qvariant/tst_qvariant.cpp | 12 ++++-------- tests/auto/dbus/qdbusmarshall/common.h | 8 ++++---- 8 files changed, 29 insertions(+), 34 deletions(-) diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index fc5bebd11da..280b5d93f90 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -437,6 +437,13 @@ Qt for Windows CE cause an abort(). +- QVariant + + * Definition of QVariant::UserType changed. Currently it is the same as + QMetaType::User, which means that it points to the first registered custom + type, instead of a nonexistent type. + + - QMessageBox * The static function QMessageBox::question has changed the default argument diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 400fe54c7fa..7975fc26288 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -2243,9 +2243,8 @@ QVariant QMetaProperty::read(const QObject *object) const t = QMetaType::type(typeName); if (t == QVariant::Invalid) t = QVariant::nameToType(typeName); - if (t == QVariant::Invalid || t == QVariant::UserType) { - if (t == QVariant::Invalid) - qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property '%s::%s'", typeName, mobj->className(), name()); + if (t == QVariant::Invalid) { + qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property '%s::%s'", typeName, mobj->className(), name()); return QVariant(); } } diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index cfaf22c1464..4197fe90931 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -1608,7 +1608,7 @@ QVariant::Type QVariant::nameToType(const char *name) return Invalid; int metaType = QMetaType::type(name); - return metaType <= int(LastGuiType) ? QVariant::Type(metaType) : UserType; + return metaType <= int(UserType) ? QVariant::Type(metaType) : UserType; } #ifndef QT_NO_DATASTREAM @@ -1670,7 +1670,9 @@ void QVariant::load(QDataStream &s) return; typeId = mapIdFromQt3ToCurrent[typeId]; } else if (s.version() < QDataStream::Qt_5_0) { - if (typeId >= 128 && typeId != QVariant::UserType) { + if (typeId == 127 /* QVariant::UserType */) { + typeId = QMetaType::User; + } else if (typeId >= 128 && typeId != QVariant::UserType) { // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes // by moving all ids down by 97. typeId -= 97; @@ -1741,7 +1743,9 @@ void QVariant::save(QDataStream &s) const return; } } else if (s.version() < QDataStream::Qt_5_0) { - if (typeId >= 128 - 97 && typeId <= LastCoreType) { + if (typeId == QMetaType::User) { + typeId = 127; // QVariant::UserType had this value in Qt4 + } else if (typeId >= 128 - 97 && typeId <= LastCoreType) { // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes // by moving all ids down by 97. typeId += 97; @@ -1762,7 +1766,7 @@ void QVariant::save(QDataStream &s) const s << typeId; if (s.version() >= QDataStream::Qt_4_2) s << qint8(d.is_null); - if (typeId == QVariant::UserType) { + if (d.type >= QVariant::UserType) { s << QMetaType::typeName(userType()); } diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index 07ef4dc41ed..b61b0cc33ce 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -153,7 +153,7 @@ class Q_CORE_EXPORT QVariant Icon = QMetaType::QIcon, SizePolicy = QMetaType::QSizePolicy, - UserType = 127, + UserType = QMetaType::User, LastType = 0xffffffff // need this so that gcc >= 3.4 allocates 32 bits for Type }; diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h index 7065bcfd6b2..30159f1831e 100644 --- a/src/corelib/kernel/qvariant_p.h +++ b/src/corelib/kernel/qvariant_p.h @@ -348,14 +348,6 @@ public: void delegate(const QMetaTypeSwitcher::UnknownType*) { - if (m_x->type == QVariant::UserType) { - // TODO get rid of it - // And yes! we can support historical magic, unkonwn/unconstructed user type isn't that - // awesome? this QVariant::isValid will be true! - m_x->is_null = !m_copy; - m_x->is_shared = false; - return; - } qWarning("Trying to construct an instance of an invalid type, type id: %i", m_x->type); m_x->type = QVariant::Invalid; } @@ -406,8 +398,6 @@ public: void delegate(const QMetaTypeSwitcher::UnknownType*) { - if (m_d->type == QVariant::UserType) - return; qWarning("Trying to destruct an instance of an invalid type, type id: %i", m_d->type); } // Ignore nonconstructible type @@ -454,10 +444,7 @@ public: void delegate(const QMetaTypeSwitcher::UnknownType*) { - if (m_d->type == QVariant::UserType) - m_debugStream.nospace() << "QVariant::UserType"; - else - qWarning("Trying to stream an instance of an invalid type, type id: %i", m_d->type); + qWarning("Trying to stream an instance of an invalid type, type id: %i", m_d->type); } void delegate(const void*) { diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 7f95f680754..4e7935be312 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -1704,6 +1704,7 @@ void tst_QObject::property() QVERIFY(!property.isEnumType()); QCOMPARE(property.typeName(), "CustomType*"); QCOMPARE(property.type(), QVariant::UserType); + QCOMPARE(property.userType(), qMetaTypeId()); CustomType *customPointer = 0; QVariant customVariant = object.property("custom"); @@ -1718,6 +1719,7 @@ void tst_QObject::property() QVERIFY(property.isWritable()); QCOMPARE(property.typeName(), "CustomType*"); QCOMPARE(property.type(), QVariant::UserType); + QCOMPARE(property.userType(), qMetaTypeId()); QVERIFY(object.setProperty("custom", customVariant)); QCOMPARE(object.custom(), customPointer); diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 2bf554dd782..f7bdfd800ad 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -1842,10 +1842,6 @@ void tst_QVariant::operator_eq_eq_data() QTest::newRow("HashSecondLarger") << QVariant(hash1) << QVariant(hash2) << false; } - - QTest::newRow( "UserType" ) << QVariant(QVariant::UserType) << QVariant(QVariant::UserType) << true; - QVariant mUserType(QVariant::UserType); - QTest::newRow( "Shared UserType" ) << mUserType << mUserType << true; } void tst_QVariant::operator_eq_eq() @@ -1919,7 +1915,6 @@ void tst_QVariant::typeName_data() QTest::newRow("39") << int(QVariant::RectF) << QByteArray("QRectF"); QTest::newRow("40") << int(QVariant::PointF) << QByteArray("QPointF"); QTest::newRow("41") << int(QVariant::RegExp) << QByteArray("QRegExp"); - QTest::newRow("42") << int(QVariant::UserType) << QByteArray(); QTest::newRow("43") << int(QVariant::Matrix) << QByteArray("QMatrix"); QTest::newRow("44") << int(QVariant::Transform) << QByteArray("QTransform"); QTest::newRow("45") << int(QVariant::Hash) << QByteArray("QVariantHash"); @@ -2031,10 +2026,10 @@ void tst_QVariant::userType() qVariantSetValue(userVar, data); QCOMPARE(userVar.type(), QVariant::UserType); + QCOMPARE(userVar.userType(), qMetaTypeId()); QCOMPARE(userVar.typeName(), "MyType"); QVERIFY(!userVar.isNull()); QVERIFY(!userVar.canConvert(QVariant::String)); - QVERIFY(!userVar.canConvert(QVariant::UserType)); QVariant userVar2(userVar); QVERIFY(userVar == userVar2); @@ -2060,10 +2055,10 @@ void tst_QVariant::userType() qVariantSetValue(userVar, &data); QCOMPARE(userVar.type(), QVariant::UserType); + QCOMPARE(userVar.userType(), qMetaTypeId()); QCOMPARE(userVar.typeName(), "MyType*"); QVERIFY(!userVar.isNull()); QVERIFY(!userVar.canConvert(QVariant::String)); - QVERIFY(!userVar.canConvert(QVariant::UserType)); QVariant userVar2(userVar); QVERIFY(userVar == userVar2); @@ -2696,7 +2691,7 @@ Q_DECLARE_METATYPE( MyClass ) void tst_QVariant::loadUnknownUserType() { qRegisterMetaType("MyClass"); - char data[] = {0, 0, 0, 127, 0, 0, 0, 0, 8, 77, 121, 67, 108, 97, 115, 115, 0}; + char data[] = {0, 0, 1, 0, 0, 0, 0, 0, 8, 77, 121, 67, 108, 97, 115, 115, 0}; QByteArray ba(data, sizeof(data)); QDataStream ds(&ba, QIODevice::ReadOnly); @@ -3306,6 +3301,7 @@ void tst_QVariant::movabilityTest() memcpy(buffer, &variant, sizeof(QVariant)); QCOMPARE(buffer[0].type(), QVariant::UserType); + QCOMPARE(buffer[0].userType(), qMetaTypeId()); MyNotMovable tmp(buffer[0].value()); new (&variant) QVariant(); diff --git a/tests/auto/dbus/qdbusmarshall/common.h b/tests/auto/dbus/qdbusmarshall/common.h index d49f4eff304..87c434b71eb 100644 --- a/tests/auto/dbus/qdbusmarshall/common.h +++ b/tests/auto/dbus/qdbusmarshall/common.h @@ -610,10 +610,6 @@ template<> bool compare(const QVariant &v1, const QVariant &v2) else if (id == QVariant::ByteArray) return compare(v1.toByteArray(), v2.toByteArray()); - else if (id < int(QVariant::UserType)) // yes, v1.type() - // QVariant can compare - return v1 == v2; - else if (id == QMetaType::UChar) return qvariant_cast(v1) == qvariant_cast(v2); @@ -716,6 +712,10 @@ template<> bool compare(const QVariant &v1, const QVariant &v2) else if (id == qMetaTypeId()) // (is) return qvariant_cast(v1) == qvariant_cast(v2); + else if (id < int(QVariant::UserType)) // yes, v1.type() + // QVariant can compare + return v1 == v2; + else { qWarning() << "Please write a comparison case for type" << v1.typeName(); return false; // unknown type From b8cf1d6bdcaefaa610014a742808af3ab2c6fe06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Fri, 3 Feb 2012 12:54:25 +0100 Subject: [PATCH 024/406] Remove QMetaType::unregisterType(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function hasn't been working properly. It was not well tested, for example it is undefined how QVariant should behave if it contains an instance of an unregistered type. Concept of unregistering types was inspired by plug-in system, but in most supported platforms we do not unload plug-ins. Idea of type unregistering may block optimizations in meta object system, because it would be not possible to cache a type id. QMetaType::type() could return different ids for the same name. Currently QMetaType::unregisterType() is not used in Qt. Change-Id: I878b6e8d91de99f9bcefeab73af2e2ba0bd0cba0 Reviewed-by: Prasanth Ullattil Reviewed-by: Bradley T. Hughes Reviewed-by: João Abecasis Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira Reviewed-by: Kent Hansen --- dist/changes-5.0.0 | 4 ++- src/corelib/kernel/qmetatype.cpp | 30 ------------------- src/corelib/kernel/qmetatype.h | 1 - .../kernel/qmetatype/tst_qmetatype.cpp | 23 -------------- 4 files changed, 3 insertions(+), 55 deletions(-) diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index 280b5d93f90..617b2d3d95a 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -45,7 +45,9 @@ information about a particular change. in Qt4, so these methods return a bool now. If your code used the undocumented QBool, simply replace it with bool. -- QMetaType::construct() has been renamed to QMetaType::create(). +- QMetaType: + * QMetaType::construct() has been renamed to QMetaType::create(). + * QMetaType::unregisterType() has been removed. - QTestLib: * The QTRY_VERIFY and QTRY_COMPARE macros have been moved into QTestLib. diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 50b11e0e983..b31bece3768 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -531,36 +531,6 @@ int QMetaType::registerTypedef(const char* typeName, int aliasId) return aliasId; } -/*! - \since 4.4 - - Unregisters a user type, with \a typeName. - - \sa type(), typeName() - */ -void QMetaType::unregisterType(const char *typeName) -{ - QVector *ct = customTypes(); - if (!ct || !typeName) - return; - -#ifdef QT_NO_QOBJECT - NS(QByteArray) normalizedTypeName = typeName; -#else - NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName); -#endif - QWriteLocker locker(customTypesLock()); - for (int v = 0; v < ct->count(); ++v) { - if (ct->at(v).typeName == typeName) { - QCustomTypeInfo &inf = (*ct)[v]; - inf.typeName.clear(); - inf.creator = 0; - inf.deleter = 0; - inf.alias = -1; - } - } -} - /*! Returns true if the datatype with ID \a type is registered; otherwise returns false. diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 0ea9d26394c..e99c93c3722 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -247,7 +247,6 @@ public: static void destroy(int type, void *data); static void *construct(int type, void *where, const void *copy); static void destruct(int type, void *where); - static void unregisterType(const char *typeName); #ifndef QT_NO_DATASTREAM static bool save(QDataStream &stream, int type, const void *data); diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index be13b39e7ea..ca2964d3e2c 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -87,7 +87,6 @@ private slots: void typedefs(); void isRegistered_data(); void isRegistered(); - void unregisterType(); void registerStreamBuiltin(); void automaticTemplateRegistration(); }; @@ -857,28 +856,6 @@ void tst_QMetaType::isRegistered() QCOMPARE(QMetaType::isRegistered(typeId), registered); } -class RegUnreg -{ -public: - RegUnreg() {}; - RegUnreg(const RegUnreg &) {}; - ~RegUnreg() {}; -}; - -void tst_QMetaType::unregisterType() -{ - // cannot unregister standard types - int typeId = qRegisterMetaType >("QList"); - QCOMPARE(QMetaType::isRegistered(typeId), true); - QMetaType::unregisterType("QList"); - QCOMPARE(QMetaType::isRegistered(typeId), true); - // allow unregister user types - typeId = qRegisterMetaType("RegUnreg"); - QCOMPARE(QMetaType::isRegistered(typeId), true); - QMetaType::unregisterType("RegUnreg"); - QCOMPARE(QMetaType::isRegistered(typeId), false); -} - void tst_QMetaType::registerStreamBuiltin() { //should not crash; From 5a92dd612472378ec329d380fdc8fe609478b06c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 30 Jan 2012 14:50:04 +0100 Subject: [PATCH 025/406] Detect incompatibilities in repeated type registration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QMetaType used to register a typeName and factory functions for creation/destruction of objects. While it would be possible for a single type name to be registered matching different actual types and memory layouts, there was little that could be done about it. Now that QMetaType is tracking type information with a direct impact on data layout and ABI (size and type flags) it is important that we check and detect binary incompatibilities as early as possible. [Such incompatibilities could arise from type name re-use (technically, ODR violations) or, more commonly, as version mismatch between different shared libraries or plugins.] Only type size and flags are checked as function pointers to inline and template or otherwise non-exported functions could trivially differ across translation units and shared libraries. When registering typedef types, a check is made to ensure the same name doesn't get registered as different types. Change-Id: I8211c3de75d4854ce8fafdb620d3a931c206e0c3 Reviewed-by: Olivier Goffart Reviewed-by: Jędrzej Nowacki Reviewed-by: Kent Hansen --- src/corelib/kernel/qmetatype.cpp | 66 ++++++++++++++----- .../kernel/qmetatype/tst_qmetatype.cpp | 39 +++++++++++ 2 files changed, 88 insertions(+), 17 deletions(-) diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index b31bece3768..a6b15994445 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -465,6 +465,8 @@ int QMetaType::registerType(const char *typeName, Deleter deleter, int idx = qMetaTypeStaticType(normalizedTypeName.constData(), normalizedTypeName.size()); + int previousSize = 0; + int previousFlags = 0; if (!idx) { QWriteLocker locker(customTypesLock()); idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(), @@ -485,8 +487,33 @@ int QMetaType::registerType(const char *typeName, Deleter deleter, inf.flags = flags; idx = ct->size() + User; ct->append(inf); + return idx; + } + + if (idx >= User) { + previousSize = ct->at(idx - User).size; + previousFlags = ct->at(idx - User).flags; } } + + if (idx < User) { + previousSize = QMetaType::sizeOf(idx); + previousFlags = QMetaType::typeFlags(idx); + } + + if (previousSize != size) { + qFatal("QMetaType::registerType: Binary compatibility break " + "-- Size mismatch for type '%s' [%i]. Previously registered " + "size %i, now registering size %i.", + normalizedTypeName.constData(), idx, previousSize, size); + } + if (previousFlags != flags) { + qFatal("QMetaType::registerType: Binary compatibility break " + "-- Type flags for type '%s' [%i] don't match. Previously " + "registered TypeFlags(0x%x), now registering TypeFlags(0x%x).", + normalizedTypeName.constData(), idx, previousFlags, int(flags)); + } + return idx; } @@ -510,25 +537,30 @@ int QMetaType::registerTypedef(const char* typeName, int aliasId) int idx = qMetaTypeStaticType(normalizedTypeName.constData(), normalizedTypeName.size()); - if (idx) { - Q_ASSERT(idx == aliasId); - return idx; + if (!idx) { + QWriteLocker locker(customTypesLock()); + idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(), + normalizedTypeName.size()); + + if (!idx) { + QCustomTypeInfo inf; + inf.typeName = normalizedTypeName; + inf.alias = aliasId; + inf.creator = 0; + inf.deleter = 0; + ct->append(inf); + return aliasId; + } } - QWriteLocker locker(customTypesLock()); - idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(), - normalizedTypeName.size()); - - if (idx) - return idx; - - QCustomTypeInfo inf; - inf.typeName = normalizedTypeName; - inf.alias = aliasId; - inf.creator = 0; - inf.deleter = 0; - ct->append(inf); - return aliasId; + if (idx != aliasId) { + qFatal("QMetaType::registerTypedef: Binary compatibility break " + "-- Type name '%s' previously registered as typedef of '%s' [%i], " + "now registering as typedef of '%s' [%i].", + normalizedTypeName.constData(), QMetaType::typeName(idx), idx, + QMetaType::typeName(aliasId), aliasId); + } + return idx; } /*! diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index ca2964d3e2c..f90e7f463f4 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -85,6 +85,7 @@ private slots: void constructCopy_data(); void constructCopy(); void typedefs(); + void registerType(); void isRegistered_data(); void isRegistered(); void registerStreamBuiltin(); @@ -828,6 +829,44 @@ void tst_QMetaType::typedefs() QCOMPARE(QMetaType::type("WhityDouble"), ::qMetaTypeId()); } +void tst_QMetaType::registerType() +{ + // Built-in + QCOMPARE(qRegisterMetaType("QString"), int(QMetaType::QString)); + QCOMPARE(qRegisterMetaType("QString"), int(QMetaType::QString)); + + // Custom + int fooId = qRegisterMetaType("TestSpace::Foo"); + QVERIFY(fooId >= int(QMetaType::User)); + QCOMPARE(qRegisterMetaType("TestSpace::Foo"), fooId); + + int movableId = qRegisterMetaType("CustomMovable"); + QVERIFY(movableId >= int(QMetaType::User)); + QCOMPARE(qRegisterMetaType("CustomMovable"), movableId); + + // Alias to built-in + typedef QString MyString; + + QCOMPARE(qRegisterMetaType("MyString"), int(QMetaType::QString)); + QCOMPARE(qRegisterMetaType("MyString"), int(QMetaType::QString)); + + QCOMPARE(QMetaType::type("MyString"), int(QMetaType::QString)); + + // Alias to custom type + typedef CustomMovable MyMovable; + typedef TestSpace::Foo MyFoo; + + QCOMPARE(qRegisterMetaType("MyMovable"), movableId); + QCOMPARE(qRegisterMetaType("MyMovable"), movableId); + + QCOMPARE(QMetaType::type("MyMovable"), movableId); + + QCOMPARE(qRegisterMetaType("MyFoo"), fooId); + QCOMPARE(qRegisterMetaType("MyFoo"), fooId); + + QCOMPARE(QMetaType::type("MyFoo"), fooId); +} + class IsRegisteredDummyType { }; void tst_QMetaType::isRegistered_data() From 6a75785f49ad11ab1cd026dc8cc2c765f003031f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 7 Feb 2012 09:10:51 +0100 Subject: [PATCH 026/406] Compile with -no-freetype. Fix breakage introduced by 3f75fb8d8f25af5b79b71ae74f453a2b220a11ce. Task-number: QTBUG-24091 Change-Id: I322bbab382a5e375dccd4273c70a0ed8b525d125 Reviewed-by: Jonathan Liu Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/windows.pro | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro index 453265405a1..01976a99364 100644 --- a/src/plugins/platforms/windows/windows.pro +++ b/src/plugins/platforms/windows/windows.pro @@ -75,6 +75,9 @@ HEADERS += \ qwindowstheme.h \ qwindowsdialoghelpers.h +# Enable access to HB_Face in harfbuzz includes included by qfontengine_p.h. +DEFINES *= QT_COMPILES_IN_HARFBUZZ + contains(QT_CONFIG, freetype) { DEFINES *= QT_NO_FONTCONFIG DEFINES *= QT_COMPILES_IN_HARFBUZZ From 36f5cc848de25251bfb1cae2ddeea0871ded1fac Mon Sep 17 00:00:00 2001 From: Caroline Chao Date: Mon, 23 Jan 2012 12:55:21 +0100 Subject: [PATCH 027/406] CodeCoverage: Save coverage data in QTestLog::stopLogging() Currently when tests are crashing, aborting or hanging, their status are reported with a status "Unknown" because SaveCoverageTool is never called for them. The status of the test given by the coverage tool should be the same as the one reported in the log output when the test is run. This change will allow more accuracy in the status reported. Add QTestResult::setCurrentAppname and QTestResult::currentAppname. To retrieve the name of the current application running. Task-number: QTQAINFRA-460 Change-Id: Icc476dc2d6cb28185e5447f1e79da6a8a31cad54 Reviewed-by: Rohan McGovern Reviewed-by: Jason McDonald --- src/testlib/qtestcase.cpp | 25 +++++-------------------- src/testlib/qtestlog.cpp | 17 +++++++++++++++++ src/testlib/qtestresult.cpp | 12 ++++++++++++ src/testlib/qtestresult_p.h | 3 +++ 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 8a1d4bf44a6..b76ff39de4f 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -947,22 +947,6 @@ static void installCoverageTool(const char * appname, const char * testname) #endif } -static void saveCoverageTool(const char * appname, bool testfailed) -{ -#ifdef __COVERAGESCANNER__ - // install again to make sure the filename is correct. - // without this, a plugin or similar may have changed the filename. - __coveragescanner_install(appname); - __coveragescanner_teststate(testfailed ? "FAILED" : "PASSED"); - __coveragescanner_save(); - __coveragescanner_testname(""); - __coveragescanner_clear(); -#else - Q_UNUSED(appname); - Q_UNUSED(testfailed); -#endif -} - namespace QTest { static QObject *currentTestObject = 0; @@ -1970,10 +1954,13 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) const QMetaObject *metaObject = testObject->metaObject(); QTEST_ASSERT(metaObject); + QTestResult::setCurrentTestObject(metaObject->className()); + QTestResult::setCurrentAppname(argv[0]); + + qtest_qParseArgs(argc, argv, false); + installCoverageTool(argv[0], metaObject->className()); - QTestResult::setCurrentTestObject(metaObject->className()); - qtest_qParseArgs(argc, argv, false); #ifdef QTESTLIB_USE_VALGRIND if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess) { const QStringList origAppArgs(QCoreApplication::arguments()); @@ -2025,8 +2012,6 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) } #endif - saveCoverageTool(argv[0], QTestLog::failCount()); - #ifdef QTESTLIB_USE_VALGRIND if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess) return callgrindChildExitCode; diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp index 7a4358a393a..1d66101a0fc 100644 --- a/src/testlib/qtestlog.cpp +++ b/src/testlib/qtestlog.cpp @@ -56,6 +56,22 @@ QT_BEGIN_NAMESPACE +static void saveCoverageTool(const char * appname, bool testfailed) +{ +#ifdef __COVERAGESCANNER__ + // install again to make sure the filename is correct. + // without this, a plugin or similar may have changed the filename. + __coveragescanner_install(appname); + __coveragescanner_teststate(testfailed ? "FAILED" : "PASSED"); + __coveragescanner_save(); + __coveragescanner_testname(""); + __coveragescanner_clear(); +#else + Q_UNUSED(appname); + Q_UNUSED(testfailed); +#endif +} + namespace QTest { int fails = 0; @@ -368,6 +384,7 @@ void QTestLog::stopLogging() QTest::TestLoggers::stopLogging(); QTest::TestLoggers::destroyLoggers(); QTest::loggerUsingStdout = false; + saveCoverageTool(QTestResult::currentAppname(), failCount() != 0); } void QTestLog::addLogger(LogMode mode, const char *filename) diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp index 1fb5bddcbbd..d6846f363b9 100644 --- a/src/testlib/qtestresult.cpp +++ b/src/testlib/qtestresult.cpp @@ -64,6 +64,8 @@ namespace QTest static const char *expectFailComment = 0; static int expectFailMode = 0; + + static const char *currentAppname = 0; } void QTestResult::reset() @@ -313,4 +315,14 @@ bool QTestResult::skipCurrentTest() return QTest::skipCurrentTest; } +void QTestResult::setCurrentAppname(const char *appname) +{ + QTest::currentAppname = appname; +} + +const char *QTestResult::currentAppname() +{ + return QTest::currentAppname; +} + QT_END_NAMESPACE diff --git a/src/testlib/qtestresult_p.h b/src/testlib/qtestresult_p.h index fc7f8347562..5bbb7e2d27b 100644 --- a/src/testlib/qtestresult_p.h +++ b/src/testlib/qtestresult_p.h @@ -95,6 +95,9 @@ public: static void setSkipCurrentTest(bool value); static bool skipCurrentTest(); + static void setCurrentAppname(const char *appname); + static const char *currentAppname(); + private: Q_DISABLE_COPY(QTestResult) }; From 3722bc5d3cd1b246f1480ea969a8d9cd5e41b1ee Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Mon, 6 Feb 2012 16:13:45 +0100 Subject: [PATCH 028/406] Ensure that posted events are sent by Q*Application::processEvents() Commit b7ca6a81dbf6a2b96c8f04b856372050618e60c0 removed a call to sendPostedEvents() that deemed unnecessary. Unfortunately, it is necessary, as shown by the tst_QScriptEngine::processEventsWhileRunning() test in the QtScript module. Re-add the call, but only when not waiting for more events. Change-Id: I648d66dd3ba484ad9e9a93fc03a9792cca5035c6 Reviewed-by: Friedemann Kleint Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 6de22cf58cb..305a8ddc953 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -569,6 +569,7 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) } retVal = true; } else { + int lastSerialCopy = d->lastSerial; bool hadModalSession = d->currentModalSessionCached != 0; // We cannot block the thread (and run in a tight loop). // Instead we will process all current pending events and return. @@ -631,6 +632,14 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) } } while (!d->interrupt && event != nil); + if ((flags & QEventLoop::WaitForMoreEvents) == 0) { + // when called "manually", always send posted events + d->processPostedEvents(); + } + + // be sure to return true if the posted event source fired + retVal = retVal || lastSerialCopy != d->lastSerial; + // Since the window that holds modality might have changed while processing // events, we we need to interrupt when we return back the previous process // event recursion to ensure that we spin the correct modal session. From e09025c1b6d43342e3086b7179109a08f39afd10 Mon Sep 17 00:00:00 2001 From: jian liang Date: Sun, 22 Jan 2012 22:38:49 +0800 Subject: [PATCH 029/406] fix memory leak of QLibraryPrivate this commit is aimed to fix QTBUG-4341. now QFactoryLoaderPrivate's destructor will call unload() to QLibaryPrivate object which will destory the plugin's root instance if its refcount reach zero. Task-number: QTBUG-4341 Change-Id: I3cd3e071b34271bf5802ab09f6c125beda5e9844 Reviewed-by: Robin Burchell Reviewed-by: David Faure Reviewed-by: Olivier Goffart --- src/corelib/plugin/qfactoryloader.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index e887ae8bf92..fe5aea0e8a9 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -78,8 +78,11 @@ public: QFactoryLoaderPrivate::~QFactoryLoaderPrivate() { - for (int i = 0; i < libraryList.count(); ++i) - libraryList.at(i)->release(); + for (int i = 0; i < libraryList.count(); ++i) { + QLibraryPrivate *library = libraryList.at(i); + library->unload(); + library->release(); + } } QFactoryLoader::QFactoryLoader(const char *iid, @@ -142,7 +145,10 @@ void QFactoryLoader::update() library->release(); continue; } - QObject *instance = library->instance(); + + if (!library->inst) + library->inst = library->instance(); + QObject *instance = library->inst.data(); if (!instance) { library->release(); // ignore plugins that have a valid signature but cannot be loaded. @@ -215,8 +221,11 @@ QObject *QFactoryLoader::instance(const QString &key) const QString lowered = d->cs ? key : key.toLower(); if (QLibraryPrivate* library = d->keyMap.value(lowered)) { if (library->instance || library->loadPlugin()) { - if (QObject *obj = library->instance()) { - if (obj && !obj->parent()) + if (!library->inst) + library->inst = library->instance(); + QObject *obj = library->inst.data(); + if (obj) { + if (!obj->parent()) obj->moveToThread(QCoreApplicationPrivate::mainThread()); return obj; } From fe2344bd44e183b9893934d175c61a725af29b90 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Mon, 6 Feb 2012 18:36:32 +0100 Subject: [PATCH 030/406] Use the QNX implementation of mkdtemp for win and wince. There is no mktemp for Windows CE, nor mkdtemp. So use the implementation for QNX for Windows CE too, to simplify the implementation use it for windows too. Change-Id: Icddaf474a2d696752d8f9774fb4f033454e34e83 Reviewed-by: David Faure Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qtemporarydir.cpp | 39 ++++++++++++-------------------- 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/src/corelib/io/qtemporarydir.cpp b/src/corelib/io/qtemporarydir.cpp index 53a48609e59..13969ca90ec 100644 --- a/src/corelib/io/qtemporarydir.cpp +++ b/src/corelib/io/qtemporarydir.cpp @@ -53,8 +53,7 @@ #include // mkdtemp #ifdef Q_OS_WIN -#include -#include +#include #endif QT_BEGIN_NAMESPACE @@ -95,7 +94,7 @@ static QString defaultTemplateName() return QDir::tempPath() + QLatin1Char('/') + baseName + QLatin1String("-XXXXXX"); } -#ifdef Q_OS_QNX +#if defined(Q_OS_QNX ) || defined(Q_OS_WIN) static char *mkdtemp(char *templateName) { static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; @@ -123,33 +122,26 @@ static char *mkdtemp(char *templateName) v /= 62; XXXXXX[5] = letters[v % 62]; - if (!mkdir(templateName, 0700)) - return templateName; - } + QString templateNameStr = QFile::decodeName(templateName); + QFileSystemEntry fileSystemEntry(templateNameStr); + if (QFileSystemEngine::createDirectory(fileSystemEntry, false)) { + QSystemError error; + QFileSystemEngine::setPermissions(fileSystemEntry, + QFile::ReadOwner | + QFile::WriteOwner | + QFile::ExeOwner, error); + if (error.error() != 0) + continue; + return templateName; + } + } return 0; } #endif void QTemporaryDirPrivate::create(const QString &templateName) { -#ifdef Q_OS_WIN - QString buffer = templateName; - // Windows' mktemp believes 26 temp files per process ought to be enough for everyone (!) - // Let's add a few random chars then, before the XXXXXX template. - for (int i = 0 ; i < 4 ; ++i) - buffer += QChar((qrand() & 0xffff) % (26) + 'A'); - if (!buffer.endsWith(QLatin1String("XXXXXX"))) - buffer += QLatin1String("XXXXXX"); - QFileSystemEntry baseEntry(buffer); - QFileSystemEntry::NativePath basePath = baseEntry.nativeFilePath(); - wchar_t* array = (wchar_t*)basePath.utf16(); - if (_wmktemp(array) && ::CreateDirectory(array, 0)) { - success = true; - QFileSystemEntry entry(QString::fromWCharArray(array), QFileSystemEntry::FromNativePath()); - path = entry.filePath(); - } -#else QByteArray buffer = QFile::encodeName(templateName); if (!buffer.endsWith("XXXXXX")) buffer += "XXXXXX"; @@ -157,7 +149,6 @@ void QTemporaryDirPrivate::create(const QString &templateName) success = true; path = QFile::decodeName(buffer.constData()); } -#endif } //************* QTemporaryDir From ba1cf5dae397031730fb77321db1807937e81617 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Fri, 13 Jan 2012 12:07:11 +0100 Subject: [PATCH 031/406] Removed image format specific template functions in raster engine. Simplified the raster engine by treating image formats in a more generic way and removed some unused code. Change-Id: Ib3979a1a6e3e6f17c5002248545779ec36fff7c9 Reviewed-by: Gunnar Sletta --- src/gui/image/qimage.cpp | 511 +-- src/gui/image/qpixmap_blitter.cpp | 26 +- src/gui/image/qpixmap_raster.cpp | 42 +- src/gui/painting/qblendfunctions.cpp | 208 +- src/gui/painting/qdrawhelper.cpp | 3834 +++++++------------- src/gui/painting/qdrawhelper_neon.cpp | 2 +- src/gui/painting/qdrawhelper_p.h | 1361 +------ src/gui/painting/qdrawhelper_sse2.cpp | 2 +- src/gui/painting/qdrawhelper_sse_p.h | 2 +- src/gui/painting/qmemrotate.cpp | 380 +- src/gui/painting/qmemrotate_p.h | 38 +- tests/auto/gui/image/qimage/tst_qimage.cpp | 71 +- 12 files changed, 1849 insertions(+), 4628 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 07af19d06a6..5b23dbf4dcb 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -74,30 +74,6 @@ static inline bool isLocked(QImageData *data) return data != 0 && data->is_locked; } -static inline bool checkPixelSize(const QImage::Format format) -{ - switch (format) { - case QImage::Format_ARGB8565_Premultiplied: - return (sizeof(qargb8565) == 3); - case QImage::Format_RGB666: - return (sizeof(qrgb666) == 3); - case QImage::Format_ARGB6666_Premultiplied: - return (sizeof(qargb6666) == 3); - case QImage::Format_RGB555: - return (sizeof(qrgb555) == 2); - case QImage::Format_ARGB8555_Premultiplied: - return (sizeof(qargb8555) == 3); - case QImage::Format_RGB888: - return (sizeof(qrgb888) == 3); - case QImage::Format_RGB444: - return (sizeof(qrgb444) == 2); - case QImage::Format_ARGB4444_Premultiplied: - return (sizeof(qargb4444) == 2); - default: - return true; - } -} - #if defined(Q_CC_DEC) && defined(__alpha) && (__DECCXX_VER-0 >= 50190001) #pragma message disable narrowptr #endif @@ -141,12 +117,6 @@ QImageData * QImageData::create(const QSize &size, QImage::Format format, int nu if (!size.isValid() || numColors < 0 || format == QImage::Format_Invalid) return 0; // invalid parameter(s) - if (!checkPixelSize(format)) { - qWarning("QImageData::create(): Invalid pixel size for format %i", - format); - return 0; - } - uint width = size.width(); uint height = size.height(); uint depth = qt_depthForFormat(format); @@ -793,12 +763,6 @@ QImageData *QImageData::create(uchar *data, int width, int height, int bpl, QIm if (format == QImage::Format_Invalid) return d; - if (!checkPixelSize(format)) { - qWarning("QImageData::create(): Invalid pixel size for format %i", - format); - return 0; - } - const int depth = qt_depthForFormat(format); const int calc_bytes_per_line = ((width * depth + 31)/32) * 4; const int min_bytes_per_line = (width * depth + 7)/8; @@ -1708,9 +1672,8 @@ void QImage::fill(const QColor &color) pixel = PREMUL(pixel); fill((uint) pixel); - } else if (d->depth == 16 && d->format == QImage::Format_RGB16) { - qrgb565 p(color.rgba()); - fill((uint) p.rawValue()); + } else if (d->format == QImage::Format_RGB16) { + fill((uint) qConvertRgb32To16(color.rgba())); } else if (d->depth == 1) { if (color == Qt::color1) @@ -2025,12 +1988,12 @@ static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConvers quint16 colorTableRGB16[256]; if (data->colortable.isEmpty()) { for (int i = 0; i < 256; ++i) - colorTableRGB16[i] = qt_colorConvert(qRgb(i, i, i), 0); + colorTableRGB16[i] = qConvertRgb32To16(qRgb(i, i, i)); } else { // 1) convert the existing colors to RGB16 const int tableSize = data->colortable.size(); for (int i = 0; i < tableSize; ++i) - colorTableRGB16[i] = qt_colorConvert(data->colortable.at(i), 0); + colorTableRGB16[i] = qConvertRgb32To16(data->colortable.at(i)); data->colortable = QVector(); // 2) fill the rest of the table in case src_data > colortable.size() @@ -2068,7 +2031,8 @@ static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFl quint16 *dst_data = (quint16 *) data->data; for (int i = 0; i < data->height; ++i) { - qt_memconvert(dst_data, src_data, data->width); + for (int j = 0; j < data->width; ++j) + dst_data[j] = qConvertRgb32To16(src_data[j]); src_data = (quint32 *) (((char*)src_data) + src_bytes_per_line); dst_data = (quint16 *) (((char*)dst_data) + dst_bytes_per_line); } @@ -2878,60 +2842,33 @@ static void convert_Mono_to_Indexed8(QImageData *dest, const QImageData *src, Qt } } -#define CONVERT_DECL(DST, SRC) \ - static void convert_##SRC##_to_##DST(QImageData *dest, \ - const QImageData *src, \ - Qt::ImageConversionFlags) \ - { \ - qt_rectconvert(reinterpret_cast(dest->data), \ - reinterpret_cast(src->data), \ - 0, 0, src->width, src->height, \ - dest->bytes_per_line, src->bytes_per_line); \ +// Cannot be used with indexed formats. +static void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + const int buffer_size = 2048; + uint buffer[buffer_size]; + const QPixelLayout *srcLayout = &qPixelLayouts[src->format]; + const QPixelLayout *destLayout = &qPixelLayouts[dest->format]; + const uchar *srcData = src->data; + uchar *destData = dest->data; + + FetchPixelsFunc fetch = qFetchPixels[srcLayout->bpp]; + StorePixelsFunc store = qStorePixels[destLayout->bpp]; + + for (int y = 0; y < src->height; ++y) { + int x = 0; + while (x < src->width) { + int l = qMin(src->width - x, buffer_size); + const uint *ptr = fetch(buffer, srcData, x, l); + ptr = srcLayout->convertToARGB32PM(buffer, ptr, l, srcLayout, 0); + ptr = destLayout->convertFromARGB32PM(buffer, ptr, l, destLayout, 0); + store(destData, ptr, x, l); + x += l; + } + srcData += src->bytes_per_line; + destData += dest->bytes_per_line; } - -CONVERT_DECL(quint32, quint16) -CONVERT_DECL(quint16, quint32) -CONVERT_DECL(quint32, qargb8565) -CONVERT_DECL(qargb8565, quint32) -CONVERT_DECL(quint32, qrgb555) -CONVERT_DECL(qrgb666, quint32) -CONVERT_DECL(quint32, qrgb666) -CONVERT_DECL(qargb6666, quint32) -CONVERT_DECL(quint32, qargb6666) -CONVERT_DECL(qrgb555, quint32) -#if (defined(QT_QWS_DEPTH_15) && defined(QT_QWS_DEPTH_16)) -CONVERT_DECL(quint16, qrgb555) -CONVERT_DECL(qrgb555, quint16) -#endif -CONVERT_DECL(quint32, qrgb888) -CONVERT_DECL(qrgb888, quint32) -CONVERT_DECL(quint32, qargb8555) -CONVERT_DECL(qargb8555, quint32) -CONVERT_DECL(quint32, qrgb444) -CONVERT_DECL(qrgb444, quint32) -CONVERT_DECL(quint32, qargb4444) -CONVERT_DECL(qargb4444, quint32) -#undef CONVERT_DECL -#define CONVERT_PTR(DST, SRC) convert_##SRC##_to_##DST - -/* - Format_Invalid, - Format_Mono, - Format_MonoLSB, - Format_Indexed8, - Format_RGB32, - Format_ARGB32, - Format_ARGB32_Premultiplied, - Format_RGB16, - Format_ARGB8565_Premultiplied, - Format_RGB666, - Format_ARGB6666_Premultiplied, - Format_RGB555, - Format_ARGB8555_Premultiplied, - Format_RGB888 - Format_RGB444 - Format_ARGB4444_Premultiplied -*/ +} // first index source, second dest @@ -3005,15 +2942,15 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, mask_alpha_converter, mask_alpha_converter, - CONVERT_PTR(quint16, quint32), - CONVERT_PTR(qargb8565, quint32), - CONVERT_PTR(qrgb666, quint32), - CONVERT_PTR(qargb6666, quint32), - CONVERT_PTR(qrgb555, quint32), - CONVERT_PTR(qargb8555, quint32), - CONVERT_PTR(qrgb888, quint32), - CONVERT_PTR(qrgb444, quint32), - CONVERT_PTR(qargb4444, quint32) + convert_generic, + convert_generic, + convert_generic, + convert_generic, + convert_generic, + convert_generic, + convert_generic, + convert_generic, + convert_generic }, // Format_RGB32 { @@ -3024,15 +2961,15 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat mask_alpha_converter, 0, convert_ARGB_to_ARGB_PM, - CONVERT_PTR(quint16, quint32), - CONVERT_PTR(qargb8565, quint32), - CONVERT_PTR(qrgb666, quint32), - CONVERT_PTR(qargb6666, quint32), - CONVERT_PTR(qrgb555, quint32), - CONVERT_PTR(qargb8555, quint32), - CONVERT_PTR(qrgb888, quint32), - CONVERT_PTR(qrgb444, quint32), - CONVERT_PTR(qargb4444, quint32) + convert_generic, + convert_generic, + convert_generic, + convert_generic, + convert_generic, + convert_generic, + convert_generic, + convert_generic, + convert_generic }, // Format_ARGB32 { @@ -3059,15 +2996,15 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - CONVERT_PTR(quint32, quint16), - CONVERT_PTR(quint32, quint16), - CONVERT_PTR(quint32, quint16), + convert_generic, + convert_generic, + convert_generic, 0, 0, 0, 0, #if defined(QT_QWS_DEPTH_15) && defined(QT_QWS_DEPTH_16) - CONVERT_PTR(qrgb555, quint16), + convert_generic, #else 0, #endif @@ -3082,9 +3019,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - CONVERT_PTR(quint32, qargb8565), - CONVERT_PTR(quint32, qargb8565), - CONVERT_PTR(quint32, qargb8565), + convert_generic, + convert_generic, + convert_generic, 0, 0, 0, @@ -3101,9 +3038,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - CONVERT_PTR(quint32, qrgb666), - CONVERT_PTR(quint32, qrgb666), - CONVERT_PTR(quint32, qrgb666), + convert_generic, + convert_generic, + convert_generic, 0, 0, 0, @@ -3120,9 +3057,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - CONVERT_PTR(quint32, qargb6666), - CONVERT_PTR(quint32, qargb6666), - CONVERT_PTR(quint32, qargb6666), + convert_generic, + convert_generic, + convert_generic, 0, 0, 0, @@ -3139,11 +3076,11 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - CONVERT_PTR(quint32, qrgb555), - CONVERT_PTR(quint32, qrgb555), - CONVERT_PTR(quint32, qrgb555), + convert_generic, + convert_generic, + convert_generic, #if defined(QT_QWS_DEPTH_15) && defined(QT_QWS_DEPTH_16) - CONVERT_PTR(quint16, qrgb555), + convert_generic, #else 0, #endif @@ -3162,9 +3099,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - CONVERT_PTR(quint32, qargb8555), - CONVERT_PTR(quint32, qargb8555), - CONVERT_PTR(quint32, qargb8555), + convert_generic, + convert_generic, + convert_generic, 0, 0, 0, @@ -3181,9 +3118,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - CONVERT_PTR(quint32, qrgb888), - CONVERT_PTR(quint32, qrgb888), - CONVERT_PTR(quint32, qrgb888), + convert_generic, + convert_generic, + convert_generic, 0, 0, 0, @@ -3200,9 +3137,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - CONVERT_PTR(quint32, qrgb444), - CONVERT_PTR(quint32, qrgb444), - CONVERT_PTR(quint32, qrgb444), + convert_generic, + convert_generic, + convert_generic, 0, 0, 0, @@ -3219,9 +3156,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - CONVERT_PTR(quint32, qargb4444), - CONVERT_PTR(quint32, qargb4444), - CONVERT_PTR(quint32, qargb4444), + convert_generic, + convert_generic, + convert_generic, 0, 0, 0, @@ -3626,35 +3563,28 @@ QRgb QImage::pixel(int x, int y) const qWarning("QImage::pixel: coordinate (%d,%d) out of range", x, y); return 12345; } - const uchar * s = scanLine(y); + + const uchar * s = constScanLine(y); switch(d->format) { case Format_Mono: - return d->colortable.at((*(s + (x >> 3)) >> (7- (x & 7))) & 1); + return d->colortable.at((*(s + (x >> 3)) >> (~x & 7)) & 1); case Format_MonoLSB: return d->colortable.at((*(s + (x >> 3)) >> (x & 7)) & 1); case Format_Indexed8: return d->colortable.at((int)s[x]); - case Format_ARGB8565_Premultiplied: - return qt_colorConvert(reinterpret_cast(s)[x], 0); - case Format_RGB666: - return qt_colorConvert(reinterpret_cast(s)[x], 0); - case Format_ARGB6666_Premultiplied: - return qt_colorConvert(reinterpret_cast(s)[x], 0); - case Format_RGB555: - return qt_colorConvert(reinterpret_cast(s)[x], 0); - case Format_ARGB8555_Premultiplied: - return qt_colorConvert(reinterpret_cast(s)[x], 0); - case Format_RGB888: - return qt_colorConvert(reinterpret_cast(s)[x], 0); - case Format_RGB444: - return qt_colorConvert(reinterpret_cast(s)[x], 0); - case Format_ARGB4444_Premultiplied: - return qt_colorConvert(reinterpret_cast(s)[x], 0); + case Format_RGB32: + case Format_ARGB32: // Keep old behaviour. + case Format_ARGB32_Premultiplied: + return reinterpret_cast(s)[x]; case Format_RGB16: - return qt_colorConvert(reinterpret_cast(s)[x], 0); + return qConvertRgb16To32(reinterpret_cast(s)[x]); default: - return ((QRgb*)s)[x]; + break; } + const QPixelLayout *layout = &qPixelLayouts[d->format]; + uint result; + const uint *ptr = qFetchPixels[layout->bpp](&result, s, x, 1); + return *layout->convertToARGB32PM(&result, ptr, 1, layout, 0); } @@ -3693,7 +3623,6 @@ void QImage::setPixel(int x, int y, uint index_or_rgb) } // detach is called from within scanLine uchar * s = scanLine(y); - const quint32p p = quint32p::fromRawData(index_or_rgb); switch(d->format) { case Format_Mono: case Format_MonoLSB: @@ -3710,54 +3639,38 @@ void QImage::setPixel(int x, int y, uint index_or_rgb) else *(s + (x >> 3)) |= (1 << (7-(x & 7))); } - break; + return; case Format_Indexed8: if (index_or_rgb >= (uint)d->colortable.size()) { qWarning("QImage::setPixel: Index %d out of range", index_or_rgb); return; } s[x] = index_or_rgb; - break; + return; case Format_RGB32: //make sure alpha is 255, we depend on it in qdrawhelper for cases // when image is set as a texture pattern on a qbrush ((uint *)s)[x] = uint(255 << 24) | index_or_rgb; - break; + return; case Format_ARGB32: case Format_ARGB32_Premultiplied: ((uint *)s)[x] = index_or_rgb; - break; + return; case Format_RGB16: - ((quint16 *)s)[x] = qt_colorConvert(p, 0); - break; - case Format_ARGB8565_Premultiplied: - ((qargb8565*)s)[x] = qt_colorConvert(p, 0); - break; - case Format_RGB666: - ((qrgb666*)s)[x] = qt_colorConvert(p, 0); - break; - case Format_ARGB6666_Premultiplied: - ((qargb6666*)s)[x] = qt_colorConvert(p, 0); - break; - case Format_RGB555: - ((qrgb555*)s)[x] = qt_colorConvert(p, 0); - break; - case Format_ARGB8555_Premultiplied: - ((qargb8555*)s)[x] = qt_colorConvert(p, 0); - break; - case Format_RGB888: - ((qrgb888*)s)[x] = qt_colorConvert(p, 0); - break; - case Format_RGB444: - ((qrgb444*)s)[x] = qt_colorConvert(p, 0); - break; - case Format_ARGB4444_Premultiplied: - ((qargb4444*)s)[x] = qt_colorConvert(p, 0); - break; + ((quint16 *)s)[x] = qConvertRgb32To16(INV_PREMUL(index_or_rgb)); + return; case Format_Invalid: case NImageFormats: Q_ASSERT(false); + return; + default: + break; } + + const QPixelLayout *layout = &qPixelLayouts[d->format]; + uint result; + const uint *ptr = layout->convertFromARGB32PM(&result, &index_or_rgb, 1, layout, 0); + qStorePixels[layout->bpp](s, ptr, x, 1); } /*! @@ -3774,30 +3687,56 @@ bool QImage::allGray() const if (!d) return true; - if (d->depth == 32) { - int p = width()*height(); - const QRgb* b = (const QRgb*)bits(); - while (p--) - if (!qIsGray(*b++)) - return false; - } else if (d->depth == 16) { - int p = width()*height(); - const ushort* b = (const ushort *)bits(); - while (p--) - if (!qIsGray(qt_colorConvert(*b++, 0))) - return false; - } else if (d->format == QImage::Format_RGB888) { - int p = width()*height(); - const qrgb888* b = (const qrgb888 *)bits(); - while (p--) - if (!qIsGray(qt_colorConvert(*b++, 0))) - return false; - } else { - if (d->colortable.isEmpty()) - return true; - for (int i = 0; i < colorCount(); i++) + switch (d->format) { + case Format_Mono: + case Format_MonoLSB: + case Format_Indexed8: + for (int i = 0; i < d->colortable.size(); ++i) { if (!qIsGray(d->colortable.at(i))) return false; + } + return true; + case Format_RGB32: + case Format_ARGB32: + case Format_ARGB32_Premultiplied: + for (int j = 0; j < d->height; ++j) { + const QRgb *b = (const QRgb *)constScanLine(j); + for (int i = 0; i < d->width; ++i) { + if (!qIsGray(b[i])) + return false; + } + } + return true; + case Format_RGB16: + for (int j = 0; j < d->height; ++j) { + const quint16 *b = (const quint16 *)constScanLine(j); + for (int i = 0; i < d->width; ++i) { + if (!qIsGray(qConvertRgb16To32(b[i]))) + return false; + } + } + return true; + default: + break; + } + + const int buffer_size = 2048; + uint buffer[buffer_size]; + const QPixelLayout *layout = &qPixelLayouts[d->format]; + FetchPixelsFunc fetch = qFetchPixels[layout->bpp]; + for (int j = 0; j < d->height; ++j) { + const uchar *b = constScanLine(j); + int x = 0; + while (x < d->width) { + int l = qMin(d->width - x, buffer_size); + const uint *ptr = fetch(buffer, b, x, l); + ptr = layout->convertToARGB32PM(buffer, ptr, l, layout, 0); + for (int i = 0; i < l; ++i) { + if (!qIsGray(ptr[i])) + return false; + } + x += l; + } } return true; } @@ -4320,7 +4259,7 @@ QImage QImage::rgbSwapped() const case Format_Invalid: case NImageFormats: Q_ASSERT(false); - break; + return res; case Format_Mono: case Format_MonoLSB: case Format_Indexed8: @@ -4329,7 +4268,7 @@ QImage QImage::rgbSwapped() const QRgb c = res.d->colortable.at(i); res.d->colortable[i] = QRgb(((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00)); } - break; + return res; case Format_RGB32: case Format_ARGB32: case Format_ARGB32_Premultiplied: @@ -4345,7 +4284,7 @@ QImage QImage::rgbSwapped() const q++; } } - break; + return res; case Format_RGB16: res = QImage(d->width, d->height, d->format); QIMAGE_SANITYCHECK_MEMORY(res); @@ -4359,113 +4298,41 @@ QImage QImage::rgbSwapped() const q++; } } + return res; + default: break; - case Format_ARGB8565_Premultiplied: - res = QImage(d->width, d->height, d->format); - QIMAGE_SANITYCHECK_MEMORY(res); - for (int i = 0; i < d->height; i++) { - const quint8 *p = constScanLine(i); - quint8 *q = res.scanLine(i); - const quint8 *end = p + d->width * sizeof(qargb8565); - while (p < end) { - q[0] = p[0]; - q[1] = (p[1] & 0xe0) | (p[2] >> 3); - q[2] = (p[2] & 0x07) | (p[1] << 3); - p += sizeof(qargb8565); - q += sizeof(qargb8565); + } + + res = QImage(d->width, d->height, d->format); + QIMAGE_SANITYCHECK_MEMORY(res); + const QPixelLayout *layout = &qPixelLayouts[d->format]; + Q_ASSERT(layout->redWidth == layout->blueWidth); + FetchPixelsFunc fetch = qFetchPixels[layout->bpp]; + StorePixelsFunc store = qStorePixels[layout->bpp]; + + const uint redBlueMask = (1 << layout->redWidth) - 1; + const uint alphaGreenMask = (((1 << layout->alphaWidth) - 1) << layout->alphaShift) + | (((1 << layout->greenWidth) - 1) << layout->greenShift); + + const int buffer_size = 2048; + uint buffer[buffer_size]; + for (int i = 0; i < d->height; ++i) { + uchar *q = res.scanLine(i); + const uchar *p = constScanLine(i); + int x = 0; + while (x < d->width) { + int l = qMin(d->width - x, buffer_size); + const uint *ptr = fetch(buffer, p, x, l); + for (int j = 0; j < l; ++j) { + uint red = (ptr[j] >> layout->redShift) & redBlueMask; + uint blue = (ptr[j] >> layout->blueShift) & redBlueMask; + buffer[j] = (ptr[j] & alphaGreenMask) + | (red << layout->blueShift) + | (blue << layout->redShift); } + store(q, buffer, x, l); + x += l; } - break; - case Format_RGB666: - res = QImage(d->width, d->height, d->format); - QIMAGE_SANITYCHECK_MEMORY(res); - for (int i = 0; i < d->height; i++) { - qrgb666 *q = reinterpret_cast(res.scanLine(i)); - const qrgb666 *p = reinterpret_cast(constScanLine(i)); - const qrgb666 *end = p + d->width; - while (p < end) { - const QRgb rgb = quint32(*p++); - *q++ = qRgb(qBlue(rgb), qGreen(rgb), qRed(rgb)); - } - } - break; - case Format_ARGB6666_Premultiplied: - res = QImage(d->width, d->height, d->format); - QIMAGE_SANITYCHECK_MEMORY(res); - for (int i = 0; i < d->height; i++) { - const quint8 *p = constScanLine(i); - const quint8 *end = p + d->width * sizeof(qargb6666); - quint8 *q = res.scanLine(i); - while (p < end) { - q[0] = (p[1] >> 4) | ((p[2] & 0x3) << 4) | (p[0] & 0xc0); - q[1] = (p[1] & 0xf) | (p[0] << 4); - q[2] = (p[2] & 0xfc) | ((p[0] >> 4) & 0x3); - p += sizeof(qargb6666); - q += sizeof(qargb6666); - } - } - break; - case Format_RGB555: - res = QImage(d->width, d->height, d->format); - QIMAGE_SANITYCHECK_MEMORY(res); - for (int i = 0; i < d->height; i++) { - quint16 *q = (quint16*)res.scanLine(i); - const quint16 *p = (const quint16*)constScanLine(i); - const quint16 *end = p + d->width; - while (p < end) { - *q = ((*p << 10) & 0x7c00) | ((*p >> 10) & 0x1f) | (*p & 0x3e0); - p++; - q++; - } - } - break; - case Format_ARGB8555_Premultiplied: - res = QImage(d->width, d->height, d->format); - QIMAGE_SANITYCHECK_MEMORY(res); - for (int i = 0; i < d->height; i++) { - const quint8 *p = constScanLine(i); - quint8 *q = res.scanLine(i); - const quint8 *end = p + d->width * sizeof(qargb8555); - while (p < end) { - q[0] = p[0]; - q[1] = (p[1] & 0xe0) | (p[2] >> 2); - q[2] = (p[2] & 0x03) | ((p[1] << 2) & 0x7f); - p += sizeof(qargb8555); - q += sizeof(qargb8555); - } - } - break; - case Format_RGB888: - res = QImage(d->width, d->height, d->format); - QIMAGE_SANITYCHECK_MEMORY(res); - for (int i = 0; i < d->height; i++) { - quint8 *q = res.scanLine(i); - const quint8 *p = constScanLine(i); - const quint8 *end = p + d->width * sizeof(qrgb888); - while (p < end) { - q[0] = p[2]; - q[1] = p[1]; - q[2] = p[0]; - q += sizeof(qrgb888); - p += sizeof(qrgb888); - } - } - break; - case Format_RGB444: - case Format_ARGB4444_Premultiplied: - res = QImage(d->width, d->height, d->format); - QIMAGE_SANITYCHECK_MEMORY(res); - for (int i = 0; i < d->height; i++) { - quint16 *q = reinterpret_cast(res.scanLine(i)); - const quint16 *p = reinterpret_cast(constScanLine(i)); - const quint16 *end = p + d->width; - while (p < end) { - *q = (*p & 0xf0f0) | ((*p & 0x0f) << 8) | ((*p & 0xf00) >> 8); - p++; - q++; - } - } - break; } return res; } diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp index e5222fa2160..382c0b8d1a7 100644 --- a/src/gui/image/qpixmap_blitter.cpp +++ b/src/gui/image/qpixmap_blitter.cpp @@ -144,27 +144,11 @@ void QBlittablePlatformPixmap::fill(const QColor &color) m_alpha = true; } - uint pixel; - switch (blittable()->lock()->format()) { - case QImage::Format_ARGB32_Premultiplied: - pixel = PREMUL(color.rgba()); - break; - case QImage::Format_ARGB8565_Premultiplied: - pixel = qargb8565(color.rgba()).rawValue(); - break; - case QImage::Format_ARGB8555_Premultiplied: - pixel = qargb8555(color.rgba()).rawValue(); - break; - case QImage::Format_ARGB6666_Premultiplied: - pixel = qargb6666(color.rgba()).rawValue(); - break; - case QImage::Format_ARGB4444_Premultiplied: - pixel = qargb4444(color.rgba()).rawValue(); - break; - default: - pixel = color.rgba(); - break; - } + uint pixel = PREMUL(color.rgba()); + const QPixelLayout *layout = &qPixelLayouts[blittable()->lock()->format()]; + Q_ASSERT(layout->convertFromARGB32PM); + layout->convertFromARGB32PM(&pixel, &pixel, 1, layout, 0); + //so premultiplied formats are supported and ARGB32 and RGB32 blittable()->lock()->fill(pixel); } diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index 3fe52163133..8125b1360d8 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -202,46 +202,10 @@ void QRasterPlatformPixmap::fill(const QColor &color) image = QImage(image.width(), image.height(), toFormat); } } - - switch (image.format()) { - case QImage::Format_ARGB8565_Premultiplied: - pixel = qargb8565(color.rgba()).rawValue(); - break; - case QImage::Format_ARGB8555_Premultiplied: - pixel = qargb8555(color.rgba()).rawValue(); - break; - case QImage::Format_ARGB6666_Premultiplied: - pixel = qargb6666(color.rgba()).rawValue(); - break; - case QImage::Format_ARGB4444_Premultiplied: - pixel = qargb4444(color.rgba()).rawValue(); - break; - default: - pixel = PREMUL(color.rgba()); - break; - } - } else { - switch (image.format()) { - case QImage::Format_RGB16: - pixel = qt_colorConvert(color.rgba(), 0); - break; - case QImage::Format_RGB444: - pixel = qrgb444(color.rgba()).rawValue(); - break; - case QImage::Format_RGB555: - pixel = qrgb555(color.rgba()).rawValue(); - break; - case QImage::Format_RGB666: - pixel = qrgb666(color.rgba()).rawValue(); - break; - case QImage::Format_RGB888: - pixel = qrgb888(color.rgba()).rawValue(); - break; - default: - pixel = color.rgba(); - break; - } } + pixel = PREMUL(color.rgba()); + const QPixelLayout *layout = &qPixelLayouts[image.format()]; + layout->convertFromARGB32PM(&pixel, &pixel, 1, layout, 0); } else { pixel = 0; // ### what about 8 bits diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp index a83cadb1611..f17a630c8d0 100644 --- a/src/gui/painting/qblendfunctions.cpp +++ b/src/gui/painting/qblendfunctions.cpp @@ -71,21 +71,6 @@ struct SourceAndConstAlpha RGB16 (565) format target format ************************************************************************/ -static inline quint16 convert_argb32_to_rgb16(quint32 spix) -{ - quint32 b = spix; - quint32 g = spix; - b >>= 8; - g >>= 5; - b &= 0x0000f800; - g &= 0x000007e0; - spix >>= 3; - b |= g; - spix &= 0x0000001f; - b |= spix; - return b; -} - struct Blend_RGB16_on_RGB16_NoAlpha { inline void write(quint16 *dst, quint16 src) { *dst = src; } @@ -108,46 +93,11 @@ struct Blend_RGB16_on_RGB16_ConstAlpha { quint32 m_ialpha; }; -struct Blend_ARGB24_on_RGB16_SourceAlpha { - inline void write(quint16 *dst, const qargb8565 &src) { - const uint alpha = src.alpha(); - if (alpha) { - quint16 s = src.rawValue16(); - if (alpha < 255) - s += BYTE_MUL_RGB16(*dst, 255 - alpha); - *dst = s; - } - } - - inline void flush(void *) {} -}; - -struct Blend_ARGB24_on_RGB16_SourceAndConstAlpha { - inline Blend_ARGB24_on_RGB16_SourceAndConstAlpha(quint32 alpha) { - m_alpha = (alpha * 255) >> 8; - } - - inline void write(quint16 *dst, qargb8565 src) { - src = src.byte_mul(src.alpha(m_alpha)); - const uint alpha = src.alpha(); - if (alpha) { - quint16 s = src.rawValue16(); - if (alpha < 255) - s += BYTE_MUL_RGB16(*dst, 255 - alpha); - *dst = s; - } - } - - inline void flush(void *) {} - - quint32 m_alpha; -}; - struct Blend_ARGB32_on_RGB16_SourceAlpha { inline void write(quint16 *dst, quint32 src) { const quint8 alpha = qAlpha(src); - if(alpha) { - quint16 s = convert_argb32_to_rgb16(src); + if (alpha) { + quint16 s = qConvertRgb32To16(src); if(alpha < 255) s += BYTE_MUL_RGB16(*dst, 255 - alpha); *dst = s; @@ -166,7 +116,7 @@ struct Blend_ARGB32_on_RGB16_SourceAndConstAlpha { src = BYTE_MUL(src, m_alpha); const quint8 alpha = qAlpha(src); if(alpha) { - quint16 s = convert_argb32_to_rgb16(src); + quint16 s = qConvertRgb32To16(src); if(alpha < 255) s += BYTE_MUL_RGB16(*dst, 255 - alpha); *dst = s; @@ -203,32 +153,6 @@ void qt_scale_image_rgb16_on_rgb16(uchar *destPixels, int dbpl, } } -void qt_scale_image_argb24_on_rgb16(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - const QRectF &targetRect, - const QRectF &sourceRect, - const QRect &clip, - int const_alpha) -{ -#ifdef QT_DEBUG_DRAW - printf("qt_scale_argb24_on_rgb16: dst=(%p, %d), src=(%p, %d), target=(%d, %d), [%d x %d], src=(%d, %d) [%d x %d] alpha=%d\n", - destPixels, dbpl, srcPixels, sbpl, - targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(), - sourceRect.x(), sourceRect.y(), sourceRect.width(), sourceRect.height(), - const_alpha); -#endif - if (const_alpha == 256) { - Blend_ARGB24_on_RGB16_SourceAlpha noAlpha; - qt_scale_image_16bit(destPixels, dbpl, srcPixels, sbpl, - targetRect, sourceRect, clip, noAlpha); - } else { - Blend_ARGB24_on_RGB16_SourceAndConstAlpha constAlpha(const_alpha); - qt_scale_image_16bit(destPixels, dbpl, srcPixels, sbpl, - targetRect, sourceRect, clip, constAlpha); - } -} - - void qt_scale_image_argb32_on_rgb16(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, const QRectF &targetRect, @@ -280,7 +204,6 @@ void qt_blend_rgb16_on_rgb16(uchar *dst, int dbpl, } } } else if (const_alpha != 0) { - SourceAndConstAlpha alpha(const_alpha); // expects the 0-256 range quint16 *d = (quint16 *) dst; const quint16 *s = (const quint16 *) src; quint8 a = (255 * const_alpha) >> 8; @@ -296,79 +219,6 @@ void qt_blend_rgb16_on_rgb16(uchar *dst, int dbpl, } -template void qt_blend_argb24_on_rgb16(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, const T &alphaFunc) -{ - int srcOffset = w*3; - int dstJPL = dbpl / 2; - quint16 *dst = (quint16 *) destPixels; - int dstExtraStride = dstJPL - w; - - for (int y=0; y>8) + (0x80 << 8)) >> 8) & 0xf800; - quint32 rg = ((siag + (siag>>8) + (0x80 << 3)) >> 8) & 0x07e0; - quint32 rb = ((siab + (siab>>8) + (0x80 >> 3)) >> 8) & 0x001f; - - *dst = alphaFunc.bytemul(spix) + rr + rg + rb; - } - - ++dst; - src += 3; - } - dst += dstExtraStride; - } - -} - -static void qt_blend_argb24_on_rgb16(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha) -{ -#ifdef QT_DEBUG_DRAW - printf("qt_blend_argb24_on_rgb16: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n", - destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha); -#endif - - if (const_alpha != 256) { - SourceAndConstAlpha alphaFunc(const_alpha); - qt_blend_argb24_on_rgb16(destPixels, dbpl, srcPixels, sbpl, w, h, alphaFunc); - } else { - SourceOnlyAlpha alphaFunc; - qt_blend_argb24_on_rgb16(destPixels, dbpl, srcPixels, sbpl, w, h, alphaFunc); - } -} - - - - void qt_blend_argb32_on_rgb16_const_alpha(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, int w, int h, @@ -383,7 +233,7 @@ void qt_blend_argb32_on_rgb16_const_alpha(uchar *destPixels, int dbpl, uint s = src[i]; s = BYTE_MUL(s, const_alpha); int alpha = qAlpha(s); - s = convert_argb32_to_rgb16(s); + s = qConvertRgb32To16(s); s += BYTE_MUL_RGB16(dst[i], 255 - alpha); dst[i] = s; } @@ -412,7 +262,7 @@ static void qt_blend_argb32_on_rgb16(uchar *destPixels, int dbpl, quint32 alpha = spix >> 24; if (alpha == 255) { - dst[x] = convert_argb32_to_rgb16(spix); + dst[x] = qConvertRgb32To16(spix); } else if (alpha != 0) { quint32 dpix = dst[x]; @@ -473,7 +323,7 @@ static void qt_blend_rgb32_on_rgb16(uchar *destPixels, int dbpl, while (dst < dstEnd) { const quint32 *srcEnd = src + w; while (src < srcEnd) { - *dst = convert_argb32_to_rgb16(*src); + *dst = qConvertRgb32To16(*src); ++dst; ++src; } @@ -545,19 +395,11 @@ void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl, const uint *src = (const uint *) srcPixels; uint *dst = (uint *) destPixels; - if (w <= 64) { - for (int y=0; y(destPixels), dbpl, - reinterpret_cast(srcPixels), sbpl, - targetRect, sourceRect, clip, targetRectTransform, noAlpha); - } else { - Blend_ARGB24_on_RGB16_SourceAndConstAlpha constAlpha(const_alpha); - qt_transform_image(reinterpret_cast(destPixels), dbpl, - reinterpret_cast(srcPixels), sbpl, - targetRect, sourceRect, clip, targetRectTransform, constAlpha); - } -} - - void qt_transform_image_argb32_on_rgb16(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, const QRectF &targetRect, @@ -903,7 +723,7 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB32, qt_scale_image_argb32_on_rgb16, // Format_ARGB32_Premultiplied, qt_scale_image_rgb16_on_rgb16, // Format_RGB16, - qt_scale_image_argb24_on_rgb16, // Format_ARGB8565_Premultiplied, + 0, // Format_ARGB8565_Premultiplied, 0, // Format_RGB666, 0, // Format_ARGB6666_Premultiplied, 0, // Format_RGB555, @@ -1195,7 +1015,7 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB32, qt_blend_argb32_on_rgb16, // Format_ARGB32_Premultiplied, qt_blend_rgb16_on_rgb16, // Format_RGB16, - qt_blend_argb24_on_rgb16, // Format_ARGB8565_Premultiplied, + 0, // Format_ARGB8565_Premultiplied, 0, // Format_RGB666, 0, // Format_ARGB6666_Premultiplied, 0, // Format_RGB555, @@ -1486,7 +1306,7 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB32, qt_transform_image_argb32_on_rgb16, // Format_ARGB32_Premultiplied, qt_transform_image_rgb16_on_rgb16, // Format_RGB16, - qt_transform_image_argb24_on_rgb16, // Format_ARGB8565_Premultiplied, + 0, // Format_ARGB8565_Premultiplied, 0, // Format_RGB666, 0, // Format_ARGB6666_Premultiplied, 0, // Format_RGB555, diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 13b8c8cae5d..6a34b5c7ca0 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -79,6 +79,244 @@ enum { // must be multiple of 4 for easier SIMD implementations static const int buffer_size = 2048; + + + +// To convert in place, let 'dest' and 'src' be the same. +static const uint *QT_FASTCALL convertIndexedToARGB32PM(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *clut) +{ + for (int i = 0; i < count; ++i) + buffer[i] = PREMUL(clut[src[i]]); + return buffer; +} + +static const uint *QT_FASTCALL convertPassThrough(uint *, const uint *src, int, + const QPixelLayout *, const QRgb *) +{ + return src; +} + +static const uint *QT_FASTCALL convertRGB16ToARGB32PM(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = qConvertRgb16To32(src[i]); + return buffer; +} + +static const uint *QT_FASTCALL convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = PREMUL(src[i]); + return buffer; +} + +static const uint *QT_FASTCALL convertToRGB32(uint *buffer, const uint *src, int count, + const QPixelLayout *layout, const QRgb *) +{ + Q_ASSERT(layout->redWidth >= 4); + Q_ASSERT(layout->greenWidth >= 4); + Q_ASSERT(layout->blueWidth >= 4); + Q_ASSERT(layout->alphaWidth == 0); + + const uint redMask = ((1 << layout->redWidth) - 1); + const uint greenMask = ((1 << layout->greenWidth) - 1); + const uint blueMask = ((1 << layout->blueWidth) - 1); + + const uchar redLeftShift = 8 - layout->redWidth; + const uchar greenLeftShift = 8 - layout->greenWidth; + const uchar blueLeftShift = 8 - layout->blueWidth; + + const uchar redRightShift = 2 * layout->redWidth - 8; + const uchar greenRightShift = 2 * layout->greenWidth - 8; + const uchar blueRightShift = 2 * layout->blueWidth - 8; + + for (int i = 0; i < count; ++i) { + uint red = (src[i] >> layout->redShift) & redMask; + uint green = (src[i] >> layout->greenShift) & greenMask; + uint blue = (src[i] >> layout->blueShift) & blueMask; + + red = ((red << redLeftShift) | (red >> redRightShift)) << 16; + green = ((green << greenLeftShift) | (green >> greenRightShift)) << 8; + blue = (blue << blueLeftShift) | (blue >> blueRightShift); + buffer[i] = 0xff000000 | red | green | blue; + } + + return buffer; +} + +static const uint *QT_FASTCALL convertToARGB32PM(uint *buffer, const uint *src, int count, + const QPixelLayout *layout, const QRgb *) +{ + Q_ASSERT(layout->redWidth >= 4); + Q_ASSERT(layout->greenWidth >= 4); + Q_ASSERT(layout->blueWidth >= 4); + Q_ASSERT(layout->alphaWidth >= 4); + + const uint redMask = ((1 << layout->redWidth) - 1); + const uint greenMask = ((1 << layout->greenWidth) - 1); + const uint blueMask = ((1 << layout->blueWidth) - 1); + + const uchar redLeftShift = 8 - layout->redWidth; + const uchar greenLeftShift = 8 - layout->greenWidth; + const uchar blueLeftShift = 8 - layout->blueWidth; + + const uchar redRightShift = 2 * layout->redWidth - 8; + const uchar greenRightShift = 2 * layout->greenWidth - 8; + const uchar blueRightShift = 2 * layout->blueWidth - 8; + + const uint alphaMask = ((1 << layout->alphaWidth) - 1); + const uchar alphaLeftShift = 8 - layout->alphaWidth; + const uchar alphaRightShift = 2 * layout->alphaWidth - 8; + + if (layout->premultiplied) { + for (int i = 0; i < count; ++i) { + uint alpha = (src[i] >> layout->alphaShift) & alphaMask; + uint red = (src[i] >> layout->redShift) & redMask; + uint green = (src[i] >> layout->greenShift) & greenMask; + uint blue = (src[i] >> layout->blueShift) & blueMask; + + alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift); + red = qMin(alpha, (red << redLeftShift) | (red >> redRightShift)); + green = qMin(alpha, (green << greenLeftShift) | (green >> greenRightShift)); + blue = qMin(alpha, (blue << blueLeftShift) | (blue >> blueRightShift)); + buffer[i] = (alpha << 24) | (red << 16) | (green << 8) | blue; + } + } else { + for (int i = 0; i < count; ++i) { + uint alpha = (src[i] >> layout->alphaShift) & alphaMask; + uint red = (src[i] >> layout->redShift) & redMask; + uint green = (src[i] >> layout->greenShift) & greenMask; + uint blue = (src[i] >> layout->blueShift) & blueMask; + + alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift); + red = (red << redLeftShift) | (red >> redRightShift); + green = (green << greenLeftShift) | (green >> greenRightShift); + blue = (blue << blueLeftShift) | (blue >> blueRightShift); + buffer[i] = PREMUL((alpha << 24) | (red << 16) | (green << 8) | blue); + } + } + return buffer; +} + +static const uint *QT_FASTCALL convertRGB16FromARGB32PM(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = qConvertRgb32To16(INV_PREMUL(src[i])); + return buffer; +} + +static const uint *QT_FASTCALL convertARGB32FromARGB32PM(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = INV_PREMUL(src[i]); + return buffer; +} + +static const uint *QT_FASTCALL convertFromARGB32PM(uint *buffer, const uint *src, int count, + const QPixelLayout *layout, const QRgb *) +{ + Q_ASSERT(layout->redWidth <= 8); + Q_ASSERT(layout->greenWidth <= 8); + Q_ASSERT(layout->blueWidth <= 8); + Q_ASSERT(layout->alphaWidth <= 8); + + const uint redMask = (1 << layout->redWidth) - 1; + const uint greenMask = (1 << layout->greenWidth) - 1; + const uint blueMask = (1 << layout->blueWidth) - 1; + const uint alphaMask = (1 << layout->alphaWidth) - 1; + + const uchar redRightShift = 24 - layout->redWidth; + const uchar greenRightShift = 16 - layout->greenWidth; + const uchar blueRightShift = 8 - layout->blueWidth; + const uchar alphaRightShift = 32 - layout->alphaWidth; + + if (!layout->premultiplied) { + for (int i = 0; i < count; ++i) + buffer[i] = qAlpha(src[i]) == 255 ? src[i] : INV_PREMUL(src[i]); + src = buffer; + } + for (int i = 0; i < count; ++i) { + uint red = ((src[i] >> redRightShift) & redMask) << layout->redShift; + uint green = ((src[i] >> greenRightShift) & greenMask) << layout->greenShift; + uint blue = ((src[i] >> blueRightShift) & blueMask) << layout->blueShift; + uint alpha = ((src[i] >> alphaRightShift) & alphaMask) << layout->alphaShift; + buffer[i] = red | green | blue | alpha; + } + return buffer; +} + +// Note: +// convertToArgb32() assumes that no color channel is less than 4 bits. +// convertFromArgb32() assumes that no color channel is more than 8 bits. +// QImage::rgbSwapped() assumes that the red and blue color channels have the same number of bits. +QPixelLayout qPixelLayouts[QImage::NImageFormats] = { + { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPPNone, 0, 0 }, // Format_Invalid + { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1MSB, convertIndexedToARGB32PM, 0 }, // Format_Mono + { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1LSB, convertIndexedToARGB32PM, 0 }, // Format_MonoLSB + { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertIndexedToARGB32PM, 0 }, // Format_Indexed8 + { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP32, convertPassThrough, convertPassThrough }, // Format_RGB32 + { 8, 16, 8, 8, 8, 0, 8, 24, false, QPixelLayout::BPP32, convertARGB32ToARGB32PM, convertARGB32FromARGB32PM }, // Format_ARGB32 + { 8, 16, 8, 8, 8, 0, 8, 24, true, QPixelLayout::BPP32, convertPassThrough, convertPassThrough }, // Format_ARGB32_Premultiplied + { 5, 11, 6, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertRGB16ToARGB32PM, convertRGB16FromARGB32PM }, // Format_RGB16 + { 5, 19, 6, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB8565_Premultiplied + { 6, 12, 6, 6, 6, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM }, // Format_RGB666 + { 6, 12, 6, 6, 6, 0, 6, 18, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB6666_Premultiplied + { 5, 10, 5, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM }, // Format_RGB555 + { 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB8555_Premultiplied + { 8, 0, 8, 8, 8, 16, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM }, // Format_RGB888 + { 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM }, // Format_RGB444 + { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, convertToARGB32PM, convertFromARGB32PM } // Format_ARGB4444_Premultiplied +}; + +FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount] = { + 0, // BPPNone + fetchPixels, // BPP1MSB + fetchPixels, // BPP1LSB + fetchPixels, // BPP8 + fetchPixels, // BPP16 + fetchPixels, // BPP24 + fetchPixels // BPP32 +}; + +StorePixelsFunc qStorePixels[QPixelLayout::BPPCount] = { + 0, // BPPNone + storePixels, // BPP1MSB + storePixels, // BPP1LSB + storePixels, // BPP8 + storePixels, // BPP16 + storePixels, // BPP24 + storePixels // BPP32 +}; + +typedef uint (QT_FASTCALL *FetchPixelFunc)(const uchar *src, int index); +typedef void (QT_FASTCALL *StorePixelFunc)(uchar *dest, int index, uint pixel); + +FetchPixelFunc qFetchPixel[QPixelLayout::BPPCount] = { + 0, // BPPNone + fetchPixel, // BPP1MSB + fetchPixel, // BPP1LSB + fetchPixel, // BPP8 + fetchPixel, // BPP16 + fetchPixel, // BPP24 + fetchPixel // BPP32 +}; + +StorePixelFunc qStorePixel[QPixelLayout::BPPCount] = { + 0, // BPPNone + storePixel, // BPP1MSB + storePixel, // BPP1LSB + storePixel, // BPP8 + storePixel, // BPP16 + storePixel, // BPP24 + storePixel // BPP32 +}; + + /* Destination fetch. This is simple as we don't have to do bounds checks or transformations @@ -110,14 +348,6 @@ static uint * QT_FASTCALL destFetchMonoLsb(uint *buffer, QRasterBuffer *rasterBu return start; } -static uint * QT_FASTCALL destFetchARGB32(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length) -{ - const uint *data = (const uint *)rasterBuffer->scanLine(y) + x; - for (int i = 0; i < length; ++i) - buffer[i] = PREMUL(data[i]); - return buffer; -} - static uint * QT_FASTCALL destFetchARGB32P(uint *, QRasterBuffer *rasterBuffer, int x, int y, int) { return (uint *)rasterBuffer->scanLine(y) + x; @@ -131,37 +361,32 @@ static uint * QT_FASTCALL destFetchRGB16(uint *buffer, QRasterBuffer *rasterBuff return buffer; } -template -Q_STATIC_TEMPLATE_FUNCTION uint * QT_FASTCALL destFetch(uint *buffer, QRasterBuffer *rasterBuffer, - int x, int y, int length) +static uint *QT_FASTCALL destFetch(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length) { - const DST *src = reinterpret_cast(rasterBuffer->scanLine(y)) + x; - quint32 *dest = reinterpret_cast(buffer); - while (length--) - *dest++ = *src++; - return buffer; + const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format]; + const uint *ptr = qFetchPixels[layout->bpp](buffer, rasterBuffer->scanLine(y), x, length); + return const_cast(layout->convertToARGB32PM(buffer, ptr, length, layout, 0)); } -# define SPANFUNC_POINTER_DESTFETCH(Arg) destFetch static DestFetchProc destFetchProc[QImage::NImageFormats] = { - 0, // Format_Invalid - destFetchMono, // Format_Mono, - destFetchMonoLsb, // Format_MonoLSB - 0, // Format_Indexed8 - destFetchARGB32P, // Format_RGB32 - destFetchARGB32, // Format_ARGB32, - destFetchARGB32P, // Format_ARGB32_Premultiplied - destFetchRGB16, // Format_RGB16 - SPANFUNC_POINTER_DESTFETCH(qargb8565), // Format_ARGB8565_Premultiplied - SPANFUNC_POINTER_DESTFETCH(qrgb666), // Format_RGB666 - SPANFUNC_POINTER_DESTFETCH(qargb6666), // Format_ARGB6666_Premultiplied - SPANFUNC_POINTER_DESTFETCH(qrgb555), // Format_RGB555 - SPANFUNC_POINTER_DESTFETCH(qargb8555), // Format_ARGB8555_Premultiplied - SPANFUNC_POINTER_DESTFETCH(qrgb888), // Format_RGB888 - SPANFUNC_POINTER_DESTFETCH(qrgb444), // Format_RGB444 - SPANFUNC_POINTER_DESTFETCH(qargb4444) // Format_ARGB4444_Premultiplied + 0, // Format_Invalid + destFetchMono, // Format_Mono, + destFetchMonoLsb, // Format_MonoLSB + 0, // Format_Indexed8 + destFetchARGB32P, // Format_RGB32 + destFetch, // Format_ARGB32, + destFetchARGB32P, // Format_ARGB32_Premultiplied + destFetchRGB16, // Format_RGB16 + destFetch, // Format_ARGB8565_Premultiplied + destFetch, // Format_RGB666 + destFetch, // Format_ARGB6666_Premultiplied + destFetch, // Format_RGB555 + destFetch, // Format_ARGB8555_Premultiplied + destFetch, // Format_RGB888 + destFetch, // Format_RGB444 + destFetch // Format_ARGB4444_Premultiplied }; /* @@ -253,63 +478,47 @@ static void QT_FASTCALL destStoreMonoLsb(QRasterBuffer *rasterBuffer, int x, int } } -static void QT_FASTCALL destStoreARGB32(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length) -{ - uint *data = (uint *)rasterBuffer->scanLine(y) + x; - for (int i = 0; i < length; ++i) { - int p = buffer[i]; - int alpha = qAlpha(p); - if (alpha == 255) - data[i] = p; - else if (alpha == 0) - data[i] = 0; - else { - int inv_alpha = 0xff0000/qAlpha(buffer[i]); - data[i] = (p & 0xff000000) - | ((qRed(p)*inv_alpha) & 0xff0000) - | (((qGreen(p)*inv_alpha) >> 8) & 0xff00) - | ((qBlue(p)*inv_alpha) >> 16); - } - } -} - static void QT_FASTCALL destStoreRGB16(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length) { quint16 *data = (quint16*)rasterBuffer->scanLine(y) + x; - qt_memconvert(data, buffer, length); + for (int i = 0; i < length; ++i) + data[i] = qConvertRgb32To16(buffer[i]); } -template -Q_STATIC_TEMPLATE_FUNCTION void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer, - int x, int y, - const uint *buffer, int length) +static void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length) { - DST *dest = reinterpret_cast(rasterBuffer->scanLine(y)) + x; - const quint32p *src = reinterpret_cast(buffer); - while (length--) - *dest++ = DST(*src++); + uint buf[buffer_size]; + const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format]; + StorePixelsFunc store = qStorePixels[layout->bpp]; + uchar *dest = rasterBuffer->scanLine(y); + while (length) { + int l = qMin(length, buffer_size); + const uint *ptr = layout->convertFromARGB32PM(buf, buffer, l, layout, 0); + store(dest, ptr, x, l); + length -= l; + buffer += l; + x += l; + } } -# define SPANFUNC_POINTER_DESTSTORE(DEST) destStore - static DestStoreProc destStoreProc[QImage::NImageFormats] = { - 0, // Format_Invalid - destStoreMono, // Format_Mono, - destStoreMonoLsb, // Format_MonoLSB - 0, // Format_Indexed8 - 0, // Format_RGB32 - destStoreARGB32, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied - destStoreRGB16, // Format_RGB16 - SPANFUNC_POINTER_DESTSTORE(qargb8565), // Format_ARGB8565_Premultiplied - SPANFUNC_POINTER_DESTSTORE(qrgb666), // Format_RGB666 - SPANFUNC_POINTER_DESTSTORE(qargb6666), // Format_ARGB6666_Premultiplied - SPANFUNC_POINTER_DESTSTORE(qrgb555), // Format_RGB555 - SPANFUNC_POINTER_DESTSTORE(qargb8555), // Format_ARGB8555_Premultiplied - SPANFUNC_POINTER_DESTSTORE(qrgb888), // Format_RGB888 - SPANFUNC_POINTER_DESTSTORE(qrgb444), // Format_RGB444 - SPANFUNC_POINTER_DESTSTORE(qargb4444) // Format_ARGB4444_Premultiplied + 0, // Format_Invalid + destStoreMono, // Format_Mono, + destStoreMonoLsb, // Format_MonoLSB + 0, // Format_Indexed8 + 0, // Format_RGB32 + destStore, // Format_ARGB32, + 0, // Format_ARGB32_Premultiplied + destStoreRGB16, // Format_RGB16 + destStore, // Format_ARGB8565_Premultiplied + destStore, // Format_RGB666 + destStore, // Format_ARGB6666_Premultiplied + destStore, // Format_RGB555 + destStore, // Format_ARGB8555_Premultiplied + destStore, // Format_RGB888 + destStore, // Format_RGB444 + destStore // Format_ARGB4444_Premultiplied }; /* @@ -327,175 +536,6 @@ static DestStoreProc destStoreProc[QImage::NImageFormats] = The generic implementation does pixel by pixel fetches */ -template -Q_STATIC_TEMPLATE_FUNCTION uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, int x, const QVector *rgb); - -template<> -Q_STATIC_TEMPLATE_SPECIALIZATION -uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, - int x, const QVector *rgb) -{ - bool pixel = scanLine[x>>3] & (0x80 >> (x & 7)); - if (rgb) return PREMUL(rgb->at(pixel ? 1 : 0)); - return pixel ? 0xff000000 : 0xffffffff; -} - -template<> -Q_STATIC_TEMPLATE_SPECIALIZATION -uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, - int x, const QVector *rgb) -{ - bool pixel = scanLine[x>>3] & (0x1 << (x & 7)); - if (rgb) return PREMUL(rgb->at(pixel ? 1 : 0)); - return pixel ? 0xff000000 : 0xffffffff; -} - -template<> -Q_STATIC_TEMPLATE_SPECIALIZATION -uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, - int x, const QVector *rgb) -{ - return PREMUL(rgb->at(scanLine[x])); -} - -template<> -Q_STATIC_TEMPLATE_SPECIALIZATION -uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, - int x, const QVector *) -{ - return PREMUL(((const uint *)scanLine)[x]); -} - -template<> -Q_STATIC_TEMPLATE_SPECIALIZATION -uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, - int x, const QVector *) -{ - return ((const uint *)scanLine)[x]; -} - -template<> -Q_STATIC_TEMPLATE_SPECIALIZATION -uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, - int x, const QVector *) -{ - return qConvertRgb16To32(((const ushort *)scanLine)[x]); -} - -template<> -Q_STATIC_TEMPLATE_SPECIALIZATION -uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, - int x, - const QVector *) -{ - const qargb8565 color = reinterpret_cast(scanLine)[x]; - return qt_colorConvert(color, 0); -} - -template<> -Q_STATIC_TEMPLATE_SPECIALIZATION -uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, - int x, - const QVector *) -{ - const qrgb666 color = reinterpret_cast(scanLine)[x]; - return qt_colorConvert(color, 0); -} - -template<> -Q_STATIC_TEMPLATE_SPECIALIZATION -uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, - int x, - const QVector *) -{ - const qargb6666 color = reinterpret_cast(scanLine)[x]; - return qt_colorConvert(color, 0); -} - -template<> -Q_STATIC_TEMPLATE_SPECIALIZATION -uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, - int x, - const QVector *) -{ - const qrgb555 color = reinterpret_cast(scanLine)[x]; - return qt_colorConvert(color, 0); -} - -template<> -Q_STATIC_TEMPLATE_SPECIALIZATION -uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, - int x, - const QVector *) -{ - const qargb8555 color = reinterpret_cast(scanLine)[x]; - return qt_colorConvert(color, 0); -} - -template<> -Q_STATIC_TEMPLATE_SPECIALIZATION -uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, - int x, - const QVector *) -{ - const qrgb888 color = reinterpret_cast(scanLine)[x]; - return qt_colorConvert(color, 0); -} - -template<> -Q_STATIC_TEMPLATE_SPECIALIZATION -uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, - int x, - const QVector *) -{ - const qrgb444 color = reinterpret_cast(scanLine)[x]; - return qt_colorConvert(color, 0); -} - -template<> -Q_STATIC_TEMPLATE_SPECIALIZATION -uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, - int x, - const QVector *) -{ - const qargb4444 color = reinterpret_cast(scanLine)[x]; - return qt_colorConvert(color, 0); -} - -template<> -Q_STATIC_TEMPLATE_SPECIALIZATION -uint QT_FASTCALL qt_fetchPixel(const uchar *, - int , - const QVector *) -{ - return 0; -} - -typedef uint (QT_FASTCALL *FetchPixelProc)(const uchar *scanLine, int x, const QVector *); - -#define SPANFUNC_POINTER_FETCHPIXEL(Arg) qt_fetchPixel - - -static const FetchPixelProc fetchPixelProc[QImage::NImageFormats] = -{ - 0, - SPANFUNC_POINTER_FETCHPIXEL(Format_Mono), - SPANFUNC_POINTER_FETCHPIXEL(Format_MonoLSB), - SPANFUNC_POINTER_FETCHPIXEL(Format_Indexed8), - SPANFUNC_POINTER_FETCHPIXEL(Format_ARGB32_Premultiplied), - SPANFUNC_POINTER_FETCHPIXEL(Format_ARGB32), - SPANFUNC_POINTER_FETCHPIXEL(Format_ARGB32_Premultiplied), - SPANFUNC_POINTER_FETCHPIXEL(Format_RGB16), - SPANFUNC_POINTER_FETCHPIXEL(Format_ARGB8565_Premultiplied), - SPANFUNC_POINTER_FETCHPIXEL(Format_RGB666), - SPANFUNC_POINTER_FETCHPIXEL(Format_ARGB6666_Premultiplied), - SPANFUNC_POINTER_FETCHPIXEL(Format_RGB555), - SPANFUNC_POINTER_FETCHPIXEL(Format_ARGB8555_Premultiplied), - SPANFUNC_POINTER_FETCHPIXEL(Format_RGB888), - SPANFUNC_POINTER_FETCHPIXEL(Format_RGB444), - SPANFUNC_POINTER_FETCHPIXEL(Format_ARGB4444_Premultiplied) -}; - enum TextureBlendType { BlendUntransformed, BlendTiled, @@ -506,33 +546,38 @@ enum TextureBlendType { NBlendTypes }; -template -Q_STATIC_TEMPLATE_FUNCTION const uint * QT_FASTCALL qt_fetchUntransformed(uint *buffer, const Operator *, const QSpanData *data, - int y, int x, int length) +static const uint *QT_FASTCALL fetchUntransformed(uint *buffer, const Operator *, + const QSpanData *data, int y, int x, int length) { - const uchar *scanLine = data->texture.scanLine(y); - for (int i = 0; i < length; ++i) - buffer[i] = qt_fetchPixel(scanLine, x + i, data->texture.colorTable); - return buffer; + const QPixelLayout *layout = &qPixelLayouts[data->texture.format]; + const uint *ptr = qFetchPixels[layout->bpp](buffer, data->texture.scanLine(y), x, length); + const QRgb *clut = data->texture.colorTable ? data->texture.colorTable->constData() : 0; + return layout->convertToARGB32PM(buffer, ptr, length, layout, clut); } -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION const uint * QT_FASTCALL -qt_fetchUntransformed(uint *, const Operator *, - const QSpanData *data, - int y, int x, int) +static const uint *QT_FASTCALL fetchUntransformedARGB32PM(uint *, const Operator *, + const QSpanData *data, int y, int x, int) { const uchar *scanLine = data->texture.scanLine(y); return ((const uint *)scanLine) + x; } -template /* either BlendTransformed or BlendTransformedTiled */ -Q_STATIC_TEMPLATE_FUNCTION -const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const QSpanData *data, - int y, int x, int length) +static const uint *QT_FASTCALL fetchUntransformedRGB16(uint *buffer, const Operator *, + const QSpanData *data, int y, int x, + int length) { - FetchPixelProc fetch = fetchPixelProc[data->texture.format]; + const quint16 *scanLine = (const quint16 *)data->texture.scanLine(y) + x; + for (int i = 0; i < length; ++i) + buffer[i] = qConvertRgb16To32(scanLine[i]); + return buffer; +} +// blendType is either BlendTransformed or BlendTransformedTiled +template +Q_STATIC_TEMPLATE_FUNCTION +const uint *QT_FASTCALL fetchTransformedARGB32PM(uint *buffer, const Operator *, const QSpanData *data, + int y, int x, int length) +{ int image_width = data->texture.width; int image_height = data->texture.height; @@ -560,18 +605,12 @@ const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const py %= image_height; if (px < 0) px += image_width; if (py < 0) py += image_height; - - const uchar *scanLine = data->texture.scanLine(py); - *b = fetch(scanLine, px, data->texture.colorTable); } else { - if ((px < 0) || (px >= image_width) - || (py < 0) || (py >= image_height)) { - *b = uint(0); - } else { - const uchar *scanLine = data->texture.scanLine(py); - *b = fetch(scanLine, px, data->texture.colorTable); - } + px = qBound(0, px, image_width - 1); + py = qBound(0, py, image_height - 1); } + *b = reinterpret_cast(data->texture.scanLine(py))[px]; + fx += fdx; fy += fdy; ++b; @@ -597,18 +636,12 @@ const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const py %= image_height; if (px < 0) px += image_width; if (py < 0) py += image_height; - - const uchar *scanLine = data->texture.scanLine(py); - *b = fetch(scanLine, px, data->texture.colorTable); } else { - if ((px < 0) || (px >= image_width) - || (py < 0) || (py >= image_height)) { - *b = uint(0); - } else { - const uchar *scanLine = data->texture.scanLine(py); - *b = fetch(scanLine, px, data->texture.colorTable); - } + px = qBound(0, px, image_width - 1); + py = qBound(0, py, image_height - 1); } + *b = reinterpret_cast(data->texture.scanLine(py))[px]; + fx += fdx; fy += fdy; fw += fdw; @@ -619,10 +652,95 @@ const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const ++b; } } - return buffer; } +template /* either BlendTransformed or BlendTransformedTiled */ +Q_STATIC_TEMPLATE_FUNCTION +const uint *QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const QSpanData *data, + int y, int x, int length) +{ + int image_width = data->texture.width; + int image_height = data->texture.height; + + const qreal cx = x + qreal(0.5); + const qreal cy = y + qreal(0.5); + + const QPixelLayout *layout = &qPixelLayouts[data->texture.format]; + FetchPixelFunc fetch = qFetchPixel[layout->bpp]; + + const uint *end = buffer + length; + uint *b = buffer; + if (data->fast_matrix) { + // The increment pr x in the scanline + int fdx = (int)(data->m11 * fixed_scale); + int fdy = (int)(data->m12 * fixed_scale); + + int fx = int((data->m21 * cy + + data->m11 * cx + data->dx) * fixed_scale); + int fy = int((data->m22 * cy + + data->m12 * cx + data->dy) * fixed_scale); + + while (b < end) { + int px = fx >> 16; + int py = fy >> 16; + + if (blendType == BlendTransformedTiled) { + px %= image_width; + py %= image_height; + if (px < 0) px += image_width; + if (py < 0) py += image_height; + } else { + px = qBound(0, px, image_width - 1); + py = qBound(0, py, image_height - 1); + } + *b = fetch(data->texture.scanLine(py), px); + + fx += fdx; + fy += fdy; + ++b; + } + } else { + const qreal fdx = data->m11; + const qreal fdy = data->m12; + const qreal fdw = data->m13; + + qreal fx = data->m21 * cy + data->m11 * cx + data->dx; + qreal fy = data->m22 * cy + data->m12 * cx + data->dy; + qreal fw = data->m23 * cy + data->m13 * cx + data->m33; + + while (b < end) { + const qreal iw = fw == 0 ? 1 : 1 / fw; + const qreal tx = fx * iw; + const qreal ty = fy * iw; + int px = int(tx) - (tx < 0); + int py = int(ty) - (ty < 0); + + if (blendType == BlendTransformedTiled) { + px %= image_width; + py %= image_height; + if (px < 0) px += image_width; + if (py < 0) py += image_height; + } else { + px = qBound(0, px, image_width - 1); + py = qBound(0, py, image_height - 1); + } + *b = fetch(data->texture.scanLine(py), px); + + fx += fdx; + fy += fdy; + fw += fdw; + //force increment to avoid /0 + if (!fw) { + fw += fdw; + } + ++b; + } + } + const QRgb *clut = data->texture.colorTable ? data->texture.colorTable->constData() : 0; + return layout->convertToARGB32PM(buffer, buffer, length, layout, clut); +} + /** \internal interpolate 4 argb pixels with the distx and disty factor. distx and disty bust be between 0 and 16 @@ -714,42 +832,42 @@ static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, i #endif template -Q_STATIC_TEMPLATE_FUNCTION inline void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2) -{ - if (blendType == BlendTransformedBilinearTiled) { - v1 %= max; - if (v1 < 0) v1 += max; - v2 = v1 + 1; - v2 %= max; - } else { - if (v1 < l1) { - v2 = v1 = l1; - } else if (v1 >= l2) { - v2 = v1 = l2; - } else { - v2 = v1 + 1; - } - } +void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2); +template<> +Q_STATIC_TEMPLATE_SPECIALIZATION +inline void fetchTransformedBilinear_pixelBounds(int max, int, int, int &v1, int &v2) +{ + v1 %= max; + if (v1 < 0) + v1 += max; + v2 = v1 + 1; + if (v2 == max) + v2 = 0; Q_ASSERT(v1 >= 0 && v1 < max); Q_ASSERT(v2 >= 0 && v2 < max); } -template /* blendType = BlendTransformedBilinear or BlendTransformedBilinearTiled */ -Q_STATIC_TEMPLATE_FUNCTION -const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *, const QSpanData *data, - int y, int x, int length) +template<> +Q_STATIC_TEMPLATE_SPECIALIZATION +inline void fetchTransformedBilinear_pixelBounds(int, int l1, int l2, int &v1, int &v2) { -#ifdef Q_CC_RVCT // needed to avoid compiler crash in RVCT 2.2 - FetchPixelProc fetch; - if (format != QImage::Format_Invalid) - fetch = qt_fetchPixel; + if (v1 < l1) + v2 = v1 = l1; + else if (v1 >= l2) + v2 = v1 = l2; else - fetch = fetchPixelProc[data->texture.format]; -#else - FetchPixelProc fetch = (format != QImage::Format_Invalid) ? FetchPixelProc(qt_fetchPixel) : fetchPixelProc[data->texture.format]; -#endif + v2 = v1 + 1; + Q_ASSERT(v1 >= l1 && v1 <= l2); + Q_ASSERT(v2 >= l1 && v2 <= l2); +} +template /* blendType = BlendTransformedBilinear or BlendTransformedBilinearTiled */ +Q_STATIC_TEMPLATE_FUNCTION +const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, const Operator *, + const QSpanData *data, int y, int x, + int length) +{ int image_width = data->texture.width; int image_height = data->texture.height; @@ -780,8 +898,8 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * int y1 = (fy >> 16); int y2; fetchTransformedBilinear_pixelBounds(image_height, image_y1, image_y2, y1, y2); - const uchar *s1 = data->texture.scanLine(y1); - const uchar *s2 = data->texture.scanLine(y2); + const uint *s1 = (const uint *)data->texture.scanLine(y1); + const uint *s2 = (const uint *)data->texture.scanLine(y2); if (fdx <= fixed_scale && fdx > 0) { // scale up on X int disty = (fy & 0x0000ffff) >> 8; @@ -806,8 +924,8 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * lim = qMin(count, image_x2-x+1); if (x < image_x1) { Q_ASSERT(x <= image_x2); - uint t = fetch(s1, image_x1, data->texture.colorTable); - uint b = fetch(s2, image_x1, data->texture.colorTable); + uint t = s1[image_x1]; + uint b = s2[image_x1]; quint32 rb = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff; quint32 ag = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff; do { @@ -819,8 +937,7 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * } } - if (blendType != BlendTransformedBilinearTiled && - (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32)) { + if (blendType != BlendTransformedBilinearTiled) { #if defined(QT_ALWAYS_HAVE_SSE2) const __m128i disty_ = _mm_set1_epi16(disty); const __m128i idisty_ = _mm_set1_epi16(idisty); @@ -890,8 +1007,8 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * x = qMin(x, image_x2); } - uint t = fetch(s1, x, data->texture.colorTable); - uint b = fetch(s2, x, data->texture.colorTable); + uint t = s1[x]; + uint b = s2[x]; intermediate_buffer[0][f] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff; intermediate_buffer[1][f] = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff; @@ -918,18 +1035,18 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * int y1 = (fy >> 16); int y2; fetchTransformedBilinear_pixelBounds(image_height, image_y1, image_y2, y1, y2); - const uchar *s1 = data->texture.scanLine(y1); - const uchar *s2 = data->texture.scanLine(y2); + const uint *s1 = (const uint *)data->texture.scanLine(y1); + const uint *s2 = (const uint *)data->texture.scanLine(y2); int disty = (fy & 0x0000ffff) >> 8; int idisty = 256 - disty; while (b < end) { int x1 = (fx >> 16); int x2; fetchTransformedBilinear_pixelBounds(image_width, image_x1, image_x2, x1, x2); - uint tl = fetch(s1, x1, data->texture.colorTable); - uint tr = fetch(s1, x2, data->texture.colorTable); - uint bl = fetch(s2, x1, data->texture.colorTable); - uint br = fetch(s2, x2, data->texture.colorTable); + uint tl = s1[x1]; + uint tr = s1[x2]; + uint bl = s2[x1]; + uint br = s2[x2]; int distx = (fx & 0x0000ffff) >> 8; int idistx = 256 - distx; @@ -945,13 +1062,11 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * int y1 = (fy >> 16); int y2; fetchTransformedBilinear_pixelBounds(image_height, image_y1, image_y2, y1, y2); - const uchar *s1 = data->texture.scanLine(y1); - const uchar *s2 = data->texture.scanLine(y2); + const uint *s1 = (const uint *)data->texture.scanLine(y1); + const uint *s2 = (const uint *)data->texture.scanLine(y2); int disty = (fy & 0x0000ffff) >> 12; - if (blendType != BlendTransformedBilinearTiled && - (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32)) { - + if (blendType != BlendTransformedBilinearTiled) { #define BILINEAR_DOWNSCALE_BOUNDS_PROLOG \ while (b < end) { \ int x1 = (fx >> 16); \ @@ -959,10 +1074,10 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * fetchTransformedBilinear_pixelBounds(image_width, image_x1, image_x2, x1, x2); \ if (x1 != x2) \ break; \ - uint tl = fetch(s1, x1, data->texture.colorTable); \ - uint tr = fetch(s1, x2, data->texture.colorTable); \ - uint bl = fetch(s2, x1, data->texture.colorTable); \ - uint br = fetch(s2, x2, data->texture.colorTable); \ + uint tl = s1[x1]; \ + uint tr = s1[x2]; \ + uint bl = s2[x1]; \ + uint br = s2[x2]; \ int distx = (fx & 0x0000ffff) >> 12; \ *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty); \ fx += fdx; \ @@ -1070,10 +1185,10 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * int x1 = (fx >> 16); int x2; fetchTransformedBilinear_pixelBounds(image_width, image_x1, image_x2, x1, x2); - uint tl = fetch(s1, x1, data->texture.colorTable); - uint tr = fetch(s1, x2, data->texture.colorTable); - uint bl = fetch(s2, x1, data->texture.colorTable); - uint br = fetch(s2, x2, data->texture.colorTable); + uint tl = s1[x1]; + uint tr = s1[x2]; + uint bl = s2[x1]; + uint br = s2[x2]; int distx = (fx & 0x0000ffff) >> 12; *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty); fx += fdx; @@ -1092,13 +1207,13 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * fetchTransformedBilinear_pixelBounds(image_width, image_x1, image_x2, x1, x2); fetchTransformedBilinear_pixelBounds(image_height, image_y1, image_y2, y1, y2); - const uchar *s1 = data->texture.scanLine(y1); - const uchar *s2 = data->texture.scanLine(y2); + const uint *s1 = (const uint *)data->texture.scanLine(y1); + const uint *s2 = (const uint *)data->texture.scanLine(y2); - uint tl = fetch(s1, x1, data->texture.colorTable); - uint tr = fetch(s1, x2, data->texture.colorTable); - uint bl = fetch(s2, x1, data->texture.colorTable); - uint br = fetch(s2, x2, data->texture.colorTable); + uint tl = s1[x1]; + uint tr = s1[x2]; + uint bl = s2[x1]; + uint br = s2[x2]; int distx = (fx & 0x0000ffff) >> 8; int disty = (fy & 0x0000ffff) >> 8; @@ -1124,13 +1239,13 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * fetchTransformedBilinear_pixelBounds(image_width, image_x1, image_x2, x1, x2); fetchTransformedBilinear_pixelBounds(image_height, image_y1, image_y2, y1, y2); - const uchar *s1 = data->texture.scanLine(y1); - const uchar *s2 = data->texture.scanLine(y2); + const uint *s1 = (const uint *)data->texture.scanLine(y1); + const uint *s2 = (const uint *)data->texture.scanLine(y2); - uint tl = fetch(s1, x1, data->texture.colorTable); - uint tr = fetch(s1, x2, data->texture.colorTable); - uint bl = fetch(s2, x1, data->texture.colorTable); - uint br = fetch(s2, x2, data->texture.colorTable); + uint tl = s1[x1]; + uint tr = s1[x2]; + uint bl = s2[x1]; + uint br = s2[x2]; int distx = (fx & 0x0000ffff) >> 12; int disty = (fy & 0x0000ffff) >> 12; @@ -1170,13 +1285,13 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * fetchTransformedBilinear_pixelBounds(image_width, image_x1, image_x2, x1, x2); fetchTransformedBilinear_pixelBounds(image_height, image_y1, image_y2, y1, y2); - const uchar *s1 = data->texture.scanLine(y1); - const uchar *s2 = data->texture.scanLine(y2); + const uint *s1 = (const uint *)data->texture.scanLine(y1); + const uint *s2 = (const uint *)data->texture.scanLine(y2); - uint tl = fetch(s1, x1, data->texture.colorTable); - uint tr = fetch(s1, x2, data->texture.colorTable); - uint bl = fetch(s2, x1, data->texture.colorTable); - uint br = fetch(s2, x2, data->texture.colorTable); + uint tl = s1[x1]; + uint tr = s1[x2]; + uint bl = s2[x1]; + uint br = s2[x2]; uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); @@ -1196,119 +1311,452 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * return buffer; } -#define SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Arg) qt_fetchUntransformed +// blendType = BlendTransformedBilinear or BlendTransformedBilinearTiled +template +Q_STATIC_TEMPLATE_FUNCTION +const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *, + const QSpanData *data, int y, int x, int length) +{ + const QPixelLayout *layout = &qPixelLayouts[data->texture.format]; + const QRgb *clut = data->texture.colorTable ? data->texture.colorTable->constData() : 0; + + int image_width = data->texture.width; + int image_height = data->texture.height; + + int image_x1 = data->texture.x1; + int image_y1 = data->texture.y1; + int image_x2 = data->texture.x2 - 1; + int image_y2 = data->texture.y2 - 1; + + const qreal cx = x + qreal(0.5); + const qreal cy = y + qreal(0.5); + + if (data->fast_matrix) { + // The increment pr x in the scanline + int fdx = (int)(data->m11 * fixed_scale); + int fdy = (int)(data->m12 * fixed_scale); + + int fx = int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale); + int fy = int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale); + + fx -= half_point; + fy -= half_point; + + if (fdy == 0) { //simple scale, no rotation + int y1 = (fy >> 16); + int y2; + fetchTransformedBilinear_pixelBounds(image_height, image_y1, image_y2, y1, y2); + const uchar *s1 = data->texture.scanLine(y1); + const uchar *s2 = data->texture.scanLine(y2); + + if (fdx <= fixed_scale && fdx > 0) { // scale up on X + int disty = (fy & 0x0000ffff) >> 8; + int idisty = 256 - disty; + int x = fx >> 16; + + // The idea is first to do the interpolation between the row s1 and the row s2 + // into an intermediate buffer, then we interpolate between two pixel of this buffer. + FetchPixelsFunc fetch = qFetchPixels[layout->bpp]; + uint buf1[buffer_size + 2]; + uint buf2[buffer_size + 2]; + const uint *ptr1; + const uint *ptr2; + + int count = qCeil(length * data->m11) + 2; //+1 for the last pixel to interpolate with, and +1 for rounding errors. + Q_ASSERT(count <= buffer_size + 2); //length is supposed to be <= buffer_size and data->m11 < 1 in this case + + if (blendType == BlendTransformedBilinearTiled) { + x %= image_width; + if (x < 0) + x += image_width; + int len1 = qMin(count, image_width - x); + int len2 = qMin(x, count - len1); + + ptr1 = fetch(buf1, s1, x, len1); + ptr1 = layout->convertToARGB32PM(buf1, ptr1, len1, layout, clut); + ptr2 = fetch(buf2, s2, x, len1); + ptr2 = layout->convertToARGB32PM(buf2, ptr2, len1, layout, clut); + for (int i = 0; i < len1; ++i) { + uint t = ptr1[i]; + uint b = ptr2[i]; + buf1[i] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff; + buf2[i] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff; + } + + if (len2) { + ptr1 = fetch(buf1 + len1, s1, 0, len2); + ptr1 = layout->convertToARGB32PM(buf1 + len1, ptr1, len2, layout, clut); + ptr2 = fetch(buf2 + len1, s2, 0, len2); + ptr2 = layout->convertToARGB32PM(buf2 + len1, ptr2, len2, layout, clut); + for (int i = 0; i < len2; ++i) { + uint t = ptr1[i]; + uint b = ptr2[i]; + buf1[i + len1] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff; + buf2[i + len1] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff; + } + } + for (int i = image_width; i < count; ++i) { + buf1[i] = buf1[i - image_width]; + buf2[i] = buf2[i - image_width]; + } + } else { + int start = qMax(x, image_x1); + int end = qMin(x + count, image_x2 + 1); + int len = qMax(1, end - start); + int leading = start - x; + + ptr1 = fetch(buf1 + leading, s1, start, len); + ptr1 = layout->convertToARGB32PM(buf1 + leading, ptr1, len, layout, clut); + ptr2 = fetch(buf2 + leading, s2, start, len); + ptr2 = layout->convertToARGB32PM(buf2 + leading, ptr2, len, layout, clut); + + for (int i = 0; i < len; ++i) { + uint t = ptr1[i]; + uint b = ptr2[i]; + buf1[i + leading] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff; + buf2[i + leading] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff; + } + + for (int i = 0; i < leading; ++i) { + buf1[i] = buf1[leading]; + buf2[i] = buf2[leading]; + } + for (int i = leading + len; i < count; ++i) { + buf1[i] = buf1[i - 1]; + buf2[i] = buf2[i - 1]; + } + } + + // Now interpolate the values from the intermediate_buffer to get the final result. + fx &= fixed_scale - 1; + Q_ASSERT((fx >> 16) == 0); + for (int i = 0; i < length; ++i) { + register int x1 = (fx >> 16); + register int x2 = x1 + 1; + Q_ASSERT(x1 >= 0); + Q_ASSERT(x2 < count); + + register int distx = (fx & 0x0000ffff) >> 8; + register int idistx = 256 - distx; + int rb = ((buf1[x1] * idistx + buf1[x2] * distx) >> 8) & 0xff00ff; + int ag = (buf2[x1] * idistx + buf2[x2] * distx) & 0xff00ff00; + buffer[i] = rb | ag; + fx += fdx; + } + } else { + FetchPixelFunc fetch = qFetchPixel[layout->bpp]; + uint buf1[buffer_size]; + uint buf2[buffer_size]; + uint *b = buffer; + while (length) { + int len = qMin(length, buffer_size / 2); + int fracX = fx; + for (int i = 0; i < len; ++i) { + int x1 = (fx >> 16); + int x2; + fetchTransformedBilinear_pixelBounds(image_width, image_x1, image_x2, x1, x2); + + buf1[i * 2 + 0] = fetch(s1, x1); + buf1[i * 2 + 1] = fetch(s1, x2); + buf2[i * 2 + 0] = fetch(s2, x1); + buf2[i * 2 + 1] = fetch(s2, x2); + + fx += fdx; + } + layout->convertToARGB32PM(buf1, buf1, len * 2, layout, clut); + layout->convertToARGB32PM(buf2, buf2, len * 2, layout, clut); + + if ((fdx < 0 && fdx > -(fixed_scale / 8)) || fabs(data->m22) < (1./8.)) { // scale up more than 8x + int disty = (fy & 0x0000ffff) >> 8; + int idisty = 256 - disty; + for (int i = 0; i < len; ++i) { + uint tl = buf1[i * 2 + 0]; + uint tr = buf1[i * 2 + 1]; + uint bl = buf2[i * 2 + 0]; + uint br = buf2[i * 2 + 1]; + int distx = (fracX & 0x0000ffff) >> 8; + int idistx = 256 - distx; + uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); + uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); + b[i] = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); + fracX += fdx; + } + } else { //scale down + int disty = (fy & 0x0000ffff) >> 12; + for (int i = 0; i < len; ++i) { + uint tl = buf1[i * 2 + 0]; + uint tr = buf1[i * 2 + 1]; + uint bl = buf2[i * 2 + 0]; + uint br = buf2[i * 2 + 1]; + int distx = (fracX & 0x0000ffff) >> 12; + b[i] = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty); + fracX += fdx; + } + } + length -= len; + b += len; + } + } + } else { //rotation + FetchPixelFunc fetch = qFetchPixel[layout->bpp]; + uint buf1[buffer_size]; + uint buf2[buffer_size]; + uint *b = buffer; + + while (length) { + int len = qMin(length, buffer_size / 2); + int fracX = fx; + int fracY = fy; + for (int i = 0; i < len; ++i) { + int x1 = (fx >> 16); + int x2; + int y1 = (fy >> 16); + int y2; + fetchTransformedBilinear_pixelBounds(image_width, image_x1, image_x2, x1, x2); + fetchTransformedBilinear_pixelBounds(image_height, image_y1, image_y2, y1, y2); + + const uchar *s1 = data->texture.scanLine(y1); + const uchar *s2 = data->texture.scanLine(y2); + + buf1[i * 2 + 0] = fetch(s1, x1); + buf1[i * 2 + 1] = fetch(s1, x2); + buf2[i * 2 + 0] = fetch(s2, x1); + buf2[i * 2 + 1] = fetch(s2, x2); + + fx += fdx; + fy += fdy; + } + layout->convertToARGB32PM(buf1, buf1, len * 2, layout, clut); + layout->convertToARGB32PM(buf2, buf2, len * 2, layout, clut); + + if (fabs(data->m11) > 8 || fabs(data->m22) > 8) { + //if we are zooming more than 8 times, we use 8bit precision for the position. + for (int i = 0; i < len; ++i) { + uint tl = buf1[i * 2 + 0]; + uint tr = buf1[i * 2 + 1]; + uint bl = buf2[i * 2 + 0]; + uint br = buf2[i * 2 + 1]; + + int distx = (fracX & 0x0000ffff) >> 8; + int disty = (fracY & 0x0000ffff) >> 8; + int idistx = 256 - distx; + int idisty = 256 - disty; + + uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); + uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); + b[i] = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); + fracX += fdx; + fracY += fdy; + } + } else { + //we are zooming less than 8x, use 4bit precision + for (int i = 0; i < len; ++i) { + uint tl = buf1[i * 2 + 0]; + uint tr = buf1[i * 2 + 1]; + uint bl = buf2[i * 2 + 0]; + uint br = buf2[i * 2 + 1]; + + int distx = (fracX & 0x0000ffff) >> 12; + int disty = (fracY & 0x0000ffff) >> 12; + + b[i] = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty); + fracX += fdx; + fracY += fdy; + } + } + + length -= len; + b += len; + } + } + } else { + const qreal fdx = data->m11; + const qreal fdy = data->m12; + const qreal fdw = data->m13; + + qreal fx = data->m21 * cy + data->m11 * cx + data->dx; + qreal fy = data->m22 * cy + data->m12 * cx + data->dy; + qreal fw = data->m23 * cy + data->m13 * cx + data->m33; + + FetchPixelFunc fetch = qFetchPixel[layout->bpp]; + uint buf1[buffer_size]; + uint buf2[buffer_size]; + uint *b = buffer; + + int distxs[buffer_size / 2]; + int distys[buffer_size / 2]; + + while (length) { + int len = qMin(length, buffer_size / 2); + for (int i = 0; i < len; ++i) { + const qreal iw = fw == 0 ? 1 : 1 / fw; + const qreal px = fx * iw - qreal(0.5); + const qreal py = fy * iw - qreal(0.5); + + int x1 = int(px) - (px < 0); + int x2; + int y1 = int(py) - (py < 0); + int y2; + + distxs[i] = int((px - x1) * 256); + distys[i] = int((py - y1) * 256); + + fetchTransformedBilinear_pixelBounds(image_width, image_x1, image_x2, x1, x2); + fetchTransformedBilinear_pixelBounds(image_height, image_y1, image_y2, y1, y2); + + const uchar *s1 = data->texture.scanLine(y1); + const uchar *s2 = data->texture.scanLine(y2); + + buf1[i * 2 + 0] = fetch(s1, x1); + buf1[i * 2 + 1] = fetch(s1, x2); + buf2[i * 2 + 0] = fetch(s2, x1); + buf2[i * 2 + 1] = fetch(s2, x2); + + fx += fdx; + fy += fdy; + fw += fdw; + //force increment to avoid /0 + if (!fw) + fw += fdw; + } + + layout->convertToARGB32PM(buf1, buf1, len * 2, layout, clut); + layout->convertToARGB32PM(buf2, buf2, len * 2, layout, clut); + + for (int i = 0; i < len; ++i) { + int distx = distxs[i]; + int disty = distys[i]; + int idistx = 256 - distx; + int idisty = 256 - disty; + + uint tl = buf1[i * 2 + 0]; + uint tr = buf1[i * 2 + 1]; + uint bl = buf2[i * 2 + 0]; + uint br = buf2[i * 2 + 1]; + + uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); + uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); + b[i] = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); + } + length -= len; + b += len; + } + } + + return buffer; +} static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { // Untransformed { 0, // Invalid - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_Mono), // Mono - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_MonoLSB), // MonoLsb - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_Indexed8), // Indexed8 - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB32_Premultiplied), // RGB32 - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB32), // ARGB32 - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB32_Premultiplied), // ARGB32_Premultiplied - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB16), // RGB16 - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB8565_Premultiplied),// ARGB8565_Premultiplied - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB666), // RGB666 - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB6666_Premultiplied),// ARGB6666_Premultiplied - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB555), // RGB555 - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB8555_Premultiplied),// ARGB8555_Premultiplied - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB888), // RGB888 - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB444), // RGB444 - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB4444_Premultiplied) // ARGB4444_Premultiplied + fetchUntransformed, // Mono + fetchUntransformed, // MonoLsb + fetchUntransformed, // Indexed8 + fetchUntransformedARGB32PM, // RGB32 + fetchUntransformed, // ARGB32 + fetchUntransformedARGB32PM, // ARGB32_Premultiplied + fetchUntransformedRGB16, // RGB16 + fetchUntransformed, // ARGB8565_Premultiplied + fetchUntransformed, // RGB666 + fetchUntransformed, // ARGB6666_Premultiplied + fetchUntransformed, // RGB555 + fetchUntransformed, // ARGB8555_Premultiplied + fetchUntransformed, // RGB888 + fetchUntransformed, // RGB444 + fetchUntransformed // ARGB4444_Premultiplied }, // Tiled { 0, // Invalid - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_Mono), // Mono - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_MonoLSB), // MonoLsb - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_Indexed8), // Indexed8 - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB32_Premultiplied), // RGB32 - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB32), // ARGB32 - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB32_Premultiplied), // ARGB32_Premultiplied - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB16), // RGB16 - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB8565_Premultiplied),// ARGB8565_Premultiplied - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB666), // RGB666 - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB6666_Premultiplied),// ARGB6666_Premultiplied - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB555), // RGB555 - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB8555_Premultiplied),// ARGB8555_Premultiplied - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB888), // RGB888 - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB444), // RGB444 - SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB4444_Premultiplied) // ARGB4444_Premultiplied + fetchUntransformed, // Mono + fetchUntransformed, // MonoLsb + fetchUntransformed, // Indexed8 + fetchUntransformedARGB32PM, // RGB32 + fetchUntransformed, // ARGB32 + fetchUntransformedARGB32PM, // ARGB32_Premultiplied + fetchUntransformedRGB16, // RGB16 + fetchUntransformed, // ARGB8565_Premultiplied + fetchUntransformed, // RGB666 + fetchUntransformed, // ARGB6666_Premultiplied + fetchUntransformed, // RGB555 + fetchUntransformed, // ARGB8555_Premultiplied + fetchUntransformed, // RGB888 + fetchUntransformed, // RGB444 + fetchUntransformed // ARGB4444_Premultiplied }, // Transformed { 0, // Invalid - fetchTransformed, // Mono - fetchTransformed, // MonoLsb - fetchTransformed, // Indexed8 - fetchTransformed, // RGB32 - fetchTransformed, // ARGB32 - fetchTransformed, // ARGB32_Premultiplied - fetchTransformed, // RGB16 - fetchTransformed, // ARGB8565_Premultiplied - fetchTransformed, // RGB666 - fetchTransformed, // ARGB6666_Premultiplied - fetchTransformed, // RGB555 - fetchTransformed, // ARGB8555_Premultiplied - fetchTransformed, // RGB888 - fetchTransformed, // RGB444 - fetchTransformed, // ARGB4444_Premultiplied + fetchTransformed, // Mono + fetchTransformed, // MonoLsb + fetchTransformed, // Indexed8 + fetchTransformedARGB32PM, // RGB32 + fetchTransformed, // ARGB32 + fetchTransformedARGB32PM, // ARGB32_Premultiplied + fetchTransformed, // RGB16 + fetchTransformed, // ARGB8565_Premultiplied + fetchTransformed, // RGB666 + fetchTransformed, // ARGB6666_Premultiplied + fetchTransformed, // RGB555 + fetchTransformed, // ARGB8555_Premultiplied + fetchTransformed, // RGB888 + fetchTransformed, // RGB444 + fetchTransformed, // ARGB4444_Premultiplied }, { 0, // TransformedTiled - fetchTransformed, // Mono - fetchTransformed, // MonoLsb - fetchTransformed, // Indexed8 - fetchTransformed, // RGB32 - fetchTransformed, // ARGB32 - fetchTransformed, // ARGB32_Premultiplied - fetchTransformed, // RGB16 - fetchTransformed, // ARGB8565_Premultiplied - fetchTransformed, // RGB666 - fetchTransformed, // ARGB6666_Premultiplied - fetchTransformed, // RGB555 - fetchTransformed, // ARGB8555_Premultiplied - fetchTransformed, // RGB888 - fetchTransformed, // RGB444 - fetchTransformed, // ARGB4444_Premultiplied + fetchTransformed, // Mono + fetchTransformed, // MonoLsb + fetchTransformed, // Indexed8 + fetchTransformedARGB32PM, // RGB32 + fetchTransformed, // ARGB32 + fetchTransformedARGB32PM, // ARGB32_Premultiplied + fetchTransformed, // RGB16 + fetchTransformed, // ARGB8565_Premultiplied + fetchTransformed, // RGB666 + fetchTransformed, // ARGB6666_Premultiplied + fetchTransformed, // RGB555 + fetchTransformed, // ARGB8555_Premultiplied + fetchTransformed, // RGB888 + fetchTransformed, // RGB444 + fetchTransformed, // ARGB4444_Premultiplied }, { 0, // Bilinear - fetchTransformedBilinear, // Mono - fetchTransformedBilinear, // MonoLsb - fetchTransformedBilinear, // Indexed8 - fetchTransformedBilinear, // RGB32 - fetchTransformedBilinear, // ARGB32 - fetchTransformedBilinear, // ARGB32_Premultiplied - fetchTransformedBilinear, // RGB16 - fetchTransformedBilinear, // ARGB8565_Premultiplied - fetchTransformedBilinear, // RGB666 - fetchTransformedBilinear, // ARGB6666_Premultiplied - fetchTransformedBilinear, // RGB555 - fetchTransformedBilinear, // ARGB8555_Premultiplied - fetchTransformedBilinear, // RGB888 - fetchTransformedBilinear, // RGB444 - fetchTransformedBilinear // ARGB4444_Premultiplied + fetchTransformedBilinear, // Mono + fetchTransformedBilinear, // MonoLsb + fetchTransformedBilinear, // Indexed8 + fetchTransformedBilinearARGB32PM, // RGB32 + fetchTransformedBilinear, // ARGB32 + fetchTransformedBilinearARGB32PM, // ARGB32_Premultiplied + fetchTransformedBilinear, // RGB16 + fetchTransformedBilinear, // ARGB8565_Premultiplied + fetchTransformedBilinear, // RGB666 + fetchTransformedBilinear, // ARGB6666_Premultiplied + fetchTransformedBilinear, // RGB555 + fetchTransformedBilinear, // ARGB8555_Premultiplied + fetchTransformedBilinear, // RGB888 + fetchTransformedBilinear, // RGB444 + fetchTransformedBilinear // ARGB4444_Premultiplied }, { 0, // BilinearTiled - fetchTransformedBilinear, // Mono - fetchTransformedBilinear, // MonoLsb - fetchTransformedBilinear, // Indexed8 - fetchTransformedBilinear, // RGB32 - fetchTransformedBilinear, // ARGB32 - fetchTransformedBilinear, // ARGB32_Premultiplied - fetchTransformedBilinear, // RGB16 - fetchTransformedBilinear, // ARGB8565_Premultiplied - fetchTransformedBilinear, // RGB666 - fetchTransformedBilinear, // ARGB6666_Premultiplied - fetchTransformedBilinear, // RGB555 - fetchTransformedBilinear, // ARGB8555_Premultiplied - fetchTransformedBilinear, // RGB888 - fetchTransformedBilinear, // RGB444 - fetchTransformedBilinear // ARGB4444_Premultiplied + fetchTransformedBilinear, // Mono + fetchTransformedBilinear, // MonoLsb + fetchTransformedBilinear, // Indexed8 + fetchTransformedBilinearARGB32PM, // RGB32 + fetchTransformedBilinear, // ARGB32 + fetchTransformedBilinearARGB32PM, // ARGB32_Premultiplied + fetchTransformedBilinear, // RGB16 + fetchTransformedBilinear, // ARGB8565_Premultiplied + fetchTransformedBilinear, // RGB666 + fetchTransformedBilinear, // ARGB6666_Premultiplied + fetchTransformedBilinear, // RGB555 + fetchTransformedBilinear, // ARGB8555_Premultiplied + fetchTransformedBilinear, // RGB888 + fetchTransformedBilinear, // RGB444 + fetchTransformedBilinear // ARGB4444_Premultiplied }, }; @@ -3274,26 +3722,6 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in // -------------------- blend methods --------------------- -enum SpanMethod { - RegularSpans, - CallbackSpans -}; - -#if !defined(Q_CC_SUN) -static -#endif -void drawBufferSpan(QSpanData *data, const uint *buffer, int bufsize, - int x, int y, int length, uint const_alpha) -{ - Q_UNUSED(data); - Q_UNUSED(buffer); - Q_UNUSED(bufsize); - Q_UNUSED(x); - Q_UNUSED(y); - Q_UNUSED(length); - Q_UNUSED(const_alpha); -} - #if !defined(Q_CC_SUN) static #endif @@ -3349,55 +3777,6 @@ static void blend_color_argb(int count, const QSpan *spans, void *userData) } } -template -Q_STATIC_TEMPLATE_FUNCTION void blendColor(int count, const QSpan *spans, void *userData) -{ - QSpanData *data = reinterpret_cast(userData); - Operator op = getOperator(data, spans, count); - - if (op.mode == QPainter::CompositionMode_Source) { - const T c = qt_colorConvert(quint32p::fromRawData(data->solid.color), 0); - while (count--) { - T *target = ((T*)data->rasterBuffer->scanLine(spans->y)) - + spans->x; - if (spans->coverage == 255) { - qt_memfill(target, c, spans->len); - } else { - const quint8 alpha = T::alpha(spans->coverage); - const T color = c.byte_mul(alpha); - const int ialpha = T::ialpha(spans->coverage); - const T *end = target + spans->len; - while (target < end) { - *target = color + target->byte_mul(ialpha); - ++target; - } - } - ++spans; - } - return; - } - - if (op.mode == QPainter::CompositionMode_SourceOver) { - while (count--) { - const quint32 color = BYTE_MUL(data->solid.color, spans->coverage); - const T c = qt_colorConvert(quint32p::fromRawData(color), 0); - const quint8 ialpha = T::alpha(qAlpha(~color)); - T *target = ((T*)data->rasterBuffer->scanLine(spans->y)) + spans->x; - const T *end = target + spans->len; - while (target != end) { - *target = c + target->byte_mul(ialpha); - ++target; - } - ++spans; - } - return; - } - - blend_color_generic(count, spans, userData); -} - -#define SPANFUNC_POINTER_BLENDCOLOR(DST) blendColor - static void blend_color_rgb16(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); @@ -3542,7 +3921,6 @@ struct QBlendBase uint src_buffer[buffer_size]; }; -template class BlendSrcGeneric : public QBlendBase { public: @@ -3553,38 +3931,30 @@ public: const uint *fetch(int x, int y, int len) { - if (spanMethod == RegularSpans) - dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, y, len) : buffer; - + dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, y, len) : buffer; return op.src_fetch(src_buffer, &op, data, y, x, len); } - void process(int x, int y, int len, int coverage, const uint *src, int offset) + void process(int, int, int len, int coverage, const uint *src, int offset) { - if (spanMethod == RegularSpans) - op.func(dest + offset, src + offset, len, coverage); - else - drawBufferSpan(data, src + offset, len, x, y, len, coverage); + op.func(dest + offset, src + offset, len, coverage); } void store(int x, int y, int len) { - if (spanMethod == RegularSpans && op.dest_store) { + if (op.dest_store) op.dest_store(data->rasterBuffer, x, y, dest, len); - } } }; -template -Q_STATIC_TEMPLATE_FUNCTION void blend_src_generic(int count, const QSpan *spans, void *userData) +static void blend_src_generic(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); - BlendSrcGeneric blend(data, getOperator(data, spans, count)); + BlendSrcGeneric blend(data, getOperator(data, spans, count)); handleSpans(count, spans, data, blend); } -template -Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_generic(int count, const QSpan *spans, void *userData) +static void blend_untransformed_generic(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); @@ -3615,15 +3985,10 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_generic(int count, const QSp while (length) { int l = qMin(buffer_size, length); const uint *src = op.src_fetch(src_buffer, &op, data, sy, sx, l); - if (spanMethod == RegularSpans) { - uint *dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer; - op.func(dest, src, l, coverage); - if (op.dest_store) - op.dest_store(data->rasterBuffer, x, spans->y, dest, l); - } else { - drawBufferSpan(data, src, l, x, spans->y, - l, coverage); - } + uint *dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer; + op.func(dest, src, l, coverage); + if (op.dest_store) + op.dest_store(data->rasterBuffer, x, spans->y, dest, l); x += l; sx += l; length -= l; @@ -3634,13 +3999,12 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_generic(int count, const QSp } } -template -Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_argb(int count, const QSpan *spans, void *userData) +static void blend_untransformed_argb(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); if (data->texture.format != QImage::Format_ARGB32_Premultiplied && data->texture.format != QImage::Format_RGB32) { - blend_untransformed_generic(count, spans, userData); + blend_untransformed_generic(count, spans, userData); return; } @@ -3667,13 +4031,8 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_argb(int count, const QSpan if (length > 0) { const int coverage = (spans->coverage * data->texture.const_alpha) >> 8; const uint *src = (uint *)data->texture.scanLine(sy) + sx; - if (spanMethod == RegularSpans) { - uint *dest = ((uint *)data->rasterBuffer->scanLine(spans->y)) + x; - op.func(dest, src, length, coverage); - } else { - drawBufferSpan(data, src, length, x, - spans->y, length, coverage); - } + uint *dest = ((uint *)data->rasterBuffer->scanLine(spans->y)) + x; + op.func(dest, src, length, coverage); } } ++spans; @@ -3731,1167 +4090,19 @@ static inline void blend_sourceOver_rgb16_rgb16(quint16 *dest, } } -template -Q_STATIC_TEMPLATE_SPECIALIZATION -inline void madd_2(DST *dest, const quint16 alpha, const SRC *src) -{ - Q_ASSERT((quintptr(dest) & 0x3) == 0); - Q_ASSERT((quintptr(src) & 0x3) == 0); - dest[0] = dest[0].byte_mul(alpha >> 8) + DST(src[0]); - dest[1] = dest[1].byte_mul(alpha & 0xff) + DST(src[1]); -} - -template -Q_STATIC_TEMPLATE_SPECIALIZATION -inline void madd_4(DST *dest, const quint32 alpha, const SRC *src) -{ - Q_ASSERT((quintptr(dest) & 0x3) == 0); - Q_ASSERT((quintptr(src) & 0x3) == 0); - dest[0] = dest[0].byte_mul(alpha >> 24) + DST(src[0]); - dest[1] = dest[1].byte_mul((alpha >> 16) & 0xff) + DST(src[1]); - dest[2] = dest[2].byte_mul((alpha >> 8) & 0xff) + DST(src[2]); - dest[3] = dest[3].byte_mul(alpha & 0xff) + DST(src[3]); -} - -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline void madd_4(qargb8565 *dest, const quint32 a, const qargb8565 *src) -{ - Q_ASSERT((quintptr(dest) & 0x3) == 0); - Q_ASSERT((quintptr(src) & 0x3) == 0); - - const quint32 *src32 = reinterpret_cast(src); - quint32 *dest32 = reinterpret_cast(dest); - quint32 x, y, t; - quint8 a8; - - { - x = dest32[0]; - y = src32[0]; - - a8 = a >> 24; - - // a0,g0 - t = ((((x & 0x0007e0ff) * a8) >> 5) & 0x0007e0ff) + (y & 0x0007c0f8); - - // r0,b0 - t |= ((((x & 0x00f81f00) * a8) >> 5) & 0x00f81f00) + (y & 0x00f81f00); - - a8 = (a >> 16) & 0xff; - - // a1 - t |= ((((x & 0xff000000) >> 5) * a8) & 0xff000000) + (y & 0xf8000000); - - dest32[0] = t; - } - { - x = dest32[1]; - y = src32[1]; - - // r1,b1 - t = ((((x & 0x0000f81f) * a8) >> 5) & 0x0000f81f) + (y & 0x0000f81f); - - // g1 - t |= ((((x & 0x000007e0) * a8) >> 5) & 0x000007e0) + (y & 0x000007c0); - - a8 = (a >> 8) & 0xff; - - // a2 - t |= ((((x & 0x00ff0000) * a8) >> 5) & 0x00ff0000) + (y & 0x00f80000); - - { - // rgb2 - quint16 x16 = (x >> 24) | ((dest32[2] & 0x000000ff) << 8); - quint16 y16 = (y >> 24) | ((src32[2] & 0x000000ff) << 8); - quint16 t16; - - t16 = ((((x16 & 0xf81f) * a8) >> 5) & 0xf81f) + (y16 & 0xf81f); - t16 |= ((((x16 & 0x07e0) * a8) >> 5) & 0x07e0) + (y16 & 0x07c0); - - // rg2 - t |= ((t16 & 0x00ff) << 24); - - dest32[1] = t; - - x = dest32[2]; - y = src32[2]; - - // gb2 - t = (t16 >> 8); - } - } - { - a8 = a & 0xff; - - // g3,a3 - t |= ((((x & 0x07e0ff00) * a8) >> 5) & 0x07e0ff00) + (y & 0x07c0f800); - - // r3,b3 - t |= ((((x & 0xf81f0000) >> 5) * a8) & 0xf81f0000)+ (y & 0xf81f0000); - - dest32[2] = t; - } -} -#endif - -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline void madd_4(qargb8555 *dest, const quint32 a, const qargb8555 *src) -{ - Q_ASSERT((quintptr(dest) & 0x3) == 0); - Q_ASSERT((quintptr(src) & 0x3) == 0); - - const quint32 *src32 = reinterpret_cast(src); - quint32 *dest32 = reinterpret_cast(dest); - quint32 x, y, t; - quint8 a8; - - { - x = dest32[0]; - y = src32[0]; - - a8 = a >> 24; - - // a0,g0 - t = ((((x & 0x0003e0ff) * a8) >> 5) & 0x0003e0ff) + (y & 0x0003e0f8); - - // r0,b0 - t |= ((((x & 0x007c1f00) * a8) >> 5) & 0x007c1f00) + (y & 0x007c1f00); - - a8 = (a >> 16) & 0xff; - - // a1 - t |= ((((x & 0xff000000) >> 5) * a8) & 0xff000000) + (y & 0xf8000000); - - dest32[0] = t; - } - { - x = dest32[1]; - y = src32[1]; - - // r1,b1 - t = ((((x & 0x00007c1f) * a8) >> 5) & 0x00007c1f) + (y & 0x00007c1f); - - // g1 - t |= ((((x & 0x000003e0) * a8) >> 5) & 0x000003e0) + (y & 0x000003e0); - - a8 = (a >> 8) & 0xff; - - // a2 - t |= ((((x & 0x00ff0000) * a8) >> 5) & 0x00ff0000) + (y & 0x00f80000); - - { - // rgb2 - quint16 x16 = (x >> 24) | ((dest32[2] & 0x000000ff) << 8); - quint16 y16 = (y >> 24) | ((src32[2] & 0x000000ff) << 8); - quint16 t16; - - t16 = ((((x16 & 0x7c1f) * a8) >> 5) & 0x7c1f) + (y16 & 0x7c1f); - t16 |= ((((x16 & 0x03e0) * a8) >> 5) & 0x03e0) + (y16 & 0x03e0); - - // rg2 - t |= ((t16 & 0x00ff) << 24); - - dest32[1] = t; - - x = dest32[2]; - y = src32[2]; - - // gb2 - t = (t16 >> 8); - } - } - { - a8 = a & 0xff; - - // g3,a3 - t |= ((((x & 0x03e0ff00) * a8) >> 5) & 0x03e0ff00) + (y & 0x03e0f800); - - // r3,b3 - t |= ((((x & 0x7c1f0000) >> 5) * a8) & 0x7c1f0000)+ (y & 0x7c1f0000); - - dest32[2] = t; - } -} -#endif - -template -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint16 alpha_2(const T *src) -{ - Q_ASSERT((quintptr(src) & 0x3) == 0); - - if (T::hasAlpha()) - return (src[0].alpha() << 8) | src[1].alpha(); - else - return 0xffff; -} - -template -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint32 alpha_4(const T *src) -{ - Q_ASSERT((quintptr(src) & 0x3) == 0); - - if (T::hasAlpha()) { - return (src[0].alpha() << 24) | (src[1].alpha() << 16) - | (src[2].alpha() << 8) | src[3].alpha(); - } else { - return 0xffffffff; - } -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint32 alpha_4(const qargb8565 *src) -{ - const quint8 *src8 = reinterpret_cast(src); - return src8[0] << 24 | src8[3] << 16 | src8[6] << 8 | src8[9]; -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint32 alpha_4(const qargb6666 *src) -{ - const quint8 *src8 = reinterpret_cast(src); - return ((src8[2] & 0xfc) | (src8[2] >> 6)) << 24 - | ((src8[5] & 0xfc) | (src8[5] >> 6)) << 16 - | ((src8[8] & 0xfc) | (src8[8] >> 6)) << 8 - | ((src8[11] & 0xfc) | (src8[11] >> 6)); -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint32 alpha_4(const qargb8555 *src) -{ - Q_ASSERT((quintptr(src) & 0x3) == 0); - const quint8 *src8 = reinterpret_cast(src); - return src8[0] << 24 | src8[3] << 16 | src8[6] << 8 | src8[9]; -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint16 alpha_2(const qargb4444 *src) -{ - const quint32 *src32 = reinterpret_cast(src); - const quint32 t = (*src32 & 0xf000f000) | - ((*src32 & 0xf000f000) >> 4); - return (t >> 24) | (t & 0xff00); -} - -template -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint16 eff_alpha_2(quint16 alpha, const T*) -{ - return (T::alpha((alpha >> 8) & 0xff) << 8) - | T::alpha(alpha & 0xff); -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint16 eff_alpha_2(quint16 a, const qrgb565*) -{ - return ((((a & 0xff00) + 0x0100) >> 3) & 0xff00) - | ((((a & 0x00ff) + 0x0001) >> 3) & 0x00ff); -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint16 eff_alpha_2(quint16 a, const qrgb444*) -{ - return (((a & 0x00ff) + 0x0001) >> 4) - | ((((a & 0xff00) + 0x0100) >> 4) & 0xff00); -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint16 eff_alpha_2(quint16 a, const qargb4444*) -{ - return (((a & 0x00ff) + 0x0001) >> 4) - | ((((a & 0xff00) + 0x0100) >> 4) & 0xff00); -} - -template -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint16 eff_ialpha_2(quint16 alpha, const T*) -{ - return (T::ialpha((alpha >> 8) & 0xff) << 8) - | T::ialpha(alpha & 0xff); -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint16 eff_ialpha_2(quint16 a, const qrgb565 *dummy) -{ - return 0x2020 - eff_alpha_2(a, dummy); -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint16 eff_ialpha_2(quint16 a, const qargb4444 *dummy) -{ - return 0x1010 - eff_alpha_2(a, dummy); -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint16 eff_ialpha_2(quint16 a, const qrgb444 *dummy) -{ - return 0x1010 - eff_alpha_2(a, dummy); -} - -template -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint32 eff_alpha_4(quint32 alpha, const T*) -{ - return (T::alpha(alpha >> 24) << 24) - | (T::alpha((alpha >> 16) & 0xff) << 16) - | (T::alpha((alpha >> 8) & 0xff) << 8) - | T::alpha(alpha & 0xff); -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint32 eff_alpha_4(quint32 a, const qrgb888*) -{ - return a; -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint32 eff_alpha_4(quint32 a, const qargb8565*) -{ - return ((((a & 0xff00ff00) + 0x01000100) >> 3) & 0xff00ff00) - | ((((a & 0x00ff00ff) + 0x00010001) >> 3) & 0x00ff00ff); -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint32 eff_alpha_4(quint32 a, const qargb6666*) -{ - return ((((a & 0xff00ff00) >> 2) + 0x00400040) & 0xff00ff00) - | ((((a & 0x00ff00ff) + 0x00010001) >> 2) & 0x00ff00ff); -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint32 eff_alpha_4(quint32 a, const qrgb666*) -{ - return ((((a & 0xff00ff00) >> 2) + 0x00400040) & 0xff00ff00) - | ((((a & 0x00ff00ff) + 0x00010001) >> 2) & 0x00ff00ff); -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint32 eff_alpha_4(quint32 a, const qargb8555*) -{ - return ((((a & 0xff00ff00) + 0x01000100) >> 3) & 0xff00ff00) - | ((((a & 0x00ff00ff) + 0x00010001) >> 3) & 0x00ff00ff); -} - -template -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint32 eff_ialpha_4(quint32 alpha, const T*) -{ - return (T::ialpha(alpha >> 24) << 24) - | (T::ialpha((alpha >> 16) & 0xff) << 16) - | (T::ialpha((alpha >> 8) & 0xff) << 8) - | T::ialpha(alpha & 0xff); -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint32 eff_ialpha_4(quint32 a, const qrgb888*) -{ - return ~a; -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint32 eff_ialpha_4(quint32 a, const qargb8565 *dummy) -{ - return 0x20202020 - eff_alpha_4(a, dummy); -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint32 eff_ialpha_4(quint32 a, const qargb6666 *dummy) -{ - return 0x40404040 - eff_alpha_4(a, dummy); -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint32 eff_ialpha_4(quint32 a, const qrgb666 *dummy) -{ - return 0x40404040 - eff_alpha_4(a, dummy); -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline quint32 eff_ialpha_4(quint32 a, const qargb8555 *dummy) -{ - return 0x20202020 - eff_alpha_4(a, dummy); -} - -template -inline void interpolate_pixel_unaligned_2(DST *dest, const SRC *src, - quint16 alpha) -{ - const quint16 a = eff_alpha_2(alpha, dest); - const quint16 ia = eff_ialpha_2(alpha, dest); - dest[0] = DST(src[0]).byte_mul(a >> 8) + dest[0].byte_mul(ia >> 8); - dest[1] = DST(src[1]).byte_mul(a & 0xff) + dest[1].byte_mul(ia & 0xff); -} - -template -inline void interpolate_pixel_2(DST *dest, const SRC *src, quint16 alpha) -{ - Q_ASSERT((quintptr(dest) & 0x3) == 0); - Q_ASSERT((quintptr(src) & 0x3) == 0); - - const quint16 a = eff_alpha_2(alpha, dest); - const quint16 ia = eff_ialpha_2(alpha, dest); - - dest[0] = DST(src[0]).byte_mul(a >> 8) + dest[0].byte_mul(ia >> 8); - dest[1] = DST(src[1]).byte_mul(a & 0xff) + dest[1].byte_mul(ia & 0xff); -} - -template -inline void interpolate_pixel(DST &dest, quint8 a, const SRC &src, quint8 b) -{ - if (SRC::hasAlpha() && !DST::hasAlpha()) - interpolate_pixel(dest, a, DST(src), b); - else - dest = dest.byte_mul(a) + DST(src).byte_mul(b); -} - -template <> -inline void interpolate_pixel(qargb8565 &dest, quint8 a, - const qargb8565 &src, quint8 b) -{ - quint8 *d = reinterpret_cast(&dest); - const quint8 *s = reinterpret_cast(&src); - d[0] = (d[0] * a + s[0] * b) >> 5; - - const quint16 x = (d[2] << 8) | d[1]; - const quint16 y = (s[2] << 8) | s[1]; - quint16 t = (((x & 0x07e0) * a + (y & 0x07e0) * b) >> 5) & 0x07e0; - t |= (((x & 0xf81f) * a + (y & 0xf81f) * b) >> 5) & 0xf81f; - - d[1] = t & 0xff; - d[2] = t >> 8; -} - -template <> -inline void interpolate_pixel(qrgb565 &dest, quint8 a, - const qrgb565 &src, quint8 b) -{ - const quint16 x = dest.rawValue(); - const quint16 y = src.rawValue(); - quint16 t = (((x & 0x07e0) * a + (y & 0x07e0) * b) >> 5) & 0x07e0; - t |= (((x & 0xf81f) * a + (y & 0xf81f) * b) >> 5) & 0xf81f; - dest = t; -} - -template <> -inline void interpolate_pixel(qrgb555 &dest, quint8 a, - const qrgb555 &src, quint8 b) -{ - const quint16 x = dest.rawValue(); - const quint16 y = src.rawValue(); - quint16 t = (((x & 0x03e0) * a + (y & 0x03e0) * b) >> 5) & 0x03e0; - t |= ((((x & 0x7c1f) * a) + ((y & 0x7c1f) * b)) >> 5) & 0x7c1f; - dest = t; -} - -template <> -inline void interpolate_pixel(qrgb444 &dest, quint8 a, - const qrgb444 &src, quint8 b) -{ - const quint16 x = dest.rawValue(); - const quint16 y = src.rawValue(); - quint16 t = ((x & 0x00f0) * a + (y & 0x00f0) * b) & 0x0f00; - t |= ((x & 0x0f0f) * a + (y & 0x0f0f) * b) & 0xf0f0; - quint16 *d = reinterpret_cast(&dest); - *d = (t >> 4); -} - -template -inline void interpolate_pixel_2(DST *dest, quint8 a, - const SRC *src, quint8 b) -{ - Q_ASSERT((quintptr(dest) & 0x3) == 0); - Q_ASSERT((quintptr(src) & 0x3) == 0); - - Q_ASSERT(!SRC::hasAlpha()); - - dest[0] = dest[0].byte_mul(a) + DST(src[0]).byte_mul(b); - dest[1] = dest[1].byte_mul(a) + DST(src[1]).byte_mul(b); -} - -template <> -inline void interpolate_pixel_2(qrgb565 *dest, quint8 a, - const qrgb565 *src, quint8 b) -{ - quint32 *x = reinterpret_cast(dest); - const quint32 *y = reinterpret_cast(src); - quint32 t = (((*x & 0xf81f07e0) >> 5) * a + - ((*y & 0xf81f07e0) >> 5) * b) & 0xf81f07e0; - t |= (((*x & 0x07e0f81f) * a - + (*y & 0x07e0f81f) * b) >> 5) & 0x07e0f81f; - *x = t; -} - -template <> -inline void interpolate_pixel_2(qrgb555 *dest, quint8 a, - const qrgb555 *src, quint8 b) -{ - quint32 *x = reinterpret_cast(dest); - const quint32 *y = reinterpret_cast(src); - quint32 t = (((*x & 0x7c1f03e0) >> 5) * a + - ((*y & 0x7c1f03e0) >> 5) * b) & 0x7c1f03e0; - t |= (((*x & 0x03e07c1f) * a - + (*y & 0x03e07c1f) * b) >> 5) & 0x03e07c1f; - *x = t; -} - -template <> -inline void interpolate_pixel_2(qrgb444 *dest, quint8 a, - const qrgb444 *src, quint8 b) -{ - quint32 *x = reinterpret_cast(dest); - const quint32 *y = reinterpret_cast(src); - quint32 t = ((*x & 0x0f0f0f0f) * a + (*y & 0x0f0f0f0f) * b) & 0xf0f0f0f0; - t |= ((*x & 0x00f000f0) * a + (*y & 0x00f000f0) * b) & 0x0f000f00; - *x = t >> 4; -} - -template -inline void interpolate_pixel_4(DST *dest, const SRC *src, quint32 alpha) -{ - Q_ASSERT((quintptr(dest) & 0x3) == 0); - Q_ASSERT((quintptr(src) & 0x3) == 0); - - const quint32 a = eff_alpha_4(alpha, dest); - const quint32 ia = eff_ialpha_4(alpha, dest); - dest[0] = DST(src[0]).byte_mul(a >> 24) - + dest[0].byte_mul(ia >> 24); - dest[1] = DST(src[1]).byte_mul((a >> 16) & 0xff) - + dest[1].byte_mul((ia >> 16) & 0xff); - dest[2] = DST(src[2]).byte_mul((a >> 8) & 0xff) - + dest[2].byte_mul((ia >> 8) & 0xff); - dest[3] = DST(src[3]).byte_mul(a & 0xff) - + dest[3].byte_mul(ia & 0xff); -} - -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN -template <> -inline void interpolate_pixel_4(qargb8565 *dest, const qargb8565 *src, - quint32 alpha) -{ - Q_ASSERT((quintptr(dest) & 0x3) == 0); - Q_ASSERT((quintptr(src) & 0x3) == 0); - - const quint32 a = eff_alpha_4(alpha, dest); - const quint32 ia = eff_ialpha_4(alpha, dest); - const quint32 *src32 = reinterpret_cast(src); - quint32 *dest32 = reinterpret_cast(dest); - - quint32 x, y, t; - quint8 a8, ia8; - { - x = src32[0]; - y = dest32[0]; - - a8 = a >> 24; - ia8 = ia >> 24; - - // a0,g0 - t = (((x & 0x0007e0ff) * a8 + (y & 0x0007e0ff) * ia8) >> 5) - & 0x0007e0ff; - - // r0,b0 - t |= (((x & 0x00f81f00) * a8 + (y & 0x00f81f00) * ia8) >> 5) - & 0x00f81f00; - - a8 = (a >> 16) & 0xff; - ia8 = (ia >> 16) & 0xff; - - // a1 - t |= (((x & 0xff000000) >> 5) * a8 + ((y & 0xff000000) >> 5) * ia8) - & 0xff000000; - - dest32[0] = t; - } - { - x = src32[1]; - y = dest32[1]; - - // r1,b1 - t = (((x & 0x0000f81f) * a8 + (y & 0x0000f81f) * ia8) >> 5) - & 0x0000f81f; - - // g1 - t |= (((x & 0x000007e0) * a8 + (y & 0x000007e0) * ia8) >> 5) - & 0x000007e0; - - a8 = (a >> 8) & 0xff; - ia8 = (ia >> 8) & 0xff; - - // a2 - t |= (((x & 0x00ff0000) * a8 + (y & 0x00ff0000) * ia8) >> 5) - & 0x00ff0000; - - { - // rgb2 - quint16 x16 = (x >> 24) | ((src32[2] & 0x000000ff) << 8); - quint16 y16 = (y >> 24) | ((dest32[2] & 0x000000ff) << 8); - quint16 t16; - - t16 = (((x16 & 0xf81f) * a8 + (y16 & 0xf81f) * ia8) >> 5) & 0xf81f; - t16 |= (((x16 & 0x07e0) * a8 + (y16 & 0x07e0) * ia8) >> 5) & 0x07e0; - - // rg2 - t |= ((t16 & 0x00ff) << 24); - - dest32[1] = t; - - x = src32[2]; - y = dest32[2]; - - // gb2 - t = (t16 >> 8); - } - } - { - a8 = a & 0xff; - ia8 = ia & 0xff; - - // g3,a3 - t |= (((x & 0x07e0ff00) * a8 + (y & 0x07e0ff00) * ia8) >> 5) - & 0x07e0ff00; - - // r3,b3 - t |= (((x & 0xf81f0000) >> 5) * a8 + ((y & 0xf81f0000) >> 5) * ia8) - & 0xf81f0000; - - dest32[2] = t; - } -} -#endif - -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN -template <> -inline void interpolate_pixel_4(qargb8555 *dest, const qargb8555 *src, - quint32 alpha) -{ - Q_ASSERT((quintptr(dest) & 0x3) == 0); - Q_ASSERT((quintptr(src) & 0x3) == 0); - - - const quint32 a = eff_alpha_4(alpha, dest); - const quint32 ia = eff_ialpha_4(alpha, dest); - const quint32 *src32 = reinterpret_cast(src); - quint32 *dest32 = reinterpret_cast(dest); - - quint32 x, y, t; - quint8 a8, ia8; - { - x = src32[0]; - y = dest32[0]; - - a8 = a >> 24; - ia8 = ia >> 24; - - // a0,g0 - t = (((x & 0x0003e0ff) * a8 + (y & 0x0003e0ff) * ia8) >> 5) - & 0x0003e0ff; - - // r0,b0 - t |= (((x & 0x007c1f00) * a8 + (y & 0x007c1f00) * ia8) >> 5) - & 0x007c1f00; - - a8 = (a >> 16) & 0xff; - ia8 = (ia >> 16) & 0xff; - - // a1 - t |= (((x & 0xff000000) >> 5) * a8 + ((y & 0xff000000) >> 5) * ia8) - & 0xff000000; - - dest32[0] = t; - } - { - x = src32[1]; - y = dest32[1]; - - // r1,b1 - t = (((x & 0x00007c1f) * a8 + (y & 0x00007c1f) * ia8) >> 5) - & 0x00007c1f; - - // g1 - t |= (((x & 0x000003e0) * a8 + (y & 0x000003e0) * ia8) >> 5) - & 0x000003e0; - - a8 = (a >> 8) & 0xff; - ia8 = (ia >> 8) & 0xff; - - // a2 - t |= (((x & 0x00ff0000) * a8 + (y & 0x00ff0000) * ia8) >> 5) - & 0x00ff0000; - - { - // rgb2 - quint16 x16 = (x >> 24) | ((src32[2] & 0x000000ff) << 8); - quint16 y16 = (y >> 24) | ((dest32[2] & 0x000000ff) << 8); - quint16 t16; - - t16 = (((x16 & 0x7c1f) * a8 + (y16 & 0x7c1f) * ia8) >> 5) & 0x7c1f; - t16 |= (((x16 & 0x03e0) * a8 + (y16 & 0x03e0) * ia8) >> 5) & 0x03e0; - - // rg2 - t |= ((t16 & 0x00ff) << 24); - - dest32[1] = t; - - x = src32[2]; - y = dest32[2]; - - // gb2 - t = (t16 >> 8); - } - } - { - a8 = a & 0xff; - ia8 = ia & 0xff; - - // g3,a3 - t |= (((x & 0x03e0ff00) * a8 + (y & 0x03e0ff00) * ia8) >> 5) - & 0x03e0ff00; - - // r3,b3 - t |= (((x & 0x7c1f0000) >> 5) * a8 + ((y & 0x7c1f0000) >> 5) * ia8) - & 0x7c1f0000; - - dest32[2] = t; - } -} -#endif - -template <> -inline void interpolate_pixel_4(qrgb888 *dest, const qrgb888 *src, - quint32 alpha) -{ - Q_ASSERT((quintptr(dest) & 0x3) == 0); - Q_ASSERT((quintptr(src) & 0x3) == 0); - - const quint32 a = eff_alpha_4(alpha, dest); - const quint32 ia = eff_ialpha_4(alpha, dest); - const quint32 *src32 = reinterpret_cast(src); - quint32 *dest32 = reinterpret_cast(dest); - - { - quint32 x = src32[0]; - quint32 y = dest32[0]; - - quint32 t; - t = ((x >> 8) & 0xff00ff) * (a >> 24) - + ((y >> 8) & 0xff00ff) * (ia >> 24); - t = (t + ((t >> 8) & 0xff00ff) + 0x800080); - t &= 0xff00ff00; - - x = (x & 0xff0000) * (a >> 24) - + (x & 0x0000ff) * ((a >> 16) & 0xff) - + (y & 0xff0000) * (ia >> 24) - + (y & 0x0000ff) * ((ia >> 16) & 0xff); - x = (x + ((x >> 8) & 0xff00ff) + 0x800080) >> 8; - x &= 0x00ff00ff; - - dest32[0] = x | t; - } - { - quint32 x = src32[1]; - quint32 y = dest32[1]; - - quint32 t; - t = ((x >> 8) & 0xff0000) * ((a >> 16) & 0xff) - + ((x >> 8) & 0x0000ff) * ((a >> 8) & 0xff) - + ((y >> 8) & 0xff0000) * ((ia >> 16) & 0xff) - + ((y >> 8) & 0x0000ff) * ((ia >> 8) & 0xff); - t = (t + ((t >> 8) & 0xff00ff) + 0x800080); - t &= 0xff00ff00; - - x = (x & 0xff0000) * ((a >> 16) & 0xff) - + (x & 0x0000ff) * ((a >> 8) & 0xff) - + (y & 0xff0000) * ((ia >> 16) & 0xff) - + (y & 0x0000ff) * ((ia >> 8) & 0xff); - x = (x + ((x >> 8) & 0xff00ff) + 0x800080) >> 8; - x &= 0x00ff00ff; - - dest32[1] = x | t; - } - { - quint32 x = src32[2]; - quint32 y = dest32[2]; - - quint32 t; - t = ((x >> 8) & 0xff0000) * ((a >> 8) & 0xff) - + ((x >> 8) & 0x0000ff) * (a & 0xff) - + ((y >> 8) & 0xff0000) * ((ia >> 8) & 0xff) - + ((y >> 8) & 0x0000ff) * (ia & 0xff); - t = (t + ((t >> 8) & 0xff00ff) + 0x800080); - t &= 0xff00ff00; - - x = (x & 0xff00ff) * (a & 0xff) - + (y & 0xff00ff) * (ia & 0xff); - x = (x + ((x >> 8) & 0xff00ff) + 0x800080) >> 8; - x &= 0x00ff00ff; - - dest32[2] = x | t; - } -} - -template -inline void interpolate_pixel_4(DST *dest, quint8 a, - const SRC *src, quint8 b) -{ - Q_ASSERT((quintptr(dest) & 0x3) == 0); - Q_ASSERT((quintptr(src) & 0x3) == 0); - - dest[0] = dest[0].byte_mul(a) + DST(src[0]).byte_mul(b); - dest[1] = dest[1].byte_mul(a) + DST(src[1]).byte_mul(b); - dest[2] = dest[2].byte_mul(a) + DST(src[2]).byte_mul(b); - dest[3] = dest[3].byte_mul(a) + DST(src[3]).byte_mul(b); -} - -template -inline void blend_sourceOver_4(DST *dest, const SRC *src) -{ - Q_ASSERT((quintptr(dest) & 0x3) == 0); - Q_ASSERT((quintptr(src) & 0x3) == 0); - - const quint32 a = alpha_4(src); - if (a == 0xffffffff) { - qt_memconvert(dest, src, 4); - } else if (a > 0) { - quint32 buf[3]; // array of quint32 to get correct alignment - qt_memconvert((DST*)(void*)buf, src, 4); - madd_4(dest, eff_ialpha_4(a, dest), (DST*)(void*)buf); - } -} - -template <> -inline void blend_sourceOver_4(qargb8565 *dest, const qargb8565 *src) -{ - Q_ASSERT((quintptr(dest) & 0x3) == 0); - Q_ASSERT((quintptr(src) & 0x3) == 0); - - const quint32 a = alpha_4(src); - if (a == 0xffffffff) { - qt_memconvert(dest, src, 4); - } else if (a > 0) { - madd_4(dest, eff_ialpha_4(a, dest), src); - } -} - -template <> -inline void blend_sourceOver_4(qargb8555 *dest, const qargb8555 *src) -{ - Q_ASSERT((quintptr(dest) & 0x3) == 0); - Q_ASSERT((quintptr(src) & 0x3) == 0); - - const quint32 a = alpha_4(src); - if (a == 0xffffffff) { - qt_memconvert(dest, src, 4); - } else if (a > 0) { - madd_4(dest, eff_ialpha_4(a, dest), src); - } -} - -template <> -inline void blend_sourceOver_4(qargb6666 *dest, const qargb6666 *src) -{ - Q_ASSERT((quintptr(dest) & 0x3) == 0); - Q_ASSERT((quintptr(src) & 0x3) == 0); - - const quint32 a = alpha_4(src); - if (a == 0xffffffff) { - qt_memconvert(dest, src, 4); - } else if (a > 0) { - madd_4(dest, eff_ialpha_4(a, dest), src); - } -} - -template -void QT_FASTCALL blendUntransformed_unaligned(DST *dest, const SRC *src, - quint8 coverage, int length) -{ - Q_ASSERT(coverage > 0); - - if (coverage < 255) { - if (SRC::hasAlpha()) { - for (int i = 0; i < length; ++i) { - if (src[i].alpha()) { - const quint8 alpha = qt_div_255(int(src[i].alpha()) * int(coverage)); - interpolate_pixel(dest[i], DST::ialpha(alpha), - src[i], DST::alpha(alpha)); - } - } - } else { - const quint8 alpha = DST::alpha(coverage); - const quint8 ialpha = DST::ialpha(coverage); - if (alpha) { - for (int i = 0; i < length; ++i) - interpolate_pixel(dest[i], ialpha, src[i], alpha); - } - } - return; - } - - Q_ASSERT(coverage == 0xff); - Q_ASSERT(SRC::hasAlpha()); - - if (SRC::hasAlpha()) { - for (int i = 0; i < length; ++i) { - const quint8 a = src->alpha(); - if (a == 0xff) - *dest = DST(*src); - else if (a > 0) { - if (DST::hasAlpha()) - *dest = DST(*src).truncedAlpha() + dest->byte_mul(DST::ialpha(a)); - else - *dest = DST(SRC(*src).truncedAlpha()) + dest->byte_mul(DST::ialpha(a)); - } - ++src; - ++dest; - } - } -} - -template -void QT_FASTCALL blendUntransformed_dest16(DST *dest, const SRC *src, - quint8 coverage, int length) -{ - Q_ASSERT(sizeof(DST) == 2); - Q_ASSERT(sizeof(SRC) == 2); - Q_ASSERT((quintptr(dest) & 0x3) == (quintptr(src) & 0x3)); - Q_ASSERT(coverage > 0); - - const int align = quintptr(dest) & 0x3; - - if (coverage < 255) { - // align - if (align) { - const quint8 alpha = SRC::hasAlpha() - ? qt_div_255(int(src->alpha()) * int(coverage)) - : coverage; - if (alpha) { - interpolate_pixel(*dest, DST::ialpha(alpha), - *src, DST::alpha(alpha)); - } - ++dest; - ++src; - --length; - } - - if (SRC::hasAlpha()) { - while (length >= 2) { - const quint16 alpha16 = BYTE_MUL(uint(alpha_2(src)), uint(coverage)); - interpolate_pixel_2(dest, src, alpha16); - length -= 2; - src += 2; - dest += 2; - } - } else { - const quint8 alpha = DST::alpha(coverage); - const quint8 ialpha = DST::ialpha(coverage); - - while (length >= 2) { - interpolate_pixel_2(dest, ialpha, src, alpha); - length -= 2; - src += 2; - dest += 2; - } - } - - // tail - if (length) { - const quint8 alpha = SRC::hasAlpha() - ? qt_div_255(int(src->alpha()) * int(coverage)) - : coverage; - if (alpha) { - interpolate_pixel(*dest, DST::ialpha(alpha), - *src, DST::alpha(alpha)); - } - } - - return; - } - - Q_ASSERT(SRC::hasAlpha()); - if (SRC::hasAlpha()) { - if (align) { - const quint8 alpha = src->alpha(); - if (alpha == 0xff) - *dest = DST(*src); - else if (alpha > 0) - *dest = DST(*src).truncedAlpha() + dest->byte_mul(DST::ialpha(alpha)); - ++dest; - ++src; - --length; - } - - while (length >= 2) { - Q_ASSERT((quintptr(dest) & 3) == 0); - Q_ASSERT((quintptr(src) & 3) == 0); - - const quint16 a = alpha_2(src); - if (a == 0xffff) { - qt_memconvert(dest, src, 2); - } else if (a > 0) { - quint32 buf; - if (sizeof(DST) == 2) - qt_memconvert((DST*)(void*)&buf, src, 2); - madd_2(dest, eff_ialpha_2(a, dest), (DST*)(void*)&buf); - } - - length -= 2; - src += 2; - dest += 2; - } - - if (length) { - const quint8 alpha = src->alpha(); - if (alpha == 0xff) - *dest = DST(*src); - else if (alpha > 0) - *dest = DST(*src).truncedAlpha() + dest->byte_mul(DST::ialpha(alpha)); - } - } -} - -template -void QT_FASTCALL blendUntransformed_dest24(DST *dest, const SRC *src, - quint8 coverage, int length) -{ - Q_ASSERT((quintptr(dest) & 0x3) == (quintptr(src) & 0x3)); - Q_ASSERT(sizeof(DST) == 3); - Q_ASSERT(coverage > 0); - - const int align = quintptr(dest) & 0x3; - - if (coverage < 255) { - // align - for (int i = 0; i < align; ++i) { - if (SRC::hasAlpha()) { - const quint8 alpha = qt_div_255(int(src->alpha()) * int(coverage)); - if (alpha) - interpolate_pixel(*dest, DST::ialpha(alpha), - *src, DST::alpha(alpha)); - } else { - interpolate_pixel(*dest, DST::ialpha(coverage), - *src, DST::alpha(coverage)); - } - ++dest; - ++src; - --length; - } - - if (SRC::hasAlpha()) { - while (length >= 4) { - const quint32 alpha = QT_PREPEND_NAMESPACE(BYTE_MUL)(uint(alpha_4(src)), uint(coverage)); - if (alpha) - interpolate_pixel_4(dest, src, alpha); - length -= 4; - src += 4; - dest += 4; - } - } else { - const quint8 alpha = DST::alpha(coverage); - const quint8 ialpha = DST::ialpha(coverage); - while (length >= 4) { - interpolate_pixel_4(dest, ialpha, src, alpha); - length -= 4; - src += 4; - dest += 4; - } - } - - // tail - while (length--) { - if (SRC::hasAlpha()) { - const quint8 alpha = qt_div_255(int(src->alpha()) * int(coverage)); - if (alpha) - interpolate_pixel(*dest, DST::ialpha(alpha), - *src, DST::alpha(alpha)); - } else { - interpolate_pixel(*dest, DST::ialpha(coverage), - *src, DST::alpha(coverage)); - } - ++dest; - ++src; - } - - return; - } - - - Q_ASSERT(coverage == 255); - Q_ASSERT(SRC::hasAlpha()); - - if (SRC::hasAlpha()) { - // align - for (int i = 0; i < align; ++i) { - const quint8 a = src->alpha(); - if (a == 0xff) { - *dest = DST(*src); - } else if (a > 0) { - *dest = DST(*src).truncedAlpha() + dest->byte_mul(DST::ialpha(a)); - } - ++dest; - ++src; - --length; - } - - while (length >= 4) { - blend_sourceOver_4(dest, src); - length -= 4; - src += 4; - dest += 4; - } - - // tail - while (length--) { - const quint8 a = src->alpha(); - if (a == 0xff) { - *dest = DST(*src); - } else if (a > 0) { - *dest = DST(*src).truncedAlpha() + dest->byte_mul(DST::ialpha(a)); - } - ++dest; - ++src; - } - } -} - -template -Q_STATIC_TEMPLATE_SPECIALIZATION -void QT_FASTCALL blendUntransformed(int count, const QSpan *spans, void *userData) +static void blend_untransformed_rgb565(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); QPainter::CompositionMode mode = data->rasterBuffer->compositionMode; - if (mode != QPainter::CompositionMode_SourceOver && - mode != QPainter::CompositionMode_Source) + if (data->texture.format != QImage::Format_RGB16 + || (mode != QPainter::CompositionMode_SourceOver + && mode != QPainter::CompositionMode_Source)) { - blend_src_generic(count, spans, userData); + blend_untransformed_generic(count, spans, userData); return; } - const bool modeSource = !SRC::hasAlpha() || - mode == QPainter::CompositionMode_Source; const int image_width = data->texture.width; const int image_height = data->texture.height; int xoff = -qRound(-data->dx); @@ -4917,20 +4128,15 @@ void QT_FASTCALL blendUntransformed(int count, const QSpan *spans, void *userDat if (sx + length > image_width) length = image_width - sx; if (length > 0) { - DST *dest = ((DST*)data->rasterBuffer->scanLine(spans->y)) + x; - const SRC *src = (SRC*)data->texture.scanLine(sy) + sx; - if (modeSource && coverage == 255) { - qt_memconvert(dest, src, length); - } else if (sizeof(DST) == 3 && sizeof(SRC) == 3 && length >= 3 && - (quintptr(dest) & 3) == (quintptr(src) & 3)) - { - blendUntransformed_dest24(dest, src, coverage, length); - } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && length >= 3 && - (quintptr(dest) & 3) == (quintptr(src) & 3)) - { - blendUntransformed_dest16(dest, src, coverage, length); + quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + x; + const quint16 *src = (quint16 *)data->texture.scanLine(sy) + sx; + if (coverage == 255) { + memcpy(dest, src, length * sizeof(quint16)); } else { - blendUntransformed_unaligned(dest, src, coverage, length); + const quint8 alpha = (coverage + 1) >> 3; + const quint8 ialpha = 0x20 - alpha; + if (alpha > 0) + blend_sourceOver_rgb16_rgb16(dest, src, length, alpha, ialpha); } } } @@ -4938,69 +4144,7 @@ void QT_FASTCALL blendUntransformed(int count, const QSpan *spans, void *userDat } } -static void blend_untransformed_rgb888(int count, const QSpan *spans, - void *userData) -{ - blend_untransformed_generic(count, spans, userData); -} - -static void blend_untransformed_argb6666(int count, const QSpan *spans, - void *userData) -{ - blend_untransformed_generic(count, spans, userData); -} - -static void blend_untransformed_rgb666(int count, const QSpan *spans, - void *userData) -{ - blend_untransformed_generic(count, spans, userData); -} - -static void blend_untransformed_argb8565(int count, const QSpan *spans, - void *userData) -{ - blend_untransformed_generic(count, spans, userData); -} - -static void blend_untransformed_rgb565(int count, const QSpan *spans, - void *userData) -{ - QSpanData *data = reinterpret_cast(userData); - - if (data->texture.format == QImage::Format_ARGB8565_Premultiplied) - blendUntransformed(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB16) - blendUntransformed(count, spans, userData); - else - blend_untransformed_generic(count, spans, userData); -} - -static void blend_untransformed_argb8555(int count, const QSpan *spans, - void *userData) -{ - blend_untransformed_generic(count, spans, userData); -} - -static void blend_untransformed_rgb555(int count, const QSpan *spans, - void *userData) -{ - blend_untransformed_generic(count, spans, userData); -} - -static void blend_untransformed_argb4444(int count, const QSpan *spans, - void *userData) -{ - blend_untransformed_generic(count, spans, userData); -} - -static void blend_untransformed_rgb444(int count, const QSpan *spans, - void *userData) -{ - blend_untransformed_generic(count, spans, userData); -} - -template -Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_generic(int count, const QSpan *spans, void *userData) +static void blend_tiled_generic(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); @@ -5034,15 +4178,10 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_generic(int count, const QSpan *span if (buffer_size < l) l = buffer_size; const uint *src = op.src_fetch(src_buffer, &op, data, sy, sx, l); - if (spanMethod == RegularSpans) { - uint *dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer; - op.func(dest, src, l, coverage); - if (op.dest_store) - op.dest_store(data->rasterBuffer, x, spans->y, dest, l); - } else { - drawBufferSpan(data, src, l, x, spans->y, l, - coverage); - } + uint *dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer; + op.func(dest, src, l, coverage); + if (op.dest_store) + op.dest_store(data->rasterBuffer, x, spans->y, dest, l); x += l; sx += l; length -= l; @@ -5053,13 +4192,12 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_generic(int count, const QSpan *span } } -template -Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_argb(int count, const QSpan *spans, void *userData) +static void blend_tiled_argb(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); if (data->texture.format != QImage::Format_ARGB32_Premultiplied && data->texture.format != QImage::Format_RGB32) { - blend_tiled_generic(count, spans, userData); + blend_tiled_generic(count, spans, userData); return; } @@ -5091,13 +4229,8 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_argb(int count, const QSpan *spans, if (buffer_size < l) l = buffer_size; const uint *src = (uint *)data->texture.scanLine(sy) + sx; - if (spanMethod == RegularSpans) { - uint *dest = ((uint *)data->rasterBuffer->scanLine(spans->y)) + x; - op.func(dest, src, l, coverage); - } else { - drawBufferSpan(data, src, buffer_size, - x, spans->y, l, coverage); - } + uint *dest = ((uint *)data->rasterBuffer->scanLine(spans->y)) + x; + op.func(dest, src, l, coverage); x += l; length -= l; sx = 0; @@ -5106,21 +4239,19 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_argb(int count, const QSpan *spans, } } -template -Q_STATIC_TEMPLATE_FUNCTION void blendTiled(int count, const QSpan *spans, void *userData) +static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); QPainter::CompositionMode mode = data->rasterBuffer->compositionMode; - if (mode != QPainter::CompositionMode_SourceOver && - mode != QPainter::CompositionMode_Source) + if (data->texture.format != QImage::Format_RGB16 + || (mode != QPainter::CompositionMode_SourceOver + && mode != QPainter::CompositionMode_Source)) { - blend_src_generic(count, spans, userData); + blend_tiled_generic(count, spans, userData); return; } - const bool modeSource = !SRC::hasAlpha() || - mode == QPainter::CompositionMode_Source; const int image_width = data->texture.width; const int image_height = data->texture.height; int xoff = -qRound(-data->dx) % image_width; @@ -5147,7 +4278,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTiled(int count, const QSpan *spans, void * if (sy < 0) sy += image_height; - if (modeSource && coverage == 255) { + if (coverage == 255) { // Copy the first texture block length = qMin(image_width,length); int tx = x; @@ -5155,10 +4286,9 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTiled(int count, const QSpan *spans, void * int l = qMin(image_width - sx, length); if (buffer_size < l) l = buffer_size; - DST *dest = ((DST*)data->rasterBuffer->scanLine(spans->y)) + tx; - const SRC *src = (SRC*)data->texture.scanLine(sy) + sx; - - qt_memconvert(dest, src, l); + quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans->y)) + tx; + const quint16 *src = (quint16 *)data->texture.scanLine(sy) + sx; + memcpy(dest, src, l * sizeof(quint16)); length -= l; tx += l; sx = 0; @@ -5172,110 +4302,51 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTiled(int count, const QSpan *spans, void * // - can use memcpy int copy_image_width = qMin(image_width, int(spans->len)); length = spans->len - copy_image_width; - DST *src = ((DST*)data->rasterBuffer->scanLine(spans->y)) + x; - DST *dest = src + copy_image_width; + quint16 *src = ((quint16 *)data->rasterBuffer->scanLine(spans->y)) + x; + quint16 *dest = src + copy_image_width; while (copy_image_width < length) { - qt_memconvert(dest, src, copy_image_width); + memcpy(dest, src, copy_image_width * sizeof(quint16)); dest += copy_image_width; length -= copy_image_width; copy_image_width *= 2; } if (length > 0) - qt_memconvert(dest, src, length); + memcpy(dest, src, length * sizeof(quint16)); } else { - while (length) { - int l = qMin(image_width - sx, length); - if (buffer_size < l) - l = buffer_size; - DST *dest = ((DST*)data->rasterBuffer->scanLine(spans->y)) + x; - const SRC *src = (SRC*)data->texture.scanLine(sy) + sx; - if (sizeof(DST) == 3 && sizeof(SRC) == 3 && l >= 4 && - (quintptr(dest) & 3) == (quintptr(src) & 3)) - { - blendUntransformed_dest24(dest, src, coverage, l); - } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 && - (quintptr(dest) & 3) == (quintptr(src) & 3)) - { - blendUntransformed_dest16(dest, src, coverage, l); - } else { - blendUntransformed_unaligned(dest, src, coverage, l); + const quint8 alpha = (coverage + 1) >> 3; + const quint8 ialpha = 0x20 - alpha; + if (alpha > 0) { + while (length) { + int l = qMin(image_width - sx, length); + if (buffer_size < l) + l = buffer_size; + quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans->y)) + x; + const quint16 *src = (quint16 *)data->texture.scanLine(sy) + sx; + blend_sourceOver_rgb16_rgb16(dest, src, l, alpha, ialpha); + x += l; + length -= l; + sx = 0; } - - x += l; - length -= l; - sx = 0; } } ++spans; } } -static void blend_tiled_rgb888(int count, const QSpan *spans, void *userData) -{ - blend_tiled_generic(count, spans, userData); -} - -static void blend_tiled_argb6666(int count, const QSpan *spans, void *userData) -{ - blend_tiled_generic(count, spans, userData); -} - -static void blend_tiled_rgb666(int count, const QSpan *spans, void *userData) -{ - blend_tiled_generic(count, spans, userData); -} - -static void blend_tiled_argb8565(int count, const QSpan *spans, void *userData) -{ - blend_tiled_generic(count, spans, userData); -} - -static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData) -{ - QSpanData *data = reinterpret_cast(userData); - - if (data->texture.format == QImage::Format_ARGB8565_Premultiplied) - blendTiled(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB16) - blendTiled(count, spans, userData); - else - blend_tiled_generic(count, spans, userData); -} - -static void blend_tiled_argb8555(int count, const QSpan *spans, void *userData) -{ - blend_tiled_generic(count, spans, userData); -} - -static void blend_tiled_rgb555(int count, const QSpan *spans, void *userData) -{ - blend_tiled_generic(count, spans, userData); -} - -static void blend_tiled_argb4444(int count, const QSpan *spans, void *userData) -{ - blend_tiled_generic(count, spans, userData); -} - -static void blend_tiled_rgb444(int count, const QSpan *spans, void *userData) -{ - blend_tiled_generic(count, spans, userData); -} - -template -Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan *spans, - void *userData) +static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); QPainter::CompositionMode mode = data->rasterBuffer->compositionMode; - - if (mode != QPainter::CompositionMode_SourceOver) { - blend_src_generic(count, spans, userData); + if (data->texture.format != QImage::Format_RGB16 + || (mode != QPainter::CompositionMode_SourceOver + && mode != QPainter::CompositionMode_Source)) + { + blend_src_generic(count, spans, userData); return; } - SRC buffer[buffer_size]; + quint16 buffer[buffer_size]; const int src_minx = data->texture.x1; const int src_miny = data->texture.y1; @@ -5289,13 +4360,14 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan while (count--) { const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8; - if (coverage == 0) { + const quint8 alpha = (coverage + 1) >> 3; + const quint8 ialpha = 0x20 - alpha; + if (alpha == 0) { ++spans; continue; } - DST *dest = (DST*)data->rasterBuffer->scanLine(spans->y) - + spans->x; + quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x; const qreal cx = spans->x + qreal(0.5); const qreal cy = spans->y + qreal(0.5); int x = int((data->m21 * cy @@ -5305,84 +4377,58 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan int length = spans->len; while (length) { - const int l = qMin(length, buffer_size); + int l; + quint16 *b; + if (ialpha == 0) { + l = length; + b = dest; + } else { + l = qMin(length, buffer_size); + b = buffer; + } + const quint16 *end = b + l; - const SRC *end = buffer + l; - SRC *b = buffer; while (b < end) { int x1 = (x >> 16); int x2; int y1 = (y >> 16); int y2; - const int distx = (x & 0x0000ffff) >> 8; - const int disty = (y & 0x0000ffff) >> 8; + fetchTransformedBilinear_pixelBounds(0, src_minx, src_maxx, x1, x2); + fetchTransformedBilinear_pixelBounds(0, src_miny, src_maxy, y1, y2); - if (x1 < src_minx) { - x2 = x1 = src_minx; - } else if (x1 >= src_maxx) { - x2 = x1 = src_maxx; - } else { - x2 = x1 + 1; - } - if (y1 < src_miny) { - y2 = y1 = src_miny; - } else if (y1 >= src_maxy) { - y2 = y1 = src_maxy; - } else { - y2 = y1 + 1; - } -#if 0 - if (x1 == x2) { - if (y1 == y2) { - *b = ((SRC*)data->texture.scanLine(y1))[x1]; - } else { - *b = ((SRC*)data->texture.scanLine(y1))[x1]; - const SRC t = data->texture.scanLine(y2)[x1]; - interpolate_pixel(*b, SRC::ialpha(disty), - t, SRC::alpha(disty)); - } - } else if (y1 == y2) { - *b = ((SRC*)data->texture.scanLine(y1))[x1]; - const SRC t = ((SRC*)data->texture.scanLine(y1))[x2]; - interpolate_pixel(*b, SRC::ialpha(distx), - t, SRC::alpha(distx)); - } else -#endif - { - const SRC *src1 = (SRC*)data->texture.scanLine(y1); - const SRC *src2 = (SRC*)data->texture.scanLine(y2); - SRC tl = src1[x1]; - const SRC tr = src1[x2]; - SRC bl = src2[x1]; - const SRC br = src2[x2]; - const quint8 ax = SRC::alpha(distx); - const quint8 iax = SRC::ialpha(distx); + const quint16 *src1 = (quint16*)data->texture.scanLine(y1); + const quint16 *src2 = (quint16*)data->texture.scanLine(y2); + quint16 tl = src1[x1]; + const quint16 tr = src1[x2]; + quint16 bl = src2[x1]; + const quint16 br = src2[x2]; + + const uint distxsl8 = x & 0xff00; + const uint distysl8 = y & 0xff00; + const uint distx = distxsl8 >> 8; + const uint disty = distysl8 >> 8; + const uint distxy = distx * disty; + + const uint tlw = 0x10000 - distxsl8 - distysl8 + distxy; // (256 - distx) * (256 - disty) + const uint trw = distxsl8 - distxy; // distx * (256 - disty) + const uint blw = distysl8 - distxy; // (256 - distx) * disty + const uint brw = distxy; // distx * disty + uint red = ((tl & 0xf800) * tlw + (tr & 0xf800) * trw + + (bl & 0xf800) * blw + (br & 0xf800) * brw) & 0xf8000000; + uint green = ((tl & 0x07e0) * tlw + (tr & 0x07e0) * trw + + (bl & 0x07e0) * blw + (br & 0x07e0) * brw) & 0x07e00000; + uint blue = ((tl & 0x001f) * tlw + (tr & 0x001f) * trw + + (bl & 0x001f) * blw + (br & 0x001f) * brw); + *b = quint16((red | green | blue) >> 16); - interpolate_pixel(tl, iax, tr, ax); - interpolate_pixel(bl, iax, br, ax); - interpolate_pixel(tl, SRC::ialpha(disty), - bl, SRC::alpha(disty)); - *b = tl; - } ++b; - x += fdx; y += fdy; } - if (!SRC::hasAlpha() && coverage == 255) { - qt_memconvert(dest, buffer, l); - } else if (sizeof(DST) == 3 && l >= 4 && - (quintptr(dest) & 3) == (quintptr(buffer) & 3)) - { - blendUntransformed_dest24(dest, buffer, coverage, l); - } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 && - (quintptr(dest) & 3) == (quintptr(buffer) & 3)) { - blendUntransformed_dest16(dest, buffer, coverage, l); - } else { - blendUntransformed_unaligned(dest, buffer, coverage, l); - } + if (ialpha != 0) + blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha); dest += l; length -= l; @@ -5396,13 +4442,14 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan while (count--) { const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8; - if (coverage == 0) { + const quint8 alpha = (coverage + 1) >> 3; + const quint8 ialpha = 0x20 - alpha; + if (alpha == 0) { ++spans; continue; } - DST *dest = (DST*)data->rasterBuffer->scanLine(spans->y) - + spans->x; + quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x; const qreal cx = spans->x + qreal(0.5); const qreal cy = spans->y + qreal(0.5); @@ -5413,9 +4460,17 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan int length = spans->len; while (length) { - const int l = qMin(length, buffer_size); - const SRC *end = buffer + l; - SRC *b = buffer; + int l; + quint16 *b; + if (ialpha == 0) { + l = length; + b = dest; + } else { + l = qMin(length, buffer_size); + b = buffer; + } + const quint16 *end = b + l; + while (b < end) { const qreal iw = w == 0 ? 1 : 1 / w; const qreal px = x * iw - qreal(0.5); @@ -5426,56 +4481,42 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan int y1 = int(py) - (py < 0); int y2; - const int distx = int((px - x1) * 256); - const int disty = int((py - y1) * 256); + fetchTransformedBilinear_pixelBounds(0, src_minx, src_maxx, x1, x2); + fetchTransformedBilinear_pixelBounds(0, src_miny, src_maxy, y1, y2); - if (x1 < src_minx) { - x2 = x1 = src_minx; - } else if (x1 >= src_maxx) { - x2 = x1 = src_maxx; - } else { - x2 = x1 + 1; - } - if (y1 < src_miny) { - y2 = y1 = src_miny; - } else if (y1 >= src_maxy) { - y2 = y1 = src_maxy; - } else { - y2 = y1 + 1; - } + const quint16 *src1 = (quint16 *)data->texture.scanLine(y1); + const quint16 *src2 = (quint16 *)data->texture.scanLine(y2); + quint16 tl = src1[x1]; + const quint16 tr = src1[x2]; + quint16 bl = src2[x1]; + const quint16 br = src2[x2]; - const SRC *src1 = (SRC*)data->texture.scanLine(y1); - const SRC *src2 = (SRC*)data->texture.scanLine(y2); - SRC tl = src1[x1]; - const SRC tr = src1[x2]; - SRC bl = src2[x1]; - const SRC br = src2[x2]; - const quint8 ax = SRC::alpha(distx); - const quint8 iax = SRC::ialpha(distx); + const uint distx = uint((px - x1) * 256); + const uint disty = uint((py - y1) * 256); + const uint distxsl8 = distx << 8; + const uint distysl8 = disty << 8; + const uint distxy = distx * disty; + + const uint tlw = 0x10000 - distxsl8 - distysl8 + distxy; // (256 - distx) * (256 - disty) + const uint trw = distxsl8 - distxy; // distx * (256 - disty) + const uint blw = distysl8 - distxy; // (256 - distx) * disty + const uint brw = distxy; // distx * disty + uint red = ((tl & 0xf800) * tlw + (tr & 0xf800) * trw + + (bl & 0xf800) * blw + (br & 0xf800) * brw) & 0xf8000000; + uint green = ((tl & 0x07e0) * tlw + (tr & 0x07e0) * trw + + (bl & 0x07e0) * blw + (br & 0x07e0) * brw) & 0x07e00000; + uint blue = ((tl & 0x001f) * tlw + (tr & 0x001f) * trw + + (bl & 0x001f) * blw + (br & 0x001f) * brw); + *b = quint16((red | green | blue) >> 16); - interpolate_pixel(tl, iax, tr, ax); - interpolate_pixel(bl, iax, br, ax); - interpolate_pixel(tl, SRC::ialpha(disty), - bl, SRC::alpha(disty)); - *b = tl; ++b; - x += fdx; y += fdy; w += fdw; } - if (!SRC::hasAlpha() && coverage == 255) { - qt_memconvert(dest, buffer, l); - } else if (sizeof(DST) == 3 && l >= 4 && - (quintptr(dest) & 3) == (quintptr(buffer) & 3)) - { - blendUntransformed_dest24(dest, buffer, coverage, l); - } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 && - (quintptr(dest) & 3) == (quintptr(buffer) & 3)) { - blendUntransformed_dest16(dest, buffer, coverage, l); - } else { - blendUntransformed_unaligned(dest, buffer, coverage, l); - } + + if (ialpha != 0) + blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha); dest += l; length -= l; @@ -5485,66 +4526,12 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan } } -static void blend_transformed_bilinear_rgb888(int count, const QSpan *spans, void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_bilinear_argb6666(int count, const QSpan *spans, void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_bilinear_rgb666(int count, const QSpan *spans, void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_bilinear_argb8565(int count, const QSpan *spans, void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans, - void *userData) -{ - QSpanData *data = reinterpret_cast(userData); - - if (data->texture.format == QImage::Format_RGB16) - blendTransformedBilinear(count, spans, userData); - else if (data->texture.format == QImage::Format_ARGB8565_Premultiplied) - blendTransformedBilinear(count, spans, userData); - else - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_bilinear_argb8555(int count, const QSpan *spans, void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_bilinear_rgb555(int count, const QSpan *spans, void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_bilinear_argb4444(int count, const QSpan *spans, void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_bilinear_rgb444(int count, const QSpan *spans, void *userData) -{ - blend_src_generic(count, spans, userData); -} - -template -Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *spans, void *userData) +static void blend_transformed_argb(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); if (data->texture.format != QImage::Format_ARGB32_Premultiplied && data->texture.format != QImage::Format_RGB32) { - blend_src_generic(count, spans, userData); + blend_src_generic(count, spans, userData); return; } @@ -5553,7 +4540,6 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *s int image_width = data->texture.width; int image_height = data->texture.height; - const int scanline_offset = data->texture.bytesPerLine / 4; if (data->fast_matrix) { // The increment pr x in the scanline @@ -5564,7 +4550,6 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *s void *t = data->rasterBuffer->scanLine(spans->y); uint *target = ((uint *)t) + spans->x; - uint *image_bits = (uint *)data->texture.imageData; const qreal cx = spans->x + qreal(0.5); const qreal cy = spans->y + qreal(0.5); @@ -5581,24 +4566,15 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *s const uint *end = buffer + l; uint *b = buffer; while (b < end) { - int px = x >> 16; - int py = y >> 16; + int px = qBound(0, x >> 16, image_width - 1); + int py = qBound(0, y >> 16, image_height - 1); + *b = reinterpret_cast(data->texture.scanLine(py))[px]; - bool out = (px < 0) || (px >= image_width) - || (py < 0) || (py >= image_height); - - int y_offset = py * scanline_offset; - *b = out ? uint(0) : image_bits[y_offset + px]; x += fdx; y += fdy; ++b; } - if (spanMethod == RegularSpans) - func(target, buffer, l, coverage); - else - drawBufferSpan(data, buffer, buffer_size, - spans->x + spans->len - length, - spans->y, l, coverage); + func(target, buffer, l, coverage); target += l; length -= l; } @@ -5612,7 +4588,6 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *s void *t = data->rasterBuffer->scanLine(spans->y); uint *target = ((uint *)t) + spans->x; - uint *image_bits = (uint *)data->texture.imageData; const qreal cx = spans->x + qreal(0.5); const qreal cy = spans->y + qreal(0.5); @@ -5631,26 +4606,17 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *s const qreal iw = w == 0 ? 1 : 1 / w; const qreal tx = x * iw; const qreal ty = y * iw; - const int px = int(tx) - (tx < 0); - const int py = int(ty) - (ty < 0); + const int px = qBound(0, int(tx) - (tx < 0), image_width - 1); + const int py = qBound(0, int(ty) - (ty < 0), image_height - 1); - bool out = (px < 0) || (px >= image_width) - || (py < 0) || (py >= image_height); - - int y_offset = py * scanline_offset; - *b = out ? uint(0) : image_bits[y_offset + px]; + *b = reinterpret_cast(data->texture.scanLine(py))[px]; x += fdx; y += fdy; w += fdw; ++b; } - if (spanMethod == RegularSpans) - func(target, buffer, l, coverage); - else - drawBufferSpan(data, buffer, buffer_size, - spans->x + spans->len - length, - spans->y, l, coverage); + func(target, buffer, l, coverage); target += l; length -= l; } @@ -5659,18 +4625,20 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *s } } -template -Q_STATIC_TEMPLATE_FUNCTION void blendTransformed(int count, const QSpan *spans, void *userData) +static void blend_transformed_rgb565(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); QPainter::CompositionMode mode = data->rasterBuffer->compositionMode; - if (mode != QPainter::CompositionMode_SourceOver) { - blend_src_generic(count, spans, userData); + if (data->texture.format != QImage::Format_RGB16 + || (mode != QPainter::CompositionMode_SourceOver + && mode != QPainter::CompositionMode_Source)) + { + blend_src_generic(count, spans, userData); return; } - SRC buffer[buffer_size]; + quint16 buffer[buffer_size]; const int image_width = data->texture.width; const int image_height = data->texture.height; @@ -5681,13 +4649,14 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformed(int count, const QSpan *spans, while (count--) { const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8; - if (coverage == 0) { + const quint8 alpha = (coverage + 1) >> 3; + const quint8 ialpha = 0x20 - alpha; + if (alpha == 0) { ++spans; continue; } - DST *dest = (DST*)data->rasterBuffer->scanLine(spans->y) - + spans->x; + quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x; const qreal cx = spans->x + qreal(0.5); const qreal cy = spans->y + qreal(0.5); int x = int((data->m21 * cy @@ -5697,39 +4666,30 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformed(int count, const QSpan *spans, int length = spans->len; while (length) { - const int l = qMin(length, buffer_size); + int l; + quint16 *b; + if (ialpha == 0) { + l = length; + b = dest; + } else { + l = qMin(length, buffer_size); + b = buffer; + } + const quint16 *end = b + l; - const SRC *end = buffer + l; - SRC *b = buffer; while (b < end) { - const int px = (x >> 16); - const int py = (y >> 16); + const int px = qBound(0, x >> 16, image_width - 1); + const int py = qBound(0, y >> 16, image_height - 1); - if ((px < 0) || (px >= image_width) || - (py < 0) || (py >= image_height)) - { - *b = 0; - } else { - *b = ((SRC*)data->texture.scanLine(py))[px]; - } + *b = ((quint16 *)data->texture.scanLine(py))[px]; ++b; x += fdx; y += fdy; } - if (!SRC::hasAlpha() && coverage == 255) { - qt_memconvert(dest, buffer, l); - } else if (sizeof(DST) == 3 && sizeof(SRC) == 3 && l >= 4 && - (quintptr(dest) & 3) == (quintptr(buffer) & 3)) - { - blendUntransformed_dest24(dest, buffer, coverage, l); - } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 && - (quintptr(dest) & 3) == (quintptr(buffer) & 3)) { - blendUntransformed_dest16(dest, buffer, coverage, l); - } else { - blendUntransformed_unaligned(dest, buffer, coverage, l); - } + if (ialpha != 0) + blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha); dest += l; length -= l; @@ -5743,13 +4703,14 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformed(int count, const QSpan *spans, while (count--) { const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8; - if (coverage == 0) { + const quint8 alpha = (coverage + 1) >> 3; + const quint8 ialpha = 0x20 - alpha; + if (alpha == 0) { ++spans; continue; } - DST *dest = (DST*)data->rasterBuffer->scanLine(spans->y) - + spans->x; + quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x; const qreal cx = spans->x + qreal(0.5); const qreal cy = spans->y + qreal(0.5); @@ -5760,42 +4721,35 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformed(int count, const QSpan *spans, int length = spans->len; while (length) { - const int l = qMin(length, buffer_size); - const SRC *end = buffer + l; - SRC *b = buffer; + int l; + quint16 *b; + if (ialpha == 0) { + l = length; + b = dest; + } else { + l = qMin(length, buffer_size); + b = buffer; + } + const quint16 *end = b + l; + while (b < end) { const qreal iw = w == 0 ? 1 : 1 / w; const qreal tx = x * iw; const qreal ty = y * iw; - const int px = int(tx) - (tx < 0); - const int py = int(ty) - (ty < 0); + const int px = qBound(0, int(tx) - (tx < 0), image_width - 1); + const int py = qBound(0, int(ty) - (ty < 0), image_height - 1); - if ((px < 0) || (px >= image_width) || - (py < 0) || (py >= image_height)) - { - *b = 0; - } else { - *b = ((SRC*)data->texture.scanLine(py))[px]; - } + *b = ((quint16 *)data->texture.scanLine(py))[px]; ++b; x += fdx; y += fdy; w += fdw; } - if (!SRC::hasAlpha() && coverage == 255) { - qt_memconvert(dest, buffer, l); - } else if (sizeof(DST) == 3 && sizeof(SRC) == 3 && l >= 4 && - (quintptr(dest) & 3) == (quintptr(buffer) & 3)) - { - blendUntransformed_dest24(dest, buffer, coverage, l); - } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 && - (quintptr(dest) & 3) == (quintptr(buffer) & 3)) { - blendUntransformed_dest16(dest, buffer, coverage, l); - } else { - blendUntransformed_unaligned(dest, buffer, coverage, l); - } + + if (ialpha != 0) + blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha); dest += l; length -= l; @@ -5805,74 +4759,12 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformed(int count, const QSpan *spans, } } -static void blend_transformed_rgb888(int count, const QSpan *spans, - void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_argb6666(int count, const QSpan *spans, - void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_rgb666(int count, const QSpan *spans, - void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_argb8565(int count, const QSpan *spans, - void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_rgb565(int count, const QSpan *spans, - void *userData) -{ - QSpanData *data = reinterpret_cast(userData); - - if (data->texture.format == QImage::Format_ARGB8565_Premultiplied) - blendTransformed(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB16) - blendTransformed(count, spans, userData); - else - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_argb8555(int count, const QSpan *spans, - void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_rgb555(int count, const QSpan *spans, - void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_argb4444(int count, const QSpan *spans, - void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_rgb444(int count, const QSpan *spans, - void *userData) -{ - blend_src_generic(count, spans, userData); -} - -template -Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_tiled_argb(int count, const QSpan *spans, void *userData) +void blend_transformed_tiled_argb(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); if (data->texture.format != QImage::Format_ARGB32_Premultiplied && data->texture.format != QImage::Format_RGB32) { - blend_src_generic(count, spans, userData); + blend_src_generic(count, spans, userData); return; } @@ -5925,12 +4817,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_tiled_argb(int count, const QS y += fdy; ++b; } - if (spanMethod == RegularSpans) - func(target, buffer, l, coverage); - else - drawBufferSpan(data, buffer, buffer_size, - spans->x + spans->len - length, - spans->y, l, coverage); + func(target, buffer, l, coverage); target += l; length -= l; } @@ -5985,12 +4872,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_tiled_argb(int count, const QS } ++b; } - if (spanMethod == RegularSpans) - func(target, buffer, l, coverage); - else - drawBufferSpan(data, buffer, buffer_size, - spans->x + spans->len - length, - spans->y, l, coverage); + func(target, buffer, l, coverage); target += l; length -= l; } @@ -5999,18 +4881,20 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_tiled_argb(int count, const QS } } -template -Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *spans, void *userData) +void blend_transformed_tiled_rgb565(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); QPainter::CompositionMode mode = data->rasterBuffer->compositionMode; - if (mode != QPainter::CompositionMode_SourceOver) { - blend_src_generic(count, spans, userData); + if (data->texture.format != QImage::Format_RGB16 + || (mode != QPainter::CompositionMode_SourceOver + && mode != QPainter::CompositionMode_Source)) + { + blend_src_generic(count, spans, userData); return; } - SRC buffer[buffer_size]; + quint16 buffer[buffer_size]; const int image_width = data->texture.width; const int image_height = data->texture.height; @@ -6021,13 +4905,14 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp while (count--) { const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8; - if (coverage == 0) { + const quint8 alpha = (coverage + 1) >> 3; + const quint8 ialpha = 0x20 - alpha; + if (alpha == 0) { ++spans; continue; } - DST *dest = (DST*)data->rasterBuffer->scanLine(spans->y) - + spans->x; + quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x; const qreal cx = spans->x + qreal(0.5); const qreal cy = spans->y + qreal(0.5); int x = int((data->m21 * cy @@ -6037,10 +4922,17 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp int length = spans->len; while (length) { - const int l = qMin(length, buffer_size); + int l; + quint16 *b; + if (ialpha == 0) { + l = length; + b = dest; + } else { + l = qMin(length, buffer_size); + b = buffer; + } + const quint16 *end = b + l; - const SRC *end = buffer + l; - SRC *b = buffer; while (b < end) { int px = (x >> 16) % image_width; int py = (y >> 16) % image_height; @@ -6050,25 +4942,15 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp if (py < 0) py += image_height; - *b = ((SRC*)data->texture.scanLine(py))[px]; + *b = ((quint16 *)data->texture.scanLine(py))[px]; ++b; x += fdx; y += fdy; } - if (!SRC::hasAlpha() && coverage == 255) { - qt_memconvert(dest, buffer, l); - } else if (sizeof(DST) == 3 && sizeof(SRC) == 3 && l >= 4 && - (quintptr(dest) & 3) == (quintptr(buffer) & 3)) - { - blendUntransformed_dest24(dest, buffer, coverage, l); - } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 && - (quintptr(dest) & 3) == (quintptr(buffer) & 3)) { - blendUntransformed_dest16(dest, buffer, coverage, l); - } else { - blendUntransformed_unaligned(dest, buffer, coverage, l); - } + if (ialpha != 0) + blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha); dest += l; length -= l; @@ -6082,13 +4964,14 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp while (count--) { const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8; - if (coverage == 0) { + const quint8 alpha = (coverage + 1) >> 3; + const quint8 ialpha = 0x20 - alpha; + if (alpha == 0) { ++spans; continue; } - DST *dest = (DST*)data->rasterBuffer->scanLine(spans->y) - + spans->x; + quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x; const qreal cx = spans->x + qreal(0.5); const qreal cy = spans->y + qreal(0.5); @@ -6099,9 +4982,17 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp int length = spans->len; while (length) { - const int l = qMin(length, buffer_size); - const SRC *end = buffer + l; - SRC *b = buffer; + int l; + quint16 *b; + if (ialpha == 0) { + l = length; + b = dest; + } else { + l = qMin(length, buffer_size); + b = buffer; + } + const quint16 *end = b + l; + while (b < end) { const qreal iw = w == 0 ? 1 : 1 / w; const qreal tx = x * iw; @@ -6117,7 +5008,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp if (py < 0) py += image_height; - *b = ((SRC*)data->texture.scanLine(py))[px]; + *b = ((quint16 *)data->texture.scanLine(py))[px]; ++b; x += fdx; @@ -6127,18 +5018,9 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp if (!w) w += fdw; } - if (!SRC::hasAlpha() && coverage == 255) { - qt_memconvert(dest, buffer, l); - } else if (sizeof(DST) == 3 && sizeof(SRC) == 3 && l >= 4 && - (quintptr(dest) & 3) == (quintptr(buffer) & 3)) - { - blendUntransformed_dest24(dest, buffer, coverage, l); - } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 && - (quintptr(dest) & 3) == (quintptr(buffer) & 3)) { - blendUntransformed_dest16(dest, buffer, coverage, l); - } else { - blendUntransformed_unaligned(dest, buffer, coverage, l); - } + + if (ialpha != 0) + blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha); dest += l; length -= l; @@ -6148,185 +5030,122 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp } } -static void blend_transformed_tiled_rgb888(int count, const QSpan *spans, - void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_tiled_argb6666(int count, const QSpan *spans, - void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_tiled_rgb666(int count, const QSpan *spans, - void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_tiled_argb8565(int count, const QSpan *spans, - void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_tiled_rgb565(int count, const QSpan *spans, - void *userData) -{ - QSpanData *data = reinterpret_cast(userData); - - if (data->texture.format == QImage::Format_ARGB8565_Premultiplied) - blendTransformedTiled(count, spans, userData); - else if (data->texture.format == QImage::Format_RGB16) - blendTransformedTiled(count, spans, userData); - else - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_tiled_argb8555(int count, const QSpan *spans, - void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_tiled_rgb555(int count, const QSpan *spans, - void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_tiled_argb4444(int count, const QSpan *spans, - void *userData) -{ - blend_src_generic(count, spans, userData); -} - -static void blend_transformed_tiled_rgb444(int count, const QSpan *spans, - void *userData) -{ - blend_src_generic(count, spans, userData); -} - -# define SPANFUNC_POINTER(Name, Arg) Name - /* Image formats here are target formats */ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats] = { // Untransformed { 0, // Invalid - SPANFUNC_POINTER(blend_untransformed_generic, RegularSpans), // Mono - SPANFUNC_POINTER(blend_untransformed_generic, RegularSpans), // MonoLsb - SPANFUNC_POINTER(blend_untransformed_generic, RegularSpans), // Indexed8 - SPANFUNC_POINTER(blend_untransformed_generic, RegularSpans), // RGB32 - SPANFUNC_POINTER(blend_untransformed_generic, RegularSpans), // ARGB32 - SPANFUNC_POINTER(blend_untransformed_argb, RegularSpans), // ARGB32_Premultiplied + blend_untransformed_generic, // Mono + blend_untransformed_generic, // MonoLsb + blend_untransformed_generic, // Indexed8 + blend_untransformed_generic, // RGB32 + blend_untransformed_generic, // ARGB32 + blend_untransformed_argb, // ARGB32_Premultiplied blend_untransformed_rgb565, - blend_untransformed_argb8565, - blend_untransformed_rgb666, - blend_untransformed_argb6666, - blend_untransformed_rgb555, - blend_untransformed_argb8555, - blend_untransformed_rgb888, - blend_untransformed_rgb444, - blend_untransformed_argb4444, + blend_untransformed_generic, + blend_untransformed_generic, + blend_untransformed_generic, + blend_untransformed_generic, + blend_untransformed_generic, + blend_untransformed_generic, + blend_untransformed_generic, + blend_untransformed_generic, }, // Tiled { 0, // Invalid - SPANFUNC_POINTER(blend_tiled_generic, RegularSpans), // Mono - SPANFUNC_POINTER(blend_tiled_generic, RegularSpans), // MonoLsb - SPANFUNC_POINTER(blend_tiled_generic, RegularSpans), // Indexed8 - SPANFUNC_POINTER(blend_tiled_generic, RegularSpans), // RGB32 - SPANFUNC_POINTER(blend_tiled_generic, RegularSpans), // ARGB32 - SPANFUNC_POINTER(blend_tiled_argb, RegularSpans), // ARGB32_Premultiplied + blend_tiled_generic, // Mono + blend_tiled_generic, // MonoLsb + blend_tiled_generic, // Indexed8 + blend_tiled_generic, // RGB32 + blend_tiled_generic, // ARGB32 + blend_tiled_argb, // ARGB32_Premultiplied blend_tiled_rgb565, - blend_tiled_argb8565, - blend_tiled_rgb666, - blend_tiled_argb6666, - blend_tiled_rgb555, - blend_tiled_argb8555, - blend_tiled_rgb888, - blend_tiled_rgb444, - blend_tiled_argb4444, + blend_tiled_generic, + blend_tiled_generic, + blend_tiled_generic, + blend_tiled_generic, + blend_tiled_generic, + blend_tiled_generic, + blend_tiled_generic, + blend_tiled_generic, }, // Transformed { 0, // Invalid - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Mono - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // MonoLsb - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Indexed8 - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32 - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32 - SPANFUNC_POINTER(blend_transformed_argb, RegularSpans), // ARGB32_Premultiplied + blend_src_generic, // Mono + blend_src_generic, // MonoLsb + blend_src_generic, // Indexed8 + blend_src_generic, // RGB32 + blend_src_generic, // ARGB32 + blend_transformed_argb, // ARGB32_Premultiplied blend_transformed_rgb565, - blend_transformed_argb8565, - blend_transformed_rgb666, - blend_transformed_argb6666, - blend_transformed_rgb555, - blend_transformed_argb8555, - blend_transformed_rgb888, - blend_transformed_rgb444, - blend_transformed_argb4444, + blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic, }, // TransformedTiled { 0, - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Mono - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // MonoLsb - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Indexed8 - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32 - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32 - SPANFUNC_POINTER(blend_transformed_tiled_argb, RegularSpans), // ARGB32_Premultiplied + blend_src_generic, // Mono + blend_src_generic, // MonoLsb + blend_src_generic, // Indexed8 + blend_src_generic, // RGB32 + blend_src_generic, // ARGB32 + blend_transformed_tiled_argb, // ARGB32_Premultiplied blend_transformed_tiled_rgb565, - blend_transformed_tiled_argb8565, - blend_transformed_tiled_rgb666, - blend_transformed_tiled_argb6666, - blend_transformed_tiled_rgb555, - blend_transformed_tiled_argb8555, - blend_transformed_tiled_rgb888, - blend_transformed_tiled_rgb444, - blend_transformed_tiled_argb4444 + blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic }, // Bilinear { 0, - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Mono - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // MonoLsb - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Indexed8 - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32 - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32 - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32_Premultiplied + blend_src_generic, // Mono + blend_src_generic, // MonoLsb + blend_src_generic, // Indexed8 + blend_src_generic, // RGB32 + blend_src_generic, // ARGB32 + blend_src_generic, // ARGB32_Premultiplied blend_transformed_bilinear_rgb565, - blend_transformed_bilinear_argb8565, - blend_transformed_bilinear_rgb666, - blend_transformed_bilinear_argb6666, - blend_transformed_bilinear_rgb555, - blend_transformed_bilinear_argb8555, - blend_transformed_bilinear_rgb888, - blend_transformed_bilinear_rgb444, - blend_transformed_bilinear_argb4444, + blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic, }, // BilinearTiled { 0, - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Mono - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // MonoLsb - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Indexed8 - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32 - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32 - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32_Premultiplied - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB16 - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB8565_Premultiplied - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB666 - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB6666_Premultiplied - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB555 - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB8555_Premultiplied - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB888 - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB444 - SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB4444_Premultiplied + blend_src_generic, // Mono + blend_src_generic, // MonoLsb + blend_src_generic, // Indexed8 + blend_src_generic, // RGB32 + blend_src_generic, // ARGB32 + blend_src_generic, // ARGB32_Premultiplied + blend_src_generic, // RGB16 + blend_src_generic, // ARGB8565_Premultiplied + blend_src_generic, // RGB666 + blend_src_generic, // ARGB6666_Premultiplied + blend_src_generic, // RGB555 + blend_src_generic, // ARGB8555_Premultiplied + blend_src_generic, // RGB888 + blend_src_generic, // RGB444 + blend_src_generic, // ARGB4444_Premultiplied } }; @@ -6339,14 +5158,11 @@ void qBlendTexture(int count, const QSpan *spans, void *userData) template inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer, - int x, int y, quint32 color, + int x, int y, DST color, const uchar *map, - int mapWidth, int mapHeight, int mapStride, - DST dummy = 0) + int mapWidth, int mapHeight, int mapStride) { - Q_UNUSED(dummy); - const DST c = qt_colorConvert(color, 0); - DST *dest = reinterpret_cast(rasterBuffer->scanLine(y)) + x; + DST *dest = reinterpret_cast(rasterBuffer->scanLine(y)) + x; const int destStride = rasterBuffer->bytesPerLine() / sizeof(DST); if (mapWidth > 8) { @@ -6360,7 +5176,7 @@ inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer, ++n; } else { if (n) { - qt_memfill(dest + x0, c, n); + qt_memfill(dest + x0, color, n); x0 += n + 1; n = 0; } else { @@ -6375,7 +5191,7 @@ inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer, } } if (n) - qt_memfill(dest + x0, c, n); + qt_memfill(dest + x0, color, n); dest += destStride; map += mapStride; } @@ -6387,7 +5203,7 @@ inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer, if (s & 0x80) { ++n; } else if (n) { - qt_memfill(dest + x0, c, n); + qt_memfill(dest + x0, color, n); x0 += n + 1; n = 0; } else { @@ -6395,7 +5211,7 @@ inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer, } } if (n) - qt_memfill(dest + x0, c, n); + qt_memfill(dest + x0, color, n); dest += destStride; map += mapStride; } @@ -6448,7 +5264,7 @@ static void qt_gradient_quint32(int count, const QSpan *spans, void *userData) } } else { - blend_src_generic(count, spans, userData); + blend_src_generic(count, spans, userData); } } @@ -6496,7 +5312,7 @@ static void qt_gradient_quint16(int count, const QSpan *spans, void *userData) data->solid.color = oldColor; } else { - blend_src_generic(count, spans, userData); + blend_src_generic(count, spans, userData); } } @@ -6514,7 +5330,7 @@ inline static void qt_bitmapblit_quint16(QRasterBuffer *rasterBuffer, const uchar *map, int mapWidth, int mapHeight, int mapStride) { - qt_bitmapblit_template(rasterBuffer, x, y, color, + qt_bitmapblit_template(rasterBuffer, x, y, qConvertRgb32To16(color), map, mapWidth, mapHeight, mapStride); } @@ -6572,7 +5388,7 @@ static void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer, int mapWidth, int mapHeight, int mapStride, const QClipData *) { - const quint16 c = qt_colorConvert(color, 0); + const quint16 c = qConvertRgb32To16(color); quint16 *dest = reinterpret_cast(rasterBuffer->scanLine(y)) + x; const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint16); @@ -6838,41 +5654,25 @@ static void qt_alphargbblit_quint32(QRasterBuffer *rasterBuffer, } } -template -inline void qt_rectfill_template(QRasterBuffer *rasterBuffer, - int x, int y, int width, int height, - quint32 color, T dummy = 0) +static void qt_rectfill_quint32(QRasterBuffer *rasterBuffer, + int x, int y, int width, int height, + quint32 color) { - Q_UNUSED(dummy); - - qt_rectfill(reinterpret_cast(rasterBuffer->buffer()), - qt_colorConvert(quint32p::fromRawData(color), 0), - x, y, width, height, rasterBuffer->bytesPerLine()); + qt_rectfill(reinterpret_cast(rasterBuffer->buffer()), + color, x, y, width, height, rasterBuffer->bytesPerLine()); } -#define QT_RECTFILL(T) \ - inline static void qt_rectfill_##T(QRasterBuffer *rasterBuffer, \ - int x, int y, int width, int height, \ - quint32 color) \ - { \ - qt_rectfill_template(rasterBuffer, x, y, width, height, color); \ - } +static void qt_rectfill_quint16(QRasterBuffer *rasterBuffer, + int x, int y, int width, int height, + quint32 color) +{ + qt_rectfill(reinterpret_cast(rasterBuffer->buffer()), + qConvertRgb32To16(color), x, y, width, height, rasterBuffer->bytesPerLine()); +} -QT_RECTFILL(quint32) -QT_RECTFILL(quint16) -QT_RECTFILL(qargb8565) -QT_RECTFILL(qrgb666) -QT_RECTFILL(qargb6666) -QT_RECTFILL(qrgb555) -QT_RECTFILL(qargb8555) -QT_RECTFILL(qrgb888) -QT_RECTFILL(qrgb444) -QT_RECTFILL(qargb4444) -#undef QT_RECTFILL - -inline static void qt_rectfill_nonpremul_quint32(QRasterBuffer *rasterBuffer, - int x, int y, int width, int height, - quint32 color) +static void qt_rectfill_nonpremul_quint32(QRasterBuffer *rasterBuffer, + int x, int y, int width, int height, + quint32 color) { qt_rectfill(reinterpret_cast(rasterBuffer->buffer()), INV_PREMUL(color), x, y, width, height, rasterBuffer->bytesPerLine()); @@ -6889,19 +5689,19 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_Mono, { blend_color_generic, - SPANFUNC_POINTER(blend_src_generic, RegularSpans), + blend_src_generic, 0, 0, 0, 0 }, // Format_MonoLSB, { blend_color_generic, - SPANFUNC_POINTER(blend_src_generic, RegularSpans), + blend_src_generic, 0, 0, 0, 0 }, // Format_Indexed8, { blend_color_generic, - SPANFUNC_POINTER(blend_src_generic, RegularSpans), + blend_src_generic, 0, 0, 0, 0 }, // Format_RGB32, @@ -6942,88 +5742,78 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = }, // Format_ARGB8565_Premultiplied { - SPANFUNC_POINTER_BLENDCOLOR(qargb8565), - SPANFUNC_POINTER(blend_src_generic, RegularSpans), - 0, 0, 0, - qt_rectfill_qargb8565 + blend_color_generic, + blend_src_generic, + 0, 0, 0, 0 }, // Format_RGB666 { - SPANFUNC_POINTER_BLENDCOLOR(qrgb666), - SPANFUNC_POINTER(blend_src_generic, RegularSpans), - 0, 0, 0, - qt_rectfill_qrgb666 + blend_color_generic, + blend_src_generic, + 0, 0, 0, 0 }, // Format_ARGB6666_Premultiplied { - SPANFUNC_POINTER_BLENDCOLOR(qargb6666), - SPANFUNC_POINTER(blend_src_generic, RegularSpans), - 0, 0, 0, - qt_rectfill_qargb6666 + blend_color_generic, + blend_src_generic, + 0, 0, 0, 0 }, // Format_RGB555 { - SPANFUNC_POINTER_BLENDCOLOR(qrgb555), - SPANFUNC_POINTER(blend_src_generic, RegularSpans), - 0, 0, 0, - qt_rectfill_qrgb555 + blend_color_generic, + blend_src_generic, + 0, 0, 0, 0 }, // Format_ARGB8555_Premultiplied { - SPANFUNC_POINTER_BLENDCOLOR(qargb8555), - SPANFUNC_POINTER(blend_src_generic, RegularSpans), - 0, 0, 0, - qt_rectfill_qargb8555 + blend_color_generic, + blend_src_generic, + 0, 0, 0, 0 }, // Format_RGB888 { - SPANFUNC_POINTER_BLENDCOLOR(qrgb888), - SPANFUNC_POINTER(blend_src_generic, RegularSpans), - 0, 0, 0, - qt_rectfill_qrgb888 + blend_color_generic, + blend_src_generic, + 0, 0, 0, 0 }, // Format_RGB444 { - SPANFUNC_POINTER_BLENDCOLOR(qrgb444), - SPANFUNC_POINTER(blend_src_generic, RegularSpans), - 0, 0, 0, - qt_rectfill_qrgb444 + blend_color_generic, + blend_src_generic, + 0, 0, 0, 0 }, // Format_ARGB4444_Premultiplied { - SPANFUNC_POINTER_BLENDCOLOR(qargb4444), - SPANFUNC_POINTER(blend_src_generic, RegularSpans), - 0, 0, 0, - qt_rectfill_qargb4444 + blend_color_generic, + blend_src_generic, + 0, 0, 0, 0 } }; #if defined(Q_CC_MSVC) && !defined(_MIPS_) -template -inline void qt_memfill_template(DST *dest, SRC color, int count) +template +inline void qt_memfill_template(T *dest, T color, int count) { - const DST c = qt_colorConvert(color, 0); while (count--) - *dest++ = c; + *dest++ = color; } #else -template -inline void qt_memfill_template(DST *dest, SRC color, int count) +template +inline void qt_memfill_template(T *dest, T color, int count) { - const DST c = qt_colorConvert(color, 0); int n = (count + 7) / 8; switch (count & 0x07) { - case 0: do { *dest++ = c; - case 7: *dest++ = c; - case 6: *dest++ = c; - case 5: *dest++ = c; - case 4: *dest++ = c; - case 3: *dest++ = c; - case 2: *dest++ = c; - case 1: *dest++ = c; + case 0: do { *dest++ = color; + case 7: *dest++ = color; + case 6: *dest++ = color; + case 5: *dest++ = color; + case 4: *dest++ = color; + case 3: *dest++ = color; + case 2: *dest++ = color; + case 1: *dest++ = color; } while (--n > 0); } } @@ -7053,7 +5843,7 @@ inline void qt_memfill_template(quint16 *dest, quint16 value, int count) static void qt_memfill_quint16(quint16 *dest, quint16 color, int count) { - qt_memfill_template(dest, color, count); + qt_memfill_template(dest, color, count); } typedef void (*qt_memfill32_func)(quint32 *dest, quint32 value, int count); @@ -7067,8 +5857,8 @@ qt_memfill16_func qt_memfill16 = qt_memfill16_setup; void qInitDrawhelperAsm() { - qt_memfill32 = qt_memfill_template; - qt_memfill16 = qt_memfill_quint16; //qt_memfill_template; + qt_memfill32 = qt_memfill_template; + qt_memfill16 = qt_memfill_quint16; //qt_memfill_template; CompositionFunction *functionForModeAsm = 0; CompositionFunctionSolid *functionForModeSolidAsm = 0; diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index c3dd4fb1ef5..895b44dc17a 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -198,7 +198,7 @@ void qt_blend_rgb16_on_argb32_neon(uchar *destPixels, int dbpl, while (h--) { for (int x=0; x -inline DST qt_colorConvert(SRC color, DST dummy) -{ - Q_UNUSED(dummy); - return DST(color); -} - - -template <> -inline quint32 qt_colorConvert(quint16 color, quint32 dummy) -{ - Q_UNUSED(dummy); - const int r = (color & 0xf800); - const int g = (color & 0x07e0); - const int b = (color & 0x001f); - const int tr = (r >> 8) | (r >> 13); - const int tg = (g >> 3) | (g >> 9); - const int tb = (b << 3) | (b >> 2); - - return qRgb(tr, tg, tb); -} - -template <> -inline quint16 qt_colorConvert(quint32 color, quint16 dummy) -{ - Q_UNUSED(dummy); - const int r = qRed(color) << 8; - const int g = qGreen(color) << 3; - const int b = qBlue(color) >> 3; - - return (r & 0xf800) | (g & 0x07e0)| (b & 0x001f); -} - -class quint32p -{ -public: - inline quint32p(quint32 v) : data(PREMUL(v)) {} - - inline operator quint32() const { return data; } - - inline operator quint16() const - { - return qt_colorConvert(data, 0); - } - - Q_STATIC_INLINE_FUNCTION quint32p fromRawData(quint32 v) - { - quint32p p; - p.data = v; - return p; - } - -private: - quint32p() {} - quint32 data; -} Q_PACKED; - -class qabgr8888 -{ -public: - inline qabgr8888(quint32 v) - { - data = qRgba(qBlue(v), qGreen(v), qRed(v), qAlpha(v)); - } - - inline bool operator==(const qabgr8888 &v) const { return data == v.data; } - -private: - quint32 data; -} Q_PACKED; - -class qrgb565; - -class qargb8565 -{ -public: - Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return true; } - - inline qargb8565() {} - inline qargb8565(quint32 v); - inline explicit qargb8565(quint32p v); - inline qargb8565(const qargb8565 &v); - inline qargb8565(const qrgb565 &v); - - inline operator quint32() const; - inline operator quint16() const; - - inline quint8 alpha() const { return data[0]; } - inline qargb8565 truncedAlpha() { - data[0] &= 0xf8; - data[1] &= 0xdf; - return *this; - } - Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 3; } - Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x20 - alpha(a); } - - inline qargb8565 byte_mul(quint8 a) const; - inline qargb8565 operator+(qargb8565 v) const; - inline bool operator==(const qargb8565 &v) const; - - inline quint32 rawValue() const; - inline quint16 rawValue16() const; - -private: - friend class qrgb565; - - quint8 data[3]; -} Q_PACKED; - -class qrgb565 -{ -public: - Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return false; } - - qrgb565(int v = 0) : data(v) {} - - inline explicit qrgb565(quint32p v); - inline explicit qrgb565(quint32 v); - inline explicit qrgb565(const qargb8565 &v); - - inline operator quint32() const; - inline operator quint16() const; - - inline qrgb565 operator+(qrgb565 v) const; - - inline quint8 alpha() const { return 0xff; } - inline qrgb565 truncedAlpha() { return *this; } - Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 3; } - Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x20 - alpha(a); } - - inline qrgb565 byte_mul(quint8 a) const; - - inline bool operator==(const qrgb565 &v) const; - inline quint16 rawValue() const { return data; } - -private: - friend class qargb8565; - - quint16 data; -} Q_PACKED; - -qargb8565::qargb8565(quint32 v) -{ - *this = qargb8565(quint32p(v)); -} - -qargb8565::qargb8565(quint32p v) -{ - data[0] = qAlpha(v); - const int r = qRed(v); - const int g = qGreen(v); - const int b = qBlue(v); - data[1] = ((g << 3) & 0xe0) | (b >> 3); - data[2] = (r & 0xf8) | (g >> 5); -} - -qargb8565::qargb8565(const qargb8565 &v) -{ - data[0] = v.data[0]; - data[1] = v.data[1]; - data[2] = v.data[2]; -} - -qargb8565::qargb8565(const qrgb565 &v) -{ - data[0] = 0xff; - data[1] = v.data & 0xff; - data[2] = v.data >> 8; -} - -qargb8565::operator quint32() const -{ - const quint16 rgb = (data[2] << 8) | data[1]; - const int a = data[0]; - const int r = (rgb & 0xf800); - const int g = (rgb & 0x07e0); - const int b = (rgb & 0x001f); - const int tr = qMin(a, (r >> 8) | (r >> 13)); - const int tg = qMin(a, (g >> 3) | (g >> 9)); - const int tb = qMin(a, (b << 3) | (b >> 2)); - return qRgba(tr, tg, tb, data[0]); -} - -qargb8565::operator quint16() const -{ - return (data[2] << 8) | data[1]; -} - -qargb8565 qargb8565::operator+(qargb8565 v) const -{ - qargb8565 t; - t.data[0] = data[0] + v.data[0]; - const quint16 rgb = ((data[2] + v.data[2]) << 8) - + (data[1] + v.data[1]); - t.data[1] = rgb & 0xff; - t.data[2] = rgb >> 8; - return t; -} - -qargb8565 qargb8565::byte_mul(quint8 a) const -{ - qargb8565 result; - result.data[0] = (data[0] * a) >> 5; - - const quint16 x = (data[2] << 8) | data[1]; - const quint16 t = ((((x & 0x07e0) >> 5) * a) & 0x07e0) | - ((((x & 0xf81f) * a) >> 5) & 0xf81f); - result.data[1] = t & 0xff; - result.data[2] = t >> 8; - return result; -} - -bool qargb8565::operator==(const qargb8565 &v) const -{ - return data[0] == v.data[0] - && data[1] == v.data[1] - && data[2] == v.data[2]; -} - -quint32 qargb8565::rawValue() const -{ - return (data[2] << 16) | (data[1] << 8) | data[0]; -} - -quint16 qargb8565::rawValue16() const -{ - return (data[2] << 8) | data[1]; -} - -qrgb565::qrgb565(quint32p v) -{ - *this = qrgb565(quint32(v)); -} - -qrgb565::qrgb565(quint32 v) -{ - const int r = qRed(v) << 8; - const int g = qGreen(v) << 3; - const int b = qBlue(v) >> 3; - - data = (r & 0xf800) | (g & 0x07e0)| (b & 0x001f); -} - -qrgb565::qrgb565(const qargb8565 &v) -{ - data = (v.data[2] << 8) | v.data[1]; -} - -qrgb565::operator quint32() const -{ - const int r = (data & 0xf800); - const int g = (data & 0x07e0); - const int b = (data & 0x001f); - const int tr = (r >> 8) | (r >> 13); - const int tg = (g >> 3) | (g >> 9); - const int tb = (b << 3) | (b >> 2); - return qRgb(tr, tg, tb); -} - -qrgb565::operator quint16() const -{ - return data; -} - -qrgb565 qrgb565::operator+(qrgb565 v) const -{ - qrgb565 t; - t.data = data + v.data; - return t; -} - -qrgb565 qrgb565::byte_mul(quint8 a) const -{ - qrgb565 result; - result.data = ((((data & 0x07e0) >> 5) * a) & 0x07e0) | - ((((data & 0xf81f) * a) >> 5) & 0xf81f); - return result; -} - -bool qrgb565::operator==(const qrgb565 &v) const -{ - return data == v.data; -} - -class qbgr565 -{ -public: - inline qbgr565(quint16 v) - { - data = ((v & 0x001f) << 11) | - (v & 0x07e0) | - ((v & 0xf800) >> 11); - } - - inline bool operator==(const qbgr565 &v) const - { - return data == v.data; - } - -private: - quint16 data; -} Q_PACKED; - -class qrgb555; - -class qargb8555 -{ -public: - Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return true; } - - qargb8555() {} - inline qargb8555(quint32 v); - inline explicit qargb8555(quint32p v); - inline qargb8555(const qargb8555 &v); - inline qargb8555(const qrgb555 &v); - - inline operator quint32() const; - - inline quint8 alpha() const { return data[0]; } - inline qargb8555 truncedAlpha() { data[0] &= 0xf8; return *this; } - Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 3; } - Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x20 - alpha(a); } - - inline qargb8555 operator+(qargb8555 v) const; - inline qargb8555 byte_mul(quint8 a) const; - - inline bool operator==(const qargb8555 &v) const; - - inline quint32 rawValue() const; - -private: - friend class qrgb555; - quint8 data[3]; -} Q_PACKED; - -class qrgb555 -{ -public: - Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return false; } - - inline qrgb555(int v = 0) : data(v) {} - - inline explicit qrgb555(quint32p v) { *this = qrgb555(quint32(v)); } - - inline explicit qrgb555(quint32 v) - { - const int r = qRed(v) << 7; - const int g = qGreen(v) << 2; - const int b = qBlue(v) >> 3; - - data = (r & 0x7c00) | (g & 0x03e0) | (b & 0x001f); - } - - inline explicit qrgb555(quint16 v) - { - data = ((v >> 1) & (0x7c00 | 0x03e0)) | - (v & 0x001f); - } - - inline explicit qrgb555(const qargb8555 &v); - - inline operator quint32() const - { - const int r = (data & 0x7c00); - const int g = (data & 0x03e0); - const int b = (data & 0x001f); - const int tr = (r >> 7) | (r >> 12); - const int tg = (g >> 2) | (g >> 7); - const int tb = (b << 3) | (b >> 2); - - return qRgb(tr, tg, tb); - } - - inline operator quint16() const - { - const int r = ((data & 0x7c00) << 1) & 0xf800; - const int g = (((data & 0x03e0) << 1) | ((data >> 4) & 0x0020)) & 0x07e0; - const int b = (data & 0x001f); - - return r | g | b; - } - - inline qrgb555 operator+(qrgb555 v) const; - inline qrgb555 byte_mul(quint8 a) const; - - inline quint8 alpha() const { return 0xff; } - inline qrgb555 truncedAlpha() { return *this; } - Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 3; } - Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x20 - alpha(a); } - - inline bool operator==(const qrgb555 &v) const { return v.data == data; } - inline bool operator!=(const qrgb555 &v) const { return v.data != data; } - - inline quint16 rawValue() const { return data; } - -private: - friend class qargb8555; - friend class qbgr555; - quint16 data; - -} Q_PACKED; - -qrgb555::qrgb555(const qargb8555 &v) -{ - data = (v.data[2] << 8) | v.data[1]; -} - -qrgb555 qrgb555::operator+(qrgb555 v) const -{ - qrgb555 t; - t.data = data + v.data; - return t; -} - -qrgb555 qrgb555::byte_mul(quint8 a) const -{ - quint16 t = (((data & 0x3e0) * a) >> 5) & 0x03e0; - t |= (((data & 0x7c1f) * a) >> 5) & 0x7c1f; - - qrgb555 result; - result.data = t; - return result; -} - -class qbgr555 -{ -public: - inline qbgr555(quint32 v) { *this = qbgr555(qrgb555(v)); } - - inline qbgr555(qrgb555 v) - { - data = ((v.data & 0x001f) << 10) | - (v.data & 0x03e0) | - ((v.data & 0x7c00) >> 10); - } - - inline bool operator==(const qbgr555 &v) const - { - return data == v.data; - } - -private: - quint16 data; -} Q_PACKED; - -qargb8555::qargb8555(quint32 v) -{ - v = quint32p(v); - data[0] = qAlpha(v); - const int r = qRed(v); - const int g = qGreen(v); - const int b = qBlue(v); - data[1] = ((g << 2) & 0xe0) | (b >> 3); - data[2] = ((r >> 1) & 0x7c) | (g >> 6); - -} - -qargb8555::qargb8555(quint32p v) -{ - data[0] = qAlpha(v); - const int r = qRed(v); - const int g = qGreen(v); - const int b = qBlue(v); - data[1] = ((g << 2) & 0xe0) | (b >> 3); - data[2] = ((r >> 1) & 0x7c) | (g >> 6); -} - -qargb8555::qargb8555(const qargb8555 &v) -{ - data[0] = v.data[0]; - data[1] = v.data[1]; - data[2] = v.data[2]; -} - -qargb8555::qargb8555(const qrgb555 &v) -{ - data[0] = 0xff; - data[1] = v.data & 0xff; - data[2] = v.data >> 8; -} - -qargb8555::operator quint32() const -{ - const quint16 rgb = (data[2] << 8) | data[1]; - const int r = (rgb & 0x7c00); - const int g = (rgb & 0x03e0); - const int b = (rgb & 0x001f); - const int tr = (r >> 7) | (r >> 12); - const int tg = (g >> 2) | (g >> 7); - const int tb = (b << 3) | (b >> 2); - - return qRgba(tr, tg, tb, data[0]); -} - -bool qargb8555::operator==(const qargb8555 &v) const -{ - return data[0] == v.data[0] - && data[1] == v.data[1] - && data[2] == v.data[2]; -} - -quint32 qargb8555::rawValue() const -{ - return (data[2] << 16) | (data[1] << 8) | data[0]; -} - -qargb8555 qargb8555::operator+(qargb8555 v) const -{ - qargb8555 t; - t.data[0] = data[0] + v.data[0]; - const quint16 rgb = ((data[2] + v.data[2]) << 8) - + (data[1] + v.data[1]); - t.data[1] = rgb & 0xff; - t.data[2] = rgb >> 8; - return t; -} - -qargb8555 qargb8555::byte_mul(quint8 a) const -{ - qargb8555 result; - result.data[0] = (data[0] * a) >> 5; - - const quint16 x = (data[2] << 8) | data[1]; - quint16 t = (((x & 0x3e0) * a) >> 5) & 0x03e0; - t |= (((x & 0x7c1f) * a) >> 5) & 0x7c1f; - result.data[1] = t & 0xff; - result.data[2] = t >> 8; - return result; - -} - -class qrgb666; - -class qargb6666 -{ -public: - Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return true; } - - inline qargb6666() {} - inline qargb6666(quint32 v) { *this = qargb6666(quint32p(v)); } - inline explicit qargb6666(quint32p v); - inline qargb6666(const qargb6666 &v); - inline qargb6666(const qrgb666 &v); - - inline operator quint32 () const; - - inline quint8 alpha() const; - inline qargb6666 truncedAlpha() { return *this; } - Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 2; } - Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return (255 - a + 1) >> 2; } - - inline qargb6666 byte_mul(quint8 a) const; - inline qargb6666 operator+(qargb6666 v) const; - inline bool operator==(const qargb6666 &v) const; - - inline quint32 rawValue() const; - -private: - friend class qrgb666; - quint8 data[3]; - -} Q_PACKED; - -class qrgb666 -{ -public: - Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return false; } - - inline qrgb666() {} - inline qrgb666(quint32 v); - inline qrgb666(const qargb6666 &v); - - inline operator quint32 () const; - - inline quint8 alpha() const { return 0xff; } - inline qrgb666 truncedAlpha() { return *this; } - Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 2; } - Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return (255 - a + 1) >> 2; } - - inline qrgb666 operator+(qrgb666 v) const; - inline qrgb666 byte_mul(quint8 a) const; - - inline bool operator==(const qrgb666 &v) const; - inline bool operator!=(const qrgb666 &v) const { return !(*this == v); } - - inline quint32 rawValue() const - { - return (data[2] << 16) | (data[1] << 8) | data[0]; - } - -private: - friend class qargb6666; - - quint8 data[3]; -} Q_PACKED; - -qrgb666::qrgb666(quint32 v) -{ - const uchar b = qBlue(v); - const uchar g = qGreen(v); - const uchar r = qRed(v); - const uint p = (b >> 2) | ((g >> 2) << 6) | ((r >> 2) << 12); - data[0] = qBlue(p); - data[1] = qGreen(p); - data[2] = qRed(p); -} - -qrgb666::qrgb666(const qargb6666 &v) -{ - data[0] = v.data[0]; - data[1] = v.data[1]; - data[2] = v.data[2] & 0x03; -} - -qrgb666::operator quint32 () const -{ - const uchar r = (data[2] << 6) | ((data[1] & 0xf0) >> 2) | (data[2] & 0x3); - const uchar g = (data[1] << 4) | ((data[0] & 0xc0) >> 4) | ((data[1] & 0x0f) >> 2); - const uchar b = (data[0] << 2) | ((data[0] & 0x3f) >> 4); - return qRgb(r, g, b); -} - -qrgb666 qrgb666::operator+(qrgb666 v) const -{ - const quint32 x1 = (data[2] << 16) | (data[1] << 8) | data[0]; - const quint32 x2 = (v.data[2] << 16) | (v.data[1] << 8) | v.data[0]; - const quint32 t = x1 + x2; - qrgb666 r; - r.data[0] = t & 0xff; - r.data[1] = (t >> 8) & 0xff; - r.data[2] = (t >> 16) & 0xff; - return r; -} - -qrgb666 qrgb666::byte_mul(quint8 a) const -{ - const quint32 x = (data[2] << 16) | (data[1] << 8) | data[0]; - const quint32 t = ((((x & 0x03f03f) * a) >> 6) & 0x03f03f) | - ((((x & 0x000fc0) * a) >> 6) & 0x000fc0); - - qrgb666 r; - r.data[0] = t & 0xff; - r.data[1] = (t >> 8) & 0xff; - r.data[2] = (t >> 16) & 0xff; - return r; -} - -bool qrgb666::operator==(const qrgb666 &v) const -{ - return (data[0] == v.data[0] && - data[1] == v.data[1] && - data[2] == v.data[2]); -} - -qargb6666::qargb6666(quint32p v) -{ - const quint8 b = qBlue(v) >> 2; - const quint8 g = qGreen(v) >> 2; - const quint8 r = qRed(v) >> 2; - const quint8 a = qAlpha(v) >> 2; - const uint p = (a << 18) | (r << 12) | (g << 6) | b; - data[0] = qBlue(p); - data[1] = qGreen(p); - data[2] = qRed(p); -} - -qargb6666::qargb6666(const qargb6666 &v) -{ - data[0] = v.data[0]; - data[1] = v.data[1]; - data[2] = v.data[2]; -} - -qargb6666::qargb6666(const qrgb666 &v) -{ - data[0] = v.data[0]; - data[1] = v.data[1]; - data[2] = (v.data[2] | 0xfc); -} - -qargb6666::operator quint32 () const -{ - const quint8 r = (data[2] << 6) | ((data[1] & 0xf0) >> 2) | (data[2] & 0x3); - const quint8 g = (data[1] << 4) | ((data[0] & 0xc0) >> 4) | ((data[1] & 0x0f) >> 2); - const quint8 b = (data[0] << 2) | ((data[0] & 0x3f) >> 4); - const quint8 a = (data[2] & 0xfc) | (data[2] >> 6); - return qRgba(r, g, b, a); -} - -qargb6666 qargb6666::operator+(qargb6666 v) const -{ - const quint32 x1 = (data[2] << 16) | (data[1] << 8) | data[0]; - const quint32 x2 = (v.data[2] << 16) | (v.data[1] << 8) | v.data[0]; - const quint32 t = x1 + x2; - qargb6666 r; - r.data[0] = t & 0xff; - r.data[1] = (t >> 8) & 0xff; - r.data[2] = (t >> 16) & 0xff; - return r; -} - -quint8 qargb6666::alpha() const -{ - return (data[2] & 0xfc) | (data[2] >> 6); -} - -inline qargb6666 qargb6666::byte_mul(quint8 a) const -{ - const quint32 x = (data[2] << 16) | (data[1] << 8) | data[0]; - const quint32 t = ((((x & 0x03f03f) * a) >> 6) & 0x03f03f) | - ((((x & 0xfc0fc0) * a) >> 6) & 0xfc0fc0); - - qargb6666 r; - r.data[0] = t & 0xff; - r.data[1] = (t >> 8) & 0xff; - r.data[2] = (t >> 16) & 0xff; - return r; -} - -bool qargb6666::operator==(const qargb6666 &v) const -{ - return data[0] == v.data[0] - && data[1] == v.data[1] - && data[2] == v.data[2]; -} - -quint32 qargb6666::rawValue() const -{ - return (data[2] << 16) | (data[1] << 8) | data[0]; -} - -class qrgb888 -{ -public: - Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return false; } - - inline qrgb888() {} - inline qrgb888(quint32 v); - - inline operator quint32() const; - - inline quint8 alpha() const { return 0xff; } - inline qrgb888 truncedAlpha() { return *this; } - Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return a; } - Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 255 - a; } - - inline qrgb888 byte_mul(quint8 a) const; - inline qrgb888 operator+(qrgb888 v) const; - inline bool operator==(qrgb888 v) const; - - inline quint32 rawValue() const; - -private: - uchar data[3]; - -} Q_PACKED; - -qrgb888::qrgb888(quint32 v) -{ - data[0] = qRed(v); - data[1] = qGreen(v); - data[2] = qBlue(v); -} - -qrgb888::operator quint32() const -{ - return qRgb(data[0], data[1], data[2]); -} - -qrgb888 qrgb888::operator+(qrgb888 v) const -{ - qrgb888 t = *this; - t.data[0] += v.data[0]; - t.data[1] += v.data[1]; - t.data[2] += v.data[2]; - return t; -} - -qrgb888 qrgb888::byte_mul(quint8 a) const -{ - quint32 x(*this); - - quint32 t = (x & 0xff00ff) * a; - t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8; - t &= 0xff00ff; - - x = ((x >> 8) & 0xff00ff) * a; - x = (x + ((x >> 8) & 0xff00ff) + 0x800080); - x &= 0xff00ff00; - x |= t; - return qrgb888(x); -} - -bool qrgb888::operator==(qrgb888 v) const -{ - return (data[0] == v.data[0] && - data[1] == v.data[1] && - data[2] == v.data[2]); -} - -quint32 qrgb888::rawValue() const -{ - return (data[2] << 16) | (data[1] << 8) | data[0]; -} - -template <> -inline qrgb888 qt_colorConvert(quint32 color, qrgb888 dummy) -{ - Q_UNUSED(dummy); - return qrgb888(color); -} - -template <> -inline quint32 qt_colorConvert(qrgb888 color, quint32 dummy) -{ - Q_UNUSED(dummy); - return quint32(color); -} - -// hw: endianess?? -class quint24 -{ -public: - inline quint24(quint32 v) - { - data[0] = qBlue(v); - data[1] = qGreen(v); - data[2] = qRed(v); - } - - inline operator quint32 () - { - return qRgb(data[2], data[1], data[0]); - } - - inline bool operator==(const quint24 &v) const - { - return data[0] == v.data[0] - && data[1] == v.data[1] - && data[2] == v.data[2]; - } - -private: +struct quint24 { + quint24(uint value); + operator uint() const; uchar data[3]; } Q_PACKED; -template <> -inline quint24 qt_colorConvert(quint32 color, quint24 dummy) +inline quint24::quint24(uint value) { - Q_UNUSED(dummy); - return quint24(color); + data[0] = uchar(value); + data[1] = uchar(value >> 8); + data[2] = uchar(value >> 16); } -// hw: endianess?? -class quint18 +inline quint24::operator uint() const { -public: - inline quint18(quint32 v) - { - uchar b = qBlue(v); - uchar g = qGreen(v); - uchar r = qRed(v); - uint p = (b >> 2) | ((g >> 2) << 6) | ((r >> 2) << 12); - data[0] = qBlue(p); - data[1] = qGreen(p); - data[2] = qRed(p); - } - - inline operator quint32 () - { - const uchar r = (data[2] << 6) | ((data[1] & 0xf0) >> 2) | (data[2] & 0x3); - const uchar g = (data[1] << 4) | ((data[0] & 0xc0) >> 4) | ((data[1] & 0x0f) >> 2); - const uchar b = (data[0] << 2) | ((data[0] & 0x3f) >> 4); - return qRgb(r, g, b); - } - -private: - uchar data[3]; -} Q_PACKED; - -template <> -inline quint18 qt_colorConvert(quint32 color, quint18 dummy) -{ - Q_UNUSED(dummy); - return quint18(color); -} - -class qrgb444; - -class qargb4444 -{ -public: - Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return true; } - - inline qargb4444() {} - inline qargb4444(quint32 v) { *this = qargb4444(quint32p(v)); } - inline explicit qargb4444(quint32p v); - inline qargb4444(const qrgb444 &v); - - inline operator quint32() const; - inline operator quint8() const; - - inline qargb4444 operator+(qargb4444 v) const; - - inline quint8 alpha() const { return ((data & 0xf000) >> 8) | ((data & 0xf000) >> 12); } - inline qargb4444 truncedAlpha() { return *this; } - Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 4; } - Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x10 - alpha(a); } - inline qargb4444 byte_mul(quint8 a) const; - - inline bool operator==(const qargb4444 &v) const { return data == v.data; } - - inline quint16 rawValue() const { return data; } - -private: - friend class qrgb444; - quint16 data; - -} Q_PACKED; - -class qrgb444 -{ -public: - Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return false; } - - inline qrgb444() {} - inline qrgb444(quint32 v); - inline explicit qrgb444(qargb4444 v); - - inline operator quint32() const; - inline operator quint8() const; - - inline qrgb444 operator+(qrgb444 v) const; - inline quint8 alpha() const { return 0xff; } - inline qrgb444 truncedAlpha() { return *this; } - Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 4; } - Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x10 - alpha(a); } - inline qrgb444 byte_mul(quint8 a) const; - - inline bool operator==(const qrgb444 &v) const { return data == v.data; } - inline bool operator!=(const qrgb444 &v) const { return data != v.data; } - - inline quint16 rawValue() const { return data; } - -private: - friend class qargb4444; - quint16 data; - -} Q_PACKED; - - -qargb4444::qargb4444(quint32p color) -{ - quint32 v = color; - v &= 0xf0f0f0f0; - const int a = qAlpha(v) << 8; - const int r = qRed(v) << 4; - const int g = qGreen(v); - const int b = qBlue(v) >> 4; - - data = a | r | g | b; -} - -qargb4444::qargb4444(const qrgb444 &v) -{ - data = v.data | 0xf000; -} - -qargb4444::operator quint32() const -{ - const int a = (data & 0xf000); - const int r = (data & 0x0f00); - const int g = (data & 0x00f0); - const int b = (data & 0x000f); - const int ta = (a >> 8) | (a >> 12); - const int tr = (r >> 4) | (r >> 8); - const int tg = g | (g >> 4); - const int tb = (b << 4) | b; - - return qRgba(tr, tg, tb, ta); -} - -qargb4444::operator quint8() const -{ - // hw: optimize! - return qt_colorConvert(operator quint32(), 0); -} - -qargb4444 qargb4444::operator+(qargb4444 v) const -{ - qargb4444 t; - t.data = data + v.data; - return t; -} - -qargb4444 qargb4444::byte_mul(quint8 a) const -{ - quint16 t = (((data & 0xf0f0) * a) >> 4) & 0xf0f0; - t |= (((data & 0x0f0f) * a) >> 4) & 0x0f0f; - - qargb4444 result; - result.data = t; - return result; -} - -qrgb444::qrgb444(quint32 v) -{ - v &= 0xf0f0f0f0; - const int r = qRed(v) << 4; - const int g = qGreen(v); - const int b = qBlue(v) >> 4; - - data = r | g | b; -} - -qrgb444::qrgb444(qargb4444 v) -{ - data = v.data & 0x0fff; -} - -qrgb444::operator quint32() const -{ - const int r = (data & 0x0f00); - const int g = (data & 0x00f0); - const int b = (data & 0x000f); - const int tr = (r >> 4) | (r >> 8); - const int tg = g | (g >> 4); - const int tb = (b << 4) | b; - - return qRgb(tr, tg, tb); -} - -qrgb444::operator quint8() const -{ - // hw: optimize! - return qt_colorConvert(operator quint32(), 0); -} - -qrgb444 qrgb444::operator+(qrgb444 v) const -{ - qrgb444 t; - t.data = data + v.data; - return t; -} - -qrgb444 qrgb444::byte_mul(quint8 a) const -{ - quint16 t = (((data & 0xf0f0) * a) >> 4) & 0xf0f0; - t |= (((data & 0x0f0f) * a) >> 4) & 0x0f0f; - - qrgb444 result; - result.data = t; - return result; + return data[0] | (data[1] << 8) | (data[2] << 16); } template @@ -1769,156 +732,6 @@ inline void qt_rectfill(T *dest, T value, } } -template -inline void qt_memconvert(DST *dest, const SRC *src, int count) -{ - if (sizeof(DST) == 1) { - while (count) { - int n = 1; - const SRC color = *src++; - const DST dstColor = qt_colorConvert(color, 0); - while (--count && (*src == color || dstColor == qt_colorConvert(*src, 0))) { - ++n; - ++src; - } - qt_memfill(dest, dstColor, n); - dest += n; - } - } else { - /* Duff's device */ - int n = (count + 7) / 8; - switch (count & 0x07) - { - case 0: do { *dest++ = qt_colorConvert(*src++, 0); - case 7: *dest++ = qt_colorConvert(*src++, 0); - case 6: *dest++ = qt_colorConvert(*src++, 0); - case 5: *dest++ = qt_colorConvert(*src++, 0); - case 4: *dest++ = qt_colorConvert(*src++, 0); - case 3: *dest++ = qt_colorConvert(*src++, 0); - case 2: *dest++ = qt_colorConvert(*src++, 0); - case 1: *dest++ = qt_colorConvert(*src++, 0); - } while (--n > 0); - } - } -} - -#define QT_TRIVIAL_MEMCONVERT_IMPL(T) \ - template <> \ - inline void qt_memconvert(T *dest, const T *src, int count) \ - { \ - memcpy(dest, src, count * sizeof(T)); \ - } -QT_TRIVIAL_MEMCONVERT_IMPL(quint32) -QT_TRIVIAL_MEMCONVERT_IMPL(qrgb888) -QT_TRIVIAL_MEMCONVERT_IMPL(qargb6666) -QT_TRIVIAL_MEMCONVERT_IMPL(qrgb666) -QT_TRIVIAL_MEMCONVERT_IMPL(quint16) -QT_TRIVIAL_MEMCONVERT_IMPL(qrgb565) -QT_TRIVIAL_MEMCONVERT_IMPL(qargb8565) -QT_TRIVIAL_MEMCONVERT_IMPL(qargb8555) -QT_TRIVIAL_MEMCONVERT_IMPL(qrgb555) -QT_TRIVIAL_MEMCONVERT_IMPL(qargb4444) -QT_TRIVIAL_MEMCONVERT_IMPL(qrgb444) -#undef QT_TRIVIAL_MEMCONVERT_IMPL - -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN -template <> -inline void qt_memconvert(qrgb666 *dest, const quint32 *src, int count) -{ - if (count < 3) { - switch (count) { - case 2: *dest++ = qrgb666(*src++); - case 1: *dest = qrgb666(*src); - } - return; - } - - const int align = (quintptr(dest) & 3); - switch (align) { - case 1: *dest++ = qrgb666(*src++); --count; - case 2: *dest++ = qrgb666(*src++); --count; - case 3: *dest++ = qrgb666(*src++); --count; - } - - quint32 *dest32 = reinterpret_cast(dest); - int sourceCount = count >> 2; - while (sourceCount--) { - dest32[0] = ((src[1] & 0x00000c00) << 20) - | ((src[1] & 0x000000fc) << 22) - | ((src[0] & 0x00fc0000) >> 6) - | ((src[0] & 0x0000fc00) >> 4) - | ((src[0] & 0x000000fc) >> 2); - dest32[1] = ((src[2] & 0x003c0000) << 10) - | ((src[2] & 0x0000fc00) << 12) - | ((src[2] & 0x000000fc) << 14) - | ((src[1] & 0x00fc0000) >> 14) - | ((src[1] & 0x0000f000) >> 12); - dest32[2] = ((src[3] & 0x00fc0000) << 2) - | ((src[3] & 0x0000fc00) << 4) - | ((src[3] & 0x000000fc) << 6) - | ((src[2] & 0x00c00000) >> 22); - dest32 += 3; - src += 4; - } - - dest = reinterpret_cast(dest32); - switch (count & 3) { - case 3: *dest++ = qrgb666(*src++); - case 2: *dest++ = qrgb666(*src++); - case 1: *dest = qrgb666(*src); - } -} -#endif // Q_BYTE_ORDER - -template -inline void qt_rectcopy(T *dest, const T *src, - int x, int y, int width, int height, - int dstStride, int srcStride) -{ - char *d = (char*)(dest + x) + y * dstStride; - const char *s = (char*)(src); - for (int i = 0; i < height; ++i) { - ::memcpy(d, s, width * sizeof(T)); - d += dstStride; - s += srcStride; - } -} - -template -inline void qt_rectconvert(DST *dest, const SRC *src, - int x, int y, int width, int height, - int dstStride, int srcStride) -{ - char *d = (char*)(dest + x) + y * dstStride; - const char *s = (char*)(src); - for (int i = 0; i < height; ++i) { - qt_memconvert((DST*)d, (const SRC*)s, width); - d += dstStride; - s += srcStride; - } -} - -#define QT_RECTCONVERT_TRIVIAL_IMPL(T) \ - template <> \ - inline void qt_rectconvert(T *dest, const T *src, \ - int x, int y, int width, int height, \ - int dstStride, int srcStride) \ - { \ - qt_rectcopy(dest, src, x, y, width, height, dstStride, srcStride); \ - } -QT_RECTCONVERT_TRIVIAL_IMPL(quint32) -QT_RECTCONVERT_TRIVIAL_IMPL(qrgb888) -QT_RECTCONVERT_TRIVIAL_IMPL(qargb6666) -QT_RECTCONVERT_TRIVIAL_IMPL(qrgb666) -QT_RECTCONVERT_TRIVIAL_IMPL(qrgb565) -QT_RECTCONVERT_TRIVIAL_IMPL(qargb8565) -QT_RECTCONVERT_TRIVIAL_IMPL(quint16) -QT_RECTCONVERT_TRIVIAL_IMPL(qargb8555) -QT_RECTCONVERT_TRIVIAL_IMPL(qrgb555) -QT_RECTCONVERT_TRIVIAL_IMPL(qargb4444) -QT_RECTCONVERT_TRIVIAL_IMPL(qrgb444) -#undef QT_RECTCONVERT_TRIVIAL_IMPL - #define QT_MEMFILL_UINT(dest, length, color) \ qt_memfill(dest, color, length); @@ -2137,6 +950,162 @@ void QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length, uint color, ui void QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest, int length, uint color, uint const_alpha); void QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest, int length, uint color, uint const_alpha); + +struct QPixelLayout; +typedef const uint *(QT_FASTCALL *ConvertFunc)(uint *buffer, const uint *src, int count, + const QPixelLayout *layout, const QRgb *clut); + +struct QPixelLayout +{ + // Bits per pixel + enum BPP { + BPPNone, + BPP1MSB, + BPP1LSB, + BPP8, + BPP16, + BPP24, + BPP32, + BPPCount + }; + + // All numbers in bits. + uchar redWidth; + uchar redShift; + uchar greenWidth; + uchar greenShift; + uchar blueWidth; + uchar blueShift; + uchar alphaWidth; + uchar alphaShift; + bool premultiplied; + BPP bpp; + ConvertFunc convertToARGB32PM; + ConvertFunc convertFromARGB32PM; +}; + +template +uint fetchPixel(const uchar *src, int index); + +template <> +inline uint QT_FASTCALL fetchPixel(const uchar *src, int index) +{ + return (src[index >> 3] >> (index & 7)) & 1; +} + +template <> +inline uint QT_FASTCALL fetchPixel(const uchar *src, int index) +{ + return (src[index >> 3] >> (~index & 7)) & 1; +} + +template <> +inline uint QT_FASTCALL fetchPixel(const uchar *src, int index) +{ + return src[index]; +} + +template <> +inline uint QT_FASTCALL fetchPixel(const uchar *src, int index) +{ + return reinterpret_cast(src)[index]; +} + +template <> +inline uint QT_FASTCALL fetchPixel(const uchar *src, int index) +{ + return reinterpret_cast(src)[index]; +} + +template <> +inline uint QT_FASTCALL fetchPixel(const uchar *src, int index) +{ + return reinterpret_cast(src)[index]; +} + +template +inline const uint *QT_FASTCALL fetchPixels(uint *buffer, const uchar *src, int index, int count) +{ + for (int i = 0; i < count; ++i) + buffer[i] = fetchPixel(src, index + i); + return buffer; +} + +template <> +inline const uint *QT_FASTCALL fetchPixels(uint *, const uchar *src, int index, int) +{ + return reinterpret_cast(src) + index; +} + +typedef const uint *(QT_FASTCALL *FetchPixelsFunc)(uint *buffer, const uchar *src, int index, int count); + + +template +void storePixel(uchar *dest, int index, uint pixel); + +template <> +inline void QT_FASTCALL storePixel(uchar *dest, int index, uint pixel) +{ + if (pixel) + dest[index >> 3] |= 1 << (index & 7); + else + dest[index >> 3] &= ~(1 << (index & 7)); +} + +template <> +inline void QT_FASTCALL storePixel(uchar *dest, int index, uint pixel) +{ + if (pixel) + dest[index >> 3] |= 1 << (~index & 7); + else + dest[index >> 3] &= ~(1 << (~index & 7)); +} + +template <> +inline void QT_FASTCALL storePixel(uchar *dest, int index, uint pixel) +{ + dest[index] = uchar(pixel); +} + +template <> +inline void QT_FASTCALL storePixel(uchar *dest, int index, uint pixel) +{ + reinterpret_cast(dest)[index] = quint16(pixel); +} + +template <> +inline void QT_FASTCALL storePixel(uchar *dest, int index, uint pixel) +{ + reinterpret_cast(dest)[index] = quint24(pixel); +} + +template <> +inline void QT_FASTCALL storePixel(uchar *dest, int index, uint pixel) +{ + reinterpret_cast(dest)[index] = pixel; +} + +template +inline void QT_FASTCALL storePixels(uchar *dest, const uint *src, int index, int count) +{ + for (int i = 0; i < count; ++i) + storePixel(dest, index + i, src[i]); +} + +template <> +inline void QT_FASTCALL storePixels(uchar *dest, const uint *src, int index, int count) +{ + memcpy(reinterpret_cast(dest) + index, src, count * sizeof(uint)); +} + +typedef void (QT_FASTCALL *StorePixelsFunc)(uchar *dest, const uint *src, int index, int count); + +extern QPixelLayout qPixelLayouts[QImage::NImageFormats]; +extern FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount]; +extern StorePixelsFunc qStorePixels[QPixelLayout::BPPCount]; + + + QT_END_NAMESPACE #endif // QDRAWHELPER_P_H diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index 17b249a2350..300a28158df 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -459,7 +459,7 @@ void qt_bitmapblit16_sse2(QRasterBuffer *rasterBuffer, int x, int y, quint32 color, const uchar *src, int width, int height, int stride) { - const quint16 c = qt_colorConvert(color, 0); + const quint16 c = qConvertRgb32To16(color); quint16 *dest = reinterpret_cast(rasterBuffer->scanLine(y)) + x; const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint16); diff --git a/src/gui/painting/qdrawhelper_sse_p.h b/src/gui/painting/qdrawhelper_sse_p.h index 81a5001fb3a..494ee70fcba 100644 --- a/src/gui/painting/qdrawhelper_sse_p.h +++ b/src/gui/painting/qdrawhelper_sse_p.h @@ -127,7 +127,7 @@ inline void qt_bitmapblit16_sse_template(QRasterBuffer *rasterBuffer, const uchar *src, int width, int height, int stride) { - const quint16 c = qt_colorConvert(color, 0); + const quint16 c = qConvertRgb32To16(color); quint16 *dest = reinterpret_cast(rasterBuffer->scanLine(y)) + x; const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint16); diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp index 5d027b669b8..e6fcc3e5ddb 100644 --- a/src/gui/painting/qmemrotate.cpp +++ b/src/gui/painting/qmemrotate.cpp @@ -53,36 +53,36 @@ static const int tileSize = 32; #endif #endif -template -Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_cachedRead(const SRC *src, int w, int h, - int sstride, - DST *dest, int dstride) +template +Q_STATIC_TEMPLATE_FUNCTION +inline void qt_memrotate90_cachedRead(const T *src, int w, int h, int sstride, T *dest, + int dstride) { const char *s = reinterpret_cast(src); char *d = reinterpret_cast(dest); for (int y = 0; y < h; ++y) { for (int x = w - 1; x >= 0; --x) { - DST *destline = reinterpret_cast(d + (w - x - 1) * dstride); - destline[y] = qt_colorConvert(src[x], 0); + T *destline = reinterpret_cast(d + (w - x - 1) * dstride); + destline[y] = src[x]; } s += sstride; - src = reinterpret_cast(s); + src = reinterpret_cast(s); } } -template -Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_cachedRead(const SRC *src, int w, int h, - int sstride, - DST *dest, int dstride) +template +Q_STATIC_TEMPLATE_FUNCTION +inline void qt_memrotate270_cachedRead(const T *src, int w, int h, int sstride, T *dest, + int dstride) { const char *s = reinterpret_cast(src); char *d = reinterpret_cast(dest); s += (h - 1) * sstride; for (int y = h - 1; y >= 0; --y) { - src = reinterpret_cast(s); + src = reinterpret_cast(s); for (int x = 0; x < w; ++x) { - DST *destline = reinterpret_cast(d + x * dstride); - destline[h - y - 1] = qt_colorConvert(src[x], 0); + T *destline = reinterpret_cast(d + x * dstride); + destline[h - y - 1] = src[x]; } s -= sstride; } @@ -90,29 +90,29 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_cachedRead(const SRC *src #if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE -template -Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_cachedWrite(const SRC *src, int w, int h, - int sstride, - DST *dest, int dstride) +template +Q_STATIC_TEMPLATE_FUNCTION +inline void qt_memrotate90_cachedWrite(const T *src, int w, int h, int sstride, T *dest, + int dstride) { for (int x = w - 1; x >= 0; --x) { - DST *d = dest + (w - x - 1) * dstride; + T *d = dest + (w - x - 1) * dstride; for (int y = 0; y < h; ++y) { - *d++ = qt_colorConvert(src[y * sstride + x], 0); + *d++ = src[y * sstride + x]; } } } -template -Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_cachedWrite(const SRC *src, int w, int h, - int sstride, - DST *dest, int dstride) +template +Q_STATIC_TEMPLATE_FUNCTION +inline void qt_memrotate270_cachedWrite(const T *src, int w, int h, int sstride, T *dest, + int dstride) { for (int x = 0; x < w; ++x) { - DST *d = dest + x * dstride; + T *d = dest + x * dstride; for (int y = h - 1; y >= 0; --y) { - *d++ = qt_colorConvert(src[y * sstride + x], 0); + *d++ = src[y * sstride + x]; } } } @@ -123,23 +123,21 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_cachedWrite(const SRC *sr // TODO: packing algorithms should probably be modified on 64-bit architectures -template -Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_packing(const SRC *src, int w, int h, - int sstride, - DST *dest, int dstride) +template +Q_STATIC_TEMPLATE_FUNCTION +inline void qt_memrotate90_packing(const T *src, int w, int h, int sstride, T *dest, int dstride) { - sstride /= sizeof(SRC); - dstride /= sizeof(DST); + sstride /= sizeof(T); + dstride /= sizeof(T); - const int pack = sizeof(quint32) / sizeof(DST); - const int unaligned = int((long(dest) & (sizeof(quint32)-1))) / sizeof(DST); + const int pack = sizeof(quint32) / sizeof(T); + const int unaligned = int((long(dest) & (sizeof(quint32)-1))) / sizeof(T); for (int x = w - 1; x >= 0; --x) { int y = 0; for (int i = 0; i < unaligned; ++i) { - dest[(w - x - 1) * dstride + y] - = qt_colorConvert(src[y * sstride + x], 0); + dest[(w - x - 1) * dstride + y] = src[y * sstride + x]; ++y; } @@ -147,40 +145,36 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_packing(const SRC *src, in + unaligned); const int rest = (h - unaligned) % pack; while (y < h - rest) { - quint32 c = qt_colorConvert(src[y * sstride + x], 0); + quint32 c = src[y * sstride + x]; for (int i = 1; i < pack; ++i) { - c |= qt_colorConvert(src[(y + i) * sstride + x], 0) - << (sizeof(int) * 8 / pack * i); + c |= src[(y + i) * sstride + x] << (sizeof(int) * 8 / pack * i); } *d++ = c; y += pack; } while (y < h) { - dest[(w - x - 1) * dstride + y] - = qt_colorConvert(src[y * sstride + x], 0); + dest[(w - x - 1) * dstride + y] = src[y * sstride + x]; ++y; } } } -template -Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_packing(const SRC *src, int w, int h, - int sstride, - DST *dest, int dstride) +template +Q_STATIC_TEMPLATE_FUNCTION +inline void qt_memrotate270_packing(const T *src, int w, int h, int sstride, T *dest, int dstride) { - sstride /= sizeof(SRC); - dstride /= sizeof(DST); + sstride /= sizeof(T); + dstride /= sizeof(T); - const int pack = sizeof(quint32) / sizeof(DST); - const int unaligned = int((long(dest) & (sizeof(quint32)-1))) / sizeof(DST); + const int pack = sizeof(quint32) / sizeof(T); + const int unaligned = int((long(dest) & (sizeof(quint32)-1))) / sizeof(T); for (int x = 0; x < w; ++x) { int y = h - 1; for (int i = 0; i < unaligned; ++i) { - dest[x * dstride + h - y - 1] - = qt_colorConvert(src[y * sstride + x], 0); + dest[x * dstride + h - y - 1] = src[y * sstride + x]; --y; } @@ -188,17 +182,15 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_packing(const SRC *src, i + unaligned); const int rest = (h - unaligned) % pack; while (y > rest) { - quint32 c = qt_colorConvert(src[y * sstride + x], 0); + quint32 c = src[y * sstride + x]; for (int i = 1; i < pack; ++i) { - c |= qt_colorConvert(src[(y - i) * sstride + x], 0) - << (sizeof(int) * 8 / pack * i); + c |= src[(y - i) * sstride + x] << (sizeof(int) * 8 / pack * i); } *d++ = c; y -= pack; } while (y >= 0) { - dest[x * dstride + h - y - 1] - = qt_colorConvert(src[y * sstride + x], 0); + dest[x * dstride + h - y - 1] = src[y * sstride + x]; --y; } } @@ -207,17 +199,16 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_packing(const SRC *src, i #endif // QT_ROTATION_PACKING #if QT_ROTATION_ALGORITHM == QT_ROTATION_TILED -template -Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_tiled(const SRC *src, int w, int h, - int sstride, - DST *dest, int dstride) +template +Q_STATIC_TEMPLATE_FUNCTION +inline void qt_memrotate90_tiled(const T *src, int w, int h, int sstride, T *dest, int dstride) { - sstride /= sizeof(SRC); - dstride /= sizeof(DST); + sstride /= sizeof(T); + dstride /= sizeof(T); - const int pack = sizeof(quint32) / sizeof(DST); + const int pack = sizeof(quint32) / sizeof(T); const int unaligned = - qMin(uint((quintptr(dest) & (sizeof(quint32)-1)) / sizeof(DST)), uint(h)); + qMin(uint((quintptr(dest) & (sizeof(quint32)-1)) / sizeof(T)), uint(h)); const int restX = w % tileSize; const int restY = (h - unaligned) % tileSize; const int unoptimizedY = restY % pack; @@ -230,9 +221,9 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_tiled(const SRC *src, int if (unaligned) { for (int x = startx; x >= stopx; --x) { - DST *d = dest + (w - x - 1) * dstride; + T *d = dest + (w - x - 1) * dstride; for (int y = 0; y < unaligned; ++y) { - *d++ = qt_colorConvert(src[y * sstride + x], 0); + *d++ = src[y * sstride + x]; } } } @@ -244,10 +235,10 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_tiled(const SRC *src, int for (int x = startx; x >= stopx; --x) { quint32 *d = reinterpret_cast(dest + (w - x - 1) * dstride + starty); for (int y = starty; y < stopy; y += pack) { - quint32 c = qt_colorConvert(src[y * sstride + x], 0); + quint32 c = src[y * sstride + x]; for (int i = 1; i < pack; ++i) { const int shift = (sizeof(int) * 8 / pack * i); - const DST color = qt_colorConvert(src[(y + i) * sstride + x], 0); + const T color = src[(y + i) * sstride + x]; c |= color << shift; } *d++ = c; @@ -258,19 +249,19 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_tiled(const SRC *src, int if (unoptimizedY) { const int starty = h - unoptimizedY; for (int x = startx; x >= stopx; --x) { - DST *d = dest + (w - x - 1) * dstride + starty; + T *d = dest + (w - x - 1) * dstride + starty; for (int y = starty; y < h; ++y) { - *d++ = qt_colorConvert(src[y * sstride + x], 0); + *d++ = src[y * sstride + x]; } } } } } -template -Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_tiled_unpacked(const SRC *src, int w, int h, - int sstride, - DST *dest, int dstride) +template +Q_STATIC_TEMPLATE_FUNCTION +inline void qt_memrotate90_tiled_unpacked(const T *src, int w, int h, int sstride, T *dest, + int dstride) { const int numTilesX = (w + tileSize - 1) / tileSize; const int numTilesY = (h + tileSize - 1) / tileSize; @@ -284,10 +275,10 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_tiled_unpacked(const SRC * const int stopy = qMin(starty + tileSize, h); for (int x = startx; x >= stopx; --x) { - DST *d = (DST*)((char*)dest + (w - x - 1) * dstride) + starty; + T *d = (T *)((char*)dest + (w - x - 1) * dstride) + starty; const char *s = (const char*)(src + x) + starty * sstride; for (int y = starty; y < stopy; ++y) { - *d++ = qt_colorConvert(*(const SRC*)(s), 0); + *d++ = *(const T *)(s); s += sstride; } } @@ -295,17 +286,16 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_tiled_unpacked(const SRC * } } -template -Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_tiled(const SRC *src, int w, int h, - int sstride, - DST *dest, int dstride) +template +Q_STATIC_TEMPLATE_FUNCTION +inline void qt_memrotate270_tiled(const T *src, int w, int h, int sstride, T *dest, int dstride) { - sstride /= sizeof(SRC); - dstride /= sizeof(DST); + sstride /= sizeof(T); + dstride /= sizeof(T); - const int pack = sizeof(quint32) / sizeof(DST); + const int pack = sizeof(quint32) / sizeof(T); const int unaligned = - qMin(uint((long(dest) & (sizeof(quint32)-1)) / sizeof(DST)), uint(h)); + qMin(uint((long(dest) & (sizeof(quint32)-1)) / sizeof(T)), uint(h)); const int restX = w % tileSize; const int restY = (h - unaligned) % tileSize; const int unoptimizedY = restY % pack; @@ -318,9 +308,9 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_tiled(const SRC *src, int if (unaligned) { for (int x = startx; x < stopx; ++x) { - DST *d = dest + x * dstride; + T *d = dest + x * dstride; for (int y = h - 1; y >= h - unaligned; --y) { - *d++ = qt_colorConvert(src[y * sstride + x], 0); + *d++ = src[y * sstride + x]; } } } @@ -333,10 +323,10 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_tiled(const SRC *src, int quint32 *d = reinterpret_cast(dest + x * dstride + h - 1 - starty); for (int y = starty; y > stopy; y -= pack) { - quint32 c = qt_colorConvert(src[y * sstride + x], 0); + quint32 c = src[y * sstride + x]; for (int i = 1; i < pack; ++i) { const int shift = (sizeof(int) * 8 / pack * i); - const DST color = qt_colorConvert(src[(y - i) * sstride + x], 0); + const T color = src[(y - i) * sstride + x]; c |= color << shift; } *d++ = c; @@ -346,19 +336,19 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_tiled(const SRC *src, int if (unoptimizedY) { const int starty = unoptimizedY - 1; for (int x = startx; x < stopx; ++x) { - DST *d = dest + x * dstride + h - 1 - starty; + T *d = dest + x * dstride + h - 1 - starty; for (int y = starty; y >= 0; --y) { - *d++ = qt_colorConvert(src[y * sstride + x], 0); + *d++ = src[y * sstride + x]; } } } } } -template -Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_tiled_unpacked(const SRC *src, int w, int h, - int sstride, - DST *dest, int dstride) +template +Q_STATIC_TEMPLATE_FUNCTION +inline void qt_memrotate270_tiled_unpacked(const T *src, int w, int h, int sstride, T *dest, + int dstride) { const int numTilesX = (w + tileSize - 1) / tileSize; const int numTilesY = (h + tileSize - 1) / tileSize; @@ -372,10 +362,10 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_tiled_unpacked(const SRC const int stopy = qMax(starty - tileSize, 0); for (int x = startx; x < stopx; ++x) { - DST *d = (DST*)((char*)dest + x * dstride) + h - 1 - starty; + T *d = (T*)((char*)dest + x * dstride) + h - 1 - starty; const char *s = (const char*)(src + x) + starty * sstride; for (int y = starty; y >= stopy; --y) { - *d++ = qt_colorConvert(*(const SRC*)s, 0); + *d++ = *(const T*)s; s -= sstride; } } @@ -385,214 +375,112 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_tiled_unpacked(const SRC #endif // QT_ROTATION_ALGORITHM -template -Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_template(const SRC *src, - int srcWidth, int srcHeight, int srcStride, - DST *dest, int dstStride) +template +Q_STATIC_TEMPLATE_FUNCTION +inline void qt_memrotate90_template(const T *src, int srcWidth, int srcHeight, int srcStride, + T *dest, int dstStride) { #if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD - qt_memrotate90_cachedRead(src, srcWidth, srcHeight, srcStride, - dest, dstStride); + qt_memrotate90_cachedRead(src, srcWidth, srcHeight, srcStride, dest, dstStride); #elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE - qt_memrotate90_cachedWrite(src, srcWidth, srcHeight, srcStride, - dest, dstStride); + qt_memrotate90_cachedWrite(src, srcWidth, srcHeight, srcStride, dest, dstStride); #elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING - qt_memrotate90_packing(src, srcWidth, srcHeight, srcStride, - dest, dstStride); + qt_memrotate90_packing(src, srcWidth, srcHeight, srcStride, dest, dstStride); #elif QT_ROTATION_ALGORITHM == QT_ROTATION_TILED - qt_memrotate90_tiled(src, srcWidth, srcHeight, srcStride, - dest, dstStride); + qt_memrotate90_tiled(src, srcWidth, srcHeight, srcStride, dest, dstStride); #endif } -template -Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate180_template(const SRC *src, - int w, int h, int sstride, - DST *dest, int dstride) +template +Q_STATIC_TEMPLATE_FUNCTION +inline void qt_memrotate180_template(const T *src, int w, int h, int sstride, T *dest, int dstride) { const char *s = (const char*)(src) + (h - 1) * sstride; for (int y = h - 1; y >= 0; --y) { - DST *d = reinterpret_cast((char *)(dest) + (h - y - 1) * dstride); - src = reinterpret_cast(s); + T *d = reinterpret_cast((char *)(dest) + (h - y - 1) * dstride); + src = reinterpret_cast(s); for (int x = w - 1; x >= 0; --x) { - d[w - x - 1] = qt_colorConvert(src[x], 0); + d[w - x - 1] = src[x]; } s -= sstride; } } -template -Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_template(const SRC *src, - int srcWidth, int srcHeight, int srcStride, - DST *dest, int dstStride) +template +Q_STATIC_TEMPLATE_FUNCTION +inline void qt_memrotate270_template(const T *src, int srcWidth, int srcHeight, int srcStride, + T *dest, int dstStride) { #if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD - qt_memrotate270_cachedRead(src, srcWidth, srcHeight, srcStride, - dest, dstStride); + qt_memrotate270_cachedRead(src, srcWidth, srcHeight, srcStride, dest, dstStride); #elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE - qt_memrotate270_cachedWrite(src, srcWidth, srcHeight, srcStride, - dest, dstStride); + qt_memrotate270_cachedWrite(src, srcWidth, srcHeight, srcStride, dest, dstStride); #elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING - qt_memrotate270_packing(src, srcWidth, srcHeight, srcStride, - dest, dstStride); + qt_memrotate270_packing(src, srcWidth, srcHeight, srcStride, dest, dstStride); #elif QT_ROTATION_ALGORITHM == QT_ROTATION_TILED - qt_memrotate270_tiled_unpacked(src, srcWidth, srcHeight, - srcStride, - dest, dstStride); + qt_memrotate270_tiled_unpacked(src, srcWidth, srcHeight, srcStride, dest, dstStride); #endif } template <> Q_STATIC_TEMPLATE_SPECIALIZATION -inline void qt_memrotate90_template(const quint24 *src, - int srcWidth, int srcHeight, int srcStride, - quint24 *dest, int dstStride) +inline void qt_memrotate90_template(const quint24 *src, int srcWidth, int srcHeight, + int srcStride, quint24 *dest, int dstStride) { #if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD - qt_memrotate90_cachedRead(src, srcWidth, srcHeight, - srcStride, dest, dstStride); + qt_memrotate90_cachedRead(src, srcWidth, srcHeight, srcStride, dest, dstStride); #elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE - qt_memrotate90_cachedWrite(src, srcWidth, srcHeight, - srcStride, dest, dstStride); + qt_memrotate90_cachedWrite(src, srcWidth, srcHeight, srcStride, dest, dstStride); #elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING // packed algorithm not implemented - qt_memrotate90_cachedRead(src, srcWidth, srcHeight, - srcStride, dest, dstStride); + qt_memrotate90_cachedRead(src, srcWidth, srcHeight, srcStride, dest, dstStride); #elif QT_ROTATION_ALGORITHM == QT_ROTATION_TILED // packed algorithm not implemented - qt_memrotate90_tiled_unpacked(src, srcWidth, srcHeight, - srcStride, dest, dstStride); + qt_memrotate90_tiled_unpacked(src, srcWidth, srcHeight, srcStride, dest, dstStride); #endif } -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline void qt_memrotate90_template(const quint32 *src, - int srcWidth, int srcHeight, int srcStride, - quint24 *dest, int dstStride) -{ -#if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD - qt_memrotate90_cachedRead(src, srcWidth, srcHeight, - srcStride, dest, dstStride); -#elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE - qt_memrotate90_cachedWrite(src, srcWidth, srcHeight, - srcStride, dest, dstStride); -#elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING - // packed algorithm not implemented - qt_memrotate90_cachedRead(src, srcWidth, srcHeight, - srcStride, dest, dstStride); -#elif QT_ROTATION_ALGORITHM == QT_ROTATION_TILED - // packed algorithm not implemented - qt_memrotate90_tiled_unpacked(src, srcWidth, srcHeight, - srcStride, dest, dstStride); -#endif -} - -template <> -Q_STATIC_TEMPLATE_SPECIALIZATION -inline void qt_memrotate90_template(const quint32 *src, - int srcWidth, int srcHeight, int srcStride, - quint18 *dest, int dstStride) -{ -#if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD - qt_memrotate90_cachedRead(src, srcWidth, srcHeight, - srcStride, dest, dstStride); -#elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE - qt_memrotate90_cachedWrite(src, srcWidth, srcHeight, - srcStride, dest, dstStride); -#elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING - // packed algorithm not implemented - qt_memrotate90_cachedRead(src, srcWidth, srcHeight, - srcStride, dest, dstStride); -#elif QT_ROTATION_ALGORITHM == QT_ROTATION_TILED - // packed algorithm not implemented - qt_memrotate90_tiled_unpacked(src, srcWidth, srcHeight, - srcStride, dest, dstStride); -#endif -} - -#define QT_IMPL_MEMROTATE(srctype, desttype) \ -Q_GUI_EXPORT void qt_memrotate90(const srctype *src, int w, int h, int sstride, \ - desttype *dest, int dstride) \ +#define QT_IMPL_MEMROTATE(type) \ +Q_GUI_EXPORT void qt_memrotate90(const type *src, int w, int h, int sstride, \ + type *dest, int dstride) \ { \ qt_memrotate90_template(src, w, h, sstride, dest, dstride); \ } \ -Q_GUI_EXPORT void qt_memrotate180(const srctype *src, int w, int h, int sstride, \ - desttype *dest, int dstride) \ +Q_GUI_EXPORT void qt_memrotate180(const type *src, int w, int h, int sstride, \ + type *dest, int dstride) \ { \ qt_memrotate180_template(src, w, h, sstride, dest, dstride); \ } \ -Q_GUI_EXPORT void qt_memrotate270(const srctype *src, int w, int h, int sstride, \ - desttype *dest, int dstride) \ +Q_GUI_EXPORT void qt_memrotate270(const type *src, int w, int h, int sstride, \ + type *dest, int dstride) \ { \ qt_memrotate270_template(src, w, h, sstride, dest, dstride); \ } -#define QT_IMPL_SIMPLE_MEMROTATE(srctype, desttype) \ -Q_GUI_EXPORT void qt_memrotate90(const srctype *src, int w, int h, int sstride, \ - desttype *dest, int dstride) \ +#define QT_IMPL_SIMPLE_MEMROTATE(type) \ +Q_GUI_EXPORT void qt_memrotate90(const type *src, int w, int h, int sstride, \ + type *dest, int dstride) \ { \ - qt_memrotate90_tiled_unpacked(src, w, h, sstride, dest, dstride); \ + qt_memrotate90_tiled_unpacked(src, w, h, sstride, dest, dstride); \ } \ -Q_GUI_EXPORT void qt_memrotate180(const srctype *src, int w, int h, int sstride, \ - desttype *dest, int dstride) \ +Q_GUI_EXPORT void qt_memrotate180(const type *src, int w, int h, int sstride, \ + type *dest, int dstride) \ { \ qt_memrotate180_template(src, w, h, sstride, dest, dstride); \ } \ -Q_GUI_EXPORT void qt_memrotate270(const srctype *src, int w, int h, int sstride, \ - desttype *dest, int dstride) \ +Q_GUI_EXPORT void qt_memrotate270(const type *src, int w, int h, int sstride, \ + type *dest, int dstride) \ { \ - qt_memrotate270_tiled_unpacked(src, w, h, sstride, dest, dstride); \ + qt_memrotate270_tiled_unpacked(src, w, h, sstride, dest, dstride); \ } -QT_IMPL_MEMROTATE(quint32, quint32) -QT_IMPL_MEMROTATE(quint32, quint16) -QT_IMPL_MEMROTATE(quint16, quint32) -QT_IMPL_MEMROTATE(quint16, quint16) -QT_IMPL_MEMROTATE(quint24, quint24) -QT_IMPL_MEMROTATE(quint32, quint24) -QT_IMPL_MEMROTATE(quint32, quint18) -QT_IMPL_MEMROTATE(quint32, quint8) -QT_IMPL_MEMROTATE(quint16, quint8) -QT_IMPL_MEMROTATE(qrgb444, quint8) -QT_IMPL_MEMROTATE(quint8, quint8) - -#if defined(QT_QWS_ROTATE_BGR) -QT_IMPL_SIMPLE_MEMROTATE(quint16, qbgr565) -QT_IMPL_SIMPLE_MEMROTATE(quint32, qbgr565) -QT_IMPL_SIMPLE_MEMROTATE(qrgb555, qbgr555) -QT_IMPL_SIMPLE_MEMROTATE(quint32, qbgr555) -#endif - -#ifdef QT_QWS_DEPTH_GENERIC -QT_IMPL_MEMROTATE(quint32, qrgb_generic16) -QT_IMPL_MEMROTATE(quint16, qrgb_generic16) -#endif - -struct qrgb_gl_rgba -{ -public: - inline qrgb_gl_rgba(quint32 v) { - if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) - data = ((v << 16) & 0xff0000) | ((v >> 16) & 0xff) | (v & 0xff00ff00); - else - data = (v << 8) | ((v >> 24) & 0xff); - } - - inline operator quint32() const { return data; } - -private: - quint32 data; -} Q_PACKED; - -void Q_GUI_EXPORT qt_memrotate90_gl(const quint32 *src, int srcWidth, int srcHeight, int srcStride, - quint32 *dest, int dstStride) -{ - qt_memrotate90_template(src, srcWidth, srcHeight, srcStride, reinterpret_cast(dest), dstStride); -} +QT_IMPL_MEMROTATE(quint32) +QT_IMPL_MEMROTATE(quint16) +QT_IMPL_MEMROTATE(quint24) +QT_IMPL_MEMROTATE(quint8) void qt_memrotate90_16(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl) { diff --git a/src/gui/painting/qmemrotate_p.h b/src/gui/painting/qmemrotate_p.h index 4c4bc947677..a72310e330a 100644 --- a/src/gui/painting/qmemrotate_p.h +++ b/src/gui/painting/qmemrotate_p.h @@ -70,37 +70,15 @@ QT_BEGIN_NAMESPACE #endif #endif -#define QT_DECL_MEMROTATE(srctype, desttype) \ - void Q_GUI_EXPORT qt_memrotate90(const srctype*, int, int, int, desttype*, int); \ - void Q_GUI_EXPORT qt_memrotate180(const srctype*, int, int, int, desttype*, int); \ - void Q_GUI_EXPORT qt_memrotate270(const srctype*, int, int, int, desttype*, int) +#define QT_DECL_MEMROTATE(type) \ + void Q_GUI_EXPORT qt_memrotate90(const type*, int, int, int, type*, int); \ + void Q_GUI_EXPORT qt_memrotate180(const type*, int, int, int, type*, int); \ + void Q_GUI_EXPORT qt_memrotate270(const type*, int, int, int, type*, int) -void Q_GUI_EXPORT qt_memrotate90(const quint32*, int, int, int, quint32*, int); -void Q_GUI_EXPORT qt_memrotate180(const quint32*, int, int, int, quint32*, int); -void Q_GUI_EXPORT qt_memrotate270(const quint32*, int, int, int, quint32*, int); - -QT_DECL_MEMROTATE(quint32, quint16); -QT_DECL_MEMROTATE(quint16, quint32); -QT_DECL_MEMROTATE(quint16, quint16); -QT_DECL_MEMROTATE(quint24, quint24); -QT_DECL_MEMROTATE(quint32, quint24); -QT_DECL_MEMROTATE(quint32, quint18); -QT_DECL_MEMROTATE(quint32, quint8); -QT_DECL_MEMROTATE(quint16, quint8); -QT_DECL_MEMROTATE(qrgb444, quint8); -QT_DECL_MEMROTATE(quint8, quint8); - -#ifdef QT_QWS_ROTATE_BGR -QT_DECL_MEMROTATE(quint16, qbgr565); -QT_DECL_MEMROTATE(quint32, qbgr565); -QT_DECL_MEMROTATE(qrgb555, qbgr555); -QT_DECL_MEMROTATE(quint32, qbgr555); -#endif - -#ifdef QT_QWS_DEPTH_GENERIC -QT_DECL_MEMROTATE(quint32, qrgb_generic16); -QT_DECL_MEMROTATE(quint16, qrgb_generic16); -#endif +QT_DECL_MEMROTATE(quint32); +QT_DECL_MEMROTATE(quint16); +QT_DECL_MEMROTATE(quint24); +QT_DECL_MEMROTATE(quint8); #undef QT_DECL_MEMROTATE diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index cda887d8e13..c5c2b13b3e9 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -1025,17 +1025,17 @@ void tst_QImage::setPixel_data() QTest::newRow("RGB16 blue") << int(QImage::Format_RGB16) << 0xff0000ff << 0x001fu; QTest::newRow("ARGB8565_Premultiplied red") << int(QImage::Format_ARGB8565_Premultiplied) - << 0xffff0000 << 0xffff0000; + << 0xffff0000 << 0xf800ffu; QTest::newRow("ARGB8565_Premultiplied green") << int(QImage::Format_ARGB8565_Premultiplied) - << 0xff00ff00 << 0xff00ff00; + << 0xff00ff00 << 0x07e0ffu; QTest::newRow("ARGB8565_Premultiplied blue") << int(QImage::Format_ARGB8565_Premultiplied) - << 0xff0000ff << 0xff0000ff; + << 0xff0000ff << 0x001fffu; QTest::newRow("RGB666 red") << int(QImage::Format_RGB666) - << 0xffff0000 << 0xffff0000; + << 0xffff0000 << 0x03f000u; QTest::newRow("RGB666 green") << int(QImage::Format_RGB666) - << 0xff00ff00 << 0xff00ff00;; + << 0xff00ff00 << 0x000fc0u; QTest::newRow("RGB666 blue") << int(QImage::Format_RGB666) - << 0xff0000ff << 0xff0000ff; + << 0xff0000ff << 0x00003fu; QTest::newRow("RGB555 red") << int(QImage::Format_RGB555) << 0xffff0000 << 0x7c00u; QTest::newRow("RGB555 green") << int(QImage::Format_RGB555) @@ -1043,17 +1043,17 @@ void tst_QImage::setPixel_data() QTest::newRow("RGB555 blue") << int(QImage::Format_RGB555) << 0xff0000ff << 0x001fu; QTest::newRow("ARGB8555_Premultiplied red") << int(QImage::Format_ARGB8555_Premultiplied) - << 0xffff0000 << 0xffff0000; + << 0xffff0000 << 0x7c00ffu; QTest::newRow("ARGB8555_Premultiplied green") << int(QImage::Format_ARGB8555_Premultiplied) - << 0xff00ff00 << 0xff00ff00; + << 0xff00ff00 << 0x03e0ffu; QTest::newRow("ARGB8555_Premultiplied blue") << int(QImage::Format_ARGB8555_Premultiplied) - << 0xff0000ff << 0xff0000ff; + << 0xff0000ff << 0x001fffu; QTest::newRow("RGB888 red") << int(QImage::Format_RGB888) - << 0xffff0000 << 0xffff0000; + << 0xffff0000 << 0x0000ffu; QTest::newRow("RGB888 green") << int(QImage::Format_RGB888) - << 0xff00ff00 << 0xff00ff00; + << 0xff00ff00 << 0x00ff00u; QTest::newRow("RGB888 blue") << int(QImage::Format_RGB888) - << 0xff0000ff << 0xff0000ff; + << 0xff0000ff << 0xff0000u; } void tst_QImage::setPixel() @@ -1106,57 +1106,18 @@ void tst_QImage::setPixel() break; } case int(QImage::Format_RGB666): - { - for (int y = 0; y < h; ++y) { - const qrgb666 *row = (const qrgb666*)(img.scanLine(y)); - for (int x = 0; x < w; ++x) { - quint32 result = row[x]; - if (result != expected) - printf("[x,y]: %d,%d, expected=%04x, result=%04x\n", - x, y, expected, result); - QCOMPARE(result, expected); - } - } - break; - } case int(QImage::Format_ARGB8565_Premultiplied): - { - for (int y = 0; y < h; ++y) { - const qargb8565 *row = (const qargb8565*)(img.scanLine(y)); - for (int x = 0; x < w; ++x) { - quint32 result = row[x]; - if (result != expected) - printf("[x,y]: %d,%d, expected=%04x, result=%04x\n", - x, y, expected, result); - QCOMPARE(result, expected); - } - } - break; - } case int(QImage::Format_ARGB8555_Premultiplied): - { - for (int y = 0; y < h; ++y) { - const qargb8555 *row = (const qargb8555*)(img.scanLine(y)); - for (int x = 0; x < w; ++x) { - quint32 result = row[x]; - if (result != expected) - printf("[x,y]: %d,%d, expected=%04x, result=%04x\n", - x, y, expected, result); - QCOMPARE(result, expected); - } - } - break; - } case int(QImage::Format_RGB888): { for (int y = 0; y < h; ++y) { - const qrgb888 *row = (const qrgb888*)(img.scanLine(y)); + const quint24 *row = (const quint24*)(img.scanLine(y)); for (int x = 0; x < w; ++x) { - qrgb888 result = row[x]; + quint32 result = row[x]; if (result != expected) printf("[x,y]: %d,%d, expected=%04x, result=%04x\n", - x, y, expected, quint32(result)); - QCOMPARE(uint(result), expected); + x, y, expected, result); + QCOMPARE(result, expected); } } break; From 9c31f6793e50b8ded908168e8083aac052ce0947 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Tue, 7 Feb 2012 13:52:41 +0100 Subject: [PATCH 032/406] Fixed jagged lines when drawing scaled image with raster engine. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-24055 Change-Id: I97a0bf3711e1b4423e2c76ec907c9e2a57522ff9 Reviewed-by: Samuel Rødal --- src/gui/painting/qdrawhelper_sse2.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index 300a28158df..7b57d5c5e26 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -629,8 +629,9 @@ void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, int x = 0; ALIGNMENT_PROLOGUE_16BYTES(dst, x, w) { - uint s = src[(srcx + x*ix) >> 16]; + uint s = src[srcx >> 16]; dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); + srcx += ix; } __m128i srcxVector = _mm_set_epi32(srcx, srcx + ix, srcx + ix + ix, srcx + ix + ix + ix); @@ -646,7 +647,7 @@ void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, } for (; x> 16]; + uint s = src[(basex + x*ix) >> 16]; dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); } dst = (quint32 *)(((uchar *) dst) + dbpl); From 8aeb70ed366650dd39c4edf9777bd7a9777cb313 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 2 Feb 2012 22:40:30 +0100 Subject: [PATCH 033/406] Add special casing for static modules. QtUITools is a static library, so we need to mark that in its CMakeConfig.cmake file. Change-Id: I4e3684f7c62f4af28956a6e8f58edce7724f50dd Reviewed-by: Stephen Kelly Reviewed-by: Oswald Buddenhagen --- mkspecs/features/create_cmake.prf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf index 0a14b5cea46..e52e65c06ff 100644 --- a/mkspecs/features/create_cmake.prf +++ b/mkspecs/features/create_cmake.prf @@ -29,13 +29,15 @@ CMAKE_BIN_DIR = $$replace(CMAKE_BINS, ^.*/, ) CMAKE_RELATIVE_INSTALL_DIR = "../../../" +static|staticlib:CMAKE_STATIC_TYPE = true + macx { CONFIG(qt_framework, qt_framework|qt_no_framework) { CMAKE_LIB_FILE_LOCATION_DEBUG = Qt$${CMAKE_MODULE_NAME}$${QT_LIBINFIX}.framework/Qt$${CMAKE_MODULE_NAME}$${QT_LIBINFIX} CMAKE_LIB_FILE_LOCATION_RELEASE = Qt$${CMAKE_MODULE_NAME}$${QT_LIBINFIX}.framework/Qt$${CMAKE_MODULE_NAME}$${QT_LIBINFIX} CMAKE_BUILD_IS_FRAMEWORK = "true" } else { - static { + !isEmpty(CMAKE_STATIC_TYPE) { CMAKE_LIB_FILE_LOCATION_DEBUG = libQt$${CMAKE_MODULE_NAME}$${QT_LIBINFIX}.a CMAKE_LIB_FILE_LOCATION_RELEASE = libQt$${CMAKE_MODULE_NAME}$${QT_LIBINFIX}.a } else { @@ -44,7 +46,7 @@ macx { } } } else:win32 { - static { + !isEmpty(CMAKE_STATIC_TYPE) { CMAKE_IMPLIB_FILE_LOCATION_DEBUG = Qt$${CMAKE_MODULE_NAME}$${QT_LIBINFIX}d.lib CMAKE_IMPLIB_FILE_LOCATION_RELEASE = Qt$${CMAKE_MODULE_NAME}$${QT_LIBINFIX}.lib } else { @@ -55,7 +57,7 @@ macx { } CMAKE_BIN_SUFFIX = ".exe" } else { - static { + !isEmpty(CMAKE_STATIC_TYPE) { CMAKE_LIB_FILE_LOCATION_DEBUG = libQt$${CMAKE_MODULE_NAME}$${QT_LIBINFIX}.a CMAKE_LIB_FILE_LOCATION_RELEASE = libQt$${CMAKE_MODULE_NAME}$${QT_LIBINFIX}.a } else { @@ -72,8 +74,6 @@ debug_and_release|release:release_type = release INSTALLS += cmake_qt5_module_files -static:CMAKE_STATIC_TYPE = true - cmake_config_file.input = $$PWD/../cmake/Qt5BasicConfig.cmake.in cmake_config_file.output = $$eval(QT.$${MODULE}.libs)/cmake/Qt5$${CMAKE_MODULE_NAME}/Qt5$${CMAKE_MODULE_NAME}Config.cmake From 1de30075a2cb398df89806ed5655105c60a9f85c Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 7 Feb 2012 10:56:38 +0100 Subject: [PATCH 034/406] Add missing subdirectory test. Change-Id: If59f124ce8be520c8c8692ac4f1400552749557b Reviewed-by: Stephen Kelly --- tests/manual/cmake/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/manual/cmake/CMakeLists.txt b/tests/manual/cmake/CMakeLists.txt index 91ead649ec8..7eca679e1b6 100644 --- a/tests/manual/cmake/CMakeLists.txt +++ b/tests/manual/cmake/CMakeLists.txt @@ -33,3 +33,4 @@ expect_pass(pass2) expect_pass(pass3) expect_fail(fail4) expect_fail(fail5) +expect_pass("pass(needsquoting)6") From deea48ef6a545ba0c198efcc8db3c5ba7b0b432b Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 1 Feb 2012 13:57:24 +0000 Subject: [PATCH 035/406] Fix QFile autotest not to require elevated privilege to pass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The open test case tests opening a device path on windows. As this requires privilege elevation, the test fails when running nmake check from a console. As the CI machines appear to run tests with admin privileges, first check opening the device using the windows API. If that succeeds, then opening using QFile should succeed. If that fails, the opening using QFile should fail. (Since Windows vista, members of the "administrators" group do not run at elevated privilege all the time. The user needs to opt in via a UAC prompt or "run as administrator". This is similar to using the sudo command on unix) Ran the test as administrator and normally. Now passes in both cases. Change-Id: Ibd7682eceb61e35d4912fa0392df536f4331f6ed Reviewed-by: João Abecasis --- tests/auto/corelib/io/qfile/tst_qfile.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 00e45354ba3..67a4f71f540 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -53,7 +53,9 @@ #include #endif #include -#ifndef Q_OS_WIN +#ifdef Q_OS_WIN +# include +#else # include # include #endif @@ -476,8 +478,16 @@ void tst_QFile::open_data() QTest::newRow("noreadfile") << QString("noreadfile") << int(QIODevice::ReadOnly) << false << QFile::OpenError; #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) - QTest::newRow("//./PhysicalDrive0") << QString("//./PhysicalDrive0") << int(QIODevice::ReadOnly) - << true << QFile::NoError; + //opening devices requires administrative privileges (and elevation). + HANDLE hTest = CreateFile(_T("\\\\.\\PhysicalDrive0"), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if (hTest != INVALID_HANDLE_VALUE) { + CloseHandle(hTest); + QTest::newRow("//./PhysicalDrive0") << QString("//./PhysicalDrive0") << int(QIODevice::ReadOnly) + << true << QFile::NoError; + } else { + QTest::newRow("//./PhysicalDrive0") << QString("//./PhysicalDrive0") << int(QIODevice::ReadOnly) + << false << QFile::OpenError; + } QTest::newRow("uncFile") << "//" + QtNetworkSettings::winServerName() + "/testshare/test.pri" << int(QIODevice::ReadOnly) << true << QFile::NoError; #endif From 8e1107fb2291733181497a8fa99a201b469e2b68 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 7 Feb 2012 16:35:53 +0100 Subject: [PATCH 036/406] Fix compiler warnings in accessible code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add missing return value. - Remove unused static functions. Change-Id: I0271cacc2a01b33209c4d9d2d958ad89924f8951 Reviewed-by: Jan-Arve Sæther --- .../accessible/widgets/qaccessiblewidgets.cpp | 24 ------------------- src/widgets/accessible/qaccessiblewidget.cpp | 1 + 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp index 94101efa670..2d6330cb38b 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp @@ -106,30 +106,6 @@ QList childWidgets(const QWidget *widget, bool includeTopLevel) \internal */ -static QTextBlock qTextBlockAt(const QTextDocument *doc, int pos) -{ - Q_ASSERT(pos >= 0); - - QTextBlock block = doc->begin(); - int i = 0; - while (block.isValid() && i < pos) { - block = block.next(); - ++i; - } - return block; -} - -static int qTextBlockPosition(QTextBlock block) -{ - int child = 0; - while (block.isValid()) { - block = block.previous(); - ++child; - } - - return child; -} - /*! \fn QAccessibleTextEdit::QAccessibleTextEdit(QWidget* widget) diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index be579fecf87..7a0aab56ddb 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -390,6 +390,7 @@ QAccessibleInterface *QAccessibleWidget::focusChild() const if (isAncestor(widget(), fw) || fw == widget()) return QAccessible::queryAccessibleInterface(fw); + return 0; } /*! \reimp */ From de7e3a7db734bcfee3fbe6a444ed0a9e56c5bee5 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Tue, 7 Feb 2012 13:44:09 +0100 Subject: [PATCH 037/406] Fix include of resource file. The file was moved, but got never renamed. Change-Id: I4f13d87976cf35a1e14b9a8c178050332f45b7ee Reviewed-by: Miikka Heikkinen Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qmenu_wince.rc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/widgets/qmenu_wince.rc b/src/widgets/widgets/qmenu_wince.rc index 2540d9f43a6..497c5491373 100644 --- a/src/widgets/widgets/qmenu_wince.rc +++ b/src/widgets/widgets/qmenu_wince.rc @@ -4,9 +4,9 @@ #include "winuser.h" #if defined (_DEBUG) && defined(QT_DLL) -#include "QtGuid_resource.rc" +#include "QtWidgetsd_resource.rc" #elif defined(QT_DLL) -#include "QtGui_resource.rc" +#include "QtWidgets_resource.rc" #endif #define DIALOGEX DIALOG DISCARDABLE From b03cabc4cdcc1e416dbb3c59eeb00cc1488ec21f Mon Sep 17 00:00:00 2001 From: Jonathan Liu Date: Tue, 7 Feb 2012 23:12:36 +1100 Subject: [PATCH 038/406] Change WId to be a quintptr. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix compilation with MinGW-w64: Use quintptr instead of unsigned long as WId needs to be able to cast to HWND which is a 64-bit pointer on Windows 64-bit. Acked-by: Samuel Rødal Change-Id: I7bbe83ce02b739eb04218ca4b6b478509347d515 Reviewed-by: Friedemann Kleint --- src/gui/kernel/qwindowdefs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qwindowdefs.h b/src/gui/kernel/qwindowdefs.h index 82cce0394b2..c2d7a2fe2fd 100644 --- a/src/gui/kernel/qwindowdefs.h +++ b/src/gui/kernel/qwindowdefs.h @@ -42,6 +42,7 @@ #ifndef QWINDOWDEFS_H #define QWINDOWDEFS_H +#include #include #include @@ -99,7 +100,7 @@ QT_END_HEADER -typedef unsigned long WId; +typedef QT_PREPEND_NAMESPACE(quintptr) WId; From 3cb871241a727193b17b1e0f28a5a9ba87f61d36 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Tue, 7 Feb 2012 10:19:43 +0100 Subject: [PATCH 039/406] Fix compilation with QT_NO_PRINTER. Change-Id: Iacfa47b8d384461ce08202a9a8e1642288cbe1e6 Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qplaintextedit.cpp | 2 ++ src/widgets/widgets/qtextedit.cpp | 2 ++ src/widgets/widgets/qwidgettextcontrol.cpp | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp index 674a8180529..de6cb6a283a 100644 --- a/src/widgets/widgets/qplaintextedit.cpp +++ b/src/widgets/widgets/qplaintextedit.cpp @@ -2519,11 +2519,13 @@ bool QPlainTextEdit::canPaste() const \sa QTextDocument::print() */ +#ifndef QT_NO_PRINTER void QPlainTextEdit::print(QPagedPaintDevice *printer) const { Q_D(const QPlainTextEdit); d->control->print(printer); } +#endif /*! \property QPlainTextEdit::tabChangesFocus \brief whether \gui Tab changes focus or is accepted as input diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp index 002d7860cd1..5273e16ab58 100644 --- a/src/widgets/widgets/qtextedit.cpp +++ b/src/widgets/widgets/qtextedit.cpp @@ -2264,11 +2264,13 @@ bool QTextEdit::canPaste() const \sa QTextDocument::print() */ +#ifndef QT_NO_PRINTER void QTextEdit::print(QPagedPaintDevice *printer) const { Q_D(const QTextEdit); d->control->print(printer); } +#endif /*! \property QTextEdit::tabChangesFocus \brief whether \gui Tab changes focus or is accepted as input diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index 96389b83333..a2c7915a5ea 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -2441,6 +2441,7 @@ bool QWidgetTextControl::isWordSelectionEnabled() const return d->wordSelectionEnabled; } +#ifndef QT_NO_PRINTER void QWidgetTextControl::print(QPagedPaintDevice *printer) const { Q_D(const QWidgetTextControl); @@ -2465,6 +2466,7 @@ void QWidgetTextControl::print(QPagedPaintDevice *printer) const doc->print(printer); delete tempDoc; } +#endif QMimeData *QWidgetTextControl::createMimeDataFromSelection() const { From 194d2ca5c3bbf7e5c06a5f8e4fbbbc8e1247f549 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Tue, 7 Feb 2012 14:23:50 +0100 Subject: [PATCH 040/406] Use Q_OS_WINCE instead of Q_WS_WINCE Window system defines have been deprecated, so use Q_OS_WINCE instead. Change-Id: I52059d0f854fe783ac20610ab248800c3e1e827c Reviewed-by: Oswald Buddenhagen Reviewed-by: Friedemann Kleint --- src/corelib/global/qt_windows.h | 2 +- src/corelib/io/qstandardpaths_win.cpp | 2 +- .../windows/qwindowsaccessibility.cpp | 8 +-- src/widgets/dialogs/qcolordialog.cpp | 6 +- src/widgets/dialogs/qdialog.cpp | 6 +- src/widgets/dialogs/qdialog.h | 4 +- src/widgets/dialogs/qdialog_p.h | 2 +- src/widgets/dialogs/qerrormessage.cpp | 10 +-- src/widgets/dialogs/qfiledialog.cpp | 2 +- src/widgets/dialogs/qfontdialog.cpp | 4 +- src/widgets/dialogs/qmessagebox.cpp | 18 +++--- src/widgets/dialogs/qmessagebox.h | 2 +- src/widgets/dialogs/qwizard.cpp | 4 +- src/widgets/kernel/qapplication.cpp | 14 ++-- src/widgets/kernel/qapplication.h | 4 +- src/widgets/kernel/qapplication_p.h | 2 +- src/widgets/kernel/qguiplatformplugin.cpp | 4 +- src/widgets/kernel/qwidget.cpp | 6 +- src/widgets/kernel/qwidget.h | 2 +- src/widgets/styles/qwindowsmobilestyle.cpp | 64 +++++++++---------- src/widgets/styles/qwindowsmobilestyle_p.h | 6 +- src/widgets/util/qsystemtrayicon.cpp | 10 +-- src/widgets/widgets/qdockwidget.cpp | 2 +- src/widgets/widgets/qeffects.cpp | 2 +- src/widgets/widgets/qmdisubwindow.cpp | 2 +- src/widgets/widgets/qmenu.cpp | 2 +- src/widgets/widgets/qmenu.h | 6 +- src/widgets/widgets/qmenu_p.h | 8 +-- src/widgets/widgets/qmenu_wince.cpp | 4 +- src/widgets/widgets/qmenubar.cpp | 22 +++---- src/widgets/widgets/qmenubar.h | 4 +- src/widgets/widgets/qmenubar_p.h | 10 +-- src/widgets/widgets/qscrollbar.cpp | 2 +- src/widgets/widgets/qtoolbar.cpp | 2 +- 34 files changed, 124 insertions(+), 124 deletions(-) diff --git a/src/corelib/global/qt_windows.h b/src/corelib/global/qt_windows.h index e4af46d939d..a63185b5a50 100644 --- a/src/corelib/global/qt_windows.h +++ b/src/corelib/global/qt_windows.h @@ -149,6 +149,6 @@ #ifndef LR_SHARED #define LR_SHARED 0 #endif -#endif // Q_WS_WINCE +#endif // Q_OS_WINCE #endif // QT_WINDOWS_H diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp index 310b1eb40d9..16bc7661706 100644 --- a/src/corelib/io/qstandardpaths_win.cpp +++ b/src/corelib/io/qstandardpaths_win.cpp @@ -177,7 +177,7 @@ QStringList QStandardPaths::standardLocations(StandardLocation type) // type-specific handling goes here -#ifndef Q_WS_WINCE +#ifndef Q_OS_WINCE static GetSpecialFolderPath SHGetSpecialFolderPath = resolveGetSpecialFolderPath(); if (SHGetSpecialFolderPath) { wchar_t path[MAX_PATH]; diff --git a/src/plugins/platforms/windows/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/qwindowsaccessibility.cpp index 8d117454106..2c49d8614d0 100644 --- a/src/plugins/platforms/windows/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/qwindowsaccessibility.cpp @@ -69,7 +69,7 @@ #include #if !defined(WINABLEAPI) -# if defined(Q_WS_WINCE) +# if defined(Q_OS_WINCE) # include # endif # include @@ -80,7 +80,7 @@ #include #endif -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE #include "qguifunctions_wince.h" #endif @@ -1344,7 +1344,7 @@ void QWindowsAccessibility::notifyAccessibilityUpdate(const QAccessibleEvent &ev typedef void (WINAPI *PtrNotifyWinEvent)(DWORD, HWND, LONG, LONG); -#if defined(Q_WS_WINCE) // ### TODO: check for NotifyWinEvent in CE 6.0 +#if defined(Q_OS_WINCE) // ### TODO: check for NotifyWinEvent in CE 6.0 // There is no user32.lib nor NotifyWinEvent for CE return; #else @@ -1382,7 +1382,7 @@ void QWindowsAccessibility::notifyAccessibilityUpdate(const QAccessibleEvent &ev ++eventNum; } -#endif // Q_WS_WINCE +#endif // Q_OS_WINCE } /* diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index e592f147049..4a91443d003 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -1060,7 +1060,7 @@ QColorShower::QColorShower(QColorDialog *parent) gl->setMargin(gl->spacing()); lab = new QColorShowLabel(this); -#ifndef Q_WS_WINCE +#ifndef Q_OS_WINCE #ifdef QT_SMALL_COLORDIALOG lab->setMinimumHeight(60); #endif @@ -1452,7 +1452,7 @@ void QColorDialogPrivate::init(const QColor &initial) leftLay = 0; -#if defined(Q_WS_WINCE) || defined(QT_SMALL_COLORDIALOG) +#if defined(Q_OS_WINCE) || defined(QT_SMALL_COLORDIALOG) smallDisplay = true; const int lumSpace = 20; #else @@ -1477,7 +1477,7 @@ void QColorDialogPrivate::init(const QColor &initial) leftLay->addWidget(lblBasicColors); leftLay->addWidget(standard); -#if !defined(Q_WS_WINCE) +#if !defined(Q_OS_WINCE) leftLay->addStretch(); #endif diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index f462a362ca3..861cbf902c9 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -404,8 +404,8 @@ void QDialogPrivate::resetModalitySetByOpen() resetModalityTo = -1; } -#if defined(Q_WS_WINCE) -#ifdef Q_WS_WINCE_WM +#if defined(Q_OS_WINCE) +#ifdef Q_OS_WINCE_WM void QDialogPrivate::_q_doneAction() { //Done... @@ -419,7 +419,7 @@ void QDialogPrivate::_q_doneAction() bool QDialog::event(QEvent *e) { bool result = QWidget::event(e); -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE if (e->type() == QEvent::OkRequest) { accept(); result = true; diff --git a/src/widgets/dialogs/qdialog.h b/src/widgets/dialogs/qdialog.h index 40bfbb63ee3..7d3052a782c 100644 --- a/src/widgets/dialogs/qdialog.h +++ b/src/widgets/dialogs/qdialog.h @@ -102,7 +102,7 @@ public Q_SLOTS: protected: QDialog(QDialogPrivate &, QWidget *parent, Qt::WindowFlags f = 0); -#if defined(Q_WS_WINCE) +#if defined(Q_OS_WINCE) bool event(QEvent *e); #endif void keyPressEvent(QKeyEvent *); @@ -119,7 +119,7 @@ private: Q_DISABLE_COPY(QDialog) Q_PRIVATE_SLOT(d_func(), void _q_platformRunNativeAppModalPanel()) -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM Q_PRIVATE_SLOT(d_func(), void _q_doneAction()) #endif }; diff --git a/src/widgets/dialogs/qdialog_p.h b/src/widgets/dialogs/qdialog_p.h index ca996004892..c40a885f86c 100644 --- a/src/widgets/dialogs/qdialog_p.h +++ b/src/widgets/dialogs/qdialog_p.h @@ -101,7 +101,7 @@ public: void hideDefault(); void resetModalitySetByOpen(); -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM void _q_doneAction(); #endif diff --git a/src/widgets/dialogs/qerrormessage.cpp b/src/widgets/dialogs/qerrormessage.cpp index 4993a6d80f5..84021d09889 100644 --- a/src/widgets/dialogs/qerrormessage.cpp +++ b/src/widgets/dialogs/qerrormessage.cpp @@ -61,7 +61,7 @@ #include #include -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE extern bool qt_wince_is_mobile(); //defined in qguifunctions_wince.cpp extern bool qt_wince_is_high_dpi(); //defined in qguifunctions_wince.cpp @@ -107,7 +107,7 @@ public: QSize QErrorMessageTextView::minimumSizeHint() const { -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE if (qt_wince_is_mobile()) if (qt_wince_is_high_dpi()) return QSize(200, 200); @@ -122,7 +122,7 @@ QSize QErrorMessageTextView::minimumSizeHint() const QSize QErrorMessageTextView::sizeHint() const { -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE if (qt_wince_is_mobile()) if (qt_wince_is_high_dpi()) return QSize(400, 200); @@ -132,7 +132,7 @@ QSize QErrorMessageTextView::sizeHint() const return QSize(300, 100); #else return QSize(250, 75); -#endif //Q_WS_WINCE +#endif //Q_OS_WINCE } /*! @@ -255,7 +255,7 @@ QErrorMessage::QErrorMessage(QWidget * parent) #endif -#if defined(Q_WS_WINCE) +#if defined(Q_OS_WINCE) d->ok->setFixedSize(0,0); #endif connect(d->ok, SIGNAL(clicked()), this, SLOT(accept())); diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index db13cfea0f1..ecedf8328f1 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -2002,7 +2002,7 @@ QString QFileDialog::getExistingDirectory(QWidget *parent, #if defined(Q_WS_WIN) if (QGuiApplicationPrivate::platformIntegration()->usePlatformNativeDialog() && !(args.options & DontUseNativeDialog) && (options & ShowDirsOnly) -#if defined(Q_WS_WINCE) +#if defined(Q_OS_WINCE) && qt_priv_ptr_valid #endif ) { diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp index 2402f2a9557..7e71cd7cd44 100644 --- a/src/widgets/dialogs/qfontdialog.cpp +++ b/src/widgets/dialogs/qfontdialog.cpp @@ -316,11 +316,11 @@ void QFontDialogPrivate::init() buttonBox->addButton(QDialogButtonBox::Cancel); QObject::connect(buttonBox, SIGNAL(rejected()), q, SLOT(reject())); -#if defined(Q_WS_WINCE) +#if defined(Q_OS_WINCE) q->resize(180, 120); #else q->resize(500, 360); -#endif // Q_WS_WINCE +#endif // Q_OS_WINCE sizeEdit->installEventFilter(q); familyList->installEventFilter(q); diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index 0f57fa67e1f..c6ffaa27886 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -189,7 +189,7 @@ public: int layoutMinimumWidth(); void retranslateStrings(); -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE void hideSpecial(); #endif @@ -307,7 +307,7 @@ void QMessageBoxPrivate::updateSize() return; QSize screenSize = QApplication::desktop()->availableGeometry(QCursor::pos()).size(); -#if defined(Q_WS_QWS) || defined(Q_WS_WINCE) +#if defined(Q_WS_QWS) || defined(Q_OS_WINCE) // the width of the screen, less the window border. int hardLimit = screenSize.width() - (q->frameGeometry().width() - q->geometry().width()); #else @@ -322,11 +322,11 @@ void QMessageBoxPrivate::updateSize() int softLimit = qMin(hardLimit, 500); #else // note: ideally on windows, hard and soft limits but it breaks compat -#ifndef Q_WS_WINCE +#ifndef Q_OS_WINCE int softLimit = qMin(screenSize.width()/2, 500); #else int softLimit = qMin(screenSize.width() * 3 / 4, 500); -#endif //Q_WS_WINCE +#endif //Q_OS_WINCE #endif if (informativeLabel) @@ -384,7 +384,7 @@ void QMessageBoxPrivate::updateSize() } -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE /*! \internal Hides special buttons which are rather shown in the title bar @@ -1239,7 +1239,7 @@ bool QMessageBox::event(QEvent *e) case QEvent::LanguageChange: d_func()->retranslateStrings(); break; -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE case QEvent::OkRequest: case QEvent::HelpRequest: { QString bName = @@ -1382,7 +1382,7 @@ void QMessageBox::keyPressEvent(QKeyEvent *e) QDialog::keyPressEvent(e); } -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE /*! \reimp */ @@ -1453,7 +1453,7 @@ void QMessageBox::showEvent(QShowEvent *e) Q_D(QMessageBox); if (d->autoAddOkButton) { addButton(Ok); -#if defined(Q_WS_WINCE) +#if defined(Q_OS_WINCE) d->hideSpecial(); #endif } @@ -1773,7 +1773,7 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title) QPixmap pm(QLatin1String(":/trolltech/qmessagebox/images/qtlogo-64.png")); if (!pm.isNull()) msgBox->setIconPixmap(pm); -#if defined(Q_WS_WINCE) +#if defined(Q_OS_WINCE) msgBox->setDefaultButton(msgBox->addButton(QMessageBox::Ok)); #endif diff --git a/src/widgets/dialogs/qmessagebox.h b/src/widgets/dialogs/qmessagebox.h index b42681a5657..37dfd96514d 100644 --- a/src/widgets/dialogs/qmessagebox.h +++ b/src/widgets/dialogs/qmessagebox.h @@ -143,7 +143,7 @@ public: QPushButton *addButton(StandardButton button); void removeButton(QAbstractButton *button); -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE void setVisible(bool visible); #endif diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp index 629b6828b7a..324831ea52d 100644 --- a/src/widgets/dialogs/qwizard.cpp +++ b/src/widgets/dialogs/qwizard.cpp @@ -69,7 +69,7 @@ #include "private/qdialog_p.h" #include -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE extern bool qt_wince_is_mobile(); //defined in qguifunctions_wce.cpp #endif @@ -2178,7 +2178,7 @@ QWizard::QWizard(QWidget *parent, Qt::WindowFlags flags) { Q_D(QWizard); d->init(); -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE if (!qt_wince_is_mobile()) setWindowFlags(windowFlags() & ~Qt::WindowOkButtonHint); #endif diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index ae15c9f62ac..9bef6f8f710 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -104,7 +104,7 @@ #include "qlibrary.h" #endif -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE #include "qdatetime.h" #include "qguifunctions_wince.h" extern bool qt_wince_is_smartphone(); //qguifunctions_wince.cpp @@ -122,7 +122,7 @@ extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp static void initResources() { -#if defined(Q_WS_WINCE) +#if defined(Q_OS_WINCE) Q_INIT_RESOURCE_EXTERN(qstyle_wince) Q_INIT_RESOURCE(qstyle_wince); #else @@ -140,7 +140,7 @@ Q_CORE_EXPORT void qt_call_post_routines(); QApplicationPrivate *QApplicationPrivate::self = 0; -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE int QApplicationPrivate::autoMaximizeThreshold = -1; bool QApplicationPrivate::autoSipEnabled = false; #else @@ -873,7 +873,7 @@ void QApplicationPrivate::initialize() if (qgetenv("QT_USE_NATIVE_WINDOWS").toInt() > 0) q->setAttribute(Qt::AA_NativeWindows); -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE #ifdef QT_AUTO_MAXIMIZE_THRESHOLD autoMaximizeThreshold = QT_AUTO_MAXIMIZE_THRESHOLD; #else @@ -882,7 +882,7 @@ void QApplicationPrivate::initialize() else autoMaximizeThreshold = -1; #endif //QT_AUTO_MAXIMIZE_THRESHOLD -#endif //Q_WS_WINCE +#endif //Q_OS_WINCE #ifndef QT_NO_WHEELEVENT QApplicationPrivate::wheel_scroll_lines = 3; @@ -1202,7 +1202,7 @@ bool QApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventLis The default is platform dependent. */ -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE void QApplication::setAutoMaximizeThreshold(const int threshold) { QApplicationPrivate::autoMaximizeThreshold = threshold; @@ -3993,7 +3993,7 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e) if (receiver->isWidgetType()) { QWidget *widget = static_cast(receiver); -#if !defined(Q_WS_WINCE) || (defined(GWES_ICONCURS) && !defined(QT_NO_CURSOR)) +#if !defined(Q_OS_WINCE) || (defined(GWES_ICONCURS) && !defined(QT_NO_CURSOR)) // toggle HasMouse widget state on enter and leave if ((e->type() == QEvent::Enter || e->type() == QEvent::DragEnter) && (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == widget->window())) diff --git a/src/widgets/kernel/qapplication.h b/src/widgets/kernel/qapplication.h index b613b0f7c03..bace73e072d 100644 --- a/src/widgets/kernel/qapplication.h +++ b/src/widgets/kernel/qapplication.h @@ -89,7 +89,7 @@ class Q_WIDGETS_EXPORT QApplication : public QGuiApplication #ifndef QT_NO_STYLE_STYLESHEET Q_PROPERTY(QString styleSheet READ styleSheet WRITE setStyleSheet) #endif -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE Q_PROPERTY(int autoMaximizeThreshold READ autoMaximizeThreshold WRITE setAutoMaximizeThreshold) #endif Q_PROPERTY(bool autoSipEnabled READ autoSipEnabled WRITE setAutoSipEnabled) @@ -245,7 +245,7 @@ public Q_SLOTS: #ifndef QT_NO_STYLE_STYLESHEET void setStyleSheet(const QString& sheet); #endif -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE void setAutoMaximizeThreshold(const int threshold); int autoMaximizeThreshold() const; #endif diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index 601c5114386..d9d184d51ae 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -187,7 +187,7 @@ public: static bool qws_apply_settings(); static QWidget *findWidget(const QObjectList&, const QPoint &, bool rec); #endif -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE static int autoMaximizeThreshold; #endif static bool autoSipEnabled; diff --git a/src/widgets/kernel/qguiplatformplugin.cpp b/src/widgets/kernel/qguiplatformplugin.cpp index f5f00cc7693..540499887e4 100644 --- a/src/widgets/kernel/qguiplatformplugin.cpp +++ b/src/widgets/kernel/qguiplatformplugin.cpp @@ -50,7 +50,7 @@ #include "qplatformdefs.h" #include "qicon.h" -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE #include "qguifunctions_wince.h" extern bool qt_wince_is_smartphone(); //qguifunctions_wince.cpp extern bool qt_wince_is_mobile(); //qguifunctions_wince.cpp @@ -130,7 +130,7 @@ QGuiPlatformPlugin::~QGuiPlatformPlugin() {} /* return the string key to be used by default the application */ QString QGuiPlatformPlugin::styleName() { -#if defined(Q_WS_WIN) && defined(Q_WS_WINCE) +#if defined(Q_WS_WIN) && defined(Q_OS_WINCE) if (qt_wince_is_smartphone() || qt_wince_is_pocket_pc()) return QLatin1String("WindowsMobile"); else diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 4709a89d273..008f0391bc5 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1095,7 +1095,7 @@ void QWidgetPrivate::adjustFlags(Qt::WindowFlags &flags, QWidget *w) if (customize) ; // don't modify window flags if the user explicitly set them. else if (type == Qt::Dialog || type == Qt::Sheet) -#ifndef Q_WS_WINCE +#ifndef Q_OS_WINCE flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowContextHelpButtonHint | Qt::WindowCloseButtonHint; #else flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint; @@ -4150,7 +4150,7 @@ const QPalette &QWidget::palette() const if (!isEnabled()) { data->pal.setCurrentColorGroup(QPalette::Disabled); } else if ((!isVisible() || isActiveWindow()) -#if defined(Q_OS_WIN) && !defined(Q_WS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !QApplicationPrivate::isBlockedByModal(const_cast(this)) #endif ) { @@ -7579,7 +7579,7 @@ QSize QWidgetPrivate::adjustedSize() const #else // all others QRect screen = QApplication::desktop()->screenGeometry(q->pos()); #endif -#if defined (Q_WS_WINCE) +#if defined (Q_OS_WINCE) s.setWidth(qMin(s.width(), screen.width())); s.setHeight(qMin(s.height(), screen.height())); #else diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index 0f13d0b7f6f..2bad2e9f1e6 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -481,7 +481,7 @@ public Q_SLOTS: virtual void setVisible(bool visible); inline void setHidden(bool hidden) { setVisible(!hidden); } -#ifndef Q_WS_WINCE +#ifndef Q_OS_WINCE inline void show() { setVisible(true); } #else void show(); diff --git a/src/widgets/styles/qwindowsmobilestyle.cpp b/src/widgets/styles/qwindowsmobilestyle.cpp index 284d42dacc9..86513c82677 100644 --- a/src/widgets/styles/qwindowsmobilestyle.cpp +++ b/src/widgets/styles/qwindowsmobilestyle.cpp @@ -72,13 +72,13 @@ #include "qdebug.h" #include "qtabwidget.h" -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE #include "qt_windows.h" #include "qguifunctions_wince.h" extern bool qt_wince_is_high_dpi(); //defined in qguifunctions_wince.cpp extern bool qt_wince_is_smartphone(); //defined in qguifunctions_wince.cpp extern bool qt_wince_is_windows_mobile_65(); //defined in qguifunctions_wince.cpp -#endif // Q_WS_WINCE +#endif // Q_OS_WINCE #include "qstylehelper_p.h" @@ -667,7 +667,7 @@ static const char * const min_small_xpm[] = { " ++++++++++++ ", " "}; -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM static char * sbhandleup_xpm[] = { "26 41 45 1", @@ -4033,12 +4033,12 @@ void tintImage(QImage *image, QColor color, qreal saturation) } } -#endif //Q_WS_WINCE_WM +#endif //Q_OS_WINCE_WM enum QSliderDirection { SliderUp, SliderDown, SliderLeft, SliderRight }; -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM void QWindowsMobileStylePrivate::tintImagesButton(QColor color) { @@ -4096,11 +4096,11 @@ void QWindowsMobileStylePrivate::tintListViewHighlight(QColor color) } } -#endif //Q_WS_WINCE_WM +#endif //Q_OS_WINCE_WM void QWindowsMobileStylePrivate::setupWindowsMobileStyle65() { -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM wm65 = qt_wince_is_windows_mobile_65(); if (wm65) { imageScrollbarHandleUp = QImage(sbhandleup_xpm); @@ -4119,13 +4119,13 @@ void QWindowsMobileStylePrivate::setupWindowsMobileStyle65() } tintImagesHigh(Qt::blue); } -#endif //Q_WS_WINCE_WM +#endif //Q_OS_WINCE_WM } void QWindowsMobileStylePrivate::drawTabBarTab(QPainter *painter, const QStyleOptionTab *tab) { #ifndef QT_NO_TABBAR -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM if (wm65) { tintImagesButton(tab->palette.button().color()); QRect r; @@ -4154,7 +4154,7 @@ void QWindowsMobileStylePrivate::drawTabBarTab(QPainter *painter, const QStyleOp //imageTabBarBig return; } -#endif //Q_WS_WINCE_WM +#endif //Q_OS_WINCE_WM painter->save(); painter->setPen(tab->palette.shadow().color()); if (doubleControls) { @@ -4216,7 +4216,7 @@ void QWindowsMobileStylePrivate::drawTabBarTab(QPainter *painter, const QStyleOp void QWindowsMobileStylePrivate::drawPanelItemViewSelected(QPainter *painter, const QStyleOptionViewItemV4 *option, QRect rect) { -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM if (wm65) { QRect r; if (rect.isValid()) @@ -4257,7 +4257,7 @@ void QWindowsMobileStylePrivate::drawPanelItemViewSelected(QPainter *painter, co } return; } -#endif //Q_WS_WINCE_WM +#endif //Q_OS_WINCE_WM QPalette::ColorGroup cg = option->state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; @@ -4269,7 +4269,7 @@ void QWindowsMobileStylePrivate::drawPanelItemViewSelected(QPainter *painter, co void QWindowsMobileStylePrivate::drawScrollbarGrip(QPainter *p, QStyleOptionSlider *newScrollbar, const QStyleOptionComplex *option, bool drawCompleteFrame) { -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM if (wm65) { if (newScrollbar->orientation == Qt::Horizontal) { QTransform transform; @@ -4361,7 +4361,7 @@ void QWindowsMobileStylePrivate::drawScrollbarGrip(QPainter *p, QStyleOptionSlid void QWindowsMobileStylePrivate::drawScrollbarHandleUp(QPainter *p, QStyleOptionSlider *opt, bool completeFrame, bool ) { -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM if (wm65) { tintImagesHigh(opt->palette.highlight().color()); QRect r = opt->rect; @@ -4380,7 +4380,7 @@ void QWindowsMobileStylePrivate::drawScrollbarHandleUp(QPainter *p, QStyleOption } return ; } -#endif //Q_WS_WINCE_WM +#endif //Q_OS_WINCE_WM QBrush fill = opt->palette.button(); if (opt->state & QStyle::State_Sunken) @@ -4418,7 +4418,7 @@ void QWindowsMobileStylePrivate::drawScrollbarHandleUp(QPainter *p, QStyleOption void QWindowsMobileStylePrivate::drawScrollbarHandleDown(QPainter *p, QStyleOptionSlider *opt, bool completeFrame, bool secondScrollBar) { #ifndef QT_NO_SCROLLBAR -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM if (wm65) { tintImagesHigh(opt->palette.highlight().color()); QRect r = opt->rect; @@ -4437,7 +4437,7 @@ void QWindowsMobileStylePrivate::drawScrollbarHandleDown(QPainter *p, QStyleOpti } return ; } -#endif //Q_WS_WINCE_WM +#endif //Q_OS_WINCE_WM QBrush fill = opt->palette.button(); if (opt->state & QStyle::State_Sunken) @@ -4520,13 +4520,13 @@ QWindowsMobileStyle::QWindowsMobileStyle() : QWindowsStyle(*new QWindowsMobileSt QWindowsMobileStylePrivate::QWindowsMobileStylePrivate() :QWindowsStylePrivate() { -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE doubleControls = qt_wince_is_high_dpi(); smartphone = qt_wince_is_smartphone(); #else doubleControls = false; smartphone = false; -#endif //Q_WS_WINCE +#endif //Q_OS_WINCE #ifndef QT_NO_IMAGEFORMAT_XPM @@ -5215,7 +5215,7 @@ void QWindowsMobileStyle::drawPrimitive(PrimitiveElement element, const QStyleOp } switch (tab->shape) { case QTabBar::RoundedNorth: -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM if (!d->wm65) #endif { @@ -5226,7 +5226,7 @@ void QWindowsMobileStyle::drawPrimitive(PrimitiveElement element, const QStyleOp } break; case QTabBar::RoundedSouth: -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM if (!d->wm65) #endif { @@ -5237,13 +5237,13 @@ void QWindowsMobileStyle::drawPrimitive(PrimitiveElement element, const QStyleOp } break; case QTabBar::RoundedEast: -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM if (!d->wm65) #endif painter->drawLine(rect.topRight(), rect.bottomRight()); break; case QTabBar::RoundedWest: -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM if (!d->wm65) #endif painter->drawLine(rect.topLeft(), rect.bottomLeft()); @@ -6458,7 +6458,7 @@ QSize QWindowsMobileStyle::sizeFromContents(ContentsType type, const QStyleOptio newSize += QSize(4, 2); break; #ifndef QT_NO_ITEMVIEWS -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM case CT_ItemViewItem: if (d_func()->wm65) if (d_func()->doubleControls) @@ -6466,7 +6466,7 @@ QSize QWindowsMobileStyle::sizeFromContents(ContentsType type, const QStyleOptio else newSize.setHeight(23); break; -#endif //Q_WS_WINCE_WM +#endif //Q_OS_WINCE_WM #endif //QT_NO_ITEMVIEWS default: break; @@ -6508,7 +6508,7 @@ QRect QWindowsMobileStyle::subElementRect(SubElement element, const QStyleOption #endif // QT_NO_SLIDER #ifndef QT_NO_ITEMVIEWS case SE_ItemViewItemFocusRect: -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM if (d->wm65) rect = QRect(); #endif @@ -6533,13 +6533,13 @@ QRect QWindowsMobileStyle::subControlRect(ComplexControl control, const QStyleOp float stretchFactor = 1.4f; int sliderButtonExtentDir = int (sliderButtonExtent * stretchFactor); -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM if (d->wm65) { sliderButtonExtent = d->imageScrollbarHandleUp.width(); sliderButtonExtentDir = d->imageScrollbarHandleUp.height(); } -#endif //Q_WS_WINCE_WM +#endif //Q_OS_WINCE_WM int sliderlen; int maxlen = ((scrollbar->orientation == Qt::Horizontal) ? @@ -7067,7 +7067,7 @@ int QWindowsMobileStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, co d->doubleControls ? ret = 42 : ret = 21; break; case PM_ScrollBarSliderMin: -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM if (d->wm65) #else if (false) @@ -7085,7 +7085,7 @@ int QWindowsMobileStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, co else d->doubleControls ? ret = 25 : ret = 13; -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM if (d->wm65) #else if (false) @@ -7239,10 +7239,10 @@ QPixmap QWindowsMobileStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPi switch (iconMode) { case QIcon::Selected: { -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM if (d_func()->wm65) return pixmap; -#endif //Q_WS_WINCE_WM +#endif //Q_OS_WINCE_WM QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32); int imgh = img.height(); int imgw = img.width(); diff --git a/src/widgets/styles/qwindowsmobilestyle_p.h b/src/widgets/styles/qwindowsmobilestyle_p.h index d536afe50e6..0e5cf18548e 100644 --- a/src/widgets/styles/qwindowsmobilestyle_p.h +++ b/src/widgets/styles/qwindowsmobilestyle_p.h @@ -71,7 +71,7 @@ public: QWindowsMobileStylePrivate(); bool doubleControls; bool smartphone; -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM bool wm65; #endif @@ -95,7 +95,7 @@ public: void setupWindowsMobileStyle65(); -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM //Windows Mobile 6.5 images QImage imageScrollbarHandleUp; QImage imageScrollbarHandleDown; @@ -119,7 +119,7 @@ public: void tintImagesButton(QColor color); void tintListViewHighlight(QColor color); -#endif //Q_WS_WINCE_WM +#endif //Q_OS_WINCE_WM void drawScrollbarHandleUp(QPainter *p, QStyleOptionSlider *opt, bool completeFrame = false, bool secondScrollBar = false); void drawScrollbarHandleDown(QPainter *p, QStyleOptionSlider *opt, bool completeFrame = false, bool secondScrollBar = false); diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp index 321323733b4..bed8dc2eaea 100644 --- a/src/widgets/util/qsystemtrayicon.cpp +++ b/src/widgets/util/qsystemtrayicon.cpp @@ -434,13 +434,13 @@ QBalloonTip::QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title titleLabel->setText(title); QFont f = titleLabel->font(); f.setBold(true); -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE f.setPointSize(f.pointSize() - 2); #endif titleLabel->setFont(f); titleLabel->setTextFormat(Qt::PlainText); // to maintain compat with windows -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE const int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize); const int closeButtonSize = style()->pixelMetric(QStyle::PM_SmallIconSize) - 2; #else @@ -456,7 +456,7 @@ QBalloonTip::QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title QObject::connect(closeButton, SIGNAL(clicked()), this, SLOT(close())); QLabel *msgLabel = new QLabel; -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE f.setBold(false); msgLabel->setFont(f); #endif @@ -466,7 +466,7 @@ QBalloonTip::QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title msgLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft); // smart size for the message label -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE int limit = QApplication::desktop()->availableGeometry(msgLabel).size().width() / 2; #else int limit = QApplication::desktop()->availableGeometry(msgLabel).size().width() / 3; @@ -481,7 +481,7 @@ QBalloonTip::QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title control->document()->setDefaultTextOption(opt); } } -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE // Make sure that the text isn't wrapped "somewhere" in the balloon widget // in the case that we have a long title label. setMaximumWidth(limit); diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index 6da7605f4cc..a90c754cee4 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -207,7 +207,7 @@ bool QDockWidgetLayout::nativeWindowDeco() const bool QDockWidgetLayout::nativeWindowDeco(bool floating) const { -#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_WINCE) +#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_WINCE) Q_UNUSED(floating); return false; #else diff --git a/src/widgets/widgets/qeffects.cpp b/src/widgets/widgets/qeffects.cpp index 486905658d1..84823675dd3 100644 --- a/src/widgets/widgets/qeffects.cpp +++ b/src/widgets/widgets/qeffects.cpp @@ -111,7 +111,7 @@ QAlphaWidget::QAlphaWidget(QWidget* w, Qt::WindowFlags f) QAlphaWidget::~QAlphaWidget() { -#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE) +#if defined(Q_WS_WIN) && !defined(Q_OS_WINCE) // Restore user-defined opacity value if (widget) widget->setWindowOpacity(1); diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp index cca39a65025..b42fedf0be7 100644 --- a/src/widgets/widgets/qmdisubwindow.cpp +++ b/src/widgets/widgets/qmdisubwindow.cpp @@ -1772,7 +1772,7 @@ bool QMdiSubWindowPrivate::drawTitleBarWhenMaximized() const if (isChildOfTabbedQMdiArea(q)) return false; -#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC) || defined(Q_WS_WINCE_WM) +#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC) || defined(Q_OS_WINCE_WM) return true; #else if (q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q)) diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 1ad697c4304..a4f9dc9c963 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -2882,7 +2882,7 @@ void QMenu::actionEvent(QActionEvent *e) d->platformMenu->syncAction(e->action()); } -#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR) +#if defined(Q_OS_WINCE) && !defined(QT_NO_MENUBAR) if (!d->wce_menu) d->wce_menu = new QMenuPrivate::QWceMenuPrivate; if (e->type() == QEvent::ActionAdded) diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h index fa0542b6c27..182b0bc2b85 100644 --- a/src/widgets/widgets/qmenu.h +++ b/src/widgets/widgets/qmenu.h @@ -48,7 +48,7 @@ #include #include -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE #include // for HMENU #endif @@ -136,7 +136,7 @@ public: void setNoReplayFor(QWidget *widget); QPlatformMenu *platformMenu(); -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE HMENU wceMenu(); #endif @@ -170,7 +170,7 @@ protected: bool focusNextPrevChild(bool next); void initStyleOption(QStyleOptionMenuItem *option, const QAction *action) const; -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE QAction* wceCommands(uint command); #endif diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index af236c1c8f1..ee6e62653fc 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -68,7 +68,7 @@ QT_BEGIN_NAMESPACE class QTornOffMenu; class QEventLoop; -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE struct QWceMenuAction { uint command; QPointer action; @@ -91,7 +91,7 @@ public: scroll(0), eventLoop(0), tearoff(0), tornoff(0), tearoffHighlighted(0), hasCheckableItems(0), sloppyAction(0), doChildEffects(false), platformMenu(0) -#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR) +#if defined(Q_OS_WINCE) && !defined(QT_NO_MENUBAR) ,wce_menu(0) #endif { } @@ -99,7 +99,7 @@ public: { delete scroll; delete platformMenu; -#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR) +#if defined(Q_OS_WINCE) && !defined(QT_NO_MENUBAR) delete wce_menu; #endif } @@ -228,7 +228,7 @@ public: QPointer actionAboutToTrigger; -#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR) +#if defined(Q_OS_WINCE) && !defined(QT_NO_MENUBAR) struct QWceMenuPrivate { QList actionItems; HMENU menuHandle; diff --git a/src/widgets/widgets/qmenu_wince.cpp b/src/widgets/widgets/qmenu_wince.cpp index ae90d23b28e..11ae2844f88 100644 --- a/src/widgets/widgets/qmenu_wince.cpp +++ b/src/widgets/widgets/qmenu_wince.cpp @@ -40,7 +40,7 @@ ****************************************************************************/ //Native menubars are only supported for Windows Mobile not the standard SDK/generic WinCE -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE #include "qmenu.h" #include "qt_windows.h" #include "qapplication.h" @@ -665,4 +665,4 @@ void QMenuBarPrivate::QWceMenuBarPrivate::rebuild() QT_END_NAMESPACE #endif //QT_NO_MENUBAR -#endif //Q_WS_WINCE +#endif //Q_OS_WINCE diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index f1269fde0f8..7d6c1d8df9c 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -64,7 +64,7 @@ #include "qmenubar_p.h" #include "qdebug.h" -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE extern bool qt_wince_is_mobile(); //defined in qguifunctions_wce.cpp #endif @@ -719,7 +719,7 @@ void QMenuBarPrivate::init() if (platformMenuBar) q->hide(); -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE if (qt_wince_is_mobile()) { wceCreateMenuBar(q->parentWidget()); if(wce_menubar) @@ -783,7 +783,7 @@ QMenuBar::~QMenuBar() delete d->platformMenuBar; d->platformMenuBar = 0; -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE Q_D(QMenuBar); if (qt_wince_is_mobile()) d->wceDestroyMenuBar(); @@ -1245,7 +1245,7 @@ void QMenuBar::actionEvent(QActionEvent *e) if (d->platformMenuBar) { QPlatformMenuBar *nativeMenuBar = d->platformMenuBar; -#if defined(Q_WS_WINCE) +#if defined(Q_OS_WINCE) QMenuBarPrivate::QWceMenuBarPrivate *nativeMenuBar = d->wce_menubar; #endif if (!nativeMenuBar) @@ -1338,7 +1338,7 @@ void QMenuBarPrivate::handleReparent() if (platformMenuBar) platformMenuBar->handleReparent(newParent); -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE if (qt_wince_is_mobile() && wce_menubar) wce_menubar->rebuild(); #endif @@ -1526,7 +1526,7 @@ QRect QMenuBar::actionGeometry(QAction *act) const QSize QMenuBar::minimumSizeHint() const { Q_D(const QMenuBar); -#if defined(Q_OS_MAC) || defined(Q_WS_WINCE) +#if defined(Q_OS_MAC) || defined(Q_OS_WINCE) const bool as_gui_menubar = !isNativeMenuBar(); #else const bool as_gui_menubar = true; @@ -1582,7 +1582,7 @@ QSize QMenuBar::minimumSizeHint() const QSize QMenuBar::sizeHint() const { Q_D(const QMenuBar); -#if defined(Q_OS_MAC) || defined(Q_WS_WINCE) +#if defined(Q_OS_MAC) || defined(Q_OS_WINCE) const bool as_gui_menubar = !isNativeMenuBar(); #else const bool as_gui_menubar = true; @@ -1641,7 +1641,7 @@ QSize QMenuBar::sizeHint() const int QMenuBar::heightForWidth(int) const { Q_D(const QMenuBar); -#if defined(Q_OS_MAC) || defined(Q_WS_WINCE) +#if defined(Q_OS_MAC) || defined(Q_OS_WINCE) const bool as_gui_menubar = !isNativeMenuBar(); #else const bool as_gui_menubar = true; @@ -1838,13 +1838,13 @@ QPlatformMenuBar *QMenuBar::platformMenuBar() \sa defaultAction() */ -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE void QMenuBar::setDefaultAction(QAction *act) { Q_D(QMenuBar); if (d->defaultAction == act) return; -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE if (qt_wince_is_mobile()) if (d->defaultAction) { disconnect(d->defaultAction, SIGNAL(changed()), this, SLOT(_q_updateDefaultAction())); @@ -1852,7 +1852,7 @@ void QMenuBar::setDefaultAction(QAction *act) } #endif d->defaultAction = act; -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE if (qt_wince_is_mobile()) if (d->defaultAction) { connect(d->defaultAction, SIGNAL(changed()), this, SLOT(_q_updateDefaultAction())); diff --git a/src/widgets/widgets/qmenubar.h b/src/widgets/widgets/qmenubar.h index b20682ef6c6..98185265438 100644 --- a/src/widgets/widgets/qmenubar.h +++ b/src/widgets/widgets/qmenubar.h @@ -102,7 +102,7 @@ public: void setCornerWidget(QWidget *w, Qt::Corner corner = Qt::TopRightCorner); QWidget *cornerWidget(Qt::Corner corner = Qt::TopRightCorner) const; -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE void setDefaultAction(QAction *); QAction *defaultAction() const; @@ -145,7 +145,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_internalShortcutActivated(int)) Q_PRIVATE_SLOT(d_func(), void _q_updateLayout()) -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE Q_PRIVATE_SLOT(d_func(), void _q_updateDefaultAction()) #endif diff --git a/src/widgets/widgets/qmenubar_p.h b/src/widgets/widgets/qmenubar_p.h index a15a1e432e4..1af94bb236b 100644 --- a/src/widgets/widgets/qmenubar_p.h +++ b/src/widgets/widgets/qmenubar_p.h @@ -57,7 +57,7 @@ #include "QtWidgets/qstyleoption.h" #include // Mac needs what in this file! -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE #include "qguifunctions_wince.h" #endif @@ -73,14 +73,14 @@ public: closePopupMode(0), defaultPopDown(1), popupState(0), keyboardState(0), altPressed(0), nativeMenuBar(-1), doChildEffects(false), platformMenuBar(0) -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE , wce_menubar(0), wceClassicMenu(false) #endif { } ~QMenuBarPrivate() { delete platformMenuBar; -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE delete wce_menubar; #endif } @@ -124,7 +124,7 @@ public: void _q_internalShortcutActivated(int); void _q_updateLayout(); -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE void _q_updateDefaultAction(); #endif @@ -150,7 +150,7 @@ public: QBasicTimer autoReleaseTimer; QPlatformMenuBar *platformMenuBar; -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE void wceCreateMenuBar(QWidget *); void wceDestroyMenuBar(); struct QWceMenuBarPrivate { diff --git a/src/widgets/widgets/qscrollbar.cpp b/src/widgets/widgets/qscrollbar.cpp index bca5517d8ab..cb3126e5665 100644 --- a/src/widgets/widgets/qscrollbar.cpp +++ b/src/widgets/widgets/qscrollbar.cpp @@ -387,7 +387,7 @@ void QScrollBarPrivate::init() q->setAttribute(Qt::WA_WState_OwnSizePolicy, false); q->setAttribute(Qt::WA_OpaquePaintEvent); -#if !defined(QT_NO_CONTEXTMENU) && defined(Q_WS_WINCE) +#if !defined(QT_NO_CONTEXTMENU) && defined(Q_OS_WINCE) if (!q->style()->styleHint(QStyle::SH_ScrollBar_ContextMenu, 0, q)) { q->setContextMenuPolicy(Qt::PreventContextMenu); } diff --git a/src/widgets/widgets/qtoolbar.cpp b/src/widgets/widgets/qtoolbar.cpp index c9fe4f7cc28..84cb5fd10c2 100644 --- a/src/widgets/widgets/qtoolbar.cpp +++ b/src/widgets/widgets/qtoolbar.cpp @@ -1163,7 +1163,7 @@ bool QToolBar::event(QEvent *event) if (d->mouseMoveEvent(static_cast(event))) return true; break; -#ifdef Q_WS_WINCE +#ifdef Q_OS_WINCE case QEvent::ContextMenu: { QContextMenuEvent* contextMenuEvent = static_cast(event); From 7e4232f10a9c3bace9bf9864fac16d186d23bce7 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Tue, 7 Feb 2012 08:08:04 +0100 Subject: [PATCH 041/406] Fix src/concurrent/concurrent.pro First, heed the warning from qmake and add load(qt_module) to the top of src/concurrent/concurrent.pro Second, qtconcurrentversion.h is in src/concurrent, not src/xml Change-Id: If4fc55ac2fe21c093023b377195ed82a54d8c963 Reviewed-by: Friedemann Kleint Reviewed-by: Oswald Buddenhagen --- src/concurrent/concurrent.pro | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/concurrent/concurrent.pro b/src/concurrent/concurrent.pro index a9482af0572..8ef3c5ca590 100644 --- a/src/concurrent/concurrent.pro +++ b/src/concurrent/concurrent.pro @@ -1,3 +1,5 @@ +load(qt_module) + TARGET = QtConcurrent QPRO_PWD = $$PWD QT = core-private @@ -12,7 +14,7 @@ unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore load(qt_module_config) -HEADERS += $$QT_SOURCE_TREE/src/xml/qtconcurrentversion.h +HEADERS += $$QT_SOURCE_TREE/src/concurrent/qtconcurrentversion.h PRECOMPILED_HEADER = ../corelib/global/qt_pch.h From 1247683d40c3fbb4b7ce50cc5361e2398b45875e Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Mon, 6 Feb 2012 23:41:27 +0100 Subject: [PATCH 042/406] QSqlTableModelPrivate: deduplicate field stripping logic Change-Id: Ic969a192644e84d78558da0f19e588033e4af43d Reviewed-by: Yunqiao Yin --- src/sql/models/qsqlrelationaltablemodel.cpp | 4 +--- src/sql/models/qsqltablemodel.cpp | 7 ++++++- src/sql/models/qsqltablemodel_p.h | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/sql/models/qsqlrelationaltablemodel.cpp b/src/sql/models/qsqlrelationaltablemodel.cpp index e12976ef245..3a8c12085f5 100644 --- a/src/sql/models/qsqlrelationaltablemodel.cpp +++ b/src/sql/models/qsqlrelationaltablemodel.cpp @@ -299,9 +299,7 @@ void QSqlRelationalTableModelPrivate::revertCachedRow(int row) int QSqlRelationalTableModelPrivate::nameToIndex(const QString &name) const { - QString fieldname = name; - if (db.driver()->isIdentifierEscaped(fieldname, QSqlDriver::FieldName)) - fieldname = db.driver()->stripDelimiters(fieldname, QSqlDriver::FieldName); + QString fieldname = strippedFieldName(name); int idx = baseRec.indexOf(fieldname); if (idx == -1) { // If the name is an alias we can find it here. diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index ff325334408..0d062e250ff 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -67,11 +67,16 @@ QSqlRecord QSqlTableModelPrivate::record(const QVector &values) const } int QSqlTableModelPrivate::nameToIndex(const QString &name) const +{ + return rec.indexOf(strippedFieldName(name)); +} + +QString QSqlTableModelPrivate::strippedFieldName(const QString &name) const { QString fieldname = name; if (db.driver()->isIdentifierEscaped(fieldname, QSqlDriver::FieldName)) fieldname = db.driver()->stripDelimiters(fieldname, QSqlDriver::FieldName); - return rec.indexOf(fieldname); + return fieldname; } void QSqlTableModelPrivate::initRecordAndPrimaryIndex() diff --git a/src/sql/models/qsqltablemodel_p.h b/src/sql/models/qsqltablemodel_p.h index 56fd839a0ce..15cbe8ef7a1 100644 --- a/src/sql/models/qsqltablemodel_p.h +++ b/src/sql/models/qsqltablemodel_p.h @@ -77,6 +77,7 @@ public: const QSqlRecord &rec, const QSqlRecord &whereValues); virtual void revertCachedRow(int row); virtual int nameToIndex(const QString &name) const; + QString strippedFieldName(const QString &name) const; void initRecordAndPrimaryIndex(); QSqlDatabase db; From 763d0a55e912689f2c0cbad41e81cdc3dbf402d0 Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Mon, 11 Jul 2011 14:41:00 +0200 Subject: [PATCH 043/406] QSqlTableModelPrivate::ModifiedRow guard private data Even though ModifiedRow is not part of the public API, guarding its data helps make clear the intended patterns of use. "op" and "primaryValues" are read-only after construction. setValue() encourages maintainers to let ModifiedRow manage the "generated" flags of the record. The primeInsert() signal still exposes the actual record, including the "generated" flags, which is the justification for recRef(). Change-Id: I16d1610a8f9233af78b90662b08706b48ea19c41 Reviewed-by: Yunqiao Yin --- src/sql/models/qsqlrelationaltablemodel.cpp | 6 +- src/sql/models/qsqltablemodel.cpp | 70 ++++++++++----------- src/sql/models/qsqltablemodel_p.h | 24 ++++--- 3 files changed, 53 insertions(+), 47 deletions(-) diff --git a/src/sql/models/qsqlrelationaltablemodel.cpp b/src/sql/models/qsqlrelationaltablemodel.cpp index 3a8c12085f5..75bf3ebe43d 100644 --- a/src/sql/models/qsqlrelationaltablemodel.cpp +++ b/src/sql/models/qsqlrelationaltablemodel.cpp @@ -438,9 +438,9 @@ QVariant QSqlRelationalTableModel::data(const QModelIndex &index, int role) cons //already have the correct display value. if (d->strategy != OnFieldChange) { const QSqlTableModelPrivate::ModifiedRow row = d->cache.value(index.row()); - if (row.op != QSqlTableModelPrivate::None && row.rec.isGenerated(index.column())) { - if (d->strategy == OnManualSubmit || row.op != QSqlTableModelPrivate::Delete) { - QVariant v = row.rec.value(index.column()); + if (row.op() != QSqlTableModelPrivate::None && row.rec().isGenerated(index.column())) { + if (d->strategy == OnManualSubmit || row.op() != QSqlTableModelPrivate::Delete) { + QVariant v = row.rec().value(index.column()); if (v.isValid()) return relation.dictionary[v.toString()]; } diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 0d062e250ff..46d493b7264 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -106,7 +106,7 @@ void QSqlTableModelPrivate::revertCachedRow(int row) { Q_Q(QSqlTableModel); ModifiedRow r = cache.value(row); - switch (r.op) { + switch (r.op()) { case QSqlTableModelPrivate::None: Q_ASSERT_X(false, "QSqlTableModelPrivate::revertCachedRow()", "Invalid entry in cache map"); return; @@ -394,20 +394,20 @@ QVariant QSqlTableModel::data(const QModelIndex &index, int role) const switch (d->strategy) { case OnFieldChange: case OnRowChange: - if (row.op == QSqlTableModelPrivate::Insert) { - if (item.column() < 0 || item.column() >= row.rec.count()) + if (row.op() == QSqlTableModelPrivate::Insert) { + if (item.column() < 0 || item.column() >= row.rec().count()) return QVariant(); - return row.rec.value(item.column()); - } else if (row.op == QSqlTableModelPrivate::Update) { - if (row.rec.isGenerated(item.column())) - return row.rec.value(item.column()); + return row.rec().value(item.column()); + } else if (row.op() == QSqlTableModelPrivate::Update) { + if (row.rec().isGenerated(item.column())) + return row.rec().value(item.column()); } break; case OnManualSubmit: - if (row.op == QSqlTableModelPrivate::Insert - || (row.op != QSqlTableModelPrivate::None - && row.rec.isGenerated(item.column()))) - return row.rec.value(item.column()); + if (row.op() == QSqlTableModelPrivate::Insert + || (row.op() != QSqlTableModelPrivate::None + && row.rec().isGenerated(item.column()))) + return row.rec().value(item.column()); break; } } @@ -424,7 +424,7 @@ QVariant QSqlTableModel::headerData(int section, Qt::Orientation orientation, in Q_D(const QSqlTableModel); if (orientation == Qt::Vertical && role == Qt::DisplayRole) { if (d->cache.contains(section)) { - const QSqlTableModelPrivate::Op op = d->cache.value(section).op; + const QSqlTableModelPrivate::Op op = d->cache.value(section).op(); if (op == QSqlTableModelPrivate::Insert) return QLatin1String("*"); else if (op == QSqlTableModelPrivate::Delete) @@ -452,15 +452,15 @@ bool QSqlTableModel::isDirty(const QModelIndex &index) const return false; case OnRowChange: { const QSqlTableModelPrivate::ModifiedRow row = d->cache.value(index.row()); - return row.op == QSqlTableModelPrivate::Update - && row.rec.isGenerated(index.column()); + return row.op() == QSqlTableModelPrivate::Update + && row.rec().isGenerated(index.column()); } case OnManualSubmit: { const QSqlTableModelPrivate::ModifiedRow row = d->cache.value(index.row()); - return row.op == QSqlTableModelPrivate::Insert - || row.op == QSqlTableModelPrivate::Delete - || (row.op == QSqlTableModelPrivate::Update - && row.rec.isGenerated(index.column())); + return row.op() == QSqlTableModelPrivate::Insert + || row.op() == QSqlTableModelPrivate::Delete + || (row.op() == QSqlTableModelPrivate::Update + && row.rec().isGenerated(index.column())); } } return false; @@ -485,7 +485,7 @@ bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, in if (!index.isValid() || index.column() >= d->rec.count() || index.row() >= rowCount()) return false; - if (d->strategy == OnFieldChange && d->cache.value(index.row()).op != QSqlTableModelPrivate::Insert) { + if (d->strategy == OnFieldChange && d->cache.value(index.row()).op() != QSqlTableModelPrivate::Insert) { d->cache.clear(); } else if (d->strategy == OnRowChange && !d->cache.isEmpty() && !d->cache.contains(index.row())) { submit(); @@ -494,7 +494,7 @@ bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, in QSqlTableModelPrivate::ModifiedRow &row = d->cache[index.row()]; - if (row.op == QSqlTableModelPrivate::None) { + if (row.op() == QSqlTableModelPrivate::None) { row = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Update, d->rec, d->primaryValues(indexInQuery(index).row())); @@ -503,11 +503,11 @@ bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, in row.setValue(index.column(), value); bool isOk = true; - if (d->strategy == OnFieldChange && row.op != QSqlTableModelPrivate::Insert) { + if (d->strategy == OnFieldChange && row.op() != QSqlTableModelPrivate::Insert) { // historical bug: bad style to call updateRowInTable. // Should call submit(), but maybe the author wanted to avoid // clearing the cache on failure. - isOk = updateRowInTable(index.row(), row.rec); + isOk = updateRowInTable(index.row(), row.rec()); if (isOk) select(); } @@ -523,7 +523,7 @@ bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, in // It's not clear why OnManualSubmit is excluded from this workaround. // Calling setData() while handling primeInsert() is arguably very wrong anyway. // primeInsert() provides a ref to the record for settings values. - if (d->strategy == OnManualSubmit || row.op != QSqlTableModelPrivate::Insert) + if (d->strategy == OnManualSubmit || row.op() != QSqlTableModelPrivate::Insert) emit dataChanged(index, index); return isOk; @@ -563,7 +563,7 @@ bool QSqlTableModel::updateRowInTable(int row, const QSqlRecord &values) QSqlRecord rec(values); emit beforeUpdate(row, rec); - const QSqlRecord whereValues = d->strategy == OnManualSubmit ? d->cache[row].primaryValues : d->primaryValues(row); + const QSqlRecord whereValues = d->strategy == OnManualSubmit ? d->cache[row].primaryValues() : d->primaryValues(row); bool prepStatement = d->db.driver()->hasFeature(QSqlDriver::PreparedQueries); QString stmt = d->db.driver()->sqlStatement(QSqlDriver::UpdateStatement, d->tableName, rec, prepStatement); @@ -630,7 +630,7 @@ bool QSqlTableModel::deleteRowFromTable(int row) Q_D(QSqlTableModel); emit beforeDelete(row); - const QSqlRecord whereValues = d->strategy == OnManualSubmit ? d->cache[row].primaryValues : d->primaryValues(row); + const QSqlRecord whereValues = d->strategy == OnManualSubmit ? d->cache[row].primaryValues() : d->primaryValues(row); bool prepStatement = d->db.driver()->hasFeature(QSqlDriver::PreparedQueries); QString stmt = d->db.driver()->sqlStatement(QSqlDriver::DeleteStatement, d->tableName, @@ -672,14 +672,14 @@ bool QSqlTableModel::submitAll() for (QSqlTableModelPrivate::CacheMap::ConstIterator it = d->cache.constBegin(); it != d->cache.constEnd(); ++it) { - switch (it.value().op) { + switch (it.value().op()) { case QSqlTableModelPrivate::Insert: - if (!insertRowIntoTable(it.value().rec)) + if (!insertRowIntoTable(it.value().rec())) return false; d->bottom = d->bottom.sibling(d->bottom.row() + 1, d->bottom.column()); break; case QSqlTableModelPrivate::Update: - if (!updateRowInTable(it.key(), it.value().rec)) + if (!updateRowInTable(it.key(), it.value().rec())) return false; break; case QSqlTableModelPrivate::Delete: @@ -995,7 +995,7 @@ bool QSqlTableModel::removeRows(int row, int count, const QModelIndex &parent) int i; for (i = 0; i < count && row + i < rowCount(); ++i) { int idx = row + i; - if (d->cache.value(idx).op == QSqlTableModelPrivate::Insert) { + if (d->cache.value(idx).op() == QSqlTableModelPrivate::Insert) { revertRow(idx); // Reverting a row means all the other cache entries have been adjusted downwards // so fake this by adjusting row @@ -1068,7 +1068,7 @@ bool QSqlTableModel::insertRows(int row, int count, const QModelIndex &parent) for (int i = 0; i < count; ++i) { d->cache[row + i] = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Insert, d->rec); - emit primeInsert(row + i, d->cache[row + i].rec); + emit primeInsert(row + i, d->cache[row + i].recRef()); } endInsertRows(); @@ -1110,7 +1110,7 @@ int QSqlTableModel::rowCount(const QModelIndex &parent) const int rc = QSqlQueryModel::rowCount(); for (QSqlTableModelPrivate::CacheMap::ConstIterator it = d->cache.constBegin(); it != d->cache.constEnd(); ++it) { - if (it.value().op == QSqlTableModelPrivate::Insert) + if (it.value().op() == QSqlTableModelPrivate::Insert) ++rc; } return rc; @@ -1135,7 +1135,7 @@ QModelIndex QSqlTableModel::indexInQuery(const QModelIndex &item) const int rowOffset = 0; QSqlTableModelPrivate::CacheMap::ConstIterator i = d->cache.constBegin(); while (i != d->cache.constEnd() && i.key() <= it.row()) { - if (i.value().op == QSqlTableModelPrivate::Insert) + if (i.value().op() == QSqlTableModelPrivate::Insert) ++rowOffset; ++i; } @@ -1209,13 +1209,13 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record) if (row >= rowCount()) return false; - if (d->strategy == OnFieldChange && d->cache.value(row).op != QSqlTableModelPrivate::Insert) + if (d->strategy == OnFieldChange && d->cache.value(row).op() != QSqlTableModelPrivate::Insert) d->cache.clear(); else if (d->strategy == OnRowChange && !d->cache.isEmpty() && !d->cache.contains(row)) submit(); QSqlTableModelPrivate::ModifiedRow &mrow = d->cache[row]; - if (mrow.op == QSqlTableModelPrivate::None) + if (mrow.op() == QSqlTableModelPrivate::None) mrow = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Update, d->rec, d->primaryValues(indexInQuery(createIndex(row, 0)).row())); @@ -1236,7 +1236,7 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record) if (oldValue.isNull() || oldValue != value) { // historical bug: dataChanged() is suppressed for Insert. See also setData(). mrow.setValue(idx, record.value(i)); - if (mrow.op != QSqlTableModelPrivate::Insert) + if (mrow.op() != QSqlTableModelPrivate::Insert) emit dataChanged(cIndex, cIndex); } } else { diff --git a/src/sql/models/qsqltablemodel_p.h b/src/sql/models/qsqltablemodel_p.h index 15cbe8ef7a1..e6e70d23bcd 100644 --- a/src/sql/models/qsqltablemodel_p.h +++ b/src/sql/models/qsqltablemodel_p.h @@ -94,22 +94,28 @@ public: enum Op { None, Insert, Update, Delete }; - struct ModifiedRow + class ModifiedRow { + public: inline ModifiedRow(Op o = None, const QSqlRecord &r = QSqlRecord(), const QSqlRecord &pVals = QSqlRecord()) - : op(o), rec(r), primaryValues(pVals) + : m_op(o), m_rec(r), m_primaryValues(pVals) { - for (int i = rec.count() - 1; i >= 0; --i) - rec.setGenerated(i, false); + for (int i = m_rec.count() - 1; i >= 0; --i) + m_rec.setGenerated(i, false); } + inline Op op() const { return m_op; } + inline QSqlRecord rec() const { return m_rec; } + inline QSqlRecord& recRef() { return m_rec; } + inline QSqlRecord primaryValues() const { return m_primaryValues; } inline void setValue(int c, const QVariant &v) { - rec.setValue(c, v); - rec.setGenerated(c, true); + m_rec.setValue(c, v); + m_rec.setGenerated(c, true); } - Op op; - QSqlRecord rec; - QSqlRecord primaryValues; + private: + Op m_op; + QSqlRecord m_rec; + QSqlRecord m_primaryValues; }; typedef QMap CacheMap; From 63f634322b2c0f795bd424be9e51953a10c701de Mon Sep 17 00:00:00 2001 From: Jonas Gastal Date: Sun, 29 Jan 2012 22:57:56 -0200 Subject: [PATCH 044/406] Don't allow cd'ing to above root. Task-number: QTBUG-23893 Change-Id: Ifc6e22f135a1f6bff7c0fa8bef3ea7e1042ae819 Reviewed-by: Oswald Buddenhagen Reviewed-by: David Faure --- src/corelib/io/qdir.cpp | 21 +++++++++++++----- tests/auto/corelib/io/qdir/tst_qdir.cpp | 29 +++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index afd6620e654..220fc43b92f 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -861,19 +861,28 @@ bool QDir::cd(const QString &dirName) if (isAbsolutePath(dirName)) { newPath = cleanPath(dirName); } else { - if (isRoot()) { - if (dirName == QLatin1String("..")) - return false; + if (isRoot()) newPath = d->dirEntry.filePath(); - } else { + else newPath = d->dirEntry.filePath() % QLatin1Char('/'); - } - newPath += dirName; if (dirName.indexOf(QLatin1Char('/')) >= 0 || dirName == QLatin1String("..") || d->dirEntry.filePath() == QLatin1String(".")) { newPath = cleanPath(newPath); +#if defined (Q_OS_UNIX) + //After cleanPath() if path is "/.." or starts with "/../" it means trying to cd above root. + if (newPath.startsWith(QLatin1String("/../")) || newPath == QLatin1String("/..")) +#else + /* + cleanPath() already took care of replacing '\' with '/'. + We can't use startsWith here because the letter of the drive is unknown. + After cleanPath() if path is "[A-Z]:/.." or starts with "[A-Z]:/../" it means trying to cd above root. + */ + + if (newPath.midRef(1, 4) == QLatin1String(":/..") && (newPath.length() == 5 || newPath.at(5) == QLatin1Char('/'))) +#endif + return false; /* If newPath starts with .., we convert it to absolute to avoid infinite looping on diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp index f1c9015092e..539bea5e8d3 100644 --- a/tests/auto/corelib/io/qdir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp @@ -190,6 +190,8 @@ private slots: void isReadable(); + void cdBelowRoot(); + private: QString m_dataPath; }; @@ -1942,6 +1944,33 @@ void tst_QDir::isReadable() #endif } +void tst_QDir::cdBelowRoot() +{ +#if defined (Q_OS_UNIX) +#define ROOT QString("/") +#define DIR QString("/tmp") +#define CD_INTO "tmp" +#else +#define ROOT QString::fromLocal8Bit(qgetenv("SystemDrive"))+"/" +#define DIR QString::fromLocal8Bit(qgetenv("SystemRoot")).replace('\\', '/') +#define CD_INTO QString::fromLocal8Bit(qgetenv("SystemRoot")).mid(3) +#endif + + QDir root(ROOT); + QVERIFY(!root.cd("..")); + QCOMPARE(root.path(), ROOT); + QVERIFY(root.cd(CD_INTO)); + QCOMPARE(root.path(), DIR); + + QDir dir(DIR); + QVERIFY(!dir.cd("../..")); + QCOMPARE(dir.path(), DIR); + QVERIFY(!dir.cd("../abs/../..")); + QCOMPARE(dir.path(), DIR); + QVERIFY(dir.cd("..")); + QCOMPARE(dir.path(), ROOT); +} + QTEST_MAIN(tst_QDir) #include "tst_qdir.moc" From f5e1da12f0e7bdeee4db74acc52dfabeb12a4e31 Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Mon, 6 Feb 2012 17:02:32 +0100 Subject: [PATCH 045/406] QSqlTableModel::removeRows(): don't emit extra beforeDelete Qt 5 seems like a welcome opportunity to stop emitting this spurious beforeDelete signal. Change-Id: Ib8628343ca9b8fdd85c154a206c7e2bf2c4c9dc1 Reviewed-by: Yunqiao Yin --- dist/changes-5.0.0 | 2 ++ src/sql/models/qsqltablemodel.cpp | 8 -------- .../auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp | 7 +++---- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index 617b2d3d95a..6bacccc34a5 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -329,6 +329,8 @@ QTestLib and log formats simultaneously. +* removeRows() no longer emits extra beforeDelete signal for out of range row. + **************************************************************************** * Database Drivers * **************************************************************************** diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 46d493b7264..4094052f1a0 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -990,8 +990,6 @@ bool QSqlTableModel::removeRows(int row, int count, const QModelIndex &parent) if (parent.isValid() || row < 0 || count <= 0) return false; - int initialRowCount = rowCount(); - int i; for (i = 0; i < count && row + i < rowCount(); ++i) { int idx = row + i; @@ -1012,12 +1010,6 @@ bool QSqlTableModel::removeRows(int row, int count, const QModelIndex &parent) if (d->strategy != OnManualSubmit && i > 0) submit(); - // historical bug: emit beforeDelete for 1st row beyond end - if (d->strategy != OnManualSubmit) { - if (row + count > initialRowCount) - emit beforeDelete(qMax(initialRowCount, row)); - } - if (i < count) return false; diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp index c8b5513a298..6a827e65c50 100644 --- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp @@ -703,10 +703,9 @@ void tst_QSqlTableModel::removeRows() QVERIFY(!model.removeRows(1, 0, model.index(2, 0))); // can't pass a valid modelindex QVERIFY_SQL(model, removeRows(0, 2)); - QCOMPARE(beforeDeleteSpy.count(), 3); - QVERIFY(beforeDeleteSpy.at(0).at(0).toInt() == 5); - QVERIFY(beforeDeleteSpy.at(1).at(0).toInt() == 0); - QVERIFY(beforeDeleteSpy.at(2).at(0).toInt() == 1); + QCOMPARE(beforeDeleteSpy.count(), 2); + QVERIFY(beforeDeleteSpy.at(0).at(0).toInt() == 0); + QVERIFY(beforeDeleteSpy.at(1).at(0).toInt() == 1); QCOMPARE(model.rowCount(), 1); QCOMPARE(model.data(model.index(0, 1)).toString(), QString("vohi")); model.clear(); From 269ef14215d3c3f89fe6239879a5db111dc1a7b4 Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Mon, 6 Feb 2012 17:19:19 +0100 Subject: [PATCH 046/406] QSqlTableModel::removeRows(): require valid full range of rows If an invalid range of rows is specified, it's likely to be a programming or user error. The old behavior of ignoring out of range rows seems dangerous and complicates the code. Also implement the documented behavior of returning false if changes are unsuccessful for OnFieldChange and OnRowChange. Previously the return value of submit() was ignored. Updated and improved documentation. Change-Id: Iaaf51c6d9a0c8c06fd5d186b4b88358fbeab9936 Reviewed-by: Yunqiao Yin --- dist/changes-5.0.0 | 5 +++++ src/sql/models/qsqltablemodel.cpp | 33 +++++++++++++++++++------------ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index 6bacccc34a5..53171370594 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -331,6 +331,11 @@ QTestLib * removeRows() no longer emits extra beforeDelete signal for out of range row. +* removeRows() now requires the whole range of targetted rows to be valid +before doing anything. Previously, it would remove what it could and +ignore the rest of the range. + + **************************************************************************** * Database Drivers * **************************************************************************** diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 4094052f1a0..df48115af3e 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -974,13 +974,20 @@ bool QSqlTableModel::removeColumns(int column, int count, const QModelIndex &par does not support hierarchical structures, \a parent must be an invalid model index. - Emits the beforeDelete() signal before a row is deleted. When - the edit strategy is OnManualSubmit signal emission is delayed - until submitAll() is called. + When the edit strategy is OnManualSubmit, deletion of rows from + the database is delayed until submitAll() is called; otherwise, + deletions are immediate. - Returns true if all rows could be removed; otherwise returns - false. Detailed error information can be retrieved using - lastError(). + Inserted but not yet submitted rows in the range to be removed + are immediately removed from the model. + + Before a row is deleted from the database, the beforeDelete() + signal is emitted. + + If row < 0 or row + count > rowCount(), no action is taken and + false is returned. Returns true if all rows could be removed; + otherwise returns false. Detailed database error information + can be retrieved using lastError(). \sa removeColumns(), insertRows() */ @@ -989,9 +996,12 @@ bool QSqlTableModel::removeRows(int row, int count, const QModelIndex &parent) Q_D(QSqlTableModel); if (parent.isValid() || row < 0 || count <= 0) return false; + else if (row + count > rowCount()) + return false; + else if (!count) + return true; - int i; - for (i = 0; i < count && row + i < rowCount(); ++i) { + for (int i = 0; i < count; ++i) { int idx = row + i; if (d->cache.value(idx).op() == QSqlTableModelPrivate::Insert) { revertRow(idx); @@ -1007,11 +1017,8 @@ bool QSqlTableModel::removeRows(int row, int count, const QModelIndex &parent) } } - if (d->strategy != OnManualSubmit && i > 0) - submit(); - - if (i < count) - return false; + if (d->strategy != OnManualSubmit) + return submit(); return true; } From f50a84008eb24d164df4e375084df457e9c85ce7 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 8 Feb 2012 10:59:38 +1000 Subject: [PATCH 047/406] Improved stability of tst_qhttpsocketengine This autotest assumed that various network operations could always be completed within 5 seconds. Notably, it assumed that an attempt to resolve a nonexistent hostname would always result in an error within 5 seconds. In my testing, it usually takes 4-6 seconds to complete, but occasionally takes as much as 13 seconds. (cherry picked from qt4 commit c85faef67b6a7e8fcedb4ce800282d41f5b79ec1) Change-Id: I982ecf6ebc1bb8ee2184cf5592cb2684474c870b Reviewed-by: Jason McDonald --- .../qhttpsocketengine/tst_qhttpsocketengine.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/auto/network/socket/qhttpsocketengine/tst_qhttpsocketengine.cpp b/tests/auto/network/socket/qhttpsocketengine/tst_qhttpsocketengine.cpp index 9b8391d6be5..43b1f225c41 100644 --- a/tests/auto/network/socket/qhttpsocketengine/tst_qhttpsocketengine.cpp +++ b/tests/auto/network/socket/qhttpsocketengine/tst_qhttpsocketengine.cpp @@ -294,7 +294,7 @@ void tst_QHttpSocketEngine::errorTest() connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(5); + QTestEventLoop::instance().enterLoop(30); QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(int(socket.error()), expectedError); @@ -371,7 +371,7 @@ void tst_QHttpSocketEngine::simpleErrorsAndStates() QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState); QVERIFY(!socketDevice.connectToHost(QHostAddress(QtNetworkSettings::serverName()), 8088)); QVERIFY(socketDevice.state() == QAbstractSocket::ConnectingState); - if (socketDevice.waitForWrite(15000)) { + if (socketDevice.waitForWrite(30000)) { QVERIFY(socketDevice.state() == QAbstractSocket::ConnectedState || socketDevice.state() == QAbstractSocket::UnconnectedState); } else { @@ -425,7 +425,7 @@ void tst_QHttpSocketEngine::tcpLoopbackPerformance() QTime timer; timer.start(); qlonglong readBytes = 0; - while (timer.elapsed() < 5000) { + while (timer.elapsed() < 30000) { qlonglong written = serverSocket.write(message1.data(), message1.size()); while (written > 0) { client.waitForRead(); @@ -458,7 +458,7 @@ void tst_QHttpSocketEngine::tcpSocketBlockingTest() QCOMPARE(socket.state(), QTcpSocket::ConnectedState); // Read greeting - QVERIFY(socket.waitForReadyRead(5000)); + QVERIFY(socket.waitForReadyRead(30000)); QString s = socket.readLine(); QVERIFY2(QtNetworkSettings::compareReplyIMAP(s.toLatin1()), qPrintable(s)); @@ -466,7 +466,7 @@ void tst_QHttpSocketEngine::tcpSocketBlockingTest() QCOMPARE((int) socket.write("1 NOOP\r\n", 8), 8); if (!socket.canReadLine()) - QVERIFY(socket.waitForReadyRead(5000)); + QVERIFY(socket.waitForReadyRead(30000)); // Read response s = socket.readLine(); @@ -476,14 +476,14 @@ void tst_QHttpSocketEngine::tcpSocketBlockingTest() QCOMPARE((int) socket.write("2 LOGOUT\r\n", 10), 10); if (!socket.canReadLine()) - QVERIFY(socket.waitForReadyRead(5000)); + QVERIFY(socket.waitForReadyRead(30000)); // Read two lines of respose s = socket.readLine(); QCOMPARE(s.toLatin1().constData(), "* BYE LOGOUT received\r\n"); if (!socket.canReadLine()) - QVERIFY(socket.waitForReadyRead(5000)); + QVERIFY(socket.waitForReadyRead(30000)); s = socket.readLine(); QCOMPARE(s.toLatin1().constData(), "2 OK Completed\r\n"); From 3ae3aa0e51711ea4051c82ed7911ccc744f44268 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Mon, 6 Feb 2012 14:17:08 +1000 Subject: [PATCH 048/406] Improved stability of tst_qsemaphore (especially on mac) Timers are not entirely precise; if we ask for a timeout of 10000 milliseconds, we might time out in 9999 instead. Also, we know the expected elapsed time in each case, so do a fuzzy comparison against that time. Previously the test was verifying that the elapsed time was greater than or equal to the timeout in the case where a timeout was expected, which means the test would not detect bugs which incorrectly caused the timeout to occur later than it should. (cherry picked from qt4 commit 9a2573dc13b3e8df6cd15bef64370ea407480fc7) Change-Id: I91d0c81f989ab43a3c48f6abbb4c5b28e2b35402 Reviewed-by: Jason McDonald --- .../corelib/thread/qsemaphore/qsemaphore.pro | 2 - .../thread/qsemaphore/tst_qsemaphore.cpp | 41 +++++++++++-------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/tests/auto/corelib/thread/qsemaphore/qsemaphore.pro b/tests/auto/corelib/thread/qsemaphore/qsemaphore.pro index cd87e688485..0ad311de994 100644 --- a/tests/auto/corelib/thread/qsemaphore/qsemaphore.pro +++ b/tests/auto/corelib/thread/qsemaphore/qsemaphore.pro @@ -2,5 +2,3 @@ CONFIG += testcase parallel_test TARGET = tst_qsemaphore QT = core testlib SOURCES = tst_qsemaphore.cpp - -mac*:CONFIG+=insignificant_test diff --git a/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp b/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp index 1d54c8e036d..884e8718cb2 100644 --- a/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp +++ b/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp @@ -223,11 +223,21 @@ void tst_QSemaphore::tryAcquireWithTimeout() { QFETCH(int, timeout); + // timers are not guaranteed to be accurate down to the last millisecond, + // so we permit the elapsed times to be up to this far from the expected value. + int fuzz = 10; + QSemaphore semaphore; QTime time; -#define QVERIFYGE(a,b) QVERIFY2(a >= b, qPrintable(QString("%1 = %2 !>= %3 = %4").arg(#a).arg(a).arg(#b).arg(b))); -#define QVERIFYLE(a,b) QVERIFY2(a <= b, qPrintable(QString("%1 = %2 !<= %3 = %4").arg(#a).arg(a).arg(#b).arg(b))); +#define FUZZYCOMPARE(a,e) \ + do { \ + int a1 = a; \ + int e1 = e; \ + QVERIFY2(qAbs(a1-e1) < fuzz, \ + qPrintable(QString("(%1=%2) is more than %3 milliseconds different from (%4=%5)") \ + .arg(#a).arg(a1).arg(fuzz).arg(#e).arg(e1))); \ + } while (0) QCOMPARE(semaphore.available(), 0); @@ -235,73 +245,72 @@ void tst_QSemaphore::tryAcquireWithTimeout() QCOMPARE(semaphore.available(), 1); time.start(); QVERIFY(!semaphore.tryAcquire(2, timeout)); - QVERIFYGE(time.elapsed(), timeout); + FUZZYCOMPARE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 1); semaphore.release(); QCOMPARE(semaphore.available(), 2); time.start(); QVERIFY(!semaphore.tryAcquire(3, timeout)); - QVERIFYGE(time.elapsed(), timeout); + FUZZYCOMPARE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 2); semaphore.release(10); QCOMPARE(semaphore.available(), 12); time.start(); QVERIFY(!semaphore.tryAcquire(100, timeout)); - QVERIFYGE(time.elapsed(), timeout); + FUZZYCOMPARE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 12); semaphore.release(10); QCOMPARE(semaphore.available(), 22); time.start(); QVERIFY(!semaphore.tryAcquire(100, timeout)); - QVERIFYGE(time.elapsed(), timeout); + FUZZYCOMPARE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 22); time.start(); QVERIFY(semaphore.tryAcquire(1, timeout)); - QVERIFYLE(time.elapsed(), timeout); + FUZZYCOMPARE(time.elapsed(), 0); QCOMPARE(semaphore.available(), 21); time.start(); QVERIFY(semaphore.tryAcquire(1, timeout)); - QVERIFYLE(time.elapsed(), timeout); + FUZZYCOMPARE(time.elapsed(), 0); QCOMPARE(semaphore.available(), 20); time.start(); QVERIFY(semaphore.tryAcquire(10, timeout)); - QVERIFYLE(time.elapsed(), timeout); + FUZZYCOMPARE(time.elapsed(), 0); QCOMPARE(semaphore.available(), 10); time.start(); QVERIFY(semaphore.tryAcquire(10, timeout)); - QVERIFYLE(time.elapsed(), timeout); + FUZZYCOMPARE(time.elapsed(), 0); QCOMPARE(semaphore.available(), 0); // should not be able to acquire more time.start(); QVERIFY(!semaphore.tryAcquire(1, timeout)); - QVERIFYGE(time.elapsed(), timeout); + FUZZYCOMPARE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 0); time.start(); QVERIFY(!semaphore.tryAcquire(1, timeout)); - QVERIFYGE(time.elapsed(), timeout); + FUZZYCOMPARE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 0); time.start(); QVERIFY(!semaphore.tryAcquire(10, timeout)); - QVERIFYGE(time.elapsed(), timeout); + FUZZYCOMPARE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 0); time.start(); QVERIFY(!semaphore.tryAcquire(10, timeout)); - QVERIFYGE(time.elapsed(), timeout); + FUZZYCOMPARE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 0); -#undef QVERIFYGE -#undef QVERIFYLE +#undef FUZZYCOMPARE } void tst_QSemaphore::tryAcquireWithTimeoutStarvation() From 009cd671ec5a51ab360bce39262482ee1b86dc46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Mill=C3=A1n=20Soto?= Date: Wed, 18 Jan 2012 18:23:43 +0100 Subject: [PATCH 049/406] Do not check isActiveWindow in QAccessibleWidget::state QWidget::isActiveWindow() was being checked in QAccessibleWidget::state to determine if a widget is focusable. As a result, focusable widgets were reported to be not focusable when the window was not active. Change-Id: I73c47181ed132a84f0251cb67d0e20912e29a1a6 Reviewed-by: Frederik Gladhorn --- src/widgets/accessible/qaccessiblewidget.cpp | 2 +- tests/auto/other/qaccessibility/tst_qaccessibility.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index 7a0aab56ddb..56ba990382f 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -597,7 +597,7 @@ QAccessible::State QAccessibleWidget::state() const QWidget *w = widget(); if (w->testAttribute(Qt::WA_WState_Visible) == false) state.invisible = true; - if (w->focusPolicy() != Qt::NoFocus && w->isActiveWindow()) + if (w->focusPolicy() != Qt::NoFocus) state.focusable = true; if (w->hasFocus()) state.focused = true; diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index eca5814b8e3..eb76202e35a 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -1685,7 +1685,7 @@ void tst_QAccessibility::lineEditTest() QCOMPARE(iface->childCount(), 0); QVERIFY(iface->state().sizeable); QVERIFY(iface->state().movable); - QCOMPARE(bool(iface->state().focusable), le->isActiveWindow()); + QVERIFY(iface->state().focusable); QVERIFY(iface->state().selectable); QVERIFY(iface->state().hasPopup); QCOMPARE(bool(iface->state().focused), le->hasFocus()); @@ -1714,7 +1714,7 @@ void tst_QAccessibility::lineEditTest() QApplication::processEvents(); QVERIFY(!(iface->state().sizeable)); QVERIFY(!(iface->state().movable)); - QCOMPARE(bool(iface->state().focusable), le->isActiveWindow()); + QVERIFY(iface->state().focusable); QVERIFY(iface->state().selectable); QVERIFY(iface->state().hasPopup); QCOMPARE(bool(iface->state().focused), le->hasFocus()); From 684a1559f0de4354cd9427e4c9a86e4a6a4e238a Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Sun, 5 Feb 2012 13:32:40 +0200 Subject: [PATCH 050/406] Reorganize evdev plugins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit linuxinput becomes evdevmouse. The experimental touch code is removed, now the plugin's purpose is solely to generate mouse events from absolute and relative pointer events. The plugin key is EvdevMouse. touchscreen becomes evdevtouch. The plugin key is EvdevTouch. In case keyboard support appears some day, it will fit nicely in the system by the name of evdevkeyboard or similar. Some little udev code is moved to platformsupport so it can be shared between the plugins. This may be extended later if more sophisticated udev support is needed. N.B. the intention is to keep this as simple as possible. We are shipping these plug-ins as reference examples, not as full-featured drivers. evdev and udev support has configure time tests from now on. This means the "drivers" (generic plugins) will get built automatically when the support is available. Change-Id: Iaf6260b5c2edfb9f25d070d2764466725adc6b4e Reviewed-by: Oswald Buddenhagen Reviewed-by: Samuel Rødal --- config.tests/unix/evdev/evdev.cpp | 59 +++ config.tests/unix/evdev/evdev.pro | 2 + config.tests/unix/libudev/libudev.cpp | 49 +++ config.tests/unix/libudev/libudev.pro | 3 + configure | 42 ++ src/platformsupport/platformsupport.pro | 1 + src/platformsupport/udev/qudevhelper.cpp | 73 ++++ .../udev/qudevhelper_p.h} | 40 +- src/platformsupport/udev/udev.pri | 5 + src/plugins/generic/evdevmouse/README | 11 + src/plugins/generic/evdevmouse/evdevmouse.pro | 13 + .../{linuxinput => evdevmouse}/main.cpp | 24 +- .../generic/evdevmouse/qevdevmouse.cpp | 214 ++++++++++ .../qevdevmouse.h} | 32 +- .../70-qtouchscreen.rules | 0 src/plugins/generic/evdevtouch/README | 36 ++ src/plugins/generic/evdevtouch/evdevtouch.pro | 14 + .../{touchscreen => evdevtouch}/main.cpp | 18 +- .../qevdevtouch.cpp} | 123 +++--- .../qevdevtouch.h} | 20 +- src/plugins/generic/generic.pro | 6 + src/plugins/generic/linuxinput/linuxinput.pro | 14 - .../generic/linuxinput/qlinuxinput.cpp | 365 ------------------ src/plugins/generic/touchscreen/README | 45 --- .../touchscreen/qtoucheventsenderqpa.cpp | 116 ------ .../generic/touchscreen/touchscreen.pro | 18 - 26 files changed, 651 insertions(+), 692 deletions(-) create mode 100644 config.tests/unix/evdev/evdev.cpp create mode 100644 config.tests/unix/evdev/evdev.pro create mode 100644 config.tests/unix/libudev/libudev.cpp create mode 100644 config.tests/unix/libudev/libudev.pro create mode 100644 src/platformsupport/udev/qudevhelper.cpp rename src/{plugins/generic/touchscreen/qtoucheventsenderqpa.h => platformsupport/udev/qudevhelper_p.h} (66%) create mode 100644 src/platformsupport/udev/udev.pri create mode 100644 src/plugins/generic/evdevmouse/README create mode 100644 src/plugins/generic/evdevmouse/evdevmouse.pro rename src/plugins/generic/{linuxinput => evdevmouse}/main.cpp (77%) create mode 100644 src/plugins/generic/evdevmouse/qevdevmouse.cpp rename src/plugins/generic/{linuxinput/qlinuxinput.h => evdevmouse/qevdevmouse.h} (77%) rename src/plugins/generic/{touchscreen => evdevtouch}/70-qtouchscreen.rules (100%) create mode 100644 src/plugins/generic/evdevtouch/README create mode 100644 src/plugins/generic/evdevtouch/evdevtouch.pro rename src/plugins/generic/{touchscreen => evdevtouch}/main.cpp (81%) rename src/plugins/generic/{touchscreen/qtouchscreen.cpp => evdevtouch/qevdevtouch.cpp} (80%) rename src/plugins/generic/{touchscreen/qtouchscreen.h => evdevtouch/qevdevtouch.h} (80%) delete mode 100644 src/plugins/generic/linuxinput/linuxinput.pro delete mode 100644 src/plugins/generic/linuxinput/qlinuxinput.cpp delete mode 100644 src/plugins/generic/touchscreen/README delete mode 100644 src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp delete mode 100644 src/plugins/generic/touchscreen/touchscreen.pro diff --git a/config.tests/unix/evdev/evdev.cpp b/config.tests/unix/evdev/evdev.cpp new file mode 100644 index 00000000000..3dddd600380 --- /dev/null +++ b/config.tests/unix/evdev/evdev.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the config.tests 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 + +enum { + e1 = ABS_MT_POSITION_X, + e2 = ABS_MT_TRACKING_ID, + e3 = ABS_PRESSURE, + e4 = ABS_X, + e5 = REL_X, + e6 = SYN_REPORT, + e7 = SYN_MT_REPORT +}; + +int main() +{ + ::input_event buf[32]; + (void) buf; + return 0; +} diff --git a/config.tests/unix/evdev/evdev.pro b/config.tests/unix/evdev/evdev.pro new file mode 100644 index 00000000000..42db3912162 --- /dev/null +++ b/config.tests/unix/evdev/evdev.pro @@ -0,0 +1,2 @@ +SOURCES = evdev.cpp +CONFIG -= qt diff --git a/config.tests/unix/libudev/libudev.cpp b/config.tests/unix/libudev/libudev.cpp new file mode 100644 index 00000000000..1a08a715d88 --- /dev/null +++ b/config.tests/unix/libudev/libudev.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the config.tests 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 + +int main() +{ + udev *u = udev_new(); + udev_unref(u); + return 0; +} diff --git a/config.tests/unix/libudev/libudev.pro b/config.tests/unix/libudev/libudev.pro new file mode 100644 index 00000000000..7f571b5a6d6 --- /dev/null +++ b/config.tests/unix/libudev/libudev.pro @@ -0,0 +1,3 @@ +SOURCES = libudev.cpp +CONFIG -= qt +LIBS += -ludev diff --git a/configure b/configure index 5e78360fa68..a3b94e1eee7 100755 --- a/configure +++ b/configure @@ -727,6 +727,8 @@ CFG_XKB=auto CFG_XCB=auto CFG_XCB_LIMITED=yes CFG_WAYLAND=auto +CFG_LIBUDEV=auto +CFG_EVDEV=auto CFG_NIS=auto CFG_CUPS=auto CFG_ICONV=auto @@ -1843,6 +1845,20 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=yes fi ;; + libudev) + if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then + CFG_LIBUDEV="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; + evdev) + if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then + CFG_EVDEV="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; cups) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then CFG_CUPS="$VAL" @@ -5651,6 +5667,32 @@ if [ "$PLATFORM_QPA" = "yes" ]; then fi fi + if [ "$CFG_LIBUDEV" != "no" ]; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/libudev "libudev" $L_FLAGS $I_FLAGS $l_FLAGS; then + CFG_LIBUDEV=yes + QT_CONFIG="$QT_CONFIG libudev" + elif [ "$CFG_LIBUDEV" = "yes" ]; then + echo "The libudev functionality test failed!" + exit 1 + else + CFG_LIBUDEV=no + QMakeVar add DEFINES QT_NO_LIBUDEV + fi + fi + + if [ "$CFG_EVDEV" != "no" ]; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/evdev "evdev" $L_FLAGS $I_FLAGS $l_FLAGS; then + CFG_EVDEV=yes + QT_CONFIG="$QT_CONFIG evdev" + elif [ "$CFG_EVDEV" = "yes" ]; then + echo "The evdev functionality test failed!" + exit 1 + else + CFG_EVDEV=no + QMakeVar add DEFINES QT_NO_EVDEV + fi + fi + # Check we actually have X11 :-) if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xlib "XLib" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then QT_CONFIG="$QT_CONFIG xlib" diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro index 36323d97660..64decd03921 100644 --- a/src/platformsupport/platformsupport.pro +++ b/src/platformsupport/platformsupport.pro @@ -33,3 +33,4 @@ include(fontdatabases/fontdatabases.pri) include(glxconvenience/glxconvenience.pri) #include(printersupport/printersupport.pri) include(inputcontext/inputcontext.pri) +include(udev/udev.pri) diff --git a/src/platformsupport/udev/qudevhelper.cpp b/src/platformsupport/udev/qudevhelper.cpp new file mode 100644 index 00000000000..b63ef64ed8c --- /dev/null +++ b/src/platformsupport/udev/qudevhelper.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins 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 "qudevhelper_p.h" +#include + +QT_BEGIN_NAMESPACE + +void q_udev_devicePath(int type, QString *path) +{ + *path = QString(); + udev *u = udev_new(); + udev_enumerate *ue = udev_enumerate_new(u); + udev_enumerate_add_match_subsystem(ue, "input"); + if (type & UDev_Mouse) + udev_enumerate_add_match_property(ue, "ID_INPUT_MOUSE", "1"); + if (type & UDev_Touchpad) + udev_enumerate_add_match_property(ue, "ID_INPUT_TOUCHPAD", "1"); + if (type & UDev_Touchscreen) + udev_enumerate_add_match_property(ue, "ID_INPUT_TOUCHSCREEN", "1"); + udev_enumerate_scan_devices(ue); + udev_list_entry *entry; + udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(ue)) { + const char *syspath = udev_list_entry_get_name(entry); + udev_device *udevice = udev_device_new_from_syspath(u, syspath); + QString candidate = QString::fromLocal8Bit(udev_device_get_devnode(udevice)); + udev_device_unref(udevice); + if (path->isEmpty() && candidate.startsWith(QLatin1String("/dev/input/event"))) + *path = candidate; + } + udev_enumerate_unref(ue); + udev_unref(u); +} + +QT_END_NAMESPACE diff --git a/src/plugins/generic/touchscreen/qtoucheventsenderqpa.h b/src/platformsupport/udev/qudevhelper_p.h similarity index 66% rename from src/plugins/generic/touchscreen/qtoucheventsenderqpa.h rename to src/platformsupport/udev/qudevhelper_p.h index 6b21dfe2592..e6046ca0854 100644 --- a/src/plugins/generic/touchscreen/qtoucheventsenderqpa.h +++ b/src/platformsupport/udev/qudevhelper_p.h @@ -3,7 +3,7 @@ ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/ ** -** This file is part of the plugins module of the Qt Toolkit. +** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage @@ -39,39 +39,21 @@ ** ****************************************************************************/ -#ifndef QTOUCHEVENTSENDERQPA_H -#define QTOUCHEVENTSENDERQPA_H +#ifndef QUDEVHELPER_P_H +#define QUDEVHELPER_P_H -#include "qtouchscreen.h" - -QT_BEGIN_HEADER +#include QT_BEGIN_NAMESPACE -class QTouchDevice; - -class QTouchEventSenderQPA : public QTouchScreenObserver -{ -public: - QTouchEventSenderQPA(const QString &spec = QString()); - void touch_configure(int x_min, int x_max, int y_min, int y_max, - int pressure_min, int pressure_max, const QString &dev_name); - void touch_point(const QList &points); - -private: - bool m_forceToActiveWindow; - int hw_range_x_min; - int hw_range_x_max; - int hw_range_y_min; - int hw_range_y_max; - int hw_pressure_min; - int hw_pressure_max; - QString hw_dev_name; - QTouchDevice *m_device; +enum QUDeviceType { + UDev_Mouse = 0x01, + UDev_Touchpad = 0x02, + UDev_Touchscreen = 0x04 }; +void q_udev_devicePath(int type, QString *path); + QT_END_NAMESPACE -QT_END_HEADER - -#endif // QTOUCHEVENTSENDERQPA_H +#endif // QUDEVHELPER_P_H diff --git a/src/platformsupport/udev/udev.pri b/src/platformsupport/udev/udev.pri new file mode 100644 index 00000000000..ac3f7df40aa --- /dev/null +++ b/src/platformsupport/udev/udev.pri @@ -0,0 +1,5 @@ +contains(QT_CONFIG, libudev) { + HEADERS += $$PWD/qudevhelper_p.h + SOURCES += $$PWD/qudevhelper.cpp + LIBS += -ludev +} diff --git a/src/plugins/generic/evdevmouse/README b/src/plugins/generic/evdevmouse/README new file mode 100644 index 00000000000..b89c0a70665 --- /dev/null +++ b/src/plugins/generic/evdevmouse/README @@ -0,0 +1,11 @@ +Generic plug-in for absolute & relative evdev pointer events. + +To use it, launch apps with -plugin EvdevMouse + +The plug-in will try to pick a mouse or touchpad device from udev. +If automatic detection does not work, use -plugin +EvdevMouse:/dev/input/eventN to explicitly set the device node. + +The initial cursor position is assumed to be (0, 0). Relative events +will generate Qt mouse events with screen positions relative to this +initial position. diff --git a/src/plugins/generic/evdevmouse/evdevmouse.pro b/src/plugins/generic/evdevmouse/evdevmouse.pro new file mode 100644 index 00000000000..f25199161bb --- /dev/null +++ b/src/plugins/generic/evdevmouse/evdevmouse.pro @@ -0,0 +1,13 @@ +TARGET = qevdevmouseplugin +load(qt_plugin) + +DESTDIR = $$QT.gui.plugins/generic +target.path = $$[QT_INSTALL_PLUGINS]/generic +INSTALLS += target + +HEADERS = qevdevmouse.h + +QT += core-private platformsupport-private + +SOURCES = main.cpp \ + qevdevmouse.cpp diff --git a/src/plugins/generic/linuxinput/main.cpp b/src/plugins/generic/evdevmouse/main.cpp similarity index 77% rename from src/plugins/generic/linuxinput/main.cpp rename to src/plugins/generic/evdevmouse/main.cpp index 04fc00f5286..34ca62f960b 100644 --- a/src/plugins/generic/linuxinput/main.cpp +++ b/src/plugins/generic/evdevmouse/main.cpp @@ -40,38 +40,38 @@ ****************************************************************************/ #include -#include "qlinuxinput.h" +#include "qevdevmouse.h" QT_BEGIN_NAMESPACE -class QLinuxInputPlugin : public QGenericPlugin +class QEvdevMousePlugin : public QGenericPlugin { public: - QLinuxInputPlugin(); + QEvdevMousePlugin(); QStringList keys() const; QObject* create(const QString &key, const QString &specification); }; -QLinuxInputPlugin::QLinuxInputPlugin() +QEvdevMousePlugin::QEvdevMousePlugin() : QGenericPlugin() { } -QStringList QLinuxInputPlugin::keys() const +QStringList QEvdevMousePlugin::keys() const { return (QStringList() - << QLatin1String("LinuxInputMouse")); + << QLatin1String("EvdevMouse")); } -QObject* QLinuxInputPlugin::create(const QString &key, - const QString &specification) +QObject* QEvdevMousePlugin::create(const QString &key, + const QString &specification) { - if (!key.compare(QLatin1String("LinuxInputMouse"), Qt::CaseInsensitive)) - return new QLinuxInputMouseHandler(key, specification); + if (!key.compare(QLatin1String("EvdevMouse"), Qt::CaseInsensitive)) + return new QEvdevMouseHandler(key, specification); return 0; - } +} -Q_EXPORT_PLUGIN2(qlinuxinputplugin, QLinuxInputPlugin) +Q_EXPORT_PLUGIN2(qevdevmouseplugin, QEvdevMousePlugin) QT_END_NAMESPACE diff --git a/src/plugins/generic/evdevmouse/qevdevmouse.cpp b/src/plugins/generic/evdevmouse/qevdevmouse.cpp new file mode 100644 index 00000000000..0b72123c02f --- /dev/null +++ b/src/plugins/generic/evdevmouse/qevdevmouse.cpp @@ -0,0 +1,214 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui 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 "qevdevmouse.h" + +#include +#include +#include +#include + +#include +#include // overrides QT_OPEN +#include + +#include + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +QEvdevMouseHandler::QEvdevMouseHandler(const QString &key, + const QString &specification) + : m_notify(0), m_x(0), m_y(0), m_prevx(0), m_prevy(0), + m_xoffset(0), m_yoffset(0), m_buttons(0) +{ + Q_UNUSED(key); + setObjectName(QLatin1String("Evdev Mouse Handler")); + + QString dev; + q_udev_devicePath(UDev_Mouse | UDev_Touchpad, &dev); + if (dev.isEmpty()) + dev = QLatin1String("/dev/input/event0"); + + m_compression = true; + m_smooth = false; + int jitterLimit = 0; + + QStringList args = specification.split(QLatin1Char(':')); + foreach (const QString &arg, args) { + if (arg == "nocompress") + m_compression = false; + else if (arg.startsWith("dejitter=")) + jitterLimit = arg.mid(9).toInt(); + else if (arg.startsWith("xoffset=")) + m_xoffset = arg.mid(8).toInt(); + else if (arg.startsWith("yoffset=")) + m_yoffset = arg.mid(8).toInt(); + else if (arg.startsWith(QLatin1String("/dev/"))) + dev = arg; + } + m_jitterLimitSquared = jitterLimit*jitterLimit; + + qDebug("evdevmouse: Using device %s", qPrintable(dev)); + m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); + if (m_fd >= 0) { + m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); + connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData())); + } else { + qWarning("Cannot open mouse input device '%s': %s", qPrintable(dev), strerror(errno)); + return; + } +} + +QEvdevMouseHandler::~QEvdevMouseHandler() +{ + if (m_fd >= 0) + QT_CLOSE(m_fd); +} + +void QEvdevMouseHandler::sendMouseEvent() +{ + QPoint pos(m_x + m_xoffset, m_y + m_yoffset); + //qDebug("mouse event %d %d %d", pos.x(), pos.y(), int(m_buttons)); + QWindowSystemInterface::handleMouseEvent(0, pos, pos, m_buttons); + m_prevx = m_x; + m_prevy = m_y; +} + +void QEvdevMouseHandler::readMouseData() +{ + struct ::input_event buffer[32]; + int n = 0; + bool posChanged = false; + bool pendingMouseEvent = false; + int eventCompressCount = 0; + forever { + n = QT_READ(m_fd, reinterpret_cast(buffer) + n, sizeof(buffer) - n); + + if (n == 0) { + qWarning("Got EOF from the input device."); + return; + } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) { + qWarning("Could not read from input device: %s", strerror(errno)); + return; + } else if (n % sizeof(buffer[0]) == 0) { + break; + } + } + + n /= sizeof(buffer[0]); + + for (int i = 0; i < n; ++i) { + struct ::input_event *data = &buffer[i]; + //qDebug() << ">>" << hex << data->type << data->code << dec << data->value; + if (data->type == EV_ABS) { + if (data->code == ABS_X && m_x != data->value) { + m_x = data->value; + posChanged = true; + } else if (data->code == ABS_Y && m_y != data->value) { + m_y = data->value; + posChanged = true; + } + } else if (data->type == EV_REL) { + if (data->code == REL_X) { + m_x += data->value; + posChanged = true; + } else if (data->code == REL_Y) { + m_y += data->value; + posChanged = true; + } else if (data->code == ABS_WHEEL) { // vertical scroll + // data->value: 1 == up, -1 == down + int delta = 120 * data->value; + QWindowSystemInterface::handleWheelEvent(0, QPoint(m_x, m_y), + QPoint(m_x, m_y), + delta, Qt::Vertical); + } else if (data->code == ABS_THROTTLE) { // horizontal scroll + // data->value: 1 == right, -1 == left + int delta = 120 * -data->value; + QWindowSystemInterface::handleWheelEvent(0, QPoint(m_x, m_y), + QPoint(m_x, m_y), + delta, Qt::Horizontal); + } + } else if (data->type == EV_KEY && data->code == BTN_TOUCH) { + m_buttons = data->value ? Qt::LeftButton : Qt::NoButton; + + sendMouseEvent(); + pendingMouseEvent = false; + } else if (data->type == EV_KEY && data->code >= BTN_LEFT && data->code <= BTN_MIDDLE) { + Qt::MouseButton button = Qt::NoButton; + switch (data->code) { + case BTN_LEFT: button = Qt::LeftButton; break; + case BTN_MIDDLE: button = Qt::MidButton; break; + case BTN_RIGHT: button = Qt::RightButton; break; + } + if (data->value) + m_buttons |= button; + else + m_buttons &= ~button; + sendMouseEvent(); + pendingMouseEvent = false; + } else if (data->type == EV_SYN && data->code == SYN_REPORT) { + if (posChanged) { + posChanged = false; + if (m_compression) { + pendingMouseEvent = true; + eventCompressCount++; + } else { + sendMouseEvent(); + } + } + } else if (data->type == EV_MSC && data->code == MSC_SCAN) { + // kernel encountered an unmapped key - just ignore it + continue; + } + } + if (m_compression && pendingMouseEvent) { + int distanceSquared = (m_x - m_prevx)*(m_x - m_prevx) + (m_y - m_prevy)*(m_y - m_prevy); + if (distanceSquared > m_jitterLimitSquared) + sendMouseEvent(); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/generic/linuxinput/qlinuxinput.h b/src/plugins/generic/evdevmouse/qevdevmouse.h similarity index 77% rename from src/plugins/generic/linuxinput/qlinuxinput.h rename to src/plugins/generic/evdevmouse/qevdevmouse.h index a512ad959a2..9542d133f2a 100644 --- a/src/plugins/generic/linuxinput/qlinuxinput.h +++ b/src/plugins/generic/evdevmouse/qevdevmouse.h @@ -39,12 +39,11 @@ ** ****************************************************************************/ -#ifndef QLINUXINPUT_H -#define QLINUXINPUT_H +#ifndef QEVDEVMOUSE_H +#define QEVDEVMOUSE_H -#include -#include -#include +#include +#include QT_BEGIN_HEADER @@ -52,35 +51,34 @@ QT_BEGIN_NAMESPACE class QSocketNotifier; -class QLinuxInputMouseHandlerData; - -class QLinuxInputMouseHandler : public QObject +class QEvdevMouseHandler : public QObject { Q_OBJECT public: - QLinuxInputMouseHandler(const QString &key, const QString &specification); - ~QLinuxInputMouseHandler(); + QEvdevMouseHandler(const QString &key, const QString &specification); + ~QEvdevMouseHandler(); private slots: void readMouseData(); private: - void sendMouseEvent(int x, int y, Qt::MouseButtons buttons); - QSocketNotifier * m_notify; - int m_fd; - int m_x, m_y; + void sendMouseEvent(); + void pathFromUdev(QString *path); + + QSocketNotifier *m_notify; + int m_fd; + int m_x, m_y; int m_prevx, m_prevy; int m_xoffset, m_yoffset; int m_smoothx, m_smoothy; - Qt::MouseButtons m_buttons; + Qt::MouseButtons m_buttons; bool m_compression; bool m_smooth; int m_jitterLimitSquared; - QLinuxInputMouseHandlerData *d; }; QT_END_NAMESPACE QT_END_HEADER -#endif // QLINUXINPUT_H +#endif // QEVDEVMOUSE_H diff --git a/src/plugins/generic/touchscreen/70-qtouchscreen.rules b/src/plugins/generic/evdevtouch/70-qtouchscreen.rules similarity index 100% rename from src/plugins/generic/touchscreen/70-qtouchscreen.rules rename to src/plugins/generic/evdevtouch/70-qtouchscreen.rules diff --git a/src/plugins/generic/evdevtouch/README b/src/plugins/generic/evdevtouch/README new file mode 100644 index 00000000000..4764ef8f708 --- /dev/null +++ b/src/plugins/generic/evdevtouch/README @@ -0,0 +1,36 @@ +Generic plug-in for evdev touch events. (protocol type A) + +Tested with the following drivers: bcm5974, hid_magicmouse. + +To use it, pass -plugin EvdevTouch on the command line. + +If automatic detection does not work, use -plugin +EvdevTouch:/dev/input/eventN to explicitly set the device file +name. + +By default the surface of the touch device is mapped to the entire +screen. If this is not desired, pass force_window in the plugin +specification as shown in the example above. This will cause mapping +the touch surface to the active window instead. For example: +./fingerpaint -plugin EvdevTouch:force_window + +Only touch events are generated, mouse events are not. Be aware however +that ignored touch events will generate a mouse event from the first +touch point by default. See AA_SynthesizeMouseForUnhandledTouchEvents. + +If no evdev events are read, disable the synaptics driver from X or +temporarily disable the device by running +xinput set-prop 0. +Use xinput list and xinput list-props to figure out the values. + +When not running on a windowing system (eglfs, kms, etc.) and having a +touchpad, the evdevmouse and touch plugins can be combined to get both +mouse and touch events: +./app -platform kms -plugin EvdevTouch -plugin EvdevMouse + +If the input device cannot be accessed, set up a udev rule. +For example: + sudo cp 70-qtouchscreen.rules /etc/udev/rules.d + sudo udevadm trigger --subsystem-match=input +The udev rule matches any touchpad or touchscreen device. If there are +multiple ones, specify the device manually as described above. diff --git a/src/plugins/generic/evdevtouch/evdevtouch.pro b/src/plugins/generic/evdevtouch/evdevtouch.pro new file mode 100644 index 00000000000..78fe551aa27 --- /dev/null +++ b/src/plugins/generic/evdevtouch/evdevtouch.pro @@ -0,0 +1,14 @@ +TARGET = qevdevtouchplugin +load(qt_plugin) + +DESTDIR = $$QT.gui.plugins/generic +target.path = $$[QT_INSTALL_PLUGINS]/generic +INSTALLS += target + +HEADERS = \ + qevdevtouch.h + +SOURCES = main.cpp \ + qevdevtouch.cpp + +QT += core-private platformsupport-private diff --git a/src/plugins/generic/touchscreen/main.cpp b/src/plugins/generic/evdevtouch/main.cpp similarity index 81% rename from src/plugins/generic/touchscreen/main.cpp rename to src/plugins/generic/evdevtouch/main.cpp index 1f438ef1e70..526e336fd8d 100644 --- a/src/plugins/generic/touchscreen/main.cpp +++ b/src/plugins/generic/evdevtouch/main.cpp @@ -40,8 +40,7 @@ ****************************************************************************/ #include -#include "qtouchscreen.h" -#include "qtoucheventsenderqpa.h" +#include "qevdevtouch.h" QT_BEGIN_NAMESPACE @@ -60,21 +59,18 @@ QTouchScreenPlugin::QTouchScreenPlugin() QStringList QTouchScreenPlugin::keys() const { - return QStringList() << "LinuxTouchScreen"; + return QStringList() << "EvdevTouch"; } QObject* QTouchScreenPlugin::create(const QString &key, - const QString &spec) + const QString &spec) { - if (!key.compare(QLatin1String("LinuxTouchScreen"), Qt::CaseInsensitive)) { - QTouchScreenObserver *obs = new QTouchEventSenderQPA(spec); - QTouchScreenHandlerThread *h = new QTouchScreenHandlerThread(spec, obs); - return h; - } + if (!key.compare(QLatin1String("EvdevTouch"), Qt::CaseInsensitive)) + return new QTouchScreenHandlerThread(spec); return 0; - } +} -Q_EXPORT_PLUGIN2(qtouchscreenplugin, QTouchScreenPlugin) +Q_EXPORT_PLUGIN2(qevdevtouchplugin, QTouchScreenPlugin) QT_END_NAMESPACE diff --git a/src/plugins/generic/touchscreen/qtouchscreen.cpp b/src/plugins/generic/evdevtouch/qevdevtouch.cpp similarity index 80% rename from src/plugins/generic/touchscreen/qtouchscreen.cpp rename to src/plugins/generic/evdevtouch/qevdevtouch.cpp index 8e04c10b9fd..d508c4a12a2 100644 --- a/src/plugins/generic/touchscreen/qtouchscreen.cpp +++ b/src/plugins/generic/evdevtouch/qevdevtouch.cpp @@ -39,13 +39,15 @@ ** ****************************************************************************/ -#include "qtouchscreen.h" +#include "qevdevtouch.h" #include #include #include +#include +#include #include +#include #include -#include QT_BEGIN_NAMESPACE @@ -77,6 +79,8 @@ public: Contact m_currentData; int findClosestContact(const QHash &contacts, int x, int y, int *dist); + void reportPoints(); + void registerDevice(); int hw_range_x_min; int hw_range_x_max; @@ -85,8 +89,8 @@ public: int hw_pressure_min; int hw_pressure_max; QString hw_name; - - QList m_observers; + bool m_forceToActiveWindow; + QTouchDevice *m_device; }; QTouchScreenData::QTouchScreenData(QTouchScreenHandler *q_ptr, const QStringList &args) @@ -96,23 +100,37 @@ QTouchScreenData::QTouchScreenData(QTouchScreenHandler *q_ptr, const QStringList hw_range_y_min(0), hw_range_y_max(0), hw_pressure_min(0), hw_pressure_max(0) { - Q_UNUSED(args); + m_forceToActiveWindow = args.contains(QLatin1String("force_window")); +} + +void QTouchScreenData::registerDevice() +{ + m_device = new QTouchDevice; + m_device->setName(hw_name); + m_device->setType(QTouchDevice::TouchScreen); + m_device->setCapabilities(QTouchDevice::Position | QTouchDevice::Area); + if (hw_pressure_max > hw_pressure_min) + m_device->setCapabilities(m_device->capabilities() | QTouchDevice::Pressure); + + QWindowSystemInterface::registerTouchDevice(m_device); } QTouchScreenHandler::QTouchScreenHandler(const QString &spec) : m_notify(0), m_fd(-1), d(0) { - setObjectName(QLatin1String("Linux Touch Handler")); + setObjectName(QLatin1String("Evdev Touch Handler")); - QString dev = QLatin1String("/dev/input/event5"); - try_udev(&dev); + QString dev; + q_udev_devicePath(UDev_Touchpad | UDev_Touchscreen, &dev); + if (dev.isEmpty()) + dev = QLatin1String("/dev/input/event0"); QStringList args = spec.split(QLatin1Char(':')); for (int i = 0; i < args.count(); ++i) if (args.at(i).startsWith(QLatin1String("/dev/"))) dev = args.at(i); - qDebug("Using device '%s'", qPrintable(dev)); + qDebug("evdevtouch: Using device %s", qPrintable(dev)); m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); if (m_fd >= 0) { @@ -149,6 +167,8 @@ QTouchScreenHandler::QTouchScreenHandler(const QString &spec) d->hw_name = QString::fromLocal8Bit(name); qDebug("device name: %s", name); } + + d->registerDevice(); } QTouchScreenHandler::~QTouchScreenHandler() @@ -159,38 +179,6 @@ QTouchScreenHandler::~QTouchScreenHandler() delete d; } -void QTouchScreenHandler::addObserver(QTouchScreenObserver *observer) -{ - if (!d || !observer) - return; - d->m_observers.append(observer); - observer->touch_configure(d->hw_range_x_min, d->hw_range_x_max, - d->hw_range_y_min, d->hw_range_y_max, - d->hw_pressure_min, d->hw_pressure_max, - d->hw_name); -} - -void QTouchScreenHandler::try_udev(QString *path) -{ - *path = QString(); - udev *u = udev_new(); - udev_enumerate *ue = udev_enumerate_new(u); - udev_enumerate_add_match_subsystem(ue, "input"); - udev_enumerate_add_match_property(ue, "ID_INPUT_TOUCHPAD", "1"); - udev_enumerate_scan_devices(ue); - udev_list_entry *entry; - udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(ue)) { - const char *syspath = udev_list_entry_get_name(entry); - udev_device *udevice = udev_device_new_from_syspath(u, syspath); - QString candidate = QString::fromLocal8Bit(udev_device_get_devnode(udevice)); - udev_device_unref(udevice); - if (path->isEmpty() && candidate.startsWith("/dev/input/event")) - *path = candidate; - } - udev_enumerate_unref(ue); - udev_unref(u); -} - void QTouchScreenHandler::readData() { ::input_event buffer[32]; @@ -289,7 +277,7 @@ void QTouchScreenData::processInputEvent(input_event *data) tp.state = contact.state; combinedStates |= tp.state; - // Store the HW coordinates. Observers can then map it to screen space or something else. + // Store the HW coordinates for now, will be updated later. tp.area = QRectF(0, 0, contact.maj, contact.maj); tp.area.moveCenter(QPoint(contact.x, contact.y)); tp.pressure = contact.pressure; @@ -307,10 +295,8 @@ void QTouchScreenData::processInputEvent(input_event *data) m_lastContacts = m_contacts; m_contacts.clear(); - if (!m_touchPoints.isEmpty() && combinedStates != Qt::TouchPointStationary) { - for (int i = 0; i < m_observers.count(); ++i) - m_observers.at(i)->touch_point(m_touchPoints); - } + if (!m_touchPoints.isEmpty() && combinedStates != Qt::TouchPointStationary) + reportPoints(); } m_lastEventType = data->type; @@ -369,10 +355,48 @@ void QTouchScreenData::assignIds() m_contacts = newContacts; } +void QTouchScreenData::reportPoints() +{ + QRect winRect; + if (m_forceToActiveWindow) { + QWindow *win = QGuiApplication::activeWindow(); + if (!win) + return; + winRect = win->geometry(); + } else { + winRect = QGuiApplication::primaryScreen()->geometry(); + } -QTouchScreenHandlerThread::QTouchScreenHandlerThread(const QString &spec, - QTouchScreenObserver *observer) - : m_spec(spec), m_handler(0), m_observer(observer) + const int hw_w = hw_range_x_max - hw_range_x_min; + const int hw_h = hw_range_y_max - hw_range_y_min; + + // Map the coordinates based on the normalized position. QPA expects 'area' + // to be in screen coordinates. + const int pointCount = m_touchPoints.count(); + for (int i = 0; i < pointCount; ++i) { + QWindowSystemInterface::TouchPoint &tp(m_touchPoints[i]); + + // Generate a screen position that is always inside the active window + // or the primary screen. + const int wx = winRect.left() + int(tp.normalPosition.x() * winRect.width()); + const int wy = winRect.top() + int(tp.normalPosition.y() * winRect.height()); + const qreal sizeRatio = (winRect.width() + winRect.height()) / qreal(hw_w + hw_h); + tp.area = QRect(0, 0, tp.area.width() * sizeRatio, tp.area.height() * sizeRatio); + tp.area.moveCenter(QPoint(wx, wy)); + + // Calculate normalized pressure. + if (!hw_pressure_min && !hw_pressure_max) + tp.pressure = tp.state == Qt::TouchPointReleased ? 0 : 1; + else + tp.pressure = (tp.pressure - hw_pressure_min) / qreal(hw_pressure_max - hw_pressure_min); + } + + QWindowSystemInterface::handleTouchEvent(0, m_device, m_touchPoints); +} + + +QTouchScreenHandlerThread::QTouchScreenHandlerThread(const QString &spec) + : m_spec(spec), m_handler(0) { start(); } @@ -386,7 +410,6 @@ QTouchScreenHandlerThread::~QTouchScreenHandlerThread() void QTouchScreenHandlerThread::run() { m_handler = new QTouchScreenHandler(m_spec); - m_handler->addObserver(m_observer); exec(); delete m_handler; m_handler = 0; diff --git a/src/plugins/generic/touchscreen/qtouchscreen.h b/src/plugins/generic/evdevtouch/qevdevtouch.h similarity index 80% rename from src/plugins/generic/touchscreen/qtouchscreen.h rename to src/plugins/generic/evdevtouch/qevdevtouch.h index 33a1b0ad2fe..343f6385268 100644 --- a/src/plugins/generic/touchscreen/qtouchscreen.h +++ b/src/plugins/generic/evdevtouch/qevdevtouch.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QTOUCHSCREEN_H -#define QTOUCHSCREEN_H +#ifndef QEVDEVTOUCH_H +#define QEVDEVTOUCH_H #include #include @@ -55,14 +55,6 @@ QT_BEGIN_NAMESPACE class QSocketNotifier; class QTouchScreenData; -class QTouchScreenObserver -{ -public: - virtual void touch_configure(int x_min, int x_max, int y_min, int y_max, - int pressure_min, int pressure_max, const QString &dev_name) = 0; - virtual void touch_point(const QList &points) = 0; -}; - class QTouchScreenHandler : public QObject { Q_OBJECT @@ -70,13 +62,12 @@ class QTouchScreenHandler : public QObject public: QTouchScreenHandler(const QString &spec = QString()); ~QTouchScreenHandler(); - void addObserver(QTouchScreenObserver *observer); private slots: void readData(); private: - void try_udev(QString *path); + void pathFromUdev(QString *path); QSocketNotifier *m_notify; int m_fd; @@ -86,7 +77,7 @@ private: class QTouchScreenHandlerThread : public QThread { public: - QTouchScreenHandlerThread(const QString &spec, QTouchScreenObserver *observer); + QTouchScreenHandlerThread(const QString &spec); ~QTouchScreenHandlerThread(); void run(); QTouchScreenHandler *handler() { return m_handler; } @@ -94,11 +85,10 @@ public: private: QString m_spec; QTouchScreenHandler *m_handler; - QTouchScreenObserver *m_observer; }; QT_END_NAMESPACE QT_END_HEADER -#endif // QTOUCHSCREEN_H +#endif // QEVDEVTOUCH_H diff --git a/src/plugins/generic/generic.pro b/src/plugins/generic/generic.pro index 68c7636940c..c4c3f9229aa 100644 --- a/src/plugins/generic/generic.pro +++ b/src/plugins/generic/generic.pro @@ -1,3 +1,9 @@ TEMPLATE = subdirs linux-g++-maemo: SUBDIRS += meego + +contains(QT_CONFIG, evdev) { + contains(QT_CONFIG, libudev) { + SUBDIRS += evdevmouse evdevtouch + } +} diff --git a/src/plugins/generic/linuxinput/linuxinput.pro b/src/plugins/generic/linuxinput/linuxinput.pro deleted file mode 100644 index 6ef5f0fb3af..00000000000 --- a/src/plugins/generic/linuxinput/linuxinput.pro +++ /dev/null @@ -1,14 +0,0 @@ -TARGET = qlinuxinputplugin -load(qt_plugin) - -DESTDIR = $$QT.gui.plugins/generic -target.path = $$[QT_INSTALL_PLUGINS]/generic -INSTALLS += target - -HEADERS = qlinuxinput.h - -QT += core-private - -SOURCES = main.cpp \ - qlinuxinput.cpp - diff --git a/src/plugins/generic/linuxinput/qlinuxinput.cpp b/src/plugins/generic/linuxinput/qlinuxinput.cpp deleted file mode 100644 index 04633845cbe..00000000000 --- a/src/plugins/generic/linuxinput/qlinuxinput.cpp +++ /dev/null @@ -1,365 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtGui 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 "qlinuxinput.h" - - -#include -#include -#include -#include - -#include -#include // overrides QT_OPEN - -#include -#include - -#include -#include - -#include - -QT_BEGIN_NAMESPACE - - -//#define QT_QPA_EXPERIMENTAL_TOUCHEVENT - -#ifdef QT_QPA_EXPERIMENTAL_TOUCHEVENT -class QLinuxInputMouseHandlerData -{ -public: - QLinuxInputMouseHandlerData() :seenMT(false), state(QEvent::TouchBegin), currentIdx(0) {} - - void ensureCurrentPoint() { - if (currentIdx >= touchPoints.size()) { - Q_ASSERT(currentIdx == touchPoints.size()); - QWindowSystemInterface::TouchPoint tp; - tp.id = currentIdx; - tp.isPrimary = (currentIdx == 0); - tp.pressure = 1; - tp.area = QRectF(0,0,1,1); - tp.state = Qt::TouchPointReleased; // init in neutral state - touchPoints.append(tp); - } - } - void setCurrentPoint(int i) { - currentIdx = i; - if (currentIdx < touchPoints.size()) { - currentX = int(touchPoints[currentIdx].area.left()); - currentY = int(touchPoints[currentIdx].area.top()); - } else { - currentY = currentX = -999; - } - } - void advanceCurrentPoint() { - setCurrentPoint(currentIdx + 1); - } - int currentPoint() { return currentIdx; } - void setCurrentX(int value) { - ensureCurrentPoint(); - touchPoints[currentIdx].area.moveLeft(value); - } - bool currentMoved() { - return currentX != touchPoints[currentIdx].area.left() || currentY != touchPoints[currentIdx].area.top(); - } - void updateCurrentPos() { - ensureCurrentPoint(); - touchPoints[currentIdx].area.moveTopLeft(QPointF(currentX, currentY)); - } - void setCurrentState(Qt::TouchPointState state) { - ensureCurrentPoint(); - touchPoints[currentIdx].state = state; - } - Qt::TouchPointState currentState() const { - if (currentIdx < touchPoints.size()) - return touchPoints[currentIdx].state; - return Qt::TouchPointReleased; - } - QList touchPoints; - int currentX; - int currentY; - bool seenMT; - QEvent::Type state; -private: - int currentIdx; -}; -#endif - - -QLinuxInputMouseHandler::QLinuxInputMouseHandler(const QString &key, - const QString &specification) - : m_notify(0), m_x(0), m_y(0), m_prevx(0), m_prevy(0), m_xoffset(0), m_yoffset(0), m_buttons(0), d(0) -{ - qDebug() << "QLinuxInputMouseHandler" << key << specification; - - - setObjectName(QLatin1String("LinuxInputSubsystem Mouse Handler")); - - QString dev = QLatin1String("/dev/input/event0"); - m_compression = true; - m_smooth = false; - int jitterLimit = 0; - - QStringList args = specification.split(QLatin1Char(':')); - foreach (const QString &arg, args) { - if (arg == "nocompress") - m_compression = false; - else if (arg.startsWith("dejitter=")) - jitterLimit = arg.mid(9).toInt(); - else if (arg.startsWith("xoffset=")) - m_xoffset = arg.mid(8).toInt(); - else if (arg.startsWith("yoffset=")) - m_yoffset = arg.mid(8).toInt(); - else if (arg.startsWith(QLatin1String("/dev/"))) - dev = arg; - } - m_jitterLimitSquared = jitterLimit*jitterLimit; - - m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); - if (m_fd >= 0) { - m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); - connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData())); - } else { - qWarning("Cannot open mouse input device '%s': %s", qPrintable(dev), strerror(errno)); - return; - } -#ifdef QT_QPA_EXPERIMENTAL_TOUCHEVENT - d = new QLinuxInputMouseHandlerData; -#endif -} - - -QLinuxInputMouseHandler::~QLinuxInputMouseHandler() -{ - if (m_fd >= 0) - QT_CLOSE(m_fd); -#ifdef QT_QPA_EXPERIMENTAL_TOUCHEVENT - delete d; -#endif -} - -void QLinuxInputMouseHandler::sendMouseEvent(int x, int y, Qt::MouseButtons buttons) -{ - QPoint pos(x+m_xoffset, y+m_yoffset); - QWindowSystemInterface::handleMouseEvent(0, pos, pos, m_buttons); - m_prevx = x; - m_prevy = y; -} - -void QLinuxInputMouseHandler::readMouseData() -{ - struct ::input_event buffer[32]; - int n = 0; - bool posChanged = false; - bool pendingMouseEvent = false; - int eventCompressCount = 0; - forever { - n = QT_READ(m_fd, reinterpret_cast(buffer) + n, sizeof(buffer) - n); - - if (n == 0) { - qWarning("Got EOF from the input device."); - return; - } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) { - qWarning("Could not read from input device: %s", strerror(errno)); - return; - } else if (n % sizeof(buffer[0]) == 0) { - break; - } - } - - n /= sizeof(buffer[0]); - - for (int i = 0; i < n; ++i) { - struct ::input_event *data = &buffer[i]; - //qDebug() << ">>" << hex << data->type << data->code << dec << data->value; - bool unknown = false; - if (data->type == EV_ABS) { - if (data->code == ABS_X && m_x != data->value) { - m_x = data->value; - posChanged = true; - } else if (data->code == ABS_Y && m_y != data->value) { - m_y = data->value; - posChanged = true; - } else if (data->code == ABS_PRESSURE) { - //ignore for now... - } else if (data->code == ABS_TOOL_WIDTH) { - //ignore for now... - } else if (data->code == ABS_HAT0X) { - //ignore for now... - } else if (data->code == ABS_HAT0Y) { - //ignore for now... -#ifdef QT_QPA_EXPERIMENTAL_TOUCHEVENT - } else if (data->code == ABS_MT_POSITION_X) { - d->currentX = data->value; - d->seenMT = true; - } else if (data->code == ABS_MT_POSITION_Y) { - d->currentY = data->value; - d->seenMT = true; - } else if (data->code == ABS_MT_TOUCH_MAJOR) { - if (data->value == 0) - d->setCurrentState(Qt::TouchPointReleased); - //otherwise, ignore for now... - } else if (data->code == ABS_MT_TOUCH_MINOR) { - //ignore for now... -#endif - } else { - unknown = true; - } - } else if (data->type == EV_REL) { - if (data->code == REL_X) { - m_x += data->value; - posChanged = true; - } else if (data->code == REL_Y) { - m_y += data->value; - posChanged = true; - } else if (data->code == ABS_WHEEL) { // vertical scroll - // data->value: 1 == up, -1 == down - int delta = 120 * data->value; - QWindowSystemInterface::handleWheelEvent(0, QPoint(m_x, m_y), - QPoint(m_x, m_y), - delta, Qt::Vertical); - } else if (data->code == ABS_THROTTLE) { // horizontal scroll - // data->value: 1 == right, -1 == left - int delta = 120 * -data->value; - QWindowSystemInterface::handleWheelEvent(0, QPoint(m_x, m_y), - QPoint(m_x, m_y), - delta, Qt::Horizontal); - } else { - unknown = true; - } - } else if (data->type == EV_KEY && data->code == BTN_TOUCH) { - m_buttons = data->value ? Qt::LeftButton : Qt::NoButton; - - sendMouseEvent(m_x, m_y, m_buttons); - pendingMouseEvent = false; - } else if (data->type == EV_KEY && data->code >= BTN_LEFT && data->code <= BTN_MIDDLE) { - Qt::MouseButton button = Qt::NoButton; - switch (data->code) { - case BTN_LEFT: button = Qt::LeftButton; break; - case BTN_MIDDLE: button = Qt::MidButton; break; - case BTN_RIGHT: button = Qt::RightButton; break; - } - if (data->value) - m_buttons |= button; - else - m_buttons &= ~button; - sendMouseEvent(m_x, m_y, m_buttons); - pendingMouseEvent = false; - } else if (data->type == EV_SYN && data->code == SYN_REPORT) { - if (posChanged) { - posChanged = false; - if (m_compression) { - pendingMouseEvent = true; - eventCompressCount++; - } else { - sendMouseEvent(m_x, m_y, m_buttons); - } - } -#ifdef QT_QPA_EXPERIMENTAL_TOUCHEVENT - if (d->state == QEvent::TouchBegin && !d->seenMT) { - //no multipoint-touch events to send - } else { - if (!d->seenMT) - d->state = QEvent::TouchEnd; - - for (int i = d->currentPoint(); i < d->touchPoints.size(); ++i) { - d->touchPoints[i].pressure = 0; - d->touchPoints[i].state = Qt::TouchPointReleased; - } - //qDebug() << "handleTouchEvent" << d->state << d->touchPoints.size() << d->touchPoints[0].state; - QWindowSystemInterface::handleTouchEvent(0, d->state, QTouchEvent::TouchScreen, d->touchPoints); - if (d->seenMT) { - d->state = QEvent::TouchUpdate; - } else { - d->state = QEvent::TouchBegin; - d->touchPoints.clear(); - } - d->setCurrentPoint(0); - d->seenMT = false; - } - } else if (data->type == EV_SYN && data->code == SYN_MT_REPORT) { - //store data for this touch point - - if (!d->seenMT) { - d->setCurrentState(Qt::TouchPointReleased); - } else if (d->currentState() == Qt::TouchPointReleased) { - d->updateCurrentPos(); - d->setCurrentState(Qt::TouchPointPressed); - } else if (d->currentMoved()) { - d->updateCurrentPos(); - d->setCurrentState(Qt::TouchPointMoved); - } else { - d->setCurrentState(Qt::TouchPointStationary); - } - //qDebug() << "end of point" << d->currentPoint() << d->currentX << d->currentY << d->currentState(); - - //advance to next tp: - d->advanceCurrentPoint(); -#endif - } else if (data->type == EV_MSC && data->code == MSC_SCAN) { - // kernel encountered an unmapped key - just ignore it - continue; - } else { - unknown = true; - } -#ifdef QLINUXINPUT_EXTRA_DEBUG - if (unknown) { - qWarning("unknown mouse event type=%x, code=%x, value=%x", data->type, data->code, data->value); - } -#endif - } - if (m_compression && pendingMouseEvent) { - int distanceSquared = (m_x - m_prevx)*(m_x - m_prevx) + (m_y - m_prevy)*(m_y - m_prevy); - if (distanceSquared > m_jitterLimitSquared) - sendMouseEvent(m_x, m_y, m_buttons); - } -} - - - - - - - -QT_END_NAMESPACE - diff --git a/src/plugins/generic/touchscreen/README b/src/plugins/generic/touchscreen/README deleted file mode 100644 index ac73f5f147e..00000000000 --- a/src/plugins/generic/touchscreen/README +++ /dev/null @@ -1,45 +0,0 @@ -Generic plug-in for evdev touch events. - -Tested with the following drivers: bcm5974, hid_magicmouse. - -(1) Using as a QPA generic plug-in - -1. set up and connect the touch device -2. install libudev-dev or similar -3. build this plug-in (qmake && make) -4. sudo cp 70-qtouchscreen.rules /etc/udev/rules.d -5. sudo udevadm trigger --subsystem-match=input -6. ./fingerpaint -plugin LinuxTouchScreen:force_window - -If automatic detection does not work, use -plugin -LinuxTouchScreen:/dev/input/eventN to explicitly set the device file -name. - -By default the surface of the touch device is mapped to the entire -screen. If this is not desired, pass force_window in the plugin -specification as shown in the example above. This will cause mapping -the touch surface to the active window instead. - -Only touch events are generated, mouse events are not. Be aware however -that ignored touch events will generate a mouse event from the first -touch point by default. See AA_SynthesizeMouseForUnhandledTouchEvents. - -(2) Using in a compositor - -The classes (QTouchScreenHandler, QTouchScreenHandlerThread) are also -suitable for direct inclusion into an application, e.g. a Wayland -compositor. The compositor may then register its own -QTouchScreenObserver because relying on the QTouchEvents generated by -the QPA event sender may not always be satisfactory as some low-level -details get lost, and due to performance reasons. - -(3) Possible issues and solutions - -The udev rule matches any touchpad device. If there are multiple ones, -specify the device as described above. - -If no evdev events are read, remove 50-synaptics.conf (or similar) -from /usr/share/X11/xorg.conf.d and restart X. Or at least temporarily -disable the device by running xinput set-prop 0. Use xinput list and xinput list-props to figure out the -values. diff --git a/src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp b/src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp deleted file mode 100644 index ac4a12c09a4..00000000000 --- a/src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins 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 "qtoucheventsenderqpa.h" -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -QTouchEventSenderQPA::QTouchEventSenderQPA(const QString &spec) -{ - m_forceToActiveWindow = spec.split(QLatin1Char(':')).contains(QLatin1String("force_window")); - m_device = new QTouchDevice; - m_device->setType(QTouchDevice::TouchScreen); - m_device->setCapabilities(QTouchDevice::Position | QTouchDevice::Area); - QWindowSystemInterface::registerTouchDevice(m_device); -} - -void QTouchEventSenderQPA::touch_configure(int x_min, int x_max, int y_min, int y_max, - int pressure_min, int pressure_max, - const QString &dev_name) -{ - hw_range_x_min = x_min; - hw_range_x_max = x_max; - hw_range_y_min = y_min; - hw_range_y_max = y_max; - - hw_pressure_min = pressure_min; - hw_pressure_max = pressure_max; - - m_device->setName(dev_name); - - if (hw_pressure_max > hw_pressure_min) - m_device->setCapabilities(m_device->capabilities() | QTouchDevice::Pressure); -} - -void QTouchEventSenderQPA::touch_point(const QList &points) -{ - QRect winRect; - if (m_forceToActiveWindow) { - QWindow *win = QGuiApplication::activeWindow(); - if (!win) - return; - winRect = win->geometry(); - } else { - winRect = QGuiApplication::primaryScreen()->geometry(); - } - - const int hw_w = hw_range_x_max - hw_range_x_min; - const int hw_h = hw_range_y_max - hw_range_y_min; - - QList touchPoints = points; - // Map the coordinates based on the normalized position. QPA expects 'area' - // to be in screen coordinates. - for (int i = 0; i < touchPoints.size(); ++i) { - QWindowSystemInterface::TouchPoint &tp(touchPoints[i]); - - // Generate a screen position that is always inside the active window - // or the primary screen. - const int wx = winRect.left() + int(tp.normalPosition.x() * winRect.width()); - const int wy = winRect.top() + int(tp.normalPosition.y() * winRect.height()); - const qreal sizeRatio = (winRect.width() + winRect.height()) / qreal(hw_w + hw_h); - tp.area = QRect(0, 0, tp.area.width() * sizeRatio, tp.area.height() * sizeRatio); - tp.area.moveCenter(QPoint(wx, wy)); - - // Calculate normalized pressure. - if (!hw_pressure_min && !hw_pressure_max) - tp.pressure = tp.state == Qt::TouchPointReleased ? 0 : 1; - else - tp.pressure = (tp.pressure - hw_pressure_min) / qreal(hw_pressure_max - hw_pressure_min); - } - - QWindowSystemInterface::handleTouchEvent(0, m_device, touchPoints); -} - -QT_END_NAMESPACE diff --git a/src/plugins/generic/touchscreen/touchscreen.pro b/src/plugins/generic/touchscreen/touchscreen.pro deleted file mode 100644 index 60aa29c5ecc..00000000000 --- a/src/plugins/generic/touchscreen/touchscreen.pro +++ /dev/null @@ -1,18 +0,0 @@ -TARGET = qtouchscreenplugin -load(qt_plugin) - -DESTDIR = $$QT.gui.plugins/generic -target.path = $$[QT_INSTALL_PLUGINS]/generic -INSTALLS += target - -HEADERS = \ - qtouchscreen.h \ - qtoucheventsenderqpa.h - -SOURCES = main.cpp \ - qtouchscreen.cpp \ - qtoucheventsenderqpa.cpp - -QT += core-private gui-private - -LIBS += -ludev From da18ada6bf60e0a6724ee55abb619d367f8c4633 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 1 Feb 2012 15:42:00 +1000 Subject: [PATCH 051/406] testlib: Clear expected failures after every data row. Previously, expected failures were only cleared at the end of each test function, i.e. after all data rows were finished. This meant that if a data-driven test function called QEXPECT_FAIL and then didn't perform any further verification steps to trigger the expected failure, the expected failure would be carried over to the next data row, probably causing the first verification step in the test function to XPASS (with a seemingly irrelevant error message) for the next data row. This commit adds the new function QTestResult::finishedCurrentTestData() to cleanup after each data row is executed. This function treats calls to QEXPECT_FAIL without subsequent verification steps as a test failure. This commit also adds a regression test to demonstrate that expected failures can no longer be carried over from one data row to another. If run against the previous version of testlib, the new test would report a pass instead of an error. Change-Id: Ida5c7f080815b0dca9531131fed582b0918334cb Reviewed-by: Rohan McGovern --- src/testlib/qtestcase.cpp | 2 ++ src/testlib/qtestresult.cpp | 9 ++++-- src/testlib/qtestresult_p.h | 1 + .../selftests/expected_expectfail.lightxml | 32 ++++++++++++------- .../testlib/selftests/expected_expectfail.txt | 26 ++++++++------- .../testlib/selftests/expected_expectfail.xml | 32 ++++++++++++------- .../selftests/expected_expectfail.xunitxml | 6 +++- .../selftests/expectfail/tst_expectfail.cpp | 16 ++++++++++ 8 files changed, 87 insertions(+), 37 deletions(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index b76ff39de4f..84b03b73235 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1506,6 +1506,8 @@ static void qInvokeTestMethodDataEntry(char *slot) if (!invokeOk) QTestResult::addFailure("Unable to execute slot", __FILE__, __LINE__); + QTestResult::finishedCurrentTestData(); + QTestResult::setCurrentTestLocation(QTestResult::CleanupFunc); invokeMethod(QTest::currentTestObject, "cleanup()"); QTestResult::setCurrentTestLocation(QTestResult::NoWhere); diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp index d6846f363b9..c3634eb01ee 100644 --- a/src/testlib/qtestresult.cpp +++ b/src/testlib/qtestresult.cpp @@ -127,6 +127,13 @@ static void clearExpectFail() QTest::expectFailComment = 0; } +void QTestResult::finishedCurrentTestData() +{ + if (QTest::expectFailMode) + addFailure("QEXPECT_FAIL was called without any subsequent verification statements", 0, 0); + clearExpectFail(); +} + void QTestResult::finishedCurrentTestFunction() { if (!QTest::failed && QTestLog::unhandledIgnoreMessages()) { @@ -143,8 +150,6 @@ void QTestResult::finishedCurrentTestFunction() QTest::location = NoWhere; QTestLog::leaveTestFunction(); - - clearExpectFail(); } const char *QTestResult::currentTestFunction() diff --git a/src/testlib/qtestresult_p.h b/src/testlib/qtestresult_p.h index 5bbb7e2d27b..81e11180ef2 100644 --- a/src/testlib/qtestresult_p.h +++ b/src/testlib/qtestresult_p.h @@ -73,6 +73,7 @@ public: static TestLocation currentTestLocation(); static const char *currentDataTag(); static const char *currentGlobalDataTag(); + static void finishedCurrentTestData(); static void finishedCurrentTestFunction(); static void reset(); diff --git a/tests/auto/testlib/selftests/expected_expectfail.lightxml b/tests/auto/testlib/selftests/expected_expectfail.lightxml index 02e4dde7d88..eab0bbbaa38 100644 --- a/tests/auto/testlib/selftests/expected_expectfail.lightxml +++ b/tests/auto/testlib/selftests/expected_expectfail.lightxml @@ -9,7 +9,7 @@ - + @@ -21,31 +21,31 @@ - + - + - + - + - + - + @@ -55,23 +55,33 @@ - + - + + + + + + + + + + + - + - + diff --git a/tests/auto/testlib/selftests/expected_expectfail.txt b/tests/auto/testlib/selftests/expected_expectfail.txt index 1b98b6b561a..0286490372c 100644 --- a/tests/auto/testlib/selftests/expected_expectfail.txt +++ b/tests/auto/testlib/selftests/expected_expectfail.txt @@ -3,35 +3,37 @@ Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE PASS : tst_ExpectFail::initTestCase() QDEBUG : tst_ExpectFail::xfailAndContinue() begin XFAIL : tst_ExpectFail::xfailAndContinue() This should xfail - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(72)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(74)] QDEBUG : tst_ExpectFail::xfailAndContinue() after PASS : tst_ExpectFail::xfailAndContinue() QDEBUG : tst_ExpectFail::xfailAndAbort() begin XFAIL : tst_ExpectFail::xfailAndAbort() This should xfail - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(80)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(82)] PASS : tst_ExpectFail::xfailAndAbort() FAIL! : tst_ExpectFail::xfailTwice() Already expecting a fail - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(90)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(92)] XFAIL : tst_ExpectFail::xfailWithQString() A string - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(99)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(101)] XFAIL : tst_ExpectFail::xfailWithQString() Bug 5 (The message) - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(104)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(106)] PASS : tst_ExpectFail::xfailWithQString() XFAIL : tst_ExpectFail::xfailDataDriven(Abort) This test should xfail - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(133)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(135)] XFAIL : tst_ExpectFail::xfailDataDriven(Continue) This test should xfail - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(133)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(135)] PASS : tst_ExpectFail::xfailDataDriven() PASS : tst_ExpectFail::xfailOnWrongRow() XFAIL : tst_ExpectFail::xfailOnAnyRow(first row) This test should xfail - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(168)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(170)] XFAIL : tst_ExpectFail::xfailOnAnyRow(second row) This test should xfail - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(168)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(170)] PASS : tst_ExpectFail::xfailOnAnyRow() +FAIL! : tst_ExpectFail::xfailWithoutVerify(first row) QEXPECT_FAIL was called without any subsequent verification statements +FAIL! : tst_ExpectFail::xfailWithoutVerify(second row) QEXPECT_FAIL was called without any subsequent verification statements XPASS : tst_ExpectFail::xpass() 'true' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(172)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(190)] XPASS : tst_ExpectFail::xpassDataDriven(XPass) 'true' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(196)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(212)] PASS : tst_ExpectFail::cleanupTestCase() -Totals: 8 passed, 3 failed, 0 skipped +Totals: 8 passed, 5 failed, 0 skipped ********* Finished testing of tst_ExpectFail ********* diff --git a/tests/auto/testlib/selftests/expected_expectfail.xml b/tests/auto/testlib/selftests/expected_expectfail.xml index 74b11fb0e5e..3c8baf92712 100644 --- a/tests/auto/testlib/selftests/expected_expectfail.xml +++ b/tests/auto/testlib/selftests/expected_expectfail.xml @@ -11,7 +11,7 @@ - + @@ -23,31 +23,31 @@ - + - + - + - + - + - + @@ -57,23 +57,33 @@ - + - + + + + + + + + + + + - + - + diff --git a/tests/auto/testlib/selftests/expected_expectfail.xunitxml b/tests/auto/testlib/selftests/expected_expectfail.xunitxml index 017e4501c19..d13cf6687fe 100644 --- a/tests/auto/testlib/selftests/expected_expectfail.xunitxml +++ b/tests/auto/testlib/selftests/expected_expectfail.xunitxml @@ -1,5 +1,5 @@ - + @@ -30,6 +30,10 @@ + + + + diff --git a/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp b/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp index 3a000ba1826..56895b38015 100644 --- a/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp +++ b/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp @@ -60,6 +60,8 @@ private slots: void xfailOnWrongRow() const; void xfailOnAnyRow_data() const; void xfailOnAnyRow() const; + void xfailWithoutVerify_data() const; + void xfailWithoutVerify() const; void xpass() const; void xpassDataDriven_data() const; void xpassDataDriven() const; @@ -168,6 +170,20 @@ void tst_ExpectFail::xfailOnAnyRow() const QVERIFY(false); } +void tst_ExpectFail::xfailWithoutVerify_data() const +{ + QTest::addColumn("dummy"); + + QTest::newRow("first row") << 0; + QTest::newRow("second row") << 1; +} + +void tst_ExpectFail::xfailWithoutVerify() const +{ + QVERIFY(true); + QEXPECT_FAIL("", "This expected failure should be ignored", Abort); +} + void tst_ExpectFail::xpass() const { QEXPECT_FAIL("", "This test should xpass", Abort); From 26c41ed918142a6fadac142b4f7e63426bebc4a1 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 1 Feb 2012 16:39:14 +1000 Subject: [PATCH 052/406] testlib: Clear ignored messages after every data row Previously, ignored messages were only cleared at the end of each test function, i.e. after all data rows were finished. This meant that if a data row in a data-driven test function didn't cause all of the expected messages to be generated, the remaining messages would be carried over to the next data row. This would result in errors about missing messages being associated with the last data row rather than with the correct data row. This commit makes testlib check for missing ignored messages after running each data row rather than only doing so after the last data row. This commit also adds a regression test to demonstrate that ignored messages can no longer be carried over from one data row to another. Change-Id: Ibee51aa6e96866fbcbcb4acee1a8340a86a6a4ba Reviewed-by: Rohan McGovern --- src/testlib/qtestlog.cpp | 6 ++++- src/testlib/qtestlog_p.h | 1 + src/testlib/qtestresult.cpp | 11 ++++---- .../selftests/expected_warnings.lightxml | 26 +++++++++++++++++++ .../testlib/selftests/expected_warnings.txt | 8 +++++- .../testlib/selftests/expected_warnings.xml | 26 +++++++++++++++++++ .../selftests/expected_warnings.xunitxml | 14 +++++++++- .../selftests/warnings/tst_warnings.cpp | 19 ++++++++++++++ 8 files changed, 103 insertions(+), 8 deletions(-) diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp index 1d66101a0fc..29dfbc144e3 100644 --- a/src/testlib/qtestlog.cpp +++ b/src/testlib/qtestlog.cpp @@ -302,7 +302,6 @@ void QTestLog::leaveTestFunction() if (printAvailableTags) return; - QTest::IgnoreResultList::clearList(QTest::ignoreResultList); QTest::TestLoggers::leaveTestFunction(); } @@ -318,6 +317,11 @@ void QTestLog::printUnhandledIgnoreMessages() } } +void QTestLog::clearIgnoreMessages() +{ + QTest::IgnoreResultList::clearList(QTest::ignoreResultList); +} + void QTestLog::addPass(const char *msg) { if (printAvailableTags) diff --git a/src/testlib/qtestlog_p.h b/src/testlib/qtestlog_p.h index e45d9c9626d..1fe52367ec7 100644 --- a/src/testlib/qtestlog_p.h +++ b/src/testlib/qtestlog_p.h @@ -77,6 +77,7 @@ public: static void ignoreMessage(QtMsgType type, const char *msg); static int unhandledIgnoreMessages(); static void printUnhandledIgnoreMessages(); + static void clearIgnoreMessages(); static void warn(const char *msg, const char *file, int line); static void info(const char *msg, const char *file, int line); diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp index c3634eb01ee..c49c7aefe36 100644 --- a/src/testlib/qtestresult.cpp +++ b/src/testlib/qtestresult.cpp @@ -132,15 +132,16 @@ void QTestResult::finishedCurrentTestData() if (QTest::expectFailMode) addFailure("QEXPECT_FAIL was called without any subsequent verification statements", 0, 0); clearExpectFail(); + + if (!QTest::dataFailed && QTestLog::unhandledIgnoreMessages()) { + QTestLog::printUnhandledIgnoreMessages(); + addFailure("Not all expected messages were received", 0, 0); + } + QTestLog::clearIgnoreMessages(); } void QTestResult::finishedCurrentTestFunction() { - if (!QTest::failed && QTestLog::unhandledIgnoreMessages()) { - QTestLog::printUnhandledIgnoreMessages(); - addFailure("Not all expected messages were received", 0, 0); - } - if (!QTest::failed && !QTest::skipCurrentTest) { QTestLog::addPass(""); } diff --git a/tests/auto/testlib/selftests/expected_warnings.lightxml b/tests/auto/testlib/selftests/expected_warnings.lightxml index 116156ed8ad..ad786832ca4 100644 --- a/tests/auto/testlib/selftests/expected_warnings.lightxml +++ b/tests/auto/testlib/selftests/expected_warnings.lightxml @@ -37,6 +37,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_warnings.txt b/tests/auto/testlib/selftests/expected_warnings.txt index 6f7d0f491bd..6196ec0261b 100644 --- a/tests/auto/testlib/selftests/expected_warnings.txt +++ b/tests/auto/testlib/selftests/expected_warnings.txt @@ -11,6 +11,12 @@ PASS : tst_Warnings::testWarnings() INFO : tst_Warnings::testMissingWarnings() Did not receive message: "Warning0" INFO : tst_Warnings::testMissingWarnings() Did not receive message: "Warning1" FAIL! : tst_Warnings::testMissingWarnings() Not all expected messages were received +INFO : tst_Warnings::testMissingWarningsWithData(first row) Did not receive message: "Warning0" +INFO : tst_Warnings::testMissingWarningsWithData(first row) Did not receive message: "Warning1" +FAIL! : tst_Warnings::testMissingWarningsWithData(first row) Not all expected messages were received +INFO : tst_Warnings::testMissingWarningsWithData(second row) Did not receive message: "Warning0" +INFO : tst_Warnings::testMissingWarningsWithData(second row) Did not receive message: "Warning1" +FAIL! : tst_Warnings::testMissingWarningsWithData(second row) Not all expected messages were received PASS : tst_Warnings::cleanupTestCase() -Totals: 3 passed, 1 failed, 0 skipped +Totals: 3 passed, 3 failed, 0 skipped ********* Finished testing of tst_Warnings ********* diff --git a/tests/auto/testlib/selftests/expected_warnings.xml b/tests/auto/testlib/selftests/expected_warnings.xml index 13e6c1df793..12cff7c13db 100644 --- a/tests/auto/testlib/selftests/expected_warnings.xml +++ b/tests/auto/testlib/selftests/expected_warnings.xml @@ -39,6 +39,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_warnings.xunitxml b/tests/auto/testlib/selftests/expected_warnings.xunitxml index a96393d6488..3e3b9ce18ea 100644 --- a/tests/auto/testlib/selftests/expected_warnings.xunitxml +++ b/tests/auto/testlib/selftests/expected_warnings.xunitxml @@ -1,5 +1,5 @@ - + @@ -18,6 +18,14 @@ + + + + + + + + @@ -27,6 +35,10 @@ + + + + diff --git a/tests/auto/testlib/selftests/warnings/tst_warnings.cpp b/tests/auto/testlib/selftests/warnings/tst_warnings.cpp index 933d0cc6cec..e53869e18ec 100644 --- a/tests/auto/testlib/selftests/warnings/tst_warnings.cpp +++ b/tests/auto/testlib/selftests/warnings/tst_warnings.cpp @@ -49,6 +49,8 @@ class tst_Warnings: public QObject private slots: void testWarnings(); void testMissingWarnings(); + void testMissingWarningsWithData_data(); + void testMissingWarningsWithData(); }; void tst_Warnings::testWarnings() @@ -82,6 +84,23 @@ void tst_Warnings::testMissingWarnings() qWarning("Warning2"); } +void tst_Warnings::testMissingWarningsWithData_data() +{ + QTest::addColumn("dummy"); + + QTest::newRow("first row") << 0; + QTest::newRow("second row") << 1; +} + +void tst_Warnings::testMissingWarningsWithData() +{ + QTest::ignoreMessage(QtWarningMsg, "Warning0"); + QTest::ignoreMessage(QtWarningMsg, "Warning1"); + QTest::ignoreMessage(QtWarningMsg, "Warning2"); + + qWarning("Warning2"); +} + QTEST_MAIN(tst_Warnings) #include "tst_warnings.moc" From 3a706b17d39fafc405fd97210968f09af6a1ac8e Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 7 Feb 2012 10:57:12 +0100 Subject: [PATCH 053/406] Add the mkspecs dir to the include dirs. Change-Id: If844785d7d3645c33e0fcb1206cc52f8ab644070 Reviewed-by: Oswald Buddenhagen Reviewed-by: Alexander Neundorf Reviewed-by: Stephen Kelly --- src/corelib/Qt5CoreConfigExtras.cmake.in | 2 + tests/manual/cmake/CMakeLists.txt | 1 + tests/manual/cmake/pass7/CMakeLists.txt | 10 +++++ tests/manual/cmake/pass7/main.cpp | 47 ++++++++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 tests/manual/cmake/pass7/CMakeLists.txt create mode 100644 tests/manual/cmake/pass7/main.cpp diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index e97493f65d0..23a026e6151 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -5,3 +5,5 @@ get_filename_component(_qt5_corelib_install_prefix ${CMAKE_CURRENT_LIST_DIR}/$${ set(QT_QMAKE_EXECUTABLE \"${_qt5_corelib_install_prefix}/$$CMAKE_BIN_DIR/qmake$$CMAKE_BIN_SUFFIX\") set(QT_MOC_EXECUTABLE \"${_qt5_corelib_install_prefix}/$$CMAKE_BIN_DIR/moc$$CMAKE_BIN_SUFFIX\") set(QT_RCC_EXECUTABLE \"${_qt5_corelib_install_prefix}/$$CMAKE_BIN_DIR/rcc$$CMAKE_BIN_SUFFIX\") + +list(APPEND Qt5Core_INCLUDE_DIRS \"${_qt5_corelib_install_prefix}/mkspecs/default\") diff --git a/tests/manual/cmake/CMakeLists.txt b/tests/manual/cmake/CMakeLists.txt index 7eca679e1b6..07fee062be9 100644 --- a/tests/manual/cmake/CMakeLists.txt +++ b/tests/manual/cmake/CMakeLists.txt @@ -34,3 +34,4 @@ expect_pass(pass3) expect_fail(fail4) expect_fail(fail5) expect_pass("pass(needsquoting)6") +expect_pass(pass7) diff --git a/tests/manual/cmake/pass7/CMakeLists.txt b/tests/manual/cmake/pass7/CMakeLists.txt new file mode 100644 index 00000000000..f639c164ea2 --- /dev/null +++ b/tests/manual/cmake/pass7/CMakeLists.txt @@ -0,0 +1,10 @@ + +cmake_minimum_required(VERSION 2.8) + +project(pass7) + +find_package(Qt5Core REQUIRED) + +include_directories(${Qt5Core_INCLUDE_DIRS}) + +add_executable(myobject main.cpp) diff --git a/tests/manual/cmake/pass7/main.cpp b/tests/manual/cmake/pass7/main.cpp new file mode 100644 index 00000000000..0a6b09d877a --- /dev/null +++ b/tests/manual/cmake/pass7/main.cpp @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite 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 "qplatformdefs.h" + +int main(int argc, char **argv) +{ + return 0; +} From a313db2c81c904e9cdb7099d0ebd0a906b887637 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 7 Feb 2012 16:44:24 +0100 Subject: [PATCH 054/406] Fix warnings in input contexts. Change-Id: Idbd46b8bfe73015cce98d510992b3bb57c1e1ded Reviewed-by: Simon Hausmann --- .../platforminputcontexts/ibus/qibusplatforminputcontext.cpp | 2 +- .../maliit/qmaliitplatforminputcontext.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp index 5840415ded1..5579b4cd26e 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp @@ -103,7 +103,7 @@ bool QIBusPlatformInputContext::isValid() const return d->valid; } -void QIBusPlatformInputContext::invokeAction(QInputMethod::Action a, int x) +void QIBusPlatformInputContext::invokeAction(QInputMethod::Action a, int) { if (!d->valid) return; diff --git a/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.cpp b/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.cpp index bd3b914f157..dbb4e6e650f 100644 --- a/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.cpp @@ -287,7 +287,7 @@ void QMaliitPlatformInputContext::activationLostEvent() d->visibility = InputPanelHidden; } -void QMaliitPlatformInputContext::commitString(const QString &string, int replacementStart, int replacementLength, int cursorPos) +void QMaliitPlatformInputContext::commitString(const QString &string, int replacementStart, int replacementLength, int /* cursorPos */) { QObject *input = qApp->inputMethod()->inputItem(); if (!input) From 029bad8b5a3aef6a9ad86bf18e83bdad8ce9ffd2 Mon Sep 17 00:00:00 2001 From: Jonathan Liu Date: Tue, 7 Feb 2012 19:25:51 +1100 Subject: [PATCH 055/406] Fix compilation with MinGW-w64 Fix compilation with MinGW-w64 with the following changes: - Include intrin.h to fix __cpuid not declared error - Include intrin.h before *mmintrin.h headers to avoid extern linkable mismatch - Use quintptr instead of unsigned long to handle LLP64 - Do not declare winuser.h structs already provided with MinGW-w64 - Work around IID_IShellItem being declared but not defined with MinGW-w64 - Remove incorrect use of SUCCEEDED macro on pointer Change-Id: Ia21f8e3a1d225cf501e646eacd968bfc744ce0a2 Reviewed-by: Friedemann Kleint --- src/corelib/tools/qsimd.cpp | 2 +- src/corelib/tools/qsimd_p.h | 4 ++++ .../platforms/minimal/qminimalbackingstore.cpp | 2 +- .../platforms/windows/qtwindows_additional.h | 4 ++++ .../platforms/windows/qwindowsdialoghelpers.cpp | 13 ++++++++++++- 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index d65dfa35a64..b3d2d62819b 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -47,7 +47,7 @@ # if defined(Q_OS_WINCE) # include # endif -# if defined(Q_OS_WIN64) && !defined(Q_CC_GNU) +# if defined(Q_OS_WIN64) # include # endif #elif defined(Q_OS_LINUX) && defined(__arm__) diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index 47c4a9952be..44428b72849 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -62,6 +62,10 @@ QT_BEGIN_HEADER #undef QT_HAVE_MMX #endif +#ifdef __MINGW64_VERSION_MAJOR +#include +#endif + // SSE intrinsics #if defined(QT_HAVE_SSE2) && (defined(__SSE2__) || defined(Q_CC_MSVC)) #if defined(QT_LINUXBASE) diff --git a/src/plugins/platforms/minimal/qminimalbackingstore.cpp b/src/plugins/platforms/minimal/qminimalbackingstore.cpp index b6b9c0e9798..319b55ee670 100644 --- a/src/plugins/platforms/minimal/qminimalbackingstore.cpp +++ b/src/plugins/platforms/minimal/qminimalbackingstore.cpp @@ -53,7 +53,7 @@ QMinimalBackingStore::QMinimalBackingStore(QWindow *window) if (QT_PREPEND_NAMESPACE(qgetenv)("QT_DEBUG_BACKINGSTORE").toInt() > 0) mDebug = true; if (mDebug) - qDebug() << "QMinimalBackingStore::QMinimalBackingStore:" << (long)this; + qDebug() << "QMinimalBackingStore::QMinimalBackingStore:" << (quintptr)this; } QMinimalBackingStore::~QMinimalBackingStore() diff --git a/src/plugins/platforms/windows/qtwindows_additional.h b/src/plugins/platforms/windows/qtwindows_additional.h index 864107e392d..a85a798b9ed 100644 --- a/src/plugins/platforms/windows/qtwindows_additional.h +++ b/src/plugins/platforms/windows/qtwindows_additional.h @@ -66,6 +66,8 @@ #define IFACEMETHODIMP STDMETHODIMP #define IFACEMETHODIMP_(type) STDMETHODIMP_(type) +#if !defined(__MINGW64_VERSION_MAJOR) + typedef struct tagUPDATELAYEREDWINDOWINFO { DWORD cbSize; HDC hdcDst; @@ -79,6 +81,8 @@ typedef struct tagUPDATELAYEREDWINDOWINFO { const RECT *prcDirty; } UPDATELAYEREDWINDOWINFO, *PUPDATELAYEREDWINDOWINFO; +#endif // if !defined(__MINGW64_VERSION_MAJOR) + // OpenGL Pixelformat flags. #define PFD_SUPPORT_DIRECTDRAW 0x00002000 #define PFD_DIRECT3D_ACCELERATED 0x00004000 diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index f7863ae4277..8875590e639 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -76,7 +76,12 @@ static const IID IID_IFileOpenDialog = {0xd57c7288, 0xd4ad, 0x4768, {0xbe, 0x02, 0x9d, 0x96, 0x95, 0x32, 0xd9, 0x60}}; static const IID IID_IFileSaveDialog = {0x84bccd23, 0x5fde, 0x4cdb,{0xae, 0xa4, 0xaf, 0x64, 0xb8, 0x3d, 0x78, 0xab}}; +#ifdef __MINGW64_VERSION_MAJOR +static const IID q_IID_IShellItem = {0x43826d1e, 0xe718, 0x42ee, {0xbc, 0x55, 0xa1, 0xe2, 0x61, 0xc3, 0x7b, 0xfe}}; +#define IID_IShellItem q_IID_IShellItem +#else static const IID IID_IShellItem = {0x43826d1e, 0xe718, 0x42ee, {0xbc, 0x55, 0xa1, 0xe2, 0x61, 0xc3, 0x7b, 0xfe}}; +#endif static const IID IID_IFileDialogEvents = {0x973510db, 0x7d7f, 0x452b,{0x89, 0x75, 0x74, 0xa8, 0x58, 0x28, 0xd3, 0x54}}; static const CLSID CLSID_FileOpenDialog = {0xdc1c5a9c, 0xe88a, 0x4dde, {0xa5, 0xa1, 0x60, 0xf8, 0x2a, 0x20, 0xae, 0xf7}}; static const CLSID CLSID_FileSaveDialog = {0xc0b4e2f3, 0xba21, 0x4773,{0x8d, 0xba, 0x33, 0x5e, 0xc9, 0x46, 0xeb, 0x8b}}; @@ -141,6 +146,7 @@ typedef enum { SIATTRIBFLAGS_APPCOMPAT = 0x3, SIATTRIBFLAGS_MASK = 0x3 } SIATTRIBFLAGS; +#ifndef __MINGW64_VERSION_MAJOR typedef enum { SIGDN_NORMALDISPLAY = 0x00000000, SIGDN_PARENTRELATIVEPARSING = 0x80018001, @@ -151,6 +157,7 @@ typedef enum { SIGDN_FILESYSPATH = 0x80058000, SIGDN_URL = 0x80068000 } SIGDN; +#endif typedef enum { FDAP_BOTTOM = 0x00000000, FDAP_TOP = 0x00000001 @@ -193,6 +200,7 @@ typedef struct { DECLARE_INTERFACE(IFileDialogEvents); +#ifndef __MINGW64_VERSION_MAJOR DECLARE_INTERFACE_(IShellItem, IUnknown) { STDMETHOD(BindToHandler)(THIS_ IBindCtx *pbc, REFGUID bhid, REFIID riid, void **ppv) PURE; @@ -201,6 +209,7 @@ DECLARE_INTERFACE_(IShellItem, IUnknown) STDMETHOD(GetAttributes)(THIS_ ULONG sfgaoMask, ULONG *psfgaoAttribs) PURE; STDMETHOD(Compare)(THIS_ IShellItem *psi, DWORD hint, int *piOrder) PURE; }; +#endif DECLARE_INTERFACE_(IShellItemFilter, IUnknown) { @@ -227,10 +236,12 @@ DECLARE_INTERFACE_(IShellItemArray, IUnknown) STDMETHOD(EnumItems)(THIS_ IEnumShellItems **ppenumShellItems) PURE; }; +#ifndef __MINGW64_VERSION_MAJOR DECLARE_INTERFACE_(IModalWindow, IUnknown) { STDMETHOD(Show)(THIS_ HWND hwndParent) PURE; }; +#endif DECLARE_INTERFACE_(IFileDialog, IModalWindow) { @@ -754,7 +765,7 @@ void QWindowsNativeFileDialogBase::setDirectory(const QString &directory) QString QWindowsNativeFileDialogBase::directory() const { IShellItem *item = 0; - return (SUCCEEDED(m_fileDialog) && item) ? + return (m_fileDialog && item) ? QWindowsNativeFileDialogBase::itemPath(item) : QString(); } From 193caa4451e9f9125c3cc30d6536ad1d9a4e46a8 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 7 Feb 2012 17:16:55 +0100 Subject: [PATCH 056/406] Rebuild configure.exe. - Windows configure: make -mp affect the Qt build itself - Change syncqt default parameters for shadow building - Moving tiff image format support and libtiff out of qtbase - Add concurrent to QT_CONFIG also on Windows - QRegularExpression: configure support for PCRE - Remove support for the MNG file format and the bundled libmng Change-Id: I14232ed4bb6bd90bd1d77d657d426108b4a88f47 Reviewed-by: Rohan McGovern --- configure.exe | Bin 1115648 -> 1140736 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/configure.exe b/configure.exe index e27966e3cd649e8cb5e20833cf9163b7069a8d26..86dca34c9d8b6eb9b7db5415db5650e0cbb1134b 100644 GIT binary patch literal 1140736 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

`+5M}k( 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�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%0A#|i{-hCQ`lTf&h(OVoY_moyKPrhC#x^Q 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 DnRAev literal 1115648 zcmeFae_WJR_6Pn9Gr)kOj75c|NlB$)Mq#C42I-)cqeCc22HK|WL{_FVY9*)*6yxKR zyK9?mR@U0)w(i!pR%}{g5a3EmW`&8xmbJ%*YRq4l=6v7h+-HVC{p^1K`2P9z^^&>I zz4!dM=iYnnx#ynyJkHx!Xl6~*EchP|Yg#RS`CqR5{qKK5DDE@xoj%%zqz^BuHBI>N zqRH-i=B3Y>`@pZ~-g#g8U3cDp{{x=%U(HIN>%Bkyp8M0sPAW{l?}3@KhV|~9oME6g z=N!CY-0jcZANl|DIlb=B$8(9*djEa$d*S^*;CIIA(ESei{r3J`{EoYQ_5B}7dB6Lw zkzbp@-FDAiZpQV0aqem{{*u0sWA0L^$Z!lSztJDg)E1@NH5VsV*tG`WJMG^ZyEbC( zX}PCmxF@Cb>?81*aVC5QNX(R4HZWa)Z!0*LIgN=%)S2t|#yt#MbS=x#=3(eb4tCu@$?yT7l zpyJFwp)zEkt;28GY4vVG?*ISq|3eA5R{>dV!EeWD^wObtE$p=g99CB#a7Q>Crsrxj zE&GUi@Ow|t#Ic%IRp&jw++5~!o(LPYZXc&amStPsw`c{rsk&~l z<#kg@eK<)sm1|Q|o~kRUZ!+!r)p%`x2|Bt+KhTuGPjoAuj*QK)nmma`l#5O*(HqNv zqh6noVacw`Y4)U!MDhGS%lhV3?erw(=HO}WPxZP<*L+mIAHru=*P8rKgpB)w9gkX)g*mLd7oX{V{+-0Mol(e);8+ zm#3F)1zSK}0Ooz8HE%|_7I2=RH&KrtdxzuK&30)o@*jT!m((+cgtDznlYvzIYR=8K z_`1ULEV=%C3)g%Gd69a>`Y~1U4z4)PQe8JcNh*)`kF)3tEJwe%;K%q9}y6QS_zY%$Y1Z=yT?9VQ!?5yGHuF`4vl#K9|fdPsuDQ))!^i z^aIslPf{^Ga1gy4H2a#vu44N4pDkKRi9dna2TlwDi%CWWw}Z#RaIS6ek3wD3T{hrb z2z2^*OJH)Gz2LUMqC`7={7aY-t^h*xa1>)t+6RAP+Gw4>(h{x0($aG+Mde|aet_Ot z2afy+F*FTH<}`ZGbGOE6n)?uVbMNC}+tt?$YBoJVw^nbhw1hSACk;Vg^B5||AkvTN zPOFRl1pa(YRy~AaWQ-zxOOv+g9+y_n6#7uhiEtQ`*c!f;uKyF5D3cLWz}nE+McLes zjA$v!w$`(t3uq5AOG;uVUAd+9rWc?`Z~qbFan=d^53xQ4BxRv8W&@I3(Buf2pmnL} zpBA1K)C_?72z39`p?~6Oej0SzX$LseK?y(5t^1=m+Nv5ziT{n z5BVJ-ItTf#0=>aM%T|6z$=!Y{8bGh?P@VHV@PH?!f4tTuqqSna!sd6LXmq5QQmR&< ziG}VFKvqOI9l!)B$!YW?Lq#NHHtKCbbM~GwOGYPqZq=P90+yVdrCfjU4NEFgH1EYZ z750h&ZWmxNHrx~NOE&_AUSWs8myAyLWEK^=$8z>yWFyaf+cC8T8c(*rA5&8!V0!`8SI3!5*e=J89dfV^qq7;mt zOsT_y$_znNnT>vjy}GU>;IJT*x!ta4;cEGhAJsv6U{MsYDutZlRweW)5Vmb0gqP22juUE|5ExiPsR_OQ1< z)+KLR>~a)#^~ZQFeLqdcGc_F!sDhtMI81IviaR}PukQfc;L)ulUd*k$>_OelvE3FJ zJI5{!AnOMfC_FW-MN3rJpvdi>J}?u!NvyBpJ0VjSryhQZmswV7CVh*tM9vJd6H*iq zX1`V`cUGOeGQ4#uCPJLF&sSm9JiWNiiwvMvb39_XbJ4wMG+>y33xb>Xf)ZT78PY@4 zmmA$kw*w87b-7mC)(cqI6Qp*Gtt<_zI+l1e)mYm-33fVq7}^a(p~yvj1bM1LzJtz< zBFD-~8@dGfFTlpg4VEV{@&ny0{{T^+!g4LE;ck|1!m=cL3t_oTVSS}1)?@$aiFMWK zSbx=xwMcKK=I5hWm$i`!Ea{ZDV2}B>SPNX_YeZoQx>6aa zSaCh)7Y81)ro5E^(|i_6YZCIYTwy+YgJMEjwHR<~%YOs^Zrho_mw`A4vVNLk%bbFJ z#cdD><`6^)m0hYb!Wm8OvA^7t3aY&gU88u)(G%E5(c!gfdHG5O(iM z!mhzw3-qEm(}43ZM4@oADfgtm^aS<83ai&wT~qZC>Y1!e|_Sf-o)rp%XN z2G-P-XuzW}Sb+~9H1!Zuw?|dSLQy?%8Sv&H|28(hc!Ti90Z}4$jGV1Mb4yYqEhz+{ zfYUA$<3T}YrGJ7>efQ>J5!?8(Jmwr*)Zg6zv(Q}y!@xa<|IA<$At8bH0(P!vHSd@n z7+aId%d8AtJs-;au~e6yZCZp`Ttsh<{SjqXIO#yfK{~u z-NO=^!8k-YEZMvgGm}klk4QSJpBd9BScZk&MNg*j13I4VEA%HaJ?BBm+Fkk%dKm0M z9C7FhYK!r>%u=m@e<-2)+qeu32JMz9rd+C+NUNb^8=1UxWH{cEpy3M_s2 z6%4&2es8;8VTCnW%bOk^Z;AfWcE6*O`GFnF1W5-KG4le>4rG{VGrG;)3H=dp?n8!! z{)UXA!hmBRVA_xqPxjln|2hf`Bnecwhci^+h5)A(=t>}u;H_aoZ0@0uZf7DSM3`zK z=CmTxVGyy>UrGcI6XCWd(GQ9yoQxuw z=3)s)L5<^})IJQNODYa(p1gpAP^puyTV>JQ?W*zgCcqgF>h_{_3KxVR_&SkkBUh_M z<<1E_1UE6wVlFMbrMbV^I~9l&L$$AMI})J$J8 z8>5WMe^-^kDVi;n`_k<(mEYjX!;Q*Ssxk&wr1DvGMNH*tRE~_hha}y}+U$Nwssa5g zr1d8HO9#d?lz3o$#t9&;wZJD#-8EI7BFo{-!Ss#ng`9ig1Y%F>ZMQ#%)7OAykt;2uLog@uY?`@lwk z%jj1_yq%u&!`{w7)isKOQDrOZ?FQQrZ^(niFBBMi4ZwkdURMPykh2x1Rry%N_}MJa z9t^E^I_l)6dE&0#gC~p;jouj#eajAD)chOL%j$LKp_%^PXr^q!^Z<83_J@@FMZC83 z1MV{R0O)z?z7cRO=>=K(S#SmItln9fpu=o{)nW?Iu~}&VCMmUh3R<>UU&Vi}ZQe zX?X?|>y7$+OJHFawDz0dLvE8S^jG|17xvBcax1o{7Y)WfVOj)EA7d>F%(E8HVqPQb<=EjKivcy&LN9-}oH{KXxCyIb|#E5YOE^ux9!5t^OkHTG*CL zd2g(^RII!!v5_e({VWzBGn(3{T@n~?I#QqRu{4@8^N!TpIWZ`2+2jm+qiI-Pqv>+? z=$dQ#=Dnk3Y1*LAmmb&BHO*^zXLg5fblP6$$nlEXqh*HgL)D2_8#LzhJLM)6F1wE&dPJe_Hyj)<@IwmY(F}Adq<= zn1(c_g(rSlu_@TA?kn?=olCw-U-GZ1)5{_>BPKykW$OHRnh0ygSD9u2qES}4z*lSWv!HatquzBQQ zFO<2tfNIpnf{jtdPcikwAlF0rMRdvgZ1n2Q!Ng_fO@vU#RUcV!c)D1J`a}y{S$%lJ zOl9my!bZ{Dm|#*HW^68&@M2xK2bkcp>ZI3x!Lq$a@A8*f{bhE4St^^0cWjEsCY)S_ z;RRNzR9iia2O1m6cc;z5Fqs)CvD4+zl5{S)g-h6sX|Vb8Q^|%>J#m>>{wxCnT2 z1y9HBVm(J6H$p$^cburMTXeY&*M{eDOAr>eH88P@3gK9Vis{YyCw0$bmYi(wzOeJe zL!ahkd(MIl6v*##(G^llZ}i0JX7O<-m*eU9vl%%c2cpv${h^o7fSzf=3?H?0JeYdu zLq*6Ygc_uN3?XAw1rS8cu7@cyi z_n)oz$=SiDFZ<+FASrw;q%sm47yoGL-zFpdG#~VuJIq?Q4|;!75C)?hEj$>Dq#Q=N zC?Jg41JZBo$P6rkM-SdMP-(vlLc`X#O$yB)6$d7-Nag*^ZCvVN8{diU45U7J8(cM9 zh+nJuBQwOZJur4fs*5tY(l$EwwK~!$1l&Q`!uqw?0ht|E?2aBwEt^(~=^DcXw(-mb z>h5O_guE>l-u3ro=v(W@A!c0rQ1va&Lv}3lu6#-a?tcDwg~eFoAKlG#<9jF0M@PVpbba2{d&%L+t_v z3w0^{?X(?z1>EgMtwdTWxZ5MRcc9{_xLXDH;BMSjI-xV}R>8d*AmW-^cr1?3TfhyQ z+s!WO1xC^NsFj3_78h+oRbNAY;N$&RG7Ssk@YmU*h$qo)jLF$7Sn~}=yknFU%rqQ1 zhA?fuCW|4+>P^tb*!clvQ=)AByu3Bj=c$01#Q zx)^-$t!}5m?8?GIXz5kQ&t?1fVDGy`-0J!PPo}Kym%z<#(*pUHVtvGXJG+mI%k3_D z7NntCis?y=wvy>=|LEJB^3zhFhUj``1>;*LAaw3o)Y%ck=>x(kyM1sL1ON5NN_Hi^ zhqX-4Pt9z~aoFaW{ZI{XoXpSFC#Dq!iY&fk?A|{g?)}d>8K<9>>9Coha^1oyzOyVbCHj+5J#K13@W#zHt*_Oj2@w;m!f%)*FfK5v8l$vBnynQV0^oP(p5;` zeJLGQuHoc+2c3su$&1Yn|8$FgK^oP-^+Q{B8b$)J7gtK^ta{Xn|`ng=+??@eYYw))^++#MVlIdmsJd3}tzGd3h z`pDVG1?ZFPtvLy0DNm`;3$}Pzk}^|#3rA_50ca^5#GuPb@btxG^VOYj(S~F01xHnIi#S?c z#n8)B!3&IG*iPU0em(YNncmB{WjKZQ8e=~jRdTR6_;aSC0dPyc#$#rED_b3~ISnho zJ4BWq?2&R@mc{+C2H4ecEPJCcneJsd&A@yL-pR%r%#1=j2n;tHV#>>Du1rBkTMEik zY0kH7w!pKM5T3)QRVmCP`{@*7D~6N_Sd&CYCIOS$SBB^=#(HfS=H{QlA@)RY)a_)3 zkMB?nhj^~!V~D|Leu7URn-X%_PbLlp={c+JX`&;yx#1gHOluw1plYsHWy>i z@Y|vzV;0CBtMs*Z{I^y57bwpExk|TjrEOH$E}fHDNPS*q%BL^V;>5%`As+-~)m1@ya1V(Tu1=}6J!z?#8v_E3}^VGmx;O>(6 zfM<4!ml<=|82TKeV+=!2zjBis;EQQHAkn+}b{Bo}C5D~s8622GO?U#4HQX6EAF)b! z5bxZJ^ehN$~*u+KLZxu;~c#Su!&%WAs^Y6B(oD1B8;dv%8vib~psM4y9^Oho+QkkrinjJXgrB zXZ1(t;~cJj|8zc$Qz2B5(5cx#7j=C5!cg86+7PdetW2BNJ3Jr8SuvdjD>Qfo)=0bN zIo}ty&pQW8PEOanIK9aQ&AOf5#o1QS29w)bjHfKnMF>~Z1$EPpwna`XS(ql7GcMlP zMuMthvQv$0ad#BsU|2tvIW9G)enC7<2Se3+<_|5>7o?VJ=7T)UZbqZAdpi#@NY!^> zcbZD8;Jo9a*M7iK45?02x~<2GI{~PGI};6X*nrx?&%B7Z3-z*8EUo46w``{%bTY8t zrst<&Gv({D&rQ_(`lncfW^AnZF-}j?i&8T`yA6hOW)rW=pWSBOVRqVF1@z=@S$22} zza2xbn8NIs1lDuGn6WskV27CI+q$KK6^CP<#7vmZX2R3|fc6=enpv-x+H>mX#p`YU zQoGTL`uWM|jespJrx`V`K}|?%DzePzcvu8jMQMO)%}vHSxtLuSO%}9`TN1Aq@w!>W zN==`b3fku5nOllo=6@B?pWBRewLJ!5-BvJt3#dI~2p3?LisV&Ja(>fU~ZEYn=t}u`$5)E^5c535+{I z891_oR^TZdGfDeLCg~20%W|-d!;0IXcrm4e1LPS&3@#d{vVi>H)Y!=i$r{mVryTOM z@NTjDkY_6E^@}=1u>r{k*u}{j5_8rQIdR^*6++lu&g%g^^#$sM5HRV57cn?T+8Cm> zJS2Ff+D3~Qk(m#TwnsJ~o|;sDg*BMMa~7qGy#oQxYX4*_E#dIeRn1cks0WXAI9L-%}YXdm88J`8cew2ISJk{Bm1mELtITPaf+-VIAU>8(l1wA8 z`ruS0L{}ma_U_|kh9o;U*$+u|hLA))v|b$)T4{l#c{83!_e#1I=>(cC=@z8psZi2t z`#Vn34ahfBj->05j-x9jEhkACNaFBB9UNyL!2r2f7+VXrU36atPGDiBWJRmw=Nwq{ z1@=l{vnfFxlB%umwOA-H>M{`Vz;l_KF#|ZD2V7M03AZ8SFI820aaGv#J6l>>%16|0 zeFj6o`2i;2F?ZtORftfg2GD;*oBM4;f;r0r5f)2;3jiXpVxoxf|kHhL~VL+}8slnIT3i zi1WH3?qP_r21HH|h+Yg~QxMF~sM*>1w8bbVI~5#0Uf8vyWn1 z&Zl^^PC+c~hWHq0-9rtCmwQ0qC`Y6D3Sv?>#ET4(VL;650U>Uhu?k{9H^c)Bk!nEX z0m5zNhe+SEkD2-?sQl#f^LXEGDOIL@b-YOY7h6hDu_nHUnzU4%K>8KM&Q}=2@>Gs=FaR zW7Mq%#Ge7tlTI4bnXjNGbwj<#Pz?suJcEwXNc|XMtb!QO4e>iu6$o_e zz5YyOy~0=hX;jXiF)NXt`7^+}AqFtS!wNzzQKDO4W{61J7xaL*kRiq^h>N;uuz=oM zhqlYAFcu*0RZ4bf{6L1uLSA%@NT+z9FvLK|4vGkTUJ(JLGLQxVU!?s=0xQuEFc(#X zPh?76#E3U4=#`&HgZDoH?eAV;^uk7fFf5q3nCt!p&!_ajAbMCKxbUTz9=MoZWPX*Y z^Lr#!4~%5wk+rG}$WB?SGMLEa3ZGdq#Eab&mPcf*x=eVAG~p74==w$e&1UHzWiWJn90wwm}Qif7`ejgPA3RQ=oDhAg+o`)F<;+K!PP5Zb_lNdtj;10S7 z5UARrXk5-TemWph*d`Di3^71x2xsl|<2He4R}h&DQKulD5r}q%2r~P_1)`1K1%x|8 z+R~<=hBDML1$CD|VFQdiSPa!)pmx#Yiq0+taRoz6RS;JR#4d*LF@#+pT4{=cXjKry z7~)a|5#GtIZ)J!AhOi1m3k^~bEehgFhTs@4Hkt&Yg&_tqgeDNpbl_jo`ep@@#Srf+ zh-U?&nIXRC26w^w4LBQUvw~<)5LYq83I%bGKr}GKMuzAVh&l==2<*1G->+tfG6iv+ zK-4jWpCLK~ViQdRgu9s^9GetWHbV_oP$q%e#88ERqUUi)QD2^3Tlxo>mOs4%(-Nni zvvvV^pNmH0A^^4+sEj*4ym4};xw#=7VjKUo6%$u8V&K?bHB;f$JYTsuo(?e|sZzh4 z8c`QD`5cUo>Jn%<;-_J_E8QATO{gsAV3V*{umOll5Cg$`7wi+x|48;OIIyDvz!d0g zvnSFn9HsG586K=u)XBZd!9NDa^NsHC=YvXbZgAP zXL}U~*qW?rjpd+Caga>6b#u^*b_FHOGC6pIy9-MIt?C9ZITN^z&h7^9O;0Is?DpFz zRT{vJfx`uStL15*94Pz;W!T6;7XDJ+-^9@iGg*|fN7;jYgp#mE9spwRK%4%_Jv^#* zKliX54|=JU<2QFTnR!`Zgd>qhBxnT#mxrB|4*UV(SY2V2*mn>lRvzbX2-w#P~To zQe z6LGo|s7tVWO{qSDot@hznG>R!|K?1KWL_7|Y~jokkaRI!9L;>2GY?5-?`Y;roEehL zu0}=3lPvb${^eXm(p@%s=>s&7S!2IAf|}=JMo2Xm)d7y3JBSx?+Hl`u6`rg1q*V3B z$a=3G@I}S6+Q6Ms{XM!58G1CMokvBha4jTHG5X z^SWqe4QH;G%!`do?*jK4$>6nBke{D`))#JywPOC;lqNJh4Mkz{-r z$++0b^$4!MDB^D6(Zobec;>5w z;E4SN`~S)^njp-c1lf|3a`SXx#({OGI~Uo$#)ViDFpn;WJ?VnJ0VlFe9(cBd-=pqO zcNVkn=s+zC*TO2uo&nU9O~T=`A~g|Big0#2ut+%jkC@gp2UM9s6j*T!522@J(tK;x z9#5k17)+5N7PPttgARN!bU{7OGu(f`;Q`JVur>yH;(W?(`eTMLJLvHHm~4)Y>^)dw zc`@BeY&$~+PXk;nfpK&IY4-$79EgnS0bz6xYj!iefebc$Ba5Pi79d(Xx+tOoz(ubVE8*(a&4ZkPOBP)&EBGtp!k~*GchUOKB!H!RhmFqq-@>K*PGJ6T0aHYO-#+l&9lr1H7>g^;hu2xJ51w zVCu-1dpB3Xo@BRdTXY*1N0q>h=I$$W(Qy`a4ZvioN(;iU+7L*<3of25v=moAFuagX zprxpe)*zioUP-elW~F;1%@RnWQlusLyp5wUvZxUg2=nX#k*~9rE^jvTKPCDfgIQGb^
J`Z^nEtI1nj$PvbY8(r*+ZIJn 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%0AF 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 From 389c5f4a52fae01ef1aea8dd98174a666d90e2dd Mon Sep 17 00:00:00 2001 From: Rick Stockton Date: Mon, 6 Feb 2012 08:38:38 -0800 Subject: [PATCH 057/406] Add 'AllButtons' into Qt::MouseButton enum, for use by QML This allows the QML programmer to set 'acceptedButtons', for a MouseArea, to accept all buttons with a single value. In comparison with OR'ing a long list of Qt::MouseButton values, this is shorter, easier, more clear, and less error-prone. Task-number: QTBUG-24106 Change-Id: I0259969223c0b44b6ce8ae84aed37d20cb77999b Reviewed-by: Alan Alpert Reviewed-by: Martin Jones --- src/corelib/global/qnamespace.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index efb49856454..2087d763ded 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -184,6 +184,7 @@ public: ExtraButton22 = 0x01000000, ExtraButton23 = 0x02000000, ExtraButton24 = 0x04000000, + AllButtons = 0x07ffffff, MaxMouseButton = ExtraButton24, // 4 high-order bits remain available for future use (0x08000000 through 0x40000000). MouseButtonMask = 0xffffffff From b113644acbeda7171b4442fba2aac3e51f9c5b0f Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 8 Feb 2012 07:36:42 +0100 Subject: [PATCH 058/406] Add configure, sync.profile, and header.* to OTHER_FILES in qtbase.pro This makes these files easily locatable when using Qt Creator. Change-Id: Ie0c15ebf2cc7045954713265bf524f2ecf1eea34 Reviewed-by: Alan Alpert --- qtbase.pro | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/qtbase.pro b/qtbase.pro index 56f40cdb7a9..5fc9cb38884 100644 --- a/qtbase.pro +++ b/qtbase.pro @@ -132,3 +132,11 @@ win32:!equals(QT_BUILD_TREE, $$QT_SOURCE_TREE) { mkspecs.files += $$QT_BUILD_TREE/mkspecs/default } INSTALLS += mkspecs + +OTHER_FILES += \ + configure \ + header.BSD \ + header.FDL \ + header.LGPL \ + header.LGPL-ONLY \ + sync.profile From 6b807a283cace845c235c24543a071e41cee0dac Mon Sep 17 00:00:00 2001 From: Giotis Nikos Date: Tue, 7 Feb 2012 01:32:44 +0200 Subject: [PATCH 059/406] Fix qmake evaluation of QMAKE_TARGET.arch on msvc2010 x86_64 This change is needed because msvc2010 tools have a '\' character at the end of environment variable VCINSTALLDIR. This variable on msvc2008 does not have this '\' character at its end. Without this change QMAKE_TARGET.arch on msvc2010 x64 evaluates to x86 instead of x86_64. Task-number: QTBUG-22686 Change-Id: Ifba833e9361c97568b8b3de9976023e8537b208a Reviewed-by: Oswald Buddenhagen Reviewed-by: Joerg Bornemann --- qmake/project.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/qmake/project.cpp b/qmake/project.cpp index d898483a476..fbeb033b866 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -3165,8 +3165,14 @@ QStringList &QMakeProject::values(const QString &_var, QHash Date: Tue, 7 Feb 2012 11:53:31 +0100 Subject: [PATCH 060/406] Make copy and cut methods work in QAccessibleTextEdit Correct the implementation of cutText and copyText in QAccessibleTextEdit so they use cut() and copy() methods of QTextEdit Cherry picked from Qt 4 - 36202cf8fca822492615d418bd563a40bee4af08 Change-Id: I86a531ed7059b1a928cb8515c2743d4d8b596b36 Reviewed-by: Frederik Gladhorn --- .../accessible/widgets/qaccessiblewidgets.cpp | 15 +++++++++++---- .../other/qaccessibility/tst_qaccessibility.cpp | 6 ++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp index 2d6330cb38b..140848a559e 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp @@ -87,7 +87,7 @@ QList childWidgets(const QWidget *widget, bool includeTopLevel) if (!w) continue; QString objectName = w->objectName(); - if ((includeTopLevel || !w->isWindow()) + if ((includeTopLevel || !w->isWindow()) && !qobject_cast(w) && !qobject_cast(w) && objectName != QLatin1String("qt_rubberband") @@ -483,12 +483,17 @@ static QTextCursor cursorForRange(QTextEdit *textEdit, int startOffset, int endO void QAccessibleTextEdit::copyText(int startOffset, int endOffset) const { +#ifndef QT_NO_CLIPBOARD + QTextCursor previousCursor = textEdit()->textCursor(); QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset); if (!cursor.hasSelection()) return; -// QApplication::clipboard()->setMimeData(new QTextEditMimeData(cursor.selection())); + textEdit()->setTextCursor(cursor); + textEdit()->copy(); + textEdit()->setTextCursor(previousCursor); +#endif } void QAccessibleTextEdit::deleteText(int startOffset, int endOffset) @@ -508,13 +513,15 @@ void QAccessibleTextEdit::insertText(int offset, const QString &text) void QAccessibleTextEdit::cutText(int startOffset, int endOffset) { +#ifndef QT_NO_CLIPBOARD QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset); if (!cursor.hasSelection()) return; -// QApplication::clipboard()->setMimeData(new QTextEditMimeData(cursor.selection())); - cursor.removeSelectedText(); + textEdit()->setTextCursor(cursor); + textEdit()->cut(); +#endif } void QAccessibleTextEdit::pasteText(int offset) diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index eb76202e35a..63770f14cb0 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -1516,6 +1516,12 @@ void tst_QAccessibility::textEditTest() QCOMPARE(iface->textInterface()->characterRect(0, QAccessible2::RelativeToParent).size(), QSize(fm.width("h"), fm.height())); QCOMPARE(iface->textInterface()->characterRect(5, QAccessible2::RelativeToParent).size(), QSize(fm.width(" "), fm.height())); QCOMPARE(iface->textInterface()->characterRect(6, QAccessible2::RelativeToParent).size(), QSize(fm.width("w"), fm.height())); + + iface->editableTextInterface()->copyText(6, 11); + QCOMPARE(QApplication::clipboard()->text(), QLatin1String("world")); + iface->editableTextInterface()->cutText(12, 16); + QCOMPARE(QApplication::clipboard()->text(), QLatin1String("how ")); + QCOMPARE(iface->textInterface()->text(12, 15), QLatin1String("are")); } QTestAccessibility::clearEvents(); } From 8e91e84e857166facf599870ad773e36e518c48a Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Mon, 6 Feb 2012 21:24:02 +0100 Subject: [PATCH 061/406] Don't include qguifunctions_wince.h in QtCore. qguifunctions_wince.h does not live anymore in QtCore, but instead in QtGui, so do not include them in QtCore. Change-Id: I22222ae7045ee0140924197ac583a3bf2e0f3d36 Reviewed-by: Miikka Heikkinen Reviewed-by: Joerg Bornemann --- src/corelib/io/qstandardpaths_win.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp index 16bc7661706..848dd448eb9 100644 --- a/src/corelib/io/qstandardpaths_win.cpp +++ b/src/corelib/io/qstandardpaths_win.cpp @@ -51,7 +51,6 @@ #if !defined(Q_OS_WINCE) # include #else -# include # if !defined(STANDARDSHELL_UI_MODEL) # include # endif From 0da03ac969e382a604f8c178820f1e8b9053d97f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Tue, 24 Jan 2012 16:06:27 +0100 Subject: [PATCH 062/406] Code cleanup and micro optimizations in QMetaType. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I0fbd713fcdf094f9d13acee855b6dd6986695e0d Reviewed-by: Stephen Kelly Reviewed-by: João Abecasis --- src/corelib/kernel/qmetatype.cpp | 112 +++++++++++++++---------------- src/corelib/kernel/qmetatype_p.h | 14 +++- 2 files changed, 66 insertions(+), 60 deletions(-) diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index a6b15994445..6a7c5c2a346 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -305,6 +305,12 @@ Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeWidgetsHelper = 0; class QCustomTypeInfo : public QMetaTypeInterface { public: + QCustomTypeInfo() + : alias(-1) + { + QMetaTypeInterface empty = QT_METATYPE_INTERFACE_INIT(void); + *static_cast(this) = empty; + } QByteArray typeName; int alias; }; @@ -1276,12 +1282,12 @@ class TypeDestroyer { static void Destroy(const int type, void *where) { if (QTypeModuleInfo::IsGui) { - if (qMetaTypeGuiHelper) + if (Q_LIKELY(qMetaTypeGuiHelper)) qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].deleter(where); return; } if (QTypeModuleInfo::IsWidget) { - if (qMetaTypeWidgetsHelper) + if (Q_LIKELY(qMetaTypeWidgetsHelper)) qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].deleter(where); return; } @@ -1310,8 +1316,7 @@ private: return; deleter = ct->at(type - QMetaType::User).deleter; } - if (Q_LIKELY(deleter)) - deleter(where); + deleter(where); } const int m_type; @@ -1340,19 +1345,15 @@ class TypeConstructor { struct ConstructorImpl { static void *Construct(const int type, void *where, const T *copy) { - QMetaType::Constructor ctor = 0; - if (QTypeModuleInfo::IsGui) { - if (!qMetaTypeGuiHelper) - return 0; - ctor = qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].constructor; - } else if (QTypeModuleInfo::IsWidget) { - if (!qMetaTypeWidgetsHelper) - return 0; - ctor = qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].constructor; - } else - return customTypeConstructor(type, where, copy); + if (QTypeModuleInfo::IsGui) + return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].constructor(where, copy) : 0; - return ctor(where, copy); + if (QTypeModuleInfo::IsWidget) + return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].constructor(where, copy) : 0; + + // This point can be reached only for known types that definition is not available, for example + // in bootstrap mode. We have no other choice then ignore it. + return 0; } }; public: @@ -1369,15 +1370,15 @@ public: private: static void *customTypeConstructor(const int type, void *where, const void *copy) { - QMetaType::Constructor ctor = 0; + QMetaType::Constructor ctor; const QVector * const ct = customTypes(); { QReadLocker locker(customTypesLock()); - if (type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User) + if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User)) return 0; ctor = ct->at(type - QMetaType::User).constructor; } - return ctor ? ctor(where, copy) : 0; + return ctor(where, copy); } const int m_type; @@ -1430,20 +1431,18 @@ class TypeDestructor { struct DestructorImpl { static void Destruct(const int type, void *where) { - QMetaType::Destructor dtor = 0; if (QTypeModuleInfo::IsGui) { - if (!qMetaTypeGuiHelper) - return; - dtor = qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].destructor; - } else if (QTypeModuleInfo::IsWidget) { - if (!qMetaTypeWidgetsHelper) - return; - dtor = qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].destructor; - } else { - customTypeDestructor(type, where); + if (Q_LIKELY(qMetaTypeGuiHelper)) + qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].destructor(where); return; } - dtor(where); + if (QTypeModuleInfo::IsWidget) { + if (Q_LIKELY(qMetaTypeWidgetsHelper)) + qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].destructor(where); + return; + } + // This point can be reached only for known types that definition is not available, for example + // in bootstrap mode. We have no other choice then ignore it. } }; public: @@ -1459,16 +1458,14 @@ public: private: static void customTypeDestructor(const int type, void *where) { - QMetaType::Destructor dtor = 0; + QMetaType::Destructor dtor; const QVector * const ct = customTypes(); { QReadLocker locker(customTypesLock()); - if (type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User) + if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User)) return; dtor = ct->at(type - QMetaType::User).destructor; } - if (!dtor) - return; dtor(where); } @@ -1505,16 +1502,15 @@ class SizeOf { struct SizeOfImpl { static int Size(const int type) { - if (QTypeModuleInfo::IsGui) { - if (!qMetaTypeGuiHelper) - return 0; - return qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].size; - } else if (QTypeModuleInfo::IsWidget) { - if (!qMetaTypeWidgetsHelper) - return 0; - return qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].size; - } - return customTypeSizeOf(type); + if (QTypeModuleInfo::IsGui) + return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].size : 0; + + if (QTypeModuleInfo::IsWidget) + return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].size : 0; + + // This point can be reached only for known types that definition is not available, for example + // in bootstrap mode. We have no other choice then ignore it. + return 0; } }; @@ -1531,7 +1527,7 @@ private: { const QVector * const ct = customTypes(); QReadLocker locker(customTypesLock()); - if (type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User) + if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User)) return 0; return ct->at(type - QMetaType::User).size; } @@ -1577,7 +1573,15 @@ class Flags { static quint32 Flags(const int type) { - return Flags::undefinedTypeFlags(type); + if (QTypeModuleInfo::IsGui) + return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].flags : 0; + + if (QTypeModuleInfo::IsWidget) + return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].flags : 0; + + // This point can be reached only for known types that definition is not available, for example + // in bootstrap mode. We have no other choice then ignore it. + return 0; } }; public: @@ -1586,31 +1590,21 @@ public: {} template quint32 delegate(const T*) { return FlagsImpl::Flags(m_type); } + quint32 delegate(const void*) { return 0; } quint32 delegate(const QMetaTypeSwitcher::UnknownType*) { return customTypeFlags(m_type); } private: const int m_type; static quint32 customTypeFlags(const int type) { const QVector * const ct = customTypes(); - if (!ct) + if (Q_UNLIKELY(!ct)) return 0; QReadLocker locker(customTypesLock()); - if (ct->count() <= type - QMetaType::User) + if (Q_UNLIKELY(ct->count() <= type - QMetaType::User)) return 0; return ct->at(type - QMetaType::User).flags; } - static quint32 undefinedTypeFlags(const int type); }; - -quint32 Flags::undefinedTypeFlags(const int type) -{ - if (type >= QMetaType::FirstGuiType && type <= QMetaType::LastGuiType) - return qMetaTypeGuiHelper ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].flags : 0; - else if (type >= QMetaType::FirstWidgetsType && type <= QMetaType::LastWidgetsType) - return qMetaTypeWidgetsHelper ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].flags : 0; - return customTypeFlags(type); -} - } // namespace /*! diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index c292f117648..b1edc350a10 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -161,6 +161,18 @@ public: quint32 flags; // same as QMetaType::TypeFlags }; +template<> +struct QMetaTypeInterface::Impl { + static void *creator(const void *) { return 0; } + static void deleter(void *) {} +#ifndef QT_NO_DATASTREAM + static void saver(QDataStream &, const void *) {} + static void loader(QDataStream &, void *) {} +#endif // QT_NO_DATASTREAM + static void destructor(void *){} + static void *constructor(void *, const void *) { return 0; } +}; + #ifndef QT_NO_DATASTREAM # define QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL(Type) \ /*saveOp*/(reinterpret_cast(QMetaTypeInterface::Impl::saver)), \ @@ -176,7 +188,7 @@ public: QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL(Type) \ /*constructor*/(reinterpret_cast(QMetaTypeInterface::Impl::constructor)), \ /*destructor*/(reinterpret_cast(QMetaTypeInterface::Impl::destructor)), \ - /*size*/(sizeof(Type)), \ + /*size*/(QTypeInfo::sizeOf), \ /*flags*/(!QTypeInfo::isStatic * QMetaType::MovableType) \ | (QTypeInfo::isComplex * QMetaType::NeedsConstruction) \ | (QTypeInfo::isComplex * QMetaType::NeedsDestruction) \ From 09900d3dc5158bca6ec4d40c1a770d32db413894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Mon, 6 Feb 2012 15:08:26 +0100 Subject: [PATCH 063/406] Fix position of a comment. The comment was wrongly placed. It describes v_cast function. Change-Id: I2390e4bf1fc19136bbbecbae4be83d5320ca244f Reviewed-by: Stephen Kelly --- src/corelib/kernel/qvariant_p.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h index 30159f1831e..cdae8997a7a 100644 --- a/src/corelib/kernel/qvariant_p.h +++ b/src/corelib/kernel/qvariant_p.h @@ -53,9 +53,6 @@ // We mean it. // -// takes a type, returns the internal void* pointer cast -// to a pointer of the input type - #include #include #include @@ -79,6 +76,8 @@ Q_STATIC_ASSERT(QVariantIntegrator::CanUseInternalSpace); #ifdef Q_CC_SUN // Sun CC picks the wrong overload, so introduce awful hack +// takes a type, returns the internal void* pointer cast +// to a pointer of the input type template inline T *v_cast(const QVariant::Private *nd, T * = 0) { From 979cb5a09e3c2c438eb7f122325d66ed6bf80aba Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Wed, 8 Feb 2012 15:13:22 +1000 Subject: [PATCH 064/406] Initialize dynamic meta object extradata. QMetaObject::invokeMethod attempts to deference the extradata for meta objects versions 6 and greater which is causing a crash in some of the qtquick1 tests. Change-Id: If5b2ca83b15de2cd558976c6b681dd5457c404d1 Reviewed-by: Chris Adams Reviewed-by: Kent Hansen --- src/corelib/kernel/qmetaobjectbuilder.cpp | 1 + .../tst_qmetaobjectbuilder.cpp | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp index 529ca22107a..064b8edafd6 100644 --- a/src/corelib/kernel/qmetaobjectbuilder.cpp +++ b/src/corelib/kernel/qmetaobjectbuilder.cpp @@ -1432,6 +1432,7 @@ void QMetaObjectBuilder::fromRelocatableData(QMetaObject *output, output->d.superdata = superclass; output->d.stringdata = buf + stringdataOffset; output->d.data = reinterpret_cast(buf + dataOffset); + output->d.extradata = 0; } /*! diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index def1b74ea48..966ac021ac2 100644 --- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -64,6 +64,7 @@ private slots: void staticMetacall(); void copyMetaObject(); void serialize(); + void relocatableData(); void removeNotifySignal(); void usage_signal(); @@ -1028,6 +1029,39 @@ void tst_QMetaObjectBuilder::serialize() } } +void tst_QMetaObjectBuilder::relocatableData() +{ + QMetaObjectBuilder builder; + builder.setClassName("TestObject"); + + QMetaMethodBuilder intPropChanged = builder.addSignal("intPropChanged(int)"); + intPropChanged.setParameterNames(QList() << "newIntPropValue"); + + QMetaPropertyBuilder prop = builder.addProperty("intProp", "int"); + prop.setNotifySignal(intPropChanged); + + QMetaMethodBuilder voidSlotInt = builder.addSlot("voidSlotInt(int)"); + voidSlotInt.setParameterNames(QList() << "slotIntArg"); + + QMetaMethodBuilder listInvokableQRealQString = builder.addMethod("listInvokableQRealQString(qreal,QString)"); + listInvokableQRealQString.setReturnType("QVariantList"); + listInvokableQRealQString.setParameterNames(QList() << "qrealArg" << "qstringArg"); + + bool ok = false; + QByteArray data = builder.toRelocatableData(&ok); + QVERIFY(ok); + + QMetaObjectBuilder builder2; + QMetaObject meta2; + builder2.fromRelocatableData(&meta2, &QObject::staticMetaObject, data); + + QMetaObject *meta = builder.toMetaObject(); + + QVERIFY(sameMetaObject(meta, &meta2)); + free(meta); +} + + // Check that removing a method updates notify signals appropriately void tst_QMetaObjectBuilder::removeNotifySignal() { From 5240055e087c9830ec6894089dfd57b09ba982bf Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Mon, 6 Feb 2012 14:07:45 +0100 Subject: [PATCH 065/406] Fixed source composition with opacity in the raster paint engine. Task-number: QTBUG-24075 Change-Id: I2b9263364bf30fb8c914823e80e7ea4a8af26035 Reviewed-by: Gunnar Sletta --- src/gui/painting/qdrawhelper.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 6a34b5c7ca0..8f2b3bab1c7 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -3695,6 +3695,8 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in // don't clear dest_fetch as it sets up the pointer correctly to save one copy break; default: { + if (data->type == QSpanData::Texture && data->texture.const_alpha != 256) + break; const QSpan *lastSpan = spans + spanCount; bool alphaSpans = false; while (spans < lastSpan) { From a2bea730c2047b2fc22bcc129b3dcfeef89a379d Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Tue, 7 Feb 2012 09:55:01 +0100 Subject: [PATCH 066/406] Fix qlocalsocket autotest Lackey is currently not built due to a qscript dependency. Mark the test as an expected failure, so we can resume testing QLocalSocket again. See QTBUG-24142 Change-Id: I2642ed30cf7a2068f30f63801c632fea7dae7691 Reviewed-by: Andrew Stanley-Jones --- .../socket/qlocalsocket/tst_qlocalsocket.cpp | 30 +++++++------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp index 221ef602a18..5d3cb6eaae5 100644 --- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp @@ -53,10 +53,6 @@ class tst_QLocalSocket : public QObject { Q_OBJECT -public: - tst_QLocalSocket(); - virtual ~tst_QLocalSocket(); - public Q_SLOTS: void init(); void cleanup(); @@ -110,20 +106,6 @@ private slots: void asyncDisconnectNotify(); }; -tst_QLocalSocket::tst_QLocalSocket() -{ - if (!QFile::exists("lackey/lackey" -#ifdef Q_OS_WIN - ".exe" -#endif - )) - qWarning() << "lackey executable doesn't exists!"; -} - -tst_QLocalSocket::~tst_QLocalSocket() -{ -} - void tst_QLocalSocket::init() { qRegisterMetaType("QLocalSocket::LocalSocketState"); @@ -749,6 +731,16 @@ void tst_QLocalSocket::processConnection_data() */ void tst_QLocalSocket::processConnection() { +#ifdef Q_OS_WIN +# define EXE_SUFFIX ".exe" +#else +# define EXE_SUFFIX +#endif + +// ### lackey is currently not build + QEXPECT_FAIL("", "lackey is currently not built due to qscript dependency, QTBUG-24142", Abort); + QVERIFY(QFile::exists("lackey/lackey" EXE_SUFFIX)); + QFETCH(int, processes); QStringList serverArguments = QStringList() << SRCDIR "lackey/scripts/server.js" << QString::number(processes); QProcess producer; @@ -758,7 +750,7 @@ void tst_QLocalSocket::processConnection() #endif QList consumers; producer.start("lackey/lackey", serverArguments); - QVERIFY(producer.waitForStarted(-1)); + QVERIFY2(producer.waitForStarted(-1), qPrintable(producer.errorString())); QTest::qWait(2000); for (int i = 0; i < processes; ++i) { QStringList arguments = QStringList() << SRCDIR "lackey/scripts/client.js"; From e999156cb42e674f121aa19f904ba969dd74cb00 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Tue, 7 Feb 2012 17:34:22 +0100 Subject: [PATCH 067/406] Disable Assertion messagebox for unittests. A messagebox will be shown for an assertion in debug mode. This introduces a need for user interaction to proceed the execution of the unit test. Setting the Report mode to debug, will only print the assertion to stderr. Change-Id: If8ae80ea96d6608cba77b9c6ca176f97d1680932 Reviewed-by: Friedemann Kleint Reviewed-by: Jason McDonald Reviewed-by: Joerg Bornemann --- src/testlib/qtestcase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 84b03b73235..0440e26aca5 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1931,6 +1931,7 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) #endif #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX); #endif From bf69cc93323ccd9abe20fd1320d35bdfcced8761 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Wed, 8 Feb 2012 12:06:49 +0100 Subject: [PATCH 068/406] Fix QProcess compile for Windows CE. There are no Pipes under Windows CE, so take out the pipereader. Change-Id: I3e6afd403ed36e86a8694674f6c4798f1226ff74 Reviewed-by: Joerg Bornemann --- src/corelib/io/io.pri | 8 ++++---- src/corelib/io/qprocess_wince.cpp | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index e8a41b2d765..1a73783604e 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -76,8 +76,6 @@ win32 { SOURCES += io/qfilesystemwatcher_win.cpp HEADERS += io/qfilesystemwatcher_win_p.h - HEADERS += io/qwindowspipereader_p.h - SOURCES += io/qwindowspipereader.cpp HEADERS += io/qwindowspipewriter_p.h SOURCES += io/qwindowspipewriter.cpp SOURCES += io/qfilesystemengine_win.cpp @@ -88,10 +86,12 @@ win32 { SOURCES += io/qprocess_wince.cpp } else { HEADERS += \ - io/qwinoverlappedionotifier_p.h + io/qwinoverlappedionotifier_p.h \ + io/qwindowspipereader_p.h SOURCES += \ io/qprocess_win.cpp \ - io/qwinoverlappedionotifier.cpp + io/qwinoverlappedionotifier.cpp \ + io/qwindowspipereader.cpp } } else:unix|integrity { SOURCES += \ diff --git a/src/corelib/io/qprocess_wince.cpp b/src/corelib/io/qprocess_wince.cpp index 8ae1d11c80a..88d5a716575 100644 --- a/src/corelib/io/qprocess_wince.cpp +++ b/src/corelib/io/qprocess_wince.cpp @@ -41,6 +41,7 @@ #include "qprocess.h" #include "qprocess_p.h" +#include "qwindowspipewriter_p.h" #include #include @@ -48,6 +49,7 @@ #include #include #include +#include #ifndef QT_NO_PROCESS From eebc124f4c7fd28b3e8da327dcfcda354712cce3 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Sun, 5 Feb 2012 13:10:55 +0100 Subject: [PATCH 069/406] Add qprocessordetection.h This detects the target processor based on preprocessor #defines, setting Q_PROCESSOR_${FAMILY} accordingly. Optional Q_PROCESSOR_${FAMILY}_${REVISION/VARIANT} #defines are also provided, usually dependent on how the compiler is invoked. Currently detected families (and variants) include: ARM (v5, v6, and v7) X86 (i386 and x86_64, as X86_32 and X86_64 respectively) IA-64 MIPS (I, II, III, IV, 32, 64) Other families that currently are not detected, but Qt has (or had) support for include: Alpha AVR32 Blackfin PA-RISC PowerPC (optional 64-bit variant) S390 (and S390X 64-bit variant) SH (and SH-4A) SPARC (SPARC V9) Detection for these is currently commented out, and can be easily enabled later. Change-Id: I571f245c189b9d80c7c3a5369ac595a271f37c8b Reviewed-by: Thiago Macieira --- src/corelib/global/global.pri | 1 + src/corelib/global/qglobal.h | 1 + src/corelib/global/qprocessordetection.h | 194 +++++++++++++++++++++++ sync.profile | 2 +- 4 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 src/corelib/global/qprocessordetection.h diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index e00917c805f..726a566796b 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -4,6 +4,7 @@ HEADERS += \ global/qglobal.h \ global/qsystemdetection.h \ global/qcompilerdetection.h \ + global/qprocessordetection.h \ global/qnamespace.h \ global/qendian.h \ global/qnumeric_p.h \ diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 7ac212be6b1..f0d902f1f5e 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -64,6 +64,7 @@ #include #include +#include #ifdef __cplusplus diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h new file mode 100644 index 00000000000..2d52847a486 --- /dev/null +++ b/src/corelib/global/qprocessordetection.h @@ -0,0 +1,194 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 QPROCESSORDETECTION_H +#define QPROCESSORDETECTION_H + +/* + This file uses preprocessor #defines to set various Q_PROCESSOR_* #defines + based on the following patterns: + + Q_PROCESSOR_{FAMILY} + Q_PROCESSOR_{FAMILY}_{VARIANT} + Q_PROCESSOR_{FAMILY}_{REVISION} + + The first is always defined. Defines for the various revisions/variants are + optional and usually dependent on how the compiler was invoked. Variants + that are a superset of another should have a define for the superset. +*/ + +/* + Alpha family, no revisions or variants +*/ +// #elif defined(__alpha__) || defined(_M_ALPHA) +// # define Q_PROCESSOR_ALPHA + +/* + ARM family, known revisions: V5, V6, and V7 +*/ +#if defined(__arm__) || defined(__TARGET_ARCH_ARM) +# define Q_PROCESSOR_ARM +# if defined(__ARM_ARCH_7__) \ + || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) \ + || defined(__ARM_ARCH_7M__) \ + || (__TARGET_ARCH_ARM-0 >= 7) +# define Q_PROCESSOR_ARM_V7 +# define Q_PROCESSOR_ARM_V6 +# define Q_PROCESSOR_ARM_V5 +# elif defined(__ARM_ARCH_6__) \ + || defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6T2__) \ + || defined(__ARM_ARCH_6Z__) \ + || defined(__ARM_ARCH_6K__) \ + || defined(__ARM_ARCH_6ZK__) \ + || defined(__ARM_ARCH_6M__) \ + || (__TARGET_ARCH_ARM-0 >= 6) +# define Q_PROCESSOR_ARM_V6 +# define Q_PROCESSOR_ARM_V5 +# elif defined(__ARM_ARCH_5TEJ__) \ + || (__TARGET_ARCH_ARM-0 >= 5) +# define Q_PROCESSOR_ARM_V5 +# else +# error "Unknown ARM processor detected." +# endif + +/* + AVR32 family, no revisions or variants +*/ +// #elif defined(__avr32__) +// # define Q_PROCESSOR_AVR32 + +/* + Blackfin family, no revisions or variants +*/ +// #elif defined(__bfin__) +// # define Q_PROCESSOR_BLACKFIN + +/* + X86 family, known variants: 32- and 64-bit +*/ +#elif defined(__i386) || defined(__i386__) || defined(_M_IX86) +# define Q_PROCESSOR_X86 +# define Q_PROCESSOR_X86_32 +#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) +# define Q_PROCESSOR_X86 +# define Q_PROCESSOR_X86_64 + +/* + Itanium (IA-64) family, no revisions or variants +*/ +#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) +# define Q_PROCESSOR_IA64 + +/* + MIPS family, known revisions: I, II, III, IV, 32, 64 +*/ +#elif defined(__mips) || defined(__mips__) || defined(_M_MRX000) +# define Q_PROCESSOR_MIPS +# if defined(_MIPS_ARCH_MIPS1) || (defined(__mips) && __mips - 0 >= 1) +# define Q_PROCESSOR_MIPS_I +# endif +# if defined(_MIPS_ARCH_MIPS2) || (defined(__mips) && __mips - 0 >= 2) +# define Q_PROCESSOR_MIPS_II +# endif +# if defined(_MIPS_ARCH_MIPS32) || defined(__mips32) +# define Q_PROCESSOR_MIPS_32 +# endif +# if defined(_MIPS_ARCH_MIPS3) || (defined(__mips) && __mips - 0 >= 3) +# define Q_PROCESSOR_MIPS_III +# endif +# if defined(_MIPS_ARCH_MIPS4) || (defined(__mips) && __mips - 0 >= 4) +# define Q_PROCESSOR_MIPS_IV +# endif +# if defined(_MIPS_ARCH_MIPS64) || defined(__mips64) +# define Q_PROCESSOR_MIPS_64 +# endif + +/* + PA-RISC family, no revisions or variants +*/ +// #elif defined(__parisc__) +// # define Q_PROCESSOR_PARISC + +/* + POWER family, optional variant: 64-bit + + There are many more known variants/revisions that we do not handle/detect. + See http://en.wikipedia.org/wiki/Power_Architecture + and http://en.wikipedia.org/wiki/File:PowerISA-evolution.svg +*/ +// #elif defined(__powerpc__) || defined(__ppc__) || defined(_M_MPPC) || defined(_M_PPC) +// # define Q_PROCESSOR_POWERPC +// # if defined(__64BIT__) || defined(__powerpc64__) || defined(__ppc64__) +// # define Q_PROCESSOR_POWERPC_64 +// # endif + +/* + S390 family, known variant: S390X (64-bit) +*/ +// #elif defined(__s390__) +// # define Q_PROCESSOR_S390 +// # if defined(__s390x__) +// # define Q_PROCESSOR_S390_X +// # endif + +/* + SuperH family, optional revision: SH-4A +*/ +// #elif defined(__sh__) +// # define Q_PROCESSOR_SH +// # if defined(__sh4a__) +// # define Q_PROCESSOR_SH_4A +// # endif + +/* + SPARC family, optional revision: V9 +*/ +// #elif defined(__sparc__) +// # define Q_PROCESSOR_SPARC +// # if defined(__sparc_v9__) +// # define Q_PROCESSOR_SPARC_V9 +// # endif + +#endif + +#endif // QPROCESSORDETECTION_H diff --git a/sync.profile b/sync.profile index 4f01b7cf730..cc681b0ebec 100644 --- a/sync.profile +++ b/sync.profile @@ -77,7 +77,7 @@ ); @ignore_for_master_contents = ( "qt.h", "qpaintdevicedefs.h" ); -@ignore_for_include_check = ( "qsystemdetection.h", "qcompilerdetection.h" ); +@ignore_for_include_check = ( "qsystemdetection.h", "qcompilerdetection.h", "qprocessordetection.h" ); @ignore_for_qt_begin_header_check = ( "qiconset.h", "qconfig.h", "qconfig-dist.h", "qconfig-large.h", "qconfig-medium.h", "qconfig-minimal.h", "qconfig-small.h", "qfeatures.h", "qt_windows.h" ); @ignore_for_qt_begin_namespace_check = ( "qconfig.h", "qconfig-dist.h", "qconfig-large.h", "qconfig-medium.h", "qconfig-minimal.h", "qconfig-small.h", "qfeatures.h", "qatomic_arch.h", "qatomic_windowsce.h", "qt_windows.h", "qatomic_macosx.h" ); @ignore_for_qt_module_check = ( "$modules{QtCore}/arch", "$modules{QtCore}/global", "$modules{QtTest}", "$modules{QtDBus}" ); From 43a6739beb19d33aa1b0b2920bc2fe2c0356194a Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Sun, 5 Feb 2012 13:14:23 +0100 Subject: [PATCH 070/406] Use Q_PROCESSOR_* when chosing an atomic implementation Use the new Q_PROCESSOR_* macros to decide which headers to include in the atomic implementation. This also removes qatomic_arm.h, which isn't needed anymore, just select the correct qatomic_armv*.h from qbasicatomic.h Change-Id: I954848feafb8c420949d066ffcee1dd2b271e13b Reviewed-by: Thiago Macieira --- src/corelib/arch/arch.pri | 1 - src/corelib/arch/qatomic_arm.h | 75 ------------------------------- src/corelib/arch/qatomic_mips.h | 2 +- src/corelib/thread/qbasicatomic.h | 18 +++++--- 4 files changed, 12 insertions(+), 84 deletions(-) delete mode 100644 src/corelib/arch/qatomic_arm.h diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index 62b07a4a996..08ab17e0f4b 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -19,7 +19,6 @@ integrity:HEADERS += arch/qatomic_integrity.h arch/qatomic_arch.h \ arch/qatomic_generic.h \ arch/qatomic_powerpc.h \ - arch/qatomic_arm.h \ arch/qatomic_armv5.h \ arch/qatomic_armv6.h \ arch/qatomic_armv7.h \ diff --git a/src/corelib/arch/qatomic_arm.h b/src/corelib/arch/qatomic_arm.h deleted file mode 100644 index 4394765d456..00000000000 --- a/src/corelib/arch/qatomic_arm.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtCore 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 QATOMIC_ARM_H -#define QATOMIC_ARM_H - -#if defined(__ARM_ARCH_7__) \ - || defined(__ARM_ARCH_7A__) \ - || defined(__ARM_ARCH_7R__) \ - || defined(__ARM_ARCH_7M__) -# define QT_ARCH_ARMV7 -# include "QtCore/qatomic_armv7.h" -#elif defined(__ARM_ARCH_6__) \ - || defined(__ARM_ARCH_6J__) \ - || defined(__ARM_ARCH_6T2__) \ - || defined(__ARM_ARCH_6Z__) \ - || defined(__ARM_ARCH_6K__) \ - || defined(__ARM_ARCH_6ZK__) \ - || defined(__ARM_ARCH_6M__) \ - || (defined(__TARGET_ARCH_ARM) && (__TARGET_ARCH_ARM-0 >= 6)) -# define QT_ARCH_ARMV6 -# include "QtCore/qatomic_armv6.h" -#else -# define QT_ARCH_ARMV5 -# include "QtCore/qatomic_armv5.h" -#endif - -#if 0 -// silence syncqt warnings -QT_BEGIN_HEADER -QT_BEGIN_NAMESPACE - -QT_END_NAMESPACE -QT_END_HEADER -#endif - -#endif // QATOMIC_ARM_H diff --git a/src/corelib/arch/qatomic_mips.h b/src/corelib/arch/qatomic_mips.h index af6e93d06ee..39119ba4119 100644 --- a/src/corelib/arch/qatomic_mips.h +++ b/src/corelib/arch/qatomic_mips.h @@ -227,7 +227,7 @@ T QBasicAtomicOps<4>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveTy return originalValue; } -#if defined(_MIPS_ARCH_MIPS64) || defined(__mips64) +#if defined(Q_PROCESSOR_MIPS_64) #define Q_ATOMIC_INT64_IS_SUPPORTED #define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_ALWAYS_NATIVE diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h index 527031bbd14..fee7561056c 100644 --- a/src/corelib/thread/qbasicatomic.h +++ b/src/corelib/thread/qbasicatomic.h @@ -48,15 +48,19 @@ # include #elif defined(Q_CC_MSVC) # include -#elif defined(__arm__) || defined(__TARGET_ARCH_ARM) -# include -#elif defined(__i386) || defined(__i386__) -# include -#elif defined(__ia64) || defined(__ia64__) +#elif defined(Q_PROCESSOR_ARM_V7) +# include "QtCore/qatomic_armv7.h" +#elif defined(Q_PROCESSOR_ARM_V6) +# include "QtCore/qatomic_armv6.h" +#elif defined(Q_PROCESSOR_ARM_V5) +# include "QtCore/qatomic_armv5.h" +#elif defined(Q_PROCESSOR_IA64) # include "QtCore/qatomic_ia64.h" -#elif defined(__mips) || defined(__mips__) +#elif defined(Q_PROCESSOR_MIPS) # include "QtCore/qatomic_mips.h" -#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) +#elif defined(Q_PROCESSOR_X86_32) +# include +#elif defined(Q_PROCESSOR_X86_64) # include #elif defined(Q_COMPILER_ATOMICS) && defined(Q_COMPILER_CONSTEXPR) # include From 0a8671fe502396e7c527dd82c3ec2e9daa4bf513 Mon Sep 17 00:00:00 2001 From: David Faure Date: Tue, 7 Feb 2012 20:42:37 +0100 Subject: [PATCH 071/406] Fix compilation with -Werror -Wshadow Change-Id: I2ef8f288415820fa08e5bab8b99a00b1ad0f2988 Reviewed-by: Thiago Macieira --- src/corelib/global/qlogging.h | 4 ++-- src/corelib/io/qurl.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h index c6edc7bc480..5ac6cc090ec 100644 --- a/src/corelib/global/qlogging.h +++ b/src/corelib/global/qlogging.h @@ -67,8 +67,8 @@ class QMessageLogContext Q_DISABLE_COPY(QMessageLogContext) public: QMessageLogContext() : version(1), line(0), file(0), function(0) {} - Q_DECL_CONSTEXPR QMessageLogContext(const char *file, int line, const char *function) - : version(1), line(line), file(file), function(function) {} + Q_DECL_CONSTEXPR QMessageLogContext(const char *fileName, int lineNumber, const char *functionName) + : version(1), line(lineNumber), file(fileName), function(functionName) {} int version; int line; diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h index c301d92dfb4..1c3390bc3d7 100644 --- a/src/corelib/io/qurl.h +++ b/src/corelib/io/qurl.h @@ -211,10 +211,10 @@ public: QString errorString() const; #if QT_DEPRECATED_SINCE(5,0) - QT_DEPRECATED void setEncodedUrl(const QByteArray &url, ParsingMode mode = TolerantMode) - { setUrl(QString::fromUtf8(url.constData(), url.size()), mode); } - QT_DEPRECATED static QUrl fromEncoded(const QByteArray &url, ParsingMode mode = TolerantMode) - { return QUrl(QString::fromUtf8(url.constData(), url.size()), mode); } + QT_DEPRECATED void setEncodedUrl(const QByteArray &u, ParsingMode mode = TolerantMode) + { setUrl(QString::fromUtf8(u.constData(), u.size()), mode); } + QT_DEPRECATED static QUrl fromEncoded(const QByteArray &u, ParsingMode mode = TolerantMode) + { return QUrl(QString::fromUtf8(u.constData(), u.size()), mode); } #endif private: From 6dc85408cdf2341f8b7c0911abfb3bb6a37021a8 Mon Sep 17 00:00:00 2001 From: Pasi Matilainen Date: Mon, 16 Jan 2012 09:10:18 +0200 Subject: [PATCH 072/406] QTextEdit cursor position fix when moving left/right with selection When text has been selected in a QTextEdit and the left or right arrow key is pressed, the cursor moves one character beyond the start or end of the selection, when it shouldn't move past the selection. Fixed by moving the cursor to the right place when a selection is active. Task-number: QTBUG-22853 Change-Id: I9ea1863436db98627a6fd041ce554cf10be26493 Reviewed-by: Jiang Jiang (cherry picked from commit 1b031759ddfdab9703dfecac13f1ed318da3dafe) --- src/gui/text/qtextcursor.cpp | 26 ++++++++++++++----- .../qplaintextedit/tst_qplaintextedit.cpp | 4 +-- .../widgets/qtextedit/tst_qtextedit.cpp | 4 +-- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index 25ec09d9db1..ddf2fb080e2 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -414,11 +414,18 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor break; } case QTextCursor::PreviousCharacter: - newPosition = priv->previousCursorPosition(position, QTextLayout::SkipCharacters); + if (mode == QTextCursor::MoveAnchor && position != adjusted_anchor) + newPosition = qMin(position, adjusted_anchor); + else + newPosition = priv->previousCursorPosition(position, QTextLayout::SkipCharacters); break; case QTextCursor::Left: - newPosition = visualMovement ? priv->leftCursorPosition(position) - : priv->previousCursorPosition(position, QTextLayout::SkipCharacters); + if (mode == QTextCursor::MoveAnchor && position != adjusted_anchor) + newPosition = visualMovement ? qMax(position, adjusted_anchor) + : qMin(position, adjusted_anchor); + else + newPosition = visualMovement ? priv->leftCursorPosition(position) + : priv->previousCursorPosition(position, QTextLayout::SkipCharacters); break; case QTextCursor::StartOfWord: { if (relativePos == 0) @@ -530,11 +537,18 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor break; } case QTextCursor::NextCharacter: - newPosition = priv->nextCursorPosition(position, QTextLayout::SkipCharacters); + if (mode == QTextCursor::MoveAnchor && position != adjusted_anchor) + newPosition = qMax(position, adjusted_anchor); + else + newPosition = priv->nextCursorPosition(position, QTextLayout::SkipCharacters); break; case QTextCursor::Right: - newPosition = visualMovement ? priv->rightCursorPosition(position) - : priv->nextCursorPosition(position, QTextLayout::SkipCharacters); + if (mode == QTextCursor::MoveAnchor && position != adjusted_anchor) + newPosition = visualMovement ? qMin(position, adjusted_anchor) + : qMax(position, adjusted_anchor); + else + newPosition = visualMovement ? priv->rightCursorPosition(position) + : priv->nextCursorPosition(position, QTextLayout::SkipCharacters); break; case QTextCursor::NextWord: case QTextCursor::WordRight: diff --git a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp index 1b483512e34..615e4453bcc 100644 --- a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp +++ b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp @@ -1474,11 +1474,11 @@ void tst_QPlainTextEdit::selectionChanged() QCOMPARE(selectionChangedSpy.count(), 3); QTest::keyClick(ed, Qt::Key_Right); - QCOMPARE(ed->textCursor().position(), 5); + QCOMPARE(ed->textCursor().position(), 4); QCOMPARE(selectionChangedSpy.count(), 4); QTest::keyClick(ed, Qt::Key_Right); - QCOMPARE(ed->textCursor().position(), 6); + QCOMPARE(ed->textCursor().position(), 5); QCOMPARE(selectionChangedSpy.count(), 4); } diff --git a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp index 47eb3a59a38..6253ef89e45 100644 --- a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp @@ -1840,11 +1840,11 @@ void tst_QTextEdit::selectionChanged() QCOMPARE(selectionChangedSpy.count(), 3); QTest::keyClick(ed, Qt::Key_Right); - QCOMPARE(ed->textCursor().position(), 5); + QCOMPARE(ed->textCursor().position(), 4); QCOMPARE(selectionChangedSpy.count(), 4); QTest::keyClick(ed, Qt::Key_Right); - QCOMPARE(ed->textCursor().position(), 6); + QCOMPARE(ed->textCursor().position(), 5); QCOMPARE(selectionChangedSpy.count(), 4); } From dd84eab9d8cccedeaaa4b00eea05e498a1aaeae7 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 7 Feb 2012 19:05:27 +0100 Subject: [PATCH 073/406] fix msvc 2008 warning about downcasting to bool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the compiler doesn't have static_assert yet, so we ran into the path which was not fixed by 10229ae. use !!() pattern instead of bool() cast, as the latter throws off macx (see 95d7abb). the other alternative - a c-style cast - would cause autotest failures (see 92464fa), and would be ugly anyway. Change-Id: Idbe9a3b60e17ae1f566f938d9b9be04f0c977492 Reviewed-by: João Abecasis --- src/corelib/global/qglobal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index f0d902f1f5e..33b5b8bd76d 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1031,7 +1031,7 @@ template <> class QStaticAssertFailure {}; #define Q_STATIC_ASSERT_PRIVATE_JOIN(A, B) Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B) #define Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B) A ## B #define Q_STATIC_ASSERT(Condition) \ - enum {Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __LINE__) = sizeof(QStaticAssertFailure<(Condition)>)} + enum {Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __LINE__) = sizeof(QStaticAssertFailure)} #define Q_STATIC_ASSERT_X(Condition, Message) Q_STATIC_ASSERT(Condition) #endif From 471cd624e632812f5b4147ba3a221562dbe9d300 Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Mon, 6 Feb 2012 23:58:40 +0100 Subject: [PATCH 074/406] QSqlTableModel::setRecord(): use submit for OnFieldChange submitAll() is supposed to be for OnManualSubmit. Change-Id: Id0335fe731669bd24e1da72ab4724f88d6f1d905 Reviewed-by: Oswald Buddenhagen --- src/sql/models/qsqltablemodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index df48115af3e..e83115b66e0 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -1246,7 +1246,7 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record) if (d->strategy == OnManualSubmit && isOk) emit dataChanged(createIndex(row, 0), createIndex(row, columnCount() - 1)); else if (d->strategy == OnFieldChange) - return submitAll(); + return submit(); else if (d->strategy == OnManualSubmit) return isOk; From f3138fa080b1c6ce7ab28c4572c3cf647b3485c1 Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Mon, 6 Feb 2012 14:04:26 +0100 Subject: [PATCH 075/406] QSqlTableModel: do not suppress dataChanged() on inserted record Affects setData() and setRecord(). Previously dataChanged() was suppressed when editing an inserted record, except for OnManualSubmit. The motivation was probably to allow setData() to be used while handling primeInsert(). Suppressing dataChanged() is not a good idea since views other than the one which made the change will not know of the change. It is a terrible idea to call setData() or setRecord() while handling primeInsert(), so this is now expressly forbidden. setData() and setRecord() now do nothing and return false if called while rows are being inserted. Change-Id: I96738c09a6268704c5626d95b72bfb46378e3242 Reviewed-by: Oswald Buddenhagen --- dist/changes-5.0.0 | 14 ++++++++++++++ src/sql/models/qsqltablemodel.cpp | 30 +++++++++++++----------------- src/sql/models/qsqltablemodel_p.h | 4 +++- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index 53171370594..c62d8b11636 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -328,6 +328,20 @@ QTestLib * [QTBUG-20615] Autotests can now log test output to multiple destinations and log formats simultaneously. +QtSql +----- +QSqlTableModel/QSqlRelationalTableModel + +* The dataChanged() signal is now emitted for changes made to an inserted +record that has not yet been committed. Previously, dataChanged() was +suppressed in this case for OnRowChange and OnFieldChange. This was probably +an attempt to avoid trouble if setData() was called while handling +primeInsert(). By emitting dataChanged(), we ensure that all views are aware +of the change. + +* While handling primeInsert() signal, the record must be manipulated using +the provided reference. Do not attempt to manipulate the records using the +model methods setData() or setRecord(). * removeRows() no longer emits extra beforeDelete signal for out of range row. diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index e83115b66e0..d943b5d1dc8 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -256,7 +256,9 @@ QSqlRecord QSqlTableModelPrivate::primaryValues(int row) initiated in the given \a row of the currently active database table. The \a record parameter can be written to (since it is a reference), for example to populate some fields with default - values. + values and set the generated flags of the fields. Do not try to + edit the record via other means such as setData() or setRecord() + while handling this signal. */ /*! @@ -479,6 +481,9 @@ bool QSqlTableModel::isDirty(const QModelIndex &index) const bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, int role) { Q_D(QSqlTableModel); + if (d->busyInsertingRows) + return false; + if (role != Qt::EditRole) return QSqlQueryModel::setData(index, value, role); @@ -512,19 +517,7 @@ bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, in select(); } - // historical bug: dataChanged() is suppressed for OnFieldChange and OnRowChange - // when operating on an "insert" record. This is to accomodate - // applications that call setData() while handling primeInsert(). - // Otherwise dataChanged() would be emitted between beginInsert() - // and endInsert(). - // The price of this workaround is that, although the view making - // the change will already display the new value, other views connected - // to the model probably will not. - // It's not clear why OnManualSubmit is excluded from this workaround. - // Calling setData() while handling primeInsert() is arguably very wrong anyway. - // primeInsert() provides a ref to the record for settings values. - if (d->strategy == OnManualSubmit || row.op() != QSqlTableModelPrivate::Insert) - emit dataChanged(index, index); + emit dataChanged(index, index); return isOk; } @@ -1049,6 +1042,7 @@ bool QSqlTableModel::insertRows(int row, int count, const QModelIndex &parent) if (d->strategy != OnManualSubmit && count != 1) return false; + d->busyInsertingRows = true; beginInsertRows(parent, row, row + count - 1); if (d->strategy != OnManualSubmit) @@ -1071,6 +1065,7 @@ bool QSqlTableModel::insertRows(int row, int count, const QModelIndex &parent) } endInsertRows(); + d->busyInsertingRows = false; return true; } @@ -1205,6 +1200,9 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record) { Q_D(QSqlTableModel); Q_ASSERT_X(row >= 0, "QSqlTableModel::setRecord()", "Cannot set a record to a row less than 0"); + if (d->busyInsertingRows) + return false; + if (row >= rowCount()) return false; @@ -1233,10 +1231,8 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record) // historical bug: it's a bad idea to check for change here // historical bug: should test oldValue.isNull() != value.isNull() if (oldValue.isNull() || oldValue != value) { - // historical bug: dataChanged() is suppressed for Insert. See also setData(). mrow.setValue(idx, record.value(i)); - if (mrow.op() != QSqlTableModelPrivate::Insert) - emit dataChanged(cIndex, cIndex); + emit dataChanged(cIndex, cIndex); } } else { mrow.setValue(idx, record.value(i)); diff --git a/src/sql/models/qsqltablemodel_p.h b/src/sql/models/qsqltablemodel_p.h index e6e70d23bcd..dbf2e275b89 100644 --- a/src/sql/models/qsqltablemodel_p.h +++ b/src/sql/models/qsqltablemodel_p.h @@ -66,7 +66,8 @@ public: QSqlTableModelPrivate() : sortColumn(-1), sortOrder(Qt::AscendingOrder), - strategy(QSqlTableModel::OnRowChange) + strategy(QSqlTableModel::OnRowChange), + busyInsertingRows(false) {} void clear(); QSqlRecord primaryValues(int index); @@ -86,6 +87,7 @@ public: Qt::SortOrder sortOrder; QSqlTableModel::EditStrategy strategy; + bool busyInsertingRows; QSqlQuery editQuery; QSqlIndex primaryIndex; From 678d56ccf1e6970c2cfe149b99f080ec1002c89f Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Wed, 8 Feb 2012 09:35:38 +0100 Subject: [PATCH 076/406] QSqlTableModel::setData(): call dataChanged() before select() Emit dataChanged() before a possible new select instead of after. The select reinserts all the rows, emitting signals for that, so there isn't any point to dataChanged() afterwards. Change-Id: I698a0d385f97104891343d94cc27e4ecf3a7233c Reviewed-by: Oswald Buddenhagen --- src/sql/models/qsqltablemodel.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index d943b5d1dc8..38705c70a90 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -506,6 +506,7 @@ bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, in } row.setValue(index.column(), value); + emit dataChanged(index, index); bool isOk = true; if (d->strategy == OnFieldChange && row.op() != QSqlTableModelPrivate::Insert) { @@ -517,8 +518,6 @@ bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, in select(); } - emit dataChanged(index, index); - return isOk; } From f5e58a1f69e5d17369198bbf1e7bb8946e3c7b5d Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Wed, 8 Feb 2012 09:38:05 +0100 Subject: [PATCH 077/406] QSqlTableModel::setData(): submit() instead of updateRowInTable() Use submit() instead of calling updatRowInTable(). The effect is exactly the same. Submit() invokes submitAll() which invokes updateRowInTable(). The cache is purged and select() is called only on success. Change-Id: I3de9a3d6acf802ee6594d034a9e261e53637995d Reviewed-by: Oswald Buddenhagen --- src/sql/models/qsqltablemodel.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 38705c70a90..1746883d34e 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -508,17 +508,10 @@ bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, in row.setValue(index.column(), value); emit dataChanged(index, index); - bool isOk = true; - if (d->strategy == OnFieldChange && row.op() != QSqlTableModelPrivate::Insert) { - // historical bug: bad style to call updateRowInTable. - // Should call submit(), but maybe the author wanted to avoid - // clearing the cache on failure. - isOk = updateRowInTable(index.row(), row.rec()); - if (isOk) - select(); - } + if (d->strategy == OnFieldChange && row.op() != QSqlTableModelPrivate::Insert) + return submit(); - return isOk; + return true; } /*! From 5953304bc5f50eca77f78fd0623479de6bebacbe Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Mon, 6 Feb 2012 15:03:25 +0100 Subject: [PATCH 078/406] QSqlTableModel::setRecord(): do not try to detect value changes In an apparent attempt to be economical with emitting dataChanged() and submitting SQL to the databse, setRecord() compares each field value of the record with the old value, taking action only when a difference is detected. Several complaints against this code are: -The comparision does not work on float type. -It is really up to the application and database to decide this. The model should make few assumptions. The application has the option to omit fields from the record that should be ignored. -The current behavior seems to assume that the "old" values are the current state of the database, but the database may have changed since the model was last refreshed. -The code compares the value from record(), which probably corresponds to the EditRole, with the DisplayRole value from data(). Change-Id: I11477c185eb411d442144dc682893d0df12d03d5 Reviewed-by: Oswald Buddenhagen --- src/sql/models/qsqltablemodel.cpp | 11 ++--------- .../sql/models/qsqltablemodel/tst_qsqltablemodel.cpp | 6 +++--- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 1746883d34e..7210ddce5bf 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -1217,15 +1217,8 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record) } else if (d->strategy != OnManualSubmit) { // historical bug: this could all be simple like OnManualSubmit, but isn't const QModelIndex cIndex = createIndex(row, idx); - // historical bug: comparing EditRole with DisplayRole values here - const QVariant oldValue = data(cIndex); - const QVariant value = record.value(i); - // historical bug: it's a bad idea to check for change here - // historical bug: should test oldValue.isNull() != value.isNull() - if (oldValue.isNull() || oldValue != value) { - mrow.setValue(idx, record.value(i)); - emit dataChanged(cIndex, cIndex); - } + mrow.setValue(idx, record.value(i)); + emit dataChanged(cIndex, cIndex); } else { mrow.setValue(idx, record.value(i)); } diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp index 6a827e65c50..518c6b6d255 100644 --- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp @@ -412,10 +412,10 @@ void tst_QSqlTableModel::setRecord() model.submit(); else { // dataChanged() is not emitted when submitAll() is called - QCOMPARE(spy.count(), 2); + QCOMPARE(spy.count(), model.columnCount()); QCOMPARE(spy.at(0).count(), 2); - QCOMPARE(qvariant_cast(spy.at(0).at(0)), model.index(i, 1)); - QCOMPARE(qvariant_cast(spy.at(0).at(1)), model.index(i, 1)); + QCOMPARE(qvariant_cast(spy.at(1).at(0)), model.index(i, 1)); + QCOMPARE(qvariant_cast(spy.at(1).at(1)), model.index(i, 1)); } } From 7b726900ecdd1d4d5e9b8f7c34f00dd27524b1c6 Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Mon, 6 Feb 2012 16:05:53 +0100 Subject: [PATCH 079/406] QSqlTableModel::setRecord(): emit dataChanged() consistently Previously, if any fields in the supplied record could not be matched with a column in the target table, dataChanged() was supressed for all columns for OnManualSubmit. This is not good because it prevents other views from noticing the fields that *do* change. It's simplest and probably more efficient just to emit dataChanged() once for the whole row. Fewer signals need to be processed and in typical cases much or all of the row is likely to be changed anyway. Change-Id: Ib56bf9a18e51b9cb85771acefcb2bf26e295a54e Reviewed-by: Oswald Buddenhagen --- src/sql/models/qsqltablemodel.cpp | 15 +++++---------- .../models/qsqltablemodel/tst_qsqltablemodel.cpp | 6 +++--- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 7210ddce5bf..437712d83ec 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -1212,21 +1212,16 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record) bool isOk = true; for (int i = 0; i < record.count(); ++i) { int idx = d->nameToIndex(record.fieldName(i)); - if (idx == -1) { + if (idx == -1) isOk = false; - } else if (d->strategy != OnManualSubmit) { - // historical bug: this could all be simple like OnManualSubmit, but isn't - const QModelIndex cIndex = createIndex(row, idx); + else mrow.setValue(idx, record.value(i)); - emit dataChanged(cIndex, cIndex); - } else { - mrow.setValue(idx, record.value(i)); - } } - if (d->strategy == OnManualSubmit && isOk) + if (columnCount()) emit dataChanged(createIndex(row, 0), createIndex(row, columnCount() - 1)); - else if (d->strategy == OnFieldChange) + + if (d->strategy == OnFieldChange) return submit(); else if (d->strategy == OnManualSubmit) return isOk; diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp index 518c6b6d255..a819cb720c1 100644 --- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp @@ -412,10 +412,10 @@ void tst_QSqlTableModel::setRecord() model.submit(); else { // dataChanged() is not emitted when submitAll() is called - QCOMPARE(spy.count(), model.columnCount()); + QCOMPARE(spy.count(), 1); QCOMPARE(spy.at(0).count(), 2); - QCOMPARE(qvariant_cast(spy.at(1).at(0)), model.index(i, 1)); - QCOMPARE(qvariant_cast(spy.at(1).at(1)), model.index(i, 1)); + QCOMPARE(qvariant_cast(spy.at(0).at(0)), model.index(i, 0)); + QCOMPARE(qvariant_cast(spy.at(0).at(1)), model.index(i, rec.count() - 1)); } } From e85c0862d92c226dcf0d0dac91808c036271d39f Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 8 Feb 2012 09:59:02 +0100 Subject: [PATCH 080/406] Mac: Fix compilation with -qtnamespace Change-Id: I85559b6698103eef865464a355d9b00012dcbd5f Reviewed-by: Friedemann Kleint --- src/corelib/kernel/qcore_mac_objc.mm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index 76705f1c8c2..35e3bb27d94 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -41,6 +41,8 @@ #include +QT_BEGIN_NAMESPACE + NSString *QCFString::toNSString(const QString &string) { // The const cast below is safe: CfStringRef is immutable and so is NSString. @@ -52,3 +54,5 @@ QString QCFString::toQString(const NSString *nsstr) return toQString(reinterpret_cast(nsstr)); } +QT_END_NAMESPACE + From ae85d7c965e7d50404c056a77c73bfe00267fa12 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 30 Dec 2011 13:18:24 +0100 Subject: [PATCH 081/406] Treat pointers to QObject derived types in QVariant specially. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is possible to do this for example: QVariant v = QVariant::fromValue(); QObject *object = v.value(); This means that if a QVariant contains a pointer to a QObject derived type, third parties can extract a QObject* and use its properties without knowing the concrete type. This is a source compatible change. Change-Id: Iee9a9437e99cc2f40d1a4bfea47275482ef7161f Reviewed-by: Jędrzej Nowacki --- src/corelib/kernel/qvariant.h | 72 ++++++++++++-- .../corelib/kernel/qvariant/tst_qvariant.cpp | 98 ++++++++++++++++++- 2 files changed, 156 insertions(+), 14 deletions(-) diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index b61b0cc33ce..089d0d643b1 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -49,6 +49,7 @@ #include #include #include +#include QT_BEGIN_HEADER @@ -88,6 +89,39 @@ inline QVariant qVariantFromValue(const T &); template inline T qvariant_cast(const QVariant &); +namespace QtPrivate { + + template + struct ObjectInvoker + { + static ReturnType invoke(Argument a) + { + return Derived::object(a); + } + }; + + template + struct MetaTypeInvoker + { + static ReturnType invoke(Argument a) + { + return Derived::metaType(a); + } + }; + + template ::Value> + struct TreatAsQObjectBeforeMetaType : ObjectInvoker + { + }; + + template + struct TreatAsQObjectBeforeMetaType : MetaTypeInvoker + { + }; + + template struct QVariantValueHelper; +} + class Q_CORE_EXPORT QVariant { public: @@ -375,14 +409,15 @@ protected: #ifndef QT_NO_DEBUG_STREAM friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant &); #endif - Private d; #ifndef Q_NO_TEMPLATE_FRIENDS template friend inline T qvariant_cast(const QVariant &); + template friend struct QtPrivate::QVariantValueHelper; protected: #else public: #endif + Private d; void create(int type, const void *copy); bool cmp(const QVariant &other) const; bool convert(const int t, void *ptr) const; @@ -481,18 +516,35 @@ inline bool operator!=(const QVariant &v1, const QVariantComparisonHelper &v2) } #endif +namespace QtPrivate { + template + struct QVariantValueHelper : TreatAsQObjectBeforeMetaType, T, const QVariant &, T> + { + static T metaType(const QVariant &v) + { + const int vid = qMetaTypeId(static_cast(0)); + if (vid == v.userType()) + return *reinterpret_cast(v.constData()); + if (vid < int(QMetaType::User)) { + T t; + if (v.convert(QVariant::Type(vid), &t)) + return t; + } + return T(); + } +#ifndef QT_NO_QOBJECT + static T object(const QVariant &v) + { + return qobject_cast(QMetaType::typeFlags(v.userType()) & QMetaType::PointerToQObject ? v.d.data.o : 0); + } +#endif + }; +} + #ifndef QT_MOC template inline T qvariant_cast(const QVariant &v) { - const int vid = qMetaTypeId(static_cast(0)); - if (vid == v.userType()) - return *reinterpret_cast(v.constData()); - if (vid < int(QMetaType::User)) { - T t; - if (v.convert(vid, &t)) - return t; - } - return T(); + return QtPrivate::QVariantValueHelper::invoke(v); } template<> inline QVariant qvariant_cast(const QVariant &v) diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index f7bdfd800ad..6991134938c 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -83,11 +83,22 @@ Q_DECLARE_METATYPE(QFont) Q_DECLARE_METATYPE(QColor) Q_DECLARE_METATYPE(QKeySequence) +class CustomNonQObject; + class tst_QVariant : public QObject { Q_OBJECT +public: + tst_QVariant(QObject *parent = 0) + : QObject(parent), customNonQObjectPointer(0) + { + + } + private slots: + void cleanupTestCase(); + void constructor(); void copy_constructor(); void isNull(); @@ -176,6 +187,7 @@ private slots: void qvariant_cast_QObject_data(); void qvariant_cast_QObject(); + void qvariant_cast_QObject_derived(); void toLocale(); @@ -275,6 +287,9 @@ private: void dataStream_data(QDataStream::Version version); void loadQVariantFromDataStream(QDataStream::Version version); void saveQVariantFromDataStream(QDataStream::Version version); + + CustomNonQObject *customNonQObjectPointer; + QVector objectPointerTestData; }; Q_DECLARE_METATYPE(QDate) @@ -2452,20 +2467,63 @@ void tst_QVariant::invalidQColor() const QVERIFY(!qvariant_cast(va).isValid()); } -void tst_QVariant::qvariant_cast_QObject_data() { +class CustomQObject : public QObject { + Q_OBJECT +public: + CustomQObject(QObject *parent = 0) : QObject(parent) {} +}; +class CustomQWidget : public QWidget { + Q_OBJECT +public: + CustomQWidget(QWidget *parent = 0) : QWidget(parent) {} +}; +Q_DECLARE_METATYPE(CustomQObject*) +Q_DECLARE_METATYPE(CustomQWidget*) +class CustomNonQObject { }; +Q_DECLARE_METATYPE(CustomNonQObject) +Q_DECLARE_METATYPE(CustomNonQObject*) + +void tst_QVariant::cleanupTestCase() +{ + delete customNonQObjectPointer; + qDeleteAll(objectPointerTestData); +} + +void tst_QVariant::qvariant_cast_QObject_data() +{ QTest::addColumn("data"); QTest::addColumn("success"); - QObject *obj = new QObject(this); + QObject *obj = new QObject; obj->setObjectName(QString::fromLatin1("Hello")); QTest::newRow("from QObject") << QVariant(QMetaType::QObjectStar, &obj) << true; QTest::newRow("from QObject2") << QVariant::fromValue(obj) << true; QTest::newRow("from String") << QVariant(QLatin1String("1, 2, 3")) << false; QTest::newRow("from int") << QVariant((int) 123) << false; + QWidget *widget = new QWidget; + widget->setObjectName(QString::fromLatin1("Hello")); + QTest::newRow("from QWidget") << QVariant::fromValue(widget) << true; + CustomQObject *customObject = new CustomQObject(this); + customObject->setObjectName(QString::fromLatin1("Hello")); + QTest::newRow("from Derived QObject") << QVariant::fromValue(customObject) << true; + CustomQWidget *customWidget = new CustomQWidget; + customWidget->setObjectName(QString::fromLatin1("Hello")); + QTest::newRow("from Derived QWidget") << QVariant::fromValue(customWidget) << true; + QTest::newRow("from custom Object") << QVariant::fromValue(CustomNonQObject()) << false; + + // Deleted in cleanupTestCase. + customNonQObjectPointer = new CustomNonQObject; + QTest::newRow("from custom ObjectStar") << QVariant::fromValue(customNonQObjectPointer) << false; + + // Deleted in cleanupTestCase. + objectPointerTestData.push_back(obj); + objectPointerTestData.push_back(widget); + objectPointerTestData.push_back(customObject); + objectPointerTestData.push_back(customWidget); } - -void tst_QVariant::qvariant_cast_QObject() { +void tst_QVariant::qvariant_cast_QObject() +{ QFETCH(QVariant, data); QFETCH(bool, success); @@ -2476,6 +2534,38 @@ void tst_QVariant::qvariant_cast_QObject() { } } +class CustomQObjectDerived : public CustomQObject { + Q_OBJECT +public: + CustomQObjectDerived(QObject *parent = 0) : CustomQObject(parent) {} +}; +Q_DECLARE_METATYPE(CustomQObjectDerived*) + +void tst_QVariant::qvariant_cast_QObject_derived() +{ + { + CustomQObjectDerived *object = new CustomQObjectDerived(this); + QVariant data = QVariant::fromValue(object); + + QVERIFY(data.userType() == qMetaTypeId()); + + QCOMPARE(data.value(), object); + QCOMPARE(data.value(), object); + QCOMPARE(data.value(), object); + QVERIFY(data.value() == 0); + } + { + CustomQWidget customWidget; + QWidget *widget = &customWidget; + QVariant data = QVariant::fromValue(widget); + QVERIFY(data.userType() == QMetaType::QWidgetStar); + + QCOMPARE(data.value(), widget); + QCOMPARE(data.value(), widget); + QCOMPARE(data.value(), widget); + } +} + Q_DECLARE_METATYPE(qint8); void tst_QVariant::convertToQUint8() const From c95a95306190bff15138b013dde33d98eab34d8d Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Wed, 8 Feb 2012 14:50:28 +0100 Subject: [PATCH 082/406] Use qgetenv instead of getenv. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the Qt Version because platforms like Windows CE don't support getenv. Change-Id: I95ca4d7194e09889ab228af80e679a3c34479e41 Reviewed-by: Miikka Heikkinen Reviewed-by: Samuel Rødal --- .../inputcontext/qplatforminputcontextfactory_qpa.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platformsupport/inputcontext/qplatforminputcontextfactory_qpa.cpp b/src/platformsupport/inputcontext/qplatforminputcontextfactory_qpa.cpp index e7fdf4385f6..9e38e4cedf2 100644 --- a/src/platformsupport/inputcontext/qplatforminputcontextfactory_qpa.cpp +++ b/src/platformsupport/inputcontext/qplatforminputcontextfactory_qpa.cpp @@ -82,7 +82,7 @@ QPlatformInputContext *QPlatformInputContextFactory::create() { QPlatformInputContext *ic = 0; - QString icString = QString::fromLatin1(getenv("QT_IM_MODULE")); + QString icString = QString::fromLatin1(qgetenv("QT_IM_MODULE")); ic = create(icString); if (ic && ic->isValid()) From 547a1f53050b887bacb766ea95381cde072a6d3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 6 Feb 2012 18:19:46 +0100 Subject: [PATCH 083/406] Fixed CustomDashLine drawing bug. The bug was caused by attempting to stroke an empty subpath. If there have been no line-to's emitted we should not try to join the start and end of that line segment. Task-number: QTBUG-23248 Change-Id: I38b7e955ed6683f8fc25f9551e93b4f472c022bf Reviewed-by: Kim M. Kalland (cherry picked from commit 593947ba70188df3d33efe031fab2fd255faa8b9) --- src/gui/painting/qstroker.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index ddf828982a7..1201a481b68 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -756,7 +756,9 @@ template bool qt_stroke_side(Iterator *it, #ifdef QPP_STROKE_DEBUG qDebug("\n ---> (side) closed subpath"); #endif - stroker->joinPoints(prev.x, prev.y, *startTangent, stroker->joinStyleMode()); + // don't join empty subpaths + if (!first) + stroker->joinPoints(prev.x, prev.y, *startTangent, stroker->joinStyleMode()); return true; } else { #ifdef QPP_STROKE_DEBUG From ee592fc042efc19acbc5407f5277abe7372c138d Mon Sep 17 00:00:00 2001 From: Nick Ratelle Date: Tue, 24 Jan 2012 17:26:13 -0500 Subject: [PATCH 084/406] realpath(X,0) IS supported on QNX. Adds check for Q_OS_QNX to force QFileSystemEntry QFileSystemEngine::canonicalName() use realpath(X, 0) on QNX as well. Change-Id: Id0a32277e6d043753c42101c91a393ebedb48a0a Reviewed-by: Thiago Macieira --- src/corelib/io/qfilesystemengine_unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 23a6b81a581..8d08bb59441 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -169,7 +169,7 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, if (entry.isEmpty() || entry.isRoot()) return entry; -#if !defined(Q_OS_MAC) && _POSIX_VERSION < 200809L +#if !defined(Q_OS_MAC) && !defined(Q_OS_QNX) && _POSIX_VERSION < 200809L // realpath(X,0) is not supported Q_UNUSED(data); return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath())); From c85eeaec7c27a8e1618537df8df31eb3f63982d8 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Wed, 8 Feb 2012 11:14:22 +0100 Subject: [PATCH 085/406] Add missing include of qdrawutil.h Change-Id: Ifda1e3a0fbe1ee3431374722878d5cde86ef3916 Reviewed-by: Miikka Heikkinen Reviewed-by: Friedemann Kleint --- src/widgets/styles/qwindowscestyle.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/widgets/styles/qwindowscestyle.cpp b/src/widgets/styles/qwindowscestyle.cpp index 72f74262687..5bd2de290a7 100644 --- a/src/widgets/styles/qwindowscestyle.cpp +++ b/src/widgets/styles/qwindowscestyle.cpp @@ -52,6 +52,7 @@ #include "qstyleoption.h" #include "qwindowscestyle_p.h" #include "qdebug.h" +#include "qdrawutil.h" QT_BEGIN_NAMESPACE From 22e0948bc3698de98831b03da92214d00cf49006 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Wed, 8 Feb 2012 11:06:21 +0100 Subject: [PATCH 086/406] Fix compilation of Menubar for Windows CE. Use QApplicationPrivate::getHWNDForWidget for getting the HWND for Widgets. The Menubar needs refactoring, but the API for native Menubars is not in place yet, so fix it temporarily. Change-Id: I090cca99d19aa881c2f41b54005a65f3ae67ae68 Reviewed-by: Miikka Heikkinen Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qmenu_wince.cpp | 6 ++++-- src/widgets/widgets/qmenubar.cpp | 4 ++-- src/widgets/widgets/qmenubar_p.h | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/widgets/widgets/qmenu_wince.cpp b/src/widgets/widgets/qmenu_wince.cpp index 11ae2844f88..9c748b2a538 100644 --- a/src/widgets/widgets/qmenu_wince.cpp +++ b/src/widgets/widgets/qmenu_wince.cpp @@ -377,7 +377,8 @@ void QMenuBarPrivate::wceCreateMenuBar(QWidget *parent) Q_Q(QMenuBar); wce_menubar = new QWceMenuBarPrivate(this); - wce_menubar->parentWindowHandle = parent ? parent->winId() : q->winId(); + wce_menubar->parentWindowHandle = parent ? QApplicationPrivate::getHWNDForWidget(parent) : + QApplicationPrivate::getHWNDForWidget(q); wce_menubar->leftButtonAction = defaultAction; wce_menubar->menubarHandle = qt_wce_create_menubar(wce_menubar->parentWindowHandle, (HINSTANCE)qWinAppInst(), 0, SHCMBF_EMPTYBAR); @@ -547,7 +548,8 @@ void QMenuBarPrivate::_q_updateDefaultAction() void QMenuBarPrivate::QWceMenuBarPrivate::rebuild() { d->q_func()->resize(0,0); - parentWindowHandle = d->q_func()->parentWidget() ? d->q_func()->parentWidget()->winId() : d->q_func()->winId(); + parentWindowHandle = d->q_func()->parentWidget() ? QApplicationPrivate::getHWNDForWidget(d->q_func()->parentWidget()) : + QApplicationPrivate::getHWNDForWidget(d->q_func()); if (d->wceClassicMenu) { QList actions = d->actions; int maxEntries; diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 7d6c1d8df9c..7a8d39f4623 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -784,7 +784,6 @@ QMenuBar::~QMenuBar() d->platformMenuBar = 0; #ifdef Q_OS_WINCE - Q_D(QMenuBar); if (qt_wince_is_mobile()) d->wceDestroyMenuBar(); #endif @@ -1244,8 +1243,9 @@ void QMenuBar::actionEvent(QActionEvent *e) d->itemsDirty = true; if (d->platformMenuBar) { +#if !defined(Q_OS_WINCE) QPlatformMenuBar *nativeMenuBar = d->platformMenuBar; -#if defined(Q_OS_WINCE) +#else QMenuBarPrivate::QWceMenuBarPrivate *nativeMenuBar = d->wce_menubar; #endif if (!nativeMenuBar) diff --git a/src/widgets/widgets/qmenubar_p.h b/src/widgets/widgets/qmenubar_p.h index 1af94bb236b..d73fc26a385 100644 --- a/src/widgets/widgets/qmenubar_p.h +++ b/src/widgets/widgets/qmenubar_p.h @@ -168,6 +168,7 @@ public: QWceMenuBarPrivate(QMenuBarPrivate *menubar); ~QWceMenuBarPrivate(); + void addAction(QAction *, QAction *); void addAction(QAction *, QWceMenuAction* =0); void addAction(QWceMenuAction *, QWceMenuAction* =0); void syncAction(QWceMenuAction *); From 14577726ee97c8d6dd176e0039ab2da0193c7bb1 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 8 Feb 2012 01:35:19 +0100 Subject: [PATCH 087/406] Build with QT_NO_CAST_FROM_BYTEARRAY Change-Id: I9069b61c6247bdff323e2e5e93b70e42c3504201 Reviewed-by: Marius Storm-Olsen Reviewed-by: David Faure --- src/corelib/kernel/qmetatype.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index e99c93c3722..fd27bb81de8 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -530,7 +530,7 @@ struct QMetaTypeId< SINGLE_ARG_TEMPLATE > \ { \ static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \ if (!metatype_id.load()) \ - metatype_id.storeRelease(qRegisterMetaType< SINGLE_ARG_TEMPLATE >( QByteArray(QByteArray(#SINGLE_ARG_TEMPLATE "<") + QMetaType::typeName(qMetaTypeId()) + ">"), \ + metatype_id.storeRelease(qRegisterMetaType< SINGLE_ARG_TEMPLATE >( QByteArray(QByteArray(#SINGLE_ARG_TEMPLATE "<") + QMetaType::typeName(qMetaTypeId()) + ">").constData(), \ reinterpret_cast< SINGLE_ARG_TEMPLATE *>(quintptr(-1)))); \ return metatype_id.loadAcquire(); \ } \ From 0c978407088fdbd15dc185aef7506087a88e1443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 31 Jan 2012 17:35:00 +0100 Subject: [PATCH 088/406] Introduce Q_DECLARE_OPAQUE_POINTER To hide the IsPointerToTypeDerivedFromQObject monstruosity :-) Documentation for Q_DECLARE_METATYPE and qRegisterMetaType was updated to mention requirements on registered types and how they can be circumvented for pointer types with the new macro. Change-Id: If83b037a8e2f28761eb903525e87008107298801 Reviewed-by: Harald Fernengel Reviewed-by: Stephen Kelly --- src/corelib/kernel/qmetatype.cpp | 20 +++++++++++++++++++ src/corelib/kernel/qmetatype.h | 10 ++++++++++ src/sql/drivers/psql/qsql_psql.cpp | 12 ++--------- src/sql/drivers/sqlite/qsql_sqlite.cpp | 12 ++--------- src/sql/drivers/sqlite2/qsql_sqlite2.cpp | 11 +++------- src/sql/drivers/tds/qsql_tds.cpp | 15 +++----------- .../corelib/kernel/qvariant/tst_qvariant.cpp | 8 ++------ 7 files changed, 42 insertions(+), 46 deletions(-) diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 6a7c5c2a346..d965c482557 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -116,6 +116,16 @@ template<> struct TypeDefinition { static const bool IsAvailable = fals #endif } // namespace +/*! + \macro Q_DECLARE_OPAQUE_POINTER(Pointer) + \relates QMetaType + + This macro enables pointers to forward-declared types to be registered with + QMetaType using either Q_DECLARE_METATYPE() or qRegisterMetaType(). + + \sa Q_DECLARE_METATYPE(), qRegisterMetaType() + +*/ /*! \macro Q_DECLARE_METATYPE(Type) @@ -126,6 +136,11 @@ template<> struct TypeDefinition { static const bool IsAvailable = fals a public destructor. It is needed to use the type \a Type as a custom type in QVariant. + This macro requires that \a Type is a fully defined type at the point where + it is used. For pointer types, it also requires that the pointed to type is + fully defined. Use in conjunction with Q_DECLARE_OPAQUE_POINTER() to + register pointers to forward declared types. + Ideally, this macro should be placed below the declaration of the class or struct. If that is not possible, it can be put in a private header file which has to be included every time that @@ -1630,6 +1645,11 @@ QMetaType::TypeFlags QMetaType::typeFlags(int type) public default constructor, a public copy constructor and a public destructor can be registered. + This function requires that \c{T} is a fully defined type at the point + where the function is called. For pointer types, it also requires that the + pointed to type is fully defined. Use Q_DECLARE_OPAQUE_POINTER() to be able + to register pointers to forward declared types. + After a type has been registered, you can create and destroy objects of that type dynamically at run-time. diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index fd27bb81de8..9e702298c13 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -471,6 +471,16 @@ inline int qRegisterMetaTypeStreamOperators() } #endif +#define Q_DECLARE_OPAQUE_POINTER(POINTER) \ + QT_BEGIN_NAMESPACE namespace QtPrivate { \ + template <> \ + struct IsPointerToTypeDerivedFromQObject \ + { \ + enum { Value = false }; \ + }; \ + } QT_END_NAMESPACE \ + /**/ + #define Q_DECLARE_METATYPE(TYPE) \ QT_BEGIN_NAMESPACE \ template <> \ diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index e3533581baf..ec31d54f0f1 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -107,18 +107,10 @@ template inline void PQfreemem(T *t, int = 0) { free(t); } -QT_BEGIN_NAMESPACE namespace QtPrivate { -template <> struct IsPointerToTypeDerivedFromQObject { - enum { Value = false }; -}; -} QT_END_NAMESPACE +Q_DECLARE_OPAQUE_POINTER(PGconn*) Q_DECLARE_METATYPE(PGconn*) -QT_BEGIN_NAMESPACE namespace QtPrivate { -template <> struct IsPointerToTypeDerivedFromQObject { - enum { Value = false }; -}; -} QT_END_NAMESPACE +Q_DECLARE_OPAQUE_POINTER(PGresult*) Q_DECLARE_METATYPE(PGresult*) QT_BEGIN_NAMESPACE diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp index 962fc97dfc2..d2dc5af0703 100644 --- a/src/sql/drivers/sqlite/qsql_sqlite.cpp +++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp @@ -59,18 +59,10 @@ #include -QT_BEGIN_NAMESPACE namespace QtPrivate { -template <> struct IsPointerToTypeDerivedFromQObject { - enum { Value = false }; -}; -} QT_END_NAMESPACE +Q_DECLARE_OPAQUE_POINTER(sqlite3*) Q_DECLARE_METATYPE(sqlite3*) -QT_BEGIN_NAMESPACE namespace QtPrivate { -template <> struct IsPointerToTypeDerivedFromQObject { - enum { Value = false }; -}; -} QT_END_NAMESPACE +Q_DECLARE_OPAQUE_POINTER(sqlite3_stmt*) Q_DECLARE_METATYPE(sqlite3_stmt*) QT_BEGIN_NAMESPACE diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp index 46127923bf8..b42f82e8008 100644 --- a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp +++ b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp @@ -60,15 +60,10 @@ typedef struct sqlite_vm sqlite_vm; -QT_BEGIN_NAMESPACE namespace QtPrivate { -template <> struct IsPointerToTypeDerivedFromQObject { - enum { Value = false }; -}; -template <> struct IsPointerToTypeDerivedFromQObject { - enum { Value = false }; -}; -} QT_END_NAMESPACE +Q_DECLARE_OPAQUE_POINTER(sqlite_vm*) Q_DECLARE_METATYPE(sqlite_vm*) + +Q_DECLARE_OPAQUE_POINTER(sqlite*) Q_DECLARE_METATYPE(sqlite*) QT_BEGIN_NAMESPACE diff --git a/src/sql/drivers/tds/qsql_tds.cpp b/src/sql/drivers/tds/qsql_tds.cpp index 2a97a3c392f..b9414499d8f 100644 --- a/src/sql/drivers/tds/qsql_tds.cpp +++ b/src/sql/drivers/tds/qsql_tds.cpp @@ -63,6 +63,9 @@ #include +Q_DECLARE_OPAQUE_POINTER(LOGINREC*) +Q_DECLARE_OPAQUE_POINTER(DBPROCESS*) + QT_BEGIN_NAMESPACE #ifdef DBNTWIN32 @@ -127,18 +130,6 @@ QT_BEGIN_NAMESPACE #define CS_PUBLIC #endif -namespace QtPrivate { -template <> struct IsPointerToTypeDerivedFromQObject { - enum { Value = false }; -}; -} - -namespace QtPrivate { -template <> struct IsPointerToTypeDerivedFromQObject { - enum { Value = false }; -}; -} - QSqlError qMakeError(const QString& err, QSqlError::ErrorType type, int errNo = -1) { return QSqlError(QLatin1String("QTDS: ") + err, QString(), type, errNo); diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 6991134938c..001749e88ed 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -3451,12 +3451,8 @@ void tst_QVariant::colorInteger() } class Forward; -QT_BEGIN_NAMESPACE namespace QtPrivate { -template <> struct IsPointerToTypeDerivedFromQObject { - enum { Value = false }; -}; -} QT_END_NAMESPACE -Q_DECLARE_METATYPE(Forward*); +Q_DECLARE_OPAQUE_POINTER(Forward*) +Q_DECLARE_METATYPE(Forward*) void tst_QVariant::forwardDeclare() { From 88f15faa4aad798d37df6a4baf1950c31d04dcf1 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Wed, 8 Feb 2012 14:54:54 +0100 Subject: [PATCH 089/406] Fix compile with QT_NO_OPENGL. Change-Id: Icade54a6e3b43fdc9c151efbc25adcef6b7e41d6 Reviewed-by: Miikka Heikkinen Reviewed-by: Gunnar Sletta --- src/gui/kernel/qopenglcontext_p.h | 3 +++ src/gui/kernel/qplatformopenglcontext_qpa.h | 3 +++ src/opengl/qgl.h | 3 +++ 3 files changed, 9 insertions(+) diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h index 7b4e880ade8..3e2c35f0885 100644 --- a/src/gui/kernel/qopenglcontext_p.h +++ b/src/gui/kernel/qopenglcontext_p.h @@ -42,6 +42,8 @@ #ifndef QGUIGLCONTEXT_P_H #define QGUIGLCONTEXT_P_H +#ifndef QT_NO_OPENGL + #include "qopengl.h" #include "qopenglcontext.h" #include @@ -245,4 +247,5 @@ QT_END_NAMESPACE QT_END_HEADER +#endif // QT_NO_OPENGL #endif // QGUIGLCONTEXT_P_H diff --git a/src/gui/kernel/qplatformopenglcontext_qpa.h b/src/gui/kernel/qplatformopenglcontext_qpa.h index 17d4e96f8ec..af70368f5e9 100644 --- a/src/gui/kernel/qplatformopenglcontext_qpa.h +++ b/src/gui/kernel/qplatformopenglcontext_qpa.h @@ -42,6 +42,8 @@ #ifndef QPLATFORMGLCONTEXT_H #define QPLATFORMGLCONTEXT_H +#ifndef QT_NO_OPENGL + #include #include #include @@ -91,5 +93,6 @@ QT_END_NAMESPACE QT_END_HEADER +#endif // QT_NO_OPENGL #endif // QPLATFORMGLCONTEXT_H diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index be1651ea2f4..caa5b96cdc9 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -42,6 +42,8 @@ #ifndef QGL_H #define QGL_H +#ifndef QT_NO_OPENGL + #include #include #include @@ -551,4 +553,5 @@ QT_END_NAMESPACE QT_END_HEADER +#endif // QT_NO_OPENGL #endif // QGL_H From 0efb8a7ee3ef3ca37760ecf1972c0f2bc5ae2846 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 8 Feb 2012 10:16:37 +0100 Subject: [PATCH 090/406] Avoid advancing animations outside the animation "tick" We have logic to prevent animations from starting in the middle of an animation as a result of a previously slow frame. This was based on current time, not the animation driver time and would cause severe jumping when custom animation drivers were being used. Also, this logic would trigger multiple animation runs per frame, which is very bad for performance, so this change introduces a threshold of 50ms to compensate for that. 50ms because that is triplebuffer limit. Change-Id: I1c7ebac30060e849d03c14d62411c2b953854d98 Reviewed-by: Michael Brasser --- src/corelib/animation/qabstractanimation.cpp | 8 +++++++- src/corelib/animation/qabstractanimation.h | 2 +- src/corelib/animation/qabstractanimation_p.h | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 30f071498ed..04df52c6f01 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -248,6 +248,12 @@ QUnifiedTimer *QUnifiedTimer::instance() return instance(true); } +void QUnifiedTimer::maybeUpdateAnimationsToCurrentTime() +{ + if (time.elapsed() - lastTick > 50) + updateAnimationTimers(driver->elapsed()); +} + void QUnifiedTimer::updateAnimationTimers(qint64 currentTick) { //setCurrentTime can get this called again while we're the for loop. At least with pauseAnimations @@ -590,7 +596,7 @@ void QAnimationTimer::startAnimations() startAnimationPending = false; //force timer to update, which prevents large deltas for our newly added animations if (!animations.isEmpty()) - QUnifiedTimer::instance()->updateAnimationTimers(-1); + QUnifiedTimer::instance()->maybeUpdateAnimationsToCurrentTime(); //we transfer the waiting animations into the "really running" state animations += animationsToStart; diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h index 70200c4064d..34ddbc606f5 100644 --- a/src/corelib/animation/qabstractanimation.h +++ b/src/corelib/animation/qabstractanimation.h @@ -149,7 +149,7 @@ public: bool isRunning() const; - qint64 elapsed() const; + virtual qint64 elapsed() const; Q_SIGNALS: void started(); diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index c4d53342c25..02a3c02ddce 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -185,6 +185,7 @@ public: bool canUninstallAnimationDriver(QAnimationDriver *driver); void restart(); + void maybeUpdateAnimationsToCurrentTime(); void updateAnimationTimers(qint64 currentTick); //useful for profiling/debugging From 931f4501a6f5fb77c9bd9f48b63a8ee88cba4355 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 8 Feb 2012 14:06:18 +1000 Subject: [PATCH 091/406] Fixed tst_selftests on OSX 10.7 Our OSX 10.7 test machines send a SIGILL rather than a SIGSEGV to a process which attempts to dereference a null pointer. Change the "crashes" test to dereference an invalid pointer with a value slightly greater than 0 so that we get the same crash behavior on all (unix) platforms. Change-Id: I700a2c7d654a9468af5e5996010a258695ed2ae5 Reviewed-by: Jason McDonald --- tests/auto/testlib/selftests/crashes/tst_crashes.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/auto/testlib/selftests/crashes/tst_crashes.cpp b/tests/auto/testlib/selftests/crashes/tst_crashes.cpp index b6298f5e63a..c2174e90e84 100644 --- a/tests/auto/testlib/selftests/crashes/tst_crashes.cpp +++ b/tests/auto/testlib/selftests/crashes/tst_crashes.cpp @@ -61,8 +61,14 @@ void tst_Crashes::crash() //we avoid the error dialogbox to appear on windows SetErrorMode( SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); #endif + /* + We deliberately dereference an invalid but non-zero address; + it should be non-zero because a few platforms may have special crash behavior + when dereferencing exactly 0 (e.g. some macs have been observed to generate SIGILL + rather than SIGSEGV). + */ int *i = 0; - *i = 1; + i[1] = 1; } QTEST_MAIN(tst_Crashes) From 95d0b27711c2f75af233c9a083c9818400db0957 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Fri, 3 Feb 2012 10:22:13 +1000 Subject: [PATCH 092/406] testlib: Add selftests for skip and fail inside cleanupTestCase(). Change-Id: I9bbe774c3259338d452cd1eb1a6f37a85db15921 Reviewed-by: Rohan McGovern --- .../selftests/expected_failcleanup.lightxml | 15 +++++ .../selftests/expected_failcleanup.txt | 8 +++ .../selftests/expected_failcleanup.xml | 18 ++++++ .../selftests/expected_failcleanup.xunitxml | 13 ++++ .../selftests/expected_skipcleanup.lightxml | 15 +++++ .../selftests/expected_skipcleanup.txt | 8 +++ .../selftests/expected_skipcleanup.xml | 18 ++++++ .../selftests/expected_skipcleanup.xunitxml | 15 +++++ .../selftests/failcleanup/failcleanup.pro | 7 +++ .../selftests/failcleanup/tst_failcleanup.cpp | 63 +++++++++++++++++++ tests/auto/testlib/selftests/selftests.pri | 2 +- tests/auto/testlib/selftests/selftests.qrc | 8 +++ .../selftests/skipcleanup/skipcleanup.pro | 7 +++ .../selftests/skipcleanup/tst_skipcleanup.cpp | 63 +++++++++++++++++++ .../auto/testlib/selftests/tst_selftests.cpp | 2 + 15 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 tests/auto/testlib/selftests/expected_failcleanup.lightxml create mode 100644 tests/auto/testlib/selftests/expected_failcleanup.txt create mode 100644 tests/auto/testlib/selftests/expected_failcleanup.xml create mode 100644 tests/auto/testlib/selftests/expected_failcleanup.xunitxml create mode 100644 tests/auto/testlib/selftests/expected_skipcleanup.lightxml create mode 100644 tests/auto/testlib/selftests/expected_skipcleanup.txt create mode 100644 tests/auto/testlib/selftests/expected_skipcleanup.xml create mode 100644 tests/auto/testlib/selftests/expected_skipcleanup.xunitxml create mode 100644 tests/auto/testlib/selftests/failcleanup/failcleanup.pro create mode 100644 tests/auto/testlib/selftests/failcleanup/tst_failcleanup.cpp create mode 100644 tests/auto/testlib/selftests/skipcleanup/skipcleanup.pro create mode 100644 tests/auto/testlib/selftests/skipcleanup/tst_skipcleanup.cpp diff --git a/tests/auto/testlib/selftests/expected_failcleanup.lightxml b/tests/auto/testlib/selftests/expected_failcleanup.lightxml new file mode 100644 index 00000000000..83ce7a7b151 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_failcleanup.lightxml @@ -0,0 +1,15 @@ + + @INSERT_QT_VERSION_HERE@ + @INSERT_QT_VERSION_HERE@ + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_failcleanup.txt b/tests/auto/testlib/selftests/expected_failcleanup.txt new file mode 100644 index 00000000000..08c10b18232 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_failcleanup.txt @@ -0,0 +1,8 @@ +********* Start testing of tst_FailCleanup ********* +Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ +PASS : tst_FailCleanup::initTestCase() +PASS : tst_FailCleanup::aTestFunction() +FAIL! : tst_FailCleanup::cleanupTestCase() 'false' returned FALSE. (Fail inside cleanupTestCase) + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/failcleanup/tst_failcleanup.cpp(59)] +Totals: 2 passed, 1 failed, 0 skipped +********* Finished testing of tst_FailCleanup ********* diff --git a/tests/auto/testlib/selftests/expected_failcleanup.xml b/tests/auto/testlib/selftests/expected_failcleanup.xml new file mode 100644 index 00000000000..5d0d2c57518 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_failcleanup.xml @@ -0,0 +1,18 @@ + + + + @INSERT_QT_VERSION_HERE@ + @INSERT_QT_VERSION_HERE@ + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_failcleanup.xunitxml b/tests/auto/testlib/selftests/expected_failcleanup.xunitxml new file mode 100644 index 00000000000..6e35566be88 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_failcleanup.xunitxml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_skipcleanup.lightxml b/tests/auto/testlib/selftests/expected_skipcleanup.lightxml new file mode 100644 index 00000000000..d2bc3b766eb --- /dev/null +++ b/tests/auto/testlib/selftests/expected_skipcleanup.lightxml @@ -0,0 +1,15 @@ + + @INSERT_QT_VERSION_HERE@ + @INSERT_QT_VERSION_HERE@ + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_skipcleanup.txt b/tests/auto/testlib/selftests/expected_skipcleanup.txt new file mode 100644 index 00000000000..c97f31c2a9b --- /dev/null +++ b/tests/auto/testlib/selftests/expected_skipcleanup.txt @@ -0,0 +1,8 @@ +********* Start testing of tst_SkipCleanup ********* +Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ +PASS : tst_SkipCleanup::initTestCase() +PASS : tst_SkipCleanup::aTestFunction() +SKIP : tst_SkipCleanup::cleanupTestCase() Skip inside cleanupTestCase. + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skipcleanup/tst_skipcleanup.cpp(59)] +Totals: 2 passed, 0 failed, 1 skipped +********* Finished testing of tst_SkipCleanup ********* diff --git a/tests/auto/testlib/selftests/expected_skipcleanup.xml b/tests/auto/testlib/selftests/expected_skipcleanup.xml new file mode 100644 index 00000000000..8fbfc7711c0 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_skipcleanup.xml @@ -0,0 +1,18 @@ + + + + @INSERT_QT_VERSION_HERE@ + @INSERT_QT_VERSION_HERE@ + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_skipcleanup.xunitxml b/tests/auto/testlib/selftests/expected_skipcleanup.xunitxml new file mode 100644 index 00000000000..b8f67e2d072 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_skipcleanup.xunitxml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/failcleanup/failcleanup.pro b/tests/auto/testlib/selftests/failcleanup/failcleanup.pro new file mode 100644 index 00000000000..426d7cc45b7 --- /dev/null +++ b/tests/auto/testlib/selftests/failcleanup/failcleanup.pro @@ -0,0 +1,7 @@ +SOURCES += tst_failcleanup.cpp +QT = core testlib + +mac:CONFIG -= app_bundle +CONFIG -= debug_and_release_target + +TARGET = failcleanup diff --git a/tests/auto/testlib/selftests/failcleanup/tst_failcleanup.cpp b/tests/auto/testlib/selftests/failcleanup/tst_failcleanup.cpp new file mode 100644 index 00000000000..a1b3b2d15a0 --- /dev/null +++ b/tests/auto/testlib/selftests/failcleanup/tst_failcleanup.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite 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 + +class tst_FailCleanup: public QObject +{ +Q_OBJECT +private slots: + void aTestFunction() const; + void cleanupTestCase() const; +}; + +void tst_FailCleanup::aTestFunction() const +{ + QVERIFY(true); +} + +void tst_FailCleanup::cleanupTestCase() const +{ + QVERIFY2(false, "Fail inside cleanupTestCase"); +} + +QTEST_APPLESS_MAIN(tst_FailCleanup) +#include "tst_failcleanup.moc" diff --git a/tests/auto/testlib/selftests/selftests.pri b/tests/auto/testlib/selftests/selftests.pri index 95664c3793e..9d4b2bd600f 100644 --- a/tests/auto/testlib/selftests/selftests.pri +++ b/tests/auto/testlib/selftests/selftests.pri @@ -4,4 +4,4 @@ SUBPROGRAMS = subtest warnings maxwarnings cmptest globaldata skip \ exceptionthrow qexecstringlist datatable commandlinedata\ benchlibwalltime benchlibcallgrind benchlibeventcounter benchlibtickcounter \ benchliboptions xunit badxml longstring float printdatatags \ - printdatatagswithglobaltags findtestdata counting + printdatatagswithglobaltags findtestdata counting skipcleanup failcleanup diff --git a/tests/auto/testlib/selftests/selftests.qrc b/tests/auto/testlib/selftests/selftests.qrc index d10aa56cebd..f882068f6de 100644 --- a/tests/auto/testlib/selftests/selftests.qrc +++ b/tests/auto/testlib/selftests/selftests.qrc @@ -64,6 +64,10 @@ expected_expectfail.txt expected_expectfail.xml expected_expectfail.xunitxml + expected_failcleanup.lightxml + expected_failcleanup.txt + expected_failcleanup.xml + expected_failcleanup.xunitxml expected_failinit.lightxml expected_failinit.txt expected_failinit.xml @@ -108,6 +112,10 @@ expected_skip.txt expected_skip.xml expected_skip.xunitxml + expected_skipcleanup.lightxml + expected_skipcleanup.txt + expected_skipcleanup.xml + expected_skipcleanup.xunitxml expected_skipinit.lightxml expected_skipinit.txt expected_skipinit.xml diff --git a/tests/auto/testlib/selftests/skipcleanup/skipcleanup.pro b/tests/auto/testlib/selftests/skipcleanup/skipcleanup.pro new file mode 100644 index 00000000000..f98cda7596a --- /dev/null +++ b/tests/auto/testlib/selftests/skipcleanup/skipcleanup.pro @@ -0,0 +1,7 @@ +SOURCES += tst_skipcleanup.cpp +QT = core testlib + +mac:CONFIG -= app_bundle +CONFIG -= debug_and_release_target + +TARGET = skipcleanup diff --git a/tests/auto/testlib/selftests/skipcleanup/tst_skipcleanup.cpp b/tests/auto/testlib/selftests/skipcleanup/tst_skipcleanup.cpp new file mode 100644 index 00000000000..262aefa9827 --- /dev/null +++ b/tests/auto/testlib/selftests/skipcleanup/tst_skipcleanup.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite 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 + +class tst_SkipCleanup: public QObject +{ +Q_OBJECT +private slots: + void aTestFunction() const; + void cleanupTestCase() const; +}; + +void tst_SkipCleanup::aTestFunction() const +{ + QVERIFY(true); +} + +void tst_SkipCleanup::cleanupTestCase() const +{ + QSKIP("Skip inside cleanupTestCase."); +} + +QTEST_APPLESS_MAIN(tst_SkipCleanup) +#include "tst_skipcleanup.moc" diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index aaa58e092c3..dc7966b82b0 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -338,6 +338,7 @@ void tst_Selftests::runSubTest_data() << "exceptionthrow" #endif << "expectfail" + << "failcleanup" << "failinit" << "failinitdata" #if !defined(Q_OS_WIN) @@ -354,6 +355,7 @@ void tst_Selftests::runSubTest_data() << "qexecstringlist" << "singleskip" << "skip" + << "skipcleanup" << "skipinit" << "skipinitdata" << "sleep" From 7aa5a89eeff40b70b8318171f71bc222dc23179d Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Fri, 3 Feb 2012 13:03:10 +1000 Subject: [PATCH 093/406] Add data tag names to datetime selftest. Change-Id: I73a0faab06df99521a48f106d93dd7b9a620148d Reviewed-by: Rohan McGovern --- tests/auto/testlib/selftests/datetime/tst_datetime.cpp | 8 ++++---- tests/auto/testlib/selftests/expected_datetime.lightxml | 2 ++ tests/auto/testlib/selftests/expected_datetime.txt | 4 ++-- tests/auto/testlib/selftests/expected_datetime.xml | 2 ++ tests/auto/testlib/selftests/expected_datetime.xunitxml | 4 ++-- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/auto/testlib/selftests/datetime/tst_datetime.cpp b/tests/auto/testlib/selftests/datetime/tst_datetime.cpp index 60ebbfc104a..c98f119f75a 100644 --- a/tests/auto/testlib/selftests/datetime/tst_datetime.cpp +++ b/tests/auto/testlib/selftests/datetime/tst_datetime.cpp @@ -78,10 +78,10 @@ void tst_DateTime::qurl_data() const QTest::addColumn("operandA"); QTest::addColumn("operandB"); - QTest::newRow("") << QUrl() << QUrl(); - QTest::newRow("") << QUrl(QLatin1String("http://example.com")) << QUrl(); - QTest::newRow("") << QUrl() << QUrl(QLatin1String("http://example.com")); - QTest::newRow("") << QUrl(QLatin1String("http://example.com")) << QUrl(QLatin1String("http://example.com")); + QTest::newRow("empty urls") << QUrl() << QUrl(); + QTest::newRow("empty rhs") << QUrl(QLatin1String("http://example.com")) << QUrl(); + QTest::newRow("empty lhs") << QUrl() << QUrl(QLatin1String("http://example.com")); + QTest::newRow("same urls") << QUrl(QLatin1String("http://example.com")) << QUrl(QLatin1String("http://example.com")); } QTEST_MAIN(tst_DateTime) diff --git a/tests/auto/testlib/selftests/expected_datetime.lightxml b/tests/auto/testlib/selftests/expected_datetime.lightxml index 1b7e6015859..0024b101aae 100644 --- a/tests/auto/testlib/selftests/expected_datetime.lightxml +++ b/tests/auto/testlib/selftests/expected_datetime.lightxml @@ -14,11 +14,13 @@ + + diff --git a/tests/auto/testlib/selftests/expected_datetime.txt b/tests/auto/testlib/selftests/expected_datetime.txt index 70d5c5a70c6..e2966b9168a 100644 --- a/tests/auto/testlib/selftests/expected_datetime.txt +++ b/tests/auto/testlib/selftests/expected_datetime.txt @@ -5,11 +5,11 @@ FAIL! : tst_DateTime::dateTime() Compared values are not the same Actual (local): 2000/05/03 04:03:04.000[local time] Expected (utc): 2000/05/03 04:03:04.000[UTC] Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp(33)] -FAIL! : tst_DateTime::qurl() Compared values are not the same +FAIL! : tst_DateTime::qurl(empty rhs) Compared values are not the same Actual (operandA): http://example.com Expected (operandB): Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp(41)] -FAIL! : tst_DateTime::qurl() Compared values are not the same +FAIL! : tst_DateTime::qurl(empty lhs) Compared values are not the same Actual (operandA): Expected (operandB): http://example.com Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp(41)] diff --git a/tests/auto/testlib/selftests/expected_datetime.xml b/tests/auto/testlib/selftests/expected_datetime.xml index d848e73c824..f1b5a6aafd9 100644 --- a/tests/auto/testlib/selftests/expected_datetime.xml +++ b/tests/auto/testlib/selftests/expected_datetime.xml @@ -16,11 +16,13 @@ + + diff --git a/tests/auto/testlib/selftests/expected_datetime.xunitxml b/tests/auto/testlib/selftests/expected_datetime.xunitxml index b30d1c441f7..f25e20674b1 100644 --- a/tests/auto/testlib/selftests/expected_datetime.xunitxml +++ b/tests/auto/testlib/selftests/expected_datetime.xunitxml @@ -11,10 +11,10 @@ Expected (utc): 2000/05/03 04:03:04.000[UTC]" result="fail"/> - - From 7b7b58ae095e1f098a401f584aeefeb6e2a2fd43 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Fri, 3 Feb 2012 15:02:08 +1000 Subject: [PATCH 094/406] Remove unused test results from testlib selftests. Some of the subtests are only run with plain-text output format. For those subtests, the other output formats were unused and gradually becoming out-of-date. Change-Id: I4c10f7f5bab2d2cc7d2d2ad641fbf5d4df02b798 Reviewed-by: Rohan McGovern --- .../expected_benchlibcallgrind.lightxml | 14 ------ .../selftests/expected_benchlibcallgrind.xml | 17 ------- .../expected_benchlibcallgrind.xunitxml | 12 ----- .../expected_benchliboptions.lightxml | 15 ------ .../selftests/expected_benchliboptions.xml | 17 ------- .../expected_benchliboptions.xunitxml | 12 ----- .../selftests/expected_crashes.lightxml | 15 ------ .../testlib/selftests/expected_crashes.xml | 18 ------- .../selftests/expected_crashes.xunitxml | 15 ------ .../testlib/selftests/expected_float.lightxml | 44 ----------------- .../auto/testlib/selftests/expected_float.xml | 47 ------------------- .../testlib/selftests/expected_float.xunitxml | 29 ------------ .../selftests/expected_multiexec.lightxml | 13 ----- .../testlib/selftests/expected_multiexec.xml | 16 ------- .../selftests/expected_multiexec.xunitxml | 11 ----- .../testlib/selftests/expected_sleep.lightxml | 13 ----- .../auto/testlib/selftests/expected_sleep.xml | 16 ------- .../testlib/selftests/expected_sleep.xunitxml | 11 ----- tests/auto/testlib/selftests/selftests.qrc | 18 ------- 19 files changed, 353 deletions(-) delete mode 100644 tests/auto/testlib/selftests/expected_benchlibcallgrind.lightxml delete mode 100644 tests/auto/testlib/selftests/expected_benchlibcallgrind.xml delete mode 100644 tests/auto/testlib/selftests/expected_benchlibcallgrind.xunitxml delete mode 100644 tests/auto/testlib/selftests/expected_benchliboptions.lightxml delete mode 100644 tests/auto/testlib/selftests/expected_benchliboptions.xml delete mode 100644 tests/auto/testlib/selftests/expected_benchliboptions.xunitxml delete mode 100644 tests/auto/testlib/selftests/expected_crashes.lightxml delete mode 100644 tests/auto/testlib/selftests/expected_crashes.xml delete mode 100644 tests/auto/testlib/selftests/expected_crashes.xunitxml delete mode 100644 tests/auto/testlib/selftests/expected_float.lightxml delete mode 100644 tests/auto/testlib/selftests/expected_float.xml delete mode 100644 tests/auto/testlib/selftests/expected_float.xunitxml delete mode 100644 tests/auto/testlib/selftests/expected_multiexec.lightxml delete mode 100644 tests/auto/testlib/selftests/expected_multiexec.xml delete mode 100644 tests/auto/testlib/selftests/expected_multiexec.xunitxml delete mode 100644 tests/auto/testlib/selftests/expected_sleep.lightxml delete mode 100644 tests/auto/testlib/selftests/expected_sleep.xml delete mode 100644 tests/auto/testlib/selftests/expected_sleep.xunitxml diff --git a/tests/auto/testlib/selftests/expected_benchlibcallgrind.lightxml b/tests/auto/testlib/selftests/expected_benchlibcallgrind.lightxml deleted file mode 100644 index c2394e545e8..00000000000 --- a/tests/auto/testlib/selftests/expected_benchlibcallgrind.lightxml +++ /dev/null @@ -1,14 +0,0 @@ - - @INSERT_QT_VERSION_HERE@ - @INSERT_QT_VERSION_HERE@ - - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/expected_benchlibcallgrind.xml b/tests/auto/testlib/selftests/expected_benchlibcallgrind.xml deleted file mode 100644 index b29b9c569ea..00000000000 --- a/tests/auto/testlib/selftests/expected_benchlibcallgrind.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - @INSERT_QT_VERSION_HERE@ - @INSERT_QT_VERSION_HERE@ - - - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/expected_benchlibcallgrind.xunitxml b/tests/auto/testlib/selftests/expected_benchlibcallgrind.xunitxml deleted file mode 100644 index cc58f7fdd45..00000000000 --- a/tests/auto/testlib/selftests/expected_benchlibcallgrind.xunitxml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/expected_benchliboptions.lightxml b/tests/auto/testlib/selftests/expected_benchliboptions.lightxml deleted file mode 100644 index 63d0218b2c1..00000000000 --- a/tests/auto/testlib/selftests/expected_benchliboptions.lightxml +++ /dev/null @@ -1,15 +0,0 @@ - - @INSERT_QT_VERSION_HERE@ - @INSERT_QT_VERSION_HERE@ - - - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/expected_benchliboptions.xml b/tests/auto/testlib/selftests/expected_benchliboptions.xml deleted file mode 100644 index 40bff95f798..00000000000 --- a/tests/auto/testlib/selftests/expected_benchliboptions.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - @INSERT_QT_VERSION_HERE@ - @INSERT_QT_VERSION_HERE@ - - - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/expected_benchliboptions.xunitxml b/tests/auto/testlib/selftests/expected_benchliboptions.xunitxml deleted file mode 100644 index 7317e90470d..00000000000 --- a/tests/auto/testlib/selftests/expected_benchliboptions.xunitxml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/expected_crashes.lightxml b/tests/auto/testlib/selftests/expected_crashes.lightxml deleted file mode 100644 index 76890deb75d..00000000000 --- a/tests/auto/testlib/selftests/expected_crashes.lightxml +++ /dev/null @@ -1,15 +0,0 @@ - - @INSERT_QT_VERSION_HERE@ - @INSERT_QT_VERSION_HERE@ - - - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/expected_crashes.xml b/tests/auto/testlib/selftests/expected_crashes.xml deleted file mode 100644 index be01e633e9e..00000000000 --- a/tests/auto/testlib/selftests/expected_crashes.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - @INSERT_QT_VERSION_HERE@ - @INSERT_QT_VERSION_HERE@ - - - - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/expected_crashes.xunitxml b/tests/auto/testlib/selftests/expected_crashes.xunitxml deleted file mode 100644 index 558491c5987..00000000000 --- a/tests/auto/testlib/selftests/expected_crashes.xunitxml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/expected_float.lightxml b/tests/auto/testlib/selftests/expected_float.lightxml deleted file mode 100644 index a34618cf02d..00000000000 --- a/tests/auto/testlib/selftests/expected_float.lightxml +++ /dev/null @@ -1,44 +0,0 @@ - - @INSERT_QT_VERSION_HERE@ - @INSERT_QT_VERSION_HERE@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/expected_float.xml b/tests/auto/testlib/selftests/expected_float.xml deleted file mode 100644 index a9c74282506..00000000000 --- a/tests/auto/testlib/selftests/expected_float.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - @INSERT_QT_VERSION_HERE@ - @INSERT_QT_VERSION_HERE@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/expected_float.xunitxml b/tests/auto/testlib/selftests/expected_float.xunitxml deleted file mode 100644 index f88e5e410e5..00000000000 --- a/tests/auto/testlib/selftests/expected_float.xunitxml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/expected_multiexec.lightxml b/tests/auto/testlib/selftests/expected_multiexec.lightxml deleted file mode 100644 index 1a66e92f8f9..00000000000 --- a/tests/auto/testlib/selftests/expected_multiexec.lightxml +++ /dev/null @@ -1,13 +0,0 @@ - - @INSERT_QT_VERSION_HERE@ - @INSERT_QT_VERSION_HERE@ - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/expected_multiexec.xml b/tests/auto/testlib/selftests/expected_multiexec.xml deleted file mode 100644 index 7f71f6edaca..00000000000 --- a/tests/auto/testlib/selftests/expected_multiexec.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - @INSERT_QT_VERSION_HERE@ - @INSERT_QT_VERSION_HERE@ - - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/expected_multiexec.xunitxml b/tests/auto/testlib/selftests/expected_multiexec.xunitxml deleted file mode 100644 index 6bc04c3ddda..00000000000 --- a/tests/auto/testlib/selftests/expected_multiexec.xunitxml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/expected_sleep.lightxml b/tests/auto/testlib/selftests/expected_sleep.lightxml deleted file mode 100644 index 1a056c85629..00000000000 --- a/tests/auto/testlib/selftests/expected_sleep.lightxml +++ /dev/null @@ -1,13 +0,0 @@ - - @INSERT_QT_VERSION_HERE@ - @INSERT_QT_VERSION_HERE@ - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/expected_sleep.xml b/tests/auto/testlib/selftests/expected_sleep.xml deleted file mode 100644 index cbc4d140048..00000000000 --- a/tests/auto/testlib/selftests/expected_sleep.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - @INSERT_QT_VERSION_HERE@ - @INSERT_QT_VERSION_HERE@ - - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/expected_sleep.xunitxml b/tests/auto/testlib/selftests/expected_sleep.xunitxml deleted file mode 100644 index 409621e6bc1..00000000000 --- a/tests/auto/testlib/selftests/expected_sleep.xunitxml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/tests/auto/testlib/selftests/selftests.qrc b/tests/auto/testlib/selftests/selftests.qrc index f882068f6de..d2f0a50824a 100644 --- a/tests/auto/testlib/selftests/selftests.qrc +++ b/tests/auto/testlib/selftests/selftests.qrc @@ -9,18 +9,12 @@ expected_badxml.txt expected_badxml.xml expected_badxml.xunitxml - expected_benchlibcallgrind.lightxml expected_benchlibcallgrind.txt - expected_benchlibcallgrind.xml - expected_benchlibcallgrind.xunitxml expected_benchlibeventcounter.lightxml expected_benchlibeventcounter.txt expected_benchlibeventcounter.xml expected_benchlibeventcounter.xunitxml - expected_benchliboptions.lightxml expected_benchliboptions.txt - expected_benchliboptions.xml - expected_benchliboptions.xunitxml expected_benchlibtickcounter.lightxml expected_benchlibtickcounter.txt expected_benchlibtickcounter.xml @@ -41,9 +35,6 @@ expected_counting.txt expected_counting.xml expected_counting.xunitxml - expected_crashes.lightxml - expected_crashes.xml - expected_crashes.xunitxml expected_crashes_1.txt expected_crashes_2.txt expected_crashes_3.txt @@ -81,10 +72,7 @@ expected_fetchbogus.txt expected_fetchbogus.xml expected_fetchbogus.xunitxml - expected_float.lightxml expected_float.txt - expected_float.xml - expected_float.xunitxml expected_globaldata.lightxml expected_globaldata.txt expected_globaldata.xml @@ -97,10 +85,7 @@ expected_maxwarnings.txt expected_maxwarnings.xml expected_maxwarnings.xunitxml - expected_multiexec.lightxml expected_multiexec.txt - expected_multiexec.xml - expected_multiexec.xunitxml expected_printdatatags.txt expected_printdatatagswithglobaltags.txt expected_qexecstringlist.txt @@ -124,10 +109,7 @@ expected_skipinitdata.txt expected_skipinitdata.xml expected_skipinitdata.xunitxml - expected_sleep.lightxml expected_sleep.txt - expected_sleep.xml - expected_sleep.xunitxml expected_strcmp.lightxml expected_strcmp.txt expected_strcmp.xml From 52744f505381c2840efbe1dc4858d422d32d9f32 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Fri, 3 Feb 2012 15:43:28 +1000 Subject: [PATCH 095/406] Improve float selftest Correct a bug in the test and use unique names for data rows. The bug was that the test assumed that QCOMPARE for float values 100001 and 100002 would fail, but it actually succeeds. QCOMPARE for floats uses qFuzzyCompare(), which succeeds if the numbers differ by no more than 1/100,000th of the smaller value. Thus QCOMPARE(100001, 100002) passes, while QCOMPARE(99998, 99999) fails. Change-Id: Ia35d3126c2e3ebe91d64daa309048514a365d9fb Reviewed-by: Rohan McGovern --- tests/auto/testlib/selftests/expected_float.txt | 16 ++++++++++------ .../auto/testlib/selftests/float/tst_float.cpp | 17 +++++++++++++---- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/tests/auto/testlib/selftests/expected_float.txt b/tests/auto/testlib/selftests/expected_float.txt index acd0aaa54ae..81e4d7b067b 100644 --- a/tests/auto/testlib/selftests/expected_float.txt +++ b/tests/auto/testlib/selftests/expected_float.txt @@ -1,26 +1,30 @@ ********* Start testing of tst_float ********* Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ PASS : tst_float::initTestCase() -FAIL! : tst_float::floatComparisons(should FAIL) Compared floats are not the same (fuzzy compare) +FAIL! : tst_float::floatComparisons(should FAIL 1) Compared floats are not the same (fuzzy compare) Actual (operandLeft): 1 Expected (operandRight): 3 Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(61)] -FAIL! : tst_float::floatComparisons(should FAIL) Compared floats are not the same (fuzzy compare) +FAIL! : tst_float::floatComparisons(should FAIL 2) Compared floats are not the same (fuzzy compare) Actual (operandLeft): 1e-07 Expected (operandRight): 3e-07 Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(61)] +FAIL! : tst_float::floatComparisons(should FAIL 3) Compared floats are not the same (fuzzy compare) + Actual (operandLeft): 99998 + Expected (operandRight): 99999 + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(61)] FAIL! : tst_float::compareFloatTests(1e0) Compared floats are not the same (fuzzy compare) Actual (t1): 1 Expected (t3): 3 - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(100)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(104)] FAIL! : tst_float::compareFloatTests(1e-7) Compared floats are not the same (fuzzy compare) Actual (t1): 1e-07 Expected (t3): 3e-07 - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(100)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(104)] FAIL! : tst_float::compareFloatTests(1e+7) Compared floats are not the same (fuzzy compare) Actual (t1): 1e+07 Expected (t3): 3e+07 - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(100)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(104)] PASS : tst_float::cleanupTestCase() -Totals: 2 passed, 5 failed, 0 skipped +Totals: 2 passed, 6 failed, 0 skipped ********* Finished testing of tst_float ********* diff --git a/tests/auto/testlib/selftests/float/tst_float.cpp b/tests/auto/testlib/selftests/float/tst_float.cpp index 9b7865ed25a..fb10521604a 100644 --- a/tests/auto/testlib/selftests/float/tst_float.cpp +++ b/tests/auto/testlib/selftests/float/tst_float.cpp @@ -66,19 +66,28 @@ void tst_float::floatComparisons_data() const QTest::addColumn("operandLeft"); QTest::addColumn("operandRight"); - QTest::newRow("should SUCCEED") + QTest::newRow("should SUCCEED 1") << float(0) << float(0); - QTest::newRow("should FAIL") + QTest::newRow("should FAIL 1") << float(1.00000) << float(3.00000); - QTest::newRow("should FAIL") + QTest::newRow("should FAIL 2") << float(1.00000e-7f) << float(3.00000e-7f); - QTest::newRow("should FAIL") + // QCOMPARE for floats uses qFuzzyCompare(), which succeeds if the numbers + // differ by no more than 1/100,000th of the smaller value. Thus + // QCOMPARE(99998, 99999) should fail, while QCOMPARE(100001, 100002) + // should pass. + + QTest::newRow("should FAIL 3") + << float(99998) + << float(99999); + + QTest::newRow("should SUCCEED 2") << float(100001) << float(100002); } From 1fe0a4cc68e5e199961cf3a5d920b6bf8004940c Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Fri, 3 Feb 2012 15:56:26 +1000 Subject: [PATCH 096/406] Make selftest.pri more readable/maintainable. Change-Id: Ic5a74beebb718df4cce5a9b02cdfd6f6d4cec97d Reviewed-by: Rohan McGovern --- tests/auto/testlib/selftests/selftests.pri | 48 ++++++++++++++++++---- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/tests/auto/testlib/selftests/selftests.pri b/tests/auto/testlib/selftests/selftests.pri index 9d4b2bd600f..2297186f62b 100644 --- a/tests/auto/testlib/selftests/selftests.pri +++ b/tests/auto/testlib/selftests/selftests.pri @@ -1,7 +1,41 @@ -SUBPROGRAMS = subtest warnings maxwarnings cmptest globaldata skip \ - strcmp expectfail sleep fetchbogus crashes multiexec failinit failinitdata \ - skipinit skipinitdata datetime singleskip assert differentexec \ - exceptionthrow qexecstringlist datatable commandlinedata\ - benchlibwalltime benchlibcallgrind benchlibeventcounter benchlibtickcounter \ - benchliboptions xunit badxml longstring float printdatatags \ - printdatatagswithglobaltags findtestdata counting skipcleanup failcleanup +SUBPROGRAMS = \ + #alive \ + assert \ + badxml \ + benchlibcallgrind \ + benchlibeventcounter \ + benchliboptions \ + benchlibtickcounter \ + benchlibwalltime \ + cmptest \ + commandlinedata \ + counting \ + crashes \ + datatable \ + datetime \ + differentexec \ + exceptionthrow \ + expectfail \ + failcleanup \ + failinit \ + failinitdata \ + fetchbogus \ + findtestdata \ + float \ + globaldata \ + longstring \ + maxwarnings \ + multiexec \ + printdatatags \ + printdatatagswithglobaltags \ + qexecstringlist \ + singleskip \ + skip \ + skipcleanup \ + skipinit \ + skipinitdata \ + sleep \ + strcmp \ + subtest \ + warnings \ + xunit From 2ba0700ebffabb6d89595724ef7efe5baf230928 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 1 Feb 2012 12:58:31 +0100 Subject: [PATCH 097/406] Update note about metatype fully defined requirement. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is now public API to re-allow forward declared types as metatypes. Change-Id: I6c956ea2dc96f66eccfcfa81fcbb833b58b58d61 Reviewed-by: João Abecasis Reviewed-by: Jonas Gastal --- dist/changes-5.0.0 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index c62d8b11636..d2e8dde9de2 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -124,8 +124,9 @@ information about a particular change. - QMetaType - * It is no longer possible to use Q_DECLARE_METATYPE(Foo*) where Foo is only - forward declared - it must be fully defined. + * Q_DECLARE_METATYPE(Foo*) now requires that Foo is fully defined. In + cases where a forward declared type should be used as a metatype, + Q_DECLARE_OPAQUE_POINTER(Foo*) can be used to allow that. - QItemEditorFactory From 7f403f368eac8a0ebba83a1c30e83ff0a3963acb Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Thu, 9 Feb 2012 10:36:08 +1000 Subject: [PATCH 098/406] Fixed qfile unittest rename() failing as root When run as root was able to move file to /etc directory but was expecting a failure. Change-Id: Ic2ac5506253f2a3395ed56e88a856542bf82ad6d Reviewed-by: Rohan McGovern Reviewed-by: Jason McDonald --- tests/auto/corelib/io/qfile/tst_qfile.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 67a4f71f540..0ed1b8ed5a3 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -2349,6 +2349,13 @@ void tst_QFile::rename() QFETCH(QString, destination); QFETCH(bool, result); +#if defined(Q_OS_UNIX) + if (strcmp(QTest::currentDataTag(), "renamefile -> /etc/renamefile") == 0) { + if (::getuid() == 0) + QSKIP("Running this test as root doesn't make sense"); + } +#endif + QFile::remove("renamedfile"); QFile f("renamefile"); f.open(QFile::WriteOnly); From 951c0b7afa2538037795644bf9759d0574ef99fd Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Thu, 9 Feb 2012 11:15:32 +1000 Subject: [PATCH 099/406] Fixed qdir unittest to handle being run as root - Added checks to see if running as root and skip as needed Change-Id: I4f94d5bfe511c6dfda315854b7cd1f64efe6e4f4 Reviewed-by: Rohan McGovern Reviewed-by: Jason McDonald --- tests/auto/corelib/io/qdir/tst_qdir.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp index 539bea5e8d3..6a48d7e60fa 100644 --- a/tests/auto/corelib/io/qdir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp @@ -385,6 +385,10 @@ void tst_QDir::removeRecursively() void tst_QDir::removeRecursivelyFailure() { +#ifdef Q_OS_UNIX + if (::getuid() == 0) + QSKIP("Running this test as root doesn't make sense"); +#endif const QString tmpdir = QDir::currentPath() + "/tmpdir/"; const QString path = tmpdir + "undeletable"; QDir().mkpath(path); @@ -1932,6 +1936,10 @@ void tst_QDir::isRelative() void tst_QDir::isReadable() { +#ifdef Q_OS_UNIX + if (::getuid() == 0) + QSKIP("Running this test as root doesn't make sense"); +#endif QDir dir; QVERIFY(dir.isReadable()); @@ -1961,7 +1969,10 @@ void tst_QDir::cdBelowRoot() QCOMPARE(root.path(), ROOT); QVERIFY(root.cd(CD_INTO)); QCOMPARE(root.path(), DIR); - +#ifdef Q_OS_UNIX + if (::getuid() == 0) + QSKIP("Running this test as root doesn't make sense"); +#endif QDir dir(DIR); QVERIFY(!dir.cd("../..")); QCOMPARE(dir.path(), DIR); From 805d8959787ba03a35436e1235648d01bdfd91c7 Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Thu, 9 Feb 2012 11:27:15 +1000 Subject: [PATCH 100/406] Fixed qstandardpaths unittest to handle being run as root - testCustomRuntimeDirectory test skips if run as root Change-Id: Idcc2a1db5d8a96b2ec0248b8b1c392fffc0b2e11 Reviewed-by: Jason McDonald --- tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index 1e288e24186..ebfd640dfb4 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -229,6 +229,11 @@ void tst_qstandardpaths::testRuntimeDirectory() void tst_qstandardpaths::testCustomRuntimeDirectory() { +#if defined(Q_OS_UNIX) + if (::getuid() == 0) + QSKIP("Running this test as root doesn't make sense"); +#endif + #ifdef Q_XDG_PLATFORM qputenv("XDG_RUNTIME_DIR", QFile::encodeName("/tmp")); // It's very unlikely that /tmp is 0600 or that we can chmod it From 76804c842f838f4f53e25be1aab9bcb46ff8ce46 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Wed, 8 Feb 2012 10:52:01 +0100 Subject: [PATCH 101/406] Don't link shell32 for Windows CE. Windows CE normally don't come with a shell32, so its better to don't use it. Change-Id: I7198b5fadb0dfe37d1321800371110b7b407f577 Reviewed-by: Miikka Heikkinen Reviewed-by: Friedemann Kleint --- src/widgets/kernel/win.pri | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/win.pri b/src/widgets/kernel/win.pri index 4288e09ecb3..dd47664c286 100644 --- a/src/widgets/kernel/win.pri +++ b/src/widgets/kernel/win.pri @@ -2,4 +2,6 @@ # -------------------------------------------------------------------- INCLUDEPATH += ../3rdparty/wintab -LIBS *= -lshell32 +!wince* { + LIBS *= -lshell32 +} From 40afbf3deb4a0d8823a3307286a35bd046c44e01 Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Wed, 8 Feb 2012 00:40:51 +0100 Subject: [PATCH 102/406] QSqlTableModel::insertRecord(): correct documentation Change-Id: I35680f842a650493cf530c0b74894e2b45aa3c6e Reviewed-by: Yunqiao Yin --- src/sql/models/qsqltablemodel.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 437712d83ec..dd4629662bd 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -1062,11 +1062,11 @@ bool QSqlTableModel::insertRows(int row, int count, const QModelIndex &parent) } /*! - Inserts the \a record after \a row. If \a row is negative, the - record will be appended to the end. Calls insertRows() and + Inserts the \a record at position \a row. If \a row is negative, + the record will be appended to the end. Calls insertRows() and setRecord() internally. - Returns true if the row could be inserted, otherwise false. + Returns true if the record could be inserted, otherwise false. \sa insertRows(), removeRows() */ From a58e630b61c19eac8f0c0d931825b42eeb7ea16b Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Wed, 8 Feb 2012 00:16:46 +0100 Subject: [PATCH 103/406] QSqlTableModel::setRecord(): improve handling of field mapping -Only use fields where generated flag is set to true. -Require all fields to map correctly. If fields don't map, that is a sign of a programming or user error. Change-Id: Ie8474393005de6c9926b4e46985d62b194eafde2 Reviewed-by: Yunqiao Yin --- dist/changes-5.0.0 | 5 +++++ src/sql/models/qsqltablemodel.cpp | 34 ++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index d2e8dde9de2..996bdf4b0b1 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -350,6 +350,11 @@ model methods setData() or setRecord(). before doing anything. Previously, it would remove what it could and ignore the rest of the range. +* setRecord() and insertRecord() + -Only use fields where generated flag is set to true. This is + is consistent with the meaning of the flag. + -Require all fields to map correctly. Previously fields that didn't + map were simply ignored. **************************************************************************** * Database Drivers * diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index dd4629662bd..9e1cfe3051e 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -1066,6 +1066,8 @@ bool QSqlTableModel::insertRows(int row, int count, const QModelIndex &parent) the record will be appended to the end. Calls insertRows() and setRecord() internally. + Only fields where the generated flag is true will be included. + Returns true if the record could be inserted, otherwise false. \sa insertRows(), removeRows() @@ -1183,8 +1185,10 @@ Qt::ItemFlags QSqlTableModel::flags(const QModelIndex &index) const /*! Sets the values at the specified \a row to the values of \a - record. Returns true if all the values could be set; otherwise - returns false. + record for fields where generated flag is true. + + Returns true if all the values could be set; otherwise returns + false. \sa record() */ @@ -1203,28 +1207,34 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record) else if (d->strategy == OnRowChange && !d->cache.isEmpty() && !d->cache.contains(row)) submit(); + // Check field names and remember mapping + typedef QMap Map; + Map map; + for (int i = 0; i < record.count(); ++i) { + if (record.isGenerated(i)) { + int idx = d->nameToIndex(record.fieldName(i)); + if (idx == -1) + return false; + map[i] = idx; + } + } + QSqlTableModelPrivate::ModifiedRow &mrow = d->cache[row]; if (mrow.op() == QSqlTableModelPrivate::None) mrow = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Update, d->rec, d->primaryValues(indexInQuery(createIndex(row, 0)).row())); - bool isOk = true; - for (int i = 0; i < record.count(); ++i) { - int idx = d->nameToIndex(record.fieldName(i)); - if (idx == -1) - isOk = false; - else - mrow.setValue(idx, record.value(i)); - } + Map::const_iterator i = map.constBegin(); + const Map::const_iterator e = map.constEnd(); + for ( ; i != e; ++i) + mrow.setValue(i.value(), record.value(i.key())); if (columnCount()) emit dataChanged(createIndex(row, 0), createIndex(row, columnCount() - 1)); if (d->strategy == OnFieldChange) return submit(); - else if (d->strategy == OnManualSubmit) - return isOk; return true; } From 9c99f23ffb1666dae34f0a3aa0182f43de8e7d0c Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Wed, 8 Feb 2012 16:04:34 +0100 Subject: [PATCH 104/406] Remove leftover show() prototype. In Qt4.8 this was declared in qwidget_wince.cpp. It was for auto maximizing. This would need to go into lighthouse if needed. This fixes the Windows CE compile. Change-Id: I6fe8361f745e16d9e8053ab58eb76ead0b22d261 Reviewed-by: Miikka Heikkinen Reviewed-by: Thiago Macieira Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qwidget.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index 2bad2e9f1e6..0594fd6f50f 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -481,11 +481,7 @@ public Q_SLOTS: virtual void setVisible(bool visible); inline void setHidden(bool hidden) { setVisible(!hidden); } -#ifndef Q_OS_WINCE inline void show() { setVisible(true); } -#else - void show(); -#endif inline void hide() { setVisible(false); } void showMinimized(); From 68cee5258b3db95aaf98c456a257863a2ef7ba14 Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Wed, 8 Feb 2012 00:45:47 +0100 Subject: [PATCH 105/406] QSqlTableModel::insertRecord(): clean up after failed setRecord() Change-Id: Ic9f314144bd3ccf4b59b9cb3f0d79f8d6f97a824 Reviewed-by: Yunqiao Yin --- dist/changes-5.0.0 | 2 ++ src/sql/models/qsqltablemodel.cpp | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index 996bdf4b0b1..7726843ccb4 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -355,6 +355,8 @@ ignore the rest of the range. is consistent with the meaning of the flag. -Require all fields to map correctly. Previously fields that didn't map were simply ignored. + -For OnManualSubmit, insertRecord() no longer leaves behind an empty + row if setRecord() fails. **************************************************************************** * Database Drivers * diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 9e1cfe3051e..35346c0f835 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -1079,8 +1079,11 @@ bool QSqlTableModel::insertRecord(int row, const QSqlRecord &record) row = rowCount(); if (!insertRow(row, QModelIndex())) return false; - if (!setRecord(row, record)) + if (!setRecord(row, record)) { + if (d->strategy == OnManualSubmit) + revertRow(row); return false; + } if (d->strategy == OnFieldChange || d->strategy == OnRowChange) return submit(); return true; From adfca27ac09cfd87121bb3611d74a75136ea6498 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 8 Feb 2012 16:56:38 +1000 Subject: [PATCH 106/406] Fixed tst_qobject::property for clang MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test was failing at: QCOMPARE(property.userType(), qMetaTypeId()); The CustomType* metatype was not registered before this part of the test. qMetaTypeId will register the metatype for T before returning it if it is not yet registered, while QMetaProperty::userType() returns 0 if the metatype is not yet registered. However, the order of evaluation of these two expressions in the above statement is technically undefined. Apparently, gcc evaluates the arguments in order from right to left, allowing the test to pass, while clang evaluates the arguments in order from left to right, causing the test to fail. Change-Id: I5059556e860cec29b57c31e4e26f46cf9e6055da Reviewed-by: Jędrzej Nowacki --- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 4e7935be312..91b93e4ccd1 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -1703,6 +1703,7 @@ void tst_QObject::property() QVERIFY(property.isWritable()); QVERIFY(!property.isEnumType()); QCOMPARE(property.typeName(), "CustomType*"); + qRegisterMetaType(); QCOMPARE(property.type(), QVariant::UserType); QCOMPARE(property.userType(), qMetaTypeId()); From ef7fd678457496abc0b2d204c816b10a57816907 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Thu, 9 Feb 2012 09:55:09 +0100 Subject: [PATCH 107/406] Replace Q_WS_WINCE against Q_OS_WINCE. Window system Macros where deprecated so use Q_OS_WINCE for now. This code will need some refactoring, but this is the first step to it. Change-Id: I5876b80ee45d4b38ac63fc7d51e775dc70bbd485 Reviewed-by: Friedemann Kleint --- src/widgets/dialogs/qfiledialog.cpp | 2 +- src/widgets/itemviews/qfileiconprovider.cpp | 2 +- .../auto/network/access/qnetworkreply/tst_qnetworkreply.cpp | 2 +- tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp | 2 +- .../qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp | 2 +- tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp | 2 +- tests/benchmarks/corelib/io/qfile/main.cpp | 2 +- .../benchmarks/corelib/tools/containers-sequential/main.cpp | 2 +- .../gui/graphicsview/qgraphicsview/tst_qgraphicsview.cpp | 2 +- .../network/access/qnetworkreply/tst_qnetworkreply.cpp | 6 +++--- .../benchmarks/network/socket/qtcpserver/tst_qtcpserver.cpp | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index ecedf8328f1..ed5264159f4 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -59,7 +59,7 @@ #include #include #include -#if !defined(Q_WS_WINCE) +#if !defined(Q_OS_WINCE) #include "ui_qfiledialog.h" #else #define Q_EMBEDDED_SMALLSCREEN diff --git a/src/widgets/itemviews/qfileiconprovider.cpp b/src/widgets/itemviews/qfileiconprovider.cpp index dd52aebea59..6b5478b6caf 100644 --- a/src/widgets/itemviews/qfileiconprovider.cpp +++ b/src/widgets/itemviews/qfileiconprovider.cpp @@ -429,7 +429,7 @@ QIcon QFileIconProvider::icon(const QFileInfo &info) const return icon; #endif if (info.isRoot()) -#if defined (Q_OS_WIN) && !defined(Q_WS_WINCE) +#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) { UINT type = GetDriveType((wchar_t *)info.absoluteFilePath().utf16()); diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 44cafe4de90..0e9136dbc79 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -5850,7 +5850,7 @@ void tst_QNetworkReply::getFromHttpIntoBuffer2() QFETCH(bool, useDownloadBuffer); // On my Linux Desktop the results are already visible with 128 kB, however we use this to have good results. -#if defined(Q_WS_WINCE_WM) +#if defined(Q_OS_WINCE_WM) // Show some mercy to non-desktop platform/s enum {UploadSize = 4*1024*1024}; // 4 MB #else diff --git a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp index b332fb40f8e..e46d9050224 100644 --- a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp +++ b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp @@ -440,7 +440,7 @@ public slots: void tst_QDialog::throwInExec() { -#if defined(Q_OS_MAC) || (defined(Q_WS_WINCE) && defined(_ARM_)) +#if defined(Q_OS_MAC) || (defined(Q_OS_WINCE) && defined(_ARM_)) QSKIP("Throwing exceptions in exec() is not supported on this platform."); #endif #if defined(Q_OS_LINUX) diff --git a/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp b/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp index c30701e0f96..35b67d4451b 100644 --- a/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp @@ -152,7 +152,7 @@ void tst_QGraphicsLinearLayout::initTestCase() { // since the style will influence the results, we have to ensure // that the tests are run using the same style on all platforms -#if defined (Q_WS_WINCE) +#if defined (Q_OS_WINCE) QApplication::setStyle(new QWindowsStyle); #else QApplication::setStyle(new QPlastiqueStyle); diff --git a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp index 33b7ade7155..13540355c75 100644 --- a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp +++ b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp @@ -538,7 +538,7 @@ void tst_QMainWindow::menuBar() mw.setMenuBar(mb1); QVERIFY(mw.menuBar() != 0); QCOMPARE(mw.menuBar(), (QMenuBar *)mb1); -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM QSKIP("With native menubar integration the menubar is not a child"); #endif QCOMPARE(mb1->parentWidget(), (QWidget *)&mw); diff --git a/tests/benchmarks/corelib/io/qfile/main.cpp b/tests/benchmarks/corelib/io/qfile/main.cpp index 92edd430601..3d16921b7f3 100644 --- a/tests/benchmarks/corelib/io/qfile/main.cpp +++ b/tests/benchmarks/corelib/io/qfile/main.cpp @@ -542,7 +542,7 @@ void tst_qfile::createSmallFiles() dir.cd("tst"); tmpDirName = dir.absolutePath(); -#if defined(Q_WS_WINCE) +#if defined(Q_OS_WINCE) for (int i = 0; i < 100; ++i) #else for (int i = 0; i < 1000; ++i) diff --git a/tests/benchmarks/corelib/tools/containers-sequential/main.cpp b/tests/benchmarks/corelib/tools/containers-sequential/main.cpp index ee13a63a570..e42a40b110d 100644 --- a/tests/benchmarks/corelib/tools/containers-sequential/main.cpp +++ b/tests/benchmarks/corelib/tools/containers-sequential/main.cpp @@ -133,7 +133,7 @@ struct Large { // A "large" item type }; // Embedded devices typically have limited memory -#if defined(Q_WS_WINCE) +#if defined(Q_OS_WINCE) # define LARGE_MAX_SIZE 2000 #else # define LARGE_MAX_SIZE 20000 diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsview/tst_qgraphicsview.cpp index cc549f835d3..8eef993c06e 100644 --- a/tests/benchmarks/gui/graphicsview/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/tst_qgraphicsview.cpp @@ -414,7 +414,7 @@ void tst_QGraphicsView::chipTester_data() void tst_QGraphicsView::chipTester() { -#ifdef Q_WS_WINCE_WM +#ifdef Q_OS_WINCE_WM QSKIP("WinCE WM: Fails on Windows Mobile w/o OpenGL"); #endif QFETCH(bool, antialias); diff --git a/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp index e48172da89e..829bba5c5df 100644 --- a/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -565,7 +565,7 @@ void tst_qnetworkreply::uploadPerformance() void tst_qnetworkreply::httpUploadPerformance() { -#if defined(Q_WS_WINCE_WM) +#if defined(Q_OS_WINCE_WM) // Show some mercy for non-desktop platform/s enum {UploadSize = 4*1024*1024}; // 4 MB #else @@ -636,7 +636,7 @@ void tst_qnetworkreply::httpDownloadPerformance() { QFETCH(bool, serverSendsContentLength); QFETCH(bool, chunkedEncoding); -#if defined(Q_WS_WINCE_WM) +#if defined(Q_OS_WINCE_WM) // Show some mercy to non-desktop platform/s enum {UploadSize = 4*1024*1024}; // 4 MB #else @@ -720,7 +720,7 @@ void tst_qnetworkreply::httpDownloadPerformanceDownloadBuffer() QFETCH(HttpDownloadPerformanceDownloadBufferTestType, testType); // On my Linux Desktop the results are already visible with 128 kB, however we use this to have good results. -#if defined(Q_WS_WINCE_WM) +#if defined(Q_OS_WINCE_WM) // Show some mercy to non-desktop platform/s enum {UploadSize = 4*1024*1024}; // 4 MB #else diff --git a/tests/benchmarks/network/socket/qtcpserver/tst_qtcpserver.cpp b/tests/benchmarks/network/socket/qtcpserver/tst_qtcpserver.cpp index ea923a7fd0c..2bb23e5781f 100644 --- a/tests/benchmarks/network/socket/qtcpserver/tst_qtcpserver.cpp +++ b/tests/benchmarks/network/socket/qtcpserver/tst_qtcpserver.cpp @@ -173,7 +173,7 @@ void tst_QTcpServer::ipv6LoopbackPerformanceTest() QFETCH_GLOBAL(bool, setProxy); if (setProxy) return; -#if defined(Q_WS_WINCE_WM) +#if defined(Q_OS_WINCE_WM) QSKIP("WinCE WM: Not yet supported"); #endif From 3e720809b0313ba1d3e51e29e951604971946935 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Mon, 6 Feb 2012 13:05:21 +0100 Subject: [PATCH 108/406] Eliminate a warning Change-Id: I984821d90df272b85d02c6ee0db5a89174d80873 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qtextlayout.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index ac92c4dd516..84d3fce518e 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2124,8 +2124,8 @@ static QGlyphRun glyphRunWithInfo(QFontEngine *fontEngine, const QGlyphLayout &g Q_ASSERT(glyphsArray.size() == positionsArray.size()); qreal fontHeight = font.ascent() + font.descent(); - qreal minY; - qreal maxY; + qreal minY = 0; + qreal maxY = 0; QVector glyphs; QVector positions; for (int i=0; i Date: Wed, 8 Feb 2012 15:03:34 +1000 Subject: [PATCH 109/406] Fixed tst_qfileinfo::group crash if getgrgid fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QVERIFY2 and gracefully fail with an error message, rather than crashing, if getgrgid() fails. Change-Id: I82a7290f83208486577988cc831d5d3cba20f98e Reviewed-by: João Abecasis --- tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp index 7b80152b624..a3d80cb66f3 100644 --- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp @@ -1722,7 +1722,13 @@ void tst_QFileInfo::group() #if defined(Q_OS_UNIX) struct group *gr; gid_t gid = getegid(); + + errno = 0; gr = getgrgid(gid); + + QVERIFY2(gr, qPrintable( + QString("getgrgid returned 0: %1, cannot determine my own group") + .arg(QString::fromLocal8Bit(strerror(errno))))); expected = QString::fromLocal8Bit(gr->gr_name); #endif From 651016020f9ac996f2aac50e2d30505bdffe2331 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Tue, 7 Feb 2012 15:48:51 +0100 Subject: [PATCH 110/406] Take into account shaping in findRealWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It can happen that there is a window covering all the screen but it is shaped to only take part of the screen. If that happens, besides the condition of QRect(attr.x,attr.y,attr.width,attr.height).contains(pos) we also need to query the server for its region rectangles and make sure the cursor is inside one of those rectangles. If that does not happen we have to return 0 so the hierarchical xcb_query_tree_children xcb_query_tree_childrenntinues Change-Id: I67327672e3d854d064190b55a07bd56ade4dfddb Reviewed-by: Lars Knoll Reviewed-by: Uli Schlachter Reviewed-by: Samuel Rødal --- src/plugins/platforms/xcb/qxcbdrag.cpp | 28 +++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index a05fc780bcf..e928fe2d0a7 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -234,6 +234,7 @@ xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(xcb_connection(), w); xcb_get_geometry_reply_t *greply = xcb_get_geometry_reply(xcb_connection(), gcookie, 0); if (reply && QRect(greply->x, greply->y, greply->width, greply->height).contains(pos)) { + bool windowContainsMouse = true; { xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(xcb_connection(), false, w, connection()->atom(QXcbAtom::XdndAware), @@ -242,8 +243,26 @@ xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md bool isAware = reply && reply->type != XCB_NONE; free(reply); - if (isAware) - return w; + if (isAware) { + xcb_xfixes_region_t region = xcb_generate_id(xcb_connection()); + xcb_xfixes_create_region_from_window(xcb_connection(), region, w, XCB_SHAPE_SK_BOUNDING); + xcb_xfixes_fetch_region_reply_t *reply = xcb_xfixes_fetch_region_reply(xcb_connection(), xcb_xfixes_fetch_region(xcb_connection(), region), NULL); + if (reply) { + xcb_rectangle_t *rectangles = xcb_xfixes_fetch_region_rectangles(reply); + if (rectangles) { + windowContainsMouse = false; + const int nRectangles = xcb_xfixes_fetch_region_rectangles_length(reply); + for (int i = 0; !windowContainsMouse && i < nRectangles; ++i) { + windowContainsMouse = QRect(rectangles[i].x, rectangles[i].y, rectangles[i].width, rectangles[i].height).contains(pos); + } + } + free(reply); + } + xcb_xfixes_destroy_region(xcb_connection(), region); + + if (windowContainsMouse) + return w; + } } xcb_query_tree_cookie_t cookie = xcb_query_tree (xcb_connection(), w); @@ -266,7 +285,10 @@ xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md // innermost window. // No children! - return w; + if (!windowContainsMouse) + return 0; + else + return w; } } return 0; From 7aca5aa910f610239c7d33696003d100e558d45a Mon Sep 17 00:00:00 2001 From: Teemu Katajisto Date: Wed, 8 Feb 2012 13:42:41 +0200 Subject: [PATCH 111/406] Various documentation fixes ported from 4.8 Selected documentation fixes for qtbase from 4.8 commit 40fb4750910e23d3e7128ca8e0f1c5920b05bd5a Task-number: QTBUG-8625 Task-number: QTBUG-19808 Task-number: QTBUG-1231 Task-number: QTBUG-21073 Task-number: QTBUG-8939 Task-number: QTBUG-20399 Task-number: QTBUG-20944 Task-number: QTBUG-22095 Task-number: QTBUG-11278 Task-number: QTBUG-15653 Change-Id: Ia4f59fce7c85f04b6da953a3988f705d9d9a658a Reviewed-by: Casper van Donderen --- .../code/src_corelib_kernel_qmetatype.cpp | 2 +- doc/src/snippets/sqldatabase/sqldatabase.cpp | 2 +- src/corelib/global/qnamespace.qdoc | 2 +- src/corelib/io/qurl.cpp | 1 + .../kernel/qabstracteventdispatcher.cpp | 4 +-- src/corelib/kernel/qmetaobject.cpp | 25 ++++++++++++++++++- src/corelib/kernel/qobject.cpp | 2 +- src/corelib/tools/qlocale.qdoc | 1 - src/corelib/tools/qregexp.cpp | 2 +- src/widgets/graphicsview/qgraphicsitem.cpp | 6 ++--- src/widgets/graphicsview/qgraphicslayout.cpp | 4 +++ src/xml/dom/qdom.cpp | 2 +- 12 files changed, 40 insertions(+), 13 deletions(-) diff --git a/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp b/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp index b1e5df90019..9d72c425045 100644 --- a/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp +++ b/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp @@ -73,7 +73,7 @@ MyStruct s2 = var.value(); //! [3] int id = QMetaType::type("MyClass"); -if (id == 0) { +if (id != 0) { void *myClassPtr = QMetaType::create(id); ... QMetaType::destroy(id, myClassPtr); diff --git a/doc/src/snippets/sqldatabase/sqldatabase.cpp b/doc/src/snippets/sqldatabase/sqldatabase.cpp index 305c79e6ea3..81f806309af 100644 --- a/doc/src/snippets/sqldatabase/sqldatabase.cpp +++ b/doc/src/snippets/sqldatabase/sqldatabase.cpp @@ -284,12 +284,12 @@ void QSqlTableModel_snippets() model->setTable("employee"); model->setEditStrategy(QSqlTableModel::OnManualSubmit); model->select(); - model->removeColumn(0); // don't show the ID model->setHeaderData(0, Qt::Horizontal, tr("Name")); model->setHeaderData(1, Qt::Horizontal, tr("Salary")); QTableView *view = new QTableView; view->setModel(model); + view->hideColumn(0); // don't show the ID view->show(); //! [24] diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index ae395a2dfa5..da7bcb714a5 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -510,7 +510,7 @@ When using signals and slots with multiple threads, see \l{Signals and Slots Across Threads}. - \sa {Thread Support in Qt}, QObject::connect(), qRegisterMetaType() + \sa {Thread Support in Qt}, QObject::connect(), qRegisterMetaType(), Q_DECLARE_METATYPE() */ /*! diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index d74e7b81214..ecd154b1132 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -4176,6 +4176,7 @@ QString QUrlPrivate::createErrorString() Constructs a URL by parsing \a url. \a url is assumed to be in human readable representation, with no percent encoding. QUrl will automatically percent encode all characters that are not allowed in a URL. + The default parsing mode is TolerantMode. The parsing mode \a parsingMode is used for parsing \a url. diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index 31a46ad7446..0348faf1f21 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -135,8 +135,8 @@ void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId) QAbstractEventDispatcher also allows the integration of an external event loop with the Qt event loop. For example, the - \l{Qt Solutions}{Motif Extension Qt Solution} includes a - reimplementation of QAbstractEventDispatcher that merges Qt and + \l{Motif Extension} + includes a reimplementation of QAbstractEventDispatcher that merges Qt and Motif events together. \sa QEventLoop, QCoreApplication, QThread diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 7975fc26288..5ffa2d81dd8 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1353,7 +1353,30 @@ const char *QMetaMethod::typeName() const Returns the tag associated with this method. Tags are special macros recognized by \c moc that make it - possible to add extra information about a method. For the moment, + possible to add extra information about a method. + + Tag information can be added in the following + way in the function declaration: + + \code + #define THISISTESTTAG // tag text + ... + private slots: + THISISTESTTAG void testFunc(); + \endcode + + and the information can be accessed by using: + + \code + MainWindow win; + win.show(); + + int functionIndex = win.metaObject()->indexOfSlot("testFunc()"); + QMetaMethod mm = metaObject()->method(functionIndex); + qDebug() << mm.tag(); // prints THISISTESTTAG + \endcode + + For the moment, \c moc doesn't support any special tags. */ const char *QMetaMethod::tag() const diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 43773554863..252a7138726 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2247,7 +2247,7 @@ static inline void check_and_warn_compat(const QMetaObject *sender, const QMetaM call qRegisterMetaType() to register the data type before you establish the connection. - \sa disconnect(), sender(), qRegisterMetaType() + \sa disconnect(), sender(), qRegisterMetaType(), Q_DECLARE_METATYPE() */ QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/tools/qlocale.qdoc index cc335a45755..2fff58333d9 100644 --- a/src/corelib/tools/qlocale.qdoc +++ b/src/corelib/tools/qlocale.qdoc @@ -595,7 +595,6 @@ \value Yugoslavia \value Zambia \value Zimbabwe - \value SerbiaAndMontenegro \value Montenegro \value Serbia \value SaintBarthelemy diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp index 421d15c436a..054ec1d9f8d 100644 --- a/src/corelib/tools/qregexp.cpp +++ b/src/corelib/tools/qregexp.cpp @@ -426,7 +426,7 @@ int qFindString(const QChar *haystack, int haystackLen, int from, For historical reasons, quantifiers (e.g. \bold{*}) that apply to capturing parentheses are more "greedy" than other quantifiers. - For example, \bold{a*(a)*} will match "aaa" with cap(1) == "aaa". + For example, \bold{a*(a*)} will match "aaa" with cap(1) == "aaa". This behavior is different from what other regexp engines do (notably, Perl). To obtain a more intuitive capturing behavior, specify QRegExp::RegExp2 to the QRegExp constructor or call diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp index ba3b4962e7b..ab03ff7a9e2 100644 --- a/src/widgets/graphicsview/qgraphicsitem.cpp +++ b/src/widgets/graphicsview/qgraphicsitem.cpp @@ -11064,9 +11064,9 @@ QGraphicsItemGroup::~QGraphicsItemGroup() } /*! - Adds the given \a item to this item group. The item will be - reparented to this group, but its position and transformation - relative to the scene will stay intact. + Adds the given \a item and item's child items to this item group. + The item and child items will be reparented to this group, but its + position and transformation relative to the scene will stay intact. \sa removeFromGroup(), QGraphicsScene::createItemGroup() */ diff --git a/src/widgets/graphicsview/qgraphicslayout.cpp b/src/widgets/graphicsview/qgraphicslayout.cpp index cec5ba57a3f..63f04f67bc7 100644 --- a/src/widgets/graphicsview/qgraphicslayout.cpp +++ b/src/widgets/graphicsview/qgraphicslayout.cpp @@ -103,6 +103,10 @@ QT_BEGIN_NAMESPACE any way, but for a linear layout, the order is essential. When writing your own layout subclass, you are free to choose the API that best suits your layout. + QGraphicsLayout provides the addChildLayoutItem() convenience function to add + layout items to a custom layout. The function will automatically reparent + graphics items, if required. + \section1 Activating the Layout When the layout's geometry changes, QGraphicsLayout immediately rearranges diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index c84b1f63195..f029b7258e7 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -2951,7 +2951,7 @@ QDomElement QDomNode::firstChildElement(const QString &tagName) const /*! Returns the last child element with tag name \a tagName if tagName is non-empty; - otherwise returns the first child element. Returns a null element if no + otherwise returns the last child element. Returns a null element if no such child exists. \sa firstChildElement() previousSiblingElement() nextSiblingElement() From 581f079b04d4c1901d820304b3e9195e096e34e2 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 9 Feb 2012 11:31:01 +0200 Subject: [PATCH 112/406] Make "nmake check" pass for corelib tests in Windows. - Marked four tests insignificant due to failures, these need to be fixed later and then re-enabled: - tst_qfilesystemwatcher - tst_qsettings - tst_qlibrary - tst_qsharedpointer - Skipped one invalid case (tst_QCoreApplication::argc()) - Ifdeffed around vsprintf issue in MSVC (tst_QByteArray::qvsnprintf()) Task-number: QTBUG-24157 Task-number: QTBUG-24146 Task-number: QTBUG-24128 Change-Id: I4db957a65fbf0093f5ae3dc1a04d792492818104 Reviewed-by: Friedemann Kleint Reviewed-by: Sergio Ahumada --- .../auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro | 1 + tests/auto/corelib/io/qsettings/qsettings.pro | 1 + .../corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp | 3 +++ tests/auto/corelib/plugin/qlibrary/tst/tst.pro | 2 ++ tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp | 3 +++ tests/auto/corelib/tools/qsharedpointer/qsharedpointer.pro | 2 ++ 6 files changed, 12 insertions(+) diff --git a/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro b/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro index e712a6ad5f5..043b2b5d1d4 100644 --- a/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro +++ b/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro @@ -4,3 +4,4 @@ QT = core testlib SOURCES = tst_qfilesystemwatcher.cpp mac: CONFIG += insignificant_test # QTBUG-22744 +win32:CONFIG += insignificant_test # QTBUG-24029 diff --git a/tests/auto/corelib/io/qsettings/qsettings.pro b/tests/auto/corelib/io/qsettings/qsettings.pro index ed3be0f23f0..a5483bf5853 100644 --- a/tests/auto/corelib/io/qsettings/qsettings.pro +++ b/tests/auto/corelib/io/qsettings/qsettings.pro @@ -7,3 +7,4 @@ RESOURCES += qsettings.qrc win32-msvc*:LIBS += advapi32.lib mac: CONFIG += insignificant_test # QTBUG-22745 +win32: CONFIG += insignificant_test # QTBUG-24145 diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp index 97c9757107e..572c2fdfd10 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp @@ -126,6 +126,9 @@ void tst_QCoreApplication::qAppName() void tst_QCoreApplication::argc() { +#ifdef Q_OS_WIN + QSKIP("QCoreApplication::arguments() always parses arguments from actual command line in Windows, making this test invalid."); +#endif { int argc = 1; char *argv[] = { "tst_qcoreapplication" }; diff --git a/tests/auto/corelib/plugin/qlibrary/tst/tst.pro b/tests/auto/corelib/plugin/qlibrary/tst/tst.pro index 6e71ec8ff93..0992ad89f38 100644 --- a/tests/auto/corelib/plugin/qlibrary/tst/tst.pro +++ b/tests/auto/corelib/plugin/qlibrary/tst/tst.pro @@ -12,3 +12,5 @@ win32 { } TESTDATA += ../library_path/invalid.so + +win32:CONFIG += insignificant_test # QTBUG-24151 diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index c1598c452da..40e4cc398fb 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -521,7 +521,10 @@ void tst_QByteArray::qvsnprintf() QCOMPARE(::qsnprintf(buf, 10, "%s", "bubu"), 4); QCOMPARE(static_cast(buf), "bubu"); +#ifndef Q_CC_MSVC + // MSVC implementation of vsnprintf overwrites bytes after null terminator so this would fail. QCOMPARE(buf[5], char(42)); +#endif qMemSet(buf, 42, sizeof(buf)); QCOMPARE(::qsnprintf(buf, 5, "%s", "bubu"), 4); diff --git a/tests/auto/corelib/tools/qsharedpointer/qsharedpointer.pro b/tests/auto/corelib/tools/qsharedpointer/qsharedpointer.pro index b1cd309293c..1b227109b37 100644 --- a/tests/auto/corelib/tools/qsharedpointer/qsharedpointer.pro +++ b/tests/auto/corelib/tools/qsharedpointer/qsharedpointer.pro @@ -13,3 +13,5 @@ HEADERS = forwarddeclared.h \ TESTDATA += forwarddeclared.cpp forwarddeclared.h include(externaltests.pri) + +win32:CONFIG += insignificant_test # QTBUG-24160 From 4af285c7d1be43b1882fb5b2ece8539622ea1b22 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Wed, 8 Feb 2012 17:28:13 +0100 Subject: [PATCH 113/406] Preserve weight and style request for multi font engines So that fallback fonts can pickup the weight/style requested instead of using the weight and style of the primary font. Change-Id: Ia592e079cad61334f21e0453412b198a900bb6b6 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontdatabase.cpp | 8 +++++--- src/gui/text/qfontdatabase_qpa.cpp | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 3ef28b8e504..e9b7d1a1dd8 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -724,7 +724,7 @@ static void match(int script, const QFontDef &request, const QString &family_name, const QString &foundry_name, int force_encoding_id, QtFontDesc *desc, const QList &blacklistedFamilies = QList(), bool forceXLFD=false); -static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDef *fontDef) +static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDef *fontDef, bool multi) { fontDef->family = desc.family->name; if (! desc.foundry->name.isEmpty() && desc.family->count > 1) { @@ -743,8 +743,10 @@ static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDe fontDef->styleHint = request.styleHint; fontDef->styleStrategy = request.styleStrategy; - fontDef->weight = desc.style->key.weight; - fontDef->style = desc.style->key.style; + if (!multi) + fontDef->weight = desc.style->key.weight; + if (!multi) + fontDef->style = desc.style->key.style; fontDef->fixedPitch = desc.family->fixedPitch; fontDef->stretch = desc.style->key.stretch; fontDef->ignorePitch = false; diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp index c57fe4b3435..266ad4d453e 100644 --- a/src/gui/text/qfontdatabase_qpa.cpp +++ b/src/gui/text/qfontdatabase_qpa.cpp @@ -278,7 +278,7 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, } if (engine && engine->type() != QFontEngine::TestFontEngine) { - initFontDef(desc, request, &engine->fontDef); + initFontDef(desc, request, &engine->fontDef, engine->type() == QFontEngine::Multi); if (fp) { QFontDef def = request; @@ -305,7 +305,7 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, } engine = loadEngine(script, def, desc.family, desc.foundry, desc.style, desc.size); if (engine) { - initFontDef(desc, def, &engine->fontDef); + initFontDef(desc, def, &engine->fontDef, engine->type() == QFontEngine::Multi); } } } From d5268eabfbad3743c47cf7a6aaf98ef7029d2ef1 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 9 Feb 2012 12:25:46 +0200 Subject: [PATCH 114/406] Add event type for TouchCancel. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Id8b68e5cb19a2a325139e3241647cc36581cf6f8 Reviewed-by: Lars Knoll Reviewed-by: Samuel Rødal --- src/corelib/kernel/qcoreevent.cpp | 1 + src/corelib/kernel/qcoreevent.h | 2 ++ src/gui/kernel/qevent.cpp | 12 +++++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index 9ed696539a9..032590fa7f7 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -228,6 +228,7 @@ QT_BEGIN_NAMESPACE \value TouchBegin Beginning of a sequence of touch-screen and/or track-pad events (QTouchEvent) \value TouchUpdate Touch-screen event (QTouchEvent) \value TouchEnd End of touch-event sequence (QTouchEvent) + \value TouchCancel Cancellation of touch-event sequence (QTouchEvent) \value WinIdChange The window system identifer for this native widget has changed \value Gesture A gesture was triggered (QGestureEvent) \value GestureOverride A gesture override was triggered (QGestureEvent) diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index 8910763daf0..8182ac907e9 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -277,6 +277,8 @@ public: InputMethodQuery = 209, OrientationChange = 210, // Screen orientation has changed + TouchCancel = 211, + // 512 reserved for Qt Jambi's MetaCall event // 513 reserved for Qt Jambi's DeleteOnMainThread event diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 543f5453ff8..c3a6be692b6 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3305,15 +3305,21 @@ QWindowStateChangeEvent::~QWindowStateChangeEvent() \section1 Event Handling - All touch events are of type QEvent::TouchBegin, QEvent::TouchUpdate, or QEvent::TouchEnd. - Reimplement QWidget::event() or QAbstractScrollArea::viewportEvent() for widgets and - QGraphicsItem::sceneEvent() for items in a graphics view to receive touch events. + All touch events are of type QEvent::TouchBegin, QEvent::TouchUpdate, QEvent::TouchEnd or + QEvent::TouchCancel. Reimplement QWidget::event() or QAbstractScrollArea::viewportEvent() for + widgets and QGraphicsItem::sceneEvent() for items in a graphics view to receive touch events. The QEvent::TouchUpdate and QEvent::TouchEnd events are sent to the widget or item that accepted the QEvent::TouchBegin event. If the QEvent::TouchBegin event is not accepted and not filtered by an event filter, then no further touch events are sent until the next QEvent::TouchBegin. + Some systems may send an event of type QEvent::TouchCancel. Upon receiving this event + applications are requested to ignore the entire active touch sequence. For example in a + composited system the compositor may decide to treat certain gestures as system-wide + gestures. Whenever such a decision is made (the gesture is recognized), the clients will be + notified with a QEvent::TouchCancel event so they can update their state accordingly. + The touchPoints() function returns a list of all touch points contained in the event. Information about each touch point can be retrieved using the QTouchEvent::TouchPoint class. The Qt::TouchPointState enum describes the different states that a touch point may have. From e7e87993042ac9a4fd899da5ea0340322b47d9ff Mon Sep 17 00:00:00 2001 From: Nick Ratelle Date: Fri, 6 Jan 2012 12:19:27 -0500 Subject: [PATCH 115/406] Initializes seqDumpPos on qiodevice.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was spotted by RIM static code checking team. seqDumpPos is a dummy variable which is only used on sequential mode. It is used as a simultaneous storage area of both pPos and pDevicePos when in sequential mode, to keep both in sync. They just suggested that it would be a good practice to initialize the variable, since it does not have any side effect, and there's not much value on not doing it. Change-Id: I8138729eb31df5779c91b368c2cfaecd39788f29 Reviewed-by: João Abecasis Reviewed-by: Jonas Gastal --- src/corelib/io/qiodevice.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index 0ad1a91d6c3..3d9391ebaa7 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -118,7 +118,7 @@ void debugBinaryString(const char *data, qint64 maxlen) */ QIODevicePrivate::QIODevicePrivate() : openMode(QIODevice::NotOpen), buffer(QIODEVICE_BUFFERSIZE), - pos(0), devicePos(0) + pos(0), devicePos(0), seqDumpPos(0) , pPos(&pos), pDevicePos(&devicePos) , baseReadLineDataCalled(false) , firstRead(true) @@ -562,6 +562,7 @@ void QIODevice::close() d->openMode = NotOpen; d->errorString.clear(); d->pos = 0; + d->seqDumpPos = 0; d->buffer.clear(); d->firstRead = true; } From be98fa32c7d56ea91359b647a329356fa44eca04 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 3 Feb 2012 09:35:22 +0100 Subject: [PATCH 116/406] Allow customization of qDebug output at runtime Check the QT_OUTPUT_PATTERN environment variable in the default message handler to customize the output of messages. Following place holders are right now supported: %{message}, %{type}, %{file}, %{line}, %{function} The original cleanupFuncinfo was written by Thiago Macieira. Change-Id: I6ad25baaa0e6a1c9f886105d2a93ef3310e512a9 Reviewed-by: Olivier Goffart Reviewed-by: David Faure --- qmake/Makefile.unix | 6 +- qmake/Makefile.win32 | 4 +- qmake/Makefile.win32-g++ | 5 +- qmake/Makefile.win32-g++-sh | 6 +- qmake/qmake.pri | 3 +- src/corelib/global/qglobal.cpp | 21 +- src/corelib/global/qlogging.cpp | 313 ++++++++- src/corelib/kernel/qcoreapplication_win.cpp | 24 +- tests/auto/corelib/global/global.pro | 2 +- .../auto/corelib/global/qlogging/app/app.pro | 9 + .../auto/corelib/global/qlogging/app/main.cpp | 55 ++ .../auto/corelib/global/qlogging/qlogging.pro | 5 + .../corelib/global/qlogging/tst_qlogging.cpp | 645 ++++++++++++++++++ .../corelib/global/qlogging/tst_qlogging.pro | 4 + .../qmessagehandler/qmessagehandler.pro | 4 - .../qmessagehandler/tst_qmessagehandler.cpp | 147 ---- tools/configure/configure.pro | 2 + 17 files changed, 1076 insertions(+), 179 deletions(-) create mode 100644 tests/auto/corelib/global/qlogging/app/app.pro create mode 100644 tests/auto/corelib/global/qlogging/app/main.cpp create mode 100644 tests/auto/corelib/global/qlogging/qlogging.pro create mode 100644 tests/auto/corelib/global/qlogging/tst_qlogging.cpp create mode 100644 tests/auto/corelib/global/qlogging/tst_qlogging.pro delete mode 100644 tests/auto/corelib/global/qmessagehandler/qmessagehandler.pro delete mode 100644 tests/auto/corelib/global/qmessagehandler/tst_qmessagehandler.cpp diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index 286e2ebcbcd..16af49311b0 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -22,7 +22,7 @@ QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qgl qfileinfo.o qdatetime.o qstringlist.o qabstractfileengine.o qtemporaryfile.o \ qmap.o qmetatype.o qsettings.o qsystemerror.o qlibraryinfo.o qvariant.o qvsnprintf.o \ qlocale.o qlocale_tools.o qlocale_unix.o qlinkedlist.o qurl.o qnumeric.o qcryptographichash.o \ - qxmlstream.o qxmlutils.o \ + qxmlstream.o qxmlutils.o qlogging.o \ $(QTOBJS) @@ -66,6 +66,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp \ $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp \ $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp \ + $(SOURCE_PATH)/src/corelib/global/qlogging.cpp \ $(QTSRCS) CPPFLAGS = -g -I. -Igenerators -Igenerators/unix -Igenerators/win32 \ @@ -316,6 +317,9 @@ qxmlstream.o: $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp qxmlutils.o: $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp +qlogging.o: $(SOURCE_PATH)/src/corelib/global/qlogging.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qlogging.cpp + #default rules .cpp.o: $(CXX) -c -o $@ $(CXXFLAGS) $< diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index e7677860012..3efe6a67e0c 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -118,8 +118,8 @@ QTOBJS= \ qmetatype.obj \ qxmlstream.obj \ qxmlutils.obj \ - qnumeric.obj - + qnumeric.obj \ + qlogging.obj first all: qmake.exe diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++ index 443dba390aa..585061ed268 100644 --- a/qmake/Makefile.win32-g++ +++ b/qmake/Makefile.win32-g++ @@ -95,7 +95,8 @@ QTOBJS= \ qmetatype.o \ qxmlstream.o \ qxmlutils.o \ - qnumeric.o + qnumeric.o \ + qlogging.o qmake.exe: $(OBJS) $(QTOBJS) @@ -339,3 +340,5 @@ qxmlstream.o: $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp qxmlutils.o: $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp +qlogging.o: $(SOURCE_PATH)/src/corelib/global/qlogging.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qlogging.cpp diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh index bc8356e178a..6dfb4863754 100644 --- a/qmake/Makefile.win32-g++-sh +++ b/qmake/Makefile.win32-g++-sh @@ -95,7 +95,8 @@ QTOBJS= \ qmetatype.o \ qxmlstream.o \ qxmlutils.o \ - qnumeric.o + qnumeric.o \ + qlogging.o qmake.exe: $(OBJS) $(QTOBJS) $(LINKQMAKE) @@ -337,3 +338,6 @@ qxmlstream.o: $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp qxmlutils.o: $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp + +qlogging.o: $(SOURCE_PATH)/src/corelib/global/qlogging.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qlogging.cpp diff --git a/qmake/qmake.pri b/qmake/qmake.pri index 1f59531c420..ba6ab383c7e 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -76,7 +76,8 @@ bootstrap { #Qt code qvector.cpp \ qvsnprintf.cpp \ qxmlstream.cpp \ - qxmlutils.cpp + qxmlutils.cpp \ + qlogging.cpp HEADERS+= \ qbitarray.h \ diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 01b3e2ec327..983116f1b35 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1862,27 +1862,32 @@ extern Q_CORE_EXPORT void qWinMessageHandler(QtMsgType t, const QMessageLogConte const char *str); #endif +// defined in qlogging.cpp +extern Q_CORE_EXPORT QByteArray qMessageFormatString(QtMsgType type, const QMessageLogContext &context, + const char *str); + /*! \internal */ -static void qDefaultMsgHandler(QtMsgType, const char *buf) +static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &context, const char *buf) { + QByteArray logMessage = qMessageFormatString(type, context, buf); #if defined(Q_OS_WINCE) - QString fstr = QString::fromLatin1(buf); - fstr += QLatin1Char('\n'); - OutputDebugString(reinterpret_cast (fstr.utf16())); + QString fstr = QString::fromLocal8Bit(logMessage); + OutputDebugString(reinterpret_cast (fstr.utf16())); #else - fprintf(stderr, "%s\n", buf); - fflush(stderr); + fprintf(stderr, "%s", logMessage.constData()); + fflush(stderr); #endif } /*! \internal */ -static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &, const char *buf) +static void qDefaultMsgHandler(QtMsgType type, const char *buf) { - qDefaultMsgHandler(type, buf); + QMessageLogContext emptyContext; + qDefaultMessageHandler(type, emptyContext, buf); } QMessageHandler qInstallMessageHandler(QMessageHandler h) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index bc26c9b6b7e..39b32055713 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -39,7 +39,13 @@ ** ****************************************************************************/ -#include +#include "qlogging.h" +#include "qlist.h" +#include "qbytearray.h" +#include "qstring.h" +#include "qvarlengtharray.h" + +#include QT_BEGIN_NAMESPACE @@ -73,4 +79,309 @@ QT_BEGIN_NAMESPACE \sa QMessageLogContext, qDebug(), qWarning(), qCritical(), qFatal() */ +/*! + \internal +*/ +Q_AUTOTEST_EXPORT QByteArray qCleanupFuncinfo(QByteArray info) +{ + // Strip the function info down to the base function name + // note that this throws away the template definitions, + // the parameter types (overloads) and any const/volatile qualifiers. + + if (info.isEmpty()) + return info; + + int pos; + + // skip trailing [with XXX] for templates (gcc) + pos = info.size() - 1; + if (info.endsWith(']')) { + while (--pos) { + if (info.at(pos) == '[') + info.truncate(pos); + } + } + + // operator names with '(', ')', '<', '>' in it + static const char operator_call[] = "operator()"; + static const char operator_lessThan[] = "operator<"; + static const char operator_greaterThan[] = "operator>"; + static const char operator_lessThanEqual[] = "operator<="; + static const char operator_greaterThanEqual[] = "operator>="; + + // canonize operator names + info.replace("operator ", "operator"); + + // remove argument list + forever { + int parencount = 0; + pos = info.lastIndexOf(')'); + if (pos == -1) { + // Don't know how to parse this function name + return info; + } + + // find the beginning of the argument list + --pos; + ++parencount; + while (pos && parencount) { + if (info.at(pos) == ')') + ++parencount; + else if (info.at(pos) == '(') + --parencount; + --pos; + } + if (parencount != 0) + return info; + + info.truncate(++pos); + + if (info.at(pos - 1) == ')') { + if (info.indexOf(operator_call) == pos - (int)strlen(operator_call)) + break; + + // this function returns a pointer to a function + // and we matched the arguments of the return type's parameter list + // try again + info.remove(0, info.indexOf('(')); + info.chop(1); + continue; + } else { + break; + } + } + + // find the beginning of the function name + int parencount = 0; + int templatecount = 0; + --pos; + + // make sure special characters in operator names are kept + if (pos > -1) { + switch (info.at(pos)) { + case ')': + if (info.indexOf(operator_call) == pos - (int)strlen(operator_call) + 1) + pos -= 2; + break; + case '<': + if (info.indexOf(operator_lessThan) == pos - (int)strlen(operator_lessThan) + 1) + --pos; + break; + case '>': + if (info.indexOf(operator_greaterThan) == pos - (int)strlen(operator_greaterThan) + 1) + --pos; + break; + case '=': { + int operatorLength = (int)strlen(operator_lessThanEqual); + if (info.indexOf(operator_lessThanEqual) == pos - operatorLength + 1) + pos -= 2; + else if (info.indexOf(operator_greaterThanEqual) == pos - operatorLength + 1) + pos -= 2; + break; + } + default: + break; + } + } + + while (pos > -1) { + if (parencount < 0 || templatecount < 0) + return info; + + char c = info.at(pos); + if (c == ')') + ++parencount; + else if (c == '(') + --parencount; + else if (c == '>') + ++templatecount; + else if (c == '<') + --templatecount; + else if (c == ' ' && templatecount == 0 && parencount == 0) + break; + + --pos; + } + info = info.mid(pos + 1); + + // we have the full function name now. + // clean up the templates + while ((pos = info.lastIndexOf('>')) != -1) { + if (!info.contains('<')) + break; + + // find the matching close + int end = pos; + templatecount = 1; + --pos; + while (pos && templatecount) { + register char c = info.at(pos); + if (c == '>') + ++templatecount; + else if (c == '<') + --templatecount; + --pos; + } + ++pos; + info.remove(pos, end - pos + 1); + } + + return info; +} + +// tokens as recognized in QT_MESSAGE_PATTERN +static const char typeTokenC[] = "%{type}"; +static const char messageTokenC[] = "%{message}"; +static const char fileTokenC[] = "%{file}"; +static const char lineTokenC[] = "%{line}"; +static const char functionTokenC[] = "%{function}"; +static const char emptyTokenC[] = ""; + +struct QMessagePattern { + QMessagePattern(); + ~QMessagePattern(); + + // 0 terminated arrays of literal tokens / literal or placeholder tokens + const char **literals; + const char **tokens; +}; + +QMessagePattern::QMessagePattern() +{ + QString pattern = QString::fromLocal8Bit(qgetenv("QT_MESSAGE_PATTERN")); + if (pattern.isEmpty()) { + pattern = QLatin1String("%{message}"); + } + + // scanner + QList lexemes; + QString lexeme; + bool inPlaceholder = false; + for (int i = 0; i < pattern.size(); ++i) { + const QChar c = pattern.at(i); + if ((c == QLatin1Char('%')) + && !inPlaceholder) { + if ((i + 1 < pattern.size()) + && pattern.at(i + 1) == QLatin1Char('{')) { + // beginning of placeholder + if (!lexeme.isEmpty()) { + lexemes.append(lexeme); + lexeme.clear(); + } + inPlaceholder = true; + } + } + + lexeme.append(c); + + if ((c == QLatin1Char('}') && inPlaceholder)) { + // end of placeholder + lexemes.append(lexeme); + lexeme.clear(); + inPlaceholder = false; + } + } + if (!lexeme.isEmpty()) + lexemes.append(lexeme); + + // tokenizer + QVarLengthArray literalsVar; + tokens = new const char*[lexemes.size() + 1]; + tokens[lexemes.size()] = 0; + + for (int i = 0; i < lexemes.size(); ++i) { + const QString lexeme = lexemes.at(i); + if (lexeme.startsWith(QLatin1String("%{")) + && lexeme.endsWith(QLatin1Char('}'))) { + // placeholder + if (lexeme == QLatin1String(typeTokenC)) { + tokens[i] = typeTokenC; + } else if (lexeme == QLatin1String(messageTokenC)) + tokens[i] = messageTokenC; + else if (lexeme == QLatin1String(fileTokenC)) + tokens[i] = fileTokenC; + else if (lexeme == QLatin1String(lineTokenC)) + tokens[i] = lineTokenC; + else if (lexeme == QLatin1String(functionTokenC)) + tokens[i] = functionTokenC; + else { + fprintf(stderr, "%s\n", + QString::fromLatin1("QT_MESSAGE_PATTERN: Unknown placeholder %1\n" + ).arg(lexeme).toLocal8Bit().constData()); + fflush(stderr); + tokens[i] = emptyTokenC; + } + } else { + char *literal = new char[lexeme.size() + 1]; + strncpy(literal, lexeme.toLocal8Bit().constData(), lexeme.size()); + literal[lexeme.size()] = '\0'; + literalsVar.append(literal); + tokens[i] = literal; + } + } + literals = new const char*[literalsVar.size() + 1]; + literals[literalsVar.size()] = 0; + memcpy(literals, literalsVar.constData(), literalsVar.size() * sizeof(const char*)); +} + +QMessagePattern::~QMessagePattern() +{ + for (int i = 0; literals[i] != 0; ++i) + delete [] literals[i]; + delete [] literals; + literals = 0; + delete [] tokens; + tokens = 0; +} + +Q_GLOBAL_STATIC(QMessagePattern, qMessagePattern) + +/*! + \internal +*/ +Q_CORE_EXPORT QByteArray qMessageFormatString(QtMsgType type, const QMessageLogContext &context, + const char *str) +{ + QByteArray message; + + QMessagePattern *pattern = qMessagePattern(); + if (!pattern) { + // after destruction of static QMessagePattern instance + message.append(str); + message.append('\n'); + return message; + } + + // we do not convert file, function, line literals to local encoding due to overhead + for (int i = 0; pattern->tokens[i] != 0; ++i) { + const char *token = pattern->tokens[i]; + if (token == messageTokenC) { + message.append(str); + } else if (token == typeTokenC) { + switch (type) { + case QtDebugMsg: message.append("debug"); break; + case QtWarningMsg: message.append("warning"); break; + case QtCriticalMsg:message.append("critical"); break; + case QtFatalMsg: message.append("fatal"); break; + } + } else if (token == fileTokenC) { + if (context.file) + message.append(context.file); + else + message.append("unknown"); + } else if (token == lineTokenC) { + message.append(QString::number(context.line).toLatin1().constData()); + } else if (token == functionTokenC) { + if (context.function) + message.append(qCleanupFuncinfo(context.function)); + else + message.append("unknown"); + } else { + message.append(token); + } + } + message.append('\n'); + return message; +} + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index 9a45f28f16f..c1f7c8ab25b 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -140,30 +140,30 @@ public: { LeaveCriticalSection(&cs); } }; -Q_CORE_EXPORT void qWinMsgHandler(QtMsgType t, const char* str) -{ - Q_UNUSED(t); - // OutputDebugString is not threadsafe. +// defined in qlogging.cpp +extern Q_CORE_EXPORT QByteArray qMessageFormatString(QtMsgType type, + const QMessageLogContext &context, + const char *str); +Q_CORE_EXPORT void qWinMessageHandler(QtMsgType t, const QMessageLogContext &context, const char *str) +{ // cannot use QMutex here, because qWarning()s in the QMutex // implementation may cause this function to recurse static QWinMsgHandlerCriticalSection staticCriticalSection; - if (!str) - str = "(null)"; + QByteArray message = qMessageFormatString(t, context, str); + QString s(QString::fromLocal8Bit(message)); + // OutputDebugString is not threadsafe. staticCriticalSection.lock(); - - QString s(QString::fromLocal8Bit(str)); - s += QLatin1Char('\n'); OutputDebugString((wchar_t*)s.utf16()); - staticCriticalSection.unlock(); } -Q_CORE_EXPORT void qWinMessageHandler(QtMsgType t, const QMessageLogContext &, const char* str) +Q_CORE_EXPORT void qWinMsgHandler(QtMsgType t, const char *str) { - qWinMsgHandler(t, str); + QMessageLogContext emptyContext; + qWinMessageHandler(t, emptyContext, str); } /***************************************************************************** diff --git a/tests/auto/corelib/global/global.pro b/tests/auto/corelib/global/global.pro index a6c638f530e..d4293a896cc 100644 --- a/tests/auto/corelib/global/global.pro +++ b/tests/auto/corelib/global/global.pro @@ -6,4 +6,4 @@ SUBDIRS=\ qglobal \ qnumeric \ qrand \ - qmessagehandler + qlogging diff --git a/tests/auto/corelib/global/qlogging/app/app.pro b/tests/auto/corelib/global/qlogging/app/app.pro new file mode 100644 index 00000000000..a167cc45cd6 --- /dev/null +++ b/tests/auto/corelib/global/qlogging/app/app.pro @@ -0,0 +1,9 @@ +TEMPLATE = app + +TARGET = app +QT = core + +CONFIG -= debug_and_release app_bundle +CONFIG += debug console + +SOURCES += main.cpp diff --git a/tests/auto/corelib/global/qlogging/app/main.cpp b/tests/auto/corelib/global/qlogging/app/main.cpp new file mode 100644 index 00000000000..c26b29ea560 --- /dev/null +++ b/tests/auto/corelib/global/qlogging/app/main.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite 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 + +struct T { + T() { qDebug("static constructor"); } + ~T() { qDebug("static destructor"); } +} t; + +int main(int, char **) +{ + qDebug("qDebug"); + qWarning("qWarning"); + qCritical("qCritical"); + return 0; +} diff --git a/tests/auto/corelib/global/qlogging/qlogging.pro b/tests/auto/corelib/global/qlogging/qlogging.pro new file mode 100644 index 00000000000..449b7dfa5ee --- /dev/null +++ b/tests/auto/corelib/global/qlogging/qlogging.pro @@ -0,0 +1,5 @@ +TEMPLATE = subdirs + +SUBDIRS += \ + tst_qlogging.pro \ + app \ No newline at end of file diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp new file mode 100644 index 00000000000..742a858961b --- /dev/null +++ b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp @@ -0,0 +1,645 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite 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 +#include +#include +#include + +class tst_qmessagehandler : public QObject +{ + Q_OBJECT +private slots: + void cleanup(); + + void defaultHandler(); + void installMessageHandler(); + void installMsgHandler(); + void installBothHandler(); + + void cleanupFuncinfo_data(); + void cleanupFuncinfo(); + + void qMessagePattern(); +}; + +static QtMsgType s_type; +const char *s_file; +int s_line; +const char *s_function; +static QString s_message; + +void customMessageHandler(QtMsgType type, const QMessageLogContext &context, const char *msg) +{ + s_type = type; + s_file = context.file; + s_line = context.line; + s_function = context.function; + s_message = QString::fromLocal8Bit(msg); +} + +void customMsgHandler(QtMsgType type, const char *msg) +{ + s_type = type; + s_file = 0; + s_line = 0; + s_function = 0; + s_message = QString::fromLocal8Bit(msg); +} + +void tst_qmessagehandler::cleanup() +{ + qInstallMsgHandler(0); + qInstallMessageHandler(0); + s_type = QtFatalMsg; + s_file = 0; + s_line = 0; + s_function = 0; +} + +void tst_qmessagehandler::defaultHandler() +{ + // check that the default works + QTest::ignoreMessage(QtDebugMsg, "defaultHandler"); + qDebug("defaultHandler"); +} + +void tst_qmessagehandler::installMessageHandler() +{ + QMessageHandler oldHandler = qInstallMessageHandler(customMessageHandler); + + qDebug("installMessageHandler"); int line = __LINE__; + + QCOMPARE(s_type, QtDebugMsg); + QCOMPARE(s_message, QString::fromLocal8Bit("installMessageHandler")); + QCOMPARE(s_file, __FILE__); + QCOMPARE(s_function, Q_FUNC_INFO); + QCOMPARE(s_line, line); + + QMessageHandler myHandler = qInstallMessageHandler(oldHandler); + QCOMPARE((void*)myHandler, (void*)customMessageHandler); +} + +void tst_qmessagehandler::installMsgHandler() +{ + QtMsgHandler oldHandler = qInstallMsgHandler(customMsgHandler); + + qDebug("installMsgHandler"); + + QCOMPARE(s_type, QtDebugMsg); + QCOMPARE(s_message, QString::fromLocal8Bit("installMsgHandler")); + QCOMPARE(s_file, (const char*)0); + QCOMPARE(s_function, (const char*)0); + QCOMPARE(s_line, 0); + + QtMsgHandler myHandler = qInstallMsgHandler(oldHandler); + QCOMPARE((void*)myHandler, (void*)customMsgHandler); +} + +void tst_qmessagehandler::installBothHandler() +{ + qInstallMessageHandler(customMessageHandler); + qInstallMsgHandler(customMsgHandler); + + qDebug("installBothHandler"); int line = __LINE__; + + QCOMPARE(s_type, QtDebugMsg); + QCOMPARE(s_message, QString::fromLocal8Bit("installBothHandler")); + QCOMPARE(s_file, __FILE__); + QCOMPARE(s_function, Q_FUNC_INFO); + QCOMPARE(s_line, line); +} + +# define ADD(x) QTest::newRow(x) << Q_FUNC_INFO << x; + +class TestClass1 +{ +public: + enum Something { foo }; + + void func_void() { ADD("TestClass1::func_void"); } + int func_int() { ADD("TestClass1::func_int"); return 0; } + unsigned func_unsigned() { ADD("TestClass1::func_unsigned"); return 0; } + long func_long() { ADD("TestClass1::func_long"); return 0; } + long long func_ll() { ADD("TestClass1::func_ll"); return 0; } + unsigned long long func_ull() { ADD("TestClass1::func_ull"); return 0; } + char func_char() { ADD("TestClass1::func_char"); return 0; } + signed char func_schar() { ADD("TestClass1::func_schar"); return 0; } + unsigned char func_uchar() { ADD("TestClass1::func_uchar"); return 0; } + char *func_Pchar() { ADD("TestClass1::func_Pchar"); return 0; } + const char *func_KPchar() { ADD("TestClass1::func_KPchar"); return 0; } + const volatile char *func_VKPchar() { ADD("TestClass1::func_VKPchar"); return 0; } + const volatile unsigned long long * const volatile func_KVPKVull() { ADD("TestClass1::func_KVPKVull"); return 0; } + const void * const volatile *func_KPKVvoid() { ADD("TestClass1::func_KPKVvoid"); return 0; } + + QList func_ai() { ADD("TestClass1::func_ai"); return QList(); } + QList func_aptr() { ADD("TestClass1::func_aptr"); return QList(); } + + QList func_aenum() { ADD("TestClass1::func_aenum"); return QList(); } + QList > func_aaptr() { ADD("TestClass1::func_aaptr"); return QList >(); } + + QMap func_ienummap() { ADD("TestClass1::func_ienummap"); return QMap(); } + + template + T* func_template1() { ADD("TestClass1::func_template1"); return 0; } + template + long func_template2() { ADD("TestClass1::func_template2"); return long(val); } + + typedef unsigned long long * ( *fptr)(); + typedef unsigned long long * (TestClass1::* pmf)(); + typedef fptr (TestClass1::* uglypmf)(); + fptr func_fptr() { ADD("TestClass1::func_fptr"); return 0; } + pmf func_pmf() { ADD("TestClass1::func_pmf"); return 0; } + uglypmf func_uglypmf(uglypmf = 0) { ADD("TestClass1::func_uglypmf"); return 0; } + QMap func_uglypmf2() { ADD("TestClass1::func_uglypmf2"); return QMap(); } + + void operator()() { ADD("TestClass1::operator()"); } + int operator<(int) { ADD("TestClass1::operator<"); return 0; } + int operator>(int) { ADD("TestClass1::operator>"); return 0; } + int operator<=(int) { ADD("TestClass1::operator<="); return 0; } + int operator>=(int) { ADD("TestClass1::operator>="); return 0; } + int operator=(int) { ADD("TestClass1::operator="); return 0; } + int operator+(int) { ADD("TestClass1::operator+"); return 0; } + int operator-(int) { ADD("TestClass1::operator-"); return 0; } + int operator*(int) { ADD("TestClass1::operator*"); return 0; } + int operator/(int) { ADD("TestClass1::operator/"); return 0; } + int operator%(int) { ADD("TestClass1::operator%"); return 0; } + int x; + int &operator++() { ADD("TestClass1::operator++"); return x; } + int operator++(int) { ADD("TestClass1::operator++"); return 0; } + int &operator--() { ADD("TestClass1::operator--"); return x; } + int operator--(int) { ADD("TestClass1::operator--"); return 0; } + +public: + TestClass1() + { + // instantiate + func_void(); + func_int(); + func_unsigned(); + func_long(); + func_ll(); + func_ull(); + func_char(); + func_schar(); + func_uchar(); + func_Pchar(); + func_KPchar(); + func_VKPchar(); + func_KVPKVull(); + func_KPKVvoid(); + func_ai(); + func_aptr(); + func_aenum(); + func_aaptr(); + func_ienummap(); + func_template1(); + func_template2(); + func_fptr(); + func_pmf(); + func_uglypmf(); + func_uglypmf2(); + operator()(); + operator<(0); + operator>(0); + operator<=(0); + operator>=(0); + operator=(0); + operator+(0); + operator-(0); + operator*(0); + operator/(0); + operator%(0); + operator++(); + operator++(0); + operator--(); + operator--(0); + } +}; + +template class TestClass2 +{ + long func_long() { ADD("TestClass2::func_long"); return 0; } + template + T* func_template1() { ADD("TestClass2::func_template1"); return 0; } + template + long func_template2() { ADD("TestClass2::func_template2"); return long(val); } +public: + TestClass2() + { + func_long(); + func_template1(); + func_template2(); + } +}; + +template class TestClass3 +{ + long func_long() { ADD("TestClass3::func_long"); return 0; } + template + S* func_template1() { ADD("TestClass3::func_template1"); return 0; } + template + long func_template2() { ADD("TestClass3::func_template2"); return long(val); } +public: + struct Foo { TestClass3 foo; }; + TestClass3() + { + func_long(); + func_template1 >(); + func_template2(); + } +}; + +class TestClass4 +{ + TestClass1 c1; + + TestClass2 > func2() + { ADD("TestClass4::func2"); return TestClass2 >(); } + TestClass3, const void *>, TestClass1::foo>::Foo func3() + { ADD("TestClass4::func3"); return TestClass3, const void *>, TestClass1::foo>::Foo(); } +public: + TestClass4() + { + func2(); + func3(); + ADD("TestClass4::TestClass4"); + } + ~TestClass4() + { + ADD("TestClass4::~TestClass4"); + } +}; + + +void tst_qmessagehandler::cleanupFuncinfo_data() +{ +#ifndef QT_BUILD_INTERNAL + QSKIP("Requires -developer-build"); +#endif + QTest::addColumn("funcinfo"); + QTest::addColumn("expected"); + + TestClass4 c4; + + QTest::newRow("msvc_01") + << "void __thiscall TestClass1::func_void(void)" + << "TestClass1::func_void"; + QTest::newRow("gcc_01") + << "void TestClass1::func_void()" + << "TestClass1::func_void"; + + QTest::newRow("msvc_02") + << "int __thiscall TestClass1::func_int(void)" + << "TestClass1::func_int"; + QTest::newRow("gcc_02") + << "int TestClass1::func_int()" + << "TestClass1::func_int"; + + QTest::newRow("msvc_03") + << "unsigned int __thiscall TestClass1::func_unsigned(void)" + << "TestClass1::func_unsigned"; + QTest::newRow("gcc_03") + << "unsigned int TestClass1::func_unsigned()" + << "TestClass1::func_unsigned"; + + QTest::newRow("msvc_04") + << "long __thiscall TestClass1::func_long(void)" + << "TestClass1::func_long"; + QTest::newRow("gcc_04") + << "long int TestClass1::func_long()" + << "TestClass1::func_long"; + + QTest::newRow("msvc_05") + << "__int64 __thiscall TestClass1::func_ll(void)" + << "TestClass1::func_ll"; + QTest::newRow("gcc_05") + << "long long int TestClass1::func_ll()" + << "TestClass1::func_ll"; + + QTest::newRow("msvc_06") + << "unsigned __int64 __thiscall TestClass1::func_ull(void)" + << "TestClass1::func_ull"; + QTest::newRow("gcc_06") + << "long long unsigned int TestClass1::func_ull()" + << "TestClass1::func_ull"; + + QTest::newRow("msvc_07") + << "char __thiscall TestClass1::func_char(void)" + << "TestClass1::func_char"; + QTest::newRow("gcc_07") + << "char TestClass1::func_char()" + << "TestClass1::func_char"; + + QTest::newRow("msvc_08") + << "signed char __thiscall TestClass1::func_schar(void)" + << "TestClass1::func_schar"; + QTest::newRow("gcc_08") + << "signed char TestClass1::func_schar()" + << "TestClass1::func_schar"; + + QTest::newRow("msvc_09") + << "unsigned char __thiscall TestClass1::func_uchar(void)" + << "TestClass1::func_uchar"; + QTest::newRow("gcc_09") + << "unsigned char TestClass1::func_uchar()" + << "TestClass1::func_uchar"; + + QTest::newRow("msvc_10") + << "char *__thiscall TestClass1::func_Pchar(void)" + << "TestClass1::func_Pchar"; + QTest::newRow("gcc_10") + << "char* TestClass1::func_Pchar()" + << "TestClass1::func_Pchar"; + + QTest::newRow("msvc_11") + << "const char *__thiscall TestClass1::func_KPchar(void)" + << "TestClass1::func_KPchar"; + QTest::newRow("gcc_11") + << "const char* TestClass1::func_KPchar()" + << "TestClass1::func_KPchar"; + + QTest::newRow("msvc_12") + << "volatile const char *__thiscall TestClass1::func_VKPchar(void)" + << "TestClass1::func_VKPchar"; + QTest::newRow("gcc_12") + << "const volatile char* TestClass1::func_VKPchar()" + << "TestClass1::func_VKPchar"; + + QTest::newRow("msvc_13") + << "volatile const unsigned __int64 *volatile const __thiscall TestClass1::func_KVPKVull(void)" + << "TestClass1::func_KVPKVull"; + QTest::newRow("gcc_13") + << "const volatile long long unsigned int* const volatile TestClass1::func_KVPKVull()" + << "TestClass1::func_KVPKVull"; + + QTest::newRow("msvc_14") + << "const void *volatile const *__thiscall TestClass1::func_KPKVvoid(void)" + << "TestClass1::func_KPKVvoid"; + QTest::newRow("gcc_14") + << "const void* const volatile* TestClass1::func_KPKVvoid()" + << "TestClass1::func_KPKVvoid"; + + QTest::newRow("msvc_15") + << "class QList __thiscall TestClass1::func_ai(void)" + << "TestClass1::func_ai"; + QTest::newRow("gcc_15") + << "QList TestClass1::func_ai()" + << "TestClass1::func_ai"; + + QTest::newRow("msvc_16") + << "class QList __thiscall TestClass1::func_aptr(void)" + << "TestClass1::func_aptr"; + QTest::newRow("gcc_16") + << "QList TestClass1::func_aptr()" + << "TestClass1::func_aptr"; + + QTest::newRow("msvc_17") + << "class QList __thiscall TestClass1::func_aenum(void)" + << "TestClass1::func_aenum"; + QTest::newRow("gcc_17") + << "QList TestClass1::func_aenum()" + << "TestClass1::func_aenum"; + + QTest::newRow("msvc_18") + << "class QList > __thiscall TestClass1::func_aaptr(void)" + << "TestClass1::func_aaptr"; + QTest::newRow("gcc_18") + << "QList > TestClass1::func_aaptr()" + << "TestClass1::func_aaptr"; + + QTest::newRow("msvc_19") + << "class QMap __thiscall TestClass1::func_ienummap(void)" + << "TestClass1::func_ienummap"; + QTest::newRow("gcc_19") + << "QMap TestClass1::func_ienummap()" + << "TestClass1::func_ienummap"; + + QTest::newRow("msvc_20") + << "class TestClass1 *__thiscall TestClass1::func_template1(void)" + << "TestClass1::func_template1"; + QTest::newRow("gcc_20") + << "T* TestClass1::func_template1() [with T = TestClass1]" + << "TestClass1::func_template1"; + + QTest::newRow("msvc_21") + << "long __thiscall TestClass1::func_template2(void)" + << "TestClass1::func_template2"; + QTest::newRow("gcc_21") + << "long int TestClass1::func_template2() [with TestClass1::Something val = foo]" + << "TestClass1::func_template2"; + + QTest::newRow("msvc_22") + << "unsigned __int64 *(__cdecl *__thiscall TestClass1::func_fptr(void))(void)" + << "TestClass1::func_fptr"; + QTest::newRow("gcc_22") + << "long long unsigned int* (* TestClass1::func_fptr())()" + << "TestClass1::func_fptr"; + + QTest::newRow("msvc_23") + << "unsigned __int64 *(__thiscall TestClass1::* __thiscall TestClass1::func_pmf(void))(void)" + << "TestClass1::func_pmf"; + QTest::newRow("gcc_23") + << "long long unsigned int* (TestClass1::* TestClass1::func_pmf())()" + << "TestClass1::func_pmf"; + + QTest::newRow("msvc_24") + << "unsigned __int64 *(__cdecl *(__thiscall TestClass1::* __thiscall TestClass1::func_uglypmf(unsigned __int64 *(__cdecl *(__thiscall TestClass1::* )(void))(void)))(void))(void)" + << "TestClass1::func_uglypmf"; + QTest::newRow("gcc_24") + << "long long unsigned int* (* (TestClass1::* TestClass1::func_uglypmf(long long unsigned int* (* (TestClass1::*)())()))())()" + << "TestClass1::func_uglypmf"; + + QTest::newRow("msvc_25") + << "class QMap __thiscall TestClass1::func_uglypmf2(void)" + << "TestClass1::func_uglypmf2"; + QTest::newRow("gcc_25") + << "QMap TestClass1::func_uglypmf2()" + << "TestClass1::func_uglypmf2"; + + QTest::newRow("msvc_26") + << "class TestClass2,class std::allocator > > > __thiscall TestClass4::func2(void)" + << "TestClass4::func2"; + QTest::newRow("gcc_26") + << "TestClass2, std::allocator > > > TestClass4::func2()" + << "TestClass4::func2"; + + QTest::newRow("msvc_27") + << "long __thiscall TestClass2,class std::allocator > > >::func_long(void)" + << "TestClass2::func_long"; + QTest::newRow("gcc_27") + << "long int TestClass2::func_long() [with T = std::map, std::allocator > >]" + << "TestClass2::func_long"; + + QTest::newRow("msvc_28") + << "class std::map,class std::allocator > > *__thiscall TestClass2,class std::allocator > > >::func_template1,class std::allocator > > >>(void)" + << "TestClass2::func_template1"; + QTest::newRow("gcc_21") + << "T* TestClass2::func_template1() [with S = TestClass2, std::allocator > > >, T = std::map, std::allocator > >]" + << "TestClass2::func_template1"; + + QTest::newRow("msvc_29") + << "long __thiscall TestClass2,class std::allocator > > >::func_template2(void)" + << "TestClass2::func_template2"; + QTest::newRow("gcc_29") + << "long int TestClass2::func_template2() [with TestClass1::Something val = foo, T = std::map, std::allocator > >]" + << "TestClass2::func_template2"; + + QTest::newRow("msvc_30") + << "struct TestClass3 >,void const *,struct std::less > >,class std::allocator > const ,void const *> > >,0>::Foo __thiscall TestClass4::func3(void)" + << "TestClass4::func3"; + QTest::newRow("gcc_30") + << "TestClass3 >, const void*, std::less > >, std::allocator >, const void*> > >, foo>::Foo TestClass4::func3()" + << "TestClass4::func3"; + + QTest::newRow("msvc_31") + << "long __thiscall TestClass3 >,void const *,struct std::less > >,class std::allocator > const ,void const *> > >,0>::func_long(void)" + << "TestClass3::func_long"; + QTest::newRow("gcc_31") + << "long int TestClass3::func_long() [with T = std::map >, const void*, std::less > >, std::allocator >, const void*> > >, TestClass1::Something v = foo]" + << "TestClass3::func_long"; + + QTest::newRow("msvc_32") + << "class TestClass2 >,void const *,struct std::less > >,class std::allocator > const ,void const *> > > > *__thiscall TestClass3 >,void const *,struct std::less > >,class std::allocator > const ,void const *> > >,0>::func_template1 >,void const *,struct std::less > >,class std::allocator > const ,void const *> > > >>(void)" + << "TestClass3::func_template1"; + QTest::newRow("gcc_32") + << "S* TestClass3::func_template1() [with S = TestClass2 >, const void*, std::less > >, std::allocator >, const void*> > > >, T = std::map >, const void*, std::less > >, std::allocator >, const void*> > >, TestClass1::Something v = foo]" + << "TestClass3::func_template1"; + + QTest::newRow("msvc_33") + << "long __thiscall TestClass3 >,void const *,struct std::less > >,class std::allocator > const ,void const *> > >,0>::func_template2(void)" + << "TestClass3::func_template2"; + QTest::newRow("gcc_33") + << "long int TestClass3::func_template2() [with TestClass1::Something val = foo, T = std::map >, const void*, std::less > >, std::allocator >, const void*> > >, TestClass1::Something v = foo]" + << "TestClass3::func_template2"; + + QTest::newRow("msvc_34") + << "__thiscall TestClass4::TestClass4(void)" + << "TestClass4::TestClass4"; + QTest::newRow("gcc_34") + << "TestClass4::TestClass4()" + << "TestClass4::TestClass4"; + + QTest::newRow("msvc_35") + << "__thiscall TestClass4::~TestClass4(void)" + << "TestClass4::~TestClass4"; + QTest::newRow("gcc_35") + << "TestClass4::~TestClass4()" + << "TestClass4::~TestClass4"; + + QTest::newRow("gcc_36") + << "void TestClass1::operator()()" + << "TestClass1::operator()"; + + QTest::newRow("gcc_37") + << "long int TestClass1::func_template2() [with TestClass1::Something val = (TestClass1::Something)0u]" + << "TestClass1::func_template2"; + + QTest::newRow("gcc_38") + << "int TestClass1::operator<(int)" + << "TestClass1::operator<"; + + QTest::newRow("gcc_39") + << "int TestClass1::operator>(int)" + << "TestClass1::operator>";} + +#ifdef QT_BUILD_INTERNAL +QT_BEGIN_NAMESPACE +extern QByteArray qCleanupFuncinfo(QByteArray); +QT_END_NAMESPACE +#endif + +void tst_qmessagehandler::cleanupFuncinfo() +{ +#ifdef QT_BUILD_INTERNAL + QFETCH(QString, funcinfo); + + QByteArray result = qCleanupFuncinfo(funcinfo.toLatin1()); + QTEST(QString::fromLatin1(result), "expected"); +#endif +} + +void tst_qmessagehandler::qMessagePattern() +{ + QProcess process; + + QStringList environment = QProcess::systemEnvironment(); + // %{file} is tricky because of shadow builds + environment.prepend("QT_MESSAGE_PATTERN=\"%{type} %{line} %{function} %{message}\""); + process.setEnvironment(environment); +#ifdef Q_OS_WIN + process.start("app/app.exe"); +#else + process.start("app/app"); +#endif + process.waitForFinished(); + + QByteArray output = process.readAllStandardError(); +// qDebug() << output; + QVERIFY(!output.isEmpty()); + + QVERIFY(output.contains("debug 45 T::T static constructor")); + // we can't be sure whether the QT_MESSAGE_PATTERN is already destructed + QVERIFY(output.contains("static destructor")); + QVERIFY(output.contains("debug 51 main qDebug")); + QVERIFY(output.contains("warning 52 main qWarning")); + QVERIFY(output.contains("critical 53 main qCritical")); + + environment = QProcess::systemEnvironment(); + environment.prepend("QT_MESSAGE_PATTERN=\"PREFIX: %{unknown} %{message}\""); + process.setEnvironment(environment); +#ifdef Q_OS_WIN + process.start("app/app.exe"); +#else + process.start("app/app"); +#endif + process.waitForFinished(); + + output = process.readAllStandardError(); +// qDebug() << output; + QVERIFY(!output.isEmpty()); + + QVERIFY(output.contains("QT_MESSAGE_PATTERN: Unknown placeholder %{unknown}")); + QVERIFY(output.contains("PREFIX: qDebug")); +} + +QTEST_MAIN(tst_qmessagehandler) +#include "tst_qlogging.moc" diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.pro b/tests/auto/corelib/global/qlogging/tst_qlogging.pro new file mode 100644 index 00000000000..60377e0fdc9 --- /dev/null +++ b/tests/auto/corelib/global/qlogging/tst_qlogging.pro @@ -0,0 +1,4 @@ +CONFIG += testcase parallel_test +TARGET = tst_qlogging +QT = core testlib +SOURCES = tst_qlogging.cpp diff --git a/tests/auto/corelib/global/qmessagehandler/qmessagehandler.pro b/tests/auto/corelib/global/qmessagehandler/qmessagehandler.pro deleted file mode 100644 index 8bdba4bfc42..00000000000 --- a/tests/auto/corelib/global/qmessagehandler/qmessagehandler.pro +++ /dev/null @@ -1,4 +0,0 @@ -CONFIG += testcase parallel_test -TARGET = tst_qmessagehandler -QT = core testlib -SOURCES = tst_qmessagehandler.cpp diff --git a/tests/auto/corelib/global/qmessagehandler/tst_qmessagehandler.cpp b/tests/auto/corelib/global/qmessagehandler/tst_qmessagehandler.cpp deleted file mode 100644 index 39bd0986a5e..00000000000 --- a/tests/auto/corelib/global/qmessagehandler/tst_qmessagehandler.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the test suite 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 -#include - -#include - -class tst_qmessagehandler : public QObject -{ - Q_OBJECT -private slots: - void cleanup(); - - void defaultHandler(); - void installMessageHandler(); - void installMsgHandler(); - void installBothHandler(); -}; - -static QtMsgType s_type; -const char *s_file; -int s_line; -const char *s_function; -static QString s_message; - -void customMessageHandler(QtMsgType type, const QMessageLogContext &context, const char *msg) -{ - s_type = type; - s_file = context.file; - s_line = context.line; - s_function = context.function; - s_message = QString::fromLocal8Bit(msg); -} - -void customMsgHandler(QtMsgType type, const char *msg) -{ - s_type = type; - s_file = 0; - s_line = 0; - s_function = 0; - s_message = QString::fromLocal8Bit(msg); -} - -void tst_qmessagehandler::cleanup() -{ - qInstallMsgHandler(0); - qInstallMessageHandler(0); - s_type = QtFatalMsg; - s_file = 0; - s_line = 0; - s_function = 0; -} - -void tst_qmessagehandler::defaultHandler() -{ - // check that the default works - QTest::ignoreMessage(QtDebugMsg, "defaultHandler"); - qDebug("defaultHandler"); -} - -void tst_qmessagehandler::installMessageHandler() -{ - QMessageHandler oldHandler = qInstallMessageHandler(customMessageHandler); - - qDebug("installMessageHandler"); int line = __LINE__; - - QCOMPARE(s_type, QtDebugMsg); - QCOMPARE(s_message, QString::fromLocal8Bit("installMessageHandler")); - QCOMPARE(s_file, __FILE__); - QCOMPARE(s_function, Q_FUNC_INFO); - QCOMPARE(s_line, line); - - QMessageHandler myHandler = qInstallMessageHandler(oldHandler); - QCOMPARE((void*)myHandler, (void*)customMessageHandler); -} - -void tst_qmessagehandler::installMsgHandler() -{ - QtMsgHandler oldHandler = qInstallMsgHandler(customMsgHandler); - - qDebug("installMsgHandler"); - - QCOMPARE(s_type, QtDebugMsg); - QCOMPARE(s_message, QString::fromLocal8Bit("installMsgHandler")); - QCOMPARE(s_file, (const char*)0); - QCOMPARE(s_function, (const char*)0); - QCOMPARE(s_line, 0); - - QtMsgHandler myHandler = qInstallMsgHandler(oldHandler); - QCOMPARE((void*)myHandler, (void*)customMsgHandler); -} - -void tst_qmessagehandler::installBothHandler() -{ - qInstallMessageHandler(customMessageHandler); - qInstallMsgHandler(customMsgHandler); - - qDebug("installBothHandler"); int line = __LINE__; - - QCOMPARE(s_type, QtDebugMsg); - QCOMPARE(s_message, QString::fromLocal8Bit("installBothHandler")); - QCOMPARE(s_file, __FILE__); - QCOMPARE(s_function, Q_FUNC_INFO); - QCOMPARE(s_line, line); -} - -QTEST_MAIN(tst_qmessagehandler) -#include "tst_qmessagehandler.moc" diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index d39d9b45cc4..f68e3c0e54e 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -46,6 +46,7 @@ HEADERS = configureapp.h environment.h tools.h\ $$QT_SOURCE_TREE/src/corelib/codecs/qtextcodec.h \ $$QT_SOURCE_TREE/src/corelib/global/qglobal.h \ $$QT_SOURCE_TREE/src/corelib/global/qnumeric.h \ + $$QT_SOURCE_TREE/src/corelib/global/qlogging.h \ $$QT_SOURCE_TREE/src/corelib/io/qbuffer.h \ $$QT_SOURCE_TREE/src/corelib/io/qdatastream.h \ $$QT_SOURCE_TREE/src/corelib/io/qdir.h \ @@ -89,6 +90,7 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \ $$QT_SOURCE_TREE/src/corelib/codecs/qtextcodec.cpp \ $$QT_SOURCE_TREE/src/corelib/global/qglobal.cpp \ $$QT_SOURCE_TREE/src/corelib/global/qnumeric.cpp \ + $$QT_SOURCE_TREE/src/corelib/global/qlogging.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qbuffer.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qdatastream.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qdir.cpp \ From 41914453d38d01b9b69e16ccee69444d1a304bf7 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 9 Feb 2012 13:46:28 +0100 Subject: [PATCH 117/406] Introduce QScreen::grabWindow(), deprecate QPixmap::grabWindow(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WId can be local to a screen. Change-Id: I09ca71313836a34dbf33289b254c80207a956bb1 Reviewed-by: Samuel Rødal --- src/gui/image/image.pri | 1 - src/gui/image/qpixmap.cpp | 13 +++++++++ src/gui/image/qpixmap_qpa.cpp | 53 ----------------------------------- src/gui/kernel/qscreen.cpp | 48 +++++++++++++++++++++++++++++++ src/gui/kernel/qscreen.h | 3 ++ 5 files changed, 64 insertions(+), 54 deletions(-) delete mode 100644 src/gui/image/qpixmap_qpa.cpp diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri index dd7b665ecce..f83e7e60c9d 100644 --- a/src/gui/image/image.pri +++ b/src/gui/image/image.pri @@ -45,7 +45,6 @@ SOURCES += \ image/qimagepixmapcleanuphooks.cpp \ image/qvolatileimage.cpp -SOURCES += image/qpixmap_qpa.cpp win32: SOURCES += image/qpixmap_win.cpp SOURCES += image/qvolatileimagedata.cpp diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index f1a06fa33c0..16945edc90a 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1613,9 +1613,22 @@ QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionF \warning In general, grabbing an area outside the screen is not safe. This depends on the underlying window system. + \warning The function is deprecated in Qt 5.0 since there might be + platform plugins in which window system identifiers (\c WId) + are local to a screen. Use QScreen::grabWindow() instead. + \sa grabWidget(), {Screenshot Example} + \sa QScreen + \deprecated */ +QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h) +{ + qWarning("%s is deprecated, use QScreen::grabWindow() instead." + " Defaulting to primary screen.", Q_FUNC_INFO); + return QGuiApplication::primaryScreen()->grabWindow(window, x, y, w, h); +} + /*! \internal */ diff --git a/src/gui/image/qpixmap_qpa.cpp b/src/gui/image/qpixmap_qpa.cpp deleted file mode 100644 index 162c5f52869..00000000000 --- a/src/gui/image/qpixmap_qpa.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtGui 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 -#include -#include - -QT_BEGIN_NAMESPACE - -QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h) -{ - return QGuiApplication::primaryScreen()->handle()->grabWindow(window, x, y, w, h); -} - -QT_END_NAMESPACE diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp index 67eb991b199..da0716b7d5d 100644 --- a/src/gui/kernel/qscreen.cpp +++ b/src/gui/kernel/qscreen.cpp @@ -41,6 +41,7 @@ #include "qscreen.h" #include "qscreen_p.h" +#include "qpixmap.h" #include "qplatformscreen_qpa.h" #include @@ -542,4 +543,51 @@ void QScreenPrivate::updatePrimaryOrientation() primaryOrientation = geometry.width() >= geometry.height() ? Qt::LandscapeOrientation : Qt::PortraitOrientation; } +/*! + Creates and returns a pixmap constructed by grabbing the contents + of the given \a window restricted by QRect(\a x, \a y, \a width, + \a height). + + The arguments (\a{x}, \a{y}) specify the offset in the window, + whereas (\a{width}, \a{height}) specify the area to be copied. If + \a width is negative, the function copies everything to the right + border of the window. If \a height is negative, the function + copies everything to the bottom of the window. + + The window system identifier (\c WId) can be retrieved using the + QWidget::winId() function. The rationale for using a window + identifier and not a QWidget, is to enable grabbing of windows + that are not part of the application, window system frames, and so + on. + + The grabWindow() function grabs pixels from the screen, not from + the window, i.e. if there is another window partially or entirely + over the one you grab, you get pixels from the overlying window, + too. The mouse cursor is generally not grabbed. + + Note on X11 that if the given \a window doesn't have the same depth + as the root window, and another window partially or entirely + obscures the one you grab, you will \e not get pixels from the + overlying window. The contents of the obscured areas in the + pixmap will be undefined and uninitialized. + + On Windows Vista and above grabbing a layered window, which is + created by setting the Qt::WA_TranslucentBackground attribute, will + not work. Instead grabbing the desktop widget should work. + + \warning In general, grabbing an area outside the screen is not + safe. This depends on the underlying window system. + \since 5.0 +*/ + +QPixmap QScreen::grabWindow(WId window, int x, int y, int w, int h) const +{ + const QPlatformScreen *platformScreen = handle(); + if (!platformScreen) { + qWarning("%s invoked with handle==0", Q_FUNC_INFO); + return QPixmap(); + } + return platformScreen->grabWindow(window, x, y, w, h); +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h index f73cd0836f7..111e10d340d 100644 --- a/src/gui/kernel/qscreen.h +++ b/src/gui/kernel/qscreen.h @@ -61,6 +61,7 @@ class QPlatformScreen; class QScreenPrivate; class QWindow; class QRect; +class QPixmap; class Q_GUI_EXPORT QScreen : public QObject { @@ -124,6 +125,8 @@ public: bool isPortrait(Qt::ScreenOrientation orientation); bool isLandscape(Qt::ScreenOrientation orientation); + QPixmap grabWindow(WId window, int x, int y, int w, int h) const; + Q_SIGNALS: void sizeChanged(const QSize &size); void geometryChanged(const QRect &geometry); From af93c70de72f6bcea948b43e8f7bf50dad8face3 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 30 Jan 2012 15:29:56 +0100 Subject: [PATCH 118/406] consolidate Read* options this brings some clarity which combinations are actually possible, which allows for some optimization later on. Change-Id: I930027e426c5f9abea8d21eb1ebaa39bd29787b8 Reviewed-by: Joerg Bornemann --- qmake/project.cpp | 14 +++++++------- qmake/project.h | 3 +-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/qmake/project.cpp b/qmake/project.cpp index fbeb033b866..f8b24bb0976 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -1284,7 +1284,7 @@ QMakeProject::read(uchar cmd) if(!Option::user_template_prefix.isEmpty()) base_vars["TEMPLATE_PREFIX"] = QStringList(Option::user_template_prefix); - if(cmd & ReadCache && Option::mkfile::do_cache) { // parse the cache + if ((cmd & ReadSetup) && Option::mkfile::do_cache) { // parse the cache int cache_depth = -1; QString qmake_cache = Option::mkfile::cachefile; if(qmake_cache.isEmpty()) { //find it as it has not been specified @@ -1315,7 +1315,7 @@ QMakeProject::read(uchar cmd) } } } - if(cmd & ReadConf) { // parse mkspec + if (cmd & ReadSetup) { // parse mkspec QString qmakespec = fixEnvVariables(Option::mkfile::qmakespec); QStringList mkspec_roots = qmake_mkspec_paths(); debug_msg(2, "Looking for mkspec %s in (%s)", qmakespec.toLatin1().constData(), @@ -1389,7 +1389,7 @@ QMakeProject::read(uchar cmd) vars["TARGET"].append(QFileInfo(pfile).baseName()); //before commandline - if(cmd & ReadCmdLine) { + if (cmd & ReadSetup) { cfile = pfile; parser.file = "(internal)"; parser.from_file = false; @@ -1406,7 +1406,7 @@ QMakeProject::read(uchar cmd) } //commandline configs - if(cmd & ReadConfigs && !Option::user_configs.isEmpty()) { + if ((cmd & ReadSetup) && !Option::user_configs.isEmpty()) { parser.file = "(configs)"; parser.from_file = false; parser.line_no = 1; //really arg count now.. duh @@ -1421,7 +1421,7 @@ QMakeProject::read(uchar cmd) return false; } - if(cmd & ReadCmdLine) { + if (cmd & ReadSetup) { parser.file = "(internal)"; parser.from_file = false; parser.line_no = 1; //really arg count now.. duh @@ -1437,7 +1437,7 @@ QMakeProject::read(uchar cmd) } //after configs (set in BUILDS) - if(cmd & ReadConfigs && !Option::after_user_configs.isEmpty()) { + if ((cmd & ReadSetup) && !Option::after_user_configs.isEmpty()) { parser.file = "(configs)"; parser.from_file = false; parser.line_no = 1; //really arg count now.. duh @@ -1447,7 +1447,7 @@ QMakeProject::read(uchar cmd) if(pfile != "-" && vars["TARGET"].isEmpty()) vars["TARGET"].append(QFileInfo(pfile).baseName()); - if(cmd & ReadConfigs && !Option::user_configs.isEmpty()) { + if ((cmd & ReadSetup) && !Option::user_configs.isEmpty()) { parser.file = "(configs)"; parser.from_file = false; parser.line_no = 1; //really arg count now.. duh diff --git a/qmake/project.h b/qmake/project.h index 83174455d12..7a9cc1eae4b 100644 --- a/qmake/project.h +++ b/qmake/project.h @@ -117,8 +117,7 @@ public: QMakeProject(QMakeProperty *p, const QHash &nvars) { init(p, &nvars); } ~QMakeProject(); - enum { ReadCache=0x01, ReadConf=0x02, ReadCmdLine=0x04, ReadProFile=0x08, - ReadFeatures=0x20, ReadConfigs=0x40, ReadAll=0xFF }; + enum { ReadProFile=0x01, ReadSetup=0x02, ReadFeatures=0x04, ReadAll=0xFF }; inline bool parse(const QString &text) { return parse(text, vars); } bool read(const QString &project, uchar cmd=ReadAll); bool read(uchar cmd=ReadAll); From 0678a7db8e8eb6997b0acb106dd4347ef8c76fbe Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 8 Feb 2012 10:21:28 +0100 Subject: [PATCH 119/406] remove bizarre magic from precompiled header it doesn't serve any puropse (any more?) and it breaks the mingw build. Change-Id: I02a5e7502586e7e9f5956991498ff602eff66e81 Reviewed-by: Joerg Bornemann --- tools/configure/configure_pch.h | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/tools/configure/configure_pch.h b/tools/configure/configure_pch.h index 6f601c7c297..0831364fe15 100644 --- a/tools/configure/configure_pch.h +++ b/tools/configure/configure_pch.h @@ -39,34 +39,11 @@ ** ****************************************************************************/ -#if (defined(_WIN32) || defined(__NT__)) -# define QT_UNDEF_MACROS_IN_PCH -# define _WINSCARD_H_ -# define _POSIX_ /* Make sure PATH_MAX et al. are defined */ -# include -# undef _POSIX_ /* Don't polute */ - - /* Make sure IP v6 is defined first of all, before windows.h */ -# include -# include -#endif - -#if defined __cplusplus +#include #include #include #include // All moc genereated code has this include -#include #include #include #include #include - -#include -#include -#endif - -#if defined(QT_UNDEF_MACROS_IN_PCH) -# undef max /* These are defined in windef.h, but */ -# undef min /* we don't want them when building Qt */ -# undef _WINSCARD_H_ -#endif From 2b969b89b95317f04bd562aee3528cab227e57b8 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 8 Feb 2012 10:55:49 +0100 Subject: [PATCH 120/406] add missing errno.h include it was masked by the precompiled header Change-Id: I9ba7b0faa716cfa6844b9a9f81fa2a3aa67f5da4 Reviewed-by: Joerg Bornemann --- tools/configure/environment.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/configure/environment.cpp b/tools/configure/environment.cpp index 5e0fa00c6cd..80542e76975 100644 --- a/tools/configure/environment.cpp +++ b/tools/configure/environment.cpp @@ -42,6 +42,7 @@ #include "environment.h" #include +#include #include #include #include From 2091d4c33a0f20e44f64ecf9953bb7725ceed287 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 9 Feb 2012 18:40:26 +0100 Subject: [PATCH 121/406] build with QT_NO_GEOM_VARIANT saves us some pointless code Change-Id: I24e4fe4107f44ab579c0f951551c4138713a749f Reviewed-by: Joerg Bornemann --- tools/configure/configure.pro | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index f68e3c0e54e..8819fef576a 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -3,7 +3,7 @@ DESTDIR = $$PWD/../.. # build directly in source dir CONFIG += console flat CONFIG -= moc qt -DEFINES = UNICODE QT_NODLL QT_NO_CODECS QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_LITE_COMPONENT QT_NO_STL QT_NO_COMPRESS QT_NO_THREAD QT_NO_QOBJECT _CRT_SECURE_NO_DEPRECATE +DEFINES = UNICODE QT_NODLL QT_NO_CODECS QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_LITE_COMPONENT QT_NO_STL QT_NO_COMPRESS QT_NO_THREAD QT_NO_QOBJECT QT_NO_GEOM_VARIANT _CRT_SECURE_NO_DEPRECATE DEFINES += QT_BOOTSTRAPPED win32 : LIBS += -lole32 -ladvapi32 @@ -121,10 +121,6 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \ $$QT_SOURCE_TREE/src/corelib/kernel/qvariant.cpp \ $$QT_SOURCE_TREE/src/corelib/kernel/qsystemerror.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qurl.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qline.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qsize.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qpoint.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qrect.cpp \ $$QT_SOURCE_TREE/src/corelib/kernel/qmetatype.cpp \ $$QT_SOURCE_TREE/src/corelib/global/qmalloc.cpp \ $$QT_SOURCE_TREE/src/corelib/xml/qxmlstream.cpp \ From cb03577711a7dddd6444c0f6114fbf3785552353 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 9 Feb 2012 18:41:21 +0100 Subject: [PATCH 122/406] properly enable stl via qmake instead of hacking compiler flags Change-Id: I2c037c9a28043afe53167a766bce7c9d09b8f3a3 Reviewed-by: Joerg Bornemann --- tools/configure/configure.pro | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index 8819fef576a..6e0571c5b86 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -1,13 +1,12 @@ TARGET = configure DESTDIR = $$PWD/../.. # build directly in source dir -CONFIG += console flat +CONFIG += console flat stl CONFIG -= moc qt DEFINES = UNICODE QT_NODLL QT_NO_CODECS QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_LITE_COMPONENT QT_NO_STL QT_NO_COMPRESS QT_NO_THREAD QT_NO_QOBJECT QT_NO_GEOM_VARIANT _CRT_SECURE_NO_DEPRECATE DEFINES += QT_BOOTSTRAPPED win32 : LIBS += -lole32 -ladvapi32 -win32-msvc.net | win32-msvc2* : QMAKE_CXXFLAGS += /EHsc win32-g++* : LIBS += -luuid win32-msvc* { From 946501ab350f0c3dbaf163c03415f459efb8c6bd Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 9 Feb 2012 18:43:14 +0100 Subject: [PATCH 123/406] remove pointless include paths we rely on a syncqt'd tree anyway Change-Id: I23b288b98a5e9289993b058f7dce02e19564c67a Reviewed-by: Joerg Bornemann --- tools/configure/configure.pro | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index 6e0571c5b86..6dd37233a36 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -25,8 +25,6 @@ win32-msvc* { PRECOMPILED_HEADER = configure_pch.h INCLUDEPATH += \ - $$QT_SOURCE_TREE/src/corelib/arch/generic \ - $$QT_SOURCE_TREE/src/corelib/global \ $$QT_BUILD_TREE/include \ $$QT_BUILD_TREE/include/QtCore \ $$QT_BUILD_TREE/include/QtCore/$$QT.core.VERSION \ @@ -129,7 +127,3 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \ $$QT_SOURCE_TREE/tools/shared/windows/registry.cpp DEFINES += COMMERCIAL_VERSION - -INCLUDEPATH += $$QT_SOURCE_TREE/src/corelib/arch/generic \ - $$QT_SOURCE_TREE/include/QtCore \ - $$QT_SOURCE_TREE/tools/shared From dc810b81a38a2a4d33f6909ff213809e1bf384ca Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 9 Feb 2012 18:47:37 +0100 Subject: [PATCH 124/406] compile without rtti no point in it Change-Id: Id6ad95c197095131c6c100afe37b3d48adb157d1 Reviewed-by: Joerg Bornemann --- tools/configure/configure.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index 6dd37233a36..b0224891c3c 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -1,7 +1,7 @@ TARGET = configure DESTDIR = $$PWD/../.. # build directly in source dir -CONFIG += console flat stl +CONFIG += console flat stl rtti_off CONFIG -= moc qt DEFINES = UNICODE QT_NODLL QT_NO_CODECS QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_LITE_COMPONENT QT_NO_STL QT_NO_COMPRESS QT_NO_THREAD QT_NO_QOBJECT QT_NO_GEOM_VARIANT _CRT_SECURE_NO_DEPRECATE DEFINES += QT_BOOTSTRAPPED From 2b42987d0ad46e0d51088bf7787316d9e66a1f81 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Tue, 7 Feb 2012 10:07:48 +0100 Subject: [PATCH 125/406] Dont build printer support for Windows CE. Windows CE has no printing support, so we can disable this. Change-Id: I0ec83dff2d045de56d613cd676e9eb290145bf41 Reviewed-by: Friedemann Kleint Reviewed-by: Stephen Kelly --- src/src.pro | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/src.pro b/src/src.pro index 9ef8bf43628..f3f6937c506 100644 --- a/src/src.pro +++ b/src/src.pro @@ -5,7 +5,8 @@ unset(SRC_SUBDIRS) win32:SRC_SUBDIRS += src_winmain !wince*:include(tools/tools.pro) SRC_SUBDIRS += src_corelib -SRC_SUBDIRS += src_network src_sql src_gui src_xml src_widgets src_printsupport src_testlib src_platformsupport +SRC_SUBDIRS += src_network src_sql src_gui src_xml src_widgets src_testlib src_platformsupport +!wince*:SRC_SUBDIRS += src_printsupport nacl: SRC_SUBDIRS -= src_network src_testlib contains(QT_CONFIG, dbus):SRC_SUBDIRS += src_dbus contains(QT_CONFIG, concurrent):SRC_SUBDIRS += src_concurrent @@ -35,8 +36,10 @@ src_plugins.subdir = $$QT_SOURCE_TREE/src/plugins src_plugins.target = sub-plugins src_widgets.subdir = $$QT_SOURCE_TREE/src/widgets src_widgets.target = sub-widgets -src_printsupport.subdir = $$QT_SOURCE_TREE/src/printsupport -src_printsupport.target = sub-printsupport +!wince*: { + src_printsupport.subdir = $$QT_SOURCE_TREE/src/printsupport + src_printsupport.target = sub-printsupport +} src_testlib.subdir = $$QT_SOURCE_TREE/src/testlib src_testlib.target = sub-testlib src_platformsupport.subdir = $$QT_SOURCE_TREE/src/platformsupport From 73a5bc2aac7638438dfde260a4246359a06e89ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lund=20Martsum?= Date: Fri, 3 Feb 2012 20:02:46 +0100 Subject: [PATCH 126/406] QHeaderView - minor bug in visualIndexAt This fixes a minor bug in VisualIndex triggered when calling resizeSection with size 0 (but not hideSection). It is mostly cosmetics - however hopefully there will soon be a minor refactoring and there is really no need to make strange code to keep a semantic bug. However it is also doubtful to make a semantic change while refactoring. Change-Id: Ide153e421fd7a634062cb74867f4a49da4bf9cd6 Reviewed-by: Stephen Kelly --- src/widgets/itemviews/qheaderview.cpp | 4 +-- .../itemviews/qheaderview/tst_qheaderview.cpp | 33 ++++++++++++------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 33c8da4f698..85d9ff0ce61 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -3496,8 +3496,8 @@ int QHeaderViewPrivate::headerVisualIndexAt(int position) const const QHeaderViewPrivate::SectionSpan ¤tSection = sectionSpans.at(i); int next_span_start_section = span_start_section + currentSection.count; int next_span_position = span_position + currentSection.size; - if (position == span_position) - return span_start_section; // spans with no size + if (position == span_position && currentSection.size > 0) + return span_start_section; if (position > span_position && position < next_span_position) { int position_in_span = position - span_position; return span_start_section + (position_in_span / currentSection.sectionSize()); diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index 75a72a754f7..4089768e7a4 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -204,6 +204,7 @@ private slots: void QTBUG8650_crashOnInsertSections(); void QTBUG12268_hiddenMovedSectionSorting(); void QTBUG14242_hideSectionAutoSize(); + void ensureNoIndexAtLength(); void initialSortOrderRole(); @@ -2156,6 +2157,17 @@ void tst_QHeaderView::QTBUG14242_hideSectionAutoSize() QVERIFY(calced_length == afterlength); } +void tst_QHeaderView::ensureNoIndexAtLength() +{ + QTableView qtv; + QStandardItemModel amodel(4, 4); + qtv.setModel(&amodel); + QHeaderView *hv = qtv.verticalHeader(); + QVERIFY(hv->visualIndexAt(hv->length()) == -1); + hv->resizeSection(hv->count() - 1, 0); + QVERIFY(hv->visualIndexAt(hv->length()) == -1); +} + void tst_QHeaderView::initialSortOrderRole() { QTableView view; // ### Shadowing member view (of type QHeaderView) @@ -2341,8 +2353,8 @@ void tst_QHeaderView::calculateAndCheck(int cppline, const int precalced_compare QVERIFY2(chk_logical == x[1], verifytext); QVERIFY2(chk_sizes == x[2], verifytext); QVERIFY2(chk_hidden_size == x[3], verifytext); - QVERIFY2(chk_lookup_visual == x[4], verifytext); // Here the semantic can change. See final note (*). - QVERIFY2(chk_lookup_logical == x[5], verifytext); // Here the semantic can change. See final note (*). + QVERIFY2(chk_lookup_visual == x[4], verifytext); + QVERIFY2(chk_lookup_logical == x[5], verifytext); QVERIFY2(header_lenght == x[6], verifytext); } @@ -2438,10 +2450,10 @@ void tst_QHeaderView::logicalIndexAtTest() //qDebug() << "logicalIndexAtTest" << check1 << check2; const int precalced_check1 = 106327; const int precalced_check2 = 29856418; - QVERIFY(precalced_check1 == check1); // Here the semantic can change. See final note (*) - QVERIFY(precalced_check2 == check2); // Here the semantic can change. See final note (*) + QVERIFY(precalced_check1 == check1); + QVERIFY(precalced_check2 == check2); - const int precalced_results[] = { 1145298384, -1710423344, -650981936, 372919464, 2139446944, 854793816, 12124 }; + const int precalced_results[] = { 1145298384, -1710423344, -650981936, 372919464, -1544372176, -426463328, 12124 }; calculateAndCheck(__LINE__, precalced_results); } @@ -2466,10 +2478,10 @@ void tst_QHeaderView::visualIndexAtTest() //qDebug() << "visualIndexAtTest" << check1 << check2; const int precalced_check1 = 72665; const int precalced_check2 = 14015890; - QVERIFY(precalced_check1 == check1); // Here the semantic can change. See final note (*) - QVERIFY(precalced_check2 == check2); // Here the semantic can change. See final note (*) + QVERIFY(precalced_check1 == check1); + QVERIFY(precalced_check2 == check2); - const int precalced_results[] = { 1145298384, -1710423344, -1457520212, 169223959, 726651072, -2105938696, 5453 }; + const int precalced_results[] = { 1145298384, -1710423344, -1457520212, 169223959, 557466160, -324939600, 5453 }; calculateAndCheck(__LINE__, precalced_results); } @@ -2598,7 +2610,7 @@ void tst_QHeaderView::mixedTests() model->setRowCount(model->rowCount() - 10); if (m_using_reset_model) { - const int precalced_results[] = { 898296472, 337096378, -543340640, 1, 703951756, 250831536, 9250 }; + const int precalced_results[] = { 898296472, 337096378, -543340640, 1, -1251526424, -568618976, 9250 }; calculateAndCheck(__LINE__, precalced_results); } else { const int precalced_results[] = { 1911338224, 1693514365, -613398968, -1912534953, 1582159424, -1851079000, 9300 }; @@ -2633,8 +2645,5 @@ void tst_QHeaderView::resizeToContentTest() calculateAndCheck(__LINE__, precalced_results); } -// (*) Currently qheaderview position lookup acts a bit strange. It can return sections with size 0. -// This could be changed in the future. - QTEST_MAIN(tst_QHeaderView) #include "tst_qheaderview.moc" From 0abc98847d4e7c51486aabcac8b9fa59a7361d13 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Thu, 9 Feb 2012 08:41:25 +0100 Subject: [PATCH 127/406] Compile fix QWindowsMobileStyle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Idb3f8b3cb19b0ed1f49245fa7e43f26f6faa174d Reviewed-by: João Abecasis Reviewed-by: Olivier Goffart --- src/widgets/styles/qwindowsmobilestyle_p.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/widgets/styles/qwindowsmobilestyle_p.h b/src/widgets/styles/qwindowsmobilestyle_p.h index 0e5cf18548e..3efbe535c27 100644 --- a/src/widgets/styles/qwindowsmobilestyle_p.h +++ b/src/widgets/styles/qwindowsmobilestyle_p.h @@ -62,7 +62,6 @@ QT_BEGIN_NAMESPACE class QStyleOptionTab; class QStyleOptionSlider; -class QStyleOptionViewItemV4; class QWindowsMobileStylePrivate : public QWindowsStylePrivate { From cd2a2251d1a739b5d84f2543c280cf399eba47d0 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 23 Jan 2012 15:04:53 +0100 Subject: [PATCH 128/406] make locateSyncProfile() a "tad" less convoluted Change-Id: I261b6c6b42bed576edb8a1d8420da19d34bd87a1 Reviewed-by: Marius Storm-Olsen Reviewed-by: Joerg Bornemann --- bin/syncqt | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/bin/syncqt b/bin/syncqt index 15814df3f9c..07b9d2432eb 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -607,22 +607,14 @@ sub loadSyncProfile { sub locateSyncProfile { my ($directory) = @_; - my $syncprofile; $directory = abs_path($directory); - while(!defined $syncprofile) { - local(*D); - if (opendir(D, $directory)) { - foreach my $file (sort readdir(D)) { - next if ($file =~ /^\.\.?$/); - $syncprofile = "$directory/$file" if ($file =~ /^sync\.profile$/); - last if (defined $syncprofile); - } - closedir(D); - } - last if (defined $syncprofile || $directory eq "/" || $directory =~ /^?:[\/\\]$/); + while (1) { + my $file = $directory."/sync.profile"; + return $file if (-e $file); + my $odir = $directory; $directory = dirname($directory); + return undef if ($directory eq $odir); } - return $syncprofile; } # check if this is an in-source build, and if so use that as the basedir too From c6a1cb701ce1a973d9c950161d72db0e7f9a6b7c Mon Sep 17 00:00:00 2001 From: jian liang Date: Sat, 4 Feb 2012 19:53:54 +0800 Subject: [PATCH 129/406] Improvement to font database cleanup This patch do the following things: 1) Call QFontDatabasePrivate::free() to clean up font database before destroying the platform integration object. This is to prevent object leak which is allocated by platform plugin. 2) Allocate FontFile structure for each font registered in windows platform to prevent double free of FontFile structure. 3) qt_registerFont() will release the old handle of the registered font and replace it with the new handle. This is to prevent FontFont structure leak. Change-Id: Ib5ca20c695e1e365689fd8554f7caff6ee77a0b1 Reviewed-by: Jiang Jiang --- src/gui/kernel/qguiapplication.cpp | 4 ++ src/gui/text/qfontdatabase.cpp | 10 ++++- src/gui/text/qfontdatabase_qpa.cpp | 43 +++++++++++-------- .../windows/qwindowsfontdatabase_ft.cpp | 31 +++++++------ 4 files changed, 56 insertions(+), 32 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index b1cbb5fcaec..d41c90636bc 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -502,6 +502,8 @@ void QGuiApplicationPrivate::init() QWindowSystemInterface::sendWindowSystemEvents(QCoreApplicationPrivate::eventDispatcher, QEventLoop::AllEvents); } +extern void qt_cleanupFontDatabase(); + QGuiApplicationPrivate::~QGuiApplicationPrivate() { is_app_closing = true; @@ -526,6 +528,8 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate() delete styleHints; delete inputMethod; + qt_cleanupFontDatabase(); + delete platform_integration; platform_integration = 0; } diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index e9b7d1a1dd8..be8c1c0bb1b 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -196,7 +196,7 @@ struct QtFontStyle // bitfield count-- in while condition does not work correctly in mwccsym2 count--; QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration(); - if (integration) { //on shut down there will be some that we don't release. + if (integration) { integration->fontDatabase()->releaseHandle(pixelSizes[count].handle); } } @@ -796,6 +796,14 @@ static QStringList familyList(const QFontDef &req) Q_GLOBAL_STATIC(QFontDatabasePrivate, privateDb) Q_GLOBAL_STATIC_WITH_ARGS(QMutex, fontDatabaseMutex, (QMutex::Recursive)) +// used in qguiapplication.cpp +void qt_cleanupFontDatabase() +{ + QFontDatabasePrivate *db = privateDb(); + if (db) + db->free(); +} + // used in qfontengine_x11.cpp QMutex *qt_fontdatabase_mutex() { diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp index 266ad4d453e..c3d7529c2e9 100644 --- a/src/gui/text/qfontdatabase_qpa.cpp +++ b/src/gui/text/qfontdatabase_qpa.cpp @@ -58,28 +58,33 @@ Q_GUI_EXPORT void qt_registerFont(const QString &familyName, const QString &fou const QSupportedWritingSystems &writingSystems, void *handle) { QFontDatabasePrivate *d = privateDb(); - // qDebug() << "Adding font" << familyName << weight << style << pixelSize << antialiased; - QtFontStyle::Key styleKey; - styleKey.style = style; - styleKey.weight = weight; - styleKey.stretch = stretch; - QtFontFamily *f = d->family(familyName, true); - f->fixedPitch = fixedPitch; +// qDebug() << "Adding font" << familyName << weight << style << pixelSize << antialiased; + QtFontStyle::Key styleKey; + styleKey.style = style; + styleKey.weight = weight; + styleKey.stretch = stretch; + QtFontFamily *f = d->family(familyName, true); + f->fixedPitch = fixedPitch; - for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) { - if (writingSystems.supported(QFontDatabase::WritingSystem(i))) { - f->writingSystems[i] = QtFontFamily::Supported; - } else { - f->writingSystems[i] = QtFontFamily::Unsupported; - } + for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) { + if (writingSystems.supported(QFontDatabase::WritingSystem(i))) { + f->writingSystems[i] = QtFontFamily::Supported; + } else { + f->writingSystems[i] = QtFontFamily::Unsupported; } + } - QtFontFoundry *foundry = f->foundry(foundryname, true); - QtFontStyle *fontStyle = foundry->style(styleKey, QString(), true); - fontStyle->smoothScalable = scalable; - fontStyle->antialiased = antialiased; - QtFontSize *size = fontStyle->pixelSize(pixelSize?pixelSize:SMOOTH_SCALABLE, true); - size->handle = handle; + QtFontFoundry *foundry = f->foundry(foundryname, true); + QtFontStyle *fontStyle = foundry->style(styleKey, QString(), true); + fontStyle->smoothScalable = scalable; + fontStyle->antialiased = antialiased; + QtFontSize *size = fontStyle->pixelSize(pixelSize ? pixelSize : SMOOTH_SCALABLE, true); + if (size->handle) { + QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration(); + if (integration) + integration->fontDatabase()->releaseHandle(size->handle); + } + size->handle = handle; } static QStringList fallbackFamilies(const QString &family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index f397e9cb922..8455e9e6d0f 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -100,6 +100,14 @@ static inline QFont::Weight weightFromInteger(long weight) return QFont::Black; } +static FontFile * createFontFile(const QString &fileName, int index) +{ + FontFile *fontFile = new FontFile; + fontFile->fileName = fileName; + fontFile->indexValue = index; + return fontFile; +} + static bool addFontToDatabase(QString familyName, const QString &scriptName, const TEXTMETRIC *textmetric, const FONTSIGNATURE *signature, @@ -212,23 +220,22 @@ static bool addFontToDatabase(QString familyName, const QString &scriptName, if (!QDir::isAbsolutePath(value)) value.prepend(QString::fromLocal8Bit(qgetenv("windir") + "\\Fonts\\")); - // Pointer is deleted in QBasicFontDatabase::releaseHandle(void *handle) - FontFile *fontFile = new FontFile; - fontFile->fileName = value; - fontFile->indexValue = index; + QPlatformFontDatabase::registerFont(faceName, foundryName, weight, style, stretch, + antialias, scalable, size, fixed, writingSystems, createFontFile(value, index)); - QPlatformFontDatabase::registerFont(faceName, foundryName, weight, - style, stretch, antialias, scalable, size, fixed, writingSystems, fontFile); // add fonts windows can generate for us: if (weight <= QFont::DemiBold) - QPlatformFontDatabase::registerFont(faceName, foundryName, QFont::Bold, - style, stretch, antialias, scalable, size, fixed, writingSystems, fontFile); + QPlatformFontDatabase::registerFont(faceName, foundryName, QFont::Bold, style, stretch, + antialias, scalable, size, fixed, writingSystems, createFontFile(value, index)); + if (style != QFont::StyleItalic) - QPlatformFontDatabase::registerFont(faceName, foundryName, weight, - QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, fontFile); + QPlatformFontDatabase::registerFont(faceName, foundryName, weight, QFont::StyleItalic, stretch, + antialias, scalable, size, fixed, writingSystems, createFontFile(value, index)); + if (weight <= QFont::DemiBold && style != QFont::StyleItalic) - QPlatformFontDatabase::registerFont(faceName, foundryName, QFont::Bold, - QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, fontFile); + QPlatformFontDatabase::registerFont(faceName, foundryName, QFont::Bold, QFont::StyleItalic, stretch, + antialias, scalable, size, fixed, writingSystems, createFontFile(value, index)); + return true; } From 8522cb5c97e092d83484768152704f7d9a69901d Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 9 Feb 2012 11:21:18 +0100 Subject: [PATCH 130/406] Update docs for QAccessibleEvent. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This class completely changed, the old docs were still around. Change-Id: Ice7b106b33ffc60f45f7af1b4f44dc01462ee0da Reviewed-by: Jan-Arve Sæther --- src/gui/accessible/qaccessible.cpp | 56 ++++++------------------------ 1 file changed, 10 insertions(+), 46 deletions(-) diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index b45c7e8d845..dd0468d9f98 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -1158,60 +1158,24 @@ QColor QAccessibleInterface::backgroundColor() const /*! \class QAccessibleEvent - \internal + \brief The QAccessibleEvent class is used to give detailed updates to the + accessibility framework. It is used together with \l QAccessible::updateAccessibility. - \brief The QAccessibleEvent class is used to query addition - accessibility information about complex widgets. - - The event can be of type QEvent::AccessibilityDescription or - QEvent::AccessibilityHelp. - - Some QAccessibleInterface implementations send QAccessibleEvents - to the widget they wrap to obtain the description or help text of - a widget or of its children. The widget can answer by calling - setValue() with the requested information. - - The default QWidget::event() implementation simply sets the text - to be the widget's \l{QWidget::toolTip}{tooltip} (for \l - AccessibilityDescription event) or its - \l{QWidget::whatsThis}{"What's This?" text} (for \l - AccessibilityHelp event). + The event is one of the \l QAccessible::Event which depending on the type of event needs to use + one of the subclasses of QAccessibleEvent. \ingroup accessibility - \ingroup events - \inmodule QtWidgets + \inmodule QtGui */ /*! - \fn QAccessibleEvent::QAccessibleEvent(Type type) + \fn QAccessibleEvent::QAccessibleEvent(QAccessible::Event type, QObject *object, int child = -1) - Constructs an accessibility event of the given \a type, which - must be QEvent::AccessibilityDescription or - QEvent::AccessibilityHelp. -*/ + Constructs an accessibility event of the given \a type. + It also requires an \a object as source of the event and optionally a \a child index, + if the event comes from a child of the object. -/*! - \fn int QAccessibleEvent::child() const - - Returns the (1-based) index of the child to which the request - applies. If the child is 0, the request is for the widget itself. -*/ - -/*! - \fn QString QAccessibleEvent::value() const - - Returns the text set using setValue(). - - \sa setValue() -*/ - -/*! - \fn void QAccessibleEvent::setValue(const QString &text) - - Set the description or help text for the given child() to \a - text, thereby answering the request. - - \sa value() + Using a \a child index maybe more efficient than creating the accessible interface for the child. */ /*! From 49b53061550c15ce3b9cc38ee5e82e970f75d5ea Mon Sep 17 00:00:00 2001 From: Andrew Stanley-Jones Date: Mon, 6 Feb 2012 18:36:06 +0100 Subject: [PATCH 131/406] Add socketOptions flags to QLocalServer QLocalServer had no way to set socket options that more complicated servers require. The first set of options allow setting of access control on the sockets. Change-Id: If4268c66462fc2e6cf1e70b1d5f56c76d2c69228 Reviewed-by: Harald Fernengel --- src/network/socket/qlocalserver.cpp | 63 ++++++++++++++++++ src/network/socket/qlocalserver.h | 16 +++++ src/network/socket/qlocalserver_p.h | 4 +- src/network/socket/qlocalserver_unix.cpp | 65 ++++++++++++++++++- .../socket/qlocalsocket/tst_qlocalsocket.cpp | 55 ++++++++++++++++ 5 files changed, 200 insertions(+), 3 deletions(-) diff --git a/src/network/socket/qlocalserver.cpp b/src/network/socket/qlocalserver.cpp index b3fe4ac4481..97f5920171e 100644 --- a/src/network/socket/qlocalserver.cpp +++ b/src/network/socket/qlocalserver.cpp @@ -81,6 +81,27 @@ QT_BEGIN_NAMESPACE \sa QLocalSocket, QTcpServer */ +/*! + \enum QLocalServer::SocketOption + + This enum describes the possible options that can be used to create the + socket. This changes the access permissions on platforms (Linux, Windows) + that support access permissions on the socket. Both GroupAccess and OtherAccess + may vary slightly in meanings depending on the platform. + + \value UserAccess + Access is restricted to the same user as the process that created the socket. + \value GroupAccess + Access is restricted to the same group but not the user that created the socket on Linux. + \value OtherAccess + Access is available to everyone but the user and group that created the socket on Linux. + \value WorldAccess + No access restrictions. + + \sa SocketOptions +*/ + + /*! Create a new local socket server with the given \a parent. @@ -108,6 +129,48 @@ QLocalServer::~QLocalServer() close(); } +/*! + \property QLocalServer::socketOptions + \since 5.0 + + The setSocketOptions method controls how the socket operates. + For example the socket may restrict access to what user ids can + connect to the socket. + + These options must be set before listen() is called. + + In some cases, such as with Unix domain sockets on Linux, the + access to the socket will be determined by file system permissions, + and are created based on the umask. Setting the access flags will + overide this and will restrict or permit access as specified. + + Other Unix-based operating systems, such as Mac OS X, do not + honor file permissions for Unix domain sockets and by default + have WorldAccess and these permission flags will have no effect. + + By default none of the flags are set, access permissions + are the platform default. + + \sa listen() +*/ +void QLocalServer::setSocketOptions(SocketOptions options) +{ + Q_D(QLocalServer); + + d->socketOptions = options; +} + +/*! + Returns the socket options set on the socket. + + \sa setSocketOptions() + */ +QLocalServer::SocketOptions QLocalServer::socketOptions() const +{ + Q_D(const QLocalServer); + return d->socketOptions; +} + /*! Stop listening for incoming connections. Existing connections are not effected, but any new connections will be refused. diff --git a/src/network/socket/qlocalserver.h b/src/network/socket/qlocalserver.h index f694131953a..6f883adc24c 100644 --- a/src/network/socket/qlocalserver.h +++ b/src/network/socket/qlocalserver.h @@ -58,11 +58,22 @@ class Q_NETWORK_EXPORT QLocalServer : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QLocalServer) + Q_PROPERTY(SocketOptions socketOptions READ socketOptions WRITE setSocketOptions) + Q_FLAGS(SocketOption SocketOptions) Q_SIGNALS: void newConnection(); public: + enum SocketOption { + NoOptions = 0x0, + UserAccessOption = 0x01, + GroupAccessOption = 0x2, + OtherAccessOption = 0x4, + WorldAccessOption = 0x7 + }; + Q_DECLARE_FLAGS(SocketOptions, SocketOption) + QLocalServer(QObject *parent = 0); ~QLocalServer(); @@ -80,6 +91,9 @@ public: void setMaxPendingConnections(int numConnections); bool waitForNewConnection(int msec = 0, bool *timedOut = 0); + void setSocketOptions(SocketOptions options); + SocketOptions socketOptions() const; + protected: virtual void incomingConnection(quintptr socketDescriptor); @@ -88,6 +102,8 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_onNewConnection()) }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QLocalServer::SocketOptions) + #endif // QT_NO_LOCALSERVER QT_END_NAMESPACE diff --git a/src/network/socket/qlocalserver_p.h b/src/network/socket/qlocalserver_p.h index 6e39136dd48..03c06a42e3b 100644 --- a/src/network/socket/qlocalserver_p.h +++ b/src/network/socket/qlocalserver_p.h @@ -80,7 +80,8 @@ public: #if !defined(QT_LOCALSOCKET_TCP) && !defined(Q_OS_WIN) listenSocket(-1), socketNotifier(0), #endif - maxPendingConnections(30), error(QAbstractSocket::UnknownSocketError) + maxPendingConnections(30), error(QAbstractSocket::UnknownSocketError), + socketOptions(QLocalServer::NoOptions) { } @@ -121,6 +122,7 @@ public: QQueue pendingConnections; QString errorString; QAbstractSocket::SocketError error; + QLocalServer::SocketOptions socketOptions; }; QT_END_NAMESPACE diff --git a/src/network/socket/qlocalserver_unix.cpp b/src/network/socket/qlocalserver_unix.cpp index c4482dadfc6..ce0c283f0b4 100644 --- a/src/network/socket/qlocalserver_unix.cpp +++ b/src/network/socket/qlocalserver_unix.cpp @@ -44,6 +44,7 @@ #include "qlocalsocket.h" #include "qlocalsocket_p.h" #include "qnet_unix_p.h" +#include "qtemporarydir.h" #ifndef QT_NO_LOCALSERVER @@ -92,6 +93,20 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName) } serverName = requestedServerName; + QString tempPath; + QScopedPointer tempDir; + + // Check any of the flags + if (socketOptions & QLocalServer::WorldAccessOption) { + tempDir.reset(new QTemporaryDir(fullServerName)); + if (!tempDir->isValid()) { + setError(QLatin1String("QLocalServer::listen")); + return false; + } + tempPath = tempDir->path(); + tempPath += QLatin1Char('/') + requestedServerName; + } + // create the unix socket listenSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0); if (-1 == listenSocket) { @@ -108,8 +123,26 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName) closeServer(); return false; } - ::memcpy(addr.sun_path, fullServerName.toLatin1().data(), - fullServerName.toLatin1().size() + 1); + + if (socketOptions & QLocalServer::WorldAccessOption) { + if (sizeof(addr.sun_path) < (uint)tempPath.toLatin1().size() + 1) { + setError(QLatin1String("QLocalServer::listen")); + closeServer(); + return false; + } + ::memcpy(addr.sun_path, tempPath.toLatin1().data(), + tempPath.toLatin1().size() + 1); + + if (-1 == ::fchmod(listenSocket, 0)) { + setError(QLatin1String("QLocalServer::listen")); + closeServer(); + return false; + } + + } else { + ::memcpy(addr.sun_path, fullServerName.toLatin1().data(), + fullServerName.toLatin1().size() + 1); + } // bind if(-1 == QT_SOCKET_BIND(listenSocket, (sockaddr *)&addr, sizeof(sockaddr_un))) { @@ -133,6 +166,34 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName) QFile::remove(fullServerName); return false; } + + if (socketOptions & QLocalServer::WorldAccessOption) { + mode_t mode = 000; + + if (socketOptions & QLocalServer::UserAccessOption) { + mode |= S_IRWXU; + } + if (socketOptions & QLocalServer::GroupAccessOption) { + mode |= S_IRWXG; + } + if (socketOptions & QLocalServer::OtherAccessOption) { + mode |= S_IRWXO; + } + + if (mode) { + if (-1 == ::chmod(tempPath.toLatin1(), mode)) { + setError(QLatin1String("QLocalServer::listen")); + closeServer(); + return false; + } + } + if (-1 == ::rename(tempPath.toLatin1(), fullServerName.toLatin1())){ + setError(QLatin1String("QLocalServer::listen")); + closeServer(); + return false; + } + } + Q_ASSERT(!socketNotifier); socketNotifier = new QSocketNotifier(listenSocket, QSocketNotifier::Read, q); diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp index 5d3cb6eaae5..03b95bfa2fd 100644 --- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp @@ -48,6 +48,8 @@ Q_DECLARE_METATYPE(QLocalSocket::LocalSocketError) Q_DECLARE_METATYPE(QLocalSocket::LocalSocketState) +Q_DECLARE_METATYPE(QLocalServer::SocketOption) +Q_DECLARE_METATYPE(QFile::Permissions) class tst_QLocalSocket : public QObject { @@ -104,12 +106,17 @@ private slots: void bytesWrittenSignal(); void syncDisconnectNotify(); void asyncDisconnectNotify(); + + void verifySocketOptions(); + void verifySocketOptions_data(); }; void tst_QLocalSocket::init() { qRegisterMetaType("QLocalSocket::LocalSocketState"); qRegisterMetaType("QLocalSocket::LocalSocketError"); + qRegisterMetaType("QLocalServer::SocketOption"); + qRegisterMetaType("QFile::Permissions"); } void tst_QLocalSocket::cleanup() @@ -1010,6 +1017,54 @@ void tst_QLocalSocket::asyncDisconnectNotify() QTRY_VERIFY(!disconnectedSpy.isEmpty()); } +void tst_QLocalSocket::verifySocketOptions_data() +{ +#ifdef Q_OS_LINUX + QTest::addColumn("service"); + QTest::addColumn("opts"); + QTest::addColumn("perms"); + + QFile::Permissions p = QFile::ExeOwner|QFile::WriteOwner|QFile::ReadOwner | + QFile::ExeUser|QFile::WriteUser|QFile::ReadUser; + QTest::newRow("user") << "userPerms" << QLocalServer::UserAccess << p; + + p = QFile::ExeGroup|QFile::WriteGroup|QFile::ReadGroup; + QTest::newRow("group") << "groupPerms" << QLocalServer::GroupAccess << p; + + p = QFile::ExeOther|QFile::WriteOther|QFile::ReadOther; + QTest::newRow("other") << "otherPerms" << QLocalServer::OtherAccess << p; + + p = QFile::ExeOwner|QFile::WriteOwner|QFile::ReadOwner| + QFile::ExeUser|QFile::WriteUser|QFile::ReadUser | + QFile::ExeGroup|QFile::WriteGroup|QFile::ReadGroup| + QFile::ExeOther|QFile::WriteOther|QFile::ReadOther; + QTest::newRow("all") << "worldPerms" << QLocalServer::WorldAccess << p; +#endif +} + +void tst_QLocalSocket::verifySocketOptions() +{ + // These are only guaranteed to be useful on linux at this time +#ifdef Q_OS_LINUX + QFETCH(QString, service); + QFETCH(QLocalServer::SocketOption, opts); + QFETCH(QFile::Permissions, perms); + + + QLocalServer::removeServer(service); + QLocalServer server; + server.setSocketOptions(opts); + QVERIFY2(server.listen(service), "service failed to start listening"); + + // find the socket + QString fullServerPath = QDir::cleanPath(QDir::tempPath()); + fullServerPath += QLatin1Char('/') + service; + + QFile socketFile(fullServerPath); + QVERIFY2(perms == socketFile.permissions(), "permissions on the socket don't match"); +#endif +} + QTEST_MAIN(tst_QLocalSocket) #include "tst_qlocalsocket.moc" From c5618fd880801b36e31cd876170cfde7427878fe Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Thu, 9 Feb 2012 11:51:44 +1000 Subject: [PATCH 132/406] Fixed qsharedpointer unittest to run from installation directory - Only run invalidConstructs() tests if not cross compiled Change-Id: If99fccdf9bca339507ca60c49aa89dc35c535d3d Reviewed-by: Rohan McGovern Reviewed-by: Jason McDonald --- tests/auto/corelib/tools/qsharedpointer/externaltests.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/corelib/tools/qsharedpointer/externaltests.pri b/tests/auto/corelib/tools/qsharedpointer/externaltests.pri index e12bb914c0e..10d30e3c767 100644 --- a/tests/auto/corelib/tools/qsharedpointer/externaltests.pri +++ b/tests/auto/corelib/tools/qsharedpointer/externaltests.pri @@ -3,5 +3,5 @@ HEADERS += $$PWD/externaltests.h cleanedQMAKESPEC = $$replace(QMAKESPEC, \\\\, /) DEFINES += DEFAULT_MAKESPEC=\\\"$$cleanedQMAKESPEC\\\" -embedded:DEFINES += QTEST_NO_RTTI QTEST_CROSS_COMPILED +cross_compile:DEFINES += QTEST_NO_RTTI QTEST_CROSS_COMPILED wince*:DEFINES += QTEST_CROSS_COMPILED QTEST_NO_RTTI From 6e3c4de94f394bfdb07035fe7e71237779c45971 Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Thu, 9 Feb 2012 12:55:30 +1000 Subject: [PATCH 133/406] Fixed qlibrary unittest to work on mac - Changed unload_after_implicit_load() to use full path - Turned off app_bundle Change-Id: Ibdf3ae0dc833d97eba64298715eb88c70408fff6 Reviewed-by: Rohan McGovern Reviewed-by: Jason McDonald --- tests/auto/corelib/plugin/qlibrary/tst/tst.pro | 1 + tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/auto/corelib/plugin/qlibrary/tst/tst.pro b/tests/auto/corelib/plugin/qlibrary/tst/tst.pro index 0992ad89f38..ae6cf97891d 100644 --- a/tests/auto/corelib/plugin/qlibrary/tst/tst.pro +++ b/tests/auto/corelib/plugin/qlibrary/tst/tst.pro @@ -1,4 +1,5 @@ CONFIG += testcase +CONFIG -= app_bundle TARGET = ../tst_qlibrary QT = core testlib SOURCES = ../tst_qlibrary.cpp diff --git a/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp b/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp index cff98de54ff..efbc89880f4 100644 --- a/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp +++ b/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp @@ -258,7 +258,7 @@ void tst_QLibrary::unload() void tst_QLibrary::unload_after_implicit_load() { - QLibrary library( "./mylib" ); + QLibrary library( QCoreApplication::applicationDirPath() + "/mylib" ); QFunctionPointer p = library.resolve("mylibversion"); QVERIFY(p); // Check if it was loaded QVERIFY(library.isLoaded()); From 7038151326feef8331d3a258ea03c870012a8f36 Mon Sep 17 00:00:00 2001 From: John Stanley Date: Tue, 7 Feb 2012 03:59:40 -0500 Subject: [PATCH 134/406] Add support for xlib backend X Event filters Change-Id: Id1e7995f98395de748ce47a27365e4bdd564ea49 Reviewed-by: Simon Hausmann --- src/plugins/platforms/xlib/qxlibintegration.cpp | 2 +- src/plugins/platforms/xlib/qxlibintegration.h | 3 ++- src/plugins/platforms/xlib/qxlibnativeinterface.cpp | 11 +++++++++++ src/plugins/platforms/xlib/qxlibnativeinterface.h | 4 ++++ src/plugins/platforms/xlib/qxlibscreen.cpp | 11 +++++++++-- src/plugins/platforms/xlib/qxlibscreen.h | 3 ++- 6 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/xlib/qxlibintegration.cpp b/src/plugins/platforms/xlib/qxlibintegration.cpp index 965f6ffcc51..65d4d231c8b 100644 --- a/src/plugins/platforms/xlib/qxlibintegration.cpp +++ b/src/plugins/platforms/xlib/qxlibintegration.cpp @@ -68,7 +68,7 @@ QXlibIntegration::QXlibIntegration() XInitThreads(); - mPrimaryScreen = new QXlibScreen(); + mPrimaryScreen = new QXlibScreen(mNativeInterface); mScreens.append(mPrimaryScreen); screenAdded(mPrimaryScreen); } diff --git a/src/plugins/platforms/xlib/qxlibintegration.h b/src/plugins/platforms/xlib/qxlibintegration.h index b76c6e85d8c..76c3f13ff65 100644 --- a/src/plugins/platforms/xlib/qxlibintegration.h +++ b/src/plugins/platforms/xlib/qxlibintegration.h @@ -54,6 +54,7 @@ QT_BEGIN_NAMESPACE class QXlibScreen; +class QXlibNativeInterface; class QXlibIntegration : public QPlatformIntegration { @@ -82,7 +83,7 @@ private: QList mScreens; QPlatformFontDatabase *mFontDb; QPlatformClipboard *mClipboard; - QPlatformNativeInterface *mNativeInterface; + QXlibNativeInterface *mNativeInterface; QAbstractEventDispatcher *mEventDispatcher; }; diff --git a/src/plugins/platforms/xlib/qxlibnativeinterface.cpp b/src/plugins/platforms/xlib/qxlibnativeinterface.cpp index 06f11773bbb..0519a365cff 100644 --- a/src/plugins/platforms/xlib/qxlibnativeinterface.cpp +++ b/src/plugins/platforms/xlib/qxlibnativeinterface.cpp @@ -92,6 +92,17 @@ void * QXlibNativeInterface::nativeResourceForWindow(const QByteArray &resourceS } return result; } +QPlatformNativeInterface::EventFilter QXlibNativeInterface::setEventFilter(const QByteArray &eventType, QPlatformNativeInterface::EventFilter filter) +{ + EventFilter oldFilter = m_eventFilters.value(eventType); + m_eventFilters.insert(eventType, filter); + return oldFilter; +} + +QPlatformNativeInterface::EventFilter QXlibNativeInterface::eventFilterForEventType(const QByteArray& eventType) const +{ + return m_eventFilters.value(eventType); +} void * QXlibNativeInterface::displayForWindow(QWindow *window) { diff --git a/src/plugins/platforms/xlib/qxlibnativeinterface.h b/src/plugins/platforms/xlib/qxlibnativeinterface.h index 8f68e61caff..9ec4ab51c81 100644 --- a/src/plugins/platforms/xlib/qxlibnativeinterface.h +++ b/src/plugins/platforms/xlib/qxlibnativeinterface.h @@ -60,6 +60,9 @@ public: void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window); + EventFilter setEventFilter(const QByteArray &eventType, EventFilter filter); + EventFilter eventFilterForEventType(const QByteArray& eventType) const; + void *displayForWindow(QWindow *window); void *eglDisplayForWindow(QWindow *window); void *connectionForWindow(QWindow *window); @@ -68,6 +71,7 @@ public: void *eglContextForWindow(QWindow *window); private: + QHash m_eventFilters; static QXlibScreen *qPlatformScreenForWindow(QWindow *window); }; diff --git a/src/plugins/platforms/xlib/qxlibscreen.cpp b/src/plugins/platforms/xlib/qxlibscreen.cpp index ed6f77d830b..fc903708b36 100644 --- a/src/plugins/platforms/xlib/qxlibscreen.cpp +++ b/src/plugins/platforms/xlib/qxlibscreen.cpp @@ -50,6 +50,7 @@ #include "qxlibstatic.h" #include "qxlibclipboard.h" #include "qxlibdisplay.h" +#include "qxlibnativeinterface.h" #include #include @@ -190,8 +191,9 @@ qDebug() << "qt_x_errhandler" << err->error_code; return 0; } -QXlibScreen::QXlibScreen() - : mFormat(QImage::Format_RGB32) +QXlibScreen::QXlibScreen(QXlibNativeInterface *nativeInterface) + : mNativeInterface(nativeInterface) + , mFormat(QImage::Format_RGB32) #if !defined(QT_NO_OPENGL) && defined(QT_OPENGL_ES_2) , mEGLDisplay(0) #endif @@ -263,6 +265,11 @@ unsigned long QXlibScreen::whitePixel() bool QXlibScreen::handleEvent(XEvent *xe) { + if (QPlatformNativeInterface::EventFilter filter = mNativeInterface->eventFilterForEventType(QByteArrayLiteral("XEvent"))) { + if (filter(xe, 0)) + return true; + } + int quit = false; QXlibWindow *platformWindow = QXlibWindow::platformWindowForXWindow(xe->xany.window); if (!platformWindow) diff --git a/src/plugins/platforms/xlib/qxlibscreen.h b/src/plugins/platforms/xlib/qxlibscreen.h index 3404243c2c1..c6672c35400 100644 --- a/src/plugins/platforms/xlib/qxlibscreen.h +++ b/src/plugins/platforms/xlib/qxlibscreen.h @@ -55,7 +55,7 @@ class QXlibScreen : public QObject, public QPlatformScreen { Q_OBJECT public: - QXlibScreen(); + QXlibScreen(QXlibNativeInterface *nativeInterface); ~QXlibScreen(); @@ -93,6 +93,7 @@ public slots: private: void handleSelectionRequest(XEvent *event); + QXlibNativeInterface *mNativeInterface; QRect mGeometry; QSizeF mPhysicalSize; int mDepth; From b942106bb661736264aec69961caecc35c814c09 Mon Sep 17 00:00:00 2001 From: Toby Tomkins Date: Tue, 7 Feb 2012 14:08:53 +1000 Subject: [PATCH 135/406] Remove SVG specific tests and testdata from QIcon. SVG support is now handled in QtSvg. Previously this test code would normally be skipped when testing qtbase. This code is only executed when testing qt5 with QtSvg enabled. This code will be moved to QtSvg. Task-number: QTBUG-22360 Change-Id: I7372012469f9c0f9b7d3851a0ae696f8f935ba10 Reviewed-by: Jason McDonald Reviewed-by: Rohan McGovern --- tests/auto/gui/image/qicon/heart.svg | 55 -------------- tests/auto/gui/image/qicon/heart.svgz | Bin 1506 -> 0 bytes tests/auto/gui/image/qicon/rect.svg | 76 -------------------- tests/auto/gui/image/qicon/trash.svg | 58 --------------- tests/auto/gui/image/qicon/tst_qicon.cpp | 88 ----------------------- 5 files changed, 277 deletions(-) delete mode 100644 tests/auto/gui/image/qicon/heart.svg delete mode 100644 tests/auto/gui/image/qicon/heart.svgz delete mode 100644 tests/auto/gui/image/qicon/rect.svg delete mode 100644 tests/auto/gui/image/qicon/trash.svg diff --git a/tests/auto/gui/image/qicon/heart.svg b/tests/auto/gui/image/qicon/heart.svg deleted file mode 100644 index 8c982cd93ca..00000000000 --- a/tests/auto/gui/image/qicon/heart.svg +++ /dev/null @@ -1,55 +0,0 @@ - - - - - -Heart Left-Highlight -This is a normal valentines day heart. - - -holiday -valentines - -valentine -hash(0x8a091c0) -hash(0x8a0916c) -signs_and_symbols -hash(0x8a091f0) -day - - - - -Jon Phillips - - - - -Jon Phillips - - - - -Jon Phillips - - - -image/svg+xml - - -en - - - - - - - - - - - - - - - diff --git a/tests/auto/gui/image/qicon/heart.svgz b/tests/auto/gui/image/qicon/heart.svgz deleted file mode 100644 index 0f0913ffa7f06603ee97906415ae90ac61868272..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1506 zcmV<81s(byiwFqO@{vdY188Moa&$5-b9QF{wO3n@(>N4<=T~?$FCZGncH+b-)1rkD zf)z*zSnbP5C{5fZOBzRU+D`fP9OqVdrpqqNZe}_YpZn#reR}=;Zd;Wjg+noM zkgQUb71d_p{Ql{cD;%WTq{@;~RdV4}%6Yzgbp4C#qL+?g&8)KAgjcfa_cqo4j2(BA{4^I1205 zK}EK3K#juNU~fJJOmIM+rh5%RLd-RM=9x-YiH1;L&Tns2y4%XC)d(^`A7$G@Ui$Vo zRiXEJQIQ9-%OA5TCY2ATvt9Pqyp^ejfzN%ykzH(`VOSx{{98xGv z8W@7MWUZKe=0Mf5HeWbA=9opC$0k$gMWw;mse%W;s~r@Hc%8XUWS*ucDY?Rp)N0qH zeVx=EWM z=7NN)k5!x8xs|>e^~T~%%9F!Bp*2{MxRR}R^XbMLrCoxvHk)khH{UH8pmi(TBum-^ zULlV8hnrXbUmbtA6cALJ&i_!&7i5Au?a-WF{sm#+=F&|8D9*CV>Fy@}mP zW>Tk3QMUlG<)^&R2!0b(sb-tN22V-|w5X&;S#m@jT5)H=R_p8l&<)^+QoTqv!&_M_ zb5$0ge(eqGiE%RjkoO(whpar&`D1b?5)#vtJo&yrm|hUj#ir7qVYh$Q$L&g$7b3E4 ztS>n^&(S;8!8@xDEb85=EOaiLzKOqXAThg(77kPm=W2hb7(kr$*FKNV`s$5F2j{jw zSf=I#R<`qhW%XnR7L5Uy{#lcg6$3H2C6+zd%v(oW8(g-_Vw-HF*`-fm^K>EuqxX4) z`@~dp+?N-3VU}(SBk6r?A+R^bqT}`PmqjWo{TDVaZTR=5zUhtHCPmd5fhfwP+U&sS zQdV7r)4I>vY~0@4Tg%(M{{Nk;-asuINJania6d@6p0ZtPcJG+;4;#5DblViG-Om}3 zO|ehfVlPcSbZ5sq)nwd8aPpd0>pafnT6Z_RdGR~F>Bck{PG*J$v{Fqbn^cvmSvXf= z_c#Mp!IcC67={;P%3S}}u#oPW29W8N$x(uO_sl9bR~aK z)J>yy^;Tta;90CPS;=zYyftJ*4fg8A5Gmi9yqL=2MDj}ePv?8B1GID-Mq_o+aBL~$GmMrI)wIN*NFKs(?u z=9~oqNCFl(;UNkM!8{-kPartvaqKgTX8S%-$0!BjL5L$k#3`Ey1!9u3@(z54gO~}M z>c=o`z#pJNtvC&RYDMmo0Q>M5ZJ#qNXcU|z3Gyk$LFh-e?@KlRiu$c&Iult#Yy}-P zhbLs@TQom9 z`L?KRjFN>@Hqn?31Tf|uo$@wRh?n1&jN^!kjur+nWk54|joKj(S*J~6%vj)ufFr1P z1W6!+W3@zRuN(GYELlGK2D*-k I&LIx~04I6ZF8}}l diff --git a/tests/auto/gui/image/qicon/rect.svg b/tests/auto/gui/image/qicon/rect.svg deleted file mode 100644 index 8eb24727bea..00000000000 --- a/tests/auto/gui/image/qicon/rect.svg +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - - - - - - - diff --git a/tests/auto/gui/image/qicon/trash.svg b/tests/auto/gui/image/qicon/trash.svg deleted file mode 100644 index c44e4c75a2b..00000000000 --- a/tests/auto/gui/image/qicon/trash.svg +++ /dev/null @@ -1,58 +0,0 @@ - - - - - -Keep Tidy Inside - - - - -symbol -bin -signs_and_symbols -clean -rubish -trash -inside -garbage -sign - - - - -Martin Owens - - - - -Martin Owens - - - - -Martin Owens - - - -image/svg+xml - - -en - - - - - - - - - - - - - - - - - diff --git a/tests/auto/gui/image/qicon/tst_qicon.cpp b/tests/auto/gui/image/qicon/tst_qicon.cpp index 7d455f10102..4a9ab93921e 100644 --- a/tests/auto/gui/image/qicon/tst_qicon.cpp +++ b/tests/auto/gui/image/qicon/tst_qicon.cpp @@ -58,13 +58,11 @@ private slots: void actualSize(); void actualSize2_data(); // test with 2 pixmaps with different aspect ratio void actualSize2(); - void svgActualSize(); void isNull(); void swap(); void bestMatch(); void cacheKey(); void detach(); - void svg(); void addFile(); void availableSizes(); void name(); @@ -181,28 +179,6 @@ void tst_QIcon::actualSize2() QCOMPARE(icon.pixmap(argument).size(), result); } -void tst_QIcon::svgActualSize() -{ - if (!haveImageFormat("svg")) { - QSKIP("SVG support is not available"); - } - - const QString prefix = QFileInfo(QFINDTESTDATA("icons")).absolutePath() + "/"; - QIcon icon(prefix + "rect.svg"); - QCOMPARE(icon.actualSize(QSize(16, 16)), QSize(16, 2)); - QCOMPARE(icon.pixmap(QSize(16, 16)).size(), QSize(16, 2)); - - QPixmap p(16, 16); - p.fill(Qt::cyan); - icon.addPixmap(p); - - QCOMPARE(icon.actualSize(QSize(16, 16)), QSize(16, 16)); - QCOMPARE(icon.pixmap(QSize(16, 16)).size(), QSize(16, 16)); - - QCOMPARE(icon.actualSize(QSize(16, 14)), QSize(16, 2)); - QCOMPARE(icon.pixmap(QSize(16, 14)).size(), QSize(16, 2)); -} - void tst_QIcon::isNull() { // test default constructor QIcon defaultConstructor; @@ -395,54 +371,6 @@ void tst_QIcon::detach() QVERIFY(img1 == img2); } -void tst_QIcon::svg() -{ - if (!haveImageFormat("svg")) { - QSKIP("SVG support is not available"); - } - QIcon icon1("heart.svg"); - - QVERIFY(!icon1.pixmap(32).isNull()); - QImage img1 = icon1.pixmap(32).toImage(); - QVERIFY(!icon1.pixmap(32, QIcon::Disabled).isNull()); - QImage img2 = icon1.pixmap(32, QIcon::Disabled).toImage(); - - icon1.addFile("trash.svg", QSize(), QIcon::Disabled); - QVERIFY(!icon1.pixmap(32, QIcon::Disabled).isNull()); - QImage img3 = icon1.pixmap(32, QIcon::Disabled).toImage(); - QVERIFY(img3 != img2); - QVERIFY(img3 != img1); - - QPixmap pm("image.png"); - icon1.addPixmap(pm, QIcon::Normal, QIcon::On); - QVERIFY(!icon1.pixmap(128, QIcon::Normal, QIcon::On).isNull()); - QImage img4 = icon1.pixmap(128, QIcon::Normal, QIcon::On).toImage(); - QVERIFY(img4 != img3); - QVERIFY(img4 != img2); - QVERIFY(img4 != img1); - - QIcon icon2; - icon2.addFile("heart.svg"); - QVERIFY(icon2.pixmap(57).toImage() == icon1.pixmap(57).toImage()); - - QIcon icon3("trash.svg"); - icon3.addFile("heart.svg"); - QVERIFY(icon3.pixmap(57).toImage() == icon1.pixmap(57).toImage()); - - QIcon icon4("heart.svg"); - icon4.addFile("image.png", QSize(), QIcon::Active); - QVERIFY(!icon4.pixmap(32).isNull()); - QVERIFY(!icon4.pixmap(32, QIcon::Active).isNull()); - QVERIFY(icon4.pixmap(32).toImage() == img1); - QIcon pmIcon(pm); - QVERIFY(icon4.pixmap(pm.size(), QIcon::Active).toImage() == pmIcon.pixmap(pm.size(), QIcon::Active).toImage()); - -#ifndef QT_NO_COMPRESS - QIcon icon5("heart.svgz"); - QVERIFY(!icon5.pixmap(32).isNull()); -#endif -} - void tst_QIcon::addFile() { QIcon icon; @@ -506,22 +434,6 @@ void tst_QIcon::availableSizes() QCOMPARE(availableSizes.at(0), QSize(16,16)); } - if (haveImageFormat("svg")) { - // checks that there are no availableSizes for scalable images. - QIcon icon("heart.svg"); - QList availableSizes = icon.availableSizes(); - QVERIFY(availableSizes.isEmpty()); - } - - if (haveImageFormat("svg")) { - // even if an a scalable image contain added pixmaps, - // availableSizes still should be empty. - QIcon icon("heart.svg"); - icon.addFile("image.png", QSize(32,32)); - QList availableSizes = icon.availableSizes(); - QVERIFY(availableSizes.isEmpty()); - } - { // we try to load an icon from resources QIcon icon(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-16.png")); From cbd6b4eb20e645f36bf819b5fc2de4c10d4b1763 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Thu, 9 Feb 2012 17:31:21 +0100 Subject: [PATCH 136/406] Clean up qguifunctions_wince includes. There are leftovers from Qt 4.8 in regards of the qguifunctions_wince. The parts which where needed in widgets have been taken over into qwidgetsfunctions_wince. Change-Id: I737684a7f56ba356df89c1be77ab776bca034ae9 Reviewed-by: Friedemann Kleint --- src/widgets/dialogs/qerrormessage.cpp | 2 - src/widgets/kernel/kernel.pri | 5 +- src/widgets/kernel/qapplication.cpp | 1 - src/widgets/kernel/qguiplatformplugin.cpp | 1 - .../kernel/qwidgetsfunctions_wince.cpp | 126 ++++++++++++++++++ src/widgets/kernel/qwidgetsfunctions_wince.h | 62 +++++++++ src/widgets/styles/qwindowsmobilestyle.cpp | 1 - src/widgets/widgets/qmenu_wince.cpp | 2 - src/widgets/widgets/qmenubar_p.h | 4 - 9 files changed, 190 insertions(+), 14 deletions(-) create mode 100644 src/widgets/kernel/qwidgetsfunctions_wince.cpp create mode 100644 src/widgets/kernel/qwidgetsfunctions_wince.h diff --git a/src/widgets/dialogs/qerrormessage.cpp b/src/widgets/dialogs/qerrormessage.cpp index 84021d09889..094c35b1073 100644 --- a/src/widgets/dialogs/qerrormessage.cpp +++ b/src/widgets/dialogs/qerrormessage.cpp @@ -64,8 +64,6 @@ #ifdef Q_OS_WINCE extern bool qt_wince_is_mobile(); //defined in qguifunctions_wince.cpp extern bool qt_wince_is_high_dpi(); //defined in qguifunctions_wince.cpp - -#include "qguifunctions_wince.h" #endif #if defined(QT_SOFTKEYS_ENABLED) diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri index 32934dc7059..80f165063c7 100644 --- a/src/widgets/kernel/kernel.pri +++ b/src/widgets/kernel/kernel.pri @@ -137,9 +137,8 @@ false:!x11:mac { wince*: { HEADERS += \ ../corelib/kernel/qfunctions_wince.h \ - kernel/qguifunctions_wince.h + kernel/qwidgetsfunctions_wince.h SOURCES += \ - ../corelib/kernel/qfunctions_wince.cpp \ - kernel/qguifunctions_wince.cpp + kernel/qwidgetsfunctions_wince.cpp } diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 9bef6f8f710..d2b4e01c0b3 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -106,7 +106,6 @@ #ifdef Q_OS_WINCE #include "qdatetime.h" -#include "qguifunctions_wince.h" extern bool qt_wince_is_smartphone(); //qguifunctions_wince.cpp extern bool qt_wince_is_mobile(); //qguifunctions_wince.cpp extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp diff --git a/src/widgets/kernel/qguiplatformplugin.cpp b/src/widgets/kernel/qguiplatformplugin.cpp index 540499887e4..7646ae417e3 100644 --- a/src/widgets/kernel/qguiplatformplugin.cpp +++ b/src/widgets/kernel/qguiplatformplugin.cpp @@ -51,7 +51,6 @@ #include "qicon.h" #ifdef Q_OS_WINCE -#include "qguifunctions_wince.h" extern bool qt_wince_is_smartphone(); //qguifunctions_wince.cpp extern bool qt_wince_is_mobile(); //qguifunctions_wince.cpp extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp diff --git a/src/widgets/kernel/qwidgetsfunctions_wince.cpp b/src/widgets/kernel/qwidgetsfunctions_wince.cpp new file mode 100644 index 00000000000..a45694177e9 --- /dev/null +++ b/src/widgets/kernel/qwidgetsfunctions_wince.cpp @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtWidgets 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 "qwidgetsfunctions_wince.h" +#include + +QT_USE_NAMESPACE + +#ifndef ShellExecute +HINSTANCE qt_wince_ShellExecute(HWND hwnd, LPCWSTR, LPCWSTR file, LPCWSTR params, LPCWSTR dir, int showCmd) +{ + SHELLEXECUTEINFO info; + info.hwnd = hwnd; + info.lpVerb = L"Open"; + info.lpFile = file; + info.lpParameters = params; + info.lpDirectory = dir; + info.nShow = showCmd; + info.cbSize = sizeof(info); + ShellExecuteEx(&info); + return info.hInstApp; +} +#endif + +#ifndef SPI_GETPLATFORMTYPE +#define SPI_GETPLATFORMTYPE 257 +#endif + +// Internal Qt ----------------------------------------------------- +bool qt_wince_is_platform(const QString &platformString) { + wchar_t tszPlatform[64]; + if (SystemParametersInfo(SPI_GETPLATFORMTYPE, sizeof(tszPlatform) / sizeof(wchar_t), tszPlatform, 0)) + if (0 == _tcsicmp(reinterpret_cast (platformString.utf16()), tszPlatform)) + return true; + return false; +} + +int qt_wince_get_build() +{ + OSVERSIONINFO osvi; + osvi.dwOSVersionInfoSize = sizeof(osvi); + if (GetVersionEx(&osvi)) + return osvi.dwBuildNumber; + return 0; +} + +int qt_wince_get_version() +{ + OSVERSIONINFO osvi; + osvi.dwOSVersionInfoSize = sizeof(osvi); + if (GetVersionEx(&osvi)) + return (osvi.dwMajorVersion * 10 + osvi.dwMinorVersion); + return 0; +} + +bool qt_wince_is_windows_mobile_65() +{ + const DWORD dwFirstWM65BuildNumber = 21139; + OSVERSIONINFO osvi; + osvi.dwOSVersionInfoSize = sizeof(osvi); + if (!GetVersionEx(&osvi)) + return false; + return osvi.dwMajorVersion > 5 + || (osvi.dwMajorVersion == 5 && (osvi.dwMinorVersion > 2 || + (osvi.dwMinorVersion == 2 && osvi.dwBuildNumber >= dwFirstWM65BuildNumber))); +} + +bool qt_wince_is_pocket_pc() { + return qt_wince_is_platform(QString::fromLatin1("PocketPC")); +} + +bool qt_wince_is_smartphone() { + return qt_wince_is_platform(QString::fromLatin1("Smartphone")); +} +bool qt_wince_is_mobile() { + return (qt_wince_is_smartphone() || qt_wince_is_pocket_pc()); +} + +bool qt_wince_is_high_dpi() { + if (!qt_wince_is_pocket_pc()) + return false; + HDC deviceContext = GetDC(0); + int dpi = GetDeviceCaps(deviceContext, LOGPIXELSX); + ReleaseDC(0, deviceContext); + if ((dpi < 1000) && (dpi > 0)) + return dpi > 96; + else + return false; +} diff --git a/src/widgets/kernel/qwidgetsfunctions_wince.h b/src/widgets/kernel/qwidgetsfunctions_wince.h new file mode 100644 index 00000000000..8223b0fb68a --- /dev/null +++ b/src/widgets/kernel/qwidgetsfunctions_wince.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtWidgets 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 QWIDGETSFUNCTIONS_WCE_H +#define QWIDGETSFUNCTIONS_WCE_H +#ifdef Q_OS_WINCE +#include + +#ifdef QT_BUILD_GUI_LIB +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE +QT_MODULE(Gui) +QT_END_NAMESPACE +QT_END_HEADER +#endif + + +//WinCe 7 has shell support +#ifndef ShellExecute +HINSTANCE qt_wince_ShellExecute(HWND hwnd, LPCWSTR operation, LPCWSTR file, LPCWSTR params, LPCWSTR dir, int showCmd); +#define ShellExecute(a,b,c,d,e,f) qt_wince_ShellExecute(a,b,c,d,e,f) +#endif + +#endif // Q_OS_WINCE +#endif // QWIDGETSFUNCTIONS_WCE_H \ No newline at end of file diff --git a/src/widgets/styles/qwindowsmobilestyle.cpp b/src/widgets/styles/qwindowsmobilestyle.cpp index 86513c82677..30269751caa 100644 --- a/src/widgets/styles/qwindowsmobilestyle.cpp +++ b/src/widgets/styles/qwindowsmobilestyle.cpp @@ -74,7 +74,6 @@ #ifdef Q_OS_WINCE #include "qt_windows.h" -#include "qguifunctions_wince.h" extern bool qt_wince_is_high_dpi(); //defined in qguifunctions_wince.cpp extern bool qt_wince_is_smartphone(); //defined in qguifunctions_wince.cpp extern bool qt_wince_is_windows_mobile_65(); //defined in qguifunctions_wince.cpp diff --git a/src/widgets/widgets/qmenu_wince.cpp b/src/widgets/widgets/qmenu_wince.cpp index 9c748b2a538..dae0a67e110 100644 --- a/src/widgets/widgets/qmenu_wince.cpp +++ b/src/widgets/widgets/qmenu_wince.cpp @@ -62,8 +62,6 @@ # include #endif -#include "qguifunctions_wince.h" - #ifndef QT_NO_MENUBAR #ifndef SHCMBF_EMPTYBAR diff --git a/src/widgets/widgets/qmenubar_p.h b/src/widgets/widgets/qmenubar_p.h index d73fc26a385..9e1d3179c7e 100644 --- a/src/widgets/widgets/qmenubar_p.h +++ b/src/widgets/widgets/qmenubar_p.h @@ -57,10 +57,6 @@ #include "QtWidgets/qstyleoption.h" #include // Mac needs what in this file! -#ifdef Q_OS_WINCE -#include "qguifunctions_wince.h" -#endif - QT_BEGIN_NAMESPACE #ifndef QT_NO_MENUBAR From 84607219c0e1e01a82132af9172e350529c3eb38 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Thu, 9 Feb 2012 17:39:31 +0100 Subject: [PATCH 137/406] Add qt_pixmapFromWinHICON again for Windows CE. qt_pixmapFromWinHICON is used by qfileiconprovider and qwindowsstyle. So use this one from Qt 4.8. Also put functions of qguifunctions_wince in here, because this was splitted. Change-Id: I00ffb9d66a84884f7338648982e516ca016b9bd6 Reviewed-by: Friedemann Kleint --- src/gui/image/qpixmap_win.cpp | 179 ++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp index 6b0ec38f532..227e70e1a69 100644 --- a/src/gui/image/qpixmap_win.cpp +++ b/src/gui/image/qpixmap_win.cpp @@ -47,8 +47,91 @@ #include #include +#ifdef Q_OS_WINCE +#define UNDER_NT +#include +#endif + QT_BEGIN_NAMESPACE +#ifdef Q_OS_WINCE +#define GetDIBits(a,b,c,d,e,f,g) qt_wince_GetDIBits(a,b,c,d,e,f,g) +int qt_wince_GetDIBits(HDC /*hdc*/ , HBITMAP hSourceBitmap, uint, uint, LPVOID lpvBits, LPBITMAPINFO, uint) +{ + if (!lpvBits) { + qWarning("::GetDIBits(), lpvBits NULL"); + return 0; + } + BITMAP bm; + GetObject(hSourceBitmap, sizeof(BITMAP), &bm); + bm.bmHeight = qAbs(bm.bmHeight); + + HBITMAP hTargetBitmap; + void *pixels; + + BITMAPINFO dibInfo; + memset(&dibInfo, 0, sizeof(dibInfo)); + dibInfo.bmiHeader.biBitCount = 32; + dibInfo.bmiHeader.biClrImportant = 0; + dibInfo.bmiHeader.biClrUsed = 0; + dibInfo.bmiHeader.biCompression = BI_RGB;; + dibInfo.bmiHeader.biHeight = -bm.bmHeight; + dibInfo.bmiHeader.biWidth = bm.bmWidth; + dibInfo.bmiHeader.biPlanes = 1; + dibInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + dibInfo.bmiHeader.biSizeImage = bm.bmWidth * bm.bmHeight * 4; + + HDC displayDC = GetDC(NULL); + if (!displayDC) { + qWarning("::GetDIBits(), failed to GetDC"); + return 0; + } + + int ret = bm.bmHeight; + + hTargetBitmap = CreateDIBSection(displayDC, (const BITMAPINFO*) &dibInfo, DIB_RGB_COLORS, + (void**)&pixels, NULL, 0); + if (!hTargetBitmap) { + qWarning("::GetDIBits(), failed to CreateDIBSection"); + return 0; + } + + HDC hdcSrc = CreateCompatibleDC(displayDC); + HDC hdcDst = CreateCompatibleDC(displayDC); + + if (!(hdcDst && hdcSrc)) { + qWarning("::GetDIBits(), failed to CreateCompatibleDC"); + ret = 0; + } + + HBITMAP hOldBitmap1 = (HBITMAP) SelectObject(hdcSrc, hSourceBitmap); + HBITMAP hOldBitmap2 = (HBITMAP) SelectObject(hdcDst, hTargetBitmap); + + if (!(hOldBitmap1 && hOldBitmap2)) { + qWarning("::GetDIBits(), failed to SelectObject for bitmaps"); + ret = 0; + } + + if (!BitBlt(hdcDst, 0, 0, bm.bmWidth, bm.bmHeight, hdcSrc, 0, 0, SRCCOPY)) { + qWarning("::GetDIBits(), BitBlt failed"); + ret = 0; + } + + SelectObject(hdcSrc, hOldBitmap1); + SelectObject(hdcDst, hOldBitmap2); + + DeleteDC(hdcSrc); + DeleteDC(hdcDst); + + ReleaseDC(NULL, displayDC); + + memcpy(lpvBits, pixels, dibInfo.bmiHeader.biSizeImage); + + DeleteObject(hTargetBitmap); + return ret; +} +#endif + enum HBitmapFormat { HBitmapNoAlpha, @@ -128,6 +211,8 @@ Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = return bitmap; } +#ifndef Q_OS_WINCE + Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0) { // Verify size @@ -191,6 +276,8 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = return QPixmap::fromImage(image); } +#endif //ifndef Q_OS_WINCE + Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &p) { QBitmap maskBitmap = p.mask(); @@ -214,6 +301,8 @@ Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &p) return hIcon; } +#ifndef Q_OS_WINCE + Q_GUI_EXPORT QImage qt_imageFromWinHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h) { BITMAPINFO bmi; @@ -315,5 +404,95 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon) DeleteDC(hdc); return QPixmap::fromImage(image); } +#else //ifndef Q_OS_WINCE +Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon) +{ + HDC screenDevice = GetDC(0); + HDC hdc = CreateCompatibleDC(screenDevice); + ReleaseDC(0, screenDevice); + + ICONINFO iconinfo; + bool result = GetIconInfo(icon, &iconinfo); + if (!result) + qWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()"); + + int w = 0; + int h = 0; + if (!iconinfo.xHotspot || !iconinfo.yHotspot) { + // We could not retrieve the icon size via GetIconInfo, + // so we try again using the icon bitmap. + BITMAP bm; + int result = GetObject(iconinfo.hbmColor, sizeof(BITMAP), &bm); + if (!result) result = GetObject(iconinfo.hbmMask, sizeof(BITMAP), &bm); + if (!result) { + qWarning("QPixmap::fromWinHICON(), failed to retrieve icon size"); + return QPixmap(); + } + w = bm.bmWidth; + h = bm.bmHeight; + } else { + // x and y Hotspot describes the icon center + w = iconinfo.xHotspot * 2; + h = iconinfo.yHotspot * 2; + } + const DWORD dwImageSize = w * h * 4; + + BITMAPINFO bmi; + memset(&bmi, 0, sizeof(bmi)); + bmi.bmiHeader.biSize = sizeof(BITMAPINFO); + bmi.bmiHeader.biWidth = w; + bmi.bmiHeader.biHeight = -h; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biSizeImage = dwImageSize; + + uchar* bits; + + HBITMAP winBitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**) &bits, 0, 0); + if (winBitmap ) + memset(bits, 0xff, dwImageSize); + if (!winBitmap) { + qWarning("QPixmap::fromWinHICON(), failed to CreateDIBSection()"); + return QPixmap(); + } + + HGDIOBJ oldhdc = (HBITMAP)SelectObject(hdc, winBitmap); + if (!DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_NORMAL)) + qWarning("QPixmap::fromWinHICON(), failed to DrawIcon()"); + + uint mask = 0xff000000; + // Create image and copy data into image. + QImage image(w, h, QImage::Format_ARGB32); + + if (!image.isNull()) { // failed to alloc? + int bytes_per_line = w * sizeof(QRgb); + for (int y=0; y < h; ++y) { + QRgb *dest = (QRgb *) image.scanLine(y); + const QRgb *src = (const QRgb *) (bits + y * bytes_per_line); + for (int x=0; x < w; ++x) { + dest[x] = src[x]; + } + } + } + if (!DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK)) + qWarning("QPixmap::fromWinHICON(), failed to DrawIcon()"); + if (!image.isNull()) { // failed to alloc? + int bytes_per_line = w * sizeof(QRgb); + for (int y=0; y < h; ++y) { + QRgb *dest = (QRgb *) image.scanLine(y); + const QRgb *src = (const QRgb *) (bits + y * bytes_per_line); + for (int x=0; x < w; ++x) { + if (!src[x]) + dest[x] = dest[x] | mask; + } + } + } + SelectObject(hdc, oldhdc); //restore state + DeleteObject(winBitmap); + DeleteDC(hdc); + return QPixmap::fromImage(image); +} +#endif //ifndef Q_OS_WINCE QT_END_NAMESPACE From def35efe2a1e258d94791dc29ac36353deb0c03c Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Thu, 9 Feb 2012 17:43:42 +0100 Subject: [PATCH 138/406] Remove no longer needed ifdef Q_OS_WINCE. There is now an implementation to qt_pixmapFromWinHICON. So use it for Windows CE too. Change-Id: Ie2f3cacd4be9209e33d49e53703c5abc95d98d09 Reviewed-by: Friedemann Kleint --- src/widgets/itemviews/qfileiconprovider.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/widgets/itemviews/qfileiconprovider.cpp b/src/widgets/itemviews/qfileiconprovider.cpp index 6b5478b6caf..e90f78c801a 100644 --- a/src/widgets/itemviews/qfileiconprovider.cpp +++ b/src/widgets/itemviews/qfileiconprovider.cpp @@ -288,11 +288,7 @@ QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const } } if (pixmap.isNull()) { -#ifndef Q_OS_WINCE pixmap = qt_pixmapFromWinHICON(info.hIcon); -#else - pixmap = QPixmap::fromWinHICON(ImageList_GetIcon((HIMAGELIST) val, info.iIcon, ILD_NORMAL)); -#endif if (!pixmap.isNull()) { retIcon.addPixmap(pixmap); if (!key.isEmpty()) @@ -318,11 +314,7 @@ QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const //using the unique icon index provided by windows save us from duplicate keys key = QString::fromLatin1("qt_dir_%1").arg(info.iIcon); } -#ifndef Q_OS_WINCE pixmap = qt_pixmapFromWinHICON(info.hIcon); -#else - pixmap = QPixmap::fromWinHICON(ImageList_GetIcon((HIMAGELIST) val, info.iIcon, ILD_NORMAL)); -#endif if (!pixmap.isNull()) { retIcon.addPixmap(pixmap); if (!key.isEmpty()) From e5830479d62240ed0af580780c0586baca2b66a2 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Fri, 10 Feb 2012 10:37:07 +0100 Subject: [PATCH 139/406] Escape Dependencies of precompiled header right. Change-Id: I847c85250b78a934bd29e09250d209d9ef412f7f Reviewed-by: Oswald Buddenhagen --- qmake/generators/win32/msvc_nmake.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 4d52c4be2e1..b48dd4230ac 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -158,7 +158,7 @@ void NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) // precompiled header if(usePCH) { QString precompRule = QString("-c -Yc -Fp%1 -Fo%2").arg(precompPch).arg(precompObj); - t << precompObj << ": " << precompH << " " << findDependencies(precompH).join(" \\\n\t\t") + t << precompObj << ": " << precompH << " " << escapeDependencyPaths(findDependencies(precompH)).join(" \\\n\t\t") << "\n\t" << "$(CXX) " + precompRule +" $(CXXFLAGS) $(INCPATH) -TP " << precompH << endl << endl; } } From 09e2e77be25e02ff1c3ba432d739fbc5fe860ec7 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 9 Feb 2012 14:39:40 +0200 Subject: [PATCH 140/406] Handle TouchCancel in gui and widgets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I31739840348d88ae408ac1aae2399f6328ccdd43 Reviewed-by: Samuel Rødal --- src/gui/kernel/qguiapplication.cpp | 55 ++++++++- src/gui/kernel/qguiapplication_p.h | 7 ++ src/gui/kernel/qwindow.cpp | 1 + src/gui/kernel/qwindowsysteminterface_qpa.cpp | 16 +++ src/gui/kernel/qwindowsysteminterface_qpa.h | 2 + src/widgets/kernel/qapplication.cpp | 22 ++++ src/widgets/kernel/qapplication_p.h | 1 + src/widgets/kernel/qwidget.cpp | 2 + src/widgets/kernel/qwidgetwindow_qpa.cpp | 6 +- tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 116 +++++++++++++++++- 10 files changed, 221 insertions(+), 7 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index d41c90636bc..b17cf5824c3 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -184,7 +184,8 @@ QGuiApplication::~QGuiApplication() QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv, int flags) : QCoreApplicationPrivate(argc, argv, flags), styleHints(0), - inputMethod(0) + inputMethod(0), + lastTouchType(QEvent::TouchEnd) { self = this; application_type = QCoreApplication::GuiClient; @@ -950,8 +951,53 @@ Q_GUI_EXPORT bool operator==(const QGuiApplicationPrivate::ActiveTouchPointsKey void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e) { - QWindow *window = e->window.data(); QGuiApplicationPrivate *d = self; + + if (e->touchType == QEvent::TouchCancel) { + // The touch sequence has been canceled (e.g. by the compositor). + // Send the TouchCancel to all windows with active touches and clean up. + QTouchEvent touchEvent(QEvent::TouchCancel, e->device, e->modifiers); + touchEvent.setTimestamp(e->timestamp); + QHash::const_iterator it + = self->activeTouchPoints.constBegin(), ite = self->activeTouchPoints.constEnd(); + QSet windowsNeedingCancel; + while (it != ite) { + QWindow *w = it->window.data(); + if (w) + windowsNeedingCancel.insert(w); + ++it; + } + for (QSet::const_iterator winIt = windowsNeedingCancel.constBegin(), + winItEnd = windowsNeedingCancel.constEnd(); winIt != winItEnd; ++winIt) { + touchEvent.setWindow(*winIt); + QGuiApplication::sendSpontaneousEvent(*winIt, &touchEvent); + } + if (!self->synthesizedMousePoints.isEmpty() && !e->synthetic) { + for (QHash::const_iterator synthIt = self->synthesizedMousePoints.constBegin(), + synthItEnd = self->synthesizedMousePoints.constEnd(); synthIt != synthItEnd; ++synthIt) { + QWindowSystemInterfacePrivate::MouseEvent fake(synthIt.key(), + e->timestamp, + synthIt->pos, + synthIt->screenPos, + Qt::NoButton, + e->modifiers); + fake.synthetic = true; + processMouseEvent(&fake); + } + self->synthesizedMousePoints.clear(); + } + self->activeTouchPoints.clear(); + self->lastTouchType = e->touchType; + return; + } + + // Prevent sending ill-formed event sequences: Cancel can only be followed by a Begin. + if (self->lastTouchType == QEvent::TouchCancel && e->touchType != QEvent::TouchBegin) + return; + + self->lastTouchType = e->touchType; + + QWindow *window = e->window.data(); typedef QPair > StatesAndTouchPoints; QHash windowsNeedingEvents; @@ -1101,6 +1147,8 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To // exclude touchpads as those generate their own mouse events if (touchEvent.device()->type() != QTouchDevice::TouchPad) { Qt::MouseButtons b = eventType == QEvent::TouchEnd ? Qt::NoButton : Qt::LeftButton; + if (b == Qt::NoButton) + self->synthesizedMousePoints.clear(); QList touchPoints = touchEvent.touchPoints(); if (eventType == QEvent::TouchBegin) @@ -1109,6 +1157,9 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To for (int i = 0; i < touchPoints.count(); ++i) { const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i); if (touchPoint.id() == m_fakeMouseSourcePointId) { + if (b != Qt::NoButton) + self->synthesizedMousePoints.insert(w, SynthesizedMouseData( + touchPoint.pos(), touchPoint.screenPos())); QWindowSystemInterfacePrivate::MouseEvent fake(w, e->timestamp, touchPoint.pos(), touchPoint.screenPos(), diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index d9444ebe95b..3ca007fb362 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -199,6 +199,13 @@ public: QTouchEvent::TouchPoint touchPoint; }; QHash activeTouchPoints; + QEvent::Type lastTouchType; + struct SynthesizedMouseData { + SynthesizedMouseData(const QPointF &p, const QPointF &sp) : pos(p), screenPos(sp) { } + QPointF pos; + QPointF screenPos; + }; + QHash synthesizedMousePoints; private: void init(); diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index b451a6ee331..43b7e391035 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -943,6 +943,7 @@ bool QWindow::event(QEvent *ev) case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: + case QEvent::TouchCancel: touchEvent(static_cast(ev)); break; diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.cpp b/src/gui/kernel/qwindowsysteminterface_qpa.cpp index ae94b75076e..f4f7551c049 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa.cpp +++ b/src/gui/kernel/qwindowsysteminterface_qpa.cpp @@ -296,6 +296,22 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QTo QWindowSystemInterfacePrivate::queueWindowSystemEvent(e); } +void QWindowSystemInterface::handleTouchCancelEvent(QWindow *w, QTouchDevice *device, + Qt::KeyboardModifiers mods) +{ + unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed(); + handleTouchCancelEvent(w, time, device, mods); +} + +void QWindowSystemInterface::handleTouchCancelEvent(QWindow *w, ulong timestamp, QTouchDevice *device, + Qt::KeyboardModifiers mods) +{ + QWindowSystemInterfacePrivate::TouchEvent *e = + new QWindowSystemInterfacePrivate::TouchEvent(w, timestamp, QEvent::TouchCancel, device, + QList(), mods); + QWindowSystemInterfacePrivate::queueWindowSystemEvent(e); +} + void QWindowSystemInterface::handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation orientation) { QWindowSystemInterfacePrivate::ScreenOrientationEvent *e = diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.h b/src/gui/kernel/qwindowsysteminterface_qpa.h index b99363eda77..28ec68ec590 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa.h +++ b/src/gui/kernel/qwindowsysteminterface_qpa.h @@ -101,6 +101,8 @@ public: const QList &points, Qt::KeyboardModifiers mods = Qt::NoModifier); static void handleTouchEvent(QWindow *w, ulong timestamp, QTouchDevice *device, const QList &points, Qt::KeyboardModifiers mods = Qt::NoModifier); + static void handleTouchCancelEvent(QWindow *w, QTouchDevice *device, Qt::KeyboardModifiers mods = Qt::NoModifier); + static void handleTouchCancelEvent(QWindow *w, ulong timestamp, QTouchDevice *device, Qt::KeyboardModifiers mods = Qt::NoModifier); static void handleGeometryChange(QWindow *w, const QRect &newRect); static void handleSynchronousGeometryChange(QWindow *w, const QRect &newRect); diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index d2b4e01c0b3..8d776e2f29a 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -5200,6 +5200,28 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window, } } +void QApplicationPrivate::translateTouchCancel(QTouchDevice *device, ulong timestamp) +{ + QTouchEvent touchEvent(QEvent::TouchCancel, device, QApplication::keyboardModifiers()); + touchEvent.setTimestamp(timestamp); + QHash::const_iterator it + = self->activeTouchPoints.constBegin(), ite = self->activeTouchPoints.constEnd(); + QSet widgetsNeedingCancel; + while (it != ite) { + QWidget *widget = static_cast(it->target.data()); + if (widget) + widgetsNeedingCancel.insert(widget); + ++it; + } + for (QSet::const_iterator widIt = widgetsNeedingCancel.constBegin(), + widItEnd = widgetsNeedingCancel.constEnd(); widIt != widItEnd; ++widIt) { + QWidget *widget = *widIt; + touchEvent.setWindow(widget->windowHandle()); + touchEvent.setTarget(widget); + QApplication::sendSpontaneousEvent(widget, &touchEvent); + } +} + #ifndef QT_NO_GESTURES QGestureManager* QGestureManager::instance() { diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index d9d184d51ae..b4cd22df132 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -386,6 +386,7 @@ public: QTouchDevice *device, const QList &touchPoints, ulong timestamp); + static void translateTouchCancel(QTouchDevice *device, ulong timestamp); private: #ifdef Q_WS_QWS diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 008f0391bc5..cd3669717dd 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -7776,6 +7776,7 @@ bool QWidget::event(QEvent *event) case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: + case QEvent::TouchCancel: case QEvent::ContextMenu: #ifndef QT_NO_WHEELEVENT case QEvent::Wheel: @@ -8178,6 +8179,7 @@ bool QWidget::event(QEvent *event) case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: + case QEvent::TouchCancel: { event->ignore(); break; diff --git a/src/widgets/kernel/qwidgetwindow_qpa.cpp b/src/widgets/kernel/qwidgetwindow_qpa.cpp index e7ba4853a08..c2524567f10 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa.cpp +++ b/src/widgets/kernel/qwidgetwindow_qpa.cpp @@ -110,6 +110,7 @@ bool QWidgetWindow::event(QEvent *event) case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: + case QEvent::TouchCancel: handleTouchEvent(static_cast(event)); return true; @@ -289,7 +290,10 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) void QWidgetWindow::handleTouchEvent(QTouchEvent *event) { - QApplicationPrivate::translateRawTouchEvent(m_widget, event->device(), event->touchPoints(), event->timestamp()); + if (event->type() == QEvent::TouchCancel) + QApplicationPrivate::translateTouchCancel(event->device(), event->timestamp()); + else + QApplicationPrivate::translateRawTouchEvent(m_widget, event->device(), event->touchPoints(), event->timestamp()); } void QWidgetWindow::handleKeyEvent(QKeyEvent *event) diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index d7c153dca18..8c4c53cc5cd 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -57,6 +57,8 @@ private slots: void touchToMouseTranslation(); void mouseToTouchTranslation(); void mouseToTouchLoop(); + void touchCancel(); + void touchCancelWithTouchToMouse(); void orientation(); void close(); void initTestCase() @@ -274,6 +276,7 @@ public: event->ignore(); return; } + touchEventType = event->type(); QList points = event->touchPoints(); for (int i = 0; i < points.count(); ++i) { switch (points.at(i).state()) { @@ -283,6 +286,9 @@ public: case Qt::TouchPointReleased: ++touchReleasedCount; break; + case Qt::TouchPointMoved: + ++touchMovedCount; + break; default: break; } @@ -292,14 +298,15 @@ public: InputTestWindow() { keyPressCode = keyReleaseCode = 0; mousePressButton = mouseReleaseButton = 0; - touchPressedCount = touchReleasedCount = 0; - ignoreMouse = ignoreTouch = 0; + touchPressedCount = touchReleasedCount = touchMovedCount = 0; + ignoreMouse = ignoreTouch = false; } int keyPressCode, keyReleaseCode; int mousePressButton, mouseReleaseButton, mouseMoveButton; QPointF mousePressScreenPos, mouseMoveScreenPos; - int touchPressedCount, touchReleasedCount; + int touchPressedCount, touchReleasedCount, touchMovedCount; + QEvent::Type touchEventType; bool ignoreMouse, ignoreTouch; }; @@ -480,7 +487,108 @@ void tst_QWindow::mouseToTouchLoop() QCoreApplication::processEvents(); qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false); - qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false); + qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true); +} + +void tst_QWindow::touchCancel() +{ + InputTestWindow window; + window.setGeometry(80, 80, 40, 40); + window.show(); + QTest::qWaitForWindowShown(&window); + + QList points; + QWindowSystemInterface::TouchPoint tp1; + tp1.id = 1; + + // Start a touch. + tp1.state = Qt::TouchPointPressed; + tp1.area = QRect(10, 10, 4, 4); + points << tp1; + QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points); + QCoreApplication::processEvents(); + QTRY_COMPARE(window.touchEventType, QEvent::TouchBegin); + QTRY_COMPARE(window.touchPressedCount, 1); + + // Cancel the active touch sequence. + QWindowSystemInterface::handleTouchCancelEvent(&window, touchDevice); + QCoreApplication::processEvents(); + QTRY_COMPARE(window.touchEventType, QEvent::TouchCancel); + + // Send a move -> will not be delivered due to the cancellation. + QTRY_COMPARE(window.touchMovedCount, 0); + points[0].state = Qt::TouchPointMoved; + tp1.area.adjust(2, 2, 2, 2); + QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points); + QCoreApplication::processEvents(); + QTRY_COMPARE(window.touchMovedCount, 0); + + // Likewise. The only allowed transition is TouchCancel -> TouchBegin. + QTRY_COMPARE(window.touchReleasedCount, 0); + points[0].state = Qt::TouchPointReleased; + QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points); + QCoreApplication::processEvents(); + QTRY_COMPARE(window.touchReleasedCount, 0); + + // Start a new sequence -> from this point on everything should go through normally. + points[0].state = Qt::TouchPointPressed; + QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points); + QCoreApplication::processEvents(); + QTRY_COMPARE(window.touchEventType, QEvent::TouchBegin); + QTRY_COMPARE(window.touchPressedCount, 2); + + points[0].state = Qt::TouchPointMoved; + tp1.area.adjust(2, 2, 2, 2); + QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points); + QCoreApplication::processEvents(); + QTRY_COMPARE(window.touchMovedCount, 1); + + points[0].state = Qt::TouchPointReleased; + QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points); + QCoreApplication::processEvents(); + QTRY_COMPARE(window.touchReleasedCount, 1); +} + +void tst_QWindow::touchCancelWithTouchToMouse() +{ + InputTestWindow window; + window.ignoreTouch = true; + window.setGeometry(80, 80, 40, 40); + window.show(); + QTest::qWaitForWindowShown(&window); + + QList points; + QWindowSystemInterface::TouchPoint tp1; + tp1.id = 1; + + tp1.state = Qt::TouchPointPressed; + tp1.area = QRect(100, 100, 4, 4); + points << tp1; + QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points); + QCoreApplication::processEvents(); + QTRY_COMPARE(window.mousePressButton, int(Qt::LeftButton)); + QTRY_COMPARE(window.mousePressScreenPos, points[0].area.center()); + + // Cancel the touch. Should result in a mouse release for windows that have + // have an active touch-to-mouse sequence. + QWindowSystemInterface::handleTouchCancelEvent(0, touchDevice); + QCoreApplication::processEvents(); + + QTRY_COMPARE(window.mouseReleaseButton, int(Qt::LeftButton)); + + // Now change the window to accept touches. + window.mousePressButton = window.mouseReleaseButton = 0; + window.ignoreTouch = false; + + // Send a touch, there will be no mouse event generated. + QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points); + QCoreApplication::processEvents(); + QTRY_COMPARE(window.mousePressButton, 0); + + // Cancel the touch. It should not result in a mouse release with this window. + QWindowSystemInterface::handleTouchCancelEvent(0, touchDevice); + QCoreApplication::processEvents(); + QTRY_COMPARE(window.mouseReleaseButton, 0); } void tst_QWindow::orientation() From 482d96a0c5d523ace63f56bda6851926b4469dd0 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Sun, 29 Jan 2012 13:54:19 +0100 Subject: [PATCH 141/406] Force -fPIE on ELF if Qt is built with reduced relocations Put in qconfig.h whether qt is compiled with reduced relocations. When using -Bsymbolic-functions (enabled by default on Qt) but not -fPIE, the comparison of the function pointers fail because the addresses are different in Qt, and in the executable. Hence we now enable -fPIE by default on qmake, and force a compilation error when it is not enabled and built with reduced relocations. Done-with: Sune Vuorela Change-Id: Ib3fdba06fab6e8a93b75b4c6cf16cc973ab335db Reviewed-by: Bradley T. Hughes Reviewed-by: Thiago Macieira --- configure | 5 +++++ mkspecs/common/gcc-base.conf | 2 ++ src/corelib/global/qglobal.h | 6 ++++++ tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 3 --- tests/auto/tools/moc/tst_moc.cpp | 4 ++-- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/configure b/configure index a3b94e1eee7..d497c2f77c6 100755 --- a/configure +++ b/configure @@ -7066,6 +7066,11 @@ else echo "#define QT_POINTER_SIZE $?" >>"$outpath/src/corelib/global/qconfig.h.new" fi +#REDUCE_RELOCATIONS is a elf/unix only thing, so not in windows configure.exe +if [ "$CFG_REDUCE_RELOCATIONS" = "yes" ]; then + echo "#define QT_REDUCE_RELOCATIONS" >>"$outpath/src/corelib/global/qconfig.h.new" +fi + echo "" >>"$outpath/src/corelib/global/qconfig.h.new" diff --git a/mkspecs/common/gcc-base.conf b/mkspecs/common/gcc-base.conf index 0e906663502..28e3b87b5d8 100644 --- a/mkspecs/common/gcc-base.conf +++ b/mkspecs/common/gcc-base.conf @@ -39,6 +39,7 @@ QMAKE_CFLAGS_RELEASE += -O2 QMAKE_CFLAGS_DEBUG += -g QMAKE_CFLAGS_SHLIB += -fPIC QMAKE_CFLAGS_STATIC_LIB += -fPIC +QMAKE_CFLAGS_APP += -fPIE QMAKE_CFLAGS_YACC += -Wno-unused -Wno-parentheses QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden @@ -50,6 +51,7 @@ QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG QMAKE_CXXFLAGS_SHLIB += $$QMAKE_CFLAGS_SHLIB QMAKE_CXXFLAGS_STATIC_LIB += $$QMAKE_CFLAGS_STATIC_LIB +QMAKE_CXXFLAGS_APP += $$QMAKE_CFLAGS_APP QMAKE_CXXFLAGS_YACC += $$QMAKE_CFLAGS_YACC QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 33b5b8bd76d..ffeb8a2bab1 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -62,6 +62,7 @@ #include #endif + #include #include #include @@ -1783,6 +1784,11 @@ Q_CORE_EXPORT int qrand(); # endif #endif +#if defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && !defined(__PIC__) +# error "You must build your code with position independent code if Qt was built with -reduce-relocations. "\ + "Compile your code with -fPIC or -fPIE." +#endif + namespace QtPrivate { //like std::enable_if template struct QEnableIf; diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 91b93e4ccd1..8f4203a2163 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -4152,9 +4152,6 @@ void tst_QObject::pointerConnect() QVERIFY( connect( s, &SenderObject::signal1 , r2, &ReceiverObject::slot1 ) ); QVERIFY( connect( s, &SenderObject::signal1 , r1, &ReceiverObject::slot3 ) ); QVERIFY( connect( s, &SenderObject::signal3 , r1, &ReceiverObject::slot3 ) ); -#if defined(Q_CC_GNU) && defined(Q_OS_UNIX) - QEXPECT_FAIL("", "Test may fail due to failing comparison of pointers to member functions caused by problems with -reduce-relocations on this platform.", Continue); -#endif QVERIFY2( connect( &timer, &QTimer::timeout, r1, &ReceiverObject::deleteLater ), "Signal connection failed most likely due to failing comparison of pointers to member functions caused by problems with -reduce-relocations on this platform."); diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 7c47d60e81e..0aa1a68a646 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -614,7 +614,7 @@ void tst_Moc::oldStyleCasts() QStringList args; args << "-c" << "-x" << "c++" << "-Wold-style-cast" << "-I" << "." - << "-I" << qtIncludePath << "-o" << "/dev/null" << "-"; + << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIE" << "-"; proc.start("gcc", args); QVERIFY(proc.waitForStarted()); proc.write(mocOut); @@ -683,7 +683,7 @@ void tst_Moc::inputFileNameWithDotsButNoExtension() QStringList args; args << "-c" << "-x" << "c++" << "-I" << ".." - << "-I" << qtIncludePath << "-o" << "/dev/null" << "-"; + << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIE" << "-"; proc.start("gcc", args); QVERIFY(proc.waitForStarted()); proc.write(mocOut); From ff2886db6a3308c1f4ee0879af497a5d43c33133 Mon Sep 17 00:00:00 2001 From: Jan-Arve Saether Date: Thu, 9 Feb 2012 11:20:34 +0100 Subject: [PATCH 142/406] Move all usages of Relation enum values to QAccessible::relations() Next step is to remove navigate(), but that has to be done in qtdeclarative first. Change-Id: I01ea1386c092446be04cc19d0f70adf53f094adc Reviewed-by: Frederik Gladhorn --- src/gui/accessible/qaccessible.cpp | 6 +- src/gui/accessible/qaccessible.h | 5 +- .../accessible/widgets/simplewidgets.cpp | 61 +++--- .../accessible/widgets/simplewidgets.h | 3 +- .../windows/qwindowsaccessibility.cpp | 23 +++ src/widgets/accessible/qaccessiblewidget.cpp | 179 +++++++----------- src/widgets/accessible/qaccessiblewidget.h | 3 +- .../qaccessibility/tst_qaccessibility.cpp | 35 ++++ 8 files changed, 153 insertions(+), 162 deletions(-) diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index dd0468d9f98..6664e5d3128 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -894,17 +894,19 @@ QAccessibleInterface *QAccessibleEvent::accessibleInterface() const */ QAccessible::Relation QAccessibleInterface::relationTo(const QAccessibleInterface *) const { - return QAccessible::Unrelated; + return QAccessible::Relation(); } /*! Returns the meaningful relations to other widgets. Usually this will not return parent/child relations, unless they are handled in a specific way such as in tree views. It will typically return the labelled-by and label relations. + It should never return itself. \sa relationTo(), navigate() */ -QVector > QAccessibleInterface::relations() const +QVector > +QAccessibleInterface::relations(QAccessible::Relation /*match = QAccessible::AllRelations*/) const { return QVector >(); } diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index 214ec20f9ca..9fc13a827ba 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -306,12 +306,11 @@ public: }; enum RelationFlag { - Unrelated = 0x00000000, Label = 0x00020000, Labelled = 0x00040000, Controller = 0x00080000, Controlled = 0x00100000, - LogicalMask = 0x00ff0000 + AllRelations = 0xffffffff }; Q_DECLARE_FLAGS(Relation, RelationFlag) @@ -380,7 +379,7 @@ public: // relations virtual QAccessible::Relation relationTo(const QAccessibleInterface *other) const; - virtual QVector > relations() const; + virtual QVector > relations(QAccessible::Relation match = QAccessible::AllRelations) const; virtual QAccessibleInterface *focusChild() const; virtual QAccessibleInterface *childAt(int x, int y) const = 0; diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp index 652150f3926..0fdd4490f7c 100644 --- a/src/plugins/accessible/widgets/simplewidgets.cpp +++ b/src/plugins/accessible/widgets/simplewidgets.cpp @@ -54,6 +54,7 @@ #include #include #include +#include #ifdef Q_OS_MAC #include @@ -427,52 +428,36 @@ QString QAccessibleDisplay::text(QAccessible::Text t) const return qt_accStripAmp(str); } -QAccessible::Relation QAccessibleDisplay::relationTo(const QAccessibleInterface *other) const +/*! \reimp */ +QVector > +QAccessibleDisplay::relations(QAccessible::Relation match /*= QAccessible::AllRelations*/) const { - QAccessible::Relation relation = QAccessibleWidget::relationTo(other); + QVector > rels = QAccessibleWidget::relations(match); + if (match & QAccessible::Labelled) { + QVarLengthArray relatedObjects; - QObject *o = other->object(); - QLabel *label = qobject_cast(object()); - if (label) { #ifndef QT_NO_SHORTCUT - if (o == label->buddy()) - relation |= QAccessible::Label; + if (QLabel *label = qobject_cast(object())) { + relatedObjects.append(label->buddy()); #endif #ifndef QT_NO_GROUPBOX - } else { - QGroupBox *groupbox = qobject_cast(object()); - if (groupbox && !groupbox->title().isEmpty()) - if (groupbox->children().contains(o)) - relation |= QAccessible::Label; -#endif - } - return relation; -} - -int QAccessibleDisplay::navigate(QAccessible::RelationFlag rel, int entry, QAccessibleInterface **target) const -{ - *target = 0; - if (rel == QAccessible::Labelled) { - QObject *targetObject = 0; - QLabel *label = qobject_cast(object()); - if (label) { -#ifndef QT_NO_SHORTCUT - if (entry == 1) - targetObject = label->buddy(); -#endif -#ifndef QT_NO_GROUPBOX - } else { - QGroupBox *groupbox = qobject_cast(object()); - if (groupbox && !groupbox->title().isEmpty()) - *target = child(entry - 1); + } else if (QGroupBox *groupbox = qobject_cast(object())) { + if (!groupbox->title().isEmpty()) { + const QList kids = childWidgets(widget()); + for (int i = 0; i < kids.count(); ++i) { + relatedObjects.append(kids.at(i)); + } + } #endif } - if (targetObject) - *target = QAccessible::queryAccessibleInterface(targetObject); - if (*target) - return 0; + for (int i = 0; i < relatedObjects.count(); ++i) { + const QAccessible::Relation rel = QAccessible::Labelled; + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(relatedObjects.at(i)); + if (iface) + rels.append(qMakePair(iface, rel)); + } } - return QAccessibleWidget::navigate(rel, entry, target); + return rels; } void *QAccessibleDisplay::interface_cast(QAccessible::InterfaceType t) diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h index bbdececadf8..c2287754214 100644 --- a/src/plugins/accessible/widgets/simplewidgets.h +++ b/src/plugins/accessible/widgets/simplewidgets.h @@ -104,8 +104,7 @@ public: QString text(QAccessible::Text t) const; QAccessible::Role role() const; - QAccessible::Relation relationTo(const QAccessibleInterface *other) const; - int navigate(QAccessible::RelationFlag, int entry, QAccessibleInterface **target) const; + QVector >relations(QAccessible::Relation match = QAccessible::AllRelations) const; void *interface_cast(QAccessible::InterfaceType t); // QAccessibleImageInterface diff --git a/src/plugins/platforms/windows/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/qwindowsaccessibility.cpp index 2c49d8614d0..e36e2559476 100644 --- a/src/plugins/platforms/windows/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/qwindowsaccessibility.cpp @@ -988,6 +988,17 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accKeyboardShortcut(VARIANT va return *pszKeyboardShortcut ? S_OK : S_FALSE; } +static QAccessibleInterface *relatedInterface(QAccessibleInterface *iface, QAccessible::RelationFlag flag) +{ + typedef QPair RelationPair; + QVector rels = iface->relations(flag); + + for (int i = 1; i < rels.count(); ++i) + delete rels.at(i).first; + + return rels.value(0).first; +} + // moz: [important] HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accName(VARIANT varID, BSTR* pszName) { @@ -1001,8 +1012,20 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accName(VARIANT varID, BSTR* p if (!child) return E_FAIL; name = child->text(QAccessible::Name); + if (name.isEmpty()) { + if (QAccessibleInterface *labelInterface = relatedInterface(child.data(), QAccessible::Label)) { + name = labelInterface->text(QAccessible::Name); + delete labelInterface; + } + } } else { name = accessible->text(QAccessible::Name); + if (name.isEmpty()) { + if (QAccessibleInterface *labelInterface = relatedInterface(accessible, QAccessible::Label)) { + name = labelInterface->text(QAccessible::Name); + delete labelInterface; + } + } } if (name.size()) { *pszName = QStringToBSTR(name); diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index 56ba990382f..feac42780dc 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -327,37 +327,76 @@ static inline bool isAncestor(const QObject *obj, const QObject *child) return false; } - /*! \reimp */ -QAccessible::Relation QAccessibleWidget::relationTo(const QAccessibleInterface *other) const +QVector > +QAccessibleWidget::relations(QAccessible::Relation match /*= QAccessible::AllRelations*/) const { - QAccessible::Relation relation = QAccessible::Unrelated; - if (d->asking == this) // recursive call - return relation; - - QObject *o = other ? other->object() : 0; - if (!o) - return relation; - - QACConnectionObject *connectionObject = (QACConnectionObject*)object(); - for (int sig = 0; sig < d->primarySignals.count(); ++sig) { - if (connectionObject->isSender(o, d->primarySignals.at(sig).toAscii())) { - relation |= QAccessible::Controller; - break; + QVector > rels; + if (match & QAccessible::Label) { + const QAccessible::Relation rel = QAccessible::Label; + if (QWidget *parent = widget()->parentWidget()) { +#ifndef QT_NO_SHORTCUT + // first check for all siblings that are labels to us + // ideally we would go through all objects and check, but that + // will be too expensive + const QList kids = childWidgets(parent); + for (int i = 0; i < kids.count(); ++i) { + if (QLabel *labelSibling = qobject_cast(kids.at(i))) { + if (labelSibling->buddy() == widget()) { + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(labelSibling); + rels.append(qMakePair(iface, rel)); + } + } + } +#endif +#ifndef QT_NO_GROUPBOX + QGroupBox *groupbox = qobject_cast(parent); + if (groupbox && !groupbox->title().isEmpty()) { + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(groupbox); + rels.append(qMakePair(iface, rel)); + } +#endif } } - // test for passive relationships. - // d->asking protects from endless recursion. - d->asking = this; - int inverse = other->relationTo(this); - d->asking = 0; - if (inverse & QAccessible::Controller) - relation |= QAccessible::Controlled; - if (inverse & QAccessible::Label) - relation |= QAccessible::Labelled; + if (match & QAccessible::Controller) { + const QAccessible::Relation rel = QAccessible::Controller; + QACConnectionObject *connectionObject = (QACConnectionObject*)object(); + const QObjectList senderList = connectionObject->senderList(); + for (int s = 0; s < senderList.count(); ++s) { + QObject *sender = senderList.at(s); + if (sender->isWidgetType() && sender != object()) { + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(sender); + QACConnectionObject *connectionSender = (QACConnectionObject*)sender; + QStringList senderPrimarySignals = static_cast(iface)->d->primarySignals; + for (int sig = 0; sig < senderPrimarySignals.count(); ++sig) { + const QByteArray strSignal = senderPrimarySignals.at(sig).toAscii(); + if (connectionSender->isSender(object(), strSignal.constData())) + rels.append(qMakePair(iface, rel)); + } + } + } + } - return relation; + if (match & QAccessible::Controlled) { + QObjectList allReceivers; + QACConnectionObject *connectionObject = (QACConnectionObject*)object(); + for (int sig = 0; sig < d->primarySignals.count(); ++sig) { + const QObjectList receivers = connectionObject->receiverList(d->primarySignals.at(sig).toAscii()); + allReceivers += receivers; + } + + allReceivers.removeAll(object()); //### The object might connect to itself internally + + for (int i = 0; i < allReceivers.count(); ++i) { + const QAccessible::Relation rel = QAccessible::Controlled; + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(allReceivers.at(i)); + if (iface) + rels.append(qMakePair(iface, rel)); + } + } + + return rels; } /*! \reimp */ @@ -393,96 +432,6 @@ QAccessibleInterface *QAccessibleWidget::focusChild() const return 0; } -/*! \reimp */ -int QAccessibleWidget::navigate(QAccessible::RelationFlag relation, int entry, - QAccessibleInterface **target) const -{ - if (!target) - return -1; - - *target = 0; - QObject *targetObject = 0; - - switch (relation) { - // Logical - case QAccessible::Label: - if (entry > 0) { - QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject()); - if (!pIface) - return -1; - - // first check for all siblings that are labels to us - // ideally we would go through all objects and check, but that - // will be too expensive - int sibCount = pIface->childCount(); - QAccessibleInterface *candidate = 0; - for (int i = 0; i < sibCount && entry; ++i) { - candidate = pIface->child(i); - Q_ASSERT(candidate); - if (candidate->relationTo(this) & QAccessible::Label) - --entry; - if (!entry) - break; - - delete candidate; - candidate = 0; - } - if (!candidate) { - if (pIface->relationTo(this) & QAccessible::Label) - --entry; - if (!entry) - candidate = pIface; - } - if (pIface != candidate) - delete pIface; - - *target = candidate; - if (*target) - return 0; - } - break; - case QAccessible::Labelled: // only implemented in subclasses - break; - case QAccessible::Controller: - if (entry > 0) { - // check all senders we are connected to, - // and figure out which one are controllers to us - QACConnectionObject *connectionObject = (QACConnectionObject*)object(); - QObjectList allSenders = connectionObject->senderList(); - QObjectList senders; - for (int s = 0; s < allSenders.size(); ++s) { - QObject *sender = allSenders.at(s); - QAccessibleInterface *candidate = QAccessible::queryAccessibleInterface(sender); - if (!candidate) - continue; - if (candidate->relationTo(this) & QAccessible::Controller) - senders << sender; - delete candidate; - } - if (entry <= senders.size()) - targetObject = senders.at(entry-1); - } - break; - case QAccessible::Controlled: - if (entry > 0) { - QObjectList allReceivers; - QACConnectionObject *connectionObject = (QACConnectionObject*)object(); - for (int sig = 0; sig < d->primarySignals.count(); ++sig) { - QObjectList receivers = connectionObject->receiverList(d->primarySignals.at(sig).toAscii()); - allReceivers += receivers; - } - if (entry <= allReceivers.size()) - targetObject = allReceivers.at(entry-1); - } - break; - default: - break; - } - - *target = QAccessible::queryAccessibleInterface(targetObject); - return *target ? 0 : -1; -} - /*! \reimp */ int QAccessibleWidget::childCount() const { diff --git a/src/widgets/accessible/qaccessiblewidget.h b/src/widgets/accessible/qaccessiblewidget.h index d34d852e277..4b480ca0ee7 100644 --- a/src/widgets/accessible/qaccessiblewidget.h +++ b/src/widgets/accessible/qaccessiblewidget.h @@ -61,14 +61,13 @@ public: QWindow *window() const; int childCount() const; int indexOfChild(const QAccessibleInterface *child) const; - QAccessible::Relation relationTo(const QAccessibleInterface *other) const; + QVector > relations(QAccessible::Relation match = QAccessible::AllRelations) const; QAccessibleInterface *focusChild() const; QRect rect() const; QAccessibleInterface *parent() const; QAccessibleInterface *child(int index) const; - int navigate(QAccessible::RelationFlag rel, int entry, QAccessibleInterface **target) const; QString text(QAccessible::Text t) const; QAccessible::Role role() const; diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index 63770f14cb0..b2a4b1cca24 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -846,6 +846,17 @@ public Q_SLOTS: } }; +static QAccessibleInterface *relatedInterface(QAccessibleInterface *iface, QAccessible::RelationFlag flag) +{ + typedef QPair RelationPair; + QVector rels = iface->relations(flag); + + for (int i = 1; i < rels.count(); ++i) + delete rels.at(i).first; + + return rels.value(0).first; +} + void tst_QAccessibility::buttonTest() { QWidget window; @@ -879,6 +890,30 @@ void tst_QAccessibility::buttonTest() toggletool.setText("Toggle"); toggletool.setMinimumSize(20,20); + // test Controller/Controlled relations + { + QCheckBox toggler("Toggle me!", &window); + bool ok = connect(&pushButton, SIGNAL(clicked()), &toggler, SLOT(toggle())); + QCOMPARE(ok, true); + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&toggler); + QVERIFY(iface); + QCOMPARE(iface->role(), QAccessible::CheckBox); + QAccessibleInterface *buttonIFace = relatedInterface(iface, QAccessible::Controller); + QVERIFY(buttonIFace); + QCOMPARE(buttonIFace->role(), QAccessible::Button); + QCOMPARE(buttonIFace->object(), &pushButton); + delete buttonIFace; + delete iface; + + buttonIFace = QAccessible::queryAccessibleInterface(&pushButton); + QVERIFY(buttonIFace); + QCOMPARE(buttonIFace->role(), QAccessible::Button); + iface = relatedInterface(buttonIFace, QAccessible::Controlled); + QVERIFY(iface); + QCOMPARE(iface->object(), &toggler); + + } + // test push button QAccessibleInterface* interface = QAccessible::queryAccessibleInterface(&pushButton); QAccessibleActionInterface* actionInterface = interface->actionInterface(); From c50f026a22b675bdebe61c2d185913926fdf8f1c Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Mon, 23 Jan 2012 07:49:04 +0100 Subject: [PATCH 143/406] Add tst_QEventDispatcher to tests/auto/corelib/kernel This will test the event dispatcher in corelib for proper timer and posted event handling. The test makes sure all of the necessary virtual functions are implemented and working as expected. This test doesn't test socket notifiers or Win32 event notifiers, as these are already covered in existing tests. Change-Id: I5540ffc4e6d7f97bcd6c3725d7e74c0ab9c97015 Reviewed-by: Robin Burchell --- tests/auto/corelib/kernel/kernel.pro | 1 + .../qeventdispatcher/qeventdispatcher.pro | 4 + .../qeventdispatcher/tst_qeventdispatcher.cpp | 186 ++++++++++++++++++ 3 files changed, 191 insertions(+) create mode 100644 tests/auto/corelib/kernel/qeventdispatcher/qeventdispatcher.pro create mode 100644 tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp diff --git a/tests/auto/corelib/kernel/kernel.pro b/tests/auto/corelib/kernel/kernel.pro index 3c697f4149b..1020899d943 100644 --- a/tests/auto/corelib/kernel/kernel.pro +++ b/tests/auto/corelib/kernel/kernel.pro @@ -1,6 +1,7 @@ TEMPLATE=subdirs SUBDIRS=\ qcoreapplication \ + qeventdispatcher \ qeventloop \ qmath \ qmetaobject \ diff --git a/tests/auto/corelib/kernel/qeventdispatcher/qeventdispatcher.pro b/tests/auto/corelib/kernel/qeventdispatcher/qeventdispatcher.pro new file mode 100644 index 00000000000..ff048d0429d --- /dev/null +++ b/tests/auto/corelib/kernel/qeventdispatcher/qeventdispatcher.pro @@ -0,0 +1,4 @@ +CONFIG += testcase +TARGET = tst_qeventdispatcher +QT = core testlib +SOURCES += tst_qeventdispatcher.cpp diff --git a/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp new file mode 100644 index 00000000000..07bd73f0d7e --- /dev/null +++ b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite 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 +#include + +enum { + PreciseTimerInterval = 10, + CoarseTimerInterval = 200, + VeryCoarseTimerInterval = 1000 +}; + +class tst_QEventDispatcher : public QObject +{ + Q_OBJECT + + QAbstractEventDispatcher *eventDispatcher; + int receivedEventType; + int timerIdFromEvent; + +protected: + bool event(QEvent *e); + +public: + inline tst_QEventDispatcher() + : QObject(), + eventDispatcher(QAbstractEventDispatcher::instance(thread())), + receivedEventType(-1), + timerIdFromEvent(-1) + { } + +private slots: + void registerTimer(); + /* void registerSocketNotifier(); */ // Not implemented here, see tst_QSocketNotifier instead + /* void registerEventNotifiier(); */ // Not implemented here, see tst_QWinEventNotifier instead + void sendPostedEvents(); +}; + +bool tst_QEventDispatcher::event(QEvent *e) +{ + switch (receivedEventType = e->type()) { + case QEvent::Timer: + { + timerIdFromEvent = static_cast(e)->timerId(); + return true; + } + default: + break; + } + return QObject::event(e); +} + +// test that the eventDispatcher's timer implementation is complete and working +void tst_QEventDispatcher::registerTimer() +{ +#define FIND_TIMERS() \ + do { \ + foundPrecise = false; \ + foundCoarse = false; \ + foundVeryCoarse = false; \ + for (int i = 0; i < registeredTimers.count(); ++i) { \ + const QAbstractEventDispatcher::TimerInfo &timerInfo = registeredTimers.at(i); \ + if (timerInfo.timerId == preciseTimerId) { \ + QCOMPARE(timerInfo.interval, int(PreciseTimerInterval)); \ + QCOMPARE(timerInfo.timerType, Qt::PreciseTimer); \ + foundPrecise = true; \ + } else if (timerInfo.timerId == coarseTimerId) { \ + QCOMPARE(timerInfo.interval, int(CoarseTimerInterval)); \ + QCOMPARE(timerInfo.timerType, Qt::CoarseTimer); \ + foundCoarse = true; \ + } else if (timerInfo.timerId == veryCoarseTimerId) { \ + QCOMPARE(timerInfo.interval, int(VeryCoarseTimerInterval)); \ + QCOMPARE(timerInfo.timerType, Qt::VeryCoarseTimer); \ + foundVeryCoarse = true; \ + } \ + } \ + } while (0) + + // start 3 timers, each with the different timer types and different intervals + int preciseTimerId = eventDispatcher->registerTimer(PreciseTimerInterval, Qt::PreciseTimer, this); + int coarseTimerId = eventDispatcher->registerTimer(CoarseTimerInterval, Qt::CoarseTimer, this); + int veryCoarseTimerId = eventDispatcher->registerTimer(VeryCoarseTimerInterval, Qt::VeryCoarseTimer, this); + QVERIFY(preciseTimerId > 0); + QVERIFY(coarseTimerId > 0); + QVERIFY(veryCoarseTimerId > 0); + + // check that all 3 are present in the eventDispatcher's registeredTimer() list + QList registeredTimers = eventDispatcher->registeredTimers(this); + QCOMPARE(registeredTimers.count(), 3); + bool foundPrecise, foundCoarse, foundVeryCoarse; + FIND_TIMERS(); + QVERIFY(foundPrecise && foundCoarse && foundVeryCoarse); + + // process events, waiting for the next event... this should only fire the precise timer + receivedEventType = -1; + timerIdFromEvent = -1; + QVERIFY(eventDispatcher->processEvents(QEventLoop::WaitForMoreEvents)); + QCOMPARE(receivedEventType, int(QEvent::Timer)); + QCOMPARE(timerIdFromEvent, preciseTimerId); + // now unregister it and make sure it's gone + eventDispatcher->unregisterTimer(preciseTimerId); + registeredTimers = eventDispatcher->registeredTimers(this); + QCOMPARE(registeredTimers.count(), 2); + FIND_TIMERS(); + QVERIFY(!foundPrecise && foundCoarse && foundVeryCoarse); + + // do the same again for the coarse timer + receivedEventType = -1; + timerIdFromEvent = -1; + QVERIFY(eventDispatcher->processEvents(QEventLoop::WaitForMoreEvents)); + QCOMPARE(receivedEventType, int(QEvent::Timer)); + QCOMPARE(timerIdFromEvent, coarseTimerId); + // now unregister it and make sure it's gone + eventDispatcher->unregisterTimer(coarseTimerId); + registeredTimers = eventDispatcher->registeredTimers(this); + QCOMPARE(registeredTimers.count(), 1); + FIND_TIMERS(); + QVERIFY(!foundPrecise && !foundCoarse && foundVeryCoarse); + + // not going to wait for the VeryCoarseTimer, would take too long, just unregister it + eventDispatcher->unregisterTimers(this); + registeredTimers = eventDispatcher->registeredTimers(this); + QVERIFY(registeredTimers.isEmpty()); + +#undef FIND_TIMERS +} + +// test that the eventDispatcher sends posted events correctly +void tst_QEventDispatcher::sendPostedEvents() +{ + QElapsedTimer elapsedTimer; + elapsedTimer.start(); + while (!elapsedTimer.hasExpired(200)) { + receivedEventType = -1; + QCoreApplication::postEvent(this, new QEvent(QEvent::User)); + + // event shouldn't be delivered as a result of posting + QCOMPARE(receivedEventType, -1); + + // since there is a pending posted event, this should not actually block, it should send the posted event and return + QVERIFY(eventDispatcher->processEvents(QEventLoop::WaitForMoreEvents)); + // event shouldn't be delivered as a result of posting + QCOMPARE(receivedEventType, int(QEvent::User)); + } +} + +QTEST_MAIN(tst_QEventDispatcher) +#include "tst_qeventdispatcher.moc" From 358c14821bf907025c1b3db6ff3f8e3bd3cdbb0f Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Mon, 23 Jan 2012 08:52:13 +0100 Subject: [PATCH 144/406] Run tst_QEventDispatcher with the GUI event dispatchers as well Since some GUI event dispatchers are complete reimplementations and do not build on the corelib ones, we want to run the same tests with the other dispatcher. Since this is a GUI test now, we need to make sure to drain system events queued during application startup to make sure we can reliably run the test functions. Change-Id: I4905db70bc8f8584c4ef1f4d767824040281452c Reviewed-by: Robin Burchell --- .../qeventdispatcher/tst_qeventdispatcher.cpp | 17 ++++++++++++++++- tests/auto/gui/kernel/kernel.pro | 1 + .../qguieventdispatcher/qguieventdispatcher.pro | 4 ++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 tests/auto/gui/kernel/qguieventdispatcher/qguieventdispatcher.pro diff --git a/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp index 07bd73f0d7e..d06912ee91a 100644 --- a/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp +++ b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp @@ -39,7 +39,11 @@ ** ****************************************************************************/ -#include +#ifdef QT_GUI_LIB +# include +#else +# include +#endif #include enum { @@ -68,6 +72,7 @@ public: { } private slots: + void initTestCase(); void registerTimer(); /* void registerSocketNotifier(); */ // Not implemented here, see tst_QSocketNotifier instead /* void registerEventNotifiier(); */ // Not implemented here, see tst_QWinEventNotifier instead @@ -88,6 +93,16 @@ bool tst_QEventDispatcher::event(QEvent *e) return QObject::event(e); } +// drain the system event queue after the test starts to avoid destabilizing the test functions +void tst_QEventDispatcher::initTestCase() +{ + QElapsedTimer elapsedTimer; + elapsedTimer.start(); + while (!elapsedTimer.hasExpired(CoarseTimerInterval) && eventDispatcher->processEvents(QEventLoop::AllEvents)) { + ; + } +} + // test that the eventDispatcher's timer implementation is complete and working void tst_QEventDispatcher::registerTimer() { diff --git a/tests/auto/gui/kernel/kernel.pro b/tests/auto/gui/kernel/kernel.pro index 1adae128cf3..116e9dd1f12 100644 --- a/tests/auto/gui/kernel/kernel.pro +++ b/tests/auto/gui/kernel/kernel.pro @@ -4,6 +4,7 @@ SUBDIRS=\ qdrag \ qevent \ qfileopenevent \ + qguieventdispatcher \ qguimetatype \ qguivariant \ qinputmethod \ diff --git a/tests/auto/gui/kernel/qguieventdispatcher/qguieventdispatcher.pro b/tests/auto/gui/kernel/qguieventdispatcher/qguieventdispatcher.pro new file mode 100644 index 00000000000..3057037e74c --- /dev/null +++ b/tests/auto/gui/kernel/qguieventdispatcher/qguieventdispatcher.pro @@ -0,0 +1,4 @@ +CONFIG += testcase +TARGET = tst_qguieventdispatcher +QT = core gui testlib +SOURCES += ../../../corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp From 8f8e3db6ae1328bb03e46dbbdea0d787b656bb97 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Mon, 6 Feb 2012 16:09:18 +0100 Subject: [PATCH 145/406] Test posted events in tst_QEventDispatcher with various flags Add QEventLoop::ProcessEventsFlags test data for tst_QEventDispatcher::sendPostedEvents() to test that posted events are sent when waiting for events and when not waiting. Change-Id: I99f9eb121d0b1ded725e19c5233922fc0a6b81e4 Reviewed-by: Robin Burchell --- .../qeventdispatcher/tst_qeventdispatcher.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp index d06912ee91a..bc6d6bfaddf 100644 --- a/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp +++ b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp @@ -76,6 +76,7 @@ private slots: void registerTimer(); /* void registerSocketNotifier(); */ // Not implemented here, see tst_QSocketNotifier instead /* void registerEventNotifiier(); */ // Not implemented here, see tst_QWinEventNotifier instead + void sendPostedEvents_data(); void sendPostedEvents(); }; @@ -178,9 +179,20 @@ void tst_QEventDispatcher::registerTimer() #undef FIND_TIMERS } +void tst_QEventDispatcher::sendPostedEvents_data() +{ + QTest::addColumn("processEventsFlagsInt"); + + QTest::newRow("WaitForMoreEvents") << int(QEventLoop::WaitForMoreEvents); + QTest::newRow("AllEvents") << int(QEventLoop::AllEvents); +} + // test that the eventDispatcher sends posted events correctly void tst_QEventDispatcher::sendPostedEvents() { + QFETCH(int, processEventsFlagsInt); + QEventLoop::ProcessEventsFlags processEventsFlags = QEventLoop::ProcessEventsFlags(processEventsFlagsInt); + QElapsedTimer elapsedTimer; elapsedTimer.start(); while (!elapsedTimer.hasExpired(200)) { @@ -191,7 +203,7 @@ void tst_QEventDispatcher::sendPostedEvents() QCOMPARE(receivedEventType, -1); // since there is a pending posted event, this should not actually block, it should send the posted event and return - QVERIFY(eventDispatcher->processEvents(QEventLoop::WaitForMoreEvents)); + QVERIFY(eventDispatcher->processEvents(processEventsFlags)); // event shouldn't be delivered as a result of posting QCOMPARE(receivedEventType, int(QEvent::User)); } From 8f7716c32cfc801b9dfed62126773fc7e4a39e01 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 7 Feb 2012 17:47:30 +0100 Subject: [PATCH 146/406] lower qmake optimization level on msvc -O2 triggers an optimizer bug where compiling unixmake*.cpp would take several minutes each. -O1 is not measurably slower, so use that instead. Change-Id: Ibf8abbecdd69e35cef800841f781543121168f76 Reviewed-by: Kai Koehne Reviewed-by: Joerg Bornemann --- qmake/Makefile.win32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 3efe6a67e0c..767237fcfc7 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -29,7 +29,7 @@ CFLAGS_EXTRA = /MP !endif CFLAGS_BARE = -c -Fo./ \ - -W3 -nologo -O2 \ + -W3 -nologo -O1 \ $(CFLAGS_EXTRA) \ -I. -Igenerators -Igenerators\unix -Igenerators\win32 -Igenerators\mac -Igenerators\integrity \ -I$(BUILD_PATH)\include -I$(BUILD_PATH)\include\QtCore -I$(BUILD_PATH)\include\QtCore\$(QT_VERSION) -I$(BUILD_PATH)\include\QtCore\$(QT_VERSION)\QtCore \ From dd119e14d0b53491d6b1578f913ad3edfe35c9a5 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 10 Feb 2012 09:41:50 +0100 Subject: [PATCH 147/406] Fix qlogging autotest for clang Change-Id: Iac82c4847554534174b5419ec78319c9ac381628 Reviewed-by: Bradley T. Hughes Reviewed-by: Olivier Goffart --- src/corelib/global/qlogging.cpp | 5 +++++ .../corelib/global/qlogging/tst_qlogging.cpp | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 39b32055713..164b8460741 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -204,6 +204,11 @@ Q_AUTOTEST_EXPORT QByteArray qCleanupFuncinfo(QByteArray info) } info = info.mid(pos + 1); + // remove trailing '*', '&' that are part of the return argument + while ((info.at(0) == '*') + || (info.at(0) == '&')) + info = info.mid(1); + // we have the full function name now. // clean up the templates while ((pos = info.lastIndexOf('>')) != -1) { diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp index 742a858961b..b2935ea6f2c 100644 --- a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp +++ b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp @@ -154,6 +154,7 @@ class TestClass1 { public: enum Something { foo }; + char c; void func_void() { ADD("TestClass1::func_void"); } int func_int() { ADD("TestClass1::func_int"); return 0; } @@ -164,6 +165,7 @@ public: char func_char() { ADD("TestClass1::func_char"); return 0; } signed char func_schar() { ADD("TestClass1::func_schar"); return 0; } unsigned char func_uchar() { ADD("TestClass1::func_uchar"); return 0; } + char &func_Rchar() { ADD("TestClass1::func_Rchar"); return c; } char *func_Pchar() { ADD("TestClass1::func_Pchar"); return 0; } const char *func_KPchar() { ADD("TestClass1::func_KPchar"); return 0; } const volatile char *func_VKPchar() { ADD("TestClass1::func_VKPchar"); return 0; } @@ -221,6 +223,7 @@ public: func_char(); func_schar(); func_uchar(); + func_Rchar(); func_Pchar(); func_KPchar(); func_VKPchar(); @@ -383,12 +386,25 @@ void tst_qmessagehandler::cleanupFuncinfo_data() << "unsigned char TestClass1::func_uchar()" << "TestClass1::func_uchar"; + QTest::newRow("msvc_09a") + << "char &__thiscall TestClass1::func_Rchar(void)" + << "TestClass1::func_Rchar"; + QTest::newRow("gcc_09a") + << "char& TestClass1::func_Rchar()" + << "TestClass1::func_Rchar"; + QTest::newRow("clang_09a") + << "char &TestClass1::func_Rchar()" + << "TestClass1::func_Rchar"; + QTest::newRow("msvc_10") << "char *__thiscall TestClass1::func_Pchar(void)" << "TestClass1::func_Pchar"; QTest::newRow("gcc_10") << "char* TestClass1::func_Pchar()" << "TestClass1::func_Pchar"; + QTest::newRow("clang_10") + << "char *TestClass1::func_Pchar()" + << "TestClass1::func_Pchar"; QTest::newRow("msvc_11") << "const char *__thiscall TestClass1::func_KPchar(void)" @@ -592,6 +608,7 @@ void tst_qmessagehandler::cleanupFuncinfo() #ifdef QT_BUILD_INTERNAL QFETCH(QString, funcinfo); +// qDebug() << funcinfo.toLatin1(); QByteArray result = qCleanupFuncinfo(funcinfo.toLatin1()); QTEST(QString::fromLatin1(result), "expected"); #endif From 281673e5d3e25f543590bf63bb2b97517486f4e1 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Wed, 8 Feb 2012 14:15:33 +0100 Subject: [PATCH 148/406] Include winsock2.h for ntohl. This fixes the compilation for Windows CE. Include Windock2.h before Windows.h. Change-Id: Iae1ab98239bb75b59c78460e0c0e48dfa1326032 Reviewed-by: Jonas Gastal Reviewed-by: Miikka Heikkinen Reviewed-by: Stephen Kelly --- src/network/kernel/qdnslookup_win.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/kernel/qdnslookup_win.cpp b/src/network/kernel/qdnslookup_win.cpp index ba97e649421..9b2c088ee27 100644 --- a/src/network/kernel/qdnslookup_win.cpp +++ b/src/network/kernel/qdnslookup_win.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include #include "qdnslookup_p.h" #include From 497622cafe235eadb5dd5056b196d8451ee89071 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 23 Dec 2011 17:13:05 +0100 Subject: [PATCH 149/406] Make it possible to put QObject tracked with QWeakPointer inside QSharedPointer Do that by keeping the QWeakPointer that track QObject independent of the ones that track QSharedPointer. QSharedPointer do not touch the sharedRefCount in QObjectPrivate anymore When converting a QWeakPointer constructed from a QObject to a QSharedPointer, it will display a warning saying one should not do that. Task-number: QTBUG-22622 Change-Id: I3595e3e7401702410776c458687ab357ad9366ab Reviewed-by: Bradley T. Hughes Reviewed-by: Stephen Kelly Reviewed-by: Olivier Goffart --- src/corelib/tools/qsharedpointer.cpp | 28 ++++++++-------- src/corelib/tools/qsharedpointer_impl.h | 8 +++-- .../qsharedpointer/tst_qsharedpointer.cpp | 33 ++++++++++++++----- 3 files changed, 44 insertions(+), 25 deletions(-) diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index ee0aee23990..77c3d1e2cb7 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -1226,24 +1226,22 @@ QT_BEGIN_NAMESPACE /*! \internal This function is called for a just-created QObject \a obj, to enable - the use of QSharedPointer and QWeakPointer. + the use of QSharedPointer and QWeakPointer in the future. + */ +void QtSharedPointer::ExternalRefCountData::setQObjectShared(const QObject *, bool) +{} - When QSharedPointer is active in a QObject, the object must not be deleted - directly: the lifetime is managed by the QSharedPointer object. In that case, - the deleteLater() and parent-child relationship in QObject only decrease - the strong reference count, instead of deleting the object. +/*! + \internal + This function is called when a QSharedPointer is created from a QWeakPointer + + We check that the QWeakPointer was really created from a QSharedPointer, and + not from a QObject. */ -void QtSharedPointer::ExternalRefCountData::setQObjectShared(const QObject *obj, bool) +void QtSharedPointer::ExternalRefCountData::checkQObjectShared(const QObject *) { - Q_ASSERT(obj); - QObjectPrivate *d = QObjectPrivate::get(const_cast(obj)); - - if (d->sharedRefcount.load() != 0) - qFatal("QSharedPointer: pointer %p already has reference counting", obj); - d->sharedRefcount.store(this); - - // QObject decreases the refcount too, so increase it up - weakref.ref(); + if (strongref.load() < 0) + qWarning("QSharedPointer: cannot create a QSharedPointer from a QObject-tracking QWeakPointer"); } QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::getAndRef(const QObject *obj) diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index ebab027196f..58010dd8d9e 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -192,7 +192,9 @@ namespace QtSharedPointer { #ifndef QT_NO_QOBJECT Q_CORE_EXPORT static ExternalRefCountData *getAndRef(const QObject *); Q_CORE_EXPORT void setQObjectShared(const QObject *, bool enable); + Q_CORE_EXPORT void checkQObjectShared(const QObject *); #endif + inline void checkQObjectShared(...) { } inline void setQObjectShared(...) { } }; // sizeof(ExternalRefCount) = 12 (32-bit) / 16 (64-bit) @@ -432,10 +434,12 @@ namespace QtSharedPointer { tmp = o->strongref.load(); // failed, try again } - if (tmp > 0) + if (tmp > 0) { o->weakref.ref(); - else + } else { + o->checkQObjectShared(actual); o = 0; + } } qSwap(d, o); diff --git a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp index 2bae52a6225..6dae58a006b 100644 --- a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp @@ -76,6 +76,7 @@ private slots: void upCast(); void qobjectWeakManagement(); void noSharedPointerFromWeakQObject(); + void sharedPointerFromQObjectWithWeak(); void weakQObjectFromSharedPointer(); void objectCast(); void differentPointers(); @@ -692,12 +693,34 @@ void tst_QSharedPointer::noSharedPointerFromWeakQObject() QObject obj; QWeakPointer weak(&obj); - QSharedPointer strong = weak.toStrongRef(); - QVERIFY(strong.isNull()); + { + QTest::ignoreMessage(QtWarningMsg , "QSharedPointer: cannot create a QSharedPointer from a QObject-tracking QWeakPointer"); + QSharedPointer strong = weak.toStrongRef(); + QVERIFY(strong.isNull()); + } + { + QTest::ignoreMessage(QtWarningMsg , "QSharedPointer: cannot create a QSharedPointer from a QObject-tracking QWeakPointer"); + QSharedPointer strong = weak; + QVERIFY(strong.isNull()); + } + QCOMPARE(weak.data(), &obj); // if something went wrong, we'll probably crash here } +void tst_QSharedPointer::sharedPointerFromQObjectWithWeak() +{ + QObject *ptr = new QObject; + QWeakPointer weak = ptr; + { + QSharedPointer shared(ptr); + QVERIFY(!weak.isNull()); + QCOMPARE(shared.data(), ptr); + QCOMPARE(weak.data(), ptr); + } + QVERIFY(weak.isNull()); +} + void tst_QSharedPointer::weakQObjectFromSharedPointer() { // this is the inverse of the above: you're allowed to create a QWeakPointer @@ -1767,12 +1790,6 @@ void tst_QSharedPointer::invalidConstructs_data() << "Data *ptr = 0;\n" "QWeakPointer weakptr(ptr);\n"; - QTest::newRow("shared-pointer-from-unmanaged-qobject") - << &QTest::QExternalTest::tryRunFail - << "QObject *ptr = new QObject;\n" - "QWeakPointer weak = ptr;\n" // this makes the object unmanaged - "QSharedPointer shared(ptr);\n"; - QTest::newRow("shared-pointer-implicit-from-uninitialized") << &QTest::QExternalTest::tryCompileFail << "Data *ptr = 0;\n" From 38dbb45e79acecf9e98cb283d234a5d7e8b1b470 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 9 Feb 2012 15:02:42 +0200 Subject: [PATCH 150/406] Make "nmake check" pass for gui tests in Windows. Marked the following tests insignificant due to failures, these need to be fixed later and then re-enabled: tst_QPixmap tst_QClipboard tst_QWindow tst_QGuiApplication tst_QPainter tst_QPrinterInfo tst_QPrinter tst_QOpenGL tst_QFontDatabse tst_QFontMetrics tst_QGlyphRun tst_QRawFont Task-number: QTBUG-24128 Change-Id: I39ade8a693c4580b5cd618624e892cdcac21d78c Reviewed-by: Friedemann Kleint Reviewed-by: Sergio Ahumada --- tests/auto/gui/image/qpixmap/qpixmap.pro | 2 ++ tests/auto/gui/kernel/qclipboard/test/test.pro | 1 + tests/auto/gui/kernel/qguiapplication/qguiapplication.pro | 2 ++ tests/auto/gui/kernel/qwindow/qwindow.pro | 1 + tests/auto/gui/painting/qpainter/qpainter.pro | 1 + tests/auto/gui/painting/qprinter/qprinter.pro | 1 + tests/auto/gui/painting/qprinterinfo/qprinterinfo.pro | 1 + tests/auto/gui/qopengl/qopengl.pro | 1 + tests/auto/gui/text/qfontdatabase/qfontdatabase.pro | 1 + tests/auto/gui/text/qfontmetrics/qfontmetrics.pro | 1 + tests/auto/gui/text/qglyphrun/qglyphrun.pro | 2 ++ tests/auto/gui/text/qrawfont/qrawfont.pro | 2 ++ 12 files changed, 16 insertions(+) diff --git a/tests/auto/gui/image/qpixmap/qpixmap.pro b/tests/auto/gui/image/qpixmap/qpixmap.pro index 15098770c6b..91d93a781d5 100644 --- a/tests/auto/gui/image/qpixmap/qpixmap.pro +++ b/tests/auto/gui/image/qpixmap/qpixmap.pro @@ -10,3 +10,5 @@ SOURCES += tst_qpixmap.cpp RESOURCES += qpixmap.qrc TESTDATA += convertFromImage/* convertFromToHICON/* loadFromData/* images/* + +win32:CONFIG += insignificant_test # QTBUG-24183 diff --git a/tests/auto/gui/kernel/qclipboard/test/test.pro b/tests/auto/gui/kernel/qclipboard/test/test.pro index 4be6769592c..ffab4dec4f3 100644 --- a/tests/auto/gui/kernel/qclipboard/test/test.pro +++ b/tests/auto/gui/kernel/qclipboard/test/test.pro @@ -16,6 +16,7 @@ wince* { } mac: CONFIG += insignificant_test # QTBUG-23057 +win32:CONFIG += insignificant_test # QTBUG-24184 load(testcase) # for target.path and installTestHelperApp() installTestHelperApp("../copier/copier",copier,copier) diff --git a/tests/auto/gui/kernel/qguiapplication/qguiapplication.pro b/tests/auto/gui/kernel/qguiapplication/qguiapplication.pro index fffa097d730..777e2c6b1a3 100644 --- a/tests/auto/gui/kernel/qguiapplication/qguiapplication.pro +++ b/tests/auto/gui/kernel/qguiapplication/qguiapplication.pro @@ -2,3 +2,5 @@ CONFIG += testcase TARGET = tst_qguiapplication QT += core gui testlib SOURCES = tst_qguiapplication.cpp + +win32:CONFIG += insignificant_test # QTBUG-24186 diff --git a/tests/auto/gui/kernel/qwindow/qwindow.pro b/tests/auto/gui/kernel/qwindow/qwindow.pro index 0115d96c568..d191b9fb8e2 100644 --- a/tests/auto/gui/kernel/qwindow/qwindow.pro +++ b/tests/auto/gui/kernel/qwindow/qwindow.pro @@ -6,3 +6,4 @@ QT += core-private gui-private testlib SOURCES += tst_qwindow.cpp mac: CONFIG += insignificant_test # QTBUG-23059 +win32:CONFIG += insignificant_test # QTBUG-24185 diff --git a/tests/auto/gui/painting/qpainter/qpainter.pro b/tests/auto/gui/painting/qpainter/qpainter.pro index 0209043d201..2cbd5b7e1ca 100644 --- a/tests/auto/gui/painting/qpainter/qpainter.pro +++ b/tests/auto/gui/painting/qpainter/qpainter.pro @@ -5,6 +5,7 @@ QT += widgets widgets-private printsupport testlib SOURCES += tst_qpainter.cpp mac*:CONFIG+=insignificant_test +win32:CONFIG += insignificant_test # QTBUG-24188 TESTDATA += drawEllipse/* drawLine_rop_bitmap/* drawPixmap_rop/* drawPixmap_rop_bitmap/* \ task217400.png diff --git a/tests/auto/gui/painting/qprinter/qprinter.pro b/tests/auto/gui/painting/qprinter/qprinter.pro index ebf8edea328..7543e91f8c2 100644 --- a/tests/auto/gui/painting/qprinter/qprinter.pro +++ b/tests/auto/gui/painting/qprinter/qprinter.pro @@ -4,3 +4,4 @@ QT += printsupport widgets testlib SOURCES += tst_qprinter.cpp mac*:CONFIG+=insignificant_test +win32:CONFIG += insignificant_test # QTBUG-24191 diff --git a/tests/auto/gui/painting/qprinterinfo/qprinterinfo.pro b/tests/auto/gui/painting/qprinterinfo/qprinterinfo.pro index b0e69dca2e5..88cb07f338a 100644 --- a/tests/auto/gui/painting/qprinterinfo/qprinterinfo.pro +++ b/tests/auto/gui/painting/qprinterinfo/qprinterinfo.pro @@ -7,3 +7,4 @@ QT += printsupport network testlib DEFINES += QT_USE_USING_NAMESPACE mac: CONFIG += insignificant_test # QTBUG-23060 +win32:CONFIG += insignificant_test # QTBUG-24190 diff --git a/tests/auto/gui/qopengl/qopengl.pro b/tests/auto/gui/qopengl/qopengl.pro index f3c020dde2e..d0af96df37a 100644 --- a/tests/auto/gui/qopengl/qopengl.pro +++ b/tests/auto/gui/qopengl/qopengl.pro @@ -9,3 +9,4 @@ QT += gui gui-private core-private testlib SOURCES += tst_qopengl.cpp mac: CONFIG += insignificant_test # QTBUG-23061 +win32:CONFIG += insignificant_test # QTBUG-24192 diff --git a/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro b/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro index c853aaa1000..034d08fc8f6 100644 --- a/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro +++ b/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro @@ -11,3 +11,4 @@ wince* { } mac: CONFIG += insignificant_test # QTBUG-23062 +win32:CONFIG += insignificant_test # QTBUG-24193 diff --git a/tests/auto/gui/text/qfontmetrics/qfontmetrics.pro b/tests/auto/gui/text/qfontmetrics/qfontmetrics.pro index a636651724f..bb0d8e3c4a8 100644 --- a/tests/auto/gui/text/qfontmetrics/qfontmetrics.pro +++ b/tests/auto/gui/text/qfontmetrics/qfontmetrics.pro @@ -4,3 +4,4 @@ QT += testlib SOURCES += tst_qfontmetrics.cpp RESOURCES += testfont.qrc +win32:CONFIG += insignificant_test # QTBUG-24195 diff --git a/tests/auto/gui/text/qglyphrun/qglyphrun.pro b/tests/auto/gui/text/qglyphrun/qglyphrun.pro index acdff0584fb..97b9806c117 100644 --- a/tests/auto/gui/text/qglyphrun/qglyphrun.pro +++ b/tests/auto/gui/text/qglyphrun/qglyphrun.pro @@ -10,3 +10,5 @@ wince* { } else { DEFINES += SRCDIR=\\\"$$PWD/\\\" } + +win32:CONFIG += insignificant_test # QTBUG-24196 diff --git a/tests/auto/gui/text/qrawfont/qrawfont.pro b/tests/auto/gui/text/qrawfont/qrawfont.pro index 149ad6442e3..8cac4abc574 100644 --- a/tests/auto/gui/text/qrawfont/qrawfont.pro +++ b/tests/auto/gui/text/qrawfont/qrawfont.pro @@ -9,3 +9,5 @@ SOURCES += \ INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/harfbuzz/src TESTDATA += testfont_bold_italic.ttf testfont.ttf + +win32:CONFIG += insignificant_test # QTBUG-24197 From 0b9904aab346fc647270ba3fddc8e2b2ef3ed79c Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 10 Feb 2012 12:08:56 +0100 Subject: [PATCH 151/406] Fix Harmattan compile target to be usable outside of Scratchbox Simply include the generic arm-gnueabi configuration. This should work from within and outside sbox, but at the same time keeping this mkspec allows us to enable Harmattan specific features such as the xinput2/touch support in the xcb back-end. Change-Id: I5cc0cdc3e222deb6374580392c3e3aadfc3a4bd9 Reviewed-by: Jocelyn Turcotte --- mkspecs/linux-g++-maemo/qmake.conf | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/mkspecs/linux-g++-maemo/qmake.conf b/mkspecs/linux-g++-maemo/qmake.conf index 23f1f71e0f1..d5828ab5c83 100644 --- a/mkspecs/linux-g++-maemo/qmake.conf +++ b/mkspecs/linux-g++-maemo/qmake.conf @@ -10,19 +10,5 @@ CONFIG += nostrip QT += core gui QMAKE_INCREMENTAL_STYLE = sublib -include(../common/linux.conf) -include(../common/gcc-base-unix.conf) -include(../common/g++-unix.conf) +include(../linux-arm-gnueabi-g++/qmake.conf) - -# Override the default lib/include directories for scratchbox: -QMAKE_INCDIR_X11 = /usr/include/X11 -QMAKE_INCDIR_OPENGL = /usr/include -QMAKE_LIBDIR_X11 = /usr/lib -QMAKE_LIBDIR_OPENGL = /usr/lib - -# We still need to generate debug symbols in release mode to put into the *-dbg packages: -QMAKE_CFLAGS_RELEASE += -g -Wno-psabi -QMAKE_CXXFLAGS_RELEASE += -g -Wno-psabi - -load(qt_config) From fb62fdac1cdb4e26388b5bacc7422ec4579b217e Mon Sep 17 00:00:00 2001 From: Leonard Lee Date: Fri, 3 Feb 2012 13:41:47 +0100 Subject: [PATCH 152/406] Display QThread name for debugging. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks to João's help. Change-Id: I9ad3035f016945bed9fdf425fc7b7edd5d20822d Reviewed-by: João Abecasis Reviewed-by: Thiago Macieira --- src/corelib/thread/qthread_unix.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 9ce951cf3b7..d458ee94724 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -90,6 +90,10 @@ # endif #endif +#if defined(Q_OS_LINUX) +#include +#endif + #if defined(Q_OS_LINUX) && !defined(SCHED_IDLE) // from linux/sched.h # define SCHED_IDLE 5 @@ -283,6 +287,20 @@ void *QThreadPrivate::start(void *arg) else createEventDispatcher(data); +#if !defined(QT_NO_DEBUG) && (defined(Q_OS_LINUX) || defined(Q_OS_MAC)) + // sets the name of the current thread. + QByteArray objectName = thr->objectName().toLocal8Bit(); + + if (objectName.isEmpty()) + objectName = thr->metaObject()->className(); + +#if defined(Q_OS_LINUX) + prctl(PR_SET_NAME, (unsigned long)objectName.constData(), 0, 0, 0); +#elif defined(Q_OS_MAC) + pthread_setname_np(objectName.constData()); +#endif +#endif + emit thr->started(); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_testcancel(); From a541fd4d7133618a3748b952196dd69dae786e95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 10 Feb 2012 09:52:47 +0100 Subject: [PATCH 153/406] More graceful handling of QSurfaceFormat::samples() with EGL. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Earlier, if we asked for say 16 and the implementation only handled 4, we defaulted to 0 (no antialiasing). Now, we instead try a progressively lower number until we find a match. Task-number: QTBUG-22669 Change-Id: I63f4b8aadf8e06713d19fdc9b9d73672162c816a Reviewed-by: Jørgen Lind --- .../eglconvenience/qeglconvenience.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/platformsupport/eglconvenience/qeglconvenience.cpp b/src/platformsupport/eglconvenience/qeglconvenience.cpp index f9ccde6b527..4ba9c1f5ac3 100644 --- a/src/platformsupport/eglconvenience/qeglconvenience.cpp +++ b/src/platformsupport/eglconvenience/qeglconvenience.cpp @@ -152,13 +152,19 @@ bool q_reduceConfigAttributes(QVector *configAttributes) } } + i = configAttributes->indexOf(EGL_SAMPLES); + if (i >= 0) { + EGLint value = configAttributes->value(i+1, 0); + if (value > 1) + configAttributes->replace(i+1, qMin(EGLint(16), value / 2)); + else + configAttributes->remove(i, 2); + return true; + } + i = configAttributes->indexOf(EGL_SAMPLE_BUFFERS); if (i >= 0) { configAttributes->remove(i,2); - i = configAttributes->indexOf(EGL_SAMPLES); - if (i >= 0) { - configAttributes->remove(i,2); - } return true; } From 7dca7c3c571ec595b792bbc2d2d448aac587886a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 10 Feb 2012 10:18:03 +0100 Subject: [PATCH 154/406] More graceful handling of QSurfaceFormat::samples() with GLX. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Earlier, if we asked for say 16 and the implementation only handled 4, we defaulted to 0 (no antialiasing). Now, we instead try a progressively lower number until we find a match. Task-number: QTBUG-22669 Change-Id: I3d89f2a302f9c6195e2d43827006fd015d981ce7 Reviewed-by: Jørgen Lind --- src/platformsupport/glxconvenience/qglxconvenience.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platformsupport/glxconvenience/qglxconvenience.cpp b/src/platformsupport/glxconvenience/qglxconvenience.cpp index 5acb2d0b656..11d8a5901fa 100644 --- a/src/platformsupport/glxconvenience/qglxconvenience.cpp +++ b/src/platformsupport/glxconvenience/qglxconvenience.cpp @@ -264,7 +264,7 @@ QSurfaceFormat qglx_reduceSurfaceFormat(const QSurfaceFormat &format, bool *redu } else if (retFormat.blueBufferSize() > 1) { retFormat.setBlueBufferSize(1); } else if (retFormat.samples() > 1) { - retFormat.setSamples(0); + retFormat.setSamples(qMin(retFormat.samples() / 2, 16)); } else if (retFormat.stereo()) { retFormat.setStereo(false); }else if (retFormat.stencilBufferSize() > 0) { From 38257651b7e2085ae66c1c67ee9e33e93587b573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 10 Feb 2012 10:23:15 +0100 Subject: [PATCH 155/406] Properly read back the actual format in xcb and xlib plugins. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Iccef2c4a87863b93914b84edf3a6015dad5e512a Reviewed-by: Jørgen Lind --- .../glxconvenience/qglxconvenience.cpp | 15 ++++++++++----- .../glxconvenience/qglxconvenience_p.h | 4 ++-- src/plugins/platforms/xcb/qglxintegration.cpp | 3 ++- src/plugins/platforms/xcb/qxcbwindow.cpp | 12 +++++++----- src/plugins/platforms/xcb/qxcbwindow.h | 2 +- src/plugins/platforms/xlib/qglxintegration.cpp | 3 ++- src/plugins/platforms/xlib/qxlibwindow.cpp | 7 ++++--- src/plugins/platforms/xlib/qxlibwindow.h | 2 ++ 8 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/platformsupport/glxconvenience/qglxconvenience.cpp b/src/platformsupport/glxconvenience/qglxconvenience.cpp index 11d8a5901fa..f619bf53b82 100644 --- a/src/platformsupport/glxconvenience/qglxconvenience.cpp +++ b/src/platformsupport/glxconvenience/qglxconvenience.cpp @@ -153,23 +153,28 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , const QSurfaceFormat XFree(configs); } - reducedFormat = qglx_reduceSurfaceFormat(reducedFormat,&reduced); + if (!chosenConfig) + reducedFormat = qglx_reduceSurfaceFormat(reducedFormat,&reduced); } return chosenConfig; } -XVisualInfo *qglx_findVisualInfo(Display *display, int screen, const QSurfaceFormat &format) +XVisualInfo *qglx_findVisualInfo(Display *display, int screen, QSurfaceFormat *format) { + Q_ASSERT(format); + XVisualInfo *visualInfo = 0; - GLXFBConfig config = qglx_findConfig(display,screen,format); - if (config) + GLXFBConfig config = qglx_findConfig(display,screen,*format); + if (config) { visualInfo = glXGetVisualFromFBConfig(display, config); + *format = qglx_surfaceFormatFromGLXFBConfig(display, config); + } // attempt to fall back to glXChooseVisual bool reduced = true; - QSurfaceFormat reducedFormat = format; + QSurfaceFormat reducedFormat = *format; while (!visualInfo && reduced) { QVarLengthArray attribs; attribs.append(GLX_RGBA); diff --git a/src/platformsupport/glxconvenience/qglxconvenience_p.h b/src/platformsupport/glxconvenience/qglxconvenience_p.h index 6d4cecfbe6a..a60f789a859 100644 --- a/src/platformsupport/glxconvenience/qglxconvenience_p.h +++ b/src/platformsupport/glxconvenience/qglxconvenience_p.h @@ -48,9 +48,9 @@ #include #include -XVisualInfo *qglx_findVisualInfo(Display *display, int screen, const QSurfaceFormat &format); +XVisualInfo *qglx_findVisualInfo(Display *display, int screen, QSurfaceFormat *format); GLXFBConfig qglx_findConfig(Display *display, int screen, const QSurfaceFormat &format, int drawableBit = GLX_WINDOW_BIT); -QSurfaceFormat qglx_surfaceFormatFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext context); +QSurfaceFormat qglx_surfaceFormatFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext context = 0); QVector qglx_buildSpec(const QSurfaceFormat &format, int drawableBit = GLX_WINDOW_BIT); QSurfaceFormat qglx_reduceSurfaceFormat(const QSurfaceFormat &format, bool *reduced); diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index 6ada127beb4..0144caae3de 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -64,6 +64,7 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat : QPlatformOpenGLContext() , m_screen(screen) , m_context(0) + , m_format(format) { m_shareContext = 0; if (share) @@ -82,7 +83,7 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat if (m_context) m_format = qglx_surfaceFormatFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context); } else { - XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen), screen->screenNumber(), format); + XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen), screen->screenNumber(), &m_format); if (!visualInfo) qFatal("Could not initialize GLX"); m_context = glXCreateContext(DISPLAY_FROM_XCB(screen), visualInfo, m_shareContext, true); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 959209dd33b..4f05c4cf5a7 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -201,19 +201,21 @@ void QXcbWindow::create() if (parent()) xcb_parent_id = static_cast(parent())->xcb_window(); - m_requestedFormat = window()->format(); + m_format = window()->requestedFormat(); #if (defined(XCB_USE_GLX) || defined(XCB_USE_EGL)) && defined(XCB_USE_XLIB) if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL) - || window()->format().hasAlpha()) + || m_format.hasAlpha()) { #if defined(XCB_USE_GLX) - XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen),m_screen->screenNumber(), window()->format()); + XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen), m_screen->screenNumber(), &m_format); if (!visualInfo) qFatal("Could not initialize GLX"); #elif defined(XCB_USE_EGL) EGLDisplay eglDisplay = connection()->egl_display(); - EGLConfig eglConfig = q_configFromGLFormat(eglDisplay, window()->format(), true); + EGLConfig eglConfig = q_configFromGLFormat(eglDisplay, m_format, true); + m_format = q_glFormatFromConfig(eglDisplay, eglConfig); + VisualID id = QXlibEglIntegration::getCompatibleVisualId(DISPLAY_FROM_XCB(this), eglDisplay, eglConfig); XVisualInfo visualInfoTemplate; @@ -1167,7 +1169,7 @@ void QXcbWindow::setOrientation(Qt::ScreenOrientation orientation) QSurfaceFormat QXcbWindow::format() const { // ### return actual format - return m_requestedFormat; + return m_format; } #if defined(XCB_USE_EGL) diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 3cbf9e7e0d3..365c8b05492 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -155,7 +155,7 @@ private: bool m_transparent; xcb_window_t m_netWmUserTimeWindow; - QSurfaceFormat m_requestedFormat; + QSurfaceFormat m_format; mutable bool m_dirtyFrameMargins; mutable QMargins m_frameMargins; diff --git a/src/plugins/platforms/xlib/qglxintegration.cpp b/src/plugins/platforms/xlib/qglxintegration.cpp index e78689374a6..51621408b9d 100644 --- a/src/plugins/platforms/xlib/qglxintegration.cpp +++ b/src/plugins/platforms/xlib/qglxintegration.cpp @@ -65,6 +65,7 @@ QGLXContext::QGLXContext(QXlibScreen *screen, const QSurfaceFormat &format, QPla : QPlatformOpenGLContext() , m_screen(screen) , m_context(0) + , m_windowFormat(format) { GLXContext shareGlxContext = 0; if (share) @@ -77,7 +78,7 @@ QGLXContext::QGLXContext(QXlibScreen *screen, const QSurfaceFormat &format, QPla m_context = glXCreateNewContext(xDisplay,config,GLX_RGBA_TYPE,shareGlxContext,TRUE); m_windowFormat = qglx_surfaceFormatFromGLXFBConfig(xDisplay,config,m_context); } else { - XVisualInfo *visualInfo = qglx_findVisualInfo(xDisplay, screen->xScreenNumber(), format); + XVisualInfo *visualInfo = qglx_findVisualInfo(xDisplay, screen->xScreenNumber(), &m_windowFormat); if (!visualInfo) qFatal("Could not initialize GLX"); m_context = glXCreateContext(xDisplay, visualInfo, shareGlxContext, true); diff --git a/src/plugins/platforms/xlib/qxlibwindow.cpp b/src/plugins/platforms/xlib/qxlibwindow.cpp index 635caf81f89..94c4332e657 100644 --- a/src/plugins/platforms/xlib/qxlibwindow.cpp +++ b/src/plugins/platforms/xlib/qxlibwindow.cpp @@ -82,11 +82,12 @@ QXlibWindow::QXlibWindow(QWindow *window) int w = window->width(); int h = window->height(); + mSurfaceFormat = window->requestedFormat(); + #if !defined(QT_NO_OPENGL) if(window->surfaceType() == QWindow::OpenGLSurface) { #if !defined(QT_OPENGL_ES_2) - XVisualInfo *visualInfo = qglx_findVisualInfo(mScreen->display()->nativeDisplay(), mScreen->xScreenNumber(), - window->format()); + XVisualInfo *visualInfo = qglx_findVisualInfo(mScreen->display()->nativeDisplay(), mScreen->xScreenNumber(), &mSurfaceFormat); if (!visualInfo) qFatal("Could not initialize GLX"); #else @@ -694,7 +695,7 @@ void QXlibWindow::setCursor(const Cursor &cursor) QSurfaceFormat QXlibWindow::format() const { - return window()->format(); + return mSurfaceFormat; } diff --git a/src/plugins/platforms/xlib/qxlibwindow.h b/src/plugins/platforms/xlib/qxlibwindow.h index 8287f3a8a2d..6b9e2d63bde 100644 --- a/src/plugins/platforms/xlib/qxlibwindow.h +++ b/src/plugins/platforms/xlib/qxlibwindow.h @@ -143,6 +143,8 @@ private: QImage::Format mFormat; Visual* mVisual; + QSurfaceFormat mSurfaceFormat; + GC createGC(); QPlatformOpenGLContext *mGLContext; From 1406659948c226ef663e9dca7728958b9ad5023c Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 7 Feb 2012 19:07:49 +0100 Subject: [PATCH 156/406] Add -fPIE to the Qt5Core_COMPILE_FLAGS with reduce-relocations. Qt requires this since 482d96a0c5d523ace63f56bda6851926b4469dd0 Change-Id: Iba783e283b17654abf46f11b81cc1641c3ce7d83 Reviewed-by: Oswald Buddenhagen Reviewed-by: Olivier Goffart Reviewed-by: Clinton Stimpson Reviewed-by: Stephen Kelly --- mkspecs/features/create_cmake.prf | 2 ++ src/corelib/Qt5CoreConfigExtras.cmake.in | 4 ++++ tests/manual/cmake/pass1/CMakeLists.txt | 1 + 3 files changed, 7 insertions(+) diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf index e52e65c06ff..fe1fe4c3762 100644 --- a/mkspecs/features/create_cmake.prf +++ b/mkspecs/features/create_cmake.prf @@ -31,6 +31,8 @@ CMAKE_RELATIVE_INSTALL_DIR = "../../../" static|staticlib:CMAKE_STATIC_TYPE = true +contains(QT_CONFIG, reduce_relocations):CMAKE_ADD_FPIE_FLAGS = "true" + macx { CONFIG(qt_framework, qt_framework|qt_no_framework) { CMAKE_LIB_FILE_LOCATION_DEBUG = Qt$${CMAKE_MODULE_NAME}$${QT_LIBINFIX}.framework/Qt$${CMAKE_MODULE_NAME}$${QT_LIBINFIX} diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index 23a026e6151..057c8ff75e9 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -7,3 +7,7 @@ set(QT_MOC_EXECUTABLE \"${_qt5_corelib_install_prefix}/$$CMAKE_BIN_DIR/moc$$CMAK set(QT_RCC_EXECUTABLE \"${_qt5_corelib_install_prefix}/$$CMAKE_BIN_DIR/rcc$$CMAKE_BIN_SUFFIX\") list(APPEND Qt5Core_INCLUDE_DIRS \"${_qt5_corelib_install_prefix}/mkspecs/default\") + +if (NOT \"$${CMAKE_ADD_FPIE_FLAGS}\" STREQUAL \"\") + set(Qt5Core_COMPILE_FLAGS "-fPIE") +endif() diff --git a/tests/manual/cmake/pass1/CMakeLists.txt b/tests/manual/cmake/pass1/CMakeLists.txt index f11887e5458..b1922c075b7 100644 --- a/tests/manual/cmake/pass1/CMakeLists.txt +++ b/tests/manual/cmake/pass1/CMakeLists.txt @@ -18,6 +18,7 @@ macro(qt5_use_package _target _package) # set_property(TARGET ${_target} APPEND PROPERTY INCLUDE_DIRECTORIES ${Qt5${_package}_INCLUDE_DIRS}) include_directories(${Qt5${_package}_INCLUDE_DIRS}) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS ${Qt5${_package}_COMPILE_DEFINITIONS}) + set_property(TARGET ${_target} APPEND PROPERTY COMPILE_FLAGS ${Qt5${_package}_COMPILE_FLAGS}) else() message(FATAL_ERROR "NOT FOUND: Qt5${_package}") endif() From 9633459274f99487360bcc7c7e7c593c4ac98ce2 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 8 Feb 2012 23:01:05 +0100 Subject: [PATCH 157/406] Fixed alignment check in QJsonDocument::fromRawData Change-Id: I1d107e26a77e40f91ff09d43e9529b08da8f7c3b Reviewed-by: Lars Knoll --- src/corelib/json/qjsondocument.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/json/qjsondocument.cpp b/src/corelib/json/qjsondocument.cpp index 98a0b8c3d33..5ae1bcbe4eb 100644 --- a/src/corelib/json/qjsondocument.cpp +++ b/src/corelib/json/qjsondocument.cpp @@ -179,8 +179,8 @@ QJsonDocument &QJsonDocument::operator =(const QJsonDocument &other) */ QJsonDocument QJsonDocument::fromRawData(const char *data, int size, DataValidation validation) { - if (!(((quintptr)validation) & ~3)) { - qWarning() <<"QJsonDocumnt::fromRawData: data has to have 4 byte alignment"; + if (quintptr(data) & 3) { + qWarning() <<"QJsonDocument::fromRawData: data has to have 4 byte alignment"; return QJsonDocument(); } From 19a39a4ea2f7ef7f9a1e8a54fc13240e79ccf79d Mon Sep 17 00:00:00 2001 From: Jan Arne Petersen Date: Fri, 10 Feb 2012 14:52:32 +0100 Subject: [PATCH 158/406] Add support for "none" QT_IM_MODULE Do not try to load any input method when QT_IM_MODULE is set to "none". Change-Id: I695cb76d616bb2ce5021979bae2790b2f286122d Reviewed-by: Pekka Vuorela Reviewed-by: Lars Knoll --- .../inputcontext/qplatforminputcontextfactory_qpa.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/platformsupport/inputcontext/qplatforminputcontextfactory_qpa.cpp b/src/platformsupport/inputcontext/qplatforminputcontextfactory_qpa.cpp index 9e38e4cedf2..ca3673f670a 100644 --- a/src/platformsupport/inputcontext/qplatforminputcontextfactory_qpa.cpp +++ b/src/platformsupport/inputcontext/qplatforminputcontextfactory_qpa.cpp @@ -83,8 +83,11 @@ QPlatformInputContext *QPlatformInputContextFactory::create() QPlatformInputContext *ic = 0; QString icString = QString::fromLatin1(qgetenv("QT_IM_MODULE")); - ic = create(icString); + if (icString == QStringLiteral("none")) + return 0; + + ic = create(icString); if (ic && ic->isValid()) return ic; From 1e744d252370c258590ee4b28ceefa3a5db5b720 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 10 Feb 2012 13:40:20 +0200 Subject: [PATCH 159/406] Avoid crash when windows with active mouse synthesization are deleted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some QtQuick autotests, that apparently generate incomplete touch sequences and delete windows without finishing them, triggered a crash when handling the TouchCancel event in QGuiApplication. Change-Id: Ie725d5a16f55acc40bdc8e2c38f93daac9477f2a Reviewed-by: Samuel Rødal --- src/gui/kernel/qguiapplication.cpp | 6 ++++-- src/gui/kernel/qguiapplication_p.h | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index b17cf5824c3..0e525da1516 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -975,7 +975,9 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To if (!self->synthesizedMousePoints.isEmpty() && !e->synthetic) { for (QHash::const_iterator synthIt = self->synthesizedMousePoints.constBegin(), synthItEnd = self->synthesizedMousePoints.constEnd(); synthIt != synthItEnd; ++synthIt) { - QWindowSystemInterfacePrivate::MouseEvent fake(synthIt.key(), + if (!synthIt->window) + continue; + QWindowSystemInterfacePrivate::MouseEvent fake(synthIt->window.data(), e->timestamp, synthIt->pos, synthIt->screenPos, @@ -1159,7 +1161,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To if (touchPoint.id() == m_fakeMouseSourcePointId) { if (b != Qt::NoButton) self->synthesizedMousePoints.insert(w, SynthesizedMouseData( - touchPoint.pos(), touchPoint.screenPos())); + touchPoint.pos(), touchPoint.screenPos(), w)); QWindowSystemInterfacePrivate::MouseEvent fake(w, e->timestamp, touchPoint.pos(), touchPoint.screenPos(), diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 3ca007fb362..66db8437e54 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -201,9 +201,11 @@ public: QHash activeTouchPoints; QEvent::Type lastTouchType; struct SynthesizedMouseData { - SynthesizedMouseData(const QPointF &p, const QPointF &sp) : pos(p), screenPos(sp) { } + SynthesizedMouseData(const QPointF &p, const QPointF &sp, QWindow *w) + : pos(p), screenPos(sp), window(w) { } QPointF pos; QPointF screenPos; + QWeakPointer window; }; QHash synthesizedMousePoints; From a4fbae9fd9ad41bea52d328d559cd7f7c10af84b Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 10 Feb 2012 16:28:19 +0200 Subject: [PATCH 160/406] Fix xcb's native resource getters. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Returning pointers to unexpected types for unknown keys is quite wrong. The clients expect 0 in such a case but what they got (until now) was whatever was associated with the default constructed enum value. Change-Id: Iefd7bf461bfb2c1f4c73f5f9f291aecad60219eb Reviewed-by: Samuel Rødal Reviewed-by: Jani Uusi-Rantala --- src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index b7403cfdced..406f9c24bdb 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -84,6 +84,9 @@ QXcbNativeInterface::QXcbNativeInterface() void *QXcbNativeInterface::nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context) { QByteArray lowerCaseResource = resourceString.toLower(); + if (!qXcbResourceMap()->contains(lowerCaseResource)) + return 0; + ResourceType resource = qXcbResourceMap()->value(lowerCaseResource); void *result = 0; switch(resource) { @@ -91,14 +94,18 @@ void *QXcbNativeInterface::nativeResourceForContext(const QByteArray &resourceSt result = eglContextForContext(context); break; default: - result = 0; + break; } + return result; } void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) { QByteArray lowerCaseResource = resourceString.toLower(); + if (!qXcbResourceMap()->contains(lowerCaseResource)) + return 0; + ResourceType resource = qXcbResourceMap()->value(lowerCaseResource); void *result = 0; switch(resource) { @@ -118,8 +125,9 @@ void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceStr result = graphicsDeviceForWindow(window); break; default: - result = 0; + break; } + return result; } From 89b192a082652061ae1874f6bc1816c0f01e7a55 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 10 Feb 2012 16:40:06 +0200 Subject: [PATCH 161/406] Add an entry about TouchCancel to the changes file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: If6d29db42ac59fcdbab82c23f30bd32e884354b2 Reviewed-by: Samuel Rødal --- dist/changes-5.0.0 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index 7726843ccb4..b8a4e21490c 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -122,6 +122,11 @@ information about a particular change. * QWidget *widget() has been removed and is replaced by QObject *target() in order to avoid QWidget dependencies. + * QEvent::TouchCancel has been introduced. On systems where it makes + sense this event type can be used to differentiate between a + regular TouchEnd and abrupt touch sequence cancellations caused by + the compositor, for example when a system gesture gets recognized. + - QMetaType * Q_DECLARE_METATYPE(Foo*) now requires that Foo is fully defined. In From d43a01e1496c9be16cd2e3dc290bf70e926ceb99 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 9 Feb 2012 16:09:31 +0100 Subject: [PATCH 162/406] Re-add default positioning for Widgets. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Center widgets on the screen in show_sys() in case they are top levels that have not been moved yet. This was previously done in platform-specific code on Window creation. Change-Id: I191f20c0105ed3f27274c6505852b212d400b395 Reviewed-by: Samuel Rødal --- src/widgets/kernel/qwidget_qpa.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp index c0dbf0497e1..a37de8547ad 100644 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ b/src/widgets/kernel/qwidget_qpa.cpp @@ -424,6 +424,19 @@ void QWidget::activateWindow() windowHandle()->requestActivateWindow(); } +// Position top level windows at the center, avoid showing +// Windows at the default 0,0 position excluding the frame. +static inline QRect positionTopLevelWindow(QRect geometry, const QScreen *screen) +{ + if (screen && geometry.x() == 0 && geometry.y() == 0) { + const QRect availableGeometry = screen->availableGeometry(); + if (availableGeometry.width() > geometry.width() + && availableGeometry.height() > geometry.height()) + geometry.moveCenter(availableGeometry.center()); + } + return geometry; +} + void QWidgetPrivate::show_sys() { Q_Q(QWidget); @@ -441,7 +454,10 @@ void QWidgetPrivate::show_sys() QWindow *window = q->windowHandle(); if (window) { QRect geomRect = q->geometry(); - if (!q->isWindow()) { + if (q->isWindow()) { + if (!q->testAttribute(Qt::WA_Moved)) + geomRect = positionTopLevelWindow(geomRect, window->screen()); + } else { QPoint topLeftOfWindow = q->mapTo(q->nativeParentWidget(),QPoint()); geomRect.moveTopLeft(topLeftOfWindow); } From c908fc4448989d0319f86da35c8fa66ad1440fa2 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 8 Feb 2012 08:40:48 +0100 Subject: [PATCH 163/406] Add QPlatformServices class. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add QPlatformServices as back-end for QDesktopServices. - Bring back UNIX/Linux desktop detection in platformsupport as a generic implementation. - Add Windows implementation. Reviewed-by: Morten Johan Sorvig Reviewed-by: Samuel Rødal Reviewed-by: Anselmo Lacerda S. de Melo Change-Id: If94bb65755df4f849edd83c57143ee2c73002137 Reviewed-by: Friedemann Kleint --- src/gui/kernel/kernel.pri | 6 +- src/gui/kernel/qplatformintegration_qpa.cpp | 5 + src/gui/kernel/qplatformintegration_qpa.h | 3 + src/gui/kernel/qplatformservices_qpa.cpp | 74 ++++++++ .../qplatformservices_qpa.h} | 30 +-- src/gui/util/qdesktopservices.cpp | 21 ++- src/gui/util/qdesktopservices_mac.cpp | 127 ------------- src/gui/util/qdesktopservices_win.cpp | 177 ------------------ src/gui/util/qdesktopservices_x11.cpp | 131 ------------- src/platformsupport/platformsupport.pro | 1 + .../services/genericunix/genericunix.pri | 2 + .../genericunix/qgenericunixservices.cpp | 151 +++++++++++++++ .../genericunix/qgenericunixservices_p.h | 76 ++++++++ src/platformsupport/services/services.pri | 3 + .../platforms/windows/qwindowsintegration.cpp | 7 + .../platforms/windows/qwindowsintegration.h | 1 + .../platforms/windows/qwindowsservices.cpp | 154 +++++++++++++++ .../platforms/windows/qwindowsservices.h | 58 ++++++ src/plugins/platforms/windows/windows.pro | 7 +- src/plugins/platforms/xcb/qxcbintegration.cpp | 10 +- src/plugins/platforms/xcb/qxcbintegration.h | 4 + 21 files changed, 585 insertions(+), 463 deletions(-) create mode 100644 src/gui/kernel/qplatformservices_qpa.cpp rename src/gui/{util/qdesktopservices_qpa.cpp => kernel/qplatformservices_qpa.h} (83%) delete mode 100644 src/gui/util/qdesktopservices_mac.cpp delete mode 100644 src/gui/util/qdesktopservices_win.cpp delete mode 100644 src/gui/util/qdesktopservices_x11.cpp create mode 100644 src/platformsupport/services/genericunix/genericunix.pri create mode 100644 src/platformsupport/services/genericunix/qgenericunixservices.cpp create mode 100644 src/platformsupport/services/genericunix/qgenericunixservices_p.h create mode 100644 src/platformsupport/services/services.pri create mode 100644 src/plugins/platforms/windows/qwindowsservices.cpp create mode 100644 src/plugins/platforms/windows/qwindowsservices.h diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 7b01ba14cd6..9c5f3b10da2 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -55,7 +55,8 @@ HEADERS += \ kernel/qtouchdevice.h \ kernel/qtouchdevice_p.h \ kernel/qplatformsharedgraphicscache_qpa.h \ - kernel/qplatformdialoghelper_qpa.h + kernel/qplatformdialoghelper_qpa.h \ + kernel/qplatformservices_qpa.h SOURCES += \ kernel/qclipboard_qpa.cpp \ @@ -97,7 +98,8 @@ SOURCES += \ kernel/qstylehints.cpp \ kernel/qtouchdevice.cpp \ kernel/qplatformsharedgraphicscache_qpa.cpp \ - kernel/qplatformdialoghelper_qpa.cpp + kernel/qplatformdialoghelper_qpa.cpp \ + kernel/qplatformservices_qpa.cpp contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2)|contains(QT_CONFIG, egl) { HEADERS += \ diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp index e867e4e5880..1336a1a9a2b 100644 --- a/src/gui/kernel/qplatformintegration_qpa.cpp +++ b/src/gui/kernel/qplatformintegration_qpa.cpp @@ -107,6 +107,11 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const return 0; } +QPlatformServices *QPlatformIntegration::services() const +{ + return 0; +} + /*! \class QPlatformIntegration \since 4.8 diff --git a/src/gui/kernel/qplatformintegration_qpa.h b/src/gui/kernel/qplatformintegration_qpa.h index efaf495b811..bd9ecd54dc9 100644 --- a/src/gui/kernel/qplatformintegration_qpa.h +++ b/src/gui/kernel/qplatformintegration_qpa.h @@ -66,6 +66,7 @@ class QPlatformAccessibility; class QPlatformTheme; class QPlatformDialogHelper; class QPlatformSharedGraphicsCache; +class QPlatformServices; class Q_GUI_EXPORT QPlatformIntegration { @@ -106,6 +107,8 @@ public: // Access native handles. The window handle is already available from Wid; virtual QPlatformNativeInterface *nativeInterface() const; + virtual QPlatformServices *services() const; + enum StyleHint { CursorFlashTime, KeyboardInputInterval, diff --git a/src/gui/kernel/qplatformservices_qpa.cpp b/src/gui/kernel/qplatformservices_qpa.cpp new file mode 100644 index 00000000000..7993a82f4e7 --- /dev/null +++ b/src/gui/kernel/qplatformservices_qpa.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui 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 "qplatformservices_qpa.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QPlatformServices + \since 5.0 + \internal + \preliminary + \ingroup qpa + + \brief The QPlatformServices provides the backend for desktop-related functionality. +*/ + +bool QPlatformServices::openUrl(const QUrl &url) +{ + qWarning("This plugin does not support QPlatformServices::openUrl() for '%s'.", + qPrintable(url.toString())); + return false; +} + +bool QPlatformServices::openDocument(const QUrl &url) +{ + qWarning("This plugin does not support QPlatformServices::openDocument() for '%s'.", + qPrintable(url.toString())); + return false; +} + +QT_END_NAMESPACE diff --git a/src/gui/util/qdesktopservices_qpa.cpp b/src/gui/kernel/qplatformservices_qpa.h similarity index 83% rename from src/gui/util/qdesktopservices_qpa.cpp rename to src/gui/kernel/qplatformservices_qpa.h index b94267e72e0..aff2e5d6fea 100644 --- a/src/gui/util/qdesktopservices_qpa.cpp +++ b/src/gui/kernel/qplatformservices_qpa.h @@ -39,23 +39,27 @@ ** ****************************************************************************/ -#include -#include +#ifndef QPLATFORMSERVICES_QPA_H +#define QPLATFORMSERVICES_QPA_H + +#include + +QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -static bool launchWebBrowser(const QUrl &url) -{ - Q_UNUSED(url); - qWarning("QDesktopServices::launchWebBrowser not implemented"); - return false; -} +class QUrl; -static bool openDocument(const QUrl &file) +class Q_GUI_EXPORT QPlatformServices { - Q_UNUSED(file); - qWarning("QDesktopServices::openDocument not implemented"); - return false; -} +public: + virtual ~QPlatformServices() { } + + virtual bool openUrl(const QUrl &url); + virtual bool openDocument(const QUrl &url); +}; QT_END_NAMESPACE +QT_END_HEADER + +#endif // QPLATFORMSERVICES_QPA_H diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp index 0f1312e02d4..13e2585b885 100644 --- a/src/gui/util/qdesktopservices.cpp +++ b/src/gui/util/qdesktopservices.cpp @@ -45,14 +45,14 @@ #include -#include "qdesktopservices_qpa.cpp" - #include #include #include #include +#include #include #include +#include QT_BEGIN_NAMESPACE @@ -185,14 +185,15 @@ bool QDesktopServices::openUrl(const QUrl &url) return result; // ### support bool slot return type } } - - bool result; - if (url.scheme() == QLatin1String("file")) - result = openDocument(url); - else - result = launchWebBrowser(url); - - return result; + if (!url.isValid()) + return false; + QPlatformServices *platformServices = QGuiApplicationPrivate::platformIntegration()->services(); + if (!platformServices) { + qWarning("%s: The platform plugin does not support services.", Q_FUNC_INFO); + return false; + } + return url.scheme() == QStringLiteral("file") ? + platformServices->openDocument(url) : platformServices->openUrl(url); } /*! diff --git a/src/gui/util/qdesktopservices_mac.cpp b/src/gui/util/qdesktopservices_mac.cpp deleted file mode 100644 index 84c7156ef3f..00000000000 --- a/src/gui/util/qdesktopservices_mac.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtGui 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 QT_NO_DESKTOPSERVICES - -#include -#include -#include -#include -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -/* - Translates a QDesktopServices::StandardLocation into the mac equivalent. -*/ -OSType translateLocation(QDesktopServices::StandardLocation type) -{ - switch (type) { - case QDesktopServices::DesktopLocation: - return kDesktopFolderType; break; - - case QDesktopServices::DocumentsLocation: - return kDocumentsFolderType; break; - - case QDesktopServices::FontsLocation: - // There are at least two different font directories on the mac: /Library/Fonts and ~/Library/Fonts. - // To select a specific one we have to specify a different first parameter when calling FSFindFolder. - return kFontsFolderType; break; - - case QDesktopServices::ApplicationsLocation: - return kApplicationsFolderType; break; - - case QDesktopServices::MusicLocation: - return kMusicDocumentsFolderType; break; - - case QDesktopServices::MoviesLocation: - return kMovieDocumentsFolderType; break; - - case QDesktopServices::PicturesLocation: - return kPictureDocumentsFolderType; break; - - case QDesktopServices::TempLocation: - return kTemporaryFolderType; break; - - case QDesktopServices::DataLocation: - return kApplicationSupportFolderType; break; - - case QDesktopServices::CacheLocation: - return kCachedDataFolderType; break; - - default: - return kDesktopFolderType; break; - } -} - -static bool lsOpen(const QUrl &url) -{ - if (!url.isValid() || url.scheme().isEmpty()) - return false; - - QCFType cfUrl = CFURLCreateWithString(0, QCFString(QString::fromLatin1(url.toEncoded())), 0); - if (cfUrl == 0) - return false; - - const OSStatus err = LSOpenCFURLRef(cfUrl, 0); - return (err == noErr); -} - -static bool launchWebBrowser(const QUrl &url) -{ - return lsOpen(url); -} - -static bool openDocument(const QUrl &file) -{ - if (!file.isValid()) - return false; - - // LSOpen does not work in this case, use QProcess open instead. - return QProcess::startDetached(QLatin1String("open"), QStringList() << file.toLocalFile()); -} - -QT_END_NAMESPACE - -#endif // QT_NO_DESKTOPSERVICES diff --git a/src/gui/util/qdesktopservices_win.cpp b/src/gui/util/qdesktopservices_win.cpp deleted file mode 100644 index 88f245d6f67..00000000000 --- a/src/gui/util/qdesktopservices_win.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtGui 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#if !defined(Q_OS_WINCE) -# include -#else -# include -# if !defined(STANDARDSHELL_UI_MODEL) -# include -# endif -#endif - -#ifndef CSIDL_MYMUSIC -#define CSIDL_MYMUSIC 13 -#define CSIDL_MYVIDEO 14 -#endif - -#ifndef QT_NO_DESKTOPSERVICES - -QT_BEGIN_NAMESPACE - -static bool openDocument(const QUrl &file) -{ - if (!file.isValid()) - return false; - QString filePath = file.toLocalFile(); - if (filePath.isEmpty()) - filePath = file.toString(); - quintptr returnValue = (quintptr)ShellExecute(0, 0, (wchar_t*)filePath.utf16(), 0, 0, SW_SHOWNORMAL); - return (returnValue > 32); //ShellExecute returns a value greater than 32 if successful -} - -static QString expandEnvStrings(const QString &command) -{ -#if defined(Q_OS_WINCE) - return command; -#else - wchar_t buffer[MAX_PATH]; - if (ExpandEnvironmentStrings((wchar_t*)command.utf16(), buffer, MAX_PATH)) - return QString::fromWCharArray(buffer); - else - return command; -#endif -} - -static bool launchWebBrowser(const QUrl &url) -{ - if (url.scheme() == QLatin1String("mailto")) { - //Retrieve the commandline for the default mail client - //the default key used below is the command line for the mailto: shell command - DWORD bufferSize = sizeof(wchar_t) * MAX_PATH; - long returnValue = -1; - QString command; - - HKEY handle; - LONG res; - wchar_t keyValue[MAX_PATH] = {0}; - QString keyName(QLatin1String("mailto")); - - //Check if user has set preference, otherwise use default. - res = RegOpenKeyEx(HKEY_CURRENT_USER, - L"Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\mailto\\UserChoice", - 0, KEY_READ, &handle); - if (res == ERROR_SUCCESS) { - returnValue = RegQueryValueEx(handle, L"Progid", 0, 0, reinterpret_cast(keyValue), &bufferSize); - if (!returnValue) - keyName = QString::fromUtf16((const ushort*)keyValue); - RegCloseKey(handle); - } - keyName += QLatin1String("\\Shell\\Open\\Command"); - res = RegOpenKeyExW(HKEY_CLASSES_ROOT, (const wchar_t*)keyName.utf16(), 0, KEY_READ, &handle); - if (res != ERROR_SUCCESS) - return false; - - bufferSize = sizeof(wchar_t) * MAX_PATH; - returnValue = RegQueryValueEx(handle, L"", 0, 0, reinterpret_cast(keyValue), &bufferSize); - if (!returnValue) - command = QString::fromRawData((QChar*)keyValue, bufferSize); - RegCloseKey(handle); - - if (returnValue) - return false; - - command = expandEnvStrings(command); - command = command.trimmed(); - //Make sure the path for the process is in quotes - int index = -1 ; - if (command[0]!= QLatin1Char('\"')) { - index = command.indexOf(QLatin1String(".exe "), 0, Qt::CaseInsensitive); - command.insert(index+4, QLatin1Char('\"')); - command.insert(0, QLatin1Char('\"')); - } - //pass the url as the parameter - index = command.lastIndexOf(QLatin1String("%1")); - if (index != -1){ - command.replace(index, 2, url.toString()); - } - //start the process - PROCESS_INFORMATION pi; - ZeroMemory(&pi, sizeof(pi)); - STARTUPINFO si; - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - - returnValue = CreateProcess(NULL, (wchar_t*)command.utf16(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); - - if (!returnValue) - return false; - - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - return true; - } - - if (!url.isValid()) - return false; - - if (url.scheme().isEmpty()) - return openDocument(url); - - quintptr returnValue = (quintptr)ShellExecute(0, 0, (wchar_t *)QString::fromUtf8(url.toEncoded().constData()).utf16(), - 0, 0, SW_SHOWNORMAL); - return (returnValue > 32); -} - -QT_END_NAMESPACE - -#endif // QT_NO_DESKTOPSERVICES diff --git a/src/gui/util/qdesktopservices_x11.cpp b/src/gui/util/qdesktopservices_x11.cpp deleted file mode 100644 index 73cf47a1dbc..00000000000 --- a/src/gui/util/qdesktopservices_x11.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtGui 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 "qdesktopservices.h" - -#ifndef QT_NO_DESKTOPSERVICES - -#include -#include -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -inline static bool launch(const QUrl &url, const QString &client) -{ -#if !defined(QT_NO_PROCESS) - return (QProcess::startDetached(client + QLatin1Char(' ') + QString::fromLatin1(url.toEncoded().constData()))); -#else - return (::system((client + QLatin1Char(' ') + QString::fromLatin1(url.toEncoded().constData())).toLocal8Bit().constData()) != -1); -#endif -} - -static bool openDocument(const QUrl &url) -{ - if (!url.isValid()) - return false; - - if (launch(url, QLatin1String("xdg-open"))) - return true; - - // Use the X11->desktopEnvironment value if X11 is non-NULL, - // otherwise just attempt to launch command regardless of the desktop environment - if ((!X11 || (X11 && X11->desktopEnvironment == DE_GNOME)) && launch(url, QLatin1String("gnome-open"))) { - return true; - } else { - if ((!X11 || (X11 && X11->desktopEnvironment == DE_KDE)) && launch(url, QLatin1String("kfmclient exec"))) - return true; - } - - if (launch(url, QLatin1String("firefox"))) - return true; - if (launch(url, QLatin1String("mozilla"))) - return true; - if (launch(url, QLatin1String("netscape"))) - return true; - if (launch(url, QLatin1String("opera"))) - return true; - - return false; -} - -static bool launchWebBrowser(const QUrl &url) -{ - if (!url.isValid()) - return false; - if (url.scheme() == QLatin1String("mailto")) - return openDocument(url); - - if (launch(url, QLatin1String("xdg-open"))) - return true; - if (launch(url, QString::fromLocal8Bit(getenv("DEFAULT_BROWSER")))) - return true; - if (launch(url, QString::fromLocal8Bit(getenv("BROWSER")))) - return true; - - // Use the X11->desktopEnvironment value if X11 is non-NULL, - // otherwise just attempt to launch command regardless of the desktop environment - if ((!X11 || (X11 && X11->desktopEnvironment == DE_GNOME)) && launch(url, QLatin1String("gnome-open"))) { - return true; - } else { - if ((!X11 || (X11 && X11->desktopEnvironment == DE_KDE)) && launch(url, QLatin1String("kfmclient openURL"))) - return true; - } - - if (launch(url, QLatin1String("firefox"))) - return true; - if (launch(url, QLatin1String("mozilla"))) - return true; - if (launch(url, QLatin1String("netscape"))) - return true; - if (launch(url, QLatin1String("opera"))) - return true; - return false; -} - -QT_END_NAMESPACE - -#endif // QT_NO_DESKTOPSERVICES diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro index 64decd03921..4c02a8ff57a 100644 --- a/src/platformsupport/platformsupport.pro +++ b/src/platformsupport/platformsupport.pro @@ -34,3 +34,4 @@ include(glxconvenience/glxconvenience.pri) #include(printersupport/printersupport.pri) include(inputcontext/inputcontext.pri) include(udev/udev.pri) +include(services/services.pri) diff --git a/src/platformsupport/services/genericunix/genericunix.pri b/src/platformsupport/services/genericunix/genericunix.pri new file mode 100644 index 00000000000..6afafa31d0b --- /dev/null +++ b/src/platformsupport/services/genericunix/genericunix.pri @@ -0,0 +1,2 @@ +HEADERS += $$PWD/qgenericunixservices_p.h +SOURCES += $$PWD/qgenericunixservices.cpp diff --git a/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/src/platformsupport/services/genericunix/qgenericunixservices.cpp new file mode 100644 index 00000000000..3c10fb63f60 --- /dev/null +++ b/src/platformsupport/services/genericunix/qgenericunixservices.cpp @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins 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 "qgenericunixservices_p.h" + +#include +#include +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +enum { debug = 0 }; + +static inline QGenericUnixServices::DesktopEnvironment detectDesktopEnvironment() +{ + if (!qgetenv("KDE_FULL_SESSION").isEmpty()) + return QGenericUnixServices::DE_KDE; + // GNOME_DESKTOP_SESSION_ID is deprecated for some reason, but still check it + if (qgetenv("DESKTOP_SESSION") == "gnome" || !qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty()) + return QGenericUnixServices::DE_GNOME; + return QGenericUnixServices::DE_UNKNOWN; +} + +static inline bool checkExecutable(const QString &candidate, QString *result) +{ + *result = QStandardPaths::findExecutable(candidate); + return !result->isEmpty(); +} + +static inline bool detectWebBrowser(QGenericUnixServices::DesktopEnvironment desktop, + bool checkBrowserVariable, + QString *browser) +{ + const char *browsers[] = {"google-chrome", "firefox", "mozilla", "opera"}; + + browser->clear(); + if (checkExecutable(QStringLiteral("xdg-open"), browser)) + return true; + + if (checkBrowserVariable) { + QByteArray browserVariable = qgetenv("DEFAULT_BROWSER"); + if (browserVariable.isEmpty()) + browserVariable = qgetenv("BROWSER"); + if (!browserVariable.isEmpty() && checkExecutable(QString::fromLocal8Bit(browserVariable), browser)) + return true; + } + + switch (desktop) { + case QGenericUnixServices::DE_UNKNOWN: + break; + case QGenericUnixServices::DE_KDE: + // Konqueror launcher + if (checkExecutable(QStringLiteral("kfmclient"), browser)) { + browser->append(QStringLiteral(" exec")); + return true; + } + case QGenericUnixServices::DE_GNOME: + if (checkExecutable(QStringLiteral("gnome-open"), browser)) + return true; + break; + } + + for (size_t i = 0; i < sizeof(browsers)/sizeof(char *); ++i) + if (checkExecutable(QLatin1String(browsers[i]), browser)) + return true; + return false; +} + +static inline bool launch(const QString &launcher, const QUrl &url) +{ + const QString command = launcher + QLatin1Char(' ') + QLatin1String(url.toEncoded()); + if (debug) + qDebug("Launching %s", qPrintable(command)); +#if defined(QT_NO_PROCESS) + const bool ok = ::system(qPrintable(command + QStringLiteral(" &"))); +#else + const bool ok = QProcess::startDetached(command); +#endif + if (!ok) + qWarning("Launch failed (%s)", qPrintable(command)); + return ok; +} + +QGenericUnixServices::QGenericUnixServices() : + m_desktopEnvironment(detectDesktopEnvironment()) +{ +} + +bool QGenericUnixServices::openUrl(const QUrl &url) +{ + if (url.scheme() == QStringLiteral("mailto")) + return openDocument(url); + + if (m_webBrowser.isEmpty() && !detectWebBrowser(m_desktopEnvironment, true, &m_webBrowser)) { + qWarning("%s: Unable to detect a web browser to launch '%s'", Q_FUNC_INFO, qPrintable(url.toString())); + return false; + } + return launch(m_webBrowser, url); +} + +bool QGenericUnixServices::openDocument(const QUrl &url) +{ + if (m_documentLauncher.isEmpty() && !detectWebBrowser(m_desktopEnvironment, false, &m_documentLauncher)) { + qWarning("%s: Unable to detect a launcher for '%s'", Q_FUNC_INFO, qPrintable(url.toString())); + return false; + } + return launch(m_documentLauncher, url); +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/services/genericunix/qgenericunixservices_p.h b/src/platformsupport/services/genericunix/qgenericunixservices_p.h new file mode 100644 index 00000000000..48b790a5b8c --- /dev/null +++ b/src/platformsupport/services/genericunix/qgenericunixservices_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins 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 QGENERICUNIXDESKTOPSERVICES_H +#define QGENERICUNIXDESKTOPSERVICES_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QGenericUnixServices : public QPlatformServices +{ +public: + enum DesktopEnvironment { + DE_UNKNOWN, + DE_KDE, + DE_GNOME + }; + + QGenericUnixServices(); + + virtual bool openUrl(const QUrl &url); + virtual bool openDocument(const QUrl &url); + +private: + const DesktopEnvironment m_desktopEnvironment; + QString m_webBrowser; + QString m_documentLauncher; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGENERICUNIXDESKTOPSERVICES_H diff --git a/src/platformsupport/services/services.pri b/src/platformsupport/services/services.pri new file mode 100644 index 00000000000..adee8526266 --- /dev/null +++ b/src/platformsupport/services/services.pri @@ -0,0 +1,3 @@ +unix:!mac { + include($$PWD/genericunix/genericunix.pri) +} diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 2771ec7e8a9..3e98be47419 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -46,6 +46,7 @@ #include "qwindowsglcontext.h" #include "qwindowsscreen.h" #include "qwindowstheme.h" +#include "qwindowsservices.h" #ifndef QT_NO_FREETYPE #include "qwindowsfontdatabase_ft.h" #endif @@ -162,6 +163,7 @@ struct QWindowsIntegrationPrivate QWindowsInputContext m_inputContext; QWindowsAccessibility m_accessibility; QWindowsTheme m_theme; + QWindowsServices m_services; }; QWindowsIntegrationPrivate::QWindowsIntegrationPrivate() @@ -339,4 +341,9 @@ QPlatformTheme *QWindowsIntegration::platformTheme() const return &d->m_theme; } +QPlatformServices *QWindowsIntegration::services() const +{ + return &d->m_services; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h index a96605f259b..ba5fafbbb5b 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.h +++ b/src/plugins/platforms/windows/qwindowsintegration.h @@ -70,6 +70,7 @@ public: virtual QPlatformNativeInterface *nativeInterface() const; virtual QPlatformFontDatabase *fontDatabase() const; virtual QPlatformTheme *platformTheme() const; + QPlatformServices *services() const; virtual QVariant styleHint(StyleHint hint) const; static QWindowsIntegration *instance(); diff --git a/src/plugins/platforms/windows/qwindowsservices.cpp b/src/plugins/platforms/windows/qwindowsservices.cpp new file mode 100644 index 00000000000..5cc4ce93afc --- /dev/null +++ b/src/plugins/platforms/windows/qwindowsservices.cpp @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins 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 "qwindowsservices.h" +#include "qtwindows_additional.h" + +#include +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +enum { debug = 0 }; + +static inline bool shellExecute(const QString &file) +{ + const int result = (int)ShellExecute(0, 0, (wchar_t*)file.utf16(), 0, 0, SW_SHOWNORMAL); + // ShellExecute returns a value greater than 32 if successful + if (result <= 32) { + qWarning("ShellExecute '%s' failed (error %0x).", qPrintable(file), result); + return false; + } + return true; +} + +// Retrieve the commandline for the default mail client. It contains a +// placeholder %1 for the URL. The default key used below is the +// command line for the mailto: shell command. +static inline QString mailCommand() +{ + enum { BufferSize = sizeof(wchar_t) * MAX_PATH }; + + const wchar_t mailUserKey[] = L"Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\mailto\\UserChoice"; + + wchar_t command[MAX_PATH] = {0}; + // Check if user has set preference, otherwise use default. + HKEY handle; + QString keyName; + if (!RegOpenKeyEx(HKEY_CURRENT_USER, mailUserKey, 0, KEY_READ, &handle)) { + DWORD bufferSize = BufferSize; + if (!RegQueryValueEx(handle, L"Progid", 0, 0, reinterpret_cast(command), &bufferSize)) + keyName = QString::fromWCharArray(command); + RegCloseKey(handle); + } + if (keyName.isEmpty()) + keyName = QStringLiteral("mailto"); + keyName += QStringLiteral("\\Shell\\Open\\Command"); + if (debug) + qDebug() << __FUNCTION__ << "keyName=" << keyName; + command[0] = 0; + if (!RegOpenKeyExW(HKEY_CLASSES_ROOT, (const wchar_t*)keyName.utf16(), 0, KEY_READ, &handle)) { + DWORD bufferSize = BufferSize; + RegQueryValueEx(handle, L"", 0, 0, reinterpret_cast(command), &bufferSize); + RegCloseKey(handle); + } + if (!command[0]) + return QString(); + wchar_t expandedCommand[MAX_PATH] = {0}; + return ExpandEnvironmentStrings(command, expandedCommand, MAX_PATH) ? + QString::fromWCharArray(expandedCommand) : QString::fromWCharArray(command); +} + +static inline bool launchMail(const QUrl &url) +{ + QString command = mailCommand(); + if (command.isEmpty()) { + qWarning("Cannot launch '%s': There is no mail program installed."); + return false; + } + //Make sure the path for the process is in quotes + const QChar doubleQuote = QLatin1Char('"'); + if (!command.startsWith(doubleQuote)) { + const int exeIndex = command.indexOf(QStringLiteral(".exe "), 0, Qt::CaseInsensitive); + if (exeIndex != -1) { + command.insert(exeIndex + 4, doubleQuote); + command.prepend(doubleQuote); + } + } + // Pass the url as the parameter. Should use QProcess::startDetached(), + // but that cannot handle a Windows command line [yet]. + command.replace(QStringLiteral("%1"), url.toString()); + if (debug) + qDebug() << __FUNCTION__ << "Launching" << command; + //start the process + PROCESS_INFORMATION pi; + ZeroMemory(&pi, sizeof(pi)); + STARTUPINFO si; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + if (!CreateProcess(NULL, (wchar_t*)command.utf16(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { + qErrnoWarning("Unable to launch '%s'", qPrintable(command)); + return false; + } + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + return true; +} + +bool QWindowsServices::openUrl(const QUrl &url) +{ + const QString scheme = url.scheme(); + if (scheme.isEmpty()) + return openDocument(url); + if (scheme == QStringLiteral("mailto") && launchMail(url)) + return true; + return shellExecute(QLatin1String(url.toEncoded())); +} + +bool QWindowsServices::openDocument(const QUrl &url) +{ + return shellExecute(url.isLocalFile() ? url.toLocalFile() : url.toString()); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsservices.h b/src/plugins/platforms/windows/qwindowsservices.h new file mode 100644 index 00000000000..d979ed1af13 --- /dev/null +++ b/src/plugins/platforms/windows/qwindowsservices.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins 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 QWINDOWSDESKTOPSERVICES_H +#define QWINDOWSDESKTOPSERVICES_H + +#include + +QT_BEGIN_NAMESPACE + +class QWindowsServices : public QPlatformServices +{ +public: + bool openUrl(const QUrl &url); + bool openDocument(const QUrl &url); +}; + +QT_END_NAMESPACE + +#endif // QWINDOWSDESKTOPSERVICES_H diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro index 01976a99364..58a117b8aff 100644 --- a/src/plugins/platforms/windows/windows.pro +++ b/src/plugins/platforms/windows/windows.pro @@ -13,6 +13,7 @@ LIBS *= -lOpenGL32 -lGdi32 -lUser32 -lOle32 -lWinspool -lImm32 -lWinmm -lOleaut win32-g++: LIBS *= -luuid # For the dialog helpers: LIBS *= -lshlwapi -lShell32 +LIBS *= -lAdvapi32 DEFINES *= QT_NO_CAST_FROM_ASCII @@ -46,7 +47,8 @@ SOURCES += \ qwindowsinputcontext.cpp \ qwindowsaccessibility.cpp \ qwindowstheme.cpp \ - qwindowsdialoghelpers.cpp + qwindowsdialoghelpers.cpp \ + qwindowsservices.cpp HEADERS += \ qwindowsnativeimage.h \ @@ -73,7 +75,8 @@ HEADERS += \ qwindowsinputcontext.h \ qwindowsaccessibility.h \ qwindowstheme.h \ - qwindowsdialoghelpers.h + qwindowsdialoghelpers.h \ + qwindowsservices.h # Enable access to HB_Face in harfbuzz includes included by qfontengine_p.h. DEFINES *= QT_COMPILES_IN_HARFBUZZ diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 40359169cae..0f7648a21b0 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -53,6 +53,8 @@ #include #include +#include +#include #include @@ -84,7 +86,8 @@ QT_BEGIN_NAMESPACE QXcbIntegration::QXcbIntegration(const QStringList ¶meters) - : m_eventDispatcher(createUnixEventDispatcher()) + : m_eventDispatcher(createUnixEventDispatcher()), + m_services(new QGenericUnixServices) { QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher); @@ -268,4 +271,9 @@ QPlatformSharedGraphicsCache *QXcbIntegration::createPlatformSharedGraphicsCache } #endif +QPlatformServices *QXcbIntegration::services() const +{ + return m_services.data(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index eefecd509b7..77d0e4903c9 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -81,6 +81,8 @@ public: QPlatformSharedGraphicsCache *createPlatformSharedGraphicsCache(const char *cacheId) const; #endif + QPlatformServices *services() const; + private: QList m_connections; @@ -95,6 +97,8 @@ private: #if defined(QT_USE_XCB_SHARED_GRAPHICS_CACHE) QScopedPointer m_sharedGraphicsCache; #endif + + QScopedPointer m_services; }; QT_END_NAMESPACE From 8723c2c90d8a30f2a593687c32e5b3063c8e213b Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Fri, 10 Feb 2012 13:44:30 +0100 Subject: [PATCH 164/406] Don't build printer plugins for Windows CE. Windows CE does not support printing. Change-Id: Ia00296fe05b460e9f78c60f8d0400698c6f6b3f3 Reviewed-by: Miikka Heikkinen Reviewed-by: Friedemann Kleint --- src/plugins/plugins.pro | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index b92ccff9859..177f64c71b6 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -4,4 +4,6 @@ SUBDIRS *= sqldrivers bearer !contains(QT_CONFIG, no-gui): SUBDIRS *= imageformats !isEmpty(QT.widgets.name): SUBDIRS += accessible -SUBDIRS += platforms platforminputcontexts printsupport generic +SUBDIRS += platforms platforminputcontexts generic + +!wince*:SUBDIRS += printsupport From 4ef2988aedff9d1b36fd366675e137fc606e8ddb Mon Sep 17 00:00:00 2001 From: John Stanley Date: Fri, 10 Feb 2012 16:34:29 -0500 Subject: [PATCH 165/406] Raise loopLevel for deleteLater in event filters Change-Id: Ibd0cd2a2efbcb13a54fe8ba055e7243c0c01b26e Reviewed-by: Bradley T. Hughes --- src/corelib/kernel/qabstracteventdispatcher.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index 0348faf1f21..3075eab7530 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -413,8 +413,12 @@ QAbstractEventDispatcher::EventFilter QAbstractEventDispatcher::setEventFilter(E bool QAbstractEventDispatcher::filterEvent(void *message) { Q_D(QAbstractEventDispatcher); - if (d->event_filter) + if (d->event_filter) { + // Raise the loopLevel so that deleteLater() calls in or triggered + // by event_filter() will be processed from the main event loop. + QScopedLoopLevelCounter loopLevelCounter(d->threadData); return d->event_filter(message); + } return false; } From e9a201fee27e2f213ab9adc87aabeeb57d6b40f4 Mon Sep 17 00:00:00 2001 From: Johannes Zellner Date: Fri, 10 Feb 2012 11:47:32 +0100 Subject: [PATCH 166/406] Add evdev based generic linux keyboard plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This introduces a udev based evdev keyboard plugin. It contains a default US keyboard map to fit the QKey enumeration. Most of the udev related code was developed by ICS. Major parts of the keyboard handler itself is reused from Qt 4 codebase. Change-Id: I383d05eecfde1c8916b0007dd101bfcb66711968 Reviewed-by: Laszlo Agocs Reviewed-by: Samuel Rødal --- .../generic/evdevkeyboard/evdevkeyboard.pro | 19 + src/plugins/generic/evdevkeyboard/main.cpp | 77 ++ .../evdevkeyboard/qevdevkeyboard_defaultmap.h | 787 ++++++++++++++++++ .../evdevkeyboard/qevdevkeyboardhandler.cpp | 490 +++++++++++ .../evdevkeyboard/qevdevkeyboardhandler.h | 202 +++++ .../evdevkeyboard/qevdevkeyboardmanager.cpp | 250 ++++++ .../evdevkeyboard/qevdevkeyboardmanager.h | 85 ++ src/plugins/generic/generic.pro | 2 +- 8 files changed, 1911 insertions(+), 1 deletion(-) create mode 100644 src/plugins/generic/evdevkeyboard/evdevkeyboard.pro create mode 100644 src/plugins/generic/evdevkeyboard/main.cpp create mode 100644 src/plugins/generic/evdevkeyboard/qevdevkeyboard_defaultmap.h create mode 100644 src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.cpp create mode 100644 src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.h create mode 100644 src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.cpp create mode 100644 src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.h diff --git a/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro b/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro new file mode 100644 index 00000000000..243cd0c0b1e --- /dev/null +++ b/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro @@ -0,0 +1,19 @@ +TARGET = qevdevkeyboardplugin +load(qt_plugin) + +DESTDIR = $$QT.gui.plugins/generic +target.path = $$[QT_INSTALL_PLUGINS]/generic +INSTALLS += target + +HEADERS = \ + qevdevkeybaord_defaultmap.h \ + qevdevkeyboardhandler.h \ + qevdevkeyboardmanager.h + +QT += core-private + +LIBS += -ludev + +SOURCES = main.cpp \ + qevdevkeyboardhandler.cpp \ + qevdevkeyboardmanager.cpp diff --git a/src/plugins/generic/evdevkeyboard/main.cpp b/src/plugins/generic/evdevkeyboard/main.cpp new file mode 100644 index 00000000000..c3cc9f629a3 --- /dev/null +++ b/src/plugins/generic/evdevkeyboard/main.cpp @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui 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 +#include "qevdevkeyboardmanager.h" + +QT_BEGIN_NAMESPACE + +class QEvdevKeyboardPlugin : public QGenericPlugin +{ +public: + QEvdevKeyboardPlugin(); + + QStringList keys() const; + QObject* create(const QString &key, const QString &specification); +}; + +QEvdevKeyboardPlugin::QEvdevKeyboardPlugin() + : QGenericPlugin() +{ +} + +QStringList QEvdevKeyboardPlugin::keys() const +{ + return (QStringList() + << QLatin1String("EvdevKeyboard")); +} + +QObject* QEvdevKeyboardPlugin::create(const QString &key, + const QString &specification) +{ + if (!key.compare(QLatin1String("EvdevKeyboard"), Qt::CaseInsensitive)) + return new QEvdevKeyboardManager(key, specification); + return 0; +} + +Q_EXPORT_PLUGIN2(qevdevkeyboarplugin, QEvdevKeyboardPlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/generic/evdevkeyboard/qevdevkeyboard_defaultmap.h b/src/plugins/generic/evdevkeyboard/qevdevkeyboard_defaultmap.h new file mode 100644 index 00000000000..49b07efff9c --- /dev/null +++ b/src/plugins/generic/evdevkeyboard/qevdevkeyboard_defaultmap.h @@ -0,0 +1,787 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui 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 QEVDEVKEYBOARDHANDLER_DEFAULTMAP_H +#define QEVDEVKEYBOARDHANDLER_DEFAULTMAP_H + +// no QT_BEGIN_NAMESPACE, since we include it internally... + +const QEvdevKeyboardMap::Mapping QEvdevKeyboardHandler::s_keymap_default[] = { + { 1, 0xffff, 0x01000000, 0x00, 0x00, 0x0000 }, + { 2, 0x0031, 0x00000031, 0x00, 0x00, 0x0000 }, + { 2, 0x0021, 0x00000021, 0x01, 0x00, 0x0000 }, + { 3, 0x0032, 0x00000032, 0x00, 0x00, 0x0000 }, + { 3, 0x0040, 0x00000040, 0x01, 0x00, 0x0000 }, + { 3, 0x0040, 0x00000040, 0x02, 0x00, 0x0000 }, + { 4, 0x0033, 0x00000033, 0x00, 0x00, 0x0000 }, + { 4, 0x0023, 0x00000023, 0x01, 0x00, 0x0000 }, + { 4, 0xffff, 0x01000000, 0x04, 0x00, 0x0000 }, + { 5, 0x0034, 0x00000034, 0x00, 0x00, 0x0000 }, + { 5, 0x0024, 0x00000024, 0x01, 0x00, 0x0000 }, + { 5, 0x0024, 0x00000024, 0x02, 0x00, 0x0000 }, + { 5, 0x005c, 0x0400005c, 0x04, 0x00, 0x0000 }, + { 6, 0x0035, 0x00000035, 0x00, 0x00, 0x0000 }, + { 6, 0x0025, 0x00000025, 0x01, 0x00, 0x0000 }, + { 6, 0x005d, 0x0400005d, 0x04, 0x00, 0x0000 }, + { 7, 0x0036, 0x00000036, 0x00, 0x00, 0x0000 }, + { 7, 0x005e, 0x0000005e, 0x01, 0x00, 0x0000 }, + { 7, 0x005e, 0x01001252, 0x02, 0x01, 0x0000 }, + { 7, 0x005e, 0x0400005e, 0x04, 0x00, 0x0000 }, + { 8, 0x0037, 0x00000037, 0x00, 0x00, 0x0000 }, + { 8, 0x0026, 0x00000026, 0x01, 0x00, 0x0000 }, + { 8, 0x007b, 0x0000007b, 0x02, 0x00, 0x0000 }, + { 8, 0x005f, 0x0400005f, 0x04, 0x00, 0x0000 }, + { 9, 0x0038, 0x00000038, 0x00, 0x00, 0x0000 }, + { 9, 0x002a, 0x0000002a, 0x01, 0x00, 0x0000 }, + { 9, 0x005b, 0x0000005b, 0x02, 0x00, 0x0000 }, + { 9, 0xffff, 0x01000003, 0x04, 0x00, 0x0000 }, + { 10, 0x0039, 0x00000039, 0x00, 0x00, 0x0000 }, + { 10, 0x0028, 0x00000028, 0x01, 0x00, 0x0000 }, + { 10, 0x005d, 0x0000005d, 0x02, 0x00, 0x0000 }, + { 11, 0x0030, 0x00000030, 0x00, 0x00, 0x0000 }, + { 11, 0x0029, 0x00000029, 0x01, 0x00, 0x0000 }, + { 11, 0x007d, 0x0000007d, 0x02, 0x00, 0x0000 }, + { 12, 0x002d, 0x0000002d, 0x00, 0x00, 0x0000 }, + { 12, 0x005f, 0x0000005f, 0x01, 0x00, 0x0000 }, + { 12, 0x005c, 0x0000005c, 0x02, 0x00, 0x0000 }, + { 12, 0x005f, 0x0400005f, 0x04, 0x00, 0x0000 }, + { 12, 0x005f, 0x0400005f, 0x05, 0x00, 0x0000 }, + { 13, 0x003d, 0x0000003d, 0x00, 0x00, 0x0000 }, + { 13, 0x002b, 0x0000002b, 0x01, 0x00, 0x0000 }, + { 14, 0xffff, 0x01000003, 0x00, 0x00, 0x0000 }, + { 14, 0xffff, 0x01000000, 0x0c, 0x08, 0x0300 }, + { 15, 0xffff, 0x01000001, 0x00, 0x00, 0x0000 }, + { 16, 0x0071, 0x00000051, 0x00, 0x00, 0x0000 }, + { 16, 0x0051, 0x00000051, 0x01, 0x00, 0x0000 }, + { 16, 0x0071, 0x00000051, 0x02, 0x00, 0x0000 }, + { 16, 0x0051, 0x00000051, 0x03, 0x00, 0x0000 }, + { 16, 0x0071, 0x04000051, 0x04, 0x00, 0x0000 }, + { 16, 0x0071, 0x04000051, 0x05, 0x00, 0x0000 }, + { 16, 0x0071, 0x04000051, 0x06, 0x00, 0x0000 }, + { 16, 0x0071, 0x04000051, 0x07, 0x00, 0x0000 }, + { 16, 0x0071, 0x08000051, 0x08, 0x00, 0x0000 }, + { 16, 0x0071, 0x08000051, 0x09, 0x00, 0x0000 }, + { 16, 0x0071, 0x08000051, 0x0a, 0x00, 0x0000 }, + { 16, 0x0071, 0x08000051, 0x0b, 0x00, 0x0000 }, + { 16, 0x0071, 0x0c000051, 0x0c, 0x00, 0x0000 }, + { 16, 0x0071, 0x0c000051, 0x0d, 0x00, 0x0000 }, + { 16, 0x0071, 0x0c000051, 0x0e, 0x00, 0x0000 }, + { 16, 0x0071, 0x0c000051, 0x0f, 0x00, 0x0000 }, + { 17, 0x0077, 0x00000057, 0x00, 0x00, 0x0000 }, + { 17, 0x0057, 0x00000057, 0x01, 0x00, 0x0000 }, + { 17, 0x0077, 0x00000057, 0x02, 0x00, 0x0000 }, + { 17, 0x0057, 0x00000057, 0x03, 0x00, 0x0000 }, + { 17, 0x0077, 0x04000057, 0x04, 0x00, 0x0000 }, + { 17, 0x0077, 0x04000057, 0x05, 0x00, 0x0000 }, + { 17, 0x0077, 0x04000057, 0x06, 0x00, 0x0000 }, + { 17, 0x0077, 0x04000057, 0x07, 0x00, 0x0000 }, + { 17, 0x0077, 0x08000057, 0x08, 0x00, 0x0000 }, + { 17, 0x0077, 0x08000057, 0x09, 0x00, 0x0000 }, + { 17, 0x0077, 0x08000057, 0x0a, 0x00, 0x0000 }, + { 17, 0x0077, 0x08000057, 0x0b, 0x00, 0x0000 }, + { 17, 0x0077, 0x0c000057, 0x0c, 0x00, 0x0000 }, + { 17, 0x0077, 0x0c000057, 0x0d, 0x00, 0x0000 }, + { 17, 0x0077, 0x0c000057, 0x0e, 0x00, 0x0000 }, + { 17, 0x0077, 0x0c000057, 0x0f, 0x00, 0x0000 }, + { 18, 0x0065, 0x00000045, 0x00, 0x00, 0x0000 }, + { 18, 0x0045, 0x00000045, 0x01, 0x00, 0x0000 }, + { 18, 0x0065, 0x00000045, 0x02, 0x00, 0x0000 }, + { 18, 0x0045, 0x00000045, 0x03, 0x00, 0x0000 }, + { 18, 0x0065, 0x04000045, 0x04, 0x00, 0x0000 }, + { 18, 0x0065, 0x04000045, 0x05, 0x00, 0x0000 }, + { 18, 0x0065, 0x04000045, 0x06, 0x00, 0x0000 }, + { 18, 0x0065, 0x04000045, 0x07, 0x00, 0x0000 }, + { 18, 0x0065, 0x08000045, 0x08, 0x00, 0x0000 }, + { 18, 0x0065, 0x08000045, 0x09, 0x00, 0x0000 }, + { 18, 0x0065, 0x08000045, 0x0a, 0x00, 0x0000 }, + { 18, 0x0065, 0x08000045, 0x0b, 0x00, 0x0000 }, + { 18, 0x0065, 0x0c000045, 0x0c, 0x00, 0x0000 }, + { 18, 0x0065, 0x0c000045, 0x0d, 0x00, 0x0000 }, + { 18, 0x0065, 0x0c000045, 0x0e, 0x00, 0x0000 }, + { 18, 0x0065, 0x0c000045, 0x0f, 0x00, 0x0000 }, + { 19, 0x0072, 0x00000052, 0x00, 0x00, 0x0000 }, + { 19, 0x0052, 0x00000052, 0x01, 0x00, 0x0000 }, + { 19, 0x0072, 0x00000052, 0x02, 0x00, 0x0000 }, + { 19, 0x0052, 0x00000052, 0x03, 0x00, 0x0000 }, + { 19, 0x0072, 0x04000052, 0x04, 0x00, 0x0000 }, + { 19, 0x0072, 0x04000052, 0x05, 0x00, 0x0000 }, + { 19, 0x0072, 0x04000052, 0x06, 0x00, 0x0000 }, + { 19, 0x0072, 0x04000052, 0x07, 0x00, 0x0000 }, + { 19, 0x0072, 0x08000052, 0x08, 0x00, 0x0000 }, + { 19, 0x0072, 0x08000052, 0x09, 0x00, 0x0000 }, + { 19, 0x0072, 0x08000052, 0x0a, 0x00, 0x0000 }, + { 19, 0x0072, 0x08000052, 0x0b, 0x00, 0x0000 }, + { 19, 0x0072, 0x0c000052, 0x0c, 0x00, 0x0000 }, + { 19, 0x0072, 0x0c000052, 0x0d, 0x00, 0x0000 }, + { 19, 0x0072, 0x0c000052, 0x0e, 0x00, 0x0000 }, + { 19, 0x0072, 0x0c000052, 0x0f, 0x00, 0x0000 }, + { 20, 0x0074, 0x00000054, 0x00, 0x00, 0x0000 }, + { 20, 0x0054, 0x00000054, 0x01, 0x00, 0x0000 }, + { 20, 0x0074, 0x00000054, 0x02, 0x00, 0x0000 }, + { 20, 0x0054, 0x00000054, 0x03, 0x00, 0x0000 }, + { 20, 0x0074, 0x04000054, 0x04, 0x00, 0x0000 }, + { 20, 0x0074, 0x04000054, 0x05, 0x00, 0x0000 }, + { 20, 0x0074, 0x04000054, 0x06, 0x00, 0x0000 }, + { 20, 0x0074, 0x04000054, 0x07, 0x00, 0x0000 }, + { 20, 0x0074, 0x08000054, 0x08, 0x00, 0x0000 }, + { 20, 0x0074, 0x08000054, 0x09, 0x00, 0x0000 }, + { 20, 0x0074, 0x08000054, 0x0a, 0x00, 0x0000 }, + { 20, 0x0074, 0x08000054, 0x0b, 0x00, 0x0000 }, + { 20, 0x0074, 0x0c000054, 0x0c, 0x00, 0x0000 }, + { 20, 0x0074, 0x0c000054, 0x0d, 0x00, 0x0000 }, + { 20, 0x0074, 0x0c000054, 0x0e, 0x00, 0x0000 }, + { 20, 0x0074, 0x0c000054, 0x0f, 0x00, 0x0000 }, + { 21, 0x0079, 0x00000059, 0x00, 0x00, 0x0000 }, + { 21, 0x0059, 0x00000059, 0x01, 0x00, 0x0000 }, + { 21, 0x0079, 0x00000059, 0x02, 0x00, 0x0000 }, + { 21, 0x0059, 0x00000059, 0x03, 0x00, 0x0000 }, + { 21, 0x0079, 0x04000059, 0x04, 0x00, 0x0000 }, + { 21, 0x0079, 0x04000059, 0x05, 0x00, 0x0000 }, + { 21, 0x0079, 0x04000059, 0x06, 0x00, 0x0000 }, + { 21, 0x0079, 0x04000059, 0x07, 0x00, 0x0000 }, + { 21, 0x0079, 0x08000059, 0x08, 0x00, 0x0000 }, + { 21, 0x0079, 0x08000059, 0x09, 0x00, 0x0000 }, + { 21, 0x0079, 0x08000059, 0x0a, 0x00, 0x0000 }, + { 21, 0x0079, 0x08000059, 0x0b, 0x00, 0x0000 }, + { 21, 0x0079, 0x0c000059, 0x0c, 0x00, 0x0000 }, + { 21, 0x0079, 0x0c000059, 0x0d, 0x00, 0x0000 }, + { 21, 0x0079, 0x0c000059, 0x0e, 0x00, 0x0000 }, + { 21, 0x0079, 0x0c000059, 0x0f, 0x00, 0x0000 }, + { 22, 0x0075, 0x00000055, 0x00, 0x00, 0x0000 }, + { 22, 0x0055, 0x00000055, 0x01, 0x00, 0x0000 }, + { 22, 0x0075, 0x00000055, 0x02, 0x00, 0x0000 }, + { 22, 0x0055, 0x00000055, 0x03, 0x00, 0x0000 }, + { 22, 0x0075, 0x04000055, 0x04, 0x00, 0x0000 }, + { 22, 0x0075, 0x04000055, 0x05, 0x00, 0x0000 }, + { 22, 0x0075, 0x04000055, 0x06, 0x00, 0x0000 }, + { 22, 0x0075, 0x04000055, 0x07, 0x00, 0x0000 }, + { 22, 0x0075, 0x08000055, 0x08, 0x00, 0x0000 }, + { 22, 0x0075, 0x08000055, 0x09, 0x00, 0x0000 }, + { 22, 0x0075, 0x08000055, 0x0a, 0x00, 0x0000 }, + { 22, 0x0075, 0x08000055, 0x0b, 0x00, 0x0000 }, + { 22, 0x0075, 0x0c000055, 0x0c, 0x00, 0x0000 }, + { 22, 0x0075, 0x0c000055, 0x0d, 0x00, 0x0000 }, + { 22, 0x0075, 0x0c000055, 0x0e, 0x00, 0x0000 }, + { 22, 0x0075, 0x0c000055, 0x0f, 0x00, 0x0000 }, + { 23, 0x0069, 0x00000049, 0x00, 0x00, 0x0000 }, + { 23, 0x0049, 0x00000049, 0x01, 0x00, 0x0000 }, + { 23, 0x0069, 0x00000049, 0x02, 0x00, 0x0000 }, + { 23, 0x0049, 0x00000049, 0x03, 0x00, 0x0000 }, + { 23, 0x0069, 0x04000049, 0x04, 0x00, 0x0000 }, + { 23, 0x0069, 0x04000049, 0x05, 0x00, 0x0000 }, + { 23, 0x0069, 0x04000049, 0x06, 0x00, 0x0000 }, + { 23, 0x0069, 0x04000049, 0x07, 0x00, 0x0000 }, + { 23, 0x0069, 0x08000049, 0x08, 0x00, 0x0000 }, + { 23, 0x0069, 0x08000049, 0x09, 0x00, 0x0000 }, + { 23, 0x0069, 0x08000049, 0x0a, 0x00, 0x0000 }, + { 23, 0x0069, 0x08000049, 0x0b, 0x00, 0x0000 }, + { 23, 0x0069, 0x0c000049, 0x0c, 0x00, 0x0000 }, + { 23, 0x0069, 0x0c000049, 0x0d, 0x00, 0x0000 }, + { 23, 0x0069, 0x0c000049, 0x0e, 0x00, 0x0000 }, + { 23, 0x0069, 0x0c000049, 0x0f, 0x00, 0x0000 }, + { 24, 0x006f, 0x0000004f, 0x00, 0x00, 0x0000 }, + { 24, 0x004f, 0x0000004f, 0x01, 0x00, 0x0000 }, + { 24, 0x006f, 0x0000004f, 0x02, 0x00, 0x0000 }, + { 24, 0x004f, 0x0000004f, 0x03, 0x00, 0x0000 }, + { 24, 0x006f, 0x0400004f, 0x04, 0x00, 0x0000 }, + { 24, 0x006f, 0x0400004f, 0x05, 0x00, 0x0000 }, + { 24, 0x006f, 0x0400004f, 0x06, 0x00, 0x0000 }, + { 24, 0x006f, 0x0400004f, 0x07, 0x00, 0x0000 }, + { 24, 0x006f, 0x0800004f, 0x08, 0x00, 0x0000 }, + { 24, 0x006f, 0x0800004f, 0x09, 0x00, 0x0000 }, + { 24, 0x006f, 0x0800004f, 0x0a, 0x00, 0x0000 }, + { 24, 0x006f, 0x0800004f, 0x0b, 0x00, 0x0000 }, + { 24, 0x006f, 0x0c00004f, 0x0c, 0x00, 0x0000 }, + { 24, 0x006f, 0x0c00004f, 0x0d, 0x00, 0x0000 }, + { 24, 0x006f, 0x0c00004f, 0x0e, 0x00, 0x0000 }, + { 24, 0x006f, 0x0c00004f, 0x0f, 0x00, 0x0000 }, + { 25, 0x0070, 0x00000050, 0x00, 0x00, 0x0000 }, + { 25, 0x0050, 0x00000050, 0x01, 0x00, 0x0000 }, + { 25, 0x0070, 0x00000050, 0x02, 0x00, 0x0000 }, + { 25, 0x0050, 0x00000050, 0x03, 0x00, 0x0000 }, + { 25, 0x0070, 0x04000050, 0x04, 0x00, 0x0000 }, + { 25, 0x0070, 0x04000050, 0x05, 0x00, 0x0000 }, + { 25, 0x0070, 0x04000050, 0x06, 0x00, 0x0000 }, + { 25, 0x0070, 0x04000050, 0x07, 0x00, 0x0000 }, + { 25, 0x0070, 0x08000050, 0x08, 0x00, 0x0000 }, + { 25, 0x0070, 0x08000050, 0x09, 0x00, 0x0000 }, + { 25, 0x0070, 0x08000050, 0x0a, 0x00, 0x0000 }, + { 25, 0x0070, 0x08000050, 0x0b, 0x00, 0x0000 }, + { 25, 0x0070, 0x0c000050, 0x0c, 0x00, 0x0000 }, + { 25, 0x0070, 0x0c000050, 0x0d, 0x00, 0x0000 }, + { 25, 0x0070, 0x0c000050, 0x0e, 0x00, 0x0000 }, + { 25, 0x0070, 0x0c000050, 0x0f, 0x00, 0x0000 }, + { 26, 0x005b, 0x0000005b, 0x00, 0x00, 0x0000 }, + { 26, 0x007b, 0x0000007b, 0x01, 0x00, 0x0000 }, + { 26, 0xffff, 0x01000000, 0x04, 0x00, 0x0000 }, + { 27, 0x005d, 0x0000005d, 0x00, 0x00, 0x0000 }, + { 27, 0x007d, 0x0000007d, 0x01, 0x00, 0x0000 }, + { 27, 0x007e, 0x0000007e, 0x02, 0x00, 0x0000 }, + { 27, 0x005d, 0x0400005d, 0x04, 0x00, 0x0000 }, + { 28, 0xffff, 0x01000004, 0x00, 0x00, 0x0000 }, + { 28, 0x006d, 0x0c00004d, 0x08, 0x00, 0x0000 }, + { 29, 0xffff, 0x01000021, 0x00, 0x04, 0x0004 }, + { 30, 0x0061, 0x00000041, 0x00, 0x00, 0x0000 }, + { 30, 0x0041, 0x00000041, 0x01, 0x00, 0x0000 }, + { 30, 0x0061, 0x00000041, 0x02, 0x00, 0x0000 }, + { 30, 0x0041, 0x00000041, 0x03, 0x00, 0x0000 }, + { 30, 0x0061, 0x04000041, 0x04, 0x00, 0x0000 }, + { 30, 0x0061, 0x04000041, 0x05, 0x00, 0x0000 }, + { 30, 0x0061, 0x04000041, 0x06, 0x00, 0x0000 }, + { 30, 0x0061, 0x04000041, 0x07, 0x00, 0x0000 }, + { 30, 0x0061, 0x08000041, 0x08, 0x00, 0x0000 }, + { 30, 0x0061, 0x08000041, 0x09, 0x00, 0x0000 }, + { 30, 0x0061, 0x08000041, 0x0a, 0x00, 0x0000 }, + { 30, 0x0061, 0x08000041, 0x0b, 0x00, 0x0000 }, + { 30, 0x0061, 0x0c000041, 0x0c, 0x00, 0x0000 }, + { 30, 0x0061, 0x0c000041, 0x0d, 0x00, 0x0000 }, + { 30, 0x0061, 0x0c000041, 0x0e, 0x00, 0x0000 }, + { 30, 0x0061, 0x0c000041, 0x0f, 0x00, 0x0000 }, + { 31, 0x0073, 0x00000053, 0x00, 0x00, 0x0000 }, + { 31, 0x0053, 0x00000053, 0x01, 0x00, 0x0000 }, + { 31, 0x0073, 0x00000053, 0x02, 0x00, 0x0000 }, + { 31, 0x0053, 0x00000053, 0x03, 0x00, 0x0000 }, + { 31, 0x0073, 0x04000053, 0x04, 0x00, 0x0000 }, + { 31, 0x0073, 0x04000053, 0x05, 0x00, 0x0000 }, + { 31, 0x0073, 0x04000053, 0x06, 0x00, 0x0000 }, + { 31, 0x0073, 0x04000053, 0x07, 0x00, 0x0000 }, + { 31, 0x0073, 0x08000053, 0x08, 0x00, 0x0000 }, + { 31, 0x0073, 0x08000053, 0x09, 0x00, 0x0000 }, + { 31, 0x0073, 0x08000053, 0x0a, 0x00, 0x0000 }, + { 31, 0x0073, 0x08000053, 0x0b, 0x00, 0x0000 }, + { 31, 0x0073, 0x0c000053, 0x0c, 0x00, 0x0000 }, + { 31, 0x0073, 0x0c000053, 0x0d, 0x00, 0x0000 }, + { 31, 0x0073, 0x0c000053, 0x0e, 0x00, 0x0000 }, + { 31, 0x0073, 0x0c000053, 0x0f, 0x00, 0x0000 }, + { 32, 0x0064, 0x00000044, 0x00, 0x00, 0x0000 }, + { 32, 0x0044, 0x00000044, 0x01, 0x00, 0x0000 }, + { 32, 0x0064, 0x00000044, 0x02, 0x00, 0x0000 }, + { 32, 0x0044, 0x00000044, 0x03, 0x00, 0x0000 }, + { 32, 0x0064, 0x04000044, 0x04, 0x00, 0x0000 }, + { 32, 0x0064, 0x04000044, 0x05, 0x00, 0x0000 }, + { 32, 0x0064, 0x04000044, 0x06, 0x00, 0x0000 }, + { 32, 0x0064, 0x04000044, 0x07, 0x00, 0x0000 }, + { 32, 0x0064, 0x08000044, 0x08, 0x00, 0x0000 }, + { 32, 0x0064, 0x08000044, 0x09, 0x00, 0x0000 }, + { 32, 0x0064, 0x08000044, 0x0a, 0x00, 0x0000 }, + { 32, 0x0064, 0x08000044, 0x0b, 0x00, 0x0000 }, + { 32, 0x0064, 0x0c000044, 0x0c, 0x00, 0x0000 }, + { 32, 0x0064, 0x0c000044, 0x0d, 0x00, 0x0000 }, + { 32, 0x0064, 0x0c000044, 0x0e, 0x00, 0x0000 }, + { 32, 0x0064, 0x0c000044, 0x0f, 0x00, 0x0000 }, + { 33, 0x0066, 0x00000046, 0x00, 0x00, 0x0000 }, + { 33, 0x0046, 0x00000046, 0x01, 0x00, 0x0000 }, + { 33, 0x0066, 0x00000046, 0x02, 0x00, 0x0000 }, + { 33, 0x0046, 0x00000046, 0x03, 0x00, 0x0000 }, + { 33, 0x0066, 0x04000046, 0x04, 0x00, 0x0000 }, + { 33, 0x0066, 0x04000046, 0x05, 0x00, 0x0000 }, + { 33, 0x0066, 0x04000046, 0x06, 0x00, 0x0000 }, + { 33, 0x0066, 0x04000046, 0x07, 0x00, 0x0000 }, + { 33, 0x0066, 0x08000046, 0x08, 0x00, 0x0000 }, + { 33, 0x0066, 0x08000046, 0x09, 0x00, 0x0000 }, + { 33, 0x0066, 0x08000046, 0x0a, 0x00, 0x0000 }, + { 33, 0x0066, 0x08000046, 0x0b, 0x00, 0x0000 }, + { 33, 0x0066, 0x0c000046, 0x0c, 0x00, 0x0000 }, + { 33, 0x0066, 0x0c000046, 0x0d, 0x00, 0x0000 }, + { 33, 0x0066, 0x0c000046, 0x0e, 0x00, 0x0000 }, + { 33, 0x0066, 0x0c000046, 0x0f, 0x00, 0x0000 }, + { 34, 0x0067, 0x00000047, 0x00, 0x00, 0x0000 }, + { 34, 0x0047, 0x00000047, 0x01, 0x00, 0x0000 }, + { 34, 0x0067, 0x00000047, 0x02, 0x00, 0x0000 }, + { 34, 0x0047, 0x00000047, 0x03, 0x00, 0x0000 }, + { 34, 0x0067, 0x04000047, 0x04, 0x00, 0x0000 }, + { 34, 0x0067, 0x04000047, 0x05, 0x00, 0x0000 }, + { 34, 0x0067, 0x04000047, 0x06, 0x00, 0x0000 }, + { 34, 0x0067, 0x04000047, 0x07, 0x00, 0x0000 }, + { 34, 0x0067, 0x08000047, 0x08, 0x00, 0x0000 }, + { 34, 0x0067, 0x08000047, 0x09, 0x00, 0x0000 }, + { 34, 0x0067, 0x08000047, 0x0a, 0x00, 0x0000 }, + { 34, 0x0067, 0x08000047, 0x0b, 0x00, 0x0000 }, + { 34, 0x0067, 0x0c000047, 0x0c, 0x00, 0x0000 }, + { 34, 0x0067, 0x0c000047, 0x0d, 0x00, 0x0000 }, + { 34, 0x0067, 0x0c000047, 0x0e, 0x00, 0x0000 }, + { 34, 0x0067, 0x0c000047, 0x0f, 0x00, 0x0000 }, + { 35, 0x0068, 0x00000048, 0x00, 0x00, 0x0000 }, + { 35, 0x0048, 0x00000048, 0x01, 0x00, 0x0000 }, + { 35, 0x0068, 0x00000048, 0x02, 0x00, 0x0000 }, + { 35, 0x0048, 0x00000048, 0x03, 0x00, 0x0000 }, + { 35, 0x0068, 0x04000048, 0x04, 0x00, 0x0000 }, + { 35, 0x0068, 0x04000048, 0x05, 0x00, 0x0000 }, + { 35, 0x0068, 0x04000048, 0x06, 0x00, 0x0000 }, + { 35, 0x0068, 0x04000048, 0x07, 0x00, 0x0000 }, + { 35, 0x0068, 0x08000048, 0x08, 0x00, 0x0000 }, + { 35, 0x0068, 0x08000048, 0x09, 0x00, 0x0000 }, + { 35, 0x0068, 0x08000048, 0x0a, 0x00, 0x0000 }, + { 35, 0x0068, 0x08000048, 0x0b, 0x00, 0x0000 }, + { 35, 0x0068, 0x0c000048, 0x0c, 0x00, 0x0000 }, + { 35, 0x0068, 0x0c000048, 0x0d, 0x00, 0x0000 }, + { 35, 0x0068, 0x0c000048, 0x0e, 0x00, 0x0000 }, + { 35, 0x0068, 0x0c000048, 0x0f, 0x00, 0x0000 }, + { 36, 0x006a, 0x0000004a, 0x00, 0x00, 0x0000 }, + { 36, 0x004a, 0x0000004a, 0x01, 0x00, 0x0000 }, + { 36, 0x006a, 0x0000004a, 0x02, 0x00, 0x0000 }, + { 36, 0x004a, 0x0000004a, 0x03, 0x00, 0x0000 }, + { 36, 0x006a, 0x0400004a, 0x04, 0x00, 0x0000 }, + { 36, 0x006a, 0x0400004a, 0x05, 0x00, 0x0000 }, + { 36, 0x006a, 0x0400004a, 0x06, 0x00, 0x0000 }, + { 36, 0x006a, 0x0400004a, 0x07, 0x00, 0x0000 }, + { 36, 0x006a, 0x0800004a, 0x08, 0x00, 0x0000 }, + { 36, 0x006a, 0x0800004a, 0x09, 0x00, 0x0000 }, + { 36, 0x006a, 0x0800004a, 0x0a, 0x00, 0x0000 }, + { 36, 0x006a, 0x0800004a, 0x0b, 0x00, 0x0000 }, + { 36, 0x006a, 0x0c00004a, 0x0c, 0x00, 0x0000 }, + { 36, 0x006a, 0x0c00004a, 0x0d, 0x00, 0x0000 }, + { 36, 0x006a, 0x0c00004a, 0x0e, 0x00, 0x0000 }, + { 36, 0x006a, 0x0c00004a, 0x0f, 0x00, 0x0000 }, + { 37, 0x006b, 0x0000004b, 0x00, 0x00, 0x0000 }, + { 37, 0x004b, 0x0000004b, 0x01, 0x00, 0x0000 }, + { 37, 0x006b, 0x0000004b, 0x02, 0x00, 0x0000 }, + { 37, 0x004b, 0x0000004b, 0x03, 0x00, 0x0000 }, + { 37, 0x006b, 0x0400004b, 0x04, 0x00, 0x0000 }, + { 37, 0x006b, 0x0400004b, 0x05, 0x00, 0x0000 }, + { 37, 0x006b, 0x0400004b, 0x06, 0x00, 0x0000 }, + { 37, 0x006b, 0x0400004b, 0x07, 0x00, 0x0000 }, + { 37, 0x006b, 0x0800004b, 0x08, 0x00, 0x0000 }, + { 37, 0x006b, 0x0800004b, 0x09, 0x00, 0x0000 }, + { 37, 0x006b, 0x0800004b, 0x0a, 0x00, 0x0000 }, + { 37, 0x006b, 0x0800004b, 0x0b, 0x00, 0x0000 }, + { 37, 0x006b, 0x0c00004b, 0x0c, 0x00, 0x0000 }, + { 37, 0x006b, 0x0c00004b, 0x0d, 0x00, 0x0000 }, + { 37, 0x006b, 0x0c00004b, 0x0e, 0x00, 0x0000 }, + { 37, 0x006b, 0x0c00004b, 0x0f, 0x00, 0x0000 }, + { 38, 0x006c, 0x0000004c, 0x00, 0x00, 0x0000 }, + { 38, 0x004c, 0x0000004c, 0x01, 0x00, 0x0000 }, + { 38, 0x006c, 0x0000004c, 0x02, 0x00, 0x0000 }, + { 38, 0x004c, 0x0000004c, 0x03, 0x00, 0x0000 }, + { 38, 0x006c, 0x0400004c, 0x04, 0x00, 0x0000 }, + { 38, 0x006c, 0x0400004c, 0x05, 0x00, 0x0000 }, + { 38, 0x006c, 0x0400004c, 0x06, 0x00, 0x0000 }, + { 38, 0x006c, 0x0400004c, 0x07, 0x00, 0x0000 }, + { 38, 0x006c, 0x0800004c, 0x08, 0x00, 0x0000 }, + { 38, 0x006c, 0x0800004c, 0x09, 0x00, 0x0000 }, + { 38, 0x006c, 0x0800004c, 0x0a, 0x00, 0x0000 }, + { 38, 0x006c, 0x0800004c, 0x0b, 0x00, 0x0000 }, + { 38, 0x006c, 0x0c00004c, 0x0c, 0x00, 0x0000 }, + { 38, 0x006c, 0x0c00004c, 0x0d, 0x00, 0x0000 }, + { 38, 0x006c, 0x0c00004c, 0x0e, 0x00, 0x0000 }, + { 38, 0x006c, 0x0c00004c, 0x0f, 0x00, 0x0000 }, + { 39, 0x003b, 0x0000003b, 0x00, 0x00, 0x0000 }, + { 39, 0x003a, 0x0000003a, 0x01, 0x00, 0x0000 }, + { 40, 0x0027, 0x00000027, 0x00, 0x00, 0x0000 }, + { 40, 0x0022, 0x00000022, 0x01, 0x00, 0x0000 }, + { 40, 0x0027, 0x01001251, 0x02, 0x01, 0x0000 }, + { 40, 0x0022, 0x01001257, 0x03, 0x01, 0x0000 }, + { 40, 0x0067, 0x04000047, 0x04, 0x00, 0x0000 }, + { 41, 0x0060, 0x00000060, 0x00, 0x00, 0x0000 }, + { 41, 0x007e, 0x0000007e, 0x01, 0x00, 0x0000 }, + { 41, 0x0060, 0x01001250, 0x02, 0x01, 0x0000 }, + { 41, 0x007e, 0x01001253, 0x03, 0x01, 0x0000 }, + { 42, 0xffff, 0x01000020, 0x00, 0x04, 0x0001 }, + { 43, 0x005c, 0x0000005c, 0x00, 0x00, 0x0000 }, + { 43, 0x007c, 0x0000007c, 0x01, 0x00, 0x0000 }, + { 43, 0x005c, 0x0400005c, 0x04, 0x00, 0x0000 }, + { 44, 0x007a, 0x0000005a, 0x00, 0x00, 0x0000 }, + { 44, 0x005a, 0x0000005a, 0x01, 0x00, 0x0000 }, + { 44, 0x007a, 0x0000005a, 0x02, 0x00, 0x0000 }, + { 44, 0x005a, 0x0000005a, 0x03, 0x00, 0x0000 }, + { 44, 0x007a, 0x0400005a, 0x04, 0x00, 0x0000 }, + { 44, 0x007a, 0x0400005a, 0x05, 0x00, 0x0000 }, + { 44, 0x007a, 0x0400005a, 0x06, 0x00, 0x0000 }, + { 44, 0x007a, 0x0400005a, 0x07, 0x00, 0x0000 }, + { 44, 0x007a, 0x0800005a, 0x08, 0x00, 0x0000 }, + { 44, 0x007a, 0x0800005a, 0x09, 0x00, 0x0000 }, + { 44, 0x007a, 0x0800005a, 0x0a, 0x00, 0x0000 }, + { 44, 0x007a, 0x0800005a, 0x0b, 0x00, 0x0000 }, + { 44, 0x007a, 0x0c00005a, 0x0c, 0x00, 0x0000 }, + { 44, 0x007a, 0x0c00005a, 0x0d, 0x00, 0x0000 }, + { 44, 0x007a, 0x0c00005a, 0x0e, 0x00, 0x0000 }, + { 44, 0x007a, 0x0c00005a, 0x0f, 0x00, 0x0000 }, + { 45, 0x0078, 0x00000058, 0x00, 0x00, 0x0000 }, + { 45, 0x0058, 0x00000058, 0x01, 0x00, 0x0000 }, + { 45, 0x0078, 0x00000058, 0x02, 0x00, 0x0000 }, + { 45, 0x0058, 0x00000058, 0x03, 0x00, 0x0000 }, + { 45, 0x0078, 0x04000058, 0x04, 0x00, 0x0000 }, + { 45, 0x0078, 0x04000058, 0x05, 0x00, 0x0000 }, + { 45, 0x0078, 0x04000058, 0x06, 0x00, 0x0000 }, + { 45, 0x0078, 0x04000058, 0x07, 0x00, 0x0000 }, + { 45, 0x0078, 0x08000058, 0x08, 0x00, 0x0000 }, + { 45, 0x0078, 0x08000058, 0x09, 0x00, 0x0000 }, + { 45, 0x0078, 0x08000058, 0x0a, 0x00, 0x0000 }, + { 45, 0x0078, 0x08000058, 0x0b, 0x00, 0x0000 }, + { 45, 0x0078, 0x0c000058, 0x0c, 0x00, 0x0000 }, + { 45, 0x0078, 0x0c000058, 0x0d, 0x00, 0x0000 }, + { 45, 0x0078, 0x0c000058, 0x0e, 0x00, 0x0000 }, + { 45, 0x0078, 0x0c000058, 0x0f, 0x00, 0x0000 }, + { 46, 0x0063, 0x00000043, 0x00, 0x00, 0x0000 }, + { 46, 0x0043, 0x00000043, 0x01, 0x00, 0x0000 }, + { 46, 0x0063, 0x00000043, 0x02, 0x00, 0x0000 }, + { 46, 0x0043, 0x00000043, 0x03, 0x00, 0x0000 }, + { 46, 0x0063, 0x04000043, 0x04, 0x00, 0x0000 }, + { 46, 0x0063, 0x04000043, 0x05, 0x00, 0x0000 }, + { 46, 0x0063, 0x04000043, 0x06, 0x00, 0x0000 }, + { 46, 0x0063, 0x04000043, 0x07, 0x00, 0x0000 }, + { 46, 0x0063, 0x08000043, 0x08, 0x00, 0x0000 }, + { 46, 0x0063, 0x08000043, 0x09, 0x00, 0x0000 }, + { 46, 0x0063, 0x08000043, 0x0a, 0x00, 0x0000 }, + { 46, 0x0063, 0x08000043, 0x0b, 0x00, 0x0000 }, + { 46, 0x0063, 0x0c000043, 0x0c, 0x00, 0x0000 }, + { 46, 0x0063, 0x0c000043, 0x0d, 0x00, 0x0000 }, + { 46, 0x0063, 0x0c000043, 0x0e, 0x00, 0x0000 }, + { 46, 0x0063, 0x0c000043, 0x0f, 0x00, 0x0000 }, + { 47, 0x0076, 0x00000056, 0x00, 0x00, 0x0000 }, + { 47, 0x0056, 0x00000056, 0x01, 0x00, 0x0000 }, + { 47, 0x0076, 0x00000056, 0x02, 0x00, 0x0000 }, + { 47, 0x0056, 0x00000056, 0x03, 0x00, 0x0000 }, + { 47, 0x0076, 0x04000056, 0x04, 0x00, 0x0000 }, + { 47, 0x0076, 0x04000056, 0x05, 0x00, 0x0000 }, + { 47, 0x0076, 0x04000056, 0x06, 0x00, 0x0000 }, + { 47, 0x0076, 0x04000056, 0x07, 0x00, 0x0000 }, + { 47, 0x0076, 0x08000056, 0x08, 0x00, 0x0000 }, + { 47, 0x0076, 0x08000056, 0x09, 0x00, 0x0000 }, + { 47, 0x0076, 0x08000056, 0x0a, 0x00, 0x0000 }, + { 47, 0x0076, 0x08000056, 0x0b, 0x00, 0x0000 }, + { 47, 0x0076, 0x0c000056, 0x0c, 0x00, 0x0000 }, + { 47, 0x0076, 0x0c000056, 0x0d, 0x00, 0x0000 }, + { 47, 0x0076, 0x0c000056, 0x0e, 0x00, 0x0000 }, + { 47, 0x0076, 0x0c000056, 0x0f, 0x00, 0x0000 }, + { 48, 0x0062, 0x00000042, 0x00, 0x00, 0x0000 }, + { 48, 0x0042, 0x00000042, 0x01, 0x00, 0x0000 }, + { 48, 0x0062, 0x00000042, 0x02, 0x00, 0x0000 }, + { 48, 0x0042, 0x00000042, 0x03, 0x00, 0x0000 }, + { 48, 0x0062, 0x04000042, 0x04, 0x00, 0x0000 }, + { 48, 0x0062, 0x04000042, 0x05, 0x00, 0x0000 }, + { 48, 0x0062, 0x04000042, 0x06, 0x00, 0x0000 }, + { 48, 0x0062, 0x04000042, 0x07, 0x00, 0x0000 }, + { 48, 0x0062, 0x08000042, 0x08, 0x00, 0x0000 }, + { 48, 0x0062, 0x08000042, 0x09, 0x00, 0x0000 }, + { 48, 0x0062, 0x08000042, 0x0a, 0x00, 0x0000 }, + { 48, 0x0062, 0x08000042, 0x0b, 0x00, 0x0000 }, + { 48, 0x0062, 0x0c000042, 0x0c, 0x00, 0x0000 }, + { 48, 0x0062, 0x0c000042, 0x0d, 0x00, 0x0000 }, + { 48, 0x0062, 0x0c000042, 0x0e, 0x00, 0x0000 }, + { 48, 0x0062, 0x0c000042, 0x0f, 0x00, 0x0000 }, + { 49, 0x006e, 0x0000004e, 0x00, 0x00, 0x0000 }, + { 49, 0x004e, 0x0000004e, 0x01, 0x00, 0x0000 }, + { 49, 0x006e, 0x0000004e, 0x02, 0x00, 0x0000 }, + { 49, 0x004e, 0x0000004e, 0x03, 0x00, 0x0000 }, + { 49, 0x006e, 0x0400004e, 0x04, 0x00, 0x0000 }, + { 49, 0x006e, 0x0400004e, 0x05, 0x00, 0x0000 }, + { 49, 0x006e, 0x0400004e, 0x06, 0x00, 0x0000 }, + { 49, 0x006e, 0x0400004e, 0x07, 0x00, 0x0000 }, + { 49, 0x006e, 0x0800004e, 0x08, 0x00, 0x0000 }, + { 49, 0x006e, 0x0800004e, 0x09, 0x00, 0x0000 }, + { 49, 0x006e, 0x0800004e, 0x0a, 0x00, 0x0000 }, + { 49, 0x006e, 0x0800004e, 0x0b, 0x00, 0x0000 }, + { 49, 0x006e, 0x0c00004e, 0x0c, 0x00, 0x0000 }, + { 49, 0x006e, 0x0c00004e, 0x0d, 0x00, 0x0000 }, + { 49, 0x006e, 0x0c00004e, 0x0e, 0x00, 0x0000 }, + { 49, 0x006e, 0x0c00004e, 0x0f, 0x00, 0x0000 }, + { 50, 0x006d, 0x0000004d, 0x00, 0x00, 0x0000 }, + { 50, 0x004d, 0x0000004d, 0x01, 0x00, 0x0000 }, + { 50, 0x006d, 0x0000004d, 0x02, 0x00, 0x0000 }, + { 50, 0x004d, 0x0000004d, 0x03, 0x00, 0x0000 }, + { 50, 0x006d, 0x0400004d, 0x04, 0x00, 0x0000 }, + { 50, 0x006d, 0x0400004d, 0x05, 0x00, 0x0000 }, + { 50, 0x006d, 0x0400004d, 0x06, 0x00, 0x0000 }, + { 50, 0x006d, 0x0400004d, 0x07, 0x00, 0x0000 }, + { 50, 0x006d, 0x0800004d, 0x08, 0x00, 0x0000 }, + { 50, 0x006d, 0x0800004d, 0x09, 0x00, 0x0000 }, + { 50, 0x006d, 0x0800004d, 0x0a, 0x00, 0x0000 }, + { 50, 0x006d, 0x0800004d, 0x0b, 0x00, 0x0000 }, + { 50, 0x006d, 0x0c00004d, 0x0c, 0x00, 0x0000 }, + { 50, 0x006d, 0x0c00004d, 0x0d, 0x00, 0x0000 }, + { 50, 0x006d, 0x0c00004d, 0x0e, 0x00, 0x0000 }, + { 50, 0x006d, 0x0c00004d, 0x0f, 0x00, 0x0000 }, + { 51, 0x002c, 0x0000002c, 0x00, 0x00, 0x0000 }, + { 51, 0x003c, 0x0000003c, 0x01, 0x00, 0x0000 }, + { 51, 0x002c, 0x0100125b, 0x02, 0x01, 0x0000 }, + { 52, 0x002e, 0x0000002e, 0x00, 0x00, 0x0000 }, + { 52, 0x003e, 0x0000003e, 0x01, 0x00, 0x0000 }, + { 52, 0xffff, 0x01001120, 0x02, 0x00, 0x0000 }, + { 53, 0x002f, 0x0000002f, 0x00, 0x00, 0x0000 }, + { 53, 0x003f, 0x0000003f, 0x01, 0x00, 0x0000 }, + { 53, 0xffff, 0x01000003, 0x04, 0x00, 0x0000 }, + { 54, 0xffff, 0x01000020, 0x00, 0x04, 0x0001 }, + { 55, 0x002a, 0x2000002a, 0x00, 0x00, 0x0000 }, + { 56, 0xffff, 0x01000023, 0x00, 0x04, 0x0008 }, + { 57, 0x0020, 0x00000020, 0x00, 0x00, 0x0000 }, + { 58, 0xffff, 0x01000024, 0x00, 0x00, 0x0000 }, + { 59, 0xffff, 0x01000030, 0x00, 0x00, 0x0000 }, + { 59, 0xffff, 0x0100003c, 0x01, 0x00, 0x0000 }, + { 59, 0xffff, 0x01000048, 0x04, 0x00, 0x0000 }, + { 59, 0xffff, 0x01000000, 0x0c, 0x08, 0x0100 }, + { 60, 0xffff, 0x01000031, 0x00, 0x00, 0x0000 }, + { 60, 0xffff, 0x0100003d, 0x01, 0x00, 0x0000 }, + { 60, 0xffff, 0x01000049, 0x04, 0x00, 0x0000 }, + { 60, 0xffff, 0x01000000, 0x0c, 0x08, 0x0101 }, + { 61, 0xffff, 0x01000032, 0x00, 0x00, 0x0000 }, + { 61, 0xffff, 0x0100003e, 0x01, 0x00, 0x0000 }, + { 61, 0xffff, 0x0100004a, 0x04, 0x00, 0x0000 }, + { 61, 0xffff, 0x01000000, 0x0c, 0x08, 0x0102 }, + { 62, 0xffff, 0x01000033, 0x00, 0x00, 0x0000 }, + { 62, 0xffff, 0x0100003f, 0x01, 0x00, 0x0000 }, + { 62, 0xffff, 0x0100004b, 0x04, 0x00, 0x0000 }, + { 62, 0xffff, 0x01000000, 0x0c, 0x08, 0x0103 }, + { 63, 0xffff, 0x01000034, 0x00, 0x00, 0x0000 }, + { 63, 0xffff, 0x01000040, 0x01, 0x00, 0x0000 }, + { 63, 0xffff, 0x0100004c, 0x04, 0x00, 0x0000 }, + { 63, 0xffff, 0x01000000, 0x0c, 0x08, 0x0104 }, + { 64, 0xffff, 0x01000035, 0x00, 0x00, 0x0000 }, + { 64, 0xffff, 0x01000041, 0x01, 0x00, 0x0000 }, + { 64, 0xffff, 0x0100004d, 0x04, 0x00, 0x0000 }, + { 64, 0xffff, 0x01000000, 0x0c, 0x08, 0x0105 }, + { 65, 0xffff, 0x01000036, 0x00, 0x00, 0x0000 }, + { 65, 0xffff, 0x01000042, 0x01, 0x00, 0x0000 }, + { 65, 0xffff, 0x0100004e, 0x04, 0x00, 0x0000 }, + { 65, 0xffff, 0x01000000, 0x0c, 0x08, 0x0106 }, + { 66, 0xffff, 0x01000037, 0x00, 0x00, 0x0000 }, + { 66, 0xffff, 0x01000043, 0x01, 0x00, 0x0000 }, + { 66, 0xffff, 0x0100004f, 0x04, 0x00, 0x0000 }, + { 66, 0xffff, 0x01000000, 0x0c, 0x08, 0x0107 }, + { 67, 0xffff, 0x01000038, 0x00, 0x00, 0x0000 }, + { 67, 0xffff, 0x01000044, 0x01, 0x00, 0x0000 }, + { 67, 0xffff, 0x01000050, 0x04, 0x00, 0x0000 }, + { 67, 0xffff, 0x01000000, 0x0c, 0x08, 0x0108 }, + { 68, 0xffff, 0x01000039, 0x00, 0x00, 0x0000 }, + { 68, 0xffff, 0x01000045, 0x01, 0x00, 0x0000 }, + { 68, 0xffff, 0x01000051, 0x04, 0x00, 0x0000 }, + { 68, 0xffff, 0x01000000, 0x0c, 0x08, 0x0109 }, + { 69, 0xffff, 0x01000025, 0x00, 0x00, 0x0000 }, + { 70, 0xffff, 0x01000026, 0x00, 0x00, 0x0000 }, + { 70, 0xffff, 0x01000026, 0x08, 0x00, 0x0000 }, + { 71, 0x0037, 0x20000037, 0x00, 0x00, 0x0000 }, + { 72, 0x0038, 0x20000038, 0x00, 0x00, 0x0000 }, + { 73, 0x0039, 0x20000039, 0x00, 0x00, 0x0000 }, + { 74, 0x002d, 0x2000002d, 0x00, 0x00, 0x0000 }, + { 75, 0x0034, 0x20000034, 0x00, 0x00, 0x0000 }, + { 76, 0x0035, 0x20000035, 0x00, 0x00, 0x0000 }, + { 77, 0x0036, 0x20000036, 0x00, 0x00, 0x0000 }, + { 78, 0x002b, 0x2000002b, 0x00, 0x00, 0x0000 }, + { 79, 0x0031, 0x20000031, 0x00, 0x00, 0x0000 }, + { 80, 0x0032, 0x20000032, 0x00, 0x00, 0x0000 }, + { 81, 0x0033, 0x20000033, 0x00, 0x00, 0x0000 }, + { 82, 0x0030, 0x20000030, 0x00, 0x00, 0x0000 }, + { 83, 0x002e, 0x2000002e, 0x00, 0x00, 0x0000 }, + { 83, 0xffff, 0x01000000, 0x06, 0x08, 0x0200 }, + { 83, 0xffff, 0x01000000, 0x0c, 0x08, 0x0200 }, + { 86, 0x003c, 0x0000003c, 0x00, 0x00, 0x0000 }, + { 86, 0x003e, 0x0000003e, 0x01, 0x00, 0x0000 }, + { 86, 0x007c, 0x0000007c, 0x02, 0x00, 0x0000 }, + { 87, 0xffff, 0x0100003a, 0x00, 0x00, 0x0000 }, + { 87, 0xffff, 0x01000046, 0x01, 0x00, 0x0000 }, + { 87, 0xffff, 0x01000052, 0x04, 0x00, 0x0000 }, + { 87, 0xffff, 0x01000000, 0x0c, 0x08, 0x010a }, + { 88, 0xffff, 0x0100003b, 0x00, 0x00, 0x0000 }, + { 88, 0xffff, 0x01000047, 0x01, 0x00, 0x0000 }, + { 88, 0xffff, 0x01000000, 0x0c, 0x08, 0x010b }, + { 96, 0xffff, 0x21000005, 0x00, 0x00, 0x0000 }, + { 97, 0xffff, 0x01000021, 0x00, 0x04, 0x0004 }, + { 98, 0x002f, 0x2000002f, 0x00, 0x00, 0x0000 }, + { 99, 0x005c, 0x0400005c, 0x00, 0x00, 0x0000 }, + { 100, 0xffff, 0x01001103, 0x00, 0x04, 0x0002 }, + { 102, 0xffff, 0x01000010, 0x00, 0x00, 0x0000 }, + { 103, 0xffff, 0x01000013, 0x00, 0x00, 0x0000 }, + { 104, 0xffff, 0x01000016, 0x00, 0x00, 0x0000 }, + { 105, 0xffff, 0x01000012, 0x00, 0x00, 0x0000 }, + { 105, 0xffff, 0x01000000, 0x0c, 0x08, 0x0180 }, + { 106, 0xffff, 0x01000014, 0x00, 0x00, 0x0000 }, + { 106, 0xffff, 0x01000000, 0x0c, 0x08, 0x0181 }, + { 107, 0xffff, 0x01000011, 0x00, 0x00, 0x0000 }, + { 108, 0xffff, 0x01000015, 0x00, 0x00, 0x0000 }, + { 109, 0xffff, 0x01000017, 0x00, 0x00, 0x0000 }, + { 110, 0xffff, 0x01000006, 0x00, 0x00, 0x0000 }, + { 111, 0xffff, 0x01000007, 0x00, 0x00, 0x0000 }, + { 111, 0xffff, 0x01000000, 0x06, 0x08, 0x0200 }, + { 111, 0xffff, 0x01000000, 0x0c, 0x08, 0x0200 }, + { 119, 0xffff, 0x01000008, 0x00, 0x00, 0x0000 }, +}; + +const QEvdevKeyboardMap::Composing QEvdevKeyboardHandler::s_keycompose_default[] = { + { 0x0060, 0x0041, 0x00c0 }, + { 0x0060, 0x0061, 0x00e0 }, + { 0x0027, 0x0041, 0x00c1 }, + { 0x0027, 0x0061, 0x00e1 }, + { 0x005e, 0x0041, 0x00c2 }, + { 0x005e, 0x0061, 0x00e2 }, + { 0x007e, 0x0041, 0x00c3 }, + { 0x007e, 0x0061, 0x00e3 }, + { 0x0022, 0x0041, 0x00c4 }, + { 0x0022, 0x0061, 0x00e4 }, + { 0x002d, 0x0061, 0x00aa }, + { 0x002d, 0x0041, 0x00aa }, + { 0x004f, 0x0041, 0x00c5 }, + { 0x006f, 0x0061, 0x00e5 }, + { 0x0030, 0x0041, 0x00c5 }, + { 0x0030, 0x0061, 0x00e5 }, + { 0x0041, 0x0041, 0x00c5 }, + { 0x0061, 0x0061, 0x00e5 }, + { 0x00b0, 0x0041, 0x00c5 }, + { 0x00b0, 0x0061, 0x00e5 }, + { 0x0041, 0x0045, 0x00c6 }, + { 0x0061, 0x0065, 0x00e6 }, + { 0x002c, 0x0043, 0x00c7 }, + { 0x002c, 0x0063, 0x00e7 }, + { 0x005e, 0x0043, 0x00c7 }, + { 0x005e, 0x0063, 0x00e7 }, + { 0x0060, 0x0045, 0x00c8 }, + { 0x0060, 0x0065, 0x00e8 }, + { 0x0027, 0x0045, 0x00c9 }, + { 0x0027, 0x0065, 0x00e9 }, + { 0x005e, 0x0045, 0x00ca }, + { 0x005e, 0x0065, 0x00ea }, + { 0x0022, 0x0045, 0x00cb }, + { 0x0022, 0x0065, 0x00eb }, + { 0x0060, 0x0049, 0x00cc }, + { 0x0060, 0x0069, 0x00ec }, + { 0x0027, 0x0049, 0x00cd }, + { 0x0027, 0x0069, 0x00ed }, + { 0x005e, 0x0049, 0x00ce }, + { 0x005e, 0x0069, 0x00ee }, + { 0x0022, 0x0049, 0x00cf }, + { 0x0022, 0x0069, 0x00ef }, + { 0x002d, 0x0044, 0x00d0 }, + { 0x002d, 0x0064, 0x00f0 }, + { 0x005e, 0x0044, 0x00d0 }, + { 0x005e, 0x0064, 0x00f0 }, + { 0x007e, 0x004e, 0x00d1 }, + { 0x007e, 0x006e, 0x00f1 }, + { 0x005e, 0x004e, 0x00d1 }, + { 0x005e, 0x006e, 0x00f1 }, + { 0x0060, 0x004f, 0x00d2 }, + { 0x0060, 0x006f, 0x00f2 }, + { 0x0027, 0x004f, 0x00d3 }, + { 0x0027, 0x006f, 0x00f3 }, + { 0x005e, 0x004f, 0x00d4 }, + { 0x005e, 0x006f, 0x00f4 }, + { 0x007e, 0x004f, 0x00d5 }, + { 0x007e, 0x006f, 0x00f5 }, + { 0x0022, 0x004f, 0x00d6 }, + { 0x0022, 0x006f, 0x00f6 }, + { 0x002f, 0x004f, 0x00d8 }, + { 0x002f, 0x006f, 0x00f8 }, + { 0x002d, 0x006f, 0x00ba }, + { 0x002d, 0x004f, 0x00ba }, + { 0x0060, 0x0055, 0x00d9 }, + { 0x0060, 0x0075, 0x00f9 }, + { 0x0027, 0x0055, 0x00da }, + { 0x0027, 0x0075, 0x00fa }, + { 0x005e, 0x0055, 0x00db }, + { 0x005e, 0x0075, 0x00fb }, + { 0x0022, 0x0055, 0x00dc }, + { 0x0022, 0x0075, 0x00fc }, + { 0x0027, 0x0059, 0x00dd }, + { 0x0027, 0x0079, 0x00fd }, + { 0x0054, 0x0048, 0x00de }, + { 0x0074, 0x0068, 0x00fe }, + { 0x0073, 0x0073, 0x00df }, + { 0x0022, 0x0079, 0x00ff }, + { 0x0073, 0x007a, 0x00df }, + { 0x006e, 0x006e, 0x00f1 }, + { 0x006e, 0x0068, 0x00f1 }, + { 0x004e, 0x0059, 0x00d1 }, + { 0x004e, 0x004e, 0x00d1 }, + { 0x004e, 0x0048, 0x00d1 }, + { 0x004e, 0x0079, 0x00d1 }, + { 0x004e, 0x006e, 0x00d1 }, + { 0x004e, 0x0068, 0x00d1 }, + { 0x002d, 0x004c, 0x00a3 }, + { 0x003c, 0x003c, 0x00ab }, + { 0x003e, 0x003e, 0x00bb }, + { 0x003f, 0x003f, 0x00bf }, + { 0x005e, 0x003f, 0x00bf }, + { 0x0021, 0x0021, 0x00a1 }, + { 0x005e, 0x0021, 0x00a1 }, + { 0x005e, 0x0031, 0x00b9 }, + { 0x005e, 0x0032, 0x00b2 }, + { 0x005e, 0x0033, 0x00b3 }, + { 0x002b, 0x002d, 0x00b1 }, + { 0x0063, 0x003d, 0x00a2 }, + { 0x0063, 0x002f, 0x00a2 }, + { 0x002f, 0x0063, 0x00a2 }, + { 0x002d, 0x0063, 0x00a2 }, + { 0x002d, 0x0043, 0x00a2 }, + { 0x004c, 0x003d, 0x00a3 }, + { 0x002d, 0x004c, 0x00a3 }, + { 0x002d, 0x006c, 0x00a3 }, + { 0x005e, 0x002a, 0x00d7 }, + { 0x005e, 0x0078, 0x00d7 }, + { 0x0078, 0x0078, 0x00d7 }, + { 0x005e, 0x002e, 0x00b7 }, + { 0x002e, 0x002e, 0x00b7 }, + { 0x005e, 0x002f, 0x00f7 }, + { 0x005e, 0x003a, 0x00f7 }, + { 0x002d, 0x003a, 0x00f7 }, + { 0x003a, 0x002d, 0x00f7 }, + { 0x0059, 0x003d, 0x00a5 }, + { 0x002d, 0x0059, 0x00a5 }, + { 0x002d, 0x006c, 0x00a5 }, + { 0x0028, 0x0063, 0x00a9 }, + { 0x0022, 0x0063, 0x00a9 }, + { 0x002d, 0x0061, 0x00aa }, + { 0x002d, 0x0041, 0x00aa }, + { 0x002d, 0x006f, 0x00ba }, + { 0x002d, 0x004f, 0x00ba }, + { 0x0028, 0x0072, 0x00ae }, + { 0x0022, 0x0072, 0x00ae }, + { 0x006d, 0x0075, 0x00b5 }, + { 0x0031, 0x0034, 0x0152 }, + { 0x0031, 0x0032, 0x0153 }, + { 0x0033, 0x0034, 0x0178 }, + { 0x0065, 0x003d, 0x20ac }, + { 0x002d, 0x0065, 0x20ac }, + { 0x002d, 0x0045, 0x20ac }, + { 0x0076, 0x0053, 0x0160 }, + { 0x005e, 0x0053, 0x0160 }, + { 0x0076, 0x0073, 0x0161 }, + { 0x005e, 0x0073, 0x0161 }, + { 0x0076, 0x005a, 0x017d }, + { 0x005e, 0x005a, 0x017d }, + { 0x0076, 0x007a, 0x017e }, + { 0x005e, 0x007a, 0x017e }, + { 0x004f, 0x0045, 0x0152 }, + { 0x004f, 0x0065, 0x0152 }, + { 0x006f, 0x0065, 0x0153 }, + { 0x0022, 0x0059, 0x0178 }, + { 0x0069, 0x006a, 0x00ff }, + { 0x0049, 0x004a, 0x0178 }, +}; + +#endif // QEVDEVKEYBOARDHANDLER_DEFAULTMAP_H diff --git a/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.cpp new file mode 100644 index 00000000000..f9237e33251 --- /dev/null +++ b/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.cpp @@ -0,0 +1,490 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui 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 "qevdevkeyboardhandler.h" + +#include + +#include +#include +#include +#include +#include + +#include + +//#define QT_QPA_KEYMAP_DEBUG + +#ifdef QT_QPA_KEYMAP_DEBUG +#include +#endif + +QT_BEGIN_NAMESPACE + +// simple builtin US keymap +#include "qevdevkeyboard_defaultmap.h" + +QEvdevKeyboardHandler::QEvdevKeyboardHandler(int deviceDescriptor, const QString &device, bool disableZap, bool enableCompose, const QString &keymapFile) + : m_fd(deviceDescriptor), m_device(device), + m_modifiers(0), m_composing(0), m_dead_unicode(0xffff), + m_no_zap(disableZap), m_do_compose(enableCompose), + m_keymap(0), m_keymap_size(0), m_keycompose(0), m_keycompose_size(0) +{ +#ifdef QT_QPA_KEYMAP_DEBUG + qWarning() << "Create keyboard handler with for device" << device; +#endif + + setObjectName(QLatin1String("LinuxInput Keyboard Handler")); + + memset(m_locks, 0, sizeof(m_locks)); + + if (keymapFile.isEmpty() || !loadKeymap(keymapFile)) + unloadKeymap(); + + // socket notifier for events on the keyboard device + QSocketNotifier *notifier; + notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); + connect(notifier, SIGNAL(activated(int)), this, SLOT(readKeycode())); +} + +QEvdevKeyboardHandler::~QEvdevKeyboardHandler() +{ + unloadKeymap(); + + if (m_fd >= 0) + qt_safe_close(m_fd); +} + +QEvdevKeyboardHandler *QEvdevKeyboardHandler::createLinuxInputKeyboardHandler(const QString &key, const QString &specification) +{ +#ifdef QT_QPA_KEYMAP_DEBUG + qWarning() << "Try to create keyboard handler with" << key << specification; +#else + Q_UNUSED(key) +#endif + + QString keymapFile; + QString device = "/dev/input/event0"; + int repeatDelay = 400; + int repeatRate = 80; + bool disableZap = false; + bool enableCompose = false; + + QStringList args = specification.split(QLatin1Char(':')); + foreach (const QString &arg, args) { + if (arg.startsWith(QLatin1String("keymap="))) + keymapFile = arg.mid(7); + else if (arg == QLatin1String("disable-zap")) + disableZap = true; + else if (arg == QLatin1String("enable-compose")) + enableCompose = true; + else if (arg.startsWith(QLatin1String("repeat-delay="))) + repeatDelay = arg.mid(13).toInt(); + else if (arg.startsWith(QLatin1String("repeat-rate="))) + repeatRate = arg.mid(12).toInt(); + else if (arg.startsWith(QLatin1String("/dev/"))) + device = arg; + } + +#ifdef QT_QPA_KEYMAP_DEBUG + qWarning() << "Opening keyboard at" << device; +#endif + + int fd; + fd = qt_safe_open(device.toLocal8Bit().constData(), O_RDWR, 0); + if (fd >= 0) { + if (repeatDelay > 0 && repeatRate > 0) { + int kbdrep[2] = { repeatDelay, repeatRate }; + ::ioctl(fd, EVIOCSREP, kbdrep); + } + + return new QEvdevKeyboardHandler(fd, device, disableZap, enableCompose, keymapFile); + } else { + qWarning("Cannot open keyboard input device '%s': %s", qPrintable(device), strerror(errno)); + return 0; + } +} + +void QEvdevKeyboardHandler::switchLed(int led, bool state) +{ +#ifdef QT_QPA_KEYMAP_DEBUG + qWarning() << "switchLed" << led << state; +#endif + + struct ::input_event led_ie; + ::gettimeofday(&led_ie.time, 0); + led_ie.type = EV_LED; + led_ie.code = led; + led_ie.value = state; + + qt_safe_write(m_fd, &led_ie, sizeof(led_ie)); +} + +void QEvdevKeyboardHandler::readKeycode() +{ +#ifdef QT_QPA_KEYMAP_DEBUG + qWarning() << "Read new keycode on" << m_device; +#endif + + struct ::input_event buffer[32]; + int n = 0; + + forever { + n = qt_safe_read(m_fd, reinterpret_cast(buffer) + n, sizeof(buffer) - n); + + if (n == 0) { + qWarning("Got EOF from the input device."); + return; + } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) { + qWarning("Could not read from input device: %s", strerror(errno)); + return; + } else if (n % sizeof(buffer[0]) == 0) { + break; + } + } + + n /= sizeof(buffer[0]); + + for (int i = 0; i < n; ++i) { + if (buffer[i].type != EV_KEY) + continue; + + quint16 code = buffer[i].code; + qint32 value = buffer[i].value; + + QEvdevKeyboardHandler::KeycodeAction ka; + ka = processKeycode(code, value != 0, value == 2); + + switch (ka) { + case QEvdevKeyboardHandler::CapsLockOn: + case QEvdevKeyboardHandler::CapsLockOff: + switchLed(LED_CAPSL, ka == QEvdevKeyboardHandler::CapsLockOn); + break; + + case QEvdevKeyboardHandler::NumLockOn: + case QEvdevKeyboardHandler::NumLockOff: + switchLed(LED_NUML, ka == QEvdevKeyboardHandler::NumLockOn); + break; + + case QEvdevKeyboardHandler::ScrollLockOn: + case QEvdevKeyboardHandler::ScrollLockOff: + switchLed(LED_SCROLLL, ka == QEvdevKeyboardHandler::ScrollLockOn); + break; + + default: + // ignore console switching and reboot + break; + } + } +} + +void QEvdevKeyboardHandler::processKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat) +{ + QWindowSystemInterface::handleKeyEvent(0, ( isPress ? QEvent::KeyPress : QEvent::KeyRelease ), keycode, modifiers, QString( unicode ), autoRepeat ); +} + +QEvdevKeyboardHandler::KeycodeAction QEvdevKeyboardHandler::processKeycode(quint16 keycode, bool pressed, bool autorepeat) +{ + KeycodeAction result = None; + bool first_press = pressed && !autorepeat; + + const QEvdevKeyboardMap::Mapping *map_plain = 0; + const QEvdevKeyboardMap::Mapping *map_withmod = 0; + + // get a specific and plain mapping for the keycode and the current modifiers + for (int i = 0; i < m_keymap_size && !(map_plain && map_withmod); ++i) { + const QEvdevKeyboardMap::Mapping *m = m_keymap + i; + if (m->keycode == keycode) { + if (m->modifiers == 0) + map_plain = m; + + quint8 testmods = m_modifiers; + if (m_locks[0] /*CapsLock*/ && (m->flags & QEvdevKeyboardMap::IsLetter)) + testmods ^= QEvdevKeyboardMap::ModShift; + if (m->modifiers == testmods) + map_withmod = m; + } + } + +#ifdef QT_QPA_KEYMAP_DEBUG + qWarning("Processing key event: keycode=%3d, modifiers=%02x pressed=%d, autorepeat=%d | plain=%d, withmod=%d, size=%d", \ + keycode, m_modifiers, pressed ? 1 : 0, autorepeat ? 1 : 0, \ + map_plain ? map_plain - m_keymap : -1, \ + map_withmod ? map_withmod - m_keymap : -1, \ + m_keymap_size); +#endif + + const QEvdevKeyboardMap::Mapping *it = map_withmod ? map_withmod : map_plain; + + if (!it) { +#ifdef QT_QPA_KEYMAP_DEBUG + // we couldn't even find a plain mapping + qWarning("Could not find a suitable mapping for keycode: %3d, modifiers: %02x", keycode, m_modifiers); +#endif + return result; + } + + bool skip = false; + quint16 unicode = it->unicode; + quint32 qtcode = it->qtcode; + + if ((it->flags & QEvdevKeyboardMap::IsModifier) && it->special) { + // this is a modifier, i.e. Shift, Alt, ... + if (pressed) + m_modifiers |= quint8(it->special); + else + m_modifiers &= ~quint8(it->special); + } else if (qtcode >= Qt::Key_CapsLock && qtcode <= Qt::Key_ScrollLock) { + // (Caps|Num|Scroll)Lock + if (first_press) { + quint8 &lock = m_locks[qtcode - Qt::Key_CapsLock]; + lock ^= 1; + + switch (qtcode) { + case Qt::Key_CapsLock : result = lock ? CapsLockOn : CapsLockOff; m_modifiers ^= QEvdevKeyboardMap::ModShift; break; + case Qt::Key_NumLock : result = lock ? NumLockOn : NumLockOff; break; + case Qt::Key_ScrollLock: result = lock ? ScrollLockOn : ScrollLockOff; break; + default : break; + } + } + } else if ((it->flags & QEvdevKeyboardMap::IsSystem) && it->special && first_press) { + switch (it->special) { + case QEvdevKeyboardMap::SystemReboot: + result = Reboot; + break; + + case QEvdevKeyboardMap::SystemZap: + if (!m_no_zap) + qApp->quit(); + break; + + case QEvdevKeyboardMap::SystemConsolePrevious: + result = PreviousConsole; + break; + + case QEvdevKeyboardMap::SystemConsoleNext: + result = NextConsole; + break; + + default: + if (it->special >= QEvdevKeyboardMap::SystemConsoleFirst && + it->special <= QEvdevKeyboardMap::SystemConsoleLast) { + result = KeycodeAction(SwitchConsoleFirst + ((it->special & QEvdevKeyboardMap::SystemConsoleMask) & SwitchConsoleMask)); + } + break; + } + + skip = true; // no need to tell Qt about it + } else if ((qtcode == Qt::Key_Multi_key) && m_do_compose) { + // the Compose key was pressed + if (first_press) + m_composing = 2; + skip = true; + } else if ((it->flags & QEvdevKeyboardMap::IsDead) && m_do_compose) { + // a Dead key was pressed + if (first_press && m_composing == 1 && m_dead_unicode == unicode) { // twice + m_composing = 0; + qtcode = Qt::Key_unknown; // otherwise it would be Qt::Key_Dead... + } else if (first_press && unicode != 0xffff) { + m_dead_unicode = unicode; + m_composing = 1; + skip = true; + } else { + skip = true; + } + } + + if (!skip) { + // a normal key was pressed + const int modmask = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier | Qt::KeypadModifier; + + // we couldn't find a specific mapping for the current modifiers, + // or that mapping didn't have special modifiers: + // so just report the plain mapping with additional modifiers. + if ((it == map_plain && it != map_withmod) || + (map_withmod && !(map_withmod->qtcode & modmask))) { + qtcode |= QEvdevKeyboardHandler::toQtModifiers(m_modifiers); + } + + if (m_composing == 2 && first_press && !(it->flags & QEvdevKeyboardMap::IsModifier)) { + // the last key press was the Compose key + if (unicode != 0xffff) { + int idx = 0; + // check if this code is in the compose table at all + for ( ; idx < m_keycompose_size; ++idx) { + if (m_keycompose[idx].first == unicode) + break; + } + if (idx < m_keycompose_size) { + // found it -> simulate a Dead key press + m_dead_unicode = unicode; + unicode = 0xffff; + m_composing = 1; + skip = true; + } else { + m_composing = 0; + } + } else { + m_composing = 0; + } + } else if (m_composing == 1 && first_press && !(it->flags & QEvdevKeyboardMap::IsModifier)) { + // the last key press was a Dead key + bool valid = false; + if (unicode != 0xffff) { + int idx = 0; + // check if this code is in the compose table at all + for ( ; idx < m_keycompose_size; ++idx) { + if (m_keycompose[idx].first == m_dead_unicode && m_keycompose[idx].second == unicode) + break; + } + if (idx < m_keycompose_size) { + quint16 composed = m_keycompose[idx].result; + if (composed != 0xffff) { + unicode = composed; + qtcode = Qt::Key_unknown; + valid = true; + } + } + } + if (!valid) { + unicode = m_dead_unicode; + qtcode = Qt::Key_unknown; + } + m_composing = 0; + } + + if (!skip) { +#ifdef QT_QPA_KEYMAP_DEBUG + qWarning("Processing: uni=%04x, qt=%08x, qtmod=%08x", unicode, qtcode & ~modmask, (qtcode & modmask)); +#endif + + // send the result to the server + processKeyEvent(unicode, qtcode & ~modmask, Qt::KeyboardModifiers(qtcode & modmask), pressed, autorepeat); + } + } + return result; +} + +void QEvdevKeyboardHandler::unloadKeymap() +{ +#ifdef QT_QPA_KEYMAP_DEBUG + qWarning() << "Unload current keymap and restore built-in"; +#endif + + if (m_keymap && m_keymap != s_keymap_default) + delete [] m_keymap; + if (m_keycompose && m_keycompose != s_keycompose_default) + delete [] m_keycompose; + + m_keymap = s_keymap_default; + m_keymap_size = sizeof(s_keymap_default) / sizeof(s_keymap_default[0]); + m_keycompose = s_keycompose_default; + m_keycompose_size = sizeof(s_keycompose_default) / sizeof(s_keycompose_default[0]); + + // reset state, so we could switch keymaps at runtime + m_modifiers = 0; + memset(m_locks, 0, sizeof(m_locks)); + m_composing = 0; + m_dead_unicode = 0xffff; +} + +bool QEvdevKeyboardHandler::loadKeymap(const QString &file) +{ +#ifdef QT_QPA_KEYMAP_DEBUG + qWarning() << "Load keymap" << file; +#endif + + QFile f(file); + + if (!f.open(QIODevice::ReadOnly)) { + qWarning("Could not open keymap file '%s'", qPrintable(file)); + return false; + } + + // .qmap files have a very simple structure: + // quint32 magic (QKeyboard::FileMagic) + // quint32 version (1) + // quint32 keymap_size (# of struct QKeyboard::Mappings) + // quint32 keycompose_size (# of struct QKeyboard::Composings) + // all QKeyboard::Mappings via QDataStream::operator(<<|>>) + // all QKeyboard::Composings via QDataStream::operator(<<|>>) + + quint32 qmap_magic, qmap_version, qmap_keymap_size, qmap_keycompose_size; + + QDataStream ds(&f); + + ds >> qmap_magic >> qmap_version >> qmap_keymap_size >> qmap_keycompose_size; + + if (ds.status() != QDataStream::Ok || qmap_magic != QEvdevKeyboardMap::FileMagic || qmap_version != 1 || qmap_keymap_size == 0) { + qWarning("'%s' is ot a valid.qmap keymap file.", qPrintable(file)); + return false; + } + + QEvdevKeyboardMap::Mapping *qmap_keymap = new QEvdevKeyboardMap::Mapping[qmap_keymap_size]; + QEvdevKeyboardMap::Composing *qmap_keycompose = qmap_keycompose_size ? new QEvdevKeyboardMap::Composing[qmap_keycompose_size] : 0; + + for (quint32 i = 0; i < qmap_keymap_size; ++i) + ds >> qmap_keymap[i]; + for (quint32 i = 0; i < qmap_keycompose_size; ++i) + ds >> qmap_keycompose[i]; + + if (ds.status() != QDataStream::Ok) { + delete [] qmap_keymap; + delete [] qmap_keycompose; + + qWarning("Keymap file '%s' can not be loaded.", qPrintable(file)); + return false; + } + + // unload currently active and clear state + unloadKeymap(); + + m_keymap = qmap_keymap; + m_keymap_size = qmap_keymap_size; + m_keycompose = qmap_keycompose; + m_keycompose_size = qmap_keycompose_size; + + m_do_compose = true; + + return true; +} + +QT_END_NAMESPACE diff --git a/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.h b/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.h new file mode 100644 index 00000000000..76b5c5703be --- /dev/null +++ b/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.h @@ -0,0 +1,202 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui 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 QEVDEVKEYBOARDHANDLER_H +#define QEVDEVKEYBOARDHANDLER_H + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QEvdevKeyboardMap { + const quint32 FileMagic = 0x514d4150; // 'QMAP' + + struct Mapping { + quint16 keycode; + quint16 unicode; + quint32 qtcode; + quint8 modifiers; + quint8 flags; + quint16 special; + + }; + + enum Flags { + IsDead = 0x01, + IsLetter = 0x02, + IsModifier = 0x04, + IsSystem = 0x08 + }; + + enum System { + SystemConsoleFirst = 0x0100, + SystemConsoleMask = 0x007f, + SystemConsoleLast = 0x017f, + SystemConsolePrevious = 0x0180, + SystemConsoleNext = 0x0181, + SystemReboot = 0x0200, + SystemZap = 0x0300 + }; + + struct Composing { + quint16 first; + quint16 second; + quint16 result; + }; + + enum Modifiers { + ModPlain = 0x00, + ModShift = 0x01, + ModAltGr = 0x02, + ModControl = 0x04, + ModAlt = 0x08, + ModShiftL = 0x10, + ModShiftR = 0x20, + ModCtrlL = 0x40, + ModCtrlR = 0x80 + // ModCapsShift = 0x100, // not supported! + }; +} + +inline QDataStream &operator>>(QDataStream &ds, QEvdevKeyboardMap::Mapping &m) +{ + return ds >> m.keycode >> m.unicode >> m.qtcode >> m.modifiers >> m.flags >> m.special; +} + +inline QDataStream &operator<<(QDataStream &ds, const QEvdevKeyboardMap::Mapping &m) +{ + return ds << m.keycode << m.unicode << m.qtcode << m.modifiers << m.flags << m.special; +} + +inline QDataStream &operator>>(QDataStream &ds, QEvdevKeyboardMap::Composing &c) +{ + return ds >> c.first >> c.second >> c.result; +} + +inline QDataStream &operator<<(QDataStream &ds, const QEvdevKeyboardMap::Composing &c) +{ + return ds << c.first << c.second << c.result; +} + + +class QEvdevKeyboardHandler : public QObject +{ + Q_OBJECT +public: + QEvdevKeyboardHandler(int deviceDescriptor, const QString &device, bool disableZap, bool enableCompose, const QString &keymapFile); + ~QEvdevKeyboardHandler(); + + enum KeycodeAction { + None = 0, + + CapsLockOff = 0x01000000, + CapsLockOn = 0x01000001, + NumLockOff = 0x02000000, + NumLockOn = 0x02000001, + ScrollLockOff = 0x03000000, + ScrollLockOn = 0x03000001, + + Reboot = 0x04000000, + + PreviousConsole = 0x05000000, + NextConsole = 0x05000001, + SwitchConsoleFirst = 0x06000000, + SwitchConsoleLast = 0x0600007f, + SwitchConsoleMask = 0x0000007f + }; + + static QEvdevKeyboardHandler *createLinuxInputKeyboardHandler(const QString &key, const QString &specification); + + static Qt::KeyboardModifiers toQtModifiers(quint8 mod) + { + Qt::KeyboardModifiers qtmod = Qt::NoModifier; + + if (mod & (QEvdevKeyboardMap::ModShift | QEvdevKeyboardMap::ModShiftL | QEvdevKeyboardMap::ModShiftR)) + qtmod |= Qt::ShiftModifier; + if (mod & (QEvdevKeyboardMap::ModControl | QEvdevKeyboardMap::ModCtrlL | QEvdevKeyboardMap::ModCtrlR)) + qtmod |= Qt::ControlModifier; + if (mod & QEvdevKeyboardMap::ModAlt) + qtmod |= Qt::AltModifier; + + return qtmod; + } + +private slots: + void readKeycode(); + KeycodeAction processKeycode(quint16 keycode, bool pressed, bool autorepeat); + +private: + void unloadKeymap(); + bool loadKeymap(const QString &file); + void processKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat); + void switchLed(int, bool); + + int m_fd; + QString m_device; + + // keymap handling + quint8 m_modifiers; + quint8 m_locks[3]; + int m_composing; + quint16 m_dead_unicode; + + bool m_no_zap; + bool m_do_compose; + + const QEvdevKeyboardMap::Mapping *m_keymap; + int m_keymap_size; + const QEvdevKeyboardMap::Composing *m_keycompose; + int m_keycompose_size; + + static const QEvdevKeyboardMap::Mapping s_keymap_default[]; + static const QEvdevKeyboardMap::Composing s_keycompose_default[]; +}; + + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QEVDEVKEYBOARDHANDLER_H diff --git a/src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.cpp b/src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.cpp new file mode 100644 index 00000000000..8769b704954 --- /dev/null +++ b/src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.cpp @@ -0,0 +1,250 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui 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 "qevdevkeyboardmanager.h" + +#include +#include +#include + +#include +#include + +//#define QT_QPA_KEYMAP_DEBUG + +QT_BEGIN_NAMESPACE + +QEvdevKeyboardManager::QEvdevKeyboardManager(const QString &key, const QString &specification) + : m_udev(0), m_udevMonitor(0), m_udevMonitorFileDescriptor(-1), m_udevSocketNotifier(0) +{ + Q_UNUSED(key); + + bool useUDev = false; + QStringList args = specification.split(QLatin1Char(':')); + QStringList devices; + + foreach (const QString &arg, args) { + if (arg.startsWith("udev") && !arg.contains("no")) { + useUDev = true; + } else if (arg.startsWith("/dev/")) { + // if device is specified try to use it + devices.append(arg); + args.removeAll(arg); + } + } + + m_spec = args.join(":"); + + // add all keyboards for devices specified in the argument list + foreach (const QString &device, devices) + addKeyboard(device); + + // no udev and no devices specified, try a fallback + if (!useUDev && devices.isEmpty()) { + addKeyboard(); + return; + } + + m_udev = udev_new(); + if (!m_udev) { + qWarning() << "Failed to read udev configuration. Try to open a keyboard without it"; + addKeyboard(); + } else { + // Look for already attached devices: + parseConnectedDevices(); + // Watch for device add/remove + startWatching(); + } +} + +QEvdevKeyboardManager::~QEvdevKeyboardManager() +{ + // cleanup udev related resources + stopWatching(); + if (m_udev) + udev_unref(m_udev); + + // cleanup all resources of connected keyboards + qDeleteAll(m_keyboards); + m_keyboards.clear(); +} + +void QEvdevKeyboardManager::addKeyboard(const QString &devnode) +{ + QString specification = m_spec; + QString deviceString = devnode; + + if (!deviceString.isEmpty()) { + specification.append(":"); + specification.append(deviceString); + } else { + deviceString = "default"; + } + +#ifdef QT_QPA_KEYMAP_DEBUG + qWarning() << "Adding keyboard at" << deviceString; +#endif + + QEvdevKeyboardHandler *keyboard; + keyboard = QEvdevKeyboardHandler::createLinuxInputKeyboardHandler("EvdevKeyboard", specification); + if (keyboard) + m_keyboards.insert(deviceString, keyboard); + else + qWarning() << "Failed to open keyboard"; +} + +void QEvdevKeyboardManager::removeKeyboard(const QString &devnode) +{ + if (m_keyboards.contains(devnode)) { +#ifdef QT_QPA_KEYMAP_DEBUG + qWarning() << "Removing keyboard at" << devnode; +#endif + QEvdevKeyboardHandler *keyboard = m_keyboards.value(devnode); + m_keyboards.remove(devnode); + delete keyboard; + } +} + +void QEvdevKeyboardManager::startWatching() +{ + m_udevMonitor = udev_monitor_new_from_netlink(m_udev, "udev"); + if (!m_udevMonitor) { +#ifdef QT_QPA_KEYMAP_DEBUG + qWarning("Unable to create an Udev monitor. No devices can be detected."); +#endif + return; + } + + udev_monitor_filter_add_match_subsystem_devtype(m_udevMonitor, "input", NULL); + udev_monitor_enable_receiving(m_udevMonitor); + m_udevMonitorFileDescriptor = udev_monitor_get_fd(m_udevMonitor); + + m_udevSocketNotifier = new QSocketNotifier(m_udevMonitorFileDescriptor, QSocketNotifier::Read, this); + connect(m_udevSocketNotifier, SIGNAL(activated(int)), this, SLOT(deviceDetected())); +} + +void QEvdevKeyboardManager::stopWatching() +{ + if (m_udevSocketNotifier) + delete m_udevSocketNotifier; + + if (m_udevMonitor) + udev_monitor_unref(m_udevMonitor); + + m_udevSocketNotifier = 0; + m_udevMonitor = 0; + m_udevMonitorFileDescriptor = 0; +} + +void QEvdevKeyboardManager::deviceDetected() +{ + if (!m_udevMonitor) + return; + + struct udev_device *dev; + dev = udev_monitor_receive_device(m_udevMonitor); + if (!dev) + return; + + if (qstrcmp(udev_device_get_action(dev), "add") == 0) { + checkDevice(dev); + } else { + // We can't determine what the device was, so we handle false positives outside of this class + QString str = udev_device_get_devnode(dev); + if (!str.isEmpty()) + removeKeyboard(str); + } + + udev_device_unref(dev); +} + +void QEvdevKeyboardManager::parseConnectedDevices() +{ + struct udev_enumerate *enumerate; + struct udev_list_entry *devices; + struct udev_list_entry *dev_list_entry; + struct udev_device *dev; + const char *str; + + enumerate = udev_enumerate_new(m_udev); + udev_enumerate_add_match_subsystem(enumerate, "input"); + udev_enumerate_scan_devices(enumerate); + devices = udev_enumerate_get_list_entry(enumerate); + + udev_list_entry_foreach(dev_list_entry, devices) { + str = udev_list_entry_get_name(dev_list_entry); + dev = udev_device_new_from_syspath(m_udev, str); + checkDevice(dev); + } + + udev_enumerate_unref(enumerate); +} + +void QEvdevKeyboardManager::checkDevice(udev_device *dev) +{ + const char *str; + QString devnode; + + str = udev_device_get_devnode(dev); + if (!str) + return; + + devnode = str; + + dev = udev_device_get_parent_with_subsystem_devtype(dev, "input", NULL); + if (!dev) + return; + + str = udev_device_get_sysattr_value(dev, "capabilities/key"); + QStringList val = QString(str).split(' ', QString::SkipEmptyParts); + + bool ok; + unsigned long long keys = val.last().toULongLong(&ok, 16); + if (!ok) + return; + + // Tests if the letter Q is valid for the device. We may want to alter this test, but it seems mostly reliable. + bool test = (keys >> KEY_Q) & 1; + if (test) { + addKeyboard(devnode); + return; + } +} diff --git a/src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.h b/src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.h new file mode 100644 index 00000000000..11892d12dca --- /dev/null +++ b/src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui 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 QEVDEVKEYBOARDMANAGER_H +#define QEVDEVKEYBOARDMANAGER_H + +#include "qevdevkeyboardhandler.h" + +#include +#include +#include + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QEvdevKeyboardManager : public QObject +{ + Q_OBJECT +public: + explicit QEvdevKeyboardManager(const QString &key, const QString &specification); + ~QEvdevKeyboardManager(); + +private slots: + void deviceDetected(); + +private: + void startWatching(); + void stopWatching(); + void parseConnectedDevices(); + void checkDevice(struct udev_device *dev); + + void addKeyboard(const QString &devnode = QString()); + void removeKeyboard(const QString &devnode); + + QString m_spec; + QHash m_keyboards; + + struct udev *m_udev; + struct udev_monitor *m_udevMonitor; + int m_udevMonitorFileDescriptor; + QSocketNotifier *m_udevSocketNotifier; +}; + +#endif // QEVDEVKEYBOARDMANAGER_H diff --git a/src/plugins/generic/generic.pro b/src/plugins/generic/generic.pro index c4c3f9229aa..06bc0091f48 100644 --- a/src/plugins/generic/generic.pro +++ b/src/plugins/generic/generic.pro @@ -4,6 +4,6 @@ linux-g++-maemo: SUBDIRS += meego contains(QT_CONFIG, evdev) { contains(QT_CONFIG, libudev) { - SUBDIRS += evdevmouse evdevtouch + SUBDIRS += evdevmouse evdevtouch evdevkeyboard } } From 10830e844683c75d96c024450b4b7a624d8d6d8f Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Fri, 10 Feb 2012 11:27:00 +0100 Subject: [PATCH 167/406] Fixed zlib build for WEC7. errno in zutil.c is leftover, and not used anymore -> removed. In gzguts.h qfunctions_wince.h are included. To use this header qglobal.h is needed. In qfunctions_wince.h a special define section is added for zlib. Task-number: QTBUG-22507 Change-Id: I78ec78d22e2930a03b349a47ab3a3ad077277c42 Reviewed-by: Miikka Heikkinen Reviewed-by: Friedemann Kleint --- src/3rdparty/zlib/gzguts.h | 9 +++++++-- src/3rdparty/zlib/zutil.c | 8 -------- src/corelib/kernel/qfunctions_wince.h | 10 ++++++++++ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/3rdparty/zlib/gzguts.h b/src/3rdparty/zlib/gzguts.h index c752b5763b6..26b4d37c1d2 100644 --- a/src/3rdparty/zlib/gzguts.h +++ b/src/3rdparty/zlib/gzguts.h @@ -32,7 +32,10 @@ # include #endif #if !defined(_WIN32_WCE) -#include +# include +#else +# include +# include #endif #ifdef NO_DEFLATE /* for compatibility with old definition */ @@ -40,7 +43,9 @@ #endif #ifdef _MSC_VER -# include +# if !defined(_WIN32_WCE) +# include +# endif # define vsnprintf _vsnprintf #endif diff --git a/src/3rdparty/zlib/zutil.c b/src/3rdparty/zlib/zutil.c index 898ed345b0e..3418c5999fd 100644 --- a/src/3rdparty/zlib/zutil.c +++ b/src/3rdparty/zlib/zutil.c @@ -136,14 +136,6 @@ const char * ZEXPORT zError(err) return ERR_MSG(err); } -#if defined(_WIN32_WCE) - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. - */ - int errno = 0; -#endif - #ifndef HAVE_MEMCPY void ZLIB_INTERNAL zmemcpy(dest, source, len) diff --git a/src/corelib/kernel/qfunctions_wince.h b/src/corelib/kernel/qfunctions_wince.h index f83dad0dde6..7cd8ea66a22 100644 --- a/src/corelib/kernel/qfunctions_wince.h +++ b/src/corelib/kernel/qfunctions_wince.h @@ -182,6 +182,16 @@ void qt_wince_rewind( FILE *stream ); int qt_wince___fileno(FILE *); FILE *qt_wince_tmpfile( void ); +//For zlib we need these helper functions, but they break the build when +//set globally, so just set them for zlib use +#ifdef ZLIB_H +#define open qt_wince_open +#define close qt_wince__close +#define lseek qt_wince__lseek +#define read qt_wince__read +#define write qt_wince__write +#endif + int qt_wince__mkdir(const char *dirname); int qt_wince__rmdir(const char *dirname); int qt_wince__access( const char *path, int pmode ); From 3791d3b0c2dab448b53720979b2375998d06e209 Mon Sep 17 00:00:00 2001 From: David Faure Date: Wed, 8 Feb 2012 22:17:03 +0100 Subject: [PATCH 168/406] Add QUrl::toDisplayString(), which is toString() without password. And fix documentation of toString() which said this was the method to use for displaying to humans, while this has never been true. Change-Id: Iff6df92e32b2517e1481d4992d80cae2d58da427 Reviewed-by: Oswald Buddenhagen Reviewed-by: Jonas Gastal Reviewed-by: Giuseppe D'Angelo Reviewed-by: Stephen Kelly --- src/corelib/io/qurl.cpp | 27 +++++++++++++++++++------ src/corelib/io/qurl.h | 1 + tests/auto/corelib/io/qurl/tst_qurl.cpp | 6 ++++++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index ecd154b1132..183e5706fa0 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -5679,9 +5679,8 @@ static QString toPrettyPercentEncoding(const QString &input, bool forFragment) } /*! - Returns the human-displayable string representation of the - URL. The output can be customized by passing flags with \a - options. + Returns a string representation of the URL. + The output can be customized by passing flags with \a options. The resulting QString can be passed back to a QUrl later on. @@ -5734,9 +5733,8 @@ QString QUrl::toString(FormattingOptions options) const } /*! - Returns the human-displayable string representation of the - URL. The output can be customized by passing flags with \a - options. + Returns a string representation of the URL. + The output can be customized by passing flags with \a options. The resulting QString can be passed back to a QUrl later on. @@ -5749,6 +5747,23 @@ QString QUrl::url(FormattingOptions options) const return toString(options); } +/*! + Returns a human-displayable string representation of the URL. + The output can be customized by passing flags with \a options. + The option RemovePassword is always enabled, since passwords + should never be shown back to users. + + The resulting QString can be passed back to a QUrl later on, + but any password that was present initially will be lost. + + \sa FormattingOptions, toEncoded(), toString() +*/ + +QString QUrl::toDisplayString(FormattingOptions options) const +{ + return toString(options | RemovePassword); +} + /*! Returns the encoded representation of the URL if it's valid; otherwise an empty QByteArray is returned. The output can be diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h index 1c3390bc3d7..3e5c62cd7c7 100644 --- a/src/corelib/io/qurl.h +++ b/src/corelib/io/qurl.h @@ -102,6 +102,7 @@ public: void setUrl(const QString &url, ParsingMode mode = TolerantMode); QString url(FormattingOptions options = None) const; QString toString(FormattingOptions options = None) const; + QString toDisplayString(FormattingOptions options = None) const; bool isValid() const; diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 611847852f4..e2831036df7 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -350,6 +350,8 @@ void tst_QUrl::setUrl() QVERIFY(url.authority().isEmpty()); QVERIFY(url.fragment().isEmpty()); QCOMPARE(url.port(), -1); + QCOMPARE(url.toString(), QString::fromLatin1("file:///")); + QCOMPARE(url.toDisplayString(), QString::fromLatin1("file:///")); } { @@ -363,6 +365,8 @@ void tst_QUrl::setUrl() QCOMPARE(url.host(), QString::fromLatin1("www.foo.bar")); QCOMPARE(url.authority(), QString::fromLatin1("www.foo.bar:80")); QCOMPARE(url.port(), 80); + QCOMPARE(url.toString(), QString::fromLatin1("http://www.foo.bar:80")); + QCOMPARE(url.toDisplayString(), QString::fromLatin1("http://www.foo.bar:80")); QUrl url2("//www1.foo.bar"); QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("http://www1.foo.bar")); @@ -379,6 +383,8 @@ void tst_QUrl::setUrl() QCOMPARE(url.host(), QString::fromLatin1("56::56:56:56:127.0.0.1")); QCOMPARE(url.authority(), QString::fromLatin1("user:pass@[56::56:56:56:127.0.0.1]:99")); QCOMPARE(url.port(), 99); + QCOMPARE(url.url(), QString::fromLatin1("http://user:pass@[56::56:56:56:127.0.0.1]:99")); + QCOMPARE(url.toDisplayString(), QString::fromLatin1("http://user@[56::56:56:56:127.0.0.1]:99")); } { From 8b7a9b4898c85e81d87cf642ec59ce85e917ee35 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Fri, 10 Feb 2012 11:32:43 +0100 Subject: [PATCH 169/406] Escape project file name in makefile rebuild rules. Change-Id: I5407c2477613119b5aea2d00eb88cc24d35788ad Reviewed-by: Oswald Buddenhagen --- qmake/generators/makefile.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 59e17b0beaf..b5954868217 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2496,10 +2496,10 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QListtarget << "-qmake_all: "; if(project->isEmpty("QMAKE_NOFORCE")) @@ -2508,10 +2508,10 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList Date: Sat, 11 Feb 2012 10:42:03 +0100 Subject: [PATCH 170/406] Implement QMAKE_SUBSTITUTES.config = verbatim. Change-Id: Ie0b333fa7fae2283e99e42f9cd7bab4e84991f40 Reviewed-by: Oswald Buddenhagen --- qmake/generators/makefile.cpp | 110 ++++++++++-------- .../tools/qmake/testdata/substitutes/copy.txt | 3 + .../tools/qmake/testdata/substitutes/test.pro | 5 +- tests/auto/tools/qmake/tst_qmake.cpp | 8 ++ 4 files changed, 76 insertions(+), 50 deletions(-) create mode 100644 tests/auto/tools/qmake/testdata/substitutes/copy.txt diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index b5954868217..dd098596e9c 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -498,62 +498,74 @@ MakefileGenerator::init() } outn = fileFixify(inn.left(inn.length()-3), qmake_getpwd(), Option::output_dir); } + + QString confign = subs.at(i) + ".config"; + bool verbatim = false; + if (v.contains(confign)) + verbatim = v[confign].contains(QLatin1String("verbatim")); + QFile in(inn); - if(in.open(QFile::ReadOnly)) { - QString contents; - QStack state; - enum { IN_CONDITION, MET_CONDITION, PENDING_CONDITION }; - for(int count = 1; !in.atEnd(); ++count) { - QString line = QString::fromUtf8(in.readLine()); - if(line.startsWith("!!IF ")) { - if(state.isEmpty() || state.top() == IN_CONDITION) { - QString test = line.mid(5, line.length()-(5+1)); - if(project->test(test)) - state.push(IN_CONDITION); - else - state.push(PENDING_CONDITION); - } else { - state.push(MET_CONDITION); - } - } else if(line.startsWith("!!ELIF ")) { - if(state.isEmpty()) { - warn_msg(WarnLogic, "(%s:%d): Unexpected else condition", - in.fileName().toLatin1().constData(), count); - } else if(state.top() == PENDING_CONDITION) { - QString test = line.mid(7, line.length()-(7+1)); - if(project->test(test)) { + if (in.open(QFile::ReadOnly)) { + QByteArray contentBytes; + if (verbatim) { + contentBytes = in.readAll(); + } else { + QString contents; + QStack state; + enum { IN_CONDITION, MET_CONDITION, PENDING_CONDITION }; + for (int count = 1; !in.atEnd(); ++count) { + QString line = QString::fromUtf8(in.readLine()); + if (line.startsWith("!!IF ")) { + if (state.isEmpty() || state.top() == IN_CONDITION) { + QString test = line.mid(5, line.length()-(5+1)); + if (project->test(test)) + state.push(IN_CONDITION); + else + state.push(PENDING_CONDITION); + } else { + state.push(MET_CONDITION); + } + } else if (line.startsWith("!!ELIF ")) { + if (state.isEmpty()) { + warn_msg(WarnLogic, "(%s:%d): Unexpected else condition", + in.fileName().toLatin1().constData(), count); + } else if (state.top() == PENDING_CONDITION) { + QString test = line.mid(7, line.length()-(7+1)); + if (project->test(test)) { + state.pop(); + state.push(IN_CONDITION); + } + } else if (state.top() == IN_CONDITION) { + state.pop(); + state.push(MET_CONDITION); + } + } else if (line.startsWith("!!ELSE")) { + if (state.isEmpty()) { + warn_msg(WarnLogic, "(%s:%d): Unexpected else condition", + in.fileName().toLatin1().constData(), count); + } else if (state.top() == PENDING_CONDITION) { state.pop(); state.push(IN_CONDITION); + } else if (state.top() == IN_CONDITION) { + state.pop(); + state.push(MET_CONDITION); } - } else if(state.top() == IN_CONDITION) { - state.pop(); - state.push(MET_CONDITION); + } else if (line.startsWith("!!ENDIF")) { + if (state.isEmpty()) + warn_msg(WarnLogic, "(%s:%d): Unexpected endif", + in.fileName().toLatin1().constData(), count); + else + state.pop(); + } else if (state.isEmpty() || state.top() == IN_CONDITION) { + contents += project->expand(line, in.fileName(), count); } - } else if(line.startsWith("!!ELSE")) { - if(state.isEmpty()) { - warn_msg(WarnLogic, "(%s:%d): Unexpected else condition", - in.fileName().toLatin1().constData(), count); - } else if(state.top() == PENDING_CONDITION) { - state.pop(); - state.push(IN_CONDITION); - } else if(state.top() == IN_CONDITION) { - state.pop(); - state.push(MET_CONDITION); - } - } else if(line.startsWith("!!ENDIF")) { - if(state.isEmpty()) - warn_msg(WarnLogic, "(%s:%d): Unexpected endif", - in.fileName().toLatin1().constData(), count); - else - state.pop(); - } else if(state.isEmpty() || state.top() == IN_CONDITION) { - contents += project->expand(line, in.fileName(), count); } + contentBytes = contents.toUtf8(); } QFile out(outn); - if(out.exists() && out.open(QFile::ReadOnly)) { - QString old = QString::fromUtf8(out.readAll()); - if(contents == old) { + if (out.exists() && out.open(QFile::ReadOnly)) { + QByteArray old = out.readAll(); + if (contentBytes == old) { v["QMAKE_INTERNAL_INCLUDED_FILES"].append(in.fileName()); continue; } @@ -567,7 +579,7 @@ MakefileGenerator::init() mkdir(QFileInfo(out).absolutePath()); if(out.open(QFile::WriteOnly)) { v["QMAKE_INTERNAL_INCLUDED_FILES"].append(in.fileName()); - out.write(contents.toUtf8()); + out.write(contentBytes); } else { warn_msg(WarnLogic, "Cannot open substitute for output '%s'", out.fileName().toLatin1().constData()); diff --git a/tests/auto/tools/qmake/testdata/substitutes/copy.txt b/tests/auto/tools/qmake/testdata/substitutes/copy.txt new file mode 100644 index 00000000000..65e58407399 --- /dev/null +++ b/tests/auto/tools/qmake/testdata/substitutes/copy.txt @@ -0,0 +1,3 @@ +This file is $processed verbatim. It's not going to "warn about + +anything that is usually substituted in qmake such as $${PWD}. diff --git a/tests/auto/tools/qmake/testdata/substitutes/test.pro b/tests/auto/tools/qmake/testdata/substitutes/test.pro index 26b02722e8c..65bb2d85bf6 100644 --- a/tests/auto/tools/qmake/testdata/substitutes/test.pro +++ b/tests/auto/tools/qmake/testdata/substitutes/test.pro @@ -1,5 +1,8 @@ -QMAKE_SUBSTITUTES += test.in sub/test2.in indirect +QMAKE_SUBSTITUTES += test.in sub/test2.in indirect copy indirect.input = $$PWD/test3.txt indirect.output = $$OUT_PWD/sub/indirect_test.txt +copy.input = $$PWD/copy.txt +copy.output = $$OUT_PWD/copy_test.txt +copy.config = verbatim diff --git a/tests/auto/tools/qmake/tst_qmake.cpp b/tests/auto/tools/qmake/tst_qmake.cpp index fcebd6b8216..4da781f763d 100644 --- a/tests/auto/tools/qmake/tst_qmake.cpp +++ b/tests/auto/tools/qmake/tst_qmake.cpp @@ -510,6 +510,14 @@ void tst_qmake::substitutes() QVERIFY( test_compiler.exists( buildDir, "test", Plain, "" )); QVERIFY( test_compiler.exists( buildDir, "sub/test2", Plain, "" )); QVERIFY( test_compiler.exists( buildDir, "sub/indirect_test.txt", Plain, "" )); + + QFile copySource(workDir + "/copy.txt"); + QFile copyDestination(buildDir + "/copy_test.txt"); + + QVERIFY(copySource.open(QFile::ReadOnly)); + QVERIFY(copyDestination.open(QFile::ReadOnly)); + QCOMPARE(copySource.readAll(), copyDestination.readAll()); + QVERIFY( test_compiler.makeDistClean( buildDir )); } From 46a4a0e8c9bf7707f5e07cbc05cbe08468526a7b Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sat, 11 Feb 2012 11:45:32 +0100 Subject: [PATCH 171/406] Fix warnings about existing directories during cmake file creation. Use the new QMAKE_SUBSTITUTES.config = vebatim feature. Change-Id: I4c08bd4694c11d48434eb225fc6902e69a4cdec2 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/create_cmake.prf | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf index fe1fe4c3762..3ae4ddc83b5 100644 --- a/mkspecs/features/create_cmake.prf +++ b/mkspecs/features/create_cmake.prf @@ -102,19 +102,16 @@ exists($$cmake_extras_file.input) { $$cmake_extras_file.output } -cmake_macros_file = $$_PRO_FILE_PWD_/Qt5$${CMAKE_MODULE_NAME}Macros.cmake -exists($$cmake_macros_file) { +cmake_macros_file.input = $$_PRO_FILE_PWD_/Qt5$${CMAKE_MODULE_NAME}Macros.cmake +exists($$cmake_macros_file.input) { CMAKE_MODULE_MACROS = "true" - cmake_qt5_module_files.files += $$cmake_macros_file - CMAKE_MACROS_FILE_SOURCE = $$_PRO_FILE_PWD_/Qt5$${CMAKE_MODULE_NAME}Macros.cmake - CMAKE_MACROS_FILE_DESTINATION = $$eval(QT.$${MODULE}.libs)/cmake/Qt5$${CMAKE_MODULE_NAME} + cmake_macros_file.output = $$eval(QT.$${MODULE}.libs)/cmake/Qt5$${CMAKE_MODULE_NAME}/Qt5$${CMAKE_MODULE_NAME}Macros.cmake + cmake_macros_file.config = verbatim - CMAKE_MACROS_FILE_SOURCE ~= s,[/\\\\],$$QMAKE_DIR_SEP, - CMAKE_MACROS_FILE_DESTINATION ~= s,[/\\\\],$$QMAKE_DIR_SEP, + QMAKE_SUBSTITUTES += cmake_macros_file - system($$QMAKE_MKDIR \"$$CMAKE_MACROS_FILE_DESTINATION\") - system($$QMAKE_COPY \"$$CMAKE_MACROS_FILE_SOURCE\" \"$$CMAKE_MACROS_FILE_DESTINATION\") + cmake_qt5_module_files.files += $$cmake_macros_file.output } cmake_qt5_module_files.path = $$[QT_INSTALL_LIBS]/cmake/Qt5$${CMAKE_MODULE_NAME} From 3755caa12a0ef81c5d36dc3e1479aab2870f9d47 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Fri, 10 Feb 2012 14:57:55 +0100 Subject: [PATCH 172/406] Remove failing for ARM Architectures. Checks cover only V7, V6 and V5. But when trying to compile for V4 it fails. Change-Id: I573361c61acc904661bf2c8bfe1132cba57f296a Reviewed-by: Bradley T. Hughes --- src/corelib/global/qprocessordetection.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h index 2d52847a486..dc219e7321a 100644 --- a/src/corelib/global/qprocessordetection.h +++ b/src/corelib/global/qprocessordetection.h @@ -87,8 +87,6 @@ # elif defined(__ARM_ARCH_5TEJ__) \ || (__TARGET_ARCH_ARM-0 >= 5) # define Q_PROCESSOR_ARM_V5 -# else -# error "Unknown ARM processor detected." # endif /* From bc8a2de9d4d6ae642b38f03eca7bdc3b494bc8c9 Mon Sep 17 00:00:00 2001 From: David Faure Date: Thu, 9 Feb 2012 14:23:25 +0100 Subject: [PATCH 173/406] Use toDisplayString when debugging urls (no passwords in logs) Change-Id: I618027c5913438bf341864d07d4831f9e33633b6 Reviewed-by: Jonas Gastal Reviewed-by: Giuseppe D'Angelo Reviewed-by: Stephen Kelly --- src/corelib/io/qurl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 183e5706fa0..eeeca1bf77f 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -6253,7 +6253,7 @@ QDataStream &operator>>(QDataStream &in, QUrl &url) #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const QUrl &url) { - d.maybeSpace() << "QUrl(" << url.toString() << ')'; + d.maybeSpace() << "QUrl(" << url.toDisplayString() << ')'; return d.space(); } #endif From 3aacbc1e2bea0855f5a405be0e1577320af784f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 6 Feb 2012 11:48:46 +0100 Subject: [PATCH 174/406] Compile without OpenGL. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since a GLuint returning virtual was added to QPlatformOpenGLContext we need to make sure it's protected by #ifndef QT_NO_OPENGL. Change-Id: Id2f56ccdccc3863986250ee1b3aa7efccf88ba5c Reviewed-by: Casper van Donderen Reviewed-by: Jørgen Lind --- src/gui/kernel/qplatformintegration_qpa.cpp | 2 ++ src/gui/kernel/qplatformintegration_qpa.h | 2 ++ src/plugins/platforms/xcb/qxcbintegration.cpp | 2 ++ src/plugins/platforms/xcb/qxcbintegration.h | 2 ++ src/plugins/platforms/xcb/xcb.pro | 2 +- 5 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp index 1336a1a9a2b..7a3fe05f7a9 100644 --- a/src/gui/kernel/qplatformintegration_qpa.cpp +++ b/src/gui/kernel/qplatformintegration_qpa.cpp @@ -220,12 +220,14 @@ QPlatformPixmap *QPlatformIntegration::createPlatformPixmap(QPlatformPixmap::Pix return new QRasterPlatformPixmap(type); } +#ifndef QT_NO_OPENGL QPlatformOpenGLContext *QPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { Q_UNUSED(context); qWarning("This plugin does not support createPlatformOpenGLContext!"); return 0; } +#endif /*! Factory function for QPlatformSharedGraphicsCache. This function will return 0 if the platform diff --git a/src/gui/kernel/qplatformintegration_qpa.h b/src/gui/kernel/qplatformintegration_qpa.h index bd9ecd54dc9..483964b8f38 100644 --- a/src/gui/kernel/qplatformintegration_qpa.h +++ b/src/gui/kernel/qplatformintegration_qpa.h @@ -87,7 +87,9 @@ public: virtual QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const; virtual QPlatformWindow *createPlatformWindow(QWindow *window) const = 0; virtual QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const = 0; +#ifndef QT_NO_OPENGL virtual QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; +#endif virtual QPlatformSharedGraphicsCache *createPlatformSharedGraphicsCache(const char *cacheId) const; // Event dispatcher: diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 0f7648a21b0..c976e75dbf6 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -171,6 +171,7 @@ private: }; #endif +#ifndef QT_NO_OPENGL QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { QXcbScreen *screen = static_cast(context->screen()->handle()); @@ -185,6 +186,7 @@ QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLCont qWarning("Cannot create platform GL context, none of GLX, EGL, DRI2 is enabled"); return 0; } +#endif QPlatformBackingStore *QXcbIntegration::createPlatformBackingStore(QWindow *window) const { diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index 77d0e4903c9..0f20658c70a 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -58,7 +58,9 @@ public: ~QXcbIntegration(); QPlatformWindow *createPlatformWindow(QWindow *window) const; +#ifndef QT_NO_OPENGL QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; +#endif QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; bool hasCapability(Capability cap) const; diff --git a/src/plugins/platforms/xcb/xcb.pro b/src/plugins/platforms/xcb/xcb.pro index d80a6df0b65..50ca8bf2693 100644 --- a/src/plugins/platforms/xcb/xcb.pro +++ b/src/plugins/platforms/xcb/xcb.pro @@ -78,7 +78,7 @@ contains(DEFINES, XCB_USE_DRI2) { HEADERS += qdri2context.h SOURCES += qdri2context.cpp -} else { +} else:contains(QT_CONFIG, opengl) { contains(QT_CONFIG, opengles2) { DEFINES += XCB_USE_EGL LIBS += -lEGL From a6d3983ef6b7affef1d2aa48ed8bf8000a6e4267 Mon Sep 17 00:00:00 2001 From: Caroline Chao Date: Thu, 2 Feb 2012 10:12:21 +0100 Subject: [PATCH 175/406] CodeCoverage: Handle QTest based subtests. Set QT_TESTCOCOON_ACTIVE environment variable when the coverage is installed for a test and unset it when the coverage data is saved. Tests that run when QT_TESTCOCOON_ACTIVE is set are subtests and will not be considered as stand-alone tests for the coverage. When a test is run as a subtest its coverage data will not be saved for itself but for the main test it is merged with. Also its status will not be reported since only the status of the main test is expected in the test report, e.g. the test tests/auto/testlib/selftests. Change-Id: Icfdf99300aae18040e1a3441a8af21f68df4c0db Reviewed-by: Rohan McGovern Reviewed-by: Jason McDonald --- src/testlib/qtestcase.cpp | 13 ++++++++-- src/testlib/qtestlog.cpp | 19 ++++++++++++-- src/testlib/qtestlog_p.h | 3 +++ .../auto/testlib/selftests/tst_selftests.cpp | 25 +++++++++++-------- 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 0440e26aca5..d94abff23c6 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -934,16 +934,24 @@ QT_BEGIN_NAMESPACE QTouchEventSequence is called (ie when the object returned runs out of scope). */ -static void installCoverageTool(const char * appname, const char * testname) +static bool installCoverageTool(const char * appname, const char * testname) { #ifdef __COVERAGESCANNER__ + if (!qgetenv("QT_TESTCOCOON_ACTIVE").isEmpty()) + return false; + // Set environment variable QT_TESTCOCOON_ACTIVE to prevent an eventual subtest from + // being considered as a stand-alone test regarding the coverage analysis. + qputenv("QT_TESTCOCOON_ACTIVE", "1"); + // Install Coverage Tool __coveragescanner_install(appname); __coveragescanner_testname(testname); __coveragescanner_clear(); + return true; #else Q_UNUSED(appname); Q_UNUSED(testname); + return false; #endif } @@ -1962,7 +1970,8 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) qtest_qParseArgs(argc, argv, false); - installCoverageTool(argv[0], metaObject->className()); + bool installedTestCoverage = installCoverageTool(argv[0], metaObject->className()); + QTestLog::setInstalledTestCoverage(installedTestCoverage); #ifdef QTESTLIB_USE_VALGRIND if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess) { diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp index 29dfbc144e3..c8487a2c54d 100644 --- a/src/testlib/qtestlog.cpp +++ b/src/testlib/qtestlog.cpp @@ -56,9 +56,11 @@ QT_BEGIN_NAMESPACE -static void saveCoverageTool(const char * appname, bool testfailed) +static void saveCoverageTool(const char * appname, bool testfailed, bool installedTestCoverage) { #ifdef __COVERAGESCANNER__ + if (!installedTestCoverage) + return; // install again to make sure the filename is correct. // without this, a plugin or similar may have changed the filename. __coveragescanner_install(appname); @@ -66,9 +68,11 @@ static void saveCoverageTool(const char * appname, bool testfailed) __coveragescanner_save(); __coveragescanner_testname(""); __coveragescanner_clear(); + unsetenv("QT_TESTCOCOON_ACTIVE"); #else Q_UNUSED(appname); Q_UNUSED(testfailed); + Q_UNUSED(installedTestCoverage); #endif } @@ -198,6 +202,7 @@ namespace QTest { static int verbosity = 0; static int maxWarnings = 2002; + static bool installedTestCoverage = true; static QtMsgHandler oldMessageHandler; @@ -388,7 +393,7 @@ void QTestLog::stopLogging() QTest::TestLoggers::stopLogging(); QTest::TestLoggers::destroyLoggers(); QTest::loggerUsingStdout = false; - saveCoverageTool(QTestResult::currentAppname(), failCount() != 0); + saveCoverageTool(QTestResult::currentAppname(), failCount() != 0, QTestLog::installedTestCoverage()); } void QTestLog::addLogger(LogMode mode, const char *filename) @@ -502,4 +507,14 @@ void QTestLog::resetCounters() QTest::skips = 0; } +void QTestLog::setInstalledTestCoverage(bool installed) +{ + QTest::installedTestCoverage = installed; +} + +bool QTestLog::installedTestCoverage() +{ + return QTest::installedTestCoverage; +} + QT_END_NAMESPACE diff --git a/src/testlib/qtestlog_p.h b/src/testlib/qtestlog_p.h index 1fe52367ec7..1a9754e4606 100644 --- a/src/testlib/qtestlog_p.h +++ b/src/testlib/qtestlog_p.h @@ -103,6 +103,9 @@ public: static void resetCounters(); + static void setInstalledTestCoverage(bool installed); + static bool installedTestCoverage(); + private: QTestLog(); ~QTestLog(); diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index dc7966b82b0..7e671a50f22 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -456,23 +456,26 @@ void tst_Selftests::runSubTest_data() } } +static void insertEnvironmentVariable(QString const& name, QProcessEnvironment &result) +{ + const QProcessEnvironment systemEnvironment = QProcessEnvironment::systemEnvironment(); + const QString value = systemEnvironment.value(name); + if (!value.isEmpty()) + result.insert(name, value); +} + static inline QProcessEnvironment processEnvironment() { QProcessEnvironment result; - const QString path = QStringLiteral("PATH"); - const QProcessEnvironment systemEnvironment = QProcessEnvironment::systemEnvironment(); - result.insert(path, systemEnvironment.value(path)); + insertEnvironmentVariable(QStringLiteral("PATH"), result); // Preserve DISPLAY for X11 as some tests use QtGui. #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) - const QString display = QStringLiteral("DISPLAY"); - const QString displayValue = systemEnvironment.value(display); - if (!displayValue.isEmpty()) - result.insert(display, displayValue); + insertEnvironmentVariable(QStringLiteral("DISPLAY"), result); +#endif + insertEnvironmentVariable(QStringLiteral("QT_QPA_PLATFORM"), result); +#ifdef __COVERAGESCANNER__ + insertEnvironmentVariable(QStringLiteral("QT_TESTCOCOON_ACTIVE"), result); #endif - const QString platform = QStringLiteral("QT_QPA_PLATFORM"); - const QString platformValue = systemEnvironment.value(platform); - if (!platformValue.isEmpty()) - result.insert(platform, platformValue); return result; } From 9b2971cbb4ebf102198c2320a575e2fd718c182e Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Thu, 2 Feb 2012 17:08:44 +1000 Subject: [PATCH 176/406] testlib: Count passes, fails and skips consistently. For data-driven tests, testlib previously counted one fail or skip for each data row that failed or skipped, while it counted only one pass for a test function where all rows passed and counted no passes for a test function where some rows passed and some rows failed. A similar problem also existed for benchmark tests, which could run multiple iterations of the same test, with each fail and skip being counted but only a single pass being counted for the entire series of iterations. This commit makes testlib count one pass, fail or skip for each data row. Test functions that are not data-driven count one result for the test function, as before. Benchmark tests count one pass, fail or skip per iteration. A side-effect of this change is that the test output in plain text, xml and light xml formats now shows a result for every data row and benchmark iteration executed, allowing post-processors to correctly calculate the total number of tests executed. Previously, individual rows were not shown in the test output if they passed, making such calculations impossible. The only change to the xunitxml output format is to correct a bug where no test result was recorded for a test function if the last data row was skipped and all other rows passed -- in which case the overall result should be a pass. Note that there is also a pre-existing bug in the xunit logger, where no result is reported if all rows are skipped; that bug is unaffected by this commit. Task-number: QTBUG-21848 Task-number: QTBUG-22124 Change-Id: I7e17177e10d6e89e55b9684c159bd506f21d002b Reviewed-by: Ed Baak --- dist/changes-5.0.0 | 5 ++ src/testlib/qtestcase.cpp | 9 ++- src/testlib/qtestresult.cpp | 24 ++++---- src/testlib/qtestresult_p.h | 2 +- .../selftests/expected_badxml.lightxml | 13 ++++- .../testlib/selftests/expected_badxml.txt | 7 ++- .../testlib/selftests/expected_badxml.xml | 13 ++++- .../selftests/expected_benchlibcallgrind.txt | 7 ++- .../expected_benchlibeventcounter.lightxml | 22 ++++++- .../expected_benchlibeventcounter.txt | 14 +++-- .../expected_benchlibeventcounter.xml | 22 ++++++- .../selftests/expected_benchliboptions.txt | 14 +++-- .../selftests/expected_cmptest.lightxml | 57 +++++++++++++------ .../testlib/selftests/expected_cmptest.txt | 45 ++++++++------- .../testlib/selftests/expected_cmptest.xml | 57 +++++++++++++------ .../expected_commandlinedata.lightxml | 20 ++++++- .../selftests/expected_commandlinedata.txt | 22 ++++--- .../selftests/expected_commandlinedata.xml | 20 ++++++- .../selftests/expected_counting.lightxml | 20 ++++++- .../testlib/selftests/expected_counting.txt | 10 +++- .../testlib/selftests/expected_counting.xml | 20 ++++++- .../selftests/expected_counting.xunitxml | 2 +- .../selftests/expected_datatable.lightxml | 52 ++++++++++++++++- .../testlib/selftests/expected_datatable.txt | 46 ++++++++++----- .../testlib/selftests/expected_datatable.xml | 52 ++++++++++++++++- .../selftests/expected_datetime.lightxml | 6 ++ .../testlib/selftests/expected_datetime.txt | 4 +- .../testlib/selftests/expected_datetime.xml | 6 ++ .../selftests/expected_expectfail.lightxml | 27 ++++++++- .../testlib/selftests/expected_expectfail.txt | 13 +++-- .../testlib/selftests/expected_expectfail.xml | 27 ++++++++- .../auto/testlib/selftests/expected_float.txt | 4 +- .../selftests/expected_globaldata.lightxml | 23 +++++++- .../testlib/selftests/expected_globaldata.txt | 11 +++- .../testlib/selftests/expected_globaldata.xml | 23 +++++++- .../selftests/expected_qexecstringlist.txt | 56 ++++++++++-------- .../testlib/selftests/expected_skip.lightxml | 4 +- .../auto/testlib/selftests/expected_skip.txt | 2 +- .../auto/testlib/selftests/expected_skip.xml | 4 +- .../selftests/expected_subtest.lightxml | 13 ++++- .../testlib/selftests/expected_subtest.txt | 7 ++- .../testlib/selftests/expected_subtest.xml | 13 ++++- 42 files changed, 641 insertions(+), 177 deletions(-) diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index b8a4e21490c..bb4ceef0d09 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -50,6 +50,11 @@ information about a particular change. * QMetaType::unregisterType() has been removed. - QTestLib: + * The plain-text, xml and lightxml test output formats have been changed to + show a test result for every row of test data in data-driven tests. In + Qt4, only fails and skips were shown for individual data rows and passes + were not shown for individual data rows, preventing accurate calculation + of test run rates and pass rates. * The QTRY_VERIFY and QTRY_COMPARE macros have been moved into QTestLib. These macros formerly lived in tests/shared/util.h but are now provided by including the header. In addition, diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index d94abff23c6..161af0f10f5 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1518,6 +1518,7 @@ static void qInvokeTestMethodDataEntry(char *slot) QTestResult::setCurrentTestLocation(QTestResult::CleanupFunc); invokeMethod(QTest::currentTestObject, "cleanup()"); + QTestResult::finishedCurrentTestDataCleanup(); QTestResult::setCurrentTestLocation(QTestResult::NoWhere); // If this test method has a benchmark, repeat until all measurements are @@ -1749,8 +1750,10 @@ static void qInvokeTestMethods(QObject *testObject) QTestResult::setCurrentTestLocation(QTestResult::InitFunc); invokeMethod(testObject, "initTestCase()"); - // finishedCurrentTestFunction() resets QTestResult::testFailed(), so use a local copy. - const bool previousFailed = QTestResult::testFailed(); + // finishedCurrentTestDataCleanup() resets QTestResult::currentTestFailed(), so use a local copy. + const bool previousFailed = QTestResult::currentTestFailed(); + QTestResult::finishedCurrentTestData(); + QTestResult::finishedCurrentTestDataCleanup(); QTestResult::finishedCurrentTestFunction(); if (!QTestResult::skipCurrentTest() && !previousFailed) { @@ -1782,6 +1785,8 @@ static void qInvokeTestMethods(QObject *testObject) QTestResult::setSkipCurrentTest(false); QTestResult::setCurrentTestFunction("cleanupTestCase"); invokeMethod(testObject, "cleanupTestCase()"); + QTestResult::finishedCurrentTestData(); + QTestResult::finishedCurrentTestDataCleanup(); } QTestResult::finishedCurrentTestFunction(); QTestResult::setCurrentTestFunction(0); diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp index c49c7aefe36..cfa85eb0658 100644 --- a/src/testlib/qtestresult.cpp +++ b/src/testlib/qtestresult.cpp @@ -58,7 +58,6 @@ namespace QTest static const char *currentTestFunc = 0; static const char *currentTestObjectName = 0; static bool failed = false; - static bool dataFailed = false; static bool skipCurrentTest = false; static QTestResult::TestLocation location = QTestResult::NoWhere; @@ -75,7 +74,6 @@ void QTestResult::reset() QTest::currentTestFunc = 0; QTest::currentTestObjectName = 0; QTest::failed = false; - QTest::dataFailed = false; QTest::location = QTestResult::NoWhere; QTest::expectFailComment = 0; @@ -86,7 +84,7 @@ void QTestResult::reset() bool QTestResult::currentTestFailed() { - return QTest::dataFailed; + return QTest::failed; } QTestData *QTestResult::currentGlobalTestData() @@ -107,7 +105,7 @@ void QTestResult::setCurrentGlobalTestData(QTestData *data) void QTestResult::setCurrentTestData(QTestData *data) { QTest::currentTestData = data; - QTest::dataFailed = false; + QTest::failed = false; } void QTestResult::setCurrentTestFunction(const char *func) @@ -133,21 +131,27 @@ void QTestResult::finishedCurrentTestData() addFailure("QEXPECT_FAIL was called without any subsequent verification statements", 0, 0); clearExpectFail(); - if (!QTest::dataFailed && QTestLog::unhandledIgnoreMessages()) { + if (!QTest::failed && QTestLog::unhandledIgnoreMessages()) { QTestLog::printUnhandledIgnoreMessages(); addFailure("Not all expected messages were received", 0, 0); } QTestLog::clearIgnoreMessages(); } -void QTestResult::finishedCurrentTestFunction() +void QTestResult::finishedCurrentTestDataCleanup() { + // If the current test hasn't failed or been skipped, then it passes. if (!QTest::failed && !QTest::skipCurrentTest) { QTestLog::addPass(""); } + + QTest::failed = false; +} + +void QTestResult::finishedCurrentTestFunction() +{ QTest::currentTestFunc = 0; QTest::failed = false; - QTest::dataFailed = false; QTest::location = NoWhere; QTestLog::leaveTestFunction(); @@ -276,7 +280,6 @@ void QTestResult::addFailure(const char *message, const char *file, int line) QTestLog::addFail(message, file, line); QTest::failed = true; - QTest::dataFailed = true; } void QTestResult::addSkip(const char *message, const char *file, int line) @@ -306,11 +309,6 @@ const char *QTestResult::currentTestObjectName() return QTest::currentTestObjectName ? QTest::currentTestObjectName : ""; } -bool QTestResult::testFailed() -{ - return QTest::failed; -} - void QTestResult::setSkipCurrentTest(bool value) { QTest::skipCurrentTest = value; diff --git a/src/testlib/qtestresult_p.h b/src/testlib/qtestresult_p.h index 81e11180ef2..5c6c4fba905 100644 --- a/src/testlib/qtestresult_p.h +++ b/src/testlib/qtestresult_p.h @@ -74,6 +74,7 @@ public: static const char *currentDataTag(); static const char *currentGlobalDataTag(); static void finishedCurrentTestData(); + static void finishedCurrentTestDataCleanup(); static void finishedCurrentTestFunction(); static void reset(); @@ -92,7 +93,6 @@ public: QTest::TestFailMode mode, const char *file, int line); static bool verify(bool statement, const char *statementStr, const char *extraInfo, const char *file, int line); - static bool testFailed(); static void setSkipCurrentTest(bool value); static bool skipCurrentTest(); diff --git a/tests/auto/testlib/selftests/expected_badxml.lightxml b/tests/auto/testlib/selftests/expected_badxml.lightxml index 43446c31699..a8cdf56dc1c 100644 --- a/tests/auto/testlib/selftests/expected_badxml.lightxml +++ b/tests/auto/testlib/selftests/expected_badxml.lightxml @@ -48,19 +48,30 @@ text ]]]> more text]]> + + + + + + open < tags < text]]> + + + " mixed ]]]> up > " in < the ]]]> hopes < of triggering "< ]]]> bugs]]> - + + + diff --git a/tests/auto/testlib/selftests/expected_badxml.txt b/tests/auto/testlib/selftests/expected_badxml.txt index 0db292e2697..d4f44320664 100644 --- a/tests/auto/testlib/selftests/expected_badxml.txt +++ b/tests/auto/testlib/selftests/expected_badxml.txt @@ -22,11 +22,14 @@ FAIL! : tst_BadXml::badDataTag(all > " mixed ]]> up > " in < the ]]> hopes < of RESULT : tst_BadXml::badDataTag():"all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs": 0 events per iteration (total: 0, iterations: 1) QDEBUG : tst_BadXml::badMessage(string 0) end cdata ]]> text ]]> more text +PASS : tst_BadXml::badMessage(string 0) QDEBUG : tst_BadXml::badMessage(string 1) quotes " text" more text +PASS : tst_BadXml::badMessage(string 1) QDEBUG : tst_BadXml::badMessage(string 2) xml close > open < tags < text +PASS : tst_BadXml::badMessage(string 2) QDEBUG : tst_BadXml::badMessage(string 3) all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs -PASS : tst_BadXml::badMessage() +PASS : tst_BadXml::badMessage(string 3) FAIL! : tst_BadXml::failWithNoFile() failure message PASS : tst_BadXml::cleanupTestCase() -Totals: 3 passed, 5 failed, 0 skipped +Totals: 6 passed, 5 failed, 0 skipped ********* Finished testing of tst_BadXml ********* diff --git a/tests/auto/testlib/selftests/expected_badxml.xml b/tests/auto/testlib/selftests/expected_badxml.xml index fbb584d5e56..9f083d3917f 100644 --- a/tests/auto/testlib/selftests/expected_badxml.xml +++ b/tests/auto/testlib/selftests/expected_badxml.xml @@ -50,19 +50,30 @@ text ]]]> more text]]> + + + + + + open < tags < text]]> + + + " mixed ]]]> up > " in < the ]]]> hopes < of triggering "< ]]]> bugs]]> - + + + diff --git a/tests/auto/testlib/selftests/expected_benchlibcallgrind.txt b/tests/auto/testlib/selftests/expected_benchlibcallgrind.txt index 2498c811385..714b67fa77a 100644 --- a/tests/auto/testlib/selftests/expected_benchlibcallgrind.txt +++ b/tests/auto/testlib/selftests/expected_benchlibcallgrind.txt @@ -1,9 +1,10 @@ ********* Start testing of tst_BenchlibCallgrind ********* Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ PASS : tst_BenchlibCallgrind::initTestCase() -RESULT : tst_BenchlibCallgrind::twoHundredMillionInstructions(): - 200,000,000 instruction reads per iteration (total: 200000000, iterations: 1) PASS : tst_BenchlibCallgrind::twoHundredMillionInstructions() +PASS : tst_BenchlibCallgrind::twoHundredMillionInstructions() +RESULT : tst_BenchlibCallgrind::twoHundredMillionInstructions(): + 200,000,158 instruction reads per iteration (total: 200,000,158, iterations: 1) PASS : tst_BenchlibCallgrind::cleanupTestCase() -Totals: 3 passed, 0 failed, 0 skipped +Totals: 4 passed, 0 failed, 0 skipped ********* Finished testing of tst_BenchlibCallgrind ********* diff --git a/tests/auto/testlib/selftests/expected_benchlibeventcounter.lightxml b/tests/auto/testlib/selftests/expected_benchlibeventcounter.lightxml index 3bede6de838..3cb59d209b8 100644 --- a/tests/auto/testlib/selftests/expected_benchlibeventcounter.lightxml +++ b/tests/auto/testlib/selftests/expected_benchlibeventcounter.lightxml @@ -6,14 +6,34 @@ + + + + + + + + + + + + + + + + + + + + + - diff --git a/tests/auto/testlib/selftests/expected_benchlibeventcounter.txt b/tests/auto/testlib/selftests/expected_benchlibeventcounter.txt index e3dc6c04115..7be4bcccc49 100644 --- a/tests/auto/testlib/selftests/expected_benchlibeventcounter.txt +++ b/tests/auto/testlib/selftests/expected_benchlibeventcounter.txt @@ -1,21 +1,27 @@ ********* Start testing of tst_BenchlibEventCounter ********* Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ PASS : tst_BenchlibEventCounter::initTestCase() +PASS : tst_BenchlibEventCounter::events(0) RESULT : tst_BenchlibEventCounter::events():"0": 0 events per iteration (total: 0, iterations: 1) +PASS : tst_BenchlibEventCounter::events(1) RESULT : tst_BenchlibEventCounter::events():"1": 1 events per iteration (total: 1, iterations: 1) +PASS : tst_BenchlibEventCounter::events(10) RESULT : tst_BenchlibEventCounter::events():"10": 10 events per iteration (total: 10, iterations: 1) +PASS : tst_BenchlibEventCounter::events(100) RESULT : tst_BenchlibEventCounter::events():"100": 100 events per iteration (total: 100, iterations: 1) +PASS : tst_BenchlibEventCounter::events(500) RESULT : tst_BenchlibEventCounter::events():"500": 500 events per iteration (total: 500, iterations: 1) +PASS : tst_BenchlibEventCounter::events(5000) RESULT : tst_BenchlibEventCounter::events():"5000": - 5,000 events per iteration (total: 5000, iterations: 1) + 5,000 events per iteration (total: 5,000, iterations: 1) +PASS : tst_BenchlibEventCounter::events(100000) RESULT : tst_BenchlibEventCounter::events():"100000": - 100,000 events per iteration (total: 100000, iterations: 1) -PASS : tst_BenchlibEventCounter::events() + 100,000 events per iteration (total: 100,000, iterations: 1) PASS : tst_BenchlibEventCounter::cleanupTestCase() -Totals: 3 passed, 0 failed, 0 skipped +Totals: 9 passed, 0 failed, 0 skipped ********* Finished testing of tst_BenchlibEventCounter ********* diff --git a/tests/auto/testlib/selftests/expected_benchlibeventcounter.xml b/tests/auto/testlib/selftests/expected_benchlibeventcounter.xml index 646cf22b804..47b497881af 100644 --- a/tests/auto/testlib/selftests/expected_benchlibeventcounter.xml +++ b/tests/auto/testlib/selftests/expected_benchlibeventcounter.xml @@ -8,14 +8,34 @@ + + + + + + + + + + + + + + + + + + + + + - diff --git a/tests/auto/testlib/selftests/expected_benchliboptions.txt b/tests/auto/testlib/selftests/expected_benchliboptions.txt index 3e75d209d0e..6d6d91c25e9 100644 --- a/tests/auto/testlib/selftests/expected_benchliboptions.txt +++ b/tests/auto/testlib/selftests/expected_benchliboptions.txt @@ -1,27 +1,33 @@ ********* Start testing of tst_BenchlibOptions ********* Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ PASS : tst_BenchlibOptions::initTestCase() +PASS : tst_BenchlibOptions::threeEvents() RESULT : tst_BenchlibOptions::threeEvents(): 3 events per iteration (total: 3, iterations: 1) -PASS : tst_BenchlibOptions::threeEvents() PASS : tst_BenchlibOptions::cleanupTestCase() Totals: 3 passed, 0 failed, 0 skipped ********* Finished testing of tst_BenchlibOptions ********* ********* Start testing of tst_BenchlibFifteenIterations ********* Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ PASS : tst_BenchlibFifteenIterations::initTestCase() +PASS : tst_BenchlibFifteenIterations::threeEvents() RESULT : tst_BenchlibFifteenIterations::threeEvents(): 3.0 events per iteration (total: 45, iterations: 15) -PASS : tst_BenchlibFifteenIterations::threeEvents() PASS : tst_BenchlibFifteenIterations::cleanupTestCase() Totals: 3 passed, 0 failed, 0 skipped ********* Finished testing of tst_BenchlibFifteenIterations ********* ********* Start testing of tst_BenchlibOneHundredMinimum ********* Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ PASS : tst_BenchlibOneHundredMinimum::initTestCase() +PASS : tst_BenchlibOneHundredMinimum::threeEvents() +PASS : tst_BenchlibOneHundredMinimum::threeEvents() +PASS : tst_BenchlibOneHundredMinimum::threeEvents() +PASS : tst_BenchlibOneHundredMinimum::threeEvents() +PASS : tst_BenchlibOneHundredMinimum::threeEvents() +PASS : tst_BenchlibOneHundredMinimum::threeEvents() +PASS : tst_BenchlibOneHundredMinimum::threeEvents() RESULT : tst_BenchlibOneHundredMinimum::threeEvents(): 3.00 events per iteration (total: 192, iterations: 64) -PASS : tst_BenchlibOneHundredMinimum::threeEvents() PASS : tst_BenchlibOneHundredMinimum::cleanupTestCase() -Totals: 3 passed, 0 failed, 0 skipped +Totals: 9 passed, 0 failed, 0 skipped ********* Finished testing of tst_BenchlibOneHundredMinimum ********* diff --git a/tests/auto/testlib/selftests/expected_cmptest.lightxml b/tests/auto/testlib/selftests/expected_cmptest.lightxml index 17f3e6ec3a9..d1cccd4bd28 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.lightxml +++ b/tests/auto/testlib/selftests/expected_cmptest.lightxml @@ -12,25 +12,28 @@ - + - + + + + - + - + ) @@ -38,31 +41,37 @@ - + + + + + + + - + - + - + - + - + + + + - + - + + + + - + - + + + + - + - + + + + - + - + diff --git a/tests/auto/testlib/selftests/expected_cmptest.txt b/tests/auto/testlib/selftests/expected_cmptest.txt index 36a4995d91d..fce635ae5af 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.txt +++ b/tests/auto/testlib/selftests/expected_cmptest.txt @@ -6,71 +6,78 @@ PASS : tst_Cmptest::compare_pointerfuncs() FAIL! : tst_Cmptest::compare_tostring(int, string) Compared values are not the same Actual (actual): QVariant(int,123) Expected (expected): QVariant(QString,hi) - Loc: [tst_cmptest.cpp(214)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(214)] +PASS : tst_Cmptest::compare_tostring(both invalid) FAIL! : tst_Cmptest::compare_tostring(null hash, invalid) Compared values are not the same Actual (actual): QVariant(QVariantHash) Expected (expected): QVariant() - Loc: [tst_cmptest.cpp(214)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(214)] FAIL! : tst_Cmptest::compare_tostring(string, null user type) Compared values are not the same Actual (actual): QVariant(QString,A simple string) Expected (expected): QVariant(PhonyClass) - Loc: [tst_cmptest.cpp(214)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(214)] FAIL! : tst_Cmptest::compare_tostring(both non-null user type) Compared values are not the same Actual (actual): QVariant(PhonyClass,) Expected (expected): QVariant(PhonyClass,) - Loc: [tst_cmptest.cpp(214)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(214)] +PASS : tst_Cmptest::compareQStringLists(empty lists) +PASS : tst_Cmptest::compareQStringLists(equal lists) FAIL! : tst_Cmptest::compareQStringLists(last item different) Compared QStringLists differ at index 2. Actual (opA) : 'string3' Expected (opB) : 'DIFFERS' - Loc: [tst_cmptest.cpp(308)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(308)] FAIL! : tst_Cmptest::compareQStringLists(second-last item different) Compared QStringLists differ at index 2. Actual (opA) : 'string3' Expected (opB) : 'DIFFERS' - Loc: [tst_cmptest.cpp(308)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(308)] FAIL! : tst_Cmptest::compareQStringLists(prefix) Compared QStringLists have different sizes. Actual (opA) size : '2' Expected (opB) size: '1' - Loc: [tst_cmptest.cpp(308)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(308)] FAIL! : tst_Cmptest::compareQStringLists(short list second) Compared QStringLists have different sizes. Actual (opA) size : '12' Expected (opB) size: '1' - Loc: [tst_cmptest.cpp(308)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(308)] FAIL! : tst_Cmptest::compareQStringLists(short list first) Compared QStringLists have different sizes. Actual (opA) size : '1' Expected (opB) size: '12' - Loc: [tst_cmptest.cpp(308)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(308)] +PASS : tst_Cmptest::compareQPixmaps(both null) FAIL! : tst_Cmptest::compareQPixmaps(one null) Compared QPixmaps differ. Actual (opA).isNull() : 1 Expected (opB).isNull(): 0 - Loc: [tst_cmptest.cpp(333)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(333)] FAIL! : tst_Cmptest::compareQPixmaps(other null) Compared QPixmaps differ. Actual (opA).isNull() : 0 Expected (opB).isNull(): 1 - Loc: [tst_cmptest.cpp(333)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(333)] +PASS : tst_Cmptest::compareQPixmaps(equal) FAIL! : tst_Cmptest::compareQPixmaps(different size) Compared QPixmaps differ in size. Actual (opA) : 11x20 Expected (opB): 20x20 - Loc: [tst_cmptest.cpp(333)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(333)] FAIL! : tst_Cmptest::compareQPixmaps(different pixels) Compared values are not the same - Loc: [tst_cmptest.cpp(333)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(333)] +PASS : tst_Cmptest::compareQImages(both null) FAIL! : tst_Cmptest::compareQImages(one null) Compared QImages differ. Actual (opA).isNull() : 1 Expected (opB).isNull(): 0 - Loc: [tst_cmptest.cpp(360)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(360)] FAIL! : tst_Cmptest::compareQImages(other null) Compared QImages differ. Actual (opA).isNull() : 0 Expected (opB).isNull(): 1 - Loc: [tst_cmptest.cpp(360)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(360)] +PASS : tst_Cmptest::compareQImages(equal) FAIL! : tst_Cmptest::compareQImages(different size) Compared QImages differ in size. Actual (opA) : 11x20 Expected (opB): 20x20 - Loc: [tst_cmptest.cpp(360)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(360)] FAIL! : tst_Cmptest::compareQImages(different format) Compared QImages differ in format. Actual (opA) : 6 Expected (opB): 3 - Loc: [tst_cmptest.cpp(360)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(360)] FAIL! : tst_Cmptest::compareQImages(different pixels) Compared values are not the same - Loc: [tst_cmptest.cpp(360)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(360)] PASS : tst_Cmptest::cleanupTestCase() -Totals: 4 passed, 18 failed, 0 skipped +Totals: 11 passed, 18 failed, 0 skipped ********* Finished testing of tst_Cmptest ********* diff --git a/tests/auto/testlib/selftests/expected_cmptest.xml b/tests/auto/testlib/selftests/expected_cmptest.xml index aba1ce5edde..90bb3135187 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.xml +++ b/tests/auto/testlib/selftests/expected_cmptest.xml @@ -14,25 +14,28 @@ - + - + + + + - + - + ) @@ -40,31 +43,37 @@ - + + + + + + + - + - + - + - + - + + + + - + - + + + + - + - + + + + - + - + + + + - + - + diff --git a/tests/auto/testlib/selftests/expected_commandlinedata.lightxml b/tests/auto/testlib/selftests/expected_commandlinedata.lightxml index 8de90f05d83..37eb5f5a2b6 100644 --- a/tests/auto/testlib/selftests/expected_commandlinedata.lightxml +++ b/tests/auto/testlib/selftests/expected_commandlinedata.lightxml @@ -10,30 +10,46 @@ + + + + + + + + + + + + - + + + - + + + diff --git a/tests/auto/testlib/selftests/expected_commandlinedata.txt b/tests/auto/testlib/selftests/expected_commandlinedata.txt index c1b97e2a301..10e4916b540 100644 --- a/tests/auto/testlib/selftests/expected_commandlinedata.txt +++ b/tests/auto/testlib/selftests/expected_commandlinedata.txt @@ -4,21 +4,25 @@ INFO : tst_DataTable::initTestCase() entering PASS : tst_DataTable::initTestCase() INFO : tst_DataTable::fiveTablePasses() entering INFO : tst_DataTable::fiveTablePasses(fiveTablePasses_data1) QVERIFY(test) - Loc: [tst_commandlinedata.cpp(30)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp(65)] +PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data1) INFO : tst_DataTable::fiveTablePasses(fiveTablePasses_data2) QVERIFY(test) - Loc: [tst_commandlinedata.cpp(30)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp(65)] +PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data2) INFO : tst_DataTable::fiveTablePasses(fiveTablePasses_data3) QVERIFY(test) - Loc: [tst_commandlinedata.cpp(30)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp(65)] +PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data3) INFO : tst_DataTable::fiveTablePasses(fiveTablePasses_data4) QVERIFY(test) - Loc: [tst_commandlinedata.cpp(30)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp(65)] +PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data4) INFO : tst_DataTable::fiveTablePasses(fiveTablePasses_data5) QVERIFY(test) - Loc: [tst_commandlinedata.cpp(30)] -PASS : tst_DataTable::fiveTablePasses() + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp(65)] +PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data5) INFO : tst_DataTable::fiveTablePasses() entering INFO : tst_DataTable::fiveTablePasses(fiveTablePasses_data1) QVERIFY(test) - Loc: [tst_commandlinedata.cpp(30)] -PASS : tst_DataTable::fiveTablePasses() + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp(65)] +PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data1) INFO : tst_DataTable::cleanupTestCase() entering PASS : tst_DataTable::cleanupTestCase() -Totals: 4 passed, 0 failed, 0 skipped +Totals: 8 passed, 0 failed, 0 skipped ********* Finished testing of tst_DataTable ********* diff --git a/tests/auto/testlib/selftests/expected_commandlinedata.xml b/tests/auto/testlib/selftests/expected_commandlinedata.xml index bfaf6233305..2296ae8e744 100644 --- a/tests/auto/testlib/selftests/expected_commandlinedata.xml +++ b/tests/auto/testlib/selftests/expected_commandlinedata.xml @@ -12,30 +12,46 @@ + + + + + + + + + + + + - + + + - + + + diff --git a/tests/auto/testlib/selftests/expected_counting.lightxml b/tests/auto/testlib/selftests/expected_counting.lightxml index f16abef1283..fd80292b904 100644 --- a/tests/auto/testlib/selftests/expected_counting.lightxml +++ b/tests/auto/testlib/selftests/expected_counting.lightxml @@ -6,15 +6,26 @@ - + + + + + + + + + + + + @@ -25,7 +36,9 @@ - + + + @@ -52,6 +65,9 @@ + + + diff --git a/tests/auto/testlib/selftests/expected_counting.txt b/tests/auto/testlib/selftests/expected_counting.txt index adf80012c72..bd70a44b2e8 100644 --- a/tests/auto/testlib/selftests/expected_counting.txt +++ b/tests/auto/testlib/selftests/expected_counting.txt @@ -1,14 +1,17 @@ ********* Start testing of tst_Counting ********* Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ PASS : tst_Counting::initTestCase() -PASS : tst_Counting::testPassPass() +PASS : tst_Counting::testPassPass(row 1) +PASS : tst_Counting::testPassPass(row 2) +PASS : tst_Counting::testPassSkip(row 1) SKIP : tst_Counting::testPassSkip(row 2) Skipping Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(102)] +PASS : tst_Counting::testPassFail(row 1) FAIL! : tst_Counting::testPassFail(row 2) 'false' returned FALSE. () Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(99)] SKIP : tst_Counting::testSkipPass(row 1) Skipping Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(102)] -PASS : tst_Counting::testSkipPass() +PASS : tst_Counting::testSkipPass(row 2) SKIP : tst_Counting::testSkipSkip(row 1) Skipping Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(102)] SKIP : tst_Counting::testSkipSkip(row 2) Skipping @@ -19,6 +22,7 @@ FAIL! : tst_Counting::testSkipFail(row 2) 'false' returned FALSE. () Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(99)] FAIL! : tst_Counting::testFailPass(row 1) 'false' returned FALSE. () Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(99)] +PASS : tst_Counting::testFailPass(row 2) FAIL! : tst_Counting::testFailSkip(row 1) 'false' returned FALSE. () Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(99)] SKIP : tst_Counting::testFailSkip(row 2) Skipping @@ -28,5 +32,5 @@ FAIL! : tst_Counting::testFailFail(row 1) 'false' returned FALSE. () FAIL! : tst_Counting::testFailFail(row 2) 'false' returned FALSE. () Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(99)] PASS : tst_Counting::cleanupTestCase() -Totals: 4 passed, 6 failed, 6 skipped +Totals: 8 passed, 6 failed, 6 skipped ********* Finished testing of tst_Counting ********* diff --git a/tests/auto/testlib/selftests/expected_counting.xml b/tests/auto/testlib/selftests/expected_counting.xml index f5982d7052a..c5460a73466 100644 --- a/tests/auto/testlib/selftests/expected_counting.xml +++ b/tests/auto/testlib/selftests/expected_counting.xml @@ -8,15 +8,26 @@ - + + + + + + + + + + + + @@ -27,7 +38,9 @@ - + + + @@ -54,6 +67,9 @@ + + + diff --git a/tests/auto/testlib/selftests/expected_counting.xunitxml b/tests/auto/testlib/selftests/expected_counting.xunitxml index c19a1612cbb..496546700ef 100644 --- a/tests/auto/testlib/selftests/expected_counting.xunitxml +++ b/tests/auto/testlib/selftests/expected_counting.xunitxml @@ -6,7 +6,7 @@ - + diff --git a/tests/auto/testlib/selftests/expected_datatable.lightxml b/tests/auto/testlib/selftests/expected_datatable.lightxml index 1741b6f1e3d..83ac0c0b5d0 100644 --- a/tests/auto/testlib/selftests/expected_datatable.lightxml +++ b/tests/auto/testlib/selftests/expected_datatable.lightxml @@ -12,7 +12,21 @@ - + + + + + + + + + + + + + + + @@ -41,18 +55,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_datatable.txt b/tests/auto/testlib/selftests/expected_datatable.txt index 4031ca22dd0..68c33e6efd8 100644 --- a/tests/auto/testlib/selftests/expected_datatable.txt +++ b/tests/auto/testlib/selftests/expected_datatable.txt @@ -3,33 +3,49 @@ Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE PASS : tst_DataTable::initTestCase() PASS : tst_DataTable::singleTestFunction1() PASS : tst_DataTable::singleTestFunction2() -PASS : tst_DataTable::fiveTablePasses() +PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data 1) +PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data 2) +PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data 3) +PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data 4) +PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data 5) FAIL! : tst_DataTable::fiveTableFailures(fiveTableFailures_data 1) 'test' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(58)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(91)] FAIL! : tst_DataTable::fiveTableFailures(fiveTableFailures_data 2) 'test' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(58)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(91)] FAIL! : tst_DataTable::fiveTableFailures(fiveTableFailures_data 3) 'test' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(58)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(91)] FAIL! : tst_DataTable::fiveTableFailures(fiveTableFailures_data 4) 'test' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(58)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(91)] FAIL! : tst_DataTable::fiveTableFailures(fiveTableFailures_data 5) 'test' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(58)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(91)] FAIL! : tst_DataTable::startsWithFailure(startsWithFailure_data 1) 'test' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(58)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(91)] +PASS : tst_DataTable::startsWithFailure(startsWithFailure_data 2) +PASS : tst_DataTable::startsWithFailure(startsWithFailure_data 3) +PASS : tst_DataTable::startsWithFailure(startsWithFailure_data 4) +PASS : tst_DataTable::startsWithFailure(startsWithFailure_data 5) +PASS : tst_DataTable::endsWithFailure(endsWithFailure 1) +PASS : tst_DataTable::endsWithFailure(endsWithFailure 2) +PASS : tst_DataTable::endsWithFailure(endsWithFailure 3) +PASS : tst_DataTable::endsWithFailure(endsWithFailure 4) FAIL! : tst_DataTable::endsWithFailure(endsWithFailure 5) 'test' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(58)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(91)] +PASS : tst_DataTable::failureInMiddle(failureInMiddle_data 1) +PASS : tst_DataTable::failureInMiddle(failureInMiddle_data 2) FAIL! : tst_DataTable::failureInMiddle(failureInMiddle_data 3) 'test' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(58)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(91)] +PASS : tst_DataTable::failureInMiddle(failureInMiddle_data 4) +PASS : tst_DataTable::failureInMiddle(failureInMiddle_data 5) FAIL! : tst_DataTable::fiveIsolatedFailures(fiveIsolatedFailures_data 1) '!test' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(140)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(173)] FAIL! : tst_DataTable::fiveIsolatedFailures(fiveIsolatedFailures_data 2) '!test' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(140)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(173)] FAIL! : tst_DataTable::fiveIsolatedFailures(fiveIsolatedFailures_data 3) '!test' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(140)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(173)] FAIL! : tst_DataTable::fiveIsolatedFailures(fiveIsolatedFailures_data 4) '!test' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(140)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(173)] FAIL! : tst_DataTable::fiveIsolatedFailures(fiveIsolatedFailures_data 5) '!test' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(140)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(173)] PASS : tst_DataTable::cleanupTestCase() -Totals: 5 passed, 13 failed, 0 skipped +Totals: 21 passed, 13 failed, 0 skipped ********* Finished testing of tst_DataTable ********* diff --git a/tests/auto/testlib/selftests/expected_datatable.xml b/tests/auto/testlib/selftests/expected_datatable.xml index ce123d836c0..132b34ec4a1 100644 --- a/tests/auto/testlib/selftests/expected_datatable.xml +++ b/tests/auto/testlib/selftests/expected_datatable.xml @@ -14,7 +14,21 @@ - + + + + + + + + + + + + + + + @@ -43,18 +57,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_datetime.lightxml b/tests/auto/testlib/selftests/expected_datetime.lightxml index 0024b101aae..17fd48a196d 100644 --- a/tests/auto/testlib/selftests/expected_datetime.lightxml +++ b/tests/auto/testlib/selftests/expected_datetime.lightxml @@ -13,6 +13,9 @@ + + + + + + diff --git a/tests/auto/testlib/selftests/expected_datetime.txt b/tests/auto/testlib/selftests/expected_datetime.txt index e2966b9168a..239886ca8ec 100644 --- a/tests/auto/testlib/selftests/expected_datetime.txt +++ b/tests/auto/testlib/selftests/expected_datetime.txt @@ -5,6 +5,7 @@ FAIL! : tst_DateTime::dateTime() Compared values are not the same Actual (local): 2000/05/03 04:03:04.000[local time] Expected (utc): 2000/05/03 04:03:04.000[UTC] Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp(33)] +PASS : tst_DateTime::qurl(empty urls) FAIL! : tst_DateTime::qurl(empty rhs) Compared values are not the same Actual (operandA): http://example.com Expected (operandB): @@ -13,6 +14,7 @@ FAIL! : tst_DateTime::qurl(empty lhs) Compared values are not the same Actual (operandA): Expected (operandB): http://example.com Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp(41)] +PASS : tst_DateTime::qurl(same urls) PASS : tst_DateTime::cleanupTestCase() -Totals: 2 passed, 3 failed, 0 skipped +Totals: 4 passed, 3 failed, 0 skipped ********* Finished testing of tst_DateTime ********* diff --git a/tests/auto/testlib/selftests/expected_datetime.xml b/tests/auto/testlib/selftests/expected_datetime.xml index f1b5a6aafd9..747ff13730a 100644 --- a/tests/auto/testlib/selftests/expected_datetime.xml +++ b/tests/auto/testlib/selftests/expected_datetime.xml @@ -15,6 +15,9 @@ + + + + + + diff --git a/tests/auto/testlib/selftests/expected_expectfail.lightxml b/tests/auto/testlib/selftests/expected_expectfail.lightxml index eab0bbbaa38..8fdac12d213 100644 --- a/tests/auto/testlib/selftests/expected_expectfail.lightxml +++ b/tests/auto/testlib/selftests/expected_expectfail.lightxml @@ -41,29 +41,47 @@ + + + + + + + + + - + + + - + + + + + + - + + + @@ -85,6 +103,9 @@ + + + diff --git a/tests/auto/testlib/selftests/expected_expectfail.txt b/tests/auto/testlib/selftests/expected_expectfail.txt index 0286490372c..f1ad4061b9b 100644 --- a/tests/auto/testlib/selftests/expected_expectfail.txt +++ b/tests/auto/testlib/selftests/expected_expectfail.txt @@ -17,23 +17,28 @@ XFAIL : tst_ExpectFail::xfailWithQString() A string XFAIL : tst_ExpectFail::xfailWithQString() Bug 5 (The message) Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(106)] PASS : tst_ExpectFail::xfailWithQString() +PASS : tst_ExpectFail::xfailDataDriven(Pass 1) +PASS : tst_ExpectFail::xfailDataDriven(Pass 2) XFAIL : tst_ExpectFail::xfailDataDriven(Abort) This test should xfail Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(135)] +PASS : tst_ExpectFail::xfailDataDriven(Abort) XFAIL : tst_ExpectFail::xfailDataDriven(Continue) This test should xfail Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(135)] -PASS : tst_ExpectFail::xfailDataDriven() -PASS : tst_ExpectFail::xfailOnWrongRow() +PASS : tst_ExpectFail::xfailDataDriven(Continue) +PASS : tst_ExpectFail::xfailOnWrongRow(right row) XFAIL : tst_ExpectFail::xfailOnAnyRow(first row) This test should xfail Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(170)] +PASS : tst_ExpectFail::xfailOnAnyRow(first row) XFAIL : tst_ExpectFail::xfailOnAnyRow(second row) This test should xfail Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(170)] -PASS : tst_ExpectFail::xfailOnAnyRow() +PASS : tst_ExpectFail::xfailOnAnyRow(second row) FAIL! : tst_ExpectFail::xfailWithoutVerify(first row) QEXPECT_FAIL was called without any subsequent verification statements FAIL! : tst_ExpectFail::xfailWithoutVerify(second row) QEXPECT_FAIL was called without any subsequent verification statements XPASS : tst_ExpectFail::xpass() 'true' returned FALSE. () Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(190)] XPASS : tst_ExpectFail::xpassDataDriven(XPass) 'true' returned FALSE. () Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(212)] +PASS : tst_ExpectFail::xpassDataDriven(Pass) PASS : tst_ExpectFail::cleanupTestCase() -Totals: 8 passed, 5 failed, 0 skipped +Totals: 13 passed, 5 failed, 0 skipped ********* Finished testing of tst_ExpectFail ********* diff --git a/tests/auto/testlib/selftests/expected_expectfail.xml b/tests/auto/testlib/selftests/expected_expectfail.xml index 3c8baf92712..cb061f55bf9 100644 --- a/tests/auto/testlib/selftests/expected_expectfail.xml +++ b/tests/auto/testlib/selftests/expected_expectfail.xml @@ -43,29 +43,47 @@ + + + + + + + + + - + + + - + + + + + + - + + + @@ -87,6 +105,9 @@ + + + diff --git a/tests/auto/testlib/selftests/expected_float.txt b/tests/auto/testlib/selftests/expected_float.txt index 81e4d7b067b..6ebbeffde50 100644 --- a/tests/auto/testlib/selftests/expected_float.txt +++ b/tests/auto/testlib/selftests/expected_float.txt @@ -1,6 +1,7 @@ ********* Start testing of tst_float ********* Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ PASS : tst_float::initTestCase() +PASS : tst_float::floatComparisons(should SUCCEED 1) FAIL! : tst_float::floatComparisons(should FAIL 1) Compared floats are not the same (fuzzy compare) Actual (operandLeft): 1 Expected (operandRight): 3 @@ -13,6 +14,7 @@ FAIL! : tst_float::floatComparisons(should FAIL 3) Compared floats are not the Actual (operandLeft): 99998 Expected (operandRight): 99999 Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(61)] +PASS : tst_float::floatComparisons(should SUCCEED 2) FAIL! : tst_float::compareFloatTests(1e0) Compared floats are not the same (fuzzy compare) Actual (t1): 1 Expected (t3): 3 @@ -26,5 +28,5 @@ FAIL! : tst_float::compareFloatTests(1e+7) Compared floats are not the same (fu Expected (t3): 3e+07 Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(104)] PASS : tst_float::cleanupTestCase() -Totals: 2 passed, 6 failed, 0 skipped +Totals: 4 passed, 6 failed, 0 skipped ********* Finished testing of tst_float ********* diff --git a/tests/auto/testlib/selftests/expected_globaldata.lightxml b/tests/auto/testlib/selftests/expected_globaldata.lightxml index 7a50f01cb8a..6d68bfbdb54 100644 --- a/tests/auto/testlib/selftests/expected_globaldata.lightxml +++ b/tests/auto/testlib/selftests/expected_globaldata.lightxml @@ -25,6 +25,9 @@ + + + @@ -41,6 +44,9 @@ + + + @@ -57,6 +63,9 @@ + + + @@ -73,7 +82,9 @@ - + + + @@ -120,6 +131,9 @@ + + + @@ -132,6 +146,9 @@ + + + @@ -156,7 +173,9 @@ - + + + diff --git a/tests/auto/testlib/selftests/expected_globaldata.txt b/tests/auto/testlib/selftests/expected_globaldata.txt index e3905e2fa3c..59b95fa2533 100644 --- a/tests/auto/testlib/selftests/expected_globaldata.txt +++ b/tests/auto/testlib/selftests/expected_globaldata.txt @@ -6,19 +6,22 @@ QDEBUG : tst_globaldata::testGlobal(1:local 1) init testGlobal local 1 QDEBUG : tst_globaldata::testGlobal(1:local 1) global: false QDEBUG : tst_globaldata::testGlobal(1:local 1) local: false QDEBUG : tst_globaldata::testGlobal(1:local 1) cleanup testGlobal local 1 +PASS : tst_globaldata::testGlobal(1:local 1) QDEBUG : tst_globaldata::testGlobal(1:local 2) init testGlobal local 2 QDEBUG : tst_globaldata::testGlobal(1:local 2) global: false QDEBUG : tst_globaldata::testGlobal(1:local 2) local: true QDEBUG : tst_globaldata::testGlobal(1:local 2) cleanup testGlobal local 2 +PASS : tst_globaldata::testGlobal(1:local 2) QDEBUG : tst_globaldata::testGlobal(2:local 1) init testGlobal local 1 QDEBUG : tst_globaldata::testGlobal(2:local 1) global: true QDEBUG : tst_globaldata::testGlobal(2:local 1) local: false QDEBUG : tst_globaldata::testGlobal(2:local 1) cleanup testGlobal local 1 +PASS : tst_globaldata::testGlobal(2:local 1) QDEBUG : tst_globaldata::testGlobal(2:local 2) init testGlobal local 2 QDEBUG : tst_globaldata::testGlobal(2:local 2) global: true QDEBUG : tst_globaldata::testGlobal(2:local 2) local: true QDEBUG : tst_globaldata::testGlobal(2:local 2) cleanup testGlobal local 2 -PASS : tst_globaldata::testGlobal() +PASS : tst_globaldata::testGlobal(2:local 2) SKIP : tst_globaldata::skip(1) skipping Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/globaldata/tst_globaldata.cpp(129)] QDEBUG : tst_globaldata::skipLocal(1:local 1) init skipLocal local 1 @@ -32,9 +35,11 @@ QDEBUG : tst_globaldata::skipLocal(1:local 2) cleanup skipLocal local 2 QDEBUG : tst_globaldata::skipSingle(1:local 1) init skipSingle local 1 QDEBUG : tst_globaldata::skipSingle(1:local 1) global: false local: false QDEBUG : tst_globaldata::skipSingle(1:local 1) cleanup skipSingle local 1 +PASS : tst_globaldata::skipSingle(1:local 1) QDEBUG : tst_globaldata::skipSingle(1:local 2) init skipSingle local 2 QDEBUG : tst_globaldata::skipSingle(1:local 2) global: false local: true QDEBUG : tst_globaldata::skipSingle(1:local 2) cleanup skipSingle local 2 +PASS : tst_globaldata::skipSingle(1:local 2) QDEBUG : tst_globaldata::skipSingle(2:local 1) init skipSingle local 1 SKIP : tst_globaldata::skipSingle(2:local 1) skipping Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/globaldata/tst_globaldata.cpp(143)] @@ -42,8 +47,8 @@ QDEBUG : tst_globaldata::skipSingle(2:local 1) cleanup skipSingle local 1 QDEBUG : tst_globaldata::skipSingle(2:local 2) init skipSingle local 2 QDEBUG : tst_globaldata::skipSingle(2:local 2) global: true local: true QDEBUG : tst_globaldata::skipSingle(2:local 2) cleanup skipSingle local 2 -PASS : tst_globaldata::skipSingle() +PASS : tst_globaldata::skipSingle(2:local 2) QDEBUG : tst_globaldata::cleanupTestCase() cleanupTestCase cleanupTestCase (null) PASS : tst_globaldata::cleanupTestCase() -Totals: 4 passed, 0 failed, 4 skipped +Totals: 9 passed, 0 failed, 4 skipped ********* Finished testing of tst_globaldata ********* diff --git a/tests/auto/testlib/selftests/expected_globaldata.xml b/tests/auto/testlib/selftests/expected_globaldata.xml index 9abbeeef35e..09edaacd436 100644 --- a/tests/auto/testlib/selftests/expected_globaldata.xml +++ b/tests/auto/testlib/selftests/expected_globaldata.xml @@ -27,6 +27,9 @@ + + + @@ -43,6 +46,9 @@ + + + @@ -59,6 +65,9 @@ + + + @@ -75,7 +84,9 @@ - + + + @@ -122,6 +133,9 @@ + + + @@ -134,6 +148,9 @@ + + + @@ -158,7 +175,9 @@ - + + + diff --git a/tests/auto/testlib/selftests/expected_qexecstringlist.txt b/tests/auto/testlib/selftests/expected_qexecstringlist.txt index 87df97af485..da283e106f0 100644 --- a/tests/auto/testlib/selftests/expected_qexecstringlist.txt +++ b/tests/auto/testlib/selftests/expected_qexecstringlist.txt @@ -2,38 +2,44 @@ Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ PASS : tst_QExecStringList::initTestCase() PASS : tst_QExecStringList::testA() -PASS : tst_QExecStringList::testB() +PASS : tst_QExecStringList::testB(Data1) +PASS : tst_QExecStringList::testB(Data2) +PASS : tst_QExecStringList::testB(Data3) PASS : tst_QExecStringList::testC() PASS : tst_QExecStringList::cleanupTestCase() +Totals: 7 passed, 0 failed, 0 skipped +********* Finished testing of tst_QExecStringList ********* +********* Start testing of tst_QExecStringList ********* +Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ +PASS : tst_QExecStringList::initTestCase() +PASS : tst_QExecStringList::testA() +PASS : tst_QExecStringList::testB(Data1) +PASS : tst_QExecStringList::testB(Data2) +PASS : tst_QExecStringList::testB(Data3) +PASS : tst_QExecStringList::testC() +PASS : tst_QExecStringList::cleanupTestCase() +Totals: 7 passed, 0 failed, 0 skipped +********* Finished testing of tst_QExecStringList ********* +********* Start testing of tst_QExecStringList ********* +Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ +PASS : tst_QExecStringList::initTestCase() +PASS : tst_QExecStringList::testA() +PASS : tst_QExecStringList::cleanupTestCase() +Totals: 3 passed, 0 failed, 0 skipped +********* Finished testing of tst_QExecStringList ********* +********* Start testing of tst_QExecStringList ********* +Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ +PASS : tst_QExecStringList::initTestCase() +PASS : tst_QExecStringList::testB(Data1) +PASS : tst_QExecStringList::testB(Data2) +PASS : tst_QExecStringList::testB(Data3) +PASS : tst_QExecStringList::cleanupTestCase() Totals: 5 passed, 0 failed, 0 skipped ********* Finished testing of tst_QExecStringList ********* ********* Start testing of tst_QExecStringList ********* Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ PASS : tst_QExecStringList::initTestCase() -PASS : tst_QExecStringList::testA() -PASS : tst_QExecStringList::testB() -PASS : tst_QExecStringList::testC() -PASS : tst_QExecStringList::cleanupTestCase() -Totals: 5 passed, 0 failed, 0 skipped -********* Finished testing of tst_QExecStringList ********* -********* Start testing of tst_QExecStringList ********* -Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ -PASS : tst_QExecStringList::initTestCase() -PASS : tst_QExecStringList::testA() -PASS : tst_QExecStringList::cleanupTestCase() -Totals: 3 passed, 0 failed, 0 skipped -********* Finished testing of tst_QExecStringList ********* -********* Start testing of tst_QExecStringList ********* -Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ -PASS : tst_QExecStringList::initTestCase() -PASS : tst_QExecStringList::testB() -PASS : tst_QExecStringList::cleanupTestCase() -Totals: 3 passed, 0 failed, 0 skipped -********* Finished testing of tst_QExecStringList ********* -********* Start testing of tst_QExecStringList ********* -Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ -PASS : tst_QExecStringList::initTestCase() -PASS : tst_QExecStringList::testB() +PASS : tst_QExecStringList::testB(Data2) PASS : tst_QExecStringList::cleanupTestCase() Totals: 3 passed, 0 failed, 0 skipped ********* Finished testing of tst_QExecStringList ********* diff --git a/tests/auto/testlib/selftests/expected_skip.lightxml b/tests/auto/testlib/selftests/expected_skip.lightxml index 8399a76fa20..b01570e2757 100644 --- a/tests/auto/testlib/selftests/expected_skip.lightxml +++ b/tests/auto/testlib/selftests/expected_skip.lightxml @@ -24,7 +24,9 @@ - + + + diff --git a/tests/auto/testlib/selftests/expected_skip.txt b/tests/auto/testlib/selftests/expected_skip.txt index e18386e109b..fadbc966f02 100644 --- a/tests/auto/testlib/selftests/expected_skip.txt +++ b/tests/auto/testlib/selftests/expected_skip.txt @@ -8,7 +8,7 @@ SKIP : tst_Skip::emptytest() skipping all SKIP : tst_Skip::singleSkip(local 1) skipping one Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skip/tst_skip.cpp(97)] QDEBUG : tst_Skip::singleSkip(local 2) this line should only be reached once (true) -PASS : tst_Skip::singleSkip() +PASS : tst_Skip::singleSkip(local 2) PASS : tst_Skip::cleanupTestCase() Totals: 3 passed, 0 failed, 3 skipped ********* Finished testing of tst_Skip ********* diff --git a/tests/auto/testlib/selftests/expected_skip.xml b/tests/auto/testlib/selftests/expected_skip.xml index d0e45d0ff82..6609c0464a6 100644 --- a/tests/auto/testlib/selftests/expected_skip.xml +++ b/tests/auto/testlib/selftests/expected_skip.xml @@ -26,7 +26,9 @@ - + + + diff --git a/tests/auto/testlib/selftests/expected_subtest.lightxml b/tests/auto/testlib/selftests/expected_subtest.lightxml index d76ec131de5..e7d8d53efc6 100644 --- a/tests/auto/testlib/selftests/expected_subtest.lightxml +++ b/tests/auto/testlib/selftests/expected_subtest.lightxml @@ -43,6 +43,9 @@ + + + @@ -59,6 +62,9 @@ + + + @@ -75,7 +81,9 @@ - + + + @@ -100,6 +108,9 @@ + + + diff --git a/tests/auto/testlib/selftests/expected_subtest.txt b/tests/auto/testlib/selftests/expected_subtest.txt index e35fb805e06..7b29bfc8c35 100644 --- a/tests/auto/testlib/selftests/expected_subtest.txt +++ b/tests/auto/testlib/selftests/expected_subtest.txt @@ -12,21 +12,24 @@ QDEBUG : tst_Subtest::test2(data0) init test2 data0 QDEBUG : tst_Subtest::test2(data0) test2 test2 data0 QDEBUG : tst_Subtest::test2(data0) test2 end QDEBUG : tst_Subtest::test2(data0) cleanup test2 data0 +PASS : tst_Subtest::test2(data0) QDEBUG : tst_Subtest::test2(data1) init test2 data1 QDEBUG : tst_Subtest::test2(data1) test2 test2 data1 QDEBUG : tst_Subtest::test2(data1) test2 end QDEBUG : tst_Subtest::test2(data1) cleanup test2 data1 +PASS : tst_Subtest::test2(data1) QDEBUG : tst_Subtest::test2(data2) init test2 data2 QDEBUG : tst_Subtest::test2(data2) test2 test2 data2 QDEBUG : tst_Subtest::test2(data2) test2 end QDEBUG : tst_Subtest::test2(data2) cleanup test2 data2 -PASS : tst_Subtest::test2() +PASS : tst_Subtest::test2(data2) QDEBUG : tst_Subtest::test3() test3_data test3 (null) QDEBUG : tst_Subtest::test3() test3_data end QDEBUG : tst_Subtest::test3(data0) init test3 data0 QDEBUG : tst_Subtest::test3(data0) test2 test3 data0 QDEBUG : tst_Subtest::test3(data0) test2 end QDEBUG : tst_Subtest::test3(data0) cleanup test3 data0 +PASS : tst_Subtest::test3(data0) QDEBUG : tst_Subtest::test3(data1) init test3 data1 QDEBUG : tst_Subtest::test3(data1) test2 test3 data1 FAIL! : tst_Subtest::test3(data1) Compared values are not the same @@ -43,5 +46,5 @@ FAIL! : tst_Subtest::test3(data2) Compared values are not the same QDEBUG : tst_Subtest::test3(data2) cleanup test3 data2 QDEBUG : tst_Subtest::cleanupTestCase() cleanupTestCase cleanupTestCase (null) PASS : tst_Subtest::cleanupTestCase() -Totals: 4 passed, 2 failed, 0 skipped +Totals: 7 passed, 2 failed, 0 skipped ********* Finished testing of tst_Subtest ********* diff --git a/tests/auto/testlib/selftests/expected_subtest.xml b/tests/auto/testlib/selftests/expected_subtest.xml index d79242f0616..8a3846599c3 100644 --- a/tests/auto/testlib/selftests/expected_subtest.xml +++ b/tests/auto/testlib/selftests/expected_subtest.xml @@ -45,6 +45,9 @@ + + + @@ -61,6 +64,9 @@ + + + @@ -77,7 +83,9 @@ - + + + @@ -102,6 +110,9 @@ + + + From eeabf829581a2957de501acd96f5ef71b9d0d2d9 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Mon, 13 Feb 2012 09:42:08 +1000 Subject: [PATCH 177/406] Fixed compile with -qtnamespace Add missing (unbalanced) macros. Some files had QT_BEGIN_NAMESPACE without a corresponding QT_END_NAMESPACE. Change-Id: I50226a37a3710eda80ad76320d11efee39aa1fd8 Reviewed-by: Toby Tomkins --- src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.cpp | 2 ++ src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.cpp b/src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.cpp index 8769b704954..cb23d3a49c1 100644 --- a/src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.cpp +++ b/src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.cpp @@ -248,3 +248,5 @@ void QEvdevKeyboardManager::checkDevice(udev_device *dev) return; } } + +QT_END_NAMESPACE diff --git a/src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.h b/src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.h index 11892d12dca..3caed6ff436 100644 --- a/src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.h +++ b/src/plugins/generic/evdevkeyboard/qevdevkeyboardmanager.h @@ -82,4 +82,8 @@ private: QSocketNotifier *m_udevSocketNotifier; }; +QT_END_HEADER + +QT_END_NAMESPACE + #endif // QEVDEVKEYBOARDMANAGER_H From 9b4db5151f81903bf34621b9db27473051b02e80 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 10 Feb 2012 11:25:32 +0100 Subject: [PATCH 178/406] Remove out-of-line atomic implementation for Alpha This implementation has not been tested or supported at all during the Qt 4.x lifetime. Do not bring it with us into Qt 5.x. Only inline assembler with GCC is supported. Change-Id: I31b48721bb7f4c96f4a777da604d80cc63c6fd79 Reviewed-by: Thiago Macieira --- src/corelib/arch/alpha/arch.pri | 4 - src/corelib/arch/alpha/qatomic_alpha.s | 239 ------------------------- src/corelib/arch/qatomic_alpha.h | 126 +------------ 3 files changed, 2 insertions(+), 367 deletions(-) delete mode 100644 src/corelib/arch/alpha/arch.pri delete mode 100644 src/corelib/arch/alpha/qatomic_alpha.s diff --git a/src/corelib/arch/alpha/arch.pri b/src/corelib/arch/alpha/arch.pri deleted file mode 100644 index 448a531f073..00000000000 --- a/src/corelib/arch/alpha/arch.pri +++ /dev/null @@ -1,4 +0,0 @@ -# -# Alpha architecture -# -!*-g++*:SOURCES += $$QT_ARCH_CPP/qatomic_alpha.s diff --git a/src/corelib/arch/alpha/qatomic_alpha.s b/src/corelib/arch/alpha/qatomic_alpha.s deleted file mode 100644 index 3bccd128493..00000000000 --- a/src/corelib/arch/alpha/qatomic_alpha.s +++ /dev/null @@ -1,239 +0,0 @@ -;/**************************************************************************** -;** -;** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -;** Contact: http://www.qt-project.org/ -;** -;** This file is part of the QtGui 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$ -;** -;****************************************************************************/ - .set noreorder - .set volatile - .set noat - .arch ev4 - .text - .align 2 - .align 4 - .globl q_atomic_test_and_set_int - .ent q_atomic_test_and_set_int -q_atomic_test_and_set_int: - .frame $30,0,$26,0 - .prologue 0 -1: ldl_l $0,0($16) - cmpeq $0,$17,$0 - beq $0,3f - mov $18,$0 - stl_c $0,0($16) - beq $0,2f - br 3f -2: br 1b -3: addl $31,$0,$0 - ret $31,($26),1 - .end q_atomic_test_and_set_int - .align 2 - .align 4 - .globl q_atomic_test_and_set_acquire_int - .ent q_atomic_test_and_set_acquire_int -q_atomic_test_and_set_acquire_int: - .frame $30,0,$26,0 - .prologue 0 -1: ldl_l $0,0($16) - cmpeq $0,$17,$0 - beq $0,3f - mov $18,$0 - stl_c $0,0($16) - beq $0,2f - br 3f -2: br 1b -3: mb - addl $31,$0,$0 - ret $31,($26),1 - .end q_atomic_test_and_set_acquire_int - .align 2 - .align 4 - .globl q_atomic_test_and_set_release_int - .ent q_atomic_test_and_set_release_int -q_atomic_test_and_set_release_int: - .frame $30,0,$26,0 - .prologue 0 - mb -1: ldl_l $0,0($16) - cmpeq $0,$17,$0 - beq $0,3f - mov $18,$0 - stl_c $0,0($16) - beq $0,2f - br 3f -2: br 1b -3: addl $31,$0,$0 - ret $31,($26),1 - .end q_atomic_test_and_set_release_int - .align 2 - .align 4 - .globl q_atomic_test_and_set_ptr - .ent q_atomic_test_and_set_ptr -q_atomic_test_and_set_ptr: - .frame $30,0,$26,0 - .prologue 0 -1: ldq_l $0,0($16) - cmpeq $0,$17,$0 - beq $0,3f - mov $18,$0 - stq_c $0,0($16) - beq $0,2f - br 3f -2: br 1b -3: addl $31,$0,$0 - ret $31,($26),1 - .end q_atomic_test_and_set_ptr - .align 2 - .align 4 - .globl q_atomic_increment - .ent q_atomic_increment -q_atomic_increment: - .frame $30,0,$26,0 - .prologue 0 -1: ldl_l $0,0($16) - addl $0,1,$1 - stl_c $1,0($16) - beq $1,2f - br 3f -2: br 1b -3: addl $31,$0,$0 - cmpeq $0,$1,$0 - xor $0,1,$0 - ret $31,($26),1 - .end q_atomic_increment - .align 2 - .align 4 - .globl q_atomic_decrement - .ent q_atomic_decrement -q_atomic_decrement: - .frame $30,0,$26,0 - .prologue 0 -1: ldl_l $0,0($16) - subl $0,1,$1 - stl_c $1,0($16) - beq $1,2f - br 3f -2: br 1b -3: addl $31,$0,$0 - cmpeq $0,1,$0 - xor $0,1,$0 - ret $31,($26),1 - .end q_atomic_decrement - .align 2 - .align 4 - .globl q_atomic_set_int - .ent q_atomic_set_int -q_atomic_set_int: - .frame $30,0,$26,0 - .prologue 0 -1: ldl_l $0,0($16) - mov $17,$1 - stl_c $1,0($16) - beq $1,2f - br 3f -2: br 1b -3: addl $31,$0,$0 - ret $31,($26),1 - .end q_atomic_set_int - .align 2 - .align 4 - .globl q_atomic_set_ptr - .ent q_atomic_set_ptr -q_atomic_set_ptr: - .frame $30,0,$26,0 - .prologue 0 -1: ldq_l $0,0($16) - mov $17,$1 - stq_c $1,0($16) - beq $1,2f - br 3f -2: br 1b -3: ret $31,($26),1 - .end q_atomic_set_ptr - - .align 2 - .align 4 - .globl q_atomic_fetch_and_add_int - .ent q_atomic_fetch_and_add_int -q_atomic_fetch_and_add_int: - .frame $30,0,$26,0 - .prologue 0 -1: ldl_l $0,0($16) - addl $0,$17,$1 - stl_c $1,0($16) - beq $1,2f - br 3f -2: br 1b -3: addl $31,$0,$0 - ret $31,($26),1 - .end q_atomic_fetch_and_add_int - - .align 2 - .align 4 - .globl q_atomic_fetch_and_add_acquire_int - .ent q_atomic_fetch_and_add_acquire_int -q_atomic_fetch_and_add_acquire_int: - .frame $30,0,$26,0 - .prologue 0 -1: ldl_l $0,0($16) - addl $0,$17,$1 - stl_c $1,0($16) - beq $1,2f - br 3f -2: br 1b -3: mb - addl $31,$0,$0 - ret $31,($26),1 - .end q_atomic_fetch_and_add_acquire_int - - .align 2 - .align 4 - .globl q_atomic_fetch_and_add_release_int - .ent q_atomic_fetch_and_add_release_int -q_atomic_fetch_and_add_release_int: - .frame $30,0,$26,0 - .prologue 0 - mb -1: ldl_l $0,0($16) - addl $0,$17,$1 - stl_c $1,0($16) - beq $1,2f - br 3f -2: br 1b -3: addl $31,$0,$0 - ret $31,($26),1 - .end q_atomic_fetch_and_add_release_int diff --git a/src/corelib/arch/qatomic_alpha.h b/src/corelib/arch/qatomic_alpha.h index 432fb62c0a9..79546448e63 100644 --- a/src/corelib/arch/qatomic_alpha.h +++ b/src/corelib/arch/qatomic_alpha.h @@ -476,130 +476,8 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelease(qptrdiff valueTo return reinterpret_cast(old); } -#else // !Q_CC_GNU - -extern "C" { - Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval); - Q_CORE_EXPORT int q_atomic_test_and_set_acquire_int(volatile int *ptr, int expected, int newval); - Q_CORE_EXPORT int q_atomic_test_and_set_release_int(volatile int *ptr, int expected, int newval); - Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval); - Q_CORE_EXPORT int q_atomic_increment(volatile int *ptr); - Q_CORE_EXPORT int q_atomic_decrement(volatile int *ptr); - Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval); - Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, void *newval); - Q_CORE_EXPORT int q_atomic_fetch_and_add_int(volatile int *ptr, int value); - Q_CORE_EXPORT int q_atomic_fetch_and_add_acquire_int(volatile int *ptr, int value); - Q_CORE_EXPORT int q_atomic_fetch_and_add_release_int(volatile int *ptr, int value); -} // extern "C" - -inline bool QBasicAtomicInt::ref() -{ - return q_atomic_increment(&_q_value) != 0; -} - -inline bool QBasicAtomicInt::deref() -{ - return q_atomic_decrement(&_q_value) != 0; -} - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0; -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0; -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - return q_atomic_test_and_set_release_int(&_q_value, expectedValue, newValue) != 0; -} - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - return q_atomic_set_int(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - return q_atomic_fetch_and_store_acquire_int(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - return q_atomic_fetch_and_store_release_int(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - return q_atomic_fetch_and_add_int(&_q_value, valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - return q_atomic_fetch_and_add_acquire_int(&_q_value, valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - return q_atomic_fetch_and_add_release_int(&_q_value, valueToAdd); -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue) != 0; -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0; -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelease(T *expectedValue, T *newValue) -{ - return q_atomic_test_and_set_release_ptr(&_q_value, expectedValue, newValue) != 0; -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelaxed(T *newValue) -{ - return reinterpret_cast(q_atomic_set_ptr(&_q_value, newValue)); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreAcquire(T *newValue) -{ - return reinterpret_cast(q_atomic_fetch_and_store_acquire_ptr(&_q_value, newValue)); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelease(T *newValue) -{ - return reinterpret_cast(q_atomic_fetch_and_store_release_ptr(&_q_value, newValue)); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - return reinterpret_cast(q_atomic_fetch_and_add_ptr(&_q_value, newValue)); -} -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - return reinterpret_cast(q_atomic_fetch_and_add_acquire_ptr(&_q_value, newValue)); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelease(qptrdiff valueToAdd) -{ - return reinterpret_cast(q_atomic_fetch_and_add_release_ptr(&_q_value, newValue)); -} - +#else +# error "This compiler for Alpha is not supported" #endif // Q_CC_GNU inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) From 48e48f25974afbac2d54e77e92e27a23732fc2c8 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 10 Feb 2012 11:31:34 +0100 Subject: [PATCH 179/406] Remove out-of-line atomic implementation for PowerPC Only support inline assembler with GCC. Support for xlC or other compilers is not provided or tested. The files in src/corelib/arch/vxworks only supported out-of-line PowerPC, so remove it as well. The xlC compiler seems to support GNU-style inline assembly, which we prefer. Anyone wishing to support that compiler again should first test if the inline assembly (the prefered method) works. See http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/topic/com.ibm.xlcpp8l.doc/language/ref/asm.htm#asm Change-Id: I70e56c0b06428bfb6538ca5e101baebd870f92f5 Reviewed-by: Thiago Macieira --- src/corelib/arch/powerpc/arch.pri | 10 - src/corelib/arch/powerpc/qatomic32.s | 525 ------------------------ src/corelib/arch/powerpc/qatomic64.s | 533 ------------------------- src/corelib/arch/qatomic_powerpc.h | 134 +------ src/corelib/arch/vxworks/arch.pri | 6 - src/corelib/arch/vxworks/qatomic_ppc.s | 415 ------------------- 6 files changed, 1 insertion(+), 1622 deletions(-) delete mode 100644 src/corelib/arch/powerpc/arch.pri delete mode 100644 src/corelib/arch/powerpc/qatomic32.s delete mode 100644 src/corelib/arch/powerpc/qatomic64.s delete mode 100644 src/corelib/arch/vxworks/arch.pri delete mode 100644 src/corelib/arch/vxworks/qatomic_ppc.s diff --git a/src/corelib/arch/powerpc/arch.pri b/src/corelib/arch/powerpc/arch.pri deleted file mode 100644 index 1989ac73a7d..00000000000 --- a/src/corelib/arch/powerpc/arch.pri +++ /dev/null @@ -1,10 +0,0 @@ -# -# PowerPC architecture -# -!*-g++* { - *-64 { - SOURCES += $$QT_ARCH_CPP/qatomic64.s - } else { - SOURCES += $$QT_ARCH_CPP/qatomic32.s - } -} diff --git a/src/corelib/arch/powerpc/qatomic32.s b/src/corelib/arch/powerpc/qatomic32.s deleted file mode 100644 index 8e2dbe2e2f7..00000000000 --- a/src/corelib/arch/powerpc/qatomic32.s +++ /dev/null @@ -1,525 +0,0 @@ -############################################################################ -## -## Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -## Contact: http://www.qt-project.org/ -## -## This file is part of the QtGui 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$ -## -############################################################################ - .machine "ppc" - .toc - .csect .text[PR] - - .align 2 - .globl q_atomic_test_and_set_int - .globl .q_atomic_test_and_set_int - .csect q_atomic_test_and_set_int[DS],3 -q_atomic_test_and_set_int: - .long .q_atomic_test_and_set_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_test_and_set_int: - lwarx 6,0,3 - xor. 6,6,4 - bne $+12 - stwcx. 5,0,3 - bne- $-16 - subfic 3,6,0 - adde 3,3,6 - blr -LT..q_atomic_test_and_set_int: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_int-.q_atomic_test_and_set_int - .short 25 - .byte "q_atomic_test_and_set_int" - .align 2 - - .align 2 - .globl q_atomic_test_and_set_acquire_int - .globl .q_atomic_test_and_set_acquire_int - .csect q_atomic_test_and_set_acquire_int[DS],3 -q_atomic_test_and_set_acquire_int: - .long .q_atomic_test_and_set_acquire_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_test_and_set_acquire_int: - lwarx 6,0,3 - xor. 6,6,4 - bne $+16 - stwcx. 5,0,3 - bne- $-16 - isync - subfic 3,6,0 - adde 3,3,6 - blr -LT..q_atomic_test_and_set_acquire_int: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_acquire_int-.q_atomic_test_and_set_acquire_int - .short 33 - .byte "q_atomic_test_and_set_acquire_int" - .align 2 - - .align 2 - .globl q_atomic_test_and_set_release_int - .globl .q_atomic_test_and_set_release_int - .csect q_atomic_test_and_set_release_int[DS],3 -q_atomic_test_and_set_release_int: - .long .q_atomic_test_and_set_release_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_test_and_set_release_int: - eieio - lwarx 6,0,3 - xor. 6,6,4 - bne $+12 - stwcx. 5,0,3 - bne- $-16 - subfic 3,6,0 - adde 3,3,6 - blr -LT..q_atomic_test_and_set_release_int: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_release_int-.q_atomic_test_and_set_release_int - .short 33 - .byte "q_atomic_test_and_set_release_int" - .align 2 - - .align 2 - .globl q_atomic_test_and_set_ptr - .globl .q_atomic_test_and_set_ptr - .csect q_atomic_test_and_set_ptr[DS],3 -q_atomic_test_and_set_ptr: - .long .q_atomic_test_and_set_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_test_and_set_ptr: - lwarx 6,0,3 - xor. 6,6,4 - bne $+12 - stwcx. 5,0,3 - bne- $-16 - subfic 3,6,0 - adde 3,3,6 - blr -LT..q_atomic_test_and_set_ptr: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_ptr-.q_atomic_test_and_set_ptr - .short 25 - .byte "q_atomic_test_and_set_ptr" - .align 2 - - .align 2 - .globl q_atomic_test_and_set_acquire_ptr - .globl .q_atomic_test_and_set_acquire_ptr - .csect q_atomic_test_and_set_acquire_ptr[DS],3 -q_atomic_test_and_set_acquire_ptr: - .long .q_atomic_test_and_set_acquire_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_test_and_set_acquire_ptr: - lwarx 6,0,3 - xor. 6,6,4 - bne $+16 - stwcx. 5,0,3 - bne- $-16 - isync - subfic 3,6,0 - adde 3,3,6 - blr -LT..q_atomic_test_and_set_acquire_ptr: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_acquire_ptr-.q_atomic_test_and_set_acquire_ptr - .short 25 - .byte "q_atomic_test_and_set_acquire_ptr" - .align 2 - - .align 2 - .globl q_atomic_test_and_set_release_ptr - .globl .q_atomic_test_and_set_release_ptr - .csect q_atomic_test_and_set_release_ptr[DS],3 -q_atomic_test_and_set_release_ptr: - .long .q_atomic_test_and_set_release_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_test_and_set_release_ptr: - eieio - lwarx 6,0,3 - xor. 6,6,4 - bne $+12 - stwcx. 5,0,3 - bne- $-16 - subfic 3,6,0 - adde 3,3,6 - blr -LT..q_atomic_test_and_set_release_ptr: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_release_ptr-.q_atomic_test_and_set_release_ptr - .short 33 - .byte "q_atomic_test_and_set_release_ptr" - .align 2 - - .align 2 - .globl q_atomic_increment - .globl .q_atomic_increment - .csect q_atomic_increment[DS],3 -q_atomic_increment: - .long .q_atomic_increment,TOC[tc0],0 - .csect .text[PR] -.q_atomic_increment: - lwarx 4,0,3 - addi 4,4,1 - stwcx. 4,0,3 - bne- $-12 - mr 3,4 - blr -LT..q_atomic_increment: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_increment-.q_atomic_increment - .short 18 - .byte "q_atomic_increment" - .align 2 - - .align 2 - .globl q_atomic_decrement - .globl .q_atomic_decrement - .csect q_atomic_decrement[DS],3 -q_atomic_decrement: - .long .q_atomic_decrement,TOC[tc0],0 - .csect .text[PR] -.q_atomic_decrement: - lwarx 4,0,3 - subi 4,4,1 - stwcx. 4,0,3 - bne- $-12 - mr 3,4 - blr -LT..q_atomic_decrement: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_decrement-.q_atomic_decrement - .short 18 - .byte "q_atomic_decrement" - .align 2 - - .align 2 - .globl q_atomic_set_int - .globl .q_atomic_set_int - .csect q_atomic_set_int[DS],3 -q_atomic_set_int: - .long .q_atomic_set_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_set_int: - lwarx 5,0,3 - stwcx. 4,0,3 - bne- $-8 - mr 3,5 - blr -LT..q_atomic_set_int: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_set_int-.q_atomic_set_int - .short 16 - .byte "q_atomic_set_int" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_store_acquire_int - .globl .q_atomic_fetch_and_store_acquire_int - .csect q_atomic_fetch_and_store_acquire_int[DS],3 -q_atomic_fetch_and_store_acquire_int: - .long .q_atomic_fetch_and_store_acquire_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_store_acquire_int: - lwarx 5,0,3 - stwcx. 4,0,3 - bne- $-8 - isync - mr 3,5 - blr -LT..q_atomic_fetch_and_store_acquire_int: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_fetch_and_store_acquire_int-.q_atomic_fetch_and_store_acquire_int - .short 16 - .byte "q_atomic_fetch_and_store_acquire_int" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_store_release_int - .globl .q_atomic_fetch_and_store_release_int - .csect q_atomic_fetch_and_store_release_int[DS],3 -q_atomic_fetch_and_store_release_int: - .long .q_atomic_fetch_and_store_release_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_store_release_int: - eieio - lwarx 5,0,3 - stwcx. 4,0,3 - bne- $-8 - mr 3,5 - blr -LT..q_atomic_fetch_and_store_release_int: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_fetch_and_store_release_int-.q_atomic_fetch_and_store_release_int - .short 16 - .byte "q_atomic_fetch_and_store_release_int" - .align 2 - - .align 2 - .globl q_atomic_set_ptr - .globl .q_atomic_set_ptr - .csect q_atomic_set_ptr[DS],3 -q_atomic_set_ptr: - .long .q_atomic_set_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_set_ptr: - lwarx 5,0,3 - stwcx. 4,0,3 - bne- $-8 - mr 3,5 - blr -LT..q_atomic_set_ptr: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_set_ptr-.q_atomic_set_ptr - .short 16 - .byte "q_atomic_set_ptr" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_store_acquire_ptr - .globl .q_atomic_fetch_and_store_acquire_ptr - .csect q_atomic_fetch_and_store_acquire_ptr[DS],3 -q_atomic_fetch_and_store_acquire_ptr: - .long .q_atomic_fetch_and_store_acquire_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_store_acquire_ptr: - lwarx 5,0,3 - stwcx. 4,0,3 - bne- $-8 - isync - mr 3,5 - blr -LT..q_atomic_fetch_and_store_acquire_ptr: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_fetch_and_store_acquire_ptr-.q_atomic_fetch_and_store_acquire_ptr - .short 16 - .byte "q_atomic_fetch_and_store_acquire_ptr" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_store_release_ptr - .globl .q_atomic_fetch_and_store_release_ptr - .csect q_atomic_fetch_and_store_release_ptr[DS],3 -q_atomic_fetch_and_store_release_ptr: - .long .q_atomic_fetch_and_store_release_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_store_release_ptr: - eieio - lwarx 5,0,3 - stwcx. 4,0,3 - bne- $-8 - mr 3,5 - blr -LT..q_atomic_fetch_and_store_release_ptr: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_fetch_and_store_release_ptr-.q_atomic_fetch_and_store_release_ptr - .short 16 - .byte "q_atomic_fetch_and_store_release_ptr" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_int - .globl .q_atomic_fetch_and_add_int - .csect q_atomic_fetch_and_add_int[DS],3 -q_atomic_fetch_and_add_int: - .long .q_atomic_fetch_and_add_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_add_int: - lwarx 5,0,3 - add 6,4,5 - stwcx. 6,0,3 - bne- $-12 - mr 3,5 - blr -LT..q_atomic_fetch_and_add_int: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_int-.q_atomic_fetch_and_add_int - .short 18 - .byte "q_atomic_fetch_and_add_int" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_acquire_int - .globl .q_atomic_fetch_and_add_acquire_int - .csect q_atomic_fetch_and_add_acquire_int[DS],3 -q_atomic_fetch_and_add_acquire_int: - .long .q_atomic_fetch_and_add_acquire_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_add_acquire_int: - lwarx 5,0,3 - add 6,4,5 - stwcx. 6,0,3 - bne- $-12 - isync - mr 3,5 - blr -LT..q_atomic_fetch_and_add_acquire_int: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_acquire_int-.q_atomic_fetch_and_add_acquire_int - .short 18 - .byte "q_atomic_fetch_and_add_acquire_int" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_release_int - .globl .q_atomic_fetch_and_add_release_int - .csect q_atomic_fetch_and_add_release_int[DS],3 -q_atomic_fetch_and_add_release_int: - .long .q_atomic_fetch_and_add_release_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_add_release_int: - eieio - lwarx 5,0,3 - add 6,4,5 - stwcx. 6,0,3 - bne- $-12 - mr 3,5 - blr -LT..q_atomic_fetch_and_add_release_int: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_release_int-.q_atomic_fetch_and_add_release_int - .short 34 - .byte "q_atomic_fetch_and_add_release_int" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_ptr - .globl .q_atomic_fetch_and_add_ptr - .csect q_atomic_fetch_and_add_ptr[DS],3 -q_atomic_fetch_and_add_ptr: - .long .q_atomic_fetch_and_add_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_add_ptr: - lwarx 5,0,3 - add 6,4,5 - stwcx. 6,0,3 - bne- $-12 - mr 3,5 - blr -LT..q_atomic_fetch_and_add_ptr: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_ptr-.q_atomic_fetch_and_add_ptr - .short 26 - .byte "q_atomic_fetch_and_add_ptr" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_acquire_ptr - .globl .q_atomic_fetch_and_add_acquire_ptr - .csect q_atomic_fetch_and_add_acquire_ptr[DS],3 -q_atomic_fetch_and_add_acquire_ptr: - .long .q_atomic_fetch_and_add_acquire_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_add_acquire_ptr: - lwarx 5,0,3 - add 6,4,5 - stwcx. 6,0,3 - bne- $-12 - isync - mr 3,5 - blr -LT..q_atomic_fetch_and_add_acquire_ptr: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_acquire_ptr-.q_atomic_fetch_and_add_acquire_ptr - .short 34 - .byte "q_atomic_fetch_and_add_acquire_ptr" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_release_ptr - .globl .q_atomic_fetch_and_add_release_ptr - .csect q_atomic_fetch_and_add_release_ptr[DS],3 -q_atomic_fetch_and_add_release_ptr: - .long .q_atomic_fetch_and_add_release_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_add_release_ptr: - eieio - lwarx 5,0,3 - add 6,4,5 - stwcx. 6,0,3 - bne- $-12 - mr 3,5 - blr -LT..q_atomic_fetch_and_add_release_ptr: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_release_ptr-.q_atomic_fetch_and_add_release_ptr - .short 34 - .byte "q_atomic_fetch_and_add_release_ptr" - .align 2 - -_section_.text: - .csect .data[RW],3 - .long _section_.text diff --git a/src/corelib/arch/powerpc/qatomic64.s b/src/corelib/arch/powerpc/qatomic64.s deleted file mode 100644 index 84977d5a936..00000000000 --- a/src/corelib/arch/powerpc/qatomic64.s +++ /dev/null @@ -1,533 +0,0 @@ -############################################################################ -## -## Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -## Contact: http://www.qt-project.org/ -## -## This file is part of the QtGui 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$ -## -############################################################################ - .machine "ppc64" - .toc - .csect .text[PR] - - .align 2 - .globl q_atomic_test_and_set_int - .globl .q_atomic_test_and_set_int - .csect q_atomic_test_and_set_int[DS],3 -q_atomic_test_and_set_int: - .llong .q_atomic_test_and_set_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_test_and_set_int: - lwarx 6,0,3 - xor. 6,6,4 - bne $+12 - stwcx. 5,0,3 - bne- $-16 - subfic 3,6,0 - adde 3,3,6 - extsw 3,3 - blr -LT..q_atomic_test_and_set_int: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_int-.q_atomic_test_and_set_int - .short 25 - .byte "q_atomic_test_and_set_int" - .align 2 - - .align 2 - .globl q_atomic_test_and_set_acquire_int - .globl .q_atomic_test_and_set_acquire_int - .csect q_atomic_test_and_set_acquire_int[DS],3 -q_atomic_test_and_set_acquire_int: - .llong .q_atomic_test_and_set_acquire_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_test_and_set_acquire_int: - lwarx 6,0,3 - xor. 6,6,4 - bne $+16 - stwcx. 5,0,3 - bne- $-16 - isync - subfic 3,6,0 - adde 3,3,6 - extsw 3,3 - blr -LT..q_atomic_test_and_set_acquire_int: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_acquire_int-.q_atomic_test_and_set_acquire_int - .short 33 - .byte "q_atomic_test_and_set_acquire_int" - .align 2 - - .align 2 - .globl q_atomic_test_and_set_release_int - .globl .q_atomic_test_and_set_release_int - .csect q_atomic_test_and_set_release_int[DS],3 -q_atomic_test_and_set_release_int: - .llong .q_atomic_test_and_set_release_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_test_and_set_release_int: - eieio - lwarx 6,0,3 - xor. 6,6,4 - bne $+12 - stwcx. 5,0,3 - bne- $-16 - subfic 3,6,0 - adde 3,3,6 - extsw 3,3 - blr -LT..q_atomic_test_and_set_release_int: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_release_int-.q_atomic_test_and_set_release_int - .short 33 - .byte "q_atomic_test_and_set_release_int" - .align 2 - - .align 2 - .globl q_atomic_test_and_set_ptr - .globl .q_atomic_test_and_set_ptr - .csect q_atomic_test_and_set_ptr[DS],3 -q_atomic_test_and_set_ptr: - .llong .q_atomic_test_and_set_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_test_and_set_ptr: - ldarx 6,0,3 - xor. 6,6,4 - bne $+12 - stdcx. 5,0,3 - bne- $-16 - subfic 3,6,0 - adde 3,3,6 - blr -LT..q_atomic_test_and_set_ptr: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_ptr-.q_atomic_test_and_set_ptr - .short 25 - .byte "q_atomic_test_and_set_ptr" - .align 2 - - .align 2 - .globl q_atomic_test_and_set_acquire_ptr - .globl .q_atomic_test_and_set_acquire_ptr - .csect q_atomic_test_and_set_acquire_ptr[DS],3 -q_atomic_test_and_set_acquire_ptr: - .llong .q_atomic_test_and_set_acquire_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_test_and_set_acquire_ptr: - ldarx 6,0,3 - xor. 6,6,4 - bne $+16 - stdcx. 5,0,3 - bne- $-16 - isync - subfic 3,6,0 - adde 3,3,6 - blr -LT..q_atomic_test_and_set_acquire_ptr: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_acquire_ptr-.q_atomic_test_and_set_acquire_ptr - .short 33 - .byte "q_atomic_test_and_set_acquire_ptr" - .align 2 - - .align 2 - .globl q_atomic_test_and_set_release_ptr - .globl .q_atomic_test_and_set_release_ptr - .csect q_atomic_test_and_set_release_ptr[DS],3 -q_atomic_test_and_set_release_ptr: - .llong .q_atomic_test_and_set_release_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_test_and_set_release_ptr: - eieio - ldarx 6,0,3 - xor. 6,6,4 - bne $+12 - stdcx. 5,0,3 - bne- $-16 - subfic 3,6,0 - adde 3,3,6 - blr -LT..q_atomic_test_and_set_release_ptr: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_release_ptr-.q_atomic_test_and_set_release_ptr - .short 33 - .byte "q_atomic_test_and_set_release_ptr" - .align 2 - - .align 2 - .globl q_atomic_increment - .globl .q_atomic_increment - .csect q_atomic_increment[DS],3 -q_atomic_increment: - .llong .q_atomic_increment,TOC[tc0],0 - .csect .text[PR] -.q_atomic_increment: - lwarx 4,0,3 - addi 5,4,1 - extsw 4,5 - stwcx. 4,0,3 - bne- $-16 - mr 3,4 - blr -LT..q_atomic_increment: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_increment-.q_atomic_increment - .short 18 - .byte "q_atomic_increment" - .align 2 - - .align 2 - .globl q_atomic_decrement - .globl .q_atomic_decrement - .csect q_atomic_decrement[DS],3 -q_atomic_decrement: - .llong .q_atomic_decrement,TOC[tc0],0 - .csect .text[PR] -.q_atomic_decrement: - lwarx 4,0,3 - subi 5,4,1 - extsw 4,5 - stwcx. 4,0,3 - bne- $-16 - mr 3,4 - blr -LT..q_atomic_decrement: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_decrement-.q_atomic_decrement - .short 18 - .byte "q_atomic_decrement" - .align 2 - - .align 2 - .globl q_atomic_set_int - .globl .q_atomic_set_int - .csect q_atomic_set_int[DS],3 -q_atomic_set_int: - .llong .q_atomic_set_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_set_int: - lwarx 5,0,3 - stwcx. 4,0,3 - bne- $-8 - extsw 3,5 - blr -LT..q_atomic_set_int: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_set_int-.q_atomic_set_int - .short 16 - .byte "q_atomic_set_int" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_store_acquire_int - .globl .q_atomic_fetch_and_store_acquire_int - .csect q_atomic_fetch_and_store_acquire_int[DS],3 -q_atomic_fetch_and_store_acquire_int: - .llong .q_atomic_fetch_and_store_acquire_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_store_acquire_int: - lwarx 5,0,3 - stwcx. 4,0,3 - bne- $-8 - isync - extsw 3,5 - blr -LT..q_atomic_fetch_and_store_acquire_int: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_fetch_and_store_acquire_int-.q_atomic_fetch_and_store_acquire_int - .short 36 - .byte "q_atomic_fetch_and_store_acquire_int" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_store_release_int - .globl .q_atomic_fetch_and_store_release_int - .csect q_atomic_fetch_and_store_release_int[DS],3 -q_atomic_fetch_and_store_release_int: - .llong .q_atomic_fetch_and_store_release_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_store_release_int: - eieio - lwarx 5,0,3 - stwcx. 4,0,3 - bne- $-8 - extsw 3,5 - blr -LT..q_atomic_fetch_and_store_release_int: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_fetch_and_store_release_int-.q_atomic_fetch_and_store_release_int - .short 36 - .byte "q_atomic_fetch_and_store_release_int" - .align 2 - - .align 2 - .globl q_atomic_set_ptr - .globl .q_atomic_set_ptr - .csect q_atomic_set_ptr[DS],3 -q_atomic_set_ptr: - .llong .q_atomic_set_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_set_ptr: - ldarx 5,0,3 - stdcx. 4,0,3 - bne- $-8 - mr 3,5 - blr -LT..q_atomic_set_ptr: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_set_ptr-.q_atomic_set_ptr - .short 16 - .byte "q_atomic_set_ptr" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_store_acquire_ptr - .globl .q_atomic_fetch_and_store_acquire_ptr - .csect q_atomic_fetch_and_store_acquire_ptr[DS],3 -q_atomic_fetch_and_store_acquire_ptr: - .llong .q_atomic_fetch_and_store_acquire_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_store_acquire_ptr: - ldarx 5,0,3 - stdcx. 4,0,3 - bne- $-8 - isync - mr 3,5 - blr -LT..q_atomic_fetch_and_store_acquire_ptr: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_fetch_and_store_acquire_ptr-.q_atomic_fetch_and_store_acquire_ptr - .short 36 - .byte "q_atomic_fetch_and_store_acquire_ptr" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_store_release_ptr - .globl .q_atomic_fetch_and_store_release_ptr - .csect q_atomic_fetch_and_store_release_ptr[DS],3 -q_atomic_fetch_and_store_release_ptr: - .llong .q_atomic_fetch_and_store_release_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_store_release_ptr: - eieio - ldarx 5,0,3 - stdcx. 4,0,3 - bne- $-8 - mr 3,5 - blr -LT..q_atomic_fetch_and_store_release_ptr: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_fetch_and_store_release_ptr-.q_atomic_fetch_and_store_release_ptr - .short 36 - .byte "q_atomic_fetch_and_store_release_ptr" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_int - .globl .q_atomic_fetch_and_add_int - .csect q_atomic_fetch_and_add_int[DS],3 -q_atomic_fetch_and_add_int: - .llong .q_atomic_fetch_and_add_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_add_int: - lwarx 5,0,3 - add 6,4,5 - extsw 7,6 - stwcx. 7,0,3 - bne- $-16 - extsw 3,5 - blr -LT..q_atomic_fetch_and_add_int: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_int-.q_atomic_fetch_and_add_int - .short 26 - .byte "q_atomic_fetch_and_add_int" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_acquire_int - .globl .q_atomic_fetch_and_add_acquire_int - .csect q_atomic_fetch_and_add_acquire_int[DS],3 -q_atomic_fetch_and_add_acquire_int: - .llong .q_atomic_fetch_and_add_acquire_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_add_acquire_int: - lwarx 5,0,3 - add 6,4,5 - extsw 7,6 - stwcx. 7,0,3 - bne- $-16 - isync - extsw 3,5 - blr -LT..q_atomic_fetch_and_add_acquire_int: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_acquire_int-.q_atomic_fetch_and_add_acquire_int - .short 34 - .byte "q_atomic_fetch_and_add_acquire_int" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_release_int - .globl .q_atomic_fetch_and_add_release_int - .csect q_atomic_fetch_and_add_release_int[DS],3 -q_atomic_fetch_and_add_release_int: - .llong .q_atomic_fetch_and_add_release_int,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_add_release_int: - eieio - lwarx 5,0,3 - add 6,4,5 - extsw 7,6 - stwcx. 7,0,3 - bne- $-16 - extsw 3,5 - blr -LT..q_atomic_fetch_and_add_release_int: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_release_int-.q_atomic_fetch_and_add_release_int - .short 34 - .byte "q_atomic_fetch_and_add_release_int" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_ptr - .globl .q_atomic_fetch_and_add_ptr - .csect q_atomic_fetch_and_add_ptr[DS],3 -q_atomic_fetch_and_add_ptr: - .llong .q_atomic_fetch_and_add_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_add_ptr: - ldarx 5,0,3 - add 6,4,5 - stdcx. 6,0,3 - bne- $-12 - mr 3,5 - blr -LT..q_atomic_fetch_and_add_ptr: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_ptr-.q_atomic_fetch_and_add_ptr - .short 26 - .byte "q_atomic_fetch_and_add_ptr" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_acquire_ptr - .globl .q_atomic_fetch_and_add_acquire_ptr - .csect q_atomic_fetch_and_add_acquire_ptr[DS],3 -q_atomic_fetch_and_add_acquire_ptr: - .llong .q_atomic_fetch_and_add_acquire_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_add_acquire_ptr: - ldarx 5,0,3 - add 6,4,5 - stdcx. 6,0,3 - bne- $-12 - isync - mr 3,5 - blr -LT..q_atomic_fetch_and_add_acquire_ptr: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_acquire_ptr-.q_atomic_fetch_and_add_acquire_ptr - .short 34 - .byte "q_atomic_fetch_and_add_acquire_ptr" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_release_ptr - .globl .q_atomic_fetch_and_add_release_ptr - .csect q_atomic_fetch_and_add_release_ptr[DS],3 -q_atomic_fetch_and_add_release_ptr: - .llong .q_atomic_fetch_and_add_release_ptr,TOC[tc0],0 - .csect .text[PR] -.q_atomic_fetch_and_add_release_ptr: - eieio - ldarx 5,0,3 - add 6,4,5 - stdcx. 6,0,3 - bne- $-12 - mr 3,5 - blr -LT..q_atomic_fetch_and_add_release_ptr: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_release_ptr-.q_atomic_fetch_and_add_release_ptr - .short 34 - .byte "q_atomic_fetch_and_add_release_ptr" - .align 2 - -_section_.text: - .csect .data[RW],3 - .llong _section_.text diff --git a/src/corelib/arch/qatomic_powerpc.h b/src/corelib/arch/qatomic_powerpc.h index 949102748a9..f03539dcd54 100644 --- a/src/corelib/arch/qatomic_powerpc.h +++ b/src/corelib/arch/qatomic_powerpc.h @@ -473,139 +473,7 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelease(qptrdiff valueTo #undef _Q_VALUE_REGISTER_OPERAND #else - -extern "C" { - int q_atomic_test_and_set_int(volatile int *ptr, int expectedValue, int newValue); - int q_atomic_test_and_set_acquire_int(volatile int *ptr, int expectedValue, int newValue); - int q_atomic_test_and_set_release_int(volatile int *ptr, int expectedValue, int newValue); - int q_atomic_test_and_set_ptr(volatile void *ptr, void *expectedValue, void *newValue); - int q_atomic_test_and_set_acquire_ptr(volatile void *ptr, void *expectedValue, void *newValue); - int q_atomic_test_and_set_release_ptr(volatile void *ptr, void *expectedValue, void *newValue); - int q_atomic_increment(volatile int *); - int q_atomic_decrement(volatile int *); - int q_atomic_set_int(volatile int *, int); - int q_atomic_fetch_and_store_acquire_int(volatile int *ptr, int newValue); - int q_atomic_fetch_and_store_release_int(volatile int *ptr, int newValue); - void *q_atomic_set_ptr(volatile void *, void *); - int q_atomic_fetch_and_store_acquire_ptr(volatile void *ptr, void *newValue); - int q_atomic_fetch_and_store_release_ptr(volatile void *ptr, void *newValue); - int q_atomic_fetch_and_add_int(volatile int *ptr, int valueToAdd); - int q_atomic_fetch_and_add_acquire_int(volatile int *ptr, int valueToAdd); - int q_atomic_fetch_and_add_release_int(volatile int *ptr, int valueToAdd); - void *q_atomic_fetch_and_add_ptr(volatile void *ptr, qptrdiff valueToAdd); - void *q_atomic_fetch_and_add_acquire_ptr(volatile void *ptr, qptrdiff valueToAdd); - void *q_atomic_fetch_and_add_release_ptr(volatile void *ptr, qptrdiff valueToAdd); -} // extern "C" - - -inline bool QBasicAtomicInt::ref() -{ - return q_atomic_increment(&_q_value) != 0; -} - -inline bool QBasicAtomicInt::deref() -{ - return q_atomic_decrement(&_q_value) != 0; -} - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0; -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0; -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - return q_atomic_test_and_set_release_int(&_q_value, expectedValue, newValue) != 0; -} - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - return q_atomic_set_int(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - return q_atomic_fetch_and_store_acquire_int(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - return q_atomic_fetch_and_store_release_int(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - return q_atomic_fetch_and_add_int(&_q_value, valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - return q_atomic_fetch_and_add_acquire_int(&_q_value, valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - return q_atomic_fetch_and_add_release_int(&_q_value, valueToAdd); -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue) != 0; -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0; -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelease(T *expectedValue, T *newValue) -{ - return q_atomic_test_and_set_release_ptr(&_q_value, expectedValue, newValue) != 0; -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelaxed(T *newValue) -{ - return reinterpret_cast(q_atomic_set_ptr(&_q_value, newValue)); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreAcquire(T *newValue) -{ - return reinterpret_cast(q_atomic_fetch_and_store_acquire_ptr(&_q_value, newValue)); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelease(T *newValue) -{ - return reinterpret_cast(q_atomic_fetch_and_store_release_ptr(&_q_value, newValue)); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - return reinterpret_cast(q_atomic_fetch_and_add_ptr(&_q_value, valueToAdd * sizeof(T))); -} -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - return reinterpret_cast(q_atomic_fetch_and_add_acquire_ptr(&_q_value, valueToAdd * sizeof(T))); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelease(qptrdiff valueToAdd) -{ - return reinterpret_cast(q_atomic_fetch_and_add_release_ptr(&_q_value, valueToAdd * sizeof(T))); -} - +# error "This compiler for PowerPC is not supported" #endif inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) diff --git a/src/corelib/arch/vxworks/arch.pri b/src/corelib/arch/vxworks/arch.pri deleted file mode 100644 index a7686186b0e..00000000000 --- a/src/corelib/arch/vxworks/arch.pri +++ /dev/null @@ -1,6 +0,0 @@ -# -# VxWorks generic -# -*-ppc-* { - SOURCES += qatomic_ppc.s -} diff --git a/src/corelib/arch/vxworks/qatomic_ppc.s b/src/corelib/arch/vxworks/qatomic_ppc.s deleted file mode 100644 index 03971e89e8e..00000000000 --- a/src/corelib/arch/vxworks/qatomic_ppc.s +++ /dev/null @@ -1,415 +0,0 @@ - - .align 2 - .globl q_atomic_test_and_set_int - .globl .q_atomic_test_and_set_int -q_atomic_test_and_set_int: -.q_atomic_test_and_set_int: - lwarx 6,0,3 - xor. 6,6,4 - bne $+12 - stwcx. 5,0,3 - bne- $-16 - subfic 3,6,0 - adde 3,3,6 - blr -LT..q_atomic_test_and_set_int: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_int-.q_atomic_test_and_set_int - .short 25 - .byte "q_atomic_test_and_set_int" - .align 2 - - .align 2 - .globl q_atomic_test_and_set_acquire_int - .globl .q_atomic_test_and_set_acquire_int -q_atomic_test_and_set_acquire_int: -.q_atomic_test_and_set_acquire_int: - lwarx 6,0,3 - xor. 6,6,4 - bne $+16 - stwcx. 5,0,3 - bne- $-16 - isync - subfic 3,6,0 - adde 3,3,6 - blr -LT..q_atomic_test_and_set_acquire_int: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_acquire_int-.q_atomic_test_and_set_acquire_int - .short 33 - .byte "q_atomic_test_and_set_acquire_int" - .align 2 - - .align 2 - .globl q_atomic_test_and_set_release_int - .globl .q_atomic_test_and_set_release_int -q_atomic_test_and_set_release_int: -.q_atomic_test_and_set_release_int: - lwarx 6,0,3 - xor. 6,6,4 - bne $+12 - stwcx. 5,0,3 - bne- $-16 - subfic 3,6,0 - adde 3,3,6 - blr -LT..q_atomic_test_and_set_release_int: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_release_int-.q_atomic_test_and_set_release_int - .short 33 - .byte "q_atomic_test_and_set_release_int" - .align 2 - - .align 2 - .globl q_atomic_test_and_set_ptr - .globl .q_atomic_test_and_set_ptr -q_atomic_test_and_set_ptr: -.q_atomic_test_and_set_ptr: - lwarx 6,0,3 - xor. 6,6,4 - bne $+12 - stwcx. 5,0,3 - bne- $-16 - subfic 3,6,0 - adde 3,3,6 - blr -LT..q_atomic_test_and_set_ptr: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_ptr-.q_atomic_test_and_set_ptr - .short 25 - .byte "q_atomic_test_and_set_ptr" - .align 2 - - .align 2 - .globl q_atomic_test_and_set_acquire_ptr - .globl .q_atomic_test_and_set_acquire_ptr -q_atomic_test_and_set_acquire_ptr: -.q_atomic_test_and_set_acquire_ptr: - lwarx 6,0,3 - xor. 6,6,4 - bne $+16 - stwcx. 5,0,3 - bne- $-16 - isync - subfic 3,6,0 - adde 3,3,6 - blr -LT..q_atomic_test_and_set_acquire_ptr: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_acquire_ptr-.q_atomic_test_and_set_acquire_ptr - .short 25 - .byte "q_atomic_test_and_set_acquire_ptr" - .align 2 - - .align 2 - .globl q_atomic_test_and_set_release_ptr - .globl .q_atomic_test_and_set_release_ptr -q_atomic_test_and_set_release_ptr: -.q_atomic_test_and_set_release_ptr: - lwarx 6,0,3 - xor. 6,6,4 - bne $+12 - stwcx. 5,0,3 - bne- $-16 - subfic 3,6,0 - adde 3,3,6 - blr -LT..q_atomic_test_and_set_release_ptr: - .long 0 - .byte 0,9,32,64,0,0,3,0 - .long 0 - .long LT..q_atomic_test_and_set_release_ptr-.q_atomic_test_and_set_release_ptr - .short 33 - .byte "q_atomic_test_and_set_release_ptr" - .align 2 - - .align 2 - .globl q_atomic_increment - .globl .q_atomic_increment -q_atomic_increment: -.q_atomic_increment: - lwarx 4,0,3 - addi 4,4,1 - stwcx. 4,0,3 - bne- $-12 - mr 3,4 - blr -LT..q_atomic_increment: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_increment-.q_atomic_increment - .short 18 - .byte "q_atomic_increment" - .align 2 - - .align 2 - .globl q_atomic_decrement - .globl .q_atomic_decrement -q_atomic_decrement: -.q_atomic_decrement: - lwarx 4,0,3 - subi 4,4,1 - stwcx. 4,0,3 - bne- $-12 - mr 3,4 - blr -LT..q_atomic_decrement: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_decrement-.q_atomic_decrement - .short 18 - .byte "q_atomic_decrement" - .align 2 - - .align 2 - .globl q_atomic_set_int - .globl .q_atomic_set_int -q_atomic_set_int: -.q_atomic_set_int: - lwarx 5,0,3 - stwcx. 4,0,3 - bne- $-8 - mr 3,5 - blr -LT..q_atomic_set_int: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_set_int-.q_atomic_set_int - .short 16 - .byte "q_atomic_set_int" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_store_acquire_int - .globl .q_atomic_fetch_and_store_acquire_int -q_atomic_fetch_and_store_acquire_int: -.q_atomic_fetch_and_store_acquire_int: - lwarx 5,0,3 - stwcx. 4,0,3 - bne- $-8 - isync - mr 3,5 - blr -LT..q_atomic_fetch_and_store_acquire_int: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_fetch_and_store_acquire_int-.q_atomic_fetch_and_store_acquire_int - .short 16 - .byte "q_atomic_fetch_and_store_acquire_int" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_store_release_int - .globl .q_atomic_fetch_and_store_release_int -q_atomic_fetch_and_store_release_int: -.q_atomic_fetch_and_store_release_int: - lwarx 5,0,3 - stwcx. 4,0,3 - bne- $-8 - mr 3,5 - blr -LT..q_atomic_fetch_and_store_release_int: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_fetch_and_store_release_int-.q_atomic_fetch_and_store_release_int - .short 16 - .byte "q_atomic_fetch_and_store_release_int" - .align 2 - - .align 2 - .globl q_atomic_set_ptr - .globl .q_atomic_set_ptr -q_atomic_set_ptr: -.q_atomic_set_ptr: - lwarx 5,0,3 - stwcx. 4,0,3 - bne- $-8 - mr 3,5 - blr -LT..q_atomic_set_ptr: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_set_ptr-.q_atomic_set_ptr - .short 16 - .byte "q_atomic_set_ptr" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_store_acquire_ptr - .globl .q_atomic_fetch_and_store_acquire_ptr -q_atomic_fetch_and_store_acquire_ptr: -.q_atomic_fetch_and_store_acquire_ptr: - lwarx 5,0,3 - stwcx. 4,0,3 - bne- $-8 - isync - mr 3,5 - blr -LT..q_atomic_fetch_and_store_acquire_ptr: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_fetch_and_store_acquire_ptr-.q_atomic_fetch_and_store_acquire_ptr - .short 16 - .byte "q_atomic_fetch_and_store_acquire_ptr" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_store_release_ptr - .globl .q_atomic_fetch_and_store_release_ptr -q_atomic_fetch_and_store_release_ptr: -.q_atomic_fetch_and_store_release_ptr: - lwarx 5,0,3 - stwcx. 4,0,3 - bne- $-8 - mr 3,5 - blr -LT..q_atomic_fetch_and_store_release_ptr: - .long 0 - .byte 0,9,32,64,0,0,2,0 - .long 0 - .long LT..q_atomic_fetch_and_store_release_ptr-.q_atomic_fetch_and_store_release_ptr - .short 16 - .byte "q_atomic_fetch_and_store_release_ptr" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_int - .globl .q_atomic_fetch_and_add_int -q_atomic_fetch_and_add_int: -.q_atomic_fetch_and_add_int: - lwarx 5,0,3 - add 6,4,5 - stwcx. 6,0,3 - bne- $-12 - mr 3,5 - blr -LT..q_atomic_fetch_and_add_int: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_int-.q_atomic_fetch_and_add_int - .short 18 - .byte "q_atomic_fetch_and_add_int" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_acquire_int - .globl .q_atomic_fetch_and_add_acquire_int -q_atomic_fetch_and_add_acquire_int: -.q_atomic_fetch_and_add_acquire_int: - lwarx 5,0,3 - add 6,4,5 - stwcx. 6,0,3 - bne- $-12 - isync - mr 3,5 - blr -LT..q_atomic_fetch_and_add_acquire_int: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_acquire_int-.q_atomic_fetch_and_add_acquire_int - .short 18 - .byte "q_atomic_fetch_and_add_acquire_int" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_release_int - .globl .q_atomic_fetch_and_add_release_int -q_atomic_fetch_and_add_release_int: -.q_atomic_fetch_and_add_release_int: - lwarx 5,0,3 - add 6,4,5 - stwcx. 6,0,3 - bne- $-12 - mr 3,5 - blr -LT..q_atomic_fetch_and_add_release_int: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_release_int-.q_atomic_fetch_and_add_release_int - .short 34 - .byte "q_atomic_fetch_and_add_release_int" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_ptr - .globl .q_atomic_fetch_and_add_ptr -q_atomic_fetch_and_add_ptr: -.q_atomic_fetch_and_add_ptr: - lwarx 5,0,3 - add 6,4,5 - stwcx. 6,0,3 - bne- $-12 - mr 3,5 - blr -LT..q_atomic_fetch_and_add_ptr: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_ptr-.q_atomic_fetch_and_add_ptr - .short 26 - .byte "q_atomic_fetch_and_add_ptr" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_acquire_ptr - .globl .q_atomic_fetch_and_add_acquire_ptr -q_atomic_fetch_and_add_acquire_ptr: -.q_atomic_fetch_and_add_acquire_ptr: - lwarx 5,0,3 - add 6,4,5 - stwcx. 6,0,3 - bne- $-12 - isync - mr 3,5 - blr -LT..q_atomic_fetch_and_add_acquire_ptr: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_acquire_ptr-.q_atomic_fetch_and_add_acquire_ptr - .short 34 - .byte "q_atomic_fetch_and_add_acquire_ptr" - .align 2 - - .align 2 - .globl q_atomic_fetch_and_add_release_ptr - .globl .q_atomic_fetch_and_add_release_ptr -q_atomic_fetch_and_add_release_ptr: -.q_atomic_fetch_and_add_release_ptr: - lwarx 5,0,3 - add 6,4,5 - stwcx. 6,0,3 - bne- $-12 - mr 3,5 - blr -LT..q_atomic_fetch_and_add_release_ptr: - .long 0 - .byte 0,9,32,64,0,0,1,0 - .long 0 - .long LT..q_atomic_fetch_and_add_release_ptr-.q_atomic_fetch_and_add_release_ptr - .short 34 - .byte "q_atomic_fetch_and_add_release_ptr" - .align 2 - -_section_.text: - .long _section_.text From c4759d19f8428b64b46bfd1e07a5cfda2937e7d1 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 10 Feb 2012 12:18:41 +0100 Subject: [PATCH 180/406] Remove the SH atomic implementation... ... but keep SH-4a, which provides a more efficient implementation. The implementation removed here was very similar to the code removed by commit dc5388e79b71d796c1207681235cf007c39810bd. Support for SH can be provided by qatomic_gcc.h, or re-added in the future if absolutely necessary. Change-Id: Ic38b57c9513fc9c3c99ba7e102780a3939b735b9 Reviewed-by: Thiago Macieira --- src/corelib/arch/arch.pri | 1 - src/corelib/arch/qatomic_arch.h | 2 - src/corelib/arch/qatomic_sh.h | 330 ----------------------------- src/corelib/arch/sh/arch.pri | 4 - src/corelib/arch/sh/qatomic_sh.cpp | 72 ------- 5 files changed, 409 deletions(-) delete mode 100644 src/corelib/arch/qatomic_sh.h delete mode 100644 src/corelib/arch/sh/arch.pri delete mode 100644 src/corelib/arch/sh/qatomic_sh.cpp diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index 08ab17e0f4b..b94fa01309d 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -26,7 +26,6 @@ integrity:HEADERS += arch/qatomic_integrity.h arch/qatomic_mips.h \ arch/qatomic_s390.h \ arch/qatomic_x86_64.h \ - arch/qatomic_sh.h \ arch/qatomic_sh4a.h \ arch/qatomic_gcc.h \ arch/qatomic_cxx11.h diff --git a/src/corelib/arch/qatomic_arch.h b/src/corelib/arch/qatomic_arch.h index 59c8de3cdeb..140cb4702a6 100644 --- a/src/corelib/arch/qatomic_arch.h +++ b/src/corelib/arch/qatomic_arch.h @@ -64,8 +64,6 @@ QT_BEGIN_HEADER # include "QtCore/qatomic_s390.h" #elif defined(QT_ARCH_SPARC) # include "QtCore/qatomic_sparc.h" -#elif defined(QT_ARCH_SH) -# include "QtCore/qatomic_sh.h" #elif defined(QT_ARCH_SH4A) # include "QtCore/qatomic_sh4a.h" #else diff --git a/src/corelib/arch/qatomic_sh.h b/src/corelib/arch/qatomic_sh.h deleted file mode 100644 index d16aaf26b15..00000000000 --- a/src/corelib/arch/qatomic_sh.h +++ /dev/null @@ -1,330 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtCore 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 QATOMIC_SH_H -#define QATOMIC_SH_H - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return false; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return false; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return false; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return false; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isTestAndSetNative() -{ return false; } -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndStoreNative() -{ return false; } -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndAddNative() -{ return false; } -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndAddWaitFree() -{ return false; } - -extern Q_CORE_EXPORT volatile char qt_atomic_lock; -Q_CORE_EXPORT void qt_atomic_yield(int *count); - -inline int qt_atomic_tasb(volatile char *ptr) -{ - register int ret; - asm volatile("tas.b @%2\n" - "movt %0" - : "=&r"(ret), "=m"(*ptr) - : "r"(ptr) - : "cc", "memory"); - return ret; -} - -// Reference counting - -inline bool QBasicAtomicInt::ref() -{ - int count = 0; - while (qt_atomic_tasb(&qt_atomic_lock) == 0) - qt_atomic_yield(&count); - int originalValue = _q_value++; - qt_atomic_lock = 0; - return originalValue != -1; -} - -inline bool QBasicAtomicInt::deref() -{ - int count = 0; - while (qt_atomic_tasb(&qt_atomic_lock) == 0) - qt_atomic_yield(&count); - int originalValue = _q_value--; - qt_atomic_lock = 0; - return originalValue != 1; -} - -// Test and set for integers - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - bool returnValue = false; - int count = 0; - while (qt_atomic_tasb(&qt_atomic_lock) == 0) - qt_atomic_yield(&count); - if (_q_value == expectedValue) { - _q_value = newValue; - returnValue = true; - } - qt_atomic_lock = 0; - return returnValue; -} - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -// Fetch and store for integers - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - int count = 0; - while (qt_atomic_tasb(&qt_atomic_lock) == 0) - qt_atomic_yield(&count); - int originalValue = _q_value; - _q_value = newValue; - qt_atomic_lock = 0; - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -// Fetch and add for integers - -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - int count = 0; - while (qt_atomic_tasb(&qt_atomic_lock) == 0) - qt_atomic_yield(&count); - int originalValue = _q_value; - _q_value += valueToAdd; - qt_atomic_lock = 0; - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -// Test and set for pointers - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetOrdered(T *expectedValue, T *newValue) -{ - bool returnValue = false; - int count = 0; - while (qt_atomic_tasb(&qt_atomic_lock) == 0) - qt_atomic_yield(&count); - if (_q_value == expectedValue) { - _q_value = newValue; - returnValue = true; - } - qt_atomic_lock = 0; - return returnValue; -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelease(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -// Fetch and store for pointers - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreOrdered(T *newValue) -{ - int count = 0; - while (qt_atomic_tasb(&qt_atomic_lock) == 0) - qt_atomic_yield(&count); - T *originalValue = _q_value; - _q_value = newValue; - qt_atomic_lock = 0; - return originalValue; -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelaxed(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreAcquire(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelease(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -// Fetch and add for pointers - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - int count = 0; - while (qt_atomic_tasb(&qt_atomic_lock) == 0) - qt_atomic_yield(&count); - T *originalValue = (_q_value); - _q_value += valueToAdd; - qt_atomic_lock = 0; - return originalValue; -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelease(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QATOMIC_SH_H diff --git a/src/corelib/arch/sh/arch.pri b/src/corelib/arch/sh/arch.pri deleted file mode 100644 index 67fbb16c105..00000000000 --- a/src/corelib/arch/sh/arch.pri +++ /dev/null @@ -1,4 +0,0 @@ -# -# SH (Renesas SuperH) architecture -# -SOURCES += $$QT_ARCH_CPP/qatomic_sh.cpp diff --git a/src/corelib/arch/sh/qatomic_sh.cpp b/src/corelib/arch/sh/qatomic_sh.cpp deleted file mode 100644 index 5cd1b593d8c..00000000000 --- a/src/corelib/arch/sh/qatomic_sh.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtCore 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 - -#include -#ifdef _POSIX_PRIORITY_SCHEDULING -# include -#endif -#include - -QT_BEGIN_NAMESPACE - -QT_USE_NAMESPACE - -Q_CORE_EXPORT volatile char qt_atomic_lock = 0; - -Q_CORE_EXPORT void qt_atomic_yield(int *count) -{ -#ifdef _POSIX_PRIORITY_SCHEDULING - if((*count)++ < 50) { - sched_yield(); - } else -#endif - { - struct timespec tm; - tm.tv_sec = 0; - tm.tv_nsec = 2000001; - nanosleep(&tm, NULL); - *count = 0; - } -} - -QT_END_NAMESPACE From 771a3f29f96d2004d6d39740180a80ef93567cb8 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 10 Feb 2012 11:16:41 +0100 Subject: [PATCH 181/406] Remove HP PA-RISC atomic implementation. This architecture is obsolete and discontinued. Support for PA-RISC can be re-added if needed, but it would be preferred to use the GCC intrinsic support from qatomic_gcc.h (on Linux/HPPA, for example). Change-Id: I952e521a2c8c68840df0d44843b5487d5c20b135 Reviewed-by: Thiago Macieira --- src/corelib/arch/arch.pri | 1 - src/corelib/arch/parisc/arch.pri | 5 - src/corelib/arch/parisc/q_ldcw.s | 62 ---- src/corelib/arch/parisc/qatomic_parisc.cpp | 88 ----- src/corelib/arch/qatomic_arch.h | 2 - src/corelib/arch/qatomic_parisc.h | 305 ------------------ src/corelib/global/qprocessordetection.h | 6 - src/corelib/thread/qatomic.h | 12 - src/corelib/thread/qoldbasicatomic.h | 10 +- .../qsharedpointer/tst_qsharedpointer.cpp | 5 - 10 files changed, 1 insertion(+), 495 deletions(-) delete mode 100644 src/corelib/arch/parisc/arch.pri delete mode 100644 src/corelib/arch/parisc/q_ldcw.s delete mode 100644 src/corelib/arch/parisc/qatomic_parisc.cpp delete mode 100644 src/corelib/arch/qatomic_parisc.h diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index b94fa01309d..4803d6f8b02 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -14,7 +14,6 @@ integrity:HEADERS += arch/qatomic_integrity.h !wince*:!win32:!mac:HEADERS += arch/qatomic_alpha.h \ arch/qatomic_ia64.h \ - arch/qatomic_parisc.h \ arch/qatomic_sparc.h \ arch/qatomic_arch.h \ arch/qatomic_generic.h \ diff --git a/src/corelib/arch/parisc/arch.pri b/src/corelib/arch/parisc/arch.pri deleted file mode 100644 index fab2897f04d..00000000000 --- a/src/corelib/arch/parisc/arch.pri +++ /dev/null @@ -1,5 +0,0 @@ -# -# HP PA-RISC architecture -# -SOURCES += $$QT_ARCH_CPP/q_ldcw.s \ - $$QT_ARCH_CPP/qatomic_parisc.cpp diff --git a/src/corelib/arch/parisc/q_ldcw.s b/src/corelib/arch/parisc/q_ldcw.s deleted file mode 100644 index 8af2861c504..00000000000 --- a/src/corelib/arch/parisc/q_ldcw.s +++ /dev/null @@ -1,62 +0,0 @@ -;/**************************************************************************** -;** -;** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -;** Contact: http://www.qt-project.org/ -;** -;** This file is part of the QtGui 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$ -;** -;****************************************************************************/ - .SPACE $PRIVATE$ - .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31 - .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82 - .SPACE $TEXT$ - .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44 - .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY - .IMPORT $global$,DATA - .IMPORT $$dyncall,MILLICODE - .SPACE $TEXT$ - .SUBSPA $CODE$ - - .align 4 - .EXPORT q_ldcw,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR -q_ldcw - .PROC - .CALLINFO FRAME=0,CALLS,SAVE_RP - .ENTRY - ldcw 0(%r26),%r1 - bv %r0(%r2) - copy %r1,%r28 - .EXIT - .PROCEND diff --git a/src/corelib/arch/parisc/qatomic_parisc.cpp b/src/corelib/arch/parisc/qatomic_parisc.cpp deleted file mode 100644 index 5e59669b227..00000000000 --- a/src/corelib/arch/parisc/qatomic_parisc.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtCore 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 -#include - -QT_BEGIN_NAMESPACE - -QT_USE_NAMESPACE - -#define UNLOCKED {-1,-1,-1,-1} -#define UNLOCKED2 UNLOCKED,UNLOCKED -#define UNLOCKED4 UNLOCKED2,UNLOCKED2 -#define UNLOCKED8 UNLOCKED4,UNLOCKED4 -#define UNLOCKED16 UNLOCKED8,UNLOCKED8 -#define UNLOCKED32 UNLOCKED16,UNLOCKED16 -#define UNLOCKED64 UNLOCKED32,UNLOCKED32 -#define UNLOCKED128 UNLOCKED64,UNLOCKED64 -#define UNLOCKED256 UNLOCKED128,UNLOCKED128 - -// use a 4k page for locks -static int locks[256][4] = { UNLOCKED256 }; - -int *getLock(volatile void *addr) -{ return locks[qHash(const_cast(addr)) % 256]; } - -static int *align16(int *lock) -{ - ulong off = (((ulong) lock) % 16); - return off ? (int *)(ulong(lock) + 16 - off) : lock; -} - -extern "C" { - - int q_ldcw(volatile int *addr); - - void q_atomic_lock(int *lock) - { - // ldcw requires a 16-byte aligned address - volatile int *x = align16(lock); - while (q_ldcw(x) == 0) - ; - } - - void q_atomic_unlock(int *lock) - { lock[0] = lock[1] = lock[2] = lock[3] = -1; } -} - - -QT_END_NAMESPACE diff --git a/src/corelib/arch/qatomic_arch.h b/src/corelib/arch/qatomic_arch.h index 140cb4702a6..6f6d1c45a0e 100644 --- a/src/corelib/arch/qatomic_arch.h +++ b/src/corelib/arch/qatomic_arch.h @@ -56,8 +56,6 @@ QT_BEGIN_HEADER # include "QtCore/qatomic_bfin.h" #elif defined(QT_ARCH_GENERIC) # include "QtCore/qatomic_generic.h" -#elif defined(QT_ARCH_PARISC) -# include "QtCore/qatomic_parisc.h" #elif defined(QT_ARCH_POWERPC) # include "QtCore/qatomic_powerpc.h" #elif defined(QT_ARCH_S390) diff --git a/src/corelib/arch/qatomic_parisc.h b/src/corelib/arch/qatomic_parisc.h deleted file mode 100644 index 221d0e36ffa..00000000000 --- a/src/corelib/arch/qatomic_parisc.h +++ /dev/null @@ -1,305 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtCore 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 QATOMIC_PARISC_H -#define QATOMIC_PARISC_H - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return false; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return false; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return false; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return false; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isTestAndSetNative() -{ return false; } -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndStoreNative() -{ return false; } -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndAddNative() -{ return false; } -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndAddWaitFree() -{ return false; } - -extern "C" { - Q_CORE_EXPORT void q_atomic_lock(int *lock); - Q_CORE_EXPORT void q_atomic_unlock(int *lock); -} - -// Reference counting - -inline bool QBasicAtomicInt::ref() -{ - q_atomic_lock(_q_lock); - bool ret = (++_q_value != 0); - q_atomic_unlock(_q_lock); - return ret; -} - -inline bool QBasicAtomicInt::deref() -{ - q_atomic_lock(_q_lock); - bool ret = (--_q_value != 0); - q_atomic_unlock(_q_lock); - return ret; -} - -// Test-and-set for integers - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - q_atomic_lock(_q_lock); - if (_q_value == expectedValue) { - _q_value = newValue; - q_atomic_unlock(_q_lock); - return true; - } - q_atomic_unlock(_q_lock); - return false; -} - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -// Fetch-and-store for integers - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - q_atomic_lock(_q_lock); - int returnValue = _q_value; - _q_value = newValue; - q_atomic_unlock(_q_lock); - return returnValue; -} - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -// Fetch-and-add for integers - -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - q_atomic_lock(_q_lock); - int originalValue = _q_value; - _q_value += valueToAdd; - q_atomic_unlock(_q_lock); - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -// Test and set for pointers - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetOrdered(T *expectedValue, T *newValue) -{ - q_atomic_lock(_q_lock); - if (_q_value == expectedValue) { - _q_value = newValue; - q_atomic_unlock(_q_lock); - return true; - } - q_atomic_unlock(_q_lock); - return false; -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelease(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -// Fetch and store for pointers - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreOrdered(T *newValue) -{ - q_atomic_lock(_q_lock); - T *returnValue = (_q_value); - _q_value = newValue; - q_atomic_unlock(_q_lock); - return returnValue; -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelaxed(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreAcquire(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelease(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -// Fetch and add for pointers - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - q_atomic_lock(_q_lock); - T *returnValue = (_q_value); - _q_value += valueToAdd; - q_atomic_unlock(_q_lock); - return returnValue; -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelease(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QATOMIC_PARISC_H diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h index dc219e7321a..bec070747f5 100644 --- a/src/corelib/global/qprocessordetection.h +++ b/src/corelib/global/qprocessordetection.h @@ -141,12 +141,6 @@ # define Q_PROCESSOR_MIPS_64 # endif -/* - PA-RISC family, no revisions or variants -*/ -// #elif defined(__parisc__) -// # define Q_PROCESSOR_PARISC - /* POWER family, optional variant: 64-bit diff --git a/src/corelib/thread/qatomic.h b/src/corelib/thread/qatomic.h index b75ae94429b..94cef790db1 100644 --- a/src/corelib/thread/qatomic.h +++ b/src/corelib/thread/qatomic.h @@ -63,17 +63,11 @@ public: // Non-atomic API inline QAtomicInt(int value = 0) { -#ifdef QT_ARCH_PARISC - this->_q_lock[0] = this->_q_lock[1] = this->_q_lock[2] = this->_q_lock[3] = -1; -#endif _q_value = value; } inline QAtomicInt(const QAtomicInt &other) { -#ifdef QT_ARCH_PARISC - this->_q_lock[0] = this->_q_lock[1] = this->_q_lock[2] = this->_q_lock[3] = -1; -#endif store(other.load()); } @@ -123,16 +117,10 @@ class QAtomicPointer : public QBasicAtomicPointer public: inline QAtomicPointer(T *value = 0) { -#ifdef QT_ARCH_PARISC - this->_q_lock[0] = this->_q_lock[1] = this->_q_lock[2] = this->_q_lock[3] = -1; -#endif this->store(value); } inline QAtomicPointer(const QAtomicPointer &other) { -#ifdef QT_ARCH_PARISC - this->_q_lock[0] = this->_q_lock[1] = this->_q_lock[2] = this->_q_lock[3] = -1; -#endif this->store(other.load()); } diff --git a/src/corelib/thread/qoldbasicatomic.h b/src/corelib/thread/qoldbasicatomic.h index 4697da63019..2bd62f69426 100644 --- a/src/corelib/thread/qoldbasicatomic.h +++ b/src/corelib/thread/qoldbasicatomic.h @@ -61,9 +61,6 @@ QT_END_HEADER class Q_CORE_EXPORT QBasicAtomicInt { public: -#ifdef QT_ARCH_PARISC - int _q_lock[4]; -#endif #if defined(QT_ARCH_WINDOWS) || defined(QT_ARCH_WINDOWSCE) union { // needed for Q_BASIC_ATOMIC_INITIALIZER volatile long _q_value; @@ -114,9 +111,6 @@ template class QBasicAtomicPointer { public: -#ifdef QT_ARCH_PARISC - int _q_lock[4]; -#endif #if defined(QT_ARCH_WINDOWS) || defined(QT_ARCH_WINDOWSCE) union { T * volatile _q_value; @@ -163,9 +157,7 @@ public: T *fetchAndAddOrdered(qptrdiff valueToAdd); }; -#ifdef QT_ARCH_PARISC -# define Q_BASIC_ATOMIC_INITIALIZER(a) {{-1,-1,-1,-1},(a)} -#elif defined(QT_ARCH_WINDOWS) || defined(QT_ARCH_WINDOWSCE) +#if defined(QT_ARCH_WINDOWS) || defined(QT_ARCH_WINDOWSCE) # define Q_BASIC_ATOMIC_INITIALIZER(a) { {(a)} } #else # define Q_BASIC_ATOMIC_INITIALIZER(a) { (a) } diff --git a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp index 6dae58a006b..5b697a35098 100644 --- a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp @@ -1093,10 +1093,6 @@ void tst_QSharedPointer::constCorrectness() ptr = cptr.constCast(); ptr = vptr.constCast(); -#if !defined(Q_CC_HPACC) && !defined(QT_ARCH_PARISC) - // the aCC series 3 compiler we have on the PA-RISC - // machine crashes compiling this code - QSharedPointer cvptr(ptr); QSharedPointer cvptr2(cptr); QSharedPointer cvptr3(vptr); @@ -1105,7 +1101,6 @@ void tst_QSharedPointer::constCorrectness() cvptr3 = vptr; ptr = qSharedPointerConstCast(cvptr); ptr = cvptr.constCast(); -#endif } safetyCheck(); From d4441b014803e782abcd9ab598df5035f0ff58ed Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 13 Feb 2012 10:32:40 +0100 Subject: [PATCH 182/406] Fix qmake compilation No need to error out in bootstrapped mode because we don't use -fPIC Change-Id: I0cc2889c75b41968edfd8e801b9161a1eb63f6ef Reviewed-by: Thiago Macieira --- src/corelib/global/qglobal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index ffeb8a2bab1..0e4509362fe 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1784,7 +1784,7 @@ Q_CORE_EXPORT int qrand(); # endif #endif -#if defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && !defined(__PIC__) +#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && !defined(__PIC__) # error "You must build your code with position independent code if Qt was built with -reduce-relocations. "\ "Compile your code with -fPIC or -fPIE." #endif From 23688d8942895507f4bc1517dd3c161134f4f9d0 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 10 Feb 2012 15:54:50 +0100 Subject: [PATCH 183/406] Reshuffle code between qglobal, qlogging Make the content of the .h, .cpp files match. Change-Id: Ib2506aeff74281ec4bcbf04d21da451038391203 Reviewed-by: David Faure --- src/corelib/global/qglobal.cpp | 467 -------------------------------- src/corelib/global/qglobal.h | 4 - src/corelib/global/qlogging.cpp | 465 ++++++++++++++++++++++++++++++- src/corelib/global/qlogging.h | 14 +- 4 files changed, 473 insertions(+), 477 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 983116f1b35..58a3a6b7fd9 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -45,15 +45,12 @@ #include "qlist.h" #include "qthreadstorage.h" #include "qdir.h" -#include "qstringlist.h" #include "qdatetime.h" -#include "qdebug.h" #ifndef QT_NO_QOBJECT #include #endif -#include #include #include #include @@ -677,34 +674,6 @@ QT_BEGIN_NAMESPACE \sa quintptr, qint32, qint64 */ -/*! - \typedef QtMsgHandler - \relates - \deprecated - - This is a typedef for a pointer to a function with the following - signature: - - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 7 - - This typedef is deprecated, you should use QMessageHandler instead. - \sa QtMsgType, QMessageHandler, qInstallMsgHandler(), qInstallMessageHandler() -*/ - -/*! - \typedef QMessageHandler - \relates - \since 5.0 - - This is a typedef for a pointer to a function with the following - signature: - - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 49 - - \sa QtMsgType, qInstallMessageHandler() -*/ - - /*! \enum QtMsgType \relates @@ -1726,9 +1695,6 @@ Q_CORE_EXPORT unsigned int qt_int_sqrt(unsigned int n) void *qMemCopy(void *dest, const void *src, size_t n) { return memcpy(dest, src, n); } void *qMemSet(void *dest, int c, size_t n) { return memset(dest, c, n); } -static QtMsgHandler msgHandler = 0; // pointer to debug handler (without context) -static QMessageHandler messageHandler = 0; // pointer to debug handler (with context) - #if !defined(Q_OS_WIN) && !defined(QT_NO_THREAD) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX) && \ defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L namespace { @@ -1808,439 +1774,6 @@ QString qt_error_string(int errorCode) return ret.trimmed(); } -/*! - \fn QtMsgHandler qInstallMsgHandler(QtMsgHandler handler) - \relates - \deprecated - - Installs a Qt message \a handler which has been defined - previously. This method is deprecated, use qInstallMessageHandler - instead. - - \sa QtMsgHandler, qInstallMessageHandler -*/ - -/*! - \fn QMessageHandler qInstallMessageHandler(QMessageHandler handler) - \relates - \since 5.0 - - Installs a Qt message \a handler which has been defined - previously. Returns a pointer to the previous message handler - (which may be 0). - - The message handler is a function that prints out debug messages, - warnings, critical and fatal error messages. The Qt library (debug - mode) contains hundreds of warning messages that are printed - when internal errors (usually invalid function arguments) - occur. Qt built in release mode also contains such warnings unless - QT_NO_WARNING_OUTPUT and/or QT_NO_DEBUG_OUTPUT have been set during - compilation. If you implement your own message handler, you get total - control of these messages. - - The default message handler prints the message to the standard - output under X11 or to the debugger under Windows. If it is a - fatal message, the application aborts immediately. - - Only one message handler can be defined, since this is usually - done on an application-wide basis to control debug output. - - To restore the message handler, call \c qInstallMessageHandler(0). - - Example: - - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 23 - - \sa qDebug(), qWarning(), qCritical(), qFatal(), QtMsgType, - {Debugging Techniques} -*/ - -#if defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB) -extern bool usingWinMain; -extern Q_CORE_EXPORT void qWinMsgHandler(QtMsgType t, const char *str); -extern Q_CORE_EXPORT void qWinMessageHandler(QtMsgType t, const QMessageLogContext &context, - const char *str); -#endif - -// defined in qlogging.cpp -extern Q_CORE_EXPORT QByteArray qMessageFormatString(QtMsgType type, const QMessageLogContext &context, - const char *str); - -/*! - \internal -*/ -static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &context, const char *buf) -{ - QByteArray logMessage = qMessageFormatString(type, context, buf); -#if defined(Q_OS_WINCE) - QString fstr = QString::fromLocal8Bit(logMessage); - OutputDebugString(reinterpret_cast (fstr.utf16())); -#else - fprintf(stderr, "%s", logMessage.constData()); - fflush(stderr); -#endif -} - -/*! - \internal -*/ -static void qDefaultMsgHandler(QtMsgType type, const char *buf) -{ - QMessageLogContext emptyContext; - qDefaultMessageHandler(type, emptyContext, buf); -} - -QMessageHandler qInstallMessageHandler(QMessageHandler h) -{ - if (!messageHandler) - messageHandler = qDefaultMessageHandler; - QMessageHandler old = messageHandler; - messageHandler = h; -#if defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB) - if (!messageHandler && usingWinMain) - messageHandler = qWinMessageHandler; -#endif - return old; -} - -QtMsgHandler qInstallMsgHandler(QtMsgHandler h) -{ - //if handler is 0, set it to the - //default message handler - if (!msgHandler) - msgHandler = qDefaultMsgHandler; - QtMsgHandler old = msgHandler; - msgHandler = h; -#if defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB) - if (!msgHandler && usingWinMain) - msgHandler = qWinMsgHandler; -#endif - return old; -} - -/*! - \internal -*/ -void qt_message_output(QtMsgType msgType, const QMessageLogContext &context, const char *buf) -{ - if (!msgHandler) - msgHandler = qDefaultMsgHandler; - if (!messageHandler) - messageHandler = qDefaultMessageHandler; - - // prefer new message handler over the old one - if (msgHandler == qDefaultMsgHandler - || messageHandler != qDefaultMessageHandler) { - (*messageHandler)(msgType, context, buf); - } else { - (*msgHandler)(msgType, buf); - } - - if (msgType == QtFatalMsg - || (msgType == QtWarningMsg - && (!qgetenv("QT_FATAL_WARNINGS").isNull())) ) { - -#if defined(Q_CC_MSVC) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR) - // get the current report mode - int reportMode = _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW); - _CrtSetReportMode(_CRT_ERROR, reportMode); -#if !defined(Q_OS_WINCE) - int ret = _CrtDbgReport(_CRT_ERROR, __FILE__, __LINE__, QT_VERSION_STR, buf); -#else - int ret = _CrtDbgReportW(_CRT_ERROR, _CRT_WIDE(__FILE__), - __LINE__, _CRT_WIDE(QT_VERSION_STR), reinterpret_cast (QString::fromLatin1(buf).utf16())); -#endif - if (ret == 0 && reportMode & _CRTDBG_MODE_WNDW) - return; // ignore - else if (ret == 1) - _CrtDbgBreak(); -#endif - -#if (defined(Q_OS_UNIX) || defined(Q_CC_MINGW)) - abort(); // trap; generates core dump -#else - exit(1); // goodbye cruel world -#endif - } -} - -#if !defined(QT_NO_EXCEPTIONS) -/*! - \internal - Uses a local buffer to output the message. Not locale safe + cuts off - everything after character 255, but will work in out of memory situations. -*/ -static void qEmergencyOut(QtMsgType msgType, const char *msg, va_list ap) -{ - char emergency_buf[256] = { '\0' }; - emergency_buf[255] = '\0'; - if (msg) - qvsnprintf(emergency_buf, 255, msg, ap); - QMessageLogContext context; - qt_message_output(msgType, context, emergency_buf); -} -#endif - -/*! - \internal -*/ -static void qt_message(QtMsgType msgType, const QMessageLogContext &context, const char *msg, va_list ap) -{ -#if !defined(QT_NO_EXCEPTIONS) - if (std::uncaught_exception()) { - qEmergencyOut(msgType, msg, ap); - return; - } -#endif - QByteArray buf; - if (msg) { - QT_TRY { - buf = QString().vsprintf(msg, ap).toLocal8Bit(); - } QT_CATCH(const std::bad_alloc &) { -#if !defined(QT_NO_EXCEPTIONS) - qEmergencyOut(msgType, msg, ap); - // don't rethrow - we use qWarning and friends in destructors. - return; -#endif - } - } - qt_message_output(msgType, context, buf.constData()); -} - -#undef qDebug -/*! - \fn qDebug(const char *message, ...) - \relates - - Calls the message handler with the debug message \a msg. If no - message handler has been installed, the message is printed to - stderr. Under Windows, the message is sent to the console, if it is a - console application; otherwise, it is sent to the debugger. This - function does nothing if \c QT_NO_DEBUG_OUTPUT was defined - during compilation. - - If you pass the function a format string and a list of arguments, - it works in similar way to the C printf() function. The format - should be a Latin-1 string. - - Example: - - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 24 - - If you include \c , a more convenient syntax is also - available: - - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 25 - - With this syntax, the function returns a QDebug object that is - configured to use the QtDebugMsg message type. It automatically - puts a single space between each item, and outputs a newline at - the end. It supports many C++ and Qt types. - - To suppress the output at run-time, install your own message handler - with qInstallMessageHandler(). - - \sa qWarning(), qCritical(), qFatal(), qInstallMessageHandler(), - {Debugging Techniques} -*/ - -void QMessageLogger::debug(const char *msg, ...) -{ - va_list ap; - va_start(ap, msg); // use variable arg list - qt_message(QtDebugMsg, context, msg, ap); - va_end(ap); -} - -#ifndef QT_NO_DEBUG_STREAM - -QDebug QMessageLogger::debug() -{ - QDebug dbg = QDebug(QtDebugMsg); - QMessageLogContext &ctxt = dbg.stream->context; - ctxt.file = context.file; - ctxt.line = context.line; - ctxt.function = context.function; - return dbg; -} - -QNoDebug QMessageLogger::noDebug() -{ - return QNoDebug(); -} - -#endif - -#undef qWarning -/*! - \fn qWarning(const char *message, ...) - \relates - - Calls the message handler with the warning message \a msg. If no - message handler has been installed, the message is printed to - stderr. Under Windows, the message is sent to the debugger. This - function does nothing if \c QT_NO_WARNING_OUTPUT was defined - during compilation; it exits if the environment variable \c - QT_FATAL_WARNINGS is defined. - - This function takes a format string and a list of arguments, - similar to the C printf() function. The format should be a Latin-1 - string. - - Example: - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 26 - - If you include , a more convenient syntax is - also available: - - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 27 - - This syntax inserts a space between each item, and - appends a newline at the end. - - To suppress the output at runtime, install your own message handler - with qInstallMessageHandler(). - - \sa qDebug(), qCritical(), qFatal(), qInstallMessageHandler(), - {Debugging Techniques} -*/ - -void QMessageLogger::warning(const char *msg, ...) -{ - va_list ap; - va_start(ap, msg); // use variable arg list - qt_message(QtWarningMsg, context, msg, ap); - va_end(ap); -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug QMessageLogger::warning() -{ - QDebug dbg = QDebug(QtWarningMsg); - QMessageLogContext &ctxt = dbg.stream->context; - ctxt.file = context.file; - ctxt.line = context.line; - ctxt.function = context.function; - return dbg; -} -#endif - -#undef qCritical -/*! - \fn qCritical(const char *message, ...) - \relates - - Calls the message handler with the critical message \a msg. If no - message handler has been installed, the message is printed to - stderr. Under Windows, the message is sent to the debugger. - - This function takes a format string and a list of arguments, - similar to the C printf() function. The format should be a Latin-1 - string. - - Example: - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 28 - - If you include , a more convenient syntax is - also available: - - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 29 - - A space is inserted between the items, and a newline is - appended at the end. - - To suppress the output at runtime, install your own message handler - with qInstallMessageHandler(). - - \sa qDebug(), qWarning(), qFatal(), qInstallMessageHandler(), - {Debugging Techniques} -*/ - -void QMessageLogger::critical(const char *msg, ...) -{ - va_list ap; - va_start(ap, msg); // use variable arg list - qt_message(QtCriticalMsg, context, msg, ap); - va_end(ap); -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug QMessageLogger::critical() -{ - QDebug dbg = QDebug(QtCriticalMsg); - QMessageLogContext &ctxt = dbg.stream->context; - ctxt.file = context.file; - ctxt.line = context.line; - ctxt.function = context.function; - return dbg; -} -#endif - -void qErrnoWarning(const char *msg, ...) -{ - // qt_error_string() will allocate anyway, so we don't have - // to be careful here (like we do in plain qWarning()) - QString buf; - va_list ap; - va_start(ap, msg); - if (msg) - buf.vsprintf(msg, ap); - va_end(ap); - - QMessageLogger().critical("%s (%s)", buf.toLocal8Bit().constData(), - qt_error_string(-1).toLocal8Bit().constData()); -} - -void qErrnoWarning(int code, const char *msg, ...) -{ - // qt_error_string() will allocate anyway, so we don't have - // to be careful here (like we do in plain qWarning()) - QString buf; - va_list ap; - va_start(ap, msg); - if (msg) - buf.vsprintf(msg, ap); - va_end(ap); - - QMessageLogger().critical("%s (%s)", buf.toLocal8Bit().constData(), - qt_error_string(code).toLocal8Bit().constData()); -} - -#undef qFatal -/*! - \fn qFatal(const char *message, ...) - \relates - - Calls the message handler with the fatal message \a msg. If no - message handler has been installed, the message is printed to - stderr. Under Windows, the message is sent to the debugger. - - If you are using the \bold{default message handler} this function will - abort on Unix systems to create a core dump. On Windows, for debug builds, - this function will report a _CRT_ERROR enabling you to connect a debugger - to the application. - - This function takes a format string and a list of arguments, - similar to the C printf() function. - - Example: - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 30 - - To suppress the output at runtime, install your own message handler - with qInstallMessageHandler(). - - \sa qDebug(), qCritical(), qWarning(), qInstallMessageHandler(), - {Debugging Techniques} -*/ - -void QMessageLogger::fatal(const char *msg, ...) -{ - va_list ap; - va_start(ap, msg); // use variable arg list - qt_message(QtFatalMsg, context, msg, ap); - va_end(ap); -} - // getenv is declared as deprecated in VS2005. This function // makes use of the new secure getenv function. /*! diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 0e4509362fe..456624071c2 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -992,10 +992,6 @@ inline void qUnused(T &x) { (void)x; } class QString; Q_CORE_EXPORT QString qt_error_string(int errorCode = -1); - -Q_CORE_EXPORT void qErrnoWarning(int code, const char *msg, ...); -Q_CORE_EXPORT void qErrnoWarning(const char *msg, ...); - Q_CORE_EXPORT void qt_assert(const char *assertion, const char *file, int line); #if !defined(Q_ASSERT) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 164b8460741..8a75f5a9eaf 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -44,6 +44,7 @@ #include "qbytearray.h" #include "qstring.h" #include "qvarlengtharray.h" +#include "qdebug.h" #include @@ -79,6 +80,254 @@ QT_BEGIN_NAMESPACE \sa QMessageLogContext, qDebug(), qWarning(), qCritical(), qFatal() */ +#if !defined(QT_NO_EXCEPTIONS) +/*! + \internal + Uses a local buffer to output the message. Not locale safe + cuts off + everything after character 255, but will work in out of memory situations. +*/ +static void qEmergencyOut(QtMsgType msgType, const char *msg, va_list ap) +{ + char emergency_buf[256] = { '\0' }; + emergency_buf[255] = '\0'; + if (msg) + qvsnprintf(emergency_buf, 255, msg, ap); + QMessageLogContext context; + qt_message_output(msgType, context, emergency_buf); +} +#endif + +/*! + \internal +*/ +static void qt_message(QtMsgType msgType, const QMessageLogContext &context, const char *msg, + va_list ap) +{ +#if !defined(QT_NO_EXCEPTIONS) + if (std::uncaught_exception()) { + qEmergencyOut(msgType, msg, ap); + return; + } +#endif + QByteArray buf; + if (msg) { + QT_TRY { + buf = QString().vsprintf(msg, ap).toLocal8Bit(); + } QT_CATCH(const std::bad_alloc &) { +#if !defined(QT_NO_EXCEPTIONS) + qEmergencyOut(msgType, msg, ap); + // don't rethrow - we use qWarning and friends in destructors. + return; +#endif + } + } + qt_message_output(msgType, context, buf.constData()); +} + +#undef qDebug +/*! + \fn qDebug(const char *message, ...) + \relates + + Calls the message handler with the debug message \a msg. If no + message handler has been installed, the message is printed to + stderr. Under Windows, the message is sent to the console, if it is a + console application; otherwise, it is sent to the debugger. This + function does nothing if \c QT_NO_DEBUG_OUTPUT was defined + during compilation. + + If you pass the function a format string and a list of arguments, + it works in similar way to the C printf() function. The format + should be a Latin-1 string. + + Example: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 24 + + If you include \c , a more convenient syntax is also + available: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 25 + + With this syntax, the function returns a QDebug object that is + configured to use the QtDebugMsg message type. It automatically + puts a single space between each item, and outputs a newline at + the end. It supports many C++ and Qt types. + + To suppress the output at run-time, install your own message handler + with qInstallMessageHandler(). + + \sa qWarning(), qCritical(), qFatal(), qInstallMessageHandler(), + {Debugging Techniques} +*/ + +void QMessageLogger::debug(const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); // use variable arg list + qt_message(QtDebugMsg, context, msg, ap); + va_end(ap); +} + +#ifndef QT_NO_DEBUG_STREAM + +QDebug QMessageLogger::debug() +{ + QDebug dbg = QDebug(QtDebugMsg); + QMessageLogContext &ctxt = dbg.stream->context; + ctxt.file = context.file; + ctxt.line = context.line; + ctxt.function = context.function; + return dbg; +} + +QNoDebug QMessageLogger::noDebug() +{ + return QNoDebug(); +} + +#endif + +#undef qWarning +/*! + \fn qWarning(const char *message, ...) + \relates + + Calls the message handler with the warning message \a msg. If no + message handler has been installed, the message is printed to + stderr. Under Windows, the message is sent to the debugger. This + function does nothing if \c QT_NO_WARNING_OUTPUT was defined + during compilation; it exits if the environment variable \c + QT_FATAL_WARNINGS is defined. + + This function takes a format string and a list of arguments, + similar to the C printf() function. The format should be a Latin-1 + string. + + Example: + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 26 + + If you include , a more convenient syntax is + also available: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 27 + + This syntax inserts a space between each item, and + appends a newline at the end. + + To suppress the output at runtime, install your own message handler + with qInstallMessageHandler(). + + \sa qDebug(), qCritical(), qFatal(), qInstallMessageHandler(), + {Debugging Techniques} +*/ + +void QMessageLogger::warning(const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); // use variable arg list + qt_message(QtWarningMsg, context, msg, ap); + va_end(ap); +} + +#ifndef QT_NO_DEBUG_STREAM +QDebug QMessageLogger::warning() +{ + QDebug dbg = QDebug(QtWarningMsg); + QMessageLogContext &ctxt = dbg.stream->context; + ctxt.file = context.file; + ctxt.line = context.line; + ctxt.function = context.function; + return dbg; +} +#endif + +#undef qCritical +/*! + \fn qCritical(const char *message, ...) + \relates + + Calls the message handler with the critical message \a msg. If no + message handler has been installed, the message is printed to + stderr. Under Windows, the message is sent to the debugger. + + This function takes a format string and a list of arguments, + similar to the C printf() function. The format should be a Latin-1 + string. + + Example: + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 28 + + If you include , a more convenient syntax is + also available: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 29 + + A space is inserted between the items, and a newline is + appended at the end. + + To suppress the output at runtime, install your own message handler + with qInstallMessageHandler(). + + \sa qDebug(), qWarning(), qFatal(), qInstallMessageHandler(), + {Debugging Techniques} +*/ + +void QMessageLogger::critical(const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); // use variable arg list + qt_message(QtCriticalMsg, context, msg, ap); + va_end(ap); +} + +#ifndef QT_NO_DEBUG_STREAM +QDebug QMessageLogger::critical() +{ + QDebug dbg = QDebug(QtCriticalMsg); + QMessageLogContext &ctxt = dbg.stream->context; + ctxt.file = context.file; + ctxt.line = context.line; + ctxt.function = context.function; + return dbg; +} +#endif + +#undef qFatal +/*! + \fn qFatal(const char *message, ...) + \relates + + Calls the message handler with the fatal message \a msg. If no + message handler has been installed, the message is printed to + stderr. Under Windows, the message is sent to the debugger. + + If you are using the \bold{default message handler} this function will + abort on Unix systems to create a core dump. On Windows, for debug builds, + this function will report a _CRT_ERROR enabling you to connect a debugger + to the application. + + This function takes a format string and a list of arguments, + similar to the C printf() function. + + Example: + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 30 + + To suppress the output at runtime, install your own message handler + with qInstallMessageHandler(). + + \sa qDebug(), qCritical(), qWarning(), qInstallMessageHandler(), + {Debugging Techniques} +*/ + +void QMessageLogger::fatal(const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); // use variable arg list + qt_message(QtFatalMsg, context, msg, ap); + va_end(ap); +} + /*! \internal */ @@ -345,7 +594,7 @@ Q_GLOBAL_STATIC(QMessagePattern, qMessagePattern) \internal */ Q_CORE_EXPORT QByteArray qMessageFormatString(QtMsgType type, const QMessageLogContext &context, - const char *str) + const char *str) { QByteArray message; @@ -389,4 +638,218 @@ Q_CORE_EXPORT QByteArray qMessageFormatString(QtMsgType type, const QMessageLogC return message; } +static QtMsgHandler msgHandler = 0; // pointer to debug handler (without context) +static QMessageHandler messageHandler = 0; // pointer to debug handler (with context) + +/*! + \internal +*/ +static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &context, + const char *buf) +{ + QByteArray logMessage = qMessageFormatString(type, context, buf); +#if defined(Q_OS_WINCE) + QString fstr = QString::fromLocal8Bit(logMessage); + OutputDebugString(reinterpret_cast (fstr.utf16())); +#else + fprintf(stderr, "%s", logMessage.constData()); + fflush(stderr); +#endif +} + +/*! + \internal +*/ +static void qDefaultMsgHandler(QtMsgType type, const char *buf) +{ + QMessageLogContext emptyContext; + qDefaultMessageHandler(type, emptyContext, buf); +} + +/*! + \internal +*/ +void qt_message_output(QtMsgType msgType, const QMessageLogContext &context, const char *buf) +{ + if (!msgHandler) + msgHandler = qDefaultMsgHandler; + if (!messageHandler) + messageHandler = qDefaultMessageHandler; + + // prefer new message handler over the old one + if (msgHandler == qDefaultMsgHandler + || messageHandler != qDefaultMessageHandler) { + (*messageHandler)(msgType, context, buf); + } else { + (*msgHandler)(msgType, buf); + } + + if (msgType == QtFatalMsg + || (msgType == QtWarningMsg + && (!qgetenv("QT_FATAL_WARNINGS").isNull())) ) { + +#if defined(Q_CC_MSVC) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR) + // get the current report mode + int reportMode = _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW); + _CrtSetReportMode(_CRT_ERROR, reportMode); +#if !defined(Q_OS_WINCE) + int ret = _CrtDbgReport(_CRT_ERROR, __FILE__, __LINE__, QT_VERSION_STR, buf); +#else + int ret = _CrtDbgReportW(_CRT_ERROR, _CRT_WIDE(__FILE__), + __LINE__, _CRT_WIDE(QT_VERSION_STR), + reinterpret_cast ( + QString::fromLatin1(buf).utf16())); +#endif + if (ret == 0 && reportMode & _CRTDBG_MODE_WNDW) + return; // ignore + else if (ret == 1) + _CrtDbgBreak(); +#endif + +#if (defined(Q_OS_UNIX) || defined(Q_CC_MINGW)) + abort(); // trap; generates core dump +#else + exit(1); // goodbye cruel world +#endif + } +} + +void qErrnoWarning(const char *msg, ...) +{ + // qt_error_string() will allocate anyway, so we don't have + // to be careful here (like we do in plain qWarning()) + QString buf; + va_list ap; + va_start(ap, msg); + if (msg) + buf.vsprintf(msg, ap); + va_end(ap); + + QMessageLogger().critical("%s (%s)", buf.toLocal8Bit().constData(), + qt_error_string(-1).toLocal8Bit().constData()); +} + +void qErrnoWarning(int code, const char *msg, ...) +{ + // qt_error_string() will allocate anyway, so we don't have + // to be careful here (like we do in plain qWarning()) + QString buf; + va_list ap; + va_start(ap, msg); + if (msg) + buf.vsprintf(msg, ap); + va_end(ap); + + QMessageLogger().critical("%s (%s)", buf.toLocal8Bit().constData(), + qt_error_string(code).toLocal8Bit().constData()); +} + +#if defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB) +extern bool usingWinMain; +extern Q_CORE_EXPORT void qWinMsgHandler(QtMsgType t, const char *str); +extern Q_CORE_EXPORT void qWinMessageHandler(QtMsgType t, const QMessageLogContext &context, + const char *str); +#endif + +/*! + \typedef QtMsgHandler + \relates + \deprecated + + This is a typedef for a pointer to a function with the following + signature: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 7 + + This typedef is deprecated, you should use QMessageHandler instead. + \sa QtMsgType, QMessageHandler, qInstallMsgHandler(), qInstallMessageHandler() +*/ + +/*! + \typedef QMessageHandler + \relates + \since 5.0 + + This is a typedef for a pointer to a function with the following + signature: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 49 + + \sa QtMsgType, qInstallMessageHandler() +*/ + +/*! + \fn QMessageHandler qInstallMessageHandler(QMessageHandler handler) + \relates + \since 5.0 + + Installs a Qt message \a handler which has been defined + previously. Returns a pointer to the previous message handler + (which may be 0). + + The message handler is a function that prints out debug messages, + warnings, critical and fatal error messages. The Qt library (debug + mode) contains hundreds of warning messages that are printed + when internal errors (usually invalid function arguments) + occur. Qt built in release mode also contains such warnings unless + QT_NO_WARNING_OUTPUT and/or QT_NO_DEBUG_OUTPUT have been set during + compilation. If you implement your own message handler, you get total + control of these messages. + + The default message handler prints the message to the standard + output under X11 or to the debugger under Windows. If it is a + fatal message, the application aborts immediately. + + Only one message handler can be defined, since this is usually + done on an application-wide basis to control debug output. + + To restore the message handler, call \c qInstallMessageHandler(0). + + Example: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 23 + + \sa qDebug(), qWarning(), qCritical(), qFatal(), QtMsgType, + {Debugging Techniques} +*/ + +QMessageHandler qInstallMessageHandler(QMessageHandler h) +{ + if (!messageHandler) + messageHandler = qDefaultMessageHandler; + QMessageHandler old = messageHandler; + messageHandler = h; +#if defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB) + if (!messageHandler && usingWinMain) + messageHandler = qWinMessageHandler; +#endif + return old; +} + +/*! + \fn QtMsgHandler qInstallMsgHandler(QtMsgHandler handler) + \relates + \deprecated + + Installs a Qt message \a handler which has been defined + previously. This method is deprecated, use qInstallMessageHandler + instead. + \sa QtMsgHandler, qInstallMessageHandler +*/ + +QtMsgHandler qInstallMsgHandler(QtMsgHandler h) +{ + //if handler is 0, set it to the + //default message handler + if (!msgHandler) + msgHandler = qDefaultMsgHandler; + QtMsgHandler old = msgHandler; + msgHandler = h; +#if defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB) + if (!msgHandler && usingWinMain) + msgHandler = qWinMsgHandler; +#endif + return old; +} + QT_END_NAMESPACE diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h index 5ac6cc090ec..4de04bdc330 100644 --- a/src/corelib/global/qlogging.h +++ b/src/corelib/global/qlogging.h @@ -67,7 +67,8 @@ class QMessageLogContext Q_DISABLE_COPY(QMessageLogContext) public: QMessageLogContext() : version(1), line(0), file(0), function(0) {} - Q_DECL_CONSTEXPR QMessageLogContext(const char *fileName, int lineNumber, const char *functionName) + Q_DECL_CONSTEXPR QMessageLogContext(const char *fileName, int lineNumber, + const char *functionName) : version(1), line(lineNumber), file(fileName), function(functionName) {} int version; @@ -126,8 +127,6 @@ private: QMessageLogContext context; }; -Q_CORE_EXPORT void qt_message_output(QtMsgType, const QMessageLogContext &context, const char *buf); - /* qDebug, qWarning, qCritical, qFatal are redefined to automatically include context information */ @@ -139,15 +138,20 @@ Q_CORE_EXPORT void qt_message_output(QtMsgType, const QMessageLogContext &contex #define QT_NO_QDEBUG_MACRO while (false) QMessageLogger().noDebug #define QT_NO_QWARNING_MACRO while (false) QMessageLogger().noDebug -#ifdef QT_NO_DEBUG_OUTPUT +#if defined(QT_NO_DEBUG_OUTPUT) # undef qDebug # define qDebug QT_NO_QDEBUG_MACRO #endif -#ifdef QT_NO_WARNING_OUTPUT +#if defined(QT_NO_WARNING_OUTPUT) # undef qWarning # define qWarning QT_NO_QWARNING_MACRO #endif +Q_CORE_EXPORT void qt_message_output(QtMsgType, const QMessageLogContext &context, const char *buf); + +Q_CORE_EXPORT void qErrnoWarning(int code, const char *msg, ...); +Q_CORE_EXPORT void qErrnoWarning(const char *msg, ...); + // deprecated. Use qInstallMessageHandler instead! typedef void (*QtMsgHandler)(QtMsgType, const char *); Q_CORE_EXPORT QtMsgHandler qInstallMsgHandler(QtMsgHandler); From f748875fa8f693aca7fc0f937ebc8499e10b0b16 Mon Sep 17 00:00:00 2001 From: Jonathan Liu Date: Sat, 11 Feb 2012 21:52:07 +1100 Subject: [PATCH 184/406] Add missing crtdbg.h include _CrtSetReportMode requires crtdbg.h to be included. Change-Id: I7e2cbdf7e3087bbe115cd6a51024422b619ac552 Reviewed-by: Jason McDonald Reviewed-by: Friedemann Kleint --- src/testlib/qtestcase.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 161af0f10f5..76bea243b13 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -69,6 +69,9 @@ #include #ifdef Q_OS_WIN +#ifndef Q_OS_WINCE +# include +#endif #include // for Sleep #endif #ifdef Q_OS_UNIX From df4746db04087ed8641b2fbc2a8d0cf29a6993fd Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 10 Feb 2012 14:11:26 +0100 Subject: [PATCH 185/406] Remove the generic atomic implementation This implementation is not used on Windows, and needs to be updated on UNIX for processors that we do not support (this will be done in a separate commit). Change-Id: I471d0ed00f4e8b89ecfa400796a2dbe2330935c6 Reviewed-by: Thiago Macieira --- src/corelib/arch/arch.pri | 7 +- src/corelib/arch/generic/arch.pri | 6 - .../arch/generic/qatomic_generic_unix.cpp | 120 -------- .../arch/generic/qatomic_generic_windows.cpp | 131 -------- src/corelib/arch/qatomic_arch.h | 2 - src/corelib/arch/qatomic_generic.h | 282 ------------------ 6 files changed, 2 insertions(+), 546 deletions(-) delete mode 100644 src/corelib/arch/generic/arch.pri delete mode 100644 src/corelib/arch/generic/qatomic_generic_unix.cpp delete mode 100644 src/corelib/arch/generic/qatomic_generic_windows.cpp delete mode 100644 src/corelib/arch/qatomic_generic.h diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index 4803d6f8b02..825df37cd14 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -1,12 +1,10 @@ -win32:HEADERS += arch/qatomic_msvc.h \ - arch/qatomic_generic.h +win32:HEADERS += arch/qatomic_msvc.h win32-g++*:HEADERS += arch/qatomic_i386.h \ arch/qatomic_x86_64.h mac:HEADERS += arch/qatomic_i386.h \ - arch/qatomic_x86_64.h \ - arch/qatomic_generic.h + arch/qatomic_x86_64.h vxworks:HEADERS += arch/qatomic_vxworks.h @@ -16,7 +14,6 @@ integrity:HEADERS += arch/qatomic_integrity.h arch/qatomic_ia64.h \ arch/qatomic_sparc.h \ arch/qatomic_arch.h \ - arch/qatomic_generic.h \ arch/qatomic_powerpc.h \ arch/qatomic_armv5.h \ arch/qatomic_armv6.h \ diff --git a/src/corelib/arch/generic/arch.pri b/src/corelib/arch/generic/arch.pri deleted file mode 100644 index 8fee63fa5da..00000000000 --- a/src/corelib/arch/generic/arch.pri +++ /dev/null @@ -1,6 +0,0 @@ -# -# 'generic' architecture -# - -unix:SOURCES += qatomic_generic_unix.cpp -win32:SOURCES += qatomic_generic_windows.cpp diff --git a/src/corelib/arch/generic/qatomic_generic_unix.cpp b/src/corelib/arch/generic/qatomic_generic_unix.cpp deleted file mode 100644 index eb1498fcebc..00000000000 --- a/src/corelib/arch/generic/qatomic_generic_unix.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtCore 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 "qplatformdefs.h" - -#include - -QT_BEGIN_NAMESPACE -static pthread_mutex_t qAtomicMutex = PTHREAD_MUTEX_INITIALIZER; - -Q_CORE_EXPORT -bool QBasicAtomicInt_testAndSetOrdered(volatile int *_q_value, int expectedValue, int newValue) -{ - bool returnValue = false; - pthread_mutex_lock(&qAtomicMutex); - if (*_q_value == expectedValue) { - *_q_value = newValue; - returnValue = true; - } - pthread_mutex_unlock(&qAtomicMutex); - return returnValue; -} - -Q_CORE_EXPORT -int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *_q_value, int newValue) -{ - int returnValue; - pthread_mutex_lock(&qAtomicMutex); - returnValue = *_q_value; - *_q_value = newValue; - pthread_mutex_unlock(&qAtomicMutex); - return returnValue; -} - -Q_CORE_EXPORT -int QBasicAtomicInt_fetchAndAddOrdered(volatile int *_q_value, int valueToAdd) -{ - int returnValue; - pthread_mutex_lock(&qAtomicMutex); - returnValue = *_q_value; - *_q_value += valueToAdd; - pthread_mutex_unlock(&qAtomicMutex); - return returnValue; -} - -Q_CORE_EXPORT -bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *_q_value, - void *expectedValue, - void *newValue) -{ - bool returnValue = false; - pthread_mutex_lock(&qAtomicMutex); - if (*_q_value == expectedValue) { - *_q_value = newValue; - returnValue = true; - } - pthread_mutex_unlock(&qAtomicMutex); - return returnValue; -} - -Q_CORE_EXPORT -void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *_q_value, void *newValue) -{ - void *returnValue; - pthread_mutex_lock(&qAtomicMutex); - returnValue = *_q_value; - *_q_value = newValue; - pthread_mutex_unlock(&qAtomicMutex); - return returnValue; -} - -Q_CORE_EXPORT -void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *_q_value, qptrdiff valueToAdd) -{ - void *returnValue; - pthread_mutex_lock(&qAtomicMutex); - returnValue = *_q_value; - *_q_value = reinterpret_cast(returnValue) + valueToAdd; - pthread_mutex_unlock(&qAtomicMutex); - return returnValue; -} -QT_END_NAMESPACE diff --git a/src/corelib/arch/generic/qatomic_generic_windows.cpp b/src/corelib/arch/generic/qatomic_generic_windows.cpp deleted file mode 100644 index dafc8133b20..00000000000 --- a/src/corelib/arch/generic/qatomic_generic_windows.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtCore 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 "qplatformdefs.h" - -#include - - -class QCriticalSection -{ -public: - QCriticalSection() { InitializeCriticalSection(§ion); } - ~QCriticalSection() { DeleteCriticalSection(§ion); } - void lock() { EnterCriticalSection(§ion); } - void unlock() { LeaveCriticalSection(§ion); } - -private: - CRITICAL_SECTION section; -}; - -static QCriticalSection qAtomicCriticalSection; - -Q_CORE_EXPORT -bool QBasicAtomicInt_testAndSetOrdered(volatile int *_q_value, int expectedValue, int newValue) -{ - bool returnValue = false; - qAtomicCriticalSection.lock(); - if (*_q_value == expectedValue) { - *_q_value = newValue; - returnValue = true; - } - qAtomicCriticalSection.unlock(); - return returnValue; -} - -Q_CORE_EXPORT -int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *_q_value, int newValue) -{ - int returnValue; - qAtomicCriticalSection.lock(); - returnValue = *_q_value; - *_q_value = newValue; - qAtomicCriticalSection.unlock(); - return returnValue; -} - -Q_CORE_EXPORT -int QBasicAtomicInt_fetchAndAddOrdered(volatile int *_q_value, int valueToAdd) -{ - int returnValue; - qAtomicCriticalSection.lock(); - returnValue = *_q_value; - *_q_value += valueToAdd; - qAtomicCriticalSection.unlock(); - return returnValue; -} - -Q_CORE_EXPORT -bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *_q_value, - void *expectedValue, - void *newValue) -{ - bool returnValue = false; - qAtomicCriticalSection.lock(); - if (*_q_value == expectedValue) { - *_q_value = newValue; - returnValue = true; - } - qAtomicCriticalSection.unlock(); - return returnValue; -} - -Q_CORE_EXPORT -void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *_q_value, void *newValue) -{ - void *returnValue; - qAtomicCriticalSection.lock(); - returnValue = *_q_value; - *_q_value = newValue; - qAtomicCriticalSection.unlock(); - return returnValue; -} - -Q_CORE_EXPORT -void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *_q_value, qptrdiff valueToAdd) -{ - void *returnValue; - qAtomicCriticalSection.lock(); - returnValue = *_q_value; - *_q_value = reinterpret_cast(returnValue) + valueToAdd; - qAtomicCriticalSection.unlock(); - return returnValue; -} diff --git a/src/corelib/arch/qatomic_arch.h b/src/corelib/arch/qatomic_arch.h index 6f6d1c45a0e..9219ad187a0 100644 --- a/src/corelib/arch/qatomic_arch.h +++ b/src/corelib/arch/qatomic_arch.h @@ -54,8 +54,6 @@ QT_BEGIN_HEADER # include "QtCore/qatomic_alpha.h" #elif defined(QT_ARCH_BFIN) # include "QtCore/qatomic_bfin.h" -#elif defined(QT_ARCH_GENERIC) -# include "QtCore/qatomic_generic.h" #elif defined(QT_ARCH_POWERPC) # include "QtCore/qatomic_powerpc.h" #elif defined(QT_ARCH_S390) diff --git a/src/corelib/arch/qatomic_generic.h b/src/corelib/arch/qatomic_generic.h deleted file mode 100644 index 621a767dd66..00000000000 --- a/src/corelib/arch/qatomic_generic.h +++ /dev/null @@ -1,282 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtCore 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 QATOMIC_GENERIC_H -#define QATOMIC_GENERIC_H - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return false; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return false; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return false; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return false; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isTestAndSetNative() -{ return false; } -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndStoreNative() -{ return false; } -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndAddNative() -{ return false; } -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndAddWaitFree() -{ return false; } - -Q_CORE_EXPORT bool QBasicAtomicInt_testAndSetOrdered(volatile int *, int, int); -Q_CORE_EXPORT int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *, int); -Q_CORE_EXPORT int QBasicAtomicInt_fetchAndAddOrdered(volatile int *, int); - -Q_CORE_EXPORT bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *, void *, void *); -Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *, void *); -Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *, qptrdiff); - -// Reference counting - -inline bool QBasicAtomicInt::ref() -{ - return QBasicAtomicInt_fetchAndAddOrdered(&_q_value, 1) != -1; -} - -inline bool QBasicAtomicInt::deref() -{ - return QBasicAtomicInt_fetchAndAddOrdered(&_q_value, -1) != 1; -} - -// Test and set for integers - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - return QBasicAtomicInt_testAndSetOrdered(&_q_value, expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -// Fetch and store for integers - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - return QBasicAtomicInt_fetchAndStoreOrdered(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -// Fetch and add for integers - -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - return QBasicAtomicInt_fetchAndAddOrdered(&_q_value, valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -// Test and set for pointers - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetOrdered(T *expectedValue, T *newValue) -{ - union { T * volatile * typed; void * volatile * voidp; } pointer; - pointer.typed = &_q_value; - return QBasicAtomicPointer_testAndSetOrdered(pointer.voidp, expectedValue, newValue); -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelease(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -// Fetch and store for pointers - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreOrdered(T *newValue) -{ - union { T * volatile * typed; void * volatile * voidp; } pointer; - union { T *typed; void *voidp; } returnValue; - pointer.typed = &_q_value; - returnValue.voidp = QBasicAtomicPointer_fetchAndStoreOrdered(pointer.voidp, newValue); - return returnValue.typed; -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelaxed(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreAcquire(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelease(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -// Fetch and add for pointers - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - union { T * volatile *typed; void * volatile *voidp; } pointer; - union { T *typed; void *voidp; } returnValue; - pointer.typed = &_q_value; - returnValue.voidp = QBasicAtomicPointer_fetchAndAddOrdered(pointer.voidp, valueToAdd * sizeof(T)); - return returnValue.typed; -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelease(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QATOMIC_GENERIC_H From 5c5498ca0d2f8f1876836730b29a98e97a68487e Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Mon, 13 Feb 2012 06:56:30 +0100 Subject: [PATCH 186/406] Remove Windows specific code from qoldbasicatomic.h This header is not used on Windows anymore, so remove the dead #ifdefs. Change-Id: I76cfbd13c9fff0eab87cc69e8ca1e0d5ccab9e3a Reviewed-by: Thiago Macieira --- src/corelib/thread/qoldbasicatomic.h | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/src/corelib/thread/qoldbasicatomic.h b/src/corelib/thread/qoldbasicatomic.h index 2bd62f69426..7482d95a110 100644 --- a/src/corelib/thread/qoldbasicatomic.h +++ b/src/corelib/thread/qoldbasicatomic.h @@ -61,13 +61,7 @@ QT_END_HEADER class Q_CORE_EXPORT QBasicAtomicInt { public: -#if defined(QT_ARCH_WINDOWS) || defined(QT_ARCH_WINDOWSCE) - union { // needed for Q_BASIC_ATOMIC_INITIALIZER - volatile long _q_value; - }; -#else volatile int _q_value; -#endif // Atomic API, implemented in qatomic_XXX.h @@ -111,19 +105,7 @@ template class QBasicAtomicPointer { public: -#if defined(QT_ARCH_WINDOWS) || defined(QT_ARCH_WINDOWSCE) - union { - T * volatile _q_value; -# if !defined(Q_OS_WINCE) && !defined(__i386__) && !defined(_M_IX86) - qint64 -# else - long -# endif - volatile _q_value_integral; - }; -#else T * volatile _q_value; -#endif // Atomic API, implemented in qatomic_XXX.h @@ -157,11 +139,7 @@ public: T *fetchAndAddOrdered(qptrdiff valueToAdd); }; -#if defined(QT_ARCH_WINDOWS) || defined(QT_ARCH_WINDOWSCE) -# define Q_BASIC_ATOMIC_INITIALIZER(a) { {(a)} } -#else -# define Q_BASIC_ATOMIC_INITIALIZER(a) { (a) } -#endif +#define Q_BASIC_ATOMIC_INITIALIZER(a) { (a) } QT_END_NAMESPACE QT_END_HEADER From 605339a5dd3b9c5740927ad9af85bb6d0f94c5b7 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Mon, 13 Feb 2012 06:49:56 +0100 Subject: [PATCH 187/406] Remove qatomic_arch.h Make qbasicatomic.h include the OS/compiler/processor dependent implementation. For implementations that have not yet been ported to declare a QAtomicOps, they need to #include , and the new QBasicAtomicInteger and QBasicAtomicPointer should not be declared. Change-Id: Ia951834484c9f8dfa75131592e5e716b68ff989b Reviewed-by: Thiago Macieira --- src/corelib/arch/arch.pri | 1 - src/corelib/arch/qatomic_alpha.h | 2 + src/corelib/arch/qatomic_arch.h | 71 ---------------------------- src/corelib/arch/qatomic_bfin.h | 2 + src/corelib/arch/qatomic_integrity.h | 1 + src/corelib/arch/qatomic_powerpc.h | 2 + src/corelib/arch/qatomic_s390.h | 2 + src/corelib/arch/qatomic_sh4a.h | 2 + src/corelib/arch/qatomic_sparc.h | 2 + src/corelib/arch/qatomic_vxworks.h | 2 + src/corelib/thread/qbasicatomic.h | 39 +++++++++++---- src/corelib/thread/qoldbasicatomic.h | 4 +- 12 files changed, 47 insertions(+), 83 deletions(-) delete mode 100644 src/corelib/arch/qatomic_arch.h diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index 825df37cd14..2a4fddb913c 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -13,7 +13,6 @@ integrity:HEADERS += arch/qatomic_integrity.h !wince*:!win32:!mac:HEADERS += arch/qatomic_alpha.h \ arch/qatomic_ia64.h \ arch/qatomic_sparc.h \ - arch/qatomic_arch.h \ arch/qatomic_powerpc.h \ arch/qatomic_armv5.h \ arch/qatomic_armv6.h \ diff --git a/src/corelib/arch/qatomic_alpha.h b/src/corelib/arch/qatomic_alpha.h index 79546448e63..0ac2d8da9c9 100644 --- a/src/corelib/arch/qatomic_alpha.h +++ b/src/corelib/arch/qatomic_alpha.h @@ -42,6 +42,8 @@ #ifndef QATOMIC_ALPHA_H #define QATOMIC_ALPHA_H +#include + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE diff --git a/src/corelib/arch/qatomic_arch.h b/src/corelib/arch/qatomic_arch.h deleted file mode 100644 index 9219ad187a0..00000000000 --- a/src/corelib/arch/qatomic_arch.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtCore 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 QATOMIC_ARCH_H -#define QATOMIC_ARCH_H - -QT_BEGIN_HEADER - -#include "QtCore/qglobal.h" - -#if defined(QT_ARCH_INTEGRITY) -# include "QtCore/qatomic_integrity.h" -#elif defined(QT_ARCH_VXWORKS) -# include "QtCore/qatomic_vxworks.h" -#elif defined(QT_ARCH_ALPHA) -# include "QtCore/qatomic_alpha.h" -#elif defined(QT_ARCH_BFIN) -# include "QtCore/qatomic_bfin.h" -#elif defined(QT_ARCH_POWERPC) -# include "QtCore/qatomic_powerpc.h" -#elif defined(QT_ARCH_S390) -# include "QtCore/qatomic_s390.h" -#elif defined(QT_ARCH_SPARC) -# include "QtCore/qatomic_sparc.h" -#elif defined(QT_ARCH_SH4A) -# include "QtCore/qatomic_sh4a.h" -#else -# error "Qt has not been ported to this architecture" -#endif - -QT_END_HEADER - -#endif // QATOMIC_ARCH_H diff --git a/src/corelib/arch/qatomic_bfin.h b/src/corelib/arch/qatomic_bfin.h index 530ac8d50f2..28a5cd60c94 100644 --- a/src/corelib/arch/qatomic_bfin.h +++ b/src/corelib/arch/qatomic_bfin.h @@ -42,6 +42,8 @@ #ifndef QATOMIC_BFIN_H #define QATOMIC_BFIN_H +#include + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE diff --git a/src/corelib/arch/qatomic_integrity.h b/src/corelib/arch/qatomic_integrity.h index e5d226ad7f2..f290984611f 100644 --- a/src/corelib/arch/qatomic_integrity.h +++ b/src/corelib/arch/qatomic_integrity.h @@ -42,6 +42,7 @@ #ifndef QATOMIC_INTEGRITY_H #define QATOMIC_INTEGRITY_H +#include #include QT_BEGIN_HEADER diff --git a/src/corelib/arch/qatomic_powerpc.h b/src/corelib/arch/qatomic_powerpc.h index f03539dcd54..10f6e4c4882 100644 --- a/src/corelib/arch/qatomic_powerpc.h +++ b/src/corelib/arch/qatomic_powerpc.h @@ -42,6 +42,8 @@ #ifndef QATOMIC_POWERPC_H #define QATOMIC_POWERPC_H +#include + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE diff --git a/src/corelib/arch/qatomic_s390.h b/src/corelib/arch/qatomic_s390.h index b6246e817fe..ef7ab346e30 100644 --- a/src/corelib/arch/qatomic_s390.h +++ b/src/corelib/arch/qatomic_s390.h @@ -42,6 +42,8 @@ #ifndef QATOMIC_S390_H #define QATOMIC_S390_H +#include + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE diff --git a/src/corelib/arch/qatomic_sh4a.h b/src/corelib/arch/qatomic_sh4a.h index 042a602c77c..d00b9adc1de 100644 --- a/src/corelib/arch/qatomic_sh4a.h +++ b/src/corelib/arch/qatomic_sh4a.h @@ -42,6 +42,8 @@ #ifndef QATOMIC_SH4A_H #define QATOMIC_SH4A_H +#include + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE diff --git a/src/corelib/arch/qatomic_sparc.h b/src/corelib/arch/qatomic_sparc.h index 5fc640e01b2..63282290c17 100644 --- a/src/corelib/arch/qatomic_sparc.h +++ b/src/corelib/arch/qatomic_sparc.h @@ -42,6 +42,8 @@ #ifndef QATOMIC_SPARC_H #define QATOMIC_SPARC_H +#include + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE diff --git a/src/corelib/arch/qatomic_vxworks.h b/src/corelib/arch/qatomic_vxworks.h index c18563ef3c7..dbec16a5409 100644 --- a/src/corelib/arch/qatomic_vxworks.h +++ b/src/corelib/arch/qatomic_vxworks.h @@ -48,6 +48,8 @@ QT_BEGIN_HEADER # include #else // generic implementation with taskLock() +#include + #if 0 // we don't want to include the system header here for two function prototypes, // because it pulls in a _lot_ of stuff that pollutes the global namespace diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h index fee7561056c..ba9e30b0dce 100644 --- a/src/corelib/thread/qbasicatomic.h +++ b/src/corelib/thread/qbasicatomic.h @@ -46,34 +46,58 @@ #if defined(QT_MOC) || defined(QT_BUILD_QMAKE) || defined(QT_RCC) || defined(QT_UIC) || defined(QT_BOOTSTRAPPED) # include + +// Compiler dependent implementation #elif defined(Q_CC_MSVC) # include + +// Operating system dependent implementation +#elif defined(Q_OS_INTEGRITY) +# include "QtCore/qatomic_integrity.h" +#elif defined(Q_OS_VXWORKS) +# include "QtCore/qatomic_vxworks.h" + +// Processor dependent implementation +#elif defined(Q_PROCESSOR_ALPHA) +# include "QtCore/qatomic_alpha.h" #elif defined(Q_PROCESSOR_ARM_V7) # include "QtCore/qatomic_armv7.h" #elif defined(Q_PROCESSOR_ARM_V6) # include "QtCore/qatomic_armv6.h" #elif defined(Q_PROCESSOR_ARM_V5) # include "QtCore/qatomic_armv5.h" +#elif defined(Q_PROCESSOR_BFIN) +# include "QtCore/qatomic_bfin.h" #elif defined(Q_PROCESSOR_IA64) # include "QtCore/qatomic_ia64.h" #elif defined(Q_PROCESSOR_MIPS) # include "QtCore/qatomic_mips.h" +#elif defined(Q_PROCESSOR_POWERPC) +# include "QtCore/qatomic_powerpc.h" +#elif defined(Q_PROCESSOR_S390) +# include "QtCore/qatomic_s390.h" +#elif defined(Q_PROCESSOR_SH4A) +# include "QtCore/qatomic_sh4a.h" +#elif defined(Q_PROCESSOR_SPARC) +# include "QtCore/qatomic_sparc.h" #elif defined(Q_PROCESSOR_X86_32) # include #elif defined(Q_PROCESSOR_X86_64) # include + +// Fallback compiler dependent implementation #elif defined(Q_COMPILER_ATOMICS) && defined(Q_COMPILER_CONSTEXPR) # include #elif defined(Q_CC_GNU) # include + +// No fallback #else -# define QT_OLD_ATOMICS +# error "Qt has not been ported to this platform" #endif -#ifdef QT_OLD_ATOMICS -# include "QtCore/qoldbasicatomic.h" -# undef QT_OLD_ATOMICS -#else +// Only include if the implementation has been ported to QAtomicOps +#ifndef QOLDBASICATOMIC_H QT_BEGIN_HEADER @@ -234,7 +258,6 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QT_OLD_ATOMICS +#endif // QOLDBASICATOMIC_H - -#endif // QBASIC_ATOMIC +#endif // QBASICATOMIC_H diff --git a/src/corelib/thread/qoldbasicatomic.h b/src/corelib/thread/qoldbasicatomic.h index 7482d95a110..4df07adfd06 100644 --- a/src/corelib/thread/qoldbasicatomic.h +++ b/src/corelib/thread/qoldbasicatomic.h @@ -144,6 +144,4 @@ public: QT_END_NAMESPACE QT_END_HEADER -# include - -#endif // QBASIC_ATOMIC +#endif // QOLDBASICATOMIC_H From de35b37c68991d87095ad087a635cd9d4e5fe185 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 10 Feb 2012 14:27:34 +0100 Subject: [PATCH 188/406] Add src/corelib/arch/qatomic_unix.h and qatomic_unix.cpp This provides a fallback implementation on UNIX when the Q_PROCESSOR_* and Q_CC_*/Q_COMPILER_* checks fail to find an implementation. Note that we always compile qatomic_unix.cpp, but code is only included when QATOMIC_UNIX_H is defined (meaning the checks above did not find an implementation). Change-Id: I8ce047847206003b4fa96eb3fb76b1c2ffbc2dfc Reviewed-by: Thiago Macieira --- src/corelib/arch/arch.pri | 6 ++ src/corelib/arch/qatomic_unix.cpp | 82 +++++++++++++++++++++ src/corelib/arch/qatomic_unix.h | 117 ++++++++++++++++++++++++++++++ src/corelib/thread/qbasicatomic.h | 4 + 4 files changed, 209 insertions(+) create mode 100644 src/corelib/arch/qatomic_unix.cpp create mode 100644 src/corelib/arch/qatomic_unix.h diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index 2a4fddb913c..14e90b8736b 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -25,6 +25,12 @@ integrity:HEADERS += arch/qatomic_integrity.h arch/qatomic_gcc.h \ arch/qatomic_cxx11.h +unix { + # fallback implementation when no other appropriate qatomic_*.h exists + HEADERS += arch/qatomic_unix.h + SOURCES += arch/qatomic_unix.cpp +} + QT_ARCH_CPP = $$QT_SOURCE_TREE/src/corelib/arch/$$QT_ARCH exists($$QT_ARCH_CPP) { DEPENDPATH += $$QT_ARCH_CPP diff --git a/src/corelib/arch/qatomic_unix.cpp b/src/corelib/arch/qatomic_unix.cpp new file mode 100644 index 00000000000..a709be3fa17 --- /dev/null +++ b/src/corelib/arch/qatomic_unix.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 "qplatformdefs.h" + +#include + +// If operating system, processor, and compiler detection fails, we fall back +// to this generic, out-of-line implementation + +#if defined(QATOMIC_UNIX_H) + +QT_BEGIN_NAMESPACE +static pthread_mutex_t qAtomicMutex = PTHREAD_MUTEX_INITIALIZER; + +Q_CORE_EXPORT +bool QAtomicOps::testAndSetRelaxed(int &_q_value, int expectedValue, int newValue) +{ + bool returnValue = false; + pthread_mutex_lock(&qAtomicMutex); + if (_q_value == expectedValue) { + _q_value = newValue; + returnValue = true; + } + pthread_mutex_unlock(&qAtomicMutex); + return returnValue; +} + +Q_CORE_EXPORT +bool QAtomicOps::testAndSetRelaxed(void *&_q_value, void *expectedValue, void *newValue) +{ + bool returnValue = false; + pthread_mutex_lock(&qAtomicMutex); + if (_q_value == expectedValue) { + _q_value = newValue; + returnValue = true; + } + pthread_mutex_unlock(&qAtomicMutex); + return returnValue; +} + +QT_END_NAMESPACE + +#endif // QATOMIC_UNIX_H diff --git a/src/corelib/arch/qatomic_unix.h b/src/corelib/arch/qatomic_unix.h new file mode 100644 index 00000000000..3dc168c0aeb --- /dev/null +++ b/src/corelib/arch/qatomic_unix.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 QATOMIC_UNIX_H +#define QATOMIC_UNIX_H + +#include + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +#if 0 +// silence syncqt warnings +QT_END_NAMESPACE +QT_END_HEADER + +#pragma qt_sync_stop_processing +#endif + +#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE +#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE +#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE +#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE + +#define Q_ATOMIC_INT32_IS_SUPPORTED + +#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE +#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE +#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE + +template<> struct QAtomicIntegerTraits { enum { IsInteger = 1 }; }; + +// No definition, needs specialization +template struct QAtomicOps; + +template <> +struct QAtomicOps : QGenericAtomicOps > +{ + typedef int Type; + + static inline bool isTestAndSetNative() { return false; } + static inline bool isTestAndSetWaitFree() { return false; } + Q_CORE_EXPORT static bool testAndSetRelaxed(int &_q_value, int expectedValue, int newValue); +}; + +template <> +struct QAtomicOps : QGenericAtomicOps > +{ + typedef void *Type; + + static inline bool isTestAndSetNative() { return false; } + static inline bool isTestAndSetWaitFree() { return false; } + Q_CORE_EXPORT static bool testAndSetRelaxed(void *&_q_value, void *expectedValue, void *newValue); +}; + +template +struct QAtomicOps : QGenericAtomicOps > +{ + typedef T *Type; + + // helper to strip cv qualifiers + static inline void *nocv(const T *p) { return const_cast(static_cast(p)); } + + static inline bool isTestAndSetNative() { return false; } + static inline bool isTestAndSetWaitFree() { return false; } + static inline bool testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue) + { + // forward to the void* specialization + void *voidp = nocv(_q_value); + bool returnValue = QAtomicOps::testAndSetRelaxed(voidp, nocv(expectedValue), nocv(newValue)); + _q_value = reinterpret_cast(voidp); + return returnValue; + } +}; + +QT_END_NAMESPACE +QT_END_HEADER + +#endif // QATOMIC_UNIX_H diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h index ba9e30b0dce..363a4da3388 100644 --- a/src/corelib/thread/qbasicatomic.h +++ b/src/corelib/thread/qbasicatomic.h @@ -91,6 +91,10 @@ #elif defined(Q_CC_GNU) # include +// Fallback operating system dependent implementation +#elif defined(Q_OS_UNIX) +# include + // No fallback #else # error "Qt has not been ported to this platform" From 7bf37d966e062790ff04a51a860a16eb52d46838 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 10 Feb 2012 14:34:12 +0100 Subject: [PATCH 189/406] Cleanup HEADERS+=... in src/corelib/arch/arch.pri Include all qatomic_*.h files in HEADERS, since we don't know which include the compiler will end up choosing in the end (operating system specific includes are still conditionally included, though). Change-Id: I4241e40ad51d34dede04be0c4ee95378d6f3d037 Reviewed-by: Thiago Macieira --- src/corelib/arch/arch.pri | 41 +++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index 14e90b8736b..cb2102cefd3 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -1,29 +1,24 @@ -win32:HEADERS += arch/qatomic_msvc.h - -win32-g++*:HEADERS += arch/qatomic_i386.h \ - arch/qatomic_x86_64.h - -mac:HEADERS += arch/qatomic_i386.h \ - arch/qatomic_x86_64.h - +win32|wince:HEADERS += arch/qatomic_msvc.h vxworks:HEADERS += arch/qatomic_vxworks.h - integrity:HEADERS += arch/qatomic_integrity.h -!wince*:!win32:!mac:HEADERS += arch/qatomic_alpha.h \ - arch/qatomic_ia64.h \ - arch/qatomic_sparc.h \ - arch/qatomic_powerpc.h \ - arch/qatomic_armv5.h \ - arch/qatomic_armv6.h \ - arch/qatomic_armv7.h \ - arch/qatomic_i386.h \ - arch/qatomic_mips.h \ - arch/qatomic_s390.h \ - arch/qatomic_x86_64.h \ - arch/qatomic_sh4a.h \ - arch/qatomic_gcc.h \ - arch/qatomic_cxx11.h +HEADERS += \ + arch/qatomic_alpha.h \ + arch/qatomic_armv5.h \ + arch/qatomic_armv6.h \ + arch/qatomic_armv7.h \ + arch/qatomic_bfin.h \ + arch/qatomic_bootstrap.h \ + arch/qatomic_i386.h \ + arch/qatomic_ia64.h \ + arch/qatomic_mips.h \ + arch/qatomic_powerpc.h \ + arch/qatomic_s390.h \ + arch/qatomic_sh4a.h \ + arch/qatomic_sparc.h \ + arch/qatomic_x86_64.h \ + arch/qatomic_gcc.h \ + arch/qatomic_cxx11.h unix { # fallback implementation when no other appropriate qatomic_*.h exists From 3f74aea9bb67bcd2ec463792ee111402f10825d5 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 8 Feb 2012 12:26:09 +0100 Subject: [PATCH 190/406] Fix tst_QSocketNotifier on Mac OS X Socket notifier behavior is very OS-dependent. QtNetwork uses non- immediately (it will return -1 w/ errno=EINPROGRESS). We have to wait with select(2) to indicate that the connection is ready, then call connect(2) again. When this happens, we need another call to select(2) to get notification on the listening socket so that we can call accept(2) to complete the connection. The mixingWithTimers() failure happens due to the test expecting a single processEvents() call to be able to completely connect a TCP socket. But as described above, this may not happen. The test should QTRY_COMPARE() to give the test a chance to let all this happen. The posixSockets() test can fail due to the same connect() behavior. The test already has a comment about the write notifier behavior being very OS dependent. This caused the first enterLoop() to return too early, before the read notifier fired (which is what the test is checking for, that the read notifier fired). Move creation of the write notifier to where we expect it to fire, just before writing to the posix socket. In the same test, the read notifier inside QTcpSocket may not fire after the write notifier on the posix socket. Use the waitForReadyRead() function to give the socket a chance to read the data written to the posix socket. Change-Id: I541e6ee9a39a92ce3acf6b9ffee51079febe43e4 Reviewed-by: Jonas Gastal Reviewed-by: Shane Kearns --- .../qsocketnotifier/qsocketnotifier.pro | 2 -- .../qsocketnotifier/tst_qsocketnotifier.cpp | 19 ++++++++++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/auto/corelib/kernel/qsocketnotifier/qsocketnotifier.pro b/tests/auto/corelib/kernel/qsocketnotifier/qsocketnotifier.pro index 55f6934fc92..58e4b98af73 100644 --- a/tests/auto/corelib/kernel/qsocketnotifier/qsocketnotifier.pro +++ b/tests/auto/corelib/kernel/qsocketnotifier/qsocketnotifier.pro @@ -6,5 +6,3 @@ SOURCES = tst_qsocketnotifier.cpp requires(contains(QT_CONFIG,private_tests)) include(../../../network/socket/platformsocketengine/platformsocketengine.pri) - -mac: CONFIG += insignificant_test # QTBUG-22746 diff --git a/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp b/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp index e3bfe3bc6d9..5442303e7e0 100644 --- a/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp +++ b/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp @@ -237,7 +237,7 @@ void tst_QSocketNotifier::mixingWithTimers() QCoreApplication::processEvents(); QCOMPARE(helper.timerActivated, true); - QCOMPARE(helper.socketActivated, true); + QTRY_COMPARE(helper.socketActivated, true); } void tst_QSocketNotifier::posixSockets() @@ -264,10 +264,7 @@ void tst_QSocketNotifier::posixSockets() connect(&rn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); QSignalSpy readSpy(&rn, SIGNAL(activated(int))); QVERIFY(readSpy.isValid()); - QSocketNotifier wn(posixSocket, QSocketNotifier::Write); - connect(&wn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); - QSignalSpy writeSpy(&wn, SIGNAL(activated(int))); - QVERIFY(writeSpy.isValid()); + // No write notifier, some systems trigger write notification on socket creation, but not all QSocketNotifier en(posixSocket, QSocketNotifier::Exception); connect(&en, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); QSignalSpy errorSpy(&en, SIGNAL(activated(int))); @@ -278,19 +275,27 @@ void tst_QSocketNotifier::posixSockets() QTestEventLoop::instance().enterLoop(3); QCOMPARE(readSpy.count(), 1); - writeSpy.clear(); //depending on OS, write notifier triggers on creation or not. QCOMPARE(errorSpy.count(), 0); char buffer[100]; - qt_safe_read(posixSocket, buffer, 100); + int r = qt_safe_read(posixSocket, buffer, 100); + QCOMPARE(r, 6); QCOMPARE(buffer, "hello"); + QSocketNotifier wn(posixSocket, QSocketNotifier::Write); + connect(&wn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QSignalSpy writeSpy(&wn, SIGNAL(activated(int))); + QVERIFY(writeSpy.isValid()); qt_safe_write(posixSocket, "goodbye", 8); QTestEventLoop::instance().enterLoop(3); QCOMPARE(readSpy.count(), 1); QCOMPARE(writeSpy.count(), 1); QCOMPARE(errorSpy.count(), 0); + + // Write notifier may have fired before the read notifier inside + // QTcpSocket, give QTcpSocket a chance to see the incoming data + passive->waitForReadyRead(100); QCOMPARE(passive->readAll(), QByteArray("goodbye",8)); } qt_safe_close(posixSocket); From 5c637e9171975a86ec1a3982579cd6f371b1d5ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 8 Feb 2012 11:28:30 +0100 Subject: [PATCH 191/406] Add QFileInfo::isNativePath This function returns true if the file path can be used directly with native APIs, modulo encoding and path separator conversions. This is important for applications that interface with other libraries or simply need to use native APIs together with Qt. Traditionally, this information was available in QAbstractFileEngine and forced users to explicitly create an engine or use internal API such as QFile::fileEngine to access the underlying engine and this piece of information. Given its usefulness, exposing the information in a more visible place is more appropriate. This reduces the need for people to know or care about implementation details, like file engines... The existing isLocalFs test was updated and repurposed to use the new API, instead of relying on file engines and internal implementation details of QFileInfo. Change-Id: I65f497bb25741f6f7ea4d2c3b3562c8c4aab8bea Reviewed-by: Oswald Buddenhagen Reviewed-by: David Faure Reviewed-by: Lars Knoll --- src/corelib/io/qfileinfo.cpp | 23 +++++++++++++++++++ src/corelib/io/qfileinfo.h | 1 + .../corelib/io/qfileinfo/tst_qfileinfo.cpp | 23 ++++++++++--------- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 7277a7a0e4f..a7fb0fb6c7b 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -917,6 +917,29 @@ bool QFileInfo::isHidden() const return d->getFileFlags(QAbstractFileEngine::HiddenFlag); } +/*! + \since 5.0 + Returns true if the file path can be used directly with native APIs. + Returns false if the file is otherwise supported by a virtual file system + inside Qt, such as \l{the Qt Resource System}. + + \bold{Note:} Native paths may still require conversion of path separators + and character encoding, depending on platform and input requirements of the + native API. + + \sa QDir::toNativeSeparators(), QFile::encodeName(), filePath(), + absoluteFilePath(), canonicalFilePath() +*/ +bool QFileInfo::isNativePath() const +{ + Q_D(const QFileInfo); + if (d->isDefaultConstructed) + return false; + if (d->fileEngine == 0) + return true; + return d->getFileFlags(QAbstractFileEngine::LocalDiskFlag); +} + /*! Returns true if this object points to a file or to a symbolic link to a file. Returns false if the diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h index bc9b057fb53..0f43ebd4394 100644 --- a/src/corelib/io/qfileinfo.h +++ b/src/corelib/io/qfileinfo.h @@ -103,6 +103,7 @@ public: bool isWritable() const; bool isExecutable() const; bool isHidden() const; + bool isNativePath() const; bool isRelative() const; inline bool isAbsolute() const { return !isRelative(); } diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp index a3d80cb66f3..797d5ff5e35 100644 --- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp @@ -159,8 +159,8 @@ private slots: void isBundle_data(); void isBundle(); - void isLocalFs_data(); - void isLocalFs(); + void isNativePath_data(); + void isNativePath(); void refresh(); @@ -1222,10 +1222,13 @@ void tst_QFileInfo::isBundle() QCOMPARE(fi.isBundle(), isBundle); } -void tst_QFileInfo::isLocalFs_data() +void tst_QFileInfo::isNativePath_data() { QTest::addColumn("path"); - QTest::addColumn("isLocalFs"); + QTest::addColumn("isNativePath"); + + QTest::newRow("default-constructed") << QString() << false; + QTest::newRow("empty") << QString("") << true; QTest::newRow("local root") << QString::fromLatin1("/") << true; QTest::newRow("local non-existent file") << QString::fromLatin1("/abrakadabra.boo") << true; @@ -1233,17 +1236,15 @@ void tst_QFileInfo::isLocalFs_data() QTest::newRow("qresource root") << QString::fromLatin1(":/") << false; } -void tst_QFileInfo::isLocalFs() +void tst_QFileInfo::isNativePath() { QFETCH(QString, path); - QFETCH(bool, isLocalFs); + QFETCH(bool, isNativePath); QFileInfo info(path); - QFileInfoPrivate *privateInfo = getPrivate(info); - QCOMPARE((privateInfo->fileEngine == 0), isLocalFs); - if (privateInfo->fileEngine) - QCOMPARE(bool(privateInfo->fileEngine->fileFlags(QAbstractFileEngine::LocalDiskFlag) - & QAbstractFileEngine::LocalDiskFlag), isLocalFs); + if (path.isNull()) + info = QFileInfo(); + QCOMPARE(info.isNativePath(), isNativePath); } void tst_QFileInfo::refresh() From 731da2a6abf8139600ff3d79875f47756df290b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Sat, 4 Feb 2012 01:00:51 +0100 Subject: [PATCH 192/406] Use newly-added QFileInfo::isNativePath Don't indirect over internal API. With QAbstractFileEngine and friends on the way out, QFile is losing its (marked internal) virtual fileEngine() function and the file engine can't be queried for LocalDiskFlag. That information is now available through QFileInfo, instead. Change-Id: I48827a96fd8cd748055ad5f075912fc8e1c5ef7f Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontdatabase.cpp | 8 ++++---- src/gui/text/qfontengine_ft.cpp | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index be8c1c0bb1b..fa9cae43590 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -39,7 +39,6 @@ ** ****************************************************************************/ -#include #include "qfontdatabase.h" #include "qdebug.h" #include "qalgorithms.h" @@ -47,12 +46,13 @@ #include "qvarlengtharray.h" // here or earlier - workaround for VC++6 #include "qthread.h" #include "qmutex.h" +#include "qfile.h" +#include "qfileinfo.h" #include "private/qunicodetables_p.h" #include "qfontengine_p.h" #include #include -#include "qabstractfileengine.h" #include #include @@ -2203,8 +2203,8 @@ bool QFontDatabasePrivate::isApplicationFont(const QString &fileName) int QFontDatabase::addApplicationFont(const QString &fileName) { QByteArray data; - QFile f(fileName); - if (!(f.fileEngine()->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag)) { + if (!QFileInfo(fileName).isNativePath()) { + QFile f(fileName); if (!f.open(QIODevice::ReadOnly)) return -1; data = f.readAll(); diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index cecf9d1feb6..c9eadd386ee 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -49,7 +49,7 @@ #ifndef QT_NO_FREETYPE #include "qfile.h" -#include "qabstractfileengine.h" +#include "qfileinfo.h" #include "qthreadstorage.h" #include @@ -231,7 +231,7 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id, QScopedPointer newFreetype(new QFreetypeFace); FT_Face face; if (!face_id.filename.isEmpty()) { - QFile file(QString::fromUtf8(face_id.filename)); + QString fileName = QString::fromUtf8(face_id.filename); if (face_id.filename.startsWith(":qmemoryfonts/")) { // from qfontdatabase.cpp QByteArray idx = face_id.filename; @@ -240,7 +240,8 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id, newFreetype->fontData = qt_fontdata_from_index(idx.toInt(&ok)); if (!ok) newFreetype->fontData = QByteArray(); - } else if (!(file.fileEngine()->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag)) { + } else if (!QFileInfo(fileName).isNativePath()) { + QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { return 0; } From e0fd9b5b06dd8f8c00d67621656b0f591b1f14bc Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 13 Feb 2012 16:53:24 +0200 Subject: [PATCH 193/406] Make "nmake check" pass for network tests in Windows. Marked two tests insignificant due to failures, these need to be fixed later and then re-enabled: - tst_qnetworkreply - tst_qsslsocket Task-number: QTBUG-24203 Change-Id: I9647833bf15fe5a340d7ef59e1dcb007a92677dc Reviewed-by: Sergio Ahumada Reviewed-by: Friedemann Kleint --- tests/auto/network/access/qnetworkreply/test/test.pro | 2 ++ tests/auto/network/ssl/qsslsocket/qsslsocket.pro | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/auto/network/access/qnetworkreply/test/test.pro b/tests/auto/network/access/qnetworkreply/test/test.pro index 1dfd67a1c89..56b8acc6e56 100644 --- a/tests/auto/network/access/qnetworkreply/test/test.pro +++ b/tests/auto/network/access/qnetworkreply/test/test.pro @@ -28,3 +28,5 @@ wince* { certFiles.path = . DEPLOYMENT += certFiles } + +win32:CONFIG += insignificant_test # QTBUG-24226 diff --git a/tests/auto/network/ssl/qsslsocket/qsslsocket.pro b/tests/auto/network/ssl/qsslsocket/qsslsocket.pro index a8763d69afa..bb04e0b9c4c 100644 --- a/tests/auto/network/ssl/qsslsocket/qsslsocket.pro +++ b/tests/auto/network/ssl/qsslsocket/qsslsocket.pro @@ -35,3 +35,5 @@ wince* { linux-*:system(". /etc/lsb-release && [ $DISTRIB_CODENAME = oneiric ]"):DEFINES+=UBUNTU_ONEIRIC requires(contains(QT_CONFIG,private_tests)) + +win32:CONFIG += insignificant_test # QTBUG-24234 From c954bf8b91bb0e7bc7ce4eb8cecca1331766b051 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 13 Feb 2012 11:55:39 +0100 Subject: [PATCH 194/406] Fix host endian detection when compiling with sysroot Apply the sysroot argument for the endian test only for the test used for detecting the target endianness, don't use --sysroot for the host detection. Change-Id: I53edda6ebfd06e73cc64f2561b707bd2ba052ae7 Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- config.tests/unix/endian.test | 3 ++- configure | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/config.tests/unix/endian.test b/config.tests/unix/endian.test index 2985fd8241b..6c5c3118883 100755 --- a/config.tests/unix/endian.test +++ b/config.tests/unix/endian.test @@ -4,13 +4,14 @@ QMKSPEC=$1 VERBOSE=$2 SRCDIR=$3 OUTDIR=$4 +QMFLAGS=$5 # debuggery [ "$VERBOSE" = "yes" ] && echo "Determining machine byte-order... ($*)" # build and run a test program test -d "$OUTDIR/config.tests/unix/endian" || mkdir -p "$OUTDIR/config.tests/unix/endian" -"$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "QT_BUILD_TREE=$OUTDIR" "QMAKE_LFLAGS+=$SYSROOT_FLAG" "$SRCDIR/config.tests/unix/endian/endiantest.pro" -o "$OUTDIR/config.tests/unix/endian/Makefile" >/dev/null 2>&1 +"$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "QT_BUILD_TREE=$OUTDIR" $QMFLAGS "$SRCDIR/config.tests/unix/endian/endiantest.pro" -o "$OUTDIR/config.tests/unix/endian/Makefile" >/dev/null 2>&1 cd "$OUTDIR/config.tests/unix/endian" diff --git a/configure b/configure index d497c2f77c6..bfbb5c7768d 100755 --- a/configure +++ b/configure @@ -5979,7 +5979,7 @@ if [ "$CFG_ENDIAN" = "auto" ]; then elif [ "$PLATFORM_MAC" = "yes" ]; then true #leave as auto else - "$unixtests/endian.test" "$XQMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath" + "$unixtests/endian.test" "$XQMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath" "QMAKE_LFLAGS+=$SYSROOT_FLAG" F="$?" if [ "$F" -eq 0 ]; then CFG_ENDIAN="Q_LITTLE_ENDIAN" From 28f02bcd51b30dd1981159d507b3f2dc215314e2 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Mon, 13 Feb 2012 16:01:11 +0100 Subject: [PATCH 195/406] Removed unused qStorePixel[] array. Change-Id: I9c9df19fcf06b127aaebb7ab093221e1b254ab9e Reviewed-by: Thiago Macieira --- src/gui/painting/qdrawhelper.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 8f2b3bab1c7..bb4b23a3674 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -294,7 +294,6 @@ StorePixelsFunc qStorePixels[QPixelLayout::BPPCount] = { }; typedef uint (QT_FASTCALL *FetchPixelFunc)(const uchar *src, int index); -typedef void (QT_FASTCALL *StorePixelFunc)(uchar *dest, int index, uint pixel); FetchPixelFunc qFetchPixel[QPixelLayout::BPPCount] = { 0, // BPPNone @@ -306,17 +305,6 @@ FetchPixelFunc qFetchPixel[QPixelLayout::BPPCount] = { fetchPixel // BPP32 }; -StorePixelFunc qStorePixel[QPixelLayout::BPPCount] = { - 0, // BPPNone - storePixel, // BPP1MSB - storePixel, // BPP1LSB - storePixel, // BPP8 - storePixel, // BPP16 - storePixel, // BPP24 - storePixel // BPP32 -}; - - /* Destination fetch. This is simple as we don't have to do bounds checks or transformations From 3af86043ba27c2720b6d61a9457a6aefa4210efd Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Sun, 22 Jan 2012 14:46:13 +0200 Subject: [PATCH 196/406] Add a testcase of a list of UUIDs in string form. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UUIDs are a good testcase, because the textual content is all fairly similar. This also changes data generation to be a little neater now that we're starting to get multiple pieces of data. Change-Id: Ie4100a1ca4dbe7bf1cd73de883a9854377ac2f5e Reviewed-by: Giuseppe D'Angelo Reviewed-by: João Abecasis --- tests/benchmarks/corelib/tools/qhash/main.cpp | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/tests/benchmarks/corelib/tools/qhash/main.cpp b/tests/benchmarks/corelib/tools/qhash/main.cpp index 6f3228d0ebc..18138cbd47a 100644 --- a/tests/benchmarks/corelib/tools/qhash/main.cpp +++ b/tests/benchmarks/corelib/tools/qhash/main.cpp @@ -45,7 +45,7 @@ #include #include #include - +#include #include @@ -69,12 +69,36 @@ private: void tst_QHash::data() { - QFile smallPathsData("paths_small_data.txt"); - smallPathsData.open(QIODevice::ReadOnly); - QTest::addColumn("items"); - QTest::newRow("paths-small") - << QString::fromLatin1(smallPathsData.readAll()).split(QLatin1Char('\n')); + static QStringList smallFilePaths; + + { + // small list of file paths + if (smallFilePaths.isEmpty()) { + QFile smallPathsData("paths_small_data.txt"); + QVERIFY(smallPathsData.open(QIODevice::ReadOnly)); + smallFilePaths = QString::fromLatin1(smallPathsData.readAll()).split(QLatin1Char('\n')); + Q_ASSERT(!smallFilePaths.isEmpty()); + } + + QTest::newRow("paths-small") << smallFilePaths; + } + + { + // list of UUIDs + static QStringList uuids; + if (uuids.isEmpty()) { + // guaranteed to be completely random, generated by http://xkcd.com/221/ + QUuid ns = QUuid("{f43d2ef3-2fe9-4563-a6f5-5a0100c2d699}"); + uuids.reserve(smallFilePaths.size()); + + foreach (const QString &path, smallFilePaths) + uuids.append(QUuid::createUuidV5(ns, path).toString()); + } + + QTest::newRow("uuids-list") << uuids; + } + } void tst_QHash::qhash_qt4() From c7fa95bd90805f291775b9441d38a4f016871dc4 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Mon, 13 Feb 2012 15:30:54 +0100 Subject: [PATCH 197/406] Added static keyword to blend_transformed_tiled_argb/rgb565(). Change-Id: I43745c672d5d31ef89901234c04bf2433269462c Reviewed-by: Thiago Macieira --- src/gui/painting/qdrawhelper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index bb4b23a3674..0491a3deaf9 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -4749,7 +4749,7 @@ static void blend_transformed_rgb565(int count, const QSpan *spans, void *userDa } } -void blend_transformed_tiled_argb(int count, const QSpan *spans, void *userData) +static void blend_transformed_tiled_argb(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); if (data->texture.format != QImage::Format_ARGB32_Premultiplied @@ -4871,7 +4871,7 @@ void blend_transformed_tiled_argb(int count, const QSpan *spans, void *userData) } } -void blend_transformed_tiled_rgb565(int count, const QSpan *spans, void *userData) +static void blend_transformed_tiled_rgb565(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); QPainter::CompositionMode mode = data->rasterBuffer->compositionMode; From ac02eaa8a7676ff9a10159bc1be4961d32a7e842 Mon Sep 17 00:00:00 2001 From: Morten Johan Sorvig Date: Tue, 3 Jan 2012 20:54:57 +0100 Subject: [PATCH 198/406] Reduce PLATFORM_MAC usage in the configure script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All platforms are PLATFORM_QPA now, so we want to remove PLATFORM_MAC. Do one of two things: either remove the PLATFORM_MAC code path or test on BUILD_ON_MAC instead. Change-Id: I6037a1a5f79498d9e0b5c2607e3698319fc7f68f Reviewed-by: Tor Arne Vestbø --- configure | 85 ++++++++++++++++++------------------------------------- 1 file changed, 28 insertions(+), 57 deletions(-) diff --git a/configure b/configure index bfbb5c7768d..c780af362f5 100755 --- a/configure +++ b/configure @@ -1357,7 +1357,7 @@ while [ "$#" -gt 0 ]; do PLATFORM_X11=yes ;; sdk) - if [ "$PLATFORM_MAC" = "yes" ]; then + if [ "$BUILD_ON_MAC" = "yes" ]; then CFG_SDK="$VAL" else UNKNOWN_OPT=yes @@ -1383,7 +1383,7 @@ while [ "$#" -gt 0 ]; do CFG_HOST_ARCH=$VAL ;; harfbuzz) - if [ "$PLATFORM_MAC" = "yes" ] && [ "$VAL" = "yes" ]; then + if [ "$BUILD_ON_MAC" = "yes" ] && [ "$VAL" = "yes" ]; then CFG_MAC_HARFBUZZ="$VAL" else UNKNOWN_OPT=yes @@ -1391,7 +1391,7 @@ while [ "$#" -gt 0 ]; do ;; framework) - if [ "$PLATFORM_MAC" = "yes" ] || [ "$PLATFORM_QPA" = "yes" ]; then + if [ "$BUILD_ON_MAC" = "yes" ]; then CFG_FRAMEWORK="$VAL" else UNKNOWN_OPT=yes @@ -2144,7 +2144,7 @@ while [ "$#" -gt 0 ]; do l_FLAGS="$l_FLAGS -l\"${VAL}\"" ;; add_fpath) - if [ "$PLATFORM_MAC" = "yes" ]; then + if [ "$BUILD_ON_MAC" = "yes" ]; then L_FLAGS="$L_FLAGS -F\"${VAL}\"" I_FLAGS="$I_FLAGS -F\"${VAL}\"" else @@ -2152,7 +2152,7 @@ while [ "$#" -gt 0 ]; do fi ;; add_framework) - if [ "$PLATFORM_MAC" = "yes" ]; then + if [ "$BUILD_ON_MAC" = "yes" ]; then l_FLAGS="$l_FLAGS -framework \"${VAL}\"" else UNKNOWN_OPT=yes @@ -2503,7 +2503,7 @@ if [ -z "$PLATFORM" ]; then PLATFORM_NOTES= case "$UNAME_SYSTEM:$UNAME_RELEASE" in Darwin:*) - if [ "$PLATFORM_MAC" = "yes" -o "$PLATFORM_QPA" = "yes" ]; then + if [ "$PLATFORM_QPA" = "yes" ]; then OSX_VERSION=`uname -r | cut -d. -f1` if [ "$OSX_VERSION" -ge 11 ]; then # We're on Lion or above. Check if we have a supported Clang version @@ -2704,7 +2704,7 @@ if [ "$PLATFORM" != "$XPLATFORM" ]; then QMAKE_CONFIG="$QMAKE_CONFIG cross_compile" fi -if [ "$PLATFORM_MAC" = "yes" ]; then +if [ "$BUILD_ON_MAC" = "yes" ]; then if [ `basename $QMAKESPEC` = "macx-xcode" ] || [ `basename $XQMAKESPEC` = "macx-xcode" ]; then echo >&2 echo " Platform 'macx-xcode' should not be used when building Qt/Mac." >&2 @@ -3043,7 +3043,7 @@ if [ '!' -z "$CFG_SDK" ]; then fi # find the default framework value -if [ "$PLATFORM_MAC" = "yes" ]; then +if [ "$BUILD_ON_MAC" = "yes" ]; then if [ "$CFG_FRAMEWORK" = "auto" ]; then CFG_FRAMEWORK="$CFG_SHARED" elif [ "$CFG_FRAMEWORK" = "yes" ] && [ "$CFG_SHARED" = "no" ]; then @@ -3093,7 +3093,7 @@ if [ "$CFG_PRECOMPILE" = "auto" ]; then fi #auto-detect DWARF2 on the mac -if [ "$PLATFORM_MAC" = "yes" ] && [ "$CFG_MAC_DWARF2" = "auto" ]; then +if [ "$BUILD_ON_MAC" = "yes" ] && [ "$CFG_MAC_DWARF2" = "auto" ]; then if "$mactests/dwarf2.test" "$TEST_COMPILER" "$OPT_VERBOSE" "$mactests" ; then CFG_MAC_DWARF2=no else @@ -3157,15 +3157,8 @@ if [ "$PLATFORM_QWS" = "yes" ] && [ "$CFG_OPENGL" = "auto" ]; then CFG_OPENGL=no fi -# mac -if [ "$PLATFORM_MAC" = "yes" ]; then - if [ "$CFG_OPENGL" = "auto" ] || [ "$CFG_OPENGL" = "yes" ]; then - CFG_OPENGL=desktop - fi -fi - # find the default framework value -if [ "$PLATFORM_MAC" = "yes" ]; then +if [ "$BUILD_ON_MAC" = "yes" ]; then if [ "$CFG_FRAMEWORK" = "auto" ]; then CFG_FRAMEWORK="$CFG_SHARED" elif [ "$CFG_FRAMEWORK" = "yes" ] && [ "$CFG_SHARED" = "no" ]; then @@ -3178,18 +3171,6 @@ else CFG_FRAMEWORK=no fi -# Print a warning if configure was called with the 10.4u SDK option on Snow Leopard -# with the default mkspec. The 10.4u SDK does not support gcc 4.2. -if [ "$PLATFORM_MAC" = "yes" ] && [ '!' -z "$CFG_SDK" ]; then - # get the darwin version. 10.0.0 and up means snow leopard. - VERSION=`uname -r | tr '.' ' ' | awk '{print $1}'` - if [ "$VERSION" -gt 9 ] && [ "$CFG_SDK" == "/Developer/SDKs/MacOSX10.4u.sdk/" ] && [ "$PLATFORM" == "macx-g++" ]; then - echo - echo "WARNING: The 10.4u SDK does not support gcc 4.2. Configure with -platform macx-g++40. " - echo - fi -fi - # x11 tests are done after qmake is built @@ -3227,7 +3208,7 @@ QT_INSTALL_PREFIX=`"$relpath/config.tests/unix/makeabs" "$QT_INSTALL_PREFIX"` if [ -z "$QT_INSTALL_DOCS" ]; then #default if [ "$CFG_PREFIX_INSTALL" = "no" ]; then - if [ "$PLATFORM_MAC" = "yes" ]; then + if [ "$BUILD_ON_MAC" = "yes" ]; then QT_INSTALL_DOCS="/Developer/Documentation/Qt" fi fi @@ -3238,7 +3219,7 @@ QT_INSTALL_DOCS=`"$relpath/config.tests/unix/makeabs" "$QT_INSTALL_DOCS"` if [ -z "$QT_INSTALL_HEADERS" ]; then #default if [ "$CFG_PREFIX_INSTALL" = "no" ]; then - if [ "$PLATFORM_MAC" = "yes" ]; then + if [ "$BUILD_ON_MAC" = "yes" ]; then if [ "$CFG_FRAMEWORK" = "yes" ]; then QT_INSTALL_HEADERS= fi @@ -3251,7 +3232,7 @@ QT_INSTALL_HEADERS=`"$relpath/config.tests/unix/makeabs" "$QT_INSTALL_HEADERS"` if [ -z "$QT_INSTALL_LIBS" ]; then #default if [ "$CFG_PREFIX_INSTALL" = "no" ]; then - if [ "$PLATFORM_MAC" = "yes" ]; then + if [ "$BUILD_ON_MAC" = "yes" ]; then if [ "$CFG_FRAMEWORK" = "yes" ]; then QT_INSTALL_LIBS="/Libraries/Frameworks" fi @@ -3263,7 +3244,7 @@ QT_INSTALL_LIBS=`"$relpath/config.tests/unix/makeabs" "$QT_INSTALL_LIBS"` if [ -z "$QT_INSTALL_BINS" ]; then #default if [ "$CFG_PREFIX_INSTALL" = "no" ]; then - if [ "$PLATFORM_MAC" = "yes" ]; then + if [ "$BUILD_ON_MAC" = "yes" ]; then QT_INSTALL_BINS="/Developer/Applications/Qt" fi fi @@ -3273,7 +3254,7 @@ QT_INSTALL_BINS=`"$relpath/config.tests/unix/makeabs" "$QT_INSTALL_BINS"` if [ -z "$QT_INSTALL_PLUGINS" ]; then #default if [ "$CFG_PREFIX_INSTALL" = "no" ]; then - if [ "$PLATFORM_MAC" = "yes" ]; then + if [ "$BUILD_ON_MAC" = "yes" ]; then QT_INSTALL_PLUGINS="/Developer/Applications/Qt/plugins" fi fi @@ -3283,7 +3264,7 @@ QT_INSTALL_PLUGINS=`"$relpath/config.tests/unix/makeabs" "$QT_INSTALL_PLUGINS"` if [ -z "$QT_INSTALL_IMPORTS" ]; then #default if [ "$CFG_PREFIX_INSTALL" = "no" ]; then - if [ "$PLATFORM_MAC" = "yes" ]; then + if [ "$BUILD_ON_MAC" = "yes" ]; then QT_INSTALL_IMPORTS="/Developer/Applications/Qt/imports" fi fi @@ -3302,7 +3283,7 @@ fi QT_INSTALL_TRANSLATIONS=`"$relpath/config.tests/unix/makeabs" "$QT_INSTALL_TRANSLATIONS"` if [ -z "$QT_INSTALL_SETTINGS" ]; then #default - if [ "$PLATFORM_MAC" = "yes" ]; then + if [ "$BUILD_ON_MAC" = "yes" ]; then QT_INSTALL_SETTINGS=/Library/Preferences/Qt else QT_INSTALL_SETTINGS=/etc/xdg @@ -3312,7 +3293,7 @@ QT_INSTALL_SETTINGS=`"$relpath/config.tests/unix/makeabs" "$QT_INSTALL_SETTINGS" if [ -z "$QT_INSTALL_EXAMPLES" ]; then #default if [ "$CFG_PREFIX_INSTALL" = "no" ]; then - if [ "$PLATFORM_MAC" = "yes" ]; then + if [ "$BUILD_ON_MAC" = "yes" ]; then QT_INSTALL_EXAMPLES="/Developer/Examples/Qt" fi fi @@ -3323,7 +3304,7 @@ QT_INSTALL_EXAMPLES=`"$relpath/config.tests/unix/makeabs" "$QT_INSTALL_EXAMPLES" #tests if [ -z "$QT_INSTALL_TESTS" ]; then #default if [ "$CFG_PREFIX_INSTALL" = "no" ]; then - if [ "$PLATFORM_MAC" = "yes" ]; then + if [ "$BUILD_ON_MAC" = "yes" ]; then QT_INSTALL_TESTS="/Developer/Tests/Qt" fi fi @@ -4069,8 +4050,6 @@ if [ "$PLATFORM_QWS" = "yes" ]; then Platform="Qt for Embedded Linux" elif [ "$PLATFORM_QPA" = "yes" ]; then Platform="Qt Lighthouse" -elif [ "$PLATFORM_MAC" = "yes" ]; then - Platform="Qt for Mac OS X" elif [ "$XPLATFORM_MINGW" = "yes" ]; then Platform="Qt for Windows" elif [ '!' -z "`getQMakeConf \"$XQMAKESPEC\" | grep QMAKE_LIBS_X11 | awk '{print $3;}'`" ]; then @@ -4849,7 +4828,7 @@ for _SQLDR in $CFG_SQL_AVAILABLE; do ;; odbc) if [ "$CFG_SQL_odbc" != "no" ]; then - if ( [ "$PLATFORM_MAC" != "yes" ] || [ "$XPLATFORM_MINGW" = "yes" ] ) && "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/odbc "ODBC" $L_FLAGS $I_FLAGS $l_FLAGS $MAC_CONFIG_TEST_COMMANDLINE; then + if ( [ "$BUILD_ON_MAC" != "yes" ] || [ "$XPLATFORM_MINGW" = "yes" ] ) && "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/odbc "ODBC" $L_FLAGS $I_FLAGS $l_FLAGS $MAC_CONFIG_TEST_COMMANDLINE; then if [ "$CFG_SQL_odbc" = "auto" ]; then CFG_SQL_odbc=plugin fi @@ -5559,7 +5538,7 @@ if [ "$PLATFORM_X11" = "yes" ]; then fi # X11 -if [ "$PLATFORM_MAC" = "yes" ]; then +if [ "$BUILD_ON_MAC" = "yes" ]; then if [ "$CFG_PHONON" != "no" ]; then # Always enable Phonon (unless it was explicitly disabled) CFG_PHONON=yes @@ -5577,9 +5556,7 @@ fi if [ "$PLATFORM_QPA" = "yes" ]; then # auto-detect OpenGL support (es2 = OpenGL ES 2.x) - if [ "$PLATFORM_MAC" = "yes" ]; then - CFG_OPENGL=desktop - elif [ "$CFG_OPENGL" = "auto" ] || [ "$CFG_OPENGL" = "yes" ]; then + if [ "$CFG_OPENGL" = "auto" ] || [ "$CFG_OPENGL" = "yes" ]; then if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengldesktop "OpenGL" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then CFG_OPENGL=desktop elif "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengles2 "OpenGL ES 2.x" $L_FLAGS $I_FLAGS $l_FLAGS; then @@ -5963,7 +5940,6 @@ fi # freetype support [ "x$CFG_EMBEDDED" != "xno" ] && CFG_LIBFREETYPE="$CFG_QWS_FREETYPE" -[ "x$PLATFORM_MAC" = "xyes" ] && CFG_LIBFREETYPE=no [ "$XPLATFORM_MINGW" = "yes" ] && [ "$CFG_LIBFREETYPE" = "auto" ] && CFG_LIBFREETYPE=no if [ "$CFG_LIBFREETYPE" = "auto" ]; then if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/freetype "FreeType" $L_FLAGS $I_FLAGS $l_FLAGS $MAC_CONFIG_TEST_COMMANDLINE; then @@ -5976,7 +5952,7 @@ fi if [ "$CFG_ENDIAN" = "auto" ]; then if [ "$XPLATFORM_MINGW" = "yes" ]; then CFG_ENDIAN="Q_LITTLE_ENDIAN" - elif [ "$PLATFORM_MAC" = "yes" ]; then + elif [ "$BUILD_ON_MAC" = "yes" ]; then true #leave as auto else "$unixtests/endian.test" "$XQMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath" "QMAKE_LFLAGS+=$SYSROOT_FLAG" @@ -5997,7 +5973,7 @@ if [ "$CFG_ENDIAN" = "auto" ]; then fi if [ "$CFG_HOST_ENDIAN" = "auto" ]; then - if [ "$PLATFORM_MAC" = "yes" ]; then + if [ "$BUILD_ON_MAC" = "yes" ]; then true #leave as auto else "$unixtests/endian.test" "$QMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath" @@ -6554,7 +6530,7 @@ else fi -if [ "x$PLATFORM_MAC" = "xyes" ] && [ "$XPLATFORM_MINGW" != "yes" ]; then +if [ "x$BUILD_ON_MAC" = "xyes" ] && [ "$XPLATFORM_MINGW" != "yes" ]; then #On Mac we implicitly link against libz, so we #never use the 3rdparty stuff. [ "$CFG_ZLIB" = "yes" ] && CFG_ZLIB="system" @@ -7053,7 +7029,7 @@ if [ "$CFG_FRAMEWORK" = "yes" ]; then echo "#define QT_MAC_FRAMEWORK_BUILD" >>"$outpath/src/corelib/global/qconfig.h.new" fi -if [ "$PLATFORM_MAC" = "yes" ]; then +if [ "$BUILD_ON_MAC" = "yes" ]; then cat >>"$outpath/src/corelib/global/qconfig.h.new" <> "$QTMODULE.tmp" fi -# mac gcc -Xarch support -if [ "$CFG_MAC_XARCH" = "no" ]; then - echo "QMAKE_MAC_XARCH = no" >> "$QTMODULE.tmp" -fi - # cmdline args cat "$QMAKE_VARS_FILE" >> "$QTMODULE.tmp" rm -f "$QMAKE_VARS_FILE" 2>/dev/null @@ -7702,7 +7673,7 @@ elif [ "$CFG_OPENSSL" = "linked" ]; then fi echo "OpenSSL support ........ $CFG_OPENSSL $OPENSSL_LINKAGE" echo "Alsa support ........... $CFG_ALSA" -if [ "$PLATFORM_MAC" = "yes" ]; then +if [ "$BUILD_ON_MAC" = "yes" ]; then echo "CoreWlan support ....... $CFG_COREWLAN" fi echo "libICU support ......... $CFG_ICU" @@ -7734,7 +7705,7 @@ if [ "$CFG_OPENSSL" = "linked" ] && [ "$OPENSSL_LIBS" = "" ]; then echo " OPENSSL_LIBS='-L/opt/ssl/lib -lssl -lcrypto' ./configure -openssl-linked" echo fi -if [ "$PLATFORM_MAC" = "yes" ] && [ "$CFG_FRAMEWORK" = "yes" ] && [ "$CFG_DEBUG" = "yes" ] && [ "$CFG_DEBUG_RELEASE" = "no" ]; then +if [ "$BUILD_ON_MAC" = "yes" ] && [ "$CFG_FRAMEWORK" = "yes" ] && [ "$CFG_DEBUG" = "yes" ] && [ "$CFG_DEBUG_RELEASE" = "no" ]; then echo echo "Error: debug-only framework builds are not supported. Configure with -no-framework" echo "if you want a pure debug build." From 647aa53d72ad15f39dea676b97f6b4b21f8c9143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 13 Feb 2012 14:35:58 +0100 Subject: [PATCH 199/406] Don't hard-code paths to /usr/X11R6 in linux-mkspecs It was causing issues when cross-compiling with a sysroot, as the paths were not prefixed with the sysroot. The right include paths should be taken care of by pkgconfig anyways. Change-Id: I2cf7bf6377c88e6bf3b015100444d082530337ec Reviewed-by: Thiago Macieira --- mkspecs/common/linux.conf | 8 ++++---- mkspecs/linux-cxx/qmake.conf | 8 ++++---- mkspecs/linux-ecc-64/qmake.conf | 8 ++++---- mkspecs/linux-icc/qmake.conf | 8 ++++---- mkspecs/linux-kcc/qmake.conf | 8 ++++---- mkspecs/linux-pgcc/qmake.conf | 8 ++++---- mkspecs/unsupported/linux-host-g++/qmake.conf | 8 ++++---- 7 files changed, 28 insertions(+), 28 deletions(-) diff --git a/mkspecs/common/linux.conf b/mkspecs/common/linux.conf index de28ec7d1fc..0771bb79ebd 100644 --- a/mkspecs/common/linux.conf +++ b/mkspecs/common/linux.conf @@ -7,12 +7,12 @@ QMAKE_CXXFLAGS_THREAD += $$QMAKE_CFLAGS_THREAD QMAKE_INCDIR = QMAKE_LIBDIR = -QMAKE_INCDIR_X11 = /usr/X11R6/include -QMAKE_LIBDIR_X11 = /usr/X11R6/lib +QMAKE_INCDIR_X11 = +QMAKE_LIBDIR_X11 = QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] -QMAKE_INCDIR_OPENGL = /usr/X11R6/include -QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib +QMAKE_INCDIR_OPENGL = +QMAKE_LIBDIR_OPENGL = QMAKE_INCDIR_OPENGL_ES1 = $$QMAKE_INCDIR_OPENGL QMAKE_LIBDIR_OPENGL_ES1 = $$QMAKE_LIBDIR_OPENGL QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_INCDIR_OPENGL diff --git a/mkspecs/linux-cxx/qmake.conf b/mkspecs/linux-cxx/qmake.conf index ce303b7f90f..79aa834a90e 100644 --- a/mkspecs/linux-cxx/qmake.conf +++ b/mkspecs/linux-cxx/qmake.conf @@ -38,12 +38,12 @@ QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC QMAKE_INCDIR = QMAKE_LIBDIR = -QMAKE_INCDIR_X11 = /usr/X11R6/include -QMAKE_LIBDIR_X11 = /usr/X11R6/lib +QMAKE_INCDIR_X11 = +QMAKE_LIBDIR_X11 = QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] -QMAKE_INCDIR_OPENGL = /usr/X11R6/include -QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib +QMAKE_INCDIR_OPENGL = +QMAKE_LIBDIR_OPENGL = QMAKE_LINK = cxx QMAKE_LINK_SHLIB = cxx diff --git a/mkspecs/linux-ecc-64/qmake.conf b/mkspecs/linux-ecc-64/qmake.conf index 61a056b7467..50f841f1d4e 100644 --- a/mkspecs/linux-ecc-64/qmake.conf +++ b/mkspecs/linux-ecc-64/qmake.conf @@ -40,12 +40,12 @@ QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD QMAKE_INCDIR = QMAKE_LIBDIR = -QMAKE_INCDIR_X11 = /usr/X11R6/include -QMAKE_LIBDIR_X11 = /usr/X11R6/lib +QMAKE_INCDIR_X11 = +QMAKE_LIBDIR_X11 = QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] -QMAKE_INCDIR_OPENGL = /usr/X11R6/include -QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib +QMAKE_INCDIR_OPENGL = +QMAKE_LIBDIR_OPENGL = QMAKE_LINK = ecpc QMAKE_LINK_SHLIB = ecpc diff --git a/mkspecs/linux-icc/qmake.conf b/mkspecs/linux-icc/qmake.conf index 38916ece5c9..4ff63cda710 100644 --- a/mkspecs/linux-icc/qmake.conf +++ b/mkspecs/linux-icc/qmake.conf @@ -46,12 +46,12 @@ QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD QMAKE_INCDIR = QMAKE_LIBDIR = -QMAKE_INCDIR_X11 = /usr/X11R6/include -QMAKE_LIBDIR_X11 = /usr/X11R6/lib +QMAKE_INCDIR_X11 = +QMAKE_LIBDIR_X11 = QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] -QMAKE_INCDIR_OPENGL = /usr/X11R6/include -QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib +QMAKE_INCDIR_OPENGL = +QMAKE_LIBDIR_OPENGL = QMAKE_LINK = icpc QMAKE_LINK_SHLIB = icpc diff --git a/mkspecs/linux-kcc/qmake.conf b/mkspecs/linux-kcc/qmake.conf index 01e3b73479f..23fd6298ac5 100644 --- a/mkspecs/linux-kcc/qmake.conf +++ b/mkspecs/linux-kcc/qmake.conf @@ -49,12 +49,12 @@ QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD QMAKE_INCDIR = QMAKE_LIBDIR = -QMAKE_INCDIR_X11 = /usr/X11R6/include -QMAKE_LIBDIR_X11 = /usr/X11R6/lib +QMAKE_INCDIR_X11 = +QMAKE_LIBDIR_X11 = QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] -QMAKE_INCDIR_OPENGL = /usr/X11R6/include -QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib +QMAKE_INCDIR_OPENGL = +QMAKE_LIBDIR_OPENGL = QMAKE_LINK = KCC QMAKE_LINK_SHLIB = KCC diff --git a/mkspecs/linux-pgcc/qmake.conf b/mkspecs/linux-pgcc/qmake.conf index 63ede781a7d..ed882156098 100644 --- a/mkspecs/linux-pgcc/qmake.conf +++ b/mkspecs/linux-pgcc/qmake.conf @@ -40,12 +40,12 @@ QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD QMAKE_INCDIR = QMAKE_LIBDIR = -QMAKE_INCDIR_X11 = /usr/X11R6/include -QMAKE_LIBDIR_X11 = /usr/X11R6/lib +QMAKE_INCDIR_X11 = +QMAKE_LIBDIR_X11 = QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] -QMAKE_INCDIR_OPENGL = /usr/X11R6/include -QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib +QMAKE_INCDIR_OPENGL = +QMAKE_LIBDIR_OPENGL = QMAKE_LINK = pgCC QMAKE_LINK_SHLIB = pgCC diff --git a/mkspecs/unsupported/linux-host-g++/qmake.conf b/mkspecs/unsupported/linux-host-g++/qmake.conf index 46ecf375e87..1ad529ebae7 100644 --- a/mkspecs/unsupported/linux-host-g++/qmake.conf +++ b/mkspecs/unsupported/linux-host-g++/qmake.conf @@ -80,12 +80,12 @@ QMAKE_CXXFLAGS_THREAD += $$QMAKE_CFLAGS_THREAD QMAKE_INCDIR = QMAKE_LIBDIR = -QMAKE_INCDIR_X11 = /usr/X11R6/include -QMAKE_LIBDIR_X11 = /usr/X11R6/lib +QMAKE_INCDIR_X11 = +QMAKE_LIBDIR_X11 = QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] -QMAKE_INCDIR_OPENGL = /usr/X11R6/include -QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib +QMAKE_INCDIR_OPENGL = +QMAKE_LIBDIR_OPENGL = QMAKE_INCDIR_OPENGL_ES1 = $$QMAKE_INCDIR_OPENGL QMAKE_LIBDIR_OPENGL_ES1 = $$QMAKE_LIBDIR_OPENGL QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_INCDIR_OPENGL From 2907fbd8982203053a16a0cf8a6c4b72b2c61984 Mon Sep 17 00:00:00 2001 From: Christoph Schleifenbaum Date: Tue, 31 Jan 2012 16:15:51 +0100 Subject: [PATCH 200/406] Add QCocoaColor- and FontDialogHelper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ie6e648e9e1f4ffbb34d73f9afdd6cc77e86bc3d1 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/cocoa.pro | 4 + .../platforms/cocoa/qcocoacolordialoghelper.h | 78 +++ .../cocoa/qcocoacolordialoghelper.mm | 465 +++++++++++++++++ .../platforms/cocoa/qcocoafontdialoghelper.h | 82 +++ .../platforms/cocoa/qcocoafontdialoghelper.mm | 488 ++++++++++++++++++ src/plugins/platforms/cocoa/qcocoatheme.mm | 25 +- src/widgets/dialogs/qcolordialog.cpp | 6 +- 7 files changed, 1140 insertions(+), 8 deletions(-) create mode 100644 src/plugins/platforms/cocoa/qcocoacolordialoghelper.h create mode 100644 src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm create mode 100644 src/plugins/platforms/cocoa/qcocoafontdialoghelper.h create mode 100644 src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index 09b708d9a19..1e803a1c7c6 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -23,7 +23,9 @@ OBJECTIVE_SOURCES += main.mm \ qmultitouch_mac.mm \ qcocoaaccessibilityelement.mm \ qcocoaaccessibility.mm \ + qcocoacolordialoghelper.mm \ qcocoafiledialoghelper.mm \ + qcocoafontdialoghelper.mm \ qcocoacursor.mm \ HEADERS += qcocoaintegration.h \ @@ -45,7 +47,9 @@ HEADERS += qcocoaintegration.h \ qmultitouch_mac_p.h \ qcocoaaccessibilityelement.h \ qcocoaaccessibility.h \ + qcocoacolordialoghelper.h \ qcocoafiledialoghelper.h \ + qcocoafontdialoghelper.h \ qcocoacursor.h \ FORMS += $$PWD/../../../widgets/dialogs/qfiledialog.ui diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h new file mode 100644 index 00000000000..505fd4f1115 --- /dev/null +++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui 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 QCOCOACOLORDIALOGHELPER_H +#define QCOCOACOLORDIALOGHELPER_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QCocoaColorDialogHelper : public QPlatformColorDialogHelper +{ +public: + QCocoaColorDialogHelper(); + virtual ~QCocoaColorDialogHelper(); + + void platformNativeDialogModalHelp(); + void _q_platformRunNativeAppModalPanel(); + void deleteNativeDialog_sys(); + bool show_sys(QFlags, Qt::WindowFlags, QWindow*); + void hide_sys(); + + DialogCode dialogResultCode_sys(); + void setCurrentColor_sys(const QColor&); + QColor currentColor_sys() const; + +public: + bool showCocoaColorPanel(QWindow *parent); + bool hideCocoaColorPanel(); + + void createNSColorPanelDelegate(); + +private: + void *mDelegate; +}; + +QT_END_NAMESPACE + +#endif // QCOCOACOLORDIALOGHELPER_H diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm new file mode 100644 index 00000000000..f1d6129e3dd --- /dev/null +++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm @@ -0,0 +1,465 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui 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 "qcocoacolordialoghelper.h" + +#ifndef QT_NO_COLORDIALOG + +#include +#include +#include +#include + +#include "qcocoahelpers.h" + +#import + +QT_USE_NAMESPACE + +static NSButton *macCreateButton(const char *text, NSView *superview) +{ + static const NSRect buttonFrameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } }; + + NSButton *button = [[NSButton alloc] initWithFrame:buttonFrameRect]; + [button setButtonType:NSMomentaryLightButton]; + [button setBezelStyle:NSRoundedBezelStyle]; + [button setTitle:(NSString*)(CFStringRef)QCFString(QDialogButtonBox::tr(text) + .remove(QLatin1Char('&')))]; + [[button cell] setFont:[NSFont systemFontOfSize: + [NSFont systemFontSizeForControlSize:NSRegularControlSize]]]; + [superview addSubview:button]; + return button; +} + +@class QT_MANGLE_NAMESPACE(QNSColorPanelDelegate); + +@interface QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) : NSObject +{ + @public + NSColorPanel *mColorPanel; + QCocoaColorDialogHelper *mHelper; + NSView *mStolenContentView; + NSButton *mOkButton; + NSButton *mCancelButton; + QColor mQtColor; + NSInteger mResultCode; + BOOL mDialogIsExecuting; + BOOL mResultSet; +}; +- (void)relayout; +- (void)updateQtColor; +- (void)finishOffWithCode:(NSInteger)code; +@end + +@implementation QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) + +- (id)initWithDialogHelper:(QCocoaColorDialogHelper *)helper +{ + self = [super init]; + mColorPanel = [NSColorPanel sharedColorPanel]; + mHelper = helper; + mResultCode = NSCancelButton; + mDialogIsExecuting = false; + mResultSet = false; + + if (mHelper->options()->testOption(QColorDialogOptions::NoButtons)) { + mStolenContentView = 0; + mOkButton = 0; + mCancelButton = 0; + } else { + // steal the color panel's contents view + mStolenContentView = [mColorPanel contentView]; + [mStolenContentView retain]; + [mColorPanel setContentView:0]; + + // create a new content view and add the stolen one as a subview + NSRect frameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } }; + NSView *ourContentView = [[NSView alloc] initWithFrame:frameRect]; + [ourContentView addSubview:mStolenContentView]; + + // create OK and Cancel buttons and add these as subviews + mOkButton = macCreateButton("&OK", ourContentView); + mCancelButton = macCreateButton("Cancel", ourContentView); + + [mColorPanel setContentView:ourContentView]; + [mColorPanel setDefaultButtonCell:[mOkButton cell]]; + [self relayout]; + + [mOkButton setAction:@selector(onOkClicked)]; + [mOkButton setTarget:self]; + + [mCancelButton setAction:@selector(onCancelClicked)]; + [mCancelButton setTarget:self]; + } + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(colorChanged:) + name:NSColorPanelColorDidChangeNotification + object:mColorPanel]; + + [mColorPanel retain]; + return self; +} + +- (void)dealloc +{ + if (mOkButton) { + NSView *ourContentView = [mColorPanel contentView]; + + // return stolen stuff to its rightful owner + [mStolenContentView removeFromSuperview]; + [mColorPanel setContentView:mStolenContentView]; + [mOkButton release]; + [mCancelButton release]; + [ourContentView release]; + } + + [mColorPanel setDelegate:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [super dealloc]; +} + +- (void)closePanel +{ + [mColorPanel close]; +} + +- (void)windowDidResize:(NSNotification *)notification +{ + Q_UNUSED(notification); + [self relayout]; +} + +- (void)colorChanged:(NSNotification *)notification +{ + Q_UNUSED(notification); + [self updateQtColor]; + emit mHelper->colorSelected(mQtColor); +} + +- (void)relayout +{ + if (!mOkButton) + return; + + NSRect rect = [[mStolenContentView superview] frame]; + + // should a priori be kept in sync with qfontdialog_mac.mm + const CGFloat ButtonMinWidth = 78.0; // 84.0 for Carbon + const CGFloat ButtonMinHeight = 32.0; + const CGFloat ButtonSpacing = 0.0; + const CGFloat ButtonTopMargin = 0.0; + const CGFloat ButtonBottomMargin = 7.0; + const CGFloat ButtonSideMargin = 9.0; + + [mOkButton sizeToFit]; + NSSize okSizeHint = [mOkButton frame].size; + + [mCancelButton sizeToFit]; + NSSize cancelSizeHint = [mCancelButton frame].size; + + const CGFloat ButtonWidth = qMin(qMax(ButtonMinWidth, + qMax(okSizeHint.width, cancelSizeHint.width)), + CGFloat((rect.size.width - 2.0 * ButtonSideMargin - ButtonSpacing) * 0.5)); + const CGFloat ButtonHeight = qMax(ButtonMinHeight, + qMax(okSizeHint.height, cancelSizeHint.height)); + + NSRect okRect = { { rect.size.width - ButtonSideMargin - ButtonWidth, + ButtonBottomMargin }, + { ButtonWidth, ButtonHeight } }; + [mOkButton setFrame:okRect]; + [mOkButton setNeedsDisplay:YES]; + + NSRect cancelRect = { { okRect.origin.x - ButtonSpacing - ButtonWidth, + ButtonBottomMargin }, + { ButtonWidth, ButtonHeight } }; + [mCancelButton setFrame:cancelRect]; + [mCancelButton setNeedsDisplay:YES]; + + const CGFloat Y = ButtonBottomMargin + ButtonHeight + ButtonTopMargin; + NSRect stolenCVRect = { { 0.0, Y }, + { rect.size.width, rect.size.height - Y } }; + [mStolenContentView setFrame:stolenCVRect]; + [mStolenContentView setNeedsDisplay:YES]; + + [[mStolenContentView superview] setNeedsDisplay:YES]; +} + +- (void)onOkClicked +{ + Q_ASSERT(mHackedPanel); + [mColorPanel close]; + [self updateQtColor]; + [self finishOffWithCode:NSOKButton]; +} + +- (void)onCancelClicked +{ + if (mOkButton) { + [mColorPanel close]; + mQtColor = QColor(); + [self finishOffWithCode:NSCancelButton]; + } +} + +- (void)updateQtColor +{ + NSColor *color = [mColorPanel color]; + NSString *colorSpaceName = [color colorSpaceName]; + if (colorSpaceName == NSDeviceCMYKColorSpace) { + CGFloat cyan = 0, magenta = 0, yellow = 0, black = 0, alpha = 0; + [color getCyan:&cyan magenta:&magenta yellow:&yellow black:&black alpha:&alpha]; + mQtColor.setCmykF(cyan, magenta, yellow, black, alpha); + } else if (colorSpaceName == NSCalibratedRGBColorSpace || colorSpaceName == NSDeviceRGBColorSpace) { + CGFloat red = 0, green = 0, blue = 0, alpha = 0; + [color getRed:&red green:&green blue:&blue alpha:&alpha]; + mQtColor.setRgbF(red, green, blue, alpha); + } else if (colorSpaceName == NSNamedColorSpace) { + NSColor *tmpColor = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; + CGFloat red = 0, green = 0, blue = 0, alpha = 0; + [tmpColor getRed:&red green:&green blue:&blue alpha:&alpha]; + mQtColor.setRgbF(red, green, blue, alpha); + } else { + NSColorSpace *colorSpace = [color colorSpace]; + if ([colorSpace colorSpaceModel] == NSCMYKColorSpaceModel && [color numberOfComponents] == 5){ + CGFloat components[5]; + [color getComponents:components]; + mQtColor.setCmykF(components[0], components[1], components[2], components[3], components[4]); + } else { + NSColor *tmpColor = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; + CGFloat red = 0, green = 0, blue = 0, alpha = 0; + [tmpColor getRed:&red green:&green blue:&blue alpha:&alpha]; + mQtColor.setRgbF(red, green, blue, alpha); + } + } + emit mHelper->currentColorChanged(mQtColor); +} + +- (void)showModelessPanel +{ + mDialogIsExecuting = false; + [mColorPanel makeKeyAndOrderFront:mColorPanel]; +} + +- (BOOL)runApplicationModalPanel +{ + mDialogIsExecuting = true; + [mColorPanel setDelegate:self]; + [mColorPanel setContinuous:YES]; + [NSApp runModalForWindow:mColorPanel]; + return (mResultCode == NSOKButton); +} + +- (QT_PREPEND_NAMESPACE(QPlatformDialogHelper::DialogCode))dialogResultCode +{ + return (mResultCode == NSOKButton) ? QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Accepted) : QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Rejected); +} + +- (BOOL)windowShouldClose:(id)window +{ + Q_UNUSED(window); + if (!mOkButton) + [self updateQtColor]; + if (mDialogIsExecuting) { + [self finishOffWithCode:NSCancelButton]; + } else { + mResultSet = true; + emit mHelper->reject(); + } + return true; +} + +- (void)finishOffWithCode:(NSInteger)code +{ + mResultCode = code; + if (mDialogIsExecuting) { + // We stop the current modal event loop. The control + // will then return inside -(void)exec below. + // It's important that the modal event loop is stopped before + // we accept/reject QColorDialog, since QColorDialog has its + // own event loop that needs to be stopped last. + [NSApp stopModalWithCode:code]; + } else { + // Since we are not in a modal event loop, we can safely close + // down QColorDialog + // Calling accept() or reject() can in turn call closeCocoaColorPanel. + // This check will prevent any such recursion. + if (!mResultSet) { + mResultSet = true; + if (mResultCode == NSCancelButton) { + emit mHelper->reject(); + } else { + emit mHelper->accept(); + } + } + } +} + +@end + +QT_BEGIN_NAMESPACE + +QCocoaColorDialogHelper::QCocoaColorDialogHelper() : + mDelegate(0) +{ +} + +QCocoaColorDialogHelper::~QCocoaColorDialogHelper() +{ + deleteNativeDialog_sys(); +} + +void QCocoaColorDialogHelper::platformNativeDialogModalHelp() +{ + // Do a queued meta-call to open the native modal dialog so it opens after the new + // event loop has started to execute (in QDialog::exec). Using a timer rather than + // a queued meta call is intentional to ensure that the call is only delivered when + // [NSApp run] runs (timers are handeled special in cocoa). If NSApp is not + // running (which is the case if e.g a top-most QEventLoop has been + // interrupted, and the second-most event loop has not yet been reactivated (regardless + // if [NSApp run] is still on the stack)), showing a native modal dialog will fail. + QTimer::singleShot(1, this, SIGNAL(launchNativeAppModalPanel())); +} + +void QCocoaColorDialogHelper::_q_platformRunNativeAppModalPanel() +{ + // TODO: +#if 0 + QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active); +#endif + QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *delegate = static_cast(mDelegate); + [delegate runApplicationModalPanel]; + if (dialogResultCode_sys() == QPlatformDialogHelper::Accepted) + emit accept(); + else + emit reject(); +} + +void QCocoaColorDialogHelper::deleteNativeDialog_sys() +{ + if (!mDelegate) + return; + [reinterpret_cast(mDelegate) release]; + mDelegate = 0; +} + +bool QCocoaColorDialogHelper::show_sys(QFlags, Qt::WindowFlags, QWindow *parent) +{ + return showCocoaColorPanel(parent); +} + +void QCocoaColorDialogHelper::hide_sys() +{ + if (!mDelegate) + return; + [reinterpret_cast(mDelegate)->mColorPanel close]; +} + +QCocoaColorDialogHelper::DialogCode QCocoaColorDialogHelper::dialogResultCode_sys() +{ + QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *delegate = static_cast(mDelegate); + return [delegate dialogResultCode]; +} + +void QCocoaColorDialogHelper::setCurrentColor_sys(const QColor &color) +{ + if (!mDelegate) + createNSColorPanelDelegate(); + QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *delegate = static_cast(mDelegate); + NSColor *nsColor; + const QColor::Spec spec = color.spec(); + if (spec == QColor::Cmyk) { + nsColor = [NSColor colorWithDeviceCyan:color.cyanF() + magenta:color.magentaF() + yellow:color.yellowF() + black:color.blackF() + alpha:color.alphaF()]; + } else { + nsColor = [NSColor colorWithCalibratedRed:color.redF() + green:color.greenF() + blue:color.blueF() + alpha:color.alphaF()]; + } + delegate->mQtColor = color; + [delegate->mColorPanel setColor:nsColor]; +} + +QColor QCocoaColorDialogHelper::currentColor_sys() const +{ + return reinterpret_cast(mDelegate)->mQtColor; +} + +void QCocoaColorDialogHelper::createNSColorPanelDelegate() +{ + if (mDelegate) + return; + + QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) alloc] + initWithDialogHelper:this]; + + mDelegate = delegate; +} + +bool QCocoaColorDialogHelper::showCocoaColorPanel(QWindow *parent) +{ + Q_UNUSED(parent); + createNSColorPanelDelegate(); + QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *delegate = static_cast(mDelegate); + [delegate->mColorPanel setShowsAlpha:options()->testOption(QColorDialogOptions::ShowAlphaChannel)]; + [delegate showModelessPanel]; + return true; +} + +bool QCocoaColorDialogHelper::hideCocoaColorPanel() +{ + if (!mDelegate){ + return false; + } else { + QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *delegate = static_cast(mDelegate); + [delegate closePanel]; + return true; + } +} + +QT_END_NAMESPACE + +#endif // QT_NO_COLORDIALOG diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h new file mode 100644 index 00000000000..8a914bf6329 --- /dev/null +++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui 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 QCOCOAFONTDIALOGHELPER_H +#define QCOCOAFONTDIALOGHELPER_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QFontDialog; +class QFontDialogPrivate; + +class QCocoaFontDialogHelper : public QPlatformFontDialogHelper +{ +public: + QCocoaFontDialogHelper(); + virtual ~QCocoaFontDialogHelper(); + + void platformNativeDialogModalHelp(); + void _q_platformRunNativeAppModalPanel(); + void deleteNativeDialog_sys(); + + bool show_sys(ShowFlags showFlags, Qt::WindowFlags windowFlags, QWindow *parent); + void hide_sys(); + + QPlatformDialogHelper::DialogCode dialogResultCode_sys(); + + void setCurrentFont_sys(const QFont &); + QFont currentFont_sys() const; + +protected: + void createNSFontPanelDelegate(); + bool showCocoaFontPanel(QWindow *parent); + bool hideCocoaFontPanel(); + +private: + void *mDelegate; +}; + +QT_END_NAMESPACE + +#endif // QCOCOAFONTDIALOGHELPER_H diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm new file mode 100644 index 00000000000..5d40e5c48ca --- /dev/null +++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm @@ -0,0 +1,488 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui 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 "qcocoafontdialoghelper.h" + +#ifndef QT_NO_FONTDIALOG + +#include +#include +#include +#include + +#include +#include +#include + +#include "qcocoahelpers.h" + +#import + +#if !CGFLOAT_DEFINED +typedef float CGFloat; // Should only not be defined on 32-bit platforms +#endif + +QT_USE_NAMESPACE + +// should a priori be kept in sync with qcolordialog_mac.mm +const CGFloat ButtonMinWidth = 78.0; +const CGFloat ButtonMinHeight = 32.0; +const CGFloat ButtonSpacing = 0.0; +const CGFloat ButtonTopMargin = 0.0; +const CGFloat ButtonBottomMargin = 7.0; +const CGFloat ButtonSideMargin = 9.0; + +// looks better with some margins +const CGFloat DialogTopMargin = 7.0; +const CGFloat DialogSideMargin = 9.0; + +static NSButton *macCreateButton(const char *text, NSView *superview) +{ + static const NSRect buttonFrameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } }; + + NSButton *button = [[NSButton alloc] initWithFrame:buttonFrameRect]; + [button setButtonType:NSMomentaryLightButton]; + [button setBezelStyle:NSRoundedBezelStyle]; + [button setTitle:(NSString*)(CFStringRef)QCFString(QDialogButtonBox::tr(text) + .remove(QLatin1Char('&')))]; + [[button cell] setFont:[NSFont systemFontOfSize: + [NSFont systemFontSizeForControlSize:NSRegularControlSize]]]; + [superview addSubview:button]; + return button; +} + +static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont) +{ + QFont newFont; + if (cocoaFont) { + int pSize = qRound([cocoaFont pointSize]); + QString family(QCFString::toQString([cocoaFont familyName])); + QString typeface(QCFString::toQString([cocoaFont fontName])); + + int hyphenPos = typeface.indexOf(QLatin1Char('-')); + if (hyphenPos != -1) { + typeface.remove(0, hyphenPos + 1); + } else { + typeface = QLatin1String("Normal"); + } + + newFont = QFontDatabase().font(family, typeface, pSize); + newFont.setUnderline(resolveFont.underline()); + newFont.setStrikeOut(resolveFont.strikeOut()); + + } + return newFont; +} + +@class QT_MANGLE_NAMESPACE(QNSFontPanelDelegate); + +@interface QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) : NSObject +{ + @public + NSFontPanel *mFontPanel; + QCocoaFontDialogHelper *mHelper; + NSView *mStolenContentView; + NSButton *mOkButton; + NSButton *mCancelButton; + QFont mQtFont; + NSInteger mResultCode; + BOOL mDialogIsExecuting; + BOOL mResultSet; +}; +- (void)relayout; +- (void)relayoutToContentSize:(NSSize)frameSize; +- (void)updateQtFont; +- (void)changeFont:(id)sender; +- (void)finishOffWithCode:(NSInteger)code; +@end + +@implementation QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) + +- (id)initWithDialogHelper: + (QCocoaFontDialogHelper *)helper +{ + self = [super init]; + mFontPanel = [NSFontPanel sharedFontPanel]; + mHelper = helper; + mResultCode = NSCancelButton; + mDialogIsExecuting = false; + mResultSet = false; + + [mFontPanel setTitle:QCFString::toNSString(helper->options()->windowTitle())]; + + if (mHelper->options()->testOption(QFontDialogOptions::NoButtons)) { + mStolenContentView = 0; + mOkButton = 0; + mCancelButton = 0; + } else { + // steal the font panel's contents view + mStolenContentView = [mFontPanel contentView]; + [mStolenContentView retain]; + [mFontPanel setContentView:0]; + + // create a new content view and add the stolen one as a subview + NSRect frameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } }; + NSView *ourContentView = [[NSView alloc] initWithFrame:frameRect]; + [ourContentView addSubview:mStolenContentView]; + + // create OK and Cancel buttons and add these as subviews + mOkButton = macCreateButton("&OK", ourContentView); + mCancelButton = macCreateButton("Cancel", ourContentView); + + [mFontPanel setContentView:ourContentView]; + [mFontPanel setDefaultButtonCell:[mOkButton cell]]; + [self relayoutToContentSize:[[mStolenContentView superview] frame].size]; + + [mOkButton setAction:@selector(onOkClicked)]; + [mOkButton setTarget:self]; + + [mCancelButton setAction:@selector(onCancelClicked)]; + [mCancelButton setTarget:self]; + } + + [mFontPanel retain]; + return self; +} + +- (void)dealloc +{ + if (mOkButton) { + NSView *ourContentView = [mFontPanel contentView]; + + // return stolen stuff to its rightful owner + [mStolenContentView removeFromSuperview]; + [mFontPanel setContentView:mStolenContentView]; + [mOkButton release]; + [mCancelButton release]; + [ourContentView release]; + } + + [mFontPanel setDelegate:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [super dealloc]; +} + +- (void)closePanel +{ + [mFontPanel close]; +} + +- (void)windowDidResize:(NSNotification *)notification +{ + Q_UNUSED(notification); + if (mOkButton) + [self relayout]; +} + +- (void)relayout +{ + [self relayoutToContentSize:[[mStolenContentView superview] frame].size]; +} + +- (void)relayoutToContentSize:(NSSize)frameSize +{ + Q_ASSERT(mOkButton); + + [mOkButton sizeToFit]; + NSSize okSizeHint = [mOkButton frame].size; + + [mCancelButton sizeToFit]; + NSSize cancelSizeHint = [mCancelButton frame].size; + + const CGFloat ButtonWidth = qMin(qMax(ButtonMinWidth, + qMax(okSizeHint.width, cancelSizeHint.width)), + CGFloat((frameSize.width - 2.0 * ButtonSideMargin - ButtonSpacing) * 0.5)); + const CGFloat ButtonHeight = qMax(ButtonMinHeight, + qMax(okSizeHint.height, cancelSizeHint.height)); + + const CGFloat X = DialogSideMargin; + const CGFloat Y = ButtonBottomMargin + ButtonHeight + ButtonTopMargin; + + NSRect okRect = { { frameSize.width - ButtonSideMargin - ButtonWidth, + ButtonBottomMargin }, + { ButtonWidth, ButtonHeight } }; + [mOkButton setFrame:okRect]; + [mOkButton setNeedsDisplay:YES]; + + NSRect cancelRect = { { okRect.origin.x - ButtonSpacing - ButtonWidth, + ButtonBottomMargin }, + { ButtonWidth, ButtonHeight } }; + [mCancelButton setFrame:cancelRect]; + [mCancelButton setNeedsDisplay:YES]; + + NSRect stolenCVRect = { { X, Y }, + { frameSize.width - X - X, frameSize.height - Y - DialogTopMargin } }; + [mStolenContentView setFrame:stolenCVRect]; + [mStolenContentView setNeedsDisplay:YES]; + + [[mStolenContentView superview] setNeedsDisplay:YES]; +} + + +- (void)onOkClicked +{ + Q_ASSERT(mHackedPanel); + [mFontPanel close]; + [self finishOffWithCode:NSOKButton]; +} + +- (void)onCancelClicked +{ + if (mOkButton) { + [mFontPanel close]; + mQtFont = QFont(); + [self finishOffWithCode:NSCancelButton]; + } +} + +- (void)changeFont:(id)sender +{ + Q_UNUSED(sender); + [self updateQtFont]; +} + +- (void)updateQtFont +{ + // Get selected font + NSFontManager *fontManager = [NSFontManager sharedFontManager]; + NSFont *selectedFont = [fontManager selectedFont]; + if (selectedFont == nil) { + selectedFont = [NSFont systemFontOfSize:[NSFont systemFontSize]]; + } + NSFont *panelFont = [fontManager convertFont:selectedFont]; + mQtFont = qfontForCocoaFont(panelFont, mQtFont); + + emit mHelper->currentFontChanged(mQtFont); +} + +- (void)showModelessPanel +{ + mDialogIsExecuting = false; + [mFontPanel makeKeyAndOrderFront:mFontPanel]; +} + +- (BOOL)runApplicationModalPanel +{ + mDialogIsExecuting = true; + [mFontPanel setDelegate:self]; + [NSApp runModalForWindow:mFontPanel]; + return (mResultCode == NSOKButton); +} + +- (QT_PREPEND_NAMESPACE(QPlatformDialogHelper::DialogCode))dialogResultCode +{ + return (mResultCode == NSOKButton) ? QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Accepted) : QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Rejected); +} + +- (BOOL)windowShouldClose:(id)window +{ + Q_UNUSED(window); + if (!mOkButton) + [self updateQtFont]; + if (mDialogIsExecuting) { + [self finishOffWithCode:NSCancelButton]; + } else { + mResultSet = true; + emit mHelper->reject(); + } + return true; +} + +- (void)finishOffWithCode:(NSInteger)code +{ + mResultCode = code; + if (mDialogIsExecuting) { + // We stop the current modal event loop. The control + // will then return inside -(void)exec below. + // It's important that the modal event loop is stopped before + // we accept/reject QFontDialog, since QFontDialog has its + // own event loop that needs to be stopped last. + [NSApp stopModalWithCode:code]; + } else { + // Since we are not in a modal event loop, we can safely close + // down QFontDialog + // Calling accept() or reject() can in turn call closeCocoaFontPanel. + // This check will prevent any such recursion. + if (!mResultSet) { + mResultSet = true; + if (mResultCode == NSCancelButton) { + emit mHelper->reject(); + } else { + emit mHelper->accept(); + } + } + } +} + +@end + +QT_BEGIN_NAMESPACE + +QCocoaFontDialogHelper::QCocoaFontDialogHelper() : + mDelegate(0) +{ +} + +QCocoaFontDialogHelper::~QCocoaFontDialogHelper() +{ + deleteNativeDialog_sys(); +} + +void QCocoaFontDialogHelper::platformNativeDialogModalHelp() +{ + // Do a queued meta-call to open the native modal dialog so it opens after the new + // event loop has started to execute (in QDialog::exec). Using a timer rather than + // a queued meta call is intentional to ensure that the call is only delivered when + // [NSApp run] runs (timers are handeled special in cocoa). If NSApp is not + // running (which is the case if e.g a top-most QEventLoop has been + // interrupted, and the second-most event loop has not yet been reactivated (regardless + // if [NSApp run] is still on the stack)), showing a native modal dialog will fail. + QTimer::singleShot(1, this, SIGNAL(launchNativeAppModalPanel())); +} + +void QCocoaFontDialogHelper::_q_platformRunNativeAppModalPanel() +{ + // TODO: +#if 0 + QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active); +#endif + QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast(mDelegate); + [delegate runApplicationModalPanel]; + if (dialogResultCode_sys() == QPlatformDialogHelper::Accepted) + emit accept(); + else + emit reject(); +} + +void QCocoaFontDialogHelper::deleteNativeDialog_sys() +{ + if (!mDelegate) + return; + [reinterpret_cast(mDelegate) release]; + mDelegate = 0; +} + +bool QCocoaFontDialogHelper::show_sys(QFlags, Qt::WindowFlags, QWindow *parent) +{ + return showCocoaFontPanel(parent); +} + +void QCocoaFontDialogHelper::hide_sys() +{ + if (!mDelegate) + return; + [reinterpret_cast(mDelegate)->mFontPanel close]; +} + +QCocoaFontDialogHelper::DialogCode QCocoaFontDialogHelper::dialogResultCode_sys() +{ + QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast(mDelegate); + return [delegate dialogResultCode]; +} + +void QCocoaFontDialogHelper::setCurrentFont_sys(const QFont &font) +{ + NSFontManager *mgr = [NSFontManager sharedFontManager]; + const NSFont *nsFont = 0; + + int weight = 5; + NSFontTraitMask mask = 0; + if (font.style() == QFont::StyleItalic) { + mask |= NSItalicFontMask; + } + if (font.weight() == QFont::Bold) { + weight = 9; + mask |= NSBoldFontMask; + } + + QFontInfo fontInfo(font); + nsFont = [mgr fontWithFamily:QCFString::toNSString(fontInfo.family()) + traits:mask + weight:weight + size:fontInfo.pointSize()]; + + if (!mDelegate) + createNSFontPanelDelegate(); + + [mgr setSelectedFont:const_cast(nsFont) isMultiple:NO]; + static_cast(mDelegate)->mQtFont = font; +} + +QFont QCocoaFontDialogHelper::currentFont_sys() const +{ + return reinterpret_cast(mDelegate)->mQtFont; +} + +void QCocoaFontDialogHelper::createNSFontPanelDelegate() +{ + if (mDelegate) + return; + + QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) alloc] + initWithDialogHelper:this]; + + mDelegate = delegate; +} + +bool QCocoaFontDialogHelper::showCocoaFontPanel(QWindow *parent) +{ + Q_UNUSED(parent); + createNSFontPanelDelegate(); + QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast(mDelegate); + [delegate showModelessPanel]; + return true; +} + +bool QCocoaFontDialogHelper::hideCocoaFontPanel() +{ + if (!mDelegate){ + return false; + } else { + QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast(mDelegate); + [delegate closePanel]; + return true; + } +} + +QT_END_NAMESPACE + +#endif // QT_NO_FONTDIALOG diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index f0e58abebd6..a23faf438dc 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -42,8 +42,9 @@ #include "qcocoatheme.h" #include "qmenu_mac.h" +#include "qcocoacolordialoghelper.h" #include "qcocoafiledialoghelper.h" -#include +#include "qcocoafontdialoghelper.h" QT_BEGIN_NAMESPACE @@ -72,15 +73,33 @@ bool QCocoaTheme::usePlatformNativeDialog(DialogType dialogType) const { if (dialogType == QPlatformTheme::FileDialog) return true; +#ifndef QT_NO_COLORDIALOG + if (dialogType == QPlatformTheme::ColorDialog) + return true; +#endif +#ifndef QT_NO_FONTDIALOG + if (dialogType == QPlatformTheme::FontDialog) + return true; +#endif return false; } QPlatformDialogHelper * QCocoaTheme::createPlatformDialogHelper(DialogType dialogType) const { - if (dialogType == QPlatformTheme::FileDialog) { + switch (dialogType) { + case QPlatformTheme::FileDialog: return new QCocoaFileDialogHelper(); +#ifndef QT_NO_COLORDIALOG + case QPlatformTheme::ColorDialog: + return new QCocoaColorDialogHelper(); +#endif +#ifndef QT_NO_FONTDIALOG + case QPlatformTheme::FontDialog: + return new QCocoaFontDialogHelper(); +#endif + default: + return 0; } - return 0; } QT_END_NAMESPACE diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 4a91443d003..263d3a623c2 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -1440,7 +1440,7 @@ void QColorDialogPrivate::init(const QColor &initial) q->setSizeGripEnabled(false); q->setWindowTitle(QColorDialog::tr("Select Color")); - nativeDialogInUse = false; + nativeDialogInUse = (platformColorDialogHelper() != 0); nextCust = 0; QVBoxLayout *mainLay = new QVBoxLayout(q); @@ -1697,10 +1697,6 @@ void QColorDialog::setCurrentColor(const QColor &color) d->selectColor(color); d->setCurrentAlpha(color.alpha()); -#ifdef Q_WS_MAC - d->setCurrentQColor(color); - d->setCocoaPanelColor(color); -#endif // ### fixme: Call helper if (d->nativeDialogInUse) d->platformColorDialogHelper()->setCurrentColor_sys(color); From b904576b37854ede07c8c671a07c735364dd2736 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Mon, 13 Feb 2012 16:07:18 +1000 Subject: [PATCH 201/406] Use meaningful data row names in tst_QTextCodec::fromUnicode test. Use the codec name instead of just numbering the rows. This eliminates some duplicate row names. Two duplicate rows have also been removed -- for the WINSAMI2 row, the last value in the row is different, making one copy do a subset of the testing done by the other, so the row that did less testing was removed. Change-Id: I859f681a627e8d3839ca8a4ba09d541bec43d9fb Reviewed-by: Rohan McGovern --- .../codecs/qtextcodec/tst_qtextcodec.cpp | 119 +++++++++--------- 1 file changed, 58 insertions(+), 61 deletions(-) diff --git a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp index 7daed397d52..69e38d167ea 100644 --- a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp +++ b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp @@ -172,75 +172,72 @@ void tst_QTextCodec::fromUnicode_data() QTest::addColumn("codecName"); QTest::addColumn("eightBit"); - QTest::newRow("data1") << "ISO-8859-1" << true; - QTest::newRow("data2") << "ISO-8859-2" << true; - QTest::newRow("data3") << "ISO-8859-3" << true; - QTest::newRow("data4") << "ISO-8859-4" << true; - QTest::newRow("data5") << "ISO-8859-5" << true; - QTest::newRow("data6") << "ISO-8859-6" << true; - QTest::newRow("data7") << "ISO-8859-7" << true; - QTest::newRow("data8") << "ISO-8859-8" << true; - QTest::newRow("data9") << "ISO-8859-9" << true; - QTest::newRow("data10") << "ISO-8859-10" << true; - QTest::newRow("data13") << "ISO-8859-13" << true; - QTest::newRow("data14") << "ISO-8859-14" << true; - QTest::newRow("data15") << "ISO-8859-15" << true; - QTest::newRow("data16") << "ISO-8859-16" << true; + QTest::newRow("ISO-8859-1") << "ISO-8859-1" << true; + QTest::newRow("ISO-8859-2") << "ISO-8859-2" << true; + QTest::newRow("ISO-8859-3") << "ISO-8859-3" << true; + QTest::newRow("ISO-8859-4") << "ISO-8859-4" << true; + QTest::newRow("ISO-8859-5") << "ISO-8859-5" << true; + QTest::newRow("ISO-8859-6") << "ISO-8859-6" << true; + QTest::newRow("ISO-8859-7") << "ISO-8859-7" << true; + QTest::newRow("ISO-8859-8") << "ISO-8859-8" << true; + QTest::newRow("ISO-8859-9") << "ISO-8859-9" << true; + QTest::newRow("ISO-8859-10") << "ISO-8859-10" << true; + QTest::newRow("ISO-8859-13") << "ISO-8859-13" << true; + QTest::newRow("ISO-8859-14") << "ISO-8859-14" << true; + QTest::newRow("ISO-8859-15") << "ISO-8859-15" << true; + QTest::newRow("ISO-8859-16") << "ISO-8859-16" << true; - QTest::newRow("data18") << "IBM850" << true; - QTest::newRow("data19") << "IBM874" << true; - QTest::newRow("data20") << "IBM866" << true; + QTest::newRow("IBM850") << "IBM850" << true; + QTest::newRow("IBM874") << "IBM874" << true; + QTest::newRow("IBM866") << "IBM866" << true; - QTest::newRow("data21") << "windows-1250" << true; - QTest::newRow("data22") << "windows-1251" << true; - QTest::newRow("data23") << "windows-1252" << true; - QTest::newRow("data24") << "windows-1253" << true; - QTest::newRow("data25") << "windows-1254" << true; - QTest::newRow("data26") << "windows-1255" << true; - QTest::newRow("data27") << "windows-1256" << true; - QTest::newRow("data28") << "windows-1257" << true; - QTest::newRow("data28") << "windows-1258" << true; + QTest::newRow("windows-1250") << "windows-1250" << true; + QTest::newRow("windows-1251") << "windows-1251" << true; + QTest::newRow("windows-1252") << "windows-1252" << true; + QTest::newRow("windows-1253") << "windows-1253" << true; + QTest::newRow("windows-1254") << "windows-1254" << true; + QTest::newRow("windows-1255") << "windows-1255" << true; + QTest::newRow("windows-1256") << "windows-1256" << true; + QTest::newRow("windows-1257") << "windows-1257" << true; + QTest::newRow("windows-1258") << "windows-1258" << true; - QTest::newRow("data29") << "Apple Roman" << true; - QTest::newRow("data29") << "WINSAMI2" << true; - QTest::newRow("data30") << "TIS-620" << true; - QTest::newRow("data31") << "roman8" << true; - - QTest::newRow("data32") << "SJIS" << false; - QTest::newRow("data33") << "EUC-KR" << false; + QTest::newRow("Apple Roman") << "Apple Roman" << true; + QTest::newRow("WINSAMI2") << "WINSAMI2" << true; + QTest::newRow("TIS-620") << "TIS-620" << true; + QTest::newRow("roman8") << "roman8" << true; + QTest::newRow("SJIS") << "SJIS" << false; // all codecs from documentation - QTest::newRow("doc2") << "Big5" << false; - QTest::newRow("doc3") << "Big5-HKSCS" << false; - QTest::newRow("doc4") << "CP949" << false; - QTest::newRow("doc5") << "EUC-JP" << false; - QTest::newRow("doc6") << "EUC-KR" << false; - //QTest::newRow("doc7") << "GB18030-0" << false; // only GB18030 works - QTest::newRow("doc7-bis") << "GB18030" << false; - QTest::newRow("doc8") << "IBM 850" << false; - QTest::newRow("doc9") << "IBM 866" << false; - QTest::newRow("doc10") << "IBM 874" << false; - QTest::newRow("doc11") << "ISO 2022-JP" << false; + QTest::newRow("Big5") << "Big5" << false; + QTest::newRow("Big5-HKSCS") << "Big5-HKSCS" << false; + QTest::newRow("CP949") << "CP949" << false; + QTest::newRow("EUC-JP") << "EUC-JP" << false; + QTest::newRow("EUC-KR") << "EUC-KR" << false; + //QTest::newRow("GB18030-0") << "GB18030-0" << false; // only GB18030 works + QTest::newRow("GB18030") << "GB18030" << false; + QTest::newRow("IBM 850") << "IBM 850" << false; + QTest::newRow("IBM 866") << "IBM 866" << false; + QTest::newRow("IBM 874") << "IBM 874" << false; + QTest::newRow("ISO 2022-JP") << "ISO 2022-JP" << false; //ISO 8859-1 to 10 and ISO 8859-13 to 16 tested previously // Iscii-Bng, Dev, Gjr, Knd, Mlm, Ori, Pnj, Tlg, and Tml tested in Iscii test - //QTest::newRow("doc12") << "JIS X 0201" << false; //actually not there - //QTest::newRow("doc13") << "JIS X 0208" << false; // actually not there - QTest::newRow("doc14") << "KOI8-R" << false; - QTest::newRow("doc15") << "KOI8-U" << false; - //QTest::newRow("doc16") << "MuleLao-1" << false; //only on x11 - QTest::newRow("doc17") << "ROMAN8" << false; - QTest::newRow("doc18") << "Shift-JIS" << false; - QTest::newRow("doc19") << "TIS-620" << false; - QTest::newRow("doc20") << "TSCII" << false; - QTest::newRow("doc21") << "UTF-8" << false; - QTest::newRow("doc22") << "UTF-16" << false; - QTest::newRow("doc23") << "UTF-16BE" << false; - QTest::newRow("doc24") << "UTF-16LE" << false; - QTest::newRow("doc25") << "UTF-32" << false; - QTest::newRow("doc26") << "UTF-32BE" << false; - QTest::newRow("doc27") << "UTF-32LE" << false; + //QTest::newRow("JIS X 0201") << "JIS X 0201" << false; // actually not there + //QTest::newRow("JIS X 0208") << "JIS X 0208" << false; // actually not there + QTest::newRow("KOI8-R") << "KOI8-R" << false; + QTest::newRow("KOI8-U") << "KOI8-U" << false; + //QTest::newRow("MuleLao-1") << "MuleLao-1" << false; //only on x11 + QTest::newRow("ROMAN8") << "ROMAN8" << false; + QTest::newRow("Shift-JIS") << "Shift-JIS" << false; + QTest::newRow("TIS-620") << "TIS-620" << false; + QTest::newRow("TSCII") << "TSCII" << false; + QTest::newRow("UTF-8") << "UTF-8" << false; + QTest::newRow("UTF-16") << "UTF-16" << false; + QTest::newRow("UTF-16BE") << "UTF-16BE" << false; + QTest::newRow("UTF-16LE") << "UTF-16LE" << false; + QTest::newRow("UTF-32") << "UTF-32" << false; + QTest::newRow("UTF-32BE") << "UTF-32BE" << false; + QTest::newRow("UTF-32LE") << "UTF-32LE" << false; //Windows-1250 to 1258 tested previously - QTest::newRow("doc3") << "WINSAMI2" << false; } void tst_QTextCodec::fromUnicode() From db0eacaa740a4e6af00da9e2619b6fd46377c3e2 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Mon, 13 Feb 2012 16:17:17 +1000 Subject: [PATCH 202/406] Fix duplicate data row name in tst_QTextCodec::utf8Codec test. Rename rows using naming convention used elsewhere in this test. Change-Id: I8e669cedcc2058cf84cee976c8a0a478bc1cea0a Reviewed-by: Rohan McGovern --- tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp index 69e38d167ea..4144e82a29c 100644 --- a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp +++ b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp @@ -1219,7 +1219,7 @@ void tst_QTextCodec::utf8Codec_data() utf8.clear(); utf8 += char(0xff); str = fromInvalidUtf8Sequence(utf8); - QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.5.1") << utf8 << str << -1; + QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.5.2") << utf8 << str << -1; // 3.5.2 utf8.clear(); @@ -1227,7 +1227,7 @@ void tst_QTextCodec::utf8Codec_data() utf8 += char(0xfe); utf8 += char(0xff); str = fromInvalidUtf8Sequence(utf8); - QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.5.1") << utf8 << str << -1; + QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.5.2-1") << utf8 << str << -1; // 4.1.1 utf8.clear(); From 1cda7678a61cb5807d73a06e96fdc3068001d9fb Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Mon, 13 Feb 2012 16:27:10 +1000 Subject: [PATCH 203/406] Eliminate duplicate data row names in utf8 autotest. Change-Id: I30dfd4b93ab1e5430b5bc7fc25fe6aea0e0cc551 Reviewed-by: Rohan McGovern --- tests/auto/corelib/codecs/utf8/tst_utf8.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp index 69b91683d4a..e07b7cb2391 100644 --- a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp +++ b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp @@ -239,7 +239,7 @@ void tst_Utf8::invalidUtf8_data() QTest::newRow("non-unicode-3") << QByteArray("\xFC\x84\x80\x80\x80\x80"); // 0x7fffffff: 1 11 1111 11 1111 11 1111 11 1111 11 1111 // encoding: xxxx:xxz0 xz00:0100 xz00:0000 xz00:0000 xz00:0001 xz00:0001 - QTest::newRow("non-unicode-3") << QByteArray("\xFD\xBF\xBF\xBF\xBF\xBF"); + QTest::newRow("non-unicode-4") << QByteArray("\xFD\xBF\xBF\xBF\xBF\xBF"); // As seen above, 0xFE and 0xFF never appear: QTest::newRow("fe") << QByteArray("\xFE"); @@ -269,9 +269,9 @@ void tst_Utf8::invalidUtf8_data() // overlong 4: xxxx:z000 xz00:0000 xz00:0010 xz00:0000 QTest::newRow("overlong-2-4") << QByteArray("\xF0\x80\x82\x80"); // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz00:0010 xz00:0000 - QTest::newRow("overlong-2-4") << QByteArray("\xF8\x80\x80\x82\x80"); + QTest::newRow("overlong-2-5") << QByteArray("\xF8\x80\x80\x82\x80"); // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz00:0010 xz00:0000 - QTest::newRow("overlong-2-4") << QByteArray("\xFC\x80\x80\x80\x82\x80"); + QTest::newRow("overlong-2-6") << QByteArray("\xFC\x80\x80\x80\x82\x80"); // U+0800: 10 0000 00 0000 // proper encoding: xxxz:0000 xz10:0000 xz00:0000 From ab9be7cc23e52c2b5a43c66ec53bcb961188f924 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 14 Feb 2012 11:52:40 +1000 Subject: [PATCH 204/406] Eliminate duplicate data row names from corelib autotests. Change-Id: I57a37f19746b76c6c9c3534f5c66c5a5478dae24 Reviewed-by: Rohan McGovern --- .../corelib/global/qnumeric/tst_qnumeric.cpp | 2 +- .../io/qdatastream/tst_qdatastream.cpp | 4 +- .../qfilesystementry/tst_qfilesystementry.cpp | 18 +++--- .../io/qtextstream/tst_qtextstream.cpp | 2 +- tests/auto/corelib/io/qurl/tst_qurl.cpp | 4 +- .../tst_qabstractitemmodel.cpp | 58 +++++++++---------- .../itemmodels/qitemmodel/tst_qitemmodel.cpp | 42 +++++++------- .../thread/qthreadpool/tst_qthreadpool.cpp | 22 +++---- .../tools/qbytearray/tst_qbytearray.cpp | 36 ++++++------ .../tst_qcryptographichash.cpp | 4 +- tests/auto/corelib/tools/qdate/tst_qdate.cpp | 26 ++++----- .../corelib/tools/qdatetime/tst_qdatetime.cpp | 22 +++---- .../corelib/tools/qlocale/tst_qlocale.cpp | 4 +- .../corelib/tools/qstring/tst_qstring.cpp | 58 +++++++++---------- .../tools/qstringlist/tst_qstringlist.cpp | 16 ++--- .../qstringmatcher/tst_qstringmatcher.cpp | 18 +++--- .../tools/qstringref/tst_qstringref.cpp | 24 ++++---- .../tst_qtextboundaryfinder.cpp | 16 ++--- .../corelib/xml/qxmlstream/tst_qxmlstream.cpp | 2 +- 19 files changed, 189 insertions(+), 189 deletions(-) diff --git a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp index 064724e8887..899efc11d9f 100644 --- a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp +++ b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp @@ -72,7 +72,7 @@ void tst_QNumeric::fuzzyCompare_data() QTest::newRow("mis2") << 0.0 << 10000000.0 << false; QTest::newRow("mis3") << 0.0 << 0.000000001 << false; QTest::newRow("mis4") << 100000000.0 << 0.000000001 << false; - QTest::newRow("mis4") << 0.0000000001 << 0.000000001 << false; + QTest::newRow("mis5") << 0.0000000001 << 0.000000001 << false; } void tst_QNumeric::fuzzyCompare() diff --git a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp index eb227625a72..79c96fbdc9d 100644 --- a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp @@ -2680,8 +2680,8 @@ void tst_QDataStream::status_QBitArray_data() // past end QTest::newRow("empty") << QByteArray() << (int) QDataStream::ReadPastEnd << QBitArray(); QTest::newRow("badsize 0a") << QByteArray("\x00", 1) << (int) QDataStream::ReadPastEnd << QBitArray(); - QTest::newRow("badsize 0a") << QByteArray("\x00\x00", 2) << (int) QDataStream::ReadPastEnd << QBitArray(); - QTest::newRow("badsize 0a") << QByteArray("\x00\x00\x00", 3) << (int) QDataStream::ReadPastEnd << QBitArray(); + QTest::newRow("badsize 0b") << QByteArray("\x00\x00", 2) << (int) QDataStream::ReadPastEnd << QBitArray(); + QTest::newRow("badsize 0c") << QByteArray("\x00\x00\x00", 3) << (int) QDataStream::ReadPastEnd << QBitArray(); QTest::newRow("badsize 1") << QByteArray("\x00\x00\x00\x01", 4) << (int) QDataStream::ReadPastEnd << QBitArray(); QTest::newRow("badsize 2") << QByteArray("\x00\x00\x00\x02", 4) << (int) QDataStream::ReadPastEnd << QBitArray(); QTest::newRow("badsize 3") << QByteArray("\x00\x00\x00\x03", 4) << (int) QDataStream::ReadPastEnd << QBitArray(); diff --git a/tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp index fe2e30a95c1..b083d3b1c3e 100644 --- a/tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp +++ b/tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp @@ -241,15 +241,15 @@ void tst_QFileSystemEntry::suffix_data() QTest::newRow("data1") << "file.tar.gz" << "gz"; QTest::newRow("data2") << "/path/file/file.tar.gz" << "gz"; QTest::newRow("data3") << "/path/file.tar" << "tar"; - QTest::newRow("hidden1") << ".ext1" << "ext1"; - QTest::newRow("hidden1") << ".ext" << "ext"; - QTest::newRow("hidden1") << ".ex" << "ex"; - QTest::newRow("hidden1") << ".e" << "e"; - QTest::newRow("hidden2") << ".ext1.ext2" << "ext2"; - QTest::newRow("hidden2") << ".ext.ext2" << "ext2"; - QTest::newRow("hidden2") << ".ex.ext2" << "ext2"; - QTest::newRow("hidden2") << ".e.ext2" << "ext2"; - QTest::newRow("hidden2") << "..ext2" << "ext2"; + QTest::newRow("hidden1-1") << ".ext1" << "ext1"; + QTest::newRow("hidden1-2") << ".ext" << "ext"; + QTest::newRow("hidden1-3") << ".ex" << "ex"; + QTest::newRow("hidden1-4") << ".e" << "e"; + QTest::newRow("hidden2-1") << ".ext1.ext2" << "ext2"; + QTest::newRow("hidden2-2") << ".ext.ext2" << "ext2"; + QTest::newRow("hidden2-3") << ".ex.ext2" << "ext2"; + QTest::newRow("hidden2-4") << ".e.ext2" << "ext2"; + QTest::newRow("hidden2-5") << "..ext2" << "ext2"; QTest::newRow("dots") << "/path/file.with.dots/file..ext2" << "ext2"; QTest::newRow("dots2") << "/path/file.with.dots/.file..ext2" << "ext2"; } diff --git a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp index 01aecc2a216..37a1556cf9c 100644 --- a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp +++ b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp @@ -2755,7 +2755,7 @@ void tst_QTextStream::double_write_with_flags_data() QTest::newRow("inf uppercase") << qInf() << QString("INF") << (int)QTextStream::UppercaseDigits << 0; QTest::newRow("-inf uppercase") << -qInf() << QString("-INF") << (int)QTextStream::UppercaseDigits << 0; QTest::newRow("nan") << qQNaN() << QString("nan") << 0 << 0; - QTest::newRow("nan") << qQNaN() << QString("NAN") << (int)QTextStream::UppercaseDigits << 0; + QTest::newRow("NAN") << qQNaN() << QString("NAN") << (int)QTextStream::UppercaseDigits << 0; QTest::newRow("scientific") << 1.234567e+02 << QString("1.234567e+02") << 0 << (int)QTextStream::ScientificNotation; QTest::newRow("scientific2") << 1.234567e+02 << QString("1.234567e+02") << (int)QTextStream::UppercaseBase << (int)QTextStream::ScientificNotation; QTest::newRow("scientific uppercase") << 1.234567e+02 << QString("1.234567E+02") << (int)QTextStream::UppercaseDigits << (int)QTextStream::ScientificNotation; diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index e2831036df7..a74d817b8ae 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -3120,8 +3120,8 @@ void tst_QUrl::fromUserInput_data() QTest::newRow("port-0") << "example.org:80" << portUrl; QTest::newRow("port-1") << "http://example.org:80" << portUrl; portUrl.setPath("path"); - QTest::newRow("port-1") << "example.org:80/path" << portUrl; - QTest::newRow("port-1") << "http://example.org:80/path" << portUrl; + QTest::newRow("port-2") << "example.org:80/path" << portUrl; + QTest::newRow("port-3") << "http://example.org:80/path" << portUrl; // mailto doesn't have a ://, but is valid QUrl mailto("ben@example.net"); diff --git a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp index 2ca5df477bf..8d451dbff9a 100644 --- a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp +++ b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp @@ -1257,13 +1257,13 @@ void tst_QAbstractItemModel::testMoveToGrandParent_data() QTest::newRow("move09") << 8 << 8 << 8; // Moving to the row of my parent and its neighbours doesn't confuse things - QTest::newRow("move09") << 8 << 8 << 4; - QTest::newRow("move10") << 8 << 8 << 5; - QTest::newRow("move11") << 8 << 8 << 6; + QTest::newRow("move10") << 8 << 8 << 4; + QTest::newRow("move11") << 8 << 8 << 5; + QTest::newRow("move12") << 8 << 8 << 6; // Moving everything from one parent to another - QTest::newRow("move12") << 0 << 9 << 10; - QTest::newRow("move13") << 0 << 9 << 0; + QTest::newRow("move13") << 0 << 9 << 10; + QTest::newRow("move14") << 0 << 9 << 0; } void tst_QAbstractItemModel::testMoveToGrandParent() @@ -1397,14 +1397,14 @@ void tst_QAbstractItemModel::testMoveToSibling_data() QTest::newRow("move09") << 8 << 8 << 8; // Moving to the row of my target and its neighbours doesn't confuse things - QTest::newRow("move09") << 8 << 8 << 4; - QTest::newRow("move10") << 8 << 8 << 5; - QTest::newRow("move11") << 8 << 8 << 6; + QTest::newRow("move10") << 8 << 8 << 4; + QTest::newRow("move11") << 8 << 8 << 5; + QTest::newRow("move12") << 8 << 8 << 6; // Move such that the destination parent no longer valid after the move. // The destination parent is always QMI(5, 0), but after this move the // row count is 5, so (5, 0) (used internally in QAIM) no longer refers to a valid index. - QTest::newRow("move12") << 0 << 4 << 0; + QTest::newRow("move13") << 0 << 4 << 0; } void tst_QAbstractItemModel::testMoveToSibling() @@ -1541,12 +1541,12 @@ void tst_QAbstractItemModel::testMoveToUncle_data() QTest::newRow("move09") << 8 << 8 << 8; // Moving to the row of my parent and its neighbours doesn't confuse things - QTest::newRow("move09") << 8 << 8 << 4; - QTest::newRow("move10") << 8 << 8 << 5; - QTest::newRow("move11") << 8 << 8 << 6; + QTest::newRow("move10") << 8 << 8 << 4; + QTest::newRow("move11") << 8 << 8 << 5; + QTest::newRow("move12") << 8 << 8 << 6; // Moving everything from one parent to another - QTest::newRow("move12") << 0 << 9 << 10; + QTest::newRow("move13") << 0 << 9 << 10; } void tst_QAbstractItemModel::testMoveToUncle() @@ -1734,22 +1734,22 @@ void tst_QAbstractItemModel::testMoveWithinOwnRange_data() QTest::newRow("move07") << 0 << 5 << 4; QTest::newRow("move08") << 0 << 5 << 5; QTest::newRow("move09") << 0 << 5 << 6; - QTest::newRow("move08") << 3 << 5 << 5; - QTest::newRow("move08") << 3 << 5 << 6; - QTest::newRow("move09") << 4 << 5 << 5; - QTest::newRow("move10") << 4 << 5 << 6; - QTest::newRow("move11") << 5 << 5 << 5; - QTest::newRow("move12") << 5 << 5 << 6; - QTest::newRow("move13") << 5 << 9 << 9; - QTest::newRow("move14") << 5 << 9 << 10; - QTest::newRow("move15") << 6 << 9 << 9; - QTest::newRow("move16") << 6 << 9 << 10; - QTest::newRow("move17") << 7 << 9 << 9; - QTest::newRow("move18") << 7 << 9 << 10; - QTest::newRow("move19") << 8 << 9 << 9; - QTest::newRow("move20") << 8 << 9 << 10; - QTest::newRow("move21") << 9 << 9 << 9; - QTest::newRow("move22") << 0 << 9 << 10; + QTest::newRow("move10") << 3 << 5 << 5; + QTest::newRow("move11") << 3 << 5 << 6; + QTest::newRow("move12") << 4 << 5 << 5; + QTest::newRow("move13") << 4 << 5 << 6; + QTest::newRow("move14") << 5 << 5 << 5; + QTest::newRow("move15") << 5 << 5 << 6; + QTest::newRow("move16") << 5 << 9 << 9; + QTest::newRow("move17") << 5 << 9 << 10; + QTest::newRow("move18") << 6 << 9 << 9; + QTest::newRow("move19") << 6 << 9 << 10; + QTest::newRow("move20") << 7 << 9 << 9; + QTest::newRow("move21") << 7 << 9 << 10; + QTest::newRow("move22") << 8 << 9 << 9; + QTest::newRow("move23") << 8 << 9 << 10; + QTest::newRow("move24") << 9 << 9 << 9; + QTest::newRow("move25") << 0 << 9 << 10; } void tst_QAbstractItemModel::testMoveWithinOwnRange() diff --git a/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp b/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp index cbe7da11ad7..d27d685f37c 100644 --- a/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp +++ b/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp @@ -779,19 +779,19 @@ void tst_QItemModel::remove_data() makeTestRow(":none at the middle", MIDDLE, 0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); makeTestRow(":none at the end", END, 0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":invalid start, valid count", -99, 0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":invalid start, valid count", 9999, 0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":invalid start, valid count", -99, 1, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":invalid start, valid count", 9999, 1, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":invalid start, valid count", -99, MANY, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":invalid start, valid count", 9999, MANY, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":invalid start, valid count 1", -99, 0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":invalid start, valid count 2", 9999, 0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":invalid start, valid count 3", -99, 1, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":invalid start, valid count 4", 9999, 1, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":invalid start, valid count 5", -99, MANY, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":invalid start, valid count 6", 9999, MANY, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":valid start, invalid count", START, -2, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":valid start, invalid count", MIDDLE, -2, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":valid start, invalid count", END, -2, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":valid start, invalid count", START, 9999, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":valid start, invalid count", MIDDLE, 9999, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":valid start, invalid count", END, 9999, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":valid start, invalid count 1", START, -2, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":valid start, invalid count 2", MIDDLE, -2, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":valid start, invalid count 3", END, -2, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":valid start, invalid count 4", START, 9999, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":valid start, invalid count 5", MIDDLE, 9999, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":valid start, invalid count 6", END, 9999, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); // Recursive remove's might assert, haven't decided yet... //makeTestRow(":one at the start recursivly", START, DEFAULTCOUNT, 2, DNS, 2, DNS, RECURSIVE, START, DEFAULTCOUNT, FAIL); @@ -1126,16 +1126,16 @@ void tst_QItemModel::insert_data() makeTestRow(":none at the middle", MIDDLE, 0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); makeTestRow(":none at the end", END, 0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":invalid start, valid count", -99, 0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":invalid start, valid count", 9999, 0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":invalid start, valid count", -99, 1, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":invalid start, valid count", 9999, 1, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":invalid start, valid count", -99, MANY, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":invalid start, valid count", 9999, MANY, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":invalid start, valid count 1", -99, 0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":invalid start, valid count 2", 9999, 0, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":invalid start, valid count 3", -99, 1, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":invalid start, valid count 4", 9999, 1, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":invalid start, valid count 5", -99, MANY, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":invalid start, valid count 6", 9999, MANY, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":valid start, invalid count", START, -2, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":valid start, invalid count", MIDDLE, -2, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); - makeTestRow(":valid start, invalid count", END, -2, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":valid start, invalid count 1", START, -2, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":valid start, invalid count 2", MIDDLE, -2, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); + makeTestRow(":valid start, invalid count 3", END, -2, NOSIGNALS, NOSIGNALS, NOSIGNALS, NOSIGNALS, !RECURSIVE, 0, 0, FAIL); // Recursive insert's might assert, haven't decided yet... //makeTestRow(":one at the start recursivly", START, DEFAULTCOUNT, 2, DNS, 2, DNS, RECURSIVE, START, DEFAULTCOUNT, FAIL); diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index 1dd0410f411..aa4d163fc4a 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -367,17 +367,17 @@ void tst_QThreadPool::setMaxThreadCount_data() { QTest::addColumn("limit"); - QTest::newRow("") << 1; - QTest::newRow("") << -1; - QTest::newRow("") << 2; - QTest::newRow("") << -2; - QTest::newRow("") << 4; - QTest::newRow("") << -4; - QTest::newRow("") << 0; - QTest::newRow("") << 12345; - QTest::newRow("") << -6789; - QTest::newRow("") << 42; - QTest::newRow("") << -666; + QTest::newRow("1") << 1; + QTest::newRow("-1") << -1; + QTest::newRow("2") << 2; + QTest::newRow("-2") << -2; + QTest::newRow("4") << 4; + QTest::newRow("-4") << -4; + QTest::newRow("0") << 0; + QTest::newRow("12345") << 12345; + QTest::newRow("-6789") << -6789; + QTest::newRow("42") << 42; + QTest::newRow("-666") << -666; } void tst_QThreadPool::setMaxThreadCount() diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 40e4cc398fb..5e53683abd4 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -865,7 +865,7 @@ void tst_QByteArray::indexOf_data() QTest::newRow("BoyerMooreStressTest4") << QByteArray(veryBigHaystack) << QByteArray(veryBigHaystack + 'c') << 0 << -1; QTest::newRow("BoyerMooreStressTest5") << QByteArray(veryBigHaystack) << QByteArray('c' + veryBigHaystack) << 0 << -1; QTest::newRow("BoyerMooreStressTest6") << QByteArray('d' + veryBigHaystack) << QByteArray('c' + veryBigHaystack) << 0 << -1; - QTest::newRow("BoyerMooreStressTest6") << QByteArray(veryBigHaystack + 'c') << QByteArray('c' + veryBigHaystack) << 0 << -1; + QTest::newRow("BoyerMooreStressTest7") << QByteArray(veryBigHaystack + 'c') << QByteArray('c' + veryBigHaystack) << 0 << -1; } void tst_QByteArray::indexOf() @@ -988,13 +988,13 @@ void tst_QByteArray::toInt_data() QTest::addColumn("expectedok"); QTest::newRow("base 10") << QByteArray("100") << 10 << int(100) << true; - QTest::newRow("base 16") << QByteArray("100") << 16 << int(256) << true; - QTest::newRow("base 16") << QByteArray("0400") << 16 << int(1024) << true; + QTest::newRow("base 16-1") << QByteArray("100") << 16 << int(256) << true; + QTest::newRow("base 16-2") << QByteArray("0400") << 16 << int(1024) << true; QTest::newRow("base 2") << QByteArray("1111") << 2 << int(15) << true; QTest::newRow("base 8") << QByteArray("100") << 8 << int(64) << true; - QTest::newRow("base 0") << QByteArray("0x10") << 0 << int(16) << true; - QTest::newRow("base 0") << QByteArray("10") << 0 << int(10) << true; - QTest::newRow("base 0") << QByteArray("010") << 0 << int(8) << true; + QTest::newRow("base 0-1") << QByteArray("0x10") << 0 << int(16) << true; + QTest::newRow("base 0-2") << QByteArray("10") << 0 << int(10) << true; + QTest::newRow("base 0-3") << QByteArray("010") << 0 << int(8) << true; QTest::newRow("empty") << QByteArray() << 0 << int(0) << false; // using fromRawData @@ -1002,7 +1002,7 @@ void tst_QByteArray::toInt_data() QTest::newRow("raw2") << QByteArray::fromRawData("1foo", 1) << 10 << 1 << true; QTest::newRow("raw3") << QByteArray::fromRawData("12", 1) << 10 << 1 << true; QTest::newRow("raw4") << QByteArray::fromRawData("123456789", 1) << 10 << 1 << true; - QTest::newRow("raw4") << QByteArray::fromRawData("123456789", 2) << 10 << 12 << true; + QTest::newRow("raw5") << QByteArray::fromRawData("123456789", 2) << 10 << 12 << true; QTest::newRow("raw-static") << QByteArray::fromRawData(&globalChar, 1) << 10 << 1 << true; } @@ -1394,58 +1394,58 @@ void tst_QByteArray::repeated_data() const QTest::addColumn("count" ); /* Empty strings. */ - QTest::newRow("") + QTest::newRow("data1") << QByteArray() << QByteArray() << 0; - QTest::newRow("") + QTest::newRow("data2") << QByteArray() << QByteArray() << -1004; - QTest::newRow("") + QTest::newRow("data3") << QByteArray() << QByteArray() << 1; - QTest::newRow("") + QTest::newRow("data4") << QByteArray() << QByteArray() << 5; /* On simple string. */ - QTest::newRow("") + QTest::newRow("data5") << QByteArray("abc") << QByteArray() << -1004; - QTest::newRow("") + QTest::newRow("data6") << QByteArray("abc") << QByteArray() << -1; - QTest::newRow("") + QTest::newRow("data7") << QByteArray("abc") << QByteArray() << 0; - QTest::newRow("") + QTest::newRow("data8") << QByteArray("abc") << QByteArray("abc") << 1; - QTest::newRow("") + QTest::newRow("data9") << QByteArray(("abc")) << QByteArray(("abcabc")) << 2; - QTest::newRow("") + QTest::newRow("data10") << QByteArray(("abc")) << QByteArray(("abcabcabc")) << 3; - QTest::newRow("") + QTest::newRow("data11") << QByteArray(("abc")) << QByteArray(("abcabcabcabc")) << 4; diff --git a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp index 3a257c2f117..0f35089ff76 100644 --- a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp +++ b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp @@ -158,8 +158,8 @@ void tst_QCryptographicHash::files_data() { QTest::addColumn("filename"); QTest::addColumn("algorithm"); QTest::addColumn("md5sum"); - QTest::newRow("Line") << QString::fromAscii("data/2c1517dad3678f03917f15849b052fd5.md5") << QCryptographicHash::Md5 << QByteArray("2c1517dad3678f03917f15849b052fd5"); - QTest::newRow("Line") << QString::fromAscii("data/d41d8cd98f00b204e9800998ecf8427e.md5") << QCryptographicHash::Md5 << QByteArray("d41d8cd98f00b204e9800998ecf8427e"); + QTest::newRow("data1") << QString::fromAscii("data/2c1517dad3678f03917f15849b052fd5.md5") << QCryptographicHash::Md5 << QByteArray("2c1517dad3678f03917f15849b052fd5"); + QTest::newRow("data2") << QString::fromAscii("data/d41d8cd98f00b204e9800998ecf8427e.md5") << QCryptographicHash::Md5 << QByteArray("d41d8cd98f00b204e9800998ecf8427e"); } diff --git a/tests/auto/corelib/tools/qdate/tst_qdate.cpp b/tests/auto/corelib/tools/qdate/tst_qdate.cpp index 4921a7e7343..258dbf8625e 100644 --- a/tests/auto/corelib/tools/qdate/tst_qdate.cpp +++ b/tests/auto/corelib/tools/qdate/tst_qdate.cpp @@ -147,14 +147,14 @@ void tst_QDate::isValid_data() QTest::newRow("month 13") << 2000 << 13 << 1 << nullJd << false; // test leap years - QTest::newRow("non-leap") << 2006 << 2 << 29 << nullJd << false; - QTest::newRow("normal leap") << 2004 << 2 << 29 << qint64(2453065) << true; - QTest::newRow("century leap") << 1900 << 2 << 29 << nullJd << false; - QTest::newRow("century leap") << 2100 << 2 << 29 << nullJd << false; - QTest::newRow("400-years leap") << 2000 << 2 << 29 << qint64(2451604) << true; - QTest::newRow("400-years leap 2") << 2400 << 2 << 29 << qint64(2597701) << true; - QTest::newRow("400-years leap 3") << 1600 << 2 << 29 << qint64(2305507) << true; - QTest::newRow("year 0") << 0 << 2 << 27 << nullJd << false; + QTest::newRow("non-leap") << 2006 << 2 << 29 << nullJd << false; + QTest::newRow("normal leap") << 2004 << 2 << 29 << qint64(2453065) << true; + QTest::newRow("century leap 1900") << 1900 << 2 << 29 << nullJd << false; + QTest::newRow("century leap 2100") << 2100 << 2 << 29 << nullJd << false; + QTest::newRow("400-years leap 2000") << 2000 << 2 << 29 << qint64(2451604) << true; + QTest::newRow("400-years leap 2400") << 2400 << 2 << 29 << qint64(2597701) << true; + QTest::newRow("400-years leap 1600") << 1600 << 2 << 29 << qint64(2305507) << true; + QTest::newRow("year 0") << 0 << 2 << 27 << nullJd << false; // test the number of days in months: QTest::newRow("jan") << 2000 << 1 << 31 << qint64(2451575) << true; @@ -262,7 +262,7 @@ void tst_QDate::dayOfWeek_data() QTest::newRow("data8") << -4800 << 1 << 1 << 1; QTest::newRow("data9") << -4800 << 1 << 2 << 2; QTest::newRow("data10") << -4800 << 1 << 3 << 3; - QTest::newRow("data12") << -4800 << 1 << 4 << 4; + QTest::newRow("data11") << -4800 << 1 << 4 << 4; QTest::newRow("data12") << -4800 << 1 << 5 << 5; QTest::newRow("data13") << -4800 << 1 << 6 << 6; QTest::newRow("data14") << -4800 << 1 << 7 << 7; @@ -580,10 +580,10 @@ void tst_QDate::addMonths_data() QTest::newRow( "data14" ) << 2000 << 2 << 29 << -12 << 1999 << 2 << 28; // year sign change: - QTest::newRow( "data14" ) << 1 << 1 << 1 << -1 << -1 << 12 << 1; - QTest::newRow( "data15" ) << 1 << 1 << 1 << -12 << -1 << 1 << 1; - QTest::newRow( "data16" ) << -1 << 12 << 1 << 1 << 1 << 1 << 1; - QTest::newRow( "data17" ) << -1 << 1 << 1 << 12 << 1 << 1 << 1; + QTest::newRow( "data15" ) << 1 << 1 << 1 << -1 << -1 << 12 << 1; + QTest::newRow( "data16" ) << 1 << 1 << 1 << -12 << -1 << 1 << 1; + QTest::newRow( "data17" ) << -1 << 12 << 1 << 1 << 1 << 1 << 1; + QTest::newRow( "data18" ) << -1 << 1 << 1 << 12 << 1 << 1 << 1; } void tst_QDate::addYears() diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index af8deefa4cf..eb6af23ba50 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -1363,19 +1363,19 @@ void tst_QDateTime::dateFromStringFormat_data() QTest::newRow("data24") << tuesday << QString("dddd") << QDate(1900, 1, 2); QTest::newRow("data25") << wednesday << QString("dddd") << QDate(1900, 1, 3); QTest::newRow("data26") << thursday << QString("dddd") << QDate(1900, 1, 4); - QTest::newRow("data26") << friday << QString("dddd") << QDate(1900, 1, 5); - QTest::newRow("data27") << saturday << QString("dddd") << QDate(1900, 1, 6); - QTest::newRow("data28") << sunday << QString("dddd") << QDate(1900, 1, 7); + QTest::newRow("data27") << friday << QString("dddd") << QDate(1900, 1, 5); + QTest::newRow("data28") << saturday << QString("dddd") << QDate(1900, 1, 6); + QTest::newRow("data29") << sunday << QString("dddd") << QDate(1900, 1, 7); - QTest::newRow("data29") << monday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 2); - QTest::newRow("data30") << tuesday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 3); - QTest::newRow("data31") << wednesday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 4); - QTest::newRow("data32") << thursday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 5); - QTest::newRow("data33") << friday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 6); - QTest::newRow("data34") << saturday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 7); - QTest::newRow("data35") << sunday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 1); + QTest::newRow("data30") << monday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 2); + QTest::newRow("data31") << tuesday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 3); + QTest::newRow("data32") << wednesday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 4); + QTest::newRow("data33") << thursday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 5); + QTest::newRow("data34") << friday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 6); + QTest::newRow("data35") << saturday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 7); + QTest::newRow("data36") << sunday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 1); - QTest::newRow("data36 ") << tuesday + " 2007 " + march << QString("dddd yyyy MMMM") << QDate(2007, 3, 6); + QTest::newRow("data37") << tuesday + " 2007 " + march << QString("dddd yyyy MMMM") << QDate(2007, 3, 6); } diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index 5544c0fd718..e23448c056a 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -934,7 +934,7 @@ void tst_QLocale::formatDateTime_data() << "\"yymm\"" << "\"7414\""; QTest::newRow("27C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) << "'\"yymm\"'" << "\"yymm\""; - QTest::newRow("27C") << "C" << QDateTime() + QTest::newRow("28C") << "C" << QDateTime() << "'\"yymm\"'" << ""; QTest::newRow("1no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(5, 14, 13)) @@ -976,7 +976,7 @@ void tst_QLocale::formatDateTime_data() << "\"yymm\"" << "\"7414\""; QTest::newRow("27no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) << "'\"yymm\"'" << "\"yymm\""; - QTest::newRow("27no_NO") << "no_NO" << QDateTime() + QTest::newRow("28no_NO") << "no_NO" << QDateTime() << "'\"yymm\"'" << ""; } diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 3be73022239..3fb253c6461 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -447,7 +447,7 @@ void tst_QString::replace_uint_uint_data() QTest::newRow( "rep08" ) << QString("ACABCAB") << 3 << 2 << QString("XX") << QString("ACAXXAB"); QTest::newRow( "rep09" ) << QString("ACABCAB") << 4 << 2 << QString("XX") << QString("ACABXXB"); QTest::newRow( "rep10" ) << QString("ACABCAB") << 5 << 2 << QString("XX") << QString("ACABCXX"); - QTest::newRow( "rep10" ) << QString("ACABCAB") << 6 << 2 << QString("XX") << QString("ACABCAXX"); + QTest::newRow( "rep11" ) << QString("ACABCAB") << 6 << 2 << QString("XX") << QString("ACABCAXX"); QTest::newRow( "rep12" ) << QString() << 0 << 10 << QString("X") << QString("X"); QTest::newRow( "rep13" ) << QString("short") << 0 << 10 << QString("X") << QString("X"); QTest::newRow( "rep14" ) << QString() << 0 << 10 << QString("XX") << QString("XX"); @@ -1042,7 +1042,7 @@ void tst_QString::indexOf_data() QTest::newRow("BoyerMooreStressTest4") << veryBigHaystack << QString(veryBigHaystack + 'c') << 0 << true << -1; QTest::newRow("BoyerMooreStressTest5") << veryBigHaystack << QString('c' + veryBigHaystack) << 0 << true << -1; QTest::newRow("BoyerMooreStressTest6") << QString('d' + veryBigHaystack) << QString('c' + veryBigHaystack) << 0 << true << -1; - QTest::newRow("BoyerMooreStressTest6") << QString(veryBigHaystack + 'c') << QString('c' + veryBigHaystack) << 0 << true << -1; + QTest::newRow("BoyerMooreStressTest7") << QString(veryBigHaystack + 'c') << QString('c' + veryBigHaystack) << 0 << true << -1; QTest::newRow("BoyerMooreInsensitiveStressTest") << veryBigHaystack << veryBigHaystack << 0 << false << 0; @@ -1211,15 +1211,15 @@ void tst_QString::lastIndexOf_data() QTest::newRow("4") << a << "G" << 14 << 14 << true; QTest::newRow("5") << a << "G" << 13 << 11 << true; QTest::newRow("6") << a << "B" << a.size() - 1 << 1 << true; - QTest::newRow("6") << a << "B" << - 1 << 1 << true; - QTest::newRow("7") << a << "B" << 1 << 1 << true; - QTest::newRow("8") << a << "B" << 0 << -1 << true; + QTest::newRow("7") << a << "B" << - 1 << 1 << true; + QTest::newRow("8") << a << "B" << 1 << 1 << true; + QTest::newRow("9") << a << "B" << 0 << -1 << true; - QTest::newRow("9") << a << "G" << -1 << a.size()-1 << true; - QTest::newRow("10") << a << "G" << a.size()-1 << a.size()-1 << true; - QTest::newRow("11") << a << "G" << a.size() << -1 << true; - QTest::newRow("12") << a << "A" << 0 << 0 << true; - QTest::newRow("13") << a << "A" << -1*a.size() << 0 << true; + QTest::newRow("10") << a << "G" << -1 << a.size()-1 << true; + QTest::newRow("11") << a << "G" << a.size()-1 << a.size()-1 << true; + QTest::newRow("12") << a << "G" << a.size() << -1 << true; + QTest::newRow("13") << a << "A" << 0 << 0 << true; + QTest::newRow("14") << a << "A" << -1*a.size() << 0 << true; QTest::newRow("15") << a << "efg" << 0 << -1 << false; QTest::newRow("16") << a << "efg" << a.size() << -1 << false; @@ -4672,8 +4672,8 @@ void tst_QString::compare_data() // different length QTest::newRow("data6") << QString("abcdef") << QString("abc") << 1 << 1; - QTest::newRow("data6") << QString("abCdef") << QString("abc") << -1 << 1; - QTest::newRow("data7") << QString("abc") << QString("abcdef") << -1 << -1; + QTest::newRow("data7") << QString("abCdef") << QString("abc") << -1 << 1; + QTest::newRow("data8") << QString("abc") << QString("abcdef") << -1 << -1; QString upper; upper += QChar(QChar::highSurrogate(0x10400)); @@ -4685,12 +4685,12 @@ void tst_QString::compare_data() // embedded nulls // These don't work as of now. It's OK that these don't work since \0 is not a valid unicode - /*QTest::newRow("data9") << QString(QByteArray("\0", 1)) << QString(QByteArray("\0", 1)) << 0 << 0; - QTest::newRow("data10") << QString(QByteArray("\0", 1)) << QString("") << 1 << 1; - QTest::newRow("data11") << QString("") << QString(QByteArray("\0", 1)) << -1 << -1; - QTest::newRow("data12") << QString("ab\0c") << QString(QByteArray("ab\0c", 4)) << 0 << 0; - QTest::newRow("data13") << QString(QByteArray("ab\0c", 4)) << QString("abc") << -1 << -1; - QTest::newRow("data14") << QString("abc") << QString(QByteArray("ab\0c", 4)) << 1 << 1;*/ + /*QTest::newRow("data10") << QString(QByteArray("\0", 1)) << QString(QByteArray("\0", 1)) << 0 << 0; + QTest::newRow("data11") << QString(QByteArray("\0", 1)) << QString("") << 1 << 1; + QTest::newRow("data12") << QString("") << QString(QByteArray("\0", 1)) << -1 << -1; + QTest::newRow("data13") << QString("ab\0c") << QString(QByteArray("ab\0c", 4)) << 0 << 0; + QTest::newRow("data14") << QString(QByteArray("ab\0c", 4)) << QString("abc") << -1 << -1; + QTest::newRow("data15") << QString("abc") << QString(QByteArray("ab\0c", 4)) << 1 << 1;*/ } static bool isLatin(const QString &s) @@ -4934,58 +4934,58 @@ void tst_QString::repeated_data() const QTest::addColumn("count" ); /* Empty strings. */ - QTest::newRow("") + QTest::newRow("data1") << QString() << QString() << 0; - QTest::newRow("") + QTest::newRow("data2") << QString() << QString() << -1004; - QTest::newRow("") + QTest::newRow("data3") << QString() << QString() << 1; - QTest::newRow("") + QTest::newRow("data4") << QString() << QString() << 5; /* On simple string. */ - QTest::newRow("") + QTest::newRow("data5") << QString(QLatin1String("abc")) << QString() << -1004; - QTest::newRow("") + QTest::newRow("data6") << QString(QLatin1String("abc")) << QString() << -1; - QTest::newRow("") + QTest::newRow("data7") << QString(QLatin1String("abc")) << QString() << 0; - QTest::newRow("") + QTest::newRow("data8") << QString(QLatin1String("abc")) << QString(QLatin1String("abc")) << 1; - QTest::newRow("") + QTest::newRow("data9") << QString(QLatin1String("abc")) << QString(QLatin1String("abcabc")) << 2; - QTest::newRow("") + QTest::newRow("data10") << QString(QLatin1String("abc")) << QString(QLatin1String("abcabcabc")) << 3; - QTest::newRow("") + QTest::newRow("data11") << QString(QLatin1String("abc")) << QString(QLatin1String("abcabcabcabc")) << 4; diff --git a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp index e3eb1a21ac5..6066f7c8e07 100644 --- a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp +++ b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp @@ -193,8 +193,8 @@ void tst_QStringList::removeDuplicates_data() QTest::addColumn("after"); QTest::addColumn("count"); - QTest::newRow("empty") << "Hello,Hello" << "Hello" << 1; - QTest::newRow("empty") << "Hello,World" << "Hello,World" << 0; + QTest::newRow("empty-1") << "Hello,Hello" << "Hello" << 1; + QTest::newRow("empty-2") << "Hello,World" << "Hello,World" << 0; } void tst_QStringList::removeDuplicates() @@ -245,35 +245,35 @@ void tst_QStringList::join_data() const QTest::addColumn("separator"); QTest::addColumn("expectedResult"); - QTest::newRow("") + QTest::newRow("data1") << QStringList() << QString() << QString(); - QTest::newRow("") + QTest::newRow("data2") << QStringList() << QString(QLatin1String("separator")) << QString(); - QTest::newRow("") + QTest::newRow("data3") << QStringList("one") << QString(QLatin1String("separator")) << QString("one"); - QTest::newRow("") + QTest::newRow("data4") << QStringList("one") << QString(QLatin1String("separator")) << QString("one"); - QTest::newRow("") + QTest::newRow("data5") << (QStringList() << QLatin1String("a") << QLatin1String("b")) << QString(QLatin1String(" ")) << QString("a b"); - QTest::newRow("") + QTest::newRow("data6") << (QStringList() << QLatin1String("a") << QLatin1String("b") diff --git a/tests/auto/corelib/tools/qstringmatcher/tst_qstringmatcher.cpp b/tests/auto/corelib/tools/qstringmatcher/tst_qstringmatcher.cpp index ebbad86c81e..5829c0e9176 100644 --- a/tests/auto/corelib/tools/qstringmatcher/tst_qstringmatcher.cpp +++ b/tests/auto/corelib/tools/qstringmatcher/tst_qstringmatcher.cpp @@ -81,16 +81,16 @@ void tst_QStringMatcher::indexIn_data() QTest::addColumn("haystack"); QTest::addColumn("from"); QTest::addColumn("indexIn"); - QTest::newRow("empty") << QString() << QString("foo") << 0 << 0; - QTest::newRow("empty") << QString() << QString("foo") << 10 << -1; - QTest::newRow("empty") << QString() << QString("foo") << -10 << 0; + QTest::newRow("empty-1") << QString() << QString("foo") << 0 << 0; + QTest::newRow("empty-2") << QString() << QString("foo") << 10 << -1; + QTest::newRow("empty-3") << QString() << QString("foo") << -10 << 0; - QTest::newRow("simple") << QString("a") << QString("foo") << 0 << -1; - QTest::newRow("simple") << QString("a") << QString("bar") << 0 << 1; - QTest::newRow("harder") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 0 << 26; - QTest::newRow("harder") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 20 << 26; - QTest::newRow("harder") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 26 << 26; - QTest::newRow("harder") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 27 << -1; + QTest::newRow("simple-1") << QString("a") << QString("foo") << 0 << -1; + QTest::newRow("simple-2") << QString("a") << QString("bar") << 0 << 1; + QTest::newRow("harder-1") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 0 << 26; + QTest::newRow("harder-2") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 20 << 26; + QTest::newRow("harder-3") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 26 << 26; + QTest::newRow("harder-4") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 27 << -1; } void tst_QStringMatcher::indexIn() diff --git a/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp b/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp index 77d21013204..de01df2001a 100644 --- a/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp +++ b/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp @@ -288,7 +288,7 @@ void tst_QStringRef::indexOf_data() QTest::newRow("BoyerMooreStressTest4") << veryBigHaystack << veryBigHaystack + 'c' << 0 << true << -1; QTest::newRow("BoyerMooreStressTest5") << veryBigHaystack << 'c' + veryBigHaystack << 0 << true << -1; QTest::newRow("BoyerMooreStressTest6") << 'd' + veryBigHaystack << 'c' + veryBigHaystack << 0 << true << -1; - QTest::newRow("BoyerMooreStressTest6") << veryBigHaystack + 'c' << 'c' + veryBigHaystack << 0 << true << -1; + QTest::newRow("BoyerMooreStressTest7") << veryBigHaystack + 'c' << 'c' + veryBigHaystack << 0 << true << -1; QTest::newRow("BoyerMooreInsensitiveStressTest") << veryBigHaystack << veryBigHaystack << 0 << false << 0; @@ -441,15 +441,15 @@ void tst_QStringRef::lastIndexOf_data() QTest::newRow("4") << a << "G" << 14 << 14 << true; QTest::newRow("5") << a << "G" << 13 << 11 << true; QTest::newRow("6") << a << "B" << a.size() - 1 << 1 << true; - QTest::newRow("6") << a << "B" << - 1 << 1 << true; - QTest::newRow("7") << a << "B" << 1 << 1 << true; - QTest::newRow("8") << a << "B" << 0 << -1 << true; + QTest::newRow("7") << a << "B" << - 1 << 1 << true; + QTest::newRow("8") << a << "B" << 1 << 1 << true; + QTest::newRow("9") << a << "B" << 0 << -1 << true; - QTest::newRow("9") << a << "G" << -1 << a.size()-1 << true; - QTest::newRow("10") << a << "G" << a.size()-1 << a.size()-1 << true; - QTest::newRow("11") << a << "G" << a.size() << -1 << true; - QTest::newRow("12") << a << "A" << 0 << 0 << true; - QTest::newRow("13") << a << "A" << -1*a.size() << 0 << true; + QTest::newRow("10") << a << "G" << -1 << a.size()-1 << true; + QTest::newRow("11") << a << "G" << a.size()-1 << a.size()-1 << true; + QTest::newRow("12") << a << "G" << a.size() << -1 << true; + QTest::newRow("13") << a << "A" << 0 << 0 << true; + QTest::newRow("14") << a << "A" << -1*a.size() << 0 << true; QTest::newRow("15") << a << "efg" << 0 << -1 << false; QTest::newRow("16") << a << "efg" << a.size() << -1 << false; @@ -777,8 +777,8 @@ void tst_QStringRef::compare_data() // different length QTest::newRow("data6") << QString("abcdef") << QString("abc") << 1 << 1; - QTest::newRow("data6") << QString("abCdef") << QString("abc") << -1 << 1; - QTest::newRow("data7") << QString("abc") << QString("abcdef") << -1 << -1; + QTest::newRow("data7") << QString("abCdef") << QString("abc") << -1 << 1; + QTest::newRow("data8") << QString("abc") << QString("abcdef") << -1 << -1; QString upper; upper += QChar(QChar::highSurrogate(0x10400)); @@ -786,7 +786,7 @@ void tst_QStringRef::compare_data() QString lower; lower += QChar(QChar::highSurrogate(0x10428)); lower += QChar(QChar::lowSurrogate(0x10428)); - QTest::newRow("data8") << upper << lower << -1 << 0; + QTest::newRow("data9") << upper << lower << -1 << 0; } static bool isLatin(const QString &s) diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/tst_qtextboundaryfinder.cpp b/tests/auto/corelib/tools/qtextboundaryfinder/tst_qtextboundaryfinder.cpp index 89dd01ac3a9..b8ae709fd0f 100644 --- a/tests/auto/corelib/tools/qtextboundaryfinder/tst_qtextboundaryfinder.cpp +++ b/tests/auto/corelib/tools/qtextboundaryfinder/tst_qtextboundaryfinder.cpp @@ -302,22 +302,22 @@ void tst_QTextBoundaryFinder::toNextBoundary_data() QList boundaries; boundaries << 0 << 3 << 4 << 7 << 8 << 11 << 12 << 13 << 16 << 17 << 20 << 21 << 24 << 25; - QTest::newRow("Line") << QString("Aaa bbb ccc. Ddd eee fff.") << int(QTextBoundaryFinder::Word) \ + QTest::newRow("data1") << QString("Aaa bbb ccc. Ddd eee fff.") << int(QTextBoundaryFinder::Word) \ << boundaries; boundaries.clear(); boundaries << 0 << 13 << 25; - QTest::newRow("Line") << QString("Aaa bbb ccc. Ddd eee fff.") << int(QTextBoundaryFinder::Sentence) \ + QTest::newRow("data2") << QString("Aaa bbb ccc. Ddd eee fff.") << int(QTextBoundaryFinder::Sentence) \ << boundaries; boundaries.clear(); boundaries << 0 << 4 << 8 << 13 << 17 << 21 << 25; - QTest::newRow("Line") << QString("Aaa bbb ccc. Ddd eee fff.") << int(QTextBoundaryFinder::Line) \ + QTest::newRow("data3") << QString("Aaa bbb ccc. Ddd eee fff.") << int(QTextBoundaryFinder::Line) \ << boundaries; boundaries.clear(); boundaries << 0 << 5 << 9 << 15 << 17 << 21 << 28; - QTest::newRow("Line") << QString::fromUtf8("Diga-nos qualé a sua opinião") << int(QTextBoundaryFinder::Line) + QTest::newRow("data4") << QString::fromUtf8("Diga-nos qualé a sua opinião") << int(QTextBoundaryFinder::Line) << boundaries; } @@ -344,22 +344,22 @@ void tst_QTextBoundaryFinder::toPreviousBoundary_data() QList boundaries; boundaries << 25 << 24 << 21 << 20 << 17 << 16 << 13 << 12 << 11 << 8 << 7 << 4 << 3 << 0; - QTest::newRow("Line") << QString("Aaa bbb ccc. Ddd eee fff.") << int(QTextBoundaryFinder::Word) + QTest::newRow("data1") << QString("Aaa bbb ccc. Ddd eee fff.") << int(QTextBoundaryFinder::Word) << boundaries; boundaries.clear(); boundaries << 25 << 13 << 0; - QTest::newRow("Line") << QString("Aaa bbb ccc. Ddd eee fff.") << int(QTextBoundaryFinder::Sentence) + QTest::newRow("data2") << QString("Aaa bbb ccc. Ddd eee fff.") << int(QTextBoundaryFinder::Sentence) << boundaries; boundaries.clear(); boundaries << 25 << 21 << 17 << 13 << 8 << 4 << 0; - QTest::newRow("Line") << QString("Aaa bbb ccc. Ddd eee fff.") << int(QTextBoundaryFinder::Line) + QTest::newRow("data3") << QString("Aaa bbb ccc. Ddd eee fff.") << int(QTextBoundaryFinder::Line) << boundaries; boundaries.clear(); boundaries << 28 << 21 << 17 << 15 << 9 << 5 << 0; - QTest::newRow("Line") << QString::fromUtf8("Diga-nos qualé a sua opinião") << int(QTextBoundaryFinder::Line) + QTest::newRow("data4") << QString::fromUtf8("Diga-nos qualé a sua opinião") << int(QTextBoundaryFinder::Line) << boundaries; } diff --git a/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp index 0ce0da06aa9..bd9fa2a8db5 100644 --- a/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp @@ -674,7 +674,7 @@ void tst_QXmlStream::reportSuccess_data() const const int len = m_handler.successes.count(); for(int i = 0; i < len; ++i) - QTest::newRow(m_handler.successes.at(i).toLatin1().constData()) << false; + QTest::newRow(qPrintable(QString("%1. %2").arg(i).arg(m_handler.successes.at(i)))) << false; if(len == 0) QTest::newRow("No test cases succeeded.") << true; From 2cb41b3da66167d612d72744205d0aeb696cf241 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 14 Feb 2012 12:20:56 +1000 Subject: [PATCH 205/406] Eliminate duplicate data row names in gui autotests. Change-Id: I1b39a7d13399ea8d47369203e9617810a34c0097 Reviewed-by: Rohan McGovern --- .../qicoimageformat/tst_qicoimageformat.cpp | 16 ++++++++-------- .../gui/image/qimagereader/tst_qimagereader.cpp | 1 - tests/auto/gui/image/qpixmap/tst_qpixmap.cpp | 2 +- .../painting/qpainterpath/tst_qpainterpath.cpp | 10 +++++----- .../gui/text/qtextdocument/tst_qtextdocument.cpp | 4 ++-- .../tst_qtextdocumentfragment.cpp | 2 +- 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp b/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp index 25c6c81b2ab..74eec26c52e 100644 --- a/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp +++ b/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp @@ -127,8 +127,8 @@ void tst_QIcoImageFormat::canRead_data() QTest::newRow("16px,32px,48px - 16,256,16M colors") << "valid/Obj_N2_Internal_Mem.ico" << 1; QTest::newRow("16px - 16,256,16M colors") << "valid/Status_Play.ico" << 1; QTest::newRow("16px,32px - 16 colors") << "valid/TIMER01.ICO" << 1; - QTest::newRow("16px16c, 32px32c, 32px256c") << "valid/WORLD.ico" << 1; - QTest::newRow("16px16c, 32px32c, 32px256c") << "valid/WORLDH.ico" << 1; + QTest::newRow("16px16c, 32px32c, 32px256c 1") << "valid/WORLD.ico" << 1; + QTest::newRow("16px16c, 32px32c, 32px256c 2") << "valid/WORLDH.ico" << 1; QTest::newRow("invalid floppy (first 8 bytes = 0xff)") << "invalid/35floppy.ico" << 0; QTest::newRow("103x16px, 24BPP") << "valid/trolltechlogo_tiny.ico" << 1; QTest::newRow("includes 32BPP w/alpha") << "valid/semitransparent.ico" << 1; @@ -198,8 +198,8 @@ void tst_QIcoImageFormat::imageCount_data() QTest::newRow("16px,32px,48px - 16,256,16M colors") << "valid/Obj_N2_Internal_Mem.ico" << 9; QTest::newRow("16px - 16,256,16M colors") << "valid/Status_Play.ico" << 3; QTest::newRow("16px,32px - 16 colors") << "valid/TIMER01.ICO" << 2; - QTest::newRow("16px16c, 32px32c, 32px256c") << "valid/WORLD.ico" << 3; - QTest::newRow("16px16c, 32px32c, 32px256c") << "valid/WORLDH.ico" << 3; + QTest::newRow("16px16c, 32px32c, 32px256c 1") << "valid/WORLD.ico" << 3; + QTest::newRow("16px16c, 32px32c, 32px256c 2") << "valid/WORLDH.ico" << 3; QTest::newRow("invalid floppy (first 8 bytes = 0xff)") << "invalid/35floppy.ico" << 0; QTest::newRow("includes 32BPP w/alpha") << "valid/semitransparent.ico" << 9; QTest::newRow("PNG compression") << "valid/Qt.ico" << 4; @@ -227,8 +227,8 @@ void tst_QIcoImageFormat::jumpToNextImage_data() QTest::newRow("16px,32px,48px - 16,256,16M colors") << "valid/Obj_N2_Internal_Mem.ico" << 9; QTest::newRow("16px - 16,256,16M colors") << "valid/Status_Play.ico" << 3; QTest::newRow("16px,32px - 16 colors") << "valid/TIMER01.ICO" << 2; - QTest::newRow("16px16c, 32px32c, 32px256c") << "valid/WORLD.ico" << 3; - QTest::newRow("16px16c, 32px32c, 32px256c") << "valid/WORLDH.ico" << 3; + QTest::newRow("16px16c, 32px32c, 32px256c 1") << "valid/WORLD.ico" << 3; + QTest::newRow("16px16c, 32px32c, 32px256c 2") << "valid/WORLDH.ico" << 3; QTest::newRow("includes 32BPP w/alpha") << "valid/semitransparent.ico" << 9; QTest::newRow("PNG compression") << "valid/Qt.ico" << 4; } @@ -276,8 +276,8 @@ void tst_QIcoImageFormat::nextImageDelay_data() QTest::newRow("16px,32px,48px - 16,256,16M colors") << "valid/Obj_N2_Internal_Mem.ico" << 9; QTest::newRow("16px - 16,256,16M colors") << "valid/Status_Play.ico" << 3; QTest::newRow("16px,32px - 16 colors") << "valid/TIMER01.ICO" << 2; - QTest::newRow("16px16c, 32px32c, 32px256c") << "valid/WORLD.ico" << 3; - QTest::newRow("16px16c, 32px32c, 32px256c") << "valid/WORLDH.ico" << 3; + QTest::newRow("16px16c, 32px32c, 32px256c 1") << "valid/WORLD.ico" << 3; + QTest::newRow("16px16c, 32px32c, 32px256c 2") << "valid/WORLDH.ico" << 3; QTest::newRow("invalid floppy (first 8 bytes = 0xff)") << "invalid/35floppy.ico" << -1; QTest::newRow("includes 32BPP w/alpha") << "valid/semitransparent.ico" << 9; QTest::newRow("PNG compression") << "valid/Qt.ico" << 4; diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp index 8a18bee83fd..96171740e2e 100644 --- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp @@ -623,7 +623,6 @@ void tst_QImageReader::supportsAnimation_data() QTest::newRow("XPM: marble") << QString("marble.xpm") << false; QTest::newRow("PNG: kollada") << QString("kollada.png") << false; QTest::newRow("PPM: teapot") << QString("teapot.ppm") << false; - QTest::newRow("PPM: teapot") << QString("teapot.ppm") << false; QTest::newRow("PPM: runners") << QString("runners.ppm") << false; QTest::newRow("XBM: gnus") << QString("gnus.xbm") << false; diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp index 527dcce916a..c1643ea3552 100644 --- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp @@ -1342,7 +1342,7 @@ void tst_QPixmap::fromImageReader_data() QTest::newRow("designer_indexed8_with_alpha.gif") << prefix + "/designer_indexed8_with_alpha.gif"; QTest::newRow("designer_rgb32.jpg") << prefix + "/designer_rgb32.jpg"; QTest::newRow("designer_indexed8_with_alpha_animated") << prefix + "/designer_indexed8_with_alpha_animated.gif"; - QTest::newRow("designer_indexed8_with_alpha_animated") << prefix + "/designer_indexed8_no_alpha_animated.gif"; + QTest::newRow("designer_indexed8_no_alpha_animated") << prefix + "/designer_indexed8_no_alpha_animated.gif"; } void tst_QPixmap::fromImageReader() diff --git a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp index bcd009dfb41..44006d45716 100644 --- a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp +++ b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp @@ -282,13 +282,13 @@ void tst_QPainterPath::contains_QPointF_data() inside.addEllipse(base_rect.adjusted(5, 5, -5, -5)); QPolygonF inside_poly = inside.toFillPolygon(); for (int i=0; i

"); } @@ -1183,7 +1183,7 @@ void tst_QTextDocument::toHtml_data() fmt.setVerticalAlignment(QTextCharFormat::AlignTop); cursor.insertImage(fmt); - QTest::newRow("image-malign") << QTextDocumentFragment(&doc) + QTest::newRow("image-align-top") << QTextDocumentFragment(&doc) << QString("

"); } diff --git a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp index 33293400c2d..50ae22c530f 100644 --- a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp +++ b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp @@ -3078,7 +3078,7 @@ void tst_QTextDocumentFragment::html_preNewlineHandling_data() << QString("Foo\nBar"); QTest::newRow("pre2") << QString("Foo
\nBar")
                           << QString("Foo\nBar");
-    QTest::newRow("pre2") << QString("Foo
\n\nBar")
+    QTest::newRow("pre3") << QString("Foo
\n\nBar")
                           << QString("Foo\n\nBar");
     QTest::newRow("pre4") << QString("Foo
\nBar")
                           << QString("Foo\nBar");

From 2b465676aa76b3735c6a444498dd699dc67427f9 Mon Sep 17 00:00:00 2001
From: Mark Brand 
Date: Mon, 13 Feb 2012 09:42:27 +0100
Subject: [PATCH 206/406] QSqlTableModel::primaryValues(): make const

Change-Id: I6d53beb2b177dc5c71c74755f2fb602ab87502c0
Reviewed-by: Yunqiao Yin 
---
 src/sql/models/qsqltablemodel.cpp | 2 +-
 src/sql/models/qsqltablemodel_p.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index 35346c0f835..29f29bac0d0 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -179,7 +179,7 @@ bool QSqlTableModelPrivate::exec(const QString &stmt, bool prepStatement,
     return true;
 }
 
-QSqlRecord QSqlTableModelPrivate::primaryValues(int row)
+QSqlRecord QSqlTableModelPrivate::primaryValues(int row) const
 {
     QSqlRecord record;
     if (!query.seek(row)) {
diff --git a/src/sql/models/qsqltablemodel_p.h b/src/sql/models/qsqltablemodel_p.h
index dbf2e275b89..8649a91e53b 100644
--- a/src/sql/models/qsqltablemodel_p.h
+++ b/src/sql/models/qsqltablemodel_p.h
@@ -70,7 +70,7 @@ public:
           busyInsertingRows(false)
     {}
     void clear();
-    QSqlRecord primaryValues(int index);
+    QSqlRecord primaryValues(int index) const;
     virtual void clearCache();
     QSqlRecord record(const QVector &values) const;
 

From bfec6b9a7d7ae7bc6772633de1808771d9e6e70b Mon Sep 17 00:00:00 2001
From: Mark Brand 
Date: Mon, 13 Feb 2012 14:16:01 +0100
Subject: [PATCH 207/406] update comment on test

Fix up for f5e1da12f0e7bdeee4db74acc52dfabeb12a4e31.

Change-Id: I3a730ce7e47d71551a46cc105ba2d1fe4e33b65b
Reviewed-by: Robin Burchell 
Reviewed-by: Yunqiao Yin 
---
 tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
index a819cb720c1..c0bdfae8b76 100644
--- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
+++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
@@ -699,7 +699,7 @@ void tst_QSqlTableModel::removeRows()
     QVERIFY(!model.removeRows(-1,1)); // negative start
     QVERIFY(!model.removeRows(-1, 0)); // negative start, and zero count
     QVERIFY(!model.removeRows(1, 0)); // zero count
-    QVERIFY(!model.removeRows(5, 1)); // past end (causes a beforeDelete to be emitted)
+    QVERIFY(!model.removeRows(5, 1)); // past end (DOESN'T causes a beforeDelete to be emitted)
     QVERIFY(!model.removeRows(1, 0, model.index(2, 0))); // can't pass a valid modelindex
 
     QVERIFY_SQL(model, removeRows(0, 2));

From 4a99a42adb865ee58aed023822a1b784338eed8b Mon Sep 17 00:00:00 2001
From: "Bradley T. Hughes" 
Date: Tue, 14 Feb 2012 07:48:34 +0100
Subject: [PATCH 208/406] Compile

mHackedPanel is not declared anywhere in the Cocoa dialog helpers.

Change-Id: I3ba5dd429aa9fe5833b19c1e081425ec4020658d
Reviewed-by: Bradley T. Hughes 
---
 src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm | 1 -
 src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm  | 1 -
 2 files changed, 2 deletions(-)

diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
index f1d6129e3dd..bfc626fdbac 100644
--- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
@@ -226,7 +226,6 @@ static NSButton *macCreateButton(const char *text, NSView *superview)
 
 - (void)onOkClicked
 {
-    Q_ASSERT(mHackedPanel);
     [mColorPanel close];
     [self updateQtColor];
     [self finishOffWithCode:NSOKButton];
diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
index 5d40e5c48ca..d05a0156b13 100644
--- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
@@ -260,7 +260,6 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
 
 - (void)onOkClicked
 {
-    Q_ASSERT(mHackedPanel);
     [mFontPanel close];
     [self finishOffWithCode:NSOKButton];
 }

From 5fb2122c34a8a129379d637a203b6f50cef02e02 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= 
Date: Mon, 6 Feb 2012 00:40:36 +0100
Subject: [PATCH 209/406] Move QtConcurrent configuration to a single file
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This file lives in src/concurrent, alongside the rest of the library. Relevant
configuration was moved out of qglobal.h, as it isn't relevant for other
parties and thus isn't needed there.

This introduces a global header that all QtConcurrent headers now include. This
header includes qglobal.h and defines library-specific configuration for all to
follow.

Change-Id: If6f11e7bbc6139d29004eb1602bd579b75b637c8
Reviewed-by: Oswald Buddenhagen 
Reviewed-by: Morten Johan Sørvig 
---
 src/concurrent/concurrent.pro                 |  1 +
 src/concurrent/qfuture.h                      |  2 +-
 src/concurrent/qfutureinterface.h             |  3 +-
 src/concurrent/qfutureinterface_p.h           |  2 +
 src/concurrent/qfuturesynchronizer.h          |  2 +
 src/concurrent/qfuturewatcher.h               |  2 +
 src/concurrent/qfuturewatcher_p.h             |  2 +
 src/concurrent/qtconcurrent_global.h          | 84 +++++++++++++++++++
 src/concurrent/qtconcurrentcompilertest.h     |  9 +-
 src/concurrent/qtconcurrentexception.h        |  2 +-
 src/concurrent/qtconcurrentfilter.h           |  2 +-
 src/concurrent/qtconcurrentfilterkernel.h     |  2 +-
 src/concurrent/qtconcurrentfunctionwrappers.h |  2 +-
 src/concurrent/qtconcurrentiteratekernel.h    |  2 +-
 src/concurrent/qtconcurrentmap.h              |  2 +-
 src/concurrent/qtconcurrentmapkernel.h        |  2 +-
 src/concurrent/qtconcurrentmedian.h           |  2 +-
 src/concurrent/qtconcurrentreducekernel.h     |  2 +-
 src/concurrent/qtconcurrentresultstore.h      |  2 +-
 src/concurrent/qtconcurrentrun.h              |  2 +-
 src/concurrent/qtconcurrentrunbase.h          |  2 +-
 .../qtconcurrentstoredfunctioncall.h          |  2 +-
 src/concurrent/qtconcurrentthreadengine.h     |  2 +-
 src/corelib/global/qglobal.h                  | 19 -----
 24 files changed, 111 insertions(+), 43 deletions(-)
 create mode 100644 src/concurrent/qtconcurrent_global.h

diff --git a/src/concurrent/concurrent.pro b/src/concurrent/concurrent.pro
index 8ef3c5ca590..6bf16e6a0a5 100644
--- a/src/concurrent/concurrent.pro
+++ b/src/concurrent/concurrent.pro
@@ -31,6 +31,7 @@ SOURCES += \
         qtconcurrentexception.cpp
 
 HEADERS += \
+        qtconcurrent_global.h \
         qfuture.h \
         qfutureinterface.h \
         qfuturesynchronizer.h \
diff --git a/src/concurrent/qfuture.h b/src/concurrent/qfuture.h
index 6e99a6068e2..4005fe58fa9 100644
--- a/src/concurrent/qfuture.h
+++ b/src/concurrent/qfuture.h
@@ -42,7 +42,7 @@
 #ifndef QFUTURE_H
 #define QFUTURE_H
 
-#include 
+#include 
 
 #ifndef QT_NO_QFUTURE
 
diff --git a/src/concurrent/qfutureinterface.h b/src/concurrent/qfutureinterface.h
index 3f05466cc69..9ae2df5d07d 100644
--- a/src/concurrent/qfutureinterface.h
+++ b/src/concurrent/qfutureinterface.h
@@ -42,7 +42,8 @@
 #ifndef QFUTUREINTERFACE_H
 #define QFUTUREINTERFACE_H
 
-#include 
+#include 
+
 #include 
 
 #ifndef QT_NO_QFUTURE
diff --git a/src/concurrent/qfutureinterface_p.h b/src/concurrent/qfutureinterface_p.h
index ea52621378a..3a73f846ac5 100644
--- a/src/concurrent/qfutureinterface_p.h
+++ b/src/concurrent/qfutureinterface_p.h
@@ -53,6 +53,8 @@
 // We mean it.
 //
 
+#include 
+
 #include 
 #include 
 #include 
diff --git a/src/concurrent/qfuturesynchronizer.h b/src/concurrent/qfuturesynchronizer.h
index 8b7e710ea93..3106dd44acd 100644
--- a/src/concurrent/qfuturesynchronizer.h
+++ b/src/concurrent/qfuturesynchronizer.h
@@ -42,6 +42,8 @@
 #ifndef QFUTRUESYNCHRONIZER_H
 #define QFUTRUESYNCHRONIZER_H
 
+#include 
+
 #include 
 
 #ifndef QT_NO_CONCURRENT
diff --git a/src/concurrent/qfuturewatcher.h b/src/concurrent/qfuturewatcher.h
index 6b4b9416218..11dab42174c 100644
--- a/src/concurrent/qfuturewatcher.h
+++ b/src/concurrent/qfuturewatcher.h
@@ -42,6 +42,8 @@
 #ifndef QFUTUREWATCHER_H
 #define QFUTUREWATCHER_H
 
+#include 
+
 #include 
 
 #ifndef QT_NO_QFUTURE
diff --git a/src/concurrent/qfuturewatcher_p.h b/src/concurrent/qfuturewatcher_p.h
index 27bc49439ae..46486bf571e 100644
--- a/src/concurrent/qfuturewatcher_p.h
+++ b/src/concurrent/qfuturewatcher_p.h
@@ -53,6 +53,8 @@
 // We mean it.
 //
 
+#include 
+
 #include "qfutureinterface_p.h"
 #include 
 
diff --git a/src/concurrent/qtconcurrent_global.h b/src/concurrent/qtconcurrent_global.h
new file mode 100644
index 00000000000..1e26c2321d2
--- /dev/null
+++ b/src/concurrent/qtconcurrent_global.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore 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 QTCONCURRENT_GLOBAL_H
+#define QTCONCURRENT_GLOBAL_H
+
+#include 
+
+#ifdef QT_NO_CONCURRENT
+#  define QT_NO_QFUTURE
+#endif
+
+#if defined(Q_OS_WIN) && !defined(QT_NODLL)
+#  if defined(QT_MAKEDLL)
+#    if defined(QT_BUILD_CONCURRENT_LIB)
+#      define Q_CONCURRENT_EXPORT Q_DECL_EXPORT
+#    else
+#      define Q_CONCURRENT_EXPORT Q_DECL_IMPORT
+#    endif
+#  elif defined(QT_DLL)
+#    define Q_CONCURRENT_EXPORT Q_DECL_IMPORT
+#  endif
+#endif
+
+#if !defined(Q_CONCURRENT_EXPORT)
+#  if defined(QT_SHARED)
+#    define Q_CONCURRENT_EXPORT Q_DECL_EXPORT
+#  else
+#    define Q_CONCURRENT_EXPORT
+#  endif
+#endif
+
+// gcc 3 version has problems with some of the
+// map/filter overloads.
+#if defined(Q_CC_GNU) && (__GNUC__ < 4)
+#  define QT_NO_CONCURRENT_MAP
+#  define QT_NO_CONCURRENT_FILTER
+#endif
+
+#if defined (Q_CC_MSVC) && (_MSC_VER < 1300)
+#  define QT_TYPENAME
+#else
+#  define QT_TYPENAME typename
+#endif
+
+#endif // include guard
diff --git a/src/concurrent/qtconcurrentcompilertest.h b/src/concurrent/qtconcurrentcompilertest.h
index 78184230902..7f3f7d42628 100644
--- a/src/concurrent/qtconcurrentcompilertest.h
+++ b/src/concurrent/qtconcurrentcompilertest.h
@@ -42,20 +42,13 @@
 #ifndef QTCONCURRENT_COMPILERTEST_H
 #define QTCONCURRENT_COMPILERTEST_H
 
-#include 
+#include 
 
 #ifndef QT_NO_CONCURRENT
 
 QT_BEGIN_HEADER
 QT_BEGIN_NAMESPACE
 
-
-#if defined (Q_CC_MSVC) && (_MSC_VER < 1300)
-#  define QT_TYPENAME
-#else
-#  define QT_TYPENAME typename
-#endif
-
 namespace QtPrivate {
 
 template
diff --git a/src/concurrent/qtconcurrentexception.h b/src/concurrent/qtconcurrentexception.h
index 2021e7787c1..80926c49c19 100644
--- a/src/concurrent/qtconcurrentexception.h
+++ b/src/concurrent/qtconcurrentexception.h
@@ -42,7 +42,7 @@
 #ifndef QTCONCURRENT_EXCEPTION_H
 #define QTCONCURRENT_EXCEPTION_H
 
-#include 
+#include 
 
 #ifndef QT_NO_QFUTURE
 
diff --git a/src/concurrent/qtconcurrentfilter.h b/src/concurrent/qtconcurrentfilter.h
index 1de8d230b1d..3d4c1d6f57a 100644
--- a/src/concurrent/qtconcurrentfilter.h
+++ b/src/concurrent/qtconcurrentfilter.h
@@ -42,7 +42,7 @@
 #ifndef QTCONCURRENT_FILTER_H
 #define QTCONCURRENT_FILTER_H
 
-#include 
+#include 
 
 #ifndef QT_NO_CONCURRENT
 
diff --git a/src/concurrent/qtconcurrentfilterkernel.h b/src/concurrent/qtconcurrentfilterkernel.h
index 71112cb5a34..9bb4396f41e 100644
--- a/src/concurrent/qtconcurrentfilterkernel.h
+++ b/src/concurrent/qtconcurrentfilterkernel.h
@@ -42,7 +42,7 @@
 #ifndef QTCONCURRENT_FILTERKERNEL_H
 #define QTCONCURRENT_FILTERKERNEL_H
 
-#include 
+#include 
 
 #ifndef QT_NO_CONCURRENT
 
diff --git a/src/concurrent/qtconcurrentfunctionwrappers.h b/src/concurrent/qtconcurrentfunctionwrappers.h
index 9b86b73f6d3..c87770f6c06 100644
--- a/src/concurrent/qtconcurrentfunctionwrappers.h
+++ b/src/concurrent/qtconcurrentfunctionwrappers.h
@@ -42,7 +42,7 @@
 #ifndef QTCONCURRENT_FUNCTIONWRAPPERS_H
 #define QTCONCURRENT_FUNCTIONWRAPPERS_H
 
-#include 
+#include 
 
 #ifndef QT_NO_CONCURRENT
 
diff --git a/src/concurrent/qtconcurrentiteratekernel.h b/src/concurrent/qtconcurrentiteratekernel.h
index 48580537524..6776ff03469 100644
--- a/src/concurrent/qtconcurrentiteratekernel.h
+++ b/src/concurrent/qtconcurrentiteratekernel.h
@@ -42,7 +42,7 @@
 #ifndef QTCONCURRENT_ITERATEKERNEL_H
 #define QTCONCURRENT_ITERATEKERNEL_H
 
-#include 
+#include 
 
 #ifndef QT_NO_CONCURRENT
 
diff --git a/src/concurrent/qtconcurrentmap.h b/src/concurrent/qtconcurrentmap.h
index 8a5557183d9..4e51816b587 100644
--- a/src/concurrent/qtconcurrentmap.h
+++ b/src/concurrent/qtconcurrentmap.h
@@ -42,7 +42,7 @@
 #ifndef QTCONCURRENT_MAP_H
 #define QTCONCURRENT_MAP_H
 
-#include 
+#include 
 
 #ifndef QT_NO_CONCURRENT
 
diff --git a/src/concurrent/qtconcurrentmapkernel.h b/src/concurrent/qtconcurrentmapkernel.h
index ceeaa6e3b35..a1ca2b60fd8 100644
--- a/src/concurrent/qtconcurrentmapkernel.h
+++ b/src/concurrent/qtconcurrentmapkernel.h
@@ -42,7 +42,7 @@
 #ifndef QTCONCURRENT_MAPKERNEL_H
 #define QTCONCURRENT_MAPKERNEL_H
 
-#include 
+#include 
 
 #ifndef QT_NO_CONCURRENT
 
diff --git a/src/concurrent/qtconcurrentmedian.h b/src/concurrent/qtconcurrentmedian.h
index 78fc3d97c88..9a17ecb3b47 100644
--- a/src/concurrent/qtconcurrentmedian.h
+++ b/src/concurrent/qtconcurrentmedian.h
@@ -42,7 +42,7 @@
 #ifndef QTCONCURRENT_MEDIAN_H
 #define QTCONCURRENT_MEDIAN_H
 
-#include 
+#include 
 
 #ifndef QT_NO_CONCURRENT
 
diff --git a/src/concurrent/qtconcurrentreducekernel.h b/src/concurrent/qtconcurrentreducekernel.h
index ddf56298adb..4eaa767b1dd 100644
--- a/src/concurrent/qtconcurrentreducekernel.h
+++ b/src/concurrent/qtconcurrentreducekernel.h
@@ -42,7 +42,7 @@
 #ifndef QTCONCURRENT_REDUCEKERNEL_H
 #define QTCONCURRENT_REDUCEKERNEL_H
 
-#include 
+#include 
 
 #ifndef QT_NO_CONCURRENT
 
diff --git a/src/concurrent/qtconcurrentresultstore.h b/src/concurrent/qtconcurrentresultstore.h
index 4be3c20d486..bb7b39311fe 100644
--- a/src/concurrent/qtconcurrentresultstore.h
+++ b/src/concurrent/qtconcurrentresultstore.h
@@ -42,7 +42,7 @@
 #ifndef QTCONCURRENT_RESULTSTORE_H
 #define QTCONCURRENT_RESULTSTORE_H
 
-#include 
+#include 
 
 #ifndef QT_NO_QFUTURE
 
diff --git a/src/concurrent/qtconcurrentrun.h b/src/concurrent/qtconcurrentrun.h
index d7285388da6..0e46db868d6 100644
--- a/src/concurrent/qtconcurrentrun.h
+++ b/src/concurrent/qtconcurrentrun.h
@@ -43,7 +43,7 @@
 #ifndef QTCONCURRENT_RUN_H
 #define QTCONCURRENT_RUN_H
 
-#include 
+#include 
 
 #ifndef QT_NO_CONCURRENT
 
diff --git a/src/concurrent/qtconcurrentrunbase.h b/src/concurrent/qtconcurrentrunbase.h
index 2105437edeb..2637abfc2e7 100644
--- a/src/concurrent/qtconcurrentrunbase.h
+++ b/src/concurrent/qtconcurrentrunbase.h
@@ -42,7 +42,7 @@
 #ifndef QTCONCURRENT_RUNBASE_H
 #define QTCONCURRENT_RUNBASE_H
 
-#include 
+#include 
 
 #ifndef QT_NO_CONCURRENT
 
diff --git a/src/concurrent/qtconcurrentstoredfunctioncall.h b/src/concurrent/qtconcurrentstoredfunctioncall.h
index c311a72427c..d980e256235 100644
--- a/src/concurrent/qtconcurrentstoredfunctioncall.h
+++ b/src/concurrent/qtconcurrentstoredfunctioncall.h
@@ -43,7 +43,7 @@
 #ifndef QTCONCURRENT_STOREDFUNCTIONCALL_H
 #define QTCONCURRENT_STOREDFUNCTIONCALL_H
 
-#include 
+#include 
 
 #ifndef QT_NO_CONCURRENT
 #include 
diff --git a/src/concurrent/qtconcurrentthreadengine.h b/src/concurrent/qtconcurrentthreadengine.h
index 679496ce408..3ecdc84600e 100644
--- a/src/concurrent/qtconcurrentthreadengine.h
+++ b/src/concurrent/qtconcurrentthreadengine.h
@@ -42,7 +42,7 @@
 #ifndef QTCONCURRENT_THREADENGINE_H
 #define QTCONCURRENT_THREADENGINE_H
 
-#include 
+#include 
 
 #ifndef QT_NO_CONCURRENT
 
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 456624071c2..91ac4bd41de 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -671,11 +671,6 @@ class QDataStream;
 #      define Q_DBUS_EXPORT Q_DECL_IMPORT
 #    endif
 #    define Q_TEMPLATEDLL
-#    if defined(QT_BUILD_CONCURRENT_LIB)
-#      define Q_CONCURRENT_EXPORT Q_DECL_EXPORT
-#    else
-#      define Q_CONCURRENT_EXPORT Q_DECL_IMPORT
-#    endif
 #  elif defined(QT_DLL) /* use a Qt DLL library */
 #    define Q_CORE_EXPORT Q_DECL_IMPORT
 #    define Q_GUI_EXPORT Q_DECL_IMPORT
@@ -697,7 +692,6 @@ class QDataStream;
 #    define Q_SCRIPTTOOLS_EXPORT Q_DECL_IMPORT
 #    define Q_COMPAT_EXPORT Q_DECL_IMPORT
 #    define Q_DBUS_EXPORT Q_DECL_IMPORT
-#    define Q_CONCURRENT_EXPORT Q_DECL_IMPORT
 #    define Q_TEMPLATEDLL
 #  endif
 #  define Q_NO_DECLARED_NOT_DEFINED
@@ -731,7 +725,6 @@ class QDataStream;
 #    define Q_SCRIPTTOOLS_EXPORT Q_DECL_EXPORT
 #    define Q_COMPAT_EXPORT Q_DECL_EXPORT
 #    define Q_DBUS_EXPORT Q_DECL_EXPORT
-#    define Q_CONCURRENT_EXPORT Q_DECL_EXPORT
 #  else
 #    define Q_CORE_EXPORT
 #    define Q_GUI_EXPORT
@@ -752,7 +745,6 @@ class QDataStream;
 #    define Q_SCRIPTTOOLS_EXPORT
 #    define Q_COMPAT_EXPORT
 #    define Q_DBUS_EXPORT
-#    define Q_CONCURRENT_EXPORT
 #  endif
 #endif
 
@@ -1752,17 +1744,6 @@ Q_CORE_EXPORT int qrand();
 
 #define QT_MODULE(x)
 
-#ifdef QT_NO_CONCURRENT
-#  define QT_NO_QFUTURE
-#endif
-
-// gcc 3 version has problems with some of the
-// map/filter overloads.
-#if defined(Q_CC_GNU) && (__GNUC__ < 4)
-#  define QT_NO_CONCURRENT_MAP
-#  define QT_NO_CONCURRENT_FILTER
-#endif
-
 #ifdef Q_OS_QNX
 // QNX doesn't have SYSV style shared memory. Multiprocess QWS apps,
 // shared fonts and QSystemSemaphore + QSharedMemory are not available

From c93ac6758606f64af7fe2bac6c8bb08391d218a7 Mon Sep 17 00:00:00 2001
From: Xizhi Zhu 
Date: Wed, 18 Jan 2012 21:38:17 +0100
Subject: [PATCH 210/406] Fix online status checking in generic bearer plugin.

QNetworkInterface::IsUp means the interface is up, but not necessarily
connected. QNetworkInterface::IsRunning means the interface is up and
connected.

Task-number: QTBUG-22873
Change-Id: Ieb544058814520b4292b496de2e4672214f3d00a
Reviewed-by: Shane Kearns 
---
 src/plugins/bearer/generic/qgenericengine.cpp |  2 +-
 .../qnetworkconfigurationmanager/main.cpp     | 84 +++++++++++++++++++
 .../qnetworkconfigurationmanager.pro          | 13 +++
 3 files changed, 98 insertions(+), 1 deletion(-)
 create mode 100644 tests/manual/qnetworkconfigurationmanager/main.cpp
 create mode 100644 tests/manual/qnetworkconfigurationmanager/qnetworkconfigurationmanager.pro

diff --git a/src/plugins/bearer/generic/qgenericengine.cpp b/src/plugins/bearer/generic/qgenericengine.cpp
index a90d066ad65..7b30b5d64c2 100644
--- a/src/plugins/bearer/generic/qgenericengine.cpp
+++ b/src/plugins/bearer/generic/qgenericengine.cpp
@@ -232,7 +232,7 @@ void QGenericEngine::doRequestUpdate()
             name = interface.name();
 
         QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Defined;
-        if((interface.flags() & QNetworkInterface::IsUp) && !interface.addressEntries().isEmpty())
+        if ((interface.flags() & QNetworkInterface::IsRunning) && !interface.addressEntries().isEmpty())
             state |= QNetworkConfiguration::Active;
 
         if (accessPointConfigurations.contains(id)) {
diff --git a/tests/manual/qnetworkconfigurationmanager/main.cpp b/tests/manual/qnetworkconfigurationmanager/main.cpp
new file mode 100644
index 00000000000..2ac33d4fe1e
--- /dev/null
+++ b/tests/manual/qnetworkconfigurationmanager/main.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the test suite 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 
+#include 
+#include 
+#include 
+
+class tst_qnetworkconfigurationmanager : public QObject
+{
+    Q_OBJECT
+
+private slots:
+    void isOnline();
+};
+
+class SignalHandler : public QObject
+{
+    Q_OBJECT
+
+public slots:
+    void onOnlineStateChanged(bool isOnline)
+    {
+        qDebug() << "Online state changed to:" << isOnline;
+    }
+};
+
+void tst_qnetworkconfigurationmanager::isOnline()
+{
+    QNetworkConfigurationManager manager;
+    qDebug() << "Testing QNetworkConfigurationManager online status reporting functionality.";
+    qDebug() << "This should tell the current online state:" << manager.isOnline();
+    qDebug() << "Now please plug / unplug the network cable, and check the state update signal.";
+    qDebug() << "Note that there might be some delays before you see the change, depending on the backend.";
+
+    SignalHandler signalHandler;
+    connect(&manager, SIGNAL(onlineStateChanged(bool)), &signalHandler, SLOT(onOnlineStateChanged(bool)));
+
+    // event loop
+    QTestEventLoop::instance().enterLoop(30);
+    QVERIFY(QTestEventLoop::instance().timeout());
+}
+
+QTEST_MAIN(tst_qnetworkconfigurationmanager)
+
+#include "main.moc"
diff --git a/tests/manual/qnetworkconfigurationmanager/qnetworkconfigurationmanager.pro b/tests/manual/qnetworkconfigurationmanager/qnetworkconfigurationmanager.pro
new file mode 100644
index 00000000000..613fcd85e49
--- /dev/null
+++ b/tests/manual/qnetworkconfigurationmanager/qnetworkconfigurationmanager.pro
@@ -0,0 +1,13 @@
+CONFIG += testcase
+TEMPLATE = app
+TARGET = tst_qnetworkconfigurationmanager
+DEPENDPATH += .
+INCLUDEPATH += .
+
+QT -= gui
+QT += network testlib
+
+CONFIG += release
+
+# Input
+SOURCES += main.cpp

From 960f246ffc37141101952757bc0234183a6163a9 Mon Sep 17 00:00:00 2001
From: Rick Stockton 
Date: Tue, 14 Feb 2012 09:02:10 -0800
Subject: [PATCH 211/406] fix whitespace in qnamespace.qdoc

repair instances of (1) trailing ws; and (2) tabs+spaces.

Task-number: QTBUG-22642

Change-Id: I775c6e1c65625340f6279bcff042dd8e74271021
Reviewed-by: Rick Stockton 
Reviewed-by: Alan Alpert 
---
 src/corelib/global/qnamespace.qdoc | 48 +++++++++++++++---------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index da7bcb714a5..8c3fa148fcd 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -174,8 +174,8 @@
     \value NoButton        The button state does not refer to any
     button (see QMouseEvent::button()).
     \value LeftButton      The left button is pressed, or an event refers
-    to the left button. (The left button may be the right button on
-    left-handed mice.)
+           to the left button. (The left button may be the right button on
+           left-handed mice.)
     \value RightButton     The right button.
     \value MidButton       The middle button.
     \value MiddleButton    The middle button.
@@ -462,20 +462,20 @@
     delivery at a later time.
 
     \value AutoConnection
-            (default) If the signal is emitted from a different thread than the
-            receiving object, the signal is queued, behaving as
-            Qt::QueuedConnection. Otherwise, the slot is invoked directly,
-            behaving as Qt::DirectConnection. The type of connection is
-            determined when the signal is emitted.
+           (default) If the signal is emitted from a different thread than the
+           receiving object, the signal is queued, behaving as
+           Qt::QueuedConnection. Otherwise, the slot is invoked directly,
+           behaving as Qt::DirectConnection. The type of connection is
+           determined when the signal is emitted.
 
     \value DirectConnection
-	   The slot is invoked immediately, when the signal is
-       	   emitted.
+           The slot is invoked immediately, when the signal is
+           emitted.
 
     \value QueuedConnection
-    	   The slot is invoked when control returns to the event loop
-       	   of the receiver's thread. The slot is executed in the
-       	   receiver's thread.
+           The slot is invoked when control returns to the event loop
+           of the receiver's thread. The slot is executed in the
+           receiver's thread.
 
     \value BlockingQueuedConnection
            Same as QueuedConnection, except the current thread blocks
@@ -486,17 +486,17 @@
 
     \value UniqueConnection
            Same as AutoConnection, but the connection is made only if
-    	   it does not duplicate an existing connection. i.e., if the
-    	   same signal is already connected to the same slot for the
-    	   same pair of objects, then the connection will fail. This
-    	   connection type was introduced in Qt 4.6.
+           it does not duplicate an existing connection. i.e., if the
+           same signal is already connected to the same slot for the
+           same pair of objects, then the connection will fail. This
+           connection type was introduced in Qt 4.6.
 
     \value AutoCompatConnection
-    	   The default type when Qt 3 support is enabled. Same as
-	   AutoConnection but will also cause warnings to be output in
-	   certain situations. See \l{Porting to Qt 4#Compatibility
-	   Signals and Slots}{Compatibility Signals and Slots} for
-	   further information.
+           The default type when Qt 3 support is enabled. Same as
+           AutoConnection but will also cause warnings to be output in
+           certain situations. See \l{Porting to Qt 4#Compatibility
+           Signals and Slots}{Compatibility Signals and Slots} for
+           further information.
 
     With queued connections, the parameters must be of types that are
     known to Qt's meta-object system, because Qt needs to copy the
@@ -2137,9 +2137,9 @@
                             should be taken over by the target application,
                             i.e., the source application should not delete
                             the data.
-			    \br
-			    On X11 this value is used to do a move.
-			    \br
+                            \br
+                            On X11 this value is used to do a move.
+                            \br
                             TargetMoveAction is not used on the Mac.
 */
 

From 78a6447e311e55320ab3acd5f1035f3c295bf5f8 Mon Sep 17 00:00:00 2001
From: Miikka Heikkinen 
Date: Mon, 13 Feb 2012 16:45:13 +0200
Subject: [PATCH 212/406] Windows: Fixed helper process finding in network
 tests

Helper processes were not found properly on all network tests
when the test was run with "nmake check":

- tst_qtcpsocket
- tst_qtcpserver
- tst_qnetworksession
- tst_qnetworkreply

Task-number: QTBUG-24199
Task-number: QTBUG-24203
Task-number: QTBUG-24226
Task-number: QTBUG-24231
Task-number: QTBUG-24232

Change-Id: Ia4451b5a5e3fe9f81aba3837baf8292411f995d8
Reviewed-by: Friedemann Kleint 
Reviewed-by: Shane Kearns 
---
 .../access/qnetworkreply/tst_qnetworkreply.cpp  | 10 +++++++++-
 .../test/tst_qnetworksession.cpp                | 13 +++++++++----
 .../socket/qtcpserver/tst_qtcpserver.cpp        | 15 +++++++++++++--
 .../socket/qtcpsocket/tst_qtcpsocket.cpp        | 17 +++++++++++++----
 4 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
index 0e9136dbc79..866afbf0a5e 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -135,6 +135,7 @@ class tst_QNetworkReply: public QObject
     enum RunSimpleRequestReturn { Timeout = 0, Success, Failure };
     int returnCode;
     QString testFileName;
+    QString echoProcessDir;
 #if !defined Q_OS_WIN
     QString wronlyFileName;
 #endif
@@ -1308,6 +1309,10 @@ void tst_QNetworkReply::initTestCase()
         QVERIFY(networkSession->waitForOpened(30000));
     }
 #endif
+
+    echoProcessDir = QFINDTESTDATA("echo");
+    QVERIFY2(!echoProcessDir.isEmpty(), qPrintable(
+        QString::fromLatin1("Couldn't find echo dir starting from %1.").arg(QDir::currentPath())));
 }
 
 void tst_QNetworkReply::cleanupTestCase()
@@ -3849,7 +3854,10 @@ void tst_QNetworkReply::ioPutToFileFromProcess()
 
     QFETCH(QByteArray, data);
     QProcess process;
-    process.start("echo/echo all");
+    QString echoExe = echoProcessDir + "/echo";
+    process.start(echoExe, QStringList("all"));
+    QVERIFY2(process.waitForStarted(), qPrintable(
+        QString::fromLatin1("Could not start %1: %2").arg(echoExe, process.errorString())));
     process.write(data);
     process.closeWriteChannel();
 
diff --git a/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp b/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp
index a51b4e56322..27e1e7f013e 100644
--- a/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp
+++ b/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp
@@ -96,6 +96,7 @@ private slots:
 private:
     QNetworkConfigurationManager manager;
     int inProcessSessionManagementCount;
+    QString lackeyDir;
 #endif
 };
 
@@ -117,6 +118,10 @@ void tst_QNetworkSession::initTestCase()
     QSignalSpy spy(&manager, SIGNAL(updateCompleted()));
     manager.updateConfigurations();
     QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, TestTimeOut);
+
+    lackeyDir = QFINDTESTDATA("lackey");
+    QVERIFY2(!lackeyDir.isEmpty(), qPrintable(
+        QString::fromLatin1("Couldn't find lackey dir starting from %1.").arg(QDir::currentPath())));
 }
 
 void tst_QNetworkSession::cleanupTestCase()
@@ -916,10 +921,10 @@ void tst_QNetworkSession::outOfProcessSession()
     oopServer.listen("tst_qnetworksession");
 
     QProcess lackey;
-    lackey.start("lackey/lackey");
-    qDebug() << lackey.error() << lackey.errorString();
-    QVERIFY(lackey.waitForStarted());
-
+    QString lackeyExe = lackeyDir + "/lackey";
+    lackey.start(lackeyExe);
+    QVERIFY2(lackey.waitForStarted(), qPrintable(
+        QString::fromLatin1("Could not start %1: %2").arg(lackeyExe, lackey.errorString())));
 
     QVERIFY(oopServer.waitForNewConnection(-1));
     QLocalSocket *oopSocket = oopServer.nextPendingConnection();
diff --git a/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp b/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp
index 941e0b21423..ac27a621bbd 100644
--- a/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp
+++ b/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp
@@ -119,6 +119,7 @@ private:
 #ifndef QT_NO_BEARERMANAGEMENT
     QNetworkSession *networkSession;
 #endif
+    QString crashingServerDir;
 };
 
 // Testing get/set functions
@@ -150,6 +151,10 @@ void tst_QTcpServer::initTestCase_data()
 
     QTest::newRow("WithoutProxy") << false << 0;
     QTest::newRow("WithSocks5Proxy") << true << int(QNetworkProxy::Socks5Proxy);
+
+    crashingServerDir = QFINDTESTDATA("crashingServer");
+    QVERIFY2(!crashingServerDir.isEmpty(), qPrintable(
+        QString::fromLatin1("Couldn't find crashingServer dir starting from %1.").arg(QDir::currentPath())));
 }
 
 void tst_QTcpServer::initTestCase()
@@ -538,7 +543,10 @@ void tst_QTcpServer::addressReusable()
     QFile::remove(signalName);
     // The crashingServer process will crash once it gets a connection.
     QProcess process;
-    process.start("crashingServer/crashingServer");
+    QString processExe = crashingServerDir + "/crashingServer";
+    process.start(processExe);
+    QVERIFY2(process.waitForStarted(), qPrintable(
+        QString::fromLatin1("Could not start %1: %2").arg(processExe, process.errorString())));
     int waitCount = 5;
     while (waitCount-- && !QFile::exists(signalName))
         QTest::qWait(1000);
@@ -547,7 +555,10 @@ void tst_QTcpServer::addressReusable()
 #else
     // The crashingServer process will crash once it gets a connection.
     QProcess process;
-    process.start("crashingServer/crashingServer");
+    QString processExe = crashingServerDir + "/crashingServer";
+    process.start(processExe);
+    QVERIFY2(process.waitForStarted(), qPrintable(
+        QString::fromLatin1("Could not start %1: %2").arg(processExe, process.errorString())));
     QVERIFY(process.waitForReadyRead(5000));
 #endif
 
diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
index 829ddd20549..abeb1ed06d5 100644
--- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
+++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
@@ -246,6 +246,7 @@ private:
     SocketPair *earlyConstructedSockets;
     int earlyBytesWrittenCount;
     int earlyReadyReadCount;
+    QString stressTestDir;
 };
 
 enum ProxyTests {
@@ -340,6 +341,10 @@ void tst_QTcpSocket::initTestCase_data()
     QTest::newRow("WithHttpProxyBasicAuth SSL") << true << int(HttpProxy | AuthBasic) << true;
 //    QTest::newRow("WithHttpProxyNtlmAuth SSL") << true << int(HttpProxy | AuthNtlm) << true;
 #endif
+
+    stressTestDir = QFINDTESTDATA("stressTest");
+    QVERIFY2(!stressTestDir.isEmpty(), qPrintable(
+        QString::fromLatin1("Couldn't find stressTest dir starting from %1.").arg(QDir::currentPath())));
 }
 
 void tst_QTcpSocket::initTestCase()
@@ -2225,11 +2230,14 @@ void tst_QTcpSocket::suddenRemoteDisconnect()
     if (ssl)
         return;
 
+    QString processExe = stressTestDir + "/stressTest";
+
     // Start server
     QProcess serverProcess;
     serverProcess.setReadChannel(QProcess::StandardError);
-    serverProcess.start(QString::fromLatin1("stressTest/stressTest %1").arg(server),
-                        QIODevice::ReadWrite | QIODevice::Text);
+    serverProcess.start(processExe, QStringList(server), QIODevice::ReadWrite | QIODevice::Text);
+    QVERIFY2(serverProcess.waitForStarted(), qPrintable(
+        QString::fromLatin1("Could not start %1: %2").arg(processExe, serverProcess.errorString())));
     while (!serverProcess.canReadLine())
         QVERIFY(serverProcess.waitForReadyRead(10000));
     QCOMPARE(serverProcess.readLine().data(), (server.toLatin1() + "\n").data());
@@ -2237,8 +2245,9 @@ void tst_QTcpSocket::suddenRemoteDisconnect()
     // Start client
     QProcess clientProcess;
     clientProcess.setReadChannel(QProcess::StandardError);
-    clientProcess.start(QString::fromLatin1("stressTest/stressTest %1").arg(client),
-                        QIODevice::ReadWrite | QIODevice::Text);
+    clientProcess.start(processExe, QStringList(client), QIODevice::ReadWrite | QIODevice::Text);
+    QVERIFY2(clientProcess.waitForStarted(), qPrintable(
+        QString::fromLatin1("Could not start %1: %2").arg(processExe, clientProcess.errorString())));
     while (!clientProcess.canReadLine())
         QVERIFY(clientProcess.waitForReadyRead(10000));
     QCOMPARE(clientProcess.readLine().data(), (client.toLatin1() + "\n").data());

From 3d3f5f84fe3bbe9862ac3837c9dfb38216c1a081 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint 
Date: Tue, 14 Feb 2012 08:55:02 +0100
Subject: [PATCH 213/406] Move desktopSettingsAware to QGuiApplication.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

For use by the QPA plugins.

Reviewed-by: Samuel Rødal 
Reviewed-by: Morten Sørvig 

Task-number: QTBUG-24204

Change-Id: I7f35274eedb55fcb60ad289768234bc302286d01
Reviewed-by: Friedemann Kleint 
---
 src/gui/kernel/qguiapplication.cpp  | 27 +++++++++++++++++++++++++++
 src/gui/kernel/qguiapplication.h    |  3 +++
 src/gui/kernel/qguiapplication_p.h  |  1 +
 src/widgets/kernel/qapplication.cpp | 28 ----------------------------
 src/widgets/kernel/qapplication.h   |  3 ---
 src/widgets/kernel/qapplication_p.h |  1 -
 6 files changed, 31 insertions(+), 32 deletions(-)

diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 0e525da1516..5ca6364fbb5 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -126,6 +126,7 @@ QWindow *QGuiApplicationPrivate::focus_window = 0;
 
 static QBasicMutex applicationFontMutex;
 QFont *QGuiApplicationPrivate::app_font = 0;
+bool QGuiApplicationPrivate::obey_desktop_settings = true;
 
 extern void qRegisterGuiVariant();
 extern void qUnregisterGuiVariant();
@@ -1619,6 +1620,32 @@ QStyleHints *QGuiApplication::styleHints() const
     return d->styleHints;
 }
 
+/*!
+    Sets whether Qt should use the system's standard colors, fonts, etc., to
+    \a on. By default, this is true.
+
+    This function must be called before creating the QGuiApplication object, like
+    this:
+
+    \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 6
+
+    \sa desktopSettingsAware()
+*/
+void QGuiApplication::setDesktopSettingsAware(bool on)
+{
+    QGuiApplicationPrivate::obey_desktop_settings = on;
+}
+
+/*!
+    Returns true if Qt is set to use the system's standard colors, fonts, etc.;
+    otherwise returns false. The default is true.
+
+    \sa setDesktopSettingsAware()
+*/
+bool QGuiApplication::desktopSettingsAware()
+{
+    return QGuiApplicationPrivate::obey_desktop_settings;
+}
 
 /*!
   \since 5.0
diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h
index 75046d8767f..d853bc14109 100644
--- a/src/gui/kernel/qguiapplication.h
+++ b/src/gui/kernel/qguiapplication.h
@@ -121,6 +121,9 @@ public:
     static inline bool isLeftToRight() { return layoutDirection() == Qt::LeftToRight; }
 
     QStyleHints *styleHints() const;
+    static void setDesktopSettingsAware(bool on);
+    static bool desktopSettingsAware();
+
     QT_DEPRECATED QInputPanel *inputPanel() const;
     QInputMethod *inputMethod() const;
 
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 66db8437e54..5f2e92c504e 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -181,6 +181,7 @@ public:
     static QFont *app_font;
 
     QStyleHints *styleHints;
+    static bool obey_desktop_settings;
     QInputMethod *inputMethod;
 
     static QList generic_plugin_list;
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 8d776e2f29a..4387d2a2878 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -419,7 +419,6 @@ QWidget *QApplicationPrivate::main_widget = 0;        // main application widget
 QWidget *QApplicationPrivate::focus_widget = 0;        // has keyboard input focus
 QWidget *QApplicationPrivate::hidden_focus_widget = 0; // will get keyboard input focus after show()
 QWidget *QApplicationPrivate::active_window = 0;        // toplevel with keyboard focus
-bool QApplicationPrivate::obey_desktop_settings = true;        // use winsys resources
 #ifndef QT_NO_WHEELEVENT
 int QApplicationPrivate::wheel_scroll_lines;   // number of lines to scroll
 #endif
@@ -2910,33 +2909,6 @@ QDesktopWidget *QApplication::desktop()
     return qt_desktopWidget;
 }
 
-/*!
-    Sets whether Qt should use the system's standard colors, fonts, etc., to
-    \a on. By default, this is true.
-
-    This function must be called before creating the QApplication object, like
-    this:
-
-    \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 6
-
-    \sa desktopSettingsAware()
-*/
-void QApplication::setDesktopSettingsAware(bool on)
-{
-    QApplicationPrivate::obey_desktop_settings = on;
-}
-
-/*!
-    Returns true if Qt is set to use the system's standard colors, fonts, etc.;
-    otherwise returns false. The default is true.
-
-    \sa setDesktopSettingsAware()
-*/
-bool QApplication::desktopSettingsAware()
-{
-    return QApplicationPrivate::obey_desktop_settings;
-}
-
 /*!
     Returns the current state of the modifier keys on the keyboard. The current
     state is updated sychronously as the event queue is emptied of events that
diff --git a/src/widgets/kernel/qapplication.h b/src/widgets/kernel/qapplication.h
index bace73e072d..503b36aec67 100644
--- a/src/widgets/kernel/qapplication.h
+++ b/src/widgets/kernel/qapplication.h
@@ -158,9 +158,6 @@ public:
     static Qt::KeyboardModifiers queryKeyboardModifiers();
     static Qt::MouseButtons mouseButtons();
 
-    static void setDesktopSettingsAware(bool);
-    static bool desktopSettingsAware();
-
     static void setCursorFlashTime(int);
     static int cursorFlashTime();
 
diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h
index b4cd22df132..790176afe37 100644
--- a/src/widgets/kernel/qapplication_p.h
+++ b/src/widgets/kernel/qapplication_p.h
@@ -267,7 +267,6 @@ public:
     static QWidget *hidden_focus_widget;
     static QWidget *active_window;
     static QIcon *app_icon;
-    static bool obey_desktop_settings;
 #ifndef QT_NO_WHEELEVENT
     static int  wheel_scroll_lines;
 #endif

From 016633931f708f6495874a8722c7aae657e37438 Mon Sep 17 00:00:00 2001
From: Kent Hansen 
Date: Mon, 6 Feb 2012 19:00:13 +0100
Subject: [PATCH 214/406] Store only unique strings in the QtDBus meta-object
 string table

Do like moc: If the string has already been entered into the table,
just return its position, don't make a new copy. This can save
space, for example, if there are several properties of the same type;
the typename only occurs once in the string table but will be
referenced by several property descriptors.

Change-Id: I63e5c73d28ba117fd00a5261d0e89f3a3d83df9a
Reviewed-by: Thiago Macieira 
---
 src/dbus/qdbusmetaobject.cpp | 88 +++++++++++++++++++++---------------
 1 file changed, 51 insertions(+), 37 deletions(-)

diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp
index c83865978cd..734b21c0fbd 100644
--- a/src/dbus/qdbusmetaobject.cpp
+++ b/src/dbus/qdbusmetaobject.cpp
@@ -360,9 +360,39 @@ void QDBusMetaObjectGenerator::parseProperties()
 
 void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
 {
+    class MetaStringTable
+    {
+    public:
+        typedef QHash Entries; // string --> offset mapping
+        typedef Entries::const_iterator const_iterator;
+        Entries::const_iterator constBegin() const
+        { return m_entries.constBegin(); }
+        Entries::const_iterator constEnd() const
+        { return m_entries.constEnd(); }
+
+        MetaStringTable() : m_offset(0) {}
+
+        int enter(const QByteArray &value)
+        {
+            Entries::iterator it = m_entries.find(value);
+            if (it != m_entries.end())
+                return it.value();
+            int pos = m_offset;
+            m_entries.insert(value, pos);
+            m_offset += value.size() + 1;
+            return pos;
+        }
+
+        int arraySize() const { return m_offset; }
+
+    private:
+        Entries m_entries;
+        int m_offset;
+    };
+
     // this code here is mostly copied from qaxbase.cpp
     // with a few modifications to make it cleaner
-    
+
     QString className = interface;
     className.replace(QLatin1Char('.'), QLatin1String("::"));
     if (className.isEmpty())
@@ -400,10 +430,8 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
         data_size += 2 + mm.inputTypes.count() + mm.outputTypes.count();
     idata.resize(data_size + 1);
 
-    char null('\0');
-    QByteArray stringdata = className.toLatin1();
-    stringdata += null;
-    stringdata.reserve(8192);
+    MetaStringTable strings;
+    strings.enter(className.toLatin1());
 
     int offset = header->methodData;
     int signatureOffset = header->methodDBusData;
@@ -419,29 +447,15 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
             // form "prototype\0parameters\0typeName\0tag\0methodname\0inputSignature\0outputSignature"
             const Method &mm = it.value();
 
-            idata[offset++] = stringdata.length();
-            stringdata += it.key();                 // prototype
-            stringdata += null;
-            idata[offset++] = stringdata.length();
-            stringdata += mm.parameters;
-            stringdata += null;
-            idata[offset++] = stringdata.length();
-            stringdata += mm.typeName;
-            stringdata += null;
-            idata[offset++] = stringdata.length();
-            stringdata += mm.tag;
-            stringdata += null;
+            idata[offset++] = strings.enter(it.key()); // prototype
+            idata[offset++] = strings.enter(mm.parameters);
+            idata[offset++] = strings.enter(mm.typeName);
+            idata[offset++] = strings.enter(mm.tag);
             idata[offset++] = mm.flags;
 
-            idata[signatureOffset++] = stringdata.length();
-            stringdata += mm.name;
-            stringdata += null;
-            idata[signatureOffset++] = stringdata.length();
-            stringdata += mm.inputSignature;
-            stringdata += null;
-            idata[signatureOffset++] = stringdata.length();
-            stringdata += mm.outputSignature;
-            stringdata += null;
+            idata[signatureOffset++] = strings.enter(mm.name);
+            idata[signatureOffset++] = strings.enter(mm.inputSignature);
+            idata[signatureOffset++] = strings.enter(mm.outputSignature);
 
             idata[signatureOffset++] = typeidOffset;
             idata[typeidOffset++] = mm.inputTypes.count();
@@ -466,25 +480,25 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
         const Property &mp = it.value();
 
         // form is "name\0typeName\0signature\0"
-        idata[offset++] = stringdata.length();
-        stringdata += it.key();                 // name
-        stringdata += null;
-        idata[offset++] = stringdata.length();
-        stringdata += mp.typeName;
-        stringdata += null;
+        idata[offset++] = strings.enter(it.key()); // name
+        idata[offset++] = strings.enter(mp.typeName);
         idata[offset++] = mp.flags;
 
-        idata[signatureOffset++] = stringdata.length();
-        stringdata += mp.signature;
-        stringdata += null;
+        idata[signatureOffset++] = strings.enter(mp.signature);
         idata[signatureOffset++] = mp.type;
     }
 
     Q_ASSERT(offset == header->propertyDBusData);
     Q_ASSERT(signatureOffset == header->methodDBusData);
 
-    char *string_data = new char[stringdata.length()];
-    memcpy(string_data, stringdata, stringdata.length());
+    char *string_data = new char[strings.arraySize()];
+    {
+        MetaStringTable::const_iterator it;
+        for (it = strings.constBegin(); it != strings.constEnd(); ++it) {
+            memcpy(string_data + it.value(), it.key().constData(), it.key().size());
+            string_data[it.value() + it.key().size()] = '\0';
+        }
+    }
 
     uint *uint_data = new uint[idata.size()];
     memcpy(uint_data, idata.data(), idata.size() * sizeof(int));

From 0554d1391028e6deffd7b52fa95650bc1f95d295 Mon Sep 17 00:00:00 2001
From: Kent Hansen 
Date: Mon, 13 Feb 2012 14:43:40 +0100
Subject: [PATCH 215/406] Remove needless line "#define d d_ptr"

There was a time when qsslsocket.h declared its private slots as

Q_PRIVATE_SLOT(d, void _q_connectedSlot())

But now they are correctly declared as

Q_PRIVATE_SLOT(d_func(), void _q_connectedSlot())

so the "#define d d_ptr" hack isn't needed.
Specifically, the define would break moc-generated code that refers
to the member d of a structure (which a future moc revision does,
namely QByteArrayData::d).

Change-Id: Ic94fa4d523fb17e8088973cfc0d090d5cce97267
Reviewed-by: Jonas Gastal 
Reviewed-by: Thiago Macieira 
---
 src/network/ssl/qsslsocket.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index ffc9f3f9fee..311ac5fe86b 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -2345,6 +2345,4 @@ QList QSslSocketPrivate::unixRootCertDirectories()
 
 QT_END_NAMESPACE
 
-// For private slots
-#define d d_ptr
 #include "moc_qsslsocket.cpp"

From 45bf920947a7be2af047bd0f09a76a3c2064c3d7 Mon Sep 17 00:00:00 2001
From: Rafael Roquetto 
Date: Tue, 14 Feb 2012 17:44:44 +0100
Subject: [PATCH 216/406] Fixes QTemporaryDir compilation error under QNX.

Checking for Q_OS_QNX as well upon QFileSystemEngine inclusion.

Change-Id: Ia0e0d7344abaae6dd6375528f0cc17dbefafe8d8
Reviewed-by: Andreas Holzammer 
Reviewed-by: Oswald Buddenhagen 
---
 src/corelib/io/qtemporarydir.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/corelib/io/qtemporarydir.cpp b/src/corelib/io/qtemporarydir.cpp
index 13969ca90ec..f8cd2e780e8 100644
--- a/src/corelib/io/qtemporarydir.cpp
+++ b/src/corelib/io/qtemporarydir.cpp
@@ -52,7 +52,7 @@
 #endif
 
 #include  // mkdtemp
-#ifdef Q_OS_WIN
+#if defined(Q_OS_QNX) || defined(Q_OS_WIN)
 #include 
 #endif
 

From a28c433b290dae1b3509ddf1eee616ba91ce221b Mon Sep 17 00:00:00 2001
From: Shane Kearns 
Date: Tue, 14 Feb 2012 20:12:42 +0000
Subject: [PATCH 217/406] Abort FTP download, not the whole application

An old coding error meant that the C runtime abort() function was
being called instead of QFtp::abort() when cancelling an FTP download
using QNetworkReply::close()

Task-number: QTBUG-22820
Change-Id: Ib97fda9769b2b55a08c042c66c4444cb6216d2b1
Reviewed-by: Thiago Macieira 
---
 .../access/qnetworkaccessftpbackend.cpp       |  6 +----
 .../qnetworkreply/tst_qnetworkreply.cpp       | 24 +++++++++++++++++++
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp
index 98967e730e9..42201aa9a31 100644
--- a/src/network/access/qnetworkaccessftpbackend.cpp
+++ b/src/network/access/qnetworkaccessftpbackend.cpp
@@ -179,11 +179,7 @@ void QNetworkAccessFtpBackend::closeDownstreamChannel()
 {
     state = Disconnecting;
     if (operation() == QNetworkAccessManager::GetOperation)
-#ifndef Q_OS_WINCE
-        abort();
-#else
-        exit(3);
-#endif
+        ftp->abort();
 }
 
 void QNetworkAccessFtpBackend::downstreamReadyWrite()
diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
index 866afbf0a5e..61f44c5c09f 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -392,6 +392,9 @@ private Q_SLOTS:
     void synchronousAuthenticationCache();
     void pipelining();
 
+    void closeDuringDownload_data();
+    void closeDuringDownload();
+
     // NOTE: This test must be last!
     void parentingRepliesToTheApp();
 };
@@ -6736,6 +6739,27 @@ void tst_QNetworkReply::pipeliningHelperSlot() {
     }
 }
 
+void tst_QNetworkReply::closeDuringDownload_data()
+{
+    QTest::addColumn("url");
+    QTest::newRow("http") << QUrl("http://" + QtNetworkSettings::serverName() + "/bigfile");
+    QTest::newRow("ftp") << QUrl("ftp://" + QtNetworkSettings::serverName() + "/qtest/bigfile");
+}
+
+void tst_QNetworkReply::closeDuringDownload()
+{
+    QFETCH(QUrl, url);
+    QNetworkRequest request(url);
+    QNetworkReply* reply = manager.get(request);
+    connect(reply, SIGNAL(readyRead()), &QTestEventLoop::instance(), SLOT(exitLoop()));
+    QTestEventLoop::instance().enterLoop(10);
+    QVERIFY(!QTestEventLoop::instance().timeout());
+    connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
+    reply->close();
+    reply->deleteLater();
+    QTest::qWait(1000); //cancelling ftp takes some time, this avoids a warning caused by test's cleanup() destroying the connection cache before the abort is finished
+}
+
 // NOTE: This test must be last testcase in tst_qnetworkreply!
 void tst_QNetworkReply::parentingRepliesToTheApp()
 {

From be0dfa34737a014e7ad060a90c4c24be9998fe13 Mon Sep 17 00:00:00 2001
From: Eskil Abrahamsen Blomfeldt 
Date: Tue, 14 Feb 2012 13:01:23 +0100
Subject: [PATCH 218/406] Optimize memory consumption for simple GPOS tables

Sometimes GPOS tables are used for kerning and can grow quite
large if the font is unoptimized. In that case, allocating the
maximum size for each ValueRecord will have a great impact on
memory consumption. For GPOS tables which do not contain device
tables, we only allocate the memory actually need to store the
data instead.

While it would be possible to optimize memory for GPOS tables that
contain device tables as well, this is not a part of this patch.

Change-Id: Id665b2821675ef955c497c782f09f99af765b8a3
Reviewed-by: Lars Knoll 
---
 .../harfbuzz/src/harfbuzz-gpos-private.h      |  10 +-
 src/3rdparty/harfbuzz/src/harfbuzz-gpos.c     | 203 +++++++++++++-----
 2 files changed, 163 insertions(+), 50 deletions(-)

diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-gpos-private.h b/src/3rdparty/harfbuzz/src/harfbuzz-gpos-private.h
index 63ba90797d1..b363b81d874 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-gpos-private.h
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-gpos-private.h
@@ -39,6 +39,10 @@ HB_BEGIN_HEADER
 #define VR_X_ADVANCE_DEVICE   2
 #define VR_Y_ADVANCE_DEVICE   3
 
+#ifndef HB_SUPPORT_MULTIPLE_MASTER
+#  define HB_USE_FLEXIBLE_VALUE_RECORD
+#endif
+
 struct  HB_ValueRecord_
 {
   HB_Short    XPlacement;             /* horizontal adjustment for
@@ -242,7 +246,11 @@ typedef struct HB_Class2Record_  HB_Class2Record;
 
 struct  HB_Class1Record_
 {
-  HB_Class2Record*  Class2Record;    /* array of Class2Record tables */
+  hb_uint8 IsFlexible;
+  union {
+    HB_Class2Record*  Class2Record;    /* array of Class2Record tables */
+    HB_Short* ValueRecords;
+  } c2r;
 };
 
 typedef struct HB_Class1Record_  HB_Class1Record;
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-gpos.c b/src/3rdparty/harfbuzz/src/harfbuzz-gpos.c
index a21600579e5..2a86cb21e91 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-gpos.c
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-gpos.c
@@ -194,6 +194,43 @@ HB_Error  HB_Done_GPOS_Table( HB_GPOSHeader* gpos )
 
 /* ValueRecord */
 
+static HB_Error  Get_FlexibleValueRecord( GPOS_Instance*   gpi,
+                                          HB_Short*        vr,
+                                          HB_UShort        format,
+                                          HB_Position      gd )
+{
+  HB_Error         error = HB_Err_Ok;
+
+  HB_16Dot16   x_scale, y_scale;
+
+  if ( !format )
+    return HB_Err_Ok;
+
+  x_scale = gpi->font->x_scale;
+  y_scale = gpi->font->y_scale;
+
+  /* design units -> fractional pixel */
+
+  if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT ) {
+    gd->x_pos += *vr * x_scale / 0x10000;
+    vr++;
+  }
+  if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT ) {
+    gd->y_pos += *vr * y_scale / 0x10000;
+    vr++;
+  }
+  if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE ) {
+    gd->x_advance += *vr * x_scale / 0x10000;
+    vr++;
+  }
+  if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE ) {
+    gd->y_advance += *vr * y_scale  / 0x10000;
+    vr++;
+  }
+
+  return error;
+}
+
 /* There is a subtle difference in the specs between a `table' and a
    `record' -- offsets for device tables in ValueRecords are taken from
    the parent table and not the parent record.                          */
@@ -1245,6 +1282,19 @@ static void  Free_PairPos1( HB_PairPosFormat1*  ppf1,
   }
 }
 
+static HB_UInt Calculate_Class2RecordSize(HB_UShort format1, HB_UShort format2)
+{
+    // Return number of 16 bit values in two value records with given formats
+    return  (format1 & 0x01)       +  (format2 & 0x01)
+         + ((format1 & 0x02) >> 1) + ((format2 & 0x02) >> 1)
+         + ((format1 & 0x04) >> 2) + ((format2 & 0x04) >> 2)
+         + ((format1 & 0x08) >> 3) + ((format2 & 0x08) >> 3)
+         + ((format1 & 0x10) >> 4) + ((format2 & 0x10) >> 4)
+         + ((format1 & 0x20) >> 5) + ((format2 & 0x20) >> 5)
+         + ((format1 & 0x40) >> 6) + ((format2 & 0x40) >> 6)
+         + ((format1 & 0x80) >> 7) + ((format2 & 0x80) >> 7);
+}
+
 
 /* PairPosFormat2 */
 
@@ -1256,11 +1306,14 @@ static HB_Error  Load_PairPos2( HB_PairPosFormat2*  ppf2,
   HB_Error  error;
 
   HB_UShort          m, n, k, count1, count2;
-  HB_UInt           cur_offset, new_offset1, new_offset2, base_offset;
+  HB_UInt           cur_offset, new_offset1, new_offset2, base_offset, cls2_record_size = 0;
 
   HB_Class1Record*  c1r;
   HB_Class2Record*  c2r;
 
+  HB_Short* vr;
+
+  hb_uint8 use_flexible_value_records;
 
   base_offset = FILE_Pos() - 8L;
 
@@ -1276,6 +1329,13 @@ static HB_Error  Load_PairPos2( HB_PairPosFormat2*  ppf2,
   count1 = ppf2->Class1Count = GET_UShort();
   count2 = ppf2->Class2Count = GET_UShort();
 
+#ifndef HB_USE_FLEXIBLE_VALUE_RECORD
+  use_flexible_value_records = 0;
+#else
+  use_flexible_value_records = !((format1 & HB_GPOS_FORMAT_HAVE_DEVICE_TABLES) ||
+                                 (format2 & HB_GPOS_FORMAT_HAVE_DEVICE_TABLES));
+#endif
+
   FORGET_Frame();
 
   cur_offset = FILE_Pos();
@@ -1296,35 +1356,55 @@ static HB_Error  Load_PairPos2( HB_PairPosFormat2*  ppf2,
 
   c1r = ppf2->Class1Record;
 
+  if ( use_flexible_value_records )
+    cls2_record_size = Calculate_Class2RecordSize(format1, format2);
+
   for ( m = 0; m < count1; m++ )
   {
-    c1r[m].Class2Record = NULL;
+    c1r[m].IsFlexible = use_flexible_value_records;
+    if ( use_flexible_value_records ) {
+        c1r[m].c2r.ValueRecords = NULL;
 
-    if ( ALLOC_ARRAY( c1r[m].Class2Record, count2, HB_Class2Record ) )
-      goto Fail1;
+        if ( ALLOC_ARRAY( c1r[m].c2r.ValueRecords, count2 * cls2_record_size, HB_UShort ) )
+          goto Fail1;
 
-    c2r = c1r[m].Class2Record;
+        vr = c1r[m].c2r.ValueRecords;
 
-    for ( n = 0; n < count2; n++ )
-    {
-      if ( format1 )
-      {
-	error = Load_ValueRecord( &c2r[n].Value1, format1,
-				  base_offset, stream );
-	if ( error )
-	  goto Fail0;
-      }
-      if ( format2 )
-      {
-	error = Load_ValueRecord( &c2r[n].Value2, format2,
-				  base_offset, stream );
-	if ( error )
-	{
-	  if ( format1 )
-	    Free_ValueRecord( &c2r[n].Value1, format1 );
-	  goto Fail0;
-	}
-      }
+        if ( ACCESS_Frame( count2 * cls2_record_size * 2L ))
+            goto Fail1;
+
+        for ( n = 0; n < count2 * cls2_record_size; n++ )
+            vr[n] = GET_Short();
+
+        FORGET_Frame();
+    } else {
+        c1r[m].c2r.Class2Record = NULL;
+
+        if ( ALLOC_ARRAY( c1r[m].c2r.Class2Record, count2, HB_Class2Record ) )
+          goto Fail1;
+
+        c2r = c1r[m].c2r.Class2Record;
+        for ( n = 0; n < count2; n++ )
+        {
+            if ( format1 )
+            {
+                error = Load_ValueRecord( &c2r[n].Value1, format1,
+                                          base_offset, stream );
+                if ( error )
+                    goto Fail0;
+            }
+            if ( format2 )
+            {
+                error = Load_ValueRecord( &c2r[n].Value2, format2,
+                                          base_offset, stream );
+                if ( error )
+                {
+                    if ( format1 )
+                        Free_ValueRecord( &c2r[n].Value1, format1 );
+                    goto Fail0;
+                }
+            }
+        }
     }
 
     continue;
@@ -1345,17 +1425,21 @@ static HB_Error  Load_PairPos2( HB_PairPosFormat2*  ppf2,
 Fail1:
   for ( k = 0; k < m; k++ )
   {
-    c2r = c1r[k].Class2Record;
+      if ( !use_flexible_value_records ) {
+        c2r = c1r[k].c2r.Class2Record;
 
-    for ( n = 0; n < count2; n++ )
-    {
-      if ( format1 )
-	Free_ValueRecord( &c2r[n].Value1, format1 );
-      if ( format2 )
-	Free_ValueRecord( &c2r[n].Value2, format2 );
-    }
+        for ( n = 0; n < count2; n++ )
+        {
+          if ( format1 )
+        Free_ValueRecord( &c2r[n].Value1, format1 );
+          if ( format2 )
+        Free_ValueRecord( &c2r[n].Value2, format2 );
+        }
 
-    FREE( c2r );
+        FREE( c2r );
+      } else {
+          FREE( c1r[k].c2r.ValueRecords );
+      }
   }
 
   FREE( c1r );
@@ -1387,17 +1471,21 @@ static void  Free_PairPos2( HB_PairPosFormat2*  ppf2,
 
     for ( m = 0; m < count1; m++ )
     {
-      c2r = c1r[m].Class2Record;
+        if ( !c1r[m].IsFlexible ) {
+            c2r = c1r[m].c2r.Class2Record;
 
-      for ( n = 0; n < count2; n++ )
-      {
-	if ( format1 )
-	  Free_ValueRecord( &c2r[n].Value1, format1 );
-	if ( format2 )
-	  Free_ValueRecord( &c2r[n].Value2, format2 );
-      }
+            for ( n = 0; n < count2; n++ )
+            {
+                if ( format1 )
+                    Free_ValueRecord( &c2r[n].Value1, format1 );
+                if ( format2 )
+                    Free_ValueRecord( &c2r[n].Value2, format2 );
+            }
 
-      FREE( c2r );
+            FREE( c2r );
+        } else {
+            FREE( c1r[m].c2r.ValueRecords );
+        }
     }
 
     FREE( c1r );
@@ -1544,6 +1632,10 @@ static HB_Error  Lookup_PairPos2( GPOS_Instance*       gpi,
 
   HB_Class1Record*  c1r;
   HB_Class2Record*  c2r;
+  HB_Short*         vr;
+
+  HB_UShort         vr1_size;
+  HB_UShort         vr2_size;
 
 
   error = _HB_OPEN_Get_Class( &ppf2->ClassDef1, IN_GLYPH( first_pos ),
@@ -1558,15 +1650,28 @@ static HB_Error  Lookup_PairPos2( GPOS_Instance*       gpi,
   c1r = &ppf2->Class1Record[cl1];
   if ( !c1r )
     return ERR(HB_Err_Invalid_SubTable);
-  c2r = &c1r->Class2Record[cl2];
 
-  error = Get_ValueRecord( gpi, &c2r->Value1, format1, POSITION( first_pos ) );
-  if ( error )
-    return error;
-  return Get_ValueRecord( gpi, &c2r->Value2, format2, POSITION( buffer->in_pos ) );
+  if ( !c1r->IsFlexible ) {
+      c2r = &c1r->c2r.Class2Record[cl2];
+
+      error = Get_ValueRecord( gpi, &c2r->Value1, format1, POSITION( first_pos ) );
+      if ( error )
+          return error;
+      return Get_ValueRecord( gpi, &c2r->Value2, format2, POSITION( buffer->in_pos ) );
+  } else {
+      vr1_size = Calculate_Class2RecordSize( format1, 0 );
+      vr2_size = Calculate_Class2RecordSize( format2, 0 );
+
+      vr = c1r->c2r.ValueRecords + (cl2 * ( vr1_size + vr2_size ));
+
+      error = Get_FlexibleValueRecord( gpi, vr, format1, POSITION( first_pos ) );
+      if ( error )
+          return error;
+      vr += vr1_size; // Skip to second record
+      return Get_FlexibleValueRecord( gpi, vr, format2, POSITION( buffer->in_pos ) );
+  }
 }
 
-
 static HB_Error  Lookup_PairPos( GPOS_Instance*    gpi,
 				 HB_GPOS_SubTable* st,
 				 HB_Buffer        buffer,

From c7d3f9be585b5aa4d0d53350a0a23f68ddd3c22f Mon Sep 17 00:00:00 2001
From: Alex Wilson 
Date: Tue, 14 Feb 2012 13:25:26 +1000
Subject: [PATCH 219/406] Produce unimplemented warning for QOpenGLBuffer::map
 only once
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Change-Id: Ia4f136e964e4e0ca326f462b0996ef3d1b843cf6
Reviewed-by: Samuel Rødal 
---
 src/gui/opengl/qopenglbuffer.cpp | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/gui/opengl/qopenglbuffer.cpp b/src/gui/opengl/qopenglbuffer.cpp
index e0ab98df210..e6879a9e602 100644
--- a/src/gui/opengl/qopenglbuffer.cpp
+++ b/src/gui/opengl/qopenglbuffer.cpp
@@ -529,7 +529,11 @@ void *QOpenGLBuffer::map(QOpenGLBuffer::Access access)
     return glMapBufferARB(d->type, access);
 #endif
     Q_UNUSED(access);
-    qWarning("QOpenGLBuffer::map(): pending implementation");
+    static bool warned = false;
+    if (!warned) {
+        qWarning("QOpenGLBuffer::map(): pending implementation");
+        warned = true;
+    }
     return 0;
 }
 
@@ -560,7 +564,11 @@ bool QOpenGLBuffer::unmap()
         return false;
     return glUnmapBufferARB(d->type) == GL_TRUE;
 #endif
-    qWarning("QOpenGLBuffer::map(): pending implementation");
+    static bool warned = false;
+    if (!warned) {
+        qWarning("QOpenGLBuffer::map(): pending implementation");
+        warned = true;
+    }
     return 0;
 }
 

From fc8f92106d6743d4165de7d8a440b7e5dbd14391 Mon Sep 17 00:00:00 2001
From: Miikka Heikkinen 
Date: Tue, 14 Feb 2012 15:47:27 +0200
Subject: [PATCH 220/406] Remove fileLineEndingTest from networkselftest.

The fileLineEndingTest case doesn't test network in any way and it is
conceptually wrong, too, as any tests where line endings are an issue
should be handled with .gitattributes rather than forcing user to
check out the repo with unix line endings.

Task-number: QTBUG-24271
Change-Id: I73986993edc227cb68b8f61d51cc1cf458d20989
Reviewed-by: Shane Kearns 
---
 .../networkselftest/tst_networkselftest.cpp   | 26 -------------------
 1 file changed, 26 deletions(-)

diff --git a/tests/auto/other/networkselftest/tst_networkselftest.cpp b/tests/auto/other/networkselftest/tst_networkselftest.cpp
index c1a3cd17d21..99d4ac9522e 100644
--- a/tests/auto/other/networkselftest/tst_networkselftest.cpp
+++ b/tests/auto/other/networkselftest/tst_networkselftest.cpp
@@ -70,7 +70,6 @@ private slots:
     void serverReachability();
     void remotePortsOpen_data();
     void remotePortsOpen();
-    void fileLineEndingTest();
 
     // specific protocol tests
     void ftpServer();
@@ -458,31 +457,6 @@ void tst_NetworkSelfTest::remotePortsOpen()
     QVERIFY(socket.state() == QAbstractSocket::ConnectedState);
 }
 
-
-void tst_NetworkSelfTest::fileLineEndingTest()
-{
-    QString referenceName = SRCDIR "/rfc3252.txt";
-    long long expectedReferenceSize = 25962;
-
-    QString lineEndingType("LF");
-
-    QFile reference(referenceName);
-    QVERIFY(reference.open(QIODevice::ReadOnly));
-    QByteArray byteLine = reference.readLine();
-    if(byteLine.endsWith("\r\n"))
-        lineEndingType = "CRLF";
-    else if(byteLine.endsWith("\r"))
-        lineEndingType = "CR";
-
-    QString referenceAsTextData;
-    QFile referenceAsText(referenceName);
-    QVERIFY(referenceAsText.open(QIODevice::ReadOnly));
-    referenceAsTextData = referenceAsText.readAll();
-
-    QVERIFY2(expectedReferenceSize == referenceAsTextData.length(), QString("Reference file %1 has %2 as line ending and file size not matching - Git checkout issue !?!").arg(referenceName, lineEndingType).toLocal8Bit());
-    QVERIFY2(!lineEndingType.compare("LF"), QString("Reference file %1 has %2 as line ending - Git checkout issue !?!").arg(referenceName, lineEndingType).toLocal8Bit());
-}
-
 static QList ftpChat(const QByteArray &userSuffix = QByteArray())
 {
     QList rv;

From 980947122307797e1d8da03f768d8f14a360d20b Mon Sep 17 00:00:00 2001
From: Andrew Stanley-Jones 
Date: Thu, 9 Feb 2012 15:51:22 +0100
Subject: [PATCH 221/406] Allow the QLocalServer to listen to a native
 descriptor

QLocalServer could only listen to sockets it created.
Thi is not always possible as sockets may be passed
by socketpair() or have to be created locally by
other means.  This adds a similar feature to QLocalSocket
where a native descriptor maybe used.

Change-Id: I43b0af179b3b868dd164d4e1fd312ff4546cf9ff
Reviewed-by: Michalina Ziemba 
Reviewed-by: Tapani Mikola 
Reviewed-by: Harald Fernengel 
---
 src/network/socket/qlocalserver.cpp           |  34 ++++++
 src/network/socket/qlocalserver.h             |   1 +
 src/network/socket/qlocalserver_p.h           |   1 +
 src/network/socket/qlocalserver_tcp.cpp       |   7 ++
 src/network/socket/qlocalserver_unix.cpp      |  42 +++++++
 src/network/socket/qlocalserver_win.cpp       |   6 +
 .../socket/qlocalsocket/tst_qlocalsocket.cpp  | 104 +++++++++++++++++-
 7 files changed, 191 insertions(+), 4 deletions(-)

diff --git a/src/network/socket/qlocalserver.cpp b/src/network/socket/qlocalserver.cpp
index 97f5920171e..05f26883d37 100644
--- a/src/network/socket/qlocalserver.cpp
+++ b/src/network/socket/qlocalserver.cpp
@@ -298,6 +298,40 @@ bool QLocalServer::listen(const QString &name)
     return true;
 }
 
+/*!
+    \since 5.0
+
+    Instructs the server to listen for incoming connections on
+    \a socketDescriptor. The property returns \c false if the server is
+    currently listening. It returns \c true on success; otherwise,
+    it returns \c false. The socket must be ready to accept
+    new connections with no extra platform-specific functions
+    called. The socket is set into non-blocking mode.
+
+    serverName(), fullServerName() may return a string with
+    a name if this option is supported by the platform;
+    otherwise, they return an empty QString.
+
+    \sa isListening(), close()
+ */
+bool QLocalServer::listen(qintptr socketDescriptor)
+{
+    Q_D(QLocalServer);
+    if (isListening()) {
+        qWarning("QLocalServer::listen() called when already listening");
+        return false;
+    }
+
+    d->serverName.clear();
+    d->fullServerName.clear();
+
+    if (!d->listen(socketDescriptor)) {
+        return false;
+    }
+
+    return true;
+}
+
 /*!
     Returns the maximum number of pending accepted connections.
     The default is 30.
diff --git a/src/network/socket/qlocalserver.h b/src/network/socket/qlocalserver.h
index 6f883adc24c..291122e10de 100644
--- a/src/network/socket/qlocalserver.h
+++ b/src/network/socket/qlocalserver.h
@@ -82,6 +82,7 @@ public:
     virtual bool hasPendingConnections() const;
     bool isListening() const;
     bool listen(const QString &name);
+    bool listen(qintptr socketDescriptor);
     int maxPendingConnections() const;
     virtual QLocalSocket *nextPendingConnection();
     QString serverName() const;
diff --git a/src/network/socket/qlocalserver_p.h b/src/network/socket/qlocalserver_p.h
index 03c06a42e3b..84081159c76 100644
--- a/src/network/socket/qlocalserver_p.h
+++ b/src/network/socket/qlocalserver_p.h
@@ -87,6 +87,7 @@ public:
 
     void init();
     bool listen(const QString &name);
+    bool listen(qintptr socketDescriptor);
     static bool removeServer(const QString &name);
     void closeServer();
     void waitForNewConnection(int msec, bool *timedOut);
diff --git a/src/network/socket/qlocalserver_tcp.cpp b/src/network/socket/qlocalserver_tcp.cpp
index d6c6a1af920..9ac1bfaf0eb 100644
--- a/src/network/socket/qlocalserver_tcp.cpp
+++ b/src/network/socket/qlocalserver_tcp.cpp
@@ -78,6 +78,13 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName)
     return true;
 }
 
+bool QLocalServerPrivate::listen(qintptr socketDescriptor)
+{
+    Q_Q(QLocalServer);
+
+    return tcpServer.setSocketDescriptor(socketDescriptor);
+}
+
 void QLocalServerPrivate::closeServer()
 {
     QSettings settings(QLatin1String("Trolltech"), QLatin1String("Qt"));
diff --git a/src/network/socket/qlocalserver_unix.cpp b/src/network/socket/qlocalserver_unix.cpp
index ce0c283f0b4..0c2edef578e 100644
--- a/src/network/socket/qlocalserver_unix.cpp
+++ b/src/network/socket/qlocalserver_unix.cpp
@@ -203,6 +203,48 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName)
     return true;
 }
 
+bool QLocalServerPrivate::listen(qintptr socketDescriptor)
+{
+    Q_Q(QLocalServer);
+
+    // Attach to the localsocket
+    listenSocket = socketDescriptor;
+
+    ::fcntl(listenSocket, F_SETFD, FD_CLOEXEC);
+    ::fcntl(listenSocket, F_SETFL, ::fcntl(listenSocket, F_GETFL) | O_NONBLOCK);
+
+#ifdef Q_OS_LINUX
+    struct ::sockaddr_un addr;
+    socklen_t len;
+    memset(&addr, 0, sizeof(addr));
+    if (0 == ::getsockname(listenSocket, (sockaddr *)&addr, &len)) {
+        // check for absract sockets
+        if (addr.sun_family == PF_UNIX && addr.sun_path[0] == 0) {
+            addr.sun_path[0] = '@';
+        }
+        QString name = QString::fromLatin1(addr.sun_path);
+        if (!name.isEmpty()) {
+            fullServerName = name;
+            serverName = fullServerName.mid(fullServerName.lastIndexOf(QLatin1String("/"))+1);
+            if (serverName.isEmpty()) {
+                serverName = fullServerName;
+            }
+        }
+    }
+#else
+    serverName.clear();
+    fullServerName.clear();
+#endif
+
+    Q_ASSERT(!socketNotifier);
+    socketNotifier = new QSocketNotifier(listenSocket,
+                                         QSocketNotifier::Read, q);
+    q->connect(socketNotifier, SIGNAL(activated(int)),
+               q, SLOT(_q_onNewConnection()));
+    socketNotifier->setEnabled(maxPendingConnections > 0);
+    return true;
+}
+
 /*!
     \internal
 
diff --git a/src/network/socket/qlocalserver_win.cpp b/src/network/socket/qlocalserver_win.cpp
index 67e319cdbba..07357e57897 100644
--- a/src/network/socket/qlocalserver_win.cpp
+++ b/src/network/socket/qlocalserver_win.cpp
@@ -144,6 +144,12 @@ bool QLocalServerPrivate::listen(const QString &name)
     return true;
 }
 
+bool QLocalServerPrivate::listen(qintptr)
+{
+    qWarning("QLocalServer::listen(qintptr) is not supported on Windows QTBUG-24230");
+    return false;
+}
+
 void QLocalServerPrivate::_q_onNewConnection()
 {
     Q_Q(QLocalServer);
diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
index 03b95bfa2fd..72fa9f74a4b 100644
--- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
+++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
@@ -46,6 +46,12 @@
 #include 
 #include 
 
+#ifdef Q_OS_UNIX
+#include 
+#include 
+#include 
+#endif
+
 Q_DECLARE_METATYPE(QLocalSocket::LocalSocketError)
 Q_DECLARE_METATYPE(QLocalSocket::LocalSocketState)
 Q_DECLARE_METATYPE(QLocalServer::SocketOption)
@@ -109,6 +115,10 @@ private slots:
 
     void verifySocketOptions();
     void verifySocketOptions_data();
+
+    void verifyListenWithDescriptor();
+    void verifyListenWithDescriptor_data();
+
 };
 
 void tst_QLocalSocket::init()
@@ -1026,19 +1036,19 @@ void tst_QLocalSocket::verifySocketOptions_data()
 
     QFile::Permissions p = QFile::ExeOwner|QFile::WriteOwner|QFile::ReadOwner |
                            QFile::ExeUser|QFile::WriteUser|QFile::ReadUser;
-    QTest::newRow("user")  << "userPerms"  << QLocalServer::UserAccess << p;
+    QTest::newRow("user")  << "userPerms"  << QLocalServer::UserAccessOption << p;
 
     p = QFile::ExeGroup|QFile::WriteGroup|QFile::ReadGroup;
-    QTest::newRow("group") << "groupPerms" << QLocalServer::GroupAccess << p;
+    QTest::newRow("group") << "groupPerms" << QLocalServer::GroupAccessOption << p;
 
     p = QFile::ExeOther|QFile::WriteOther|QFile::ReadOther;
-    QTest::newRow("other") << "otherPerms" << QLocalServer::OtherAccess << p;
+    QTest::newRow("other") << "otherPerms" << QLocalServer::OtherAccessOption << p;
 
     p = QFile::ExeOwner|QFile::WriteOwner|QFile::ReadOwner|
         QFile::ExeUser|QFile::WriteUser|QFile::ReadUser |
         QFile::ExeGroup|QFile::WriteGroup|QFile::ReadGroup|
         QFile::ExeOther|QFile::WriteOther|QFile::ReadOther;
-    QTest::newRow("all")   << "worldPerms" << QLocalServer::WorldAccess << p;
+    QTest::newRow("all")   << "worldPerms" << QLocalServer::WorldAccessOption << p;
 #endif
 }
 
@@ -1065,6 +1075,92 @@ void tst_QLocalSocket::verifySocketOptions()
 #endif
 }
 
+void tst_QLocalSocket::verifyListenWithDescriptor()
+{
+#ifdef Q_OS_UNIX
+    QFETCH(QString, path);
+    QFETCH(bool, abstract);
+    QFETCH(bool, bound);
+
+    qDebug() << "socket" << path << abstract;
+
+    int listenSocket;
+
+    if (bound) {
+        // create the unix socket
+        listenSocket = ::socket(PF_UNIX, SOCK_STREAM, 0);
+        QVERIFY2(listenSocket != -1, "failed to create test socket");
+
+        // Construct the unix address
+        struct ::sockaddr_un addr;
+        addr.sun_family = PF_UNIX;
+
+        QVERIFY2(sizeof(addr.sun_path) > ((uint)path.size() + 1), "path to large to create socket");
+
+        ::memset(addr.sun_path, 0, sizeof(addr.sun_path));
+        if (abstract)
+            ::memcpy(addr.sun_path+1, path.toLatin1().data(), path.toLatin1().size());
+        else
+            ::memcpy(addr.sun_path, path.toLatin1().data(), path.toLatin1().size());
+
+        if (path.startsWith(QLatin1Char('/'))) {
+            ::unlink(path.toLatin1());
+        }
+
+        QVERIFY2(-1 != ::bind(listenSocket, (sockaddr *)&addr, sizeof(sockaddr_un)), "failed to bind test socket to address");
+
+        // listen for connections
+        QVERIFY2(-1 != ::listen(listenSocket, 50), "failed to call listen on test socket");
+    } else {
+        int fds[2];
+        QVERIFY2(-1 != ::socketpair(PF_UNIX, SOCK_STREAM, 0, fds), "failed to create socket pair");
+
+        listenSocket = fds[0];
+        close(fds[1]);
+    }
+
+    QLocalServer server;
+    QVERIFY2(server.listen(listenSocket), "failed to start create QLocalServer with local socket");
+
+#ifdef Q_OS_LINUX
+    if (!bound) {
+        QVERIFY(server.serverName().at(0) == QLatin1Char('@'));
+        QVERIFY(server.fullServerName().at(0) == QLatin1Char('@'));
+    } else if (abstract) {
+        QVERIFY2(server.fullServerName().at(0) == QLatin1Char('@'), "abstract sockets should start with a '@'");
+    } else {
+        QVERIFY2(server.fullServerName() == path, "full server path doesn't match patch provided");
+        if (path.contains(QLatin1String("/"))) {
+            QVERIFY2(server.serverName() == path.mid(path.lastIndexOf(QLatin1Char('/'))+1), "server name invalid short name");
+        } else {
+            QVERIFY2(server.serverName() == path, "servier name doesn't match the path provided");
+        }
+    }
+#else
+    QVERIFY(server.serverName().isEmpty());
+    QVERIFY(server.fullServerName().isEmpty());
+#endif
+
+
+#endif
+}
+
+void tst_QLocalSocket::verifyListenWithDescriptor_data()
+{
+#ifdef Q_OS_UNIX
+    QTest::addColumn("path");
+    QTest::addColumn("abstract");
+    QTest::addColumn("bound");
+
+    QTest::newRow("normal") << QDir::tempPath() + QLatin1Literal("/testsocket") << false << true;
+    QTest::newRow("absrtact") << QString::fromLatin1("abstractsocketname") << true << true;
+    QTest::newRow("abstractwithslash") << QString::fromLatin1("abstractsocketwitha/inthename") << true << true;
+    QTest::newRow("no path") << QString::fromLatin1("/invalid/no path name speficied") << true << false;
+
+#endif
+
+}
+
 QTEST_MAIN(tst_QLocalSocket)
 #include "tst_qlocalsocket.moc"
 

From 2ecdb8c091cbfdc2b4f81c90828fb61b96c565fe Mon Sep 17 00:00:00 2001
From: Mark Brand 
Date: Thu, 9 Feb 2012 14:53:35 +0100
Subject: [PATCH 222/406] QSql*Model: make indexInQuery() virtual

Qt 5 seems like an excellent opportunity to simplify logic and separate
concerns by making indexInQuery() virtual. Note that this wasn't my
idea, but was mentioned in a helpful comment.

Change-Id: Ie29ead110def45297c32de3ce6d07a8eefb08d8c
Reviewed-by: Yunqiao Yin 
---
 dist/changes-5.0.0                |  6 ++++++
 src/sql/models/qsqlquerymodel.h   |  2 +-
 src/sql/models/qsqltablemodel.cpp | 26 +++++++++-----------------
 3 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0
index bb4ceef0d09..884c3083fcd 100644
--- a/dist/changes-5.0.0
+++ b/dist/changes-5.0.0
@@ -213,6 +213,8 @@ information about a particular change.
 
 - QSystemLocale has been removed from the public API.
 
+- QSqlQueryModel::indexInQuery() is now virtual. See note below under QSql.
+
 ****************************************************************************
 *                           General                                        *
 ****************************************************************************
@@ -368,6 +370,10 @@ ignore the rest of the range.
   -For OnManualSubmit, insertRecord() no longer leaves behind an empty
   row if setRecord() fails.
 
+* QSqlQueryModel::indexInQuery() is now virtual. See
+QSqlTableModel::indexInQuery() as example of how to implement in a
+subclass.
+
 ****************************************************************************
 *                          Database Drivers                                *
 ****************************************************************************
diff --git a/src/sql/models/qsqlquerymodel.h b/src/sql/models/qsqlquerymodel.h
index 7db973b0d42..b5e1a7a7468 100644
--- a/src/sql/models/qsqlquerymodel.h
+++ b/src/sql/models/qsqlquerymodel.h
@@ -92,7 +92,7 @@ public:
 protected:
     virtual void queryChange();
 
-    QModelIndex indexInQuery(const QModelIndex &item) const;
+    virtual QModelIndex indexInQuery(const QModelIndex &item) const;
     void setLastError(const QSqlError &error);
     QSqlQueryModel(QSqlQueryModelPrivate &dd, QObject *parent = 0);
 };
diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index 29f29bac0d0..ab87397da59 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -384,12 +384,6 @@ QVariant QSqlTableModel::data(const QModelIndex &index, int role) const
     if (!index.isValid() || (role != Qt::DisplayRole && role != Qt::EditRole))
         return QVariant();
 
-    // Problem.. we need to use QSQM::indexInQuery to handle inserted columns
-    // but inserted rows we need to handle
-    // and indexInQuery is not virtual (grrr) so any values we pass to QSQM need
-    // to handle the insertedRows
-    QModelIndex item = indexInQuery(index);
-
     if (d->cache.contains(index.row())) {
         const QSqlTableModelPrivate::ModifiedRow row = d->cache.value(index.row());
 
@@ -397,25 +391,24 @@ QVariant QSqlTableModel::data(const QModelIndex &index, int role) const
         case OnFieldChange:
         case OnRowChange:
             if (row.op() == QSqlTableModelPrivate::Insert) {
-                if (item.column() < 0 || item.column() >= row.rec().count())
+                if (index.column() < 0 || index.column() >= row.rec().count())
                     return QVariant();
-                return row.rec().value(item.column());
+                return row.rec().value(index.column());
             } else if (row.op() == QSqlTableModelPrivate::Update) {
-                if (row.rec().isGenerated(item.column()))
-                    return row.rec().value(item.column());
+                if (row.rec().isGenerated(index.column()))
+                    return row.rec().value(index.column());
             }
             break;
         case OnManualSubmit:
             if (row.op() == QSqlTableModelPrivate::Insert
                 || (row.op() != QSqlTableModelPrivate::None
-                    && row.rec().isGenerated(item.column())))
-                return row.rec().value(item.column());
+                    && row.rec().isGenerated(index.column())))
+                return row.rec().value(index.column());
             break;
         }
     }
 
-    // We need to handle row mapping here, but not column mapping
-    return QSqlQueryModel::data(index.sibling(item.row(), index.column()), role);
+    return QSqlQueryModel::data(index, role);
 }
 
 /*!
@@ -1122,15 +1115,14 @@ int QSqlTableModel::rowCount(const QModelIndex &parent) const
 QModelIndex QSqlTableModel::indexInQuery(const QModelIndex &item) const
 {
     Q_D(const QSqlTableModel);
-    const QModelIndex it = QSqlQueryModel::indexInQuery(item); // this adjusts columns only
     int rowOffset = 0;
     QSqlTableModelPrivate::CacheMap::ConstIterator i = d->cache.constBegin();
-    while (i != d->cache.constEnd() && i.key() <= it.row()) {
+    while (i != d->cache.constEnd() && i.key() <= item.row()) {
         if (i.value().op() == QSqlTableModelPrivate::Insert)
             ++rowOffset;
         ++i;
     }
-    return createIndex(it.row() - rowOffset, it.column(), it.internalPointer());
+    return QSqlQueryModel::indexInQuery(createIndex(item.row() - rowOffset, item.column(), item.internalPointer()));
 }
 
 /*!

From 76418628f14ff555242d7819e6cbcc6191c44360 Mon Sep 17 00:00:00 2001
From: Mark Brand 
Date: Thu, 9 Feb 2012 15:33:43 +0100
Subject: [PATCH 223/406] QSqlTableModel: deduplicate and optimize counting of
 inserts

Reading STL iteration code is painful enough if you only have
to do it once.
Thiago suggested remembering the end iterator for performance.

Change-Id: Ic2cdc480f591932ea420e692a4d2796d49f05313
Reviewed-by: Yunqiao Yin 
---
 src/sql/models/qsqltablemodel.cpp | 31 +++++++++++++++++--------------
 src/sql/models/qsqltablemodel_p.h |  1 +
 2 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index ab87397da59..51c717062db 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -79,6 +79,21 @@ QString QSqlTableModelPrivate::strippedFieldName(const QString &name) const
     return fieldname;
 }
 
+int QSqlTableModelPrivate::insertCount(int maxRow) const
+{
+    int cnt = 0;
+    CacheMap::ConstIterator i = cache.constBegin();
+    const CacheMap::ConstIterator e = cache.constEnd();
+    for (;
+         i != e && (maxRow < 0 || i.key() <= maxRow);
+         ++i) {
+        if (i.value().op() == Insert)
+            ++cnt;
+    }
+
+    return cnt;
+}
+
 void QSqlTableModelPrivate::initRecordAndPrimaryIndex()
 {
     rec = db.record(tableName);
@@ -1091,13 +1106,7 @@ int QSqlTableModel::rowCount(const QModelIndex &parent) const
     if (parent.isValid())
         return 0;
 
-    int rc = QSqlQueryModel::rowCount();
-    for (QSqlTableModelPrivate::CacheMap::ConstIterator it = d->cache.constBegin();
-         it != d->cache.constEnd(); ++it) {
-         if (it.value().op() == QSqlTableModelPrivate::Insert)
-             ++rc;
-    }
-    return rc;
+    return QSqlQueryModel::rowCount() + d->insertCount();
 }
 
 /*!
@@ -1115,13 +1124,7 @@ int QSqlTableModel::rowCount(const QModelIndex &parent) const
 QModelIndex QSqlTableModel::indexInQuery(const QModelIndex &item) const
 {
     Q_D(const QSqlTableModel);
-    int rowOffset = 0;
-    QSqlTableModelPrivate::CacheMap::ConstIterator i = d->cache.constBegin();
-    while (i != d->cache.constEnd() && i.key() <= item.row()) {
-        if (i.value().op() == QSqlTableModelPrivate::Insert)
-            ++rowOffset;
-        ++i;
-    }
+    const int rowOffset = d->insertCount(item.row());
     return QSqlQueryModel::indexInQuery(createIndex(item.row() - rowOffset, item.column(), item.internalPointer()));
 }
 
diff --git a/src/sql/models/qsqltablemodel_p.h b/src/sql/models/qsqltablemodel_p.h
index 8649a91e53b..c2e4442a6b2 100644
--- a/src/sql/models/qsqltablemodel_p.h
+++ b/src/sql/models/qsqltablemodel_p.h
@@ -79,6 +79,7 @@ public:
     virtual void revertCachedRow(int row);
     virtual int nameToIndex(const QString &name) const;
     QString strippedFieldName(const QString &name) const;
+    int insertCount(int maxRow = -1) const;
     void initRecordAndPrimaryIndex();
 
     QSqlDatabase db;

From 555aa4439b3a4a2c5fd12b6ac155b87fe69e749f Mon Sep 17 00:00:00 2001
From: Mark Brand 
Date: Fri, 10 Feb 2012 00:47:33 +0100
Subject: [PATCH 224/406] QSqlTableModel::commitAll(): replace row removal hack

The purpose of the hack was to fool QSqlQueryModel into signaling the
removal of extra rows via rowsRemoved(). The extra rows are the
inserted rows generated by QSqlTableModel.

While it is important to signal the removal of all the rows before
requerying after committing changes, there is a cleaner way. The
table model should remove its rows before the query model removes its
rows.

Iterating backwards avoids having to decrement row numbers above ones
being removed.

Expected test results have been adjusted for these changes.

Change-Id: I0e8aa81f5e7b8fea5922f5ffd1cfb4a932313a10
Reviewed-by: Yunqiao Yin 
---
 src/sql/models/qsqltablemodel.cpp                  | 14 +++++++++++++-
 .../models/qsqltablemodel/tst_qsqltablemodel.cpp   | 10 +++++++---
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index 51c717062db..cbb04964476 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -669,7 +669,6 @@ bool QSqlTableModel::submitAll()
         case QSqlTableModelPrivate::Insert:
             if (!insertRowIntoTable(it.value().rec()))
                 return false;
-            d->bottom = d->bottom.sibling(d->bottom.row() + 1, d->bottom.column());
             break;
         case QSqlTableModelPrivate::Update:
             if (!updateRowInTable(it.key(), it.value().rec()))
@@ -684,6 +683,19 @@ bool QSqlTableModel::submitAll()
             break;
         }
     }
+
+    // all changes have been committed
+
+    // clean up inserted rows
+    QSqlTableModelPrivate::CacheMap::Iterator it = d->cache.end();
+    while (it != d->cache.constBegin()) {
+        --it;
+        if (it.value().op()  == QSqlTableModelPrivate::Insert) {
+            beginRemoveRows(QModelIndex(), it.key(), it.key());
+            it = d->cache.erase(it);
+            endRemoveRows();
+        }
+    }
     d->clearCache();
     return select();
 }
diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
index c0bdfae8b76..270de8292b1 100644
--- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
+++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
@@ -1199,9 +1199,13 @@ void tst_QSqlTableModel::insertRecordsInLoop()
     model.submitAll(); // submitAll() calls select() which clears and repopulates the table
 
     int firstRowIndex = 0, lastRowIndex = 12;
-    QCOMPARE(spyRowsRemoved.count(), 1);
-    QCOMPARE(spyRowsRemoved.at(0).at(1).toInt(), firstRowIndex);
-    QCOMPARE(spyRowsRemoved.at(0).at(2).toInt(), lastRowIndex);
+    QCOMPARE(spyRowsRemoved.count(), 11);
+    // QSqlTableModel emits 10 signals for its 10 inserted rows
+    QCOMPARE(spyRowsRemoved.at(0).at(1).toInt(), lastRowIndex);
+    QCOMPARE(spyRowsRemoved.at(9).at(1).toInt(), firstRowIndex + 3);
+    // QSqlQueryModel emits 1 signal for its 3 rows
+    QCOMPARE(spyRowsRemoved.at(10).at(1).toInt(), firstRowIndex);
+    QCOMPARE(spyRowsRemoved.at(10).at(2).toInt(), firstRowIndex + 2);
 
     QCOMPARE(spyRowsInserted.at(10).at(1).toInt(), firstRowIndex);
     QCOMPARE(spyRowsInserted.at(10).at(2).toInt(), lastRowIndex);

From f805dd0b40c4b99b63e13e6e1bff08a63b76e0dd Mon Sep 17 00:00:00 2001
From: Mark Brand 
Date: Mon, 13 Feb 2012 09:57:56 +0100
Subject: [PATCH 225/406] QSqlTableModel::primaryValues(): take care of row
 mapping

There is no reason for the caller to be concerned with this.
primaryValues() now takes advantage of the fact that QSqlQueryModel
uses indexInQuery which was recently made virtual.

Change-Id: I7d856ee05f55c3199fd17c618e559320d0582989
Reviewed-by: Yunqiao Yin 
---
 src/sql/models/qsqltablemodel.cpp | 31 +++++++++++++------------------
 1 file changed, 13 insertions(+), 18 deletions(-)

diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index cbb04964476..457e7539a34 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -196,21 +196,16 @@ bool QSqlTableModelPrivate::exec(const QString &stmt, bool prepStatement,
 
 QSqlRecord QSqlTableModelPrivate::primaryValues(int row) const
 {
-    QSqlRecord record;
-    if (!query.seek(row)) {
-        error = query.lastError();
-        return record;
-    }
-    if (primaryIndex.isEmpty()) {
-        record = rec;
-        for (int i = 0; i < record.count(); ++i)
-            record.setValue(i, query.value(i));
-    } else {
-        record = primaryIndex;
-        for (int i = 0; i < record.count(); ++i)
-            record.setValue(i, query.value(rec.indexOf(record.fieldName(i))));
-    }
-    return record;
+    Q_Q(const QSqlTableModel);
+    if (cache.value(row).op() == Insert)
+        return QSqlRecord();
+
+    QSqlRecord values(primaryIndex.isEmpty() ? rec : primaryIndex);
+
+    for (int i = 0; i < values.count(); ++i)
+        values.setValue(i, q->QSqlQueryModel::data(createIndex(row, rec.indexOf(values.fieldName(i))), Qt::EditRole));
+
+    return values;
 }
 
 /*!
@@ -510,7 +505,7 @@ bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, in
     if (row.op() == QSqlTableModelPrivate::None) {
         row = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Update,
                                                  d->rec,
-                                                 d->primaryValues(indexInQuery(index).row()));
+                                                 d->primaryValues(index.row()));
     }
 
     row.setValue(index.column(), value);
@@ -1016,7 +1011,7 @@ bool QSqlTableModel::removeRows(int row, int count, const QModelIndex &parent)
         } else {
             d->cache[idx] = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Delete,
                                                                QSqlRecord(),
-                                                               d->primaryValues(indexInQuery(createIndex(idx, 0)).row()));
+                                                               d->primaryValues(idx));
             if (d->strategy == OnManualSubmit)
                 emit headerDataChanged(Qt::Vertical, idx, idx);
         }
@@ -1233,7 +1228,7 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record)
     if (mrow.op() == QSqlTableModelPrivate::None)
         mrow = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Update,
                                                   d->rec,
-                                                  d->primaryValues(indexInQuery(createIndex(row, 0)).row()));
+                                                  d->primaryValues(row));
 
     Map::const_iterator i = map.constBegin();
     const Map::const_iterator e = map.constEnd();

From 434c46e8dc838cec0d2a2193701c52cc78ba0862 Mon Sep 17 00:00:00 2001
From: Mark Brand 
Date: Fri, 10 Feb 2012 02:36:29 +0100
Subject: [PATCH 226/406] QSqlTableModel: do not store primaryValues in change
 cache

They can be generated on demand regardless of edit strategy.

Change-Id: I1e1853e93cc453f1486b65ce577f00141b9c5c47
Reviewed-by: Yunqiao Yin 
---
 src/sql/models/qsqltablemodel.cpp | 14 +++++---------
 src/sql/models/qsqltablemodel_p.h |  6 ++----
 2 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index 457e7539a34..12561ee189e 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -504,8 +504,7 @@ bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, in
 
     if (row.op() == QSqlTableModelPrivate::None) {
         row = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Update,
-                                                 d->rec,
-                                                 d->primaryValues(index.row()));
+                                                 d->rec);
     }
 
     row.setValue(index.column(), value);
@@ -551,7 +550,7 @@ bool QSqlTableModel::updateRowInTable(int row, const QSqlRecord &values)
     QSqlRecord rec(values);
     emit beforeUpdate(row, rec);
 
-    const QSqlRecord whereValues = d->strategy == OnManualSubmit ? d->cache[row].primaryValues() : d->primaryValues(row);
+    const QSqlRecord whereValues = d->primaryValues(row);
     bool prepStatement = d->db.driver()->hasFeature(QSqlDriver::PreparedQueries);
     QString stmt = d->db.driver()->sqlStatement(QSqlDriver::UpdateStatement, d->tableName,
                                                 rec, prepStatement);
@@ -618,7 +617,7 @@ bool QSqlTableModel::deleteRowFromTable(int row)
     Q_D(QSqlTableModel);
     emit beforeDelete(row);
 
-    const QSqlRecord whereValues = d->strategy == OnManualSubmit ? d->cache[row].primaryValues() : d->primaryValues(row);
+    const QSqlRecord whereValues = d->primaryValues(row);
     bool prepStatement = d->db.driver()->hasFeature(QSqlDriver::PreparedQueries);
     QString stmt = d->db.driver()->sqlStatement(QSqlDriver::DeleteStatement,
                                                 d->tableName,
@@ -1009,9 +1008,7 @@ bool QSqlTableModel::removeRows(int row, int count, const QModelIndex &parent)
             // so fake this by adjusting row
             --row;
         } else {
-            d->cache[idx] = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Delete,
-                                                               QSqlRecord(),
-                                                               d->primaryValues(idx));
+            d->cache[idx] = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Delete);
             if (d->strategy == OnManualSubmit)
                 emit headerDataChanged(Qt::Vertical, idx, idx);
         }
@@ -1227,8 +1224,7 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record)
     QSqlTableModelPrivate::ModifiedRow &mrow = d->cache[row];
     if (mrow.op() == QSqlTableModelPrivate::None)
         mrow = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Update,
-                                                  d->rec,
-                                                  d->primaryValues(row));
+                                                  d->rec);
 
     Map::const_iterator i = map.constBegin();
     const Map::const_iterator e = map.constEnd();
diff --git a/src/sql/models/qsqltablemodel_p.h b/src/sql/models/qsqltablemodel_p.h
index c2e4442a6b2..052f99005fa 100644
--- a/src/sql/models/qsqltablemodel_p.h
+++ b/src/sql/models/qsqltablemodel_p.h
@@ -100,8 +100,8 @@ public:
     class ModifiedRow
     {
     public:
-        inline ModifiedRow(Op o = None, const QSqlRecord &r = QSqlRecord(), const QSqlRecord &pVals = QSqlRecord())
-            : m_op(o), m_rec(r), m_primaryValues(pVals)
+        inline ModifiedRow(Op o = None, const QSqlRecord &r = QSqlRecord())
+            : m_op(o), m_rec(r)
         {
             for (int i = m_rec.count() - 1; i >= 0; --i)
                 m_rec.setGenerated(i, false);
@@ -109,7 +109,6 @@ public:
         inline Op op() const { return m_op; }
         inline QSqlRecord rec() const { return m_rec; }
         inline QSqlRecord& recRef() { return m_rec; }
-        inline QSqlRecord primaryValues() const { return m_primaryValues; }
         inline void setValue(int c, const QVariant &v)
         {
             m_rec.setValue(c, v);
@@ -118,7 +117,6 @@ public:
     private:
         Op m_op;
         QSqlRecord m_rec;
-        QSqlRecord m_primaryValues;
     };
 
     typedef QMap CacheMap;

From 7bced2878047840bb9bca58289fa1aa4119f034a Mon Sep 17 00:00:00 2001
From: Mark Brand 
Date: Fri, 10 Feb 2012 03:08:36 +0100
Subject: [PATCH 227/406] QSqlTableModel::submitAll(): avoid resubmiting
 successful changes

Consider what happens the 1st change succeeds and the 2nd fails. No
select will be done. When submitAll() is called again, the 1st will
still seem to be pending. It will fail or have unexpected effects if
the primary values were changed.

The solution is to avoid resubmitting successful changes. We leave
them in the cache so they stay visible. Submitted changes cannot
be reverted of course.

Change-Id: Ibf400555effa1c3801d02f8713b4b69856ede23a
Reviewed-by: Yunqiao Yin 
---
 src/sql/models/qsqltablemodel.cpp | 17 ++++++++++++++++-
 src/sql/models/qsqltablemodel_p.h |  5 ++++-
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index 12561ee189e..b21a965c212 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -121,6 +121,11 @@ void QSqlTableModelPrivate::revertCachedRow(int row)
 {
     Q_Q(QSqlTableModel);
     ModifiedRow r = cache.value(row);
+
+    // cannot revert a committed change
+    if (r.submitted())
+        return;
+
     switch (r.op()) {
     case QSqlTableModelPrivate::None:
         Q_ASSERT_X(false, "QSqlTableModelPrivate::revertCachedRow()", "Invalid entry in cache map");
@@ -373,6 +378,12 @@ bool QSqlTableModel::select()
     if (query.isEmpty())
         return false;
 
+    // clear the submitted flags so revertAll can do its job
+    for (QSqlTableModelPrivate::CacheMap::Iterator it = d->cache.begin();
+         it != d->cache.constEnd();
+         ++it)
+        it.value().setSubmitted(false);
+
     revertAll();
     QSqlQuery qu(query, d->db);
     setQuery(qu);
@@ -657,8 +668,11 @@ bool QSqlTableModel::submitAll()
 {
     Q_D(QSqlTableModel);
 
-    for (QSqlTableModelPrivate::CacheMap::ConstIterator it = d->cache.constBegin();
+    for (QSqlTableModelPrivate::CacheMap::Iterator it = d->cache.begin();
          it != d->cache.constEnd(); ++it) {
+        if (it.value().submitted())
+            continue;
+
         switch (it.value().op()) {
         case QSqlTableModelPrivate::Insert:
             if (!insertRowIntoTable(it.value().rec()))
@@ -676,6 +690,7 @@ bool QSqlTableModel::submitAll()
             Q_ASSERT_X(false, "QSqlTableModel::submitAll()", "Invalid cache operation");
             break;
         }
+        it.value().setSubmitted(true);
     }
 
     // all changes have been committed
diff --git a/src/sql/models/qsqltablemodel_p.h b/src/sql/models/qsqltablemodel_p.h
index 052f99005fa..0ae6b53742f 100644
--- a/src/sql/models/qsqltablemodel_p.h
+++ b/src/sql/models/qsqltablemodel_p.h
@@ -101,7 +101,7 @@ public:
     {
     public:
         inline ModifiedRow(Op o = None, const QSqlRecord &r = QSqlRecord())
-            : m_op(o), m_rec(r)
+            : m_op(o), m_rec(r), m_submitted(false)
         {
             for (int i = m_rec.count() - 1; i >= 0; --i)
                 m_rec.setGenerated(i, false);
@@ -114,9 +114,12 @@ public:
             m_rec.setValue(c, v);
             m_rec.setGenerated(c, true);
         }
+        inline bool submitted() const { return m_submitted; }
+        inline void setSubmitted(bool b) { m_submitted = b; }
     private:
         Op m_op;
         QSqlRecord m_rec;
+        bool m_submitted;
     };
 
     typedef QMap CacheMap;

From 76fa96b99e9ee79d0a2016fb28f17bc2dc58ab0a Mon Sep 17 00:00:00 2001
From: Mark Brand 
Date: Mon, 13 Feb 2012 09:26:21 +0100
Subject: [PATCH 228/406] QSqlRelationalTableModelPrivate: simplify field name
 translation

It's not appropriate to use indexInQuery() here. First of all,
the row might be an inserted row, and thus not be in the query.
The intent was probably to get the column position in the query,
but this is certainly not row dependent. Furthermore, if there
are inserted or removed columns, these are managed within
QSqlQueryModel.

Change-Id: I89668655b263747a5b849136404112e911722b3d
Reviewed-by: Yunqiao Yin 
---
 src/sql/models/qsqlrelationaltablemodel.cpp | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/src/sql/models/qsqlrelationaltablemodel.cpp b/src/sql/models/qsqlrelationaltablemodel.cpp
index 75bf3ebe43d..8dd18ca1d04 100644
--- a/src/sql/models/qsqlrelationaltablemodel.cpp
+++ b/src/sql/models/qsqlrelationaltablemodel.cpp
@@ -268,7 +268,7 @@ public:
     void clearCache();
     void revertCachedRow(int row);
 
-    void translateFieldNames(int row, QSqlRecord &values) const;
+    void translateFieldNames(QSqlRecord &values) const;
     QSqlRelationalTableModel::JoinMode joinMode;
 };
 
@@ -744,16 +744,13 @@ void QSqlRelationalTableModel::setTable(const QString &table)
 
 /*! \internal
  */
-void QSqlRelationalTableModelPrivate::translateFieldNames(int row, QSqlRecord &values) const
+void QSqlRelationalTableModelPrivate::translateFieldNames(QSqlRecord &values) const
 {
-    Q_Q(const QSqlRelationalTableModel);
-
     for (int i = 0; i < values.count(); ++i) {
-        int realCol = q->indexInQuery(q->createIndex(row, i)).column();
-        if (realCol != -1 && relations.value(realCol).isValid()) {
+        if (relations.value(i).isValid()) {
             QVariant v = values.value(i);
             bool gen = values.isGenerated(i);
-            values.replace(i, baseRec.field(realCol));
+            values.replace(i, baseRec.field(i));
             values.setValue(i, v);
             values.setGenerated(i, gen);
         }
@@ -768,7 +765,7 @@ bool QSqlRelationalTableModel::updateRowInTable(int row, const QSqlRecord &value
     Q_D(QSqlRelationalTableModel);
 
     QSqlRecord rec = values;
-    d->translateFieldNames(row, rec);
+    d->translateFieldNames(rec);
 
     return QSqlTableModel::updateRowInTable(row, rec);
 }
@@ -781,7 +778,7 @@ bool QSqlRelationalTableModel::insertRowIntoTable(const QSqlRecord &values)
     Q_D(QSqlRelationalTableModel);
 
     QSqlRecord rec = values;
-    d->translateFieldNames(0, rec);
+    d->translateFieldNames(rec);
 
     return QSqlTableModel::insertRowIntoTable(rec);
 }

From 22e0060e596c73e614f88f1269893214cf24bf6a Mon Sep 17 00:00:00 2001
From: Mark Brand 
Date: Mon, 13 Feb 2012 08:46:23 +0100
Subject: [PATCH 229/406] QSqlTableModel::indexInQuery(): fix for inserted rows

Should return invalid QModelIndex since inserted row does not map to
query.

Change-Id: Ib1d15cf4198a7063717fb3f3b594b2b1d8a54dfe
Reviewed-by: Yunqiao Yin 
---
 src/sql/models/qsqltablemodel.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index b21a965c212..932bbbfd6b0 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -1143,6 +1143,9 @@ int QSqlTableModel::rowCount(const QModelIndex &parent) const
 QModelIndex QSqlTableModel::indexInQuery(const QModelIndex &item) const
 {
     Q_D(const QSqlTableModel);
+    if (d->cache.value(item.row()).op() == QSqlTableModelPrivate::Insert)
+        return QModelIndex();
+
     const int rowOffset = d->insertCount(item.row());
     return QSqlQueryModel::indexInQuery(createIndex(item.row() - rowOffset, item.column(), item.internalPointer()));
 }

From 1acc490248655d7a2db5835f6f9ac0c68d6df454 Mon Sep 17 00:00:00 2001
From: Jason McDonald 
Date: Tue, 14 Feb 2012 13:03:16 +1000
Subject: [PATCH 230/406] Eliminate duplicate data row names in widgets
 autotests.

Change-Id: I82bab3cc39320014fac6732c7b60233b262cb30d
Reviewed-by: Rohan McGovern 
---
 .../qfilesystemmodel/tst_qfilesystemmodel.cpp | 46 +++++++------
 .../tst_qgraphicsgridlayout.cpp               |  3 +-
 .../itemviews/qheaderview/tst_qheaderview.cpp | 10 +--
 .../itemviews/qlistview/tst_qlistview.cpp     |  2 +-
 .../itemviews/qtableview/tst_qtableview.cpp   |  2 +-
 .../tst_qtreewidgetitemiterator.cpp           | 14 ++--
 .../kernel/qapplication/tst_qapplication.cpp  | 12 ++--
 .../kernel/qgridlayout/tst_qgridlayout.cpp    | 21 +++---
 .../util/qcompleter/tst_qcompleter.cpp        | 54 +++++++--------
 .../qabstractbutton/tst_qabstractbutton.cpp   | 14 ++--
 .../qabstractslider/tst_qabstractslider.cpp   |  4 +-
 .../qdoublevalidator/tst_qdoublevalidator.cpp |  8 +--
 .../qfontcombobox/tst_qfontcombobox.cpp       |  2 +-
 .../qintvalidator/tst_qintvalidator.cpp       |  4 +-
 .../widgets/widgets/qlabel/tst_qlabel.cpp     |  2 +-
 .../widgets/qlineedit/tst_qlineedit.cpp       | 65 +++++++++----------
 .../widgets/widgets/qspinbox/tst_qspinbox.cpp | 32 ++++-----
 .../widgets/qsplitter/tst_qsplitter.cpp       |  2 +-
 18 files changed, 150 insertions(+), 147 deletions(-)

diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
index ea4eed54d2a..8724bf63c87 100644
--- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
+++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
@@ -240,6 +240,9 @@ void tst_QFileSystemModel::naturalCompare_data()
     QTest::addColumn("caseSensitive");
     QTest::addColumn("result");
     QTest::addColumn("swap");
+
+#define ROWNAME(name) (qPrintable(QString("prefix=%1, postfix=%2, num=%3, i=%4, test=%5").arg(prefix).arg(postfix).arg(num).arg(i).arg(name)))
+
     for (int j = 0; j < 4; ++j) { // <- set a prefix and a postfix string (not numbers)
         QString prefix = (j == 0 || j == 1) ? "b" : "";
         QString postfix = (j == 1 || j == 2) ? "y" : "";
@@ -248,32 +251,33 @@ void tst_QFileSystemModel::naturalCompare_data()
             QString num = QString("%1").arg(k);
             QString nump = QString("%1").arg(k + 1);
             for (int i = 10; i < 12; ++i) { // <- swap s1 and s2 and reverse the result
-                QTest::newRow("basic") << prefix + "0" + postfix << prefix + "0" + postfix << int(Qt::CaseInsensitive) << 0;
+                QTest::newRow(ROWNAME("basic"))          << prefix + "0" + postfix << prefix + "0" + postfix << int(Qt::CaseInsensitive) << 0;
 
                 // s1 should always be less then s2
-                QTest::newRow("just text")    << prefix + "fred" + postfix     << prefix + "jane" + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("just numbers") << prefix + num + postfix        << prefix + "9" + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("zero")         << prefix + num + postfix        << prefix + "0" + nump + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("space b")      << prefix + num + postfix        << prefix + " " + nump + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("space a")      << prefix + num + postfix        << prefix + nump + " " + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("tab b")        << prefix + num + postfix        << prefix + "    " + nump + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("tab a")        << prefix + num + postfix        << prefix + nump + "   " + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("10 vs 2")      << prefix + num + postfix        << prefix + "10" + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("diff len")     << prefix + num + postfix        << prefix + nump + postfix + "x" << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("01 before 1")  << prefix + "0" + num + postfix  << prefix + nump + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("mul nums 2nd") << prefix + "1-" + num + postfix << prefix + "1-" + nump + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("mul nums 2nd") << prefix + "10-" + num + postfix<< prefix + "10-10" + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("mul nums 2nd") << prefix + "10-0"+ num + postfix<< prefix + "10-10" + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("mul nums 2nd") << prefix + "10-" + num + postfix<< prefix + "10-010" + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("mul nums big") << prefix + "10-" + num + postfix<< prefix + "20-0" + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("mul nums big") << prefix + "2-" + num + postfix << prefix + "10-0" + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("mul alphabet") << prefix + num + "-a" + postfix << prefix + num + "-c" + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("mul alphabet2")<< prefix + num + "-a9" + postfix<< prefix + num + "-c0" + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("mul nums w\\0")<< prefix + num + "-"+ num + postfix<< prefix + num+"-0"+nump + postfix << int(Qt::CaseInsensitive) << i;
-                QTest::newRow("num first")    << prefix + num + postfix  << prefix + "a" + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("just text"))      << prefix + "fred" + postfix     << prefix + "jane" + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("just numbers"))   << prefix + num + postfix        << prefix + "9" + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("zero"))           << prefix + num + postfix        << prefix + "0" + nump + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("space b"))        << prefix + num + postfix        << prefix + " " + nump + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("space a"))        << prefix + num + postfix        << prefix + nump + " " + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("tab b"))          << prefix + num + postfix        << prefix + "    " + nump + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("tab a"))          << prefix + num + postfix        << prefix + nump + "   " + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("10 vs 2"))        << prefix + num + postfix        << prefix + "10" + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("diff len"))       << prefix + num + postfix        << prefix + nump + postfix + "x" << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("01 before 1"))    << prefix + "0" + num + postfix  << prefix + nump + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("mul nums 2nd 1")) << prefix + "1-" + num + postfix << prefix + "1-" + nump + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("mul nums 2nd 2")) << prefix + "10-" + num + postfix<< prefix + "10-10" + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("mul nums 2nd 3")) << prefix + "10-0"+ num + postfix<< prefix + "10-10" + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("mul nums 2nd 4")) << prefix + "10-" + num + postfix<< prefix + "10-010" + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("mul nums big 1")) << prefix + "10-" + num + postfix<< prefix + "20-0" + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("mul nums big 2")) << prefix + "2-" + num + postfix << prefix + "10-0" + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("mul alphabet 1")) << prefix + num + "-a" + postfix << prefix + num + "-c" + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("mul alphabet 2")) << prefix + num + "-a9" + postfix<< prefix + num + "-c0" + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("mul nums w\\0"))  << prefix + num + "-"+ num + postfix<< prefix + num+"-0"+nump + postfix << int(Qt::CaseInsensitive) << i;
+                QTest::newRow(ROWNAME("num first"))      << prefix + num + postfix  << prefix + "a" + postfix << int(Qt::CaseInsensitive) << i;
             }
         }
     }
+#undef ROWNAME
 }
 
 void tst_QFileSystemModel::naturalCompare()
diff --git a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
index bbe70625072..51ce7f909cd 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
@@ -454,7 +454,6 @@ void tst_QGraphicsGridLayout::addItem_data()
     for (int b = -1; b < 2; ++b) {
     for (int c = -1; c < 2; ++c) {
     for (int d = -1; d < 2; ++d) {
-    for (int e = 0; e < 9; ++e) {
         int row = a;
         int column = b;
         int rowSpan = c;
@@ -462,7 +461,7 @@ void tst_QGraphicsGridLayout::addItem_data()
         QString name = QString::fromAscii("(%1,%2,%3,%4").arg(a).arg(b).arg(c).arg(d);
         Qt::Alignment alignment = Qt::AlignLeft;
         QTest::newRow(name.toLatin1()) << row << column << rowSpan << columnSpan << alignment;
-    }}}}}
+    }}}}
 }
 
 // public void addItem(QGraphicsLayoutItem* item, int row, int column, int rowSpan, int columnSpan, Qt::Alignment alignment = 0)
diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
index 4089768e7a4..4dd57e1b907 100644
--- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
@@ -2365,16 +2365,16 @@ void tst_QHeaderView::setupTestData(bool also_use_reset_model)
     QTest::addColumn("reset_model");
 
     if (also_use_reset_model) {
-        QTest::newRow("no_updates+normal")  << false << false << true;
-        QTest::newRow("hasupdates+normal")  << true << false << true;
-        QTest::newRow("no_updates+special") << false << true << true;
-        QTest::newRow("no_updates+special") << true << true << true;
+        QTest::newRow("no_updates+normal+reset")  << false << false << true;
+        QTest::newRow("hasupdates+normal+reset")  << true << false << true;
+        QTest::newRow("no_updates+special+reset") << false << true << true;
+        QTest::newRow("hasupdates+special+reset") << true << true << true;
     }
 
     QTest::newRow("no_updates+normal")  << false << false << false;
     QTest::newRow("hasupdates+normal")  << true << false << false;
     QTest::newRow("no_updates+special") << false << true << false;
-    QTest::newRow("no_updates+special") << true << true << false;
+    QTest::newRow("hasupdates+special") << true << true << false;
 }
 
 void tst_QHeaderView::additionalInit()
diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
index 523516a4b42..f139eac2755 100644
--- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
+++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
@@ -970,7 +970,7 @@ void tst_QListView::selection_data()
         << QRect(300, 10, 1, 1)                 // selection rectangle
         << IntList();                           // expected items
 
-    QTest::newRow("select to the right, (on viewport)")
+    QTest::newRow("select to the right 2, (on viewport)")
         << 40                                   // itemCount
         << int(QListView::ListMode)
         << int(QListView::TopToBottom)
diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
index 586c2efd8f8..9144a023d7c 100644
--- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
@@ -1204,7 +1204,7 @@ void tst_QTableView::moveCursorStrikesBack_data()
             << 0 << 5 << (IntList() << int(QtTestTableView::MoveNext))
             << 1 << 0;
 
-    QTest::newRow("Last column disabled. Task QTBUG-3878") << -1 << -1
+    QTest::newRow("Last column disabled 2. Task QTBUG-3878") << -1 << -1
             << IntList()
             << (IntList() << 6)
             << QRect()
diff --git a/tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp b/tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp
index 0e518b3e165..14c61c7932c 100644
--- a/tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp
+++ b/tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp
@@ -1014,13 +1014,13 @@ void tst_QTreeWidgetItemIterator::minus_eq_data()
     QTest::addColumn("iteratorflags");
     QTest::addColumn("expecteditem");
 
-    QTest::newRow("-=0") << 0 << 0 << (int)QTreeWidgetItemIterator::All << QString("top0");
-    QTest::newRow("-=1") << 2 << 1 << (int)QTreeWidgetItemIterator::All << QString("top0,child0");
-    QTest::newRow("-=2") << 4 << 2 << (int)QTreeWidgetItemIterator::All << QString("top0,child1");
-    QTest::newRow("-=(-1)") << 0 << -1 << (int)QTreeWidgetItemIterator::All << QString("top0,child0");
-    QTest::newRow("-=(-2)") << 0 << -2 << (int)QTreeWidgetItemIterator::All << QString("top0,child1");
-    QTest::newRow("-=1)") << 18 << 1 << (int)QTreeWidgetItemIterator::All << QString("top0,child16");
-    QTest::newRow("-=1)") << 1 << 1 << (int)QTreeWidgetItemIterator::All << QString("top0");
+    QTest::newRow("0-=0") << 0 << 0 << (int)QTreeWidgetItemIterator::All << QString("top0");
+    QTest::newRow("2-=1") << 2 << 1 << (int)QTreeWidgetItemIterator::All << QString("top0,child0");
+    QTest::newRow("4-=2") << 4 << 2 << (int)QTreeWidgetItemIterator::All << QString("top0,child1");
+    QTest::newRow("0-=(-1)") << 0 << -1 << (int)QTreeWidgetItemIterator::All << QString("top0,child0");
+    QTest::newRow("0-=(-2)") << 0 << -2 << (int)QTreeWidgetItemIterator::All << QString("top0,child1");
+    QTest::newRow("18-=1") << 18 << 1 << (int)QTreeWidgetItemIterator::All << QString("top0,child16");
+    QTest::newRow("1-=1") << 1 << 1 << (int)QTreeWidgetItemIterator::All << QString("top0");
 }
 
 void tst_QTreeWidgetItemIterator::minus_eq()
diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
index d9f4081ed33..7017c6157e0 100644
--- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
@@ -380,16 +380,16 @@ void tst_QApplication::setFont_data()
 	++cnt;
     }
 
-    QTest::newRow("nonexistingfont") << "nosuchfont_probably_quiteunlikely"
+    QTest::newRow("nonexistingfont after") << "nosuchfont_probably_quiteunlikely"
         << 0 << false;
-    QTest::newRow("nonexistingfont") << "nosuchfont_probably_quiteunlikely"
+    QTest::newRow("nonexistingfont before") << "nosuchfont_probably_quiteunlikely"
         << 0 << true;
 
-    QTest::newRow("largescaleable") << "smoothtimes" << 100 << false;
-    QTest::newRow("largescaleable") << "smoothtimes" << 100 << true;
+    QTest::newRow("largescaleable after") << "smoothtimes" << 100 << false;
+    QTest::newRow("largescaleable before") << "smoothtimes" << 100 << true;
 
-    QTest::newRow("largeunscaleale") << "helvetica" << 100 << false;
-    QTest::newRow("largeunscaleale") << "helvetica" << 100 << true;
+    QTest::newRow("largeunscaleale after") << "helvetica" << 100 << false;
+    QTest::newRow("largeunscaleale before") << "helvetica" << 100 << true;
 }
 
 void tst_QApplication::setFont()
diff --git a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp
index c8e5591f8b8..c43ea065f35 100644
--- a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp
+++ b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp
@@ -797,6 +797,16 @@ void tst_QGridLayout::minMaxSize_data()
                 << SizeInfo(QPoint(10, 10), QSize( 90, 90), QSize(100,100))
                 << SizeInfo(QPoint(10 + 100 + 1, 10), QSize( 90, 90))
                 );
+    QTest::newRow("2x1 grid, extend to minimumSize, motif") << QString::fromAscii("motif") << 2 << 1
+                << int(QSizePolicy::Preferred) << QSize() << (SizeInfoList()
+                << SizeInfo(QPoint(11, 11), QSize( 90, 90), QSize(100,100))
+                << SizeInfo(QPoint(11 + 100 + 6, 11), QSize( 90, 90))
+                );
+    QTest::newRow("2x1 grid, extend to minimumSize, windows") << QString::fromAscii("windows") << 2 << 1
+                << int(QSizePolicy::Preferred) << QSize() << (SizeInfoList()
+                << SizeInfo(QPoint(11, 11), QSize( 90, 90), QSize(100,100))
+                << SizeInfo(QPoint(11 + 100 + 6, 11), QSize( 90, 90))
+                );
     QTest::newRow("1x2 grid, extend to minimumSize") << QString() << 1 << 2
                 << int(QSizePolicy::Preferred) << QSize() << (SizeInfoList()
                 << SizeInfo(QPoint(10, 10), QSize( 90, 90), QSize(100,100))
@@ -818,17 +828,6 @@ void tst_QGridLayout::minMaxSize_data()
             << SizeInfo(QPoint(10, 10 + 100 + 1), QSize(100,100), QSize(), QSize(), 100*100)
             << SizeInfo(QPoint(10, 10 + 100 + 1 + 50 + 1), QSize(100,100), QSize(), QSize(100, 100))
             );
-    QTest::newRow("2x1 grid, extend to minimumSize") << QString::fromAscii("motif") << 2 << 1
-                << int(QSizePolicy::Preferred) << QSize() << (SizeInfoList()
-                << SizeInfo(QPoint(11, 11), QSize( 90, 90), QSize(100,100))
-                << SizeInfo(QPoint(11 + 100 + 6, 11), QSize( 90, 90))
-                );
-    QTest::newRow("2x1 grid, extend to minimumSize") << QString::fromAscii("windows") << 2 << 1
-                << int(QSizePolicy::Preferred) << QSize() << (SizeInfoList()
-                << SizeInfo(QPoint(11, 11), QSize( 90, 90), QSize(100,100))
-                << SizeInfo(QPoint(11 + 100 + 6, 11), QSize( 90, 90))
-                );
-
 }
 
 void tst_QGridLayout::minMaxSize()
diff --git a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp
index 228ff40ee52..a257eb17985 100644
--- a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp
+++ b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp
@@ -367,40 +367,42 @@ void tst_QCompleter::csMatchingOnCsSortedModel_data()
     QTest::addColumn("completion");
     QTest::addColumn("completionText");
 
+#define ROWNAME(name) (qPrintable(QString("%1 %2").arg(name).arg(i)))
+
     for (int i = 0; i < 2; i++) {
          if (i == 1)
              QTest::newRow("FILTERING_OFF") << "FILTERING_OFF" << "" << "" << "";
 
          // Plain text filter
-         QTest::newRow("()") << "" << "" << "P0" << "P0";
-         QTest::newRow("()F") << "" << "F" << "P0" << "P0";
-         QTest::newRow("()L") << "" << "L" << "p4" << "p4";
-         QTest::newRow("()L") << "" << "L" << "p4" << "p4";
-         QTest::newRow("()N") << "" << "N" << "P1" << "P1";
-         QTest::newRow("(P)") << "P" << "" << "P0" << "P0";
-         QTest::newRow("(P)F") << "P" << "" << "P0" << "P0";
-         QTest::newRow("(P)L") << "P" << "L" << "P4" << "P4";
-         QTest::newRow("(p)") << "p" << "" << "p0" << "p0";
-         QTest::newRow("(p)N") << "p" << "N" << "p1" << "p1";
-         QTest::newRow("(p)NN") << "p" << "NN" << "p2" << "p2";
-         QTest::newRow("(p)NNN") << "p" << "NNN" << "p3" << "p3";
-         QTest::newRow("(p)NNNN") << "p" << "NNNN" << "p4" << "p4";
-         QTest::newRow("(p1)") << "p1" << "" << "p1" << "p1";
-         QTest::newRow("(p11)") << "p11" << "" << "" << "";
+         QTest::newRow(ROWNAME("()")) << "" << "" << "P0" << "P0";
+         QTest::newRow(ROWNAME("()F")) << "" << "F" << "P0" << "P0";
+         QTest::newRow(ROWNAME("()L")) << "" << "L" << "p4" << "p4";
+         QTest::newRow(ROWNAME("()N")) << "" << "N" << "P1" << "P1";
+         QTest::newRow(ROWNAME("(P)")) << "P" << "" << "P0" << "P0";
+         QTest::newRow(ROWNAME("(P)F")) << "P" << "" << "P0" << "P0";
+         QTest::newRow(ROWNAME("(P)L")) << "P" << "L" << "P4" << "P4";
+         QTest::newRow(ROWNAME("(p)")) << "p" << "" << "p0" << "p0";
+         QTest::newRow(ROWNAME("(p)N")) << "p" << "N" << "p1" << "p1";
+         QTest::newRow(ROWNAME("(p)NN")) << "p" << "NN" << "p2" << "p2";
+         QTest::newRow(ROWNAME("(p)NNN")) << "p" << "NNN" << "p3" << "p3";
+         QTest::newRow(ROWNAME("(p)NNNN")) << "p" << "NNNN" << "p4" << "p4";
+         QTest::newRow(ROWNAME("(p1)")) << "p1" << "" << "p1" << "p1";
+         QTest::newRow(ROWNAME("(p11)")) << "p11" << "" << "" << "";
 
          // Tree filter
-         QTest::newRow("(P0,)") << "P0," << "" << "c0P0" << "P0,c0P0";
-         QTest::newRow("(P0,c)") << "P0,c" << "" << "c0P0" << "P0,c0P0";
-         QTest::newRow("(P0,c1)") << "P0,c1" << "" << "c1P0" << "P0,c1P0";
-         QTest::newRow("(P0,c3P0)") << "P0,c3P0" << "" << "c3P0" << "P0,c3P0";
-         QTest::newRow("(P3,c)F") << "P3,c" << "F" << "c0P3" << "P3,c0P3";
-         QTest::newRow("(P3,c)L") << "P3,c" << "L" << "c4P3" << "P3,c4P3";
-         QTest::newRow("(P3,c)N") << "P3,c" << "N" << "c1P3" << "P3,c1P3";
-         QTest::newRow("(P3,c)NN") << "P3,c" << "NN" << "c2P3" << "P3,c2P3";
-         QTest::newRow("(P3,,c)") << "P3,,c" << "" << "" << "";
-         QTest::newRow("(P3,c0P3,)") << "P3,c0P3," << "" << "" << "";
-         QTest::newRow("(P,)") << "P," << "" << "" << "";
+         QTest::newRow(ROWNAME("(P0,)")) << "P0," << "" << "c0P0" << "P0,c0P0";
+         QTest::newRow(ROWNAME("(P0,c)")) << "P0,c" << "" << "c0P0" << "P0,c0P0";
+         QTest::newRow(ROWNAME("(P0,c1)")) << "P0,c1" << "" << "c1P0" << "P0,c1P0";
+         QTest::newRow(ROWNAME("(P0,c3P0)")) << "P0,c3P0" << "" << "c3P0" << "P0,c3P0";
+         QTest::newRow(ROWNAME("(P3,c)F")) << "P3,c" << "F" << "c0P3" << "P3,c0P3";
+         QTest::newRow(ROWNAME("(P3,c)L")) << "P3,c" << "L" << "c4P3" << "P3,c4P3";
+         QTest::newRow(ROWNAME("(P3,c)N")) << "P3,c" << "N" << "c1P3" << "P3,c1P3";
+         QTest::newRow(ROWNAME("(P3,c)NN")) << "P3,c" << "NN" << "c2P3" << "P3,c2P3";
+         QTest::newRow(ROWNAME("(P3,,c)")) << "P3,,c" << "" << "" << "";
+         QTest::newRow(ROWNAME("(P3,c0P3,)")) << "P3,c0P3," << "" << "" << "";
+         QTest::newRow(ROWNAME("(P,)")) << "P," << "" << "" << "";
      }
+#undef ROWNAME
 }
 
 void tst_QCompleter::csMatchingOnCsSortedModel()
diff --git a/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp b/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
index 5695834e61d..85cd2a8d925 100644
--- a/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
+++ b/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
@@ -229,13 +229,13 @@ void tst_QAbstractButton::onReleased()
 void tst_QAbstractButton::setAutoRepeat_data()
 {
     QTest::addColumn("mode");
-    QTest::newRow( "" ) << 0;
-    QTest::newRow( "" ) << 1;
-    QTest::newRow( "" ) << 2;
-    QTest::newRow( "" ) << 3;
-    QTest::newRow( "" ) << 4;
-    QTest::newRow( "" ) << 5;
-    QTest::newRow( "" ) << 6;
+    QTest::newRow("mode 0") << 0;
+    QTest::newRow("mode 1") << 1;
+    QTest::newRow("mode 2") << 2;
+    QTest::newRow("mode 3") << 3;
+    QTest::newRow("mode 4") << 4;
+    QTest::newRow("mode 5") << 5;
+    QTest::newRow("mode 6") << 6;
 }
 
 #define REPEAT_DELAY 1000
diff --git a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp
index 6ed5d59db02..6021f90ed43 100644
--- a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp
+++ b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp
@@ -482,7 +482,7 @@ void tst_QAbstractSlider::keyPressed_data()
     QList list;
 
     list << Qt::Key_Down;
-    QTest::newRow("Step down once") << 10   // initial position
+    QTest::newRow("Step down once 1") << 10   // initial position
                                  << 0    // minimum
                                  << 100  // maximum
                                  << 3    // single step size
@@ -495,7 +495,7 @@ void tst_QAbstractSlider::keyPressed_data()
 
     list = QList();
     list << Qt::Key_Up;
-    QTest::newRow("Step down once") << 10   // initial position
+    QTest::newRow("Step down once 2") << 10   // initial position
                                  << 0    // minimum
                                  << 100  // maximum
                                  << 3    // single step size
diff --git a/tests/auto/widgets/widgets/qdoublevalidator/tst_qdoublevalidator.cpp b/tests/auto/widgets/widgets/qdoublevalidator/tst_qdoublevalidator.cpp
index deb8a3bb6f6..474acc0a78e 100644
--- a/tests/auto/widgets/widgets/qdoublevalidator/tst_qdoublevalidator.cpp
+++ b/tests/auto/widgets/widgets/qdoublevalidator/tst_qdoublevalidator.cpp
@@ -360,11 +360,11 @@ void tst_QDoubleValidator::validateIntEquiv_data()
     QTest::newRow("4.6") << 0.0 << 10.0 << QString(".1") << INV;
     QTest::newRow("4.7") << 0.0 << 10.0 << QString("-1.0") << INV;
 
-    QTest::newRow("5.1") << 6.0 << 8.0 << QString("5") << ITM;
-    QTest::newRow("5.1") << 6.0 << 8.0 << QString("56") << INV;
+    QTest::newRow("5.1a") << 6.0 << 8.0 << QString("5") << ITM;
+    QTest::newRow("5.1b") << 6.0 << 8.0 << QString("56") << INV;
     QTest::newRow("5.2") << 6.0 << 8.0 << QString("7") << ACC;
-    QTest::newRow("5.3") << 6.0 << 8.0 << QString("9") << ITM;
-    QTest::newRow("5.3") << 6.0 << 8.0 << QString("-") << INV;
+    QTest::newRow("5.3a") << 6.0 << 8.0 << QString("9") << ITM;
+    QTest::newRow("5.3b") << 6.0 << 8.0 << QString("-") << INV;
     QTest::newRow("5.4a") << -8.0 << -6.0 << QString("+") << INV;
     QTest::newRow("5.4b") << -8.0 << -6.0 << QString("+5") << INV;
     QTest::newRow("5.4c") << -8.0 << -6.0 << QString("-5") << ITM;
diff --git a/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp b/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp
index e7736071642..3832d39d6f8 100644
--- a/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp
+++ b/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp
@@ -256,7 +256,7 @@ void tst_QFontComboBox::writingSystem_data()
     QTest::newRow("Runic") << QFontDatabase::Runic;
 
     for (int i = 0; i < 31; ++i)
-        QTest::newRow("enum") << (QFontDatabase::WritingSystem)i;
+        QTest::newRow(qPrintable(QString("enum %1").arg(i))) << (QFontDatabase::WritingSystem)i;
 }
 
 // public QFontDatabase::WritingSystem writingSystem() const
diff --git a/tests/auto/widgets/widgets/qintvalidator/tst_qintvalidator.cpp b/tests/auto/widgets/widgets/qintvalidator/tst_qintvalidator.cpp
index 6aec414ae67..99d8ded15c7 100644
--- a/tests/auto/widgets/widgets/qintvalidator/tst_qintvalidator.cpp
+++ b/tests/auto/widgets/widgets/qintvalidator/tst_qintvalidator.cpp
@@ -70,8 +70,8 @@ void tst_QIntValidator::validate_data()
     QTest::newRow("data1") << 0 << 100 << QString("500") << INV;
     QTest::newRow("data1a") << 0 << 100 << QString("5000") << INV;
     QTest::newRow("data1b") << -100 << 0 << QString("50") << INT;
-    QTest::newRow("data1b") << -100 << 0 << QString("500") << INV;
-    QTest::newRow("data1c") << -100 << 0 << QString("5000") << INV;
+    QTest::newRow("data1c") << -100 << 0 << QString("500") << INV;
+    QTest::newRow("data1d") << -100 << 0 << QString("5000") << INV;
     QTest::newRow("data2") << 0 << 100 << QString("-35") << INV;
     QTest::newRow("data3") << 0 << 100 << QString("a") << INV;
     QTest::newRow("data4") << 0 << 100 << QString("-") << INV;
diff --git a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp
index 6d6b9384b97..d8b2a800b9e 100644
--- a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp
+++ b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp
@@ -312,7 +312,7 @@ void tst_QLabel::eventPropagation_data()
     QTest::newRow("rich text2") << QString("rich text") << (int)Qt::TextSelectableByKeyboard << (int)Qt::ClickFocus << true;
     QTest::newRow("rich text3") << QString("rich text") << (int)Qt::TextSelectableByMouse << (int)Qt::ClickFocus << false;
     QTest::newRow("rich text4") << QString("rich text") << (int)Qt::NoTextInteraction << (int)Qt::NoFocus << true;
-    QTest::newRow("rich text4") << QString("rich text") << (int)Qt::LinksAccessibleByKeyboard << (int)Qt::StrongFocus << true;
+    QTest::newRow("rich text5") << QString("rich text") << (int)Qt::LinksAccessibleByKeyboard << (int)Qt::StrongFocus << true;
 
     if (!test_box)
         test_box = new Widget;
diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
index b004efd07cb..645f47fc728 100644
--- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
+++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
@@ -647,22 +647,21 @@ void tst_QLineEdit::inputMask_data()
     QTest::addColumn("expectedMask");
 
     // if no mask is set a nul string should be returned
-    QTest::newRow("") << QString("") << QString();
-    QTest::newRow("") << QString() << QString();
+    QTest::newRow("nul 1") << QString("") << QString();
+    QTest::newRow("nul 2") << QString() << QString();
 
     // try different masks
-    QTest::newRow("") << QString("000.000.000.000") << QString("000.000.000.000; ");
-    QTest::newRow("") << QString("000.000.000.000;#") << QString("000.000.000.000;#");
-    QTest::newRow("") << QString("AAA.aa.999.###;") << QString("AAA.aa.999.###; ");
-    QTest::newRow("") << QString(">abcdefabcdefabcdefabcdef("replacementLength");
     QTest::addColumn("commitString");
 
-    QTest::newRow("") << 4 << 4 << 0 << 0 << QString("");
-    QTest::newRow("") << 4 << 4 << 0 << 0 << QString("x");
-    QTest::newRow("") << 4 << 4 << 0 << 0 << QString("xxxxxxxxxxxxxxxx");
-    QTest::newRow("") << 4 << 3 << 0 << 0 << QString("");
-    QTest::newRow("") << 4 << 3 << 0 << 0 << QString("x");
-    QTest::newRow("") << 4 << 3 << 0 << 0 << QString("xxxxxxxxxxxxxxxx");
-    QTest::newRow("") << 4 << 0 << 0 << 0 << QString("");
-    QTest::newRow("") << 4 << 0 << 0 << 0 << QString("x");
-    QTest::newRow("") << 4 << 0 << 0 << 0 << QString("xxxxxxxxxxxxxxxx");
+    QTest::newRow("data1")  << 4 << 4 << 0 << 0 << QString("");
+    QTest::newRow("data2")  << 4 << 4 << 0 << 0 << QString("x");
+    QTest::newRow("data3")  << 4 << 4 << 0 << 0 << QString("xxxxxxxxxxxxxxxx");
+    QTest::newRow("data4")  << 4 << 3 << 0 << 0 << QString("");
+    QTest::newRow("data5")  << 4 << 3 << 0 << 0 << QString("x");
+    QTest::newRow("data6")  << 4 << 3 << 0 << 0 << QString("xxxxxxxxxxxxxxxx");
+    QTest::newRow("data7")  << 4 << 0 << 0 << 0 << QString("");
+    QTest::newRow("data8")  << 4 << 0 << 0 << 0 << QString("x");
+    QTest::newRow("data9")  << 4 << 0 << 0 << 0 << QString("xxxxxxxxxxxxxxxx");
 
-    QTest::newRow("") << 4 << 4 << -4 << 4 << QString("");
-    QTest::newRow("") << 4 << 4 << -4 << 4 << QString("x");
-    QTest::newRow("") << 4 << 4 << -4 << 4 << QString("xxxxxxxxxxxxxxxx");
-    QTest::newRow("") << 4 << 3 << -3 << 4 << QString("");
-    QTest::newRow("") << 4 << 3 << -3 << 4 << QString("x");
-    QTest::newRow("") << 4 << 3 << -3 << 4 << QString("xxxxxxxxxxxxxxxx");
-    QTest::newRow("") << 4 << 0 << 0 << 4 << QString("");
-    QTest::newRow("") << 4 << 0 << 0 << 4 << QString("x");
-    QTest::newRow("") << 4 << 0 << 0 << 4 << QString("xxxxxxxxxxxxxxxx");
+    QTest::newRow("data10") << 4 << 4 << -4 << 4 << QString("");
+    QTest::newRow("data11") << 4 << 4 << -4 << 4 << QString("x");
+    QTest::newRow("data12") << 4 << 4 << -4 << 4 << QString("xxxxxxxxxxxxxxxx");
+    QTest::newRow("data13") << 4 << 3 << -3 << 4 << QString("");
+    QTest::newRow("data14") << 4 << 3 << -3 << 4 << QString("x");
+    QTest::newRow("data15") << 4 << 3 << -3 << 4 << QString("xxxxxxxxxxxxxxxx");
+    QTest::newRow("data16") << 4 << 0 << 0 << 4 << QString("");
+    QTest::newRow("data17") << 4 << 0 << 0 << 4 << QString("x");
+    QTest::newRow("data18") << 4 << 0 << 0 << 4 << QString("xxxxxxxxxxxxxxxx");
 
-    QTest::newRow("") << 4 << 4 << -4 << 0 << QString("");
-    QTest::newRow("") << 4 << 4 << -4 << 0 << QString("x");
-    QTest::newRow("") << 4 << 4 << -4 << 0 << QString("xxxxxxxxxxxxxxxx");
-    QTest::newRow("") << 4 << 3 << -3 << 0 << QString("");
-    QTest::newRow("") << 4 << 3 << -3 << 0 << QString("x");
-    QTest::newRow("") << 4 << 3 << -3 << 0 << QString("xxxxxxxxxxxxxxxx");
+    QTest::newRow("data19") << 4 << 4 << -4 << 0 << QString("");
+    QTest::newRow("data20") << 4 << 4 << -4 << 0 << QString("x");
+    QTest::newRow("data21") << 4 << 4 << -4 << 0 << QString("xxxxxxxxxxxxxxxx");
+    QTest::newRow("data22") << 4 << 3 << -3 << 0 << QString("");
+    QTest::newRow("data23") << 4 << 3 << -3 << 0 << QString("x");
+    QTest::newRow("data24") << 4 << 3 << -3 << 0 << QString("xxxxxxxxxxxxxxxx");
 }
 
 void tst_QLineEdit::task233101_cursorPosAfterInputMethod()
diff --git a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
index c3d982388d5..07efb60b491 100644
--- a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
+++ b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
@@ -657,22 +657,22 @@ void tst_QSpinBox::valueFromTextAndValidate_data()
     QTest::newRow("data3") << QString("2") << Acceptable << 0 << 100 << QString();
     QTest::newRow("data4") << QString() << Intermediate << 0 << 1 << QString();
     QTest::newRow("data5") << QString() << Invalid << 0 << 0 << QString();
-    QTest::newRow("data5") << QString("5") << Intermediate << 2004 << 2005 << QString();
-    QTest::newRow("data6") << QString("50") << Intermediate << 2004 << 2005 << QString();
-    QTest::newRow("data7") << QString("205") << Intermediate << 2004 << 2005 << QString();
-    QTest::newRow("data8") << QString("2005") << Acceptable << 2004 << 2005 << QString();
-    QTest::newRow("data9") << QString("3") << Intermediate << 2004 << 2005 << QString();
-    QTest::newRow("data10") << QString("-") << Intermediate << -20 << -10 << QString();
-    QTest::newRow("data11") << QString("-1") << Intermediate << -20 << -10 << QString();
-    QTest::newRow("data12") << QString("-5") << Intermediate << -20 << -10 << QString();
-    QTest::newRow("data13") << QString("-5") << Intermediate << -20 << -16 << QString();
-    QTest::newRow("data14") << QString("-2") << Intermediate << -20 << -16 << QString();
-    QTest::newRow("data15") << QString("2") << Invalid << -20 << -16 << QString();
-    QTest::newRow("data16") << QString() << Intermediate << -20 << -16 << QString();
-    QTest::newRow("data17") << QString("  22") << Acceptable << 0 << 1000 << QString("22");
-    QTest::newRow("data18") << QString("22  ") << Acceptable << 0 << 1000 << QString("22");
-    QTest::newRow("data19") << QString("  22  ") << Acceptable << 0 << 1000 << QString("22");
-    QTest::newRow("data20") << QString("2 2") << Invalid << 0 << 1000 << QString();
+    QTest::newRow("data6") << QString("5") << Intermediate << 2004 << 2005 << QString();
+    QTest::newRow("data7") << QString("50") << Intermediate << 2004 << 2005 << QString();
+    QTest::newRow("data8") << QString("205") << Intermediate << 2004 << 2005 << QString();
+    QTest::newRow("data9") << QString("2005") << Acceptable << 2004 << 2005 << QString();
+    QTest::newRow("data10") << QString("3") << Intermediate << 2004 << 2005 << QString();
+    QTest::newRow("data11") << QString("-") << Intermediate << -20 << -10 << QString();
+    QTest::newRow("data12") << QString("-1") << Intermediate << -20 << -10 << QString();
+    QTest::newRow("data13") << QString("-5") << Intermediate << -20 << -10 << QString();
+    QTest::newRow("data14") << QString("-5") << Intermediate << -20 << -16 << QString();
+    QTest::newRow("data15") << QString("-2") << Intermediate << -20 << -16 << QString();
+    QTest::newRow("data16") << QString("2") << Invalid << -20 << -16 << QString();
+    QTest::newRow("data17") << QString() << Intermediate << -20 << -16 << QString();
+    QTest::newRow("data18") << QString("  22") << Acceptable << 0 << 1000 << QString("22");
+    QTest::newRow("data19") << QString("22  ") << Acceptable << 0 << 1000 << QString("22");
+    QTest::newRow("data20") << QString("  22  ") << Acceptable << 0 << 1000 << QString("22");
+    QTest::newRow("data21") << QString("2 2") << Invalid << 0 << 1000 << QString();
 }
 
 static QString stateName(int state)
diff --git a/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp b/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp
index 048f1441a20..294a656482f 100644
--- a/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp
+++ b/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp
@@ -507,7 +507,7 @@ void tst_QSplitter::setStretchFactor_data()
     QTest::newRow("ok06") << int(Qt::Vertical) << 1 << 1 << 1 << 1;
     QTest::newRow("ok07") << int(Qt::Vertical) << 2 << 2 << 2 << 2;
     QTest::newRow("ok08") << int(Qt::Vertical) << 3 << 5 << 5 << 5;
-    QTest::newRow("ok08") << int(Qt::Vertical) << -1 << 5 << 0 << 0;
+    QTest::newRow("ok09") << int(Qt::Vertical) << -1 << 5 << 0 << 0;
 }
 
 void tst_QSplitter::setStretchFactor()

From 3296b7327bd84f420df7e5561d192c0a8d0bb409 Mon Sep 17 00:00:00 2001
From: Rohan McGovern 
Date: Mon, 13 Feb 2012 09:43:29 +1000
Subject: [PATCH 231/406] Fixed typo.

keyboar -> keyboard

Change-Id: Ia305237ac92ac5b0d5c8b0d3cc638292238cec02
Reviewed-by: Johannes Zellner 
Reviewed-by: Toby Tomkins 
---
 src/plugins/generic/evdevkeyboard/main.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/plugins/generic/evdevkeyboard/main.cpp b/src/plugins/generic/evdevkeyboard/main.cpp
index c3cc9f629a3..6df4e29fcb2 100644
--- a/src/plugins/generic/evdevkeyboard/main.cpp
+++ b/src/plugins/generic/evdevkeyboard/main.cpp
@@ -72,6 +72,6 @@ QObject* QEvdevKeyboardPlugin::create(const QString &key,
     return 0;
 }
 
-Q_EXPORT_PLUGIN2(qevdevkeyboarplugin, QEvdevKeyboardPlugin)
+Q_EXPORT_PLUGIN2(qevdevkeyboardplugin, QEvdevKeyboardPlugin)
 
 QT_END_NAMESPACE

From 9c23257fe4ea4778433909e28a5af9895fdb7e24 Mon Sep 17 00:00:00 2001
From: Jonathan Liu 
Date: Tue, 14 Feb 2012 23:27:32 +1100
Subject: [PATCH 232/406] Fix compilation with MinGW

Some headers and constants are available in MinGW-w64 that are not
available in the official MinGW. STATE_SYSTEM_HASPOPUP and
STATE_SYSTEM_PROTECTED constants are defined if they are not already
defined by including oleacc.h. _CrtSetReportMode is not used and
crtdbg.h is not included when using official MinGW as crtdbg.h is
missing from official MinGW.

Change-Id: Ie7f3f3726a1663d0fdeb6ee17b86873ae3f61860
Reviewed-by: Jonathan Liu 
Reviewed-by: Friedemann Kleint 
---
 src/plugins/platforms/windows/qtwindows_additional.h    | 3 +++
 src/plugins/platforms/windows/qwindowsaccessibility.cpp | 2 ++
 src/testlib/qtestcase.cpp                               | 6 +++++-
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/plugins/platforms/windows/qtwindows_additional.h b/src/plugins/platforms/windows/qtwindows_additional.h
index a85a798b9ed..ab51f36c247 100644
--- a/src/plugins/platforms/windows/qtwindows_additional.h
+++ b/src/plugins/platforms/windows/qtwindows_additional.h
@@ -68,6 +68,9 @@
 
 #if !defined(__MINGW64_VERSION_MAJOR)
 
+#define STATE_SYSTEM_HASPOPUP 0x40000000
+#define STATE_SYSTEM_PROTECTED 0x20000000
+
 typedef struct tagUPDATELAYEREDWINDOWINFO {
   DWORD               cbSize;
   HDC                 hdcDst;
diff --git a/src/plugins/platforms/windows/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/qwindowsaccessibility.cpp
index e36e2559476..3ef21fa0b7b 100644
--- a/src/plugins/platforms/windows/qwindowsaccessibility.cpp
+++ b/src/plugins/platforms/windows/qwindowsaccessibility.cpp
@@ -84,6 +84,8 @@
 #include "qguifunctions_wince.h"
 #endif
 
+#include "qtwindows_additional.h"
+
 QT_BEGIN_NAMESPACE
 
 //#define DEBUG_SHOW_ATCLIENT_COMMANDS
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 76bea243b13..549d16b9974 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -70,7 +70,9 @@
 
 #ifdef Q_OS_WIN
 #ifndef Q_OS_WINCE
-# include 
+# if !defined(Q_CC_MINGW) || (defined(Q_CC_MINGW) && defined(__MINGW64_VERSION_MAJOR))
+#  include 
+# endif
 #endif
 #include  // for Sleep
 #endif
@@ -1947,7 +1949,9 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
 #endif
 
 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+# if !defined(Q_CC_MINGW) || (defined(Q_CC_MINGW) && defined(__MINGW64_VERSION_MAJOR))
     _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
+# endif
     SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX);
 #endif
 

From 58d6c856ece204be11bc4f53a0967d317468d558 Mon Sep 17 00:00:00 2001
From: Kent Hansen 
Date: Sat, 4 Feb 2012 21:39:38 +0100
Subject: [PATCH 233/406] qmetaobjectbuilder: Add support for revisioned
 methods and properties
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

moc supports it, so qmetaobjectbuilder should too.

Change-Id: I01475794e928b5a1b659f0dab044933948186971
Reviewed-by: Bradley T. Hughes 
Reviewed-by: Jędrzej Nowacki 
Reviewed-by: Kent Hansen 
---
 src/corelib/kernel/qmetaobjectbuilder.cpp     | 130 +++++++++++++++++-
 src/corelib/kernel/qmetaobjectbuilder_p.h     |   6 +
 .../tst_qmetaobjectbuilder.cpp                |  25 ++++
 3 files changed, 157 insertions(+), 4 deletions(-)

diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp
index 064b8edafd6..c84c95cb6f6 100644
--- a/src/corelib/kernel/qmetaobjectbuilder.cpp
+++ b/src/corelib/kernel/qmetaobjectbuilder.cpp
@@ -106,10 +106,12 @@ public:
             (QMetaMethod::MethodType _methodType,
              const QByteArray& _signature,
              const QByteArray& _returnType = QByteArray(),
-             QMetaMethod::Access _access = QMetaMethod::Public)
+             QMetaMethod::Access _access = QMetaMethod::Public,
+             int _revision = 0)
         : signature(QMetaObject::normalizedSignature(_signature.constData())),
           returnType(QMetaObject::normalizedType(_returnType)),
-          attributes(((int)_access) | (((int)_methodType) << 2))
+          attributes(((int)_access) | (((int)_methodType) << 2)),
+          revision(_revision)
     {
     }
 
@@ -118,6 +120,7 @@ public:
     QList parameterNames;
     QByteArray tag;
     int attributes;
+    int revision;
 
     QMetaMethod::MethodType methodType() const
     {
@@ -139,10 +142,12 @@ class QMetaPropertyBuilderPrivate
 {
 public:
     QMetaPropertyBuilderPrivate
-            (const QByteArray& _name, const QByteArray& _type, int notifierIdx=-1)
+            (const QByteArray& _name, const QByteArray& _type, int notifierIdx=-1,
+             int _revision = 0)
         : name(_name),
           type(QMetaObject::normalizedType(_type.constData())),
-          flags(Readable | Writable | Scriptable), notifySignal(-1)
+          flags(Readable | Writable | Scriptable), notifySignal(-1),
+          revision(_revision)
     {
         if (notifierIdx >= 0) {
             flags |= Notify;
@@ -154,6 +159,7 @@ public:
     QByteArray type;
     int flags;
     int notifySignal;
+    int revision;
 
     bool flag(int f) const
     {
@@ -193,6 +199,9 @@ public:
         staticMetacallFunction = 0;
     }
 
+    bool hasRevisionedProperties() const;
+    bool hasRevisionedMethods() const;
+
     QByteArray className;
     const QMetaObject *superClass;
     QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction;
@@ -206,6 +215,24 @@ public:
     int flags;
 };
 
+bool QMetaObjectBuilderPrivate::hasRevisionedProperties() const
+{
+    for (int i = 0; i < properties.size(); ++i) {
+        if (properties.at(i).revision)
+            return true;
+    }
+    return false;
+}
+
+bool QMetaObjectBuilderPrivate::hasRevisionedMethods() const
+{
+    for (int i = 0; i < methods.size(); ++i) {
+        if (methods.at(i).revision)
+            return true;
+    }
+    return false;
+}
+
 /*!
     Constructs a new QMetaObjectBuilder.
 */
@@ -443,6 +470,7 @@ QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QMetaMethod& prototype)
     method.setTag(prototype.tag());
     method.setAccess(prototype.access());
     method.setAttributes(prototype.attributes());
+    method.setRevision(prototype.revision());
     return method;
 }
 
@@ -556,6 +584,7 @@ QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty& protot
     property.setEnumOrFlag(prototype.isEnumType());
     property.setConstant(prototype.isConstant());
     property.setFinal(prototype.isFinal());
+    property.setRevision(prototype.revision());
     if (prototype.hasNotifySignal()) {
         // Find an existing method for the notify signal, or add a new one.
         QMetaMethod method = prototype.notifySignal();
@@ -1109,6 +1138,8 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
     int dataIndex;
     int enumIndex;
     int index;
+    bool hasRevisionedMethods = d->hasRevisionedMethods();
+    bool hasRevisionedProperties = d->hasRevisionedProperties();
     bool hasNotifySignals = false;
 
     if (relocatable &&
@@ -1149,12 +1180,16 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
         pmeta->methodCount = d->methods.size();
         pmeta->methodData = dataIndex;
         dataIndex += 5 * d->methods.size();
+        if (hasRevisionedMethods)
+            dataIndex += d->methods.size();
 
         pmeta->propertyCount = d->properties.size();
         pmeta->propertyData = dataIndex;
         dataIndex += 3 * d->properties.size();
         if (hasNotifySignals)
             dataIndex += d->properties.size();
+        if (hasRevisionedProperties)
+            dataIndex += d->properties.size();
 
         pmeta->enumeratorCount = d->enumerators.size();
         pmeta->enumeratorData = dataIndex;
@@ -1166,9 +1201,13 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
     } else {
         dataIndex += 2 * d->classInfoNames.size();
         dataIndex += 5 * d->methods.size();
+        if (hasRevisionedMethods)
+            dataIndex += d->methods.size();
         dataIndex += 3 * d->properties.size();
         if (hasNotifySignals)
             dataIndex += d->properties.size();
+        if (hasRevisionedProperties)
+            dataIndex += d->properties.size();
         dataIndex += 4 * d->enumerators.size();
         dataIndex += 5 * d->constructors.size();
     }
@@ -1241,6 +1280,14 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
         }
         dataIndex += 5;
     }
+    if (hasRevisionedMethods) {
+        for (index = 0; index < d->methods.size(); ++index) {
+            QMetaMethodBuilderPrivate *method = &(d->methods[index]);
+            if (buf)
+                data[dataIndex] = method->revision;
+            ++dataIndex;
+        }
+    }
 
     // Output the properties in the class.
     for (index = 0; index < d->properties.size(); ++index) {
@@ -1274,6 +1321,14 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
             ++dataIndex;
         }
     }
+    if (hasRevisionedProperties) {
+        for (index = 0; index < d->properties.size(); ++index) {
+            QMetaPropertyBuilderPrivate *prop = &(d->properties[index]);
+            if (buf)
+                data[dataIndex] = prop->revision;
+            ++dataIndex;
+        }
+    }
 
     // Output the enumerators in the class.
     for (index = 0; index < d->enumerators.size(); ++index) {
@@ -1506,6 +1561,8 @@ void QMetaObjectBuilder::serialize(QDataStream& stream) const
         stream << method->parameterNames;
         stream << method->tag;
         stream << method->attributes;
+        if (method->revision)
+            stream << method->revision;
     }
 
     // Write the properties.
@@ -1515,6 +1572,8 @@ void QMetaObjectBuilder::serialize(QDataStream& stream) const
         stream << property->type;
         stream << property->flags;
         stream << property->notifySignal;
+        if (property->revision)
+            stream << property->revision;
     }
 
     // Write the enumerators.
@@ -1645,6 +1704,8 @@ void QMetaObjectBuilder::deserialize
         stream >> method->parameterNames;
         stream >> method->tag;
         stream >> method->attributes;
+        if (method->attributes & MethodRevisioned)
+            stream >> method->revision;
         if (method->methodType() == QMetaMethod::Constructor) {
             // Cannot add a constructor in this set of methods.
             stream.setStatus(QDataStream::ReadCorruptData);
@@ -1675,6 +1736,8 @@ void QMetaObjectBuilder::deserialize
             stream.setStatus(QDataStream::ReadCorruptData);
             return;
         }
+        if (property->flags & Revisioned)
+            stream >> property->revision;
     }
 
     // Read the enumerators.
@@ -1928,6 +1991,37 @@ void QMetaMethodBuilder::setAttributes(int value)
         d->attributes = ((d->attributes & 0x0f) | (value << 4));
 }
 
+/*!
+    Returns the revision of this method.
+
+    \sa setRevision()
+*/
+int QMetaMethodBuilder::revision() const
+{
+    QMetaMethodBuilderPrivate *d = d_func();
+    if (d)
+        return d->revision;
+    return 0;
+
+}
+
+/*!
+    Sets the \a revision of this method.
+
+    \sa revision()
+*/
+void QMetaMethodBuilder::setRevision(int revision)
+{
+    QMetaMethodBuilderPrivate *d = d_func();
+    if (d) {
+        d->revision = revision;
+        if (revision)
+            d->attributes |= MethodRevisioned;
+        else
+            d->attributes &= ~MethodRevisioned;
+    }
+}
+
 /*!
     \class QMetaPropertyBuilder
     \internal
@@ -2370,6 +2464,34 @@ void QMetaPropertyBuilder::setFinal(bool value)
         d->setFlag(Final, value);
 }
 
+/*!
+    Returns the revision of this property.
+
+    \sa setRevision()
+*/
+int QMetaPropertyBuilder::revision() const
+{
+    QMetaPropertyBuilderPrivate *d = d_func();
+    if (d)
+        return d->revision;
+    return 0;
+
+}
+
+/*!
+    Sets the \a revision of this property.
+
+    \sa revision()
+*/
+void QMetaPropertyBuilder::setRevision(int revision)
+{
+    QMetaPropertyBuilderPrivate *d = d_func();
+    if (d) {
+        d->revision = revision;
+        d->setFlag(Revisioned, revision != 0);
+    }
+}
+
 
 /*!
     \class QMetaEnumBuilder
diff --git a/src/corelib/kernel/qmetaobjectbuilder_p.h b/src/corelib/kernel/qmetaobjectbuilder_p.h
index 17b7af0c770..86bc354164d 100644
--- a/src/corelib/kernel/qmetaobjectbuilder_p.h
+++ b/src/corelib/kernel/qmetaobjectbuilder_p.h
@@ -215,6 +215,9 @@ public:
     int attributes() const;
     void setAttributes(int value);
 
+    int revision() const;
+    void setRevision(int revision);
+
 private:
     const QMetaObjectBuilder *_mobj;
     int _index;
@@ -269,6 +272,9 @@ public:
     void setConstant(bool value);
     void setFinal(bool value);
 
+    int revision() const;
+    void setRevision(int revision);
+
 private:
     const QMetaObjectBuilder *_mobj;
     int _index;
diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
index 966ac021ac2..02c69b9b1bf 100644
--- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
+++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
@@ -91,6 +91,7 @@ class SomethingOfEverything : public QObject
     Q_CLASSINFO("ci_bar", "DEF")
     Q_PROPERTY(QString prop READ prop WRITE setProp NOTIFY propChanged)
     Q_PROPERTY(QString prop2 READ prop WRITE setProp)
+    Q_PROPERTY(QString revisionProp READ prop WRITE setProp REVISION 42)
     Q_PROPERTY(SomethingEnum eprop READ eprop)
     Q_PROPERTY(SomethingFlagEnum fprop READ fprop)
     Q_PROPERTY(QLocale::Language language READ language)
@@ -124,6 +125,7 @@ public:
 public slots:
     void slot1(const QString&) {}
     void slot2(int, const QString&) {}
+    Q_REVISION(24) void revisionSlot() {}
 
 private slots:
     void slot3() {}
@@ -219,6 +221,7 @@ void tst_QMetaObjectBuilder::method()
     QVERIFY(nullMethod.tag().isEmpty());
     QVERIFY(nullMethod.access() == QMetaMethod::Public);
     QCOMPARE(nullMethod.attributes(), 0);
+    QCOMPARE(nullMethod.revision(), 0);
     QCOMPARE(nullMethod.index(), 0);
 
     // Add a method and check its attributes.
@@ -230,6 +233,7 @@ void tst_QMetaObjectBuilder::method()
     QVERIFY(method1.tag().isEmpty());
     QVERIFY(method1.access() == QMetaMethod::Public);
     QCOMPARE(method1.attributes(), 0);
+    QCOMPARE(method1.revision(), 0);
     QCOMPARE(method1.index(), 0);
     QCOMPARE(builder.methodCount(), 1);
 
@@ -242,6 +246,7 @@ void tst_QMetaObjectBuilder::method()
     QVERIFY(method2.tag().isEmpty());
     QVERIFY(method2.access() == QMetaMethod::Public);
     QCOMPARE(method2.attributes(), 0);
+    QCOMPARE(method2.revision(), 0);
     QCOMPARE(method2.index(), 1);
     QCOMPARE(builder.methodCount(), 2);
 
@@ -256,6 +261,7 @@ void tst_QMetaObjectBuilder::method()
     method1.setTag("tag");
     method1.setAccess(QMetaMethod::Private);
     method1.setAttributes(42);
+    method1.setRevision(123);
 
     // Check that method1 is changed, but method2 is not.
     QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
@@ -265,6 +271,7 @@ void tst_QMetaObjectBuilder::method()
     QCOMPARE(method1.tag(), QByteArray("tag"));
     QVERIFY(method1.access() == QMetaMethod::Private);
     QCOMPARE(method1.attributes(), 42);
+    QCOMPARE(method1.revision(), 123);
     QCOMPARE(method1.index(), 0);
     QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
     QVERIFY(method2.methodType() == QMetaMethod::Method);
@@ -273,6 +280,7 @@ void tst_QMetaObjectBuilder::method()
     QVERIFY(method2.tag().isEmpty());
     QVERIFY(method2.access() == QMetaMethod::Public);
     QCOMPARE(method2.attributes(), 0);
+    QCOMPARE(method2.revision(), 0);
     QCOMPARE(method2.index(), 1);
     QCOMPARE(builder.methodCount(), 2);
 
@@ -282,6 +290,7 @@ void tst_QMetaObjectBuilder::method()
     method2.setTag("Q_FOO");
     method2.setAccess(QMetaMethod::Protected);
     method2.setAttributes(24);
+    method2.setRevision(321);
 
     // This time check that only method2 changed.
     QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
@@ -291,6 +300,7 @@ void tst_QMetaObjectBuilder::method()
     QCOMPARE(method1.tag(), QByteArray("tag"));
     QVERIFY(method1.access() == QMetaMethod::Private);
     QCOMPARE(method1.attributes(), 42);
+    QCOMPARE(method1.revision(), 123);
     QCOMPARE(method1.index(), 0);
     QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
     QVERIFY(method2.methodType() == QMetaMethod::Method);
@@ -299,6 +309,7 @@ void tst_QMetaObjectBuilder::method()
     QCOMPARE(method2.tag(), QByteArray("Q_FOO"));
     QVERIFY(method2.access() == QMetaMethod::Protected);
     QCOMPARE(method2.attributes(), 24);
+    QCOMPARE(method2.revision(), 321);
     QCOMPARE(method2.index(), 1);
     QCOMPARE(builder.methodCount(), 2);
 
@@ -313,6 +324,7 @@ void tst_QMetaObjectBuilder::method()
     QCOMPARE(method2.tag(), QByteArray("Q_FOO"));
     QVERIFY(method2.access() == QMetaMethod::Protected);
     QCOMPARE(method2.attributes(), 24);
+    QCOMPARE(method2.revision(), 321);
     QCOMPARE(method2.index(), 0);
 
     // Perform index-based lookup again.
@@ -542,6 +554,7 @@ void tst_QMetaObjectBuilder::property()
     QVERIFY(!nullProp.isConstant());
     QVERIFY(!nullProp.isFinal());
     QCOMPARE(nullProp.index(), 0);
+    QCOMPARE(nullProp.revision(), 0);
 
     // Add a property and check its attributes.
     QMetaPropertyBuilder prop1 = builder.addProperty("foo", "const QString &");
@@ -560,6 +573,7 @@ void tst_QMetaObjectBuilder::property()
     QVERIFY(!prop1.isEnumOrFlag());
     QVERIFY(!prop1.isConstant());
     QVERIFY(!prop1.isFinal());
+    QCOMPARE(prop1.revision(), 0);
     QCOMPARE(prop1.index(), 0);
     QCOMPARE(builder.propertyCount(), 1);
 
@@ -580,6 +594,7 @@ void tst_QMetaObjectBuilder::property()
     QVERIFY(!prop2.isEnumOrFlag());
     QVERIFY(!prop2.isConstant());
     QVERIFY(!prop2.isFinal());
+    QCOMPARE(prop2.revision(), 0);
     QCOMPARE(prop2.index(), 1);
     QCOMPARE(builder.propertyCount(), 2);
 
@@ -603,6 +618,7 @@ void tst_QMetaObjectBuilder::property()
     prop1.setEnumOrFlag(true);
     prop1.setConstant(true);
     prop1.setFinal(true);
+    prop1.setRevision(123);
 
     // Check that prop1 is changed, but prop2 is not.
     QCOMPARE(prop1.name(), QByteArray("foo"));
@@ -619,6 +635,7 @@ void tst_QMetaObjectBuilder::property()
     QVERIFY(prop1.isEnumOrFlag());
     QVERIFY(prop1.isConstant());
     QVERIFY(prop1.isFinal());
+    QCOMPARE(prop1.revision(), 123);
     QVERIFY(prop2.isReadable());
     QVERIFY(prop2.isWritable());
     QCOMPARE(prop2.name(), QByteArray("bar"));
@@ -633,6 +650,7 @@ void tst_QMetaObjectBuilder::property()
     QVERIFY(!prop2.isEnumOrFlag());
     QVERIFY(!prop2.isConstant());
     QVERIFY(!prop2.isFinal());
+    QCOMPARE(prop2.revision(), 0);
 
     // Remove prop1 and check that prop2 becomes index 0.
     builder.removeProperty(0);
@@ -650,6 +668,7 @@ void tst_QMetaObjectBuilder::property()
     QVERIFY(!prop2.isEnumOrFlag());
     QVERIFY(!prop2.isConstant());
     QVERIFY(!prop2.isFinal());
+    QCOMPARE(prop2.revision(), 0);
     QCOMPARE(prop2.index(), 0);
 
     // Perform index-based lookup again.
@@ -1163,6 +1182,9 @@ static bool sameMethod(const QMetaMethod& method1, const QMetaMethod& method2)
     if (method1.attributes() != method2.attributes())
         return false;
 
+    if (method1.revision() != method2.revision())
+        return false;
+
     return true;
 }
 
@@ -1193,6 +1215,9 @@ static bool sameProperty(const QMetaProperty& prop1, const QMetaProperty& prop2)
             return false;
     }
 
+    if (prop1.revision() != prop2.revision())
+        return false;
+
     return true;
 }
 

From e121d6d7e82067c557bcd2f5f3aed1e6ebc9d3fc Mon Sep 17 00:00:00 2001
From: Kent Hansen 
Date: Sat, 4 Feb 2012 22:51:41 +0100
Subject: [PATCH 234/406] Test template-based connect() with qmetaobjectbuilder

For template-based connect(), the meta-object is resolved at
compile-time (the virtual metaObject() function isn't called).
But we can make it work by copying the members of the dynamically
constructed meta-object to the statically defined one.

Change-Id: Ia4d3263a89008e36e187c584db6d25d9042f32b3
Reviewed-by: Olivier Goffart 
Reviewed-by: Bradley T. Hughes 
---
 .../tst_qmetaobjectbuilder.cpp                | 26 ++++++++++++-------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
index 02c69b9b1bf..97b14a374e8 100644
--- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
+++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
@@ -1341,11 +1341,11 @@ class TestObject : public QObject
     // Manually expanded from Q_OBJECT macro
 public:
     Q_OBJECT_CHECK
+    static QMetaObject staticMetaObject;
     virtual const QMetaObject *metaObject() const;
     virtual void *qt_metacast(const char *);
     virtual int qt_metacall(QMetaObject::Call, int, void **);
 private:
-    Q_DECL_HIDDEN static const QMetaObjectExtraData staticMetaObjectExtraData;
     Q_DECL_HIDDEN static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **);
 
     //Q_PROPERTY(int intProp READ intProp WRITE setIntProp NOTIFY intPropChanged)
@@ -1378,14 +1378,15 @@ private:
     int m_voidSlotIntArg;
 };
 
-const QMetaObjectExtraData TestObject::staticMetaObjectExtraData = {
-    0,  qt_static_metacall
+QMetaObject TestObject::staticMetaObject = {
+    { 0, 0, 0, 0 }
 };
 
 TestObject::TestObject(QObject *parent)
     : QObject(parent), m_metaObject(buildMetaObject()),
       m_intProp(-1), m_voidSlotIntArg(-1)
 {
+    staticMetaObject = *m_metaObject;
 }
 
 TestObject::~TestObject()
@@ -1481,9 +1482,6 @@ void TestObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id,
           }
         }
     } else if (_c == QMetaObject::IndexOfMethod) {
-        // This code is currently unreachable because it's only used by the
-        // template-based versions of connect() and disconnect(), which don't
-        // work with dynamically generated meta-objects (see test).
         int *result = reinterpret_cast(_a[0]);
         void **func = reinterpret_cast(_a[1]);
         {
@@ -1504,7 +1502,6 @@ void TestObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id,
                 *result = 2;
             }
         }
-        qFatal("You forgot to add one or more IndexOfMethod cases");
     }
 }
 
@@ -1668,11 +1665,22 @@ void tst_QMetaObjectBuilder::usage_templateConnect()
 {
     QScopedPointer testObject(new TestObject);
 
-    QTest::ignoreMessage(QtWarningMsg, "QObject::connect: signal not found in QObject");
     QMetaObject::Connection con = QObject::connect(testObject.data(), &TestObject::intPropChanged,
                                                    testObject.data(), &TestObject::voidSlotInt);
-    QEXPECT_FAIL("", "template-based connect() fails because meta-object is deduced at compile-time", Abort);
     QVERIFY(con);
+
+    QVERIFY(testObject->voidSlotIntArgument() == -1);
+    testObject->setProperty("intProp", 123);
+    QCOMPARE(testObject->voidSlotIntArgument(), 123);
+
+    QVERIFY(QObject::disconnect(testObject.data(), &TestObject::intPropChanged,
+                                testObject.data(), &TestObject::voidSlotInt));
+
+    // Something that isn't a signal
+    QTest::ignoreMessage(QtWarningMsg, "QObject::connect: signal not found in TestObject");
+    con = QObject::connect(testObject.data(), &TestObject::setIntProp,
+                           testObject.data(), &TestObject::intPropChanged);
+    QVERIFY(!con);
 }
 
 QTEST_MAIN(tst_QMetaObjectBuilder)

From b9cf3dec9042bc0527e405da2b7f78ebfc561804 Mon Sep 17 00:00:00 2001
From: "Bradley T. Hughes" 
Date: Tue, 14 Feb 2012 11:31:37 +0100
Subject: [PATCH 235/406] tst_QVariant passes on Mac OS X

Do not mark with insignificant_test anymore.

Task-number: QTBUG-22747
Change-Id: I4ef6d5d7e1189b03fd1ab812a0839e3709686e1b
Reviewed-by: Jason McDonald 
---
 tests/auto/corelib/kernel/qvariant/qvariant.pro | 2 --
 1 file changed, 2 deletions(-)

diff --git a/tests/auto/corelib/kernel/qvariant/qvariant.pro b/tests/auto/corelib/kernel/qvariant/qvariant.pro
index 48229ee140b..9b4b346d357 100644
--- a/tests/auto/corelib/kernel/qvariant/qvariant.pro
+++ b/tests/auto/corelib/kernel/qvariant/qvariant.pro
@@ -3,5 +3,3 @@ TARGET = tst_qvariant
 QT += widgets network testlib
 SOURCES = tst_qvariant.cpp
 RESOURCES += qvariant.qrc
-
-mac: CONFIG += insignificant_test # QTBUG-QTBUG-22747

From 752a02143b8b29bfde40d1e70482bc051457f251 Mon Sep 17 00:00:00 2001
From: Teemu Katajisto 
Date: Thu, 9 Feb 2012 10:17:53 +0200
Subject: [PATCH 236/406] Various documentation fixes ported from Qt 4.8

Final set of selected documentation fixes for qtbase
from Qt 4.8 commit bacae725e584f51ee2fd83af7bef3e4515de9587

Task-number: QTBUG-13362
Task-number: QTBUG-18356
Task-number: QTBUG-18417
Task-number: QTBUG-18664
Task-number: QTBUG-21562
Task-number: QTBUG-22094
Task-number: QTBUG-18741
Task-number: QTBUG-15921
Task-number: QTBUG-15738

Change-Id: I3bd33bb7ce7aa991913ba82f3ea0e4b124f3ee41
Reviewed-by: Casper van Donderen 
---
 doc/src/examples/editabletreemodel.qdoc             | 5 +++--
 doc/src/network/files-and-resources/resources.qdoc  | 4 ++--
 doc/src/snippets/code/src_corelib_thread_qmutex.cpp | 4 ++--
 doc/src/sql/sql-programming/sql-driver.qdoc         | 2 +-
 src/corelib/tools/qregexp.cpp                       | 2 +-
 src/network/kernel/qnetworkproxy.cpp                | 6 +++---
 src/widgets/dialogs/qdialog.cpp                     | 6 +++++-
 src/widgets/dialogs/qmessagebox.cpp                 | 3 +++
 src/widgets/kernel/qwidget.cpp                      | 4 ++--
 src/widgets/widgets/qabstractbutton.cpp             | 4 +++-
 src/xml/dom/qdom.cpp                                | 4 ++++
 11 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/doc/src/examples/editabletreemodel.qdoc b/doc/src/examples/editabletreemodel.qdoc
index 20d9efccd70..306295842eb 100644
--- a/doc/src/examples/editabletreemodel.qdoc
+++ b/doc/src/examples/editabletreemodel.qdoc
@@ -48,14 +48,15 @@
     As described in the \l{Model Subclassing Reference}, models must
     provide implementations for the standard set of model functions:
     \l{QAbstractItemModel::}{flags()}, \l{QAbstractItemModel::}{data()},
-    \l{QAbstractItemModel::}{headerData()}, and
+    \l{QAbstractItemModel::}{headerData()},
+    \l{QAbstractItemModel::}{columnCount()}, and
     \l{QAbstractItemModel::}{rowCount()}. In addition, hierarchical models,
     such as this one, need to provide implementations of
     \l{QAbstractItemModel::}{index()} and \l{QAbstractItemModel::}{parent()}.
 
     An editable model needs to provide implementations of
     \l{QAbstractItemModel::}{setData()} and
-    \l{QAbstractItemModel::}{headerData()}, and must return a suitable
+    \l{QAbstractItemModel::}{setHeaderData()}, and must return a suitable
     combination of flags from its \l{QAbstractItemModel::}{flags()} function.
 
     Since this example allows the dimensions of the model to be changed,
diff --git a/doc/src/network/files-and-resources/resources.qdoc b/doc/src/network/files-and-resources/resources.qdoc
index 847f086bee8..1d0fc51631b 100644
--- a/doc/src/network/files-and-resources/resources.qdoc
+++ b/doc/src/network/files-and-resources/resources.qdoc
@@ -101,8 +101,8 @@
     In this case, the file is accessible as \c
     :/myresources/cut-img.png.
 
-    Some resources, such as translation files and icons, many need to
-    change based on the user's locale. This is done by adding a \c lang
+    Some resources need to change based on the user's locale,
+    such as translation files or icons. This is done by adding a \c lang
     attribute to the \c qresource tag, specifying a suitable locale
     string. For example:
 
diff --git a/doc/src/snippets/code/src_corelib_thread_qmutex.cpp b/doc/src/snippets/code/src_corelib_thread_qmutex.cpp
index 84fe348eb24..f5fbeb8419a 100644
--- a/doc/src/snippets/code/src_corelib_thread_qmutex.cpp
+++ b/doc/src/snippets/code/src_corelib_thread_qmutex.cpp
@@ -114,8 +114,8 @@ int complexFunction(int flag)
     switch (flag) {
     case 0:
     case 1:
-        mutex.unlock();
-        return moreComplexFunction(flag);
+        retVal = moreComplexFunction(flag);
+        break;
     case 2:
         {
             int status = anotherFunction();
diff --git a/doc/src/sql/sql-programming/sql-driver.qdoc b/doc/src/sql/sql-programming/sql-driver.qdoc
index 994d31f43f7..667b9eba54e 100644
--- a/doc/src/sql/sql-programming/sql-driver.qdoc
+++ b/doc/src/sql/sql-programming/sql-driver.qdoc
@@ -494,7 +494,7 @@
     \snippet doc/src/snippets/code/doc_src_sql-driver.qdoc 15
 
     Users of MinGW may wish to consult the following online document:
-    \l{Compiling PostgreSQL On Native Win32 FAQ}.
+    \l{PostgreSQL MinGW/Native Windows}.
 
     \bold{Note:} This database plugin is not supported for Windows CE.
 
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
index 054ec1d9f8d..e8c0d4eccc8 100644
--- a/src/corelib/tools/qregexp.cpp
+++ b/src/corelib/tools/qregexp.cpp
@@ -670,7 +670,7 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
 
     Wildcard matching can be convenient because of its simplicity, but
     any wildcard regexp can be defined using full regexps, e.g.
-    \bold{.*\.html$}. Notice that we can't match both \c .html and \c
+    \bold{.*\\.html$}. Notice that we can't match both \c .html and \c
     .htm files with a wildcard unless we use \bold{*.htm*} which will
     also match 'test.html.bak'. A full regexp gives us the precision
     we need, \bold{.*\\.html?$}.
diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp
index 4070c8f0145..295260f7f18 100644
--- a/src/network/kernel/qnetworkproxy.cpp
+++ b/src/network/kernel/qnetworkproxy.cpp
@@ -1440,7 +1440,7 @@ void QNetworkProxyFactory::setApplicationProxyFactory(QNetworkProxyFactory *fact
 /*!
     \fn QList QNetworkProxyFactory::queryProxy(const QNetworkProxyQuery &query)
 
-    This function examines takes the query request, \a query,
+    This function takes the query request, \a query,
     examines the details of the type of socket or request and returns
     a list of QNetworkProxy objects that indicate the proxy servers to
     be used, in order of preference.
@@ -1461,7 +1461,7 @@ void QNetworkProxyFactory::setApplicationProxyFactory(QNetworkProxyFactory *fact
 /*!
     \fn QList QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery &query)
 
-    This function examines takes the query request, \a query,
+    This function takes the query request, \a query,
     examines the details of the type of socket or request and returns
     a list of QNetworkProxy objects that indicate the proxy servers to
     be used, in order of preference.
@@ -1507,7 +1507,7 @@ void QNetworkProxyFactory::setApplicationProxyFactory(QNetworkProxyFactory *fact
 */
 
 /*!
-    This function examines takes the query request, \a query,
+    This function takes the query request, \a query,
     examines the details of the type of socket or request and returns
     a list of QNetworkProxy objects that indicate the proxy servers to
     be used, in order of preference.
diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp
index 861cbf902c9..41683a261be 100644
--- a/src/widgets/dialogs/qdialog.cpp
+++ b/src/widgets/dialogs/qdialog.cpp
@@ -430,7 +430,11 @@ bool QDialog::event(QEvent *e)
 #endif
 
 /*!
-  Returns the modal dialog's result code, \c Accepted or \c Rejected.
+  In general returns the modal dialog's result code, \c Accepted or
+  \c Rejected.
+
+  \note When called on a QMessageBox instance, the returned value is a
+  value of the \l QMessageBox::StandardButton enum.
 
   Do not call this function if the dialog was constructed with the
   Qt::WA_DeleteOnClose attribute.
diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp
index c6ffaa27886..634e911cd14 100644
--- a/src/widgets/dialogs/qmessagebox.cpp
+++ b/src/widgets/dialogs/qmessagebox.cpp
@@ -2597,6 +2597,9 @@ QPixmap QMessageBox::standardIcon(Icon icon)
   When using QMessageBox with custom buttons, this function returns an
   opaque value; use clickedButton() to determine which button was clicked.
 
+  \note The result() function returns also \l StandardButton value instead
+  of \l QDialog::DialogCode.
+
   Users cannot interact with any other window in the same
   application until they close the dialog, either by clicking a
   button or by using a mechanism provided by the window system.
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index cd3669717dd..e3a8908c375 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -3018,8 +3018,8 @@ QList QWidget::actions() const
     \property QWidget::enabled
     \brief whether the widget is enabled
 
-    An enabled widget handles keyboard and mouse events; a disabled
-    widget does not.
+    In general an enabled widget handles keyboard and mouse events; a disabled
+    widget does not. An exception is made with \l{QAbstractButton}.
 
     Some widgets display themselves differently when they are
     disabled. For example a button might draw its label grayed out. If
diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp
index a398cc15679..be250c54e15 100644
--- a/src/widgets/widgets/qabstractbutton.cpp
+++ b/src/widgets/widgets/qabstractbutton.cpp
@@ -115,7 +115,9 @@ Q_WIDGETS_EXPORT extern bool qt_tab_all_widgets;
     checkable buttons can be checked and unchecked (see below).
 
     \o isEnabled() indicates whether the button can be pressed by the
-    user.
+    user. \note As opposed to other widgets, buttons derived from
+    QAbstractButton accepts mouse and context menu events
+    when disabled.
 
     \o setAutoRepeat() sets whether the button will auto-repeat if the
     user holds it down. \l autoRepeatDelay and \l autoRepeatInterval
diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp
index f029b7258e7..1eaa74a7300 100644
--- a/src/xml/dom/qdom.cpp
+++ b/src/xml/dom/qdom.cpp
@@ -6561,6 +6561,10 @@ void QDomDocumentPrivate::saveDocument(QTextStream& s, const int indent, QDomNod
     element is available using documentElement(). The textual
     representation of the document can be obtained using toString().
 
+    \note The DOM tree might end up reserving a lot of memory if the XML
+    document is big. For such documents, the QXmlStreamReader or the
+    QXmlQuery classes might be better solutions.
+
     It is possible to insert a node from another document into the
     document using importNode().
 

From 0f0d8a5a8fecf545cdf58ab50d05253ffd20e90b Mon Sep 17 00:00:00 2001
From: Friedemann Kleint 
Date: Tue, 14 Feb 2012 15:52:49 +0100
Subject: [PATCH 237/406] Stabilize QFileSystemWatcher test.

- Run each test in a temporary directory, avoid writing test
  files in source/build tree and prevents tests being influenced
  by left-overs from previous runs and locks of the application
  on the current directory.
- Modify test to be able to use absolute paths to the temporary
  directory.
- Skip parts of test removeFileAndUnWatch if a race condition
  occurs.

Task-number: QTBUG-24029
Change-Id: I215cc2e0fe6f92d2ffe597b01cdc9c9a39e3c5b4
Reviewed-by: Robin Burchell 
---
 .../qfilesystemwatcher/qfilesystemwatcher.pro |   1 -
 .../tst_qfilesystemwatcher.cpp                | 103 ++++++++++++------
 2 files changed, 69 insertions(+), 35 deletions(-)

diff --git a/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro b/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro
index 043b2b5d1d4..e712a6ad5f5 100644
--- a/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro
+++ b/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro
@@ -4,4 +4,3 @@ QT = core testlib
 SOURCES = tst_qfilesystemwatcher.cpp
 
 mac: CONFIG += insignificant_test # QTBUG-22744
-win32:CONFIG += insignificant_test # QTBUG-24029
diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
index 5e5a99f9371..2635565c2b6 100644
--- a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
+++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
@@ -42,6 +42,7 @@
 
 #include 
 
+#include 
 #include 
 
 #ifdef Q_OS_LINUX
@@ -52,9 +53,15 @@
 # endif
 #endif
 
+/* All tests need to run in temporary directories not used
+ * by the application to avoid non-deterministic failures on Windows
+ * due to locked directories and left-overs from previous tests. */
+
 class tst_QFileSystemWatcher : public QObject
 {
     Q_OBJECT
+public:
+    tst_QFileSystemWatcher();
 
 private slots:
     void basicTest_data();
@@ -75,11 +82,20 @@ private slots:
 
     void removeFileAndUnWatch();
 
-    void cleanup();
-
     void destroyAfterQCoreApplication();
+
+private:
+    QString m_tempDirPattern;
 };
 
+tst_QFileSystemWatcher::tst_QFileSystemWatcher()
+{
+    m_tempDirPattern = QDir::tempPath();
+    if (!m_tempDirPattern.endsWith(QLatin1Char('/')))
+        m_tempDirPattern += QLatin1Char('/');
+    m_tempDirPattern += QStringLiteral("tst_qfilesystemwatcherXXXXXX");
+}
+
 void tst_QFileSystemWatcher::basicTest_data()
 {
     QTest::addColumn("backend");
@@ -92,7 +108,9 @@ void tst_QFileSystemWatcher::basicTest()
     QFETCH(QString, backend);
 
     // create test file
-    QFile testFile("testfile.txt");
+    QTemporaryDir temporaryDirectory(m_tempDirPattern);
+    QVERIFY(temporaryDirectory.isValid());
+    QFile testFile(temporaryDirectory.path() + QStringLiteral("/testfile.txt"));
     testFile.setPermissions(QFile::ReadOwner | QFile::WriteOwner);
     testFile.remove();
     QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
@@ -151,14 +169,16 @@ void tst_QFileSystemWatcher::basicTest()
     QCOMPARE(changedSpy.count(), 0);
 
     // readd the file watch with a relative path
-    QVERIFY(watcher.addPath(testFile.fileName().prepend("./")));
+    const QString relativeTestFileName = QDir::current().relativeFilePath(testFile.fileName());
+    QVERIFY(!relativeTestFileName.isEmpty());
+    QVERIFY(watcher.addPath(relativeTestFileName));
     testFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
     testFile.write(QByteArray("hello multiverse!"));
     testFile.close();
 
     QTRY_VERIFY(changedSpy.count() > 0);
 
-    QVERIFY(watcher.removePath(testFile.fileName().prepend("./")));
+    QVERIFY(watcher.removePath(relativeTestFileName));
 
     changedSpy.clear();
 
@@ -222,15 +242,21 @@ void tst_QFileSystemWatcher::watchDirectory()
 {
     QFETCH(QString, backend);
 
-    QDir().mkdir("testDir");
-    QDir testDir("testDir");
+    QTemporaryDir temporaryDirectory(m_tempDirPattern);
+    QVERIFY(temporaryDirectory.isValid());
+
+    QDir temporaryDir(temporaryDirectory.path());
+    const QString testDirName = QStringLiteral("testDir");
+    QVERIFY(temporaryDir.mkdir(testDirName));
+    QDir testDir = temporaryDir;
+    QVERIFY(testDir.cd(testDirName));
 
     QString testFileName = testDir.filePath("testFile.txt");
     QFile::remove(testFileName);
 
     QFileSystemWatcher watcher;
     watcher.setObjectName(QLatin1String("_qt_autotest_force_engine_") + backend);
-    QVERIFY(watcher.addPath(testDir.dirName()));
+    QVERIFY(watcher.addPath(testDir.absolutePath()));
 
     QSignalSpy changedSpy(&watcher, SIGNAL(directoryChanged(const QString &)));
     QVERIFY(changedSpy.isValid());
@@ -246,7 +272,7 @@ void tst_QFileSystemWatcher::watchDirectory()
     QString fileName;
 
     // remove the watch, should not get notification of a new file
-    QVERIFY(watcher.removePath(testDir.dirName()));
+    QVERIFY(watcher.removePath(testDir.absolutePath()));
     QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
     testFile.close();
 
@@ -256,7 +282,7 @@ void tst_QFileSystemWatcher::watchDirectory()
 
     QCOMPARE(changedSpy.count(), 0);
 
-    QVERIFY(watcher.addPath(testDir.dirName()));
+    QVERIFY(watcher.addPath(testDir.absolutePath()));
 
     // remove the file again, should get a signal from the watcher
     QVERIFY(testFile.remove());
@@ -265,7 +291,7 @@ void tst_QFileSystemWatcher::watchDirectory()
     eventLoop.exec();
 
     // remove the directory, should get a signal from the watcher
-    QVERIFY(QDir().rmdir("testDir"));
+    QVERIFY(temporaryDir.rmdir(testDirName));
 
     // waiting max 5 seconds for notification for directory removal to trigger
 #ifdef Q_OS_WINCE
@@ -276,15 +302,16 @@ void tst_QFileSystemWatcher::watchDirectory()
     QCOMPARE(changedSpy.at(1).count(), 1);
 
     fileName = changedSpy.at(0).at(0).toString();
-    QCOMPARE(fileName, testDir.dirName());
+    QCOMPARE(fileName, testDir.absolutePath());
     fileName = changedSpy.at(1).at(0).toString();
-    QCOMPARE(fileName, testDir.dirName());
+    QCOMPARE(fileName, testDir.absolutePath());
 
     changedSpy.clear();
 
     // recreate the file, we should not get any notification
-    if (!QDir().mkdir("testDir"))
-        QSKIP("Failed to recreate directory, skipping final test.");
+    if (!temporaryDir.mkdir(testDirName))
+        QSKIP(qPrintable(QString::fromLatin1("Failed to recreate directory '%1' under '%2', skipping final test.").
+                         arg(testDirName, temporaryDir.absolutePath())));
 
     // waiting max 5 seconds for notification for dir recreation to trigger
     timer.start(5000);
@@ -292,7 +319,7 @@ void tst_QFileSystemWatcher::watchDirectory()
 
     QCOMPARE(changedSpy.count(), 0);
 
-    QVERIFY(QDir().rmdir("testDir"));
+    QVERIFY(temporaryDir.rmdir(testDirName));
 }
 
 void tst_QFileSystemWatcher::addPath()
@@ -360,8 +387,15 @@ void tst_QFileSystemWatcher::removePaths()
 void tst_QFileSystemWatcher::watchFileAndItsDirectory()
 {
     QFETCH(QString, backend);
-    QDir().mkdir("testDir");
-    QDir testDir("testDir");
+
+    QTemporaryDir temporaryDirectory(m_tempDirPattern);
+    QVERIFY(temporaryDirectory.isValid());
+
+    QDir temporaryDir(temporaryDirectory.path());
+    const QString testDirName = QStringLiteral("testDir");
+    QVERIFY(temporaryDir.mkdir(testDirName));
+    QDir testDir = temporaryDir;
+    QVERIFY(testDir.cd(testDirName));
 
     QString testFileName = testDir.filePath("testFile.txt");
     QString secondFileName = testDir.filePath("testFile2.txt");
@@ -378,7 +412,7 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory()
     QFileSystemWatcher watcher;
     watcher.setObjectName(QLatin1String("_qt_autotest_force_engine_") + backend);
 
-    QVERIFY(watcher.addPath(testDir.dirName()));
+    QVERIFY(watcher.addPath(testDir.absolutePath()));
     QVERIFY(watcher.addPath(testFileName));
 
     QSignalSpy fileChangedSpy(&watcher, SIGNAL(fileChanged(const QString &)));
@@ -443,17 +477,7 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory()
     QCOMPARE(fileChangedSpy.count(), 0);
     QCOMPARE(dirChangedSpy.count(), 1);
 
-    QVERIFY(QDir().rmdir("testDir"));
-}
-
-void tst_QFileSystemWatcher::cleanup()
-{
-    QDir testDir("testDir");
-    QString testFileName = testDir.filePath("testFile.txt");
-    QString secondFileName = testDir.filePath("testFile2.txt");
-    QFile::remove(testFileName);
-    QFile::remove(secondFileName);
-    QDir().rmdir("testDir");
+    QVERIFY(temporaryDir.rmdir(testDirName));
 }
 
 void tst_QFileSystemWatcher::nonExistingFile()
@@ -475,22 +499,33 @@ void tst_QFileSystemWatcher::nonExistingFile()
 
 void tst_QFileSystemWatcher::removeFileAndUnWatch()
 {
-    static const char * const filename = "foo.txt";
+    QTemporaryDir temporaryDirectory(m_tempDirPattern);
+    QVERIFY(temporaryDirectory.isValid());
+
+    const QString filename = temporaryDirectory.path() + QStringLiteral("/foo.txt");
+
     QFileSystemWatcher watcher;
 
     {
         QFile testFile(filename);
-        testFile.open(QIODevice::WriteOnly);
+        QVERIFY2(testFile.open(QIODevice::WriteOnly),
+                 qPrintable(QString::fromLatin1("Cannot open %1 for writing: %2").arg(filename, testFile.errorString())));
         testFile.close();
     }
     QVERIFY(watcher.addPath(filename));
 
     QFile::remove(filename);
-    QVERIFY(watcher.removePath(filename));
+    /* There are potential race conditions here; the watcher thread might remove the file from its list
+     * before the call to watcher.removePath(), which then fails. When that happens, the auto-signal
+     * notification to remove the file from the watcher's main list will not be delivered before the next
+     * event loop such that the call to watcher.addPath() fails since the file is still in the main list. */
+    if (!watcher.removePath(filename))
+        QSKIP("Skipping remaining test due to race condition.");
 
     {
         QFile testFile(filename);
-        testFile.open(QIODevice::WriteOnly);
+        QVERIFY2(testFile.open(QIODevice::WriteOnly),
+                 qPrintable(QString::fromLatin1("Cannot open %1 for writing: %2").arg(filename, testFile.errorString())));
         testFile.close();
     }
     QVERIFY(watcher.addPath(filename));

From b36ece3ff4ee516eab8f0f34c8e7f54d2fcee311 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= 
Date: Tue, 14 Feb 2012 19:43:46 +0100
Subject: [PATCH 238/406] Added support for resetting QOpenGLFramebufferObject
 attachments.

As the documentation says, this can be useful to free or recreate
attachments when needed. For example, it might be useful to free stencil
and depth attachments to free up resources when not rendering to the
framebuffer object.

Change-Id: Ib267024fdd380a788c256eb8fb86e0f8832329e0
Reviewed-by: Kim M. Kalland 
---
 src/gui/opengl/qopenglframebufferobject.cpp | 103 +++++++++++++++-----
 src/gui/opengl/qopenglframebufferobject.h   |   2 +
 src/gui/opengl/qopenglframebufferobject_p.h |   4 +-
 3 files changed, 82 insertions(+), 27 deletions(-)

diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index 5e22554303a..aac6ea05584 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -313,9 +313,8 @@ bool QOpenGLFramebufferObjectFormat::operator!=(const QOpenGLFramebufferObjectFo
     return !(*this == other);
 }
 
-bool QOpenGLFramebufferObjectPrivate::checkFramebufferStatus() const
+bool QOpenGLFramebufferObjectPrivate::checkFramebufferStatus(QOpenGLContext *ctx) const
 {
-    QOpenGLContext *ctx = QOpenGLContext::currentContext();
     if (!ctx)
         return false;   // Context no longer exists.
     GLenum status = ctx->functions()->glCheckFramebufferStatus(GL_FRAMEBUFFER);
@@ -402,8 +401,6 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
 
     GLuint texture = 0;
     GLuint color_buffer = 0;
-    GLuint depth_buffer = 0;
-    GLuint stencil_buffer = 0;
 
     QT_CHECK_GLERROR();
     // init texture
@@ -432,7 +429,7 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
                 target, texture, 0);
 
         QT_CHECK_GLERROR();
-        valid = checkFramebufferStatus();
+        valid = checkFramebufferStatus(ctx);
         glBindTexture(target, 0);
 
         color_buffer = 0;
@@ -458,12 +455,57 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
                                              GL_RENDERBUFFER, color_buffer);
 
         QT_CHECK_GLERROR();
-        valid = checkFramebufferStatus();
+        valid = checkFramebufferStatus(ctx);
 
         if (valid)
             funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
     }
 
+    format.setTextureTarget(target);
+    format.setSamples(int(samples));
+    format.setInternalTextureFormat(internal_format);
+    format.setMipmap(mipmap);
+
+    initAttachments(ctx, attachment);
+
+    funcs.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_func()->current_fbo);
+    if (valid) {
+        fbo_guard = new QOpenGLSharedResourceGuard(ctx, fbo, freeFramebufferFunc);
+        if (color_buffer)
+            color_buffer_guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc);
+        else
+            texture_guard = new QOpenGLSharedResourceGuard(ctx, texture, freeTextureFunc);
+    } else {
+        if (color_buffer)
+            funcs.glDeleteRenderbuffers(1, &color_buffer);
+        else
+            glDeleteTextures(1, &texture);
+        funcs.glDeleteFramebuffers(1, &fbo);
+    }
+    QT_CHECK_GLERROR();
+}
+
+void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment)
+{
+    int samples = format.samples();
+
+    // free existing attachments
+    if (depth_buffer_guard) {
+        funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
+        depth_buffer_guard->free();
+    }
+    if (stencil_buffer_guard) {
+        funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
+        if (stencil_buffer_guard != depth_buffer_guard)
+            stencil_buffer_guard->free();
+    }
+
+    depth_buffer_guard = 0;
+    stencil_buffer_guard = 0;
+
+    GLuint depth_buffer = 0;
+    GLuint stencil_buffer = 0;
+
     // In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a
     // separate stencil buffer is not. On embedded devices however, a combined depth-stencil buffer
     // might not be supported while separate buffers are, according to QTBUG-12861.
@@ -488,7 +530,7 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
         funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
                                      GL_RENDERBUFFER, stencil_buffer);
 
-        valid = checkFramebufferStatus();
+        valid = checkFramebufferStatus(ctx);
         if (!valid) {
             funcs.glDeleteRenderbuffers(1, &depth_buffer);
             stencil_buffer = depth_buffer = 0;
@@ -529,7 +571,7 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
         }
         funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                                      GL_RENDERBUFFER, depth_buffer);
-        valid = checkFramebufferStatus();
+        valid = checkFramebufferStatus(ctx);
         if (!valid) {
             funcs.glDeleteRenderbuffers(1, &depth_buffer);
             depth_buffer = 0;
@@ -559,7 +601,7 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
         }
         funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
                                   GL_RENDERBUFFER, stencil_buffer);
-        valid = checkFramebufferStatus();
+        valid = checkFramebufferStatus(ctx);
         if (!valid) {
             funcs.glDeleteRenderbuffers(1, &stencil_buffer);
             stencil_buffer = 0;
@@ -567,7 +609,7 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
     }
 
     // The FBO might have become valid after removing the depth or stencil buffer.
-    valid = checkFramebufferStatus();
+    valid = checkFramebufferStatus(ctx);
 
     if (depth_buffer && stencil_buffer) {
         fbo_attachment = QOpenGLFramebufferObject::CombinedDepthStencil;
@@ -577,13 +619,7 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
         fbo_attachment = QOpenGLFramebufferObject::NoAttachment;
     }
 
-    funcs.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_func()->current_fbo);
     if (valid) {
-        fbo_guard = new QOpenGLSharedResourceGuard(ctx, fbo, freeFramebufferFunc);
-        if (color_buffer)
-            color_buffer_guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc);
-        else
-            texture_guard = new QOpenGLSharedResourceGuard(ctx, texture, freeTextureFunc);
         if (depth_buffer)
             depth_buffer_guard = new QOpenGLSharedResourceGuard(ctx, depth_buffer, freeRenderbufferFunc);
         if (stencil_buffer) {
@@ -593,23 +629,14 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
                 stencil_buffer_guard = new QOpenGLSharedResourceGuard(ctx, stencil_buffer, freeRenderbufferFunc);
         }
     } else {
-        if (color_buffer)
-            funcs.glDeleteRenderbuffers(1, &color_buffer);
-        else
-            glDeleteTextures(1, &texture);
         if (depth_buffer)
             funcs.glDeleteRenderbuffers(1, &depth_buffer);
         if (stencil_buffer && depth_buffer != stencil_buffer)
             funcs.glDeleteRenderbuffers(1, &stencil_buffer);
-        funcs.glDeleteFramebuffers(1, &fbo);
     }
     QT_CHECK_GLERROR();
 
-    format.setTextureTarget(target);
-    format.setSamples(int(samples));
     format.setAttachment(fbo_attachment);
-    format.setInternalTextureFormat(internal_format);
-    format.setMipmap(mipmap);
 }
 
 /*!
@@ -861,7 +888,7 @@ bool QOpenGLFramebufferObject::bind()
         qWarning("QOpenGLFramebufferObject::bind() called from incompatible context");
 #endif
     d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo());
-    d->valid = d->checkFramebufferStatus();
+    d->valid = d->checkFramebufferStatus(current);
     if (d->valid && current)
         current->d_func()->current_fbo = d->fbo();
     return d->valid;
@@ -1107,6 +1134,30 @@ QOpenGLFramebufferObject::Attachment QOpenGLFramebufferObject::attachment() cons
     return NoAttachment;
 }
 
+/*!
+    Sets the attachments of the framebuffer object.
+
+    This can be used to free or reattach the depth and stencil buffer
+    attachments as needed.
+ */
+void QOpenGLFramebufferObject::setAttachment(QOpenGLFramebufferObject::Attachment attachment)
+{
+    Q_D(QOpenGLFramebufferObject);
+    if (attachment == d->fbo_attachment || !isValid())
+        return;
+    QOpenGLContext *current = QOpenGLContext::currentContext();
+    if (!current)
+        return;
+#ifdef QT_DEBUG
+    if (current->shareGroup() != d->fbo_guard->group())
+        qWarning("QOpenGLFramebufferObject::setAttachment() called from incompatible context");
+#endif
+    d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo());
+    d->initAttachments(current, attachment);
+    if (current->d_func()->current_fbo != d->fbo())
+        d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, current->d_func()->current_fbo);
+}
+
 /*!
     Returns true if the framebuffer object is currently bound to a context,
     otherwise false is returned.
diff --git a/src/gui/opengl/qopenglframebufferobject.h b/src/gui/opengl/qopenglframebufferobject.h
index 0b2ead1cbbf..63260f1940f 100644
--- a/src/gui/opengl/qopenglframebufferobject.h
+++ b/src/gui/opengl/qopenglframebufferobject.h
@@ -101,6 +101,8 @@ public:
     QImage toImage() const;
     Attachment attachment() const;
 
+    void setAttachment(Attachment attachment);
+
     GLuint handle() const;
 
     static bool bindDefault();
diff --git a/src/gui/opengl/qopenglframebufferobject_p.h b/src/gui/opengl/qopenglframebufferobject_p.h
index 78d9d93ffe1..23cab8f0afb 100644
--- a/src/gui/opengl/qopenglframebufferobject_p.h
+++ b/src/gui/opengl/qopenglframebufferobject_p.h
@@ -120,7 +120,9 @@ public:
               QOpenGLFramebufferObject::Attachment attachment,
               GLenum internal_format, GLenum texture_target,
               GLint samples = 0, bool mipmap = false);
-    bool checkFramebufferStatus() const;
+    void initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment);
+
+    bool checkFramebufferStatus(QOpenGLContext *ctx) const;
     QOpenGLSharedResourceGuard *fbo_guard;
     QOpenGLSharedResourceGuard *texture_guard;
     QOpenGLSharedResourceGuard *depth_buffer_guard;

From b8342ad6fd1ab3363baf3468173aa9bcdf0616eb Mon Sep 17 00:00:00 2001
From: Andy Shaw 
Date: Tue, 14 Feb 2012 16:39:08 +0100
Subject: [PATCH 239/406] Remove a couple of QtGui/QtGui header entries
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Removed a couple of header entries since they were causing build
problems on Mac.  Additionally it is a bit much to include QtGui/QtGui
in a private header file.  Added in an include to QCache and QGradient
which was necessary afterwards.

Change-Id: I442efc799a4c81b50ec30d58f1aedfb08e686fcb
Reviewed-by: Samuel Rødal 
---
 src/gui/opengl/qopenglgradientcache_p.h | 2 +-
 src/gui/opengl/qopengltexturecache_p.h  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/gui/opengl/qopenglgradientcache_p.h b/src/gui/opengl/qopenglgradientcache_p.h
index 4035689abd8..7acc8c1d9d0 100644
--- a/src/gui/opengl/qopenglgradientcache_p.h
+++ b/src/gui/opengl/qopenglgradientcache_p.h
@@ -52,9 +52,9 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
+#include 
 
 QT_BEGIN_NAMESPACE
 
diff --git a/src/gui/opengl/qopengltexturecache_p.h b/src/gui/opengl/qopengltexturecache_p.h
index 549a2f4eab7..8ff20e94643 100644
--- a/src/gui/opengl/qopengltexturecache_p.h
+++ b/src/gui/opengl/qopengltexturecache_p.h
@@ -55,7 +55,7 @@
 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 

From e452923f1effdfd015ca32b8830b9ddfda696570 Mon Sep 17 00:00:00 2001
From: Kim Motoyoshi Kalland 
Date: Wed, 15 Feb 2012 12:45:08 +0100
Subject: [PATCH 240/406] Corrected the size of mipmaps in framebuffer objects.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Change-Id: Ia3c0daefc6537b12be7f9072e7defc0631794690
Reviewed-by: Samuel Rødal 
---
 src/gui/opengl/qopenglframebufferobject.cpp | 4 ++--
 src/opengl/qglframebufferobject.cpp         | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index aac6ea05584..0eb264b2d9d 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -414,8 +414,8 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
             int height = size.height();
             int level = 0;
             while (width > 1 || height > 1) {
-                width = (width + 1) >> 1;
-                height = (height + 1) >> 1;
+                width = qMax(1, width >> 1);
+                height = qMax(1, height >> 1);
                 ++level;
                 glTexImage2D(target, level, internal_format, width, height, 0,
                         GL_RGBA, GL_UNSIGNED_BYTE, NULL);
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 96479e189e6..21b3abfdd89 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -459,8 +459,8 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
             int height = size.height();
             int level = 0;
             while (width > 1 || height > 1) {
-                width = (width + 1) >> 1;
-                height = (height + 1) >> 1;
+                width = qMax(1, width >> 1);
+                height = qMax(1, height >> 1);
                 ++level;
                 glTexImage2D(target, level, internal_format, width, height, 0,
                         GL_RGBA, GL_UNSIGNED_BYTE, NULL);

From ded417b75a95cb5e3622f95d41f81c024aa532fb Mon Sep 17 00:00:00 2001
From: Kent Hansen 
Date: Mon, 13 Feb 2012 11:48:03 +0100
Subject: [PATCH 241/406] Add autotest for QMetaMethod introspection
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This autotest checks that meta-methods can be properly inspected
(signature, return type, parameter types, etc.).

Change-Id: I13dc75ec5123280e94ec738dade3f54e427fdbaa
Reviewed-by: Olivier Goffart 
Reviewed-by: João Abecasis 
Reviewed-by: Bradley T. Hughes 
---
 tests/auto/corelib/kernel/kernel.pro          |   1 +
 .../kernel/qmetamethod/qmetamethod.pro        |   5 +
 .../kernel/qmetamethod/tst_qmetamethod.cpp    | 615 ++++++++++++++++++
 3 files changed, 621 insertions(+)
 create mode 100644 tests/auto/corelib/kernel/qmetamethod/qmetamethod.pro
 create mode 100644 tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp

diff --git a/tests/auto/corelib/kernel/kernel.pro b/tests/auto/corelib/kernel/kernel.pro
index 1020899d943..7ec01d4a360 100644
--- a/tests/auto/corelib/kernel/kernel.pro
+++ b/tests/auto/corelib/kernel/kernel.pro
@@ -6,6 +6,7 @@ SUBDIRS=\
     qmath \
     qmetaobject \
     qmetaobjectbuilder \
+    qmetamethod \
     qmetaproperty \
     qmetatype \
     qmimedata \
diff --git a/tests/auto/corelib/kernel/qmetamethod/qmetamethod.pro b/tests/auto/corelib/kernel/qmetamethod/qmetamethod.pro
new file mode 100644
index 00000000000..f9097427487
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetamethod/qmetamethod.pro
@@ -0,0 +1,5 @@
+CONFIG += testcase
+TARGET = tst_qmetamethod
+QT = core testlib
+SOURCES = tst_qmetamethod.cpp
+macx:CONFIG -= app_bundle
diff --git a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp
new file mode 100644
index 00000000000..cb34d411fd3
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp
@@ -0,0 +1,615 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the test suite 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 
+
+#include 
+#include 
+
+class tst_QMetaMethod : public QObject
+{
+    Q_OBJECT
+
+private slots:
+    void method_data();
+    void method();
+};
+
+struct CustomType { };
+Q_DECLARE_METATYPE(CustomType)
+
+struct CustomUnregisteredType { };
+
+Q_DECLARE_METATYPE(QMetaMethod::Access)
+Q_DECLARE_METATYPE(QMetaMethod::MethodType)
+
+class MethodTestObject : public QObject
+{
+    Q_OBJECT
+public:
+    Q_INVOKABLE MethodTestObject();
+    Q_INVOKABLE MethodTestObject(int constructorIntArg);
+    Q_INVOKABLE MethodTestObject(qreal constructorQRealArg);
+    Q_INVOKABLE MethodTestObject(const QString &constructorQStringArg);
+    Q_INVOKABLE MethodTestObject(CustomType constructorCustomTypeArg);
+    Q_INVOKABLE MethodTestObject(CustomUnregisteredType constructorCustomUnregisteredTypeArg);
+    Q_INVOKABLE MethodTestObject(bool boolArg, int intArg, uint uintArg,
+                                 qlonglong longlongArg, qulonglong ulonglongArg,
+                                 double doubleArg, long longArg, short shortArg,
+                                 char charArg, ulong ulongArg, ushort ushortArg,
+                                 uchar ucharArg, float floatArg);
+    Q_INVOKABLE MethodTestObject(bool, int);
+
+    Q_INVOKABLE void voidInvokable();
+    Q_INVOKABLE void voidInvokableInt(int voidInvokableIntArg);
+    Q_INVOKABLE void voidInvokableQReal(qreal voidInvokableQRealArg);
+    Q_INVOKABLE void voidInvokableQString(const QString &voidInvokableQStringArg);
+    Q_INVOKABLE void voidInvokableCustomType(CustomType voidInvokableCustomTypeArg);
+    Q_INVOKABLE void voidInvokableCustomUnregisteredType(CustomUnregisteredType voidInvokableCustomUnregisteredTypeArg);
+    Q_INVOKABLE bool boolInvokable();
+    Q_INVOKABLE qreal qrealInvokable();
+    Q_INVOKABLE QString qstringInvokable();
+    Q_INVOKABLE CustomType customTypeInvokable();
+    Q_INVOKABLE CustomUnregisteredType customUnregisteredTypeInvokable();
+    Q_INVOKABLE QVariant qvariantInvokableBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat(
+        bool boolArg, int intArg, uint uintArg, qlonglong longlongArg, qulonglong ulonglongArg, double doubleArg,
+        long longArg, short shortArg, char charArg, ulong ulongArg, ushort ushortArg, uchar ucharArg, float floatArg);
+    Q_INVOKABLE void voidInvokableNoParameterNames(bool, int);
+public slots:
+    void voidSlot();
+    void voidSlotInt(int voidSlotIntArg);
+    void voidSlotQReal(qreal voidSlotQRealArg);
+    void voidSlotQString(const QString &voidSlotQStringArg);
+    void voidSlotCustomType(CustomType voidSlotCustomTypeArg);
+    void voidSlotCustomUnregisteredType(CustomUnregisteredType voidSlotCustomUnregisteredTypeArg);
+    bool boolSlot();
+    qreal qrealSlot();
+    QString qstringSlot();
+    CustomType customTypeSlot();
+    CustomUnregisteredType customUnregisteredTypeSlot();
+    QVariant qvariantSlotBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat(
+        bool boolArg, int intArg, uint uintArg, qlonglong longlongArg, qulonglong ulonglongArg, double doubleArg,
+        long longArg, short shortArg, char charArg, ulong ulongArg, ushort ushortArg, uchar ucharArg, float floatArg);
+    void voidSlotNoParameterNames(bool, int);
+signals:
+    void voidSignal();
+    void voidSignalInt(int voidSignalIntArg);
+    void voidSignalQReal(qreal voidSignalQRealArg);
+    void voidSignalQString(const QString &voidSignalQStringArg);
+    void voidSignalCustomType(CustomType voidSignalCustomTypeArg);
+    void voidSignalCustomUnregisteredType(CustomUnregisteredType voidSignalCustomUnregisteredTypeArg);
+    bool boolSignal();
+    qreal qrealSignal();
+    QString qstringSignal();
+    CustomType customTypeSignal();
+    CustomUnregisteredType customUnregisteredTypeSignal();
+    QVariant qvariantSignalBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat(
+        bool boolArg, int intArg, uint uintArg, qlonglong longlongArg, qulonglong ulonglongArg, double doubleArg,
+        long longArg, short shortArg, char charArg, ulong ulongArg, ushort ushortArg, uchar ucharArg, float floatArg);
+    void voidSignalNoParameterNames(bool, int);
+};
+
+MethodTestObject::MethodTestObject() {}
+MethodTestObject::MethodTestObject(int) {}
+MethodTestObject::MethodTestObject(qreal) {}
+MethodTestObject::MethodTestObject(const QString &) {}
+MethodTestObject::MethodTestObject(CustomType) {}
+MethodTestObject::MethodTestObject(CustomUnregisteredType) {}
+MethodTestObject::MethodTestObject(bool, int, uint, qlonglong, qulonglong,
+                                   double, long, short, char, ulong, ushort,
+                                   uchar, float) {}
+MethodTestObject::MethodTestObject(bool, int) {}
+
+void MethodTestObject::voidInvokable() {}
+void MethodTestObject::voidInvokableInt(int) {}
+void MethodTestObject::voidInvokableQReal(qreal) {}
+void MethodTestObject::voidInvokableQString(const QString &) {}
+void MethodTestObject::voidInvokableCustomType(CustomType) {}
+void MethodTestObject::voidInvokableCustomUnregisteredType(CustomUnregisteredType) {}
+bool MethodTestObject::boolInvokable() { return true; }
+qreal MethodTestObject::qrealInvokable() { return 1.0; }
+QString MethodTestObject::qstringInvokable() { return QString(); }
+CustomType MethodTestObject::customTypeInvokable() { return CustomType(); }
+CustomUnregisteredType MethodTestObject::customUnregisteredTypeInvokable()
+{
+    return CustomUnregisteredType();
+}
+QVariant MethodTestObject::qvariantInvokableBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat(
+    bool, int, uint, qlonglong, qulonglong, double, long, short, char, ulong, ushort, uchar, float)
+{
+    return QVariant();
+}
+void MethodTestObject::voidInvokableNoParameterNames(bool, int) {}
+
+void MethodTestObject::voidSlot() {}
+void MethodTestObject::voidSlotInt(int) {}
+void MethodTestObject::voidSlotQReal(qreal) {}
+void MethodTestObject::voidSlotQString(const QString &) {}
+void MethodTestObject::voidSlotCustomType(CustomType) {}
+void MethodTestObject::voidSlotCustomUnregisteredType(CustomUnregisteredType) {}
+bool MethodTestObject::boolSlot() { return true; }
+qreal MethodTestObject::qrealSlot() { return 1.0; }
+QString MethodTestObject::qstringSlot() { return QString(); }
+CustomType MethodTestObject::customTypeSlot() { return CustomType(); }
+CustomUnregisteredType MethodTestObject::customUnregisteredTypeSlot()
+{
+    return CustomUnregisteredType();
+}
+QVariant MethodTestObject::qvariantSlotBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat(
+    bool, int, uint, qlonglong, qulonglong, double, long, short, char, ulong, ushort, uchar, float)
+{
+    return QVariant();
+}
+void MethodTestObject::voidSlotNoParameterNames(bool, int) {}
+
+void tst_QMetaMethod::method_data()
+{
+    QTest::addColumn("signature");
+    QTest::addColumn("returnType");
+    QTest::addColumn("returnTypeName");
+    QTest::addColumn >("parameterTypes");
+    QTest::addColumn >("parameterTypeNames");
+    QTest::addColumn >("parameterNames");
+    QTest::addColumn("access");
+    QTest::addColumn("methodType");
+
+    QTest::newRow("voidSignal")
+            << QByteArray("voidSignal()")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList())
+            << (QList())
+            << (QList())
+            << QMetaMethod::Protected
+            << QMetaMethod::Signal;
+
+    QTest::newRow("voidInvokable")
+            << QByteArray("voidInvokable()")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList())
+            << (QList())
+            << (QList())
+            << QMetaMethod::Public
+            << QMetaMethod::Method;
+
+    QTest::newRow("voidSlot")
+            << QByteArray("voidSlot()")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList())
+            << (QList())
+            << (QList())
+            << QMetaMethod::Public
+            << QMetaMethod::Slot;
+
+    QTest::newRow("MethodTestObject()")
+            << QByteArray("MethodTestObject()")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList())
+            << (QList())
+            << (QList())
+            << QMetaMethod::Public
+            << QMetaMethod::Constructor;
+
+    QTest::newRow("voidSignalInt")
+            << QByteArray("voidSignalInt(int)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << int(QMetaType::Int))
+            << (QList() << QByteArray("int"))
+            << (QList() << QByteArray("voidSignalIntArg"))
+            << QMetaMethod::Protected
+            << QMetaMethod::Signal;
+
+    QTest::newRow("voidInvokableInt")
+            << QByteArray("voidInvokableInt(int)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << int(QMetaType::Int))
+            << (QList() << QByteArray("int"))
+            << (QList() << QByteArray("voidInvokableIntArg"))
+            << QMetaMethod::Public
+            << QMetaMethod::Method;
+
+    QTest::newRow("voidSlotInt")
+            << QByteArray("voidSlotInt(int)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << int(QMetaType::Int))
+            << (QList() << QByteArray("int"))
+            << (QList() << QByteArray("voidSlotIntArg"))
+            << QMetaMethod::Public
+            << QMetaMethod::Slot;
+
+    QTest::newRow("MethodTestObject(int)")
+            << QByteArray("MethodTestObject(int)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << int(QMetaType::Int))
+            << (QList() << QByteArray("int"))
+            << (QList() << QByteArray("constructorIntArg"))
+            << QMetaMethod::Public
+            << QMetaMethod::Constructor;
+
+    QTest::newRow("voidSignalQReal")
+            << QByteArray("voidSignalQReal(qreal)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << qMetaTypeId())
+            << (QList() << QByteArray("qreal"))
+            << (QList() << QByteArray("voidSignalQRealArg"))
+            << QMetaMethod::Protected
+            << QMetaMethod::Signal;
+
+    QTest::newRow("voidInvokableQReal")
+            << QByteArray("voidInvokableQReal(qreal)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << qMetaTypeId())
+            << (QList() << QByteArray("qreal"))
+            << (QList() << QByteArray("voidInvokableQRealArg"))
+            << QMetaMethod::Public
+            << QMetaMethod::Method;
+
+    QTest::newRow("voidSlotQReal")
+            << QByteArray("voidSlotQReal(qreal)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << qMetaTypeId())
+            << (QList() << QByteArray("qreal"))
+            << (QList() << QByteArray("voidSlotQRealArg"))
+            << QMetaMethod::Public
+            << QMetaMethod::Slot;
+
+    QTest::newRow("MethodTestObject(qreal)")
+            << QByteArray("MethodTestObject(qreal)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << qMetaTypeId())
+            << (QList() << QByteArray("qreal"))
+            << (QList() << QByteArray("constructorQRealArg"))
+            << QMetaMethod::Public
+            << QMetaMethod::Constructor;
+
+    QTest::newRow("voidSignalQString")
+            << QByteArray("voidSignalQString(QString)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << int(QMetaType::QString))
+            << (QList() << QByteArray("QString"))
+            << (QList() << QByteArray("voidSignalQStringArg"))
+            << QMetaMethod::Protected
+            << QMetaMethod::Signal;
+
+    QTest::newRow("voidInvokableQString")
+            << QByteArray("voidInvokableQString(QString)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << int(QMetaType::QString))
+            << (QList() << QByteArray("QString"))
+            << (QList() << QByteArray("voidInvokableQStringArg"))
+            << QMetaMethod::Public
+            << QMetaMethod::Method;
+
+    QTest::newRow("voidSlotQString")
+            << QByteArray("voidSlotQString(QString)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << int(QMetaType::QString))
+            << (QList() << QByteArray("QString"))
+            << (QList() << QByteArray("voidSlotQStringArg"))
+            << QMetaMethod::Public
+            << QMetaMethod::Slot;
+
+    QTest::newRow("MethodTestObject(QString)")
+            << QByteArray("MethodTestObject(QString)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << int(QMetaType::QString))
+            << (QList() << QByteArray("QString"))
+            << (QList() << QByteArray("constructorQStringArg"))
+            << QMetaMethod::Public
+            << QMetaMethod::Constructor;
+
+    QTest::newRow("voidSignalCustomType")
+            << QByteArray("voidSignalCustomType(CustomType)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << qMetaTypeId())
+            << (QList() << QByteArray("CustomType"))
+            << (QList() << QByteArray("voidSignalCustomTypeArg"))
+            << QMetaMethod::Protected
+            << QMetaMethod::Signal;
+
+    QTest::newRow("voidInvokableCustomType")
+            << QByteArray("voidInvokableCustomType(CustomType)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << qMetaTypeId())
+            << (QList() << QByteArray("CustomType"))
+            << (QList() << QByteArray("voidInvokableCustomTypeArg"))
+            << QMetaMethod::Public
+            << QMetaMethod::Method;
+
+    QTest::newRow("voidSlotCustomType")
+            << QByteArray("voidSlotCustomType(CustomType)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << qMetaTypeId())
+            << (QList() << QByteArray("CustomType"))
+            << (QList() << QByteArray("voidSlotCustomTypeArg"))
+            << QMetaMethod::Public
+            << QMetaMethod::Slot;
+
+    QTest::newRow("MethodTestObject(CustomType)")
+            << QByteArray("MethodTestObject(CustomType)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << qMetaTypeId())
+            << (QList() << QByteArray("CustomType"))
+            << (QList() << QByteArray("constructorCustomTypeArg"))
+            << QMetaMethod::Public
+            << QMetaMethod::Constructor;
+
+    QTest::newRow("voidSignalCustomUnregisteredType")
+            << QByteArray("voidSignalCustomUnregisteredType(CustomUnregisteredType)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << 0)
+            << (QList() << QByteArray("CustomUnregisteredType"))
+            << (QList() << QByteArray("voidSignalCustomUnregisteredTypeArg"))
+            << QMetaMethod::Protected
+            << QMetaMethod::Signal;
+
+    QTest::newRow("voidInvokableCustomUnregisteredType")
+            << QByteArray("voidInvokableCustomUnregisteredType(CustomUnregisteredType)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << 0)
+            << (QList() << QByteArray("CustomUnregisteredType"))
+            << (QList() << QByteArray("voidInvokableCustomUnregisteredTypeArg"))
+            << QMetaMethod::Public
+            << QMetaMethod::Method;
+
+    QTest::newRow("voidSlotCustomUnregisteredType")
+            << QByteArray("voidSlotCustomUnregisteredType(CustomUnregisteredType)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << 0)
+            << (QList() << QByteArray("CustomUnregisteredType"))
+            << (QList() << QByteArray("voidSlotCustomUnregisteredTypeArg"))
+            << QMetaMethod::Public
+            << QMetaMethod::Slot;
+
+    QTest::newRow("MethodTestObject(CustomUnregisteredType)")
+            << QByteArray("MethodTestObject(CustomUnregisteredType)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << 0)
+            << (QList() << QByteArray("CustomUnregisteredType"))
+            << (QList() << QByteArray("constructorCustomUnregisteredTypeArg"))
+            << QMetaMethod::Public
+            << QMetaMethod::Constructor;
+
+    QTest::newRow("boolSignal")
+            << QByteArray("boolSignal()")
+            << int(QMetaType::Bool) << QByteArray("bool")
+            << (QList())
+            << (QList())
+            << (QList())
+            << QMetaMethod::Protected
+            << QMetaMethod::Signal;
+
+    QTest::newRow("boolInvokable")
+            << QByteArray("boolInvokable()")
+            << int(QMetaType::Bool) << QByteArray("bool")
+            << (QList())
+            << (QList())
+            << (QList())
+            << QMetaMethod::Public
+            << QMetaMethod::Method;
+
+    QTest::newRow("boolSlot")
+            << QByteArray("boolSlot()")
+            << int(QMetaType::Bool) << QByteArray("bool")
+            << (QList())
+            << (QList())
+            << (QList())
+            << QMetaMethod::Public
+            << QMetaMethod::Slot;
+
+    QTest::newRow("qrealSignal")
+            << QByteArray("qrealSignal()")
+            << int(QMetaType::QReal) << QByteArray("qreal")
+            << (QList())
+            << (QList())
+            << (QList())
+            << QMetaMethod::Protected
+            << QMetaMethod::Signal;
+
+    QTest::newRow("qrealInvokable")
+            << QByteArray("qrealInvokable()")
+            << int(QMetaType::QReal) << QByteArray("qreal")
+            << (QList())
+            << (QList())
+            << (QList())
+            << QMetaMethod::Public
+            << QMetaMethod::Method;
+
+    QTest::newRow("qrealSlot")
+            << QByteArray("qrealSlot()")
+            << int(QMetaType::QReal) << QByteArray("qreal")
+            << (QList())
+            << (QList())
+            << (QList())
+            << QMetaMethod::Public
+            << QMetaMethod::Slot;
+
+    QTest::newRow("qstringSignal")
+            << QByteArray("qstringSignal()")
+            << int(QMetaType::QString) << QByteArray("QString")
+            << (QList())
+            << (QList())
+            << (QList())
+            << QMetaMethod::Protected
+            << QMetaMethod::Signal;
+
+    QTest::newRow("qstringInvokable")
+            << QByteArray("qstringInvokable()")
+            << int(QMetaType::QString) << QByteArray("QString")
+            << (QList())
+            << (QList())
+            << (QList())
+            << QMetaMethod::Public
+            << QMetaMethod::Method;
+
+    QTest::newRow("qstringSlot")
+            << QByteArray("qstringSlot()")
+            << int(QMetaType::QString) << QByteArray("QString")
+            << (QList())
+            << (QList())
+            << (QList())
+            << QMetaMethod::Public
+            << QMetaMethod::Slot;
+
+    {
+        QList parameterTypes = QList()
+                << int(QMetaType::Bool) << int(QMetaType::Int) << int(QMetaType::UInt)
+                << int(QMetaType::LongLong) << int(QMetaType::ULongLong) << int(QMetaType::Double)
+                << int(QMetaType::Long) << int(QMetaType::Short) << int(QMetaType::Char)
+                << int(QMetaType::ULong) << int(QMetaType::UShort) << int(QMetaType::UChar)
+                << int(QMetaType::Float);
+        QList parameterTypeNames = QList()
+                << QByteArray("bool") << QByteArray("int") << QByteArray("uint")
+                << QByteArray("qlonglong") << QByteArray("qulonglong") << QByteArray("double")
+                << QByteArray("long") << QByteArray("short") << QByteArray("char") << QByteArray("ulong")
+                << QByteArray("ushort") << QByteArray("uchar") << QByteArray("float");
+        QList parameterNames = QList()
+                << QByteArray("boolArg") << QByteArray("intArg") << QByteArray("uintArg")
+                << QByteArray("longlongArg") << QByteArray("ulonglongArg") << QByteArray("doubleArg")
+                << QByteArray("longArg") << QByteArray("shortArg") << QByteArray("charArg")
+                << QByteArray("ulongArg") << QByteArray("ushortArg") << QByteArray("ucharArg")
+                << QByteArray("floatArg");
+
+        QTest::newRow("qvariantSignalBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat")
+                << QByteArray("qvariantSignalBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat("
+                              "bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)")
+                << int(QMetaType::QVariant) << QByteArray("QVariant")
+                << parameterTypes << parameterTypeNames << parameterNames
+                << QMetaMethod::Protected
+                << QMetaMethod::Signal;
+
+        QTest::newRow("qvariantInvokableBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat")
+                << QByteArray("qvariantInvokableBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat("
+                              "bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)")
+                << int(QMetaType::QVariant) << QByteArray("QVariant")
+                << parameterTypes << parameterTypeNames << parameterNames
+                << QMetaMethod::Public
+                << QMetaMethod::Method;
+
+        QTest::newRow("qvariantSlotBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat")
+                << QByteArray("qvariantSlotBoolIntUIntLonglongULonglongDoubleLongShortCharUlongUshortUcharFloat("
+                              "bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)")
+                << int(QMetaType::QVariant) << QByteArray("QVariant")
+                << parameterTypes << parameterTypeNames << parameterNames
+                << QMetaMethod::Public
+                << QMetaMethod::Slot;
+
+        QTest::newRow("MethodTestObject(bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)")
+                << QByteArray("MethodTestObject(bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)")
+                << int(QMetaType::Void) << QByteArray("")
+                << parameterTypes << parameterTypeNames << parameterNames
+                << QMetaMethod::Public
+                << QMetaMethod::Constructor;
+    }
+
+    QTest::newRow("voidSignalNoParameterNames")
+            << QByteArray("voidSignalNoParameterNames(bool,int)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << int(QMetaType::Bool) << int(QMetaType::Int))
+            << (QList() << QByteArray("bool") << QByteArray("int"))
+            << (QList() << QByteArray("") << QByteArray(""))
+            << QMetaMethod::Protected
+            << QMetaMethod::Signal;
+
+    QTest::newRow("voidInvokableNoParameterNames")
+            << QByteArray("voidInvokableNoParameterNames(bool,int)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << int(QMetaType::Bool) << int(QMetaType::Int))
+            << (QList() << QByteArray("bool") << QByteArray("int"))
+            << (QList() << QByteArray("") << QByteArray(""))
+            << QMetaMethod::Public
+            << QMetaMethod::Method;
+
+    QTest::newRow("voidSlotNoParameterNames")
+            << QByteArray("voidSlotNoParameterNames(bool,int)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << int(QMetaType::Bool) << int(QMetaType::Int))
+            << (QList() << QByteArray("bool") << QByteArray("int"))
+            << (QList() << QByteArray("") << QByteArray(""))
+            << QMetaMethod::Public
+            << QMetaMethod::Slot;
+
+    QTest::newRow("MethodTestObject(bool,int)")
+            << QByteArray("MethodTestObject(bool,int)")
+            << int(QMetaType::Void) << QByteArray("")
+            << (QList() << int(QMetaType::Bool) << int(QMetaType::Int))
+            << (QList() << QByteArray("bool") << QByteArray("int"))
+            << (QList() << QByteArray("") << QByteArray(""))
+            << QMetaMethod::Public
+            << QMetaMethod::Constructor;
+}
+
+void tst_QMetaMethod::method()
+{
+    QFETCH(QByteArray, signature);
+    QFETCH(int, returnType);
+    QFETCH(QByteArray, returnTypeName);
+    QFETCH(QList, parameterTypes);
+    QFETCH(QList, parameterTypeNames);
+    QFETCH(QList, parameterNames);
+    QFETCH(QMetaMethod::MethodType, methodType);
+    QFETCH(QMetaMethod::Access, access);
+
+    QVERIFY(parameterTypes.size() == parameterTypeNames.size());
+    QVERIFY(parameterTypes.size() == parameterNames.size());
+
+    const QMetaObject *mo = &MethodTestObject::staticMetaObject;
+    int index = (methodType == QMetaMethod::Constructor)
+                ? mo->indexOfConstructor(signature) : mo->indexOfMethod(signature);
+    QVERIFY(index != -1);
+    QMetaMethod method = (methodType == QMetaMethod::Constructor)
+                         ? mo->constructor(index) : mo->method(index);
+    QCOMPARE(method.methodType(), methodType);
+    QCOMPARE(method.access(), access);
+
+    QCOMPARE(method.signature(), signature.constData());
+
+    QCOMPARE(method.tag(), "");
+
+    QCOMPARE(method.typeName(), returnTypeName.constData());
+    QCOMPARE(QMetaType::type(method.typeName()), returnType);
+
+    QCOMPARE(method.parameterTypes(), parameterTypeNames);
+    QCOMPARE(method.parameterNames(), parameterNames);
+}
+
+QTEST_MAIN(tst_QMetaMethod)
+#include "tst_qmetamethod.moc"

From 556dd0228aca07dfe8443fd99e9f2ead4e13ab22 Mon Sep 17 00:00:00 2001
From: Lars Knoll 
Date: Mon, 6 Feb 2012 10:36:48 +0100
Subject: [PATCH 242/406] Add JSON support to the bootstrap library
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The JSON support will get used in moc to support
the creation of plugin metadata that's embedded
into the plugin itself.

Change-Id: I3bc52b16ca0a43bc8bf9141b450045c6183b7823
Reviewed-by: João Abecasis 
Reviewed-by: Bradley T. Hughes 
Reviewed-by: Thiago Macieira 
---
 src/corelib/json/qjsonarray.h     | 1 +
 src/corelib/json/qjsonobject.h    | 1 +
 src/corelib/plugin/quuid.cpp      | 8 +++++++-
 src/corelib/plugin/quuid.h        | 3 ++-
 src/tools/bootstrap/bootstrap.pri | 2 +-
 src/tools/bootstrap/bootstrap.pro | 9 +++++++++
 6 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/src/corelib/json/qjsonarray.h b/src/corelib/json/qjsonarray.h
index 8bb1ac0b512..83b07e33c94 100644
--- a/src/corelib/json/qjsonarray.h
+++ b/src/corelib/json/qjsonarray.h
@@ -43,6 +43,7 @@
 #define QJSONARRAY_H
 
 #include 
+#include 
 
 QT_BEGIN_HEADER
 
diff --git a/src/corelib/json/qjsonobject.h b/src/corelib/json/qjsonobject.h
index d2831a3cea7..973a01585bd 100644
--- a/src/corelib/json/qjsonobject.h
+++ b/src/corelib/json/qjsonobject.h
@@ -43,6 +43,7 @@
 #define QJSONOBJECT_H
 
 #include 
+#include 
 
 QT_BEGIN_HEADER
 
diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp
index 7b1c682e21a..3d7988a8fca 100644
--- a/src/corelib/plugin/quuid.cpp
+++ b/src/corelib/plugin/quuid.cpp
@@ -45,6 +45,9 @@
 #include "qendian.h"
 #include "qdebug.h"
 
+#ifndef QT_BOOTSTRAPPED
+#include "qcryptographichash.h"
+#endif
 QT_BEGIN_NAMESPACE
 
 #ifndef QT_NO_QUUID_STRING
@@ -133,6 +136,7 @@ bool _q_uuidFromHex(const Char *&src, uint &d1, ushort &d2, ushort &d3, uchar (&
 }
 #endif
 
+#ifndef QT_BOOTSTRAPPED
 static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCryptographicHash::Algorithm algorithm, int version)
 {
     QByteArray hashResult;
@@ -155,6 +159,7 @@ static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCrypto
 
     return result;
 }
+#endif
 
 /*!
     \class QUuid
@@ -437,7 +442,7 @@ QUuid::QUuid(const QByteArray &text)
 
   \sa variant(), version(), createUuidV3()
 */
-
+#ifndef QT_BOOTSTRAPPED
 QUuid QUuid::createUuidV3(const QUuid &ns, const QByteArray &baseData)
 {
     return createFromName(ns, baseData, QCryptographicHash::Md5, 3);
@@ -447,6 +452,7 @@ QUuid QUuid::createUuidV5(const QUuid &ns, const QByteArray &baseData)
 {
     return createFromName(ns, baseData, QCryptographicHash::Sha1, 5);
 }
+#endif
 
 /*!
   Creates a QUuid object from the binary representation of the UUID, as
diff --git a/src/corelib/plugin/quuid.h b/src/corelib/plugin/quuid.h
index a55d6af3eba..dee97d93a57 100644
--- a/src/corelib/plugin/quuid.h
+++ b/src/corelib/plugin/quuid.h
@@ -43,7 +43,6 @@
 #define QUUID_H
 
 #include 
-#include 
 
 QT_BEGIN_HEADER
 
@@ -175,6 +174,7 @@ public:
     }
 #endif
     static QUuid createUuid();
+#ifndef QT_BOOTSTRAPPED
     static QUuid createUuidV3(const QUuid &ns, const QByteArray &baseData);
     static QUuid createUuidV5(const QUuid &ns, const QByteArray &baseData);
 #ifndef QT_NO_QUUID_STRING
@@ -188,6 +188,7 @@ public:
         return QUuid::createUuidV5(ns, baseData.toUtf8());
     }
 
+#endif
 #endif
 
     QUuid::Variant variant() const;
diff --git a/src/tools/bootstrap/bootstrap.pri b/src/tools/bootstrap/bootstrap.pri
index 8a368cb228b..e34cc5c0330 100644
--- a/src/tools/bootstrap/bootstrap.pri
+++ b/src/tools/bootstrap/bootstrap.pri
@@ -60,7 +60,7 @@ hpux-acc*|hpuxi-acc* {
     else:if(unix|win32-g++*):LIBS_PRIVATE += -lz
     else:LIBS += zdll.lib
 }
-win32:LIBS += -luser32
+win32:LIBS += -luser32 -lole32
 
 mac {
     CONFIG -= incremental
diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro
index fdf41c55c24..1d641d23018 100644
--- a/src/tools/bootstrap/bootstrap.pro
+++ b/src/tools/bootstrap/bootstrap.pro
@@ -43,6 +43,7 @@ DEPENDPATH += $$INCLUDEPATH \
               ../../corelib/tools \
               ../../corelib/io \
               ../../corelib/codecs \
+              ../../corelib/json \
               ../../xml
 
 SOURCES += \
@@ -72,6 +73,7 @@ SOURCES += \
            ../../corelib/kernel/qmetatype.cpp \
            ../../corelib/kernel/qvariant.cpp \
            ../../corelib/kernel/qsystemerror.cpp \
+           ../../corelib/plugin/quuid.cpp \
            ../../corelib/tools/qbitarray.cpp \
            ../../corelib/tools/qbytearray.cpp \
            ../../corelib/tools/qbytearraymatcher.cpp \
@@ -88,6 +90,13 @@ SOURCES += \
            ../../corelib/tools/qvsnprintf.cpp \
            ../../corelib/xml/qxmlutils.cpp \
            ../../corelib/xml/qxmlstream.cpp \
+           ../../corelib/json/qjson.cpp \
+           ../../corelib/json/qjsondocument.cpp \
+           ../../corelib/json/qjsonobject.cpp \
+           ../../corelib/json/qjsonarray.cpp \
+           ../../corelib/json/qjsonvalue.cpp \
+           ../../corelib/json/qjsonparser.cpp \
+           ../../corelib/json/qjsonwriter.cpp \
            ../../xml/dom/qdom.cpp \
            ../../xml/sax/qxml.cpp
 

From 7184456f9a26a9c07a689c15b415ddf82eb000b7 Mon Sep 17 00:00:00 2001
From: Lars Knoll 
Date: Mon, 6 Feb 2012 23:36:17 +0100
Subject: [PATCH 243/406] Implement new plugin mechanism
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

moc can now embed meta information about the plugin
inside the plugin itself. This information can
be queried by Qt without having to load the plugin.

Source compatibility with the old plugin loading
mechanism is still there, but will be removed before
Qt 5.0.

Change-Id: I03e4196ddfed07d0fe94acca40d5de8a6ce7f920
Reviewed-by: João Abecasis 
Reviewed-by: Thiago Macieira 
---
 src/corelib/kernel/qobjectdefs.h         |   1 +
 src/corelib/plugin/qelfparser_p.cpp      |   4 +-
 src/corelib/plugin/qelfparser_p.h        |   2 +-
 src/corelib/plugin/qfactoryloader.cpp    | 157 +++++++++--
 src/corelib/plugin/qfactoryloader_p.h    |   9 +-
 src/corelib/plugin/qlibrary.cpp          | 171 +++++++++---
 src/corelib/plugin/qlibrary_p.h          |  19 +-
 src/corelib/plugin/qplugin.h             |  84 ++++--
 src/corelib/plugin/qpluginloader.cpp     |  29 +-
 src/corelib/plugin/qpluginloader.h       |   3 +-
 src/tools/moc/generator.cpp              |  48 ++++
 src/tools/moc/generator.h                |   1 +
 src/tools/moc/keywords.cpp               | 334 ++++++++++++-----------
 src/tools/moc/moc.cpp                    |  52 ++++
 src/tools/moc/moc.h                      |  10 +-
 src/tools/moc/token.h                    |   1 +
 src/tools/moc/util/generate_keywords.cpp |   1 +
 17 files changed, 653 insertions(+), 273 deletions(-)

diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index 315619761c0..0b1fa8839f8 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -76,6 +76,7 @@ class QString;
 # define emit
 #endif
 #define Q_CLASSINFO(name, value)
+#define Q_PLUGIN_METADATA(x)
 #define Q_INTERFACES(x)
 #define Q_PROPERTY(text)
 #define Q_PRIVATE_PROPERTY(d, text)
diff --git a/src/corelib/plugin/qelfparser_p.cpp b/src/corelib/plugin/qelfparser_p.cpp
index 0e8d43454cf..70abbaf6e11 100644
--- a/src/corelib/plugin/qelfparser_p.cpp
+++ b/src/corelib/plugin/qelfparser_p.cpp
@@ -203,7 +203,7 @@ int QElfParser::parse(const char *dataStart, ulong fdlen, const QString &library
         qDebug() << "++++" << i << shnam;
 #endif
 
-        if (qstrcmp(shnam, ".qtplugin") == 0 || qstrcmp(shnam, ".rodata") == 0) {
+        if (qstrcmp(shnam, ".qtmetadata") == 0 || qstrcmp(shnam, ".qtplugin") == 0 || qstrcmp(shnam, ".rodata") == 0) {
             if (!(sh.type & 0x1)) {
                 if (shnam[1] == 'r') {
                     if (lib)
@@ -227,7 +227,7 @@ int QElfParser::parse(const char *dataStart, ulong fdlen, const QString &library
             *pos = sh.offset;
             *sectionlen = sh.size - 1;
             if (shnam[1] == 'q')
-                return Ok;
+                return shnam[3] == 'm' ? QtMetaDataSection : QtPluginSection;
         }
         s += e_shentsize;
     }
diff --git a/src/corelib/plugin/qelfparser_p.h b/src/corelib/plugin/qelfparser_p.h
index 96e1eac33f6..afd81121380 100644
--- a/src/corelib/plugin/qelfparser_p.h
+++ b/src/corelib/plugin/qelfparser_p.h
@@ -72,7 +72,7 @@ typedef quintptr qelfaddr_t;
 class QElfParser
 {
 public:
-    enum {Ok = 0, NotElf = 1, NoQtSection = 2, Corrupt = 3};
+    enum { QtMetaDataSection, QtPluginSection, NoQtSection, NotElf, Corrupt };
     enum {ElfLittleEndian = 0, ElfBigEndian = 1};
 
     struct ElfSectionHeader
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index fe5aea0e8a9..ce988fa2ff9 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -51,6 +51,10 @@
 #include "qpluginloader.h"
 #include "private/qobject_p.h"
 #include "private/qcoreapplication_p.h"
+#include "qjsondocument.h"
+#include "qjsonvalue.h"
+#include "qjsonobject.h"
+#include "qjsonarray.h"
 
 QT_BEGIN_NAMESPACE
 
@@ -137,29 +141,44 @@ void QFactoryLoader::update()
                 continue;
             }
             QStringList keys;
-            if (!library->loadPlugin()) {
-                if (qt_debug_component()) {
-                    qDebug() << library->errorString;
-                    qDebug() << "           could not load";
+            if (library->compatPlugin) {
+                qWarning() << "Compat plugin, need to load for accessing meta data";
+                if (!library->loadPlugin()) {
+                    if (qt_debug_component()) {
+                        qDebug() << library->errorString;
+                        qDebug() << "           could not load";
+                    }
+                    library->release();
+                    continue;
                 }
-                library->release();
-                continue;
+
+                if (!library->inst)
+                    library->inst = library->instance();
+                QObject *instance = library->inst.data();
+                if (!instance) {
+                    library->release();
+                    // ignore plugins that have a valid signature but cannot be loaded.
+                    continue;
+                }
+                QFactoryInterface *factory = qobject_cast(instance);
+                if (instance && factory && instance->qt_metacast(d->iid))
+                    keys = factory->keys();
+            } else {
+                QString iid = library->metaData.value(QLatin1String("IID")).toString();
+                if (iid == QLatin1String(d->iid.constData(), d->iid.size())) {
+                    QJsonObject object = library->metaData.value(QLatin1String("MetaData")).toObject();
+                    QJsonArray k = object.value(QLatin1String("Keys")).toArray();
+                    for (int i = 0; i < k.size(); ++i) {
+                        QString s = k.at(i).toString();
+                        keys += s;
+                    }
+                }
+                if (qt_debug_component())
+                    qDebug() << "Got keys from plugin meta data" << keys;
             }
 
-            if (!library->inst)
-                library->inst = library->instance();
-            QObject *instance = library->inst.data();
-            if (!instance) {
-                library->release();
-                // ignore plugins that have a valid signature but cannot be loaded.
-                continue;
-            }
-            QFactoryInterface *factory = qobject_cast(instance);
-            if (instance && factory && instance->qt_metacast(d->iid))
-                keys = factory->keys();
-            if (keys.isEmpty())
-                library->unload();
             if (keys.isEmpty()) {
+                library->unload();
                 library->release();
                 continue;
             }
@@ -173,7 +192,12 @@ void QFactoryLoader::update()
                 if (!d->cs)
                     key = key.toLower();
                 QLibraryPrivate *previous = d->keyMap.value(key);
-                if (!previous || (previous->qt_version > QT_VERSION && library->qt_version <= QT_VERSION)) {
+                int prev_qt_version = 0;
+                if (previous) {
+                    prev_qt_version = (int)previous->metaData.value(QLatin1String("version")).toDouble();
+                }
+                int qt_version = (int)library->metaData.value(QLatin1String("version")).toDouble();
+                if (!previous || (prev_qt_version > QT_VERSION && qt_version <= QT_VERSION)) {
                     d->keyMap[key] = library;
                     d->keyList += keys.at(k);
                 }
@@ -200,23 +224,76 @@ QStringList QFactoryLoader::keys() const
     Q_D(const QFactoryLoader);
     QMutexLocker locker(&d->mutex);
     QStringList keys = d->keyList;
-    QObjectList instances = QPluginLoader::staticInstances();
-    for (int i = 0; i < instances.count(); ++i)
-        if (QFactoryInterface *factory = qobject_cast(instances.at(i)))
-            if (instances.at(i)->qt_metacast(d->iid))
-                keys += factory->keys();
+    QVector staticPlugins = QLibraryPrivate::staticPlugins();
+    for (int i = 0; i < staticPlugins.count(); ++i) {
+        if (staticPlugins.at(i).metaData) {
+            const char *rawMetaData = staticPlugins.at(i).metaData();
+            QJsonObject object = QLibraryPrivate::fromRawMetaData(rawMetaData).object();
+            if (object.value(QLatin1String("IID")) != QLatin1String(d->iid.constData(), d->iid.size()))
+                continue;
+
+            QJsonObject meta = object.value(QLatin1String("MetaData")).toObject();
+            QJsonArray a = meta.value(QLatin1String("Keys")).toArray();
+            for (int i = 0; i < a.size(); ++i) {
+                QString s = a.at(i).toString();
+                if (!s.isEmpty())
+                    keys += s;
+            }
+        } else {
+            // compat plugin
+            QObject *instance = staticPlugins.at(i).instance();
+            QFactoryInterface *factory = qobject_cast(instance);
+            if (instance && factory && instance->qt_metacast(d->iid))
+                keys = factory->keys();
+        }
+    }
     return keys;
 }
 
+QList QFactoryLoader::metaData() const
+{
+    Q_D(const QFactoryLoader);
+    QMutexLocker locker(&d->mutex);
+    QList metaData;
+    for (int i = 0; i < d->libraryList.size(); ++i)
+        metaData.append(d->libraryList.at(i)->metaData);
+
+    QVector staticPlugins = QLibraryPrivate::staticPlugins();
+    for (int i = 0; i < staticPlugins.count(); ++i) {
+        if (staticPlugins.at(i).metaData) {
+            const char *rawMetaData = staticPlugins.at(i).metaData();
+            QJsonObject object = QLibraryPrivate::fromRawMetaData(rawMetaData).object();
+            if (object.value(QLatin1String("IID")) != QLatin1String(d->iid.constData(), d->iid.size()))
+                continue;
+
+            QJsonObject meta = object.value(QLatin1String("MetaData")).toObject();
+            metaData.append(meta);
+        } else {
+            // compat plugins
+            QObject *instance = staticPlugins.at(i).instance();
+            QFactoryInterface *factory = qobject_cast(instance);
+            if (instance && factory && instance->qt_metacast(d->iid)) {
+                QJsonObject meta;
+                QJsonArray a = QJsonArray::fromStringList(factory->keys());
+                meta.insert(QLatin1String("Keys"), a);
+                metaData.append(meta);
+            }
+        }
+    }
+    return metaData;
+}
+
 QObject *QFactoryLoader::instance(const QString &key) const
 {
     Q_D(const QFactoryLoader);
     QMutexLocker locker(&d->mutex);
-    QObjectList instances = QPluginLoader::staticInstances();
-    for (int i = 0; i < instances.count(); ++i)
-        if (QFactoryInterface *factory = qobject_cast(instances.at(i)))
-            if (instances.at(i)->qt_metacast(d->iid) && factory->keys().contains(key, Qt::CaseInsensitive))
-                return instances.at(i);
+    QVector staticPlugins = QLibraryPrivate::staticPlugins();
+    for (int i = 0; i < staticPlugins.count(); ++i) {
+        QObject *instance = staticPlugins.at(i).instance();
+        if (QFactoryInterface *factory = qobject_cast(instance))
+            if (instance->qt_metacast(d->iid) && factory->keys().contains(key, Qt::CaseInsensitive))
+                return instance;
+    }
 
     QString lowered = d->cs ? key : key.toLower();
     if (QLibraryPrivate* library = d->keyMap.value(lowered)) {
@@ -234,6 +311,26 @@ QObject *QFactoryLoader::instance(const QString &key) const
     return 0;
 }
 
+QObject *QFactoryLoader::instance(int index) const
+{
+    Q_D(const QFactoryLoader);
+    if (index < 0 || index >= d->libraryList.size())
+        return 0;
+
+    QLibraryPrivate *library = d->libraryList.at(index);
+    if (library->instance || library->loadPlugin()) {
+        if (!library->inst)
+            library->inst = library->instance();
+        QObject *obj = library->inst.data();
+        if (obj) {
+            if (!obj->parent())
+                obj->moveToThread(QCoreApplicationPrivate::mainThread());
+            return obj;
+        }
+    }
+    return 0;
+}
+
 #if defined(Q_OS_UNIX) && !defined (Q_OS_MAC)
 QLibraryPrivate *QFactoryLoader::library(const QString &key) const
 {
diff --git a/src/corelib/plugin/qfactoryloader_p.h b/src/corelib/plugin/qfactoryloader_p.h
index 2241a22e5f9..ee7a68d6f89 100644
--- a/src/corelib/plugin/qfactoryloader_p.h
+++ b/src/corelib/plugin/qfactoryloader_p.h
@@ -55,8 +55,8 @@
 
 #include "QtCore/qobject.h"
 #include "QtCore/qstringlist.h"
+#include "QtCore/qjsonobject.h"
 #include "private/qlibrary_p.h"
-
 #ifndef QT_NO_LIBRARY
 
 QT_BEGIN_NAMESPACE
@@ -74,8 +74,11 @@ public:
                    Qt::CaseSensitivity = Qt::CaseSensitive);
     ~QFactoryLoader();
 
-    QStringList keys() const;
-    QObject *instance(const QString &key) const;
+    QT_DEPRECATED QStringList keys() const;
+    QList metaData() const;
+
+    QT_DEPRECATED QObject *instance(const QString &key) const;
+    QObject *instance(int index) const;
 
 #if defined(Q_OS_UNIX) && !defined (Q_OS_MAC)
     QLibraryPrivate *library(const QString &key) const;
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index dc08b32db18..b171577184e 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -60,6 +60,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include "qelfparser_p.h"
 
 QT_BEGIN_NAMESPACE
@@ -330,7 +333,7 @@ static long qt_find_pattern(const char *s, ulong s_len,
                 information could not be read.
   Returns  true if version information is present and successfully read.
 */
-static bool qt_unix_query(const QString &library, uint *version, bool *debug, QLibraryPrivate *lib = 0)
+static bool qt_unix_query(const QString &library, QLibraryPrivate *lib)
 {
     QFile file(library);
     if (!file.open(QIODevice::ReadOnly)) {
@@ -357,35 +360,71 @@ static bool qt_unix_query(const QString &library, uint *version, bool *debug, QL
     /*
        ELF binaries on GNU, have .qplugin sections.
     */
+    bool hasMetaData = false;
     long pos = 0;
-    const char pattern[] = "pattern=QT_PLUGIN_VERIFICATION_DATA";
+    const char oldPattern[] = "pattern=QT_PLUGIN_VERIFICATION_DATA";
+    const ulong oldPlen = qstrlen(oldPattern);
+    const char pattern[] = "QTMETADATA  ";
     const ulong plen = qstrlen(pattern);
 #if defined (Q_OF_ELF) && defined(Q_CC_GNU)
     int r = QElfParser().parse(filedata, fdlen, library, lib, &pos, &fdlen);
-    if (r == QElfParser::NoQtSection) {
+    if (r == QElfParser::Corrupt || r == QElfParser::NotElf) {
+            if (lib && qt_debug_component()) {
+                qWarning("QElfParser: %s",qPrintable(lib->errorString));
+            }
+            return false;
+    } else if (r == QElfParser::NoQtSection || r == QElfParser::QtPluginSection) {
         if (pos > 0) {
             // find inside .rodata
-            long rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen);
+            long rel = qt_find_pattern(filedata + pos, fdlen, oldPattern, oldPlen);
             if (rel < 0) {
                 pos = -1;
             } else {
                 pos += rel;
             }
         } else {
-            pos = qt_find_pattern(filedata, fdlen, pattern, plen);
+            pos = qt_find_pattern(filedata, fdlen, oldPattern, oldPlen);
         }
-    } else if (r != QElfParser::Ok) {
-        if (lib && qt_debug_component()) {
-            qWarning("QElfParser: %s",qPrintable(lib->errorString));
-        }
-        return false;
+    } else if (r == QElfParser::QtMetaDataSection) {
+        long rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen);
+        if (rel < 0)
+            pos = -1;
+        else
+            pos += rel;
+        hasMetaData = true;
     }
 #else
     pos = qt_find_pattern(filedata, fdlen, pattern, plen);
+    if (pos > 0)
+        hasMetaData = true;
+    else
+        pos = qt_find_pattern(filedata, fdlen, oldPattern, oldPlen);
 #endif // defined(Q_OF_ELF) && defined(Q_CC_GNU)
+
     bool ret = false;
-    if (pos >= 0)
-        ret = qt_parse_pattern(filedata + pos, version, debug);
+
+    if (pos >= 0) {
+        if (hasMetaData) {
+            const char *data = filedata + pos;
+            QJsonDocument doc = QLibraryPrivate::fromRawMetaData(data);
+            lib->metaData = doc.object();
+            lib->compatPlugin = false;
+            if (qt_debug_component())
+                qWarning("Found metadata in lib %s, metadata=\n%s\n",
+                         library.toLocal8Bit().constData(), doc.toJson().constData());
+            ret = !doc.isNull();
+        } else {
+            qWarning("Old plugin format found in lib %s", library.toLocal8Bit().constData());
+            uint version;
+            bool isDebug;
+            ret = qt_parse_pattern(filedata + pos, &version, &isDebug);
+            if (ret) {
+                lib->metaData.insert(QLatin1String("version"), (int)version);
+                lib->metaData.insert(QLatin1String("debug"), isDebug);
+                lib->compatPlugin = true;
+            }
+        }
+    }
 
     if (!ret && lib)
         lib->errorString = QLibrary::tr("Plugin verification data mismatch in '%1'").arg(library);
@@ -446,8 +485,9 @@ static LibraryMap *libraryMap()
 }
 
 QLibraryPrivate::QLibraryPrivate(const QString &canonicalFileName, const QString &version)
-    :pHnd(0), fileName(canonicalFileName), fullVersion(version), instance(0), qt_version(0),
-     libraryRefCount(1), libraryUnloadCount(0), pluginState(MightBeAPlugin)
+    : pHnd(0), fileName(canonicalFileName), fullVersion(version), instance(0),
+      compatPlugin(false), loadHints(0),
+      libraryRefCount(1), libraryUnloadCount(0), pluginState(MightBeAPlugin)
 { libraryMap()->insert(canonicalFileName, this); }
 
 QLibraryPrivate *QLibraryPrivate::findOrCreate(const QString &fileName, const QString &version)
@@ -488,6 +528,8 @@ bool QLibraryPrivate::load()
         return false;
 
     bool ret = load_sys();
+    if (qt_debug_component())
+        qDebug() << "loaded library" << fileName;
     if (ret) {
         //when loading a library we add a reference to it so that the QLibraryPrivate won't get deleted
         //this allows to unload the library at a later time
@@ -643,13 +685,9 @@ const char* qt_try_versioninfo(void *pfn, bool *exceptionThrown)
 }
 #endif
 
-#ifdef Q_CC_BOR
-typedef const char * __stdcall (*QtPluginQueryVerificationDataFunction)();
-#else
 typedef const char * (*QtPluginQueryVerificationDataFunction)();
-#endif
 
-bool qt_get_verificationdata(QtPluginQueryVerificationDataFunction pfn, uint *qt_version, bool *debug, bool *exceptionThrown)
+bool qt_get_verificationdata(QtPluginQueryVerificationDataFunction pfn, QLibraryPrivate *priv, bool *exceptionThrown)
 {
     *exceptionThrown = false;
     const char *szData = 0;
@@ -662,9 +700,41 @@ bool qt_get_verificationdata(QtPluginQueryVerificationDataFunction pfn, uint *qt
 #else
     szData = pfn();
 #endif
-    return qt_parse_pattern(szData, qt_version, debug);
+    uint qt_version;
+    bool debug;
+    if (qt_parse_pattern(szData, &qt_version, &debug)) {
+        priv->metaData.insert(QLatin1String("version"), (int)qt_version);
+        priv->metaData.insert(QLatin1String("debug"), debug);
+        priv->compatPlugin = true;
+        return true;
+    }
+    return false;
 }
 
+bool qt_get_metadata(QtPluginQueryVerificationDataFunction pfn, QLibraryPrivate *priv, bool *exceptionThrown)
+{
+    *exceptionThrown = false;
+    const char *szData = 0;
+    if (!pfn)
+        return false;
+#ifdef QT_USE_MS_STD_EXCEPTION
+    szData = qt_try_versioninfo((void *)pfn, exceptionThrown);
+    if (*exceptionThrown)
+        return false;
+#else
+    szData = pfn();
+#endif
+    if (!szData)
+        return false;
+    QJsonDocument doc = QLibraryPrivate::fromRawMetaData(szData);
+    if (doc.isNull())
+        return false;
+    priv->metaData = doc.object();
+    priv->compatPlugin = false;
+    return true;
+}
+
+
 bool QLibraryPrivate::isPlugin()
 {
     errorString.clear();
@@ -672,7 +742,6 @@ bool QLibraryPrivate::isPlugin()
         return pluginState == IsAPlugin;
 
 #ifndef QT_NO_PLUGIN_CHECK
-    bool debug = !QLIBRARY_AS_DEBUG;
     bool success = false;
 
 #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
@@ -692,7 +761,7 @@ bool QLibraryPrivate::isPlugin()
 #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
     if (!pHnd) {
         // use unix shortcut to avoid loading the library
-        success = qt_unix_query(fileName, &qt_version, &debug, this);
+        success = qt_unix_query(fileName, this);
     } else
 #endif
     {
@@ -713,24 +782,50 @@ bool QLibraryPrivate::isPlugin()
                 temporary_load =  load_sys();
 #endif
             }
-#ifdef Q_OS_WIN
-            QtPluginQueryVerificationDataFunction qtPluginQueryVerificationDataFunction = hTempModule ? (QtPluginQueryVerificationDataFunction)
-#ifdef Q_OS_WINCE
-                    ::GetProcAddress(hTempModule, L"qt_plugin_query_verification_data")
-#else
-                    ::GetProcAddress(hTempModule, "qt_plugin_query_verification_data")
-#endif
-                    : (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data");
-#else
-            QtPluginQueryVerificationDataFunction qtPluginQueryVerificationDataFunction = NULL;
-            qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data");
-#endif
+            QtPluginQueryVerificationDataFunction getMetaData = NULL;
+
             bool exceptionThrown = false;
-            bool ret = qt_get_verificationdata(qtPluginQueryVerificationDataFunction,
-                                               &qt_version, &debug, &exceptionThrown);
+            bool ret = false;
+#ifdef Q_OS_WIN
+            if (hTempModule) {
+                getMetaData = (QtPluginQueryVerificationDataFunction)
+#ifdef Q_OS_WINCE
+                    ::GetProcAddress(hTempModule, L"qt_plugin_query_metadata")
+#else
+                    ::GetProcAddress(hTempModule, "qt_plugin_query_metadata")
+#endif
+                        ;
+            } else
+#endif
+            {
+                getMetaData = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_metadata");
+            }
+
+            if (getMetaData) {
+                ret = qt_get_metadata(getMetaData, this, &exceptionThrown);
+            } else {
+                // try the old plugin style
+                QtPluginQueryVerificationDataFunction qtPluginQueryVerificationDataFunction = NULL;
+#ifdef Q_OS_WIN
+                if (hTempModule) {
+                    qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction)
+#ifdef Q_OS_WINCE
+                        ::GetProcAddress(hTempModule, L"qt_plugin_query_verification_data")
+#else
+                        ::GetProcAddress(hTempModule, "qt_plugin_query_verification_data")
+#endif
+                            ;
+                } else
+#endif
+                {
+                    qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data");
+                }
+
+                ret = qt_get_verificationdata(qtPluginQueryVerificationDataFunction, this, &exceptionThrown);
+            }
+
             if (!exceptionThrown) {
                 if (!ret) {
-                    qt_version = 0;
                     if (temporary_load)
                         unload_sys();
                 } else {
@@ -772,6 +867,8 @@ bool QLibraryPrivate::isPlugin()
 
     pluginState = IsNotAPlugin; // be pessimistic
 
+    uint qt_version = (uint)metaData.value(QLatin1String("version")).toDouble();
+    bool debug = metaData.value(QLatin1String("debug")).toBool();
     if ((qt_version & 0x00ff00) > (QT_VERSION & 0x00ff00) || (qt_version & 0xff0000) != (QT_VERSION & 0xff0000)) {
         if (qt_debug_component()) {
             qWarning("In %s:\n"
diff --git a/src/corelib/plugin/qlibrary_p.h b/src/corelib/plugin/qlibrary_p.h
index a5f366070ce..604a5fbddee 100644
--- a/src/corelib/plugin/qlibrary_p.h
+++ b/src/corelib/plugin/qlibrary_p.h
@@ -58,6 +58,9 @@
 #include "QtCore/qstringlist.h"
 #include "QtCore/qplugin.h"
 #include "QtCore/qsharedpointer.h"
+#include "QtCore/qjsonobject.h"
+#include "QtCore/qjsondocument.h"
+#include "QtCore/qendian.h"
 #ifdef Q_OS_WIN
 #  include "QtCore/qt_windows.h"
 #endif
@@ -90,16 +93,26 @@ public:
 
     static QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version = QString());
 
+    static QVector staticPlugins();
+
+
     QWeakPointer inst;
     QtPluginInstanceFunction instance;
-    uint qt_version;
-    QString lastModified;
+    QJsonObject metaData;
+    bool compatPlugin;
 
     QString errorString;
     QLibrary::LoadHints loadHints;
 
     bool isPlugin();
 
+    static inline QJsonDocument fromRawMetaData(const char *raw) {
+        raw += strlen("QTMETADATA  ");
+        // the size of the embedded JSON object can be found 8 bytes into the data (see qjson_p.h),
+        // but doesn't include the size of the header (8 bytes)
+        QByteArray json(raw, qFromLittleEndian(*(uint *)(raw + 8)) + 8);
+        return QJsonDocument::fromBinaryData(json);
+    }
 
 private:
     explicit QLibraryPrivate(const QString &canonicalFileName, const QString &version);
@@ -112,7 +125,7 @@ private:
     QAtomicInt libraryRefCount;
     QAtomicInt libraryUnloadCount;
 
-    enum {IsAPlugin, IsNotAPlugin, MightBeAPlugin } pluginState;
+    enum { IsAPlugin, IsNotAPlugin, MightBeAPlugin } pluginState;
     friend class QLibraryPrivateHasFriends;
 };
 
diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h
index 6cc0ceb5c23..90ab8369c92 100644
--- a/src/corelib/plugin/qplugin.h
+++ b/src/corelib/plugin/qplugin.h
@@ -59,15 +59,33 @@ QT_BEGIN_NAMESPACE
 #endif
 
 typedef QObject *(*QtPluginInstanceFunction)();
+typedef const char *(*QtPluginMetaDataFunction)();
+
+struct QStaticPlugin
+{
+    QtPluginInstanceFunction instance;
+    QtPluginMetaDataFunction metaData;
+};
+
+void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin);
+
+#if defined (Q_OF_ELF) && defined (Q_CC_GNU)
+#  define QT_PLUGIN_VERIFICATION_SECTION \
+    __attribute__ ((section (".qtplugin"))) __attribute__((used))
+#  define QT_PLUGIN_METADATA_SECTION \
+    __attribute__ ((section (".qtmetadata"))) __attribute__((used))
+#else
+#  define QT_PLUGIN_VERIFICATION_SECTION
+#  define QT_PLUGIN_METADATA_SECTION
+#endif
 
-void Q_CORE_EXPORT qRegisterStaticPluginInstanceFunction(QtPluginInstanceFunction function);
 
 #define Q_IMPORT_PLUGIN(PLUGIN) \
-        extern QT_PREPEND_NAMESPACE(QObject) *qt_plugin_instance_##PLUGIN(); \
+        extern const QT_PREPEND_NAMESPACE(QStaticPlugin) qt_static_plugin_##PLUGIN(); \
         class Static##PLUGIN##PluginInstance{ \
         public: \
                 Static##PLUGIN##PluginInstance() { \
-                qRegisterStaticPluginInstanceFunction(qt_plugin_instance_##PLUGIN); \
+                    qRegisterStaticPluginFunction(qt_static_plugin_##PLUGIN()); \
                 } \
         }; \
        static Static##PLUGIN##PluginInstance static##PLUGIN##Instance;
@@ -80,21 +98,43 @@ void Q_CORE_EXPORT qRegisterStaticPluginInstanceFunction(QtPluginInstanceFunctio
             return _instance; \
         }
 
-#  define Q_EXPORT_PLUGIN(PLUGIN) \
-            Q_EXPORT_PLUGIN2(PLUGIN, PLUGIN)
+#if defined(QT_STATICPLUGIN)
 
-#  define Q_EXPORT_STATIC_PLUGIN(PLUGIN) \
-            Q_EXPORT_STATIC_PLUGIN2(PLUGIN, PLUGIN)
+#  define QT_MOC_EXPORT_PLUGIN(PLUGINCLASS) \
+    static QT_PREPEND_NAMESPACE(QObject) *qt_plugin_instance() \
+    Q_PLUGIN_INSTANCE(PLUGINCLASS) \
+    static const char *qt_plugin_query_metadata() { return (const char *)qt_pluginMetaData; } \
+    const QT_PREPEND_NAMESPACE(QStaticPlugin) qt_static_plugin_##PLUGINCLASS() { \
+        QT_PREPEND_NAMESPACE(QStaticPlugin) plugin = { qt_plugin_instance, qt_plugin_query_metadata }; \
+        return plugin; \
+    }
+
+#else
+
+#  define QT_MOC_EXPORT_PLUGIN(PLUGINCLASS)      \
+            Q_EXTERN_C Q_DECL_EXPORT \
+            const char *qt_plugin_query_metadata() \
+            { return (const char *)qt_pluginMetaData; } \
+            Q_EXTERN_C Q_DECL_EXPORT QT_PREPEND_NAMESPACE(QObject) *qt_plugin_instance() \
+            Q_PLUGIN_INSTANCE(PLUGINCLASS)
+
+#endif
+
+
+#define Q_EXPORT_PLUGIN(PLUGIN) \
+            Q_EXPORT_PLUGIN2(PLUGIN, PLUGIN)
+#define Q_EXPORT_STATIC_PLUGIN(PLUGIN)
+#define Q_EXPORT_STATIC_PLUGIN2(PLUGIN, PLUGINCLASS)
 
 #if defined(QT_STATICPLUGIN)
 
 #  define Q_EXPORT_PLUGIN2(PLUGIN, PLUGINCLASS) \
-            QT_PREPEND_NAMESPACE(QObject) \
-                *qt_plugin_instance_##PLUGIN() \
-            Q_PLUGIN_INSTANCE(PLUGINCLASS)
-
-#  define Q_EXPORT_STATIC_PLUGIN2(PLUGIN, PLUGINCLASS) \
-            Q_EXPORT_PLUGIN2(PLUGIN, PLUGINCLASS)
+    static QT_PREPEND_NAMESPACE(QObject) *qt_plugin_instance() \
+    Q_PLUGIN_INSTANCE(PLUGINCLASS) \
+    const QT_PREPEND_NAMESPACE(QStaticPlugin) qt_static_plugin_##PLUGIN() { \
+        QT_PREPEND_NAMESPACE(QStaticPlugin) plugin = { qt_plugin_instance, 0 }; \
+        return plugin; \
+    }
 
 #else
 // NOTE: if you change pattern, you MUST change the pattern in
@@ -118,25 +158,13 @@ void Q_CORE_EXPORT qRegisterStaticPluginInstanceFunction(QtPluginInstanceFunctio
       "version="QT_VERSION_STR"\n" \
       "debug="QPLUGIN_DEBUG_STR;
 
-#  if defined (Q_OF_ELF) && defined (Q_CC_GNU)
-#  define Q_PLUGIN_VERIFICATION_SECTION \
-    __attribute__ ((section (".qtplugin"))) __attribute__((used))
-#  else
-#  define Q_PLUGIN_VERIFICATION_SECTION
-#  endif
-
-#  if defined (Q_OS_WIN32) && defined(Q_CC_BOR)
-#     define Q_STANDARD_CALL __stdcall
-#  else
-#     define Q_STANDARD_CALL
-#  endif
 
 #  define Q_EXPORT_PLUGIN2(PLUGIN, PLUGINCLASS)      \
-            Q_PLUGIN_VERIFICATION_SECTION Q_PLUGIN_VERIFICATION_DATA \
+            QT_PLUGIN_VERIFICATION_SECTION Q_PLUGIN_VERIFICATION_DATA \
             Q_EXTERN_C Q_DECL_EXPORT \
-            const char * Q_STANDARD_CALL qt_plugin_query_verification_data() \
+            const char * qt_plugin_query_verification_data() \
             { return qt_plugin_verification_data; } \
-            Q_EXTERN_C Q_DECL_EXPORT QT_PREPEND_NAMESPACE(QObject) * Q_STANDARD_CALL qt_plugin_instance() \
+            Q_EXTERN_C Q_DECL_EXPORT QT_PREPEND_NAMESPACE(QObject) * qt_plugin_instance() \
             Q_PLUGIN_INSTANCE(PLUGINCLASS)
 
 #  define Q_EXPORT_STATIC_PLUGIN2(PLUGIN, PLUGINCLASS)
diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index 4ef04f2ea3d..d652b251f14 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -291,8 +291,8 @@ QString QPluginLoader::errorString() const
     return (!d || d->errorString.isEmpty()) ? tr("Unknown error") : d->errorString;
 }
 
-typedef QList StaticInstanceFunctionList;
-Q_GLOBAL_STATIC(StaticInstanceFunctionList, staticInstanceFunctionList)
+typedef QVector StaticPluginList;
+Q_GLOBAL_STATIC(StaticPluginList, staticPluginList)
 
 /*! \since 4.4
 
@@ -329,13 +329,13 @@ QLibrary::LoadHints QPluginLoader::loadHints() const
 
 /*!
     \relates QPluginLoader
-    \since 4.4
+    \since 5.0
 
-    Registers the given \a function with the plugin loader.
+    Registers the given \a plugin with the plugin loader.
 */
-void Q_CORE_EXPORT qRegisterStaticPluginInstanceFunction(QtPluginInstanceFunction function)
+void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin plugin)
 {
-    staticInstanceFunctionList()->append(function);
+    staticPluginList()->append(plugin);
 }
 
 /*!
@@ -345,14 +345,23 @@ void Q_CORE_EXPORT qRegisterStaticPluginInstanceFunction(QtPluginInstanceFunctio
 QObjectList QPluginLoader::staticInstances()
 {
     QObjectList instances;
-    StaticInstanceFunctionList *functions = staticInstanceFunctionList();
-    if (functions) {
-        for (int i = 0; i < functions->count(); ++i)
-            instances.append((*functions)[i]());
+    const StaticPluginList *plugins = staticPluginList();
+    if (plugins) {
+        for (int i = 0; i < plugins->size(); ++i)
+            instances += plugins->at(i).instance();
     }
     return instances;
 }
 
+
+QVector QLibraryPrivate::staticPlugins()
+{
+    StaticPluginList *plugins = staticPluginList();
+    if (plugins)
+        return *plugins;
+    return QVector();
+}
+
 QT_END_NAMESPACE
 
 #endif // QT_NO_LIBRARY
diff --git a/src/corelib/plugin/qpluginloader.h b/src/corelib/plugin/qpluginloader.h
index ee62986f212..6ca1892fa92 100644
--- a/src/corelib/plugin/qpluginloader.h
+++ b/src/corelib/plugin/qpluginloader.h
@@ -55,7 +55,6 @@ QT_BEGIN_HEADER
 
 QT_BEGIN_NAMESPACE
 
-
 class QLibraryPrivate;
 
 class Q_CORE_EXPORT QPluginLoader : public QObject
@@ -70,7 +69,7 @@ public:
 
     QObject *instance();
 
-    static QObjectList staticInstances();
+    QT_DEPRECATED static QObjectList staticInstances();
 
     bool load();
     bool unload();
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index b4f3d23f4e7..e2055e44e89 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -43,6 +43,11 @@
 #include "outputrevision.h"
 #include "utils.h"
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
 #include 
 
 #include  //for the flags.
@@ -421,6 +426,11 @@ void Generator::generateCode()
 //
     for (int signalindex = 0; signalindex < cdef->signalList.size(); ++signalindex)
         generateSignal(&cdef->signalList[signalindex], signalindex);
+
+//
+// Generate plugin meta data
+//
+    generatePluginMetaData();
 }
 
 
@@ -1051,4 +1061,42 @@ void Generator::generateSignal(FunctionDef *def,int index)
     fprintf(out, "}\n");
 }
 
+void Generator::generatePluginMetaData()
+{
+    if (cdef->pluginData.iid.isEmpty())
+        return;
+
+    QJsonObject data;
+    data.insert(QLatin1String("IID"), QLatin1String(cdef->pluginData.iid.constData()));
+    data.insert(QLatin1String("className"), QLatin1String(cdef->classname.constData()));
+    data.insert(QLatin1String("version"), (int)QT_VERSION);
+    data.insert(QLatin1String("debug"),
+#ifdef QT_NO_DEBUG
+                false
+#else
+                true
+#endif
+                );
+    data.insert(QLatin1String("MetaData"), cdef->pluginData.metaData.object());
+    QJsonDocument doc(data);
+
+    fprintf(out, "\nQT_PLUGIN_METADATA_SECTION const uint qt_section_alignment_dummy = 42;\n");
+    fprintf(out,
+            "\nQT_PLUGIN_METADATA_SECTION\n"
+            "static const unsigned char qt_pluginMetaData[] = {\n"
+            "    'Q', 'T', 'M', 'E', 'T', 'A', 'D', 'A', 'T', 'A', ' ', ' ',\n   ");
+#if 0
+    fprintf(out, "\"%s\";\n", doc.toJson().constData());
+#else
+    QByteArray binary = doc.toBinaryData();
+    for (int i = 0; i < binary.size() - 1; ++i) {
+        fprintf(out, " 0x%02x,", (uchar)binary.at(i));
+        if (!((i + 1) % 8))
+            fprintf(out, "\n   ");
+    }
+    fprintf(out, " 0x%02x\n};\n", (uchar)binary.at(binary.size() - 1));
+#endif
+    fprintf(out, "QT_MOC_EXPORT_PLUGIN(%s)\n\n", cdef->classname.constData());
+}
+
 QT_END_NAMESPACE
diff --git a/src/tools/moc/generator.h b/src/tools/moc/generator.h
index a3dc3d00418..6682e1a36ae 100644
--- a/src/tools/moc/generator.h
+++ b/src/tools/moc/generator.h
@@ -63,6 +63,7 @@ private:
     void generateMetacall();
     void generateStaticMetacall();
     void generateSignal(FunctionDef *def, int index);
+    void generatePluginMetaData();
 
     int strreg(const char *); // registers a string and returns its id
     QList strings;
diff --git a/src/tools/moc/keywords.cpp b/src/tools/moc/keywords.cpp
index 7a6b44074b5..f6151bdbf5b 100644
--- a/src/tools/moc/keywords.cpp
+++ b/src/tools/moc/keywords.cpp
@@ -43,12 +43,12 @@
 // DO NOT EDIT.
 
 static const short keyword_trans[][128] = {
-    {0,0,0,0,0,0,0,0,0,532,529,0,0,0,0,0,
+    {0,0,0,0,0,0,0,0,0,546,543,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     532,252,530,533,0,38,239,531,25,26,236,234,30,235,27,237,
+     546,252,544,547,0,38,239,545,25,26,236,234,30,235,27,237,
      22,22,22,22,22,22,22,22,22,22,34,41,23,39,24,43,
      0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-     8,21,8,8,8,8,8,8,8,8,8,31,534,32,238,8,
+     8,21,8,8,8,8,8,8,8,8,8,31,548,32,238,8,
      0,1,2,3,4,5,6,7,8,9,8,8,10,11,12,13,
      14,8,15,16,17,18,19,20,8,8,8,36,245,37,248,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -129,7 +129,7 @@ static const short keyword_trans[][128] = {
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     0,0,0,0,0,0,0,0,290,222,0,0,461,0,0,0,
+     0,0,0,0,0,0,0,0,290,222,0,0,475,0,0,0,
      0,0,0,0,55,0,0,330,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -168,7 +168,7 @@ static const short keyword_trans[][128] = {
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     0,0,0,0,485,0,0,0,0,0,0,0,0,0,0,357,
+     0,0,0,0,499,0,0,0,0,0,0,0,0,0,0,357,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -190,7 +190,7 @@ static const short keyword_trans[][128] = {
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,42,0,0,0,28,0,
-     537,537,537,537,537,537,537,537,537,537,0,0,0,0,0,0,
+     551,551,551,551,551,551,551,551,551,551,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -349,7 +349,7 @@ static const short keyword_trans[][128] = {
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     0,0,0,0,0,0,0,0,0,0,536,0,0,0,0,535,
+     0,0,0,0,0,0,0,0,0,0,550,0,0,0,0,549,
      0,0,0,0,0,0,0,0,0,0,0,0,0,258,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -385,21 +385,29 @@ static const short keyword_trans[][128] = {
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     0,458,0,0,0,300,0,0,0,0,0,0,0,0,0,0,
+     0,472,0,0,0,300,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     0,0,0,439,388,378,383,364,0,448,0,0,0,0,0,358,
-     370,0,521,436,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,453,402,392,397,364,0,462,0,0,0,0,0,358,
+     370,0,535,450,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     0,0,0,0,0,0,0,0,0,475,0,0,0,0,0,372,
+     0,0,0,0,0,0,0,0,0,0,0,0,378,0,0,0,
+     0,0,371,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,489,0,0,0,0,0,372,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
@@ -407,7 +415,7 @@ static const short keyword_trans[][128] = {
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     0,0,0,0,0,418,396,0,0,401,0,0,0,410,0,0,
+     0,0,0,0,0,432,410,0,0,415,0,0,0,424,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
@@ -415,7 +423,7 @@ static const short keyword_trans[][128] = {
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     0,0,0,504,0,437,0,0,0,465,0,0,471,0,0,0,
+     0,0,0,518,0,451,0,0,0,479,0,0,485,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
@@ -424,7 +432,7 @@ static const short keyword_trans[][128] = {
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     0,0,0,0,450,0,497,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,464,0,511,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -432,7 +440,7 @@ static const short keyword_trans[][128] = {
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     513,0,0,481,0,0,0,0,0,0,0,0,0,0,0,0,
+     527,0,0,495,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
 };
@@ -815,164 +823,178 @@ static const struct
     {CHARACTER, 0, 69, 368, CHARACTER},
     {CHARACTER, 0, 84, 369, CHARACTER},
     {Q_GADGET_TOKEN, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 82, 371, CHARACTER},
     {CHARACTER, 44, 0, 0, CHARACTER},
+    {CHARACTER, 45, 0, 0, CHARACTER},
     {CHARACTER, 0, 80, 373, CHARACTER},
     {CHARACTER, 0, 69, 374, CHARACTER},
     {CHARACTER, 0, 82, 375, CHARACTER},
     {CHARACTER, 0, 84, 376, CHARACTER},
     {CHARACTER, 0, 89, 377, CHARACTER},
     {Q_PROPERTY_TOKEN, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 78, 379, CHARACTER},
-    {CHARACTER, 0, 85, 380, CHARACTER},
-    {CHARACTER, 0, 77, 381, CHARACTER},
-    {CHARACTER, 0, 83, 382, CHARACTER},
+    {CHARACTER, 0, 85, 379, CHARACTER},
+    {CHARACTER, 0, 71, 380, CHARACTER},
+    {CHARACTER, 0, 73, 381, CHARACTER},
+    {CHARACTER, 0, 78, 382, CHARACTER},
+    {CHARACTER, 0, 95, 383, CHARACTER},
+    {CHARACTER, 0, 77, 384, CHARACTER},
+    {CHARACTER, 0, 69, 385, CHARACTER},
+    {CHARACTER, 0, 84, 386, CHARACTER},
+    {CHARACTER, 0, 65, 387, CHARACTER},
+    {CHARACTER, 0, 68, 388, CHARACTER},
+    {CHARACTER, 0, 65, 389, CHARACTER},
+    {CHARACTER, 0, 84, 390, CHARACTER},
+    {CHARACTER, 0, 65, 391, CHARACTER},
+    {Q_PLUGIN_METADATA_TOKEN, 0, 0, 0, CHARACTER},
+    {CHARACTER, 0, 78, 393, CHARACTER},
+    {CHARACTER, 0, 85, 394, CHARACTER},
+    {CHARACTER, 0, 77, 395, CHARACTER},
+    {CHARACTER, 0, 83, 396, CHARACTER},
     {Q_ENUMS_TOKEN, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 76, 384, CHARACTER},
-    {CHARACTER, 0, 65, 385, CHARACTER},
-    {CHARACTER, 0, 71, 386, CHARACTER},
-    {CHARACTER, 0, 83, 387, CHARACTER},
+    {CHARACTER, 0, 76, 398, CHARACTER},
+    {CHARACTER, 0, 65, 399, CHARACTER},
+    {CHARACTER, 0, 71, 400, CHARACTER},
+    {CHARACTER, 0, 83, 401, CHARACTER},
     {Q_FLAGS_TOKEN, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 69, 389, CHARACTER},
-    {CHARACTER, 0, 67, 390, CHARACTER},
-    {CHARACTER, 0, 76, 391, CHARACTER},
-    {CHARACTER, 0, 65, 392, CHARACTER},
-    {CHARACTER, 0, 82, 393, CHARACTER},
-    {CHARACTER, 0, 69, 394, CHARACTER},
-    {CHARACTER, 0, 95, 395, CHARACTER},
-    {CHARACTER, 45, 0, 0, CHARACTER},
-    {CHARACTER, 0, 76, 397, CHARACTER},
-    {CHARACTER, 0, 65, 398, CHARACTER},
-    {CHARACTER, 0, 71, 399, CHARACTER},
-    {CHARACTER, 0, 83, 400, CHARACTER},
-    {Q_DECLARE_FLAGS_TOKEN, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 78, 402, CHARACTER},
-    {CHARACTER, 0, 84, 403, CHARACTER},
-    {CHARACTER, 0, 69, 404, CHARACTER},
-    {CHARACTER, 0, 82, 405, CHARACTER},
-    {CHARACTER, 0, 70, 406, CHARACTER},
-    {CHARACTER, 0, 65, 407, CHARACTER},
-    {CHARACTER, 0, 67, 408, CHARACTER},
-    {CHARACTER, 0, 69, 409, CHARACTER},
-    {Q_DECLARE_INTERFACE_TOKEN, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 69, 411, CHARACTER},
-    {CHARACTER, 0, 84, 412, CHARACTER},
-    {CHARACTER, 0, 65, 413, CHARACTER},
-    {CHARACTER, 0, 84, 414, CHARACTER},
-    {CHARACTER, 0, 89, 415, CHARACTER},
-    {CHARACTER, 0, 80, 416, CHARACTER},
-    {CHARACTER, 0, 69, 417, CHARACTER},
-    {Q_DECLARE_METATYPE_TOKEN, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 88, 419, CHARACTER},
-    {CHARACTER, 0, 84, 420, CHARACTER},
-    {CHARACTER, 0, 69, 421, CHARACTER},
-    {CHARACTER, 0, 78, 422, CHARACTER},
-    {CHARACTER, 0, 83, 423, CHARACTER},
-    {CHARACTER, 0, 73, 424, CHARACTER},
-    {CHARACTER, 0, 79, 425, CHARACTER},
-    {CHARACTER, 0, 78, 426, CHARACTER},
-    {CHARACTER, 0, 95, 427, CHARACTER},
-    {CHARACTER, 0, 73, 428, CHARACTER},
-    {CHARACTER, 0, 78, 429, CHARACTER},
-    {CHARACTER, 0, 84, 430, CHARACTER},
-    {CHARACTER, 0, 69, 431, CHARACTER},
-    {CHARACTER, 0, 82, 432, CHARACTER},
-    {CHARACTER, 0, 70, 433, CHARACTER},
-    {CHARACTER, 0, 65, 434, CHARACTER},
-    {CHARACTER, 0, 67, 435, CHARACTER},
-    {CHARACTER, 0, 69, 409, CHARACTER},
+    {CHARACTER, 0, 69, 403, CHARACTER},
+    {CHARACTER, 0, 67, 404, CHARACTER},
+    {CHARACTER, 0, 76, 405, CHARACTER},
+    {CHARACTER, 0, 65, 406, CHARACTER},
+    {CHARACTER, 0, 82, 407, CHARACTER},
+    {CHARACTER, 0, 69, 408, CHARACTER},
+    {CHARACTER, 0, 95, 409, CHARACTER},
     {CHARACTER, 46, 0, 0, CHARACTER},
-    {CHARACTER, 0, 84, 438, CHARACTER},
-    {CHARACTER, 0, 83, 387, CHARACTER},
-    {CHARACTER, 0, 76, 440, CHARACTER},
-    {CHARACTER, 0, 65, 441, CHARACTER},
-    {CHARACTER, 0, 83, 442, CHARACTER},
-    {CHARACTER, 0, 83, 443, CHARACTER},
-    {CHARACTER, 0, 73, 444, CHARACTER},
-    {CHARACTER, 0, 78, 445, CHARACTER},
-    {CHARACTER, 0, 70, 446, CHARACTER},
-    {CHARACTER, 0, 79, 447, CHARACTER},
-    {Q_CLASSINFO_TOKEN, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 78, 449, CHARACTER},
+    {CHARACTER, 0, 76, 411, CHARACTER},
+    {CHARACTER, 0, 65, 412, CHARACTER},
+    {CHARACTER, 0, 71, 413, CHARACTER},
+    {CHARACTER, 0, 83, 414, CHARACTER},
+    {Q_DECLARE_FLAGS_TOKEN, 0, 0, 0, CHARACTER},
+    {CHARACTER, 0, 78, 416, CHARACTER},
+    {CHARACTER, 0, 84, 417, CHARACTER},
+    {CHARACTER, 0, 69, 418, CHARACTER},
+    {CHARACTER, 0, 82, 419, CHARACTER},
+    {CHARACTER, 0, 70, 420, CHARACTER},
+    {CHARACTER, 0, 65, 421, CHARACTER},
+    {CHARACTER, 0, 67, 422, CHARACTER},
+    {CHARACTER, 0, 69, 423, CHARACTER},
+    {Q_DECLARE_INTERFACE_TOKEN, 0, 0, 0, CHARACTER},
+    {CHARACTER, 0, 69, 425, CHARACTER},
+    {CHARACTER, 0, 84, 426, CHARACTER},
+    {CHARACTER, 0, 65, 427, CHARACTER},
+    {CHARACTER, 0, 84, 428, CHARACTER},
+    {CHARACTER, 0, 89, 429, CHARACTER},
+    {CHARACTER, 0, 80, 430, CHARACTER},
+    {CHARACTER, 0, 69, 431, CHARACTER},
+    {Q_DECLARE_METATYPE_TOKEN, 0, 0, 0, CHARACTER},
+    {CHARACTER, 0, 88, 433, CHARACTER},
+    {CHARACTER, 0, 84, 434, CHARACTER},
+    {CHARACTER, 0, 69, 435, CHARACTER},
+    {CHARACTER, 0, 78, 436, CHARACTER},
+    {CHARACTER, 0, 83, 437, CHARACTER},
+    {CHARACTER, 0, 73, 438, CHARACTER},
+    {CHARACTER, 0, 79, 439, CHARACTER},
+    {CHARACTER, 0, 78, 440, CHARACTER},
+    {CHARACTER, 0, 95, 441, CHARACTER},
+    {CHARACTER, 0, 73, 442, CHARACTER},
+    {CHARACTER, 0, 78, 443, CHARACTER},
+    {CHARACTER, 0, 84, 444, CHARACTER},
+    {CHARACTER, 0, 69, 445, CHARACTER},
+    {CHARACTER, 0, 82, 446, CHARACTER},
+    {CHARACTER, 0, 70, 447, CHARACTER},
+    {CHARACTER, 0, 65, 448, CHARACTER},
+    {CHARACTER, 0, 67, 449, CHARACTER},
+    {CHARACTER, 0, 69, 423, CHARACTER},
     {CHARACTER, 47, 0, 0, CHARACTER},
-    {CHARACTER, 0, 69, 451, CHARACTER},
-    {CHARACTER, 0, 82, 452, CHARACTER},
-    {CHARACTER, 0, 70, 453, CHARACTER},
-    {CHARACTER, 0, 65, 454, CHARACTER},
-    {CHARACTER, 0, 67, 455, CHARACTER},
-    {CHARACTER, 0, 69, 456, CHARACTER},
+    {CHARACTER, 0, 84, 452, CHARACTER},
+    {CHARACTER, 0, 83, 401, CHARACTER},
+    {CHARACTER, 0, 76, 454, CHARACTER},
+    {CHARACTER, 0, 65, 455, CHARACTER},
+    {CHARACTER, 0, 83, 456, CHARACTER},
     {CHARACTER, 0, 83, 457, CHARACTER},
-    {Q_INTERFACES_TOKEN, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 108, 459, CHARACTER},
-    {CHARACTER, 0, 115, 460, CHARACTER},
-    {SIGNALS, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 111, 462, CHARACTER},
-    {CHARACTER, 0, 116, 463, CHARACTER},
-    {CHARACTER, 0, 115, 464, CHARACTER},
-    {SLOTS, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 71, 466, CHARACTER},
-    {CHARACTER, 0, 78, 467, CHARACTER},
-    {CHARACTER, 0, 65, 468, CHARACTER},
-    {CHARACTER, 0, 76, 469, CHARACTER},
-    {Q_SIGNAL_TOKEN, 0, 83, 470, CHARACTER},
-    {Q_SIGNALS_TOKEN, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 79, 472, CHARACTER},
-    {CHARACTER, 0, 84, 473, CHARACTER},
-    {Q_SLOT_TOKEN, 0, 83, 474, CHARACTER},
-    {Q_SLOTS_TOKEN, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 86, 476, CHARACTER},
-    {CHARACTER, 0, 65, 477, CHARACTER},
-    {CHARACTER, 0, 84, 478, CHARACTER},
-    {CHARACTER, 0, 69, 479, CHARACTER},
-    {CHARACTER, 0, 95, 480, CHARACTER},
+    {CHARACTER, 0, 73, 458, CHARACTER},
+    {CHARACTER, 0, 78, 459, CHARACTER},
+    {CHARACTER, 0, 70, 460, CHARACTER},
+    {CHARACTER, 0, 79, 461, CHARACTER},
+    {Q_CLASSINFO_TOKEN, 0, 0, 0, CHARACTER},
+    {CHARACTER, 0, 78, 463, CHARACTER},
     {CHARACTER, 48, 0, 0, CHARACTER},
-    {CHARACTER, 0, 76, 482, CHARACTER},
-    {CHARACTER, 0, 79, 483, CHARACTER},
-    {CHARACTER, 0, 84, 484, CHARACTER},
+    {CHARACTER, 0, 69, 465, CHARACTER},
+    {CHARACTER, 0, 82, 466, CHARACTER},
+    {CHARACTER, 0, 70, 467, CHARACTER},
+    {CHARACTER, 0, 65, 468, CHARACTER},
+    {CHARACTER, 0, 67, 469, CHARACTER},
+    {CHARACTER, 0, 69, 470, CHARACTER},
+    {CHARACTER, 0, 83, 471, CHARACTER},
+    {Q_INTERFACES_TOKEN, 0, 0, 0, CHARACTER},
+    {CHARACTER, 0, 108, 473, CHARACTER},
+    {CHARACTER, 0, 115, 474, CHARACTER},
+    {SIGNALS, 0, 0, 0, CHARACTER},
+    {CHARACTER, 0, 111, 476, CHARACTER},
+    {CHARACTER, 0, 116, 477, CHARACTER},
+    {CHARACTER, 0, 115, 478, CHARACTER},
+    {SLOTS, 0, 0, 0, CHARACTER},
+    {CHARACTER, 0, 71, 480, CHARACTER},
+    {CHARACTER, 0, 78, 481, CHARACTER},
+    {CHARACTER, 0, 65, 482, CHARACTER},
+    {CHARACTER, 0, 76, 483, CHARACTER},
+    {Q_SIGNAL_TOKEN, 0, 83, 484, CHARACTER},
+    {Q_SIGNALS_TOKEN, 0, 0, 0, CHARACTER},
+    {CHARACTER, 0, 79, 486, CHARACTER},
+    {CHARACTER, 0, 84, 487, CHARACTER},
+    {Q_SLOT_TOKEN, 0, 83, 488, CHARACTER},
+    {Q_SLOTS_TOKEN, 0, 0, 0, CHARACTER},
+    {CHARACTER, 0, 86, 490, CHARACTER},
+    {CHARACTER, 0, 65, 491, CHARACTER},
+    {CHARACTER, 0, 84, 492, CHARACTER},
+    {CHARACTER, 0, 69, 493, CHARACTER},
+    {CHARACTER, 0, 95, 494, CHARACTER},
+    {CHARACTER, 49, 0, 0, CHARACTER},
+    {CHARACTER, 0, 76, 496, CHARACTER},
+    {CHARACTER, 0, 79, 497, CHARACTER},
+    {CHARACTER, 0, 84, 498, CHARACTER},
     {Q_PRIVATE_SLOT_TOKEN, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 95, 486, CHARACTER},
-    {CHARACTER, 0, 77, 487, CHARACTER},
-    {CHARACTER, 0, 79, 488, CHARACTER},
-    {CHARACTER, 0, 67, 489, CHARACTER},
-    {CHARACTER, 0, 95, 490, CHARACTER},
-    {CHARACTER, 0, 67, 491, CHARACTER},
-    {CHARACTER, 0, 79, 492, CHARACTER},
-    {CHARACTER, 0, 77, 493, CHARACTER},
-    {CHARACTER, 0, 80, 494, CHARACTER},
-    {CHARACTER, 0, 65, 495, CHARACTER},
-    {CHARACTER, 0, 84, 496, CHARACTER},
-    {Q_MOC_COMPAT_TOKEN, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 79, 498, CHARACTER},
-    {CHARACTER, 0, 75, 499, CHARACTER},
-    {CHARACTER, 0, 65, 500, CHARACTER},
-    {CHARACTER, 0, 66, 501, CHARACTER},
-    {CHARACTER, 0, 76, 502, CHARACTER},
-    {CHARACTER, 0, 69, 503, CHARACTER},
-    {Q_INVOKABLE_TOKEN, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 82, 505, CHARACTER},
-    {CHARACTER, 0, 73, 506, CHARACTER},
-    {CHARACTER, 0, 80, 507, CHARACTER},
-    {CHARACTER, 0, 84, 508, CHARACTER},
+    {CHARACTER, 0, 95, 500, CHARACTER},
+    {CHARACTER, 0, 77, 501, CHARACTER},
+    {CHARACTER, 0, 79, 502, CHARACTER},
+    {CHARACTER, 0, 67, 503, CHARACTER},
+    {CHARACTER, 0, 95, 504, CHARACTER},
+    {CHARACTER, 0, 67, 505, CHARACTER},
+    {CHARACTER, 0, 79, 506, CHARACTER},
+    {CHARACTER, 0, 77, 507, CHARACTER},
+    {CHARACTER, 0, 80, 508, CHARACTER},
     {CHARACTER, 0, 65, 509, CHARACTER},
-    {CHARACTER, 0, 66, 510, CHARACTER},
-    {CHARACTER, 0, 76, 511, CHARACTER},
-    {CHARACTER, 0, 69, 512, CHARACTER},
-    {Q_SCRIPTABLE_TOKEN, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 82, 514, CHARACTER},
-    {CHARACTER, 0, 79, 515, CHARACTER},
-    {CHARACTER, 0, 80, 516, CHARACTER},
+    {CHARACTER, 0, 84, 510, CHARACTER},
+    {Q_MOC_COMPAT_TOKEN, 0, 0, 0, CHARACTER},
+    {CHARACTER, 0, 79, 512, CHARACTER},
+    {CHARACTER, 0, 75, 513, CHARACTER},
+    {CHARACTER, 0, 65, 514, CHARACTER},
+    {CHARACTER, 0, 66, 515, CHARACTER},
+    {CHARACTER, 0, 76, 516, CHARACTER},
     {CHARACTER, 0, 69, 517, CHARACTER},
-    {CHARACTER, 0, 82, 518, CHARACTER},
-    {CHARACTER, 0, 84, 519, CHARACTER},
-    {CHARACTER, 0, 89, 520, CHARACTER},
+    {Q_INVOKABLE_TOKEN, 0, 0, 0, CHARACTER},
+    {CHARACTER, 0, 82, 519, CHARACTER},
+    {CHARACTER, 0, 73, 520, CHARACTER},
+    {CHARACTER, 0, 80, 521, CHARACTER},
+    {CHARACTER, 0, 84, 522, CHARACTER},
+    {CHARACTER, 0, 65, 523, CHARACTER},
+    {CHARACTER, 0, 66, 524, CHARACTER},
+    {CHARACTER, 0, 76, 525, CHARACTER},
+    {CHARACTER, 0, 69, 526, CHARACTER},
+    {Q_SCRIPTABLE_TOKEN, 0, 0, 0, CHARACTER},
+    {CHARACTER, 0, 82, 528, CHARACTER},
+    {CHARACTER, 0, 79, 529, CHARACTER},
+    {CHARACTER, 0, 80, 530, CHARACTER},
+    {CHARACTER, 0, 69, 531, CHARACTER},
+    {CHARACTER, 0, 82, 532, CHARACTER},
+    {CHARACTER, 0, 84, 533, CHARACTER},
+    {CHARACTER, 0, 89, 534, CHARACTER},
     {Q_PRIVATE_PROPERTY_TOKEN, 0, 0, 0, CHARACTER},
-    {CHARACTER, 0, 69, 522, CHARACTER},
-    {CHARACTER, 0, 86, 523, CHARACTER},
-    {CHARACTER, 0, 73, 524, CHARACTER},
-    {CHARACTER, 0, 83, 525, CHARACTER},
-    {CHARACTER, 0, 73, 526, CHARACTER},
-    {CHARACTER, 0, 79, 527, CHARACTER},
-    {CHARACTER, 0, 78, 528, CHARACTER},
+    {CHARACTER, 0, 69, 536, CHARACTER},
+    {CHARACTER, 0, 86, 537, CHARACTER},
+    {CHARACTER, 0, 73, 538, CHARACTER},
+    {CHARACTER, 0, 83, 539, CHARACTER},
+    {CHARACTER, 0, 73, 540, CHARACTER},
+    {CHARACTER, 0, 79, 541, CHARACTER},
+    {CHARACTER, 0, 78, 542, CHARACTER},
     {Q_REVISION_TOKEN, 0, 0, 0, CHARACTER},
     {NEWLINE, 0, 0, 0, NOTOKEN},
     {QUOTE, 0, 0, 0, NOTOKEN},
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index 5c9e1ee8386..97316eedde2 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -44,6 +44,9 @@
 #include "qdatetime.h"
 #include "utils.h"
 #include "outputrevision.h"
+#include 
+#include 
+#include 
 
 // for normalizeTypeInternal
 #include 
@@ -673,6 +676,9 @@ void Moc::parse()
                 case Q_PROPERTY_TOKEN:
                     parseProperty(&def);
                     break;
+                case Q_PLUGIN_METADATA_TOKEN:
+                    parsePluginData(&def);
+                    break;
                 case Q_ENUMS_TOKEN:
                     parseEnumOrFlag(&def, false);
                     break;
@@ -813,6 +819,8 @@ void Moc::generate(FILE *out)
 
     if (mustIncludeQMetaTypeH)
         fprintf(out, "#include \n");
+    if (mustIncludeQPluginH)
+        fprintf(out, "#include \n");
 
     fprintf(out, "#if !defined(Q_MOC_OUTPUT_REVISION)\n"
             "#error \"The header file '%s' doesn't include .\"\n", (const char *)fn);
@@ -1080,6 +1088,50 @@ void Moc::parseProperty(ClassDef *def)
     def->propertyList += propDef;
 }
 
+void Moc::parsePluginData(ClassDef *def)
+{
+    next(LPAREN);
+    QByteArray metaData;
+    while (test(IDENTIFIER)) {
+        QByteArray l = lexem();
+        if (l == "IID") {
+            next(STRING_LITERAL);
+            def->pluginData.iid = unquotedLexem();
+        } else if (l == "FILE") {
+            next(STRING_LITERAL);
+            QByteArray metaDataFile = unquotedLexem();
+            QFileInfo fi(QFileInfo(QString::fromLocal8Bit(currentFilenames.top())).dir(), QString::fromLocal8Bit(metaDataFile));
+            if (!fi.exists()) {
+                QByteArray msg;
+                msg += "Plugin Metadata file ";
+                msg += lexem();
+                msg += " does not exist. Declaration will be ignored";
+                warning(msg.constData());
+                return;
+            }
+            QFile file(fi.canonicalFilePath());
+            file.open(QFile::ReadOnly);
+            metaData = file.readAll();
+        }
+    }
+
+    if (!metaData.isEmpty()) {
+        def->pluginData.metaData = QJsonDocument::fromJson(metaData);
+        if (!def->pluginData.metaData.isObject()) {
+            QByteArray msg;
+            msg += "Plugin Metadata file ";
+            msg += lexem();
+            msg += " does not contain a valid JSON object. Declaration will be ignored";
+            warning(msg.constData());
+            def->pluginData.iid = QByteArray();
+            return;
+        }
+    }
+
+    mustIncludeQPluginH = true;
+    next(RPAREN);
+}
+
 void Moc::parsePrivateProperty(ClassDef *def)
 {
     next(LPAREN);
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index b780272dff7..aedb97b2349 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -46,6 +46,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -167,6 +168,11 @@ struct ClassDef {
     bool hasQObject;
     bool hasQGadget;
 
+    struct PluginData {
+        QByteArray iid;
+        QJsonDocument metaData;
+    } pluginData;
+
     QList constructorList;
     QList signalList, slotList, methodList, publicList;
     int notifyableProperties;
@@ -192,7 +198,7 @@ class Moc : public Parser
 {
 public:
     Moc()
-        : noInclude(false), generatedCode(false), mustIncludeQMetaTypeH(false)
+        : noInclude(false), generatedCode(false), mustIncludeQMetaTypeH(false), mustIncludeQPluginH(false)
         {}
 
     QByteArray filename;
@@ -200,6 +206,7 @@ public:
     bool noInclude;
     bool generatedCode;
     bool mustIncludeQMetaTypeH;
+    bool mustIncludeQPluginH;
     QByteArray includePath;
     QList includeFiles;
     QList classList;
@@ -229,6 +236,7 @@ public:
     void parseSlots(ClassDef *def, FunctionDef::Access access);
     void parseSignals(ClassDef *def);
     void parseProperty(ClassDef *def);
+    void parsePluginData(ClassDef *def);
     void createPropertyDef(PropertyDef &def);
     void parseEnumOrFlag(ClassDef *def, bool isFlag);
     void parseFlag(ClassDef *def);
diff --git a/src/tools/moc/token.h b/src/tools/moc/token.h
index a694ff4eb22..a9f028f20ae 100644
--- a/src/tools/moc/token.h
+++ b/src/tools/moc/token.h
@@ -169,6 +169,7 @@ enum Token {
     Q_OBJECT_TOKEN = Q_META_TOKEN_BEGIN,
     Q_GADGET_TOKEN,
     Q_PROPERTY_TOKEN,
+    Q_PLUGIN_METADATA_TOKEN,
     Q_ENUMS_TOKEN,
     Q_FLAGS_TOKEN,
     Q_DECLARE_FLAGS_TOKEN,
diff --git a/src/tools/moc/util/generate_keywords.cpp b/src/tools/moc/util/generate_keywords.cpp
index eb06315fed7..4560944a47c 100644
--- a/src/tools/moc/util/generate_keywords.cpp
+++ b/src/tools/moc/util/generate_keywords.cpp
@@ -228,6 +228,7 @@ static const Keyword keywords[] = {
     { "Q_OBJECT", "Q_OBJECT_TOKEN" },
     { "Q_GADGET", "Q_GADGET_TOKEN" },
     { "Q_PROPERTY", "Q_PROPERTY_TOKEN" },
+    { "Q_PLUGIN_METADATA", "Q_PLUGIN_METADATA_TOKEN" },
     { "Q_ENUMS", "Q_ENUMS_TOKEN" },
     { "Q_FLAGS", "Q_FLAGS_TOKEN" },
     { "Q_DECLARE_FLAGS", "Q_DECLARE_FLAGS_TOKEN" },

From 79e90762748865af9ed3d9260aceaaf69c34d252 Mon Sep 17 00:00:00 2001
From: Miikka Heikkinen 
Date: Wed, 15 Feb 2012 15:22:35 +0200
Subject: [PATCH 244/406] Remove XFAIL in QGraphicsWidget test for Windows

The XFAILed initStyleOption() case passes on Windows, so do not XFAIL
it there.

Task-number: QTBUG-24297
Change-Id: I9615c408aa7e72b5eb8fe9739903594e45eb5fd7
Reviewed-by: Friedemann Kleint 
---
 .../graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp      | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp
index 0607d2ab304..0a2d0cd2f86 100644
--- a/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp
@@ -1157,8 +1157,10 @@ void tst_QGraphicsWidget::initStyleOption()
     bool hasFocus = option.state & QStyle::State_HasFocus;
     QCOMPARE(hasFocus, focus);
     bool isUnderMouse = option.state & QStyle::State_MouseOver;
-#if !defined(Q_OS_WINCE) && !defined(Q_OS_MAC)
+#ifndef Q_OS_WINCE
+# if !defined(Q_OS_MAC) && !defined(Q_OS_WIN)
     QEXPECT_FAIL("all", "QTBUG-22457", Abort);
+# endif
     QCOMPARE(isUnderMouse, underMouse);
 #endif
     // if (layoutDirection != Qt::LeftToRight)

From 656dff47a6f2c5e53c1bb2e54bf21e053c82c32a Mon Sep 17 00:00:00 2001
From: Miikka Heikkinen 
Date: Wed, 15 Feb 2012 13:23:22 +0200
Subject: [PATCH 245/406] Fix tst_QFileDialog2 for Windows 7.

There are no rights for typical user or even administrator to write
directly under c:\ root in windows without rights elevation, so
completionOnLevelAfterRoot() test case failed. Changed the test case
to use an existing directory.

Task-number: QTBUG-24289
Change-Id: I6a8dfc9d1d6ae798b3b9049c542b45fdbdbd9a8c
Reviewed-by: Friedemann Kleint 
---
 .../dialogs/qfiledialog2/tst_qfiledialog2.cpp | 44 +++++++++++++++----
 1 file changed, 35 insertions(+), 9 deletions(-)

diff --git a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
index 472469e7970..7ab3100cabc 100644
--- a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
+++ b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
@@ -559,9 +559,39 @@ void tst_QFileDialog2::completionOnLevelAfterRoot()
 {
     QNonNativeFileDialog fd;
 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
-    fd.setDirectory("C:");
+    fd.setDirectory("C:/");
     QDir current = fd.directory();
-    current.mkdir("completionOnLevelAfterRootTest");
+    QStringList entryList = current.entryList(QStringList(), QDir::Dirs);
+    // Find a suitable test dir under c:-root:
+    // - At least 6 characters long
+    // - Ascii, letters only
+    // - No another dir with same start
+    QString testDir;
+    foreach (const QString &entry, entryList) {
+        if (entry.size() > 5 && QString(entry.toAscii()).compare(entry) == 0) {
+            bool invalid = false;
+            for (int i = 0; i < 5; i++) {
+                if (!entry.at(i).isLetter()) {
+                    invalid = true;
+                    break;
+                }
+            }
+            if (!invalid) {
+                foreach (const QString &check, entryList) {
+                    if (check.startsWith(entry.left(5)) && check != entry) {
+                        invalid = true;
+                        break;
+                    }
+                }
+            }
+            if (!invalid) {
+                testDir = entry;
+                break;
+            }
+        }
+    }
+    if (testDir.isEmpty())
+        QSKIP("This test requires to have an unique directory of at least six ascii characters under c:/");
 #else
     fd.setFilter(QDir::Hidden | QDir::AllDirs | QDir::Files | QDir::System);
     fd.setDirectory("/");
@@ -574,11 +604,8 @@ void tst_QFileDialog2::completionOnLevelAfterRoot()
     QTest::qWait(2000);
 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
     //I love testlib :D
-    QTest::keyClick(edit, Qt::Key_C);
-    QTest::keyClick(edit, Qt::Key_O);
-    QTest::keyClick(edit, Qt::Key_M);
-    QTest::keyClick(edit, Qt::Key_P);
-    QTest::keyClick(edit, Qt::Key_L);
+    for (int i = 0; i < 5; i++)
+        QTest::keyClick(edit, testDir.at(i).toLower().toAscii() - 'a' + Qt::Key_A);
 #else
     QTest::keyClick(edit, Qt::Key_E);
     QTest::keyClick(edit, Qt::Key_T);
@@ -587,8 +614,7 @@ void tst_QFileDialog2::completionOnLevelAfterRoot()
     QTest::keyClick(edit->completer()->popup(), Qt::Key_Down);
     QTest::qWait(200);
 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
-    QCOMPARE(edit->text(), QString("completionOnLevelAfterRootTest"));
-    current.rmdir("completionOnLevelAfterRootTest");
+    QCOMPARE(edit->text(), testDir);
 #else
     QTRY_COMPARE(edit->text(), QString("etc"));
 #endif

From b800d8b94a7861ecf8853621f6556fca186fb5b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thorbj=C3=B8rn=20Lund=20Martsum?= 
Date: Thu, 29 Dec 2011 08:59:37 +0100
Subject: [PATCH 246/406] QHeaderView::moveSection performance boost

The patch also speeds up swapSections and hideSection a lot.

It work by eliminating the Span. (That is forcing each 'Span'
to have exactly one element) That saves a lot of loops since
we can often lookup info fast - and/or change it fast.

Since it is often a complexity change, it is difficult to
put %-increase on. (The most used linear function is
recalcSectionStartPos() - and it has a very low constant)

However comparing with the new benchmark (2500 rows)
swapSection, showHideSection and moveSection are about
20-40 factors faster. (Yes, it is a lot faster!)

In the benchmark moveSection is about 300 factors faster.

Beside being a far better model it is also far more simple.

This fix partly solves:
Task-number: QTBUG-19092

Change-Id: I8deeb9315276d15c68e8a27d5dcb8e0c0badf367
Reviewed-by: Stephen Kelly 
---
 src/widgets/itemviews/qheaderview.cpp | 290 ++++++--------------------
 src/widgets/itemviews/qheaderview_p.h |  35 ++--
 2 files changed, 80 insertions(+), 245 deletions(-)

diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index 85d9ff0ce61..299dcb3dd4f 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -1660,31 +1660,22 @@ void QHeaderView::sectionsInserted(const QModelIndex &parent,
     d->invalidateCachedSizeHint();
 
     // add the new sections
-    int insertAt = 0;
-    for (int spanStart = 0; insertAt < d->sectionSpans.count() && spanStart < logicalFirst; ++insertAt)
-        spanStart += d->sectionSpans.at(insertAt).count;
+    int insertAt = logicalFirst;
 
     int insertCount = logicalLast - logicalFirst + 1;
     d->sectionCount += insertCount;
+    QHeaderViewPrivate::SectionSpan span(d->defaultSectionSize, d->globalResizeMode);
+    d->sectionStartposRecalc = true;
 
     if (d->sectionSpans.isEmpty() || insertAt >= d->sectionSpans.count()) {
         int insertLength = d->defaultSectionSize * insertCount;
         d->length += insertLength;
-        QHeaderViewPrivate::SectionSpan span(insertLength, insertCount, d->globalResizeMode);
-        d->sectionSpans.append(span);
-    } else if ((d->sectionSpans.at(insertAt).sectionSize() == d->defaultSectionSize)
-               && d->sectionSpans.at(insertAt).resizeMode == d->globalResizeMode) {
-        // add the new sections to an existing span
-        int insertLength = d->sectionSpans.at(insertAt).sectionSize() * insertCount;
-        d->length += insertLength;
-        d->sectionSpans[insertAt].size += insertLength;
-        d->sectionSpans[insertAt].count += insertCount;
+        d->sectionSpans.insert(d->sectionSpans.count(), insertCount, span); // append
     } else {
-        // separate them out into their own span
+        // separate them out into their own spans
         int insertLength = d->defaultSectionSize * insertCount;
         d->length += insertLength;
-        QHeaderViewPrivate::SectionSpan span(insertLength, insertCount, d->globalResizeMode);
-        d->sectionSpans.insert(insertAt, span);
+        d->sectionSpans.insert(insertAt, insertCount, span);
     }
 
     // update sorting column
@@ -3112,177 +3103,27 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool
 
 void QHeaderViewPrivate::createSectionSpan(int start, int end, int size, QHeaderView::ResizeMode mode)
 {
-    // ### the code for merging spans does not merge at all opertuneties
-    // ### what if the number of sections is reduced ?
-
-    SectionSpan span(size, (end - start) + 1, mode);
-    int start_section = 0;
-#if !defined(QT_NO_DEBUG) || defined(QT_FORCE_ASSERTS)
-    int initial_section_count = headerSectionCount(); // ### debug code
-#endif
-
-    QList spansToRemove;
-    for (int i = 0; i < sectionSpans.count(); ++i) {
-        int end_section = start_section + sectionSpans.at(i).count - 1;
-        int section_count = sectionSpans.at(i).count;
-        if (start <= start_section && end > end_section) {
-            // the existing span is entirely coveded by the new span
-            spansToRemove.append(i);
-        } else if (start < start_section && end >= end_section) {
-            // the existing span is entirely coveded by the new span
-            spansToRemove.append(i);
-        } else if (start == start_section && end == end_section) {
-            // the new span is covered by an existin span
-            length -= sectionSpans.at(i).size;
-            length += size;
-            sectionSpans[i].size = size;
-            sectionSpans[i].resizeMode = mode;
-            // ### check if we can merge the section with any of its neighbours
-            removeSpans(spansToRemove);
-            Q_ASSERT(initial_section_count == headerSectionCount());
-            return;
-        } else if (start > start_section && end < end_section) {
-            if (sectionSpans.at(i).sectionSize() == span.sectionSize()
-                && sectionSpans.at(i).resizeMode == span.resizeMode) {
-                Q_ASSERT(initial_section_count == headerSectionCount());
-                return;
-            }
-            // the new span is in the middle of the old span, so we have to split it
-            length -= sectionSpans.at(i).size;
-            int section_size = sectionSpans.at(i).sectionSize();
-#if !defined(QT_NO_DEBUG) || defined(QT_FORCE_ASSERTS)
-            const int span_count = sectionSpans.at(i).count;
-#endif
-            QHeaderView::ResizeMode span_mode = sectionSpans.at(i).resizeMode;
-            // first span
-            int first_span_count = start - start_section;
-            int first_span_size = section_size * first_span_count;
-            sectionSpans[i].count = first_span_count;
-            sectionSpans[i].size = first_span_size;
-            sectionSpans[i].resizeMode = span_mode;
-            length += first_span_size;
-            // middle span (the new span)
-#if !defined(QT_NO_DEBUG) || defined(QT_FORCE_ASSERTS)
-            const int mid_span_count = span.count;
-#endif
-            int mid_span_size = span.size;
-            sectionSpans.insert(i + 1, span);
-            length += mid_span_size;
-            // last span
-            int last_span_count = end_section - end;
-            int last_span_size = section_size * last_span_count;
-            sectionSpans.insert(i + 2, SectionSpan(last_span_size, last_span_count, span_mode));
-            length += last_span_size;
-            Q_ASSERT(span_count == first_span_count + mid_span_count + last_span_count);
-            removeSpans(spansToRemove);
-            Q_ASSERT(initial_section_count == headerSectionCount());
-            return;
-        } else if (start > start_section && start <= end_section && end >= end_section) {
-            // the new span covers the last part of the existing span
-            length -= sectionSpans.at(i).size;
-            int removed_count = (end_section - start + 1);
-            int span_count = sectionSpans.at(i).count - removed_count;
-            int section_size = sectionSpans.at(i).sectionSize();
-            int span_size = section_size * span_count;
-            sectionSpans[i].count = span_count;
-            sectionSpans[i].size = span_size;
-            length += span_size;
-            if (end == end_section) {
-                sectionSpans.insert(i + 1, span); // insert after
-                length += span.size;
-                removeSpans(spansToRemove);
-                Q_ASSERT(initial_section_count == headerSectionCount());
-                return;
-            }
-        } else if (end < end_section && end >= start_section && start <= start_section) {
-            // the new span covers the first part of the existing span
-            length -= sectionSpans.at(i).size;
-            int removed_count = (end - start_section + 1);
-            int section_size = sectionSpans.at(i).sectionSize();
-            int span_count = sectionSpans.at(i).count - removed_count;
-            int span_size = section_size * span_count;
-            sectionSpans[i].count = span_count;
-            sectionSpans[i].size = span_size;
-            length += span_size;
-            sectionSpans.insert(i, span); // insert before
-            length += span.size;
-            removeSpans(spansToRemove);
-            Q_ASSERT(initial_section_count == headerSectionCount());
-            return;
-        }
-        start_section += section_count;
-    }
-
-    // ### adding and removing _ sections_  in addition to spans
-    // ### add some more checks here
-
-    if (spansToRemove.isEmpty()) {
-        if (!sectionSpans.isEmpty()
-            && sectionSpans.last().sectionSize() == span.sectionSize()
-            && sectionSpans.last().resizeMode == span.resizeMode) {
-            length += span.size;
-            int last = sectionSpans.count() - 1;
-            sectionSpans[last].count += span.count;
-            sectionSpans[last].size += span.size;
-            sectionSpans[last].resizeMode = span.resizeMode;
-        } else {
-            length += span.size;
-            sectionSpans.append(span);
-        }
-    } else {
-        removeSpans(spansToRemove);
-        length += span.size;
-        sectionSpans.insert(spansToRemove.first(), span);
-        //Q_ASSERT(initial_section_count == headerSectionCount());
+    int sizePerSection = size / (end - start + 1);
+    if (end >= sectionSpans.count())
+        sectionSpans.resize(end + 1);
+    SectionSpan *sectiondata = sectionSpans.data();
+    for (int i = start; i <= end; ++i) {
+        length += (sizePerSection - sectiondata[i].size);
+        sectionStartposRecalc |= (sectiondata[i].size != sizePerSection);
+        sectiondata[i].size = sizePerSection;
+        sectiondata[i].resizeMode = mode;
     }
 }
 
 void QHeaderViewPrivate::removeSectionsFromSpans(int start, int end)
 {
     // remove sections
-    int start_section = 0;
-    QList spansToRemove;
-    for (int i = 0; i < sectionSpans.count(); ++i) {
-        int end_section = start_section + sectionSpans.at(i).count - 1;
-        int section_size = sectionSpans.at(i).sectionSize();
-        int section_count = sectionSpans.at(i).count;
-        if (start <= start_section && end >= end_section) {
-            // the change covers the entire span
-            spansToRemove.append(i);
-            if (end == end_section)
-                break;
-        } else if (start > start_section && end < end_section) {
-            // all the removed sections are inside the span
-            int change = (end - start + 1);
-            sectionSpans[i].count -= change;
-            sectionSpans[i].size = section_size * sectionSpans.at(i).count;
-            length -= (change * section_size);
-            break;
-        } else if (start >= start_section && start <= end_section) {
-            // the some of the removed sections are inside the span,at the end
-            int change = qMin(end_section - start + 1, end - start + 1);
-            sectionSpans[i].count -= change;
-            sectionSpans[i].size = section_size * sectionSpans.at(i).count;
-            start += change;
-            length -= (change * section_size);
-            // the change affects several spans
-        } else if (end >= start_section && end <= end_section) {
-            // the some of the removed sections are inside the span, at the beginning
-            int change = qMin((end - start_section + 1), end - start + 1);
-            sectionSpans[i].count -= change;
-            sectionSpans[i].size = section_size * sectionSpans.at(i).count;
-            length -= (change * section_size);
-            break;
-        }
-        start_section += section_count;
-    }
-
-    for (int i = spansToRemove.count() - 1; i >= 0; --i) {
-        int s = spansToRemove.at(i);
-        length -= sectionSpans.at(s).size;
-        sectionSpans.remove(s);
-        // ### merge remaining spans
-    }
+    sectionStartposRecalc |= (end != sectionSpans.count() - 1);
+    int removedlength = 0;
+    for (int u = start; u <= end; ++u)
+        removedlength += sectionSpans.at(u).size;
+    length -= removedlength;
+    sectionSpans.remove(start, end - start + 1);
 }
 
 void QHeaderViewPrivate::clear()
@@ -3427,25 +3268,31 @@ void QHeaderViewPrivate::setDefaultSectionSize(int size)
 {
     Q_Q(QHeaderView);
     defaultSectionSize = size;
-    int currentVisualIndex = 0;
     for (int i = 0; i < sectionSpans.count(); ++i) {
         QHeaderViewPrivate::SectionSpan &span = sectionSpans[i];
         if (span.size > 0) {
             //we resize it if it is not hidden (ie size > 0)
-            const int newSize = span.count * size;
+            const int newSize = size;
             if (newSize != span.size) {
                 length += newSize - span.size; //the whole length is changed
                 const int oldSectionSize = span.sectionSize();
-                span.size = span.count * size;
-                for (int i = currentVisualIndex; i < currentVisualIndex + span.count; ++i) {
-                    emit q->sectionResized(logicalIndex(i), oldSectionSize, size);
-                }
+                span.size = size;
+                emit q->sectionResized(logicalIndex(i), oldSectionSize, size);
             }
         }
-        currentVisualIndex += span.count;
     }
 }
 
+void QHeaderViewPrivate::recalcSectionStartPos() const // linear (but fast)
+{
+    int pixelpos = 0;
+    for (QVector::const_iterator i = sectionSpans.constBegin(); i != sectionSpans.constEnd(); ++i) {
+        i->calculated_startpos = pixelpos; // write into const mutable
+        pixelpos += i->size;
+    }
+    sectionStartposRecalc = false;
+}
+
 void QHeaderViewPrivate::resizeSectionSpan(int visualIndex, int oldSize, int newSize)
 {
     Q_Q(QHeaderView);
@@ -3456,54 +3303,37 @@ void QHeaderViewPrivate::resizeSectionSpan(int visualIndex, int oldSize, int new
 
 int QHeaderViewPrivate::headerSectionSize(int visual) const
 {
-    // ### stupid iteration
-    int section_start = 0;
-    const int sectionSpansCount = sectionSpans.count();
-    for (int i = 0; i < sectionSpansCount; ++i) {
-        const QHeaderViewPrivate::SectionSpan ¤tSection = sectionSpans.at(i);
-        int section_end = section_start + currentSection.count - 1;
-        if (visual >= section_start && visual <= section_end)
-            return currentSection.sectionSize();
-        section_start = section_end + 1;
-    }
+    if (visual < sectionCount && visual >= 0)
+        return sectionSpans.at(visual).sectionSize();
     return -1;
 }
 
 int QHeaderViewPrivate::headerSectionPosition(int visual) const
 {
-    // ### stupid iteration
-    int section_start = 0;
-    int span_position = 0;
-    const int sectionSpansCount = sectionSpans.count();
-    for (int i = 0; i < sectionSpansCount; ++i) {
-        const QHeaderViewPrivate::SectionSpan ¤tSection = sectionSpans.at(i);
-        int section_end = section_start + currentSection.count - 1;
-        if (visual >= section_start && visual <= section_end)
-            return span_position + (visual - section_start) * currentSection.sectionSize();
-        section_start = section_end + 1;
-        span_position += currentSection.size;
+    if (visual < sectionCount && visual >= 0) {
+        if (sectionStartposRecalc)
+            recalcSectionStartPos();
+        return sectionSpans.at(visual).calculated_startpos;
     }
     return -1;
 }
 
 int QHeaderViewPrivate::headerVisualIndexAt(int position) const
 {
-    // ### stupid iteration
-    int span_start_section = 0;
-    int span_position = 0;
-    const int sectionSpansCount = sectionSpans.count();
-    for (int i = 0; i < sectionSpansCount; ++i) {
-        const QHeaderViewPrivate::SectionSpan ¤tSection = sectionSpans.at(i);
-        int next_span_start_section = span_start_section + currentSection.count;
-        int next_span_position = span_position + currentSection.size;
-        if (position == span_position && currentSection.size > 0)
-            return span_start_section;
-        if (position > span_position && position < next_span_position) {
-            int position_in_span = position - span_position;
-            return span_start_section + (position_in_span / currentSection.sectionSize());
+    if (sectionStartposRecalc)
+        recalcSectionStartPos();
+    int startidx = 0;
+    int endidx = sectionSpans.count() - 1;
+    while (startidx <= endidx) {
+        int middle = (endidx + startidx) / 2;
+        if (sectionSpans.at(middle).calculated_startpos > position) {
+            endidx = middle - 1;
+        } else {
+            if (sectionSpans.at(middle).calculatedEndPos() <= position)
+                startidx = middle + 1;
+            else // we found it.
+                return middle;
         }
-        span_start_section = next_span_start_section;
-        span_position = next_span_position;
     }
     return -1;
 }
@@ -3546,9 +3376,9 @@ int QHeaderViewPrivate::adjustedVisualIndex(int visualIndex) const
         int currentVisualIndex = 0;
         for (int i = 0; i < sectionSpans.count(); ++i) {
             if (sectionSpans.at(i).size == 0)
-                adjustedVisualIndex += sectionSpans.at(i).count;
+                ++adjustedVisualIndex;
             else
-                currentVisualIndex += sectionSpans.at(i).count;
+                ++currentVisualIndex;
             if (currentVisualIndex >= visualIndex)
                 break;
         }
@@ -3626,7 +3456,15 @@ bool QHeaderViewPrivate::read(QDataStream &in)
     globalResizeMode = (QHeaderView::ResizeMode)global;
 
     in >> sectionSpans;
-
+    // Spans in Qt5 only contains one element - but for backward compability with Qt4 we do the following
+    QVector newSectionSpans;
+    for (int u = 0; u < sectionSpans.count(); ++u) {
+        int count = sectionSpans.at(u).tmpDataStreamSectionCount;
+        for (int n = 0; n < count; ++n)
+            newSectionSpans.append(sectionSpans[u]);
+    }
+    sectionSpans = newSectionSpans;
+    recalcSectionStartPos();
     return true;
 }
 
diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h
index e26c4a64759..9d7d97f5828 100644
--- a/src/widgets/itemviews/qheaderview_p.h
+++ b/src/widgets/itemviews/qheaderview_p.h
@@ -97,7 +97,8 @@ public:
           lastSectionSize(0),
           sectionIndicatorOffset(0),
           sectionIndicator(0),
-          globalResizeMode(QHeaderView::Interactive)
+          globalResizeMode(QHeaderView::Interactive),
+          sectionStartposRecalc(true)
     {}
 
 
@@ -281,22 +282,24 @@ public:
     QLabel *sectionIndicator;
     QHeaderView::ResizeMode globalResizeMode;
     QList persistentHiddenSections;
-
+    mutable bool sectionStartposRecalc;
     // header section spans
 
     struct SectionSpan {
         int size;
-        int count;
+        mutable int calculated_startpos;
         QHeaderView::ResizeMode resizeMode;
-        inline SectionSpan() : size(0), count(0), resizeMode(QHeaderView::Interactive) {}
-        inline SectionSpan(int length, int sections, QHeaderView::ResizeMode mode)
-            : size(length), count(sections), resizeMode(mode) {}
-        inline int sectionSize() const { return (count > 0 ? size / count : 0); }
+        inline SectionSpan() : size(0), resizeMode(QHeaderView::Interactive) {}
+        inline SectionSpan(int length, QHeaderView::ResizeMode mode)
+            : size(length), calculated_startpos(-1), resizeMode(mode) {}
+        inline int sectionSize() const { return size; }
+        inline int calculatedEndPos() const { return calculated_startpos + size; }
 #ifndef QT_NO_DATASTREAM
+        int tmpDataStreamSectionCount;
         inline void write(QDataStream &out) const
-        { out << size; out << count; out << (int)resizeMode; }
+        { out << size; out << 1; out << (int)resizeMode; }
         inline void read(QDataStream &in)
-        { in >> size; in >> count; int m; in >> m; resizeMode = (QHeaderView::ResizeMode)m; }
+        { in >> size; in >> tmpDataStreamSectionCount; int m; in >> m; resizeMode = (QHeaderView::ResizeMode)m; }
 #endif
     };
 
@@ -306,12 +309,10 @@ public:
     void removeSectionsFromSpans(int start, int end);
     void resizeSectionSpan(int visualIndex, int oldSize, int newSize);
     void setDefaultSectionSize(int size);
+    void recalcSectionStartPos() const; // not really const
 
     inline int headerSectionCount() const { // for debugging
-        int count = 0;
-        for (int i = 0; i < sectionSpans.count(); ++i)
-            count += sectionSpans.at(i).count;
-        return count;
+        return sectionSpans.count();
     }
 
     inline int headerLength() const { // for debugging
@@ -329,12 +330,8 @@ public:
     }
 
     inline int sectionSpanIndex(int visual) const {
-        int section_start = 0;
-        for (int i = 0; i < sectionSpans.count(); ++i) {
-            int section_end = section_start + sectionSpans.at(i).count - 1;
-            if (visual >= section_start && visual <= section_end)
-                return i;
-            section_start = section_end + 1;
+        if (visual < sectionSpans.count() && visual >= 0) {
+            return visual;
         }
         return -1;
     }

From c455674555b263c98fe613612babab3efcf10345 Mon Sep 17 00:00:00 2001
From: Stephen Kelly 
Date: Fri, 10 Feb 2012 16:40:12 +0100
Subject: [PATCH 247/406] Make the cmake tests work with a namespace build.

Change-Id: I6858c324548373c57963b5ef137772a1f780ec78
Reviewed-by: Oswald Buddenhagen 
Reviewed-by: Clinton Stimpson 
Reviewed-by: Stephen Kelly 
---
 src/corelib/Qt5CoreConfigExtras.cmake.in              | 3 +++
 tests/manual/cmake/fail4/CMakeLists.txt               | 2 ++
 tests/manual/cmake/fail5/CMakeLists.txt               | 2 ++
 tests/manual/cmake/pass(needsquoting)6/CMakeLists.txt | 2 ++
 tests/manual/cmake/pass2/CMakeLists.txt               | 2 ++
 tests/manual/cmake/pass3/CMakeLists.txt               | 2 ++
 tests/manual/cmake/pass7/CMakeLists.txt               | 1 +
 7 files changed, 14 insertions(+)

diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in
index 057c8ff75e9..155961bc9a6 100644
--- a/src/corelib/Qt5CoreConfigExtras.cmake.in
+++ b/src/corelib/Qt5CoreConfigExtras.cmake.in
@@ -11,3 +11,6 @@ list(APPEND Qt5Core_INCLUDE_DIRS \"${_qt5_corelib_install_prefix}/mkspecs/defaul
 if (NOT \"$${CMAKE_ADD_FPIE_FLAGS}\" STREQUAL \"\")
     set(Qt5Core_COMPILE_FLAGS "-fPIE")
 endif()
+
+list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE)
+list(APPEND Qt5Core_COMPILE_DEFINITIONS QT_NAMESPACE=$$QT_NAMESPACE)
diff --git a/tests/manual/cmake/fail4/CMakeLists.txt b/tests/manual/cmake/fail4/CMakeLists.txt
index dcd4b8bd650..2466e24d3a3 100644
--- a/tests/manual/cmake/fail4/CMakeLists.txt
+++ b/tests/manual/cmake/fail4/CMakeLists.txt
@@ -7,6 +7,8 @@ find_package(Qt5Core REQUIRED)
 
 include_directories(${Qt5Core_INCLUDE_DIRS})
 
+add_definitions(${Qt5Core_DEFINITIONS})
+
 qt5_wrap_cpp(moc_files myobject.h)
 
 # Test options. The -binary option generates a binary to dlopen instead of
diff --git a/tests/manual/cmake/fail5/CMakeLists.txt b/tests/manual/cmake/fail5/CMakeLists.txt
index f82a62b626f..9aedf4a0089 100644
--- a/tests/manual/cmake/fail5/CMakeLists.txt
+++ b/tests/manual/cmake/fail5/CMakeLists.txt
@@ -7,6 +7,8 @@ find_package(Qt5Core REQUIRED)
 
 include_directories(${Qt5Core_INCLUDE_DIRS})
 
+add_definitions(${Qt5Core_DEFINITIONS})
+
 # Test options. The -i option removes the include "myobject.h" from the moc file
 # causing a compile failure. -> Options work
 qt5_wrap_cpp(moc_files myobject.h OPTIONS -i)
diff --git a/tests/manual/cmake/pass(needsquoting)6/CMakeLists.txt b/tests/manual/cmake/pass(needsquoting)6/CMakeLists.txt
index cc1a1bc588f..fb971f9ebd2 100644
--- a/tests/manual/cmake/pass(needsquoting)6/CMakeLists.txt
+++ b/tests/manual/cmake/pass(needsquoting)6/CMakeLists.txt
@@ -9,6 +9,8 @@ find_package(Qt5Widgets REQUIRED)
 
 include_directories(${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS})
 
+add_definitions(${Qt5Core_DEFINITIONS})
+
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
 
 qt5_wrap_cpp(moc_files mywidget.h)
diff --git a/tests/manual/cmake/pass2/CMakeLists.txt b/tests/manual/cmake/pass2/CMakeLists.txt
index ac1bb15846a..a52744623e6 100644
--- a/tests/manual/cmake/pass2/CMakeLists.txt
+++ b/tests/manual/cmake/pass2/CMakeLists.txt
@@ -7,6 +7,8 @@ find_package(Qt5Core REQUIRED)
 
 include_directories(${Qt5Core_INCLUDE_DIRS})
 
+add_definitions(${Qt5Core_DEFINITIONS})
+
 qt5_wrap_cpp(moc_files myobject.h)
 
 qt5_add_resources(rcc_files "pass2.qrc")
diff --git a/tests/manual/cmake/pass3/CMakeLists.txt b/tests/manual/cmake/pass3/CMakeLists.txt
index 11402e2e186..b8361618136 100644
--- a/tests/manual/cmake/pass3/CMakeLists.txt
+++ b/tests/manual/cmake/pass3/CMakeLists.txt
@@ -8,6 +8,8 @@ find_package(Qt5Widgets REQUIRED)
 
 include_directories(${Qt5Widgets_INCLUDE_DIRS})
 
+add_definitions(${Qt5Core_DEFINITIONS})
+
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
 
 qt5_wrap_cpp(moc_files mywidget.h)
diff --git a/tests/manual/cmake/pass7/CMakeLists.txt b/tests/manual/cmake/pass7/CMakeLists.txt
index f639c164ea2..e7c9b46eada 100644
--- a/tests/manual/cmake/pass7/CMakeLists.txt
+++ b/tests/manual/cmake/pass7/CMakeLists.txt
@@ -6,5 +6,6 @@ project(pass7)
 find_package(Qt5Core REQUIRED)
 
 include_directories(${Qt5Core_INCLUDE_DIRS})
+add_definitions(${Qt5Core_DEFINITIONS})
 
 add_executable(myobject main.cpp)

From 394315d902d9068a53439737906c00d48023d182 Mon Sep 17 00:00:00 2001
From: Stephen Kelly 
Date: Sat, 11 Feb 2012 01:10:07 +0100
Subject: [PATCH 248/406] Move the removal of the Quit event to QWindow.

Change-Id: If524127ba9dab9ef065aaf4079294295eef8e49b
Reviewed-by: Bradley T. Hughes 
---
 src/gui/kernel/qwindow.cpp                    |  3 ++
 src/widgets/kernel/qwidget.cpp                |  3 --
 .../qguiapplication/tst_qguiapplication.cpp   | 40 +++++++++++++++++++
 .../kernel/qapplication/tst_qapplication.cpp  | 40 +++++++++++++++++++
 4 files changed, 83 insertions(+), 3 deletions(-)

diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 43b7e391035..61ae2a2438c 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -178,6 +178,9 @@ void QWindow::setVisible(bool visible)
         create();
 
     if (visible) {
+        // remove posted quit events when showing a new window
+        QCoreApplication::removePostedEvents(qApp, QEvent::Quit);
+
         QShowEvent showEvent;
         QGuiApplication::sendEvent(this, &showEvent);
     }
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index e3a8908c375..f5a1ea15cd0 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -7245,9 +7245,6 @@ void QWidget::setVisible(bool visible)
         setAttribute(Qt::WA_KeyboardFocusChange, false);
 
         if (isWindow() || parentWidget()->isVisible()) {
-            // remove posted quit events when showing a new window
-            QCoreApplication::removePostedEvents(qApp, QEvent::Quit);
-
             d->show_helper();
 
             qApp->d_func()->sendSyntheticEnterLeave(this);
diff --git a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp
index 2fd875b7f4b..8d0836e7c3b 100644
--- a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp
+++ b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp
@@ -53,6 +53,7 @@ private slots:
     void focusObject();
     void allWindows();
     void topLevelWindows();
+    void abortQuitOnShow();
 };
 
 class DummyWindow : public QWindow
@@ -152,5 +153,44 @@ void tst_QGuiApplication::topLevelWindows()
     QCOMPARE(app.topLevelWindows().count(), 0);
 }
 
+class ShowCloseShowWindow : public QWindow
+{
+    Q_OBJECT
+public:
+    ShowCloseShowWindow(bool showAgain, QWindow *parent = 0)
+      : QWindow(parent), showAgain(showAgain)
+    {
+        QTimer::singleShot(0, this, SLOT(doClose()));
+        QTimer::singleShot(500, this, SLOT(exitApp()));
+    }
+
+private slots:
+    void doClose() {
+        close();
+        if (showAgain)
+            show();
+    }
+
+    void exitApp() {
+      qApp->exit(1);
+    }
+
+private:
+    bool showAgain;
+};
+
+void tst_QGuiApplication::abortQuitOnShow()
+{
+    int argc = 0;
+    QGuiApplication app(argc, 0);
+    QWindow *window1 = new ShowCloseShowWindow(false);
+    window1->show();
+    QCOMPARE(app.exec(), 0);
+
+    QWindow *window2 = new ShowCloseShowWindow(true);
+    window2->show();
+    QCOMPARE(app.exec(), 1);
+}
+
 QTEST_APPLESS_MAIN(tst_QGuiApplication)
 #include "tst_qguiapplication.moc"
diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
index 7017c6157e0..c6009569127 100644
--- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
@@ -149,6 +149,8 @@ private slots:
     void testQuitLock8();
 
     void globalStaticObjectDestruction(); // run this last
+
+    void abortQuitOnShow();
 };
 
 class EventSpy : public QObject
@@ -2560,6 +2562,44 @@ void tst_QApplication::testQuitLock8()
     // No hang = pass
 }
 
+class ShowCloseShowWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    ShowCloseShowWidget(bool showAgain, QWidget *parent = 0)
+      : QWidget(parent), showAgain(showAgain)
+    {
+        QTimer::singleShot(0, this, SLOT(doClose()));
+        QTimer::singleShot(500, this, SLOT(exitApp()));
+    }
+
+private slots:
+    void doClose() {
+        close();
+        if (showAgain)
+            show();
+    }
+
+    void exitApp() {
+      qApp->exit(1);
+    }
+
+private:
+    bool showAgain;
+};
+
+void tst_QApplication::abortQuitOnShow()
+{
+    int argc = 0;
+    QApplication app(argc, 0);
+    QWidget *window1 = new ShowCloseShowWidget(false);
+    window1->show();
+    QCOMPARE(app.exec(), 0);
+
+    QWidget *window2 = new ShowCloseShowWidget(true);
+    window2->show();
+    QCOMPARE(app.exec(), 1);
+}
 
 /*
     This test is meant to ensure that certain objects (public & commonly used)

From 1747f66457420e970b9402e6418693e17a950a6f Mon Sep 17 00:00:00 2001
From: Friedemann Kleint 
Date: Tue, 14 Feb 2012 11:52:05 +0100
Subject: [PATCH 249/406] Add a ThemeChange event.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Pass it from QWindowSystemInterface via QWindow to the widgets.
- Add handler code from 4.8 / qapplication_win.cpp to qwidget.cpp.

Change-Id: Ic759563aa00cb93fe014c1bf41020446c1927dec
Reviewed-by: Morten Johan Sørvig 
Reviewed-by: Samuel Rødal 
---
 src/corelib/kernel/qcoreevent.h               |  2 ++
 src/gui/kernel/qguiapplication.cpp            | 12 ++++++++++++
 src/gui/kernel/qguiapplication_p.h            |  1 +
 src/gui/kernel/qwindowsysteminterface_qpa.cpp |  6 ++++++
 src/gui/kernel/qwindowsysteminterface_qpa.h   |  2 ++
 src/gui/kernel/qwindowsysteminterface_qpa_p.h |  8 ++++++++
 src/widgets/kernel/qwidget.cpp                | 15 +++++++++++++++
 src/widgets/kernel/qwidgetwindow_qpa.cpp      |  6 ++++++
 8 files changed, 52 insertions(+)

diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h
index 8182ac907e9..1f36f9c9c8c 100644
--- a/src/corelib/kernel/qcoreevent.h
+++ b/src/corelib/kernel/qcoreevent.h
@@ -279,6 +279,8 @@ public:
 
         TouchCancel = 211,
 
+        ThemeChange = 212,
+
         // 512 reserved for Qt Jambi's MetaCall event
         // 513 reserved for Qt Jambi's DeleteOnMainThread event
 
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 5ca6364fbb5..4d80aafea54 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -661,6 +661,10 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
         QGuiApplicationPrivate::reportLogicalDotsPerInchChange(
                 static_cast(e));
         break;
+    case QWindowSystemInterfacePrivate::ThemeChange:
+        QGuiApplicationPrivate::processThemeChanged(
+                    static_cast(e));
+        break;
     case QWindowSystemInterfacePrivate::Map:
         QGuiApplicationPrivate::processMapEvent(static_cast(e));
         break;
@@ -888,6 +892,14 @@ void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfa
     }
 }
 
+void QGuiApplicationPrivate::processThemeChanged(QWindowSystemInterfacePrivate::ThemeChangeEvent *tce)
+{
+    if (QWindow *window  = tce->window.data()) {
+        QEvent e(QEvent::ThemeChange);
+        QGuiApplication::sendSpontaneousEvent(window, &e);
+    }
+}
+
 void QGuiApplicationPrivate::processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent *e)
 {
     if (e->tlw.isNull())
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 5f2e92c504e..7fafe0336dc 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -125,6 +125,7 @@ public:
     static void reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e);
     static void reportAvailableGeometryChange(QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e);
     static void reportLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e);
+    static void processThemeChanged(QWindowSystemInterfacePrivate::ThemeChangeEvent *tce);
 
     static void processMapEvent(QWindowSystemInterfacePrivate::MapEvent *e);
     static void processUnmapEvent(QWindowSystemInterfacePrivate::UnmapEvent *e);
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.cpp b/src/gui/kernel/qwindowsysteminterface_qpa.cpp
index f4f7551c049..e6c4454104e 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa.cpp
+++ b/src/gui/kernel/qwindowsysteminterface_qpa.cpp
@@ -340,6 +340,12 @@ void QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QScreen *scree
     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
 }
 
+void QWindowSystemInterface::handleThemeChange(QWindow *tlw)
+{
+    QWindowSystemInterfacePrivate::ThemeChangeEvent *e = new QWindowSystemInterfacePrivate::ThemeChangeEvent(tlw);
+    QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+}
+
 void QWindowSystemInterface::handleMapEvent(QWindow *tlw)
 {
     QWindowSystemInterfacePrivate::MapEvent *e = new QWindowSystemInterfacePrivate::MapEvent(tlw);
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.h b/src/gui/kernel/qwindowsysteminterface_qpa.h
index 28ec68ec590..78152a11783 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa.h
+++ b/src/gui/kernel/qwindowsysteminterface_qpa.h
@@ -130,6 +130,8 @@ public:
     static void handleScreenAvailableGeometryChange(QScreen *screen, const QRect &newAvailableGeometry);
     static void handleScreenLogicalDotsPerInchChange(QScreen *screen, qreal newDpiX, qreal newDpiY);
 
+    static void handleThemeChange(QWindow *tlw);
+
     // For event dispatcher implementations
     static bool sendWindowSystemEvents(QAbstractEventDispatcher *eventDispatcher, QEventLoop::ProcessEventsFlags flags);
     static int windowSystemEventsQueued();
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa_p.h b/src/gui/kernel/qwindowsysteminterface_qpa_p.h
index 0bd9ba017aa..661b39da882 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_qpa_p.h
@@ -64,6 +64,7 @@ public:
         ScreenGeometry,
         ScreenAvailableGeometry,
         ScreenLogicalDotsPerInch,
+        ThemeChange,
         Map,
         Unmap,
         Expose
@@ -230,6 +231,13 @@ public:
         qreal dpiY;
     };
 
+    class ThemeChangeEvent : public WindowSystemEvent {
+    public:
+        explicit ThemeChangeEvent(QWindow * w)
+            : WindowSystemEvent(ThemeChange), window(w) { }
+        QWeakPointer window;
+    };
+
     class MapEvent : public WindowSystemEvent {
     public:
         MapEvent(QWindow *mapped)
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index f5a1ea15cd0..f98f7fbe669 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -8046,6 +8046,7 @@ bool QWidget::event(QEvent *event)
     case QEvent::LocaleChange:
     case QEvent::MacSizeChange:
     case QEvent::ContentsRectChange:
+    case QEvent::ThemeChange:
         changeEvent(event);
         break;
 
@@ -8249,6 +8250,20 @@ void QWidget::changeEvent(QEvent * event)
         update();
         break;
 
+    case QEvent::ThemeChange:
+        if (QApplication::desktopSettingsAware() && windowType() != Qt::Desktop
+            && qApp && !QApplication::closingDown()) {
+            if (testAttribute(Qt::WA_WState_Polished))
+                QApplication::style()->unpolish(this);
+            if (testAttribute(Qt::WA_WState_Polished))
+                QApplication::style()->polish(this);
+            QEvent styleChangedEvent(QEvent::StyleChange);
+            QCoreApplication::sendEvent(this, &styleChangedEvent);
+            if (isVisible())
+                update();
+        }
+        break;
+
 #ifdef Q_WS_MAC
     case QEvent::MacSizeChange:
         updateGeometry();
diff --git a/src/widgets/kernel/qwidgetwindow_qpa.cpp b/src/widgets/kernel/qwidgetwindow_qpa.cpp
index c2524567f10..c04d8a9dc3e 100644
--- a/src/widgets/kernel/qwidgetwindow_qpa.cpp
+++ b/src/widgets/kernel/qwidgetwindow_qpa.cpp
@@ -150,6 +150,12 @@ bool QWidgetWindow::event(QEvent *event)
         handleWindowStateChangedEvent(static_cast(event));
         return true;
 
+    case QEvent::ThemeChange: {
+        QEvent widgetEvent(QEvent::ThemeChange);
+        QGuiApplication::sendSpontaneousEvent(m_widget, &widgetEvent);
+    }
+        return true;
+
     default:
         break;
     }

From 18965b1384cb3f85dc9e2d9c961c343331e8bd47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= 
Date: Mon, 13 Feb 2012 13:01:59 +0100
Subject: [PATCH 250/406] Add QMetaType::FirstCoreType enum value.

We should not assume that the first type id is 0.

Change-Id: I17ba6ba57e97ebd495904bfd11235fe458f214e5
Reviewed-by: Kent Hansen 
---
 src/corelib/kernel/qmetatype.h                              | 1 +
 tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp         | 3 ++-
 tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp | 2 +-
 tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp   | 2 +-
 4 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 9e702298c13..ff3f9341e4e 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -184,6 +184,7 @@ public:
         // these are merged with QVariant
         QT_FOR_EACH_STATIC_TYPE(QT_DEFINE_METATYPE_ID)
 
+        FirstCoreType = Void,
         LastCoreType = QModelIndex,
         FirstGuiType = QFont,
         LastGuiType = QPolygonF,
diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
index 001749e88ed..ccdab176680 100644
--- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
+++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
@@ -3542,6 +3542,7 @@ void tst_QVariant::loadQVariantFromDataStream(QDataStream::Version version)
     stream >> typeName >> loadedVariant;
 
     const int id = QMetaType::type(typeName.toLatin1());
+
     QVariant constructedVariant(static_cast(id));
     QCOMPARE(constructedVariant.userType(), id);
     QCOMPARE(QMetaType::typeName(loadedVariant.userType()), typeName.toLatin1().constData());
@@ -3616,7 +3617,7 @@ void tst_QVariant::debugStream_data()
 {
     QTest::addColumn("variant");
     QTest::addColumn("typeId");
-    for (int id = QMetaType::Void; id < QMetaType::User; ++id) {
+    for (int id = 0; id < QMetaType::User; ++id) {
         const char *tagName = QMetaType::typeName(id);
         if (!tagName)
             continue;
diff --git a/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp
index 14895863e45..1c5dc9227fc 100644
--- a/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp
+++ b/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp
@@ -240,7 +240,7 @@ void tst_QMetaType::isRegisteredNotRegistered()
 void tst_QMetaType::constructCoreType_data()
 {
     QTest::addColumn("typeId");
-    for (int i = 0; i <= QMetaType::LastCoreType; ++i)
+    for (int i = QMetaType::FirstCoreType; i <= QMetaType::LastCoreType; ++i)
         QTest::newRow(QMetaType::typeName(i)) << i;
     // GUI types are tested in tst_QGuiMetaType.
 }
diff --git a/tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp
index 0c4af173765..e842e18d52f 100644
--- a/tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp
+++ b/tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp
@@ -305,7 +305,7 @@ void tst_qvariant::stringVariantValue()
 void tst_qvariant::createCoreType_data()
 {
     QTest::addColumn("typeId");
-    for (int i = 0; i <= QMetaType::LastCoreType; ++i)
+    for (int i = QMetaType::FirstCoreType; i <= QMetaType::LastCoreType; ++i)
         QTest::newRow(QMetaType::typeName(i)) << i;
 }
 

From 90feedb6429df225b81bc279093ae1ca1278b391 Mon Sep 17 00:00:00 2001
From: Oswald Buddenhagen 
Date: Wed, 8 Feb 2012 11:38:07 +0100
Subject: [PATCH 251/406] bootstrap configure.exe on windows

it is *ugly* to have the binary in the repository.
this adds a few seconds to the windows build, as the configure needs to
be rebuilt, obviously. that's almost negligible.

Change-Id: I40ffde23b3c3af2b6bab3e78cd0a9f433214b563
Reviewed-by: Rohan McGovern 
---
 configure.bat                    | 121 ++++++++++++++++++++++++
 configure.exe                    | Bin 1140736 -> 0 bytes
 tools/configure/Makefile.mingw   |  92 ++++++++++++++++++
 tools/configure/Makefile.win32   | 157 +++++++++++++++++++++++++++++++
 tools/configure/configureapp.cpp |  22 +++--
 5 files changed, 385 insertions(+), 7 deletions(-)
 create mode 100644 configure.bat
 delete mode 100644 configure.exe
 create mode 100644 tools/configure/Makefile.mingw
 create mode 100644 tools/configure/Makefile.win32

diff --git a/configure.bat b/configure.bat
new file mode 100644
index 00000000000..e872de27972
--- /dev/null
+++ b/configure.bat
@@ -0,0 +1,121 @@
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::
+:: Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+:: Contact: http://www.qt-project.org/
+::
+:: 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$
+::
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+@echo off
+set QTSRC=%~dp0
+set QTDIR=%CD%
+if exist configure.exe goto conf
+echo Please wait while bootstrapping configure ...
+
+for %%C in (cl.exe icl.exe g++.exe perl.exe) do set %%C=%%~$PATH:C
+
+set nosyncqt=
+if not exist include (
+    if "%perl.exe%" == "" (
+        echo Perl not found in PATH. Aborting. >&2
+        exit /b 1
+    )
+    if not exist mkspecs (
+        md mkspecs
+        if errorlevel 1 goto exit
+    )
+    perl %QTSRC%bin\syncqt -outdir %QTDIR% %QTSRC%
+    if errorlevel 1 goto exit
+    set nosyncqt=-no-syncqt
+)
+
+if not exist src\corelib\global\qconfig.h (
+    if not exist src\corelib\global (
+        md src\corelib\global
+        if errorlevel 1 goto exit
+    )
+    echo #define Q_BIG_ENDIAN 4321 > src\corelib\global\qconfig.h
+    echo #define Q_LITTLE_ENDIAN 1234 >> src\corelib\global\qconfig.h
+    echo #define Q_BYTE_ORDER Q_LITTLE_ENDIAN >> src\corelib\global\qconfig.h
+)
+
+if not exist tools\configure (
+    md tools\configure
+    if errorlevel 1 goto exit
+)
+cd tools\configure
+if errorlevel 1 goto exit
+
+echo #### Generated by configure.bat - DO NOT EDIT! ####> Makefile
+echo/>> Makefile
+for /f "tokens=3 usebackq" %%V in (`findstr QT_VERSION_STR %QTSRC%\src\corelib\global\qglobal.h`) do @echo QTVERSION = %%~V>> Makefile
+if not "%cl.exe%" == "" (
+    echo CXX = cl>>Makefile
+    echo EXTRA_CXXFLAGS =>>Makefile
+    rem This must have a trailing space.
+    echo QTSRC = %QTSRC% >> Makefile
+    set tmpl=win32
+    set make=nmake
+) else if not "%icl.exe%" == "" (
+    echo CXX = icl>>Makefile
+    echo EXTRA_CXXFLAGS = /Zc:forScope>>Makefile
+    rem This must have a trailing space.
+    echo QTSRC = %QTSRC% >> Makefile
+    set tmpl=win32
+    set make=nmake
+) else if not "%g++.exe%" == "" (
+    echo CXX = g++>>Makefile
+    echo EXTRA_CXXFLAGS =>>Makefile
+    rem This must NOT have a trailing space.
+    echo QTSRC = %QTSRC:\=/%>> Makefile
+    set tmpl=mingw
+    set make=mingw32-make
+) else (
+    echo No suitable compiler found in PATH. Aborting. >&2
+    cd ..\..
+    exit /b 1
+)
+echo/>> Makefile
+type %QTSRC%tools\configure\Makefile.%tmpl% >> Makefile
+
+%make%
+if errorlevel 1 (cd ..\.. & exit /b 1)
+
+cd ..\..
+
+:conf
+configure.exe -srcdir %QTSRC% %nosyncqt% %*
+:exit
diff --git a/configure.exe b/configure.exe
deleted file mode 100644
index 86dca34c9d8b6eb9b7db5415db5650e0cbb1134b..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1140736
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

`+5M}k( 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�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%0A#|i{-hCQ`lTf&h(OVoY_moyKPrhC#x^Q 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 DnRAev diff --git a/tools/configure/Makefile.mingw b/tools/configure/Makefile.mingw new file mode 100644 index 00000000000..5951cb4e922 --- /dev/null +++ b/tools/configure/Makefile.mingw @@ -0,0 +1,92 @@ +CORESRC = $(QTSRC)src/corelib +TOOLSRC = $(QTSRC)tools +CONFSRC = $(TOOLSRC)/configure + +RAW_PCH = configure_pch.h +PCH = $(RAW_PCH).gch/c++ +CXX = g++ +DEFINES = -DUNICODE -DQT_NODLL -DQT_NO_DATASTREAM -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_STL -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DCOMMERCIAL_VERSION +INCPATH = -I"../../include" -I"../../include/QtCore" -I"../../include/QtCore/$(QTVERSION)" -I"../../include/QtCore/$(QTVERSION)/QtCore" -I"$(TOOLSRC)/shared" -I"$(QTSRC)mkspecs/win32-g++" +CXXFLAGS_BARE = -fno-rtti -fno-exceptions -mthreads -Wall -Wextra $(DEFINES) $(INCPATH) +CXXFLAGS = -include $(RAW_PCH) $(CXXFLAGS_BARE) +LINK = g++ +LFLAGS = -Wl,-subsystem,console -mthreads +LIBS = -lole32 -ladvapi32 -luuid + +TARGET = ../../configure.exe + +OBJECTS = \ + main.o \ + configureapp.o \ + environment.o \ + tools.o \ + qbytearray.o \ + qbytearraymatcher.o \ + qhash.o \ + qlist.o \ + qlocale.o \ + qlocale_win.o \ + qlocale_tools.o \ + qvector.o \ + qutfcodec.o \ + qtextcodec.o \ + qglobal.o \ + qnumeric.o \ + qbuffer.o \ + qdatastream.o \ + qdir.o \ + qdiriterator.o \ + qfile.o \ + qfileinfo.o \ + qabstractfileengine.o \ + qfilesystementry.o \ + qfilesystemengine.o \ + qfilesystemengine_win.o \ + qfilesystemiterator_win.o \ + qfsfileengine.o \ + qfsfileengine_win.o \ + qfsfileengine_iterator.o \ + qiodevice.o \ + qtextstream.o \ + qlogging.o \ + qtemporaryfile.o \ + qsystemlibrary.o \ + qbitarray.o \ + qdatetime.o \ + qmap.o \ + qregexp.o \ + qstring.o \ + qstringlist.o \ + qvsnprintf.o \ + qvariant.o \ + qsystemerror.o \ + qurl.o \ + qmetatype.o \ + qmalloc.o \ + qxmlstream.o \ + qxmlutils.o \ + quuid.o \ + qcryptographichash.o \ + registry.o + +$(TARGET): $(OBJECTS) + $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS) + +$(OBJECTS): $(PCH) + +CHK_DIR_EXISTS = test -d +MKDIR=mkdir -p +$(PCH): $(CONFSRC)/configure_pch.h + @$(CHK_DIR_EXISTS) $(RAW_PCH).gch || $(MKDIR) $(RAW_PCH).gch + $(CXX) -x c++-header -c $(CXXFLAGS_BARE) -o $@ $< + +VPATH = $(CONFSRC):$(TOOLSRC)/shared/windows:$(CORESRC)/global:$(CORESRC)/kernel:$(CORESRC)/tools:$(CORESRC)/codecs:$(CORESRC)/io:$(CORESRC)/xml:$(CORESRC)/plugin + +main.o: $(CONFSRC)/configureapp.h +configureapp.o: $(CONFSRC)/configureapp.h $(CONFSRC)/environment.h $(CONFSRC)/tools.h +environment.o: $(CONFSRC)/environment.h +tools.o: $(CONFSRC)/tools.h + +clean: + -rm -f *.o + -rm -rf *.gch diff --git a/tools/configure/Makefile.win32 b/tools/configure/Makefile.win32 new file mode 100644 index 00000000000..92de55f137d --- /dev/null +++ b/tools/configure/Makefile.win32 @@ -0,0 +1,157 @@ +CORESRC = $(QTSRC)src\corelib +TOOLSRC = $(QTSRC)tools +CONFSRC = $(TOOLSRC)\configure + +PCH = configure_pch.pch +DEFINES = -DUNICODE -DQT_NODLL -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_STL -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DCOMMERCIAL_VERSION +INCPATH = -I"..\..\include" -I"..\..\include\QtCore" -I"..\..\include\QtCore\$(QTVERSION)" -I"..\..\include\QtCore\$(QTVERSION)\QtCore" -I"$(TOOLSRC)\shared" -I"$(QTSRC)mkspecs\win32-msvc2008" +CXXFLAGS_BARE = -nologo -Zm200 -Zc:wchar_t -MT -W3 -GR -EHsc -w34100 -w34189 $(EXTRA_CXXFLAGS) $(DEFINES) $(INCPATH) +CXXFLAGS = -FIconfigure_pch.h -Yuconfigure_pch.h -Fp$(PCH) -MP $(CXXFLAGS_BARE) +LINK = link +LFLAGS = /NOLOGO /DYNAMICBASE /NXCOMPAT /INCREMENTAL:NO /SUBSYSTEM:CONSOLE "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" /MANIFEST /MANIFESTFILE:"configure.intermediate.manifest" +LIBS = ole32.lib advapi32.lib + +TARGET = ..\..\configure.exe + +OBJECTS = \ + main.obj \ + configureapp.obj \ + environment.obj \ + tools.obj \ + qbytearray.obj \ + qbytearraymatcher.obj \ + qhash.obj \ + qlist.obj \ + qlocale.obj \ + qlocale_win.obj \ + qlocale_tools.obj \ + qvector.obj \ + qutfcodec.obj \ + qtextcodec.obj \ + qglobal.obj \ + qnumeric.obj \ + qbuffer.obj \ + qdatastream.obj \ + qdir.obj \ + qdiriterator.obj \ + qfile.obj \ + qfileinfo.obj \ + qabstractfileengine.obj \ + qfilesystementry.obj \ + qfilesystemengine.obj \ + qfilesystemengine_win.obj \ + qfilesystemiterator_win.obj \ + qfsfileengine.obj \ + qfsfileengine_win.obj \ + qfsfileengine_iterator.obj \ + qiodevice.obj \ + qtextstream.obj \ + qlogging.obj \ + qtemporaryfile.obj \ + qsystemlibrary.obj \ + qbitarray.obj \ + qdatetime.obj \ + qmap.obj \ + qregexp.obj \ + qstring.obj \ + qstringlist.obj \ + qvsnprintf.obj \ + qvariant.obj \ + qsystemerror.obj \ + qurl.obj \ + qmetatype.obj \ + qmalloc.obj \ + qxmlstream.obj \ + qxmlutils.obj \ + quuid.obj \ + qcryptographichash.obj \ + registry.obj + +$(TARGET): $(OBJECTS) + $(LINK) $(LFLAGS) /OUT:$(TARGET) @<< + $(OBJECTS) $(LIBS) +<< + mt.exe -nologo -manifest "configure.intermediate.manifest" -outputresource:$(TARGET);1 + +clean: + -del *.obj + -del *.pch + -del configure.intermediate.manifest + +$(PCH): $(CONFSRC)\configure_pch.h + $(CXX) -c -Yc $(CXXFLAGS_BARE) -Fp$@ -Foconfigure_pch.obj -TP $** + +main.obj: $(CONFSRC)\main.cpp $(CONFSRC)\configureapp.h $(PCH) +configureapp.obj: $(CONFSRC)\configureapp.cpp $(CONFSRC)\configureapp.h $(CONFSRC)\environment.h $(CONFSRC)\tools.h $(PCH) +environment.obj: $(CONFSRC)\environment.cpp $(CONFSRC)\environment.h $(PCH) +tools.obj: $(CONFSRC)\tools.cpp $(CONFSRC)\tools.h $(PCH) +registry.obj: $(TOOLSRC)\shared\windows\registry.cpp $(PCH) +qbytearray.obj: $(CORESRC)\tools\qbytearray.cpp $(PCH) +qbytearraymatcher.obj: $(CORESRC)\tools\qbytearraymatcher.cpp $(PCH) +qhash.obj: $(CORESRC)\tools\qhash.cpp $(PCH) +qlist.obj: $(CORESRC)\tools\qlist.cpp $(PCH) +qlocale.obj: $(CORESRC)\tools\qlocale.cpp $(PCH) +qlocale_win.obj: $(CORESRC)\tools\qlocale_win.cpp $(PCH) +qlocale_tools.obj: $(CORESRC)\tools\qlocale_tools.cpp $(PCH) +qvector.obj: $(CORESRC)\tools\qvector.cpp $(PCH) +qutfcodec.obj: $(CORESRC)\codecs\qutfcodec.cpp $(PCH) +qtextcodec.obj: $(CORESRC)\codecs\qtextcodec.cpp $(PCH) +qglobal.obj: $(CORESRC)\global\qglobal.cpp $(PCH) +qnumeric.obj: $(CORESRC)\global\qnumeric.cpp $(PCH) +qbuffer.obj: $(CORESRC)\io\qbuffer.cpp $(PCH) +qdatastream.obj: $(CORESRC)\io\qdatastream.cpp $(PCH) +qdir.obj: $(CORESRC)\io\qdir.cpp $(PCH) +qdiriterator.obj: $(CORESRC)\io\qdiriterator.cpp $(PCH) +qfile.obj: $(CORESRC)\io\qfile.cpp $(PCH) +qfileinfo.obj: $(CORESRC)\io\qfileinfo.cpp $(PCH) +qabstractfileengine.obj: $(CORESRC)\io\qabstractfileengine.cpp $(PCH) +qfilesystementry.obj: $(CORESRC)\io\qfilesystementry.cpp $(PCH) +qfilesystemengine.obj: $(CORESRC)\io\qfilesystemengine.cpp $(PCH) +qfilesystemengine_win.obj: $(CORESRC)\io\qfilesystemengine_win.cpp $(PCH) +qfilesystemiterator_win.obj: $(CORESRC)\io\qfilesystemiterator_win.cpp $(PCH) +qfsfileengine.obj: $(CORESRC)\io\qfsfileengine.cpp $(PCH) +qfsfileengine_win.obj: $(CORESRC)\io\qfsfileengine_win.cpp $(PCH) +qfsfileengine_iterator.obj: $(CORESRC)\io\qfsfileengine_iterator.cpp $(PCH) +qiodevice.obj: $(CORESRC)\io\qiodevice.cpp $(PCH) +qtextstream.obj: $(CORESRC)\io\qtextstream.cpp $(PCH) +qtemporaryfile.obj: $(CORESRC)\io\qtemporaryfile.cpp $(PCH) +qsystemlibrary.obj: $(CORESRC)\plugin\qsystemlibrary.cpp $(PCH) +qbitarray.obj: $(CORESRC)\tools\qbitarray.cpp $(PCH) +qdatetime.obj: $(CORESRC)\tools\qdatetime.cpp $(PCH) +qmap.obj: $(CORESRC)\tools\qmap.cpp $(PCH) +qregexp.obj: $(CORESRC)\tools\qregexp.cpp $(PCH) +qstring.obj: $(CORESRC)\tools\qstring.cpp $(PCH) +qstringlist.obj: $(CORESRC)\tools\qstringlist.cpp $(PCH) +qvsnprintf.obj: $(CORESRC)\tools\qvsnprintf.cpp $(PCH) +qvariant.obj: $(CORESRC)\kernel\qvariant.cpp $(PCH) +qsystemerror.obj: $(CORESRC)\kernel\qsystemerror.cpp $(PCH) +qurl.obj: $(CORESRC)\io\qurl.cpp $(PCH) +qline.obj: $(CORESRC)\tools\qline.cpp $(PCH) +qsize.obj: $(CORESRC)\tools\qsize.cpp $(PCH) +qpoint.obj: $(CORESRC)\tools\qpoint.cpp $(PCH) +qrect.obj: $(CORESRC)\tools\qrect.cpp $(PCH) +qmetatype.obj: $(CORESRC)\kernel\qmetatype.cpp $(PCH) +qmalloc.obj: $(CORESRC)\global\qmalloc.cpp $(PCH) +qxmlstream.obj: $(CORESRC)\xml\qxmlstream.cpp $(PCH) +qxmlutils.obj: $(CORESRC)\xml\qxmlutils.cpp $(PCH) +quuid.obj: $(CORESRC)\plugin\quuid.cpp $(PCH) +qcryptographichash.obj: $(CORESRC)\tools\qcryptographichash.cpp $(PCH) + +{$(CONFSRC)}.cpp{}.obj:: + $(CXX) -c $(CXXFLAGS) $< +{$(TOOLSRC)\shared\windows}.cpp{}.obj:: + $(CXX) -c $(CXXFLAGS) $< +{$(CORESRC)\tools}.cpp{}.obj:: + $(CXX) -c $(CXXFLAGS) $< +{$(CORESRC)\codecs}.cpp{}.obj:: + $(CXX) -c $(CXXFLAGS) $< +{$(CORESRC)\global}.cpp{}.obj:: + $(CXX) -c $(CXXFLAGS) $< +{$(CORESRC)\io}.cpp{}.obj:: + $(CXX) -c $(CXXFLAGS) $< +{$(CORESRC)\kernel}.cpp{}.obj:: + $(CXX) -c $(CXXFLAGS) $< +{$(CORESRC)\plugin}.cpp{}.obj:: + $(CXX) -c $(CXXFLAGS) $< +{$(CORESRC)\xml}.cpp{}.obj:: + $(CXX) -c $(CXXFLAGS) $< diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index fc82fe0702a..3e291c2cd02 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -114,13 +114,18 @@ Configure::Configure(int& argc, char** argv) for (i = 1; i < argc; i++) configCmdLine += argv[ i ]; - - // Get the path to the executable - wchar_t module_name[MAX_PATH]; - GetModuleFileName(0, module_name, sizeof(module_name) / sizeof(wchar_t)); - QFileInfo sourcePathInfo = QString::fromWCharArray(module_name); - sourcePath = sourcePathInfo.absolutePath(); - sourceDir = sourcePathInfo.dir(); + if (configCmdLine.size() >= 2 && configCmdLine.at(0) == "-srcdir") { + sourcePath = QDir::cleanPath(configCmdLine.at(1)); + sourceDir = QDir(sourcePath); + configCmdLine.erase(configCmdLine.begin(), configCmdLine.begin() + 2); + } else { + // Get the path to the executable + wchar_t module_name[MAX_PATH]; + GetModuleFileName(0, module_name, sizeof(module_name) / sizeof(wchar_t)); + QFileInfo sourcePathInfo = QString::fromWCharArray(module_name); + sourcePath = sourcePathInfo.absolutePath(); + sourceDir = sourcePathInfo.dir(); + } buildPath = QDir::currentPath(); #if 0 const QString installPath = QString("C:\\Qt\\%1").arg(QT_VERSION_STR); @@ -889,6 +894,9 @@ void Configure::parseCmdLine() else if (configCmdLine.at(i) == "-internal") dictionary[ "QMAKE_INTERNAL" ] = "yes"; + else if (configCmdLine.at(i) == "-no-syncqt") + dictionary[ "SYNCQT" ] = "no"; + else if (configCmdLine.at(i) == "-no-qmake") dictionary[ "BUILD_QMAKE" ] = "no"; else if (configCmdLine.at(i) == "-qmake") From 66603985f2de74ac5f3bd5d259f0e65f710f62d7 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sat, 11 Feb 2012 01:33:55 +0100 Subject: [PATCH 252/406] Fix ref counted window close handling. Instead of refcounting QWindow visibility, we ask the Application subclass whether quitting is appropriate. Task-Id: QTBUG-24120 Change-Id: Idd19cc1a3e5742fddded89c7638aaaa5e47c568d Reviewed-by: Bradley T. Hughes Reviewed-by: Robin Burchell --- src/corelib/kernel/qcoreapplication.cpp | 10 +- src/corelib/kernel/qcoreapplication_p.h | 4 + src/gui/kernel/qguiapplication.cpp | 11 + src/gui/kernel/qguiapplication_p.h | 2 + src/gui/kernel/qwindow.cpp | 24 +- src/widgets/kernel/qapplication.cpp | 15 + src/widgets/kernel/qapplication_p.h | 2 + src/widgets/kernel/qwidget.cpp | 20 +- .../kernel/qapplication/tst_qapplication.cpp | 513 +----------------- 9 files changed, 79 insertions(+), 522 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index cf3ae1b7c5f..80e42336d65 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1506,8 +1506,14 @@ void QCoreApplicationPrivate::ref() void QCoreApplicationPrivate::deref() { - if (!quitLockRef.deref() && in_exec && quitLockRefEnabled) - QCoreApplication::postEvent(qApp, new QEvent(QEvent::Quit)); + if (!quitLockRef.deref()) + maybeQuit(); +} + +void QCoreApplicationPrivate::maybeQuit() +{ + if (quitLockRef.load() == 0 && in_exec && quitLockRefEnabled && shouldQuit()) + QCoreApplication::postEvent(QCoreApplication::instance(), new QEvent(QEvent::Quit)); } /*! diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index 861a046f16f..112b3131297 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -92,6 +92,10 @@ public: QAtomicInt quitLockRef; void ref(); void deref(); + virtual bool shouldQuit() { + return true; + } + void maybeQuit(); static QThread *theMainThread; static QThread *mainThread(); diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 4d80aafea54..5f50fe343ae 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1477,6 +1477,17 @@ void QGuiApplicationPrivate::emitLastWindowClosed() } } +bool QGuiApplicationPrivate::shouldQuit() +{ + /* if there is no visible top-level window left, we allow the quit */ + QWindowList list = QGuiApplication::topLevelWindows(); + for (int i = 0; i < list.size(); ++i) { + QWindow *w = list.at(i); + if (w->visible()) + return false; + } + return true; +} /*! \property QGuiApplication::layoutDirection diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 7fafe0336dc..f86d8264fab 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -74,6 +74,8 @@ public: virtual void notifyLayoutDirectionChange(); virtual void notifyActiveWindowChange(QWindow *previous); + virtual bool shouldQuit(); + static Qt::KeyboardModifiers modifier_buttons; static Qt::MouseButtons mouse_buttons; diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 61ae2a2438c..d15198c5056 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -165,14 +165,6 @@ void QWindow::setVisible(bool visible) return; d->visible = visible; emit visibleChanged(visible); - if (QCoreApplication::instance() && !transientParent()) { - QCoreApplicationPrivate *applicationPrivate = static_cast(QObjectPrivate::get(QCoreApplication::instance())); - if (visible) { - applicationPrivate->ref(); - } else { - applicationPrivate->deref(); - } - } if (!d->platformWindow) create(); @@ -514,15 +506,6 @@ void QWindow::setTransientParent(QWindow *parent) QWindow *previousParent = d->transientParent; d->transientParent = parent; - - if (QCoreApplication::instance() && d->visible) { - QCoreApplicationPrivate *applicationPrivate = static_cast(QObjectPrivate::get(QCoreApplication::instance())); - if (parent && !previousParent) { - applicationPrivate->deref(); - } else if (!parent && previousParent) { - applicationPrivate->ref(); - } - } } QWindow *QWindow::transientParent() const @@ -1116,13 +1099,16 @@ void QWindowPrivate::maybeQuitOnLastWindowClosed() bool lastWindowClosed = true; for (int i = 0; i < list.size(); ++i) { QWindow *w = list.at(i); - if (!w->visible() || w->parent()) + if (!w->visible()) continue; lastWindowClosed = false; break; } - if (lastWindowClosed) + if (lastWindowClosed) { QGuiApplicationPrivate::emitLastWindowClosed(); + QCoreApplicationPrivate *applicationPrivate = static_cast(QObjectPrivate::get(QCoreApplication::instance())); + applicationPrivate->maybeQuit(); + } } } diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 4387d2a2878..b04925d85d9 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -67,6 +67,7 @@ #include "private/qstylesheetstyle_p.h" #include "private/qstyle_p.h" #include "qmessagebox.h" +#include "qwidgetwindow_qpa_p.h" #include #include #include @@ -3289,6 +3290,20 @@ int QApplication::exec() return QGuiApplication::exec(); } +bool QApplicationPrivate::shouldQuit() +{ + /* if there is no non-withdrawn primary window left (except + the ones without QuitOnClose), we emit the lastWindowClosed + signal */ + QWidgetList list = QApplication::topLevelWidgets(); + for (int i = 0; i < list.size(); ++i) { + QWidget *w = list.at(i); + if (w->isVisible() && !w->parentWidget() && w->testAttribute(Qt::WA_QuitOnClose)) + return false; + } + return true; +} + /*! \reimp */ bool QApplication::notify(QObject *receiver, QEvent *e) diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index 790176afe37..e7288681829 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -178,6 +178,8 @@ public: virtual void notifyLayoutDirectionChange(); virtual void notifyActiveWindowChange(QWindow *); + virtual bool shouldQuit(); + #if defined(Q_WS_X11) #ifndef QT_NO_SETTINGS static bool x11_apply_settings(); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index f98f7fbe669..f095e475aff 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -7410,8 +7410,24 @@ bool QWidgetPrivate::close_helper(CloseMode mode) // Attempt to close the application only if this has WA_QuitOnClose set and a non-visible parent quitOnClose = quitOnClose && (parentWidget.isNull() || !parentWidget->isVisible()); - if (quitOnClose && q->windowHandle()) { - static_cast(QObjectPrivate::get(q->windowHandle()))->maybeQuitOnLastWindowClosed(); + if (quitOnClose) { + /* if there is no non-withdrawn primary window left (except + the ones without QuitOnClose), we emit the lastWindowClosed + signal */ + QWidgetList list = QApplication::topLevelWidgets(); + bool lastWindowClosed = true; + for (int i = 0; i < list.size(); ++i) { + QWidget *w = list.at(i); + if (!w->isVisible() || w->parentWidget() || !w->testAttribute(Qt::WA_QuitOnClose)) + continue; + lastWindowClosed = false; + break; + } + if (lastWindowClosed) { + QGuiApplicationPrivate::emitLastWindowClosed(); + QCoreApplicationPrivate *applicationPrivate = static_cast(QObjectPrivate::get(QCoreApplication::instance())); + applicationPrivate->maybeQuit(); + } } diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index c6009569127..fcb6b93e99a 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -137,16 +137,7 @@ private slots: void touchEventPropagation(); void qtbug_12673(); - - void testQuitLockRef(); - void testQuitLock1(); - void testQuitLock2(); - void testQuitLock3(); - void testQuitLock4(); - void testQuitLock5(); - void testQuitLock6(); - void testQuitLock7(); - void testQuitLock8(); + void noQuitOnHide(); void globalStaticObjectDestruction(); // run this last @@ -2060,506 +2051,30 @@ void tst_QApplication::qtbug_12673() QCOMPARE(testProcess.exitStatus(), QProcess::NormalExit); } -class JobObject : public QObject +class NoQuitOnHideWidget : public QWidget { Q_OBJECT public: - JobObject(int milliseconds, QObject *parent = 0) - : QObject(parent) + NoQuitOnHideWidget(QWidget *parent = 0) + : QWidget(parent) { - QTimer::singleShot(milliseconds, this, SLOT(timeout())); - } - - JobObject(QObject *parent = 0) - : QObject(parent) - { - QTimer::singleShot(1000, this, SLOT(timeout())); + QTimer::singleShot(0, this, SLOT(hide())); + QTimer::singleShot(500, this, SLOT(exitApp())); } private slots: - void timeout() - { - emit done(); - deleteLater(); - } - -signals: - void done(); - -private: - QEventLoopLocker locker; -}; - -class QuitLockRefTester : public QObject -{ - Q_OBJECT -public: - QuitLockRefTester(QObject *parent = 0) - : QObject(parent) - { - QTimer::singleShot(0, this, SLOT(doTest())); - } - -private slots: - void doTest() - { - QApplicationPrivate *privateClass = static_cast(QObjectPrivate::get(qApp)); - - { - QDialog *win1 = new QDialog; - - // Test with a lock active so that the refcount doesn't drop to zero during these tests, causing a quit. - // (until we exit the scope) - QEventLoopLocker locker; - - QCOMPARE(privateClass->quitLockRef.load(), 1); - - win1->show(); - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - QDialog *win2 = new QDialog; - - win2->show(); - - QCOMPARE(privateClass->quitLockRef.load(), 3); - - delete win1; - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - delete win2; - - QCOMPARE(privateClass->quitLockRef.load(), 1); - - win1 = new QDialog; - - win1->show(); - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - JobObject *job1 = new JobObject(this); - - QCOMPARE(privateClass->quitLockRef.load(), 3); - - delete win1; - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - delete job1; - - QCOMPARE(privateClass->quitLockRef.load(), 1); - - QWidget *w1 = new QWidget; - - w1->show(); - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - QWidget *w2 = new QMainWindow; - - w2->show(); - - QCOMPARE(privateClass->quitLockRef.load(), 3); - - QWidget *w3 = new QWidget(0, Qt::Dialog); - - w3->show(); - - QCOMPARE(privateClass->quitLockRef.load(), 4); - - delete w3; - - QCOMPARE(privateClass->quitLockRef.load(), 3); - - delete w2; - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - QWidget *subWidget1 = new QWidget(w1, Qt::Window); - - // Even though We create a new widget and show it, - // the ref count does not go up because it is a child of - // w1, which is the top-level, and what we are actually - // refcounting. - subWidget1->show(); - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - // When we use setParent(0) and re-show, the - // ref count does increase: - QCOMPARE(subWidget1->isVisible(), true); - subWidget1->setParent(0); - QCOMPARE(subWidget1->isVisible(), false); - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - subWidget1->show(); - QCOMPARE(subWidget1->isVisible(), true); - QCOMPARE(privateClass->quitLockRef.load(), 3); - - subWidget1->setParent(w1); - QCOMPARE(privateClass->quitLockRef.load(), 2); - - QWidget *subWidget2 = new QWidget(w1); - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - subWidget2->show(); - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - delete subWidget2; - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - QWidget *subWidget3 = new QWidget(w1); - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - subWidget3->show(); - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - subWidget3->hide(); - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - delete subWidget3; - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - QWidget *subWidget4 = new QWidget(subWidget1); - QWidget *subWidget5 = new QWidget(subWidget1); - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - QWidget *subWidget6 = new QWidget(subWidget4, Qt::Window); - - subWidget6->show(); - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - delete w1; - - QCOMPARE(privateClass->quitLockRef.load(), 1); - - w1 = new QWidget; - w2 = new QWidget; - w3 = new QWidget; - - QHBoxLayout *layout = new QHBoxLayout(w1); - - layout->addWidget(w2); - layout->addWidget(w3); - - QCOMPARE(privateClass->quitLockRef.load(), 1); - - w1->show(); - - QCOMPARE(privateClass->quitLockRef.load(), 2); - - w1->hide(); - QCOMPARE(privateClass->quitLockRef.load(), 1); - - delete w1; - - } - QCOMPARE(privateClass->quitLockRef.load(), 0); + void exitApp() { + qApp->exit(1); } }; -void tst_QApplication::testQuitLockRef() +void tst_QApplication::noQuitOnHide() { - int argc = 1; - char *argv[] = { "tst_qapplication" }; - QApplication app(argc, argv); - - QuitLockRefTester tester; - - app.exec(); -} - -void tst_QApplication::testQuitLock1() -{ - int argc = 1; - char *argv[] = { "tst_qcoreapplication" }; - QApplication app(argc, argv); - - QWidget *w = new QWidget; - - w->show(); - - QMetaObject::invokeMethod(w, "close", Qt::QueuedConnection); - - app.exec(); - - // No hang = pass. -} - -void tst_QApplication::testQuitLock2() -{ - int argc = 1; - char *argv[] = { "tst_qcoreapplication" }; - QApplication app(argc, argv); - - QWidget *w1 = new QWidget; - - w1->show(); - - QWidget *w2 = new QWidget; - - w2->show(); - - QMetaObject::invokeMethod(w1, "deleteLater", Qt::QueuedConnection); - QMetaObject::invokeMethod(w2, "hide", Qt::QueuedConnection); - - app.exec(); - - // No hang = pass. -} - -class Result : public QObject -{ - Q_OBJECT -public: - Result(QObject *parent = 0) - : QObject(parent), m_passes(false) - { - - } - - bool result() const - { - return m_passes; - } - -public slots: - - void setPasses() - { - setResult(true); - } - - void setFails() - { - setResult(false); - } - - void setResult(bool result) - { - m_passes = result; - } - -private: - bool m_passes; -}; - -void tst_QApplication::testQuitLock3() -{ - int argc = 1; - char *argv[] = { "tst_qcoreapplication" }; - QApplication app(argc, argv); - - Result *result = new Result(&app); - - JobObject *job = new JobObject(&app); - - QObject::connect(job, SIGNAL(done()), result, SLOT(setPasses())); - - app.exec(); - - QVERIFY(result->result()); -} - -void tst_QApplication::testQuitLock4() -{ - int argc = 1; - char *argv[] = { "tst_qcoreapplication" }; - QApplication app(argc, argv); - - QWidget *w = new QWidget; - - w->show(); - - Result *result = new Result(&app); - JobObject *job = new JobObject(1000, &app); - - QTimer::singleShot(500, w, SLOT(deleteLater())); - - QObject::connect(w, SIGNAL(destroyed()), result, SLOT(setFails())); - QObject::connect(job, SIGNAL(done()), result, SLOT(setPasses())); - - app.exec(); - - QVERIFY(result->result()); -} - -class JobBeforeWindowRunner : public QObject -{ - Q_OBJECT -public: - JobBeforeWindowRunner(QObject *parent = 0) - : QObject(parent), m_result(new Result(this)) - { - - } - - void start() - { - JobObject *job = new JobObject(this); - connect(job, SIGNAL(done()), m_result, SLOT(setFails())); - connect(job, SIGNAL(destroyed()), SLOT(showWindowDelayed()), Qt::QueuedConnection); - } - - bool result() const { return m_result->result(); } - -private slots: - void showWindowDelayed() - { - qApp->setQuitLockEnabled(true); - QTimer::singleShot(500, this, SLOT(showWindow())); - } - - void showWindow() - { - QWidget *w = new QWidget; - w->show(); - w->deleteLater(); - connect(w, SIGNAL(destroyed()), m_result, SLOT(setPasses())); - } - -private: - Result * const m_result; -}; - -void tst_QApplication::testQuitLock5() -{ - int argc = 1; - char *argv[] = { "tst_qcoreapplication" }; - QApplication app(argc, argv); - app.setQuitLockEnabled(false); - // Run a job before showing a window, and only enable the refcounting - // after doing so. - // Although the job brings the refcount to zero, the app does not exit - // until setQuitLockEnabled is called and the feature re-enabled. - - JobBeforeWindowRunner *eventRunner = new JobBeforeWindowRunner(&app); - - eventRunner->start(); - - app.exec(); - - QVERIFY(eventRunner->result()); -} - -class JobDuringWindowRunner : public QObject -{ - Q_OBJECT -public: - JobDuringWindowRunner(QObject *parent = 0) - : QObject(parent), m_result(new Result(this)) - { - - } - - void start() - { - JobObject *job = new JobObject(this); - - QWidget *w = new QWidget; - w->show(); - w->deleteLater(); - - QObject::connect(w, SIGNAL(destroyed()), m_result, SLOT(setFails())); - QObject::connect(job, SIGNAL(done()), m_result, SLOT(setPasses())); - } - - bool result() const { return m_result->result(); } - -private: - Result * const m_result; -}; - -void tst_QApplication::testQuitLock6() -{ - int argc = 1; - char *argv[] = { "tst_qcoreapplication" }; - QApplication app(argc, argv); - - // A job runs, and while it is running, a window is shown and closed, - // then the job ends, which causes the quit. - - JobDuringWindowRunner *eventRunner = new JobDuringWindowRunner(&app); - - eventRunner->start(); - - app.exec(); - - QVERIFY(eventRunner->result()); -} -class JobWindowJobWindowRunner : public QObject -{ - Q_OBJECT -public: - JobWindowJobWindowRunner(QObject *parent = 0) - : QObject(parent), m_result(new Result(this)) - { - - } - - void start() - { - JobObject *job = new JobObject(500, this); - - QWidget *w = new QWidget; - w->show(); - QTimer::singleShot(1000, w, SLOT(deleteLater())); - - QObject::connect(w, SIGNAL(destroyed()), m_result, SLOT(setPasses())); - QObject::connect(job, SIGNAL(done()), m_result, SLOT(setFails())); - } - - bool result() const { return m_result->result(); } -private: - Result * const m_result; -}; - -void tst_QApplication::testQuitLock7() -{ - int argc = 1; - char *argv[] = { "tst_qcoreapplication" }; - QApplication app(argc, argv); - - // A job runs, and while it is running, a window is shown - // then the job ends, then the window is closed, which causes the quit. - - JobWindowJobWindowRunner *eventRunner = new JobWindowJobWindowRunner(&app); - - eventRunner->start(); - - app.exec(); - - QVERIFY(eventRunner->result()); -} - -void tst_QApplication::testQuitLock8() -{ - int argc = 1; - char *argv[] = { "tst_qcoreapplication" }; - QApplication app(argc, argv); - - QMainWindow *mw1 = new QMainWindow; - mw1->show(); - QMainWindow *mw2 = new QMainWindow; - mw2->show(); - - QMetaObject::invokeMethod(mw1, "close", Qt::QueuedConnection); - QMetaObject::invokeMethod(mw2, "close", Qt::QueuedConnection); - - app.exec(); - - // No hang = pass + int argc = 0; + QApplication app(argc, 0); + QWidget *window1 = new NoQuitOnHideWidget(false); + window1->show(); + QCOMPARE(app.exec(), 1); } class ShowCloseShowWidget : public QWidget From de07c490336c9541857567c08214d6f9019f22a2 Mon Sep 17 00:00:00 2001 From: Xizhi Zhu Date: Tue, 14 Feb 2012 22:21:35 +0100 Subject: [PATCH 253/406] Add missing private headers to .pri. Change-Id: Ia0f37953124198dce000adad9dfae051925d526e Reviewed-by: Shane Kearns --- src/network/kernel/kernel.pri | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index ea937da5183..091d67ccc42 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -8,10 +8,12 @@ HEADERS += kernel/qauthenticator.h \ kernel/qdnslookup.h \ kernel/qdnslookup_p.h \ kernel/qhostaddress.h \ + kernel/qhostaddress_p.h \ kernel/qhostinfo.h \ kernel/qhostinfo_p.h \ kernel/qurlinfo.h \ kernel/qnetworkproxy.h \ + kernel/qnetworkproxy_p.h \ kernel/qnetworkinterface.h \ kernel/qnetworkinterface_p.h @@ -24,7 +26,10 @@ SOURCES += kernel/qauthenticator.cpp \ kernel/qnetworkinterface.cpp unix:SOURCES += kernel/qdnslookup_unix.cpp kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp -win32:SOURCES += kernel/qdnslookup_win.cpp kernel/qhostinfo_win.cpp kernel/qnetworkinterface_win.cpp +win32: { + HEADERS += qnetworkinterface_win_p.h + SOURCES += kernel/qdnslookup_win.cpp kernel/qhostinfo_win.cpp kernel/qnetworkinterface_win.cpp +} integrity:SOURCES += kernel/qdnslookup_unix.cpp kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp mac:LIBS_PRIVATE += -framework SystemConfiguration -framework CoreFoundation From acb9537551afa46330edfcc1bbad27c15099b902 Mon Sep 17 00:00:00 2001 From: Xizhi Zhu Date: Tue, 14 Feb 2012 22:32:52 +0100 Subject: [PATCH 254/406] Include headers before QT_BEGIN_NAMESPACE. Change-Id: Icaef1cb280d2968e4a35c93375749d2d9feff856 Reviewed-by: Shane Kearns --- src/network/kernel/qhostaddress.cpp | 1 + src/network/kernel/qhostaddress_p.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index b68335314fb..dd46b8126b2 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -38,6 +38,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #include "qhostaddress.h" #include "qhostaddress_p.h" #include "qdebug.h" diff --git a/src/network/kernel/qhostaddress_p.h b/src/network/kernel/qhostaddress_p.h index 26dbf861f2b..0471d4414a8 100644 --- a/src/network/kernel/qhostaddress_p.h +++ b/src/network/kernel/qhostaddress_p.h @@ -53,11 +53,11 @@ // We mean it. // -QT_BEGIN_NAMESPACE - #include "qhostaddress.h" #include "qabstractsocket.h" +QT_BEGIN_NAMESPACE + class QNetmaskAddress: public QHostAddress { int length; From 10de7f77f4ff37899db57d08fbd2a2b0702d1ab0 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Sun, 5 Feb 2012 22:38:56 +0100 Subject: [PATCH 255/406] qmetaobjectbuilder: Add asserts to confirm validity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit buildMetaObject() can operate in two "modes", based on whether a buffer to write the meta-object into is passed or not. Add asserts to make sure that the intermediate meta-data indexes are correct in both "modes", and that the final size in "write mode" matches the size that was computed in the preceding non-writing pass. The asserts make it easier to catch obvious problems when changing buildMetaObject() to generate a new meta-object revision. Change-Id: Ief7c74e6f6fca836587e831b06072d6aa98c7193 Reviewed-by: Bradley T. Hughes Reviewed-by: Jędrzej Nowacki Reviewed-by: João Abecasis Reviewed-by: Kent Hansen --- src/corelib/kernel/qmetaobjectbuilder.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp index c84c95cb6f6..a19f1fde809 100644 --- a/src/corelib/kernel/qmetaobjectbuilder.cpp +++ b/src/corelib/kernel/qmetaobjectbuilder.cpp @@ -1132,8 +1132,9 @@ static QByteArray buildParameterNames // build the QMetaObject. Returns -1 if the metaobject if // relocatable is set, but the metaobject contains extradata. static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, - bool relocatable) + int expectedSize, bool relocatable) { + Q_UNUSED(expectedSize); // Avoid warning in release mode int size = 0; int dataIndex; int enumIndex; @@ -1248,6 +1249,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, int empty = buildString(buf, str, &offset, QByteArray(), -1); // Output the class infos, + Q_ASSERT(!buf || dataIndex == pmeta->classInfoData); for (index = 0; index < d->classInfoNames.size(); ++index) { int name = buildString(buf, str, &offset, d->classInfoNames[index], empty); int value = buildString(buf, str, &offset, d->classInfoValues[index], empty); @@ -1259,6 +1261,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, } // Output the methods in the class. + Q_ASSERT(!buf || dataIndex == pmeta->methodData); for (index = 0; index < d->methods.size(); ++index) { QMetaMethodBuilderPrivate *method = &(d->methods[index]); int sig = buildString(buf, str, &offset, method->signature, empty); @@ -1290,6 +1293,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, } // Output the properties in the class. + Q_ASSERT(!buf || dataIndex == pmeta->propertyData); for (index = 0; index < d->properties.size(); ++index) { QMetaPropertyBuilderPrivate *prop = &(d->properties[index]); int name = buildString(buf, str, &offset, prop->name, empty); @@ -1331,6 +1335,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, } // Output the enumerators in the class. + Q_ASSERT(!buf || dataIndex == pmeta->enumeratorData); for (index = 0; index < d->enumerators.size(); ++index) { QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]); int name = buildString(buf, str, &offset, enumerator->name, empty); @@ -1355,6 +1360,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, } // Output the constructors in the class. + Q_ASSERT(!buf || dataIndex == pmeta->constructorData); for (index = 0; index < d->constructors.size(); ++index) { QMetaMethodBuilderPrivate *method = &(d->constructors[index]); int sig = buildString(buf, str, &offset, method->signature, empty); @@ -1411,6 +1417,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, // Align the final size and return it. ALIGN(size, void *); + Q_ASSERT(!buf || size == expectedSize); return size; } @@ -1426,10 +1433,10 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, */ QMetaObject *QMetaObjectBuilder::toMetaObject() const { - int size = buildMetaObject(d, 0, false); + int size = buildMetaObject(d, 0, 0, false); char *buf = reinterpret_cast(malloc(size)); memset(buf, 0, size); - buildMetaObject(d, buf, false); + buildMetaObject(d, buf, size, false); return reinterpret_cast(buf); } @@ -1449,7 +1456,7 @@ QMetaObject *QMetaObjectBuilder::toMetaObject() const */ QByteArray QMetaObjectBuilder::toRelocatableData(bool *ok) const { - int size = buildMetaObject(d, 0, true); + int size = buildMetaObject(d, 0, 0, true); if (size == -1) { if (ok) *ok = false; return QByteArray(); @@ -1459,7 +1466,7 @@ QByteArray QMetaObjectBuilder::toRelocatableData(bool *ok) const data.resize(size); char *buf = data.data(); memset(buf, 0, size); - buildMetaObject(d, buf, true); + buildMetaObject(d, buf, size, true); if (ok) *ok = true; return data; } From 6a6425dff5fb12bf7522dd3c0894a43336667263 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Mon, 6 Feb 2012 08:32:59 +0100 Subject: [PATCH 256/406] Don't hardcode the number 14 in meta-object generators MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 14 is the number of fields (ints) in the QMetaObjectPrivate struct as of revision 6. Use the calculated number of fields instead, so that the code will still be correct when more fields are added in future revisions. Change-Id: I4f2c2bfc125f3fabc8e8caedf5c6ba6c17a34d06 Reviewed-by: Olivier Goffart Reviewed-by: Bradley T. Hughes Reviewed-by: Jędrzej Nowacki --- src/corelib/kernel/qmetaobject_p.h | 4 ++++ src/corelib/kernel/qmetaobjectbuilder.cpp | 4 ++-- src/tools/moc/generator.cpp | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h index 5fc0555fb5f..d6e49b92d25 100644 --- a/src/corelib/kernel/qmetaobject_p.h +++ b/src/corelib/kernel/qmetaobject_p.h @@ -152,6 +152,10 @@ struct QMetaObjectPrivate #endif }; +// For meta-object generators + +enum { MetaObjectPrivateFieldCount = sizeof(QMetaObjectPrivate) / sizeof(int) }; + #ifndef UTILS_H // mirrored in moc's utils.h static inline bool is_ident_char(char s) diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp index a19f1fde809..e22257b0d81 100644 --- a/src/corelib/kernel/qmetaobjectbuilder.cpp +++ b/src/corelib/kernel/qmetaobjectbuilder.cpp @@ -1160,7 +1160,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, QMetaObjectPrivate *pmeta = reinterpret_cast(buf + size); int pmetaSize = size; - dataIndex = 14; // Number of fields in the QMetaObjectPrivate. + dataIndex = MetaObjectPrivateFieldCount; for (index = 0; index < d->properties.size(); ++index) { if (d->properties[index].notifySignal != -1) { hasNotifySignals = true; @@ -1238,7 +1238,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, } // Reset the current data position to just past the QMetaObjectPrivate. - dataIndex = 14; + dataIndex = MetaObjectPrivateFieldCount; // Add the class name to the string table. int offset = 0; diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index e2055e44e89..8242fb45ece 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -164,7 +164,7 @@ void Generator::generateCode() QByteArray qualifiedClassNameIdentifier = cdef->qualified; qualifiedClassNameIdentifier.replace(':', '_'); - int index = 14; + int index = MetaObjectPrivateFieldCount; fprintf(out, "static const uint qt_meta_data_%s[] = {\n", qualifiedClassNameIdentifier.constData()); fprintf(out, "\n // content:\n"); fprintf(out, " %4d, // revision\n", int(QMetaObjectPrivate::OutputRevision)); From e0d26ebe2e09c3d5756859972f9a71873786318a Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Mon, 6 Feb 2012 15:38:34 +0100 Subject: [PATCH 257/406] qmetaobjectbuilder: Store only unique strings in the string table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do like moc: If the string has already been entered into the table, just return its position, don't make a new copy. This can save space, for example, if there are several properties of the same type; the typename only occurs once in the string table but will be referenced by several property descriptors. Change-Id: Ic0087697716cab1c6449ea51c0c758a6fd1a1c82 Reviewed-by: Bradley T. Hughes Reviewed-by: Jędrzej Nowacki Reviewed-by: Kent Hansen --- src/corelib/kernel/qmetaobjectbuilder.cpp | 90 +++++++++++++---------- 1 file changed, 53 insertions(+), 37 deletions(-) diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp index e22257b0d81..8bece6636bb 100644 --- a/src/corelib/kernel/qmetaobjectbuilder.cpp +++ b/src/corelib/kernel/qmetaobjectbuilder.cpp @@ -1070,21 +1070,35 @@ int QMetaObjectBuilder::indexOfClassInfo(const QByteArray& name) #define ALIGN(size,type) \ (size) = ((size) + sizeof(type) - 1) & ~(sizeof(type) - 1) -// Build a string into a QMetaObject representation. Returns the -// position in the string table where the string was placed. -static int buildString - (char *buf, char *str, int *offset, const QByteArray& value, int empty) +class MetaStringTable { - if (value.size() == 0 && empty >= 0) - return empty; - if (buf) { - memcpy(str + *offset, value.constData(), value.size()); - str[*offset + value.size()] = '\0'; +public: + typedef QHash Entries; // string --> offset mapping + typedef Entries::const_iterator const_iterator; + Entries::const_iterator constBegin() const + { return m_entries.constBegin(); } + Entries::const_iterator constEnd() const + { return m_entries.constEnd(); } + + MetaStringTable() : m_offset(0) {} + + int enter(const QByteArray &value) + { + Entries::iterator it = m_entries.find(value); + if (it != m_entries.end()) + return it.value(); + int pos = m_offset; + m_entries.insert(value, pos); + m_offset += value.size() + 1; + return pos; } - int posn = *offset; - *offset += value.size() + 1; - return posn; -} + + int arraySize() const { return m_offset; } + +private: + Entries m_entries; + int m_offset; +}; // Build the parameter array string for a method. static QByteArray buildParameterNames @@ -1240,19 +1254,14 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, // Reset the current data position to just past the QMetaObjectPrivate. dataIndex = MetaObjectPrivateFieldCount; - // Add the class name to the string table. - int offset = 0; - buildString(buf, str, &offset, d->className, -1); - - // Add a common empty string, which is used to indicate "void" - // method returns, empty tag strings, etc. - int empty = buildString(buf, str, &offset, QByteArray(), -1); + MetaStringTable strings; + strings.enter(d->className); // Output the class infos, Q_ASSERT(!buf || dataIndex == pmeta->classInfoData); for (index = 0; index < d->classInfoNames.size(); ++index) { - int name = buildString(buf, str, &offset, d->classInfoNames[index], empty); - int value = buildString(buf, str, &offset, d->classInfoValues[index], empty); + int name = strings.enter(d->classInfoNames[index]); + int value = strings.enter(d->classInfoValues[index]); if (buf) { data[dataIndex] = name; data[dataIndex + 1] = value; @@ -1264,13 +1273,13 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, Q_ASSERT(!buf || dataIndex == pmeta->methodData); for (index = 0; index < d->methods.size(); ++index) { QMetaMethodBuilderPrivate *method = &(d->methods[index]); - int sig = buildString(buf, str, &offset, method->signature, empty); + int sig = strings.enter(method->signature); int params; QByteArray names = buildParameterNames (method->signature, method->parameterNames); - params = buildString(buf, str, &offset, names, empty); - int ret = buildString(buf, str, &offset, method->returnType, empty); - int tag = buildString(buf, str, &offset, method->tag, empty); + params = strings.enter(names); + int ret = strings.enter(method->returnType); + int tag = strings.enter(method->tag); int attrs = method->attributes; if (buf) { data[dataIndex] = sig; @@ -1296,8 +1305,8 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, Q_ASSERT(!buf || dataIndex == pmeta->propertyData); for (index = 0; index < d->properties.size(); ++index) { QMetaPropertyBuilderPrivate *prop = &(d->properties[index]); - int name = buildString(buf, str, &offset, prop->name, empty); - int type = buildString(buf, str, &offset, prop->type, empty); + int name = strings.enter(prop->name); + int type = strings.enter(prop->type); int flags = prop->flags; if (!isVariantType(prop->type)) { @@ -1338,7 +1347,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, Q_ASSERT(!buf || dataIndex == pmeta->enumeratorData); for (index = 0; index < d->enumerators.size(); ++index) { QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]); - int name = buildString(buf, str, &offset, enumerator->name, empty); + int name = strings.enter(enumerator->name); int isFlag = (int)(enumerator->isFlag); int count = enumerator->keys.size(); int enumOffset = enumIndex; @@ -1349,7 +1358,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, data[dataIndex + 3] = enumOffset; } for (int key = 0; key < count; ++key) { - int keyIndex = buildString(buf, str, &offset, enumerator->keys[key], empty); + int keyIndex = strings.enter(enumerator->keys[key]); if (buf) { data[enumOffset++] = keyIndex; data[enumOffset++] = enumerator->values[key]; @@ -1363,13 +1372,13 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, Q_ASSERT(!buf || dataIndex == pmeta->constructorData); for (index = 0; index < d->constructors.size(); ++index) { QMetaMethodBuilderPrivate *method = &(d->constructors[index]); - int sig = buildString(buf, str, &offset, method->signature, empty); + int sig = strings.enter(method->signature); int params; QByteArray names = buildParameterNames (method->signature, method->parameterNames); - params = buildString(buf, str, &offset, names, empty); - int ret = buildString(buf, str, &offset, method->returnType, empty); - int tag = buildString(buf, str, &offset, method->tag, empty); + params = strings.enter(names); + int ret = strings.enter(method->returnType); + int tag = strings.enter(method->tag); int attrs = method->attributes; if (buf) { data[dataIndex] = sig; @@ -1381,9 +1390,16 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, dataIndex += 5; } - // One more empty string to act as a terminator. - buildString(buf, str, &offset, QByteArray(), -1); - size += offset; + size += strings.arraySize(); + + if (buf) { + // Write strings to string data array. + MetaStringTable::const_iterator it; + for (it = strings.constBegin(); it != strings.constEnd(); ++it) { + memcpy(str + it.value(), it.key().constData(), it.key().size()); + str[it.value() + it.key().size()] = '\0'; + } + } // Output the zero terminator in the data array. if (buf) From 7a5bb18dc68326537ff0dc81932e715f1d129a83 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 15 Feb 2012 17:56:30 +1000 Subject: [PATCH 258/406] Fixed tst_QFile when redirecting stdin/stdout/stderr to/from files. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit openStandardStreamsBufferedStreams would fail if standard streams were redirected to a file (e.g. ./tst_qfile > testlog.txt). openStandardStreamsFileDescriptors already has a workaround, so apply it here too. Change-Id: Iffe9d7864909e489e77c1114e80c4e3bc70a8722 Reviewed-by: João Abecasis --- tests/auto/corelib/io/qfile/tst_qfile.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 0ed1b8ed5a3..d1a0debf4d2 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -3028,25 +3028,28 @@ void tst_QFile::openStandardStreamsBufferedStreams() { QFile in; in.open(stdin, QIODevice::ReadOnly); + if (!in.isSequential()) + QSKIP("Standard input redirected."); QCOMPARE( in.pos(), (qint64)0 ); QCOMPARE( in.size(), (qint64)0 ); - QVERIFY( in.isSequential() ); } { QFile out; out.open(stdout, QIODevice::WriteOnly); + if (!out.isSequential()) + QSKIP("Standard output redirected."); QCOMPARE( out.pos(), (qint64)0 ); QCOMPARE( out.size(), (qint64)0 ); - QVERIFY( out.isSequential() ); } { QFile err; err.open(stderr, QIODevice::WriteOnly); + if (!err.isSequential()) + QSKIP("Standard error redirected."); QCOMPARE( err.pos(), (qint64)0 ); QCOMPARE( err.size(), (qint64)0 ); - QVERIFY( err.isSequential() ); } } From af115e5bc02eea489d7c15f62e07bc0d46781c3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Sat, 4 Feb 2012 01:10:55 +0100 Subject: [PATCH 259/406] Drop QFile::fileEngine The function was already marked as internal. By moving access to the underlying file engine to private API this supports the effort to completely drop file engines from public API. In the future, the goal is to completely drop the file-engine abstraction as it exists today. Change-Id: I332fa56e70c87e83c1e08bb9f75e04df7c93fec7 Reviewed-by: Jonas Gastal Reviewed-by: Anselmo L. S. Melo Reviewed-by: Lars Knoll Reviewed-by: Robin Burchell --- src/corelib/io/qfile.cpp | 51 +++++++++++++++---------------- src/corelib/io/qfile.h | 6 ++-- src/corelib/io/qfile_p.h | 5 +++ src/corelib/io/qtemporaryfile.cpp | 35 ++++++++++----------- src/corelib/io/qtemporaryfile.h | 2 -- 5 files changed, 48 insertions(+), 51 deletions(-) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index d7308c710df..58935fad3ba 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -130,6 +130,13 @@ QFilePrivate::openExternalFile(int flags, FILE *fh, QFile::FileHandleFlags handl #endif } +QAbstractFileEngine *QFilePrivate::engine() const +{ + if (!fileEngine) + fileEngine = QAbstractFileEngine::create(fileName); + return fileEngine; +} + inline bool QFilePrivate::ensureFlushed() const { // This function ensures that the write buffer has been flushed (const @@ -424,7 +431,8 @@ QFile::~QFile() */ QString QFile::fileName() const { - return fileEngine()->fileName(QAbstractFileEngine::DefaultName); + Q_D(const QFile); + return d->engine()->fileName(QAbstractFileEngine::DefaultName); } /*! @@ -569,8 +577,9 @@ QFile::setDecodingFunction(DecoderFn f) bool QFile::exists() const { + Q_D(const QFile); // 0x1000000 = QAbstractFileEngine::Refresh, forcing an update - return (fileEngine()->fileFlags(QAbstractFileEngine::FlagsMask + return (d->engine()->fileFlags(QAbstractFileEngine::FlagsMask | QAbstractFileEngine::FileFlag(0x1000000)) & QAbstractFileEngine::ExistsFlag); } @@ -608,7 +617,8 @@ QFile::exists(const QString &fileName) QString QFile::readLink() const { - return fileEngine()->fileName(QAbstractFileEngine::LinkName); + Q_D(const QFile); + return d->engine()->fileName(QAbstractFileEngine::LinkName); } /*! @@ -654,7 +664,7 @@ QFile::remove() unsetError(); close(); if(error() == QFile::NoError) { - if(fileEngine()->remove()) { + if (d->engine()->remove()) { unsetError(); return true; } @@ -709,7 +719,7 @@ QFile::rename(const QString &newName) unsetError(); close(); if(error() == QFile::NoError) { - if (fileEngine()->rename(newName)) { + if (d->engine()->rename(newName)) { unsetError(); // engine was able to handle the new name so we just reset it d->fileEngine->setFileName(newName); @@ -806,7 +816,7 @@ QFile::link(const QString &linkName) return false; } QFileInfo fi(linkName); - if(fileEngine()->link(fi.absoluteFilePath())) { + if (d->engine()->link(fi.absoluteFilePath())) { unsetError(); return true; } @@ -861,7 +871,7 @@ QFile::copy(const QString &newName) unsetError(); close(); if(error() == QFile::NoError) { - if(fileEngine()->copy(newName)) { + if (d->engine()->copy(newName)) { unsetError(); return true; } else { @@ -996,7 +1006,7 @@ bool QFile::open(OpenMode mode) } // QIODevice provides the buffering, so there's no need to request it from the file engine. - if (fileEngine()->open(mode | QIODevice::Unbuffered)) { + if (d->engine()->open(mode | QIODevice::Unbuffered)) { QIODevice::open(mode); if (mode & Append) seek(size()); @@ -1271,7 +1281,7 @@ QFile::handle() const uchar *QFile::map(qint64 offset, qint64 size, MemoryMapFlags flags) { Q_D(QFile); - if (fileEngine() + if (d->engine() && d->fileEngine->supportsExtension(QAbstractFileEngine::MapExtension)) { unsetError(); uchar *address = d->fileEngine->map(offset, size, flags); @@ -1293,7 +1303,7 @@ uchar *QFile::map(qint64 offset, qint64 size, MemoryMapFlags flags) bool QFile::unmap(uchar *address) { Q_D(QFile); - if (fileEngine() + if (d->engine() && d->fileEngine->supportsExtension(QAbstractFileEngine::UnMapExtension)) { unsetError(); bool success = d->fileEngine->unmap(address); @@ -1320,7 +1330,7 @@ QFile::resize(qint64 sz) Q_D(QFile); if (!d->ensureFlushed()) return false; - fileEngine(); + d->engine(); if (isOpen() && d->fileEngine->pos() > sz) seek(sz); if(d->fileEngine->setSize(sz)) { @@ -1360,7 +1370,8 @@ QFile::resize(const QString &fileName, qint64 sz) QFile::Permissions QFile::permissions() const { - QAbstractFileEngine::FileFlags perms = fileEngine()->fileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask; + Q_D(const QFile); + QAbstractFileEngine::FileFlags perms = d->engine()->fileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask; return QFile::Permissions((int)perms); //ewww } @@ -1389,7 +1400,7 @@ bool QFile::setPermissions(Permissions permissions) { Q_D(QFile); - if(fileEngine()->setPermissions(permissions)) { + if (d->engine()->setPermissions(permissions)) { unsetError(); return true; } @@ -1490,7 +1501,7 @@ qint64 QFile::size() const Q_D(const QFile); if (!d->ensureFlushed()) return 0; - d->cachedSize = fileEngine()->size(); + d->cachedSize = d->engine()->size(); return d->cachedSize; } @@ -1730,18 +1741,6 @@ QFile::writeData(const char *data, qint64 len) return len; } -/*! - \internal - Returns the QIOEngine for this QFile object. -*/ -QAbstractFileEngine *QFile::fileEngine() const -{ - Q_D(const QFile); - if(!d->fileEngine) - d->fileEngine = QAbstractFileEngine::create(d->fileName); - return d->fileEngine; -} - /*! Returns the file error status. diff --git a/src/corelib/io/qfile.h b/src/corelib/io/qfile.h index bc278cf6000..bf7290dda21 100644 --- a/src/corelib/io/qfile.h +++ b/src/corelib/io/qfile.h @@ -54,8 +54,7 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE - -class QAbstractFileEngine; +class QTemporaryFile; class QFilePrivate; class Q_CORE_EXPORT QFile : public QIODevice @@ -174,8 +173,6 @@ public: uchar *map(qint64 offset, qint64 size, MemoryMapFlags flags = NoOptions); bool unmap(uchar *address); - virtual QAbstractFileEngine *fileEngine() const; - protected: #ifdef QT_NO_QOBJECT QFile(QFilePrivate &dd); @@ -188,6 +185,7 @@ protected: qint64 readLineData(char *data, qint64 maxlen); private: + friend class QTemporaryFile; Q_DISABLE_COPY(QFile) }; diff --git a/src/corelib/io/qfile_p.h b/src/corelib/io/qfile_p.h index b932627ec06..4a637d44a89 100644 --- a/src/corelib/io/qfile_p.h +++ b/src/corelib/io/qfile_p.h @@ -59,9 +59,12 @@ QT_BEGIN_NAMESPACE +class QTemporaryFile; + class QFilePrivate : public QIODevicePrivate { Q_DECLARE_PUBLIC(QFile) + friend class QTemporaryFile; protected: QFilePrivate(); @@ -70,6 +73,8 @@ protected: bool openExternalFile(int flags, int fd, QFile::FileHandleFlags handleFlags); bool openExternalFile(int flags, FILE *fh, QFile::FileHandleFlags handleFlags); + virtual QAbstractFileEngine *engine() const; + QString fileName; mutable QAbstractFileEngine *fileEngine; diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index b80ba6eee15..75681dadffd 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -407,6 +407,8 @@ protected: QTemporaryFilePrivate(); ~QTemporaryFilePrivate(); + QAbstractFileEngine *engine() const; + bool autoRemove; QString templateName; }; @@ -419,6 +421,17 @@ QTemporaryFilePrivate::~QTemporaryFilePrivate() { } +QAbstractFileEngine *QTemporaryFilePrivate::engine() const +{ + if (!fileEngine) { + if (fileName.isEmpty()) + fileEngine = new QTemporaryFileEngine(templateName); + else + fileEngine = new QTemporaryFileEngine(fileName, false); + } + return fileEngine; +} + static QString defaultTemplateName() { QString baseName; @@ -640,7 +653,7 @@ QString QTemporaryFile::fileName() const Q_D(const QTemporaryFile); if(d->fileName.isEmpty()) return QString(); - return fileEngine()->fileName(QAbstractFileEngine::DefaultName); + return d->engine()->fileName(QAbstractFileEngine::DefaultName); } /*! @@ -692,7 +705,7 @@ void QTemporaryFile::setFileTemplate(const QString &name) */ QTemporaryFile *QTemporaryFile::createLocalFile(QFile &file) { - if (QAbstractFileEngine *engine = file.fileEngine()) { + if (QAbstractFileEngine *engine = file.d_func()->engine()) { if(engine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag) return 0; //local already //cache @@ -725,22 +738,6 @@ QTemporaryFile *QTemporaryFile::createLocalFile(QFile &file) return 0; } -/*! - \internal -*/ - -QAbstractFileEngine *QTemporaryFile::fileEngine() const -{ - Q_D(const QTemporaryFile); - if(!d->fileEngine) { - if (d->fileName.isEmpty()) - d->fileEngine = new QTemporaryFileEngine(d->templateName); - else - d->fileEngine = new QTemporaryFileEngine(d->fileName, false); - } - return d->fileEngine; -} - /*! \reimp @@ -752,7 +749,7 @@ bool QTemporaryFile::open(OpenMode flags) { Q_D(QTemporaryFile); if (!d->fileName.isEmpty()) { - if (static_cast(fileEngine())->isReallyOpen()) { + if (static_cast(d->engine())->isReallyOpen()) { setOpenMode(flags); return true; } diff --git a/src/corelib/io/qtemporaryfile.h b/src/corelib/io/qtemporaryfile.h index 8b14e5a14a2..e7665692933 100644 --- a/src/corelib/io/qtemporaryfile.h +++ b/src/corelib/io/qtemporaryfile.h @@ -88,8 +88,6 @@ public: { QFile file(fileName); return createLocalFile(file); } static QTemporaryFile *createLocalFile(QFile &file); - virtual QAbstractFileEngine *fileEngine() const; - protected: bool open(OpenMode flags); From 6a5d1370b3209c7c5ed6fc498190deff69e74552 Mon Sep 17 00:00:00 2001 From: Michalina Ziemba Date: Tue, 14 Feb 2012 13:27:58 +0100 Subject: [PATCH 260/406] Qt Network: Added the \inmodule command in the class documentation. -Some of the public classes were missing the \inmodule command. -Fixed a sentence. Change-Id: I88ebe12680c744e32253dc01c5ddb4292267caf9 Reviewed-by: Lars Knoll --- src/network/access/qnetworkcookie.cpp | 2 ++ src/network/access/qnetworkcookiejar.cpp | 4 +++- src/network/access/qnetworkrequest.cpp | 8 ++++---- src/network/kernel/qnetworkinterface.cpp | 2 ++ src/network/kernel/qnetworkproxy.cpp | 2 +- src/network/kernel/qurlinfo.cpp | 1 + src/network/socket/qlocalserver.cpp | 1 + src/network/socket/qlocalsocket.cpp | 1 + 8 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index c987c50017a..88b021d7806 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -58,6 +58,8 @@ QT_BEGIN_NAMESPACE /*! \class QNetworkCookie \since 4.4 + \inmodule QtNetwork + \brief The QNetworkCookie class holds one network cookie. Cookies are small bits of information that stateless protocols diff --git a/src/network/access/qnetworkcookiejar.cpp b/src/network/access/qnetworkcookiejar.cpp index 4136043e2eb..a7436cb38c0 100644 --- a/src/network/access/qnetworkcookiejar.cpp +++ b/src/network/access/qnetworkcookiejar.cpp @@ -51,8 +51,10 @@ QT_BEGIN_NAMESPACE /*! \class QNetworkCookieJar - \brief The QNetworkCookieJar class implements a simple jar of QNetworkCookie objects \since 4.4 + \inmodule QtNetwork + + \brief The QNetworkCookieJar class implements a simple jar of QNetworkCookie objects Cookies are small bits of information that stateless protocols like HTTP use to maintain some persistent information across diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index b9c149e5d89..ef81b6081d1 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -57,12 +57,12 @@ QT_BEGIN_NAMESPACE /*! \class QNetworkRequest - \brief The QNetworkRequest class holds a request to be sent with QNetworkAccessManager. \since 4.4 - \ingroup network \inmodule QtNetwork + \brief The QNetworkRequest class holds a request to be sent with QNetworkAccessManager. + QNetworkRequest is part of the Network Access API and is the class holding the information necessary to send a request over the network. It contains a URL and some ancillary information that can @@ -115,7 +115,7 @@ QT_BEGIN_NAMESPACE /*! \enum QNetworkRequest::Attribute \since 4.7 - + Attribute codes for the QNetworkRequest and QNetworkReply. Attributes are extra meta-data that are used to control the @@ -606,7 +606,7 @@ QNetworkRequest::Priority QNetworkRequest::priority() const /*! \enum QNetworkRequest::Priority \since 4.7 - + This enum lists the possible network request priorities. \value HighPriority High priority diff --git a/src/network/kernel/qnetworkinterface.cpp b/src/network/kernel/qnetworkinterface.cpp index 7b68ed6c125..947b2ab0d93 100644 --- a/src/network/kernel/qnetworkinterface.cpp +++ b/src/network/kernel/qnetworkinterface.cpp @@ -149,6 +149,7 @@ QString QNetworkInterfacePrivate::makeHwAddress(int len, uchar *data) \since 4.2 \reentrant \ingroup network + \inmodule QtNetwork Each network interface can contain zero or more IP addresses, which in turn can be associated with a netmask and/or a broadcast @@ -333,6 +334,7 @@ void QNetworkAddressEntry::setBroadcast(const QHostAddress &newBroadcast) \since 4.2 \reentrant \ingroup network + \inmodule QtNetwork QNetworkInterface represents one network interface attached to the host where the program is being run. Each network interface may diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp index 295260f7f18..1181497d820 100644 --- a/src/network/kernel/qnetworkproxy.cpp +++ b/src/network/kernel/qnetworkproxy.cpp @@ -853,7 +853,7 @@ template<> void QSharedDataPointer::detach() \since 4.5 \inmodule QtNetwork \brief The QNetworkProxyQuery class is used to query the proxy - settings for a socket + settings for a socket. QNetworkProxyQuery holds the details of a socket being created or request being made. It is used by QNetworkProxy and diff --git a/src/network/kernel/qurlinfo.cpp b/src/network/kernel/qurlinfo.cpp index a446f03b85a..9f571b9e8c1 100644 --- a/src/network/kernel/qurlinfo.cpp +++ b/src/network/kernel/qurlinfo.cpp @@ -86,6 +86,7 @@ public: \ingroup io \ingroup network + \inmodule QtNetwork The information about a URL that can be retrieved includes name(), permissions(), owner(), group(), size(), lastModified(), diff --git a/src/network/socket/qlocalserver.cpp b/src/network/socket/qlocalserver.cpp index 05f26883d37..e9848213d87 100644 --- a/src/network/socket/qlocalserver.cpp +++ b/src/network/socket/qlocalserver.cpp @@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE /*! \class QLocalServer \since 4.4 + \inmodule QtNetwork \brief The QLocalServer class provides a local socket based server. diff --git a/src/network/socket/qlocalsocket.cpp b/src/network/socket/qlocalsocket.cpp index 3097eaa96c9..ced7bba09be 100644 --- a/src/network/socket/qlocalsocket.cpp +++ b/src/network/socket/qlocalsocket.cpp @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE /*! \class QLocalSocket \since 4.4 + \inmodule QtNetwork \brief The QLocalSocket class provides a local socket. From b9eb3715f55378802a1a0ae2f61d799ab84ee49a Mon Sep 17 00:00:00 2001 From: Donald Carr Date: Tue, 14 Feb 2012 21:55:48 +0000 Subject: [PATCH 261/406] Redirect libjpeg messages via qWarning This allows us to catch spurious libjpeg warnings via the installation of a message handler Change-Id: I82f3257118b5fbdf66550be80e72f75e9a24d3c1 Reviewed-by: Girish Ramakrishnan Reviewed-by: Johannes Zellner Reviewed-by: Lars Knoll --- src/gui/image/qjpeghandler.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index 0260d18217d..013a1a83b0b 100644 --- a/src/gui/image/qjpeghandler.cpp +++ b/src/gui/image/qjpeghandler.cpp @@ -106,6 +106,13 @@ static void my_error_exit (j_common_ptr cinfo) longjmp(myerr->setjmp_buffer, 1); } +static void my_output_message(j_common_ptr cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + (*cinfo->err->format_message)(cinfo, buffer); + qWarning("%s", buffer); +} + #if defined(Q_C_CALLBACKS) } #endif @@ -530,6 +537,7 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, int sourceQ cinfo.err = jpeg_std_error(&jerr); jerr.error_exit = my_error_exit; + jerr.output_message = my_output_message; if (!setjmp(jerr.setjmp_buffer)) { // WARNING: @@ -744,6 +752,7 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device) info.src = iod_src; info.err = jpeg_std_error(&err); err.error_exit = my_error_exit; + err.output_message = my_output_message; if (!setjmp(err.setjmp_buffer)) { #if defined(Q_OS_UNIXWARE) From 214e031d56714ba69ef929f1e763e243b393e460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Tue, 20 Dec 2011 17:11:46 +0100 Subject: [PATCH 262/406] Implement new static less API for QMetaType. Currently QMetaType API contains almost only static methods. This works nice until someone needs more information or needs to do more operations on a type. In this case every function call has to do type dispatch. This API allows to avoid redundant type dispatching, by caching a type information in a QMetaType instance. It gives significant performance boost especially for custom types (up to 9x). Change-Id: I223d066268402e072e41ca1d0a3e7bc160655d7f Reviewed-by: Stephen Kelly Reviewed-by: Bradley T. Hughes --- src/corelib/kernel/qmetatype.cpp | 170 ++++++++++++++++++ src/corelib/kernel/qmetatype.h | 145 ++++++++++++++- src/corelib/kernel/qmetatype_p.h | 43 ++++- .../kernel/qmetatype/tst_qmetatype.cpp | 156 +++++++++++++--- .../kernel/qmetatype/tst_qmetatype.cpp | 54 +++++- 5 files changed, 534 insertions(+), 34 deletions(-) diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index d965c482557..a1baf28f107 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1753,4 +1753,174 @@ QMetaType::TypeFlags QMetaType::typeFlags(int type) \sa Q_DECLARE_METATYPE(), QMetaType::type() */ +namespace { +class TypeInfo { + template::IsAccepted> + struct TypeInfoImpl + { + TypeInfoImpl(const uint /* type */, QMetaTypeInterface &info) + { + QMetaTypeInterface tmp = QT_METATYPE_INTERFACE_INIT_NO_DATASTREAM(T); + info = tmp; + } + }; + + template + struct TypeInfoImpl + { + TypeInfoImpl(const uint type, QMetaTypeInterface &info) + { + if (QTypeModuleInfo::IsGui) { + if (Q_LIKELY(qMetaTypeGuiHelper)) + info = qMetaTypeGuiHelper[type - QMetaType::FirstGuiType]; + return; + } + if (QTypeModuleInfo::IsWidget) { + if (Q_LIKELY(qMetaTypeWidgetsHelper)) + info = qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType]; + return; + } + } + }; +public: + QMetaTypeInterface info; + TypeInfo(const uint type) + : m_type(type) + { + QMetaTypeInterface tmp = QT_METATYPE_INTERFACE_INIT_EMPTY(); + info = tmp; + } + template + void delegate(const T*) { TypeInfoImpl(m_type, info); } + void delegate(const void*) {} + void delegate(const QMetaTypeSwitcher::UnknownType*) { customTypeInfo(m_type); } +private: + void customTypeInfo(const uint type) + { + const QVector * const ct = customTypes(); + if (Q_UNLIKELY(!ct)) + return; + QReadLocker locker(customTypesLock()); + if (Q_LIKELY(uint(ct->count()) > type - QMetaType::User)) + info = ct->at(type - QMetaType::User); + } + + const uint m_type; +}; +} // namespace + +QMetaType QMetaType::typeInfo(const int type) +{ + TypeInfo typeInfo(type); + QMetaTypeSwitcher::switcher(typeInfo, type, 0); + return typeInfo.info.creator || !type ? QMetaType(QMetaType::NoExtensionFlags + , static_cast(0) // typeInfo::info is a temporary variable, we can't return address of it. + , typeInfo.info.creator + , typeInfo.info.deleter + , typeInfo.info.saveOp + , typeInfo.info.loadOp + , typeInfo.info.constructor + , typeInfo.info.destructor + , typeInfo.info.size + , typeInfo.info.flags + , type) + : QMetaType(-1); +} + +QMetaType::QMetaType(const int typeId) + : m_typeId(typeId) +{ + if (Q_UNLIKELY(typeId == -1)) { + // Constructs invalid QMetaType instance. + m_extensionFlags = 0xffffffff; + Q_ASSERT(!isValid()); + } else { + // TODO it can be better. + *this = QMetaType::typeInfo(typeId); + if (m_typeId > 0 && !m_creator) { + m_extensionFlags = 0xffffffff; + m_typeId = -1; + } + if (m_typeId == QMetaType::Void) { + m_extensionFlags = CreateEx | DestroyEx | ConstructEx | DestructEx; + } + } +} + +QMetaType::QMetaType(const QMetaType &other) + : m_creator(other.m_creator) + , m_deleter(other.m_deleter) + , m_saveOp(other.m_saveOp) + , m_loadOp(other.m_loadOp) + , m_constructor(other.m_constructor) + , m_destructor(other.m_destructor) + , m_extension(other.m_extension) // space reserved for future use + , m_size(other.m_size) + , m_typeFlags(other.m_typeFlags) + , m_extensionFlags(other.m_extensionFlags) + , m_typeId(other.m_typeId) +{} + +QMetaType &QMetaType::operator =(const QMetaType &other) +{ + m_creator = other.m_creator; + m_deleter = other.m_deleter; + m_saveOp = other.m_saveOp; + m_loadOp = other.m_loadOp; + m_constructor = other.m_constructor; + m_destructor = other.m_destructor; + m_size = other.m_size; + m_typeFlags = other.m_typeFlags; + m_extensionFlags = other.m_extensionFlags; + m_extension = other.m_extension; // space reserved for future use + m_typeId = other.m_typeId; + return *this; +} + +void QMetaType::ctor(const QMetaTypeInterface *info) +{ + // Special case for Void type, the type is valid but not constructible. + // In future we may consider to remove this assert and extend this function to initialize + // differently m_extensionFlags for different types. Currently it is not needed. + Q_ASSERT(m_typeId == QMetaType::Void); + Q_UNUSED(info); + m_extensionFlags = CreateEx | DestroyEx | ConstructEx | DestructEx; +} + +void QMetaType::dtor() +{} + +void *QMetaType::createExtended(const void *copy) const +{ + Q_UNUSED(copy); + return 0; +} + +void QMetaType::destroyExtended(void *data) const +{ + Q_UNUSED(data); +} + +void *QMetaType::constructExtended(void *where, const void *copy) const +{ + Q_UNUSED(where); + Q_UNUSED(copy); + return 0; +} + +void QMetaType::destructExtended(void *data) const +{ + Q_UNUSED(data); +} + +uint QMetaType::sizeExtended() const +{ + return 0; +} + +QMetaType::TypeFlags QMetaType::flagsExtended() const +{ + return 0; +} + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index ff3f9341e4e..0b6a62e5c84 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -177,8 +177,16 @@ QT_BEGIN_NAMESPACE TypeName = Id, class QDataStream; +class QMetaTypeInterface; class Q_CORE_EXPORT QMetaType { + enum ExtensionFlag { NoExtensionFlags, + CreateEx = 0x1, DestroyEx = 0x2, + ConstructEx = 0x4, DestructEx = 0x8, + NameEx = 0x10, SizeEx = 0x20, + CtorEx = 0x40, DtorEx = 0x80, + FlagsEx = 0x100 + }; public: enum Type { // these are merged with QVariant @@ -218,9 +226,9 @@ public: typedef void (*Destructor)(void *); typedef void *(*Constructor)(void *, const void *); -#ifndef QT_NO_DATASTREAM typedef void (*SaveOperator)(QDataStream &, const void *); typedef void (*LoadOperator)(QDataStream &, void *); +#ifndef QT_NO_DATASTREAM static void registerStreamOperators(const char *typeName, SaveOperator saveOp, LoadOperator loadOp); static void registerStreamOperators(int type, SaveOperator saveOp, @@ -253,6 +261,56 @@ public: static bool save(QDataStream &stream, int type, const void *data); static bool load(QDataStream &stream, int type, void *data); #endif + + QMetaType(const int type); + inline ~QMetaType(); + + inline bool isValid() const; + inline bool isRegistered() const; + inline int sizeOf() const; + inline TypeFlags flags() const; + + inline void *create(const void *copy = 0) const; + inline void destroy(void *data) const; + inline void *construct(void *where, const void *copy = 0) const; + inline void destruct(void *data) const; +private: + static QMetaType typeInfo(const int type); + inline QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info, + Creator creator, + Deleter deleter, + SaveOperator saveOp, + LoadOperator loadOp, + Constructor constructor, + Destructor destructor, + uint sizeOf, + uint typeFlags, + int typeId); + QMetaType(const QMetaType &other); + QMetaType &operator =(const QMetaType &); + inline bool isExtended(const ExtensionFlag flag) const { return m_extensionFlags & flag; } + + // Methods used for future binary compatibile extensions + void ctor(const QMetaTypeInterface *info); + void dtor(); + uint sizeExtended() const; + QMetaType::TypeFlags flagsExtended() const; + void *createExtended(const void *copy = 0) const; + void destroyExtended(void *data) const; + void *constructExtended(void *where, const void *copy = 0) const; + void destructExtended(void *data) const; + + Creator m_creator; + Deleter m_deleter; + SaveOperator m_saveOp; + LoadOperator m_loadOp; + Constructor m_constructor; + Destructor m_destructor; + void *m_extension; // space reserved for future use + uint m_size; + uint m_typeFlags; + uint m_extensionFlags; + int m_typeId; }; #undef QT_DEFINE_METATYPE_ID @@ -555,6 +613,91 @@ Q_DECLARE_METATYPE_TEMPLATE_1ARG(QSet) Q_DECLARE_METATYPE_TEMPLATE_1ARG(QSharedPointer) Q_DECLARE_METATYPE_TEMPLATE_1ARG(QLinkedList) +inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info, + Creator creator, + Deleter deleter, + SaveOperator saveOp, + LoadOperator loadOp, + Constructor constructor, + Destructor destructor, + uint size, + uint typeFlags, + int typeId) + : m_creator(creator) + , m_deleter(deleter) + , m_saveOp(saveOp) + , m_loadOp(loadOp) + , m_constructor(constructor) + , m_destructor(destructor) + , m_size(size) + , m_typeFlags(typeFlags) + , m_extensionFlags(extensionFlags) + , m_typeId(typeId) +{ + if (Q_UNLIKELY(isExtended(CtorEx) || typeId == QMetaType::Void)) + ctor(info); +} + +inline QMetaType::~QMetaType() +{ + if (Q_UNLIKELY(isExtended(DtorEx))) + dtor(); +} + +inline bool QMetaType::isValid() const +{ + return m_typeId >= 0; +} + +inline bool QMetaType::isRegistered() const +{ + return isValid(); +} + +inline void *QMetaType::create(const void *copy) const +{ + if (Q_UNLIKELY(isExtended(CreateEx))) + return createExtended(copy); + return m_creator(copy); +} + +inline void QMetaType::destroy(void *data) const +{ + if (Q_UNLIKELY(isExtended(DestroyEx))) + return destroyExtended(data); + m_deleter(data); +} + +inline void *QMetaType::construct(void *where, const void *copy) const +{ + if (Q_UNLIKELY(isExtended(ConstructEx))) + return constructExtended(where, copy); + return m_constructor(where, copy); +} + +inline void QMetaType::destruct(void *data) const +{ + if (Q_UNLIKELY(isExtended(DestructEx))) + return destructExtended(data); + if (Q_UNLIKELY(!data)) + return; + m_destructor(data); +} + +inline int QMetaType::sizeOf() const +{ + if (Q_UNLIKELY(isExtended(SizeEx))) + return sizeExtended(); + return m_size; +} + +inline QMetaType::TypeFlags QMetaType::flags() const +{ + if (Q_UNLIKELY(isExtended(FlagsEx))) + return flagsExtended(); + return QMetaType::TypeFlags(m_typeFlags); +} + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index b1edc350a10..e48c5d3033d 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -132,10 +132,8 @@ public: } static void deleter(T *t) { delete t; } - #ifndef QT_NO_DATASTREAM static void saver(QDataStream &stream, const T *t) { stream << *t; } static void loader(QDataStream &stream, T *t) { stream >> *t; } - #endif // QT_NO_DATASTREAM static void destructor(T *t) { Q_UNUSED(t) // Silence MSVC that warns for POD types. @@ -151,10 +149,8 @@ public: QMetaType::Creator creator; QMetaType::Deleter deleter; -#ifndef QT_NO_DATASTREAM QMetaType::SaveOperator saveOp; QMetaType::LoadOperator loadOp; -#endif QMetaType::Constructor constructor; QMetaType::Destructor destructor; int size; @@ -165,10 +161,8 @@ template<> struct QMetaTypeInterface::Impl { static void *creator(const void *) { return 0; } static void deleter(void *) {} -#ifndef QT_NO_DATASTREAM static void saver(QDataStream &, const void *) {} static void loader(QDataStream &, void *) {} -#endif // QT_NO_DATASTREAM static void destructor(void *){} static void *constructor(void *, const void *) { return 0; } }; @@ -177,15 +171,22 @@ struct QMetaTypeInterface::Impl { # define QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL(Type) \ /*saveOp*/(reinterpret_cast(QMetaTypeInterface::Impl::saver)), \ /*loadOp*/(reinterpret_cast(QMetaTypeInterface::Impl::loader)), +# define QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(Type) \ + /*saveOp*/ 0, \ + /*loadOp*/ 0, #else -# define QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL(Type) +# define QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(Type) \ + /*saveOp*/ 0, \ + /*loadOp*/ 0, +# define QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL(Type) \ + QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(Type) #endif -#define QT_METATYPE_INTERFACE_INIT(Type) \ +#define QT_METATYPE_INTERFACE_INIT_IMPL(Type, DATASTREAM_DELEGATE) \ { \ /*creator*/(reinterpret_cast(QMetaTypeInterface::Impl::creator)), \ /*deleter*/(reinterpret_cast(QMetaTypeInterface::Impl::deleter)), \ - QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL(Type) \ + DATASTREAM_DELEGATE(Type) \ /*constructor*/(reinterpret_cast(QMetaTypeInterface::Impl::constructor)), \ /*destructor*/(reinterpret_cast(QMetaTypeInterface::Impl::destructor)), \ /*size*/(QTypeInfo::sizeOf), \ @@ -194,6 +195,30 @@ struct QMetaTypeInterface::Impl { | (QTypeInfo::isComplex * QMetaType::NeedsDestruction) \ } + +/* These QT_METATYPE_INTERFACE_INIT* macros are used to initialize QMetaTypeInterface instance. + + - QT_METATYPE_INTERFACE_INIT(Type) -> It takes Type argument and creates all necessary wrapper functions for the Type, + it detects if QT_NO_DATASTREAM was defined. Probably it is the macro that you want to use. + + - QT_METATYPE_INTERFACE_INIT_EMPTY() -> It initializes an empty QMetaTypeInterface instance. + + - QT_METATYPE_INTERFACE_INIT_NO_DATASTREAM(Type) -> Temporary workaround for missing auto-detection of data stream + operators. It creates same instance as QT_METATYPE_INTERFACE_INIT(Type) but with null stream operators callbacks. + */ +#define QT_METATYPE_INTERFACE_INIT(Type) QT_METATYPE_INTERFACE_INIT_IMPL(Type, QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL) +#define QT_METATYPE_INTERFACE_INIT_NO_DATASTREAM(Type) QT_METATYPE_INTERFACE_INIT_IMPL(Type, QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL) +#define QT_METATYPE_INTERFACE_INIT_EMPTY() \ +{ \ + /*creator*/ 0, \ + /*deleter*/ 0, \ + QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL() \ + /*constructor*/ 0, \ + /*destructor*/ 0, \ + /*size*/ 0, \ + /*flags*/ 0 \ +} + QT_END_NAMESPACE #endif // QMETATYPE_P_H diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index f90e7f463f4..72913d10f27 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -78,8 +78,12 @@ private slots: void createCopy(); void sizeOf_data(); void sizeOf(); + void sizeOfStaticLess_data(); + void sizeOfStaticLess(); void flags_data(); void flags(); + void flagsStaticLess_data(); + void flagsStaticLess(); void construct_data(); void construct(); void constructCopy_data(); @@ -88,6 +92,8 @@ private slots: void registerType(); void isRegistered_data(); void isRegistered(); + void isRegisteredStaticLess_data(); + void isRegisteredStaticLess(); void registerStreamBuiltin(); void automaticTemplateRegistration(); }; @@ -125,6 +131,9 @@ class MetaTypeTorturer: public QThread protected: void run() { + Bar space[1]; + space[0].~Bar(); + for (int i = 0; i < 1000; ++i) { const QByteArray name = QString("Bar%1_%2").arg(i).arg((size_t)QThread::currentThreadId()).toLatin1(); const char *nm = name.constData(); @@ -132,6 +141,15 @@ protected: #ifdef Q_OS_LINUX pthread_yield(); #endif + QMetaType info(tp); + if (!info.isValid()) { + ++failureCount; + qWarning() << "Wrong typeInfo returned for" << tp; + } + if (!info.isRegistered()) { + ++failureCount; + qWarning() << name << "is not a registered metatype"; + } if (QMetaType::typeFlags(tp) != (QMetaType::NeedsConstruction | QMetaType::NeedsDestruction)) { ++failureCount; qWarning() << "Wrong typeInfo returned for" << tp; @@ -148,9 +166,22 @@ protected: ++failureCount; qWarning() << "Wrong typeName returned for" << tp; } - void *buf = QMetaType::create(tp, 0); - void *buf2 = QMetaType::create(tp, buf); - if (!buf) { + void *buf1 = QMetaType::create(tp, 0); + void *buf2 = QMetaType::create(tp, buf1); + void *buf3 = info.create(tp, 0); + void *buf4 = info.create(tp, buf1); + + QMetaType::construct(tp, space, 0); + QMetaType::destruct(tp, space); + QMetaType::construct(tp, space, buf1); + QMetaType::destruct(tp, space); + + info.construct(space, 0); + info.destruct(space); + info.construct(space, buf1); + info.destruct(space); + + if (!buf1) { ++failureCount; qWarning() << "Null buffer returned by QMetaType::create(tp, 0)"; } @@ -158,9 +189,20 @@ protected: ++failureCount; qWarning() << "Null buffer returned by QMetaType::create(tp, buf)"; } - QMetaType::destroy(tp, buf); + if (!buf3) { + ++failureCount; + qWarning() << "Null buffer returned by info.create(tp, 0)"; + } + if (!buf4) { + ++failureCount; + qWarning() << "Null buffer returned by infocreate(tp, buf)"; + } + QMetaType::destroy(tp, buf1); QMetaType::destroy(tp, buf2); + info.destroy(buf3); + info.destroy(buf4); } + new (space) Bar; } public: MetaTypeTorturer() : failureCount(0) { } @@ -480,13 +522,17 @@ template static void testCreateHelper() { typedef typename MetaEnumToType::Type Type; - void *actual = QMetaType::create(ID); + QMetaType info(ID); + void *actual1 = QMetaType::create(ID); + void *actual2 = info.create(); if (DefaultValueTraits::IsInitialized) { Type *expected = DefaultValueFactory::create(); - QCOMPARE(*static_cast(actual), *expected); + QCOMPARE(*static_cast(actual1), *expected); + QCOMPARE(*static_cast(actual2), *expected); delete expected; } - QMetaType::destroy(ID, actual); + QMetaType::destroy(ID, actual1); + info.destroy(actual2); } template<> @@ -529,9 +575,13 @@ static void testCreateCopyHelper() { typedef typename MetaEnumToType::Type Type; Type *expected = TestValueFactory::create(); - void *actual = QMetaType::create(ID, expected); - QCOMPARE(*static_cast(actual), *expected); - QMetaType::destroy(ID, actual); + QMetaType info(ID); + void *actual1 = QMetaType::create(ID, expected); + void *actual2 = info.create(expected); + QCOMPARE(*static_cast(actual1), *expected); + QCOMPARE(*static_cast(actual2), *expected); + QMetaType::destroy(ID, actual1); + info.destroy(actual2); delete expected; } @@ -588,6 +638,18 @@ void tst_QMetaType::sizeOf() QCOMPARE(QMetaType::sizeOf(type), size); } +void tst_QMetaType::sizeOfStaticLess_data() +{ + sizeOf_data(); +} + +void tst_QMetaType::sizeOfStaticLess() +{ + QFETCH(QMetaType::Type, type); + QFETCH(int, size); + QCOMPARE(QMetaType(type).sizeOf(), size); +} + struct CustomMovable {}; QT_BEGIN_NAMESPACE Q_DECLARE_TYPEINFO(CustomMovable, Q_MOVABLE_TYPE); @@ -653,6 +715,23 @@ void tst_QMetaType::flags() QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::PointerToQObject), isPointerToQObject); } +void tst_QMetaType::flagsStaticLess_data() +{ + flags_data(); +} + +void tst_QMetaType::flagsStaticLess() +{ + QFETCH(int, type); + QFETCH(bool, isMovable); + QFETCH(bool, isComplex); + + int flags = QMetaType(type).flags(); + QCOMPARE(bool(flags & QMetaType::NeedsConstruction), isComplex); + QCOMPARE(bool(flags & QMetaType::NeedsDestruction), isComplex); + QCOMPARE(bool(flags & QMetaType::MovableType), isMovable); +} + void tst_QMetaType::construct_data() { create_data(); @@ -688,20 +767,30 @@ template static void testConstructHelper() { typedef typename MetaEnumToType::Type Type; - int size = QMetaType::sizeOf(ID); - void *storage = qMallocAligned(size, TypeAlignment::Value); - void *actual = QMetaType::construct(ID, storage, /*copy=*/0); - QCOMPARE(actual, storage); + QMetaType info(ID); + int size = info.sizeOf(); + void *storage1 = qMallocAligned(size, TypeAlignment::Value); + void *actual1 = QMetaType::construct(ID, storage1, /*copy=*/0); + void *storage2 = qMallocAligned(size, TypeAlignment::Value); + void *actual2 = info.construct(storage2, /*copy=*/0); + QCOMPARE(actual1, storage1); + QCOMPARE(actual2, storage2); if (DefaultValueTraits::IsInitialized) { Type *expected = DefaultValueFactory::create(); - QCOMPARE(*static_cast(actual), *expected); + QCOMPARE(*static_cast(actual1), *expected); + QCOMPARE(*static_cast(actual2), *expected); delete expected; } - QMetaType::destruct(ID, actual); - qFreeAligned(storage); + QMetaType::destruct(ID, actual1); + qFreeAligned(storage1); + info.destruct(actual2); + qFreeAligned(storage2); QVERIFY(QMetaType::construct(ID, 0, /*copy=*/0) == 0); QMetaType::destruct(ID, 0); + + QVERIFY(info.construct(0, /*copy=*/0) == 0); + info.destruct(0); } template<> @@ -748,15 +837,24 @@ static void testConstructCopyHelper() { typedef typename MetaEnumToType::Type Type; Type *expected = TestValueFactory::create(); + QMetaType info(ID); int size = QMetaType::sizeOf(ID); - void *storage = qMallocAligned(size, TypeAlignment::Value); - void *actual = QMetaType::construct(ID, storage, expected); - QCOMPARE(actual, storage); - QCOMPARE(*static_cast(actual), *expected); - QMetaType::destruct(ID, actual); - qFreeAligned(storage); + QCOMPARE(info.sizeOf(), size); + void *storage1 = qMallocAligned(size, TypeAlignment::Value); + void *actual1 = QMetaType::construct(ID, storage1, expected); + void *storage2 = qMallocAligned(size, TypeAlignment::Value); + void *actual2 = info.construct(storage2, expected); + QCOMPARE(actual1, storage1); + QCOMPARE(actual2, storage2); + QCOMPARE(*static_cast(actual1), *expected); + QCOMPARE(*static_cast(actual2), *expected); + QMetaType::destruct(ID, actual1); + qFreeAligned(storage1); + info.destruct(actual2); + qFreeAligned(storage2); QVERIFY(QMetaType::construct(ID, 0, expected) == 0); + QVERIFY(info.construct(0, expected) == 0); delete expected; } @@ -895,6 +993,18 @@ void tst_QMetaType::isRegistered() QCOMPARE(QMetaType::isRegistered(typeId), registered); } +void tst_QMetaType::isRegisteredStaticLess_data() +{ + isRegistered_data(); +} + +void tst_QMetaType::isRegisteredStaticLess() +{ + QFETCH(int, typeId); + QFETCH(bool, registered); + QCOMPARE(QMetaType(typeId).isRegistered(), registered); +} + void tst_QMetaType::registerStreamBuiltin() { //should not crash; diff --git a/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp index 1c5dc9227fc..a3cdd38e560 100644 --- a/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -72,6 +72,8 @@ private slots: void constructCoreType_data(); void constructCoreType(); + void constructCoreTypeStaticLess_data(); + void constructCoreTypeStaticLess(); void constructCoreTypeCopy_data(); void constructCoreTypeCopy(); @@ -79,6 +81,8 @@ private slots: void constructInPlace(); void constructInPlaceCopy_data(); void constructInPlaceCopy(); + void constructInPlaceCopyStaticLess_data(); + void constructInPlaceCopyStaticLess(); }; tst_QMetaType::tst_QMetaType() @@ -89,6 +93,12 @@ tst_QMetaType::~tst_QMetaType() { } +struct BigClass +{ + double n,i,e,r,o,b; +}; +Q_DECLARE_METATYPE(BigClass); + void tst_QMetaType::typeBuiltin_data() { QTest::addColumn("typeName"); @@ -260,6 +270,23 @@ void tst_QMetaType::constructCoreType() } } +void tst_QMetaType::constructCoreTypeStaticLess_data() +{ + constructCoreType_data(); +} + +void tst_QMetaType::constructCoreTypeStaticLess() +{ + QFETCH(int, typeId); + QBENCHMARK { + QMetaType type(typeId); + for (int i = 0; i < 100000; ++i) { + void *data = type.create((void *)0); + type.destroy(data); + } + } +} + void tst_QMetaType::constructCoreTypeCopy_data() { constructCoreType_data(); @@ -285,6 +312,7 @@ void tst_QMetaType::constructCoreTypeCopy() void tst_QMetaType::constructInPlace_data() { constructCoreType_data(); + QTest::newRow("custom") << qMetaTypeId(); } void tst_QMetaType::constructInPlace() @@ -305,7 +333,7 @@ void tst_QMetaType::constructInPlace() void tst_QMetaType::constructInPlaceCopy_data() { - constructCoreType_data(); + constructInPlace_data(); } void tst_QMetaType::constructInPlaceCopy() @@ -326,5 +354,29 @@ void tst_QMetaType::constructInPlaceCopy() qFreeAligned(storage); } +void tst_QMetaType::constructInPlaceCopyStaticLess_data() +{ + constructInPlaceCopy_data(); +} + +void tst_QMetaType::constructInPlaceCopyStaticLess() +{ + QFETCH(int, typeId); + int size = QMetaType::sizeOf(typeId); + void *storage = qMallocAligned(size, 2 * sizeof(qlonglong)); + void *other = QMetaType::create(typeId); + QCOMPARE(QMetaType::construct(typeId, storage, other), storage); + QMetaType::destruct(typeId, storage); + QBENCHMARK { + QMetaType type(typeId); + for (int i = 0; i < 100000; ++i) { + type.construct(storage, other); + type.destruct(storage); + } + } + QMetaType::destroy(typeId, other); + qFreeAligned(storage); +} + QTEST_MAIN(tst_QMetaType) #include "tst_qmetatype.moc" From 1b23336a297681dc12700880540a5a8d31f146fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Mon, 9 Jan 2012 11:36:03 +0100 Subject: [PATCH 263/406] Use static-less QMetaType API in QVariant. This patch improves performance when constructing a custom type in a QVariant by ~ 7-20% (instructions count) depending on the type size and metatype attributes. Change-Id: Ic2707ff5abd689b66e23c1794f111504bf9b3b01 Reviewed-by: Stephen Kelly --- src/corelib/kernel/qvariant.cpp | 9 +++++---- .../benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 4197fe90931..d0470ff796a 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -787,7 +787,8 @@ const QVariant::Handler qt_dummy_variant_handler = { static void customConstruct(QVariant::Private *d, const void *copy) { - const uint size = QMetaType::sizeOf(d->type); + const QMetaType type(d->type); + const uint size = type.sizeOf(); if (!size) { d->type = QVariant::Invalid; return; @@ -795,11 +796,11 @@ static void customConstruct(QVariant::Private *d, const void *copy) // this logic should match with QVariantIntegrator::CanUseInternalSpace if (size <= sizeof(QVariant::Private::Data) - && (QMetaType::typeFlags(d->type) & QMetaType::MovableType)) { - QMetaType::construct(d->type, &d->data.ptr, copy); + && (type.flags() & QMetaType::MovableType)) { + type.construct(&d->data.ptr, copy); d->is_shared = false; } else { - void *ptr = QMetaType::create(d->type, copy); + void *ptr = type.create(copy); d->is_shared = true; d->data.shared = new QVariant::PrivateShared(ptr); } diff --git a/tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp index e842e18d52f..f6b4d88311c 100644 --- a/tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp @@ -90,6 +90,7 @@ struct BigClass double n,i,e,r,o,b; }; Q_STATIC_ASSERT(sizeof(BigClass) > sizeof(QVariant::Private::Data)); +Q_DECLARE_TYPEINFO(BigClass, Q_MOVABLE_TYPE); Q_DECLARE_METATYPE(BigClass); struct SmallClass @@ -97,6 +98,7 @@ struct SmallClass char s; }; Q_STATIC_ASSERT(sizeof(SmallClass) <= sizeof(QVariant::Private::Data)); +Q_DECLARE_TYPEINFO(SmallClass, Q_MOVABLE_TYPE); Q_DECLARE_METATYPE(SmallClass); void tst_qvariant::testBound() From 45cf303d3a873ff96cad1e1e8ff736602d0e8a5a Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 7 Feb 2012 12:50:54 +1000 Subject: [PATCH 264/406] Remove code related to test location. Testlib no longer does anything with the test location, and neither do any of Qt's tests, so the code is no longer needed. Change-Id: I1a464116179f3e26efadad6901f00f3c33e0ce84 Reviewed-by: Rohan McGovern --- src/testlib/qtestcase.cpp | 8 -------- src/testlib/qtestresult.cpp | 15 --------------- src/testlib/qtestresult_p.h | 4 ---- 3 files changed, 27 deletions(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 549d16b9974..c084441f5c5 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1499,13 +1499,10 @@ static void qInvokeTestMethodDataEntry(char *slot) /* Benchmarking: for each accumulation iteration*/ bool invokeOk; do { - QTestResult::setCurrentTestLocation(QTestResult::InitFunc); invokeMethod(QTest::currentTestObject, "init()"); if (QTestResult::skipCurrentTest()) break; - QTestResult::setCurrentTestLocation(QTestResult::Func); - QBenchmarkTestMethodData::current->result = QBenchmarkResult(); QBenchmarkTestMethodData::current->resultAccepted = false; @@ -1521,10 +1518,8 @@ static void qInvokeTestMethodDataEntry(char *slot) QTestResult::finishedCurrentTestData(); - QTestResult::setCurrentTestLocation(QTestResult::CleanupFunc); invokeMethod(QTest::currentTestObject, "cleanup()"); QTestResult::finishedCurrentTestDataCleanup(); - QTestResult::setCurrentTestLocation(QTestResult::NoWhere); // If this test method has a benchmark, repeat until all measurements are // acceptable. @@ -1593,7 +1588,6 @@ static bool qInvokeTestMethod(const char *slotName, const char *data=0) QTestResult::setCurrentGlobalTestData(gTable->testData(curGlobalDataIndex)); if (curGlobalDataIndex == 0) { - QTestResult::setCurrentTestLocation(QTestResult::DataFunc); qsnprintf(member, 512, "%s_data()", slot); invokeMethod(QTest::currentTestObject, member); } @@ -1747,12 +1741,10 @@ static void qInvokeTestMethods(QObject *testObject) QTEST_ASSERT(metaObject); QTestLog::startLogging(); QTestResult::setCurrentTestFunction("initTestCase"); - QTestResult::setCurrentTestLocation(QTestResult::DataFunc); QTestTable::globalTestTable(); invokeMethod(testObject, "initTestCase_data()"); if (!QTestResult::skipCurrentTest() && !QTest::currentTestFailed()) { - QTestResult::setCurrentTestLocation(QTestResult::InitFunc); invokeMethod(testObject, "initTestCase()"); // finishedCurrentTestDataCleanup() resets QTestResult::currentTestFailed(), so use a local copy. diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp index cfa85eb0658..79ea22bb434 100644 --- a/src/testlib/qtestresult.cpp +++ b/src/testlib/qtestresult.cpp @@ -59,7 +59,6 @@ namespace QTest static const char *currentTestObjectName = 0; static bool failed = false; static bool skipCurrentTest = false; - static QTestResult::TestLocation location = QTestResult::NoWhere; static const char *expectFailComment = 0; static int expectFailMode = 0; @@ -74,7 +73,6 @@ void QTestResult::reset() QTest::currentTestFunc = 0; QTest::currentTestObjectName = 0; QTest::failed = false; - QTest::location = QTestResult::NoWhere; QTest::expectFailComment = 0; QTest::expectFailMode = 0; @@ -112,8 +110,6 @@ void QTestResult::setCurrentTestFunction(const char *func) { QTest::currentTestFunc = func; QTest::failed = false; - if (!func) - QTest::location = NoWhere; if (func) QTestLog::enterTestFunction(func); } @@ -152,7 +148,6 @@ void QTestResult::finishedCurrentTestFunction() { QTest::currentTestFunc = 0; QTest::failed = false; - QTest::location = NoWhere; QTestLog::leaveTestFunction(); } @@ -289,16 +284,6 @@ void QTestResult::addSkip(const char *message, const char *file, int line) QTestLog::addSkip(message, file, line); } -QTestResult::TestLocation QTestResult::currentTestLocation() -{ - return QTest::location; -} - -void QTestResult::setCurrentTestLocation(TestLocation loc) -{ - QTest::location = loc; -} - void QTestResult::setCurrentTestObject(const char *name) { QTest::currentTestObjectName = name; diff --git a/src/testlib/qtestresult_p.h b/src/testlib/qtestresult_p.h index 5c6c4fba905..b060926f2ae 100644 --- a/src/testlib/qtestresult_p.h +++ b/src/testlib/qtestresult_p.h @@ -63,14 +63,11 @@ class QTestData; class Q_TESTLIB_EXPORT QTestResult { public: - enum TestLocation { NoWhere = 0, DataFunc = 1, InitFunc = 2, Func = 3, CleanupFunc = 4 }; - static const char *currentTestObjectName(); static bool currentTestFailed(); static QTestData *currentTestData(); static QTestData *currentGlobalTestData(); static const char *currentTestFunction(); - static TestLocation currentTestLocation(); static const char *currentDataTag(); static const char *currentGlobalDataTag(); static void finishedCurrentTestData(); @@ -86,7 +83,6 @@ public: static void setCurrentGlobalTestData(QTestData *data); static void setCurrentTestData(QTestData *data); static void setCurrentTestFunction(const char *func); - static void setCurrentTestLocation(TestLocation loc); static void setCurrentTestObject(const char *name); static void addSkip(const char *message, const char *file, int line); static bool expectFail(const char *dataIndex, const char *comment, From 9864241309203aeeda3c247fed8da8ab0ca2d041 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Mon, 13 Feb 2012 13:34:21 +1000 Subject: [PATCH 265/406] testlib: Remove obsolete version of QSKIP macro. A variadic version of the QSKIP macro has been left in qtestlib for a transitional period to give upstream projects time to catch up with the removal of the function from the API. This transitional period is now finished. Task-number: QTBUG-21652 Change-Id: Ib1a9158c2efbae05ffd0e69e72879f6387d4b2e8 Reviewed-by: Rohan McGovern --- src/testlib/qtestcase.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index c721dfd0d94..128decb6460 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -117,22 +117,11 @@ do { \ #define QTRY_COMPARE(__expr, __expected) QTRY_COMPARE_WITH_TIMEOUT(__expr, __expected, 5000) -#ifdef Q_CC_MSVC #define QSKIP(statement) \ do {\ QTest::qSkip(statement, __FILE__, __LINE__);\ return;\ } while (0) -#else -#define QSKIP(statement, ...) \ -do {\ - if (strcmp(#__VA_ARGS__, "") != 0)\ - QTest::qFail("The two argument version of QSKIP is no longer available. "\ - "Please update this test by removing the second argument in each QSKIP.", __FILE__, __LINE__);\ - QTest::qSkip(statement, __FILE__, __LINE__);\ - return;\ -} while (0) -#endif #define QEXPECT_FAIL(dataIndex, comment, mode)\ do {\ From 6dfb1de099158bb640f830647d09499934209b53 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 14 Feb 2012 13:10:02 +1000 Subject: [PATCH 266/406] Eliminate duplicate data row names in network autotests Change-Id: Icbfc24309a182f37268232fc3c299d35d6d6a0ea Reviewed-by: Rohan McGovern --- .../qnetworkcookie/tst_qnetworkcookie.cpp | 34 +++++++++---------- .../tst_qnetworkcookiejar.cpp | 6 ++-- .../tst_qnetworkdiskcache.cpp | 2 +- .../auto/network/ssl/qsslkey/tst_qsslkey.cpp | 5 +-- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/tests/auto/network/access/qnetworkcookie/tst_qnetworkcookie.cpp b/tests/auto/network/access/qnetworkcookie/tst_qnetworkcookie.cpp index 7c27973b564..bcd9cbdff78 100644 --- a/tests/auto/network/access/qnetworkcookie/tst_qnetworkcookie.cpp +++ b/tests/auto/network/access/qnetworkcookie/tst_qnetworkcookie.cpp @@ -165,11 +165,11 @@ void tst_QNetworkCookie::parseSingleCookie_data() QTest::newRow("with-value2") << " a=b" << cookie; QTest::newRow("with-value3") << "a=b " << cookie; QTest::newRow("with-value4") << " a=b " << cookie; - QTest::newRow("with-value4") << " a=b ;" << cookie; - QTest::newRow("with-value5") << "a =b" << cookie; - QTest::newRow("with-value6") << "a= b" << cookie; - QTest::newRow("with-value7") << "a = b" << cookie; - QTest::newRow("with-value8") << "a = b " << cookie; + QTest::newRow("with-value5") << " a=b ;" << cookie; + QTest::newRow("with-value6") << "a =b" << cookie; + QTest::newRow("with-value7") << "a= b" << cookie; + QTest::newRow("with-value8") << "a = b" << cookie; + QTest::newRow("with-value9") << "a = b " << cookie; cookie.setValue("\",\""); QTest::newRow("with-value-with-special1") << "a = \",\" " << cookie; @@ -376,31 +376,31 @@ void tst_QNetworkCookie::parseSingleCookie_data() // extra offsets cookie.setExpirationDate(QDateTime(QDate(1989, 1, 2), QTime(0, 0), Qt::UTC)); - QTest::newRow("zoneoffset-14") << "a=b;expires=Jan 1 89 15:0 JST+1" << cookie; + QTest::newRow("zoneoffset-15") << "a=b;expires=Jan 1 89 15:0 JST+1" << cookie; cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 0), Qt::UTC)); - QTest::newRow("zoneoffset-15") << "a=b;expires=Jan 1 89 0:0 GMT+1" << cookie; + QTest::newRow("zoneoffset-16") << "a=b;expires=Jan 1 89 0:0 GMT+1" << cookie; cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); - QTest::newRow("zoneoffset-15b") << "a=b;expires=Jan 1 89 1:0 GMT-1" << cookie; + QTest::newRow("zoneoffset-17") << "a=b;expires=Jan 1 89 1:0 GMT-1" << cookie; cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 0), Qt::UTC)); - QTest::newRow("zoneoffset-16") << "a=b;expires=Jan 1 89 0:0 GMT+01" << cookie; + QTest::newRow("zoneoffset-18") << "a=b;expires=Jan 1 89 0:0 GMT+01" << cookie; cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 5), Qt::UTC)); - QTest::newRow("zoneoffset-17") << "a=b;expires=Jan 1 89 0:0 GMT+0105" << cookie; + QTest::newRow("zoneoffset-19") << "a=b;expires=Jan 1 89 0:0 GMT+0105" << cookie; cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); - QTest::newRow("zoneoffset-18") << "a=b;expires=Jan 1 89 0:0 GMT+015" << cookie; + QTest::newRow("zoneoffset-20") << "a=b;expires=Jan 1 89 0:0 GMT+015" << cookie; cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); - QTest::newRow("zoneoffset-19") << "a=b;expires=Jan 1 89 0:0 GM" << cookie; + QTest::newRow("zoneoffset-21") << "a=b;expires=Jan 1 89 0:0 GM" << cookie; cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); - QTest::newRow("zoneoffset-19b") << "a=b;expires=Jan 1 89 0:0 GMT" << cookie; + QTest::newRow("zoneoffset-22") << "a=b;expires=Jan 1 89 0:0 GMT" << cookie; // offsets from gmt cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 0), Qt::UTC)); - QTest::newRow("zoneoffset-20") << "a=b;expires=Jan 1 89 0:0 +1" << cookie; + QTest::newRow("zoneoffset-23") << "a=b;expires=Jan 1 89 0:0 +1" << cookie; cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 0), Qt::UTC)); - QTest::newRow("zoneoffset-21") << "a=b;expires=Jan 1 89 0:0 +01" << cookie; + QTest::newRow("zoneoffset-24") << "a=b;expires=Jan 1 89 0:0 +01" << cookie; cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 1), Qt::UTC)); - QTest::newRow("zoneoffset-22") << "a=b;expires=Jan 1 89 0:0 +0101" << cookie; + QTest::newRow("zoneoffset-25") << "a=b;expires=Jan 1 89 0:0 +0101" << cookie; cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); - QTest::newRow("zoneoffset-23") << "a=b;expires=Jan 1 89 1:0 -1" << cookie; + QTest::newRow("zoneoffset-26") << "a=b;expires=Jan 1 89 1:0 -1" << cookie; // Y2k cookie.setExpirationDate(QDateTime(QDate(2000, 1, 1), QTime(0, 0), Qt::UTC)); diff --git a/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp b/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp index 73d0a4a6503..0e046ad6f9c 100644 --- a/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp +++ b/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp @@ -284,7 +284,7 @@ void tst_QNetworkCookieJar::cookiesForUrl_data() QTest::newRow("match-2") << allCookies << "http://nokia.com/web/" << result; QTest::newRow("match-3") << allCookies << "http://nokia.com/web/content" << result; QTest::newRow("match-4") << allCookies << "http://qt.nokia.com/web" << result; - QTest::newRow("match-4") << allCookies << "http://qt.nokia.com/web/" << result; + QTest::newRow("match-5") << allCookies << "http://qt.nokia.com/web/" << result; QTest::newRow("match-6") << allCookies << "http://qt.nokia.com/web/content" << result; cookie.setPath("/web/wiki"); @@ -295,7 +295,7 @@ void tst_QNetworkCookieJar::cookiesForUrl_data() QTest::newRow("one-match-2") << allCookies << "http://nokia.com/web/" << result; QTest::newRow("one-match-3") << allCookies << "http://nokia.com/web/content" << result; QTest::newRow("one-match-4") << allCookies << "http://qt.nokia.com/web" << result; - QTest::newRow("one-match-4") << allCookies << "http://qt.nokia.com/web/" << result; + QTest::newRow("one-match-5") << allCookies << "http://qt.nokia.com/web/" << result; QTest::newRow("one-match-6") << allCookies << "http://qt.nokia.com/web/content" << result; result.prepend(cookie); // longer path, it must match first @@ -317,7 +317,7 @@ void tst_QNetworkCookieJar::cookiesForUrl_data() QTest::newRow("exp-match-2") << allCookies << "http://nokia.com/web/" << result; QTest::newRow("exp-match-3") << allCookies << "http://nokia.com/web/content" << result; QTest::newRow("exp-match-4") << allCookies << "http://qt.nokia.com/web" << result; - QTest::newRow("exp-match-4") << allCookies << "http://qt.nokia.com/web/" << result; + QTest::newRow("exp-match-5") << allCookies << "http://qt.nokia.com/web/" << result; QTest::newRow("exp-match-6") << allCookies << "http://qt.nokia.com/web/content" << result; // path matching diff --git a/tests/auto/network/access/qnetworkdiskcache/tst_qnetworkdiskcache.cpp b/tests/auto/network/access/qnetworkdiskcache/tst_qnetworkdiskcache.cpp index 533108e76be..8a3c52cf725 100644 --- a/tests/auto/network/access/qnetworkdiskcache/tst_qnetworkdiskcache.cpp +++ b/tests/auto/network/access/qnetworkdiskcache/tst_qnetworkdiskcache.cpp @@ -306,7 +306,7 @@ void tst_QNetworkDiskCache::data_data() QNetworkCacheMetaData::RawHeaderList headers; headers.append(QNetworkCacheMetaData::RawHeader("type", "bin")); metaData.setRawHeaders(headers); - QTest::newRow("null") << metaData; + QTest::newRow("non-null") << metaData; } // public QIODevice* data(QUrl const& url) diff --git a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp index f59f0bb5a9b..657b91152fe 100644 --- a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp +++ b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp @@ -295,10 +295,11 @@ void tst_QSslKey::toEncryptedPemOrDer_data() << "aAzZ`1234567890-=~!@#$%^&*()_+[]{}\\|;:'\",.<>/?"; // ### add more (?) foreach (KeyInfo keyInfo, keyInfoList) { foreach (QString password, passwords) { - QString testName = QString("%1-%2-%3-%4").arg(keyInfo.fileInfo.fileName()) + QString testName = QString("%1-%2-%3-%4-%5").arg(keyInfo.fileInfo.fileName()) .arg(keyInfo.algorithm == QSsl::Rsa ? "RSA" : "DSA") .arg(keyInfo.type == QSsl::PrivateKey ? "PrivateKey" : "PublicKey") - .arg(keyInfo.format == QSsl::Pem ? "PEM" : "DER"); + .arg(keyInfo.format == QSsl::Pem ? "PEM" : "DER") + .arg(password); QTest::newRow(testName.toLatin1()) << keyInfo.fileInfo.absoluteFilePath() << keyInfo.algorithm << keyInfo.type << keyInfo.format << password; From eb64bb89cf6b7aa892c44723e3d14b845cc178bd Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 14 Feb 2012 13:13:05 +1000 Subject: [PATCH 267/406] Eliminate duplicate data row names in dbus, tools and xml autotests. Change-Id: Ic734435f57bb4f2160ecb3bc645e642207931a99 Reviewed-by: Rohan McGovern --- .../qdbusxmlparser/tst_qdbusxmlparser.cpp | 4 +- tests/auto/tools/moc/tst_moc.cpp | 6 +-- tests/auto/xml/dom/qdom/tst_qdom.cpp | 51 +++++++++---------- 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/tests/auto/dbus/qdbusxmlparser/tst_qdbusxmlparser.cpp b/tests/auto/dbus/qdbusxmlparser/tst_qdbusxmlparser.cpp index 7eb31ffb41f..25e3fdeabdd 100644 --- a/tests/auto/dbus/qdbusxmlparser/tst_qdbusxmlparser.cpp +++ b/tests/auto/dbus/qdbusxmlparser/tst_qdbusxmlparser.cpp @@ -470,12 +470,12 @@ void tst_QDBusXmlParser::properties_data() prop.type = "i"; prop.access = QDBusIntrospection::Property::Read; map << prop; - QTest::newRow("two") << + QTest::newRow("two-1") << "" "" << map; // invert the order of the declaration - QTest::newRow("two") << + QTest::newRow("two-2") << "" "" << map; diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 0aa1a68a646..27db6cc59c8 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -1623,7 +1623,7 @@ void tst_Moc::warnings_data() << QString("standard input:1: Warning: Property declaration x has no READ accessor function. The property will be invalid."); // Passing "-nn" should NOT suppress the warning - QTest::newRow("Invalid property warning") + QTest::newRow("Invalid property warning with -nn") << QByteArray("class X : public QObject { Q_OBJECT Q_PROPERTY(int x) };") << (QStringList() << "-nn") << 0 @@ -1631,7 +1631,7 @@ void tst_Moc::warnings_data() << QString("standard input:1: Warning: Property declaration x has no READ accessor function. The property will be invalid."); // Passing "-nw" should suppress the warning - QTest::newRow("Invalid property warning") + QTest::newRow("Invalid property warning with -nw") << QByteArray("class X : public QObject { Q_OBJECT Q_PROPERTY(int x) };") << (QStringList() << "-nw") << 0 @@ -1655,7 +1655,7 @@ void tst_Moc::warnings_data() << QString("standard input:1: Error: Class contains Q_OBJECT macro but does not inherit from QObject"); // "-nw" should not suppress the error - QTest::newRow("Does not inherit QObject with -nn") + QTest::newRow("Does not inherit QObject with -nw") << QByteArray("class X { Q_OBJECT };") << (QStringList() << "-nw") << 1 diff --git a/tests/auto/xml/dom/qdom/tst_qdom.cpp b/tests/auto/xml/dom/qdom/tst_qdom.cpp index f9570f76316..d79044157a6 100644 --- a/tests/auto/xml/dom/qdom/tst_qdom.cpp +++ b/tests/auto/xml/dom/qdom/tst_qdom.cpp @@ -555,7 +555,6 @@ void tst_QDom::saveWithSerialization_data() const if (prefix.isEmpty()) QFAIL("Cannot find testdata!"); QTest::newRow("doc01.xml") << QString(prefix + "/doc01.xml"); - QTest::newRow("doc01.xml") << QString(prefix + "/doc01.xml"); QTest::newRow("doc02.xml") << QString(prefix + "/doc02.xml"); QTest::newRow("doc03.xml") << QString(prefix + "/doc03.xml"); QTest::newRow("doc04.xml") << QString(prefix + "/doc04.xml"); @@ -1868,34 +1867,34 @@ void tst_QDom::setContentWhitespace_data() const QTest::addColumn("doc"); QTest::addColumn("expectedValidity"); - QTest::newRow("") << QString::fromLatin1(" ") << true; - QTest::newRow("") << QString::fromLatin1(" ") << true; - QTest::newRow("") << QString::fromLatin1(" ") << true; - QTest::newRow("") << QString::fromLatin1(" ") << true; - QTest::newRow("") << QString::fromLatin1("\n") << true; - QTest::newRow("") << QString::fromLatin1("\n\n") << true; - QTest::newRow("") << QString::fromLatin1("\n\n\n") << true; - QTest::newRow("") << QString::fromLatin1("\n\n\n\n") << true; - QTest::newRow("") << QString::fromLatin1("\t") << true; - QTest::newRow("") << QString::fromLatin1("\t\t") << true; - QTest::newRow("") << QString::fromLatin1("\t\t\t") << true; - QTest::newRow("") << QString::fromLatin1("\t\t\t\t") << true; + QTest::newRow("data1") << QString::fromLatin1(" ") << true; + QTest::newRow("data2") << QString::fromLatin1(" ") << true; + QTest::newRow("data3") << QString::fromLatin1(" ") << true; + QTest::newRow("data4") << QString::fromLatin1(" ") << true; + QTest::newRow("data5") << QString::fromLatin1("\n") << true; + QTest::newRow("data6") << QString::fromLatin1("\n\n") << true; + QTest::newRow("data7") << QString::fromLatin1("\n\n\n") << true; + QTest::newRow("data8") << QString::fromLatin1("\n\n\n\n") << true; + QTest::newRow("data9") << QString::fromLatin1("\t") << true; + QTest::newRow("data10") << QString::fromLatin1("\t\t") << true; + QTest::newRow("data11") << QString::fromLatin1("\t\t\t") << true; + QTest::newRow("data12") << QString::fromLatin1("\t\t\t\t") << true; /* With XML prolog. */ - QTest::newRow("") << QString::fromLatin1("") << true; + QTest::newRow("data13") << QString::fromLatin1("") << true; - QTest::newRow("") << QString::fromLatin1(" ") << false; - QTest::newRow("") << QString::fromLatin1(" ") << false; - QTest::newRow("") << QString::fromLatin1(" ") << false; - QTest::newRow("") << QString::fromLatin1(" ") << false; - QTest::newRow("") << QString::fromLatin1("\n") << false; - QTest::newRow("") << QString::fromLatin1("\n\n") << false; - QTest::newRow("") << QString::fromLatin1("\n\n\n") << false; - QTest::newRow("") << QString::fromLatin1("\n\n\n\n") << false; - QTest::newRow("") << QString::fromLatin1("\t") << false; - QTest::newRow("") << QString::fromLatin1("\t\t") << false; - QTest::newRow("") << QString::fromLatin1("\t\t\t") << false; - QTest::newRow("") << QString::fromLatin1("\t\t\t\t") << false; + QTest::newRow("data14") << QString::fromLatin1(" ") << false; + QTest::newRow("data15") << QString::fromLatin1(" ") << false; + QTest::newRow("data16") << QString::fromLatin1(" ") << false; + QTest::newRow("data17") << QString::fromLatin1(" ") << false; + QTest::newRow("data18") << QString::fromLatin1("\n") << false; + QTest::newRow("data19") << QString::fromLatin1("\n\n") << false; + QTest::newRow("data20") << QString::fromLatin1("\n\n\n") << false; + QTest::newRow("data21") << QString::fromLatin1("\n\n\n\n") << false; + QTest::newRow("data22") << QString::fromLatin1("\t") << false; + QTest::newRow("data23") << QString::fromLatin1("\t\t") << false; + QTest::newRow("data24") << QString::fromLatin1("\t\t\t") << false; + QTest::newRow("data25") << QString::fromLatin1("\t\t\t\t") << false; } void tst_QDom::taskQTBUG4595_dontAssertWhenDocumentSpecifiesUnknownEncoding() const From dfddabe1157bc6d826612b82d5bfb301205e7ad5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 9 Dec 2011 09:02:48 +0100 Subject: [PATCH 268/406] QDial: Fix crash when singleStep-property is 0. Task-number: QTBUG-23072 Change-Id: I296b46af23420b24fa5460b9660e33bf203ea29f Reviewed-by: Jarek Kobus (cherry picked from commit 6d370a19e367d0ccec59db5c34cbe2e3f7cfc586) Reviewed-by: Friedemann Kleint --- src/widgets/styles/qstylehelper.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/widgets/styles/qstylehelper.cpp b/src/widgets/styles/qstylehelper.cpp index 818671f85f7..3fdbc98323f 100644 --- a/src/widgets/styles/qstylehelper.cpp +++ b/src/widgets/styles/qstylehelper.cpp @@ -159,7 +159,9 @@ QPolygonF calcLines(const QStyleOptionSlider *dial) qreal xc = width / 2 + 0.5; qreal yc = height / 2 + 0.5; - int ns = dial->tickInterval; + const int ns = dial->tickInterval; + if (!ns) // Invalid values may be set by Qt Designer. + return poly; int notches = (dial->maximum + ns - 1 - dial->minimum) / ns; if (notches <= 0) return poly; From 0347ac1982477923ce93722ddd52bb9cb700961f Mon Sep 17 00:00:00 2001 From: jian liang Date: Mon, 13 Feb 2012 21:26:28 +0800 Subject: [PATCH 269/406] Use english name to match font in windows platform In windows platform, simplified chinese envrionment, the default font family name is "SimSun" which is not in the font list generated by EnumFontFamiliesEx(), this will cause chinese font can't be displayed. This patch will generate font's english name during font enumeration in windows platform, and take font's english name into consideration in font matching. The english name generation code is taken from Qt4.8 Change-Id: Ie939ec0c8c08c628a835c7a53fb22d0545626d9c Reviewed-by: Jiang Jiang Reviewed-by: Friedemann Kleint --- src/gui/text/qfontdatabase.cpp | 24 ++- src/gui/text/qfontdatabase_qpa.cpp | 16 ++ .../windows/qwindowsfontdatabase.cpp | 17 +- .../windows/qwindowsfontdatabase_ft.cpp | 193 +++++++++++++++++- 4 files changed, 238 insertions(+), 12 deletions(-) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index fa9cae43590..77262d66f0c 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -349,6 +349,7 @@ struct QtFontFamily #endif QString name; + QStringList aliases; int count; QtFontFoundry **foundries; @@ -996,6 +997,25 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy, return score; } +static bool matchFamilyName(const QString &familyName, QtFontFamily *f) +{ + if (familyName.isEmpty()) + return true; + + if (f->name.compare(familyName, Qt::CaseInsensitive) == 0) + return true; + + QStringList::const_iterator it = f->aliases.constBegin(); + while (it != f->aliases.constEnd()) { + if ((*it).compare(familyName, Qt::CaseInsensitive) == 0) + return true; + + ++it; + } + + return false; +} + /*! \internal @@ -1045,9 +1065,7 @@ static void match(int script, const QFontDef &request, test.family = db->families[x]; test.familyIndex = x; - if (!family_name.isEmpty() - && test.family->name.compare(family_name, Qt::CaseInsensitive) != 0 - ) + if (!matchFamilyName(family_name, test.family)) continue; if (family_name.isEmpty()) diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp index c3d7529c2e9..2a9c37fb137 100644 --- a/src/gui/text/qfontdatabase_qpa.cpp +++ b/src/gui/text/qfontdatabase_qpa.cpp @@ -87,6 +87,22 @@ Q_GUI_EXPORT void qt_registerFont(const QString &familyName, const QString &fou size->handle = handle; } +Q_GUI_EXPORT void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias) +{ + if (alias.isEmpty()) + return; + + QFontDatabasePrivate *d = privateDb(); + QtFontFamily *f = d->family(familyName, false); + if (!f) + return; + + if (f->aliases.contains(alias, Qt::CaseInsensitive)) + return; + + f->aliases.push_back(alias); +} + static QStringList fallbackFamilies(const QString &family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) { QStringList retList = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script); diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index fa95f4f529a..1df985c8a78 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -329,6 +329,11 @@ static inline QFontDatabase::WritingSystem writingSystemFromScript(const QString return QFontDatabase::Any; } +extern bool localizedName(const QString &name); +extern QString getEnglishName(const QString &familyName); + +Q_GUI_EXPORT void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias); + static bool addFontToDatabase(QString familyName, const QString &scriptName, const TEXTMETRIC *textmetric, const FONTSIGNATURE *signature, @@ -365,10 +370,10 @@ static bool addFontToDatabase(QString familyName, const QString &scriptName, << " stretch=" << stretch; } -/* Fixme: omitted for the moment - if(ttf && localizedName(familyName) && family->english_name.isEmpty()) - family->english_name = getEnglishName(familyName); -*/ + QString englishName; + if (ttf && localizedName(familyName)) + englishName = getEnglishName(familyName); + QSupportedWritingSystems writingSystems; if (type & TRUETYPE_FONTTYPE) { quint32 unicodeRange[4] = { @@ -405,6 +410,10 @@ static bool addFontToDatabase(QString familyName, const QString &scriptName, if (weight <= QFont::DemiBold && style != QFont::StyleItalic) QPlatformFontDatabase::registerFont(familyName, foundryName, QFont::Bold, QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, 0); + + if (!englishName.isEmpty()) + qt_registerAliasToFontFamily(familyName, englishName); + return true; } diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index 8455e9e6d0f..6b6d1a294a0 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -100,6 +100,184 @@ static inline QFont::Weight weightFromInteger(long weight) return QFont::Black; } +#ifdef MAKE_TAG +#undef MAKE_TAG +#endif +// GetFontData expects the tags in little endian ;( +#define MAKE_TAG(ch1, ch2, ch3, ch4) (\ + (((quint32)(ch4)) << 24) | \ + (((quint32)(ch3)) << 16) | \ + (((quint32)(ch2)) << 8) | \ + ((quint32)(ch1)) \ + ) + +bool localizedName(const QString &name) +{ + const QChar *c = name.unicode(); + for (int i = 0; i < name.length(); ++i) { + if (c[i].unicode() >= 0x100) + return true; + } + return false; +} + +static inline quint16 getUShort(const unsigned char *p) +{ + quint16 val; + val = *p++ << 8; + val |= *p; + + return val; +} + +static QString getEnglishName(const uchar *table, quint32 bytes) +{ + QString i18n_name; + enum { + NameRecordSize = 12, + FamilyId = 1, + MS_LangIdEnglish = 0x009 + }; + + // get the name table + quint16 count; + quint16 string_offset; + const unsigned char *names; + + int microsoft_id = -1; + int apple_id = -1; + int unicode_id = -1; + + if (getUShort(table) != 0) + goto error; + + count = getUShort(table+2); + string_offset = getUShort(table+4); + names = table + 6; + + if (string_offset >= bytes || 6 + count*NameRecordSize > string_offset) + goto error; + + for (int i = 0; i < count; ++i) { + // search for the correct name entry + + quint16 platform_id = getUShort(names + i*NameRecordSize); + quint16 encoding_id = getUShort(names + 2 + i*NameRecordSize); + quint16 language_id = getUShort(names + 4 + i*NameRecordSize); + quint16 name_id = getUShort(names + 6 + i*NameRecordSize); + + if (name_id != FamilyId) + continue; + + enum { + PlatformId_Unicode = 0, + PlatformId_Apple = 1, + PlatformId_Microsoft = 3 + }; + + quint16 length = getUShort(names + 8 + i*NameRecordSize); + quint16 offset = getUShort(names + 10 + i*NameRecordSize); + if (DWORD(string_offset + offset + length) >= bytes) + continue; + + if ((platform_id == PlatformId_Microsoft + && (encoding_id == 0 || encoding_id == 1)) + && (language_id & 0x3ff) == MS_LangIdEnglish + && microsoft_id == -1) + microsoft_id = i; + // not sure if encoding id 4 for Unicode is utf16 or ucs4... + else if (platform_id == PlatformId_Unicode && encoding_id < 4 && unicode_id == -1) + unicode_id = i; + else if (platform_id == PlatformId_Apple && encoding_id == 0 && language_id == 0) + apple_id = i; + } + { + bool unicode = false; + int id = -1; + if (microsoft_id != -1) { + id = microsoft_id; + unicode = true; + } else if (apple_id != -1) { + id = apple_id; + unicode = false; + } else if (unicode_id != -1) { + id = unicode_id; + unicode = true; + } + if (id != -1) { + quint16 length = getUShort(names + 8 + id*NameRecordSize); + quint16 offset = getUShort(names + 10 + id*NameRecordSize); + if (unicode) { + // utf16 + + length /= 2; + i18n_name.resize(length); + QChar *uc = (QChar *) i18n_name.unicode(); + const unsigned char *string = table + string_offset + offset; + for (int i = 0; i < length; ++i) + uc[i] = getUShort(string + 2*i); + } else { + // Apple Roman + + i18n_name.resize(length); + QChar *uc = (QChar *) i18n_name.unicode(); + const unsigned char *string = table + string_offset + offset; + for (int i = 0; i < length; ++i) + uc[i] = QLatin1Char(string[i]); + } + } + } +error: + //qDebug("got i18n name of '%s' for font '%s'", i18n_name.latin1(), familyName.toLocal8Bit().data()); + return i18n_name; +} + +QString getEnglishName(const QString &familyName) +{ + QString i18n_name; + + HDC hdc = GetDC( 0 ); + LOGFONT lf; + memset(&lf, 0, sizeof(LOGFONT)); + memcpy(lf.lfFaceName, familyName.utf16(), qMin(LF_FACESIZE, familyName.length()) * sizeof(wchar_t)); + lf.lfCharSet = DEFAULT_CHARSET; + HFONT hfont = CreateFontIndirect(&lf); + + if (!hfont) { + ReleaseDC(0, hdc); + return QString(); + } + + HGDIOBJ oldobj = SelectObject( hdc, hfont ); + + const DWORD name_tag = MAKE_TAG( 'n', 'a', 'm', 'e' ); + + // get the name table + unsigned char *table = 0; + + DWORD bytes = GetFontData( hdc, name_tag, 0, 0, 0 ); + if ( bytes == GDI_ERROR ) { + // ### Unused variable + // int err = GetLastError(); + goto error; + } + + table = new unsigned char[bytes]; + GetFontData(hdc, name_tag, 0, table, bytes); + if ( bytes == GDI_ERROR ) + goto error; + + i18n_name = getEnglishName(table, bytes); +error: + delete [] table; + SelectObject( hdc, oldobj ); + DeleteObject( hfont ); + ReleaseDC( 0, hdc ); + + //qDebug("got i18n name of '%s' for font '%s'", i18n_name.latin1(), familyName.toLocal8Bit().data()); + return i18n_name; +} + static FontFile * createFontFile(const QString &fileName, int index) { FontFile *fontFile = new FontFile; @@ -108,6 +286,8 @@ static FontFile * createFontFile(const QString &fileName, int index) return fontFile; } +Q_GUI_EXPORT void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias); + static bool addFontToDatabase(QString familyName, const QString &scriptName, const TEXTMETRIC *textmetric, const FONTSIGNATURE *signature, @@ -151,10 +331,10 @@ static bool addFontToDatabase(QString familyName, const QString &scriptName, << " stretch=" << stretch; } -/* Fixme: omitted for the moment - if(ttf && localizedName(faceName) && family->english_name.isEmpty()) - family->english_name = getEnglishName(faceName); -*/ + QString englishName; + if (ttf && localizedName(faceName)) + englishName = getEnglishName(faceName); + QSupportedWritingSystems writingSystems; if (type & TRUETYPE_FONTTYPE) { quint32 unicodeRange[4] = { @@ -204,7 +384,7 @@ static bool addFontToDatabase(QString familyName, const QString &scriptName, const FontKey &fontKey = allFonts.at(k); for (int i = 0; i < fontKey.second.length(); ++i) { const QString &font = fontKey.second.at(i); - if (font == faceName || (faceName != fullName && fullName == font)) { + if (font == faceName || fullName == font || englishName == font) { value = fontRegistry.value(fontKey.first).toString(); index = i; break; @@ -236,6 +416,9 @@ static bool addFontToDatabase(QString familyName, const QString &scriptName, QPlatformFontDatabase::registerFont(faceName, foundryName, QFont::Bold, QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(value, index)); + if (!englishName.isEmpty()) + qt_registerAliasToFontFamily(faceName, englishName); + return true; } From 922e0ab5154c72c78e0b8871d06ef5d0e4a0acc3 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Wed, 15 Feb 2012 11:32:59 +1000 Subject: [PATCH 270/406] Add support for querying an elided sub-string from QTextEngine. The QML Text element attempts to layout text first without eliding and only builds an elided string for the last visible line. This allows it to re-use the already generated layout information to build the elided string rather than doing a second layout of the relevant text. Change-Id: Ieee45902d0c129853abe822c465eece4d634a028 Reviewed-by: Martin Jones Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qtextengine.cpp | 42 ++++++++++++++++++++---------------- src/gui/text/qtextengine_p.h | 2 +- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 5e5354a9806..bc7f4f7ad67 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -2237,7 +2237,7 @@ static inline bool prevCharJoins(const QString &string, int pos) return (joining == QChar::Dual || joining == QChar::Center); } -QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int flags) const +QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int flags, int from, int count) const { // qDebug() << "elidedText; available width" << width.toReal() << "text width:" << this->width(0, layoutData->string.length()).toReal(); @@ -2271,10 +2271,14 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int validate(); + const int to = count >= 0 && count <= layoutData->string.length() - from + ? from + count + : layoutData->string.length(); + if (mode == Qt::ElideNone - || this->width(0, layoutData->string.length()) <= width - || layoutData->string.length() <= 1) - return layoutData->string; + || this->width(from, layoutData->string.length()) <= width + || to - from <= 1) + return layoutData->string.mid(from, from - to); QFixed ellipsisWidth; QString ellipsisText; @@ -2328,7 +2332,7 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int if (mode == Qt::ElideRight) { QFixed currentWidth; int pos; - int nextBreak = 0; + int nextBreak = from; do { pos = nextBreak; @@ -2338,17 +2342,17 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int ++nextBreak; currentWidth += this->width(pos, nextBreak - pos); - } while (nextBreak < layoutData->string.length() + } while (nextBreak < to && currentWidth < availableWidth); if (nextCharJoins(layoutData->string, pos)) ellipsisText.prepend(QChar(0x200d) /* ZWJ */); - return layoutData->string.left(pos) + ellipsisText; + return layoutData->string.mid(from, pos - from) + ellipsisText; } else if (mode == Qt::ElideLeft) { QFixed currentWidth; int pos; - int nextBreak = layoutData->string.length(); + int nextBreak = to; do { pos = nextBreak; @@ -2358,22 +2362,22 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int --nextBreak; currentWidth += this->width(nextBreak, pos - nextBreak); - } while (nextBreak > 0 + } while (nextBreak > from && currentWidth < availableWidth); if (prevCharJoins(layoutData->string, pos)) ellipsisText.append(QChar(0x200d) /* ZWJ */); - return ellipsisText + layoutData->string.mid(pos); + return ellipsisText + layoutData->string.mid(pos, to - pos); } else if (mode == Qt::ElideMiddle) { QFixed leftWidth; QFixed rightWidth; - int leftPos = 0; - int nextLeftBreak = 0; + int leftPos = from; + int nextLeftBreak = from; - int rightPos = layoutData->string.length(); - int nextRightBreak = layoutData->string.length(); + int rightPos = to; + int nextRightBreak = to; do { leftPos = nextLeftBreak; @@ -2384,13 +2388,13 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int ++nextLeftBreak; --nextRightBreak; - while (nextRightBreak > 0 && !attributes[nextRightBreak].charStop) + while (nextRightBreak > from && !attributes[nextRightBreak].charStop) --nextRightBreak; leftWidth += this->width(leftPos, nextLeftBreak - leftPos); rightWidth += this->width(nextRightBreak, rightPos - nextRightBreak); - } while (nextLeftBreak < layoutData->string.length() - && nextRightBreak > 0 + } while (nextLeftBreak < to + && nextRightBreak > from && leftWidth + rightWidth < availableWidth); if (nextCharJoins(layoutData->string, leftPos)) @@ -2398,10 +2402,10 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int if (prevCharJoins(layoutData->string, rightPos)) ellipsisText.append(QChar(0x200d) /* ZWJ */); - return layoutData->string.left(leftPos) + ellipsisText + layoutData->string.mid(rightPos); + return layoutData->string.mid(from, leftPos - from) + ellipsisText + layoutData->string.mid(rightPos, to - rightPos); } - return layoutData->string; + return layoutData->string.mid(from, to - from); } void QTextEngine::setBoundary(int strPos) const diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 641d946aa94..53031cfcee3 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -619,7 +619,7 @@ public: bool atSpace(int position) const; void indexAdditionalFormats(); - QString elidedText(Qt::TextElideMode mode, const QFixed &width, int flags = 0) const; + QString elidedText(Qt::TextElideMode mode, const QFixed &width, int flags = 0, int from = 0, int count = -1) const; void shapeLine(const QScriptLine &line); QFixed leadingSpaceWidth(const QScriptLine &line); From 32060c2115308e2e480a5b1787dbb2ebb1ed7936 Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Wed, 15 Feb 2012 14:22:48 +1000 Subject: [PATCH 271/406] Changed json unittest to work from installation directory - Changed json unittest to use TESTDATA and QFINDTESTDATA Change-Id: Id29f8257565f409fa184ba465f25bc8454e2b7fb Reviewed-by: Rohan McGovern Reviewed-by: Jason McDonald --- tests/auto/corelib/json/json.pro | 2 +- tests/auto/corelib/json/tst_qtjson.cpp | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/tests/auto/corelib/json/json.pro b/tests/auto/corelib/json/json.pro index 5158b7337ab..7978a742783 100644 --- a/tests/auto/corelib/json/json.pro +++ b/tests/auto/corelib/json/json.pro @@ -3,6 +3,6 @@ QT = core testlib CONFIG -= app_bundle CONFIG += testcase -DEFINES += SRCDIR=\\\"$$PWD/\\\" +TESTDATA += test.json test.bjson test3.json test2.json SOURCES += tst_qtjson.cpp diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp index e35f645ef61..323546b8eae 100644 --- a/tests/auto/corelib/json/tst_qtjson.cpp +++ b/tests/auto/corelib/json/tst_qtjson.cpp @@ -111,6 +111,8 @@ private Q_SLOTS: void testCompaction(); void testDebugStream(); void testCompactionError(); +private: + QString testDataDir; }; TestQtJson::TestQtJson(QObject *parent) : QObject(parent) @@ -119,6 +121,9 @@ TestQtJson::TestQtJson(QObject *parent) : QObject(parent) void TestQtJson::initTestCase() { + testDataDir = QFileInfo(QFINDTESTDATA("test.json")).absolutePath(); + if (testDataDir.isEmpty()) + testDataDir = QCoreApplication::applicationDirPath(); } void TestQtJson::cleanupTestCase() @@ -1077,7 +1082,7 @@ void TestQtJson::fromJson() void TestQtJson::fromBinary() { - QFile file(QLatin1String(SRCDIR "test.json")); + QFile file(testDataDir + "/test.json"); file.open(QFile::ReadOnly); QByteArray testJson = file.readAll(); @@ -1086,7 +1091,7 @@ void TestQtJson::fromBinary() QVERIFY(!outdoc.isNull()); QVERIFY(doc == outdoc); - QFile bfile(QLatin1String(SRCDIR "test.bjson")); + QFile bfile(testDataDir + "/test.bjson"); bfile.open(QFile::ReadOnly); QByteArray binary = bfile.readAll(); @@ -1099,8 +1104,8 @@ void TestQtJson::fromBinary() void TestQtJson::toAndFromBinary_data() { QTest::addColumn("filename"); - QTest::newRow("test.json") << QString::fromLatin1(SRCDIR "test.json"); - QTest::newRow("test2.json") << QString::fromLatin1(SRCDIR "test2.json"); + QTest::newRow("test.json") << (testDataDir + "/test.json"); + QTest::newRow("test2.json") << (testDataDir + "/test2.json"); } void TestQtJson::toAndFromBinary() @@ -1279,7 +1284,7 @@ void TestQtJson::parseDuplicateKeys() void TestQtJson::testParser() { - QFile file(QLatin1String(SRCDIR "test.json")); + QFile file(testDataDir + "/test.json"); file.open(QFile::ReadOnly); QByteArray testJson = file.readAll(); @@ -1364,7 +1369,7 @@ void TestQtJson::compactObject() void TestQtJson::validation() { // this basically tests that we don't crash on corrupt data - QFile file(QLatin1String(SRCDIR "test.json")); + QFile file(testDataDir + "/test.json"); QVERIFY(file.open(QFile::ReadOnly)); QByteArray testJson = file.readAll(); QVERIFY(!testJson.isEmpty()); @@ -1385,7 +1390,7 @@ void TestQtJson::validation() } - QFile file2(QLatin1String(SRCDIR "test3.json")); + QFile file2(testDataDir + "/test3.json"); file2.open(QFile::ReadOnly); testJson = file2.readAll(); QVERIFY(!testJson.isEmpty()); From 857775f701cf3e1418e9cdc123a67ed3dde1c439 Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Wed, 15 Feb 2012 14:30:16 +1000 Subject: [PATCH 272/406] Changed qcryptographichash unittest to work from installation directory - Changed qcryptographichash to use TESTDATA and QFINDTESTDATA Change-Id: Ic3a1bdccc9f81605c648dab2a642421d17f7fe80 Reviewed-by: Jason McDonald Reviewed-by: Rohan McGovern --- .../tools/qcryptographichash/qcryptographichash.pro | 12 +----------- .../qcryptographichash/tst_qcryptographichash.cpp | 4 +++- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/tests/auto/corelib/tools/qcryptographichash/qcryptographichash.pro b/tests/auto/corelib/tools/qcryptographichash/qcryptographichash.pro index fddd67fbd68..1c4b74e16dc 100644 --- a/tests/auto/corelib/tools/qcryptographichash/qcryptographichash.pro +++ b/tests/auto/corelib/tools/qcryptographichash/qcryptographichash.pro @@ -3,14 +3,4 @@ TARGET = tst_qcryptographichash QT = core testlib SOURCES = tst_qcryptographichash.cpp - -wince* { - addFiles.files = data/* - addFiles.path = data/ - DEPLOYMENT += addFiles - - DEFINES += SRCDIR=\\\".\\\" -} -else { - DEFINES += SRCDIR=\\\"$$PWD/\\\" -} \ No newline at end of file +TESTDATA += data/* diff --git a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp index 0f35089ff76..81cc66f045a 100644 --- a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp +++ b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp @@ -169,7 +169,9 @@ void tst_QCryptographicHash::files() QFETCH(QCryptographicHash::Algorithm, algorithm); QFETCH(QByteArray, md5sum); { - QFile f(QString::fromLocal8Bit(SRCDIR) + filename); + QString testData = QFINDTESTDATA(filename); + QVERIFY2(!testData.isEmpty(), qPrintable(QString("Cannot find test data: %1").arg(filename))); + QFile f(testData); QCryptographicHash hash(algorithm); QVERIFY(! hash.addData(&f)); // file is not open for reading; if (f.open(QIODevice::ReadOnly)) { From 20f6dc615ac6dfe97681eb1652a10e6d29affbce Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Thu, 16 Feb 2012 08:13:13 +1000 Subject: [PATCH 273/406] Changed qsslcertificate unittest to work from install directory - Changed to use TESTDATA and QFINDTESTDATA instead of SRCDIR Change-Id: I1957ef287ba2f337b5e0b2c6245d872eacb6316f Reviewed-by: Jason McDonald Reviewed-by: Rohan McGovern --- .../ssl/qsslcertificate/qsslcertificate.pro | 17 +--- .../qsslcertificate/tst_qsslcertificate.cpp | 84 ++++++++----------- 2 files changed, 38 insertions(+), 63 deletions(-) diff --git a/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro b/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro index 7e2abac3f80..60ad3cbfd1e 100644 --- a/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro +++ b/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro @@ -6,19 +6,4 @@ QT = core network testlib TARGET = tst_qsslcertificate -win32 { - CONFIG(debug, debug|release) { - DESTDIR = debug -} else { - DESTDIR = release - } -} - -wince* { - certFiles.files = certificates more-certificates - certFiles.path = . - DEPLOYMENT += certFiles - DEFINES += SRCDIR=\\\".\\\" -} else { - DEFINES += SRCDIR=\\\"$$PWD/\\\" -} +TESTDATA += certificates/* more-certificates/* verify-certs/* diff --git a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp index 8003ad19326..da2dd989c71 100644 --- a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp +++ b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp @@ -71,14 +71,10 @@ class tst_QSslCertificate : public QObject #endif QString oldCurrentDir; -public: - tst_QSslCertificate(); - virtual ~tst_QSslCertificate(); public slots: - void initTestCase_data(); - void init(); - void cleanup(); + void initTestCase(); + void cleanupTestCase(); #ifndef QT_NO_OPENSSL private slots: @@ -120,11 +116,23 @@ private slots: // ### add tests for certificate bundles (multiple certificates concatenated into a single // structure); both PEM and DER formatted #endif +private: + QString testDataDir; }; -tst_QSslCertificate::tst_QSslCertificate() +void tst_QSslCertificate::initTestCase() { - QDir dir(SRCDIR + QLatin1String("/certificates")); + testDataDir = QFileInfo(QFINDTESTDATA("certificates")).absolutePath(); + if (testDataDir.isEmpty()) + testDataDir = QCoreApplication::applicationDirPath(); + + if (QDir::current().absolutePath() != testDataDir) { + oldCurrentDir = QDir::current().absolutePath(); + QVERIFY2(QDir::setCurrent(testDataDir), + qPrintable(QString("Cannot change directory to %1").arg(testDataDir))); + } + + QDir dir(testDataDir + "/certificates"); QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::Readable); QRegExp rxCert(QLatin1String("^.+\\.(pem|der)$")); QRegExp rxSan(QLatin1String("^(.+\\.(?:pem|der))\\.san$")); @@ -148,29 +156,11 @@ tst_QSslCertificate::tst_QSslCertificate() } } -tst_QSslCertificate::~tst_QSslCertificate() -{ -} - -void tst_QSslCertificate::initTestCase_data() -{ -} - -void tst_QSslCertificate::init() -{ - QString srcdir(QLatin1String(SRCDIR)); - if (!srcdir.isEmpty()) { - oldCurrentDir = QDir::current().absolutePath(); - QDir::setCurrent(srcdir); - } -} - -void tst_QSslCertificate::cleanup() +void tst_QSslCertificate::cleanupTestCase() { if (!oldCurrentDir.isEmpty()) { QDir::setCurrent(oldCurrentDir); } - } static QByteArray readFile(const QString &absFilePath) @@ -569,7 +559,7 @@ void tst_QSslCertificate::fromPath_data() QTest::newRow("\"d.*/c.*.pem\" wildcard pem") << QString("d.*/c.*.pem") << int(QRegExp::Wildcard) << true << 0; QTest::newRow("\"d.*/c.*.pem\" wildcard der") << QString("d.*/c.*.pem") << int(QRegExp::Wildcard) << false << 0; #ifdef Q_OS_LINUX - QTest::newRow("absolute path wildcard pem") << QString(QDir::currentPath() + "/certificates/*.pem") << int(QRegExp::Wildcard) << true << 5; + QTest::newRow("absolute path wildcard pem") << (testDataDir + "/certificates/*.pem") << int(QRegExp::Wildcard) << true << 5; #endif QTest::newRow("trailing-whitespace") << QString("more-certificates/trailing-whitespace.pem") << int(QRegExp::FixedString) << true << 1; @@ -783,7 +773,7 @@ void tst_QSslCertificate::task256066toPem() void tst_QSslCertificate::nulInCN() { QList certList = - QSslCertificate::fromPath(SRCDIR "more-certificates/badguy-nul-cn.crt"); + QSslCertificate::fromPath(testDataDir + "/more-certificates/badguy-nul-cn.crt"); QCOMPARE(certList.size(), 1); const QSslCertificate &cert = certList.at(0); @@ -799,7 +789,7 @@ void tst_QSslCertificate::nulInCN() void tst_QSslCertificate::nulInSan() { QList certList = - QSslCertificate::fromPath(SRCDIR "more-certificates/badguy-nul-san.crt"); + QSslCertificate::fromPath(testDataDir + "/more-certificates/badguy-nul-san.crt"); QCOMPARE(certList.size(), 1); const QSslCertificate &cert = certList.at(0); @@ -819,7 +809,7 @@ void tst_QSslCertificate::nulInSan() void tst_QSslCertificate::largeSerialNumber() { QList certList = - QSslCertificate::fromPath(SRCDIR "more-certificates/cert-large-serial-number.pem"); + QSslCertificate::fromPath(testDataDir + "/more-certificates/cert-large-serial-number.pem"); QCOMPARE(certList.size(), 1); @@ -831,7 +821,7 @@ void tst_QSslCertificate::largeSerialNumber() void tst_QSslCertificate::largeExpirationDate() // QTBUG-12489 { QList certList = - QSslCertificate::fromPath(SRCDIR "more-certificates/cert-large-expiration-date.pem"); + QSslCertificate::fromPath(testDataDir + "/more-certificates/cert-large-expiration-date.pem"); QCOMPARE(certList.size(), 1); @@ -854,18 +844,18 @@ void tst_QSslCertificate::blacklistedCertificates() void tst_QSslCertificate::toText() { QList certList = - QSslCertificate::fromPath(SRCDIR "more-certificates/cert-large-expiration-date.pem"); + QSslCertificate::fromPath(testDataDir + "/more-certificates/cert-large-expiration-date.pem"); QCOMPARE(certList.size(), 1); const QSslCertificate &cert = certList.at(0); // Openssl's cert dump method changed slightly between 0.9.8 and 1.0.0 versions, so we want it to match any output - QFile fOld(SRCDIR "more-certificates/cert-large-expiration-date.txt.0.9.8"); + QFile fOld(testDataDir + "/more-certificates/cert-large-expiration-date.txt.0.9.8"); QVERIFY(fOld.open(QIODevice::ReadOnly | QFile::Text)); QByteArray txtOld = fOld.readAll(); - QFile fNew(SRCDIR "more-certificates/cert-large-expiration-date.txt.1.0.0"); + QFile fNew(testDataDir + "/more-certificates/cert-large-expiration-date.txt.1.0.0"); QVERIFY(fNew.open(QIODevice::ReadOnly | QFile::Text)); QByteArray txtNew = fNew.readAll(); QVERIFY(txtOld == cert.toText() || txtNew == cert.toText()); @@ -874,7 +864,7 @@ void tst_QSslCertificate::toText() void tst_QSslCertificate::multipleCommonNames() { QList certList = - QSslCertificate::fromPath(SRCDIR "more-certificates/test-cn-two-cns-cert.pem"); + QSslCertificate::fromPath(testDataDir + "/more-certificates/test-cn-two-cns-cert.pem"); QVERIFY2(certList.count() > 0, "Please run this test from the source directory"); QStringList commonNames = certList[0].subjectInfo(QSslCertificate::CommonName); @@ -885,14 +875,14 @@ void tst_QSslCertificate::multipleCommonNames() void tst_QSslCertificate::subjectAndIssuerAttributes() { QList certList = - QSslCertificate::fromPath(SRCDIR "more-certificates/test-cn-with-drink-cert.pem"); + QSslCertificate::fromPath(testDataDir + "/more-certificates/test-cn-with-drink-cert.pem"); QVERIFY2(certList.count() > 0, "Please run this test from the source directory"); QList attributes = certList[0].subjectInfoAttributes(); QVERIFY(attributes.contains(QByteArray("favouriteDrink"))); attributes.clear(); - certList = QSslCertificate::fromPath(SRCDIR "more-certificates/natwest-banking.pem"); + certList = QSslCertificate::fromPath(testDataDir + "/more-certificates/natwest-banking.pem"); QVERIFY2(certList.count() > 0, "Please run this test from the source directory"); attributes = certList[0].subjectInfoAttributes(); @@ -917,17 +907,17 @@ void tst_QSslCertificate::verify() errors.clear(); // Verify a valid cert signed by a CA - QList caCerts = QSslCertificate::fromPath(SRCDIR "verify-certs/cacert.pem"); + QList caCerts = QSslCertificate::fromPath(testDataDir + "/verify-certs/cacert.pem"); QSslSocket::addDefaultCaCertificate(caCerts.first()); - toVerify = QSslCertificate::fromPath(SRCDIR "verify-certs/test-ocsp-good-cert.pem"); + toVerify = QSslCertificate::fromPath(testDataDir + "/verify-certs/test-ocsp-good-cert.pem"); errors = QSslCertificate::verify(toVerify); VERIFY_VERBOSE(errors.count() == 0); errors.clear(); // Test a blacklisted certificate - toVerify = QSslCertificate::fromPath(SRCDIR "verify-certs/test-addons-mozilla-org-cert.pem"); + toVerify = QSslCertificate::fromPath(testDataDir + "/verify-certs/test-addons-mozilla-org-cert.pem"); errors = QSslCertificate::verify(toVerify); bool foundBlack = false; foreach (const QSslError &error, errors) { @@ -940,7 +930,7 @@ void tst_QSslCertificate::verify() errors.clear(); // This one is expired and untrusted - toVerify = QSslCertificate::fromPath(SRCDIR "more-certificates/cert-large-serial-number.pem"); + toVerify = QSslCertificate::fromPath(testDataDir + "/more-certificates/cert-large-serial-number.pem"); errors = QSslCertificate::verify(toVerify); VERIFY_VERBOSE(errors.contains(QSslError(QSslError::SelfSignedCertificate, toVerify[0]))); VERIFY_VERBOSE(errors.contains(QSslError(QSslError::CertificateExpired, toVerify[0]))); @@ -948,15 +938,15 @@ void tst_QSslCertificate::verify() toVerify.clear(); // This one is signed by a valid cert, but the signer is not a valid CA - toVerify << QSslCertificate::fromPath(SRCDIR "verify-certs/test-intermediate-not-ca-cert.pem").first(); - toVerify << QSslCertificate::fromPath(SRCDIR "verify-certs/test-ocsp-good-cert.pem").first(); + toVerify << QSslCertificate::fromPath(testDataDir + "/verify-certs/test-intermediate-not-ca-cert.pem").first(); + toVerify << QSslCertificate::fromPath(testDataDir + "/verify-certs/test-ocsp-good-cert.pem").first(); errors = QSslCertificate::verify(toVerify); VERIFY_VERBOSE(errors.contains(QSslError(QSslError::InvalidCaCertificate, toVerify[1]))); toVerify.clear(); // This one is signed by a valid cert, and the signer is a valid CA - toVerify << QSslCertificate::fromPath(SRCDIR "verify-certs/test-intermediate-is-ca-cert.pem").first(); - toVerify << QSslCertificate::fromPath(SRCDIR "verify-certs/test-intermediate-ca-cert.pem").first(); + toVerify << QSslCertificate::fromPath(testDataDir + "/verify-certs/test-intermediate-is-ca-cert.pem").first(); + toVerify << QSslCertificate::fromPath(testDataDir + "/verify-certs/test-intermediate-ca-cert.pem").first(); errors = QSslCertificate::verify(toVerify); VERIFY_VERBOSE(errors.count() == 0); @@ -986,7 +976,7 @@ QString tst_QSslCertificate::toString(const QList& errors) void tst_QSslCertificate::extensions() { QList certList = - QSslCertificate::fromPath(SRCDIR "more-certificates/natwest-banking.pem"); + QSslCertificate::fromPath(testDataDir + "/more-certificates/natwest-banking.pem"); QVERIFY2(certList.count() > 0, "Please run this test from the source directory"); QSslCertificate cert = certList[0]; From 4121f9df29c85d45e0fe128d237c0009cded7574 Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Thu, 16 Feb 2012 08:25:31 +1000 Subject: [PATCH 274/406] Changed qsslkey to work from installation directory - Changed to use TESTDATA and QFINDTESTDATA instead of SRCDIR Change-Id: I30bf175c2c9044e1f8556260a032467ca0dfc09f Reviewed-by: Rohan McGovern Reviewed-by: Jason McDonald --- tests/auto/network/ssl/qsslkey/qsslkey.pro | 21 +-------- .../auto/network/ssl/qsslkey/tst_qsslkey.cpp | 43 +++++-------------- 2 files changed, 12 insertions(+), 52 deletions(-) diff --git a/tests/auto/network/ssl/qsslkey/qsslkey.pro b/tests/auto/network/ssl/qsslkey/qsslkey.pro index 4af35487cd5..d794c0faf06 100644 --- a/tests/auto/network/ssl/qsslkey/qsslkey.pro +++ b/tests/auto/network/ssl/qsslkey/qsslkey.pro @@ -6,23 +6,4 @@ QT = core network testlib TARGET = tst_qsslkey -win32 { - CONFIG(debug, debug|release) { - DESTDIR = debug -} else { - DESTDIR = release - } -} - -wince* { - keyFiles.files = keys - keyFiles.path = . - - passphraseFiles.files = rsa-without-passphrase.pem rsa-with-passphrase.pem - passphraseFiles.path = . - - DEPLOYMENT += keyFiles passphraseFiles - DEFINES += SRCDIR=\\\".\\\" -} else { - DEFINES+= SRCDIR=\\\"$$PWD\\\" -} +TESTDATA += keys/* rsa-without-passphrase.pem rsa-with-passphrase.pem diff --git a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp index 657b91152fe..e8941a2642d 100644 --- a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp +++ b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp @@ -68,14 +68,8 @@ class tst_QSslKey : public QObject void createPlainTestRows(); -public: - tst_QSslKey(); - virtual ~tst_QSslKey(); - public slots: - void initTestCase_data(); - void init(); - void cleanup(); + void initTestCase(); #ifndef QT_NO_OPENSSL @@ -95,16 +89,17 @@ private slots: void passphraseChecks(); #endif +private: + QString testDataDir; }; -tst_QSslKey::tst_QSslKey() +void tst_QSslKey::initTestCase() { -#ifdef Q_OS_MAC - // applicationDirPath() points to a path inside the app bundle on Mac. - QDir dir(qApp->applicationDirPath() + QLatin1String("/../../../keys")); -#else - QDir dir(SRCDIR + QLatin1String("/keys")); // prefer this way to avoid ifdeffery and support shadow builds? -#endif + testDataDir = QFileInfo(QFINDTESTDATA("rsa-without-passphrase.pem")).absolutePath(); + if (testDataDir.isEmpty()) + testDataDir = QCoreApplication::applicationDirPath(); + + QDir dir(testDataDir + "/keys"); QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::Readable); QRegExp rx(QLatin1String("^(rsa|dsa)-(pub|pri)-(\\d+)\\.(pem|der)$")); foreach (QFileInfo fileInfo, fileInfoList) { @@ -118,22 +113,6 @@ tst_QSslKey::tst_QSslKey() } } -tst_QSslKey::~tst_QSslKey() -{ -} - -void tst_QSslKey::initTestCase_data() -{ -} - -void tst_QSslKey::init() -{ -} - -void tst_QSslKey::cleanup() -{ -} - static QByteArray readFile(const QString &absFilePath) { QFile file(absFilePath); @@ -368,7 +347,7 @@ void tst_QSslKey::toEncryptedPemOrDer() void tst_QSslKey::passphraseChecks() { { - QString fileName(SRCDIR "/rsa-with-passphrase.pem"); + QString fileName(testDataDir + "/rsa-with-passphrase.pem"); QFile keyFile(fileName); QVERIFY(keyFile.exists()); { @@ -407,7 +386,7 @@ void tst_QSslKey::passphraseChecks() { // be sure and check a key without passphrase too - QString fileName(SRCDIR "/rsa-without-passphrase.pem"); + QString fileName(testDataDir + "/rsa-without-passphrase.pem"); QFile keyFile(fileName); { if (!keyFile.isOpen()) From 64642a4d9768b767c51c7f92dec94f655ba60195 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Thu, 16 Feb 2012 16:00:41 +1000 Subject: [PATCH 275/406] testlib: Skip test function if init() fails. Prior to this commit, the following statement in the qtestlib documentation was untrue: "If init() fails, the following testfunction will not be executed, the test will proceed to the next testfunction." If init() called QSKIP, the test function would be skipped, but if init() reported a failure, the test function would still be executed (even though doing so could be unsafe). This commit makes testlib skip a test function if init() reports a failure and enhances the selftests to cover skips and fails in both init() and cleanup(). Task-number: QTBUG-20371 Change-Id: Id1cc8464ae0b8c257ae1b74dbe9189a501f5366b Reviewed-by: Rohan McGovern --- src/testlib/qtestcase.cpp | 2 +- .../selftests/counting/tst_counting.cpp | 87 +++++++++++++++++++ .../selftests/expected_counting.lightxml | 80 ++++++++++++++--- .../testlib/selftests/expected_counting.txt | 44 +++++++--- .../testlib/selftests/expected_counting.xml | 80 ++++++++++++++--- .../selftests/expected_counting.xunitxml | 20 ++++- 6 files changed, 274 insertions(+), 39 deletions(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index c084441f5c5..8b9ba6d748c 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1500,7 +1500,7 @@ static void qInvokeTestMethodDataEntry(char *slot) bool invokeOk; do { invokeMethod(QTest::currentTestObject, "init()"); - if (QTestResult::skipCurrentTest()) + if (QTestResult::skipCurrentTest() || QTestResult::currentTestFailed()) break; QBenchmarkTestMethodData::current->result = QBenchmarkResult(); diff --git a/tests/auto/testlib/selftests/counting/tst_counting.cpp b/tests/auto/testlib/selftests/counting/tst_counting.cpp index 6758b533bb7..fa61fce173a 100644 --- a/tests/auto/testlib/selftests/counting/tst_counting.cpp +++ b/tests/auto/testlib/selftests/counting/tst_counting.cpp @@ -47,6 +47,8 @@ class tst_Counting : public QObject Q_OBJECT private slots: + // The following test functions exercise each possible combination of test + // results for two data rows. void testPassPass_data(); void testPassPass(); @@ -74,6 +76,19 @@ private slots: void testFailFail_data(); void testFailFail(); + // The following test functions test skips and fails in the special + // init() and cleanup() slots. + void init(); + void cleanup(); + void testFailInInit_data(); + void testFailInInit(); + void testFailInCleanup_data(); + void testFailInCleanup(); + void testSkipInInit_data(); + void testSkipInInit(); + void testSkipInCleanup_data(); + void testSkipInCleanup(); + private: void helper(); }; @@ -212,5 +227,77 @@ void tst_Counting::testFailFail() helper(); } +void tst_Counting::init() +{ + if (strcmp(QTest::currentTestFunction(), "testFailInInit") == 0 && strcmp(QTest::currentDataTag(), "fail") == 0) + QFAIL("Fail in init()"); + else if (strcmp(QTest::currentTestFunction(), "testSkipInInit") == 0 && strcmp(QTest::currentDataTag(), "skip") == 0) + QSKIP("Skip in init()"); +} + +void tst_Counting::cleanup() +{ + if (strcmp(QTest::currentTestFunction(), "testFailInCleanup") == 0 && strcmp(QTest::currentDataTag(), "fail") == 0) + QFAIL("Fail in cleanup()"); + else if (strcmp(QTest::currentTestFunction(), "testSkipInCleanup") == 0 && strcmp(QTest::currentDataTag(), "skip") == 0) + QSKIP("Skip in cleanup()"); +} + +void tst_Counting::testFailInInit_data() +{ + QTest::addColumn("dummy"); + QTest::newRow("before") << true; + QTest::newRow("fail") << true; + QTest::newRow("after") << true; +} + +void tst_Counting::testFailInInit() +{ + if (strcmp(QTest::currentDataTag(), "fail") == 0) + QFAIL("This test function should have been skipped due to QFAIL in init()"); +} + +void tst_Counting::testFailInCleanup_data() +{ + QTest::addColumn("dummy"); + QTest::newRow("before") << true; + QTest::newRow("fail") << true; + QTest::newRow("after") << true; +} + +void tst_Counting::testFailInCleanup() +{ + if (strcmp(QTest::currentDataTag(), "fail") == 0) + qDebug() << "This test function should execute and then QFAIL in cleanup()"; +} + +void tst_Counting::testSkipInInit_data() +{ + QTest::addColumn("dummy"); + QTest::newRow("before") << true; + QTest::newRow("skip") << true; + QTest::newRow("after") << true; +} + +void tst_Counting::testSkipInInit() +{ + if (strcmp(QTest::currentDataTag(), "skip") == 0) + QFAIL("This test function should have been skipped due to QSKIP in init()"); +} + +void tst_Counting::testSkipInCleanup_data() +{ + QTest::addColumn("dummy"); + QTest::newRow("before") << true; + QTest::newRow("skip") << true; + QTest::newRow("after") << true; +} + +void tst_Counting::testSkipInCleanup() +{ + if (strcmp(QTest::currentDataTag(), "skip") == 0) + qDebug() << "This test function should execute and then QSKIP in cleanup()"; +} + QTEST_MAIN(tst_Counting) #include "tst_counting.moc" diff --git a/tests/auto/testlib/selftests/expected_counting.lightxml b/tests/auto/testlib/selftests/expected_counting.lightxml index fd80292b904..e7b11364176 100644 --- a/tests/auto/testlib/selftests/expected_counting.lightxml +++ b/tests/auto/testlib/selftests/expected_counting.lightxml @@ -17,7 +17,7 @@ - + @@ -26,13 +26,13 @@ - + - + @@ -41,27 +41,27 @@ - + - + - + - + - + @@ -70,25 +70,81 @@ - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_counting.txt b/tests/auto/testlib/selftests/expected_counting.txt index bd70a44b2e8..5c17e3c2577 100644 --- a/tests/auto/testlib/selftests/expected_counting.txt +++ b/tests/auto/testlib/selftests/expected_counting.txt @@ -5,32 +5,50 @@ PASS : tst_Counting::testPassPass(row 1) PASS : tst_Counting::testPassPass(row 2) PASS : tst_Counting::testPassSkip(row 1) SKIP : tst_Counting::testPassSkip(row 2) Skipping - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(102)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(117)] PASS : tst_Counting::testPassFail(row 1) FAIL! : tst_Counting::testPassFail(row 2) 'false' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(99)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(114)] SKIP : tst_Counting::testSkipPass(row 1) Skipping - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(102)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(117)] PASS : tst_Counting::testSkipPass(row 2) SKIP : tst_Counting::testSkipSkip(row 1) Skipping - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(102)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(117)] SKIP : tst_Counting::testSkipSkip(row 2) Skipping - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(102)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(117)] SKIP : tst_Counting::testSkipFail(row 1) Skipping - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(102)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(117)] FAIL! : tst_Counting::testSkipFail(row 2) 'false' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(99)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(114)] FAIL! : tst_Counting::testFailPass(row 1) 'false' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(99)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(114)] PASS : tst_Counting::testFailPass(row 2) FAIL! : tst_Counting::testFailSkip(row 1) 'false' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(99)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(114)] SKIP : tst_Counting::testFailSkip(row 2) Skipping - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(102)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(117)] FAIL! : tst_Counting::testFailFail(row 1) 'false' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(99)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(114)] FAIL! : tst_Counting::testFailFail(row 2) 'false' returned FALSE. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(99)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(114)] +PASS : tst_Counting::testFailInInit(before) +FAIL! : tst_Counting::testFailInInit(fail) Fail in init() + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(233)] +PASS : tst_Counting::testFailInInit(after) +PASS : tst_Counting::testFailInCleanup(before) +QDEBUG : tst_Counting::testFailInCleanup(fail) This test function should execute and then QFAIL in cleanup() +FAIL! : tst_Counting::testFailInCleanup(fail) Fail in cleanup() + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(241)] +PASS : tst_Counting::testFailInCleanup(after) +PASS : tst_Counting::testSkipInInit(before) +SKIP : tst_Counting::testSkipInInit(skip) Skip in init() + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(235)] +PASS : tst_Counting::testSkipInInit(after) +PASS : tst_Counting::testSkipInCleanup(before) +QDEBUG : tst_Counting::testSkipInCleanup(skip) This test function should execute and then QSKIP in cleanup() +SKIP : tst_Counting::testSkipInCleanup(skip) Skip in cleanup() + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(243)] +PASS : tst_Counting::testSkipInCleanup(after) PASS : tst_Counting::cleanupTestCase() -Totals: 8 passed, 6 failed, 6 skipped +Totals: 16 passed, 8 failed, 8 skipped ********* Finished testing of tst_Counting ********* diff --git a/tests/auto/testlib/selftests/expected_counting.xml b/tests/auto/testlib/selftests/expected_counting.xml index c5460a73466..a97296807dd 100644 --- a/tests/auto/testlib/selftests/expected_counting.xml +++ b/tests/auto/testlib/selftests/expected_counting.xml @@ -19,7 +19,7 @@ - + @@ -28,13 +28,13 @@ - + - + @@ -43,27 +43,27 @@ - + - + - + - + - + @@ -72,25 +72,81 @@ - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_counting.xunitxml b/tests/auto/testlib/selftests/expected_counting.xunitxml index 496546700ef..f317ed59230 100644 --- a/tests/auto/testlib/selftests/expected_counting.xunitxml +++ b/tests/auto/testlib/selftests/expected_counting.xunitxml @@ -1,5 +1,5 @@ - + @@ -34,6 +34,20 @@ + + + + + + + + + + + + + + @@ -42,5 +56,9 @@ + + + + From 2193df65a380e27b839bae3dc63ad7496af575e8 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Tue, 14 Feb 2012 07:03:18 +0100 Subject: [PATCH 276/406] Fix tst_QFileSystemWatcher failure on Mac OS X The watchFileAndItsDirectory() test would fail due to atime updates for the first watched file coming up to 2 seconds after the file was closed. Observation shows that the atime has a 2 second resolution on Mac OS X using HFS+, so add an appropriate delay to make sure that the atime update from the kqueue based file system watcher can dispatch all updates. Task-number: QTBUG-22744 Change-Id: Ie79af20d6b4c154021307c8a8f6d336369720337 Reviewed-by: Robin Burchell --- .../corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro | 2 -- .../corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp | 5 +++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro b/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro index e712a6ad5f5..8ada44fdf75 100644 --- a/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro +++ b/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro @@ -2,5 +2,3 @@ CONFIG += testcase parallel_test TARGET = tst_qfilesystemwatcher QT = core testlib SOURCES = tst_qfilesystemwatcher.cpp - -mac: CONFIG += insignificant_test # QTBUG-22744 diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index 2635565c2b6..8caccb6da9d 100644 --- a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp @@ -432,6 +432,11 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory() testFile.write(QByteArray("hello again")); testFile.close(); +#ifdef Q_OS_MAC + // wait again for the file's atime to be updated + QTest::qWait(2000); +#endif + QTRY_VERIFY(fileChangedSpy.count() > 0); //according to Qt 4 documentation: From b838170cebc8d1adefc6c8de34e6a39494ffd75e Mon Sep 17 00:00:00 2001 From: David Faure Date: Sun, 12 Feb 2012 01:39:47 +0100 Subject: [PATCH 277/406] QDebug: Add support for %{pid}, %{appname} and %{threadid} Change-Id: I4add0a374e6524b615c6dc0ecfb010a90075b04f Reviewed-by: Kai Koehne Reviewed-by: Thiago Macieira --- src/corelib/global/qlogging.cpp | 23 ++++++++++++++++++- .../auto/corelib/global/qlogging/app/main.cpp | 7 ++++-- .../corelib/global/qlogging/tst_qlogging.cpp | 10 ++++---- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 8a75f5a9eaf..77c147bc54b 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -45,6 +45,10 @@ #include "qstring.h" #include "qvarlengtharray.h" #include "qdebug.h" +#ifndef QT_BOOTSTRAPPED +#include "qcoreapplication.h" +#include "qthread.h" +#endif #include @@ -489,6 +493,9 @@ static const char messageTokenC[] = "%{message}"; static const char fileTokenC[] = "%{file}"; static const char lineTokenC[] = "%{line}"; static const char functionTokenC[] = "%{function}"; +static const char pidTokenC[] = "%{pid}"; +static const char appnameTokenC[] = "%{appname}"; +static const char threadidTokenC[] = "%{threadid}"; static const char emptyTokenC[] = ""; struct QMessagePattern { @@ -558,6 +565,12 @@ QMessagePattern::QMessagePattern() tokens[i] = lineTokenC; else if (lexeme == QLatin1String(functionTokenC)) tokens[i] = functionTokenC; + else if (lexeme == QLatin1String(pidTokenC)) + tokens[i] = pidTokenC; + else if (lexeme == QLatin1String(appnameTokenC)) + tokens[i] = appnameTokenC; + else if (lexeme == QLatin1String(threadidTokenC)) + tokens[i] = threadidTokenC; else { fprintf(stderr, "%s\n", QString::fromLatin1("QT_MESSAGE_PATTERN: Unknown placeholder %1\n" @@ -624,12 +637,20 @@ Q_CORE_EXPORT QByteArray qMessageFormatString(QtMsgType type, const QMessageLogC else message.append("unknown"); } else if (token == lineTokenC) { - message.append(QString::number(context.line).toLatin1().constData()); + message.append(QByteArray::number(context.line)); } else if (token == functionTokenC) { if (context.function) message.append(qCleanupFuncinfo(context.function)); else message.append("unknown"); +#ifndef QT_BOOTSTRAPPED + } else if (token == pidTokenC) { + message.append(QByteArray::number(QCoreApplication::applicationPid())); + } else if (token == appnameTokenC) { + message.append(QCoreApplication::applicationName().toUtf8().constData()); + } else if (token == threadidTokenC) { + message.append("0x" + QByteArray::number(qlonglong(QThread::currentThread()->currentThread()), 16)); +#endif } else { message.append(token); } diff --git a/tests/auto/corelib/global/qlogging/app/main.cpp b/tests/auto/corelib/global/qlogging/app/main.cpp index c26b29ea560..dfa52315c7f 100644 --- a/tests/auto/corelib/global/qlogging/app/main.cpp +++ b/tests/auto/corelib/global/qlogging/app/main.cpp @@ -39,15 +39,18 @@ ** ****************************************************************************/ -#include +#include struct T { T() { qDebug("static constructor"); } ~T() { qDebug("static destructor"); } } t; -int main(int, char **) +int main(int argc, char **argv) { + QCoreApplication app(argc, argv); + app.setApplicationName("tst_qlogging"); + qDebug("qDebug"); qWarning("qWarning"); qCritical("qCritical"); diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp index b2935ea6f2c..11949cf1db2 100644 --- a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp +++ b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp @@ -620,7 +620,7 @@ void tst_qmessagehandler::qMessagePattern() QStringList environment = QProcess::systemEnvironment(); // %{file} is tricky because of shadow builds - environment.prepend("QT_MESSAGE_PATTERN=\"%{type} %{line} %{function} %{message}\""); + environment.prepend("QT_MESSAGE_PATTERN=\"%{type} %{appname} %{line} %{function} %{message}\""); process.setEnvironment(environment); #ifdef Q_OS_WIN process.start("app/app.exe"); @@ -633,12 +633,12 @@ void tst_qmessagehandler::qMessagePattern() // qDebug() << output; QVERIFY(!output.isEmpty()); - QVERIFY(output.contains("debug 45 T::T static constructor")); + QVERIFY(output.contains("debug 45 T::T static constructor")); // we can't be sure whether the QT_MESSAGE_PATTERN is already destructed QVERIFY(output.contains("static destructor")); - QVERIFY(output.contains("debug 51 main qDebug")); - QVERIFY(output.contains("warning 52 main qWarning")); - QVERIFY(output.contains("critical 53 main qCritical")); + QVERIFY(output.contains("debug tst_qlogging 54 main qDebug")); + QVERIFY(output.contains("warning tst_qlogging 55 main qWarning")); + QVERIFY(output.contains("critical tst_qlogging 56 main qCritical")); environment = QProcess::systemEnvironment(); environment.prepend("QT_MESSAGE_PATTERN=\"PREFIX: %{unknown} %{message}\""); From 543d994967628f580eb34d4d0241846eaef3bd7d Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 16 Feb 2012 12:27:46 +0200 Subject: [PATCH 278/406] Fix QWindowsClipboard crash when mimeData is NULL. When setting NULL mimeData in QWindowsClipboard::setMimeData, and the OleSetClipboard call failed, the warning print crashed because it tried to access mimeData. Task-number: QTBUG-24327 Change-Id: I1f56fd28c9191a330e14a93b4b11ac9c89db6985 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowsclipboard.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp index 521ca3dc074..c1167ccf3a4 100644 --- a/src/plugins/platforms/windows/qwindowsclipboard.cpp +++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp @@ -326,13 +326,16 @@ void QWindowsClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode) const bool newData = !m_data || m_data->mimeData() != mimeData; if (newData) { releaseIData(); - m_data = new QWindowsOleDataObject(mimeData); + if (mimeData) + m_data = new QWindowsOleDataObject(mimeData); } const HRESULT src = OleSetClipboard(m_data); if (src != S_OK) { + QString mimeDataFormats = mimeData ? + mimeData->formats().join(QStringLiteral(", ")) : QString(QStringLiteral("NULL")); qErrnoWarning("OleSetClipboard: Failed to set mime data (%s) on clipboard: %s", - qPrintable(mimeData->formats().join(QStringLiteral(", "))), + qPrintable(mimeDataFormats), QWindowsContext::comErrorString(src).constData()); releaseIData(); return; From 4212898822f1798dac0167e4f6a147bd8a3b3dcc Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 16 Feb 2012 12:24:32 +0100 Subject: [PATCH 279/406] Base active window handling on WM_SET/KILLFOCUS. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make it work for child windows, fixing the isActive() test of QWindow. Task-number: QTBUG-24185 Change-Id: I75597c2d322969f7e109d76e30b9b1f4b66c6e1e Reviewed-by: Samuel Rødal --- src/plugins/platforms/windows/qtwindowsglobal.h | 6 ++++++ src/plugins/platforms/windows/qwindowscontext.cpp | 9 ++++----- src/plugins/platforms/windows/qwindowswindow.cpp | 6 +++++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h index f0443622993..3445a3c7a89 100644 --- a/src/plugins/platforms/windows/qtwindowsglobal.h +++ b/src/plugins/platforms/windows/qtwindowsglobal.h @@ -77,6 +77,8 @@ enum WindowsEventType // Simplify event types ResizeEvent = WindowEventFlag + 12, QuerySizeHints = WindowEventFlag + 15, CalculateSize = WindowEventFlag + 16, + FocusInEvent = WindowEventFlag + 17, + FocusOutEvent = WindowEventFlag + 18, MouseEvent = MouseEventFlag + 1, MouseWheelEvent = MouseEventFlag + 2, TouchEvent = TouchEventFlag + 1, @@ -170,6 +172,10 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI } case WM_GETOBJECT: return QtWindows::AccessibleObjectFromWindowRequest; + case WM_SETFOCUS: + return QtWindows::FocusInEvent; + case WM_KILLFOCUS: + return QtWindows::FocusOutEvent; case WM_DISPLAYCHANGE: return QtWindows::DisplayChangedEvent; default: diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 5f7dfb1b10e..a257736d986 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -676,10 +676,6 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, } // Events without an associated QWindow or events we are not interested in. switch (et) { - case QtWindows::DeactivateApplicationEvent: - case QtWindows::DeactivateWindowEvent: - QWindowSystemInterface::handleWindowActivated(0); - return true; case QtWindows::InputMethodStartCompositionEvent: return QWindowsInputContext::instance()->startComposition(hwnd); case QtWindows::InputMethodCompositionEvent: @@ -773,9 +769,12 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, return d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); case QtWindows::TouchEvent: return d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result); - case QtWindows::ActivateWindowEvent: + case QtWindows::FocusInEvent: // see QWindowsWindow::requestActivateWindow(). QWindowSystemInterface::handleWindowActivated(platformWindow->window()); return true; + case QtWindows::FocusOutEvent: + QWindowSystemInterface::handleWindowActivated(0); + return true; case QtWindows::ShowEvent: platformWindow->handleShown(); return true; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 5d8de2e01d7..28ef2c3b6ca 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1220,8 +1220,12 @@ void QWindowsWindow::requestActivateWindow() { if (QWindowsContext::verboseWindows) qDebug() << __FUNCTION__ << this << window(); - if (m_data.hwnd) + // 'Active' state handling is based in focus since it needs to work for + // child windows as well. + if (m_data.hwnd) { SetForegroundWindow(m_data.hwnd); + SetFocus(m_data.hwnd); + } } bool QWindowsWindow::setKeyboardGrabEnabled(bool grab) From 2801db558c56e98753e297c1aeabd4fd2975e09a Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 15 Feb 2012 15:06:00 +0100 Subject: [PATCH 280/406] Avoid loading and keeping unused fallback font engines When we request glyphs from fallback fonts, we would potentially load all fonts on the system into memory. This is especially true for glyphs that are not supported by any font (or by the last in the list) in any "Common" script (which e.g. includes CJK). This would make any application which tried to display unsupported glyphs use huge amounts of memory for keeping unused fonts cached, only limited by the number of fonts on the system. The patch contains two solutions: First, before loading the font, the multi font engine will be asked whether it needs to be tried for the given character. By default, this will always be true, so all fonts will be tried, but with the new font config multi engine in the platform plugin, it will ask FontConfig whether the font contains a glyph for the character. Should the font be loaded and still fail to resolve the character (which could be the case for other platforms), we will simply delete it again immediately instead keeping it cached. Change-Id: I92dfb39289a359f49caa02c2caf8baf66098fb59 Reviewed-by: Lars Knoll --- src/gui/text/qfont.cpp | 14 +++ src/gui/text/qfont_p.h | 1 + src/gui/text/qfontdatabase_qpa.cpp | 3 +- src/gui/text/qfontengine.cpp | 37 +++++++- src/gui/text/qfontengine_ft_p.h | 1 + src/gui/text/qfontengine_p.h | 3 + src/gui/text/qfontengine_qpa_p.h | 5 +- src/gui/text/qplatformfontdatabase_qpa.cpp | 12 +++ src/gui/text/qplatformfontdatabase_qpa.h | 2 + .../fontdatabases/fontconfig/fontconfig.pri | 6 +- .../fontconfig/qfontconfigdatabase.cpp | 11 ++- .../fontconfig/qfontconfigdatabase_p.h | 1 + .../fontconfig/qfontenginemultifontconfig.cpp | 87 +++++++++++++++++++ .../fontconfig/qfontenginemultifontconfig_p.h | 60 +++++++++++++ 14 files changed, 235 insertions(+), 8 deletions(-) create mode 100644 src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp create mode 100644 src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig_p.h diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index a347c626294..ee833a06cfa 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -2729,6 +2729,20 @@ QFontEngine *QFontCache::findEngine(const Key &key) return it.value().data; } +void QFontCache::removeEngine(QFontEngine *engine) +{ + EngineCache::iterator it = engineCache.begin(); + while (it != engineCache.end()) { + if (it.value().data == engine) { + it = engineCache.erase(it); + if (--engine->cache_count == 0) + decreaseCost(engine->cache_cost); + } else { + ++it; + } + } +} + void QFontCache::insertEngine(const Key &key, QFontEngine *engine) { FC_DEBUG("QFontCache: inserting new engine %p", engine); diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h index e26a98aaf24..d10249201ab 100644 --- a/src/gui/text/qfont_p.h +++ b/src/gui/text/qfont_p.h @@ -243,6 +243,7 @@ public: QFontEngine *findEngine(const Key &key); void insertEngine(const Key &key, QFontEngine *engine); + void removeEngine(QFontEngine *engine); private: diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp index 2a9c37fb137..1a1f08f73d4 100644 --- a/src/gui/text/qfontdatabase_qpa.cpp +++ b/src/gui/text/qfontdatabase_qpa.cpp @@ -206,7 +206,8 @@ QFontEngine *loadEngine(int script, const QFontDef &request, if (family && !family->fallbackFamilies.isEmpty()) fallbacks = family->fallbackFamilies; - engine = new QFontEngineMultiQPA(engine, script, fallbacks); + QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase(); + engine = pfdb->fontEngineMulti(engine, QUnicodeTables::Script(script), fallbacks); // Cache Multi font engine as well in case we got the FT single // font engine when we are actually looking for a Multi one diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 156a4a1e591..a084a3dd8cf 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1379,18 +1379,24 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len, int glyph_pos = 0; for (int i = 0; i < len; ++i) { bool surrogate = (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()); - + uint ucs4 = surrogate ? QChar::surrogateToUcs4(str[i], str[i+1]) : str[i].unicode(); if (glyphs->glyphs[glyph_pos] == 0 && str[i].category() != QChar::Separator_Line) { QGlyphLayoutInstance tmp = glyphs->instance(glyph_pos); - for (int x = 1; x < engines.size(); ++x) { + for (int x=1; x < engines.size(); ++x) { + if (!shouldLoadFontEngineForCharacter(x, ucs4)) + continue; + QFontEngine *engine = engines.at(x); + bool deleteThisEngine = false; if (!engine) { const_cast(this)->loadEngine(x); engine = engines.at(x); + deleteThisEngine = true; } Q_ASSERT(engine != 0); if (engine->type() == Box) continue; + glyphs->advances_x[glyph_pos] = glyphs->advances_y[glyph_pos] = 0; glyphs->offsets[glyph_pos] = QFixedPoint(); int num = 2; @@ -1401,13 +1407,17 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len, // set the high byte to indicate which engine the glyph came from glyphs->glyphs[glyph_pos] |= (x << 24); break; + } else if (deleteThisEngine) { + const_cast(this)->unloadEngine(x); } } + // ensure we use metrics from the 1st font when we use the fallback image. if (!glyphs->glyphs[glyph_pos]) { glyphs->setInstance(glyph_pos, tmp); } } + if (surrogate) ++i; ++glyph_pos; @@ -1418,6 +1428,29 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len, return true; } +bool QFontEngineMulti::shouldLoadFontEngineForCharacter(int at, uint ucs4) const +{ + Q_UNUSED(at); + Q_UNUSED(ucs4); + return true; +} + +void QFontEngineMulti::unloadEngine(int at) +{ + QFontEngine *fontEngine = engines.at(at); + if (fontEngine == 0) + return; + + // If there are other references to the engine, keep it around and keep the reference + if (fontEngine->ref.load() == 1) { + QFontCache::instance()->removeEngine(fontEngine); + if (fontEngine->cache_count == 0) { + delete fontEngine; + engines[at] = 0; + } + } +} + glyph_metrics_t QFontEngineMulti::boundingBox(const QGlyphLayout &glyphs) { if (glyphs.numGlyphs <= 0) diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index a9e67c10e8a..83b51685c03 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -328,6 +328,7 @@ protected: private: friend class QFontEngineFTRawFont; friend class QFontconfigDatabase; + friend class QFontEngineMultiFontConfig; int loadFlags(QGlyphSet *set, GlyphFormat format, int flags, bool &hsubpixel, int &vfactor) const; diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index c0bd1afb80c..023882d5600 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -392,11 +392,14 @@ public: loadEngine(at); } + virtual bool shouldLoadFontEngineForCharacter(int at, uint ucs4) const; + protected: friend class QPSPrintEnginePrivate; friend class QPSPrintEngineFontMulti; friend class QRawFont; virtual void loadEngine(int at) = 0; + virtual void unloadEngine(int at); QVector engines; }; diff --git a/src/gui/text/qfontengine_qpa_p.h b/src/gui/text/qfontengine_qpa_p.h index 6a73b9d3096..ed2e071ac2a 100644 --- a/src/gui/text/qfontengine_qpa_p.h +++ b/src/gui/text/qfontengine_qpa_p.h @@ -243,13 +243,16 @@ struct QPAGenerator QFontEngine *fe; }; -class QFontEngineMultiQPA : public QFontEngineMulti +class Q_GUI_EXPORT QFontEngineMultiQPA : public QFontEngineMulti { public: QFontEngineMultiQPA(QFontEngine *fe, int script, const QStringList &fallbacks); void loadEngine(int at); + int fallbackFamilyCount() const { return fallbackFamilies.size(); } + QString fallbackFamilyAt(int at) const { return fallbackFamilies.at(at); } + private: QStringList fallbackFamilies; int script; diff --git a/src/gui/text/qplatformfontdatabase_qpa.cpp b/src/gui/text/qplatformfontdatabase_qpa.cpp index f9cc97cbc7a..8fcf4213306 100644 --- a/src/gui/text/qplatformfontdatabase_qpa.cpp +++ b/src/gui/text/qplatformfontdatabase_qpa.cpp @@ -270,6 +270,18 @@ void QPlatformFontDatabase::populateFontDatabase() } } +/*! + Returns a multi font engine in the specified \a script to encapsulate \a fontEngine with the + option to fall back to to the fonts given by \a fallbacks if \a fontEngine does not support + a certain character. +*/ +QFontEngineMulti *QPlatformFontDatabase::fontEngineMulti(QFontEngine *fontEngine, + QUnicodeTables::Script script, + const QStringList &fallbacks) +{ + return new QFontEngineMultiQPA(fontEngine, script, fallbacks); +} + /*! Returns the font engine that can be used to render the font described by the font definition, \a fontDef, in the specified \a script. diff --git a/src/gui/text/qplatformfontdatabase_qpa.h b/src/gui/text/qplatformfontdatabase_qpa.h index 151442c5e15..6a58a3106ce 100644 --- a/src/gui/text/qplatformfontdatabase_qpa.h +++ b/src/gui/text/qplatformfontdatabase_qpa.h @@ -82,12 +82,14 @@ Q_GUI_EXPORT bool operator==(const QSupportedWritingSystems &, const QSupportedW Q_GUI_EXPORT bool operator!=(const QSupportedWritingSystems &, const QSupportedWritingSystems &); class QFontRequestPrivate; +class QFontEngineMulti; class Q_GUI_EXPORT QPlatformFontDatabase { public: virtual ~QPlatformFontDatabase(); virtual void populateFontDatabase(); + virtual QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QUnicodeTables::Script script, const QStringList &fallbacks); virtual QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle); virtual QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const; virtual QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName); diff --git a/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri b/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri index 7ea1c64e33c..2c896ef2cc7 100644 --- a/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri +++ b/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri @@ -1,3 +1,5 @@ -HEADERS += $$PWD/qfontconfigdatabase_p.h -SOURCES += $$PWD/qfontconfigdatabase.cpp +HEADERS += $$PWD/qfontconfigdatabase_p.h \ + fontdatabases/fontconfig/qfontenginemultifontconfig_p.h +SOURCES += $$PWD/qfontconfigdatabase.cpp \ + fontdatabases/fontconfig/qfontenginemultifontconfig.cpp DEFINES -= QT_NO_FONTCONFIG diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index f048ed91de1..8a9670118fe 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qfontconfigdatabase_p.h" +#include "qfontenginemultifontconfig_p.h" #include #include @@ -50,8 +51,7 @@ #include #include - - +#include #include #include FT_TRUETYPE_TABLES_H @@ -471,6 +471,13 @@ void QFontconfigDatabase::populateFontDatabase() // QApplication::setFont(font); } +QFontEngineMulti *QFontconfigDatabase::fontEngineMulti(QFontEngine *fontEngine, + QUnicodeTables::Script script, + const QStringList &fallbacks) +{ + return new QFontEngineMultiFontConfig(fontEngine, script, fallbacks); +} + QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QUnicodeTables::Script script, void *usrPtr) { if (!usrPtr) diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h index 77509f76e52..d4742167e9f 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h @@ -51,6 +51,7 @@ class QFontconfigDatabase : public QBasicFontDatabase { public: void populateFontDatabase(); + QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QUnicodeTables::Script script, const QStringList &fallbacks); QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle); QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const; QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName); diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp new file mode 100644 index 00000000000..7b28b20bcbe --- /dev/null +++ b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins 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 "qfontenginemultifontconfig_p.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +QFontEngineMultiFontConfig::QFontEngineMultiFontConfig(QFontEngine *fe, int script, + const QStringList &fallbacks) + : QFontEngineMultiQPA(fe, script, fallbacks) +{ +} + +bool QFontEngineMultiFontConfig::shouldLoadFontEngineForCharacter(int at, uint ucs4) const +{ + QFontEngineFT *fontEngine = static_cast(engines.at(at)); + bool charSetHasChar = true; + if (fontEngine != 0) { + FcCharSet *charSet = fontEngine->freetype->charset; + charSetHasChar = FcCharSetHasChar(charSet, ucs4); + } else { + FcPattern *requestPattern = FcPatternCreate(); + + FcValue value; + value.type = FcTypeString; + QByteArray cs = fallbackFamilyAt(at-1).toUtf8(); + value.u.s = reinterpret_cast(cs.data()); + FcPatternAdd(requestPattern, FC_FAMILY, value, true); + + FcResult result; + FcPattern *matchPattern = FcFontMatch(0, requestPattern, &result); + if (matchPattern != 0) { + FcCharSet *charSet; + FcPatternGetCharSet(matchPattern, FC_CHARSET, 0, &charSet); + charSetHasChar = FcCharSetHasChar(charSet, ucs4); + FcPatternDestroy(matchPattern); + } + + FcPatternDestroy(requestPattern); + } + + return charSetHasChar; +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig_p.h b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig_p.h new file mode 100644 index 00000000000..4323cb7d2ec --- /dev/null +++ b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig_p.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins 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 QFONTENGINEMULTIFONTCONFIG_H +#define QFONTENGINEMULTIFONTCONFIG_H + +#include + +QT_BEGIN_NAMESPACE + +class QFontEngineMultiFontConfig : public QFontEngineMultiQPA +{ + Q_OBJECT +public: + explicit QFontEngineMultiFontConfig(QFontEngine *fe, int script, const QStringList &fallbacks); + + bool shouldLoadFontEngineForCharacter(int at, uint ucs4) const; +}; + +QT_END_NAMESPACE + +#endif // QFONTENGINEMULTIFONTCONFIG_H From cb8445f0323b0eefbb04f1d8adad81a00b53abd8 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 3 Feb 2012 14:28:16 +0100 Subject: [PATCH 281/406] Remove historical +1 from font height calculation Historically, we've calculated font height as ascent+descent+1. In Qt 4, a patch was added to work around this by subtracting 1 from the descent of the font engines. We now remove the +1 and the work arounds. Change-Id: I7e25d49b97ac892015d3328f32d70eb9a7c2d88f Reviewed-by: Friedemann Kleint Reviewed-by: Lars Knoll --- src/gui/text/qabstracttextdocumentlayout.cpp | 2 +- src/gui/text/qfontengine_ft.cpp | 5 ++--- src/gui/text/qfontenginedirectwrite.cpp | 4 ++-- src/gui/text/qfontmetrics.cpp | 8 ++++---- src/gui/text/qtextengine_p.h | 4 ++-- src/gui/text/qtextlayout.cpp | 4 ++-- .../fontdatabases/mac/qfontengine_coretext.mm | 4 +--- src/plugins/platforms/windows/qwindowsfontengine.cpp | 4 +--- tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp | 4 ++-- tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp | 10 +++++----- 10 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/gui/text/qabstracttextdocumentlayout.cpp b/src/gui/text/qabstracttextdocumentlayout.cpp index 2c22b728468..7bf2a631ea7 100644 --- a/src/gui/text/qabstracttextdocumentlayout.cpp +++ b/src/gui/text/qabstracttextdocumentlayout.cpp @@ -469,7 +469,7 @@ void QAbstractTextDocumentLayout::resizeInlineObject(QTextInlineObject item, int QSizeF s = handler.iface->intrinsicSize(document(), posInDocument, format); item.setWidth(s.width()); - item.setAscent(s.height() - 1); + item.setAscent(s.height()); item.setDescent(0); } diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index c9eadd386ee..8880eb7cb36 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1173,8 +1173,7 @@ QFixed QFontEngineFT::ascent() const QFixed QFontEngineFT::descent() const { - // subtract a pixel to work around QFontMetrics's built-in + 1 - return QFixed::fromFixed(-metrics.descender - 64); + return QFixed::fromFixed(-metrics.descender); } QFixed QFontEngineFT::leading() const @@ -1589,7 +1588,7 @@ glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout &glyphs) glyph_metrics_t overall; // initialize with line height, we get the same behaviour on all platforms overall.y = -ascent(); - overall.height = ascent() + descent() + 1; + overall.height = ascent() + descent(); QFixed ymax = 0; QFixed xmax = 0; diff --git a/src/gui/text/qfontenginedirectwrite.cpp b/src/gui/text/qfontenginedirectwrite.cpp index afbc41daeb9..0f21ae8a1ea 100644 --- a/src/gui/text/qfontenginedirectwrite.cpp +++ b/src/gui/text/qfontenginedirectwrite.cpp @@ -484,8 +484,8 @@ QFixed QFontEngineDirectWrite::ascent() const QFixed QFontEngineDirectWrite::descent() const { return fontDef.styleStrategy & QFont::ForceIntegerMetrics - ? (m_descent - 1).round() - : (m_descent - 1); + ? (m_descent).round() + : (m_descent); } QFixed QFontEngineDirectWrite::leading() const diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index a2f0dd724af..283494e316b 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -288,7 +288,7 @@ int QFontMetrics::height() const { QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); - return qRound(engine->ascent()) + qRound(engine->descent()) + 1; + return qRound(engine->ascent()) + qRound(engine->descent()); } /*! @@ -316,7 +316,7 @@ int QFontMetrics::lineSpacing() const { QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); - return qRound(engine->leading()) + qRound(engine->ascent()) + qRound(engine->descent()) + 1; + return qRound(engine->leading()) + qRound(engine->ascent()) + qRound(engine->descent()); } /*! @@ -1147,7 +1147,7 @@ qreal QFontMetricsF::height() const QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); - return (engine->ascent() + engine->descent() + 1).toReal(); + return (engine->ascent() + engine->descent()).toReal(); } /*! @@ -1175,7 +1175,7 @@ qreal QFontMetricsF::lineSpacing() const { QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); - return (engine->leading() + engine->ascent() + engine->descent() + 1).toReal(); + return (engine->leading() + engine->ascent() + engine->descent()).toReal(); } /*! diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 53031cfcee3..b29f626b68f 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -366,7 +366,7 @@ struct Q_AUTOTEST_EXPORT QScriptItem QFixed leading; QFixed width; int glyph_data_offset; - QFixed height() const { return ascent + descent + 1; } + QFixed height() const { return ascent + descent; } }; @@ -396,7 +396,7 @@ struct Q_AUTOTEST_EXPORT QScriptLine mutable uint gridfitted : 1; uint hasTrailingSpaces : 1; uint leadingIncluded : 1; - QFixed height() const { return (ascent + descent).ceil() + 1 + QFixed height() const { return (ascent + descent).ceil() + (leadingIncluded? qMax(QFixed(),leading) : QFixed()); } QFixed base() const { return ascent + (leadingIncluded ? qMax(QFixed(),leading) : QFixed()); } diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 84d3fce518e..943caea6449 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1429,9 +1429,9 @@ qreal QTextLine::descent() const } /*! - Returns the line's height. This is equal to ascent() + descent() + 1 + Returns the line's height. This is equal to ascent() + descent() if leading is not included. If leading is included, this equals to - ascent() + descent() + leading() + 1. + ascent() + descent() + leading(). \sa ascent(), descent(), leading(), setLeadingIncluded() */ diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 489138abaed..a51ffb77eaf 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -255,9 +255,7 @@ QFixed QCoreTextFontEngine::descent() const if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) d = d.round(); - // subtract a pixel to even out the historical +1 in QFontMetrics::height(). - // Fix in Qt 5. - return d - 1; + return d; } QFixed QCoreTextFontEngine::leading() const { diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index ffa57ad58f5..007f6d597a5 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -517,9 +517,7 @@ QFixed QWindowsFontEngine::ascent() const QFixed QWindowsFontEngine::descent() const { - // ### we subtract 1 to even out the historical +1 in QFontMetrics' - // ### height=asc+desc+1 equation. Fix in Qt5. - return tm.tmDescent - 1; + return tm.tmDescent; } QFixed QWindowsFontEngine::leading() const diff --git a/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp index 0b5486dd5ad..4dbdf9a4f17 100644 --- a/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp +++ b/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp @@ -140,7 +140,7 @@ void tst_QFontMetrics::metrics() font = fdb.font(family, style, 12); QFontMetrics fontmetrics(font); - QCOMPARE(fontmetrics.ascent() + fontmetrics.descent() + 1, + QCOMPARE(fontmetrics.ascent() + fontmetrics.descent(), fontmetrics.height()); QCOMPARE(fontmetrics.height() + fontmetrics.leading(), @@ -156,7 +156,7 @@ void tst_QFontMetrics::metrics() font = fdb.font(family, style, size); QFontMetrics fontmetrics(font); - QCOMPARE(fontmetrics.ascent() + fontmetrics.descent() + 1, + QCOMPARE(fontmetrics.ascent() + fontmetrics.descent(), fontmetrics.height()); QCOMPARE(fontmetrics.height() + fontmetrics.leading(), fontmetrics.lineSpacing()); diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp index e7435743e5f..8920e639575 100644 --- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp @@ -352,7 +352,7 @@ void tst_QTextLayout::threeLineBoundingRect() QCOMPARE(qRound(line.naturalTextWidth()), thirdLineWidth); y += qRound(line.ascent() + line.descent()); - QCOMPARE(layout.boundingRect(), QRectF(0, 0, longestLine, y + 1)); + QCOMPARE(layout.boundingRect(), QRectF(0, 0, longestLine, y)); } void tst_QTextLayout::boundingRectWithLongLineAndNoWrap() @@ -386,7 +386,7 @@ void tst_QTextLayout::forcedBreaks() QCOMPARE(line.textStart(), pos); QCOMPARE(line.textLength(),2); QCOMPARE(qRound(line.naturalTextWidth()),testFont.pixelSize()); - QCOMPARE((int) line.height(), testFont.pixelSize() + 1); // + 1 baseline + QCOMPARE((int) line.height(), testFont.pixelSize()); QCOMPARE(line.xToCursor(0), line.textStart()); pos += line.textLength(); @@ -395,7 +395,7 @@ void tst_QTextLayout::forcedBreaks() QCOMPARE(line.textStart(),pos); QCOMPARE(line.textLength(),1); QCOMPARE(qRound(line.naturalTextWidth()), 0); - QCOMPARE((int) line.height(), testFont.pixelSize() + 1); // + 1 baseline + QCOMPARE((int) line.height(), testFont.pixelSize()); QCOMPARE(line.xToCursor(0), line.textStart()); pos += line.textLength(); @@ -404,7 +404,7 @@ void tst_QTextLayout::forcedBreaks() QCOMPARE(line.textStart(),pos); QCOMPARE(line.textLength(),2); QCOMPARE(qRound(line.naturalTextWidth()),testFont.pixelSize()); - QCOMPARE(qRound(line.height()), testFont.pixelSize() + 1); // + 1 baseline + QCOMPARE(qRound(line.height()), testFont.pixelSize()); QCOMPARE(line.xToCursor(0), line.textStart()); pos += line.textLength(); @@ -413,7 +413,7 @@ void tst_QTextLayout::forcedBreaks() QCOMPARE(line.textStart(),pos); QCOMPARE(line.textLength(),1); QCOMPARE(qRound(line.naturalTextWidth()), testFont.pixelSize()); - QCOMPARE((int) line.height(), testFont.pixelSize() + 1); // + 1 baseline + QCOMPARE((int) line.height(), testFont.pixelSize()); QCOMPARE(line.xToCursor(0), line.textStart()); } From 1209fccaf7c78f46f7d30cf729ed34e12e295e62 Mon Sep 17 00:00:00 2001 From: David Faure Date: Sat, 11 Feb 2012 02:13:22 +0100 Subject: [PATCH 282/406] QMimeData: export URLs as text too This allows to drop or paste them into lineedits and text widgets (including such widgets in non-Qt applications) Implementation note: this is done on-demand rather than in setUrls so that it's still possible to setText explicitely; the new code is only a fallback for when no text/plain data is available. Change-Id: Ie90c43a30bfa64a6047b627e7351d20bf5ec8e03 Reviewed-by: Lars Knoll --- src/corelib/kernel/qmimedata.cpp | 28 ++++++++++++++++++- .../kernel/qmimedata/tst_qmimedata.cpp | 7 +++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp index 25e2b3532b8..cfe985da26e 100644 --- a/src/corelib/kernel/qmimedata.cpp +++ b/src/corelib/kernel/qmimedata.cpp @@ -105,6 +105,28 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty Q_Q(const QMimeData); QVariant data = q->retrieveData(format, type); + + // Text data requested: fallback to URL data if available + if (format == QLatin1String("text/plain") && !data.isValid()) { + data = retrieveTypedData(QLatin1String("text/uri-list"), QVariant::List); + if (data.type() == QVariant::Url) { + data = QVariant(data.toUrl().toDisplayString()); + } else if (data.type() == QVariant::List) { + QString text; + int numUrls = 0; + const QList list = data.toList(); + for (int i = 0; i < list.size(); ++i) { + if (list.at(i).type() == QVariant::Url) { + text.append(list.at(i).toUrl().toDisplayString() + QLatin1Char('\n')); + ++numUrls; + } + } + if (numUrls == 1) + text.chop(1); // no final '\n' if there's only one URL + data = QVariant(text); + } + } + if (data.type() == type || !data.isValid()) return data; @@ -326,6 +348,10 @@ QList QMimeData::urls() const URLs correspond to the MIME type \c text/uri-list. + Since Qt 5.0, setUrls also exports the urls as plain text, if setText + was not called before, to make it possible to drop them into any lineedit + and text editor. + \sa hasUrls(), setData() */ void QMimeData::setUrls(const QList &urls) @@ -385,7 +411,7 @@ void QMimeData::setText(const QString &text) */ bool QMimeData::hasText() const { - return hasFormat(QLatin1String("text/plain")); + return hasFormat(QLatin1String("text/plain")) || hasUrls(); } /*! diff --git a/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp b/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp index 09f17602b3f..f9a6bae0877 100644 --- a/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp +++ b/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp @@ -317,19 +317,22 @@ void tst_QMimeData::setUrls() const longUrlList += QUrl("http://www.google.com"); // verify initial state - QVERIFY(mimeData.hasUrls() == false); + QCOMPARE(mimeData.hasUrls(), false); // set a few, verify mimeData.setUrls(shortUrlList); QCOMPARE(mimeData.urls(), shortUrlList); + QCOMPARE(mimeData.text(), QString("http://qt.nokia.com")); // change them, verify mimeData.setUrls(longUrlList); QCOMPARE(mimeData.urls(), longUrlList); + QCOMPARE(mimeData.text(), QString("http://qt.nokia.com\nhttp://www.google.com\n")); // clear, verify mimeData.clear(); - QVERIFY(mimeData.hasUrls() == false); + QCOMPARE(mimeData.hasUrls(), false); + QCOMPARE(mimeData.hasText(), false); } QTEST_MAIN(tst_QMimeData) From 3b5f6f76471118e60ee9c9b8536d6b4fba1e785d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 16 Feb 2012 12:50:22 +0100 Subject: [PATCH 283/406] QWindow-test: Fix QSignalSpy warning about Qt::ScreenOrientation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I5954445057c1a597b5062ee8e472d684832812e5 Reviewed-by: Samuel Rødal --- tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index 8c4c53cc5cd..a860793ce45 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -45,6 +45,9 @@ #include +// For QSignalSpy slot connections. +Q_DECLARE_METATYPE(Qt::ScreenOrientation) + class tst_QWindow: public QObject { Q_OBJECT From 7c081ba94239e26f4e5c8b8c8a8c3486d1a8c76e Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 16 Feb 2012 14:20:57 +0200 Subject: [PATCH 284/406] Fix qlogging test for release configuration The helper process 'app' wasn't built in release configuration. Also improved finding the helper executable to utilize QFINDTESTDATA and print out a proper errors if it could not be found or started. Note that adding ".exe" to process name in Windows is unnecessary as QProcess already does that for you, so removed the ifdeffing. Task-number: QTBUG-24330 Change-Id: Ibe75e0ecd24181ab623d0a60f17ecaf92052b0dd Reviewed-by: Friedemann Kleint --- .../auto/corelib/global/qlogging/app/app.pro | 6 ++-- .../corelib/global/qlogging/tst_qlogging.cpp | 32 +++++++++++++------ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/tests/auto/corelib/global/qlogging/app/app.pro b/tests/auto/corelib/global/qlogging/app/app.pro index a167cc45cd6..1088d08a587 100644 --- a/tests/auto/corelib/global/qlogging/app/app.pro +++ b/tests/auto/corelib/global/qlogging/app/app.pro @@ -3,7 +3,9 @@ TEMPLATE = app TARGET = app QT = core -CONFIG -= debug_and_release app_bundle -CONFIG += debug console +DESTDIR = ./ + +CONFIG -= app_bundle +CONFIG += console SOURCES += main.cpp diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp index 11949cf1db2..aaec46fe646 100644 --- a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp +++ b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp @@ -47,6 +47,9 @@ class tst_qmessagehandler : public QObject { Q_OBJECT +public slots: + void initTestCase(); + private slots: void cleanup(); @@ -59,6 +62,9 @@ private slots: void cleanupFuncinfo(); void qMessagePattern(); + +private: + QString m_appDir; }; static QtMsgType s_type; @@ -85,6 +91,13 @@ void customMsgHandler(QtMsgType type, const char *msg) s_message = QString::fromLocal8Bit(msg); } +void tst_qmessagehandler::initTestCase() +{ + m_appDir = QFINDTESTDATA("app"); + QVERIFY2(!m_appDir.isEmpty(), qPrintable( + QString::fromLatin1("Couldn't find helper app dir starting from %1.").arg(QDir::currentPath()))); +} + void tst_qmessagehandler::cleanup() { qInstallMsgHandler(0); @@ -622,11 +635,11 @@ void tst_qmessagehandler::qMessagePattern() // %{file} is tricky because of shadow builds environment.prepend("QT_MESSAGE_PATTERN=\"%{type} %{appname} %{line} %{function} %{message}\""); process.setEnvironment(environment); -#ifdef Q_OS_WIN - process.start("app/app.exe"); -#else - process.start("app/app"); -#endif + + QString appExe = m_appDir + "/app"; + process.start(appExe); + QVERIFY2(process.waitForStarted(), qPrintable( + QString::fromLatin1("Could not start %1: %2").arg(appExe, process.errorString()))); process.waitForFinished(); QByteArray output = process.readAllStandardError(); @@ -643,11 +656,10 @@ void tst_qmessagehandler::qMessagePattern() environment = QProcess::systemEnvironment(); environment.prepend("QT_MESSAGE_PATTERN=\"PREFIX: %{unknown} %{message}\""); process.setEnvironment(environment); -#ifdef Q_OS_WIN - process.start("app/app.exe"); -#else - process.start("app/app"); -#endif + + process.start(appExe); + QVERIFY2(process.waitForStarted(), qPrintable( + QString::fromLatin1("Could not start %1: %2").arg(appExe, process.errorString()))); process.waitForFinished(); output = process.readAllStandardError(); From 48a366e6c87ac3572405d55a361f070e8b94902c Mon Sep 17 00:00:00 2001 From: Casper van Donderen Date: Thu, 16 Feb 2012 16:41:38 +0100 Subject: [PATCH 285/406] Make sure to print short text for QSslCertifictaeExtension. Change-Id: If2471bea27f095352ae8c28604e104b896fd97c7 Reviewed-by: Richard J. Moore Reviewed-by: Thiago Macieira --- src/network/ssl/qsslcertificateextension.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/ssl/qsslcertificateextension.cpp b/src/network/ssl/qsslcertificateextension.cpp index 2b5c57e3f05..9434d27e961 100644 --- a/src/network/ssl/qsslcertificateextension.cpp +++ b/src/network/ssl/qsslcertificateextension.cpp @@ -41,7 +41,8 @@ /*! \class QSslCertificateExtension - \brief The QSslCertificateExtension provides an API for accessing the extensions of an X509 certificate. + \brief The QSslCertificateExtension class provides an API for accessing the + extensions of an X509 certificate. \since 5.0 \rentrant From 03cbcab18471c02878b0207e2a59976ffa76caa5 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 16 Feb 2012 14:39:51 +0100 Subject: [PATCH 286/406] xcb: avoid use of statically-sized QList MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change the use of QList> to a simple C array of xcb_keycode_t*s. This is possible since the number of elements in the container is statically known. I have not measured speedup; this is just preventing premature pessimisation. Change-Id: I8855fc8a4e7ee840d8b7497ec4166074da7d8ea8 Reviewed-by: Samuel Rødal --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 33 ++++++++++------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 8c86d43f171..1b874e345cd 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -939,38 +939,35 @@ void QXcbKeyboard::setupModifiers() return; } - // Figure out the modifier mapping, ICCCM 6.6 - typedef QPair SymCodes; - QList modKeyCodes; - // for Alt and Meta L and R are the same - modKeyCodes << SymCodes(XK_Alt_L, xcb_key_symbols_get_keycode(m_key_symbols, XK_Alt_L)); - modKeyCodes << SymCodes(XK_Meta_L, xcb_key_symbols_get_keycode(m_key_symbols, XK_Meta_L)); - modKeyCodes << SymCodes(XK_Super_L, xcb_key_symbols_get_keycode(m_key_symbols, XK_Super_L)); - modKeyCodes << SymCodes(XK_Super_R, xcb_key_symbols_get_keycode(m_key_symbols, XK_Super_R)); - modKeyCodes << SymCodes(XK_Hyper_L, xcb_key_symbols_get_keycode(m_key_symbols, XK_Hyper_L)); - modKeyCodes << SymCodes(XK_Hyper_R, xcb_key_symbols_get_keycode(m_key_symbols, XK_Hyper_R)); - modKeyCodes << SymCodes(XK_Num_Lock, xcb_key_symbols_get_keycode(m_key_symbols, XK_Num_Lock)); - modKeyCodes << SymCodes(XK_Mode_switch, xcb_key_symbols_get_keycode(m_key_symbols, XK_Mode_switch)); - modKeyCodes << SymCodes(XK_Caps_Lock, xcb_key_symbols_get_keycode(m_key_symbols, XK_Caps_Lock)); + static const xcb_keysym_t symbols[] = { + XK_Alt_L, XK_Meta_L, XK_Super_L, XK_Super_R, + XK_Hyper_L, XK_Hyper_R, XK_Num_Lock, XK_Mode_switch, XK_Caps_Lock, + }; + static const size_t numSymbols = sizeof symbols / sizeof *symbols; + + // Figure out the modifier mapping, ICCCM 6.6 + xcb_keycode_t* modKeyCodes[numSymbols]; + for (size_t i = 0; i < numSymbols; ++i) + modKeyCodes[i] = xcb_key_symbols_get_keycode(m_key_symbols, symbols[i]); xcb_keycode_t *modMap = xcb_get_modifier_mapping_keycodes(modMapReply); const int w = modMapReply->keycodes_per_modifier; - for (int i = 0; i < modKeyCodes.count(); ++i) { + for (size_t i = 0; i < numSymbols; ++i) { for (int bit = 0; bit < 8; ++bit) { uint mask = 1 << bit; for (int x = 0; x < w; ++x) { xcb_keycode_t keyCode = modMap[x + bit * w]; - xcb_keycode_t *itk = modKeyCodes.at(i).second; + xcb_keycode_t *itk = modKeyCodes[i]; while (itk && *itk != XCB_NO_SYMBOL) if (*itk++ == keyCode) - setMask(modKeyCodes.at(i).first, mask); + setMask(symbols[i], mask); } } } - for (int i = 0; i < modKeyCodes.count(); ++i) - free(modKeyCodes.at(i).second); + for (size_t i = 0; i < numSymbols; ++i) + free(modKeyCodes[i]); free(modMapReply); } From d94ab97b7741de7c73d4d203b9cca7bd150d581f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 16 Feb 2012 07:40:20 +0100 Subject: [PATCH 287/406] [QTBUG-22847] Compile with C++11 compiler C++11 supports user-defined string literals, which makes the C++98-accepted literal string concatenation sequence "foo"MACRO illegal under C++11. The solution is to add whitespace between the string literal and the macro. For symmetry, this patch adds it on both sides. Change-Id: Ie0c698f610986c4d1b12dc2083489043b696936d Reviewed-by: Thiago Macieira --- src/corelib/plugin/qplugin.h | 6 +++--- src/testlib/qxmltestlogger.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h index 90ab8369c92..93be7248c34 100644 --- a/src/corelib/plugin/qplugin.h +++ b/src/corelib/plugin/qplugin.h @@ -154,9 +154,9 @@ void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin); # endif # define Q_PLUGIN_VERIFICATION_DATA \ static const char qt_plugin_verification_data[] = \ - "pattern=""QT_PLUGIN_VERIFICATION_DATA""\n" \ - "version="QT_VERSION_STR"\n" \ - "debug="QPLUGIN_DEBUG_STR; + "pattern=" "QT_PLUGIN_VERIFICATION_DATA" "\n" \ + "version=" QT_VERSION_STR "\n" \ + "debug=" QPLUGIN_DEBUG_STR; # define Q_EXPORT_PLUGIN2(PLUGIN, PLUGINCLASS) \ diff --git a/src/testlib/qxmltestlogger.cpp b/src/testlib/qxmltestlogger.cpp index 28ae6ff0954..7e5da206806 100644 --- a/src/testlib/qxmltestlogger.cpp +++ b/src/testlib/qxmltestlogger.cpp @@ -118,7 +118,7 @@ void QXmlTestLogger::startLogging() QTest::qt_asprintf(&buf, "\n" " %s\n" - " "QTEST_VERSION_STR"\n" + " " QTEST_VERSION_STR "\n" "\n", qVersion()); outputString(buf.constData()); } From b1004b6f8380a46c379b819ef4a5c7ba555f6666 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 16 Feb 2012 14:37:04 +0100 Subject: [PATCH 288/406] Compilation fix: missing includes for geteuid() Change-Id: I054b8c9a398b5e192c2e005a39cba19bb4930966 Reviewed-by: David Faure Reviewed-by: Thiago Macieira --- tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp | 4 ++++ tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp index 46d2fa2bde0..0b2e1e19028 100644 --- a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp +++ b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp @@ -50,6 +50,10 @@ #ifdef Q_OS_WIN # include #endif +#ifdef Q_OS_UNIX // for geteuid() +# include +# include +#endif class tst_QTemporaryDir : public QObject { diff --git a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp index 8473597dac5..ad9da27c7e8 100644 --- a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp +++ b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp @@ -52,6 +52,11 @@ #include #include +#ifdef Q_OS_UNIX // for geteuid() +# include +# include +#endif + typedef QMap QStringMap; typedef QList QIntList; Q_DECLARE_METATYPE(QImage) From 7e11fdd6e6668a3dd8d9355c2222fb6a34b9f3cd Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 15 Feb 2012 22:12:41 +0100 Subject: [PATCH 289/406] Only define QT_NAMESPACE if it is used. Fixes non-namespaced builds. Change-Id: Ie743fc57e7f208fdd50c61b08dc8a4b150de3930 Reviewed-by: Clinton Stimpson Reviewed-by: Alexander Neundorf Reviewed-by: Stephen Kelly --- src/corelib/Qt5CoreConfigExtras.cmake.in | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index 155961bc9a6..440d5e92bb3 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -12,5 +12,7 @@ if (NOT \"$${CMAKE_ADD_FPIE_FLAGS}\" STREQUAL \"\") set(Qt5Core_COMPILE_FLAGS "-fPIE") endif() -list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) -list(APPEND Qt5Core_COMPILE_DEFINITIONS QT_NAMESPACE=$$QT_NAMESPACE) +if (NOT \"$$QT_NAMESPACE\" STREQUAL \"\") + list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) + list(APPEND Qt5Core_COMPILE_DEFINITIONS QT_NAMESPACE=$$QT_NAMESPACE) +endif() From 3ea33062d42f821cf3230de3f1d7d6d4f033a609 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 15 Feb 2012 23:19:19 +0100 Subject: [PATCH 290/406] Use ctest to run all tests and print output. Change-Id: Ib5a8513cc2d08adce49602b2590059b918b1ffda Reviewed-by: Alexander Neundorf Reviewed-by: Stephen Kelly --- src/corelib/Qt5CoreConfigExtras.cmake.in | 6 +- tests/manual/cmake/CMakeLists.txt | 81 +++++++++++++++++++----- 2 files changed, 68 insertions(+), 19 deletions(-) diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index 440d5e92bb3..155961bc9a6 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -12,7 +12,5 @@ if (NOT \"$${CMAKE_ADD_FPIE_FLAGS}\" STREQUAL \"\") set(Qt5Core_COMPILE_FLAGS "-fPIE") endif() -if (NOT \"$$QT_NAMESPACE\" STREQUAL \"\") - list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) - list(APPEND Qt5Core_COMPILE_DEFINITIONS QT_NAMESPACE=$$QT_NAMESPACE) -endif() +list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) +list(APPEND Qt5Core_COMPILE_DEFINITIONS QT_NAMESPACE=$$QT_NAMESPACE) diff --git a/tests/manual/cmake/CMakeLists.txt b/tests/manual/cmake/CMakeLists.txt index 07fee062be9..7ec3cebf4b9 100644 --- a/tests/manual/cmake/CMakeLists.txt +++ b/tests/manual/cmake/CMakeLists.txt @@ -1,33 +1,84 @@ +# This is an automatic test for the CMake configuration files. +# To run it, +# 1) mkdir build # Create a build directory +# 2) cd build +# 3) cmake .. # Run cmake on this directory. +# 4) ctest # Run ctest +# +# The expected output is something like: +# +# Start 1: pass1 +# 1/7 Test #1: pass1 ............................ Passed 4.25 sec +# Start 2: pass2 +# 2/7 Test #2: pass2 ............................ Passed 2.00 sec +# Start 3: pass3 +# 3/7 Test #3: pass3 ............................ Passed 2.85 sec +# Start 4: fail4 +# 4/7 Test #4: fail4 ............................ Passed 1.88 sec +# Start 5: fail5 +# 5/7 Test #5: fail5 ............................ Passed 1.36 sec +# Start 6: pass_needsquoting_6 +# 6/7 Test #6: pass_needsquoting_6 .............. Passed 2.88 sec +# Start 7: pass7 +# 7/7 Test #7: pass7 ............................ Passed 0.93 sec +# +# Note that if Qt is not installed, or if it is installed to a +# non-standard prefix, the environment variable CMAKE_PREFIX_PATH +# needs to be set to the installation prefix or build prefix of Qt +# before running these tests. + cmake_minimum_required(VERSION 2.8) project(qmake_cmake_files) -macro(_do_build _dir) - try_compile(Result ${CMAKE_CURRENT_BINARY_DIR}/${_dir} - ${CMAKE_CURRENT_SOURCE_DIR}/${_dir} - ${_dir} - OUTPUT_VARIABLE Out - ) -endmacro() +enable_testing() macro(expect_pass _dir) - _do_build(${_dir}) - if (NOT Result) - message(SEND_ERROR "Build failed: ${Out}") - endif() + string(REPLACE "(" "_" testname "${_dir}") + string(REPLACE ")" "_" testname "${testname}") + add_test(${testname} ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMAKE_CURRENT_SOURCE_DIR}/${_dir}" + "${CMAKE_CURRENT_BINARY_DIR}/${_dir}" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${CMAKE_MAKE_PROGRAM} + ) endmacro() macro(expect_fail _dir) - _do_build(${_dir}) - if (Result) - message(SEND_ERROR "Build should fail, but did not: ${Out}") - endif() + string(REPLACE "(" "_" testname "${_dir}") + string(REPLACE ")" "_" testname "${testname}") + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/failbuild/${_dir}") + file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/${_dir}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/failbuild/${_dir}") + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/failbuild/${_dir}/CMakeLists.txt" + " + cmake_minimum_required(VERSION 2.8) + project(${_dir}_build) + + try_compile(Result \${CMAKE_CURRENT_BINARY_DIR}/${_dir} + \${CMAKE_CURRENT_SOURCE_DIR}/${_dir} + ${_dir} + ) + if (Result) + message(SEND_ERROR \"Succeeded build which should fail\") + endif() + " + ) + add_test(${testname} ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMAKE_CURRENT_BINARY_DIR}/failbuild/${_dir}" + "${CMAKE_CURRENT_BINARY_DIR}/failbuild/${_dir}/build" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${CMAKE_MAKE_PROGRAM} + ) endmacro() if(${CMAKE_VERSION} VERSION_GREATER 2.8.7) # Requires CMAKE_AUTOMOC function in CMake 2.8.7 expect_pass(pass1) +else() + message("CMake version older than 2.8.7. Not running test \"pass1\"") endif() expect_pass(pass2) expect_pass(pass3) From 9aa51821e446152517aa3022bcf7ebbcc7d3d888 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Sat, 4 Feb 2012 00:45:33 +0100 Subject: [PATCH 291/406] Ensure the header's context menu is in sync with the visible sections When the filedialog was reshown the context menu for the header was not in sync with the sections that were actually visible. This ensures that it is in sync after the state of the header is restored. Task-number: QTBUG-23271 Change-Id: Ia1546bf300d43a5822482f63de99eb52b674bf52 Reviewed-by: Zeno Albisser (cherry picked from commit 2e220e4603d6a0c21efee3a884be76e9f2d7ebb7) --- src/widgets/dialogs/qfiledialog.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index ed5264159f4..84fdef67022 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -482,9 +482,20 @@ bool QFileDialog::restoreState(const QByteArray &state) history.pop_front(); setHistory(history); setDirectory(lastVisitedDir()->isEmpty() ? currentDirectory : *lastVisitedDir()); - if (!d->qFileDialogUi->treeView->header()->restoreState(headerData)) + QHeaderView *headerView = d->qFileDialogUi->treeView->header(); + if (!headerView->restoreState(headerData)) return false; + QList actions = headerView->actions(); + QAbstractItemModel *abstractModel = d->model; +#ifndef QT_NO_PROXYMODEL + if (d->proxyModel) + abstractModel = d->proxyModel; +#endif + int total = qMin(abstractModel->columnCount(QModelIndex()), actions.count() + 1); + for (int i = 1; i < total; ++i) + actions.at(i - 1)->setChecked(!headerView->isSectionHidden(i)); + setViewMode(ViewMode(viewMode)); return true; } From 90128ba8778327a13f4eac2809d9db783f33690c Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 10 Nov 2011 07:56:57 +0100 Subject: [PATCH 292/406] Ensure that QSqlDatabase::database() is still thread-safe QSqlDatabase::database() is documented to be thread-safe and when the driver is queried for the numericalPrecisionPolicy set then it can comprimise the thread-safety. Since the driver itself (if one is set) will be queried for the numericalPrecisionPolicy when numericalPrecisionPolicy() is called on the QSqlDatabase then we can have it fallback to the default instead rather than taking the driver's own setting. Task-number: QTBUG-13423 (cherry picked from commit e7e9fca6c0cd1d0869029fc6e9d7605234ee5bb2) Change-Id: Ie7e9fca6c0cd1d0869029fc6e9d7605234ee5bb2 Reviewed-by: Yunqiao Yin --- src/sql/kernel/qsqldatabase.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp index d260588dd53..7b6a2b8c128 100644 --- a/src/sql/kernel/qsqldatabase.cpp +++ b/src/sql/kernel/qsqldatabase.cpp @@ -138,10 +138,7 @@ public: driver(dr), port(-1) { - if(driver) - precisionPolicy = driver->numericalPrecisionPolicy(); - else - precisionPolicy= QSql::LowPrecisionDouble; + precisionPolicy = QSql::LowPrecisionDouble; } QSqlDatabasePrivate(const QSqlDatabasePrivate &other); ~QSqlDatabasePrivate(); From 692064bcfd116c2f3a2b30572e511ee68c6a0531 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Wed, 15 Feb 2012 14:41:07 +0100 Subject: [PATCH 293/406] Don't render glyph with FT with fetchMetricsOnly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Neither rendering with outline nor fetchMetricsOnly requires the rendering from FreeType so we don't need to render them or cache it. It should speed up recalcAdvances() quite a lot. Change-Id: I0f623cb4f79da2edf6e9c9634a2f22fb0c66823c Reviewed-by: Samuel Rødal --- src/gui/text/qfontengine_ft.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 8880eb7cb36..14e2dba3644 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -877,7 +877,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, if (err != FT_Err_Ok) qWarning("load glyph failed err=%x face=%p, glyph=%d", err, face, glyph); - if ((!set || set->outline_drawing) && fetchMetricsOnly) + if (!set || set->outline_drawing || fetchMetricsOnly) return 0; FT_GlyphSlot slot = face->glyph; From e7b8c9227132a26acd3d975050fd1f6fd4f22944 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 3 Feb 2012 23:53:31 +0100 Subject: [PATCH 294/406] Some small doc fixes, typos and removal of one incorrect paragraph The QTextStream paragraph that is removed referred to something that is incorrect. This was confirmed for Windows, Linux and Mac. Change-Id: Ibac8f82482f2060308b5b8485d6da228bdf52fe6 Reviewed-by: Casper van Donderen (cherry picked from commit 80cebfde10cf34dcc0777c24f1b3ff37cad20181) --- doc/src/examples/dirview.qdoc | 2 +- src/corelib/io/qtextstream.cpp | 5 ----- src/widgets/itemviews/qlistwidget.cpp | 8 ++++---- src/widgets/itemviews/qtreeview.cpp | 2 +- src/widgets/widgets/qtextedit.cpp | 2 +- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/doc/src/examples/dirview.qdoc b/doc/src/examples/dirview.qdoc index 329f90e6979..a4b799678a1 100644 --- a/doc/src/examples/dirview.qdoc +++ b/doc/src/examples/dirview.qdoc @@ -30,7 +30,7 @@ \title Dir View Example The Dir View example shows a tree view onto the local filing system. It uses the - QDirModel class to provide supply file and directory information. + QDirModel class to provide file and directory information. \image dirview-example.png */ diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 7f378662262..a6d58c760f5 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -66,11 +66,6 @@ static const int QTEXTSTREAM_BUFFERSIZE = 16384; \snippet doc/src/snippets/code/src_corelib_io_qtextstream.cpp 1 - Note that you cannot use QTextStream::atEnd(), which returns true when you - have reached the end of the data stream, with stdin. The reason for this is - that as long as stdin doesn't give any input to the QTextStream, \c atEnd() - will return true even if the stdin is open and waiting for more characters. - Besides using QTextStream's constructors, you can also set the device or string QTextStream operates on by calling setDevice() or setString(). You can seek to a position by calling seek(), and diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp index c8a7c664b01..97fbea6c3d9 100644 --- a/src/widgets/itemviews/qlistwidget.cpp +++ b/src/widgets/itemviews/qlistwidget.cpp @@ -1167,10 +1167,10 @@ void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 1 - If you need to insert a new item into the list at a particular position, it - is more required to construct the item without a parent widget and use the - insertItem() function to place it within the list. The list widget will - take ownership of the item. + If you need to insert a new item into the list at a particular position, + then it should be constructed without a parent widget. The insertItem() + function should then be used to place it within the list. The list widget + will take ownership of the item. \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 6 \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 7 diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 179b1228054..7f5e5964ab6 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -83,7 +83,7 @@ QT_BEGIN_NAMESPACE It is simple to construct a tree view displaying data from a model. In the following example, the contents of a directory are - supplied by a QDirModel and displayed as a tree: + supplied by a QFileSystemModel and displayed as a tree: \snippet doc/src/snippets/shareddirmodel/main.cpp 3 \snippet doc/src/snippets/shareddirmodel/main.cpp 6 diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp index 5273e16ab58..d0065aacb90 100644 --- a/src/widgets/widgets/qtextedit.cpp +++ b/src/widgets/widgets/qtextedit.cpp @@ -404,7 +404,7 @@ void QTextEditPrivate::_q_ensureVisible(const QRectF &_rect) within the text. If you want to limit the total number of paragraphs in a QTextEdit, - as it is for example open useful in a log viewer, then you can use + as for example it is often useful in a log viewer, then you can use QTextDocument's maximumBlockCount property for that. \section2 Read-only Key Bindings From f0f78eb0a9cc5d5898937201baa0e543ce4cac22 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 10 Feb 2012 15:50:47 +0100 Subject: [PATCH 295/406] Remove usages of QT_ARCH and QT_ARCH_* from qtbase The architecture is detected at compile time based on the predefined macros from the compiler. Don't use QT_ARCH in .pro, .pri, or .prf files. The PNG_NO_ASSEMBLER_CODE define from libpng.pri is not present in the current copy of src/3rdparty/libpng, so no change in functionality is expected. The conditional for the SUPPORT_JIT define in pcre.pri is moved to src/3rdparty/pcre/config.h, again so that we can use the compiler's predefined macros to detect the architecture at compile time. Replace QT_ARCH_ARM, QT_ARCH_MIPS, and QT_ARCH_SPARC with their Q_PROCESSOR_* equivalents. Replace QT_ARCH_INTEGRITY, QT_ARCH_VXWORKS, and QT_ARCH_WINDOWSCE with their Q_OS_* equivalents. Note that this commit also effectively disables the SPARC atomic implementation. An inline implementation for SPARC needs to be added, or we remove the current code and instead rely on the GCC intrinsic or C++11 std::atomic support on SPARC. Note also that this commit does not remove QT_ARCH from configure or qconfig.h. This will continue to be set until all Qt 5 projects can be moved away from using QT_ARCH. Change-Id: I5de747cc4436d21941329974cff3016970f497b8 Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- mkspecs/features/qt_installs.prf | 3 +-- mkspecs/features/qt_module_config.prf | 1 - src/3rdparty/libpng.pri | 1 - src/3rdparty/pcre.pri | 9 --------- src/3rdparty/pcre/config.h | 17 +++++++++++++++++ src/corelib/arch/arch.pri | 6 ------ src/corelib/arch/sparc/arch.pri | 6 +++--- src/corelib/global/qglobal.h | 2 +- src/corelib/kernel/qmetatype.h | 2 +- src/corelib/tools/qvector.h | 2 +- src/testlib/qtestcase.h | 4 ++-- src/tools/uic/uic.pro | 2 +- .../qwaitcondition/tst_qwaitcondition.cpp | 2 +- .../tst_qgraphicsproxywidget.cpp | 2 +- .../qgraphicsscene/tst_qgraphicsscene.cpp | 4 ++-- .../qgraphicsview/tst_qgraphicsview.cpp | 2 +- .../itemviews/qitemview/tst_qitemview.cpp | 2 +- .../widgets/widgets/qcombobox/tst_qcombobox.cpp | 4 ++-- .../qplaintextedit/tst_qplaintextedit.cpp | 2 +- .../widgets/widgets/qtextedit/tst_qtextedit.cpp | 2 +- 20 files changed, 37 insertions(+), 38 deletions(-) diff --git a/mkspecs/features/qt_installs.prf b/mkspecs/features/qt_installs.prf index b0de7b8fd86..8b17aa90fb2 100644 --- a/mkspecs/features/qt_installs.prf +++ b/mkspecs/features/qt_installs.prf @@ -11,8 +11,7 @@ qt_install_headers { INSTALL_HEADERS = $$SYNCQT.HEADER_FILES equals(TARGET, QtCore) { #headers created by configure - INSTALL_HEADERS *= $$QT_BUILD_TREE/src/corelib/global/qconfig.h \ - $$QT_SOURCE_TREE/src/corelib/arch/$$QT_ARCH/arch + INSTALL_HEADERS *= $$QT_BUILD_TREE/src/corelib/global/qconfig.h } equals(TARGET, phonon) { diff --git a/mkspecs/features/qt_module_config.prf b/mkspecs/features/qt_module_config.prf index 4da1666fc58..a8439198dfa 100644 --- a/mkspecs/features/qt_module_config.prf +++ b/mkspecs/features/qt_module_config.prf @@ -17,7 +17,6 @@ INCLUDEPATH *= $$MODULE_PRIVATE_INCLUDES INCLUDEPATH *= $$MODULE_PRIVATE_INCLUDES/$$TARGET INCLUDEPATH *= $$MODULE_INCLUDES $$MODULE_INCLUDES/.. #just for today to have some compat !isEmpty(RCC_DIR): INCLUDEPATH += $$RCC_DIR -isEmpty(QT_ARCH):!isEmpty(ARCH):QT_ARCH=$$ARCH #another compat that will rot for change #215700 TEMPLATE = lib isEmpty(QT_MAJOR_VERSION) { VERSION=5.0.0 diff --git a/src/3rdparty/libpng.pri b/src/3rdparty/libpng.pri index 7ac19101516..8479114aa23 100644 --- a/src/3rdparty/libpng.pri +++ b/src/3rdparty/libpng.pri @@ -1,5 +1,4 @@ DEFINES *= QT_USE_BUNDLED_LIBPNG -!isEqual(QT_ARCH, i386):!isEqual(QT_ARCH, x86_64):DEFINES += PNG_NO_ASSEMBLER_CODE INCLUDEPATH += $$PWD/libpng SOURCES += $$PWD/libpng/png.c \ $$PWD/libpng/pngerror.c \ diff --git a/src/3rdparty/pcre.pri b/src/3rdparty/pcre.pri index 92066e1aeea..7febd8fd0bb 100644 --- a/src/3rdparty/pcre.pri +++ b/src/3rdparty/pcre.pri @@ -1,14 +1,5 @@ DEFINES += PCRE_HAVE_CONFIG_H -# man 3 pcrejit for a list of supported platforms; -# as PCRE 8.30, stable JIT support is available for: -# - ARM v5, v7, and Thumb2 -# - x86/x86-64 -# - MIPS 32bit -equals(QT_ARCH, "i386")|equals(QT_ARCH, "x86_64")|equals(QT_ARCH, "arm")|if(equals(QT_ARCH, "mips"):!*-64) { - DEFINES += SUPPORT_JIT -} - win32:DEFINES += PCRE_STATIC INCLUDEPATH += $$PWD/pcre diff --git a/src/3rdparty/pcre/config.h b/src/3rdparty/pcre/config.h index 4fe10f41d8a..fede0dcbb0c 100644 --- a/src/3rdparty/pcre/config.h +++ b/src/3rdparty/pcre/config.h @@ -13,3 +13,20 @@ #define SUPPORT_UCP #define SUPPORT_UTF16 +/* + man 3 pcrejit for a list of supported platforms; + as PCRE 8.30, stable JIT support is available for: + - ARM v5, v7, and Thumb2 + - x86/x86-64 + - MIPS 32bit +*/ +#if \ + /* ARM */ \ + defined(__arm__) || defined(__TARGET_ARCH_ARM) \ + /* x86 32/64 */ \ + || defined(__i386) || defined(__i386__) || defined(_M_IX86) \ + || defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) \ + /* MIPS32 */ \ + || defined(__mips) || defined(__mips__) || defined(_M_MRX000) && !(defined(_MIPS_ARCH_MIPS64) || defined(__mips64)) +# define SUPPORT_JIT +#endif diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index cb2102cefd3..c64bbe2821f 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -25,9 +25,3 @@ unix { HEADERS += arch/qatomic_unix.h SOURCES += arch/qatomic_unix.cpp } - -QT_ARCH_CPP = $$QT_SOURCE_TREE/src/corelib/arch/$$QT_ARCH -exists($$QT_ARCH_CPP) { - DEPENDPATH += $$QT_ARCH_CPP - include($$QT_ARCH_CPP/arch.pri, "", true) -} diff --git a/src/corelib/arch/sparc/arch.pri b/src/corelib/arch/sparc/arch.pri index 9bb3a888e81..b3ca3996406 100644 --- a/src/corelib/arch/sparc/arch.pri +++ b/src/corelib/arch/sparc/arch.pri @@ -2,9 +2,9 @@ # SPARC architecture # *-64* { - SOURCES += $$QT_ARCH_CPP/qatomic64.s + SOURCES += $$PWD/qatomic64.s } else { - SOURCES += $$QT_ARCH_CPP/qatomic32.s \ - $$QT_ARCH_CPP/qatomic_sparc.cpp + SOURCES += $$PWD/qatomic32.s \ + $$PWD/qatomic_sparc.cpp } diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 91ac4bd41de..22e73ede26c 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -463,7 +463,7 @@ typedef int QNoImplicitBoolCast; // This logic must match the one in qmetatype.h #if defined(QT_COORD_TYPE) typedef QT_COORD_TYPE qreal; -#elif defined(QT_NO_FPU) || defined(QT_ARCH_ARM) || defined(QT_ARCH_WINDOWSCE) +#elif defined(QT_NO_FPU) || defined(Q_PROCESSOR_ARM) || defined(Q_OS_WINCE) typedef float qreal; #else typedef double qreal; diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 0b6a62e5c84..1473231d644 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -203,7 +203,7 @@ public: // This logic must match the one in qglobal.h #if defined(QT_COORD_TYPE) QReal = 0, -#elif defined(QT_NO_FPU) || defined(QT_ARCH_ARM) || defined(QT_ARCH_WINDOWSCE) +#elif defined(QT_NO_FPU) || defined(Q_PROCESSOR_ARM) || defined(Q_OS_WINCE) QReal = Float, #else QReal = Double, diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 0eb227e59d8..4230e55ff54 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -67,7 +67,7 @@ struct Q_CORE_EXPORT QVectorData QtPrivate::RefCount ref; int alloc; int size; -#if defined(QT_ARCH_SPARC) && defined(Q_CC_GNU) && defined(__LP64__) && defined(QT_BOOTSTRAPPED) +#if defined(Q_PROCESSOR_SPARC) && defined(Q_CC_GNU) && defined(__LP64__) && defined(QT_BOOTSTRAPPED) // workaround for bug in gcc 3.4.2 uint sharable; uint capacity; diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index 128decb6460..e4f40204617 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -264,7 +264,7 @@ namespace QTest template bool qCompare(T1 const &, T2 const &, const char *, const char *, const char *, int); -#if defined(QT_COORD_TYPE) && (defined(QT_ARCH_ARM) || defined(QT_NO_FPU) || defined(QT_ARCH_WINDOWSCE)) +#if defined(QT_COORD_TYPE) && (defined(Q_PROCESSOR_ARM) || defined(QT_NO_FPU) || defined(Q_OS_WINCE)) template <> inline bool qCompare(qreal const &t1, float const &t2, const char *actual, const char *expected, const char *file, int line) @@ -279,7 +279,7 @@ namespace QTest return qCompare(qreal(t1), t2, actual, expected, file, line); } -#elif defined(QT_COORD_TYPE) || defined(QT_ARCH_ARM) || defined(QT_NO_FPU) || defined(QT_ARCH_WINDOWSCE) +#elif defined(QT_COORD_TYPE) || defined(Q_PROCESSOR_ARM) || defined(QT_NO_FPU) || defined(Q_OS_WINCE) template <> inline bool qCompare(qreal const &t1, double const &t2, const char *actual, const char *expected, const char *file, int line) diff --git a/src/tools/uic/uic.pro b/src/tools/uic/uic.pro index 6598180e45e..7a95db861f3 100644 --- a/src/tools/uic/uic.pro +++ b/src/tools/uic/uic.pro @@ -14,7 +14,7 @@ HEADERS += uic.h SOURCES += main.cpp \ uic.cpp -linux-g++-maemo:contains(QT_ARCH, arm) { +linux-g++-maemo { # UIC will crash when running inside QEMU if built with -O2 QMAKE_CFLAGS_RELEASE -= -O2 QMAKE_CXXFLAGS_RELEASE -= -O2 diff --git a/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp b/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp index 578f8670321..73cb8e9cd64 100644 --- a/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp +++ b/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp @@ -62,7 +62,7 @@ private slots: static const int iterations = 10; // Note: some tests rely on ThreadCount being multiple of 2 -#if defined(Q_OS_SOLARIS) || ( defined(Q_OS_LINUX) && defined(QT_ARCH_ARMV6) ) +#if defined(Q_OS_SOLARIS) || ( defined(Q_OS_LINUX) && defined(Q_PROCESSOR_ARM) ) static const int ThreadCount = 4; #else static const int ThreadCount = 10; diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index 3ccc533086c..ca5b9920123 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -1574,7 +1574,7 @@ void tst_QGraphicsProxyWidget::resize_simple_data() QTest::addColumn("size"); QTest::newRow("200, 200") << QSizeF(200, 200); -#if !defined(QT_ARCH_ARM) && !defined(Q_OS_WINCE) +#if !defined(Q_PROCESSOR_ARM) && !defined(Q_OS_WINCE) QTest::newRow("1000, 1000") << QSizeF(1000, 1000); // Since 4.5, 10000x10000 runs out of memory. // QTest::newRow("10000, 10000") << QSizeF(10000, 10000); diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp index f103d3d529b..3257e7efea0 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp @@ -365,7 +365,7 @@ void tst_QGraphicsScene::itemIndexMethod() QGraphicsScene scene; QCOMPARE(scene.itemIndexMethod(), QGraphicsScene::BspTreeIndex); -#ifdef QT_ARCH_ARM +#ifdef Q_PROCESSOR_ARM const int minY = -500; const int maxY = 500; const int minX = -500; @@ -426,7 +426,7 @@ void tst_QGraphicsScene::bspTreeDepth() void tst_QGraphicsScene::items() { -#ifdef QT_ARCH_ARM +#ifdef Q_PROCESSOR_ARM const int minY = -500; const int maxY = 500; const int minX = -500; diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp index 7681b3c787e..7ceeaaa0d3e 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp @@ -1656,7 +1656,7 @@ void tst_QGraphicsView::mapToScene() QCOMPARE(view.size(), viewSize); // First once without setting the scene rect -#ifdef QT_ARCH_ARM +#ifdef Q_PROCESSOR_ARM const int step = 20; #else const int step = 1; diff --git a/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp b/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp index 04b32d1e563..4e71bf964c2 100644 --- a/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp +++ b/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp @@ -286,7 +286,7 @@ void tst_QItemView::populate() { treeModel = new CheckerModel; QModelIndex parent; -#if defined(QT_ARCH_ARM) +#if defined(Q_PROCESSOR_ARM) const int baseInsert = 4; #else const int baseInsert = 26; diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index 80285ded78b..907a2399127 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -765,7 +765,7 @@ void tst_QComboBox::virtualAutocompletion() // We need to set the keyboard input interval to a higher value // as the processEvent() call takes too much time, so it restarts // the keyboard search then -#if defined(QT_ARCH_ARM) || defined(QT_ARCH_MIPS) +#if defined(Q_PROCESSOR_ARM) || defined(Q_PROCESSOR_MIPS) int oldInterval = QApplication::keyboardInputInterval(); QApplication::setKeyboardInputInterval(1500); #endif @@ -797,7 +797,7 @@ void tst_QComboBox::virtualAutocompletion() QApplication::sendEvent(testWidget, &kr2); qApp->processEvents(); // Process events to trigger autocompletion QTRY_COMPARE(testWidget->currentIndex(), 3); -#if defined(QT_ARCH_ARM) || defined(QT_ARCH_MIPS) +#if defined(Q_PROCESSOR_ARM) || defined(Q_PROCESSOR_MIPS) QApplication::setKeyboardInputInterval(oldInterval); #endif } diff --git a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp index 615e4453bcc..4019faf428c 100644 --- a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp +++ b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp @@ -219,7 +219,7 @@ void tst_QPlainTextEdit::getSetCheck() QCOMPARE(0, obj1.tabStopWidth()); obj1.setTabStopWidth(INT_MIN); QCOMPARE(0, obj1.tabStopWidth()); // Makes no sense to set a negative tabstop value -#if defined(QT_ARCH_WINDOWSCE) +#if defined(Q_OS_WINCE) // due to rounding error in qRound when qreal==float // we cannot use INT_MAX for this check obj1.setTabStopWidth(SHRT_MAX*2); diff --git a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp index 6253ef89e45..249e9d7fbe4 100644 --- a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp @@ -288,7 +288,7 @@ void tst_QTextEdit::getSetCheck() QCOMPARE(0, obj1.tabStopWidth()); obj1.setTabStopWidth(INT_MIN); QCOMPARE(0, obj1.tabStopWidth()); // Makes no sense to set a negative tabstop value -#if defined(QT_ARCH_WINDOWSCE) +#if defined(Q_OS_WINCE) // due to rounding error in qRound when qreal==float // we cannot use INT_MAX for this check obj1.setTabStopWidth(SHRT_MAX*2); From 7a8883c4342fbb17309cc7dfcc8f6829af33d0cd Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 16 Feb 2012 15:30:37 +0100 Subject: [PATCH 296/406] Fix naming of plugins for QPA plugins and use new plugin system. - Fix naming "com.nokia" -> "org.qt-project" in platform integration & platform theme. - Adapt Windows, XCB, Cocoa, Minimal. Change-Id: I7834f5c3d94473b6f06c1bffee074a70ee25f426 Reviewed-by: Lars Knoll --- src/gui/kernel/qplatformintegrationplugin_qpa.h | 2 +- src/gui/kernel/qplatformthemeplugin_qpa.h | 2 +- src/plugins/platforms/cocoa/cocoa.json | 3 +++ src/plugins/platforms/cocoa/cocoa.pro | 1 + src/plugins/platforms/cocoa/main.mm | 6 ++++-- src/plugins/platforms/minimal/main.cpp | 6 ++++-- src/plugins/platforms/minimal/minimal.json | 3 +++ src/plugins/platforms/minimal/minimal.pro | 2 ++ src/plugins/platforms/windows/main.cpp | 6 ++++-- src/plugins/platforms/windows/windows.json | 3 +++ src/plugins/platforms/windows/windows.pro | 2 ++ src/plugins/platforms/xcb/main.cpp | 6 ++++-- src/plugins/platforms/xcb/xcb.json | 3 +++ src/plugins/platforms/xcb/xcb.pro | 2 ++ 14 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 src/plugins/platforms/cocoa/cocoa.json create mode 100644 src/plugins/platforms/minimal/minimal.json create mode 100644 src/plugins/platforms/windows/windows.json create mode 100644 src/plugins/platforms/xcb/xcb.json diff --git a/src/gui/kernel/qplatformintegrationplugin_qpa.h b/src/gui/kernel/qplatformintegrationplugin_qpa.h index 84c2567bbd2..d70569cbba6 100644 --- a/src/gui/kernel/qplatformintegrationplugin_qpa.h +++ b/src/gui/kernel/qplatformintegrationplugin_qpa.h @@ -68,7 +68,7 @@ struct QPlatformIntegrationFactoryInterface : public QFactoryInterface virtual QPlatformIntegration *create(const QString &key, const QStringList ¶mList) = 0; }; -#define QPlatformIntegrationFactoryInterface_iid "com.nokia.Qt.QPlatformIntegrationFactoryInterface" +#define QPlatformIntegrationFactoryInterface_iid "org.qt-project.Qt.QPlatformIntegrationFactoryInterface" Q_DECLARE_INTERFACE(QPlatformIntegrationFactoryInterface, QPlatformIntegrationFactoryInterface_iid) diff --git a/src/gui/kernel/qplatformthemeplugin_qpa.h b/src/gui/kernel/qplatformthemeplugin_qpa.h index fb4f9f9b7cc..3ce7cc5b022 100644 --- a/src/gui/kernel/qplatformthemeplugin_qpa.h +++ b/src/gui/kernel/qplatformthemeplugin_qpa.h @@ -68,7 +68,7 @@ struct QPlatformThemeFactoryInterface : public QFactoryInterface virtual QPlatformTheme *create(const QString &key, const QStringList ¶mList) = 0; }; -#define QPlatformThemeFactoryInterface_iid "com.nokia.Qt.QPlatformThemeFactoryInterface" +#define QPlatformThemeFactoryInterface_iid "org.qt-project.Qt.QPlatformThemeFactoryInterface" Q_DECLARE_INTERFACE(QPlatformThemeFactoryInterface, QPlatformThemeFactoryInterface_iid) diff --git a/src/plugins/platforms/cocoa/cocoa.json b/src/plugins/platforms/cocoa/cocoa.json new file mode 100644 index 00000000000..520c4f5a506 --- /dev/null +++ b/src/plugins/platforms/cocoa/cocoa.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "cocoa" ] +} diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index 1e803a1c7c6..45dd3525d50 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -59,6 +59,7 @@ LIBS += -framework Cocoa QT += core-private gui-private widgets-private platformsupport-private +OTHER_FILES += cocoa.json target.path += $$[QT_INSTALL_PLUGINS]/platforms INSTALLS += target diff --git a/src/plugins/platforms/cocoa/main.mm b/src/plugins/platforms/cocoa/main.mm index 334a1fefc3d..9857a4e1771 100644 --- a/src/plugins/platforms/cocoa/main.mm +++ b/src/plugins/platforms/cocoa/main.mm @@ -50,6 +50,8 @@ QT_BEGIN_NAMESPACE class QCocoaIntegrationPlugin : public QPlatformIntegrationPlugin { + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformIntegrationFactoryInterface" FILE "cocoa.json") public: QStringList keys() const; QPlatformIntegration *create(const QString&, const QStringList&); @@ -71,6 +73,6 @@ QPlatformIntegration * QCocoaIntegrationPlugin::create(const QString& system, co return 0; } -Q_EXPORT_PLUGIN2(CocoaIntegration, QCocoaIntegrationPlugin) - QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/platforms/minimal/main.cpp b/src/plugins/platforms/minimal/main.cpp index 4d3b3a1362f..8a6e8fb4b09 100644 --- a/src/plugins/platforms/minimal/main.cpp +++ b/src/plugins/platforms/minimal/main.cpp @@ -47,6 +47,8 @@ QT_BEGIN_NAMESPACE class QMinimalIntegrationPlugin : public QPlatformIntegrationPlugin { + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformIntegrationFactoryInterface" FILE "minimal.json") public: QStringList keys() const; QPlatformIntegration *create(const QString&, const QStringList&); @@ -68,6 +70,6 @@ QPlatformIntegration *QMinimalIntegrationPlugin::create(const QString& system, c return 0; } -Q_EXPORT_PLUGIN2(minimal, QMinimalIntegrationPlugin) - QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/platforms/minimal/minimal.json b/src/plugins/platforms/minimal/minimal.json new file mode 100644 index 00000000000..d3cf684b62a --- /dev/null +++ b/src/plugins/platforms/minimal/minimal.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "minimal" ] +} diff --git a/src/plugins/platforms/minimal/minimal.pro b/src/plugins/platforms/minimal/minimal.pro index 392d12d19a5..6430ccde753 100644 --- a/src/plugins/platforms/minimal/minimal.pro +++ b/src/plugins/platforms/minimal/minimal.pro @@ -10,5 +10,7 @@ SOURCES = main.cpp \ HEADERS = qminimalintegration.h \ qminimalbackingstore.h +OTHER_FILES += minimal.json + target.path += $$[QT_INSTALL_PLUGINS]/platforms INSTALLS += target diff --git a/src/plugins/platforms/windows/main.cpp b/src/plugins/platforms/windows/main.cpp index d54a1dbb893..f16eff54497 100644 --- a/src/plugins/platforms/windows/main.cpp +++ b/src/plugins/platforms/windows/main.cpp @@ -100,6 +100,8 @@ QT_BEGIN_NAMESPACE class QWindowsIntegrationPlugin : public QPlatformIntegrationPlugin { + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformIntegrationFactoryInterface" FILE "windows.json") public: QStringList keys() const; QPlatformIntegration *create(const QString&, const QStringList&); @@ -118,6 +120,6 @@ QPlatformIntegration *QWindowsIntegrationPlugin::create(const QString& system, c return 0; } -Q_EXPORT_PLUGIN2(windows, QWindowsIntegrationPlugin) - QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/platforms/windows/windows.json b/src/plugins/platforms/windows/windows.json new file mode 100644 index 00000000000..05032c1b72a --- /dev/null +++ b/src/plugins/platforms/windows/windows.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "windows" ] +} diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro index 58a117b8aff..bb41fe87fc7 100644 --- a/src/plugins/platforms/windows/windows.pro +++ b/src/plugins/platforms/windows/windows.pro @@ -149,5 +149,7 @@ contains(QT_CONFIG, freetype) { } } +OTHER_FILES += windows.json + target.path += $$[QT_INSTALL_PLUGINS]/platforms INSTALLS += target diff --git a/src/plugins/platforms/xcb/main.cpp b/src/plugins/platforms/xcb/main.cpp index 5aa3e921f37..50c5a1a0178 100644 --- a/src/plugins/platforms/xcb/main.cpp +++ b/src/plugins/platforms/xcb/main.cpp @@ -46,6 +46,8 @@ QT_BEGIN_NAMESPACE class QXcbIntegrationPlugin : public QPlatformIntegrationPlugin { + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformIntegrationFactoryInterface" FILE "xcb.json") public: QStringList keys() const; QPlatformIntegration *create(const QString&, const QStringList&); @@ -66,6 +68,6 @@ QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const return 0; } -Q_EXPORT_PLUGIN2(xcb, QXcbIntegrationPlugin) - QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/platforms/xcb/xcb.json b/src/plugins/platforms/xcb/xcb.json new file mode 100644 index 00000000000..dc09d7b54f8 --- /dev/null +++ b/src/plugins/platforms/xcb/xcb.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "xcb" ] +} diff --git a/src/plugins/platforms/xcb/xcb.pro b/src/plugins/platforms/xcb/xcb.pro index 50ca8bf2693..7bad2b4dadc 100644 --- a/src/plugins/platforms/xcb/xcb.pro +++ b/src/plugins/platforms/xcb/xcb.pro @@ -108,5 +108,7 @@ QT += dbus LIBS += -ldbus-1 } +OTHER_FILES += xcb.json + target.path += $$[QT_INSTALL_PLUGINS]/platforms INSTALLS += target From c08fb806bb75db7b7b71103e47d5c6c3287ad011 Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Thu, 16 Feb 2012 09:32:06 +1000 Subject: [PATCH 297/406] Removed rfc3252.txt from networkselftest unittest - no longer needed after test that used it was removed Change-Id: I63fc8a9db07f9250507becb9bf6c2aefe0fdc254 Reviewed-by: Jason McDonald Reviewed-by: Rohan McGovern --- .../other/networkselftest/networkselftest.pro | 11 - tests/auto/other/networkselftest/rfc3252.txt | 899 ------------------ 2 files changed, 910 deletions(-) delete mode 100644 tests/auto/other/networkselftest/rfc3252.txt diff --git a/tests/auto/other/networkselftest/networkselftest.pro b/tests/auto/other/networkselftest/networkselftest.pro index 3cd5f266894..1c0d256dbbb 100644 --- a/tests/auto/other/networkselftest/networkselftest.pro +++ b/tests/auto/other/networkselftest/networkselftest.pro @@ -4,14 +4,3 @@ TARGET = tst_networkselftest SOURCES += tst_networkselftest.cpp QT = core network testlib -wince*: { - addFiles.files = rfc3252.txt - addFiles.path = . - DEPLOYMENT += addFiles - DEFINES += SRCDIR=\\\"\\\" -} else:vxworks*: { - DEFINES += SRCDIR=\\\"\\\" -} else { - DEFINES += SRCDIR=\\\"$$PWD/\\\" -} - diff --git a/tests/auto/other/networkselftest/rfc3252.txt b/tests/auto/other/networkselftest/rfc3252.txt deleted file mode 100644 index b80c61bf0a1..00000000000 --- a/tests/auto/other/networkselftest/rfc3252.txt +++ /dev/null @@ -1,899 +0,0 @@ - - - - - - -Network Working Group H. Kennedy -Request for Comments: 3252 Mimezine -Category: Informational 1 April 2002 - - - Binary Lexical Octet Ad-hoc Transport - -Status of this Memo - - This memo provides information for the Internet community. It does - not specify an Internet standard of any kind. Distribution of this - memo is unlimited. - -Copyright Notice - - Copyright (C) The Internet Society (2002). All Rights Reserved. - -Abstract - - This document defines a reformulation of IP and two transport layer - protocols (TCP and UDP) as XML applications. - -1. Introduction - -1.1. Overview - - This document describes the Binary Lexical Octet Ad-hoc Transport - (BLOAT): a reformulation of a widely-deployed network-layer protocol - (IP [RFC791]), and two associated transport layer protocols (TCP - [RFC793] and UDP [RFC768]) as XML [XML] applications. It also - describes methods for transporting BLOAT over Ethernet and IEEE 802 - networks as well as encapsulating BLOAT in IP for gatewaying BLOAT - across the public Internet. - -1.2. Motivation - - The wild popularity of XML as a basis for application-level protocols - such as the Blocks Extensible Exchange Protocol [RFC3080], the Simple - Object Access Protocol [SOAP], and Jabber [JABBER] prompted - investigation into the possibility of extending the use of XML in the - protocol stack. Using XML at both the transport and network layer in - addition to the application layer would provide for an amazing amount - of power and flexibility while removing dependencies on proprietary - and hard-to-understand binary protocols. This protocol unification - would also allow applications to use a single XML parser for all - aspects of their operation, eliminating developer time spent figuring - out the intricacies of each new protocol, and moving the hard work of - - - - -Kennedy Informational [Page 1] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - parsing to the XML toolset. The use of XML also mitigates concerns - over "network vs. host" byte ordering which is at the root of many - network application bugs. - -1.3. Relation to Existing Protocols - - The reformulations specified in this RFC follow as closely as - possible the spirit of the RFCs on which they are based, and so MAY - contain elements or attributes that would not be needed in a pure - reworking (e.g. length attributes, which are implicit in XML.) - - The layering of network and transport protocols are maintained in - this RFC despite the optimizations that could be made if the line - were somewhat blurred (i.e. merging TCP and IP into a single, larger - element in the DTD) in order to foster future use of this protocol as - a basis for reformulating other protocols (such as ICMP.) - - Other than the encoding, the behavioral aspects of each of the - existing protocols remain unchanged. Routing, address spaces, TCP - congestion control, etc. behave as specified in the extant standards. - Adapting to new standards and experimental algorithm heuristics for - improving performance will become much easier once the move to BLOAT - has been completed. - -1.4. Requirement Levels - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in BCP 14, RFC 2119 - [RFC2119]. - -2. IPoXML - - This protocol MUST be implemented to be compliant with this RFC. - IPoXML is the root protocol REQUIRED for effective use of TCPoXML - (section 3.) and higher-level application protocols. - - The DTD for this document type can be found in section 7.1. - - The routing of IPoXML can be easily implemented on hosts with an XML - parser, as the regular structure lends itself handily to parsing and - validation of the document/datagram and then processing the - destination address, TTL, and checksum before sending it on to its - next-hop. - - The reformulation of IPv4 was chosen over IPv6 [RFC2460] due to the - wider deployment of IPv4 and the fact that implementing IPv6 as XML - would have exceeded the 1500 byte Ethernet MTU. - - - -Kennedy Informational [Page 2] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - All BLOAT implementations MUST use - and specify - the UTF-8 encoding - of RFC 2279 [RFC2279]. All BLOAT document/datagrams MUST be well- - formed and include the XMLDecl. - -2.1. IP Description - - A number of items have changed (for the better) from the original IP - specification. Bit-masks, where present have been converted into - human-readable values. IP addresses are listed in their dotted- - decimal notation [RFC1123]. Length and checksum values are present - as decimal integers. - - To calculate the length and checksum fields of the IP element, a - canonicalized form of the element MUST be used. The canonical form - SHALL have no whitespace (including newline characters) between - elements and only one space character between attributes. There - SHALL NOT be a space following the last attribute in an element. - - An iterative method SHOULD be used to calculate checksums, as the - length field will vary based on the size of the checksum. - - The payload element bears special attention. Due to the character - set restrictions of XML, the payload of IP datagrams (which MAY - contain arbitrary data) MUST be encoded for transport. This RFC - REQUIRES the contents of the payload to be encoded in the base-64 - encoding of RFC 2045 [RFC2045], but removes the requirement that the - encoded output MUST be wrapped on 76-character lines. - - - - - - - - - - - - - - - - - - - - - - - - -Kennedy Informational [Page 3] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - -2.2. Example Datagram - - The following is an example IPoXML datagram with an empty payload: - - - - -

- - - - - - - - - - - - - - - -
- - - - -3. TCPoXML - - This protocol MUST be implemented to be compliant with this RFC. The - DTD for this document type can be found in section 7.2. - -3.1. TCP Description - - A number of items have changed from the original TCP specification. - Bit-masks, where present have been converted into human-readable - values. Length and checksum and port values are present as decimal - integers. - - To calculate the length and checksum fields of the TCP element, a - canonicalized form of the element MUST be used as in section 2.1. - - An iterative method SHOULD be used to calculate checksums as in - section 2.1. - - The payload element MUST be encoded as in section 2.1. - - - -Kennedy Informational [Page 4] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - The TCP offset element was expanded to a maximum of 255 from 16 to - allow for the increased size of the header in XML. - - TCPoXML datagrams encapsulated by IPoXML MAY omit the header - as well as the declaration. - -3.2. Example Datagram - - The following is an example TCPoXML datagram with an empty payload: - - - - - - - - - - - - - - - - - - - - - - - - -4. UDPoXML - - This protocol MUST be implemented to be compliant with this RFC. The - DTD for this document type can be found in section 7.3. - -4.1. UDP Description - - A number of items have changed from the original UDP specification. - Bit-masks, where present have been converted into human-readable - values. Length and checksum and port values are present as decimal - integers. - - - - - - - -Kennedy Informational [Page 5] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - To calculate the length and checksum fields of the UDP element, a - canonicalized form of the element MUST be used as in section 2.1. An - iterative method SHOULD be used to calculate checksums as in section - 2.1. - - The payload element MUST be encoded as in section 2.1. - - UDPoXML datagrams encapsulated by IPoXML MAY omit the header - as well as the declaration. - -4.2. Example Datagram - - The following is an example UDPoXML datagram with an empty payload: - - - - - - - - - - - - - - -5. Network Transport - - This document provides for the transmission of BLOAT datagrams over - two common families of physical layer transport. Future RFCs will - address additional transports as routing vendors catch up to the - specification, and we begin to see BLOAT routed across the Internet - backbone. - -5.1. Ethernet - - BLOAT is encapsulated in Ethernet datagrams as in [RFC894] with the - exception that the type field of the Ethernet frame MUST contain the - value 0xBEEF. The first 5 octets of the Ethernet frame payload will - be 0x3c 3f 78 6d 6c (" - --> - - - - -Kennedy Informational [Page 7] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Kennedy Informational [Page 9] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - - - - - - - - - - - - - - - - - - - - - - -Kennedy Informational [Page 10] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - - - - - - - - - - - -7.2. TCPoXML DTD - - - - - - - - - - - - - - - - - -Kennedy Informational [Page 11] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Kennedy Informational [Page 12] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - - - - - - - - - - - - - - - - - - -7.3. UDPoXML DTD - - - - - - - - - - - - - - - -Kennedy Informational [Page 13] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - -8. Security Considerations - - XML, as a subset of SGML, has the same security considerations as - specified in SGML Media Types [RFC1874]. Security considerations - that apply to IP, TCP and UDP also likely apply to BLOAT as it does - not attempt to correct for issues not related to message format. - -9. References - - [JABBER] Miller, J., "Jabber", draft-miller-jabber-00.txt, - February 2002. (Work in Progress) - - [RFC768] Postel, J., "User Datagram Protocol", STD 6, RFC 768, - August 1980. - - [RFC791] Postel, J., "Internet Protocol", STD 5, RFC 791, - September 1981. - - [RFC793] Postel, J., "Transmission Control Protocol", STD 7, RFC - 793, September 1981. - - [RFC894] Hornig, C., "Standard for the Transmission of IP - Datagrams over Ethernet Networks.", RFC 894, April 1984. - - [RFC1042] Postel, J. and J. Reynolds, "Standard for the - Transmission of IP Datagrams Over IEEE 802 Networks", STD - 43, RFC 1042, February 1988. - - [RFC1123] Braden, R., "Requirements for Internet Hosts - - Application and Support", RFC 1123, October 1989. - - [RFC1874] Levinson, E., "SGML Media Types", RFC 1874, December - 1995. - - [RFC2003] Perkins, C., "IP Encapsulation within IP", RFC 2003, - October 1996. - - [RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail - Extensions (MIME) Part One: Format of Internet Message - Bodies", RFC 2045, November 1996. - - [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - - [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO - 10646", RFC 2279, January 1998. - - - - - -Kennedy Informational [Page 14] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - [RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6 - (IPv6) Specification", RFC 2460, December 1998. - - [RFC3080] Rose, M., "The Blocks Extensible Exchange Protocol Core", - RFC 3080, March 2001. - - [SOAP] Box, D., Ehnebuske, D., Kakivaya, G., Layman, A., - Mendelsohn, N., Nielsen, H. F., Thatte, S. Winer, D., - "Simple Object Access Protocol (SOAP) 1.1" World Wide Web - Consortium Note, May 2000 http://www.w3.org/TR/SOAP/ - - [XML] Bray, T., Paoli, J., Sperberg-McQueen, C. M., "Extensible - Markup Language (XML)" World Wide Web Consortium - Recommendation REC- xml-19980210. - http://www.w3.org/TR/1998/REC-xml-19980210 - -10. Author's Address - - Hugh Kennedy - Mimezine - 1060 West Addison - Chicago, IL 60613 - USA - - EMail: kennedyh@engin.umich.edu - - - - - - - - - - - - - - - - - - - - - - - - - - -Kennedy Informational [Page 15] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - -11. Full Copyright Statement - - Copyright (C) The Internet Society (2002). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - - - - - - - - - - - - - - - -Kennedy Informational [Page 16] - From d0759e348dd4d49b2e7e3907776406e93374ea40 Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Tue, 14 Feb 2012 11:46:03 +1000 Subject: [PATCH 298/406] Changed qnetworkreply unittest to work from install directory - made subdir test depend on echo - remove SRCDIR and changed to use TESTDATA and QFINDTESTDATA - added waitForFinish() to handle slow networks - removed core module header from echo subprogram and replaced with needed header only - Added ipv6 skip to connectToIPV6Address() if not available - Added check QT_BUILD_INTERNAL and skip tests if backend not available - Skip permission tests if run as root - Removed win32 debug and release directory locations so that application is in known location relative to test data Change-Id: I58c3c2fca3cd2fee72fdb81d016bb4fd7fe08ac2 Reviewed-by: Rohan McGovern --- .../access/qnetworkreply/echo/main.cpp | 3 +- .../access/qnetworkreply/qnetworkreply.pro | 3 +- .../access/qnetworkreply/test/test.pro | 25 +- .../qnetworkreply/tst_qnetworkreply.cpp | 501 ++++++++---------- 4 files changed, 243 insertions(+), 289 deletions(-) diff --git a/tests/auto/network/access/qnetworkreply/echo/main.cpp b/tests/auto/network/access/qnetworkreply/echo/main.cpp index 8e6811d2ff6..90217e49233 100644 --- a/tests/auto/network/access/qnetworkreply/echo/main.cpp +++ b/tests/auto/network/access/qnetworkreply/echo/main.cpp @@ -39,8 +39,7 @@ ** ****************************************************************************/ - -#include +#include int main(int argc, char **) { diff --git a/tests/auto/network/access/qnetworkreply/qnetworkreply.pro b/tests/auto/network/access/qnetworkreply/qnetworkreply.pro index 0bcf067c4f3..885e7f15b67 100644 --- a/tests/auto/network/access/qnetworkreply/qnetworkreply.pro +++ b/tests/auto/network/access/qnetworkreply/qnetworkreply.pro @@ -1,4 +1,5 @@ TEMPLATE = subdirs -SUBDIRS = test !wince*:SUBDIRS += echo +test.depends += $$SUBDIRS +SUBDIRS += test diff --git a/tests/auto/network/access/qnetworkreply/test/test.pro b/tests/auto/network/access/qnetworkreply/test/test.pro index 56b8acc6e56..f267b096313 100644 --- a/tests/auto/network/access/qnetworkreply/test/test.pro +++ b/tests/auto/network/access/qnetworkreply/test/test.pro @@ -5,28 +5,13 @@ TARGET = ../tst_qnetworkreply contains(QT_CONFIG,xcb): CONFIG+=insignificant_test # unstable, QTBUG-21102 -win32 { - CONFIG(debug, debug|release) { - TARGET = ../../debug/tst_qnetworkreply -} else { - TARGET = ../../release/tst_qnetworkreply - } -} - -DEFINES += SRCDIR=\\\"$$PWD/..\\\" - QT = core-private network-private testlib RESOURCES += ../qnetworkreply.qrc -wince* { - # For cross compiled targets, reference data files need to be deployed - addFiles.files = ../empty ../rfc3252.txt ../resource ../bigfile ../*.jpg - addFiles.path = . - DEPLOYMENT += addFiles - - certFiles.files = ../certs - certFiles.path = . - DEPLOYMENT += certFiles -} +contains(QT_CONFIG,ipv6ifname): DEFINES += HAVE_IPV6 +TESTDATA += ../empty ../rfc3252.txt ../resource ../bigfile ../*.jpg ../certs \ + ../index.html ../smb-file.txt win32:CONFIG += insignificant_test # QTBUG-24226 +load(testcase) # for target.path and installTestHelperApp() +installTestHelperApp("../echo/echo",echo,echo) diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 61f44c5c09f..279613904f9 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -163,6 +163,7 @@ public: QString runCustomRequest(const QNetworkRequest &request, QNetworkReplyPtr &reply, const QByteArray &verb, QIODevice *data); + int waitForFinish(QNetworkReplyPtr &reply); public Q_SLOTS: void finished(); @@ -397,6 +398,8 @@ private Q_SLOTS: // NOTE: This test must be last! void parentingRepliesToTheApp(); +private: + QString testDataDir; }; bool tst_QNetworkReply::seedCreated = false; @@ -450,9 +453,13 @@ QT_END_NAMESPACE #ifndef QT_NO_OPENSSL static void setupSslServer(QSslSocket* serverSocket) { + QString testDataDir = QFileInfo(QFINDTESTDATA("rfc3252.txt")).absolutePath(); + if (testDataDir.isEmpty()) + testDataDir = QCoreApplication::applicationDirPath(); + serverSocket->setProtocol(QSsl::AnyProtocol); - serverSocket->setLocalCertificate(SRCDIR "/certs/server.pem"); - serverSocket->setPrivateKey(SRCDIR "/certs/server.key"); + serverSocket->setLocalCertificate(testDataDir + "/certs/server.pem"); + serverSocket->setPrivateKey(testDataDir + "/certs/server.key"); } #endif @@ -1235,9 +1242,18 @@ QString tst_QNetworkReply::runSimpleRequest(QNetworkAccessManager::Operation op, connect(reply, SIGNAL(finished()), SLOT(finished())); connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(gotError())); + int count = 0; loop = new QEventLoop; - QTimer::singleShot(20000, loop, SLOT(quit())); - code = returnCode == Timeout ? loop->exec() : returnCode; + QSignalSpy spy(reply, SIGNAL(downloadProgress(qint64,qint64))); + while (!reply->isFinished()) { + QTimer::singleShot(20000, loop, SLOT(quit())); + code = loop->exec(); + if (count == spy.count() && !reply->isFinished()) { + code = Timeout; + break; + } + count = spy.count(); + } delete loop; loop = 0; } @@ -1277,6 +1293,31 @@ QString tst_QNetworkReply::runCustomRequest(const QNetworkRequest &request, return QString(); } +int tst_QNetworkReply::waitForFinish(QNetworkReplyPtr &reply) +{ + int code = Success; + int count = 0; + + connect(reply, SIGNAL(finished()), SLOT(finished())); + connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(gotError())); + + loop = new QEventLoop; + QSignalSpy spy(reply, SIGNAL(downloadProgress(qint64,qint64))); + while (!reply->isFinished()) { + QTimer::singleShot(10000, loop, SLOT(quit())); + code = loop->exec(); + if (count == spy.count() && !reply->isFinished()) { + code = Timeout; + break; + } + count = spy.count(); + } + delete loop; + loop = 0; + + return code; +} + void tst_QNetworkReply::finished() { loop->exit(returnCode = Success); @@ -1290,16 +1331,20 @@ void tst_QNetworkReply::gotError() void tst_QNetworkReply::initTestCase() { + testDataDir = QFileInfo(QFINDTESTDATA("rfc3252.txt")).absolutePath(); + if (testDataDir.isEmpty()) + testDataDir = QCoreApplication::applicationDirPath(); + QVERIFY(QtNetworkSettings::verifyTestNetworkSettings()); #if !defined Q_OS_WIN - wronlyFileName = QDir::currentPath() + "/write-only"; + wronlyFileName = testDataDir + "/write-only"; QFile wr(wronlyFileName); QVERIFY(wr.open(QIODevice::WriteOnly | QIODevice::Truncate)); wr.setPermissions(QFile::WriteOwner | QFile::WriteUser); wr.close(); #endif - QDir::setSearchPaths("srcdir", QStringList() << SRCDIR); + QDir::setSearchPaths("testdata", QStringList() << testDataDir); #ifndef QT_NO_OPENSSL QSslSocket::defaultCaCertificates(); //preload certificates #endif @@ -1536,10 +1581,10 @@ void tst_QNetworkReply::getFromFileSpecial_data() QTest::addColumn("url"); QTest::newRow("resource") << ":/resource" << "qrc:/resource"; - QTest::newRow("search-path") << "srcdir:/rfc3252.txt" << "srcdir:/rfc3252.txt"; - QTest::newRow("bigfile-path") << "srcdir:/bigfile" << "srcdir:/bigfile"; + QTest::newRow("search-path") << "testdata:/rfc3252.txt" << "testdata:/rfc3252.txt"; + QTest::newRow("bigfile-path") << "testdata:/bigfile" << "testdata:/bigfile"; #ifdef Q_OS_WIN - QTest::newRow("smb-path") << "srcdir:/smb-file.txt" << "file://" + QtNetworkSettings::winServerName() + "/testshare/test.pri"; + QTest::newRow("smb-path") << "testdata:/smb-file.txt" << "file://" + QtNetworkSettings::winServerName() + "/testshare/test.pri"; #endif } @@ -1569,8 +1614,8 @@ void tst_QNetworkReply::getFromFtp_data() QTest::addColumn("referenceName"); QTest::addColumn("url"); - QTest::newRow("rfc3252.txt") << SRCDIR "/rfc3252.txt" << "ftp://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"; - QTest::newRow("bigfile") << SRCDIR "/bigfile" << "ftp://" + QtNetworkSettings::serverName() + "/qtest/bigfile"; + QTest::newRow("rfc3252.txt") << (testDataDir + "/rfc3252.txt") << "ftp://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"; + QTest::newRow("bigfile") << (testDataDir + "/bigfile") << "ftp://" + QtNetworkSettings::serverName() + "/qtest/bigfile"; } void tst_QNetworkReply::getFromFtp() @@ -1597,9 +1642,9 @@ void tst_QNetworkReply::getFromHttp_data() QTest::addColumn("referenceName"); QTest::addColumn("url"); - QTest::newRow("success-internal") << SRCDIR "/rfc3252.txt" << "http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"; - QTest::newRow("success-external") << SRCDIR "/rfc3252.txt" << "http://www.ietf.org/rfc/rfc3252.txt"; - QTest::newRow("bigfile-internal") << SRCDIR "/bigfile" << "http://" + QtNetworkSettings::serverName() + "/qtest/bigfile"; + QTest::newRow("success-internal") << (testDataDir + "/rfc3252.txt") << "http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"; + QTest::newRow("success-external") << (testDataDir + "/rfc3252.txt") << "http://www.ietf.org/rfc/rfc3252.txt"; + QTest::newRow("bigfile-internal") << (testDataDir + "/bigfile") << "http://" + QtNetworkSettings::serverName() + "/qtest/bigfile"; } void tst_QNetworkReply::getFromHttp() @@ -1636,9 +1681,9 @@ void tst_QNetworkReply::headFromHttp_data() QTest::addColumn("contentType"); QTest::addColumn("proxy"); - qint64 rfcsize = QFileInfo(SRCDIR "/rfc3252.txt").size(); - qint64 bigfilesize = QFileInfo(SRCDIR "/bigfile").size(); - qint64 indexsize = QFileInfo(SRCDIR "/index.html").size(); + qint64 rfcsize = QFileInfo(testDataDir + "/rfc3252.txt").size(); + qint64 bigfilesize = QFileInfo(testDataDir + "/bigfile").size(); + qint64 indexsize = QFileInfo(testDataDir + "/index.html").size(); //testing proxies, mainly for the 407 response from http proxy for (int i = 0; i < proxies.count(); ++i) { @@ -1697,7 +1742,7 @@ void tst_QNetworkReply::getErrors_data() // empties QTest::newRow("empty-url") << QString() << int(QNetworkReply::ProtocolUnknownError) << 0 << true; - QTest::newRow("empty-scheme-host") << SRCDIR "/rfc3252.txt" << int(QNetworkReply::ProtocolUnknownError) << 0 << true; + QTest::newRow("empty-scheme-host") << (testDataDir + "/rfc3252.txt") << int(QNetworkReply::ProtocolUnknownError) << 0 << true; QTest::newRow("empty-scheme") << "//" + QtNetworkSettings::winServerName() + "/testshare/test.pri" << int(QNetworkReply::ProtocolUnknownError) << 0 << true; @@ -1750,6 +1795,14 @@ void tst_QNetworkReply::getErrors() QFETCH(QString, url); QNetworkRequest request(url); +#ifdef Q_OS_UNIX + if ((qstrcmp(QTest::currentDataTag(), "file-is-wronly") == 0) || + (qstrcmp(QTest::currentDataTag(), "file-permissions") == 0)) { + if (::getuid() == 0) + QSKIP("Running this test as root doesn't make sense"); + } +#endif + QNetworkReplyPtr reply = manager.get(request); reply->setParent(this); // we have expect-fails @@ -1757,11 +1810,7 @@ void tst_QNetworkReply::getErrors() QCOMPARE(reply->error(), QNetworkReply::NoError); // now run the request: - connect(reply, SIGNAL(finished()), - &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); - //qDebug() << reply->errorString(); + QVERIFY(waitForFinish(reply) != Timeout); QFETCH(int, error); QEXPECT_FAIL("ftp-is-dir", "QFtp cannot provide enough detail", Abort); @@ -1867,7 +1916,14 @@ void tst_QNetworkReply::putToFtp() QNetworkReply *r = qnam.get(req); QObject::connect(r, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); + int count = 0; + QSignalSpy spy(r, SIGNAL(downloadProgress(qint64,qint64))); + while (!r->isFinished()) { + QTestEventLoop::instance().enterLoop(10); + if (count == spy.count() && !r->isFinished()) + break; + count = spy.count(); + } QObject::disconnect(r, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); QByteArray uploaded = r->readAll(); @@ -2111,7 +2167,7 @@ void tst_QNetworkReply::postToHttpMultipart_data() imagePart11.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"testImage\"")); imagePart11.setRawHeader("Content-Location", "http://my.test.location.tld"); imagePart11.setRawHeader("Content-ID", "my@id.tld"); - QFile *file11 = new QFile(SRCDIR "/image1.jpg"); + QFile *file11 = new QFile(testDataDir + "/image1.jpg"); file11->open(QIODevice::ReadOnly); imagePart11.setBodyDevice(file11); QHttpMultiPart *imageMultiPart1 = new QHttpMultiPart(QHttpMultiPart::FormDataType); @@ -2125,7 +2181,7 @@ void tst_QNetworkReply::postToHttpMultipart_data() imagePart21.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"testImage1\"")); imagePart21.setRawHeader("Content-Location", "http://my.test.location.tld"); imagePart21.setRawHeader("Content-ID", "my@id.tld"); - QFile *file21 = new QFile(SRCDIR "/image1.jpg"); + QFile *file21 = new QFile(testDataDir + "/image1.jpg"); file21->open(QIODevice::ReadOnly); imagePart21.setBodyDevice(file21); QHttpMultiPart *imageMultiPart2 = new QHttpMultiPart(); @@ -2136,7 +2192,7 @@ void tst_QNetworkReply::postToHttpMultipart_data() QHttpPart imagePart22; imagePart22.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); imagePart22.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"testImage2\"")); - QFile *file22 = new QFile(SRCDIR "/image2.jpg"); + QFile *file22 = new QFile(testDataDir + "/image2.jpg"); file22->open(QIODevice::ReadOnly); imagePart22.setBodyDevice(file22); imageMultiPart2->append(imagePart22); @@ -2152,7 +2208,7 @@ void tst_QNetworkReply::postToHttpMultipart_data() imagePart31.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"testImage1\"")); imagePart31.setRawHeader("Content-Location", "http://my.test.location.tld"); imagePart31.setRawHeader("Content-ID", "my@id.tld"); - QFile *file31 = new QFile(SRCDIR "/image1.jpg"); + QFile *file31 = new QFile(testDataDir + "/image1.jpg"); file31->open(QIODevice::ReadOnly); imagePart31.setBodyDevice(file31); QHttpMultiPart *imageMultiPart3 = new QHttpMultiPart(QHttpMultiPart::FormDataType); @@ -2161,7 +2217,7 @@ void tst_QNetworkReply::postToHttpMultipart_data() QHttpPart imagePart32; imagePart32.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); imagePart32.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"testImage2\"")); - QFile *file32 = new QFile(SRCDIR "/image2.jpg"); + QFile *file32 = new QFile(testDataDir + "/image2.jpg"); file32->open(QIODevice::ReadOnly); imagePart32.setBodyDevice(file31); // check that resetting works imagePart32.setBodyDevice(file32); @@ -2170,7 +2226,7 @@ void tst_QNetworkReply::postToHttpMultipart_data() QHttpPart imagePart33; imagePart33.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); imagePart33.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"testImage3\"")); - QFile *file33 = new QFile(SRCDIR "/image3.jpg"); + QFile *file33 = new QFile(testDataDir + "/image3.jpg"); file33->open(QIODevice::ReadOnly); imagePart33.setBodyDevice(file33); imageMultiPart3->append(imagePart33); @@ -2185,7 +2241,7 @@ void tst_QNetworkReply::postToHttpMultipart_data() // QHttpPart imagePart41; // imagePart41.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); -// QFile *file41 = new QFile(SRCDIR "/image1.jpg"); +// QFile *file41 = new QFile(testDataDir + "/image1.jpg"); // file41->open(QIODevice::ReadOnly); // imagePart41.setBodyDevice(file41); // @@ -2219,7 +2275,7 @@ void tst_QNetworkReply::postToHttpMultipart_data() QHttpPart imagePart51; imagePart51.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); imagePart51.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"testImage\"")); - QFile *file51 = new QFile(SRCDIR "/image1.jpg"); + QFile *file51 = new QFile(testDataDir + "/image1.jpg"); file51->open(QIODevice::ReadOnly); QByteArray imageData = file51->readAll(); file51->close(); @@ -2426,6 +2482,10 @@ void tst_QNetworkReply::connectToIPv6Address() QFETCH(QByteArray, dataToSend); QFETCH(QByteArray, hostfield); +#if !defined(HAVE_IPV6) && defined(Q_OS_UNIX) + QSKIP("system doesn't support ipv6!"); +#endif + QByteArray httpResponse = QByteArray("HTTP/1.0 200 OK\r\nContent-Length: "); httpResponse += QByteArray::number(dataToSend.size()); httpResponse += "\r\n\r\n"; @@ -2438,9 +2498,7 @@ void tst_QNetworkReply::connectToIPv6Address() QNetworkRequest request(url); QNetworkReplyPtr reply = manager.get(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); QByteArray content = reply->readAll(); //qDebug() << server.receivedData; QByteArray hostinfo = "\r\nHost: " + hostfield + ":" + QByteArray::number(server.serverPort()) + "\r\n"; @@ -2607,7 +2665,7 @@ void tst_QNetworkReply::ioGetFromFtp_data() QTest::newRow("bigfile") << "bigfile" << Q_INT64_C(519240); - QFile file(SRCDIR "/rfc3252.txt"); + QFile file(testDataDir + "/rfc3252.txt"); QTest::newRow("rfc3252.txt") << "rfc3252.txt" << file.size(); } @@ -2621,9 +2679,7 @@ void tst_QNetworkReply::ioGetFromFtp() QNetworkReplyPtr reply = manager.get(request); DataReader reader(reply); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->url(), request.url()); QCOMPARE(reply->error(), QNetworkReply::NoError); @@ -2638,7 +2694,7 @@ void tst_QNetworkReply::ioGetFromFtp() void tst_QNetworkReply::ioGetFromFtpWithReuse() { - QString fileName = SRCDIR "/rfc3252.txt"; + QString fileName = testDataDir + "/rfc3252.txt"; QFile reference(fileName); reference.open(QIODevice::ReadOnly); @@ -2651,14 +2707,8 @@ void tst_QNetworkReply::ioGetFromFtpWithReuse() DataReader reader2(reply2); QSignalSpy spy(reply1, SIGNAL(finished())); - connect(reply2, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); - if (spy.count() == 0) { - connect(reply1, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); - } + QVERIFY(waitForFinish(reply1) == Success); + QVERIFY(waitForFinish(reply2) == Success); QCOMPARE(reply1->url(), request.url()); QCOMPARE(reply2->url(), request.url()); @@ -2677,16 +2727,14 @@ void tst_QNetworkReply::ioGetFromFtpWithReuse() void tst_QNetworkReply::ioGetFromHttp() { - QFile reference(SRCDIR "/rfc3252.txt"); + QFile reference(testDataDir + "/rfc3252.txt"); QVERIFY(reference.open(QIODevice::ReadOnly)); QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); QNetworkReplyPtr reply = manager.get(request); DataReader reader(reply); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->url(), request.url()); QCOMPARE(reply->error(), QNetworkReply::NoError); @@ -2700,7 +2748,7 @@ void tst_QNetworkReply::ioGetFromHttp() void tst_QNetworkReply::ioGetFromHttpWithReuseParallel() { - QFile reference(SRCDIR "/rfc3252.txt"); + QFile reference(testDataDir + "/rfc3252.txt"); QVERIFY(reference.open(QIODevice::ReadOnly)); QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); @@ -2710,14 +2758,8 @@ void tst_QNetworkReply::ioGetFromHttpWithReuseParallel() DataReader reader2(reply2); QSignalSpy spy(reply1, SIGNAL(finished())); - connect(reply2, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); - if (spy.count() == 0) { - connect(reply1, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); - } + QVERIFY(waitForFinish(reply2) == Success); + QVERIFY(waitForFinish(reply1) == Success); QCOMPARE(reply1->url(), request.url()); QCOMPARE(reply2->url(), request.url()); @@ -2738,7 +2780,7 @@ void tst_QNetworkReply::ioGetFromHttpWithReuseParallel() void tst_QNetworkReply::ioGetFromHttpWithReuseSequential() { - QFile reference(SRCDIR "/rfc3252.txt"); + QFile reference(testDataDir + "/rfc3252.txt"); QVERIFY(reference.open(QIODevice::ReadOnly)); QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); @@ -2746,9 +2788,7 @@ void tst_QNetworkReply::ioGetFromHttpWithReuseSequential() QNetworkReplyPtr reply = manager.get(request); DataReader reader(reply); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->url(), request.url()); QCOMPARE(reply->error(), QNetworkReply::NoError); @@ -2766,9 +2806,7 @@ void tst_QNetworkReply::ioGetFromHttpWithReuseSequential() QNetworkReplyPtr reply = manager.get(request); DataReader reader(reply); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->url(), request.url()); QCOMPARE(reply->error(), QNetworkReply::NoError); @@ -2786,7 +2824,7 @@ void tst_QNetworkReply::ioGetFromHttpWithAuth_data() QTest::addColumn("url"); QTest::addColumn("expectedData"); - QFile reference(SRCDIR "/rfc3252.txt"); + QFile reference(testDataDir + "/rfc3252.txt"); reference.open(QIODevice::ReadOnly); QByteArray referenceData = reference.readAll(); QTest::newRow("basic") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt") << referenceData; @@ -2813,14 +2851,9 @@ void tst_QNetworkReply::ioGetFromHttpWithAuth() connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); - connect(reply2, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); - if (finishedspy.count() == 0) { - connect(reply1, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); - } + QVERIFY(waitForFinish(reply2) == Success); + QVERIFY(waitForFinish(reply1) == Success); + manager.disconnect(SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); @@ -2840,9 +2873,9 @@ void tst_QNetworkReply::ioGetFromHttpWithAuth() QSignalSpy authspy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(waitForFinish(reply) == Success); + manager.disconnect(SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); @@ -2898,7 +2931,7 @@ void tst_QNetworkReply::ioGetFromHttpWithProxyAuth() // This test sends three requests // The first two in parallel // The third after the first two finished - QFile reference(SRCDIR "/rfc3252.txt"); + QFile reference(testDataDir + "/rfc3252.txt"); QVERIFY(reference.open(QIODevice::ReadOnly)); QNetworkProxy proxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129); @@ -2917,14 +2950,9 @@ void tst_QNetworkReply::ioGetFromHttpWithProxyAuth() connect(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); - connect(reply2, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); - if (finishedspy.count() == 0) { - connect(reply1, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); - } + QVERIFY(waitForFinish(reply2) == Success); + QVERIFY(waitForFinish(reply1) == Success); + manager.disconnect(SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); @@ -2948,9 +2976,9 @@ void tst_QNetworkReply::ioGetFromHttpWithProxyAuth() QSignalSpy authspy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); connect(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(waitForFinish(reply) == Success); + manager.disconnect(SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); @@ -3010,7 +3038,7 @@ void tst_QNetworkReply::ioGetFromHttpWithSocksProxy() qRegisterMetaType(); // for QSignalSpy qRegisterMetaType(); - QFile reference(SRCDIR "/rfc3252.txt"); + QFile reference(testDataDir + "/rfc3252.txt"); QVERIFY(reference.open(QIODevice::ReadOnly)); QNetworkProxy proxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080); @@ -3024,9 +3052,9 @@ void tst_QNetworkReply::ioGetFromHttpWithSocksProxy() QSignalSpy authspy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); connect(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(waitForFinish(reply) == Success); + manager.disconnect(SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); @@ -3047,9 +3075,9 @@ void tst_QNetworkReply::ioGetFromHttpWithSocksProxy() QSignalSpy authspy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); connect(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(waitForFinish(reply) == Failure); + manager.disconnect(SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); @@ -3070,7 +3098,7 @@ void tst_QNetworkReply::ioGetFromHttpsWithSslErrors() qRegisterMetaType(); // for QSignalSpy qRegisterMetaType >(); - QFile reference(SRCDIR "/rfc3252.txt"); + QFile reference(testDataDir + "/rfc3252.txt"); QVERIFY(reference.open(QIODevice::ReadOnly)); QNetworkRequest request(QUrl("https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); @@ -3082,9 +3110,8 @@ void tst_QNetworkReply::ioGetFromHttpsWithSslErrors() SLOT(sslErrors(QNetworkReply*,QList))); connect(reply, SIGNAL(metaDataChanged()), SLOT(storeSslConfiguration())); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); + manager.disconnect(SIGNAL(sslErrors(QNetworkReply*,QList)), this, SLOT(sslErrors(QNetworkReply*,QList))); @@ -3105,7 +3132,7 @@ void tst_QNetworkReply::ioGetFromHttpsWithIgnoreSslErrors() qRegisterMetaType(); // for QSignalSpy qRegisterMetaType >(); - QFile reference(SRCDIR "/rfc3252.txt"); + QFile reference(testDataDir + "/rfc3252.txt"); QVERIFY(reference.open(QIODevice::ReadOnly)); QNetworkRequest request(QUrl("https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); @@ -3116,9 +3143,8 @@ void tst_QNetworkReply::ioGetFromHttpsWithIgnoreSslErrors() QSignalSpy sslspy(&manager, SIGNAL(sslErrors(QNetworkReply*,QList))); connect(reply, SIGNAL(metaDataChanged()), SLOT(storeSslConfiguration())); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); QCOMPARE(reader.data, reference.readAll()); @@ -3134,7 +3160,7 @@ void tst_QNetworkReply::ioGetFromHttpsWithSslHandshakeError() qRegisterMetaType(); // for QSignalSpy qRegisterMetaType >(); - QFile reference(SRCDIR "/rfc3252.txt"); + QFile reference(testDataDir + "/rfc3252.txt"); QVERIFY(reference.open(QIODevice::ReadOnly)); QNetworkRequest request(QUrl("https://" + QtNetworkSettings::serverName() + ":80")); @@ -3145,9 +3171,8 @@ void tst_QNetworkReply::ioGetFromHttpsWithSslHandshakeError() QSignalSpy sslspy(&manager, SIGNAL(sslErrors(QNetworkReply*,QList))); connect(reply, SIGNAL(metaDataChanged()), SLOT(storeSslConfiguration())); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(waitForFinish(reply) == Failure); QCOMPARE(reply->error(), QNetworkReply::SslHandshakeFailedError); QCOMPARE(sslspy.count(), 0); @@ -3205,10 +3230,7 @@ void tst_QNetworkReply::ioGetFromHttpBrokenServer() QNetworkReplyPtr reply = manager.get(request); QSignalSpy spy(reply, SIGNAL(error(QNetworkReply::NetworkError))); - - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Failure); QCOMPARE(reply->url(), request.url()); QCOMPARE(spy.count(), 1); @@ -3238,9 +3260,7 @@ void tst_QNetworkReply::ioGetFromHttpStatus100() QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); QNetworkReplyPtr reply = manager.get(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->url(), request.url()); QCOMPARE(reply->error(), QNetworkReply::NoError); @@ -3263,9 +3283,7 @@ void tst_QNetworkReply::ioGetFromHttpNoHeaders() QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); QNetworkReplyPtr reply = manager.get(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->url(), request.url()); QCOMPARE(reply->error(), QNetworkReply::NoError); @@ -3434,9 +3452,7 @@ void tst_QNetworkReply::ioGetFromHttpWithCache() QNetworkReplyPtr reply = manager.get(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) != Timeout); QTEST(reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool(), "loadedFromCache"); QTEST(server.totalConnections > 0, "networkUsed"); @@ -3649,7 +3665,7 @@ void tst_QNetworkReply::ioGetWithManyProxies() qRegisterMetaType(); // for QSignalSpy qRegisterMetaType(); - QFile reference(SRCDIR "/rfc3252.txt"); + QFile reference(testDataDir + "/rfc3252.txt"); QVERIFY(reference.open(QIODevice::ReadOnly)); // set the proxy factory: @@ -3667,13 +3683,12 @@ void tst_QNetworkReply::ioGetWithManyProxies() QSignalSpy authspy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); connect(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); #ifndef QT_NO_OPENSSL connect(&manager, SIGNAL(sslErrors(QNetworkReply*,QList)), SLOT(sslErrors(QNetworkReply*,QList))); #endif - QTestEventLoop::instance().enterLoop(15); - QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(waitForFinish(reply) != Timeout); manager.disconnect(SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); @@ -3714,10 +3729,10 @@ void tst_QNetworkReply::ioPutToFileFromFile_data() { QTest::addColumn("fileName"); - QTest::newRow("empty") << SRCDIR "/empty"; - QTest::newRow("real-file") << SRCDIR "/rfc3252.txt"; + QTest::newRow("empty") << (testDataDir + "/empty"); + QTest::newRow("real-file") << (testDataDir + "/rfc3252.txt"); QTest::newRow("resource") << ":/resource"; - QTest::newRow("search-path") << "srcdir:/rfc3252.txt"; + QTest::newRow("search-path") << "testdata:/rfc3252.txt"; } void tst_QNetworkReply::ioPutToFileFromFile() @@ -3732,9 +3747,7 @@ void tst_QNetworkReply::ioPutToFileFromFile() QNetworkRequest request(url); QNetworkReplyPtr reply = manager.put(request, &sourceFile); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->url(), url); QCOMPARE(reply->error(), QNetworkReply::NoError); @@ -3770,10 +3783,8 @@ void tst_QNetworkReply::ioPutToFileFromSocket() QNetworkReplyPtr reply = manager.put(QNetworkRequest(url), socketpair.endPoints[1]); socketpair.endPoints[0]->close(); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->error(), QNetworkReply::NoError); - QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(reply->url(), url); QCOMPARE(reply->error(), QNetworkReply::NoError); @@ -3816,10 +3827,8 @@ void tst_QNetworkReply::ioPutToFileFromLocalSocket() QNetworkReplyPtr reply = manager.put(QNetworkRequest(url), passive); passive->setParent(reply); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->error(), QNetworkReply::NoError); - QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(reply->url(), url); QCOMPARE(reply->error(), QNetworkReply::NoError); @@ -3866,9 +3875,7 @@ void tst_QNetworkReply::ioPutToFileFromProcess() QNetworkReplyPtr reply = manager.put(QNetworkRequest(url), &process); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->url(), url); QCOMPARE(reply->error(), QNetworkReply::NoError); @@ -3902,9 +3909,7 @@ void tst_QNetworkReply::ioPutToFtpFromFile() QNetworkRequest request(url); QNetworkReplyPtr reply = manager.put(request, &sourceFile); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->url(), url); QCOMPARE(reply->error(), QNetworkReply::NoError); @@ -3953,9 +3958,7 @@ void tst_QNetworkReply::ioPutToHttpFromFile() QNetworkRequest request(url); QNetworkReplyPtr reply = manager.put(request, &sourceFile); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->url(), url); QCOMPARE(reply->error(), QNetworkReply::NoError); @@ -3969,9 +3972,8 @@ void tst_QNetworkReply::ioPutToHttpFromFile() // download the file again from HTTP to make sure it was uploaded // correctly reply = manager.get(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->url(), url); QCOMPARE(reply->error(), QNetworkReply::NoError); @@ -3997,9 +3999,7 @@ void tst_QNetworkReply::ioPostToHttpFromFile() QNetworkReplyPtr reply = manager.post(request, &sourceFile); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->url(), url); QCOMPARE(reply->error(), QNetworkReply::NoError); @@ -4077,7 +4077,6 @@ void tst_QNetworkReply::ioPostToHttpFromSocket() QNetworkReplyPtr reply = manager.post(request, socketpair.endPoints[1]); socketpair.endPoints[0]->close(); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); connect(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), @@ -4086,13 +4085,13 @@ void tst_QNetworkReply::ioPostToHttpFromSocket() QSignalSpy authenticationRequiredSpy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); QSignalSpy proxyAuthenticationRequiredSpy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); - QTestEventLoop::instance().enterLoop(12); + QVERIFY(waitForFinish(reply) == Success); + disconnect(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); disconnect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); QCOMPARE(reply->error(), QNetworkReply::NoError); - QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(reply->url(), url); QCOMPARE(reply->error(), QNetworkReply::NoError); @@ -4170,7 +4169,7 @@ void tst_QNetworkReply::ioPostToHttpFromSocketSynchronous() // worked. void tst_QNetworkReply::ioPostToHttpFromMiddleOfFileToEnd() { - QFile sourceFile(SRCDIR "/rfc3252.txt"); + QFile sourceFile(testDataDir + "/rfc3252.txt"); QVERIFY(sourceFile.open(QIODevice::ReadOnly)); // seeking to the middle sourceFile.seek(sourceFile.size() / 2); @@ -4180,14 +4179,13 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfFileToEnd() request.setRawHeader("Content-Type", "application/octet-stream"); QNetworkReplyPtr reply = manager.post(request, &sourceFile); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); - QTestEventLoop::instance().enterLoop(2); + QVERIFY(waitForFinish(reply) == Success); + disconnect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); - QVERIFY(!QTestEventLoop::instance().timeout()); // compare half data sourceFile.seek(sourceFile.size() / 2); @@ -4197,7 +4195,7 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfFileToEnd() void tst_QNetworkReply::ioPostToHttpFromMiddleOfFileFiveBytes() { - QFile sourceFile(SRCDIR "/rfc3252.txt"); + QFile sourceFile(testDataDir + "/rfc3252.txt"); QVERIFY(sourceFile.open(QIODevice::ReadOnly)); // seeking to the middle sourceFile.seek(sourceFile.size() / 2); @@ -4210,14 +4208,13 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfFileFiveBytes() QVERIFY(request.header(QNetworkRequest::ContentLengthHeader).isValid()); QNetworkReplyPtr reply = manager.post(request, &sourceFile); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); - QTestEventLoop::instance().enterLoop(2); + QVERIFY(waitForFinish(reply) == Success); + disconnect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); - QVERIFY(!QTestEventLoop::instance().timeout()); // compare half data sourceFile.seek(sourceFile.size() / 2); @@ -4239,14 +4236,13 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfQBufferFiveBytes() request.setRawHeader("Content-Type", "application/octet-stream"); QNetworkReplyPtr reply = manager.post(request, &uploadBuffer); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); - QTestEventLoop::instance().enterLoop(2); + QVERIFY(waitForFinish(reply) == Success); + disconnect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); - QVERIFY(!QTestEventLoop::instance().timeout()); // compare half data uploadBuffer.seek(5); @@ -4273,11 +4269,11 @@ void tst_QNetworkReply::ioPostToHttpNoBufferFlag() QNetworkReplyPtr reply = manager.post(request, socketpair.endPoints[1]); socketpair.endPoints[0]->close(); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); - QTestEventLoop::instance().enterLoop(2); + QVERIFY(waitForFinish(reply) == Failure); + disconnect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); @@ -4295,12 +4291,16 @@ public: serverSocket->setParent(this); if (serverSocket->setSocketDescriptor(socketDescriptor)) { + QString testDataDir = QFileInfo(QFINDTESTDATA("rfc3252.txt")).absolutePath(); + if (testDataDir.isEmpty()) + testDataDir = QCoreApplication::applicationDirPath(); + connect(serverSocket, SIGNAL(encrypted()), this, SLOT(encryptedSlot())); connect(serverSocket, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); serverSocket->setProtocol(QSsl::AnyProtocol); connect(serverSocket, SIGNAL(sslErrors(const QList&)), serverSocket, SLOT(ignoreSslErrors())); - serverSocket->setLocalCertificate(SRCDIR "/certs/server.pem"); - serverSocket->setPrivateKey(SRCDIR "/certs/server.key"); + serverSocket->setLocalCertificate(testDataDir + "/certs/server.pem"); + serverSocket->setPrivateKey(testDataDir + "/certs/server.key"); serverSocket->startServerEncryption(); } else { delete serverSocket; @@ -4325,7 +4325,7 @@ public: // very similar to ioPostToHttpUploadProgress but for SSL void tst_QNetworkReply::ioPostToHttpsUploadProgress() { - //QFile sourceFile(SRCDIR "/bigfile"); + //QFile sourceFile(testDataDir + "/bigfile"); //QVERIFY(sourceFile.open(QIODevice::ReadOnly)); qint64 wantedSize = 2*1024*1024; // 2 MB QByteArray sourceFile; @@ -4377,13 +4377,11 @@ void tst_QNetworkReply::ioPostToHttpsUploadProgress() QCOMPARE(args3.at(0).toLongLong(), qint64(sourceFile.size())); // after sending this, the QNAM should emit finished() - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); incomingSocket->write("HTTP/1.0 200 OK\r\n"); incomingSocket->write("Content-Length: 0\r\n"); incomingSocket->write("\r\n"); - QTestEventLoop::instance().enterLoop(10); - // not timeouted -> finished() was emitted - QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(waitForFinish(reply) == Success); incomingSocket->close(); server.close(); @@ -4440,10 +4438,11 @@ void tst_QNetworkReply::ioGetFromBuiltinHttp() const int rate = 200; // in kB per sec RateControlledReader reader(server, reply, rate, bufferSize); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); QTime loopTime; loopTime.start(); - QTestEventLoop::instance().enterLoop(30); + + QVERIFY(waitForFinish(reply) == Success); + const int elapsedTime = loopTime.elapsed(); server.wait(); reader.wrapUp(); @@ -4452,8 +4451,6 @@ void tst_QNetworkReply::ioGetFromBuiltinHttp() qDebug() << "receive rate:" << reader.totalBytesRead * 1000 / elapsedTime << "(it received" << reader.totalBytesRead << "bytes in" << elapsedTime << "ms)"; - QVERIFY(!QTestEventLoop::instance().timeout()); - QCOMPARE(reply->url(), request.url()); QCOMPARE(reply->error(), QNetworkReply::NoError); QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); @@ -4483,7 +4480,7 @@ void tst_QNetworkReply::ioGetFromBuiltinHttp() void tst_QNetworkReply::ioPostToHttpUploadProgress() { - QFile sourceFile(SRCDIR "/bigfile"); + QFile sourceFile(testDataDir + "/bigfile"); QVERIFY(sourceFile.open(QIODevice::ReadOnly)); // emulate a minimal http server @@ -4588,16 +4585,15 @@ void tst_QNetworkReply::ioPostToHttpEmptyUploadProgress() void tst_QNetworkReply::lastModifiedHeaderForFile() { - QFileInfo fileInfo(SRCDIR "/bigfile"); + QFileInfo fileInfo(testDataDir + "/bigfile"); QVERIFY(fileInfo.exists()); QUrl url = QUrl::fromLocalFile(fileInfo.filePath()); QNetworkRequest request(url); QNetworkReplyPtr reply = manager.head(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(waitForFinish(reply) == Success); QDateTime header = reply->header(QNetworkRequest::LastModifiedHeader).toDateTime(); QCOMPARE(header, fileInfo.lastModified()); @@ -4610,9 +4606,8 @@ void tst_QNetworkReply::lastModifiedHeaderForHttp() QNetworkRequest request(url); QNetworkReplyPtr reply = manager.head(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(waitForFinish(reply) == Success); QDateTime header = reply->header(QNetworkRequest::LastModifiedHeader).toDateTime(); QDateTime realDate = QDateTime::fromString("2007-05-22T12:04:57", Qt::ISODate); @@ -4626,9 +4621,8 @@ void tst_QNetworkReply::httpCanReadLine() QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); QNetworkReplyPtr reply = manager.get(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); + QCOMPARE(reply->error(), QNetworkReply::NoError); QVERIFY(reply->canReadLine()); @@ -4656,13 +4650,16 @@ void tst_QNetworkReply::rateControl() // faster than the data is being consumed. QFETCH(int, rate); +#if !defined(QT_BUILD_INTERNAL) + QSKIP("backend for testing not available!"); +#endif + // ask for 20 seconds worth of data FastSender sender(20 * rate * 1024); QNetworkRequest request("debugpipe://localhost:" + QString::number(sender.serverPort())); QNetworkReplyPtr reply = manager.get(request); reply->setReadBufferSize(32768); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); qRegisterMetaType("QNetworkReply::NetworkError"); QSignalSpy errorSpy(reply, SIGNAL(error(QNetworkReply::NetworkError))); @@ -4671,7 +4668,9 @@ void tst_QNetworkReply::rateControl() // this test is designed to run for 25 seconds at most QTime loopTime; loopTime.start(); - QTestEventLoop::instance().enterLoop(40); + + QVERIFY(waitForFinish(reply) == Success); + int elapsedTime = loopTime.elapsed(); if (!errorSpy.isEmpty()) { @@ -4683,7 +4682,6 @@ void tst_QNetworkReply::rateControl() << "(it received" << reader.totalBytesRead << "bytes in" << elapsedTime << "ms)"; sender.wait(); - QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(reply->url(), request.url()); QCOMPARE(reply->error(), QNetworkReply::NoError); @@ -4706,6 +4704,9 @@ void tst_QNetworkReply::downloadProgress_data() void tst_QNetworkReply::downloadProgress() { +#if !defined(QT_BUILD_INTERNAL) + QSKIP("backend for testing not available!"); +#endif QTcpServer server; QVERIFY(server.listen()); @@ -4769,6 +4770,9 @@ void tst_QNetworkReply::uploadProgress_data() void tst_QNetworkReply::uploadProgress() { QFETCH(QByteArray, data); +#if !defined(QT_BUILD_INTERNAL) + QSKIP("backend for testing not available!"); +#endif QTcpServer server; QVERIFY(server.listen()); @@ -4787,9 +4791,7 @@ void tst_QNetworkReply::uploadProgress() QTcpSocket *receiver = server.nextPendingConnection(); if (finished.count() == 0) { // it's not finished yet, so wait for it to be - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(2); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); } delete receiver; @@ -4825,9 +4827,7 @@ void tst_QNetworkReply::chaining() request.setUrl(url); QNetworkReplyPtr putReply = manager.put(request, getReply); - connect(putReply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(putReply) == Success); QCOMPARE(getReply->url(), QUrl::fromLocalFile(sourceFile.fileName())); QCOMPARE(getReply->error(), QNetworkReply::NoError); @@ -5108,11 +5108,7 @@ void tst_QNetworkReply::httpProxyCommands() //manager.setProxy(QNetworkProxy()); // wait for the finished signal - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - - QTestEventLoop::instance().enterLoop(15); - - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) != Timeout); //qDebug() << reply->error() << reply->errorString(); //qDebug() << proxyServer.receivedData; @@ -5245,9 +5241,8 @@ void tst_QNetworkReply::proxyChange() manager.setProxy(dummyProxy); QNetworkReplyPtr reply3 = manager.get(req); - connect(reply3, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(5); - QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(waitForFinish(reply3) == Failure); QVERIFY(int(reply3->error()) > 0); } @@ -5283,10 +5278,7 @@ void tst_QNetworkReply::authorizationError() QSignalSpy errorSpy(reply, SIGNAL(error(QNetworkReply::NetworkError))); QSignalSpy finishedSpy(reply, SIGNAL(finished())); // now run the request: - connect(reply, SIGNAL(finished()), - &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Failure); QFETCH(int, errorSignalCount); QCOMPARE(errorSpy.count(), errorSignalCount); @@ -5512,8 +5504,7 @@ void tst_QNetworkReply::ignoreSslErrorsList_data() QTest::addColumn("expectedNetworkError"); QList expectedSslErrors; - // apparently, because of some weird behaviour of SRCDIR, the file name below needs to start with a slash - QList certs = QSslCertificate::fromPath(QLatin1String(SRCDIR "/certs/qt-test-server-cacert.pem")); + QList certs = QSslCertificate::fromPath(testDataDir + "/certs/qt-test-server-cacert.pem"); QSslError rightError(QSslError::SelfSignedCertificate, certs.at(0)); QSslError wrongError(QSslError::SelfSignedCertificate); @@ -5537,9 +5528,7 @@ void tst_QNetworkReply::ignoreSslErrorsList() QFETCH(QList, expectedSslErrors); reply->ignoreSslErrors(expectedSslErrors); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) != Timeout); QFETCH(QNetworkReply::NetworkError, expectedNetworkError); QCOMPARE(reply->error(), expectedNetworkError); @@ -5570,9 +5559,7 @@ void tst_QNetworkReply::ignoreSslErrorsListWithSlot() this, SLOT(ignoreSslErrorListSlot(QNetworkReply *, const QList &))); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) != Timeout); QFETCH(QNetworkReply::NetworkError, expectedNetworkError); QCOMPARE(reply->error(), expectedNetworkError); @@ -5586,7 +5573,7 @@ void tst_QNetworkReply::sslConfiguration_data() QTest::newRow("empty") << QSslConfiguration() << false; QSslConfiguration conf = QSslConfiguration::defaultConfiguration(); QTest::newRow("default") << conf << false; // does not contain test server cert - QList testServerCert = QSslCertificate::fromPath(SRCDIR "/certs/qt-test-server-cacert.pem"); + QList testServerCert = QSslCertificate::fromPath(testDataDir + "/certs/qt-test-server-cacert.pem"); conf.setCaCertificates(testServerCert); QTest::newRow("set-root-cert") << conf << true; conf.setProtocol(QSsl::SecureProtocols); @@ -5600,9 +5587,7 @@ void tst_QNetworkReply::sslConfiguration() request.setSslConfiguration(configuration); QNetworkReplyPtr reply = manager.get(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) != Timeout); QFETCH(bool, works); QNetworkReply::NetworkError expectedError = works ? QNetworkReply::NoError : QNetworkReply::SslHandshakeFailedError; @@ -5686,12 +5671,11 @@ void tst_QNetworkReply::getFromHttpIntoBuffer() QNetworkAccessManager manager; QNetworkReply *reply = manager.get(request); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); QVERIFY(!QTestEventLoop::instance().timeout()); QVERIFY(reply->isFinished()); - QFile reference(SRCDIR "/rfc3252.txt"); + QFile reference(testDataDir + "/rfc3252.txt"); QVERIFY(reference.open(QIODevice::ReadOnly)); QCOMPARE(reference.bytesAvailable(), reply->bytesAvailable()); @@ -5897,9 +5881,7 @@ void tst_QNetworkReply::getFromHttpIntoBufferCanReadLine() request.setAttribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute, 1024*1024*128); // 128 MB is max allowed QNetworkReplyPtr reply = manager.get(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->error(), QNetworkReply::NoError); QVERIFY(reply->canReadLine()); @@ -5923,9 +5905,7 @@ void tst_QNetworkReply::ioGetFromHttpWithoutContentLength() QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); QNetworkReplyPtr reply = manager.get(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->url(), request.url()); QVERIFY(reply->isFinished()); @@ -5973,9 +5953,7 @@ void tst_QNetworkReply::qtbug12908compressedHttpReply() QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); QNetworkReplyPtr reply = manager.get(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); QCOMPARE(reply->error(), QNetworkReply::NoError); QCOMPARE(reply->size(), qint64(16384)); @@ -5998,9 +5976,7 @@ void tst_QNetworkReply::compressedHttpReplyBrokenGzip() QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); QNetworkReplyPtr reply = manager.get(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Failure); QCOMPARE(reply->error(), QNetworkReply::ProtocolFailure); } @@ -6013,9 +5989,7 @@ void tst_QNetworkReply::getFromUnreachableIp() QNetworkRequest request(QUrl("http://255.255.255.255/42/23/narf/narf/narf")); QNetworkReplyPtr reply = manager.get(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Failure); QVERIFY(reply->error() != QNetworkReply::NoError); } @@ -6348,9 +6322,8 @@ void tst_QNetworkReply::qtbug15311doubleContentLength() QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); QNetworkReplyPtr reply = manager.get(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); + QVERIFY(reply->isFinished()); QCOMPARE(reply->error(), QNetworkReply::NoError); QCOMPARE(reply->size(), qint64(3)); @@ -6368,9 +6341,8 @@ void tst_QNetworkReply::qtbug18232gzipContentLengthZero() QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); QNetworkReplyPtr reply = manager.get(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); + QVERIFY(reply->isFinished()); QCOMPARE(reply->error(), QNetworkReply::NoError); QCOMPARE(reply->size(), qint64(0)); @@ -6390,9 +6362,8 @@ void tst_QNetworkReply::qtbug22660gzipNoContentLengthEmptyContent() QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); QNetworkReplyPtr reply = manager.get(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); + QVERIFY(reply->isFinished()); QCOMPARE(reply->error(), QNetworkReply::NoError); QCOMPARE(reply->size(), qint64(0)); @@ -6411,13 +6382,13 @@ void tst_QNetworkReply::synchronousRequest_data() QTest::newRow("http") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt") - << QString("file:" SRCDIR "/rfc3252.txt") + << QString("file:" + testDataDir + "/rfc3252.txt") << true << QString("text/plain"); QTest::newRow("http-gzip") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/deflate/rfc3252.txt") - << QString("file:" SRCDIR "/rfc3252.txt") + << QString("file:" + testDataDir + "/rfc3252.txt") << false // don't check content length, because it's gzip encoded // ### we would need to enflate (un-deflate) the file content and compare the sizes << QString("text/plain"); @@ -6425,7 +6396,7 @@ void tst_QNetworkReply::synchronousRequest_data() #ifndef QT_NO_OPENSSL QTest::newRow("https") << QUrl("https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt") - << QString("file:" SRCDIR "/rfc3252.txt") + << QString("file:" + testDataDir + "/rfc3252.txt") << true << QString("text/plain"); #endif @@ -6437,8 +6408,8 @@ void tst_QNetworkReply::synchronousRequest_data() << QString("text/plain"); QTest::newRow("simple-file") - << QUrl::fromLocalFile(SRCDIR "/rfc3252.txt") - << QString("file:" SRCDIR "/rfc3252.txt") + << QUrl::fromLocalFile(testDataDir + "/rfc3252.txt") + << QString("file:" + testDataDir + "/rfc3252.txt") << true << QString(); } @@ -6460,7 +6431,7 @@ void tst_QNetworkReply::synchronousRequest() // QNetworkRequest, see http://bugreports.qt.nokia.com/browse/QTBUG-14774 if (url.scheme() == "https") { QSslConfiguration sslConf; - QList certs = QSslCertificate::fromPath(SRCDIR "/certs/qt-test-server-cacert.pem"); + QList certs = QSslCertificate::fromPath(testDataDir + "/certs/qt-test-server-cacert.pem"); sslConf.setCaCertificates(certs); request.setSslConfiguration(sslConf); } @@ -6570,8 +6541,9 @@ void tst_QNetworkReply::httpAbort() // Abort after the finished() QNetworkRequest request3("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"); QNetworkReplyPtr reply3 = manager.get(request3); - connect(reply3, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); + + QVERIFY(waitForFinish(reply3) == Success); + QVERIFY(reply3->isFinished()); reply3->abort(); QCOMPARE(reply3->error(), QNetworkReply::NoError); @@ -6601,9 +6573,7 @@ void tst_QNetworkReply::dontInsertPartialContentIntoTheCache() QNetworkReplyPtr reply = manager.get(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); QVERIFY(server.totalConnections > 0); QCOMPARE(reply->readAll().constData(), "load"); @@ -6620,9 +6590,8 @@ void tst_QNetworkReply::httpUserAgent() request.setHeader(QNetworkRequest::UserAgentHeader, "abcDEFghi"); QNetworkReplyPtr reply = manager.get(request); - connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(waitForFinish(reply) == Success); + QVERIFY(reply->isFinished()); QCOMPARE(reply->error(), QNetworkReply::NoError); QVERIFY(server.receivedData.contains("\r\nUser-Agent: abcDEFghi\r\n")); From 147a38faa6afbe616a9e6a123c8dbb5b00e458ef Mon Sep 17 00:00:00 2001 From: Lincoln Ramsay Date: Fri, 17 Feb 2012 16:31:06 +1000 Subject: [PATCH 299/406] Static plugins don't break QFactoryLoader::keys() The = means that a single, static, compat plugin replaces the list of keys (eg. from previously checked static plugins or from dynamic plugins). Using += prevents this undesirable behaviour. Change-Id: I3a40752c08dddbfe81444ca9c782b633e9742ab9 Reviewed-by: Bradley T. Hughes Reviewed-by: Lars Knoll --- src/corelib/plugin/qfactoryloader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index ce988fa2ff9..2d31e1da7ee 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -244,7 +244,7 @@ QStringList QFactoryLoader::keys() const QObject *instance = staticPlugins.at(i).instance(); QFactoryInterface *factory = qobject_cast(instance); if (instance && factory && instance->qt_metacast(d->iid)) - keys = factory->keys(); + keys += factory->keys(); } } return keys; From e3363fd945b3ab961fba720ee013533dd8ba2930 Mon Sep 17 00:00:00 2001 From: Rafael Roquetto Date: Wed, 15 Feb 2012 16:52:43 +0100 Subject: [PATCH 300/406] Enables QProcess back on QNX. Because fork()/vfork() on QNX are not supported on multithreaded applications, QProcess had been disabled on this platform. The corresponding code has now been replaced with functions that wrap around spawn(). Change-Id: I46091b7d41f322a5cad07d17893aa929c84941ef Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- src/corelib/global/qglobal.h | 2 - src/corelib/io/qprocess.cpp | 13 ++- src/corelib/io/qprocess_p.h | 4 +- src/corelib/io/qprocess_unix.cpp | 159 ++++++++++++++++++++++++++++--- 4 files changed, 160 insertions(+), 18 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 22e73ede26c..7330a49939a 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1751,8 +1751,6 @@ Q_CORE_EXPORT int qrand(); # define QT_NO_QWS_SHARE_FONTS # define QT_NO_SYSTEMSEMAPHORE # define QT_NO_SHAREDMEMORY -// QNX currently doesn't support forking in a thread, so disable QProcess -# define QT_NO_PROCESS #endif #if defined (__ELF__) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 0a0097c8877..1312e9b55f5 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -520,6 +520,11 @@ void QProcessPrivate::Channel::clear() setWorkingDirectory(). By default, processes are run in the current working directory of the calling process. + \note On QNX, setting the working directory may cause all + application threads, with the exception of the QProcess caller + thread, to momentaneusly freeze, owing to a limitation in + the operating system. + \section1 Synchronous Process API QProcess provides a set of functions which allow it to be used @@ -1433,6 +1438,9 @@ QString QProcess::workingDirectory() const process in this directory. The default behavior is to start the process in the working directory of the calling process. + \note On QNX, this may cause all application threads to + momentaneusly freeze. + \sa workingDirectory(), start() */ void QProcess::setWorkingDirectory(const QString &dir) @@ -1755,7 +1763,7 @@ void QProcess::setProcessState(ProcessState state) exit(). \warning This function is called by QProcess on Unix and Mac OS X - only. On Windows, it is not called. + only. On Windows and QNX, it is not called. */ void QProcess::setupChildProcess() { @@ -2149,6 +2157,9 @@ int QProcess::execute(const QString &program) The process will be started in the directory \a workingDirectory. + \note On QNX, this may cause all application threads to + momentaneusly freeze. + If the function is successful then *\a pid is set to the process identifier of the started process. */ diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index 236e716b340..311b5ce8458 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -304,8 +304,10 @@ public: #endif void startProcess(); -#if defined(Q_OS_UNIX) +#if defined(Q_OS_UNIX) && !defined(Q_OS_QNX) void execChild(const char *workingDirectory, char **path, char **argv, char **envp); +#elif defined(Q_OS_QNX) + pid_t spawnChild(const char *workingDirectory, char **argv, char **envp); #endif bool processStarted(); void terminateProcess(); diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 9e35978c772..2da2913c6f3 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -48,6 +48,7 @@ #include "qstring.h" #include + /* Returns a human readable representation of the first \a len characters in \a data. @@ -105,6 +106,10 @@ QT_END_NAMESPACE #include #include #include +#ifdef Q_OS_QNX +#include +#include +#endif QT_BEGIN_NAMESPACE @@ -538,16 +543,6 @@ static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environm return envp; } -// under QNX RTOS we have to use vfork() when multithreading -inline pid_t qt_fork() -{ -#if defined(Q_OS_QNX) - return vfork(); -#else - return fork(); -#endif -} - void QProcessPrivate::startProcess() { Q_Q(QProcess); @@ -664,8 +659,12 @@ void QProcessPrivate::startProcess() // Start the process manager, and fork off the child process. processManager()->lock(); - pid_t childPid = qt_fork(); +#if defined(Q_OS_QNX) + pid_t childPid = spawnChild(workingDirPtr, argv, envp); +#else + pid_t childPid = fork(); int lastForkErrno = errno; +#endif if (childPid != 0) { // Clean up duplicated memory. free(dupProgramName); @@ -679,10 +678,22 @@ void QProcessPrivate::startProcess() delete [] envp; delete [] path; } + + // This is not a valid check under QNX, because the semantics are + // different. While under other platforms where fork() may succeed and exec() can still fail, + // causing the childPid to hold a valid value (and thus evaluating the + // following if to false), and then signaling the error via + // childStartedPipe, under QNX on the other hand, spawn() return value will be assigned + // to childPid (which will be -1 in case of failure). This will force + // QProcess to cleanup, instead of signaling the error via + // childStartedPipe. Since it will invalidade the pipes, functions like + // QProcess::waitForStarted() will fail, for childStartedPipe will be + // '-1' and mess with the select() calls. +#if !defined(Q_OS_QNX) if (childPid < 0) { // Cleanup, report error and return #if defined (QPROCESS_DEBUG) - qDebug("qt_fork failed: %s", qPrintable(qt_error_string(lastForkErrno))); + qDebug("fork failed: %s", qPrintable(qt_error_string(lastForkErrno))); #endif processManager()->unlock(); q->setProcessState(QProcess::NotRunning); @@ -698,6 +709,7 @@ void QProcessPrivate::startProcess() execChild(workingDirPtr, path, argv, envp); ::_exit(-1); } +#endif // Register the child. In the mean time, we can get a SIGCHLD, so we need // to keep the lock held to avoid a race to catch the child. @@ -735,6 +747,87 @@ void QProcessPrivate::startProcess() ::fcntl(stderrChannel.pipe[0], F_SETFL, ::fcntl(stderrChannel.pipe[0], F_GETFL) | O_NONBLOCK); } +#if defined(Q_OS_QNX) +static pid_t doSpawn(int fd_count, int fd_map[], char **argv, char **envp, + const char *workingDir, bool spawn_detached) +{ + // A multi threaded QNX Process can't fork so we call spawn() instead. + + struct inheritance inherit; + memset(&inherit, 0, sizeof(inherit)); + inherit.flags |= SPAWN_SETSID; + inherit.flags |= SPAWN_CHECK_SCRIPT; + if (spawn_detached) + inherit.flags |= SPAWN_NOZOMBIE; + inherit.flags |= SPAWN_SETSIGDEF; + sigaddset(&inherit.sigdefault, SIGPIPE); // reset the signal that we ignored + + // enter the working directory + const char *oldWorkingDir = 0; + char buff[PATH_MAX + 1]; + + if (workingDir) { + //we need to freeze everyone in order to avoid race conditions with //chdir(). + if (ThreadCtl(_NTO_TCTL_THREADS_HOLD, 0) == -1) + qWarning("ThreadCtl(): cannot hold threads: %s", qPrintable(qt_error_string(errno))); + + oldWorkingDir = QT_GETCWD(buff, PATH_MAX + 1); + QT_CHDIR(workingDir); + } + + pid_t childPid; + EINTR_LOOP(childPid, ::spawn(argv[0], fd_count, fd_map, &inherit, argv, envp)); + if (childPid == -1) { + inherit.flags |= SPAWN_SEARCH_PATH; + EINTR_LOOP(childPid, ::spawn(argv[0], fd_count, fd_map, &inherit, argv, envp)); + } + + if (oldWorkingDir) { + QT_CHDIR(oldWorkingDir); + + if (ThreadCtl(_NTO_TCTL_THREADS_CONT, 0) == -1) + qFatal("ThreadCtl(): cannot resume threads: %s", qPrintable(qt_error_string(errno))); + } + + return childPid; +} + +pid_t QProcessPrivate::spawnChild(const char *workingDir, char **argv, char **envp) +{ + const int fd_count = 3; + int fd_map[fd_count]; + switch (processChannelMode) { + case QProcess::ForwardedChannels: + fd_map[0] = stdinChannel.pipe[0]; + fd_map[1] = QT_FILENO(stdout); + fd_map[2] = QT_FILENO(stderr); + break; + case QProcess::MergedChannels: + fd_map[0] = stdinChannel.pipe[0]; + fd_map[1] = stdoutChannel.pipe[1]; + fd_map[2] = stdoutChannel.pipe[1]; + break; + case QProcess::SeparateChannels: + fd_map[0] = stdinChannel.pipe[0]; + fd_map[1] = stdoutChannel.pipe[1]; + fd_map[2] = stderrChannel.pipe[1]; + break; + } + + pid_t childPid = doSpawn(fd_count, fd_map, argv, envp, workingDir, false); + + if (childPid == -1) { + QString error = qt_error_string(errno); + qt_safe_write(childStartedPipe[1], error.data(), error.length() * sizeof(QChar)); + qt_safe_close(childStartedPipe[1]); + childStartedPipe[1] = -1; + } + + return childPid; +} + +#else + void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv, char **envp) { ::signal(SIGPIPE, SIG_DFL); // reset the signal that we ignored @@ -797,6 +890,7 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv qt_safe_close(childStartedPipe[1]); childStartedPipe[1] = -1; } +#endif bool QProcessPrivate::processStarted() { @@ -1213,6 +1307,42 @@ void QProcessPrivate::_q_notified() { } +#if defined(Q_OS_QNX) +bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, qint64 *pid) +{ + const int fd_count = 3; + int fd_map[fd_count] = { QT_FILENO(stdin), QT_FILENO(stdout), QT_FILENO(stderr) }; + + QList enc_args; + enc_args.append(QFile::encodeName(program)); + for (int i = 0; i < arguments.size(); ++i) + enc_args.append(arguments.at(i).toLocal8Bit()); + + const int argc = enc_args.size(); + QScopedArrayPointer raw_argv(new char*[argc + 1]); + for (int i = 0; i < argc; ++i) + raw_argv[i] = const_cast(enc_args.at(i).data()); + raw_argv[argc] = 0; + + char **envp = 0; // inherit environment + + // Encode the working directory if it's non-empty, otherwise just pass 0. + const char *workingDirPtr = 0; + QByteArray encodedWorkingDirectory; + if (!workingDirectory.isEmpty()) { + encodedWorkingDirectory = QFile::encodeName(workingDirectory); + workingDirPtr = encodedWorkingDirectory.constData(); + } + + pid_t childPid = doSpawn(fd_count, fd_map, raw_argv.data(), envp, workingDirPtr, true); + if (pid && childPid != -1) + *pid = childPid; + + return childPid != -1; +} + +#else + bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, qint64 *pid) { processManager()->start(); @@ -1226,7 +1356,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a int pidPipe[2]; qt_safe_pipe(pidPipe); - pid_t childPid = qt_fork(); + pid_t childPid = fork(); if (childPid == 0) { struct sigaction noaction; memset(&noaction, 0, sizeof(noaction)); @@ -1238,7 +1368,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a qt_safe_close(startedPipe[0]); qt_safe_close(pidPipe[0]); - pid_t doubleForkPid = qt_fork(); + pid_t doubleForkPid = fork(); if (doubleForkPid == 0) { qt_safe_close(pidPipe[1]); @@ -1326,6 +1456,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a qt_safe_close(pidPipe[0]); return success; } +#endif void QProcessPrivate::initializeProcessManager() { From 963b4c1647299fd023ddbe7c4a25ac404e303c5d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 9 Feb 2012 21:34:26 +0100 Subject: [PATCH 301/406] Convert GIF plugin to the new format Change-Id: I3adf1d2402a07213cb4cb5193c465bd820919bd1 Reviewed-by: Thiago Macieira --- src/plugins/imageformats/gif/gif.json | 3 ++ src/plugins/imageformats/gif/gif.pro | 2 + src/plugins/imageformats/gif/main.cpp | 15 +------ src/plugins/imageformats/gif/main.h | 65 +++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 13 deletions(-) create mode 100644 src/plugins/imageformats/gif/gif.json create mode 100644 src/plugins/imageformats/gif/main.h diff --git a/src/plugins/imageformats/gif/gif.json b/src/plugins/imageformats/gif/gif.json new file mode 100644 index 00000000000..b599b40ffe0 --- /dev/null +++ b/src/plugins/imageformats/gif/gif.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "gif" ] +} diff --git a/src/plugins/imageformats/gif/gif.pro b/src/plugins/imageformats/gif/gif.pro index a4cde20c6fc..b85ee984ac6 100644 --- a/src/plugins/imageformats/gif/gif.pro +++ b/src/plugins/imageformats/gif/gif.pro @@ -3,6 +3,8 @@ load(qt_plugin) include(../../../gui/image/qgifhandler.pri) SOURCES += $$PWD/main.cpp +HEADERS += $$PWD/main.h +OTHER_FILES += gif.json DESTDIR = $$QT.gui.plugins/imageformats target.path += $$[QT_INSTALL_PLUGINS]/imageformats diff --git a/src/plugins/imageformats/gif/main.cpp b/src/plugins/imageformats/gif/main.cpp index 0b6c99a9e4c..9dd61c44996 100644 --- a/src/plugins/imageformats/gif/main.cpp +++ b/src/plugins/imageformats/gif/main.cpp @@ -44,6 +44,8 @@ #ifndef QT_NO_IMAGEFORMATPLUGIN +#include "main.h" + #ifdef QT_NO_IMAGEFORMAT_GIF #undef QT_NO_IMAGEFORMAT_GIF #endif @@ -51,16 +53,6 @@ QT_BEGIN_NAMESPACE -class QGifPlugin : public QImageIOPlugin -{ -public: - QGifPlugin(); - ~QGifPlugin(); - - QStringList keys() const; - Capabilities capabilities(QIODevice *device, const QByteArray &format) const; - QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const; -}; QGifPlugin::QGifPlugin() { @@ -90,9 +82,6 @@ QImageIOHandler *QGifPlugin::create(QIODevice *device, const QByteArray &format) return handler; } -Q_EXPORT_STATIC_PLUGIN(QGifPlugin) -Q_EXPORT_PLUGIN2(qgif, QGifPlugin) - #endif // QT_NO_IMAGEFORMATPLUGIN QT_END_NAMESPACE diff --git a/src/plugins/imageformats/gif/main.h b/src/plugins/imageformats/gif/main.h new file mode 100644 index 00000000000..97335b19685 --- /dev/null +++ b/src/plugins/imageformats/gif/main.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins 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 +#include + +#ifdef QT_NO_IMAGEFORMAT_GIF +#undef QT_NO_IMAGEFORMAT_GIF +#endif +#include + +QT_BEGIN_NAMESPACE + +class QGifPlugin : public QImageIOPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "gif.json") +public: + QGifPlugin(); + ~QGifPlugin(); + + QStringList keys() const; + Capabilities capabilities(QIODevice *device, const QByteArray &format) const; + QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const; +}; + +QT_END_NAMESPACE From 8fddd96d422f72255936fcb898f8ff36f779840a Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 10 Feb 2012 10:54:01 +0100 Subject: [PATCH 302/406] Convert ico plugin to new format. Change-Id: Ib0fb7bb9f853e39cd62b693bb5b43ae15f750d84 Reviewed-by: Thiago Macieira --- src/plugins/imageformats/ico/ico.json | 3 ++ src/plugins/imageformats/ico/ico.pro | 3 +- src/plugins/imageformats/ico/main.cpp | 18 +------- src/plugins/imageformats/ico/main.h | 66 +++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 18 deletions(-) create mode 100644 src/plugins/imageformats/ico/ico.json create mode 100644 src/plugins/imageformats/ico/main.h diff --git a/src/plugins/imageformats/ico/ico.json b/src/plugins/imageformats/ico/ico.json new file mode 100644 index 00000000000..d22cb739a1b --- /dev/null +++ b/src/plugins/imageformats/ico/ico.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "ico" ] +} diff --git a/src/plugins/imageformats/ico/ico.pro b/src/plugins/imageformats/ico/ico.pro index c0972fe189c..242e42b8697 100644 --- a/src/plugins/imageformats/ico/ico.pro +++ b/src/plugins/imageformats/ico/ico.pro @@ -3,9 +3,10 @@ load(qt_plugin) QTDIR_build:REQUIRES = "!contains(QT_CONFIG, no-ico)" -HEADERS += qicohandler.h +HEADERS += qicohandler.h main.h SOURCES += main.cpp \ qicohandler.cpp +OTHER_FILES += ico.json DESTDIR = $$QT.gui.plugins/imageformats target.path += $$[QT_INSTALL_PLUGINS]/imageformats diff --git a/src/plugins/imageformats/ico/main.cpp b/src/plugins/imageformats/ico/main.cpp index 5ebb24d06e7..9c9525f48f5 100644 --- a/src/plugins/imageformats/ico/main.cpp +++ b/src/plugins/imageformats/ico/main.cpp @@ -39,26 +39,12 @@ ** ****************************************************************************/ -#include -#include +#include "main.h" #ifndef QT_NO_IMAGEFORMATPLUGIN -#ifdef QT_NO_IMAGEFORMAT_ICO -#undef QT_NO_IMAGEFORMAT_ICO -#endif -#include "qicohandler.h" - QT_BEGIN_NAMESPACE -class QICOPlugin : public QImageIOPlugin -{ -public: - QStringList keys() const; - Capabilities capabilities(QIODevice *device, const QByteArray &format) const; - QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const; -}; - QStringList QICOPlugin::keys() const { return QStringList() << QLatin1String("ico"); @@ -89,8 +75,6 @@ QImageIOHandler *QICOPlugin::create(QIODevice *device, const QByteArray &format) return handler; } -Q_EXPORT_PLUGIN2(qico, QICOPlugin) - QT_END_NAMESPACE #endif /* QT_NO_IMAGEFORMATPLUGIN */ diff --git a/src/plugins/imageformats/ico/main.h b/src/plugins/imageformats/ico/main.h new file mode 100644 index 00000000000..6c7634002a3 --- /dev/null +++ b/src/plugins/imageformats/ico/main.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins 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 +#include + +#ifndef QT_NO_IMAGEFORMATPLUGIN + +#ifdef QT_NO_IMAGEFORMAT_ICO +#undef QT_NO_IMAGEFORMAT_ICO +#endif +#include "qicohandler.h" + +QT_BEGIN_NAMESPACE + +class QICOPlugin : public QImageIOPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "ico.json") +public: + QStringList keys() const; + Capabilities capabilities(QIODevice *device, const QByteArray &format) const; + QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const; +}; + +QT_END_NAMESPACE + +#endif From c11f0dfae1267008bc6e6414911de3406e0ee916 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 10 Feb 2012 10:57:48 +0100 Subject: [PATCH 303/406] Convert jpeg plugin to new format Change-Id: Icadeb366c39a71dac948904197464f7e0b4272b8 Reviewed-by: Thiago Macieira --- src/plugins/imageformats/jpeg/jpeg.json | 3 ++ src/plugins/imageformats/jpeg/jpeg.pro | 2 + src/plugins/imageformats/jpeg/main.cpp | 14 +----- src/plugins/imageformats/jpeg/main.h | 65 +++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 13 deletions(-) create mode 100644 src/plugins/imageformats/jpeg/jpeg.json create mode 100644 src/plugins/imageformats/jpeg/main.h diff --git a/src/plugins/imageformats/jpeg/jpeg.json b/src/plugins/imageformats/jpeg/jpeg.json new file mode 100644 index 00000000000..132c642c05b --- /dev/null +++ b/src/plugins/imageformats/jpeg/jpeg.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "jpg", "jpeg" ] +} diff --git a/src/plugins/imageformats/jpeg/jpeg.pro b/src/plugins/imageformats/jpeg/jpeg.pro index aa489729a10..f2a41129d56 100644 --- a/src/plugins/imageformats/jpeg/jpeg.pro +++ b/src/plugins/imageformats/jpeg/jpeg.pro @@ -7,6 +7,8 @@ QTDIR_build:REQUIRES = "!contains(QT_CONFIG, no-jpeg)" include(../../../gui/image/qjpeghandler.pri) SOURCES += main.cpp +HEADERS += main.h +OTHER_FILES += jpeg.json DESTDIR = $$QT.gui.plugins/imageformats target.path += $$[QT_INSTALL_PLUGINS]/imageformats diff --git a/src/plugins/imageformats/jpeg/main.cpp b/src/plugins/imageformats/jpeg/main.cpp index beb3970af14..ecda04864b3 100644 --- a/src/plugins/imageformats/jpeg/main.cpp +++ b/src/plugins/imageformats/jpeg/main.cpp @@ -39,8 +39,7 @@ ** ****************************************************************************/ -#include -#include +#include "main.h" #ifndef QT_NO_IMAGEFORMATPLUGIN @@ -51,14 +50,6 @@ QT_BEGIN_NAMESPACE -class QJpegPlugin : public QImageIOPlugin -{ -public: - QStringList keys() const; - Capabilities capabilities(QIODevice *device, const QByteArray &format) const; - QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const; -}; - QStringList QJpegPlugin::keys() const { return QStringList() << QLatin1String("jpeg") << QLatin1String("jpg"); @@ -89,9 +80,6 @@ QImageIOHandler *QJpegPlugin::create(QIODevice *device, const QByteArray &format return handler; } -Q_EXPORT_STATIC_PLUGIN(QJpegPlugin) -Q_EXPORT_PLUGIN2(qjpeg, QJpegPlugin) - QT_END_NAMESPACE #endif // QT_NO_IMAGEFORMATPLUGIN diff --git a/src/plugins/imageformats/jpeg/main.h b/src/plugins/imageformats/jpeg/main.h new file mode 100644 index 00000000000..8606eabdd94 --- /dev/null +++ b/src/plugins/imageformats/jpeg/main.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins 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 +#include + +#ifndef QT_NO_IMAGEFORMATPLUGIN + +#ifdef QT_NO_IMAGEFORMAT_JPEG +#undef QT_NO_IMAGEFORMAT_JPEG +#endif + +QT_BEGIN_NAMESPACE + +class QJpegPlugin : public QImageIOPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "jpeg.json") +public: + QStringList keys() const; + Capabilities capabilities(QIODevice *device, const QByteArray &format) const; + QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const; +}; + +QT_END_NAMESPACE + +#endif From 71bad3e8180297351b143271856b4b6732169f39 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 17 Feb 2012 08:48:05 +0100 Subject: [PATCH 304/406] Plugin loader: Output offending plugin name in warning. Change-Id: I0aba0cf04f703b893459af55263685c5548a92f9 Reviewed-by: Lars Knoll --- src/corelib/plugin/qfactoryloader.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index 2d31e1da7ee..566ece77c9a 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -142,7 +142,8 @@ void QFactoryLoader::update() } QStringList keys; if (library->compatPlugin) { - qWarning() << "Compat plugin, need to load for accessing meta data"; + qWarning("Qt plugin loader: Compatibility plugin '%s', need to load for accessing meta data.", + qPrintable(QDir::toNativeSeparators(fileName))); if (!library->loadPlugin()) { if (qt_debug_component()) { qDebug() << library->errorString; From 4cf0deef73ff2f24a80622ec5f391d10c74ea6c7 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 10 Feb 2012 17:17:36 +0100 Subject: [PATCH 305/406] Add palette() and further hints to QtGui/QPlatformTheme. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Move palette() from deprecated QtWidgets/QGuiPlatformPlugin to QtGui/QPlatformTheme, Make it return a const * since QPalette does not have isNull(). - Initialize QGuiApplication::palette() and QApplication::systemPalette() from it. - Do not initialize QPalette from QGuiApplication::palette() unless app_pal is non-null (default to Qt::black if it is 0). This avoids initialization order crashes/recursions in the QPA plugin. Streamline initialization function. - Remove styleName(), systemIconThemeName() and iconSearchPaths() from QGuiPlatformPlugin and re-add them as QPlatformTheme::themeHint(). - Remove styleHint() from QGuiPlatformPlugin, add it to QPlatformTheme::themeHint(). - Add UNIX themes with factory function (Generic, KDE, Gnome), taking it from Qt 4.8 code (stripping the KDE 3 code). - Implement Windows palettes. Task-number: QTBUG-24204 Change-Id: Ie27ec035df4f84c42deaffc4816b2e53ce705462 Reviewed-by: Morten Johan Sørvig --- src/gui/kernel/qguiapplication.cpp | 4 + src/gui/kernel/qpalette.cpp | 62 ++-- src/gui/kernel/qplatformtheme_qpa.cpp | 36 ++ src/gui/kernel/qplatformtheme_qpa.h | 19 +- src/platformsupport/platformsupport.pro | 1 + .../genericunix/qgenericunixservices.cpp | 9 +- .../genericunix/qgenericunixservices_p.h | 5 +- .../themes/genericunix/genericunix.pri | 2 + .../themes/genericunix/qgenericunixthemes.cpp | 325 ++++++++++++++++++ .../themes/genericunix/qgenericunixthemes_p.h | 106 ++++++ src/platformsupport/themes/themes.pri | 3 + src/plugins/platforms/cocoa/qcocoatheme.h | 2 + src/plugins/platforms/cocoa/qcocoatheme.mm | 12 + .../platforms/windows/qtwindows_additional.h | 4 + .../platforms/windows/qtwindowsglobal.h | 6 +- .../platforms/windows/qwindowscontext.cpp | 6 + .../platforms/windows/qwindowscontext.h | 1 + .../windows/qwindowsdialoghelpers.cpp | 7 +- .../windows/qwindowsguieventdispatcher.cpp | 3 +- .../platforms/windows/qwindowstheme.cpp | 175 ++++++++++ src/plugins/platforms/windows/qwindowstheme.h | 24 ++ src/plugins/platforms/xcb/qxcbintegration.cpp | 9 +- src/plugins/platforms/xcb/qxcbintegration.h | 3 + src/widgets/kernel/qapplication.cpp | 15 +- src/widgets/kernel/qapplication_qpa.cpp | 7 +- src/widgets/kernel/qguiplatformplugin.cpp | 159 --------- src/widgets/kernel/qguiplatformplugin_p.h | 7 - src/widgets/kernel/qicon.cpp | 1 - src/widgets/kernel/qiconloader.cpp | 52 ++- src/widgets/styles/qcommonstyle.cpp | 19 +- .../dialogs/qmessagebox/tst_qmessagebox.cpp | 4 +- 31 files changed, 849 insertions(+), 239 deletions(-) create mode 100644 src/platformsupport/themes/genericunix/genericunix.pri create mode 100644 src/platformsupport/themes/genericunix/qgenericunixthemes.cpp create mode 100644 src/platformsupport/themes/genericunix/qgenericunixthemes_p.h create mode 100644 src/platformsupport/themes/themes.pri diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 5f50fe343ae..9f8186424e5 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -48,6 +48,7 @@ #include "qplatformfontdatabase_qpa.h" #include "qplatformwindow_qpa.h" #include "qplatformnativeinterface_qpa.h" +#include "qplatformtheme_qpa.h" #include #include @@ -1382,6 +1383,9 @@ QClipboard * QGuiApplication::clipboard() */ QPalette QGuiApplication::palette() { + if (!QGuiApplicationPrivate::app_pal) + if (const QPalette *themePalette = QGuiApplicationPrivate::platformTheme()->palette()) + QGuiApplicationPrivate::app_pal = new QPalette(*themePalette); if (!QGuiApplicationPrivate::app_pal) QGuiApplicationPrivate::app_pal = new QPalette(Qt::black); return *QGuiApplicationPrivate::app_pal; diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp index 627731ff20d..d5b17fa665c 100644 --- a/src/gui/kernel/qpalette.cpp +++ b/src/gui/kernel/qpalette.cpp @@ -41,6 +41,7 @@ #include "qpalette.h" #include "qguiapplication.h" +#include "qguiapplication_p.h" #include "qdatastream.h" #include "qvariant.h" #include "qdebug.h" @@ -64,6 +65,29 @@ static QColor qt_mix_colors(QColor a, QColor b) (a.blue() + b.blue()) / 2, (a.alpha() + b.alpha()) / 2); } +static void qt_palette_from_color(QPalette &pal, const QColor &button) +{ + int h, s, v; + button.getHsv(&h, &s, &v); + // inactive and active are the same.. + const QBrush baseBrush = QBrush(v > 128 ? Qt::white : Qt::black); + const QBrush foregroundBrush = QBrush(v > 128 ? Qt::black : Qt::white); + const QBrush buttonBrush = QBrush(button); + const QBrush buttonBrushDark = QBrush(button.darker()); + const QBrush buttonBrushDark150 = QBrush(button.darker(150)); + const QBrush buttonBrushLight150 = QBrush(button.lighter(150)); + const QBrush whiteBrush = QBrush(Qt::white); + pal.setColorGroup(QPalette::Active, foregroundBrush, buttonBrush, buttonBrushLight150, + buttonBrushDark, buttonBrushDark150, foregroundBrush, whiteBrush, + baseBrush, buttonBrush); + pal.setColorGroup(QPalette::Inactive, foregroundBrush, buttonBrush, buttonBrushLight150, + buttonBrushDark, buttonBrushDark150, foregroundBrush, whiteBrush, + baseBrush, buttonBrush); + pal.setColorGroup(QPalette::Disabled, buttonBrushDark, buttonBrush, buttonBrushLight150, + buttonBrushDark, buttonBrushDark150, buttonBrushDark, + whiteBrush, buttonBrush, buttonBrush); +} + /*! \fn const QColor &QPalette::color(ColorRole role) const @@ -488,40 +512,20 @@ static QColor qt_mix_colors(QColor a, QColor b) \sa QApplication::setPalette(), QApplication::palette() */ QPalette::QPalette() - : d(QGuiApplication::palette().d), - current_group(Active), - resolve_mask(0) + : d(0), current_group(Active), resolve_mask(0) { - d->ref.ref(); -} - -static void qt_palette_from_color(QPalette &pal, const QColor & button) -{ - QColor bg = button, - btn = button, - fg, base; - int h, s, v; - bg.getHsv(&h, &s, &v); - if(v > 128) { - fg = Qt::black; - base = Qt::white; + // Initialize to application palette if present, else default to black. + // This makes it possible to instantiate QPalette outside QGuiApplication, + // for example in the platform plugins. + if (QGuiApplicationPrivate::app_pal) { + d = QGuiApplicationPrivate::app_pal->d; + d->ref.ref(); } else { - fg = Qt::white; - base = Qt::black; + init(); + qt_palette_from_color(*this, Qt::black); } - //inactive and active are the same.. - pal.setColorGroup(QPalette::Active, QBrush(fg), QBrush(btn), QBrush(btn.lighter(150)), - QBrush(btn.darker()), QBrush(btn.darker(150)), QBrush(fg), QBrush(Qt::white), - QBrush(base), QBrush(bg)); - pal.setColorGroup(QPalette::Inactive, QBrush(fg), QBrush(btn), QBrush(btn.lighter(150)), - QBrush(btn.darker()), QBrush(btn.darker(150)), QBrush(fg), QBrush(Qt::white), - QBrush(base), QBrush(bg)); - pal.setColorGroup(QPalette::Disabled, QBrush(btn.darker()), QBrush(btn), QBrush(btn.lighter(150)), - QBrush(btn.darker()), QBrush(btn.darker(150)), QBrush(btn.darker()), - QBrush(Qt::white), QBrush(bg), QBrush(bg)); } - /*! Constructs a palette from the \a button color. The other colors are automatically calculated, based on this color. \c Window will be diff --git a/src/gui/kernel/qplatformtheme_qpa.cpp b/src/gui/kernel/qplatformtheme_qpa.cpp index d2ff804ddf1..aec465f0fff 100644 --- a/src/gui/kernel/qplatformtheme_qpa.cpp +++ b/src/gui/kernel/qplatformtheme_qpa.cpp @@ -42,6 +42,8 @@ #include "qplatformtheme_qpa.h" #include +#include +#include QT_BEGIN_NAMESPACE @@ -68,6 +70,21 @@ QT_BEGIN_NAMESPACE \value MaximumScrollBarDragDistance (int) Determines the value returned by QStyle::pixelMetric(PM_MaximumDragDistance) + \value ToolButtonStyle (int) A value representing a Qt::ToolButtonStyle. + + \value ToolBarIconSize Icon size for tool bars. + + \value SystemIconThemeName (QString) Name of the icon theme. + + \value SystemIconFallbackThemeName (QString) Name of the fallback icon theme. + + \value IconThemeSearchPaths (QStringList) Search paths for icons. + + \value ItemViewActivateItemOnSingleClick (bool) Activate items by single click. + + \value StyleNames (QStringList) A list of preferred style names. + + \sa themeHint(), QStyle::pixelMetric() */ @@ -95,9 +112,28 @@ QPlatformDialogHelper *QPlatformTheme::createPlatformDialogHelper(DialogType typ return 0; } +const QPalette *QPlatformTheme::palette(Palette type) const +{ + Q_UNUSED(type) + return 0; +} + QVariant QPlatformTheme::themeHint(ThemeHint hint) const { switch (hint) { + case QPlatformTheme::ItemViewActivateItemOnSingleClick: + return QVariant(false); + case QPlatformTheme::ToolButtonStyle: + return QVariant(int(Qt::ToolButtonIconOnly)); + case QPlatformTheme::ToolBarIconSize: + return QVariant(int(0)); + case QPlatformTheme::SystemIconThemeName: + case QPlatformTheme::SystemIconFallbackThemeName: + return QVariant(QString()); + case QPlatformTheme::IconThemeSearchPaths: + return QVariant(QStringList()); + case QPlatformTheme::StyleNames: + return QVariant(QStringList()); case TextCursorWidth: return QVariant(1); case DropShadow: diff --git a/src/gui/kernel/qplatformtheme_qpa.h b/src/gui/kernel/qplatformtheme_qpa.h index 2b87e632879..036432054ec 100644 --- a/src/gui/kernel/qplatformtheme_qpa.h +++ b/src/gui/kernel/qplatformtheme_qpa.h @@ -48,13 +48,13 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE - class QMenu; class QMenuBar; class QPlatformMenu; class QPlatformMenuBar; class QPlatformDialogHelper; class QVariant; +class QPalette; class Q_GUI_EXPORT QPlatformTheme { @@ -62,7 +62,14 @@ public: enum ThemeHint { TextCursorWidth, DropShadow, - MaximumScrollBarDragDistance + MaximumScrollBarDragDistance, + ToolButtonStyle, + ToolBarIconSize, + ItemViewActivateItemOnSingleClick, + SystemIconThemeName, + SystemIconFallbackThemeName, + IconThemeSearchPaths, + StyleNames }; enum DialogType { @@ -71,12 +78,20 @@ public: FontDialog }; + enum Palette { + SystemPalette, + ToolTipPalette, + NPalettes + }; + virtual QPlatformMenu *createPlatformMenu(QMenu *menu = 0) const; virtual QPlatformMenuBar *createPlatformMenuBar(QMenuBar *menuBar = 0) const; virtual bool usePlatformNativeDialog(DialogType type) const; virtual QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const; + virtual const QPalette *palette(Palette type = SystemPalette) const; + virtual QVariant themeHint(ThemeHint hint) const; }; diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro index 4c02a8ff57a..8322d4c70f3 100644 --- a/src/platformsupport/platformsupport.pro +++ b/src/platformsupport/platformsupport.pro @@ -35,3 +35,4 @@ include(glxconvenience/glxconvenience.pri) include(inputcontext/inputcontext.pri) include(udev/udev.pri) include(services/services.pri) +include(themes/themes.pri) diff --git a/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/src/platformsupport/services/genericunix/qgenericunixservices.cpp index 3c10fb63f60..34f46e4e6ed 100644 --- a/src/platformsupport/services/genericunix/qgenericunixservices.cpp +++ b/src/platformsupport/services/genericunix/qgenericunixservices.cpp @@ -122,9 +122,10 @@ static inline bool launch(const QString &launcher, const QUrl &url) return ok; } -QGenericUnixServices::QGenericUnixServices() : - m_desktopEnvironment(detectDesktopEnvironment()) +QGenericUnixServices::DesktopEnvironment QGenericUnixServices::desktopEnvironment() { + static const DesktopEnvironment result = detectDesktopEnvironment(); + return result; } bool QGenericUnixServices::openUrl(const QUrl &url) @@ -132,7 +133,7 @@ bool QGenericUnixServices::openUrl(const QUrl &url) if (url.scheme() == QStringLiteral("mailto")) return openDocument(url); - if (m_webBrowser.isEmpty() && !detectWebBrowser(m_desktopEnvironment, true, &m_webBrowser)) { + if (m_webBrowser.isEmpty() && !detectWebBrowser(desktopEnvironment(), true, &m_webBrowser)) { qWarning("%s: Unable to detect a web browser to launch '%s'", Q_FUNC_INFO, qPrintable(url.toString())); return false; } @@ -141,7 +142,7 @@ bool QGenericUnixServices::openUrl(const QUrl &url) bool QGenericUnixServices::openDocument(const QUrl &url) { - if (m_documentLauncher.isEmpty() && !detectWebBrowser(m_desktopEnvironment, false, &m_documentLauncher)) { + if (m_documentLauncher.isEmpty() && !detectWebBrowser(desktopEnvironment(), false, &m_documentLauncher)) { qWarning("%s: Unable to detect a launcher for '%s'", Q_FUNC_INFO, qPrintable(url.toString())); return false; } diff --git a/src/platformsupport/services/genericunix/qgenericunixservices_p.h b/src/platformsupport/services/genericunix/qgenericunixservices_p.h index 48b790a5b8c..3923a45f897 100644 --- a/src/platformsupport/services/genericunix/qgenericunixservices_p.h +++ b/src/platformsupport/services/genericunix/qgenericunixservices_p.h @@ -58,13 +58,14 @@ public: DE_GNOME }; - QGenericUnixServices(); + QGenericUnixServices() {} + + static DesktopEnvironment desktopEnvironment(); virtual bool openUrl(const QUrl &url); virtual bool openDocument(const QUrl &url); private: - const DesktopEnvironment m_desktopEnvironment; QString m_webBrowser; QString m_documentLauncher; }; diff --git a/src/platformsupport/themes/genericunix/genericunix.pri b/src/platformsupport/themes/genericunix/genericunix.pri new file mode 100644 index 00000000000..eed48257d01 --- /dev/null +++ b/src/platformsupport/themes/genericunix/genericunix.pri @@ -0,0 +1,2 @@ +HEADERS += $$PWD/qgenericunixthemes_p.h +SOURCES += $$PWD/qgenericunixthemes.cpp diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp new file mode 100644 index 00000000000..a9f05f6084f --- /dev/null +++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp @@ -0,0 +1,325 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins 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 "qgenericunixthemes_p.h" +#include "../../services/genericunix/qgenericunixservices_p.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QGenericX11ThemeQKdeTheme + \brief QGenericX11Theme is a generic theme implementation for X11. + \since 5.0 + \internal + \ingroup qpa +*/ + +// Helper to return the icon theme paths from XDG. +QStringList QGenericUnixTheme::xdgIconThemePaths() +{ + QStringList paths; + // Add home directory first in search path + const QFileInfo homeIconDir(QDir::homePath() + QStringLiteral("/.icons")); + if (homeIconDir.isDir()) + paths.prepend(homeIconDir.absoluteFilePath()); + + QString xdgDirString = QFile::decodeName(qgetenv("XDG_DATA_DIRS")); + if (xdgDirString.isEmpty()) + xdgDirString = QLatin1String("/usr/local/share/:/usr/share/"); + foreach (const QString &xdgDir, xdgDirString.split(QLatin1Char(':'))) { + const QFileInfo xdgIconsDir(xdgDir + QStringLiteral("/icons")); + if (xdgIconsDir.isDir()) + paths.append(xdgIconsDir.absoluteFilePath()); + } + return paths; +} + +QVariant QGenericUnixTheme::themeHint(ThemeHint hint) const +{ + switch (hint) { + case QPlatformTheme::SystemIconFallbackThemeName: + return QVariant(QString(QStringLiteral("hicolor"))); + case QPlatformTheme::IconThemeSearchPaths: + return xdgIconThemePaths(); + case QPlatformTheme::StyleNames: { + QStringList styleNames; + styleNames << QStringLiteral("Plastique") << QStringLiteral("Windows"); + return QVariant(styleNames); + } + break; + default: + break; + } + return QPlatformTheme::themeHint(hint); +} + +// Reads the color from the KDE configuration, and store it in the +// palette with the given color role if found. +static inline bool kdeColor(QPalette *pal, QPalette::ColorRole role, + const QSettings &kdeSettings, const QString &key) +{ + const QVariant value = kdeSettings.value(key); + if (!value.isValid()) + return false; + const QStringList values = value.toStringList(); + if (values.size() != 3) + return false; + pal->setBrush(role, QColor(values.at(0).toInt(), values.at(1).toInt(), values.at(2).toInt())); + return true; +} + +// Reads the KDE system palette +static inline bool readKdeSystemPalette(const QSettings &kdeSettings, QPalette *pal) +{ + // Setup KDE palette + return kdeColor(pal, QPalette::Button, kdeSettings, QStringLiteral("Colors:Button/BackgroundNormal")) + || kdeColor(pal, QPalette::Window, kdeSettings, QStringLiteral("Colors:Window/BackgroundNormal")) + || kdeColor(pal, QPalette::Text, kdeSettings, QStringLiteral("Colors:View/ForegroundNormal")) + || kdeColor(pal, QPalette::WindowText, kdeSettings, QStringLiteral("Colors:Window/ForegroundNormal")) + || kdeColor(pal, QPalette::Base, kdeSettings, QStringLiteral("Colors:View/BackgroundNormal")) + || kdeColor(pal, QPalette::Highlight, kdeSettings, QStringLiteral("Colors:Selection/BackgroundNormal")) + || kdeColor(pal, QPalette::HighlightedText, kdeSettings, QStringLiteral("Colors:Selection/ForegroundNormal")) + || kdeColor(pal, QPalette::AlternateBase, kdeSettings, QStringLiteral("Colors:View/BackgroundAlternate")) + || kdeColor(pal, QPalette::ButtonText, kdeSettings, QStringLiteral("Colors:Button/ForegroundNormal")) + || kdeColor(pal, QPalette::Link, kdeSettings, QStringLiteral("Colors:View/ForegroundLink")) + || kdeColor(pal, QPalette::LinkVisited, kdeSettings, QStringLiteral("Colors:View/ForegroundVisited")); +} + +/*! + \class QKdeTheme + \brief QKdeTheme is a theme implementation for the KDE desktop (version 4 or higher). + \since 5.0 + \internal + \ingroup qpa +*/ + +QKdeTheme::QKdeTheme(const QString &kdeHome, int kdeVersion) : + m_kdeHome(kdeHome), m_kdeVersion(kdeVersion), + m_toolButtonStyle(Qt::ToolButtonTextBesideIcon), m_toolBarIconSize(0) +{ + qFill(m_palettes, m_palettes + NPalettes, static_cast(0)); + refresh(); +} + +void QKdeTheme::clearPalettes() +{ + qDeleteAll(m_palettes, m_palettes + NPalettes); + qFill(m_palettes, m_palettes + NPalettes, static_cast(0)); +} + +void QKdeTheme::refresh() +{ + clearPalettes(); + + m_toolButtonStyle = Qt::ToolButtonTextBesideIcon; + m_toolBarIconSize = 0; + m_styleNames.clear(); + m_styleNames << QStringLiteral("Oxygen") << QStringLiteral("plastique") << QStringLiteral("windows"); + m_iconFallbackThemeName = m_iconThemeName = QStringLiteral("oxygen"); + + // Read settings file. + const QString settingsFile = globalSettingsFile(); + if (!QFileInfo(settingsFile).isReadable()) + return; + + const QSettings kdeSettings(settingsFile, QSettings::IniFormat); + + QPalette systemPalette; + if (readKdeSystemPalette(kdeSettings, &systemPalette)) + m_palettes[SystemPalette] = new QPalette(systemPalette); + //## TODO tooltip color + + const QVariant styleValue = kdeSettings.value(QStringLiteral("widgetStyle")); + if (styleValue.isValid()) { + const QString style = styleValue.toString(); + if (style != m_styleNames.front()) + m_styleNames.push_front(style); + } + + const QVariant themeValue = kdeSettings.value(QStringLiteral("Icons/Theme")); + if (themeValue.isValid()) + m_iconThemeName = themeValue.toString(); + + const QVariant toolBarIconSizeValue = kdeSettings.value(QStringLiteral("ToolbarIcons/Size")); + if (toolBarIconSizeValue.isValid()) + m_toolBarIconSize = toolBarIconSizeValue.toInt(); + + const QVariant toolbarStyleValue = kdeSettings.value(QStringLiteral("ToolButtonStyle")); + if (toolbarStyleValue.isValid()) { + const QString toolBarStyle = toolbarStyleValue.toString(); + if (toolBarStyle == QStringLiteral("TextBesideIcon")) + m_toolButtonStyle = Qt::ToolButtonTextBesideIcon; + else if (toolBarStyle == QStringLiteral("TextOnly")) + m_toolButtonStyle = Qt::ToolButtonTextOnly; + else if (toolBarStyle == QStringLiteral("TextUnderIcon")) + m_toolButtonStyle = Qt::ToolButtonTextUnderIcon; + } +} + +QString QKdeTheme::globalSettingsFile() const +{ + return m_kdeHome + QStringLiteral("/share/config/kdeglobals"); +} + +static QStringList kdeIconThemeSearchPaths(const QString &kdeHome) +{ + QStringList candidates = QStringList(kdeHome); + const QString kdeDirs = QFile::decodeName(qgetenv("KDEDIRS")); + if (!kdeDirs.isEmpty()) + candidates.append(kdeDirs.split(QLatin1Char(':'))); + + QStringList paths = QGenericUnixTheme::xdgIconThemePaths(); + const QString iconPath = QStringLiteral("/share/icons"); + foreach (const QString &candidate, candidates) { + const QFileInfo fi(candidate + iconPath); + if (fi.isDir()) + paths.append(fi.absoluteFilePath()); + } + return paths; +} + +QVariant QKdeTheme::themeHint(QPlatformTheme::ThemeHint hint) const +{ + switch (hint) { + case QPlatformTheme::ToolButtonStyle: + return QVariant(m_toolButtonStyle); + case QPlatformTheme::ToolBarIconSize: + return QVariant(m_toolBarIconSize); + case QPlatformTheme::SystemIconThemeName: + return QVariant(m_iconThemeName); + case QPlatformTheme::SystemIconFallbackThemeName: + return QVariant(m_iconFallbackThemeName); + case QPlatformTheme::IconThemeSearchPaths: + return QVariant(kdeIconThemeSearchPaths(m_kdeHome)); + case QPlatformTheme::StyleNames: + return QVariant(m_styleNames); + default: + break; + } + return QPlatformTheme::themeHint(hint); +} + +QPlatformTheme *QKdeTheme::createKdeTheme() +{ + // Check for version >= 4 and determine home folder from environment, + // defaulting to ~/.kde, ~/.kde + const QByteArray kdeVersionBA = qgetenv("KDE_SESSION_VERSION"); + const int kdeVersion = kdeVersionBA.toInt(); + if (kdeVersion < 4) + return 0; + const QString kdeHomePathVar = QString::fromLocal8Bit(qgetenv("KDEHOME")); + if (!kdeHomePathVar.isEmpty()) + return new QKdeTheme(kdeHomePathVar, kdeVersion); + + const QString kdeVersionHomePath = QDir::homePath() + QStringLiteral("/.kde") + QLatin1String(kdeVersionBA); + if (QFileInfo(kdeVersionHomePath).isDir()) + return new QKdeTheme(kdeVersionHomePath, kdeVersion); + + const QString kdeHomePath = QDir::homePath() + QStringLiteral("/.kde"); + if (QFileInfo(kdeHomePath).isDir()) + return new QKdeTheme(kdeHomePath, kdeVersion); + + qWarning("%s: Unable to determine KDEHOME", Q_FUNC_INFO); + return 0; +} + +/*! + \class QGnomeTheme + \brief QGnomeTheme is a theme implementation for the Gnome desktop. + \since 5.0 + \internal + \ingroup qpa +*/ + +QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const +{ + switch (hint) { + case QPlatformTheme::SystemIconThemeName: + case QPlatformTheme::SystemIconFallbackThemeName: + return QVariant(QString(QStringLiteral("gnome"))); + case QPlatformTheme::IconThemeSearchPaths: + return QVariant(QGenericUnixTheme::xdgIconThemePaths()); + case QPlatformTheme::StyleNames: { + QStringList styleNames; + styleNames << QStringLiteral("GTK+") << QStringLiteral("cleanlooks") << QStringLiteral("windows"); + return QVariant(styleNames); + } + default: + break; + } + return QPlatformTheme::themeHint(hint); +} + +/*! + \brief Creates a UNIX theme according to the detected desktop environment. +*/ + +QPlatformTheme *QGenericUnixTheme::createUnixTheme() +{ + QPlatformTheme *result = 0; + if (QGuiApplication::desktopSettingsAware()) { + switch (QGenericUnixServices::desktopEnvironment()) { + case QGenericUnixServices::DE_UNKNOWN: + break; + case QGenericUnixServices::DE_KDE: + result = QKdeTheme::createKdeTheme(); + break; + case QGenericUnixServices::DE_GNOME: + result = new QGnomeTheme; + break; + } + } + if (!result) + result = new QGenericUnixTheme; + return result; +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h b/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h new file mode 100644 index 00000000000..12937a205f1 --- /dev/null +++ b/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins 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 QGENERICUNIXTHEMES_H +#define QGENERICUNIXTHEMES_H + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QGenericUnixTheme : public QPlatformTheme +{ +public: + QGenericUnixTheme() {} + + static QPlatformTheme *createUnixTheme(); + + virtual QVariant themeHint(ThemeHint hint) const; + + static QStringList xdgIconThemePaths(); +}; + +class QKdeTheme : public QPlatformTheme +{ + QKdeTheme(const QString &kdeHome, int kdeVersion); +public: + ~QKdeTheme() { clearPalettes(); } + + static QPlatformTheme *createKdeTheme(); + virtual QVariant themeHint(ThemeHint hint) const; + virtual const QPalette *palette(Palette type = SystemPalette) const + { return m_palettes[type]; } + +private: + QString globalSettingsFile() const; + void clearPalettes(); + void refresh(); + + const QString m_kdeHome; + const int m_kdeVersion; + QPalette *m_palettes[NPalettes]; + QString m_iconThemeName; + QString m_iconFallbackThemeName; + QStringList m_styleNames; + int m_toolButtonStyle; + int m_toolBarIconSize; +}; + +class QGnomeTheme : public QPlatformTheme +{ +public: + QGnomeTheme() {} + virtual QVariant themeHint(ThemeHint hint) const; + +private: +}; + +QPlatformTheme *qt_createUnixTheme(); + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGENERICUNIXTHEMES_H diff --git a/src/platformsupport/themes/themes.pri b/src/platformsupport/themes/themes.pri new file mode 100644 index 00000000000..adee8526266 --- /dev/null +++ b/src/platformsupport/themes/themes.pri @@ -0,0 +1,3 @@ +unix:!mac { + include($$PWD/genericunix/genericunix.pri) +} diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h index 08f813b9066..a7dc9739375 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.h +++ b/src/plugins/platforms/cocoa/qcocoatheme.h @@ -59,6 +59,8 @@ public: bool usePlatformNativeDialog(DialogType dialogType) const; QPlatformDialogHelper *createPlatformDialogHelper(DialogType dialogType) const; + + QVariant themeHint(ThemeHint hint) const; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index a23faf438dc..ad20c2fb27d 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -102,4 +102,16 @@ QPlatformDialogHelper * QCocoaTheme::createPlatformDialogHelper(DialogType dialo } } +QVariant QCocoaTheme::themeHint(ThemeHint hint) const +{ + switch (hint) { + case QPlatformTheme::StyleNames: + return QStringList() << QLatin1Literal("macintosh"); + break; + default: + return QPlatformTheme::themeHint(hint); + break; + } +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qtwindows_additional.h b/src/plugins/platforms/windows/qtwindows_additional.h index ab51f36c247..d82240255e6 100644 --- a/src/plugins/platforms/windows/qtwindows_additional.h +++ b/src/plugins/platforms/windows/qtwindows_additional.h @@ -45,6 +45,10 @@ #include // get compiler define #include +#ifndef WM_THEMECHANGED +# define WM_THEMECHANGED 0x031A +#endif + /* Complement the definitions and declarations missing * when using MinGW or older Windows SDKs. */ diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h index 3445a3c7a89..27cfbdc662d 100644 --- a/src/plugins/platforms/windows/qtwindowsglobal.h +++ b/src/plugins/platforms/windows/qtwindowsglobal.h @@ -60,7 +60,8 @@ enum KeyDownEventFlag = 0x200000, TouchEventFlag = 0x400000, ClipboardEventFlag = 0x800000, - ApplicationEventFlag = 0x1000000 + ApplicationEventFlag = 0x1000000, + ThemingEventFlag = 0x2000000 }; enum WindowsEventType // Simplify event types @@ -97,6 +98,7 @@ enum WindowsEventType // Simplify event types InputMethodOpenCandidateWindowEvent = InputMethodEventFlag + 4, InputMethodCloseCandidateWindowEvent = InputMethodEventFlag + 5, InputMethodRequest = InputMethodEventFlag + 6, + ThemeChanged = ThemingEventFlag + 1, DisplayChangedEvent = 437, UnknownEvent = 542 }; @@ -178,6 +180,8 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI return QtWindows::FocusOutEvent; case WM_DISPLAYCHANGE: return QtWindows::DisplayChangedEvent; + case WM_THEMECHANGED: + return QtWindows::ThemeChanged; default: break; } diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index a257736d986..2706e02cf89 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -49,6 +49,7 @@ #include "qwindowsinputcontext.h" #include "qwindowsaccessibility.h" #include "qwindowsscreen.h" +#include "qwindowstheme.h" #include #include @@ -78,6 +79,7 @@ int QWindowsContext::verboseGL = 0; int QWindowsContext::verboseOLE = 0; int QWindowsContext::verboseInputMethods = 0; int QWindowsContext::verboseDialogs = 0; +int QWindowsContext::verboseTheming = 0; // Get verbosity of components from "foo:2,bar:3" static inline int componentVerbose(const char *v, const char *keyWord) @@ -284,6 +286,7 @@ QWindowsContext::QWindowsContext() : QWindowsContext::verboseOLE = componentVerbose(v, "ole"); QWindowsContext::verboseInputMethods = componentVerbose(v, "im"); QWindowsContext::verboseDialogs = componentVerbose(v, "dialogs"); + QWindowsContext::verboseTheming = componentVerbose(v, "theming"); } } @@ -784,6 +787,9 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::CloseEvent: QWindowSystemInterface::handleCloseEvent(platformWindow->window()); return true; + case QtWindows::ThemeChanged: // ### fixme: Compress these events? + QWindowsTheme::instance()->windowsThemeChanged(platformWindow->window()); + return true; default: break; } diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index b5a36c3fe9e..9f16ed232b5 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -121,6 +121,7 @@ public: static int verboseOLE; static int verboseInputMethods; static int verboseDialogs; + static int verboseTheming; explicit QWindowsContext(); ~QWindowsContext(); diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 8875590e639..25b93363615 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -43,6 +43,7 @@ #include "qwindowscontext.h" #include "qwindowswindow.h" +#include "qwindowstheme.h" // Color conversion helpers #include #include @@ -1268,12 +1269,6 @@ QWindowsNativeColorDialog::QWindowsNativeColorDialog(const SharedPointerColor &c qFill(m_customColors, m_customColors + 16, COLORREF(0)); } -static inline COLORREF qColorToCOLORREF(const QColor &color) -{ return RGB(color.red(), color.green(), color.blue()); } - -static inline QColor COLORREFToQColor(COLORREF cr) -{ return QColor(GetRValue(cr), GetGValue(cr), GetBValue(cr)); } - void QWindowsNativeColorDialog::exec(HWND owner) { typedef BOOL (WINAPI *ChooseColorWType)(LPCHOOSECOLORW); diff --git a/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp index 34ab1665d8b..49158dce48e 100644 --- a/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp +++ b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp @@ -203,7 +203,8 @@ messageDebugEntries[] = { {WM_IME_ENDCOMPOSITION, "WM_IME_ENDCOMPOSITION"}, {WM_IME_NOTIFY, "WM_IME_NOTIFY"}, {WM_IME_REQUEST, "WM_IME_REQUEST"}, - {WM_DISPLAYCHANGE, "WM_DISPLAYCHANGE"} + {WM_DISPLAYCHANGE, "WM_DISPLAYCHANGE"}, + {WM_THEMECHANGED , "WM_THEMECHANGED"} }; static inline const MessageDebugEntry *messageDebugEntry(UINT msg) diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index 73cff3c9cef..a59b74cef38 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -42,12 +42,126 @@ #include "qwindowstheme.h" #include "qwindowsdialoghelpers.h" #include "qwindowscontext.h" +#include "qwindowsintegration.h" #include "qt_windows.h" #include +#include +#include +#include +#include +#include +#include QT_BEGIN_NAMESPACE +static inline QTextStream& operator<<(QTextStream &str, const QColor &c) +{ + str.setIntegerBase(16); + str.setFieldWidth(2); + str.setPadChar(QLatin1Char('0')); + str << " rgb: #" << c.red() << c.green() << c.blue(); + str.setIntegerBase(10); + str.setFieldWidth(0); + return str; +} + +static inline QString paletteToString(const QPalette &palette) +{ + QString result; + QTextStream str(&result); + str << "text=" << palette.color(QPalette::WindowText) + << " background=" << palette.color(QPalette::Window); + return result; +} + +static inline QColor mixColors(const QColor &c1, const QColor &c2) +{ + return QColor ((c1.red() + c2.red()) / 2, + (c1.green() + c2.green()) / 2, + (c1.blue() + c2.blue()) / 2); +} + +static inline QColor getSysColor(int index) +{ + return qColorToCOLORREF(GetSysColor(index)); +} + +static inline QPalette systemPalette() +{ + QPalette result; + result.setColor(QPalette::WindowText, getSysColor(COLOR_WINDOWTEXT)); + result.setColor(QPalette::Button, getSysColor(COLOR_BTNFACE)); + result.setColor(QPalette::Light, getSysColor(COLOR_BTNHIGHLIGHT)); + result.setColor(QPalette::Dark, getSysColor(COLOR_BTNSHADOW)); + result.setColor(QPalette::Mid, result.button().color().darker(150)); + result.setColor(QPalette::Text, getSysColor(COLOR_WINDOWTEXT)); + result.setColor(QPalette::BrightText, getSysColor(COLOR_BTNHIGHLIGHT)); + result.setColor(QPalette::Base, getSysColor(COLOR_WINDOW)); + result.setColor(QPalette::Window, getSysColor(COLOR_BTNFACE)); + result.setColor(QPalette::ButtonText, getSysColor(COLOR_BTNTEXT)); + result.setColor(QPalette::Midlight, getSysColor(COLOR_3DLIGHT)); + result.setColor(QPalette::Shadow, getSysColor(COLOR_3DDKSHADOW)); + result.setColor(QPalette::Highlight, getSysColor(COLOR_HIGHLIGHT)); + result.setColor(QPalette::HighlightedText, getSysColor(COLOR_HIGHLIGHTTEXT)); + result.setColor(QPalette::Link, Qt::blue); + result.setColor(QPalette::LinkVisited, Qt::magenta); + result.setColor(QPalette::Inactive, QPalette::Button, result.button().color()); + result.setColor(QPalette::Inactive, QPalette::Window, result.background().color()); + result.setColor(QPalette::Inactive, QPalette::Light, result.light().color()); + result.setColor(QPalette::Inactive, QPalette::Dark, result.dark().color()); + + if (result.midlight() == result.button()) + result.setColor(QPalette::Midlight, result.button().color().lighter(110)); + if (result.background() != result.base()) { + result.setColor(QPalette::Inactive, QPalette::Highlight, result.color(QPalette::Inactive, QPalette::Window)); + result.setColor(QPalette::Inactive, QPalette::HighlightedText, result.color(QPalette::Inactive, QPalette::Text)); + } + + const QColor disabled = + mixColors(result.foreground().color(), result.button().color()); + + result.setColorGroup(QPalette::Disabled, result.foreground(), result.button(), + result.light(), result.dark(), result.mid(), + result.text(), result.brightText(), result.base(), + result.background()); + result.setColor(QPalette::Disabled, QPalette::WindowText, disabled); + result.setColor(QPalette::Disabled, QPalette::Text, disabled); + result.setColor(QPalette::Disabled, QPalette::ButtonText, disabled); + result.setColor(QPalette::Disabled, QPalette::Highlight, + getSysColor(COLOR_HIGHLIGHT)); + result.setColor(QPalette::Disabled, QPalette::HighlightedText, + getSysColor(COLOR_HIGHLIGHTTEXT)); + result.setColor(QPalette::Disabled, QPalette::Base, + result.background().color()); + return result; +} + +QPalette toolTipPalette(const QPalette &systemPalette) +{ + QPalette result(systemPalette); + const QColor tipBgColor(getSysColor(COLOR_INFOBK)); + const QColor tipTextColor(getSysColor(COLOR_INFOTEXT)); + + result.setColor(QPalette::All, QPalette::Button, tipBgColor); + result.setColor(QPalette::All, QPalette::Window, tipBgColor); + result.setColor(QPalette::All, QPalette::Text, tipTextColor); + result.setColor(QPalette::All, QPalette::WindowText, tipTextColor); + result.setColor(QPalette::All, QPalette::ButtonText, tipTextColor); + result.setColor(QPalette::All, QPalette::Button, tipBgColor); + result.setColor(QPalette::All, QPalette::Window, tipBgColor); + result.setColor(QPalette::All, QPalette::Text, tipTextColor); + result.setColor(QPalette::All, QPalette::WindowText, tipTextColor); + result.setColor(QPalette::All, QPalette::ButtonText, tipTextColor); + const QColor disabled = + mixColors(result.foreground().color(), result.button().color()); + result.setColor(QPalette::Disabled, QPalette::WindowText, disabled); + result.setColor(QPalette::Disabled, QPalette::Text, disabled); + result.setColor(QPalette::Disabled, QPalette::Base, Qt::white); + result.setColor(QPalette::Disabled, QPalette::BrightText, Qt::white); + return result; +} + static inline bool booleanSystemParametersInfo(UINT what, bool defaultValue) { BOOL result; @@ -66,11 +180,53 @@ static inline bool dWordSystemParametersInfo(UINT what, DWORD defaultValue) QWindowsTheme::QWindowsTheme() { + qFill(m_palettes, m_palettes + NPalettes, static_cast(0)); + refresh(); +} + +QWindowsTheme::~QWindowsTheme() +{ + clearPalettes(); +} + +void QWindowsTheme::clearPalettes() +{ + qDeleteAll(m_palettes, m_palettes + NPalettes); + qFill(m_palettes, m_palettes + NPalettes, static_cast(0)); +} + +QWindowsTheme *QWindowsTheme::instance() +{ + return static_cast(QWindowsIntegration::instance()->platformTheme()); +} + +static inline QStringList iconThemeSearchPaths() +{ + const QFileInfo appDir(QCoreApplication::applicationDirPath() + QStringLiteral("/icons")); + return appDir.isDir() ? QStringList(appDir.absoluteFilePath()) : QStringList(); +} + +static inline QStringList styleNames() +{ + QStringList result; + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA) + result.append(QStringLiteral("WindowsVista")); + if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP) + result.append(QStringLiteral("WindowsXP")); + result.append(QStringLiteral("Windows")); + return result; } QVariant QWindowsTheme::themeHint(ThemeHint hint) const { switch (hint) { + case SystemIconThemeName: + break; + case IconThemeSearchPaths: + return QVariant(iconThemeSearchPaths()); + break; + case StyleNames: + return QVariant(styleNames()); case TextCursorWidth: return QVariant(int(dWordSystemParametersInfo(SPI_GETCARETWIDTH, 1u))); case DropShadow: @@ -81,6 +237,19 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const return QVariant(); } +void QWindowsTheme::refresh() +{ + clearPalettes(); + if (QGuiApplication::desktopSettingsAware()) { + m_palettes[SystemPalette] = new QPalette(systemPalette()); + m_palettes[ToolTipPalette] = new QPalette(toolTipPalette(*m_palettes[SystemPalette])); + if (QWindowsContext::verboseTheming) + qDebug() << __FUNCTION__ << '\n' + << " system=" << paletteToString(*m_palettes[SystemPalette]) + << " tooltip=" << paletteToString(*m_palettes[ToolTipPalette]); + } +} + bool QWindowsTheme::usePlatformNativeDialog(DialogType type) const { return QWindowsDialogs::useHelper(type); @@ -91,4 +260,10 @@ QPlatformDialogHelper *QWindowsTheme::createPlatformDialogHelper(DialogType type return QWindowsDialogs::createHelper(type); } +void QWindowsTheme::windowsThemeChanged(QWindow * /* window */) +{ + refresh(); + // QWindowSystemInterface::handleThemeChange(window); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h index 77c85b2d6e1..950c380737f 100644 --- a/src/plugins/platforms/windows/qwindowstheme.h +++ b/src/plugins/platforms/windows/qwindowstheme.h @@ -43,19 +43,43 @@ #define QWINDOWSTHEME_H #include +#include + +#include "qtwindows_additional.h" QT_BEGIN_NAMESPACE +class QWindow; + class QWindowsTheme : public QPlatformTheme { public: QWindowsTheme(); + ~QWindowsTheme(); + + static QWindowsTheme *instance(); virtual bool usePlatformNativeDialog(DialogType type) const; virtual QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const; virtual QVariant themeHint(ThemeHint) const; + virtual const QPalette *palette(Palette type = SystemPalette) const + { return m_palettes[type]; } + + void windowsThemeChanged(QWindow *window); + +private: + void refresh(); + void clearPalettes(); + + QPalette *m_palettes[NPalettes]; }; +static inline COLORREF qColorToCOLORREF(const QColor &color) +{ return RGB(color.red(), color.green(), color.blue()); } + +static inline QColor COLORREFToQColor(COLORREF cr) +{ return QColor(GetRValue(cr), GetGValue(cr), GetBValue(cr)); } + QT_END_NAMESPACE #endif // QWINDOWSTHEME_H diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index c976e75dbf6..e7cdef4da9f 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -70,6 +70,7 @@ #endif #include +#include #include #if defined(XCB_USE_GLX) @@ -87,7 +88,8 @@ QT_BEGIN_NAMESPACE QXcbIntegration::QXcbIntegration(const QStringList ¶meters) : m_eventDispatcher(createUnixEventDispatcher()), - m_services(new QGenericUnixServices) + m_services(new QGenericUnixServices), + m_theme(QGenericUnixTheme::createUnixTheme()) { QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher); @@ -278,4 +280,9 @@ QPlatformServices *QXcbIntegration::services() const return m_services.data(); } +QPlatformTheme *QXcbIntegration::platformTheme() const +{ + return m_theme.data(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index 0f20658c70a..457f90d6e07 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -85,6 +85,8 @@ public: QPlatformServices *services() const; + QPlatformTheme *platformTheme() const; + private: QList m_connections; @@ -101,6 +103,7 @@ private: #endif QScopedPointer m_services; + QScopedPointer m_theme; }; QT_END_NAMESPACE diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index b04925d85d9..ae4f5e01b79 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -62,6 +62,7 @@ #include "qvariant.h" #include "qwidget.h" #include "private/qdnd_p.h" +#include "private/qguiapplication_p.h" #include "qcolormap.h" #include "qdebug.h" #include "private/qstylesheetstyle_p.h" @@ -71,6 +72,7 @@ #include #include #include +#include #include "private/qkeymapper_p.h" @@ -1297,6 +1299,9 @@ QStyle *QApplication::style() // take ownership of the style QApplicationPrivate::app_style->setParent(qApp); + if (!QApplicationPrivate::sys_pal) + if (const QPalette *themePalette = QGuiApplicationPrivate::platformTheme()->palette()) + QApplicationPrivate::setSystemPalette(*themePalette); if (!QApplicationPrivate::sys_pal) QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette()); if (QApplicationPrivate::set_pal) // repolish set palette with the new style @@ -1850,7 +1855,15 @@ void QApplicationPrivate::setSystemFont(const QFont &font) */ QString QApplicationPrivate::desktopStyleKey() { - return qt_guiPlatformPlugin()->styleName(); + // The platform theme might return a style that is not available, find + // first valid one. + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { + const QStringList availableKeys = QStyleFactory::keys(); + foreach (const QString &style, theme->themeHint(QPlatformTheme::StyleNames).toStringList()) + if (availableKeys.contains(style, Qt::CaseInsensitive)) + return style; + } + return QString(); } /*! diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp index e221df7ef76..54c5c393964 100644 --- a/src/widgets/kernel/qapplication_qpa.cpp +++ b/src/widgets/kernel/qapplication_qpa.cpp @@ -41,6 +41,7 @@ #include "qapplication_p.h" #include "qcolormap.h" +#include "qpalette.h" #include "qpixmapcache.h" #ifndef QT_NO_CURSOR #include "private/qcursor_p.h" @@ -53,8 +54,9 @@ #include "qgenericpluginfactory_qpa.h" #include "private/qplatformintegrationfactory_qpa_p.h" #include - #include +#include + #include #include #include "private/qwindowsysteminterface_qpa_p.h" @@ -62,6 +64,7 @@ #include "qdesktopwidget_qpa_p.h" #include "qwidgetwindow_qpa_p.h" +#include "qtooltip.h" #ifdef Q_OS_WIN # include // for qt_win_display_dc() @@ -393,6 +396,8 @@ void qt_init(QApplicationPrivate *priv, int type) qApp->setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); QColormap::initialize(); + if (const QPalette *toolTipPalette = QGuiApplicationPrivate::platformTheme()->palette(QPlatformTheme::ToolTipPalette)) + QToolTip::setPalette(*toolTipPalette); qApp->setObjectName(appName); } diff --git a/src/widgets/kernel/qguiplatformplugin.cpp b/src/widgets/kernel/qguiplatformplugin.cpp index 7646ae417e3..f5c8399a0ba 100644 --- a/src/widgets/kernel/qguiplatformplugin.cpp +++ b/src/widgets/kernel/qguiplatformplugin.cpp @@ -125,169 +125,10 @@ QGuiPlatformPlugin *qt_guiPlatformPlugin() QGuiPlatformPlugin::QGuiPlatformPlugin(QObject *parent) : QObject(parent) {} QGuiPlatformPlugin::~QGuiPlatformPlugin() {} - -/* return the string key to be used by default the application */ -QString QGuiPlatformPlugin::styleName() -{ -#if defined(Q_WS_WIN) && defined(Q_OS_WINCE) - if (qt_wince_is_smartphone() || qt_wince_is_pocket_pc()) - return QLatin1String("WindowsMobile"); - else - return QLatin1String("WindowsCE"); -#elif defined(Q_OS_WIN) - if ((QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA - && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) - return QLatin1String("WindowsVista"); - else if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP - && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) - return QLatin1String("WindowsXP"); - else - return QLatin1String("Windows"); // default styles for Windows -#elif defined(Q_WS_X11) && defined(Q_OS_SOLARIS) - return QLatin1String("CDE"); // default style for X11 on Solaris -#elif defined(Q_WS_X11) && defined(Q_OS_IRIX) - return QLatin1String("SGI"); // default style for X11 on IRIX -#elif defined(Q_OS_MAC) - return QLatin1String("Macintosh"); // default style for all Mac's -#elif defined(Q_WS_X11) - QString stylename; - switch(X11->desktopEnvironment) { - case DE_KDE: - stylename = QKde::kdeStyle(); - break; - case DE_GNOME: { - QStringList availableStyles = QStyleFactory::keys(); - // Set QGtkStyle for GNOME if available - QString gtkStyleKey = QString::fromLatin1("GTK+"); - if (availableStyles.contains(gtkStyleKey)) { - stylename = gtkStyleKey; - break; - } - if (X11->use_xrender) - stylename = QLatin1String("cleanlooks"); - else - stylename = QLatin1String("windows"); - break; - } - case DE_CDE: - stylename = QLatin1String("cde"); - break; - default: - // Don't do anything - break; - } - return stylename; -#else - return QLatin1String("Plastique"); // default style for X11 and small devices -#endif -} - -/* return an additional default palette (only work on X11) */ -QPalette QGuiPlatformPlugin::palette() -{ -#ifdef Q_WS_X11 - if (QApplication::desktopSettingsAware() && X11->desktopEnvironment == DE_KDE) - return QKde::kdePalette(); -#endif - - return QPalette(); -} - -/* the default icon theme name for QIcon::fromTheme. */ -QString QGuiPlatformPlugin::systemIconThemeName() -{ - QString result; -#ifdef Q_WS_X11 - if (X11->desktopEnvironment == DE_GNOME) { - result = QString::fromLatin1("gnome"); -#ifndef QT_NO_STYLE_GTK - result = QGtkStylePrivate::getGConfString(QLatin1String("/desktop/gnome/interface/icon_theme"), result); -#endif - } else if (X11->desktopEnvironment == DE_KDE) { - result = X11->desktopVersion >= 4 ? QString::fromLatin1("oxygen") : QString::fromLatin1("crystalsvg"); - QSettings settings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); - settings.beginGroup(QLatin1String("Icons")); - result = settings.value(QLatin1String("Theme"), result).toString(); - } -#endif - return result; -} - - -QStringList QGuiPlatformPlugin::iconThemeSearchPaths() -{ - QStringList paths; -#if defined(Q_WS_X11) - QString xdgDirString = QFile::decodeName(getenv("XDG_DATA_DIRS")); - if (xdgDirString.isEmpty()) - xdgDirString = QLatin1String("/usr/local/share/:/usr/share/"); - - QStringList xdgDirs = xdgDirString.split(QLatin1Char(':')); - - for (int i = 0 ; i < xdgDirs.size() ; ++i) { - QDir dir(xdgDirs[i]); - if (dir.exists()) - paths.append(dir.path() + QLatin1String("/icons")); - } - if (X11->desktopEnvironment == DE_KDE) { - paths << QLatin1Char(':') + QKde::kdeHome() + QLatin1String("/share/icons"); - QStringList kdeDirs = QFile::decodeName(getenv("KDEDIRS")).split(QLatin1Char(':')); - for (int i = 0 ; i< kdeDirs.count() ; ++i) { - QDir dir(QLatin1Char(':') + kdeDirs.at(i) + QLatin1String("/share/icons")); - if (dir.exists()) - paths.append(dir.path()); - } - } - - // Add home directory first in search path - QDir homeDir(QDir::homePath() + QLatin1String("/.icons")); - if (homeDir.exists()) - paths.prepend(homeDir.path()); -#endif - -#if defined(Q_WS_WIN) - paths.append(qApp->applicationDirPath() + QLatin1String("/icons")); -#elif defined(Q_WS_MAC) - paths.append(qApp->applicationDirPath() + QLatin1String("/../Resources/icons")); -#endif - return paths; -} - /* backend for QFileIconProvider, null icon means default */ QIcon QGuiPlatformPlugin::fileSystemIcon(const QFileInfo &) { return QIcon(); } -/* Like QStyle::styleHint */ -int QGuiPlatformPlugin::platformHint(PlatformHint hint) -{ - int ret = 0; - switch(hint) - { - case PH_ToolButtonStyle: - ret = Qt::ToolButtonIconOnly; -#ifdef Q_WS_X11 - if (X11->desktopEnvironment == DE_KDE && X11->desktopVersion >= 4 - && QApplication::desktopSettingsAware()) { - ret = QKde::kdeToolButtonStyle(); - } -#endif - break; - case PH_ToolBarIconSize: -#ifdef Q_WS_X11 - if (X11->desktopEnvironment == DE_KDE && X11->desktopVersion >= 4 - && QApplication::desktopSettingsAware()) { - ret = QKde::kdeToolBarIconSize(); - } -#endif - //by default keep ret = 0 so QCommonStyle will use the style default - break; - default: - break; - } - return ret; -} - - QT_END_NAMESPACE diff --git a/src/widgets/kernel/qguiplatformplugin_p.h b/src/widgets/kernel/qguiplatformplugin_p.h index 09b65640616..c42db3bb923 100644 --- a/src/widgets/kernel/qguiplatformplugin_p.h +++ b/src/widgets/kernel/qguiplatformplugin_p.h @@ -87,14 +87,7 @@ class Q_WIDGETS_EXPORT QGuiPlatformPlugin : public QObject, public QGuiPlatformP virtual QStringList keys() const { return QStringList(QStringLiteral("default")); } - virtual QString styleName(); - virtual QPalette palette(); - virtual QString systemIconThemeName(); - virtual QStringList iconThemeSearchPaths(); virtual QIcon fileSystemIcon(const QFileInfo &); - - enum PlatformHint { PH_ToolButtonStyle, PH_ToolBarIconSize, PH_ItemView_ActivateItemOnSingleClick }; - virtual int platformHint(PlatformHint hint); }; //internal diff --git a/src/widgets/kernel/qicon.cpp b/src/widgets/kernel/qicon.cpp index 1d3236aa467..e579fac4f4f 100644 --- a/src/widgets/kernel/qicon.cpp +++ b/src/widgets/kernel/qicon.cpp @@ -53,7 +53,6 @@ #include "qvariant.h" #include "qcache.h" #include "qdebug.h" -#include "private/qguiplatformplugin_p.h" #include "qapplication.h" #ifdef Q_WS_MAC diff --git a/src/widgets/kernel/qiconloader.cpp b/src/widgets/kernel/qiconloader.cpp index 0b86189b5ec..2f9576f864a 100644 --- a/src/widgets/kernel/qiconloader.cpp +++ b/src/widgets/kernel/qiconloader.cpp @@ -43,11 +43,12 @@ #include #include -#include +#include #include #include #include +#include #include #include #include @@ -73,17 +74,11 @@ Q_GLOBAL_STATIC(QIconLoader, iconLoaderInstance) /* Theme to use in last resort, if the theme does not have the icon, neither the parents */ static QString fallbackTheme() { -#ifdef Q_WS_X11 - if (X11->desktopEnvironment == DE_GNOME) { - return QLatin1String("gnome"); - } else if (X11->desktopEnvironment == DE_KDE) { - return X11->desktopVersion >= 4 - ? QString::fromLatin1("oxygen") - : QString::fromLatin1("crystalsvg"); - } else { - return QLatin1String("hicolor"); + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { + const QVariant themeHint = theme->themeHint(QPlatformTheme::SystemIconThemeName); + if (themeHint.isValid()) + return themeHint.toString(); } -#endif return QString(); } @@ -94,6 +89,27 @@ QIconLoader::QIconLoader() : // We lazily initialize the loader to make static icons // work. Though we do not officially support this. + +static inline QString systemThemeName() +{ + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { + const QVariant themeHint = theme->themeHint(QPlatformTheme::SystemIconThemeName); + if (themeHint.isValid()) + return themeHint.toString(); + } + return QString(); +} + +static inline QStringList systemIconSearchPaths() +{ + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { + const QVariant themeHint = theme->themeHint(QPlatformTheme::IconThemeSearchPaths); + if (themeHint.isValid()) + return themeHint.toStringList(); + } + return QStringList(); +} + void QIconLoader::ensureInitialized() { if (!m_initialized) { @@ -101,7 +117,8 @@ void QIconLoader::ensureInitialized() Q_ASSERT(qApp); - m_systemTheme = qt_guiPlatformPlugin()->systemIconThemeName(); + m_systemTheme = systemThemeName(); + if (m_systemTheme.isEmpty()) m_systemTheme = fallbackTheme(); #ifndef QT_NO_LIBRARY @@ -125,7 +142,7 @@ void QIconLoader::updateSystemTheme() { // Only change if this is not explicitly set by the user if (m_userTheme.isEmpty()) { - QString theme = qt_guiPlatformPlugin()->systemIconThemeName(); + QString theme = systemThemeName(); if (theme.isEmpty()) theme = fallbackTheme(); if (theme != m_systemTheme) { @@ -151,7 +168,7 @@ void QIconLoader::setThemeSearchPath(const QStringList &searchPaths) QStringList QIconLoader::themeSearchPaths() const { if (m_iconDirs.isEmpty()) { - m_iconDirs = qt_guiPlatformPlugin()->iconThemeSearchPaths(); + m_iconDirs = systemIconSearchPaths(); // Always add resource directory as search path m_iconDirs.append(QLatin1String(":/icons")); } @@ -221,8 +238,11 @@ QIconTheme::QIconTheme(const QString &themeName) QLatin1String("Icon Theme/Inherits")).toStringList(); // Ensure a default platform fallback for all themes - if (m_parents.isEmpty()) - m_parents.append(fallbackTheme()); + if (m_parents.isEmpty()) { + const QString fallback = fallbackTheme(); + if (!fallback.isEmpty()) + m_parents.append(fallback); + } // Ensure that all themes fall back to hicolor if (!m_parents.contains(QLatin1String("hicolor"))) diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index db783d14d40..75476faeeb7 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -75,7 +76,6 @@ #include #include #include -#include #include @@ -4509,9 +4509,11 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid break; case PM_ToolBarIconSize: - ret = qt_guiPlatformPlugin()->platformHint(QGuiPlatformPlugin::PH_ToolBarIconSize); - if (!ret) - ret = int(QStyleHelper::dpiScaled(24.)); + ret = 0; + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) + ret = theme->themeHint(QPlatformTheme::ToolBarIconSize).toInt(); + if (ret <= 0) + ret = int(QStyleHelper::dpiScaled(24.)); break; case PM_TabBarIconSize: @@ -4903,9 +4905,10 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget break; case SH_ItemView_ActivateItemOnSingleClick: - ret = qt_guiPlatformPlugin()->platformHint(QGuiPlatformPlugin::PH_ItemView_ActivateItemOnSingleClick); + ret = 0; + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) + ret = theme->themeHint(QPlatformTheme::ToolButtonStyle).toBool() ? 1 : 0; break; - case SH_TitleBar_ModifyNotification: ret = true; break; @@ -4997,7 +5000,9 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget ret = true; break; case SH_ToolButtonStyle: - ret = qt_guiPlatformPlugin()->platformHint(QGuiPlatformPlugin::PH_ToolButtonStyle); + ret = 0; + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) + ret = theme->themeHint(QPlatformTheme::ToolButtonStyle).toInt(); break; case SH_RequestSoftwareInputPanel: ret = RSIP_OnMouseClickAndAlreadyFocused; diff --git a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp index 9e965ff2354..7fc752488d4 100644 --- a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp @@ -411,8 +411,10 @@ void tst_QMessageBox::staticSourceCompat() if (qobject_cast(qApp->style())) expectedButton = int(QMessageBox::No); #elif !defined(QT_NO_STYLE_CLEANLOOKS) - if (qobject_cast(qApp->style())) + if (qobject_cast(qApp->style())) { + QEXPECT_FAIL("", "Special handling of QMessageBox::information buttons for Cleanlooks not implemented yet, QTBUG-24315", Continue); expectedButton = int(QMessageBox::No); + } #endif QCOMPARE(ret, expectedButton); QCOMPARE(keyToSend, -1); From 2c3b2b47036bda2b0a953c9c5bedbad67240e85f Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Tue, 14 Feb 2012 08:46:22 +0100 Subject: [PATCH 306/406] Expect tst_QSettings::ctor(native) failures on Mac OS X The default constructor for QSettings does not set NoAccess status, even if the organization domain, organization name, and application name are empty. Instead of trying to fix QSettings, keep the existing behavior, and test for it. Failures from tst_QSettings no longer need to be ignored, so mac:CONFIG+=insignificant_test has been removed from the .pro file. Task-number: QTBUG-22745 Change-Id: Ic9f8b6821c483c217e1ef2ece704be2da169e340 Reviewed-by: Robin Burchell --- tests/auto/corelib/io/qsettings/qsettings.pro | 1 - tests/auto/corelib/io/qsettings/tst_qsettings.cpp | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/auto/corelib/io/qsettings/qsettings.pro b/tests/auto/corelib/io/qsettings/qsettings.pro index a5483bf5853..9de476fe134 100644 --- a/tests/auto/corelib/io/qsettings/qsettings.pro +++ b/tests/auto/corelib/io/qsettings/qsettings.pro @@ -6,5 +6,4 @@ RESOURCES += qsettings.qrc win32-msvc*:LIBS += advapi32.lib -mac: CONFIG += insignificant_test # QTBUG-22745 win32: CONFIG += insignificant_test # QTBUG-24145 diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp index 0d6443c5ac9..df8e97ab9c9 100644 --- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp +++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp @@ -580,6 +580,9 @@ void tst_QSettings::ctor() QCoreApplication::instance()->setOrganizationName(""); QCoreApplication::instance()->setApplicationName(""); QSettings settings; +#ifdef Q_OS_MAC + QEXPECT_FAIL("native", "Default settings on Mac are valid, despite organization domain, name, and app name being null", Continue); +#endif QCOMPARE(settings.status(), QSettings::AccessError); QCoreApplication::instance()->setOrganizationName("software.org"); QCoreApplication::instance()->setApplicationName("KillerAPP"); @@ -592,6 +595,9 @@ void tst_QSettings::ctor() } QSettings settings(format, QSettings::UserScope, "", ""); +#ifdef Q_OS_MAC + QEXPECT_FAIL("native", "Default settings on Mac are valid, despite organization domain, name, and app name being null", Continue); +#endif QCOMPARE(settings.status(), QSettings::AccessError); QSettings settings2(format, QSettings::UserScope, "software.org", "KillerAPP"); QCOMPARE(settings2.status(), QSettings::NoError); From 5efb3c27079a17b023ca4f1c9babfee00949c876 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 15 Feb 2012 12:51:15 +0100 Subject: [PATCH 307/406] Remove unused config.tests from config.tests/mac/* MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The xarch.test and crc.test are not run by configure, so remove them along with the related CFG_MACH_XARCH and QT_NAMESPACE_MAC_CRC configure variables. The kEventClassQt variable in qt_mac_p.h is also unused now, so remove it as well. Change-Id: I596ab9b493ce3164b6a4d40e8942479efc91b60d Reviewed-by: Morten Johan Sørvig Reviewed-by: Oswald Buddenhagen --- config.tests/mac/crc.test | 71 ---------------- config.tests/mac/crc/crc.pro | 2 - config.tests/mac/crc/main.cpp | 108 ------------------------- config.tests/mac/xarch.test | 26 ------ configure | 2 - src/plugins/platforms/cocoa/qt_mac_p.h | 10 --- 6 files changed, 219 deletions(-) delete mode 100755 config.tests/mac/crc.test delete mode 100644 config.tests/mac/crc/crc.pro delete mode 100644 config.tests/mac/crc/main.cpp delete mode 100755 config.tests/mac/xarch.test diff --git a/config.tests/mac/crc.test b/config.tests/mac/crc.test deleted file mode 100755 index 9cbe7bad948..00000000000 --- a/config.tests/mac/crc.test +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/sh - -SUCCESS=no -QMKSPEC=$1 -XPLATFORM=`basename "$1"` -QMAKE_CONFIG=$2 -VERBOSE=$3 -SRCDIR=$4 -OUTDIR=$5 -TEST=$6 -EXE=`basename "$6"` -ARG=$7 -shift 7 -LFLAGS="" -INCLUDEPATH="" -CXXFLAGS="" -while [ "$#" -gt 0 ]; do - PARAM=$1 - case $PARAM in - -framework) - LFLAGS="$LFLAGS -framework \"$2\"" - shift - ;; - -F*|-m*|-x*) - LFLAGS="$LFLAGS $PARAM" - CXXFLAGS="$CXXFLAGS $PARAM" - ;; - -L*|-l*|-pthread) - LFLAGS="$LFLAGS $PARAM" - ;; - -I*) - INC=`echo $PARAM | sed -e 's/^-I//'` - INCLUDEPATH="$INCLUDEPATH $INC" - ;; - -f*|-D*) - CXXFLAGS="$CXXFLAGS $PARAM" - ;; - -Qoption) - # Two-argument form for the Sun Compiler - CXXFLAGS="$CXXFLAGS $PARAM \"$2\"" - shift - ;; - *) ;; - esac - shift -done - -# debuggery -[ "$VERBOSE" = "yes" ] && echo "$DESCRIPTION auto-detection... ($*)" - -test -d "$OUTDIR/$TEST" || mkdir -p "$OUTDIR/$TEST" - -cd "$OUTDIR/$TEST" - -$MAKE distclean >/dev/null 2>&1 -"$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "CONFIG+=$QMAKE_CONFIG" "LIBS*=$LFLAGS" "INCLUDEPATH*=$INCLUDEPATH" "QMAKE_CXXFLAGS*=$CXXFLAGS" "QT_BUILD_TREE=$OUTDIR" "$SRCDIR/$TEST/$EXE.pro" -o "$OUTDIR/$TEST/Makefile" - -if [ "$VERBOSE" = "yes" ]; then - $MAKE -else - $MAKE >/dev/null 2>&1 -fi - - -if [ -x "$EXE" ]; then - foo=`$OUTDIR/$TEST/$EXE $ARG` - echo "$foo" -else - echo "'CUTE'" #1129665605 # == 'CUTE' -fi - diff --git a/config.tests/mac/crc/crc.pro b/config.tests/mac/crc/crc.pro deleted file mode 100644 index c3abf15759d..00000000000 --- a/config.tests/mac/crc/crc.pro +++ /dev/null @@ -1,2 +0,0 @@ -SOURCES = main.cpp -CONFIG -= app_bundle qt diff --git a/config.tests/mac/crc/main.cpp b/config.tests/mac/crc/main.cpp deleted file mode 100644 index f02177ccb74..00000000000 --- a/config.tests/mac/crc/main.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the config.tests 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 -#include -#include - - -class CCRC32 -{ -public: - CCRC32() { initialize(); } - - unsigned long FullCRC(const unsigned char *sData, unsigned long ulDataLength) - { - unsigned long ulCRC = 0xffffffff; - PartialCRC(&ulCRC, sData, ulDataLength); - return(ulCRC ^ 0xffffffff); - } - - void PartialCRC(unsigned long *ulCRC, const unsigned char *sData, unsigned long ulDataLength) - { - while(ulDataLength--) { - *ulCRC = (*ulCRC >> 8) ^ ulTable[(*ulCRC & 0xFF) ^ *sData++]; - } - } - -private: - void initialize(void) - { - unsigned long ulPolynomial = 0x04C11DB7; - memset(&ulTable, 0, sizeof(ulTable)); - for(int iCodes = 0; iCodes <= 0xFF; iCodes++) { - ulTable[iCodes] = Reflect(iCodes, 8) << 24; - for(int iPos = 0; iPos < 8; iPos++) { - ulTable[iCodes] = ((ulTable[iCodes] << 1) & 0xffffffff) - ^ ((ulTable[iCodes] & (1 << 31)) ? ulPolynomial : 0); - } - - ulTable[iCodes] = Reflect(ulTable[iCodes], 32); - } - } - unsigned long Reflect(unsigned long ulReflect, const char cChar) - { - unsigned long ulValue = 0; - // Swap bit 0 for bit 7, bit 1 For bit 6, etc.... - for(int iPos = 1; iPos < (cChar + 1); iPos++) { - if(ulReflect & 1) { - ulValue |= (1ul << (cChar - iPos)); - } - ulReflect >>= 1; - } - return ulValue; - } - unsigned long ulTable[256]; // CRC lookup table array. -}; - - -int main(int argc, char **argv) -{ - CCRC32 crc; - char *name; - if (argc < 2) { - std::cerr << "usage: crc \n"; - return 0; - } else { - name = argv[1]; - } - std::cout << crc.FullCRC((unsigned char *)name, strlen(name)) << std::endl; -} diff --git a/config.tests/mac/xarch.test b/config.tests/mac/xarch.test deleted file mode 100755 index 08322a96cfa..00000000000 --- a/config.tests/mac/xarch.test +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -XARCH_SUPPORT=no -COMPILER=$1 -VERBOSE=$2 -WORKDIR=$3 - -touch xarch.c - -if "$COMPILER" -c xarch.c -Xarch_i386 -mmmx 2>/dev/null 1>&2; then - if "$COMPILER" -c xarch.c -Xarch_i386 -mmmx 2>&1 | grep "unrecognized" >/dev/null ; then - true - else - XARCH_SUPPORT=yes - fi -fi -rm -f xarch.c xarch.o - -# done -if [ "$XARCH_SUPPORT" != "yes" ]; then - [ "$VERBOSE" = "yes" ] && echo "Xarch is not supported" - exit 0 -else - [ "$VERBOSE" = "yes" ] && echo "Xarch support detected" - exit 1 -fi diff --git a/configure b/configure index c780af362f5..7e6aa9ef99e 100755 --- a/configure +++ b/configure @@ -774,7 +774,6 @@ CFG_FRAMEWORK=auto CFG_MAC_ARCHS= MAC_CONFIG_TEST_COMMANDLINE= # used to make the configure tests run with the correct arch's and SDK settings CFG_MAC_DWARF2=auto -CFG_MAC_XARCH=auto CFG_MAC_HARFBUZZ=no CFG_SXE=no CFG_PREFIX_INSTALL=yes @@ -7309,7 +7308,6 @@ QT_PATCH_VERSION = $QT_PATCH_VERSION #namespaces QT_LIBINFIX = $QT_LIBINFIX QT_NAMESPACE = $QT_NAMESPACE -QT_NAMESPACE_MAC_CRC = $QT_NAMESPACE_MAC_CRC EOF if [ -n "$CFG_SYSROOT" ]; then diff --git a/src/plugins/platforms/cocoa/qt_mac_p.h b/src/plugins/platforms/cocoa/qt_mac_p.h index 947097294ae..8e94880c5af 100644 --- a/src/plugins/platforms/cocoa/qt_mac_p.h +++ b/src/plugins/platforms/cocoa/qt_mac_p.h @@ -80,16 +80,6 @@ class QDragMoveEvent; /* Event masks */ // internal Qt types - // Event class for our own Carbon events. -#if defined(QT_NAMESPACE) && defined(QT_NAMESPACE_MAC_CRC) -// Take the CRC we generated at configure time. This *may* result in a -// collision with another value If that is the case, please change the value -// here to something other than 'Cute'. -const UInt32 kEventClassQt = QT_NAMESPACE_MAC_CRC; -#else -const UInt32 kEventClassQt = 'Cute'; -#endif - enum { //AE types typeAEClipboardChanged = 1, From 33fe2cf23f4fc7aa1b2576dd09f8e9154e0db0ea Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Thu, 16 Feb 2012 09:22:39 +0100 Subject: [PATCH 308/406] Skip hanging/failing tst_QApplication tests on Mac OS X The first block of tst_QApplication::quitOnLastWindowClosed() hangs on Mac OS X, so skip that block for now. tst_QApplication::testDeleteLAter() both hangs and fails on Mac OS X, so skip the test and XFAIL the failure. Task-number: QTBUG-24318 Task-number: QTBUG-24319 Change-Id: Ice11292d84e63215f1bb9e03f3ef369943d1d887 Reviewed-by: Rohan McGovern Reviewed-by: Jason McDonald --- tests/auto/widgets/kernel/qapplication/test/test.pro | 2 -- tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/auto/widgets/kernel/qapplication/test/test.pro b/tests/auto/widgets/kernel/qapplication/test/test.pro index 9f6db3cd3e5..61035cc24ba 100644 --- a/tests/auto/widgets/kernel/qapplication/test/test.pro +++ b/tests/auto/widgets/kernel/qapplication/test/test.pro @@ -14,8 +14,6 @@ win32 { } } -mac*:CONFIG+=insignificant_test - TESTDATA = ../test/test.pro ../tmp/README SUBPROGRAMS = desktopsettingsaware modal diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index fcb6b93e99a..fc38840bf77 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -601,6 +601,8 @@ public slots: void tst_QApplication::quitOnLastWindowClosed() { +#ifndef Q_OS_MAC + // Test hangs on Mac OS X, see QTBUG-24319 { int argc = 0; QApplication app(argc, 0, QApplication::GuiServer); @@ -615,6 +617,7 @@ void tst_QApplication::quitOnLastWindowClosed() // lastWindowClosed() signal should only be sent after the last dialog is closed QCOMPARE(appSpy.count(), 2); } +#endif { int argc = 0; QApplication app(argc, 0, QApplication::GuiServer); @@ -1204,6 +1207,9 @@ void DeleteLaterWidget::checkDeleteLater() void tst_QApplication::testDeleteLater() { +#ifdef Q_OS_MAC + QSKIP("This test fails and then hangs on Mac OS X, see QTBUG-24318"); +#endif int argc = 0; QApplication app(argc, 0, QApplication::GuiServer); connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit())); From a902387204e3b9713697ed0ec8fbb11ee5c88428 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Thu, 16 Feb 2012 09:31:59 +0100 Subject: [PATCH 309/406] Skip hanging tst_QColorDialog test, expect failing test on Mac OS X tst_QColorDialog::native_activeModalWidget() hangs, so skip this test. tst_QColorDialog::task247349_alpha() fails, so XFAIL this failure. Task-number: QTBUG-24320 Change-Id: Ie4d69e07063e9a648ec4fa3337274143a52ea3e3 Reviewed-by: Rohan McGovern Reviewed-by: Jason McDonald --- .../auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp b/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp index 31fab971a07..ff34b009e94 100644 --- a/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp +++ b/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp @@ -100,6 +100,9 @@ tst_QColorDialog::~tst_QColorDialog() void tst_QColorDialog::native_activeModalWidget() { +#ifdef Q_OS_MAC + QSKIP("Test hangs on Mac OS X, see QTBUG-24320"); +#endif // Check that QApplication::activeModalWidget retruns the // color dialog when it is executing, even when using a native // dialog: @@ -153,6 +156,9 @@ void tst_QColorDialog::task247349_alpha() dialog.setOption(QColorDialog::ShowAlphaChannel, true); int alpha = 0x17; dialog.setCurrentColor(QColor(0x01, 0x02, 0x03, alpha)); +#ifdef Q_OS_MAC + QEXPECT_FAIL("", "Fails on Mac OS X, see QTBUG-24320", Abort); +#endif QCOMPARE(alpha, dialog.currentColor().alpha()); QCOMPARE(alpha, qAlpha(dialog.currentColor().rgba())); } From ea1ef2a471ef50495e8db9fd47aee6af72264470 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Thu, 16 Feb 2012 09:35:53 +0100 Subject: [PATCH 310/406] Skip all tst_QFontDialog tests on Mac OS X All of these tests currently hang. Task-number: QTBUG-24321 Change-Id: I7664b57f6539d4c03008701da66e193019a4440a Reviewed-by: Rohan McGovern Reviewed-by: Jason McDonald --- .../widgets/dialogs/qfontdialog/tst_qfontdialog.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp index f5c3e08217e..6b2caf17d77 100644 --- a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp +++ b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp @@ -114,6 +114,9 @@ void tst_QFontDialog::postKeyReturn() { void tst_QFontDialog::defaultOkButton() { +#ifdef Q_OS_MAC + QSKIP("Test hangs on Mac OS X, see QTBUG-24321"); +#endif bool ok = false; QTimer::singleShot(2000, this, SLOT(postKeyReturn())); QFontDialog::getFont(&ok); @@ -123,6 +126,9 @@ void tst_QFontDialog::defaultOkButton() void tst_QFontDialog::setFont() { +#ifdef Q_OS_MAC + QSKIP("Test hangs on Mac OS X, see QTBUG-24321"); +#endif /* The font should be the same before as it is after if nothing changed while the font dialog was open. Task #27662 @@ -154,6 +160,10 @@ class FriendlyFontDialog : public QFontDialog void tst_QFontDialog::task256466_wrongStyle() { +#ifdef Q_OS_MAC + QSKIP("Test crashes on Mac OS X, see QTBUG-24321"); +#endif + QFontDatabase fdb; FriendlyFontDialog dialog; QListView *familyList = reinterpret_cast(dialog.d_func()->familyList); From ee7c81b9c4cfcc3635ff8241480d10c94af4d316 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Thu, 16 Feb 2012 09:40:02 +0100 Subject: [PATCH 311/406] Skip tst_QGuiApplication::focusObject() on Mac OS X This test fails intermittently, and at random locations. Task-number: QTBUG-24322 Change-Id: Ied6dd4d1593066debc0fb48c6ca2a17a1f4d51b7 Reviewed-by: Rohan McGovern Reviewed-by: Jason McDonald --- tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp index 8d0836e7c3b..7664706b93a 100644 --- a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp +++ b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp @@ -78,6 +78,9 @@ public: void tst_QGuiApplication::focusObject() { +#ifdef Q_OS_MAC + QSKIP("This test fails intermittently, and at different locations. See QTBUG-24322"); +#endif int argc = 0; QGuiApplication app(argc, 0); From 0a6516e12609d91389fd0e033ebb434d64649bc4 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Thu, 16 Feb 2012 14:18:10 +0100 Subject: [PATCH 312/406] Expect failure in tst_QStyleSheetStyle::hoverColors() This is similar to the focusColors() failures in QTBUG-23686. Task-number: QTBUG-23686 Change-Id: I1f01a4e41e61a7a664309be34cfa4fe916a92b15 Reviewed-by: Rohan McGovern Reviewed-by: Jason McDonald --- .../widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp index 2dc985439d2..1201b0f1da4 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -881,6 +881,11 @@ void tst_QStyleSheetStyle::hoverColors() QVERIFY2(testForColors(image, QColor(0xe8, 0xff, 0x66)), (QString::fromLatin1(widget->metaObject()->className()) + " did not contain background color #e8ff66").toLocal8Bit().constData()); +#ifdef Q_OS_MAC + if (qobject_cast(widget) + || qobject_cast(widget)) + QEXPECT_FAIL("", "Failure only for QPushButton and QComboBox, see QTBUG-23686", Continue); +#endif QVERIFY2(testForColors(image, QColor(0xff, 0x00, 0x84)), (QString::fromLatin1(widget->metaObject()->className()) + " did not contain text color #ff0084").toLocal8Bit().constData()); From 51699245d7e3a27867f440697eca9b30ea4578f4 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 17 Feb 2012 10:10:27 +0100 Subject: [PATCH 313/406] Windows: Fix compilation with -qtnamespace Change-Id: I00ba88887100b699d620875d868f8a769259a768 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp | 4 ++++ src/plugins/platforms/windows/qwindowsfontdatabase_ft.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index 6b6d1a294a0..031d6ad1a66 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -53,6 +53,8 @@ #include +QT_BEGIN_NAMESPACE + static inline QFontDatabase::WritingSystem writingSystemFromScript(const QString &scriptName) { if (scriptName == QStringLiteral("Western") @@ -699,3 +701,5 @@ QFont QWindowsFontDatabaseFT::LOGFONT_to_QFont(const LOGFONT& logFont, int verti qFont.setStrikeOut(logFont.lfStrikeOut); return qFont; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h index b12c1067fdc..5a0c4c6377b 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h @@ -46,6 +46,8 @@ #include #include "qtwindows_additional.h" +QT_BEGIN_NAMESPACE + class QWindowsFontDatabaseFT : public QBasicFontDatabase { public: @@ -68,4 +70,6 @@ private: QSet m_families; }; +QT_END_NAMESPACE + #endif // QWINDOWSFONTDATABASEFT_H From 64d06c1c673253cd247947e840ba96c628c1a4b1 Mon Sep 17 00:00:00 2001 From: Jeremy Katz Date: Wed, 15 Feb 2012 18:49:31 +0100 Subject: [PATCH 314/406] QStandardPaths implementation configured using JSON The default JSON file is /etc/user-dirs.json, but may be overridden by setting PATH_CONFIG_HOME to the file to be used. This provides functionality similar to the XDG based QStandardPaths, but uses a JSON file to define paths, rather than the XDG A=B format. Values other than HomeLocation and TempLocation may be specified by removing the "Location" postfix, converting to upper case, and separating words with _. Values are independent. For example, CacheLocation does not depend on GenericCacheLocation. Variables specified as ${[^{]*} will be replaced with environment variables. Change-Id: I374f5e6bae498dbfa9cb4ecadf915b05fb91fc34 Reviewed-by: David Faure --- src/corelib/io/io.pri | 2 + src/corelib/io/qstandardpaths_json.cpp | 184 +++++++++++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 src/corelib/io/qstandardpaths_json.cpp diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 1a73783604e..2df862e360a 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -106,6 +106,8 @@ win32 { } macx-*: { SOURCES += io/qstandardpaths_mac.cpp + } else:standardpathsjson { + SOURCES += io/qstandardpaths_json.cpp } else { SOURCES += io/qstandardpaths_unix.cpp } diff --git a/src/corelib/io/qstandardpaths_json.cpp b/src/corelib/io/qstandardpaths_json.cpp new file mode 100644 index 00000000000..52b194bea82 --- /dev/null +++ b/src/corelib/io/qstandardpaths_json.cpp @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui 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 "qstandardpaths.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef QT_NO_STANDARDPATHS + +QT_BEGIN_NAMESPACE + +class QStandardPathsPrivate { +public: + QStandardPathsPrivate() : object(0){} + ~QStandardPathsPrivate() { delete object.load(); } + QAtomicPointer object; +}; + +Q_GLOBAL_STATIC(QStandardPathsPrivate, configCache); + +QString QStandardPaths::writableLocation(StandardLocation type) +{ + switch (type) { + case HomeLocation: + return QDir::homePath(); // set $HOME + case TempLocation: + return QDir::tempPath(); // set $TMPDIR + default: + break; + } + + QJsonObject * localConfigObject = configCache()->object.loadAcquire(); + if (localConfigObject == 0) { + QString configHome = QFile::decodeName(qgetenv("PATH_CONFIG_HOME")); + if (configHome.isEmpty()) + configHome = QLatin1String("/etc/user-dirs.json"); + QFile file(configHome); + if (file.open(QIODevice::ReadOnly)) { + QJsonDocument configDoc = QJsonDocument::fromJson(file.readAll()); + if (configDoc.isNull()) + return QString(); + + QJsonObject myConfigObject = configDoc.object(); + localConfigObject = new QJsonObject(myConfigObject); + if (!configCache()->object.testAndSetRelease(0, localConfigObject)) { + delete localConfigObject; + localConfigObject = configCache()->object.loadAcquire(); + } + } else { + return QString(); + } + } + + QLatin1String key(""); + + switch (type) { + case DocumentsLocation: + key = QLatin1String("DOCUMENTS"); + break; + case PicturesLocation: + key = QLatin1String("PICTURES"); + break; + case MusicLocation: + key = QLatin1String("MUSIC"); + break; + case MoviesLocation: + key = QLatin1String("VIDEOS"); + break; + case DownloadLocation: + key = QLatin1String("DOWNLOAD"); + break; + case ApplicationsLocation: + key = QLatin1String("APPLICATIONS"); + break; + case CacheLocation: + key = QLatin1String("CACHE"); + break; + case GenericCacheLocation: + key = QLatin1String("GENERIC_CACHE"); + break; + case DataLocation: + key = QLatin1String("DATA"); + break; + case GenericDataLocation: + key = QLatin1String("GENERIC_DATA"); + break; + case ConfigLocation: + key = QLatin1String("CONFIG"); + break; + case RuntimeLocation: + key = QLatin1String("RUNTIME"); + break; + case DesktopLocation: + key = QLatin1String("DESKTOP"); + break; + case FontsLocation: + key = QLatin1String("FONTS"); + break; + + default: + return QString(); + } + + QJsonObject::const_iterator iter = localConfigObject->constFind(key); + if (iter == localConfigObject->constEnd() || ! iter.value().isString()) + return QString(); + QString value = iter.value().toString(); + + // optimize for a common case + value.replace(QLatin1String("${HOME}"), QFile::decodeName(qgetenv("HOME"))); + + // Do ${} format environment variable substitution if necessary + if (!value.isEmpty() && value.contains(QLatin1String("${"))) { + QRegExp varRegExp(QLatin1String("\\$\\{([^\\}]*)\\}")); + while (value.contains(varRegExp)) { + QString replacement = + QFile::decodeName(qgetenv(varRegExp.cap(1).toAscii().data())); + value.replace(varRegExp.cap(0), replacement); + } + } + return value; +} + +QStringList QStandardPaths::standardLocations(StandardLocation type) +{ + QStringList dirs; + const QString localDir = writableLocation(type); + dirs.prepend(localDir); + return dirs; +} + +QString QStandardPaths::displayName(StandardLocation type) +{ + Q_UNUSED(type); + return QString(); +} + +QT_END_NAMESPACE + +#endif // QT_NO_STANDARDPATHS From f89d02e0039562fadf8d8708bd71cff42a46b7a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 17 Feb 2012 10:19:35 +0100 Subject: [PATCH 315/406] Fixed API in QWindow: visible() -> isVisible(). Change-Id: I14706abb8441c153f738563cb1a46205fdb2dae6 QWindow::visible() did not follow the API guidelines. Reviewed-by: Gunnar Sletta --- src/gui/kernel/qguiapplication.cpp | 2 +- src/gui/kernel/qplatformscreen_qpa.cpp | 2 +- src/gui/kernel/qwindow.cpp | 10 ++++++++-- src/gui/kernel/qwindow.h | 6 ++++-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 9f8186424e5..625b466233d 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1487,7 +1487,7 @@ bool QGuiApplicationPrivate::shouldQuit() QWindowList list = QGuiApplication::topLevelWindows(); for (int i = 0; i < list.size(); ++i) { QWindow *w = list.at(i); - if (w->visible()) + if (w->isVisible()) return false; } return true; diff --git a/src/gui/kernel/qplatformscreen_qpa.cpp b/src/gui/kernel/qplatformscreen_qpa.cpp index b8f1430d1b2..c832d853f4b 100644 --- a/src/gui/kernel/qplatformscreen_qpa.cpp +++ b/src/gui/kernel/qplatformscreen_qpa.cpp @@ -93,7 +93,7 @@ QWindow *QPlatformScreen::topLevelAt(const QPoint & pos) const QWindowList list = QGuiApplication::topLevelWindows(); for (int i = list.size()-1; i >= 0; --i) { QWindow *w = list[i]; - if (w->visible() && w->geometry().contains(pos)) + if (w->isVisible() && w->geometry().contains(pos)) return w; } diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index d15198c5056..96fb3946430 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -185,7 +185,13 @@ void QWindow::setVisible(bool visible) } } + bool QWindow::visible() const +{ + return isVisible(); +} + +bool QWindow::isVisible() const { Q_D(const QWindow); @@ -965,7 +971,7 @@ bool QWindow::event(QEvent *ev) case QEvent::Close: { Q_D(QWindow); - bool wasVisible = visible(); + bool wasVisible = isVisible(); destroy(); if (wasVisible) d->maybeQuitOnLastWindowClosed(); @@ -1099,7 +1105,7 @@ void QWindowPrivate::maybeQuitOnLastWindowClosed() bool lastWindowClosed = true; for (int i = 0; i < list.size(); ++i) { QWindow *w = list.at(i); - if (!w->visible()) + if (!w->isVisible()) continue; lastWindowClosed = false; break; diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h index 98b468b1424..061426befb1 100644 --- a/src/gui/kernel/qwindow.h +++ b/src/gui/kernel/qwindow.h @@ -89,7 +89,7 @@ class Q_GUI_EXPORT QWindow : public QObject, public QSurface Q_PROPERTY(int y READ y WRITE setY NOTIFY yChanged) Q_PROPERTY(int width READ width WRITE setWidth NOTIFY widthChanged) Q_PROPERTY(int height READ height WRITE setHeight NOTIFY heightChanged) - Q_PROPERTY(bool visible READ visible WRITE setVisible NOTIFY visibleChanged) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged) Q_PROPERTY(Qt::ScreenOrientation contentOrientation READ contentOrientation WRITE reportContentOrientationChange NOTIFY contentOrientationChanged) public: @@ -101,7 +101,9 @@ public: void setSurfaceType(SurfaceType surfaceType); SurfaceType surfaceType() const; - bool visible() const; + QT_DEPRECATED bool visible() const; + + bool isVisible() const; void create(); From 304fc533bddde005ce786c4ab2da71678f89e379 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 15 Feb 2012 20:12:15 +0000 Subject: [PATCH 316/406] Fortune client example - list all IP addresses The first IP address on the machine might not be a usable one. Changed the QLineEdit to a QComboBox, and populated it with all IP addresses of the machine, along with the machine names if they are configured. Task-number: QTBUG-13121 Change-Id: I7c443f5ce6efb0d0b525c5abad1671d3dcbba33c Reviewed-by: Casper van Donderen --- examples/network/fortuneclient/client.cpp | 47 ++++++++++++++--------- examples/network/fortuneclient/client.h | 3 +- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/examples/network/fortuneclient/client.cpp b/examples/network/fortuneclient/client.cpp index 01048f137d4..fe16554eae9 100644 --- a/examples/network/fortuneclient/client.cpp +++ b/examples/network/fortuneclient/client.cpp @@ -51,26 +51,35 @@ Client::Client(QWidget *parent) hostLabel = new QLabel(tr("&Server name:")); portLabel = new QLabel(tr("S&erver port:")); - // find out which IP to connect to - QString ipAddress; - QList ipAddressesList = QNetworkInterface::allAddresses(); - // use the first non-localhost IPv4 address - for (int i = 0; i < ipAddressesList.size(); ++i) { - if (ipAddressesList.at(i) != QHostAddress::LocalHost && - ipAddressesList.at(i).toIPv4Address()) { - ipAddress = ipAddressesList.at(i).toString(); - break; - } + hostCombo = new QComboBox; + hostCombo->setEditable(true); + // find out name of this machine + QString name = QHostInfo::localHostName(); + if (!name.isEmpty()) { + hostCombo->addItem(name); + QString domain = QHostInfo::localDomainName(); + if (!domain.isEmpty()) + hostCombo->addItem(name + QChar('.') + domain); + } + if (name != QString("localhost")) + hostCombo->addItem(QString("localhost")); + // find out IP addresses of this machine + QList ipAddressesList = QNetworkInterface::allAddresses(); + // add non-localhost addresses + for (int i = 0; i < ipAddressesList.size(); ++i) { + if (!ipAddressesList.at(i).isLoopback()) + hostCombo->addItem(ipAddressesList.at(i).toString()); + } + // add localhost addresses + for (int i = 0; i < ipAddressesList.size(); ++i) { + if (ipAddressesList.at(i).isLoopback()) + hostCombo->addItem(ipAddressesList.at(i).toString()); } - // if we did not find one, use IPv4 localhost - if (ipAddress.isEmpty()) - ipAddress = QHostAddress(QHostAddress::LocalHost).toString(); - hostLineEdit = new QLineEdit(ipAddress); portLineEdit = new QLineEdit; portLineEdit->setValidator(new QIntValidator(1, 65535, this)); - hostLabel->setBuddy(hostLineEdit); + hostLabel->setBuddy(hostCombo); portLabel->setBuddy(portLineEdit); statusLabel = new QLabel(tr("This examples requires that you run the " @@ -90,7 +99,7 @@ Client::Client(QWidget *parent) tcpSocket = new QTcpSocket(this); //! [1] - connect(hostLineEdit, SIGNAL(textChanged(QString)), + connect(hostCombo, SIGNAL(editTextChanged(QString)), this, SLOT(enableGetFortuneButton())); connect(portLineEdit, SIGNAL(textChanged(QString)), this, SLOT(enableGetFortuneButton())); @@ -107,7 +116,7 @@ Client::Client(QWidget *parent) QGridLayout *mainLayout = new QGridLayout; mainLayout->addWidget(hostLabel, 0, 0); - mainLayout->addWidget(hostLineEdit, 0, 1); + mainLayout->addWidget(hostCombo, 0, 1); mainLayout->addWidget(portLabel, 1, 0); mainLayout->addWidget(portLineEdit, 1, 1); mainLayout->addWidget(statusLabel, 2, 0, 1, 2); @@ -150,7 +159,7 @@ void Client::requestNewFortune() blockSize = 0; tcpSocket->abort(); //! [7] - tcpSocket->connectToHost(hostLineEdit->text(), + tcpSocket->connectToHost(hostCombo->currentText(), portLineEdit->text().toInt()); //! [7] } @@ -224,7 +233,7 @@ void Client::displayError(QAbstractSocket::SocketError socketError) void Client::enableGetFortuneButton() { getFortuneButton->setEnabled((!networkSession || networkSession->isOpen()) && - !hostLineEdit->text().isEmpty() && + !hostCombo->currentText().isEmpty() && !portLineEdit->text().isEmpty()); } diff --git a/examples/network/fortuneclient/client.h b/examples/network/fortuneclient/client.h index 6e65e6e021c..dc652514762 100644 --- a/examples/network/fortuneclient/client.h +++ b/examples/network/fortuneclient/client.h @@ -45,6 +45,7 @@ #include QT_BEGIN_NAMESPACE +class QComboBox; class QDialogButtonBox; class QLabel; class QLineEdit; @@ -71,7 +72,7 @@ private slots: private: QLabel *hostLabel; QLabel *portLabel; - QLineEdit *hostLineEdit; + QComboBox *hostCombo; QLineEdit *portLineEdit; QLabel *statusLabel; QPushButton *getFortuneButton; From 3bd29d1f0af0c26189de7208582a23bfb9582e3c Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 15 Feb 2012 13:49:55 +0100 Subject: [PATCH 317/406] Clean up default arch setting on Mac OS X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove config.tests/mac/defaultarch.test, but do the same type of default arch detection, only using the qmake binary instead of compiling an empty file. Qt 5 will only support 10.6 and up, which means we only support i386 and x86_64 now. Change-Id: I24949ac803b965c523b1ee45cf769e266dcde134 Reviewed-by: Morten Johan Sørvig --- config.tests/mac/defaultarch.test | 33 -------------------------- configure | 39 +++++++++++++++++++------------ 2 files changed, 24 insertions(+), 48 deletions(-) delete mode 100755 config.tests/mac/defaultarch.test diff --git a/config.tests/mac/defaultarch.test b/config.tests/mac/defaultarch.test deleted file mode 100755 index 80f244a8bb2..00000000000 --- a/config.tests/mac/defaultarch.test +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh - -COMPILER=$1 -VERBOSE=$2 -WORKDIR=$3 -QT_MAC_DEFAULT_ARCH= - -touch defaultarch.c - -# compile something and run 'file' on it. -if "$COMPILER" -c defaultarch.c 2>/dev/null 1>&2; then - FIlE_OUTPUT=`file defaultarch.o` - [ "$VERBOSE" = "yes" ] && echo "'file' reports compiler ($COMPILER) default architechture as: $FIlE_OUTPUT" - -fi -rm -f defaultarch.c defaultarch.o - -# detect our known archs. -if echo "$FIlE_OUTPUT" | grep '\' > /dev/null 2>&1; then - QT_MAC_DEFAULT_ARCH=x86 # configure knows it as "x86" not "i386" -fi -if echo "$FIlE_OUTPUT" | grep '\' > /dev/null 2>&1; then - QT_MAC_DEFAULT_ARCH=x86_64 -fi -if echo "$FIlE_OUTPUT" | grep '\' > /dev/null 2>&1; then - QT_MAC_DEFAULT_ARCH=ppc -fi -if echo "$FIlE_OUTPUT" | grep '\' > /dev/null 2>&1; then - QT_MAC_DEFAULT_ARCH=ppc64 -fi - -[ "$VERBOSE" = "yes" ] && echo "setting QT_MAC_DEFAULT_ARCH to \"$QT_MAC_DEFAULT_ARCH\"" -export QT_MAC_DEFAULT_ARCH diff --git a/configure b/configure index 7e6aa9ef99e..1215f2f3e72 100755 --- a/configure +++ b/configure @@ -6315,11 +6315,30 @@ if [ "$CFG_MAC_DWARF2" = "yes" ]; then QT_CONFIG="$QT_CONFIG dwarf2" fi -# Set the default arch if there are no "-arch" arguments on the configure line -if [ "$PLATFORM_MAC" = "yes" ] && [ "$CFG_MAC_ARCHS" = "" ]; then - source "$mactests/defaultarch.test" "$TEST_COMPILER" "$OPT_VERBOSE" "$mactests" - CFG_MAC_ARCHS=" $QT_MAC_DEFAULT_ARCH" - [ "$OPT_VERBOSE" = "yes" ] && echo "Setting Mac architechture to$CFG_MAC_ARCHS." +# Set the default Mac OS X arch if there are no "-arch" arguments on the configure line +if [ "$BUILD_ON_MAC" = "yes" ]; then + DEFAULT_ARCH="$CFG_MAC_ARCHS" + if [ -z "$DEFAULT_ARCH" ]; then + case `file "${outpath}/bin/qmake"` in + *i?86) + DEFAULT_ARCH=x86 + ;; + *x86_64) + DEFAULT_ARCH=x86_64 + ;; + *ppc|*ppc64|*) + # unsupported/unknown + ;; + esac + fi + if [ -n "$DEFAULT_ARCH" ]; then + [ "$OPT_VERBOSE" = "yes" ] && echo "Setting default Mac OS X architechture to $DEFAULT_ARCH." + QT_CONFIG="$QT_CONFIG $DEFAULT_ARCH" + QMAKE_CONFIG="$QMAKE_CONFIG $DEFAULT_ARCH" + # Make the application arch follow the Qt arch for single arch builds. + # (for multiple-arch builds, set CONFIG manually in the application .pro file) + [ `echo "$DEFAULT_ARCH" | wc -w` -eq 1 ] && QTCONFIG_CONFIG="$QTCONFIG_CONFIG $DEFAULT_ARCH" + fi fi # ### Vestige @@ -6463,7 +6482,6 @@ fi [ "$CFG_AVX" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG avx" [ "$CFG_IWMMXT" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG iwmmxt" [ "$CFG_NEON" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG neon" -[ "$PLATFORM_MAC" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG $CFG_MAC_ARCHS" if [ "$CFG_CLOCK_GETTIME" = "yes" ]; then QT_CONFIG="$QT_CONFIG clock-gettime" fi @@ -7279,19 +7297,10 @@ else QT_CONFIG="$QT_CONFIG qt_framework" QTCONFIG_CONFIG="$QTCONFIG_CONFIG qt_framework" fi -if [ "$BUILD_ON_MAC" = "yes" ]; then - QT_CONFIG="$QT_CONFIG $CFG_MAC_ARCHS" -fi if [ "$CFG_DEV" = "yes" ]; then QT_CONFIG="$QT_CONFIG private_tests" fi -# Make the application arch follow the Qt arch for single arch builds. -# (for multiple-arch builds, set CONFIG manually in the application .pro file) -if [ `echo "$CFG_MAC_ARCHS" | wc -w` -eq 1 ]; then - QTCONFIG_CONFIG="$QTCONFIG_CONFIG $CFG_MAC_ARCHS" -fi - cat >>"$QTCONFIG.tmp" < Date: Fri, 17 Feb 2012 11:01:26 +0100 Subject: [PATCH 318/406] Qt 5 plugin system: Fix handling of namespaced plugin classes. - Add 'using namespace' to moc code as was the case in 4.8. Change-Id: I26cba9ad74bf05eecc5205714c32c3176695e3b4 Reviewed-by: Lars Knoll --- src/tools/moc/generator.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 8242fb45ece..f3a2b4a39b9 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -1096,6 +1096,10 @@ void Generator::generatePluginMetaData() } fprintf(out, " 0x%02x\n};\n", (uchar)binary.at(binary.size() - 1)); #endif + // 'Use' all namespaces. + int pos = cdef->qualified.indexOf("::"); + for ( ; pos != -1 ; pos = cdef->qualified.indexOf("::", pos + 2) ) + fprintf(out, "using namespace %s;\n", cdef->qualified.left(pos).constData()); fprintf(out, "QT_MOC_EXPORT_PLUGIN(%s)\n\n", cdef->classname.constData()); } From a61f754c928c715cfb59a1b20c26920c54eb38c0 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 17 Feb 2012 10:48:22 +0200 Subject: [PATCH 319/406] Fix "check" target when load(testcase) is used in .pro file. The "check" target always depended on debug-check on projects that explicitly loaded the testcase.prf, even if Qt was configured with -release parameter. This obviously caused build failure. Changed the testcase.prf to check which configuration is preferred using CONFIG(debug, debug|release) like is done with similar cases in other .prf files. Task-number: QTBUG-24332 Change-Id: Ib5140b106e99efe51932bdd5a48914786de23230 Reviewed-by: Oswald Buddenhagen Reviewed-by: Friedemann Kleint --- mkspecs/features/testcase.prf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/testcase.prf b/mkspecs/features/testcase.prf index f890e97733e..9bb9875f6d3 100644 --- a/mkspecs/features/testcase.prf +++ b/mkspecs/features/testcase.prf @@ -49,11 +49,11 @@ QMAKE_EXTRA_TARGETS *= check } else { check.CONFIG = recursive # In debug and release mode, only run the test once. - # Run debug if available, release otherwise. + # Run debug if that is the preferred config, release otherwise. debug_and_release { check.target = dummy_check check.recurse_target = check - debug { + CONFIG(debug, debug|release) { real_check.depends = debug-check real_check.target = check QMAKE_EXTRA_TARGETS += real_check From 3efb0d50e590f6a1e8d67d0136a648cd3b97c37d Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 17 Feb 2012 12:28:50 +0200 Subject: [PATCH 320/406] Disable 'check' target generation for network autotests for Windows. A number of network autotests are unstable in Windows, so don't generate check target for them as is done for mac. Once the tests are acceptably stable, this needs to be reverted. Change-Id: I18262e28ce40eba541aecf3cfb651bff34698ead Reviewed-by: Friedemann Kleint --- tests/auto/auto.pro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 1796fa2db92..63c4ca6a48d 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -18,8 +18,8 @@ cross_compile: SUBDIRS -= tools !contains(QT_CONFIG, opengl): SUBDIRS -= opengl !unix|embedded|!contains(QT_CONFIG, dbus): SUBDIRS -= dbus -# disable 'make check' on Mac OS X for the following subdirs for the time being -mac { +# disable 'make check' on Mac OS X and Windows for the following subdirs for the time being +mac|win32 { network.CONFIG += no_check_target } From 93af98f72a9f7bbca6013382349c0a2e7f1ab1a7 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 14 Feb 2012 16:46:31 +0100 Subject: [PATCH 321/406] Widgets: Remove obsolete QGuiPlatformPlugin. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It has been superseeded by QPlatformTheme. Task-number: QTBUG-24204 Change-Id: I8c4131c7bfd8201e747984d772ed8042610192b8 Reviewed-by: Morten Johan Sørvig --- src/widgets/itemviews/qfileiconprovider.cpp | 5 - src/widgets/kernel/kernel.pri | 2 - src/widgets/kernel/qapplication.cpp | 6 - src/widgets/kernel/qguiplatformplugin.cpp | 134 -------------------- src/widgets/kernel/qguiplatformplugin_p.h | 101 --------------- 5 files changed, 248 deletions(-) delete mode 100644 src/widgets/kernel/qguiplatformplugin.cpp delete mode 100644 src/widgets/kernel/qguiplatformplugin_p.h diff --git a/src/widgets/itemviews/qfileiconprovider.cpp b/src/widgets/itemviews/qfileiconprovider.cpp index e90f78c801a..b6669c0784d 100644 --- a/src/widgets/itemviews/qfileiconprovider.cpp +++ b/src/widgets/itemviews/qfileiconprovider.cpp @@ -47,7 +47,6 @@ #include #include #include -#include #if defined(Q_OS_WIN) # define _WIN32_IE 0x0500 @@ -399,10 +398,6 @@ QIcon QFileIconProvider::icon(const QFileInfo &info) const { Q_D(const QFileIconProvider); - QIcon platformIcon = qt_guiPlatformPlugin()->fileSystemIcon(info); - if (!platformIcon.isNull()) - return platformIcon; - #if defined(Q_WS_X11) && !defined(QT_NO_STYLE_GTK) if (X11->desktopEnvironment == DE_GNOME) { QIcon gtkIcon = QGtkStylePrivate::getFilesystemIcon(info); diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri index 80f165063c7..97430babd34 100644 --- a/src/widgets/kernel/kernel.pri +++ b/src/widgets/kernel/kernel.pri @@ -40,7 +40,6 @@ HEADERS += \ kernel/qgesturemanager_p.h \ kernel/qsoftkeymanager_p.h \ kernel/qsoftkeymanager_common_p.h \ - kernel/qguiplatformplugin_p.h \ kernel/qdesktopwidget_qpa_p.h \ kernel/qwidgetwindow_qpa_p.h \ kernel/qplatformmenu_qpa.h @@ -72,7 +71,6 @@ SOURCES += \ kernel/qgesturemanager.cpp \ kernel/qsoftkeymanager.cpp \ kernel/qdesktopwidget.cpp \ - kernel/qguiplatformplugin.cpp \ kernel/qwidgetsvariant.cpp \ kernel/qapplication_qpa.cpp \ kernel/qdesktopwidget_qpa.cpp \ diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index ae4f5e01b79..f7153a0f329 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -80,8 +80,6 @@ #include #endif -#include "qguiplatformplugin_p.h" - #include #include @@ -758,10 +756,6 @@ void QApplicationPrivate::construct( qCritical("Library qttestability load failed!"); } } - - //make sure the plugin is loaded - if (qt_is_gui_used) - qt_guiPlatformPlugin(); #endif } diff --git a/src/widgets/kernel/qguiplatformplugin.cpp b/src/widgets/kernel/qguiplatformplugin.cpp deleted file mode 100644 index f5c8399a0ba..00000000000 --- a/src/widgets/kernel/qguiplatformplugin.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtGui 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 "qguiplatformplugin_p.h" -#include -#include -#include -#include -#include "private/qfactoryloader_p.h" -#include "qstylefactory.h" -#include "qapplication.h" -#include "qplatformdefs.h" -#include "qicon.h" - -#ifdef Q_OS_WINCE -extern bool qt_wince_is_smartphone(); //qguifunctions_wince.cpp -extern bool qt_wince_is_mobile(); //qguifunctions_wince.cpp -extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp -#endif - - -#if defined(Q_WS_X11) -#include -#include -#include -#endif - - -QT_BEGIN_NAMESPACE - - -/*! \internal - Return (an construct if necesseray) the Gui Platform plugin. - - The plugin key to be loaded is inside the QT_PLATFORM_PLUGIN environment variable. - If it is not set, it will be the DESKTOP_SESSION on X11. - - If no plugin can be loaded, the default one is returned. - */ -QGuiPlatformPlugin *qt_guiPlatformPlugin() -{ - static QGuiPlatformPlugin *plugin; - if (!plugin) - { -#ifndef QT_NO_LIBRARY - - QString key = QString::fromLocal8Bit(qgetenv("QT_PLATFORM_PLUGIN")); -#ifdef Q_WS_X11 - if (key.isEmpty()) { - switch(X11->desktopEnvironment) { - case DE_KDE: - key = QString::fromLatin1("kde"); - break; - default: - key = QString::fromLocal8Bit(qgetenv("DESKTOP_SESSION")); - break; - } - } -#endif - - if (!key.isEmpty() && QApplication::desktopSettingsAware()) { - QFactoryLoader loader(QGuiPlatformPluginInterface_iid, QLatin1String("/gui_platform")); - plugin = qobject_cast(loader.instance(key)); - } -#endif // QT_NO_LIBRARY - - if(!plugin) { - static QGuiPlatformPlugin def; - plugin = &def; - } - } - return plugin; -} - - -/* \class QPlatformPlugin - QGuiPlatformPlugin can be used to integrate Qt applications in a platform built on top of Qt. - The application developer should not know or use the plugin, it is only used by Qt internaly. - - But full platforms that are built on top of Qt may provide a plugin so 3rd party Qt applications - running on the platform are integrated. - */ - -/* - The constructor can be used to install hooks in Qt - */ -QGuiPlatformPlugin::QGuiPlatformPlugin(QObject *parent) : QObject(parent) {} -QGuiPlatformPlugin::~QGuiPlatformPlugin() {} - -/* backend for QFileIconProvider, null icon means default */ -QIcon QGuiPlatformPlugin::fileSystemIcon(const QFileInfo &) -{ - return QIcon(); -} - -QT_END_NAMESPACE diff --git a/src/widgets/kernel/qguiplatformplugin_p.h b/src/widgets/kernel/qguiplatformplugin_p.h deleted file mode 100644 index c42db3bb923..00000000000 --- a/src/widgets/kernel/qguiplatformplugin_p.h +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtGui 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 QGUIPLATFORM_P_H -#define QGUIPLATFORM_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - - -class QStyle; -class QPalette; -class QIcon; -class QFileDialog; -class QColorDialog; -class QFileInfo; - -struct Q_WIDGETS_EXPORT QGuiPlatformPluginInterface : public QFactoryInterface -{ -}; - -#define QGuiPlatformPluginInterface_iid "com.nokia.qt.QGuiPlatformPluginInterface" - -Q_DECLARE_INTERFACE(QGuiPlatformPluginInterface, QGuiPlatformPluginInterface_iid) - -class Q_WIDGETS_EXPORT QGuiPlatformPlugin : public QObject, public QGuiPlatformPluginInterface -{ - Q_OBJECT - Q_INTERFACES(QGuiPlatformPluginInterface:QFactoryInterface) - public: - explicit QGuiPlatformPlugin(QObject *parent = 0); - ~QGuiPlatformPlugin(); - - virtual QStringList keys() const { return QStringList(QStringLiteral("default")); } - - virtual QIcon fileSystemIcon(const QFileInfo &); -}; - -//internal -QGuiPlatformPlugin *qt_guiPlatformPlugin(); - -QT_END_NAMESPACE - -QT_END_HEADER - - -#endif // QGUIPLATFORMPLUGIN_H From 70ac149a16a632309dbba48385f0dfc9ebc9d774 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 17 Feb 2012 13:59:20 +0100 Subject: [PATCH 322/406] Fix another typo in the evdev keyboard plugin. Amend 3296b7327bd84f420df7e5561d192c0a8d0bb409 Change-Id: Ide58a6b8cbd980eda6ff91948c8f4fb45a30e527 Reviewed-by: Friedemann Kleint --- src/plugins/generic/evdevkeyboard/evdevkeyboard.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro b/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro index 243cd0c0b1e..997a58ef6e5 100644 --- a/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro +++ b/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro @@ -6,7 +6,7 @@ target.path = $$[QT_INSTALL_PLUGINS]/generic INSTALLS += target HEADERS = \ - qevdevkeybaord_defaultmap.h \ + qevdevkeyboard_defaultmap.h \ qevdevkeyboardhandler.h \ qevdevkeyboardmanager.h From f8e2753323248e2c8d5812a4a4f4b28aff61aa17 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 16 Feb 2012 13:36:27 +0200 Subject: [PATCH 323/406] Make 'nmake check' succeed for widgets tests Marked a bunch of tests insignificant, and skipped one crashing test case in QApplication test, as that couldn't be made to pass simply by marking the test insignificant. Once the underlying issues are fixed, the tests need to be re-enabled. Task-number: QTBUG-24203 Change-Id: I9aea4fa207d307793445efdcaead72219fbf6c4f Reviewed-by: Sergio Ahumada Reviewed-by: Friedemann Kleint --- .../auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro | 2 ++ .../graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro | 2 ++ .../widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro | 2 ++ .../auto/widgets/graphicsview/qgraphicsview/qgraphicsview.pro | 2 ++ tests/auto/widgets/itemviews/qlistwidget/qlistwidget.pro | 2 ++ tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp | 3 +++ .../auto/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro | 2 ++ tests/auto/widgets/widgets/qmenu/qmenu.pro | 2 ++ tests/auto/widgets/widgets/qmenubar/qmenubar.pro | 2 ++ tests/auto/widgets/widgets/qtextedit/qtextedit.pro | 2 ++ 10 files changed, 21 insertions(+) diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro b/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro index 166306757c2..6e08e2d02bd 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro @@ -5,3 +5,5 @@ QT += core-private gui testlib SOURCES += tst_qfilesystemmodel.cpp TARGET = tst_qfilesystemmodel + +win32:CONFIG += insignificant_test # QTBUG-24291 diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro index 50f4f7ab746..f2bd7bde708 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro +++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro @@ -8,3 +8,5 @@ SOURCES += tst_qgraphicsproxywidget.cpp # ### fixme: QTBUG-20756 crashes on xcb contains(QT_CONFIG,xcb):CONFIG+=insignificant_test + +win32:CONFIG += insignificant_test # QTBUG-24294 diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro b/tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro index 8a084472b88..c0a9075d104 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro @@ -17,3 +17,5 @@ wince* { DEPLOYMENT += rootFiles renderFiles DEFINES += SRCDIR=\\\".\\\" } + +win32:CONFIG += insignificant_test # QTBUG-24295 diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/qgraphicsview.pro b/tests/auto/widgets/graphicsview/qgraphicsview/qgraphicsview.pro index e3a6edd6820..439cf547ef2 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/qgraphicsview.pro +++ b/tests/auto/widgets/graphicsview/qgraphicsview/qgraphicsview.pro @@ -8,3 +8,5 @@ SOURCES += tst_qgraphicsview.cpp tst_qgraphicsview_2.cpp DEFINES += QT_NO_CAST_TO_ASCII linux-*:system(". /etc/lsb-release && [ $DISTRIB_CODENAME = oneiric ]"):CONFIG+=insignificant_test + +win32:CONFIG += insignificant_test # QTBUG-24296 diff --git a/tests/auto/widgets/itemviews/qlistwidget/qlistwidget.pro b/tests/auto/widgets/itemviews/qlistwidget/qlistwidget.pro index f3979576092..8821ac7038b 100644 --- a/tests/auto/widgets/itemviews/qlistwidget/qlistwidget.pro +++ b/tests/auto/widgets/itemviews/qlistwidget/qlistwidget.pro @@ -5,3 +5,5 @@ QT += core-private gui-private SOURCES += tst_qlistwidget.cpp contains(QT_CONFIG,xcb):CONFIG+=insignificant_test # QTBUG-21098, fails unstably + +win32:CONFIG += insignificant_test # QTBUG-24299 diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index fc38840bf77..6e4bbc75c21 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -601,6 +601,9 @@ public slots: void tst_QApplication::quitOnLastWindowClosed() { +#ifdef Q_OS_WIN32 + QSKIP("This test crashes on Windows. Remove skip once the issue causing the crash is fixed (QTBUG-24300)."); +#endif #ifndef Q_OS_MAC // Test hangs on Mac OS X, see QTBUG-24319 { diff --git a/tests/auto/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro b/tests/auto/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro index 137d6a2bc55..f908c3ab7d2 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro +++ b/tests/auto/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro @@ -6,3 +6,5 @@ QT += gui-private SOURCES += tst_qstylesheetstyle.cpp RESOURCES += resources.qrc requires(contains(QT_CONFIG,private_tests)) + +win32:CONFIG += insignificant_test # QTBUG-24323 diff --git a/tests/auto/widgets/widgets/qmenu/qmenu.pro b/tests/auto/widgets/widgets/qmenu/qmenu.pro index f919c12cb50..55099f1c54c 100644 --- a/tests/auto/widgets/widgets/qmenu/qmenu.pro +++ b/tests/auto/widgets/widgets/qmenu/qmenu.pro @@ -2,3 +2,5 @@ CONFIG += testcase TARGET = tst_qmenu QT += widgets testlib SOURCES += tst_qmenu.cpp + +win32:CONFIG += insignificant_test # QTBUG-24325 diff --git a/tests/auto/widgets/widgets/qmenubar/qmenubar.pro b/tests/auto/widgets/widgets/qmenubar/qmenubar.pro index 6bacaa0d37e..6f35d4516fb 100644 --- a/tests/auto/widgets/widgets/qmenubar/qmenubar.pro +++ b/tests/auto/widgets/widgets/qmenubar/qmenubar.pro @@ -5,3 +5,5 @@ SOURCES += tst_qmenubar.cpp # QTBUG-4965, QTBUG-11823 - unstable tests linux-*:system(". /etc/lsb-release && [ $DISTRIB_CODENAME = oneiric ]"):CONFIG += insignificant_test + +win32:CONFIG += insignificant_test # QTBUG-24326 diff --git a/tests/auto/widgets/widgets/qtextedit/qtextedit.pro b/tests/auto/widgets/widgets/qtextedit/qtextedit.pro index 85658c222e3..294f1d84e75 100644 --- a/tests/auto/widgets/widgets/qtextedit/qtextedit.pro +++ b/tests/auto/widgets/widgets/qtextedit/qtextedit.pro @@ -17,3 +17,5 @@ wince* { } contains(QT_CONFIG,xcb):CONFIG+=insignificant_test # QTBUG-20756 crashes on xcb + +win32:CONFIG += insignificant_test # QTBUG-24348 From a68ada633f165d1a6f9d4a4b3cab26487e92cb21 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 16 Feb 2012 16:38:52 +0100 Subject: [PATCH 324/406] QSize/QSizeF: add const versions of scale()/transpose() Non-mutating functions can (potentially) be constexpr. On top of that, they often make for more readable code. Change-Id: I3547327cf5a7162737353a864a1025d0d02ccc2f Reviewed-by: Gunnar Sletta Reviewed-by: David Faure --- src/corelib/tools/qsize.cpp | 79 ++++++++++++++++++++++++++++--------- src/corelib/tools/qsize.h | 24 +++++++++++ 2 files changed, 85 insertions(+), 18 deletions(-) diff --git a/src/corelib/tools/qsize.cpp b/src/corelib/tools/qsize.cpp index d5e6f18326a..4c94f899e73 100644 --- a/src/corelib/tools/qsize.cpp +++ b/src/corelib/tools/qsize.cpp @@ -160,7 +160,7 @@ QT_BEGIN_NAMESPACE /*! Swaps the width and height values. - \sa setWidth(), setHeight() + \sa setWidth(), setHeight(), transposed() */ void QSize::transpose() @@ -170,6 +170,15 @@ void QSize::transpose() ht = tmp; } +/*! + \fn QSize QSize::transposed() const + \since 5.0 + + Returns a QSize with width and height swapped. + + \sa transpose() +*/ + /*! \fn void QSize::scale(int width, int height, Qt::AspectRatioMode mode) @@ -187,7 +196,7 @@ void QSize::transpose() Example: \snippet doc/src/snippets/code/src_corelib_tools_qsize.cpp 0 - \sa setWidth(), setHeight() + \sa setWidth(), setHeight(), scaled() */ /*! @@ -197,11 +206,25 @@ void QSize::transpose() Scales the size to a rectangle with the given \a size, according to the specified \a mode. */ -void QSize::scale(const QSize &s, Qt::AspectRatioMode mode) + +/*! + \fn QSize QSize::scaled(int width, int height, Qt::AspectRatioMode mode) const + \since 5.0 + + Return a size scaled to a rectangle with the given \a width and \a + height, according to the specified \a mode. + + \sa scale() +*/ + +/*! + \overload + \since 5.0 +*/ +QSize QSize::scaled(const QSize &s, Qt::AspectRatioMode mode) const { if (mode == Qt::IgnoreAspectRatio || wd == 0 || ht == 0) { - wd = s.wd; - ht = s.ht; + return s; } else { bool useHeight; qint64 rw = qint64(s.ht) * qint64(wd) / qint64(ht); @@ -213,11 +236,10 @@ void QSize::scale(const QSize &s, Qt::AspectRatioMode mode) } if (useHeight) { - wd = rw; - ht = s.ht; + return QSize(rw, s.ht); } else { - ht = qint32(qint64(s.wd) * qint64(ht) / qint64(wd)); - wd = s.wd; + return QSize(s.wd, + qint32(qint64(s.wd) * qint64(ht) / qint64(wd))); } } } @@ -566,7 +588,7 @@ QDebug operator<<(QDebug dbg, const QSize &s) { /*! Swaps the width and height values. - \sa setWidth(), setHeight() + \sa setWidth(), setHeight(), transposed() */ void QSizeF::transpose() @@ -576,6 +598,15 @@ void QSizeF::transpose() ht = tmp; } +/*! + \fn QSizeF QSizeF::transposed() const + \since 5.0 + + Returns the size with width and height values swapped. + + \sa transpose() +*/ + /*! \fn void QSizeF::scale(qreal width, qreal height, Qt::AspectRatioMode mode) @@ -593,7 +624,7 @@ void QSizeF::transpose() Example: \snippet doc/src/snippets/code/src_corelib_tools_qsize.cpp 5 - \sa setWidth(), setHeight() + \sa setWidth(), setHeight(), scaled() */ /*! @@ -603,11 +634,25 @@ void QSizeF::transpose() Scales the size to a rectangle with the given \a size, according to the specified \a mode. */ -void QSizeF::scale(const QSizeF &s, Qt::AspectRatioMode mode) + +/*! + \fn QSizeF QSizeF::scaled(int width, int height, Qt::AspectRatioMode mode) const + \since 5.0 + + Returns a size scaled to a rectangle with the given \a width and + \a height, according to the specified \mode. + + \sa scale() +*/ + +/*! + \overload + \since 5.0 +*/ +QSizeF QSizeF::scaled(const QSizeF &s, Qt::AspectRatioMode mode) const { if (mode == Qt::IgnoreAspectRatio || qIsNull(wd) || qIsNull(ht)) { - wd = s.wd; - ht = s.ht; + return s; } else { bool useHeight; qreal rw = s.ht * wd / ht; @@ -619,11 +664,9 @@ void QSizeF::scale(const QSizeF &s, Qt::AspectRatioMode mode) } if (useHeight) { - wd = rw; - ht = s.ht; + return QSizeF(rw, s.ht); } else { - ht = s.wd * ht / wd; - wd = s.wd; + return QSizeF(s.wd, s.wd * ht / wd); } } } diff --git a/src/corelib/tools/qsize.h b/src/corelib/tools/qsize.h index 5400f76a3ad..fece0ac943a 100644 --- a/src/corelib/tools/qsize.h +++ b/src/corelib/tools/qsize.h @@ -64,9 +64,12 @@ public: void setWidth(int w); void setHeight(int h); void transpose(); + QSize transposed() const; void scale(int w, int h, Qt::AspectRatioMode mode); void scale(const QSize &s, Qt::AspectRatioMode mode); + QSize scaled(int w, int h, Qt::AspectRatioMode mode) const; + QSize scaled(const QSize &s, Qt::AspectRatioMode mode) const; QSize expandedTo(const QSize &) const; QSize boundedTo(const QSize &) const; @@ -134,9 +137,18 @@ inline void QSize::setWidth(int w) inline void QSize::setHeight(int h) { ht = h; } +inline QSize QSize::transposed() const +{ return QSize(ht, wd); } + inline void QSize::scale(int w, int h, Qt::AspectRatioMode mode) { scale(QSize(w, h), mode); } +inline void QSize::scale(const QSize &s, Qt::AspectRatioMode mode) +{ *this = scaled(s, mode); } + +inline QSize QSize::scaled(int w, int h, Qt::AspectRatioMode mode) const +{ return scaled(QSize(w, h), mode); } + inline int &QSize::rwidth() { return wd; } @@ -214,9 +226,12 @@ public: void setWidth(qreal w); void setHeight(qreal h); void transpose(); + QSizeF transposed() const; void scale(qreal w, qreal h, Qt::AspectRatioMode mode); void scale(const QSizeF &s, Qt::AspectRatioMode mode); + QSizeF scaled(qreal w, qreal h, Qt::AspectRatioMode mode) const; + QSizeF scaled(const QSizeF &s, Qt::AspectRatioMode mode) const; QSizeF expandedTo(const QSizeF &) const; QSizeF boundedTo(const QSizeF &) const; @@ -292,9 +307,18 @@ inline void QSizeF::setWidth(qreal w) inline void QSizeF::setHeight(qreal h) { ht = h; } +inline QSizeF QSizeF::transposed() const +{ return QSizeF(ht, wd); } + inline void QSizeF::scale(qreal w, qreal h, Qt::AspectRatioMode mode) { scale(QSizeF(w, h), mode); } +inline void QSizeF::scale(const QSizeF &s, Qt::AspectRatioMode mode) +{ *this = scaled(s, mode); } + +inline QSizeF QSizeF::scaled(qreal w, qreal h, Qt::AspectRatioMode mode) const +{ return scaled(QSizeF(w, h), mode); } + inline qreal &QSizeF::rwidth() { return wd; } From 6f7bd6532d34713811c8f70b287d151d24cdda7c Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 15 Feb 2012 15:34:09 +0000 Subject: [PATCH 325/406] Update documentation to show NTLMv2 is supported This feature was implemented in 4.8, but documentation was not updated at the time. Task-number: QTBUG-18181 Change-Id: I657d7ab7aaf43b73b7bf8fd1cb76086522cf5c2b Reviewed-by: Thiago Macieira --- src/network/kernel/qauthenticator.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp index 36f47eb5b4e..b14fbf8c30d 100644 --- a/src/network/kernel/qauthenticator.cpp +++ b/src/network/kernel/qauthenticator.cpp @@ -81,12 +81,10 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas QAuthenticator supports the following authentication methods: \list \o Basic - \o NTLM version 1 + \o NTLM version 2 \o Digest-MD5 \endlist - Note that, in particular, NTLM version 2 is not supported. - \section1 Options In addition to the username and password required for authentication, a @@ -112,7 +110,7 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas The Basic authentication mechanism supports no outgoing options. - \section2 NTLM version 1 + \section2 NTLM version 2 The NTLM authentication mechanism currently supports no incoming or outgoing options. From d425a0dad38e51c99cfe59294a3706ced90b24a0 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 15 Feb 2012 17:58:11 +0000 Subject: [PATCH 326/406] Fix incorrect use of QObject::disconnect in synchronous http request In certain circumstances, this could cause the request to time out (and repeatedly send bad authentication credentials to the server) instead of failing with AuthenticationRequiredError. Change-Id: Iff66b32f1d7268f21fd77b6620aae4b5d49d857f Reviewed-by: Richard J. Moore --- src/network/access/qhttpthreaddelegate.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp index 5cf153325ba..3901635ca07 100644 --- a/src/network/access/qhttpthreaddelegate.cpp +++ b/src/network/access/qhttpthreaddelegate.cpp @@ -560,7 +560,8 @@ void QHttpThreadDelegate::synchronousAuthenticationRequiredSlot(const QHttpNetwo } // Disconnect this connection now since we only want to ask the authentication cache once. - QObject::disconnect(this, SLOT(synchronousAuthenticationRequiredSlot(QHttpNetworkRequest,QAuthenticator*))); + QObject::disconnect(httpReply, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)), + this, SLOT(synchronousAuthenticationRequiredSlot(QHttpNetworkRequest,QAuthenticator*))); } #ifndef QT_NO_NETWORKPROXY @@ -577,7 +578,8 @@ void QHttpThreadDelegate::synchronousProxyAuthenticationRequiredSlot(const QNet } // Disconnect this connection now since we only want to ask the authentication cache once. - QObject::disconnect(this, SLOT(synchronousProxyAuthenticationRequiredSlot(QNetworkProxy,QAuthenticator*))); + QObject::disconnect(httpReply, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + this, SLOT(synchronousProxyAuthenticationRequiredSlot(QNetworkProxy,QAuthenticator*))); } #endif From b4a538ea1c3cdce09e3528227dba2e8f5765cbdc Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 15 Feb 2012 17:24:14 +0000 Subject: [PATCH 327/406] Fix handling of urls containing username/password in QNetworkAccessManager QNetworkAccessManager was ignoring the supplied credentials, although webkit seems to support these urls at a higher level. Following the behaviour of browsers: We use supplied credentials if authentication is required. We add supplied credentials to the authentication cache. We emit authenticationRequired signal if the credentials were wrong. We do not use previously cached credentials for that url Synchronous http requests fail, if the credentials were wrong. Task-number: QTBUG-18107 Change-Id: If46e8eab1511ba8a0f4bbe0d4efaabc4df0b8ab4 Reviewed-by: Richard J. Moore Reviewed-by: Thiago Macieira --- src/network/access/qnetworkaccessmanager.cpp | 10 +++ .../qnetworkreply/tst_qnetworkreply.cpp | 63 ++++++++++++++++--- 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 85375021169..7be9d278f79 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -1094,6 +1094,16 @@ void QNetworkAccessManagerPrivate::authenticationRequired(QAuthenticator *authen // also called when last URL is empty, e.g. on first call if (urlForLastAuthentication->isEmpty() || url != *urlForLastAuthentication) { + // if credentials are included in the url, then use them + if (!url.userName().isEmpty() + && !url.password().isEmpty()) { + authenticator->setUser(url.userName()); + authenticator->setPassword(url.password()); + *urlForLastAuthentication = url; + authenticationManager->cacheCredentials(url, authenticator); + return; + } + QNetworkAuthenticationCredential cred = authenticationManager->fetchCachedCredentials(url, authenticator); if (!cred.isNull()) { authenticator->setUser(cred.user); diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 279613904f9..279570b5474 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -2823,12 +2823,21 @@ void tst_QNetworkReply::ioGetFromHttpWithAuth_data() { QTest::addColumn("url"); QTest::addColumn("expectedData"); + QTest::addColumn("expectedAuth"); QFile reference(testDataDir + "/rfc3252.txt"); reference.open(QIODevice::ReadOnly); QByteArray referenceData = reference.readAll(); - QTest::newRow("basic") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt") << referenceData; - QTest::newRow("digest") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/auth-digest/") << QByteArray("digest authentication successful\n"); + QTest::newRow("basic") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt") << referenceData << 1; + QTest::newRow("digest") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/auth-digest/") << QByteArray("digest authentication successful\n") << 1; + //if url contains username & password, then it should be used + QTest::newRow("basic-in-url") << QUrl("http://httptest:httptest@" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt") << referenceData << 0; + QTest::newRow("digest-in-url") << QUrl("http://httptest:httptest@" + QtNetworkSettings::serverName() + "/qtest/auth-digest/") << QByteArray("digest authentication successful\n") << 0; + // if url contains incorrect credentials, expect QNAM to ask for good ones (even if cached - matches behaviour of browsers) + QTest::newRow("basic-bad-user-in-url") << QUrl("http://baduser:httptest@" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt") << referenceData << 3; + QTest::newRow("basic-bad-password-in-url") << QUrl("http://httptest:wrong@" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt") << referenceData << 3; + QTest::newRow("digest-bad-user-in-url") << QUrl("http://baduser:httptest@" + QtNetworkSettings::serverName() + "/qtest/auth-digest/") << QByteArray("digest authentication successful\n") << 3; + QTest::newRow("digest-bad-password-in-url") << QUrl("http://httptest:wrong@" + QtNetworkSettings::serverName() + "/qtest/auth-digest/") << QByteArray("digest authentication successful\n") << 3; } void tst_QNetworkReply::ioGetFromHttpWithAuth() @@ -2839,6 +2848,7 @@ void tst_QNetworkReply::ioGetFromHttpWithAuth() QFETCH(QUrl, url); QFETCH(QByteArray, expectedData); + QFETCH(int, expectedAuth); QNetworkRequest request(url); { QNetworkReplyPtr reply1 = manager.get(request); @@ -2862,7 +2872,8 @@ void tst_QNetworkReply::ioGetFromHttpWithAuth() QCOMPARE(reader1.data, expectedData); QCOMPARE(reader2.data, expectedData); - QCOMPARE(authspy.count(), 1); + QCOMPARE(authspy.count(), (expectedAuth ? 1 : 0)); + expectedAuth = qMax(0, expectedAuth - 1); } // rinse and repeat: @@ -2882,7 +2893,8 @@ void tst_QNetworkReply::ioGetFromHttpWithAuth() QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); QCOMPARE(reader.data, expectedData); - QCOMPARE(authspy.count(), 0); + QCOMPARE(authspy.count(), (expectedAuth ? 1 : 0)); + expectedAuth = qMax(0, expectedAuth - 1); } // now check with synchronous calls: @@ -2894,14 +2906,45 @@ void tst_QNetworkReply::ioGetFromHttpWithAuth() QSignalSpy authspy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); QNetworkReplyPtr replySync = manager.get(request); QVERIFY(replySync->isFinished()); // synchronous - QCOMPARE(authspy.count(), 0); + if (expectedAuth) { + // bad credentials in a synchronous request should just fail + QCOMPARE(replySync->error(), QNetworkReply::AuthenticationRequiredError); + } else { + QCOMPARE(authspy.count(), 0); - // we cannot use a data reader here, since that connects to the readyRead signal, - // just use readAll() + // we cannot use a data reader here, since that connects to the readyRead signal, + // just use readAll() - // the only thing we check here is that the auth cache was used when using synchronous requests - QCOMPARE(replySync->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); - QCOMPARE(replySync->readAll(), expectedData); + // the only thing we check here is that the auth cache was used when using synchronous requests + QCOMPARE(replySync->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); + QCOMPARE(replySync->readAll(), expectedData); + } + } + + // check that credentials are used from cache if the same url is requested without credentials + { + url.setUserInfo(QString()); + request.setUrl(url); + request.setAttribute( + QNetworkRequest::SynchronousRequestAttribute, + true); + + QSignalSpy authspy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); + QNetworkReplyPtr replySync = manager.get(request); + QVERIFY(replySync->isFinished()); // synchronous + if (expectedAuth) { + // bad credentials in a synchronous request should just fail + QCOMPARE(replySync->error(), QNetworkReply::AuthenticationRequiredError); + } else { + QCOMPARE(authspy.count(), 0); + + // we cannot use a data reader here, since that connects to the readyRead signal, + // just use readAll() + + // the only thing we check here is that the auth cache was used when using synchronous requests + QCOMPARE(replySync->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); + QCOMPARE(replySync->readAll(), expectedData); + } } } From d5a65cb526366754f52d21e1b4c4f55c54012945 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 17 Feb 2012 11:59:48 +0100 Subject: [PATCH 328/406] Fix warnings about missing file. Change-Id: I8644d2b80bab9c18f666d742da389e84bf3f124c Reviewed-by: Xizhi Zhu --- src/network/kernel/kernel.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index 091d67ccc42..adc72bbcbb6 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -27,7 +27,7 @@ SOURCES += kernel/qauthenticator.cpp \ unix:SOURCES += kernel/qdnslookup_unix.cpp kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp win32: { - HEADERS += qnetworkinterface_win_p.h + HEADERS += kernel/qnetworkinterface_win_p.h SOURCES += kernel/qdnslookup_win.cpp kernel/qhostinfo_win.cpp kernel/qnetworkinterface_win.cpp } integrity:SOURCES += kernel/qdnslookup_unix.cpp kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp From aee4cbf22a5942c7bd4b9545a8fcb7cf2930e0ee Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 16 Feb 2012 17:02:11 +0000 Subject: [PATCH 329/406] Remove unnecessary locking from QNetworkProxy constructor QGlobalNetworkProxy (a singleton) had two phase construction, with the second phase being called from QNetworkProxy's constructor. This isn't necessary, and has been reported as causing deadlocks. Although constructing socket engine handlers has side effects (they add themselves to a list on construction and remove themselves on destruction), this appears to be safe. The socket engine handlers are only used while holding the list mutex, and any socket engines created don't have any reference to the factory that created them. With the new version, it is possible that two instances of QHttpSocketEngineHandler and QSocks5SocketEngineHandler exist temporarily if a Q_GLOBAL_STATIC initialisation race occurs. This appears safe, because the loser of the race deletes its handlers, which remove themselves from the global list as above. Task-number: QTBUG-13088 Change-Id: I8cf520da717d8ab7d862ab89c6de13aea6d60ac3 Reviewed-by: Richard J. Moore Reviewed-by: Thiago Macieira --- src/network/kernel/qnetworkproxy.cpp | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp index 1181497d820..0238d22eb64 100644 --- a/src/network/kernel/qnetworkproxy.cpp +++ b/src/network/kernel/qnetworkproxy.cpp @@ -247,6 +247,12 @@ public: , socks5SocketEngineHandler(0) , httpSocketEngineHandler(0) { +#ifndef QT_NO_SOCKS5 + socks5SocketEngineHandler = new QSocks5SocketEngineHandler(); +#endif +#ifndef QT_NO_HTTP + httpSocketEngineHandler = new QHttpSocketEngineHandler(); +#endif } ~QGlobalNetworkProxy() @@ -257,19 +263,6 @@ public: delete httpSocketEngineHandler; } - void init() - { - QMutexLocker lock(&mutex); -#ifndef QT_NO_SOCKS5 - if (!socks5SocketEngineHandler) - socks5SocketEngineHandler = new QSocks5SocketEngineHandler(); -#endif -#ifndef QT_NO_HTTP - if (!httpSocketEngineHandler) - httpSocketEngineHandler = new QHttpSocketEngineHandler(); -#endif - } - void setApplicationProxy(const QNetworkProxy &proxy) { QMutexLocker lock(&mutex); @@ -431,8 +424,6 @@ template<> void QSharedDataPointer::detach() QNetworkProxy::QNetworkProxy() : d(0) { - if (QGlobalNetworkProxy *globalProxy = globalNetworkProxy()) - globalProxy->init(); } /*! @@ -447,8 +438,6 @@ QNetworkProxy::QNetworkProxy(ProxyType type, const QString &hostName, quint16 po const QString &user, const QString &password) : d(new QNetworkProxyPrivate(type, hostName, port, user, password)) { - if (QGlobalNetworkProxy *globalProxy = globalNetworkProxy()) - globalProxy->init(); } /*! From e5bcb4844d71b833d62aedcca3829f44b505dbb0 Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 17 Feb 2012 14:16:55 +0100 Subject: [PATCH 330/406] No need to stat with QFile::exists before QFile::open, for reading. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I14ca7f8a377bca39004defc96d69d62c151181f5 Reviewed-by: João Abecasis Reviewed-by: Jeremy Katz --- src/corelib/io/qstandardpaths_unix.cpp | 2 +- src/plugins/bearer/connman/qconnmanengine.cpp | 4 ++-- src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp | 4 ++-- src/widgets/styles/qgtkstyle_p.cpp | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp index 6057c26e0d9..62c846738e2 100644 --- a/src/corelib/io/qstandardpaths_unix.cpp +++ b/src/corelib/io/qstandardpaths_unix.cpp @@ -137,7 +137,7 @@ QString QStandardPaths::writableLocation(StandardLocation type) if (xdgConfigHome.isEmpty()) xdgConfigHome = QDir::homePath() + QLatin1String("/.config"); QFile file(xdgConfigHome + QLatin1String("/user-dirs.dirs")); - if (file.exists() && file.open(QIODevice::ReadOnly)) { + if (file.open(QIODevice::ReadOnly)) { QHash lines; QTextStream stream(&file); // Only look for lines like: XDG_DESKTOP_DIR="$HOME/Desktop" diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp index 1a874a92b70..0e54668394a 100644 --- a/src/plugins/bearer/connman/qconnmanengine.cpp +++ b/src/plugins/bearer/connman/qconnmanengine.cpp @@ -255,7 +255,7 @@ quint64 QConnmanEngine::bytesWritten(const QString &id) quint64 result = 0; QString devFile = getInterfaceFromId(id); QFile tx("/sys/class/net/"+devFile+"/statistics/tx_bytes"); - if(tx.exists() && tx.open(QIODevice::ReadOnly | QIODevice::Text)) { + if (tx.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&tx); in >> result; tx.close(); @@ -270,7 +270,7 @@ quint64 QConnmanEngine::bytesReceived(const QString &id) quint64 result = 0; QString devFile = getInterfaceFromId(id); QFile rx("/sys/class/net/"+devFile+"/statistics/rx_bytes"); - if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) { + if (rx.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&rx); in >> result; rx.close(); diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp index fd79cff484b..a71a241ea67 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -837,7 +837,7 @@ quint64 QNetworkManagerEngine::bytesWritten(const QString &id) quint64 result = Q_UINT64_C(0); QFile tx(devFile); - if (tx.exists() && tx.open(QIODevice::ReadOnly | QIODevice::Text)) { + if (tx.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&tx); in >> result; tx.close(); @@ -865,7 +865,7 @@ quint64 QNetworkManagerEngine::bytesReceived(const QString &id) quint64 result = Q_UINT64_C(0); QFile tx(devFile); - if (tx.exists() && tx.open(QIODevice::ReadOnly | QIODevice::Text)) { + if (tx.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&tx); in >> result; tx.close(); diff --git a/src/widgets/styles/qgtkstyle_p.cpp b/src/widgets/styles/qgtkstyle_p.cpp index 40ad9f2a954..18e120a4eb3 100644 --- a/src/widgets/styles/qgtkstyle_p.cpp +++ b/src/widgets/styles/qgtkstyle_p.cpp @@ -661,7 +661,7 @@ QString QGtkStylePrivate::getThemeName() foreach (const QString &rcPath, paths) { if (!rcPath.isEmpty()) { QFile rcFile(rcPath); - if (rcFile.exists() && rcFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + if (rcFile.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&rcFile); while(!in.atEnd()) { QString line = in.readLine(); From 45053fffc401dcfc32013bc0fc4e86a9fe4e9421 Mon Sep 17 00:00:00 2001 From: "Simon A. Eugster" Date: Tue, 14 Feb 2012 19:04:11 +0100 Subject: [PATCH 331/406] Mention QT_NO_STL in the QString documentation Defining QT_NO_STL disables STL functions (toStdString() etc.) too. Change-Id: Id5c8e12d933af6af63ee7f80fa2d5d7577cd689a Reviewed-by: Thiago Macieira --- src/corelib/tools/qstring.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 524096b8890..ca34096ec5e 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -936,7 +936,7 @@ int QString::grow(int size) systems). This method is only available if Qt is configured with STL - compatibility enabled. + compatibility enabled and if QT_NO_STL is not defined. \sa fromUtf16(), fromLatin1(), fromLocal8Bit(), fromUtf8(), fromUcs4() */ @@ -964,7 +964,7 @@ int QString::grow(int size) that accepts a std::wstring object. This operator is only available if Qt is configured with STL - compatibility enabled. + compatibility enabled and if QT_NO_STL is not defined. \sa utf16(), toAscii(), toLatin1(), toUtf8(), toLocal8Bit() */ @@ -7029,7 +7029,7 @@ bool QString::isRightToLeft() const can lead to loss of information. This operator is only available if Qt is configured with STL - compatibility enabled. + compatibility enabled and if QT_NO_STL is not defined. \sa toAscii(), toLatin1(), toUtf8(), toLocal8Bit() */ From 77172b25fe18c8c9e1578e2c0caeb63cb674513a Mon Sep 17 00:00:00 2001 From: Rafael Roquetto Date: Fri, 17 Feb 2012 12:17:30 +0100 Subject: [PATCH 332/406] QProcess documentation typo fix and improvement. The word 'momentaneously' does not exist. Change-Id: I3d2201d5b7b3a01af5989bb1c3fcd55110d5482c Reviewed-by: Thiago Macieira Reviewed-by: Till Adam Reviewed-by: Robin Burchell --- src/corelib/io/qprocess.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 1312e9b55f5..7a81313fa06 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -522,8 +522,8 @@ void QProcessPrivate::Channel::clear() \note On QNX, setting the working directory may cause all application threads, with the exception of the QProcess caller - thread, to momentaneusly freeze, owing to a limitation in - the operating system. + thread, to temporarily freeze during the spawning process, + owing to a limitation in the operating system. \section1 Synchronous Process API @@ -1439,7 +1439,7 @@ QString QProcess::workingDirectory() const process in the working directory of the calling process. \note On QNX, this may cause all application threads to - momentaneusly freeze. + temporarily freeze. \sa workingDirectory(), start() */ @@ -2158,7 +2158,7 @@ int QProcess::execute(const QString &program) The process will be started in the directory \a workingDirectory. \note On QNX, this may cause all application threads to - momentaneusly freeze. + temporarily freeze. If the function is successful then *\a pid is set to the process identifier of the started process. From 7e970eb58c71dc08981575c648a04d258dbf0684 Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 17 Feb 2012 09:05:39 +0100 Subject: [PATCH 333/406] Ensure that Qt public headers compile with strict flags Those from http://wiki.qt-project.org/Coding_Conventions#Conventions_for_public_header_files (unfortunatey -Wold-style-cast cannot be used due to the glibc macro bswap_16) and many Qt defines that disable casts. Change-Id: I97ac707a101df9819e8c031fa75a31b30e20247f Reviewed-by: Thiago Macieira --- src/corelib/kernel/qmetatype.h | 6 ++--- src/gui/accessible/qaccessible.h | 6 ++--- .../auto/other/headersclean/headersclean.pro | 27 ++++++++++++++++--- .../other/headersclean/tst_headersclean.cpp | 5 +++- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 1473231d644..4af77fcedc7 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -284,7 +284,7 @@ private: Constructor constructor, Destructor destructor, uint sizeOf, - uint typeFlags, + uint theTypeFlags, int typeId); QMetaType(const QMetaType &other); QMetaType &operator =(const QMetaType &); @@ -621,7 +621,7 @@ inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeI Constructor constructor, Destructor destructor, uint size, - uint typeFlags, + uint theTypeFlags, int typeId) : m_creator(creator) , m_deleter(deleter) @@ -630,7 +630,7 @@ inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeI , m_constructor(constructor) , m_destructor(destructor) , m_size(size) - , m_typeFlags(typeFlags) + , m_typeFlags(theTypeFlags) , m_extensionFlags(extensionFlags) , m_typeId(typeId) { diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index 9fc13a827ba..a3661e6f92e 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -432,10 +432,10 @@ private: class Q_GUI_EXPORT QAccessibleEvent { public: - inline QAccessibleEvent(QAccessible::Event type, QObject *object, int child = -1) - : m_type(type), m_object(object), m_child(child) + inline QAccessibleEvent(QAccessible::Event typ, QObject *obj, int chld = -1) + : m_type(typ), m_object(obj), m_child(chld) { - Q_ASSERT(object); + Q_ASSERT(obj); } QAccessible::Event type() const { return m_type; } diff --git a/tests/auto/other/headersclean/headersclean.pro b/tests/auto/other/headersclean/headersclean.pro index 814f19c8658..5444bebfb9d 100644 --- a/tests/auto/other/headersclean/headersclean.pro +++ b/tests/auto/other/headersclean/headersclean.pro @@ -1,7 +1,28 @@ CONFIG += testcase TARGET = tst_headersclean SOURCES += tst_headersclean.cpp -QT = core network xml sql testlib -contains(QT_CONFIG,dbus): QT += dbus -contains(QT_CONFIG,opengl): QT += opengl +# No need to link to all modules, only those actually used +QT = core testlib gui widgets + +*-g++*: QMAKE_CXXFLAGS += -W -Wall -Wextra -Werror + +# The flags here come from http://wiki.qt-project.org/Coding_Conventions#Conventions_for_public_header_files +# -Wold-style-cast cannot be used, /usr/include/bits/byteswap.h defines the macro bswap_16 using C style casts :( +# -Wfloat-equal cannot be used, qrect.h and qvector2d.h do exact comparisons in isNull and operator==. Would need #pragmas. +*-g++*: QMAKE_CXXFLAGS += -Woverloaded-virtual -Wshadow -Wundef + +# Other nice flags +*-g++*: QMAKE_CXXFLAGS += -Wnon-virtual-dtor -ansi -Wcast-align -Wchar-subscripts -Wpointer-arith -Wformat-security + +# Enable pedantic mode, but accept variadic macros and 'long long' usage. +*-g++*: QMAKE_CXXFLAGS += -Wno-long-long -Wno-variadic-macros -pedantic-errors + +QMAKE_CXXFLAGS += -DQT_NO_CAST_TO_ASCII \ + -DQT_NO_CAST_FROM_ASCII \ + -DQT_STRICT_ITERATORS \ + -DQT_NO_URL_CAST_FROM_STRING \ + -DQT_NO_CAST_FROM_BYTEARRAY \ + -DQT_NO_KEYWORDS \ + -DQT_USE_FAST_CONCATENATION \ + -DQT_USE_FAST_OPERATOR_PLUS diff --git a/tests/auto/other/headersclean/tst_headersclean.cpp b/tests/auto/other/headersclean/tst_headersclean.cpp index 41992b8d2a4..81d0aa3a4a6 100644 --- a/tests/auto/other/headersclean/tst_headersclean.cpp +++ b/tests/auto/other/headersclean/tst_headersclean.cpp @@ -39,7 +39,6 @@ ** ****************************************************************************/ -#define QT_NO_KEYWORDS #define signals int #define slots int #define emit public:; @@ -47,12 +46,16 @@ #define forever public:; #include +#include #include #include #include #include #include +#include +#include +#include #ifndef QT_NO_OPENGL #include From 1b08a485889aed6f2e9147257595383d60d22e77 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 15 Feb 2012 22:12:41 +0100 Subject: [PATCH 334/406] Only define QT_NAMESPACE if it is used. Fixes non-namespaced builds. Change-Id: I0ec3c29f58042313dfa864f15c2b2d47914cdedb Reviewed-by: Clinton Stimpson Reviewed-by: Stephen Kelly --- src/corelib/Qt5CoreConfigExtras.cmake.in | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index 155961bc9a6..440d5e92bb3 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -12,5 +12,7 @@ if (NOT \"$${CMAKE_ADD_FPIE_FLAGS}\" STREQUAL \"\") set(Qt5Core_COMPILE_FLAGS "-fPIE") endif() -list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) -list(APPEND Qt5Core_COMPILE_DEFINITIONS QT_NAMESPACE=$$QT_NAMESPACE) +if (NOT \"$$QT_NAMESPACE\" STREQUAL \"\") + list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) + list(APPEND Qt5Core_COMPILE_DEFINITIONS QT_NAMESPACE=$$QT_NAMESPACE) +endif() From 3ca194eb129c227b81bf1f04bfb879c404dc9f89 Mon Sep 17 00:00:00 2001 From: Rick Stockton Date: Tue, 14 Feb 2012 08:52:09 -0800 Subject: [PATCH 335/406] qnamespace.qdoc: Add doco for new values of Qt::MouseButton MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QtTBUG-22642 added about 25 new values for the Qt::MouseButton Enum. This change adds documentation for the new values. Note that the special value 'Qt::AllButtons' is documented at the top (next to the other special value, 'Qt::NoButton'.) The new internal value 'Qt::MaxMouseButton' is listed as a \omitvalue. Task Number: QTBUG-22642 Change-Id: Iaec623754156fff8a2c73e357fef82e1fe36354b Reviewed-by: Alan Alpert Reviewed-by: Samuel Rødal --- src/corelib/global/qnamespace.qdoc | 52 ++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 8c3fa148fcd..d50960f68b4 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -172,18 +172,64 @@ This enum type describes the different mouse buttons. \value NoButton The button state does not refer to any - button (see QMouseEvent::button()). + button (see QMouseEvent::button()). + + \value AllButtons This value corresponds to a mask of all + possible mouse buttons. Use to set the 'acceptedButtons' + property of a mouseArea to accept ALL mouse buttons. + \value LeftButton The left button is pressed, or an event refers to the left button. (The left button may be the right button on left-handed mice.) \value RightButton The right button. \value MidButton The middle button. \value MiddleButton The middle button. - \value XButton1 The first X button. - \value XButton2 The second X button. + \value BackButton The 'Back' button. (Typically present on + the 'thumb' side of a mouse with extra buttons. This is NOT + the tilt wheel.) + \value XButton1 The 'Back' Button. + \value ExtraButton1 The 'Back' Button. + + \value ForwardButton The 'Forward' Button. (Typically present + beside the 'Back' button, and also pressed by the thumb.) + \value XButton2 The 'Forward Button. + \value ExtraButton2 The 'Forward' Button. + + \value TaskButton The 'Task' Button. + \value ExtraButton3 The 'Task' Button. + + \value ExtraButton4 The 7th non-wheel Mouse Button. + \value ExtraButton5 The 8th non-wheel Mouse Button. + \value ExtraButton6 The 9th non-wheel Mouse Button. + \value ExtraButton7 The 10th non-wheel Mouse Button. + \value ExtraButton8 The 11th non-wheel Mouse Button. + \value ExtraButton9 The 12th non-wheel Mouse Button. + \value ExtraButton10 The 13th non-wheel Mouse Button. + \value ExtraButton11 The 14th non-wheel Mouse Button. + \value ExtraButton12 The 15th non-wheel Mouse Button. + \value ExtraButton13 The 16th non-wheel Mouse Button. + \value ExtraButton14 The 17th non-wheel Mouse Button. + \value ExtraButton15 The 18th non-wheel Mouse Button. + \value ExtraButton16 The 19th non-wheel Mouse Button. + \value ExtraButton17 The 20th non-wheel Mouse Button. + \value ExtraButton18 The 21st non-wheel Mouse Button. + \value ExtraButton19 The 22nd non-wheel Mouse Button. + \value ExtraButton20 The 23rd non-wheel Mouse Button. + \value ExtraButton21 The 24th non-wheel Mouse Button. + \value ExtraButton22 The 25th non-wheel Mouse Button. + \value ExtraButton23 The 26th non-wheel Mouse Button. + \value ExtraButton44 The 27th non-wheel Mouse Button. + + \omitvalue MaxMouseButton \omitvalue MouseButtonMask + \note Some models of multi-button mice are pre-configured with + high-numbered Buttons emulating keyboard sequences, for use in + specific games. In order for these Buttons to be seen as + actual 'Mouse Buttons', the device must be re-configured (using + the vendor's configuration tool). + \sa KeyboardModifier Modifier */ From 400c865f2994e67189108e36cfa206c365d57274 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 17 Feb 2012 16:08:17 +0100 Subject: [PATCH 336/406] Windows: Fix QWindow-test. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Save & Restore style and geometry when switching to full screen and back since it is not a real state on Windows. - Obey the positioning policy in setGeometry. Task-number: QTBUG-24185 Change-Id: I18dea4fd372e0b2e46273a7a27e0c6f4f4bde771 Reviewed-by: Samuel Rødal --- .../platforms/windows/qwindowswindow.cpp | 47 ++++++++++++++----- .../platforms/windows/qwindowswindow.h | 3 ++ tests/auto/gui/kernel/qwindow/qwindow.pro | 2 +- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 28ef2c3b6ca..58db9b32c46 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -618,7 +619,8 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) : m_opacity(1.0), m_mouseGrab(false), m_cursor(QWindowsScreen::screenOf(aWindow)->cursor().standardWindowCursor()), - m_dropTarget(0) + m_dropTarget(0), + m_savedStyle(0) { if (aWindow->surfaceType() == QWindow::OpenGLSurface) setFlag(OpenGLSurface); @@ -809,8 +811,15 @@ void QWindowsWindow::handleHidden() QWindowSystemInterface::handleUnmapEvent(window()); } -void QWindowsWindow::setGeometry(const QRect &rect) +void QWindowsWindow::setGeometry(const QRect &rectIn) { + QRect rect = rectIn; + // This means it is a call from QWindow::setFramePos() and + // the coordinates include the frame (size is still the contents rectangle). + if (qt_window_private(window())->positionPolicy == QWindowPrivate::WindowFrameInclusive) { + const QMargins margins = frameMargins(); + rect.moveTopLeft(rect.topLeft() + QPoint(margins.left(), margins.top())); + } const QSize oldSize = m_data.geometry.size(); m_data.geometry = rect; const QSize newSize = rect.size(); @@ -904,11 +913,15 @@ void QWindowsWindow::setGeometry_sys(const QRect &rect) const << " \n resulting " << rc << geometry_sys(); } -QRect QWindowsWindow::geometry_sys() const +QRect QWindowsWindow::frameGeometry_sys() const { // Warning: Returns bogus values when minimized. - QRect result = frameGeometry(m_data.hwnd, window()->isTopLevel()) - frameMargins(); - return result; + return frameGeometry(m_data.hwnd, window()->isTopLevel()); +} + +QRect QWindowsWindow::geometry_sys() const +{ + return frameGeometry_sys() - frameMargins(); } /*! @@ -1098,7 +1111,12 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState) #else UINT newStyle = WS_POPUP; #endif - if (style() & WS_SYSMENU) + // Save geometry and style to be restored when fullscreen + // is turned off again, since on Windows, it is not a real + // Window state but emulated by changing geometry and style. + m_savedStyle = style(); + m_savedFrameGeometry = frameGeometry_sys(); + if (m_savedStyle & WS_SYSMENU) newStyle |= WS_SYSMENU; if (visible) newStyle |= WS_VISIBLE; @@ -1108,19 +1126,26 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState) UINT swpf = SWP_FRAMECHANGED; if (newStates & Qt::WindowActive) swpf |= SWP_NOACTIVATE; - SetWindowPos(m_data.hwnd, HWND_TOP, r.left(), r.top(), r.width(), r.height(), swpf); } else { + // Restore saved state. + unsigned newStyle = m_savedStyle ? m_savedStyle : style(); if (visible) - setStyle(style() | WS_VISIBLE); - UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE; + newStyle |= WS_VISIBLE; + setStyle(newStyle); + + UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER; if (newStates & Qt::WindowActive) swpf |= SWP_NOACTIVATE; - SetWindowPos(m_data.hwnd, 0, 0, 0, 0, 0, swpf); - + if (!m_savedFrameGeometry.isValid()) + swpf |= SWP_NOSIZE | SWP_NOMOVE; + SetWindowPos(m_data.hwnd, 0, m_savedFrameGeometry.x(), m_savedFrameGeometry.y(), + m_savedFrameGeometry.width(), m_savedFrameGeometry.height(), swpf); // preserve maximized state if (visible) ShowWindow(m_data.hwnd, (newStates & Qt::WindowMaximized) ? max : normal); + m_savedStyle = 0; + m_savedFrameGeometry = QRect(); } } diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 1d5f3c29d66..e3336d1c3a1 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -193,6 +193,7 @@ private: inline void show_sys() const; inline void hide_sys() const; inline void setGeometry_sys(const QRect &rect) const; + inline QRect frameGeometry_sys() const; inline QRect geometry_sys() const; inline WindowData setWindowFlags_sys(Qt::WindowFlags wt, unsigned flags = 0) const; inline void setWindowState_sys(Qt::WindowState newState); @@ -213,6 +214,8 @@ private: bool m_mouseGrab; QWindowsWindowCursor m_cursor; QWindowsOleDropTarget *m_dropTarget; + unsigned m_savedStyle; + QRect m_savedFrameGeometry; }; // Conveniences for window frames. diff --git a/tests/auto/gui/kernel/qwindow/qwindow.pro b/tests/auto/gui/kernel/qwindow/qwindow.pro index d191b9fb8e2..363f7dd92eb 100644 --- a/tests/auto/gui/kernel/qwindow/qwindow.pro +++ b/tests/auto/gui/kernel/qwindow/qwindow.pro @@ -6,4 +6,4 @@ QT += core-private gui-private testlib SOURCES += tst_qwindow.cpp mac: CONFIG += insignificant_test # QTBUG-23059 -win32:CONFIG += insignificant_test # QTBUG-24185 + From 844b096d674c3b803923357502435ef89ce0c738 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 17 Feb 2012 15:14:01 +0000 Subject: [PATCH 337/406] Fix error handling in QHostInfo windows backend If the DNS server returns a non authoritative host not found response, then windows returns WSATRY_AGAIN error code. This is now reported as HostNotFound and not UnknownError Change-Id: I212985acd4e85ff4b2bdb6c57ec403405a7695fb Reviewed-by: Miikka Heikkinen Reviewed-by: Richard J. Moore --- src/network/kernel/qhostinfo_win.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/network/kernel/qhostinfo_win.cpp b/src/network/kernel/qhostinfo_win.cpp index a00389e3ede..8ace68d9614 100644 --- a/src/network/kernel/qhostinfo_win.cpp +++ b/src/network/kernel/qhostinfo_win.cpp @@ -95,6 +95,22 @@ static void resolveLibrary() #endif } +static void translateWSAError(int error, QHostInfo *results) +{ + switch (error) { + case WSAHOST_NOT_FOUND: //authoritative not found + case WSATRY_AGAIN: //non authoritative not found + case WSANO_DATA: //valid name, no associated address + results->setError(QHostInfo::HostNotFound); + results->setErrorString(QHostInfoAgent::tr("Host not found")); + return; + default: + results->setError(QHostInfo::UnknownError); + results->setErrorString(QHostInfoAgent::tr("Unknown error (%1)").arg(error)); + return; + } +} + QHostInfo QHostInfoAgent::fromName(const QString &hostName) { #if defined(Q_OS_WINCE) @@ -200,12 +216,8 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) } results.setAddresses(addresses); local_freeaddrinfo(res); - } else if (WSAGetLastError() == WSAHOST_NOT_FOUND || WSAGetLastError() == WSANO_DATA) { - results.setError(QHostInfo::HostNotFound); - results.setErrorString(tr("Host not found")); } else { - results.setError(QHostInfo::UnknownError); - results.setErrorString(tr("Unknown error")); + translateWSAError(WSAGetLastError(), &results); } } else { // Fall back to gethostbyname, which only supports IPv4. @@ -228,12 +240,8 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) break; } results.setAddresses(addresses); - } else if (WSAGetLastError() == 11001) { - results.setErrorString(tr("Host not found")); - results.setError(QHostInfo::HostNotFound); } else { - results.setErrorString(tr("Unknown error")); - results.setError(QHostInfo::UnknownError); + translateWSAError(WSAGetLastError(), &results); } } From e0d9fade038130ad408715e946c5c08cd2faf81e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 15 Feb 2012 12:34:04 +0100 Subject: [PATCH 338/406] Fix qclipboard autotest on Windows. Emit changed signal only if the clipboard is not owned, in which case QClipboard does it. Task-number: QTBUG-24184 Change-Id: I27420583a718a5f8cd93b9d361b1e422a75df300 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowsclipboard.cpp | 11 +++++++---- tests/auto/gui/kernel/qclipboard/test/test.pro | 1 - 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp index c1167ccf3a4..4f083e93d29 100644 --- a/src/plugins/platforms/windows/qwindowsclipboard.cpp +++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp @@ -283,14 +283,17 @@ bool QWindowsClipboard::clipboardViewerWndProc(HWND hwnd, UINT message, WPARAM w } } return true; - case WM_DRAWCLIPBOARD: + case WM_DRAWCLIPBOARD: { + const bool owned = ownsClipboard(); if (QWindowsContext::verboseOLE) - qDebug("Clipboard changed"); - emitChanged(QClipboard::Clipboard); + qDebug("Clipboard changed owned %d", owned); + if (!owned) // changed is emitted by QClipboard in that case. + emitChanged(QClipboard::Clipboard); // clean up the clipboard object if we no longer own the clipboard - if (!ownsClipboard() && m_data) + if (!owned && m_data) releaseIData(); propagateClipboardMessage(message, wParam, lParam); + } return true; case WM_DESTROY: // Recommended shutdown diff --git a/tests/auto/gui/kernel/qclipboard/test/test.pro b/tests/auto/gui/kernel/qclipboard/test/test.pro index ffab4dec4f3..4be6769592c 100644 --- a/tests/auto/gui/kernel/qclipboard/test/test.pro +++ b/tests/auto/gui/kernel/qclipboard/test/test.pro @@ -16,7 +16,6 @@ wince* { } mac: CONFIG += insignificant_test # QTBUG-23057 -win32:CONFIG += insignificant_test # QTBUG-24184 load(testcase) # for target.path and installTestHelperApp() installTestHelperApp("../copier/copier",copier,copier) From 7e2afb9168b3f07dd3a0d97cc7d7572bd5b6e67b Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 17 Feb 2012 09:41:35 +0100 Subject: [PATCH 339/406] Document Q_PROCESSOR_* macros All known processors and their variants/revisions are documented. I added Q_PROCESSOR_MIPS_V based on the MIPS64 online documentation, which documents MIPS64 as a superset of MIPS IV and MIPS V. Change-Id: Ie2796d4f03499283aa2c96d60f5e37bd74a36ab0 Reviewed-by: Thiago Macieira Reviewed-by: Casper van Donderen --- src/corelib/global/qglobal.cpp | 215 +++++++++++++++++++++++ src/corelib/global/qprocessordetection.h | 3 + 2 files changed, 218 insertions(+) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 58a3a6b7fd9..44d44b2cdb8 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1359,6 +1359,221 @@ bool qSharedBuild() Defined on MAC OS (synonym for Darwin). */ +/*! + \macro Q_PROCESSOR_ALPHA + \relates + + Defined if the application is compiled for Alpha processors. +*/ + +/*! + \macro Q_PROCESSOR_ARM + \relates + + Defined if the application is compiled for ARM processors. Qt currently + supports three optional ARM revisions: \l Q_PROCESSOR_ARM_V5, \l + Q_PROCESSOR_ARM_V6, and \l Q_PROCESSOR_ARM_V7. +*/ +/*! + \macro Q_PROCESSOR_ARM_V5 + \relates + + Defined if the application is compiled for ARMv5 processors. The \l + Q_PROCESSOR_ARM macro is also defined when Q_PROCESSOR_ARM_V5 is defined. +*/ +/*! + \macro Q_PROCESSOR_ARM_V6 + \relates + + Defined if the application is compiled for ARMv6 processors. The \l + Q_PROCESSOR_ARM and \l Q_PROCESSOR_ARM_V5 macros are also defined when + Q_PROCESSOR_ARM_V6 is defined. +*/ +/*! + \macro Q_PROCESSOR_ARM_V7 + \relates + + Defined if the application is compiled for ARMv7 processors. The \l + Q_PROCESSOR_ARM, \l Q_PROCESSOR_ARM_V5, and \l Q_PROCESSOR_ARM_V6 macros + are also defined when Q_PROCESSOR_ARM_V7 is defined. +*/ + +/*! + \macro Q_PROCESSOR_AVR32 + \relates + + Defined if the application is compiled for AVR32 processors. +*/ + +/*! + \macro Q_PROCESSOR_BLACKFIN + \relates + + Defined if the application is compiled for Blackfin processors. +*/ + +/*! + \macro Q_PROCESSOR_IA64 + \relates + + Defined if the application is compiled for IA-64 processors. This includes + all Itanium and Itanium 2 processors. +*/ + +/*! + \macro Q_PROCESSOR_MIPS + \relates + + Defined if the application is compiled for MIPS processors. Qt currently + supports seven MIPS revisions: \l Q_PROCESSOR_MIPS_I, \l + Q_PROCESSOR_MIPS_II, \l Q_PROCESSOR_MIPS_III, \l Q_PROCESSOR_MIPS_IV, \l + Q_PROCESSOR_MIPS_V, \l Q_PROCESSOR_MIPS_32, and \l Q_PROCESSOR_MIPS_64. +*/ +/*! + \macro Q_PROCESSOR_MIPS_I + \relates + + Defined if the application is compiled for MIPS-I processors. The \l + Q_PROCESSOR_MIPS macro is also defined when Q_PROCESSOR_MIPS_I is defined. +*/ +/*! + \macro Q_PROCESSOR_MIPS_II + \relates + + Defined if the application is compiled for MIPS-II processors. The \l + Q_PROCESSOR_MIPS and \l Q_PROCESSOR_MIPS_I macros are also defined when + Q_PROCESSOR_MIPS_II is defined. +*/ +/*! + \macro Q_PROCESSOR_MIPS_32 + \relates + + Defined if the application is compiled for MIPS32 processors. The \l + Q_PROCESSOR_MIPS, \l Q_PROCESSOR_MIPS_I, and \l Q_PROCESSOR_MIPS_II macros + are also defined when Q_PROCESSOR_MIPS_32 is defined. +*/ +/*! + \macro Q_PROCESSOR_MIPS_III + \relates + + Defined if the application is compiled for MIPS-III processors. The \l + Q_PROCESSOR_MIPS, \l Q_PROCESSOR_MIPS_I, and \l Q_PROCESSOR_MIPS_II macros + are also defined when Q_PROCESSOR_MIPS_III is defined. +*/ +/*! + \macro Q_PROCESSOR_MIPS_IV + \relates + + Defined if the application is compiled for MIPS-IV processors. The \l + Q_PROCESSOR_MIPS, \l Q_PROCESSOR_MIPS_I, \l Q_PROCESSOR_MIPS_II, and \l + Q_PROCESSOR_MIPS_III macros are also defined when Q_PROCESSOR_MIPS_IV is + defined. +*/ +/*! + \macro Q_PROCESSOR_MIPS_V + \relates + + Defined if the application is compiled for MIPS-V processors. The \l + Q_PROCESSOR_MIPS, \l Q_PROCESSOR_MIPS_I, \l Q_PROCESSOR_MIPS_II, \l + Q_PROCESSOR_MIPS_III, and \l Q_PROCESSOR_MIPS_IV macros are also defined + when Q_PROCESSOR_MIPS_V is defined. +*/ +/*! + \macro Q_PROCESSOR_MIPS_64 + \relates + + Defined if the application is compiled for MIPS64 processors. The \l + Q_PROCESSOR_MIPS, \l Q_PROCESSOR_MIPS_I, \l Q_PROCESSOR_MIPS_II, \l + Q_PROCESSOR_MIPS_III, \l Q_PROCESSOR_MIPS_IV, and \l Q_PROCESSOR_MIPS_V + macros are also defined when Q_PROCESSOR_MIPS_64 is defined. +*/ + +/*! + \macro Q_PROCESSOR_POWERPC + \relates + + Defined if the application is compiled for PowerPC processors. Qt currently + supports one optional PowerPC variant: \l Q_PROCESSOR_POWERPC_64. +*/ +/*! + \macro Q_PROCESSOR_POWERPC_64 + \relates + + Defined if the application is compiled for 64-bit PowerPC processors. The + \l Q_PROCESSOR_POWERPC macro is also defined when Q_PROCESSOR_POWERPC_64 is + defined. +*/ + +/*! + \macro Q_PROCESSOR_S390 + \relates + + Defined if the application is compiled for S/390 processors. Qt supports + one optional variant of S/390: Q_PROCESSOR_S390_X. +*/ +/*! + \macro Q_PROCESSOR_S390_X + \relates + + Defined if the application is compiled for S/390x processors. The \l + Q_PROCESSOR_S390 macro is also defined when Q_PROCESSOR_S390_X is defined. +*/ + +/*! + \macro Q_PROCESSOR_SH + \relates + + Defined if the application is compiled for SuperH processors. Qt currently + supports one SuperH revision: \l Q_PROCESSOR_SH_4A. +*/ +/*! + \macro Q_PROCESSOR_SH_4A + \relates + + Defined if the application is compiled for SuperH 4A processors. The \l + Q_PROCESSOR_SH macro is also defined when Q_PROCESSOR_SH_4A is defined. +*/ + +/*! + \macro Q_PROCESSOR_SPARC + \relates + + Defined if the application is compiled for SPARC processors. Qt currently + supports one optional SPARC revision: \l Q_PROCESSOR_SPARC_V9. +*/ +/*! + \macro Q_PROCESSOR_SPARC_V9 + \relates + + Defined if the application is compiled for SPARC V9 processors. The \l + Q_PROCESSOR_SPARC macro is also defined when Q_PROCESSOR_SPARC_V9 is + defined. +*/ + +/*! + \macro Q_PROCESSOR_X86 + \relates + + Defined if the application is compiled for x86 processors. Qt currently + supports two x86 variants: \l Q_PROCESSOR_X86_32 and \l Q_PROCESSOR_X86_64. +*/ +/*! + \macro Q_PROCESSOR_X86_32 + \relates + + Defined if the application is compiled for 32-bit x86 processors. This + includes all i386, i486, i586, and i686 processors. The \l Q_PROCESSOR_X86 + macro is also defined when Q_PROCESSOR_X86_32 is defined. +*/ +/*! + \macro Q_PROCESSOR_X86_64 + \relates + + Defined if the application is compiled for 64-bit x86 processors. This + includes all AMD64, Intel 64, and other x86_64/x64 processors. The \l + Q_PROCESSOR_X86 macro is also defined when Q_PROCESSOR_X86_64 is defined. +*/ + /*! \macro QT_DISABLE_DEPRECATED_BEFORE \relates diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h index bec070747f5..69815ba1994 100644 --- a/src/corelib/global/qprocessordetection.h +++ b/src/corelib/global/qprocessordetection.h @@ -137,6 +137,9 @@ # if defined(_MIPS_ARCH_MIPS4) || (defined(__mips) && __mips - 0 >= 4) # define Q_PROCESSOR_MIPS_IV # endif +# if defined(_MIPS_ARCH_MIPS5) || (defined(__mips) && __mips - 0 >= 5) +# define Q_PROCESSOR_MIPS_V +# endif # if defined(_MIPS_ARCH_MIPS64) || defined(__mips64) # define Q_PROCESSOR_MIPS_64 # endif From 1703558330454d0a9d2e71ecd60d99bb7f2b79b7 Mon Sep 17 00:00:00 2001 From: Richard Moore Date: Sat, 18 Feb 2012 10:57:42 +0000 Subject: [PATCH 340/406] Trivial doc fix Change-Id: I9b63e0b63f225b245eec68ea4211cb0f2ccf9bb5 Reviewed-by: Sergio Ahumada --- src/network/ssl/qsslcertificateextension.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/ssl/qsslcertificateextension.cpp b/src/network/ssl/qsslcertificateextension.cpp index 9434d27e961..eef27d7c2e2 100644 --- a/src/network/ssl/qsslcertificateextension.cpp +++ b/src/network/ssl/qsslcertificateextension.cpp @@ -45,7 +45,7 @@ extensions of an X509 certificate. \since 5.0 - \rentrant + \reentrant \ingroup network \ingroup ssl \inmodule QtNetwork From f63b23afdac47bbf71a7b72fdd965c55b2f60602 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 15 Feb 2012 18:55:25 +0100 Subject: [PATCH 341/406] QEasingCurve: return QVector for cubic spline representation QEasingCurve internally holds the spline data in a QVector. For the return from cubicBezierSpline(), the vector is transformed into a QList. This involves copying, and into an inefficient (for QPointF payloads) container at that, so deprecate cubicBezierSpline() in favour of a new toCubicSpline() returning the QVector directly. Change-Id: Ie4827fe7c6e289ad97a0b09772e47298779c76ca Reviewed-by: Lars Knoll --- src/corelib/tools/qeasingcurve.cpp | 12 +++++++++--- src/corelib/tools/qeasingcurve.h | 11 +++++++++-- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp index 76c06cb0d54..5731faa69cf 100644 --- a/src/corelib/tools/qeasingcurve.cpp +++ b/src/corelib/tools/qeasingcurve.cpp @@ -1303,14 +1303,20 @@ void QEasingCurve::addTCBSegment(const QPointF &nextPoint, qreal t, qreal c, qre } /*! + \fn QList QEasingCurve::cubicBezierSpline() const + \obsolete Use toCubicSpline() instead. + */ + +/*! + \since 5.0 Returns the cubicBezierSpline that defines a custom easing curve. If the easing curve does not have a custom bezier easing curve the list is empty. - */ -QList QEasingCurve::cubicBezierSpline() const +*/ +QVector QEasingCurve::toCubicSpline() const { - return d_ptr->config ? d_ptr->config->_bezierCurves.toList() : QList(); + return d_ptr->config ? d_ptr->config->_bezierCurves : QVector(); } /*! diff --git a/src/corelib/tools/qeasingcurve.h b/src/corelib/tools/qeasingcurve.h index 4d53af591b0..ad2e510799f 100644 --- a/src/corelib/tools/qeasingcurve.h +++ b/src/corelib/tools/qeasingcurve.h @@ -44,7 +44,11 @@ #include #include -#include +#include +#if QT_DEPRECATED_SINCE(5, 0) +# include +# include +#endif QT_BEGIN_HEADER @@ -94,7 +98,10 @@ public: void addCubicBezierSegment(const QPointF & c1, const QPointF & c2, const QPointF & endPoint); void addTCBSegment(const QPointF &nextPoint, qreal t, qreal c, qreal b); - QList cubicBezierSpline() const; + QVector toCubicSpline() const; +#if QT_DEPRECATED_SINCE(5, 0) + QT_DEPRECATED QList cubicBezierSpline() const { return toCubicSpline().toList(); } +#endif Type type() const; void setType(Type type); From 908a080006faff333b061b69b0dc0fd9cab36114 Mon Sep 17 00:00:00 2001 From: Andrew Christian Date: Fri, 17 Feb 2012 15:38:23 -0500 Subject: [PATCH 342/406] Added error reporting to QJsonParser Change-Id: Ib2390c0faf1ed7ada3fc185abce83740ad112929 Reviewed-by: Lars Knoll --- src/corelib/json/qjsondocument.cpp | 4 +- src/corelib/json/qjsondocument.h | 22 +++- src/corelib/json/qjsonparser.cpp | 80 +++++++++--- src/corelib/json/qjsonparser_p.h | 4 +- tests/auto/corelib/json/tst_qtjson.cpp | 165 +++++++++++++++++++++++++ 5 files changed, 252 insertions(+), 23 deletions(-) diff --git a/src/corelib/json/qjsondocument.cpp b/src/corelib/json/qjsondocument.cpp index 5ae1bcbe4eb..8a7fa760ae9 100644 --- a/src/corelib/json/qjsondocument.cpp +++ b/src/corelib/json/qjsondocument.cpp @@ -317,10 +317,10 @@ QByteArray QJsonDocument::toJson() const \sa toJson */ -QJsonDocument QJsonDocument::fromJson(const QByteArray &json) +QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error) { QJsonPrivate::Parser parser(json.constData(), json.length()); - return parser.parse(); + return parser.parse(error); } /*! diff --git a/src/corelib/json/qjsondocument.h b/src/corelib/json/qjsondocument.h index 39db830726c..7eca0302db6 100644 --- a/src/corelib/json/qjsondocument.h +++ b/src/corelib/json/qjsondocument.h @@ -54,6 +54,26 @@ namespace QJsonPrivate { class Parser; } +struct Q_CORE_EXPORT QJsonParseError +{ + enum ParseError { + NoError = 0, + UnterminatedObject, + MissingNameSeparator, + UnterminatedArray, + MissingValueSeparator, + IllegalValue, + EndOfNumber, + IllegalNumber, + StringEscapeSequence, + StringUTF8Scan, + EndOfString + }; + + int offset; + ParseError error; +}; + class Q_CORE_EXPORT QJsonDocument { public: @@ -85,7 +105,7 @@ public: static QJsonDocument fromVariant(const QVariant &variant); QVariant toVariant() const; - static QJsonDocument fromJson(const QByteArray &json); + static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error = 0); QByteArray toJson() const; bool isEmpty() const; diff --git a/src/corelib/json/qjsonparser.cpp b/src/corelib/json/qjsonparser.cpp index 75ed7de48fa..16eedadf1ae 100644 --- a/src/corelib/json/qjsonparser.cpp +++ b/src/corelib/json/qjsonparser.cpp @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE using namespace QJsonPrivate; Parser::Parser(const char *json, int length) - : json(json), data(0), dataLength(0), current(0) + : head(json), json(json), data(0), dataLength(0), current(0), lastError(QJsonParseError::NoError) { end = json + length; } @@ -134,8 +134,6 @@ char Parser::nextToken() case BeginObject: case NameSeparator: case ValueSeparator: - if (!eatSpace()) - return 0; case EndArray: case EndObject: eatSpace(); @@ -151,7 +149,7 @@ char Parser::nextToken() /* JSON-text = object / array */ -QJsonDocument Parser::parse() +QJsonDocument Parser::parse(QJsonParseError *error) { #ifdef PARSER_DEBUG indent = 0; @@ -182,6 +180,10 @@ QJsonDocument Parser::parse() END; { + if (error) { + error->offset = 0; + error->error = QJsonParseError::NoError; + } QJsonPrivate::Data *d = new QJsonPrivate::Data(data, current); return QJsonDocument(d); } @@ -190,6 +192,10 @@ error: #ifdef PARSER_DEBUG qDebug() << ">>>>> parser error"; #endif + if (error) { + error->offset = json - head; + error->error = lastError; + } free(data); return QJsonDocument(); } @@ -241,8 +247,10 @@ bool Parser::parseObject() } DEBUG << "end token=" << token; - if (token != EndObject) + if (token != EndObject) { + lastError = QJsonParseError::UnterminatedObject; return false; + } DEBUG << "numEntries" << parsedObject.offsets.size(); int table = objectOffset; @@ -283,8 +291,10 @@ bool Parser::parseMember(int baseOffset) if (!parseString(&latin1)) return false; char token = nextToken(); - if (token != NameSeparator) + if (token != NameSeparator) { + lastError = QJsonParseError::MissingNameSeparator; return false; + } QJsonPrivate::Value val; if (!parseValue(&val, baseOffset)) return false; @@ -308,8 +318,10 @@ bool Parser::parseArray() QVarLengthArray values; - if (!eatSpace()) + if (!eatSpace()) { + lastError = QJsonParseError::UnterminatedArray; return false; + } if (*json == EndArray) { nextToken(); } else { @@ -321,8 +333,13 @@ bool Parser::parseArray() char token = nextToken(); if (token == EndArray) break; - else if (token != ValueSeparator) + else if (token != ValueSeparator) { + if (!eatSpace()) + lastError = QJsonParseError::UnterminatedArray; + else + lastError = QJsonParseError::MissingValueSeparator; return false; + } } } @@ -358,8 +375,10 @@ bool Parser::parseValue(QJsonPrivate::Value *val, int baseOffset) switch (*json++) { case 'n': - if (end - json < 4) + if (end - json < 4) { + lastError = QJsonParseError::IllegalValue; return false; + } if (*json++ == 'u' && *json++ == 'l' && *json++ == 'l') { @@ -368,10 +387,13 @@ bool Parser::parseValue(QJsonPrivate::Value *val, int baseOffset) END; return true; } + lastError = QJsonParseError::IllegalValue; return false; case 't': - if (end - json < 4) + if (end - json < 4) { + lastError = QJsonParseError::IllegalValue; return false; + } if (*json++ == 'r' && *json++ == 'u' && *json++ == 'e') { @@ -381,10 +403,13 @@ bool Parser::parseValue(QJsonPrivate::Value *val, int baseOffset) END; return true; } + lastError = QJsonParseError::IllegalValue; return false; case 'f': - if (end - json < 5) + if (end - json < 5) { + lastError = QJsonParseError::IllegalValue; return false; + } if (*json++ == 'a' && *json++ == 'l' && *json++ == 's' && @@ -395,6 +420,7 @@ bool Parser::parseValue(QJsonPrivate::Value *val, int baseOffset) END; return true; } + lastError = QJsonParseError::IllegalValue; return false; case Quote: { val->type = QJsonValue::String; @@ -490,8 +516,10 @@ bool Parser::parseNumber(QJsonPrivate::Value *val, int baseOffset) ++json; } - if (json >= end) + if (json >= end) { + lastError = QJsonParseError::EndOfNumber; return false; + } QByteArray number(start, json - start); DEBUG << "numberstring" << number; @@ -514,8 +542,10 @@ bool Parser::parseNumber(QJsonPrivate::Value *val, int baseOffset) }; d = number.toDouble(&ok); - if (!ok) + if (!ok) { + lastError = QJsonParseError::IllegalNumber; return false; + } int pos = reserveSpace(sizeof(double)); *(quint64 *)(data + pos) = qToLittleEndian(ui); @@ -679,11 +709,15 @@ bool Parser::parseString(bool *latin1) if (*json == '"') break; else if (*json == '\\') { - if (!scanEscapeSequence(json, end, &ch)) + if (!scanEscapeSequence(json, end, &ch)) { + lastError = QJsonParseError::StringEscapeSequence; return false; + } } else { - if (!scanUtf8Char(json, end, &ch)) + if (!scanUtf8Char(json, end, &ch)) { + lastError = QJsonParseError::StringUTF8Scan; return false; + } } if (ch > 0xff) { *latin1 = false; @@ -695,8 +729,10 @@ bool Parser::parseString(bool *latin1) } ++json; DEBUG << "end of string"; - if (json >= end) + if (json >= end) { + lastError = QJsonParseError::EndOfString; return false; + } // no unicode string, we are done if (*latin1) { @@ -720,11 +756,15 @@ bool Parser::parseString(bool *latin1) if (*json == '"') break; else if (*json == '\\') { - if (!scanEscapeSequence(json, end, &ch)) + if (!scanEscapeSequence(json, end, &ch)) { + lastError = QJsonParseError::StringEscapeSequence; return false; + } } else { - if (!scanUtf8Char(json, end, &ch)) + if (!scanUtf8Char(json, end, &ch)) { + lastError = QJsonParseError::StringUTF8Scan; return false; + } } if (ch > 0xffff) { int pos = reserveSpace(4); @@ -737,8 +777,10 @@ bool Parser::parseString(bool *latin1) } ++json; - if (json >= end) + if (json >= end) { + lastError = QJsonParseError::EndOfString; return false; + } // write string length *(QJsonPrivate::qle_int *)(data + stringPos) = (current - outStart - sizeof(int))/2; diff --git a/src/corelib/json/qjsonparser_p.h b/src/corelib/json/qjsonparser_p.h index eae6c08718f..20e57dcf26d 100644 --- a/src/corelib/json/qjsonparser_p.h +++ b/src/corelib/json/qjsonparser_p.h @@ -65,7 +65,7 @@ class Parser public: Parser(const char *json, int length); - QJsonDocument parse(); + QJsonDocument parse(QJsonParseError *error); class ParsedObject { @@ -93,12 +93,14 @@ private: bool parseString(bool *latin1); bool parseValue(QJsonPrivate::Value *val, int baseOffset); bool parseNumber(QJsonPrivate::Value *val, int baseOffset); + const char *head; const char *json; const char *end; char *data; int dataLength; int current; + QJsonParseError::ParseError lastError; inline int reserveSpace(int space) { if (current + space >= dataLength) { diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp index 323546b8eae..2ac0574ec56 100644 --- a/tests/auto/corelib/json/tst_qtjson.cpp +++ b/tests/auto/corelib/json/tst_qtjson.cpp @@ -92,6 +92,7 @@ private Q_SLOTS: void toJson(); void fromJson(); + void fromJsonErrors(); void fromBinary(); void toAndFromBinary_data(); void toAndFromBinary(); @@ -1080,6 +1081,170 @@ void TestQtJson::fromJson() } } +void TestQtJson::fromJsonErrors() +{ + { + QJsonParseError error; + QByteArray json = "{\n \n\n"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::UnterminatedObject); + QCOMPARE(error.offset, 8); + } + { + QJsonParseError error; + QByteArray json = "{\n \"key\" 10\n"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::MissingNameSeparator); + QCOMPARE(error.offset, 13); + } + { + QJsonParseError error; + QByteArray json = "[\n \n\n"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::UnterminatedArray); + QCOMPARE(error.offset, 8); + } + { + QJsonParseError error; + QByteArray json = "[\n 1, true\n\n"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::UnterminatedArray); + QCOMPARE(error.offset, 14); + } + { + QJsonParseError error; + QByteArray json = "[\n 1 true\n\n"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::MissingValueSeparator); + QCOMPARE(error.offset, 7); + } + { + QJsonParseError error; + QByteArray json = "[\n nul"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::IllegalValue); + QCOMPARE(error.offset, 7); + } + { + QJsonParseError error; + QByteArray json = "[\n nulzz"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::IllegalValue); + QCOMPARE(error.offset, 10); + } + { + QJsonParseError error; + QByteArray json = "[\n tru"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::IllegalValue); + QCOMPARE(error.offset, 7); + } + { + QJsonParseError error; + QByteArray json = "[\n trud]"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::IllegalValue); + QCOMPARE(error.offset, 10); + } + { + QJsonParseError error; + QByteArray json = "[\n fal"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::IllegalValue); + QCOMPARE(error.offset, 7); + } + { + QJsonParseError error; + QByteArray json = "[\n falsd]"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::IllegalValue); + QCOMPARE(error.offset, 11); + } + { + QJsonParseError error; + QByteArray json = "[\n 11111"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::EndOfNumber); + QCOMPARE(error.offset, 11); + } + { + QJsonParseError error; + QByteArray json = "[\n -1E10000]"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::IllegalNumber); + QCOMPARE(error.offset, 14); + } + { + QJsonParseError error; + QByteArray json = "[\n -1e-10000]"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::IllegalNumber); + QCOMPARE(error.offset, 15); + } + { + QJsonParseError error; + QByteArray json = "[\n \"\\u12\"]"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::StringEscapeSequence); + QCOMPARE(error.offset, 11); + } + { + QJsonParseError error; + QByteArray json = "[\n \"foo\uffffbar\"]"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::StringUTF8Scan); + QCOMPARE(error.offset, 13); + } + { + QJsonParseError error; + QByteArray json = "[\n \""; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::EndOfString); + QCOMPARE(error.offset, 8); + } + { + QJsonParseError error; + QByteArray json = "[\n \"cЂa\\u12\"]"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::StringEscapeSequence); + QCOMPARE(error.offset, 15); + } + { + QJsonParseError error; + QByteArray json = "[\n \"cЂa\uffffbar\"]"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::StringUTF8Scan); + QCOMPARE(error.offset, 14); + } + { + QJsonParseError error; + QByteArray json = "[\n \"cЂa ]"; + QJsonDocument doc = QJsonDocument::fromJson(json, &error); + QVERIFY(doc.isEmpty()); + QCOMPARE(error.error, QJsonParseError::EndOfString); + QCOMPARE(error.offset, 14); + } +} + void TestQtJson::fromBinary() { QFile file(testDataDir + "/test.json"); From 466107107a85e7211c4b7f77b36ec50625657061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lund=20Martsum?= Date: Mon, 6 Feb 2012 09:24:50 +0100 Subject: [PATCH 343/406] Adding hasHeightForWidth as a virtual Widget funcion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just implements what the note states (and removes the private function) Change-Id: I9a6fd5134460712accf09ba01691df8b9b1f5d0d Reviewed-by: Jan-Arve Sæther --- src/widgets/kernel/qlayoutitem.cpp | 2 +- src/widgets/kernel/qwidget.cpp | 15 ++++----------- src/widgets/kernel/qwidget.h | 1 + src/widgets/kernel/qwidget_p.h | 1 - src/widgets/widgets/qsizegrip.cpp | 8 ++++---- src/widgets/widgets/qtabwidget.cpp | 14 +++++++++----- src/widgets/widgets/qtabwidget.h | 1 + 7 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/widgets/kernel/qlayoutitem.cpp b/src/widgets/kernel/qlayoutitem.cpp index 860f1cc1932..664334d7258 100644 --- a/src/widgets/kernel/qlayoutitem.cpp +++ b/src/widgets/kernel/qlayoutitem.cpp @@ -522,7 +522,7 @@ bool QWidgetItem::hasHeightForWidth() const { if (isEmpty()) return false; - return wid->d_func()->hasHeightForWidth(); + return wid->hasHeightForWidth(); } /*! diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index f095e475aff..44995f09596 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -9226,19 +9226,12 @@ int QWidget::heightForWidth(int w) const /*! - \internal - - *virtual private* - - This is a bit hackish, but ideally we would have created a virtual function - in the public API (however, too late...) so that subclasses could reimplement - their own function. - Instead we add a virtual function to QWidgetPrivate. - ### Qt5: move to public class and make virtual + Returns true if the widget's preferred height depends on its width; otherwise returns false. */ -bool QWidgetPrivate::hasHeightForWidth() const +bool QWidget::hasHeightForWidth() const { - return layout ? layout->hasHeightForWidth() : size_policy.hasHeightForWidth(); + Q_D(const QWidget); + return d->layout ? d->layout->hasHeightForWidth() : d->size_policy.hasHeightForWidth(); } /*! diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index 0594fd6f50f..78b693c78d6 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -524,6 +524,7 @@ public: void setSizePolicy(QSizePolicy); inline void setSizePolicy(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical); virtual int heightForWidth(int) const; + virtual bool hasHeightForWidth() const; QRegion visibleRegion() const; diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 0da0c65aaa4..8b66f145405 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -468,7 +468,6 @@ public: bool setMinimumSize_helper(int &minw, int &minh); bool setMaximumSize_helper(int &maxw, int &maxh); - virtual bool hasHeightForWidth() const; void setConstraints_sys(); bool pointInsideRectAndMask(const QPoint &) const; QWidget *childAt_helper(const QPoint &, bool) const; diff --git a/src/widgets/widgets/qsizegrip.cpp b/src/widgets/widgets/qsizegrip.cpp index 145bdf02d41..09557a3c909 100644 --- a/src/widgets/widgets/qsizegrip.cpp +++ b/src/widgets/widgets/qsizegrip.cpp @@ -301,7 +301,7 @@ void QSizeGrip::mousePressEvent(QMouseEvent * e) // Use a native X11 sizegrip for "real" top-level windows if supported. if (tlw->isWindow() && X11->isSupportedByWM(ATOM(_NET_WM_MOVERESIZE)) && !(tlw->windowFlags() & Qt::X11BypassWindowManagerHint) - && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) { + && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !tlw->hasHeightForWidth()) { XEvent xev; xev.xclient.type = ClientMessage; xev.xclient.message_type = ATOM(_NET_WM_MOVERESIZE); @@ -323,7 +323,7 @@ void QSizeGrip::mousePressEvent(QMouseEvent * e) } #endif // Q_WS_X11 #ifdef Q_OS_WIN - if (tlw->isWindow() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) { + if (tlw->isWindow() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !tlw->hasHeightForWidth()) { uint orientation = 0; if (d->atBottom()) orientation = d->atLeft() ? SZ_SIZEBOTTOMLEFT : SZ_SIZEBOTTOMRIGHT; @@ -413,11 +413,11 @@ void QSizeGrip::mouseMoveEvent(QMouseEvent * e) #ifdef Q_WS_X11 if (tlw->isWindow() && X11->isSupportedByWM(ATOM(_NET_WM_MOVERESIZE)) && tlw->isTopLevel() && !(tlw->windowFlags() & Qt::X11BypassWindowManagerHint) - && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) + && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !tlw->hasHeightForWidth()) return; #endif #ifdef Q_OS_WIN - if (tlw->isWindow() && qt_getWindowsSystemMenu(tlw) && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) { + if (tlw->isWindow() && qt_getWindowsSystemMenu(tlw) && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !tlw->hasHeightForWidth()) { if (const HWND hwnd = QApplicationPrivate::getHWNDForWidget(tlw)) { MSG msg; while (PeekMessage(&msg, hwnd, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) ; diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp index 66d31e72c72..612d51826c2 100644 --- a/src/widgets/widgets/qtabwidget.cpp +++ b/src/widgets/widgets/qtabwidget.cpp @@ -186,7 +186,6 @@ public: void _q_removeTab(int); void _q_tabMoved(int from, int to); void init(); - bool hasHeightForWidth() const; QTabBar *tabs; QStackedWidget *stack; @@ -238,11 +237,16 @@ void QTabWidgetPrivate::init() } -bool QTabWidgetPrivate::hasHeightForWidth() const +/*! + \reimp +*/ + +bool QTabWidget::hasHeightForWidth() const { - bool has = size_policy.hasHeightForWidth(); - if (!has && stack) - has = qt_widget_private(stack)->hasHeightForWidth(); + Q_D(const QTabWidget); + bool has = d->size_policy.hasHeightForWidth(); + if (!has && d->stack) + has = d->stack->hasHeightForWidth(); return has; } diff --git a/src/widgets/widgets/qtabwidget.h b/src/widgets/widgets/qtabwidget.h index 1865ddf8979..26d9243eb97 100644 --- a/src/widgets/widgets/qtabwidget.h +++ b/src/widgets/widgets/qtabwidget.h @@ -125,6 +125,7 @@ public: QSize sizeHint() const; QSize minimumSizeHint() const; int heightForWidth(int width) const; + bool hasHeightForWidth() const; void setCornerWidget(QWidget * w, Qt::Corner corner = Qt::TopRightCorner); QWidget * cornerWidget(Qt::Corner corner = Qt::TopRightCorner) const; From 2e4d8f67a871f2033abeb08cf94d8a31a14ad1cc Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 17 Feb 2012 11:30:56 +0100 Subject: [PATCH 344/406] Introduced QWindow::isExposed(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The visible property along with show/hideEvent tracks the windows visibility from the application perspective and is really a request. The exposeEvent() along with the isExposed() accessor is used to notify the application of the actual state of the window in the windowing system. Change-Id: I7f5b7ed74a168e34aaa21ce0ae9042ddfb0bf6d8 Reviewed-by: Samuel Rødal --- src/gui/kernel/qplatformwindow_qpa.cpp | 15 +++++++++ src/gui/kernel/qplatformwindow_qpa.h | 2 ++ src/gui/kernel/qwindow.cpp | 32 +++++++++++++++++++ src/gui/kernel/qwindow.h | 2 ++ .../platforms/windows/qwindowswindow.cpp | 1 + 5 files changed, 52 insertions(+) diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp index c52a1cf7571..f3f0a558620 100644 --- a/src/gui/kernel/qplatformwindow_qpa.cpp +++ b/src/gui/kernel/qplatformwindow_qpa.cpp @@ -142,6 +142,7 @@ QMargins QPlatformWindow::frameMargins() const void QPlatformWindow::setVisible(bool visible) { Q_UNUSED(visible); + QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size())); } /*! Requests setting the window flags of this surface @@ -152,6 +153,20 @@ Qt::WindowFlags QPlatformWindow::setWindowFlags(Qt::WindowFlags flags) return flags; } + + +/*! + Returns if this window is exposed in the windowing system. + + An exposeEvent() is sent every time this value changes. + */ + +bool QPlatformWindow::isExposed() const +{ + Q_D(const QPlatformWindow); + return d->window->visible(); +} + /*! Requests setting the window state of this surface to \a type. Returns the actual state set. diff --git a/src/gui/kernel/qplatformwindow_qpa.h b/src/gui/kernel/qplatformwindow_qpa.h index 88bf633425a..170f62162f4 100644 --- a/src/gui/kernel/qplatformwindow_qpa.h +++ b/src/gui/kernel/qplatformwindow_qpa.h @@ -89,6 +89,8 @@ public: virtual void raise(); virtual void lower(); + virtual bool isExposed() const; + virtual void propagateSizeHints(); virtual void setOpacity(qreal level); diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 96fb3946430..5b6ee0e9cb8 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -374,6 +374,25 @@ void QWindow::requestActivateWindow() d->platformWindow->requestActivateWindow(); } + +/*! + Returns if this window is exposed in the windowing system. + + When the window is not exposed, it is shown by the application + but it is still not showing in the windowing system, so the application + should minimize rendering and other graphical activities. + + An exposeEvent() is sent every time this value changes. + */ + +bool QWindow::isExposed() const +{ + Q_D(const QWindow); + if (d->platformWindow) + return d->platformWindow->isExposed(); + return false; +} + /*! Returns true if the window should appear active from a style perspective. @@ -888,6 +907,19 @@ bool QWindow::close() return true; } + + +/*! + The expose event is sent by the window system whenever the window's + exposure on screen changes. + + If the window is moved off screen, is made totally obscured by another + window, iconified or similar, this function might be called and the + value of isExposed() might change to false. When this happens, + an application should stop its rendering as it is no longer visible + to the user. + */ + void QWindow::exposeEvent(QExposeEvent *ev) { ev->ignore(); diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h index 061426befb1..1461f125206 100644 --- a/src/gui/kernel/qwindow.h +++ b/src/gui/kernel/qwindow.h @@ -152,6 +152,8 @@ public: bool isAncestorOf(const QWindow *child, AncestorMode mode = IncludeTransients) const; + bool isExposed() const; + QSize minimumSize() const; QSize maximumSize() const; QSize baseSize() const; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 58db9b32c46..3e0bec8d461 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -708,6 +708,7 @@ void QWindowsWindow::setVisible(bool visible) hide_sys(); } } + QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size())); } bool QWindowsWindow::isVisible() const From 87fcbd82fc679715853e5261f8f0194a80c10b76 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 30 Jan 2012 22:11:43 +0100 Subject: [PATCH 345/406] make configure ignore $CC and $CXX this was inconsistent with how qmake itself works, and was actually wreaking havoc. Change-Id: I5aa83cc88ffe7141cc0c31b03b76c48274f1ebdb Reviewed-by: Thiago Macieira Reviewed-by: Bradley T. Hughes --- configure | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/configure b/configure index 1215f2f3e72..d33e2489a70 100755 --- a/configure +++ b/configure @@ -3056,9 +3056,8 @@ else fi QMAKE_CONF_COMPILER=`getQMakeConf "$XQMAKESPEC" | grep "^QMAKE_CXX[^_A-Z0-9]" | sed "s,.* *= *\(.*\)$,\1," | tail -1` -TEST_COMPILER="$CXX" -[ -z "$TEST_COMPILER" ] && TEST_COMPILER=$QMAKE_CONF_COMPILER +TEST_COMPILER=$QMAKE_CONF_COMPILER if [ "$XPLATFORM_SYMBIAN_SBSV2" = "no" ]; then if [ -z "$TEST_COMPILER" ]; then echo "ERROR: Cannot set the compiler for the configuration tests" @@ -4472,14 +4471,12 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; EXTRA_LFLAGS="$EXTRA_LFLAGS -lm" fi - [ -n "$CC" ] && echo "CC = $CC" >> "$mkfile" - [ -n "$CXX" ] && echo "CXX = $CXX" >> "$mkfile" if [ "$CFG_SILENT" = "yes" ]; then - [ -z "$CC" ] && setBootstrapVariable QMAKE_CC 's,QMAKE_CC.*=,CC=\@,' - [ -z "$CXX" ] && setBootstrapVariable QMAKE_CXX 's,QMAKE_CXX.*=,CXX=\@,' + setBootstrapVariable QMAKE_CC 's,QMAKE_CC.*=,CC=\@,' + setBootstrapVariable QMAKE_CXX 's,QMAKE_CXX.*=,CXX=\@,' else - [ -z "$CC" ] && setBootstrapVariable QMAKE_CC 's,QMAKE_CC,CC,' - [ -z "$CXX" ] && setBootstrapVariable QMAKE_CXX 's,QMAKE_CXX,CXX,' + setBootstrapVariable QMAKE_CC 's,QMAKE_CC,CC,' + setBootstrapVariable QMAKE_CXX 's,QMAKE_CXX,CXX,' fi setBootstrapVariable QMAKE_CFLAGS setBootstrapVariable QMAKE_CXXFLAGS 's,\$\$QMAKE_CFLAGS,\$(QMAKE_CFLAGS),' From b164911b7f0efd81ec33325405b88bff8b2334d0 Mon Sep 17 00:00:00 2001 From: David Faure Date: Sat, 18 Feb 2012 16:00:09 +0100 Subject: [PATCH 346/406] Import QMimeType / QMimeDatabase into QtCore. History of the development before the import: ssh://codereview.qt-project.org/playground/mimetypes.git Mimetype definitions come from shared-mime-info where available (UNIX systems), loaded using a mmap'ed binary cache generated by update-mime-database. As a fallback if no cache is found, we parse the raw XML files otherwise. This makes the MIME type support fast and with very low memory usage on UNIX, and it makes it easy to use on Windows (no dependency on shared-mime-info, Qt even includes a freedesktop.xml file to use if none are found on the system). Change-Id: I27b05008216ff936dc463bd80d3893422bfb940e Reviewed-by: Richard J. Moore --- .gitignore | 2 + .../src_corelib_mimetype_qmimedatabase.cpp | 47 + src/corelib/corelib.pro | 1 + .../mime/packages/freedesktop.org.xml | 31966 ++++++++++++++++ src/corelib/mimetypes/mimetypes.pri | 25 + src/corelib/mimetypes/mimetypes.qrc | 5 + src/corelib/mimetypes/qmimedatabase.cpp | 609 + src/corelib/mimetypes/qmimedatabase.h | 95 + src/corelib/mimetypes/qmimedatabase_p.h | 90 + src/corelib/mimetypes/qmimeglobpattern.cpp | 240 + src/corelib/mimetypes/qmimeglobpattern_p.h | 146 + src/corelib/mimetypes/qmimemagicrule.cpp | 387 + src/corelib/mimetypes/qmimemagicrule_p.h | 89 + .../mimetypes/qmimemagicrulematcher.cpp | 108 + .../mimetypes/qmimemagicrulematcher_p.h | 79 + src/corelib/mimetypes/qmimeprovider.cpp | 830 + src/corelib/mimetypes/qmimeprovider_p.h | 165 + src/corelib/mimetypes/qmimetype.cpp | 506 + src/corelib/mimetypes/qmimetype.h | 115 + src/corelib/mimetypes/qmimetype_p.h | 114 + src/corelib/mimetypes/qmimetypeparser.cpp | 342 + src/corelib/mimetypes/qmimetypeparser_p.h | 142 + tests/auto/corelib/corelib.pro | 1 + .../io/qdiriterator/tst_qdiriterator.cpp | 7 +- .../qresourceengine/tst_qresourceengine.cpp | 1 + tests/auto/corelib/mimetypes/mimetypes.pro | 8 + .../qmimedatabase-cache.pro | 12 + .../tst_qmimedatabase-cache.cpp | 56 + .../qmimedatabase-xml/qmimedatabase-xml.pro | 14 + .../tst_qmimedatabase-xml.cpp | 51 + .../mimetypes/qmimedatabase/qmimedatabase.pro | 3 + .../qmimedatabase/tst_qmimedatabase.cpp | 829 + .../qmimedatabase/tst_qmimedatabase.h | 99 + .../yast2-metapackage-handler-mimetypes.xml | 15 + .../corelib/mimetypes/qmimetype/qmimetype.pro | 7 + .../mimetypes/qmimetype/tst_qmimetype.cpp | 257 + 36 files changed, 37461 insertions(+), 2 deletions(-) create mode 100644 doc/src/snippets/code/src_corelib_mimetype_qmimedatabase.cpp create mode 100644 src/corelib/mimetypes/mime/packages/freedesktop.org.xml create mode 100644 src/corelib/mimetypes/mimetypes.pri create mode 100644 src/corelib/mimetypes/mimetypes.qrc create mode 100644 src/corelib/mimetypes/qmimedatabase.cpp create mode 100644 src/corelib/mimetypes/qmimedatabase.h create mode 100644 src/corelib/mimetypes/qmimedatabase_p.h create mode 100644 src/corelib/mimetypes/qmimeglobpattern.cpp create mode 100644 src/corelib/mimetypes/qmimeglobpattern_p.h create mode 100644 src/corelib/mimetypes/qmimemagicrule.cpp create mode 100644 src/corelib/mimetypes/qmimemagicrule_p.h create mode 100644 src/corelib/mimetypes/qmimemagicrulematcher.cpp create mode 100644 src/corelib/mimetypes/qmimemagicrulematcher_p.h create mode 100644 src/corelib/mimetypes/qmimeprovider.cpp create mode 100644 src/corelib/mimetypes/qmimeprovider_p.h create mode 100644 src/corelib/mimetypes/qmimetype.cpp create mode 100644 src/corelib/mimetypes/qmimetype.h create mode 100644 src/corelib/mimetypes/qmimetype_p.h create mode 100644 src/corelib/mimetypes/qmimetypeparser.cpp create mode 100644 src/corelib/mimetypes/qmimetypeparser_p.h create mode 100644 tests/auto/corelib/mimetypes/mimetypes.pro create mode 100644 tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro create mode 100644 tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp create mode 100644 tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro create mode 100644 tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp create mode 100644 tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro create mode 100644 tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp create mode 100644 tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h create mode 100644 tests/auto/corelib/mimetypes/qmimedatabase/yast2-metapackage-handler-mimetypes.xml create mode 100644 tests/auto/corelib/mimetypes/qmimetype/qmimetype.pro create mode 100644 tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp diff --git a/.gitignore b/.gitignore index c059b261116..3aeefbafe9e 100644 --- a/.gitignore +++ b/.gitignore @@ -112,6 +112,8 @@ tests/auto/qmake/testdata/quotedfilenames/*.exe tests/auto/compilerwarnings/*.exe tests/auto/qmake/testdata/quotedfilenames/test.cpp tests/auto/qprocess/fileWriterProcess.txt +tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/mime/ +tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/mime/ .com.apple.timemachine.supported tests/auto/qlibrary/libmylib.so* tests/auto/qresourceengine/runtime_resource.rcc diff --git a/doc/src/snippets/code/src_corelib_mimetype_qmimedatabase.cpp b/doc/src/snippets/code/src_corelib_mimetype_qmimedatabase.cpp new file mode 100644 index 00000000000..e59a96b87a3 --- /dev/null +++ b/doc/src/snippets/code/src_corelib_mimetype_qmimedatabase.cpp @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QMimeDatabase db; +QMimeType mime = db.mimeTypeForFile(fileName); +if (mime.inherits("text/plain")) { + // The file is plain text, we can display it in a QTextEdit +} +//! [0] diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index c8c9b9b8e6f..40b42f4dbea 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -28,6 +28,7 @@ include(plugin/plugin.pri) include(kernel/kernel.pri) include(codecs/codecs.pri) include(statemachine/statemachine.pri) +include(mimetypes/mimetypes.pri) include(xml/xml.pri) mac|darwin { diff --git a/src/corelib/mimetypes/mime/packages/freedesktop.org.xml b/src/corelib/mimetypes/mime/packages/freedesktop.org.xml new file mode 100644 index 00000000000..f607f1d3ff9 --- /dev/null +++ b/src/corelib/mimetypes/mime/packages/freedesktop.org.xml @@ -0,0 +1,31966 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]> + + + ATK inset + شكل ATK + Ustaŭka ATK + Сбор — ATK + inset ATK + Vložka ATK + ATK-indsættelse + ATK-Inset + ATK inset + inserción ATK + ATK sartzapena + ATK-osio + ATK innskot + encart ATK + intlis ATK + conxunto ATK + תוספת ATK + ATK betét + Inset ATK + Inset ATK + ATK インセット + ATK беті + ATK inset + ATK inset + ATK ielaidums + ATK-innsats + ATK-invoegsel + ATK-innskot + Wstawka ATK + Conjunto de entrada do ATK + Inset ATK + вкладка ATK + Vložka ATK + Vložka ATK + Inset ATK + ATK-inlägg + вкладка ATK + Bộ dát ATK + ATK 嵌入对象 + ATK + Andrew Toolkit + + + + + electronic book document + مستند كتاب إلكتروني + elektronnaja kniha + Документ — електронна книга + document de llibre electrònic + Dokument elektronické knihy + elektronisk bogdokument + Elektronisches Buch + documento de libro electrónico + liburu elektronikoaren dokumentua + elektroninen kirja + elektroniskbóka skjal + document livre électronique + leabhar leictreonach + documento de libro electrónico + מסמך מסוג ספר אלקטרוני + elektronikus könyvdokumentum + dokumen buku elektronik + Documento libro elettronico + 電子ブックドキュメント + электронды кітабы + 전자책 문서 + elektroninės knygos dokumentas + elektroniskās grāmatas dokuments + elektronisch boek + elektronisk bok-dokument + Dokument książki elektronicznej + documento de livro eletrônico + document carte electronică + электронная книга + Dokument elektronickej knihy + dokument elektronske knjige + Dokument libri elektronik + elektroniskt bokdokument + документ електронної книги + tài liệu cuốn sách điện tử + 电子书文档 + 電子書文件 + + + + + + + + + + + + + Adobe Illustrator document + مستند أدوبي المصور + Dakument Adobe Illustrator + Документ — Adobe Illustrator + document d'Adobe Illustrator + Dokument Adobe Illustrator + Adobe Illustrator-dokument + Adobe-Illustrator-Dokument + έγγραφο Adobe Illustrator + Adobe Illustrator document + dokumento de Adobe Illustrator + documento de Adobe Illustrator + Adobe Illustrator dokumentua + Adobe Illustrator -asiakirja + Adobe Illustrator skjal + document Adobe Illustrator + cáipéis Adobe Illustrator + documento de Adobe Ilustrator + מסמך Adobe Ill + Adobe Illustrator-dokumentum + Dokumen Adobe Illustrator + Documento Adobe Illustrator + Adobe Illustrator ドキュメント + Adobe Illustrator құжаты + 어도비 일러스트레이터 문서 + Adobe Illustrator dokumentas + Adobe Illustrator dokuments + Dokumen Adobe Illustrator + Adobe Illustrator-dokument + Adobe Illustrator-document + Adobe Illustrator-dokument + Dokument Adobe Illustrator + documento Adobe Illustrator + Documento do Adobe Illustrator + Document Adobe Illustrator + документ Adobe Illustrator + Dokument Adobe Illustrator + Dokument Adobe Illustrator + Dokument Adobe Illustrator + Адоуби Илустратор документ + Adobe Illustrator-dokument + документ Adobe Illustrator + Tài liệu Adobe Illustrator + Adobe Illustrator 文档 + Adobe Illustrator 文件 + + + + + Macintosh BinHex-encoded file + ملف Macintosh BinHex مشفر + Macintosh BinHex-kodlanmış fayl + Fajł Macintosh, BinHex-zakadavany + Файл — кодиран във формат BinHex за Macintosh + fitxer codificat BinHex de Macintosh + Soubor kódovaný pomocí Macintosh BinHex + Ffeil BinHex-amgodwyd Macintosh + Macintosh BinHex-kodet fil + Macintosh-Datei (BinHex-kodiert) + αρχείο Macintosh κωδικοποίησης BinHex + Macintosh BinHex-encoded file + dosiero kodigita laŭ Macintosh BinHex + archivo Macintosh codificado con BinHex + Macintosh BinHex-ekin kodetutako fitxategia + Macintosh BinHex -koodattu tiedosto + Macintosh BinHex-bronglað fíla + fichier codé Macintosh BinHex + comhad ionchódaithe le Macintosh BinHex + ficheiro de Macintosh codificado con BinHex + קובץ מסוג Macintosh BinHex-encoded + Macintosh BinHex kódolású fájl + Berkas tersandi Macintosh BinHex + File Macintosh codificato BinHex + Macintosh BinHex エンコードファイル + Macintosh BinHex кодталған файлы + 맥킨토시 BinHex 인코딩된 압축 파일 + Macintosh BinHex-encoded failas + Macintosh BinHex-kodēts fails + Fail terenkod-BinHex Macintosh + Macintosh BinHe-kodet arkiv + Macintosh BinHex-gecodeerd bestand + Macintosh BinHex-koda fil + Zakodowany w BinHex plik Macintosh + ficheiro codificado em BinHex de Macintosh + Arquivo Macintosh codificado com BinHex + Fișier codat Macintosh BinHex + файл (закодированный Macintosh BinHex) + Súbor kódovaný pomocou Macintosh BinHex + Kodirana datoteka Macintosh (BinHex) + File Macintosh i kodifikuar BinHex + Мекинтош BinHex-encoded датотека + Macintosh BinHex-kodad fil + файл закодований Macintosh BinHex + Tập tin đã mã hoá BinHex của Macintosh + Macintosh BinHex 编码的文件 + Macintosh BinHex 編碼檔 + + + + + + + Mathematica Notebook + مذكرة رياضيات + Natatnik Mathematica + Тетрадка — Mathematica + llibreta de notes de Mathematica + Sešit Mathematica + Mathematica Notebook + Mathematica-Dokument + Mathematica Notebook + notebook de Mathematica + Mathematica Notebook + Mathematica-muistilehtiö + Mathematica skriviblokkur + carnet de notes Mathematica + leabhar nótaí Mathematica + notebook de Mathematica + מחברת מתמטיקה + Mathematica notesz + Mathematica Notebook + Notebook Mathematica + Mathematica ノートブック + Mathematica Notebook + Mathematica 노트북 + Mathematica užrašinė + Mathematica bloknots + Mathematica notisblokk + Mathematica-notitieboek + Mathematica-notatbok + Notatnik Mathematica + Caderno do Mathematica + Carnețel Mathematica + Mathematica Notebook + Zošit Mathematica + Datoteka dokumenta Mathematica + Notebook matematike + Mathematica Notebook-dokument + математичний записник + Cuốn vở Mathematica + Mathematica 记事 + Mathematica Notebook + + + + + + + + + + + + MathML document + مستند MathML + MathML sənədi + Dakument MathML + Документ — MathML + document de MathML + Dokument MathML + Dogfen MathML + MathML-dokument + MathML-Dokument + έγγραφο MathML + MathML document + MathML-dokumento + documento MathML + MathML dokumentua + MathML-asiakirja + MathML skjal + document MathML + cáipéis MathML + documento de MathML + מסמך MathML + MathML-dokumentum + Dokumen MathML + Documento MathML + MathML ドキュメント + MathML құжаты + MathML 문서 + MathML dokumentas + MathML dokuments + Dokumen MathML + MathML-dokument + MathML-document + MathML-dokument + Dokument MathML + documento MathML + Documento do MathML + Document MathML + документ MathML + Dokument MathML + Dokument MathML + Dokument MathML + MathML документ + MathML-dokument + документ MathML + Tài liệu MathML + MathML 文档 + MathML 文件 + MathML + Mathematical Markup Language + + + + + + + mailbox file + ملف صندوق البريد + fajł paštovaj skryni + Файл — Mailbox + fitxer mailbox + Soubor mailbox + postkassefil + Mailbox-Datei + archivo de buzón de correo + mailbox fitxategia + mailbox-tiedosto + postkassafíla + fichier boîte aux lettres + comhad bhosca poist + ficheiro de caixa de correo + קובץ תיבת-דואר + mailbox fájl + berkas kotak surat + File mailbox + メールボックスファイル + пошта жәшігінің файлы + 메일함 파일 + pašto dėžutės failas + pastkastītes fails + postboksfil + mailbox-bestand + mailbox-fil + Plik poczty (Mailbox) + Arquivo de caixa de correio + fișier căsuță poștală + файл почтового ящика + Súbor mailbox + datoteka poštnega predala + File mailbox + brevlådefil + файл поштової скриньки + tập tin hộp thư + mailbox 文件 + 郵箱檔 + + + + + + + + + Metalink file + ملف ميتالنك + Изтегляне — Metalink + fitxer Metalink + Soubor metalink + Metahenvisningsfil + Metalink-Datei + Metalink-dosiero + archivo de metaenlace + Metaestekaren fitxategia + Metalink-tiedosto + Metalink fíla + fichier metalink + comhad Metalink + ficheiro Metalink + קובץ Metalink + Metalink fájl + Berkas Metalink + File Metalink + Metalink ファイル + Metalink файлы + Metalink 파일 + Metalink failas + Metalink fails + Plik Metalink + Fișier Metalink + файл Metalink + Súbor Metalink + Datoteka povezave Metalink + Metalink-fil + файл метапосилання + 元链接文件 + Metalink 檔案 + + + + + + + + + Metalink file + ملف ميتالنك + Изтегляне — Metalink + fitxer Metalink + Soubor metalink + Metahenvisningsfil + Metalink-Datei + Metalink-dosiero + archivo de metaenlace + Metaestekaren fitxategia + Metalink-tiedosto + Metalink fíla + fichier metalink + comhad Metalink + ficheiro Metalink + קובץ Metalink + Metalink fájl + Berkas Metalink + File Metalink + Metalink ファイル + Metalink файлы + Metalink 파일 + Metalink failas + Metalink fails + Plik Metalink + Fișier Metalink + файл Metalink + Súbor Metalink + Datoteka povezave Metalink + Metalink-fil + файл метапосилання + 元链接文件 + Metalink 檔案 + + + + + + + + + unknown + مجهول + nieviadomy + Неизвестен тип + desconegut + Neznámý + ukendt + Unbekannt + αγνωστο + unknown + nekonate + desconocido + ezezaguna + tuntematon + ókent + inconnu + anaithnid + descoñecido + לא ידוע + ismeretlen + tak diketahui + Sconosciuto + 不明 + белгісіз + 알 수 없음 + nežinoma + nezināms + Entah + ukjent + onbekend + ukjend + Nieznany typ + desconhecido + desconhecido + necunoscut + неизвестно + Neznámy + neznano + Nuk njihet + непознато + okänd + невідомо + không rõ + 未知 + 不明 + + + + ODA document + مستند ODA + ODA sənədi + Dakument ODA + Документ — ODA + document ODA + Dokument ODA + Dogfen ODA + ODA-dokument + ODA-Dokument + έγγραφο ODA + ODA document + ODA-dokumento + documento ODA + ODA dokumentua + ODA-asiakirja + ODA skjal + document ODA + cáipéis ODA + documento ODA + מסמך ODA + ODA-dokumentum + Dokumen ODA + Documento ODA + ODA ドキュメント + ODA құжаты + ODA 문서 + ODA dokumentas + ODA dokuments + Dokumen ODA + ODA-dokument + ODA-document + ODA-dokument + Dokument ODA + documento ODA + Documento ODA + Document ODA + документ ODA + Dokument ODA + Dokument ODA + Dokument ODA + ODA документ + ODA-dokument + документ ODA + Tài liệu ODA + ODA 文档 + ODA 文件 + ODA + Office Document Architecture + + + + + WWF document + Документ — WWF + document WWF + Dokument WWF + WWF-Dokument + WWF-dokumento + Documento de WWF + WWF-asiakirja + document WWF + documento de WWF + מסמך WWF + WWF dokumentum + Dokumen WWF + Documento WWF + WWF 文書 + WWF құжаты + WWF 문서 + WWF dokuments + Dokument WWF + документ WWF + Dokument WWF + WWF-dokument + документ WWF + WWF + WWF 文件 + + + + + + + PDF document + مستند PDF + Dakument PDF + Документ — PDF + document PDF + Dokument PDF + Dogfen PDF + PDF-dokument + PDF-Dokument + έγγραφο PDF + PDF document + PDF-dokumento + documento PDF + PDF dokumentua + PDF-asiakirja + PDF skjal + document PDF + cáipéis PDF + documento PDF + מסמך PDF + PDF-dokumentum + Dokumen PDF + Documento PDF + PDF ドキュメント + PDF құжаты + PDF 문서 + PDF dokumentas + PDF dokuments + Dokumen PDF + PDF-dokument + PDF-document + PDF-dokument + Dokument PDF + documento PDF + Documento PDF + Document PDF + документ PDF + Dokument PDF + Dokument PDF + Dokument PDF + PDF документ + PDF-dokument + документ PDF + Tài liệu PDF + PDF 文档 + PDF 文件 + PDF + Portable Document Format + + + + + + + + + + + XSPF playlist + قائمة تشغيل XSPF + Śpis piesień XSPF + Списък за изпълнение — XSPF + llista de reproducció XSPF + Seznam skladeb XSPF + XSPF-afspilningsliste + XSPF-Wiedergabeliste + XSPF-ludlisto + lista de reproducción XSPF + XSPF erreprodukzio-zerrenda + XSPF-soittolista + XSPF avspælingarlisti + liste de lecture XSPF + seinmliosta XSPF + lista de reprodución XSPF + רשימת השמעה XSPF + XSPF-lejátszólista + Senarai pular XSPF + Scaletta XSPF + XSPF 再生リスト + XSPF ойнау тізімі + XSPF 재생 목록 + XSPF grojaraštis + XSPF repertuārs + XSPF-spilleliste + XSPF-afspeellijst + XSPF-speleliste + Lista odtwarzania XSPF + Lista de reprodução XSPF + Listă XSPF + список воспроизведения XSPF + Zoznam skladieb XSPF + Seznam predvajanja XSPF + Listë titujsh XSPF + XSPF-spellista + список програвання XSPF + Danh mục nhạc XSPF + XSPF 播放列表 + XSPF 播放清單 + XSPF + XML Shareable Playlist Format + + + + + + + + + + + + Microsoft Windows theme pack + حزمة سمات Microsoft Works + Пакет с тема — Microsoft Windows + paquet de temes Windows de Microsoft + Balík motivů Microsoft Windows + Microsoft Windows-temapakke + Themenpaket für Microsoft Windows + paquete de tema para Microsoft Windows + Microsoft Windows-en gaiaren paketea + Microsoft Windows -teemapaketti + Microsoft Windows tema pakki + paquet de thèmes Microsoft Windows + paca téamaí Microsoft Windows + paquete de tema de Microsoft Windows + חבילת ערכות נושא של Microsoft Windows + Microsoft Windows témacsomag + Pak tema Microsoft Windows + Pacchetto temi Microsoft Windows + Microsoft Windows テーマパック + Microsoft Windows тема дестесі + 마이크로소프트 윈도우 테마 패키지 + Microsoft Windows temų paketas + Microsoft Windows tēmas paka + Pakiet motywu Microsoft Windows + Pachet de teme Microsoft Windows + пакет темы Microsoft Windows + Balík tém Microsoft Windows + Datoteka teme Microsoft Windows + Microsoft Windows-temapaket + пакунок з темою Microsoft Windows + Microsoft Windows 主题包 + 微軟視窗佈景主題包 + + + + + + GSM 06.10 audio + GSM 06.10 سمعي + Аудио — GSM 06.10 + àudio GSM 06.10 + Zvuk GSM 06.10 + GSM 06.10-lyd + GSM-06.10-Audio + sonido GSM 06.10 + GSM 06.10 audioa + GSM 06.10 -ääni + GSM 06.10 ljóður + audio GSM 06.10 + fuaim GSM 06.10 + son de GSM 06.10 + שמע GSM 06.10 + GSM 06.10 hang + Audio GSM 06.10 + Audio GSM 06.10 + GSM 06.10 オーディオ + GSM 06.10 аудиосы + GSM 06.10 오디오 + GSM 06.10 garso įrašas + GSM 06.10 audio + GSM 06.10 audio + Plik dźwiękowy GSM 06.10 + Áudio GSM 06.10 + GSM 06.10 audio + аудио GSM 06.10 + Zvuk GSM 06.10 + Zvočna datoteka GSM 06.10 + GSM 06.10-ljud + звук GSM 06.10 + Âm thanh GSM 06.10 + GSM 06.10 音频 + GSM 06.10 音訊 + GSM + Global System for Mobile communications + + + + iRiver Playlist + قائمة تشغيل iRiver + Śpis piesień iRiver + Списък за изпълнение — iRiver + llista de reproducció iRiver + Seznam skladeb iRiver + iRiver-afspilningsliste + iRiver-Wiedergabeliste + iRiver-ludlisto + lista de reproducción de iRiver + iRiver erreprodukzio-zerrenda + iRiver-soittolista + iRiver avspælingarlisti + liste de lecture iRiver + seinmliosta iRiver + lista de reprodución de iRiver + רשימת השמעה של iRiver + iRiver lejátszólista + iRiver Playlist + Scaletta iRiver + iRiver 再生リスト + iRiver ойнау тізімі + iRiver 재생 목록 + iRiver grojaraštis + iRiver repertuārs + iRiver-spilleliste + iRiver-afspeellijst + iRiver speleliste + Lista odtwarzania iRiver + Lista de reprodução do iRiver + Listă iRiver + список воспроизведения iRiver + Zoznam skladieb iRiver + Seznam predvajanja iRiver + Listë titujsh iRiver + iRiver-spellista + список програвання iRiver + danh mục nhạc iRiver + iRiver 播放列表 + iRiver 播放清單 + + + + + + + PGP/MIME-encrypted message header + ترويسة رسالة PGP/MIME-مشفرة + Zahałovak paviedamleńnia, zašyfravany ŭ PGP/MIME + Заглавна част на шифрирано съобщение — PGP/MIME + capçalera de missatge xifrat amb PGP/MIME + Záhlaví zprávy zašifrované pomocí PGP/MIME + PGP-/MIME-krypteret meddelelseshoved + PGP/MIME-verschlüsselter Nachrichtenkopf + κεφαλίδα μηνύματος κρυπτογραφημένου κατά PGP/MIME + PGP/MIME-encrypted message header + PGP/MIME-ĉifrita ĉapo de mesaĝo + cabecera de mensaje cifrado PGP/MIME + PGP/MIME enkriptatutako mezu-goiburua + PGP/MIME-salattu viestiotsikko + PGP/MIME-encrypted boð tekshøvd + en-tête de message codé PGP/MIME + ceanntásc teachtaireachta ionchódaithe le PGP/MIME + cabeceira de mensaxe cifrado PGP/MIME + כותר של קובץ מוצפן מסוג PGP/MIME + PGP/MIME titkosított üzenetfejléc + Tajuk pesan terenkripsi PGP/MIME + Intestazione messaggio PGP/MIME-encrypted + PGP/MIME 暗号化メッセージヘッダー + PGP/MIME-шифрленген мәлімдеме тақырыптамасы + PGP/MIME으로 암호화된 메시지 헤더 + PGP/MIME užšifruota žinutės antraštė + PGP/MIME-šifrēta ziņas galvene + Pengepala mesej terenkripsi PGP/MIME + PGP/MIME-kryptert meldingshode + PGP/MIME-versleutelde berichtkopregels + PGP/MIME-kryptert meldingshovud + Nagłówek listu zaszyfrowanego PGP/MIME + cabeçalho de mensagem cifrada com PGP/MIME + Cabeçalho de mensagem criptografada PGP/MIME + Antet de mesaj encriptat PGP/MIME + заголовок сообщения, зашифрованный PGP/MIME + Hlavičke správy zašifrovaná pomocou PGP/MIME + Datoteka glave šifriranega sporočila PGP/MIME + Header mesazhi të kriptuar PGP/MIME + ПГП/МИМЕ шифровано заглавље поруке + PGP/MIME-krypterat meddelandehuvud + заголовок шифрованого PGP/MIME повідомлення + Phần đầu thông điệp đã mật mã bằng PGP/MIME + PGP/MIME 加密的信件头 + PGP/MIME 加密訊息標頭 + + + + + + + + + + + PGP keys + مفاتيح PGP + PGP açarları + Klučy PGP + Ключове — PGP + claus PGP + Klíče PGP + Allweddi PGP + PGP-nøgler + PGP-Schlüssel + κλειδιά PGP + PGP keys + PGP-ŝlosiloj + claves PGP + PGP giltzak + PGP-avainrengas + PGP lyklar + clés PGP + eochracha PGP + Chaves PGP + מפתח PGP + PGP-kulcs + Kunci PGP + Chiavi PGP + PGP 鍵 + PGP кілттері + PGP 키 + PGP raktai + PGP atslēgas + Kekunci PGP + PGP-nøkler + PGP-sleutels + PGP-nøkler + Klucze PGP + chaves PGP + Chaves PGP + Chei PGP + ключи PGP + Kľúče PGP + Datoteka ključa PGP + Kyçe PGP + PGP кључ + PGP-nycklar + ключі PGP + Khoá PGP + PGP 密钥 + PGP 鑰匙 + PGP + Pretty Good Privacy + + + + + + + + + + + + + + + + detached OpenPGP signature + إمضاء OpenPGP مفصول + adłučany podpis OpenPGP + Отделен подпис — OpenPGP + signatura OpenPGP separada + Oddělený podpis OpenPGP + frigjort OpenPGP-signatur + Isolierte OpenPGP-Signatur + αποκομμένη υπογραφή OpenPGP + detached OpenPGP signature + dekroĉa OpenPGP-subskribo + firma OpenPGP separada + desuzturtako OpenPGP sinadura + erillinen OpenPGP-allekirjoitus + skild OpenPGP undirskrift + signature OpenPGP détachée + síniú OpenPGP scartha + sinatura de OpenPGP independente + חתימת OpenPGP מנותקת + leválasztott OpenPGP-aláírás + tanda tangan OpenPGP yang terlepas + Firma staccata OpenPGP + 分離 OpenPGP 署名 + бөлінген OpenPGP қолтаңбасы + 분리된 OpenPGP 서명 + neprisegtas OpenPGP parašas + atvienots OpenPGP paraksts + Tandatangan OpenPGP terlerai + frakoblet OpenPGP-signatur + losse OpenPGP-ondertekening + fråkopla OpenPGP-signatur + Oddzielony podpis OpenPGP + assinatura OpenPGP solta + assinatura OpenPGP destacada + semnătură OpenPGP detașată + отсоединённая подпись OpenPGP + Oddelený podpis OpenPGP + odpet podpis OpenPGP + Firmë e shkëputur OpenPGP + одвојени ОпенПГП потпис + frikopplad OpenPGP-signatur + відокремлений OpenPGP підпис + chữ ký OpenPGP tách rời + 分离的 OpenPGP 签名 + 分離的 OpenPGP 簽章 + + + + + + + + + S/MIME file + ملف S/MIME + S/MIME faylı + Fajł S/MIME + Файл — S/MIME + fitxer S/MIME + Soubor S/MIME + Ffeil S/MIME + S/MIME-fil + S/MIME-Datei + αρχείο S/MIME + S/MIME file + S/MIME-dosiero + archivo S/MIME + S/MIME fitxategia + S/MIME-tiedosto + S/MIME fíla + fichier S/MIME + comhad S/MIME + ficheiro S/MIME + קובץ S/MIME + S/MIME-fájl + Berkas S/MIME + File S/MIME + S/MIME ファイル + S/MIME файлы + S/MIME 파일 + S/MIME failas + S/MIME fails + Fail S/MIME + S/MIME-fil + S/MIME-bestand + S/MIME-fil + Plik S/MIME + ficheiro S/MIME + Arquivo S/MIME + Fișier S/MIME + файл S/MIME + Súbor S/MIME + Datoteka S/MIME + File S/MIME + S/MIME датотека + S/MIME-fil + файл S/MIME + Tập tin S/MIME + S/MIME 文件 + S/MIME 檔 + S/MIME + Secure/Multipurpose Internet Mail Extensions + + + + detached S/MIME signature + إمضاء S/MIME مفصول + adłučany podpis S/MIME + Отделен подпис — S/MIME + signatura S/MIME separada + Oddělený podpis S/MIME + frigjort S/MIME-signatur + Isolierte S/MIME-Signatur + αποκομμένη υπογραφή S/MIME + detached S/MIME signature + dekroĉa S/MIME-subskribo + firma S/MIME separada + desuzturtako S/MIME sinadura + erillinen S/MIME-allekirjoitus + skild S/MIME undirskrift + signature S/MIME détachée + síniú S/MIME scartha + sinatura S/MIME independente + חתימת S/MIME מנותקת + leválasztott S/MIME-aláírás + tanda tangan S/MIME yang terlepas + Firma staccata S/MIME + 分離 S/MIME 署名 + бөлінген S/MIME қолтаңбасы + 분리된 S/MIME 서명 + neprisegtas S/MIME parašas + atvienots S/MIME paraksts + Tandatangan S/MIME terlerai + frakoblet S/MIME-signatur + losse S/MIME-ondertekening + fråkopla S/MIME-signatur + Oddzielony podpis S/MIME + assinatura S/MIME solta + assinatura S/MIME destacada + semnătură S/MIME detașată + отсоединённая подпись S/MIME + Oddelený podpis S/MIME + odpet podpis S/MIME + Firmë e shkëputur S/MIME + одвојени S/MIME потпис + frikopplad S/MIME-signatur + відокремлений S/MIME підпис + chữ ký S/MIME tách rời + 分离的 S/MIME 签名 + 分離的 S/MIME 簽章 + S/MIME + Secure/Multipurpose Internet Mail Extensions + + + + + + PKCS#8 private key + رزمة الشهادة PKCS#8 + Ключ, частен — PKCS#8 + clau privada PKCS#8 + Soukromý klíč PKCS#8 + PKCS#8-privat nøgle + PKCS#8 Geheimer Schlüssel + clave privada PCKS#8 + PKCS#8 yksityinen avain + PKCS#8 privatur lykil + clé privée PKCS#8 + eochair phríobháideach PKCS#8 + Chave privada PKCS#8 + מפתח פרטי של PKCS#8 + PKCS#8 személyes kulcs + Kunci privat PKCS#8 + Chiave privata PKCS#8 + PKCS#8 秘密鍵 + PKCS#8 меншік кілті + PKCS#8 개인 키 + PKCS#8 asmeninis raktas + PKCS#8 privātā atslēga + Klucz prywatny PKCS#8 + Cheie privată PKCS#8 + личный ключ PKCS#8 + Súkromný kľúč PKCS#8 + Datoteka osebnega ključa PKCS#8 + Privat PKCS#8-nyckel + закритий ключ PKCS#8 + PKCS#8 私钥 + PKCS#8 私人金鑰 + PKCS + Public-Key Cryptography Standards + + + + PKCS#10 certification request + طلب شهادة PKCS#10 + Zapyt sertyfikacyi PKCS#10 + Заявка за сертификат — PKCS#10 + sol·licitud de certificació PKCS#10 + Požadavek na certifikát PKCS#10 + PKCS#10-certifikatanmodning + PKCS#10-Zertifikatanfrage + petición de certificados PKCS#10 + PKCS#10 ziurtagirien eskaera + PKCS#10-varmennepyyntö + PKCS#10 váttanarumbøn + requête de certification PKCS#10 + iarratas dheimhniúchán PKCS#10 + Solicitude de certificado PKCS#10 + בקשה מוסמכת PLCS#10 + PKCS#10-tanúsítványkérés + Permintaan sertifikasi PKCS#10 + Richiesta certificazione PKCS#10 + PKCS#10 証明書署名要求 + PKCS#10 сертификацияға сұранымы + PKCS#10 인증서 요청 + PKCS#10 liudijimų užklausa + PKCS#10 sertifikācijas pieprasījums + PKCS#10-sertifikatforespørsel + PKCS#10-certificatieverzoek + PKCS#10-sertifiseringsførespurnad + Żądanie certyfikatu PKCS#10 + Pedido de certificação PKCS#12 + Cerere de certificat PKCS#10 + запрос сертификации PKCS#10 + Požiadavka na certifikát PKCS#10 + Datoteka potrdila PKCS#10 + Kërkesë çertifikimi PKCS#10 + PKCS#10-certifikatbegäran + комплект сертифікатів PKCS#10 + Yêu cầu chứng nhận PKCS#10 + PKCS#10 认证请求 + PKCS#10 憑證請求 + PKCS + Public-Key Cryptography Standards + + + + + X.509 certificate + شهادة X.509 + Сертификат — X.509 + certificat X.509 + Certifikát X.509 + X.509-certifikat + X.509-Zertifikat + certificado X.509 + X.509 ziurtagiria + X.509-varmenne + X.509 prógv + certificat X.509 + teastas X.509 + Certificado X.509 + אישור X.509 + X.509 tanúsítvány + Sertifikat X.509 + Certificato X.509 + X.509 証明書 + X.509 сертификаты + X.509 인증서 + X.509 liudijimas + X.509 sertifikāts + Certyfikat X.509 + Certificat X.509 + сертификат X.509 + Certifikát X.509 + Datoteka potrdila X.509 + X.509-certifikat + сертифікат X.509 + X.509 证书 + X.509 憑證 + + + + Certificate revocation list + قائمة إبطال الشهادات + Списък с отхвърлени сертификати + llista de revocació de certificats + Seznam odvolaných certifikátů + Certifikattilbagekaldelsesliste + Liste widerrufener Zertifikate + lista de revocación de certificados + Ziurtagiri-errebokatzeen zerrenda + Varmenteiden sulkulista + Prógv afturtøkulisti + liste de révocation de certificat + liosta teastas cúlghairmthe + lista de certificados de revogación + רשימת אישורים מבוטלים + Tanúsítvány-visszavonási lista + Daftar pencabutan sertificat (CRL) + Elenco certificati di revoca + 証明書失効リスト + Сертификатты қайта шақыру тізімі + 인증서 철회 목록 + Panaikintų liudijimų sąrašas + Sertifikātu atsaukšanu saraksts + Lista unieważnień certyfikatów + Listă de revocare a certificatelor + Список аннулирования сертификатов + Zoznam zrušených certifikátov + Datoteka seznama preklica potrdil + Spärrlista för certifikat + список відкликання сертифікатів + 证书吊销列表 + 憑證撤銷清單 + + + + PkiPath certification path + مسار شهادة PkiPath + Сертификационна верига — PkiPath + ruta de certificació PkiPath + Cesta k certifikátu PkiPath + PkiPath-certifikationssti + PkiPath-Zertifikatspfad + ruta de certificación PkiPath + PkiPath ziurtagirien bide-izena + PkiPath-varmennepolku + PkiPath váttanleið + chemin de certification PkiPath + conair dheimhniúcháin PkiPath + Ruta de certificación PkiPath + נתיב מאושר של PkiPath + PkiPath tanúsítványútvonal + Alamat sertifikasi PkiPath + Percorso certificazione PkiPath + PkiPath 証明書パス + PkiPath сертификаттау жолы + PkiPath 인증서 요청 + PkiPath liudijimų maršrutas + PkiPath sertifikāta ceļš + PkiPath-certificatiepad + Ścieżka certyfikacji PkiPath + Pedido de certificação PkiPath + Cale certificare PkiPath + путь сертификации PkiPath + Cesta k certifikátu PkiPath + Datoteka poti potrdila PkiPath + PkiPath-certifikatsekvens + шлях сертифікації PkiPath + Đường dẫn cấp chứng nhận PkiPath + PkiPath 证书目录 + PkiPath 憑證路徑 + + + + PS document + مستند PS + Dakument PS + Документ — PS + document PS + Dokument PS + PS-dokument + PS-Dokument + PS document + PS-dokumento + documento PS + PS dokumentua + PS-asiakirja + PS skjal + document PS + cáipéis PS + documento PS + מסמך PS + PS dokumentum + Dokumen PS + Documento PS + PS ドキュメント + PS құжаты + PS 문서 + PS dokumentas + PS dokuments + PS-dokument + PS-document + PS-dokument + Dokument PS + Documento PS + Document PS + документ PS + Dokument PS + Dokument PS + Dokument PS + PS-dokument + документ PS + Tài liệu PS + PS 文档 + Ps 文件 + PS + PostScript + + + + + + + + + + Plucker document + مستند Plucker + Dakument Plucker + Документ — Plucker + document Plucker + Dokument Plucker + Pluckerdokument + Plucker-Dokument + Plucker-dokumento + documento de Plucker + Plucker dokumentua + Plucker-asiakirja + Plucker skjal + document Plucker + cáipéis Plucker + documento de Plucker + מסמך של Plucker + Plucker dokumentum + Dokumen Plucker + Documento Plucker + Plucker ドキュメント + Plucker құжаты + Plucker 문서 + Plucker dokumentas + Plucker dokuments + Plucker-dokument + Plucker-document + Plucker-dokument + Dokument Plucker + Documento do Plucker + Document Plucker + документ Plucker + Dokument Plucker + Dokument Plucker + Dokument Plucker + Plucker-dokument + документ Plucker + Tài liệu Plucker + Plucker 文档 + Plucker 文件 + + + + + + + RELAX NG XML schema + مخطط RELAX NG XML + Схема за XML — RELAX NG + esquema XML RELAX NG + Schéma RELAX NG XML + RELAX NG XML-skema + RELAX NG XML-Schema + Esquema XML RELAX NG + RELAX NG XML-skeema + schéma XML RELAX NG + scéimre XML RELAX NG + Esquema XML RELAX NG + סכנת RELAX NG XML + RELAX NG XML-séma + Skema XML RELAX NG + Schema XML RELAX NG + RELAX NG XML スキーマ + RELAX NG XML сұлбасы + RELAX NG XML 스키마 + RELAX NG XML schema + RELAX NG XML shēma + Schemat XML RELAX NG + Schemă RELAX NG XML + XML-схема RELAX NG + XML schéma RELAX NG + Datoteka shema RELAX NG XML + RELAX NG XML-schema + XML-схема RELAX NG + RELAX NG XML 模式 + RELAX NG + REgular LAnguage for XML Next Generation + + + + + + + RTF document + مستند RTF + Dakument RTF + Документ — RTF + document RTF + Dokument RTF + RTF-dokument + RTF-Dokument + RTF document + RTF-dokumento + documento RTF + RTF dokumentua + RTF-asiakirja + RTF skjal + document RTF + cáipéis RTF + documento RTF + מסמך RTF + RTF dokumentum + Dokumen RTF + Documento RTF + RTF ドキュメント + RTF құжаты + RTF 문서 + RTF dokumentas + RTF dokuments + RTF-dokument + RTF-document + TRF-dokument + Dokument RTF + Documento RTF + Document RTF + документ RTF + Dokument RTF + Dokument RTF + Dokument RTF + RTF-dokument + документ RTF + Tài liệu RTF + RTF 文档 + RTF 文件 + RTF + Rich Text Format + + + + + + + + + + Sieve mail filter script + سكربت مرشح بريد Sieve + Skrypt filtravańnia pošty Sieve + Скрипт-филтър за пресяване на поща + script de filtre de correu Sieve + Skript poštovního filtru Sieve + Sieve e-post-filterprogram + Sieve-E-Mail-Filterskript + script de filtro de correo Sieve + Sieve posta-iragazki script-a + Sieve-postinsuodatuskomentotiedosto + script de filtrage de courriel Sieve + script scagaire phost Sieve + Script de filtro de correo Sieve + תסריט סינון דואר של Sieve + Sieve levélszűrő parancsfájl + Skrip filter surat Sieve + Script filtro posta Sieve + Sieve メールフィルタスクリプト + Sieve пошталық фильтр сценарийі + Sieve 메일 필터 스크립트 + Sieve pašto filtro scenarijus + Sieve pasta filtra skripts + Sieve e-postfilter skript + Sieve mailfilter-script + Sieve e-postfilterskript + Skrypt filtra poczty Sieve + Script de filtro de mensagens do Sieve + Script filtrare email Sieve + сценарий почтового фильтра Sieve + Skript poštového filtra Sieve + Skriptna datoteka Sieve poštnega filtra + Script filtrim poste Sieve + Sieve-epostfilterskript + скрипт поштового фільтру Sieve + Văn lệnh lọc thư Sieve + Sieve 邮件过滤脚本 + Sieve 郵件過濾指令稿 + + + + + + SMIL document + مستند SMIL + Dakument SMIL + Документ — SMIL + document SMIL + Dokument SMIL + SMIL-dokument + SMIL-Dokument + SMIL document + SMIL-dokumento + documento SMIL + SMIL dokumentua + SMIL-asiakirja + SMIL skjal + document SMIL + cáipéis SMIL + documento SMIL + מסמך SMIL + SMIL dokumentum + Dokumen SMIL + Documento SMIL + SMIL ドキュメント + SMIL құжаты + SMIL 문서 + SMIL dokumentas + SMIL dokuments + SMIL-dokument + SMIL-document + SMIL-dokument + Dokument SMIL + Documento SMIL + Document SMIL + документ SMIL + Dokument SMIL + Dokument SMIL + Dokument SMIL + SMIL-dokument + документ SMIL + Tài liệu SMIL + SMIL 文档 + SMIL 文件 + SMIL + Synchronized Multimedia Integration Language + + + + + + + + + + + + + + + + WPL playlist + قائمة تشغيل WPL + Списък за изпълнение — WPL + llista de reproducció WPL + Seznam skladeb WPL + WPL-afspilningsliste + WPL-Wiedergabeliste + WPL-ludlisto + lista de reproducción WPL + WPL erreprodukzio-zerrenda + WPL-soittolista + WPL avspælingarlisti + liste de lecture WPL + seinmliosta WPL + lista de reprodución WPL + רשימת השמעה WPL + WPL-lejátszólista + Senarai putar WPL + Scaletta WPL + WPL 再生リスト + WPL ойнау тізімі + WPL 재생 목록 + WPL grojaraštis + WPL repertuārs + WPL-afspeellijst + Lista odtwarzania WPL + Lista de reprodução do WPL + Listă redare WPL + список воспроизведения WPL + Zoznam skladieb WPL + Seznam predvajanja WPL + WPL-spellista + список відтворення WPL + Danh mục nhạc WPL + WPL 播放列表 + WPL 播放清單 + WPL + Windows Media Player Playlist + + + + + + + + SQLite2 database + قاعدة بيانات SQLite2 + Baza źviestak SQLite2 + База от данни — SQLite2 + base de dades SQLite2 + Databáze SQLite2 + SQLite2-database + SQLite2-Datenbank + SQLite2 database + SQLite2-datumbazo + base de datos SQLite2 + SQLite2 datu-basea + SQLite2-tietokanta + SQLite2 dátustovnur + base de données SQLite2 + bunachar sonraí SQLite2 + base de datos SQLite2 + בסיס מידע של SQLite2 + SQLite2 adatbázis + Basis data SQLite2 + Database SQLite2 + SQLite2 データベース + SQLite2 дерекқоры + SQLite2 데이터베이스 + SQLite2 duomenų bazė + SQLite2 datubāze + SQLite2-database + SQLite2-gegevensbank + SQLite2-database + Baza danych SQLite2 + Banco de dados do SQLite2 + Bază de date SQLite2 + база данных SQLite2 + Databáza SQLite2 + Podatkovna zbirka SQLite2 + Bazë me të dhëna SQLite2 + SQLite2-databas + База даних SQLite2 + Cơ sở dữ liệu SQLite2 + SQLite2 数据库 + SQLite2 資料庫 + + + + + + SQLite3 database + قاعدة بيانات SQLite3 + Baza źviestak SQLite3 + База от данни — SQLite3 + base de dades SQLite3 + Databáze SQLite3 + SQLite3-database + SQLite3-Datenbank + SQLite3 database + SQLite3-datumbazo + base de datos SQLite3 + SQLite3 datu-basea + SQLite3-tietokanta + SQLite3 dátustovnur + base de données SQLite3 + bunachar sonraí SQLite3 + base de datos SQLite3 + בסיס מידע של SQLite3 + SQLite3 adatbázis + Basis data SQLite3 + Database SQLite3 + SQLite3 データベース + SQLite3 дерекқоры + SQLite3 데이터베이스 + SQLite3 duomenų bazė + SQLite3 datubāze + SQLite3-database + SQLite3-gegevensbank + SQLite3-database + Baza danych SQLite3 + Banco de dados do SQLite3 + Bază de date SQLite3 + база данных SQLite3 + Databáza SQLite3 + Podatkovna zbirka SQLite3 + Bazë me të dhëna SQLite3 + SQLite3-databas + база даних SQLite3 + Cơ sở dữ liệu SQLite3 + SQLite3 数据库 + SQLite3 資料庫 + + + + + + GEDCOM family history + تاريخ عائلة GEDCOM + Siamiejnaja historyja GEDCOM + Родословно дърво — GEDCOM + història familiar GEDCOM + Rodokmen GEDCOM + GEDCOM-familiehistorie + GEDCOM-Stammbaum + GEDCOM family history + historia familiar GEDCOM + GEDCOM famili historia + GEDCOM-sukuhistoria + GEDCOM familjusøga + généalogie GEDCOM + stair theaghlach GEDCOM + historial de familia GEDCOM + היסטוריה משפחתית של GEDCOM + GEDCOM családtörténet + Sejarah keluarga GEDCOM + Cronologia famiglia GEDCOM + GEDCOM 家系図データ + GEDCOM отбасы тарихы + GEDCOM family history + GEDCOM šeimos istorija + GEDCOM ģimenes vēsture + GEDCOM-familiehistorikk + GEDCOM-stamboom + GEDCOM-familehistorie + Plik historii rodziny GEDCOM + Histórico familiar do GEDCOM + Tablou genealogic GEDCOM + история семьи GEDCOM + Rodokmeň GEDCOM + Datoteka družinske zgodovine GEDCOM + Kronollogji familje GEDCOM + GEDCOM-släktträd + історія родини GEDCOM + Lịch sử gia đình GEDCOM + GEDCOM 家谱 + GEDCOM 家族史 + GEDCOM + GEnealogical Data COMmunication + + + + + + + + + + Flash video + Flash مرئي + Videa Flash + Видео — Flash + vídeo de Flash + Video Flash + Flashvideo + Flash-Video + Flash video + Flash-video + vídeo Flash + Flash bideoa + Flash-video + Flash video + vidéo Flash + físeán Flash + vídeo Flash + וידאו של פלאש + Flash videó + Video Flash + Video Flash + Flash 動画 + Flash видеосы + Flash 비디오 + Flash vaizdo įrašas + Flash video + Flash-film + Flash-video + Flash-video + Plik wideo Flash + Vídeo Flash + Video Flash + видео Flash + Video Flash + Video datoteka Flash + Video Flash + Flash-video + відеокліп Flash + Ảnh động Flash + Flash 影片 + Flash 視訊 + + + + + + + + + + + JavaFX video + Видео — JavaFX + vídeo JavaFX + Video JavaFX + JavaFX-video + JavaFX-Video + JavaFX-video + vídeo JavaFX + JavaFX-video + JavaFX video + vidéo JavaFX + físeán JavaFX + vídeo JavaFX + וידאו JavaFX + JavaFX videó + Video JavaFX + Video JavaFX + JavaFX 動画 + JavaFX аудиосы + 자바FX 비디오 + JavaFX video + Plik wideo JavaFX + Video JavaFX + видео JavaFX + Video JavaFX + Video JavaFX + JavaFX-video + відеокліп JavaFX + JavaFX 视频 + JavaFX 視訊 + + + + + + + + + + SGF record + تسجيلة SGF + Zapisanaja hulnia SGF + Запис — SGF + registre SGF + Záznam SGF + SGF-optagelse + SGF-Aufzeichnung + grabación SGF + SGF erregistroa + SGF-nauhoitus + SGF met + partie SGF + taifead SGF + Grabación SGF + הקלטת SGF + SGF pontszám + Catatan SGF + Registrazione SGF + SGF レコード + SGF жазбасы + SGF 기록파일 + SGF įrašas + SGF ieraksts + SGF-oppføring + SGF-record + SGF-logg + Zapis gry SGF + Gravação do SGF + Înregistrare SGF + запись SGF + Záznam SGF + Datoteka shranjene igre SGF + Regjistrim SGF + SGF-protokoll + запис SGF + Mục ghi SGF + SGF 记录 + SGF 紀錄 + SGF + Smart Game Format + + + + + + + + + + XLIFF translation file + ملف ترجمة XLIFF + Fajł pierakładu XLIFF + Превод — XLIFF + fitxer traducció XLIFF + Soubor překladu XLIFF + XLIFF-oversættelsesfil + XLIFF-Übersetzung + archivo de traducción XLIFF + XLIFF itzulpen-fitxategia + XLIFF-käännöstiedosto + XLIFF týðingarfíla + fichier de traduction XLIFF + comhad aistrithe XLIFF + ficheiro de tradución XLIFF + קובץ תרגום CLIFF + XLIFF fordítási fájl + Berkas terjemahan XLIFF + File traduzione XLIFF + XLIFF 翻訳ファイル + XLIFF аударма файлы + XLIFF 번역 파일 + XLIFF vertimo failas + XLIFF tulkošanas fails + XLIFF-oversettelsesfil + XLIFF-vertalingsbestand + XLIFF-omsetjingsfil + Plik tłumaczenia XLIFF + Arquivo de tradução XLIFF + Fișier de traducere XLIFF + файл перевода XLIFF + Súbor prekladu XLIFF + Datoteka prevoda XLIFF + File përkthimesh XLIFF + XLIFF-översättningsfil + файл перекладу XLIFF + Tập tin dịch XLIFF + XLIFF 消息翻译文件 + XLIFF 翻譯檔 + XLIFF + XML Localization Interchange File Format + + + + + + + + + + + YAML document + مستند YAML + Документ — YAML + document YAML + Dokument YAML + YAML-dokument + YAML-Dokument + YAML-dokumento + documento YAML + YAML-asiakirja + YAML skjal + document YAML + cáipéis YAML + documento YAML + מסמך YAML + YAML-dokumentum + Dokumen YAML + Documento YAML + YAML ドキュメント + YAML құжаты + YAML 문서 + YAML dokumentas + YAML dokuments + Dokument YAML + Document YAML + документ YAML + Dokument YAML + Dokument YAML + YAML-dokument + документ YAML + YAML 文档 + YAML 文件 + YAML + YAML Ain't Markup Language + + + + + + + + + + + + Corel Draw drawing + تصميم Corel Draw + Corel Draw çəkimi + Rysunak Corel Draw + Чертеж — Corel Draw + dibuix de Corel Draw + Kresba Corel Draw + Darlun Corel Draw + Corel Draw-tegning + Corel-Draw-Zeichnung + σχέδιο Corel Draw + Corel Draw drawing + grafikaĵo de Corel Draw + dibujo de Corel Draw + Corel Draw-eko marrazkia + Corel Draw -piirros + Corel Draw tekning + dessin Corel Draw + líníocht Corel Draw + debuxo de Corel Draw + ציור של Corel Draw + Corel Draw-rajz + Gambar Corel Draw + Disegno Corel Draw + Corel Draw ドロー + Corel Draw суреті + 코렐 드로우 드로잉 + Corel Draw piešinys + Corel Draw zīmējums + Lukisan Corel Draw + Corel Draw-tegning + Corel Draw-tekening + Corel Draw-teikning + Rysunek Corel Draw + desenho Corel Draw + Desenho do Corel Draw + Desen Corel Draw + изображение Corel Draw + Kresba Corel Draw + Datoteka risbe Corel Draw + Vizatim Corel Draw + Corel Draw цртеж + Corel Draw-teckning + малюнок Corel Draw + Bản vẽ Corel Draw + Corel Draw 图形 + Corel Draw 繪圖 + + + + + + + + + + + + + + + HPGL file + ملف HPGL + Fajł HPGL + Файл — HPGL + fitxer HPGL + Soubor HPGL + HPGL-fil + HPGL-Datei + HPGL file + HPGL-dosiero + archivo HPGL + HPGL fitxategia + HPGL-tiedosto + HPGL fíla + fichier HPGL + comhad HPGL + ficheiro HPGL + קובץ HGPL + HPGL fájl + Berkas HPGL + File HPGL + HPGL ファイル + HPGL файлы + HPGL 파일 + HPGL failas + HPGL fails + HPGL-fil + HPGL-bestand + HPGL-fil + Plik HPGL + Arquivo HPGL + Fișier HPGL + файл HPGL + Súbor HPGL + Datoteka HPGL + File HPGL + HPGL-fil + файл HPGL + Tập tin HPGL + HPGL 文件 + HPGL 檔案 + HPGL + HP Graphics Language + + + + + PCL file + ملف PCL + Fajł PCL + Файл — PCL + fitxer PCL + Soubor PCL + PCL-fil + PCL-Datei + PCL file + PCL-dosiero + archivo PCL + PCL fitxategia + PCL-tiedosto + PCL fíla + fichier PCL + comhad PCL + ficheiro PCL + קובץ PCL + PCL fájl + Berkas PCL + File PCL + PCL ファイル + PCL файлы + PCL 파일 + PCL failas + PCL fails + PCL-fil + PCL-bestand + PCL-fil + Plik PCL + Arquivo PCL + Fișier PCL + файл PCL + Súbor PCL + Datoteka PCL + File PCL + PCL-fil + файл PCL + Tập tin PCL + PCL 文件 + PCL 檔 + PCL + HP Printer Control Language + + + + + Lotus 1-2-3 spreadsheet + جدول Lotus 1-2-3 + Lotus 1-2-3 hesab cədvəli + Raźlikovy arkuš Lotus 1-2-3 + Таблица — Lotus 1-2-3 + full de càlcul de Lotus 1-2-3 + Sešit Lotus 1-2-3 + Taenlen Lotus 1-2-3 + Lotus 1-2-3-regneark + Lotus-1-2-3-Tabelle + λογιστικό φύλλο Lotus 1-2-3 + Lotus 1-2-3 spreadsheet + Kalkultabelo de Lotus 1-2-3 + hoja de cálculo de Lotus 1-2-3 + Lotus 1-2-3 kalkulu-orria + Lotus 1-2-3 -taulukko + Lotus 1-2-3 rokniark + feuille de calcul Lotus 1-2-3 + scarbhileog Lotus 1-2-3 + folla de cálculo de Lotus 1-2-3 + גליון נתונים של Lotus 1-2-3 + Lotus 1-2-3-munkafüzet + Lembar sebar Lotus 1-2-3 + Foglio di calcolo Lotus 1-2-3 + Lotus 1-2-3 スプレッドシート + Lotus 1-2-3 электрондық кестесі + Lotus 1-2-3 스프레드시트 + Lotus 1-2-3 skaičialentė + Lotus 1-2-3 izklājlapa + Hamparan Lotus 1-2-3 + Lotus 1-2-3 regneark + Lotus 1-2-3-rekenblad + Lotus 1-2-3 rekneark + Arkusz Lotus 1-2-3 + folha de cálculo Lotus 1-2-3 + Planilha do Lotus 1-2-3 + Foaie de calcul Lotus 1-2-3 + электронная таблица Lotus 1-2-3 + Zošit Lotus 1-2-3 + Razpredelnica Lotus 1-2-3 + Fletë llogaritjesh Lotus 1-2-3 + Lotus 1-2-3 табеларни прорачун + Lotus 1-2-3-kalkylblad + ел. таблиця Lotus 1-2-3 + Bảng tính Lotus 1-2-3 + Lotus 1-2-3 工作簿 + Lotus 1-2-3 試算表 + + + + + + + + + + + + + + + + JET database + قاعدة بيانات JET + Baza źviestak JET + База от данни — JET + base de dades JET + Databáze JET + JET-database + JET-Datenbank + JET database + JET-datumbazo + base de datos JET + JET datu-basea + JET-tietokanta + JET dátustovnur + base de données JET + bunachar sonraí JET + base de datos JET + מסד נתונים JET + JET adatbázis + Basis data JET + Database JET + JET データベース + JET дерекқоры + JET 데이터베이스 + JET duomenų bazė + JET datubāze + JET-database + JET-gegevensbank + JET-database + Baza Danych JET + Banco de dados JET + Bază de date JET + база данных JET + Databáza JET + Podatkovna zbirka JET + Bazë me të dhëna JET + JET-databas + База даних JET + Cơ sở dữ liệu JET + JET 数据库 + JET 資料庫 + JET + Joint Engine Technology + + + + + + + + + + + + + + Microsoft Cabinet archive + أرشيف Microsoft Cabinet + Архив — Microsoft Cabinet + arxiu Cabinet de Microsoft + Archiv Microsoft Cabinet + Microsoft Cabinet-arkiv + Microsoft-Cabinet-Archiv + archivador Microsoft Cabinet + Microsoft Cabinet artxiboa + Microsoft Cabinet -arkisto + Microsoft Cabinet skjalasavn + archive Cab Microsoft + cartlann Microsoft Cabinet + arquivo de Microsoft Cabinet + ארכיון CAB (מיקרוסופט) + Microsoft Cabinet archívum + Arsip Microsoft Cabinet + Archivio Microsoft Cabinet + Microsoft Cabinet アーカイブ + Microsoft Cabinet архиві + 마이크로소프트 캐비넛 묶음 + Microsoft Cabinet archyvas + Microsoft kabineta arhīvs + Microsoft Cabinet-archief + Archiwum Microsoft Cabinet + Pacote do Microsoft Cabinet + Arhivă Microsoft Cabinet + архив Microsoft Cabinet + Archív Microsoft Cabinet + Datoteka arhiva Microsoft Cabinet + Microsoft Cabinet-arkiv + архів Cabinet Microsoft + Kho lưu Cabinet Microsoft + Microsoft CAB 归档文件 + 微軟 Cabinet 封存檔 + + + + + + + + Excel spreadsheet + جدول Excel + Raźlikovy akruš Excel + Таблица — Excel + full de càlcul d'Excel + Sešit Excel + Excelregneark + Excel-Tabelle + Excel spreadsheet + Excel-kalkultabelo + hoja de cálculo de Excel + Excel kalkulu-orria + Excel-taulukko + Excel rokniark + feuille de calcul Excel + scarbhileog Excel + folla de cálculo de Excel + גליון נתונים של אקסל + Excel táblázat + Lembar sebar Excel + Foglio di calcolo Excel + Excel スプレッドシート + Excel электрондық кестесі + 엑셀 스프레드시트 + Excel skaičialentė + Excel izklājlapa + Excel regneark + Excel-rekenblad + Excel-rekneark + Arkusz Excel + Planilha do Excel + Foaie de calcul Excel + электронная таблица Excel + Zošit Excel + Razpredelnica Microsoft Excel + Fletë llogaritje Excel + Excel-kalkylblad + ел. таблиця Excel + Bảng tính Excel + Microsoft Excel 工作簿 + Excel 試算表 + + + + + + + + + + + + + + + + + Excel add-in + Приставка — Excel + complement d'Excel + Doplněk aplikace Excel + Excel Add-in + Complemento de Excel + complément Excel + complemento de Excel + תוסף של Excel + Excel bővítmény + Add-in Excel + Add-in Excel + Excel アドイン + Excel қосымшасы + 엑셀 추가 기능 + Excel pievienojumprogramma + Dodatek Excel + дополнение Excel + Vstavek Excel + додаток Excel + Excel 增益集 + + + + + + Excel 2007 binary spreadsheet + Таблица — Excel 2007, двоична + full de càlcul binari d'Excel 2007 + Binární formát sešitu Excel 2007 + Excel 2007-Tabelle (binär) + Hoja de cálculo de Excel 2007 + feuille de calcul binaire Excel 2007 + ficheiro binario de folla de cálculo Excel 2007 + גיליון נתונים בינרי של Excel 2007 + Excel 2007 bináris táblázat + Lembar kerja biner Excel 2007 + Foglio di calcolo binario Excel 2007 + Excel 2007 バイナリスプレッドシート + Excel 2007 бинарды кестесі + 엑셀 2007 바이너리 스프레드시트 + Excel 2007 binārā izklājlapa + Binarny arkusz Excel 2007 + двоичная электронная таблица Excel 2007 + Binarna preglednica Excel 2007 + бінарна електронна таблиця Excel 2007 + Excel 2007 二進位試算表 + + + + + + Excel macro-enabled spreadsheet + Таблица — Excel, с макроси + full de càlcul amb macros d'Excel + Sešit Excel s podporou maker + Excel-Tabelle mit aktivierten Makros + Hoja de cálculo con macros activados de Excel + feuille de calcul Excel avec macros + folla de cálculo de Excel con macros activadas + גיליון נתונים עם תכונות מקרו פעילות של Excel + Excel makrókat tartalmazó táblázat + Lembar kerja Excel dengan makro + Foglio di calcolo Excel con macro abilitate + Excel マクロ有効スプレッドシート + макростары іске қосылған Excel кестесі + 엑셀 매크로 사용 스프레드시트 + Excel izklājlapa ar makrosiem + Arkusz z włączonymi makrami Excel + электронная таблица Excel с включёнными макросами + Preglednica Excel z omogočenimi makri + електронна таблиця Excel з увімкненими макросами + Excel 巨集啟用試算表 + + + + + + Excel macro-enabled spreadsheet template + Шаблон за таблици — Excel, с макроси + plantilla de full de càlcul amb macros d'Excel + Šablona sešitu Excel s podporou maker + Excel-Tabellenvorlage mit aktivierten Makros + Plantilla de hoja de cálculo con macros activados de Excel + modèle de feuille de calcul Excel avec macros + modelo de folla de cálculo de Excel con macros activadas + תבנית של גיליון נתונים עם תכונות מקרו פעילות של Excel + Excel makrókat tartalmazó táblázatsablon + Templat lembar kerja Excel dengan makro + Modello foglio di calcolo Excel con macro abilitate + Excel マクロ有効スプレッドシートテンプレート + макростары іске қосылған Excel кестесінің үлгісі + 엑셀 매크로 사용 스프레드시트 서식 + Excel izklājlapas ar makrosiem veidne + Szablon arkusza z włączonymi makrami Excel + шаблон электронной таблицы Excel с включёнными макросами + Predloga preglednice Excel z omogočenimi makri + шаблон електронної таблиці Excel з увімкненими макросами + Excel 巨集啟用試算表範本 + + + + + + PowerPoint presentation + عرض تقديمي PowerPoint + Prezentacyja PowerPoint + Презентация — PowerPoint + presentació de PowerPoint + Prezentace PowerPoint + PowerPoint-præsentation + PowerPoint-Präsentation + PowerPoint presentation + PowerPoint-prezentaĵo + presentación de PowerPoint + PowerPoint aurkezpena + PowerPoint-esitys + PowerPoint framløga + présentation PowerPoint + láithreoireacht PowerPoint + presentación de PowerPoint + מצגת PowerPoint + PowerPoint prezentáció + Presentasi PowerPoint + Presentazione PowerPoint + PowerPoint プレゼンテーション + PowerPoint презентациясы + 파워포인트 프리젠테이션 + PowerPoint pateiktis + PowerPoint prezentācija + PowerPoint-presentasjon + PowerPoint-presentatie + PowerPoint-presentasjon + Prezentacja PowerPoint + Apresentação do PowerPoint + Prezentare PowerPoint + презентация PowerPoint + Prezentácia PowerPoint + Predstavitev Microsoft PowerPoint + Prezantim PowerPoint + PowerPoint-presentation + презентація PowerPoint + Trình diễn PowerPoint + Microsoft PowerPoint 演示文稿 + PowerPoint 簡報 + + + + + + + + + + + PowerPoint add-in + Приставка — PowerPoint + complement de + Doplněk PowerPoint + PowerPoint Add-in + Complemento de PowerPoint + complément PowerPoint + complemento de PowerPoint + תוסף של PowerPoint + PowerPoint bővítmény + Add-in PowerPoint + Add-in PowerPoint + PowerPoint アドイン + PowerPoint қосымшасы + 파워포인트 기능 추가 + PowerPoint pievienojumprogramma + Dodatek PowerPoint + дополнение PowerPoint + Vstavek PowerPoint + додаток PowerPoint + PowerPoint 增益集 + + + + + PowerPoint macro-enabled presentation + Презентация — PowerPoint, с макроси + presentació amb macros + Prezentace PowerPoint s podporou maker + PowerPoint-Präsentation mit aktivierten Makros + Presentación con macros activadas de PowerPoint + présentation PowerPoint avec macros + presentación con macros activadas de PowerPoint + מצגת של PowerPoint בעלת תכונות מקרו פעילות + PowerPoint makrókat tartalmazó bemutató + Presentasi PowerPoint dengan makro + Presentazione PowerPoint con macro abilitate + PowerPoint マクロ有効プレゼンテーション + макростары іске қосылған PowerPoint презентациясы + 파워포인트 매크로 사용 프리젠테이션 + PowerPoint prezentācija ar makrosiem + Prezentacja z włączonymi makrami PowerPoint + презентация PowerPoint с включёнными макросами + Predstavitev PowerPoint z omogočenimi makri + презентація PowerPoint з увімкненими макросами + PowerPoint 巨集啟用簡報 + + + + + + PowerPoint macro-enabled slide + Кадър — PowerPoint, с макроси + dispositiva amb macros + Snímek PowerPoint s podporou maker + PowerPoint-Folie mit aktivierten Makros + Diapositiva con macros activadas de PowerPoint + diapositive PowerPoint avec macros + Diapositiva con macros activadas de Powerpoint + שקופית של PowerPoint בעלת תכונות מקרו פעילות + PowerPoint makrókat tartalmazó dia + Slide PowerPoint dengan makro + Diapositiva PowerPoint con macro abilitate + PowerPoint マクロ有効スライド + макростары іске қосылған PowerPoint слайды + 파워포인트 매크로 사용 슬라이드 + PowerPoint slaids ar makrosiem + Slajd z włączonymi makrami PowerPoint + слайд PowerPoint с включёнными макросами + Prosojnica PowerPoint z omogočenimi makri + слайд PowerPoint з увімкненими макросами + PowerPoint 巨集啟用投影片 + + + + + + PowerPoint macro-enabled presentation + Презентация — PowerPoint, с макроси + presentació amb macros + Prezentace PowerPoint s podporou maker + PowerPoint-Präsentation mit aktivierten Makros + Presentación con macros activadas de PowerPoint + présentation PowerPoint avec macros + presentación con macros activadas de PowerPoint + מצגת של PowerPoint בעלת תכונות מקרו פעילות + PowerPoint makrókat tartalmazó bemutató + Presentasi PowerPoint dengan makro + Presentazione PowerPoint con macro abilitate + PowerPoint マクロ有効プレゼンテーション + макростары іске қосылған PowerPoint презентациясы + 파워포인트 매크로 사용 프리젠테이션 + PowerPoint prezentācija ar makrosiem + Prezentacja z włączonymi makrami PowerPoint + презентация PowerPoint с включёнными макросами + Predstavitev PowerPoint z omogočenimi makri + презентація PowerPoint з увімкненими макросами + PowerPoint 巨集啟用簡報 + + + + + + PowerPoint macro-enabled presentation template + Шаблон за презентации — PowerPoint, с макроси + plantilla de presentació amb macros + Šablona prezentace PowerPoint s podporou maker + PowerPoint-Präsentationsvorlage mit aktivierten Makros + Plantilla de presentación con macros activadas de PowerPoint + modèle de présentation PowerPoint avec macros + modelo de presentación con macros activadas de PowerPoint + תבנית של מצגת של PowerPoint בעלת תכונות מקרו פעילות + PowerPoint makrókat tartalmazó bemutatósablon + Templat presentasi PowerPoint dengan makro + Modello presentazione PowerPoint con macro abilitate + PowerPoint マクロ有効プレゼンテーションテンプレート + макростары іске қосылған PowerPoint презентациясының үлгісі + 파워포인트 매크로 사용 프리젠테이션 서식 + PowerPoint prezentācijas ar makrosiem veidne + Szablon prezentacji z włączonymi makrami PowerPoint + шаблон презентации PowerPoint с включёнными макросами + Predloga predstavitve PowerPoint z omogočenimi makri + шаблон презентації PowerPoint з увімкненими макросами + PowerPoint 巨集啟用簡報範本 + + + + + + Word macro-enabled document + Документ — Word, с макроси + document amb macros de Word + Dokument Word s podporou maker + Word-Dokument mit aktivierten Makros + Documento con macros activadas de Word + document Word avec macros + documento con macros activadas de Word + מסמך של Word בעל תכונות מקרו פעילות + Word makrókat tartalmazó dokumentum + Dokumen Word dengan makro + Documento Word con macro abilitate + Word マクロ有効文書 + макростары іске қосылған Word құжаты + 워드 매크로 사용 문서 + Word dokuments ar makrosiem + Dokument z włączonymi makrami Word + документ Word с включёнными макросами + Dokument Word z omogočenimi makri + документ Word з увімкненими макросами + Word 巨集啟用文件 + + + + + + Word macro-enabled document template + Шаблон за документи — Word, с макроси + plantilla de document amb macros de Word + Šablona dokumentu Word s podporou maker + Word-Dokumentvorlage mit aktivierten Makros + Plantilla de documento con macros activadas de Word + modèle de document Word avec macros + Plantilla de documento con macros activadas de Word + תבנית של מסמך של Word בעל תכונות מקרו פעילות + Word makrókat tartalmazó dokumentumsablon + Templat dokumen Word dengan makro + Modello documento Word con macro abilitate + Word マクロ有効文書テンプレート + макростары іске қосылған Word құжатының үлгісі + 워드 매크로 사용 문서 서식 + Word dokumenta ar makrosiem veidne + Szablon dokumentu z włączonymi makrami Word + шаблон документа Word с включёнными макросами + Predloga dokumenta Word z omogočenimi makri + шаблон документа Word з увімкненими макросами + Word 巨集啟用文件範本 + + + + + + XPS document + مستند XPS + Dakument XPS + Документ — XPS + document XPS + Dokument XPS + XPS-dokument + XPS-Dokument + XPS-dokumento + documento XPS + XPS dokumentua + XPS-asiakirja + XPS skjal + document XPS + cáipéis XPS + documento XPS + מסמך XPS + XPS dokumentum + Dokumen XPS + Documento XPS + XPS ドキュメント + XPS құжаты + XPS 문서 + XPS dokumentas + XPS dokuments + XPS-dokument + XPS-document + XPS-dokument + Dokument XPS + Documento XPS + Document XPS + документ XPS + Dokument XPS + Dokument XPS + Dokument XPS + XPS-dokument + документ XPS + Tài liệu XPS + XPS 文档 + XPS 文件 + XPS + Open XML Paper Specification + + + + + + + + Microsoft Works document + مستند Microsoft Works + Dakument Microsoft Works + Документ — Microsoft Works + document Works de Microsoft + Dokument Microsoft Works + Microsoft Works-dokument + Microsoft-Works-Dokument + documento de Microsoft Works + Microsoft Works dokumentua + Microsoft Works -asiakirja + Microsoft Works skjal + document Microsoft Works + cáipéis Microsoft Works + documento de Microsoft Works + מסמך Microsoft Works + Microsoft Works dokumentum + Dokumen Microsoft Works + Documento Microsoft Works + Microsoft Works ドキュメント + Microsoft Works құжаты + 마이크로소프트 웍스 문서 + Microsoft Works dokumentas + Microsoft Works dokuments + Microsoft Works-dokument + Microsoft Works-document + Microsoft Works-dokument + Dokument Microsoft Works + Documento do Microsoft Works + Document Microsoft Works + документ Microsoft Works + Dokument Microsoft Works + Dokument Microsoft Works + Dokument Microsoft Works + Microsoft Works-dokument + документ Microsoft Works + Tài liệu Microsoft Works + Microsoft Works 文档 + 微軟 Works 文件 + + + + + + + + + Microsoft Visio document + + + + + + + + + Word document + مستند Word + Dakument Word + Документ — Word + document de Word + Dokument Word + Worddokument + Word-Dokument + Word document + Word-dokumento + documento de Word + Word dokumentua + Word-asiakirja + Word skjal + document Word + cáipéis Word + documento de Word + מסמך Word + Word dokumentum + Dokumen Word + Documento Word + Word ドキュメント + Word құжаты + 워드 문서 + Word dokumentas + Word dokuments + Word-dokument + Word-document + Word-dokument + Dokument Word + Documento do Word + Document Word + документ Word + Dokument Word + Dokument Word + Dokument Word + Word-dokument + документ Word + Tài liệu Word + Microsoft Word 文档 + Word 文件 + + + + + + + + + + + + + + + + + + + Word template + قالب Word + Šablon Word + Шаблон за документи — Word + plantilla de Word + Šablona Word + Wordskabelon + Word-Vorlage + Word-ŝablono + plantilla de Word + Word txantiloia + Word-malli + Word formur + modèle Word + teimpléad Word + Plantilla de Word + תבנית Word + Word sablon + Templat Word + Modello Word + Word テンプレート + Word үлгісі + 워드 서식 + Word šablonas + Word veidne + Word-mal + Word-sjabloon + Word-mal + Szablon Word + Modelo do Word + Șablon Word + шаблон Word + Šablóna Word + Predloga dokumenta Microsoft Word + Model Word + Word-mall + шаблон Word + Mẫu Word + Word 模板 + Word 範本 + + + + + + GNUnet search file + ملف بحث GNUnet + fajł pošuku GNUnet + Указател за търсене — GNUnet + fitxer de cerca GNUnet + Vyhledávací soubor GNUnet + GNunet-søgefil + GNUnet-Suchdatei + archivo de búsqueda GNUnet + GNUnet bilaketako fitxategia + GNUnet-hakutiedosto + GNUnet leitifíla + fichier de recherche GNUnet + comhad cuardaigh GNUnet + ficheiro de busca de GNUnet + קובץ חיפוש של GNUnet + GNUnet keresési fájl + Berkas telusur GNUnet + File ricerca GNUnet + GNUnet 検索ファイル + GNUnet іздеу файлы + GNUnet 검색 파일 + GNUnet paieškos failas + GNUnet meklēšanas fails + GNUnet søkefil + GNUnet-zoekbestand + GNUnet-søkjefil + Plik wyszukiwania GNUnet + Arquivo de pesquisa do GNUnet + Fișier căutare GNUnet + файл поиска GNUnet + Vyhľadávací súbor GNUnet + Iskalna datoteka GNUnet + File kërkimi GNUnet + GNUnet-sökfil + файл пошуку GNUnet + Tập tin tìm kiếm GNUnet + GNUnet 搜索文件 + GNUnet 搜尋檔案 + + + + + + + TNEF message + رسالة TNEF + List TNEF + Съобщение — TNEF + missatge TNEF + Zpráva TNEF + TNEF-meddelelse + TNEF-Nachricht + mensaje TNEF + TNEF mezua + TNEF-viesti + TNEF boð + message TNEF + teachtaireacht TNEF + mensaxe TNEF + הודעת TNEF + TNEF üzenet + Pesan TNEF + Messaggio TNEF + TNEF メッセージ + TNEF мәлімдемесі + TNEF 메시지 + TNEF žinutė + TNEF ziņojums + TNEF-melding + TNEF-bericht + TNEF-melding + Wiadomość TNEF + Mensagem TNEF + Mesaj TNEF + сообщение TNEF + Správa TNEF + Datoteka sporočila TNEF + Mesazh TNEF + TNEF-meddelande + повідомлення TNEF + Thông điệp TNEF + TNEF 信件 + TNEF 訊息 + TNEF + Transport Neutral Encapsulation Format + + + + + + + + + + StarCalc spreadsheet + جدول StarCalc + StarCalc hesab cədvəli + Raźlikovy arkuš StarCalc + Таблица — StarCalc + full de càlcul de StarCalc + Sešit StarCalc + Taenlen StarCalc + StarCalc-regneark + StarCalc-Tabelle + λογιστικό φύλλο StarCalc + StarCalc spreadsheet + StarCalc-kalkultabelo + hoja de cálculo de StarCalc + StarCalc kalkulu-orria + StarCalc-taulukko + StarCalc rokniark + feuille de calcul StarCalc + scarbhileog StarCalc + folla de cálculo de StarCalc + גליון נתונים של StarCalc + StarCalc-munkafüzet + Lembar sebar StarCalc + Foglio di calcolo StarCalc + StarCalc スプレッドシート + StarCalc электрондық кестесі + StarCalc 스프레드시트 + StarCalc skaičialentė + StarCalc izklājlapa + Hamparan StarCalc + StarCalc-regneark + StarCalc-rekenblad + StarCalc-rekneark + Arkusz StarCalc + folha de cálculo do StarCalc + Planilha do StarCalc + Foaie de calcul StarCalc + электронная таблица StarCalc + Zošit StarCalc + Razpredelnica StarCalc + Fletë llogaritjesh StarCalc + StarCalc табеларни прорачун + StarCalc-kalkylblad + ел. таблиця StarCalc + Bảng tính StarCalc + STarCalc 工作簿 + StarCalc 試算表 + + + + + StarChart chart + مخطط StarChart + StarChart cədvəli + Dyjahrama StarChart + Диаграма — StarChart + diagrama de StarChart + Graf StarChart + Siart StarChart + StarChart-diagram + StarChart-Diagramm + γράφημα StarChart + StarChart chart + StarChart-diagramo + gráfica de StarChart + StarChart diagrama + StarChart-kaavio + StarChart strikumynd + graphique StarChart + cairt StarChart + gráfica de StarChart + טבלה של StarChart + StarChart-grafikon + Bagan StarChart + Grafico StarChart + StarChart チャート + StarChart диаграммасы + StarCalc 표 + StarChart diagrama + StarChart diagramma + Carta StarChart + StarChart graf + StarChart-kaart + StarChart-graf + Wykres StarChart + gráfico do StarChart + Gráfico StarChart + Diagramă StarChart + диаграмма StarChart + Graf StarChart + Datoteka grafikona StarChart + Grafik StarChart + StarChart графикон + StarChart-diagram + діаграма StarChart + Đồ thị StarChart + STarChart 图表 + StarChart 圖表 + + + + + StarDraw drawing + تصميم StarDraw + StarDraw çəkimi + Rysunak StarDraw + Чертеж — StarDraw + dibuix de StarDraw + Kresba StarDraw + Darlun StarDraw + StarDraw-tegning + StarDraw-Zeichnung + σχέδιο StarDraw + StarDraw drawing + StarDraw-grafikaĵo + dibujo de StarDraw + StarDraw marrazkia + StarDraw-piirros + StarDraw tekning + dessin StarDraw + líníocht StarDraw + debuxo de StarDraw + ציור של StarDrawing + StarDraw-rajz + Gambar StarDraw + Disegno StarDraw + StarDraw ドロー + StarDraw суреті + StarCalc 드로잉 + StarDraw piešinys + StarDraw zīmējums + Lukisan StarDraw + StarDraw tegning + StarDraw-tekening + StarDraw-teikning + Rysunek StarDraw + desenho do StarDraw + Desenho do StarDraw + Desen StarDraw + изображение StarDraw + Kresba StarDraw + Datoteka risbe StarDraw + Vizatim StarDraw + StarDraw drawing + StarDraw-teckning + малюнок StarDraw + Bản vẽ StarDraw + STarDraw 绘图 + StarDraw 繪圖 + + + + + StarImpress presentation + عرض تقديمي StarImpress + StarImpress təqdimatı + Prezentacyja StarImpress + Презентация — StarImpress + presentació de StarImpress + Prezentace StarImpress + Cyflwyniad StarImpress + StarImpress-præsentation + StarImpress-Präsentation + παρουσίαση StarImpress + StarImpress presentation + StarImpress-prezentaĵo + presentación de StarImpress + StarImpress aurkezpena + StarImpress-esitys + StarImpress framløga + présentation StarImpress + láithreoireacht StarImpress + presentación de StarImpress + מצגת של StarImpress + StarImpress-bemutató + Presentasi StarImpress + Presentazione StarImpress + StarImpress プレゼンテーション + StarImpress презентациясы + StarImpress 프리젠테이션 + StarImpress pateiktis + StarImpress prezentācija + Persembahan StarImpress + StarImpress-presentasjon + StarImpress-presentatie + StarImpress-presentasjon + Prezentacja StarImpress + apresentação do StarImpress + Apresentação do StarImpress + Prezentare StarImpress + презентация StarImpress + Prezentácia StarImpress + Predstavitev StarImpress + Prezantim StarImpress + StarImpress презентација + StarImpress-presentation + презентація StarImpress + Trình diễn StarImpress + STarImpress 演示文稿 + StarImpress 簡報檔 + + + + + + StarMail email + بريد StarMail الإلكتروني + Email StarMail + Електронно писмо — StarMail + correu electrònic de StarMail + E-mail StarMail + StarMail-e-brev + StarMail-E-Mail + ηλ. μήνυμα StarMail + StarMail email + StarMail-retpoŝto + correo electrónico de StarMail + StarMail helb.el. + StarMail-sähköposti + StarMail t-postur + courriel StarMail + ríomhphost StarMail + Correo electrónico de StarMail + דוא"ל של StarMail + StarMail e-mail + Email StarMail + Email StarMail + StarMail メール + StarMail электрондық хаты + StarMail 전자우편 + StarMail el. laiškas + StarMail epasts + Emel StarMail + StarMail-melding + StarMail-e-mail + StarMail-fil + E-Mail StarMail + e-mail do StarMail + E-mail do StarMail + Email StarEmail + электронное письмо StarMail + E-mail StarMail + Datoteka pošte StarMail + Mesazh StarMail + StarMail пошта + StarMail-e-post + поштове повідомлення StarMail + Thư điện tử StarMail + STarMail 电子邮件 + StarMail 郵件 + + + + StarMath formula + صيغة StarMath + Formuła StarMath + Формула — StarMath + fórmula de StarMath + Vzorec StarMath + StarMath-formel + StarMath-Formel + μαθηματικός τύπος StarMath + StarMath formula + StarMath-formulo + fórmula de StarMath + StarMath formula + StarMath-kaava + StarMath frymil + formule StarMath + foirmle StarMath + fórmula de StarMath + נוסחה של StarMath + StarMath-képlet + Formula StarMath + Formula StarMath + StarMath 計算式 + StarMath формуласы + StarMath 수식 + StarMath formulė + StarMath formula + Formula StarMath + StarMath-formel + StarMath-formule + StarMath-formel + Formuła StarMath + fórmula do StarMath + Fórmula do StarMath + Formulă StarMath + формула StarMath + Vzorec StarMath + Datoteka formule StarMath + Formulë StarMath + StarMath формула + StarMath-formel + формула StarMath + Công thức StarMath + STarMath 公式 + StarMath 公式 + + + + + StarWriter document + مستند StarWriter + StarWriter sənədi + Dakument StarWriter + Документ — StarWriter + document de StarWriter + Dokument StarWriter + Dogfen StarWriter + StarWriter-dokument + StarWriter-Dokument + έγγραφο StarWriter + StarWriter document + StarWriter-dokumento + documento de StarWriter + StarWriter dokumentua + StarWriter-asiakirja + StarWriter skjal + document StarWriter + cáipéis StarWriter + documento de StarWriter + מסמך של StarWriter + StarWriter-dokumentum + Dokumen StarWriter + Documento StrarWriter + StarWriter ドキュメント + StarWriter құжаты + StarWriter 문서 + StarWriter dokumentas + StarWriter dokuments + Dokumen StarWriter + StarWriter-dokument + StarWriter-document + StarWriter document + Dokument StarWriter + documento do StarWriter + Documento do StarWriter + Document StarWriter + документ StarWriter + Dokument StarWriter + Dokument StarWriter + Dokument StarWriter + StarWriter документ + StarWriter-dokument + документ StarWriter + Tài liệu StarWriter + STarWriter 文档 + StarWriter 文件 + + + + + + + + + + OpenOffice Calc spreadsheet + جدول Calc المكتب المفتوح + Raźlikovy arkuš OpenOffice Calc + Таблица — OpenOffice Calc + full de càlcul d'OpenOffice Calc + Sešit OpenOffice Calc + OpenOffice Calc-regneark + OpenOffice-Calc-Tabelle + hoja de cálculo de OpenOffice Calc + OpenOffice.org Calc kalkulu-orria + OpenOffice Calc -taulukko + OpenOffice Calc rokniark + feuille de calcul OpenOffice Calc + scarbhileog OpenOffice Calc + folla de cálculo de OpenOffice Calc + גליון נתונים של OpenOffice Calc + OpenOffice Calc táblázat + Lembar sebar OpenOffice Calc + Foglio di calcolo OpenOffice Calc + OpenOffice Calc スプレッドシート + OpenOffice Calc электрондық кестесі + OpenOffice Calc 스프레드시트 + OpenOffice Calc skaičialentė + OpenOffice Calc izklājlapa + OpenOffice Calc-regneark + OpenOffice.org Calc-rekenblad + OpenOffice Calc-rekneark + Arkusz kalkulacyjny OpenOffice.org Calc + Planilha do OpenOffice Calc + Foaie de calcul OpenOffice Calc + электронная таблица OpenOffice Calc + Zošit OpenOffice Calc + Razpredelnica OpenOffice.org Calc + Fletë llogaritjesh OpenOffice Calc + OpenOffice Calc-kalkylblad + ел. таблиця OpenOffice Calc + Bảng tính Calc của OpenOffice.org + OpenOffice.org Calc 工作簿 + OpenOffice Calc 試算表 + + + + + + + + + + + + + OpenOffice Calc template + قالب Calc المكتب المفتوح + Šablon OpenOffice Calc + Шаблон за таблици — OpenOffice Calc + plantilla d'OpenOffice Calc + Šablona OpenOffice Calc + OpenOffice Calc-skabelon + OpenOffice-Calc-Vorlage + OpenOffice Calc template + plantilla de OpenOffice Calc + OpenOffice Calc txantiloia + OpenOffice Calc -malli + OpenOffice Calc formur + modèle OpenOffice Calc + teimpléad OpenOffice Calc + modelo de OpenOffice Calc + תבנית של OpenOffice Calc + OpenOffice Calc sablon + Templat OpenOffice Calc + Modello OpenOffice Calc + OpenOffice Calc テンプレート + OpenOffice Calc үлгісі + OpenOffice Calc 스프레드시트 문서 서식 + OpenOffice Calc šablonas + OpenOffice Calc veidne + OpenOffice Calc-mal + OpenOffice.org Calc-sjabloon + OpenOffice Calc-mal + Szablon arkusza OpenOffice.org Calc + Modelo do OpenOffice Calc + Șablon OpenOffice Calc + шаблон OpenOffice Calc + Šablóna OpenOffice Calc + Predloga OpenOffice.org Calc + Model OpenOffice Calc + OpenOffice Calc-mall + шаблон ел.таблиці OpenOffice Calc + Mẫu bảng tính Calc của OpenOffice.org + OpenOffice.org Calc 工作簿模板 + OpenOffice Calc 範本 + + + + + + + + + + + + + OpenOffice Draw drawing + تصميم Draw المكتب المفتوح + Rysunak OpenOffice Draw + Чертеж — OpenOffice Draw + dibuix d'OpenOffice Draw + Kresba OpenOffice Draw + OpenOffice Draw-tegning + OpenOffice-Draw-Zeichnung + dibujo de OpenOffice Draw + OpenOffice.org Draw marrazkia + OpenOffice Draw -piirros + OpenOffice Draw tekning + dessin OpenOffice Draw + líníocht OpenOffice Draw + debuxo de OpenOffice Draw + ציור של OpenOffice Draw + OpenOffice Draw rajz + Gambar OpenOffice Draw + Disegno OpenOffice Draw + OpenOffice Draw ドロー + OpenOffice Draw суреті + OpenOffice Draw 그림 + OpenOffice Draw piešinys + OpenOffice Draw zīmējums + OpenOffice Draw-tegning + OpenOffice.org Draw-tekening + OpenOffice Draw-teikning + Rysunek OpenOffice.org Draw + Desenho do OpenOffice Draw + Desen OpenOffice Draw + изображение OpenOffice Draw + Kresba OpenOffice Draw + Datoteka risbe OpenOffice.org Draw + Vizatim OpenOffice Draw + OpenOffice Draw-teckning + малюнок OpenOffice Draw + Bản vẽ Draw của OpenOffice.org + OpenOffice.org Draw 绘图 + OpenOffice Draw 繪圖 + + + + + + + + + + + + + OpenOffice Draw template + قالب Draw المكتب المفتوح + Šablon OpenOffice Draw + Шаблон за чертежи — OpenOffice Draw + plantilla d'OpenOffice Draw + Šablona OpenOffice Draw + OpenOffice Draw-skabelon + OpenOffice-Draw-Vorlage + OpenOffice Draw template + plantilla de OpenOffice.org Draw + OpenOffice Draw txantiloia + OpenOffice Draw -malli + OpenOffice Draw formur + modèle OpenOffice Draw + teimpléad OpenOffice Draw + modelo de OpenOffice Draw + תבנית של OpenOffice Draw + OpenOffice Draw sablon + Templat OpenOffice Draw + Modello OpenOffice Draw + OpenOffice Draw テンプレート + OpenOffice Draw үлгісі + OpenOffice Draw 그림 문서 서식 + OpenOffice Draw šablonas + OpenOffice Draw veidne + OpenOffice Draw-mal + OpenOffice.org Draw-sjabloon + OpenOffice Draw-mal + Szablon rysunku OpenOffice.org Draw + Modelo do OpenOffice Draw + Șablon OpenOffice Draw + шаблон OpenOffice Draw + Šablóna OpenOffice Draw + Predloga OpenOffice.org Draw + Model OpenOffice Draw + OpenOffice Draw-mall + шаблон малюнку OpenOffice Draw + Mẫu bản vẽ Draw của OpenOffice.org + OpenOffice.org Draw 绘图模板 + OpenOffice Draw 範本 + + + + + + + + + + + + + OpenOffice Impress presentation + عرض تقديمي Impress المكتب المفتوح + OpenOffice Impress sənədi + Prezentacyja OpenOffice Impress + Презентация — OpenOffice Impress + presentació d'OpenOffice Impress + Prezentace OpenOffice Impress + Cyflwyniad OpenOffice (Impress) + OpenOffice Impress-præsentation + OpenOffice-Impress-Vorlage + presentación de OpenOffice Impress + OpenOffice.org Impress aurkezpena + OpenOffice Impress -esitys + OpenOffice Impress framløga + présentation OpenOffice Impress + láithreoireacht OpenOffice Impress + presentación de de OpenOffice Impress + מצגת של OpenOffice Impress + OpenOffice Impress bemutató + Presentasi OpenOffice Impress + Presentazione OpenOffice Impress + OpenOffice Impress プレゼンテーション + OpenOffice Impress презентациясы + OpenOffice Impress 프리젠테이션 + OpenOffice Impress pateiktis + OpenOffice Impress prezentācija + OpenOffice Impress-presentasjon + OpenOffice.org Impress-presentatie + OpenOffice Impress-presentasjon + Prezentacja OpenOffice.org Impress + Apresentação do OpenOffice Impress + Prezentare OpenOffice Impress + презентация OpenOffice Impress + Prezentácia OpenOffice Impress + Predstavitev OpenOffice.org Impress + Prezantim OpenOffice Impress + OpenOffice Impress-presentation + презентація OpenOffice Impress + Trình diễn Impress của OpenOffice.org + OpenOffice.org Impress 演示文稿 + OpenOffice Impress 簡報 + + + + + + + + + + + + + OpenOffice Impress template + قالب Impress المكتب المفتوح + Šablon OpenOffice Impress + Шаблон за презентации — OpenOffice Impress + plantilla d'OpenOffice Impress + Šablona OpenOffice Impress + OpenOffice Impress-skabelon + OpenOffice-Impress-Vorlage + OpenOffice Impress template + plantilla de OpenOffice Impress + OpenOffice Impress txantiloia + OpenOffice Impress -malli + OpenOffice Impress formur + modèle OpenOffice Impress + teimpléad OpenOffice Impress + modelo de OpenOffice Impress + תבנית של OpenOffice Impress + OpenOffice Impress sablon + Templat OpenOffice Impress + Modello OpenOffice Impress + OpenOffice Impress テンプレート + OpenOffice Impress үлгісі + OpenOffice Impress 프리젠테이션 문서 서식 + OpenOffice Impress šablonas + OpenOffice Impress veidne + OpenOffice Impress-mal + OpenOffice.org Impress-sjabloon + OpenOffice Impress-mal + Szablon prezentacji OpenOffice.org Impress + Modelo do OpenOffice Impress + Șablon OpenOffice Impress + шаблон OpenOffice Impress + Šablóna OpenOffice Impress + Predloga OpenOffice.org Impress + Model OpenOffice Impress + OpenOffice Impress-mall + шаблон презентації OpenOffice Impress + Mẫu trình diễn Impress của OpenOffice.org + OpenOffice.org Impress 演示文稿模板 + OpenOffice Impress 範本 + + + + + + + + + + + + + OpenOffice Math formula + صيغة Math المكتب المفتوح + Formuła OpenOffice Math + Формула — OpenOffice Math + fórmula d'OpenOffice Math + Vzorec OpenOffice Math + OpenOffice Math-formel + OpenOffice-Math-Formel + fórmula de OpenOffice Math + OpenOffice.org Math formula + OpenOffice Math -kaava + OpenOffice Math frymil + formule OpenOffice Math + foirmle OpenOffice Math + fórmula de OpenOffice Math + נוסחה של OpenOffice Math + OpenOffice Math képlet + Formula OpenOffice Math + Formula OpenOffice Math + OpenOffice Math 計算式 + OpenOffice Math формуласы + OpenOffice Math 수식 + OpenOffice Math formulė + OpenOffice Math formula + OpenOffice Math-formel + OpenOffice.org Math-formule + OpenOffice Math-formel + Formuła OpenOffice.org Math + Fórmula do OpenOffice Math + Formulă OpenOffice Math + формула OpenOffice Math + Vzorec OpenOffice Math + Dokument formule OpenOffice.org Math + Formulë OpenOffice Math + OpenOffice Math-formel + формула OpenOffice Math + Công thức Math của OpenOffice.org + OpenOffice.org Math 公式 + OpenOffice Math 公式 + + + + + + + + + + + + + OpenOffice Writer document + مستند Writer المكتب المفتوح + OpenOffice Writer sənədi + Dakument OpenOffice Writer + Документ — OpenOffice Writer + document d'OpenOffice Writer + Dokument OpenOffice Writer + Dogfen OpenOffice (Writer) + OpenOffice Writer-dokument + OpenOffice-Writer-Dokument + documento de OpenOffice Writer + OpenOffice.org Writer dokumentua + OpenOffice Writer -asiakirja + OpenOffice Writer skjal + document OpenOffice Writer + cáipéis OpenOffice Writer + documento de OpenOffice Writer + מסמך של OpenOffice Writer + OpenOffice Writer dokumentum + Dokumen OpenOffice Writer + Documento OpenOffice Writer + OpenOffice Writer ドキュメント + OpenOffice Writer құжаты + OpenOffice Writer 문서 + OpenOffice Writer dokumentas + OpenOffice Writer dokuments + OpenOffice Writer-dokument + OpenOffice.org Writer-document + OpenOffice Writer-dokument + Dokument OpenOffice.org Writer + Documento do OpenOffice Writer + Document OpenOffice Writer + документ OpenOffice Writer + Dokument OpenOffice Writer + Dokument OpenOffice.org Writer + Dokument OpenOffice Writer + OpenOffice Writer-dokument + документ OpenOffice Writer + Tài liệu Writer của OpenOffice.org + OpenOffice.org Writer 文档 + OpenOffice Writer 文件 + + + + + + + + + + + + + OpenOffice Writer global document + مستند المكتب المفتوح Writer العالمي + OpenOffice Writer qlobal sənədi + Hlabalny dakument OpenOffice Writer + Документ - глобален — OpenOffice Writer + document global d'OpenOffice Writer + Globální dokument OpenOffice Writer + Dogfen eang OpenOffice (Writer) + OpenOffice Writer-globalt dokument + OpenOffice-Writer-Globaldokument + documento global de OpenOffice Writer + OpenOffice.org Writer dokumentu globala + OpenOffice Writer - yleinen asiakirja + OpenOffice Writer heiltøkt skjal + document global OpenOffice Writer + cáipéis chomhchoiteann OpenOffice Writer + documento global de OpenOffice Writer + מסמך גלובלי של OpenOffice Writer + OpenOffice Writer globális dokumentum + Dokumen global OpenOffice Writer + Documento globale OpenOffice Writer + OpenOffice Writer グローバルドキュメント + OpenOffice Writer негізгі құжаты + OpenOffice Writer 글로벌 문서 + OpenOffice Writer bendrinis dokumentas + OpenOffice Writer globālais dokuments + Global OpenOffice Writer globalt dokument + OpenOffice.org Writer-globaal-document + OpenOffice Writer globalt dokument + Globalny dokument OpenOffice.org Writer + Documento global do OpenOffice Writer + Document global OpenOffice Writer + основной документ OpenOffice Writer + Globálny dokument OpenOffice Writer + Splošni dokument OpenOffice.org Writer + Dokument i përgjithshëm OpenOffice Writer + OpenOffice Writer-globaldokument + загальний документ OpenOffice Writer + Tài liệu toàn cục Writer của OpenOffice.org + OpenOffice.org Writer 全局文档 + OpenOffice Writer 主控文件 + + + + + + + + + + + + + OpenOffice Writer template + قالب Writer المكتب المفتوح + OpenOffice Writer şablonu + Šablon OpenOffice Writer + Шаблон за документи — OpenOffice Writer + plantilla d'OpenOffice Writer + Šablona OpenOffice Writer + Templed OpenOffice (Writer) + OpenOffice Writer-skabelon + OpenOffice-Writer-Vorlage + OpenOffice Writer template + plantilla de OpenOffice Writer + OpenOffice Writer txantiloia + OpenOffice Writer -malli + OpenOffice Writer formur + modèle OpenOffice Writer + teimpléad OpenOffice Writer + modelo de OpenOffice Writer + תסנית של OpenOffice Writer + OpenOffice Writer sablon + Templat OpenOffice Writer + Modello OpenOffice Writer + OpenOffice Writer ドキュメントテンプレート + OpenOffice Writer үлгісі + OpenOffice Writer 문서 서식 + OpenOffice Writer šablonas + OpenOffice Writer veidne + Templat OpenOffice Writer + OpenOffice Writer-mal + OpenOffice.org Writer-sjabloon + OpenOffice Writer-mal + Szablon dokumentu OpenOffice.org Writer + Modelo do OpenOffice Writer + Șablon OpenOffice Writer + шаблон OpenOffice Writer + Šablóna OpenOffice Writer + Predloga OpenOffice.org Writer + Model OpenOffice Writer + OpenOffice Writer-mall + шаблон документа OpenOffice Writer + Mẫu tài liệu Writer của OpenOffice.org + OpenOffice.org Writer 文档模板 + OpenOffice Writer 範本 + + + + + + + + + + + + + ODT document + مستند ODT + Dakument ODT + Документ — ODT + document ODT + Dokument ODT + ODT-dokument + ODT-Dokument + ODT document + ODT-dokumento + documento ODT + ODT dokumentua + ODT-asiakirja + ODT skjal + document ODT + cáipéis ODT + documento ODT + מסמך ODT + ODT-dokumentum + Dokumen ODT + Documento ODT + ODT ドキュメント + ODT құжаты + ODT 문서 + ODT dokumentas + ODT dokuments + ODT-dokument + ODT-document + ODT-dokument + Dokument ODT + Documento ODT + Document ODT + документ ODT + Dokument ODT + Dokument ODT + Dokument ODT + ODT-dokument + документ ODT + Tài liệu ODT + ODT 文档 + ODT 文件 + ODT + OpenDocument Text + + + + + + + + + + + + + ODT document (Flat XML) + مستند ODT (Flat XML) + Документ — ODT (само XML) + document ODT (XML pla) + Dokument ODT (Flat XML) + ODT-dokument (flad XML) + ODT-Dokument (Unkomprimiertes XML) + documento ODT (XML plano) + ODT dokumentua (XML soila) + ODT skjal (Flat XML) + document ODT (XML plat) + cáipéis ODT (XML cothrom) + documento ODT (XML plano) + מסמך ODT‏ (Flat XML) + ODT-dokumentum (egyszerű XML) + Dokumen ODT (Flat XML) + Documento ODT (XML semplice) + ODT ドキュメント (Flat XML) + ODT құжаты (Тек XML) + ODT 문서 (단일 XML) + ODT dokumentas (Flat XML) + ODT dokuments (plakans XML) + Dokument ODT (prosty XML) + Document ODT (XML simplu) + документ ODT (простой XML) + Dokument ODT (čisté XML) + Datoteka dokumenta ODT (nepovezan XML) + ODT-dokument (platt XML) + документ ODT (Flat XML) + ODT 文档(Flat XML) + ODT 文件 (Flat XML) + FODT + OpenDocument Text (Flat XML) + + + + + + ODT template + قالب ODT + Šablon ODT + Шаблон за документи — ODT + plantilla ODT + Šablona ODT + ODT-skabelon + ODT-Vorlage + ODT template + ODT-ŝablono + plantilla ODT + ODT txantiloia + ODT-malli + ODT formur + modèle ODT + teimpléad ODT + modelo ODT + תבנית ODT + ODT-sablon + Templat ODT + Modello ODT + ODT テンプレート + ODT үлгісі + ODT 문서 서식 + ODT šablonas + ODT veidne + ODT-mal + ODT-sjabloon + ODT-mal + Szablon ODT + Modelo ODT + Șablon ODT + шаблон ODT + Šablóna ODT + Predloga dokumenta ODT + Model ODT + ODT-mall + шаблон ODT + Mẫu ODT + ODT 模板 + ODT 範本 + ODT + OpenDocument Text + + + + + + + + + + + + + OTH template + قالب OTH + Šablon OTH + Шаблон за страници — OTH + plantilla OTH + Šablona OTH + OTH-skabelon + OTH-Vorlage + OTH template + OTH-ŝablono + plantilla OTH + OTH txantiloia + OTH-malli + OTH formur + modèle OTH + teimpléad OTH + modelo OTH + תבנית OTH + OTH-sablon + Templat OTH + Modello OTH + OTH テンプレート + OTH үлгісі + OTH 문서 서식 + OTH šablonas + OTH veidne + OTH-mal + OTH-sjabloon + OTH-mal + Szablon OTH + Modelo OTH + Șablon OTH + шаблон OTH + Šablóna OTH + Predloga OTH + Model OTH + OTH-mall + шаблон OTH + Mẫu ODH + OTH 模板 + OTH 範本 + OTH + OpenDocument HTML + + + + + + + + + + + + + ODM document + مستند ODM + Dakument ODM + Документ — ODM + document ODM + Dokument ODM + ODM-dokument + ODM-Dokument + ODM document + ODM-dokumento + documento ODM + ODM dokumentua + ODM-asiakirja + ODM skjal + document ODM + cáipéis ODM + documento ODM + מסמך ODM + ODM-dokumentum + Dokumen ODM + Documento ODM + ODM ドキュメント + ODM құжаты + ODM 문서 + ODM dokumentas + ODM dokuments + ODM-dokument + ODM-document + ODM-dokument + Dokument ODM + Documento ODM + Document ODM + документ ODM + Dokument ODM + Dokument ODM + Dokument ODM + ODM-dokument + документ ODM + Tài liệu ODM + ODM 文档 + ODM 文件 + ODM + OpenDocument Master + + + + + + + + + + + + + ODG drawing + تصميم ODG + Rysunak ODG + Чертеж — ODG + dibuix ODG + Kresba ODG + ODG-tegning + ODG-Zeichnung + ODG drawing + ODG-desegnaĵo + dibujo ODG + ODG marrazkia + ODG-piirros + ODG tekning + dessin ODG + líníocht ODG + debuxo ODG + ציור ODG + ODG-rajz + Gambar ODG + Disegno ODG + ODG ドロー + ODG суреті + ODG 드로잉 + ODG piešinys + ODG zīmējums + ODG-tegning + ODG-tekening + ODG-teikning + Rysunek ODG + Desenho ODG + Desen ODG + изображение ODG + Kresba ODG + Datoteka risbe ODG + Vizatim ODG + ODG-teckning + малюнок ODG + Bản vẽ ODG + ODG 绘图 + ODG 繪圖 + ODG + OpenDocument Drawing + + + + + + + + + + + + + ODG drawing (Flat XML) + رسمة ODG (Flat XML) + Чертеж — ODG (само XML) + dibuix ODG (XML pla) + Kresba ODG (Flat XML) + ODG-tegning (flad XML) + ODG-Zeichnung (Unkomprimiertes XML) + dibujo ODG (XML plano) + ODG marrazkia (XML soila) + ODG tekning (Flat XML) + dessin ODG (XML plat) + líníocht ODG (XML cothrom) + debuxo ODB (XML plano) + ציור ODG (Flat XML( + ODG-rajz (egyszerű XML) + Gambar ODG (FLAT XML) + Disegno ODG (XML semplice) + ODG ドロー (Flat XML) + ODG сызбасы (Тек XML) + ODG 드로잉 (단일 XML) + ODG piešinys (Flat XML) + ODG zīmējums (plakans XML) + Rysunek ODG (prosty XML) + Desen ODG (XML simplu) + изображение ODG (простой XML) + Kresba ODG (čisté XML) + Datoteka risbe ODG (nepovezan XML) + ODG-teckning (platt XML) + малюнок ODG (Flat XML) + ODG 绘图(Flat XML) + ODG 繪圖 (Flat XML) + FODG + OpenDocument Drawing (Flat XML) + + + + + + ODG template + قالب ODG + Šablon ODG + Шаблон за чертежи — ODG + plantilla ODG + Šablona ODG + ODG-skabelon + ODG-Vorlage + ODG template + ODG-ŝablono + plantilla ODG + ODG txantiloia + ODG-malli + ODG formur + modèle ODG + teimpléad ODG + modelo ODG + תבנית ODG + ODG-sablon + Templat ODG + Modello ODG + ODG テンプレート + ODG үлгісі + ODG 문서 서식 + ODG šablonas + ODG veidne + ODG-mal + ODG-sjabloon + ODG-mal + Szablon ODG + Modelo ODG + Șablon ODG + шаблон ODG + Šablóna ODG + Predloga dokumenta ODG + Model ODG + ODG-mall + шаблон ODG + Mẫu ODG + ODG 模板 + ODG 範本 + ODG + OpenDocument Drawing + + + + + + + + + + + + + ODP presentation + عرض تقديمي ODP + Prezentacyja ODP + Презентация — ODP + presentació ODP + Prezentace ODP + ODP-præsentation + ODP-Präsentation + ODP presentation + ODP-prezentaĵo + presentación ODP + ODP aurkezpena + ODP-esitys + ODP framløga + présentation ODP + láithreoireacht ODP + presentación ODP + מצגת ODP + ODP-prezentáció + Presentasi ODP + Presentazione ODP + ODP プレゼンテーション + ODP презентациясы + ODP 프리젠테이션 + ODP pateiktis + ODP prezentācija + ODP-presentasjon + ODP-presentatie + ODP-presentasjon + Prezentacja ODP + Apresentação ODP + Prezentare ODP + презентация ODP + Prezentácia ODP + Predstavitev ODP + Prezantim ODP + ODP-presentation + презентація ODP + Trình diễn ODM + ODP 演示文稿 + ODP 簡報 + ODP + OpenDocument Presentation + + + + + + + + + + + + + ODP presentation (Flat XML) + عرض ODP (Flat XML) + Презентация — ODP (само XML) + presentació ODP (XML pla) + Prezentace ODP (Flat XML) + ODP-præsentation (flad XML) + ODP-Präsentation (Unkomprimiertes XML) + presentación ODP (XML plano) + ODP aurkezpena (XML soila) + ODP framløga (Flat XML) + présentation ODP (XML plat) + láithreoireacht ODP (XML cothrom) + presentación ODP (XML plano) + מצגת ODP‏ (Flat XML) + ODP-prezentáció (egyszerű XML) + Presentasi ODP (Flat XML) + Presentazione ODP (XML semplice) + ODP プレゼンテーション (Flat XML) + ODP презентациясы (Тек XML) + ODP 프리젠테이션 (단일 XML) + ODP pateiktis (Flat XML) + ODP prezentācija (plakans XML) + Prezentacja ODP (prosty XML) + Prezentare ODP (XML simplu) + презентация ODP (простой XML) + Prezentácia ODP (čisté XML) + Predstavitev ODP (nepovezan XML) + ODP-presentation (platt XML) + презентація ODP (Flat XML) + ODP 演示文稿(Flat XML) + ODP 範本 (Flat XML) + FODP + OpenDocument Presentation (Flat XML) + + + + + + ODP template + قالب ODP + Šablon ODP + Шаблон за презентации — ODP + plantilla ODP + Šablona ODP + ODP-skabelon + ODP-Vorlage + ODP template + ODP-ŝablono + plantilla ODP + ODP txantiloia + ODP-malli + ODP formur + modèle ODP + teimpléad ODP + modelo ODP + תבנית ODP + ODP-sablon + Templat ODP + Modello ODP + ODP テンプレート + ODP үлгісі + ODP 문서 서식 + ODP šablonas + ODP veidne + ODP-mal + ODP-sjabloon + ODP-mal + Szablon ODP + Modelo ODP + Șablon ODP + шаблон ODP + Šablóna ODP + Predloga dokumenta ODP + Model ODP + ODP-mall + шаблон ODP + Mẫu ODP + ODP 模板 + ODP 範本 + ODP + OpenDocument Presentation + + + + + + + + + + + + + ODS spreadsheet + جدول ODS + Raźlikovy arkuš ODS + Таблица — ODS + full de càlcul ODS + Sešit ODS + ODS-regneark + ODS-Tabelle + ODS spreadsheet + ODS-kalkultabelo + hoja de cálculo ODS + ODS kalkulu-orria + ODS-taulukko + ODS rokniark + feuille de calcul ODS + scarbhileog ODS + folla de cálculo ODS + גליון נתונים ODS + ODS-táblázat + Lembar sebar ODS + Foglio di calcolo ODS + ODS スプレッドシート + ODS электрондық кестесі + ODS 스프레드시트 + ODS skaičialentė + ODS izklājlapa + ODS-regneark + ODS-rekenblad + ODS-rekneark + Arkusz ODS + Planilha ODS + Foaie de calcul ODS + электронная таблица ODS + Zošit ODS + Razpredelnica ODS + Fletë llogaritjesh ODS + ODS-kalkylblad + ел. таблиця ODS + Bảng tính ODS + ODS 工作簿 + ODS 試算表 + ODS + OpenDocument Spreadsheet + + + + + + + + + + + + + ODS spreadsheet (Flat XML) + جدول ODS (Flat XML) + Таблица — ODS (само XML) + full de càlcul ODS (XML pla) + Sešit ODS (Flat XML) + ODS-regneark (flad XML) + ODS-Tabelle (Unkomprimiertes XML) + hoja de cálculo ODS (XML plano) + ODS kalkulu-orria (XML soila) + ODS rokniark (Flat XML) + feuille de calcul ODS (XML plat) + scarbhileog ODS (XML cothrom) + folla de cálculo ODS (XML plano) + גליון נתונים ODS‏ (XML פשוט) + ODS-táblázat (egyszerű XML) + Lembar sebar ODS (Flat XML) + Foglio di calcolo ODS (XML semplice) + ODS スプレッドシート (Flat XML) + ODS электрондық кестесі (Тек XML) + ODS 스프레드시트 (단일 XML) + ODS skaičialentė (Flat XML) + ODS izklājlapa (plakans XML) + Arkusz ODS (prosty XML) + Foaie de calcul ODS (XML simplu) + электронная таблица ODS (простой XML) + Zošit ODS (čisté XML) + Razpredelnica ODS (nepovezan XML) + ODS-kalkylblad (platt XML) + ел. таблиця ODS (Flat XML) + ODS 工作簿(Flat XML) + ODS 試算表 (Flat XML) + FODS + OpenDocument Spreadsheet (Flat XML) + + + + + + ODS template + قالب ODS + Šablon ODS + Шаблон за таблици — ODS + plantilla ODS + Šablona ODS + ODS-skabelon + ODS-Vorlage + ODS template + ODS-ŝablono + plantilla ODS + ODS txantiloia + ODS-malli + ODS formur + modèle ODS + teimpléad ODS + modelo ODS + תבנית ODS + ODS-sablon + Templat ODS + Modello ODS + ODS テンプレート + ODS үлгісі + ODS 문서 서식 + ODS šablonas + ODS veidne + ODS-mal + ODS-sjabloon + ODS-mal + Szablon ODS + Modelo ODS + Șablon ODS + шаблон ODS + Šablóna ODS + Predloga dokumenta ODS + Model ODS + ODS-mall + шаблон ODS + Mẫu ODS + ODS 模板 + ODS 範本 + ODS + OpenDocument Spreadsheet + + + + + + + + + + + + + ODC chart + مخطط ODC + Dyjahrama ODC + Диаграма — ODC + diagrama ODC + Graf ODC + ODC-diagram + ODC-Diagramm + ODC chart + ODC-diagramo + gráfica ODC + ODC diagrama + ODC-kaavio + ODC strikumynd + graphique ODC + cairt ODC + gráfica ODC + תו ODC + ODC-táblázat + Bagan ODC + Grafico ODC + ODC チャート + ODC диаграммасы + ODC 차트 + ODC diagrama + ODC diagramma + ODC-graf + ODC-grafiek + ODC-diagram + Wykres ODC + Gráfico ODC + Diagramă ODC + диаграмма ODC + Graf ODC + Datoteka grafikona ODC + Grafik ODC + ODC-diagram + діаграма ODC + Sơ đồ ODC + ODC 图表 + ODC 圖表 + ODC + OpenDocument Chart + + + + + + + + + + + + + ODC template + قالب ODC + Шаблон за диаграми — ODC + plantilla ODC + Šablona ODC + ODC-skabelon + ODC-Vorlage + ODC-ŝablono + plantilla ODC + ODC txantiloia + ODC-malli + ODC formur + modèle ODC + teimpléad ODC + modelo ODC + תבנית ODC + ODC-sablon + Templat ODC + Modello ODC + ODC テンプレート + ODC үлгісі + ODC 문서 서식 + ODC šablonas + ODC veidne + ODC-sjabloon + Szablon ODC + Modelo ODC + Șablon ODC + шаблон ODC + Šablóna ODC + Predloga ODC + ODC-mall + шаблон ODC + Mẫu ODC + ODC 模板 + ODC 範本 + ODC + OpenDocument Chart + + + + + + + + + + + + + ODF formula + صيغة ODF + Formuła ODF + Формула — ODF + fórmula ODF + Vzorec ODF + ODF-formel + ODF-Formel + ODF formula + ODF-formulo + fórmula ODF + ODF formula + ODF-kaava + ODF frymil + formule ODF + foirmle ODF + Fórula ODF + נוסחת ODF + ODF-képlet + Formula ODF + Formula ODF + ODF 計算式 + ODF формуласы + ODF 수식 + ODF formulė + ODF formula + ODF-formel + ODF-formule + ODF-formel + Formuła ODF + Fórmula ODF + Formulă ODF + формула ODF + Vzorec ODF + Dokument formule ODF + Formulë ODF + ODF-formel + формула ODF + Công thức ODF + ODF 公式 + ODF 公式 + ODF + OpenDocument Formula + + + + + + + + + + + + + ODF template + قالب ODF + Шаблон за формули — ODF + plantilla ODF + Šablona ODF + ODF-skabelon + ODF-Vorlage + ODF-ŝablono + plantilla ODF + ODF txantiloia + ODF-malli + ODF formur + modèle ODF + teimpléad ODF + modelo ODF + תבנית ODF + ODG-sablon + Templat ODF + Modello ODF + ODF テンプレート + ODF үлгісі + ODF 문서 서식 + ODF šablonas + ODF veidne + ODF-sjabloon + Szablon ODF + Modelo ODF + Șablon ODF + шаблон ODF + Šablóna ODF + Predloga dokumenta ODF + ODF-mall + шаблон ODF + Mẫu ODF + ODF 模板 + ODF 範本 + ODF + OpenDocument Formula + + + + + + + + + + + + + ODB database + قاعدة بيانات ODB + Baza źviestak ODB + База от данни — ODB + base de dades ODB + Databáze ODB + ODB-database + ODB-Datenbank + ODB database + ODB-datumbazo + base de datos ODB + ODB datu-basea + ODB-tietokanta + ODB dátustovnur + base de données ODB + bunachar sonraí ODB + base de datos ODB + בסיס נתונים ODB + ODB-adatbázis + Basis data ODB + Database ODB + ODB データベース + ODB дерекқоры + ODB 데이터베이스 + ODB duomenų bazė + ODB datubāze + ODB-database + ODB-gegevensbank + ODB-database + Baza danych ODB + Banco de dados ODB + Bază de date ODB + база данных ODB + Databáza ODB + Podatkovna zbirka ODB + Bazë me të dhëna ODB + ODB-databas + база даних ODB + Cơ sở dữ liệu ODB + ODB 数据库 + ODB 資料庫 + ODB + OpenDocument Database + + + + + + ODI image + صورة ODI + Vyjava ODI + Изображение — ODI + imatge ODI + Obrázek ODI + ODI-billede + ODI-Bild + ODI image + ODI-bildo + imagen ODI + ODI irudia + ODI-kuva + ODI mynd + image ODI + íomhá ODI + imaxe ODI + תמונת ODI + ODI-kép + Citra ODI + Immagine ODI + ODI 画像 + ODI суреті + ODI 그림 + ODI paveikslėlis + ODI attēls + ODI-bilde + ODI-afbeelding + ODI-bilete + Obraz ODI + Imagem ODI + Imagine ODI + изображение ODI + Obrázok ODI + Slikovna datoteka ODI + Figurë ODI + ODI-bild + зображення ODI + Ảnh ODI + ODI 图像 + ODI 影像 + ODI + OpenDocument Image + + + + + + + + + + + + + OpenOffice.org extension + امتداد OpenOffice.org + Pašyreńnie OpenOffice.org + Разширение — OpenOffice + extensió d'OpenOffice.org + Rozšíření OpenOffice.org + OpenOffice.org-udvidelse + OpenOffice.org-Erweiterung + extensión de OpenOffice + OpenOffice.org luzapena + OpenOffice.org-laajennus + OpenOffice.org víðkan + extension OpenOffice.org + eisínteacht OpenOffice.org + Extensión de OpenOffice.org + הרחבה של OpenOffice.org + OpenOffice.org kiterjesztés + Ekstensi OpenOffice.org + Estensione OpenOffice.org + OpenOffice.org 拡張機能 + OpenOffice.org кеңейтуі + OpenOffice.org 확장 + OpenOffice.org plėtinys + OpenOffice.org paplašinājums + OpenOffice.org-uitbreiding + OpenOffice Writer-utviding + Rozszerzenie OpenOffice.org + Extensão do OpenOffice + Extensie OpenOffice.org + расширение OpenOffice.org + Rozšírenie OpenOffice.org + Razširitev OpenOffice.org + Shtojcë për OpenOffice.org + OpenOffice.org-tillägg + розширення OpenOffice.org + Phần mở rộng của OpenOffice.org + OpenOffice.org 扩展 + OpenOffice.org 擴充套件 + + + + + + Android package + Пакет — Android + paquet d'Android + Balíčky systému Android + Android-Paket + Android-pakaĵo + Paquete de Android + Android-paketti + paquet Android + paquete de Android + חבילת אנדרויד + Android csomag + Paket Android + Pacchetto Android + Android パッケージ + Android дестесі + 안드로이드 패키지 + Android pakotne + Pakiet Androida + пакет Android + Paket Android + Android-paket + пакунок Android + Android + Android 套件 + + + + + SIS package + حزمة SIS + Pakunak SIS + Пакет — SIS + paquet SIS + Balíček SIS + SIS-pakke + SIS-Paket + SIS-pakaĵo + paquete SIS + SIS paketea + SIS-paketti + SIS pakki + paquet SIS + pacáiste SIS + paquete SIS + חבילת SIS + SIS csomag + Paket SIS + Pacchetto SIS + SIS パッケージ + SIS дестесі + SIS 패키지 + SIS paketas + SIS pakotne + SIS-pakke + SIS-pakket + SIS-pakke + Pakiet SIS + Pacote SIS + Pachet SIS + пакет SIS + Balíček SIS + Datoteka paketa SIS + Paketë SIS + SIS-paket + пакунок SIS + Gói SIS + SIS 软件包 + SIS 套件 + SIS + Symbian Installation File + + + + + + + + SISX package + حزمة SISX + Pakunak SISX + Пакет — SISX + paquet SISX + Balíček SISX + SISX-pakke + SISX-Paket + SISX-pakaĵo + paquete SISX + SISX paketea + SISX-paketti + SISX pakki + paquet SISX + pacáiste SISX + paquete SISX + חבילת SISX + SISX csomag + Paket SISX + Pacchetto SISX + SISX パッケージ + SISX дестесі + SISX 패키지 + SISX paketas + SISX pakotne + SISX-pakke + SISX-pakket + SISX-pakke + Pakiet SISX + Pacote SISX + Pachet SISX + пакет SISX + Balíček SISX + Datoteka paketa SISX + Paketë SISX + SISX-paket + пакунок SISX + Gói SISX + SISX 软件包 + SISX 套件 + SIS + Symbian Installation File + + + + + + + + Network Packet Capture + Прихванати пакети по мрежата + captura de paquets de xarxa + Network Packet Capture + Netzwerk-Paketmitschnitt + Caputra de paquete de red + capture de paquet réseau + Captura de Network Packet + לכידה של מנות נתונים ברשת + Hálózati csomagelfogás + Tangkapan Paket Jaringan + Cattura pacchetti rete + ネットワークパケットキャプチャー + ұсталған желілік пакеттер + 네트워크 패킷 캡처 + Network Packet Capture + Przechwycenie pakietu sieciowego + захваченные сетевые пакеты + Zajem omrežnih paketov + перехоплені дані мережевих пакетів + 網路封包捕捉 + + + + + + + + + + + + WordPerfect document + مستند WordPerfect + WordPerfect sənədi + Dakument WordPerfect + Документ — WordPerfect + document de WordPerfect + Dokument WordPerfect + Dogfen WordPerfect + WordPerfect-dokument + WordPerfect-Dokument + έγγραφο WordPerfect + WordPerfect document + WordPerfect-dokumento + documento de WordPerfect + WordPerfect dokumentua + WordPerfect-asiakirja + WordPerfect skjal + document WordPerfect + cáipéis WordPerfect + documento de WordPerfect + מסמך WordPerfect + WordPerfect-dokumentum + Dokumen WordPerfect + Documento WordPerfect + WordPerfect ドキュメント + WordPerfect құжаты + 워드퍼펙트 문서 + WordPerfect dokumentas + WordPerfect dokuments + Dokumen WordPerfect + WordPerfect-dokument + WordPerfect-document + WordPerfect-dokument + Dokument WordPerfect + documento do WordPerfect + Documento do WordPerfect + Document WordPerfect + документ WordPerfect + Dokument WordPerfect + Dokument WordPerfect + Dokument WordPerfect + WordPerfect документ + WordPerfect-dokument + документ WordPerfect + Tài liệu WordPerfect + WordPerfect 文档 + WordPerfect 文件 + + + + + + + + + + + + + + + + SPSS Portable Data File + ملف بيانات SPSS متنقلة + Данни — SPSS, преносими + fitxer de dades portables SPSS + Soubor přenositelných dat SPSS + Portabel SPSS-datafil + SPSS portable Datendatei + archivo de datos portable SPSS + SPSS datuen fitxategi eramangarria + SPSS flytifør dátufíla + fichier portable de données SPSS + comhad iniompartha sonraí SPSS + ficheiro de datos portábel SPSS + קובץ מידע נייד SPSS + SPSS hordozható adatfájl + Berkas Data Portabel SPSS + File dati SPSS Portable + SPSS ポータブルデータファイル + SPSS тасымалы ақпарат файлы + SPSS 이동식 데이터 파일 + SPSS perkeliamų duomenų failas + SPSS pārvietojamu datu fails + Plik przenośnych danych SPSS + Fișier portabil de date SPSS + файл переносимых данных SPSS + Súbor prenosných dát SPSS + Prenosna podatkovna datoteka SPSS + Portabel SPSS-datafil + файл даних SPSS Portable + SPSS 便携式数据文件 + SPSS 可攜式資料檔 + + + + + + + SPSS Data File + ملف بيانات SPSS + Данни — SPSS + fitxer de dades SPSS + Datový soubor SPSS + SPSS-datafil + SPSS-Datendatei + archivo de datos SPSS + SPSS datuen fitxategia + SPSS dátufíla + fichier de données SPSS + comhad sonraí SPSS + ficheiro de datos SPSS + קובץ מידע SPSS + SPSS adatfájl + Berkas Data SPSS + File dati SPSS + SPSS データファイル + SPSS ақпарат файлы + SPSS 데이터 파일 + SPSS duomenų failas + SPSS datu fails + Plik danych SPSS + Fișier date SPSS + файл данных SPSS + Dátový súbor SPSS + Podatkovna datoteka SPSS + SPSS-datafil + файл даних SPSS + SPSS 数据文件 + SPSS 資料檔 + + + + + + + + XBEL bookmarks + علامات XBEL + Zakładki XBEL + Отметки — XBEL + llista d'adreces d'interès XBEL + Záložky XBEL + XBEL-bogmærker + XBEL-Lesezeichen + σελιδοδείκτες XBEL + XBEL bookmarks + XBEL-legosignoj + marcadores XBEL + XBEL laster-markak + XBEL-kirjanmerkit + XBEL bókamerki + marque-pages XBEL + leabharmharcanna XBEL + Marcadores XBEL + סמניית XBEL + XBEL-könyvjelzők + Bookmark XBEL + Segnalibri XBEL + XBEL ブックマーク + XBEL бетбелгілері + XBEL 책갈피 + XBEL žymelės + XBEL grāmatzīmes + Tandabuku XBEL + XBEL-bokmerker + XBEL-bladwijzers + XBEL-bokmerker + Zakładki XBEL + marcadores XBEL + Marcadores do XBEL + Semne de carte XBEL + закладки XBEL + Záložky XBEL + Datoteka zaznamkov XBEL + Libërshënues XBEL + XBEL обележивачи + XBEL-bokmärken + закладки XBEL + Liên kết đã lưu XBEL + XBEL 书签 + XBEL 格式書籤 + XBEL + XML Bookmark Exchange Language + + + + + + + + + 7-zip archive + أرشيف 7-zip + Archiŭ 7-zip + Архив — 7-zip + arxiu 7-zip + Archiv 7-zip + 7-zip-arkiv + 7zip-Archiv + 7z-arkivo + archivador 7-zip + 7-zip artxiboa + 7-zip-arkisto + 7-zip skjalasavn + archive 7-zip + cartlann 7-zip + arquivo 7-zip + ארכיון 7-zip + 7-zip archívum + Arsip 7-zip + Archivio 7-zip + 7-zip アーカイブ + 7-zip архиві + 7-ZIP 압축 파일 + 7-zip archyvas + 7-zip arhīvs + 7-zip-arkiv + 7-zip-archief + 7-zip-arkiv + Archiwum 7-zip + Pacote 7-zip + Arhivă 7-zip + архив 7-zip + Archív 7-zip + Datoteka arhiva 7-zip + Arkiv 7-zip + 7-zip-arkiv + архів 7-zip + Kho nén 7-zip + 7-zip 归档文件 + 7-zip 封存檔 + + + + + + + + AbiWord document + مستند آبي وورد + Dakument AbiWord + Документ — AbiWord + document d'AbiWord + Dokument AbiWord + AbiWord-dokument + AbiWord-Dokument + έγγραφο AbiWord + AbiWord document + AbiWord-dokumento + documento de Abiword + AbiWord dokumentua + AbiWord-asiakirja + AbiWord skjal + document AbiWord + cáipéis AbiWord + documento de AbiWord + מסמך AbiWord + AbiWord-dokumentum + Dokumen AbiWord + Documento AbiWord + AbiWord ドキュメント + AbiWord құжаты + AbiWord 문서 + AbiWord dokumentas + AbiWord dokuments + Dokumen AbiWord + AbiWord-dokument + AbiWord-document + AbiWord-dokument + Dokument AbiWord + documento AbiWord + Documento do AbiWord + Document AbiWord + документ AbiWord + Dokument AbiWord + Dokument AbiWord + Dokument AbiWord + Абиворд документ + AbiWord-dokument + документ AbiWord + Tài liệu AbiWord + AbiWord 文档 + AbiWord 文件 + + + + + + + + + + + + + + CD image cuesheet + صفيحة صورة الـCD جديلة + Infarmacyjny arkuš vyjavy CD + Описание на изображение на CD + «cuesheet» d'imatge de CD + Rozvržení stop obrazu CD + Cd-aftrykscuesheet + CD-Abbild-Cuesheet + CD image cuesheet + cue sheet de una imagen de CD + CD irudiaren CUE orria + CD-vedos cuesheet + index de pistes de CD + bileog chiúáil íomhá CD + cue sheet dunha imaxe de CD + גליון נתונים לתמונת דיסק + CD kép cuesheet + Citra cuesheet CD + Cuesheet immagine CD + CD イメージキューシート + CD бейнесінің құрама кестесі + CD 이미지 큐시트 + CD atvaizdžio aprašas + CD attēla rindulapa + Filliste for CD-avtrykk + CD-inhoudsopgave + CD-bilete-indeksfil + Obraz cuesheet płyty CD + Índice de Imagem de CD + Imagine CD cuesheet + таблица содержания образа CD + Rozvrhnutie stôp obrazu CD + Datoteka razpredelnice odtisa CD cue + Cuesheet imazhi CD + Indexblad för cd-avbild + таблиця CUE образу CD + Tờ tín hiệu báo ảnh CD + CD 映像标记文件 + CD 映像指示表 + + + + + + Lotus AmiPro document + مستند Lotus AmiPro + Lotus AmiPro sənədi + Dakument Lotus AmiPro + Документ — Lotus AmiPro + document de Lotus AmiPro + Dokument Lotus AmiPro + Dogfen Lotus AmiPro + Lotus AmiPro-dokument + Lotus-AmiPro-Dokument + έγγραφο Lotus AmiPro + Lotus AmiPro document + dokumento de Lotus AmiPro + documento de Lotus AmiPro + Lotus AmiPro dokumentua + Lotus AmiPro -asiakirja + Lotus AmiPro skjal + document Lotus AmiPro + cáipéis Lotus AmiPro + documento de Lotus AmiPro + מסמך של Lotus AmiPro + Lotus AmiPro-dokumentum + Dokumen Lotus AmiPro + Documento Lotus AmiPro + Lotus AmiPro ドキュメント + Lotus AmiPro құжаты + Lotus AmiPro 문서 + Lotus AmiPro dokumentas + Lotus AmiPro dokuments + Dokumen Lotus AmiPro + Lotus AmiPro-dokument + Lotus AmiPro-document + Lotus AmiPro-dokument + Dokument Lotus AmiPro + documento Lotus AmiPro + Documento do Lotus AmiPro + Document Lotus AmiPro + документ Lotus AmiPro + Dokument Lotus AmiPro + Dokument Lotus AmiPro + Dokument Lotus AmiPro + Лотус АмиПро документ + Lotus AmiPro-dokument + документ Lotus AmiPro + Tài liệu Lotus AmiPro + Lotus AmiPro 文档 + Lotus AmiPro 文件 + + + + + AportisDoc document + مستند AportisDoc + Документ — AportisDoc + document AportisDoc + Dokument AportisDoc + AportisDoc-dokument + AportisDoc-Dokument + AportisDoc-dokumento + documento AportisDoc + AportisDoc dokumentua + AportisDoc-asiakirja + AportisDoc skjal + document AportisDoc + cáipéis AportisDoc + documento de AportiDoc + מסמך AportisDoc + AportisDoc-dokumentum + Dokumen AportisDoc + Documento AportisDoc + AportisDoc ドキュメント + AportisDoc құжаты + AportisDoc 문서 + AportisDoc dokumentas + AportisDoc dokuments + AportisDoc-document + Dokument AportisDoc + Documento do AportisDoc + Document AportisDoc + документ AportisDoc + Dokument AportisDoc + Dokument AportisDoc + AportisDoc-dokument + документ AportisDoc + Tài liệu AportisDoc + AportisDoc 文档 + AportisDoc 文件 + + + + + + + + + + + Applix Spreadsheets spreadsheet + جداول بيانات Applix + Raźlikovy arkuš Applix Spreadsheets + Таблица — Applix Spreadsheets + full de càlcul d'Applix Spreadsheets + Sešit Applix Spreadsheets + Applix Spreadsheets-regneark + Applix-Spreadsheets-Tabelle + λογιστικό φύλλο Applix Spreadsheets + Applix Spreadsheets spreadsheet + sterntabelo de Applix Spreadsheets + hoja de cálculo de Applix Spreadsheets + Applix Spreadsheets kalkulu-orria + Applix Spreadsheets -taulukko + Applix Spreadsheets rokniark + feuille de calcul Applix + scarbhileog Applix Spreadsheets + folla de cálculo de Applix + גליון נתונים של Applix Spreadsheets + Applix Spreadsheets-munkafüzet + Lembar sebar Applix Spreadsheets + Foglio di calcolo Applix Spreadsheets + Applix Spreadsheets スプレッドシート + Applix Spreadsheets электрондық кестесі + Applix 스프레드시트 + Applix Spreadsheets skaičialentė + Applix Spreadsheets izklājlapa + Hamparan Applix Spreadsheets + Applix Spreadsheets-regneark + Applix Spreadsheets-rekenblad + Applix Spreadsheets-dokument + Arkusz Applix Spreadsheets + folha de cálculo Applix Spreadsheets + Planilha do Applix Spreadsheets + Foaie de calcul Applix + электронная таблица Applix Spreadsheets + Zošit Applix Spreadsheets + Razpredelnica Applix Spreadsheets + Fletë llogaritjesh Applix Spreadsheets + Applix табеларни документ + Applix Spreadsheets-kalkylblad + ел. таблиця Applix Spreadsheets + Bảng tính Applix Spreadsheets + Applix Spreadsheets 工作簿 + Applix Spreadsheets 試算表 + + + + + + + + + + + Applix Words document + مستند كلمات Applix + Applix Words sənədi + Dakument Applix Words + Документ — Applix Words + document d'Applix Words + Dokument Applix Words + Dogfen Applix Words + Applix Words-dokument + Applix-Words-Dokument + έγγραφο Applix Words + Applix Words document + dokumento de Applix Words + documento de Applix Words + Applix Words dokumentua + Applix Words -asiakirja + Applix Words skjal + document Applix Words + cáipéis Applix Words + documento de Applix Words + מסמך של Applix Words + Applix Words-dokumentum + Dokumen Applix Words + Documento Applix Words + Applix Words ドキュメント + Applix Words құжаты + Applix Words 문서 + Applix Words dokumentas + Applix Words dokuments + Dokumen Perkataan Applix + Applix Words-dokument + Applix Words-document + Applix Words dokument + Dokument Applix Words + documento Applix Words + Documento do Applix Words + Document Applix Words + документ Applix Words + Dokument Applix Words + Dokument Applix Words + Dokument Applix Words + Applix Words документ + Applix Words-dokument + документ Applix Words + Tài liệu Applix Words + Applix Words 文档 + Applix Words 文件 + + + + + + + + + + ARC archive + أرشيف ARC + Archiŭ ARC + Архив — ARC + arxiu ARC + Archiv ARC + ARC-arkiv + ARC-Archiv + ARC-arkivo + archivador ARC + ARC artxiboa + ARC-arkisto + ARC skjalasavn + archive ARC + cartlann ARC + arquivo ARC + ארכיון ARC + ARC-archívum + Arsip ARC + Archivio ARC + ARC アーカイブ + ARC архиві + ARC 압축 파일 + ARC archyvas + ARC arhīvs + ARC-arkiv + ARC-archief + ARC-arkiv + Archiwum ARC + Pacote ARC + Arhivă ARC + архив ARC + Archív ARC + Datoteka arhiva ARC + Arkiv ARC + ARC-arkiv + архів ARC + Kho nén ARC + ARC 归档文件 + ARC 封存檔 + + + + + + + + + + + + AR archive + أرشيف AR + Archiŭ AR + Архив — AR + arxiu AR + Archiv AR + AR-arkiv + AR-Archiv + σρχείο AR + AR archive + AR-arkivo + archivador AR + AR artxiboa + AR-arkisto + AR skjalasavn + archive AR + cartlann AR + arquivo AR + ארכיון AR + AR-archívum + Arsip AR + Archivio AR + AR アーカイブ + AR архиві + AR 묶음 파일 + AR archyvas + AR arhīvs + Arkib AR + AR-arkiv + AR-archief + AR-arkiv + Archiwum AR + arquivo AR + Pacote AR + Arhivă AR + архив AR + Archív AR + Datoteka arhiva AR + Arkiv AR + АР архива + AR-arkiv + архів AR + Kho nén AR + AR 归档文件 + AR 封存檔 + + + + + + + + + ARJ archive + أرشيف ARJ + ARJ arxivi + Archiŭ ARJ + Архив — ARJ + arxiu ARJ + Archiv ARJ + Archif ARJ + ARJ-arkiv + ARJ-Archiv + αρχείο ARJ + ARJ archive + ARJ-arkivo + archivador ARJ + ARJ artxiboa + ARJ-arkisto + ARJ skjalasavn + archive ARJ + cartlann ARJ + arquivo ARJ + ארכיון ARJ + ARJ-archívum + Arsip ARJ + Archivio ARJ + ARJ アーカイブ + ARJ архиві + ARJ 압축 파일 + ARJ archyvas + ARJ arhīvs + Arkib ARJ + ARJ-arkiv + ARJ-archief + ARJ-arkiv + Archiwum ARJ + arquivo ARJ + Pacote ARJ + Arhivă ARJ + архив ARJ + Archív ARJ + Datoteka arhiva ARJ + Arkiv ARJ + ARJ архива + ARJ-arkiv + архів ARJ + Kho nén ARJ + ARJ 归档文件 + ARJ 封存檔 + ARJ + Archived by Robert Jung + + + + + + + + ASP page + صفحة ASP + Staronka ASP + Страница — ASP + pàgina ASP + Stránka ASP + ASP-side + ASP-Seite + ASP page + ASP-paĝo + página ASP + ASP orria + ASP-sivu + ASP síða + page ASP + leathanach ASP + páxina ASP + עמוד ASP + ASP oldal + Halaman ASP + Pagina ASP + ASP ページ + ASP парағы + ASP 페이지 + ASP puslapis + ASP lapa + ASP-side + ASP-pagina + ASP-side + Strona ASP + Página ASP + Pagină ASP + страница ASP + Stránka ASP + Datoteka spletne strani ASP + Faqe ASP + ASP-sida + сторінка ASP + Trang ASP + ASP 页面 + ASP 頁面 + ASP + Active Server Page + + + + + + AWK script + سكربت AWK + AWK skripti + Skrypt AWK + Скрипт — AWK + script AWK + Skript AWK + Sgript AWK + AWK-program + AWK-Skript + πρόγραμμα εντολών AWK + AWK script + AWK-skripto + script en AWK + AWK script-a + AWK-komentotiedosto + AWK boðrøð + script AWK + script AWK + script de AWK + תסריט AWK + AWK-parancsfájl + Skrip AWK + Script AWK + AWK スクリプト + AWK сценарийі + AWK 스크립트 + AWK scenarijus + AWK skripts + Skrip AWK + AWK-skript + AWK-script + WAK-skript + Skrypt AWK + 'script' AWK + Script AWK + Script AWK + сценарий AWK + Skript AWK + Skriptna datoteka AWK + Script AWK + AWK скрипта + AWK-skript + скрипт AWK + Văn lệnh AWK + AWK 脚本 + AWK 指令稿 + + + + + + + + + + + + + + + + + + + BCPIO document + مستند BCPIO + BCPIO sənədi + Dakument BCPIO + Документ — BCPIO + document BCPIO + Dokument BCPIO + Dogfen BCPIO + BCPIO-dokument + BCPIO-Dokument + έγγραφο BCPIO + BCPIO document + BCPIO-dokumento + documento BCPIO + BCPIO dokumentua + BCPIO-asiakirja + BCPIO skjal + document BCPIO + cáipéis BCPIO + documento BCPIO + מסמך של BCPO + BCPIO-dokumentum + Dokumen BCPIO + Documento BCPIO + BCPIO ドキュメント + BCPIO құжаты + BCPIO 문서 + BCPIO dokumentas + BCPIO dokuments + Dokumen BCPIO + BCPIO-dokument + BCPIO-document + BCPIO-dokument + Dokument BCPIO + documento BCPIO + Documento BCPIO + Document BCPIO + документ BCPIO + Dokument BCPIO + Dokument BCPIO + Dokument BCPIO + BCPIO документ + BCPIO-dokument + документ BCPIO + Tài liệu BCPIO + BCPIO 文档 + BCPIO 文件 + BCPIO + Binary CPIO + + + + + BitTorrent seed file + ملف باذر البت تورنت + BitTorrent seed faylı + Fajł krynicy BitTorrent + Файл-източник — BitTorrent + fitxer llavor de BitTorrent + Soubor BitTorrent + Ffeil hadu BitTorrent + BitTorrent-frøfil + BitTorrent-Seed-Datei + αρχείο BitTorrent seed + BitTorrent seed file + BitTorrent-semdosiero + archivo semilla de BitTorrent + BitTorrent hazi-fitxategia + BitTorrent-siementiedosto + BitTorrent seed fíla + fichier graine BitTorrent + comhad síl BitTorrent + ficheiro de orixe BitTorrent + קובץ זריעה של BitTorrent + BitTorrent-magfájl + Berkas benih BitTorrent + File seed BitTorrent + BitTorrent シードファイル + BitTorrent көз файлы + 비트토렌트 시드 파일 + BitTorrent šaltinio failas + BitTorrent avota fails + Fail seed BitTorrent + Fil med utgangsverdi for BitTorrent + BitTorrent-bestand + Nedlastingsfil for BitTorrent + Plik ziarna BitTorrent + ficheiro de origem BitTorrent + Arquivo semente BitTorrent + Fișier sursă-completă BitTorrent + файл источника BitTorrent + Súbor BitTorrent + Datoteka sejanja BitTorrent + File bazë BitTorrent + Датотека са БитТорентовим полазиштима + BitTorrent-distributionsfil + файл поширення BitTorrent + Tải tập hạt BitTorrent + BitTorrent 种子文件 + BitTorrent 種子檔 + + + + + + + Blender scene + مشهد بلندر + Scena Blender + Сцена — Blender + escena Blender + Scéna Blender + Blenderscene + Blender-Szene + σκηνή Blender + Blender scene + Blender-sceno + escena de Blender + Blender-eko fitxategia + Blender-näkymä + Blender leikmynd + scène Blender + radharc Blender + escena de Blender + סצנת Blender + Blender-jelenet + Scene Blender + Scena Blender + Blender シーン + Blender сахнасы + Blender 장면 + Blender scena + Blender aina + Babak Blender + Blender-scene + Blender-scène + Blender-scene + Scena programu Blender + cenário Blender + Cena do Blender + Scenă Blender + сцена Blender + Scéna Blender + Datoteka scene Blender + Skenë Blender + Блендер сцена + Blender-scen + сцена Blender + Cảnh Blender + Blender 场景 + Blender 場景 + + + + + + + + + + TeX DVI document (bzip-compressed) + مستند TeX DVI (مضغوط-bzip) + Dakument TeX DVI (bzip-skampresavany) + Документ — TeX DVI, компресиран с bzip + document TeX DVI (comprimit amb bzip) + Dokument TeX DVI (komprimovaný pomocí bzip) + TeX DVI-dokument (bzip-komprimeret) + TeX-DVI-Dokument (bzip-komprimiert) + documento DVI de TeX (comprimido con bzip) + TeX DVI dokumentua (bzip-ekin konprimitua) + TeX DVI -asiakirja (bzip-pakattu) + TeX DVI skjal (bzip-stappað) + document DVI TeX (compressé bzip) + cáipéis DVI TeX (comhbhrúite le bzip) + documento DVI de TeX (comprimido con bzip) + מסמך מסוג TeX DVI (מכווץ ע"י bzip) + TeX DVI dokumentum (bzip-pel tömörítve) + Dokumen TeX DVI (terkompresi bzip) + Documento TeX DVI (compresso con bzip) + Tex DVI ドキュメント (bzip 圧縮) + TeX DVI құжаты (bzip-пен сығылған) + TeX DVI 문서 (BZIP 압축) + TeX DVI dokumentas (suglaudintas su bzip) + TeX DVI dokuments (saspiests ar bzip) + TeX DVI-dokument (bzip-komprimert) + TeX DVI-document (ingepakt met bzip) + TeX DVI-dokument (pakka med bzip) + Dokument TeX DVI (kompresja bzip) + Documento DVI TeX (compactado com bzip) + Document TeX DVI (comprimat bzip) + документ TeX DVI (сжатый bzip) + Dokument TeX DVI (komprimovaný pomocou bzip) + Dokument TeX DVI (stisnjen z bzip) + Dokument Tex DVI (i kompresuar me bzip) + TeX DVI-dokument (bzip-komprimerat) + документ TeX DVI (стиснений bzip) + Tài liệu DVI TeX (đã nén bzip) + TeX DVI 文档(gzip 压缩) + TeX DVI 文件 (bzip 格式壓縮) + + + + + Bzip archive + أرشيف Bzip + Archiŭ bzip + Архив — bzip + arxiu bzip + Archiv bzip + Bzip-arkiv + Bzip-Archiv + Bzip-arkivo + archivador Bzip + Bzip artxiboa + Bzip-arkisto + Bzip skjalasavn + archive bzip + cartlann Bzip + arquivo Bzip + ארכיון Bzip + Bzip archívum + Arsip Bzip + Archivio bzip + Bzip アーカイブ + Bzip архиві + BZIP 압축 파일 + Bzip archyvas + Bzip arhīvs + Bzip-arkiv + Bzip-archief + Bzip-arkiv + Archiwum bzip + Pacote Bzip + Arhivă Bzip + архив BZIP + Archív bzip + Datoteka arhiva Bzip + Arkiv bzip + Bzip-arkiv + архів bzip + Kho nén bzip + bzip 归档文件 + Bzip 封存檔 + + + + + + + + + + Tar archive (bzip-compressed) + أرشيف Tar (مضغوط-bzip) + Archiŭ tar (bzip-skampresavany) + Архив — tar, компресиран с bzip + arxiu tar (comprimit amb bzip) + Archiv tar (komprimovaný pomocí bzip) + Tar-arkiv (bzip-komprimeret) + Tar-Archiv (bzip-komprimiert) + archivador Tar (comprimido con bzip) + Tar artxiboa (bzip-ekin konprimitua) + Tar-arkisto (bzip-pakattu) + Tar skjalasavn (bzip-stappað) + archive tar (compressée bzip) + cartlann Tar (comhbhrúite le bzip) + arquivo Tar (comprimido con bzip) + ארכיון Tar (מכווץ ע"י bzip) + Tar archívum (bzip-pel tömörítve) + Arsip Tar (terkompresi bzip) + Archivio tar (compresso con bzip) + Tar アーカイブ (bzip 圧縮) + Tar архиві (bzip-пен сығылған) + TAR 묶음 파일 (BZIP 압축) + Tar archyvas (suglaudintas su bzip) + Tar arhīvs (saspiests ar bzip) + Tar-arkiv (bzip-komprimert) + Tar-archief (ingepakt met bzip) + Tar-arkiv (pakka med bzip) + Archiwum tar (kompresja bzip) + Pacote tar (compactado com bzip) + Arhivă Tar (comprimată bzip) + архив TAR (сжатый BZIP) + Archív tar (komprimovaný pomocou bzip) + Datoteka arhiva Tar (stisnjen z bzip) + Arkiv tar (i kompresuar me bzip) + Tar-arkiv (bzip-komprimerat) + архів tar (стиснений bzip) + Kho nén tar (đã nén bzip) + Tar 归档文件(bzip 压缩) + Tar 封存檔 (bzip 格式壓縮) + + + + + + + + + PDF document (bzip-compressed) + مستند PDF (مضغوط-bzip) + Dakument PDF (bzip-skampresavany) + Документ — PDF, компресиран с bzip + document PDF (comprimit amb bzip) + Dokument PDF (komprimovaný pomocí bzip) + PDF-dokument (bzip-komprimeret) + PDF-Dokument (bzip-komprimiert) + documento PDF (comprimido con bzip) + PostScript dokumentua (bzip-ekin konprimitua) + PDF-asiakirja (bzip-pakattu) + PDF skjal (bzip-stappað) + document PDF (compressé bzip) + cáipéis PDF (comhbhrúite le bzip) + documento PDF (comprimido en bzip) + מסמך PDF (מכווץ ע"י bzip) + PDF dokumentum (bzip-tömörítésű) + Dokumen PDF (terkompresi bzip) + Documento PDF (compresso con bzip) + PDF ドキュメント (bzip 圧縮) + PDF құжаты (bzip-пен сығылған) + PDF 문서 (BZIP 압축) + PDF dokumentas (suglaudintas su bzip) + PDF dokuments (saspiests ar bzip) + PDF-dokument (bzip-komprimert) + PDF-document (ingepakt met bzip) + PDF-dokument (pakka med bzip) + Dokument PDF (kompresja bzip) + Documento PDF (compactado com bzip) + Document PDF (comprimat bzip) + документ PDF (сжатый bzip) + Dokument PDF (komprimovaný pomocou bzip) + Dokument PDF (stisnjen z bzip) + Dokument PDF (i kompresuar me bzip) + PDF-dokument (bzip-komprimerat) + документ PDF (стиснений bzip) + Tài liệu PDF (đã nén bzip) + PDF 文档(bzip 压缩) + PDF 文件 (bzip 格式壓縮) + + + + + PostScript document (bzip-compressed) + مستند PostScript (مضغوط-bzip) + Dakument PostScript (bzip-skampresavany) + Документ — PostScript, компресиран с bzip + document PostScript (comprimit amb bzip) + Dokument PostScript (komprimovaný pomocí bzip) + PostScript-dokument (bzip-komprimeret) + PostScript-Dokument (bzip-komprimiert) + documento PostScript (comprimido con bzip) + PostScript dokumentua (bzip-ekin konprimitua) + PostScript-asiakirja (bzip-pakattu) + PostScript skjal (bzip-stappað) + document PostScript (compressé bzip) + cáipéis PostScript (comhbhrúite le bzip) + documento PostScript (comprimido con bzip) + מסמך PostDcript (מכווץ ע"י bzip) + PostScript dokumentum (bzip-tömörítésű) + Dokumen PostScript (terkompresi bzip) + Documento PostScript (compresso con bzip) + PostScript ドキュメント (bzip 圧縮) + PostScript құжаты (bzip-пен сығылған) + 포스트스크립트 문서 (BZIP 압축) + PostScript dokumentas (suglaudintas su bzip) + PostScript dokuments (saspiests ar bzip) + PostScript-dokument (bzip-komprimert) + PostScript-document (ingepakt met bzip) + PostScript-dokument (pakka med bzip) + Dokument Postscript (kompresja bzip) + Documento PostScript (compactado com bzip) + Document PostScript (comprimat bzip) + документ PostScript (сжатый bzip) + Dokument PostScript (komprimovaný pomocou bzip) + Dokument PostScript (stisnjen z bzip) + Dokument PostScript (i kompresuar me bzip) + Postscript-dokument (bzip-komprimerat) + документ PostScript (стиснене bzip) + Tài liệu PostScript (đã nén bzip) + PostScript 文档(bzip 压缩) + PostScript 文件 (bzip 格式壓縮) + + + + + comic book archive + أرشيف comic book + archiŭ komiksaŭ + Архив — комикси + arxiu comic book + Archiv knihy komiksů + comic book-arkiv + Comic-Book-Archiv + archivador de libro de cómic + komiki artxiboa + sarjakuva-arkisto + teknisøgubóka skjalasavn + archive Comic Book + cartlann chartúin + ficheiro de libro de banda deseñada + ארכיון ספר קומי + képregényarchívum + arsip buku komik + Archivio comic book + コミックブックアーカイブ + комикстар архиві + 코믹북 묶음 파일 + komiksų knygos archyvas + komiksu grāmatas arhīvs + Tegneseriearkiv + stripboek-archief + teikneseriearkiv + Archiwum komiksu + Pacote de livro de revista em quadrinhos + arhivă benzi desenate + архив комиксов + Archív knihy komiksov + Datoteka arhiva stripov + Arkiv comic book + serietidningsarkiv + архів коміксів + Kho nén sách tranh chuyện vui + Comic Book 归档文件 + 漫畫書封存檔 + + + + + + comic book archive + أرشيف comic book + archiŭ komiksaŭ + Архив — комикси + arxiu comic book + Archiv knihy komiksů + comic book-arkiv + Comic-Book-Archiv + archivador de libro de cómic + komiki artxiboa + sarjakuva-arkisto + teknisøgubóka skjalasavn + archive Comic Book + cartlann chartúin + ficheiro de libro de banda deseñada + ארכיון ספר קומי + képregényarchívum + arsip buku komik + Archivio comic book + コミックブックアーカイブ + комикстар архиві + 코믹북 묶음 파일 + komiksų knygos archyvas + komiksu grāmatas arhīvs + Tegneseriearkiv + stripboek-archief + teikneseriearkiv + Archiwum komiksu + Pacote de livro de revista em quadrinhos + arhivă benzi desenate + архив комиксов + Archív knihy komiksov + Datoteka arhiva stripov + Arkiv comic book + serietidningsarkiv + архів коміксів + Kho nén sách tranh chuyện vui + Comic Book 归档文件 + 漫畫書封存檔 + + + + + + comic book archive + أرشيف comic book + archiŭ komiksaŭ + Архив — комикси + arxiu comic book + Archiv knihy komiksů + comic book-arkiv + Comic-Book-Archiv + archivador de libro de cómic + komiki artxiboa + sarjakuva-arkisto + teknisøgubóka skjalasavn + archive Comic Book + cartlann chartúin + ficheiro de libro de banda deseñada + ארכיון ספר קומי + képregényarchívum + arsip buku komik + Archivio comic book + コミックブックアーカイブ + комикстар архиві + 코믹북 묶음 파일 + komiksų knygos archyvas + komiksu grāmatas arhīvs + Tegneseriearkiv + stripboek-archief + teikneseriearkiv + Archiwum komiksu + Pacote de livro de revista em quadrinhos + arhivă benzi desenate + архив комиксов + Archív knihy komiksov + Datoteka arhiva stripov + Arkiv comic book + serietidningsarkiv + архів коміксів + Kho nén sách tranh chuyện vui + Comic Book 归档文件 + 漫畫書封存檔 + + + + + + comic book archive + أرشيف comic book + archiŭ komiksaŭ + Архив — комикси + arxiu comic book + Archiv knihy komiksů + comic book-arkiv + Comic-Book-Archiv + archivador de libro de cómic + komiki artxiboa + sarjakuva-arkisto + teknisøgubóka skjalasavn + archive Comic Book + cartlann chartúin + ficheiro de libro de banda deseñada + ארכיון ספר קומי + képregényarchívum + arsip buku komik + Archivio comic book + コミックブックアーカイブ + комикстар архиві + 코믹북 묶음 파일 + komiksų knygos archyvas + komiksu grāmatas arhīvs + Tegneseriearkiv + stripboek-archief + teikneseriearkiv + Archiwum komiksu + Pacote de livro de revista em quadrinhos + arhivă benzi desenate + архив комиксов + Archív knihy komiksov + Datoteka arhiva stripov + Arkiv comic book + serietidningsarkiv + архів коміксів + Kho nén sách tranh chuyện vui + Comic Book 归档文件 + 漫畫書封存檔 + + + + + + Lrzip archive + أرشيف Lrzip + Архив — lrzip + arxiu lrzip + Archiv Lrzip + Lrzip-arkiv + Lrzip-Archiv + Lrzip-arkivo + archivador Lrzip + Lrzip-arkisto + Lrzip skjalasavn + archive lrzip + cartlann Lrzip + arquivo Lrzip + ארכיון Lrzip + Lrzip archívum + Arsip Lrzip + Archivio Lrzip + Lrzip アーカイブ + Lrzip архиві + LRZIP 압축 파일 + Lrzip archyvas + Lrzip arhīvs + Archiwum lrzip + Arhivă Lrzip + архив LRZIP + Archív Lrzip + Datoteka arhiva Lrzip + Lrzip-arkiv + архів lrzip + Lrzip 归档文件 + Lrzip 封存檔 + + + + + + + + Tar archive (lrzip-compressed) + أرشيف Tar (مضغوط-lrzip) + Архив — tar, компресиран с lrzip + arxiu tar (comprimit amb lrzip) + Archiv tar (komprimovaný pomocí lrzip) + Tar-arkiv (lrzip-komprimeret) + Tar-Archiv (lrzip-komprimiert) + archivador Tar (comprimido con lrzip) + Tar-arkisto (lrzip-pakattu) + Tar skjalasavn (lrzip-stappað) + archive tar (compressée lrzip) + cartlann Tar (comhbhrúite le lrzip) + arquivo Tar (comprimido con lrzip) + ארכיון Tar (מכווץ ע"י lrzip) + Tar archívum (lrzip-pel tömörítve) + Arsip Tar (terkompresi lrzip) + Archivio tar (compresso con lrzip) + Tar アーカイブ (lrzip 圧縮) + Tar архиві (lrzip-пен сығылған) + TAR 묶음 파일 (LRZIP 압축) + Tar archyvas (suglaudintas su lrzip) + Tar arhīvs (saspiests ar lrzip) + Archiwum tar (kompresja lrzip) + Arhivă Tar (comprimată lrzip) + архив TAR (сжатый LRZIP) + Archív tar (komprimovaný pomocou lrzip) + Datoteka arhiva Tar (stisnjen z lrzip) + Tar-arkiv (lrzip-komprimerat) + архів tar (стиснений lrzip) + Tar 归档文件 (lrzip 压缩) + Tar 封存檔 (lrzip 格式壓縮) + + + + + + + Apple disk image + Диск — Apple + imatge de disc d'Apple + Obraz disku Apple + Apple-diskaftryk + Apple-Datenträgerabbild + imagen de disco de Apple + Apple-levytiedosto + image disque Apple + imaxe de disco de Appl + תמונת כונן Apple + Apple lemezkép + Image disk Apple + Immagine disco Apple + Apple ディスクイメージ + Apple диск бейнесі + 애플 디스크 이미지 + Apple diska attēls + Obraz dysku Apple + образ диска Apple Mac OS X + Obraz disku Apple + Odtis diska Apple + Apple-skivavbild + образ диска Apple + Apple 磁盘镜像 + Apple 磁碟映像 + + + + raw CD image + صورة CD خامة + suvoraja vyjava CD + Изображение — raw CD + imatge de CD en cru + Surový obraz CD + rå cd-aftryk + CD-Roh-Abbild + εικόνα περιεχομένου ψηφιακού δίσκου + raw CD image + kruda lumdiskbildo + imagen de CD en bruto + CD gordinaren irudia + raaka CD-vedos + rá CD mynd + image CD brute + amhíomhá dhlúthdhiosca + imaxe de CD en bruto + תמונת דיסק גולמית + nyers CD-lemezkép + citra CD mentah + Immagine raw CD + 生 CD イメージ + өңделмеген CD бейнесі + CD 이미지 + raw CD atvaizdis + CD jēlattēls + Imej CD mentah + rått CD-bilde + ruw CD-beeldbestand + rått CD-bilete + Surowy obraz CD + imagem em bruto de CD + imagem bruta de CD + imagine de CD brută + образ компакт-диска + Surový obraz CD + surovi CD odtis + Imazh raw CD + сирови отисак ЦД-а + rå cd-avbild + образ raw CD + ảnh đĩa CD thô + 原始 CD 映像 + 原生 CD 映像 + + + + + + CD Table Of Contents + جدول محتويات الـ CD + Źmieściva CD + Съдържание на CD + taula de continguts de CD + Obsah CD + Cd-indholdsfotegnelse + CD-Inhaltsverzeichnis + Índice de contenidos de CD + CDaren edukien aurkibidea + CD-sisällysluettelo + CD innihaldsyvurlit + table des matières de CD + clár ábhar dlúthdhiosca + táboa de contidos de CD + תוכן עניינים של דיסק + CD tartalomjegyzék + Tabel Isi CD + Indice CD + CD Table Of Contents + CD құрама кестесі + CD 내용 목록 + CD turinys + CD satura rādītājs + Innholdsfortegnelse for CD + CD-inhoudsopgave + CD innhaldsliste + Plik zawartości płyty CD + Sumário de CD + Tabel conținut CD + таблица содержания CD + Obsah CD + Kazalo vsebine CD nosilca + Tregues CD + Cd-innehållsförteckning + зміст CD + Mục Lục của đĩa CD + CD 索引 + CD 內容目錄 + + + + + + + + + + + + + + + PGN chess game notation + تدوينة لعبة الشطرنج PGN + Zaciem ab šachmatnaj partyi PGN + Игра шах — PGN + notació de joc d'escacs PGN + Šachová notace PGN + PGN-skakspilsnotation + PGN-Schachspielnotation + notación para juegos de ajedrez PGN + PGN xake jokoaren notazioa + PGN-šakkipelinotaatio + PGN talv teknskipan + notation de jeu d'échecs PGN + nodaireacht chluiche ficheall PGN + Notación de xogo de xadrez PGN + סימון משחק שח PGN + PGN sakkfeljegyzés + Notasi permainan catur PGN + Notazione partita a scacchi PGN + PGN チェスゲーム記録 + PGN шахмат ойыны + PGN 체스게임 기보 + PGN šachmatų žaidimo žymėjimas + PGN šaha spēles notācija + PGN sjakkspillnotasjon + PGN-schaakspelnotatie + PGN-sjakkspelnotasjon + Plik PGN notacji gry w szachy + Notação de jogo de xadrez PGN + Notație joc șah PGN + шахматная партия PGN + Šachová notácia PGN + Datoteka opomb šahovske igre PGN + Njoftim loje shahu PGN + PGN-schackpartinotation + запис гри у шахи PGN + Cách ghi lượt chơi cờ PGN + PGN 象棋游戏注记 + PGN 國際象棋棋譜 + + + + + + + + + CHM document + مستند CHM + Dakument CHM + Документ — CHM + document CHM + Dokument CHM + CHM-dokument + CHM-Dokument + CHM-dokumento + documento CHM + CHM dokumentua + CHM-asiakirja + CHM skjal + document CHM + cáipéis CHM + documento CHM + מסמך CHM + CHM dokumentum + Dokumen CHM + Documento CHM + CHM ドキュメント + CHM құжаты + CHM 문서 + CHM dokumentas + CHM dokuments + CHM-dokument + CHM-document + CHM-dokument + Dokument CHM + Documento CHM + Document CHM + документ CHM + Dokument CHM + Dokument CHM + Dokument CHM + CHM-dokument + документ CHM + Tài liệu CHM + CHM 文档 + CHM 文件 + CHM + Compiled Help Modules + + + + + + Java byte code + رمز بايت الـJava + Java bayt kodu + Bajtavy kod Java + Байт код за Java + codi byte de Java + Bajtový kód Java + Côd beit Java + Javabytekode + Java-Bytecode + συμβολοκώδικας Java + Java byte code + Java-bajtkodo + bytecode Java + Java byte-kodea + Java-tavukoodi + Java býtkota + code Java binaire + beartchód Java + byte code de Java + קוד Java byte + Java-bájtkód + Kode bita Java + Bytecode Java + Java バイトコード + Java байт коды + 자바 바이트코드 + Java baitinis kodas + Java bitu kods + Kod bait Java + Java-bytekode + Java-bytecode + Jave byte-kode + Kod bajtowy Java + 'byte-code' Java + Código compilado Java + Bytecode Java + байт-код Java + Bajtový kód Java + Datoteka bitne kode Java + Byte code Java + Јава бајтни ко̂д + Java-bytekod + Байт-код Java + Mã byte Java + Java 字节码 + Java 位元碼 + + + UNIX-compressed file + ملف يونكس-مضغوط + Skampresavany UNIX-fajł + Файл — компресиран за UNIX + fitxer comprimit UNIX + Soubor komprimovaný v Unixu + UNIX-komprimeret fil + UNIX-komprimierte Datei + αρχείο συμπιεσμένο με compress + UNIX-compressed file + UNIX-kunpremita dosiero + archivo comprimido de Unix + UNIX-en konprimitutako fitxategia + UNIX-pakattu tiedosto + UNIX-stappað fíla + fichier compressé UNIX + comhad UNIX-comhbhrúite + ficheiro comprimido de UNIX + קובץ מכווץ של UNIX + Tömörített UNIX-fájl + Berkas terkompresi UNIX + File compresso-UNIX + UNIX-compress ファイル + файл (UNIX-сығылған) + 유닉스 압축 파일 + UNIX suglaudintas failas + UNIX saspiests fails + Fail termampat-UNIX + UNIX-komprimert fil + UNIX-ingepakt bestand + UNIX-komprimert fil + Skompresowany plik systemu UNIX + ficheiro comprimido UNIX + Arquivo compactado do UNIX + Fișier comprimat UNIX + файл (UNIX-сжатый) + Súbor komprimovaný v Unixe + Skrčena Unix datoteka + File i kompresuar UNIX + UNIX-компресована датотека + UNIX-komprimerad fil + стиснений файл UNIX + Tập tin đã nén UNIX + UNIX 压缩文件 + UNIX 格式壓縮檔 + + + + + + + + Tar archive (gzip-compressed) + أرشيف Tar (مضغوط-gzip) + Archiŭ tar (gzip-skampresavany) + Архив — tar, компресиран с gzip + arxiu tar (comprimit amb gzip) + Archiv tar (komprimovaný pomocí gzip) + Tar-arkiv (gzip-komprimeret) + Tar-Archiv (gzip-komprimiert) + archivador Tar (comprimido con gzip) + Tar artxiboa (gzip-ekin konprimitua) + Tar-arkisto (gzip-pakattu) + Tar skjalasavn (gzip-stappað) + archive tar (compressée gzip) + cartlann Tar (comhbhrúite le gzip) + arquivo Tar (comprimido con gzip) + ארכיון Tar (מכווץ ע"י gzip) + Tar archívum (gzip-pel tömörítve) + Arsip Tar (terkompresi gzip) + Archivio tar (compresso con gzip) + Tar アーカイブ (gzip 圧縮) + Tar архиві (gzip-пен сығылған) + TAR 묶음 파일 (GZIP 압축) + Tar archyvas (suglaudintas su gzip) + Tar arhīvs (saspiests ar gzip) + Tar-arkiv (gzip-komprimert) + Tar-archief (ingepakt met gzip) + Tar-arkiv (pakka med gzip) + Archiwum tar (kompresja gzip) + Pacote tar (compactado com gzip) + Arhivă Tar (comprimată gzip) + архив TAR (сжатый GZIP) + Archív tar (komprimovaný pomocou gzip) + Datoteka arhiva Tar (stisnjen z gzip) + Arkiv tar (i kompresuar me gzip) + Tar-arkiv (gzip-komprimerat) + архів tar (стиснений gzip) + Kho nén tar (đã nén gzip) + Tar 归档文件(gzip 压缩) + Tar 封存檔 (gzip 格式壓縮) + + + + + + + program crash data + معلومات انهيار البرنامج + źviestki złamanaj prahramy + Данни от забиване на програма + dades de fallada de programa + Data o pádu programu + programnedbrudsdata + Daten zu Programmabsturz + δεδομένα από την κατάρρευση προγράμματος + program crash data + datumo pri kraŝo de programo + datos de cuelgue de programa + programaren kraskaduraren datuak + ohjelman kaatumistiedot + forrits sordáta + données de plantage de programme + sonraí thuairt ríomhchláir + datos de colgue do programa + מידע מקריסת תוכנה + összeomlott program adatai + data program macet + Dati crash di applicazione + プログラムクラッシュデータ + апатты аяқтаудың мәліметтері + 프로그램 비정상 종료 데이터 + programos nulūžimo duomenys + programmas avārijas dati + Data program musnah + krasjdata fra program + programma-crashgegevens + data om programkrasj + Dane awarii programu + dados de estoiro de aplicação + dados de travamento de programa + date eroare program + данные аварийного завершения + Údaje o páde programu + podatki sesutja programa + Të dhëna nga programi i bllokuar + подаци о кркљавини програма + programkraschdata + аварійні дані про програму + dữ liệu sụp đổ chương trình + 程序崩溃数据 + 程式當掉資料 + + + + + + + + + + + + + + + + + + + CPIO archive + أرشيف CPIO + CPIO arxivi + Archiŭ CPIO + Архив — CPIO + arxiu CPIO + Archiv CPIO + Archif CPIO + CPIO-arkiv + CPIO-Archiv + αρχείο CPIO + CPIO archive + CPIO-arkivo + archivador CPIO + CPIO artxiboa + CPIO-arkisto + CPIO skjalasavn + archive CPIO + cartlann CPIO + arquivo CPIO + ארכיון CPIO + CPIO-archívum + Arsip CPIO + Archivio CPIO + CPIO アーカイブ + CPIO архиві + CPIO 묶음 파일 + CPIO archyvas + CPIO arhīvs + Arkib CPIO + CPIO-arkiv + CPIO-archief + CPIO-arkiv + Archiwum CPIO + arquivo CPIO + Pacote CPIO + Arhivă CPIO + архив CPIO + Archív CPIO + Datoteka arhiva CPIO + Arkiv CPIO + CPIO архива + CPIO-arkiv + архів CPIO + Kho nén CPIO + CPIO 归档文件 + CPIO 封存檔 + + + + + + + + + + + CPIO archive (gzip-compressed) + أرشيف CPIO (مضغوط-gzip) + CPIO arxivi (gzip ilə sıxışdırılmış) + Archiŭ CPIO (gzip-skampresavany) + Архив — CPIO, компресиран с gzip + arxiu CPIO (comprimit amb gzip) + Archiv CPIO (komprimovaný pomocí gzip) + Archif CPIO (gywasgwyd drwy gzip) + CPIO-arkiv (gzip-komprimeret) + CPIO-Archiv (gzip-komprimiert) + αρχείο CPIO (συμπιεσμένο με gzip) + CPIO archive (gzip-compressed) + CPIO-arkivo (kunpremita per gzip) + archivador CPIO (comprimido con gzip) + CPIO artxiboa (gzip-ekin konprimitua) + CPIO-arkisto (gzip-pakattu) + CPIO skjalasavn (gzip-stappað) + archive CPIO (compressé gzip) + cartlann CPIO (comhbhrúite le gzip) + arquivo CPIO (comprimido con gzip) + ארכיון CPIO (מכווץ ע"י gzip) + CPIO-archívum (gzip-pel tömörítve) + Arsip CPIO (terkompresi gzip) + Archivio CPIO (compresso con gzip) + CPIO (gzip 圧縮) アーカイブ + CPIO архиві (gzip-пен сығылған) + CPIO 묶음 파일 (GZIP 압축) + CPIO archyvas (suglaudintas su gzip) + CPIO arhīvs (saspiests ar gzip) + Arkib CPIO (dimampatkan-gzip) + CPIO-arkiv (gzip-komprimert) + CPIO-archief (ingepakt met gzip) + CPIO-arkiv (gzip-pakka) + Archiwum CPIO (kompresja gzip) + arquivo CPIO (comprimido com gzip) + Pacote CPIO (compactado com gzip) + Arhivă CPIO (compresie gzip) + архив CPIO (сжатый GZIP) + Archív CPIO (komprimovaný pomocou gzip) + Datoteka arhiva CPIO (skrčena z gzip) + Arkiv CPIO (kompresuar me gzip) + CPIO архива (компресована gzip-ом) + CPIO-arkiv (gzip-komprimerat) + архів CPIO (стиснений gzip) + Kho nén CPIO (đã nén gzip) + CPIO 归档文件(gzip 压缩) + CPIO 封存檔 (gzip 格式壓縮) + + + + + C shell script + سكربت شِل سي + C qabıq skripti + Skrypt abałonki C + Скрипт — обвивка C + script en C + Skript shellu C + Sgript plisgyn C + C-skalprogram + C-Shell-Skript + πρόγραμμα εντολών φλοιού C + C shell script + skripto de C-ŝelo + script en C shell + C shell script-a + Csh-komentotiedosto + C skel boðrøð + script C shell + script bhlaosc C + script de C shell + תסריט מעטפת C + C héj-parancsfájl + Skrip shell C + Script C shell + C シェルスクリプト + C shell сценарийі + C쉘 스크립트 + C shell scenarijus + C čaulas skripts + Skrip shell C + C-skallskript + C-shellscript + C-skalskript + Skrypt powłoki C + 'script' de consola C + Script de shell C + Script C shell + сценарий C shell + Skript shellu C + Skriptna datoteka lupine C + Script shell C + C скрипта окружења + Skalskript (csh) + скрипт оболонки C + Văn lệnh trình bao C + C shell 脚本 + C shell 指令稿 + + + + + + + + + + + + + Xbase document + مستند Xbase + Dakument Xbase + Документ — Xbase + document Xbase + Dokument Xbase + Xbasedokument + Xbase-Dokument + Xbase document + Xbase-dokumento + documento Xbase + Xbase dokumentua + Xbase-asiakirja + Xbase skjal + document Xbase + cáipéis Xbase + documento Xbase + מסמך Xbase + Xbase dokumentum + Dokumen Xbase + Documento Xbase + Xbase ドキュメント + Xbase құжаты + Xbase 문서 + Xbase dokumentas + Xbase dokuments + Xbase-dokument + Xbase-document + Xbase-dokument + Dokument Xbase + Documento do Xbase + Document Xbase + документ Xbase + Dokument Xbase + Dokument Xbase + Dokument Xbase + Xbase-dokument + документ Xbase + Tài liệu Xbase + Xbase 文档 + Xbase 文件 + + + + + + + + ECMAScript program + برنامج ECMAScript + Prahrama ECMAScript + Програма — ECMAScript + programa ECMAScript + Program ECMAScript + ECMA-program + ECMAScript-Programm + programa en ECMAScript + ECMAScript programa + ECMAScript-ohjelma + ECMAScript forrit + programme ECMAScript + ríomhchlár ECMAScript + programa en ECMAScript + תכנית EMCAScript + ECMAScript program + Program ECMAScript + Programma ECMAScript + ECMAScript プログラム + ECMAScript программасы + ECMA스크립트 프로그램 + ECMAScript programa + ECMAScript programma + ECMAScript-program + ECMAScript-programma + ECMAScript-program + Pogram ECMAScript + Programa ECMAScript + Program ECMAScript + программа ECMAScript + Program ECMAScript + Programska datoteka ECMAScript + Program ECMAScript + ECMAScript-program + програма мовою ECMAScript + Chương trình ECMAScript + ECMAScript 程序 + ECMAScript 程式 + + + + + + + Dreamcast ROM + Dreamcast ROM + Dreamcast ROM + ROM — Dreamcast + ROM de Dreamcast + ROM pro Dreamcast + Dreamcast-rom + Dreamcast-ROM + εικόνα μνήμης ROM Dreamcast + Dreamcast ROM + Dreamcast-NLM + ROM de Dreamcast + Dreamcast-en ROM + Dreamcast-ROM + Dreamcast ROM + ROM Dreamcast + ROM Dreamcast + ROM de Dreamcast + ROM של Dreamcast + Dreamcast ROM + Memori baca-saja Dreamcast + ROM Dreamcast + Dreamcast ROM + Dreamcast ROM + 드림캐스트 롬 + Dreamcast ROM + Dreamcast ROM + ROM Dreamcast + Dreamcast-ROM + Dreamcast-ROM + Dreamcast-ROM + Plik ROM konsoli Dreamcast + ROM Dreamcast + ROM do Dreamcast + ROM Dreamcast + Dreamcast ROM + ROM pre Dreamcast + Bralni pomnilnik Dreamcast + ROM Dreamcast + Dreamcast ROM + Dreamcast-rom + ППП Dreamcast + ROM Dreamcast + Dreamcast ROM + Dreamcast ROM + + + + + Nintendo DS ROM + Nintendo DS ROM + Nintendo DS ROM + ROM — Nintendo DS + ROM de Nintendo DS + ROM pro Nintendo DS + Nintendo DS-rom + Nintendo-DS-ROM + ROM de Nintendo DS + Nintendo DS-ko ROMa + Nintendo DS-ROM + Nintendo DS ROM + ROM Nintendo DS + ROM Nintendo DS + ROM de Nintendo DS + ROM של Nintendo + Nintendo DS ROM + Memori baca-saja Nintendo DS + ROM Nintendo DS + Nintendo DS ROM + Nintendo DS ROM + 닌텐도 DS 롬 + Nintendo DS ROM + Nintendo DS ROM + Nintendo DS-ROM + Nintendo-DS-ROM + Nintendo DS-ROM + Plik ROM konsoli Nintendo DS + ROM do Nintendo DS + ROM Nintendo DS + Nintendo DS ROM + ROM pre Nintendo DS + Bralni pomnilnik Nintendo DS + ROM Nintendo DS + Nintendo DS-rom + ППП Nintendo + ROM DS Nintendo + Nintendo DS ROM + 任天堂 DS ROM + + + + + Debian package + حزمة ديبيان + Debian paketi + Pakunak Debian + Пакет — Debian + paquet Debian + Balíček Debianu + Pecyn Debian + Debianpakke + Debian-Paket + πακέτο Debian + Debian package + Debian-pakaĵo + paquete Debian + Debian paketea + Debian-paketti + Debian pakki + paquet Debian + pacáiste Debian + paquete de Debian + חבילת דביאן + Debian-csomag + Paket Debian + Pacchetto Debian + Debian パッケージ + Debian дестесі + 데비안 패키지 + Debian paketas + Debian pakotne + Pakej Debian + Debian pakke + Debian-pakket + Debian pakke + Pakiet Debiana + pacote Debian + Pacote Debian + Pachet Debian + пакет Debian + Balíček Debianu + Datoteka paketa Debian + Paketë Debian + Debian пакет + Debianpaket + пакунок Debian + Gói Debian + Debian 软件包 + Debian 套件 + + + + + + + + + + + Qt Designer file + ملف Qt Designer + Fajł Qt Designer + Файл — Qt Designer + fitxer de Qt Designer + Soubor Qt Designer + Qt Designer-fil + Qt-Designer-Datei + αρχείο Qt Designer + Qt Designer file + dosiero de Qt Designer + archivo de Qt Designer + Qt Designer Fitxategia + Qt Designer -tiedosto + Qt Designer fíla + fichier Qt Designer + comhad Qt Designer + ficheiro de Qt Designer + קובץ של Qt Designer + Qt Designer-fájl + Berkas Qt Designer + File Qt Designer + Qt Designer ファイル + Qt Designer файлы + Qt 디자이너 파일 + Qt Designer failas + Qt Designer fails + Fail Qt Designer + Qt Designer-fil + Qt Designer-bestand + Qt Designer-fil + Plik Qt Designer + ficheiro do Qt Designer + Arquivo do Qt Designer + Fișier Qt Designer + файл Qt Designer + Súbor Qt Designer + Datoteka Qt Designer + File Qt Designer + Qt Designer датотека + Qt Designer-fil + файл програми Qt-дизайнер + Tập tin thiết kế Qt Designer + Qt Designer 文件 + Qt Designer 檔案 + + + + + + + + + + Qt Markup Language file + Файл — Qt Markup + fitxer de llenguatge de marcadors Qt + Soubor Qt Markup Language + Qt-Auszeichnungssprachendatei + Archivo de lenguaje de marcado Qt + fichier Qt Markup Language + ficheiro de linguaxe de marcado Qt + קובץ שפת סימון של Qt + Qt jelölőnyelvű fájl + Berkas Bahasa Markup Qt + File Qt Markup Language + Qt マークアップ言語ファイル + Qt Markup Language файлы + Qt 마크업 언어 파일 + Qt marķēšanas valodas fails + Plik języka znaczników Qt + файл Qt Markup Language + Datoteka označevalnega jezika Qt + файл мови розмітки Qt + Qt + Qt 標記語言檔 + + + + + + + desktop configuration file + ملف تضبيط سطح المكتب + kanfihuracyjny fajł asiarodździa + Файл с информация за работния плот + fitxer de configuració d'escriptori + Soubor nastavení pracovní plochy + skrivebordskonfigurationsfil + Desktop-Konfigurationsdatei + ρυθμίσεις επιφάνεια εργασίας + desktop configuration file + dosiero de agordoj de labortablo + archivo de configuración del escritorio + Mahaigainaren konfigurazio-fitxategia + työpöydän asetustiedosto + skriviborðssamansetingarfíla + fichier de configuration desktop + comhad chumraíocht deisce + ficheiro de configuración de escritorio + קובץ הגדרות של שולחן העבודה + asztalbeállító fájl + berkas konfigurasi destop + File configurazione desktop + デスクトップ設定ファイル + жұмыс үстел баптаулар файлы + 데스크톱 설정 파일 + darbastalio konfigūracijos failas + darbvirsmas konfigurācijas fails + Fail konfigurasi desktop + konfigurasjonsfil for skrivebordet + bureaublad-configuratiebestand + skrivebordsoppsettfil + Plik konfiguracji środowiska + ficheiro de configuração de área de trabalho + arquivo de configuração de área de trabalho + fișier de configurare al desktopului + файл настроек рабочего стола + Súbor nastavení pracovnej plochy + nastavitvena datoteka namizja + File konfigurimi desktop + датотека за подешавања радне површи + skrivbordskonfigurationsfil + файл конфігурації стільниці + tập tin cấu hình môi trường + 桌面配置文件 + 桌面組態檔 + + + + + + + + + + + + + + + FictionBook document + مستند FictionBook + Документ — FictionBook + document FictionBook + Dokument FictionBook + FictionBook-dokument + FictionBook-Dokument + FictionBook-dokumento + documento FictionBook + FictionBook dokumentua + FictionBook-asiakirja + FictionBook skjal + document FictionBook + cáipéis FictionBook + documento de FictionBook + מסמך FictionBook + FictionBook-dokumentum + Dokumen FictionBook + Documento FictionBook + FictionBook ドキュメント + FictionBook құжаты + FictionBook 문서 + FictionBook dokumentas + FictionBook dokuments + FictionBook-document + Dokument FictionBook + Documento FictionBook + Document FictionBook + документ FictionBook + Dokument FictionBook + Dokument FictionBook + FictionBook-dokument + документ FictionBook + Tài liệu FictionBook + FictionBook 文档 + FictionBook 文件 + + + + + + + + + + Dia diagram + خطاطة Dia + Dia diaqramı + Dyjahrama Dia + Диаграма — Dia + diagrama de Dia + Diagram Dia + Diagram Dia + Dia-diagram + Dia-Diagramm + διάγραμμα Dia + Dia diagram + Dia-diagramo + diagrama de Dia + Dia diagrama + Dia-kaavio + Dia ritmynd + diagramme Dia + léaráid Dia + diagrama de Dia + גרף של Dia + Dia-diagram + Diagram Dia + Diagramma Dia + Dia ダイアグラム + Dia диаграммасы + Dia 도표 + Dia diagrama + Dia diagramma + Diagram Dia + Dia-diagram + Dia-diagram + Dia diagram + Diagram Dia + diagrama Dia + Diagrama do Dia + Diagramă Dia + диаграмма Dia + Diagram Dia + Datoteka diagrama Dia + Diagramë Dia + Диа дијаграм + Dia-diagram + діаграма Dia + Biểu đồ Dia + Dia 图表 + Dia 圖表 + + + + + + + + + + Dia shape + شكل Dia + Фигура — Dia + forma del Dia + Tvary Dia + Dia-figur + Dia-Form + forma de Dia + Dia-ren forma + Dia skapur + forme Dia + cruth Dia + forma de Dia + צורה של Dia + Dia alakzat + Shape Dia + Sagoma Dia + Dia 図形 + Dia сызбасы + Dia 그림 + Dia forma + Dia forma + Kształt Dia + Figură Dia + фигура Dia + Datoteka oblik Dia + Dia-figur + форма Dia + Dia 形状 + Dia 形狀 + + + + + + + + + + TeX DVI document + مستند TeX DVI + Dakument TeX DVI + Документ — TeX DVI + document TeX DVI + Dokument TeX DVI + TeX DVI-dokument + TeX-DVI-Dokument + έγγραφο TeX DVI + TeX DVI document + DVI-dokumento de TeX + documento TeX DVI + TeX DVI dokumentua + TeX DVI -asiakirja + TeX DVI skjal + document TeX DVI + cáipéis DVI TeX + documento TeX DVI + מסמך מסוג TeX DVI + TeX DVI-dokumentum + Dokumen TeX DVI + Documento TeX DVI + TeX DVI ドキュメント + TeX DVI құжаты + TeX DVI 문서 + TeX DVI dokumentas + TeX DVI dokuments + Dokumen TeX DVI + TeX DVI-dokument + TeX DVI-document + TeX DVI-dokument + Dokument TeX DVI + documento TeX DVI + Documento TeX DVI + Document Tex DVI + документ TeX DVI + Dokument TeX DVI + Dokument TeX DVI + Dokument TeX DVI + ТеХ ДВИ документ + TeX DVI-dokument + документ TeX DVI + Tài liệu DVI Tex + TeX DVI 文档 + TeX DVI 文件 + DVI + Device independent file format + + + + + + + + Enlightenment theme + سمة Enlightenment + Enlightenment örtüyü + Matyŭ Enlightenment + Тема — Enlightenment + tema d'Enlightenment + Motiv Enlightenment + Thema Enlightenment + Enlightenmenttema + Enlightenment-Thema + Θέμα Enlightenment + Enlightenment theme + etoso de Enlightenment + tema de Enlightenment + Enlightenment gaia + Enlightenment-teema + Enlightenment tema + thème Enlightenment + téama Enlightenment + tema de Enlightenment + ערכת נושא של Enlightenment + Enlightenment-téma + Tema Enlightenment + Tema Enlightenment + Enlightenment テーマ + Enlightenment темасы + 인라이트먼트 테마 + Enlightenment tema + Enlightenment tēma + Tema Enlightenment + Enlightenment tema + Enlightenment-thema + Enlightenment-tema + Motyw Enlightenment + tema Enlightenment + Tema do Enlightenment + Temă Enlightenment + тема Enlightenment + Motív Enlightenment + Datoteka teme Enlightenment + Tema Enlightenment + Enlightenment тема + Enlightenment-tema + тема Enlightenment + Sắc thái Enlightenment + Enlightenment 主题 + Enlightenment 佈景主題 + + + + Egon Animator animation + تحريكة محرك Egon + Animacyja Egon Animator + Анимация — Egon Animator + animació d'Egon Animator + Animace Egon Animator + Egon Animator-animation + Egon-Animator-Animation + κινούμενα σχέδια Egon Animator + Egon Animator animation + animacio de Egon Animator + animación de Egon Animator + Egon Animator-eko animazioa + Egon Animator -animaatio + Egon Animator teknimyndagerð + animation Egon Animator + beochan Egon Animator + animación de Egon Animator + אנימצייה של Egon Animator + Egon Animator-animáció + Animasi Egon Animator + Animazione Egon Animator + Egon Animator アニメーション + Egon Animator анимациясы + Egon 애니메이터 + Egon Animator animacija + Egon Animator animācija + Animasi Egon Animator + Egon animator-animasjon + Egon Animator-animatie + Egon Animator-animasjon + Animacja Egon Animator + animação Egon Animator + Animação do Egon Animator + Animație Egon Animator + анимация Egon Animator + Animácia Egon Animator + Datoteka animacije Egon Animator + Animim Egon Animator + Егон аниматор анимација + Egon Animator-animering + анімація Egon Animator + Hoạt ảnh Egon Animator + Egon Animator 动画 + Egon Animator 動畫 + + + + + executable + تنفيذي + vykonvalny fajł + Изпълним файл + executable + Spustitelný soubor + kørbar + Programm + εκτελέσιμο + executable + plenumebla + ejecutable + exekutagarria + suoritettava ohjelma + inningarfør + exécutable + comhad inrite + executábel + קובץ הרצה + futtatható + dapat dieksekusi + Eseguibile + 実行ファイル + орындалатын + 실행파일 + vykdomasis failas + izpildāmais + Bolehlaksana + kjørbar + uitvoerbaar bestand + køyrbar + Program + executável + executável + executabil + исполняемый + Spustiteľný súbor + izvedljiva datoteka + I ekzekutueshëm + извршна + körbar fil + виконуваний файл + thực hiện được + 可执行文件 + 可執行檔 + + + + + + + + + + + + + + + + + + + + + FLTK Fluid file + ملف FLTK Fluid + Fajł FLTK Fluid + Интерфейс — FLTK Fluid + fitxer Fluid FLTK + Soubor FLTK Fluid + FLTK Fluid-fil + FLTK-Fluid-Datei + archivo FLTK Fluid + FLTK Fluid fitxategia + FLTK Fluid -tiedosto + FLTK Fluid fíla + fichier Fluid FLTK + comhad FLTK Fluid + ficheiro FLTK Fluid + קובץ FLTK Fluid + FLTK Fluid fájl + Berkas FLTK Fluid + File FLTK Fluid + FLTK Fluid ファイル + FLTK Fluid файлы + FLTK 파일 + FLTK Fluid failas + FLTK Fluid fails + FLTK Fluid-fil + FLTK FLUID-bestand + FLTK Fluid-fil + Plik Fluid FLTK + Arquivo Fluid do FLTK + Fișier FLTK Fluid + файл FLTK Fluid + Súbor FLTK Fluid + Datoteka FLTK Fluid + File FLTK Fluid + FLTK Fluid-fil + файл FLTK Fluid + Tập tin Fluid FLTK + FLTK 流体文档 + FLTK Fluid 檔 + + + + + + + + + Postscript type-1 font + خط Postscript type-1 + Šryft Postscript type-1 + Шрифт — Postscript Type 1 + tipus de lletra Postscript type-1 + Písmo Postscript type-1 + PostScript type-1-skrifttype + Postscript-Typ-1-Schrift + tipografía PostScript tipo-1 + PostScript type-1 letra-tipoa + PostScript tyyppi-1 -asiakirja + Postscript type-1 stavasnið + police Postscript Type 1 + cló Postscript type-1 + tipo de letra PostScript tipo-1 + גופן של Postscript type-1 + Postscript type-1 betűkészlet + Fonta tipe-1 Postscript + Tipo carattere Postscript type-1 + PostScript type-1 フォント + Postscript type-1 қарібі + 포스트스크립트 Type-1 글꼴 + Postscript type-1 šriftas + Postscript 1-tipa fonts + Postscript type-1 skrift + PostScript type-1-lettertype + PostScript type 1-skrifttype + Czcionka PostScript Type-1 + Fonte PostScript tipo-1 + Font Postscript type-1 + шрифт PostScript Type-1 + Písmo Postscript type-1 + Datoteka pisave Postscript vrste-1 + Lloj gërmash Postscript type-1 + Postscript type-1-typsnitt + шрифт Postscript type-1 + Phông kiểu 1 PostScript + Postscript type-1 字体 + Postscript type-1 字型 + + + + + + + + + + + + + + + + Adobe font metrics + مقاييس خط أدوبي + Adobe yazı növü metrikləri + Metryka šryftu Adobe + Шрифтова метрика — Adobe + mètrica de tipus de lletra Adobe + Metrika písma Adobe + Metrigau Ffont Adobe + Adobe skrifttypefil + Adobe-Schriftmetriken + μετρικά γραμματοσειράς Adobe + Adobe font metrics + metrikoj de Adobe-tiparo + métricas de tipografía Adobe + Adobe letra-tipoen neurriak + Adobe-kirjasinmitat + métriques de police Adobe + meadarachtaí cló Adobe + métricas de fonte de Adobe + מדדי גופן של Adobe + Adobe-betűmetrika + Metrik fonta Adobe + Metriche tipo carattere Adobe + Adobe フォントメトリック + Adobe қаріп метрикалары + 어도비 글꼴 메트릭스 + Adobe šriftų metrika + Adobe fonta metrika + Metrik font Adobe + Adobe skrifttypefil + Adobe-lettertype-metrieken + Adobe skrifttypemetrikk + Metryka czcionki Adobe + métrica de tipos de letra Adobe + Métricas de fonte Adobe + Dimensiuni font Adobe + метрика шрифта Adobe + Metrika písma Adobe + Matrika pisave Adobe + Metrik lloj gërmash Adobe + Adobe метрика фонта + Adobe-typsnittsmetrik + метрики шрифту Adobe + Cách đo phông chữ Adobe + Adobe 字体参数 + Adobe 字型描述檔 + + + + + BDF font + خط BDF + BDF yazı növü + Šryft BDF + Шрифт — BDF + tipus de lletra BDF + Písmo BDF + Ffont BDF + BDF-skrifttype + BDF-Schrift + γραμματοσειρά BDF + BDF font + BDF-tiparo + tipografía BDF + BDF letra-tipoa + BDF-kirjasin + BDF stavasnið + police BDF + cló BDF + tipo de fonte BDF + גופן BDF + BDF-betűkészlet + Fonta BDF + Tipo carattere BDF + BDF フォント + BDF қарібі + BDF 글꼴 + BDF šriftas + BDF fonts + Font BDF + BDF-skrifttype + BDF-lettertype + BDF-skrifttype + Czcionka BDF + tipo de letra BDF + Fonte BDF + Font BDF + шрифт BDF + Písmo BDF + Datoteka pisave BDF + Lloj gërme BDF + BDF фонт + BDF-typsnitt + шрифт BDF + Phông chữ BDF + BDF 字体 + BDF 字型 + + + + + + + + DOS font + خط DOS + DOS yazı növü + Šryft DOS + Шрифт — DOS + tipus de lletra DOS + Písmo pro DOS + Ffont DOS + DOS-skrifttype + DOS-Schrift + γραμματοσειρά DOS + DOS font + DOS-tiparo + tipografía DOS + DOS letra-tipoa + DOS-kirjasin + DOS stavasnið + police DOS + cló DOS + tipo de fonte de DOS + גופן DOS + DOS-betűkészlet + Fonta DOS + Tipo carattere DOS + DOS フォント + DOS қарібі + 도스 글꼴 + DOS šriftas + DOS fonts + Font DOS + DOS-skrifttype + DOS-lettertype + DOS-skrifttype + Czcionka DOS + tipo de letra DOS + Fonte do DOS + Font DOS + шрифт DOS + Písmo pre DOS + Datoteka pisave DOS + Gërmë DOS + DOS фонт + DOS-typsnitt + шрифт DOS + Phông chữ DOS + DOS 字体 + DOS 字型 + + + + + + + + + Adobe FrameMaker font + خط أدوبي الصانع للإطارات + Adobe FrameMaker yazı növü + Šryft Adobe FrameMaker + Шрифт — Adobe FrameMaker + tipus de lletra d'Adobe FrameMaker + Písmo Adobe FrameMaker + Ffont Adobe FrameMaker + Adobe FrameMaker-skrifttype + Adobe-FrameMaker-Schrift + γραμματοσειρά Adobe FrameMaker + Adobe FrameMaker font + Tiparo de Adobe FrameMaker + tipografía de Adobe FrameMaker + Adobe FrameMaker-en letra-tipoa + Adobe FrameMaker -kirjasin + Adobe FrameMaker stavasnið + police Adobe FrameMaker + cló Adobe FrameMaker + tipo de fonte de Adobe FrameMaker + גופן של Adobe FrameMaker + Adobe FrameMaker-betűkészlet + Fonta Adobe FrameMaker + Tipo carattere Adobe FrameMaker + Adobe FrameMaker フォント + Adobe FrameMaker қарібі + 어도비 프레임메이커 글꼴 + Adobe FrameMaker šriftas + Adobe FrameMaker fonts + Font Adobe FrameMaker + Adobe FrameMaker skrifttype + Adobe FrameMaker-lettertype + Adobe FrameMaker-skrifttype + Czcionka Adobe FrameMaker + tipo de letra Adobe FrameMaker + Fonte do Adobe FrameMaker + Font Adobe FrameMaker + шрифт Adobe FrameMaker + Písmo Adobe FrameMaker + Datoteka pisave Adobe FrameMaker + Gërma Adobe FrameMaker + Adobe FrameMaker фонт + Adobe FrameMaker-typsnitt + шрифт Adobe FrameMaker + Phông chữ Adobe FrameMaker + Adobe FrameMaker 字体 + Adobe FrameMaker 字型 + + + + + + + LIBGRX font + خط LIBGRX + LIBGRX yazı növü + Šryft LIBGRX + Шрифт — LIBGRX + tipus de lletra LIBGRX + Písmo LIBGRX + Ffont LIBGRX + LIBGRX-skrifttype + LIBGRX-Schrift + γραμματοσειρά LIBGRX + LIBGRX font + LIBGRX-tiparo + tipografía LIBGRX + LIBGRX letra-tipoa + LIBGRX-kirjasin + LIBGRX stavasnið + police LIBGRX + cló LIBGRX + tipo de fonte en LIBGRX + גופן LIBGRX + LIBGRX-betűkészlet + Fonta LIBGRX + Tipo carattere LIBGRX + LIBGRX フォーマット + LIBGRX қарібі + LIBGRX 글꼴 + LIBGRX šriftas + LIBGRX fonts + Font LIBGRX + LIBGRX-skrifttype + LIBGRX-lettertype + LIBGRX skrifttype + Czcionka LIBGRX + tipo de letra LIBGRX + Fonte LIBGRX + Font LIBGRX + шрифт LIBGRX + Písmo LIBGRX + Datoteka pisave LIBGRX + Lloj gërme LIBGRX + LIBGRX фонт + LIBGRX-typsnitt + шрифт LIBGRX + Phông chữ LIBGRX + LIBGRX 字体 + LIBGRX 字型 + + + + + + + Linux PSF console font + خط كونسول PSF لينكس + Linux PSF konsol yazı növü + Kansolny šryft PSF dla Linuksa + Шрифт — PSF, за конзолата на Линукс + tipus de lletra de consola Linux PSF + Písmo PSF pro konzolu Linuxu + Ffont Linux PSF + Linux PSF-konsolskrifttype + Linux-PSF-Konsolenschrift + γραμματοσειρά κονσόλας PSF Linux + Linux PSF console font + PSF-tiparo de Linux-konzolo + tipografía de consola Linux PSF + Linux PSF kontsolako letra-tipoa + Linux PSF -konsolikirjasin + Linux PSF stýristøðs stavasnið + police console Linux PSF + cló chonsól Linux PSF + tipo de fonte de consola Linux PSF + גופן לקונסול מסוג Linux PSF + Linux PSF konzolos betűkészlet + Fonta konsol Linux PSF + Tipo carattere console Linux PSF + Linux PSF コンソールフォント + Linux PSF консольдік қарібі + 리눅스 PSF 콘솔 글꼴 + Linux PSF konsolės šriftas + Linux PSF konsoles fonts + Font konsol PSF Linux + Linux PSF konsollskrifttype + Linux PSF-console-lettertype + Linux PSF konsoll-skrifttype + Czcionka konsoli PSF Linux + tipo de letra de consola Linux PSF + Fonte de console Linux PSF + Font consolă Linux PSF + консольный шрифт Linux PSF + Písmo PSF pre konzolu Linuxu + Datoteka pisave konzole Linux PSF + Lloj gërme për konsolë Linux PSF + Линукс PSF конзолни фонт + Linux PSF-konsolltypsnitt + консольний шрифт Linux PSF + Phông chữ bàn giao tiếp PSF Linux + Linux PSF 控制台字体 + Linux PSF console 字型 + + + + + + + + Linux PSF console font (gzip-compressed) + خط كونسول PSF لينكس (مضغوط-gzip) + Kansolny šryft PSF dla Linuksa (gzip-skampresavany) + Шрифт — Linux PSF, компресиран с gzip + tipus de lletra de consola Linux PSF (comprimida amb gzip) + Písmo PSF pro konzolu Linuxu (komprimované pomocí gzip) + Linux PSF-konsolskrifttype (gzip-komprimeret) + Linux-PSF-Konsolenschrift (gzip-komprimiert) + tipografía de consola Linux PSF (comprimida con gzip) + Linux PSF kontsolako letra-tipoa (gzip-ekin konprimitua) + Linux PSF -konsolikirjasin (gzip-pakattu) + Linux PSF stýristøðs stavasnið (gzip-stappað) + police console Linux PSF (compressée gzip) + cló chonsól Linux PSF (comhbhrúite le gzip) + tipo de fonte de consola Linux PSF (comprimida con gzip) + גופן לקונסול מסוג Linux PSF (מכווץ ע"י gzip) + Linux PSF konzolos betűkészlet (gzip-tömörítésű) + Fonta konsol Linux PSF (terkompresi gzip) + Tipo carattere console Linux PSF (compresso con gzip) + Linux PSF コンソールフォント (gzip 圧縮) + Linux PSF консольдік қарібі (gzip-пен сығылған) + 리눅스 PSF 콘솔 글꼴 (GZIP 압축) + Linux PSF konsolės šriftas (suglaudintas su gzip) + Linux PSF konsoles fonts (saspiests ar gzip) + Linux PSF konsollskrifttype (gzip-komprimert) + Linux PSF-console-lettertype (ingepakt met gzip) + Linux PSF konsoll-skrifttype (gzip-pakka) + Czcionka konsoli PSF Linux (kompresja gzip) + Fonte de console Linux PSF (compactada com gzip) + Font consolă Linux PSF (compresie gzip) + консольный шрифт Linux PSF (сжатый gzip) + Písmo PSF pre konzolu Linuxu (komprimované pomocou gzip) + Datoteka pisave konzole Linux PSF (skrčena z gzip) + Lloj gërme për konsolë Linux PSF (komresuar me gzip) + Linux PSF-konsolltypsnitt (gzip-komprimerat) + консольний шрифт Linux PSF (стиснений gzip) + Phông chữ bàn giao tiếp PSF Linux (đã nén gzip) + Linux PSF 控制台字体(gzip 压缩) + Linux PSF console 字型 (gzip 格式壓縮) + + + + + + PCF font + خط PCF + PCF yazı növü + Šryft PCF + Шрифт — PCF + tipus de lletra PCF + Písmo PCF + Ffont PCF + PCF-skrifttype + PCF-Schrift + γραμματοσειρά PCF + PCF font + PCF-tiparo + tipografía PCF + PCF letra-tipoa + PCF-kirjasin + PCF stavasnið + police PCF + cló PCF + tipo de letra PCF + פונט PCF + PCF-betűkészlet + Fonta PCF + Tipo carattere PCF + PCF フォント + PCF қарібі + PCF 글꼴 + PCF šriftas + PCF fonts + Font PCF + PCF-skrifttype + PCF-lettertype + PCF-skrifttype + Czcionka PCF + tipo de letra PCF + Fonte PCF + Font PCF + шрифт PCF + Písmo PCF + Datoteka pisave PCF + Gërma PCF + PCF фонт + PCF-typsnitt + шрифт PCF + Phông chữ PCF + PCF 字体 + PCF 字型 + + + + + + + + + + OpenType font + خط OpenType + OpenType yazı növü + Šryft OpenType + Шрифт — OpenType + tipus de lletra OpenType + Písmo OpenType + Ffont OpenType + OpenType-skrifttype + OpenType-Schrift + γραμματοσειρά OpenType + OpenType font + OpenType-tiparo + tipografía de OpenType + OpenType letra-tipoa + OpenType-kirjasin + OpenType stavasnið + police OpenType + cló OpenType + tipo de fonte OpenType + גופן של OpenType + OpenType-betűkészlet + Fonta OpenType + Tipo carattere OpenType + OpenType フォント + OpenType қарібі + 오픈타입 글꼴 + OpenType šriftas + OpenType fonts + Font OpenType + OpenType-skrifttype + OpenType-lettertype + OpenType-skrifttype + Czcionka OpenType + tipo de letra OpenType + Fonte OpenType + Font OpenType + шрифт OpenType + Písmo OpenType + Datoteka pisave OpenType + Gërma OpenType + OpenType фонт + OpenType-typsnitt + шрифт OpenType + Phông chữ OpenType + OpenType 字体 + OpenType 字型 + + + + + + + + Speedo font + خط Speedo + Speedo yazı növü + Šryft Speedo + Шрифт — Speedo + tipus de lletra Speedo + Písmo Speedo + Ffont Speedo + Speedoskrifttype + Speedo-Schrift + γραμματοσειρά Speedo + Speedo font + Speedo-tiparo + tipografía Speedo + Speedo letra-tipoa + Speedo-kirjasin + Speedo stavasnið + police Speedo + cló Speedo + tipo de letra Speedo + גופן של Speedo + Speedo-betűkészlet + Fonta Speedo + Tipo carattere Speedo + Speedo フォント + Speedo қарібі + Speedo 글꼴 + Speedo šriftas + Speedo fonts + Font Speedo + Speedo-skrifttype + Speedo-lettertype + Speedo-skrifttype + Czcionka Speedo + tipo de letra Speedo + Fonte Speedo + Font Speedo + шрифт Speedo + Písmo Speedo + Datoteka pisave Speedo + Gërma Speedo + Speedo фонт + Speedo-typsnitt + шрифт Speedo + Phông chữ Speedo + Speedo 字体 + Speedo 字型 + + + + + + + + SunOS News font + خط SunOS News + SunOS News yazı növü + Šryft SunOS News + Шрифт — SunOS News + tipus de lletra SunOS News + Písmo SunOS News + Ffont SunOS News + SunOS News-skrifttype + SunOS-News-Schrift + γραμματοσειρά SunOS News + SunOS News font + tiparo de SunOS News + tipografía SunOS News + SunOs News letra-tipoa + SunOS News -kirjasin + SunOS News stavasnið + police SunOS News + cló SunOS News + tipo de letra SunOS News + גופן של SunOS News + SunOS News-betűkészlet + Fonta SunOS News + Tipo carattere SunOS News + SunOS News フォント + SunOS News қарібі + SunOS News 글꼴 + SunOS News šriftas + SunOS News fonts + Font News SunOS + SunOS News-skrifttype + SunOS News-lettertype + SunOS NEWS-skrifttype + Czcionka SunOS News + tipo de letra SunOS News + Fonte SunOS News + Font SunOS News + шрифт SunOS News + Písmo SunOS News + Datoteka pisave SunOS News + Gërma SunOS News + SunOS News фонт + SunOS News-typsnitt + шрифт SunOS News + Phông chữ SunOS News + SunOS News 字体 + SunOS News 字型 + + + + + + + + + TeX font + خط TeX + TeX yazı növü + Šryft TeX + Шрифт — TeX + tipus de lletra TeX + Písmo TeX + Ffont TeX + TeX-skrifttype + TeX-Schrift + γραμματοσειρά TeX + TeX font + TeX-tiparo + tipografía de TeX + TeX letra-tipoa + TeX-kirjasin + TeX stavasnið + police TeX + cló TeX + tipo de letra de TeX + גופן TeX + TeX-betűkészlet + Fonta TeX + Tipo carattere TeX + TeX フォント + TeX қарібі + TeX 글꼴 + TeX šriftas + TeX fonts + Font TeX + TeX-skrift + TeX-lettertype + TeX-skrifttype + Czcionka TeX + tipo de letra TeX + Fonte TeX + Font TeX + шрифт TeX + Písmo TeX + Datoteka pisave TeX + Gërma TeX + ТеХ фонт + TeX-typsnitt + шрифт TeX + Phông chữ TeX + TeX 字体 + TeX 字型 + + + + + + + + + TeX font metrics + مقاييس خط TeX + TeX yazı növü metrikləri + Metryka šryftu TeX + Шрифтова метрика — TeX + mètrica de tipus de lletra TeX + Metrika písma TeX + Metrigau Ffont TeX + TeX-skrifttypeinformation + TeX-Schriftmetriken + μετρικά γραμματοσειράς TeX + TeX font metrics + metrikoj de TeX-tiparo + métricas de tipografía de TeX + TeX letra-tipoen neurriak + TeX-kirjasinmitat + métriques de police TeX + meadarachtaí cló TeX + Métricas de tipo de letra de TeX + גופן מטריקס של TeX + TeX-betűmetrika + Fonta metrik TeX + Metriche tipo carattere TeX + TeX フォントメトリック + TeX қаріп метрикалары + Tex 글꼴 메트릭스 + TeX šriftų metrika + TeX fonta metrikas + Metrik font TeX + TeX skrifttypemetrikk + TeX-lettertype-metrieken + TeX skrifttypemetrikk + Metryki czcionki TeX + métricas de tipo de letra TeX + Métrica de fonte TeX + Dimensiuni font TeX + метрика шрифта TeX + Metrika písma TeX + Matrika pisave Tex + Gërma TeX metrics + ТеХ метрика фонта + TeX-typsnittsmetrik + метрики шрифту TeX + Cách đo phông chữ TeX + TeX 字体参数 + TeX 字型描述檔 + + + + + + + + TrueType font + خط TrueType + Šryft TrueType + Шрифт — TrueType + tipus de lletra TrueType + Písmo TrueType + TrueType-skrifttype + TrueType-Schrift + γραμματοσειρά TrueType + TrueType font + TrueType-tiparo + tipografía TrueType + TrueType letra-tipoa + TrueType-kirjasin + TrueType stavasnið + police Truetype + cló TrueType + tipo de letra TrueType + גופן מסוג TrueType + TrueType-betűkészlet + Fonta TrueType + Tipo carattere TrueType + TrueType フォント + TrueType қарібі + 트루타입 글꼴 + TrueType šriftas + TrueType fonts + Font TrueType + TrueType-skrift + TrueType-lettertype + TrueType-skrifttype + Czcionka TrueType + tipo de letra TrueType + Fonte TrueType + Font TrueType + шрифт TrueType + Písmo TrueType + Datoteka pisave TrueType + Lloj gërme TrueType + Трутајп фонт + Truetype-typsnitt + шрифт TrueType + Phông chữ TrueType + TrueType 字体 + TrueType 字型 + + + + + + + + + + + TrueType XML font + خط TrueType XML + Šryft TrueType XML + Шрифт — TrueType XML + tipus de lletra TrueType XML + Písmo TrueType XML + TrueType XML-skrifttype + TrueType-XML-Schrift + tipografía TrueType XML + TrueType XML letra-tipoa + TrueType-XML-kirjasin + TrueType XML stavasnið + police Truetype XML + cló XML TrueType + tipo de letra TrueType XML + גופן XML מסוג TrueType + TrueType XML betűkészlet + Fonta TrueType XML + Tipo carattere TrueType XML + TrueType XML フォント + TrueType XML қарібі + 트루타입 XML 글꼴 + TrueType XML šriftas + TrueType XML fonts + TrueType XML-skrift + TrueType XML-lettertype + TrueType XML-skrifttype + Czcionka TrueType XML + Fonte TrueType XML + Font XML TrueType + шрифт TrueType XML + Písmo TrueType XML + Datoteka pisave TrueType XML + Lloj gërme TrueType XML + Truetype XML-typsnitt + шрифт TrueType XML + Phông chữ XML TrueType + TrueType XML 字体 + TrueType XML 字型 + + + + + + + + + V font + خط V + V yazı növü + Šryft V + Шрифт — V + tipus de lletra V + Písmo V + Ffont V + V-skrifttype + V-Schrift + γραμματοσειρά V + V font + V-tiparo + tipografía V + V letra-tipoa + V-kirjasin + V stavasnið + police V + cló V + tipo de letra V + גופן של V + V-betűkészlet + Fonta V + Tipo carattere V + V フォント + V font қарібі + V 글꼴 + V šriftas + V fonts + Font V + V-skrift + V-lettertype + V-skrifttype + Czcionka V + tipo de letra V + Fonte V + Font V + шрифт V font + Písmo V + Datoteka pisave V + Gërmë V + V фонт + V-typsnitt + V-шрифт + Phông chữ V + V 字体 + V 字型 + + + + + + + Adobe FrameMaker document + مستند أدوبي الصانع للإطارات + Dakument Adobe FrameMaker + Документ — Adobe FrameMaker + document FrameMaker d'Adobe + Dokument Adobe FrameMaker + Adobe FrameMaker-dokument + Adobe-FrameMaker-Dokument + Dokumento de Adobe FrameMaker + documento de Adobe FrameMaker + Adobe FrameMaker-en dokumentua + Adobe FrameMaker -asiakirja + Adobe FrameMaker skjal + document Adobe FrameMaker + cáipéis Adobe FrameMaker + documento de Adobe FrameMaker + מסמך Adobe FrameMaker + Adobe FrameMaker-dokumentum + Dokumen Adobe FrameMaker + Documento Adobe FrameMaker + Adobe FrameMaker ドキュメント + Adobe FrameMaker құжаты + 어도비 프레임메이커 문서 + Adobe FrameMaker dokumentas + Adobe FrameMaker dokuments + Adobe FrameMaker-dokument + Adobe FrameMaker-document + Adobe FrameMaker-dokument + Dokument Adobe FrameMaker + Documento do Adobe FrameMaker + Document Adobe FrameMaker + документ Adobe FrameMaker + Dokument Adobe FrameMaker + Dokument Adobe FrameMaker + Dokument Adobe FrameMaker + Adobe FrameMaker-dokument + документ Adobe FrameMaker + Tài liệu Adobe FrameMaker + Adobe FrameMaker 文档 + Adobe FrameMaker 文件 + + + + + + + + + + + + + Game Boy ROM + Game Boy ROM + Game Boy ROM + ROM — Game Boy + ROM de Game Boy + ROM pro Game Boy + Game Boy-rom + Game-Boy-ROM + εικόνα μνήμης ROM GameBoy + Game Boy ROM + NLM de Game Boy + ROM de Game Boy + Game Boy-eko ROMa + Game Boy -ROM + Game Boy ROM + ROM Game Boy + ROM Game Boy + ROM de Game Boy + ROM של Game Boy + Game Boy ROM + Memori baca-saja Game Boy + ROM Game Boy + ゲームボーイ ROM + Game Boy ROM + 게임보이 롬 + Game Boy ROM + Game Boy ROM + ROM Game Boy + Game Boy-ROM + Game Boy-ROM + Game Boy-ROM + Plik ROM konsoli Game Boy + ROM Game Boy + ROM do Game Boy + ROM Game Boy + Game Boy ROM + ROM pre Game Boy + Bralni pomnilnik Game Boy + ROM Game Boy + Гејмбој РОМ + Game Boy-rom + ППП Game Boy + ROM Game Boy + Game Boy ROM + Game Boy ROM + + + + + Game Boy Advance ROM + Game Boy Advance ROM + Game Boy Advance ROM + ROM — Game Boy Advance + ROM de Game Boy Advance + ROM pro Game Boy Advance + Game Boy Advance-rom + Game-Boy-Advance-ROM + ROM de Game Boy Advance + Game Boy Advance-ko ROMa + Game Boy Advance -ROM + Game Boy Advance ROM + ROM Game Boy Advance + ROM Game Boy Advance + ROM de Game Boy Advance + ROM של Game Boy Advance + Game Boy Advance ROM + Memori baca-saja Game Boy Advance + ROM Game Boy Advance + ゲームボーイアドバンス ROM + Game Boy Advance ROM + 게임보이 어드밴스 롬 + Game Boy Advance ROM + Game Boy Advance ROM + Game Boy Advance-ROM + Game Boy Advance-ROM + Game Boy Advance-ROM + Plik ROM konsoli Game Boy Advance + ROM do Game Boy Advance + ROM Game Boy Advance + Game Boy Advance ROM + ROM pre Game Boy Advance + Bralni pomnilnik Game Boy Advance + ROM Game Boy Advance + Game Boy Advance-rom + розширений ППП Game Boy + ROM Game Boy Advance + Game Boy Advance ROM + Game Boy Advance ROM + + + + + GDBM database + قاعدة بيانات GDBM + Baza źviestak GDBM + База от данни — GDBM + base de dades GDBM + Databáze GDBM + GDBM-database + GDBM-Datenbank + GDBM-datumbazo + base de datos GDBM + GDBM datu-basea + GDBM-tietokanta + GDBM dátustovnur + base de données GDBM + bunachar sonraí GDBM + base de datos GDBM + בסיס נתונים GDBM + GDBM adatbázis + Basis data GDBM + Database GDBM + GDBM データベース + GDBM дерекқоры + GDBM 데이터베이스 + GDBM duomenų bazė + GDBM datubāze + GDBM-database + GDBM-gegevensbank + GDBM-database + Baza danych GDBM + Banco de dados GDBM + Bază de date GDBM + база данных GDBM + Databáza GDBM + Podatkovna zbirka GDBM + Bazë me të dhëna GDBM + GDBM-databas + база даних GDBM + Cơ sở dữ liệu GDBM + GDBM 数据库 + GDBM 資料庫 + GDBM + GNU Database Manager + + + + + + + + + Genesis ROM + Genesis ROM + Genesis ROM + ROM — Genesis + ROM de Genesis + ROM pro Genesis + Genesis-rom + Genesis-ROM + εικόνα μνήμης ROM Genesis + Genesis ROM + Genesis-NLM + ROM de Genesis (Mega Drive) + Genesis-eko ROMa + Genesis-ROM + Genesis ROM + ROM Mega Drive/Genesis + ROM Genesis + ROM xenérica + ROM של Genesis + Genesis ROM + Memori baca-saja Genesis + ROM Megadrive + メガドライブ ROM + Genesis ROM + 제네시스 롬 + Genesis ROM + Genesis ROM + ROM Genesis + Genesis-ROM + Mega Drive + Genesis-ROM + Plik ROM konsoli Mega Drive + ROM Genesis + ROM do Gênesis (Mega Drive) + ROM Genesis + Genesis ROM + ROM pre Megadrive + Bralni pomnilnik Genesis + ROM Genesis + Genesis РОМ + Genesis-rom + ППП Genesis + ROM Genesis + Genesis ROM + Genesis ROM + + + + + + + + + + translated messages (machine-readable) + رسائل مترجمة (مقروءة آليا) + pierakładzienyja paviedamleńni (dla čytańnia kamputaram) + Преведени съобщения — машинен формат + missatges traduïts (llegible per màquina) + Přeložené zprávy (strojově čitelné) + oversatte meddelelser (maskinlæsbare) + Übersetzte Meldungen (maschinenlesbar) + μεταφρασμένα μηνύματα (για μηχανική ανάγνωση) + translated messages (machine-readable) + tradukitaj mesaĝoj (maŝinlegebla) + mensajes traducidos (legibles por máquinas) + itzulitako mezuak (ordenagailuek irakurtzeko) + käännetyt viestit (koneluettava) + týdd boð (maskin-lesifør) + messages traduits (lisibles par machine) + teachtaireachtaí aistrithe (inléite ag meaisín) + mensaxes traducidos (lexíbeis por máquinas) + מסר מתורגם (מובן ע"י מכונה) + lefordított üzenetek (gépi kód) + pesan diterjemahkan (dapat dibaca mesin) + Messaggi tradotti (leggibili da macchina) + 翻訳メッセージ (マシン用) + аударылған хабарламалар (машиналық түрде) + 번역 메시지 (컴퓨터 사용 형식) + išversti užrašai (kompiuteriniu formatu) + pārtulkotie ziņojumi (mašīnlasāms) + Mesej diterjemah (bolehdibaca-mesin) + oversatte meldinger (maskinlesbar) + vertaalde berichten (machine-leesbaar) + oversette meldingar (maskinlesbare) + Przetłumaczone komunikaty (czytelne dla komputera) + mensagens traduzidas (leitura pelo computador) + mensagens traduzidas (legível por máquinas) + mesaje traduse (citite de calculator) + переводы сообщений (откомпилированые) + Preložené správy (strojovo čitateľné) + prevedena sporočila (strojni zapis) + Mesazhe të përkthyer (të lexueshëm nga makina) + преведене поруке (машинама читљиво) + översatta meddelanden (maskinläsbara) + перекладені повідомлення (у машинній формі) + thông điệp đã dịch (máy đọc được) + 消息翻译(机读) + 翻譯訊息 (程式讀取格式) + + + + + Glade project + مشروع Glade + Glade layihəsi + Prajekt Glade + Проект — Glade + projecte de Glade + Projekt Glade + Prosiect Glade + Gladeprojekt + Glade-Projekt + έργο Glade + Glade project + Glade-projekto + proyecto de Glade + Glade proiektua + Glade-projekti + Glade verkætlan + projet Glade + tionscadal Glade + proxecto de Glade + מיזם Glade + Glade-projekt + Proyek Glade + Progetto Glade + Glade プロジェクト + Glade жобасы + Glade 프로젝트 + Glade projektas + Glade projekts + Projek Glade + Glade prosjekt + Glade-project + Glade prosjekt + Projekt Glade + projecto Glade + Projeto do Glade + Proiect Glade + проект Glade + Projekt Glade + Datoteka projekta Glade + Projekt Glade + Глејд пројекат + Glade-projekt + проект Glade + Dự án Glade + Glade 工程 + Glade 專案 + + + + + + + + + GMC link + وصلة GMC + GMC körpüsü + Spasyłka GMC + Връзка — GMC + enllaç GMC + Odkaz GMC + Cyswllt GMC + GMC-henvisning + GMC-Verweis + σύνδεσμος GMC + GMC link + GMC-ligilo + enlace GMC + GMC esteka + GMC-linkki + GMC leinkja + lien GMC + nasc GMC + ligazón GMC + קישור GMC + GMC-link + Taut GMC + Collegamento GMC + GMC リンク + GMC сілтемесі + GMC 연결 + GMC nuoroda + GMC saite + Pautan GMC + GMC-lenke + GMC-verwijzing + GMC-lenkje + Odnośnik GMC + 'link' GMC + Link GMC + Legătură GMC + ссылка GMC + Odkaz GMC + Datoteka povezave GMC + Lidhje GMC + GMC веза + GMC-länk + посилання GMC + Liên kết GMC + GMC 链接 + GMC 鏈結 + + + + + + + GnuCash financial data + معلومات GnuCash المالية + Финансови данни — GnuCash + dades financeres del GnuCash + Finanční data GnuCash + Finansielle data til GnuCash + GnuCash-Finanzdaten + datos financieros GnuCash + GnuCash finantzako datuak + GnuCash-taloustiedot + GnuCash fíggjarligar dátur + données financières GnuCash + sonraí airgeadúla GnuCash + datos financeiros de GNUCash + מידע כלכלי של GnuCash + GnuCash pénzügyi adatok + Data keuangan GnuCash + Dati finanziari GnuCash + GnuCash 会計データ + GnuCash қаржы ақпараты + GnuCash 재정 자료 + GnuCash finansiniai duomenys + GnuCash finanšu dati + GnuCash financiële gegevens + Dane finansowe GnuCash + Dados financeiros do GnuCash + Date financiare GnuCash + финансовые данные GnuCash + Finančné údaje GnuCash + Datoteka finančnih podatkov GnuCash + GnuCash-finansdata + фінансові дані GnuCash + Dữ liệu tài chính GnuCash + GnuCash 财务数据 + GnuCash 財務資料 + + + + + + + Gnumeric spreadsheet + جدول Gnumeric + Raźlikovy arkuš Gnumeric + Таблица — Gnumeric + full de càlcul de Gnumeric + Sešit Gnumeric + Gnumeric-regneark + Gnumeric-Tabelle + Λογιστικό φύλλο Gnumeric + Gnumeric spreadsheet + Gnumeric-kalkultabelo + hoja de cálculo de Gnumeric + Gnumeric kalkulu-orria + Gnumeric-taulukko + Gnumeric rokniark + feuille de calcul Gnumeric + scarbhileog Gnumeric + folla de cálculo de Gnumeric + גליון עבודה Gnumeric + Gnumeric-munkafüzet + Lembar sebar Gnumeric + Foglio di calcolo Gnumeric + Gnumeric スプレッドシート + Gnumeric электрондық кестесі + Gnumeric 스프레드시트 + Gnumeric skaičialentė + Gnumeric izklājlapa + Hamparan Gnumeric + Gnumeric-regneark + Gnumeric-rekenblad + Gnumeric-rekneark + Arkusz Gnumeric + folha de cálculo Gnumeric + Planilha do Gnumeric + Foaie de calcul Gnumeric + электронная таблица Gnumeric + Zošit Gnumeric + Razpredelnica Gnumeric + Fletë llogaritjesh Gnumeric + Гнумерик табеларни рачун + Gnumeric-kalkylblad + ел. таблиця Gnumeric + Bảng tính Gnumeric. + Gnumeric 工作簿 + Gnumeric 試算表 + + + + + + + + + Gnuplot document + مستند Gnuplot + Dakument Gnuplot + Документ — Gnuplot + document gnuplot + Dokument Gnuplot + Gnuplotdokument + Gnuplot-Dokument + Gnuplot document + Gnuplot-dokumento + documento de Gnuplot + Gnuplot dokumentua + Gnuplot-asiakirja + Gnuplot skjal + document Gnuplot + cáipéis Gnuplot + documento de Gnuplot + מסמך Gnuplot + Gnuplot dokumentum + Dokumen Gnuplot + Documento Gnuplot + Gnuplot ドキュメント + Gnuplot құжаты + Gnuplot 문서 + Gnuplot dokumentas + Gnuplot dokuments + Gnuplot-dokument + Gnuplot-document + Gnuplot-dokument + Dokument Gnuplot + Documento do Gnuplot + Document Gnuplot + документ Gnuplot + Dokument Gnuplot + Dokument Gnuplot + Dokument Gnuplot + Gnuplot-dokument + документ Gnuplot + Tài liệu Gnuplot + Gnuplot 文档 + Gnuplot 文件 + + + + + + + + Graphite scientific graph + مبيان الجرافيت العلمي + Navukovy hrafik Graphite + Графика — Graphite + gràfic científic Graphite + Vědecký graf Graphite + Graphite videnskabelig graf + Wissenschaftlicher Graphite-Graph + επιστημονικό γράφημα Graphite + Graphite scientific graph + scienca grafikaĵo de Graphite + gráfica científica de Graphite + Graphite - grafiko zientifikoak + Graphite- tieteellinen graafi + Grapite vísindarlig ritmynd + graphe Graphite scientific + graf eolaíoch Graphite + gráfica científica de Graphite + גרך מדעי של Graphite + Graphite tudományos grafikon + Grafik sains Graphite + Grafico scientifico Graphite + Graphite scientific グラフ + Graphite ғылыми кескіні + Graphite 공학 그래프 + Graphite mokslinė diagrama + Graphite zinātniskais grafiks + Graf saintifik Graphite + Vitenskapelig graf fra Graphite + Graphite wetenschappelijke grafiek + Graphite vitskaplege graf + Wykres naukowy Graphite + gráfico científico Graphite + Gráfico científico do Graphite + Grafic științific Graphite + научная диаграмма Graphite + Vedecký graf Graphite + Datoteka znanstvenega grafa Graphite + Grafik shkencor Graphite + Graphite научни графикони + Vetenskaplig Graphite-grafer + наукова графіка Graphite + Biểu đồ khoa học Graphite + Graphite 科学图形 + Graphite 科學圖表 + + + + + GTKtalog catalog + كتالوج GTKtalog + Kataloh GTKtalog + Каталог — Gtktalog + catàleg de GTKtalog + Katalog GTKtalog + GTKtalog-katalog + GTKtalog-Katalog + Κατάλογος GTKtalog + GTKtalog catalogue + katalogo de GTKtalog + catálogo de GTKtalog + Gtktalog katalogoa + GTKtalog-luettelo + GTKtalog skrá + catalogue Gtktalog + catalóg GTKtalog + catálogo de GTKtalog + קטלוג GTKtalog + GTKtalog-katalógus + Katalog GTKtalog + Catalogo GTKtalog + GTKtalog カタログ + GTKtalog каталогы + GTKtalog 카탈로그 + GTKtalog katalogas + GTKtalog katalogs + Katalog GTKtalog + GTKtalog-katalog + GTKtalog-catalogus + GTKtalog-katalog + Katalog programu GTKtalog + catálogo GTKtalog + Catálogo GTKtalog + Catalog GTKalog + каталог GTKtalog + Katalóg GTKtalog + Datoteka kataloga GTKtalog + Katallog GTKtalog + Гткталог каталог + GTKtalog-katalog + каталог GTKtalog + Phân loại GTKtalog + GTKtalog 目录 + GTKtalog 光碟目錄 + + + + + + + TeX DVI document (gzip-compressed) + مستند TeX DVI (مضغوط-gzip) + Dakument TeX DVI (gzip-skampresavany) + Документ — TeX DVI, компресиран с gzip + document TeX DVI (comprimit amb gzip) + Dokument TeX DVI (komprimovaný pomocí gzip) + TeX DVI-dokument (gzip-komprimeret) + TeX-DVI-Dokument (gzip-komprimiert) + documento DVI de TeX (comprimido con gzip) + TeX DVI dokumentua (gzip-ekin konprimitua) + TeX DVI -asiakirja (gzip-pakattu) + TeX DVI skjal (gzip-stappað) + document DVI TeX (compressé gzip) + cáipéis DVI TeX (comhbhrúite le gzip) + documento DVI de TeX (comprimido con gzip) + מסמך מסוג TeX DVI (מכווץ ע"י gzip) + TeX DVI dokumentum (gzip-pel tömörítve) + Dokumen TeX DVI (terkompresi gzip) + Documento Tex DVI (compresso con gzip) + Tex DVI ドキュメント (gzip 圧縮) + TeX DVI құжаты (gzip-пен сығылған) + TeX DVI 문서 (GZIP 압축) + TeX DVI dokumentas (suglaudintas su gzip) + TeX DVI dokuments (saspiests ar gzip) + TeX DVI-dokument (gzip-komprimert) + TeX DVI-document (ingepakt met gzip) + TeX DVI-dokument (pakka med gzip) + Dokument TeX DVI (kompresja gzip) + Documento DVI TeX (compactado com gzip) + Document TeX DVI (comprimat gzip) + документ TeX DVI (сжатый gzip) + Dokument TeX DVI (komprimovaný pomocou gzip) + Dokument TeX DVI (stisnjen z gzip) + Dokument TeX DVI (i kompresuar me gzip) + TeX DVI-dokument (gzip-komprimerat) + документ TeX DVI (стиснений gzip) + Tài liệu DVI TeX (đã nén gzip) + TeX DVI 文档(gzip 压缩) + TeX DVI 文件 (gzip 格式壓縮) + + + + + + Gzip archive + أرشيف Gzip + Archiŭ gzip + Архив — gzip + arxiu gzip + Archiv gzip + Gzip-arkiv + Gzip-Archiv + Gzip-arkivo + archivador Gzip + Gzip artxiboa + Gzip-arkisto + Gzip skjalasavn + archive gzip + cartlann Gzip + arquivo Gzip + ארכיון Gzip + Gzip archívum + Arsip Gzip + Archivio gzip + Gzip アーカイブ + Gzip архиві + GZIP 압축 파일 + Gzip archyvas + Gzip arhīvs + Gzip-arkiv + Gzip-archief + Gzip-arkiv + Archiwum gzip + Pacote Gzip + Arhivă Gzip + архив GZIP + Archív gzip + Datoteka arhiva Gzip + Arkiv gzip + Gzip-arkiv + архів gzip + Kho nén gzip + Gzip 归档文件 + Gzip 封存檔 + + + + + + + + PDF document (gzip-compressed) + مستند PDF (مضغوط-gzip) + Dakument PDF (gzip-skampresavany) + Документ — PDF, компресиран с gzip + document PDF (comprimit amb gzip) + Dokument PDF (komprimovaný pomocí gzip) + PDF-dokument (gzip-komprimeret) + PDF-Dokument (gzip-komprimiert) + documento PDF (comprimido con gzip) + PDF dokumentua (gzip-ekin konprimitua) + PDF-asiakirja (gzip-pakattu) + PDF skjal (gzip-stappað) + document PDF (compressé gzip) + cáipéis PDF (comhbhrúite le gzip) + documento PDF (comprimido en gzip) + מסמך PDF (מכווץ ע"י gzip) + PDF dokumentum (gzip-tömörítésű) + Dokumen PDF (terkompresi gzip) + Documento PDF (compresso con gzip) + PDF ドキュメント (gzip 圧縮) + PDF құжаты (gzip-пен сығылған) + PDF 문서 (GZIP 압축) + PDF dokumentas (suglaudintas su gzip) + PDF dokuments (saspiests ar gzip) + PDF-dokument (gzip-komprimert) + PDF-document (ingepakt met gzip) + PDF-dokument (pakka med gzip) + Dokument PDF (kompresja gzip) + Documento PDF (compactado com gzip) + Document PDF (comprimat gzip) + документ PDF (сжатый gzip) + Dokument PDF (komprimovaný pomocou gzip) + Dokument PDF (stisnjen z gzip) + Dokument PDF (i kompresuar me gzip) + PDF-dokument (gzip-komprimerat) + документ PDF (стиснений gzip) + Tài liệu PDF (đã nén gzip) + PDF 文档(gzip 压缩) + PDF 文件 (gzip 格式壓縮) + + + + + + PostScript document (gzip-compressed) + مستند PostScript (مضغوط-gzip) + Dakument PostScript (gzip-skampresavany) + Документ — PostScript, компресиран с gzip + document PostScript (comprimit amb gzip) + Dokument PostScript (komprimovaný pomocí gzip) + PostScript-dokument (gzip-komprimeret) + PostScript-Dokument (gzip-komprimiert) + έγγραφο PostScript (συμπιεσμένο με gzip) + PostScript document (gzip-compressed) + PostScript-dokumento (kunpremita per gzip) + documento PostScript (comprimido con gzip) + PostScript dokumentua (gzip-konprimitua) + PostScript-asiakirja (gzip-pakattu) + PostScript skjal (gzip-stappað) + document PostScript (compressé gzip) + cáipéis PostScript (comhbhrúite le gzip) + documento PostScript (comprimido con gzip) + מסמך PostScript (מכוות ע"י gzip) + PostScript-dokumentum (gzip-pel tömörítve) + Dokumen PostScript (terkompresi gzip) + Documento PostScript (compresso con gzip) + PostScript ドキュメント (gzip 圧縮) + PostScript құжаты (gzip-пен сығылған) + 포스트스크립트 문서 (GZIP 압축) + PostScript dokumentas (suglaudintas su gzip) + PostScript dokuments (saspiests ar gzip) + Dokumen PostScript (dimampatkan-gzip) + PostScript-dokument (gzip-komprimert) + PostScript-document (ingepakt met gzip) + PostScript-dokument (pakka med gzip) + Dokument Postscript (kompresja gzip) + documento PostScript (comprimido com gzip) + Documento PostScript (compactado com gzip) + Document PostScript (comprimat gzip) + документ PostScript (сжатый gzip) + Dokument PostScript (komprimovaný pomocou gzip) + Dokument PostScript (stisnjen z gzip) + Dokument PostScript (i kompresuar me gzip) + Постскрипт документ (компресована gzip-ом) + Postscript-dokument (gzip-komprimerat) + документ PostScript (стиснене gzip) + Tài liệu PostScript (đã nén gzip) + PostScript 文档(gzip 压缩) + PostScript 文件 (gzip 格式壓縮) + + + + + + HDF document + مستند HDF + HDF sənədi + Dakument HDF + Документ — HDF + document HDF + Dokument HDF + Dogfen HDF + HDF-dokument + HDF-Dokument + έγγραφο HDF + HDF document + HDF-dokumento + documento HDF + HDF dokumentua + HDF-asiakirja + HDF skjal + document HDF + cáipéis HDF + documento HDF + מסמך HDF + HDF-dokumentum + Dokumen HDF + Documento HDF + HDF ドキュメント + HDF құжаты + HDF 문서 + HDF dokumentas + HDF dokuments + Dokumen HDF + HDF-dokument + HDF-document + HDF-dokument + Dokument HDF + documento HDF + Documento HDF + Document HDF + документ HDF + Dokument HDF + Dokument HDF + Dokument HDF + HDF документ + HDF-dokument + документ HDF + Tài liệu HDF + HDF 文档 + HDF 文件 + HDF + Hierarchical Data Format + + + + + + + + + + + + + iPod firmware + برنامج عتاد الـiPod + Firmware iPod + Фърмуер за iPod + microprogramari d'iPod + Firmware iPod + iPod-styreprogram + iPod-Firmware + εικόνα μνήμης firmware iPod + iPod firmware + iPod-mikroprogramaro + firmware de iPod + iPod firmwarea + iPod-laiteohjelmisto + iPod fastbúnaður + firmware iPod + dochtearraí iPod + firmware de iPod + קושחת ipod + iPod-firmware + peranti tegar iPod + Firmware iPod + iPod ファームウェア + iPod микробағдарламасы + iPod 펌웨어 + iPod programinė įranga + iPod aparātprogrammatūra + Firmware iPod + iPod-firmware + iPod-firmware + iPod-firmvare + Oprogramowanie wewnętrzne iPod + 'firmware' iPod + Firmware do iPod + Firmware iPod + микропрограмма iPod + Firmware iPod + Programska strojna oprema iPod + Firmware iPod + iPod програм + fast iPod-program + мікропрограма iPod + phần vững iPod + iPod 固件 + iPod 韌體 + + + + + + Java archive + أرشيف Java + Archiŭ Java + Архив — Java + arxiu Java + Archiv Java + Javaarkiv + Java-Archiv + αρχείο Java + Java archive + Java-arkivo + archivador Java + Java artxiboa + Java-arkisto + Java skjalasavn + archive Java + cartlann Java + arquivo Java + ארכיון Java + Java-archívum + Arsip Java + Archivio Java + Java アーカイブ + Java архиві + 자바 묶음 파일 + Java archyvas + Java arhīvs + Arkib Java + Java-arkiv + Java-archief + Java-arkiv + Archiwum Java + arquivo Java + Pacote Java + Arhivă Java + архив Java + Archív Java + Datoteka arhiva Java + Arkiv Java + Јава архива + Java-arkiv + архів Java + Kho nén Java + Java 归档文件 + Java 封存檔 + + + + + + + + Java class + صنف java + Klasa Java + Клас на Java + classe Java + Třída Java + Javaklasse + Java-Klasse + κλάση Java + Java class + Java-klaso + clase Java + Java-ko klasea + Java-luokka + Java flokkur + classe Java + aicme Java + clase de Java + מחלקת Java + Java-osztály + Kelas Java + Classe Java + Java クラス + Java класы + 자바 클래스 + Java klasė + Java klase + Kelas Java + Java-klasse + Java-klasse + Java-klasse + Klasa Java + classe Java + Classe Java + Clasă Java + класс Java + Trieda Java + Datoteka razreda Java + Klasë Java + Јава класа + Java-klass + клас Java + Hạng Java + Java 类 + Java class + + + + + + + + + + + + JNLP file + ملف JNLP + Fajł JNLP + Файл — JNLP + fitxer JNLP + Soubor JNLP + JNPL-fil + JNLP-Datei + JNLP file + JNLP-dosiero + archivo JNPL + JNLP fitxategia + JNLP-tiedosto + JNLP fíla + fichier JNLP + comhad JNLP + ficheiro JNLP + קובץ JNLP + JNLP fájl + Berkas JNLP + File JNPL + JNLP ファイル + JNLP файлы + JNLP 파일 + JNLP failas + JNLP fails + JNLP-fil + JNLP-bestand + JNLP-fil + Plik JNLP + Arquivo JNLP + Fișier JNLP + файл JNLP + Súbor JNLP + Datoteka JNLP + File JNLP + JNLP-fil + файл JNLP + Tập tin JNLP + JNLP 文件 + JNLP 檔案 + JNLP + Java Network Launching Protocol + + + + + + + + + Java keystore + مخزن مفاتيح جافا + Ключодържател — Java + magatzem de claus Java + Java keystore + Javanøglelager + Java-Schlüsselbund + almacén de claves de Java + Java-ren gako-biltegia + Java-avainvarasto + Java lyklagoymsla + stockage de clés Java + eochairstór Java + almacén de chaves de Java + הקשת מקלדת של Java + Java kulcstároló + Penyimpanan kunci Java + Keystore Java + Java キーストア + Java сақталымы + 자바 키스토어 + Java raktų saugykla + Java keystore + Baza kluczy Java + Stocare chei Java + хранилище ключей Java + Úložisko kľúčov Java + Datoteka tipkovne razporeditve Java + Java-nyckellager + сховище ключів Java + Java 密钥库 + Java 金鑰儲存 + + + + + + + + + Java JCE keystore + مخزن مفاتيح Java JCE + Ключодържател — Java JCE + magatzem de claus JCE Java + Java JCE keystore + Java JCE-nøglelager + Java JCE-Schlüsselbund + almacén de claves JCE de Java + Java JCE-ren gako-biltegia + Java JCE -avainvarasto + Java JCE lyklagoymsla + stockage de clés Java JCE + eochairstór Java JCE + almacén de chves JCE de Java + הקשה מסוג Java JCE + Java JCE kulcstároló + Penyimpanan kunci Java JCE + Keystore Java JCE + Java JCE キーストア + Java JCE сақталымы + wkqk JCE 키스토어 + Java JCE raktų saugykla + Java JCE keystore + Baza kluczy Java JCE + Stocare chei Java JCE + хранилище ключей Java JCE + Úložisko kľúčov Java JCE + Datoteka tipkovne razporeditve Java JCE + Java JCE-nyckellager + сховище ключів JCE Java + Java JCE 密钥库 + Java JCE 金鑰儲存 + JCE + Java Cryptography Extension + + + + + + + Pack200 Java archive + أرشيف Pack200 Java + Archiŭ Pack200 Java + Архив — Java Pack200 + arxiu Java Pack200 + Archiv Java Pack200 + Pack200 Java-arkiv + Pack200-Java-Archiv + archivador Pack200 Java + Pack2000 Java artxiboa + Pack200-Java-arkisto + Pack200 Java skjalasavn + archive Java Pack200 + cartlann Java Pack200 + arquivo Pack200 Java + ארכיון מסוג Pack200 Java + Pack200 Java-archívum + Arsip Pack200 Java + Archivio Pack200 Java + Pack200 Java アーカイブ + Pack200 Java архиві + Pack200 자바 묶음 파일 + Pack200 Java archyvas + Pack200 Java arhīvs + Pack200 Java-arkiv + Pack200 Java-archief + Pack200 Java-arkiv + Archiwum Java Pack200 + Pacote Java Pack200 + Arhivă Java Pack2000 + архив Java Pack200 + Archív Java Pack200 + Datoteka arhiva Pack200 Java + Arkiv Java Pack200 + Pack200 Java-arkiv + архів Java Pack200 + Kho nén Java Pack200 + Pack200 Java 归档文件 + Pack200 Java 封存檔 + + + + + + + + JavaScript program + برنامج جافاسكربت + Prahrama JavaScript + Програма на JavaScript + programa JavaScript + Program v JavaScriptu + JavaScript-program + JavaScript-Programm + πρόγραμμα JavaScript + JavaScript-programo + programa en JavaScript + JavaScript programa + JavaScript-ohjelma + JavaScript forrit + programme JavaScript + ríomhchlár JavaScript + programa JavaScript + תכנית JavaScript + JavaScript-program + Program JavaScript + Programma JavaScript + JavaScript プログラム + JavaScript бағдарламасы + 자바스크립트 프로그램 + JavaScript programa + JavaScript programma + Program JavaScript + JavaScript-program + JavaScript-programma + JavaScript-program + Pogram JavaScript + Programa JavaScript + Program JavaScript + сценарий JavaScript + Program jazyka JavaScript + Programska datoteka JavaScript + Program JavaScript + JavaScript-program + програма мовою JavaScript + Chương trình JavaScript + Javascript 程序 + JavaScript 程式 + + + + + + + + JBuilder project + مشروع JBuilder + Prajekt JBuilder + Проект — JBuilder + projecte de JBuilder + Projekt JBuilder + JBuilder-projekt + JBuilder-Projekt + έργο JBuilder + JBuilder project + JBuilder-projekto + proyecto JBuilder + JBuilder proiektua + JBuilder-projekti + JBuilder verkætlan + projet JBuilder + tionscadal JBuilder + proxecto de JBuilder + מיזם JBuilder + JBuilder-projekt + Proyek JBuilder + Progetto JBuilder + JBuilder プロジェクト + JBuilder жобасы + JBuilder 프로젝트 + JBuilder projektas + JBuilder projekts + Projek JBuilder + JBuilder-prosjekt + JBuilder-project + JBuilder-prosjekt + Projekt JBuilder + projecto JBuilder + Projeto do JBuilder + Proiect JBuilder + проект JBuilder + Projekt JBuilder + Datoteka projekta JBuilder + Projekt JBuilder + JBuilder пројекат + JBuilder-projekt + проект JBuilder + Dự án JBuilder + JBuilder 工程 + JBuilder 專案 + + + + + + Karbon14 drawing + تصميم Karbon14 + Rysunak Karbon14 + Чертеж — Karbon14 + dibuix de Karbon14 + Kresba Karbon14 + Karbon14-tegning + Karbon14-Zeichnung + σχέδιο Karbon14 + Karbon14 drawing + Karbon14-grafikaĵo + dibujo de Karbon14 + Karbon14 marrazkia + Karbon14-piirros + Karbon14 tekning + dessin Karbon14 + líníocht Karbon14 + debuxo de Karbon14 + ציור Karbon14 + Karbon14-rajz + Gambar Karbon14 + Disegno Karbon14 + Karbon14 ドロー + Karbon14 суреті + Karbon14 그림 + Karbon14 piešinys + Karbon14 zīmējums + Lukisan Karbon14 + Karbon14-tegning + Karbon14-tekening + Karbon14-teikning + Rysunek Karbon14 + desenho Karbon14 + Desenho do Karbon14 + Desen Karbon14 + изображение Karbon14 + Kresba Karbon14 + Datoteka risbe Karbon14 + Vizatim Karbon14 + Karbon14 цртеж + Karbon14-teckning + малюнок Karbon14 + Bản vẽ Karbon14 + Karbon14 绘图 + Karbon14 繪圖 + + + + + + + + + + + + + + + + + KChart chart + رسم بياني KChart + Hrafik KChart + Диаграма — KChart + diagrama de KChart + Graf Chart + KChart-diagram + KChart-Diagramm + γράφημα KChart + KChart chart + KChart-diagramo + gráfica de KChart + KChart diagrama + KChart-kaavio + KChart strikumynd + graphique KChart + cairt KChart + gráfica de KChart + תרשים KChart + KChart-grafikon + Bagan KChart + Grafico KChart + KChart チャート + KChart диаграммасы + KChart 차트 + KChart diagrama + KChart diagramma + Carta KChart + KChart-graf + KChart-grafiek + KChart-diagram + Wykres KChart + gráfico KChart + Gráfico do KChart + Diagramă KChart + диаграмма KChart + Graf KChart + Datoteka grafikona KChart + Grafik KChart + KChart графикон + KChart-diagram + діаграма KChart + Sơ đồ KChart + KChart 图表 + KChart 圖表 + + + + + + + + + + + + + + + + + Kexi settings for database server connection + إعدادات Kexi للإتصال بخادم قاعدة البيانات + Връзка към база от данни — Kexi + configuració del Kexi per a la connexió al servidor de bases de dades + Nastavení Kexi ke spojení s databázovým serverem + Kexiopsætning til forbindelsen for databaseserveren + Kexi-Einstellungen für Verbindung zum Datenbankserver + configuración de Kexi para la conexión con el servidor de bases de datos + Kexi-ren ezarpenak datu-basearen zerbitzariarekin konektatzeko + Kexi-tietokantayhteysasetukset + Kexi stillingar fyri dátustovnsambætara sambinding + paramètres Kexi pour connexion au serveur de base de données + socruithe Kexi do cheangal le freastalaí bunachair sonraí + configuración de Kexi para conexión con servidor de base de datos + הגדרות של Kexi עבור חיבור שרת לבסיס נתונים + Kexi beállítások adatbáziskiszolgáló-kapcsolathoz + Tatanan Kexi bagi koneksi server basis data + Impostazioni Kexi per connessione a server di database + データベースサーバ接続用の Kexi 設定 + Дерекқор серверге байланыс Kexi баптаулары + Kexi 데이터베이스 서버 연결 설정 + Kexi duomenų bazės ryšio su serveriu parametrai + Kexi iestatījumi datubāzes servera savienojumam + Ustawienia Kexi dla połączenia serwera bazy danych + Configurări Kexi pentru conexiunea la serverul de baze de date + параметры Kexi для подключения к серверу БД + Nastavenia Kexi pre pripojenie k databázovému serveru + Strežniška povezava do nastavitvene datoteke Kexi. + Kexi-inställningar för anslutning till databasserver + параметри Kexi для встановлення з’єднання з сервером бази даних + Kexi 数据库服务器连接设置 + Kexi 設定值 (資料庫伺服器連線用) + + + + shortcut to Kexi project on database server + اختصار لمشروع Kexi على خادم قاعدة بيانات + Връзка към проект — Kexi + drecera a projecte del Kexi en un servidor de base de dades + Zástupce projektu Kexi na databázovém serveru + genvej til Kexiprojekt på databaseserver + Schnellzugriff zum Kexi-Projekt auf dem Datenbankserver + acceso directo a proyecto Kexi en el servidor de bases de datos + lasterbidea datu-basearen zerbitzariko Kexi proiekturako + snarvegur til Kexi verkætlan á dátustovnsambætara + raccourci vers projet Kexi sur serveur de base de données + aicearra go tionscadal Kexi ar fhreastalaí bunachair sonraí + acceso directo a proxecto Kexi no servidor de bases de datos + קיצור דרך לפרוירט Kexi בשרת נתונים + indítóikon adatbázis-kiszolgálón lévő Kexi projektre + pintasan ke projek Kexi pada server basis data + Scorciatoia a progetto Kexi su server di database + データベースサーバの Kexi プロジェクトへのショートカット + дерекқор серверіндегі Kexi жобасына сілтеме + Kexi 데이터베이스 서버 사용 프로젝트 바로 가기 + nuoroda į Kexi projektą duomenų bazės serveryje + īsceļš uz Kexi projektu datubāzes serverī + Skrót do projektu Kexi na serwerze bazy danych + scurtătură către un proiect Kexi pe un server de baze de date + ссылка на проект Kexi на сервере БД + bližnjica do Kexi projekta na podatkovnem strežniku + genväg till Kexi-projekt på databasserver + скорочення для проекту Kexi на сервері бази даних + 数据库服务器上 Kexi 项目的快捷方式 + 資料庫伺服器上 Kexi 專案的捷徑 + + + + Kexi database file-based project + مشروع قاعدة بيانات Kexi يعتمد على ملفات + Проект с база от данни — Kexi + projecte basat en fitxer de base de dades del Kexi + Projekt založený na souboru databáze Kexi + Filbaseret projekt for Kexidatabase + Dateibasiertes Kexi-Datenbankprojekt + proyecto basado en el archivo-base de datos Kexi + Kexi datu-baseko fitxategian oinarritutako proiektua + Kexi dátustovns fílugrundað verkætlan + projet de base de données Kexi en mode fichier + tionscadal bunachair sonraí Kexi bunaithe ar chomhaid + proxecto baseado no ficheiro-base de datos Kexi + פרויקט בסיס נתונים מבוסס-קובץ של Kexi + Kexi adatbázisfájl-alapú projekt + Projek berbasis berkas basis data Kexi + Progetto su file di database Kexi + Kexi データベース ファイルベースプロジェクト + Файл негізінде жоба үшін Kexi дерекқоры + Kexi 데이터베이스 파일 사용 프로젝트 + Kexi duomenų bazės failo tipo projektas + Kexi datubāzes faila balstīts projekts + Projekt bazy danych Kexi oparty na pliku + Proiect bazat pe fișiere al bazei de date Kexi + файловый проект базы данных Kexi + Datoteka projekta podatkovne zbirke Kexi + Kexi-databas för filbaserat projekt + проект файлової бази даних Kexi + Kexi 基于文件的数据库项目 + Kexi 資料庫檔案基礎專案 + + + + + Kexi database file-based project + مشروع قاعدة بيانات Kexi يعتمد على ملفات + Проект с база от данни — Kexi + projecte basat en fitxer de base de dades del Kexi + Projekt založený na souboru databáze Kexi + Filbaseret projekt for Kexidatabase + Dateibasiertes Kexi-Datenbankprojekt + proyecto basado en el archivo-base de datos Kexi + Kexi datu-baseko fitxategian oinarritutako proiektua + Kexi dátustovns fílugrundað verkætlan + projet de base de données Kexi en mode fichier + tionscadal bunachair sonraí Kexi bunaithe ar chomhaid + proxecto baseado no ficheiro-base de datos Kexi + פרויקט בסיס נתונים מבוסס-קובץ של Kexi + Kexi adatbázisfájl-alapú projekt + Projek berbasis berkas basis data Kexi + Progetto su file di database Kexi + Kexi データベース ファイルベースプロジェクト + Файл негізінде жоба үшін Kexi дерекқоры + Kexi 데이터베이스 파일 사용 프로젝트 + Kexi duomenų bazės failo tipo projektas + Kexi datubāzes faila balstīts projekts + Projekt bazy danych Kexi oparty na pliku + Proiect bazat pe fișiere al bazei de date Kexi + файловый проект базы данных Kexi + Datoteka projekta podatkovne zbirke Kexi + Kexi-databas för filbaserat projekt + проект файлової бази даних Kexi + Kexi 基于文件的数据库项目 + Kexi 資料庫檔案基礎專案 + + + + + + + KFormula formula + صيغة KFormula + Formuła KFormula + Формула — KFormula + fórmula de KFormula + Vzorec KFormula + KFormula-formel + KFormula-Formel + μαθηματικός τύπος KFormula + KFormula formula + KFormula-formulo + fórmula de KFormula + KFormula formula + KFormula-kaava + KFormula frymil + formule KFormula + foirmle KFormula + fórmula de KFormula + נוסחת KFormula + KFormula-képlet + Formula KFormula + Formula KFormula + KFormula 計算式 + KFormula формуласы + KFormula 수식 + KFormula formulė + KFormula formula + Formula KFormula + KFormula-formel + KFormula-formule + KFormula-formel + Formuła KFormula + fórmula KFormula + Fórmula do KFormula + Formulă KFormula + формула KFormula + Vzorec KFormula + Datoteka formule KFormula + Formulë KFormula + KFormula формула + KFormula-formel + формула KFormula + Công thức KFormula + KFormula 公式 + KFormula 公式 + + + + + + + + + + + + + + + + + KIllustrator drawing + تصميم KIllustrator + Rysunak KIllustrator + Чертеж — KIllustrator + dibuix de KIllustrator + Kresba KIllustrator + KIllustrator-tegning + KIllustrator-Zeichnung + σχέδιο KIllustrator + KIllustrator drawing + KIllustrator-grafikaĵo + dibujo de KIllustrator + KIllustrator marrazkia + KIllustrator-piirros + KIllustrator tekning + dessin KIllustrator + líníocht KIllustrator + debuxo de KIllustrator + ציור KIllustrator + KIllustrator-rajz + Gambar KIllustrator + Disegno KIllustrator + KIllustrator ドロー + KIllustrator суреті + KIllustrator 그림 + KIllustrator piešinys + KIllustrator zīmējums + Lukisan KIllustrator + KIllustrator-tegning + KIllustrator-tekening + KIllustrator-teikning + Rysunek KIllustrator + desenho KIllustrator + Desenho do KIllustrator + Desen KIllustrator + изображение KIllustrator + Kresba KIllustrator + Datoteka risbe KIllustrator + Vizatim KIllustrator + KIllustrator цртеж + KIllustrator-teckning + малюнок KIllustrator + Bản vẽ KIllustrator + KIllustrator 绘图 + KIllustrator 繪圖 + + + + + + + + + + + + Kivio flowchart + قائمة تدفق Kivio + Blok-schiema Kivio + Диаграма — Kivio + diagrama de flux de Kivio + Vývojový diagram Kivio + Kiviorutediagram + Kivio-Flussdiagramm + διάγραμμα ροής Kivio + Kivio flowchart + Kivo-fluskemo + diagrama de flujo de Kivio + Kivio diagrama + Kivio-vuokaavio + Kivio leiðarit + diagramme de flux Kivio + sreabhchairt Kivio + gráfica de fluxo de Kivio + תרשים זרימה של Kivio + Kivio-folyamatábra + Bagan Kivio + Diagramma di flusso Kivio + Kivio フローチャート + Kivio диаграммасы + Kivio 흐름도 + Kivio eigos diagrama + Kivio blokshēma + Cartalir Kivio + Kivio-flytdiagram + Kivio-stroomschema + Kivio-flytdiagram + Diagram przepływów Kivio + gráfico de fluxo Kivio + Fluxograma do Kivio + Diagramă Kivio + диаграмма Kivio + Vývojový diagram Kivio + Datoteka grafikona Kivio + Diagramë fluksi Kivio + Kivio дијаграм + Kivio-flödesschema + блок-схема Kivio + Lược đồ Kivio + Kivio 流程图 + Kivio 圖表 + + + + + + + + + + + + + + + + + Kontour drawing + تصميم Kontour + Rysunak Kontour + Чертеж — Kontour + dibuix de Kontour + Kresba Kontour + Kontourtegning + Kontour-Zeichnung + σχέδιο Kontour + Kontour drawing + Kontour-grafikaĵo + dibujo de Kontour + Kontour marrazkia + Kontour-piirros + Kontour tekning + dessin Kontour + líníocht Kontour + debuxo de Kontour + ציור Kontour + Kontour-rajz + Gambar Kontour + Disegno Kontour + Kontour ドロー + Kontour суреті + Kontour 그림 + Kontour piešinys + Kontour zīmējums + Lukisan Kontour + Kontour-tegning + Kontour-tekening + Kontour-teikning + Rysunek Kontour + desenho Kontour + Desenho do Kontour + Desen Kontour + изображение Kontour + Kresba Kontour + Datoteka risbe Kontour + Vizatim Kontour + Kontour цртеж + Kontour-teckning + малюнок Kontour + Bản vẽ Kontour + Kontour 绘图 + Kontour 繪圖 + + + + + + + + + + + + + + + + + KPovModeler scene + مشهد KPovModeler + Scena KPovModeler + Сцена — KPovModeler + escena de KPovModeler + Scéna KPovModeler + KPovModeler-scene + KPovModeler-Szene + σκηνή KPovModeler + KPovModeler scene + KPovModeler-sceno + escena de KPovModeler + KPovModeler eszena + KPovModeler-näkymä + KPovModeler leikmynd + scène KPovModeler + radharc KPovModeler + escena de KPovModeler + סצנת KPovModeler + KPovModeler-jelenet + Scene KPovModeler + Scena KPovModeler + KPovModeler シーン + KPovModeler сахнасы + KPovModeler 장면 + KPovModeler scena + KPovModeler aina + Babak KPovModeler + KPovModeler-scene + KPovModeler-scène + KPovModeler-scene + Scena KPovModeler + cenário KPovModeler + Cena do KPovModeler + Scenă KPovModeler + сцена KPovModeler + Scéna KPovModeler + Datoteka scene KPovModeler + Skenë KPovModeler + KPovModeler сцена + KPovModeler-scen + сцена KPovModeler + Cảnh KPovModeler + KPovModeler 场景 + KPovModeler 場景 + + + + + KPresenter presentation + عرض تقديمي KPresenter + Prezentacyja KPresenter + Презентация — KPresenter + presentació de KPresenter + Prezentace KPresenter + KPresenter-præsentation + KPresenter-Präsentation + παρουσίαση KPresenter + KPresenter presentation + KPresenter-prezentaĵo + presentación de KPresenter + Kpresenter aurkezpena + KPresenter-esitys + KPresenter framløga + présentation KPresenter + láithreoireacht KPresenter + presentación de KPresenter + מצגת KPresenter + KPresenter-bemutató + Presentasi KPresenter + Presentazione KPresenter + KPresenter プレゼンテーション + KPresenter презентациясы + KPresenter 프리젠테이션 + KPresenter pateiktis + KPresenter prezentācija + Persembahan Kpresenter + KPresenter-presentasjon + KPresenter-presentatie + KPresenter-presentasjon + Prezentacja KPresenter + apresentação KPresenter + Apresentação do KPresenter + Prezentare KPresenter + презентация KPresenter + Prezentácia KPresenter + Predstavitev KPresenter + Prezantim i KPresenter + KPresenter презентација + KPresenter-presentation + презентація KPresenter + Trình diễn KPresenter + KPresenter 演示文稿 + KPresenter 簡報檔 + + + + + + + + + + + + + + + + + + Krita document + مستند Krita + Dakument Krita + Документ — Krita + document de Krita + Dokument Krita + Kritadokument + Krita-Dokument + έγγραφο Krita + Krita document + Krita-dokumento + documento de Krita + Krita dokumentua + Krita-asiakirja + Krita skjal + document Krita + cáipéis Krita + documento de Krita + מסמך Krita + Krita-dokumentum + Dokumen Krita + Documento Krita + Krita ドキュメント + Krita құжаты + Krita 문서 + Krita dokumentas + Krita dokuments + Dokumen Krita + Krita-dokument + Krita-document + Krita-dokument + Dokument Krita + documento Krita + Documento do Krita + Document Krita + документ Krita + Dokument Krita + Dokument Krita + Dokument Krita + Krita документ + Krita-dokument + документ Krita + Tài liệu Krita + Krita 文档 + Krita 文件 + + + + + + + + + + + + + + + + + KSpread spreadsheet + جدول KSpread + Raźlikovy arkuš KSpread + Таблица — KSpread + full de càlcul de KSpread + Sešit KSpread + KSpread-regneark + KSpread-Tabelle + λογιστικό φύλλο KSpread + KSpread spreadsheet + KSpread-kalkultabelo + hoja de cálculo de KSpread + KSpread kalkulu-orria + KSpread-taulukko + KSpread rokniark + feuille de calcul KSpread + scarbhileog KSpread + folla de cálculo de KSpread + גליון נתונים של Kspread + KSpread-munkafüzet + Lembar sebar KSpread + Foglio di calcolo KSpread + KSpread スプレッドシート + KSpread электрондық кестесі + KSpread 스프레드시트 + KSpread skaičialentė + KSpread izklājlapa + Hamparan KSpread + KSpread-regneark + KSpread-rekenblad + KSpread-rekneark + Arkusz KSpread + folha de cálculo KSpread + Planilha do KSpread + Foaie de calcul KSpread + электронная таблица KSpread + Zošit KSpread + Razpredelnica KSpread + Fletë llogaritjesh KSpread + KSpread табеларни прорачун + KSpread-kalkylblad + ел. таблиця KSpread + Bảng tính KSpread + KSpread 工作簿 + KSpread 試算表 + + + + + + + + + + + + + + + + + KSpread spreadsheet (encrypted) + جدول KSpread (مشفر) + Raźlikovy arkuš KSpread (zašyfravany) + Таблица — KSpread, шифрирана + full de càlcul de KSpread (xifrat) + Sešit KSpread (šifrovaný) + KSpread-regneark (krypteret) + KSpread-Tabelle (verschlüsselt) + λογιστικό φύλλο KSpread (κρυπτογραφημένο) + KSpread spreadsheet (encrypted) + KSpread-kalkultabelo (ĉifrita) + hoja de cálculo de KSpread (cifrada) + KSpread kalkulu-orria (enkriptatua) + KSpread-taulukko (salattu) + KSpread rokniark (bronglað) + feuille de calcul KSpread (chiffrée) + scarbhileog KSpread (criptithe) + folla de cálculo de KSpread (cifrada) + גליון נתונים של KSpread (מוצפן) + KSpread-munkafüzet (titkosított) + Lembar sebar KSpread (terenkripsi) + Foglio di calcolo KSpread (cifrato) + KSpread (暗号化) スプレッドシート + KSpread электрондық кестесі (шифрленген) + 암호화된 KSpread 스프레드시트 + KSpread skaičialentė (užšifruota) + KSpread izklājlapa (šifrēta) + Hampatan KSpread (terenkripsi) + KSpread-regneark (kryptert) + KSpread-rekenblad (versleuteld) + Kryptert KSpread-rekneark + Arkusz KSpread (zaszyfrowany) + folha de cálculo KSpread (cifrada) + Planilha do KSpread (criptografada) + Foaie de calcul KSpread (criptat) + электронная таблица KSpread (зашифрованная) + Zošit KSpread (šifrovaný) + Razpredelnica KSpread (šifrirana) + Fletë llogaritjesh KSpread (e kriptuar) + KSpread табеларни прорачун (шифровани) + KSpread-kalkylblad (krypterat) + ел. таблиця KSpread (зашифрована) + Bảng tính KSpread (đã mật mã) + KSpread 加密工作簿 + KSpread 試算表 (已加密) + + + + + + + KSysV init package + حزمة KSysV init + Inicyjalny pakunak KSysV + Пакет — KSysV init + paquet d'inici KSysV + Balíček init KSysV + KSsV init-pakke + KSysV-Init-Paket + paquete de configuración de init para KSysV + KSysV hasieratzeko paketea + KSysV init -paketti + KSysV init pakki + paquet d'initialisation KSysV + pacáiste thosú KSysV + paquete de KsysV init + חבילת KSysV init + KSysV init csomag + Paket init KSysV + Pacchetto init KSysV + KSysV init パッケージ + KSysV инициализация дестесі + KSysV init 패키지 + KSysV init paketas + KSysV inicializācijas pakotne + KSysV init-pakke + KSysV-init-pakket + KSysV init-pakke + Pakiet KSysV init + Pacote init do KSysV + Pachet KSysV init + пакет инициализации KSysV + Balíček KSysV init + Datoteka paketa KSysV init + Paketë init KSysV + KSysV init-paket + пакунок KSysV init + Gói sở khởi KSysV + KSysV init 软件包 + KSysV init 套件 + + + + + + + + + Kugar document + مستند Kugar + Dakument Kugar + Документ — Kugar + document de Kugar + Dokument Kugar + Kugardokument + Kugar-Dokument + έγγραφο Kugar + Kugar document + Kugar-dokumento + documento de Kugar + Kugar dokumentua + Kugar-asiakirja + Kugar skjal + document Kugar + cáipéis Kugar + documento de Kugar + מסמך Kugar + Kugar-dokumentum + Dokumen Kugar + Documento Kugar + KuKrita ドキュメント + Kugar құжаты + Kugar 문서 + Kugar dokumentas + Kugar dokuments + Dokumen Kugar + Kugar-dokument + Kugar-document + Kugar-dokument + Dokument Kuguar + documento Kugar + Documento do Kugar + Document Kugar + документ Kugar + Dokument Kugar + Dokument Kugar + Dokument Kugar + Kugar документ + Kugar-dokument + документ Kugar + Tài liệu Kugar + Kugar 文档 + Kugar 文件 + + + + + KWord document + مستند KWord + Dakument KWord + Документ — KWord + document de KWord + Dokument KWord + Dogfen KWord + KWord-dokument + KWord-Dokument + έγγραφο KWord + KWord document + KWord-dokumento + documento de KWord + KWord dokumentua + KWord-asiakirja + KWord skjal + document KWord + cáipéis KWord + documento de KWord + מסמך KWord + KWord-dokumentum + Dokumen KWord + Documento KWord + KWord ドキュメント + KWord құжаты + KWord 문서 + KWord dokumentas + KWord dokuments + Dokumen KWord + KWord-dokument + KWord-document + KWord-dokument + Dokument KWord + documento KWord + Documento do KWord + Document KWord + документ KWord + Dokument KWord + Dokument KWord + Dokument KWord + KWord документ + KWord-dokument + документ KWord + Tài liệu KWord + KWord 文档 + KWord 文件 + + + + + + + + + + + + + + + + + + KWord document (encrypted) + مستند KWord (مشفر) + Dakument KWord (zašyfravany) + Документ — KWord, шифриран + document de KWord (xifrat) + Dokument KWord (šifrovaný) + KWord-dokument (krypteret) + KWord-Dokument (verschlüsselt) + έγγραφο KWord (κρυπτογραφημένο) + KWord document (encrypted) + KWord-dokumento (ĉifrita) + documento de KWord (cifrado) + KWord dokumentua (enkriptatua) + KWord-asiakirja (salattu) + KWord skjal (bronglað) + document KWord (chiffré) + cáipéis KWord (criptithe) + documento de KWord (cifrado) + מסמך KWord (מוצפן) + KWord-dokumentum (titkosított) + Dokumen KWord (terenkripsi) + Documento KWord (cifrato) + KWord (暗号化) ドキュメント + KWord құжаты (шифрленген) + 암호화된 KWord 문서 + KWord dokumentas (užšifruotas) + KWord dokuments (šifrēts) + Dokumen Kword (terenkripsi) + KWord-dokument (kryptert) + KWord-document (versleuteld) + Kryptert KWord-dokument + Dokument KWord (zaszyfrowany) + documento KWord (cifrado) + Documento do KWord (criptografado) + Document KWord (criptat) + документ KWord (зашифрованный) + Dokument KWord (šifrovaný) + Dokument KWord (šifriran) + Dokument KWord (i kriptuar) + KWord документ (шифровани) + KWord-dokument (krypterat) + документ KWord (зашифрований) + Tài liệu KWord (đã mật mã) + KWord 加密文档 + KWord 文件 (已加密) + + + + + + + LHA archive + أرشيف LHA + LHA arxivi + Archiŭ LHA + Архив — LHA + arxiu LHA + Archiv LHA + Archif LHA + LHA-arkiv + LHA-Archiv + αρχείο LHA + LHA archive + LHA-arkivo + archivador LHA + LHA artxiboa + LHA-arkisto + LHA skjalasavn + archive LHA + cartlann LHA + arquivo LHA + ארכיון LHA + LHA-archívum + Arsip LHA + Archivio LHA + LHA アーカイブ + LHA архиві + LHA 압축 파일 + LHA archyvas + LHA arhīvs + Arkib LHA + LHA-arkiv + LHA-archief + LHA-arkiv + Archiwum LHA + arquivo LHA + Pacote LHA + Arhivă LHA + архив LHA + Archív LHA + Datoteka arhiva LHA + Arkiv LHA + LHA архива + LHA-arkiv + архів LHA + Kho nén LHA + LHA 归档文件 + LHA 封存檔 + + + + + + + + + + + + + + + + + + + + LHZ archive + أرشيف LHZ + Archiŭ LHZ + Архив — LHZ + arxiu LHZ + Archiv LHZ + LHZ-arkiv + LHZ-Archiv + αρχείο LHZ + LHZ archive + LHZ-arkivo + archivador LHZ + LHZ artxiboa + LHZ-arkisto + LHZ skjalasavn + archive LHZ + cartlann LHZ + arquivo LHZ + ארכיון LHZ + LHZ-archívum + Arsip LHZ + Archivio LHZ + LHZ アーカイブ + LHZ архиві + LHZ 압축 파일 + LHZ archyvas + LHZ arhīvs + Arkib LHZ + LHZ-arkiv + LHZ-archief + LHZ-arkiv + Archiwum LHZ + arquivo LHZ + Pacote LZH + Arhivă LHZ + архив LHZ + Archív LHZ + Datoteka arhiva LHZ + Arkiv LHZ + LHZ архива + LHZ-arkiv + архів LHZ + Kho nén LHZ (LHA đã nén) + LHZ 归档文件 + LHZ 封存檔 + + + + + message catalog + كتالوج الرسالة + kataloh paviedamleńniaŭ + Каталог със съобщения + catàleg de missatges + Katalog zpráv + meddelelseskatalog + Nachrichtenkatalog + κατάλογος μηνυμάτων + message catalogue + katalogo de mesaĝoj + catálogo de mensajes + mezuen katalogoa + viestiluettelo + boðskrá + catalogue de messages + catalóg theachtaireachtaí + catálogo de mensaxes + קטלוג הודעות + üzenetkatalógus + katalog pesan + Catalogo di messaggi + メッセージカタログ + мәлімдемелер каталогы + 메시지 카탈로그 + laiškų katalogas + ziņojumu katalogs + Katalog mesej + meldingskatalog + berichtencatalogus + meldingskatalog + Katalog wiadomości + catálogo de mensagens + católogo de mensagens + catalog de mesaje + каталог сообщений + Katalóg správ + katalogov sporočil + Katallog mesazhesh + каталог порука + meddelandekatalog + каталог повідомлень + phân loại thông điệp + 消息库 + 訊息目錄 + + + + + + + + + LyX document + مستند LyX + Dakument LyX + Документ — LyX + document de LyX + Dokument LyX + LyX-dokument + LyX-Dokument + έγγραφο LyX + LyX document + LyX-dokumento + documento de LyX + LyX dokumentua + LyX-asiakirja + LyX skjal + document LyX + cáipéis LyX + documento LyX + מסמך Lyx + LyX-dokumentum + Dokumen LyX + Documento LyX + LyX ドキュメント + LyX құжаты + LyX 문서 + LyX dokumentas + LyX dokuments + Dokumen LyX + LyX-dokument + LyX-document + LyX-dokument + Dokument LyX + documento LyX + Documento LyX + Document LyX + документ LyX + Dokument LyX + Dokument LyX + Dokument LyX + LyX документ + LyX-dokument + документ LyX + Tài liệu LyX + LyX 文档 + LyX 文件 + + + + + + + + + + Lzip archive + أرشيف Lzip + Архив — lzip + arxiu lzip + Archiv Lzip + Lzip-arkiv + Lzip-Archiv + Lzip-arkivo + archivador Lzip + Lzip artxiboa + Lzip-arkisto + Lzip skjalasavn + archive lzip + cartlann Lzip + arquivo Lzip + ארכיון Lzip + Lzip archívum + Arsip Lzip + Archivio Lzip + Lzip アーカイブ + Lzip архиві + LZIP 압축 파일 + Lzip archyvas + Lzip arhīvs + Archiwum lzip + Arhivă Lzip + архив LZIP + Archív Lzip + Datoteka arhiva Lzip + Lzip-arkiv + архів lzip + Lzip 归档文件 + Lzip 封存檔 + + + + + + + + LZMA archive + أرشيف LZMA + Archiŭ LZMA + Архив — LZMA + arxiu LZMA + Archiv LZMA + LZHA-arkiv + LZMA-Archiv + LZMA-arkivo + archivador LZMA + LZMA artxiboa + LZMA-arkisto + LZMA skjalasavn + archive LZMA + cartlann LZMA + arquivo LZMA + ארכיון LZMA + LZMA-archívum + Arsip LZMA + Archivio LZMA + LZMA アーカイブ + LZMA архиві + LZMA 압축 파일 + LZMA archyvas + LZMA arhīvs + LZMA-arkiv + LZMA-archief + LZMA-arkiv + Archiwum LZMA + Pacote LZMA + Arhivă LZMA + архив LZMA + Archív LZMA + Datoteka arhiva LZMA + Arkiv LZMA + LZMA-arkiv + архів LZMA + Kho nén LZMA + LZMA 归档文件 + LZMA 封存檔 + LZMA + Lempel-Ziv-Markov chain-Algorithm + + + + + Tar archive (LZMA-compressed) + أرشيف Tar (مضغوط-LZMA) + Archiŭ tar (LZMA-skampresavany) + Архив — tar, компресиран с LZMA + arxiu tar (comprimit amb LZMA) + Archiv tar (komprimovaný pomocí LZMA) + Tar-arkiv (LZMA-komprimeret) + Tar-Archiv (LZMA-komprimiert) + archivador Tar (comprimido con LZMA) + Tar artxiboa (LZMA-rekin konprimitua) + Tar-arkisto (LZMA-pakattu) + Tar skjalasavn (LZMA-stappað) + archive tar (compression LZMA) + cartlann Tar (comhbhrúite le LZMA) + arquivo Tar (comprimido con LZMA) + ארכיון Tar (מכווץ ע"י LZMA) + Tar archívum (LZMA-val tömörítve) + Arsip Tar (terkompresi LZMA) + Archivio tar (compresso con LZMA) + Tar アーカイブ (LZMA 圧縮) + Tar архиві (LZMA-мен сығылған) + TAR 묶음 파일 (LZMA 압축) + Tar archyvas (suglaudintas su LZMA) + Tar arhīvs (saspiests ar LZMA) + Tar-arkiv (LZMA-komprimert) + Tar-archief (ingepakt met LZMA) + Tar-arkiv (pakka med LZMA) + Archiwum tar (kompresja LZMA) + Pacote tar (compactado com LZO) + Arhivă Tar (comprimată LZMA) + архив TAR (сжатый LZMA) + Archív tar (komprimovaný pomocou LZMA) + Datoteka arhiva Tar (stisnjen z LZMA) + Arkiv tar (i kompresuar me LZMA) + Tar-arkiv (LZMA-komprimerat) + архів tar (стиснений LZMA) + Kho nén tar (đã nén LZMA) + Tar 归档文件 (LZMA 压缩) + Tar 封存檔 (LZMA 格式壓縮) + + + + + + LZO archive + أرشيف LZO + Archiŭ LZO + Архив — LZO + arxiu LZO + Archiv LZO + LZO-arkiv + LZO-Archiv + αρχείο LZO + LZO archive + LZO-arkivo + archivador LZO + LZO artxiboa + LZO-arkisto + LZO skjalasavn + archive LZO + cartlann LZO + arquivo LZO + ארכיון LZO + LZO-archívum + Arsip LZO + Archivio LZO + LZO アーカイブ + LZO архиві + LZO 압축 파일 + LZO archyvas + LZO arhīvs + Arkib LZO + LZO-arkiv + LZO-archief + LZO-arkiv + Archiwum LZO + arquivo LZO + Pacote LZO + Arhivă LZO + архив LZO + Archív LZO + Datoteka arhiva LZO + Arkiv LZO + LZO архива + LZO-arkiv + архів LZO + Kho nén LZO + LZO 归档文件 + LZO 封存檔 + LZO + Lempel-Ziv-Oberhumer + + + + + + + + MagicPoint presentation + عرض تقديمي MagicPoint + Prezentacyja MagicPoint + Презентация — MagicPoint + presentació de MagicPoint + Prezentace MagicPoint + Cyflwyniad MagicPoint + MagicPoint-præsentation + MagicPoint-Präsentation + παρουσίαση MagicPoint + MagicPoint presentation + MagicPoint-prezentaĵo + presentación de MagicPoint + MagicPoint aurkezpena + MagicPoint-esitys + MagicPoint framløga + présentation MagicPoint + láithreoireacht MagicPoint + presentación de MagicPoint + מצגת MagicPoint + MagicPoint-bemutató + Presentasi MagicPoint + Presentazione MagicPoint + MagicPoint プレゼンテーション + MagicPoint презентациясы + MagicPoint 프리젠테이션 + MagicPoint pateiktis + MagicPoint prezentācija + Persembahan MagicPoint + MagicPoint-presentasjon + MagicPoint-presentatie + MagicPoint-presentasjon + Prezentacja programu MagicPoint + apresentação MagicPoint + Apresentação do MagicPoint + Prezentare MagicPoint + презентация MagicPoint + Prezentácia MagicPoint + Predstavitev MagicPoint + Prezantim MagicPoint + MagicPoint презентација + MagicPoint-presentation + презентація MagicPoint + Trình diễn MagicPoint + MagicPoint 演示文稿 + MagicPoint 簡報檔 + + + + + + Macintosh MacBinary file + ملف Macintosh MacBinary + Fajł Macintosh MacBinary + Файл — MacBinary + fitxer MacBinary de Macintosh + Soubor MacBinary pro Macintosh + Macintosh MacBinary-fil + Macintosh-MacBinary-Datei + εκτελέσιμο Macintosh MacBinary + Macintosh MacBinary file + MacBinary-dosiero de Macintosh + archivo de Macintosh MacBinary + Macintosh MacBinary fitxategia + Macintosh MacBinary -tiedosto + Macintosh MacBinary fíla + fichier Macintosh MacBinary + comhad Macintosh MacBinary + ficheiro MacBinary de Macintosh + קובץ בינארי של מקינטוש + Macintosh MacBinary-fájl + Berkas Macintosh MacBinary + File Macintosh MacBinary + MacBinary MacBinary ファイル + Macintosh MacBinary файлы + MacBinary 파일 + Macintosh MacBinary failas + Macintosh MacBinary fails + Fail MacBinary Macintosh + Macintosh MacBinary-fil + Macintosh MacBinary-bestand + Macintosh MacBinary-fil + Plik MacBinary Macintosh + ficheiro MacBinary de Macintosh + Arquivo do Macintosh MacBinary + Fișier Macintosh MacBinary + файл Macintosh MacBinary + Súbor pre Macintosh MacBinary + Izvedljiva dvojiška datoteka Macintosh MacBinary + File MacBinary Macintosh + Мекинтош MacBinary датотека + Macintosh MacBinary-fil + файл Macintosh MacBinary + Tập tin nhị phân MacBinary của Macintosh + Macintosh MacBinary 文件 + Macintosh MacBinary 檔 + + + + + + + Matroska stream + دفق Matroska + Płyń Matroska + Поток — Matroska + flux Matroska + Proud Matroska + Matroskastrøm + Matroska-Datenstrom + flujo Matroska + Matroska korrontea + Matroska-virta + Matroska streymur + flux Matroska + sruth Matroska + fluxo de Matroska + זרימת Matroska + Matroska adatfolyam + Stream Matroska + Stream Matroska + Matroska ストリーム + Matroska ағымы + 매트로스카 스트림 + Matroska srautas + Matroska straume + Matroska-stream + Matroska-straum + Strumień Matroska + Transmissão do Matroska + Flux Matroska + поток Matroska + Stream Matroska + Pretočni vir Matroska + Stream Matroska + Matroska-ström + потік даних Matroska + Luồng Matroska + Matroska 流 + Matroska 串流 + + + + + + + + + + + + + + Matroska video + Matroska مرئي + Videa Matroska + Видео — Matroska + vídeo Matroska + Video Matroska + Matroskavideo + Matroska-Video + βίντεο Matroska + Matroska video + Matroska-video + vídeo Matroska + Matroska bideoa + Matroska-video + Matroska video + vidéo Matroska + físeán Matroska + vídeo de Matroska + וידאו Matroska + Matroska-videó + Video Matroska + Video Matroska + Matroska 動画 + Matroska видеосы + 매트로스카 비디오 + Matroska vaizdo įrašas + Matroska video + Video Matroska + Matroska-film + Matroska-video + Matroska-video + Plik wideo Matroska + vídeo Matroska + Vídeo Matroska + Video Matroska + видео Matroska + Video Matroska + Video datoteka Matroska + Video Matroska + Матрошка видео + Matroska-video + відеокліп Matroska + Ảnh động Matroska + Matroska 视频 + Matroska 視訊 + + + + + Matroska audio + سمعي Matroska + Aŭdyjo Matroska + Аудио — Matroska + àudio Matroska + Zvuk Matroska + Matroskalyd + Matroska-Audio + Matroska-sondosiero + sonido Matroska + Matroska audioa + Matroska-ääni + Matroska ljóður + audio Matroska + fuaim Matroska + son de Matroska + שמע Matroska + Matroska hang + Audio Matroska + Audio Matroska + Matroska オーディオ + Matroska аудиосы + 매트로스카 오디오 + Matroska garso įrašas + Matroska audio + Matroska-lyd + Matroska-audio + Matroska-lyd + Plik dźwiękowy Matroska + Áudio do Matroska + Audio Matroska + аудио Matroska + Zvuk Matroska + Zvočna datoteka Matroska + Audio Matroska + Matroska-ljud + звук Matroska + Âm thanh Matroska + Matroska 音频 + Matroska 音訊 + + + + + WebM video + WebM مرئي + Видео — WebM + vídeo WebM + Video WebM + WebM-video + WebM-Video + WebM-video + vídeo WebM + WebM-video + WebM video + vidéo WebM + físeán WebM + vídeo WebM + וידאו WebM + WebM videó + Video WebM + Video WebM + WebM 動画 + WebM видеосы + WebM 비디오 + WebM vaizdo įrašas + WebM video + Plik wideo WebM + Video WebM + видео WebM + Video WebM + Video datoteka WebM + WebM-video + відео WebM + WebM 视频 + WebM 視訊 + + + + + + + + + + + + + + WebM audio + WebM سمعي + Аудио — WebM + àudio WebM + Zvuk WebM + WebM-lyd + WebM-Audio + WebM-sondosiero + sonido WebM + WebM-ääni + WebM ljóður + audio WebM + fuaim WebM + son WebM + שמע WebM + WebM hang + Audio WebM + Audio WebM + WebM オーディオ + WebM аудиосы + WebM 오디오 + WebM garso įrašas + WebM audio + Plik dźwiękowy WebM + Audio WebM + аудио WebM + Zvuk WebM + Zvočna datoteka WebM + WebM-ljud + звук WebM + WebM 音频 + WebM 音訊 + + + + MXF video + MXF مرئي + Видео — MXF + vídeo MXF + Video MXF + MXF-video + MXF-Video + MXF-video + vídeo MXF + MXF bideoa + MXF-video + MXF video + vidéo MXF + físeán MXF + vídeo MXF + וידאו MXF + MXF videó + Video MXF + Video MXF + MXF 動画 + MXF видеосы + MXF 비디오 + MXF vaizdo įrašas + MXF video + Plik wideo MXF + Video MXF + видео MXF + Video MXF + Video datoteka MXF + MXF-video + відеокліп MXF + MXF 视频 + MXF 視訊 + MXF + Material Exchange Format + + + + + + + + OCL file + ملف OCL + Fajł OCL + Файл — OCL + fitxer OCL + Soubor OCL + OCL-fil + OCL-Datei + OCL-dosiero + archivo OCL + OCL fitxategia + OCL-tiedosto + OCL fíla + fichier OCL + comhad OCL + ficheiro OCL + קובץ OCL + OCL fájl + Berkas OCL + File OCL + OCL ファイル + OCL файлы + OCL 파일 + OCL failas + OCL fails + OCL-fil + OCL-bestand + OCL-fil + Plik OCL + Arquivo OCL + Fișier OCL + файл OCL + Súbor OCL + Datoteka OCL + File OCL + OCL-fil + файл OCL + Tập tin OCL + OCL 文件 + OCL 檔 + OCL + Object Constraint Language + + + + + COBOL source file + Изходен код — COBOL + codi font en COBOL + Zdrojový soubor COBOL + COBOL-Quelldatei + COBOL-fontdosiero + Archivo fuente de COBOL + COBOL-lähdekoodi + fichier source COBOL + ficheiro fonte de COBOL + קובץ מקור של COBOL + COBOL forrásfájl + Berkas sumber COBOL + File sorgente COBOL + COBOL ソースファイル + COBOL бастапқы коды + COBOL 소스 파일 + COBOL pirmkods + Plik źródłowy COBOL + файл исходного кода на COBOL + Izvorna koda COBOL + COBOL-källkodsfil + вихідний код мовою COBOL + COBOL 源 + COBOL 源檔 + COBOL + COmmon Business Oriented Language + + + + + + Mobipocket e-book + Е-книга — Mobipocket + llibre electrònic Mobipocket + Elektronická kniha Mobipocket + Mobipocket E-Book + Libro electrónico Mobipocket + Mobipocket e-kirja + livre numérique Mobipocket + E-book Mobipocket + ספר אלקטרוני של Mobipocket + Mobipocket e-könyv + e-book Mobipocket + E-book Mobipocket + Mobipocket 電子書籍 + Mobipocket эл. кітабы + Mobipocket 이북 + Mobipocket e-grāmata + E-book Mobipocket + электронная книга Mobipocket + e-knjiga Mobipocket + електронна книга Mobipocket + Mobipocket e-book + + + + + + + + + + + + + + Adobe FrameMaker MIF document + مستند أدوبي الصانع للإطارات MIF + Dakument Adobe FrameMaker MIF + Документ — Adobe FrameMaker MIF + document de FrameMaker MIF d'Adobe + Dokument Adobe FrameMaker MIF + Adobe FrameMaker MIF-dokument + Adobe-FrameMaker-MIF-Dokument + MIF-dokumento de Adobe FrameMaker + documento MIF de Adobe FrameMaker + Adobe FrameMaker-en MIF dokumentua + Adobe FrameMaker MIF -asiakirja + Adobe FrameMaker MIF skjal + document MIF Adobe FrameMaker + cáipéis MIF Adobe FrameMaker + documento MIF de Adobe FrameMaker + מסמך MIF של Adobe FrameMaker + Adobe FrameMaker MIF-dokumentum + Dokumen Adobe FrameMaker MIF + Documento MIF Adobe FrameMaker + Adobe FrameMaker MIF ドキュメント + Adobe FrameMaker MIF құжаты + 어도비 프레임메이커 MIF 문서 + Adobe FrameMaker MIF dokumentas + Adobe FrameMaker MIF dokuments + Adobe FrameMaker MIF-dokument + Adobe FrameMaker MIF-document + Adobe FrameMaker MIF-dokument + Dokument MIF Adobe FrameMaker + Documento MIF do Adobe FrameMaker + Document Adobe FrameMaker MIF + документ Adobe FrameMaker MIF + Dokument Adobe FrameMaker MIF + Dokument Adobe FrameMaker MIF + Dokument MIF Adobe FrameMaker + Adobe FrameMaker MIF-dokument + документ Adobe FrameMaker MIF + Tài liệu Adobe FrameMaker MIF + Adobe FrameMaker MIF 文档 + Adobe FrameMaker MIF 文件 + + + + Mozilla bookmarks + علامات موزيلا + Zakładki Mozilla + Отметки — Mozilla + llista d'adreces d'interès de Mozilla + Záložky Mozilla + Mozillabogmærker + Mozilla-Lesezeichen + σελιδοδείκτες Mozilla + Mozilla bookmarks + Mozilla-legosignoj + marcadores de Mozilla + Mozillako laster-markak + Mozilla-kirjanmerkit + Mozilla bókamerki + marque-pages Mozilla + leabharmharcanna Mozilla + Marcadores de Mozilla + סמניה של Mozilla + Mozilla-könyvjelzők + Bookmark Mozilla + Segnalibri Mozilla + Mozilla ブックマーク + Mozilla бетбелгілері + 모질라 책갈피 + Mozilla žymelės + Mozilla grāmatzīmes + Tandabuku Mozilla + Mozilla-bokmerker + Mozilla-bladwijzers + Mozilla-bokmerker + Zakładki Mozilla + marcadores do Mozilla + Marcadores do Mozilla + Semne de carte Mozilla + закладки Mozilla + Záložky Mozilla + Datoteka zaznamkov Mozilla + Libërshënues Mozilla + Mozilla обележивачи + Mozilla-bokmärken + закладки Mozilla + Liên kết đã lưu Mozilla + Mozilla 书签 + Mozilla 書籤 + + + + + + + + + DOS/Windows executable + تنفيذي DOS/Windows + Vykonvalny fajł DOS/Windows + Изпълним файл — DOS/Windows + executable de DOS/Windows + Spustitelný soubor pro DOS/Windows + DOS-/Windowskørbar + DOS/Windows-Programm + εκτελέσιμο DOS/Windows + DOS/Windows executable + DOS/Windows-plenumebla + ejecutable de DOS/Windows + DOS/Windows-eko exekutagarria + DOS/Windows-ohjelma + DOS/Windows inningarfør + exécutable DOS/Windows + comhad inrite DOS/Windows + executábel de DOS/Windows + קובץ בר־הרצה של DOS/חלונות + DOS/Windows futtatható + DOS/Windows dapat dieksekusi + Eseguibile DOS/Windows + DOS/Windows 実行ファイル + DOS/Windows орындалатын файлы + DOS/윈도우 실행파일 + DOS/Windows vykdomasis failas + DOS/Windows izpildāmais + Bolehlaksana DOS/Windows + Kjørbar fil for DOS/Windows + DOS/Windows-uitvoerbaar bestand + DOS/Windows køyrbar fil + Program DOS/Windows + executável DOS/Windows + Executável do DOS/Windows + Executabil DOS/Windows + исполняемый файл DOS/Windows + Spustiteľný súbor pre DOS/Windows + Izvedljiva datoteka DOS/Windows + I ekzekutueshëm DOS/Windows + ДОС/Виндоуз извршна датотека + Körbar DOS/Windows-fil + виконуваний файл DOS/Windows + Tập tin có thực hiện được DOS/Windows + DOS/Windows 可执行文件 + DOS/Windows 可執行檔 + + + + + + + + Internet shortcut + اختصار الإنترنت + Sieciŭnaja spasyłka + Адрес в Интернет + drecera d'Internet + Odkaz do Internetu + Internetgenvej + Internet-Verweis + acceso directo a Internet + Interneteko lasterbidea + Internet-pikakuvake + Alnetssnarvegur + raccourci Internet + aicearra Idirlín + atallo de Internet + קיצור דרך של האינטרנט + Internetes indítóikon + Jalan pintas Internet + Scorciatoia Internet + インターネットショートカット + Интернет сілтемесі + 인터넷 단축아이콘 + Interneto nuoroda + Interneta īsceļš + Internettsnarvei + internetkoppeling + Internett-snarveg + Skrót internetowy + Atalho da internet + Scurtătură Internet + Интернет-ссылка + Internetový odkaz + Internetna bližnjica + Shkurtim internet + Internetgenväg + інтернет-посилання + Lối tắt Internet + Internet 快捷方式 + 網際網路捷徑 + + + + + + + + + + WRI document + مستند WRI + Dakument WRI + Документ — WRI + document WRI + Dokument WRI + WRI-dokument + WRI-Dokument + WRI document + WRI-dokumento + documento WRI + WRI dokumentua + WRI-asiakirja + WRI skjal + document WRI + cáipéis WRI + documento WRI + מסמך WRI + WRI dokumentum + Dokumen WRI + Documento WRI + WRI ドキュメント + WRI құжаты + WRI 문서 + WRI dokumentas + WRI dokuments + WRI-dokument + WRI-document + WRI-dokument + Dokument WRI + Documento WRI + Document WRI + документ WRI + Dokument WRI + Dokument WRI + Dokument WRI + WRI-dokument + документ WRI + Tài liệu WRI + WRI 文档 + WRI 文件 + + + + + MSX ROM + MSX ROM + MSX ROM + ROM — MSX + ROM de MSX + ROM pro MSX + ROM MSX + MSX-rom + MSX-ROM + εικόνα μνήμης ROM MSX + MSX ROM + MSX-NLM + ROM de MSX + MSX-ko ROMa + MSX-ROM + MSX ROM + ROM MSX + ROM MSX + ROM de MSX + MSX ROM + MSX ROM + Memori baca-saja MSX + ROM MSX + MSX ROM + MSX ROM + MSX 롬 + MSX ROM + MSX ROM + ROM MSX + MSX-ROM + MSX-ROM + MSX-ROM + Plik ROM konsoli MSX + ROM MSX + ROM do MSX + ROM MSX + MSX ROM + ROM pre MSX + Bralni pomnilnik MSX + ROM MSX + MSX ром + MSX-rom + ППП MSX + ROM MSX + MSX ROM + MSX ROM + + + + + M4 macro + M4 macro + Makras M4 + Макроси — M4 + macro M4 + Makro M4 + M4-makro + M4-Makro + M4 macro + macro M4 + M4 makroa + M4-makro + M4 fjølvi + macro M4 + macra M4 + macro M4 + מאקרו M4 + M4 makró + Makro M4 + Macro M4 + M4 マクロ + M4 макросы + M4 매크로 + M4 macro + M4 makross + M4-makro + M4-macro + M4-makro + Makro M4 + Macro M4 + Macro M4 + макрос M4 + Makro M4 + Makro datoteka M4 + Macro M4 + M4-makro + макрос M4 + Vĩ lệnh M4 + M4 宏 + M4 巨集 + + + + + + Nintendo64 ROM + Nintendo64 ROM + Nintendo64 ROM + ROM — Nintendo64 + ROM de Nintendo64 + ROM pro Nintendo64 + Nintendo64-rom + Nintendo64-ROM + εικόνα μνήμης ROM Nintendo64 + Nintendo64 ROM + Nintendo64-NLM + ROM de Nintendo64 + Nintendo64-ko ROMa + Nintendo64-ROM + Nintendo64 ROM + ROM Nintendo64 + ROM Nintendo64 + ROM de Nintendo64 + ROM של Nןמאקמגם64 + Nintendo64 ROM + Memori baca-saja Nintendo64 + ROM Nintendo64 + Nintendo64 ROM + Nintendo64 ROM + 닌텐도 64 롬 + Nintendo64 ROM + Nintendo64 ROM + ROM Nintendo64 + Nintendo64-ROM + Nintendo64-ROM + Nintendo64-ROM + Plik ROM konsoli Nintendo64 + ROM Nintendo64 + ROM do Nintendo64 + ROM Nintendo64 + Nintendo64 ROM + ROM pre Nintendo64 + Bralni pomnilnik Nintendo64 + ROM Nintendo64 + Нинтендо64 РОМ + Nintendo64-rom + ППП Nintendo64 + ROM Nintendo64 + Nintendo64 ROM + Nintendo64 ROM + + + + + Nautilus link + وصلة Nautilus + Nautilus körpüsü + Spasyłka Nautilus + Връзка — Nautilus + enllaç de Nautilus + Odkaz Nautilus + Cyswllt Nautilus + Nautilus-henvisning + Nautilus-Verknüpfung + σύνδεσμος Nautilus + Nautilus link + Nautilus-ligilo + enlace de Nautilus + Nautilus esteka + Nautilus-linkki + Nautilus leinkja + lien Nautilus + nasc Nautilus + ligazón de nautilus + קישור של Nautilus + Nautilus-link + Taut Nautilus + Collegamento Nautilus + Nautilus リンク + Nautilus сілтемесі + 노틸러스 링크 + Nautilus nuoroda + Nautilus saite + Pautan Nautilus + Nautilus-lenke + Nautilus-verwijzing + Nautilus-lenke + Odnośnik Nautilus + atalho Nautilus + Link do Nautilus + Legătură Nautilus + ссылка Nautilus + Odkaz Nautilus + Datoteka povezave Nautilus + Lidhje Nautilus + Наутилус веза + Nautiluslänk + посилання Nautilus + Liên kết Nautilus + Nautilus 链接 + Nautilus 鏈結 + + + + + + + + + NES ROM + NES ROM + NES ROM + ROM — NES + ROM de NES + ROM pro NES + ROM NES + NES-rom + NES-ROM + εικόνα μνήμης ROM NES + NES ROM + NES-NLM + ROM de NES + NES-eko ROMa + NES-ROM + NES ROM + ROM NES + ROM NES + ROM de NES + ROM של NES + NES ROM + Memori baca-saja NES + ROM NES + ファミコン ROM + NES ROM + NES 롬 + NES ROM + NES ROM + ROM NES + NES ROM + Nintendo + NES-ROM + Plik ROM konsoli NES + ROM NES + ROM do NES + ROM NES + NES ROM + ROM pre NES + Bralni pomnilnik NES + ROM NES + NES ром + NES-rom + ППП NES + ROM NES + NES ROM + 任天堂 ROM + + + + + Unidata NetCDF document + مستند Unidata NetCDF + Dakument Unidata NetCDF + Документ — Unidata NetCDF + document Unidata NetCDF + Dokument Unidata NetCDF + Unidata NetCDF-dokument + Unidata-NetCDF-Dokument + έγγραφο Unidata NetCDF + Unidata NetCDF document + dokumento en NetCDF-formato de Unidata + documento de Unidata NetCDF + Unidata NetCDF dokumentua + Unidata NetCDF -asiakirja + Unidata NetCDF skjal + document Unidata NetCDF + cáipéis Unidata NetCDF + Documentno de Unixdata NetCDF + מסמך של Unidata NetCDF + Unidata NetCDF-dokumentum + Dokumen Unidata NetCDF + Documento Unidata NetCDF + Unidata NetCDF ドキュメント + Unidata NetCDF құжаты + Unidata NetCDF 문서 + Unidata NetCDF dokumentas + Unidata NetCDF dokuments + Dokumen Unidata NetCDF + Unidata NetCDF-dokument + Unidata NetCDF-document + Unidata netCDF-dokument + Dokument Unidata NetCDF + documento Unidata NetCDF + Documento do Unidata NetCDF + Document Unidata NetCDF + документ Unidata NetCDF + Dokument Unidata NetCDF + Dokument Unidata NetCDF + Dokument Unidata NetCDF + Unidata NetCDF документ + Unidata NetCDF-dokument + документ Unidata NetCDF + Tài liệu NetCDF Unidata + Unidata NetCDF 文档 + Unidata NetCDF 文件 + NetCDF + Network Common Data Form + + + + + + NewzBin usenet index + Индекс — Usenet, NewzBin + índex d'Usenet NewzBin + Index NewzBin diskuzních skupin Usenet + Índice NewzBin de usenet + index usenet + Índice de usenet NEwzBin + אינדקס שרתי חדשות NewzBin + Indeks usenet NewzBin + Indice Usenet NewzBiz + NewzBin Usenet インデックス + NewzBin usenet индексі + NewzBin usenet rādītājs + Indeks grup dyskusyjnych NewzBin + индекс usenet NewzBin + Kazalo usenet NewzBin + покажчик usenet NewzBin + + + + + + + + object code + رمز الكائن + abjektny kod + Обектен код + codi objecte + Objektový kód + objektkode + Objekt-Code + μεταφρασμένος κώδικας + object code + celkodo + código objeto + objektu kodea + objektikoodi + code objet + cód réada + código obxecto + קוד אובייקט + tárgykód + kode object + Codice oggetto + オブジェクトコード + объектті коды + 개체 코드 + objektinis kodas + objekta kods + Kod objek + objektkode + objectcode + objektkode + Kod obiektowy + código de objecto + código objeto + cod sursă obiect + объектный код + Objektový kód + predmetna koda + Kod objekti + објектни ко̂д + objektkod + об'єктний код + mã đối tượng + 目标代码 + 目的碼 + + + + + + + + + + + + + + + + + Annodex exchange format + صيغة Annodex البديلة + Формат за обмяна — Annodex + format d'intercanvi Annodex + Výměnný formát Annodex + Udvekslingsformat for Annodex + Annodex-Wechselformat + formato de intercambio Annodex + Annodex trukatze-formatua + Annodex-siirtomuoto + Annodex umbýtingarsnið + format d'échange Annodex + formáid mhalairte Annodex + formato intercambiábel de Annodex + פורמט החלפת Annodex + Annodex csereformátum + Format pertukaran Annodex + Formato di scambio Annodex + Annodex 交換フォーマット + Annodex алмасу пішімі + Annodex 교환 형식 + Annodex mainų formatas + Annodex apmaiņas formāts + Annodex-exchange + Format wymiany Annodex + Formato de troca Annodex + Format schimb Annodex + формат обмена Annodex + Formát pre výmenu Annodex + Izmenjalna datoteka Annodex + Annodex-utväxlingsformat + формат обміну даними Annodex + Định dạng trao đổi Annodex + Annodex 交换格式 + Annodex 交換格式 + + + + + + + + + + + + + Annodex Video + Annodex مرئي + Видео — Annodex + Annodex Video + Annodex Video + Annodexvideo + Annodex-Video + Annodex-video + vídeo Annodex + Annodex bideoa + Annodex-video + Annodex video + vidéo Annodex + físeán Annodex + vídeo de Annodex + וידאו Annodex + Annodex videó + Video Annodex + Video Annodex + Annodex 動画 + Annodex видеосы + Annodex 비디오 + Annodex vaizdo įrašas + Annodex video + Annodex Video + Plik wideo Annodex + Vídeo Annodex + Video Annodex + видео Annodex + Video Annodex + Video datoteka Annodex + Annodex-video + відеокліп Annodex + Ảnh động Annodex + Annodex 视频 + Annodex 視訊 + + + + + + + + + + + + + Annodex Audio + Annodex سمعي + Аудио — Annodex + Annodex Audio + Annodex Audio + Annodexlyd + Annodex-Audio + Annodex-sondosiero + sonido Annodex + Annodex audioa + Annodex-ääni + Annodex ljóður + audio Annodex + fuaim Annodex + son de Annodex + שמע Annodex + Annodex hang + Audio Annodex + Audio Annodex + Annodex オーディオ + Annodex аудиосы + Annodex 오디오 + Annodex garso įrašas + Annodex audio + Annodex Audio + Plik dźwiękowy Annodex + Áudio Annodex + Audio Annodex + аудио Annodex + Zvuk Annodex + Zvočna datoteka Annodex + Annodex-ljud + звук Annodex + Âm thanh Annodex + Annodex 音频 + Annodex 音訊 + + + + + + + + + + + + + Ogg multimedia file + ملف وسائط متعددة Ogg + Multymedyjny fajł Ogg + Мултимедия — Ogg + fitxer Ogg multimèdia + Soubor multimédií Ogg + Ogg multimedie-fil + Ogg-Multimediadatei + archivo multimedia Ogg + Ogg multimediako fitxategia + Ogg-multimediatiedosto + Ogg margmiðlafíla + fichier multimédia Ogg + comhad ilmheán Ogg + ficheiro multimedia Ogg + קובץ מולטימדיה Ogg + Ogg multimédiafájl + Berkas multimedia Ogg + File multimediale Ogg + Ogg マルチメディアファイル + Ogg мультимедиа файлы + Ogg 멀티미디어 파일 + Ogg multimedijos failas + Ogg multimediju fails + Ogg-multimediafil + Ogg-multimediabestand + Ogg multimediafil + Plik multimedialny Ogg + Arquivo multimídia Ogg + Fișier multimedia Ogg + мультимедийный файл Ogg + Súbor multimédií Ogg + Večpredstavnostna datoteka Ogg + File multimedial Ogg + Ogg-multimediafil + мультимедійний файл Ogg + Tập tin đa phương tiện Ogg + Ogg 多媒体文件 + Ogg 多媒體檔案 + + + + + + + + + Ogg Audio + Ogg سمعي + Aŭdyjo Ogg + Аудио — Ogg + àudio Ogg + Zvuk Ogg + Ogg-lyd + Ogg-Audio + sonido Ogg + Ogg audioa + Ogg-ääni + Ogg ljóður + audio Ogg + fuaim Ogg + son Ogg + שמע Ogg + Ogg hang + Audio Ogg + Audio Ogg + Ogg オーディオ + Ogg аудиосы + Ogg 오디오 + Ogg garso įrašas + Ogg audio + Ogg lyd + Ogg-audio + Ogg-lyd + Plik dźwiękowy Ogg + Áudio Ogg + Audio Ogg + аудио Ogg + Zvuk Ogg + Zvočna datoteka Ogg + Audio Ogg + Ogg-ljud + звук ogg + Âm thanh Ogg + Ogg 音频 + Ogg 音訊 + + + + + + + + + + + Ogg Video + Ogg مرئي + Videa Ogg + Видео — Ogg + vídeo Ogg + Video Ogg + Ogg-video + Ogg-Video + vídeo Ogg + Ogg bideoa + Ogg-video + Ogg Video + vidéo Ogg + físeán Ogg + vídeo Ogg + וידאו Ogg + Ogg videó + Video Ogg + Video Ogg + Ogg 動画 + Ogg видеосы + Ogg 비디오 + Ogg vaizdo įrašas + Ogg video + Ogg video + Ogg-video + Ogg-video + Plik wideo Ogg + Vídeo Ogg + Video Ogg + видео Ogg + Video Ogg + Video datoteka Ogg + Video Ogg + Ogg-video + відеокліп ogg + Ảnh động Ogg + Ogg 视频 + Ogg 視訊 + + + + + + + + + Ogg Vorbis audio + Ogg Vorbis سمعي + Ogg Vorbis audio faylı + Aŭdyjo Ogg Vorbis + Аудио — Ogg Vorbis + àudio Ogg Vorbis + Zvuk Ogg Vorbis + Sain Ogg Vorbis + Ogg Vorbis-lyd + Ogg-Vorbis-Audio + ήχος Ogg Vobris + Ogg-Vorbis-sondosiero + sonido Ogg Vorbis + Ogg Vorbis audioa + Ogg Vorbis -ääni + Ogg Vorbis ljóður + audio Ogg Vorbis + fuaim Ogg Vorbis + son Ogg Vorbis + שמע Ogg Vorbis + Ogg Vorbis hang + Audio Ogg Vorbis + Audio Ogg Vorbis + Ogg Vorbis オーディオ + Ogg Vorbis аудиосы + Ogg Vorbis 오디오 + Ogg Vorbis garso įrašas + Ogg Vorbis audio + Audio Ogg Vorbis + Ogg Vorbis lyd + Ogg Vorbis-audio + Ogg Vorbis-lyd + Plik dźwiękowy Ogg Vorbis + áudio Ogg Vorbis + Áudio do Ogg Vorbis + Audio Ogg Vorbis + аудио Ogg Vorbis + Zvuk Ogg Vorbis + Zvočna datoteka Ogg Vorbis + Audio Ogg Vorbis + Ог-ворбис звучни запис + Ogg Vorbis-ljud + звук ogg Vorbis + Âm thanh Vorbis Ogg + Ogg Vorbis 音频 + Ogg Vorbis 音訊 + + + + + + + + + + + + Ogg FLAC audio + Ogg FLAC سمعي + Aŭdyjo Ogg FLAC + Аудио — Ogg FLAC + àudio Ogg FLAC + Zvuk Ogg FLAC + Ogg FLAC-lyd + Ogg-FLAC-Audio + sonido Ogg FLAC + Ogg FLAC audioa + Ogg FLAC -ääni + Ogg FLAC ljóður + audio Ogg FLAC + fuaim Ogg FLAC + son Ogg FLAC + שמע Ogg FLAC + Ogg FLAC hang + Audio Ogg FLAC + Audio Ogg FLAC + Ogg FLAC オーディオ + Ogg FLAC аудиосы + Ogg FLAC 오디오 + Ogg FLAC garso įrašas + Ogg FLAC audio + Ogg FLAC-lyd + Ogg FLAC-audio + Ogg FLAC-lyd + Plik dźwiękowy Ogg FLAC + Áudio FLAC Ogg + Audio Ogg FLAC + аудио Ogg FLAC + Zvuk Ogg FLAC + Zvočna datoteka Ogg FLAC + Audio Ogg FLAC + Ogg FLAC-ljud + звук ogg FLAC + Âm thanh FLAC Ogg + Ogg FLAC 音频 + Ogg FLAC 音訊 + + + + + + + + + + + + + + Ogg Speex audio + Ogg Speex سمعي + Aŭdyjo Ogg Speex + Аудио — Ogg Speex + àudio Ogg Speex + Zvuk Ogg Speex + Ogg Speex-lyd + Ogg-Speex-Audio + sonido Ogg Speex + Ogg Speex audioa + Ogg Speex -ääni + Ogg Speex ljóður + audio Ogg Speex + fuaim Ogg Speex + son Ogg Speex + שמע Ogg Speex + Ogg Speex hang + Audio Ogg Speex + Audio Ogg Speex + Ogg Speex オーディオ + Ogg Speex аудиосы + Ogg Speex 오디오 + Ogg Speex garso įrašas + Ogg Speex audio + Ogg Speex lyd + Ogg Speex-audio + Ogg Speex-lyd + Plik dźwiękowy Ogg Speex + Áudio Speex Ogg + Audio Ogg Speex + аудио Ogg Speex + Zvuk Ogg Speex + Zvočna datoteka Ogg Speex + Audio Ogg Speex + Ogg Speex-ljud + звук ogg Speex + Âm thanh Speex Ogg + Ogg Speex 音频 + Ogg Speex 音訊 + + + + + + + + + + Speex audio + Speex سمعي + Aŭdyjo Speex + Аудио — Speex + àudio Speex + Zvuk Speex + Speexlyd + Speex-Audio + sonido Speex + Speex audioa + Speex-ääni + Speex ljóður + audio Speex + fuaim Speex + son Speex + שמע של Speex + Speex hang + Audio Speex + Audio Speex + Speex オーディオ + Speex аудиосы + Speex 오디오 + Speex garso įrašas + Speex audio + Speex lyd + Speex-audio + Speex-lyd + Plik dźwiękowy Speex + Áudio Speex + Audio Speex + аудио Speex + Zvuk Speex + Zvočna datoteka Speex + Audio Speex + Speex-ljud + звук Speex + Âm thanh Speex + Speex 音频 + Speex 音訊 + + + + + + + Ogg Theora video + Ogg Theora مرئي + Videa Ogg Theora + Видео — Ogg Theora + vídeo Ogg Theora + Video Ogg Theora + Ogg Theora-video + Ogg-Theora-Video + vídeo Ogg Theora + Ogg Theora bideoa + Ogg Theora -video + Ogg Theora video + vidéo Ogg Theora + físeán Ogg Theora + vídeo Ogg Theora + שמע Ogg Theora + Ogg Theora videó + Video Ogg Theora + Video Ogg Theora + Ogg Theora 動画 + Ogg Theora видеосы + Ogg Theora 비디오 + Ogg Theora vaizdo įrašas + Ogg Theora video + Ogg Theora video + Ogg Theora-video + Ogg Theora-video + Plik wideo Ogg Theora + Vídeo do Ogg Theora + Video Ogg Theora + видео Ogg Theora + Video Ogg Theora + Video datoteka Ogg Theora + Video Ogg Theora + Ogg Theora-video + відеокліп ogg Theora + Ảnh động Theora Ogg + Ogg Theora 视频 + Ogg Theora 視訊 + + + + + + + + + + + OGM video + OGM مرئي + Videa OGM + Видео — OGM + vídeo OGM + Video OGM + OGM-video + OGM-Video + OGM-video + vídeo OGM + OGM bideoa + OGM-video + OGM video + vidéo OGM + físeán OGM + vídeo OGM + וידאו OGM + OGM-videó + Video OGM + Video OGM + OGM 動画 + OGM видеосы + OGM 비디오 + OGM vaizdo įrašas + OGM video + OGM-film + OGM-video + OGM-video + Plik wideo OGM + Vídeo OGM + Video OGM + видео OGM + Video OGM + Video datoteka OGM + Video OGM + OGM-video + відеокліп OGM + Ảnh động OGM + OGM 视频 + OGM 視訊 + + + + + + + + + + + + OLE2 compound document storage + تخزين مجمع مستند OLE2 + Schovišča dla kampanentaŭ dakumentu OLE2 + Съставен документ-хранилище — OLE2 + emmagatzematge de documents composats OLE2 + Úložiště složeného dokumentu OLE2 + OLE2-sammensat dokumentlager + OLE2-Verbunddokumentenspeicher + αρχείο συμπαγούς αποθήκευσης εγγράφων OLE2 + OLE2 compound document storage + OLE2-deponejo de parentezaj dokumentoj + almacenamiento de documentos compuestos OLE2 + OLE2 konposatutako dokumentu-bilduma + OLE2-yhdisteasiakirjatallenne + OLE2 samansett skjalagoymsla + document de stockage composé OLE2 + stóras cháipéisí comhshuite OLE2 + almacenamento de documento composto OLE2 + אחסון מסמך משותף OLE2 + OLE2 összetett dokumentumtároló + penyimpan dokumen kompon OLE2 + Memorizzazione documento composto OLE2 + OLE2 複合ドキュメントストレージ + OLE2 құрама құжаттар қоймасы + OLE2 복합 문서 + OLE2 sudėtinių dokumentų laikmena + OLE2 savienoto dokumentu glabātuve + Storan dokumen halaman OLE2 + OLE-lager for sammensatte dokumenter + OLE2-samengestelde documentopslag + OLE2 lager for samansett dokument + Magazyn dokumentu złożonego OLE2 + armazenamento de documento composto OLE2 + Armazenamento de documento composto OLE2 + Document de stocare compus OLE2 + хранилище составных документов OLE2 + Úložisko zloženého dokumentu OLE2 + Združeni dokument OLE2 + Arkiv dokumenti i përbërë OLE2 + ОЛЕ2 сједињени документ + Sammansatt OLE2-dokumentlager + сховище складних документів OLE2 + Kho lưu tài liệu ghép OLE2 + OLE2 组合文档存储 + OLE2 複合文件儲存 + + + + + + + + Windows Installer package + حزمة مثبّت ويندوز + Pakunak Windows Installer + Пакет — инсталация за Windows + paquet de Windows Installer + Balíček Windows Installer + Windows Installer-pakke + Windows Installationspaket + paquete de instalación de Windows + Windows-eko pakete instalatzailea + Windows-asennuspaketti + Windows innleggingarpakki + paquet d'installation Windows + pacáiste Windows Installer + paquete de instalación de Windows + חבילה של Windows Installer + Windows Installer csomag + Paket Windows Installer + Pacchetto Windows Installer + Windodws インストーラパッケージ + Windows Installer дестесі + 윈도우 설치 패키지 + Windows Installer paketas + Windows Installer pakotne + Windows-installatiepakket + Windows Installer-pakke + Pakiet instalatora Windows + Pacote do instalador do Windows + Pachet instalator Windows + пакет Windows Installer + Balík Windows Installer + Datoteka paketa Windows namestilnika + Paketë Windows Installer + Windows Installer-paket + пакунок Windows Installer + Gói cài đặt Windows + Windows 程序安装包 + Windows Installer 套件 + + + + + GNU Oleo spreadsheet + جدول جنو Oleo + Raźlikovy arkuš GNU Oleo + Таблица — GNU Oleo + full de càlcul de GNU Oleo + Sešit GNU Oleo + GNU Oleo-regneark + GNU-Oleo-Tabelle + λογιστικό φύλλο GNU Oleo + GNU Oleo spreadsheet + Kalkultabelo de GNU Oleo + hoja de cálculo de GNU Oleo + GNU Oleo kalkulu-orria + GNU Oleo -taulukko + GNU Oleo rokniark + feuille de calcul GNU Oleo + scarbhileog GNU Oleo + folla de cálculo de Oleo GNU + גליון נתונים של GNU Oleo + GNU Oleo-munkafüzet + Lembar sebar GNU Oleo + Foglio di calcolo GNU Oleo + GNU Oleo スプレッドシート + GNU Oleo электрондық кестесі + GNU Oleo 스프레드시트 + GNU Oleo skaičialentė + GNU Oleo izklājlapa + Hamparan GNU Oleo + GNU Oleo regneark + GNU Oleo-rekenblad + GNU Oleo-rekneark + Arkusz GNU Oleo + folha de cálculo GNU Oleo + Planilha do GNU Oleo + Foaie de calcul GNU Oleo + электронная таблица GNU Oleo + Zošit GNU Oleo + Razpredelnica GNU Oleo + Fletë llogaritje GNU Oleo + ГНУ Oleo табеларни прорачун + GNU Oleo-kalkylblad + ел. таблиця GNU Oleo + Bảng tính Oleo của GNU + GNU Oleo 工作簿 + GNU Oleo 試算表 + + + + + + + + PAK archive + أرشيف PAK + Archiŭ PAK + Архив — PAK + arxiu PAK + Archiv PAK + PAK-arkiv + PAK-Archiv + PAK-arkivo + archivador PAK + PAK artxiboa + PAK-arkisto + PAK skjalasavn + archive PAK + cartlann PAK + arquivo PAK + ארכיון PAK + PAK-archívum + Arsip PAK + Archivio PAK + PAK アーカイブ + PAK архиві + PAK 묶음 파일 + PAK archyvas + PAK arhīvs + PAK-arkiv + PAK-archief + PAK-arkiv + Archiwum PAK + Pacote PAK + Arhivă PAK + архив PAK + Archív PAK + Datoteka arhiva PAK + Arkiv PAK + PAK-arkiv + архів PAK + Kho nén PAK + AR 归档文件 + PAK 封存檔 + + + + + + + + Palm OS database + قاعدة بيانات Palm OS + Palm OS mə'lumat bazası + Baza źviestak Palm OS + База от данни — Palm OS + base de dades Palm OS + Databáze Palm OS + Cronfa Ddata Palm OS + Palm OS-database + Palm-OS-Datenbank + βάση δεδομένων Palm OS + Palm OS database + datumbazo de Palm OS + base de datos de Palm OS + Palm OS datu-basea + Palm OS -tietokanta + Palm OS dátustovnur + base de données Palm OS + bunachar sonraí Palm OS + base de datos de Palm OS + מסד נתונים של Palm OS + Palm OS-adatbázis + Basis data Palm OS + Database Palm OS + Palm OS データベース + Palm OS дерекқоры + 팜OS 데이터베이스 + Palm OS duomenų bazė + Palm OS datubāze + Pangkalandata PalmOS + Palm OS-database + Palm OS-gegevensbank + Palm OS-database + Baza danych Palm OS + base de dados do Palm OS + Banco de dados do Palm OS + Bază de date Palm OS + база данных Palm OS + Databáza Palm OS + Podatkovna zbirka Palm OS + Bankë me të dhëna Palm OS + Palm OS база података + Palm OS-databas + база даних Palm OS + Cơ sở dữ liệu PalmOS + Palm OS 数据库 + Palm OS 資料庫 + + + + + + Parchive archive + أرشيف Parchive + Archiŭ Parchive + Архив — parchive + arxiu Parchive + Archiv Parchive + Parchive-arkiv + Parchive-Archiv + archivador Parchive + Parchive artxiboa + Parchive-arkisto + Parchive skjalasavn + archive Parchive + cartlann Parchive + arquivo Parchive + ארכיון של Parchive + Parchive archívum + Arsip Parchive + Archivio Parchive + Parchive アーカイブ + Parchive архиві + Parchive 묶음 파일 + Parchive archyvas + Parchive arhīvs + Parchive-arkiv + Parchive-archief + Parchive-arkiv + Archiwum parchive + Pacote Parchive + Arhivă Parchive + архив Parchive + Archív Parchive + Datoteka arhiva Parchive + Arkiv Parchive + Parchive-arkiv + архів Parchive + Kho nén Parchive + Parchive 归档文件 + Parchive 封存檔 + Parchive + Parity Volume Set Archive + + + + + + + + + PEF executable + PEF تنفيذي + Vykonvalny fajł PEF + Изпълним файл — PEF + executable PEF + Spustitelný soubor PEF + PEF-kørbar + PEF-Programm + εκτελέσιμο PEF + PEF executable + PEF-plenumebla + ejecutable PEF + PEF exekutagarria + PEF-ohjelma + PEF inningarfør + exécutable PEF + comhad inrite PEF + Executábel PEF + קובץ הרצה PEF + PEF futtatható + PEF dapat dieksekusi + Eseguibile PEF + PEF 実行ファイル + PEF орындалатын файлы + PEF 실행파일 + PEF vykdomasis failas + PEF izpildāmais + Bolehlaksana PEF + PEF-kjørbar + PEF-uitvoerbaar bestand + Køyrbar PEF-fil + Program PEF + executável PEF + Executável PEF + Executabil PEF + исполняемый файл PEF + Spustiteľný súbor PEF + Izvedljiva datoteka PEF + E ekzekutueshme PEF + PEF извршна + Körbar PEF-fil + виконуваний файл PEF + Tập tin thực hiện được PEF + PEF 可执行文件 + PEF 可執行檔 + + + + + + + Perl script + سكربت بيرل + Skrypt Perl + Скрипт — Perl + script Perl + Skript v Perlu + Sgript Perl + Perlprogram + Perl-Skript + πρόγραμμα εντολών Perl + Perl script + Perl-skripto + script en Perl + Perl script-a + Perl-komentotiedosto + Perl boðrøð + script Perl + script Perl + Script de Perl + תסריט מעטפת של Perl + Perl-parancsfájl + Skrip Perl + Script Perl + Perl スクリプト + Perl сценарийі + 펄 스크립트 + Perl scenarijus + Perl skripts + Skrip Perl + Perl skript + Perl-script + Perl-skript + Skrypt Perl + 'script' Perl + Script Perl + Script Perl + сценарий Perl + Skript jazyka Perl + Skriptna datoteka Perl + Script Perl + Перл скрипта + Perlskript + скрипт на Perl + Văn lệnh Perl + Perl 脚本 + Perl 指令稿 + + + + + + + + + + + + + + + PHP script + سكربت PHP + PHP skripti + Skrypt PHP + Скрипт — PHP + script PHP + Skript PHP + Sgript PHP + PHP-program + PHP-Skript + πρόγραμμα εντολών PHP + PHP script + PHP-skripto + script en PHP + PHP script-a + PHP-komentotiedosto + PHP boðrøð + script PHP + script PHP + Script de PHP + תסריט מעטפת של PHP + PHP-parancsfájl + Skrip PHP + Script PHP + PHP スクリプト + PHP сценарийі + PHP 스크립트 + PHP scenarijus + PHP skripts + Skrip PHP + PHP-skript + PHP-script + PHP-skript + Skrypt PHP + 'script' PHP + Script PHP + Script PHP + сценарий PHP + Skript PHP + Skriptna datoteka PHP + Script PHP + PHP скрипта + PHP-skript + скрипт PHP + Văn lệnh PHP + PHP 脚本 + PHP 指令稿 + + + + + + + + + + + + + PKCS#7 certificate bundle + رزمة الشهادة PKCS#7 + Сбор със сертификати — PKCS#7 + conjunt de certificats PKCS#7 + Svazek certifikátů PKCS#7 + PKCS#7-certifikatbundt + PKCS#7-Zertifikatspaket + lote de certificados PCKS#7 + PKCS#7 zertifikazio sorta + PKCS#7-varmennenippu + PKCS#7 váttanar bundi + lot de certificats PKCS#7 + cuach theastas PKCS#7 + paquete de certificado PKCS#7 + בקשה מוסמכת PKCS#7 + PKCS#7-tanúsítványcsomag + Bundel sertifikat PKCS#7 + Bundle certificato PKCS#7 + PKCS#7 証明書 + PKCS#7 сертификаттар дестесі + PKCS#7 인증서 묶음 + PKCS#7 liudijimų ryšulys + PKCS#7 sertifikātu saišķis + PKCS#7-certificaatbundel + Pakiet certyfikatu PKCS#7 + Pacote de certificados PKCS#7 + Pachet certificat PKCS#7 + пакет сертификатов PKCS#7 + Zväzok certifikátov PKCS#7 + Datoteka potrdila PKCS#7 + PKCS#7-certifikatsamling + комплект сертифікатів PKCS#7 + Bó chứng nhận PKCS#7 + PKCS#7 证书束 + PKCS#7 憑證綁包 + PKCS + Public-Key Cryptography Standards + + + + + PKCS#12 certificate bundle + رزمة الشهادة PKCS#12 + Viazka sertyfikataŭ PKCS#12 + Сбор със сертификати — PKCS#12 + conjunt de certificats PKCS#12 + Svazek certifikátů PKCS#12 + PKCS#12-certifikatbundt + PKCS#12-Zertifikatspaket + πακέτο ψηφιακών πιστοποιητικών PKCS#12 + PKCS#12 certificate bundle + ligaĵo de PKCS#12-certigiloj + lote de certificados PCKS#12 + PKCS#12 zertifikazio sorta + PKCS#12-varmennenippu + PKCS#12 váttanar bundi + lot de certificats PKCS#12 + cuach theastas PKCS#12 + paquete de certificado PKCS#12 + בקשה מוסמכת PKCS#12 + PKCS#12-tanúsítványcsomag + Bundel sertifikat PKCS#12 + Bundle certificato PKCS#12 + PKCS#12 証明書 + PKCS#12 сертификаттар дестесі + PKCS#12 인증서 묶음 + PKCS#12 liudijimų ryšulys + PKCS#12 sertifikātu saišķis + Sijil PKCS#12 + PKCS#12 sertifikathaug + PKCS#12-certificaatbundel + PKCS#12-sertifikatbunt + Pakiet certyfikatu PKCS#12 + conjunto de certificados PKCS#12 + Pacote de certificados PKCS#12 + Certificat împachetat PKCS#12 + пакет сертификатов PKCS#12 + Zväzok certifikátov PKCS#12 + Datoteka potrdila PKCS#12 + Bundle çertifikate PKCS#12 + PKCS#12 пакет сертификата + PKCS#12-certifikatsamling + комплект сертифікатів PKCS#12 + Bó chứng nhận PKCS#12 + PKCS#12 证书束 + PKCS#12 憑證檔 + PKCS + Public-Key Cryptography Standards + + + + + PlanPerfect spreadsheet + جدول PlanPerfect + Raźlikovy arkuš PlanPerfect + Таблица — PlanPerfect + full de càlcul de PlanPerfect + Sešit PlanPerfect + PlanPerfect-regneark + PlanPerfect-Tabelle + PlanPerfect spreadsheet + hoja de cálculo de PlanPerfect + PlanPerfect kalkulu-orria + PlanPerfect-taulukko + PlanPerfect rokniark + feuille de calcul PlanPerfect + scarbhileog PlanPerfect + folla de cálculo de PlanPerfect + גליון נתונים של PlanPerfect + PlanPerfect táblázat + Lembar sebar PlanPerfect + Foglio di calcolo PlanPerfect + PlanPerfect スプレッドシート + PlanPerfect электрондық кестесі + PlanPerfect 스프레드시트 + PlanPerfect skaičialentė + PlanPerfect izklājlapa + PlanPerfect-regneark + PlanPerfect-rekenblad + PlanPerfect-rekneark + Arkusz PlanPerfect + Planilha do PlanPerfect + Foaie de calcul PlanPerfect + электронная таблица PlanPerfect + Zošit PlanPerfect + Razpredelnica PlanPerfect + Fletë llogaritjesh PlanPerfect + PlanPerfect-kalkylblad + ел. таблиця PlanPerfect + Bảng tính PlanPerfect + PlanPerfect 工作簿 + PlanPerfect 試算表 + + + + + Pocket Word document + مستند Pocket Word + Документ — Pocket Word + document Pocket Word + Dokument Pocket Word + Pocket Word-dokument + Pocket-Word-Dokument + documento de Pocket Word + Pocket Word dokumentua + Pocket Word -asiakirja + Pocket Word skjal + document Pocket Word + cáipéis Pocket Word + documento de Pocket Word + מסמך של Pocket Word + Pocket Word dokumentum + Dokumen Pocket Word + Documento Pocket Word + Pocket Word ドキュメント + Pocket Word құжаты + Pocket Word 문서 + Pocket Word dokumentas + Pocket Word dokuments + Pocket Word-document + Dokument Pocket Word + Documento do Pocket Word + Document Pocket Word + документ Pocket Word + Dokument Pocket Word + Dokument Pocket Word + Pocket Word-dokument + документ Pocket Word + Tài liệu Pocket Word + Pocket Word 文档 + Pocket Word 文件 + + + + + + + + profiler results + نتائج المحلل + profiler nəticələri + vyniki profilera + Резултати от анализатора + resultats del perfilador + Výsledky profiler + canlyniadau proffeilio + profileringsresultater + Profiler-Ergebnisse + αποτελέσματα μετρήσεων για την εκτέλεση προγράμματος + profiler results + resultoj de profililo + resultados del perfilador + profiler-aren emaitzak + profilointitulokset + résultats de profileur + torthaí próifíleora + resultados do perfilador + תוצאות מאבחן + profilírozó-eredmények + hasil profiler + Risultati profiler + プロファイラー結果 + прифильдеу нәтижелері + 프로파일러 결과 + profiliklio rezultatai + profilētāja rezultāti + Hasil pemprofil + profileingsresultat + profiler-resultaten + profileringsresultat + Wyniki profilowania + resultados do 'profiler' + resultados do profiler + rezultate profiler + результаты профилирования + Výsledky profilera + rezultati profilirnika + Rezultate të profiluesit + резултати профилатора + profilerarresultat + результати профілювання + kết quả nét hiện trạng + profiler 结果 + 硬體資訊產生器成果 + + + + + + Pathetic Writer document + مستند Pathetic Writer + Dakument Pathetic Writer + Документ — Pathetic Writer + document de Pathetic Writer + Dokument Pathetic Writer + Pathetic Writer-dokument + Pathetic-Writer-Dokument + έγγραφο Pathetic Writer + Pathetic Writer document + dokumento de Pathetic Writer + documento de Pathetic Writer + Pathetic Writer dokumentua + Pathetic Writer -asiakirja + Pathetic Writer skjal + document Pathetic Writer + cáipéis Pathetic Writer + documento de Pathetic Writer + מסמך של Pathetic Writer + Pathetic Writer-dokumentum + Dokumen Pathetic Writer + Documento Pathetic Writer + Pathetic Writer ドキュメント + Pathetic Writer құжаты + Pathetic Writer 문서 + Pathetic Writer dokumentas + Pathetic Writer dokuments + Dokumen Pathetic Writer + Pathetic Writer-dokument + Pathetic Writer-document + Pathetic Writer-dokument + Dokument Pathetic Writer + documento do Pathetic Writer + Documento do Pathetic Writer + Document Pathetic Writer + документ Pathetic Writer + Dokument Pathetic Writer + Dokument Pathetic Writer + Dokument Pathetic Writer + Документ Патетичног писца + Pathetic Writer-dokument + документ Pathetic Writer + Tài liệu Pathetic Writer + Pathetic Writer 文档 + Pathetic Writer 文件 + + + + + Python bytecode + Python bytecode + Python bayt kodu + Bajtavy kod Python + Байт код — Python + bytecode de Python + Bajtový kód Python + Côd beit Python + Pythonbytekode + Python-Bytecode + συμβολοκώδικας Python + Python bytecode + Python-bajtkodo + bytecode Python + Python byte-kodea + Python-tavukoodi + Python býtkota + bytecode Python + beartchód Python + bytecode de Python + Bytecode של Python + Python-bájtkód + Kode bita Python + Bytecode Python + Python バイトコード + Python байткоды + 파이썬 바이트코드 + Python baitinis kodas + Python bitkods + Kodbait Python + Python-bytekode + Python-bytecode + Python-bytekode + Kod bajtowy Python + código binário Python + Código compilado Python + Bytecode Python + байт-код Python + Bajtový kód Python + Datoteka bitne kode Python + Bytecode Python + Питонов бајт ко̂д + Python-bytekod + байт-код Python + Mã byte Python + Python 字节码 + Python 位元碼 + + + + + + + + Quattro Pro spreadsheet + جدول Quattro Pro + Raźlikovy arkuš Quattro Pro + Таблица — Quattro Pro + full de càlcul de Quattro Pro + Sešit Quattro Pro + Quattro Pro-regneark + Quattro-Pro-Tabelle + λογιστικό φύλλο Quattro Pro + Quattro Pro spreadsheet + sterntabelo de Quattro Pro + hoja de cálculo Quattro Pro + Quattro Pro kalkulu-orria + Quattro Pro -taulukko + Quattro Pro rokniark + feuille de calcul Quattro Pro + scarbhileog Quattro Pro + folla de cálculo Quattro Pro + גליון נתונים של Quattro Pro + Quattro Pro-munkafüzet + Lembar sebar Quattro Pro + Foglio di calcolo Quattro Pro + Quattro Pro スプレッドシート + Quattro Pro электрондық кестесі + Quattro Pro 스프레드시트 + Quattro Pro skaičialentė + Quattro Pro izklājlapa + Hamparan Quatro Pro + Quattro Pro-regneark + Quattro Pro-rekenblad + Quattro Pro-rekneark + Arkusz Quattro Pro + folha de cálculo Quattro Pro + Planilha do Quattro Pro + Foaie de calcul Quattro Pro + электронная таблица Quattro Pro + Zošit Quattro Pro + Razpredelnica Quattro Pro + Fletë llogaritjesh Quattro Pro + Quattro Pro табеларни рачун + Quattro Pro-kalkylblad + ел. таблиця Quattro Pro + Bảng tính Quattro Pro + Quattro Pro 工作簿 + Quattro Pro 試算表 + + + + + + + QuickTime metalink playlist + قائمة تشغيل QuickTime metalink + śpis metaspasyłak na pieśni QuickTime + Списък за изпълнение — QuickTime + llista de reproducció de metaenllaços QuickTime + Seznam skladeb metalink QuickTime + QuickTime metalink-afspilningsliste + QuickTime-Metalink-Wiedergabeliste + lista de reproducción de metaenlaces QuickTime + QuickTime meta-esteken erreprodukzio-zerrenda + QuickTime metalink -soittolista + QuickTime metaleinkju avspælingarlisti + liste de lecture metalink QuickTime + seinmliosta meiteanasc QuickTime + lista de reprodución de metaligazóns QuickTime + רשימת השמעה מקושרת של QuickTime + QuickTime metalink lejátszólista + Senarai berkas taut meta QuickTime + Scaletta metalink QuickTime + QuickTime メタリンク再生リスト + QuickTime метасілтемелер ойнау тізімі + 퀵타임 metalink 재생 목록 + QuickTime metanuorodos grojaraštis + QuickTime metasaites repertuārs + QuickTime metalink-spilleliste + QuickTime metalink-afspeellijst + QuickTime metalink-speleliste + Lista odtwarzania metaodnośników QuickTime + Lista de reprodução metalink do QuickTime + Listă cu metalegături QuickTime + список воспроизведения мета-ссылок QuickTime + Zoznam skladieb metalink QuickTime + Seznam predvajanja QuickTime + Listë titujsh metalink QuickTime + QuickTime-metalänkspellista + список відтворення QuickTime metalink + Danh mục nhạc siêu liên kết Quicktime + QuickTime 元链接播放列表 + QuickTime metalink 播放清單 + + + + + + + + + + + + + + + Quicken document + مستند Quicken + Quicken sənədi + Dakument Quicken + Документ — Quicken + document de Quicken + Dokument Quicken + Dogfen Quicken + Quickendokument + Quicken-Dokument + έγγραφο Quicken + Quicken document + Quicken-dokumento + documento de Quicken + Quicken dokumentua + Quicken-asiakirja + Quicken skjal + document Quicken + cáipéis Quicken + documento de Quicken + מסמך של Quicken + Quicken-dokumentum + Dokumen Quicken + Documento Quicken + Quicken ドキュメント + Quicken құжаты + Quicken 문서 + Quicken dokumentas + Quicken dokuments + Dokumen Quicken + Quicken-dokument + Quicken-document + Quicken-dokument + Dokument Quicken + documento Quicken + Documento do Quicken + Document Quicken + документ Quicken + Dokument Quicken + Dokument Quicken + Dokument Quicken + Quicken документ + Quicken-dokument + документ Quicken + Tài liệu Quicken + Quicken 文档 + Quicken 文件 + + + + + RAR archive + أرشيف RAR + Archiŭ RAR + Архив — RAR + arxiu RAR + Archiv RAR + Archif RAR + RAR-arkiv + RAR-Archiv + αρχείο RAR + RAR archive + RAR-arkivo + archivador RAR + RAR artxiboa + RAR-arkisto + RAR skjalasavn + archive RAR + cartlann RAR + ficheiro RAR + ארכיון RAR + RAR-archívum + Arsip RAR + Archivio RAR + RAR アーカイブ + RAR архиві + RAR 압축 파일 + RAR archyvas + RAR arhīvs + Arkib RAR + RAR-arkiv + RAR-archief + RAR-arkiv + Archiwum RAR + arquivo RAR + Pacote RAR + Arhivă RAR + архив RAR + Archív RAR + Datoteka arhiva RAR + Arkiv RAR + РАР архива + RAR-arkiv + архів RAR + Kho nén RAR + RAR 归档文件 + RAR 封存檔 + + + + + + + + + DAR archive + أرشيف DAR + Archiŭ DAR + Архив — DAR + arxiu DAR + Archiv DAR + DAR-arkiv + DAR-Archiv + DAR-arkivo + archivador DAR + DAR artxiboa + DAR-arkisto + DAR skjalasavn + archive DAR + cartlann DAR + arquivo DAR + ארכיון DAR + DAR archívum + Arsip DAR + Archivio DAR + DAR アーカイブ + DAR архиві + DAR 묶음 파일 + DAR archyvas + DAR arhīvs + DAR-arkiv + DAR-archief + DAR-arkiv + Archiwum DAR + Pacote DAR + Arhivă DAR + архив DAR + Archív DAR + Datoteka arhiva DAR + Arkiv DAR + DAR-arkiv + архів DAR + Kho nén DAR + DAR 归档文件 + DAR 封存檔 + + + + + + + + Alzip archive + أرشيف Alzip + Archiŭ Alzip + Архив — alzip + arxiu Alzip + Archiv Alzip + Alziparkiv + Alzip-Archiv + Alzip-arkivo + archivador Alzip + Alzip artxiboa + Alzip-arkisto + Alsip skjalasavn + archive alzip + cartlann Alzip + arquivo Alzip + ארכיון Alzip + Alzip archívum + Arsip Alzip + Archivio Alzip + Alzip アーカイブ + Alzip архиві + 알집 압축 파일 + Alzip archyvas + Alzip arhīvs + Alzip-arkiv + Alzip-archief + Alzip-arkiv + Archiwum alzip + Pacote Alzip + Arhivă Alzip + архив ALZIP + Archív Alzip + Datoteka arhiva Alzip + Arkiv Alzip + Alzip-arkiv + архів Alzip + Kho nén Alzip + Alzip 归档文件 + Alzip 封存檔 + + + + + + + + rejected patch + رقعة مرفوضة + niepryniaty patch + Отхвърлен файл с кръпка + pedaç rebutjat + Odmítnutá záplata + afvist tekstlap + Abgelehnter Patch + μπάλωμα που απορρίφθηκε + rejected patch + reĵeta flikaĵo + parche rechazado + baztertutako bide-izena + hylättyjen muutosten tiedosto + vrakað rætting + correctif rejeté + paiste diúltaithe + parche rexeitado + תלאי שנדחה + visszautasított folt + patch ditolak + Patch rifiutata + 拒否されたパッチ + алынбаған патч + 거부된 패치 파일 + atmestas lopas + noraidītais ceļš + Tampungan ditolak + avvist patchfil + verworpen patch + avvist programfiks + Odrzucona łata + ficheiro de patch rejeitado + arquivo de patch rejeitado + petec respsins + отвергнутый патч + Odmietnutá záplata + zavrnjen popravek + Patch i kthyer mbrapsht + одбијена закрпа + avvisad programfix + відхилена латка + đắp vá bị từ chối + 拒绝的补丁 + 回絕的修補 + + + + + + + RPM package + حزمة RPM + Pakunak RPM + Пакет — RPM + paquet RPM + Balíček RPM + RPM-pakke + RPM-Paket + πακέτο RPM + RPM package + RPM-pakaĵo + paquete RPM + RPM paketea + RPM-paketti + RPM pakki + paquet RPM + pacáiste RPM + paquete RFM + חבילת RPM + RPM-csomag + Paket RPM + Pacchetto RPM + RPM パッケージ + RPM дестесі + RPM 패키지 + RPM paketas + RPM pakotne + Pakej RPM + RPM-pakke + RPM-pakket + RPM-pakke + Pakiet RPM + pacote RPM + Pacote RPM + Pachet RPM + пакет RPM + Balík RPM + Datoteka paketa RPM + Paketë RPM + RPM пакет + RPM-paket + пакунок RPM + Gói RPM + RPM 软件包 + RPM 套件 + + + + + + + + + Ruby script + سكربت روبي + Skrypt Ruby + Скрипт — Ruby + script Ruby + Skript v Ruby + Rubyprogram + Ruby-Skript + πρόγραμμα εντολών Ruby + Ruby script + Ruby-skripto + script en Ruby + Ruby script-a + Ruby-komentotiedosto + Ruby boðrøð + script Ruby + script Ruby + Script de Ruby + תסריט Ruby + Ruby-parancsfájl + Skrip Ruby + Script Ruby + Ruby スクリプト + Ruby сценарийі + 루비 스크립트 + Ruby scenarijus + Ruby skripts + Skrip Ruby + Ruby-skript + Ruby-script + Ruby-skript + Skrypt Ruby + 'script' Ruby + Script Ruby + Script Ruby + сценарий Ruby + Skript Ruby + Skriptna datoteka Ruby + Script Ruby + Руби скрипта + Ruby-skript + скрипт Ruby + Văn lệnh Ruby + Ruby 脚本 + Ruby 指令稿 + + + + + + + + + + + Markaby script + سكربت Markaby + Skrypt Markaby + Скрипт — Markaby + script Markaby + Skript Markaby + Markabyprogram + Markaby-Skript + Markaby-skripto + script en Markaby + Markaby script-a + Markaby-komentotiedosto + Markaby boðrøð + script Markaby + script Markaby + Script de Markaby + תסריט Markby + Markaby parancsfájl + Skrip Markaby + Script Markaby + Markaby スクリプト + Markaby сценарийі + Markaby 스크립트 + Markaby scenarijus + Markaby skripts + Markaby-skript + Markaby-script + Markaby-skript + Skrypt Markaby + Script Markaby + Script Markaby + сценарий Markaby + Skript Markaby + Skriptna datoteka Markaby + Script Markaby + Markaby-skript + скрипт Markaby + Văn lệnh Markaby + RMarkaby 脚本 + Markaby 指令稿 + + + + + + SC/Xspread spreadsheet + جدول SC/Xspread + Raźlikovy arkuš SC/Xspread + Таблица — SC/Xspread + full de càlcul de SC/Xspread + Sešit SC/Xspread + SC/Xspread-regneark + SX/Xspread-Tabelle + SC/Xspread spreadsheet + SC/Xspread-kalkultabelo + hoja de cálculo SC/Xspread + SC/Xspread kalkulu-orria + SC/Xspread-taulukko + SC/Xspread rokniark + feuille de calcul SC/Xspread + scarbhileog SC/Xspread + folla de cálculo SC/Xspread + גליון נתונית של SC/Xspread + SC/Xspread táblázat + Lembar sebar SC/Xspread + Foglio di calcolo SC/Xspread + SC/Xspread スプレッドシート + SC/Xspread электрондық кестесі + SC/Xspread 스프레드시트 + SC/Xspread skaičialentė + SC/Xspread izklājlapa + SC/Xspread-regneark + SC/Xspread-rekenblad + SC/Xspread-rekneark + Arkusz SC/Xspread + Planilha do SC/Xspread + Foaie de calcul SC/Xspread + электронная таблица SC/Xspread + Zošit SC/Xspread + Razpredelnica SC/Xspread + Fletë llogaritjesh SC/Xspread + SC/Xspread-kalkylblad + ел. таблиця SC/Xspread + Bảng tính SC/Xspread + SC/Xspread 工作簿 + SC/Xspread 試算表 + + + + + + + shell archive + أرشيف شِل + qabıq arxivi + archiŭ abałonki + Архив на обвивката + arxiu d'intèrpret d'ordres + Archiv shellu + archif plisgyn + skalarkiv + Shell-Archiv + αρχείο φλοιού (SHAR) + shell archive + ŝel-arkivo + archivador shell + shell artxiboa + komentotulkkiarkisto + skel savn + archive shell + cartlann bhlaoisce + ficheiro shell + ארכיון מעטפת + héjarchívum + arsip shell + Archivio shell + シェルアーカイブ + қоршам архиві + 쉘 묶음 파일 + shell archyvas + čaulas arhīvs + Arkib shell + skallarkiv + shell-archief + skal-arkiv + Archiwum powłoki + arquivo de consola + Pacote shell + arhivă shell + архив оболочки UNIX + Archív shellu + lupinski arhiv + Arkiv shell + Архива љуске (SHAR) + skalarkiv + архів оболонки + kho trình bao + shell 归档文件 + shell 封存檔 + + + + + libtool shared library + مكتبة libtool المشتركة + supolnaja biblijateka libtool + Споделена библиотека — libtool + biblioteca compartida libtool + Sdílená knihovna libtool + libtool delt bibliotek + Gemeinsame libtool-Bibliothek + biblioteca compartida de libtool + libtool partekatutako liburutegia + jaettu libtool-kirjasto + libtool felagssavn + bibliothèque partagée libtool + comhleabharlann libtool + biblioteca compartida de libtool + ספריה משותפת של libtool + libtool osztott programkönyvtár + pustaka bersama libtool + Libreria condivisa libtool + libtool 共有ライブラリ + libtool ортақ жинағы + libtool 공유 라이브러리 + libtool bendroji biblioteka + libtool koplietotā bibliotēka + libtool delt bibliotek + gedeelde libtool-bibliotheek + libtool delt bibliotek + Biblioteka współdzielona libtool + biblioteca compartilhada libtool + bibliotecă partajată libtool + разделяемая библиотека libtool + Zdieľaná knižnica libtool + Souporabna knjižnica libtool + Librari e përbashkët libtool + delat libtool-bibliotek + спільна бібліотека libtool + thư viện dùng chung libtool + libtool 共享库 + libtool 共享函式庫 + + + + + + shared library + مكتبة مشتركة + bölüşülmüş kitabxana + supolnaja biblijateka + Споделена библиотека + biblioteca compartida + Sdílená knihovna + llyfrgell wedi ei rhannu + delt bibliotek + Gemeinsame Bibliothek + αρχείο κοινόχρηστης βιβλιοθήκης + shared library + dinamike bindebla biblioteko + biblioteca compartida + partekatutako liburutegia + jaettu kirjasto + felagssavn + bibliothèque partagée + comhleabharlann + biblioteca compartida + ספרייה משותפת + osztott programkönyvtár + pustaka bersama + Libreria condivisa + 共有ライブラリ + бөлісетін библиотека + 공유 라이브러리 + bendroji biblioteka + koplietotā bibliotēka + Pustaka terkongsi + delt bibliotek + gedeelde bibliotheek + delt bibliotek + Biblioteka współdzielona + biblioteca partilhada + biblioteca compartilhada + bibliotecă partajată + разделяемая библиотека + Zdieľaná knižnica + souporabljena knjižnica + Librari e përbashkët + дељена библиотека + delat bibliotek + спільна бібліотека + thư viện dùng chung + 共享库 + 共享函式庫 + + + + + + + + + + + + + + + + + + + + shell script + سكربت شِل + qabıq skripti + skrypt abałonki + Скрипт на обвивката + script d'intèrpret d'ordres + Skript shellu + sgript plisgyn + skalprogram + Shell-Skript + αρχείο εντολών φλοιού + shell script + ŝelskripto + script en shell + shell script-a + komentotulkin komentotiedosto + skel boðrøð + script shell + script bhlaoisce + script de shell + תסריט מעטפת + héj-parancsfájl + skrip shell + Script shell + シェルスクリプト + қоршам сценарийі + 쉘 스크립트 + shell scenarijus + čaulas skripts + Skrip shell + skallskript + shellscript + skalskript + Skrypt powłoki + 'script' de consola + script shell + script shell + сценарий оболочки UNIX + Skript shellu + lupinski skript + Script shell + скрипта љуске + skalskript + скрипт оболонки + văn lệnh trình bao + shell 脚本 + shell 指令稿 + + + + + + + + + + + + + + + + + + + + + Shockwave Flash file + ملف Shockwave Flash + Fajł Shockwave Flash + Файл — Shockwave Flash + fitxer Shockwave Flash + Soubor Shockwave Flash + Shockwave Flash-fil + Shockwave-Flash-Datei + αρχείο Shockwave Flash + Shockwave Flash file + dosiero de Shockwave Flash + archivo Shockwave Flash + Shockwave Flash fitxategia + Shockwave Flash -tiedosto + Shockwave Flash fíla + fichier Shockwave Flash + comhad Shockwave Flash + ficheiro sockwave Flash + קובץ של Shockwave Flash + Shockwave Flash-fájl + Berkas Shockwave Flash + File Shockwave Flash + Shockwave Flash ファイル + Shockwave Flash файлы + Shockwave 플래시 파일 + Shockwave Flash failas + Shockwave Flash fails + Fail Shockwave Flash + Shockwave Flash-fil + Shockwave Flash-bestand + Shockwave Flash-fil + Plik Shockwave Flash + ficheiro Shockwave Flash + Arquivo Shockwave Flash + Fișier Shockwave Flash + файл Shockwave Flash + Súbor Shockwave Flash + Datoteka Shockwave Flash + File Flash Shockwave + Шоквејв Флеш датотека + Shockwave Flash-fil + файл Shockwave Flash + Tập tin Flash Shockwave + Shockwave Flash 文件 + Shockwave Flash 檔 + + + + + + + + + + + + Shorten audio + Shorten سمعي + Aŭdyjo Shorten + Аудио — Shorten + àudio Shorten + Zvuk Shorten + Shortenlyd + Shorten-Audio + Shorten audio + Shorten-sondosiero + sonido Shorten + Shorten audioa + Shorten-ääni + Shorten ljóður + audio Shorten + fuaim Shorten + son Shorten + שמע של Shorten + Shorten hang + Audio Shorten + Audio Shorten + Shorten オーディオ + Shorten аудиосы + Shorten 오디오 + Shorten garso įrašas + Shorten audio + Shorten lyd + Shorten-audio + Shorten-lyd + Plik dźwiękowy Shorten + Áudio Shorten + Audio Shorten + аудио Shorten + Zvuk Shorten + Zvočna datoteka Shorten + Audio Shorten + Shorten-ljud + звук Shorten + Âm thanh Shorten + Shorten 音频 + Shorten 音訊 + + + + + + + + Siag spreadsheet + جدول Siag + Raźlikovy arkuš Siag + Таблица — Siag + full de càlcul Siag + Sešit Siag + Siagregneark + Siag-Tabelle + λογιστικό φύλλο Siag + Siag spreadsheet + Siag-kalkultabelo + hoja de cálculo de Siag + Siag kalkulu-orria + Siag-taulukko + Siag rokniark + feuille de calcul Siag + scarbhileog Siag + folla de cálculo de Siag + גליון נתונים של Siag + Siag-munkafüzet + Lembar sebar Siag + Foglio di calcolo Siag + Siag スプレッドシート + Siag электрондық кестесі + Siag 스프레드시트 + Siag skaičialentė + Siag izklājlapa + Hamparan Siag + Siag-regneark + Siag-rekenblad + Siag-rekneark + Arkusz Siag + folha de cálculo Siag + Planilha do Siag + Foaie de calcul Siag + электронная таблица Siag + Zošit Siag + Razpredelnica Siag + Fletë llogaritjesh Siag + Siag табеларни прорачун + Siag-kalkylblad + ел. таблиця Siag + Bảng tính Slag + Siag 工作簿 + Siag 試算表 + + + + + Skencil document + مستند Skencil + Dakument Skencil + Документ — Skencil + document Skencil + Dokument Skencil + Skencildokument + Skencil-Dokument + Skencil-dokumento + documento Skencil + Skencil dokumentua + Skencil-asiakirja + Skencil skjal + document Skencil + cáipéis Skencil + documento Skencil + מסמך Skencil + Skencil-dokumentum + Dokumen Skencil + Documento Skencil + Skencil ドキュメント + Skencil құжаты + Skencil 문서 + Skencil dokumentas + Skencil dokuments + Skencil-document + Skencil-dokument + Dokument Skencil + Documento do Skencil + Document Skencil + документ Skencil + Dokument Skencil + Dokument Skencil + Dokument Skencil + Skencil-dokument + документ Skencil + Tài liệu Skencil + Skencil 文档 + Skencil 文件 + + + + + + + + Stampede package + حزمة Stampede + Stampede paketi + Pakunak Stampede + Пакет — Stampede + paquet Stampede + Balíček Stampede + Pecyn Stampede + Stampedepakke + Stampede-Paket + πακέτο Stampede + Stampede package + Stampede-pakaĵo + paquete Stampede + Stampede paketea + Stampede-paketti + Stampede pakki + paquet Stampede + pacáiste Stampede + paquete Stampede + חבילה של Stampede + Stampede-csomag + Paket Stampede + Pacchetto Stampede + Stampede パッケージ + Stampede дестесі + 스탬피드 패키지 + Stampede paketas + Stampede pakotne + Pakej Stampede + Stampede-pakke + Stampede-pakket + Stampede-pakke + Pakiet Stampede + pacote Stampede + Pacote Stampede + Pachet Stampede + пакет Stampede + Balíček Stampede + Datoteka paketa Stampede + Paketë Stampede + Stampede пакет + Stampede-paket + пакунок Stampede + Gói Stampede + Stampede 软件包 + Stampede 套件 + + + + Sega Master System/Game Gear ROM + ROM الخاص بدولاب لعبة/نظام سيجا ماستر + Sega Master System/Game Gear ROM + ROM — Sega Master System/Game Gear + ROM de Sega Master System/Game Gear + ROM pro Sega Master System/Game Gear + Sega Master System/Game Gear-rom + Sega-Master-System/Game-Gear-ROM + ROM de Sega Master System/Game Gear + Sega Master System/Game Gear-eko ROMa + Sega Master System/Game Gear -ROM + Sega Master System/Game Gear ROM + ROM Sega Master System/Game Gear + ROM Sega Master System/Game Gear + ROM de Sega Master System/Game Gear + Sega Master System/Game Gear של ROM + Sega Master System/Game Gear ROM + Memori baca-saja Sega Master System/Game Gear + ROM Sega Master System/Game Gear + セガ マスターシステム/ゲームギア ROM + Sega Master System/Game Gear ROM + Sega Master System/Game Gear 롬 + Sega Master System/Game Gear ROM + Sega Master System/Game Gear ROM + Sega Master System/Game Gear-ROM + Sega Master System/Game Gear-ROM + Sega Master System/Game Gear-ROM + Plik ROM konsoli SMS/Game Gear + ROM do Master System/Game Gear + ROM Sega Master System/Game Gear + Sega Master System/Game Gear ROM + ROM pre Sega Master System/Game Gear + Bralni pomnilnik Sega Master System/Game Gear + ROM Sega Master System/Game Gear + Sega Master System/Game Gear-rom + ППП Sega Master System/Game Gear + ROM Sega Master System/Game Gear + Sega Master System/Game Gear ROM + Sega Master System/Game Gear ROM + + + + + + + Super NES ROM + Super NES ROM + Super Nintendo ROM + ROM — Super NES + ROM de Super NES + ROM pro Super Nintendo + Super NES-rom + Super-NES-ROM + ROM de Super NES + Super Nintendo-ko ROMa + Super Nintendo -ROM + Super NES ROM + ROM Super Nintendo + ROM Super NES + ROM de Super NES + ROM של Super NES + Super NES ROM + Memori baca-saja Super Nintendo + ROM Super Nintendo + スーパーファミコン ROM + Super NES ROM + 슈퍼 NES 롬 + Super NES ROM + Super NES ROM + Super Nintendo ROM + Super Nintendo + Super NES-ROM + Plik ROM konsoli SNES + ROM do Super Nintendo + ROM Super Nintendo + Super NES ROM + ROM pre Super Nintendo + Bralni pomnilnik Super NES + ROM Super NES + Super NES-rom + ППП Super NES + ROM Super Nintendo + Super NES ROM + 超級任天堂 ROM + + + + + StuffIt archive + أرشيف StuffIt + Archiŭ StuffIt + Архив — StuffIt + arxiu StuffIt + Archiv StuffIt + StuffIt-arkiv + StuffIt-Archiv + StuffIt archive + StuffIt-arkivo + archivador StuffIt + StuffIt artxiboa + StuffIt-arkisto + StuffIt skjalasavn + archive StuffIt + cartlann StuffIt + arquivo StuffIt + ארכיון של Sאוככןא + StuffIt-archívum + Arsip StuffIt + Archivio StuffIt + StuffIt アーカイブ + StuffIt архиві + StuffIt 압축 파일 + StuffIt archyvas + StuffIt arhīvs + StuffIt arkiv + StuffIt-archief + StuffIt-arkiv + Archiwum StuffIt + Pacote StuffIt + Arhivă StuffIt + архив StuffIt + Archív StuffIt + Datoteka arhiva StuffIt + Arkiv StuffIt + StuffIt архива + StuffIt-arkiv + архів StuffIt + Kho nén Stuffit + Macintosh StuffIt 归档文件 + StuffIt 封存檔 + + + + + + + + + + + SubRip subtitles + ترجمات SubRip + Subtytry SubRip + Субтитри — SubRip + subtítols SubRip + Titulky SubRip + SubRip-undertekster + SubRip-Untertitel + SubRip-subtekstoj + subtítulos SubRip + SubRip azpitituluak + SubRip-tekstitykset + SubRip undirtekstir + sous-titres SubRip + fotheidil SubRip + subtítulos SubRip + כתוביות של SubRip + SubRip feliratok + Subjudul SubRip + Sottotitoli SubRip + SubRip 字幕 + SubRip субтитрлары + SubRip 자막 파일 + SubRip subtitrai + SubRip subtitri + SubRip undertekst + SubRip-ondertitels + SubRip-teksting + Napisy SubRip + Legendas SubRip + Subtitrare SubRip + субтитры SubRip + Titulky SubRip + Datoteka podnapisov SubRip + Nëntituj SubRip + SubRip-undertexter + субтитри SubRip + Phụ đề SubRip + SubRip 字幕 + SubRip 字幕 + + + + + + + + + + + + WebVTT subtitles + Субтитри — WebVTT + subtítols WebVTT + Titulky WebVTT + Subtítulos WebVTT + WebVTT-tekstitykset + sous-titres WebVTT + subtítulos WebVTT + כתוביות WebVTT + Subtitel WebVTT + Sottotitoli WebVTT + WebVTT サブタイトル + WebVTT субтитрлары + WebVTT subtitri + Napisy WebVTT + субтитры WebVTT + Podnapisi WebVVT + WebVTT-undertexter + субтитри WebVTT + VTT + Video Text Tracks + + + + + + + + + SAMI subtitles + ترجمات SAMI + Subtytry SAMI + Субтитри — SAMI + subtítols SAMI + Titulky SAMI + SAMI-undertekster + SAMI-Untertitel + SAMI-subtekstoj + subtítulos SAMI + SAMI azpitituluak + SAMI-tekstitykset + SAMI undirtekstir + sous-titres SAMI + fotheidil SAMI + subtítulos SAMI + כתוביות SAMI + SAMI feliratok + Subjudul SAMI + Sottotitoli SAMI + SAMI 字幕 + SAMI субтитрлары + SAMI 자막 파일 + SAMI subtitrai + SAMI subtitri + SAMI undertekst + SAMI-ondertitels + SAMI teksting + Napisy SAMI + SAMI subtitles + Subtitrări SAMI + субтитры SAMI + Titulky SAMI + Datoteka podnapisov SAMI + Nëntituj SAMI + SAMI-undertexter + субтитри SAMI + Phụ đề SAMI + SAMI 字幕 + SAMI 字幕 + SAMI + Synchronized Accessible Media Interchange + + + + + + + + + + MicroDVD subtitles + ترجمات MicroDVD + Subtytry MicroDVD + Субтитри — MicroDVD + subtítols MicroDVD + Titulky MicroDVD + MicroDVD-undertekster + MicroDVD-Untertitel + MicroDVD-subtekstoj + subtítulos MicroDVD + MicroDVD azpitituluak + MicroDVD-tekstitykset + MicroDVD undirtekstir + sous-titres MicroDVD + fotheidil MicroDVD + subtítulos de MicroDVD + כתוביות של MicroDVD + MicroDVD feliratok + Subjudul MicroDVD + Sottotitoli MicroDVD + MicroDVD 字幕 + MicroDVD субтитрлары + MicroDVD 자막 파일 + MicroDVD subtitrai + MicroDVD subtitri + MicroDVD undertekst + MicroDVD-ondertitels + MicroDVD-teksting + Napisy MicroDVD + Legendas MicroDVD + Subtitrări MicroDVD + субтитры MicroDVD + Titulky MicroDVD + Datoteka podnapisov MicroDVD + Nëntituj MicroDVD + MicroDVD-undertexter + субтитри MicroDVD + Phụ đề MicroDVD + MicroDVD 字幕 + MicroDVD 字幕 + + + + + + + + + + MPSub subtitles + ترجمات MPSub + Subtytry MPSub + Субтитри — MPSub + subtítols MPSub + Titulky MPSub + MPSub-undertekster + MPSub-Untertitel + MPSub-subtekstoj + subtítulos MPSub + MPSub azpitituluak + MPSub-tekstitykset + MPSub undirtekstir + sous-titres MPSub + fotheidil MPSub + subtítulos MPSub + כתוביות MPSub + MPSub feliratok + Subjudul MPSub + Sottotitoli MPSub + MPSub サブタイトル + MPSub субтитрлары + MPSub 자막 파일 + MPSub subtitrai + MPSub subtitri + MPSub undertekst + MPSub-ondertitels + MPSub-undertekstar + Napisy MPSub + Legendas MPSub + Subtitrări MPSub + субтитры MPSub + Titulky MPSub + Datoteka podnapisov MPSub + Nëntituj MPSub + MPSub-undertexter + субтитри MPSub + Phụ đề MPSub + MPSub 字幕 + MPSub 字幕 + MPSub + MPlayer Subtitle + + + + + + + + SSA subtitles + ترجمات SSA + Subtytry SSA + Субтитри — SSA + subtítols SSA + Titulky SSA + SSA-undertekster + SSA-Untertitel + SSA-subtekstoj + subtítulos SSA + SSA azpitituluak + SSA-tekstitykset + SSA undirtekstir + sous-titres SSA + fotheidil SSA + Subtitulos SSA + כתובית SSA + SSA feliratok + Subjudul SSA + Sottotitoli SSA + SSA 字幕 + SSA субтитрлары + SSA 자막 파일 + SSA subtitrai + SSA subtitri + SSA undertekst + SSA-ondertitels + SSA-teksting + Napisy SSA + Legenda SSA + Subtitrări SSA + субтитры SSA + Titulky SSA + Datoteka podnapisov SSA + Nëntituj SSA + SSA-undertexter + субтитри SSA + Phụ đề SSA + SSA 字幕 + SSA 字幕 + SSA + SubStation Alpha + + + + + + + + + + SubViewer subtitles + ترجمات SubViewer + Subtytry SubViewer + Субтитри — SubViewer + subtítols SubViewer + Titulky SubViewer + SubViewer-undertekster + SubViewer-Untertitel + SubViewer-subtekstoj + subtítulos SubViewer + SubViewer azpitituluak + SubViewer-tekstitykset + SubViewer undirtekstir + sous-titres SubViewer + fotheidil SubViewer + subtítulos SubViewer + כתוביות של SubViewe + SubViewer feliratok + Subjudul SubViewer + Sottotitoli SubViewer + SubViewer 字幕 + SubViewer субтитрлары + SubViewer 자막 파일 + SubViewer subtitrai + SubViewer subtitri + SubViewer undertekst + SubViewer-ondertitels + SubViewer-teksting + Napisy SubViewer + Legendas SubViewer + Subtitrare SubViewer + субтитры SubViewer + Titulky SubViewer + Datoteka podnapisov SubViewer + Nëntituj SubViewer + SubViewer-undertexter + субтитри SubViewer + Phụ đề SubViewer + SubViewer 字幕 + SubViewer 字幕 + + + + + + + + iMelody ringtone + نغمة iMelody + Rington iMelody + Аудио — iMelody + to de trucada iMelody + Vyzváněcí melodie iMelody + iMelody-ringetone + iMelody-Klingelton + tono de llamada iMelody + iMelody doinua + iMelody-soittoääni + iMelody ringitóni + sonnerie iMelody + ton buailte iMelody + Melodía de iMelody + רינגטון של iMelody + iMelody csengőhang + nada dering iMelody + Suoneria iMelody + iMelody リングトーン + iMelody әуені + iMelody 벨소리 + iMelody skambučio melodija + iMelody melodija + iMelody ringetone + iMelody-beltoon + iMelody-ringetone + Dzwonek iMelody + Toque de celular do iMelody + Sonerie iMelody + мелодия iMelody + Vyzváňacie melódie iMelody + Zvonjenje iMelody + Zile iMelody + iMelody-ringsignal + рінгтон iMelody + tiếng réo iMelody + iMelody 铃声 + iMelody 鈴聲 + + + + + + + + + + SMAF audio + SMAF سمعي + Aŭdyjo SMAF + Аудио — SMAF + àudio SMAF + Zvuk SMAF + SMAF-lyd + SMAF-Audio + SMAF-sondosiero + sonido SMAF + SMAF audioa + SMAF-ääni + SMAF ljóður + audio SMAF + fuaim SMAF + son SMAF + שמע SMAF + SMAF hang + Audio SMAF + Audio SMAF + SMAF オーディオ + SMAF аудиосы + SMAF 오디오 + SMAF garso įrašas + SMAF audio + SMAF-lyd + SMAF-audio + SMAF-lyd + Plik dźwiękowy SMAF + Áudio SMAF + Audio SMAF + аудио SMAF + Zvuk SMAF + Zvočna datoteka SMAF + Audio SMAF + SMAF-ljud + звук SMAF + Âm thanh SMAF + SMAF 音频 + SMAF 音訊 + SMAF + Synthetic music Mobile Application Format + + + + + + + + + + MRML playlist + قائمة تشغيل MRML + Śpis piesień MRML + Списък за изпълнение — MRML + llista de reproducció MRML + Seznam skladeb MRML + MRML-afspilningsliste + MRML-Wiedergabeliste + MRML-ludlisto + lista de reproducción MRML + MRML erreprodukzio-zerrenda + MRML-soittolista + MRML avspælingarlisti + liste de lecture MRML + seinmliosta MRML + lista de reprodución MRML + רשימת השמעה MRML + MRML-lejátszólista + Senarai putar MRML + Scaletta MRML + MPML 再生リスト + MRML ойнау тізімі + MRML 재생 목록 + MRML grojaraštis + MRML repertuārs + MRML-spilleliste + MRML-afspeellijst + MRML-speleliste + Lista odtwarzania MRML + Lista de reprodução do MRML + Listă redare MRML + список воспроизведения MRML + Zoznam skladieb MRML + Seznam predvajanja MRML + Listë titujsh MRML + MRML-spellista + список відтворення MRML + Danh mục nhạc MRML + MRML 播放列表 + MRML 播放清單 + MRML + Multimedia Retrieval Markup Language + + + + + + + + XMF audio + XMF سمعي + Aŭdyjo XMF + Аудио — XMF + àudio XMF + Zvuk XMF + XMF-lyd + XMF-Audio + XMF-sondosiero + sonido XMF + XMF audioa + XMF-ääni + XMF ljóður + audio XMF + fuaim XMF + son XMF + שמע XMF + XMF hang + Audio XMF + Audio XMF + XMF オーディオ + XMF аудиосы + XMF 오디오 + XMF garso įrašas + XMF audio + XMF-lyd + XMF-audio + XMF-lyd + Plik dźwiękowy XMF + Áudio XMF + Audio XMF + аудио XMF + Zvuk XMF + Zvočna datoteka XMF + Audio XMF + XMF-ljud + звук XMF + Âm thanh XMF + XMF 音频 + XMF 音訊 + XMF + eXtensible Music Format + + + + + + + + + + SV4 CPIO archive + أرشيف SV4 CPIO + SV4 CPIO arxivi + Archiŭ SV4 CPIO + Архив — SV4 CPIO + arxiu CPIO SV4 + Archiv SV4 CPIO + Archif CPIO SV4 + SV4 CPIO-arkiv + SV4-CPIO-Archiv + αρχείο SV4 CPIO + SV4 CPIO archive + SV4-CPIO-arkivo + archivador SV4 CPIO + SV4 CPIO artxiboa + SV4 CPIO -arkisto + SV4 CPIO skjalasavn + archive SV4 CPIO + cartlann SV4 CPIO + arquivo SV4 CPIO + ארכיון של SV4 SPIO + SV4 CPIO-archívum + Arsip SV4 CPIO + Archivio SV4 CPIO + SV4 CPIO アーカイブ + SV4 CPIO архиві + SV4 CPIO 묶음 파일 + SV4 CPIO archyvas + SV4 CPIO arhīvs + Arkib CPIO SV4 + SV4 CPIO-arkiv + SV4 CPIO-archief + SV4 CPIO-arkiv + Archiwum SV4 CPIO + ficheiro SV4 CPIO + Pacote SV4 CPIO + Arhivă SV4 CPIO + архив SV4 CPIO + Archív SV4 CPIO + Datoteka arhiva SV4 CPIO + Arkiv SV4 CPIO + SV4 CPIO архива + SV4 CPIO-arkiv + архів SV4 CPIO + Kho nén CPIO SV4 + SV4 CPIO 归档文件 + SV4 CPIO 封存檔 + + + + + SV4 CPIO archive (with CRC) + أرشيف SV4 CPIO (مع CRC) + Archiŭ SV4 CPIO (z CRC) + Архив — SV4 CPIO, проверка за грешки CRC + arxiu CPIO SV4 (amb CRC) + Archiv SV4 CPIO (s CRC) + SV4 CPIO-arkiv (med CRC) + SV4-CPIO-Archiv (mit CRC) + αρχείο SV4 CPIO (με CRC) + SV4-CPIO-arkivo (kun CRC) + archivador SV4 CPIO (con CRC) + SV4 CPIO artxiboa (CRC-rekin) + SV4 CPIO -arkisto (CRC:llä) + SV4 CPIO skjalasavn (við CRC) + archive SV4 CPIO (avec CRC) + cartlann SV4 CPIO (le CRC) + Arquivador SV4 CPIO (con CRC) + ארכיון של SV4 SPIO (עם CRC) + SV4 CPIO-archívum (CRC-vel) + Arsip SV4 CPIO (dengan CRC) + Archivio SV4 CPIO (con CRC) + SV4 CPIO アーカイブ (CRC 有り) + SV4 CPIO архиві (CRC бар) + SV4 CPIO 묶음 파일 (CRC 포함) + SV4 CPII archyvas (su CRC) + SV4 CPIO arhīvs (ar CRC) + Arkib CPIO SV4 (dengan CRC) + SV4 CPIO-arkiv (med CRC) + SV4 CPIO-archief (met CRC) + SV4 CPIO arkiv (med CRC) + Archiwum SV4 CPIO (z sumą kontrolną) + Pacote SV4 CPIO (com CRC) + Arhivă SV4 CPIO (cu CRC) + архив SV4 CPIP (с CRC) + Archív SV4 CPIO (s CRC) + Datoteka arhiva SV4 CPIO (z razpršilom CRC) + Arkiv SV4 CPIO (me CRC) + SV4 CPIO-arkiv (med CRC) + архів SV4 CPIO (з CRC) + Kho nén CPIO SV4 (với CRC) + SV4 CPIP 归档文件(带有 CRC) + SV4 CPIO 封存檔 (具有 CRC) + + + + + Tar archive + أرشيف Tar + Tar arxivi + Archiŭ tar + Архив — tar + arxiu tar + Archiv tar + Archif tar + Tar-arkiv + Tar-Archiv + archivador Tar + Tar artxiboa + Tar-arkisto + Tar skjalasavn + archive tar + cartlann Tar + arquivo Tar + ארכיון Tar + Tar archívum + Arsip Tar + Archivio tar + Tar アーカイブ + Tar архиві + TAR 묶음 파일 + Tar archyvas + Tar arhīvs + Arkib Tar + Tar-arkiv + Tar-archief + Tar-arkiv + Archiwum tar + Pacote tar + Arhivă Tar + архив TAR + Archív tar + Datoteka arhiva Tar + Arkiv tar + Тар архива + Tar-arkiv + архів tar + Kho nén tar + Tar 归档文件 + Tar 封存檔 + + + + + + + + + + + + Tar archive (compressed) + أرشيف Tar (مضغوط) + Archiŭ tar (skampresavany) + Архив — tar, компресиран + arxiu tar (comprimit) + Archiv tar (komprimovaný) + Tar-arkiv (komprimeret) + Tar-Archiv (komprimiert) + archivador Tar (comprimido) + Tar artxiboa (konprimitua) + Tar-arkisto (pakattu) + Tar skjalasavn (stappað) + archive tar (compressée) + cartlann Tar (comhbhrúite) + arquivo Tar (comprimido) + ארכיון Tar (מכווץ) + Tar archívum (tömörített) + Arsip Tar (terkompresi) + Archivio tar (compresso) + Tar アーカイブ (compress 圧縮) + Tar архиві (сығылған) + TAR 묶음 파일 (압축) + Tar archyvas (suglaudintas) + Tar arhīvs (saspiests) + Tar-arkiv (komprimert) + Tar-archief (ingepakt) + Tar-arkiv (pakka) + Archiwum tar (skompresowane) + Pacote tar (compactado) + Arhivă Tar (comprimată) + архив TAR (сжатый) + Archív tar (komprimovaný) + Datoteka arhiva Tar (stisnjen) + Arkiv tar (i kompresuar) + Tar-arkiv (komprimerat) + архів tar (стиснений) + Kho nén tar (đã nén) + Tar 归档文件(压缩) + Tar 封存檔 (UNIX 格式壓縮) + + + + + generic font file + ملف الخط العام + zvyčajny fajł šryftu + Шрифт + fitxer genèric de tipus de lletra + Obecný soubor písma + general skrifttypefil + Allgemeine Schriftdatei + γενικό αρχείο γραμματοσειράς + generic font file + genera tipara dosiero + tipografía genérico + letra-tipo orokorra + yleinen kirjasintiedosto + felagsstavasniðsfíla + fichier de polices générique + comhad cló ginearálta + ficheiro de tipo de fonte xenérica + קובץ גופן גנרי + általános betűkészletfájl + berkas fonta generik + File tipo carattere generico + 一般フォントファイル + қаріп файлы + 일반 글꼴 파일 + bendras šrifto failas + vispārējs fonta fails + Fail font generik + vanlig skriftfil + algemeen lettertypebestand + vanleg skrifttypefil + Zwykły plik czcionki + ficheiro genérico de tipo de letra + arquivo de fonte genérico + fișier de font generic + файл шрифта + Obyčajný súbor písma + izvorna datoteka pisave + File lloj gërme i përgjithshëm + општа датотека фонта + allmän typsnittsfil + загальний файл шрифту + tập tin phông giống loài + 通用字体文件 + 通用字型檔 + + + + + packed font file + ملف الخط المرزم + zapakavany fajł šryftu + Шрифт — компресиран + fitxer empaquetat de tipus de lletra + Komprimovaný soubor písma + pakket skrifttypefil + Gepackte Schriftdatei + αρχείο συμπιεσμένης γραμματοσειράς + packed font file + pakigita tipara dosiero + archivo de tipografía empaquetada + Letra-tipo fitxategi paketatua + pakattu kirjasintiedosto + pakkað stavasniðsfíla + fichier de polices empaquetées + comhad cló pacáilte + ficheiro de fonte empaquetada + קובץ גופן ארוז + packed font-fájl + berkas fonta terkemas + File tipo carattere condensato + パックされたフォントファイル + қаріп файлы (дестеленген) + 글꼴 묶음 파일 + supakuotas šrifto failas + sapakots fonta fails + Fail font dipek + pakket skriftfil + ingepakt lettertypebestand + pakka skrifttypefil + Plik ze spakowaną czcionką + ficheiro de fontes empacotadas + arquivo de fonte empacotado + fișier font împachetat + сжатый файл шрифта + Komprimovaný súbor písma + pakirana datoteka pisave + File lloj gërmash i kondensuar + пакована датотека са фонтом + packad typsnittsfil + запакований файл шрифту + tập tin phông chữ đã đóng gói + 打包的字体文件 + 包裝字型檔 + + + + + TGIF document + مستند TGIF + Dakument TGIF + Документ — TGIF + document TGIF + Dokument TGIF + TGIF-dokument + TGIF-Dokument + Σχέδιο TGIF + TGIF document + TGIF-dokumento + documento TGIF + TGIF dokumentua + TGIF-asiakirja + TGIF skjal + document TGIF + cáipéis TGIF + documento TGIF + מסמך TGIF + TGIF-dokumentum + Dokumen TGIF + Documento TGIF + TGIF ドキュメント + TGIF құжаты + TGIF 문서 + TGIF dokumentas + TGIF dokuments + Dokumen TGIF + TGIF-dokument + TGIF-document + TGIF-dokument + Dokument TGIF + documento TGIF + Documento TGIF + Document TGIF + документ TGIF + Dokument TGIF + Dokument TGIF + Dokument TGIF + TGIF документ + TGIF-dokument + документ TGIF + Tài liệu TGIF + TGIF 文档 + TGIF 文件 + + + + + + + + theme + سمة + örtük + matyŭ + Тема + tema + Motiv + thema + tema + Thema + Θέμα + theme + etoso + tema + gaia + teema + tema + thème + téama + tema + ערכת נושא + téma + tema + Tema + テーマ + тема + 테마 + tema + tēma + Tema + tema + thema + drakt + Motyw + tema + tema + temă + тема + Motív + tema + Temë + тема + tema + тема + sắc thái + 主题 + 佈景主題 + + + + + + ToutDoux document + مستند ToutDoux + ToutDoux sənədi + Dakument ToutDoux + Документ — ToutDoux + document ToutDoux + Dokument ToutDoux + Dogfen ToutDoux + ToutDoux-dokument + ToutDoux-Dokument + έγγραφο ToutDoux + ToutDoux document + ToutDoux-dokumento + documento de ToutDoux + ToutDoux dokumentua + ToutDoux-asiakirja + ToutDoux skjal + document ToutDoux + cáipéis ToutDoux + documento de ToutDoux + משמך של ToutDoux + ToutDoux-dokumentum + Dokumen ToutDoux + Documento ToutDoux + ToutDoux ドキュメント + ToutDoux құжаты + ToutDoux 문서 + ToutDoux dokumentas + ToutDoux dokuments + Dokumen ToutDoux + ToutDoux-dokument + ToutDoux-document + ToutDoux-dokument + Dokument ToutDoux + documento ToutDoux + Documento do ToutDoux + Document ToutDoux + документ ToutDoux + Dokument ToutDoux + Dokument ToutDoux + Dokument ToutDoux + ToutDoux документ + ToutDoux-dokument + документ ToutDoux + Tài liệu ToutDoux + ToutDoux 文档 + ToutDoux 文件 + + + + backup file + ملف النسخ الاحتياطي + zapasny fajł + Резервно копие + fitxer de còpia de seguretat + Záložní soubor + sikkerhedskopi + Sicherungsdatei + αντίγραφο ασφαλείας + backup file + restaŭrkopio + archivo de respaldo + babes-kopiako fitxategia + varmuuskopio + trygdarritsfíla + fichier de sauvegarde + comhad cúltaca + ficheiro de copia de seguridade + קובץ גיבוי + biztonsági mentés + berkas cadangan + File di backup + バックアップファイル + резервті көшірмесі + 백업 파일 + atsarginis failas + rezerves fails + Fail backup + sikkerhetskopi + reservekopiebestand + tryggleikskopi + Plik zapasowy + cópia de segurança + Arquivo de backup + fișier de backup + резервная копия + Záložný súbor + varnostna kopija datoteke + File backup + резервна копија + säkerhetskopia + резервна копія + tập tin sao lưu + 备份文件 + 備份檔 + + + + + + + + Troff document + مستند Troff + Troff sənədi + Dakument Troff + Документ — Troff + document Troff + Dokument troff + Dogfen troff + Troffdokument + Troff-Dokument + έγγραφο troff + Troff document + Troff-dokumento + documento troff + Troff dokumentua + Troff-asiakirja + Troff skjal + document Troff + cáipéis Troff + documento Troff + מסמך Troff + Troff-dokumentum + Dokumen Troff + Documento Troff + Troff 入力ドキュメント + Troff құжаты + Troff 문서 + Troff dokumentas + Troff dokuments + Dokumen Troff + Troff-dokument + Troff-document + Troff-dokument + Dokument Troff + documento Troff + Documento troff + Document Troff + документ Troff + Dokument troff + Dokument Troff + Dokument Troff + Troff документ + Troff-dokument + документ Troff + Tài liệu Troff + Troff 文档 + Troff 文件 + + + + + + + + + + + + + + + Troff document (with manpage macros) + مستند Troff (مع اختصارات صفحة المساعدة) + Dakument Troff (z makrasam man-staronak) + Документ — Troff, с макроси за справочни страници + document Troff (amb macros de pàgines de manual) + Dokument troff (s makry pro manuálové stránky) + Troffdokument (med manualsidemakroer) + Troff-Dokument (mit man-Seitenmakros) + έγγραφο troff (με μακροεντολές manpage) + Troff document (with manpage macros) + Troff-dokumento (kun manpaĝaj makrooj) + documento troff (con macros de páginas de manual) + Troff dokumentua (manpage makroekin) + Troff-asiakirja (man-sivu-makroilla) + Troff skjal (við manpage fjølvi) + document Troff (avec macros manpage) + cáipéis Troff (le macraí manpage) + documento Troff (con macros de páxinas de manual) + מסמך של Troff (עם מאקרו בmanpage) + Troff-dokumentum (manpage-makrókkal) + Dokumen Troff (dengan makro halaman manual) + Documento Troff (con macro per manpage) + Troff 入力ドキュメント (man ページマクロ有り) + Troff құжаты (әдістемелік парақтар макростарымен) + Troff 문서 (맨페이지 매크로 포함) + Troff dokumentas (su žin. puslapių makrokomandomis) + Troff dokuments (ar manpage makrosiem) + Dokumen Troff (dengan macros halaman man) + Troff-dokument (med manualsidemakroer) + Troff-document (met man-macro's) + Troff-dokument med manualside-makroar + Dokument Troff (z makrami stron pomocy) + documento Troff (com macros manpage) + Documento troff (com macros de páginas de manual) + Document Troff (cu macro-uri manpage) + документ Troff (с макросами страниц руководства) + Dokument troff (s makrami pre manuálové stránky) + Dokument Troff (z makroji manpage) + Dokumet Troff (me makro për manpage) + Troff документ (са макроима за ман странице) + Troff-dokument (med manualsidemakron) + документ Troff (з макросами manpage) + Tài liệu Troff (có vĩ lệnh trang hướng dẫn) + Troff 文档(带 Man 手册宏) + Troff 文件 (含有手冊頁面巨集) + + + + + + manual page (compressed) + صفحة المساعدة (مضغوطة) + man səhifəsi (sıxışdırılmış) + staronka dapamohi (skampresavanaja) + Страница от справочника, компресирана + pàgina de manual (comprimida) + Manuálová stránka (komprimovaná) + tudalen llawlyfr (wedi ei gywasgu) + manualside (komprimeret) + Handbuchseite (komprimiert) + σελίδα οδηγιών (συμπιεσμένη) + manual page (compressed) + manpaĝo (kunpremita) + página de manual (comprimida) + eskuliburu orria (konprimitua) + manuaalisivu (pakattu) + handbókasíða (stappað) + page de manuel (compressée) + leathanach lámhleabhair (comhbhrúite) + páxina de manual (comprimida) + דף עזר (מכווץ) + kézikönyvoldal (tömörített) + halaman manual (terkompresi) + Pagina di manuale (compressa) + (圧縮) man ページ + әдістемелік парағы (сығылған) + 설명서 페이지 (압축) + žinyno puslapis (suglaudintas) + rokasgrāmatas lapa (saspiesta) + Halaman manual (termampat) + manualside (komprimert) + handleidingspagina (ingepakt) + manualside (pakka) + Strona podręcznika (skompresowana) + página de manual (comprimida) + página de manual (compactada) + pagină de manual (comprimată) + страница руководства (сжатая) + Manuálová stránka (komprimovaná) + stran priročnika (stisnjena) + Faqe manuali (e kompresuar) + страна упутства (компресована) + manualsida (komprimerad) + сторінка посібника (стиснена) + trang hướng dẫn (đã nén) + 手册页 (压缩) + 手冊頁面 (壓縮版) + + + + Tar archive (LZO-compressed) + أرشيف Tar (مضغوط-LZO) + Archiŭ tar (LZO-skampresavany) + Архив — tar, компресиран с LZO + arxiu tar (comprimit amb LZO) + Archiv tar (komprimovaný pomocí LZO) + Tar-arkiv (LZO-komprimeret) + Tar-Archiv (LZO-komprimiert) + archivador Tar (comprimido con LZO) + Tar artxiboa (LZO-rekin konprimitua) + Tar-arkisto (LZO-pakattu) + Tar skjalasavn (LZO-stappað) + archive tar (compression LZO) + cartlann Tar (comhbhrúite le LZO) + arquivo Tar (comprimido con LZO) + ארכיון Tar (מכווץ ע"י LZO) + Tar archívum (LZO-val tömörítve) + Arsip Tar (terkompresi LZO) + Archivio tar (compresso con LZO) + Tar アーカイブ (LZO 圧縮) + Tar архиві (LZO-мен сығылған) + TAR 묶음 파일 (LZO 압축) + Tar archyvas (suglaudintas su LZO) + Tar arhīvs (saspiests ar LZO) + Tar-arkiv (LZO-komprimert) + Tar-archief (ingepakt met LZO) + Tar-arkiv (pakka med LZO) + Archiwum tar (kompresja LZO) + Pacote tar (compactado com LZO) + Arhivă Tar (comprimată LZO) + архив TAR (сжатый LZO) + Archív tar (komprimovaný pomocou LZO) + Datoteka arhiva Tar (stisnjen z LZO) + Arkiv tar (i kompresuar me LZO) + Tar-arkiv (LZO-komprimerat) + архів tar (стиснений LZO) + Kho nén tar (đã nén LZO) + Tar 归档文件(LZO 压缩) + Tar 封存檔 (LZO 格式壓縮) + + + + + + XZ archive + أرشيف XZ + Архив — XZ + arxiu XZ + Archiv XZ + XZ-arkiv + XZ-Archiv + XZ-arkivo + archivador XZ + XZ artxiboa + XZ-arkisto + XZ skjalasavn + archive XZ + cartlann XZ + ficheiro XZ + ארכיון XZ + XZ-archívum + Arsip XZ + Archivio XZ + XZ アーカイブ + XZ архиві + XZ 압축 파일 + XZ archyvas + XZ arhīvs + Archiwum XZ + Arhivă XZ + архив XZ + Archív XZ + Datoteka arhiva XZ + XZ-arkiv + архів XZ + XZ 归档文件 + XZ 封存檔 + + + + + + + + Tar archive (XZ-compressed) + أرشيف Tar (مضغوط-XZ) + Архив — tar, компресиран с XZ + arxiu tar (comprimit amb XZ) + Archiv tar (komprimovaný pomocí XZ) + Tar-arkiv (XZ-komprimeret) + Tar-Archiv (XZ-komprimiert) + archivador Tar (comprimido con XZ) + Tar artxiboa (XZ-rekin konprimitua) + Tar-arkisto (XZ-pakattu) + Tar skjalasavn(XZ-stappað) + archive tar (compression XZ) + cartlann Tar (comhbhrúite le XZ) + arquivo Tar (comprimido con XZ) + ארכיון Tar (מכווץ ע"י XZ) + Tar archívum (XZ-vel tömörítve) + Arsip Tar (terkompresi XZ) + Archivio tar (compresso con XZ) + Tar アーカイブ (XZ 圧縮) + Tar архиві (XZ-мен сығылған) + TAR 묶음 파일 (XZ 압축) + Tar archyvas (suglaudintas su XZ) + Tar arhīvs (saspiests ar XZ) + Archiwum tar (kompresja XZ) + Arhivă Tar (comprimată XZ) + архив TAR (сжатый XZ) + Archív tar (komprimovaný pomocou XZ) + Datoteka arhiva Tar (stisnjen z XZ) + Tar-arkiv (XZ-komprimerat) + архів tar (стиснений XZ) + Tar 归档文件(XZ 压缩) + Tar 封存檔 (XZ 格式壓縮) + + + + + + PDF document (XZ-compressed) + Документ — PDF, компресиран с XZ + document PDF (comprimit amb XZ) + Dokument PDF (komprimovaný pomocí XZ) + PDF-Dokument (XZ-komprimiert) + Documento PDF (comprimido en XZ) + PDF-asiakirja (XZ-pakattu) + document PDF (compressé XZ) + documento PDF (comprimido en XZ) + מסמך PDF (בדחיסת XZ) + PDF dokumentum (XZ-vel tömörített) + Dokumen PDF (terkompresi XZ) + Documento PDF (compresso con XZ) + PDF 文書(XZ 圧縮) + PDF құжаты (XZ-мен сығылған) + PDF 문서 (XZ 압축) + PDF dokuments (saspiests ar XZ) + Dokument PDF (kompresja XZ) + документ PDF (сжатый XZ) + Dokument PDF (XZ-stisnjen) + PDF-dokument (XZ-komprimerad) + документ PDF (стиснений xz) + PDF 文档(XZ) + PDF 文件 (XZ 格式壓縮) + + + + + + Ustar archive + أرشيف Ustar + Archiŭ ustar + Архив — ustar + arxiu ustar + Archiv ustar + Ustararkiv + Ustar-Archiv + Ustar-arkivo + archivador Ustar + Ustar artxiboa + Ustar-arkisto + Ustar skjalasavn + archive Ustar + cartlann Ustar + arquivo Ustar + ארכיון Ustar + Ustar archívum + Arsip Ustar + Archivio ustar + Ustar アーカイブ + Ustar архиві + Ustar 묶음 파일 + Ustar archyvas + Ustar arhīvs + Ustar-arkiv + Ustar-archief + Ustar-arkiv + Archiwum ustar + Pacote Ustar + Arhivă Ustar + архив Ustar + Archív ustar + Datoteka arhiva Ustar + Arkiv Ustar + Ustar-arkiv + архів ustar + Kho nén ustar + Ustar 归档文件 + Ustar 封存檔 + + + + + WAIS source code + شفرة مصدر WAIS + WAIS mənbə faylı + Kryničny kod WAIS + Изходен код — WAIS + codi font en WAIS + Zdrojový kód WAIS + Ffynhonnell Rhaglen WAIS + WAIS-kildekode + WAIS-Quelltext + πηγαίος κώδικας WAIS + WAIS source code + WAIS-fontkodo + código fuente WAIS + WAIS iturburu-kodea + WAIS-lähdekoodi + WAIS keldukota + code source WAIS + cód foinseach WAIS + código fonte WAIS + קוד מקור של WAIS + WAIS-forráskód + Kode program WAIS + Codice sorgente WAIS + WAIS ソースコード + WAIS бастапқы коды + WAIS 소스 코드 + WAIS pradinis kodas + WAIS pirmkods + Kod sumber WAIS + WAIS-kildekode + WAIS-broncode + WAIS-kjeldekode + Plik źródłowy WAIS + código fonte WAIS + Código fonte WAIS + Cod sursă WAIS + исходный код WAIS + Zdrojový kód WAIS + Datoteka izvorne kode WAIS + Kod burues WAIS + WAIS изворни ко̂д + WAIS-källkod + вихідний код мовою WAIS + Mã nguồn WAIS + WAIS 源代码 + WAIS 源代碼 + + + + + WordPerfect/Drawperfect image + صورة WordPerfect/Drawperfect + Vyjava WordPerfect/Drawperfect + Изображение — WordPerfect/Drawperfect + imatge de WordPerfect/Drawperfect + Obrázek WordPerfect/Drawperfect + WordPerfect/Drawperfect-billede + WordPerfect/DrawPerfect-Bild + εικόνα WordPerfect/Drawperfect + WordPerfect/Drawperfect image + WordPerfect/Drawperfect-bildo + imagen de WordPerfect/Drawperfect + WordPerfect/Drawperfect irudia + WordPerfect/Drawperfect-kuva + WordPerfect/Drawperfect mynd + image WordPerfect/DrawPerfect + íomhá WordPerfect/Drawperfect + imaxe de WordPerfect/DrawPerfect + תמונה של WordPerfect/Drawperfect + WordPerfect/Drawperfect-kép + Gambar WordPerfect/Drawperfect + Immagine WordPerfect/Drawperfect + WordPerfect/Drawperfect 画像 + WordPerfect/Drawperfect суреті + 워드퍼펙트/드로우퍼펙트 그림 + WordPerfect/Drawperfect paveikslėlis + WordPerfect/Drawperfect attēls + Imej WordPerfect/Drawperfect + WordPerfect-/Drawperfect-bilde + WordPerfect/Drawperfect-afbeelding + WordPerfect/DrawPerfect-bilete + Obraz WordPerfect/DrawPerfect + imagem do WordPerfect/Drawperfect + Imagem do WordPerfect/Drawperfect + Imagine WordPerfect/Drawperfect + изображение WordPerfect/Drawperfect + Obrázok WordPerfect/Drawperfect + Slikovna datoteka Drawperfect + Figurë WordPerfect/Drawperfect + WordPerfect/Drawperfect слика + WordPerfect/Drawperfect-bild + зображення WordPerfect/Drawperfect + Ảnh WordPerfect/Drawperfect + WordPerfect/Drawperfect 图像 + WordPerfect/Drawperfect 影像 + + + + + DER/PEM/Netscape-encoded X.509 certificate + شهادة DER/PEM/Netscape-encoded X.509 + Sertyfikat X.509, zakadavany ŭ DER/PEM/Netscape + Сертификат — DER/PEM/Netscape X.509 + certificat X.509 codificat com DER/PEM/Netscape + Certifikát X.509 kódovaný jako DER/PEM/Netscape + DER-/PEM-/Netscapekodet X.509-certifikat + DER/PEM/Netscape-kodiertes X.509-Zertifikat + ψηφιακό πιστοποιητικό X.509 κωδικοποιημένο κατά DER/PEM/Netscape + DER/PEM/Netscape-encoded X.509 certificate + DER/PEM/Netscape-kodigita X.509-certigilo + certificado X.509 codificado con DER/PEM/Netscape + X.509rekin kodetutako DER, PEM edo Netscape zertifikatua + DER/PEM/Netscape-koodattu X.509-varmenne + DER/PEM/Netscape-encoded X.509 váttan + certificat X.509 codé DER/PEM/Netscape + teastas X.509 ionchódaithe le DER/PEM/Netscape + certificado X.509 codificado con DER/PEM/Netscape + אישור מסוג X.509 של DER/PEM/Netscape-encoded + DER/PEM/Netscape formátumú X.509-tanúsítvány + Sertifikat DER/PEM/Netscape-tersandi X.509 + Certificato DER/PEM/Netscape-encoded X.509 + DER/PEM/Netscape エンコード X.509 証明書 + X.509 сертификаты (DER/PEM/Netscape кодталған) + DER/PEM/X.509로 인코드된 넷스케이프 인증서 + DER/PEM/Netscape-encoded X.509 liudijimas + DER/PEM/Netscape-encoded X.509 sertifikāts + Sijil X.509 dienkod /DER/PEM/Netscape + DER/PEM/Netscape-kodet X.509-sertifikat + DER/PEM/Netscape-gecodeerd X.509-certificaat + DER/PEM/Netscape-koda X.509-sertifikat + Zakodowany w DER/PEM/Netscape certyfikat X.509 + certificado X.509 codificado com DER/PEM/Netscape + Certificado X.509 codificado com DER/PEM/Netscape + Certificat DER/PEM/Netscape-codat X.509 + сертификат X.509 (DER/PEM/Netscape-закодированный) + Certifikát X.509 kódovaný ako DER/PEM/Netscape + Datoteka potrdila DER/PEM/Netscape X.509 + Çertifikatë DER/PEM/Netscape-encoded X.509 + DER, PEM или Нетскејп кодирани сертификат X.509 + DER/PEM/Netscape-kodat X.509-certifikat + сертифікат X.509 у форматі DER/PEM/Netscape + Chứng nhận X.509 mã hoá bằng Netscape/PEM/DER + DER/PEM/Netscape-encoded X.509 证书 + DER/PEM/Netscape 編碼的 X.509 憑證 + + + + + + + + empty document + مستند فارغ + pusty dakument + Празен документ + document buit + Prázdný dokument + tomt dokument + Leeres Dokument + κενό έγγραφο + empty document + malplena dokumento + documento vacío + dokumentu hutsa + tyhjä asiakirja + tómt skjal + document vide + cáipéis fholamh + documeto baleiro + מסמך ריק + üres dokumentum + dokumen kosong + Documento vuoto + 空のドキュメント + бос құжат + 빈 문서 + tuščias dokumentas + tukšs dokuments + Dokumen kosong + tomt dokument + leeg document + tomt dokument + Pusty dokument + documento vazio + documento vazio + document gol + пустой документ + Prázdny dokument + prazen dokument + Dokument bosh + празан документ + tomt dokument + порожній документ + tài liệu rỗng + 空文档 + 空白文件 + + + Zoo archive + أرشيف Zoo + Zoo arxivi + Archiŭ zoo + Архив — zoo + arxiu zoo + Archiv zoo + Archif zoo + Zooarkiv + Zoo-Archiv + Zoo-arkivo + archivador Zoo + Zoo artxiboa + Zoo-arkisto + Zoo skjalasavn + archive zoo + cartlann Zoo + ficheiro Zoo + ארכיון Zoo + Zoo archívum + Arsip Zoo + Archivio zoo + Zoo アーカイブ + Zoo архиві + ZOO 압축 파일 + Zoo archyvas + Zoo arhīvs + Zoo-arkiv + Zoo-archief + Zoo-arkiv + Archiwum zoo + Pacote Zoo + Arhivă Zoo + архив ZOO + Archív zoo + Datoteka arhiva ZOO + Arkiv zoo + Zoo-arkiv + архів zoo + Kho nén zoo + Zoo 归档文件 + Zoo 封存檔 + + + + + + + + XHTML page + صفحة XHTML + Staronka XHTML + Страница — XHTML + pàgina XHTML + Stránka XHTML + XHTML-side + XHTML-Seite + σελίδα XHTML + XHTML page + XHTML-paĝo + página XHTML + XHTML orria + XHTML-sivu + XHTML síða + page XHTML + leathanach XHTML + Páxina XHTML + דף XHTML + XHTML-oldal + Halaman XHTML + Pagina XHTML + XHTML ページ + XHTML парағы + XHTML 페이지 + XHTML puslapis + XHTML lapa + Laman XHTML + XHTML-side + XHTML-pagina + XHTML-side + Strona XHTML + página XHTML + Página XHTML + Pagină XHTML + страница XHTML + Stránka XHTML + Datoteka spletne strani XHTML + Faqe XHTML + XHTML страна + XHTML-sida + сторінка XHTML + Trang XHTML + XHTML 页面 + XHTML 網頁 + XHTML + Extensible HyperText Markup Language + + + + + + + Zip archive + أرشيف Zip + Zip arxivi + Archiŭ zip + Архив — zip + arxiu zip + Archiv ZIP + Archif ZIP + Ziparkiv + Zip-Archiv + Zip-arkivo + archivador Zip + Zip artxiboa + Zip-arkisto + Zip skjalasavn + archive zip + cartlann Zip + ficheiro Zip + ארכיון Zip + Zip archívum + Arsip Zip + Archivio zip + Zip アーカイブ + Zip архиві + ZIP 압축 파일 + Zip archyvas + Zip arhīvs + Zip-arkiv + Zip-archief + Zip-arkiv + Archiwum ZIP + Pacote Zip + Arhivă zip + архив ZIP + Archív ZIP + Datoteka arhiva ZIP + Arkiv zip + Zip-arkiv + архів zip + Kho nén zip + Zip 归档文件 + Zip 封存檔 + + + + + + + + + + Windows Imaging Format Disk Image + Диск — Windows Imaging + imatge de disc «Windows Imaging Format» + Windows Imaging Format Disk Image + Windows Imaging Format-diskaftryk + Windows-Imaging-Format-Datenträgerabbild + imagen de disco de Windows Imaging Format + image disque Windows Imaging Format + imaxe de disco de Windows Imaging Format + מבנה תמונת כונן של Windows Imaging + Windows Imaging Format lemezkép + Image Disk Windows Imaging Format + Immagine disco formato Windows Imaging + Windows イメージング形式 ディスクイメージ + Windows Imaging Format Disk бейнесі + 윈도우 이미지 포맷 디스크 이미지 + Windows Imaging Format diska attēls + Obraz dysku Windows Imaging Format + Imagine de disc „Windows Imaging Format” + образ диска Windows + Odtis slike Windows Imaging + Windows Imaging Format Disk-avbild + формат образів дисків Windows Imaging + Windows Imaging 格式磁盘镜像 + Windows Imaging Format Disk 映像 + + + + + + + + Dolby Digital audio + Dolby Digital سمعي + Dolby Digital audio + Aŭdyjo Dolby Digital + Аудио — Dolby Digital + àudio Dolby Digital + Zvuk Dolby Digital + Sain Dolby Digital + Dolby Ditital-lyd + Dolby-Digital-Audio + ψηφιακός Ήχος Dolby + Dolby Digital audio + Sondosiero en Dolby Digital + sonido Dolby Digital + Dolby audio digitala + Dolby Digital -ääni + Dolby Digital ljóður + audio Dolby Digital + fuaim Dolby Digital + son Dolby Digital + שמע Dolby Digital + Dolby Digital hang + Audio Dolby Digital + Audio Dolby Digital + ドルビーデジタルオーディオ + Dolby Digital аудиосы + 돌비 디지털 오디오 + Dolby Digital garso įrašas + Dolby Digital audio + Audio Digital Dolby + Dolby digital lyd + Dolby Digital-audio + Dolby Digital lyd + Plik dźwiękowy Dolby Digital + áudio Dolby Digital + Áudio Dolby Digital + Audio Dolby Digital + аудио Dolby Digital + Zvuk Dolby Digital + Zvočna datoteka Dolby Digital + Audio Dolby Digital + Дигитални Dolby звучни запис + Dolby Digital-ljud + звук Dolby Digital + Âm thanh Dolby Digital + 杜比数字音频 + 杜比數位音訊 + + + + + + + AMR audio + AMR سمعي + Aŭdyjo AMR + Аудио — AMR + àudio AMR + Zvuk AMR + AMR-lyd + AMR-Audio + AMR-sondosiero + sonido AMR + AMR audioa + AMR-ääni + AMR ljóður + audio AMR + fuaim AMR + son AMR + שמע AMR + AMR hang + Audio AMR + Audio AMR + AMR オーディオ + AMR аудиосы + AMR 오디오 + AMR garso įrašas + AMR audio + AMR-lyd + AMR-audio + AMR-lyd + Plik dźwiękowy AMR + Áudio AMR + Audio AMR + аудио AMR + Zvuk AMR + Zvočna datoteka AMR + Audio AMR + AMR-ljud + звук AMR + Âm thanh AMR + AMR 音频 + AMR 音訊 + AMR + Adaptive Multi-Rate + + + + + + + + AMR-WB audio + AMR-WB سمعي + Aŭdyjo AMR-WB + Аудио — AMR-WB + àudio AMR-WB + Zvuk AMR-WB + AMR-WB-lyd + AMR-WB-Audio + AMR-WB-sondosiero + sonido AMR-WB + AMR-WB audioa + AMR-WB-ääni + AMR-WB ljóður + audio AMR-WB + fuaim AMR-WB + son AMR-WB + שמע AMR-WN + AMR-WB hang + Audio AMR-WB + Audio AMR-WB + AMR-WB オーディオ + AMR-WB аудиосы + AMR-WB 오디오 + AMR-WB garso įrašas + AMR-WB audio + AMR-WB-lyd + AMR-WB-audio + AMR-WB-lyd + Plik dźwiękowy AMR-WB + Áudio AMR-WB + Audio AMR-WB + аудио AMR-WB + Zvuk AMR-WB + Zvočna datoteka AMR-WB + Audio AMR-WB + AMR-WB-ljud + звук AMR-WB + Âm thanh AMR-WB + AMR-WB 音频 + AMR-WB 音訊 + AMR-WB + Adaptive Multi-Rate Wideband + + + + + + + + ULAW (Sun) audio + ULAW (صن) سمعي + ULAW (Sun) audio faylı + Aŭdyjo ULAW (Sun) + Аудио — ULAW, Sun + àudio ULAW (Sun) + Zvuk ULAW (Sun) + Sain ULAW (Sun) + ULAW-lyd (Sun) + ULAW-Audio (Sun) + ήχος ULAW (Sun) + ULAW (Sun) audio + ULAW-sondosiero (Sun) + sonido ULAW (Sun) + ULAW (sun) audioa + ULAW (Sun) -ääni + ULAW (Sun) ljóður + audio ULAW (Sun) + fuaim ULAW (Sun) + son ULAW (Sun) + שמע ULAW (של Sun) + ULAW (Sun) hang + Audio ULAW (Sun) + Audio ULAW (Sun) + ULAW (Sun) オーディオ + ULAW (Sun) аудиосы + ULAW (Sun) 오디오 + ULAW (Sun) garso įrašas + ULAW (Sun) audio + Audio ULAW (Sun) + ULAW-lyd (Sun) + (Sun) ULAW-audio + ULAW (Sun)-lyd + Plik dźwiękowy ULAW (Sun) + áudio ULAW (Sun) + Áudio ULAW (Sun) + Fișier audio ULAW (Sun) + аудио ULAW (Sun) + Zvuk ULAW (Sun) + Zvočna datoteka ULAW (Sun) + Audio ULAW (Sun) + ULAW (Sun) звучни запис + ULAW-ljud (Sun) + звук ULAW (Sun) + Âm thanh ULAW (Sun) + ULAW (Sun) 音频 + ULAW (Sun) 音訊 + + + + + + + + Commodore 64 audio + Commodore 64 سمعي + Aŭdyjo Commodore 64 + Аудио — Commodore 64 + àudio Commodore 64 + Zvuk Commodore 64 + Commodore 64-lyd + Commodore-64-Audio + ήχος Commodore 64 + Commodore 64 audio + Sondosiero de Commodore 64 + sonido de Commodore 64 + Commodore 64 Audioa + Commodore 64 -ääni + Commodore 64 ljóð + audio Commodore 64 + fuaim Commodore 64 + son de Commodore 64 + שמע של Commodore 64 + Commodore 64 hang + Audio Commodore 64 + Audio Commodore 64 + Commodore 64 オーディオ + Commodore 64 аудиосы + Commodore 64 오디오 + Commodore 64 garso įrašas + Commodore 64 audio + Audio Commodore 64 + Commodore 64-lyd + Commodore 64-audio + Commodore 64-lyd + Plik dźwiękowy Commodore 64 + áudio Commodore 64 + Áudio Commodore 64 + Audio Commodore 64 + аудио Commodore 64 + Zvuk Commodore 64 + Zvočna datoteka Commodore 64 + Audio Commodore 64 + Комодор 64 звучни запис + Commodore 64-ljud + звук Commodore 64 + Âm thanh Commodore 64 + Commodore 64 音频 + Commodore 64 音訊 + + + + + + + + PCM audio + سمعي PCM + PCM audio faylı + Aŭdyjo PCM + Аудио — PCM + àudio PCM + Zvuk PCM + Sain PCM + PCM-lyd + PCM-Audio + ήχος PCM + PCM audio + PCM-sondosiero + sonido PCM + PCM audioa + PCM-ääni + PCM ljóður + audio PCM + fuaim PCM + son PCM + שמע PCM + PCM hang + Audio PCM + Audio PCM + PCM オーディオ + PCM аудиосы + PCM 오디오 + PCM garso įrašas + PCM audio + Audio PCM + PCM-lyd + PCM-audio + PCM-lyd + Plik dźwiękowy PCM + áudio PCM + Áudio PCM + Audio PCM + аудио PCM + Zvuk PCM + Zvočna datoteka PCM + Audio PCM + PCM звучни запис + PCM-ljud + звук PCM + Âm thanh PCM + PCM 音频 + PCM 音訊 + + + + + + + + + + + + + + + + + + AIFC audio + AIFC سمعي + AIFC audio faylı + Aŭdyjo AIFC + Аудио — AIFC + àudio AIFC + Zvuk AIFC + Sain AIFC + AIFC-lyd + AIFC-Audio + ήχος AIFC + AIFC audio + AIFC-sondosiero + sonido AIFC + AIFC audioa + AIFC-ääni + AIFC ljóður + audio AIFC + fuaim AIFC + son AIFC + שמע AIFC + AIFC hang + Audio AIFC + Audio AIFC + AIFC オーディオ + AIFC аудиосы + AIFC 오디오 + AIFC garso įrašas + AIFC audio + Audio AIFC + AIFC-lyd + AIFC-audio + AIFC-lyd + Plik dźwiękowy AIFC + áudio AIFC + Áudio AIFC + Fișier audio AIFC + аудио AIFC + Zvuk AIFC + Zvočna datoteka AIFC + Audio AIFC + AIFC звучни запис + AIFC-ljud + звук AIFC + Âm thanh AIFC + AIFC 音频 + AIFC 音訊 + + + + + + AIFF/Amiga/Mac audio + AIFF/Amiga/Mac سمعي + AIFF/Amiga/Mac audio faylı + Aŭdyjo AIFF/Amiga/Mac + Аудио — AIFF/Amiga/Mac + àudio AIFF/Amiga/Mac + Zvuk AIFF/Amiga/Mac + Sain AIFF/Amiga/Mac + AIFF-/Amiga-/Maclyd + AIFF/Amiga/Mac-Audio + ήχος AIFF/Amiga/Mac + AIFF/Amiga/Mac audio + AIFF/Amiga/Mac-sondosiero + sonido AIFF/Amiga/Mac + AIFF/Amiga/Mac audioa + AIFF/Amiga/Mac-ääni + AIFF/Amiga/Mac ljóður + audio AIFF/Amiga/Mac + fuaim AIFF/Amiga/Mac + son AIFF/Amiga/Mac + שמע AIFF/Amiga/Mac + AIFF/Amiga/Mac hang + Audio AIFF/Amiga/Mac + Audio AIFF/Amiga/Mac + AIFF/Amiga/Mac オーディオ + AIFF/Amiga/Mac аудиосы + AIFF/Amiga/Mac 오디오 + AIFF/Amiga/Mac garso įrašas + AIFF/Amiga/Mac audio + Audio AIFF/Amiga/Mac + AIFF/Amiga/Mac-lyd + AIFF/Amiga/Mac-audio + AIFF/Amiga/Mac-lyd + Plik dźwiękowy AIFF/Amiga/Mac + áudio AIFF/Amiga/Mac + Áudio AIFF/Amiga/Mac + Audio AIFF/Amiga/Mac + аудио AIFF/Amiga/Mac + Zvuk AIFF/Amiga/Mac + Zvočna datoteka AIFF/Amiga/Mac + Audio AIFF/Amiga/Mac + AIFF/Амига/Мекинтош звучни запис + AIFF/Amiga/Mac-ljud + звук AIFF/Amiga/Mac + Âm thanh AIFF/Amiga/Mac + AIFF/Amiga/Mac 音频 + AIFF/Amiga/Mac 音訊 + + + + + + + + + + + AIFF audio + AIFF سمعي + AIFF audio faylı + Aŭdyjo AIFF + Аудио — AIFF + àudio AIFF + Zvuk AIFF + Sain AIFF + AIFF-lyd + AIFF-Audio + Ήχος AIFF + AIFF audio + AIFF-sondosiero + sonido AIFF + AIFF audioa + AIFF-ääni + AIFF ljóður + audio AIFF + fuaim AIFF + son AIFF + שמע AIFF + AIFF hang + Audio AIFF + Audio AIFF + AIFF オーディオ + AIFF аудиосы + AIFF 오디오 + AIFF garso įrašas + AIFF audio + Audio AIFF + AIFF-lyd + AIFF-audio + AIFF-lyd + Plik dźwiękowy AIFF + áudio AIFF + Áudio AIFF + Audio AIFF + аудио AIFF + Zvuk AIFF + Zvočna datoteka AIFF + Audio AIFF + AIFF звучни запис + AIFF-ljud + звук AIFF + Âm thanh AIFF + AIFF 音频 + AIFF 音訊 + + + Monkey's audio + Monkey سمعي + Aŭdyjo Monkey's + Аудио — Monkey + àudio Monkey + Zvuk Monkey's + Monkeys lyd + Monkey's-Audio + sonido Monkey + Monkey audioa + Monkey's Audio -ääni + Monkey's ljóður + audio Monkey + fuaim Monkey's + son de Monkey + שמע של Monkey's + Monkey hang + Audio Monkey + Audio Monkey's + Monkey's オーディオ + Monkey аудиосы + Monkey's 오디오 + Monkey garso įrašas + Monkey's audio + Monkey's-lyd + Monkey's-audio + Monkey's Audio-lyd + Plik dźwiękowy Monkey's Audio + Áudio Monkey's + Audio Monkey's + аудио Monkey's + Zvuk Monkey's + Zvočna datoteka Monkey + Audio Monkey's + Monkey's audio + звук Monkey's + Âm thanh cua Monkey + Monkey's audio 音频 + Monkey's 音訊 + + + + + + + Impulse Tracker audio + Impulse Tracker سمعي + Impulse Tracker audio faylı + Aŭdyjo Impulse Tracker + Аудио — Impulse Tracker + àudio d'Impulse Tracker + Zvuk Impulse Tracker + Sain Impulse Tracker + Impulse Tracker-lyd + Impulse-Tracker-Audio + ήχος Impulse Tracker + Impulse Tracker audio + Sondosiero de Impulse Tracker + sonido Impulse Tracker + Impulse Tracker audioa + Impulse Tracker -ääni + Impulse Tracker ljóður + audio Impulse Tracker + fuaim Impulse Tracker + son de Impulse Tracker + שמע של Impulse Tracker + Impulse Tracker hang + Audio Impulse Tracker + Audio Impulse Tracker + Impulse Tracker オーディオ + Impulse Tracker аудиосы + Impulse Tracker 오디오 + Impulse Tracker garso įrašas + Impulse Tracker audio + Audio Impulse Tracker + Impulse Tracker-lyd + Impulse Tracker-audio + Impulse Tracker lyd + Plik dźwiękowy Impulse Tracker + áudio Impulse Tracker + Áudio Impulse Tracker + Audio Impulse Tracker + аудио Impulse Tracker + Zvuk Impulse Tracker + Zvočna datoteka Impulse Tracker + Audio Impulse Tracker + Impulse Tracker звучни запис + Impulse Tracker-ljud + звук Impulse Tracker + Âm thanh Impulse Tracker + Impulse Tracker 音频 + Impulse Tracker 音訊 + + + + + + + FLAC audio + FLAC سمعي + Aŭdyjo FLAC + Аудио — FLAC + àudio FLAC + Zvuk FLAC + FLAC-lyd + FLAC-Audio + Ήχος FLAC + FLAC audio + FLAC-sondosiero + sonido FLAC + FLAC audioa + FLAC-ääni + FLAC ljóður + audio FLAC + fuaim FLAC + son FLAC + קובץ שמע מסוג FLAC + FLAC hang + Audio FLAC + Audio FLAC + FLAC オーディオ + FLAC аудиосы + FLAC 오디오 + FLAC garso įrašas + FLAC audio + Audio FLAC + FLAC-lyd + FLAC-audio + FLAC-lyd + Plik dźwiękowy FLAC + áudio FLAC + Áudio FLAC + Audio FLAC + аудио FLAC + Zvuk FLAC + Zvočna datoteka Flac + Audio FLAC + FLAC звучни запис + FLAC-ljud + звук FLAC + Âm thanh FLAC + FLAC 音频 + FLAC 音訊 + + + + + + + + WavPack audio + WavPack سمعي + Aŭdyjo WavPack + Аудио — WavPack + àudio WavPack + Zvuk WavPack + WavPack-lyd + WavPack-Audio + WavPack-sondosiero + sonido WavPack + WavPack audioa + WavPack-ääni + WavPack ljóður + audio WavPack + fuaim WavPack + son WavPack + שמע WavPack + WavPack hang + Audio WavPack + Audio WavPack + WavPack オーディオ + WavPack аудиосы + WavPack 오디오 + WavPack garso įrašas + WavPack audio + WavPack-lyd + WavPack-audio + WavPack-lyd + Plik dźwiękowy WavPack + Áudio WavPack + Audio WavPack + аудио WavPack + Zvuk WavPack + Zvočna datoteka WavPack + Audio WavPack + WavPack-ljud + звук WavPack + Âm thanh WavPack + WavPack 音频 + WavPack 音訊 + + + + + + + + WavPack audio correction file + ملف تصحيح WavPack السمعي + Fajł aŭdyjokarekcyi WavPack + Файл за корекции на аудио — WavPack + fitxer de correcció d'àudio WavPack + Opravný zvukový soubor WavPack + WavPack-lydkorrektionsfil + WavPack-Audiokorrekturdatei + archivo de corrección de sonido WavPack + WavPack audio-zuzenketaren fitxategia + WavPack-äänikorjaustiedosto + WavPack ljóðrættingarfíla + fichier de correction audio WavPack + comhad cheartú fhuaim WavPack + ficheiro de corrección de son WavPack + קובץ תיקון שמע של WavPack + WavPack hangjavítási fájl + Berkas koreksi audio WavPack + File correzione audio WavPack + WavPack オーディオコレクションファイル + WavPack аудио түзету файлы + WavPack 오디오 교정 파일 + WavPack garso korekcijos failas + WavPack audio korekciju fails + WavPack lydkorrigeringsfil + WavPack-audio-correctiebestand + WawPack lydopprettingsfil + Plik korekcji dźwięku WavPack + Arquivo de correção de áudio WavPack + Fișier audio de corecție WavPack + файл коррекции аудио WavPack + Opravný zvukový súbor WavPack + popravljalna zvočna datoteka WavPack + File korrigjgimi audio WavPack + WavPack-ljudkorrigeringsfil + файл корекції звуку WavPack + Tập tin sửa chữa âm thanh WavPack + WavPack 音频校正文档 + WavPack 音訊校正檔 + + + + + + + MIDI audio + MIDI سمعي + MIDI audio faylı + Aŭdyjo MIDI + Аудио — MIDI + àudio MIDI + Zvuk MIDI + Sain MIDI + MIDI-lyd + MIDI-Audio + ήχος MIDI + MIDI audio + MIDI-sondosiero + sonido MIDI + MIDI audioa + MIDI-ääni + MIDI ljóður + audio MIDI + fuaim MIDI + son MIDI + שמע MIDI + MIDI hang + Audio MIDI + Audio MIDI + MIDI オーディオ + MIDI аудиосы + 미디 오디오 + MIDI garso įrašas + MIDI audio + Audio MIDI + MIDI-lyd + MIDI-audio + MIDI-lyd + Plik dźwiękowy MIDI + áudio MIDI + Áudio MIDI + Audio MIDI + аудио MIDI + Zvuk MIDI + Zvočna datoteka MIDI + Audio MIDI + MIDI звучни запис + MIDI-ljud + звук MIDI + Âm thanh MIDI + MIDI 音频 + MIDI 音訊 + + + + + + + + + + compressed Tracker audio + Tracker سمعي مضغوط + aŭdyjo skampresavanaha Trackera + Аудио — Tracker, компресирано + àudio Tracker comprimit + Komprimovaný zvuk Tracker + Trackerkomprimeret lyd + Komprimiertes Tracker-Audio + tracker de sonido comprimido + konprimitutako Tracker audioa + pakattu Tracker-ääni + stappað Tracker ljóður + audio Tracker compressé + fuaim chomhbhrúite Tracker + son comprimido de Tracker + שמע גשש מכווץ + tömörített Tracker hang + audio Tracker terkompresi + Audio compresso Tracker + 圧縮 Tracker オーディオ + сығылған Tracker аудиосы + 압축한 Tracker 오디오 + suglaudintas Tracker garso įrašas + saspiests Tracker audio + ingepakte Tracker-audio + komprimert Tracker-lyd + Skompresowany plik dźwiękowy Tracker + áudio Tracker compactado + Tracker audio comprimat + аудио Tracker (сжатое) + Komprimovaný zvuk Tracker + Skrčena zvočna datoteka Tracker + Audio Tracker e kompresuar + komprimerat Tracker-ljud + стиснутий звук Tracker + âm thanh Tracker đã nén + 压缩的 Tracker 音频 + 壓縮版 Tracker 音訊 + + + + + + + MPEG-4 audio + MPEG-4 سمعي + Aŭdyjo MPEG-4 + Аудио — MPEG-4 + àudio MPEG-4 + Zvuk MPEG-4 + MPEG4-lyd + MPEG-4-Audio + MPEG-4 audio + MPEG4-sondosiero + sonido MPEG-4 + MPEG-4 audioa + MPEG-4-ääni + MPEG-4 ljóður + audio MPEG-4 + fuaim MPEG-4 + son MPEG-4 + שמע MPEG-4 + MPEG-4 hang + Audio MPEG-4 + Audio MPEG-4 + MPEG-4 オーディオ + MPEG-4 аудиосы + MPEG-4 오디오 + MPEG-4 garso įrašas + MPEG-4 audio + MPEG-4-lyd + MPEG4-audio + MPEG-4-lyd + Plik dźwiękowy MPEG-4 + Áudio MPEG-4 + Audio MPEG-4 + аудио MPEG-4 + Zvuk MPEG-4 + Zvočna datoteka MPEG-4 + Audio MPEG-4 + MPEG-4-ljud + звук MPEG-4 + Âm thanh MPEG-4 + MPEG-4 音频 + MPEG-4 音訊 + + + + + + + + + + MPEG-4 video + MPEG-4 مرئي + Videa MPEG-4 + Видео — MPEG-4 + vídeo MPEG-4 + Video MPEG-4 + MPEG4-video + MPEG-4-Video + MPEG-4 video + MPEG-4-video + vídeo MPEG-4 + MPEG-4 bideoa + MPEG-4-video + MPEG-4 video + vidéo MPEG-4 + físeán MPEG-4 + vídeo MPEG-4 + וידאו MPEG-4 + MPEG-4 videó + Video MPEG-4 + Video MPEG-4 + MPEG-4 動画 + MPEG-4 видеосы + MPEG-4 비디오 + MPEG-4 vaizdo įrašas + MPEG-4 video + MPEG-4-film + MPEG4-video + MPEG-4-video + Plik wideo MPEG-4 + Vídeo MPEG-4 + Video MPEG-4 + видео MPEG-4 + Video MPEG-4 + Video datoteka MPEG-4 + Video MPEG-4 + MPEG-4-video + відеокліп MPEG-4 + Ảnh động MPEG-4 + MPEG-4 视频 + MPEG-4 視訊 + + + + + + + + + + + + + + + MPEG-4 audio book + كتاب MPEG-4 السمعي + Aŭdyjokniha MPEG-4 + Аудио книга — MPEG-4 + llibre d'àudio MPEG-4 + Zvuková kniha MPEG-4 + MPEG4-lydbog + MPEG-4-Hörbuch + MPEG-4-sonlibro + audiolibro en MPEG-4 + MPEG-4 audio-liburua + MPEG-4-äänikirja + MPEG-4 ljóðbók + livre audio MPEG-4 + leabhar fhuaim MPEG-4 + sonlibro de MPEG-4 + ספר דיגיטלי MPEG-4 + MPEG-4 hangoskönyv + Buku audio MPEG-4 + Audiolibro MPEG-4 + MPEG-4 オーディオブック + MPEG-4 аудио кітабы + MPEG-4 오디오북 + MPEG-4 garso knyga + MPEG-4 audio grāmata + MPEG-4-lydbok + MPEG4-audioboek + MPEG-4-lydbok + Książka dźwiękowa MPEG-4 + Livro de Áudio MPEG-4 + Carte audio MPEG-4 + аудиокнига MPEG-4 + Zvuková kniha MPEG-4 + Zvočna knjiga MPEG-4 + Audiolibër MPEG-4 + MPEG-4-ljudbok + аудіокнига MPEG-4 + Sách âm thanh MPEG-4 + MPEG-4 有声书 + MPEG-4 音訊書 + + + + + + + + + 3GPP multimedia file + ملف وسائط متعددة 3GPP + Multymedyjny fajł 3GPP + Мултимедия — 3GPP + fitxer multimèdia 3GPP + Soubor multimédií 3GPP + 3GPP multimedie-fil + 3GPP-Multimediadatei + archivo multimedia 3GPP + 3GPP multimediako fitxategia + 3GPP-multimediatiedosto + 3GGP margmiðlafíla + fichier multimédia 3GPP + comhad ilmheán 3GPP + ficheiro multimedia 3GPP + קובץ מולטימדיה מסוג 3GPP + 3GPP multimédiafájl + Berkas multimedia 3GPP + File multimediale 3GPP + 3GPP マルチメディアファイル + 3GPP мультимедиялық файлы + 3GPP 멀티미디어 파일 + 3GPP multimedijos failas + 3GPP multimediju fails + 3GPP-multimediafil + 3GPP-multimediabestand + 3GPP-multimediafil + Plik multimedialny 3GPP + Arquivo multimídia 3GPP + Fișier multimedia 3GPP + мультимедийный файл 3GPP + Súbor multimédií 3GPP + Večpredstavnostna datoteka 3GPP + File multimedial 3GPP + 3GPP-multimediafil + файл мультимедійних даних 3GPP + Tập tin đa phương tiện 3GPP + 3GPP 多媒体文件 + 3GPP 多媒體檔案 + 3GPP + 3rd Generation Partnership Project + + + + + + + + + + + + + + + + + + + + + + + + + 3GPP2 multimedia file + Мултимедия — 3GPP2 + fitxer multimèdia 3GPP2 + Soubor multimédií 3GPP2 + 3GPP2 multimedie-fil + 3GPP2-Multimediadatei + archivo multimedia 3GPP2 + 3GPP2-multimediatiedosto + 3GGP2 margmiðlafíla + fichier multimédia 3GPP2 + comhad ilmheán 3GPP2 + ficheiro multimedia 3GPP2 + קובץ מולטימדיה 3GPP2 + 3GPP2 multimédiafájl + Berkas multimedia 3GPP2 + File multimediale 3GPP2 + 3GPP2 マルチメディアファイル + 3GPP2 мультимедиялық файлы + 3GPP2 멀티미디어 파일 + 3GPP2 multimediju fails + Plik multimedialny 3GPP2 + Fișier multimedia 3GPP2 + мультимедийный файл 3GPP2 + Súbor multimédií 3GPP2 + Večpredstavnostna datoteka 3GPP2 + 3GPP2-multimediafil + файл мультимедійних даних 3GPP2 + 3GPP2 多媒体文件 + 3GPP2 多媒體檔案 + 3GPP2 + 3rd Generation Partnership Project 2 + + + + + + + + + + + Amiga SoundTracker audio + مقتفي صوت Amiga السمعي + Aŭdyjo Amiga SoundTracker + Аудио — Amiga SoundTracker + àudio Amiga SoundTracker + Zvuk Amiga SoundTracker + Amiga SoundTracker-lyd + Amiga-SoundTracker-Audio + ήχος Amiga SoundTracker + Amiga SoundTracker audio + Sondosiero de Amiga SoundTracker + sonido de Amiga SoundTracker + Amiga soundtracker audioa + Amiga SoundTracker -ääni + Amiga SoundTracker ljóður + audio SoundTracker Amiga + fuaim Amiga SoundTracker + son de Amiga SoundTracker + קובץ שמע של Amiga SoundTracker + Amiga SoundTracker hang + Audio Amida SoundTracker + Audio Amiga SoundTracker + Amiga SoundTracker オーディオ + Amiga SoundTracker аудиосы + Amiga SoundTracker 오디오 + Amiga SoundTracker garso įrašas + Amiga SoundTracker audio + Audio Amiga Soundtracker + Amiga SoundTracker-lyd + Amiga SoundTracker-audio + Amiga soundtracker-lyd + Plik dźwiękowy Amiga SoundTracker + áudio SoundTracker do Amiga + Áudio Amiga SoundTracker + Audio Amiga SoundTracker + аудио Amiga SoundTracker + Zvuk Amiga SoundTracker + Zvočna datoteka Amiga SoundTracker + Audio Amiga SoundTracker + Амига soundtracker звук + Amiga SoundTracker-ljud + звук Amiga SoundTracker + Âm thanh Amiga SoundTracker + Amiga SoundTracker 音频 + Amiga SoundTracker 音訊 + + + + + + + + + + MP2 audio + MP2 سمعي + Aŭdyjo MP2 + Аудио — MP2 + àudio MP2 + Zvuk MP2 + MP2-lyd + MP2-Audio + MP2-sondosiero + sonido MP2 + MP2 audioa + MP2-ääni + MP2 ljóður + audio MP2 + fuaim MP2 + son MP2 + שמע MP2 + MP2 hang + Audio MP2 + Audio MP2 + MP2 オーディオ + MP2 аудиосы + MP2 오디오 + MP2 garso įrašas + MP2 audio + MP2-lyd + MP2-audio + MP2-lyd + Plik dźwiękowy MP2 + Áudio MP2 + Audio MP2 + аудио MP2 + Zvuk MP2 + Zvočna datoteka MP2 + Audio MP2 + MP2-ljud + звук MP2 + Âm thanh MP2 + MP2 音频 + MP2 音訊 + + + + + MP3 audio + MP3 سمعي + MP3 audio faylı + Aŭdyjo MP3 + Аудио — MP3 + àudio MP3 + Zvuk MP3 + Sain MP3 + MP3-lyd + MP3-Audio + ήχος MP3 + MP3 audio + MP3-sondosiero + sonido MP3 + MP3 audioa + MP3-ääni + MP3 ljóður + audio MP3 + fuaim MP3 + son MP3 + שמע MP3 + MP3 hang + Audio MP3 + Audio MP3 + MP3 オーディオ + MP3 аудиосы + MP3 오디오 + MP3 garso įrašas + MP3 audio + Audio MP3 + MP3-lyd + MP3-audio + MP3-lyd + Plik dźwiękowy MP3 + áudio MP3 + Áudio MP3 + Audio MP3 + аудио MP3 + Zvuk MP3 + Zvočna datoteka MP3 + Audio MP3 + MP3 звучни запис + MP3-ljud + звук MP3 + Âm thanh MP3 + MP3 音频 + MP3 音訊 + + + + + + + + + + + + MP3 audio (streamed) + MP3 سمعي (تدفق) + Aŭdyjo MP3 (płyń) + Аудио — MP3, поточно + àudio MP3 (flux) + Zvuk MP3 (proud) + MP3-lyd (strøm) + MP3-Audio (Stream) + ήχος MP3 (εκπεμπόμενος) + MP3 audio (streamed) + MP3-sondosiero (fluigate) + sonido MP3 (en flujo) + MP3 audioa (korrontea) + MP3-ääni (virtaus) + MP3 ljóður (streymað) + audio MP3 (flux) + fuaim MP3 (sruthaithe) + son MP3 (en stream) + שמע MP3 (מוזרם) + MP3 hang (sugárzott) + Audio MP3 (stream) + Audio MP3 (in streaming) + MP3 オーディオ (ストリーム) + MP3 аудиосы (ағымдық) + MP3 오디오 (스트림) + MP3 garso įrašas (transliuojamas) + MP3 audio (straumēts) + Audio MP3 (aliran) + MP3-lyd (streaming) + MP3-audio (gestreamd) + Strauma MP3-lyd + Dźwięk MP3 (strumień) + áudio MP3 (em fluxo) + Áudio MP3 (em fluxo) + Audio MP3 (flux) + аудио MP3 (потоковое) + Zvuk MP3 (streamovaný) + Zvočna datoteka MP3 (pretočna) + Audio MP3 (streamed) + MP3 звучни запис (непрекидан) + MP3-ljud (flöde) + звук MP3 (потоковий) + Âm thanh MP3 (chạy luồng) + MP3 流音频 + MP3 音訊 (串流) + + + + + + + + + + + + + + + HTTP Live Streaming playlist + قائمة بث HTTP حية + Списък за изпълнение — поток по HTTP + llista de reproducció en temps real HTTP + Seznam skladeb HTTP Live Streaming + Afspilningsliste til HTTP-livestrøm + HTTP Live-Streaming-Wiedergabeliste + lista de reproducción de flujo en directo HTTP + HTTP zuzeneko korrontearen erreprodukzio-zerrenda + HTTP beinleiðis streymaður avspælingarlisti + liste de lecture de flux HTTP Live + seinmliosta sruthaithe bheo HTTP + lista de reprodución de fluxo HTTP + רשימת השמעה הזרימה של HTTP + HTTP élő lejátszólista + Daftar putar HTTP Live Streaming + Scaletta Live Steaming HTTP + HTTP ライブストリーミング再生リスト + HTTP тірі ағым ойнау тізімі + HTTP 라이브 스트리밍 재생 목록 + HTTP tiesioginio transliavimo grojaraštis + HTTP dzīvās straumēšanas repertuārs + Lista odtwarzania strumieniowego na żywo HTTP + Listă de redare difuzată ca flux HTTP + список воспроизведения HTTP-потока + Seznam predvajanja živega pretoka HTTP + HTTP Live Streaming-spellista + список відтворення HTTP Live Streaming + HTTP 直播流播放列表 + HTTP 即時串流播放清單 + + + + + + + + + + + Microsoft ASX playlist + قائمة تشغيل مايكروسوفت ASX + Śpis Microsoft ASX + Списък за изпълнение — Microsoft ASX + llista de reproducció ASX de Microsoft + Seznam skladeb Microsoft ASX + Microsoft ASX-afspilningsliste + Microsoft-ASX-Wiedergabeliste + lista de reproducción ASX de Microsoft + Microsoft ASX erreprodukzio-zerrenda + Microsoft ASX -soittolista + Microsoft ASX avspælingarlisti + liste de lecture Microsoft ASX + seinmliosta Microsoft ASX + lista de reprodución Microsoft ASX + רשימת השמעה ASX (מיקרוסופט) + Microsoft ASX lejátszólista + Senarai putar Microsoft ASX + Scaletta Microsoft ASX + Microsoft ASX 再生リスト + Microsoft ASX ойнау тізімі + 마이크로소프트 ASX 재생 목록 + Microsoft ASX grojaraštis + Microsoft ASX repertuārs + Microsoft ASX-spilleliste + Microsoft ASX-afspeellijst + Microsoft ASX-speleliste + Lista odtwarzania Microsoft ASX + Lista de execução do Microsoft ASX + Listă redare Microsoft ASX + список воспроизведения Microsoft ASX + Zoznam skladieb Microsoft ASX + Seznam predvajanja Microsoft ASX + Listë titujsh Microsoft ASF + Microsoft ASX-spellista + список відтворення ASX Microsoft + Danh mục nhạc Microsoft ASX + Microsoft ASX 播放列表 + 微軟 ASX 播放清單 + + + + + + + + + + + + + + + + + PSF audio + PSF سمعي + Aŭdyjo PSF + Аудио — PSF + àudio PSF + Zvuk PSF + PSF-lyd + PSF-Audio + PSF-sondosiero + sonido PSF + PSF audioa + PSF-ääni + PSF ljóður + audio PSF + fuaim PSF + son PSF + שמע PSF + PSF hang + Audio PSF + Audio PSF + PSF オーディオ + PSF аудиосы + PSF 오디오 + PSF garso įrašas + PSF audio + PSF-lyd + PSF-audio + PSF-lyd + Plik dźwiękowy PSF + Áudio PSF + Audio PSF + аудио PSF + Zvuk PSF + Zvočna datoteka PSF + Audio PSF + PSF-ljud + звук PSF + Âm thanh PSF + PSF 音频 + PSF 音訊 + PSF + Portable Sound Format + + + + + + + MiniPSF audio + MiniPSF سمعي + Aŭdyjo MiniPSF + Аудио — MiniPSF + àudio MiniPSF + Zvuk MiniPSF + MiniPSF-lyd + MiniPSF-Audio + MiniPSF-sondosiero + sonido MiniPSF + MiniPSF audioa + MiniPSF-ääni + MiniPSF ljóður + audio MiniPSF + fuaim MiniPSF + son MiniPSF + שמע של MiniPSP + MiniPSF hang + Audio MiniPSF + Audio MiniPSF + MiniPSF オーディオ + MiniPSF аудиосы + MiniPSF 오디오 + MiniPSF garso įrašas + MiniPSF audio + MiniPSF-lyd + MiniPSF-audio + MiniPSF-lyd + Plik dźwiękowy MiniPSF + Áudio MiniPSF + Audio MiniPSF + аудио MiniPSF + Zvuk MiniPSF + Zvočna datoteka MiniPSF + Audio MiniPSF + MiniPSF-ljud + звук MiniPSF + Âm thanh MiniPSF + MiniPSF 音频 + MiniPSF 音訊 + MiniPSF + Miniature Portable Sound Format + + + + + PSFlib audio library + مكتبة PSFlib السمعية + Aŭdyjobiblijateka PSFlib + Аудио библиотека — PSFlib + biblioteca d'àudio PSFlib + Zvuková knihovna PSFlib + PSFlib-lydbibliotek + PSFlib-Audiobibliothek + biblioteca de sonido PSFlib + PSFlib audioaren liburutegia + PSFlib-äänikirjasto + PSFlib ljóðsavn + bibliothèque audio PSFlib + leabharlann fhuaim PSFlib + Biblioteca de son PSFlib + ספריית שמע PSFlib + PSFlib hanggyűjtemény + Pustaka audio PSFlib + Libreria audio PSFlib + PSFlib オーディオライブラリ + PSFlib аудио жинағы + PSFlib 오디오 라이브러리 + PSFlib garso biblioteka + PSFlib fonotēka + PSFlib-lydbibliotek + PSFlib-audiobibliotheek + PSFlib lydbibliotek + Biblioteka dźwiękowa PSFlib + Biblioteca de áudio PSFlib + Bibliotecă audio PSFlib + фонотека PSFlib + Zvuková knižnica PSFlib + Zvočna knjižnica PSFlib + Librari audio PSFlib + PSFlib-ljudbibliotek + аудіобібліотека PSFlib + Thư viện âm thanh PSFlib + PSFlib 音频库文件 + PSFlib 音訊庫 + PSFlib + Portable Sound Format Library + + + + + Windows Media audio + Windows Media سمعي + Aŭdyjo Windows Media + Аудио — Windows Media + àudio Windows Media + Zvuk Windows Media + Windows Media-lyd + Windows-Media-Audio + sonido de Windows Media + Windows Media audioa + Windows Media -ääni + Windows Media ljóður + audio Windows Media + fuaim Windows Media + son de Windows Media + שמע של Windows Media + Windows Media hang + Audio Windows Media + Audio Windows Media + Windows Media オーディオ + Windows Media аудиосы + 윈도우 미디어 오디오 + Windows Media garso įrašas + Windows Media audio + Windows Media lyd + Windows Media-audio + Windows Media-lyd + Plik dźwiękowy Windows Media + Áudio do Windows Media + Audio Windows Media + аудио Windows Media + Zvuk Windows Media + Zvočna datoteka Windows Media + Audio Windows Media + Windows Media-ljud + звук Windows Media + Âm thanh Windows Media + Windows Media 音频 + Windows Media 音訊 + + + + + + Musepack audio + Musepack سمعي + Aŭdyjo Musepack + Аудио — Musepack + àudio Musepack + Zvuk Musepack + Musepacklyd + Musepack-Audio + sonido Musepack + Musepack audioa + Musepack-ääni + Musepack ljóður + audio Musepack + fuaim Musepack + son de Musepack + שמע של Musepack + Musepack hang + Audio Musepack + Audio Musepack + Musepack オーディオ + Musepack аудиосы + Musepack 오디오 + Musepack garso įrašas + Musepack audio + Musepack-lyd + Musepack-audio + Musepack-lyd + Plik dźwiękowy Musepack + Áudio Musepack + Audio Musepack + аудио Musepack + Zvuk Musepack + Zvočna datoteka Musepack + Audio Musepack + Musepack-ljud + звук Musepack + Âm thanh Musepack + Musepack 音频 + Musepack 音訊 + + + + + + + + + RealAudio document + مستند RealAudio + Dakument RealAudio + Документ — RealAudio + document RealAudio + Dokument RealAudio + RealAudio-dokument + RealAudio-Dokument + RealAudio document + RealAudio-dokumento + documento RealAudio + RealAudio dokumentua + RealAudio-asiakirja + RealAudio skjal + document RealAudio + cáipéis RealAudio + documento Realson + מסמך של RealAudio + RealAudio dokumentum + Dokumen RealAudio + Documento RealAudio + RealAudio ドキュメント + RealAudio құжаты + RealAudio 문서 + RealAudio dokumentas + RealAudio dokuments + RealAudio-dokument + RealAudio-document + RealAudio-dokument + Dokument RealAudio + Documento RealAudio + Document RealAudio + документ RealAudio + Dokument RealAudio + Dokument RealAudio + Dokument RealAudio + RealAudio-dokument + документ RealAudio + Tài liệu âm thanh RealAudio + RealAudio 文档 + RealAudio 文件 + + + + + + + RealMedia Metafile + ملف تعريف RealMedia + Metafajł RealMedia + Метафайл — RealMedia + metafitxer RealMedia + RealMedia Metafile + RealMedia-metafil + RealMedia-Metadatei + metarchivo RealMedia + RealMedia metafitxategia + RealMedia-metatiedosto + RealMedia metafíla + métafichier RealMedia + meiteachomhad RealMedia + Metaficheiro RealMedia + קובץ מטא של RealMedia + RealMedia metafájl + RealMedia Metafile + Metafile RealMedia + RealMedia メタファイル + RealMedia метафайлы + RealMedia 메타파일 + RealMedia metafailas + RealMedia metafails + RealMedia-metafil + RealMedia-metabestand + RealMedia-metafil + Metaplik RealMedia + Meta arquivo do RealMedia + Metafișier RealMedia + мета-файл RealMedia + RealMedia Metafile + Metadatoteka RealMedia + Metafile RealMedia + RealMedia-metafil + метафайл RealMedia + Siêu tập tin RealMedia + RealMedia 元文件 + RealMedia 中介檔 + + + + RealVideo document + مستند RealVideo + Dakument RealVideo + Документ — RealVideo + document RealVideo + Dokument RealVideo + RealAudio-dokument + RealVideo-Dokument + RealVideo document + RealVideo-dokumento + documento RealVideo + RealVideo dokumentua + RealVideo-asiakirja + RealVideo skjal + document RealVideo + cáipéis RealVideo + documento RealVideo + מסמך של RealVideo + RealVideo dokumentum + Dokumen RealVideo + Documento RealVideo + RealVideo ドキュメント + RealVideo құжаты + RealVideo 문서 + RealVideo dokumentas + RealVideo dokuments + RealAudio-dokument + RealVideo-document + RealVideo-dokument + Dokument RealVideo + Documento RealVideo + Document RealVideo + документ RealVideo + Dokument RealVideo + Video datoteka RealVideo + Dokument RealVideo + RealVideo-dokument + документ RealVideo + Tài liệu ảnh động RealVideo + RealAudio 文档 + RealVideo 文件 + + + + + + RealMedia document + مستند RealMedia + Dakument RealMedia + Документ — RealMedia + document RealMedia + Dokument RealMedia + RealMedia-dokument + RealMedia-Dokument + RealMedia document + RealMedia-dokumento + documento RealMedia + RealMedia dokumentua + RealMedia-asiakirja + RealMedia skjal + document RealMedia + cáipéis RealMedia + documento RealMedia + מסמך של RealMedia + RealMedia dokumentum + Dokumen RealMedia + Documento RealMedia + RealMedia ドキュメント + RealMedia құжаты + RealMedia 문서 + RealMedia dokumentas + RealMedia dokuments + RealMedia-dokument + RealMedia-document + RealMedia-dokument + Dokument RealMedia + Documento RealMedia + Document RealMedia + документ RealMedia + Dokument RealMedia + Dokument RealMedia + Dokument RealMedia + RealMedia-dokument + документ RealMedia + Tài liệu RealMedia + RealMedia 文档 + RealMedia 文件 + + + + + + + + + + + + + RealPix document + مستند RealPix + Dakument RealPix + Документ — RealPix + document RealPix + Dokument RealPix + RealPix-dokument + RealPix-Dokument + RealPix document + RealPix-dokumento + documento RealPix + RealPix dokumentua + RealPix-asiakirja + RealPix skjal + document RealPix + cáipéis RealPix + documento RealPix + מסמך של RealPix + RealPix dokumentum + Dokumen RealPix + Documento RealPix + RealPix ドキュメント + RealPix құжаты + RealPix 문서 + RealPix dokumentas + RealPix dokuments + RealPix-dokument + RealPix-document + RealPix-dokument + Dokument RealPix + Documento RealPix + Document RealPix + документ RealPix + Dokument RealPix + Dokument RealPix + Dokument RealPix + RealPix-dokument + документ RealPix + Tài liệu ảnh RealPix + RealPix 文档 + RealPix 文件 + + + + RealText document + مستند RealText + Dakument RealText + Документ — RealText + document RealText + Dokument RealText + RealText-dokument + RealText-Dokument + RealText document + RealText-dokumento + documento RealText + RealText dokumentua + RealText-asiakirja + RealText skjal + document RealText + cáipéis RealText + documento RealText + מסמך של RealText + RealText dokumentum + Dokumen RealText + Documento RealText + RealText ドキュメント + RealText құжаты + RealText 문서 + RealText dokumentas + RealText dokuments + RealText-dokument + RealText-document + RealText-dokument + Dokument RealText + Documento RealText + Document RealText + документ RealText + Dokument RealText + Dokument RealText + Dokument RealText + RealText-dokument + документ RealText + Tài liệu văn bản RealText + RealText 文档 + RealText 文件 + + + + RIFF audio + RIFF سمعي + RIFF audio faylı + Aŭdyjo RIFF + Аудио — RIFF + àudio RIFF + Zvuk RIFF + Sain RIFF + RIFF-lyd + RIFF-Audio + ήχος RIFF + RIFF audio + RIFF-sondosiero + sonido RIFF + RIFF audioa + RIFF-ääni + RIFF ljóð + audio RIFF + fuaim RIFF + son RIFF + שמע RIFF + RIFF-kép + Audio RIFF + Audio RIFF + RIFF オーディオ + RIFF аудиосы + RIFF 오디오 + RIFF garso įrašas + RIFF audio + Audio RIFF + RIFF-lyd + RIFF-audio + RIFF-lyd + Plik dźwiękowy RIFF + áudio RIFF + Áudio RIFF + Audio RIFF + аудио RIFF + Zvuk RIFF + Zvočna datoteka RIFF + Audio RIFF + RIFF звучни запис + RIFF-ljud + звук RIFF + Âm thanh RIFF + RIFF 音频 + RIFF 音訊 + + + + + + + Scream Tracker 3 audio + Scream Tracker 3 سمعي + Scream Tracker 3 audio faylı + Aŭdyjo Scream Tracker 3 + Аудио — Scream Tracker 3 + àudio de Scream Tracker 3 + Skladba Scream Tracker 3 + Sain Scream Tracker 3 + Scream Tracker 3-lyd + Scream-Tracker-3-Audio + ήχος Scream Tracker 3 + Scream Tracker 3 audio + Sondosiero de Scream Tracker 3 + sonido Scream Tracker 3 + Scream Tracker 3 audioa + Scream Tracker 3 -ääni + Scream Tracker 3 ljóður + audio Scream Tracker 3 + fuaim Scream Tracker 3 + son Scream Tracker 3 + שמע של Scream Tracker 3 + Scream Tracker 3 hang + Audio Scream Tracker 3 + Audio Scream Tracker 3 + Scream Tracker 3 オーディオ + Scream Tracker 3 аудиосы + Scream Tracker 3 오디오 + Scream Tracker 3 garso įrašas + Scream Tracker 3 audio + Audio Scream Tracker 3 + Scream Tracker 3-lyd + Scream Tracker 3-audio + Sream Tracker 3 lyd + Plik dźwiękowy Scream Tracker 3 + áudio Scream Tracker 3 + Áudio Scream Tracker 3 + Audio Scream Tracker 3 + аудио Scream Tracker 3 + Skladba Scream Tracker 3 + Zvočna datoteka Scream Tracker 3 + Audio Scream Tracker 3 + Scream Tracker 3 звучни запис + Scream Tracker 3-ljud + звук Scream Tracker 3 + Âm thanh Scream Tracker 3 + Scheme Tracker 3 音频 + Scream Tracker 3 音訊 + + + + + + + MP3 ShoutCast playlist + قائمة تشغيل MP3 ShoutCast + Śpis piesień dla tranślacyi MP3 + Списък за изпълнение — MP3 ShoutCast + llista de reproducció MP3 ShoutCast + Seznam skladeb MP3 ShoutCast + MP3 ShoutCast-afspilningsliste + MP3-ShoutCast-Wiedergabeliste + Λίστα αναπαραγωγής MP3 ShoutCast + MP3 ShoutCast playlist + MP3-ludlisto de ShoutCast + lista de reproducción MP3 ShoutCast + MP3 ShoutCast erreprodukzio-zerrenda + MP3 ShoutCast -soittolista + MP3 ShoutCast avspælingarlisti + liste de lecture MP3 ShoutCast + seinmliosta MP3 ShoutCast + lista de reprodución MP3 de ShoutCast + רשימת השמעה MP3 של ShoutCast + MP3 ShoutCast-lejátszólista + Senarai putar MP3 ShoutCast + Scaletta MP3 ShoutCast + MP3 ShoutCast 再生リスト + MP3 ShoutCast ойнау тізімі + MP3 ShoutCast 재생 목록 + MP3 ShoutCast grojaraštis + MP3 ShoutCast repertuārs + Senaraimain ShoutCast MP3 + MP3 ShoutCast-spilleliste + MP3 ShoutCast-afspeellijst + MP3 ShoutCast-speleliste + Lista odtwarzania MP3 ShoutCast + lista de reprodução MP3 ShoutCast + Lista de reprodução MP3 ShoutCast + Listă MP3 ShoutCast + список воспроизведения MP3 ShoutCast + Zoznam skladieb MP3 ShoutCast + Seznam predvajanja MP3 ShoutCast + Listë titujsh MP3 ShoutCast + MP3 ShoutCast списак песама + MP3 ShoutCast-spellista + список програвання MP3 ShoutCast + Danh mục nhạc MP3 ShoutCast + MP3 ShoutCast 播放列表 + MP3 ShoutCast 播放清單 + + + + + + + + + + Scream Tracker audio + Scream Tracker سمعي + Scream Tracker audio faylı + Aŭdyjo Scream Tracker + Аудио — Scream Tracker + àudio de Scream Tracker + Skladba Scream Tracker + Sain Scream Tracker + Scream Tracker-lyd + Scream-Tracker-Audio + ήχος Scream Tracker + Scream Tracker audio + Sondosiero de Scream Tracker + sonido Scream Tracker + Scream Tracker audioa + Scream Tracker -ääni + Scream Tracker ljóður + audio Scream Tracker + fuaim Scream Tracker + son Scream Tracker + שמע של Scream Tracker + Scream Tracker hang + Audio Scream Tracker + Audio Scream Tracker + Scream Tracker オーディオ + Scream Tracker аудиосы + Scream Tracker 오디오 + Scream Tracker garso įrašas + Scream Tracker audio + Audio Scream Tracker + Scream Tracker-lyd + Scream Tracker-audio + Scream Tracker lyd + Plik dźwiękowy Scream Tracker + áudio Scream Tracker + Áudio Scream Tracker + Audio Scream Tracker + аудио Scream Tracker + Skladba Scream Tracker + Zvočna datoteka Scream Tracker + Audio Scream Tracker + Scream Tracker звучни запис + Scream Tracker-ljud + звук Scream Tracker + Âm thanh Scream Tracker + Scream Tracker 音频 + Scream Tracker 音訊 + + + + + + + + + VOC audio + VOC سمعي + VOC audio faylı + Aŭdyjo VOC + Аудио — VOC + àudio VOC + Zvuk VOC + Sain VOC + VOC-lyd + VOC-Audio + ήχος VOC + VOC audio + VOC-sondosiero + sonido VOC + VOC audioa + VOC-ääni + VOC ljóður + audio VOC + fuaim VOC + son VOC + שמע VOC + VOC hang + Audio VOC + Audio VOC + VOC オーディオ + VOC аудиосы + VOC 오디오 + VOC garso įrašas + VOC audio + Audio VOC + VOC-lyd + VOC-audio + VOC-lyd + Plik dźwiękowy VOC + áudio VOC + Áudio VOC + Audio VOC + аудио VOC + Zvuk VOC + Zvočna datoteka VOC + Audio VOC + VOC звучни запис + VOC-ljud + звук VOC + Âm thanh VOC + VOC 音频 + VOC 音訊 + + + + WAV audio + WAV سمعي + WAV audio faylı + Aŭdyjo WAV + Аудио — WAV + àudio WAV + Zvuk WAV + Sain WAV + WAV-lyd + WAV-Audio + ήχος WAV + WAV audio + WAV-sonkodo + sonido WAV + WAV audioa + WAV-ääni + WAV ljóður + audio WAV + fuaim WAV + son WAV + שמע WAV + WAV hang + Audio WAV + Audio WAV + WAV オーディオ + WAV аудиосы + WAV 오디오 + WAV garso įrašas + WAV audio + Audio VOC + WAV-lyd + WAV-audio + WAV-lyd + Plik dźwiękowy WAV + áudio WAV + Áudio WAV + Audio WAV + аудио WAV + Zvuk WAV + Zvočna datoteka WAV + Audio WAV + WAV звучни запис + WAV-ljud + звук WAV + Âm thanh WAV + WAV 音频 + WAV 音訊 + + + + + + + + + + Scream Tracker instrument + آلة Scream Tracker + Scream Tracker instrumenti + Instrument Scream Tracker + Инструмент — Scream Tracker + instrument de Scream Tracker + Nástroj pro Scream Tracker + Offeryn Scream Tracker + Scream Tracker-instrument + Scream-Tracker-Instrument + μουσικό όργανο Scream Tracker + Scream Tracker instrument + instrumento de Scream Tracker + instrumento Scream Tracker + Scream Tracker instrumentua + Scream Tracker -soitin + Scream Tracker ljóðføri + instrument Scream Tracker + ionstraim Scream Tracker + Instrumento Scream Tracker + כלי של Scream Tracker + Scream Tracker hangszer + Instrumen Scream Tracker + Strumento Scream Tracker + Scream Tracker インストゥルメント + Scream Tracker сайманы + Scream Tracker 악기 + Scream Tracker instrumentas + Scream Tracker instrumenti + Instrumen Scream Tracker + Scream Tracker-instrument + Scream Tracker-instrument + Scream Tracker instrument + Instrument Scream Tracker + instrumento Scream Tracker + Instrumento Scream Tracker + Instrument Scream Tracker + инструмент Scream Tracker + Nástroj pre Scream Tracker + Datoteka zvoka glasbila Scream Tracker + Instrument Scream Tracker + Scream Tracker инструмент + Scream Tracker-instrument + інструмент Scream Tracker + Nhạc khí Scream Tracker + Scream Tracker 乐器 + Scream Tracker 樂器檔 + + + + + + + FastTracker II audio + FastTracker II سمعي + FastTracker II audio faylı + Aŭdyjo FastTracker II + Аудио — FastTracker II + àudio de FastTracker II + Zvuk FastTracker II + Sain FastTracker II + FastTracker II-lyd + FastTracker-II-Audio + ήχος FastTracker II + FastTracker II audio + Sondosiero de FastTracker II + sonido FastTracker II + FastTracker II.ren audioa + FastTracker II -ääni + FastTracker II ljóður + audio FastTracker II + fuaim FastTracker II + son de FastTracker II + שמע FastTracker II + FastTracker II hang + Audio FastTracker II + Audio FastTracker II + FastTracker II オーディオ + FastTracker II аудиосы + FastTracker II 오디오 + FastTracker II garso įrašas + FastTracker II audio + Audio FastTracker II + FastTracker II-lyd + FastTracker II-audio + FastTracker II lyd + Plik dźwiękowy FastTracker II + áudio FastTracker II + Áudio FastTracker II + Audio FastTracker II + аудио FastTracker II + Zvuk FastTracker II + Zvočna datoteka FastTracker II + Audio FastTracker II + FastTracker II аудио запис + FastTracker II-ljud + звук FastTracker II + Âm thanh FastTracker II + FastTracker II 音频 + FastTracker II 音訊 + + + + + + + TrueAudio audio + TrueAudio سمعي + Aŭdyjo TrueAudio + Аудио — TrueAudio + àudio TrueAudio + Zvuk TrueAudio + TrueAudio-lyd + TrueAudio-Audio + TrueAudio-sondosiero + sonido TrueAudio + TrueAudio audioa + TrueAudio-ääni + TrueAudio ljóður + audio TrueAudio + fuaim TrueAudio + son Trueson + שמע TrueAudio + TrueAudio hang + Audio TrueAudio + Audio TrueAudio + TrueAudio オーディオ + TrueAudio аудиосы + TrueAudio 오디오 + TrueAudio garso įrašas + TrueAudio audio + TrueAudio-lyd + TrueAudio-audio + TrueAudio-lyd + Plik dźwiękowy TrueAudio + Áudio TrueAudio + Audio TrueAudio + аудио TrueAudio + Zvuk TrueAudio + Zvočna datoteka TrueAudio + Audio TrueAudio + TrueAudio-ljud + звук TrueAudio + Âm thanh TrueAudio + TrueAudio 音频 + TrueAudio 音訊 + + + + + + + + Windows BMP image + صورة Windows BMP + Windows BMP rəsmi + Vyjava Windows BMP + Изображение — Windows BMP + imatge BMP de Windows + Obrázek Windows BMP + Delwedd BMP Windows + Windows BMP-billede + Windows-BMP-Bild + εικόνα Microsoft Windows BMP + Windows BMP image + BMP-bildo de Vindozo + imagen BMP de Windows + Windows BMP irudia + Windows BMP -kuva + Windows BMP mynd + image Windows BMP + íomhá BMP Windows + imaxe BMP de Windows + תמונת BMP של Windows + Windows BMP-kép + Citra Windows BMP + Immagine Windows BMP + Windows BMP 画像 + Windows BMP суреті + 윈도우 BMP 그림 + Windows BMP paveikslėlis + Windows BMP attēls + Imej BMP Windows + Windows BMP-bilde + Windows BMP-afbeelding + Windows BMP-bilete + Obraz BMP Windows + imagem BMP Windows + Imagem BMP do Windows + Imagine Windows BMP + изображение Windows BMP + Obrázok Windows BMP + Slikovna datoteka Windows BMP + Figurë Windows BMP + Windows BMP слика + Windows BMP-bild + зображення Windows BMP + Ảnh BMP Windows + Windows BMP 图像 + Windows BMP 影像 + + + + + + + + + + + + + + WBMP image + صورة WBMP + Vyjava WBMP + Изображение — WBMP + imatge WBMP + Obrázek WBMP + WBMP-billede + WBMP-Bild + WBMP-bildo + imagen WBMP + WBMP irudia + WBMP-kuva + WBMP mynd + image WBMP + íomhá WBMP + imaxe WBMP + תמונת WBMP + WBMP kép + Citra WBMP + Immagine WBMP + WBMP 画像 + WBMP суреті + WBMP 그림 + WBMP paveikslėlis + WBMP attēls + WBMP-bilde + WBMP-afbeelding + WBMP-bilete + Obraz WBMP + Imagem WBMP + Imagine WBMP + изображение WBMP + Obrázok WBMP + Slikovna datoteka WBMP + Figurë WBMP + WBMP-bild + зображення WBMP + Ảnh WBMP + WBMP 图像 + WBMP 影像 + WBMP + WAP bitmap + + + + Computer Graphics Metafile + ملف تعريف رسوميات الحاسوب + Kompüter Qrafikası Meta Faylı + Metafajł Computer Graphics + Метафайл — Computer Graphics + metafitxer de Computer Graphics + Computer Graphics Metafile + Delwedd ffurf CGM + Computer Graphics-metafil + CGM-Datei + αρχείο Computer Graphics Metafile + Computer Graphics Metafile + metaarchivo de Computer Graphics + Ordenagailuko grafikoen meta-fitxategia + Computer Graphics -metatiedosto + Teldugrafikk metafíla + métafichier Computer Graphics + meiteachomhad Grafaicí Ríomhaire + metaficheiro de Computer Graphics + קובץ-מטה מסוג Computer Graphics + Computer Graphics-metafájl + Computer Graphics Metafile + Computer Graphics Metafile + コンピューターグラフィックメタファイル + компьютерлік графика метафайлы + 컴퓨터 그래픽스 메타파일 + Computer Graphics metafailas + Datorgrafikas metafails + Failmeta Grafik Komputer + Computer Graphics Metafile + Computer Graphics-metabestand + Computer Graphics Metafile + Metaplik grafiki komputerowej (CGM) + Computer Graphics Metafile + Meta-arquivo do Computer Graphics + Metafișier Computer Graphics + метафайл компьютерной графики + Computer Graphics Metafile + Metadatoteka računalniške grafike (CGM) + Metafile Computer Graphics + Метадатотека са рачунарском графиком (CGM) + Computer Graphics Metafil + метафайл комп'ютерної графіки + Siêu tập tin đồ họa máy tính (CMF) + CGM 计算机图像元文件 + CGM 影像 + + + + CCITT G3 fax + فاكس CCITT G3 + Faks CCITT G3 + Факс — CCITT G3 + fax CCITT G3 + Fax CCITT G3 + CCITT G3-fax + CCITT-G3-Fax + φαξ σε μορφή CCITT G3 + CCITT G3 fax + G3-fakso de CCITT + fax de CCITT G3 + CCITT G3 faxa + CCITT G3 -faksi + CCITT G3 telefaks + télécopie G3 CCITT + facs CCITT G3 + fax de CCITT G3 + פקס של CCITT G3 + CCITT G3-fax + Faks CCITT G3 + Fax CCITT G3 + CCITT G3 FAX + CCITT G3 факсі + CCITT G3 팩스 + CCITT G3 faksas + CCITT G3 fakss + Faks g3 CCITT + CCITT G3-faks + CCITT G3-fax + CCITT G3-fax + Faks CCITT G3 + fax CCITT G3 + Fax do CCITT G3 + Fax CCITT G3 + факс CCITT G3 + Fax CCITT G3 + Datoteka faksimila CCITT G3 + Fax CCITT G3 + CCITT g3 факс + CCITT G3-fax + факс CCITT G3 + Điện thư G3 CCITT + CCITT G3 传真 + CCITT G3 傳真檔 + + + + G3 fax image + صورة فاكس G3 + G3 faks rəsmi + Faksavaja vyjava G3 + Изображение — факс G3 + imatge de fax G3 + Obrázek fax G3 + Delwedd Ffacs G3 + G3-faxbillede + G3-Faxbild + εικόνα φαξ G3 + G3 fax image + G3-faksbildo + imagen de fax G3 + G3 fax-irudia + G3-faksikuva + G3 fax mynd + image de télécopie G3 + íomhá fhacs G3 + imaxe de fax G3 + תמונת פקס של G3 + G3-faxkép + Citra faks G3 + Immagine fax G3 + G3 FAX 画像 + G3 факс суреті + G3 팩스 그림 + G3 fax paveikslėlis + G3 faksa attēls + Imej fax G3 + G3-faksbilde + G3 faxafbeelding + G3 faksbilete + Obraz faksowy G3 + imagem de fax G3 + Imagem de fax G3 + Imagine fax G3 + факсовое изображение G3 + Obrázok fax G3 + Slikovna datoteka G3 fax + Figurë Fax G3 + G3 факс слика + G3-faxbild + факс G3 + Ảnh điện thư G3 + G3 传真文档 + G3 傳真圖 + + + GIF image + صورة GIF + GIF rəsmi + Vyjava GIF + Изображение — GIF + imatge GIF + Obrázek GIF + Delwedd GIF + GIF-billede + GIF-Bild + εικόνα GIF + GIF image + GIF-bildo + imagen GIF + GIF irudia + GIF-kuva + GIF mynd + image GIF + íomhá GIF + imaxe GIF + תמונת GIF + GIF-kép + Citra GIF + Immagine GIF + GIF 画像 + GIF суреті + GIF 그림 + GIF paveikslėlis + GIF attēls + Imej GIF + GIF-bilde + GIF-afbeelding + GIF-bilete + Obraz GIF + imagem GIF + Imagem GIF + Imagine GIF + изображение GIF + Obrázok GIF + Slikovna datoteka GIF + Figurë GIF + GIF слика + GIF-bild + зображення GIF + Ảnh GIF + GIF 图像 + GIF 影像 + + + + + + + IEF image + صورة IEF + IEF rəsmi + Vyjava IEF + Изображение — IEF + imatge IEF + Obrázek IEF + Delwedd IEF + IEF-billede + IEF-Bild + εικόνα IEF + IEF image + IEF-bildo + imagen IEF + IEF irudia + IEF-kuva + IEF mynd + image IEF + íomhá IEF + imaxe IEF + תמונת IEF + IEF-kép + Citra IEF + Immagine IEF + IEF 画像 + IEF суреті + IEF 그림 + IEF paveikslėlis + IEF attēls + Imej IEF + IEF-bilde + IEF-afbeelding + IEF-bilete + Obraz IEF + imagem IEF + Imagem IEF + Imagine IEF + изображение IEF + Obrázok IEF + Slikovna datoteka IEF + Figurë IEF + IEF слика + IEF-bild + зображення IEF + Ảnh IEF + IEF 图像 + IEF 影像 + + + + JPEG image + صورة JPEG + JPEG rəsmi + Vyjava JPEG + Изображение — JPEG + imatge JPEG + Obrázek JPEG + Delwedd JPEG + JPEG-billede + JPEG-Bild + εικόνα JPEG + JPEG image + JPEG-bildo + imagen JPEG + JPEG irudia + JPEG-kuva + JPEG mynd + image JPEG + íomhá JPEG + imaxe JPEG + תמונת JPEG + JPEG-kép + Citra JPEG + Immagine JPEG + JPEG 画像 + JPEG суреті + JPEG 그림 + JPEG paveikslėlis + JPEG attēls + Imej JPEG + JPEG-bilde + JPEG-afbeelding + JPEG-bilete + Obraz JPEG + imagem JPEG + Imagem JPEG + Imagine JPEG + изображение JPEG + Obrázok JPEG + Slikovna datoteka JPEG + Figurë JPEG + JPEG слика + JPEG-bild + зображення JPEG + Ảnh JPEG + JPEG 图像 + JPEG 影像 + + + + + + + + + + + JPEG-2000 image + صورة JPEG-2000 + Vyjava JPEG-2000 + Изображение — JPEG-2000 + imatge JPEG-2000 + Obrázek JPEG-2000 + JPEG2000-billede + JPEG-2000-Bild + εικόνα JPEG-2000 + JPEG-2000 image + JPEG-2000-bildo + imagen JPEG-2000 + JPEG-2000 irudia + JPEG-2000-kuva + JPEG-2000 mynd + image JPEG-2000 + íomhá JPEG-2000 + imaxe JPEG-2000 + תמונת JPEG-2000 + JPEG-2000 kép + Citra JPEG-2000 + Immagine JPEG-2000 + JPEG-2000 画像 + JPEG-2000 суреті + JPEG-2000 그림 + JPEG-2000 paveikslėlis + JPEG-2000 attēls + Imej JPEG-2000 + JPEG-2000-bilde + JPEG-2000-afbeelding + JPEG-2000-bilete + Obraz JPEG-2000 + imagem JPEG-2000 + Imagem JPEG-2000 + Imagine JPEG-2000 + изображение JPEG-2000 + Obrázok JPEG-2000 + Slikovna datoteka JPEG-2000 + Figurë JPEG-2000 + JPEG-2000 слика + JPEG-2000-bild + зображення JPEG-2000 + Ảnh JPEG-2000 + JPEG-2000 图像 + JPEG-2000 影像 + + + + + + + + + + + + + + + OpenRaster archiving image + صورة أرشيف OpenRaster + Изображение — OpenRaster + imatge d'arxivat OpenRaster + Archivační obraz OpenRaster + OpenRaster-arkivaftryk + OpenRaster-Archivierungsbild + imagen de archivado de OpenRaster + OpenRaster artxiboaren irudia + OpenRaster goymslumynd + image d'archive OpenRaster + íomhá chartlannaithe OpenRaster + imaxe arquivada de OpenRaster + תמונת ארכיון של OpenRaster + OpenRaster archiválási kép + Gambar pengarsipan OpenRaster + Immagine archiviazione OpenRaster + OpenRaster アーカイブイメージ + OpenRaster архивтеу суреті + OpenRaster 압축 이미지 + OpenRaster archyvavimo paveikslėlis + OpenRaster arhivēšanas attēls + Archiwalny obraz OpenRaster + Arhivă imagine OpenRaster + архивное изображение OpenRaster + Odtis arhiva OpenRaster + OpenRaster-arkivbild + архівоване зображення OpenRaster + OpenRaster 归档映像 + OpenRaster 封存影像 + + + + + + + + + + + DirectDraw surface + مساحة DirectDraw + Pavierchnia DirectDraw + Изображение — повърхност на DirectDraw + superfície DirectDraw + Plocha DirectDraw + DirectDraw-overflade + DirectDraw-Oberfläche + superficie DirectDraw + DirectDraw gainazala + DirectDraw-piirtoalue + DirectDraw yvirflata + surface DirectDraw + dromchla DirectDraw + superficie de DirectDraw + משטח של DirectDraw + DirectDraw felület + Permukaan DirectDraw + Superficie DirectDraw + DirectDraw サーフェイス + DirectDraw жазықтығы + DirectDraw 서피스 + DirectDraw paviršius + DirectDraw virsma + DirectDraw-overflate + DirectDraw-oppervlak + DirectDraw-overflate + Powierzchnia DirectDraw + Superfície do DirectDraw + Suprafață DirectDraw + плоскость DirectDraw + Plocha DirectDraw + Datoteka predmeta DirectDraw + Superfaqe DirectDraw + DirectDraw-yta + поверхня DirectDraw + Mặt DirectDraw + DirectDraw 表面 + DirectDraw 表面 + + + + + + + X11 cursor + مؤشر X11 + Kursor X11 + Курсор — X11 + cursor X11 + Kurzor X11 + X11-markør + X11-Zeiger + cursor X11 + X11 kurtsorea + X11-osoitin + X11 vísi + curseur X11 + cúrsóir X11 + Cursor X11 + סמן של X11 + X11 kurzor + Kursor X11 + Cursore X11 + X11 カーソル + X11 курсоры + X11 커서 + X11 žymiklis + X11 kursors + X11-markør + X11-muisaanwijzer + X11-peikar + Kursor X11 + Cursor do X11 + Cursor X11 + курсор X11 + Kurzor X11 + Datoteka kazalke X11 + Kursor X11 + X11-muspekare + курсор X11 + Con chạy X11 + X11 指针 + X11 滑鼠游標 + + + + + + EXR image + صورة EXR + Vyjava EXR + Изображение — EXR + imatge EXR + Obrázek EXR + EXR-billede + EXR-Bild + EXR-bildo + imagen EXR + EXR irudia + EXR-kuva + EXR mynd + image EXR + íomhá EXR + imaxe EXR + תמונת EXR + EXR kép + Citra EXR + Immagine EXR + EXR 画像 + EXR суреті + EXR 그림 + EXR paveikslėlis + EXR attēls + EXR-bilde + EXR-afbeelding + EXR-bilete + Obraz EXR + Imagem EXR + Imagine EXR + изображение EXR + Obrázok EXR + Slikovna datoteka EXR + Figurë EXR + EXR-bild + зображення EXR + Ảnh EXR + EXR 图像 + EXR 影像 + + + + + + + Macintosh Quickdraw/PICT drawing + رسمة ماكنتوش Quickdraw/PICT + Rysunak Macintosh Quickdraw/PICT + Чертеж — Macintosh Quickdraw/PICT + dibuix Quickdraw/PICT de Macintosh + Kresba Macintosh Quickdraw/PICT + Macintosh Quickdraw/PICT-tegning + Macintosh-Quickdraw/PICT-Zeichnung + σχέδιο Macintosh Quickdraw/PICT + Macintosh Quickdraw/PICT drawing + Quickdraw/PICT-grafikaĵo de Macintosh + dibujo de Macintosh Quickdraw/PICT + Macintosh Quickdraw/PICT marrazkia + Macintosh Quickdraw/PICT -piirros + Macintosh Quickdraw/PICT tekning + dessin Macintosh Quickdraw/PICT + líníocht Macintosh Quickdraw/PICT + debuxo de Macintosh Quickdraw/PICT + ציור של Macintosh Quickdraw/PICT + Macintosh Quickdraw/PICT-rajz + Gambar Macintosh Quickdraw/PICT + Disegno Macintosh Quickdraw/PICT + Macintosh Quickdraw/PICT ドロー + Macintosh Quickdraw/PICT суреті + 맥킨토시 Quickdraw/PICT 그림 + Macintosh Quickdraw/PICT piešinys + Macintosh Quickdraw/PICT zīmējums + Lukisan Macintosh Quickdraw/PICT + Macintosh Quickdraw/PICT-tegning + Macintosh Quickdraw/PICT-tekening + Macintosh Quickdraw/PICT-teikning + Rysunek Quickdraw/PICT Macintosh + desenho Quickdraw/PICT de Macintosh + Desenho do Macintosh Quickdraw/PICT + Desen Macintosh Quickdraw/PICT + рисунок Macintosh Quickdraw/PICT + Kresba Macintosh QuickDraw/PICT + Datoteka risbe Macintosh Quickdraw/PICT + Vizatim Macintosh Quickdraw/PICT + Мекинтош Quickdraw/PICT цртеж + Macintosh Quickdraw/PICT-teckning + малюнок Macintosh Quickdraw/PICT + Bản vẽ Quickdraw/PICT của Macintosh + Macintosh Quickdraw/PICT 绘图 + Macintosh Quickdraw/PICT 繪圖 + + + + + + UFRaw ID image + صورة UFRaw ID + Vyjava UFRaw ID + Изображение — UFRaw ID + imatge ID UFRaw + Obrázek ID UFRaw + UFRaw ID-billede + UFRaw-Bildbeschreibungsdatei + imagen de identificación UFRaw + UFRaw ID irudia + UFRaw ID -kuva + UFRaw ID mynd + image ID UFRaw + íomhá aitheantais UFRaw + imaxe de identificación UFRaw + תמונה של UFRaw ID + UFRaw azonosítófájl + Citra UFRaw ID + Immagine UFRaw ID + UFRaw ID イメージ + UFRaw ID суреті + UFRaw ID 그림 + UFRaw ID paveikslėlis + UFRaw ID attēls + UFRaw ID-bilde + UFRaw ID-afbeelding + UFRaw ID-bilete + Obraz UFRaw ID + Imagem ID do UFRaw + ID imagine UFRaw + изображение UFRaw ID + Obrázok ID UFRaw + Slikovna datoteka UFRaw ID + Figurë UFRaw ID + UFRaw ID-bild + зображення UFRaw ID + Ảnh ID UFRaw + UFRaw ID 图像 + UFRaw ID 影像 + UFRaw + Unidentified Flying Raw + + + + + + digital raw image + صورة رقمية خامة + suvoraja ličbavaja vyjava + Изображение — digital raw + imatge digital en cru + Digitální surový obrázek + digitalt råbillede + Digitales Rohbild + imagen digital en bruto + irudi gordin digitala + digitaalinen raakakuva + talgild rámynd + image brute numérique + amhíomhá digiteach + imaxe en bruto dixital + תמונה דיגטלית גולמית + digitális nyers kép + citra mentah digital + Immagine raw digitale + デジタル raw 画像 + өңделмеген сандық суреттер + 디지털 원본 이미지 + skaitmeninis neapdorotas paveikslėlis + digitāls jēlattēls + digitalt raw-bilde + onbewerkt digitaal beeld + digitalt råbilete + Surowy obraz cyfrowy + Imagem digital bruta + imagine digitală brută + необработанные цифровые изображения + Digitálny surový obrázok + surova digitalna slika + Figurë raw dixhitale + digital råbild + зображення цифрового негатива + ảnh thô số + 数字化原始图像 + 數位原生影像 + + + Adobe DNG negative + Adobe DNG negative + Adobe DNG Negative + Изображение — Adobe DNG negative + negatiu DNG d'Adobe + Adobe Digital Negative (DNG) + Adobe DNG-negativ + Adobe Digitales Negativ + negativo digital de Adobe (ADN) + Adobe DNG negatiboa + Adobe-DNG-negatiivi + Adobe DNG negativ + négatif DNG Adobe + claonchló DNG Adobe + negativo DNG de Adobe + תשליל Adobe DNG + Adobe DNG negatív + Negatif Adobe DNG + Negativo Adobe DNG + Adobe DNG ネガ + Adobe DNG негативі + 어도비 DNG 네가티브 + Adobe DNG negatyvas + Adobe DNG negatīvs + Adobe DNG-negativ + Adobe DNG-negatief + Adobe DNG-negativ + Negatyw DNG Adobe + Negativo DNG da Adobe + Negativ Adobe DNG + негатив Adobe DNG + Adobe Digital Negative (DNG) + Datoteka negativa Adobe DNG + Negativ Adobe DNG + Adobe DNG-negativ + цифровий негатив DNG Adobe + Âm bản Adobe DNG + Adobe DNG 负片 + Adobe DNG 負片 + DNG + Digital Negative + + + + + + + + Canon CRW raw image + صورة Canon CRW خامة + Suvoraja vyjava Canon CRW + Изображение — Canon CRW raw + imatge en cru de Canon CRW + Surový obrázek Canon CRW + Canon CRW-råbillede + Canon-CRW-Rohbild + imagen en bruto CRW de Canon + Canon CRW irudi gordina + Canon-CRW-raakakuva + Canon CRW rámynd + image brute CRW Canon + amhíomhá Canon CRW + imaxe en bruto de Canon CRW + תמונה גולמית של Canon CRW + Canon CRW nyers kép + Citra mentah Canon CRW + Immagine raw Canon CRW + Canon CRW raw 画像 + Canon CRW өңделмеген суреті + 캐논 CRW 원본 이미지 + Canon CRW neapdorotas paveikslėlis + Canon CRW jēlattēls + Canon CRW raw-bilde + onbewerkt Canon CRW-beeld + Canon CRW råbilete + Surowy obraz CRW Canon + Imagem bruta CRW da Canon + Imagine brută Canon CRW + необработанное изображение Canon CRW + Surový obrázok Canon CRW + Surova slikovna datoteka Canon CRW + Figurë raw Canon CRW + Canon CRW-råbild + цифровий негатив CRW Canon + Ảnh thô Canon CRW + Canon CRW 原始图像 + Canon CRW 原生影像 + CRW + Canon RaW + + + + + + + + + Canon CR2 raw image + صورة Canon CR2 خامة + Suvoraja vyjava Canon CR2 + Изображение — Canon CR2 raw + imatge en cru de Canon CR2 + Surový obrázek Canon CR2 + Canon CR2-råbillede + Canon-CR2-Rohbild + imagen en bruto CR2 de Canon + Canon CR2 irudi gordina + Canon-CR2-raakakuva + Canon CR2 rámynd + image brute CR2 Canon + amhíomhá Canon CR2 + imaxe en bruto de Canon CR2 + תמונה גולמית של Canon CR2 + Canon CR2 nyers kép + Citra mentah Canon CR2 + Immagine raw Canon CR2 + Canon CR2 raw 画像 + Canon CR2 өңделмеген суреті + 캐논 CR2 원본 이미지 + Canon CR2 neapdorotas paveikslėlis + Canon CR2 jēlattēls + Canon CR2 raw-bilde + onbewerkt Canon CR2-beeld + Canon CR2 råbilete + Surowy obraz CR2 Canon + Imagem bruta CR2 da Canon + Imagine brută Canon CR2 + необработанное изображение Canon CR2 + Surový obrázok Canon CR2 + Surova slikovna datoteka Canon CR2 + Figurë raw Canon CR2 + Canon CR2-råbild + цифровий негатив CR2 Canon + Ảnh thô Canon CR2 + Canon CR2 原始图像 + Canon CR2 原生影像 + CR2 + Canon Raw 2 + + + + + + Fuji RAF raw image + صورة Fuji RAF خامة + Suvoraja vyjava Fuji RAF + Изображение — Fuji RAF raw + imatge en cru de Fuji RAF + Surový obrázek Fuji RAF + Fuji RAF-råbillede + Fuji-RAF-Rohbild + imagen en bruto RAF de Fuji + Fuji RAF irudi gordina + Fuji-RAF-raakakuva + Fuji RAF raw mynd + image brute RAF Fuji + amhíomhá Fuji RAF + imaxe en bruto de Fuji RAF + תמונה גולמית של Fuji RAF + Fuji RAF nyers kép + Citra mentah Fuji RAF + Immagine raw Fuji RAF + Fuji RAF raw 画像 + Fuji RAF өңделмеген суреті + 후지 RAF 원본 이미지 + Fuji RAF neapdorotas paveikslėlis + Fuji RAF jēlattēls + Fuji RAF raw-bilde + onbewerkt Fuji RAF-beeld + Fuji RAF rått bilete + Surowy obraz RAF Fuji + Imagem bruta RAF da Fuji + Imagine brută Fuji RAF + необработанное изображение Fuji RAF + Surový obrázok Fuji RAF + Surova slikovna datoteka Fuji RAF + Figurë raw Fuji RAF + Fuji RAF-råbild + Цифровий негатив RAF Fuji + Ảnh thô Fuji RAF + 富士RAF 原始图像 + Fuji RAF 原生影像 + RAF + RAw Format + + + + + + + + Kodak DCR raw image + صورة Kodak DCR خامة + Suvoraja vyjava Kodak DCR + Изображение — Kodak DCR raw + imatge en cru de Kodak DCR + Surový obrázek Kodak DCR + Kodak DCR-råbillede + Kodak-DCR-Rohbild + imagen en bruto DCR de Kodak + Kodak DCR irudi gordina + Kodak-DCR-raakakuva + Kodak DCR rámynd + image brute DCR Kodak + amhíomhá Kodak DCR + imaxe en bruto de Kodad DCR + תמונה גולמית של Kodak DCR + Kodak DCR nyers kép + Citra mentah Kodak DCR + Immagine raw Kodak DCR + Kodak DCR raw 画像 + Kodak DCR өңделмеген суреті + 코닥 DCR 원본 이미지 + Kodak DCR neapdorotas paveikslėlis + Kodak DCR jēlattēls + Kodak DCR raw-bilde + onbewerkt Kodak DCR-beeld + Kodak DCR råbilete + Surowy obraz DCR Kodak + Imagem bruta DCR da Kodak + Imagine brută Kodak DCR + необработанное изображение Kodak DCR + Surový obrázok Kodak DCR + Surova slikovna datoteka Kodak DCR + Figurë raw Kodak DCR + Kodak DCR-råbild + цифровий негатив DCR Kodak + Ảnh thô Kodak DCR + Kodak DCR 原始图像 + Kodak DCR 原生影像 + DCR + Digital Camera Raw + + + + + + Kodak K25 raw image + صورة Kodak K25 خامة + Suvoraja vyjava Kodak K25 + Изображение — Kodak K25 raw + imatge en cru de Kodak K25 + Surový obrázek Kodak K25 + Kodak K25-råbillede + Kodak-K25-Rohbild + imagen en bruto K25 de Kodak + Kodak K25 raw image + Kodak-K25-raakakuva + Kodak K25 rámynd + image brute K25 Kodak + amhíomhá Kodak K25 + imaxe en bruto de Kodad K25 + תמונה גולמית של Kodak K25 + Kodak K25 nyers kép + Citra mentah Kodak K25 + Immagine raw Kodak K25 + Kodak K25 raw 画像 + Kodak K25 өңделмеген суреті + 코닥 K25 원본 이미지 + Kodak K25 neapdorotas paveikslėlis + Kodak K25 jēlattēls + Kodak K25 raw-bilde + onbewerkt Kodak K25-beeld + Kodak K25 råbilete + Surowy obraz K25 Kodak + Imagem bruta K25 da Kodak + Imagine brută Kodak K25 + необработанное изображение Kodak K25 + Surový obrázok Kodak K25 + Surova slikovna datoteka Kodak K25 + Figurë raw Kodak K25 + Kodak K25-råbild + цифровий негатив K25 Kodak + Ảnh thô Kodak K25 + Kodak K25 原始图像 + Kodak K25 原生影像 + K25 + Kodak DC25 + + + + + + Kodak KDC raw image + صورة Kodak KDC خامة + Suvoraja vyjava Kodak KDC + Изображение — Kodak KDC raw + imatge en cru de Kodak KDC + Surový obrázek Kodak KDC + Kodak KDC-råbillede + Kodak-KDC-Rohbild + imagen en bruto KDC de Kodak + Kodak KDC irudi gordina + Kodak-KDC-raakakuva + Kodak KDC rámynd + image brute KDC Kodak + amhíomhá Kodak KDC + imaxe en bruto de Kodad KDC + תמונה גולמית של Kodak KDC + Kodak KDC nyers kép + Citra mentah Kodak KDC + Immagine raw Kodak KDC + Kodak KDC raw 画像 + Kodak KDC өңделмеген суреті + 코닥 KDC 원본 이미지 + Kodak KDC neapdorotas paveikslėlis + Kodak KDC jēlattēls + Kodak KDC raw-bilde + onbewerkt Kodak KDC-beeld + Kodak KDC råbilete + Surowy obraz KDC Kodak + Imagem bruta KDC da Kodak + Imagine brută Kodak KDC + необработанное изображение Kodak KDC + Surový obrázok Kodak KDC + Surova slikovna datoteka Kodak KDC + Figurë raw Kodak KDC + Kodak KDC-råbild + цифровий негатив KDC Kodak + Ảnh thô Kodak KDC + Kodak KDC 原始图像 + Kodak KDC 原生影像 + KDC + Kodak Digital Camera + + + + + + + + + Minolta MRW raw image + صورة Minolta MRW خامة + Suvoraja vyjava Minolta MRW + Изображение — Minolta MRW raw + imatge en cru de Minolta MRW + Surový obrázek Minolta MRW + Minolta MRW-råbillede + Minolta-MRW-Rohbild + imagen en bruto MRW de Minolta + Minolta MRW irudi gordina + Minolta-MRW-raakakuva + Minolta MRW rámynd + image brute MRW Minolta + amhíomhá Minolta MRW + imaxe RAW de Minolta MRW + תמונה גולמית של Minolta MRW + Minolta MRW nyers kép + Citra mentah Minolta MRW + Immagine raw Minolta MRW + Minolta MRW raw 画像 + Minolta MRW өңделмеген суреті + 미놀타 MRW 원본 이미지 + Minolta MRW neapdorotas paveikslėlis + Minolta MRW jēlattēls + Minolta MRW raw-bilde + onbewerkt Minolta MRW-beeld + Minolta MRW råbilete + Surowy obraz MRW Minolta + Imagem bruta MRW do Minolta + Imagine brută Minolta MRW + необработанное изображение Minolta MRW + Surový obrázok Minolta MRW + Surova slikovna datoteka Minolta MRW + Figurë raw Minolta MRW + Minolta MRW-råbild + цифровий негатив MRW Minolta + Ảnh thô Minolta MRW + Minolta MRW 原始图像 + Minolta MRW 原生影像 + MRW + Minolta RaW + + + + + + + + Nikon NEF raw image + صورة Nikon NEF خامة + Suvoraja vyjava Nikon NEF + Изображение — Nikon NEF raw + imatge en cru de Nikon NEF + Surový obrázek Nikon NEF + Nikon NEF-råbillede + Nikon-NEF-Rohbild + imagen en bruto NEF de Nikon + Nikon NEF irudi gordina + Nikon-NEF-raakakuva + Nikon NEF rámynd + image brute NEF Nikon + amhíomhá Nikon NEF + imaxe RAW NEF Nikon + תמונה גולמית של Nikon NEF + Nikon NEF nyers kép + Citra mentah Nikon NEF + Immagine raw Nikon NEF + Nikon NEF raw イメージ + Nikon NEF өңделмеген суреті + 니콘 NEF 원본 이미지 + Nikon NEF neapdorotas paveikslėlis + Nikon NEF jēlattēls + Nikon NEF raw-bilde + onbewerkt Nikon NEF-beeld + Nikon NEF råbilete + Surowy obraz NEF Nikon + Imagem bruta NEF da Nikon + Imagine brută Nikon NEF + необработанное изображение Nikon NEF + Surový obrázok Nikon NEF + Surova slikovna datoteka Nikon NEF + Figurë raw Nikon NEF + Nikon NEF-råbild + цифровий негатив NEF Nikon + Ảnh thô Nikon NEF + Nikon NEF 原始图像 + Nikon NEF 原生影像 + NEF + Nikon Electronic Format + + + + + + Olympus ORF raw image + صورة Olympus ORF خامة + Suvoraja vyjava Olympus ORF + Изображение — Olympus ORF raw + imatge en cru d'Olympus ORF + Surový obrázek Olympus ORF + Olympus ORF-råbillede + Olympus-ORF-Rohbild + imagen en bruto ORF de Olympus + Olympus ORF irudi gordina + Olympus-ORF-raakakuva + Olympus ORF rámynd + image brute ORF Olympus + amhíomhá Olympus ORF + imaxe en bruto de Olympus ORF + תמונה גולמית של Olympus ORF + Olympus ORF nyers kép + Citra mentah Olympus ORF + Immagine raw Olympus ORF + Olympus ORF raw 画像 + Olympus ORF өңделмеген суреті + 올림푸스 ORF 원본 이미지 + Olympus ORF neapdorotas paveikslėlis + Olympus ORF jēlattēls + Olympus ORF raw-bilde + onbewerkt Olympus ORF-beeld + Olympus ORF råbilete + Surowy obraz Olympus ORF + Imagem bruta ORF da Olympus + Imagine brută Olympus ORF + необработанное изображение Olympus ORF + Surový obrázok Olympus ORF + Surova slikovna datoteka Olympus ORF + Figurë raw Olympus ORF + Olympus ORF-råbild + цифровий негатив ORF Olympus + Ảnh thô Olympus ORF + Olympus ORF 原始图像 + Olympus ORF 原生影像 + ORF + Olympus Raw Format + + + + + + + + + + + + + Panasonic raw image + صورة Panasonic خامة + Suvoraja vyjava Panasonic + Изображение — Panasonic raw + imatge en cru de Panasonic + Surový obrázek Panasonic + Panasonicråbillede (raw) + Panasonic-Rohbild + imagen en bruto de Panasonic + Panasonic irudi gordina + Panasonic-raakakuva + Panasonic rámynd + image brute Panasonic + amhíomhá Panasonic + imaxe en bruto de Panasonic + תמונה גולמית של Panasonic + Panasonic nyers kép + Citra mentah Panasonic + Immagine raw Panasonic + Panasonic raw 画像 + Panasonic өңделмеген суреті + 파나소닉 원본 이미지 + Panasonic neapdorotas paveikslėlis + Panasonic jēlattēls + Panasonic raw-bilde + onbewerkt Panasonic-beeld + Panasonic råbilete + Obraz raw Panasonic + Imagem bruta da Panasonic + Imagine brută Panasonic + необработанное изображение Panasonic + Surový obrázok Panasonic + Surova slikovna datoteka Panasonic + Figurë raw Panasonic + Panasonic-råbild + цифровий негатив Panasonic + Ảnh thô Panasonic + Panasonic 原始图像 + Panasonic 原生影像 + + + + + + + + + Panasonic raw2 image + Изображение — Panasonic raw2 + imatge «RAW2» de Panasonic + Surový obrázek Panasonic raw2 + Panasonic-rå2-billede (raw) + Panasonic raw2-Bild + imagen en bruto raw2 de Panasonic + Panasonic raw2 -kuva + image raw2 Panasonic + imaxe en bruto raw2 de Panasonic + תמונת raw2 של Panasonic + Panasonic raw2 kép + Image Panasonic raw2 + Immagine raw2 Panasonic + Panasonic raw2 画像 + Panasonic raw2 суреті + 파나소닉 원본 이미지 2 + Panasonic raw2 jēlattēls + Obraz raw2 Panasonic + необработанное изображение Panasonic RAW 2 + Surový obrázok Panasonic raw2 + Slikovna datoteka Panasonic raw2 + Panasonic raw2-bild + зображення формату raw2 Panasonic + Panasonic raw2 图像 + Panasonic raw2 影像 + + + + + + + + + Pentax PEF raw image + صورة Pentax PEF خامة + Suvoraja vyjava Pentax PEF + Изображение — Pentax PEF raw + imatge en cru de Pentax PEF + Surový obrázek Pentax PEF + Pentax PEF-råbillede + Pentax-PEF-Rohbild + imagen en bruto PEF de Pentax + Pentax PEF irudi gordina + Pentax-PEF-raakakuva + Pentax PEF rámynd + image brute PEF Pentax + amhíomhá Pentax PEF + imaxe en bruto PEF de Pentax + תמונה גולמית של Pentax PEF + Pentax PEF nyers kép + Citra mentah Pentax PEF + Immagine raw Pentax PEF + Pentax PEF raw 画像 + Pentax PEF өңделмеген суреті + 펜탁스 PEF 원본 이미지 + Pentax PEF neapdorotas paveikslėlis + Pentax PEF jēlattēls + Pentax PEF raw-bilde + onbewerkt Pentax PEF-beeld + Pentax PEF råbilete + Surowy obraz Pentax PEF + Imagem bruta PEF da Pentax + Imagine brută Pentax PEF + необработанное изображение Pentax PEF + Surový obrázok Pentax PEF + Surova slikovna datoteka Pentax PEF + Figurë raw Pentax PEF + Pentax PEF-råbild + цифровий негатив PEF Pentax + Ảnh thô Pentax PEF + Pentax PEF 原始图像 + Pentax PEF 原生影像 + PEF + Pentax Electronic Format + + + + + + Sigma X3F raw image + صورة Sigma X3F خامة + Suvoraja vyjava Sigma X3F + Изображение — Sigma X3F raw + imatge en cru de Sigma X3F + Surový obrázek Sigma X3F + Sigma X3F-råbillede + Sigma-X3F-Rohbild + imagen en bruto X3F de Sigma + Sigma X3F irudi gordina + Sigma-X3F-raakakuva + Sigma X3F rámynd + image brute X3F Sigma + amhíomhá Sigma X3F + imaxe en bruto X3F de Sigma + תמונה גולמית של Sigma X3F + Sigma XF3 nyers kép + Citra mentah Sigma X3F + Immagine raw Sigma X3F + Sigma X3F raw 画像 + Sigma X3F өңделмеген суреті + 시그마 X3F 원본 이미지 + Sigma X3F neapdorotas paveikslėlis + Sigma X3F jēlattēls + Sigma X3F raw-bilde + onbewerkt Sigma X3F-beeld + Sigma X3F råbilete + Surowy obraz X3F Sigma + Imagem bruta X3F da Sigma + Imagine brută Sigma X3F + необработанное изображение Sigma X3F + Surový obrázok Sigma X3F + Surova slikovna datoteka Sigma X3F + Fifurë raw Sigma X3F + Sigma X3F-råbild + цифровий негатив X3F Sigma + Ảnh thô Sigma X3F + Sigma X3F 原始图像 + Sigma X3F 原生影像 + X3F + X3 Foveon + + + + + + + + + + + + Sony SRF raw image + صورة Sony SRF خامة + Suvoraja vyjava Sony SRF + Изображение — Sony SRF raw + imatge en cru de Sony SRF + Surový obrázek Sony SRF + Sony SRF-råbillede + Sony-SRF-Rohbild + imagen en bruto SRF de Sony + Sony SRF irudi gordina + Sony-SRF-raakakuva + Sony SRF rámynd + image brute SRF Sony + amhíomhá Sony SRF + imaxe en bruto SRF de sony + תמונה גולמית של Sony SRF + Sony SRF nyers kép + Citra mentah Sony SRF + Immagine raw Sony SRF + Sony SRF raw 画像 + Sony SRF өңделмеген суреті + 소니 SRF 원본 이미지 + Sony SRF neapdorotas paveikslėlis + Sony SRF jēlattēls + Sony SRF raw-bilde + onbewerkt Sony SRF-beeld + Sony SRF råbilete + Surowy obraz SRF Sony + Imagem bruta SRF da Sony + Imagine brută Sony SRF + необработанное изображение Sony SRF + Surový obrázok Sony SRF + Surova slikovna datoteka Sony SRF + Figurë raw Sony SRF + Sony SRF-råbild + цифровий негатив SRF Sony + Ảnh thô Sony SRF + Sony SRF 原始映像 + Sony SRF 原生影像 + SRF + Sony Raw Format + + + + + + Sony SR2 raw image + صورة Sony SR2 خامة + Suvoraja vyjava Sony SR2 + Изображение — Sony SR2 raw + imatge en cru de Sony SR2 + Surový obrázek Sony SR2 + Sony SR2-råbillede + Sony-SR2-Rohbild + imagen en bruto SR2 de Sony + Sony SR2 irudi gordina + Sony-SR2-raakakuva + Sony SR2 rámynd + image brute SR2 Sony + amhíomhá Sony SR2 + imaxe en bruto SR2 de sony + תמונה גולמית של Sony SR2 + Sony SR2 nyers kép + Citra mentah Sony SR2 + Immagine raw Sony SR2 + Sony SR2 raw 画像 + Sony SR2 өңделмеген суреті + 소니 SR2 원본 이미지 + Sony SR2 neapdorotas paveikslėlis + Sony SR2 jēlattēls + Sony SR2 raw-bilde + onbewerkt Sony SR2-beeld + Sony SR2 råbilete + Surowy obraz SR2 Sony + Imagem bruta SR2 da Sony + Imagine brută Sony SR2 + необработанное изображение Sony SR2 + Surový obrázok Sony SR2 + Surova slikovna datoteka Sony SR2 + Figurë raw Sony SR2 + Sony SR2-råbild + цифровий негатив SR2 Sony + Ảnh thô Sony SR2 + Sony SR2 原始映像 + Sony SR2 原生影像 + SR2 + Sony Raw format 2 + + + + + + Sony ARW raw image + صورة Sony ARW خامة + Suvoraja vyjava Sony ARW + Изображение — Sony ARW raw + imatge en cru de Sony ARW + Surový obrázek Sony ARW + Sony ARW-råbillede + Sony-ARW-Rohbild + imagen en bruto ARW de Sony + Sony ARW irudi gordina + Sony-ARW-raakakuva + Sony ARW rámynd + image brute ARW Sony + amhíomhá Sony ARW + imaxe en bruto ARW de sony + תמונה גולמית של Sony ARW + Sony ARW nyers kép + Citra mentah Sony ARW + Immagine raw Sony ARW + Sony ARW raw 画像 + Sony ARW өңделмеген суреті + 소니 ARW 원본 이미지 + Sony ARW neapdorotas paveikslėlis + Sony ARW jēlattēls + Sony ARW raw-bilde + onbewerkt Sony ARW-beeld + Sony ARW råbilete + Surowy obraz ARW Sony + Imagem bruta ARW da Sony + Imagine brută Sony ARW + необработанное изображение Sony ARW + Surový obrázok Sony ARW + Surova slikovna datoteka Sony ARW + Figurë raw Sony ARW + Sony ARW-råbild + цифровий негатив ARW Sony + Ảnh thô Sony ARW + Sony ARW 原始映像 + Sony ARW 原生影像 + ARW + Alpha Raw format + + + + + + PNG image + صورة PNG + PNG rəsmi + Vyjava PNG + Изображение — PNG + imatge PNG + Obrázek PNG + Delwedd PNG + PNG-billede + PNG-Bild + εικόνα PNG + PNG image + PNG-bildo + imagen PNG + PNG irudia + PNG-kuva + PNG mynd + image PNG + íomhá PNG + imaxe PNG + תמונת PNG + PNG-kép + Citra PNG + Immagine PNG + PNG 画像 + PNG суреті + PNG 그림 + PNG paveikslėlis + PNG attēls + Imej PNG + PNG-bilde + PNG-afbeelding + PNG-bilete + Obraz PNG + imagem PNG + Imagem PNG + Imagine PNG + изображение PNG + Obrázok PNG + Slikovna datoteka PNG + Figurë PNG + PNG слика + PNG-bild + зображення PNG + Ảnh PNG + PNG 图像 + PNG 影像 + + + + + + + Run Length Encoded bitmap image + تشغيل صورة نقطية طولية الترميز + Bitmapnaja vyjava, zakadavanaja ŭ Run Length + Изображение — RLE Bitmap + imatge de mapa de bits «Run Lenght Encoded» + Obrázek bitové mapy Run Length Encoded + Run Length Encoded-bitmapbillede + Lauflängenkodiertes Bitmap-Bild + mapa de bits con codificación del tamaño durante la ejecución + 'Run Lenght Encoded' bitmap irudia + RLE-koodattu bittikartta + image matricielle Run Length Encoded + íomhá mhapa giotáin Run Length Encoded + mapa de bits con codificación do tamaño durante a execución + מקודד מפת סיביות של Run Length + Run Length Encoded bitkép + Citra peta bit Run Length Encoded + Immagine bitmap RLE (Run Length Encoded) + ランレングス符号化ビットマップ画像 + RLE сығылған растрлік суреті + 실행 길이 인코딩된 비트맵 그림 + Run Length Encoded rastrinis paveikslėlis + Secīgo atkārtojumu kodēts bitkartes attēls + Run Length Encoded bitmap bilde + RLE-gecodeerde bitmap-afbeelding + Run Length Encoded punktgrafikk + Obraz bitmapy RLE + Classe de comprimento imagem bitmap codificada + Imagine bitmap codată RLE + растровое изображение (сжатое RLE) + Bitmapový obrázok Run Length Encoded + Zaporedno kodirana bitna slika (RLE) + Figurë bitmap RLE (Run Length Encoded) + Körlängdskodad bitmappbild + растрове зображення RLE + Ảnh mảng mã hóa chiều dài chạy (RLE) + 游程编码位图 + Run Length Encoded 點陣影像 + + + + SVG image + صورة SVG + Vyjava SVG + Изображение — SVG + imatge SVG + Obrázek SVG + SVG-billede + SVG-Bild + SVG image + SVG-bildo + imagen SVG + SVG irudia + SVG-kuva + SVG mynd + image SVG + íomhá SVG + imaxe SVG + תמונת SVG + SVG kép + Citra SVG + Immagine SVG + SVG 画像 + SVG суреті + SVG 그림 + SVG paveikslėlis + SVG attēls + SVG-bilde + SVG-afbeelding + SVG-bilete + Obraz SVG + Imagem SVG + Imagine SVG + изображение SVG + Obrázok SVG + Slikovna vektorska datoteka SVG + Figurë SVG + SVG-bild + зображення SVG + Ảnh SVG + SVG 图像 + SVG 影像 + SVG + Scalable Vector Graphics + + + + + + + + + + compressed SVG image + صورة SVG مضغوطة + skampresavanaja vyjava SVG + Изображение — SVG, компресирано + imatge SVG comprimida + Komprimovaný obrázek SVG + SVG-komprimeret billede + Komprimiertes SVG-Bild + imagen SVG comprimida + konprimitutako SVG irudia + pakattu SVG-kuva + stappað SVG mynd + image SVG compressée + íomhá SVG comhbhrúite + imaxe SVG comprimida + תמונת SVG מכוצת + tömörített SVG kép + Citra SVG terkompresi + Immagine SVG compressa + 圧縮 SVG 画像 + сығылған SVG суреті + 압축한 SVG 그림 + suglaudintas SVG paveikslėlis + saspiests SVG attēls + komprimert SVG-bilde + ingepakte SVG-afbeelding + komprimert SVG-bilete + Skompresowany obraz SVG + Imagem compactada SVG + imagine comprimată SVG + сжатое изображение SVG + Komprimovaný obrázok SVG + Slikovna datoteka SVG (stisnjena) + Figurë SVG e kompresuar + komprimerad SVG-bild + стиснене зображення SVG + ảnh SVG đã nén + 压缩的 SVG 图像 + 壓縮版 SVG 影像 + SVG + Scalable Vector Graphics + + + + + TIFF image + صورة TIFF + Vyjava TIFF + Изображение — TIFF + imatge TIFF + Obrázek TIFF + TIFF-billede + TIFF-Bild + εικόνα TIFF + TIFF image + TIFF-bildo + imagen TIFF + TIFF irudia + TIFF-kuva + TIFF mynd + image TIFF + íomhá TIFF + imaxe TIFF + תמונת TIFF + TIFF-kép + Citra TIFF + Immagine TIFF + TIFF 画像 + TIFF суреті + TIFF 그림 + TIFF paveikslėlis + TIFF attēls + Imej TIFF + TIFF-bilde + TIFF-afbeelding + TIFF-bilete + Obraz TIFF + imagem TIFF + Imagem TIFF + Imagine TIFF + изображение TIFF + Obrázok TIFF + Slikovna datoteka TIFF + Figurë TIFF + TIFF слика + TIFF-bild + зображення TIFF + Ảnh TIFF + TIFF 图像 + TIFF 影像 + TIFF + Tagged Image File Format + + + + + + + + + AutoCAD image + صورة AutoCAD + AutoCAD rəsmi + Vyjava AutoCAD + Изображение — AutoCAD + imatge d'AutoCAD + Obrázek AutoCAD + Delwedd AutoCAD + AutoCAD-billede + AutoCAD-Bild + εικόνα AutoCAD + AutoCAD image + AutoCAD-bildo + imagen de AutoCAD + AutoCAD-eko irudia + AutoCAD-kuva + AutoCAD mynd + image AutoCAD + íomhá AutoCAD + imaxe de AutoCAD + תמונה של AutoCAD + AutoCAD-kép + Citra AutoCAD + Immagine AutoCAD + AutoCAD 画像 + AutoCAD суреті + AutoCAD 그림 + AutoCAD paveikslėlis + AutoCAD attēls + Imej AutoCAD + AutoCAD-bilde + AutoCAD-afbeelding + AutoCAD-bilete + Obraz AutoCAD + imagem AutoCAD + Imagem do AutoCAD + Imagine AutoCAD + изображение AutoCAD + Obrázok AutoCAD + Slikovna datoteka AutoCAD + Figurë AutoCAD + AutoCAD слика + AutoCAD-bild + зображення AutoCAD + Ảnh AutoCAD + AutoCAD 图像 + AutoCAD 影像 + + + + DXF vector image + صورة DXF نقطية + Vektarnaja vyjava DXF + Изображение — DXF + imatge vectorial DXF + Vektorový obrázek DXF + DXF-vektorbillede + DXF-Vektorbild + ανυσματική εικόνα DXF + DXF vector image + vektora DXF-bildo + imagen vectorial DXF + DXF bektore-grafikoa + DXF-vektorikuva + DXF vektormynd + image vectorielle DXF + íomhá veicteoir DXF + imaxe de vector DXF + תמונת DXF וקטורית + DXF-vektorkép + Citra vektor DXF + Immagine vettoriale DXF + DXF ベクター画像 + DXF векторлық суреті + DXF 벡터 그림 + DXF vektorinis paveikslėlis + DXF vektora attēls + Imej vektor DXF + DXF-vektorgrafikk + DXF-vectorafbeelding + DXF-vektorgrafikk + Obraz wektorowy DXF + imagem de vectores DXF + Imagem vetorial DXF + Imagine vectorială DXF + векторное изображение DXF + Vektorový obrázok DXF + Slikovna vektorska datoteka DXF + Figurë vektoriale DFX + DXF векторска графика + DXF-vektorbild + векторне зображення DXF + Ảnh véc-tơ DXF + DXF 矢量图像 + DXF 向量圖 + + + + + + + + Microsoft Document Imaging format + صيغة مستند تصوير مايكروسوفت + Изображение — Microsoft Document Imaging + format Microsoft Document Imaging + Formát Microsoft Document Imaging + Microsofts dokumentbilledformat + Microsoft-Document-Imaging-Bildformat + formato de imagen de Microsoft Document + Microsoft Document Imaging formatua + Microsoft Document Imaging -muoto + Microsoft Document Imaging snið + format Document Imaging Microsoft + formáid Microsoft Document Imaging + formato de Microsoft Document Imaging + פורמט של Microsoft Document Imaging + Microsoft Document Imaging formátum + Format Microsoft Document Imaging + Formato MDI (Microsoft Document Imaging) + Microsoft ドキュメントイメージフォーマット + Microsoft Document Imaging пішімі + 마이크로소프트 문서 이미지 형식 + Microsoft Document Imaging formatas + Microsoft dokumentu attēlošanas formāts + Microsoft Document Imaging + Format Microsoft Document Imaging + Formato do Microsoft Document Imaging + Format Microsoft Document Imaging + формат Microsoft Document Imaging + Formát Microsoft Document Imaging + Zapis Microsoft Document Imaging + Microsoft Document Imaging-format + формат Microsoft Document Imaging + Định dạng tạo ảnh tài liệu Microsoft + Microsoft Document Imaging 扫描图像 + 微軟文件影像格式 + MDI + Microsoft Document Imaging + + + + + + + 3D Studio image + صورة استديو ثلاثية الأبعاد + 3D Studio rəsmi + Vyjava 3D Studio + Изображение — 3D Studio + imatge de 3D Studio + Obrázek 3D Studio + Delwedd "3D Studio" + 3D Studio-billede + 3D-Studio-Bild + εικόνα 3D Studio + 3D Studio image + bildo de 3D Studio + imagen de 3D Studio + 3D Studio-ko irudia + 3D Studio -kuva + 3D Studio mynd + image 3D Studio + íomhá 3D Studio + imaxe de 3D Studio + תמונת 3D Studio + 3D Studio-kép + Citra 3D Studio + Immagine 3D Studio + 3D Studio 画像 + 3D Studio суреті + 3D Studio 그림 + 3D Studio paveikslėlis + 3D Studio attēls + Imej 3D Studio + 3D Studio-bilde + 3D-Studio-afbeelding + 3D Studio-bilete + Obraz 3D Studio + imagem 3D Studio + Imagem do 3D Studio + Imagine 3D Studio + сцена 3D Studio + Obrázok 3D Studio + Slikovna datoteka 3D Studio + Figurë 3D Studio + 3D Studio слика + 3D Studio-bild + зображення 3D Studio + Ảnh xuởng vẽ 3D + 3D Studio 图像 + 3D Studio 影像 + + + + Applix Graphics image + صورة رسوميات Applix + Vyjava Applix Graphics + Изображение — Applix Graphics + imatge d'Applix Graphics + Obrázek Applix Graphics + Applix Graphics-billede + Applix-Graphics-Bild + εικόνα Applix Graphics + Applix Graphics image + bildo de Applix Graphics + imagen de Applix Graphics + Applix Graphics irudia + Applix Graphics -kuva + Applix Graphics mynd + image Applix Graphics + íomhá Applix Graphics + imaxe de Applix Graphics + תמונה של Applix Graphics + Applix Graphics-kép + Citra Applix Graphics + Immagine Applix Graphics + Applix Graphics 画像 + Applix Graphics суреті + Applix Graphics 그림 + Applix Graphics paveikslėlis + Applix Graphics attēls + Imej Applix Graphics + Applix Graphics-dokument + Applix Graphics-afbeelding + Applix Graphics-dokument + Obraz Applix Graphics + imagem Applix Graphics + Imagem do Applix Graphics + Imagine Applix Graphics + изображение Applix Graphics + Obrázok Applix Graphics + Slikovna datoteka Applix Graphics + Figurë Applix Graphics + Applix графички документ + Applix Graphics-bild + зображення Applix Graphics + Ảnh Applix Graphics + Applix Graphics 图像 + Applix Graphics 影像 + + + + + + + + + EPS image (bzip-compressed) + صورة EPS (مضغوط-bzip) + Vyjava EPS (bzip-skampresavanaja) + Изображение — EPS, компресирано с bzip + imatge EPS (comprimida amb bzip) + Obrázek EPS (komprimovaný pomocí bzip) + EPS-billede (bzip-komprimeret) + EPS-Bild (bzip-komprimiert) + imagen EPS (comprimida con bzip) + EPS irudia (bzip-ekin konprimitua) + EPS-kuva (bzip-pakattu) + EPS mynd (bzip-stappað) + image EPS (compressée bzip) + íomhá EPS (comhbhrúite le bzip) + imaxe EPS (comprimida con bzip) + תמונת EPS (מכווץ בbzip) + EPS kép (bzip-tömörítésű) + Citra EPS (terkompresi bzip) + Immagine EPS (compressa con bzip) + EPS 画像 (bzip 圧縮) + EPS суреті (bzip-пен сығылған) + EPS 그림 (BZIP 압축) + EPS paveikslėlis (suglaudintas su bzip) + EPS attēls (saspiests ar bzip) + EPS-bilde (bzip-komprimert) + EPS-afbeelding (ingepakt met bzip) + EPS-bilete (pakka med bzip) + Obraz EPS (kompresja bzip) + Imagem EPS (compactada com bzip) + Imagine EPS (compresie bzip) + изображение EPS (сжатое bzip) + Obrázok EPS (komprimovaný pomocou bzip) + Slikovna datoteka EPS (stisnjena z bzip) + Figurë EPS (e kompresuar me bzip) + EPS-bild (bzip-komprimerad) + зображення EPS (стиснене bzip) + Ảnh EPS (đã nén bzip) + EPS 图像(bzip 压缩) + EPS 影像 (bzip 格式壓縮) + + + + + + CMU raster image + صورة CMU نقطية + CMU raster rəsmi + Rastravaja vyjava CMU + Изображение — CMU raster + imatge ràster CMU + Rastrový obrázek CMU + Delwedd raster CMU + CMU-rasterbillede + CMU-Rasterbild + εικόνα ράστερ CMU + CMU raster image + rastruma bildo de CMU + imagen ráster CMU + CMU bilbe-irudia + CMU-rasterikuva + CMU raster mynd + image raster CMU + íomhá rastar CMU + imaxe raster CMU + תמונת סריקה CMU + CMU-raszterkép + Citra raster CMU + Immagine raster CMU + CMU ラスター画像 + CMU растрлық суреті + CMU 래스터 그림 + CMU rastrinis paveikslėlis + CMU rastra attēls + Imej raster CMU + CMU-rasterbilde + CMU-rasterafbeelding + CMU rasterbilete + Obraz rastrowy CMU + imagem rasterizada CMU + Imagem raster CMU + Imagine raster CMU + растровое изображение CMU + Rastrový obrázok CMU + Slikovna rastrska datoteka CMU + Figurë raster CMU + CMU растерска слика + CMU-rasterbild + растрове зображення CMU + Ảnh mành CMU + CMU 矢量图像 + CMU raster 影像 + + + + compressed GIMP image + صورة GIMP مضغوطة + skampresavanaja vyjava GIMP + Изображение — GIMP, компресирано + imatge GIMP comprimida + Komprimovaný obrázek GIMP + komprimeret GIMP-billede + Komprimiertes GIMP-Bild + imagen GIMP comprimida + konprimitutako GIMP irudia + pakattu GIMP-kuva + stappað GIMP mynd + image GIMP compressée + íomhá GIMP comhbhrúite + imaxe de GIMP comprimida + תמונת GIMP מכווצת + tömörített GIMP kép + Citra GIMP terkompresi + Immagine GIMP compressa + 圧縮 GIMP 画像 + сығылған GIMP суреті + 압축한 GIMP 그림 + suglaudintas GIMP paveikslėlis + saspiests GIMP attēls + komprimert GIMP-bilde + ingepakte GIMP-afbeelding + komprimert GIMP-bilete + Skompresowany obraz GIMP + Imagem compactada do GIMP + imagine comprimată GIMP + сжатое изображение GIMP + Komprimovaný obrázok GIMP + Slikovna datoteka GIMP (stisnjena) + Figurë GIMP e kompresuar + komprimerad GIMP-bild + стиснене зображення GIMP + ảnh GIMP đã nén + 压缩的 GIMP 图像 + 壓縮版 GIMP 影像 + + + + + DICOM image + صورة DICOM + Vyjava DICOM + Изображение — DICOM + imatge DICOM + Obrázek DICOM + DICOM-billede + DICOM-Bild + DICOM image + DICOM-bildo + imagen DICOM + DICOM irudia + DICOM-kuva + DICOM mynd + image DICOM + íomhá DICOM + imaxe DICOM + תמונת DICOM + DICOM kép + Citra DICOM + Immagine DICOM + DICOM 画像 + DICOM суреті + DICOM 그림 + DICOM paveikslėlis + DICOM attēls + DICOM-bilde + DICOM-afbeelding + DICOM-bilete + Obraz DICOM + Imagem DICOM + Imagine DICOM + изображение DICOM + Obrázok DICOM + Slikovna datoteka DICOM + Figurë DICOM + DICOM-bild + зображення DICOM + Ảnh DICOM + DICOM 图像 + DICOM 影像 + DICOM + Digital Imaging and Communications in Medicine + + + + + + + + DocBook document + مستند DocBook + Dakument DocBook + Документ — DocBook + document DocBook + Dokument DocBook + DocBook-dokument + DocBook-Dokument + DocBook document + DocBook-dokumento + documento DocBook + DocBook dokumentua + DocBook-asiakirja + DocBook skjal + document DocBook + cáipéis DocBook + documento de DocBook + מסמך DocBook + DocBook dokumentum + Dokumen DocBook + Documento DocBook + DocBook ドキュメント + DocBook құжаты + DocBook 문서 + DocBook dokumentas + DocBook dokuments + DocBook-dokument + DocBook-document + DocBook-dokument + Dokument DocBook + Documento DocBook + Document DocBook + документ DocBook + Dokument DocBook + Dokument DocBook + Dokument DocBook + DocBook-dokument + документ DocBook + Tài liệu DocBook + DocBook 文档 + DocBook 文件 + + + + + + + + + + + + DIB image + صورة DIB + Vyjava DIB + Изображение — DIB + imatge DIB + Obrázek DIB + DIB-billede + DIB-Bild + DIB image + DIB-bildo + imagen DIB + DIB irudia + DIB-kuva + DIB mynd + image DIB + íomhá DIB + imaxe DIB + תמונת DIB + DIB kép + Citra DIB + Immagine DIB + DIB 画像 + DIB суреті + DIB 그림 + DIB paveikslėlis + DIB attēls + DIB-bilde + DIB-afbeelding + DIB-bilete + Obraz DIB + Imagem DIB + Imagine DIB + изображение DIB + Obrázok DIB + Slikovna datoteka DIB + Figurë DIB + DIB-bild + зображення DIB + Ảnh DIB + DIB 图像 + DIB 影像 + DIB + Device Independant Bitmap + + + + + + DjVu image + صورة DjVu + Vyjava DjVu + Изображение — DjVu + imatge DjVu + Obrázek DjVu + DjVu-billede + DjVu-Bild + εικόνα DjVu + DjVu image + DjVu-bildo + imagen DjVu + DjVU-ko irudia + DjVu-kuva + DjVu mynd + image DjVu + íomhá DjVu + imaxe de DjVu + תמונת DjVu + DjVu-kép + Citra DjVu + Immagine DjVu + DjVu 画像 + DjVu суреті + DjVu 그림 + DjVu paveikslėlis + DjVu attēls + Imej DjVu + DjVu-bilde + DjVu-afbeelding + DjVu-bilete + Obraz DjVu + imagem DjVu + Imagem DjVu + Imagine DjVu + изображение DjVu + Obrázok DjVu + Slikovna datoteka DjVu + Figurë DjVu + DjVu слика + DjVu-bild + зображення DjVu + Ảnh DjVu + DjVu 图像 + DjVu 影像 + + + + + + + + + + + + + + + + + DPX image + صورة DPX + Vyjava DPX + Изображение — DPX + imatge DPX + Obrázek DPX + DPX-billede + DPX-Bild + DPX image + DPX-bildo + imagen DPX + DPX irudia + DPX-kuva + DPX mynd + image DPX + íomhá DPX + imaxe DPX + תמונת DPX + DPX kép + Citra DPX + Immagine DPX + DPX 画像 + DPX суреті + DPX 그림 + DPX paveikslėlis + DPX attēls + DPX-bilde + DPX-afbeelding + DPX-bilete + Obraz DPX + Imagem DPX + Imagine DPX + изображение DPX + Obrázok DPX + Slikovna datoteka DPX + Figurë DPX + DPX-bild + зображення DPX + Ảnh DPX + DPX 图像 + DPX 影像 + DPX + Digital Moving Picture Exchange + + + + + + EPS image + صورة EPS + Vyjava EPS + Изображение — EPS + imatge EPS + Obrázek EPS + EPS-billede + EPS-Bild + EPS image + EPS-bildo + imagen EPS + EPS irudia + EPS-kuva + EPS mynd + image EPS + íomhá EPS + imaxe EPS + תמונת EPS + EPS kép + Citra EPS + Immagine EPS + EPS 画像 + EPS суреті + EPS 그림 + EPS paveikslėlis + EPS attēls + EPS-bilde + EPS-afbeelding + EPS-bilete + Obraz EPS + Imagem EPS + Imagine EPS + изображение EPS + Obrázok EPS + Slikovna datoteka EPS + Figurë EPS + EPS-bild + зображення EPS + Ảnh EPS + EPS 图像 + EPS 影像 + EPS + Encapsulated PostScript + + + + + + + + + + + + + + + FITS document + مستند FITS + Dakument FITS + Документ — FITS + document FITS + Dokument FITS + FITS-dokument + FITS-Dokument + FITS document + FITS-dokumento + documento FITS + FITS dokumentua + FITS-asiakirja + FITS skjal + document FITS + cáipéis FITS + documento FICT + מסמך FITS + FITS dokumentum + Dokumen FITS + Documento FITS + FITS ドキュメント + FITS құжаты + FITS 문서 + FITS dokumentas + FITS dokuments + FITS-dokument + FITS-document + FITS-dokument + Dokument FITS + Documento FITS + Document FITS + документ FITS + Dokument FITS + Dokument FITS + Dokument FITS + FITS-dokument + документ FITS + Tài liệu FITS + FITS 文档 + FITS 文件 + FITS + Flexible Image Transport System + + + + + + + + FPX image + صورة FPX + Vyjava FPX + Изображение — FPX + imatge FPX + Obrázek FPX + FPX-billede + FPX-Bild + FPX image + FPX-bildo + imagen FPX + FPX irudia + FPX-kuva + FPX mynd + image FPX + íomhá FPX + imaxe FPX + תמונת FPX + FPX kép + Citra FPX + Immagine FPX + FPX 画像 + FPX суреті + FPX 그림 + FPX paveikslėlis + FPX attēls + FPX-bilde + FPX-afbeelding + FPX-bilete + Obraz FPX + Imagem FPX + Imagine FPX + изображение FPX + Obrázok FPX + Slikovna datoteka FPX + Figurë FPX + FPX-bild + зображення FPX + Ảnh FPX + FPX 图像 + FPX 影像 + FPX + FlashPiX + + + + + + EPS image (gzip-compressed) + صورة EPS (مضغوط-gzip) + Vyjava EPS (gzip-skampresavanaja) + Изображение — EPS, компресирано с gzip + imatge EPS (comprimida amb gzip) + Obrázek EPS (komprimovaný pomocí gzip) + EPS-billede (gzip-komprimeret) + EPS-Bild (gzip-komprimiert) + imagen EPS (comprimida con gzip) + EPS irudia (gzip-ekin konprimitua) + EPS-kuva (gzip-pakattu) + EPS mynd (gzip-stappað) + image EPS (compressée gzip) + íomhá EPS (comhbhrúite le gzip) + imaxe EPS (comprimida con gzip) + תמונת EPS (מכווץ בgzip) + EPS kép (gzip-tömörítésű) + Citra EPS (terkompresi gzip) + Immagine EPS (compressa con gzip) + EPS 画像 (gzip 圧縮) + EPS суреті (gzip-пен сығылған) + EPS 그림 (GZIP 압축) + EPS paveikslėlis (suglaudintas su gzip) + EPS attēls (saspiests ar gzip) + EPS-bilde (gzip-komprimert) + EPS-afbeelding (ingepakt met gzip) + EPS-bilete (pakka med gzip) + Obraz EPS (kompresja gzip) + Imagem EPS (compactada com gzip) + Imagine EPS (compresie gzip) + изображение EPS (сжатое gzip) + Obrázok EPS (komprimovaný pomocou gzip) + Slikovna datoteka EPS (stisnjena z gzip) + Figurë EPS (e kompresuar me gzip) + EPS-bild (gzip-komprimerad) + зображення EPS (стиснене gzip) + Ảnh EPS (đã nén gzip) + EPS 图像(gzip 压缩) + EPS 影像 (gzip 格式壓縮) + + + + + + Microsoft icon + أيقونة مايكروسوفت + Икона — Microsoft + icona de Microsoft + Ikona Microsoft + Microsoftikon + Microsoft-Symbol + Microsoft-piktogramo + icono de Microsoft + Microsoft ikonoa + Microsoft-kuvake + Microsoft ímynd + icône Microsoft + deilbhín Microsoft + Icona de microsoft + אייקון של Microsofr + Microsoft ikon + Ikon Microsoft + Icona Microsoft + Microsoft アイコン + Microsoft таңбашасы + 마이크로소프트 아이콘 + Microsoft piktograma + Microsoft ikona + Microsoft pictogram + Ikona Microsoft + Ícone da Microsoft + Iconiță Microsoft + значок Microsoft + Ikona Microsoft + Datoteka ikone Microsoft Windows + Microsoft-ikon + піктограма Microsoft + Biểu tượng Microsoft + Microsoft 图标 + 微軟圖示 + + + + + + + + + + + + + + + MacOS X icon + أيقونة MacOS X + Ikona MacOS X + Икона — MacOS X + icona MacOS X + Ikona MacOS X + MacOS X-ikon + MacOS-X-Symbol + MacOS-X-piktogramo + icono de MacOS X + MacOS X ikonoa + MacOS X -kuvake + MacOS X ímynd + icône MacOS X + deilbhín MacOS X + Icona de MacOS X + אייקון של MacOS X + MacOS X ikon + Ikon MacOS X + Icona MacOS X + MacOS X アイコン + MacOS X таңбашасы + MacOS X 아이콘 + MacOS X piktograma + MacOS X ikona + MacOS X-ikon + MacOS-X-pictogram + MacOS X-ikon + Ikona Mac OS X + Ícone do MacOS X + Iconiță MacOS X + значок MacOS X + Ikona MacOS X + Datoteka ikone MacOS X + Ikonë MacOS X + MacOS X-ikon + піктограма MacOS X + Biểu tượng MacOS X + MacOS X 图标 + MacOS X 圖示 + + + + + + + IFF image + صورة IFF + IFF rəsmi + Vyjava IFF + Изображение — IFF + imatge IFF + Obrázek IFF + Delwedd IFF + IFF-billede + IFF-Bild + εικόνα IFF + IFF image + IFF-bildo + imagen IFF + IFF irudia + IFF-kuva + IFF mynd + image IFF + íomhá IFF + imaxe IFF + תמונת IFF + IFF-kép + Citra IFF + Immagine IFF + IFF 画像 + IFF суреті + IFF 그림 + IFF paveikslėlis + IFF attēls + Imej IFF + IFF-bilde + IFF-afbeelding + IFF-bilete + Obraz IFF + imagem IFF + Imagem IFF + Imagine IFF + изображение IFF + Obrázok IFF + Slikovna datoteka IFF + Figurë IFF + IFF слика + IFF-bild + зображення IFF + Ảnh IFF + IFF 图像 + IFF 影像 + + + + ILBM image + صورة ILBM + ILBM rəsmi + Vyjava ILBM + Изображение — ILBM + imatge ILBM + Obrázek ILMB + Delwedd ILBM + ILBM-billede + ILBM-Bild + εικόνα ILBM + ILBM image + ILBM-bildo + imagen ILBM + ILBM irudia + ILBM-kuva + ILBM mynd + image ILBM + íomhá ILBM + imaxe ILBM + תמונת ILBM + ILBM-kép + Citra ILBM + Immagine ILBM + ILBM 画像 + ILBM суреті + ILBM 그림 + ILBM paveikslėlis + ILBM attēls + Imej ILBM + ILBM-bilde + ILBM-afbeelding + ILMB-bilete + Obraz ILBM + imagem ILBM + Imagem ILBM + Imagine ILBM + изображение ILBM + Obrázok ILMB + Slikovna datoteka ILBM + Figurë ILBM + ILBM слика + ILBM-bild + зображення ILBM + Ảnh ILBM + ILBM 图像 + ILBM 影像 + ILBM image + InterLeaved BitMap + + + + JNG image + صورة JNG + JNG rəsmi + Vyjava JNG + Изображение — JNG + imatge JNG + Obrázek JNG + Delwedd JNG + JNG-billede + JNG-Bild + εικόνα JNG + JNG image + JNG-bildo + imagen JNG + JNG irudia + JNG-kuva + JNG mynd + image JNG + íomhá JNG + imaxe JNG + תמונת JNG + JNG-kép + Citra JNG + Immagine JNG + JNG 画像 + JNG суреті + JNG 그림 + JNG paveikslėlis + JNG attēls + Imej PNG + JNG-bilde + JNG-afbeelding + JNG-bilete + Obraz JNG + imagem JNG + Imagem JNG + Imagine JNG + изображение JNG + Obrázok JNG + Slikovna datoteka JNG + Figurë JNG + JNG слика + JNG-bild + зображення JNG + Ảnh JNG + JNG 图像 + JNG 影像 + JNG + JPEG Network Graphics + + + + LightWave object + كائن LightWave + LightWave cismi + Abjekt LightWave + Обект — LightWave + objecte de LightWave + Objekt LightWave + Gwrthrych LightWave + LightWave-objekt + LightWave-Objekt + αντικείμενο LightWave + LightWave object + LightWave-objekto + objeto LightWave + LightWave objektua + LightWave-esine + LightWave lutur + objet LightWave + réad LightWave + obxecto de LightWave + עצם LightWave + LightWave-objektum + Proyek LightWave + Oggetto LightWave + LightWave オブジェクト + LightWave объекті + LightWave 개체 + LightWave objektas + LightWave objekts + Objek LightWave + LightWave-objekt + LightWave-object + LightWave-objekt + Obiekt LightWave + Objecto LightWave + Objeto LightWave + Obiect LightWave + объект LightWave + Objekt LightWave + Datoteka predmeta LightWave + Objekt LightWave + LightWave објекат + LightWave-objekt + об'єкт LightWave + Đối tượng LightWave + LightWave 对象 + LightWave 物件 + + + + + LightWave scene + مشهد LightWave + LightWave səhnəsi + Scena LightWave + Сцена — LightWave + escena de LightWave + Scéna LightWave + Golygfa LightWave + LightWave-scene + LightWave-Szene + σκηνή LightWave + LightWave scene + LightWave-sceno + escena LightWave + LightWave eszena + LightWave-maisema + LightWave leikmynd + scène LightWave + radharc LightWave + escena de LightWave + סצנה של LightWave + LightWave-jelenet + Scene LightWave + Scena LightWave + LightWave シーン + LightWave сахнасы + LightWave 장면 + LightWave scena + LightWave aina + Babak LightWave + LightWave-scene + LightWave-scène + LightWave-scene + Scena Lightwave + cenário LightWave + Cena LightWave + Scenă LightWave + сцена LightWave + Scéna LightWave + Datoteka scene LightWave + Skenë LightWave + LightWave сцена + LightWave-scen + сцена LightWave + Cảnh LightWave + LightWave 场景 + LightWave 場景 + + + + MacPaint Bitmap image + صورة MacPaint Bitmap + Bitmapnaja vyjava MacPaint + Изображение — MacPaint Bitmap + imatge de mapa de bits MacPaint + Obrázek MacPaint Bitmap + MacPaint BitMap-billede + MacPaint-Bitmap-Datei + imagen en mapa de bits de MacPaint + MacPaint Bitmap irudia + MacPaint-bittikartta + MacPaint Bitmap mynd + image matricielle MacPaint + íomhá MacPaint Bitmap + imaxe de mapa de bits MacPaint + תמונת מפת-סיביות של MacPaint + MacPaint bitkép + Citra MacPaint Bitmap + Immagine Bitmap MacPaint + MacPaint ビットマップ画像 + MacPaint растрлық суреті + 맥페인트 비트맵 그림 + MacPaint rastrinis paveikslėlis + MacPaint bitkartes attēls + MacPaint Bitmap-bilde + MacPaint-bitmap-afbeelding + MacPaint punktbilete + Obraz bitmapowy MacPaint + Imagem de bitmap do MacPaint + Imagine MacPaint Bitmap + растровое изображение MacPaint + Obrázok MacPaint Bitmap + Slikovna bitna datoteka MacPaint + Figurë BitMap MacPaint + MacPaint Bitmap-bild + растрове зображення MacPaint + Ảnh mảng MacPaint + MacPaint 位图 + MacPaint 點陣影像 + + + + Office drawing + تصميم أوفيس + Ofisny rysunak + Чертеж — Office + dibuix d'Office + Kresba Office + Officetegning + Office-Zeichnung + Office drawing + dibujo de Office + Office marrazkia + Office-piirros + Office tekning + dessin Office + líníocht Office + debuxo de Office + ציור של Office + Office rajz + Gambar Office + Disegno Office + Office ドロー + Office суреті + 오피스 드로잉 + Office piešinys + Office zīmējums + Office-tegning + Office-tekening + Office-teikning + Rysunek Office + Desenho do Office + Desen Office + изображение Office + Kresba Office + Datoteka risbe Office + Vizatim Office + Office-teckning + малюнок Office + Bản vẽ Office + Microsoft Office 绘图 + Office 繪圖 + + + + NIFF image + صورة NIFF + Vyjava NIFF + Изображение — NIFF + imatge NIFF + Obrázek NIFF + NIFF-billede + NIFF-Bild + NIFF-bildo + imagen NIFF + NIFF irudia + NIFF-kuva + NIFF mynd + image NIFF + íomhá NIFF + imaxe NIFF + תמונת NIFF + NIFF kép + Citra NIFF + Immagine NIFF + NIFF 画像 + NIFF суреті + NIFF 그림 + NIFF paveikslėlis + NIFF attēls + NIFF-bilde + NIFF-afbeelding + NIFF-bilete + Obraz NIFF + Imagem NIFF + Imagine NIF + изображение NIFF + Obrázok NIFF + Slikovna datoteka NIFF + Figurë NIFF + NIFF-bild + зображення NIFF + Ảnh NIFF + NIFF 图像 + NIFF 影像 + + + + + + PCX image + صورة PCX + Vyjava PCX + Изображение — PCX + imatge PCX + Obrázek PCX + PCX-billede + PCX-Bild + PCX image + PCX-bildo + imagen PCX + PCX irudia + PCX-kuva + PCX mynd + image PCX + íomhá PCX + imaxe PCX + תמונת PCX + PCX kép + Citra PCX + Immagine PCX + PCX 画像 + PCX суреті + PCX 그림 + PCX paveikslėlis + PCX attēls + PCX-bilde + PCX-afbeelding + PCX-bilete + Obraz PCX + Imagem PCX + Imagine PCX + изображение PCX + Obrázok PCX + Slikovna datoteka PCX + Figurë PCX + PCX-bild + зображення PCX + Ảnh PCX + PCX 图像 + PCX 影像 + PCX + PiCture eXchange + + + + + + + + + + + + PCD image + صورة PCD + Vyjava PCD + Изображение — PCD + imatge PCD + Obrázek PCD + PCD-billede + PCD-Bild + PCD image + PCD-bildo + imagen PCD + PCD irudia + PCD-kuva + PCD mynd + image PCD + íomhá PCD + imaxe PCD + תמונת PCD + PCD kép + Citra PCD + Immagine PCD + PCD 画像 + PCD суреті + PCD 그림 + PCD paveikslėlis + PCD attēls + PCD-bilde + PCD-afbeelding + PCD-bilete + Obraz PCD + Imagem PCD + Imagine PCD + изображение PCD + Obrázok PCD + Slikovna datoteka PCD + Figurë PCD + PCD-bild + зображення PCD + Ảnh PCD + PCD 图像 + PCD 影像 + PCD + PhotoCD + + + + PNM image + صورة PNM + PNM rəsmi + Vyjava PNM + Изображение — PNM + imatge PNM + Obrázek PNM + Delwedd PNM + PNM-billede + PNM-Bild + εικόνα PNM + PNM image + PNM-bildo + imagen PNM + PNM irudia + PNM-kuva + PNM mynd + image PNM + íomhá PNM + imaxe PNM + תמונת PNM + PNM-kép + Citra PNM + Immagine PNM + PNM 画像 + PNM суреті + PNM 그림 + PNM paveikslėlis + PNM attēls + Imej PNM + PNM-bilde + PNM-afbeelding + PNM-bilete + Obraz PNM + imagem PNM + Imagem PNM + Imagine PNM + изображение PNM + Obrázok PNM + Slikovna datoteka PNM + Figurë PNM + PNM слика + PNM-bild + зображення PNM + Ảnh PNM + PNM 图像 + PNM 影像 + + + + PBM image + صورة PBM + Vyjava PBM + Изображение — PBM + imatge PBM + Obrázek PBM + Delwedd PBM + PBM-billede + PBM-Bild + PBM image + PBM-bildo + imagen PBM + PBM irudia + PBM-kuva + PBM mynd + image PBM + íomhá PBM + imaxe PBM + תמונת PBM + PBM kép + Citra PBM + Immagine PBM + PBM 画像 + PBM суреті + PBM 그림 + PBM paveikslėlis + PBM attēls + PBM-bilde + PBM-afbeelding + PBM-bilete + Obraz PBM + Imagem PBM + Imagine PBM + изображение PBM + Obrázok PBM + Slikovna datoteka PBM + Figurë PBM + PBM слика + PBM-bild + зображення PBM + Ảnh PBM + PBM 图像 + PBM 影像 + PBM + Portable BitMap + + + + + + + + + + + + + + + + + + + PGM image + صورة PGM + Vyjava PGM + Изображение — PGM + imatge PGM + Obrázek PGM + Delwedd PGM + PGM-billede + PGM-Bild + PGM image + PGM-bildo + imagen PGM + PGM irudia + PGM-kuva + PGM mynd + image PGM + íomhá PGM + imaxe PGM + תמונת PGM + PGM kép + Citra PGM + Immagine PGM + PGM 画像 + PGM суреті + PGM 그림 + PGM paveikslėlis + PGM attēls + PGM-bilde + PGM-afbeelding + PGM-bilete + Obraz PGM + Imagem PGM + Imagine PGM + изображение PGM + Obrázok PGM + Slikovna datoteka PGM + Figurë PGM + PGM-bild + зображення PGM + Ảnh PGM + PGM 图像 + PGM 影像 + PGM + Portable GrayMap + + + + + + + + + + + + + + + + + + + PPM image + صورة PPM + Vyjava PPM + Изображение — PPM + imatge PPM + Obrázek PPM + Delwedd PPM + PPM-billede + PPM-Bild + PPM image + PPM-bildo + imagen PPM + PPM irudia + PPM-kuva + PPM mynd + image PPM + íomhá PPM + imaxe PPM + תמונת PPM + PPM kép + Citra PPM + Immagine PPM + PPM 画像 + PPM суреті + PPM 그림 + PPM paveikslėlis + PPM attēls + PPM-bilde + PPM-afbeelding + PPM-bilete + Obraz PPM + Imagem PPM + Imagine PPM + изображение PPM + Obrázok PPM + Slikovna datoteka PPM + Figurë PPM + PPM слика + PPM-bild + зображення PPM + Ảnh PPM + PPM 图像 + PPM 影像 + PPM + Portable PixMap + + + + + + + + + + + + + + + + + + + Photoshop image + صورة فوتوشوب + Изображение — Photoshop + imatge de Photoshop + Obrázek Photoshop + Photoshop-billede + Photoshop-Bild + εικόνα Photoshop + Photoshop-bildo + imagen de Photoshop + Photoshop irudia + Photoshop-kuva + Photoshop mynd + image Photoshop + íomhá Photoshop + imaxe de Photoshop + תמונת Photoshop + Photoshop-kép + Citra Photoshop + Immagine Photoshop + Photoshop 画像 + изображение Photoshop + 포토샵 이미지 + Photoshop paveikslėlis + Photoshop attēls + Imej Photoshop + Photoshop-afbeelding + Obraz Photoshop + imagem do Photoshop + Imagem do Photoshop + Imagine Photoshop + изображение Photoshop + Obrázok Photoshop + Slikovna datoteka Photoshop + Фотошоп слика + Photoshop-bild + зображення Photoshop + Ảnh Photoshop + Photoshop 图像 + Photoshop 影像 + + + + + + + + RGB image + صورة RGB + RGB rəsmi + Vyjava RGB + Изображение — RGB + imatge RGB + Obrázek RGB + Delwedd RGB + RGB-billede + RGB-Bild + εικόνα RGB + RGB image + RGB-bildo + imagen RGB + RGB irudia + RGB-kuva + RGB mynd + image RGB + íomhá RGB + imaxe RGB + תמונת RGB + RGB-kép + Citra RGB + Immagine RGB + RGB 画像 + RGB суреті + RGB 그림 + RGB paveikslėlis + RGB attēls + Imej RGB + RGB-bilde + RGB-afbeelding + RGB-bilete + Obraz RGB + imagem RGB + Imagem RGB + Imagine RGB + изображение RGB + Obrázok RGB + Slikovna datoteka RGB + Figurë RGB + RGB слика + RGB-bild + зображення RGB + Ảnh kiểu RGB + RGB 图像 + RGB 影像 + + + + SGI image + صورة SGI + Vyjava SGI + Изображение — SGI + imatge SGI + Obrázek SGI + SGI-billede + SGI-Bild + SGI image + SGI-bildo + imagen SGI + SGI irudia + SGI-kuva + SGI mynd + image SGI + íomhá SGI + imaxe SGI + תמונת SGI + SGI kép + Citra SGI + Immagine SGI + SGI 画像 + SGI суреті + SGI 그림 + SGI paveikslėlis + SGI attēls + SGI-bilde + SGI-afbeelding + SGI-bilete + Obraz SGI + Imagem SGI + Imagine SGI + изображение SGI + Obrázok SGI + Slikovna datoteka SGI + Figurë SGI + SGI-bild + зображення SGI + Ảnh SGI + SGI 图像 + SGI 影像 + + + + Sun raster image + صورة Sun raster + Rastravaja vyjava Sun + Изображение — Sun raster + imatge ràster Sun + Rastrový obrázek Sun + Sun rasterbillede + Sun-Rasterbild + imagen ráster de Sun + Sun raster irudia + Sun-rasterikuva + Sun raster mynd + image raster Sun + íomhá rastar Sun + imaxe ráster de Sun + תמונה סרוקה של Sun + SUN raszterkép + Citra raster Sun + Immagine raster Sun + Sun ラスタ画像 + Sun растрлық суреті + Sun 래스터 그림 + Sun rastrinis paveikslėlis + Sun rastra attēls + Sun rasterbilde + Sun-rasterafbeelding + Sun rasterbilete + Obraz rastrowy Sun + Imagem raster da Sun + Imagine rasterizată Sun + растровое изображение Sun + Rastrový obrázok Sun + Slikovna rastrska datoteka Sun + Figurë raster Sun + Sun-rasterbild + растрове зображення Sun + Ảnh mành Sun + Sun 光栅图像 + Sun raster 影像 + + + + + + + TGA image + صورة TGA + Vyjava TGA + Изображение — TGA + imatge TGA + Obrázek TGA + TGA-billede + TGA-Bild + TGA image + TGA-bildo + imagen TGA + TGA irudia + TGA-kuva + TGA mynd + image TGA + íomhá TGA + imaxe TGA + תמונת TGA + TGA kép + Citra TGA + Immagine TGA + TGA 画像 + TGA суреті + TGA 그림 + TGA paveikslėlis + TGA attēls + TGA-bilde + TGA-afbeelding + TGA-bilete + Obraz TGA + Imagem TGA + Imagine TGA + изображение TGA + Obrázok TGA + Slikovna datoteka TGA + Figurë TGA + TGA-bild + зображення TGA + Ảnh TGA + TGA 图像 + TGA 影像 + TGA + Truevision Graphics Adapter + + + + + + + + + + + + + + + + + Windows cursor + مؤشر ويندوز + Kursor Windows + Курсор — Windows + cursor de Windows + Kurzor Windows + Windowsmarkør + Windows-Cursor + δείκτης παραθυρικού περιβάλλοντος + Windows cursor + Windows-kursoro + cursor de Windows + Windows kurtsorea + Windows-osoitin + Windows vísi + curseur Windows + cúrsóir Windows + Cursor de Windows + סמן של Windows + Windows-kurzor + Kursor Windows + Cursore Windows + Windows カーソル + Windows курсоры + 윈도우 커서 + Windows žymiklis + Windows kursors + Kursor Windows + Windows-markør + Windows-muisaanwijzer + Windows-peikar + Kursor Windows + cursor Windows + Cursor do Windows + Cursor Windows + курсор Windows + Kurzor Windows + Datoteka kazalke Windows + Kursor Windows + Виндуз курзор + Windows-muspekare + курсор Windows + Con chạy Windows + Windows 光标 + Windows 滑鼠指標 + + + + + + + + + Windows animated cursor + مؤشر ويندوز المتحرك + Animavany kursor Windows + Курсор — Windows, анимиран + cursor animat de Windows + Animovaný kurzor Windows + Windowsanimeret markør + Animierter Windows-Cursor + cursor animado de Windows + Windows-eko kurtsore animatua + animoitu Windows-osoitin + Windows livindaigjørdur vísi + curseur animé Windows + cúrsóir beo Windows + Cursor animado de Windows + סמן מונפש של Windows + Windows animált kurzor + Kursor animasi Windows + Cursore animato Windows + Windows アニメーションカーソル + Windows анимациясы бар курсор + 윈도우 움직이는 커서 + Animuotas Windows žymiklis + Windows animēts kursors + geanimeerde Windows-muisaanwijzer + Windows animert peikar + Animowany kursor Windows + Cursor animado do Windows + Cursor animat Windows + анимированный курсор Windows + Animovaný kurzor Windows + Datoteka animirane kazalke Windows + Kursor i animuar Windows + Animerad Windows-muspekare + анімований курсор Windows + Con chạy hoạt họa Windows + Windows 动画光标 + Windows 滑鼠動畫游標 + + + + + + + + + EMF image + صورة EMF + Vyjava EMF + Изображение — EMF + imatge EMF + Obrázek EMF + EMF-billede + EMF-Bild + EMF-bildo + imagen EMF + EMF irudia + EMF-kuva + EMF mynd + image EMF + íomhá EMF + imaxe EMF + תמונת EMF + EMF kép + Citra EMF + Immagine EMF + EMF 画像 + EMF суреті + EMF 그림 + EMF paveikslėlis + EMF attēls + EMF-bilde + EMF-afbeelding + EMF-bilete + Obraz EMF + Imagem EMF + Imagine EMF + изображение EMF + Obrázok EMF + Slikovna datoteka EMF + Figurë EMF + EMF-bild + зображення EMF + Ảnh EMF + EMF 图像 + EMF 影像 + EMF + Enhanced MetaFile + + + + + + + + + + + + + WMF image + صورة WMF + Vyjava WMF + Изображение — WMF + imatge WMF + Obrázek WMF + WMF-billede + WMF-Bild + WMF-bildo + imagen WMF + WMF irudia + WMF-kuva + WMF mynd + image WMF + íomhá WMF + imaxe WMF + תמונת WMF + WMF kép + Citra WMF + Immagine WMF + WMF 画像 + WMF суреті + WMF 그림 + WMF paveikslėlis + WMF attēls + WMF-bilde + WMF-afbeelding + WMF-bilete + Obraz WMF + Imagem WMF + Imagine WMF + изображение WMF + Obrázok WMF + Slikovna datoteka WMF + Figurë WMF + WMF-bild + зображення WMF + Ảnh WMF + WMF 图像 + WMF 影像 + WMF + Windows Metafile + + + + + + + + + + + + + + + + + XBM image + صورة XBM + Vyjava XBM + Изображение — XBM + imatge XBM + Obrázek XBM + XBM-billede + XBM-Bild + XBM image + XBM-bildo + imagen XBM + XBM irudia + XBM-kuva + XBM mynd + image XBM + íomhá XBM + imaxe XBM + תמונת XBM + XBM-kép + Citra XBM + Immagine XBM + XBM 画像 + XBM суреті + XBM 그림 + XBM paveikslėlis + XBM attēls + XBM-bilde + XBM-afbeelding + XBM-bilete + Obraz XBM + Imagem XBM + Imagine XBM + изображение XBM + Obrázok XBM + Slikovna datoteka XBM + Figurë XBM + XBM-bild + зображення XBM + Ảnh XBM + XBM 图像 + XBM 影像 + XBM + X BitMap + + + + GIMP image + صورة GIMP + Vyjava GIMP + Изображение — GIMP + imatge del GIMP + Obrázek GIMP + GIMP-billede + GIMP-Bild + εικόνα GIMP + GIMP image + GIMP-bildo + imagen del GIMP + GIMP irudia + GIMP-kuva + GIMP mynd + image GIMP + íomhá GIMP + imaxe de GIMP + תמונת GIMP + GIMP-kép + Citra GIMP + Immagine GIMP + GIMP 画像 + GIMP суреті + GIMP 그림 + GIMP paveikslėlis + GIMP attēls + Imej GIMP + GIMP-bilde + GIMP-afbeelding + GIMP-bilete + Obraz GIMP + imagem do GIMP + Imagem do GIMP + Imagine GIMP + изображение GIMP + Obrázok GIMP + Slikovna datoteka GIMP + Figurë GIMP + Гимп слика + GIMP-bild + зображення GIMP + Ảnh GIMP + GIMP 图像 + GIMP 影像 + + + + + + + XFig image + صورة XFig + Vyjava XFig + Изображение — XFig + imatge de XFig + Obrázek XFig + XFig-billede + XFig-Bild + εικόνα XFig + XFig image + XFig-bildo + imagen de XFig + XFig irudia + XFig-kuva + XFig mynd + image XFig + íomhá XFig + imaxe de XFig + תמונת XFig + XFig-kép + Citra XFig + Immagine XFig + XFig 画像 + XFig суреті + XFig 그림 + XFig paveikslėlis + XFig attēls + Imej XFig + XFig-bilde + XFig-afbeelding + XFig-bilete + Obraz XFig + imagem XFig + Imagem do XFig + Imagine XFig + изображение XFig + Obrázok XFig + Slikovna datoteka XFig + Figurë XFig + XFig слика + XFig-bild + зображення XFig + Ảnh XFig + XFig 图像 + XFig 影像 + + + + + + + XPM image + صورة XPM + Vyjava XPM + Изображение — XPM + imatge XPM + Obrázek XPM + Delwedd XPM + XPM-billede + XPM-Bild + XPM image + XPM-bildo + imagen XPM + XPM irudia + XPM-kuva + XPM mynd + image XPM + íomhá XPM + imaxe XPM + תמונת XPM + XPM kép + Citra XPM + Immagine XPM + XPM 画像 + XPM суреті + XPM 그림 + XPM paveikslėlis + XPM attēls + XPM-bilde + XPM-afbeelding + XPM-bilete + Obraz XPM + Iimagem XPM + Imagine XPM + изображение XPM + Obrázok XPM + Slikovna datoteka XPM + Figurë XPM + XPM-bild + зображення XPM + Ảnh XPM + XPM 图像 + XPM 影像 + XPM + X PixMap + + + + + + + X window image + صورة X window + X window rəsmi + Vyjava vakna X + Изображение — X Window + imatge de X window + Obrázek X window + Delwedd ffenest X + X-billede + X-Window-Bild + εικόνα περιβάλλοντος X + X window image + bildo de X window + imagen de X window + X window irudia + X-ikkunakuva + X vindeyga mynd + image X window + íomhá fhuinneog X + imaxe de X Window + תמונת חלון של X + X window-kép + Citra X window + Immagine X window + X window 画像 + X window суреті + X 윈도우 그림 + X window paveikslėlis + X window attēls + Imej tetingkap X + X-Windows skjermbilde + X-window-afbeelding + X window bilete + Obraz X Window + imagem de janela X + Imagem de janela do X + Imagine X window + изображение X window + Obrázok X window + slika X oken + Figurë X window + X прозор слика + X-fönsterbild + зображення X window + Ảnh cửa sổ X + X window 图像 + X window 影像 + + + + block device + جهاز كتلي + blokavaja pryłada + Блоково устройство + dispositiu de blocs + Blokové zařízení + blokenhed + Blockorientiertes Gerät + συσκευή block + block device + bloka disponaĵo + dispositivo de bloques + bloke-gailua + laitetiedosto + blokka tóleind + périphérique de blocs + gléas bloc + dispositivo de bloque + התקן בלוק + blokkos eszköz + blok divais + Device a blocchi + ブロックデバイス + блоктық құрылғысы + 블럭 장치 + blokinis įrenginys + bloka ierīce + Peranti blok + blokkenhet + blok-apparaat + blokk-eining + Urządzenie blokowe + dispositivo de bloco + Dispositivo de bloco + dispozitiv bloc + блочное устройство + Blokové zariadenie + bločna naprava + device me blloqe + блок уређај + blockenhet + блоковий пристрій + thiết bị khối + 块设备 + 區塊裝置 + + + character device + جهاز حرفي + znakavaja pryłada + Символно устройство + dispositiu de caràcters + Znakové zařízení + tegnenhed + Zeichenorientiertes Gerät + συσκευή χαρακτήρων + character device + signa disponaĵo + dispositivo de caracteres + karaktereen gailua + merkkilaite + stavatóleind + périphérique de caractères + gléas carachtar + dispositivo de caracter + התקן תכונה + karakteres eszköz + karakter divais + Device a caratteri + キャラクタデバイス + символдық құрылғысы + 문자 장치 + simbolinis įrenginys + rakstzīmju ierīce + Peranti aksara + tegnenhet + byte-apparaat + teikneining + Urządzenie znakowe + dispositivo de caracteres + dispositivo de caractere + dispozitiv caracter + символьное устройство + Znakové zariadenie + znakovna naprava + device me karaktere + знаковни уређај + teckenenhet + символьний пристрій + thiết bị ký tự + 字符设备 + 字元裝置 + + + folder + مجلّد + kataloh + Папка + carpeta + Složka + mappe + Ordner + φάκελος + folder + dosierujo + carpeta + karpeta + kansio + mappa + dossier + fillteán + cartafol + תיקייה + mappa + folder + Cartella + フォルダー + бума + 폴더 + aplankas + mape + Folder + mappe + map + mappe + Katalog + pasta + pasta + dosar + папка + Priečinok + mapa + Kartelë + директоријум + mapp + тека + thư mục + 文件夹 + 資料夾 + + + + pipe + إنبوب + kanvejer + Конвейер + conducte + Roura + datakanal + Pipe + σωλήνωση + pipe + dukto + tubería + kanalizazioa + putki + rør + tube + píopa + tubería + צינור + adatcsatorna + pipa + Pipe + パイプ + арна + 파이프 + konvejeris + programmkanāls + Paip + rør + pijp + røyr + Potok + canal + pipe + canal pipe + канал + Rúra + cev + Pipe + цев + rör + канал + ống dẫn + 管道 + 管線 + + + mount point + نقطة الوصْل + punkt mantavańnia + Точка на монтиране + punt de muntatge + Místo připojení + monteringspunkt + Einhängepunkt + σημείο προσάρτησης + mount point + surmetingo + punto de montaje + muntatze-puntua + liitospiste + ísetingarpunkt + point d'accès + pointe feistithe + punto de montaxe + נקודת עיגון + csatolási pont + titik mount + Punto di mount + マウントポイント + тіркеу нүктесі + 마운트 위치 + prijungimo taškas + montēšanas punkts + Titik lekapan + monteringspunkt + aankoppelingspunt + monteringspunkt + Punkt montowania + ponto de montagem + ponto de montagem + loc montare + точка монтирования + Miesto pripojenia + priklopna točka + Pikë montimi + тачка прикључења + monteringspunkt + точка монтування + điểm lắp + 挂载点 + 掛載點 + + + + socket + مقبس + sokiet + Гнездо + sòcol + Socket + sokkel + Socket + υποδοχή + socket + kontaktoskatolo + socket + socketa + pistoke + sokkul + connecteur réseau + soicéad + socket + נקודת חיבור + illesztőpont + soket + Socket + ソケット + сокет + 소켓 + lizdas + sokets + Soket + plugg + socket + sokkel + Gniazdo + 'socket' + socket + socket + сокет + Soket + vtič + Socket + сокет + uttag + сокет + ổ cắm + 套接字 + socket + + + symbolic link + وصلة رمزية + simvolik körpü + symbalnaja spasyłka + Символна връзка + enllaç simbòlic + Symbolický odkaz + cyswllt symbolaidd + symbolsk henvisning + Symbolische Verknüpfung + συμβολικός σύνδεσμος + symbolic link + simbola ligilo + enlace simbólico + esteka sinbolikoa + symbolinen linkki + tykislig leinkja + lien symbolique + nasc siombalach + ligazón simbólica + קישור סימבולי + szimbolikus link + taut simbolik + Collegamento simbolico + シンボリックリンク + символдық сілтеме + 심볼릭 링크 + simbolinė nuoroda + simboliskā saite + Pautan simbolik + symbolsk lenke + symbolische koppeling + symbolsk lenkje + Dowiązanie symboliczne + ligação simbólica + ligação simbólica + legătură simbolică + символьная ссылка + Symbolický odkaz + simbolna povezava + Lidhje simbolike + симболичка веза + symbolisk länk + символічне посилання + liên kết tượng trưng + 符号链接 + 符號鏈結 + + + mail delivery report + تقرير تسليم البريد + poçt yollama raportu + rapart ab dastaŭcy pošty + Отчет за пристигналата поща + informe de lliurament de correu + Zpráva o doručení pošty + Adroddiad trosgludo post + postleveringsrapport + E-Mail-Zustellungsbericht + αναφορά παράδοσης μηνύματος + mail delivery report + raporto pri transdono de retpoŝto + informe de entrega de correo + posta banaketako txostena + viestin jakeluilmoitus + post útberingarfrásøgn + rapport de livraison de courriels + tuairisc sheachadadh poist + informe de entrega de correo + דוח העברת דואר + jelentés levélkézbesítésről + laporan pengantaran surat + Rapporto di consegna posta + メール配送ポート + пошта жеткізілгені туралы отчет + 메일 배달 보고서 + pašto pristatymo ataskaita + pasta piegādes atskaite + Laporan penghantaran mel + e-postleveranserapport + e-mail-bezorgingsbericht + e-post-leveringsrapport + Raport z dostarczenia poczty + relatório de entrega de e-mail + relatório de entrega de correspondência + raport de trimitere email + отчёт о доставке сообщения + Správa o doručení pošty + poročilo dostave pošte + Raport mbi dorëzimin e mesazhit + извештај доставе поруке + e-postleveransrapport + звіт про доставку пошти + thông báo phát thư + 邮件投递报告 + 郵件寄送回報 + + + + + mail disposition report + تقرير ترتيب البريد + poçt qayıtma raportu + rapart ab raźmiaščeńni pošty + Отчет за състоянието на пощата + informe de disposició de correu + Zpráva o předání pošty + adroddiad ffurf post + postdisponeringsrapport + E-Mail-Übertragungsbericht + αναφορά διάθεσης μηνύματος + mail disposition report + raporto pri dispono de retpoŝto + informe de disposición de correo + posta joerako txostena + viestin kuittausilmoitus + post avhendingarfrásøgn + rapport de disposition de courriels + tuairisc chóiriú poist + informe de disposición de correo + דוח אספקת דואר + jelentés levélkidobásról + laporan disposisi surat + Rapporto di disposizione posta + メール停止レポート + пошта жылжытылғаны туралы отчет + 메일 처리 보고서 + pašto charakteristikos ataskaita + pasta izvietojuma atskaite + Laporan pelupusan mel + e-postdispositionsrapport + e-mail-plaatsingsbericht + e-post-disposisjonsrapport + Raport z wysyłania poczty + relatório de disposição de e-mail + relatório de disposição de correspondência + confirmare primire email + отчёт о перемещении почты + Správa o odovzdaní pošty + poročilo razporeditve pošte + Raport mbi njoftimin e mesazhit + извештај слања поруке + e-postdispositionsrapport + звіт про розташування пошти + thông báo chuyển nhượng thư + 邮件接收报告 + 郵件處置回報 + + + + + reference to remote file + مرجع إلى ملف بعيد + uzaq fayla göstəriş + spasyłka da addalenaha fajłu + Препратка към отдалечен файл + referència a fitxer remot + Odkaz na vzdálený soubor + cyfeiriad at ffeil bell + reference til fjern fil + Verweis auf entfernte Datei + αναφορά σε απόμακρο αρχείο + reference to remote file + referenco al fora dosiero + referencia a un archivo remoto + erreferentzia urruneko fitxategiari + viittaus etätiedostoon + tilvísing til fjarfílu + référence au fichier distant + tagairt do chomhad cianda + referencia a un ficheiro remoto + התיחסות לקובץ מרוחק + hivatkozás távoli fájlra + referensi ke berkas jarak jauh + Riferimento a file remoto + リモートファイルへの参照 + қашықтағы файлға сілтеме + 원격 파일 참조 + nuoroda į nutolusį failą + norāde uz attālinātu failu + Rujukan ke fail jauh + referanse til ekstern fil + verwijzing naar bestand op afstand + referanse til fil over nettverk + Odwołanie do pliku zdalnego + referência a um ficheiro remoto + referência a um arquivo remoto + referință fișier la distanță + ссылка на удалённый файл + Odkaz na vzdialený súbor + sklic do oddaljene datoteke + Referim për tek file në distancë + референца на удаљену датотеку + referens till fjärrfil + посилання на віддалений файл + tham chiếu đến tập tin ở xa + 到远程文件的引用 + 遠端檔案的參照 + + + + Usenet news message + رسالة أخبار Usenet + Usenet xəbərlər ismarışı + Navina Usenet + Съобщение — Usenet + missatge de notícies Usenet + Příspěvek do diskusních skupin Usenet + Neges newyddion Usenet + Usenetnyhedsmeddelelse + Usenet-News-Nachricht + μήνυμα ομάδων συζητήσεων Usenet + Usenet news message + novaĵmesaĝo de Usenet + mensaje de noticias de Usenet + Usenet berrien mezua + nyyssiviesti + Usenet news boð + message de groupe d'échange Usenet + teachtaireacht nuacht Usenet + mensaxes de noticias de Usenet + הודעת חדשות של Usenet + USENET-hírcsoportüzenet + Pesan berita Usenet + Messaggio news Usenet + Usenet news メッセージ + Usenet жаңалық мәлімдемесі + 유즈넷 뉴스 메시지 + Usenet naujienų žinutė + Usenet jaunumu ziņojums + Mesej berita USENET + Usenet nyhetsmelding + Usenet-nieuwsbericht + USENET diskusjonsmelding + Wiadomość grupy dyskusyjnej + mensagem de notícias Usenet + Mensagem de notícias da Usenet + Mesaj Usenet de știri + новостное сообщение Usenet + Príspevok do diskusných skupín Usenet + novičarsko sporočilo Usenet + Mesazh lajmesh Usenet + Порука са дискусионе групе + Usenet-diskussionsgruppsmeddelande + повідомлення новин Usenet + Thông điệp tin tức USENET + Usenet 新闻信 + Usenet 新聞訊息 + + + + + + + + + + partial email message + رسالة البريد الإلكتروني الجزئية + qismi poçt ismarışı + niapoŭny list email + Част от електронно писмо + missatge de correu electrònic parcial + Částečná e-mailová zpráva + darn o neges e-bost + delvis postmeddelelse + E-Mail-Nachrichtenfragment + τμηματικό ηλ. μήνυμα + partial email message + parta retpoŝta mesaĝo + mensaje de correo electrónico parcial + posta mezu partziala + osittainen sähköpostiviesti + message partiel de courriel + teachtaireacht ríomhphoist neamhiomlán + mensaxe de correo electrónico parcial + מסר דוא"ל חלקי + részleges elektronikus levél + pesan email sebagian + Messaggio email parziale + 部分メールメッセージ + электронды поштаның үзінді мәлімдемесі + 부분적인 전자메일 메시지 + nepilnas el. laiškas + daļēja e-pasta vēstule + Bahagian mesej emel + del av e-postmelding + gedeeltelijk e-mailbericht + del av e-post-melding + Częściowa wiadomość e-mail + mensagem parcial de e-mail + mensagem de e-mail parcial + mesaj de email parțial + фрагмент сообщения электронной почты + Čiastočná e-mailová správa + delno elektronsko sporočilo + Mesazh poste i pjesëshëm + делимична е-порука + del av e-postmeddelande + часткове поштове повідомлення + thư điện tử riêng phần + 部分电子邮件 + 部份電子郵件訊息 + + + + + email message + رسالة البريد الإلكتروني + list email + Съобщение по електронната поща + missatge de correu electrònic + E-mailová zpráva + postmeddelelse + E-Mail-Nachricht + ηλ. μήνυμα + email message + retpoŝta mesaĝo + mensaje de correo electrónico + helbide elektronikoen mezua + sähköpostiviesti + t-post boð + message de courriel + teachtaireacht ríomhphoist + mensaxe de correo electrónico + הודעת דואר אלקטרוני + elektronikus levél + pesan email + Messaggio email + メール本文 + пошталық мәлімдеме + 전자우편 본문 + el. laiškas + e-pasta vēstule + Mesej emel + e-postmelding + e-mailbericht + e-postmelding + Wiadomość e-mail + mensagem de e-mail + mensagem de correio eletrônico + mesaj email + почтовое сообщение + E-mailová správa + sporočilo elektronske pošte + Mesazh poste + е-порука + e-postmeddelande + повідомлення email + thư điện tử + 电子邮件 + 電子郵件內容 + + + + + + + + + + + + + + + + + + GNU mail message + رسالة بريد جنو + GNU poçt ismarışı + List GNU + Съобщение — GNU mail + missatge de GNU mail + Zpráva GNU mail + Neges E-Bost GNU + GNU-postmeddelelse + GNU-Mail-Nachricht + μήνυμα αλληλογραφίας GNU + GNU mail message + mesaĝo de GNU mail + mensaje de GNU mail + GNU posta mezua + GNU-postiviesti + GNU mail boð + message de courriel GNU + teachtaireacht phost GNU + mensaxe de correo electrónico de GNU + הודעת דואר של GNU + GNU elektronikus levél + Pesan surat GNU + Messaggio GNU mail + GNU メールメッセージ + GNU пошта хабарламасы + GNU 메일 메시지 + GNU pašto žinutė + GNU pasta vēstule + Mesej emel GNU + GNU e-postmelding + GNU-mailbericht + GNU e-postmelding + Wiadomość pocztowa GNU + mensagem de e-mail GNU + Mensagem de correio GNU + Mesaj GNU mail + почтовое сообщение GNU + Správa GNU mail + Sporočilo pošte GNU + Mesazh GNU mail + ГНУ е-писмо + GNU-epostmeddelande + поштове повідомлення GNU + Thư điện tử của GNU + GNU mail 信件 + GNU 郵件訊息 + + + + + VRML document + مستند VRML + VRML sənədi + Dakument VRML + Документ — VRML + document VRML + Dokument VRML + Dogfen VRML + VRML-dokument + VRML-Dokument + έγγραφο VRML + VRML document + VRML-dokumento + documento VRML + VRML dokumentua + VRML-asiakirja + VRML skjal + document VRML + cáipéis VRML + documento VRML + מסמך VRML + VRML-dokumentum + Dokumen VRML + Documento VRML + VRML ドキュメント + VRML құжаты + VRML 문서 + VRML dokumentas + VRML dokuments + Dokumen VRML + VRML-dokument + VRML-document + VRML-dokument + Dokument VRML + documento VRML + Documento VRML + Document VRML + документ VRML + Dokument VRML + Dokument VRML + Dokument VRML + VRML документ + VRML-dokument + документ VRML + Tài liệu VRML + VRML 文档 + VRML 文件 + VRML + Virtual Reality Modeling Language + + + + + + + + message in several formats + رسالة في عدة صيغ + verici formatlarında ismarış + paviedamleńnie ŭ niekalkich farmatach + Съобщение в няколко формата + missatge en varis formats + Zpráva v několika formátech + neges mewn sawl fformat + meddelelse i flere formater + Nachricht in mehreren Formaten + μήνυμα σε διάφορες μορφές + message in several formats + mesaĝo en pluraj formatoj + mensaje en varios formatos + hainbat formatuko mezua + viesti useissa muodoissa + boð í fleiri sniðum + message en formats divers + teachtaireacht i roinnt fhormáidí + mensaxe en varios formatos + הודעה במספר פורמטים + többféle formátumú üzenet + pesan dalam beberapa format + Messaggio in diversi formati + いくつかの形式でのメッセージ + бірнеше пішімдегі мәлімдеме + 여러가지 형식의 메시지 + laiškas keletu formatų + ziņojums dažādos formātos + Mesej dalam beberapa format + melding i flere formater + bericht in meerdere opmaken + melding i fleire format + Wiadomość w wielu formatach + mensagem em vários formatos + mensagem em vários formatos + mesaj în diferite formate + сообщение в нескольких форматах + Správa v niekoľkých formátoch + sporočilo v več zapisih + Mesazh në formate të ndryshëm + поруке у више записа + meddelande i flera format + повідомлення у кількох форматах + thông điệp có vài định dạng + 各种格式的消息 + 多種格式的訊息 + + + Macintosh AppleDouble-encoded file + ملف Macintosh AppleDouble مشفر + Macintosh AppleDouble-kodlanmış fayl + Fajł Macintosh, AppleDouble-zakadavany + Файл — кодиран с Macintosh AppleDouble + fitxer codificat AppleDouble de Macintosh + Soubor kódovaný pomocí Macintosh AppleDouble + Ffeil AppleDouble-amgodedig Macintosh + Macintosh AppleDouble-kodet fil + Macintosh-Datei (AppleDouble-kodiert) + αρχείο Macintosh κωδικοποίησης AppleDouble + Macintosh AppleDouble-encoded file + dosiero kodigita laŭ Macintosh AppleDouble + archivo Macintosh codificado con AppleDouble + Macintosh AppleDouble-rekin kodetutako fitxategia + Macintosh AppleDouble -koodattu tiedosto + Macintosh AppleDouble-bronglað fíla + fichier codé Macintosh AppleDouble + comhad ionchódaithe le Macintosh AppleDouble + ficheiro de Macintosh codificado con AppleDouble + קובץ מסוג Macintosh AppleDouble-encoded + Macintosh AppleDouble kódolású fájl + Berkas tersandi Macintosh AppleDouble + File Macintosh codificato AppleDouble + Macintosh AppleDouble エンコードファイル + Macintosh AppleDouble кодталған файлы + 맥킨토시 AppleDouble-encoded 파일 + Macintosh AppleDouble-encoded failas + Macintosh AppleDouble-kodēts fails + Fail terenkod-AppleDouble Macintosh + dokument kodet med Macintosh AppleDouble + Macintosh AppleDouble-gecodeerd bestand + Macintosh AppleDouble-koda fil + Zakodowany w AppleDouble plik Macintosh + ficheiro codificado em AppleDouble de Macintosh + Arquivo Macintosh codificado com AppleDouble + Fișier codat Macintosh AppleDouble + файл (закодированный Macintosh AppleDouble) + Súbor kódovaný pomocou Macintosh AppleDouble + Kodirana datoteka Macintosh (AppleDouble) + File Macintosh i kodifikuar AppleDouble + Мекинтош AppleDouble-encoded датотека + Macintosh AppleDouble-kodad fil + файл закодований Macintosh AppleDouble + Tập tin đã mã hoá Apple-Double của Macintosh + Macintosh AppleDouble 编码的文件 + Macintosh AppleDouble 編碼檔 + + + message digest + خلاصة الرسالة + ismarış daycesti + digest paviedamleńniaŭ + Извадка от съобщение + recopilació de missatges + Přehled zpráv + crynodeb negeseuon + meddelelsessammendrag + Nachrichtensammlung + περίληψη μηνύματος + message digest + mesaĝaro + recopilación de mensajes + mezu laburra + viestikokoelma + boð samandráttur + condensé de message + achoimre theachtaireachtaí + recompilación de mensaxe + תקציר ההודעה + ömlesztett üzenet + pesan digest + Digest di messaggi + メッセージダイジェスト + мәлімдеме профилі + 메시지 묶음 + laiškų santrauka + ziņojumu apkopojums + Jilid mesej + medldingssamling + berichtenbundel + meldingsamandrag + Wiadomość przetwarzania + 'digest' de mensagens + resumo de mensagem + colecție mesaje email + профиль сообщения + Prehľad správ + povzetek sporočila + Shpërndarje mesazhesh + гомила порука + meddelandesamling + збірка повідомлень + bản tóm tắt thông điệp + 消息摘要 + 訊息摘要 + + + encrypted message + رسالة مشفرة + şifrələnmiş ismarış + zašyfravanaje paviedamleńnie + Шифрирано съобщение + missatge xifrat + Zašifrovaná zpráva + Neges wedi ei hamgryptio + krypteret meddelelse + Verschlüsselte Nachricht + κρυπτογραφημένο μήνυμα + encrypted message + ĉifrita mesaĝo + mensaje cifrado + mezu enkriptatua + salattu viesti + bronglað boð + message chiffré + teachtaireacht chriptithe + mensaxe cifrado + הודעה מוצפנת + titkosított üzenet + pesan terenkripsi + Messaggio cifrato + 暗号化メッセージ + шифрленген мәлімдеме + 암호화된 메시지 + užšifruotas laiškas + šifrēta vēstule + Mesej terenkripsi + kryptert melding + versleuteld bericht + kryptert melding + Wiadomość zaszyfrowana + mensagem cifrada + mensagem criptografada + mesaj criptat + зашифрованное сообщение + Zašifrovaná správa + šifrirano sporočilo + Mesazh i kriptuar + шифрована порука + krypterat meddelande + шифроване повідомлення + thông điệp đã mật mã + 加密信件 + 加密訊息 + + + compound documents + مستندات مركبة + składanyja dakumenty + Съставни документи + documents composats + Složené dokumenty + sammensatte dokumenter + Verbunddokumente + σύνθετα έγγραφα + compound documents + parentezaj dokumentoj + documentos compuestos + konposatutako dokumentuak + yhdisteasiakirjat + samansett skjøl + documents composés + cáipéisí comhshuite + documentos compostos + מסמכים מורכבים + összetett dokumentumok + dokumen kompon + Documenti composti + 複合ドキュメント + құрама құжаттары + 복합 문서 + sudurtiniai dokumentai + salikti dokumenti + Dokumen halaman + sammensatte dokumenter + samengestelde documenten + samansette dokument + Dokumenty złożone + documentos compostos + documentos compostos + documente compuse + составные документы + Zložené dokumenty + združeni dokumenti + dokumente të përbërë + сједињени документи + sammansatta dokument + складні документи + tài liệu ghép + 组合文档 + 複合文件 + + + compound document + مستند مركب + birləşik sənəd + składany dakument + Съставен документ + document composat + Složený dokument + dogfen gyfansawdd + sammensat dokument + Verbunddokument + σύνθετο έγγραφο + compound document + parenteza dokumento + documento compuesto + konposatutako dokumentua + yhdisteasiakirja + samansett skjal + document composé + cáipéis comhshuite + documento composto + מסמך מורכב + összetett dokumentum + dokumen kompon + Documento composto + 複合ドキュメント + құрама құжаты + 복합 문서 + sudurtinis dokumentas + salikts dokuments + Dokumen halaman + sammensatt dokument + samengesteld document + samansett dokument + Dokument złożony + documento composto + documento composto + document compus + составной документ + Zložený dokument + združeni dokument + dokumet i përbërë + сједињени документ + sammansatt dokument + складний документ + tài liệu ghép + 组合文档 + 複合文件 + + + mail system report + تقرير نظام البريد + poçt sistemi raportu + rapart paštovaj systemy + Отчет за пощенската система + informe de sistema de correu + Zpráva poštovního systému + adroddiad system bost + postsystemrapport + E-Mail-Systembericht + αναφορά συστήματος ηλ. ταχυδρομείου + mail system report + raporto de retpoŝta sistemo + informe del sistema de correo + posta sistemako txostena + viestijärjestelmän ilmoitus + postkervisfrásøgn + rapport système de courriels + tuairisc chóras poist + informe do sistema de correo + דו"ח של מערכת הדואר + levelezőrendszer jelentése + laporan sistem surat + Rapporto di sistema posta + メールシステムレポート + пошта жүйесінің мәлімдемесі + 메일 시스템 보고서 + pašto sistemos ataskaita + pasta sistēmas atskaite + Laporan sistem mel + e-postsystemrapport + e-mail-systeembericht + e-post-systemrapport + Raport systemu pocztowego + relatório de sistema de e-mail + relatório do sistema de correspondência + raport sistem email + отчёт почтовой системы + Správa poštového systému + poročilo poštnega sistema + Raport i sistemit të postës + извештај поштанског система + e-postsystemrapport + звіт поштової системи + thông báo hệ thống thư + 邮件系统报告 + 郵件系統回報 + + + signed message + رسالة موقّعة + imzalanmış ismarış + padpisanaje paviedamleńnie + Подписано съобщение + missatge signat + Podepsaná zpráva + neges lofnodwyd + signeret meddelelse + Signierte Nachricht + υπογεγραμμένο μήνυμα + signed message + pruvita mesaĝo + mensaje firmado + sinatutako mezua + allekirjoitettu viesti + undirskrivað boð + message signé + teachtaireacht sínithe + mensaxe firmado + הודעה חתומה + aláírt üzenet + pesan ditandatangani + Messaggio firmato + 署名付きメッセージ + қолтаңбасы бар мәлімдеме + 서명된 메시지 + pasirašytas laiškas + parakstīta ziņa + Mesej ditandatangani + signert melding + ondertekend bericht + signert melding + Podpisana wiadomość + mensagem assinada + mensagem assinada + mesaj semnat + подписанное сообщение + Podpísaná správa + podpisano sporočilo + Mesazh i firmosur + потписана порука + signerat meddelande + підписане повідомлення + thông điệp đã ký + 签名信件 + 簽署的訊息 + + + stream of data (server push) + دفق بيانات (دفع خادم) + płyń źviestak (ad servera) + Поток от данни, от страна на сървър + flux de dades (enviat pel servidor) + Proud dat (posílaný serverem) + datastrøm (serverskubbet) + Datenstrom (Server-Push) + χείμαρρος δεδομένων (στελλόμενα από τον εξυπηρετητή) + stream of data (server push) + datumstrio (puŝata per servilo) + flujo de datos (por iniciativa del servidor) + datu-korrontea (zerbitzari igortzailea) + tietovirta (palvelin työntää) + streymur av dáta (ambætara skump) + flux de données (émis par le serveur) + sruth sonraí (brú freastalaí) + fluxo de datos (por iniciativa do servidor) + מידע בזרימה (דחיפה ע"י השרת) + sugárzott adatfolyam (kiszolgálóról) + arus data (dorongan server) + Flusso di dati (server push) + データストリーム (サーバープッシュ型) + мәліметтер ағымы (server push) + 스트림 데이터 (서버 푸시) + duomenų srautas (iš serverio) + datu straume (servera grūsta) + Aliran dara (paksaan pelayan) + datastrøm (server push) + gegevensstroom (server duwt) + datastraum (dytta av tenaren) + Strumień danych (wymuszenie serwera) + fluxo de dados (empurrados pelo servidor) + fluxo de dados (por iniciativa do servidor) + flux de date (de la server) + поток данных (server push) + Prúd dát (posielaný serverom) + pretok podatkov (strežniški) + Fluks me të dhëna (server push) + проток података (гурање са сервера) + dataflöde (serverutsändning) + потік даних (від сервера) + luồng dữ liệu (trình phục vụ đẩy) + 数据流(服务器推送) + 資料串流 (server push) + + + VCS/ICS calendar + سجل VCS/ICS + Kalandar VCS/ICS + Календар — VCS/ICS + calendari VCS/ICS + Kalendář VCS/ICS + VCS/ICS-kalender + VCS/ICS-Kalender + VCS/ICS calendar + VCS/ICS-kalendaro + calendario VCS/ICS + VCS/ICS egutegia + VCS/ICS-kalenteri + VCS/ICS kalendari + calendrier VCS/ICS + féilire VCS/ICS + Calendario VCS/ICS + לוח שנה VCS/ICS + VCS/ICS naptár + Kalender VCS/ICS + Calendario VCS/ICS + VCS/ICS カレンダー + VCS/ICS күнтізбесі + VCS/ICS 달력 + VCS/ICS kalendorius + VCS/ICS kalendārs + VCS/ICS-kalender + VCS/ICS-kalender + VCS/ICS-kalender + Kalendarz VCS/ICS + Calendário VCS/ICS + Calendar VCS/ICS + календарь VCS/ICS + Kalendár VCS/ICS + Datoteka koledarja VCS/ICS + Kalendar VCS/ICS + VCS/ICS-kalender + календар VCS/ICS + Lịch VCS/ICS + VCS/ICS 日历 + VCS/ICS 行事曆 + VCS/ICS + vCalendar/iCalendar + + + + + + + + + + + CSS stylesheet + نمط CSS + Arkuš stylaŭ CSS + Стилове — CSS + llista d'estil CSS + Styl CSS + CSS-stilark + CSS-Stilvorlage + CSS stylesheet + CSS-stilfolio + hoja de estilo CSS + CSS estilo-orria + CSS-tyylitiedosto + CSS sniðark + feuille de style CSS + stílbhileog CSS + folla de estilos CSS + גליון עיצוב CSS + CSS stíluslap + Lembar gaya CSS + Foglio di stile CSS + CSS スタイルシート + CSS стильдер кестесі + CSS 스타일시트 + CSS stiliaus aprašas + CSS stilu saraksts + CSS-stilark + CSS-stijlblad + CSS-stilark + Arkusz stylów CSS + Folha de estilos CSS + Pagină de stil CSS + таблица стилей CSS + Štýly CSS + Slogovna predloga CSS + Fletë stili CSS + CSS-stilmall + таблиця стилів CSS + Tờ kiểu dáng CSS + CSS 样式表 + CSS 樣式表 + CSS + Cascading Style Sheets + + + + + + electronic business card + بطاقة أعمال إلكترونية + elektronnaja biznes-kartka + Електронна визитна картичка + targeta de visita electrònica + Elektronická navštívenka + elektronisk visitkort + Elektronische Visitenkarte + elektronika vizitkarto + tarjeta de visita electrónica + enpresako txartel elektronikoa + sähköinen käyntikortti + elektroniskt handilskort + carte de visite électronique + cárta gnó leictreonach + tarxeta de negocio electrónica + כרטיס ביקור אלקטרוני + elektronikus névjegykártya + kartu bisnis elektronik + Biglietto da visita elettronico + 電子名刺 + электронда визит карточкасы + 전자 명함 + elektroninė vizitinė kortelė + elektroniskā biznesa kartiņa + elektronisch visitekaartje + elektronisk visittkort + Wizytówka elektroniczna + cartão de visita electrónico + cartão de visitas eletrônico + carte de vizită electronică + электронная визитная карточка + Elektronická vizitka + elektronska poslovna vizitka + Skedë elektronike biznesi + elektroniskt visitkort + електронна бізнес-картка + danh thiếp điện tử + 电子商务卡 + 電子商務名片 + + + + + + + + + + + + + + txt2tags document + مستند txt2tags + dakument txt2tags + Документ — txt2tags + document txt2tags + Dokument txt2tags + txt2tags-dokument + txt2tags-Dokument + txt2tags-dokumento + documento txt2tags + txt2tags dokumentua + txt2tags-asiakirja + txt2tags skjal + document txt2tags + cáipéis txt2tags + documento txt2tags + מסמך txt2tags + txt2tags dokumentum + dokumen txt2tags + Documento txt2tags + txt2tags ドキュメント + txt2tags құжаты + txt2tags 문서 + txt2tags dokumentas + txt2tags dokuments + txt2tags-dokument + txt2tags-document + txt2tags-dokument + Dokument txt2tags + Documento txt2tags + document txt2tags + документ txt2tags + Dokument txt2tags + Dokument txt2tags + Dokument txt2tags + txt2tags-dokument + документ txt2tags + tài liệu txt2tags + txt2tags 文档 + txt2tags 文件 + + + + + + + + + Verilog source code + Изходен код — Verilog + codi font en Verilog + Zdrojový kód Verilog + Verilog-kildekode + Verilog-Quellcode + Verilog-fontkodo + código fuente en Verilog + Verilog-lähdekoodi + code source Verilog + código fonte en Verilog + קוד מקור של + Verilog-forráskód + Kode sumber Verilog + Codice sorgente Verilog + Verilog ソースコード + Verilog бастапқы коды + Verilog 소스 코드 + Verilog pirmkods + Kod źródłowy Verilog + Código fonte Verilog + исходный код Verilog + Zdrojový kód Verilog + Datoteka izvorne kode Verilog + Verilog-källkod + вихідний код мовою Verilog + Verilog 源代码 + Verilog 源代碼 + + + + + SystemVerilog header + Заглавен файл — SystemVerilog + capçalera de SystemVerilog + Záhlaví SystemVerilog + SystemVerilog-teksthoved + SystemVerilog-Header + cabeceras de SystemVerilog + SystemVerilog-otsake + en-tête + Cabeceiras de SystemVerilog + כותרת SystemVerilog + SystemVerilog fejléc + Header SystemVerilog + Header SystemVerilog + SystemVerilog ヘッダー + SystemVerilog тақырыптамасы + SystemVerilog 헤더 + SystemVerilog galvene + Nagłówek SystemVerilog + заголовочный файл SystemVerilog + Hlavičky SystemVerilog + Datoteka glave SystemVerilog + SystemVerilog-headerfil + заголовки SystemVerilog + SystemVerilog 头 + SystemVerilog 標頭 + + + + + SystemVerilog source code + Изходен код — SystemVerilog + codi font en SystemVerilog + Zdrojový kód SystemVerilog + SystemVerilog-kildekode + SystemVerilog-Quellcode + código fuente en SystemVerilog + SystemVerilog-lähdekoodi + code source + código fonte en SystemVerilog + קוד מקור של SystemVerilog + SystemVerilog-forráskód + Kode sumber SystemVerilog + Codice sorgente + SystemVerilog ソースコード + SystemVerilog бастапқы коды + SystemVerilog 소스 코드 + SystemVerilog pirmkods + Kod źródłowy SystemVerilog + исходный код SystemVerilog + Zdrojový kód SystemVerilog + Datoteka izvorne kode SystemVerilog + SystemVerilog-källkod + вихідний файл мовою SystemVerilog + SystemVerilog 源代码 + SystemVerilog 源代碼 + + + + + VHDL source code + Изходен код — VHDL + codi font en VHDL + Zdrojový kód VHDL + VHDL-kildekode + VHDL-Quellcode + VHDL-fontkodo + código fuente en VHDL + VHDL-lähdekoodi + code source VHDL + código fonte en VHDL + קוד מקור של VHDL + VHDL-forráskód + Kode sumber VHDL + Codice sorgente VHDL + VHDL ソースコード + VHDL бастапқы коды + VHDL 소스 코드 + VHDL pirmkods + Kod źródłowy VHDL + исходный код VHDL + Zdrojový kód VHDL + Datoteka izvorne kode VHDL + VHDL-källkod + вихідний код мовою VHDL + VHDL 源代码 + VHDL 源代碼 + VHDL + Very-High-Speed Integrated Circuit Hardware Description Language + + + + + + enriched text document + مستند نصي مغنى + zəngin mətn sənədi + azdobleny tekstavy dakument + Документ с обогатен текст + document de text enriquit + Rozšířený textový dokument + Dogfen testun wedi ei gyfoethogi + beriget tekstdokument + Angereichertes Textdokument + εγγραφο εμπλουτισμένου κειμένου + enriched text document + riĉigita teksta dokumento + documento de texto enriquecido + aberastutako testu dokumentua + rikastettu tekstiasiakirja + ríkað tekstskjal + document texte enrichi + cáipéis téacs saibhrithe + documento de texto enriquecido + מסמך טקסט מועשר + enriched text dokumentum + dokumen teks diperkaya + Documento testo arricchito + リッチテキストドキュメント + пішімделген мәтіндік құжаты + enriched text 문서 + praturtinto teksto dokumentas + bagātināta teksta formāts + Dokumen teks diperkaya + riktekst-dokument + verrijkt tekstdocument + rik tekst tekstdokument + Wzbogacony dokument tekstowy + documento de texto rico + documento de texto enriquecido + document text îmbogățit + форматированный текстовый документ + Rozšírený textový dokument + dokument z obogatenim besedilom + Dokument teksti i pasuruar + обогаћени текстуални документ + berikat textdokument + форматований текстовий документ + tài liệu văn bản có kiểu dáng + 富文本文档 + 豐富化文字文件 + + + + help page + صفحة المساعدة + yardım səhifəsi + staronka dapamohi + Страница от помощта + pàgina d'ajuda + Stránka nápovědy + tudalen gymorth + hjælpeside + Hilfeseite + σελίδα βοηθείας + help page + help-paĝo + página de ayuda + laguntzako orria + ohjesivu + hjálparsíða + page d'aide + leathanach cabhrach + páxina de axuda + דף עזרה + súgóoldal + halaman bantuan + Pagina di aiuto + ヘルプページ + анықтама парағы + 도움말 페이지 + žinyno puslapis + palīdzības lapa + Halaman bantuan + hjelpside + hulppagina + hjelpeside + Strona pomocy + página de ajuda + página de ajuda + pagină de ajutor + страница справки + Stránka Pomocníka + stran pomoči + Faqe ndihme + страна помоћи + hjälpsida + сторінка довідки + trang trợ giúp + 帮助页面 + 幫助頁面 + + + + plain text document + مستند نصي مجرد + prosty tekstavy dakument + Документ с неформатиран текст + document de text pla + Prostý textový dokument + rent tekstdokument + Einfaches Textdokument + έγγραφο απλού κειμένου + plain text document + plata teksta dokumento + documento de texto sencillo + testu soileko dokumentua + perustekstiasiakirja + document texte brut + cáipéis ghnáth-théacs + documento de texto sinxelo + מסמך טקסט פשוט + egyszerű szöveg + dokumen teks biasa + Documento in testo semplice + 平文テキストドキュメント + мәтіндік құжаты + 보통 text 문서 + paprastas tekstinis dokumentas + vienkāršs teksta dokuments + Dokumen teks jernih + vanlig tekstdokument + plattetekst-document + vanleg tekstdokument + Zwykły dokument tekstowy + documento em texto simples + documento somente texto + document text simplu + текстовый документ + Obyčajný textový dokument + običajna besedilna datoteka + Dokument në tekst të thjeshtë + обичан текстуални документ + vanligt textdokument + звичайний текстовий документ + tài liệu nhập thô + 纯文本文档 + 純文字文件 + + + + + + + + + + RDF file + ملف RDF + Fajł RDF + Файл — RDF + fitxer RDF + Soubor RDF + RDF-fil + RDF-Datei + RDF file + RDF-dosiero + archivo RDF + RDF fitxategia + RDF-tiedosto + RDF fíla + fichier RDF + comhad RDF + ficheiro RDF + קובץ RDF + RDF fájl + Arsip RDF + File RDF + RDF ファイル + RDF файлы + RDF 파일 + RDF failas + RDF fails + RDF-fil + RDF-bestand + RDF-fil + Plik RDF + Arquivo RDF + Fișier RDF + файл RDF + Súbor RDF + Datoteka RDF + File RDF + RDF-fil + файл RDF + Tập tin RDF + RDF 文件 + RDF 檔 + RDF + Resource Description Framework + + + + + + + + + email headers + ترويسة البريد الإلكتروني + epoçt başlıqları + paštovyja zahałoŭki + Заглавни части на електронни писма + capçaleres de correu electrònic + Záhlaví e-mailu + penawdau e-bost + posthoveder + E-Mail-Kopfzeilen + κεφαλίδες ηλ. μηνυμάτων + email headers + retpoŝtaj ĉapoj + cabeceras de correo electrónico + helbide elektronikoen goiburuak + sähköpostiotsakkeet + t-post tekshøvd + en-têtes de courriel + ceanntásca ríomhphoist + cabeceiras de correo electrónico + כותרת דוא"ל + levélfejléc + tajuk email + Intestazioni email + メールヘッダー + пошталық тақырыптамалары + 전자우편 헤더 + el. laiško antraštės + e-pasta galvene + Pengepala emel + e-posthode + e-mail-kopregels + e-post-hovud + Nagłówki wiadomości e-mail + cabeçalhos de e-mail + cabeçalhos de e-mail + antete email + почтовые заголовки + Hlavičky e-mailu + glava elektronske pošte + Header email + заглавља е-порука + e-posthuvuden + заголовки email + dòng đầu thư điện tử + 电子邮件头 + 電子郵件標頭 + + + + rich text document + مستند نصي غني + zəngin mətn sənədi + azdobleny tekstavy dakument + Документ — rich text + document de text enriquit + Textový dokument RTF + dogfen testun gyfoethog (rtf) + richtekstdokument + RTF-Textdokument + έγγραφο εμπλουτισμένου κειμένου (RTF) + rich text document + riĉteksta dokumento + documento de texto enriquecido + aberastutako testu formatua + RTF-asiakirja + document « rich text » + cáipéis mhéith-théacs + documento do texto enriquecido + מסמך טקסט עשיר + rich text-dokumentum + dokumen teks kaya + Documento rich text + リッチテキストドキュメント + пішімделген мәтіні бар құжаты + rich text 문서 + praturtinto teksto dokumentas + bagātā teksta dokuments + Dokumen teks diperkaya + rik tekst-dokument + opgemaakt tekstdocument + rik tekst-dokument + Dokument Rich Text + documento em texto rico + documento rich text + document text îmbogățit + документ с форматированным текстом + Textový dokument RTF + dokument z oblikovanim besedilom + Dokument rich text + обогаћени текстуални документ + RTF-textdokument + форматований текстовий документ + tài liệu văn bản có kiểu dáng (RTF) + RTF 丰富文本文档 + 豐富文字文件 + + + + + RSS summary + ملخص RSS + Karotki ahlad RSS + Обобщение за сайтове — RSS + resum RSS + Souhrn RSS + RSS-sammendrag + RSS-Zusammenfassung + RSS summary + resumen RSS + RSS laburpena + RSS-tiivistelmä + RSS samandráttur + résumé RSS + achoimre RSS + Resumo RSS + תקציר RSS + RSS összefoglaló + Ringkasan RSS + Sommario RSS + RSS サマリ + RSS жинақталғаны + RSS 요약 + RSS santrauka + RSS kopsavilkums + RSS-sammendrag + RSS-samenvatting + RSS-samandrag + Podsumowanie RSS + Resumo RSS + Rezumat RSS + сводка RSS + Súhrn RSS + Datoteka povzetek RSS + Përmbledhje RSS + RSS-sammanfattning + зведення сайту RSS + Bản tóm tắt RSS + RSS 摘要 + RSS 摘要 + RSS + RDF Site Summary + + + + + + + + + + + Atom syndication feed + مروج تغذية Atom + Syndykacyjny kanał navinaŭ Atom + Емисия — Atom + canal de sindicació Atom + Kanál Atom + Atom syndication-feed + Atom-Nachrichtenquelle + proveedor de noticias Atom + Atom harpidetze-iturria + Atom-yhdistevirta + fil de syndication Atom + fotha sindeacáitithe Atom + fonte de sindicación Atom + הזנה דרך הרשת של Atom + Atom egyesítőfolyam + Umpan sindikasi Atom + Feed di distribuzione Atom + Atom 配信フィード + Atom жаңалықтар таспасы + Atom 묶음 피드 + Atom sindikacijos kanalas + Atom sindikāta barotne + Atom syndikeringsstrøm + Atom-syndicatie-feed + Atom-kjelde + Kanał Atom + Fonte de notícias Atom + Flux agregare Atom + лента новостей Atom + Kanál Atom + Sindikalni vir Atom + Feed për përhapje Atom + Atom-syndikeringskanal + трансляція подач Atom + Nguồn tin tức Atom + Atom 更新种子 + + + + + + + + + + OPML syndication feed + مروج تغذية OPML + Syndykacyjny kanał OPML + Емисия — OPML + canal de sindicació OPML + Kanál OPML + OPML-syndikeringsfeed + OPML-Nachrichtenquelle + proveedor de noticias OPML + OPML harpidetze-iturria + OPML-yhdistevirta + fil de syndication OPML + fotha sindeacáitithe OPML + fonte de sindicación OPML + הזנה דרך הרשת OPML + OPML egyesítőfolyam + Umpan sindikasi OPML + Feed di distribuzione OPML + OPML 配信フィード + OPML жаңалықтар таспасы + OPML 묶음 feed + OPML sindikacijos kanalas + OPML sindikāta barotne + OPML syndikeringsstrøm + OPML-syndicatie-feed + OPML-kjelde + Kanał OPML + Fonte de notícias OPML + Flux OPML syndication + лента новостей OPML + Kanál OPML + Sindikalni vir OPML + Feed për përhapje OPML + OPML-syndikeringskanal + трансляція подач OPML + Nguồn tin tức OPML + OPML 聚合种子 + + + + + + + + + + SGML document + مستند SGML + Dakument SGML + Документ — SGML + document SGML + Dokument SGML + Dogfen SGML + SGML-dokument + SGML-Dokument + έγγραφο SGML + SGML document + SGML-dokumento + documento SGML + SGML dokumentua + SGML-asiakirja + SGML skjal + document SGML + cáipéis SGML + documento SGML + מסמך SGML + SGML-dokumentum + Dokumen SGML + Documento SGML + SGML ドキュメント + SGML құжаты + SGML 문서 + SGML dokumentas + SGML dokuments + Dokumen SGML + SGML-dokument + SGML-document + SGML-dokument + Dokument SGML + documento SGML + Documento SGML + Document SGML + документ SGML + Dokument SGML + Dokument SGML + Dokument SGML + SGML документ + SGML-dokument + документ SGML + Tài liệu SGML + SGML 文档 + SGML 文件 + SGML + Standard Generalized Markup Language + + + + + + spreadsheet interchange document + مستند تبادل الجدول + dakument dla abmienu raźlikovymi arkušami + Документ за обмяна между програми за електронни таблици + document d'intercanvi de full de càlcul + Sešitový přenosový dokument + regnearksudvekslingsdokument + Tabellenkalkulations-Austauschdokument + documento de intercambio de hojas de cálculo + kalkulu-orriak trukatzeko dokumentua + taulukkovälitysasiakirja + rokniarks umbýtisskjal + document d'échange de feuilles de calcul + cáipéis idirmhalartaithe scarbhileog + documento de intercambio de follas de cálculo + מסמך גליון נתונים מתחלף + spreadsheet-cserélhetődokumentum + dokumen lembar sebar saling tukar + Documento di scambio per foglio di calcolo + スプレッドシート交換ドキュメント + spreadsheet interchange құжаты + spreadsheet 교환 문서 + skaičialenčių apsikeitimo dokumentas + izklājlapu apmaiņas dokuments + dokument for regnearkutveksling + rekenblad-uitwisselingsdocument + Utvekslingsdokument for rekneark + Dokument wymiany arkuszy kalkulacyjnych + Documento de intercâmbio de planilhas + document schimb filă de calcul + документ Spreadsheet Interchange + Zošitový prenosový dokument + dokument izmenjeve razpredelnic + Dokument shkëmbimi për fletë llogaritje + spreadsheet interchange-dokument + документ обміну ел. таблицями + tài liệu hoán đổi bảng tính + 电子表格交换文档 + 試算表交換文件 + + + + + + + + + TSV document + مستند TSV + Dakument TSV + Документ — TSV + document TSV + Dokument TSV + TSV-dokument + TSV-Dokument + TSV document + documento TSV + TSV dokumentua + TSV-asiakirja + TSV skjal + document TSV + cáipéis TSV + documento TSV + מסמך TSV + TSV dokumentum + Dokumen TSV + Documento TSV + TSV ドキュメント + TSV құжаты + TSV 문서 + TSV dokumentas + TSV dokuments + TSV-dokument + TSV-document + TSV-dokument + Dokument TSV + Documento TSV + Document TSV + документ TSV + Dokument TSV + Dokument TSV + Dokument TSV + TSV-dokument + документ TSV + Tài liệu TSV + TSV 文档 + TSV 文件 + TSV + Tab Separated Values + + + + + Graphviz DOT graph + مبيان Graphviz DOT + Граф — Graphviz DOT + gràfic Graphviz DOT + Graf Graphviz DOT + Graphviz DOT-graf + Graphviz-DOT-Graph + gráfico Graphviz DOT + Graphviz DOT grafikoa + Graphviz DOT -graafi + Graphviz DOT ritmynd + graphe Graphviz DOT + graf DOT Graphviz + gráfica DOT de Graphviz + גרף של Graphviz DOT + Graphviz DOT-grafikon + Grafik Graphviz DOT + Grafico Graphviz DOT + Graphviz DOT グラフ + Graphviz DOT сызбасы + Graphviz DOT 그래프 + Graphviz DOT diagrama + Graphviz DOT grafiks + Graphviz wetenschappelijke grafiek + Wykres DOT Graphviz + Gráfico do Graphviz DOT + Grafic Graphviz DOT + Диаграмма Graphviz DOT + Graf Graphviz DOT + Datoteka grafikona Graphviz DOT + Graphviz DOT-graf + граф DOT Graphviz + Biểu đồ DOT Graphviz + Graphviz DOT 科学图形 + Graphviz DOT 圖 + + + + + + + + + + + + JAD document + مستند JAD + Dakument JAD + Документ — JAD + document JAD + Dokument JAD + JAD-dokument + JAD-Dokument + JAD-dokumento + documento JAD + JAD dokumentua + JAD-asiakirja + JAD skjal + document JAD + cáipéis JAD + documento JAD + מסמך JAD + JAD dokumentum + Dokumen JAD + Documento JAD + JAD ドキュメント + JAD құжаты + JAD 문서 + JAD dokumentas + JAD dokuments + JAD-dokument + JAD-document + JAD-dokument + Dokument JAD + Documento JAD + Document JAD + документ JAD + Dokument JAD + Dokument JAD + Dokument JAD + JAD-dokument + документ JAD + Tài liệu JAD + JAD 文档 + JAD 文件 + JAD + Java Application Descriptor + + + + + + + WML document + مستند WML + WML sənədi + Dakument WML + Документ — WML + document WML + Dokument WML + Dogfen WML + WML-dokument + WML-Dokument + έγγραφο WML + WML document + WML-dokumento + documento WML + WML dokumentua + WML-asiakirja + WML skjal + document WML + cáipéis WML + documento WML + מסמך WML + WML-dokumentum + Dokumen WML + Documento WML + WML ドキュメント + WML құжаты + WML 문서 + WML dokumentas + WML dokuments + Dokumen XML + WML-dokument + WML-document + WML-dokument + Dokument WML + documento WML + Documento WML + Document WML + документ WML + Dokument WML + Dokument WML + Dokument WML + WML документ + WML-dokument + документ WML + Tài liệu WML + WML 文档 + WML 文件 + WML + Wireless Markup Language + + + + + WMLScript program + برنامج WMLScript + Prahrama WMLScript + Програма — WMLScript + programa WMLScript + Program WMLScript + WMLScript-program + WMLScript-Programm + programa en WMLScript + WMLScript programa + WMLScript-ohjelma + WMLScript forrit + programme WMLScript + ríomhchlár WMLScript + programa en WMLScript + תוכנית של WMLScript + WMLScript program + Program WMLScript + Programma WMLScript + WMLScript プログラム + WMLScript бағдарламасы + WML스크립트 프로그램 + WMLScript programa + WMLScript programma + WMLScript-program + WMLScript-programma + WMLScript-program + Pogram WMLScript + Programa WMLScript + Program WMLScript + сценарий WMLScript + Program WMLScript + Programska datoteka WMLScript + Program WMLScript + WMLScript-program + програма мовою WMLScript + Chương trình WMLScript + WMLScript 程序 + WMLScript 程式 + + + + ACE archive + أرشيف ACE + Archiŭ ACE + Архив — ACE + arxiu ACE + Archiv ACE + ACE-arkiv + ACE-Archiv + ACE-arkivo + archivador ACE + ACE artxiboa + ACE-arkisto + ACE skjalasavn + archive ACE + cartlann ACE + arquivo ACE + ארכיון ACE + ACE archívum + Arsip ACE + Archivio ACE + ACE アーカイブ + ACE архиві + ACE 묶음 파일 + ACE archyvas + ACE arhīvs + ACE-arkiv + ACE-archief + ACE-arkiv + Archiwum ACE + Pacote ACE + Arhivă ACE + архив ACE + Archív ACE + Datoteka arhiva ACE + Arkiv ACE + ACE-arkiv + архів ACE + Kho nén ACE + ACE 归档文件 + ACE 封存檔 + + + + + + + + Ada source code + شفرة مصدر Ada + Kryničny kod Ada + Изходен код — Ada + codi font en Ada + Zdrojový kód v Adě + Ada-kildekode + Ada-Quelltext + πηγαίος κώδικας Ada + Ada source code + Ada-fontkodo + código fuente en Ada + Ada iturburu-kodea + Ada-lähdekoodi + Ada keldukota + code source Ada + cód foinseach Ada + código fonte en Ada + קוד מקור Ada + Ada-forráskód + Kode program Ada + Codice sorgente Ada + Ada ソースコード + Ada бастапқы коды + Ada 소스 코드 + Ada pradinis kodas + Ada pirmkods + Kod sumber Ada + Ada-kildekode + Ada-broncode + Ada-kjeldekode + Kod źródłowy Ada + código fonte Ada + Código fonte Ada + Cod sursă Ada + исходный код Ada + Zdrojový kód jazyka Ada + Datoteka izvorne kode Ada + Kod burues Ada + Ада изворни ко̂д + Ada-källkod + вихідний код мовою Ada + Mã nguồn Ada + Ada 源代码 + Ada 源代碼 + + + + + + author list + لائحة المؤلف + śpis aŭtaraŭ + Списък на авторите + llista d'autors + Seznam autorů + forfatterliste + Autorenliste + κατάλογος συγγραφέων + author list + listo de aŭtoroj + lista de autores + egile-zerrenda + tekijäluettelo + høvundalisti + liste d'auteurs + liosta údar + lista de autores + רשימת יוצרים + szerzőlista + senarai penulis + Elenco autori + 著者リスト + авторлар тізімі + 저자 목록 + autorių sąrašas + autoru saraksts + Senarai penulis + forfatterliste + auteurslijst + forfattarliste + Lista autorów + lista de autores + lista de autores + listă autori + список авторов + Zoznam autorov + seznam avtorjev + Lista e autorëve + списак аутора + författarlista + перелік авторів + danh sách tác giả + 作者列表 + 作者清單 + + + + + BibTeX document + مستند BibTeX + Dakument BibTeX + Документ — BibTeX + document BibTeX + Dokument BibTeX + BibTeX-dokument + BibTeX-Dokument + BibTeX document + BibTeX-dokumento + documento BibTeX + BibTeX dokumentua + BibTeX-asiakirja + BibTeX skjal + document BibTeX + cáipéis BibTeX + documento BibTex + מסמך BibTeX + BibTeX dokumentum + Dokumen BibTeX + Documento BibTeX + BibTeX ドキュメント + BibTeX құжаты + BibTeX 문서 + BibTeX dokumentas + BibTeX dokuments + BibTeX-dokument + BibTeX-document + BibTeX-dokument + Dokument BibTeX + Documento BibTeX + Document BibTeX + документ BibTeX + Dokument BibTeX + Dokument BibTeX + Dokument BibTeX + BibTeX-dokument + документ BibTeX + Tài liệu BibTeX + BibTeX 文档 + BibTeX 文件 + + + + + + + + C++ header + ترويسة سي++ + Zahałoŭny fajł C++ + Заглавен файл — C++ + capçalera en C++ + Záhlaví v C++ + C++-posthoved + C++-Header + C++ header + cabecera de código fuente en C++ + C++ goiburua + C++-otsake + C++ tekshøvd + en-tête C++ + ceanntásc C++ + cabeceira de código fonte en C++ + כותר ++C + C++ fejléc + Tajuk C++ + Header C++ + C++ ヘッダー + C++ тақырыптама файлы + C++ 헤더 + C++ antraštė + C++ galvene + C++-kildekodeheader + C++-header + C++-kjeldekode-hovud + Plik nagłówkowy C++ + Cabeçalho C++ + Antet C++ + заголовочный файл C++ + Hlavičky jazyka C++ + Datoteka glave C++ + Header C++ + C++-huvud + файл заголовків мовою C++ + Phần đầu mã nguồn C++ + C++ 源代码头文件 + C++ 標頭檔 + + + + + + + + + C++ source code + شفرة مصدر سي++ + Kryničny kod C++ + Изходен код — C++ + codi font en C++ + Zdrojový kód v C++ + C++-kildekode + C++-Quelltext + πηγαίος κώδικας C++ + C++ source code + C++-fontkodo + código fuente en C++ + C++ iturburu-kodea + C++-lähdekoodi + C++ keldukota + code source C++ + cód foinseach C++ + código fonte de C++ + קוד מקור של C++ + C++-forráskód + Kode program C++ + Codice sorgente C++ + C++ ソースコード + C++ бастапқы коды + C++ 소스 코드 + C++ pradinis kodas + C++ pirmkods + Kod sumber C++ + C++-kildekode + C++-broncode + C++-kjeldekode + Kod źródłowy C++ + código fonte C++ + Código fonte C++ + Cod sursă C++ + исходный код C++ + Zdrojový kód jazyka C++ + Datoteka izvorne kode C++ + Kod burues C++ + C++ изворни ко̂д + C++-källkod + вихідний код мовою C++ + Mã nguồn C++ + C++ 源代码 + C++ 源代碼 + + + + + + + + + ChangeLog document + مستند ChangeLog + Dakument zafiksavanych źmienaŭ ChangeLog + Дневник за промени — ChangeLog + document de registre de canvis + Dokument ChangeLog + ChangeLot-dokument + Änderungsprotokoll + ChangeLog document + documento de cambios + ChangeLog dokumentua + Muutoslokiasiakirja + ChangeLog skjal + document ChangeLog + cáipéis ChangeLog + documento Changelog + מסמך של ChangeLog + ChangeLog dokumentum + Dokumen ChangeLog + Documento ChangeLog + ChangeLog ドキュメント + ChangeLog құжаты + ChangeLog 문서 + ChangeLog dokumentas + ChangeLog dokuments + ChangeLog-dokument + ChangeLog-document + ChangeLog-dokument + Dokument zmian (ChangeLog) + Documento ChangeLog + Document ChangeLog + протокол изменений + Dokument ChangeLog + Dokument ChangeLog + Dokument ChangeLog + Ändringsloggsdokument + документ ChangeLog + Tài liệu ChangeLog (ghi lưu thay đổi) + 变更日志文档 + ChangeLog 文件 + + + + + C header + ترويسة C + Zahałoŭny fajł C + Заглавен файл — C + capçalera en C + Záhlaví v C + C-posthoved + C-Header + C header + cabecera de código fuente en C + C goiburua + C-otsake + C tekshøvd + en-tête C + ceanntásc C + cabeceira de códifo fonte de C + כותר C + C fejléc + Tajuk C + Header C + C ヘッダー + C тақырыптама файлы + C 헤더 + C antraštė + C galvene + C-kildekodeheader + C-header + C-kjeldekode-hovud + Plik nagłówkowy C + Cabeçalho C + Antet C + заголовочный файл C + Hlavičky jazyka C + Datoteka glave C + Header C + C-huvud + файл заголовків мовою C + Phần đầu mã nguồn C + C 程序头文件 + C 標頭檔 + + + + + CMake source code + شفرة مصدر CMake + Kryničny kod CMake + Изходен код — CMake + codi font en CMake + Zdrojový kód CMake + CMake-kildekode + CMake-Quelltext + CMake-fontkodo + código fuente en CMake + CMake iturburu-kodea + CMake-lähdekoodi + CMake keldukota + code source CMake + cód foinseach CMake + código fonte de CMake + קוד מקור של CMake + CMake-forráskód + Kode program CMake + Codice sorgente CMake + CMake ソースコード + CMake бастапқы коды + CMake 소스 코드 + CMake pirminis tekstas + CMake pirmkods + CMake-kildekode + CMake-broncode + CMake-kjeldekode + Kod źródłowy CMake + Código fonte CMake + Cod sursă CMake + исходный код CMake + Zdrojový kód CMake + Datoteka izvorne kode CMake + Kod burues CMake + CMake-källkod + вихідний код CMake + Mã nguồn CMake + CMake 源代码 + CMake 源代碼 + + + + + + CSV document + مستند CSV + Dakument CSV + Документ — CSV + document CSV + Dokument CSV + CSV-dokument + CSV-Dokument + CSV document + CSV-dokumento + documento CSV + CSV dokumentua + CSV-asiakirja + CSV skjal + document CSV + cáipéis CSV + documento CSV + מסמך CSV + CSV dokumentum + Dokumen CSV + Documento CSV + CSV ドキュメント + CSV құжаты + CSV 문서 + CSV dokumentas + CSV dokuments + CSV-dokument + CSV-document + CSV-dokument + Dokument CSV + Documento CSV + Document CSV + документ CSV + Dokument CSV + Dokument CSV + Dokument CSV + CSV-dokument + документ CSV + Tài liệu CSV + CSV 文档 + CSV 文件 + CSV + Comma Separated Values + + + + + + + license terms + شروط الترخيص + licenzijnyja ŭmovy + Лицензни условия + condicions de llicència + Licenční podmínky + licensbetingelser + Lizenzbedingungen + licence terms + términos de licencia + lizentzia baldintzak + lisenssiehdot + loyvistreytir + termes de licence + téarmaí ceadúnais + termos de licenza + תנאי רישיון + licencfeltételek + persyaratan lisensi + Termini di licenza + ソフトウェアライセンス条項 + лицензиялық келісімі + 라이선스 조항 + licencijos sąlygos + licences nosacījumi + lisensbestemmelser + licentievoorwaarden + lisensvilkår + Warunki licencji + termos de licença + termeni de licență + лицензионное соглашение + Licenčné podmienky + pogoji in dovoljenja uporabe + Kushte liçence + licensvillkor + ліцензійні умови + điều kiện giấy phép + 软件许可条款 + 授權條款 + + + + + author credits + شكر وتقدير المؤلف + zasłuhi aŭtara + Благодарности към авторите + atribucions d'autor + Autorské zásluhy + bidragydere + Autorendanksagung + author credits + reconocimiento de autoría + tekijöiden kiitokset + høvundaheiður + remerciements + admhálacha údar + créditos de autor + קרדיטים של היוצר + szerzők listája + kredit penulis + Riconoscimenti autori + ソフトウェア作者クレジット + бағдарлама авторлары + 저작자 크레디트 + padėkos autoriams + veidotāji + liste med bidragsytere + auteursinformatie + forfattarliste + Podziękowania autorów programu + créditos do autor + mulțumiri autori + авторы программы + Autorské zásluhy + avtorske zasluge + Kreditë e autorëve + författarlista + подяки авторам програми + công trạng tác giả + 软件作者致谢 + 作者致謝名單 + + + + + C source code + شفرة مصدر سي + Kryničny kod C + Изходен код — C + codi font en C + Zdrojový kód v C + C-kildekode + C-Quelltext + πηγαίος κώδικας C + C source code + C-fontkodo + código fuente en C + C iturburu-kodea + C-lähdekoodi + C keldukota + code source C + cód foinseach C + código fonte en C + קוד מקור של C + C-forráskód + Kode program C + Codice sorgente C + C ソースコード + C бастапқы коды + C 소스 코드 + C pradinis kodas + C pirmkods + Kod sumber C + C-kildekode + C-broncode + C-kjeldekode + Kod źródłowy C + código fonte C + Código fonte C + Cod sursă C + исходный код C + Zdrojový kód jazyka C + Datoteka izvorne kode C + Kod burues C + C изворни ко̂д + C-källkod + вихідний код мовою C + Mã nguồn C + C 源代码 + C 源代碼 + + + + + + + + + + + C# source code + شفرة مصدر سي# + Kryničny kod C# + Изходен код — C# + codi font en C# + Zdrojový kód v C# + C#-kildekode + C#-Quelltext + πηγαίος κώδικας C# + C# source code + C#-fontkodo + código fuente en C# + C# iturburu-kodea + C#-lähdekoodi + C# keldukota + code source C# + cód foinseach C# + código fonte en C# + קוד מקור של C# + C#-forráskód + Kode program C# + Codice sorgente C# + C# ソースコード + C# бастапқы коды + C# 소스 코드 + C# pradinis kodas + C# pirmkods + Kod sumber C# + C#-kildekode + C#-broncode + C#-kjeldekode + Kod źródłowy C# + código fonte C# + Código fonte C# + Cod sursă C# + исходный код C# + Zdrojový kód jazyka C# + Datoteka izvorne kode C# + Kod burues C# + C# изворни ко̂д + C#-källkod + вихідний код мовою C# + Mã nguồn C# + C# 源代码 + C# 源代碼 + + + + + Vala source code + شفرة مصدر Vala + Kryničny kod Vala + Изходен код — Vala + codi font en Vala + Zdrojový kód Vala + Valakildekode + Vala-Quelltext + Vala-fontkodo + código fuente en Vala + Vala iturburu-kodea + Vala-lähdekoodi + Vala keldukota + code source Vala + cód foinseach Vala + código fonte en Vala + קוד מקור של Vala + Vala forráskód + Kode program Vala + Codice sorgente Vala + Vala ソースコード + Vala бастапқы коды + Vala 소스 코드 + Vala pradinis kodas + Vala pirmkods + Vala-kildekode + Vala-broncode + Vala-kjeldekode + Kod źródłowy Vala + Código fonte Vala + Cod sursă Vala + исходный код Vala + Zdrojový kód Vala + Datoteka izvorne kode Vala + Kod burues Vala + Vala-källkod + вихідний код мовою Vala + Mã nguồn Vala + Vala 源代码 + Vala 源代碼 + + + + + + OOC source code + Изходен код — OOC + codi font en OOC + Zdrojový kód OOC + OOC-Quellcode + OOC-fontkodo + Código fuente en OOC + OOC-lähdekoodi + source code OOC + código fonte de OOC + קוד מקור של OOC + OOC forráskód + Kode sumber OOC + Codice sorgente OOC + OOC ソースコード + OOC бастапқы коды + OOC 소스 코드 + OOC pirmkods + Kod źródłowy OOC + исходный код OOC + Izvorna koda OOC + OOC-källkod + вихідний код мовою OOC + OOC + OOC 源代碼 + OOC + Out Of Class + + + + + DCL script + سكربت DCL + DCL skripti + Skrypt DCL + Скрипт — DCL + script DCL + Skript DCL + Sgript DCL + DCL-program + DCL-Skript + πρόγραμμα εντολών DCL + DCL script + DCL-skripto + script en DCL + DCL script-a + DCL-komentotiedosto + DCL boðrøð + script DCL + script DCL + script de DCL + תסריט DCL + DCL-parancsfájl + Skrip DCL + Script DCL + DCL スクリプト + DCL сценарийі + DCL 스크립트 + DCL scenarijus + DCL skripts + Skrip DCL + DCL-skript + DCL-script + DCL-skript + Skrypt DCL + 'script' DCL + Script DCL + Script DCL + сценарий DCL + Skript DCL + Skriptna datoteka DCL + Script DCL + DCL скрипта + DCL-skript + скрипт DCL + Văn lệnh DCL + DCL 脚本 + DCL 指令稿 + DCL + Data Conversion Laboratory + + + + + DSSSL document + مستند DSSSL + DSSSL sənədi + Dakument DSSSL + Документ — DSSSL + document DSSSL + Dokument DSSSL + Dogfen DSSSL + DSSSL-dokument + DSSSL-Dokument + έγγραφο DSSSL + DSSSL document + DSSSL-dokumento + documento DSSSL + DSSSL dokumentua + DSSSL-asiakirja + DSSSL skjal + document DSSSL + cáipéis DSSSL + documento DSSSL + מסמך DSSSL + DSSSL-dokumentum + Dokumen DSSSL + Documento DSSSL + DSSSL ドキュメント + DSSSL құжаты + DSSSL 문서 + DSSSL dokumentas + DSSSL dokuments + Dokumen DSSSL + DSSSL-dokument + DSSSL-document + DSSSL-dokument + Dokument DSSSL + documento DSSSL + Documento DSSSL + Document DSSSL + документ DSSSL + Dokument DSSSL + Dokument DSSSL + Dokument DSSSL + DSSSL документ + DSSSL-dokument + документ DSSSL + Tài liệu DSSSL + DSSSL 文档 + DSSSL 文件 + DSSSL + Document Style Semantics and Specification Language + + + + + D source code + شفرة مصدر D + Kryničny kod D + Изходен код — D + codi font en D + Zdrojový kód v D + D-kildekode + D-Quelltext + D source code + D-fontkodo + código fuente en D + D iturburu-kodea + D-lähdekoodi + D keldukota + code source D + cód foinseach D + código fonte de D + קוד מקור לשפת D + D-forráskód + Kode program D + Codice sorgente D + D ソースコード + D бастапқы коды + D 소스 코드 + D pradinis kodas + D pirmkods + D-kildekode + D-broncode + D-kjeldekode + Kod źródłowy D + Código fonte D + Cod sursă D + исходный код D + Zdrojový kód jazyka D + Datoteka izvorne kode D + Kod burues D + D изворни ко̂д + D-källkod + вихідний код мовою D + Mã nguồn D + D 源代码 + D 源代碼 + + + + + DTD file + ملف DTD + Fajł DTD + Документ — DTD + fitxer DTD + Soubor DTD + DTD-fil + DTD-Datei + DTD file + DTD-dosiero + archivo DTD + DTD fitxategia + DTD-tiedosto + DTD fíla + fichier DTD + comhad DTD + ficheiro DTD + מסמך DTD + DTD fájl + Berkas DTD + File DTD + DTD ファイル + DTD файлы + DTD 파일 + DTD failas + DTD fails + DTD-fil + DTD-bestand + DTD-fil + Plik DTD + Arquivo DTD + Fișier DTD + файл DTD + Súbor DTD + Datoteka DTD + File DTD + DTD-fil + файл DTD + Tập tin DTD + DTD 文件 + DTD 檔 + DTD + Document Type Definition + + + + + + + Eiffel source code + شفرة مصدر Eiffel + Kryničny kod Eiffel + Изходен код — Eiffel + codi font en Eiffel + Zdrojový kód Eiffel + Eiffelkildekode + Eiffel-Quelltext + Eiffel-fontkodo + código fuente en Eiffel + Eiffel iturburu-kodea + Eiffel-lähdekoodi + Eiffel keldukota + code source Eiffel + cód foinseach Eiffel + código fone de Eiffel + קוד מקור של Eiffel + Eiffel forráskód + Kode program Eiffel + Codice sorgente Eiffel + Eiffel ソースコード + Eiffel бастапқы коды + Eiffel 소스 코드 + Eiffel pirminis programos tekstas + Eiffel pirmkods + Eiffel-kildekode + Eiffel-broncode + Eiffel-kjeldekode + Kod źródłowy Eiffel + Código fonte Eiffel + Cod sursă Eiffel + исходный код Eiffel + Zdrojový kód Eiffel + Datoteka izvorne kode Eiffel + Kod burues Eiffel + Eiffel-källkod + вихідний код мовою Eiffel + Mã nguồn Eiffel + Eiffel 源代码 + Eiffel 源代碼 + + + + + + Emacs Lisp source code + شفرة مصدر Emacs Lisp + Emacs Lisp mənbə kodu + Kryničny kod Emacs Lisp + Изходен код — Emacs Lisp + codi font en Emacs Lisp + Zdrojový kód Emacs Lisp + Ffynhonnell rhaglen EMACS LISP + Emacs Lisp-kildekode + Emacs-Lisp-Quelltext + πηγαίος κώδικας Emacs Lisp + Emacs Lisp source code + fontkodo en Emacs Lisp + código fuente en Lisp de Emacs + Emacs Lisp iturburu-kodea + Emacs Lisp -lähdekoodi + Emacs Lisp keldukota + code source Emacs Lisp + cód foinseach Emacs Lisp + código fonte de Emacs Lisp + קוד מקור של Emcas Lisp + Emacs Lisp-forráskód + Kode sumber Emacs Lisp + Codice sorgente Emacs Lisp + Emacs Lisp ソースコード + Emacs Lisp бастапқы коды + Emacs Lisp 소스 코드 + Emacs Lisp pradinis kodas + Emacs Lisp pirmkods + Kod sumber Emacs Lisp + Emacs Lisp-kildekode + Emacs Lisp-broncode + Emacs Lisp kjeldekode + Plik źródłowy Emacs Lisp + código fonte Emacs Lisp + Código fonte Lisp do Emacs + Cod sursă Emacs Lisp + исходный код Emacs Lisp + Zdrojový kód Emacs Lisp + Datoteka izvorne kode Emacs Lisp + Kod burues Emacs Lisp + Емакс Лисп изворни ко̂д + Emacs Lisp-källkod + вихідний код мовою Emacs Lisp + Mã nguồn Lisp Emacs + Emacs Lisp 源代码 + Emacs Lisp 源代碼 + + + + + + + + + Erlang source code + شفرة مصدر Erlang + Kryničny kod Erlang + Изходен код — Erlang + codi font en Erlang + Zdrojový kód Erlang + Erlangkildekode + Erlang-Quelltext + Erlang-fontkodo + código fuente en Erlang + Erlang iturburu-kodea + Erlang-lähdekoodi + Erlang keldukota + code source Erlang + cód foinseach Erlang + código fonte de Erlang + קוד מקור של Erlang + Erlang forráskód + Kode program Erlang + Codice sorgente Erlang + Erlang ソースコード + Erlang бастапқы коды + Erlang 소스 코드 + Erlang pradinis kodas + Erlang pirmkods + Erlang-kildekode + Erlang-broncode + Erlang-kjeldekode + Kod źródłowy Erlang + Código fonte Erlang + Cod sursă Erlang + исходный код Erlang + Zdrojový kód Erlang + Datoteka izvorne kode Erlang + Kod burues Erlang + Erlang-källkod + вихідний код мовою Erlang + Mã nguồn Erlang + Erlang 源代码 + Erlang 源代碼 + + + + + Fortran source code + شفرة مصدر Fortran + Fortran mənbə kodu + Kryničny kod Fortran + Изходен код — Fortran + codi font en Fortran + Zdrojový kód Fortran + Ffynhonnell rhaglen FORTRAN + Fortrankildekode + Fortran-Quelltext + πηγαίος κώδικας Fortran + Fortran source code + Fotran-fontkodo + código fuente en Fortran + Fortran-en iturburu-kodea + Fortran-lähdekoodi + Fortran keldukota + code source Fortran + cód foinseach Fortran + código fonte de Fortran + קוד מקור של Fortran + Fortran-forráskód + Kode program Fortran + Codice sorgente Fortran + Fortran ソースコード + Fortran бастапқы коды + 포트란 소스 코드 + Fortran pradinis kodas + Fortran pirmkods + kod sumber Fortran + Fortran-kildekode + Fortran-broncode + Fortran-kjeldekode + Kod źródłowy Fortran + código fonte Fortran + Código fonte Fortran + Cod sursă Fortran + исходный код Fortran + Zdrojový kód Fortran + Datoteka izvorne kode Fortran + Kod burues Fortran + Фортран изворни ко̂д + Fortran-källkod + вихідний код мовою Fortran + Mã nguồn Fortran + Fortran 源代码 + Fortran 源代碼 + + + + + + + + translation file + ملف الترجمة + fajł pierakładu + Превод + fitxer traducció + Soubor překladu + oversættelsesfil + Übersetzungsdatei + tradukad-dosiero + archivo de traducción + itzulpen-fitxategia + käännöstiedosto + týðingarfíla + fichier de traduction + comhad aistrithe + ficheiro de tradución + קובץ תרגום + fordítási fájl + berkas terjemahan + File traduzione + 翻訳ファイル + аудармалар файлы + 번역 파일 + vertimo failas + tulkošanas fails + oversettelsesfil + vertalingsbestand + omsetjingsfil + Plik tłumaczenia + Arquivo de tradução + fișier traducere + файл переводов + Súbor prekladu + datoteka prevoda programa + File përkthimesh + översättningsfil + файл перекладу + tập tin dịch + 消息翻译文件 + 翻譯檔 + + + + + + + translation template + قالب الترجمة + šablon dla pierakładu + Шаблон за преводи + plantilla de traducció + Šablona překladu + oversættelsesskabelon + Übersetzungsvorlage + translation template + tradukad-ŝablono + plantilla de traducción + itzulpenen txantiloia + käännösmalli + týðingarformur + modèle de traduction + teimpléad aistrithe + plantilla de tradución + תבנית תרגום + fordítási sablon + templat terjemahan + Modello di traduzione + 翻訳テンプレート + аудармалар үлгісі + 메세지 번역 서식 + vertimo šablonas + tulkošanas veidne + mal for oversetting + vertalingssjabloon + omsetjingsmal + Szablon tłumaczenia + modelo de tradução + șablon de traducere + шаблон переводов + Šablóna prekladu + predloga datoteke prevoda programa + Model përkthimesh + översättningsmall + шаблон перекладу + mẫu dịch + 消息翻译模板 + 翻譯模版 + + + + + + HTML document + مستند HTML + Dakument HTML + Документ — HTML + document HTML + Dokument HTML + HTML-dokument + HTML-Dokument + HTML document + HTML-dokumento + documento HTML + HTML dokumentua + HTML-asiakirja + HTML skjal + document HTML + cáipéis HTML + documento HTML + מסמך HTML + HTML dokumentum + Dokumen HTML + Documento HTML + HTML ドキュメント + HTML құжаты + HTML 문서 + HTML dokumentas + HTML dokuments + HTML-dokument + HTML-document + HTML-dokument + Dokument HTML + Documento HTML + Document HTML + документ HTML + Dokument HTML + Dokument HTML + Dokument HTML + HTML-dokument + документ HTML + Tài liệu HTML + HTML 文档 + HTML 文件 + HTML + HyperText Markup Language + + + + + + + + + + + + + + + + + + + + + + + + + Web application cache manifest + قائمة التخزين الموقت لتطبيق الويب + Манифест за кеша на уеб приложение + manifest de memòria cau d'aplicació Web + Manifest mezipaměti webové aplikace + Manifest for internetprogrammellemlager + Webanwendungscache-Manifest + manifiesto de caché de aplicación web + Web aplikazioaren cache-aren agiria + Net nýtsluskipanarkova manifest + manifeste de cache d'application Web + lastliosta taisce d'fheidhmchlár Gréasáin + manifesto de caché de aplicativo web + הצהרה של מטמון של תוכנית ברשת + Webalkalmazás gyorsítótár-összefoglalója + Manifes singgahan aplikasi web + Manifesto cache applicazione Web + Web アプリケーションキャッシュ manifest + Веб қолданбасының кэш манифесті + 웹 애플리케이션 캐시 정의 + Žiniatinklio programos podėlio manifestas + Tīmekļa lietotņu keša manifests + Manifest pamięci podręcznej aplikacji WWW + Manifest de cache pentru aplicații web + манифест кэша веб-приложения + Predpomnilnik spletnega programa + Cachemanifest för webbapplikation + маніфест кешу веб-програми + 网络应用程序缓存清单 + + + + + + + + + + + + + Google Video Pointer + مؤشر فيديو جوجل + Pakazalnik Google Video + Документ-указател към видео на Google + apuntador a vídeo de Google + Google Video Pointer + Google Video-peger + Google Video Pointer + lista de reproducción de Google Video (GVP) + Google Video-ren erreprodukzio-zerrenda + Google-video-osoitin + Google Video Pointer + pointeur vidéo Google + pointeoir Google Video + punteiro de vídeo de Google + מצביע וידאו של Google + Google Video Pointer + Google Video Pointer + Puntatore Google Video + Google ビデオポインター + Google Video Pointer + 구글 비디오 포인터 + Google Video Pointer + Google Video Pointer + Peker til Google Video + Google-videoverwijzing + Google Video-peikar + Lista odtwarzania Google Video + Ponteiro do Google Vídeo + Indicator Google Video + Google Video Pointer + Google Video Pointer + Kazalec Google Video + Puntues Google Video + Google Video-pekare + вказівник відео Google + Con trỏ ảnh động Google + Google 视频指向 + Google Video Pointer + + + + + + + + + Haskell source code + شفرة مصدر Haskell + Haskell mənbə kodu + Kryničny kod Haskell + Изходен код на Haskell + codi font en Haskell + Zdrojový kód Haskell + Ffynhonnell rhaglen Haskell + Haskellkildekode + Haskell-Quelltext + πηγαίος κώδικας Haskell + Haskell source code + Haskell-fontkodo + código fuente en Haskell + Haskell iturburu-kodea + Haskell-lähdekoodi + Haskell keldukota + code source Haskell + cód foinseach Haskell + código fonte de Haskell + קוד מקור של Haskell + Haskell-forráskód + Kode program Haskell + Codice sorgente Haskell + Haskell ソースコード + Haskell бастапқы коды + Haskell 소스 코드 + Haskell pradinis kodas + Haskell pirmkods + Kod sumber Haskell + Haskell-kildekode + Haskell-broncode + Haskell-kjeldekode + Kod źródłowy Haskell + código fonte Haskell + Código fonte Haskell + Cod sursă Haskell + исходный код Haskell + Zdrojový kód Haskell + Datoteka izvorne kode Haskell + Kod burues Haskell + Haskell изворни ко̂д + Haskell-källkod + вихідний код мовою Haskell + Mã nguồn Haskell + Haskell 源代码 + Haskell 源代碼 + + + + + IDL document + مستند IDL + IDL sənədi + Dakument IDL + Документ — IDL + document IDL + Dokument IDL + Dogfen IDL + IDL-dokument + IDL-Dokument + έγγραφο IDL + IDL document + IDL-dokumento + documento IDL + IDL dokumentua + IDL-asiakirja + IDL skjal + document IDL + cáipéis IDL + documento IDL + מסמך IDL + IDL-dokumentum + Dokumen IDL + Documento IDL + IDL ドキュメント + IDL құжаты + IDL 문서 + IDL dokumentas + IDL dokuments + Dokumen IDL + IDL-dokument + IDL-document + IDL-dokument + Dokument IDL + documento IDL + Documento IDL + Document IDL + документ IDL + Dokument IDL + Dokument IDL + Dokument IDL + IDL документ + IDL-dokument + документ IDL + Tài liệu IDL + IDL 文档 + IDL 文件 + IDL + Interface Definition Language + + + + + installation instructions + تعليمات التثبيت + instrukcyja dla instalavańnia + Инструкции за инсталация + instruccions d'instal·lació + Návod k instalaci + installationsinstruktioner + Installationsanleitung + installation instructions + instrucciones de instalación + instalazioaren instrukzioak + asennusohjeet + innleggingar vegleiðing + instructions d'installation + treoracha suiteála + instrucións de instalación + הוראות התקנה + telepítési utasítások + instruksi instalasi + Istruzioni di installazione + ソフトウェアインストール説明 + бағдарламаны орнату нұсқаулары + 설치 방법 + diegimo instrukcijos + instalācijas instrukcijas + installationsinstruksjoner + installatie-instructies + installasjonsinstruksjonar + Instrukcje instalacji + instruções de instalação + instrucțiuni de instalare + инструкции по установке программы + Návod na inštaláciu + navodila namestitve + Udhëzime instalimi + installationsinstruktioner + інструкції з встановлення + hướng dẫn cài đặt + 软件安装指南 + 安裝指引 + + + + + Java source code + شفرة مصدر Java + Kryničny kod Java + Изходен код на Java + codi font en Java + Zdrojový kód v Javě + Javakildekode + Java-Quelltext + πηγαίος κώδικας Java + Java source code + Java-fontkodo + código fuente en Java + Java iturburu-kodea + Java-lähdekoodi + Java keldukota + code source Java + cód foinseach Java + código fonte de Java + קוד מקור ב־Java + Java-forráskód + Kode program Java + Codice sorgente Java + Java ソースコード + Java бастапқы коды + 자바 소스 코드 + Java pradinis kodas + Java pirmkods + Kod sumber Java + Java-kildekode + Java-broncode + Java-kjeldekode + Kod źródłowy Java + código fonte Java + Código fonte Java + Cod sursă Java + исходный код Java + Zdrojový kód Java + Datoteka izvorne kode Java + Kod burues Java + Јава изворни ко̂д + Java-källkod + вихідний код мовою Java + Mã nguồn Java + Java 源代码 + Java 源代碼 + + + + + LDIF address book + دفتر عناوين LDIF + Adrasnaja kniha LDIF + Адресна книга — LDIF + llibreta d'adreces LDIF + Adresář LDIF + LDIF-adressebog + LDIF-Adressbuch + LDIF-adresaro + libreta de direcciones LDIF + LDIF helbide-liburua + LDIF-osoitekirja + LDIF adressubók + carnet d'adresses LDIF + leabhar sheoltaí LDIF + lista de enderezos LDIF + ספר כתובות של LDIF + LDIF címjegyzék + Buku alamat LDIF + Rubrica LDIF + LDIF アドレス帳 + LDIF адрестер кітабы + LDIF 주소록 + LDIF adresų knygelė + LDIF adrešu grāmata + LDIF-adressebok + LDIF-adresboek + LDIF-adressebok + Książka adresowa LDIF + Livro de endereços LDIF + Agendă LDIF + адресная книга LDIF + Adresár LDIF + Datoteka imenika naslovov LDIF + Rubrikë LDIF + LDIF-adressbok + адресна книга LDIF + Sổ địa chỉ LDIF + LDIF 地址簿 + LDIF 通訊錄 + LDIF + LDAP Data Interchange Format + + + + + + + + + Lilypond music sheet + صفحة موسيقى Lilypond + Muzyčny arkuš Lilypond + Нотация на Lilypond + full de música Lilypond + Notový papír Lilypond + Lilypondmusikkort + Lilypond-Notenblatt + hoja de música Lilypond + Lilypond musika-orria + Lilypond-nuotit + Lilypond tónleika ark + partition musicale Lilypond + bileog cheoil Lilypond + folla de música de Lilypond + דף מוזיקה של Lilypond + Lilypond kotta + Lembar musik Lilypond + Partitura Lilypond + Lilypond 楽譜データ + Lilypond музыка тізімі + Lilypond 음악 시트 + Lilypond muzikos lapas + Lilypond mūzikas lapa + Lilypond-muziekblad + Lilypond noteark + Plik partytury Lilypond + Folha de música do Lilypond + Fișă muzică Lilypond + список музыки Lilypond + Notový papier Lilypond + Glasbena predloga Lilypond + Partiturë Lilypond + Lilypond-notblad + нотний запис Lilypond + Bản nhạc Lilypond + Lilypond 乐谱 + Lilypond 樂譜 + + + + + LHS source code + شفرة مصدر LHS + Kryničny kod LHS + Изходен код на LHS + codi font en LHS + Zdrojový kód v LHS + LHS-kildekode + LHS-Quelltext + LHS source code + LHS-fontkodo + código fuente en LHS + LHS iturburu-kodea + LHS-lähdekoodi + LHS keld + code source LHS + cód foinseach LHS + código fonte en LHS + קוד מקור של LHS + LHS forráskód + Kode program LHS + Codice sorgente LHS + LHS ソースコード + LHS бастапқы коды + LHS 소스 코드 + LHS pradinis kodas + LHS pirmkods + LHS-kildekode + LHS-broncode + LHS-kjeldekode + Kod źródłowy LHS + Código fonte LHS + Cod sursă LHS + исходный код LHS + Zdrojový kód LHS + Datoteka izvorne kode LHS + Kod burues LHS + LHS-källkod + вихідний код LHS + Mã nguồn LHS + LHS 源代码 + LHS 源代碼 + LHS + Literate Haskell source code + + + + + application log + سجل التطبيق + časopis aplikacyi + Файл-дневник на приложение + registre d'aplicació + Záznam aplikace + programlog + Anwendungsprotokoll + ημερολόγιο συμβάντων εφαρμογής + application log + protokolo de aplikaĵo + registro de aplicación + aplikazio egunkaria + sovelluksen lokitiedosto + nýtsluskipan logg + journal d'application + logchomhad feidhmchláir + rexistro de aplicativo + יומן התוכנה + alkalmazás naplója + log aplikasi + Log applicazione + アプリケーションログ + мәлімдемелер журналы + 프로그램 기록 + programos žurnalas + lietotnes žurnāls + Log aplikasi + applikasjonslogg + programma-logbestand + programlogg + Dziennik programu + registo de aplicação + Registro de aplicação + înregistrare aplicație + журнал сообщений + Záznam aplikácie + dnevnik programa + log i mesazheve të programit + дневник програма + programlogg + журнал програми + bản ghi ứng dụng + 应用程序日志 + 程式紀錄檔 + + + + + Makefile + ملف Makefile + İnşa faylı + Makefile + Файл — make + Makefile + Makefile + Ffeil "make" + Bygningsfil + Makefile + Makefile + Makefile + Muntodosiero + Makefile + Makefile + Makefile + Makefile + makefile + Makefile + Makefile + Makefile + Makefile + Makefile + Makefile + Makefile + Makefile (жинау файлы) + Makefile + Makefile + Makefile + Makefile + Makefile + Makefile + Makefile + Plik make + Makefile + Makefile (arquivo do make) + Makefile + Makefile (файл сборки) + Makefile + Datoteka Makefile + Makefile + Производна датотека + Makefil + файл проекту make + Tập tin tạo ứng dụng (Makefile) + Makefile + Makefile + + + + + + + + + + + Markdown document + Документ — Markdown + document Markdown + Dokument Markdown + Documento de Markdown + Markdown-asiakirja + document Markdown + documento de Markdown + מסמך Markdown + Dokumen markdown + Documento Markdown + Markdown + Markdown құжаты + Markdown dokuments + Dokument Markdown + документ Markdown + Dokument Markdown + документ Markdown + + + + + + + Qt MOC file + ملف Qt MOC + Fajł Qt MOC + Файл — Qt MOC + fitxer MOC de Qt + Soubor Qt MOC + Qt MOC-fil + Qt-MOC-Datei + Qt MOC file + archivo MOC Qt + Qt MOC fitxategia + Qt MOC -tiedosto + Qt MOC fíla + fichier Qt MOC + comhad MOC Qt + ficheiro MOC Qt + קובץ Qt MOC + Qt MOC fájl + Berkas Qt MOC + File MOC Qt + Qt MOC ファイル + Qt MOC файлы + Qt MOC 파일 + Qt MOC failas + Qt MOC fails + Qt MOC-fil + Qt MOC-bestand + Qt MOC-fil + Plik Qt MOC + Arquivo Qt MOC + Fișier Qt MOC + файл Qt MOC + Súbor Qt MOC + Datoteka Qt MOC + File Qt MOC + Qt MOC-fil + файл-метаоб'єкт Qt + Tập tin MOC của Qt + Qt 元对象编译文件 + Qt MOC 檔 + Qt MOC + Qt Meta Object Compiler + + + + + Windows Registry extract + استخراج مسجل ويندوز + Element rehistru Windows + Извадка от регистъра на Windows + extracte del registre de Windows + Část registrů Windows + Windows Registy-udtrækning + Windows-Registry-Auszug + extracto del registro de Windows + Windows-eko erregistro erauzlea + Windows-rekisteritietue + Windows Registry úrdráttur + extrait de registre Windows + sliocht as Clárlann Windows + Extracto do rexistro de Windows + קובץ Registry של Windows + Windows Registry kivonat + Ekstrak Windows Registry + Estratto Windows Registry + WIndows レジストリ抽出ファイル + Windows Registry бөлігі + 윈도우 레지스트리 파일 + Windows registro ištrauka + Windows Registry izvilkums + Utdrag av Windows Registry + Windows Registry-extract + Windows Registry-utdrag + Wycinek rejestru Windows + Extrator de registro do Windows + Extras al registrului Windows + фрагмент Windows Registry + Časť registrov Windows + izvleček vpisnika Windows + Pjesë Windows Registry + Windows Registry-utdrag + частина реєстру Windows + Bản trích Registry Windows + Windows 注册表文件 + Windows Registry 抽出 + + + + + + + + + + Managed Object Format + صيغة كائن مدار + Farmat Managed Object + Управлявани обекти — MOF + format d'objecte gestionat + Managed Object Format + Håndteret objektformat + Managed Object Format + formato de objeto manejado + Kudeatutako objektu formatua + Managed Object Format + format Managed Object + formáid réada bainistithe + formato de obxecto xestionado + פורמט ניהול אובייקט + Felügyelt objektum (MO) formátum + Managed Object Format + Managed Object Format + 管理オブジェクトフォーマット + Басқарылатын объект пішімі + 관리되는 오브젝트 형식 + Sutvarkytų objektų formatas + Pārvaldītu objektu formāts + Managed Object Format + Managed Object Format + Managed Object Format + Plik Managed Object Format + Formato de objeto gerenciado + Managed Object Format + формат управляемого объекта + Formát Managed Object + Datoteka Managed Object + Managed Object Format + Managed Object Format + формат керування об’єктами + Định dạng Đối tượng đã Quản lý + 托管对象格式 + Managed Object Format + + + + + Mup publication + منشور Mup + Publikacyja Mup + Издание — Mup + publicació Mup + Publikace Mup + Mupudgivelse + Mup-Veröffentlichung + Mup publication + publicación Mup + Mup publikazioa + Mup-julkaisu + Mup útgáva + publication Mup + foilseachán Mup + publicación Mup + פרסום של Mup + Mup publikáció + Publikasi Mup + Pubblicazione Mup + Mup 出版ファイル + Mup жариялымы + Mup 출판 + Mup leidinys + Mup publikācija + Mup publikasjon + Mup-publicatie + Mup-publikasjon + Publikacja Mup + Publicação do Mup + Publicație Mup + публикация Mup + Publikácie Mup + Datoteka objave Mup + Publikim Mup + Mup-publicering + публікація Mup + Bản xuất Mup + Mup 应用程序 + + + + + + + + + Objective-C source code + شفرة مصدر الهدف-C + Kryničny kod Objective-C + Изходен код — Objective C + codi font en Objective-C + Zdrojový kód v Objective-C + Objektiv C-kildekode + Objective-C-Quelltext + πηγαίος κώδικας Objective-C + Objective-C source code + fontkodo en Objective-C + código fuente en Objective-C + Objective-C iturburu-kodea + Objective-C-lähdekoodi + Objective-C keldukota + code source Objective-C + cód foinseach Objective-C + código fonte de Objective-C + קוד מקור של Objective-C + Objective-C forráskód + Kode program Objective-C + Codice sorgente Objective-C + Objective-C ソースコード + Objective-C бастапқы коды + Objective-C 소스 코드 + Objective-C pradinis kodas + Objective-C pirmkods + Kod sumber Objective-C + Objective-C-kildekode + Objective-C-broncode + Objective-C-kjeldekode + Kod źródłowy Objective-C + código fonte Objective-C + Código fonte Objective-C + Cod sursă Objective-C + исходный код Objective-C + Zdrojový kód Objective-C + Datoteka izvorne kode Objective-C + Kod burues C objekt + Објектни-C изворни ко̂д + Objective-C-källkod + вихідний код мовою Objective-C + Mã nguồn Objective-C + Objective-C 源代码 + Objective-C 源代碼 + + + + + + + + OCaml source code + شفرة مصدر OCaml + Kryničny kod OCaml + Изходен код — OCaml + codi font en OCaml + Zdrojový kód OCaml + OCaml-kildekode + OCaml-Quelltext + OCaml-fontkodo + código fuente en OCaml + OCaml iturburu-kodea + OCaml-lähdekoodi + OCaml keldukota + code source OCaml + cód foinseach OCaml + código fonte de OCaml + קוד מקור של OCaml + OCaml forráskód + Kode program OCaml + Codice sorgente OCaml + OCaml ソースコード + OCaml бастапқы коды + OCaml 소스 코드 + OCaml pradinis kodas + OCaml pirmkods + OCaml-kildekode + OCaml-broncode + OCaml-kjeldekode + Kod źródłowy OCaml + Código fonte do OCaml + Cod sursă OCaml + исходный код OCaml + Zdrojový kód OCaml + Datoteka izvorne kode OCaml + Kod burues OCaml + OCaml-källkod + первинний код мовою OCaml + Mã nguồn OCaml + OCaml 源代码 + OCaml 源代碼 + + + + + MATLAB script/function + سكربت/وظيفة MATLAB + Skrypt/funkcyja MATLAB + Скрипт/функция — MATLAB + script/funció MATLAB + Skript/funkce MATLAB + MATLAB-program/-funktion + MATLAB-Skript/-Funktion + MATLAB script/function + script/función de MATLAB + MATLAB script/funtzioa + MATLAB-komentotiedosto/funktio + MATLAB boðrøð/funka + script/fonction MATLAB + script/feidhm MATLAB + función/script de MATLAB + תסריט/פונקציית MATLAB + MATLAB parancsfájl/funkció + Skrip/fungsi MATLAB + Script/Funzione MATLAB + MATLAB スクリプト/関数 + MATLAB сценарий/функциясы + MATLAB 스크립트/함수 + MATLAB scenarijus / funkcija + MATLAB skripts/funkcija + Skript/funksjon for MATLAB + MATLAB-script/functie + MATLAB-skript/funksjon + Skrypt/funkcja MATLAB + Script/função do MATLAB + Funcție/script MATLAB + сценарий/функция MATLAB + Skript/funkcia MATLAB + Skriptna datoteka MATLAB + Script/Funksion MATLAB + MATLAB-skript/funktion + скрипт/функція MATLAB + Văn lệnh/chức năng MATLAB + MATLAB 脚本/函数 + MATLAB 指令稿/函式 + + + + + + + + + + + + + + + Pascal source code + شفرة مصدر باسكال + Kryničny kod Pascal + Изходен код — Pascal + codi font en Pascal + Zdrojový kód v Pascalu + Pascalkildekode + Pascal-Quelltext + πηγαίος κώδικας Pascal + Pascal source code + Pascal-fontkodo + código fuente en Pascal + Pascal iturburu-kodea + Pascal-lähdekoodi + Pascal keldukota + code source Pascal + cód foinseach Pascal + código fonte en Pascal + קוד מקור של Pascal + Pascal-forráskód + Kode program Pascal + Codice sorgente Pascal + Pascal ソースコード + Pascal бастапқы коды + 파스칼 소스 코드 + Pascal pradinis kodas + Pascal pirmkods + Kod sumber Pascal + Pascal-kildekode + Pascal-broncode + Pascal-kjeldekode + Kod źródłowy Pascal + código fonte Pascal + Código fonte Pascal + Cod sursă Pascal + исходный код Pascal + Zdrojový kód Pascal + Datoteka izvorne kode Pascal + Kod burues Pascal + Паскал изворни ко̂д + Pascal-källkod + вихідний код мовою Pascal + Mã nguồn Pascal + Pascal 源代码 + Pascal 源代碼 + + + + + + differences between files + الاختلافات بين الملفات + adroźnieńni pamiž fajłami + Разлики между файлове + diferències entre fitxers + Rozdíly mezi soubory + forskel mellem filer + Unterschiede zwischen Dateien + διαφορές μεταξύ αρχείων + differences between files + diferencoj inter dosieroj + diferencias entre archivos + fitxategien arteko ezberdintasunak + tiedostojen väliset erot + munur millum fílur + différences entre fichiers + difríochtaí idir chomhaid + diferenzas entre ficheiros + ההבדל בין קבצים + diff-különbségfájl + perbedaan diantara berkas + Differenze tra file + ファイル間差分 + файлдар арасындағы айырмашылықтары + 파일 사이의 바뀐점 + skirtumai tarp failų + divu failu atšķirība + Perbezaan antara fail + forskjeller mellom filer + verschillen tussen bestanden + skilnader mellom filer + Różnica pomiędzy plikami + diferenças entre ficheiros + diferenças entre arquivos + diferențe între fișiere + различия между файлами + Rozdiely medzi súbormi + razlike med datotekami + Diferencë midis file + разлике међу датотекама + skillnader mellan filer + різниця між файлами + khác biệt giữa các tập tin + 文件的区别 + 檔案內容差異 + + + + + + + + + + + + + + + + + + + Go source code + Изходен код — Go + codi font en Go + Zdrojový kód Go + Go-Quellcode + Go-fontkodo + Ir al código fuente + Go-lähdekoodi + code source Go + código fonte de Go + קוד מקור של Go + Go forráskód + Kode sumber Go + Codice sorgente Go + Go ソースコード + Go бастапқы коды + Go 소스 코드 + Go pirmkods + Kod źródłowy Go + исходный код Go + Izvorna koda Go + вихідний код мовою Go + Go + Go 源代碼 + + + + + Python script + سكربت بايثون + Skrypt Python + Скрипт — Python + script Python + Skript v Pythonu + Pythonprogram + Python-Skript + πρόγραμμα εντολών Python + Python script + Python-skripto + script en Python + Python script-a + Python-komentotiedosto + Python boðrøð + script Python + script Python + Script en Python + תסריט Python + Python-parancsfájl + Skrip Python + Script Python + Python スクリプト + Python сценарийі + 파이썬 스크립트 + Python scenarijus + Python skripts + Skrip Python + Python-skript + Python-script + Python-skript + Skrypt Python + 'script' Python + Script Python + Script Python + сценарий Python + Skript Python + Skriptna datoteka Python + Script Python + Питон скрипта + Pythonskript + скрипт мовою Python + Văn lệnh Python + Python 脚本 + Python 指令稿 + + + + + + + + + + + + + + + + + + + Lua script + سكربت Lua + Skrypt Lua + Скрипт на Lua + script Lua + Skript Lua + Luaprogram + Lua-Skript + Lua-skripto + script en Lua + Lua script-a + Lua-komentotiedosto + Lua boðrøð + script Lua + script Lua + script de Lua + תסריט Lua + Lua parancsfájl + Skrip Lua + Script Lua + Lua スクリプト + Lua сценарийі + Lua 스크립트 + Lua scenarijus + Lua skripts + Lua-skript + Lua-script + Lua-skript + Skrypt Lua + Script Lua + Script Lua + сценарий Lua + Skript Lua + Skriptna datoteka Lua + Script Lua + Lua-skript + скрипт Lua + Văn lệnh Lua + Lua 脚本 + Lua 指令稿 + + + + + + + + + + README document + مستند README + README sənədi + Dakument README + Документ — „Да се прочете“ + document README + Dokument README + Dogfen README + README-dokument + README-Dokument + έγγραφο README + README document + README-dokumento + documento README + README dokumentua + LUEMINUT-asiakirja + README skjal + document LISEZ-MOI + cáipéis README + documento README + מסמך README + README-dokumentum + Dokumen README + Documento README + README ドキュメント + README құжаты + README 문서 + README dokumentas + README dokuments + Dokumen README + README-dokument + LEESMIJ-document + README-dokument + Dokument README + documento LEIA-ME + Documento README + Document README + документ README + Dokument README + Dokument README + Dokument README + ПРОЧИТАЈМЕ документ + README-dokument + документ README + Tài liệu Đọc Đi (README) + README 文档 + README 說明文件 + + + + + NFO document + مستند NFO + Dakument NFO + Документ — NFO + document NFO + Dokument NFO + NFO-dokument + NFO-Dokument + NFO-dokumento + documento NFO + NFO dokumentua + NFO-asiakirja + NFO skjal + document NFO + cáipéis NFO + documento NFO + מסמך NFO + NFO-dokumentum + Dokumen NFO + Documento NFO + NFO ドキュメント + NFO құжаты + NFO 문서 + NFO dokumentas + NFO dokuments + NFO-dokument + NFO-document + NFO-dokument + Dokument NFO + Documento NFO + Document NFO + документ NFO + Dokument NFO + Dokument NFO + Dokument NFO + NFO-dokument + документ NFO + Tài liệu NFO + NFO 文档 + NFO 文件 + + + + + RPM spec file + ملف مواصفات RPM + Specyfikacyjny fajł RPM + Файл — спецификация за RPM + fitxer spec RPM + Soubor spec RPM + RPM spec-fil + RPM-Spezifikationsdatei + archivo de especificaciones RPM + RPM espezifikazio fitxategia + RPM spec -tiedosto + RPM tøknilýsingarfíla + fichier de spécification RPM + comhad spec RPM + ficheiro de especificacións RPM + קובץ מפרט RPM + RPM spec fájl + Berkas spesifikasi RPM + File specifica RPM + RPM spec ファイル + RPM анықтама файлы + RPM spec 파일 + RPM spec failas + RPM specifikācijas fails + RPM-spesifikasjonsfil + RPM-spec-bestand + RPM spec-fil + Plik spec RPM + Arquivo de especificação RPM + Fișier RPM spec + файл описания RPM + Súbor RPM spec + Določilna datoteka RPM + File specifikimi RPM + RPM spec-fil + spec-файл RPM + Tập tin đặc tả RPM + RPM spec 文件 + RPM spec 規格檔 + RPM + Red Hat Package Manager + + + + + + + + + Scala source code + Изходен код — Scala + codi font en Scala + Zdrojový kód Scala + Código fuente en Scala + Scala-lähdekoodi + code source Scala + código fnote en Scala + קוד מקור של Scala + Kode sumber Scala + Codice sorgente Scala + Scala ソースコード + Scala бастапқы коды + Scala pirmkods + Kod źródłowy Scala + исходный код Scala + Izvorna koda Scala + Scala-källkod + вихідний код мовою Scala + + + + + Scheme source code + شفرة مصدر Scheme + Sxem mənbə kodu + Kryničny kod Scheme + Изходен код — Scheme + codi font en Scheme + Zdrojový kód Scheme + Ffynhonnell Rhaglen Scheme + Schemekildekode + Scheme-Quelltext + πηγαίος κώδικας Scheme + Scheme source code + Scheme-fontkodo + código fuente en Scheme + Scheme iturburu-kodea + Scheme-lähdekoodi + Scheme keldukota + code source Scheme + cód foinseach Scheme + código fonte en Scheme + קוד מקור של Scheme + Scheme-forráskód + Kode program Scheme + Codice sorgente Scheme + Scheme ソースコード + Scheme бастапқы коды + Scheme 소스 코드 + Scheme pradinis kodas + Scheme pirmkods + Kod sumber Scheme + Scheme-kildekode + Scheme-broncode + Scheme-kjeldekode + Kod źródłowy Scheme + código fonte Scheme + Código fonte Scheme + Cod sursă Scheme + исходный код Scheme + Zdrojový kód Scheme + Datoteka izvorne kode Scheme + Kod burues Scheme + Scheme изворни ко̂д + Scheme-källkod + вихідний файл мовою Scheme + Mã nguồn Scheme + Scheme 源代码 + Scheme 源代碼 + + + + + + Setext document + مستند Setext + Setext sənədi + Dakument Setext + Документ — Setext + document Setext + Dokument Setext + Dogfen Setext + Setextdokument + Setext-Dokument + έγγραφο Setext + Setext document + Setext-dokumento + documento Setext + Setext dokumentua + Setext-asiakirja + Setext skjal + document Setext + cáipéis Setext + documento Settext + מסמך של Setext + Setext-dokumentum + Dokumen Setext + Documento Setext + Setext ドキュメント + Setext құжаты + Setext 문서 + Setext dokumentas + Setext dokuments + Dokumen Setext + Setext-dokument + Setext-document + Setext-dokument + Dokument Setext + documento Setext + Documento Setext + Document Setext + документ Setext + Dokument Setext + Dokument Setext + Dokument Setext + Setext документ + Setext-dokument + документ Setext + Tài liệu Setext + Setext 文档 + Setext 文件 + + + + + SQL code + شفرة SQL + SQL kodu + Kod SQL + Код — SQL + codi en SQL + Kód SQL + Côd SQL + SQL-kode + SQL-Befehle + κώδικας SQL + SQL code + SQL-kodo + código SQL + SQL kodea + SQL-koodi + SQL kota + code SQL + cód SQL + código SQL + קוד SQL + SQL-kód + Kode SQL + Codice SQL + SQL コード + SQL коды + SQL 코드 + SQL kodas + SQL kods + Kod SQL + SQL-kildekode + SQL-code + SQL-kode + Kod SQL + código SQL + Código SQL + Cod SQL + код SQL + Kód SQL + Datoteka kode SQL + Kod SQL + SQL ко̂д + SQL-kod + код SQL + Mã SQL + SQL 代码 + SQL 代碼 + + + + + Tcl script + سكربت Tcl + Skrypt Tcl + Скрипт — Tcl + script Tcl + Skript v Tcl + Tcl-program + Tcl-Skript + πρόγραμμα εντολών Tcl + Tcl script + Tcl-skripto + script en Tcl + Tcl script-a + Tcl-komentotiedosto + Tcl boðrøð + script Tcl + script Tcl + Script en Tcl + תסריט Tcl + Tcl-parancsfájl + Skrip Tcl + Script Tcl + Tcl スクリプト + Tcl сценарийі + Tcl 스크립트 + Tcl scenarijus + Tcl skripts + Skrip Tcl + Tcl-skript + Tcl-script + Tcl-skript + Skrypt Tcl + 'script' Tcl + Script Tcl + Script Tcl + сценарий Tcl + Skript Tcl + Skriptna datoteka Tcl + Script Tcl + Tcl скрипта + Tcl-skript + скрипт Tcl + Văn lệnh Tcl + Tcl 脚本 + Tcl 描述語言檔 + + + + + + TeX document + مستند TeX + Dakument TeX + Документ — TeX + document TeX + Dokument TeX + Dogfen TeX + TeX-dokument + TeX-Dokument + έγγραφο TeX + TeX document + TeX-dokumento + documento TeX + TeX dokumentua + TeX-asiakirja + TeX skjal + document TeX + cáipéis TeX + documenton TeX + מסמך TeX + TeX-dokumentum + Dokumen TeX + Documento TeX + TeX ドキュメント + TeX құжаты + TeX 문서 + TeX dokumentas + TeX dokuments + Dokumen TeX + TeX-dokument + TeX-document + TeX-dokument + Dokument TeX + documento TeX + Documento TeX + Document TeX + документ TeX + Dokument TeX + Dokument TeX + Dokument TeX + ТеХ документ + TeX-dokument + документ TeX + Tài liệu TeX + TeX 文档 + TeX 文件 + + + + + + + + + + + + + + + + + + TeXInfo document + مستند TeXInfo + TeXInfo sənədi + Dakument TeXInfo + Документ — TeXInfo + document TeXInfo + Dokument TeXInfo + Dogfen TeXInfo + TeXInfo-dokument + TeXInfo-Dokument + έγγραφο TeXInfo + TeXInfo document + TeXInfo-dokumento + documento TeXInfo + TeXInfo dokumentua + TeXInfo-asiakirja + TeXInfo skjal + document TeXInfo + cáipéis TeXInfo + documento TeXInfo + מסמך של TeXInfo + TeXInfo-dokumentum + Dokumen TeXInfo + Documento TeXInfo + TeXInfo ドキュメント + TeXInfo құжаты + TeXInfo 문서 + TeXInfo dokumentas + TeXInfo dokuments + Dokumen TeXInfo + TeXInfo-dokument + TeXInfo-document + TeXInfo-dokument + Dokument TeXInfo + documento TeXInfo + Documento TeXInfo + Document TexInfo + документ TeXInfo + Dokument TeXInfo + Dokument TeXInfo + Dokument TeXInfo + ТеХинфо документ + TeXInfo-dokument + документ TeXInfo + Tài liệu TeXInfo + TeXInfo 文档 + TeXInfo 文件 + + + + + + Troff ME input document + مستند Troff ME input + Uvodny dakument Troff ME + Изходен документ — Troff ME + document d'entrada Troff ME + Vstupní dokument Troff ME + Troff ME inddata-dokument + Troff-ME-Eingabedokument + έγγραφο/πρόγραμμα εντολών troff ME + Troff ME input document + eniga dokumento de Troff ME + documento de entrada Troff ME + Troff ME sarrerako dokumentua + Troff ME -syöteasiakirja + Troff ME inntaksskjal + document d'entrée Troff ME + cáipéis ionchur Troff ME + documento de entrada Troff ME + מסמך קלט של Troff ME + Troff ME bemeneti dokumentum + Dokumen masukan Troff ME + Documento di input Troff ME + Troff ME 入力ドキュメント + Troff ME кіріс құжаты + Troff ME 입력 문서 + Troff ME įvesties dokumentas + Troff ME ievades dokuments + Dokumen input Troff ME + Troff ME-inndatadokument + Troff ME-invoerdocument + Troff ME inndata-dokument + Dokument wejściowy Troff ME + documento origem Troff ME + Documento de entrada Troff ME + Document intrare Troff ME + входной документ Troff ME + Vstupný dokument Troff ME + Vnosni dokument Troff ME + Dokument i input Troff ME + Troff ME улазни документ + Troff ME-indatadokument + вхідний документ Troff ME + Tài liệu nhập ME Troff + Troff ME 输入文档 + Troff ME 輸入文件 + + + + + Troff MM input document + مستند Troff MM input + Uvodny dakument Troff MM + Изходен документ — Troff MM + document d'entrada Troff MM + Vstupní dokument Troff MM + Troff MM inddata-dokument + Troff-MM-Eingabedokument + έγγραφο/πρόγραμμα εντολών troff MM + Troff MM input document + eniga dokumento de Troff MM + documento de entrada Troff MM + Troff MM sarrerako dokumentua + Troff MM -syöteasiakirja + Troff MM inntaksskjal + document d'entrée Troff MM + cáipéis ionchur Troff MM + documento de entrada Troff MM + מסמך קלט של Troff MM + Troff MM bemeneti dokumentum + Dokumen masukan Troff MM + Documento di input Troff MM + Troff MM 入力ドキュメント + Troff MM кіріс құжаты + Troff MM 입력 문서 + Troff MM įvesties dokumentas + Troff MM ievades dokuments + Dokumen input Troff MM + Troff MM-inndatadokument + Troff MM-invoerdocument + Troff MM inndata-dokument + Dokument wejściowy Troff MM + documento origem Troff MM + Documento de entrada Troff MM + Document intrare Troff MM + входной документ Troff MM + Vstupný dokument Troff MM + Vnosni dokument Troff MM + Dokument i input Troff MM + Troff MM улазни документ + Troff MM-indatadokument + вхідний документ Troff MM + Tài liệu nhập MM Troff + Troff MM 输入文档 + Troff MM 輸入文件 + + + + + Troff MS input document + مستند Troff MS input + Uvodny dakument Troff MS + Изходен документ — Troff MS + document d'entrada Troff MS + Vstupní dokument Troff MS + Troff MS inddata-dokument + Troff-MS-Eingabedokument + έγγραφο/πρόγραμμα εντολών troff MS + Troff MS input document + eniga dokumento de Troff MS + documento de entrada Troff MS + Troff MS sarrerako dokumentua + Troff MS -syöteasiakirja + Troff MS inntaksskjal + document d'entrée Troff MS + cáipéis ionchur Troff MS + documento de entrada Troff MS + מסמך קלט של Troff MS + Troff MS bemeneti dokumentum + Dokumen masukan Troff MS + Documento di input Troff MS + Troff MS 入力ドキュメント + Troff MS кіріс құжаты + Troff Ms 입력 문서 + Troff MS įvesties dokumentas + Troff MS ievades dokuments + Dokumen input Troff MS + Troff MS-inndatadokument + Troff MS-invoerdocument + Troff MS inndata-dokument + Dokument wejściowy Troff MS + documento origem Troff MS + Documento de entrada Troff MS + Document intrare Troff MS + входной документ Troff MS + Vstupný dokument Troff MS + Vnosni dokument Troff MS + Dokument i input Troff MS + Troff MS улазни документ + Troff MS-indatadokument + вхідний документ Troff MS + Tài liệu nhập MS Troff + Troff MS 输入文档 + Troff MS 輸入文件 + + + + + X-Motif UIL table + جدول X-Motif UIL + Tablica X-Motif UIL + Таблица — X-Motif UIL + taula UIL de X-Motif + Tabulka X-Motif UIL + X-Motif UIL-tabel + X-Motif-UIL-Tabelle + πίνακας X-Motif UIL + X-Motif UIL table + tabla de X-Motif UIL + X-Motif UIL taula + X-Motif UIL -taulukko + X-Motif UIL talva + table X-Motif UIL + tábla X-Motif UIL + Táboa de X-Motif UIL + טבלה של X-Motif UIL + X-Motif UIL-táblázat + Tabel X-Motif UIL + Tabella UIL X-Motif + X-Motif UIL 表 + X-Motif UIL кестесі + X-Motif UIL 테이블 + X-Motif UIL lentelė + X-Motif UIL tabula + Jadual X-Motif UIL + X-Motif UIL-tabell + X-Motif UIL-tabel + X-Motif UIL-tabell + Tabela UIL X-Motif + tabela UIL do X-Motif + Tabela do X-Motif UIL + Tabel X-Motif UIL + таблица UIL X-Motif + Tabuľka X-Motif UIL + Preglednica X-Motif UIL + Tabelë X-Motif UIL + X-Motif UIL табела + X-Motif UIL-tabell + таблиця X-Motif UIL + Bảng UIL X-Motif + X-Motif UIL 表 + X-Motif UIL 表格 + + + + + resource location + موقع المورد + pałažeńnie resursu + Местоположение на ресурс + localització de recurs + Umístění zdroje + resurseplacering + Ressourcenort + τοποθεσία πόρου + resource location + loko de risurco + ubicación del recurso + baliabidearen kokalekua + resurssisijainti + tilfeingisstaður + localisation de ressource + suíomh acmhainne + localización do recurso + מיקומו של המקור + erőforrás-hely + lokasi sumber daya + Posizione risorsa + リソースの場所 + ресурс орналасуы + 자원 위치 + resurso vieta + resursa atrašanās vieta + Lokasi sumber + ressurslokasjon + bronlocatie + ressursplassering + Położenie zasobu + localização de recurso + localização de recurso + locație de resursă + расположение ресурса + Umiestnenie zdroja + mesto vira + Pozicion rezerve + путања ресурса + resursplats + розташування ресурсу + địa điểm tài nguyên + 资源位置 + 資源位置 + + + + + XMI file + ملف XMI + Fajł XMI + Файл — XMI + fitxer XMI + Soubor XMI + XMI-fil + XMI-Datei + XMI file + XMI-dosiero + archivo XMI + XMI fitxategia + XMI-tiedosto + XMI fíla + fichier XMI + comhad XMI + ficheiro XMI + קובץ XMI + XMI fájl + Berkas XMI + File XMI + XMI ファイル + XMI файлы + XMI 파일 + XMI failas + XMI fails + XMI-fil + XMI-bestand + XMI-fil + Plik XMI + Arquivo XMI + Fișier XMI + файл XMI + Súbor XMI + Datoteka XMI + File XMI + XMI-fil + файл XMI + Tập tin XMI + XMI 文件 + XMI 檔 + XMI + XML Metadata Interchange + + + + + + + XSL FO file + ملف XSL FO + Fajł XSL FO + Форматиращ файл — XSL FO + fitxer FO XSL + Soubor XSL FO + XML FO-fil + XSL-FO-Datei + XSL FO file + XSL-FO-dosiero + archivo XSL FO + XSL FO fitxategia + XSL FO -tiedosto + XSL FO fíla + fichier XSL FO + comhad XSL FO + ficheiro XSL FO + קובץ XSL FO + XSL FO fájl + Berkas XSL FO + File XSL FO + XSL FO ファイル + XSL FO файлы + XSL 포매팅 개체 파일 + XSL FO failas + XSL FO fails + FO-fil for XSL + XSL FO-bestand + XSL FO-fil + Plik XSL FO + Arquivo XSL FO + Fișier XSL FO + файл XSL FO + Súbor XSL FO + Datoteka XSL FO + File XSL FO + XSL FO-fil + файл XSL FO + Tập tin FO của XSL (XFO) + XSL 格式化对象文件 + XSL FO 檔 + XSL FO + XSL Formatting Objects + + + + + + + iptables configuration file + ملف تضبيط iptables + kanfihuracyjny fajł iptables + Настройки за iptables + fitxer de configuració d'iptables + Soubor nastavení iptables + iptableskonfigurationsfil + iptables-Konfigurationsdatei + archivo de configuración de iptables + iptables konfigurazio-fitxategia + iptables-asetustiedosto + iptables samansetingarfíla + fichier de configuration iptables + comhad cumraíochta iptables + ficheiro de configuración de iptables + קובץ הגדרה של iptables + iptables beállítófájl + berkas konfigurasi iptables + File configurazione iptables + iptables 設定ファイル + iptables баптаулар файлы + iptables 설정 파일 + iptables konfigūracijos failas + iptables konfigurācijas fails + konfigurasjonsfil for iptables + iptables-configuratiebestand + iptables oppsettfil + Plik konfiguracji iptables + arquivo de configuração do iptables + fișier configurare iptables + конфигурационный файл iptables + Súbor nastavení iptables + nastavitvena datoteka iptables + File konfigurimi iptables + iptables-konfigurationsfil + файл налаштувань iptables + tập tin cấu hình iptables + iptables 防火墙配置文件 + iptables 組態檔 + + + + + + + + + + + + + + + + + + + + + + + + + XSLT stylesheet + نمط XSLT + Arkuš stylaŭ XSLT + Стилове — XSLT + full d'estil XSLT + Styl XSLT + XSLT-stilark + XSLT-Stylesheet + φύλλο στυλ XSLT + XSLT stylesheet + XSLT-stilfolio + hoja de estilo XSLT + XSLT estilo-orria + XSLT-tyylitiedosto + XSLT sniðark + feuille de style XSLT + stílbhileog XSLT + folla de estilo XSLT + סגנון גליון XSLT + XSLT-stíluslap + Lembar gaya XSLT + Foglio di stile XSLT + XSLT スタイルシート + XSLT стильдер кестесі + XSLT 스타일시트 + XSLT stiliaus aprašas + XSLT izklājlapa + Helaian Gaya XSLT + XSLT-stilark + XSLT-stijlblad + XSLT-stilark + Arkusz stylów XSLT + folha de estilos XSLT + Folha de estilo XSLT + Fișă de stil XSLT + таблица стилей XSLT + Štýl XSLT + Slogovna predloga XSLT + Fletë stili XSLT + Датотека са XSLT стилом + XSLT-stilmall + таблиця стилів XSLT + Tờ kiểu dáng XSLT + XSLT 样式表 + XSLT 樣式表 + XSLT + eXtensible Stylesheet Language Transformation + + + + + + + + + + + XMCD CD database + قاعدة بيانات XMCD CD + Baza źviestak ab dyskach XMCD + База от данни за CD-та — XMCD + base de dades de CD XMCD + Databáze XMCD CD + XMCD-cd-database + XMCD-CD-Datenbank + base de datos de CD XMCD + XMCD CD datu-basea + XMCD CD -tietokanta + XMCD fløgu dátustovnur + base de données de CD XMCD + bunachar sonraí XMCD CD + base de datos de CD XMCD + בסיס נתונים XMCD CD + XMCD CD-adatbázis + Basis data XMCD CD + Database XMCD CD + XMCD CD データベース + XMCD CD дерекқоры + XMCD CD 데이터베이스 + XMCD CD duomenų bazė + XMCD CD datubāze + XMCD CD-database + XMCD CD-gegevensbank + XMCD CD-database + Baza danych CD XMCD + Banco de dados de CD XMCD + Bază de date XMCD CD + база данных компакт-дисков XMCD + Databáza XMCD CD + Podatkovna zbirka XMCD CD + Bazë me të dhëna XMCD CD + XMCD cd-databas + база даних XMCD CD + Cơ sở dữ liệu CD XMCD + XMCD CD 数据库 + XMCD CD 資料庫 + + + + + + + XML document + مستند XML + Dakument XML + Документ — XML + document XML + Dokument XML + XML-dokument + XML-Dokument + XML document + XML-dokumento + documento XML + XML dokumentua + XML-asiakirja + XML skjal + document XML + cáipéis XML + documento XML + מסמך XML + XML dokumentum + Dokumen XML + Documento XML + XML ドキュメント + XML құжаты + XML 문서 + XML dokumentas + XML dokuments + XML-dokument + XML-document + XML-dokument + Dokument XML + Documento XML + Document XML + документ XML + Dokument XML + Dokument XML + Dokument XML + XML-dokument + документ XML + Tài liệu XML + XML 文档 + XML 文件 + XML + eXtensible Markup Language + + + + + + + + + + + + + + XML entities document + مستند كيانات XML + Dakument elementaŭ XML + Документ — заместващи последователности в XML + document d'entitats XML + Dokument entit XML + XML-enhedsdokument + XML-Dokument-Entitäten + documento de entidades XML + XML entitateen dokumentua + XML-entiteettiasiakirja + XML einindisskjal + document d'entités XML + cáipéis aonán XML + documento de entidades XML + מסמך ישיות XML + XML egyeddokumentum + Dokumen entitas XML + Documento entità XML + XML エントリドキュメント + XML мәндер құжаты + XML 엔티티 문서 + XML esybių dokumentas + XML vienību dokuments + XML-entitetsdokument + XML entiteiten-document + XML-entitet-dokument + Dokument jednostek XML + Documento de entidades XML + Document entități XML + файл сущностей XML + Dokument entít XML + Dokument XML določil + Dokument njësish XML + XML-entitetsdokument + документ об’єктів XML + Tài liệu thực thể XML + XML 特征文档 + XML 實體文件 + XML + eXtensible Markup Language + + + + + + + DV video + DV مرئي + Videa DV + Видео — DV + vídeo DV + Video DV + DV-video + DV-Video + DV video + DV-video + vídeo DV + DV bideoa + DV-video + DV video + vidéo DV + físeán DV + vídeo DV + וידאו DV + DV videó + Video DV + Video DV + DV 動画 + DV видеосы + DV 비디오 + DV vaizdo įrašas + DV video + DV-film + DV-video + DV-video + Plik wideo DV + Vídeo DV + Video DV + видео DV + Video DV + Video datoteka DV + Video DV + DV-video + відеокліп DV + Ảnh động DV + DV 视频 + DV 視訊 + DV + Digital Video + + + + + + + ISI video + مرئي ISI + ISI video faylı + Videa ISI + Видео — ISI + vídeo ISI + Video ISI + Fideo ISI + ISI-video + ISI-Video + βίντεο ISI + ISI video + ISI-video + vídeo ISI + ISI bideoa + ISI-video + ISI video + vidéo ISI + físeán ISI + vídeo ISI + וידאו ISI + ISI-videó + Video ISI + Video ISI + ISI 動画 + ISI видеосы + ISI 비디오 + ISI vaizdo įrašas + ISI video + Video ISI + ISI-film + ISI-video + ISI video + Plik wideo ISI + vídeoISI + Vídeo ISI + Video ISI + видео ISI + Video ISI + Video datoteka ISI + Video ISI + ISI видео + ISI-video + відеокліп ISI + Ảnh động ISI + ISI 视频 + ISI 視訊 + + + MPEG-2 transport stream + بث نقل MPEG-2 + Поток — транспорт по MPEG-2 + flux de transport MPEG-2 + Přenosový proud MPEG-2 + MPEG-2-transportstrøm + MPEG-2-Transportstrom + flujo de transporte MPEG-2 + MPEG-2 -siirtobittivirta + MPEG-2 flutningsstreymur + flux de transport MPEG-2 + Sruth aistrithe MPEG-2 + fluxo de transporte MPEG-2 + העברת זרימה של MPEG-2 + MPEG-2 átviteli adatfolyam + Stream transport MPEG-2 + Stream di trasporto MPEG-2 + MPEG-2 トランスポートストリーム + MPEG-2 көліктік ағыны + MPEG-2 전송 스트림 + MPEG-2 transportavimo srautas + MPEG-2 transporta straume + Strumień przesyłania MPEG-2 + Flux transport MPEG-2 + транспортный поток MPEG-2 + Pretočni vir prenosega MPEG + MPEG-2 transportström + потік передавання даних MPEG-2 + MPEG-2 传输流 + MPEG-2 傳輸串流 + MPEG-2 TS + Moving Picture Experts Group 2 Transport Stream + + + + + + + + + + + + + + + + MPEG video + MPEG مرئي + Videa MPEG + Видео — MPEG + vídeo MPEG + Video MPEG + MPEG-video + MPEG-Video + βίντεο MPEG + MPEG video + MPEG-video + vídeo MPEG + MPEG bideoa + MPEG-video + MPEG video + vidéo MPEG + físeán MPEG + vídeo MPEG + וידאו MPEG + MPEG-videó + Video MPEG + Video MPEG + MPEG 動画 + MPEG видеосы + MPEG 비디오 + MPEG vaizdo įrašas + MPEG video + Video MPEG + MPEG-film + MPEG-video + MPEG-video + Plik wideo MPEG + vídeo MPEG + Vídeo MPEG + Video MPEG + видео MPEG + Video MPEG + Video datoteka MPEG + Video MPEG + MPEG видео + MPEG-video + відеокліп MPEG + Ảnh động MPEG + MPEG 视频 + MPEG 視訊 + MPEG + Moving Picture Experts Group + + + + + + + + + + + + + + + + MPEG video (streamed) + Видео — MPEG, поточно + vídeo MPEG (flux) + Video MPEG (proud) + MPEG-Video (Datenstrom) + Vídeo MPEG (flujo) + MPEG-video (virtaus) + vidéo MPEG (flux) + vídeo MPEG (en stream) + קובץ MPEG (בהזרמה) + MPEG videó (szórt) + Video MPEG (di-stream-kan) + Video MPEG (streamed) + MPEG ビデオ(ストリーム) + MPEG видео (ағымдық) + MPEG 비디오 (스트리밍) + MPEG video (straumēts) + Plik wideo MPEG (strumień) + видео MPEG (потоковое) + MPEG-video (pretočni) + MPEG-video (strömmad) + відеокліп MPEG (потоковий) + MPEG 視訊 (串流) + + + + + + + + + + + QuickTime video + QuickTime مرئي + Videa QuickTime + Видео — QuickTime + vídeo QuickTime + Video QuickTime + QuickTime-video + QuickTime-Video + βίντεο QuickTime + QuickTime-video + vídeo QuickTime + QuickTime bideoa + QuickTime-video + QuickTime video + vidéo QuickTime + físeán QuickTime + vídeo QuickTime + וידאו של QuickTime + QuickTime videó + Video QuickTime + Video QuickTime + QuickTime 動画 + QuickTime видеосы + 퀵타임 비디오 + QuickTime vaizdo įrašas + QuickTime video + Video QuickTime + Quicktime film + QuickTime-video + QuickTime-video + Plik wideo QuickTime + vídeo QuickTime + Vídeo do QuickTime + Video QuickTime + видео QuickTime + Video QuickTime + Video datoteka QuickTime + Video QuickTime + QuickTime видео + QuickTime-video + відеокліп QuickTime + Ảnh động QuickTime + QuickTime 视频 + QuickTime 視訊 + + + + + + + + + + + + + QuickTime image + صورة QuickTime + Vyjava QuickTime + Изображение — QuickTime + imatge QuickTime + Obrázek QuickTime + QuickTime-billede + QuickTime-Bild + QuickTime-bildo + imagen QuickTime + QuickTime irudia + QuickTime-kuva + QuickTime mynd + image QuickTime + íomhá QuickTime + imaxe QuickTime + תמונה של QuickTime + QuickTime kép + Citra QuickTime + Immagine QuickTime + QuickTime 画像 + QuickTime суреті + 퀵타임 그림 + QuickTime paveikslėlis + QuickTime attēls + Quicktime bilde + QuickTime-afbeelding + QuickTime-bilete + Obraz QuickTime + Imagem do QuickTime + Imagine QuickTime + изображение QuickTime + Obrázok QuickTime + Slikovna datoteka QuickTime + Figurë QuickTime + QuickTime-bild + зображення QuickTime + Ảnh QuickTime + QuickTime 图像 + QuickTime 影像 + + + + + + + + Vivo video + Vivo مرئي + Vivo video faylı + Videa Vivo + Видео — Vivo + vídeo Vivo + Video Vivo + Fideo Vivo + Vivo-video + Vivo-Video + βίντεο Vivo + Vivo video + Vivo-video + vídeo Vivo + Vivo bideoa + Vivo-video + Vivo video + vidéo Vivo + físeán Vivo + vídeo Vivo + וידאו של Vivo + Vivo-videó + Video Vivo + Video Vivo + Vivo 動画 + Vivo видеосы + Vivo 비디오 + Vivo vaizdo įrašas + Vivo video + Video Vivo + Vivo-film + Vivo-video + Vivo-film + Plik wideo Vivo + vídeo Vivo + Vídeo Vivo + Video Vivo + видео Vivo + Video Vivo + Video datoteka Vivo + Video Vivo + Vivo видео + Vivo-video + відео Vivo + Ảnh động Vivo + Vivo 视频 + Vivo 視訊 + + + + + + Wavelet video + Wavelet مرئي + Wavelet video faylı + Videa Wavelet + Видео — Wavelet + vídeo Wavelet + Video Wavelet + Fideo Wavelet + Waveletvideo + Wavelet-Video + βίντεο Wavelet + Wavelet video + Wavelet-video + vídeo Wavelet + Wavelet bideoa + Wavelet-video + Wavelet video + vidéo Wavelet + físeán Wavelet + vídeo Wavelet + וידאו של Wavelet + Wavelet-videó + Video Wavelet + Video Wavelet + Wavelet 動画 + Wavelet видеосы + Wavelet 비디오 + Wavelet vaizdo įrašas + Wavelet video + Video Wavelet + Wavelet-film + Wavelet-video + Wavelet video + Plik wideo Wavelet + vídeo Wavelet + Vídeo Wavelet + Video Wavelet + видео Wavelet + Video Wavelet + Video datoteka Wavelet + Video Wavelet + Wavelet видео + Wavelet-video + відеокліп Wavelet + Ảnh động Wavelet + Wavelet 视频 + Wavelet 視訊 + + + ANIM animation + تحريكة ANIM + ANIM animasiyası + Animacyja ANIM + Анимация — ANIM + animació ANIM + Animace ANIM + Animeiddiad ANIM + ANIM-animation + ANIM-Animation + κινούμενο σχέδιο ANIM + ANIM animation + ANIM-animacio + animación ANIM + ANIM animazioa + ANIM-animaatio + ANIM teknmyndagerð + animation ANIM + beochan ANIM + animación ANIM + הנפשת ANIM + ANIM-animáció + Animasi ANIM + Animazione ANIM + ANIM アニメーション + ANIM анимациясы + ANIM 동화상 + ANIM animacija + ANIM animācija + Animasi ANIM + ANIM-animasjon + ANIM-animatie + ANIM-animasjon + Plik animacji ANIM + animação ANIM + Animação ANIM + Animație ANIM + анимация ANIM + Animácia ANIM + Datoteka animacije ANIM + Animim ANIM + ANIM анимација + ANIM-animering + анімація ANIM + Hoạt ảnh ANIM + ANIM 动画 + ANIM 動畫 + + + + FLIC animation + تحريكة FLIC + Animacyja FLIC + Анимация — FLIC + animació FLIC + Animace FLIC + FLIC-animation + FLIC-Animation + FLIC animation + animación FLIC + FLIC animazioa + FLIC-animaatio + FLIC teknimyndagerð + animation FLIC + beochan FLIC + animación FLIC + הנפשת FLIC + FLIC animáció + Animasi FLIC + Animazione FLIC + FLIC アニメーション + FLIC анимациясы + FLIC 동화상 + FLIC animacija + FLIC animācija + FLIC-animasjon + FLIC-animatie + FLIC-animasjon + Plik animacji FLIC + Animação FLIC + Animație FLIC + анимация FLIC + Animácia FLIC + Datoteka animacije FLIC + Animim FLIC + FLIC-animering + анімація FLIC + Hoạt ảnh FLIC + FLIC 动画 + FLIC 動畫 + + + + + + + + + + + Haansoft Hangul document + مستند Haansoft Hangul + Dakument Haansoft Hangul + Документ — Haansoft Hangul + document Haansoft Hangul + Dokument Haansoft Hangul + Haansoft Hangul-dokument + Haansoft-Hangul-Dokument + documento de Haansoft Hangul + Haansoft Hangul dokumentua + Haansoft Hangul -asiakirja + Haansoft Hangul skjal + document Haansoft Hangul + cáipéis Haansoft Hangul + documento de Haansoft Hangul + מסמך Haansoft Hangul + Haansoft hangul dokumentum + Dokumen Haansoft Hangul + Documento Haansoft Hangul + Haansoft Hangul ドキュメント + Haansoft Hangul құжаты + 한소프트 한글 문서 + Haansoft Hangul dokumentas + Haansoft Hangul dokuments + Haansoft Hangul-dokument + Haansoft Hangul-document + Haansoft Hangul-dokument + Dokument Haansoft Hangul + Documento do Haansoft Hangul + Document Haansoft Hangul + документ Haansoft Hangul + Dokument Haansoft Hangul + Dokument Haansoft Hangul + Dokument Haansoft Hangul + Haansoft Hangul-dokument + документ Haansoft Hangul + Tài liệu Hangul Haansoft + Haansoft Hangul 文档 + Haansoft 韓文文件 + + + + + + + + + Haansoft Hangul document template + قالب مستند Haansoft Hangul + Šablon dakumentu Haansoft Hangul + Шаблон за документи — Haansoft Hangul + plantilla de document Haansoft Hangul + Šablona dokumentu Haansoft Hangul + Haansoft Hangul-dokumentskabelon + Haansoft-Hangul-Dokumentvorlage + plantilla de documento de Haansoft Hangul + Haansoft Hangul dokumentuaren txantiloia + Haansoft Hangul -asiakirjamalli + Haansoft Hangul skjalaformur + modèle de document Haansoft Hangul + teimpléad cháipéis Haansoft Hangul + modelo de documento de Haansoft Hangul + תבנית מסמך של Haansoft Hangul + Haansoft hangul dokumentumsablon + Templat dokumen Haansoft Hangul + Modello documento Haansoft Hangul + Haansoft Hangul ドキュメントテンプレート + Haansoft Hangul құжат үлгісі + 한소프트 한글 문서 서식 + Haansoft Hangul dokumento šablonas + Haansoft Hangul dokumentu veidne + Haansoft Hangul-dokumentmal + Haansoft Hangul-documentsjabloon + Haansoft Hangul-dokumentmal + Szablon dokumentu Haansoft Hangul + Modelo de documento do Haansoft Hangul + Document șablon Haansoft Hangul + шаблон документа Haansoft Hangul + Šablóna dokumentu Haansoft Hangul + Predloga dokumenta Haansoft Hangul + Model dokumenti Haansoft Hangul + Haansoft Hangul-dokumentmall + шаблон документа Haansoft Hangul + Mẫu tài liệu Hangul Haansoft + Haansoft Hangul 文档模板 + Haansoft 韓文文件範本 + + + + + + MNG animation + تحريكة MNG + Animacyja MNG + Анимация — MNG + animació MNG + Animace MNG + MNG-animation + MNG-Animation + κινούμενα σχέδια MNG + MNG animation + MNG-animacio + animación MNG + MNG animazioa + MNG-animaatio + MNG teknimyndagerð + animation MNG + beochan MNG + animación MNG + הנפשת MNG + MNG-animáció + Animasi MNG + Animazione MNG + MNG アニメーション + MNG анимациясы + MNG 동화상 + MNG animacija + MNG animācija + Animasi MNG + MNG-animasjon + MNG-animatie + MNG-animasjon + Animacja MNG + animação MNG + Animação MNG + Animație MNG + анимация MNG + Animácia MNG + Datoteka animacije MNG + Animim MNG + MNG анимација + MNG-animering + анімація MNG + Hoạt ảnh MNG + MNG 动画 + MNG 動畫 + MNG + Multiple-Image Network Graphics + + + + ASF video + ASF مرئي + Videa ASF + Видео — ASF + vídeo ASF + Video ASF + ASF-video + ASF-Video + ASF video + ASF-video + vídeo ASF + ASF bideoa + ASF-video + ASF video + vidéo ASF + físeán ASF + vídeo ASF + וידאו ASF + ASF videó + Video ASF + Video ASF + ASF 動画 + ASF видеосы + ASF 비디오 + ASF vaizdo įrašas + ASF video + ASF-film + ASF-video + ASF-video + Plik wideo ASF + Vídeo ASF + Video ASF + видео ASF + Video ASF + Video datoteka ASF + Video ASF + ASF-video + відеокліп ASF + Ảnh động ASF + ASF 视频 + ASF 視訊 + ASF + Advanced Streaming Format + + + + + + + + + + Windows Media Station file + ملف محطة Windows Media + Fajł Windows Media Station + Файл — Windows Media Station + fitxer Windows Media Station + Soubor Windows Media Station + Windows Media Station-fil + Windows-Media-Streamingbeschreibung + archivo de emisora de Windows Media + Windows Media Station fitxategia + Windows Media Station-tiedosto + Windows Media Station fíla + fichier Windows Media Station + comhad Windows Media Station + ficheiro de emisora de Windows Media + קובץ תחנה של Windows Media + Windows Media Station fájl + Berkas Windows Media Station + File Windows Media Station + Windows Media Station ファイル + Windows Media Station файлы + 윈도우 미디어 방송국 파일 + Windows Media Station failas + Windows Media Station fails + Windows Media Station-fil + Windows Media Station-bestand + Windows Media Station-fil + Plik Windows Media Station + Arquivo de estação de mídia do Windows + Fișier Windows Media Station + файл Windows Media Station + Súbor Windows Media Station + Datoteka Windows Media Station + File Windows Media Station + Windows Media Station-fil + файл Windows Media Station + Tập tin Windows Media Station + Windows 媒体工作站文件 + Windows Media Station 檔 + + + + + + + + + Windows Media video + Windows Media مرئي + Videa Windows Media + Видео — Windows Media + vídeo Windows Media + Video Windows Media + Windows Medie-video + Windows-Media-Video + vídeo de Windows Media + Windows Media bideoa + Windows Media -video + Windows Media video + vidéo Windows Media + físeán Windows Media + vídeo de Windows Media + וידאו של Windows Media + Windows Media videó + Video Windows Media + Video Windows Media + Windows Media 動画 + Windows Media видеосы + 윈도우 미디어 비디오 + Windows Media vaizdo įrašas + Windows Media video + Windows Media film + Windows Media-video + Windows Media-video + Plik wideo Windows Media + Vídeo do Windows Media + Video Windows Media + видео Windows Media + Video Windows Media + Video datoteka Windows Media + Video Windows Media + Windows Media-video + відеокліп Windows Media + Ảnh động Windows Media + Windows Media 视频 + Windows Media 視訊 + + + + + AVI video + AVI مرئي + AVI video faylı + Videa AVI + Видео — AVI + vídeo AVI + Video AVI + Fideo AVI + AVI-video + AVI-Video + βίντεο AVI + AVI video + AVI-video + vídeo AVI + AVI bideoa + AVI-video + AVI video + vidéo AVI + físeán AVI + vídeo AVI + וידאו AVI + AVI-videó + Video AVI + Video AVI + AVI 動画 + AVI видеосы + AVI 비디오 + AVI vaizdo įrašas + AVI video + Video AVI + AVI-film + AVI-video + AVI-video + Plik wideo AVI + vídeo AVI + Vídeo AVI + Video AVI + видео AVI + Video AVI + Video datoteka AVI + Video AVI + AVI видео + AVI-video + відеокліп AVI + Ảnh động AVI + AVI 视频 + AVI 視訊 + AVI + Audio Video Interleave + + + + + + + + + + + + + + + NullSoft video + NullSoft مرئي + Videa NullSoft + Видео — NullSoft + vídeo NullSoft + Video NullSoft + NullSoft-video + NullSoft-Video + NullSoft-video + vídeo NullSoft + NullSoft bideoa + NullSoft-video + NullSoft video + vidéo NullSoft + físeán NullSoft + vídeo de NullSoft + וידאו של NullSot + NullSoft videó + Video NullSoft + Video NullSoft + NullSoft 動画 + NullSoft видеосы + 널소프트 비디오 + NullSoft vaizdo įrašas + NullSoft video + Nullsoft-film + NullSoft-video + NullSoft-video + Plik wideo NullSoft + Vídeo do Nullsoft + Video NullSoft + видео Nullsoft + Video NullSoft + Video datoteka NullSoft + Video NullSoft + NullSoft-video + відеокліп NullSoft + Ảnh động NullSoft + Nullsoft 视频 + NullSoft 視訊 + + + + + + + SDP multicast stream file + ملف دفق متعدد البث SDP + Šmatadrasny płynievy fajł SDP + Файл за поток — SDP multicast + fitxer de flux de multidifusió SDP + Soubor vícesměrového vysílání proudu SDP + SDP multicast-strømfil + SDP-Multicast-Datenstromdatei + archivo de flujo multicast SDP + SDP multicast korrontearen fitxategia + SDP-monilähetysvirran tiedosto + SDP margvarpað streymafíla + fichier de flux multidiffusion SDP + comhad shruth ilchraolacháin SDP + ficheiro de fluxo multicast SDP + קובץ שידור בזרימה SDP + SDP multicast műsorfájl + Berkas SDP multicast stream + File stream multicast SDP + SDP マルチキャストストリームファイル + SDP мультикаст ағым файлы + SDP 멀티캐스트 스트림 파일 + SDP daugiaadresio srauto failas + SDP multiraides straumes fails + SDP-multicaststrøm + SDP-multicast-streambestand + SDP multicast straumfil + Plik strumienia multicast SDP + Arquivo de canal multicast SDP + Fișier flux multicast SDP + файл мультикаст-потока SDP + Súbor viacsmerového vysielania prúdu SDP + Pretočni vir večsmernega oddajanja + File stream multicast SDP + SDP multicast stream-fil + файл потокової трансляції SDP + Tập tin luồng truyền một-nhiều SDP + SDP 多播流文件 + SDP + Session Description Protocol + + + + + + + + + + + + SGI video + SGI مرئي + SGI video faylı + Videa SGI + Видео — SGI + vídeo SGI + Video SGI + Video SGI + SGI-video + SGI-Video + βίντεο SGI + SGI video + SGI-video + vídeo SGI + SGI bideoa + SGI-video + SGI video + vidéo SGI + físeán SGI + vídeo SGI + וידאו SGI + SGI-videó + Video SGI + Video SGI + SGI 動画 + SGI видеосы + SGI 비디오 + SGI vaizdo įrašas + SGI video + Video SGI + SGI-film + SGI-video + SGI-video + Plik wideo SGI + vídeo SGI + Vídeo SGI + Video SGI + видео SGI + Video SGI + Video datoteka SGI + Video SGI + SGI видео + SGI-video + відеокліп SGI + Ảnh động SGI + SGI 视频 + SGI 視訊 + + + + + + + eMusic download package + حزمة تنزيل eMusic + pakunak zahruzki eMusic + Пакет за сваляне — eMusic + paquet de descàrrega eMusic + Balíček stahování eMusic + eMusic-hentpakke + eMusic-Download-Paket + paquete de descarga eMusic + eMusic deskargaren paketea + eMusic-imurointipaketti + eMusic niðurtøkupakki + paquet de téléchargement eMusic + pacáiste íosluchtú eMusic + paquete de descarga de eMusic + חבילת הורדה של eMusic + eMusic letöltési csomag + paket unduh eMusic + Pacchetto scaricamento eMusic + eMusic ダウンロードパッケージ + eMusic жүктемелер дестесі + eMusic 다운로드 패키지 + eMusic atsiuntimo paketas + eMusic lejupielādes paciņa + eMusic nedlastingspakke + eMusic-downloadpakket + eMusic nedlastingspakke + Pobieralny pakiet eMusic + Pacote de download do eMusic + pachet descărcare eMusic + пакет загрузок eMusic + Balíček sťahovania eMusic + Datoteka paketa eMusic + Paketë shkarkimi eMusic + eMusic-hämtningspaket + пакунок завантаження eMusic + gói nhạc tải xuống eMusic + eMusic 下载包 + eMusic 下載套件 + + + + + + + + KML geographic data + بيانات جغرافية KML + Географски данни — KML + dades geogràfiques KML + Geografická data KML + Geografiske data i KML-format + KML geographische Daten + datos geográficos KML + KML datu geografikoak + KML landafrøðilig dáta + données géographiques KML + sonraí geografacha KML + datos xeográficos KML + מידע גאוגרפי KML + KML földrajzi adatok + Data geografis KML + Dati geografici KML + KML 地理データ + KML географилық ақпараты + KML 지리 정보 데이터 + KML geografiniai duomenys + KML ģeogrāfiskie dati + Dane geograficzne KML + Date geografice KML + географические данные KML + Zemepisné údaje KML + Datoteka geografskih podatkov KML + KML geografisk data + географічні дані KML + KML 地理数据 + KML 地理資料 + KML + Keyhole Markup Language + + + + + + KML geographic compressed data + بيانات جغرافية مضغوطة KML + Географски данни — KML, компресирани + dades geogràfiques comprimides KML + Komprimovaná geografická data KML + KML-geografiske komprimerede data + KML geographische komprimierte Daten + datos geográficos comprimidos KML + KML datu geografiko konprimituak + KML landafrøðilig stappað dáta + données géographiques KML compressées + sonraí comhbhrúite geografacha KML + datos xeográficos KML comprimidos + מידע גאוגרפי דחוס KML + KML tömörített földrajzi adatok + Data geografis KML terkompresi + Dati geografici KML compressi + KML 地理圧縮データ + KML географиялық сығылған ақпарат + KML 지리 정보 압축 데이터 + KML geografiniai suglaudinti duomenys + KML saspiesti ģeogrāfiskie dati + Skompresowane dane geograficzne KML + Date geografice comprimate KML + сжатые географические данные KML + Komprimované zemepisné údaje KML + Skrčeni geografski podatki KML + KML geografiskt komprimerat data + стиснуті географічні дані KML + KML 压缩地理数据 + KML 地理壓縮資料 + KML + Keyhole Markup Language + + + + + Citrix ICA settings file + ملف إعدادات Citrix ICA + Fajł naładaŭ Citrix ICA + Настройки — Citrix ICA + fitxer de paràmetres de Citrix ICA + Soubor nastavení Citrix ICA + Citrix ICA-opsætningsfil + Citrix-ICA-Einstellungsdatei + archivo de opciones de Citrix ICA + Citrix ICA ezarpenen fitxategia + Citrix ICA -asetustiedosto + Citrix ICA stillingarfíla + fichier de paramètres ICA Citrix + comhad socruithe Citrix ICA + ficheiro de configuracións de Citrix ICA + קובץ הגדרות של Citrix ICA + Citrix ICA beállításfájl + Berkas penataan Citrix ICA + File impostazioni Citrix ICA + Citrix ICA 設定ファイル + Citrix ICA баптаулар файлы + 시트릭스 ICA 설정 파일 + Citrix ICA parametrų failas + Citrix ICA iestatījumu fails + Innstillingsfil for Citrix ICA + Citrix ICA-instellingen + Citrix ICA-innstillingsfil + Plik ustawień Citrix ICA + Arquivo de configurações do Citrix ICA + Fișier de configurări Citrix ICA + файл настроек Citrix ICA + Súbor nastavení Citrix ICA + Nastavitvena datoteka Citrix ICA + File rregullimesh Citrix ICA + Citrix ICA-inställningsfil + файл параметрів ICA Citrix + Tập tin thiết lập ICA Citrix + Citrix ICA 设置文件 + Citrix ICA 設定值檔案 + ICA + Independent Computing Architecture + + + + + + XUL interface document + مستند واجهة XUL + Interfejsny dakument XUL + Документ — интерфейс за XUL + document d'interfície XUL + Dokument rozhraní XUL + XUL-grænsefladedokument + XUL-Oberflächendokument + documento de interfaz XUL + XUL interfazearen dokumentua + XUL-käyttöliittymäasiakirja + XUL markamótsskjal + document d'interface XUL + cáipéis chomhéadan XUL + documento de interface XUL + מסמך ממשק XUL + XUL-felületdokumentum + Dokumen antarmuka XUL + Documento interfaccia XUL + XUL インターフェイスドキュメント + XUL интерфейс құжаты + XUL 인터페이스 문서 + XUL sąsajos dokumentas + XUL saskarnes dokuments + XUL-grensesnittdokument + XUL-interface-document + XUL-grensesnitt-dokument + Dokument interfejsu XUL + Documento de interface XUL + Document interfață XUL + документ интерфейса XUL + Dokument rozhrania XUL + Dokument vmesnika XUL + Dokument interfaqe XUL + XUL-gränssnittsdokument + документ інтерфейсу XUL + Tài liệu giao diện XUL + XUL 界面文档 + XUL 介面文件 + XUL + XML User interface markup Language + + + + + + + XPInstall installer module + وحدة مثبت XPInstall + Пакет — инсталация XPInstall + mòdul instal·lador d'XPinstall + Modul instalátoru XPInstall + XPInstall-installationsmodul + XPInstall-Installermodul + módulo del instalador XPInstall + XPInstall instalatzailearen modulua + XPInstall-asennuspaketti + XPInstall innleggjaramótul + module d'installation XPInstall + modúl suiteála XPInstall + Módulo do instalador XPInstall + מודול התקנה של XPInstall + XPInstall telepítőmodul + Modul installer XPInstall + Modulo installatore XPInstall + XPInstall インストーラモジュール + XPInstall орнату модулі + XPInstall 설치 프로그램 모듈 + XPInstall įdiegiklio modulis + XPInstall instalatora modulis + Moduł instalatora XPInstall + Modul de instalare XPInstall + модуль установщика XPInstall + Modul inštalátora XPInstall + modul namestilnika XPInstall + XPInstall-installeringsmodul + модуль засобу встановлення XPInstall + XPInstall 安装工具模块 + XPInstall 安裝程式模組 + + + + + Word 2007 document + مستند Word 2007 + Документ — Word 2007 + document de Word 2007 + Dokument Word 2007 + Word 2007-dokument + Word-2007-Dokument + documento de Word 2007 + Word 2007 dokumentua + Word 2007 -asiakirja + Word 2007 skjal + document Word 2007 + cáipéis Word 2007 + documento de Word 2007 + מסמך Word 2007 + Word 2007 dokumentum + Dokumen Word 2007 + Documento Word 2007 + Word 2007 ドキュメント + Word 2007 құжаты + 워드 2007 문서 + Word 2007 dokumentas + Word 2007 dokuments + Word 2007-document + Dokument Word 2007 + Documento do Word 2007 + Document Word 2007 + документ Word 2007 + Dokument Word 2007 + Dokument Word 2007 + Word 2007-dokument + документ Word 2007 + Tài liệu Word 2007 + Microsoft Word 2007 文档 + Word 2007 文件 + + + + + + Word 2007 document template + Шаблон за документи — Word 2007 + plantilla de document de Word 2007 + Šablona dokumentu Word 2007 + Word 2007-Dokumentvorlage + Plantilla de documento de Word 2007 + Word 2007 -asiakirjamalli + modèle de document Word 2007 + Plantilla de documento de Word 2007 + תבנית מסמך של Word 2007 + Word 2007 dokumentumsablon + Templat dokumen Word 2007 + Modello documento Word 2007 + Word 2007 文書テンプレート + Word 2007 құжатының үлгісі + 워드 2007 문서 서식 + Word 2007 dokumenta veidne + Szablon dokumentu Word 2007 + шаблон документа Word 2007 + Predloga dokumenta Word 2007 + Word 2007-dokumentmall + шаблон документа Word 2007 + Word 2007 文件範本 + + + + + + PowerPoint 2007 presentation + عرض تقديمي PowerPoint 2007 + Презентация — PowerPoint 2007 + presentació de PowerPoint 2007 + Prezentace PowerPoint 2007 + PowerPoint 2007-præsentation + PowerPoint-2007-Präsentation + presentación de PowerPoint 2007 + PowerPoint 2007 aurkezpena + PowerPoint 2007 -esitys + PowerPoint 2007 framløga + présentation PowerPoint 2007 + láithreoireacht PowerPoint 2007 + presentación de PowerPoint 2007 + מצגת של PowerPoint 2007 + PowerPoint 2007 prezentáció + Presentasi PowerPoint 2007 + Presentazione standard PowerPoint 2007 + PowerPoint 2007 プレゼンテーション + PowerPoint 2007 презентациясы + 파워포인트 2007 프리젠테이션 + PowerPoint 2007 pateiktis + PowerPoint 2007 prezentācija + PowerPoint 2007-presentatie + Prezentacja PowerPoint 2007 + Apresentação do PowerPoint 2007 + Prezentare PowerPoint 2007 + презентация PowerPoint 2007 + Prezentácia PowerPoint 2007 + Predstavitev Microsoft PowerPoint 2007 + PowerPoint 2007-presentation + презентація PowerPoint 2007 + Trình diễn PowerPoint 2007 + Microsoft PowerPoint 2007 演示文稿 + PowerPoint 2007 簡報 + + + + + + PowerPoint 2007 slide + Кадър — PoerPoint 2007 + dispositiva de PowerPoint 2007 + Snímek PowerPoint 2007 + PowerPoint 2007-Folie + Diapositiva de PowerPoint 2007 + diapositive PowerPoint 2007 + Diaporama de PowerPoint 2007 + שקופית של PowerPoint 2007 + PowerPoint 2007 dia + Slide PowerPoint 2007 + Diapositiva PowerPoint 2007 + PowerPoint 2007 スライド + PowerPoint 2007 слайды + 파워포인트 2007 슬라이드 + PowerPoint 2007 slaids + Slajd PowerPoint 2007 + слайд PowerPoint 2007 + Prosojnica PowerPoint 2007 + слайд PowerPoint 2007 + PowerPoint 2007 文稿 + PowerPoint 2007 投影片 + + + + + + PowerPoint 2007 show + عرض PowerPoint 2007 + Презентация-шоу — PowerPoint 2007 + exposició de PowerPoint 2007 + Prezentace PowerPoint 2007 + PowerPoint 2007-dias + PowerPoint-2007-Präsentation + exposición de PowerPoint 2007 + PowerPoint 2007 ikuskizuna + PowerPoint 2007 -diaesitys + PowerPoint 2007 framsýning + diaporama PowerPoint 2007 + taispeántas PowerPoint 2007 + Exposición de PowerPoint 2007 + תצוגה של PowerPoint 2007 + PowerPoint 2007 bemutató + Presentasi PowerPoint 2007 + Solo presentazione PowerPoint 2007 + PowerPoint 2007 プレゼンテーション + PowerPoint 2007 көрсетілімі + 파워포인트 2007 쇼 + PowerPoint 2007 pateiktis + PowerPoint 2007 slīdrāde + Pokaz PowerPoint 2007 + Prezentare PowerPoint 2007 + презентация PowerPoint 2007 + Ukážka PowerPoint 2007 + Zagonska predstavitev PowerPoint 2007 + PowerPoint 2007-visning + показ слайдів PowerPoint 2007 + Microsoft PowerPoint 2007 演示文稿 + PowerPoint 2007 展示 + + + + + + PowerPoint 2007 presentation template + Шаблон за презентации — PowerPoint 2007 + plantilla de presentació de PowerPoint 2007 + Šablona prezentace PowerPoint 2007 + PowerPoint 2007-Präsentationsvorlage + Plantilla de presentación de PowerPoint 2007 + PowerPoint 2007 -esitysmalli + modèle de présentation PowerPoint 2007 + modelo de presentación de PowerPoint 2007 + תבנית למצגת של PowerPoint 2007 + PowerPoint 2007 bemutatósablon + Templat presentasi PowerPoint 2007 + Modello presentazione PowerPoint 2007 + PowerPoint 2007 プレゼンテーションテンプレート + PowerPoint 2007 презентация шаблоны + 파워포인트 2007 프리젠테이션 서식 + PowerPoint 2007 prezentācijas veidne + Szablon prezentacji PowerPoint 2007 + шаблон презентации PowerPoint 2007 + Predloga predstavitve PowerPoint 2007 + PowerPoint 2007-presentationsmall + шаблон презентації PowerPoint 2007 + PowerPoint 2007 簡報範本 + + + + + + Excel 2007 spreadsheet + جدول Excel 2007 + Таблица — Excel 2007 + full de càlcul d'Excel 2007 + Sešit Excel 2007 + Excel 2007-regneark + Excel-2007-Tabelle + hoja de cálculo de Excel 2007 + Excel 2007 kalkulu-orria + Excel 2007 -taulukko + Excel 2007 rokniark + feuille de calcul Excel 2007 + scarbhileog Excel 2007 + folla de cálculo de Excel 2007 + גליון נתונים של אקסל 2007 + Excel 2007 táblázat + Lembar sebar Excel 2007 + Foglio di calcolo Excel 2007 + Excel 2007 スプレッドシート + Excel 2007 электрондық кестесі + 엑셀 2007 스프레드시트 + Excel 2007 skaičialentė + Excel 2007 izklājlapa + Excel 2007-rekenblad + Arkusz Excel 2007 + Planilha do Excel 2007 + Foaie de calcul Excel 2007 + электронная таблица Excel 2007 + Zošit Excel 2007 + Razpredelnica Microsoft Excel 2007 + Excel 2007-kalkylblad + ел. таблиця Excel 2007 + Bảng tính Excel 2007 + Microsoft Excel 2007 工作簿 + Excel 2007 試算表 + + + + + + Excel 2007 spreadsheet template + Шаблон за таблици — Excel 2007 + plantilla de full de càlcul d'Excel 2007 + Šablona sešitu Excel 2007 + Excel 2007-Datenblattvorlage + Plantilla de hoja de cálculo Excel 2007 + Excel 2007 -taulukkomalli + modèle de feuille de calcul Excel 2007 + modelo de folla de cálculo Excel 2007 + תבנית של גיליון נתונים של Excel 2007 + Excel 2007 táblázatsablon + Templat lembar kerja Excel 2007 + Modello foglio di calcolo Excel 2007 + Excel 2007 スプレッドシートテンプレート + Excel 2007 кесте шаблоны + 엑셀 2007 스프레드쉬트 + Excel 2007 izklājlapas veidne + Szablon arkusza Excel 2007 + шаблон электронной таблицы Excel 2007 + Predloga razpredelnice Excel 2007 + Excel 2007-kalkylarksmall + шаблон електронної таблиці Excel 2007 + Excel 2007 試算表範本 + + + + + + T602 document + مستند T602 + Dakument T602 + Документ — T602 + document T602 + Dokument T602 + T602-dokument + T602-Dokument + T602-dokumento + documento T602 + T602 dokumentua + T602-asiakirja + T602 skjal + document T602 + cáipéis T602 + documento T602 + מסמך T602 + T602 dokumentum + Dokumen T602 + Documento T602 + T602 ドキュメント + T602 құжаты + T602 문서 + T602 dokumentas + T602 dokuments + T602-dokument + T602-document + T602-dokument + Dokument T602 + Documento T602 + Document T602 + документ T602 + Dokument T602 + Dokument T602 + Dokument T602 + T602-dokument + документ T602 + Tài liệu T602 + T602 文档 + T602 文件 + + + + + + + + + + Cisco VPN Settings + إعدادات Cisco VPN + Nałady Cisco VPN + Настройки — ВЧМ на Cisco + paràmetres VPN de Cisco + Nastavení Cisco VPN + Cisco VPN-opsætning + Cisco-VPN-Einstellungen + configuración VPN de Cisco + Cisco VPN ezarpenak + Cisco VPN -asetukset + Cisco VPN stillingar + paramètres VPN Cisco + socruithe VPN Cisco + configuracións de VPN de Cisco + הגדרות של Cisco VPN + Cisco VPN beállítások + Penataan Cisco VPN + Impostazioni VPN Cisco + Cisco VPN 設定 + Cisco VPN баптаулары + Cisco VPN 설정 + Cisco VPN parametrai + Cisco VPN iestatījumi + Cisco VPN-innstillinger + Cisco VPN-instellingen + Cisco VPN-innstillingar + Ustawienia VPN Cisco + Configurações de VPN da Cisco + Configurări VPN Cisco + файл настроек Cisco VPN + Nastavenia Cisco VPN + Datoteka nastavitev Cisco VPN + Rregullime VPN Cisco + Cisco VPN-inställningar + параметри VPN Cisco + Thiết lập VPN Cisco + Cisco VPN 设置 + Cisco VPN 設定值 + + + + + + + + + + ICC profile + تشكيلة OCL + Цветови профил — OCL + perfil ICC + Profil ICC + ICC-profil + ICC-Profil + ICC-profilo + perfil ICC + ICC profila + ICC-profiili + ICC umhvarv + profil ICC + próifíl ICC + perfíl ICC + פרופיל ICC + ICC profil + Profil ICC + Profilo ICC + ICC プロファイル + ICC профайлы + ICC 프로파일 + ICC profilis + ICC profils + Profil ICC + Profil ICC + профиль ICC + Profil farieb ICC + Datoteka profila ICC + ICC-profil + профіль ICC + ICC 文件 + ICC 設定檔 + + + + + + + + IT 8.7 color calibration file + ملف ضبط ألوان IT 8.7 + Файл за цветово калибриране — IT 8.7 + fitxer de calibratge de color IT 8.7 + Soubor kalibrace barev IT 8.7 + IT 8.7 farvekalibreringsfil + IT 8.7 Farbkalibrierungsdatei + archivo de calibración de color IT 8.7 + IT 8.7 kolore-kalibrazioaren fitxategia + IT 8.7 -värikalibrointitiedosto + IT 8.7 litstillingarfíla + fichier de calibration couleur IT 8.7 + comhad calabraithe dathanna IT 8.7 + ficheiro de calibración de cor IT 8.7 + קובץ כיול צבע IT 8.7 + IT 8.7 színkalibrációs fájl + Berkas kalibrasi warna IT 8.7 + File calibrazione colore IT 8.7 + IT 8.7 カラーキャリブレーションファイル + IT 8.7 түс баптау файлы + IT 8.7 색 조율 파일 + IT 8.7 spalvų kalibravimo failas + IT 8.7 krāsu kalibrācijas fails + Plik kalibracji kolorów IT 8.7 + Fișier de calibrare a culorii IT 8.7 + файл калибровки цвета IT 8.7 + Umeritvena datoteka barve IT 8.7 + IT 8.7-färgkalibreringsfil + файл калібрування кольорів IT 8.7 + IT 8.7 色彩校准文件 + IT 8.7 色彩校正檔 + + + + + + + + + + + + digital photos + الصور الرقمية + ličbavyja zdymki + Цифрови фотографии + fotos digitals + Digitální fotografie + digitale billeder + Digitale Fotos + fotos digitales + argazki digitalak + digivalokuvia + talgildar myndir + photos numériques + grianghraif dhigiteacha + fotos dixitais + תמונות דיגיטליות + digitális fényképek + foto digital + Foto digitali + デジタルフォト + сандық фотосуреттер + 디지털 사진 + skaitmeninės nuotraukos + digitāla fotogrāfija + digitale foto's + digitale fotografi + Zdjęcia cyfrowe + fotos digitais + fotografii digitale + цифровые фотографии + Digitálne fotografie + digitalne fotografije + Fotografi dixhitale + digitalbilder + цифрові фотографії + ảnh chụp số + 数字化图像 + 數位相片 + + + + + + + + Video CD + Video CD + Videa CD + CD — видео + Video CD + Video CD + Video-cd + Video-CD + Video-KD + Video CD + Bideo CDa + Video CD + Video CD + CD vidéo + Video CD + Video CD + תקליטור וידאו + Video CD + Video CD + Video CD + ビデオ CD + видео CD + 비디오 CD + Vaizdo CD + Video CD + video-CD + Video-CD + Video CD + CD de vídeo + CD video + видеодиск VCD + Video CD + Video CD + CD Video + Video-cd + Video CD + Đĩa CD ảnh động + VCD + Video CD + + + + + + + + Super Video CD + Super Video CD + Super Video CD + CD — супер видео + Super Video CD + Super Video CD + Super Video-cd + Super-Video-CD + Super-Video-KD + Super Video CD + Super Bideo CDa + Super Video CD + Super Video CD + Super VCD + Super Video CD + Super vídeo CD + Super Video CD + Super Video CD + Super Video CD + Super Video CD + スーパービデオ CD + Super Video CD + 슈퍼 비디오 CD + Super vaizdo CD + Super Video CD + super-video-CD + Super Video-CD + Super Video CD + CD de Super Vídeo (SVCD) + Super Video CD + компакт-диск Super Video + Super Video CD + Super Video CD + CD Super Video + Super Video CD + Super Video CD + Đĩa CD siêu ảnh động + SVCD + Super Video CD + + + + + + + + video DVD + DVD مرئي + videa DVD + DVD — видео + vídeo DVD + DVD-Video + video-dvd + Video-DVD + video-DVD + DVD de vídeo + bideo DVDa + video-DVD + video DVD + DVD vidéo + DVD físe + DVD de vídeo + DVD וידאו + video DVD + DVD video + DVD video + ビデオ DVD + видео DVD + 비디오 CD + vaizdo DVD + video DVD + video-DVD + Video-DVD + DVD-Video + DVD de vídeo + DVD video + видео-DVD + DVD-Video + video DVD + DVD video + video-dvd + відео-DVD + đĩa DVD ảnh động + 视频 DVD + 視訊 DVD + + + + + + + + + + + audio CD + CD سمعي + aŭdyjo CD + CD — аудио + CD d'àudio + Zvukové CD + lyd-cd + Audio-CD + Son-KD + CD de sonido + Audio CDa + ääni-CD + audio CD + CD audio + dlúthdhiosca fuaime + CD de son + תקליטור שמע + hang CD + CD audio + CD audio + オーディオ CD + аудио CD + 오디오 CD + garso CD + audio CD + audio-CD + lyd-CD + CD-Audio + CD de áudio + CD audio + звуковой CD + Zvukové CD + zvočni CD + CD audio + ljud-cd + звуковий CD + đĩa CD âm thanh + 音频 CD + 音訊 CD + + + + + blank CD disc + قرص CD فارغ + čysty dysk CD + CD — празно + disc CD en blanc + Prázdný disk CD + tom cd-disk + Leere CD + disco CD virgen + CD disko hutsa + tyhjä CD-levy + blonk fløga + CD vierge + dlúthdhiosca folamh + disco de CD en brancho + תקליטור ריק + üres CD-lemez + cakram CD kosong + Disco vuoto CD + ブランク CD ディスク + таза CD дискі + 빈 CD 디스크 + tuščias CD diskas + tukšs CD disks + blanco CD + tom CD-plate + Pusta płyta CD + Disco CD virgem + disc gol CD + чистый компакт-диск + Prázdny disk CD + prazen CD disk + Disk bosh CD + tom cd-skiva + порожній компакт-диск + đĩa CD trống + 空 CD 光盘 + 空白 CD 光碟 + + + + + blank DVD disc + قرص DVD فارغ + čysty dysk DVD + DVD — празно + disc DVD en blanc + Prázdný disk DVD + tom dvd-disk + Leere DVD + disco DVD virgen + DVD disko hutsa + tyhjä DVD-levy + blonk margfløga + DVD vierge + DVD folamh + disco de DVD en branco + תקליטור DVD ריק + üres DVD-lemez + cakram DVD kosong + Disco vuoto DVD + ブランク DVD ディスク + таза DVD дискі + 빈 DVD 디스크 + tuščias DVD diskas + tukšs DVD disks + blanco DVD + tom DVD-plate + Pusta płyta DVD + Disco DVD virgem + disc gol DVD + чистый диск DVD + Prázdny disk DVD + prazen DVD disk + Disk bosh DVD + tom dvd-skiva + порожній диск DVD + đĩa DVD trống + 空 DVD 光盘 + 空白 DVD 光碟 + + + + + blank Blu-ray disc + قرص بلو-راي فارغ + čysty dysk Blu-ray + Blu-ray — празно + disc Blu-Ray en blanc + Prázdný disk Blu-ray + tom Blu-ray-disk + Leeres Blu-Ray-Medium + disco Blu-ray virgen + Blu-ray disko hutsa + tyhjä Blu-ray-levy + blankur Blu-ray diskur + disque Blu-Ray vierge + diosca folamh Blu-Ray + disco Blu-ray en branco + תקליטור בלו־ריי ריק + üres Blu-Ray lemez + cakram Blu-ray kosong + Disco vuoto Blu-ray + ブランク Blu-ray ディスク + таза Blu-ray дискі + 빈 블루레이 디스크 + tuščias Blu-ray diskas + tukšs Blu-ray disks + blanco Blu-ray-disk + tom Blu-Ray-plate + Pusta płyta Blu-ray + Disco Blu-Ray virgem + disc gol Blu-ray + чистый диск Blu-ray + Prázdny disk Blu-ray + prazen Blu-Ray disk + Disk bosh Blu-ray + tom Blu-ray-skiva + порожній диск Blu-ray + đĩa Blu-ray trống + 空蓝光 DVD + 空白 Blu-ray 光碟 + + + + + blank HD DVD disc + قرص HD DVD فارغ + čysty dysk HD DVD + HD DVD — празно + disc DVD HD en blanc + Prázdný disk HD DVD + tom HD dvd-disk + Leere HD-DVD + disco HD DVD virgen + HD DVD disko hutsa + tyhjä HD DVD -levy + blankur HD DVD diskur + disque HD-DVD vierge + HD DVD folamh + disco de HD DVD en branco + דיסק HD DVD ריק + üres HD DVD-lemez + cakram HD DVD kosong + Disco vuoto DVD HD + ブランク HD DVD ディスク + таза HD DVD дискі + 빈 HD DVD 디스크 + tuščias HD DVD diskas + tukšs HD DVD disks + blanco HD-DVD + tom HD-DVD-plate + Pusta płyta HD DVD + Disco DVD HD virgem + disc gol HD DVD + чистый диск HD DVD + Prázdny disk HD DVD + prazen HD DVD disk + Disk bosh DVD HD + tom HD DVD-skiva + порожній диск HD DVD + đĩa DVD HD trống + 空 HD DVD 光盘 + 空白 HD DVD 光碟 + + + + + audio DVD + DVD سمعي + aŭdyjo DVD + DVD — аудио + DVD d'àudio + Zvukové DVD + lyd-dvd + Audio-DVD + Son-DVD + DVD de sonido + audio DVDa + ääni-DVD + Ljóð DVD + DVD audio + DVD fuaime + DVD de son + DVD שמע + hang DVD + DVD audio + DVD audio + オーディオ DVD + аудио DVD + 오디오 DVD + garso DVD + audio DVD + audio-DVD + lyd-DVD + DVD-Audio + DVD de áudio + DVD audio + звуковой DVD + Zvukové DVD + zvočni DVD + DVD audio + ljud-dvd + звуковий DVD + đĩa DVD âm thanh + 音频 DVD + 音訊 DVD + + + + + + + + + Blu-ray video disc + قرص بلو-راي مرئي + Videadysk Blu-ray + Blu-ray — видео + disc de vídeo Blu-Ray + Videodisk Blu-ray + Blu-ray video-disk + Blu-ray-Videoscheibe + disco de vídeo Blu-ray + Blu-ray bideo-diskoa + Blu-ray-videolevy + Blu-ray diskur + disque vidéo Blu-Ray + diosca físe Blu-Ray + disco de vídeo Blu-ray + תקליטור וידאו מסוג בלו־ריי + Blu-ray videolemez + Cakram video Blu-ray + Disco video Blu-ray + Blu-ray ビデオディスク + Blu-ray видео дискі + 블루레이 비디오 디스크 + Blu-ray vaizdo diskas + Blu-ray video disks + Blu-ray-videodisk + Blu-Ray videoplate + Płyta wideo Blu-ray + Disco de vídeo do Blu-Ray + Disc video Blu-ray + видеодиск Blu-ray + Videodisk Blu-ray + Blu-ray video disk + Disk video Blu-ray + Blu-ray-videoskiva + відеодиск Blu-ray + Đĩa ảnh động Blu-ray + 蓝光视频光盘 + Blu-ray 視訊光碟 + + + + + + + + + HD DVD video disc + قرص HD DVD مرئي + Videadysk HD DVD + HD DVD — видео + disc de vídeo DVD HD + Videodisk HD DVD + HD DVD-videodisk + HD-DVD-Videoscheibe + disco de vídeo HD DVD + HD DVD bideo-diskoa + HD DVD -videolevy + HD DVD video diskur + disque vidéo HD DVD + diosca físe HD DVD + disco de vídeo HD DVD + תקליטור וידאו HD DVD + HD DVD videolemez + Cakram video HD DVD + Disco video DVD HD + HD DVD ビデオディスク + HD DVD видео дискі + HD DVD 비디오 디스크 + HD DVD vaizdo diskas + HD DVD video disks + HD-DVD-videodisk + HD-DVD-videodisk + Płyta wideo HD DVD + Disco DVD de vídeo HD (HDDVD) + Disc video HD DVD + видеодиск HD DVD + Videodisk HD DVD + HD DVD video disk + Disk video DVD HD + HD DVD-videoskiva + відеодиск HD DVD + Đĩa ảnh động DVD HD + HD DVD 视频光盘 + HD DVD 視訊光碟 + + + + + + + + + + e-book reader + Четец на е-книги + lector de llibres electrònics + Čtečka elektronických knih + e-bogslæser + E-Book-Leser + lector de libros electrónicos + e-kirjan lukulaite + lecteur de livre numérique + lector de libros electrónicos + קורא ספרים אלקטרוניים + e-könyvolvasó + Pembaca e-book + Lettore e-book + 電子書籍リーダー + электронды кітаптарды оқу құрылғысы + 이북 리더 + e-grāmatu lasītājs + Czytnik e-booków + устройство для чтения электронных книг + Bralnik elektronskih knjig + e-book-läsare + пристрій для читання електронних книг + 电子书阅读器 + e-book 閱讀器 + + + + + Picture CD + Picture CD + Picture CD + CD — изображения + Picture CD + Picture CD + Billedcd + Bild-CD + Picture CD + Picture CD + Picture CD + Picture CD + CD Picture + Picture CD + Picture CD + תקליטור תמונות + Picture CD + CD Gambar + Picture CD + ピクチャー CD + Picture CD + Picture CD + Paveikslėlių CD + Attēlu CD + foto-CD + Bilete-CD + Picture CD + CD de Fotos + CD cu fotografii + Picture CD + Picture CD + Slikovni CD + Picture CD + Picture CD + CD з зображеннями + Đĩa CD ảnh + 柯达 Picture CD + 圖片 CD + + + + + + + + portable audio player + مشغل الملفات المسموعة المحمولة + pieranosny aŭdyjoplayer + Преносим аудио плеър + reproductor d'àudio portàtil + Přenosný zvukový přehrávač + bærbar lydafspiller + Portables Audio-Wiedergabegerät + dispositivo de sonido portable + audio erreproduzigailu eramangarria + siirrettävä äänisoitin + leysur ljóðavspælari + lecteur audio portable + seinnteoir iniompartha fuaime + dispositivo de son portábel + נגן מוזיקה נייד + hordozható zenelejátszó + pemutar audio portable + Lettore audio portabile + ポータブルオーディオプレイヤー + тасымалы аудио плеер + 휴대용 오디오 플레이어 + nešiojamasis garso leistuvas + portatīvais audio atskaņotājs + draagbare audiospeler + portable audio layer + Przenośny odtwarzacz dźwięku + reprodutor de áudio portátil + player audio portabil + портативный аудиопроигрыватель + Prenosný hudobný prehrávač + prenosni predvajalnik zvoka + Lexues audio portativ + bärbar ljudspelare + портативний аудіопрогравач + bộ phát nhạc di động + 便携式音频播放器 + 可攜式音訊播放程式 + + + + + software + برنامج + prahrama + Софтуер + programari + Software + software + Software + software + softwarea + ohjelmisto + ritbúnaður + logiciel + bogearraí + software + תכנה + szoftver + peranti lunak + Software + ソフトウェア + бағдарламалық қамтама + 소프트웨어 + programinė įranga + programmatūra + software + programvare + Oprogramowanie + Aplicação + software + программное обеспечение + Softvér + programska oprema + Software + programvara + програмне забезпечення + phần mềm + 软件 + 軟體 + + + + + UNIX software + برنامج يونكس + Софтуер за UNIX + programari UNIX + Software UNIX + UNIX-programmer + UNIX Software + software de UNIX + UNIXeko softwarea + UNIX-ohjelmisto + UNIX ritbúnaður + logiciel UNIX + bogearraí UNIX + Software de UNIX + תוכנת UNIX + UNIX-szoftver + Peranti lunak UNIX + Software UNIX + UNIX ソフトウェア + UNIX бағдарламасы + 유닉스 소프트웨어 + UNIX programinė įranga + UNIX programmatūra + Oprogramowanie systemu UNIX + Software UNIX + программа UNIX + Softvér UNIX + Programska datoteka UNIX + UNIX-programvara + програмне забезпечення UNIX + UNIX 软件 + UNIX 軟體 + + + + + + + + + + + Windows software + برنامج ويندوز + Софтуер — Windows + programari de Windows + Software Windows + Windowsprogram + Windows-Software + software de Windows + Windows-eko softwarea + Windows-ohjelmisto + Windows ritbúnaður + logiciel Windows + bogearraí Windows + Software de Windows + תוכנה לWindows + Windows-szoftver + Piranti lunak Windows + Software Windows + Windows ソフトウェア + Windows бағдарламасы + 윈도우 소프트웨어 + Windows programinė įranga + Windows programmatūra + Oprogramowanie systemu Windows + Software Windows + программа Windows + Softvér Windows + Programska oprema za okolje Windows + Windows-program + програмне забезпечення Windows + Windows 软件 + Windows 軟體 + + + + + + + + \ No newline at end of file diff --git a/src/corelib/mimetypes/mimetypes.pri b/src/corelib/mimetypes/mimetypes.pri new file mode 100644 index 00000000000..238aa837e2d --- /dev/null +++ b/src/corelib/mimetypes/mimetypes.pri @@ -0,0 +1,25 @@ +# Qt core mimetype module + +HEADERS += \ + mimetypes/qmimedatabase.h \ + mimetypes/qmimetype.h \ + mimetypes/qmimemagicrulematcher_p.h \ + mimetypes/qmimetype_p.h \ + mimetypes/qmimetypeparser_p.h \ + mimetypes/qmimedatabase_p.h \ + mimetypes/qmimemagicrule_p.h \ + mimetypes/qmimeglobpattern_p.h \ + mimetypes/qmimeprovider_p.h + +SOURCES += \ + mimetypes/qmimedatabase.cpp \ + mimetypes/qmimetype.cpp \ + mimetypes/qmimemagicrulematcher.cpp \ + mimetypes/qmimetypeparser.cpp \ + mimetypes/qmimemagicrule.cpp \ + mimetypes/qmimeglobpattern.cpp \ + mimetypes/qmimeprovider.cpp + +RESOURCES += \ + mimetypes/mimetypes.qrc + diff --git a/src/corelib/mimetypes/mimetypes.qrc b/src/corelib/mimetypes/mimetypes.qrc new file mode 100644 index 00000000000..f0cf47cd49c --- /dev/null +++ b/src/corelib/mimetypes/mimetypes.qrc @@ -0,0 +1,5 @@ + + + mime/packages/freedesktop.org.xml + + diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp new file mode 100644 index 00000000000..a7e14eed24f --- /dev/null +++ b/src/corelib/mimetypes/qmimedatabase.cpp @@ -0,0 +1,609 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 // always first + +#include "qmimedatabase.h" + +#include "qmimedatabase_p.h" + +#include "qmimeprovider_p.h" +#include "qmimetype_p.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +bool qt_isQMimeDatabaseDebuggingActivated (false); + +#ifndef QT_NO_DEBUG_OUTPUT +#define DBG() if (qt_isQMimeDatabaseDebuggingActivated) qDebug() << static_cast(this) << Q_FUNC_INFO +#else +#define DBG() if (0) qDebug() << static_cast(this) << Q_FUNC_INFO +#endif + +Q_GLOBAL_STATIC(QMimeDatabasePrivate, staticQMimeDatabase) + +QMimeDatabasePrivate *QMimeDatabasePrivate::instance() +{ + return staticQMimeDatabase(); +} + +QMimeDatabasePrivate::QMimeDatabasePrivate() + : m_provider(0), m_defaultMimeType(QLatin1String("application/octet-stream")) +{ +} + +QMimeDatabasePrivate::~QMimeDatabasePrivate() +{ + delete m_provider; + m_provider = 0; +} + +QMimeProviderBase *QMimeDatabasePrivate::provider() +{ + if (!m_provider) { + QMimeProviderBase *binaryProvider = new QMimeBinaryProvider(this); + if (binaryProvider->isValid()) { + m_provider = binaryProvider; + } else { + delete binaryProvider; + m_provider = new QMimeXMLProvider(this); + } + } + return m_provider; +} + +void QMimeDatabasePrivate::setProvider(QMimeProviderBase *theProvider) +{ + delete m_provider; + m_provider = theProvider; +} + +/*! + \internal + Returns a MIME type or an invalid one if none found + */ +QMimeType QMimeDatabasePrivate::mimeTypeForName(const QString &nameOrAlias) +{ + return provider()->mimeTypeForName(provider()->resolveAlias(nameOrAlias)); +} + +QStringList QMimeDatabasePrivate::mimeTypeForFileName(const QString &fileName, QString *foundSuffix) +{ + if (fileName.endsWith(QLatin1Char('/'))) + return QStringList() << QLatin1String("inode/directory"); + + const QStringList matchingMimeTypes = provider()->findByFileName(QFileInfo(fileName).fileName(), foundSuffix); + return matchingMimeTypes; +} + +static inline bool isTextFile(const QByteArray &data) +{ + // UTF16 byte order marks + static const char bigEndianBOM[] = "\xFE\xFF"; + static const char littleEndianBOM[] = "\xFF\xFE"; + if (data.startsWith(bigEndianBOM) || data.startsWith(littleEndianBOM)) + return true; + + // Check the first 32 bytes (see shared-mime spec) + const char *p = data.constData(); + const char *e = p + qMin(32, data.size()); + for ( ; p < e; ++p) { + if ((unsigned char)(*p) < 32 && *p != 9 && *p !=10 && *p != 13) + return false; + } + + return true; +} + +QMimeType QMimeDatabasePrivate::findByData(const QByteArray &data, int *accuracyPtr) +{ + if (data.isEmpty()) { + *accuracyPtr = 100; + return mimeTypeForName(QLatin1String("application/x-zerosize")); + } + + *accuracyPtr = 0; + QMimeType candidate = provider()->findByMagic(data, accuracyPtr); + + if (candidate.isValid()) + return candidate; + + if (isTextFile(data)) { + *accuracyPtr = 5; + return mimeTypeForName(QLatin1String("text/plain")); + } + + return mimeTypeForName(defaultMimeType()); +} + +QMimeType QMimeDatabasePrivate::mimeTypeForNameAndData(const QString &fileName, QIODevice *device, int *accuracyPtr) +{ + // First, glob patterns are evaluated. If there is a match with max weight, + // this one is selected and we are done. Otherwise, the file contents are + // evaluated and the match with the highest value (either a magic priority or + // a glob pattern weight) is selected. Matching starts from max level (most + // specific) in both cases, even when there is already a suffix matching candidate. + *accuracyPtr = 0; + + // Pass 1) Try to match on the file name + QStringList candidatesByName = mimeTypeForFileName(fileName); + if (candidatesByName.count() == 1) { + *accuracyPtr = 100; + const QMimeType mime = mimeTypeForName(candidatesByName.at(0)); + if (mime.isValid()) + return mime; + candidatesByName.clear(); + } + + // Extension is unknown, or matches multiple mimetypes. + // Pass 2) Match on content, if we can read the data + if (device->isOpen()) { + + // Read 16K in one go (QIODEVICE_BUFFERSIZE in qiodevice_p.h). + // This is much faster than seeking back and forth into QIODevice. + const QByteArray data = device->peek(16384); + + int magicAccuracy = 0; + QMimeType candidateByData(findByData(data, &magicAccuracy)); + + // Disambiguate conflicting extensions (if magic matching found something) + if (candidateByData.isValid() && magicAccuracy > 0) { + // "for glob_match in glob_matches:" + // "if glob_match is subclass or equal to sniffed_type, use glob_match" + const QString sniffedMime = candidateByData.name(); + foreach (const QString &m, candidatesByName) { + if (inherits(m, sniffedMime)) { + // We have magic + pattern pointing to this, so it's a pretty good match + *accuracyPtr = 100; + return mimeTypeForName(m); + } + } + *accuracyPtr = magicAccuracy; + return candidateByData; + } + } + + if (candidatesByName.count() > 1) { + *accuracyPtr = 20; + candidatesByName.sort(); // to make it deterministic + const QMimeType mime = mimeTypeForName(candidatesByName.at(0)); + if (mime.isValid()) + return mime; + } + + return mimeTypeForName(defaultMimeType()); +} + +QList QMimeDatabasePrivate::allMimeTypes() +{ + return provider()->allMimeTypes(); +} + +bool QMimeDatabasePrivate::inherits(const QString &mime, const QString &parent) +{ + const QString resolvedParent = provider()->resolveAlias(parent); + //Q_ASSERT(provider()->resolveAlias(mime) == mime); + QStack toCheck; + toCheck.push(mime); + while (!toCheck.isEmpty()) { + const QString current = toCheck.pop(); + if (current == resolvedParent) + return true; + foreach (const QString &par, provider()->parents(current)) + toCheck.push(par); + } + return false; +} + +/*! + \class QMimeDatabase + \brief The QMimeDatabase class maintains a database of MIME types. + + \since 5.0 + + The MIME type database is provided by the freedesktop.org shared-mime-info + project. If the MIME type database cannot be found on the system, as is the case + on most Windows and Mac OS X systems, Qt will use its own copy of it. + + Applications which want to define custom MIME types need to install an + XML file into the locations searched for MIME definitions. + These locations can be queried with + \code + QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/packages"), + QStandardPaths::LocateDirectory); + \endcode + On a typical Unix system, this will be /usr/share/mime/packages/, but it is also + possible to extend the list of directories by setting the environment variable + XDG_DATA_DIRS. For instance adding /opt/myapp/share to XDG_DATA_DIRS will result + in /opt/myapp/share/mime/packages/ being searched for MIME definitions. + + Here is an example of MIME XML: + \code + + + + Qt qmake Profile + + + + \endcode + + For more details about the syntax of XML MIME definitions, including defining + "magic" in order to detect MIME types based on data as well, read the + Shared Mime Info specification at + http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html + + On Unix systems, a binary cache is used for more performance. This cache is generated + by the command "update-mime-database path", where path would be /opt/myapp/share/mime + in the above example. Make sure to run this command when installing the MIME type + definition file. + + \threadsafe + + \snippet doc/src/snippets/code/src_corelib_mimetype_qmimedatabase.cpp 0 + + \sa QMimeType + */ + +/*! + \fn QMimeDatabase::QMimeDatabase(); + Constructs this QMimeDatabase object. + */ +QMimeDatabase::QMimeDatabase() : + d(staticQMimeDatabase()) +{ + DBG(); +} + +/*! + \fn QMimeDatabase::~QMimeDatabase(); + Destroys the QMimeDatabase object. + */ +QMimeDatabase::~QMimeDatabase() +{ + DBG(); + + d = 0; +} + +/*! + \fn QMimeType QMimeDatabase::mimeTypeForName(const QString &nameOrAlias) const; + Returns a MIME type for \a nameOrAlias or an invalid one if none found. + */ +QMimeType QMimeDatabase::mimeTypeForName(const QString &nameOrAlias) const +{ + QMutexLocker locker(&d->mutex); + + return d->mimeTypeForName(nameOrAlias); +} + +/*! + Returns a MIME type for \a fileInfo. + + A valid MIME type is always returned. + + The default matching algorithm looks at both the file name and the file + contents, if necessary. The file extension has priority over the contents, + but the contents will be used if the file extension is unknown, or + matches multiple MIME types. + If \a fileInfo is a Unix symbolic link, the file that it refers to + will be used instead. + If the file doesn't match any known pattern or data, the default MIME type + (application/octet-stream) is returned. + + When \a mode is set to MatchExtension, only the file name is used, not + the file contents. The file doesn't even have to exist. If the file name + doesn't match any known pattern, the default MIME type (application/octet-stream) + is returned. + If multiple MIME types match this file, the first one (alphabetically) is returned. + + When \a mode is set to MatchContent, and the file is readable, only the + file contents are used to determine the MIME type. This is equivalent to + calling mimeTypeForData with a QFile as input device. + + In all cases, the \a fileName can also include an absolute or relative path. + + \sa isDefault, mimeTypeForData +*/ +QMimeType QMimeDatabase::mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mode) const +{ + DBG() << "fileInfo" << fileInfo.absoluteFilePath(); + + QMutexLocker locker(&d->mutex); + + if (fileInfo.isDir()) + return d->mimeTypeForName(QLatin1String("inode/directory")); + + QFile file(fileInfo.absoluteFilePath()); + +#ifdef Q_OS_UNIX + // Cannot access statBuf.st_mode from the filesystem engine, so we have to stat again. + const QByteArray nativeFilePath = QFile::encodeName(file.fileName()); + QT_STATBUF statBuffer; + if (QT_LSTAT(nativeFilePath.constData(), &statBuffer) == 0) { + if (S_ISCHR(statBuffer.st_mode)) + return d->mimeTypeForName(QLatin1String("inode/chardevice")); + if (S_ISBLK(statBuffer.st_mode)) + return d->mimeTypeForName(QLatin1String("inode/blockdevice")); + if (S_ISFIFO(statBuffer.st_mode)) + return d->mimeTypeForName(QLatin1String("inode/fifo")); + if (S_ISSOCK(statBuffer.st_mode)) + return d->mimeTypeForName(QLatin1String("inode/socket")); + } +#endif + + int priority = 0; + switch (mode) { + case MatchDefault: + file.open(QIODevice::ReadOnly); // isOpen() will be tested by method below + return d->mimeTypeForNameAndData(fileInfo.absoluteFilePath(), &file, &priority); + case MatchExtension: + locker.unlock(); + return mimeTypeForFile(fileInfo.absoluteFilePath(), mode); + case MatchContent: + if (file.open(QIODevice::ReadOnly)) { + locker.unlock(); + return mimeTypeForData(&file); + } else { + return d->mimeTypeForName(d->defaultMimeType()); + } + default: + Q_ASSERT(false); + } + return d->mimeTypeForName(d->defaultMimeType()); +} + +/*! + Returns a MIME type for the file named \a fileName using \a mode. + + \overload +*/ +QMimeType QMimeDatabase::mimeTypeForFile(const QString &fileName, MatchMode mode) const +{ + if (mode == MatchExtension) { + QMutexLocker locker(&d->mutex); + QStringList matches = d->mimeTypeForFileName(fileName); + const int matchCount = matches.count(); + if (matchCount == 0) { + return d->mimeTypeForName(d->defaultMimeType()); + } else if (matchCount == 1) { + return d->mimeTypeForName(matches.first()); + } else { + // We have to pick one. + matches.sort(); // Make it deterministic + return d->mimeTypeForName(matches.first()); + } + } else { + // Implemented as a wrapper around mimeTypeForFile(QFileInfo), so no mutex. + QFileInfo fileInfo(fileName); + return mimeTypeForFile(fileInfo); + } +} + +/*! + \fn QMimeType QMimeDatabase::findMimeTypesByFileName(const QString &fileName) const; + Returns the MIME types for the file name \a fileName. + + If the file name doesn't match any known pattern, an empty list is returned. + If multiple MIME types match this file, they are all returned. + + This function does not try to open the file. To also use the content + when determining the MIME type, use mimeTypeForFile() or + mimeTypeForNameAndData() instead. + + \sa mimeTypeForFile +*/ +QList QMimeDatabase::mimeTypesForFileName(const QString &fileName) const +{ + QMutexLocker locker(&d->mutex); + + QStringList matches = d->mimeTypeForFileName(fileName); + QList mimes; + matches.sort(); // Make it deterministic + foreach (const QString &mime, matches) + mimes.append(d->mimeTypeForName(mime)); + return mimes; +} +/*! + Returns the suffix for the file \a fileName, as known by the MIME database. + + This allows to pre-select "tar.bz2" for foo.tar.bz2, but still only + "txt" for my.file.with.dots.txt. +*/ +QString QMimeDatabase::suffixForFileName(const QString &fileName) const +{ + QMutexLocker locker(&d->mutex); + QString foundSuffix; + d->mimeTypeForFileName(fileName, &foundSuffix); + return foundSuffix; +} + +/*! + Returns a MIME type for \a data. + + A valid MIME type is always returned. If \a data doesn't match any + known MIME type data, the default MIME type (application/octet-stream) + is returned. +*/ +QMimeType QMimeDatabase::mimeTypeForData(const QByteArray &data) const +{ + QMutexLocker locker(&d->mutex); + + int accuracy = 0; + return d->findByData(data, &accuracy); +} + +/*! + Returns a MIME type for the data in \a device. + + A valid MIME type is always returned. If the data in \a device doesn't match any + known MIME type data, the default MIME type (application/octet-stream) + is returned. +*/ +QMimeType QMimeDatabase::mimeTypeForData(QIODevice *device) const +{ + QMutexLocker locker(&d->mutex); + + int accuracy = 0; + const bool openedByUs = !device->isOpen() && device->open(QIODevice::ReadOnly); + if (device->isOpen()) { + // Read 16K in one go (QIODEVICE_BUFFERSIZE in qiodevice_p.h). + // This is much faster than seeking back and forth into QIODevice. + const QByteArray data = device->peek(16384); + const QMimeType result = d->findByData(data, &accuracy); + if (openedByUs) + device->close(); + return result; + } + return d->mimeTypeForName(d->defaultMimeType()); +} + +/*! + Returns a MIME type for \a url. + + If the URL is a local file, this calls mimeTypeForFile. + + Otherwise the matching is done based on the file name only, + except for schemes where file names don't mean much, like HTTP. + This method always returns the default mimetype for HTTP URLs, + use QNetworkAccessManager to handle HTTP URLs properly. + + A valid MIME type is always returned. If \a url doesn't match any + known MIME type data, the default MIME type (application/octet-stream) + is returned. +*/ +QMimeType QMimeDatabase::mimeTypeForUrl(const QUrl &url) const +{ + if (url.isLocalFile()) + return mimeTypeForFile(url.toLocalFile()); + + const QString scheme = url.scheme(); + if (scheme.startsWith(QLatin1String("http"))) + return mimeTypeForName(d->defaultMimeType()); + + return mimeTypeForFile(url.path()); +} + +/*! + Returns a MIME type for the given \a fileName and \a device data. + + This overload can be useful when the file is remote, and we started to + download some of its data in a device. This allows to do full MIME type + matching for remote files as well. + + If the device is not open, it will be opened by this function, and closed + after the MIME type detection is completed. + + A valid MIME type is always returned. If \a device data doesn't match any + known MIME type data, the default MIME type (application/octet-stream) + is returned. + + This method looks at both the file name and the file contents, + if necessary. The file extension has priority over the contents, + but the contents will be used if the file extension is unknown, or + matches multiple MIME types. +*/ +QMimeType QMimeDatabase::mimeTypeForNameAndData(const QString &fileName, QIODevice *device) const +{ + DBG() << "fileName" << fileName; + + int accuracy = 0; + const bool openedByUs = !device->isOpen() && device->open(QIODevice::ReadOnly); + const QMimeType result = d->mimeTypeForNameAndData(fileName, device, &accuracy); + if (openedByUs) + device->close(); + return result; +} + +/*! + Returns a MIME type for the given \a fileName and device \a data. + + This overload can be useful when the file is remote, and we started to + download some of its data. This allows to do full MIME type matching for + remote files as well. + + A valid MIME type is always returned. If \a data doesn't match any + known MIME type data, the default MIME type (application/octet-stream) + is returned. + + This method looks at both the file name and the file contents, + if necessary. The file extension has priority over the contents, + but the contents will be used if the file extension is unknown, or + matches multiple MIME types. +*/ +QMimeType QMimeDatabase::mimeTypeForNameAndData(const QString &fileName, const QByteArray &data) const +{ + DBG() << "fileName" << fileName; + + QBuffer buffer(const_cast(&data)); + buffer.open(QIODevice::ReadOnly); + int accuracy = 0; + return d->mimeTypeForNameAndData(fileName, &buffer, &accuracy); +} + +/*! + Returns the list of all available MIME types. + + This can be useful for showing all MIME types to the user, for instance + in a MIME type editor. Do not use unless really necessary in other cases + though, prefer using the mimeTypeFor* methods for performance reasons. +*/ +QList QMimeDatabase::allMimeTypes() const +{ + QMutexLocker locker(&d->mutex); + + return d->allMimeTypes(); +} + +#undef DBG + +QT_END_NAMESPACE diff --git a/src/corelib/mimetypes/qmimedatabase.h b/src/corelib/mimetypes/qmimedatabase.h new file mode 100644 index 00000000000..cfd1cfe33d7 --- /dev/null +++ b/src/corelib/mimetypes/qmimedatabase.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 QMIMEDATABASE_H +#define QMIMEDATABASE_H + +#include "qmimetype.h" + +#include + +QT_BEGIN_NAMESPACE + +class QByteArray; +class QFileInfo; +class QIODevice; +class QUrl; + +class QMimeDatabasePrivate; +class Q_CORE_EXPORT QMimeDatabase +{ + Q_DISABLE_COPY(QMimeDatabase) + +public: + QMimeDatabase(); + ~QMimeDatabase(); + + QMimeType mimeTypeForName(const QString &nameOrAlias) const; + + enum MatchMode { + MatchDefault = 0x0, + MatchExtension = 0x1, + MatchContent = 0x2 + }; + + QMimeType mimeTypeForFile(const QString &fileName, MatchMode mode = MatchDefault) const; + QMimeType mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mode = MatchDefault) const; + QList mimeTypesForFileName(const QString &fileName) const; + + QMimeType mimeTypeForData(const QByteArray &data) const; + QMimeType mimeTypeForData(QIODevice *device) const; + + QMimeType mimeTypeForUrl(const QUrl &url) const; + QMimeType mimeTypeForNameAndData(const QString &fileName, QIODevice *device) const; + QMimeType mimeTypeForNameAndData(const QString &fileName, const QByteArray &data) const; + + QString suffixForFileName(const QString &fileName) const; + + QList allMimeTypes() const; + +private: + QMimeDatabasePrivate *d; +}; + +QT_END_NAMESPACE + +#endif // QMIMEDATABASE_H diff --git a/src/corelib/mimetypes/qmimedatabase_p.h b/src/corelib/mimetypes/qmimedatabase_p.h new file mode 100644 index 00000000000..7e98548a354 --- /dev/null +++ b/src/corelib/mimetypes/qmimedatabase_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 QMIMEDATABASE_P_H +#define QMIMEDATABASE_P_H + +#include +#include + +#include "qmimetype.h" +#include "qmimetype_p.h" +#include "qmimeglobpattern_p.h" + +QT_BEGIN_NAMESPACE + +class QMimeDatabase; +class QMimeProviderBase; + +class QMimeDatabasePrivate +{ +public: + Q_DISABLE_COPY(QMimeDatabasePrivate) + + QMimeDatabasePrivate(); + ~QMimeDatabasePrivate(); + + static QMimeDatabasePrivate *instance(); + + QMimeProviderBase *provider(); + void setProvider(QMimeProviderBase *theProvider); + + inline QString defaultMimeType() const { return m_defaultMimeType; } + + bool inherits(const QString &mime, const QString &parent); + + QList allMimeTypes(); + + + QMimeType mimeTypeForName(const QString &nameOrAlias); + QMimeType mimeTypeForNameAndData(const QString &fileName, QIODevice *device, int *priorityPtr); + QMimeType findByData(const QByteArray &data, int *priorityPtr); + QStringList mimeTypeForFileName(const QString &fileName, QString *foundSuffix = 0); + + mutable QMimeProviderBase *m_provider; + const QString m_defaultMimeType; + QMutex mutex; +}; + +QT_END_NAMESPACE + +#endif // QMIMEDATABASE_P_H diff --git a/src/corelib/mimetypes/qmimeglobpattern.cpp b/src/corelib/mimetypes/qmimeglobpattern.cpp new file mode 100644 index 00000000000..de26dbaf15b --- /dev/null +++ b/src/corelib/mimetypes/qmimeglobpattern.cpp @@ -0,0 +1,240 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 "qmimeglobpattern_p.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \internal + \class QMimeGlobMatchResult + \brief The QMimeGlobMatchResult class accumulates results from glob matching. + + Handles glob weights, and preferring longer matches over shorter matches. +*/ + +void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const QString &pattern) +{ + // Is this a lower-weight pattern than the last match? Skip this match then. + if (weight < m_weight) + return; + bool replace = weight > m_weight; + if (!replace) { + // Compare the length of the match + if (pattern.length() < m_matchingPatternLength) + return; // too short, ignore + else if (pattern.length() > m_matchingPatternLength) { + // longer: clear any previous match (like *.bz2, when pattern is *.tar.bz2) + replace = true; + } + } + if (replace) { + m_matchingMimeTypes.clear(); + // remember the new "longer" length + m_matchingPatternLength = pattern.length(); + m_weight = weight; + } + m_matchingMimeTypes.append(mimeType); + if (pattern.startsWith(QLatin1String("*."))) + m_foundSuffix = pattern.mid(2); +} + +/*! + \internal + \class QMimeGlobPattern + \brief The QMimeGlobPattern class contains the glob pattern for file names for MIME type matching. + + \sa QMimeType, QMimeDatabase, QMimeMagicRuleMatcher, QMimeMagicRule +*/ + +bool QMimeGlobPattern::matchFileName(const QString &inputFilename) const +{ + // "Applications MUST match globs case-insensitively, except when the case-sensitive + // attribute is set to true." + // The constructor takes care of putting case-insensitive patterns in lowercase. + const QString filename = m_caseSensitivity == Qt::CaseInsensitive ? inputFilename.toLower() : inputFilename; + + const int pattern_len = m_pattern.length(); + if (!pattern_len) + return false; + const int len = filename.length(); + + const int starCount = m_pattern.count(QLatin1Char('*')); + + // Patterns like "*~", "*.extension" + if (m_pattern[0] == QLatin1Char('*') && m_pattern.indexOf(QLatin1Char('[')) == -1 && starCount == 1) + { + if (len + 1 < pattern_len) return false; + + const QChar *c1 = m_pattern.unicode() + pattern_len - 1; + const QChar *c2 = filename.unicode() + len - 1; + int cnt = 1; + while (cnt < pattern_len && *c1-- == *c2--) + ++cnt; + return cnt == pattern_len; + } + + // Patterns like "README*" (well this is currently the only one like that...) + if (starCount == 1 && m_pattern.at(pattern_len - 1) == QLatin1Char('*')) { + if (len + 1 < pattern_len) return false; + if (m_pattern.at(0) == QLatin1Char('*')) + return filename.indexOf(m_pattern.mid(1, pattern_len - 2)) != -1; + + const QChar *c1 = m_pattern.unicode(); + const QChar *c2 = filename.unicode(); + int cnt = 1; + while (cnt < pattern_len && *c1++ == *c2++) + ++cnt; + return cnt == pattern_len; + } + + // Names without any wildcards like "README" + if (m_pattern.indexOf(QLatin1Char('[')) == -1 && starCount == 0 && m_pattern.indexOf(QLatin1Char('?'))) + return (m_pattern == filename); + + // Other (quite rare) patterns, like "*.anim[1-9j]": use slow but correct method + const QRegExp rx(m_pattern, Qt::CaseSensitive, QRegExp::WildcardUnix); + return rx.exactMatch(filename); +} + +static bool isFastPattern(const QString &pattern) +{ + // starts with "*.", has no other '*' and no other '.' + return pattern.lastIndexOf(QLatin1Char('*')) == 0 + && pattern.lastIndexOf(QLatin1Char('.')) == 1 + // and contains no other special character + && !pattern.contains(QLatin1Char('?')) + && !pattern.contains(QLatin1Char('[')) + ; +} + +void QMimeAllGlobPatterns::addGlob(const QMimeGlobPattern &glob) +{ + const QString &pattern = glob.pattern(); + Q_ASSERT(!pattern.isEmpty()); + + // Store each patterns into either m_fastPatternDict (*.txt, *.html etc. with default weight 50) + // or for the rest, like core.*, *.tar.bz2, *~, into highWeightPatternOffset (>50) + // or lowWeightPatternOffset (<=50) + + if (glob.weight() == 50 && isFastPattern(pattern) && !glob.isCaseSensitive()) { + // The bulk of the patterns is *.foo with weight 50 --> those go into the fast patterns hash. + const QString extension = pattern.mid(2).toLower(); + QStringList &patterns = m_fastPatterns[extension]; // find or create + // This would just slow things down: if (!patterns.contains(glob.mimeType())) + patterns.append(glob.mimeType()); + } else { + if (glob.weight() > 50) { + // This would just slow things down: if (!m_highWeightGlobs.hasPattern(glob.mimeType(), glob.pattern())) + m_highWeightGlobs.append(glob); + } else { + //This would just slow things down: if (!m_lowWeightGlobs.hasPattern(glob.mimeType(), glob.pattern())) + m_lowWeightGlobs.append(glob); + } + } +} + +void QMimeAllGlobPatterns::removeMimeType(const QString &mimeType) +{ + QMutableHashIterator it(m_fastPatterns); + while (it.hasNext()) { + it.next().value().removeAll(mimeType); + } + m_highWeightGlobs.removeMimeType(mimeType); + m_lowWeightGlobs.removeMimeType(mimeType); +} + +void QMimeGlobPatternList::match(QMimeGlobMatchResult &result, + const QString &fileName) const +{ + + QMimeGlobPatternList::const_iterator it = this->constBegin(); + const QMimeGlobPatternList::const_iterator endIt = this->constEnd(); + for (; it != endIt; ++it) { + const QMimeGlobPattern &glob = *it; + if (glob.matchFileName(fileName)) + result.addMatch(glob.mimeType(), glob.weight(), glob.pattern()); + } +} + +QStringList QMimeAllGlobPatterns::matchingGlobs(const QString &fileName, QString *foundSuffix) const +{ + // First try the high weight matches (>50), if any. + QMimeGlobMatchResult result; + m_highWeightGlobs.match(result, fileName); + if (result.m_matchingMimeTypes.isEmpty()) { + + // Now use the "fast patterns" dict, for simple *.foo patterns with weight 50 + // (which is most of them, so this optimization is definitely worth it) + const int lastDot = fileName.lastIndexOf(QLatin1Char('.')); + if (lastDot != -1) { // if no '.', skip the extension lookup + const int ext_len = fileName.length() - lastDot - 1; + const QString simpleExtension = fileName.right(ext_len).toLower(); + // (toLower because fast patterns are always case-insensitive and saved as lowercase) + + const QStringList matchingMimeTypes = m_fastPatterns.value(simpleExtension); + foreach (const QString &mime, matchingMimeTypes) { + result.addMatch(mime, 50, QLatin1String("*.") + simpleExtension); + } + // Can't return yet; *.tar.bz2 has to win over *.bz2, so we need the low-weight mimetypes anyway, + // at least those with weight 50. + } + + // Finally, try the low weight matches (<=50) + m_lowWeightGlobs.match(result, fileName); + } + if (foundSuffix) + *foundSuffix = result.m_foundSuffix; + return result.m_matchingMimeTypes; +} + +void QMimeAllGlobPatterns::clear() +{ + m_fastPatterns.clear(); + m_highWeightGlobs.clear(); + m_lowWeightGlobs.clear(); +} + +QT_END_NAMESPACE diff --git a/src/corelib/mimetypes/qmimeglobpattern_p.h b/src/corelib/mimetypes/qmimeglobpattern_p.h new file mode 100644 index 00000000000..b64a0e2f2b7 --- /dev/null +++ b/src/corelib/mimetypes/qmimeglobpattern_p.h @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 QMIMEGLOBPATTERN_P_H +#define QMIMEGLOBPATTERN_P_H + +#include +#include + +QT_BEGIN_NAMESPACE + +struct QMimeGlobMatchResult +{ + QMimeGlobMatchResult() + : m_weight(0), m_matchingPatternLength(0) + {} + + void addMatch(const QString &mimeType, int weight, const QString &pattern); + + QStringList m_matchingMimeTypes; + int m_weight; + int m_matchingPatternLength; + QString m_foundSuffix; +}; + +class QMimeGlobPattern +{ +public: + static const unsigned MaxWeight = 100; + static const unsigned DefaultWeight = 50; + static const unsigned MinWeight = 1; + + explicit QMimeGlobPattern(const QString &thePattern, const QString &theMimeType, unsigned theWeight = DefaultWeight, Qt::CaseSensitivity s = Qt::CaseInsensitive) : + m_pattern(thePattern), m_mimeType(theMimeType), m_weight(theWeight), m_caseSensitivity(s) + { + if (s == Qt::CaseInsensitive) { + m_pattern = m_pattern.toLower(); + } + } + ~QMimeGlobPattern() {} + + bool matchFileName(const QString &filename) const; + + inline const QString &pattern() const { return m_pattern; } + inline unsigned weight() const { return m_weight; } + inline const QString &mimeType() const { return m_mimeType; } + inline bool isCaseSensitive() const { return m_caseSensitivity == Qt::CaseSensitive; } + +private: + QString m_pattern; + QString m_mimeType; + int m_weight; + Qt::CaseSensitivity m_caseSensitivity; +}; + +class QMimeGlobPatternList : public QList +{ +public: + bool hasPattern(const QString &mimeType, const QString &pattern) const + { + const_iterator it = begin(); + const const_iterator myend = end(); + for (; it != myend; ++it) + if ((*it).pattern() == pattern && (*it).mimeType() == mimeType) + return true; + return false; + } + + /*! + "noglobs" is very rare occurrence, so it's ok if it's slow + */ + void removeMimeType(const QString &mimeType) + { + QMutableListIterator it(*this); + while (it.hasNext()) { + if (it.next().mimeType() == mimeType) + it.remove(); + } + } + + void match(QMimeGlobMatchResult &result, const QString &fileName) const; +}; + +/*! + Result of the globs parsing, as data structures ready for efficient MIME type matching. + This contains: + 1) a map of fast regular patterns (e.g. *.txt is stored as "txt" in a qhash's key) + 2) a linear list of high-weight globs + 3) a linear list of low-weight globs + */ +class QMimeAllGlobPatterns +{ +public: + typedef QHash PatternsMap; // MIME type -> patterns + + void addGlob(const QMimeGlobPattern &glob); + void removeMimeType(const QString &mimeType); + QStringList matchingGlobs(const QString &fileName, QString *foundSuffix) const; + void clear(); + + PatternsMap m_fastPatterns; // example: "doc" -> "application/msword", "text/plain" + QMimeGlobPatternList m_highWeightGlobs; + QMimeGlobPatternList m_lowWeightGlobs; // <= 50, including the non-fast 50 patterns +}; + +QT_END_NAMESPACE + +#endif // QMIMEGLOBPATTERN_P_H diff --git a/src/corelib/mimetypes/qmimemagicrule.cpp b/src/corelib/mimetypes/qmimemagicrule.cpp new file mode 100644 index 00000000000..1dee62f6d0b --- /dev/null +++ b/src/corelib/mimetypes/qmimemagicrule.cpp @@ -0,0 +1,387 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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$ +** +****************************************************************************/ + + +#define QT_NO_CAST_FROM_ASCII + +#include "qmimemagicrule_p.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +// in the same order as Type! +static const char magicRuleTypes_string[] = + "invalid\0" + "string\0" + "host16\0" + "host32\0" + "big16\0" + "big32\0" + "little16\0" + "little32\0" + "byte\0" + "\0"; + +static const int magicRuleTypes_indices[] = { + 0, 8, 15, 22, 29, 35, 41, 50, 59, 65, 0 +}; + +QMimeMagicRule::Type QMimeMagicRule::type(const QByteArray &theTypeName) +{ + for (int i = String; i <= Byte; ++i) { + if (theTypeName == magicRuleTypes_string + magicRuleTypes_indices[i]) + return Type(i); + } + return Invalid; +} + +QByteArray QMimeMagicRule::typeName(QMimeMagicRule::Type theType) +{ + return magicRuleTypes_string + magicRuleTypes_indices[theType]; +} + +class QMimeMagicRulePrivate +{ +public: + bool operator==(const QMimeMagicRulePrivate &other) const; + + QMimeMagicRule::Type type; + QByteArray value; + int startPos; + int endPos; + QByteArray mask; + + QByteArray pattern; + quint32 number; + quint32 numberMask; + + typedef bool (*MatchFunction)(const QMimeMagicRulePrivate *d, const QByteArray &data); + MatchFunction matchFunction; +}; + +bool QMimeMagicRulePrivate::operator==(const QMimeMagicRulePrivate &other) const +{ + return type == other.type && + value == other.value && + startPos == other.startPos && + endPos == other.endPos && + mask == other.mask && + pattern == other.pattern && + number == other.number && + numberMask == other.numberMask && + matchFunction == other.matchFunction; +} + +// Used by both providers +bool QMimeMagicRule::matchSubstring(const char *dataPtr, int dataSize, int rangeStart, int rangeLength, + int valueLength, const char *valueData, const char *mask) +{ + // Size of searched data. + // Example: value="ABC", rangeLength=3 -> we need 3+3-1=5 bytes (ABCxx,xABCx,xxABC would match) + const int dataNeeded = qMin(rangeLength + valueLength - 1, dataSize - rangeStart); + + if (!mask) { + // callgrind says QByteArray::indexOf is much slower, since our strings are typically too + // short for be worth Boyer-Moore matching (1 to 71 bytes, 11 bytes on average). + bool found = false; + for (int i = rangeStart; i < rangeStart + rangeLength; ++i) { + if (i + valueLength > dataSize) + break; + + if (memcmp(valueData, dataPtr + i, valueLength) == 0) { + found = true; + break; + } + } + if (!found) + return false; + } else { + bool found = false; + const char *readDataBase = dataPtr + rangeStart; + // Example (continued from above): + // deviceSize is 4, so dataNeeded was max'ed to 4. + // maxStartPos = 4 - 3 + 1 = 2, and indeed + // we need to check for a match a positions 0 and 1 (ABCx and xABC). + const int maxStartPos = dataNeeded - valueLength + 1; + for (int i = 0; i < maxStartPos; ++i) { + const char *d = readDataBase + i; + bool valid = true; + for (int idx = 0; idx < valueLength; ++idx) { + if (((*d++) & mask[idx]) != (valueData[idx] & mask[idx])) { + valid = false; + break; + } + } + if (valid) + found = true; + } + if (!found) + return false; + } + //qDebug() << "Found" << value << "in" << searchedData; + return true; +} + +static bool matchString(const QMimeMagicRulePrivate *d, const QByteArray &data) +{ + const int rangeLength = d->endPos - d->startPos + 1; + return QMimeMagicRule::matchSubstring(data.constData(), data.size(), d->startPos, rangeLength, d->pattern.size(), d->pattern.constData(), d->mask.constData()); +} + +template +static bool matchNumber(const QMimeMagicRulePrivate *d, const QByteArray &data) +{ + const T value(d->number); + const T mask(d->numberMask); + + //qDebug() << "matchNumber" << "0x" << QString::number(d->number, 16) << "size" << sizeof(T); + //qDebug() << "mask" << QString::number(d->numberMask, 16); + + const char *p = data.constData() + d->startPos; + const char *e = data.constData() + qMin(data.size() - int(sizeof(T)), d->endPos + 1); + for ( ; p <= e; ++p) { + if ((*reinterpret_cast(p) & mask) == (value & mask)) + return true; + } + + return false; +} + +static inline QByteArray makePattern(const QByteArray &value) +{ + QByteArray pattern(value.size(), Qt::Uninitialized); + char *data = pattern.data(); + + const char *p = value.constData(); + const char *e = p + value.size(); + for ( ; p < e; ++p) { + if (*p == '\\' && ++p < e) { + if (*p == 'x') { // hex (\\xff) + char c = 0; + for (int i = 0; i < 2 && p + 1 < e; ++i) { + ++p; + if (*p >= '0' && *p <= '9') + c = (c << 4) + *p - '0'; + else if (*p >= 'a' && *p <= 'f') + c = (c << 4) + *p - 'a' + 10; + else if (*p >= 'A' && *p <= 'F') + c = (c << 4) + *p - 'A' + 10; + else + continue; + } + *data++ = c; + } else if (*p >= '0' && *p <= '7') { // oct (\\7, or \\77, or \\377) + char c = *p - '0'; + if (p + 1 < e && p[1] >= '0' && p[1] <= '7') { + c = (c << 3) + *(++p) - '0'; + if (p + 1 < e && p[1] >= '0' && p[1] <= '7' && p[-1] <= '3') + c = (c << 3) + *(++p) - '0'; + } + *data++ = c; + } else if (*p == 'n') { + *data++ = '\n'; + } else if (*p == 'r') { + *data++ = '\r'; + } else { // escaped + *data++ = *p; + } + } else { + *data++ = *p; + } + } + pattern.truncate(data - pattern.data()); + + return pattern; +} + +QMimeMagicRule::QMimeMagicRule(QMimeMagicRule::Type theType, + const QByteArray &theValue, + int theStartPos, + int theEndPos, + const QByteArray &theMask) : + d(new QMimeMagicRulePrivate) +{ + Q_ASSERT(!theValue.isEmpty()); + + d->type = theType; + d->value = theValue; + d->startPos = theStartPos; + d->endPos = theEndPos; + d->mask = theMask; + d->matchFunction = 0; + + if (d->type >= Host16 && d->type <= Byte) { + bool ok; + d->number = d->value.toUInt(&ok, 0); // autodetect + Q_ASSERT(ok); + d->numberMask = !d->mask.isEmpty() ? d->mask.toUInt(&ok, 0) : 0; // autodetect + } + + switch (d->type) { + case String: + d->pattern = makePattern(d->value); + d->pattern.squeeze(); + if (!d->mask.isEmpty()) { + Q_ASSERT(d->mask.size() >= 4 && d->mask.startsWith("0x")); + d->mask = QByteArray::fromHex(QByteArray::fromRawData(d->mask.constData() + 2, d->mask.size() - 2)); + Q_ASSERT(d->mask.size() == d->pattern.size()); + } else { + d->mask.fill(static_cast(0xff), d->pattern.size()); + } + d->mask.squeeze(); + d->matchFunction = matchString; + break; + case Byte: + if (d->number <= quint8(-1)) { + if (d->numberMask == 0) + d->numberMask = quint8(-1); + d->matchFunction = matchNumber; + } + break; + case Big16: + case Host16: + case Little16: + if (d->number <= quint16(-1)) { + d->number = d->type == Little16 ? qFromLittleEndian(d->number) : qFromBigEndian(d->number); + if (d->numberMask == 0) + d->numberMask = quint16(-1); + d->matchFunction = matchNumber; + } + break; + case Big32: + case Host32: + case Little32: + if (d->number <= quint32(-1)) { + d->number = d->type == Little32 ? qFromLittleEndian(d->number) : qFromBigEndian(d->number); + if (d->numberMask == 0) + d->numberMask = quint32(-1); + d->matchFunction = matchNumber; + } + break; + default: + break; + } +} + +QMimeMagicRule::QMimeMagicRule(const QMimeMagicRule &other) : + d(new QMimeMagicRulePrivate(*other.d)) +{ +} + +QMimeMagicRule::~QMimeMagicRule() +{ +} + +QMimeMagicRule &QMimeMagicRule::operator=(const QMimeMagicRule &other) +{ + *d = *other.d; + return *this; +} + +bool QMimeMagicRule::operator==(const QMimeMagicRule &other) const +{ + return d == other.d || + *d == *other.d; +} + +QMimeMagicRule::Type QMimeMagicRule::type() const +{ + return d->type; +} + +QByteArray QMimeMagicRule::value() const +{ + return d->value; +} + +int QMimeMagicRule::startPos() const +{ + return d->startPos; +} + +int QMimeMagicRule::endPos() const +{ + return d->endPos; +} + +QByteArray QMimeMagicRule::mask() const +{ + QByteArray result = d->mask; + if (d->type == String) { + // restore '0x' + result = "0x" + result.toHex(); + } + return result; +} + +bool QMimeMagicRule::isValid() const +{ + return d->matchFunction; +} + +bool QMimeMagicRule::matches(const QByteArray &data) const +{ + const bool ok = d->matchFunction && d->matchFunction(d.data(), data); + if (!ok) + return false; + + // No submatch? Then we are done. + if (m_subMatches.isEmpty()) + return true; + + //qDebug() << "Checking" << m_subMatches.count() << "sub-rules"; + // Check that one of the submatches matches too + for ( QList::const_iterator it = m_subMatches.begin(), end = m_subMatches.end() ; + it != end ; ++it ) { + if ((*it).matches(data)) { + // One of the hierarchies matched -> mimetype recognized. + return true; + } + } + return false; + + +} + +QT_END_NAMESPACE diff --git a/src/corelib/mimetypes/qmimemagicrule_p.h b/src/corelib/mimetypes/qmimemagicrule_p.h new file mode 100644 index 00000000000..655ca365fa0 --- /dev/null +++ b/src/corelib/mimetypes/qmimemagicrule_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 QMIMEMAGICRULE_P_H +#define QMIMEMAGICRULE_P_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QMimeMagicRulePrivate; +class QMimeMagicRule +{ +public: + enum Type { Invalid = 0, String, Host16, Host32, Big16, Big32, Little16, Little32, Byte }; + + QMimeMagicRule(Type type, const QByteArray &value, int startPos, int endPos, const QByteArray &mask = QByteArray()); + QMimeMagicRule(const QMimeMagicRule &other); + ~QMimeMagicRule(); + + QMimeMagicRule &operator=(const QMimeMagicRule &other); + + bool operator==(const QMimeMagicRule &other) const; + + Type type() const; + QByteArray value() const; + int startPos() const; + int endPos() const; + QByteArray mask() const; + + bool isValid() const; + + bool matches(const QByteArray &data) const; + + QList m_subMatches; + + static Type type(const QByteArray &type); + static QByteArray typeName(Type type); + + static bool matchSubstring(const char *dataPtr, int dataSize, int rangeStart, int rangeLength, int valueLength, const char *valueData, const char *mask); + +private: + const QScopedPointer d; +}; + +QT_END_NAMESPACE + +#endif // QMIMEMAGICRULE_H diff --git a/src/corelib/mimetypes/qmimemagicrulematcher.cpp b/src/corelib/mimetypes/qmimemagicrulematcher.cpp new file mode 100644 index 00000000000..8579d02b003 --- /dev/null +++ b/src/corelib/mimetypes/qmimemagicrulematcher.cpp @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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$ +** +****************************************************************************/ + + +#define QT_NO_CAST_FROM_ASCII + +#include "qmimemagicrulematcher_p.h" + +#include "qmimetype_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \internal + \class QMimeMagicRuleMatcher + + \brief The QMimeMagicRuleMatcher class checks a number of rules based on operator "or". + + It is used for rules parsed from XML files. + + \sa QMimeType, QMimeDatabase, MagicRule, MagicStringRule, MagicByteRule, GlobPattern + \sa QMimeTypeParserBase, MimeTypeParser +*/ + +QMimeMagicRuleMatcher::QMimeMagicRuleMatcher(const QString &mime, unsigned thePriority) : + m_list(), + m_priority(thePriority), + m_mimetype(mime) +{ +} + +bool QMimeMagicRuleMatcher::operator==(const QMimeMagicRuleMatcher &other) +{ + return m_list == other.m_list && + m_priority == other.m_priority; +} + +void QMimeMagicRuleMatcher::addRule(const QMimeMagicRule &rule) +{ + m_list.append(rule); +} + +void QMimeMagicRuleMatcher::addRules(const QList &rules) +{ + m_list.append(rules); +} + +QList QMimeMagicRuleMatcher::magicRules() const +{ + return m_list; +} + +// Check for a match on contents of a file +bool QMimeMagicRuleMatcher::matches(const QByteArray &data) const +{ + foreach (const QMimeMagicRule &magicRule, m_list) { + if (magicRule.matches(data)) + return true; + } + + return false; +} + +// Return a priority value from 1..100 +unsigned QMimeMagicRuleMatcher::priority() const +{ + return m_priority; +} + +QT_END_NAMESPACE diff --git a/src/corelib/mimetypes/qmimemagicrulematcher_p.h b/src/corelib/mimetypes/qmimemagicrulematcher_p.h new file mode 100644 index 00000000000..299f447a4c3 --- /dev/null +++ b/src/corelib/mimetypes/qmimemagicrulematcher_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 QMIMEMAGICRULEMATCHER_P_H +#define QMIMEMAGICRULEMATCHER_P_H + +#include +#include +#include + +#include "qmimemagicrule_p.h" + +QT_BEGIN_NAMESPACE + +class QMimeMagicRuleMatcher +{ +public: + explicit QMimeMagicRuleMatcher(const QString &mime, unsigned priority = 65535); + + bool operator==(const QMimeMagicRuleMatcher &other); + + void addRule(const QMimeMagicRule &rule); + void addRules(const QList &rules); + QList magicRules() const; + + bool matches(const QByteArray &data) const; + + unsigned priority() const; + + QString mimetype() const { return m_mimetype; } + +private: + QList m_list; + unsigned m_priority; + QString m_mimetype; +}; + +QT_END_NAMESPACE + +#endif // QMIMEMAGICRULEMATCHER_P_H diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp new file mode 100644 index 00000000000..8ef0ee88814 --- /dev/null +++ b/src/corelib/mimetypes/qmimeprovider.cpp @@ -0,0 +1,830 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 "qmimeprovider_p.h" + +#include "qmimetypeparser_p.h" +#include +#include "qmimemagicrulematcher_p.h" + +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +static QString fallbackParent(const QString &mimeTypeName) +{ + const QString myGroup = mimeTypeName.left(mimeTypeName.indexOf(QLatin1Char('/'))); + // All text/* types are subclasses of text/plain. + if (myGroup == QLatin1String("text") && mimeTypeName != QLatin1String("text/plain")) + return QLatin1String("text/plain"); + // All real-file mimetypes implicitly derive from application/octet-stream + if (myGroup != QLatin1String("inode") && + // ignore non-file extensions + myGroup != QLatin1String("all") && myGroup != QLatin1String("fonts") && myGroup != QLatin1String("print") && myGroup != QLatin1String("uri") + && mimeTypeName != QLatin1String("application/octet-stream")) { + return QLatin1String("application/octet-stream"); + } + return QString(); +} + +QMimeProviderBase::QMimeProviderBase(QMimeDatabasePrivate *db) + : m_db(db) +{ +} + +Q_CORE_EXPORT int qmime_secondsBetweenChecks = 5; // exported for the unit test + +bool QMimeProviderBase::shouldCheck() +{ + const QDateTime now = QDateTime::currentDateTime(); + if (m_lastCheck.isValid() && m_lastCheck.secsTo(now) < qmime_secondsBetweenChecks) + return false; + m_lastCheck = now; + return true; +} + +QMimeBinaryProvider::QMimeBinaryProvider(QMimeDatabasePrivate *db) + : QMimeProviderBase(db), m_mimetypeListLoaded(false) +{ +} + +#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY) +#define QT_USE_MMAP +#endif + +struct QMimeBinaryProvider::CacheFile +{ + CacheFile(const QString &fileName); + ~CacheFile(); + + bool isValid() const { return m_valid; } + inline quint16 getUint16(int offset) const + { + return qFromBigEndian(*reinterpret_cast(data + offset)); + } + inline quint32 getUint32(int offset) const + { + return qFromBigEndian(*reinterpret_cast(data + offset)); + } + inline const char *getCharStar(int offset) const + { + return reinterpret_cast(data + offset); + } + bool load(); + bool reload(); + + QFile file; + uchar *data; + QDateTime m_mtime; + bool m_valid; +}; + +QMimeBinaryProvider::CacheFile::CacheFile(const QString &fileName) + : file(fileName), m_valid(false) +{ + load(); +} + +QMimeBinaryProvider::CacheFile::~CacheFile() +{ +} + +bool QMimeBinaryProvider::CacheFile::load() +{ + if (!file.open(QIODevice::ReadOnly)) + return false; + data = file.map(0, file.size()); + if (data) { + const int major = getUint16(0); + const int minor = getUint16(2); + m_valid = (major == 1 && minor >= 1 && minor <= 2); + } + m_mtime = QFileInfo(file).lastModified(); + return m_valid; +} + +bool QMimeBinaryProvider::CacheFile::reload() +{ + //qDebug() << "reload!" << file->fileName(); + m_valid = false; + if (file.isOpen()) { + file.close(); + } + data = 0; + return load(); +} + +QMimeBinaryProvider::CacheFile *QMimeBinaryProvider::CacheFileList::findCacheFile(const QString &fileName) const +{ + for (const_iterator it = begin(); it != end(); ++it) { + if ((*it)->file.fileName() == fileName) + return *it; + } + return 0; +} + +QMimeBinaryProvider::~QMimeBinaryProvider() +{ + qDeleteAll(m_cacheFiles); +} + +// Position of the "list offsets" values, at the beginning of the mime.cache file +enum { + PosAliasListOffset = 4, + PosParentListOffset = 8, + PosLiteralListOffset = 12, + PosReverseSuffixTreeOffset = 16, + PosGlobListOffset = 20, + PosMagicListOffset = 24, + // PosNamespaceListOffset = 28, + PosIconsListOffset = 32, + PosGenericIconsListOffset = 36 +}; + +bool QMimeBinaryProvider::isValid() +{ +#if defined(QT_USE_MMAP) + if (!qgetenv("QT_NO_MIME_CACHE").isEmpty()) + return false; + + Q_ASSERT(m_cacheFiles.isEmpty()); // this method is only ever called once + checkCache(); + + if (m_cacheFiles.count() > 1) + return true; + if (m_cacheFiles.isEmpty()) + return false; + + // We found exactly one file; is it the user-modified mimes, or a system file? + const QString foundFile = m_cacheFiles.first()->file.fileName(); + const QString localCacheFile = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/mime/mime.cache"); + + return foundFile != localCacheFile; +#else + return false; +#endif +} + +bool QMimeBinaryProvider::CacheFileList::checkCacheChanged() +{ + bool somethingChanged = false; + QMutableListIterator it(*this); + while (it.hasNext()) { + CacheFile *cacheFile = it.next(); + QFileInfo fileInfo(cacheFile->file); + if (!fileInfo.exists()) { // This can't happen by just running update-mime-database. But the user could use rm -rf :-) + delete cacheFile; + it.remove(); + somethingChanged = true; + } else if (fileInfo.lastModified() > cacheFile->m_mtime) { + if (!cacheFile->reload()) { + delete cacheFile; + it.remove(); + } + somethingChanged = true; + } + } + return somethingChanged; +} + +void QMimeBinaryProvider::checkCache() +{ + if (!shouldCheck()) + return; + + // First iterate over existing known cache files and check for uptodate + if (m_cacheFiles.checkCacheChanged()) + m_mimetypeListLoaded = false; + + // Then check if new cache files appeared + const QStringList cacheFileNames = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/mime.cache")); + if (cacheFileNames != m_cacheFileNames) { + foreach (const QString &cacheFileName, cacheFileNames) { + CacheFile *cacheFile = m_cacheFiles.findCacheFile(cacheFileName); + if (!cacheFile) { + //qDebug() << "new file:" << cacheFileName; + cacheFile = new CacheFile(cacheFileName); + if (cacheFile->isValid()) // verify version + m_cacheFiles.append(cacheFile); + else + delete cacheFile; + } + } + m_cacheFileNames = cacheFileNames; + m_mimetypeListLoaded = false; + } +} + +static QMimeType mimeTypeForNameUnchecked(const QString &name) +{ + QMimeTypePrivate data; + data.name = name; + // The rest is retrieved on demand. + // comment and globPatterns: in loadMimeTypePrivate + // iconName: in loadIcon + // genericIconName: in loadGenericIcon + return QMimeType(data); +} + +QMimeType QMimeBinaryProvider::mimeTypeForName(const QString &name) +{ + checkCache(); + if (!m_mimetypeListLoaded) + loadMimeTypeList(); + if (!m_mimetypeNames.contains(name)) + return QMimeType(); // unknown mimetype + return mimeTypeForNameUnchecked(name); +} + +QStringList QMimeBinaryProvider::findByFileName(const QString &fileName, QString *foundSuffix) +{ + checkCache(); + const QString lowerFileName = fileName.toLower(); + QMimeGlobMatchResult result; + // TODO this parses in the order (local, global). Check that it handles "NOGLOBS" correctly. + foreach (CacheFile *cacheFile, m_cacheFiles) { + matchGlobList(result, cacheFile, cacheFile->getUint32(PosLiteralListOffset), fileName); + matchGlobList(result, cacheFile, cacheFile->getUint32(PosGlobListOffset), fileName); + const int reverseSuffixTreeOffset = cacheFile->getUint32(PosReverseSuffixTreeOffset); + const int numRoots = cacheFile->getUint32(reverseSuffixTreeOffset); + const int firstRootOffset = cacheFile->getUint32(reverseSuffixTreeOffset + 4); + matchSuffixTree(result, cacheFile, numRoots, firstRootOffset, lowerFileName, fileName.length() - 1, false); + if (result.m_matchingMimeTypes.isEmpty()) + matchSuffixTree(result, cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true); + } + if (foundSuffix) + *foundSuffix = result.m_foundSuffix; + return result.m_matchingMimeTypes; +} + +void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int off, const QString &fileName) +{ + const int numGlobs = cacheFile->getUint32(off); + //qDebug() << "Loading" << numGlobs << "globs from" << cacheFile->file.fileName() << "at offset" << cacheFile->globListOffset; + for (int i = 0; i < numGlobs; ++i) { + const int globOffset = cacheFile->getUint32(off + 4 + 12 * i); + const int mimeTypeOffset = cacheFile->getUint32(off + 4 + 12 * i + 4); + const int flagsAndWeight = cacheFile->getUint32(off + 4 + 12 * i + 8); + const int weight = flagsAndWeight & 0xff; + const bool caseSensitive = flagsAndWeight & 0x100; + const Qt::CaseSensitivity qtCaseSensitive = caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; + const QString pattern = QLatin1String(cacheFile->getCharStar(globOffset)); + + const char *mimeType = cacheFile->getCharStar(mimeTypeOffset); + //qDebug() << pattern << mimeType << weight << caseSensitive; + QMimeGlobPattern glob(pattern, QString() /*unused*/, weight, qtCaseSensitive); + + // TODO: this could be done faster for literals where a simple == would do. + if (glob.matchFileName(fileName)) + result.addMatch(QLatin1String(mimeType), weight, pattern); + } +} + +bool QMimeBinaryProvider::matchSuffixTree(QMimeGlobMatchResult &result, QMimeBinaryProvider::CacheFile *cacheFile, int numEntries, int firstOffset, const QString &fileName, int charPos, bool caseSensitiveCheck) +{ + QChar fileChar = fileName[charPos]; + int min = 0; + int max = numEntries - 1; + while (min <= max) { + const int mid = (min + max) / 2; + const int off = firstOffset + 12 * mid; + const QChar ch = cacheFile->getUint32(off); + if (ch < fileChar) + min = mid + 1; + else if (ch > fileChar) + max = mid - 1; + else { + --charPos; + int numChildren = cacheFile->getUint32(off + 4); + int childrenOffset = cacheFile->getUint32(off + 8); + bool success = false; + if (charPos > 0) + success = matchSuffixTree(result, cacheFile, numChildren, childrenOffset, fileName, charPos, caseSensitiveCheck); + if (!success) { + for (int i = 0; i < numChildren; ++i) { + const int childOff = childrenOffset + 12 * i; + const int mch = cacheFile->getUint32(childOff); + if (mch != 0) + break; + const int mimeTypeOffset = cacheFile->getUint32(childOff + 4); + const char *mimeType = cacheFile->getCharStar(mimeTypeOffset); + const int flagsAndWeight = cacheFile->getUint32(childOff + 8); + const int weight = flagsAndWeight & 0xff; + const bool caseSensitive = flagsAndWeight & 0x100; + if (caseSensitiveCheck || !caseSensitive) { + result.addMatch(QLatin1String(mimeType), weight, QLatin1Char('*') + fileName.mid(charPos+1)); + success = true; + } + } + } + return success; + } + } + return false; +} + +bool QMimeBinaryProvider::matchMagicRule(QMimeBinaryProvider::CacheFile *cacheFile, int numMatchlets, int firstOffset, const QByteArray &data) +{ + const char *dataPtr = data.constData(); + const int dataSize = data.size(); + for (int matchlet = 0; matchlet < numMatchlets; ++matchlet) { + const int off = firstOffset + matchlet * 32; + const int rangeStart = cacheFile->getUint32(off); + const int rangeLength = cacheFile->getUint32(off + 4); + //const int wordSize = cacheFile->getUint32(off + 8); + const int valueLength = cacheFile->getUint32(off + 12); + const int valueOffset = cacheFile->getUint32(off + 16); + const int maskOffset = cacheFile->getUint32(off + 20); + const char *mask = maskOffset ? cacheFile->getCharStar(maskOffset) : NULL; + + if (!QMimeMagicRule::matchSubstring(dataPtr, dataSize, rangeStart, rangeLength, valueLength, cacheFile->getCharStar(valueOffset), mask)) + continue; + + const int numChildren = cacheFile->getUint32(off + 24); + const int firstChildOffset = cacheFile->getUint32(off + 28); + if (numChildren == 0) // No submatch? Then we are done. + return true; + // Check that one of the submatches matches too + if (matchMagicRule(cacheFile, numChildren, firstChildOffset, data)) + return true; + } + return false; +} + +QMimeType QMimeBinaryProvider::findByMagic(const QByteArray &data, int *accuracyPtr) +{ + checkCache(); + foreach (CacheFile *cacheFile, m_cacheFiles) { + const int magicListOffset = cacheFile->getUint32(PosMagicListOffset); + const int numMatches = cacheFile->getUint32(magicListOffset); + //const int maxExtent = cacheFile->getUint32(magicListOffset + 4); + const int firstMatchOffset = cacheFile->getUint32(magicListOffset + 8); + + for (int i = 0; i < numMatches; ++i) { + const int off = firstMatchOffset + i * 16; + const int numMatchlets = cacheFile->getUint32(off + 8); + const int firstMatchletOffset = cacheFile->getUint32(off + 12); + if (matchMagicRule(cacheFile, numMatchlets, firstMatchletOffset, data)) { + const int mimeTypeOffset = cacheFile->getUint32(off + 4); + const char *mimeType = cacheFile->getCharStar(mimeTypeOffset); + *accuracyPtr = cacheFile->getUint32(off); + // Return the first match. We have no rules for conflicting magic data... + // (mime.cache itself is sorted, but what about local overrides with a lower prio?) + return mimeTypeForNameUnchecked(QLatin1String(mimeType)); + } + } + } + return QMimeType(); +} + +QStringList QMimeBinaryProvider::parents(const QString &mime) +{ + checkCache(); + const QByteArray mimeStr = mime.toLatin1(); + QStringList result; + foreach (CacheFile *cacheFile, m_cacheFiles) { + const int parentListOffset = cacheFile->getUint32(PosParentListOffset); + const int numEntries = cacheFile->getUint32(parentListOffset); + + int begin = 0; + int end = numEntries - 1; + while (begin <= end) { + const int medium = (begin + end) / 2; + const int off = parentListOffset + 4 + 8 * medium; + const int mimeOffset = cacheFile->getUint32(off); + const char *aMime = cacheFile->getCharStar(mimeOffset); + const int cmp = qstrcmp(aMime, mimeStr); + if (cmp < 0) { + begin = medium + 1; + } else if (cmp > 0) { + end = medium - 1; + } else { + const int parentsOffset = cacheFile->getUint32(off + 4); + const int numParents = cacheFile->getUint32(parentsOffset); + for (int i = 0; i < numParents; ++i) { + const int parentOffset = cacheFile->getUint32(parentsOffset + 4 + 4 * i); + const char *aParent = cacheFile->getCharStar(parentOffset); + result.append(QString::fromLatin1(aParent)); + } + break; + } + } + } + if (result.isEmpty()) { + const QString parent = fallbackParent(mime); + if (!parent.isEmpty()) + result.append(parent); + } + return result; +} + +QString QMimeBinaryProvider::resolveAlias(const QString &name) +{ + checkCache(); + const QByteArray input = name.toLatin1(); + foreach (CacheFile *cacheFile, m_cacheFiles) { + const int aliasListOffset = cacheFile->getUint32(PosAliasListOffset); + const int numEntries = cacheFile->getUint32(aliasListOffset); + int begin = 0; + int end = numEntries - 1; + while (begin <= end) { + const int medium = (begin + end) / 2; + const int off = aliasListOffset + 4 + 8 * medium; + const int aliasOffset = cacheFile->getUint32(off); + const char *alias = cacheFile->getCharStar(aliasOffset); + const int cmp = qstrcmp(alias, input); + if (cmp < 0) { + begin = medium + 1; + } else if (cmp > 0) { + end = medium - 1; + } else { + const int mimeOffset = cacheFile->getUint32(off + 4); + const char *mimeType = cacheFile->getCharStar(mimeOffset); + return QLatin1String(mimeType); + } + } + } + + return name; +} + +void QMimeBinaryProvider::loadMimeTypeList() +{ + if (!m_mimetypeListLoaded) { + m_mimetypeListLoaded = true; + m_mimetypeNames.clear(); + // Unfortunately mime.cache doesn't have a full list of all mimetypes. + // So we have to parse the plain-text files called "types". + const QStringList typesFilenames = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/types")); + foreach (const QString &typeFilename, typesFilenames) { + QFile file(typeFilename); + if (file.open(QIODevice::ReadOnly)) { + while (!file.atEnd()) { + QByteArray line = file.readLine(); + line.chop(1); + m_mimetypeNames.insert(QString::fromLatin1(line.constData(), line.size())); + } + } + } + } +} + +QList QMimeBinaryProvider::allMimeTypes() +{ + QList result; + loadMimeTypeList(); + + for (QSet::const_iterator it = m_mimetypeNames.constBegin(); + it != m_mimetypeNames.constEnd(); ++it) + result.append(mimeTypeForNameUnchecked(*it)); + + return result; +} + +void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data) +{ + // load comment and globPatterns + + const QString file = data.name + QLatin1String(".xml"); + const QStringList mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QString::fromLatin1("mime/") + file); + if (mimeFiles.isEmpty()) { + // TODO: ask Thiago about this + qWarning() << "No file found for" << file << ", even though the file appeared in a directory listing."; + qWarning() << "Either it was just removed, or the directory doesn't have executable permission..."; + qWarning() << QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime"), QStandardPaths::LocateDirectory); + return; + } + + QString comment; + QString mainPattern; + const QString preferredLanguage = QLocale::system().name(); + + QListIterator mimeFilesIter(mimeFiles); + mimeFilesIter.toBack(); + while (mimeFilesIter.hasPrevious()) { // global first, then local. + const QString fullPath = mimeFilesIter.previous(); + QFile qfile(fullPath); + if (!qfile.open(QFile::ReadOnly)) + continue; + + QXmlStreamReader xml(&qfile); + if (xml.readNextStartElement()) { + if (xml.name() != QLatin1String("mime-type")) { + continue; + } + const QString name = xml.attributes().value(QLatin1String("type")).toString(); + if (name.isEmpty()) + continue; + if (name != data.name) { + qWarning() << "Got name" << name << "in file" << file << "expected" << data.name; + } + + while (xml.readNextStartElement()) { + const QStringRef tag = xml.name(); + if (tag == QLatin1String("comment")) { + QString lang = xml.attributes().value(QLatin1String("xml:lang")).toString(); + const QString text = xml.readElementText(); + if (lang.isEmpty()) { + lang = QLatin1String("en_US"); + } + data.localeComments.insert(lang, text); + continue; // we called readElementText, so we're at the EndElement already. + } else if (tag == QLatin1String("icon")) { // as written out by shared-mime-info >= 0.40 + data.iconName = xml.attributes().value(QLatin1String("name")).toString(); + } else if (tag == QLatin1String("glob-deleteall")) { // as written out by shared-mime-info >= 0.70 + data.globPatterns.clear(); + } else if (tag == QLatin1String("glob")) { // as written out by shared-mime-info >= 0.70 + const QString pattern = xml.attributes().value(QLatin1String("pattern")).toString(); + if (mainPattern.isEmpty() && pattern.startsWith(QLatin1Char('*'))) { + mainPattern = pattern; + } + if (!data.globPatterns.contains(pattern)) + data.globPatterns.append(pattern); + } + xml.skipCurrentElement(); + } + Q_ASSERT(xml.name() == QLatin1String("mime-type")); + } + } + + // Let's assume that shared-mime-info is at least version 0.70 + // Otherwise we would need 1) a version check, and 2) code for parsing patterns from the globs file. +#if 1 + if (!mainPattern.isEmpty() && data.globPatterns.first() != mainPattern) { + // ensure it's first in the list of patterns + data.globPatterns.removeAll(mainPattern); + data.globPatterns.prepend(mainPattern); + } +#else + const bool globsInXml = sharedMimeInfoVersion() >= QT_VERSION_CHECK(0, 70, 0); + if (globsInXml) { + if (!mainPattern.isEmpty() && data.globPatterns.first() != mainPattern) { + // ensure it's first in the list of patterns + data.globPatterns.removeAll(mainPattern); + data.globPatterns.prepend(mainPattern); + } + } else { + // Fallback: get the patterns from the globs file + // TODO: This would be the only way to support shared-mime-info < 0.70 + // But is this really worth the effort? + } +#endif +} + +// Binary search in the icons or generic-icons list +QString QMimeBinaryProvider::iconForMime(CacheFile *cacheFile, int posListOffset, const QByteArray &inputMime) +{ + const int iconsListOffset = cacheFile->getUint32(posListOffset); + const int numIcons = cacheFile->getUint32(iconsListOffset); + int begin = 0; + int end = numIcons - 1; + while (begin <= end) { + const int medium = (begin + end) / 2; + const int off = iconsListOffset + 4 + 8 * medium; + const int mimeOffset = cacheFile->getUint32(off); + const char *mime = cacheFile->getCharStar(mimeOffset); + const int cmp = qstrcmp(mime, inputMime); + if (cmp < 0) + begin = medium + 1; + else if (cmp > 0) + end = medium - 1; + else { + const int iconOffset = cacheFile->getUint32(off + 4); + return QLatin1String(cacheFile->getCharStar(iconOffset)); + } + } + return QString(); +} + +void QMimeBinaryProvider::loadIcon(QMimeTypePrivate &data) +{ + checkCache(); + const QByteArray inputMime = data.name.toLatin1(); + foreach (CacheFile *cacheFile, m_cacheFiles) { + const QString icon = iconForMime(cacheFile, PosIconsListOffset, inputMime); + if (!icon.isEmpty()) { + data.iconName = icon; + return; + } + } +} + +void QMimeBinaryProvider::loadGenericIcon(QMimeTypePrivate &data) +{ + checkCache(); + const QByteArray inputMime = data.name.toLatin1(); + foreach (CacheFile *cacheFile, m_cacheFiles) { + const QString icon = iconForMime(cacheFile, PosGenericIconsListOffset, inputMime); + if (!icon.isEmpty()) { + data.genericIconName = icon; + return; + } + } +} + +//// + +QMimeXMLProvider::QMimeXMLProvider(QMimeDatabasePrivate *db) + : QMimeProviderBase(db), m_loaded(false) +{ +} + +bool QMimeXMLProvider::isValid() +{ + return true; +} + +QMimeType QMimeXMLProvider::mimeTypeForName(const QString &name) +{ + ensureLoaded(); + + return m_nameMimeTypeMap.value(name); +} + +QStringList QMimeXMLProvider::findByFileName(const QString &fileName, QString *foundSuffix) +{ + ensureLoaded(); + + const QStringList matchingMimeTypes = m_mimeTypeGlobs.matchingGlobs(fileName, foundSuffix); + return matchingMimeTypes; +} + +QMimeType QMimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr) +{ + ensureLoaded(); + + QString candidate; + + foreach (const QMimeMagicRuleMatcher &matcher, m_magicMatchers) { + if (matcher.matches(data)) { + const int priority = matcher.priority(); + if (priority > *accuracyPtr) { + *accuracyPtr = priority; + candidate = matcher.mimetype(); + } + } + } + return mimeTypeForName(candidate); +} + +void QMimeXMLProvider::ensureLoaded() +{ + if (!m_loaded || shouldCheck()) { + bool fdoXmlFound = false; + QStringList allFiles; + + const QStringList packageDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/packages"), QStandardPaths::LocateDirectory); + //qDebug() << "packageDirs=" << packageDirs; + foreach (const QString &packageDir, packageDirs) { + QDir dir(packageDir); + const QStringList files = dir.entryList(QDir::Files | QDir::NoDotAndDotDot); + //qDebug() << static_cast(this) << Q_FUNC_INFO << packageDir << files; + if (!fdoXmlFound) + fdoXmlFound = files.contains(QLatin1String("freedesktop.org.xml")); + QStringList::const_iterator endIt(files.constEnd()); + for (QStringList::const_iterator it(files.constBegin()); it != endIt; ++it) { + allFiles.append(packageDir + QLatin1Char('/') + *it); + } + } + + if (!fdoXmlFound) { + // We could instead install the file as part of installing Qt? + allFiles.prepend(QLatin1String(":/qt-project.org/qmime/freedesktop.org.xml")); + } + + if (m_allFiles == allFiles) + return; + m_allFiles = allFiles; + + m_nameMimeTypeMap.clear(); + m_aliases.clear(); + m_parents.clear(); + m_mimeTypeGlobs.clear(); + m_magicMatchers.clear(); + + //qDebug() << "Loading" << m_allFiles; + + foreach (const QString &file, allFiles) + load(file); + } +} + +void QMimeXMLProvider::load(const QString &fileName) +{ + QString errorMessage; + if (!load(fileName, &errorMessage)) + qWarning("QMimeDatabase: Error loading %s\n%s", qPrintable(fileName), qPrintable(errorMessage)); +} + +bool QMimeXMLProvider::load(const QString &fileName, QString *errorMessage) +{ + m_loaded = true; + + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + if (errorMessage) + *errorMessage = QString::fromLatin1("Cannot open %1: %2").arg(fileName, file.errorString()); + return false; + } + + if (errorMessage) + errorMessage->clear(); + + QMimeTypeParser parser(*this); + return parser.parse(&file, fileName, errorMessage); +} + +void QMimeXMLProvider::addGlobPattern(const QMimeGlobPattern &glob) +{ + m_mimeTypeGlobs.addGlob(glob); +} + +void QMimeXMLProvider::addMimeType(const QMimeType &mt) +{ + m_nameMimeTypeMap.insert(mt.name(), mt); +} + +QStringList QMimeXMLProvider::parents(const QString &mime) +{ + ensureLoaded(); + QStringList result = m_parents.value(mime); + if (result.isEmpty()) { + const QString parent = fallbackParent(mime); + if (!parent.isEmpty()) + result.append(parent); + } + return result; +} + +void QMimeXMLProvider::addParent(const QString &child, const QString &parent) +{ + m_parents[child].append(parent); +} + +QString QMimeXMLProvider::resolveAlias(const QString &name) +{ + ensureLoaded(); + return m_aliases.value(name, name); +} + +void QMimeXMLProvider::addAlias(const QString &alias, const QString &name) +{ + m_aliases.insert(alias, name); +} + +QList QMimeXMLProvider::allMimeTypes() +{ + ensureLoaded(); + return m_nameMimeTypeMap.values(); +} + +void QMimeXMLProvider::addMagicMatcher(const QMimeMagicRuleMatcher &matcher) +{ + m_magicMatchers.append(matcher); +} + +QT_END_NAMESPACE diff --git a/src/corelib/mimetypes/qmimeprovider_p.h b/src/corelib/mimetypes/qmimeprovider_p.h new file mode 100644 index 00000000000..cb51ba11eea --- /dev/null +++ b/src/corelib/mimetypes/qmimeprovider_p.h @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 QMIMEPROVIDER_P_H +#define QMIMEPROVIDER_P_H + +#include +#include "qmimedatabase_p.h" +#include + +QT_BEGIN_NAMESPACE + +class QMimeMagicRuleMatcher; + +class QMimeProviderBase +{ +public: + QMimeProviderBase(QMimeDatabasePrivate *db); + virtual ~QMimeProviderBase() {} + + virtual bool isValid() = 0; + virtual QMimeType mimeTypeForName(const QString &name) = 0; + virtual QStringList findByFileName(const QString &fileName, QString *foundSuffix) = 0; + virtual QStringList parents(const QString &mime) = 0; + virtual QString resolveAlias(const QString &name) = 0; + virtual QMimeType findByMagic(const QByteArray &data, int *accuracyPtr) = 0; + virtual QList allMimeTypes() = 0; + virtual void loadMimeTypePrivate(QMimeTypePrivate &) {} + virtual void loadIcon(QMimeTypePrivate &) {} + virtual void loadGenericIcon(QMimeTypePrivate &) {} + + QMimeDatabasePrivate *m_db; +protected: + bool shouldCheck(); + QDateTime m_lastCheck; +}; + +/* + Parses the files 'mime.cache' and 'types' on demand + */ +class QMimeBinaryProvider : public QMimeProviderBase +{ +public: + QMimeBinaryProvider(QMimeDatabasePrivate *db); + virtual ~QMimeBinaryProvider(); + + virtual bool isValid(); + virtual QMimeType mimeTypeForName(const QString &name); + virtual QStringList findByFileName(const QString &fileName, QString *foundSuffix); + virtual QStringList parents(const QString &mime); + virtual QString resolveAlias(const QString &name); + virtual QMimeType findByMagic(const QByteArray &data, int *accuracyPtr); + virtual QList allMimeTypes(); + virtual void loadMimeTypePrivate(QMimeTypePrivate &); + virtual void loadIcon(QMimeTypePrivate &); + virtual void loadGenericIcon(QMimeTypePrivate &); + +private: + struct CacheFile; + + void matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int offset, const QString &fileName); + bool matchSuffixTree(QMimeGlobMatchResult &result, CacheFile *cacheFile, int numEntries, int firstOffset, const QString &fileName, int charPos, bool caseSensitiveCheck); + bool matchMagicRule(CacheFile *cacheFile, int numMatchlets, int firstOffset, const QByteArray &data); + QString iconForMime(CacheFile *cacheFile, int posListOffset, const QByteArray &inputMime); + void loadMimeTypeList(); + void checkCache(); + + class CacheFileList : public QList + { + public: + CacheFile *findCacheFile(const QString &fileName) const; + bool checkCacheChanged(); + }; + CacheFileList m_cacheFiles; + QStringList m_cacheFileNames; + QSet m_mimetypeNames; + bool m_mimetypeListLoaded; +}; + +/* + Parses the raw XML files (slower) + */ +class QMimeXMLProvider : public QMimeProviderBase +{ +public: + QMimeXMLProvider(QMimeDatabasePrivate *db); + + virtual bool isValid(); + virtual QMimeType mimeTypeForName(const QString &name); + virtual QStringList findByFileName(const QString &fileName, QString *foundSuffix); + virtual QStringList parents(const QString &mime); + virtual QString resolveAlias(const QString &name); + virtual QMimeType findByMagic(const QByteArray &data, int *accuracyPtr); + virtual QList allMimeTypes(); + + bool load(const QString &fileName, QString *errorMessage); + + // Called by the mimetype xml parser + void addMimeType(const QMimeType &mt); + void addGlobPattern(const QMimeGlobPattern &glob); + void addParent(const QString &child, const QString &parent); + void addAlias(const QString &alias, const QString &name); + void addMagicMatcher(const QMimeMagicRuleMatcher &matcher); + +private: + void ensureLoaded(); + void load(const QString &fileName); + + bool m_loaded; + + typedef QHash NameMimeTypeMap; + NameMimeTypeMap m_nameMimeTypeMap; + + typedef QHash AliasHash; + AliasHash m_aliases; + + typedef QHash ParentsHash; + ParentsHash m_parents; + QMimeAllGlobPatterns m_mimeTypeGlobs; + + QList m_magicMatchers; + QStringList m_allFiles; +}; + +QT_END_NAMESPACE + +#endif // QMIMEPROVIDER_P_H diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp new file mode 100644 index 00000000000..77592880a04 --- /dev/null +++ b/src/corelib/mimetypes/qmimetype.cpp @@ -0,0 +1,506 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 "qmimetype.h" + +#include "qmimetype_p.h" +#include "qmimedatabase_p.h" +#include "qmimeprovider_p.h" + +#include "qmimeglobpattern_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +bool qt_isQMimeTypeDebuggingActivated (false); + +#ifndef QT_NO_DEBUG_OUTPUT +#define DBG() if (qt_isQMimeTypeDebuggingActivated) qDebug() << static_cast(this) << Q_FUNC_INFO +#else +#define DBG() if (0) qDebug() << static_cast(this) << Q_FUNC_INFO +#endif + +QMimeTypePrivate::QMimeTypePrivate() + : name() + //, comment() + , localeComments() + , genericIconName() + , iconName() + , globPatterns() +{} + +QMimeTypePrivate::QMimeTypePrivate(const QMimeType &other) + : name(other.d->name) + //, comment(other.d->comment) + , localeComments(other.d->localeComments) + , genericIconName(other.d->genericIconName) + , iconName(other.d->iconName) + , globPatterns(other.d->globPatterns) +{} + +void QMimeTypePrivate::clear() +{ + name.clear(); + //comment.clear(); + localeComments.clear(); + genericIconName.clear(); + iconName.clear(); + globPatterns.clear(); +} + +/*! + \fn bool QMimeTypePrivate::operator==(const QMimeTypePrivate &other) const; + Returns true if \a other equals this QMimeTypePrivate object, otherwise returns false. + */ +bool QMimeTypePrivate::operator==(const QMimeTypePrivate &other) const +{ + DBG(); + if (name == other.name && + //comment == other.comment && + localeComments == other.localeComments && + genericIconName == other.genericIconName && + iconName == other.iconName && + globPatterns == other.globPatterns) { + return true; + } + + DBG() << name << other.name << (name == other.name); + //DBG() << comment << other.comment << (comment == other.comment); + DBG() << localeComments << other.localeComments << (localeComments == other.localeComments); + DBG() << genericIconName << other.genericIconName << (genericIconName == other.genericIconName); + DBG() << iconName << other.iconName << (iconName == other.iconName); + DBG() << globPatterns << other.globPatterns << (globPatterns == other.globPatterns); + return false; +} + +void QMimeTypePrivate::addGlobPattern(const QString &pattern) +{ + globPatterns.append(pattern); +} + +/*! + \class QMimeType + \brief The QMimeType class describes types of file or data, represented by a MIME type string. + + \since 5.0 + + For instance a file named "readme.txt" has the MIME type "text/plain". + The MIME type can be determined from the file name, or from the file + contents, or from both. MIME type determination can also be done on + buffers of data not coming from files. + + Determining the MIME type of a file can be useful to make sure your + application supports it. It is also useful in file-manager-like applications + or widgets, in order to display an appropriate icon() for the file, or even + the descriptive comment() in detailed views. + + To check if a file has the expected MIME type, you should use inherits() + rather than a simple string comparison based on the name(). This is because + MIME types can inherit from each other: for instance a C source file is + a specific type of plain text file, so text/x-csrc inherits text/plain. + + \sa QMimeDatabase + */ + +/*! + \fn QMimeType::QMimeType(); + Constructs this QMimeType object initialized with default property values that indicate an invalid MIME type. + */ +QMimeType::QMimeType() : + d(new QMimeTypePrivate()) +{ + DBG() << "name():" << name(); + //DBG() << "aliases():" << aliases(); + //DBG() << "comment():" << comment(); + DBG() << "genericIconName():" << genericIconName(); + DBG() << "iconName():" << iconName(); + DBG() << "globPatterns():" << globPatterns(); + DBG() << "suffixes():" << suffixes(); + DBG() << "preferredSuffix():" << preferredSuffix(); +} + +/*! + \fn QMimeType::QMimeType(const QMimeType &other); + Constructs this QMimeType object as a copy of \a other. + */ +QMimeType::QMimeType(const QMimeType &other) : + d(other.d) +{ + DBG() << "name():" << name(); + //DBG() << "aliases():" << aliases(); + //DBG() << "comment():" << comment(); + DBG() << "genericIconName():" << genericIconName(); + DBG() << "iconName():" << iconName(); + DBG() << "globPatterns():" << globPatterns(); + DBG() << "suffixes():" << suffixes(); + DBG() << "preferredSuffix():" << preferredSuffix(); +} + +/*! + \fn QMimeType &QMimeType::operator=(const QMimeType &other); + Assigns the data of \a other to this QMimeType object, and returns a reference to this object. + */ +QMimeType &QMimeType::operator=(const QMimeType &other) +{ + if (d != other.d) + d = other.d; + return *this; +} + +#ifdef Q_COMPILER_RVALUE_REFS +/*! + \fn QMimeType::QMimeType(QMimeType &&other); + Constructs this QMimeType object by moving the data of the rvalue reference \a other. + */ +QMimeType::QMimeType(QMimeType &&other) : + d(std::move(other.d)) +{ + DBG() << "name():" << name(); + //DBG() << "aliases():" << aliases(); + //DBG() << "comment():" << comment(); + DBG() << "genericIconName():" << genericIconName(); + DBG() << "iconName():" << iconName(); + DBG() << "globPatterns():" << globPatterns(); + DBG() << "suffixes():" << suffixes(); + DBG() << "preferredSuffix():" << preferredSuffix(); +} +#endif + +/*! + \fn QMimeType::QMimeType(const QMimeTypePrivate &dd); + Assigns the data of the QMimeTypePrivate \a dd to this QMimeType object, and returns a reference to this object. + */ +QMimeType::QMimeType(const QMimeTypePrivate &dd) : + d(new QMimeTypePrivate(dd)) +{ + DBG() << "name():" << name(); + //DBG() << "aliases():" << aliases(); + //DBG() << "comment():" << comment(); + DBG() << "genericIconName():" << genericIconName(); + DBG() << "iconName():" << iconName(); + DBG() << "globPatterns():" << globPatterns(); + DBG() << "suffixes():" << suffixes(); + DBG() << "preferredSuffix():" << preferredSuffix(); +} + +/*! + \fn void QMimeType::swap(QMimeType &other); + Swaps QMimeType \a other with this QMimeType object. + + This operation is very fast and never fails. + + The swap() method helps with the implementation of assignment + operators in an exception-safe way. For more information consult + \l {http://en.wikibooks.org/wiki/More_C++_Idioms/Copy-and-swap} + {More C++ Idioms - Copy-and-swap}. + */ + +/*! + \fn QMimeType::~QMimeType(); + Destroys the QMimeType object, and releases the d pointer. + */ +QMimeType::~QMimeType() +{ + DBG() << "name():" << name(); + //DBG() << "aliases():" << aliases(); + //DBG() << "comment():" << comment(); + DBG() << "genericIconName():" << genericIconName(); + DBG() << "iconName():" << iconName(); + DBG() << "globPatterns():" << globPatterns(); + DBG() << "suffixes():" << suffixes(); + DBG() << "preferredSuffix():" << preferredSuffix(); +} + +/*! + \fn bool QMimeType::operator==(const QMimeType &other) const; + Returns true if \a other equals this QMimeType object, otherwise returns false. + */ +bool QMimeType::operator==(const QMimeType &other) const +{ + return d == other.d || *d == *other.d; +} + +/*! + \fn bool QMimeType::operator!=(const QMimeType &other) const; + Returns true if \a other does not equal this QMimeType object, otherwise returns false. + */ + +/*! + \fn bool QMimeType::isValid() const; + Returns true if the QMimeType object contains valid data, otherwise returns false. + A valid MIME type has a non-empty name(). + The invalid MIME type is the default-constructed QMimeType. + */ +bool QMimeType::isValid() const +{ + return !d->name.isEmpty(); +} + +/*! + \fn bool QMimeType::isDefault() const; + Returns true if this MIME type is the default MIME type which + applies to all files: application/octet-stream. + */ +bool QMimeType::isDefault() const +{ + return d->name == QMimeDatabasePrivate::instance()->defaultMimeType(); +} + +/*! + \fn QString QMimeType::name() const; + Returns the name of the MIME type. + */ +QString QMimeType::name() const +{ + return d->name; +} + +/*! + Returns the description of the MIME type to be displayed on user interfaces. + + The system language (QLocale::system().name()) is used to select the appropriate translation. + Another language can be specified by setting the \a localeName argument. + */ +QString QMimeType::comment() const +{ + QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d); + + QStringList languageList; + languageList << QLocale::system().name(); + languageList << QLocale::system().uiLanguages(); + Q_FOREACH (const QString &lang, languageList) { + const QString comm = d->localeComments.value(lang); + if (!comm.isEmpty()) + return comm; + const int pos = lang.indexOf(QLatin1Char('_')); + if (pos != -1) { + // "pt_BR" not found? try just "pt" + const QString shortLang = lang.left(pos); + const QString commShort = d->localeComments.value(shortLang); + if (!commShort.isEmpty()) + return commShort; + } + } + + // Use the mimetype name as fallback + return d->name; +} + +/*! + \fn QString QMimeType::genericIconName() const; + Returns the file name of a generic icon that represents the MIME type. + + This should be used if the icon returned by iconName() cannot be found on + the system. It is used for categories of similar types (like spreadsheets + or archives) that can use a common icon. + The freedesktop.org Icon Naming Specification lists a set of such icon names. + + The icon name can be given to QIcon::fromTheme() in order to load the icon. + */ +QString QMimeType::genericIconName() const +{ + QMimeDatabasePrivate::instance()->provider()->loadGenericIcon(*d); + if (d->genericIconName.isEmpty()) { + // From the spec: + // If the generic icon name is empty (not specified by the mimetype definition) + // then the mimetype is used to generate the generic icon by using the top-level + // media type (e.g. "video" in "video/ogg") and appending "-x-generic" + // (i.e. "video-x-generic" in the previous example). + QString group = name(); + const int slashindex = group.indexOf(QLatin1Char('/')); + if (slashindex != -1) + group = group.left(slashindex); + return group + QLatin1String("-x-generic"); + } + return d->genericIconName; +} + +/*! + \fn QString QMimeType::iconName() const; + Returns the file name of an icon image that represents the MIME type. + + The icon name can be given to QIcon::fromTheme() in order to load the icon. + */ +QString QMimeType::iconName() const +{ + QMimeDatabasePrivate::instance()->provider()->loadIcon(*d); + if (d->iconName.isEmpty()) { + // Make default icon name from the mimetype name + d->iconName = name(); + const int slashindex = d->iconName.indexOf(QLatin1Char('/')); + if (slashindex != -1) + d->iconName[slashindex] = QLatin1Char('-'); + } + return d->iconName; +} + +/*! + \fn QStringList QMimeType::globPatterns() const; + Returns the list of glob matching patterns. + */ +QStringList QMimeType::globPatterns() const +{ + QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d); + return d->globPatterns; +} + +/*! + A type is a subclass of another type if any instance of the first type is + also an instance of the second. For example, all image/svg+xml files are also + text/xml, text/plain and application/octet-stream files. Subclassing is about + the format, rather than the category of the data (for example, there is no + 'generic spreadsheet' class that all spreadsheets inherit from). + Conversely, the parent mimetype of image/svg+xml is text/xml. + + A mimetype can have multiple parents. For instance application/x-perl + has two parents: application/x-executable and text/plain. This makes + it possible to both execute perl scripts, and to open them in text editors. +*/ +QStringList QMimeType::parentMimeTypes() const +{ + return QMimeDatabasePrivate::instance()->provider()->parents(d->name); +} + +static void collectParentMimeTypes(const QString &mime, QStringList &allParents) +{ + QStringList parents = QMimeDatabasePrivate::instance()->provider()->parents(mime); + foreach (const QString &parent, parents) { + // I would use QSet, but since order matters I better not + if (!allParents.contains(parent)) + allParents.append(parent); + } + // We want a breadth-first search, so that the least-specific parent (octet-stream) is last + // This means iterating twice, unfortunately. + foreach (const QString &parent, parents) { + collectParentMimeTypes(parent, allParents); + } +} + +/*! + Return all the parent mimetypes of this mimetype, direct and indirect. + This includes the parent(s) of its parent(s), etc. + + For instance, for image/svg+xml the list would be: + application/xml, text/plain, application/octet-stream. + + Note that application/octet-stream is the ultimate parent for all types + of files (but not directories). +*/ +QStringList QMimeType::allAncestors() const +{ + QStringList allParents; + collectParentMimeTypes(d->name, allParents); + return allParents; +} + +/*! + \fn QStringList QMimeType::suffixes() const; + Returns the known suffixes for the MIME type. + */ +QStringList QMimeType::suffixes() const +{ + QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d); + + QStringList result; + foreach (const QString &pattern, d->globPatterns) { + // Not a simple suffix if if looks like: README or *. or *.* or *.JP*G or *.JP? + if (pattern.startsWith(QLatin1String("*.")) && + pattern.length() > 2 && + pattern.indexOf(QLatin1Char('*'), 2) < 0 && pattern.indexOf(QLatin1Char('?'), 2) < 0) { + const QString suffix = pattern.mid(2); + result.append(suffix); + } + } + + return result; +} + +/*! + \fn QString QMimeType::preferredSuffix() const; + Returns the preferred suffix for the MIME type. + */ +QString QMimeType::preferredSuffix() const +{ + const QStringList suffixList = suffixes(); + return suffixList.isEmpty() ? QString() : suffixList.at(0); +} + +/*! + \fn QString QMimeType::filterString() const; + Returns a filter string usable for a file dialog. +*/ +QString QMimeType::filterString() const +{ + QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d); + QString filter; + + if (!d->globPatterns.empty()) { + filter += comment() + QLatin1String(" ("); + for (int i = 0; i < d->globPatterns.size(); ++i) { + if (i != 0) + filter += QLatin1Char(' '); + filter += d->globPatterns.at(i); + } + filter += QLatin1Char(')'); + } + + return filter; +} + +/*! + \fn bool QMimeType::inherits(const QString &mimeTypeName) const; + Returns true if this mimetype is \a mimeTypeName, + or inherits \a mimeTypeName (see parentMimeTypes()), + or \a mimeTypeName is an alias for this mimetype. + */ +bool QMimeType::inherits(const QString &mimeTypeName) const +{ + if (d->name == mimeTypeName) + return true; + return QMimeDatabasePrivate::instance()->inherits(d->name, mimeTypeName); +} + +#undef DBG + +QT_END_NAMESPACE diff --git a/src/corelib/mimetypes/qmimetype.h b/src/corelib/mimetypes/qmimetype.h new file mode 100644 index 00000000000..68d17caaba8 --- /dev/null +++ b/src/corelib/mimetypes/qmimetype.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 QMIMETYPE_H +#define QMIMETYPE_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QMimeTypePrivate; +class QFileinfo; +class QStringList; + +class Q_CORE_EXPORT QMimeType +{ +public: + QMimeType(); + QMimeType(const QMimeType &other); + QMimeType &operator=(const QMimeType &other); +#ifdef Q_COMPILER_RVALUE_REFS + QMimeType(QMimeType &&other); + + QMimeType &operator=(QMimeType &&other) + { + qSwap(d, other.d); + return *this; + } +#endif + void swap(QMimeType &other) + { + qSwap(d, other.d); + } + explicit QMimeType(const QMimeTypePrivate &dd); + ~QMimeType(); + + bool operator==(const QMimeType &other) const; + + inline bool operator!=(const QMimeType &other) const + { + return !operator==(other); + } + + bool isValid() const; + + bool isDefault() const; + + QString name() const; + QString comment() const; + QString genericIconName() const; + QString iconName() const; + QStringList globPatterns() const; + QStringList parentMimeTypes() const; + QStringList allAncestors() const; + QStringList suffixes() const; + QString preferredSuffix() const; + + bool inherits(const QString &mimeTypeName) const; + + QString filterString() const; + +protected: + friend class QMimeTypeParserBase; + friend class MimeTypeMapEntry; + friend class QMimeDatabasePrivate; + friend class QMimeXMLProvider; + friend class QMimeBinaryProvider; + friend class QMimeTypePrivate; + + QExplicitlySharedDataPointer d; +}; + +QT_END_NAMESPACE + +#endif // QMIMETYPE_H diff --git a/src/corelib/mimetypes/qmimetype_p.h b/src/corelib/mimetypes/qmimetype_p.h new file mode 100644 index 00000000000..d8aadccf50a --- /dev/null +++ b/src/corelib/mimetypes/qmimetype_p.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 QMIMETYPE_P_H +#define QMIMETYPE_P_H + +#include "qmimetype.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +class Q_AUTOTEST_EXPORT QMimeTypePrivate : public QSharedData +{ +public: + typedef QHash LocaleHash; + + QMimeTypePrivate(); + explicit QMimeTypePrivate(const QMimeType &other); + + void clear(); + + bool operator==(const QMimeTypePrivate &other) const; + + void addGlobPattern(const QString &pattern); + + QString name; + LocaleHash localeComments; + QString genericIconName; + QString iconName; + QStringList globPatterns; +}; + +QT_END_NAMESPACE + +#define QMIMETYPE_BUILDER \ + QT_BEGIN_NAMESPACE \ + static QMimeType buildQMimeType ( \ + const QString &name, \ + const QString &genericIconName, \ + const QString &iconName, \ + const QStringList &globPatterns \ + ) \ + { \ + QMimeTypePrivate qMimeTypeData; \ + qMimeTypeData.name = name; \ + qMimeTypeData.genericIconName = genericIconName; \ + qMimeTypeData.iconName = iconName; \ + qMimeTypeData.globPatterns = globPatterns; \ + return QMimeType(qMimeTypeData); \ + } \ + QT_END_NAMESPACE + +#ifdef Q_COMPILER_RVALUE_REFS +#define QMIMETYPE_BUILDER_FROM_RVALUE_REFS \ + QT_BEGIN_NAMESPACE \ + static QMimeType buildQMimeType ( \ + QString &&name, \ + QString &&genericIconName, \ + QString &&iconName, \ + QStringList &&globPatterns \ + ) \ + { \ + QMimeTypePrivate qMimeTypeData; \ + qMimeTypeData.name = std::move(name); \ + qMimeTypeData.genericIconName = std::move(genericIconName); \ + qMimeTypeData.iconName = std::move(iconName); \ + qMimeTypeData.globPatterns = std::move(globPatterns); \ + return QMimeType(qMimeTypeData); \ + } \ + QT_END_NAMESPACE +#endif + +#endif // QMIMETYPE_P_H diff --git a/src/corelib/mimetypes/qmimetypeparser.cpp b/src/corelib/mimetypes/qmimetypeparser.cpp new file mode 100644 index 00000000000..23f57367e38 --- /dev/null +++ b/src/corelib/mimetypes/qmimetypeparser.cpp @@ -0,0 +1,342 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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$ +** +****************************************************************************/ + + +#define QT_NO_CAST_FROM_ASCII + +#include "qmimetypeparser_p.h" + +#include "qmimetype_p.h" +#include "qmimemagicrulematcher_p.h" + +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +// XML tags in MIME files +const char *const mimeInfoTagC = "mime-info"; +const char *const mimeTypeTagC = "mime-type"; +const char *const mimeTypeAttributeC = "type"; +const char *const subClassTagC = "sub-class-of"; +const char *const commentTagC = "comment"; +const char *const genericIconTagC = "generic-icon"; +const char *const iconTagC = "icon"; +const char *const nameAttributeC = "name"; +const char *const globTagC = "glob"; +const char *const aliasTagC = "alias"; +const char *const patternAttributeC = "pattern"; +const char *const weightAttributeC = "weight"; +const char *const caseSensitiveAttributeC = "case-sensitive"; +const char *const localeAttributeC = "xml:lang"; + +const char *const magicTagC = "magic"; +const char *const priorityAttributeC = "priority"; + +const char *const matchTagC = "match"; +const char *const matchValueAttributeC = "value"; +const char *const matchTypeAttributeC = "type"; +const char *const matchOffsetAttributeC = "offset"; +const char *const matchMaskAttributeC = "mask"; + +/*! + \class QMimeTypeParser + \internal + \brief The QMimeTypeParser class parses MIME types, and builds a MIME database hierarchy by adding to QMimeDatabasePrivate. + + Populates QMimeDataBase + + \sa QMimeDatabase, QMimeMagicRuleMatcher, MagicRule, MagicStringRule, MagicByteRule, GlobPattern + \sa QMimeTypeParser +*/ + + +/*! + \class QMimeTypeParserBase + \brief The QMimeTypeParserBase class parses for a sequence of in a generic way. + + Calls abstract handler function process for QMimeType it finds. + + \sa QMimeDatabase, QMimeMagicRuleMatcher, MagicRule, MagicStringRule, MagicByteRule, GlobPattern + \sa QMimeTypeParser +*/ + +/*! + \fn virtual bool QMimeTypeParserBase::process(const QMimeType &t, QString *errorMessage) = 0; + Overwrite to process the sequence of parsed data +*/ + +QMimeTypeParserBase::ParseState QMimeTypeParserBase::nextState(ParseState currentState, const QStringRef &startElement) +{ + switch (currentState) { + case ParseBeginning: + if (startElement == QLatin1String(mimeInfoTagC)) + return ParseMimeInfo; + if (startElement == QLatin1String(mimeTypeTagC)) + return ParseMimeType; + return ParseError; + case ParseMimeInfo: + return startElement == QLatin1String(mimeTypeTagC) ? ParseMimeType : ParseError; + case ParseMimeType: + case ParseComment: + case ParseGenericIcon: + case ParseIcon: + case ParseGlobPattern: + case ParseSubClass: + case ParseAlias: + case ParseOtherMimeTypeSubTag: + case ParseMagicMatchRule: + if (startElement == QLatin1String(mimeTypeTagC)) // Sequence of + return ParseMimeType; + if (startElement == QLatin1String(commentTagC )) + return ParseComment; + if (startElement == QLatin1String(genericIconTagC)) + return ParseGenericIcon; + if (startElement == QLatin1String(iconTagC)) + return ParseIcon; + if (startElement == QLatin1String(globTagC)) + return ParseGlobPattern; + if (startElement == QLatin1String(subClassTagC)) + return ParseSubClass; + if (startElement == QLatin1String(aliasTagC)) + return ParseAlias; + if (startElement == QLatin1String(magicTagC)) + return ParseMagic; + if (startElement == QLatin1String(matchTagC)) + return ParseMagicMatchRule; + return ParseOtherMimeTypeSubTag; + case ParseMagic: + if (startElement == QLatin1String(matchTagC)) + return ParseMagicMatchRule; + break; + case ParseError: + break; + } + return ParseError; +} + +// Parse int number from an (attribute) string) +static bool parseNumber(const QString &n, int *target, QString *errorMessage) +{ + bool ok; + *target = n.toInt(&ok); + if (!ok) { + *errorMessage = QString::fromLatin1("Not a number '%1'.").arg(n); + return false; + } + return true; +} + +// Evaluate a magic match rule like +// +// +static bool createMagicMatchRule(const QXmlStreamAttributes &atts, + QString *errorMessage, QMimeMagicRule *&rule) +{ + const QString type = atts.value(QLatin1String(matchTypeAttributeC)).toString(); + QMimeMagicRule::Type magicType = QMimeMagicRule::type(type.toLatin1()); + if (magicType == QMimeMagicRule::Invalid) { + qWarning("%s: match type %s is not supported.", Q_FUNC_INFO, type.toUtf8().constData()); + return true; + } + const QString value = atts.value(QLatin1String(matchValueAttributeC)).toString(); + if (value.isEmpty()) { + *errorMessage = QString::fromLatin1("Empty match value detected."); + return false; + } + // Parse for offset as "1" or "1:10" + int startPos, endPos; + const QString offsetS = atts.value(QLatin1String(matchOffsetAttributeC)).toString(); + const int colonIndex = offsetS.indexOf(QLatin1Char(':')); + const QString startPosS = colonIndex == -1 ? offsetS : offsetS.mid(0, colonIndex); + const QString endPosS = colonIndex == -1 ? offsetS : offsetS.mid(colonIndex + 1); + if (!parseNumber(startPosS, &startPos, errorMessage) || !parseNumber(endPosS, &endPos, errorMessage)) + return false; + const QString mask = atts.value(QLatin1String(matchMaskAttributeC)).toString(); + + rule = new QMimeMagicRule(magicType, value.toUtf8(), startPos, endPos, mask.toLatin1()); + + return true; +} + +bool QMimeTypeParserBase::parse(QIODevice *dev, const QString &fileName, QString *errorMessage) +{ + QMimeTypePrivate data; + int priority = 50; + QStack currentRules; // stack for the nesting of rules + QList rules; // toplevel rules + QXmlStreamReader reader(dev); + ParseState ps = ParseBeginning; + QXmlStreamAttributes atts; + while (!reader.atEnd()) { + switch (reader.readNext()) { + case QXmlStreamReader::StartElement: + ps = nextState(ps, reader.name()); + atts = reader.attributes(); + switch (ps) { + case ParseMimeType: { // start parsing a MIME type name + const QString name = atts.value(QLatin1String(mimeTypeAttributeC)).toString(); + if (name.isEmpty()) { + reader.raiseError(QString::fromLatin1("Missing '%1'-attribute").arg(QString::fromLatin1(mimeTypeAttributeC))); + } else { + data.name = name; + } + } + break; + case ParseGenericIcon: + data.genericIconName = atts.value(QLatin1String(nameAttributeC)).toString(); + break; + case ParseIcon: + data.iconName = atts.value(QLatin1String(nameAttributeC)).toString(); + break; + case ParseGlobPattern: { + const QString pattern = atts.value(QLatin1String(patternAttributeC)).toString(); + unsigned weight = atts.value(QLatin1String(weightAttributeC)).toString().toInt(); + const bool caseSensitive = atts.value(QLatin1String(caseSensitiveAttributeC)).toString() == QLatin1String("true"); + + if (weight == 0) + weight = QMimeGlobPattern::DefaultWeight; + + Q_ASSERT(!data.name.isEmpty()); + const QMimeGlobPattern glob(pattern, data.name, weight, caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); + if (!process(glob, errorMessage)) // for actual glob matching + return false; + data.addGlobPattern(pattern); // just for QMimeType::globPatterns() + } + break; + case ParseSubClass: { + const QString inheritsFrom = atts.value(QLatin1String(mimeTypeAttributeC)).toString(); + if (!inheritsFrom.isEmpty()) + processParent(data.name, inheritsFrom); + } + break; + case ParseComment: { + // comments have locale attributes. We want the default, English one + QString locale = atts.value(QLatin1String(localeAttributeC)).toString(); + const QString comment = reader.readElementText(); + if (locale.isEmpty()) + locale = QString::fromLatin1("en_US"); + data.localeComments.insert(locale, comment); + } + break; + case ParseAlias: { + const QString alias = atts.value(QLatin1String(mimeTypeAttributeC)).toString(); + if (!alias.isEmpty()) + processAlias(alias, data.name); + } + break; + case ParseMagic: { + priority = 50; + const QString priorityS = atts.value(QLatin1String(priorityAttributeC)).toString(); + if (!priorityS.isEmpty()) { + if (!parseNumber(priorityS, &priority, errorMessage)) + return false; + + } + currentRules.clear(); + //qDebug() << "MAGIC start for mimetype" << data.name; + } + break; + case ParseMagicMatchRule: { + QMimeMagicRule *rule = 0; + if (!createMagicMatchRule(atts, errorMessage, rule)) + return false; + QList *ruleList; + if (currentRules.isEmpty()) + ruleList = &rules; + else // nest this rule into the proper parent + ruleList = ¤tRules.top()->m_subMatches; + ruleList->append(*rule); + //qDebug() << " MATCH added. Stack size was" << currentRules.size(); + currentRules.push(&ruleList->last()); + delete rule; + break; + } + case ParseError: + reader.raiseError(QString::fromLatin1("Unexpected element <%1>"). + arg(reader.name().toString())); + break; + default: + break; + } + break; + // continue switch QXmlStreamReader::Token... + case QXmlStreamReader::EndElement: // Finished element + { + const QStringRef elementName = reader.name(); + if (elementName == QLatin1String(mimeTypeTagC)) { + if (!process(QMimeType(data), errorMessage)) + return false; + data.clear(); + } else if (elementName == QLatin1String(matchTagC)) { + // Closing a tag, pop stack + currentRules.pop(); + //qDebug() << " MATCH closed. Stack size is now" << currentRules.size(); + } else if (elementName == QLatin1String(magicTagC)) { + //qDebug() << "MAGIC ended, we got" << rules.count() << "rules, with prio" << priority; + // Finished a sequence + QMimeMagicRuleMatcher ruleMatcher(data.name, priority); + ruleMatcher.addRules(rules); + processMagicMatcher(ruleMatcher); + rules.clear(); + } + break; + } + default: + break; + } + } + + if (reader.hasError()) { + if (errorMessage) + *errorMessage = QString::fromLatin1("An error has been encountered at line %1 of %2: %3:").arg(reader.lineNumber()).arg(fileName, reader.errorString()); + return false; + } + + return true; +} + +QT_END_NAMESPACE diff --git a/src/corelib/mimetypes/qmimetypeparser_p.h b/src/corelib/mimetypes/qmimetypeparser_p.h new file mode 100644 index 00000000000..455c07063c5 --- /dev/null +++ b/src/corelib/mimetypes/qmimetypeparser_p.h @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 MIMETYPEPARSER_P_H +#define MIMETYPEPARSER_P_H + +#include "qmimedatabase_p.h" +#include "qmimeprovider_p.h" + +QT_BEGIN_NAMESPACE + +class QIODevice; + +// XML tags in MIME files +extern const char *const mimeInfoTagC; +extern const char *const mimeTypeTagC; +extern const char *const mimeTypeAttributeC; +extern const char *const subClassTagC; +extern const char *const commentTagC; +extern const char *const genericIconTagC; +extern const char *const nameAttributeC; +extern const char *const globTagC; +extern const char *const aliasTagC; +extern const char *const patternAttributeC; +extern const char *const weightAttributeC; +extern const char *const caseSensitiveAttributeC; +extern const char *const localeAttributeC; + +extern const char *const magicTagC; +extern const char *const priorityAttributeC; + +extern const char *const matchTagC; +extern const char *const matchValueAttributeC; +extern const char *const matchTypeAttributeC; +extern const char *const matchOffsetAttributeC; +extern const char *const matchMaskAttributeC; + +class QMimeTypeParserBase +{ + Q_DISABLE_COPY(QMimeTypeParserBase) + +public: + QMimeTypeParserBase() {} + virtual ~QMimeTypeParserBase() {} + + bool parse(QIODevice *dev, const QString &fileName, QString *errorMessage); + +protected: + virtual bool process(const QMimeType &t, QString *errorMessage) = 0; + virtual bool process(const QMimeGlobPattern &t, QString *errorMessage) = 0; + virtual void processParent(const QString &child, const QString &parent) = 0; + virtual void processAlias(const QString &alias, const QString &name) = 0; + virtual void processMagicMatcher(const QMimeMagicRuleMatcher &matcher) = 0; + +private: + enum ParseState { + ParseBeginning, + ParseMimeInfo, + ParseMimeType, + ParseComment, + ParseGenericIcon, + ParseIcon, + ParseGlobPattern, + ParseSubClass, + ParseAlias, + ParseMagic, + ParseMagicMatchRule, + ParseOtherMimeTypeSubTag, + ParseError + }; + + static ParseState nextState(ParseState currentState, const QStringRef &startElement); +}; + + +class QMimeTypeParser : public QMimeTypeParserBase +{ +public: + explicit QMimeTypeParser(QMimeXMLProvider &provider) : m_provider(provider) {} + +protected: + inline bool process(const QMimeType &t, QString *) + { m_provider.addMimeType(t); return true; } + + inline bool process(const QMimeGlobPattern &glob, QString *) + { m_provider.addGlobPattern(glob); return true; } + + inline void processParent(const QString &child, const QString &parent) + { m_provider.addParent(child, parent); } + + inline void processAlias(const QString &alias, const QString &name) + { m_provider.addAlias(alias, name); } + + inline void processMagicMatcher(const QMimeMagicRuleMatcher &matcher) + { m_provider.addMagicMatcher(matcher); } + +private: + QMimeXMLProvider &m_provider; +}; + +QT_END_NAMESPACE + +#endif // MIMETYPEPARSER_P_H diff --git a/tests/auto/corelib/corelib.pro b/tests/auto/corelib/corelib.pro index 4f284ac21e2..a85a385f80d 100644 --- a/tests/auto/corelib/corelib.pro +++ b/tests/auto/corelib/corelib.pro @@ -7,6 +7,7 @@ SUBDIRS=\ itemmodels \ json \ kernel \ + mimetypes \ plugin \ statemachine \ thread \ diff --git a/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp b/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp index ad61db51d6e..d5d490dc295 100644 --- a/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp +++ b/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp @@ -403,8 +403,11 @@ void tst_QDirIterator::iterateResource() QDirIterator it(dirName, nameFilters, filters, flags); QStringList list; - while (it.hasNext()) - list << it.next(); + while (it.hasNext()) { + const QString dir = it.next(); + if (!dir.startsWith(":/qt-project.org")) + list << dir; + } list.sort(); QStringList sortedEntries = entries; diff --git a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp index fa72083dcc7..796282d6d8c 100644 --- a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp +++ b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp @@ -92,6 +92,7 @@ void tst_QResourceEngine::checkStructure_data() << QString() << (QStringList() << "search_file.txt") << (QStringList() << QLatin1String("aliasdir") << QLatin1String("otherdir") + << QLatin1String("qt-project.org") << QLatin1String("runtime_resource") << QLatin1String("searchpath1") << QLatin1String("searchpath2") << QLatin1String("secondary_root") diff --git a/tests/auto/corelib/mimetypes/mimetypes.pro b/tests/auto/corelib/mimetypes/mimetypes.pro new file mode 100644 index 00000000000..9063d677e73 --- /dev/null +++ b/tests/auto/corelib/mimetypes/mimetypes.pro @@ -0,0 +1,8 @@ +TEMPLATE=subdirs + +SUBDIRS = \ + qmimetype \ + qmimedatabase + +!contains(QT_CONFIG, private_tests): SUBDIRS -= \ + qmimetype diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro new file mode 100644 index 00000000000..815401ce1e1 --- /dev/null +++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro @@ -0,0 +1,12 @@ +CONFIG += testcase parallel_test + +TARGET = tst_qmimedatabase-cache + +QT = core testlib concurrent + +SOURCES = tst_qmimedatabase-cache.cpp +HEADERS = ../tst_qmimedatabase.h + +DEFINES += SRCDIR='"\\"$$PWD/../\\""' + +*-g++*:QMAKE_CXXFLAGS += -W -Wall -Wextra -Werror -Wshadow -Wno-long-long -Wnon-virtual-dtor diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp new file mode 100644 index 00000000000..205331d4ddc --- /dev/null +++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite 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 "../tst_qmimedatabase.h" +#include +#include +#include +#include + +#include "../tst_qmimedatabase.cpp" + +tst_QMimeDatabase::tst_QMimeDatabase() +{ + QDir here = QDir::currentPath(); + const QString tempMime = here.absolutePath() + QString::fromLatin1("/mime"); + runUpdateMimeDatabase(tempMime); + QVERIFY(QFile::exists(tempMime + QString::fromLatin1("/mime.cache"))); +} diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro new file mode 100644 index 00000000000..ac7515f7819 --- /dev/null +++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro @@ -0,0 +1,14 @@ +CONFIG += testcase parallel_test + +TARGET = tst_qmimedatabase-xml + +QT = core testlib concurrent + +CONFIG += depend_includepath + +SOURCES += tst_qmimedatabase-xml.cpp +HEADERS += ../tst_qmimedatabase.h + +DEFINES += SRCDIR='"\\"$$PWD/../\\""' + +*-g++*:QMAKE_CXXFLAGS += -W -Wall -Wextra -Werror -Wshadow -Wno-long-long -Wnon-virtual-dtor diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp new file mode 100644 index 00000000000..13ca372290a --- /dev/null +++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite 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 "../tst_qmimedatabase.h" +#include +#include + +tst_QMimeDatabase::tst_QMimeDatabase() +{ + qputenv("QT_NO_MIME_CACHE", "1"); +} + +#include "../tst_qmimedatabase.cpp" diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro new file mode 100644 index 00000000000..876b4377dd0 --- /dev/null +++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS = qmimedatabase-xml +unix: SUBDIRS += qmimedatabase-cache diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp new file mode 100644 index 00000000000..12d6587dfb0 --- /dev/null +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp @@ -0,0 +1,829 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite 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 + +#include "qstandardpaths.h" + +#include +#include +#include + +#include + +void initializeLang() +{ + qputenv("LANG", "en_US"); +} + +// Set LANG before QCoreApplication is created +Q_CONSTRUCTOR_FUNCTION(initializeLang) + +void tst_QMimeDatabase::initTestCase() +{ + // Create a "global" and a "local" XDG data dir, right here. + // The local dir will be empty initially, while the global dir will contain a copy of freedesktop.org.xml + + QDir here = QDir::currentPath(); + + qputenv("XDG_DATA_DIRS", QFile::encodeName(here.absolutePath())); + QDir(here.absolutePath() + "/mime").removeRecursively(); + here.mkpath(QString::fromLatin1("mime/packages")); + + QFile xml(QFile::decodeName(SRCDIR "../../../src/mimetypes/mime/packages/freedesktop.org.xml")); + const QString mimeDir = here.absolutePath() + QLatin1String("/mime"); + xml.copy(mimeDir + QLatin1String("/packages/freedesktop.org.xml")); + + m_dataHome = here.absolutePath() + QLatin1String("/../datahome"); + qputenv("XDG_DATA_HOME", QFile::encodeName(m_dataHome)); + //qDebug() << "XDG_DATA_HOME=" << m_dataHome; + + // Make sure we start clean + cleanupTestCase(); +} + +void tst_QMimeDatabase::cleanupTestCase() +{ + QDir here = QDir::currentPath(); + here.remove(QString::fromLatin1("mime/packages/yast2-metapackage-handler-mimetypes.xml")); + + QDir(m_dataHome).removeRecursively(); +} + +void tst_QMimeDatabase::mimeTypeForName() +{ + QMimeDatabase db; + QMimeType s0 = db.mimeTypeForName(QString::fromLatin1("application/x-zerosize")); + QVERIFY(s0.isValid()); + QCOMPARE(s0.name(), QString::fromLatin1("application/x-zerosize")); + QCOMPARE(s0.comment(), QString::fromLatin1("empty document")); + + QMimeType s0Again = db.mimeTypeForName(QString::fromLatin1("application/x-zerosize")); + QCOMPARE(s0Again.name(), s0.name()); + + QMimeType s1 = db.mimeTypeForName(QString::fromLatin1("text/plain")); + QVERIFY(s1.isValid()); + QCOMPARE(s1.name(), QString::fromLatin1("text/plain")); + //qDebug("Comment is %s", qPrintable(s1.comment())); + + QMimeType krita = db.mimeTypeForName(QString::fromLatin1("application/x-krita")); + QVERIFY(krita.isValid()); + + // Test parsing with application/rdf+xml which has the english comment after the other ones + QMimeType rdf = db.mimeTypeForName(QString::fromLatin1("application/rdf+xml")); + QVERIFY(rdf.isValid()); + QCOMPARE(rdf.comment(), QString::fromLatin1("RDF file")); + + QMimeType bzip2 = db.mimeTypeForName(QString::fromLatin1("application/x-bzip2")); + QVERIFY(bzip2.isValid()); + QCOMPARE(bzip2.comment(), QString::fromLatin1("Bzip archive")); + + QMimeType defaultMime = db.mimeTypeForName(QString::fromLatin1("application/octet-stream")); + QVERIFY(defaultMime.isValid()); + QVERIFY(defaultMime.isDefault()); + + QMimeType doesNotExist = db.mimeTypeForName(QString::fromLatin1("foobar/x-doesnot-exist")); + QVERIFY(!doesNotExist.isValid()); + + // TODO move to findByFile +#ifdef Q_OS_LINUX + QString exePath = QStandardPaths::findExecutable(QLatin1String("ls")); + if (exePath.isEmpty()) + qWarning() << "ls not found"; + else { + const QString executableType = QString::fromLatin1("application/x-executable"); + //QTest::newRow("executable") << exePath << executableType; + QCOMPARE(db.mimeTypeForFile(exePath).name(), executableType); + } +#endif + +} + +void tst_QMimeDatabase::mimeTypeForFileName_data() +{ + QTest::addColumn("fileName"); + QTest::addColumn("expectedMimeType"); + + QTest::newRow("text") << "textfile.txt" << "text/plain"; + QTest::newRow("case-insensitive search") << "textfile.TxT" << "text/plain"; + + // Needs shared-mime-info > 0.91. Earlier versions wrote .Z to the mime.cache file... + //QTest::newRow("case-insensitive match on a non-lowercase glob") << "foo.z" << "application/x-compress"; + + QTest::newRow("case-sensitive uppercase match") << "textfile.C" << "text/x-c++src"; + QTest::newRow("case-sensitive lowercase match") << "textfile.c" << "text/x-csrc"; + QTest::newRow("case-sensitive long-extension match") << "foo.PS.gz" << "application/x-gzpostscript"; + QTest::newRow("case-sensitive-only match") << "core" << "application/x-core"; + QTest::newRow("case-sensitive-only match") << "Core" << "application/octet-stream"; // #198477 + + QTest::newRow("desktop file") << "foo.desktop" << "application/x-desktop"; + QTest::newRow("old kdelnk file is x-desktop too") << "foo.kdelnk" << "application/x-desktop"; + QTest::newRow("double-extension file") << "foo.tar.bz2" << "application/x-bzip-compressed-tar"; + QTest::newRow("single-extension file") << "foo.bz2" << "application/x-bzip"; + QTest::newRow(".doc should assume msword") << "somefile.doc" << "application/msword"; // #204139 + QTest::newRow("glob that uses [] syntax, 1") << "Makefile" << "text/x-makefile"; + QTest::newRow("glob that uses [] syntax, 2") << "makefile" << "text/x-makefile"; + QTest::newRow("glob that ends with *, no extension") << "README" << "text/x-readme"; + QTest::newRow("glob that ends with *, extension") << "README.foo" << "text/x-readme"; + QTest::newRow("glob that ends with *, also matches *.txt. Higher weight wins.") << "README.txt" << "text/plain"; + QTest::newRow("glob that ends with *, also matches *.nfo. Higher weight wins.") << "README.nfo" << "text/x-nfo"; + // fdo bug 15436, needs shared-mime-info >= 0.40 (and this tests the globs2-parsing code). + QTest::newRow("glob that ends with *, also matches *.pdf. *.pdf has higher weight") << "README.pdf" << "application/pdf"; + QTest::newRow("directory") << "/" << "inode/directory"; + QTest::newRow("doesn't exist, no extension") << "IDontExist" << "application/octet-stream"; + QTest::newRow("doesn't exist but has known extension") << "IDontExist.txt" << "text/plain"; +} + +void tst_QMimeDatabase::mimeTypeForFileName() +{ + QFETCH(QString, fileName); + QFETCH(QString, expectedMimeType); + QMimeDatabase db; + QMimeType mime = db.mimeTypeForFile(fileName, QMimeDatabase::MatchExtension); + QVERIFY(mime.isValid()); + QCOMPARE(mime.name(), expectedMimeType); + + QList mimes = db.mimeTypesForFileName(fileName); + if (expectedMimeType == "application/octet-stream") { + QVERIFY(mimes.isEmpty()); + } else { + QVERIFY(!mimes.isEmpty()); + QCOMPARE(mimes.count(), 1); + QCOMPARE(mimes.first().name(), expectedMimeType); + } +} + +void tst_QMimeDatabase::mimeTypesForFileName_data() +{ + QTest::addColumn("fileName"); + QTest::addColumn("expectedMimeTypes"); + + QTest::newRow("txt, 1 hit") << "foo.txt" << (QStringList() << "text/plain"); + QTest::newRow("txtfoobar, 0 hit") << "foo.foobar" << QStringList(); + QTest::newRow("m, 2 hits") << "foo.m" << (QStringList() << "text/x-matlab" << "text/x-objcsrc"); + QTest::newRow("sub, 3 hits") << "foo.sub" << (QStringList() << "text/x-microdvd" << "text/x-mpsub" << "text/x-subviewer"); +} + +void tst_QMimeDatabase::mimeTypesForFileName() +{ + QFETCH(QString, fileName); + QFETCH(QStringList, expectedMimeTypes); + QMimeDatabase db; + QList mimes = db.mimeTypesForFileName(fileName); + QStringList mimeNames; + foreach (const QMimeType &mime, mimes) + mimeNames.append(mime.name()); + QCOMPARE(mimeNames, expectedMimeTypes); +} + +void tst_QMimeDatabase::inheritance() +{ + QMimeDatabase db; + + // All file-like mimetypes inherit from octet-stream + const QMimeType wordperfect = db.mimeTypeForName(QString::fromLatin1("application/vnd.wordperfect")); + QVERIFY(wordperfect.isValid()); + QCOMPARE(wordperfect.parentMimeTypes().join(QString::fromLatin1(",")), QString::fromLatin1("application/octet-stream")); + QVERIFY(wordperfect.inherits(QLatin1String("application/octet-stream"))); + + QVERIFY(db.mimeTypeForName(QString::fromLatin1("image/svg+xml-compressed")).inherits(QLatin1String("application/x-gzip"))); + + // Check that msword derives from ole-storage + const QMimeType msword = db.mimeTypeForName(QString::fromLatin1("application/msword")); + QVERIFY(msword.isValid()); + const QMimeType olestorage = db.mimeTypeForName(QString::fromLatin1("application/x-ole-storage")); + QVERIFY(olestorage.isValid()); + QVERIFY(msword.inherits(olestorage.name())); + QVERIFY(msword.inherits(QLatin1String("application/octet-stream"))); + + const QMimeType directory = db.mimeTypeForName(QString::fromLatin1("inode/directory")); + QVERIFY(directory.isValid()); + QCOMPARE(directory.parentMimeTypes().count(), 0); + QVERIFY(!directory.inherits(QLatin1String("application/octet-stream"))); + + // Check that text/x-patch knows that it inherits from text/plain (it says so explicitly) + const QMimeType plain = db.mimeTypeForName(QString::fromLatin1("text/plain")); + const QMimeType derived = db.mimeTypeForName(QString::fromLatin1("text/x-patch")); + QVERIFY(derived.isValid()); + QCOMPARE(derived.parentMimeTypes().join(QString::fromLatin1(",")), plain.name()); + QVERIFY(derived.inherits(QLatin1String("text/plain"))); + QVERIFY(derived.inherits(QLatin1String("application/octet-stream"))); + + // Check that application/x-shellscript inherits from application/x-executable + // (Otherwise KRun cannot start shellscripts...) + // This is a test for multiple inheritance... + const QMimeType shellscript = db.mimeTypeForName(QString::fromLatin1("application/x-shellscript")); + QVERIFY(shellscript.isValid()); + QVERIFY(shellscript.inherits(QLatin1String("text/plain"))); + QVERIFY(shellscript.inherits(QLatin1String("application/x-executable"))); + const QStringList shellParents = shellscript.parentMimeTypes(); + QVERIFY(shellParents.contains(QLatin1String("text/plain"))); + QVERIFY(shellParents.contains(QLatin1String("application/x-executable"))); + QCOMPARE(shellParents.count(), 2); // only the above two + const QStringList allShellAncestors = shellscript.allAncestors(); + QVERIFY(allShellAncestors.contains(QLatin1String("text/plain"))); + QVERIFY(allShellAncestors.contains(QLatin1String("application/x-executable"))); + QVERIFY(allShellAncestors.contains(QLatin1String("application/octet-stream"))); + // Must be least-specific last, i.e. breadth first. + QCOMPARE(allShellAncestors.last(), QString::fromLatin1("application/octet-stream")); + + const QStringList allSvgAncestors = db.mimeTypeForName(QString::fromLatin1("image/svg+xml")).allAncestors(); + QCOMPARE(allSvgAncestors, QStringList() << QLatin1String("application/xml") << QLatin1String("text/plain") << QLatin1String("application/octet-stream")); + + // Check that text/x-mrml knows that it inherits from text/plain (implicitly) + const QMimeType mrml = db.mimeTypeForName(QString::fromLatin1("text/x-mrml")); + QVERIFY(mrml.isValid()); + QVERIFY(mrml.inherits(QLatin1String("text/plain"))); + QVERIFY(mrml.inherits(QLatin1String("application/octet-stream"))); + + // Check that msword-template inherits msword + const QMimeType mswordTemplate = db.mimeTypeForName(QString::fromLatin1("application/msword-template")); + QVERIFY(mswordTemplate.isValid()); + QVERIFY(mswordTemplate.inherits(QLatin1String("application/msword"))); +} + +void tst_QMimeDatabase::aliases() +{ + QMimeDatabase db; + + const QMimeType canonical = db.mimeTypeForName(QString::fromLatin1("application/xml")); + QVERIFY(canonical.isValid()); + + QMimeType resolvedAlias = db.mimeTypeForName(QString::fromLatin1("text/xml")); + QVERIFY(resolvedAlias.isValid()); + QCOMPARE(resolvedAlias.name(), QString::fromLatin1("application/xml")); + + QVERIFY(resolvedAlias.inherits(QLatin1String("application/xml"))); + QVERIFY(canonical.inherits(QLatin1String("text/xml"))); + + // Test for kde bug 197346: does nspluginscan see that audio/mp3 already exists? + bool mustWriteMimeType = !db.mimeTypeForName(QString::fromLatin1("audio/mp3")).isValid(); + QVERIFY(!mustWriteMimeType); +} + +void tst_QMimeDatabase::icons() +{ + QMimeDatabase db; + QMimeType directory = db.mimeTypeForFile(QString::fromLatin1("/")); + QCOMPARE(directory.name(), QString::fromLatin1("inode/directory")); + QCOMPARE(directory.iconName(), QString::fromLatin1("inode-directory")); + QCOMPARE(directory.genericIconName(), QString::fromLatin1("inode-x-generic")); + + QMimeType pub = db.mimeTypeForFile(QString::fromLatin1("foo.epub"), QMimeDatabase::MatchExtension); + QCOMPARE(pub.name(), QString::fromLatin1("application/epub+zip")); + QCOMPARE(pub.iconName(), QString::fromLatin1("application-epub+zip")); + QCOMPARE(pub.genericIconName(), QString::fromLatin1("x-office-document")); +} + +// In here we do the tests that need some content in a temporary file. +// This could also be added to shared-mime-info's testsuite... +void tst_QMimeDatabase::mimeTypeForFileWithContent() +{ + QMimeDatabase db; + QMimeType mime; + + // Test a real PDF file. + // If we find x-matlab because it starts with '%' then we are not ordering by priority. + QTemporaryFile tempFile; + QVERIFY(tempFile.open()); + QString tempFileName = tempFile.fileName(); + tempFile.write("%PDF-"); + tempFile.close(); + mime = db.mimeTypeForFile(tempFileName); + QCOMPARE(mime.name(), QString::fromLatin1("application/pdf")); + QFile file(tempFileName); + mime = db.mimeTypeForData(&file); // QIODevice ctor + QCOMPARE(mime.name(), QString::fromLatin1("application/pdf")); + // by name only, we cannot find the mimetype + mime = db.mimeTypeForFile(tempFileName, QMimeDatabase::MatchExtension); + QVERIFY(mime.isValid()); + QVERIFY(mime.isDefault()); + + // Test the case where the extension doesn't match the contents: extension wins + { + QTemporaryFile txtTempFile(QDir::tempPath() + QLatin1String("/tst_QMimeDatabase_XXXXXX.txt")); + QVERIFY(txtTempFile.open()); + txtTempFile.write("%PDF-"); + QString txtTempFileName = txtTempFile.fileName(); + txtTempFile.close(); + mime = db.mimeTypeForFile(txtTempFileName); + QCOMPARE(mime.name(), QString::fromLatin1("text/plain")); + // fast mode finds the same + mime = db.mimeTypeForFile(txtTempFileName, QMimeDatabase::MatchExtension); + QCOMPARE(mime.name(), QString::fromLatin1("text/plain")); + } + + // Now the case where extension differs from contents, but contents has >80 magic rule + // XDG spec says: contents wins. But we can't sniff all files... + { + QTemporaryFile txtTempFile(QDir::tempPath() + QLatin1String("/tst_QMimeDatabase_XXXXXX.txt")); + QVERIFY(txtTempFile.open()); + txtTempFile.write("("data"); + QTest::addColumn("expectedMimeTypeName"); + + QTest::newRow("tnef data, needs smi >= 0.20") << QByteArray("\x78\x9f\x3e\x22") << "application/vnd.ms-tnef"; + QTest::newRow("PDF magic") << QByteArray("%PDF-") << "application/pdf"; + QTest::newRow("PHP, High-priority rule") << QByteArray("("name"); + QTest::addColumn("data"); + QTest::addColumn("expectedMimeTypeName"); + + QTest::newRow("plain text, no extension") << QString::fromLatin1("textfile") << QByteArray("Hello world") << "text/plain"; + QTest::newRow("plain text, unknown extension") << QString::fromLatin1("textfile.foo") << QByteArray("Hello world") << "text/plain"; + // Needs kde/mimetypes.xml + //QTest::newRow("plain text, doc extension") << QString::fromLatin1("textfile.doc") << QByteArray("Hello world") << "text/plain"; + + // If you get powerpoint instead, then you're hit by https://bugs.freedesktop.org/show_bug.cgi?id=435, + // upgrade to shared-mime-info >= 0.22 + const QByteArray oleData("\320\317\021\340\241\261\032\341"); // same as \xD0\xCF\x11\xE0 \xA1\xB1\x1A\xE1 + QTest::newRow("msword file, unknown extension") << QString::fromLatin1("mswordfile") << oleData << "application/x-ole-storage"; + QTest::newRow("excel file, found by extension") << QString::fromLatin1("excelfile.xls") << oleData << "application/vnd.ms-excel"; + QTest::newRow("text.xls, found by extension, user is in control") << QString::fromLatin1("text.xls") << oleData << "application/vnd.ms-excel"; +} + +void tst_QMimeDatabase::mimeTypeForFileAndContent() +{ + QFETCH(QString, name); + QFETCH(QByteArray, data); + QFETCH(QString, expectedMimeTypeName); + + QMimeDatabase db; + QCOMPARE(db.mimeTypeForNameAndData(name, data).name(), expectedMimeTypeName); + + QBuffer buffer(&data); + QCOMPARE(db.mimeTypeForNameAndData(name, &buffer).name(), expectedMimeTypeName); + QVERIFY(!buffer.isOpen()); // initial state was restored + + QVERIFY(buffer.open(QIODevice::ReadOnly)); + QCOMPARE(db.mimeTypeForNameAndData(name, &buffer).name(), expectedMimeTypeName); + QVERIFY(buffer.isOpen()); + QCOMPARE(buffer.pos(), qint64(0)); +} + +void tst_QMimeDatabase::allMimeTypes() +{ + QMimeDatabase db; + const QList lst = db.allMimeTypes(); // does NOT include aliases + QVERIFY(!lst.isEmpty()); + + // Hardcoding this is the only way to check both providers find the same number of mimetypes. + QCOMPARE(lst.count(), 661); + + foreach (const QMimeType &mime, lst) { + const QString name = mime.name(); + QVERIFY(!name.isEmpty()); + QCOMPARE(name.count(QLatin1Char('/')), 1); + const QMimeType lookedupMime = db.mimeTypeForName(name); + QVERIFY(lookedupMime.isValid()); + QCOMPARE(lookedupMime.name(), name); // if this fails, you have an alias defined as a real mimetype too! + } +} + +void tst_QMimeDatabase::inheritsPerformance() +{ + // Check performance of inherits(). + // This benchmark (which started in 2009 in kmimetypetest.cpp) uses 40 mimetypes. + QStringList mimeTypes; mimeTypes << QLatin1String("image/jpeg") << QLatin1String("image/png") << QLatin1String("image/tiff") << QLatin1String("text/plain") << QLatin1String("text/html"); + mimeTypes += mimeTypes; + mimeTypes += mimeTypes; + mimeTypes += mimeTypes; + QCOMPARE(mimeTypes.count(), 40); + QMimeDatabase db; + QMimeType mime = db.mimeTypeForName(QString::fromLatin1("text/x-chdr")); + QVERIFY(mime.isValid()); + QBENCHMARK { + QString match; + foreach (const QString &mt, mimeTypes) { + if (mime.inherits(mt)) { + match = mt; + // of course there would normally be a "break" here, but we're testing worse-case + // performance here + } + } + QCOMPARE(match, QString::fromLatin1("text/plain")); + } + // Numbers from 2011, in release mode: + // KDE 4.7 numbers: 0.21 msec / 494,000 ticks / 568,345 instr. loads per iteration + // QMimeBinaryProvider (with Qt 5): 0.16 msec / NA / 416,049 instr. reads per iteration + // QMimeXmlProvider (with Qt 5): 0.062 msec / NA / 172,889 instr. reads per iteration + // (but the startup time is way higher) + // And memory usage is flat at 200K with QMimeBinaryProvider, while it peaks at 6 MB when + // parsing XML, and then keeps being around 4.5 MB for all the in-memory hashes. +} + +void tst_QMimeDatabase::suffixes_data() +{ + QTest::addColumn("mimeType"); + QTest::addColumn("patterns"); + QTest::addColumn("preferredSuffix"); + + QTest::newRow("mimetype with a single pattern") << "application/pdf" << "*.pdf" << "pdf"; + QTest::newRow("mimetype with multiple patterns") << "application/x-kpresenter" << "*.kpr;*.kpt" << "kpr"; + //if (KMimeType::sharedMimeInfoVersion() > KDE_MAKE_VERSION(0, 60, 0)) { + QTest::newRow("mimetype with many patterns") << "application/vnd.wordperfect" << "*.wp;*.wp4;*.wp5;*.wp6;*.wpd;*.wpp" << "wp"; + //} + QTest::newRow("oasis text mimetype") << "application/vnd.oasis.opendocument.text" << "*.odt" << "odt"; + QTest::newRow("oasis presentation mimetype") << "application/vnd.oasis.opendocument.presentation" << "*.odp" << "odp"; + QTest::newRow("mimetype with multiple patterns") << "text/plain" << "*.asc;*.txt;*,v" << "txt"; + QTest::newRow("mimetype with uncommon pattern") << "text/x-readme" << "README*" << QString(); + QTest::newRow("mimetype with no patterns") << "application/x-ole-storage" << QString() << QString(); +} + +void tst_QMimeDatabase::suffixes() +{ + QFETCH(QString, mimeType); + QFETCH(QString, patterns); + QFETCH(QString, preferredSuffix); + QMimeDatabase db; + QMimeType mime = db.mimeTypeForName(mimeType); + QVERIFY(mime.isValid()); + // Sort both lists; order is unreliable since shared-mime-info uses hashes internally. + QStringList expectedPatterns = patterns.split(QLatin1Char(';')); + expectedPatterns.sort(); + QStringList mimePatterns = mime.globPatterns(); + mimePatterns.sort(); + QCOMPARE(mimePatterns.join(QLatin1String(";")), expectedPatterns.join(QLatin1String(";"))); + QCOMPARE(mime.preferredSuffix(), preferredSuffix); +} + +void tst_QMimeDatabase::knownSuffix() +{ + QMimeDatabase db; + QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.tar")), QString::fromLatin1("tar")); + QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.bz2")), QString::fromLatin1("bz2")); + QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.bar.bz2")), QString::fromLatin1("bz2")); + QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.tar.bz2")), QString::fromLatin1("tar.bz2")); +} + +void tst_QMimeDatabase::findByFileName_data() +{ + QTest::addColumn("filePath"); + QTest::addColumn("mimeTypeName"); + QTest::addColumn("xFail"); + + QString prefix = QLatin1String(SRCDIR "testfiles/"); + + QFile f(prefix + QLatin1String("list")); + if (!f.open(QIODevice::ReadOnly)) { + const QString warning = QString::fromLatin1( + "Please download the shared-mime-info test suite:\n" + "cd tests/auto/corelib/mimetypes/qmimedatabase\n" + "wget http://cgit.freedesktop.org/xdg/shared-mime-info/snapshot/Release-1-0.zip\n" + "unzip Release-1-0.zip\n" + "ln -s Release-1-0/tests testfiles\n" + ); + qWarning() << warning; + QSKIP("shared-mime-info test suite not available."); + } + + QByteArray line(1024, Qt::Uninitialized); + + while (!f.atEnd()) { + int len = f.readLine(line.data(), 1023); + + if (len <= 2 || line.at(0) == '#') + continue; + + QString string = QString::fromLatin1(line.constData(), len - 1).trimmed(); + QStringList list = string.split(QLatin1Char(' '), QString::SkipEmptyParts); + QVERIFY(list.size() >= 2); + + QString filePath = list.at(0); + QString mimeTypeType = list.at(1); + QString xFail; + if (list.size() >= 3) + xFail = list.at(2); + + QTest::newRow(filePath.toLatin1().constData()) << QString(prefix + filePath) << mimeTypeType << xFail; + } +} + +void tst_QMimeDatabase::findByFileName() +{ + QFETCH(QString, filePath); + QFETCH(QString, mimeTypeName); + QFETCH(QString, xFail); + + QMimeDatabase database; + + //qDebug() << Q_FUNC_INFO << filePath; + + const QMimeType resultMimeType(database.mimeTypeForFile(filePath, QMimeDatabase::MatchExtension)); + if (resultMimeType.isValid()) { + //qDebug() << Q_FUNC_INFO << "MIME type" << resultMimeType.name() << "has generic icon name" << resultMimeType.genericIconName() << "and icon name" << resultMimeType.iconName(); + +// Loading icons depend on the icon theme, we can't enable this test +#if 0 + QCOMPARE(resultMimeType.genericIconName(), QIcon::fromTheme(resultMimeType.genericIconName()).name()); + QVERIFY2(!QIcon::fromTheme(resultMimeType.genericIconName()).isNull(), qPrintable(resultMimeType.genericIconName())); + QVERIFY2(QIcon::hasThemeIcon(resultMimeType.genericIconName()), qPrintable(resultMimeType.genericIconName())); + + QCOMPARE(resultMimeType.iconName(), QIcon::fromTheme(resultMimeType.iconName()).name()); + QVERIFY2(!QIcon::fromTheme(resultMimeType.iconName()).isNull(), qPrintable(resultMimeType.iconName())); + QVERIFY2(QIcon::hasThemeIcon(resultMimeType.iconName()), qPrintable(resultMimeType.iconName())); +#endif + } + const QString resultMimeTypeName = resultMimeType.name(); + //qDebug() << Q_FUNC_INFO << "mimeTypeForFile() returned" << resultMimeTypeName; + + const bool failed = resultMimeTypeName != mimeTypeName; + const bool shouldFail = (xFail.length() >= 1 && xFail.at(0) == QLatin1Char('x')); + if (shouldFail != failed) { + // Results are ambiguous when multiple MIME types have the same glob + // -> accept the current result if the found MIME type actually + // matches the file's extension. + // TODO: a better file format in testfiles/list! + const QMimeType foundMimeType = database.mimeTypeForName(resultMimeTypeName); + QVERIFY2(resultMimeType == foundMimeType, qPrintable(resultMimeType.name() + QString::fromLatin1(" vs. ") + foundMimeType.name())); + if (foundMimeType.isValid()) { + const QString extension = QFileInfo(filePath).suffix(); + //qDebug() << Q_FUNC_INFO << "globPatterns:" << foundMimeType.globPatterns() << "- extension:" << QString() + "*." + extension; + if (foundMimeType.globPatterns().contains(QString::fromLatin1("*.") + extension)) + return; + } + } + if (shouldFail) { + // Expected to fail + QVERIFY2(resultMimeTypeName != mimeTypeName, qPrintable(resultMimeTypeName)); + } else { + QCOMPARE(resultMimeTypeName, mimeTypeName); + } + + // Test QFileInfo overload + const QMimeType mimeForFileInfo = database.mimeTypeForFile(QFileInfo(filePath), QMimeDatabase::MatchExtension); + QCOMPARE(mimeForFileInfo.name(), resultMimeTypeName); +} + +void tst_QMimeDatabase::findByData_data() +{ + findByFileName_data(); +} + +void tst_QMimeDatabase::findByData() +{ + QFETCH(QString, filePath); + QFETCH(QString, mimeTypeName); + QFETCH(QString, xFail); + + QMimeDatabase database; + QFile f(filePath); + QVERIFY(f.open(QIODevice::ReadOnly)); + QByteArray data = f.read(16384); + + const QString resultMimeTypeName = database.mimeTypeForData(data).name(); + if (xFail.length() >= 2 && xFail.at(1) == QLatin1Char('x')) { + // Expected to fail + QVERIFY2(resultMimeTypeName != mimeTypeName, qPrintable(resultMimeTypeName)); + } else { + QCOMPARE(resultMimeTypeName, mimeTypeName); + } + + QFileInfo info(filePath); + QString mimeForInfo = database.mimeTypeForFile(info, QMimeDatabase::MatchContent).name(); + QCOMPARE(mimeForInfo, resultMimeTypeName); +} + +void tst_QMimeDatabase::findByFile_data() +{ + findByFileName_data(); +} + +void tst_QMimeDatabase::findByFile() +{ + QFETCH(QString, filePath); + QFETCH(QString, mimeTypeName); + QFETCH(QString, xFail); + + QMimeDatabase database; + const QString resultMimeTypeName = database.mimeTypeForFile(filePath).name(); + //qDebug() << Q_FUNC_INFO << filePath << "->" << resultMimeTypeName; + if (xFail.length() >= 3 && xFail.at(2) == QLatin1Char('x')) { + // Expected to fail + QVERIFY2(resultMimeTypeName != mimeTypeName, qPrintable(resultMimeTypeName)); + } else { + QCOMPARE(resultMimeTypeName, mimeTypeName); + } + + // Test QFileInfo overload + const QMimeType mimeForFileInfo = database.mimeTypeForFile(QFileInfo(filePath)); + QCOMPARE(mimeForFileInfo.name(), resultMimeTypeName); +} + + +void tst_QMimeDatabase::fromThreads() +{ + QThreadPool::globalInstance()->setMaxThreadCount(20); + // Note that data-based tests cannot be used here (QTest::fetchData asserts). + QList > futures; + futures << QtConcurrent::run(this, &tst_QMimeDatabase::mimeTypeForName); + futures << QtConcurrent::run(this, &tst_QMimeDatabase::aliases); + futures << QtConcurrent::run(this, &tst_QMimeDatabase::allMimeTypes); + futures << QtConcurrent::run(this, &tst_QMimeDatabase::icons); + futures << QtConcurrent::run(this, &tst_QMimeDatabase::inheritance); + futures << QtConcurrent::run(this, &tst_QMimeDatabase::knownSuffix); + futures << QtConcurrent::run(this, &tst_QMimeDatabase::mimeTypeForFileWithContent); + futures << QtConcurrent::run(this, &tst_QMimeDatabase::allMimeTypes); // a second time + Q_FOREACH (QFuture f, futures) + f.waitForFinished(); +} + +static void runUpdateMimeDatabase(const QString &path) // TODO make it a QMimeDatabase method? +{ + const QString umd = QStandardPaths::findExecutable(QString::fromLatin1("update-mime-database")); + if (umd.isEmpty()) + QSKIP("shared-mime-info not found, skipping mime.cache test"); + + QProcess proc; + proc.setProcessChannelMode(QProcess::MergedChannels); // silence output + proc.start(umd, QStringList() << path); + proc.waitForFinished(); + //qDebug() << "runUpdateMimeDatabase" << path; +} + +static void waitAndRunUpdateMimeDatabase(const QString &path) +{ + QFileInfo mimeCacheInfo(path + QString::fromLatin1("/mime.cache")); + if (mimeCacheInfo.exists()) { + // Wait until the begining of the next second + while (mimeCacheInfo.lastModified().secsTo(QDateTime::currentDateTime()) == 0) { + QTest::qSleep(200); + } + } + runUpdateMimeDatabase(path); +} + +static void checkHasMimeType(const QString &mimeType) +{ + QMimeDatabase db; + QVERIFY(db.mimeTypeForName(mimeType).isValid()); + + bool found = false; + foreach (const QMimeType &mt, db.allMimeTypes()) { + if (mt.name() == mimeType) { + found = true; + break; + } + } + QVERIFY(found); +} + +QT_BEGIN_NAMESPACE +extern Q_CORE_EXPORT int qmime_secondsBetweenChecks; // see qmimeprovider.cpp +QT_END_NAMESPACE + +void tst_QMimeDatabase::installNewGlobalMimeType() +{ + qmime_secondsBetweenChecks = 0; + + QMimeDatabase db; + QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid()); + + const QString fileName = QLatin1String("yast2-metapackage-handler-mimetypes.xml"); + const QString srcFile = QFile::decodeName(SRCDIR) + fileName; + + QDir here = QDir::currentPath(); + const QString mimeDir = here.absolutePath() + QLatin1String("/mime"); + const QString destDir = mimeDir + QLatin1String("/packages/"); + const QString destFile = destDir + fileName; + QFile::remove(destFile); + //qDebug() << destFile; + QVERIFY(QFile::copy(srcFile, destFile)); + waitAndRunUpdateMimeDatabase(mimeDir); + + QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(), + QString::fromLatin1("text/x-suse-ymu")); + QVERIFY(db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid()); + checkHasMimeType("text/x-suse-ymp"); + + // Now test removing it again + QFile::remove(destFile); + waitAndRunUpdateMimeDatabase(mimeDir); + QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(), + QString::fromLatin1("application/octet-stream")); + QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid()); +} + +void tst_QMimeDatabase::installNewLocalMimeType() +{ + qmime_secondsBetweenChecks = 0; + + QMimeDatabase db; + QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid()); + + const QString fileName = QLatin1String("yast2-metapackage-handler-mimetypes.xml"); + const QString srcFile = QFile::decodeName(SRCDIR) + fileName; + const QString mimeDir = m_dataHome + QLatin1String("/mime"); + const QString destDir = mimeDir + QLatin1String("/packages/"); + QDir().mkpath(destDir); + const QString destFile = destDir + fileName; + QFile::remove(destFile); + QVERIFY(QFile::copy(srcFile, destFile)); + runUpdateMimeDatabase(mimeDir); + + QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(), + QString::fromLatin1("text/x-suse-ymu")); + QVERIFY(db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid()); + checkHasMimeType("text/x-suse-ymp"); + + // Now test removing it again (note, this leaves a mostly-empty mime.cache file) + QFile::remove(destFile); + waitAndRunUpdateMimeDatabase(mimeDir); + QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(), + QString::fromLatin1("application/octet-stream")); + QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid()); + + // And now the user goes wild and uses rm -rf + QFile::remove(mimeDir + QString::fromLatin1("/mime.cache")); + QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(), + QString::fromLatin1("application/octet-stream")); + QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid()); +} + +QTEST_GUILESS_MAIN(tst_QMimeDatabase) diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h new file mode 100644 index 00000000000..869990401c5 --- /dev/null +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite 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 TST_QMIMEDATABASE_H +#define TST_QMIMEDATABASE_H + +#include + +class tst_QMimeDatabase : public QObject +{ + Q_OBJECT + +public: + tst_QMimeDatabase(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void mimeTypeForName(); + void mimeTypeForFileName_data(); + void mimeTypeForFileName(); + void mimeTypesForFileName_data(); + void mimeTypesForFileName(); + void inheritance(); + void aliases(); + void icons(); + void mimeTypeForFileWithContent(); + void mimeTypeForUrl(); + void mimeTypeForData_data(); + void mimeTypeForData(); + void mimeTypeForFileAndContent_data(); + void mimeTypeForFileAndContent(); + void allMimeTypes(); + void inheritsPerformance(); + void suffixes_data(); + void suffixes(); + void knownSuffix(); + void fromThreads(); + + // shared-mime-info test suite + + void findByFileName_data(); + void findByFileName(); + + void findByData_data(); + void findByData(); + + void findByFile_data(); + void findByFile(); + + // + + void installNewGlobalMimeType(); + void installNewLocalMimeType(); + +private: + QString m_dataHome; +}; + +#endif // TST_QMIMEDATABASE_H diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/yast2-metapackage-handler-mimetypes.xml b/tests/auto/corelib/mimetypes/qmimedatabase/yast2-metapackage-handler-mimetypes.xml new file mode 100644 index 00000000000..ef3035ef4a3 --- /dev/null +++ b/tests/auto/corelib/mimetypes/qmimedatabase/yast2-metapackage-handler-mimetypes.xml @@ -0,0 +1,15 @@ + + + + + + YaST Meta Package + + + + + URL of a YaST Meta Package + + + + diff --git a/tests/auto/corelib/mimetypes/qmimetype/qmimetype.pro b/tests/auto/corelib/mimetypes/qmimetype/qmimetype.pro new file mode 100644 index 00000000000..125d0d280fe --- /dev/null +++ b/tests/auto/corelib/mimetypes/qmimetype/qmimetype.pro @@ -0,0 +1,7 @@ +CONFIG += testcase parallel_test +TARGET = tst_qmimetype +QT = core-private testlib + +*-g++*:QMAKE_CXXFLAGS += -W -Wall -Wextra -Werror -Wshadow -Wno-long-long -Wnon-virtual-dtor + +SOURCES = tst_qmimetype.cpp diff --git a/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp b/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp new file mode 100644 index 00000000000..6f24bfe6f12 --- /dev/null +++ b/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp @@ -0,0 +1,257 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite 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 + +#include +#include + +#include + + +class tst_qmimetype : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + + void isValid(); + void name(); + void genericIconName(); + void iconName(); + void suffixes(); +}; + +// ------------------------------------------------------------------------------------------------ + +void tst_qmimetype::initTestCase() +{ + qputenv("XDG_DATA_DIRS", "doesnotexist"); +} + +// ------------------------------------------------------------------------------------------------ + +static QString qMimeTypeName() +{ + static const QString result ("No name of the MIME type"); + return result; +} + +static QString qMimeTypeGenericIconName() +{ + static const QString result ("No file name of an icon image that represents the MIME type"); + return result; +} + +static QString qMimeTypeIconName() +{ + static const QString result ("No file name of an icon image that represents the MIME type"); + return result; +} + +static QStringList buildQMimeTypeFilenameExtensions() +{ + QStringList result; + result << QString::fromLatin1("*.png"); + return result; +} + +static QStringList qMimeTypeGlobPatterns() +{ + static const QStringList result (buildQMimeTypeFilenameExtensions()); + return result; +} + +// ------------------------------------------------------------------------------------------------ + +#ifndef Q_COMPILER_RVALUE_REFS +QMIMETYPE_BUILDER +#else +QMIMETYPE_BUILDER_FROM_RVALUE_REFS +#endif + +// ------------------------------------------------------------------------------------------------ + +void tst_qmimetype::isValid() +{ + QMimeType instantiatedQMimeType ( + buildQMimeType ( + qMimeTypeName(), + qMimeTypeGenericIconName(), + qMimeTypeIconName(), + qMimeTypeGlobPatterns() + ) + ); + + QVERIFY(instantiatedQMimeType.isValid()); + + QMimeType otherQMimeType (instantiatedQMimeType); + + QVERIFY(otherQMimeType.isValid()); + QCOMPARE(instantiatedQMimeType, otherQMimeType); + + QMimeType defaultQMimeType; + + QVERIFY(!defaultQMimeType.isValid()); +} + +// ------------------------------------------------------------------------------------------------ + +void tst_qmimetype::name() +{ + QMimeType instantiatedQMimeType ( + buildQMimeType ( + qMimeTypeName(), + qMimeTypeGenericIconName(), + qMimeTypeIconName(), + qMimeTypeGlobPatterns() + ) + ); + + QMimeType otherQMimeType ( + buildQMimeType ( + QString(), + qMimeTypeGenericIconName(), + qMimeTypeIconName(), + qMimeTypeGlobPatterns() + ) + ); + + // Verify that the Name is part of the equality test: + QCOMPARE(instantiatedQMimeType.name(), qMimeTypeName()); + + QVERIFY(instantiatedQMimeType != otherQMimeType); + QVERIFY(!(instantiatedQMimeType == otherQMimeType)); +} + +// ------------------------------------------------------------------------------------------------ + +void tst_qmimetype::genericIconName() +{ + QMimeType instantiatedQMimeType ( + buildQMimeType ( + qMimeTypeName(), + qMimeTypeGenericIconName(), + qMimeTypeIconName(), + qMimeTypeGlobPatterns() + ) + ); + + QMimeType otherQMimeType ( + buildQMimeType ( + qMimeTypeName(), + QString(), + qMimeTypeGenericIconName(), + qMimeTypeGlobPatterns() + ) + ); + + // Verify that the GenericIconName is part of the equality test: + QCOMPARE(instantiatedQMimeType.genericIconName(), qMimeTypeGenericIconName()); + + QVERIFY(instantiatedQMimeType != otherQMimeType); + QVERIFY(!(instantiatedQMimeType == otherQMimeType)); +} + +// ------------------------------------------------------------------------------------------------ + +void tst_qmimetype::iconName() +{ + QMimeType instantiatedQMimeType ( + buildQMimeType ( + qMimeTypeName(), + qMimeTypeGenericIconName(), + qMimeTypeIconName(), + qMimeTypeGlobPatterns() + ) + ); + + QMimeType otherQMimeType ( + buildQMimeType ( + qMimeTypeName(), + qMimeTypeGenericIconName(), + QString(), + qMimeTypeGlobPatterns() + ) + ); + + // Verify that the IconName is part of the equality test: + QCOMPARE(instantiatedQMimeType.iconName(), qMimeTypeIconName()); + + QVERIFY(instantiatedQMimeType != otherQMimeType); + QVERIFY(!(instantiatedQMimeType == otherQMimeType)); +} + +// ------------------------------------------------------------------------------------------------ + +void tst_qmimetype::suffixes() +{ + QMimeType instantiatedQMimeType ( + buildQMimeType ( + qMimeTypeName(), + qMimeTypeGenericIconName(), + qMimeTypeIconName(), + qMimeTypeGlobPatterns() + ) + ); + + QMimeType otherQMimeType ( + buildQMimeType ( + qMimeTypeName(), + qMimeTypeGenericIconName(), + qMimeTypeIconName(), + QStringList() + ) + ); + + // Verify that the Suffixes are part of the equality test: + QCOMPARE(instantiatedQMimeType.globPatterns(), qMimeTypeGlobPatterns()); + QCOMPARE(instantiatedQMimeType.suffixes(), QStringList() << QString::fromLatin1("png")); + + QVERIFY(instantiatedQMimeType != otherQMimeType); + QVERIFY(!(instantiatedQMimeType == otherQMimeType)); +} + +// ------------------------------------------------------------------------------------------------ + +QTEST_GUILESS_MAIN(tst_qmimetype) +#include "tst_qmimetype.moc" From 2e18c16e59c535ee9907a6ccd1ca2fe5a4da8455 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Thu, 16 Feb 2012 09:47:32 +0100 Subject: [PATCH 347/406] Speed up tst_QWaitCondition Reduce the thread and iteration counts to make this test execute faster. This change reduces the runtime to 14 seconds (from 5 minutes, 38 seconds). Change-Id: Id5ea056cfd33022da5a06809f0598a5cdb02b27b Reviewed-by: Rohan McGovern --- .../corelib/thread/qwaitcondition/tst_qwaitcondition.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp b/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp index 73cb8e9cd64..0e1fa47a3e5 100644 --- a/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp +++ b/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp @@ -59,14 +59,8 @@ private slots: void wait_RaceCondition(); }; -static const int iterations = 10; - -// Note: some tests rely on ThreadCount being multiple of 2 -#if defined(Q_OS_SOLARIS) || ( defined(Q_OS_LINUX) && defined(Q_PROCESSOR_ARM) ) +static const int iterations = 4; static const int ThreadCount = 4; -#else -static const int ThreadCount = 10; -#endif class wait_QMutex_Thread_1 : public QThread { From 02140e973b86d1fbb25ec695daa59e6ff97138c5 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Mon, 20 Feb 2012 10:50:06 +1000 Subject: [PATCH 348/406] Remove unnecessary image height adjustments from layout. cb8445f0323b0eefbb04f1d8adad81a00b53abd8 removes an implied +1 from document line height so we need to remove the compensating -1 from image ascent/descent for image heights to be correct.. Change-Id: I310c06bcf1ce2eefef42c2828faa0eb435ad71cf Reviewed-by: Yann Bodson --- src/gui/text/qtextdocumentlayout.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index cc3372d6e89..2aedfe9133a 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -3002,15 +3002,15 @@ void QTextDocumentLayout::resizeInlineObject(QTextInlineObject item, int posInDo { case QTextCharFormat::AlignMiddle: item.setDescent(inlineSize.height() / 2); - item.setAscent(inlineSize.height() / 2 - 1); + item.setAscent(inlineSize.height() / 2); break; case QTextCharFormat::AlignBaseline: item.setDescent(m.descent()); - item.setAscent(inlineSize.height() - m.descent() - 1); + item.setAscent(inlineSize.height() - m.descent()); break; default: item.setDescent(0); - item.setAscent(inlineSize.height() - 1); + item.setAscent(inlineSize.height()); } } From f64f428b8112fb39558cbfe160693e1e4365f7f4 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Fri, 17 Feb 2012 15:11:20 +1000 Subject: [PATCH 349/406] testlib: make XPASS output slightly less confusing. Prior to this commit, when an unexpected pass occurred the test output showed the message "XPASS : tst_foo::function() 'expr' returned FALSE", where the problem was actually that the expression evaluated to true when it was expected to be false. This commit changes the output to make it clear that the expression evaluated to true unexpectedly. Task-number: QTBUG-22118 Change-Id: Id22c178073d3b75789675ca37a8ef019029b1f91 Reviewed-by: Rohan McGovern --- src/testlib/qtestresult.cpp | 5 ++++- tests/auto/testlib/selftests/expected_expectfail.lightxml | 4 ++-- tests/auto/testlib/selftests/expected_expectfail.txt | 4 ++-- tests/auto/testlib/selftests/expected_expectfail.xml | 4 ++-- tests/auto/testlib/selftests/expected_expectfail.xunitxml | 4 ++-- tests/auto/testlib/selftests/expected_xunit.lightxml | 2 +- tests/auto/testlib/selftests/expected_xunit.txt | 2 +- tests/auto/testlib/selftests/expected_xunit.xml | 2 +- tests/auto/testlib/selftests/expected_xunit.xunitxml | 2 +- 9 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp index 79ea22bb434..14ab29af2b4 100644 --- a/src/testlib/qtestresult.cpp +++ b/src/testlib/qtestresult.cpp @@ -237,7 +237,10 @@ bool QTestResult::verify(bool statement, const char *statementStr, QTestLog::info(msg, file, line); } - qsnprintf(msg, 1024, "'%s' returned FALSE. (%s)", statementStr, description); + const char * format = QTest::expectFailMode + ? "'%s' returned TRUE unexpectedly. (%s)" + : "'%s' returned FALSE. (%s)"; + qsnprintf(msg, 1024, format, statementStr, description); return checkStatement(statement, msg, file, line); } diff --git a/tests/auto/testlib/selftests/expected_expectfail.lightxml b/tests/auto/testlib/selftests/expected_expectfail.lightxml index 8fdac12d213..c8088866518 100644 --- a/tests/auto/testlib/selftests/expected_expectfail.lightxml +++ b/tests/auto/testlib/selftests/expected_expectfail.lightxml @@ -95,13 +95,13 @@ - + - + diff --git a/tests/auto/testlib/selftests/expected_expectfail.txt b/tests/auto/testlib/selftests/expected_expectfail.txt index f1ad4061b9b..b11ff05196e 100644 --- a/tests/auto/testlib/selftests/expected_expectfail.txt +++ b/tests/auto/testlib/selftests/expected_expectfail.txt @@ -34,9 +34,9 @@ XFAIL : tst_ExpectFail::xfailOnAnyRow(second row) This test should xfail PASS : tst_ExpectFail::xfailOnAnyRow(second row) FAIL! : tst_ExpectFail::xfailWithoutVerify(first row) QEXPECT_FAIL was called without any subsequent verification statements FAIL! : tst_ExpectFail::xfailWithoutVerify(second row) QEXPECT_FAIL was called without any subsequent verification statements -XPASS : tst_ExpectFail::xpass() 'true' returned FALSE. () +XPASS : tst_ExpectFail::xpass() 'true' returned TRUE unexpectedly. () Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(190)] -XPASS : tst_ExpectFail::xpassDataDriven(XPass) 'true' returned FALSE. () +XPASS : tst_ExpectFail::xpassDataDriven(XPass) 'true' returned TRUE unexpectedly. () Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(212)] PASS : tst_ExpectFail::xpassDataDriven(Pass) PASS : tst_ExpectFail::cleanupTestCase() diff --git a/tests/auto/testlib/selftests/expected_expectfail.xml b/tests/auto/testlib/selftests/expected_expectfail.xml index cb061f55bf9..229b0ae697b 100644 --- a/tests/auto/testlib/selftests/expected_expectfail.xml +++ b/tests/auto/testlib/selftests/expected_expectfail.xml @@ -97,13 +97,13 @@ - + - + diff --git a/tests/auto/testlib/selftests/expected_expectfail.xunitxml b/tests/auto/testlib/selftests/expected_expectfail.xunitxml index d13cf6687fe..ca13559cd62 100644 --- a/tests/auto/testlib/selftests/expected_expectfail.xunitxml +++ b/tests/auto/testlib/selftests/expected_expectfail.xunitxml @@ -35,10 +35,10 @@ - + - + diff --git a/tests/auto/testlib/selftests/expected_xunit.lightxml b/tests/auto/testlib/selftests/expected_xunit.lightxml index 35108fc410e..71a57373d60 100644 --- a/tests/auto/testlib/selftests/expected_xunit.lightxml +++ b/tests/auto/testlib/selftests/expected_xunit.lightxml @@ -45,7 +45,7 @@ - + diff --git a/tests/auto/testlib/selftests/expected_xunit.txt b/tests/auto/testlib/selftests/expected_xunit.txt index ae2508c5904..51c8f89599c 100644 --- a/tests/auto/testlib/selftests/expected_xunit.txt +++ b/tests/auto/testlib/selftests/expected_xunit.txt @@ -19,7 +19,7 @@ PASS : tst_Xunit::testFunc5() XFAIL : tst_Xunit::testFunc6() this failure is also expected Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp(104)] PASS : tst_Xunit::testFunc6() -XPASS : tst_Xunit::testFunc7() 'true' returned FALSE. () +XPASS : tst_Xunit::testFunc7() 'true' returned TRUE unexpectedly. () Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp(110)] PASS : tst_Xunit::cleanupTestCase() Totals: 5 passed, 3 failed, 1 skipped diff --git a/tests/auto/testlib/selftests/expected_xunit.xml b/tests/auto/testlib/selftests/expected_xunit.xml index 0fe9735f717..a1e6b209638 100644 --- a/tests/auto/testlib/selftests/expected_xunit.xml +++ b/tests/auto/testlib/selftests/expected_xunit.xml @@ -47,7 +47,7 @@ - + diff --git a/tests/auto/testlib/selftests/expected_xunit.xunitxml b/tests/auto/testlib/selftests/expected_xunit.xunitxml index e77004f819a..e7403443ea4 100644 --- a/tests/auto/testlib/selftests/expected_xunit.xunitxml +++ b/tests/auto/testlib/selftests/expected_xunit.xunitxml @@ -27,7 +27,7 @@ - + From 88c903f6a30bebad312e8cddc418b9612850acd7 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Mon, 20 Feb 2012 10:15:57 +1000 Subject: [PATCH 350/406] testlib: Add selftests for XPASS and XFAIL involving QCOMPARE. Change-Id: I4f897b411aaa51ff453208eda50e12665489074b Reviewed-by: Rohan McGovern --- .../selftests/expected_expectfail.lightxml | 57 ++++++++++---- .../testlib/selftests/expected_expectfail.txt | 51 ++++++++----- .../testlib/selftests/expected_expectfail.xml | 57 ++++++++++---- .../selftests/expected_expectfail.xunitxml | 19 +++-- .../selftests/expectfail/tst_expectfail.cpp | 75 +++++++++++++++++-- 5 files changed, 200 insertions(+), 59 deletions(-) diff --git a/tests/auto/testlib/selftests/expected_expectfail.lightxml b/tests/auto/testlib/selftests/expected_expectfail.lightxml index c8088866518..34f4f1e70b3 100644 --- a/tests/auto/testlib/selftests/expected_expectfail.lightxml +++ b/tests/auto/testlib/selftests/expected_expectfail.lightxml @@ -9,7 +9,7 @@ - + @@ -21,40 +21,62 @@ - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + @@ -68,14 +90,14 @@ - + - + @@ -94,12 +116,12 @@ - + - - + + @@ -107,6 +129,15 @@ + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_expectfail.txt b/tests/auto/testlib/selftests/expected_expectfail.txt index b11ff05196e..bd4e2172d65 100644 --- a/tests/auto/testlib/selftests/expected_expectfail.txt +++ b/tests/auto/testlib/selftests/expected_expectfail.txt @@ -3,42 +3,53 @@ Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE PASS : tst_ExpectFail::initTestCase() QDEBUG : tst_ExpectFail::xfailAndContinue() begin XFAIL : tst_ExpectFail::xfailAndContinue() This should xfail - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(74)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(78)] QDEBUG : tst_ExpectFail::xfailAndContinue() after PASS : tst_ExpectFail::xfailAndContinue() QDEBUG : tst_ExpectFail::xfailAndAbort() begin XFAIL : tst_ExpectFail::xfailAndAbort() This should xfail - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(82)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(86)] PASS : tst_ExpectFail::xfailAndAbort() FAIL! : tst_ExpectFail::xfailTwice() Already expecting a fail - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(92)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(96)] XFAIL : tst_ExpectFail::xfailWithQString() A string - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(101)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(105)] XFAIL : tst_ExpectFail::xfailWithQString() Bug 5 (The message) - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(106)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(110)] PASS : tst_ExpectFail::xfailWithQString() -PASS : tst_ExpectFail::xfailDataDriven(Pass 1) -PASS : tst_ExpectFail::xfailDataDriven(Pass 2) -XFAIL : tst_ExpectFail::xfailDataDriven(Abort) This test should xfail - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(135)] -PASS : tst_ExpectFail::xfailDataDriven(Abort) -XFAIL : tst_ExpectFail::xfailDataDriven(Continue) This test should xfail - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(135)] -PASS : tst_ExpectFail::xfailDataDriven(Continue) +PASS : tst_ExpectFail::xfailDataDrivenWithQVerify(Pass 1) +PASS : tst_ExpectFail::xfailDataDrivenWithQVerify(Pass 2) +XFAIL : tst_ExpectFail::xfailDataDrivenWithQVerify(Abort) This test should xfail + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(139)] +PASS : tst_ExpectFail::xfailDataDrivenWithQVerify(Abort) +XFAIL : tst_ExpectFail::xfailDataDrivenWithQVerify(Continue) This test should xfail + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(139)] +PASS : tst_ExpectFail::xfailDataDrivenWithQVerify(Continue) +PASS : tst_ExpectFail::xfailDataDrivenWithQCompare(Pass 1) +PASS : tst_ExpectFail::xfailDataDrivenWithQCompare(Pass 2) +XFAIL : tst_ExpectFail::xfailDataDrivenWithQCompare(Abort) This test should xfail + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(173)] +PASS : tst_ExpectFail::xfailDataDrivenWithQCompare(Abort) +XFAIL : tst_ExpectFail::xfailDataDrivenWithQCompare(Continue) This test should xfail + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(173)] +PASS : tst_ExpectFail::xfailDataDrivenWithQCompare(Continue) PASS : tst_ExpectFail::xfailOnWrongRow(right row) XFAIL : tst_ExpectFail::xfailOnAnyRow(first row) This test should xfail - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(170)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(208)] PASS : tst_ExpectFail::xfailOnAnyRow(first row) XFAIL : tst_ExpectFail::xfailOnAnyRow(second row) This test should xfail - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(170)] + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(208)] PASS : tst_ExpectFail::xfailOnAnyRow(second row) FAIL! : tst_ExpectFail::xfailWithoutVerify(first row) QEXPECT_FAIL was called without any subsequent verification statements FAIL! : tst_ExpectFail::xfailWithoutVerify(second row) QEXPECT_FAIL was called without any subsequent verification statements XPASS : tst_ExpectFail::xpass() 'true' returned TRUE unexpectedly. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(190)] -XPASS : tst_ExpectFail::xpassDataDriven(XPass) 'true' returned TRUE unexpectedly. () - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(212)] -PASS : tst_ExpectFail::xpassDataDriven(Pass) + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(228)] +XPASS : tst_ExpectFail::xpassDataDrivenWithQVerify(XPass) 'true' returned TRUE unexpectedly. () + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(250)] +PASS : tst_ExpectFail::xpassDataDrivenWithQVerify(Pass) +XPASS : tst_ExpectFail::xpassDataDrivenWithQCompare(XPass) COMPARE() + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(271)] +PASS : tst_ExpectFail::xpassDataDrivenWithQCompare(Pass) PASS : tst_ExpectFail::cleanupTestCase() -Totals: 13 passed, 5 failed, 0 skipped +Totals: 18 passed, 6 failed, 0 skipped ********* Finished testing of tst_ExpectFail ********* diff --git a/tests/auto/testlib/selftests/expected_expectfail.xml b/tests/auto/testlib/selftests/expected_expectfail.xml index 229b0ae697b..ff870a6a68f 100644 --- a/tests/auto/testlib/selftests/expected_expectfail.xml +++ b/tests/auto/testlib/selftests/expected_expectfail.xml @@ -11,7 +11,7 @@ - + @@ -23,40 +23,62 @@ - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + @@ -70,14 +92,14 @@ - + - + @@ -96,12 +118,12 @@ - + - - + + @@ -109,6 +131,15 @@ + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_expectfail.xunitxml b/tests/auto/testlib/selftests/expected_expectfail.xunitxml index ca13559cd62..6040af41ffa 100644 --- a/tests/auto/testlib/selftests/expected_expectfail.xunitxml +++ b/tests/auto/testlib/selftests/expected_expectfail.xunitxml @@ -1,8 +1,8 @@ - + - - + + @@ -21,7 +21,11 @@ - + + + + + @@ -37,9 +41,12 @@ - + + + + @@ -52,6 +59,8 @@ + + diff --git a/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp b/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp index 56895b38015..794b109924a 100644 --- a/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp +++ b/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp @@ -54,8 +54,10 @@ private slots: void xfailAndAbort() const; void xfailTwice() const; void xfailWithQString() const; - void xfailDataDriven_data() const; - void xfailDataDriven() const; + void xfailDataDrivenWithQVerify_data() const; + void xfailDataDrivenWithQVerify() const; + void xfailDataDrivenWithQCompare_data() const; + void xfailDataDrivenWithQCompare() const; void xfailOnWrongRow_data() const; void xfailOnWrongRow() const; void xfailOnAnyRow_data() const; @@ -63,8 +65,10 @@ private slots: void xfailWithoutVerify_data() const; void xfailWithoutVerify() const; void xpass() const; - void xpassDataDriven_data() const; - void xpassDataDriven() const; + void xpassDataDrivenWithQVerify_data() const; + void xpassDataDrivenWithQVerify() const; + void xpassDataDrivenWithQCompare_data() const; + void xpassDataDrivenWithQCompare() const; }; void tst_ExpectFail::xfailAndContinue() const @@ -106,7 +110,7 @@ void tst_ExpectFail::xfailWithQString() const QVERIFY(false); } -void tst_ExpectFail::xfailDataDriven_data() const +void tst_ExpectFail::xfailDataDrivenWithQVerify_data() const { QTest::addColumn("shouldPass"); QTest::addColumn("failMode"); @@ -117,7 +121,7 @@ void tst_ExpectFail::xfailDataDriven_data() const QTest::newRow("Continue") << false << QTest::Continue; } -void tst_ExpectFail::xfailDataDriven() const +void tst_ExpectFail::xfailDataDrivenWithQVerify() const { QFETCH(bool, shouldPass); QFETCH(QTest::TestFailMode, failMode); @@ -140,6 +144,40 @@ void tst_ExpectFail::xfailDataDriven() const QCOMPARE(failMode, QTest::Continue); } +void tst_ExpectFail::xfailDataDrivenWithQCompare_data() const +{ + QTest::addColumn("shouldPass"); + QTest::addColumn("failMode"); + + QTest::newRow("Pass 1") << true << QTest::Abort; + QTest::newRow("Pass 2") << true << QTest::Continue; + QTest::newRow("Abort") << false << QTest::Abort; + QTest::newRow("Continue") << false << QTest::Continue; +} + +void tst_ExpectFail::xfailDataDrivenWithQCompare() const +{ + QFETCH(bool, shouldPass); + QFETCH(QTest::TestFailMode, failMode); + + // You can't pass a variable as the last parameter of QEXPECT_FAIL, + // because the macro adds "QTest::" in front of the last parameter. + // That is why the following code appears to be a little strange. + if (!shouldPass) { + if (failMode == QTest::Abort) + QEXPECT_FAIL(QTest::currentDataTag(), "This test should xfail", Abort); + else + QEXPECT_FAIL(QTest::currentDataTag(), "This test should xfail", Continue); + } + + QCOMPARE(1, shouldPass ? 1 : 2); + + // If we get here, we either expected to pass or we expected to + // fail and the failure mode was Continue. + if (!shouldPass) + QCOMPARE(failMode, QTest::Continue); +} + void tst_ExpectFail::xfailOnWrongRow_data() const { QTest::addColumn("dummy"); @@ -194,7 +232,7 @@ void tst_ExpectFail::xpass() const QVERIFY2(false, "This should not be reached"); } -void tst_ExpectFail::xpassDataDriven_data() const +void tst_ExpectFail::xpassDataDrivenWithQVerify_data() const { QTest::addColumn("shouldXPass"); @@ -202,7 +240,7 @@ void tst_ExpectFail::xpassDataDriven_data() const QTest::newRow("Pass") << false; } -void tst_ExpectFail::xpassDataDriven() const +void tst_ExpectFail::xpassDataDrivenWithQVerify() const { QFETCH(bool, shouldXPass); @@ -215,5 +253,26 @@ void tst_ExpectFail::xpassDataDriven() const QVERIFY2(!shouldXPass, "Test failed to terminate on XPASS"); } +void tst_ExpectFail::xpassDataDrivenWithQCompare_data() const +{ + QTest::addColumn("shouldXPass"); + + QTest::newRow("XPass") << true; + QTest::newRow("Pass") << false; +} + +void tst_ExpectFail::xpassDataDrivenWithQCompare() const +{ + QFETCH(bool, shouldXPass); + + if (shouldXPass) + QEXPECT_FAIL(QTest::currentDataTag(), "This test should xpass", Abort); + + QCOMPARE(1, 1); + + // We should only get here if the test wasn't supposed to xpass. + QVERIFY2(!shouldXPass, "Test failed to terminate on XPASS"); +} + QTEST_MAIN(tst_ExpectFail) #include "tst_expectfail.moc" From 4cb09aea6a4f26f36961da8934819e823cfe2d4d Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Mon, 20 Feb 2012 10:18:01 +1000 Subject: [PATCH 351/406] Fixed qobject unittest to work from installation directory - Made test depend on subprogram to make sure it was there when test ran. - install signalbug subprogram Change-Id: Ie0a19e52d131adcd17c97b263389aecffb81520e Reviewed-by: Rohan McGovern Reviewed-by: Jason McDonald --- tests/auto/corelib/kernel/qobject/qobject.pro | 5 +++-- tests/auto/corelib/kernel/qobject/tst_qobject.pro | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/auto/corelib/kernel/qobject/qobject.pro b/tests/auto/corelib/kernel/qobject/qobject.pro index ee48f56b1de..0f86408fc93 100644 --- a/tests/auto/corelib/kernel/qobject/qobject.pro +++ b/tests/auto/corelib/kernel/qobject/qobject.pro @@ -1,3 +1,4 @@ TEMPLATE = subdirs -SUBDIRS = signalbug tst_qobject.pro -CONFIG += parallel_test +SUBDIRS = signalbug +tst_qobject.pro.depends = $$SUBDIRS +SUBDIRS += tst_qobject.pro diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.pro b/tests/auto/corelib/kernel/qobject/tst_qobject.pro index d74f2bcb0f5..30fd810a2e1 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.pro +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.pro @@ -6,3 +6,6 @@ SOURCES = tst_qobject.cpp # this is here for a reason, moc_oldnormalizedobject.cpp is not auto-generated, it was generated by # moc from Qt 4.6, and should *not* be generated by the current moc SOURCES += moc_oldnormalizeobject.cpp + +load(testcase) # for target.path and installTestHelperApp() +installTestHelperApp("signalbug/signalbug",signalbug,signalbug) From eb52d78e90ad8870a055f586d9d14d7068acd95b Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Fri, 17 Feb 2012 13:39:30 +1000 Subject: [PATCH 352/406] testlib: Report one test result per benchmark test. Prior to this commit, a benchmark test could report 0..n passes and 0..m fails or skips, where n is the number of accumulation iterations used to collect benchmark data and m is the number of times the test function was invoked. Depending on the type of benchmark measurer being used, this could result in a very large volume of test output and inconsistent pass, fail and skip counts between test runs. This commit changes the behaviour so that each benchmark test reports one pass, fail or skip, regardless of the number of iterations used to collect benchmark data. This commit also prevents benchmark data being reported in the test output if the benchmark test failed or skipped, as any benchmark data is of dubious value in such cases. The latter change in behaviour requires a minor modification to the badxml selftest, which now tests quoting of literal strings in xml test output for both passing and failing benchmarks. Finally, this commit also adds a new selftest specifically for verifying correct behaviour for benchmarks that fail or skip. Task-number: QTBUG-24313 Change-Id: I3426dc659a7511b62fd183a031c7235bc753f497 Reviewed-by: Rohan McGovern --- src/testlib/qtestcase.cpp | 39 ++++++---- .../testlib/selftests/badxml/tst_badxml.cpp | 9 ++- .../benchlibcounting/benchlibcounting.pro | 7 ++ .../benchlibcounting/tst_benchlibcounting.cpp | 76 +++++++++++++++++++ .../selftests/expected_badxml.lightxml | 62 ++++++++++----- .../testlib/selftests/expected_badxml.txt | 42 +++++----- .../testlib/selftests/expected_badxml.xml | 62 ++++++++++----- .../selftests/expected_badxml.xunitxml | 26 ++++--- .../selftests/expected_benchlibcallgrind.txt | 3 +- .../expected_benchlibcounting.lightxml | 24 ++++++ .../selftests/expected_benchlibcounting.txt | 13 ++++ .../selftests/expected_benchlibcounting.xml | 27 +++++++ .../expected_benchlibcounting.xunitxml | 20 +++++ .../selftests/expected_benchliboptions.txt | 8 +- tests/auto/testlib/selftests/selftests.pri | 1 + tests/auto/testlib/selftests/selftests.qrc | 4 + .../auto/testlib/selftests/tst_selftests.cpp | 4 + 17 files changed, 342 insertions(+), 85 deletions(-) create mode 100644 tests/auto/testlib/selftests/benchlibcounting/benchlibcounting.pro create mode 100644 tests/auto/testlib/selftests/benchlibcounting/tst_benchlibcounting.cpp create mode 100644 tests/auto/testlib/selftests/expected_benchlibcounting.lightxml create mode 100644 tests/auto/testlib/selftests/expected_benchlibcounting.txt create mode 100644 tests/auto/testlib/selftests/expected_benchlibcounting.xml create mode 100644 tests/auto/testlib/selftests/expected_benchlibcounting.xunitxml diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 8b9ba6d748c..56959ba62db 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1490,6 +1490,7 @@ static void qInvokeTestMethodDataEntry(char *slot) { /* Benchmarking: for each median iteration*/ + bool isBenchmark = false; int i = (QBenchmarkGlobalData::current->measurer->needsWarmupIteration()) ? -1 : 0; QList results; @@ -1516,25 +1517,30 @@ static void qInvokeTestMethodDataEntry(char *slot) if (!invokeOk) QTestResult::addFailure("Unable to execute slot", __FILE__, __LINE__); + isBenchmark = QBenchmarkTestMethodData::current->isBenchmark(); + QTestResult::finishedCurrentTestData(); invokeMethod(QTest::currentTestObject, "cleanup()"); - QTestResult::finishedCurrentTestDataCleanup(); + + // If the test isn't a benchmark, finalize the result after cleanup() has finished. + if (!isBenchmark) + QTestResult::finishedCurrentTestDataCleanup(); // If this test method has a benchmark, repeat until all measurements are // acceptable. // The QBENCHMARK macro increases the number of iterations for each run until // this happens. - } while (invokeOk - && QBenchmarkTestMethodData::current->isBenchmark() - && QBenchmarkTestMethodData::current->resultsAccepted() == false); + } while (invokeOk && isBenchmark + && QBenchmarkTestMethodData::current->resultsAccepted() == false + && !QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed()); QBenchmarkTestMethodData::current->endDataRun(); - if (i > -1) // iteration -1 is the warmup iteration. - results.append(QBenchmarkTestMethodData::current->result); + if (!QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed()) { + if (i > -1) // iteration -1 is the warmup iteration. + results.append(QBenchmarkTestMethodData::current->result); - if (QBenchmarkTestMethodData::current->isBenchmark() && - QBenchmarkGlobalData::current->verboseOutput) { + if (isBenchmark && QBenchmarkGlobalData::current->verboseOutput) { if (i == -1) { QTestLog::info(qPrintable( QString::fromLatin1("warmup stage result : %1") @@ -1545,12 +1551,19 @@ static void qInvokeTestMethodDataEntry(char *slot) .arg(QBenchmarkTestMethodData::current->result.value)), 0, 0); } } - } while (QBenchmarkTestMethodData::current->isBenchmark() - && (++i < QBenchmarkGlobalData::current->adjustMedianIterationCount())); + } + } while (isBenchmark + && (++i < QBenchmarkGlobalData::current->adjustMedianIterationCount()) + && !QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed()); - if (QBenchmarkTestMethodData::current->isBenchmark() - && QBenchmarkTestMethodData::current->resultsAccepted()) - QTestLog::addBenchmarkResult(qMedian(results)); + // If the test is a benchmark, finalize the result after all iterations have finished. + if (isBenchmark) { + bool testPassed = !QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed(); + QTestResult::finishedCurrentTestDataCleanup(); + // Only report benchmark figures if the test passed + if (testPassed && QBenchmarkTestMethodData::current->resultsAccepted()) + QTestLog::addBenchmarkResult(qMedian(results)); + } } /*! diff --git a/tests/auto/testlib/selftests/badxml/tst_badxml.cpp b/tests/auto/testlib/selftests/badxml/tst_badxml.cpp index 1c9a0d9493a..1a143e52439 100644 --- a/tests/auto/testlib/selftests/badxml/tst_badxml.cpp +++ b/tests/auto/testlib/selftests/badxml/tst_badxml.cpp @@ -106,15 +106,18 @@ void tst_BadXml::badDataTag() const QBENCHMARK { } - QFAIL("a failure"); + QFETCH(bool, shouldFail); + if (shouldFail) + QFAIL("a failure"); } void tst_BadXml::badDataTag_data() const { - QTest::addColumn("dummy"); + QTest::addColumn("shouldFail"); foreach (char const* str, badStrings()) { - QTest::newRow(str) << 0; + QTest::newRow(qPrintable(QString("fail %1").arg(str))) << true; + QTest::newRow(qPrintable(QString("pass %1").arg(str))) << false; } } diff --git a/tests/auto/testlib/selftests/benchlibcounting/benchlibcounting.pro b/tests/auto/testlib/selftests/benchlibcounting/benchlibcounting.pro new file mode 100644 index 00000000000..b495995eac3 --- /dev/null +++ b/tests/auto/testlib/selftests/benchlibcounting/benchlibcounting.pro @@ -0,0 +1,7 @@ +SOURCES += tst_benchlibcounting.cpp +QT = core testlib + +mac:CONFIG -= app_bundle +CONFIG -= debug_and_release_target + +TARGET = benchlibcounting diff --git a/tests/auto/testlib/selftests/benchlibcounting/tst_benchlibcounting.cpp b/tests/auto/testlib/selftests/benchlibcounting/tst_benchlibcounting.cpp new file mode 100644 index 00000000000..847bc1a81d8 --- /dev/null +++ b/tests/auto/testlib/selftests/benchlibcounting/tst_benchlibcounting.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite 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 +#include + +class tst_BenchlibCounting : public QObject +{ + Q_OBJECT + +private slots: + void passingBenchmark(); + void skippingBenchmark(); + void failingBenchmark(); +}; + +void tst_BenchlibCounting::passingBenchmark() +{ + QBENCHMARK { + } +} + +void tst_BenchlibCounting::skippingBenchmark() +{ + QBENCHMARK { + QSKIP("This is a skipping benchmark"); + } +} + +void tst_BenchlibCounting::failingBenchmark() +{ + QBENCHMARK { + QFAIL("This is a failing benchmark"); + }; +} + +QTEST_MAIN(tst_BenchlibCounting) +#include "tst_benchlibcounting.moc" diff --git a/tests/auto/testlib/selftests/expected_badxml.lightxml b/tests/auto/testlib/selftests/expected_badxml.lightxml index a8cdf56dc1c..08ba497efa9 100644 --- a/tests/auto/testlib/selftests/expected_badxml.lightxml +++ b/tests/auto/testlib/selftests/expected_badxml.lightxml @@ -7,41 +7,69 @@ - text ]]]> more text]]> + text ]]]> more text]]> - - text ]]]> more text]]> + + text ]]]> more text]]> - - + text ]]]> more text]]> - - - + + text ]]]> more text]]> - + - open < tags < text]]> + - - open < tags < text]]> + + - - " mixed ]]]> up > " in < the ]]]> hopes < of triggering "< ]]]> bugs]]> + - - " mixed ]]]> up > " in < the ]]]> hopes < of triggering "< ]]]> bugs]]> + + + + + + open < tags < text]]> + + + + open < tags < text]]> - + + open < tags < text]]> + + + + open < tags < text]]> + + + + " mixed ]]]> up > " in < the ]]]> hopes < of triggering "< ]]]> bugs]]> + + + + " mixed ]]]> up > " in < the ]]]> hopes < of triggering "< ]]]> bugs]]> + + + + " mixed ]]]> up > " in < the ]]]> hopes < of triggering "< ]]]> bugs]]> + + + + " mixed ]]]> up > " in < the ]]]> hopes < of triggering "< ]]]> bugs]]> + + diff --git a/tests/auto/testlib/selftests/expected_badxml.txt b/tests/auto/testlib/selftests/expected_badxml.txt index d4f44320664..68d333ec303 100644 --- a/tests/auto/testlib/selftests/expected_badxml.txt +++ b/tests/auto/testlib/selftests/expected_badxml.txt @@ -1,25 +1,33 @@ ********* Start testing of tst_BadXml ********* Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ PASS : tst_BadXml::initTestCase() -QDEBUG : tst_BadXml::badDataTag(end cdata ]]> text ]]> more text) a message -FAIL! : tst_BadXml::badDataTag(end cdata ]]> text ]]> more text) a failure - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp(109)] -RESULT : tst_BadXml::badDataTag():"end cdata ]]> text ]]> more text": +QDEBUG : tst_BadXml::badDataTag(fail end cdata ]]> text ]]> more text) a message +FAIL! : tst_BadXml::badDataTag(fail end cdata ]]> text ]]> more text) a failure + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp(111)] +QDEBUG : tst_BadXml::badDataTag(pass end cdata ]]> text ]]> more text) a message +PASS : tst_BadXml::badDataTag(pass end cdata ]]> text ]]> more text) +RESULT : tst_BadXml::badDataTag():"pass end cdata ]]> text ]]> more text": 0 events per iteration (total: 0, iterations: 1) -QDEBUG : tst_BadXml::badDataTag(quotes " text" more text) a message -FAIL! : tst_BadXml::badDataTag(quotes " text" more text) a failure - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp(109)] -RESULT : tst_BadXml::badDataTag():"quotes " text" more text": +QDEBUG : tst_BadXml::badDataTag(fail quotes " text" more text) a message +FAIL! : tst_BadXml::badDataTag(fail quotes " text" more text) a failure + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp(111)] +QDEBUG : tst_BadXml::badDataTag(pass quotes " text" more text) a message +PASS : tst_BadXml::badDataTag(pass quotes " text" more text) +RESULT : tst_BadXml::badDataTag():"pass quotes " text" more text": 0 events per iteration (total: 0, iterations: 1) -QDEBUG : tst_BadXml::badDataTag(xml close > open < tags < text) a message -FAIL! : tst_BadXml::badDataTag(xml close > open < tags < text) a failure - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp(109)] -RESULT : tst_BadXml::badDataTag():"xml close > open < tags < text": +QDEBUG : tst_BadXml::badDataTag(fail xml close > open < tags < text) a message +FAIL! : tst_BadXml::badDataTag(fail xml close > open < tags < text) a failure + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp(111)] +QDEBUG : tst_BadXml::badDataTag(pass xml close > open < tags < text) a message +PASS : tst_BadXml::badDataTag(pass xml close > open < tags < text) +RESULT : tst_BadXml::badDataTag():"pass xml close > open < tags < text": 0 events per iteration (total: 0, iterations: 1) -QDEBUG : tst_BadXml::badDataTag(all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs) a message -FAIL! : tst_BadXml::badDataTag(all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs) a failure - Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp(109)] -RESULT : tst_BadXml::badDataTag():"all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs": +QDEBUG : tst_BadXml::badDataTag(fail all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs) a message +FAIL! : tst_BadXml::badDataTag(fail all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs) a failure + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp(111)] +QDEBUG : tst_BadXml::badDataTag(pass all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs) a message +PASS : tst_BadXml::badDataTag(pass all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs) +RESULT : tst_BadXml::badDataTag():"pass all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs": 0 events per iteration (total: 0, iterations: 1) QDEBUG : tst_BadXml::badMessage(string 0) end cdata ]]> text ]]> more text PASS : tst_BadXml::badMessage(string 0) @@ -31,5 +39,5 @@ QDEBUG : tst_BadXml::badMessage(string 3) all > " mixed ]]> up > " in < the ]]> PASS : tst_BadXml::badMessage(string 3) FAIL! : tst_BadXml::failWithNoFile() failure message PASS : tst_BadXml::cleanupTestCase() -Totals: 6 passed, 5 failed, 0 skipped +Totals: 10 passed, 5 failed, 0 skipped ********* Finished testing of tst_BadXml ********* diff --git a/tests/auto/testlib/selftests/expected_badxml.xml b/tests/auto/testlib/selftests/expected_badxml.xml index 9f083d3917f..849bc07bfc0 100644 --- a/tests/auto/testlib/selftests/expected_badxml.xml +++ b/tests/auto/testlib/selftests/expected_badxml.xml @@ -9,41 +9,69 @@ - text ]]]> more text]]> + text ]]]> more text]]> - - text ]]]> more text]]> + + text ]]]> more text]]> - - + text ]]]> more text]]> - - - + + text ]]]> more text]]> - + - open < tags < text]]> + - - open < tags < text]]> + + - - " mixed ]]]> up > " in < the ]]]> hopes < of triggering "< ]]]> bugs]]> + - - " mixed ]]]> up > " in < the ]]]> hopes < of triggering "< ]]]> bugs]]> + + + + + + open < tags < text]]> + + + + open < tags < text]]> - + + open < tags < text]]> + + + + open < tags < text]]> + + + + " mixed ]]]> up > " in < the ]]]> hopes < of triggering "< ]]]> bugs]]> + + + + " mixed ]]]> up > " in < the ]]]> hopes < of triggering "< ]]]> bugs]]> + + + + " mixed ]]]> up > " in < the ]]]> hopes < of triggering "< ]]]> bugs]]> + + + + " mixed ]]]> up > " in < the ]]]> hopes < of triggering "< ]]]> bugs]]> + + diff --git a/tests/auto/testlib/selftests/expected_badxml.xunitxml b/tests/auto/testlib/selftests/expected_badxml.xunitxml index 724aed59e74..939e887a881 100644 --- a/tests/auto/testlib/selftests/expected_badxml.xunitxml +++ b/tests/auto/testlib/selftests/expected_badxml.xunitxml @@ -1,19 +1,23 @@ - + - - - - - - - - + + + + + + + + + + + + @@ -30,6 +34,10 @@ + + + + text ]]]> more text]]> open < tags < text]]> diff --git a/tests/auto/testlib/selftests/expected_benchlibcallgrind.txt b/tests/auto/testlib/selftests/expected_benchlibcallgrind.txt index 714b67fa77a..13e9a39affa 100644 --- a/tests/auto/testlib/selftests/expected_benchlibcallgrind.txt +++ b/tests/auto/testlib/selftests/expected_benchlibcallgrind.txt @@ -2,9 +2,8 @@ Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ PASS : tst_BenchlibCallgrind::initTestCase() PASS : tst_BenchlibCallgrind::twoHundredMillionInstructions() -PASS : tst_BenchlibCallgrind::twoHundredMillionInstructions() RESULT : tst_BenchlibCallgrind::twoHundredMillionInstructions(): 200,000,158 instruction reads per iteration (total: 200,000,158, iterations: 1) PASS : tst_BenchlibCallgrind::cleanupTestCase() -Totals: 4 passed, 0 failed, 0 skipped +Totals: 3 passed, 0 failed, 0 skipped ********* Finished testing of tst_BenchlibCallgrind ********* diff --git a/tests/auto/testlib/selftests/expected_benchlibcounting.lightxml b/tests/auto/testlib/selftests/expected_benchlibcounting.lightxml new file mode 100644 index 00000000000..5c436a53e0f --- /dev/null +++ b/tests/auto/testlib/selftests/expected_benchlibcounting.lightxml @@ -0,0 +1,24 @@ + + @INSERT_QT_VERSION_HERE@ + @INSERT_QT_VERSION_HERE@ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_benchlibcounting.txt b/tests/auto/testlib/selftests/expected_benchlibcounting.txt new file mode 100644 index 00000000000..e1af40b9e0b --- /dev/null +++ b/tests/auto/testlib/selftests/expected_benchlibcounting.txt @@ -0,0 +1,13 @@ +********* Start testing of tst_BenchlibCounting ********* +Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ +PASS : tst_BenchlibCounting::initTestCase() +PASS : tst_BenchlibCounting::passingBenchmark() +RESULT : tst_BenchlibCounting::passingBenchmark(): + 0 events per iteration (total: 0, iterations: 1) +SKIP : tst_BenchlibCounting::skippingBenchmark() This is a skipping benchmark + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/benchlibcounting/tst_benchlibcounting.cpp(64)] +FAIL! : tst_BenchlibCounting::failingBenchmark() This is a failing benchmark + Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/benchlibcounting/tst_benchlibcounting.cpp(71)] +PASS : tst_BenchlibCounting::cleanupTestCase() +Totals: 3 passed, 1 failed, 1 skipped +********* Finished testing of tst_BenchlibCounting ********* diff --git a/tests/auto/testlib/selftests/expected_benchlibcounting.xml b/tests/auto/testlib/selftests/expected_benchlibcounting.xml new file mode 100644 index 00000000000..5bf71fbf8eb --- /dev/null +++ b/tests/auto/testlib/selftests/expected_benchlibcounting.xml @@ -0,0 +1,27 @@ + + + + @INSERT_QT_VERSION_HERE@ + @INSERT_QT_VERSION_HERE@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_benchlibcounting.xunitxml b/tests/auto/testlib/selftests/expected_benchlibcounting.xunitxml new file mode 100644 index 00000000000..83e429aa3ab --- /dev/null +++ b/tests/auto/testlib/selftests/expected_benchlibcounting.xunitxml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_benchliboptions.txt b/tests/auto/testlib/selftests/expected_benchliboptions.txt index 6d6d91c25e9..ef9f0c5ad05 100644 --- a/tests/auto/testlib/selftests/expected_benchliboptions.txt +++ b/tests/auto/testlib/selftests/expected_benchliboptions.txt @@ -20,14 +20,8 @@ Totals: 3 passed, 0 failed, 0 skipped Config: Using QTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ PASS : tst_BenchlibOneHundredMinimum::initTestCase() PASS : tst_BenchlibOneHundredMinimum::threeEvents() -PASS : tst_BenchlibOneHundredMinimum::threeEvents() -PASS : tst_BenchlibOneHundredMinimum::threeEvents() -PASS : tst_BenchlibOneHundredMinimum::threeEvents() -PASS : tst_BenchlibOneHundredMinimum::threeEvents() -PASS : tst_BenchlibOneHundredMinimum::threeEvents() -PASS : tst_BenchlibOneHundredMinimum::threeEvents() RESULT : tst_BenchlibOneHundredMinimum::threeEvents(): 3.00 events per iteration (total: 192, iterations: 64) PASS : tst_BenchlibOneHundredMinimum::cleanupTestCase() -Totals: 9 passed, 0 failed, 0 skipped +Totals: 3 passed, 0 failed, 0 skipped ********* Finished testing of tst_BenchlibOneHundredMinimum ********* diff --git a/tests/auto/testlib/selftests/selftests.pri b/tests/auto/testlib/selftests/selftests.pri index 2297186f62b..0809c4d4972 100644 --- a/tests/auto/testlib/selftests/selftests.pri +++ b/tests/auto/testlib/selftests/selftests.pri @@ -3,6 +3,7 @@ SUBPROGRAMS = \ assert \ badxml \ benchlibcallgrind \ + benchlibcounting \ benchlibeventcounter \ benchliboptions \ benchlibtickcounter \ diff --git a/tests/auto/testlib/selftests/selftests.qrc b/tests/auto/testlib/selftests/selftests.qrc index d2f0a50824a..baa539a2593 100644 --- a/tests/auto/testlib/selftests/selftests.qrc +++ b/tests/auto/testlib/selftests/selftests.qrc @@ -10,6 +10,10 @@ expected_badxml.xml expected_badxml.xunitxml expected_benchlibcallgrind.txt + expected_benchlibcounting.lightxml + expected_benchlibcounting.txt + expected_benchlibcounting.xml + expected_benchlibcounting.xunitxml expected_benchlibeventcounter.lightxml expected_benchlibeventcounter.txt expected_benchlibeventcounter.xml diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index 7e671a50f22..decaa553863 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -323,6 +323,7 @@ void tst_Selftests::runSubTest_data() // Only run on platforms where callgrind is available. << "benchlibcallgrind" #endif + << "benchlibcounting" << "benchlibeventcounter" << "benchliboptions" << "cmptest" @@ -399,6 +400,9 @@ void tst_Selftests::runSubTest_data() else if (subtest == "badxml") { arguments << "-eventcounter"; } + else if (subtest == "benchlibcounting") { + arguments << "-eventcounter"; + } else if (subtest == "printdatatags") { arguments << "-datatags"; } From 7fbe7fd7b5a31cdadc8fb06a1d226e4a2b0a3f9f Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Mon, 20 Feb 2012 11:39:31 +1000 Subject: [PATCH 353/406] Make QLocale autotest pass for shadow builds. For shadow builds where "make install" had not been run, the tst_QLocale::emptyCtor test function would fail to find its helper application because QFINDTESTDATA was not searching for it in the build directory due to the test not instantiating QCoreApplication. This commit fixes the test by instantiating a QCoreApplication using the QTEST_MAIN macro, which also allows some special case code for Windows CE to be removed. Change-Id: Ic81d4699da2538c24b36b3d6bd52c4a02ad417f4 Reviewed-by: Rohan McGovern --- tests/auto/corelib/tools/qlocale/tst_qlocale.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index e23448c056a..db7f503f574 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -59,7 +59,6 @@ #endif #ifdef Q_OS_WINCE -#include #include // needed for GetUserDefaultLCID #define _control87 _controlfp extern "C" DWORD GetThreadLocale(void) { @@ -141,11 +140,6 @@ tst_QLocale::tst_QLocale() void tst_QLocale::ctor() { -#ifdef Q_OS_WINCE - int argc = 1; - char argv[20] = "tst_qlocale.exe"; - QCoreApplication app(argc, (char**)&argv); -#endif QLocale default_locale = QLocale::system(); QLocale::Language default_lang = default_locale.language(); QLocale::Country default_country = default_locale.country(); @@ -1988,5 +1982,5 @@ void tst_QLocale::listPatterns() QCOMPARE(zh_CN.createSeparatedList(sl5), QString::fromUtf8("aaa" "\xe3\x80\x81" "bbb" "\xe3\x80\x81" "ccc" "\xe5\x92\x8c" "ddd")); } -QTEST_APPLESS_MAIN(tst_QLocale) +QTEST_MAIN(tst_QLocale) #include "tst_qlocale.moc" From 2465143f2498e039dc7a62da7427d0aace5ee29c Mon Sep 17 00:00:00 2001 From: Toby Tomkins Date: Mon, 20 Feb 2012 15:46:46 +1000 Subject: [PATCH 354/406] Set tst_qtoolbutton triggered function skipped. This autotest seems to be caught in an event loop preventing further correct signalling. Mark test function skipped with QSKIP. Task-number: QTBUG-24374 Change-Id: Ic943a33b71fa87d0873278cb7b7b134c22602be3 Reviewed-by: Rohan McGovern --- tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp b/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp index 48b68d17956..df4efd658a2 100644 --- a/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp +++ b/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp @@ -142,6 +142,10 @@ void tst_QToolButton::triggered() QCOMPARE(spy.count(),1); QCOMPARE(qvariant_cast(spy.at(0).at(0)), def); +#ifdef Q_OS_MAC + QSKIP("QTBUG-24374 - This test hangs here on Mac OSX"); +#endif + w = menu; QTimer::singleShot(30, this, SLOT(sendMouseClick())); tb.showMenu(); From 853e9ac787f2eaf603c7756726b2d90a143aa183 Mon Sep 17 00:00:00 2001 From: Toby Tomkins Date: Mon, 20 Feb 2012 13:29:13 +1000 Subject: [PATCH 355/406] Modify helper functions to remove embedded QSKIP call and return status. The helper functions contained QSKIP macros which do not also skip their parent function. These QSKIP function were removed and replaced with a return success value. Change-Id: I533f57842fc95beaeb1fcde5235678e9807db056 Reviewed-by: Rohan McGovern --- .../qmimedatabase/tst_qmimedatabase.cpp | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp index 12d6587dfb0..fc86fa5431d 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp @@ -714,20 +714,21 @@ void tst_QMimeDatabase::fromThreads() f.waitForFinished(); } -static void runUpdateMimeDatabase(const QString &path) // TODO make it a QMimeDatabase method? +static bool runUpdateMimeDatabase(const QString &path) // TODO make it a QMimeDatabase method? { const QString umd = QStandardPaths::findExecutable(QString::fromLatin1("update-mime-database")); if (umd.isEmpty()) - QSKIP("shared-mime-info not found, skipping mime.cache test"); + return false; QProcess proc; proc.setProcessChannelMode(QProcess::MergedChannels); // silence output proc.start(umd, QStringList() << path); proc.waitForFinished(); //qDebug() << "runUpdateMimeDatabase" << path; + return true; } -static void waitAndRunUpdateMimeDatabase(const QString &path) +static bool waitAndRunUpdateMimeDatabase(const QString &path) { QFileInfo mimeCacheInfo(path + QString::fromLatin1("/mime.cache")); if (mimeCacheInfo.exists()) { @@ -736,7 +737,7 @@ static void waitAndRunUpdateMimeDatabase(const QString &path) QTest::qSleep(200); } } - runUpdateMimeDatabase(path); + return runUpdateMimeDatabase(path); } static void checkHasMimeType(const QString &mimeType) @@ -775,7 +776,8 @@ void tst_QMimeDatabase::installNewGlobalMimeType() QFile::remove(destFile); //qDebug() << destFile; QVERIFY(QFile::copy(srcFile, destFile)); - waitAndRunUpdateMimeDatabase(mimeDir); + if (!waitAndRunUpdateMimeDatabase(mimeDir)) + QSKIP("shared-mime-info not found, skipping mime.cache test"); QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(), QString::fromLatin1("text/x-suse-ymu")); @@ -784,7 +786,8 @@ void tst_QMimeDatabase::installNewGlobalMimeType() // Now test removing it again QFile::remove(destFile); - waitAndRunUpdateMimeDatabase(mimeDir); + if (!waitAndRunUpdateMimeDatabase(mimeDir)) + QSKIP("shared-mime-info not found, skipping mime.cache test"); QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(), QString::fromLatin1("application/octet-stream")); QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid()); @@ -805,7 +808,8 @@ void tst_QMimeDatabase::installNewLocalMimeType() const QString destFile = destDir + fileName; QFile::remove(destFile); QVERIFY(QFile::copy(srcFile, destFile)); - runUpdateMimeDatabase(mimeDir); + if (!runUpdateMimeDatabase(mimeDir)) + QSKIP("shared-mime-info not found, skipping mime.cache test");; QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(), QString::fromLatin1("text/x-suse-ymu")); @@ -814,7 +818,8 @@ void tst_QMimeDatabase::installNewLocalMimeType() // Now test removing it again (note, this leaves a mostly-empty mime.cache file) QFile::remove(destFile); - waitAndRunUpdateMimeDatabase(mimeDir); + if (!waitAndRunUpdateMimeDatabase(mimeDir)) + QSKIP("shared-mime-info not found, skipping mime.cache test"); QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(), QString::fromLatin1("application/octet-stream")); QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid()); From c66bb51a7551fc67290761e0ef9de1137ad07fd0 Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Mon, 20 Feb 2012 14:05:47 +1000 Subject: [PATCH 356/406] Changed qabstractnetworkcache unittest to use TESTDATA - Changed qabstractnetworkcache to install testdata Change-Id: I8f2ae6103214755ee7898dbc0ee50c0e4d7d45ab Reviewed-by: Rohan McGovern Reviewed-by: Jason McDonald --- .../access/qabstractnetworkcache/qabstractnetworkcache.pro | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/auto/network/access/qabstractnetworkcache/qabstractnetworkcache.pro b/tests/auto/network/access/qabstractnetworkcache/qabstractnetworkcache.pro index 719c34f286b..ef47a4b4586 100644 --- a/tests/auto/network/access/qabstractnetworkcache/qabstractnetworkcache.pro +++ b/tests/auto/network/access/qabstractnetworkcache/qabstractnetworkcache.pro @@ -4,10 +4,6 @@ QT += network testlib QT -= gui SOURCES += tst_qabstractnetworkcache.cpp -wince* { - testFiles.files = tests - testFiles.path = . - DEPLOYMENT += testFiles -} +TESTDATA += tests/* CONFIG += insignificant_test # QTBUG-20686; note, assumed unstable on all platforms From ad1a0138789041f4cb7083ea68168a4b9316dd99 Mon Sep 17 00:00:00 2001 From: Richard Moore Date: Sun, 19 Feb 2012 16:31:39 +0000 Subject: [PATCH 357/406] Remove dead method. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix Qt 5 TODO Change-Id: I9a12cc07ebc7c039bbeb53922b0539f177b226f8 Reviewed-by: Samuel Rødal --- src/gui/image/qpixmap.cpp | 8 -------- src/gui/image/qpixmap.h | 1 - 2 files changed, 9 deletions(-) diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 16945edc90a..e8c1304b74f 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1003,14 +1003,6 @@ bool QPixmap::isDetached() const return data && data->ref.load() == 1; } -/*! \internal - ### Qt5 - remove me. -*/ -void QPixmap::deref() -{ - Q_ASSERT_X(false, "QPixmap::deref()", "Do not call this function anymore!"); -} - /*! Replaces this pixmap's data with the given \a image using the specified \a flags to control the conversion. The \a flags diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h index de76321f0a5..27bfe156884 100644 --- a/src/gui/image/qpixmap.h +++ b/src/gui/image/qpixmap.h @@ -174,7 +174,6 @@ private: QPixmap(const QSize &s, int type); void doInit(int, int, int); - void deref(); Q_DUMMY_COMPARISON_OPERATOR(QPixmap) friend class QPlatformPixmap; friend class QBitmap; From 3ad9896361ef9382f44a5cfaa80431fe6ea3e1f9 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 1 Feb 2012 13:32:53 +0100 Subject: [PATCH 358/406] qpa: Verify that the platform returns a WId that is not WId(0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is motivated by visiting a customer that re-implemented the ::winId method and returned WId(0) that resulted in a crash. Currently there is only a comment inside the implementation of the ::winId default implementation. Add a note to the API documentation, add a Q_ASSERT to check if our assumption holds true. Change-Id: I8607a4efc4f561f7849c976cd2454f6fbcb20eaa Reviewed-by: Samuel Rødal --- src/gui/kernel/qwindow.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 5b6ee0e9cb8..85f12dd023f 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -220,7 +220,11 @@ WId QWindow::winId() const Q_D(const QWindow); if(!d->platformWindow) const_cast(this)->create(); - return d->platformWindow->winId(); + + WId id = d->platformWindow->winId(); + // See the QPlatformWindow::winId() documentation + Q_ASSERT(id != WId(0)); + return id; } QWindow *QWindow::parent() const From 52072a8c8acb1184a649bf0e78d92d108fb0bb24 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 19 Feb 2012 19:20:49 +0100 Subject: [PATCH 359/406] qwidget_p.h: Remove DontSetCompositionMode from the internal flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This flag was used by QWS to set or not set the composition mode when filling the background. E.g. this was used by 'transparent' windows to set the alpha bits. QPA didn't have this enabled in 4.8, the code paths are gone in Qt5 and it is the responsibility of the QPlatformBackingStore to initialize the alpha bits properly. Change-Id: I4011d842b718d6a40b19922b5f75c597e63079c8 Reviewed-by: Samuel Rødal --- src/widgets/kernel/qwidget_p.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 8b66f145405..38314c234bf 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -283,9 +283,8 @@ public: DrawRecursive = 0x04, DrawInvisible = 0x08, DontSubtractOpaqueChildren = 0x10, - DontSetCompositionMode = 0x20, - DontDrawOpaqueChildren = 0x40, - DontDrawNativeChildren = 0x80 + DontDrawOpaqueChildren = 0x20, + DontDrawNativeChildren = 0x40 }; enum CloseMode { From 3cb078a23cb8b86169bd9d8259f5658be0c2082e Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 17 Feb 2012 14:17:54 +0100 Subject: [PATCH 360/406] Rename Q_PROCESSOR_POWERPC to Q_PROCESSOR_POWER IBM's POWER and the PowerPC architecture have been merged into a single ISA, the Power ISA (see http://www.power.org). Use this unified name in Qt. Change-Id: Ia41492b0031d890843e43c5f7ecd1e60c65bb75b Reviewed-by: Thiago Macieira --- src/corelib/arch/arch.pri | 2 +- .../{qatomic_powerpc.h => qatomic_power.h} | 16 +++++++------- src/corelib/arch/qatomic_vxworks.h | 2 +- src/corelib/global/qglobal.cpp | 21 +++++++++++++------ src/corelib/global/qprocessordetection.h | 16 ++++++++------ src/corelib/thread/qbasicatomic.h | 4 ++-- 6 files changed, 36 insertions(+), 25 deletions(-) rename src/corelib/arch/{qatomic_powerpc.h => qatomic_power.h} (97%) diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index c64bbe2821f..c6110870431 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -12,7 +12,7 @@ HEADERS += \ arch/qatomic_i386.h \ arch/qatomic_ia64.h \ arch/qatomic_mips.h \ - arch/qatomic_powerpc.h \ + arch/qatomic_power.h \ arch/qatomic_s390.h \ arch/qatomic_sh4a.h \ arch/qatomic_sparc.h \ diff --git a/src/corelib/arch/qatomic_powerpc.h b/src/corelib/arch/qatomic_power.h similarity index 97% rename from src/corelib/arch/qatomic_powerpc.h rename to src/corelib/arch/qatomic_power.h index 10f6e4c4882..a531dfedc81 100644 --- a/src/corelib/arch/qatomic_powerpc.h +++ b/src/corelib/arch/qatomic_power.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QATOMIC_POWERPC_H -#define QATOMIC_POWERPC_H +#ifndef QATOMIC_POWER_H +#define QATOMIC_POWER_H #include @@ -105,13 +105,11 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndAddWaitFree() #if defined(Q_CC_GNU) -#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2) \ - || (!defined(__64BIT__) && !defined(__powerpc64__) && !defined(__ppc64__)) +#ifdef Q_PROCESSOR_POWER_32 # define _Q_VALUE "0, %[_q_value]" # define _Q_VALUE_MEMORY_OPERAND "+m" (_q_value) # define _Q_VALUE_REGISTER_OPERAND [_q_value] "r" (&_q_value), -#else -// On 64-bit with gcc >= 4.2 +#else // Q_PROCESSOR_POWER_64 # define _Q_VALUE "%y[_q_value]" # define _Q_VALUE_MEMORY_OPERAND [_q_value] "+Z" (_q_value) # define _Q_VALUE_REGISTER_OPERAND @@ -301,7 +299,7 @@ inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) return originalValue; } -#if defined(__64BIT__) || defined(__powerpc64__) || defined(__ppc64__) +#ifdef Q_PROCESSOR_POWER_64 # define LPARX "ldarx" # define STPCX "stdcx." #else @@ -475,7 +473,7 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelease(qptrdiff valueTo #undef _Q_VALUE_REGISTER_OPERAND #else -# error "This compiler for PowerPC is not supported" +# error "This compiler for Power/PowerPC is not supported" #endif inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) @@ -515,4 +513,4 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QATOMIC_POWERPC_H +#endif // QATOMIC_POWER_H diff --git a/src/corelib/arch/qatomic_vxworks.h b/src/corelib/arch/qatomic_vxworks.h index dbec16a5409..564a07f3eaa 100644 --- a/src/corelib/arch/qatomic_vxworks.h +++ b/src/corelib/arch/qatomic_vxworks.h @@ -45,7 +45,7 @@ QT_BEGIN_HEADER #if defined(__ppc) -# include +# include #else // generic implementation with taskLock() #include diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 44d44b2cdb8..eea4397dcdb 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1489,18 +1489,27 @@ bool qSharedBuild() */ /*! - \macro Q_PROCESSOR_POWERPC + \macro Q_PROCESSOR_POWER \relates - Defined if the application is compiled for PowerPC processors. Qt currently - supports one optional PowerPC variant: \l Q_PROCESSOR_POWERPC_64. + Defined if the application is compiled for POWER processors. Qt currently + supports two Power variants: \l Q_PROCESSOR_POWER_32 and \l + Q_PROCESSOR_POWER_64. */ /*! - \macro Q_PROCESSOR_POWERPC_64 + \macro Q_PROCESSOR_POWER_32 \relates - Defined if the application is compiled for 64-bit PowerPC processors. The - \l Q_PROCESSOR_POWERPC macro is also defined when Q_PROCESSOR_POWERPC_64 is + Defined if the application is compiled for 32-bit Power processors. The \l + Q_PROCESSOR_POWER macro is also defined when Q_PROCESSOR_POWER_32 is + defined. +*/ +/*! + \macro Q_PROCESSOR_POWER_64 + \relates + + Defined if the application is compiled for 64-bit Power processors. The \l + Q_PROCESSOR_POWER macro is also defined when Q_PROCESSOR_POWER_64 is defined. */ diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h index 69815ba1994..fd02f0e4c52 100644 --- a/src/corelib/global/qprocessordetection.h +++ b/src/corelib/global/qprocessordetection.h @@ -145,17 +145,21 @@ # endif /* - POWER family, optional variant: 64-bit + Power family, known variants: 32- and 64-bit There are many more known variants/revisions that we do not handle/detect. See http://en.wikipedia.org/wiki/Power_Architecture and http://en.wikipedia.org/wiki/File:PowerISA-evolution.svg */ -// #elif defined(__powerpc__) || defined(__ppc__) || defined(_M_MPPC) || defined(_M_PPC) -// # define Q_PROCESSOR_POWERPC -// # if defined(__64BIT__) || defined(__powerpc64__) || defined(__ppc64__) -// # define Q_PROCESSOR_POWERPC_64 -// # endif +#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \ + || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \ + || defined(_M_MPPC) || defined(_M_PPC) +# define Q_PROCESSOR_POWER +# if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__) +# define Q_PROCESSOR_POWER_64 +# else +# define Q_PROCESSOR_POWER_32 +# endif /* S390 family, known variant: S390X (64-bit) diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h index 363a4da3388..96338c62dcf 100644 --- a/src/corelib/thread/qbasicatomic.h +++ b/src/corelib/thread/qbasicatomic.h @@ -72,8 +72,8 @@ # include "QtCore/qatomic_ia64.h" #elif defined(Q_PROCESSOR_MIPS) # include "QtCore/qatomic_mips.h" -#elif defined(Q_PROCESSOR_POWERPC) -# include "QtCore/qatomic_powerpc.h" +#elif defined(Q_PROCESSOR_POWER) +# include "QtCore/qatomic_power.h" #elif defined(Q_PROCESSOR_S390) # include "QtCore/qatomic_s390.h" #elif defined(Q_PROCESSOR_SH4A) From 7d8f5777bede600d60ceb9be1213c71fd93c3ed7 Mon Sep 17 00:00:00 2001 From: Jonathan Liu Date: Sun, 19 Feb 2012 22:33:35 +1100 Subject: [PATCH 361/406] Fix compilation with MinGW-w64 This fixes a "cast from 'void*' to 'int' loses precision" error and adds a missing argument to qWarning. Change-Id: I38544c4e317a3f6d1ecf26ebb3e35c66b1878d24 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowsservices.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsservices.cpp b/src/plugins/platforms/windows/qwindowsservices.cpp index 5cc4ce93afc..905a1bd12c7 100644 --- a/src/plugins/platforms/windows/qwindowsservices.cpp +++ b/src/plugins/platforms/windows/qwindowsservices.cpp @@ -54,10 +54,10 @@ enum { debug = 0 }; static inline bool shellExecute(const QString &file) { - const int result = (int)ShellExecute(0, 0, (wchar_t*)file.utf16(), 0, 0, SW_SHOWNORMAL); + const quintptr result = (quintptr)ShellExecute(0, 0, (wchar_t*)file.utf16(), 0, 0, SW_SHOWNORMAL); // ShellExecute returns a value greater than 32 if successful if (result <= 32) { - qWarning("ShellExecute '%s' failed (error %0x).", qPrintable(file), result); + qWarning("ShellExecute '%s' failed (error %s).", qPrintable(file), qPrintable(QString::number(result))); return false; } return true; @@ -104,7 +104,7 @@ static inline bool launchMail(const QUrl &url) { QString command = mailCommand(); if (command.isEmpty()) { - qWarning("Cannot launch '%s': There is no mail program installed."); + qWarning("Cannot launch '%s': There is no mail program installed.", qPrintable(url.toString())); return false; } //Make sure the path for the process is in quotes From 5af7e089f79174e576529a742c380cf418510771 Mon Sep 17 00:00:00 2001 From: Morten Johan Sorvig Date: Fri, 17 Feb 2012 14:34:25 +0100 Subject: [PATCH 362/406] Don't use -rpath-link when building on Mac. The logic here was wrong: test if the target linker supports -rpath-link, and then set it for both host and target via mkspecs/qmodule.pri. Change-Id: Ie4da7ed2e06e784f9edb65a27290913ab838a8c2 Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index d33e2489a70..0687bd50216 100755 --- a/configure +++ b/configure @@ -7355,7 +7355,7 @@ QTMODULE="$outpath/mkspecs/qmodule.pri" echo "CONFIG += create_prl link_prl" >> "$QTMODULE.tmp" # Ensure we can link to uninistalled libraries -if [ "$XPLATFORM_MINGW" != "yes" ] && [ "$CFG_EMBEDDED" != "nacl" ] && linkerSupportsFlag -rpath-link "$outpath/lib"; then +if [ "$BUILD_ON_MAC" != "yes" ] && [ "$XPLATFORM_MINGW" != "yes" ] && linkerSupportsFlag -rpath-link "$outpath/lib"; then echo "QMAKE_LFLAGS = -Wl,-rpath-link,\$\$QT_BUILD_TREE/lib \$\$QMAKE_LFLAGS" >> "$QTMODULE.tmp" fi if [ -n "$QT_CFLAGS_PSQL" ]; then From d00db53a12d253fd71d400e413f73817fa43289e Mon Sep 17 00:00:00 2001 From: Morten Johan Sorvig Date: Fri, 17 Feb 2012 14:21:37 +0100 Subject: [PATCH 363/406] Don't force CFG_ENDIAN to "auto" on Mac. We no longer support universal ppc/x86 builds. Change-Id: I8c4a1d087d02da1ad80d91a7a04147b37e81d74f Reviewed-by: Oswald Buddenhagen --- configure | 2 -- 1 file changed, 2 deletions(-) diff --git a/configure b/configure index 0687bd50216..ce7e2fb48a0 100755 --- a/configure +++ b/configure @@ -5948,8 +5948,6 @@ fi if [ "$CFG_ENDIAN" = "auto" ]; then if [ "$XPLATFORM_MINGW" = "yes" ]; then CFG_ENDIAN="Q_LITTLE_ENDIAN" - elif [ "$BUILD_ON_MAC" = "yes" ]; then - true #leave as auto else "$unixtests/endian.test" "$XQMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath" "QMAKE_LFLAGS+=$SYSROOT_FLAG" F="$?" From cbe21c59a05ceb357c1a6bd2a84480dab0e79ea0 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Mon, 20 Feb 2012 06:48:17 +0100 Subject: [PATCH 364/406] Minuscule moc cleanup: Don't declare i in function scope This is not C. Furthermore, the function-level i was already shadowed in several places by "for (int i = 0; ..." blocks later in the function. Change-Id: Ic1777f78d9838bc2921d68337be05de454bbeabe Reviewed-by: Olivier Goffart --- src/tools/moc/generator.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index f3a2b4a39b9..73552755878 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -140,13 +140,11 @@ void Generator::generateCode() // // build the data array // - int i = 0; - // filter out undeclared enumerators and sets { QList enumList; - for (i = 0; i < cdef->enumList.count(); ++i) { + for (int i = 0; i < cdef->enumList.count(); ++i) { EnumDef def = cdef->enumList.at(i); if (cdef->enumDeclarations.contains(def.name)) { enumList += def; @@ -186,7 +184,7 @@ void Generator::generateCode() fprintf(out, " %4d, %4d, // enums/sets\n", cdef->enumList.count(), cdef->enumList.count() ? index : 0); int enumsIndex = index; - for (i = 0; i < cdef->enumList.count(); ++i) + for (int i = 0; i < cdef->enumList.count(); ++i) index += 4 + (cdef->enumList.at(i).values.count() * 2); fprintf(out, " %4d, %4d, // constructors\n", isConstructible ? cdef->constructorList.count() : 0, isConstructible ? index : 0); @@ -252,7 +250,7 @@ void Generator::generateCode() fprintf(out, " \""); int col = 0; int len = 0; - for (i = 0; i < strings.size(); ++i) { + for (int i = 0; i < strings.size(); ++i) { QByteArray s = strings.at(i); len = s.length(); if (col && col + len >= 72) { From fec37f0e9a9e4c18fd20f7b39919f08c7cb2139e Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Sat, 18 Feb 2012 18:51:46 +0100 Subject: [PATCH 365/406] moc: Get rid of implicit conversions to const char * moc mostly operates on QByteArrays. When an actual const char * is needed, it should be explicit. Change-Id: I0b3e262830128306688f4512a4b59ce8966c2579 Reviewed-by: Bradley T. Hughes Reviewed-by: Olivier Goffart --- src/tools/moc/generator.cpp | 18 ++++++++---------- src/tools/moc/generator.h | 2 +- src/tools/moc/main.cpp | 6 +++--- src/tools/moc/moc.cpp | 11 ++++++----- src/tools/moc/moc.pro | 2 +- src/tools/moc/preprocessor.cpp | 12 ++++++------ 6 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 73552755878..937a62e87c5 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -54,19 +54,19 @@ QT_BEGIN_NAMESPACE -uint qvariant_nameToType(const char* name) +uint qvariant_nameToType(const QByteArray &name) { - if (!name) + if (name.isEmpty()) return 0; - uint tp = QMetaType::type(name); + uint tp = QMetaType::type(name.constData()); return tp < QMetaType::User ? tp : 0; } /* Returns true if the type is a QVariant types. */ -bool isVariantType(const char* type) +bool isVariantType(const QByteArray &type) { return qvariant_nameToType(type) != 0; } @@ -74,9 +74,9 @@ bool isVariantType(const char* type) /*! Returns true if the type is qreal. */ -static bool isQRealType(const char *type) +static bool isQRealType(const QByteArray &type) { - return strcmp(type, "qreal") == 0; + return (type == "qreal"); } Generator::Generator(ClassDef *classDef, const QList &metaTypes, FILE *outfile) @@ -109,11 +109,9 @@ static inline int lengthOfEscapeSequence(const QByteArray &s, int i) return i - startPos; } -int Generator::strreg(const char *s) +int Generator::strreg(const QByteArray &s) { int idx = 0; - if (!s) - s = ""; for (int i = 0; i < strings.size(); ++i) { const QByteArray &str = strings.at(i); if (str == s) @@ -387,7 +385,7 @@ void Generator::generateCode() for (int i = 1; i < cdef->superclassList.size(); ++i) { // for all superclasses but the first one if (cdef->superclassList.at(i).second == FunctionDef::Private) continue; - const char *cname = cdef->superclassList.at(i).first; + const char *cname = cdef->superclassList.at(i).first.constData(); fprintf(out, " if (!strcmp(_clname, \"%s\"))\n return static_cast< %s*>(const_cast< %s*>(this));\n", cname, cname, cdef->classname.constData()); } diff --git a/src/tools/moc/generator.h b/src/tools/moc/generator.h index 6682e1a36ae..4e965116950 100644 --- a/src/tools/moc/generator.h +++ b/src/tools/moc/generator.h @@ -65,7 +65,7 @@ private: void generateSignal(FunctionDef *def, int index); void generatePluginMetaData(); - int strreg(const char *); // registers a string and returns its id + int strreg(const QByteArray &); // registers a string and returns its id QList strings; QByteArray purestSuperClass; QList metaTypes; diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp index 512d0212b78..772df1feece 100644 --- a/src/tools/moc/main.cpp +++ b/src/tools/moc/main.cpp @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE /tmp/abc, xyz/klm -> /tmp/abc */ -static QByteArray combinePath(const char *infile, const char *outfile) +static QByteArray combinePath(const QByteArray &infile, const QByteArray &outfile) { QFileInfo inFileInfo(QDir::current(), QFile::decodeName(infile)); QFileInfo outFileInfo(QDir::current(), QFile::decodeName(outfile)); @@ -379,7 +379,7 @@ int runMoc(int _argc, char **_argv) in = fopen(filename.data(), "rb"); if (!in) { #endif - fprintf(stderr, "moc: %s: No such file\n", (const char*)filename); + fprintf(stderr, "moc: %s: No such file\n", filename.constData()); return 1; } moc.filename = filename; @@ -406,7 +406,7 @@ int runMoc(int _argc, char **_argv) if (!out) #endif { - fprintf(stderr, "moc: Cannot create %s\n", (const char*)output); + fprintf(stderr, "moc: Cannot create %s\n", output.constData()); return 1; } } else { // use stdout diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 97316eedde2..7b358c1ae81 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -54,9 +54,10 @@ QT_BEGIN_NAMESPACE // only moc needs this function -static QByteArray normalizeType(const char *s, bool fixScope = false) +static QByteArray normalizeType(const QByteArray &ba, bool fixScope = false) { - int len = qstrlen(s); + const char *s = ba.constData(); + int len = ba.size(); char stackbuf[64]; char *buf = (len >= 64 ? new char[len + 1] : stackbuf); char *d = buf; @@ -794,7 +795,7 @@ void Moc::generate(FILE *out) if (i >= 0) fn = filename.mid(i); fprintf(out, "/****************************************************************************\n" - "** Meta object code from reading C++ file '%s'\n**\n" , (const char*)fn); + "** Meta object code from reading C++ file '%s'\n**\n" , fn.constData()); fprintf(out, "** Created: %s\n" "** by: The Qt Meta Object Compiler version %d (Qt %s)\n**\n" , dstr.data(), mocOutputRevision, QT_VERSION_STR); fprintf(out, "** WARNING! All changes made in this file will be lost!\n" @@ -823,7 +824,7 @@ void Moc::generate(FILE *out) fprintf(out, "#include \n"); fprintf(out, "#if !defined(Q_MOC_OUTPUT_REVISION)\n" - "#error \"The header file '%s' doesn't include .\"\n", (const char *)fn); + "#error \"The header file '%s' doesn't include .\"\n", fn.constData()); fprintf(out, "#elif Q_MOC_OUTPUT_REVISION != %d\n", mocOutputRevision); fprintf(out, "#error \"This file was generated using the moc from %s." " It\"\n#error \"cannot be used with the include files from" @@ -1100,7 +1101,7 @@ void Moc::parsePluginData(ClassDef *def) } else if (l == "FILE") { next(STRING_LITERAL); QByteArray metaDataFile = unquotedLexem(); - QFileInfo fi(QFileInfo(QString::fromLocal8Bit(currentFilenames.top())).dir(), QString::fromLocal8Bit(metaDataFile)); + QFileInfo fi(QFileInfo(QString::fromLocal8Bit(currentFilenames.top().constData())).dir(), QString::fromLocal8Bit(metaDataFile.constData())); if (!fi.exists()) { QByteArray msg; msg += "Plugin Metadata file "; diff --git a/src/tools/moc/moc.pro b/src/tools/moc/moc.pro index 8e2e76d4b93..3ee507855c9 100644 --- a/src/tools/moc/moc.pro +++ b/src/tools/moc/moc.pro @@ -1,7 +1,7 @@ TEMPLATE = app TARGET = moc -DEFINES += QT_MOC +DEFINES += QT_MOC QT_NO_CAST_FROM_BYTEARRAY DESTDIR = ../../../bin INCLUDEPATH += . DEPENDPATH += . diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp index 07b9e4c5004..07986a71e67 100644 --- a/src/tools/moc/preprocessor.cpp +++ b/src/tools/moc/preprocessor.cpp @@ -58,7 +58,7 @@ static QByteArray cleaned(const QByteArray &input) { QByteArray result; result.reserve(input.size()); - const char *data = input; + const char *data = input.constData(); char *output = result.data(); int newlines = 0; @@ -161,7 +161,7 @@ enum TokenizeMode { TokenizeCpp, TokenizePreprocessor, PreparePreprocessorStatem static Symbols tokenize(const QByteArray &input, int lineNum = 1, TokenizeMode mode = TokenizeCpp) { Symbols symbols; - const char *begin = input; + const char *begin = input.constData(); const char *data = begin; while (*data) { if (mode == TokenizeCpp) { @@ -799,7 +799,7 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) // #### stringery QFileInfo fi; if (local) - fi.setFile(QFileInfo(QString::fromLocal8Bit(filename)).dir(), QString::fromLocal8Bit(include)); + fi.setFile(QFileInfo(QString::fromLocal8Bit(filename.constData())).dir(), QString::fromLocal8Bit(include.constData())); for (int j = 0; j < Preprocessor::includes.size() && !fi.exists(); ++j) { const IncludePath &p = Preprocessor::includes.at(j); if (p.isFrameworkPath) { @@ -808,9 +808,9 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) continue; QByteArray frameworkCandidate = include.left(slashPos); frameworkCandidate.append(".framework/Headers/"); - fi.setFile(QString::fromLocal8Bit(QByteArray(p.path + '/' + frameworkCandidate)), QString::fromLocal8Bit(include.mid(slashPos + 1))); + fi.setFile(QString::fromLocal8Bit(QByteArray(p.path + '/' + frameworkCandidate).constData()), QString::fromLocal8Bit(include.mid(slashPos + 1).constData())); } else { - fi.setFile(QString::fromLocal8Bit(p.path), QString::fromLocal8Bit(include)); + fi.setFile(QString::fromLocal8Bit(p.path.constData()), QString::fromLocal8Bit(include.constData())); } // try again, maybe there's a file later in the include paths with the same name // (186067) @@ -828,7 +828,7 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) continue; Preprocessor::preprocessedIncludes.insert(include); - QFile file(QString::fromLocal8Bit(include)); + QFile file(QString::fromLocal8Bit(include.constData())); if (!file.open(QFile::ReadOnly)) continue; From 44ab16f93d4007f0bbd1591e2830bae0332aeef2 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Sun, 19 Feb 2012 18:52:19 +0100 Subject: [PATCH 366/406] Small moc cleanup: Pass lists by const reference generateFunctions() shouldn't (and doesn't) modify the list of functions, so the list should be passed by const reference. Change-Id: If5ff810e5623e734816c3089eb8b3fd4f54f2345 Reviewed-by: Bradley T. Hughes Reviewed-by: Olivier Goffart --- src/tools/moc/generator.cpp | 4 ++-- src/tools/moc/generator.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 937a62e87c5..3362a1abc1d 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -443,7 +443,7 @@ void Generator::generateClassInfos() } } -void Generator::generateFunctions(QList& list, const char *functype, int type) +void Generator::generateFunctions(const QList& list, const char *functype, int type) { if (list.isEmpty()) return; @@ -492,7 +492,7 @@ void Generator::generateFunctions(QList& list, const char *functype } } -void Generator::generateFunctionRevisions(QList& list, const char *functype) +void Generator::generateFunctionRevisions(const QList& list, const char *functype) { if (list.count()) fprintf(out, "\n // %ss: revision\n", functype); diff --git a/src/tools/moc/generator.h b/src/tools/moc/generator.h index 4e965116950..46eee4ca06c 100644 --- a/src/tools/moc/generator.h +++ b/src/tools/moc/generator.h @@ -56,8 +56,8 @@ public: void generateCode(); private: void generateClassInfos(); - void generateFunctions(QList &list, const char *functype, int type); - void generateFunctionRevisions(QList& list, const char *functype); + void generateFunctions(const QList &list, const char *functype, int type); + void generateFunctionRevisions(const QList& list, const char *functype); void generateEnums(int index); void generateProperties(); void generateMetacall(); From 3d2c8d76ecc492f37a0384b01c03065b6aae56c6 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 17 Feb 2012 21:48:52 +0100 Subject: [PATCH 367/406] Don't call metaObject() several times It's sufficient to call it once per invokeMethod. Change-Id: I1db826027eca87c799f216d65e27c801a23e64e2 Reviewed-by: Bradley T. Hughes Reviewed-by: Olivier Goffart --- src/corelib/kernel/qmetaobject.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 5ffa2d81dd8..09d6713a435 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1151,18 +1151,19 @@ bool QMetaObject::invokeMethod(QObject *obj, sig[sig.size() - 1] = ')'; sig.append('\0'); - int idx = obj->metaObject()->indexOfMethod(sig.constData()); + const QMetaObject *meta = obj->metaObject(); + int idx = meta->indexOfMethod(sig.constData()); if (idx < 0) { QByteArray norm = QMetaObject::normalizedSignature(sig.constData()); - idx = obj->metaObject()->indexOfMethod(norm.constData()); + idx = meta->indexOfMethod(norm.constData()); } - if (idx < 0 || idx >= obj->metaObject()->methodCount()) { + if (idx < 0 || idx >= meta->methodCount()) { qWarning("QMetaObject::invokeMethod: No such method %s::%s", - obj->metaObject()->className(), sig.constData()); + meta->className(), sig.constData()); return false; } - QMetaMethod method = obj->metaObject()->method(idx); + QMetaMethod method = meta->method(idx); return method.invoke(obj, type, ret, val0, val1, val2, val3, val4, val5, val6, val7, val8, val9); } From 9c1680a7eda7f465d1db0fe1298d7aabd744bd15 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Sun, 19 Feb 2012 19:02:16 +0100 Subject: [PATCH 368/406] Fix typo in QByteArray(QConstByteArrayData) constructor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no "str" member in QConstByteArrayData, it should be "ba". Change-Id: Ife76460e9332733480c1ceded21e78388656092d Reviewed-by: João Abecasis --- src/corelib/tools/qbytearray.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index 3f12d7ddb4b..8202097da5e 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -378,7 +378,7 @@ public: template inline QByteArray(const QConstByteArrayData &dd) - : d(const_cast(&dd.str)) {} + : d(const_cast(&dd.ba)) {} template Q_DECL_CONSTEXPR inline QByteArray(QConstByteArrayDataPtr dd) : d(const_cast(&dd.ptr->ba)) {} From 5640b0b4439941c621b4f0efec541e387abb7daf Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 17 Feb 2012 22:12:05 +0100 Subject: [PATCH 369/406] Add QMetaMethod::isValid() function This function provides a proper way of determining whether a function returned by QMetaObject::method() is valid. (Checking whether signature() returns a 0 pointer, which e.g. testlib does, is not an ideal API -- especially given that signature() will soon be removed and replaced by a function that returns a QByteArray.) Change-Id: I644f476b09904925f2042945f5d0ad744482b682 Reviewed-by: Olivier Goffart Reviewed-by: Lars Knoll --- src/corelib/kernel/qmetaobject.cpp | 8 ++++++++ src/corelib/kernel/qmetaobject.h | 2 ++ .../kernel/qmetamethod/tst_qmetamethod.cpp | 15 +++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 09d6713a435..03fc90b6201 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1248,6 +1248,14 @@ bool QMetaObject::invokeMethod(QObject *obj, \value Scriptable */ +/*! + \fn bool QMetaMethod::isValid() const + \since 5.0 + + Returns true if this method is valid (can be introspected and + invoked), otherwise returns false. +*/ + /*! \fn const QMetaObject *QMetaMethod::enclosingMetaObject() const \internal diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h index 650369164c6..9e51af7556f 100644 --- a/src/corelib/kernel/qmetaobject.h +++ b/src/corelib/kernel/qmetaobject.h @@ -134,6 +134,8 @@ public: val0, val1, val2, val3, val4, val5, val6, val7, val8, val9); } + inline bool isValid() const { return mobj != 0; } + private: const QMetaObject *mobj; uint handle; diff --git a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp index cb34d411fd3..1651d007388 100644 --- a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp +++ b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp @@ -52,6 +52,8 @@ class tst_QMetaMethod : public QObject private slots: void method_data(); void method(); + + void invalidMethod(); }; struct CustomType { }; @@ -597,6 +599,7 @@ void tst_QMetaMethod::method() QVERIFY(index != -1); QMetaMethod method = (methodType == QMetaMethod::Constructor) ? mo->constructor(index) : mo->method(index); + QVERIFY(method.isValid()); QCOMPARE(method.methodType(), methodType); QCOMPARE(method.access(), access); @@ -611,5 +614,17 @@ void tst_QMetaMethod::method() QCOMPARE(method.parameterNames(), parameterNames); } +void tst_QMetaMethod::invalidMethod() +{ + QMetaMethod method; + QVERIFY(!method.isValid()); + + QMetaMethod method2 = staticMetaObject.method(staticMetaObject.methodCount()); + QVERIFY(!method2.isValid()); + + QMetaMethod method3 = staticMetaObject.method(-1); + QVERIFY(!method3.isValid()); +} + QTEST_MAIN(tst_QMetaMethod) #include "tst_qmetamethod.moc" From 989670737fbb84b6e5c483fd3faccd8d2ab917fe Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 17 Feb 2012 22:26:27 +0100 Subject: [PATCH 370/406] Use QMetaMethod::isValid() to check method validity The signature() method will soon be replaced by a function that returns a QByteArray rather than a pointer, and calling it will be more expensive than calling isValid(). Plus, isValid() looks nicer. Change-Id: I6844988c84dcadf876fc86bc71c8b310a21f88de Reviewed-by: Olivier Goffart Reviewed-by: Sergio Ahumada --- src/testlib/qsignaldumper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/testlib/qsignaldumper.cpp b/src/testlib/qsignaldumper.cpp index d0a3af67646..4fd870b6446 100644 --- a/src/testlib/qsignaldumper.cpp +++ b/src/testlib/qsignaldumper.cpp @@ -76,7 +76,7 @@ static void qSignalDumperCallback(QObject *caller, int method_index, void **argv const QMetaObject *mo = caller->metaObject(); Q_ASSERT(mo); QMetaMethod member = mo->method(method_index); - Q_ASSERT(member.signature()); + Q_ASSERT(member.isValid()); if (QTest::ignoreClasses() && QTest::ignoreClasses()->contains(mo->className())) { ++QTest::ignoreLevel; @@ -132,7 +132,7 @@ static void qSignalDumperCallbackSlot(QObject *caller, int method_index, void ** const QMetaObject *mo = caller->metaObject(); Q_ASSERT(mo); QMetaMethod member = mo->method(method_index); - if (!member.signature()) + if (!member.isValid()) return; if (QTest::ignoreLevel || From f83724a0f282862aa91a28baa20e555b1b64371c Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Sat, 18 Feb 2012 21:15:45 +0100 Subject: [PATCH 371/406] Port QSignalEventGenerator meta-object to revision 6 We want to drop support for old revisions in Qt 5. This commit brings the QSignalEventGenerator meta-object in sync with current moc output. Change-Id: Id5f4954b08cf49169850bd77543b2a7ab8274c18 Reviewed-by: Olivier Goffart --- .../statemachine/qsignaleventgenerator_p.h | 8 +-- src/corelib/statemachine/qstatemachine.cpp | 59 +++++++++++++------ 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/src/corelib/statemachine/qsignaleventgenerator_p.h b/src/corelib/statemachine/qsignaleventgenerator_p.h index 2cdca89424a..c117a92a01f 100644 --- a/src/corelib/statemachine/qsignaleventgenerator_p.h +++ b/src/corelib/statemachine/qsignaleventgenerator_p.h @@ -61,13 +61,13 @@ class QStateMachine; class QSignalEventGenerator : public QObject { + Q_OBJECT_FAKE public: QSignalEventGenerator(QStateMachine *parent); - static const QMetaObject staticMetaObject; - virtual const QMetaObject *metaObject() const; - virtual void *qt_metacast(const char *); - virtual int qt_metacall(QMetaObject::Call, int, void **argv); +private: +// slots + void execute(void **_a); private: Q_DISABLE_COPY(QSignalEventGenerator) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 52fd806b055..7ff005f9a12 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -2210,16 +2210,19 @@ void QStateMachine::removeDefaultAnimation(QAbstractAnimation *animation) #endif // QT_NO_ANIMATION +// Begin moc-generated code -- modify carefully (check "HAND EDIT" parts)! static const uint qt_meta_data_QSignalEventGenerator[] = { // content: - 2, // revision + 6, // revision 0, // classname 0, 0, // classinfo - 1, 12, // methods + 1, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors + 0, // flags + 0, // signalCount // slots: signature, parameters, type, tag, flags 23, 22, 22, 22, 0x0a, @@ -2231,9 +2234,26 @@ static const char qt_meta_stringdata_QSignalEventGenerator[] = { "QSignalEventGenerator\0\0execute()\0" }; +void QSignalEventGenerator::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QSignalEventGenerator *_t = static_cast(_o); + switch (_id) { + case 0: _t->execute(_a); break; // HAND EDIT: add the _a parameter + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObjectExtraData QSignalEventGenerator::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + const QMetaObject QSignalEventGenerator::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_QSignalEventGenerator, - qt_meta_data_QSignalEventGenerator, 0 } + qt_meta_data_QSignalEventGenerator, &staticMetaObjectExtraData } }; const QMetaObject *QSignalEventGenerator::metaObject() const @@ -2255,26 +2275,27 @@ int QSignalEventGenerator::qt_metacall(QMetaObject::Call _c, int _id, void **_a) if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { - switch (_id) { - case 0: { -// ### in Qt 4.6 we can use QObject::senderSignalIndex() - QObjectPrivate *d = static_cast(d_ptr.data()); - int signalIndex = -1; - QObject *sender = this->sender(); - if (sender && d->currentSender) - signalIndex = d->currentSender->signal; - - Q_ASSERT(signalIndex != -1); - QStateMachine *machine = qobject_cast(parent()); - QStateMachinePrivate::get(machine)->handleTransitionSignal(sender, signalIndex, _a); - break; - } - default: ; - } + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); _id -= 1; } return _id; } +// End moc-generated code + +void QSignalEventGenerator::execute(void **_a) +{ +// ### in Qt 4.6 we can use QObject::senderSignalIndex() + QObjectPrivate *d = static_cast(d_ptr.data()); + int signalIndex = -1; + QObject *sender = this->sender(); + if (sender && d->currentSender) + signalIndex = d->currentSender->signal; + + Q_ASSERT(signalIndex != -1); + QStateMachine *machine = qobject_cast(parent()); + QStateMachinePrivate::get(machine)->handleTransitionSignal(sender, signalIndex, _a); +} QSignalEventGenerator::QSignalEventGenerator(QStateMachine *parent) : QObject(parent) From 4a0565b4439b9bb71d0e7a77b15b85611a697f57 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Sun, 19 Feb 2012 19:34:50 +0100 Subject: [PATCH 372/406] Move QMetaMethod::parameterTypes() implementation to helper function Because of an upcoming change to the meta-object data format, the ability to extract parameter types from a signature will be needed by meta-object builders (such as QMetaObjectBuilder) soon. Change-Id: I1f21b2be41761a5db2f1a05976fad29eb3aebb03 Reviewed-by: Olivier Goffart Reviewed-by: Thiago Macieira --- src/corelib/kernel/qmetaobject.cpp | 46 ++++++++++++++++++------------ src/corelib/kernel/qmetaobject_p.h | 2 ++ 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 03fc90b6201..d53ba707f7d 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1295,25 +1295,10 @@ const char *QMetaMethod::signature() const */ QList QMetaMethod::parameterTypes() const { - QList list; if (!mobj) - return list; - const char *signature = mobj->d.stringdata + mobj->d.data[handle]; - while (*signature && *signature != '(') - ++signature; - while (*signature && *signature != ')' && *++signature != ')') { - const char *begin = signature; - int level = 0; - while (*signature && (level > 0 || *signature != ',') && *signature != ')') { - if (*signature == '<') - ++level; - else if (*signature == '>') - --level; - ++signature; - } - list += QByteArray(begin, signature - begin); - } - return list; + return QList(); + return QMetaObjectPrivate::parameterTypeNamesFromSignature( + mobj->d.stringdata + mobj->d.data[handle]); } /*! @@ -2809,4 +2794,29 @@ int QMetaObjectPrivate::originalClone(const QMetaObject *mobj, int local_method_ return local_method_index; } +/*! + \internal + + Returns the parameter type names extracted from the given \a signature. +*/ +QList QMetaObjectPrivate::parameterTypeNamesFromSignature(const char *signature) +{ + QList list; + while (*signature && *signature != '(') + ++signature; + while (*signature && *signature != ')' && *++signature != ')') { + const char *begin = signature; + int level = 0; + while (*signature && (level > 0 || *signature != ',') && *signature != ')') { + if (*signature == '<') + ++level; + else if (*signature == '>') + --level; + ++signature; + } + list += QByteArray(begin, signature - begin); + } + return list; +} + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h index d6e49b92d25..59a5c5f2806 100644 --- a/src/corelib/kernel/qmetaobject_p.h +++ b/src/corelib/kernel/qmetaobject_p.h @@ -134,6 +134,8 @@ struct QMetaObjectPrivate bool normalizeStringData); static int originalClone(const QMetaObject *obj, int local_method_index); + static QList parameterTypeNamesFromSignature(const char *signature); + #ifndef QT_NO_QOBJECT //defined in qobject.cpp enum DisconnectType { DisconnectAll, DisconnectOne }; From 46bfd84fdc24fa3e3e721a5dda6cfbebe75be073 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Mon, 20 Feb 2012 09:37:07 +0100 Subject: [PATCH 373/406] Use standard unix mutexes on LSB LSB doesn't allow syscalls, so fall back to the normal _unix implementation Change-Id: I8aba6147da8b46e3f85b0454cf9aca219811c9fe Reviewed-by: Olivier Goffart --- src/corelib/thread/qmutex.cpp | 6 +++--- src/corelib/thread/qmutex_p.h | 12 +++++++++--- src/corelib/thread/thread.pri | 10 +++++++--- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp index 4a64feff0e1..e13c78636c0 100644 --- a/src/corelib/thread/qmutex.cpp +++ b/src/corelib/thread/qmutex.cpp @@ -49,7 +49,7 @@ #include "qthread.h" #include "qmutex_p.h" -#ifndef Q_OS_LINUX +#ifndef Q_MUTEX_LINUX #include "private/qfreelist_p.h" #endif @@ -154,7 +154,7 @@ QMutex::~QMutex() if (quintptr(d) > 0x3 && d->recursive) { delete static_cast(d); } else if (d) { -#ifndef Q_OS_LINUX +#ifndef Q_MUTEX_LINUX if (d != dummyLocked() && static_cast(d)->possiblyUnlocked.load() && tryLock()) { unlock(); @@ -340,7 +340,7 @@ bool QBasicMutex::isRecursive() { \sa unlock() */ -#ifndef Q_OS_LINUX //linux implementation is in qmutex_linux.cpp +#ifndef Q_MUTEX_LINUX //linux implementation is in qmutex_linux.cpp /*! \internal helper for lock() */ diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h index 3cf0938e943..8a9d0bf39bf 100644 --- a/src/corelib/thread/qmutex_p.h +++ b/src/corelib/thread/qmutex_p.h @@ -63,6 +63,11 @@ # include #endif +#if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE) +// use Linux mutexes everywhere except for LSB builds +# define Q_MUTEX_LINUX +#endif + QT_BEGIN_NAMESPACE class QMutexData @@ -73,8 +78,9 @@ public: : recursive(mode == QMutex::Recursive) {} }; -#if !defined(Q_OS_LINUX) -class QMutexPrivate : public QMutexData { +#if !defined(Q_MUTEX_LINUX) +class QMutexPrivate : public QMutexData +{ public: ~QMutexPrivate(); QMutexPrivate(); @@ -122,7 +128,7 @@ public: Qt::HANDLE event; #endif }; -#endif //Q_OS_LINUX +#endif //Q_MUTEX_LINUX class QRecursiveMutexPrivate : public QMutexData { diff --git a/src/corelib/thread/thread.pri b/src/corelib/thread/thread.pri index 1eefa60d500..7f383d6a4c9 100644 --- a/src/corelib/thread/thread.pri +++ b/src/corelib/thread/thread.pri @@ -44,8 +44,12 @@ integrity:SOURCES += thread/qmutex_unix.cpp \ thread/qwaitcondition_unix.cpp unix: { - macx-* { SOURCES += thread/qmutex_mac.cpp } - else:linux-* { SOURCES += thread/qmutex_linux.cpp } - else { SOURCES += thread/qmutex_unix.cpp } + macx-* { + SOURCES += thread/qmutex_mac.cpp + } else:linux-*:!linux-lsb-* { + SOURCES += thread/qmutex_linux.cpp + } else { + SOURCES += thread/qmutex_unix.cpp + } } From d2f1901807b68141755acf1ea23cecf774282708 Mon Sep 17 00:00:00 2001 From: Jan-Arve Saether Date: Sat, 18 Feb 2012 23:29:24 +0100 Subject: [PATCH 374/406] Remove QAccessibleInterface::navigate() This is replaced by parent(), child() and relations() Change-Id: Iabff6ec56176a1ca8465d6480860f6e0174fd134 Reviewed-by: Frederik Gladhorn --- .../code/src_gui_accessible_qaccessible.cpp | 9 --- src/gui/accessible/qaccessible.cpp | 62 ++----------------- src/gui/accessible/qaccessible.h | 1 - 3 files changed, 4 insertions(+), 68 deletions(-) diff --git a/doc/src/snippets/code/src_gui_accessible_qaccessible.cpp b/doc/src/snippets/code/src_gui_accessible_qaccessible.cpp index 52d40d90384..f12f55051e0 100644 --- a/doc/src/snippets/code/src_gui_accessible_qaccessible.cpp +++ b/doc/src/snippets/code/src_gui_accessible_qaccessible.cpp @@ -38,15 +38,6 @@ ** ****************************************************************************/ -//! [0] -QAccessibleInterface *child = 0; -int targetChild = object->navigate(Accessible::Child, 1, &child); -if (child) { - // ... - delete child; -} -//! [0] - //! [1] typedef QAccessibleInterface* myFactoryFunction(const QString &key, QObject *); //! [1] diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 6664e5d3128..6335a3f2494 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -380,8 +380,6 @@ QT_BEGIN_NAMESPACE Implementations of relationTo() return a combination of these flags. Some values are mutually exclusive. - - Implementations of navigate() can accept only one distinct value. */ /*! @@ -782,9 +780,8 @@ QAccessibleInterface *QAccessibleEvent::accessibleInterface() const under the mouse). The relationTo() function provides information about how two - different objects relate to each other, and navigate() allows - traversing from one object to another object with a given - relationship. + different objects relate to each other, and parent() and child() allows + traversing from one object to another object. \section1 Properties @@ -890,7 +887,7 @@ QAccessibleInterface *QAccessibleEvent::accessibleInterface() const All objects provide this information. - \sa relations(), indexOfChild(), navigate() + \sa relations(), indexOfChild(), parent(), child() */ QAccessible::Relation QAccessibleInterface::relationTo(const QAccessibleInterface *) const { @@ -903,7 +900,7 @@ QAccessible::Relation QAccessibleInterface::relationTo(const QAccessibleInterfac It will typically return the labelled-by and label relations. It should never return itself. - \sa relationTo(), navigate() + \sa relationTo(), parent(), child() */ QVector > QAccessibleInterface::relations(QAccessible::Relation /*match = QAccessible::AllRelations*/) const @@ -961,57 +958,6 @@ QAccessibleInterface *QAccessibleInterface::focusChild() const \sa childCount(), parent() */ -/*! - \fn int QAccessibleInterface::navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const - - Navigates from this object to an object that has a relationship - \a relation to this object, and returns the respective object in - \a target. It is the caller's responsibility to delete *\a target - after use. - - If an object is found, \a target is set to point to the object, and - the index of the child of \a target is returned. The return value - is 0 if \a target itself is the requested object. \a target is set - to null if this object is the target object (i.e. the requested - object is a handled by this object). - - If no object is found \a target is set to null, and the return - value is -1. - - The \a entry parameter has two different meanings: - \list - \i \e{Hierarchical and Logical relationships} -- if multiple objects with - the requested relationship exist \a entry specifies which one to - return. \a entry is 1-based, e.g. use 1 to get the first (and - possibly only) object with the requested relationship. - - The following code demonstrates how to use this function to - navigate to the first child of an object: - - \snippet doc/src/snippets/code/src_gui_accessible_qaccessible.cpp 0 - - \i \e{Geometric relationships} -- the index of the child from - which to start navigating in the specified direction. \a entry - can be 0 to navigate to a sibling of this object, or non-null to - navigate within contained children that don't provide their own - accessible information. - \endlist - - Note that the \c Descendent value for \a relation is not supported. - - All objects support navigation. - - \sa relationTo(), childCount(), parent(), child() -*/ -int QAccessibleInterface::navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const -{ - Q_UNUSED(entry); - Q_UNUSED(relation); - *target = 0; - return -1; -} - - /*! \fn QString QAccessibleInterface::text(QAccessible::Text t) const diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index a3661e6f92e..fdf747cef4c 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -389,7 +389,6 @@ public: virtual QAccessibleInterface *child(int index) const = 0; virtual int childCount() const = 0; virtual int indexOfChild(const QAccessibleInterface *) const = 0; - virtual int navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const; // properties and state virtual QString text(QAccessible::Text t) const = 0; From 4816c42115af62c500ff9825f8b5ea1d1515792f Mon Sep 17 00:00:00 2001 From: Matthew Vogt Date: Mon, 20 Feb 2012 09:40:12 +1000 Subject: [PATCH 375/406] Ensure the directory exists to receive a deprecated header. When creating a deprecated header, create the directory it will be located in, if it does not yet exist. Change-Id: Id0ac7327e7dfe5b3e34b431c7bc3844b72251a3d Reviewed-by: Rohan McGovern Reviewed-by: Oswald Buddenhagen --- bin/syncqt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bin/syncqt b/bin/syncqt index 07b9d2432eb..9129de053a3 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -1130,6 +1130,9 @@ foreach my $lib (@modules_to_sync) { my $guard = "DEPRECATED_HEADER_" . $lib . "_" . $header; $guard =~ s/([^a-zA-Z0-9_])/_/g; + my $header_dir = dirname($header_path); + make_path($header_dir, $lib, $verbose_level); + open HEADER, ">$header_path" || die "Could not open $header_path for writing!\n"; print HEADER "#ifndef $guard\n"; print HEADER "#define $guard\n"; From f8d6a164deeee500556b78a72f744ac5bce2226f Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 20 Feb 2012 12:31:37 +0100 Subject: [PATCH 376/406] fix QProcess for Windows XP CreateNamedPipe supports the flag PIPE_REJECT_REMOTE_CLIENTS since Windows Vista. On earlier Windows versions the system call would fail with ERROR_INVALID_PARAMETER. This does not open a security hole on Windows XP as there can be only one pipe instance. Change-Id: I5a1c7fdf756678009857317c7b563c884afeef2c Reviewed-by: Friedemann Kleint --- src/corelib/io/qprocess_win.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 51f34a61a6d..a52fd46c97f 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -85,10 +85,13 @@ static void qt_create_pipe(Q_PIPE *pipe, bool isInputPipe) // ### Replace the call to qrand() with a secure version, once we have it in Qt. swprintf(pipeName, L"\\\\.\\pipe\\qt-%X", qrand()); + DWORD dwPipeFlags = PIPE_TYPE_BYTE | PIPE_WAIT; + if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA) + dwPipeFlags |= PIPE_REJECT_REMOTE_CLIENTS; const DWORD dwPipeBufferSize = 1024 * 1024; hRead = CreateNamedPipe(pipeName, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_BYTE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS, + dwPipeFlags, 1, // only one pipe instance 0, // output buffer size dwPipeBufferSize, // input buffer size From ac1689245419a6fd44e3250d2fdf3d3a058a0c17 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Mon, 20 Feb 2012 09:25:24 +0100 Subject: [PATCH 377/406] Fix LSB mkspec Use the standard g++ specs, just override the compiler name Change-Id: I4adacd7204d3880155bdfc3405e20f322ad593ea Reviewed-by: Oswald Buddenhagen --- mkspecs/linux-lsb-g++/qmake.conf | 98 ++++---------------------------- 1 file changed, 10 insertions(+), 88 deletions(-) diff --git a/mkspecs/linux-lsb-g++/qmake.conf b/mkspecs/linux-lsb-g++/qmake.conf index 4197db09786..4335f5ae91e 100644 --- a/mkspecs/linux-lsb-g++/qmake.conf +++ b/mkspecs/linux-lsb-g++/qmake.conf @@ -2,96 +2,18 @@ # qmake configuration for linux-g++ # -MAKEFILE_GENERATOR = UNIX -TARGET_PLATFORM = unix -TEMPLATE = app -CONFIG += qt warn_on release incremental link_prl gdb_dwarf_index -QT += core gui +MAKEFILE_GENERATOR = UNIX +TARGET_PLATFORM = unix +TEMPLATE = app +CONFIG += qt warn_on release incremental link_prl gdb_dwarf_index +QT += core gui QMAKE_INCREMENTAL_STYLE = sublib -QMAKE_CC = lsbcc -QMAKE_LEX = flex -QMAKE_LEXFLAGS = -QMAKE_YACC = yacc -QMAKE_YACCFLAGS = -d -QMAKE_YACCFLAGS_MANGLE = -p $base -b $base -QMAKE_YACC_HEADER = $base.tab.h -QMAKE_YACC_SOURCE = $base.tab.c -QMAKE_CFLAGS = -pipe -QMAKE_CFLAGS_DEPS = -M -QMAKE_CFLAGS_WARN_ON = -Wall -W -QMAKE_CFLAGS_WARN_OFF = -w -QMAKE_CFLAGS_RELEASE = -O2 -QMAKE_CFLAGS_DEBUG = -g -QMAKE_CFLAGS_SHLIB = -fPIC -QMAKE_CFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_SHLIB -QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses -QMAKE_CFLAGS_THREAD = -D_REENTRANT -QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden +include(../common/linux.conf) +include(../common/gcc-base-unix.conf) +include(../common/g++-unix.conf) +load(qt_config) QMAKE_LSB = 1 - +QMAKE_CC = lsbcc QMAKE_CXX = lsbc++ -QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS -QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF -QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE -QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG -QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB -QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB -QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC -QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD -QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden - -QMAKE_INCDIR = -QMAKE_LIBDIR = -QMAKE_INCDIR_X11 = /opt/lsb/include -QMAKE_LIBDIR_X11 = /opt/lsb/lib -QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] -QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] -QMAKE_INCDIR_OPENGL = /opt/lsb/include -QMAKE_LIBDIR_OPENGL = /opt/lsb/lib - -QMAKE_LINK = lsbc++ -QMAKE_LINK_SHLIB = lsbc++ -QMAKE_LFLAGS = -QMAKE_LFLAGS_RELEASE = -QMAKE_LFLAGS_DEBUG = -QMAKE_LFLAGS_SHLIB = -shared -QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB -QMAKE_LFLAGS_SONAME = -Wl,-soname, -QMAKE_LFLAGS_THREAD = -QMAKE_LFLAGS_RPATH = -Wl,-rpath, - -QMAKE_LIBS = -QMAKE_LIBS_DYNLOAD = -ldl -QMAKE_LIBS_X11 = -lXext -lX11 -lm -QMAKE_LIBS_X11SM = -lSM -lICE -QMAKE_LIBS_NIS = -lnsl -QMAKE_LIBS_OPENGL = -lGL -QMAKE_LIBS_OPENGL_QT = -lGL -QMAKE_LIBS_THREAD = -lpthread - -QMAKE_MOC = $$[QT_INSTALL_BINS]/moc -QMAKE_UIC = $$[QT_INSTALL_BINS]/uic - -QMAKE_AR = ar cqs -QMAKE_OBJCOPY = objcopy -QMAKE_RANLIB = - -QMAKE_TAR = tar -cf -QMAKE_GZIP = gzip -9f - -QMAKE_COPY = cp -f -QMAKE_COPY_FILE = $(COPY) -QMAKE_COPY_DIR = $(COPY) -r -QMAKE_MOVE = mv -f -QMAKE_DEL_FILE = rm -f -QMAKE_DEL_DIR = rmdir -QMAKE_STRIP = strip -QMAKE_STRIPFLAGS_LIB += --strip-unneeded -QMAKE_CHK_DIR_EXISTS = test -d -QMAKE_MKDIR = mkdir -p -include(../common/unix.conf) -load(qt_config) From 49b08f96e824f49fab9aa5c9a1a0ed582d4558bb Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 11 Dec 2011 16:55:01 +0100 Subject: [PATCH 378/406] uic: use QStringLiteral() instead of QString::fromUtf8() where applicable Many (most?) strings written aren't in fact UTF-8, and we can check at compile-time which are and which aren't, so don't hard-code fromUtf8() but use the much more efficient QStringLiteral() where applicable. This is low-hanging fruit. This patch only optimises US-ASCII string literals, not those that are latin-1 or even UTF-8, because that would require more extensive changes to the original fixString() function. Likewise, there are also other calls to QString::fromUtf8() being generated (e.g. in the pixmap code) that could benefit from being turned into QStringLiterals, but their code paths are more involved than those this patch fixes. This patch at least suffices in turning all the setObjectName() arguments into QStringLiterals, which was the main goal. The autotest baseline has been updated with the new expected results. Change-Id: Ic1ef67f500f9ff92d36164d515f4e004ef2a10bc Reviewed-by: Friedemann Kleint --- src/tools/uic/cpp/cppwriteinitialization.cpp | 53 +++--- src/tools/uic/utils.h | 17 +- .../baseline/Dialog_with_Buttons_Bottom.ui.h | 4 +- .../baseline/Dialog_with_Buttons_Right.ui.h | 4 +- .../uic/baseline/Dialog_without_Buttons.ui.h | 2 +- .../auto/tools/uic/baseline/Main_Window.ui.h | 8 +- tests/auto/tools/uic/baseline/Widget.ui.h | 10 +- .../tools/uic/baseline/addlinkdialog.ui.h | 18 +- .../tools/uic/baseline/addtorrentform.ui.h | 48 +++--- .../uic/baseline/authenticationdialog.ui.h | 20 +-- tests/auto/tools/uic/baseline/backside.ui.h | 30 ++-- .../tools/uic/baseline/batchtranslation.ui.h | 34 ++-- .../tools/uic/baseline/bookmarkdialog.ui.h | 32 ++-- tests/auto/tools/uic/baseline/bookwindow.ui.h | 36 ++-- .../tools/uic/baseline/browserwidget.ui.h | 26 +-- tests/auto/tools/uic/baseline/calculator.ui.h | 58 +++---- .../tools/uic/baseline/calculatorform.ui.h | 38 ++--- .../tools/uic/baseline/certificateinfo.ui.h | 20 +-- tests/auto/tools/uic/baseline/chatdialog.ui.h | 16 +- .../tools/uic/baseline/chatmainwindow.ui.h | 32 ++-- .../tools/uic/baseline/chatsetnickname.ui.h | 16 +- tests/auto/tools/uic/baseline/config.ui.h | 104 ++++++------ .../tools/uic/baseline/connectdialog.ui.h | 28 ++-- tests/auto/tools/uic/baseline/controller.ui.h | 14 +- tests/auto/tools/uic/baseline/cookies.ui.h | 16 +- .../tools/uic/baseline/cookiesexceptions.ui.h | 36 ++-- tests/auto/tools/uic/baseline/default.ui.h | 52 +++--- tests/auto/tools/uic/baseline/dialog.ui.h | 10 +- .../auto/tools/uic/baseline/downloaditem.ui.h | 22 +-- tests/auto/tools/uic/baseline/downloads.ui.h | 12 +- .../tools/uic/baseline/embeddeddialog.ui.h | 20 +-- tests/auto/tools/uic/baseline/filespage.ui.h | 12 +- .../tools/uic/baseline/filternamedialog.ui.h | 12 +- tests/auto/tools/uic/baseline/filterpage.ui.h | 18 +- tests/auto/tools/uic/baseline/finddialog.ui.h | 32 ++-- tests/auto/tools/uic/baseline/form.ui.h | 20 +-- .../uic/baseline/formwindowsettings.ui.h | 56 +++---- .../auto/tools/uic/baseline/generalpage.ui.h | 12 +- .../tools/uic/baseline/gridalignment.ui.h | 12 +- tests/auto/tools/uic/baseline/gridpanel.ui.h | 26 +-- tests/auto/tools/uic/baseline/helpdialog.ui.h | 60 +++---- tests/auto/tools/uic/baseline/history.ui.h | 16 +- tests/auto/tools/uic/baseline/icontheme.ui.h | 20 +-- .../tools/uic/baseline/identifierpage.ui.h | 12 +- .../auto/tools/uic/baseline/imagedialog.ui.h | 36 ++-- tests/auto/tools/uic/baseline/inputpage.ui.h | 12 +- .../tools/uic/baseline/installdialog.ui.h | 26 +-- .../tools/uic/baseline/languagesdialog.ui.h | 26 +-- .../tools/uic/baseline/listwidgeteditor.ui.h | 28 ++-- tests/auto/tools/uic/baseline/mainwindow.ui.h | 88 +++++----- tests/auto/tools/uic/baseline/mydialog.ui.h | 8 +- tests/auto/tools/uic/baseline/myform.ui.h | 26 +-- .../tools/uic/baseline/newactiondialog.ui.h | 24 +-- .../baseline/newdynamicpropertydialog.ui.h | 18 +- tests/auto/tools/uic/baseline/newform.ui.h | 16 +- .../auto/tools/uic/baseline/orderdialog.ui.h | 18 +- tests/auto/tools/uic/baseline/outputpage.ui.h | 12 +- tests/auto/tools/uic/baseline/pagefold.ui.h | 56 +++---- .../tools/uic/baseline/paletteeditor.ui.h | 32 ++-- .../tools/uic/baseline/passworddialog.ui.h | 20 +-- tests/auto/tools/uic/baseline/pathpage.ui.h | 16 +- .../tools/uic/baseline/phrasebookbox.ui.h | 32 ++-- .../auto/tools/uic/baseline/plugindialog.ui.h | 14 +- .../tools/uic/baseline/preferencesdialog.ui.h | 36 ++-- .../baseline/previewconfigurationwidget.ui.h | 26 +-- .../tools/uic/baseline/previewdialogbase.ui.h | 26 +-- .../tools/uic/baseline/previewwidget.ui.h | 42 ++--- tests/auto/tools/uic/baseline/proxy.ui.h | 18 +- .../auto/tools/uic/baseline/qfiledialog.ui.h | 54 +++--- .../tools/uic/baseline/qpagesetupwidget.ui.h | 60 +++---- .../uic/baseline/qprintpropertieswidget.ui.h | 18 +- .../uic/baseline/qprintsettingsoutput.ui.h | 66 ++++---- .../auto/tools/uic/baseline/qprintwidget.ui.h | 32 ++-- .../uic/baseline/qsqlconnectiondialog.ui.h | 42 ++--- .../tools/uic/baseline/qtgradientdialog.ui.h | 8 +- .../tools/uic/baseline/qtgradienteditor.ui.h | 158 +++++++++--------- .../tools/uic/baseline/qtgradientview.ui.h | 16 +- .../uic/baseline/qtgradientviewdialog.ui.h | 8 +- .../uic/baseline/qtresourceeditordialog.ui.h | 32 ++-- .../tools/uic/baseline/qttoolbardialog.ui.h | 36 ++-- .../auto/tools/uic/baseline/querywidget.ui.h | 36 ++-- .../tools/uic/baseline/remotecontrol.ui.h | 56 +++---- .../uic/baseline/saveformastemplate.ui.h | 18 +- tests/auto/tools/uic/baseline/settings.ui.h | 34 ++-- .../tools/uic/baseline/signalslotdialog.ui.h | 30 ++-- tests/auto/tools/uic/baseline/sslclient.ui.h | 36 ++-- tests/auto/tools/uic/baseline/sslerrors.ui.h | 16 +- tests/auto/tools/uic/baseline/statistics.ui.h | 42 ++--- .../tools/uic/baseline/stringlisteditor.ui.h | 32 ++-- .../tools/uic/baseline/stylesheeteditor.ui.h | 18 +- .../tools/uic/baseline/tabbedbrowser.ui.h | 28 ++-- .../tools/uic/baseline/tablewidgeteditor.ui.h | 66 ++++---- .../auto/tools/uic/baseline/tetrixwindow.ui.h | 30 ++-- tests/auto/tools/uic/baseline/textfinder.ui.h | 14 +- .../auto/tools/uic/baseline/topicchooser.ui.h | 20 +-- .../tools/uic/baseline/translatedialog.ui.h | 34 ++-- .../uic/baseline/translationsettings.ui.h | 18 +- .../tools/uic/baseline/treewidgeteditor.ui.h | 56 +++---- .../tools/uic/baseline/trpreviewtool.ui.h | 38 ++--- tests/auto/tools/uic/baseline/validators.ui.h | 72 ++++---- .../uic/baseline/wateringconfigdialog.ui.h | 46 ++--- 101 files changed, 1541 insertions(+), 1529 deletions(-) diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index 91f2f2558be..5762c175cc5 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -537,7 +537,7 @@ void WriteInitialization::acceptUI(DomUI *node) continue; const QString varConn = connection + QLatin1String("Connection"); - m_output << m_indent << varConn << " = QSqlDatabase::database(" << fixString(connection, m_dindent) << ");\n"; + m_output << m_indent << varConn << " = QSqlDatabase::database(" << writeString(connection, m_dindent) << ");\n"; } acceptWidget(node->elementWidget()); @@ -1143,7 +1143,7 @@ QString WriteInitialization::writeStringListProperty(const DomStringList *list) str << '\n' << m_indent << " << " << trCall(values.at(i), comment); } else { for (int i = 0; i < values.size(); ++i) - str << " << QString::fromUtf8(" << fixString(values.at(i), m_dindent) << ')'; + str << " << " << writeString(values.at(i), m_dindent); } return propertyValue; } @@ -1159,8 +1159,8 @@ void WriteInitialization::writeProperties(const QString &varName, DomPropertyMap properties = propertyMap(lst); if (properties.contains(QLatin1String("control"))) { DomProperty *p = properties.value(QLatin1String("control")); - m_output << m_indent << varName << "->setControl(QString::fromUtf8(" - << fixString(toString(p->elementString()), m_dindent) << "));\n"; + m_output << m_indent << varName << "->setControl(" + << writeString(toString(p->elementString()), m_dindent) << ");\n"; } } @@ -1171,7 +1171,7 @@ void WriteInitialization::writeProperties(const QString &varName, } if (!(flags & WritePropertyIgnoreObjectName)) m_output << m_indent << indent << varName - << "->setObjectName(QString::fromUtf8(" << fixString(varName, m_dindent) << "));\n"; + << "->setObjectName(" << writeString(varName, m_dindent) << ");\n"; int leftMargin, topMargin, rightMargin, bottomMargin; leftMargin = topMargin = rightMargin = bottomMargin = -1; @@ -1459,8 +1459,8 @@ void WriteInitialization::writeProperties(const QString &varName, case DomProperty::Url: { const DomUrl* u = p->elementUrl(); - propertyValue = QString::fromLatin1("QUrl(QString::fromUtf8(%1))") - .arg(fixString(u->elementString()->text(), m_dindent)); + propertyValue = QString::fromLatin1("QUrl(%1)") + .arg(writeString(u->elementString()->text(), m_dindent)); break; } case DomProperty::Brush: @@ -1562,8 +1562,8 @@ QString WriteInitialization::writeFontProperties(const DomFont *f) m_output << m_indent << "QFont " << fontName << ";\n"; if (f->hasElementFamily() && !f->elementFamily().isEmpty()) { - m_output << m_indent << fontName << ".setFamily(QString::fromUtf8(" << fixString(f->elementFamily(), m_dindent) - << "));\n"; + m_output << m_indent << fontName << ".setFamily(" << writeString(f->elementFamily(), m_dindent) + << ");\n"; } if (f->hasElementPointSize() && f->elementPointSize() > 0) { m_output << m_indent << fontName << ".setPointSize(" << f->elementPointSize() @@ -1612,21 +1612,21 @@ static void writeResourceIcon(QTextStream &output, const DomResourceIcon *i) { if (i->hasElementNormalOff()) - output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOff()->text(), indent) << "), QSize(), QIcon::Normal, QIcon::Off);\n"; + output << indent << iconName << ".addFile(" << writeString(i->elementNormalOff()->text(), indent) << ", QSize(), QIcon::Normal, QIcon::Off);\n"; if (i->hasElementNormalOn()) - output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOn()->text(), indent) << "), QSize(), QIcon::Normal, QIcon::On);\n"; + output << indent << iconName << ".addFile(" << writeString(i->elementNormalOn()->text(), indent) << ", QSize(), QIcon::Normal, QIcon::On);\n"; if (i->hasElementDisabledOff()) - output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementDisabledOff()->text(), indent) << "), QSize(), QIcon::Disabled, QIcon::Off);\n"; + output << indent << iconName << ".addFile(" << writeString(i->elementDisabledOff()->text(), indent) << ", QSize(), QIcon::Disabled, QIcon::Off);\n"; if (i->hasElementDisabledOn()) - output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementDisabledOn()->text(), indent) << "), QSize(), QIcon::Disabled, QIcon::On);\n"; + output << indent << iconName << ".addFile(" << writeString(i->elementDisabledOn()->text(), indent) << ", QSize(), QIcon::Disabled, QIcon::On);\n"; if (i->hasElementActiveOff()) - output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementActiveOff()->text(), indent) << "), QSize(), QIcon::Active, QIcon::Off);\n"; + output << indent << iconName << ".addFile(" << writeString(i->elementActiveOff()->text(), indent) << ", QSize(), QIcon::Active, QIcon::Off);\n"; if (i->hasElementActiveOn()) - output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementActiveOn()->text(), indent) << "), QSize(), QIcon::Active, QIcon::On);\n"; + output << indent << iconName << ".addFile(" << writeString(i->elementActiveOn()->text(), indent) << ", QSize(), QIcon::Active, QIcon::On);\n"; if (i->hasElementSelectedOff()) - output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementSelectedOff()->text(), indent) << "), QSize(), QIcon::Selected, QIcon::Off);\n"; + output << indent << iconName << ".addFile(" << writeString(i->elementSelectedOff()->text(), indent) << ", QSize(), QIcon::Selected, QIcon::Off);\n"; if (i->hasElementSelectedOn()) - output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementSelectedOn()->text(), indent) << "), QSize(), QIcon::Selected, QIcon::On);\n"; + output << indent << iconName << ".addFile(" << writeString(i->elementSelectedOn()->text(), indent) << ", QSize(), QIcon::Selected, QIcon::On);\n"; } QString WriteInitialization::writeIconProperties(const DomResourceIcon *i) @@ -1648,7 +1648,7 @@ QString WriteInitialization::writeIconProperties(const DomResourceIcon *i) writeResourceIcon(m_output, iconName, m_indent, i); } else { // Theme: Generate code to check the theme and default to resource - const QString themeIconName = fixString(i->attributeTheme(), QString()); + const QString themeIconName = writeString(i->attributeTheme(), QString()); if (iconHasStatePixmaps(i)) { // Theme + default state pixmaps: // Generate code to check the theme and default to state pixmaps @@ -1660,8 +1660,8 @@ QString WriteInitialization::writeIconProperties(const DomResourceIcon *i) m_output << "QString "; m_firstThemeIcon = false; } - m_output << themeNameStringVariableC << " = QString::fromUtf8(" - << themeIconName << ");\n"; + m_output << themeNameStringVariableC << " = " + << themeIconName << ";\n"; m_output << m_indent << "if (QIcon::hasThemeIcon(" << themeNameStringVariableC << ")) {\n" @@ -1672,8 +1672,8 @@ QString WriteInitialization::writeIconProperties(const DomResourceIcon *i) } else { // Theme, but no state pixmaps: Construct from theme directly. m_output << m_indent << "QIcon " << iconName - << "(QIcon::fromTheme(QString::fromUtf8(" - << themeIconName << ")));\n"; + << "(QIcon::fromTheme(" + << themeIconName << "));\n"; } // Theme, but not state } // >= 4.4 } else { // pre-4.4 legacy @@ -2356,10 +2356,7 @@ QString WriteInitialization::noTrCall(DomString *str, const QString &defaultStri return QString(); if (str) value = str->text(); - QString ret = QLatin1String("QString::fromUtf8("); - ret += fixString(value, m_dindent); - ret += QLatin1Char(')'); - return ret; + return writeString(value, m_dindent); } QString WriteInitialization::autoTrCall(DomString *str, const QString &defaultString) const @@ -2481,8 +2478,8 @@ void WriteInitialization::acceptWidgetScripts(const DomScripts &widgetScripts, D } m_output << ";\n"; } - m_output << m_indent << "scriptContext.run(QString::fromUtf8(" - << fixString(script, m_dindent) << "), " + m_output << m_indent << "scriptContext.run(" + << writeString(script, m_dindent) << ", " << m_driver->findOrInsertWidget(node) << ", childWidgets);\n"; } diff --git a/src/tools/uic/utils.h b/src/tools/uic/utils.h index c864305891b..c6dbe548cb6 100644 --- a/src/tools/uic/utils.h +++ b/src/tools/uic/utils.h @@ -55,18 +55,21 @@ inline bool toBool(const QString &str) inline QString toString(const DomString *str) { return str ? str->text() : QString(); } -inline QString fixString(const QString &str, const QString &indent) +inline QString fixString(const QString &str, const QString &indent, bool *isUtf8Ret=0) { QString cursegment; QStringList result; const QByteArray utf8 = str.toUtf8(); const int utf8Length = utf8.length(); + bool isUtf8 = false; + for (int i = 0; i < utf8Length; ++i) { const uchar cbyte = utf8.at(i); if (cbyte >= 0x80) { cursegment += QLatin1Char('\\'); cursegment += QString::number(cbyte, 8); + isUtf8 = true; } else { switch(cbyte) { case '\\': @@ -100,9 +103,21 @@ inline QString fixString(const QString &str, const QString &indent) QString rc(QLatin1Char('"')); rc += result.join(joinstr); rc += QLatin1Char('"'); + if (isUtf8Ret) + *isUtf8Ret = isUtf8; return rc; } +inline QString writeString(const QString &s, const QString &indent) +{ + bool isUtf8 = false; + const QString ret = fixString(s, indent, &isUtf8); + if (isUtf8) + return QLatin1String("QString::fromUtf8(") + ret + QLatin1Char(')'); + else + return QLatin1String("QStringLiteral(") + ret + QLatin1Char(')'); +} + inline QHash propertyMap(const QList &properties) { QHash map; diff --git a/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Bottom.ui.h b/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Bottom.ui.h index b5b2bb82eac..1725fd6ece0 100644 --- a/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Bottom.ui.h +++ b/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Bottom.ui.h @@ -28,10 +28,10 @@ public: void setupUi(QDialog *Dialog) { if (Dialog->objectName().isEmpty()) - Dialog->setObjectName(QString::fromUtf8("Dialog")); + Dialog->setObjectName(QStringLiteral("Dialog")); Dialog->resize(400, 300); buttonBox = new QDialogButtonBox(Dialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setGeometry(QRect(30, 240, 341, 32)); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Right.ui.h b/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Right.ui.h index 3d5eabaace2..4b25efe6cf0 100644 --- a/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Right.ui.h +++ b/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Right.ui.h @@ -28,10 +28,10 @@ public: void setupUi(QDialog *Dialog) { if (Dialog->objectName().isEmpty()) - Dialog->setObjectName(QString::fromUtf8("Dialog")); + Dialog->setObjectName(QStringLiteral("Dialog")); Dialog->resize(400, 300); buttonBox = new QDialogButtonBox(Dialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setGeometry(QRect(290, 20, 81, 241)); buttonBox->setOrientation(Qt::Vertical); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/Dialog_without_Buttons.ui.h b/tests/auto/tools/uic/baseline/Dialog_without_Buttons.ui.h index 267646692da..21b34f86e1e 100644 --- a/tests/auto/tools/uic/baseline/Dialog_without_Buttons.ui.h +++ b/tests/auto/tools/uic/baseline/Dialog_without_Buttons.ui.h @@ -26,7 +26,7 @@ public: void setupUi(QDialog *Dialog) { if (Dialog->objectName().isEmpty()) - Dialog->setObjectName(QString::fromUtf8("Dialog")); + Dialog->setObjectName(QStringLiteral("Dialog")); Dialog->resize(400, 300); retranslateUi(Dialog); diff --git a/tests/auto/tools/uic/baseline/Main_Window.ui.h b/tests/auto/tools/uic/baseline/Main_Window.ui.h index d6e0ee4a42b..d579688a176 100644 --- a/tests/auto/tools/uic/baseline/Main_Window.ui.h +++ b/tests/auto/tools/uic/baseline/Main_Window.ui.h @@ -32,16 +32,16 @@ public: void setupUi(QMainWindow *MainWindow) { if (MainWindow->objectName().isEmpty()) - MainWindow->setObjectName(QString::fromUtf8("MainWindow")); + MainWindow->setObjectName(QStringLiteral("MainWindow")); MainWindow->resize(800, 600); menubar = new QMenuBar(MainWindow); - menubar->setObjectName(QString::fromUtf8("menubar")); + menubar->setObjectName(QStringLiteral("menubar")); MainWindow->setMenuBar(menubar); centralwidget = new QWidget(MainWindow); - centralwidget->setObjectName(QString::fromUtf8("centralwidget")); + centralwidget->setObjectName(QStringLiteral("centralwidget")); MainWindow->setCentralWidget(centralwidget); statusbar = new QStatusBar(MainWindow); - statusbar->setObjectName(QString::fromUtf8("statusbar")); + statusbar->setObjectName(QStringLiteral("statusbar")); MainWindow->setStatusBar(statusbar); retranslateUi(MainWindow); diff --git a/tests/auto/tools/uic/baseline/Widget.ui.h b/tests/auto/tools/uic/baseline/Widget.ui.h index 5dcca86903d..1ccf8e8d52a 100644 --- a/tests/auto/tools/uic/baseline/Widget.ui.h +++ b/tests/auto/tools/uic/baseline/Widget.ui.h @@ -34,22 +34,22 @@ public: void setupUi(QWidget *Form) { if (Form->objectName().isEmpty()) - Form->setObjectName(QString::fromUtf8("Form")); + Form->setObjectName(QStringLiteral("Form")); Form->resize(400, 300); vboxLayout = new QVBoxLayout(Form); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); Alabel = new QLabel(Form); - Alabel->setObjectName(QString::fromUtf8("Alabel")); + Alabel->setObjectName(QStringLiteral("Alabel")); vboxLayout->addWidget(Alabel); groupBox = new QGroupBox(Form); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); vboxLayout->addWidget(groupBox); pushButton = new QPushButton(Form); - pushButton->setObjectName(QString::fromUtf8("pushButton")); + pushButton->setObjectName(QStringLiteral("pushButton")); vboxLayout->addWidget(pushButton); diff --git a/tests/auto/tools/uic/baseline/addlinkdialog.ui.h b/tests/auto/tools/uic/baseline/addlinkdialog.ui.h index 79262a1ae64..537fa2d8b19 100644 --- a/tests/auto/tools/uic/baseline/addlinkdialog.ui.h +++ b/tests/auto/tools/uic/baseline/addlinkdialog.ui.h @@ -42,31 +42,31 @@ public: void setupUi(QDialog *AddLinkDialog) { if (AddLinkDialog->objectName().isEmpty()) - AddLinkDialog->setObjectName(QString::fromUtf8("AddLinkDialog")); + AddLinkDialog->setObjectName(QStringLiteral("AddLinkDialog")); AddLinkDialog->setSizeGripEnabled(false); AddLinkDialog->setModal(true); verticalLayout = new QVBoxLayout(AddLinkDialog); - verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); formLayout = new QFormLayout(); - formLayout->setObjectName(QString::fromUtf8("formLayout")); + formLayout->setObjectName(QStringLiteral("formLayout")); label = new QLabel(AddLinkDialog); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); formLayout->setWidget(0, QFormLayout::LabelRole, label); titleInput = new QLineEdit(AddLinkDialog); - titleInput->setObjectName(QString::fromUtf8("titleInput")); + titleInput->setObjectName(QStringLiteral("titleInput")); titleInput->setMinimumSize(QSize(337, 0)); formLayout->setWidget(0, QFormLayout::FieldRole, titleInput); label_2 = new QLabel(AddLinkDialog); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); formLayout->setWidget(1, QFormLayout::LabelRole, label_2); urlInput = new QLineEdit(AddLinkDialog); - urlInput->setObjectName(QString::fromUtf8("urlInput")); + urlInput->setObjectName(QStringLiteral("urlInput")); formLayout->setWidget(1, QFormLayout::FieldRole, urlInput); @@ -78,14 +78,14 @@ public: verticalLayout->addItem(verticalSpacer); line = new QFrame(AddLinkDialog); - line->setObjectName(QString::fromUtf8("line")); + line->setObjectName(QStringLiteral("line")); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); verticalLayout->addWidget(line); buttonBox = new QDialogButtonBox(AddLinkDialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/addtorrentform.ui.h b/tests/auto/tools/uic/baseline/addtorrentform.ui.h index a1cb6c56d4a..dfca1699aef 100644 --- a/tests/auto/tools/uic/baseline/addtorrentform.ui.h +++ b/tests/auto/tools/uic/baseline/addtorrentform.ui.h @@ -60,7 +60,7 @@ public: void setupUi(QDialog *AddTorrentFile) { if (AddTorrentFile->objectName().isEmpty()) - AddTorrentFile->setObjectName(QString::fromUtf8("AddTorrentFile")); + AddTorrentFile->setObjectName(QStringLiteral("AddTorrentFile")); AddTorrentFile->resize(464, 385); AddTorrentFile->setSizeGripEnabled(false); AddTorrentFile->setModal(true); @@ -69,57 +69,57 @@ public: vboxLayout->setSpacing(6); #endif vboxLayout->setContentsMargins(8, 8, 8, 8); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); groupBox = new QGroupBox(AddTorrentFile); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); widget = new QWidget(groupBox); - widget->setObjectName(QString::fromUtf8("widget")); + widget->setObjectName(QStringLiteral("widget")); widget->setGeometry(QRect(10, 40, 364, 33)); gridLayout = new QGridLayout(groupBox); #ifndef Q_OS_MAC gridLayout->setSpacing(6); #endif gridLayout->setContentsMargins(8, 8, 8, 8); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); label_4 = new QLabel(groupBox); - label_4->setObjectName(QString::fromUtf8("label_4")); + label_4->setObjectName(QStringLiteral("label_4")); gridLayout->addWidget(label_4, 6, 0, 1, 1); torrentFile = new QLineEdit(groupBox); - torrentFile->setObjectName(QString::fromUtf8("torrentFile")); + torrentFile->setObjectName(QStringLiteral("torrentFile")); gridLayout->addWidget(torrentFile, 0, 1, 1, 2); label_2 = new QLabel(groupBox); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); gridLayout->addWidget(label_2, 1, 0, 1, 1); browseTorrents = new QPushButton(groupBox); - browseTorrents->setObjectName(QString::fromUtf8("browseTorrents")); + browseTorrents->setObjectName(QStringLiteral("browseTorrents")); browseTorrents->setDefault(true); gridLayout->addWidget(browseTorrents, 0, 3, 1, 1); label_5 = new QLabel(groupBox); - label_5->setObjectName(QString::fromUtf8("label_5")); + label_5->setObjectName(QStringLiteral("label_5")); label_5->setAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop); gridLayout->addWidget(label_5, 5, 0, 1, 1); label_3 = new QLabel(groupBox); - label_3->setObjectName(QString::fromUtf8("label_3")); + label_3->setObjectName(QStringLiteral("label_3")); gridLayout->addWidget(label_3, 4, 0, 1, 1); label_6 = new QLabel(groupBox); - label_6->setObjectName(QString::fromUtf8("label_6")); + label_6->setObjectName(QStringLiteral("label_6")); gridLayout->addWidget(label_6, 2, 0, 1, 1); torrentContents = new QTextEdit(groupBox); - torrentContents->setObjectName(QString::fromUtf8("torrentContents")); + torrentContents->setObjectName(QStringLiteral("torrentContents")); torrentContents->setFocusPolicy(Qt::NoFocus); torrentContents->setTabChangesFocus(true); torrentContents->setLineWrapMode(QTextEdit::NoWrap); @@ -128,43 +128,43 @@ public: gridLayout->addWidget(torrentContents, 5, 1, 1, 3); destinationFolder = new QLineEdit(groupBox); - destinationFolder->setObjectName(QString::fromUtf8("destinationFolder")); + destinationFolder->setObjectName(QStringLiteral("destinationFolder")); destinationFolder->setFocusPolicy(Qt::StrongFocus); gridLayout->addWidget(destinationFolder, 6, 1, 1, 2); announceUrl = new QLabel(groupBox); - announceUrl->setObjectName(QString::fromUtf8("announceUrl")); + announceUrl->setObjectName(QStringLiteral("announceUrl")); gridLayout->addWidget(announceUrl, 1, 1, 1, 3); label = new QLabel(groupBox); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 0, 0, 1, 1); browseDestination = new QPushButton(groupBox); - browseDestination->setObjectName(QString::fromUtf8("browseDestination")); + browseDestination->setObjectName(QStringLiteral("browseDestination")); gridLayout->addWidget(browseDestination, 6, 3, 1, 1); label_7 = new QLabel(groupBox); - label_7->setObjectName(QString::fromUtf8("label_7")); + label_7->setObjectName(QStringLiteral("label_7")); gridLayout->addWidget(label_7, 3, 0, 1, 1); commentLabel = new QLabel(groupBox); - commentLabel->setObjectName(QString::fromUtf8("commentLabel")); + commentLabel->setObjectName(QStringLiteral("commentLabel")); gridLayout->addWidget(commentLabel, 3, 1, 1, 3); creatorLabel = new QLabel(groupBox); - creatorLabel->setObjectName(QString::fromUtf8("creatorLabel")); + creatorLabel->setObjectName(QStringLiteral("creatorLabel")); gridLayout->addWidget(creatorLabel, 2, 1, 1, 3); sizeLabel = new QLabel(groupBox); - sizeLabel->setObjectName(QString::fromUtf8("sizeLabel")); + sizeLabel->setObjectName(QStringLiteral("sizeLabel")); gridLayout->addWidget(sizeLabel, 4, 1, 1, 3); @@ -176,19 +176,19 @@ public: hboxLayout->setSpacing(6); #endif hboxLayout->setContentsMargins(0, 0, 0, 0); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); spacerItem = new QSpacerItem(131, 31, QSizePolicy::Expanding, QSizePolicy::Minimum); hboxLayout->addItem(spacerItem); okButton = new QPushButton(AddTorrentFile); - okButton->setObjectName(QString::fromUtf8("okButton")); + okButton->setObjectName(QStringLiteral("okButton")); okButton->setEnabled(false); hboxLayout->addWidget(okButton); cancelButton = new QPushButton(AddTorrentFile); - cancelButton->setObjectName(QString::fromUtf8("cancelButton")); + cancelButton->setObjectName(QStringLiteral("cancelButton")); hboxLayout->addWidget(cancelButton); diff --git a/tests/auto/tools/uic/baseline/authenticationdialog.ui.h b/tests/auto/tools/uic/baseline/authenticationdialog.ui.h index def597f64f3..1aef4729f6f 100644 --- a/tests/auto/tools/uic/baseline/authenticationdialog.ui.h +++ b/tests/auto/tools/uic/baseline/authenticationdialog.ui.h @@ -41,50 +41,50 @@ public: void setupUi(QDialog *Dialog) { if (Dialog->objectName().isEmpty()) - Dialog->setObjectName(QString::fromUtf8("Dialog")); + Dialog->setObjectName(QStringLiteral("Dialog")); Dialog->resize(389, 243); gridLayout = new QGridLayout(Dialog); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); label = new QLabel(Dialog); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); label->setWordWrap(false); gridLayout->addWidget(label, 0, 0, 1, 2); label_2 = new QLabel(Dialog); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); gridLayout->addWidget(label_2, 2, 0, 1, 1); userEdit = new QLineEdit(Dialog); - userEdit->setObjectName(QString::fromUtf8("userEdit")); + userEdit->setObjectName(QStringLiteral("userEdit")); gridLayout->addWidget(userEdit, 2, 1, 1, 1); label_3 = new QLabel(Dialog); - label_3->setObjectName(QString::fromUtf8("label_3")); + label_3->setObjectName(QStringLiteral("label_3")); gridLayout->addWidget(label_3, 3, 0, 1, 1); passwordEdit = new QLineEdit(Dialog); - passwordEdit->setObjectName(QString::fromUtf8("passwordEdit")); + passwordEdit->setObjectName(QStringLiteral("passwordEdit")); gridLayout->addWidget(passwordEdit, 3, 1, 1, 1); buttonBox = new QDialogButtonBox(Dialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); gridLayout->addWidget(buttonBox, 5, 0, 1, 2); label_4 = new QLabel(Dialog); - label_4->setObjectName(QString::fromUtf8("label_4")); + label_4->setObjectName(QStringLiteral("label_4")); gridLayout->addWidget(label_4, 1, 0, 1, 1); siteDescription = new QLabel(Dialog); - siteDescription->setObjectName(QString::fromUtf8("siteDescription")); + siteDescription->setObjectName(QStringLiteral("siteDescription")); QFont font; font.setBold(true); font.setWeight(75); diff --git a/tests/auto/tools/uic/baseline/backside.ui.h b/tests/auto/tools/uic/baseline/backside.ui.h index f09c468a342..7e25775c98a 100644 --- a/tests/auto/tools/uic/baseline/backside.ui.h +++ b/tests/auto/tools/uic/baseline/backside.ui.h @@ -50,47 +50,47 @@ public: void setupUi(QWidget *BackSide) { if (BackSide->objectName().isEmpty()) - BackSide->setObjectName(QString::fromUtf8("BackSide")); + BackSide->setObjectName(QStringLiteral("BackSide")); BackSide->resize(378, 385); verticalLayout_2 = new QVBoxLayout(BackSide); - verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2")); + verticalLayout_2->setObjectName(QStringLiteral("verticalLayout_2")); groupBox = new QGroupBox(BackSide); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); groupBox->setFlat(true); groupBox->setCheckable(true); gridLayout = new QGridLayout(groupBox); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); label = new QLabel(groupBox); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 0, 0, 1, 1); hostName = new QLineEdit(groupBox); - hostName->setObjectName(QString::fromUtf8("hostName")); + hostName->setObjectName(QStringLiteral("hostName")); gridLayout->addWidget(hostName, 0, 1, 1, 1); label_2 = new QLabel(groupBox); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); gridLayout->addWidget(label_2, 1, 0, 1, 1); label_3 = new QLabel(groupBox); - label_3->setObjectName(QString::fromUtf8("label_3")); + label_3->setObjectName(QStringLiteral("label_3")); gridLayout->addWidget(label_3, 2, 0, 1, 1); horizontalLayout = new QHBoxLayout(); - horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); horizontalSlider = new QSlider(groupBox); - horizontalSlider->setObjectName(QString::fromUtf8("horizontalSlider")); + horizontalSlider->setObjectName(QStringLiteral("horizontalSlider")); horizontalSlider->setValue(42); horizontalSlider->setOrientation(Qt::Horizontal); horizontalLayout->addWidget(horizontalSlider); spinBox = new QSpinBox(groupBox); - spinBox->setObjectName(QString::fromUtf8("spinBox")); + spinBox->setObjectName(QStringLiteral("spinBox")); spinBox->setValue(42); horizontalLayout->addWidget(spinBox); @@ -99,7 +99,7 @@ public: gridLayout->addLayout(horizontalLayout, 2, 1, 1, 1); dateTimeEdit = new QDateTimeEdit(groupBox); - dateTimeEdit->setObjectName(QString::fromUtf8("dateTimeEdit")); + dateTimeEdit->setObjectName(QStringLiteral("dateTimeEdit")); gridLayout->addWidget(dateTimeEdit, 1, 1, 1, 1); @@ -107,11 +107,11 @@ public: verticalLayout_2->addWidget(groupBox); groupBox_2 = new QGroupBox(BackSide); - groupBox_2->setObjectName(QString::fromUtf8("groupBox_2")); + groupBox_2->setObjectName(QStringLiteral("groupBox_2")); groupBox_2->setFlat(true); groupBox_2->setCheckable(true); horizontalLayout_2 = new QHBoxLayout(groupBox_2); - horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2")); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); treeWidget = new QTreeWidget(groupBox_2); QTreeWidgetItem *__qtreewidgetitem = new QTreeWidgetItem(treeWidget); QTreeWidgetItem *__qtreewidgetitem1 = new QTreeWidgetItem(__qtreewidgetitem); @@ -124,7 +124,7 @@ public: QTreeWidgetItem *__qtreewidgetitem4 = new QTreeWidgetItem(treeWidget); QTreeWidgetItem *__qtreewidgetitem5 = new QTreeWidgetItem(__qtreewidgetitem4); new QTreeWidgetItem(__qtreewidgetitem5); - treeWidget->setObjectName(QString::fromUtf8("treeWidget")); + treeWidget->setObjectName(QStringLiteral("treeWidget")); horizontalLayout_2->addWidget(treeWidget); diff --git a/tests/auto/tools/uic/baseline/batchtranslation.ui.h b/tests/auto/tools/uic/baseline/batchtranslation.ui.h index 302dbc2cb42..b1ba5bee31b 100644 --- a/tests/auto/tools/uic/baseline/batchtranslation.ui.h +++ b/tests/auto/tools/uic/baseline/batchtranslation.ui.h @@ -95,7 +95,7 @@ public: void setupUi(QDialog *databaseTranslationDialog) { if (databaseTranslationDialog->objectName().isEmpty()) - databaseTranslationDialog->setObjectName(QString::fromUtf8("databaseTranslationDialog")); + databaseTranslationDialog->setObjectName(QStringLiteral("databaseTranslationDialog")); databaseTranslationDialog->resize(425, 370); vboxLayout = new QVBoxLayout(databaseTranslationDialog); #ifndef Q_OS_MAC @@ -104,9 +104,9 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); groupBox = new QGroupBox(databaseTranslationDialog); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); QSizePolicy sizePolicy(static_cast(5), static_cast(4)); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -119,15 +119,15 @@ public: #ifndef Q_OS_MAC vboxLayout1->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); ckOnlyUntranslated = new QCheckBox(groupBox); - ckOnlyUntranslated->setObjectName(QString::fromUtf8("ckOnlyUntranslated")); + ckOnlyUntranslated->setObjectName(QStringLiteral("ckOnlyUntranslated")); ckOnlyUntranslated->setChecked(true); vboxLayout1->addWidget(ckOnlyUntranslated); ckMarkFinished = new QCheckBox(groupBox); - ckMarkFinished->setObjectName(QString::fromUtf8("ckMarkFinished")); + ckMarkFinished->setObjectName(QStringLiteral("ckMarkFinished")); ckMarkFinished->setChecked(true); vboxLayout1->addWidget(ckMarkFinished); @@ -136,7 +136,7 @@ public: vboxLayout->addWidget(groupBox); groupBox_2 = new QGroupBox(databaseTranslationDialog); - groupBox_2->setObjectName(QString::fromUtf8("groupBox_2")); + groupBox_2->setObjectName(QStringLiteral("groupBox_2")); QSizePolicy sizePolicy1(static_cast(5), static_cast(1)); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); @@ -149,7 +149,7 @@ public: #ifndef Q_OS_MAC vboxLayout2->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2")); + vboxLayout2->setObjectName(QStringLiteral("vboxLayout2")); hboxLayout = new QHBoxLayout(); #ifndef Q_OS_MAC hboxLayout->setSpacing(6); @@ -157,9 +157,9 @@ public: #ifndef Q_OS_MAC hboxLayout->setContentsMargins(0, 0, 0, 0); #endif - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); phrasebookList = new QListView(groupBox_2); - phrasebookList->setObjectName(QString::fromUtf8("phrasebookList")); + phrasebookList->setObjectName(QStringLiteral("phrasebookList")); phrasebookList->setUniformItemSizes(true); hboxLayout->addWidget(phrasebookList); @@ -169,14 +169,14 @@ public: vboxLayout3->setSpacing(6); #endif vboxLayout3->setContentsMargins(0, 0, 0, 0); - vboxLayout3->setObjectName(QString::fromUtf8("vboxLayout3")); + vboxLayout3->setObjectName(QStringLiteral("vboxLayout3")); moveUpButton = new QPushButton(groupBox_2); - moveUpButton->setObjectName(QString::fromUtf8("moveUpButton")); + moveUpButton->setObjectName(QStringLiteral("moveUpButton")); vboxLayout3->addWidget(moveUpButton); moveDownButton = new QPushButton(groupBox_2); - moveDownButton->setObjectName(QString::fromUtf8("moveDownButton")); + moveDownButton->setObjectName(QStringLiteral("moveDownButton")); vboxLayout3->addWidget(moveDownButton); @@ -191,7 +191,7 @@ public: vboxLayout2->addLayout(hboxLayout); label = new QLabel(groupBox_2); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); label->setWordWrap(true); vboxLayout2->addWidget(label); @@ -204,18 +204,18 @@ public: hboxLayout1->setSpacing(6); #endif hboxLayout1->setContentsMargins(0, 0, 0, 0); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); spacerItem1 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); hboxLayout1->addItem(spacerItem1); runButton = new QPushButton(databaseTranslationDialog); - runButton->setObjectName(QString::fromUtf8("runButton")); + runButton->setObjectName(QStringLiteral("runButton")); hboxLayout1->addWidget(runButton); cancelButton = new QPushButton(databaseTranslationDialog); - cancelButton->setObjectName(QString::fromUtf8("cancelButton")); + cancelButton->setObjectName(QStringLiteral("cancelButton")); hboxLayout1->addWidget(cancelButton); diff --git a/tests/auto/tools/uic/baseline/bookmarkdialog.ui.h b/tests/auto/tools/uic/baseline/bookmarkdialog.ui.h index a178497e262..33c0d19ee2f 100644 --- a/tests/auto/tools/uic/baseline/bookmarkdialog.ui.h +++ b/tests/auto/tools/uic/baseline/bookmarkdialog.ui.h @@ -51,7 +51,7 @@ public: void setupUi(QDialog *BookmarkDialog) { if (BookmarkDialog->objectName().isEmpty()) - BookmarkDialog->setObjectName(QString::fromUtf8("BookmarkDialog")); + BookmarkDialog->setObjectName(QStringLiteral("BookmarkDialog")); BookmarkDialog->resize(450, 135); QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); sizePolicy.setHorizontalStretch(0); @@ -59,18 +59,18 @@ public: sizePolicy.setHeightForWidth(BookmarkDialog->sizePolicy().hasHeightForWidth()); BookmarkDialog->setSizePolicy(sizePolicy); verticalLayout_3 = new QVBoxLayout(BookmarkDialog); - verticalLayout_3->setObjectName(QString::fromUtf8("verticalLayout_3")); + verticalLayout_3->setObjectName(QStringLiteral("verticalLayout_3")); horizontalLayout = new QHBoxLayout(); - horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); verticalLayout_2 = new QVBoxLayout(); - verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2")); + verticalLayout_2->setObjectName(QStringLiteral("verticalLayout_2")); label = new QLabel(BookmarkDialog); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); verticalLayout_2->addWidget(label); label_2 = new QLabel(BookmarkDialog); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); verticalLayout_2->addWidget(label_2); @@ -78,14 +78,14 @@ public: horizontalLayout->addLayout(verticalLayout_2); verticalLayout = new QVBoxLayout(); - verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); bookmarkEdit = new QLineEdit(BookmarkDialog); - bookmarkEdit->setObjectName(QString::fromUtf8("bookmarkEdit")); + bookmarkEdit->setObjectName(QStringLiteral("bookmarkEdit")); verticalLayout->addWidget(bookmarkEdit); bookmarkFolders = new QComboBox(BookmarkDialog); - bookmarkFolders->setObjectName(QString::fromUtf8("bookmarkFolders")); + bookmarkFolders->setObjectName(QStringLiteral("bookmarkFolders")); verticalLayout->addWidget(bookmarkFolders); @@ -96,15 +96,15 @@ public: verticalLayout_3->addLayout(horizontalLayout); horizontalLayout_3 = new QHBoxLayout(); - horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3")); + horizontalLayout_3->setObjectName(QStringLiteral("horizontalLayout_3")); toolButton = new QToolButton(BookmarkDialog); - toolButton->setObjectName(QString::fromUtf8("toolButton")); + toolButton->setObjectName(QStringLiteral("toolButton")); toolButton->setMinimumSize(QSize(25, 20)); horizontalLayout_3->addWidget(toolButton); line = new QFrame(BookmarkDialog); - line->setObjectName(QString::fromUtf8("line")); + line->setObjectName(QStringLiteral("line")); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); @@ -114,7 +114,7 @@ public: verticalLayout_3->addLayout(horizontalLayout_3); bookmarkWidget = new BookmarkWidget(BookmarkDialog); - bookmarkWidget->setObjectName(QString::fromUtf8("bookmarkWidget")); + bookmarkWidget->setObjectName(QStringLiteral("bookmarkWidget")); bookmarkWidget->setEnabled(true); QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Ignored); sizePolicy1.setHorizontalStretch(0); @@ -125,14 +125,14 @@ public: verticalLayout_3->addWidget(bookmarkWidget); horizontalLayout_4 = new QHBoxLayout(); - horizontalLayout_4->setObjectName(QString::fromUtf8("horizontalLayout_4")); + horizontalLayout_4->setObjectName(QStringLiteral("horizontalLayout_4")); newFolderButton = new QPushButton(BookmarkDialog); - newFolderButton->setObjectName(QString::fromUtf8("newFolderButton")); + newFolderButton->setObjectName(QStringLiteral("newFolderButton")); horizontalLayout_4->addWidget(newFolderButton); buttonBox = new QDialogButtonBox(BookmarkDialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/bookwindow.ui.h b/tests/auto/tools/uic/baseline/bookwindow.ui.h index 0463aeb8c9e..d27717296c1 100644 --- a/tests/auto/tools/uic/baseline/bookwindow.ui.h +++ b/tests/auto/tools/uic/baseline/bookwindow.ui.h @@ -52,10 +52,10 @@ public: void setupUi(QMainWindow *BookWindow) { if (BookWindow->objectName().isEmpty()) - BookWindow->setObjectName(QString::fromUtf8("BookWindow")); + BookWindow->setObjectName(QStringLiteral("BookWindow")); BookWindow->resize(601, 420); centralWidget = new QWidget(BookWindow); - centralWidget->setObjectName(QString::fromUtf8("centralWidget")); + centralWidget->setObjectName(QStringLiteral("centralWidget")); vboxLayout = new QVBoxLayout(centralWidget); #ifndef Q_OS_MAC vboxLayout->setSpacing(6); @@ -63,9 +63,9 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); groupBox = new QGroupBox(centralWidget); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); vboxLayout1 = new QVBoxLayout(groupBox); #ifndef Q_OS_MAC vboxLayout1->setSpacing(6); @@ -73,57 +73,57 @@ public: #ifndef Q_OS_MAC vboxLayout1->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); bookTable = new QTableView(groupBox); - bookTable->setObjectName(QString::fromUtf8("bookTable")); + bookTable->setObjectName(QStringLiteral("bookTable")); bookTable->setSelectionBehavior(QAbstractItemView::SelectRows); vboxLayout1->addWidget(bookTable); groupBox_2 = new QGroupBox(groupBox); - groupBox_2->setObjectName(QString::fromUtf8("groupBox_2")); + groupBox_2->setObjectName(QStringLiteral("groupBox_2")); formLayout = new QFormLayout(groupBox_2); - formLayout->setObjectName(QString::fromUtf8("formLayout")); + formLayout->setObjectName(QStringLiteral("formLayout")); label_5 = new QLabel(groupBox_2); - label_5->setObjectName(QString::fromUtf8("label_5")); + label_5->setObjectName(QStringLiteral("label_5")); formLayout->setWidget(0, QFormLayout::LabelRole, label_5); titleEdit = new QLineEdit(groupBox_2); - titleEdit->setObjectName(QString::fromUtf8("titleEdit")); + titleEdit->setObjectName(QStringLiteral("titleEdit")); titleEdit->setEnabled(true); formLayout->setWidget(0, QFormLayout::FieldRole, titleEdit); label_2_2_2_2 = new QLabel(groupBox_2); - label_2_2_2_2->setObjectName(QString::fromUtf8("label_2_2_2_2")); + label_2_2_2_2->setObjectName(QStringLiteral("label_2_2_2_2")); formLayout->setWidget(1, QFormLayout::LabelRole, label_2_2_2_2); authorEdit = new QComboBox(groupBox_2); - authorEdit->setObjectName(QString::fromUtf8("authorEdit")); + authorEdit->setObjectName(QStringLiteral("authorEdit")); authorEdit->setEnabled(true); formLayout->setWidget(1, QFormLayout::FieldRole, authorEdit); label_3 = new QLabel(groupBox_2); - label_3->setObjectName(QString::fromUtf8("label_3")); + label_3->setObjectName(QStringLiteral("label_3")); formLayout->setWidget(2, QFormLayout::LabelRole, label_3); genreEdit = new QComboBox(groupBox_2); - genreEdit->setObjectName(QString::fromUtf8("genreEdit")); + genreEdit->setObjectName(QStringLiteral("genreEdit")); genreEdit->setEnabled(true); formLayout->setWidget(2, QFormLayout::FieldRole, genreEdit); label_4 = new QLabel(groupBox_2); - label_4->setObjectName(QString::fromUtf8("label_4")); + label_4->setObjectName(QStringLiteral("label_4")); formLayout->setWidget(3, QFormLayout::LabelRole, label_4); yearEdit = new QSpinBox(groupBox_2); - yearEdit->setObjectName(QString::fromUtf8("yearEdit")); + yearEdit->setObjectName(QStringLiteral("yearEdit")); yearEdit->setEnabled(true); yearEdit->setMaximum(2100); yearEdit->setMinimum(-1000); @@ -131,12 +131,12 @@ public: formLayout->setWidget(3, QFormLayout::FieldRole, yearEdit); label = new QLabel(groupBox_2); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); formLayout->setWidget(4, QFormLayout::LabelRole, label); ratingEdit = new QSpinBox(groupBox_2); - ratingEdit->setObjectName(QString::fromUtf8("ratingEdit")); + ratingEdit->setObjectName(QStringLiteral("ratingEdit")); ratingEdit->setMaximum(5); formLayout->setWidget(4, QFormLayout::FieldRole, ratingEdit); diff --git a/tests/auto/tools/uic/baseline/browserwidget.ui.h b/tests/auto/tools/uic/baseline/browserwidget.ui.h index 7214898a4f6..9d7a648b213 100644 --- a/tests/auto/tools/uic/baseline/browserwidget.ui.h +++ b/tests/auto/tools/uic/baseline/browserwidget.ui.h @@ -48,22 +48,22 @@ public: void setupUi(QWidget *Browser) { if (Browser->objectName().isEmpty()) - Browser->setObjectName(QString::fromUtf8("Browser")); + Browser->setObjectName(QStringLiteral("Browser")); Browser->resize(765, 515); insertRowAction = new QAction(Browser); - insertRowAction->setObjectName(QString::fromUtf8("insertRowAction")); + insertRowAction->setObjectName(QStringLiteral("insertRowAction")); insertRowAction->setEnabled(false); deleteRowAction = new QAction(Browser); - deleteRowAction->setObjectName(QString::fromUtf8("deleteRowAction")); + deleteRowAction->setObjectName(QStringLiteral("deleteRowAction")); deleteRowAction->setEnabled(false); vboxLayout = new QVBoxLayout(Browser); #ifndef Q_OS_MAC vboxLayout->setSpacing(6); #endif vboxLayout->setContentsMargins(8, 8, 8, 8); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); splitter_2 = new QSplitter(Browser); - splitter_2->setObjectName(QString::fromUtf8("splitter_2")); + splitter_2->setObjectName(QStringLiteral("splitter_2")); QSizePolicy sizePolicy(static_cast(7), static_cast(7)); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -71,7 +71,7 @@ public: splitter_2->setSizePolicy(sizePolicy); splitter_2->setOrientation(Qt::Horizontal); connectionWidget = new ConnectionWidget(splitter_2); - connectionWidget->setObjectName(QString::fromUtf8("connectionWidget")); + connectionWidget->setObjectName(QStringLiteral("connectionWidget")); QSizePolicy sizePolicy1(static_cast(13), static_cast(7)); sizePolicy1.setHorizontalStretch(1); sizePolicy1.setVerticalStretch(0); @@ -79,7 +79,7 @@ public: connectionWidget->setSizePolicy(sizePolicy1); splitter_2->addWidget(connectionWidget); table = new QTableView(splitter_2); - table->setObjectName(QString::fromUtf8("table")); + table->setObjectName(QStringLiteral("table")); QSizePolicy sizePolicy2(static_cast(7), static_cast(7)); sizePolicy2.setHorizontalStretch(2); sizePolicy2.setVerticalStretch(0); @@ -92,7 +92,7 @@ public: vboxLayout->addWidget(splitter_2); groupBox = new QGroupBox(Browser); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); QSizePolicy sizePolicy3(static_cast(5), static_cast(3)); sizePolicy3.setHorizontalStretch(0); sizePolicy3.setVerticalStretch(0); @@ -106,9 +106,9 @@ public: #ifndef Q_OS_MAC vboxLayout1->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); sqlEdit = new QTextEdit(groupBox); - sqlEdit->setObjectName(QString::fromUtf8("sqlEdit")); + sqlEdit->setObjectName(QStringLiteral("sqlEdit")); QSizePolicy sizePolicy4(static_cast(7), static_cast(3)); sizePolicy4.setHorizontalStretch(0); sizePolicy4.setVerticalStretch(0); @@ -124,18 +124,18 @@ public: hboxLayout->setSpacing(6); #endif hboxLayout->setContentsMargins(1, 1, 1, 1); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); hboxLayout->addItem(spacerItem); clearButton = new QPushButton(groupBox); - clearButton->setObjectName(QString::fromUtf8("clearButton")); + clearButton->setObjectName(QStringLiteral("clearButton")); hboxLayout->addWidget(clearButton); submitButton = new QPushButton(groupBox); - submitButton->setObjectName(QString::fromUtf8("submitButton")); + submitButton->setObjectName(QStringLiteral("submitButton")); hboxLayout->addWidget(submitButton); diff --git a/tests/auto/tools/uic/baseline/calculator.ui.h b/tests/auto/tools/uic/baseline/calculator.ui.h index 3d69c9fdfd7..8a33fcbbd95 100644 --- a/tests/auto/tools/uic/baseline/calculator.ui.h +++ b/tests/auto/tools/uic/baseline/calculator.ui.h @@ -56,7 +56,7 @@ public: void setupUi(QWidget *Calculator) { if (Calculator->objectName().isEmpty()) - Calculator->setObjectName(QString::fromUtf8("Calculator")); + Calculator->setObjectName(QStringLiteral("Calculator")); Calculator->resize(314, 301); QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); sizePolicy.setHorizontalStretch(0); @@ -66,88 +66,88 @@ public: Calculator->setMinimumSize(QSize(314, 301)); Calculator->setMaximumSize(QSize(314, 301)); backspaceButton = new QToolButton(Calculator); - backspaceButton->setObjectName(QString::fromUtf8("backspaceButton")); + backspaceButton->setObjectName(QStringLiteral("backspaceButton")); backspaceButton->setGeometry(QRect(10, 50, 91, 41)); clearButton = new QToolButton(Calculator); - clearButton->setObjectName(QString::fromUtf8("clearButton")); + clearButton->setObjectName(QStringLiteral("clearButton")); clearButton->setGeometry(QRect(110, 50, 91, 41)); clearAllButton = new QToolButton(Calculator); - clearAllButton->setObjectName(QString::fromUtf8("clearAllButton")); + clearAllButton->setObjectName(QStringLiteral("clearAllButton")); clearAllButton->setGeometry(QRect(210, 50, 91, 41)); clearMemoryButton = new QToolButton(Calculator); - clearMemoryButton->setObjectName(QString::fromUtf8("clearMemoryButton")); + clearMemoryButton->setObjectName(QStringLiteral("clearMemoryButton")); clearMemoryButton->setGeometry(QRect(10, 100, 41, 41)); readMemoryButton = new QToolButton(Calculator); - readMemoryButton->setObjectName(QString::fromUtf8("readMemoryButton")); + readMemoryButton->setObjectName(QStringLiteral("readMemoryButton")); readMemoryButton->setGeometry(QRect(10, 150, 41, 41)); setMemoryButton = new QToolButton(Calculator); - setMemoryButton->setObjectName(QString::fromUtf8("setMemoryButton")); + setMemoryButton->setObjectName(QStringLiteral("setMemoryButton")); setMemoryButton->setGeometry(QRect(10, 200, 41, 41)); addToMemoryButton = new QToolButton(Calculator); - addToMemoryButton->setObjectName(QString::fromUtf8("addToMemoryButton")); + addToMemoryButton->setObjectName(QStringLiteral("addToMemoryButton")); addToMemoryButton->setGeometry(QRect(10, 250, 41, 41)); sevenButton = new QToolButton(Calculator); - sevenButton->setObjectName(QString::fromUtf8("sevenButton")); + sevenButton->setObjectName(QStringLiteral("sevenButton")); sevenButton->setGeometry(QRect(60, 100, 41, 41)); eightButton = new QToolButton(Calculator); - eightButton->setObjectName(QString::fromUtf8("eightButton")); + eightButton->setObjectName(QStringLiteral("eightButton")); eightButton->setGeometry(QRect(110, 100, 41, 41)); nineButton = new QToolButton(Calculator); - nineButton->setObjectName(QString::fromUtf8("nineButton")); + nineButton->setObjectName(QStringLiteral("nineButton")); nineButton->setGeometry(QRect(160, 100, 41, 41)); fourButton = new QToolButton(Calculator); - fourButton->setObjectName(QString::fromUtf8("fourButton")); + fourButton->setObjectName(QStringLiteral("fourButton")); fourButton->setGeometry(QRect(60, 150, 41, 41)); fiveButton = new QToolButton(Calculator); - fiveButton->setObjectName(QString::fromUtf8("fiveButton")); + fiveButton->setObjectName(QStringLiteral("fiveButton")); fiveButton->setGeometry(QRect(110, 150, 41, 41)); sixButton = new QToolButton(Calculator); - sixButton->setObjectName(QString::fromUtf8("sixButton")); + sixButton->setObjectName(QStringLiteral("sixButton")); sixButton->setGeometry(QRect(160, 150, 41, 41)); oneButton = new QToolButton(Calculator); - oneButton->setObjectName(QString::fromUtf8("oneButton")); + oneButton->setObjectName(QStringLiteral("oneButton")); oneButton->setGeometry(QRect(60, 200, 41, 41)); twoButton = new QToolButton(Calculator); - twoButton->setObjectName(QString::fromUtf8("twoButton")); + twoButton->setObjectName(QStringLiteral("twoButton")); twoButton->setGeometry(QRect(110, 200, 41, 41)); threeButton = new QToolButton(Calculator); - threeButton->setObjectName(QString::fromUtf8("threeButton")); + threeButton->setObjectName(QStringLiteral("threeButton")); threeButton->setGeometry(QRect(160, 200, 41, 41)); zeroButton = new QToolButton(Calculator); - zeroButton->setObjectName(QString::fromUtf8("zeroButton")); + zeroButton->setObjectName(QStringLiteral("zeroButton")); zeroButton->setGeometry(QRect(60, 250, 41, 41)); pointButton = new QToolButton(Calculator); - pointButton->setObjectName(QString::fromUtf8("pointButton")); + pointButton->setObjectName(QStringLiteral("pointButton")); pointButton->setGeometry(QRect(110, 250, 41, 41)); changeSignButton = new QToolButton(Calculator); - changeSignButton->setObjectName(QString::fromUtf8("changeSignButton")); + changeSignButton->setObjectName(QStringLiteral("changeSignButton")); changeSignButton->setGeometry(QRect(160, 250, 41, 41)); plusButton = new QToolButton(Calculator); - plusButton->setObjectName(QString::fromUtf8("plusButton")); + plusButton->setObjectName(QStringLiteral("plusButton")); plusButton->setGeometry(QRect(210, 250, 41, 41)); divisionButton = new QToolButton(Calculator); - divisionButton->setObjectName(QString::fromUtf8("divisionButton")); + divisionButton->setObjectName(QStringLiteral("divisionButton")); divisionButton->setGeometry(QRect(210, 100, 41, 41)); timesButton = new QToolButton(Calculator); - timesButton->setObjectName(QString::fromUtf8("timesButton")); + timesButton->setObjectName(QStringLiteral("timesButton")); timesButton->setGeometry(QRect(210, 150, 41, 41)); minusButton = new QToolButton(Calculator); - minusButton->setObjectName(QString::fromUtf8("minusButton")); + minusButton->setObjectName(QStringLiteral("minusButton")); minusButton->setGeometry(QRect(210, 200, 41, 41)); squareRootButton = new QToolButton(Calculator); - squareRootButton->setObjectName(QString::fromUtf8("squareRootButton")); + squareRootButton->setObjectName(QStringLiteral("squareRootButton")); squareRootButton->setGeometry(QRect(260, 100, 41, 41)); powerButton = new QToolButton(Calculator); - powerButton->setObjectName(QString::fromUtf8("powerButton")); + powerButton->setObjectName(QStringLiteral("powerButton")); powerButton->setGeometry(QRect(260, 150, 41, 41)); reciprocalButton = new QToolButton(Calculator); - reciprocalButton->setObjectName(QString::fromUtf8("reciprocalButton")); + reciprocalButton->setObjectName(QStringLiteral("reciprocalButton")); reciprocalButton->setGeometry(QRect(260, 200, 41, 41)); equalButton = new QToolButton(Calculator); - equalButton->setObjectName(QString::fromUtf8("equalButton")); + equalButton->setObjectName(QStringLiteral("equalButton")); equalButton->setGeometry(QRect(260, 250, 41, 41)); display = new QLineEdit(Calculator); - display->setObjectName(QString::fromUtf8("display")); + display->setObjectName(QStringLiteral("display")); display->setGeometry(QRect(10, 10, 291, 31)); display->setMaxLength(15); display->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); diff --git a/tests/auto/tools/uic/baseline/calculatorform.ui.h b/tests/auto/tools/uic/baseline/calculatorform.ui.h index b38a9404489..cbc62367e03 100644 --- a/tests/auto/tools/uic/baseline/calculatorform.ui.h +++ b/tests/auto/tools/uic/baseline/calculatorform.ui.h @@ -47,7 +47,7 @@ public: void setupUi(QWidget *CalculatorForm) { if (CalculatorForm->objectName().isEmpty()) - CalculatorForm->setObjectName(QString::fromUtf8("CalculatorForm")); + CalculatorForm->setObjectName(QStringLiteral("CalculatorForm")); CalculatorForm->resize(276, 98); QSizePolicy sizePolicy(static_cast(5), static_cast(5)); sizePolicy.setHorizontalStretch(0); @@ -61,30 +61,30 @@ public: #ifndef Q_OS_MAC gridLayout->setContentsMargins(9, 9, 9, 9); #endif - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); - gridLayout->setObjectName(QString::fromUtf8("")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); + gridLayout->setObjectName(QStringLiteral("")); hboxLayout = new QHBoxLayout(); #ifndef Q_OS_MAC hboxLayout->setSpacing(6); #endif hboxLayout->setContentsMargins(1, 1, 1, 1); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); - hboxLayout->setObjectName(QString::fromUtf8("")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("")); vboxLayout = new QVBoxLayout(); #ifndef Q_OS_MAC vboxLayout->setSpacing(6); #endif vboxLayout->setContentsMargins(1, 1, 1, 1); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); - vboxLayout->setObjectName(QString::fromUtf8("")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("")); label = new QLabel(CalculatorForm); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); label->setGeometry(QRect(1, 1, 45, 19)); vboxLayout->addWidget(label); inputSpinBox1 = new QSpinBox(CalculatorForm); - inputSpinBox1->setObjectName(QString::fromUtf8("inputSpinBox1")); + inputSpinBox1->setObjectName(QStringLiteral("inputSpinBox1")); inputSpinBox1->setGeometry(QRect(1, 26, 45, 25)); inputSpinBox1->setMouseTracking(true); @@ -94,7 +94,7 @@ public: hboxLayout->addLayout(vboxLayout); label_3 = new QLabel(CalculatorForm); - label_3->setObjectName(QString::fromUtf8("label_3")); + label_3->setObjectName(QStringLiteral("label_3")); label_3->setGeometry(QRect(54, 1, 7, 52)); label_3->setAlignment(Qt::AlignCenter); @@ -105,16 +105,16 @@ public: vboxLayout1->setSpacing(6); #endif vboxLayout1->setContentsMargins(1, 1, 1, 1); - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); - vboxLayout1->setObjectName(QString::fromUtf8("")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("")); label_2 = new QLabel(CalculatorForm); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); label_2->setGeometry(QRect(1, 1, 45, 19)); vboxLayout1->addWidget(label_2); inputSpinBox2 = new QSpinBox(CalculatorForm); - inputSpinBox2->setObjectName(QString::fromUtf8("inputSpinBox2")); + inputSpinBox2->setObjectName(QStringLiteral("inputSpinBox2")); inputSpinBox2->setGeometry(QRect(1, 26, 45, 25)); inputSpinBox2->setMouseTracking(true); @@ -124,7 +124,7 @@ public: hboxLayout->addLayout(vboxLayout1); label_3_2 = new QLabel(CalculatorForm); - label_3_2->setObjectName(QString::fromUtf8("label_3_2")); + label_3_2->setObjectName(QStringLiteral("label_3_2")); label_3_2->setGeometry(QRect(120, 1, 7, 52)); label_3_2->setAlignment(Qt::AlignCenter); @@ -135,16 +135,16 @@ public: vboxLayout2->setSpacing(6); #endif vboxLayout2->setContentsMargins(1, 1, 1, 1); - vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2")); - vboxLayout2->setObjectName(QString::fromUtf8("")); + vboxLayout2->setObjectName(QStringLiteral("vboxLayout2")); + vboxLayout2->setObjectName(QStringLiteral("")); label_2_2_2 = new QLabel(CalculatorForm); - label_2_2_2->setObjectName(QString::fromUtf8("label_2_2_2")); + label_2_2_2->setObjectName(QStringLiteral("label_2_2_2")); label_2_2_2->setGeometry(QRect(1, 1, 37, 17)); vboxLayout2->addWidget(label_2_2_2); outputWidget = new QLabel(CalculatorForm); - outputWidget->setObjectName(QString::fromUtf8("outputWidget")); + outputWidget->setObjectName(QStringLiteral("outputWidget")); outputWidget->setGeometry(QRect(1, 24, 37, 27)); outputWidget->setFrameShape(QFrame::Box); outputWidget->setFrameShadow(QFrame::Sunken); diff --git a/tests/auto/tools/uic/baseline/certificateinfo.ui.h b/tests/auto/tools/uic/baseline/certificateinfo.ui.h index e047aeddc04..8ea1ebebf75 100644 --- a/tests/auto/tools/uic/baseline/certificateinfo.ui.h +++ b/tests/auto/tools/uic/baseline/certificateinfo.ui.h @@ -42,16 +42,16 @@ public: void setupUi(QDialog *CertificateInfo) { if (CertificateInfo->objectName().isEmpty()) - CertificateInfo->setObjectName(QString::fromUtf8("CertificateInfo")); + CertificateInfo->setObjectName(QStringLiteral("CertificateInfo")); CertificateInfo->resize(400, 397); vboxLayout = new QVBoxLayout(CertificateInfo); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); groupBox = new QGroupBox(CertificateInfo); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); hboxLayout = new QHBoxLayout(groupBox); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); certificationPathView = new QListWidget(groupBox); - certificationPathView->setObjectName(QString::fromUtf8("certificationPathView")); + certificationPathView->setObjectName(QStringLiteral("certificationPathView")); hboxLayout->addWidget(certificationPathView); @@ -59,11 +59,11 @@ public: vboxLayout->addWidget(groupBox); groupBox_2 = new QGroupBox(CertificateInfo); - groupBox_2->setObjectName(QString::fromUtf8("groupBox_2")); + groupBox_2->setObjectName(QStringLiteral("groupBox_2")); hboxLayout1 = new QHBoxLayout(groupBox_2); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); certificateInfoView = new QListWidget(groupBox_2); - certificateInfoView->setObjectName(QString::fromUtf8("certificateInfoView")); + certificateInfoView->setObjectName(QStringLiteral("certificateInfoView")); hboxLayout1->addWidget(certificateInfoView); @@ -71,13 +71,13 @@ public: vboxLayout->addWidget(groupBox_2); hboxLayout2 = new QHBoxLayout(); - hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2")); + hboxLayout2->setObjectName(QStringLiteral("hboxLayout2")); spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); hboxLayout2->addItem(spacerItem); buttonBox = new QDialogButtonBox(CertificateInfo); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setStandardButtons(QDialogButtonBox::Close); hboxLayout2->addWidget(buttonBox); diff --git a/tests/auto/tools/uic/baseline/chatdialog.ui.h b/tests/auto/tools/uic/baseline/chatdialog.ui.h index 216e627e76c..473d20de705 100644 --- a/tests/auto/tools/uic/baseline/chatdialog.ui.h +++ b/tests/auto/tools/uic/baseline/chatdialog.ui.h @@ -39,7 +39,7 @@ public: void setupUi(QDialog *ChatDialog) { if (ChatDialog->objectName().isEmpty()) - ChatDialog->setObjectName(QString::fromUtf8("ChatDialog")); + ChatDialog->setObjectName(QStringLiteral("ChatDialog")); ChatDialog->resize(513, 349); vboxLayout = new QVBoxLayout(ChatDialog); #ifndef Q_OS_MAC @@ -48,7 +48,7 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); hboxLayout = new QHBoxLayout(); #ifndef Q_OS_MAC hboxLayout->setSpacing(6); @@ -56,16 +56,16 @@ public: #ifndef Q_OS_MAC hboxLayout->setContentsMargins(0, 0, 0, 0); #endif - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); textEdit = new QTextEdit(ChatDialog); - textEdit->setObjectName(QString::fromUtf8("textEdit")); + textEdit->setObjectName(QStringLiteral("textEdit")); textEdit->setFocusPolicy(Qt::NoFocus); textEdit->setReadOnly(true); hboxLayout->addWidget(textEdit); listWidget = new QListWidget(ChatDialog); - listWidget->setObjectName(QString::fromUtf8("listWidget")); + listWidget->setObjectName(QStringLiteral("listWidget")); listWidget->setMaximumSize(QSize(180, 16777215)); listWidget->setFocusPolicy(Qt::NoFocus); @@ -79,14 +79,14 @@ public: hboxLayout1->setSpacing(6); #endif hboxLayout1->setContentsMargins(0, 0, 0, 0); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); label = new QLabel(ChatDialog); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); hboxLayout1->addWidget(label); lineEdit = new QLineEdit(ChatDialog); - lineEdit->setObjectName(QString::fromUtf8("lineEdit")); + lineEdit->setObjectName(QStringLiteral("lineEdit")); hboxLayout1->addWidget(lineEdit); diff --git a/tests/auto/tools/uic/baseline/chatmainwindow.ui.h b/tests/auto/tools/uic/baseline/chatmainwindow.ui.h index 1001e859313..c077dd75011 100644 --- a/tests/auto/tools/uic/baseline/chatmainwindow.ui.h +++ b/tests/auto/tools/uic/baseline/chatmainwindow.ui.h @@ -51,16 +51,16 @@ public: void setupUi(QMainWindow *ChatMainWindow) { if (ChatMainWindow->objectName().isEmpty()) - ChatMainWindow->setObjectName(QString::fromUtf8("ChatMainWindow")); + ChatMainWindow->setObjectName(QStringLiteral("ChatMainWindow")); ChatMainWindow->resize(800, 600); actionQuit = new QAction(ChatMainWindow); - actionQuit->setObjectName(QString::fromUtf8("actionQuit")); + actionQuit->setObjectName(QStringLiteral("actionQuit")); actionAboutQt = new QAction(ChatMainWindow); - actionAboutQt->setObjectName(QString::fromUtf8("actionAboutQt")); + actionAboutQt->setObjectName(QStringLiteral("actionAboutQt")); actionChangeNickname = new QAction(ChatMainWindow); - actionChangeNickname->setObjectName(QString::fromUtf8("actionChangeNickname")); + actionChangeNickname->setObjectName(QStringLiteral("actionChangeNickname")); centralwidget = new QWidget(ChatMainWindow); - centralwidget->setObjectName(QString::fromUtf8("centralwidget")); + centralwidget->setObjectName(QStringLiteral("centralwidget")); hboxLayout = new QHBoxLayout(centralwidget); #ifndef Q_OS_MAC hboxLayout->setSpacing(6); @@ -68,7 +68,7 @@ public: #ifndef Q_OS_MAC hboxLayout->setContentsMargins(9, 9, 9, 9); #endif - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); vboxLayout = new QVBoxLayout(); #ifndef Q_OS_MAC vboxLayout->setSpacing(6); @@ -76,9 +76,9 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(0, 0, 0, 0); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); chatHistory = new QTextBrowser(centralwidget); - chatHistory->setObjectName(QString::fromUtf8("chatHistory")); + chatHistory->setObjectName(QStringLiteral("chatHistory")); chatHistory->setAcceptDrops(false); chatHistory->setAcceptRichText(true); @@ -89,19 +89,19 @@ public: hboxLayout1->setSpacing(6); #endif hboxLayout1->setContentsMargins(0, 0, 0, 0); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); label = new QLabel(centralwidget); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); hboxLayout1->addWidget(label); messageLineEdit = new QLineEdit(centralwidget); - messageLineEdit->setObjectName(QString::fromUtf8("messageLineEdit")); + messageLineEdit->setObjectName(QStringLiteral("messageLineEdit")); hboxLayout1->addWidget(messageLineEdit); sendButton = new QPushButton(centralwidget); - sendButton->setObjectName(QString::fromUtf8("sendButton")); + sendButton->setObjectName(QStringLiteral("sendButton")); QSizePolicy sizePolicy(static_cast(1), static_cast(0)); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -118,15 +118,15 @@ public: ChatMainWindow->setCentralWidget(centralwidget); menubar = new QMenuBar(ChatMainWindow); - menubar->setObjectName(QString::fromUtf8("menubar")); + menubar->setObjectName(QStringLiteral("menubar")); menubar->setGeometry(QRect(0, 0, 800, 31)); menuQuit = new QMenu(menubar); - menuQuit->setObjectName(QString::fromUtf8("menuQuit")); + menuQuit->setObjectName(QStringLiteral("menuQuit")); menuFile = new QMenu(menubar); - menuFile->setObjectName(QString::fromUtf8("menuFile")); + menuFile->setObjectName(QStringLiteral("menuFile")); ChatMainWindow->setMenuBar(menubar); statusbar = new QStatusBar(ChatMainWindow); - statusbar->setObjectName(QString::fromUtf8("statusbar")); + statusbar->setObjectName(QStringLiteral("statusbar")); ChatMainWindow->setStatusBar(statusbar); #ifndef QT_NO_SHORTCUT label->setBuddy(messageLineEdit); diff --git a/tests/auto/tools/uic/baseline/chatsetnickname.ui.h b/tests/auto/tools/uic/baseline/chatsetnickname.ui.h index ee69d36476f..e0de690715c 100644 --- a/tests/auto/tools/uic/baseline/chatsetnickname.ui.h +++ b/tests/auto/tools/uic/baseline/chatsetnickname.ui.h @@ -41,7 +41,7 @@ public: void setupUi(QDialog *NicknameDialog) { if (NicknameDialog->objectName().isEmpty()) - NicknameDialog->setObjectName(QString::fromUtf8("NicknameDialog")); + NicknameDialog->setObjectName(QStringLiteral("NicknameDialog")); NicknameDialog->resize(396, 105); QSizePolicy sizePolicy(static_cast(1), static_cast(1)); sizePolicy.setHorizontalStretch(0); @@ -55,7 +55,7 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); vboxLayout1 = new QVBoxLayout(); #ifndef Q_OS_MAC vboxLayout1->setSpacing(6); @@ -63,16 +63,16 @@ public: #ifndef Q_OS_MAC vboxLayout1->setContentsMargins(0, 0, 0, 0); #endif - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); label = new QLabel(NicknameDialog); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); sizePolicy.setHeightForWidth(label->sizePolicy().hasHeightForWidth()); label->setSizePolicy(sizePolicy); vboxLayout1->addWidget(label); nickname = new QLineEdit(NicknameDialog); - nickname->setObjectName(QString::fromUtf8("nickname")); + nickname->setObjectName(QStringLiteral("nickname")); vboxLayout1->addWidget(nickname); @@ -84,18 +84,18 @@ public: hboxLayout->setSpacing(6); #endif hboxLayout->setContentsMargins(0, 0, 0, 0); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); spacerItem = new QSpacerItem(131, 31, QSizePolicy::Expanding, QSizePolicy::Minimum); hboxLayout->addItem(spacerItem); okButton = new QPushButton(NicknameDialog); - okButton->setObjectName(QString::fromUtf8("okButton")); + okButton->setObjectName(QStringLiteral("okButton")); hboxLayout->addWidget(okButton); cancelButton = new QPushButton(NicknameDialog); - cancelButton->setObjectName(QString::fromUtf8("cancelButton")); + cancelButton->setObjectName(QStringLiteral("cancelButton")); hboxLayout->addWidget(cancelButton); diff --git a/tests/auto/tools/uic/baseline/config.ui.h b/tests/auto/tools/uic/baseline/config.ui.h index 5606978f099..cf21fd8c6fb 100644 --- a/tests/auto/tools/uic/baseline/config.ui.h +++ b/tests/auto/tools/uic/baseline/config.ui.h @@ -135,20 +135,20 @@ public: void setupUi(QDialog *Config) { if (Config->objectName().isEmpty()) - Config->setObjectName(QString::fromUtf8("Config")); + Config->setObjectName(QStringLiteral("Config")); Config->resize(600, 650); Config->setSizeGripEnabled(true); vboxLayout = new QVBoxLayout(Config); vboxLayout->setSpacing(6); vboxLayout->setContentsMargins(11, 11, 11, 11); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); vboxLayout->setContentsMargins(8, 8, 8, 8); hboxLayout = new QHBoxLayout(); hboxLayout->setSpacing(6); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); hboxLayout->setContentsMargins(0, 0, 0, 0); ButtonGroup1 = new QGroupBox(Config); - ButtonGroup1->setObjectName(QString::fromUtf8("ButtonGroup1")); + ButtonGroup1->setObjectName(QStringLiteral("ButtonGroup1")); QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -157,44 +157,44 @@ public: vboxLayout1 = new QVBoxLayout(ButtonGroup1); vboxLayout1->setSpacing(6); vboxLayout1->setContentsMargins(11, 11, 11, 11); - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); vboxLayout1->setContentsMargins(11, 11, 11, 11); size_176_220 = new QRadioButton(ButtonGroup1); - size_176_220->setObjectName(QString::fromUtf8("size_176_220")); + size_176_220->setObjectName(QStringLiteral("size_176_220")); vboxLayout1->addWidget(size_176_220); size_240_320 = new QRadioButton(ButtonGroup1); - size_240_320->setObjectName(QString::fromUtf8("size_240_320")); + size_240_320->setObjectName(QStringLiteral("size_240_320")); vboxLayout1->addWidget(size_240_320); size_320_240 = new QRadioButton(ButtonGroup1); - size_320_240->setObjectName(QString::fromUtf8("size_320_240")); + size_320_240->setObjectName(QStringLiteral("size_320_240")); vboxLayout1->addWidget(size_320_240); size_640_480 = new QRadioButton(ButtonGroup1); - size_640_480->setObjectName(QString::fromUtf8("size_640_480")); + size_640_480->setObjectName(QStringLiteral("size_640_480")); vboxLayout1->addWidget(size_640_480); size_800_600 = new QRadioButton(ButtonGroup1); - size_800_600->setObjectName(QString::fromUtf8("size_800_600")); + size_800_600->setObjectName(QStringLiteral("size_800_600")); vboxLayout1->addWidget(size_800_600); size_1024_768 = new QRadioButton(ButtonGroup1); - size_1024_768->setObjectName(QString::fromUtf8("size_1024_768")); + size_1024_768->setObjectName(QStringLiteral("size_1024_768")); vboxLayout1->addWidget(size_1024_768); hboxLayout1 = new QHBoxLayout(); hboxLayout1->setSpacing(6); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); hboxLayout1->setContentsMargins(0, 0, 0, 0); size_custom = new QRadioButton(ButtonGroup1); - size_custom->setObjectName(QString::fromUtf8("size_custom")); + size_custom->setObjectName(QStringLiteral("size_custom")); QSizePolicy sizePolicy1(QSizePolicy::Fixed, QSizePolicy::Fixed); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); @@ -204,7 +204,7 @@ public: hboxLayout1->addWidget(size_custom); size_width = new QSpinBox(ButtonGroup1); - size_width->setObjectName(QString::fromUtf8("size_width")); + size_width->setObjectName(QStringLiteral("size_width")); size_width->setMinimum(1); size_width->setMaximum(1280); size_width->setSingleStep(16); @@ -213,7 +213,7 @@ public: hboxLayout1->addWidget(size_width); size_height = new QSpinBox(ButtonGroup1); - size_height->setObjectName(QString::fromUtf8("size_height")); + size_height->setObjectName(QStringLiteral("size_height")); size_height->setMinimum(1); size_height->setMaximum(1024); size_height->setSingleStep(16); @@ -228,59 +228,59 @@ public: hboxLayout->addWidget(ButtonGroup1); ButtonGroup2 = new QGroupBox(Config); - ButtonGroup2->setObjectName(QString::fromUtf8("ButtonGroup2")); + ButtonGroup2->setObjectName(QStringLiteral("ButtonGroup2")); vboxLayout2 = new QVBoxLayout(ButtonGroup2); vboxLayout2->setSpacing(6); vboxLayout2->setContentsMargins(11, 11, 11, 11); - vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2")); + vboxLayout2->setObjectName(QStringLiteral("vboxLayout2")); vboxLayout2->setContentsMargins(11, 11, 11, 11); depth_1 = new QRadioButton(ButtonGroup2); - depth_1->setObjectName(QString::fromUtf8("depth_1")); + depth_1->setObjectName(QStringLiteral("depth_1")); vboxLayout2->addWidget(depth_1); depth_4gray = new QRadioButton(ButtonGroup2); - depth_4gray->setObjectName(QString::fromUtf8("depth_4gray")); + depth_4gray->setObjectName(QStringLiteral("depth_4gray")); vboxLayout2->addWidget(depth_4gray); depth_8 = new QRadioButton(ButtonGroup2); - depth_8->setObjectName(QString::fromUtf8("depth_8")); + depth_8->setObjectName(QStringLiteral("depth_8")); vboxLayout2->addWidget(depth_8); depth_12 = new QRadioButton(ButtonGroup2); - depth_12->setObjectName(QString::fromUtf8("depth_12")); + depth_12->setObjectName(QStringLiteral("depth_12")); vboxLayout2->addWidget(depth_12); depth_15 = new QRadioButton(ButtonGroup2); - depth_15->setObjectName(QString::fromUtf8("depth_15")); + depth_15->setObjectName(QStringLiteral("depth_15")); vboxLayout2->addWidget(depth_15); depth_16 = new QRadioButton(ButtonGroup2); - depth_16->setObjectName(QString::fromUtf8("depth_16")); + depth_16->setObjectName(QStringLiteral("depth_16")); vboxLayout2->addWidget(depth_16); depth_18 = new QRadioButton(ButtonGroup2); - depth_18->setObjectName(QString::fromUtf8("depth_18")); + depth_18->setObjectName(QStringLiteral("depth_18")); vboxLayout2->addWidget(depth_18); depth_24 = new QRadioButton(ButtonGroup2); - depth_24->setObjectName(QString::fromUtf8("depth_24")); + depth_24->setObjectName(QStringLiteral("depth_24")); vboxLayout2->addWidget(depth_24); depth_32 = new QRadioButton(ButtonGroup2); - depth_32->setObjectName(QString::fromUtf8("depth_32")); + depth_32->setObjectName(QStringLiteral("depth_32")); vboxLayout2->addWidget(depth_32); depth_32_argb = new QRadioButton(ButtonGroup2); - depth_32_argb->setObjectName(QString::fromUtf8("depth_32_argb")); + depth_32_argb->setObjectName(QStringLiteral("depth_32_argb")); vboxLayout2->addWidget(depth_32_argb); @@ -292,15 +292,15 @@ public: hboxLayout2 = new QHBoxLayout(); hboxLayout2->setSpacing(6); - hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2")); + hboxLayout2->setObjectName(QStringLiteral("hboxLayout2")); hboxLayout2->setContentsMargins(0, 0, 0, 0); TextLabel1_3 = new QLabel(Config); - TextLabel1_3->setObjectName(QString::fromUtf8("TextLabel1_3")); + TextLabel1_3->setObjectName(QStringLiteral("TextLabel1_3")); hboxLayout2->addWidget(TextLabel1_3); skin = new QComboBox(Config); - skin->setObjectName(QString::fromUtf8("skin")); + skin->setObjectName(QStringLiteral("skin")); QSizePolicy sizePolicy2(QSizePolicy::Expanding, QSizePolicy::Fixed); sizePolicy2.setHorizontalStretch(0); sizePolicy2.setVerticalStretch(0); @@ -313,12 +313,12 @@ public: vboxLayout->addLayout(hboxLayout2); touchScreen = new QCheckBox(Config); - touchScreen->setObjectName(QString::fromUtf8("touchScreen")); + touchScreen->setObjectName(QStringLiteral("touchScreen")); vboxLayout->addWidget(touchScreen); lcdScreen = new QCheckBox(Config); - lcdScreen->setObjectName(QString::fromUtf8("lcdScreen")); + lcdScreen->setObjectName(QStringLiteral("lcdScreen")); vboxLayout->addWidget(lcdScreen); @@ -327,7 +327,7 @@ public: vboxLayout->addItem(spacerItem); TextLabel1 = new QLabel(Config); - TextLabel1->setObjectName(QString::fromUtf8("TextLabel1")); + TextLabel1->setObjectName(QStringLiteral("TextLabel1")); sizePolicy.setHeightForWidth(TextLabel1->sizePolicy().hasHeightForWidth()); TextLabel1->setSizePolicy(sizePolicy); TextLabel1->setWordWrap(true); @@ -335,21 +335,21 @@ public: vboxLayout->addWidget(TextLabel1); GroupBox1 = new QGroupBox(Config); - GroupBox1->setObjectName(QString::fromUtf8("GroupBox1")); + GroupBox1->setObjectName(QStringLiteral("GroupBox1")); gridLayout = new QGridLayout(GroupBox1); gridLayout->setSpacing(6); gridLayout->setContentsMargins(11, 11, 11, 11); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); gridLayout->setHorizontalSpacing(6); gridLayout->setVerticalSpacing(6); gridLayout->setContentsMargins(11, 11, 11, 11); TextLabel3 = new QLabel(GroupBox1); - TextLabel3->setObjectName(QString::fromUtf8("TextLabel3")); + TextLabel3->setObjectName(QStringLiteral("TextLabel3")); gridLayout->addWidget(TextLabel3, 6, 0, 1, 1); bslider = new QSlider(GroupBox1); - bslider->setObjectName(QString::fromUtf8("bslider")); + bslider->setObjectName(QStringLiteral("bslider")); QPalette palette; QBrush brush(QColor(128, 128, 128, 255)); brush.setStyle(Qt::SolidPattern); @@ -432,17 +432,17 @@ public: gridLayout->addWidget(bslider, 6, 1, 1, 1); blabel = new QLabel(GroupBox1); - blabel->setObjectName(QString::fromUtf8("blabel")); + blabel->setObjectName(QStringLiteral("blabel")); gridLayout->addWidget(blabel, 6, 2, 1, 1); TextLabel2 = new QLabel(GroupBox1); - TextLabel2->setObjectName(QString::fromUtf8("TextLabel2")); + TextLabel2->setObjectName(QStringLiteral("TextLabel2")); gridLayout->addWidget(TextLabel2, 4, 0, 1, 1); gslider = new QSlider(GroupBox1); - gslider->setObjectName(QString::fromUtf8("gslider")); + gslider->setObjectName(QStringLiteral("gslider")); QPalette palette1; palette1.setBrush(QPalette::Active, QPalette::WindowText, brush); QBrush brush11(QColor(0, 255, 0, 255)); @@ -513,22 +513,22 @@ public: gridLayout->addWidget(gslider, 4, 1, 1, 1); glabel = new QLabel(GroupBox1); - glabel->setObjectName(QString::fromUtf8("glabel")); + glabel->setObjectName(QStringLiteral("glabel")); gridLayout->addWidget(glabel, 4, 2, 1, 1); TextLabel7 = new QLabel(GroupBox1); - TextLabel7->setObjectName(QString::fromUtf8("TextLabel7")); + TextLabel7->setObjectName(QStringLiteral("TextLabel7")); gridLayout->addWidget(TextLabel7, 0, 0, 1, 1); TextLabel8 = new QLabel(GroupBox1); - TextLabel8->setObjectName(QString::fromUtf8("TextLabel8")); + TextLabel8->setObjectName(QStringLiteral("TextLabel8")); gridLayout->addWidget(TextLabel8, 0, 2, 1, 1); gammaslider = new QSlider(GroupBox1); - gammaslider->setObjectName(QString::fromUtf8("gammaslider")); + gammaslider->setObjectName(QStringLiteral("gammaslider")); QPalette palette2; palette2.setBrush(QPalette::Active, QPalette::WindowText, brush); palette2.setBrush(QPalette::Active, QPalette::Button, brush7); @@ -593,17 +593,17 @@ public: gridLayout->addWidget(gammaslider, 0, 1, 1, 1); TextLabel1_2 = new QLabel(GroupBox1); - TextLabel1_2->setObjectName(QString::fromUtf8("TextLabel1_2")); + TextLabel1_2->setObjectName(QStringLiteral("TextLabel1_2")); gridLayout->addWidget(TextLabel1_2, 2, 0, 1, 1); rlabel = new QLabel(GroupBox1); - rlabel->setObjectName(QString::fromUtf8("rlabel")); + rlabel->setObjectName(QStringLiteral("rlabel")); gridLayout->addWidget(rlabel, 2, 2, 1, 1); rslider = new QSlider(GroupBox1); - rslider->setObjectName(QString::fromUtf8("rslider")); + rslider->setObjectName(QStringLiteral("rslider")); QPalette palette3; palette3.setBrush(QPalette::Active, QPalette::WindowText, brush); QBrush brush18(QColor(255, 0, 0, 255)); @@ -674,12 +674,12 @@ public: gridLayout->addWidget(rslider, 2, 1, 1, 1); PushButton3 = new QPushButton(GroupBox1); - PushButton3->setObjectName(QString::fromUtf8("PushButton3")); + PushButton3->setObjectName(QStringLiteral("PushButton3")); gridLayout->addWidget(PushButton3, 8, 0, 1, 3); MyCustomWidget1 = new GammaView(GroupBox1); - MyCustomWidget1->setObjectName(QString::fromUtf8("MyCustomWidget1")); + MyCustomWidget1->setObjectName(QStringLiteral("MyCustomWidget1")); gridLayout->addWidget(MyCustomWidget1, 0, 3, 9, 1); @@ -688,21 +688,21 @@ public: hboxLayout3 = new QHBoxLayout(); hboxLayout3->setSpacing(6); - hboxLayout3->setObjectName(QString::fromUtf8("hboxLayout3")); + hboxLayout3->setObjectName(QStringLiteral("hboxLayout3")); hboxLayout3->setContentsMargins(0, 0, 0, 0); spacerItem1 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); hboxLayout3->addItem(spacerItem1); buttonOk = new QPushButton(Config); - buttonOk->setObjectName(QString::fromUtf8("buttonOk")); + buttonOk->setObjectName(QStringLiteral("buttonOk")); buttonOk->setAutoDefault(true); buttonOk->setDefault(true); hboxLayout3->addWidget(buttonOk); buttonCancel = new QPushButton(Config); - buttonCancel->setObjectName(QString::fromUtf8("buttonCancel")); + buttonCancel->setObjectName(QStringLiteral("buttonCancel")); buttonCancel->setAutoDefault(true); hboxLayout3->addWidget(buttonCancel); diff --git a/tests/auto/tools/uic/baseline/connectdialog.ui.h b/tests/auto/tools/uic/baseline/connectdialog.ui.h index 71ed1bb87f7..9c46bb851d0 100644 --- a/tests/auto/tools/uic/baseline/connectdialog.ui.h +++ b/tests/auto/tools/uic/baseline/connectdialog.ui.h @@ -50,24 +50,24 @@ public: void setupUi(QDialog *ConnectDialog) { if (ConnectDialog->objectName().isEmpty()) - ConnectDialog->setObjectName(QString::fromUtf8("ConnectDialog")); + ConnectDialog->setObjectName(QStringLiteral("ConnectDialog")); ConnectDialog->resize(585, 361); gridLayout = new QGridLayout(ConnectDialog); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); signalGroupBox = new QGroupBox(ConnectDialog); - signalGroupBox->setObjectName(QString::fromUtf8("signalGroupBox")); + signalGroupBox->setObjectName(QStringLiteral("signalGroupBox")); vboxLayout = new QVBoxLayout(signalGroupBox); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); signalList = new QListWidget(signalGroupBox); - signalList->setObjectName(QString::fromUtf8("signalList")); + signalList->setObjectName(QStringLiteral("signalList")); signalList->setTextElideMode(Qt::ElideMiddle); vboxLayout->addWidget(signalList); hboxLayout = new QHBoxLayout(); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); editSignalsButton = new QToolButton(signalGroupBox); - editSignalsButton->setObjectName(QString::fromUtf8("editSignalsButton")); + editSignalsButton->setObjectName(QStringLiteral("editSignalsButton")); hboxLayout->addWidget(editSignalsButton); @@ -82,19 +82,19 @@ public: gridLayout->addWidget(signalGroupBox, 0, 0, 1, 2); slotGroupBox = new QGroupBox(ConnectDialog); - slotGroupBox->setObjectName(QString::fromUtf8("slotGroupBox")); + slotGroupBox->setObjectName(QStringLiteral("slotGroupBox")); vboxLayout1 = new QVBoxLayout(slotGroupBox); - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); slotList = new QListWidget(slotGroupBox); - slotList->setObjectName(QString::fromUtf8("slotList")); + slotList->setObjectName(QStringLiteral("slotList")); slotList->setTextElideMode(Qt::ElideMiddle); vboxLayout1->addWidget(slotList); hboxLayout1 = new QHBoxLayout(); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); editSlotsButton = new QToolButton(slotGroupBox); - editSlotsButton->setObjectName(QString::fromUtf8("editSlotsButton")); + editSlotsButton->setObjectName(QStringLiteral("editSlotsButton")); hboxLayout1->addWidget(editSlotsButton); @@ -109,12 +109,12 @@ public: gridLayout->addWidget(slotGroupBox, 0, 2, 1, 1); showAllCheckBox = new QCheckBox(ConnectDialog); - showAllCheckBox->setObjectName(QString::fromUtf8("showAllCheckBox")); + showAllCheckBox->setObjectName(QStringLiteral("showAllCheckBox")); gridLayout->addWidget(showAllCheckBox, 1, 0, 1, 1); buttonBox = new QDialogButtonBox(ConnectDialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/controller.ui.h b/tests/auto/tools/uic/baseline/controller.ui.h index 1c79f03f566..2758f1a7de6 100644 --- a/tests/auto/tools/uic/baseline/controller.ui.h +++ b/tests/auto/tools/uic/baseline/controller.ui.h @@ -35,7 +35,7 @@ public: void setupUi(QWidget *Controller) { if (Controller->objectName().isEmpty()) - Controller->setObjectName(QString::fromUtf8("Controller")); + Controller->setObjectName(QStringLiteral("Controller")); Controller->resize(255, 111); gridLayout = new QGridLayout(Controller); #ifndef Q_OS_MAC @@ -44,30 +44,30 @@ public: #ifndef Q_OS_MAC gridLayout->setContentsMargins(9, 9, 9, 9); #endif - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); label = new QLabel(Controller); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); label->setAlignment(Qt::AlignCenter); gridLayout->addWidget(label, 1, 1, 1, 1); decelerate = new QPushButton(Controller); - decelerate->setObjectName(QString::fromUtf8("decelerate")); + decelerate->setObjectName(QStringLiteral("decelerate")); gridLayout->addWidget(decelerate, 2, 1, 1, 1); accelerate = new QPushButton(Controller); - accelerate->setObjectName(QString::fromUtf8("accelerate")); + accelerate->setObjectName(QStringLiteral("accelerate")); gridLayout->addWidget(accelerate, 0, 1, 1, 1); right = new QPushButton(Controller); - right->setObjectName(QString::fromUtf8("right")); + right->setObjectName(QStringLiteral("right")); gridLayout->addWidget(right, 1, 2, 1, 1); left = new QPushButton(Controller); - left->setObjectName(QString::fromUtf8("left")); + left->setObjectName(QStringLiteral("left")); gridLayout->addWidget(left, 1, 0, 1, 1); diff --git a/tests/auto/tools/uic/baseline/cookies.ui.h b/tests/auto/tools/uic/baseline/cookies.ui.h index f866645dd80..201687c210b 100644 --- a/tests/auto/tools/uic/baseline/cookies.ui.h +++ b/tests/auto/tools/uic/baseline/cookies.ui.h @@ -42,33 +42,33 @@ public: void setupUi(QDialog *CookiesDialog) { if (CookiesDialog->objectName().isEmpty()) - CookiesDialog->setObjectName(QString::fromUtf8("CookiesDialog")); + CookiesDialog->setObjectName(QStringLiteral("CookiesDialog")); CookiesDialog->resize(550, 370); gridLayout = new QGridLayout(CookiesDialog); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); spacerItem = new QSpacerItem(252, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); gridLayout->addItem(spacerItem, 0, 0, 1, 1); search = new SearchLineEdit(CookiesDialog); - search->setObjectName(QString::fromUtf8("search")); + search->setObjectName(QStringLiteral("search")); gridLayout->addWidget(search, 0, 1, 1, 1); cookiesTable = new EditTableView(CookiesDialog); - cookiesTable->setObjectName(QString::fromUtf8("cookiesTable")); + cookiesTable->setObjectName(QStringLiteral("cookiesTable")); gridLayout->addWidget(cookiesTable, 1, 0, 1, 2); hboxLayout = new QHBoxLayout(); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); removeButton = new QPushButton(CookiesDialog); - removeButton->setObjectName(QString::fromUtf8("removeButton")); + removeButton->setObjectName(QStringLiteral("removeButton")); hboxLayout->addWidget(removeButton); removeAllButton = new QPushButton(CookiesDialog); - removeAllButton->setObjectName(QString::fromUtf8("removeAllButton")); + removeAllButton->setObjectName(QStringLiteral("removeAllButton")); hboxLayout->addWidget(removeAllButton); @@ -77,7 +77,7 @@ public: hboxLayout->addItem(spacerItem1); buttonBox = new QDialogButtonBox(CookiesDialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setStandardButtons(QDialogButtonBox::Ok); hboxLayout->addWidget(buttonBox); diff --git a/tests/auto/tools/uic/baseline/cookiesexceptions.ui.h b/tests/auto/tools/uic/baseline/cookiesexceptions.ui.h index 776afc51c87..ca4ac682ce9 100644 --- a/tests/auto/tools/uic/baseline/cookiesexceptions.ui.h +++ b/tests/auto/tools/uic/baseline/cookiesexceptions.ui.h @@ -57,23 +57,23 @@ public: void setupUi(QDialog *CookiesExceptionsDialog) { if (CookiesExceptionsDialog->objectName().isEmpty()) - CookiesExceptionsDialog->setObjectName(QString::fromUtf8("CookiesExceptionsDialog")); + CookiesExceptionsDialog->setObjectName(QStringLiteral("CookiesExceptionsDialog")); CookiesExceptionsDialog->resize(466, 446); vboxLayout = new QVBoxLayout(CookiesExceptionsDialog); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); newExceptionGroupBox = new QGroupBox(CookiesExceptionsDialog); - newExceptionGroupBox->setObjectName(QString::fromUtf8("newExceptionGroupBox")); + newExceptionGroupBox->setObjectName(QStringLiteral("newExceptionGroupBox")); gridLayout = new QGridLayout(newExceptionGroupBox); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); hboxLayout = new QHBoxLayout(); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); label = new QLabel(newExceptionGroupBox); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); hboxLayout->addWidget(label); domainLineEdit = new QLineEdit(newExceptionGroupBox); - domainLineEdit->setObjectName(QString::fromUtf8("domainLineEdit")); + domainLineEdit->setObjectName(QStringLiteral("domainLineEdit")); hboxLayout->addWidget(domainLineEdit); @@ -81,25 +81,25 @@ public: gridLayout->addLayout(hboxLayout, 0, 0, 1, 1); hboxLayout1 = new QHBoxLayout(); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); spacerItem = new QSpacerItem(81, 25, QSizePolicy::Expanding, QSizePolicy::Minimum); hboxLayout1->addItem(spacerItem); blockButton = new QPushButton(newExceptionGroupBox); - blockButton->setObjectName(QString::fromUtf8("blockButton")); + blockButton->setObjectName(QStringLiteral("blockButton")); blockButton->setEnabled(false); hboxLayout1->addWidget(blockButton); allowForSessionButton = new QPushButton(newExceptionGroupBox); - allowForSessionButton->setObjectName(QString::fromUtf8("allowForSessionButton")); + allowForSessionButton->setObjectName(QStringLiteral("allowForSessionButton")); allowForSessionButton->setEnabled(false); hboxLayout1->addWidget(allowForSessionButton); allowButton = new QPushButton(newExceptionGroupBox); - allowButton->setObjectName(QString::fromUtf8("allowButton")); + allowButton->setObjectName(QStringLiteral("allowButton")); allowButton->setEnabled(false); hboxLayout1->addWidget(allowButton); @@ -111,30 +111,30 @@ public: vboxLayout->addWidget(newExceptionGroupBox); ExceptionsGroupBox = new QGroupBox(CookiesExceptionsDialog); - ExceptionsGroupBox->setObjectName(QString::fromUtf8("ExceptionsGroupBox")); + ExceptionsGroupBox->setObjectName(QStringLiteral("ExceptionsGroupBox")); gridLayout1 = new QGridLayout(ExceptionsGroupBox); - gridLayout1->setObjectName(QString::fromUtf8("gridLayout1")); + gridLayout1->setObjectName(QStringLiteral("gridLayout1")); spacerItem1 = new QSpacerItem(252, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); gridLayout1->addItem(spacerItem1, 0, 0, 1, 3); search = new SearchLineEdit(ExceptionsGroupBox); - search->setObjectName(QString::fromUtf8("search")); + search->setObjectName(QStringLiteral("search")); gridLayout1->addWidget(search, 0, 3, 1, 1); exceptionTable = new EditTableView(ExceptionsGroupBox); - exceptionTable->setObjectName(QString::fromUtf8("exceptionTable")); + exceptionTable->setObjectName(QStringLiteral("exceptionTable")); gridLayout1->addWidget(exceptionTable, 1, 0, 1, 4); removeButton = new QPushButton(ExceptionsGroupBox); - removeButton->setObjectName(QString::fromUtf8("removeButton")); + removeButton->setObjectName(QStringLiteral("removeButton")); gridLayout1->addWidget(removeButton, 2, 0, 1, 1); removeAllButton = new QPushButton(ExceptionsGroupBox); - removeAllButton->setObjectName(QString::fromUtf8("removeAllButton")); + removeAllButton->setObjectName(QStringLiteral("removeAllButton")); gridLayout1->addWidget(removeAllButton, 2, 1, 1, 1); @@ -146,7 +146,7 @@ public: vboxLayout->addWidget(ExceptionsGroupBox); buttonBox = new QDialogButtonBox(CookiesExceptionsDialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/default.ui.h b/tests/auto/tools/uic/baseline/default.ui.h index 685fa0b476a..0bde249375b 100644 --- a/tests/auto/tools/uic/baseline/default.ui.h +++ b/tests/auto/tools/uic/baseline/default.ui.h @@ -66,18 +66,18 @@ public: void setupUi(QMainWindow *MainWindow) { if (MainWindow->objectName().isEmpty()) - MainWindow->setObjectName(QString::fromUtf8("MainWindow")); + MainWindow->setObjectName(QStringLiteral("MainWindow")); MainWindow->resize(388, 413); exitAction = new QAction(MainWindow); - exitAction->setObjectName(QString::fromUtf8("exitAction")); + exitAction->setObjectName(QStringLiteral("exitAction")); aboutQtAction = new QAction(MainWindow); - aboutQtAction->setObjectName(QString::fromUtf8("aboutQtAction")); + aboutQtAction->setObjectName(QStringLiteral("aboutQtAction")); editStyleAction = new QAction(MainWindow); - editStyleAction->setObjectName(QString::fromUtf8("editStyleAction")); + editStyleAction->setObjectName(QStringLiteral("editStyleAction")); aboutAction = new QAction(MainWindow); - aboutAction->setObjectName(QString::fromUtf8("aboutAction")); + aboutAction->setObjectName(QStringLiteral("aboutAction")); centralwidget = new QWidget(MainWindow); - centralwidget->setObjectName(QString::fromUtf8("centralwidget")); + centralwidget->setObjectName(QStringLiteral("centralwidget")); gridLayout = new QGridLayout(centralwidget); #ifndef Q_OS_MAC gridLayout->setSpacing(6); @@ -85,14 +85,14 @@ public: #ifndef Q_OS_MAC gridLayout->setContentsMargins(9, 9, 9, 9); #endif - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); nameLabel = new QLabel(centralwidget); - nameLabel->setObjectName(QString::fromUtf8("nameLabel")); + nameLabel->setObjectName(QStringLiteral("nameLabel")); gridLayout->addWidget(nameLabel, 0, 0, 1, 1); nameCombo = new QComboBox(centralwidget); - nameCombo->setObjectName(QString::fromUtf8("nameCombo")); + nameCombo->setObjectName(QStringLiteral("nameCombo")); nameCombo->setEditable(true); gridLayout->addWidget(nameCombo, 0, 1, 1, 3); @@ -102,62 +102,62 @@ public: gridLayout->addItem(spacerItem, 1, 3, 1, 1); femaleRadioButton = new QRadioButton(centralwidget); - femaleRadioButton->setObjectName(QString::fromUtf8("femaleRadioButton")); + femaleRadioButton->setObjectName(QStringLiteral("femaleRadioButton")); gridLayout->addWidget(femaleRadioButton, 1, 2, 1, 1); agreeCheckBox = new QCheckBox(centralwidget); - agreeCheckBox->setObjectName(QString::fromUtf8("agreeCheckBox")); + agreeCheckBox->setObjectName(QStringLiteral("agreeCheckBox")); gridLayout->addWidget(agreeCheckBox, 6, 0, 1, 4); maleRadioButton = new QRadioButton(centralwidget); - maleRadioButton->setObjectName(QString::fromUtf8("maleRadioButton")); + maleRadioButton->setObjectName(QStringLiteral("maleRadioButton")); gridLayout->addWidget(maleRadioButton, 1, 1, 1, 1); genderLabel = new QLabel(centralwidget); - genderLabel->setObjectName(QString::fromUtf8("genderLabel")); + genderLabel->setObjectName(QStringLiteral("genderLabel")); gridLayout->addWidget(genderLabel, 1, 0, 1, 1); ageSpinBox = new QSpinBox(centralwidget); - ageSpinBox->setObjectName(QString::fromUtf8("ageSpinBox")); + ageSpinBox->setObjectName(QStringLiteral("ageSpinBox")); ageSpinBox->setMinimum(12); ageSpinBox->setValue(22); gridLayout->addWidget(ageSpinBox, 2, 1, 1, 3); buttonBox = new QDialogButtonBox(centralwidget); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok); gridLayout->addWidget(buttonBox, 7, 2, 1, 2); ageLabel = new QLabel(centralwidget); - ageLabel->setObjectName(QString::fromUtf8("ageLabel")); + ageLabel->setObjectName(QStringLiteral("ageLabel")); gridLayout->addWidget(ageLabel, 2, 0, 1, 1); passwordLabel = new QLabel(centralwidget); - passwordLabel->setObjectName(QString::fromUtf8("passwordLabel")); + passwordLabel->setObjectName(QStringLiteral("passwordLabel")); gridLayout->addWidget(passwordLabel, 3, 0, 1, 1); passwordEdit = new QLineEdit(centralwidget); - passwordEdit->setObjectName(QString::fromUtf8("passwordEdit")); + passwordEdit->setObjectName(QStringLiteral("passwordEdit")); passwordEdit->setEchoMode(QLineEdit::Password); gridLayout->addWidget(passwordEdit, 3, 1, 1, 3); label = new QLabel(centralwidget); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 5, 0, 1, 1); countryLabel = new QLabel(centralwidget); - countryLabel->setObjectName(QString::fromUtf8("countryLabel")); + countryLabel->setObjectName(QStringLiteral("countryLabel")); gridLayout->addWidget(countryLabel, 4, 0, 1, 1); @@ -165,26 +165,26 @@ public: new QListWidgetItem(professionList); new QListWidgetItem(professionList); new QListWidgetItem(professionList); - professionList->setObjectName(QString::fromUtf8("professionList")); + professionList->setObjectName(QStringLiteral("professionList")); gridLayout->addWidget(professionList, 5, 1, 1, 3); countryCombo = new QComboBox(centralwidget); - countryCombo->setObjectName(QString::fromUtf8("countryCombo")); + countryCombo->setObjectName(QStringLiteral("countryCombo")); gridLayout->addWidget(countryCombo, 4, 1, 1, 3); MainWindow->setCentralWidget(centralwidget); menubar = new QMenuBar(MainWindow); - menubar->setObjectName(QString::fromUtf8("menubar")); + menubar->setObjectName(QStringLiteral("menubar")); menubar->setGeometry(QRect(0, 0, 388, 21)); menu_File = new QMenu(menubar); - menu_File->setObjectName(QString::fromUtf8("menu_File")); + menu_File->setObjectName(QStringLiteral("menu_File")); menu_Help = new QMenu(menubar); - menu_Help->setObjectName(QString::fromUtf8("menu_Help")); + menu_Help->setObjectName(QStringLiteral("menu_Help")); MainWindow->setMenuBar(menubar); statusbar = new QStatusBar(MainWindow); - statusbar->setObjectName(QString::fromUtf8("statusbar")); + statusbar->setObjectName(QStringLiteral("statusbar")); MainWindow->setStatusBar(statusbar); #ifndef QT_NO_SHORTCUT nameLabel->setBuddy(nameCombo); diff --git a/tests/auto/tools/uic/baseline/dialog.ui.h b/tests/auto/tools/uic/baseline/dialog.ui.h index d4860bf071b..6e3e3fdc363 100644 --- a/tests/auto/tools/uic/baseline/dialog.ui.h +++ b/tests/auto/tools/uic/baseline/dialog.ui.h @@ -33,24 +33,24 @@ public: void setupUi(QDialog *Dialog) { if (Dialog->objectName().isEmpty()) - Dialog->setObjectName(QString::fromUtf8("Dialog")); + Dialog->setObjectName(QStringLiteral("Dialog")); Dialog->resize(451, 322); gridLayout = new QGridLayout(Dialog); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); loadFromFileButton = new QPushButton(Dialog); - loadFromFileButton->setObjectName(QString::fromUtf8("loadFromFileButton")); + loadFromFileButton->setObjectName(QStringLiteral("loadFromFileButton")); gridLayout->addWidget(loadFromFileButton, 0, 0, 1, 1); label = new QLabel(Dialog); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); label->setAlignment(Qt::AlignCenter); label->setWordWrap(true); gridLayout->addWidget(label, 1, 0, 1, 1); loadFromSharedMemoryButton = new QPushButton(Dialog); - loadFromSharedMemoryButton->setObjectName(QString::fromUtf8("loadFromSharedMemoryButton")); + loadFromSharedMemoryButton->setObjectName(QStringLiteral("loadFromSharedMemoryButton")); gridLayout->addWidget(loadFromSharedMemoryButton, 2, 0, 1, 1); diff --git a/tests/auto/tools/uic/baseline/downloaditem.ui.h b/tests/auto/tools/uic/baseline/downloaditem.ui.h index 33442342b51..9aac86eb87e 100644 --- a/tests/auto/tools/uic/baseline/downloaditem.ui.h +++ b/tests/auto/tools/uic/baseline/downloaditem.ui.h @@ -45,13 +45,13 @@ public: void setupUi(QWidget *DownloadItem) { if (DownloadItem->objectName().isEmpty()) - DownloadItem->setObjectName(QString::fromUtf8("DownloadItem")); + DownloadItem->setObjectName(QStringLiteral("DownloadItem")); DownloadItem->resize(423, 110); horizontalLayout = new QHBoxLayout(DownloadItem); horizontalLayout->setContentsMargins(0, 0, 0, 0); - horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); fileIcon = new QLabel(DownloadItem); - fileIcon->setObjectName(QString::fromUtf8("fileIcon")); + fileIcon->setObjectName(QStringLiteral("fileIcon")); QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -61,9 +61,9 @@ public: horizontalLayout->addWidget(fileIcon); verticalLayout_2 = new QVBoxLayout(); - verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2")); + verticalLayout_2->setObjectName(QStringLiteral("verticalLayout_2")); fileNameLabel = new SqueezeLabel(DownloadItem); - fileNameLabel->setObjectName(QString::fromUtf8("fileNameLabel")); + fileNameLabel->setObjectName(QStringLiteral("fileNameLabel")); QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Preferred); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); @@ -73,13 +73,13 @@ public: verticalLayout_2->addWidget(fileNameLabel); progressBar = new QProgressBar(DownloadItem); - progressBar->setObjectName(QString::fromUtf8("progressBar")); + progressBar->setObjectName(QStringLiteral("progressBar")); progressBar->setValue(0); verticalLayout_2->addWidget(progressBar); downloadInfoLabel = new SqueezeLabel(DownloadItem); - downloadInfoLabel->setObjectName(QString::fromUtf8("downloadInfoLabel")); + downloadInfoLabel->setObjectName(QStringLiteral("downloadInfoLabel")); QSizePolicy sizePolicy2(QSizePolicy::Minimum, QSizePolicy::Preferred); sizePolicy2.setHorizontalStretch(0); sizePolicy2.setVerticalStretch(0); @@ -92,24 +92,24 @@ public: horizontalLayout->addLayout(verticalLayout_2); verticalLayout = new QVBoxLayout(); - verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); verticalSpacer = new QSpacerItem(17, 1, QSizePolicy::Minimum, QSizePolicy::Expanding); verticalLayout->addItem(verticalSpacer); tryAgainButton = new QPushButton(DownloadItem); - tryAgainButton->setObjectName(QString::fromUtf8("tryAgainButton")); + tryAgainButton->setObjectName(QStringLiteral("tryAgainButton")); tryAgainButton->setEnabled(false); verticalLayout->addWidget(tryAgainButton); stopButton = new QPushButton(DownloadItem); - stopButton->setObjectName(QString::fromUtf8("stopButton")); + stopButton->setObjectName(QStringLiteral("stopButton")); verticalLayout->addWidget(stopButton); openButton = new QPushButton(DownloadItem); - openButton->setObjectName(QString::fromUtf8("openButton")); + openButton->setObjectName(QStringLiteral("openButton")); verticalLayout->addWidget(openButton); diff --git a/tests/auto/tools/uic/baseline/downloads.ui.h b/tests/auto/tools/uic/baseline/downloads.ui.h index 32b534393a6..f88b6d75e77 100644 --- a/tests/auto/tools/uic/baseline/downloads.ui.h +++ b/tests/auto/tools/uic/baseline/downloads.ui.h @@ -39,21 +39,21 @@ public: void setupUi(QDialog *DownloadDialog) { if (DownloadDialog->objectName().isEmpty()) - DownloadDialog->setObjectName(QString::fromUtf8("DownloadDialog")); + DownloadDialog->setObjectName(QStringLiteral("DownloadDialog")); DownloadDialog->resize(332, 252); gridLayout = new QGridLayout(DownloadDialog); gridLayout->setSpacing(0); gridLayout->setContentsMargins(0, 0, 0, 0); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); downloadsView = new EditTableView(DownloadDialog); - downloadsView->setObjectName(QString::fromUtf8("downloadsView")); + downloadsView->setObjectName(QStringLiteral("downloadsView")); gridLayout->addWidget(downloadsView, 0, 0, 1, 3); horizontalLayout = new QHBoxLayout(); - horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); cleanupButton = new QPushButton(DownloadDialog); - cleanupButton->setObjectName(QString::fromUtf8("cleanupButton")); + cleanupButton->setObjectName(QStringLiteral("cleanupButton")); cleanupButton->setEnabled(false); horizontalLayout->addWidget(cleanupButton); @@ -66,7 +66,7 @@ public: gridLayout->addLayout(horizontalLayout, 1, 0, 1, 1); itemCount = new QLabel(DownloadDialog); - itemCount->setObjectName(QString::fromUtf8("itemCount")); + itemCount->setObjectName(QStringLiteral("itemCount")); gridLayout->addWidget(itemCount, 1, 1, 1, 1); diff --git a/tests/auto/tools/uic/baseline/embeddeddialog.ui.h b/tests/auto/tools/uic/baseline/embeddeddialog.ui.h index 3728e764a37..40634692fa9 100644 --- a/tests/auto/tools/uic/baseline/embeddeddialog.ui.h +++ b/tests/auto/tools/uic/baseline/embeddeddialog.ui.h @@ -40,47 +40,47 @@ public: void setupUi(QDialog *embeddedDialog) { if (embeddedDialog->objectName().isEmpty()) - embeddedDialog->setObjectName(QString::fromUtf8("embeddedDialog")); + embeddedDialog->setObjectName(QStringLiteral("embeddedDialog")); embeddedDialog->resize(407, 134); formLayout = new QFormLayout(embeddedDialog); - formLayout->setObjectName(QString::fromUtf8("formLayout")); + formLayout->setObjectName(QStringLiteral("formLayout")); label = new QLabel(embeddedDialog); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); formLayout->setWidget(0, QFormLayout::LabelRole, label); layoutDirection = new QComboBox(embeddedDialog); - layoutDirection->setObjectName(QString::fromUtf8("layoutDirection")); + layoutDirection->setObjectName(QStringLiteral("layoutDirection")); formLayout->setWidget(0, QFormLayout::FieldRole, layoutDirection); label_2 = new QLabel(embeddedDialog); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); formLayout->setWidget(1, QFormLayout::LabelRole, label_2); fontComboBox = new QFontComboBox(embeddedDialog); - fontComboBox->setObjectName(QString::fromUtf8("fontComboBox")); + fontComboBox->setObjectName(QStringLiteral("fontComboBox")); formLayout->setWidget(1, QFormLayout::FieldRole, fontComboBox); label_3 = new QLabel(embeddedDialog); - label_3->setObjectName(QString::fromUtf8("label_3")); + label_3->setObjectName(QStringLiteral("label_3")); formLayout->setWidget(2, QFormLayout::LabelRole, label_3); style = new QComboBox(embeddedDialog); - style->setObjectName(QString::fromUtf8("style")); + style->setObjectName(QStringLiteral("style")); formLayout->setWidget(2, QFormLayout::FieldRole, style); label_4 = new QLabel(embeddedDialog); - label_4->setObjectName(QString::fromUtf8("label_4")); + label_4->setObjectName(QStringLiteral("label_4")); formLayout->setWidget(3, QFormLayout::LabelRole, label_4); spacing = new QSlider(embeddedDialog); - spacing->setObjectName(QString::fromUtf8("spacing")); + spacing->setObjectName(QStringLiteral("spacing")); spacing->setOrientation(Qt::Horizontal); formLayout->setWidget(3, QFormLayout::FieldRole, spacing); diff --git a/tests/auto/tools/uic/baseline/filespage.ui.h b/tests/auto/tools/uic/baseline/filespage.ui.h index f8dd925df88..430e5350c85 100644 --- a/tests/auto/tools/uic/baseline/filespage.ui.h +++ b/tests/auto/tools/uic/baseline/filespage.ui.h @@ -38,23 +38,23 @@ public: void setupUi(QWidget *FilesPage) { if (FilesPage->objectName().isEmpty()) - FilesPage->setObjectName(QString::fromUtf8("FilesPage")); + FilesPage->setObjectName(QStringLiteral("FilesPage")); FilesPage->resize(417, 242); gridLayout = new QGridLayout(FilesPage); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); fileLabel = new QLabel(FilesPage); - fileLabel->setObjectName(QString::fromUtf8("fileLabel")); + fileLabel->setObjectName(QStringLiteral("fileLabel")); fileLabel->setWordWrap(true); gridLayout->addWidget(fileLabel, 0, 0, 1, 2); fileListWidget = new QListWidget(FilesPage); - fileListWidget->setObjectName(QString::fromUtf8("fileListWidget")); + fileListWidget->setObjectName(QStringLiteral("fileListWidget")); gridLayout->addWidget(fileListWidget, 1, 0, 3, 1); removeButton = new QPushButton(FilesPage); - removeButton->setObjectName(QString::fromUtf8("removeButton")); + removeButton->setObjectName(QStringLiteral("removeButton")); QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -64,7 +64,7 @@ public: gridLayout->addWidget(removeButton, 1, 1, 1, 1); removeAllButton = new QPushButton(FilesPage); - removeAllButton->setObjectName(QString::fromUtf8("removeAllButton")); + removeAllButton->setObjectName(QStringLiteral("removeAllButton")); gridLayout->addWidget(removeAllButton, 2, 1, 1, 1); diff --git a/tests/auto/tools/uic/baseline/filternamedialog.ui.h b/tests/auto/tools/uic/baseline/filternamedialog.ui.h index 703c552b4a5..dd84725e0db 100644 --- a/tests/auto/tools/uic/baseline/filternamedialog.ui.h +++ b/tests/auto/tools/uic/baseline/filternamedialog.ui.h @@ -38,24 +38,24 @@ public: void setupUi(QDialog *FilterNameDialogClass) { if (FilterNameDialogClass->objectName().isEmpty()) - FilterNameDialogClass->setObjectName(QString::fromUtf8("FilterNameDialogClass")); + FilterNameDialogClass->setObjectName(QStringLiteral("FilterNameDialogClass")); FilterNameDialogClass->resize(312, 95); gridLayout = new QGridLayout(FilterNameDialogClass); gridLayout->setSpacing(6); gridLayout->setContentsMargins(9, 9, 9, 9); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); label = new QLabel(FilterNameDialogClass); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 0, 0, 1, 1); lineEdit = new QLineEdit(FilterNameDialogClass); - lineEdit->setObjectName(QString::fromUtf8("lineEdit")); + lineEdit->setObjectName(QStringLiteral("lineEdit")); gridLayout->addWidget(lineEdit, 0, 1, 1, 2); line = new QFrame(FilterNameDialogClass); - line->setObjectName(QString::fromUtf8("line")); + line->setObjectName(QStringLiteral("line")); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); @@ -66,7 +66,7 @@ public: gridLayout->addItem(spacerItem, 2, 0, 1, 2); buttonBox = new QDialogButtonBox(FilterNameDialogClass); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/filterpage.ui.h b/tests/auto/tools/uic/baseline/filterpage.ui.h index ab1fcf12a1f..23a9c381408 100644 --- a/tests/auto/tools/uic/baseline/filterpage.ui.h +++ b/tests/auto/tools/uic/baseline/filterpage.ui.h @@ -45,37 +45,37 @@ public: void setupUi(QWidget *FilterPage) { if (FilterPage->objectName().isEmpty()) - FilterPage->setObjectName(QString::fromUtf8("FilterPage")); + FilterPage->setObjectName(QStringLiteral("FilterPage")); FilterPage->resize(419, 243); gridLayout = new QGridLayout(FilterPage); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); label = new QLabel(FilterPage); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 1, 0, 1, 1); filterLineEdit = new QLineEdit(FilterPage); - filterLineEdit->setObjectName(QString::fromUtf8("filterLineEdit")); + filterLineEdit->setObjectName(QStringLiteral("filterLineEdit")); gridLayout->addWidget(filterLineEdit, 2, 0, 1, 1); groupBox = new QGroupBox(FilterPage); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); gridLayout1 = new QGridLayout(groupBox); - gridLayout1->setObjectName(QString::fromUtf8("gridLayout1")); + gridLayout1->setObjectName(QStringLiteral("gridLayout1")); customFilterWidget = new QTreeWidget(groupBox); - customFilterWidget->setObjectName(QString::fromUtf8("customFilterWidget")); + customFilterWidget->setObjectName(QStringLiteral("customFilterWidget")); customFilterWidget->setColumnCount(2); gridLayout1->addWidget(customFilterWidget, 0, 0, 3, 1); addButton = new QPushButton(groupBox); - addButton->setObjectName(QString::fromUtf8("addButton")); + addButton->setObjectName(QStringLiteral("addButton")); gridLayout1->addWidget(addButton, 0, 1, 1, 1); removeButton = new QPushButton(groupBox); - removeButton->setObjectName(QString::fromUtf8("removeButton")); + removeButton->setObjectName(QStringLiteral("removeButton")); gridLayout1->addWidget(removeButton, 1, 1, 1, 1); diff --git a/tests/auto/tools/uic/baseline/finddialog.ui.h b/tests/auto/tools/uic/baseline/finddialog.ui.h index 12f5514d417..fdf2cd4e1f6 100644 --- a/tests/auto/tools/uic/baseline/finddialog.ui.h +++ b/tests/auto/tools/uic/baseline/finddialog.ui.h @@ -94,7 +94,7 @@ public: void setupUi(QDialog *FindDialog) { if (FindDialog->objectName().isEmpty()) - FindDialog->setObjectName(QString::fromUtf8("FindDialog")); + FindDialog->setObjectName(QStringLiteral("FindDialog")); FindDialog->resize(414, 170); QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); sizePolicy.setHorizontalStretch(0); @@ -104,22 +104,22 @@ public: hboxLayout = new QHBoxLayout(FindDialog); hboxLayout->setSpacing(6); hboxLayout->setContentsMargins(11, 11, 11, 11); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); vboxLayout = new QVBoxLayout(); vboxLayout->setSpacing(6); vboxLayout->setContentsMargins(0, 0, 0, 0); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); hboxLayout1 = new QHBoxLayout(); hboxLayout1->setSpacing(6); hboxLayout1->setContentsMargins(0, 0, 0, 0); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); findWhat = new QLabel(FindDialog); - findWhat->setObjectName(QString::fromUtf8("findWhat")); + findWhat->setObjectName(QStringLiteral("findWhat")); hboxLayout1->addWidget(findWhat); led = new QLineEdit(FindDialog); - led->setObjectName(QString::fromUtf8("led")); + led->setObjectName(QStringLiteral("led")); hboxLayout1->addWidget(led); @@ -127,36 +127,36 @@ public: vboxLayout->addLayout(hboxLayout1); groupBox = new QGroupBox(FindDialog); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); gridLayout = new QGridLayout(groupBox); gridLayout->setSpacing(6); gridLayout->setContentsMargins(9, 9, 9, 9); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); sourceText = new QCheckBox(groupBox); - sourceText->setObjectName(QString::fromUtf8("sourceText")); + sourceText->setObjectName(QStringLiteral("sourceText")); sourceText->setChecked(true); gridLayout->addWidget(sourceText, 1, 0, 1, 1); translations = new QCheckBox(groupBox); - translations->setObjectName(QString::fromUtf8("translations")); + translations->setObjectName(QStringLiteral("translations")); translations->setChecked(true); gridLayout->addWidget(translations, 2, 0, 1, 1); matchCase = new QCheckBox(groupBox); - matchCase->setObjectName(QString::fromUtf8("matchCase")); + matchCase->setObjectName(QStringLiteral("matchCase")); gridLayout->addWidget(matchCase, 0, 1, 1, 1); comments = new QCheckBox(groupBox); - comments->setObjectName(QString::fromUtf8("comments")); + comments->setObjectName(QStringLiteral("comments")); comments->setChecked(true); gridLayout->addWidget(comments, 0, 0, 1, 1); ignoreAccelerators = new QCheckBox(groupBox); - ignoreAccelerators->setObjectName(QString::fromUtf8("ignoreAccelerators")); + ignoreAccelerators->setObjectName(QStringLiteral("ignoreAccelerators")); ignoreAccelerators->setChecked(true); gridLayout->addWidget(ignoreAccelerators, 1, 1, 1, 1); @@ -170,16 +170,16 @@ public: vboxLayout1 = new QVBoxLayout(); vboxLayout1->setSpacing(6); vboxLayout1->setContentsMargins(0, 0, 0, 0); - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); findNxt = new QPushButton(FindDialog); - findNxt->setObjectName(QString::fromUtf8("findNxt")); + findNxt->setObjectName(QStringLiteral("findNxt")); findNxt->setDefault(true); findNxt->setFlat(false); vboxLayout1->addWidget(findNxt); cancel = new QPushButton(FindDialog); - cancel->setObjectName(QString::fromUtf8("cancel")); + cancel->setObjectName(QStringLiteral("cancel")); vboxLayout1->addWidget(cancel); diff --git a/tests/auto/tools/uic/baseline/form.ui.h b/tests/auto/tools/uic/baseline/form.ui.h index 6aca98a1e9b..cbae1567e93 100644 --- a/tests/auto/tools/uic/baseline/form.ui.h +++ b/tests/auto/tools/uic/baseline/form.ui.h @@ -44,7 +44,7 @@ public: void setupUi(QWidget *WorldTimeForm) { if (WorldTimeForm->objectName().isEmpty()) - WorldTimeForm->setObjectName(QString::fromUtf8("WorldTimeForm")); + WorldTimeForm->setObjectName(QStringLiteral("WorldTimeForm")); WorldTimeForm->resize(400, 300); hboxLayout = new QHBoxLayout(WorldTimeForm); #ifndef Q_OS_MAC @@ -53,9 +53,9 @@ public: #ifndef Q_OS_MAC hboxLayout->setContentsMargins(9, 9, 9, 9); #endif - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); worldTimeClock = new WorldTimeClock(WorldTimeForm); - worldTimeClock->setObjectName(QString::fromUtf8("worldTimeClock")); + worldTimeClock->setObjectName(QStringLiteral("worldTimeClock")); hboxLayout->addWidget(worldTimeClock); @@ -64,7 +64,7 @@ public: vboxLayout->setSpacing(6); #endif vboxLayout->setContentsMargins(1, 1, 1, 1); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); spacerItem = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); vboxLayout->addItem(spacerItem); @@ -74,14 +74,14 @@ public: hboxLayout1->setSpacing(6); #endif hboxLayout1->setContentsMargins(1, 1, 1, 1); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); label = new QLabel(WorldTimeForm); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); hboxLayout1->addWidget(label); timeEdit = new QTimeEdit(WorldTimeForm); - timeEdit->setObjectName(QString::fromUtf8("timeEdit")); + timeEdit->setObjectName(QStringLiteral("timeEdit")); timeEdit->setReadOnly(true); hboxLayout1->addWidget(timeEdit); @@ -94,14 +94,14 @@ public: hboxLayout2->setSpacing(6); #endif hboxLayout2->setContentsMargins(1, 1, 1, 1); - hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2")); + hboxLayout2->setObjectName(QStringLiteral("hboxLayout2")); label_2 = new QLabel(WorldTimeForm); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); hboxLayout2->addWidget(label_2); spinBox = new QSpinBox(WorldTimeForm); - spinBox->setObjectName(QString::fromUtf8("spinBox")); + spinBox->setObjectName(QStringLiteral("spinBox")); spinBox->setMaximum(12); spinBox->setMinimum(-12); diff --git a/tests/auto/tools/uic/baseline/formwindowsettings.ui.h b/tests/auto/tools/uic/baseline/formwindowsettings.ui.h index ffc1e1ad392..75d4d437bbb 100644 --- a/tests/auto/tools/uic/baseline/formwindowsettings.ui.h +++ b/tests/auto/tools/uic/baseline/formwindowsettings.ui.h @@ -109,19 +109,19 @@ public: void setupUi(QDialog *FormWindowSettings) { if (FormWindowSettings->objectName().isEmpty()) - FormWindowSettings->setObjectName(QString::fromUtf8("FormWindowSettings")); + FormWindowSettings->setObjectName(QStringLiteral("FormWindowSettings")); FormWindowSettings->resize(433, 465); gridLayout = new QGridLayout(FormWindowSettings); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); buttonBox = new QDialogButtonBox(FormWindowSettings); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok); gridLayout->addWidget(buttonBox, 6, 0, 1, 2); line = new QFrame(FormWindowSettings); - line->setObjectName(QString::fromUtf8("line")); + line->setObjectName(QStringLiteral("line")); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); @@ -132,33 +132,33 @@ public: hboxLayout->setSpacing(6); #endif hboxLayout->setContentsMargins(0, 0, 0, 0); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); layoutDefaultGroupBox = new QGroupBox(FormWindowSettings); - layoutDefaultGroupBox->setObjectName(QString::fromUtf8("layoutDefaultGroupBox")); + layoutDefaultGroupBox->setObjectName(QStringLiteral("layoutDefaultGroupBox")); layoutDefaultGroupBox->setCheckable(true); gridLayout1 = new QGridLayout(layoutDefaultGroupBox); #ifndef Q_OS_MAC gridLayout1->setSpacing(6); #endif gridLayout1->setContentsMargins(8, 8, 8, 8); - gridLayout1->setObjectName(QString::fromUtf8("gridLayout1")); + gridLayout1->setObjectName(QStringLiteral("gridLayout1")); label_2 = new QLabel(layoutDefaultGroupBox); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); gridLayout1->addWidget(label_2, 1, 0, 1, 1); label = new QLabel(layoutDefaultGroupBox); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout1->addWidget(label, 0, 0, 1, 1); defaultSpacingSpinBox = new QSpinBox(layoutDefaultGroupBox); - defaultSpacingSpinBox->setObjectName(QString::fromUtf8("defaultSpacingSpinBox")); + defaultSpacingSpinBox->setObjectName(QStringLiteral("defaultSpacingSpinBox")); gridLayout1->addWidget(defaultSpacingSpinBox, 1, 1, 1, 1); defaultMarginSpinBox = new QSpinBox(layoutDefaultGroupBox); - defaultMarginSpinBox->setObjectName(QString::fromUtf8("defaultMarginSpinBox")); + defaultMarginSpinBox->setObjectName(QStringLiteral("defaultMarginSpinBox")); gridLayout1->addWidget(defaultMarginSpinBox, 0, 1, 1, 1); @@ -166,31 +166,31 @@ public: hboxLayout->addWidget(layoutDefaultGroupBox); layoutFunctionGroupBox = new QGroupBox(FormWindowSettings); - layoutFunctionGroupBox->setObjectName(QString::fromUtf8("layoutFunctionGroupBox")); + layoutFunctionGroupBox->setObjectName(QStringLiteral("layoutFunctionGroupBox")); layoutFunctionGroupBox->setCheckable(true); gridLayout2 = new QGridLayout(layoutFunctionGroupBox); #ifndef Q_OS_MAC gridLayout2->setSpacing(6); #endif gridLayout2->setContentsMargins(8, 8, 8, 8); - gridLayout2->setObjectName(QString::fromUtf8("gridLayout2")); + gridLayout2->setObjectName(QStringLiteral("gridLayout2")); spacingFunctionLineEdit = new QLineEdit(layoutFunctionGroupBox); - spacingFunctionLineEdit->setObjectName(QString::fromUtf8("spacingFunctionLineEdit")); + spacingFunctionLineEdit->setObjectName(QStringLiteral("spacingFunctionLineEdit")); gridLayout2->addWidget(spacingFunctionLineEdit, 1, 1, 1, 1); marginFunctionLineEdit = new QLineEdit(layoutFunctionGroupBox); - marginFunctionLineEdit->setObjectName(QString::fromUtf8("marginFunctionLineEdit")); + marginFunctionLineEdit->setObjectName(QStringLiteral("marginFunctionLineEdit")); gridLayout2->addWidget(marginFunctionLineEdit, 0, 1, 1, 1); label_3 = new QLabel(layoutFunctionGroupBox); - label_3->setObjectName(QString::fromUtf8("label_3")); + label_3->setObjectName(QStringLiteral("label_3")); gridLayout2->addWidget(label_3, 0, 0, 1, 1); label_3_2 = new QLabel(layoutFunctionGroupBox); - label_3_2->setObjectName(QString::fromUtf8("label_3_2")); + label_3_2->setObjectName(QStringLiteral("label_3_2")); gridLayout2->addWidget(label_3_2, 1, 0, 1, 1); @@ -201,15 +201,15 @@ public: gridLayout->addLayout(hboxLayout, 2, 0, 1, 2); pixmapFunctionGroupBox_2 = new QGroupBox(FormWindowSettings); - pixmapFunctionGroupBox_2->setObjectName(QString::fromUtf8("pixmapFunctionGroupBox_2")); + pixmapFunctionGroupBox_2->setObjectName(QStringLiteral("pixmapFunctionGroupBox_2")); vboxLayout = new QVBoxLayout(pixmapFunctionGroupBox_2); #ifndef Q_OS_MAC vboxLayout->setSpacing(6); #endif vboxLayout->setContentsMargins(8, 8, 8, 8); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); authorLineEdit = new QLineEdit(pixmapFunctionGroupBox_2); - authorLineEdit->setObjectName(QString::fromUtf8("authorLineEdit")); + authorLineEdit->setObjectName(QStringLiteral("authorLineEdit")); vboxLayout->addWidget(authorLineEdit); @@ -217,15 +217,15 @@ public: gridLayout->addWidget(pixmapFunctionGroupBox_2, 0, 0, 1, 2); includeHintsGroupBox = new QGroupBox(FormWindowSettings); - includeHintsGroupBox->setObjectName(QString::fromUtf8("includeHintsGroupBox")); + includeHintsGroupBox->setObjectName(QStringLiteral("includeHintsGroupBox")); vboxLayout1 = new QVBoxLayout(includeHintsGroupBox); #ifndef Q_OS_MAC vboxLayout1->setSpacing(6); #endif vboxLayout1->setContentsMargins(8, 8, 8, 8); - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); includeHintsTextEdit = new QTextEdit(includeHintsGroupBox); - includeHintsTextEdit->setObjectName(QString::fromUtf8("includeHintsTextEdit")); + includeHintsTextEdit->setObjectName(QStringLiteral("includeHintsTextEdit")); vboxLayout1->addWidget(includeHintsTextEdit); @@ -237,18 +237,18 @@ public: hboxLayout1->setSpacing(6); #endif hboxLayout1->setContentsMargins(0, 0, 0, 0); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); pixmapFunctionGroupBox = new QGroupBox(FormWindowSettings); - pixmapFunctionGroupBox->setObjectName(QString::fromUtf8("pixmapFunctionGroupBox")); + pixmapFunctionGroupBox->setObjectName(QStringLiteral("pixmapFunctionGroupBox")); pixmapFunctionGroupBox->setCheckable(true); vboxLayout2 = new QVBoxLayout(pixmapFunctionGroupBox); #ifndef Q_OS_MAC vboxLayout2->setSpacing(6); #endif vboxLayout2->setContentsMargins(8, 8, 8, 8); - vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2")); + vboxLayout2->setObjectName(QStringLiteral("vboxLayout2")); pixmapFunctionLineEdit = new QLineEdit(pixmapFunctionGroupBox); - pixmapFunctionLineEdit->setObjectName(QString::fromUtf8("pixmapFunctionLineEdit")); + pixmapFunctionLineEdit->setObjectName(QStringLiteral("pixmapFunctionLineEdit")); vboxLayout2->addWidget(pixmapFunctionLineEdit); @@ -263,7 +263,7 @@ public: gridLayout->addItem(spacerItem, 4, 1, 1, 1); gridPanel = new qdesigner_internal::GridPanel(FormWindowSettings); - gridPanel->setObjectName(QString::fromUtf8("gridPanel")); + gridPanel->setObjectName(QStringLiteral("gridPanel")); gridLayout->addWidget(gridPanel, 1, 0, 1, 2); diff --git a/tests/auto/tools/uic/baseline/generalpage.ui.h b/tests/auto/tools/uic/baseline/generalpage.ui.h index a4d72117ebc..f496cb834c2 100644 --- a/tests/auto/tools/uic/baseline/generalpage.ui.h +++ b/tests/auto/tools/uic/baseline/generalpage.ui.h @@ -37,27 +37,27 @@ public: void setupUi(QWidget *GeneralPage) { if (GeneralPage->objectName().isEmpty()) - GeneralPage->setObjectName(QString::fromUtf8("GeneralPage")); + GeneralPage->setObjectName(QStringLiteral("GeneralPage")); GeneralPage->resize(417, 243); gridLayout = new QGridLayout(GeneralPage); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); label = new QLabel(GeneralPage); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 1, 0, 1, 1); namespaceLineEdit = new QLineEdit(GeneralPage); - namespaceLineEdit->setObjectName(QString::fromUtf8("namespaceLineEdit")); + namespaceLineEdit->setObjectName(QStringLiteral("namespaceLineEdit")); gridLayout->addWidget(namespaceLineEdit, 1, 1, 1, 1); label_2 = new QLabel(GeneralPage); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); gridLayout->addWidget(label_2, 2, 0, 1, 1); folderLineEdit = new QLineEdit(GeneralPage); - folderLineEdit->setObjectName(QString::fromUtf8("folderLineEdit")); + folderLineEdit->setObjectName(QStringLiteral("folderLineEdit")); gridLayout->addWidget(folderLineEdit, 2, 1, 1, 1); diff --git a/tests/auto/tools/uic/baseline/gridalignment.ui.h b/tests/auto/tools/uic/baseline/gridalignment.ui.h index 7a3291dc8c6..8d9a5561648 100644 --- a/tests/auto/tools/uic/baseline/gridalignment.ui.h +++ b/tests/auto/tools/uic/baseline/gridalignment.ui.h @@ -33,27 +33,27 @@ public: void setupUi(QWidget *Form) { if (Form->objectName().isEmpty()) - Form->setObjectName(QString::fromUtf8("Form")); + Form->setObjectName(QStringLiteral("Form")); Form->resize(279, 163); gridLayout = new QGridLayout(Form); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); pushButton = new QPushButton(Form); - pushButton->setObjectName(QString::fromUtf8("pushButton")); + pushButton->setObjectName(QStringLiteral("pushButton")); gridLayout->addWidget(pushButton, 0, 0, 1, 1, Qt::AlignLeft); pushButton_3 = new QPushButton(Form); - pushButton_3->setObjectName(QString::fromUtf8("pushButton_3")); + pushButton_3->setObjectName(QStringLiteral("pushButton_3")); gridLayout->addWidget(pushButton_3, 0, 1, 1, 1, Qt::AlignTop); pushButton_2 = new QPushButton(Form); - pushButton_2->setObjectName(QString::fromUtf8("pushButton_2")); + pushButton_2->setObjectName(QStringLiteral("pushButton_2")); gridLayout->addWidget(pushButton_2, 1, 0, 1, 1, Qt::AlignRight); pushButton_4 = new QPushButton(Form); - pushButton_4->setObjectName(QString::fromUtf8("pushButton_4")); + pushButton_4->setObjectName(QStringLiteral("pushButton_4")); gridLayout->addWidget(pushButton_4, 1, 1, 1, 1, Qt::AlignBottom); diff --git a/tests/auto/tools/uic/baseline/gridpanel.ui.h b/tests/auto/tools/uic/baseline/gridpanel.ui.h index 21e703b95b3..abe260e601e 100644 --- a/tests/auto/tools/uic/baseline/gridpanel.ui.h +++ b/tests/auto/tools/uic/baseline/gridpanel.ui.h @@ -50,17 +50,17 @@ public: void setupUi(QWidget *qdesigner_internal__GridPanel) { if (qdesigner_internal__GridPanel->objectName().isEmpty()) - qdesigner_internal__GridPanel->setObjectName(QString::fromUtf8("qdesigner_internal__GridPanel")); + qdesigner_internal__GridPanel->setObjectName(QStringLiteral("qdesigner_internal__GridPanel")); qdesigner_internal__GridPanel->resize(393, 110); vboxLayout = new QVBoxLayout(qdesigner_internal__GridPanel); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); vboxLayout->setContentsMargins(0, 0, 0, 0); m_gridGroupBox = new QGroupBox(qdesigner_internal__GridPanel); - m_gridGroupBox->setObjectName(QString::fromUtf8("m_gridGroupBox")); + m_gridGroupBox->setObjectName(QStringLiteral("m_gridGroupBox")); gridLayout = new QGridLayout(m_gridGroupBox); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); m_visibleCheckBox = new QCheckBox(m_gridGroupBox); - m_visibleCheckBox->setObjectName(QString::fromUtf8("m_visibleCheckBox")); + m_visibleCheckBox->setObjectName(QStringLiteral("m_visibleCheckBox")); QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -70,28 +70,28 @@ public: gridLayout->addWidget(m_visibleCheckBox, 0, 0, 1, 1); label = new QLabel(m_gridGroupBox); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 0, 1, 1, 1); m_deltaXSpinBox = new QSpinBox(m_gridGroupBox); - m_deltaXSpinBox->setObjectName(QString::fromUtf8("m_deltaXSpinBox")); + m_deltaXSpinBox->setObjectName(QStringLiteral("m_deltaXSpinBox")); m_deltaXSpinBox->setMinimum(2); m_deltaXSpinBox->setMaximum(100); gridLayout->addWidget(m_deltaXSpinBox, 0, 2, 1, 1); m_snapXCheckBox = new QCheckBox(m_gridGroupBox); - m_snapXCheckBox->setObjectName(QString::fromUtf8("m_snapXCheckBox")); + m_snapXCheckBox->setObjectName(QStringLiteral("m_snapXCheckBox")); sizePolicy.setHeightForWidth(m_snapXCheckBox->sizePolicy().hasHeightForWidth()); m_snapXCheckBox->setSizePolicy(sizePolicy); gridLayout->addWidget(m_snapXCheckBox, 0, 3, 1, 1); hboxLayout = new QHBoxLayout(); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); m_resetButton = new QPushButton(m_gridGroupBox); - m_resetButton->setObjectName(QString::fromUtf8("m_resetButton")); + m_resetButton->setObjectName(QStringLiteral("m_resetButton")); hboxLayout->addWidget(m_resetButton); @@ -103,19 +103,19 @@ public: gridLayout->addLayout(hboxLayout, 1, 0, 1, 1); label_2 = new QLabel(m_gridGroupBox); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); gridLayout->addWidget(label_2, 1, 1, 1, 1); m_deltaYSpinBox = new QSpinBox(m_gridGroupBox); - m_deltaYSpinBox->setObjectName(QString::fromUtf8("m_deltaYSpinBox")); + m_deltaYSpinBox->setObjectName(QStringLiteral("m_deltaYSpinBox")); m_deltaYSpinBox->setMinimum(2); m_deltaYSpinBox->setMaximum(100); gridLayout->addWidget(m_deltaYSpinBox, 1, 2, 1, 1); m_snapYCheckBox = new QCheckBox(m_gridGroupBox); - m_snapYCheckBox->setObjectName(QString::fromUtf8("m_snapYCheckBox")); + m_snapYCheckBox->setObjectName(QStringLiteral("m_snapYCheckBox")); sizePolicy.setHeightForWidth(m_snapYCheckBox->sizePolicy().hasHeightForWidth()); m_snapYCheckBox->setSizePolicy(sizePolicy); diff --git a/tests/auto/tools/uic/baseline/helpdialog.ui.h b/tests/auto/tools/uic/baseline/helpdialog.ui.h index b16632fe000..ac482ba1392 100644 --- a/tests/auto/tools/uic/baseline/helpdialog.ui.h +++ b/tests/auto/tools/uic/baseline/helpdialog.ui.h @@ -114,26 +114,26 @@ public: void setupUi(QWidget *HelpDialog) { if (HelpDialog->objectName().isEmpty()) - HelpDialog->setObjectName(QString::fromUtf8("HelpDialog")); + HelpDialog->setObjectName(QStringLiteral("HelpDialog")); HelpDialog->resize(274, 417); vboxLayout = new QVBoxLayout(HelpDialog); #ifndef Q_OS_MAC vboxLayout->setSpacing(6); #endif vboxLayout->setContentsMargins(0, 0, 0, 0); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); tabWidget = new QTabWidget(HelpDialog); - tabWidget->setObjectName(QString::fromUtf8("tabWidget")); + tabWidget->setObjectName(QStringLiteral("tabWidget")); contentPage = new QWidget(); - contentPage->setObjectName(QString::fromUtf8("contentPage")); + contentPage->setObjectName(QStringLiteral("contentPage")); vboxLayout1 = new QVBoxLayout(contentPage); #ifndef Q_OS_MAC vboxLayout1->setSpacing(6); #endif vboxLayout1->setContentsMargins(5, 5, 5, 5); - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); listContents = new QTreeWidget(contentPage); - listContents->setObjectName(QString::fromUtf8("listContents")); + listContents->setObjectName(QStringLiteral("listContents")); listContents->setContextMenuPolicy(Qt::CustomContextMenu); listContents->setRootIsDecorated(true); listContents->setUniformRowHeights(true); @@ -142,40 +142,40 @@ public: tabWidget->addTab(contentPage, QString()); indexPage = new QWidget(); - indexPage->setObjectName(QString::fromUtf8("indexPage")); + indexPage->setObjectName(QStringLiteral("indexPage")); vboxLayout2 = new QVBoxLayout(indexPage); #ifndef Q_OS_MAC vboxLayout2->setSpacing(6); #endif vboxLayout2->setContentsMargins(5, 5, 5, 5); - vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2")); + vboxLayout2->setObjectName(QStringLiteral("vboxLayout2")); TextLabel1 = new QLabel(indexPage); - TextLabel1->setObjectName(QString::fromUtf8("TextLabel1")); + TextLabel1->setObjectName(QStringLiteral("TextLabel1")); vboxLayout2->addWidget(TextLabel1); editIndex = new QLineEdit(indexPage); - editIndex->setObjectName(QString::fromUtf8("editIndex")); + editIndex->setObjectName(QStringLiteral("editIndex")); vboxLayout2->addWidget(editIndex); listIndex = new QListView(indexPage); - listIndex->setObjectName(QString::fromUtf8("listIndex")); + listIndex->setObjectName(QStringLiteral("listIndex")); listIndex->setContextMenuPolicy(Qt::CustomContextMenu); vboxLayout2->addWidget(listIndex); tabWidget->addTab(indexPage, QString()); bookmarkPage = new QWidget(); - bookmarkPage->setObjectName(QString::fromUtf8("bookmarkPage")); + bookmarkPage->setObjectName(QStringLiteral("bookmarkPage")); vboxLayout3 = new QVBoxLayout(bookmarkPage); #ifndef Q_OS_MAC vboxLayout3->setSpacing(6); #endif vboxLayout3->setContentsMargins(5, 5, 5, 5); - vboxLayout3->setObjectName(QString::fromUtf8("vboxLayout3")); + vboxLayout3->setObjectName(QStringLiteral("vboxLayout3")); listBookmarks = new QTreeWidget(bookmarkPage); - listBookmarks->setObjectName(QString::fromUtf8("listBookmarks")); + listBookmarks->setObjectName(QStringLiteral("listBookmarks")); listBookmarks->setContextMenuPolicy(Qt::CustomContextMenu); listBookmarks->setUniformRowHeights(true); @@ -186,18 +186,18 @@ public: hboxLayout->setSpacing(6); #endif hboxLayout->setContentsMargins(0, 0, 0, 0); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); spacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); hboxLayout->addItem(spacerItem); buttonAdd = new QPushButton(bookmarkPage); - buttonAdd->setObjectName(QString::fromUtf8("buttonAdd")); + buttonAdd->setObjectName(QStringLiteral("buttonAdd")); hboxLayout->addWidget(buttonAdd); buttonRemove = new QPushButton(bookmarkPage); - buttonRemove->setObjectName(QString::fromUtf8("buttonRemove")); + buttonRemove->setObjectName(QStringLiteral("buttonRemove")); hboxLayout->addWidget(buttonRemove); @@ -206,35 +206,35 @@ public: tabWidget->addTab(bookmarkPage, QString()); searchPage = new QWidget(); - searchPage->setObjectName(QString::fromUtf8("searchPage")); + searchPage->setObjectName(QStringLiteral("searchPage")); gridLayout = new QGridLayout(searchPage); #ifndef Q_OS_MAC gridLayout->setSpacing(6); #endif gridLayout->setContentsMargins(5, 5, 5, 5); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); spacerItem1 = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Fixed); gridLayout->addItem(spacerItem1, 3, 0, 1, 1); TextLabel1_2 = new QLabel(searchPage); - TextLabel1_2->setObjectName(QString::fromUtf8("TextLabel1_2")); + TextLabel1_2->setObjectName(QStringLiteral("TextLabel1_2")); gridLayout->addWidget(TextLabel1_2, 0, 0, 1, 1); termsEdit = new QLineEdit(searchPage); - termsEdit->setObjectName(QString::fromUtf8("termsEdit")); + termsEdit->setObjectName(QStringLiteral("termsEdit")); gridLayout->addWidget(termsEdit, 1, 0, 1, 1); resultBox = new QListWidget(searchPage); - resultBox->setObjectName(QString::fromUtf8("resultBox")); + resultBox->setObjectName(QStringLiteral("resultBox")); resultBox->setContextMenuPolicy(Qt::CustomContextMenu); gridLayout->addWidget(resultBox, 5, 0, 1, 1); TextLabel2 = new QLabel(searchPage); - TextLabel2->setObjectName(QString::fromUtf8("TextLabel2")); + TextLabel2->setObjectName(QStringLiteral("TextLabel2")); gridLayout->addWidget(TextLabel2, 4, 0, 1, 1); @@ -243,9 +243,9 @@ public: hboxLayout1->setSpacing(6); #endif hboxLayout1->setContentsMargins(1, 1, 1, 1); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); helpButton = new QPushButton(searchPage); - helpButton->setObjectName(QString::fromUtf8("helpButton")); + helpButton->setObjectName(QStringLiteral("helpButton")); hboxLayout1->addWidget(helpButton); @@ -254,7 +254,7 @@ public: hboxLayout1->addItem(spacerItem2); searchButton = new QPushButton(searchPage); - searchButton->setObjectName(QString::fromUtf8("searchButton")); + searchButton->setObjectName(QStringLiteral("searchButton")); searchButton->setEnabled(false); hboxLayout1->addWidget(searchButton); @@ -267,7 +267,7 @@ public: vboxLayout->addWidget(tabWidget); framePrepare = new QFrame(HelpDialog); - framePrepare->setObjectName(QString::fromUtf8("framePrepare")); + framePrepare->setObjectName(QStringLiteral("framePrepare")); framePrepare->setFrameShape(QFrame::StyledPanel); framePrepare->setFrameShadow(QFrame::Raised); hboxLayout2 = new QHBoxLayout(framePrepare); @@ -275,14 +275,14 @@ public: hboxLayout2->setSpacing(6); #endif hboxLayout2->setContentsMargins(3, 3, 3, 3); - hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2")); + hboxLayout2->setObjectName(QStringLiteral("hboxLayout2")); labelPrepare = new QLabel(framePrepare); - labelPrepare->setObjectName(QString::fromUtf8("labelPrepare")); + labelPrepare->setObjectName(QStringLiteral("labelPrepare")); hboxLayout2->addWidget(labelPrepare); progressPrepare = new QProgressBar(framePrepare); - progressPrepare->setObjectName(QString::fromUtf8("progressPrepare")); + progressPrepare->setObjectName(QStringLiteral("progressPrepare")); hboxLayout2->addWidget(progressPrepare); diff --git a/tests/auto/tools/uic/baseline/history.ui.h b/tests/auto/tools/uic/baseline/history.ui.h index 1784b216e36..57007e52800 100644 --- a/tests/auto/tools/uic/baseline/history.ui.h +++ b/tests/auto/tools/uic/baseline/history.ui.h @@ -42,33 +42,33 @@ public: void setupUi(QDialog *HistoryDialog) { if (HistoryDialog->objectName().isEmpty()) - HistoryDialog->setObjectName(QString::fromUtf8("HistoryDialog")); + HistoryDialog->setObjectName(QStringLiteral("HistoryDialog")); HistoryDialog->resize(758, 450); gridLayout = new QGridLayout(HistoryDialog); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); spacerItem = new QSpacerItem(252, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); gridLayout->addItem(spacerItem, 0, 0, 1, 1); search = new SearchLineEdit(HistoryDialog); - search->setObjectName(QString::fromUtf8("search")); + search->setObjectName(QStringLiteral("search")); gridLayout->addWidget(search, 0, 1, 1, 1); tree = new EditTreeView(HistoryDialog); - tree->setObjectName(QString::fromUtf8("tree")); + tree->setObjectName(QStringLiteral("tree")); gridLayout->addWidget(tree, 1, 0, 1, 2); hboxLayout = new QHBoxLayout(); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); removeButton = new QPushButton(HistoryDialog); - removeButton->setObjectName(QString::fromUtf8("removeButton")); + removeButton->setObjectName(QStringLiteral("removeButton")); hboxLayout->addWidget(removeButton); removeAllButton = new QPushButton(HistoryDialog); - removeAllButton->setObjectName(QString::fromUtf8("removeAllButton")); + removeAllButton->setObjectName(QStringLiteral("removeAllButton")); hboxLayout->addWidget(removeAllButton); @@ -77,7 +77,7 @@ public: hboxLayout->addItem(spacerItem1); buttonBox = new QDialogButtonBox(HistoryDialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setStandardButtons(QDialogButtonBox::Ok); hboxLayout->addWidget(buttonBox); diff --git a/tests/auto/tools/uic/baseline/icontheme.ui.h b/tests/auto/tools/uic/baseline/icontheme.ui.h index 78c90838ab4..f3f8f634f9e 100644 --- a/tests/auto/tools/uic/baseline/icontheme.ui.h +++ b/tests/auto/tools/uic/baseline/icontheme.ui.h @@ -32,39 +32,39 @@ public: void setupUi(QWidget *Form) { if (Form->objectName().isEmpty()) - Form->setObjectName(QString::fromUtf8("Form")); + Form->setObjectName(QStringLiteral("Form")); Form->resize(122, 117); verticalLayout = new QVBoxLayout(Form); - verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); fileicon = new QPushButton(Form); - fileicon->setObjectName(QString::fromUtf8("fileicon")); + fileicon->setObjectName(QStringLiteral("fileicon")); QIcon icon; - icon.addFile(QString::fromUtf8("image1.png"), QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(QStringLiteral("image1.png"), QSize(), QIcon::Normal, QIcon::Off); fileicon->setIcon(icon); verticalLayout->addWidget(fileicon); fileandthemeicon = new QPushButton(Form); - fileandthemeicon->setObjectName(QString::fromUtf8("fileandthemeicon")); + fileandthemeicon->setObjectName(QStringLiteral("fileandthemeicon")); QIcon icon1; - QString iconThemeName = QString::fromUtf8("edit-copy"); + QString iconThemeName = QStringLiteral("edit-copy"); if (QIcon::hasThemeIcon(iconThemeName)) { icon1 = QIcon::fromTheme(iconThemeName); } else { - icon1.addFile(QString::fromUtf8("image7.png"), QSize(), QIcon::Normal, QIcon::Off); + icon1.addFile(QStringLiteral("image7.png"), QSize(), QIcon::Normal, QIcon::Off); } fileandthemeicon->setIcon(icon1); verticalLayout->addWidget(fileandthemeicon); themeicon = new QPushButton(Form); - themeicon->setObjectName(QString::fromUtf8("themeicon")); + themeicon->setObjectName(QStringLiteral("themeicon")); QIcon icon2; - iconThemeName = QString::fromUtf8("edit-copy"); + iconThemeName = QStringLiteral("edit-copy"); if (QIcon::hasThemeIcon(iconThemeName)) { icon2 = QIcon::fromTheme(iconThemeName); } else { - icon2.addFile(QString::fromUtf8(""), QSize(), QIcon::Normal, QIcon::Off); + icon2.addFile(QStringLiteral(""), QSize(), QIcon::Normal, QIcon::Off); } themeicon->setIcon(icon2); diff --git a/tests/auto/tools/uic/baseline/identifierpage.ui.h b/tests/auto/tools/uic/baseline/identifierpage.ui.h index 1088ee33da6..3f0cd1a4f5e 100644 --- a/tests/auto/tools/uic/baseline/identifierpage.ui.h +++ b/tests/auto/tools/uic/baseline/identifierpage.ui.h @@ -40,16 +40,16 @@ public: void setupUi(QWidget *IdentifierPage) { if (IdentifierPage->objectName().isEmpty()) - IdentifierPage->setObjectName(QString::fromUtf8("IdentifierPage")); + IdentifierPage->setObjectName(QStringLiteral("IdentifierPage")); IdentifierPage->resize(417, 242); gridLayout = new QGridLayout(IdentifierPage); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); spacerItem = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Fixed); gridLayout->addItem(spacerItem, 0, 1, 1, 1); identifierCheckBox = new QCheckBox(IdentifierPage); - identifierCheckBox->setObjectName(QString::fromUtf8("identifierCheckBox")); + identifierCheckBox->setObjectName(QStringLiteral("identifierCheckBox")); gridLayout->addWidget(identifierCheckBox, 1, 0, 1, 3); @@ -62,20 +62,20 @@ public: gridLayout->addItem(spacerItem2, 2, 0, 1, 1); globalButton = new QRadioButton(IdentifierPage); - globalButton->setObjectName(QString::fromUtf8("globalButton")); + globalButton->setObjectName(QStringLiteral("globalButton")); globalButton->setEnabled(false); globalButton->setChecked(true); gridLayout->addWidget(globalButton, 2, 1, 1, 1); prefixLineEdit = new QLineEdit(IdentifierPage); - prefixLineEdit->setObjectName(QString::fromUtf8("prefixLineEdit")); + prefixLineEdit->setObjectName(QStringLiteral("prefixLineEdit")); prefixLineEdit->setEnabled(false); gridLayout->addWidget(prefixLineEdit, 2, 2, 1, 1); fileNameButton = new QRadioButton(IdentifierPage); - fileNameButton->setObjectName(QString::fromUtf8("fileNameButton")); + fileNameButton->setObjectName(QStringLiteral("fileNameButton")); fileNameButton->setEnabled(false); gridLayout->addWidget(fileNameButton, 3, 1, 1, 2); diff --git a/tests/auto/tools/uic/baseline/imagedialog.ui.h b/tests/auto/tools/uic/baseline/imagedialog.ui.h index 1728cac952f..c09363d3ec2 100644 --- a/tests/auto/tools/uic/baseline/imagedialog.ui.h +++ b/tests/auto/tools/uic/baseline/imagedialog.ui.h @@ -50,8 +50,8 @@ public: void setupUi(QDialog *dialog) { if (dialog->objectName().isEmpty()) - dialog->setObjectName(QString::fromUtf8("dialog")); - dialog->setObjectName(QString::fromUtf8("ImageDialog")); + dialog->setObjectName(QStringLiteral("dialog")); + dialog->setObjectName(QStringLiteral("ImageDialog")); dialog->resize(320, 180); vboxLayout = new QVBoxLayout(dialog); #ifndef Q_OS_MAC @@ -60,17 +60,17 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); - vboxLayout->setObjectName(QString::fromUtf8("")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("")); gridLayout = new QGridLayout(); #ifndef Q_OS_MAC gridLayout->setSpacing(6); #endif gridLayout->setContentsMargins(1, 1, 1, 1); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); - gridLayout->setObjectName(QString::fromUtf8("")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); + gridLayout->setObjectName(QStringLiteral("")); widthLabel = new QLabel(dialog); - widthLabel->setObjectName(QString::fromUtf8("widthLabel")); + widthLabel->setObjectName(QStringLiteral("widthLabel")); widthLabel->setGeometry(QRect(1, 27, 67, 22)); widthLabel->setFrameShape(QFrame::NoFrame); widthLabel->setFrameShadow(QFrame::Plain); @@ -79,7 +79,7 @@ public: gridLayout->addWidget(widthLabel, 1, 0, 1, 1); heightLabel = new QLabel(dialog); - heightLabel->setObjectName(QString::fromUtf8("heightLabel")); + heightLabel->setObjectName(QStringLiteral("heightLabel")); heightLabel->setGeometry(QRect(1, 55, 67, 22)); heightLabel->setFrameShape(QFrame::NoFrame); heightLabel->setFrameShadow(QFrame::Plain); @@ -88,7 +88,7 @@ public: gridLayout->addWidget(heightLabel, 2, 0, 1, 1); colorDepthCombo = new QComboBox(dialog); - colorDepthCombo->setObjectName(QString::fromUtf8("colorDepthCombo")); + colorDepthCombo->setObjectName(QStringLiteral("colorDepthCombo")); colorDepthCombo->setGeometry(QRect(74, 83, 227, 22)); QSizePolicy sizePolicy(static_cast(5), static_cast(0)); sizePolicy.setHorizontalStretch(0); @@ -100,7 +100,7 @@ public: gridLayout->addWidget(colorDepthCombo, 3, 1, 1, 1); nameLineEdit = new QLineEdit(dialog); - nameLineEdit->setObjectName(QString::fromUtf8("nameLineEdit")); + nameLineEdit->setObjectName(QStringLiteral("nameLineEdit")); nameLineEdit->setGeometry(QRect(74, 83, 227, 22)); QSizePolicy sizePolicy1(static_cast(5), static_cast(0)); sizePolicy1.setHorizontalStretch(1); @@ -112,7 +112,7 @@ public: gridLayout->addWidget(nameLineEdit, 0, 1, 1, 1); spinBox = new QSpinBox(dialog); - spinBox->setObjectName(QString::fromUtf8("spinBox")); + spinBox->setObjectName(QStringLiteral("spinBox")); spinBox->setGeometry(QRect(74, 1, 227, 20)); sizePolicy.setHeightForWidth(spinBox->sizePolicy().hasHeightForWidth()); spinBox->setSizePolicy(sizePolicy); @@ -124,7 +124,7 @@ public: gridLayout->addWidget(spinBox, 1, 1, 1, 1); spinBox_2 = new QSpinBox(dialog); - spinBox_2->setObjectName(QString::fromUtf8("spinBox_2")); + spinBox_2->setObjectName(QStringLiteral("spinBox_2")); spinBox_2->setGeometry(QRect(74, 27, 227, 22)); sizePolicy.setHeightForWidth(spinBox_2->sizePolicy().hasHeightForWidth()); spinBox_2->setSizePolicy(sizePolicy); @@ -136,7 +136,7 @@ public: gridLayout->addWidget(spinBox_2, 2, 1, 1, 1); nameLabel = new QLabel(dialog); - nameLabel->setObjectName(QString::fromUtf8("nameLabel")); + nameLabel->setObjectName(QStringLiteral("nameLabel")); nameLabel->setGeometry(QRect(1, 1, 67, 20)); nameLabel->setFrameShape(QFrame::NoFrame); nameLabel->setFrameShadow(QFrame::Plain); @@ -145,7 +145,7 @@ public: gridLayout->addWidget(nameLabel, 0, 0, 1, 1); colorDepthLabel = new QLabel(dialog); - colorDepthLabel->setObjectName(QString::fromUtf8("colorDepthLabel")); + colorDepthLabel->setObjectName(QStringLiteral("colorDepthLabel")); colorDepthLabel->setGeometry(QRect(1, 83, 67, 22)); colorDepthLabel->setFrameShape(QFrame::NoFrame); colorDepthLabel->setFrameShadow(QFrame::Plain); @@ -165,20 +165,20 @@ public: hboxLayout->setSpacing(6); #endif hboxLayout->setContentsMargins(1, 1, 1, 1); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); - hboxLayout->setObjectName(QString::fromUtf8("")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("")); spacerItem1 = new QSpacerItem(QSizePolicy::Expanding, QSizePolicy::Minimum); hboxLayout->addItem(spacerItem1); okButton = new QPushButton(dialog); - okButton->setObjectName(QString::fromUtf8("okButton")); + okButton->setObjectName(QStringLiteral("okButton")); okButton->setGeometry(QRect(135, 1, 80, 24)); hboxLayout->addWidget(okButton); cancelButton = new QPushButton(dialog); - cancelButton->setObjectName(QString::fromUtf8("cancelButton")); + cancelButton->setObjectName(QStringLiteral("cancelButton")); cancelButton->setGeometry(QRect(221, 1, 80, 24)); hboxLayout->addWidget(cancelButton); diff --git a/tests/auto/tools/uic/baseline/inputpage.ui.h b/tests/auto/tools/uic/baseline/inputpage.ui.h index 90ff131d1d3..d52d1ae93b5 100644 --- a/tests/auto/tools/uic/baseline/inputpage.ui.h +++ b/tests/auto/tools/uic/baseline/inputpage.ui.h @@ -39,16 +39,16 @@ public: void setupUi(QWidget *InputPage) { if (InputPage->objectName().isEmpty()) - InputPage->setObjectName(QString::fromUtf8("InputPage")); + InputPage->setObjectName(QStringLiteral("InputPage")); InputPage->resize(417, 242); gridLayout = new QGridLayout(InputPage); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); spacerItem = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Fixed); gridLayout->addItem(spacerItem, 0, 2, 1, 1); label = new QLabel(InputPage); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -59,14 +59,14 @@ public: hboxLayout = new QHBoxLayout(); hboxLayout->setSpacing(0); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); fileLineEdit = new QLineEdit(InputPage); - fileLineEdit->setObjectName(QString::fromUtf8("fileLineEdit")); + fileLineEdit->setObjectName(QStringLiteral("fileLineEdit")); hboxLayout->addWidget(fileLineEdit); browseButton = new QToolButton(InputPage); - browseButton->setObjectName(QString::fromUtf8("browseButton")); + browseButton->setObjectName(QStringLiteral("browseButton")); hboxLayout->addWidget(browseButton); diff --git a/tests/auto/tools/uic/baseline/installdialog.ui.h b/tests/auto/tools/uic/baseline/installdialog.ui.h index d58986f98a0..519a71005ef 100644 --- a/tests/auto/tools/uic/baseline/installdialog.ui.h +++ b/tests/auto/tools/uic/baseline/installdialog.ui.h @@ -48,32 +48,32 @@ public: void setupUi(QDialog *InstallDialog) { if (InstallDialog->objectName().isEmpty()) - InstallDialog->setObjectName(QString::fromUtf8("InstallDialog")); + InstallDialog->setObjectName(QStringLiteral("InstallDialog")); InstallDialog->resize(436, 245); gridLayout = new QGridLayout(InstallDialog); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); label = new QLabel(InstallDialog); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 0, 0, 1, 4); listWidget = new QListWidget(InstallDialog); - listWidget->setObjectName(QString::fromUtf8("listWidget")); + listWidget->setObjectName(QStringLiteral("listWidget")); gridLayout->addWidget(listWidget, 1, 0, 4, 4); installButton = new QPushButton(InstallDialog); - installButton->setObjectName(QString::fromUtf8("installButton")); + installButton->setObjectName(QStringLiteral("installButton")); gridLayout->addWidget(installButton, 1, 4, 1, 1); cancelButton = new QPushButton(InstallDialog); - cancelButton->setObjectName(QString::fromUtf8("cancelButton")); + cancelButton->setObjectName(QStringLiteral("cancelButton")); gridLayout->addWidget(cancelButton, 2, 4, 1, 1); closeButton = new QPushButton(InstallDialog); - closeButton->setObjectName(QString::fromUtf8("closeButton")); + closeButton->setObjectName(QStringLiteral("closeButton")); gridLayout->addWidget(closeButton, 3, 4, 1, 1); @@ -82,34 +82,34 @@ public: gridLayout->addItem(spacerItem, 4, 4, 1, 1); label_4 = new QLabel(InstallDialog); - label_4->setObjectName(QString::fromUtf8("label_4")); + label_4->setObjectName(QStringLiteral("label_4")); gridLayout->addWidget(label_4, 5, 0, 1, 1); pathLineEdit = new QLineEdit(InstallDialog); - pathLineEdit->setObjectName(QString::fromUtf8("pathLineEdit")); + pathLineEdit->setObjectName(QStringLiteral("pathLineEdit")); gridLayout->addWidget(pathLineEdit, 5, 1, 1, 2); browseButton = new QToolButton(InstallDialog); - browseButton->setObjectName(QString::fromUtf8("browseButton")); + browseButton->setObjectName(QStringLiteral("browseButton")); gridLayout->addWidget(browseButton, 5, 3, 1, 1); line = new QFrame(InstallDialog); - line->setObjectName(QString::fromUtf8("line")); + line->setObjectName(QStringLiteral("line")); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); gridLayout->addWidget(line, 6, 0, 1, 5); statusLabel = new QLabel(InstallDialog); - statusLabel->setObjectName(QString::fromUtf8("statusLabel")); + statusLabel->setObjectName(QStringLiteral("statusLabel")); gridLayout->addWidget(statusLabel, 7, 0, 1, 2); progressBar = new QProgressBar(InstallDialog); - progressBar->setObjectName(QString::fromUtf8("progressBar")); + progressBar->setObjectName(QStringLiteral("progressBar")); progressBar->setValue(0); progressBar->setOrientation(Qt::Horizontal); diff --git a/tests/auto/tools/uic/baseline/languagesdialog.ui.h b/tests/auto/tools/uic/baseline/languagesdialog.ui.h index 58d299096af..0419f18ecfb 100644 --- a/tests/auto/tools/uic/baseline/languagesdialog.ui.h +++ b/tests/auto/tools/uic/baseline/languagesdialog.ui.h @@ -41,50 +41,50 @@ public: void setupUi(QDialog *LanguagesDialog) { if (LanguagesDialog->objectName().isEmpty()) - LanguagesDialog->setObjectName(QString::fromUtf8("LanguagesDialog")); + LanguagesDialog->setObjectName(QStringLiteral("LanguagesDialog")); LanguagesDialog->resize(400, 300); verticalLayout = new QVBoxLayout(LanguagesDialog); - verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); languagesList = new QTreeWidget(LanguagesDialog); - languagesList->setObjectName(QString::fromUtf8("languagesList")); + languagesList->setObjectName(QStringLiteral("languagesList")); languagesList->setIndentation(0); verticalLayout->addWidget(languagesList); hboxLayout = new QHBoxLayout(); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); upButton = new QToolButton(LanguagesDialog); - upButton->setObjectName(QString::fromUtf8("upButton")); + upButton->setObjectName(QStringLiteral("upButton")); upButton->setEnabled(false); QIcon icon; - icon.addFile(QString::fromUtf8(":/images/up.png"), QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(QStringLiteral(":/images/up.png"), QSize(), QIcon::Normal, QIcon::Off); upButton->setIcon(icon); hboxLayout->addWidget(upButton); downButton = new QToolButton(LanguagesDialog); - downButton->setObjectName(QString::fromUtf8("downButton")); + downButton->setObjectName(QStringLiteral("downButton")); downButton->setEnabled(false); QIcon icon1; - icon1.addFile(QString::fromUtf8(":/images/down.png"), QSize(), QIcon::Normal, QIcon::Off); + icon1.addFile(QStringLiteral(":/images/down.png"), QSize(), QIcon::Normal, QIcon::Off); downButton->setIcon(icon1); hboxLayout->addWidget(downButton); removeButton = new QToolButton(LanguagesDialog); - removeButton->setObjectName(QString::fromUtf8("removeButton")); + removeButton->setObjectName(QStringLiteral("removeButton")); removeButton->setEnabled(false); QIcon icon2; - icon2.addFile(QString::fromUtf8(":/images/editdelete.png"), QSize(), QIcon::Normal, QIcon::Off); + icon2.addFile(QStringLiteral(":/images/editdelete.png"), QSize(), QIcon::Normal, QIcon::Off); removeButton->setIcon(icon2); hboxLayout->addWidget(removeButton); openFileButton = new QToolButton(LanguagesDialog); - openFileButton->setObjectName(QString::fromUtf8("openFileButton")); + openFileButton->setObjectName(QStringLiteral("openFileButton")); openFileButton->setEnabled(true); QIcon icon3; - icon3.addFile(QString::fromUtf8(":/images/mac/fileopen.png"), QSize(), QIcon::Normal, QIcon::Off); + icon3.addFile(QStringLiteral(":/images/mac/fileopen.png"), QSize(), QIcon::Normal, QIcon::Off); openFileButton->setIcon(icon3); hboxLayout->addWidget(openFileButton); @@ -94,7 +94,7 @@ public: hboxLayout->addItem(spacerItem); okButton = new QPushButton(LanguagesDialog); - okButton->setObjectName(QString::fromUtf8("okButton")); + okButton->setObjectName(QStringLiteral("okButton")); hboxLayout->addWidget(okButton); diff --git a/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h b/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h index 1cca34b1faf..5ea1c434589 100644 --- a/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h +++ b/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h @@ -96,7 +96,7 @@ public: void setupUi(QDialog *qdesigner_internal__ListWidgetEditor) { if (qdesigner_internal__ListWidgetEditor->objectName().isEmpty()) - qdesigner_internal__ListWidgetEditor->setObjectName(QString::fromUtf8("qdesigner_internal__ListWidgetEditor")); + qdesigner_internal__ListWidgetEditor->setObjectName(QStringLiteral("qdesigner_internal__ListWidgetEditor")); qdesigner_internal__ListWidgetEditor->resize(223, 245); vboxLayout = new QVBoxLayout(qdesigner_internal__ListWidgetEditor); #ifndef Q_OS_MAC @@ -105,25 +105,25 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); groupBox = new QGroupBox(qdesigner_internal__ListWidgetEditor); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); gridLayout = new QGridLayout(groupBox); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); listWidget = new QListWidget(groupBox); - listWidget->setObjectName(QString::fromUtf8("listWidget")); + listWidget->setObjectName(QStringLiteral("listWidget")); gridLayout->addWidget(listWidget, 0, 0, 1, 1); horizontalLayout_2 = new QHBoxLayout(); - horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2")); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); newItemButton = new QToolButton(groupBox); - newItemButton->setObjectName(QString::fromUtf8("newItemButton")); + newItemButton->setObjectName(QStringLiteral("newItemButton")); horizontalLayout_2->addWidget(newItemButton); deleteItemButton = new QToolButton(groupBox); - deleteItemButton->setObjectName(QString::fromUtf8("deleteItemButton")); + deleteItemButton->setObjectName(QStringLiteral("deleteItemButton")); horizontalLayout_2->addWidget(deleteItemButton); @@ -132,12 +132,12 @@ public: horizontalLayout_2->addItem(spacerItem); moveItemUpButton = new QToolButton(groupBox); - moveItemUpButton->setObjectName(QString::fromUtf8("moveItemUpButton")); + moveItemUpButton->setObjectName(QStringLiteral("moveItemUpButton")); horizontalLayout_2->addWidget(moveItemUpButton); moveItemDownButton = new QToolButton(groupBox); - moveItemDownButton->setObjectName(QString::fromUtf8("moveItemDownButton")); + moveItemDownButton->setObjectName(QStringLiteral("moveItemDownButton")); horizontalLayout_2->addWidget(moveItemDownButton); @@ -145,14 +145,14 @@ public: gridLayout->addLayout(horizontalLayout_2, 1, 0, 1, 1); horizontalLayout = new QHBoxLayout(); - horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); label = new QLabel(groupBox); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); horizontalLayout->addWidget(label); itemIconSelector = new qdesigner_internal::IconSelector(groupBox); - itemIconSelector->setObjectName(QString::fromUtf8("itemIconSelector")); + itemIconSelector->setObjectName(QStringLiteral("itemIconSelector")); horizontalLayout->addWidget(itemIconSelector); @@ -167,7 +167,7 @@ public: vboxLayout->addWidget(groupBox); buttonBox = new QDialogButtonBox(qdesigner_internal__ListWidgetEditor); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/mainwindow.ui.h b/tests/auto/tools/uic/baseline/mainwindow.ui.h index ef6f4cfe9c3..4e336a42629 100644 --- a/tests/auto/tools/uic/baseline/mainwindow.ui.h +++ b/tests/auto/tools/uic/baseline/mainwindow.ui.h @@ -89,14 +89,14 @@ public: void setupUi(QMainWindow *MainWindow) { if (MainWindow->objectName().isEmpty()) - MainWindow->setObjectName(QString::fromUtf8("MainWindow")); + MainWindow->setObjectName(QStringLiteral("MainWindow")); MainWindow->resize(829, 813); actionAdd_Custom_Font = new QAction(MainWindow); - actionAdd_Custom_Font->setObjectName(QString::fromUtf8("actionAdd_Custom_Font")); + actionAdd_Custom_Font->setObjectName(QStringLiteral("actionAdd_Custom_Font")); action_Exit = new QAction(MainWindow); - action_Exit->setObjectName(QString::fromUtf8("action_Exit")); + action_Exit->setObjectName(QStringLiteral("action_Exit")); centralwidget = new QWidget(MainWindow); - centralwidget->setObjectName(QString::fromUtf8("centralwidget")); + centralwidget->setObjectName(QStringLiteral("centralwidget")); vboxLayout = new QVBoxLayout(centralwidget); #ifndef Q_OS_MAC vboxLayout->setSpacing(6); @@ -104,9 +104,9 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); groupBox = new QGroupBox(centralwidget); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); hboxLayout = new QHBoxLayout(groupBox); #ifndef Q_OS_MAC hboxLayout->setSpacing(6); @@ -114,40 +114,40 @@ public: #ifndef Q_OS_MAC hboxLayout->setContentsMargins(9, 9, 9, 9); #endif - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); label = new QLabel(groupBox); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); hboxLayout->addWidget(label); fontComboBox = new QFontComboBox(groupBox); - fontComboBox->setObjectName(QString::fromUtf8("fontComboBox")); + fontComboBox->setObjectName(QStringLiteral("fontComboBox")); hboxLayout->addWidget(fontComboBox); label_2 = new QLabel(groupBox); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); hboxLayout->addWidget(label_2); pixelSize = new QSpinBox(groupBox); - pixelSize->setObjectName(QString::fromUtf8("pixelSize")); + pixelSize->setObjectName(QStringLiteral("pixelSize")); pixelSize->setMinimum(1); hboxLayout->addWidget(pixelSize); label_7 = new QLabel(groupBox); - label_7->setObjectName(QString::fromUtf8("label_7")); + label_7->setObjectName(QStringLiteral("label_7")); hboxLayout->addWidget(label_7); weightCombo = new QComboBox(groupBox); - weightCombo->setObjectName(QString::fromUtf8("weightCombo")); + weightCombo->setObjectName(QStringLiteral("weightCombo")); hboxLayout->addWidget(weightCombo); italic = new QCheckBox(groupBox); - italic->setObjectName(QString::fromUtf8("italic")); + italic->setObjectName(QStringLiteral("italic")); hboxLayout->addWidget(italic); @@ -159,7 +159,7 @@ public: vboxLayout->addWidget(groupBox); groupBox_2 = new QGroupBox(centralwidget); - groupBox_2->setObjectName(QString::fromUtf8("groupBox_2")); + groupBox_2->setObjectName(QStringLiteral("groupBox_2")); vboxLayout1 = new QVBoxLayout(groupBox_2); #ifndef Q_OS_MAC vboxLayout1->setSpacing(6); @@ -167,9 +167,9 @@ public: #ifndef Q_OS_MAC vboxLayout1->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); chooseFromCodePoints = new QRadioButton(groupBox_2); - chooseFromCodePoints->setObjectName(QString::fromUtf8("chooseFromCodePoints")); + chooseFromCodePoints->setObjectName(QStringLiteral("chooseFromCodePoints")); chooseFromCodePoints->setChecked(true); vboxLayout1->addWidget(chooseFromCodePoints); @@ -179,9 +179,9 @@ public: vboxLayout2->setSpacing(6); #endif vboxLayout2->setContentsMargins(0, 0, 0, 0); - vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2")); + vboxLayout2->setObjectName(QStringLiteral("vboxLayout2")); characterRangeView = new QListWidget(groupBox_2); - characterRangeView->setObjectName(QString::fromUtf8("characterRangeView")); + characterRangeView->setObjectName(QStringLiteral("characterRangeView")); vboxLayout2->addWidget(characterRangeView); @@ -190,19 +190,19 @@ public: hboxLayout1->setSpacing(6); #endif hboxLayout1->setContentsMargins(0, 0, 0, 0); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); selectAll = new QPushButton(groupBox_2); - selectAll->setObjectName(QString::fromUtf8("selectAll")); + selectAll->setObjectName(QStringLiteral("selectAll")); hboxLayout1->addWidget(selectAll); deselectAll = new QPushButton(groupBox_2); - deselectAll->setObjectName(QString::fromUtf8("deselectAll")); + deselectAll->setObjectName(QStringLiteral("deselectAll")); hboxLayout1->addWidget(deselectAll); invertSelection = new QPushButton(groupBox_2); - invertSelection->setObjectName(QString::fromUtf8("invertSelection")); + invertSelection->setObjectName(QStringLiteral("invertSelection")); hboxLayout1->addWidget(invertSelection); @@ -217,7 +217,7 @@ public: vboxLayout1->addLayout(vboxLayout2); chooseFromSampleFile = new QRadioButton(groupBox_2); - chooseFromSampleFile->setObjectName(QString::fromUtf8("chooseFromSampleFile")); + chooseFromSampleFile->setObjectName(QStringLiteral("chooseFromSampleFile")); vboxLayout1->addWidget(chooseFromSampleFile); @@ -226,27 +226,27 @@ public: hboxLayout2->setSpacing(6); #endif hboxLayout2->setContentsMargins(0, 0, 0, 0); - hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2")); + hboxLayout2->setObjectName(QStringLiteral("hboxLayout2")); label_5 = new QLabel(groupBox_2); - label_5->setObjectName(QString::fromUtf8("label_5")); + label_5->setObjectName(QStringLiteral("label_5")); label_5->setEnabled(false); hboxLayout2->addWidget(label_5); sampleFile = new QLineEdit(groupBox_2); - sampleFile->setObjectName(QString::fromUtf8("sampleFile")); + sampleFile->setObjectName(QStringLiteral("sampleFile")); sampleFile->setEnabled(false); hboxLayout2->addWidget(sampleFile); browseSampleFile = new QPushButton(groupBox_2); - browseSampleFile->setObjectName(QString::fromUtf8("browseSampleFile")); + browseSampleFile->setObjectName(QStringLiteral("browseSampleFile")); browseSampleFile->setEnabled(false); hboxLayout2->addWidget(browseSampleFile); charCount = new QLabel(groupBox_2); - charCount->setObjectName(QString::fromUtf8("charCount")); + charCount->setObjectName(QStringLiteral("charCount")); charCount->setEnabled(false); hboxLayout2->addWidget(charCount); @@ -258,7 +258,7 @@ public: vboxLayout->addWidget(groupBox_2); groupBox_3 = new QGroupBox(centralwidget); - groupBox_3->setObjectName(QString::fromUtf8("groupBox_3")); + groupBox_3->setObjectName(QStringLiteral("groupBox_3")); hboxLayout3 = new QHBoxLayout(groupBox_3); #ifndef Q_OS_MAC hboxLayout3->setSpacing(6); @@ -266,9 +266,9 @@ public: #ifndef Q_OS_MAC hboxLayout3->setContentsMargins(9, 9, 9, 9); #endif - hboxLayout3->setObjectName(QString::fromUtf8("hboxLayout3")); + hboxLayout3->setObjectName(QStringLiteral("hboxLayout3")); preview = new QLineEdit(groupBox_3); - preview->setObjectName(QString::fromUtf8("preview")); + preview->setObjectName(QStringLiteral("preview")); hboxLayout3->addWidget(preview); @@ -276,7 +276,7 @@ public: vboxLayout->addWidget(groupBox_3); groupBox_4 = new QGroupBox(centralwidget); - groupBox_4->setObjectName(QString::fromUtf8("groupBox_4")); + groupBox_4->setObjectName(QStringLiteral("groupBox_4")); hboxLayout4 = new QHBoxLayout(groupBox_4); #ifndef Q_OS_MAC hboxLayout4->setSpacing(6); @@ -284,29 +284,29 @@ public: #ifndef Q_OS_MAC hboxLayout4->setContentsMargins(9, 9, 9, 9); #endif - hboxLayout4->setObjectName(QString::fromUtf8("hboxLayout4")); + hboxLayout4->setObjectName(QStringLiteral("hboxLayout4")); label_3 = new QLabel(groupBox_4); - label_3->setObjectName(QString::fromUtf8("label_3")); + label_3->setObjectName(QStringLiteral("label_3")); hboxLayout4->addWidget(label_3); path = new QLineEdit(groupBox_4); - path->setObjectName(QString::fromUtf8("path")); + path->setObjectName(QStringLiteral("path")); hboxLayout4->addWidget(path); browsePath = new QPushButton(groupBox_4); - browsePath->setObjectName(QString::fromUtf8("browsePath")); + browsePath->setObjectName(QStringLiteral("browsePath")); hboxLayout4->addWidget(browsePath); label_4 = new QLabel(groupBox_4); - label_4->setObjectName(QString::fromUtf8("label_4")); + label_4->setObjectName(QStringLiteral("label_4")); hboxLayout4->addWidget(label_4); fileName = new QLineEdit(groupBox_4); - fileName->setObjectName(QString::fromUtf8("fileName")); + fileName->setObjectName(QStringLiteral("fileName")); fileName->setEnabled(false); hboxLayout4->addWidget(fileName); @@ -319,9 +319,9 @@ public: hboxLayout5->setSpacing(6); #endif hboxLayout5->setContentsMargins(0, 0, 0, 0); - hboxLayout5->setObjectName(QString::fromUtf8("hboxLayout5")); + hboxLayout5->setObjectName(QStringLiteral("hboxLayout5")); generate = new QPushButton(centralwidget); - generate->setObjectName(QString::fromUtf8("generate")); + generate->setObjectName(QStringLiteral("generate")); hboxLayout5->addWidget(generate); @@ -334,13 +334,13 @@ public: MainWindow->setCentralWidget(centralwidget); menubar = new QMenuBar(MainWindow); - menubar->setObjectName(QString::fromUtf8("menubar")); + menubar->setObjectName(QStringLiteral("menubar")); menubar->setGeometry(QRect(0, 0, 829, 29)); menuFile = new QMenu(menubar); - menuFile->setObjectName(QString::fromUtf8("menuFile")); + menuFile->setObjectName(QStringLiteral("menuFile")); MainWindow->setMenuBar(menubar); statusbar = new QStatusBar(MainWindow); - statusbar->setObjectName(QString::fromUtf8("statusbar")); + statusbar->setObjectName(QStringLiteral("statusbar")); MainWindow->setStatusBar(statusbar); menubar->addAction(menuFile->menuAction()); diff --git a/tests/auto/tools/uic/baseline/mydialog.ui.h b/tests/auto/tools/uic/baseline/mydialog.ui.h index a8750d45143..ffb49e5d97c 100644 --- a/tests/auto/tools/uic/baseline/mydialog.ui.h +++ b/tests/auto/tools/uic/baseline/mydialog.ui.h @@ -32,7 +32,7 @@ public: void setupUi(QDialog *MyDialog) { if (MyDialog->objectName().isEmpty()) - MyDialog->setObjectName(QString::fromUtf8("MyDialog")); + MyDialog->setObjectName(QStringLiteral("MyDialog")); MyDialog->resize(401, 70); vboxLayout = new QVBoxLayout(MyDialog); #ifndef Q_OS_MAC @@ -41,14 +41,14 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); aLabel = new QLabel(MyDialog); - aLabel->setObjectName(QString::fromUtf8("aLabel")); + aLabel->setObjectName(QStringLiteral("aLabel")); vboxLayout->addWidget(aLabel); aButton = new QPushButton(MyDialog); - aButton->setObjectName(QString::fromUtf8("aButton")); + aButton->setObjectName(QStringLiteral("aButton")); vboxLayout->addWidget(aButton); diff --git a/tests/auto/tools/uic/baseline/myform.ui.h b/tests/auto/tools/uic/baseline/myform.ui.h index a5ff7bcc117..140225abbe8 100644 --- a/tests/auto/tools/uic/baseline/myform.ui.h +++ b/tests/auto/tools/uic/baseline/myform.ui.h @@ -45,35 +45,35 @@ public: void setupUi(QWidget *Form) { if (Form->objectName().isEmpty()) - Form->setObjectName(QString::fromUtf8("Form")); + Form->setObjectName(QStringLiteral("Form")); Form->resize(258, 224); vboxLayout = new QVBoxLayout(Form); #ifndef Q_OS_MAC vboxLayout->setSpacing(6); #endif vboxLayout->setContentsMargins(8, 8, 8, 8); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); groupBox = new QGroupBox(Form); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); gridLayout = new QGridLayout(groupBox); #ifndef Q_OS_MAC gridLayout->setSpacing(6); #endif gridLayout->setContentsMargins(8, 8, 8, 8); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); radioButton_2 = new QRadioButton(groupBox); - radioButton_2->setObjectName(QString::fromUtf8("radioButton_2")); + radioButton_2->setObjectName(QStringLiteral("radioButton_2")); gridLayout->addWidget(radioButton_2, 1, 0, 1, 1); radioButton = new QRadioButton(groupBox); - radioButton->setObjectName(QString::fromUtf8("radioButton")); + radioButton->setObjectName(QStringLiteral("radioButton")); radioButton->setChecked(true); gridLayout->addWidget(radioButton, 0, 0, 1, 1); checkBox_2 = new QCheckBox(groupBox); - checkBox_2->setObjectName(QString::fromUtf8("checkBox_2")); + checkBox_2->setObjectName(QStringLiteral("checkBox_2")); checkBox_2->setChecked(true); gridLayout->addWidget(checkBox_2, 1, 1, 1, 1); @@ -83,32 +83,32 @@ public: gridLayout->addItem(spacerItem, 5, 0, 1, 1); checkBox = new QCheckBox(groupBox); - checkBox->setObjectName(QString::fromUtf8("checkBox")); + checkBox->setObjectName(QStringLiteral("checkBox")); gridLayout->addWidget(checkBox, 0, 1, 1, 1); radioButton_2_2 = new QRadioButton(groupBox); - radioButton_2_2->setObjectName(QString::fromUtf8("radioButton_2_2")); + radioButton_2_2->setObjectName(QStringLiteral("radioButton_2_2")); gridLayout->addWidget(radioButton_2_2, 2, 0, 1, 1); radioButton_3 = new QRadioButton(groupBox); - radioButton_3->setObjectName(QString::fromUtf8("radioButton_3")); + radioButton_3->setObjectName(QStringLiteral("radioButton_3")); gridLayout->addWidget(radioButton_3, 3, 0, 1, 1); radioButton_4 = new QRadioButton(groupBox); - radioButton_4->setObjectName(QString::fromUtf8("radioButton_4")); + radioButton_4->setObjectName(QStringLiteral("radioButton_4")); gridLayout->addWidget(radioButton_4, 4, 0, 1, 1); checkBox_3 = new QCheckBox(groupBox); - checkBox_3->setObjectName(QString::fromUtf8("checkBox_3")); + checkBox_3->setObjectName(QStringLiteral("checkBox_3")); gridLayout->addWidget(checkBox_3, 2, 1, 1, 1); checkBox_4 = new QCheckBox(groupBox); - checkBox_4->setObjectName(QString::fromUtf8("checkBox_4")); + checkBox_4->setObjectName(QStringLiteral("checkBox_4")); checkBox_4->setChecked(true); gridLayout->addWidget(checkBox_4, 3, 1, 1, 1); diff --git a/tests/auto/tools/uic/baseline/newactiondialog.ui.h b/tests/auto/tools/uic/baseline/newactiondialog.ui.h index b69e1581f9c..5b9fef13f88 100644 --- a/tests/auto/tools/uic/baseline/newactiondialog.ui.h +++ b/tests/auto/tools/uic/baseline/newactiondialog.ui.h @@ -93,42 +93,42 @@ public: void setupUi(QDialog *qdesigner_internal__NewActionDialog) { if (qdesigner_internal__NewActionDialog->objectName().isEmpty()) - qdesigner_internal__NewActionDialog->setObjectName(QString::fromUtf8("qdesigner_internal__NewActionDialog")); + qdesigner_internal__NewActionDialog->setObjectName(QStringLiteral("qdesigner_internal__NewActionDialog")); qdesigner_internal__NewActionDialog->resize(363, 156); verticalLayout = new QVBoxLayout(qdesigner_internal__NewActionDialog); - verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); formLayout = new QFormLayout(); - formLayout->setObjectName(QString::fromUtf8("formLayout")); + formLayout->setObjectName(QStringLiteral("formLayout")); label = new QLabel(qdesigner_internal__NewActionDialog); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); formLayout->setWidget(0, QFormLayout::LabelRole, label); editActionText = new QLineEdit(qdesigner_internal__NewActionDialog); - editActionText->setObjectName(QString::fromUtf8("editActionText")); + editActionText->setObjectName(QStringLiteral("editActionText")); editActionText->setMinimumSize(QSize(255, 0)); formLayout->setWidget(0, QFormLayout::FieldRole, editActionText); label_3 = new QLabel(qdesigner_internal__NewActionDialog); - label_3->setObjectName(QString::fromUtf8("label_3")); + label_3->setObjectName(QStringLiteral("label_3")); formLayout->setWidget(1, QFormLayout::LabelRole, label_3); editObjectName = new QLineEdit(qdesigner_internal__NewActionDialog); - editObjectName->setObjectName(QString::fromUtf8("editObjectName")); + editObjectName->setObjectName(QStringLiteral("editObjectName")); formLayout->setWidget(1, QFormLayout::FieldRole, editObjectName); label_2 = new QLabel(qdesigner_internal__NewActionDialog); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); formLayout->setWidget(2, QFormLayout::LabelRole, label_2); horizontalLayout = new QHBoxLayout(); - horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); iconSelector = new qdesigner_internal::IconSelector(qdesigner_internal__NewActionDialog); - iconSelector->setObjectName(QString::fromUtf8("iconSelector")); + iconSelector->setObjectName(QStringLiteral("iconSelector")); horizontalLayout->addWidget(iconSelector); @@ -147,14 +147,14 @@ public: verticalLayout->addItem(verticalSpacer); line = new QFrame(qdesigner_internal__NewActionDialog); - line->setObjectName(QString::fromUtf8("line")); + line->setObjectName(QStringLiteral("line")); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); verticalLayout->addWidget(line); buttonBox = new QDialogButtonBox(qdesigner_internal__NewActionDialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/newdynamicpropertydialog.ui.h b/tests/auto/tools/uic/baseline/newdynamicpropertydialog.ui.h index f3296421b21..ba9ba5dcfd8 100644 --- a/tests/auto/tools/uic/baseline/newdynamicpropertydialog.ui.h +++ b/tests/auto/tools/uic/baseline/newdynamicpropertydialog.ui.h @@ -46,20 +46,20 @@ public: void setupUi(QDialog *qdesigner_internal__NewDynamicPropertyDialog) { if (qdesigner_internal__NewDynamicPropertyDialog->objectName().isEmpty()) - qdesigner_internal__NewDynamicPropertyDialog->setObjectName(QString::fromUtf8("qdesigner_internal__NewDynamicPropertyDialog")); + qdesigner_internal__NewDynamicPropertyDialog->setObjectName(QStringLiteral("qdesigner_internal__NewDynamicPropertyDialog")); qdesigner_internal__NewDynamicPropertyDialog->resize(340, 118); verticalLayout = new QVBoxLayout(qdesigner_internal__NewDynamicPropertyDialog); - verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); formLayout = new QFormLayout(); - formLayout->setObjectName(QString::fromUtf8("formLayout")); + formLayout->setObjectName(QStringLiteral("formLayout")); m_lineEdit = new QLineEdit(qdesigner_internal__NewDynamicPropertyDialog); - m_lineEdit->setObjectName(QString::fromUtf8("m_lineEdit")); + m_lineEdit->setObjectName(QStringLiteral("m_lineEdit")); m_lineEdit->setMinimumSize(QSize(220, 0)); formLayout->setWidget(0, QFormLayout::FieldRole, m_lineEdit); label = new QLabel(qdesigner_internal__NewDynamicPropertyDialog); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -69,9 +69,9 @@ public: formLayout->setWidget(0, QFormLayout::LabelRole, label); horizontalLayout = new QHBoxLayout(); - horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); m_comboBox = new QComboBox(qdesigner_internal__NewDynamicPropertyDialog); - m_comboBox->setObjectName(QString::fromUtf8("m_comboBox")); + m_comboBox->setObjectName(QStringLiteral("m_comboBox")); horizontalLayout->addWidget(m_comboBox); @@ -83,7 +83,7 @@ public: formLayout->setLayout(1, QFormLayout::FieldRole, horizontalLayout); label_2 = new QLabel(qdesigner_internal__NewDynamicPropertyDialog); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); sizePolicy.setHeightForWidth(label_2->sizePolicy().hasHeightForWidth()); label_2->setSizePolicy(sizePolicy); @@ -97,7 +97,7 @@ public: verticalLayout->addItem(spacerItem); m_buttonBox = new QDialogButtonBox(qdesigner_internal__NewDynamicPropertyDialog); - m_buttonBox->setObjectName(QString::fromUtf8("m_buttonBox")); + m_buttonBox->setObjectName(QStringLiteral("m_buttonBox")); m_buttonBox->setOrientation(Qt::Horizontal); m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); m_buttonBox->setCenterButtons(false); diff --git a/tests/auto/tools/uic/baseline/newform.ui.h b/tests/auto/tools/uic/baseline/newform.ui.h index e985c3bf26e..007b2680aa1 100644 --- a/tests/auto/tools/uic/baseline/newform.ui.h +++ b/tests/auto/tools/uic/baseline/newform.ui.h @@ -83,7 +83,7 @@ public: void setupUi(QDialog *NewForm) { if (NewForm->objectName().isEmpty()) - NewForm->setObjectName(QString::fromUtf8("NewForm")); + NewForm->setObjectName(QStringLiteral("NewForm")); NewForm->resize(495, 319); vboxLayout = new QVBoxLayout(NewForm); #ifndef Q_OS_MAC @@ -92,15 +92,15 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); hboxLayout = new QHBoxLayout(); #ifndef Q_OS_MAC hboxLayout->setSpacing(6); #endif hboxLayout->setContentsMargins(1, 1, 1, 1); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); treeWidget = new QTreeWidget(NewForm); - treeWidget->setObjectName(QString::fromUtf8("treeWidget")); + treeWidget->setObjectName(QStringLiteral("treeWidget")); treeWidget->setIconSize(QSize(128, 128)); treeWidget->setRootIsDecorated(false); treeWidget->setColumnCount(1); @@ -108,7 +108,7 @@ public: hboxLayout->addWidget(treeWidget); lblPreview = new QLabel(NewForm); - lblPreview->setObjectName(QString::fromUtf8("lblPreview")); + lblPreview->setObjectName(QStringLiteral("lblPreview")); QSizePolicy sizePolicy(static_cast(7), static_cast(5)); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -124,19 +124,19 @@ public: vboxLayout->addLayout(hboxLayout); horizontalLine = new QFrame(NewForm); - horizontalLine->setObjectName(QString::fromUtf8("horizontalLine")); + horizontalLine->setObjectName(QStringLiteral("horizontalLine")); horizontalLine->setFrameShape(QFrame::HLine); horizontalLine->setFrameShadow(QFrame::Sunken); vboxLayout->addWidget(horizontalLine); chkShowOnStartup = new QCheckBox(NewForm); - chkShowOnStartup->setObjectName(QString::fromUtf8("chkShowOnStartup")); + chkShowOnStartup->setObjectName(QStringLiteral("chkShowOnStartup")); vboxLayout->addWidget(chkShowOnStartup); buttonBox = new QDialogButtonBox(NewForm); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); vboxLayout->addWidget(buttonBox); diff --git a/tests/auto/tools/uic/baseline/orderdialog.ui.h b/tests/auto/tools/uic/baseline/orderdialog.ui.h index 017222da50c..494f3e6894a 100644 --- a/tests/auto/tools/uic/baseline/orderdialog.ui.h +++ b/tests/auto/tools/uic/baseline/orderdialog.ui.h @@ -87,18 +87,18 @@ public: void setupUi(QDialog *qdesigner_internal__OrderDialog) { if (qdesigner_internal__OrderDialog->objectName().isEmpty()) - qdesigner_internal__OrderDialog->setObjectName(QString::fromUtf8("qdesigner_internal__OrderDialog")); + qdesigner_internal__OrderDialog->setObjectName(QStringLiteral("qdesigner_internal__OrderDialog")); qdesigner_internal__OrderDialog->resize(467, 310); vboxLayout = new QVBoxLayout(qdesigner_internal__OrderDialog); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); groupBox = new QGroupBox(qdesigner_internal__OrderDialog); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); hboxLayout = new QHBoxLayout(groupBox); hboxLayout->setSpacing(6); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); hboxLayout->setContentsMargins(9, 9, 9, 9); pageList = new QListWidget(groupBox); - pageList->setObjectName(QString::fromUtf8("pageList")); + pageList->setObjectName(QStringLiteral("pageList")); pageList->setMinimumSize(QSize(344, 0)); pageList->setDragDropMode(QAbstractItemView::InternalMove); pageList->setSelectionMode(QAbstractItemView::ContiguousSelection); @@ -108,15 +108,15 @@ public: vboxLayout1 = new QVBoxLayout(); vboxLayout1->setSpacing(6); - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); vboxLayout1->setContentsMargins(0, 0, 0, 0); upButton = new QToolButton(groupBox); - upButton->setObjectName(QString::fromUtf8("upButton")); + upButton->setObjectName(QStringLiteral("upButton")); vboxLayout1->addWidget(upButton); downButton = new QToolButton(groupBox); - downButton->setObjectName(QString::fromUtf8("downButton")); + downButton->setObjectName(QStringLiteral("downButton")); vboxLayout1->addWidget(downButton); @@ -131,7 +131,7 @@ public: vboxLayout->addWidget(groupBox); buttonBox = new QDialogButtonBox(qdesigner_internal__OrderDialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset); diff --git a/tests/auto/tools/uic/baseline/outputpage.ui.h b/tests/auto/tools/uic/baseline/outputpage.ui.h index 5e8332ea930..20fbf93b177 100644 --- a/tests/auto/tools/uic/baseline/outputpage.ui.h +++ b/tests/auto/tools/uic/baseline/outputpage.ui.h @@ -37,16 +37,16 @@ public: void setupUi(QWidget *OutputPage) { if (OutputPage->objectName().isEmpty()) - OutputPage->setObjectName(QString::fromUtf8("OutputPage")); + OutputPage->setObjectName(QStringLiteral("OutputPage")); OutputPage->resize(417, 242); gridLayout = new QGridLayout(OutputPage); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); spacerItem = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Fixed); gridLayout->addItem(spacerItem, 0, 1, 1, 1); label = new QLabel(OutputPage); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -56,7 +56,7 @@ public: gridLayout->addWidget(label, 1, 0, 1, 1); projectLineEdit = new QLineEdit(OutputPage); - projectLineEdit->setObjectName(QString::fromUtf8("projectLineEdit")); + projectLineEdit->setObjectName(QStringLiteral("projectLineEdit")); QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Fixed); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); @@ -66,14 +66,14 @@ public: gridLayout->addWidget(projectLineEdit, 1, 1, 1, 1); label_2 = new QLabel(OutputPage); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); sizePolicy.setHeightForWidth(label_2->sizePolicy().hasHeightForWidth()); label_2->setSizePolicy(sizePolicy); gridLayout->addWidget(label_2, 2, 0, 1, 1); collectionLineEdit = new QLineEdit(OutputPage); - collectionLineEdit->setObjectName(QString::fromUtf8("collectionLineEdit")); + collectionLineEdit->setObjectName(QStringLiteral("collectionLineEdit")); sizePolicy1.setHeightForWidth(collectionLineEdit->sizePolicy().hasHeightForWidth()); collectionLineEdit->setSizePolicy(sizePolicy1); diff --git a/tests/auto/tools/uic/baseline/pagefold.ui.h b/tests/auto/tools/uic/baseline/pagefold.ui.h index a58c4f49761..ede9a51d7c6 100644 --- a/tests/auto/tools/uic/baseline/pagefold.ui.h +++ b/tests/auto/tools/uic/baseline/pagefold.ui.h @@ -70,18 +70,18 @@ public: void setupUi(QMainWindow *MainWindow) { if (MainWindow->objectName().isEmpty()) - MainWindow->setObjectName(QString::fromUtf8("MainWindow")); + MainWindow->setObjectName(QStringLiteral("MainWindow")); MainWindow->resize(392, 412); exitAction = new QAction(MainWindow); - exitAction->setObjectName(QString::fromUtf8("exitAction")); + exitAction->setObjectName(QStringLiteral("exitAction")); aboutQtAction = new QAction(MainWindow); - aboutQtAction->setObjectName(QString::fromUtf8("aboutQtAction")); + aboutQtAction->setObjectName(QStringLiteral("aboutQtAction")); editStyleAction = new QAction(MainWindow); - editStyleAction->setObjectName(QString::fromUtf8("editStyleAction")); + editStyleAction->setObjectName(QStringLiteral("editStyleAction")); aboutAction = new QAction(MainWindow); - aboutAction->setObjectName(QString::fromUtf8("aboutAction")); + aboutAction->setObjectName(QStringLiteral("aboutAction")); centralwidget = new QWidget(MainWindow); - centralwidget->setObjectName(QString::fromUtf8("centralwidget")); + centralwidget->setObjectName(QStringLiteral("centralwidget")); vboxLayout = new QVBoxLayout(centralwidget); #ifndef Q_OS_MAC vboxLayout->setSpacing(6); @@ -89,9 +89,9 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); mainFrame = new QFrame(centralwidget); - mainFrame->setObjectName(QString::fromUtf8("mainFrame")); + mainFrame->setObjectName(QStringLiteral("mainFrame")); mainFrame->setFrameShape(QFrame::StyledPanel); mainFrame->setFrameShadow(QFrame::Raised); gridLayout = new QGridLayout(mainFrame); @@ -101,9 +101,9 @@ public: #ifndef Q_OS_MAC gridLayout->setContentsMargins(9, 9, 9, 9); #endif - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); nameCombo = new QComboBox(mainFrame); - nameCombo->setObjectName(QString::fromUtf8("nameCombo")); + nameCombo->setObjectName(QStringLiteral("nameCombo")); nameCombo->setEditable(true); gridLayout->addWidget(nameCombo, 0, 1, 1, 3); @@ -113,56 +113,56 @@ public: gridLayout->addItem(spacerItem, 1, 3, 1, 1); femaleRadioButton = new QRadioButton(mainFrame); - femaleRadioButton->setObjectName(QString::fromUtf8("femaleRadioButton")); + femaleRadioButton->setObjectName(QStringLiteral("femaleRadioButton")); gridLayout->addWidget(femaleRadioButton, 1, 2, 1, 1); genderLabel = new QLabel(mainFrame); - genderLabel->setObjectName(QString::fromUtf8("genderLabel")); + genderLabel->setObjectName(QStringLiteral("genderLabel")); gridLayout->addWidget(genderLabel, 1, 0, 1, 1); ageLabel = new QLabel(mainFrame); - ageLabel->setObjectName(QString::fromUtf8("ageLabel")); + ageLabel->setObjectName(QStringLiteral("ageLabel")); gridLayout->addWidget(ageLabel, 2, 0, 1, 1); maleRadioButton = new QRadioButton(mainFrame); - maleRadioButton->setObjectName(QString::fromUtf8("maleRadioButton")); + maleRadioButton->setObjectName(QStringLiteral("maleRadioButton")); gridLayout->addWidget(maleRadioButton, 1, 1, 1, 1); nameLabel = new QLabel(mainFrame); - nameLabel->setObjectName(QString::fromUtf8("nameLabel")); + nameLabel->setObjectName(QStringLiteral("nameLabel")); gridLayout->addWidget(nameLabel, 0, 0, 1, 1); passwordLabel = new QLabel(mainFrame); - passwordLabel->setObjectName(QString::fromUtf8("passwordLabel")); + passwordLabel->setObjectName(QStringLiteral("passwordLabel")); gridLayout->addWidget(passwordLabel, 3, 0, 1, 1); ageSpinBox = new QSpinBox(mainFrame); - ageSpinBox->setObjectName(QString::fromUtf8("ageSpinBox")); + ageSpinBox->setObjectName(QStringLiteral("ageSpinBox")); ageSpinBox->setMinimum(12); ageSpinBox->setValue(22); gridLayout->addWidget(ageSpinBox, 2, 1, 1, 3); buttonBox = new QDialogButtonBox(mainFrame); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok); gridLayout->addWidget(buttonBox, 7, 2, 1, 2); agreeCheckBox = new QCheckBox(mainFrame); - agreeCheckBox->setObjectName(QString::fromUtf8("agreeCheckBox")); + agreeCheckBox->setObjectName(QStringLiteral("agreeCheckBox")); gridLayout->addWidget(agreeCheckBox, 6, 0, 1, 4); passwordEdit = new QLineEdit(mainFrame); - passwordEdit->setObjectName(QString::fromUtf8("passwordEdit")); + passwordEdit->setObjectName(QStringLiteral("passwordEdit")); passwordEdit->setEchoMode(QLineEdit::Password); gridLayout->addWidget(passwordEdit, 3, 1, 1, 3); @@ -171,22 +171,22 @@ public: new QListWidgetItem(professionList); new QListWidgetItem(professionList); new QListWidgetItem(professionList); - professionList->setObjectName(QString::fromUtf8("professionList")); + professionList->setObjectName(QStringLiteral("professionList")); gridLayout->addWidget(professionList, 5, 1, 1, 3); label = new QLabel(mainFrame); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 5, 0, 1, 1); countryCombo = new QComboBox(mainFrame); - countryCombo->setObjectName(QString::fromUtf8("countryCombo")); + countryCombo->setObjectName(QStringLiteral("countryCombo")); gridLayout->addWidget(countryCombo, 4, 1, 1, 3); countryLabel = new QLabel(mainFrame); - countryLabel->setObjectName(QString::fromUtf8("countryLabel")); + countryLabel->setObjectName(QStringLiteral("countryLabel")); gridLayout->addWidget(countryLabel, 4, 0, 1, 1); @@ -195,15 +195,15 @@ public: MainWindow->setCentralWidget(centralwidget); menubar = new QMenuBar(MainWindow); - menubar->setObjectName(QString::fromUtf8("menubar")); + menubar->setObjectName(QStringLiteral("menubar")); menubar->setGeometry(QRect(0, 0, 392, 25)); menu_File = new QMenu(menubar); - menu_File->setObjectName(QString::fromUtf8("menu_File")); + menu_File->setObjectName(QStringLiteral("menu_File")); menu_Help = new QMenu(menubar); - menu_Help->setObjectName(QString::fromUtf8("menu_Help")); + menu_Help->setObjectName(QStringLiteral("menu_Help")); MainWindow->setMenuBar(menubar); statusbar = new QStatusBar(MainWindow); - statusbar->setObjectName(QString::fromUtf8("statusbar")); + statusbar->setObjectName(QStringLiteral("statusbar")); MainWindow->setStatusBar(statusbar); #ifndef QT_NO_SHORTCUT ageLabel->setBuddy(ageSpinBox); diff --git a/tests/auto/tools/uic/baseline/paletteeditor.ui.h b/tests/auto/tools/uic/baseline/paletteeditor.ui.h index de57468b9dd..67f74c15460 100644 --- a/tests/auto/tools/uic/baseline/paletteeditor.ui.h +++ b/tests/auto/tools/uic/baseline/paletteeditor.ui.h @@ -95,7 +95,7 @@ public: void setupUi(QDialog *qdesigner_internal__PaletteEditor) { if (qdesigner_internal__PaletteEditor->objectName().isEmpty()) - qdesigner_internal__PaletteEditor->setObjectName(QString::fromUtf8("qdesigner_internal__PaletteEditor")); + qdesigner_internal__PaletteEditor->setObjectName(QStringLiteral("qdesigner_internal__PaletteEditor")); qdesigner_internal__PaletteEditor->resize(365, 409); QSizePolicy sizePolicy(static_cast(7), static_cast(7)); sizePolicy.setHorizontalStretch(0); @@ -109,9 +109,9 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); advancedBox = new QGroupBox(qdesigner_internal__PaletteEditor); - advancedBox->setObjectName(QString::fromUtf8("advancedBox")); + advancedBox->setObjectName(QStringLiteral("advancedBox")); advancedBox->setMinimumSize(QSize(0, 0)); advancedBox->setMaximumSize(QSize(16777215, 16777215)); gridLayout = new QGridLayout(advancedBox); @@ -121,9 +121,9 @@ public: #ifndef Q_OS_MAC gridLayout->setContentsMargins(9, 9, 9, 9); #endif - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); buildButton = new QtColorButton(advancedBox); - buildButton->setObjectName(QString::fromUtf8("buildButton")); + buildButton->setObjectName(QStringLiteral("buildButton")); QSizePolicy sizePolicy1(static_cast(7), static_cast(13)); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); @@ -133,24 +133,24 @@ public: gridLayout->addWidget(buildButton, 0, 1, 1, 1); paletteView = new QTreeView(advancedBox); - paletteView->setObjectName(QString::fromUtf8("paletteView")); + paletteView->setObjectName(QStringLiteral("paletteView")); paletteView->setMinimumSize(QSize(0, 200)); gridLayout->addWidget(paletteView, 1, 0, 1, 4); detailsRadio = new QRadioButton(advancedBox); - detailsRadio->setObjectName(QString::fromUtf8("detailsRadio")); + detailsRadio->setObjectName(QStringLiteral("detailsRadio")); gridLayout->addWidget(detailsRadio, 0, 3, 1, 1); computeRadio = new QRadioButton(advancedBox); - computeRadio->setObjectName(QString::fromUtf8("computeRadio")); + computeRadio->setObjectName(QStringLiteral("computeRadio")); computeRadio->setChecked(true); gridLayout->addWidget(computeRadio, 0, 2, 1, 1); label = new QLabel(advancedBox); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 0, 0, 1, 1); @@ -158,7 +158,7 @@ public: vboxLayout->addWidget(advancedBox); GroupBox126 = new QGroupBox(qdesigner_internal__PaletteEditor); - GroupBox126->setObjectName(QString::fromUtf8("GroupBox126")); + GroupBox126->setObjectName(QStringLiteral("GroupBox126")); QSizePolicy sizePolicy2(static_cast(5), static_cast(7)); sizePolicy2.setHorizontalStretch(0); sizePolicy2.setVerticalStretch(0); @@ -169,25 +169,25 @@ public: gridLayout1->setSpacing(6); #endif gridLayout1->setContentsMargins(8, 8, 8, 8); - gridLayout1->setObjectName(QString::fromUtf8("gridLayout1")); + gridLayout1->setObjectName(QStringLiteral("gridLayout1")); disabledRadio = new QRadioButton(GroupBox126); - disabledRadio->setObjectName(QString::fromUtf8("disabledRadio")); + disabledRadio->setObjectName(QStringLiteral("disabledRadio")); gridLayout1->addWidget(disabledRadio, 0, 2, 1, 1); inactiveRadio = new QRadioButton(GroupBox126); - inactiveRadio->setObjectName(QString::fromUtf8("inactiveRadio")); + inactiveRadio->setObjectName(QStringLiteral("inactiveRadio")); gridLayout1->addWidget(inactiveRadio, 0, 1, 1, 1); activeRadio = new QRadioButton(GroupBox126); - activeRadio->setObjectName(QString::fromUtf8("activeRadio")); + activeRadio->setObjectName(QStringLiteral("activeRadio")); activeRadio->setChecked(true); gridLayout1->addWidget(activeRadio, 0, 0, 1, 1); previewFrame = new qdesigner_internal::PreviewFrame(GroupBox126); - previewFrame->setObjectName(QString::fromUtf8("previewFrame")); + previewFrame->setObjectName(QStringLiteral("previewFrame")); sizePolicy.setHeightForWidth(previewFrame->sizePolicy().hasHeightForWidth()); previewFrame->setSizePolicy(sizePolicy); @@ -197,7 +197,7 @@ public: vboxLayout->addWidget(GroupBox126); buttonBox = new QDialogButtonBox(qdesigner_internal__PaletteEditor); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/passworddialog.ui.h b/tests/auto/tools/uic/baseline/passworddialog.ui.h index f6579dac7b6..be763cf040c 100644 --- a/tests/auto/tools/uic/baseline/passworddialog.ui.h +++ b/tests/auto/tools/uic/baseline/passworddialog.ui.h @@ -40,19 +40,19 @@ public: void setupUi(QDialog *PasswordDialog) { if (PasswordDialog->objectName().isEmpty()) - PasswordDialog->setObjectName(QString::fromUtf8("PasswordDialog")); + PasswordDialog->setObjectName(QStringLiteral("PasswordDialog")); PasswordDialog->resize(399, 148); gridLayout = new QGridLayout(PasswordDialog); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); hboxLayout = new QHBoxLayout(); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); iconLabel = new QLabel(PasswordDialog); - iconLabel->setObjectName(QString::fromUtf8("iconLabel")); + iconLabel->setObjectName(QStringLiteral("iconLabel")); hboxLayout->addWidget(iconLabel); introLabel = new QLabel(PasswordDialog); - introLabel->setObjectName(QString::fromUtf8("introLabel")); + introLabel->setObjectName(QStringLiteral("introLabel")); QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -65,28 +65,28 @@ public: gridLayout->addLayout(hboxLayout, 0, 0, 1, 2); label = new QLabel(PasswordDialog); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 1, 0, 1, 1); userNameLineEdit = new QLineEdit(PasswordDialog); - userNameLineEdit->setObjectName(QString::fromUtf8("userNameLineEdit")); + userNameLineEdit->setObjectName(QStringLiteral("userNameLineEdit")); gridLayout->addWidget(userNameLineEdit, 1, 1, 1, 1); lblPassword = new QLabel(PasswordDialog); - lblPassword->setObjectName(QString::fromUtf8("lblPassword")); + lblPassword->setObjectName(QStringLiteral("lblPassword")); gridLayout->addWidget(lblPassword, 2, 0, 1, 1); passwordLineEdit = new QLineEdit(PasswordDialog); - passwordLineEdit->setObjectName(QString::fromUtf8("passwordLineEdit")); + passwordLineEdit->setObjectName(QStringLiteral("passwordLineEdit")); passwordLineEdit->setEchoMode(QLineEdit::Password); gridLayout->addWidget(passwordLineEdit, 2, 1, 1, 1); buttonBox = new QDialogButtonBox(PasswordDialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/pathpage.ui.h b/tests/auto/tools/uic/baseline/pathpage.ui.h index 5edca08fac1..8d75297ff4c 100644 --- a/tests/auto/tools/uic/baseline/pathpage.ui.h +++ b/tests/auto/tools/uic/baseline/pathpage.ui.h @@ -42,12 +42,12 @@ public: void setupUi(QWidget *PathPage) { if (PathPage->objectName().isEmpty()) - PathPage->setObjectName(QString::fromUtf8("PathPage")); + PathPage->setObjectName(QStringLiteral("PathPage")); PathPage->resize(417, 243); gridLayout = new QGridLayout(PathPage); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); label_2 = new QLabel(PathPage); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -57,7 +57,7 @@ public: gridLayout->addWidget(label_2, 0, 0, 1, 1); filterLineEdit = new QLineEdit(PathPage); - filterLineEdit->setObjectName(QString::fromUtf8("filterLineEdit")); + filterLineEdit->setObjectName(QStringLiteral("filterLineEdit")); gridLayout->addWidget(filterLineEdit, 0, 1, 1, 2); @@ -66,17 +66,17 @@ public: gridLayout->addItem(spacerItem, 1, 1, 1, 1); label = new QLabel(PathPage); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 2, 0, 1, 3); pathListWidget = new QListWidget(PathPage); - pathListWidget->setObjectName(QString::fromUtf8("pathListWidget")); + pathListWidget->setObjectName(QStringLiteral("pathListWidget")); gridLayout->addWidget(pathListWidget, 3, 0, 3, 3); addButton = new QPushButton(PathPage); - addButton->setObjectName(QString::fromUtf8("addButton")); + addButton->setObjectName(QStringLiteral("addButton")); QSizePolicy sizePolicy1(QSizePolicy::Maximum, QSizePolicy::Fixed); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); @@ -86,7 +86,7 @@ public: gridLayout->addWidget(addButton, 3, 3, 1, 1); removeButton = new QPushButton(PathPage); - removeButton->setObjectName(QString::fromUtf8("removeButton")); + removeButton->setObjectName(QStringLiteral("removeButton")); sizePolicy1.setHeightForWidth(removeButton->sizePolicy().hasHeightForWidth()); removeButton->setSizePolicy(sizePolicy1); diff --git a/tests/auto/tools/uic/baseline/phrasebookbox.ui.h b/tests/auto/tools/uic/baseline/phrasebookbox.ui.h index ad7f916f56c..ecc7190ff19 100644 --- a/tests/auto/tools/uic/baseline/phrasebookbox.ui.h +++ b/tests/auto/tools/uic/baseline/phrasebookbox.ui.h @@ -93,45 +93,45 @@ public: void setupUi(QDialog *PhraseBookBox) { if (PhraseBookBox->objectName().isEmpty()) - PhraseBookBox->setObjectName(QString::fromUtf8("PhraseBookBox")); + PhraseBookBox->setObjectName(QStringLiteral("PhraseBookBox")); PhraseBookBox->resize(596, 454); unnamed = new QHBoxLayout(PhraseBookBox); unnamed->setSpacing(6); unnamed->setContentsMargins(11, 11, 11, 11); - unnamed->setObjectName(QString::fromUtf8("unnamed")); + unnamed->setObjectName(QStringLiteral("unnamed")); inputsLayout = new QVBoxLayout(); inputsLayout->setSpacing(6); - inputsLayout->setObjectName(QString::fromUtf8("inputsLayout")); + inputsLayout->setObjectName(QStringLiteral("inputsLayout")); gridLayout = new QGridLayout(); gridLayout->setSpacing(6); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); target = new QLabel(PhraseBookBox); - target->setObjectName(QString::fromUtf8("target")); + target->setObjectName(QStringLiteral("target")); gridLayout->addWidget(target, 1, 0, 1, 1); targetLed = new QLineEdit(PhraseBookBox); - targetLed->setObjectName(QString::fromUtf8("targetLed")); + targetLed->setObjectName(QStringLiteral("targetLed")); gridLayout->addWidget(targetLed, 1, 1, 1, 1); source = new QLabel(PhraseBookBox); - source->setObjectName(QString::fromUtf8("source")); + source->setObjectName(QStringLiteral("source")); gridLayout->addWidget(source, 0, 0, 1, 1); definitionLed = new QLineEdit(PhraseBookBox); - definitionLed->setObjectName(QString::fromUtf8("definitionLed")); + definitionLed->setObjectName(QStringLiteral("definitionLed")); gridLayout->addWidget(definitionLed, 2, 1, 1, 1); sourceLed = new QLineEdit(PhraseBookBox); - sourceLed->setObjectName(QString::fromUtf8("sourceLed")); + sourceLed->setObjectName(QStringLiteral("sourceLed")); gridLayout->addWidget(sourceLed, 0, 1, 1, 1); definition = new QLabel(PhraseBookBox); - definition->setObjectName(QString::fromUtf8("definition")); + definition->setObjectName(QStringLiteral("definition")); gridLayout->addWidget(definition, 2, 0, 1, 1); @@ -139,7 +139,7 @@ public: inputsLayout->addLayout(gridLayout); phraseList = new QTreeView(PhraseBookBox); - phraseList->setObjectName(QString::fromUtf8("phraseList")); + phraseList->setObjectName(QStringLiteral("phraseList")); phraseList->setRootIsDecorated(false); phraseList->setUniformRowHeights(true); phraseList->setItemsExpandable(false); @@ -153,24 +153,24 @@ public: buttonLayout = new QVBoxLayout(); buttonLayout->setSpacing(6); - buttonLayout->setObjectName(QString::fromUtf8("buttonLayout")); + buttonLayout->setObjectName(QStringLiteral("buttonLayout")); newBut = new QPushButton(PhraseBookBox); - newBut->setObjectName(QString::fromUtf8("newBut")); + newBut->setObjectName(QStringLiteral("newBut")); buttonLayout->addWidget(newBut); removeBut = new QPushButton(PhraseBookBox); - removeBut->setObjectName(QString::fromUtf8("removeBut")); + removeBut->setObjectName(QStringLiteral("removeBut")); buttonLayout->addWidget(removeBut); saveBut = new QPushButton(PhraseBookBox); - saveBut->setObjectName(QString::fromUtf8("saveBut")); + saveBut->setObjectName(QStringLiteral("saveBut")); buttonLayout->addWidget(saveBut); closeBut = new QPushButton(PhraseBookBox); - closeBut->setObjectName(QString::fromUtf8("closeBut")); + closeBut->setObjectName(QStringLiteral("closeBut")); buttonLayout->addWidget(closeBut); diff --git a/tests/auto/tools/uic/baseline/plugindialog.ui.h b/tests/auto/tools/uic/baseline/plugindialog.ui.h index 24453cb47cb..770bb82b55f 100644 --- a/tests/auto/tools/uic/baseline/plugindialog.ui.h +++ b/tests/auto/tools/uic/baseline/plugindialog.ui.h @@ -80,39 +80,39 @@ public: void setupUi(QDialog *PluginDialog) { if (PluginDialog->objectName().isEmpty()) - PluginDialog->setObjectName(QString::fromUtf8("PluginDialog")); + PluginDialog->setObjectName(QStringLiteral("PluginDialog")); PluginDialog->resize(401, 331); vboxLayout = new QVBoxLayout(PluginDialog); vboxLayout->setSpacing(6); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); vboxLayout->setContentsMargins(8, 8, 8, 8); label = new QLabel(PluginDialog); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); label->setWordWrap(true); vboxLayout->addWidget(label); treeWidget = new QTreeWidget(PluginDialog); - treeWidget->setObjectName(QString::fromUtf8("treeWidget")); + treeWidget->setObjectName(QStringLiteral("treeWidget")); treeWidget->setTextElideMode(Qt::ElideNone); vboxLayout->addWidget(treeWidget); message = new QLabel(PluginDialog); - message->setObjectName(QString::fromUtf8("message")); + message->setObjectName(QStringLiteral("message")); message->setWordWrap(true); vboxLayout->addWidget(message); hboxLayout = new QHBoxLayout(); hboxLayout->setSpacing(6); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); hboxLayout->setContentsMargins(0, 0, 0, 0); vboxLayout->addLayout(hboxLayout); buttonBox = new QDialogButtonBox(PluginDialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Close); diff --git a/tests/auto/tools/uic/baseline/preferencesdialog.ui.h b/tests/auto/tools/uic/baseline/preferencesdialog.ui.h index 65ecc359b4c..287ccd730da 100644 --- a/tests/auto/tools/uic/baseline/preferencesdialog.ui.h +++ b/tests/auto/tools/uic/baseline/preferencesdialog.ui.h @@ -57,21 +57,21 @@ public: void setupUi(QDialog *PreferencesDialog) { if (PreferencesDialog->objectName().isEmpty()) - PreferencesDialog->setObjectName(QString::fromUtf8("PreferencesDialog")); + PreferencesDialog->setObjectName(QStringLiteral("PreferencesDialog")); PreferencesDialog->resize(455, 359); PreferencesDialog->setModal(true); vboxLayout = new QVBoxLayout(PreferencesDialog); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); hboxLayout = new QHBoxLayout(); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); vboxLayout1 = new QVBoxLayout(); - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); m_uiModeGroupBox = new QGroupBox(PreferencesDialog); - m_uiModeGroupBox->setObjectName(QString::fromUtf8("m_uiModeGroupBox")); + m_uiModeGroupBox->setObjectName(QStringLiteral("m_uiModeGroupBox")); vboxLayout2 = new QVBoxLayout(m_uiModeGroupBox); - vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2")); + vboxLayout2->setObjectName(QStringLiteral("vboxLayout2")); m_uiModeCombo = new QComboBox(m_uiModeGroupBox); - m_uiModeCombo->setObjectName(QString::fromUtf8("m_uiModeCombo")); + m_uiModeCombo->setObjectName(QStringLiteral("m_uiModeCombo")); vboxLayout2->addWidget(m_uiModeCombo); @@ -79,12 +79,12 @@ public: vboxLayout1->addWidget(m_uiModeGroupBox); m_fontPanel = new FontPanel(PreferencesDialog); - m_fontPanel->setObjectName(QString::fromUtf8("m_fontPanel")); + m_fontPanel->setObjectName(QStringLiteral("m_fontPanel")); vboxLayout1->addWidget(m_fontPanel); m_previewConfigurationWidget = new qdesigner_internal::PreviewConfigurationWidget(PreferencesDialog); - m_previewConfigurationWidget->setObjectName(QString::fromUtf8("m_previewConfigurationWidget")); + m_previewConfigurationWidget->setObjectName(QStringLiteral("m_previewConfigurationWidget")); vboxLayout1->addWidget(m_previewConfigurationWidget); @@ -92,23 +92,23 @@ public: hboxLayout->addLayout(vboxLayout1); vboxLayout3 = new QVBoxLayout(); - vboxLayout3->setObjectName(QString::fromUtf8("vboxLayout3")); + vboxLayout3->setObjectName(QStringLiteral("vboxLayout3")); m_templatePathGroupBox = new QGroupBox(PreferencesDialog); - m_templatePathGroupBox->setObjectName(QString::fromUtf8("m_templatePathGroupBox")); + m_templatePathGroupBox->setObjectName(QStringLiteral("m_templatePathGroupBox")); gridLayout = new QGridLayout(m_templatePathGroupBox); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); m_templatePathListWidget = new QListWidget(m_templatePathGroupBox); - m_templatePathListWidget->setObjectName(QString::fromUtf8("m_templatePathListWidget")); + m_templatePathListWidget->setObjectName(QStringLiteral("m_templatePathListWidget")); gridLayout->addWidget(m_templatePathListWidget, 0, 0, 1, 3); m_addTemplatePathButton = new QToolButton(m_templatePathGroupBox); - m_addTemplatePathButton->setObjectName(QString::fromUtf8("m_addTemplatePathButton")); + m_addTemplatePathButton->setObjectName(QStringLiteral("m_addTemplatePathButton")); gridLayout->addWidget(m_addTemplatePathButton, 1, 0, 1, 1); m_removeTemplatePathButton = new QToolButton(m_templatePathGroupBox); - m_removeTemplatePathButton->setObjectName(QString::fromUtf8("m_removeTemplatePathButton")); + m_removeTemplatePathButton->setObjectName(QStringLiteral("m_removeTemplatePathButton")); gridLayout->addWidget(m_removeTemplatePathButton, 1, 1, 1, 1); @@ -120,7 +120,7 @@ public: vboxLayout3->addWidget(m_templatePathGroupBox); m_gridPanel = new qdesigner_internal::GridPanel(PreferencesDialog); - m_gridPanel->setObjectName(QString::fromUtf8("m_gridPanel")); + m_gridPanel->setObjectName(QStringLiteral("m_gridPanel")); vboxLayout3->addWidget(m_gridPanel); @@ -131,14 +131,14 @@ public: vboxLayout->addLayout(hboxLayout); line = new QFrame(PreferencesDialog); - line->setObjectName(QString::fromUtf8("line")); + line->setObjectName(QStringLiteral("line")); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); vboxLayout->addWidget(line); m_dialogButtonBox = new QDialogButtonBox(PreferencesDialog); - m_dialogButtonBox->setObjectName(QString::fromUtf8("m_dialogButtonBox")); + m_dialogButtonBox->setObjectName(QStringLiteral("m_dialogButtonBox")); m_dialogButtonBox->setOrientation(Qt::Horizontal); m_dialogButtonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/previewconfigurationwidget.ui.h b/tests/auto/tools/uic/baseline/previewconfigurationwidget.ui.h index 3392d6f220d..1bdf1a049bb 100644 --- a/tests/auto/tools/uic/baseline/previewconfigurationwidget.ui.h +++ b/tests/auto/tools/uic/baseline/previewconfigurationwidget.ui.h @@ -44,40 +44,40 @@ public: void setupUi(QGroupBox *PreviewConfigurationWidget) { if (PreviewConfigurationWidget->objectName().isEmpty()) - PreviewConfigurationWidget->setObjectName(QString::fromUtf8("PreviewConfigurationWidget")); + PreviewConfigurationWidget->setObjectName(QStringLiteral("PreviewConfigurationWidget")); PreviewConfigurationWidget->setCheckable(true); formLayout = new QFormLayout(PreviewConfigurationWidget); - formLayout->setObjectName(QString::fromUtf8("formLayout")); + formLayout->setObjectName(QStringLiteral("formLayout")); m_styleLabel = new QLabel(PreviewConfigurationWidget); - m_styleLabel->setObjectName(QString::fromUtf8("m_styleLabel")); + m_styleLabel->setObjectName(QStringLiteral("m_styleLabel")); formLayout->setWidget(0, QFormLayout::LabelRole, m_styleLabel); m_styleCombo = new QComboBox(PreviewConfigurationWidget); - m_styleCombo->setObjectName(QString::fromUtf8("m_styleCombo")); + m_styleCombo->setObjectName(QStringLiteral("m_styleCombo")); formLayout->setWidget(0, QFormLayout::FieldRole, m_styleCombo); m_appStyleSheetLabel = new QLabel(PreviewConfigurationWidget); - m_appStyleSheetLabel->setObjectName(QString::fromUtf8("m_appStyleSheetLabel")); + m_appStyleSheetLabel->setObjectName(QStringLiteral("m_appStyleSheetLabel")); formLayout->setWidget(1, QFormLayout::LabelRole, m_appStyleSheetLabel); hboxLayout = new QHBoxLayout(); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); m_appStyleSheetLineEdit = new qdesigner_internal::TextPropertyEditor(PreviewConfigurationWidget); - m_appStyleSheetLineEdit->setObjectName(QString::fromUtf8("m_appStyleSheetLineEdit")); + m_appStyleSheetLineEdit->setObjectName(QStringLiteral("m_appStyleSheetLineEdit")); m_appStyleSheetLineEdit->setMinimumSize(QSize(149, 0)); hboxLayout->addWidget(m_appStyleSheetLineEdit); m_appStyleSheetChangeButton = new QToolButton(PreviewConfigurationWidget); - m_appStyleSheetChangeButton->setObjectName(QString::fromUtf8("m_appStyleSheetChangeButton")); + m_appStyleSheetChangeButton->setObjectName(QStringLiteral("m_appStyleSheetChangeButton")); hboxLayout->addWidget(m_appStyleSheetChangeButton); m_appStyleSheetClearButton = new QToolButton(PreviewConfigurationWidget); - m_appStyleSheetClearButton->setObjectName(QString::fromUtf8("m_appStyleSheetClearButton")); + m_appStyleSheetClearButton->setObjectName(QStringLiteral("m_appStyleSheetClearButton")); hboxLayout->addWidget(m_appStyleSheetClearButton); @@ -85,19 +85,19 @@ public: formLayout->setLayout(1, QFormLayout::FieldRole, hboxLayout); m_skinLabel = new QLabel(PreviewConfigurationWidget); - m_skinLabel->setObjectName(QString::fromUtf8("m_skinLabel")); + m_skinLabel->setObjectName(QStringLiteral("m_skinLabel")); formLayout->setWidget(2, QFormLayout::LabelRole, m_skinLabel); hboxLayout1 = new QHBoxLayout(); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); m_skinCombo = new QComboBox(PreviewConfigurationWidget); - m_skinCombo->setObjectName(QString::fromUtf8("m_skinCombo")); + m_skinCombo->setObjectName(QStringLiteral("m_skinCombo")); hboxLayout1->addWidget(m_skinCombo); m_skinRemoveButton = new QToolButton(PreviewConfigurationWidget); - m_skinRemoveButton->setObjectName(QString::fromUtf8("m_skinRemoveButton")); + m_skinRemoveButton->setObjectName(QStringLiteral("m_skinRemoveButton")); hboxLayout1->addWidget(m_skinRemoveButton); diff --git a/tests/auto/tools/uic/baseline/previewdialogbase.ui.h b/tests/auto/tools/uic/baseline/previewdialogbase.ui.h index 43cd278d55a..c577324b5e6 100644 --- a/tests/auto/tools/uic/baseline/previewdialogbase.ui.h +++ b/tests/auto/tools/uic/baseline/previewdialogbase.ui.h @@ -48,7 +48,7 @@ public: void setupUi(QDialog *PreviewDialogBase) { if (PreviewDialogBase->objectName().isEmpty()) - PreviewDialogBase->setObjectName(QString::fromUtf8("PreviewDialogBase")); + PreviewDialogBase->setObjectName(QStringLiteral("PreviewDialogBase")); PreviewDialogBase->resize(733, 479); vboxLayout = new QVBoxLayout(PreviewDialogBase); #ifndef Q_OS_MAC @@ -57,7 +57,7 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); hboxLayout = new QHBoxLayout(); #ifndef Q_OS_MAC hboxLayout->setSpacing(6); @@ -65,14 +65,14 @@ public: #ifndef Q_OS_MAC hboxLayout->setContentsMargins(0, 0, 0, 0); #endif - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); label = new QLabel(PreviewDialogBase); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); hboxLayout->addWidget(label); paperSizeCombo = new QComboBox(PreviewDialogBase); - paperSizeCombo->setObjectName(QString::fromUtf8("paperSizeCombo")); + paperSizeCombo->setObjectName(QStringLiteral("paperSizeCombo")); QSizePolicy sizePolicy(static_cast(1), static_cast(0)); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -82,12 +82,12 @@ public: hboxLayout->addWidget(paperSizeCombo); label_2 = new QLabel(PreviewDialogBase); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); hboxLayout->addWidget(label_2); paperOrientationCombo = new QComboBox(PreviewDialogBase); - paperOrientationCombo->setObjectName(QString::fromUtf8("paperOrientationCombo")); + paperOrientationCombo->setObjectName(QStringLiteral("paperOrientationCombo")); sizePolicy.setHeightForWidth(paperOrientationCombo->sizePolicy().hasHeightForWidth()); paperOrientationCombo->setSizePolicy(sizePolicy); @@ -105,9 +105,9 @@ public: hboxLayout1->setSpacing(6); #endif hboxLayout1->setContentsMargins(0, 0, 0, 0); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); pageList = new QTreeWidget(PreviewDialogBase); - pageList->setObjectName(QString::fromUtf8("pageList")); + pageList->setObjectName(QStringLiteral("pageList")); pageList->setIndentation(0); pageList->setRootIsDecorated(false); pageList->setUniformRowHeights(true); @@ -117,7 +117,7 @@ public: hboxLayout1->addWidget(pageList); previewArea = new QScrollArea(PreviewDialogBase); - previewArea->setObjectName(QString::fromUtf8("previewArea")); + previewArea->setObjectName(QStringLiteral("previewArea")); QSizePolicy sizePolicy1(static_cast(5), static_cast(5)); sizePolicy1.setHorizontalStretch(1); sizePolicy1.setVerticalStretch(0); @@ -134,9 +134,9 @@ public: hboxLayout2->setSpacing(6); #endif hboxLayout2->setContentsMargins(0, 0, 0, 0); - hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2")); + hboxLayout2->setObjectName(QStringLiteral("hboxLayout2")); progressBar = new QProgressBar(PreviewDialogBase); - progressBar->setObjectName(QString::fromUtf8("progressBar")); + progressBar->setObjectName(QStringLiteral("progressBar")); progressBar->setEnabled(false); QSizePolicy sizePolicy2(static_cast(7), static_cast(0)); sizePolicy2.setHorizontalStretch(1); @@ -150,7 +150,7 @@ public: hboxLayout2->addWidget(progressBar); buttonBox = new QDialogButtonBox(PreviewDialogBase); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/previewwidget.ui.h b/tests/auto/tools/uic/baseline/previewwidget.ui.h index 9fd79688f20..9997353ac81 100644 --- a/tests/auto/tools/uic/baseline/previewwidget.ui.h +++ b/tests/auto/tools/uic/baseline/previewwidget.ui.h @@ -107,7 +107,7 @@ public: void setupUi(QWidget *qdesigner_internal__PreviewWidget) { if (qdesigner_internal__PreviewWidget->objectName().isEmpty()) - qdesigner_internal__PreviewWidget->setObjectName(QString::fromUtf8("qdesigner_internal__PreviewWidget")); + qdesigner_internal__PreviewWidget->setObjectName(QStringLiteral("qdesigner_internal__PreviewWidget")); qdesigner_internal__PreviewWidget->resize(471, 251); QSizePolicy sizePolicy(static_cast(1), static_cast(1)); sizePolicy.setHorizontalStretch(0); @@ -121,7 +121,7 @@ public: #ifndef Q_OS_MAC gridLayout->setContentsMargins(9, 9, 9, 9); #endif - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); vboxLayout = new QVBoxLayout(); #ifndef Q_OS_MAC vboxLayout->setSpacing(6); @@ -129,14 +129,14 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(0, 0, 0, 0); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); LineEdit1 = new QLineEdit(qdesigner_internal__PreviewWidget); - LineEdit1->setObjectName(QString::fromUtf8("LineEdit1")); + LineEdit1->setObjectName(QStringLiteral("LineEdit1")); vboxLayout->addWidget(LineEdit1); ComboBox1 = new QComboBox(qdesigner_internal__PreviewWidget); - ComboBox1->setObjectName(QString::fromUtf8("ComboBox1")); + ComboBox1->setObjectName(QStringLiteral("ComboBox1")); vboxLayout->addWidget(ComboBox1); @@ -145,14 +145,14 @@ public: hboxLayout->setSpacing(6); #endif hboxLayout->setContentsMargins(0, 0, 0, 0); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); SpinBox1 = new QSpinBox(qdesigner_internal__PreviewWidget); - SpinBox1->setObjectName(QString::fromUtf8("SpinBox1")); + SpinBox1->setObjectName(QStringLiteral("SpinBox1")); hboxLayout->addWidget(SpinBox1); PushButton1 = new QPushButton(qdesigner_internal__PreviewWidget); - PushButton1->setObjectName(QString::fromUtf8("PushButton1")); + PushButton1->setObjectName(QStringLiteral("PushButton1")); hboxLayout->addWidget(PushButton1); @@ -160,19 +160,19 @@ public: vboxLayout->addLayout(hboxLayout); ScrollBar1 = new QScrollBar(qdesigner_internal__PreviewWidget); - ScrollBar1->setObjectName(QString::fromUtf8("ScrollBar1")); + ScrollBar1->setObjectName(QStringLiteral("ScrollBar1")); ScrollBar1->setOrientation(Qt::Horizontal); vboxLayout->addWidget(ScrollBar1); Slider1 = new QSlider(qdesigner_internal__PreviewWidget); - Slider1->setObjectName(QString::fromUtf8("Slider1")); + Slider1->setObjectName(QStringLiteral("Slider1")); Slider1->setOrientation(Qt::Horizontal); vboxLayout->addWidget(Slider1); listWidget = new QListWidget(qdesigner_internal__PreviewWidget); - listWidget->setObjectName(QString::fromUtf8("listWidget")); + listWidget->setObjectName(QStringLiteral("listWidget")); listWidget->setMaximumSize(QSize(32767, 50)); vboxLayout->addWidget(listWidget); @@ -185,13 +185,13 @@ public: gridLayout->addItem(spacerItem, 3, 0, 1, 2); ProgressBar1 = new QProgressBar(qdesigner_internal__PreviewWidget); - ProgressBar1->setObjectName(QString::fromUtf8("ProgressBar1")); + ProgressBar1->setObjectName(QStringLiteral("ProgressBar1")); ProgressBar1->setOrientation(Qt::Horizontal); gridLayout->addWidget(ProgressBar1, 2, 0, 1, 1); ButtonGroup2 = new QGroupBox(qdesigner_internal__PreviewWidget); - ButtonGroup2->setObjectName(QString::fromUtf8("ButtonGroup2")); + ButtonGroup2->setObjectName(QStringLiteral("ButtonGroup2")); vboxLayout1 = new QVBoxLayout(ButtonGroup2); #ifndef Q_OS_MAC vboxLayout1->setSpacing(6); @@ -199,15 +199,15 @@ public: #ifndef Q_OS_MAC vboxLayout1->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); CheckBox1 = new QCheckBox(ButtonGroup2); - CheckBox1->setObjectName(QString::fromUtf8("CheckBox1")); + CheckBox1->setObjectName(QStringLiteral("CheckBox1")); CheckBox1->setChecked(true); vboxLayout1->addWidget(CheckBox1); CheckBox2 = new QCheckBox(ButtonGroup2); - CheckBox2->setObjectName(QString::fromUtf8("CheckBox2")); + CheckBox2->setObjectName(QStringLiteral("CheckBox2")); vboxLayout1->addWidget(CheckBox2); @@ -215,7 +215,7 @@ public: gridLayout->addWidget(ButtonGroup2, 1, 0, 1, 1); ButtonGroup1 = new QGroupBox(qdesigner_internal__PreviewWidget); - ButtonGroup1->setObjectName(QString::fromUtf8("ButtonGroup1")); + ButtonGroup1->setObjectName(QStringLiteral("ButtonGroup1")); vboxLayout2 = new QVBoxLayout(ButtonGroup1); #ifndef Q_OS_MAC vboxLayout2->setSpacing(6); @@ -223,20 +223,20 @@ public: #ifndef Q_OS_MAC vboxLayout2->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2")); + vboxLayout2->setObjectName(QStringLiteral("vboxLayout2")); RadioButton1 = new QRadioButton(ButtonGroup1); - RadioButton1->setObjectName(QString::fromUtf8("RadioButton1")); + RadioButton1->setObjectName(QStringLiteral("RadioButton1")); RadioButton1->setChecked(true); vboxLayout2->addWidget(RadioButton1); RadioButton2 = new QRadioButton(ButtonGroup1); - RadioButton2->setObjectName(QString::fromUtf8("RadioButton2")); + RadioButton2->setObjectName(QStringLiteral("RadioButton2")); vboxLayout2->addWidget(RadioButton2); RadioButton3 = new QRadioButton(ButtonGroup1); - RadioButton3->setObjectName(QString::fromUtf8("RadioButton3")); + RadioButton3->setObjectName(QStringLiteral("RadioButton3")); vboxLayout2->addWidget(RadioButton3); diff --git a/tests/auto/tools/uic/baseline/proxy.ui.h b/tests/auto/tools/uic/baseline/proxy.ui.h index 592f1a91e31..9be6b97b81f 100644 --- a/tests/auto/tools/uic/baseline/proxy.ui.h +++ b/tests/auto/tools/uic/baseline/proxy.ui.h @@ -38,44 +38,44 @@ public: void setupUi(QDialog *ProxyDialog) { if (ProxyDialog->objectName().isEmpty()) - ProxyDialog->setObjectName(QString::fromUtf8("ProxyDialog")); + ProxyDialog->setObjectName(QStringLiteral("ProxyDialog")); ProxyDialog->resize(369, 144); gridLayout = new QGridLayout(ProxyDialog); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); iconLabel = new QLabel(ProxyDialog); - iconLabel->setObjectName(QString::fromUtf8("iconLabel")); + iconLabel->setObjectName(QStringLiteral("iconLabel")); gridLayout->addWidget(iconLabel, 0, 0, 1, 1); introLabel = new QLabel(ProxyDialog); - introLabel->setObjectName(QString::fromUtf8("introLabel")); + introLabel->setObjectName(QStringLiteral("introLabel")); introLabel->setWordWrap(true); gridLayout->addWidget(introLabel, 0, 1, 1, 2); usernameLabel = new QLabel(ProxyDialog); - usernameLabel->setObjectName(QString::fromUtf8("usernameLabel")); + usernameLabel->setObjectName(QStringLiteral("usernameLabel")); gridLayout->addWidget(usernameLabel, 1, 0, 1, 2); userNameLineEdit = new QLineEdit(ProxyDialog); - userNameLineEdit->setObjectName(QString::fromUtf8("userNameLineEdit")); + userNameLineEdit->setObjectName(QStringLiteral("userNameLineEdit")); gridLayout->addWidget(userNameLineEdit, 1, 2, 1, 1); passwordLabel = new QLabel(ProxyDialog); - passwordLabel->setObjectName(QString::fromUtf8("passwordLabel")); + passwordLabel->setObjectName(QStringLiteral("passwordLabel")); gridLayout->addWidget(passwordLabel, 2, 0, 1, 2); passwordLineEdit = new QLineEdit(ProxyDialog); - passwordLineEdit->setObjectName(QString::fromUtf8("passwordLineEdit")); + passwordLineEdit->setObjectName(QStringLiteral("passwordLineEdit")); passwordLineEdit->setEchoMode(QLineEdit::Password); gridLayout->addWidget(passwordLineEdit, 2, 2, 1, 1); buttonBox = new QDialogButtonBox(ProxyDialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/qfiledialog.ui.h b/tests/auto/tools/uic/baseline/qfiledialog.ui.h index 62030018cb6..848e07db974 100644 --- a/tests/auto/tools/uic/baseline/qfiledialog.ui.h +++ b/tests/auto/tools/uic/baseline/qfiledialog.ui.h @@ -108,20 +108,20 @@ public: void setupUi(QDialog *QFileDialog) { if (QFileDialog->objectName().isEmpty()) - QFileDialog->setObjectName(QString::fromUtf8("QFileDialog")); + QFileDialog->setObjectName(QStringLiteral("QFileDialog")); QFileDialog->resize(521, 316); QFileDialog->setSizeGripEnabled(true); gridLayout = new QGridLayout(QFileDialog); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); lookInLabel = new QLabel(QFileDialog); - lookInLabel->setObjectName(QString::fromUtf8("lookInLabel")); + lookInLabel->setObjectName(QStringLiteral("lookInLabel")); gridLayout->addWidget(lookInLabel, 0, 0, 1, 1); hboxLayout = new QHBoxLayout(); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); lookInCombo = new QFileDialogComboBox(QFileDialog); - lookInCombo->setObjectName(QString::fromUtf8("lookInCombo")); + lookInCombo->setObjectName(QStringLiteral("lookInCombo")); QSizePolicy sizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); sizePolicy.setHorizontalStretch(1); sizePolicy.setVerticalStretch(0); @@ -132,32 +132,32 @@ public: hboxLayout->addWidget(lookInCombo); backButton = new QToolButton(QFileDialog); - backButton->setObjectName(QString::fromUtf8("backButton")); + backButton->setObjectName(QStringLiteral("backButton")); hboxLayout->addWidget(backButton); forwardButton = new QToolButton(QFileDialog); - forwardButton->setObjectName(QString::fromUtf8("forwardButton")); + forwardButton->setObjectName(QStringLiteral("forwardButton")); hboxLayout->addWidget(forwardButton); toParentButton = new QToolButton(QFileDialog); - toParentButton->setObjectName(QString::fromUtf8("toParentButton")); + toParentButton->setObjectName(QStringLiteral("toParentButton")); hboxLayout->addWidget(toParentButton); newFolderButton = new QToolButton(QFileDialog); - newFolderButton->setObjectName(QString::fromUtf8("newFolderButton")); + newFolderButton->setObjectName(QStringLiteral("newFolderButton")); hboxLayout->addWidget(newFolderButton); listModeButton = new QToolButton(QFileDialog); - listModeButton->setObjectName(QString::fromUtf8("listModeButton")); + listModeButton->setObjectName(QStringLiteral("listModeButton")); hboxLayout->addWidget(listModeButton); detailModeButton = new QToolButton(QFileDialog); - detailModeButton->setObjectName(QString::fromUtf8("detailModeButton")); + detailModeButton->setObjectName(QStringLiteral("detailModeButton")); hboxLayout->addWidget(detailModeButton); @@ -165,7 +165,7 @@ public: gridLayout->addLayout(hboxLayout, 0, 1, 1, 2); splitter = new QSplitter(QFileDialog); - splitter->setObjectName(QString::fromUtf8("splitter")); + splitter->setObjectName(QStringLiteral("splitter")); QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Expanding); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); @@ -173,38 +173,38 @@ public: splitter->setSizePolicy(sizePolicy1); splitter->setOrientation(Qt::Horizontal); sidebar = new QSidebar(splitter); - sidebar->setObjectName(QString::fromUtf8("sidebar")); + sidebar->setObjectName(QStringLiteral("sidebar")); splitter->addWidget(sidebar); frame = new QFrame(splitter); - frame->setObjectName(QString::fromUtf8("frame")); + frame->setObjectName(QStringLiteral("frame")); frame->setFrameShape(QFrame::NoFrame); frame->setFrameShadow(QFrame::Raised); vboxLayout = new QVBoxLayout(frame); vboxLayout->setSpacing(0); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); vboxLayout->setContentsMargins(0, 0, 0, 0); stackedWidget = new QStackedWidget(frame); - stackedWidget->setObjectName(QString::fromUtf8("stackedWidget")); + stackedWidget->setObjectName(QStringLiteral("stackedWidget")); page = new QWidget(); - page->setObjectName(QString::fromUtf8("page")); + page->setObjectName(QStringLiteral("page")); vboxLayout1 = new QVBoxLayout(page); vboxLayout1->setSpacing(0); - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); vboxLayout1->setContentsMargins(0, 0, 0, 0); listView = new QFileDialogListView(page); - listView->setObjectName(QString::fromUtf8("listView")); + listView->setObjectName(QStringLiteral("listView")); vboxLayout1->addWidget(listView); stackedWidget->addWidget(page); page_2 = new QWidget(); - page_2->setObjectName(QString::fromUtf8("page_2")); + page_2->setObjectName(QStringLiteral("page_2")); vboxLayout2 = new QVBoxLayout(page_2); vboxLayout2->setSpacing(0); - vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2")); + vboxLayout2->setObjectName(QStringLiteral("vboxLayout2")); vboxLayout2->setContentsMargins(0, 0, 0, 0); treeView = new QFileDialogTreeView(page_2); - treeView->setObjectName(QString::fromUtf8("treeView")); + treeView->setObjectName(QStringLiteral("treeView")); vboxLayout2->addWidget(treeView); @@ -217,7 +217,7 @@ public: gridLayout->addWidget(splitter, 1, 0, 1, 3); fileNameLabel = new QLabel(QFileDialog); - fileNameLabel->setObjectName(QString::fromUtf8("fileNameLabel")); + fileNameLabel->setObjectName(QStringLiteral("fileNameLabel")); QSizePolicy sizePolicy2(QSizePolicy::Minimum, QSizePolicy::Preferred); sizePolicy2.setHorizontalStretch(0); sizePolicy2.setVerticalStretch(0); @@ -228,7 +228,7 @@ public: gridLayout->addWidget(fileNameLabel, 2, 0, 1, 1); fileNameEdit = new QFileDialogLineEdit(QFileDialog); - fileNameEdit->setObjectName(QString::fromUtf8("fileNameEdit")); + fileNameEdit->setObjectName(QStringLiteral("fileNameEdit")); QSizePolicy sizePolicy3(QSizePolicy::Expanding, QSizePolicy::Fixed); sizePolicy3.setHorizontalStretch(1); sizePolicy3.setVerticalStretch(0); @@ -238,14 +238,14 @@ public: gridLayout->addWidget(fileNameEdit, 2, 1, 1, 1); buttonBox = new QDialogButtonBox(QFileDialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Vertical); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok); gridLayout->addWidget(buttonBox, 2, 2, 2, 1); fileTypeLabel = new QLabel(QFileDialog); - fileTypeLabel->setObjectName(QString::fromUtf8("fileTypeLabel")); + fileTypeLabel->setObjectName(QStringLiteral("fileTypeLabel")); QSizePolicy sizePolicy4(QSizePolicy::Preferred, QSizePolicy::Fixed); sizePolicy4.setHorizontalStretch(0); sizePolicy4.setVerticalStretch(0); @@ -255,7 +255,7 @@ public: gridLayout->addWidget(fileTypeLabel, 3, 0, 1, 1); fileTypeCombo = new QComboBox(QFileDialog); - fileTypeCombo->setObjectName(QString::fromUtf8("fileTypeCombo")); + fileTypeCombo->setObjectName(QStringLiteral("fileTypeCombo")); QSizePolicy sizePolicy5(QSizePolicy::Expanding, QSizePolicy::Fixed); sizePolicy5.setHorizontalStretch(0); sizePolicy5.setVerticalStretch(0); diff --git a/tests/auto/tools/uic/baseline/qpagesetupwidget.ui.h b/tests/auto/tools/uic/baseline/qpagesetupwidget.ui.h index 8e0cc0a82a1..5a14eafc904 100644 --- a/tests/auto/tools/uic/baseline/qpagesetupwidget.ui.h +++ b/tests/auto/tools/uic/baseline/qpagesetupwidget.ui.h @@ -73,15 +73,15 @@ public: void setupUi(QWidget *QPageSetupWidget) { if (QPageSetupWidget->objectName().isEmpty()) - QPageSetupWidget->setObjectName(QString::fromUtf8("QPageSetupWidget")); + QPageSetupWidget->setObjectName(QStringLiteral("QPageSetupWidget")); QPageSetupWidget->resize(416, 488); gridLayout_3 = new QGridLayout(QPageSetupWidget); gridLayout_3->setContentsMargins(0, 0, 0, 0); - gridLayout_3->setObjectName(QString::fromUtf8("gridLayout_3")); + gridLayout_3->setObjectName(QStringLiteral("gridLayout_3")); horizontalLayout_4 = new QHBoxLayout(); - horizontalLayout_4->setObjectName(QString::fromUtf8("horizontalLayout_4")); + horizontalLayout_4->setObjectName(QStringLiteral("horizontalLayout_4")); unit = new QComboBox(QPageSetupWidget); - unit->setObjectName(QString::fromUtf8("unit")); + unit->setObjectName(QStringLiteral("unit")); horizontalLayout_4->addWidget(unit); @@ -93,39 +93,39 @@ public: gridLayout_3->addLayout(horizontalLayout_4, 0, 0, 1, 2); groupBox_2 = new QGroupBox(QPageSetupWidget); - groupBox_2->setObjectName(QString::fromUtf8("groupBox_2")); + groupBox_2->setObjectName(QStringLiteral("groupBox_2")); gridLayout_2 = new QGridLayout(groupBox_2); - gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2")); + gridLayout_2->setObjectName(QStringLiteral("gridLayout_2")); pageSizeLabel = new QLabel(groupBox_2); - pageSizeLabel->setObjectName(QString::fromUtf8("pageSizeLabel")); + pageSizeLabel->setObjectName(QStringLiteral("pageSizeLabel")); gridLayout_2->addWidget(pageSizeLabel, 0, 0, 1, 1); paperSize = new QComboBox(groupBox_2); - paperSize->setObjectName(QString::fromUtf8("paperSize")); + paperSize->setObjectName(QStringLiteral("paperSize")); gridLayout_2->addWidget(paperSize, 0, 1, 1, 1); widthLabel = new QLabel(groupBox_2); - widthLabel->setObjectName(QString::fromUtf8("widthLabel")); + widthLabel->setObjectName(QStringLiteral("widthLabel")); gridLayout_2->addWidget(widthLabel, 1, 0, 1, 1); horizontalLayout_3 = new QHBoxLayout(); - horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3")); + horizontalLayout_3->setObjectName(QStringLiteral("horizontalLayout_3")); paperWidth = new QDoubleSpinBox(groupBox_2); - paperWidth->setObjectName(QString::fromUtf8("paperWidth")); + paperWidth->setObjectName(QStringLiteral("paperWidth")); paperWidth->setMaximum(9999.99); horizontalLayout_3->addWidget(paperWidth); heightLabel = new QLabel(groupBox_2); - heightLabel->setObjectName(QString::fromUtf8("heightLabel")); + heightLabel->setObjectName(QStringLiteral("heightLabel")); horizontalLayout_3->addWidget(heightLabel); paperHeight = new QDoubleSpinBox(groupBox_2); - paperHeight->setObjectName(QString::fromUtf8("paperHeight")); + paperHeight->setObjectName(QStringLiteral("paperHeight")); paperHeight->setMaximum(9999.99); horizontalLayout_3->addWidget(paperHeight); @@ -134,12 +134,12 @@ public: gridLayout_2->addLayout(horizontalLayout_3, 1, 1, 1, 1); paperSourceLabel = new QLabel(groupBox_2); - paperSourceLabel->setObjectName(QString::fromUtf8("paperSourceLabel")); + paperSourceLabel->setObjectName(QStringLiteral("paperSourceLabel")); gridLayout_2->addWidget(paperSourceLabel, 2, 0, 1, 1); paperSource = new QComboBox(groupBox_2); - paperSource->setObjectName(QString::fromUtf8("paperSource")); + paperSource->setObjectName(QStringLiteral("paperSource")); gridLayout_2->addWidget(paperSource, 2, 1, 1, 1); @@ -151,27 +151,27 @@ public: gridLayout_3->addWidget(groupBox_2, 1, 0, 1, 2); groupBox_3 = new QGroupBox(QPageSetupWidget); - groupBox_3->setObjectName(QString::fromUtf8("groupBox_3")); + groupBox_3->setObjectName(QStringLiteral("groupBox_3")); verticalLayout = new QVBoxLayout(groupBox_3); - verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); portrait = new QRadioButton(groupBox_3); - portrait->setObjectName(QString::fromUtf8("portrait")); + portrait->setObjectName(QStringLiteral("portrait")); portrait->setChecked(true); verticalLayout->addWidget(portrait); landscape = new QRadioButton(groupBox_3); - landscape->setObjectName(QString::fromUtf8("landscape")); + landscape->setObjectName(QStringLiteral("landscape")); verticalLayout->addWidget(landscape); reverseLandscape = new QRadioButton(groupBox_3); - reverseLandscape->setObjectName(QString::fromUtf8("reverseLandscape")); + reverseLandscape->setObjectName(QStringLiteral("reverseLandscape")); verticalLayout->addWidget(reverseLandscape); reversePortrait = new QRadioButton(groupBox_3); - reversePortrait->setObjectName(QString::fromUtf8("reversePortrait")); + reversePortrait->setObjectName(QStringLiteral("reversePortrait")); verticalLayout->addWidget(reversePortrait); @@ -183,31 +183,31 @@ public: gridLayout_3->addWidget(groupBox_3, 2, 0, 1, 1); preview = new QWidget(QPageSetupWidget); - preview->setObjectName(QString::fromUtf8("preview")); + preview->setObjectName(QStringLiteral("preview")); gridLayout_3->addWidget(preview, 2, 1, 2, 1); groupBox = new QGroupBox(QPageSetupWidget); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); horizontalLayout_2 = new QHBoxLayout(groupBox); - horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2")); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); gridLayout = new QGridLayout(); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); topMargin = new QDoubleSpinBox(groupBox); - topMargin->setObjectName(QString::fromUtf8("topMargin")); + topMargin->setObjectName(QStringLiteral("topMargin")); topMargin->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); topMargin->setMaximum(999.99); gridLayout->addWidget(topMargin, 0, 1, 1, 1); horizontalLayout = new QHBoxLayout(); - horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); horizontalSpacer_7 = new QSpacerItem(0, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout->addItem(horizontalSpacer_7); leftMargin = new QDoubleSpinBox(groupBox); - leftMargin->setObjectName(QString::fromUtf8("leftMargin")); + leftMargin->setObjectName(QStringLiteral("leftMargin")); leftMargin->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); leftMargin->setMaximum(999.99); @@ -218,7 +218,7 @@ public: horizontalLayout->addItem(horizontalSpacer); rightMargin = new QDoubleSpinBox(groupBox); - rightMargin->setObjectName(QString::fromUtf8("rightMargin")); + rightMargin->setObjectName(QStringLiteral("rightMargin")); rightMargin->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); rightMargin->setMaximum(999.99); @@ -232,7 +232,7 @@ public: gridLayout->addLayout(horizontalLayout, 1, 0, 1, 3); bottomMargin = new QDoubleSpinBox(groupBox); - bottomMargin->setObjectName(QString::fromUtf8("bottomMargin")); + bottomMargin->setObjectName(QStringLiteral("bottomMargin")); bottomMargin->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); bottomMargin->setMaximum(999.99); diff --git a/tests/auto/tools/uic/baseline/qprintpropertieswidget.ui.h b/tests/auto/tools/uic/baseline/qprintpropertieswidget.ui.h index dd9b68f1c46..5cf337e75e1 100644 --- a/tests/auto/tools/uic/baseline/qprintpropertieswidget.ui.h +++ b/tests/auto/tools/uic/baseline/qprintpropertieswidget.ui.h @@ -39,30 +39,30 @@ public: void setupUi(QWidget *QPrintPropertiesWidget) { if (QPrintPropertiesWidget->objectName().isEmpty()) - QPrintPropertiesWidget->setObjectName(QString::fromUtf8("QPrintPropertiesWidget")); + QPrintPropertiesWidget->setObjectName(QStringLiteral("QPrintPropertiesWidget")); QPrintPropertiesWidget->resize(396, 288); verticalLayout_4 = new QVBoxLayout(QPrintPropertiesWidget); verticalLayout_4->setContentsMargins(0, 0, 0, 0); - verticalLayout_4->setObjectName(QString::fromUtf8("verticalLayout_4")); + verticalLayout_4->setObjectName(QStringLiteral("verticalLayout_4")); tabs = new QTabWidget(QPrintPropertiesWidget); - tabs->setObjectName(QString::fromUtf8("tabs")); + tabs->setObjectName(QStringLiteral("tabs")); tabPage = new QWidget(); - tabPage->setObjectName(QString::fromUtf8("tabPage")); + tabPage->setObjectName(QStringLiteral("tabPage")); tabPage->setGeometry(QRect(0, 0, 392, 261)); horizontalLayout = new QHBoxLayout(tabPage); - horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); pageSetup = new QPageSetupWidget(tabPage); - pageSetup->setObjectName(QString::fromUtf8("pageSetup")); + pageSetup->setObjectName(QStringLiteral("pageSetup")); horizontalLayout->addWidget(pageSetup); tabs->addTab(tabPage, QString()); cupsPropertiesPage = new QWidget(); - cupsPropertiesPage->setObjectName(QString::fromUtf8("cupsPropertiesPage")); + cupsPropertiesPage->setObjectName(QStringLiteral("cupsPropertiesPage")); horizontalLayout_2 = new QHBoxLayout(cupsPropertiesPage); - horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2")); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); treeView = new QTreeView(cupsPropertiesPage); - treeView->setObjectName(QString::fromUtf8("treeView")); + treeView->setObjectName(QStringLiteral("treeView")); treeView->setAlternatingRowColors(true); horizontalLayout_2->addWidget(treeView); diff --git a/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h b/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h index 2051c8b04d4..b10e44725ba 100644 --- a/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h +++ b/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h @@ -74,20 +74,20 @@ public: void setupUi(QWidget *QPrintSettingsOutput) { if (QPrintSettingsOutput->objectName().isEmpty()) - QPrintSettingsOutput->setObjectName(QString::fromUtf8("QPrintSettingsOutput")); + QPrintSettingsOutput->setObjectName(QStringLiteral("QPrintSettingsOutput")); QPrintSettingsOutput->resize(416, 166); horizontalLayout_2 = new QHBoxLayout(QPrintSettingsOutput); horizontalLayout_2->setContentsMargins(0, 0, 0, 0); - horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2")); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); tabs = new QTabWidget(QPrintSettingsOutput); - tabs->setObjectName(QString::fromUtf8("tabs")); + tabs->setObjectName(QStringLiteral("tabs")); copiesTab = new QWidget(); - copiesTab->setObjectName(QString::fromUtf8("copiesTab")); + copiesTab->setObjectName(QStringLiteral("copiesTab")); copiesTab->setGeometry(QRect(0, 0, 412, 139)); horizontalLayout = new QHBoxLayout(copiesTab); - horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); gbPrintRange = new QGroupBox(copiesTab); - gbPrintRange->setObjectName(QString::fromUtf8("gbPrintRange")); + gbPrintRange->setObjectName(QStringLiteral("gbPrintRange")); QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -96,9 +96,9 @@ public: _3 = new QVBoxLayout(gbPrintRange); _3->setSpacing(4); _3->setContentsMargins(6, 6, 6, 6); - _3->setObjectName(QString::fromUtf8("_3")); + _3->setObjectName(QStringLiteral("_3")); printAll = new QRadioButton(gbPrintRange); - printAll->setObjectName(QString::fromUtf8("printAll")); + printAll->setObjectName(QStringLiteral("printAll")); printAll->setChecked(true); _3->addWidget(printAll); @@ -108,14 +108,14 @@ public: _4->setSpacing(6); #endif _4->setContentsMargins(0, 0, 0, 0); - _4->setObjectName(QString::fromUtf8("_4")); + _4->setObjectName(QStringLiteral("_4")); printRange = new QRadioButton(gbPrintRange); - printRange->setObjectName(QString::fromUtf8("printRange")); + printRange->setObjectName(QStringLiteral("printRange")); _4->addWidget(printRange); from = new QSpinBox(gbPrintRange); - from->setObjectName(QString::fromUtf8("from")); + from->setObjectName(QStringLiteral("from")); from->setEnabled(false); from->setMinimum(1); from->setMaximum(999); @@ -123,12 +123,12 @@ public: _4->addWidget(from); label_3 = new QLabel(gbPrintRange); - label_3->setObjectName(QString::fromUtf8("label_3")); + label_3->setObjectName(QStringLiteral("label_3")); _4->addWidget(label_3); to = new QSpinBox(gbPrintRange); - to->setObjectName(QString::fromUtf8("to")); + to->setObjectName(QStringLiteral("to")); to->setEnabled(false); to->setMinimum(1); to->setMaximum(999); @@ -143,7 +143,7 @@ public: _3->addLayout(_4); printSelection = new QRadioButton(gbPrintRange); - printSelection->setObjectName(QString::fromUtf8("printSelection")); + printSelection->setObjectName(QStringLiteral("printSelection")); _3->addWidget(printSelection); @@ -155,16 +155,16 @@ public: horizontalLayout->addWidget(gbPrintRange); groupBox = new QGroupBox(copiesTab); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); gridLayout = new QGridLayout(groupBox); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); label = new QLabel(groupBox); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 0, 0, 1, 1); copies = new QSpinBox(groupBox); - copies->setObjectName(QString::fromUtf8("copies")); + copies->setObjectName(QStringLiteral("copies")); copies->setMinimum(1); copies->setMaximum(999); @@ -175,12 +175,12 @@ public: gridLayout->addItem(horizontalSpacer, 0, 3, 1, 1); collate = new QCheckBox(groupBox); - collate->setObjectName(QString::fromUtf8("collate")); + collate->setObjectName(QStringLiteral("collate")); gridLayout->addWidget(collate, 1, 0, 1, 2); outputIcon = new QLabel(groupBox); - outputIcon->setObjectName(QString::fromUtf8("outputIcon")); + outputIcon->setObjectName(QStringLiteral("outputIcon")); QSizePolicy sizePolicy1(QSizePolicy::Ignored, QSizePolicy::Ignored); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); @@ -190,7 +190,7 @@ public: gridLayout->addWidget(outputIcon, 1, 2, 2, 2); reverse = new QCheckBox(groupBox); - reverse->setObjectName(QString::fromUtf8("reverse")); + reverse->setObjectName(QStringLiteral("reverse")); gridLayout->addWidget(reverse, 2, 0, 1, 2); @@ -203,30 +203,30 @@ public: tabs->addTab(copiesTab, QString()); optionsTab = new QWidget(); - optionsTab->setObjectName(QString::fromUtf8("optionsTab")); + optionsTab->setObjectName(QStringLiteral("optionsTab")); optionsTab->setGeometry(QRect(0, 0, 412, 139)); gridLayout_2 = new QGridLayout(optionsTab); - gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2")); + gridLayout_2->setObjectName(QStringLiteral("gridLayout_2")); colorMode = new QGroupBox(optionsTab); - colorMode->setObjectName(QString::fromUtf8("colorMode")); + colorMode->setObjectName(QStringLiteral("colorMode")); gridLayout_4 = new QGridLayout(colorMode); - gridLayout_4->setObjectName(QString::fromUtf8("gridLayout_4")); + gridLayout_4->setObjectName(QStringLiteral("gridLayout_4")); verticalSpacer_6 = new QSpacerItem(1, 0, QSizePolicy::Minimum, QSizePolicy::Expanding); gridLayout_4->addItem(verticalSpacer_6, 2, 0, 1, 1); color = new QRadioButton(colorMode); - color->setObjectName(QString::fromUtf8("color")); + color->setObjectName(QStringLiteral("color")); gridLayout_4->addWidget(color, 0, 0, 1, 1); colorIcon = new QLabel(colorMode); - colorIcon->setObjectName(QString::fromUtf8("colorIcon")); + colorIcon->setObjectName(QStringLiteral("colorIcon")); gridLayout_4->addWidget(colorIcon, 0, 1, 3, 1); grayscale = new QRadioButton(colorMode); - grayscale->setObjectName(QString::fromUtf8("grayscale")); + grayscale->setObjectName(QStringLiteral("grayscale")); gridLayout_4->addWidget(grayscale, 1, 0, 1, 1); @@ -234,22 +234,22 @@ public: gridLayout_2->addWidget(colorMode, 0, 1, 1, 1); duplex = new QGroupBox(optionsTab); - duplex->setObjectName(QString::fromUtf8("duplex")); + duplex->setObjectName(QStringLiteral("duplex")); verticalLayout = new QVBoxLayout(duplex); - verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); noDuplex = new QRadioButton(duplex); - noDuplex->setObjectName(QString::fromUtf8("noDuplex")); + noDuplex->setObjectName(QStringLiteral("noDuplex")); noDuplex->setChecked(true); verticalLayout->addWidget(noDuplex); duplexLong = new QRadioButton(duplex); - duplexLong->setObjectName(QString::fromUtf8("duplexLong")); + duplexLong->setObjectName(QStringLiteral("duplexLong")); verticalLayout->addWidget(duplexLong); duplexShort = new QRadioButton(duplex); - duplexShort->setObjectName(QString::fromUtf8("duplexShort")); + duplexShort->setObjectName(QStringLiteral("duplexShort")); verticalLayout->addWidget(duplexShort); diff --git a/tests/auto/tools/uic/baseline/qprintwidget.ui.h b/tests/auto/tools/uic/baseline/qprintwidget.ui.h index 6389b61fc2c..206556cb1b1 100644 --- a/tests/auto/tools/uic/baseline/qprintwidget.ui.h +++ b/tests/auto/tools/uic/baseline/qprintwidget.ui.h @@ -50,22 +50,22 @@ public: void setupUi(QWidget *QPrintWidget) { if (QPrintWidget->objectName().isEmpty()) - QPrintWidget->setObjectName(QString::fromUtf8("QPrintWidget")); + QPrintWidget->setObjectName(QStringLiteral("QPrintWidget")); QPrintWidget->resize(443, 175); horizontalLayout_2 = new QHBoxLayout(QPrintWidget); horizontalLayout_2->setContentsMargins(0, 0, 0, 0); - horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2")); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); printerGroup = new QGroupBox(QPrintWidget); - printerGroup->setObjectName(QString::fromUtf8("printerGroup")); + printerGroup->setObjectName(QStringLiteral("printerGroup")); gridLayout = new QGridLayout(printerGroup); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); label = new QLabel(printerGroup); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 0, 0, 1, 1); printers = new QComboBox(printerGroup); - printers->setObjectName(QString::fromUtf8("printers")); + printers->setObjectName(QStringLiteral("printers")); QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); sizePolicy.setHorizontalStretch(3); sizePolicy.setVerticalStretch(0); @@ -75,7 +75,7 @@ public: gridLayout->addWidget(printers, 0, 1, 1, 1); properties = new QPushButton(printerGroup); - properties->setObjectName(QString::fromUtf8("properties")); + properties->setObjectName(QStringLiteral("properties")); QSizePolicy sizePolicy1(QSizePolicy::Minimum, QSizePolicy::Fixed); sizePolicy1.setHorizontalStretch(1); sizePolicy1.setVerticalStretch(0); @@ -85,44 +85,44 @@ public: gridLayout->addWidget(properties, 0, 2, 1, 1); label_2 = new QLabel(printerGroup); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); gridLayout->addWidget(label_2, 1, 0, 1, 1); location = new QLabel(printerGroup); - location->setObjectName(QString::fromUtf8("location")); + location->setObjectName(QStringLiteral("location")); gridLayout->addWidget(location, 1, 1, 1, 1); preview = new QCheckBox(printerGroup); - preview->setObjectName(QString::fromUtf8("preview")); + preview->setObjectName(QStringLiteral("preview")); gridLayout->addWidget(preview, 1, 2, 1, 1); label_3 = new QLabel(printerGroup); - label_3->setObjectName(QString::fromUtf8("label_3")); + label_3->setObjectName(QStringLiteral("label_3")); gridLayout->addWidget(label_3, 2, 0, 1, 1); type = new QLabel(printerGroup); - type->setObjectName(QString::fromUtf8("type")); + type->setObjectName(QStringLiteral("type")); gridLayout->addWidget(type, 2, 1, 1, 1); lOutput = new QLabel(printerGroup); - lOutput->setObjectName(QString::fromUtf8("lOutput")); + lOutput->setObjectName(QStringLiteral("lOutput")); gridLayout->addWidget(lOutput, 3, 0, 1, 1); horizontalLayout = new QHBoxLayout(); - horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); filename = new QLineEdit(printerGroup); - filename->setObjectName(QString::fromUtf8("filename")); + filename->setObjectName(QStringLiteral("filename")); horizontalLayout->addWidget(filename); fileBrowser = new QToolButton(printerGroup); - fileBrowser->setObjectName(QString::fromUtf8("fileBrowser")); + fileBrowser->setObjectName(QStringLiteral("fileBrowser")); horizontalLayout->addWidget(fileBrowser); diff --git a/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h b/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h index f784785ce00..ea957f16c82 100644 --- a/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h +++ b/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h @@ -59,44 +59,44 @@ public: void setupUi(QDialog *QSqlConnectionDialogUi) { if (QSqlConnectionDialogUi->objectName().isEmpty()) - QSqlConnectionDialogUi->setObjectName(QString::fromUtf8("QSqlConnectionDialogUi")); + QSqlConnectionDialogUi->setObjectName(QStringLiteral("QSqlConnectionDialogUi")); QSqlConnectionDialogUi->resize(315, 302); vboxLayout = new QVBoxLayout(QSqlConnectionDialogUi); #ifndef Q_OS_MAC vboxLayout->setSpacing(6); #endif vboxLayout->setContentsMargins(8, 8, 8, 8); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); connGroupBox = new QGroupBox(QSqlConnectionDialogUi); - connGroupBox->setObjectName(QString::fromUtf8("connGroupBox")); + connGroupBox->setObjectName(QStringLiteral("connGroupBox")); gridLayout = new QGridLayout(connGroupBox); #ifndef Q_OS_MAC gridLayout->setSpacing(6); #endif gridLayout->setContentsMargins(8, 8, 8, 8); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); comboDriver = new QComboBox(connGroupBox); - comboDriver->setObjectName(QString::fromUtf8("comboDriver")); + comboDriver->setObjectName(QStringLiteral("comboDriver")); gridLayout->addWidget(comboDriver, 0, 1, 1, 1); textLabel4 = new QLabel(connGroupBox); - textLabel4->setObjectName(QString::fromUtf8("textLabel4")); + textLabel4->setObjectName(QStringLiteral("textLabel4")); gridLayout->addWidget(textLabel4, 2, 0, 1, 1); textLabel2 = new QLabel(connGroupBox); - textLabel2->setObjectName(QString::fromUtf8("textLabel2")); + textLabel2->setObjectName(QStringLiteral("textLabel2")); gridLayout->addWidget(textLabel2, 0, 0, 1, 1); editDatabase = new QLineEdit(connGroupBox); - editDatabase->setObjectName(QString::fromUtf8("editDatabase")); + editDatabase->setObjectName(QStringLiteral("editDatabase")); gridLayout->addWidget(editDatabase, 1, 1, 1, 1); portSpinBox = new QSpinBox(connGroupBox); - portSpinBox->setObjectName(QString::fromUtf8("portSpinBox")); + portSpinBox->setObjectName(QStringLiteral("portSpinBox")); portSpinBox->setMaximum(65535); portSpinBox->setMinimum(-1); portSpinBox->setValue(-1); @@ -104,38 +104,38 @@ public: gridLayout->addWidget(portSpinBox, 5, 1, 1, 1); textLabel3 = new QLabel(connGroupBox); - textLabel3->setObjectName(QString::fromUtf8("textLabel3")); + textLabel3->setObjectName(QStringLiteral("textLabel3")); gridLayout->addWidget(textLabel3, 1, 0, 1, 1); editPassword = new QLineEdit(connGroupBox); - editPassword->setObjectName(QString::fromUtf8("editPassword")); + editPassword->setObjectName(QStringLiteral("editPassword")); editPassword->setEchoMode(QLineEdit::Password); gridLayout->addWidget(editPassword, 3, 1, 1, 1); editUsername = new QLineEdit(connGroupBox); - editUsername->setObjectName(QString::fromUtf8("editUsername")); + editUsername->setObjectName(QStringLiteral("editUsername")); gridLayout->addWidget(editUsername, 2, 1, 1, 1); editHostname = new QLineEdit(connGroupBox); - editHostname->setObjectName(QString::fromUtf8("editHostname")); + editHostname->setObjectName(QStringLiteral("editHostname")); gridLayout->addWidget(editHostname, 4, 1, 1, 1); textLabel5 = new QLabel(connGroupBox); - textLabel5->setObjectName(QString::fromUtf8("textLabel5")); + textLabel5->setObjectName(QStringLiteral("textLabel5")); gridLayout->addWidget(textLabel5, 4, 0, 1, 1); textLabel5_2 = new QLabel(connGroupBox); - textLabel5_2->setObjectName(QString::fromUtf8("textLabel5_2")); + textLabel5_2->setObjectName(QStringLiteral("textLabel5_2")); gridLayout->addWidget(textLabel5_2, 5, 0, 1, 1); textLabel4_2 = new QLabel(connGroupBox); - textLabel4_2->setObjectName(QString::fromUtf8("textLabel4_2")); + textLabel4_2->setObjectName(QStringLiteral("textLabel4_2")); gridLayout->addWidget(textLabel4_2, 3, 0, 1, 1); @@ -147,13 +147,13 @@ public: hboxLayout->setSpacing(6); #endif hboxLayout->setContentsMargins(0, 0, 0, 0); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); hboxLayout->addItem(spacerItem); dbCheckBox = new QCheckBox(QSqlConnectionDialogUi); - dbCheckBox->setObjectName(QString::fromUtf8("dbCheckBox")); + dbCheckBox->setObjectName(QStringLiteral("dbCheckBox")); hboxLayout->addWidget(dbCheckBox); @@ -165,19 +165,19 @@ public: hboxLayout1->setSpacing(6); #endif hboxLayout1->setContentsMargins(0, 0, 0, 0); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); spacerItem1 = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); hboxLayout1->addItem(spacerItem1); okButton = new QPushButton(QSqlConnectionDialogUi); - okButton->setObjectName(QString::fromUtf8("okButton")); + okButton->setObjectName(QStringLiteral("okButton")); okButton->setDefault(true); hboxLayout1->addWidget(okButton); cancelButton = new QPushButton(QSqlConnectionDialogUi); - cancelButton->setObjectName(QString::fromUtf8("cancelButton")); + cancelButton->setObjectName(QStringLiteral("cancelButton")); hboxLayout1->addWidget(cancelButton); diff --git a/tests/auto/tools/uic/baseline/qtgradientdialog.ui.h b/tests/auto/tools/uic/baseline/qtgradientdialog.ui.h index d9c27a769ec..45660d9224e 100644 --- a/tests/auto/tools/uic/baseline/qtgradientdialog.ui.h +++ b/tests/auto/tools/uic/baseline/qtgradientdialog.ui.h @@ -75,12 +75,12 @@ public: void setupUi(QDialog *QtGradientDialog) { if (QtGradientDialog->objectName().isEmpty()) - QtGradientDialog->setObjectName(QString::fromUtf8("QtGradientDialog")); + QtGradientDialog->setObjectName(QStringLiteral("QtGradientDialog")); QtGradientDialog->resize(178, 81); vboxLayout = new QVBoxLayout(QtGradientDialog); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); gradientEditor = new QtGradientEditor(QtGradientDialog); - gradientEditor->setObjectName(QString::fromUtf8("gradientEditor")); + gradientEditor->setObjectName(QStringLiteral("gradientEditor")); QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -90,7 +90,7 @@ public: vboxLayout->addWidget(gradientEditor); buttonBox = new QDialogButtonBox(QtGradientDialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/qtgradienteditor.ui.h b/tests/auto/tools/uic/baseline/qtgradienteditor.ui.h index c344d006b56..d94670d2ff9 100644 --- a/tests/auto/tools/uic/baseline/qtgradienteditor.ui.h +++ b/tests/auto/tools/uic/baseline/qtgradienteditor.ui.h @@ -162,10 +162,10 @@ public: void setupUi(QWidget *QtGradientEditor) { if (QtGradientEditor->objectName().isEmpty()) - QtGradientEditor->setObjectName(QString::fromUtf8("QtGradientEditor")); + QtGradientEditor->setObjectName(QStringLiteral("QtGradientEditor")); QtGradientEditor->resize(364, 518); frame = new QFrame(QtGradientEditor); - frame->setObjectName(QString::fromUtf8("frame")); + frame->setObjectName(QStringLiteral("frame")); frame->setGeometry(QRect(10, 69, 193, 150)); QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); sizePolicy.setHorizontalStretch(0); @@ -176,73 +176,73 @@ public: frame->setFrameShadow(QFrame::Raised); vboxLayout = new QVBoxLayout(frame); vboxLayout->setSpacing(6); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); vboxLayout->setContentsMargins(0, 0, 0, 0); gradientWidget = new QtGradientWidget(frame); - gradientWidget->setObjectName(QString::fromUtf8("gradientWidget")); + gradientWidget->setObjectName(QStringLiteral("gradientWidget")); sizePolicy.setHeightForWidth(gradientWidget->sizePolicy().hasHeightForWidth()); gradientWidget->setSizePolicy(sizePolicy); vboxLayout->addWidget(gradientWidget); label1 = new QLabel(QtGradientEditor); - label1->setObjectName(QString::fromUtf8("label1")); + label1->setObjectName(QStringLiteral("label1")); label1->setGeometry(QRect(209, 69, 64, 23)); spinBox1 = new QDoubleSpinBox(QtGradientEditor); - spinBox1->setObjectName(QString::fromUtf8("spinBox1")); + spinBox1->setObjectName(QStringLiteral("spinBox1")); spinBox1->setGeometry(QRect(279, 69, 73, 23)); spinBox1->setKeyboardTracking(false); spinBox1->setDecimals(3); spinBox1->setMaximum(1); spinBox1->setSingleStep(0.01); label2 = new QLabel(QtGradientEditor); - label2->setObjectName(QString::fromUtf8("label2")); + label2->setObjectName(QStringLiteral("label2")); label2->setGeometry(QRect(209, 99, 64, 23)); spinBox2 = new QDoubleSpinBox(QtGradientEditor); - spinBox2->setObjectName(QString::fromUtf8("spinBox2")); + spinBox2->setObjectName(QStringLiteral("spinBox2")); spinBox2->setGeometry(QRect(279, 99, 73, 23)); spinBox2->setKeyboardTracking(false); spinBox2->setDecimals(3); spinBox2->setMaximum(1); spinBox2->setSingleStep(0.01); label3 = new QLabel(QtGradientEditor); - label3->setObjectName(QString::fromUtf8("label3")); + label3->setObjectName(QStringLiteral("label3")); label3->setGeometry(QRect(209, 129, 64, 23)); spinBox3 = new QDoubleSpinBox(QtGradientEditor); - spinBox3->setObjectName(QString::fromUtf8("spinBox3")); + spinBox3->setObjectName(QStringLiteral("spinBox3")); spinBox3->setGeometry(QRect(279, 129, 73, 23)); spinBox3->setKeyboardTracking(false); spinBox3->setDecimals(3); spinBox3->setMaximum(1); spinBox3->setSingleStep(0.01); label4 = new QLabel(QtGradientEditor); - label4->setObjectName(QString::fromUtf8("label4")); + label4->setObjectName(QStringLiteral("label4")); label4->setGeometry(QRect(209, 159, 64, 23)); spinBox4 = new QDoubleSpinBox(QtGradientEditor); - spinBox4->setObjectName(QString::fromUtf8("spinBox4")); + spinBox4->setObjectName(QStringLiteral("spinBox4")); spinBox4->setGeometry(QRect(279, 159, 73, 23)); spinBox4->setKeyboardTracking(false); spinBox4->setDecimals(3); spinBox4->setMaximum(1); spinBox4->setSingleStep(0.01); label5 = new QLabel(QtGradientEditor); - label5->setObjectName(QString::fromUtf8("label5")); + label5->setObjectName(QStringLiteral("label5")); label5->setGeometry(QRect(209, 189, 64, 23)); spinBox5 = new QDoubleSpinBox(QtGradientEditor); - spinBox5->setObjectName(QString::fromUtf8("spinBox5")); + spinBox5->setObjectName(QStringLiteral("spinBox5")); spinBox5->setGeometry(QRect(279, 189, 73, 23)); spinBox5->setKeyboardTracking(false); spinBox5->setDecimals(3); spinBox5->setMaximum(1); spinBox5->setSingleStep(0.01); gradientStopsWidget = new QtGradientStopsWidget(QtGradientEditor); - gradientStopsWidget->setObjectName(QString::fromUtf8("gradientStopsWidget")); + gradientStopsWidget->setObjectName(QStringLiteral("gradientStopsWidget")); gradientStopsWidget->setGeometry(QRect(10, 225, 193, 67)); zoomLabel = new QLabel(QtGradientEditor); - zoomLabel->setObjectName(QString::fromUtf8("zoomLabel")); + zoomLabel->setObjectName(QStringLiteral("zoomLabel")); zoomLabel->setGeometry(QRect(209, 231, 64, 23)); zoomAllButton = new QToolButton(QtGradientEditor); - zoomAllButton->setObjectName(QString::fromUtf8("zoomAllButton")); + zoomAllButton->setObjectName(QStringLiteral("zoomAllButton")); zoomAllButton->setGeometry(QRect(279, 260, 72, 26)); QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Fixed); sizePolicy1.setHorizontalStretch(0); @@ -250,15 +250,15 @@ public: sizePolicy1.setHeightForWidth(zoomAllButton->sizePolicy().hasHeightForWidth()); zoomAllButton->setSizePolicy(sizePolicy1); positionLabel = new QLabel(QtGradientEditor); - positionLabel->setObjectName(QString::fromUtf8("positionLabel")); + positionLabel->setObjectName(QStringLiteral("positionLabel")); positionLabel->setGeometry(QRect(209, 304, 64, 23)); hLabel = new QLabel(QtGradientEditor); - hLabel->setObjectName(QString::fromUtf8("hLabel")); + hLabel->setObjectName(QStringLiteral("hLabel")); hLabel->setGeometry(QRect(10, 335, 32, 18)); sizePolicy1.setHeightForWidth(hLabel->sizePolicy().hasHeightForWidth()); hLabel->setSizePolicy(sizePolicy1); frame_2 = new QFrame(QtGradientEditor); - frame_2->setObjectName(QString::fromUtf8("frame_2")); + frame_2->setObjectName(QStringLiteral("frame_2")); frame_2->setGeometry(QRect(48, 333, 155, 23)); QSizePolicy sizePolicy2(QSizePolicy::Ignored, QSizePolicy::Preferred); sizePolicy2.setHorizontalStretch(0); @@ -268,10 +268,10 @@ public: frame_2->setFrameShape(QFrame::StyledPanel); frame_2->setFrameShadow(QFrame::Raised); hboxLayout = new QHBoxLayout(frame_2); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); hboxLayout->setContentsMargins(0, 0, 0, 0); hueColorLine = new QtColorLine(frame_2); - hueColorLine->setObjectName(QString::fromUtf8("hueColorLine")); + hueColorLine->setObjectName(QStringLiteral("hueColorLine")); QSizePolicy sizePolicy3(QSizePolicy::Expanding, QSizePolicy::Preferred); sizePolicy3.setHorizontalStretch(0); sizePolicy3.setVerticalStretch(0); @@ -281,99 +281,99 @@ public: hboxLayout->addWidget(hueColorLine); hueLabel = new QLabel(QtGradientEditor); - hueLabel->setObjectName(QString::fromUtf8("hueLabel")); + hueLabel->setObjectName(QStringLiteral("hueLabel")); hueLabel->setGeometry(QRect(209, 335, 64, 18)); sizePolicy1.setHeightForWidth(hueLabel->sizePolicy().hasHeightForWidth()); hueLabel->setSizePolicy(sizePolicy1); sLabel = new QLabel(QtGradientEditor); - sLabel->setObjectName(QString::fromUtf8("sLabel")); + sLabel->setObjectName(QStringLiteral("sLabel")); sLabel->setGeometry(QRect(10, 364, 32, 18)); sizePolicy1.setHeightForWidth(sLabel->sizePolicy().hasHeightForWidth()); sLabel->setSizePolicy(sizePolicy1); frame_5 = new QFrame(QtGradientEditor); - frame_5->setObjectName(QString::fromUtf8("frame_5")); + frame_5->setObjectName(QStringLiteral("frame_5")); frame_5->setGeometry(QRect(48, 362, 155, 23)); sizePolicy2.setHeightForWidth(frame_5->sizePolicy().hasHeightForWidth()); frame_5->setSizePolicy(sizePolicy2); frame_5->setFrameShape(QFrame::StyledPanel); frame_5->setFrameShadow(QFrame::Raised); hboxLayout1 = new QHBoxLayout(frame_5); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); hboxLayout1->setContentsMargins(0, 0, 0, 0); saturationColorLine = new QtColorLine(frame_5); - saturationColorLine->setObjectName(QString::fromUtf8("saturationColorLine")); + saturationColorLine->setObjectName(QStringLiteral("saturationColorLine")); sizePolicy3.setHeightForWidth(saturationColorLine->sizePolicy().hasHeightForWidth()); saturationColorLine->setSizePolicy(sizePolicy3); hboxLayout1->addWidget(saturationColorLine); saturationLabel = new QLabel(QtGradientEditor); - saturationLabel->setObjectName(QString::fromUtf8("saturationLabel")); + saturationLabel->setObjectName(QStringLiteral("saturationLabel")); saturationLabel->setGeometry(QRect(209, 364, 64, 18)); sizePolicy1.setHeightForWidth(saturationLabel->sizePolicy().hasHeightForWidth()); saturationLabel->setSizePolicy(sizePolicy1); vLabel = new QLabel(QtGradientEditor); - vLabel->setObjectName(QString::fromUtf8("vLabel")); + vLabel->setObjectName(QStringLiteral("vLabel")); vLabel->setGeometry(QRect(10, 393, 32, 18)); sizePolicy1.setHeightForWidth(vLabel->sizePolicy().hasHeightForWidth()); vLabel->setSizePolicy(sizePolicy1); frame_3 = new QFrame(QtGradientEditor); - frame_3->setObjectName(QString::fromUtf8("frame_3")); + frame_3->setObjectName(QStringLiteral("frame_3")); frame_3->setGeometry(QRect(48, 391, 155, 23)); sizePolicy2.setHeightForWidth(frame_3->sizePolicy().hasHeightForWidth()); frame_3->setSizePolicy(sizePolicy2); frame_3->setFrameShape(QFrame::StyledPanel); frame_3->setFrameShadow(QFrame::Raised); hboxLayout2 = new QHBoxLayout(frame_3); - hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2")); + hboxLayout2->setObjectName(QStringLiteral("hboxLayout2")); hboxLayout2->setContentsMargins(0, 0, 0, 0); valueColorLine = new QtColorLine(frame_3); - valueColorLine->setObjectName(QString::fromUtf8("valueColorLine")); + valueColorLine->setObjectName(QStringLiteral("valueColorLine")); sizePolicy3.setHeightForWidth(valueColorLine->sizePolicy().hasHeightForWidth()); valueColorLine->setSizePolicy(sizePolicy3); hboxLayout2->addWidget(valueColorLine); valueLabel = new QLabel(QtGradientEditor); - valueLabel->setObjectName(QString::fromUtf8("valueLabel")); + valueLabel->setObjectName(QStringLiteral("valueLabel")); valueLabel->setGeometry(QRect(209, 393, 64, 18)); sizePolicy1.setHeightForWidth(valueLabel->sizePolicy().hasHeightForWidth()); valueLabel->setSizePolicy(sizePolicy1); aLabel = new QLabel(QtGradientEditor); - aLabel->setObjectName(QString::fromUtf8("aLabel")); + aLabel->setObjectName(QStringLiteral("aLabel")); aLabel->setGeometry(QRect(10, 422, 32, 18)); sizePolicy1.setHeightForWidth(aLabel->sizePolicy().hasHeightForWidth()); aLabel->setSizePolicy(sizePolicy1); frame_4 = new QFrame(QtGradientEditor); - frame_4->setObjectName(QString::fromUtf8("frame_4")); + frame_4->setObjectName(QStringLiteral("frame_4")); frame_4->setGeometry(QRect(48, 420, 155, 23)); sizePolicy2.setHeightForWidth(frame_4->sizePolicy().hasHeightForWidth()); frame_4->setSizePolicy(sizePolicy2); frame_4->setFrameShape(QFrame::StyledPanel); frame_4->setFrameShadow(QFrame::Raised); hboxLayout3 = new QHBoxLayout(frame_4); - hboxLayout3->setObjectName(QString::fromUtf8("hboxLayout3")); + hboxLayout3->setObjectName(QStringLiteral("hboxLayout3")); hboxLayout3->setContentsMargins(0, 0, 0, 0); alphaColorLine = new QtColorLine(frame_4); - alphaColorLine->setObjectName(QString::fromUtf8("alphaColorLine")); + alphaColorLine->setObjectName(QStringLiteral("alphaColorLine")); sizePolicy3.setHeightForWidth(alphaColorLine->sizePolicy().hasHeightForWidth()); alphaColorLine->setSizePolicy(sizePolicy3); hboxLayout3->addWidget(alphaColorLine); alphaLabel = new QLabel(QtGradientEditor); - alphaLabel->setObjectName(QString::fromUtf8("alphaLabel")); + alphaLabel->setObjectName(QStringLiteral("alphaLabel")); alphaLabel->setGeometry(QRect(209, 422, 64, 18)); sizePolicy1.setHeightForWidth(alphaLabel->sizePolicy().hasHeightForWidth()); alphaLabel->setSizePolicy(sizePolicy1); typeComboBox = new QComboBox(QtGradientEditor); - typeComboBox->setObjectName(QString::fromUtf8("typeComboBox")); + typeComboBox->setObjectName(QStringLiteral("typeComboBox")); typeComboBox->setGeometry(QRect(10, 40, 79, 22)); spreadComboBox = new QComboBox(QtGradientEditor); - spreadComboBox->setObjectName(QString::fromUtf8("spreadComboBox")); + spreadComboBox->setObjectName(QStringLiteral("spreadComboBox")); spreadComboBox->setGeometry(QRect(96, 40, 72, 22)); colorLabel = new QLabel(QtGradientEditor); - colorLabel->setObjectName(QString::fromUtf8("colorLabel")); + colorLabel->setObjectName(QStringLiteral("colorLabel")); colorLabel->setGeometry(QRect(10, 298, 32, 29)); QSizePolicy sizePolicy4(QSizePolicy::Fixed, QSizePolicy::Preferred); sizePolicy4.setHorizontalStretch(0); @@ -381,10 +381,10 @@ public: sizePolicy4.setHeightForWidth(colorLabel->sizePolicy().hasHeightForWidth()); colorLabel->setSizePolicy(sizePolicy4); colorButton = new QtColorButton(QtGradientEditor); - colorButton->setObjectName(QString::fromUtf8("colorButton")); + colorButton->setObjectName(QStringLiteral("colorButton")); colorButton->setGeometry(QRect(48, 300, 26, 25)); hsvRadioButton = new QRadioButton(QtGradientEditor); - hsvRadioButton->setObjectName(QString::fromUtf8("hsvRadioButton")); + hsvRadioButton->setObjectName(QStringLiteral("hsvRadioButton")); hsvRadioButton->setGeometry(QRect(80, 301, 49, 23)); QSizePolicy sizePolicy5(QSizePolicy::Fixed, QSizePolicy::Fixed); sizePolicy5.setHorizontalStretch(0); @@ -393,18 +393,18 @@ public: hsvRadioButton->setSizePolicy(sizePolicy5); hsvRadioButton->setChecked(true); rgbRadioButton = new QRadioButton(QtGradientEditor); - rgbRadioButton->setObjectName(QString::fromUtf8("rgbRadioButton")); + rgbRadioButton->setObjectName(QStringLiteral("rgbRadioButton")); rgbRadioButton->setGeometry(QRect(135, 301, 49, 23)); sizePolicy5.setHeightForWidth(rgbRadioButton->sizePolicy().hasHeightForWidth()); rgbRadioButton->setSizePolicy(sizePolicy5); positionWidget = new QWidget(QtGradientEditor); - positionWidget->setObjectName(QString::fromUtf8("positionWidget")); + positionWidget->setObjectName(QStringLiteral("positionWidget")); positionWidget->setGeometry(QRect(279, 304, 73, 23)); vboxLayout1 = new QVBoxLayout(positionWidget); - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); vboxLayout1->setContentsMargins(0, 0, 0, 0); positionSpinBox = new QDoubleSpinBox(positionWidget); - positionSpinBox->setObjectName(QString::fromUtf8("positionSpinBox")); + positionSpinBox->setObjectName(QStringLiteral("positionSpinBox")); positionSpinBox->setKeyboardTracking(false); positionSpinBox->setDecimals(3); positionSpinBox->setMinimum(0); @@ -415,65 +415,65 @@ public: vboxLayout1->addWidget(positionSpinBox); hueWidget = new QWidget(QtGradientEditor); - hueWidget->setObjectName(QString::fromUtf8("hueWidget")); + hueWidget->setObjectName(QStringLiteral("hueWidget")); hueWidget->setGeometry(QRect(279, 333, 73, 23)); vboxLayout2 = new QVBoxLayout(hueWidget); - vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2")); + vboxLayout2->setObjectName(QStringLiteral("vboxLayout2")); vboxLayout2->setContentsMargins(0, 0, 0, 0); hueSpinBox = new QSpinBox(hueWidget); - hueSpinBox->setObjectName(QString::fromUtf8("hueSpinBox")); + hueSpinBox->setObjectName(QStringLiteral("hueSpinBox")); hueSpinBox->setKeyboardTracking(false); hueSpinBox->setMaximum(359); vboxLayout2->addWidget(hueSpinBox); saturationWidget = new QWidget(QtGradientEditor); - saturationWidget->setObjectName(QString::fromUtf8("saturationWidget")); + saturationWidget->setObjectName(QStringLiteral("saturationWidget")); saturationWidget->setGeometry(QRect(279, 362, 73, 23)); vboxLayout3 = new QVBoxLayout(saturationWidget); - vboxLayout3->setObjectName(QString::fromUtf8("vboxLayout3")); + vboxLayout3->setObjectName(QStringLiteral("vboxLayout3")); vboxLayout3->setContentsMargins(0, 0, 0, 0); saturationSpinBox = new QSpinBox(saturationWidget); - saturationSpinBox->setObjectName(QString::fromUtf8("saturationSpinBox")); + saturationSpinBox->setObjectName(QStringLiteral("saturationSpinBox")); saturationSpinBox->setKeyboardTracking(false); saturationSpinBox->setMaximum(255); vboxLayout3->addWidget(saturationSpinBox); valueWidget = new QWidget(QtGradientEditor); - valueWidget->setObjectName(QString::fromUtf8("valueWidget")); + valueWidget->setObjectName(QStringLiteral("valueWidget")); valueWidget->setGeometry(QRect(279, 391, 73, 23)); vboxLayout4 = new QVBoxLayout(valueWidget); - vboxLayout4->setObjectName(QString::fromUtf8("vboxLayout4")); + vboxLayout4->setObjectName(QStringLiteral("vboxLayout4")); vboxLayout4->setContentsMargins(0, 0, 0, 0); valueSpinBox = new QSpinBox(valueWidget); - valueSpinBox->setObjectName(QString::fromUtf8("valueSpinBox")); + valueSpinBox->setObjectName(QStringLiteral("valueSpinBox")); valueSpinBox->setKeyboardTracking(false); valueSpinBox->setMaximum(255); vboxLayout4->addWidget(valueSpinBox); alphaWidget = new QWidget(QtGradientEditor); - alphaWidget->setObjectName(QString::fromUtf8("alphaWidget")); + alphaWidget->setObjectName(QStringLiteral("alphaWidget")); alphaWidget->setGeometry(QRect(279, 420, 73, 23)); vboxLayout5 = new QVBoxLayout(alphaWidget); - vboxLayout5->setObjectName(QString::fromUtf8("vboxLayout5")); + vboxLayout5->setObjectName(QStringLiteral("vboxLayout5")); vboxLayout5->setContentsMargins(0, 0, 0, 0); alphaSpinBox = new QSpinBox(alphaWidget); - alphaSpinBox->setObjectName(QString::fromUtf8("alphaSpinBox")); + alphaSpinBox->setObjectName(QStringLiteral("alphaSpinBox")); alphaSpinBox->setKeyboardTracking(false); alphaSpinBox->setMaximum(255); vboxLayout5->addWidget(alphaSpinBox); zoomWidget = new QWidget(QtGradientEditor); - zoomWidget->setObjectName(QString::fromUtf8("zoomWidget")); + zoomWidget->setObjectName(QStringLiteral("zoomWidget")); zoomWidget->setGeometry(QRect(279, 231, 73, 23)); vboxLayout6 = new QVBoxLayout(zoomWidget); - vboxLayout6->setObjectName(QString::fromUtf8("vboxLayout6")); + vboxLayout6->setObjectName(QStringLiteral("vboxLayout6")); vboxLayout6->setContentsMargins(0, 0, 0, 0); zoomSpinBox = new QSpinBox(zoomWidget); - zoomSpinBox->setObjectName(QString::fromUtf8("zoomSpinBox")); + zoomSpinBox->setObjectName(QStringLiteral("zoomSpinBox")); zoomSpinBox->setKeyboardTracking(false); zoomSpinBox->setMinimum(100); zoomSpinBox->setMaximum(10000); @@ -483,33 +483,33 @@ public: vboxLayout6->addWidget(zoomSpinBox); line1Widget = new QWidget(QtGradientEditor); - line1Widget->setObjectName(QString::fromUtf8("line1Widget")); + line1Widget->setObjectName(QStringLiteral("line1Widget")); line1Widget->setGeometry(QRect(209, 219, 143, 16)); vboxLayout7 = new QVBoxLayout(line1Widget); - vboxLayout7->setObjectName(QString::fromUtf8("vboxLayout7")); + vboxLayout7->setObjectName(QStringLiteral("vboxLayout7")); vboxLayout7->setContentsMargins(0, 0, 0, 0); line1 = new QFrame(line1Widget); - line1->setObjectName(QString::fromUtf8("line1")); + line1->setObjectName(QStringLiteral("line1")); line1->setFrameShape(QFrame::HLine); line1->setFrameShadow(QFrame::Sunken); vboxLayout7->addWidget(line1); line2Widget = new QWidget(QtGradientEditor); - line2Widget->setObjectName(QString::fromUtf8("line2Widget")); + line2Widget->setObjectName(QStringLiteral("line2Widget")); line2Widget->setGeometry(QRect(209, 292, 143, 16)); vboxLayout8 = new QVBoxLayout(line2Widget); - vboxLayout8->setObjectName(QString::fromUtf8("vboxLayout8")); + vboxLayout8->setObjectName(QStringLiteral("vboxLayout8")); vboxLayout8->setContentsMargins(0, 0, 0, 0); line2 = new QFrame(line2Widget); - line2->setObjectName(QString::fromUtf8("line2")); + line2->setObjectName(QStringLiteral("line2")); line2->setFrameShape(QFrame::HLine); line2->setFrameShadow(QFrame::Sunken); vboxLayout8->addWidget(line2); zoomButtonsWidget = new QWidget(QtGradientEditor); - zoomButtonsWidget->setObjectName(QString::fromUtf8("zoomButtonsWidget")); + zoomButtonsWidget->setObjectName(QStringLiteral("zoomButtonsWidget")); zoomButtonsWidget->setGeometry(QRect(209, 260, 64, 26)); QSizePolicy sizePolicy6(QSizePolicy::Maximum, QSizePolicy::Preferred); sizePolicy6.setHorizontalStretch(0); @@ -517,15 +517,15 @@ public: sizePolicy6.setHeightForWidth(zoomButtonsWidget->sizePolicy().hasHeightForWidth()); zoomButtonsWidget->setSizePolicy(sizePolicy6); hboxLayout4 = new QHBoxLayout(zoomButtonsWidget); - hboxLayout4->setObjectName(QString::fromUtf8("hboxLayout4")); + hboxLayout4->setObjectName(QStringLiteral("hboxLayout4")); hboxLayout4->setContentsMargins(0, 0, 0, 0); zoomInButton = new QToolButton(zoomButtonsWidget); - zoomInButton->setObjectName(QString::fromUtf8("zoomInButton")); + zoomInButton->setObjectName(QStringLiteral("zoomInButton")); hboxLayout4->addWidget(zoomInButton); zoomOutButton = new QToolButton(zoomButtonsWidget); - zoomOutButton->setObjectName(QString::fromUtf8("zoomOutButton")); + zoomOutButton->setObjectName(QStringLiteral("zoomOutButton")); hboxLayout4->addWidget(zoomOutButton); @@ -534,7 +534,7 @@ public: hboxLayout4->addItem(spacerItem); detailsButton = new QToolButton(QtGradientEditor); - detailsButton->setObjectName(QString::fromUtf8("detailsButton")); + detailsButton->setObjectName(QStringLiteral("detailsButton")); detailsButton->setGeometry(QRect(176, 40, 25, 22)); QSizePolicy sizePolicy7(QSizePolicy::Fixed, QSizePolicy::Ignored); sizePolicy7.setHorizontalStretch(0); @@ -544,32 +544,32 @@ public: detailsButton->setCheckable(true); detailsButton->setAutoRaise(true); linearButton = new QToolButton(QtGradientEditor); - linearButton->setObjectName(QString::fromUtf8("linearButton")); + linearButton->setObjectName(QStringLiteral("linearButton")); linearButton->setGeometry(QRect(10, 10, 30, 26)); linearButton->setCheckable(true); linearButton->setAutoRaise(true); radialButton = new QToolButton(QtGradientEditor); - radialButton->setObjectName(QString::fromUtf8("radialButton")); + radialButton->setObjectName(QStringLiteral("radialButton")); radialButton->setGeometry(QRect(40, 10, 30, 26)); radialButton->setCheckable(true); radialButton->setAutoRaise(true); conicalButton = new QToolButton(QtGradientEditor); - conicalButton->setObjectName(QString::fromUtf8("conicalButton")); + conicalButton->setObjectName(QStringLiteral("conicalButton")); conicalButton->setGeometry(QRect(70, 10, 30, 26)); conicalButton->setCheckable(true); conicalButton->setAutoRaise(true); padButton = new QToolButton(QtGradientEditor); - padButton->setObjectName(QString::fromUtf8("padButton")); + padButton->setObjectName(QStringLiteral("padButton")); padButton->setGeometry(QRect(110, 10, 30, 26)); padButton->setCheckable(true); padButton->setAutoRaise(true); repeatButton = new QToolButton(QtGradientEditor); - repeatButton->setObjectName(QString::fromUtf8("repeatButton")); + repeatButton->setObjectName(QStringLiteral("repeatButton")); repeatButton->setGeometry(QRect(140, 10, 30, 26)); repeatButton->setCheckable(true); repeatButton->setAutoRaise(true); reflectButton = new QToolButton(QtGradientEditor); - reflectButton->setObjectName(QString::fromUtf8("reflectButton")); + reflectButton->setObjectName(QStringLiteral("reflectButton")); reflectButton->setGeometry(QRect(170, 10, 30, 26)); reflectButton->setCheckable(true); reflectButton->setAutoRaise(true); diff --git a/tests/auto/tools/uic/baseline/qtgradientview.ui.h b/tests/auto/tools/uic/baseline/qtgradientview.ui.h index 52512c4a5bb..62136c38908 100644 --- a/tests/auto/tools/uic/baseline/qtgradientview.ui.h +++ b/tests/auto/tools/uic/baseline/qtgradientview.ui.h @@ -39,15 +39,15 @@ public: void setupUi(QWidget *QtGradientView) { if (QtGradientView->objectName().isEmpty()) - QtGradientView->setObjectName(QString::fromUtf8("QtGradientView")); + QtGradientView->setObjectName(QStringLiteral("QtGradientView")); QtGradientView->resize(484, 228); vboxLayout = new QVBoxLayout(QtGradientView); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); vboxLayout->setContentsMargins(0, 0, 0, 0); hboxLayout = new QHBoxLayout(); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); newButton = new QToolButton(QtGradientView); - newButton->setObjectName(QString::fromUtf8("newButton")); + newButton->setObjectName(QStringLiteral("newButton")); QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -59,7 +59,7 @@ public: hboxLayout->addWidget(newButton); editButton = new QToolButton(QtGradientView); - editButton->setObjectName(QString::fromUtf8("editButton")); + editButton->setObjectName(QStringLiteral("editButton")); sizePolicy.setHeightForWidth(editButton->sizePolicy().hasHeightForWidth()); editButton->setSizePolicy(sizePolicy); editButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); @@ -68,7 +68,7 @@ public: hboxLayout->addWidget(editButton); renameButton = new QToolButton(QtGradientView); - renameButton->setObjectName(QString::fromUtf8("renameButton")); + renameButton->setObjectName(QStringLiteral("renameButton")); sizePolicy.setHeightForWidth(renameButton->sizePolicy().hasHeightForWidth()); renameButton->setSizePolicy(sizePolicy); renameButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); @@ -77,7 +77,7 @@ public: hboxLayout->addWidget(renameButton); removeButton = new QToolButton(QtGradientView); - removeButton->setObjectName(QString::fromUtf8("removeButton")); + removeButton->setObjectName(QStringLiteral("removeButton")); sizePolicy.setHeightForWidth(removeButton->sizePolicy().hasHeightForWidth()); removeButton->setSizePolicy(sizePolicy); removeButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); @@ -93,7 +93,7 @@ public: vboxLayout->addLayout(hboxLayout); listWidget = new QListWidget(QtGradientView); - listWidget->setObjectName(QString::fromUtf8("listWidget")); + listWidget->setObjectName(QStringLiteral("listWidget")); vboxLayout->addWidget(listWidget); diff --git a/tests/auto/tools/uic/baseline/qtgradientviewdialog.ui.h b/tests/auto/tools/uic/baseline/qtgradientviewdialog.ui.h index d93dfd605c2..cc7912d4c2e 100644 --- a/tests/auto/tools/uic/baseline/qtgradientviewdialog.ui.h +++ b/tests/auto/tools/uic/baseline/qtgradientviewdialog.ui.h @@ -75,12 +75,12 @@ public: void setupUi(QDialog *QtGradientViewDialog) { if (QtGradientViewDialog->objectName().isEmpty()) - QtGradientViewDialog->setObjectName(QString::fromUtf8("QtGradientViewDialog")); + QtGradientViewDialog->setObjectName(QStringLiteral("QtGradientViewDialog")); QtGradientViewDialog->resize(178, 72); vboxLayout = new QVBoxLayout(QtGradientViewDialog); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); gradientView = new QtGradientView(QtGradientViewDialog); - gradientView->setObjectName(QString::fromUtf8("gradientView")); + gradientView->setObjectName(QStringLiteral("gradientView")); QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -90,7 +90,7 @@ public: vboxLayout->addWidget(gradientView); buttonBox = new QDialogButtonBox(QtGradientViewDialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h b/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h index b34f246c344..72cef5353a7 100644 --- a/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h +++ b/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h @@ -52,20 +52,20 @@ public: void setupUi(QDialog *QtResourceEditorDialog) { if (QtResourceEditorDialog->objectName().isEmpty()) - QtResourceEditorDialog->setObjectName(QString::fromUtf8("QtResourceEditorDialog")); + QtResourceEditorDialog->setObjectName(QStringLiteral("QtResourceEditorDialog")); QtResourceEditorDialog->resize(469, 317); verticalLayout = new QVBoxLayout(QtResourceEditorDialog); - verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); splitter = new QSplitter(QtResourceEditorDialog); - splitter->setObjectName(QString::fromUtf8("splitter")); + splitter->setObjectName(QStringLiteral("splitter")); splitter->setOrientation(Qt::Horizontal); layoutWidget = new QWidget(splitter); - layoutWidget->setObjectName(QString::fromUtf8("layoutWidget")); + layoutWidget->setObjectName(QStringLiteral("layoutWidget")); gridLayout = new QGridLayout(layoutWidget); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); gridLayout->setContentsMargins(0, 0, 0, 0); qrcFileList = new QListWidget(layoutWidget); - qrcFileList->setObjectName(QString::fromUtf8("qrcFileList")); + qrcFileList->setObjectName(QStringLiteral("qrcFileList")); QSizePolicy sizePolicy(QSizePolicy::Ignored, QSizePolicy::Expanding); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -75,12 +75,12 @@ public: gridLayout->addWidget(qrcFileList, 0, 0, 1, 4); newQrcButton = new QToolButton(layoutWidget); - newQrcButton->setObjectName(QString::fromUtf8("newQrcButton")); + newQrcButton->setObjectName(QStringLiteral("newQrcButton")); gridLayout->addWidget(newQrcButton, 1, 0, 1, 1); removeQrcButton = new QToolButton(layoutWidget); - removeQrcButton->setObjectName(QString::fromUtf8("removeQrcButton")); + removeQrcButton->setObjectName(QStringLiteral("removeQrcButton")); gridLayout->addWidget(removeQrcButton, 1, 2, 1, 1); @@ -89,33 +89,33 @@ public: gridLayout->addItem(spacerItem, 1, 3, 1, 1); importQrcButton = new QToolButton(layoutWidget); - importQrcButton->setObjectName(QString::fromUtf8("importQrcButton")); + importQrcButton->setObjectName(QStringLiteral("importQrcButton")); gridLayout->addWidget(importQrcButton, 1, 1, 1, 1); splitter->addWidget(layoutWidget); widget = new QWidget(splitter); - widget->setObjectName(QString::fromUtf8("widget")); + widget->setObjectName(QStringLiteral("widget")); gridLayout1 = new QGridLayout(widget); - gridLayout1->setObjectName(QString::fromUtf8("gridLayout1")); + gridLayout1->setObjectName(QStringLiteral("gridLayout1")); gridLayout1->setContentsMargins(0, 0, 0, 0); resourceTreeView = new QTreeView(widget); - resourceTreeView->setObjectName(QString::fromUtf8("resourceTreeView")); + resourceTreeView->setObjectName(QStringLiteral("resourceTreeView")); gridLayout1->addWidget(resourceTreeView, 0, 0, 1, 4); newResourceButton = new QToolButton(widget); - newResourceButton->setObjectName(QString::fromUtf8("newResourceButton")); + newResourceButton->setObjectName(QStringLiteral("newResourceButton")); gridLayout1->addWidget(newResourceButton, 1, 0, 1, 1); addResourceButton = new QToolButton(widget); - addResourceButton->setObjectName(QString::fromUtf8("addResourceButton")); + addResourceButton->setObjectName(QStringLiteral("addResourceButton")); gridLayout1->addWidget(addResourceButton, 1, 1, 1, 1); removeResourceButton = new QToolButton(widget); - removeResourceButton->setObjectName(QString::fromUtf8("removeResourceButton")); + removeResourceButton->setObjectName(QStringLiteral("removeResourceButton")); gridLayout1->addWidget(removeResourceButton, 1, 2, 1, 1); @@ -128,7 +128,7 @@ public: verticalLayout->addWidget(splitter); buttonBox = new QDialogButtonBox(QtResourceEditorDialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h b/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h index 463961452f7..5b6ec991b9f 100644 --- a/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h +++ b/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h @@ -53,21 +53,21 @@ public: void setupUi(QDialog *QtToolBarDialog) { if (QtToolBarDialog->objectName().isEmpty()) - QtToolBarDialog->setObjectName(QString::fromUtf8("QtToolBarDialog")); + QtToolBarDialog->setObjectName(QStringLiteral("QtToolBarDialog")); QtToolBarDialog->resize(583, 508); gridLayout = new QGridLayout(QtToolBarDialog); #ifndef Q_OS_MAC gridLayout->setSpacing(6); #endif gridLayout->setContentsMargins(8, 8, 8, 8); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); actionTree = new QTreeWidget(QtToolBarDialog); - actionTree->setObjectName(QString::fromUtf8("actionTree")); + actionTree->setObjectName(QStringLiteral("actionTree")); gridLayout->addWidget(actionTree, 1, 0, 3, 1); label = new QLabel(QtToolBarDialog); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 0, 0, 1, 1); @@ -76,24 +76,24 @@ public: hboxLayout->setSpacing(6); #endif hboxLayout->setContentsMargins(0, 0, 0, 0); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); label_2 = new QLabel(QtToolBarDialog); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); hboxLayout->addWidget(label_2); newButton = new QToolButton(QtToolBarDialog); - newButton->setObjectName(QString::fromUtf8("newButton")); + newButton->setObjectName(QStringLiteral("newButton")); hboxLayout->addWidget(newButton); removeButton = new QToolButton(QtToolBarDialog); - removeButton->setObjectName(QString::fromUtf8("removeButton")); + removeButton->setObjectName(QStringLiteral("removeButton")); hboxLayout->addWidget(removeButton); renameButton = new QToolButton(QtToolBarDialog); - renameButton->setObjectName(QString::fromUtf8("renameButton")); + renameButton->setObjectName(QStringLiteral("renameButton")); hboxLayout->addWidget(renameButton); @@ -105,9 +105,9 @@ public: vboxLayout->setSpacing(6); #endif vboxLayout->setContentsMargins(0, 0, 0, 0); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); upButton = new QToolButton(QtToolBarDialog); - upButton->setObjectName(QString::fromUtf8("upButton")); + upButton->setObjectName(QStringLiteral("upButton")); QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -117,21 +117,21 @@ public: vboxLayout->addWidget(upButton); leftButton = new QToolButton(QtToolBarDialog); - leftButton->setObjectName(QString::fromUtf8("leftButton")); + leftButton->setObjectName(QStringLiteral("leftButton")); sizePolicy.setHeightForWidth(leftButton->sizePolicy().hasHeightForWidth()); leftButton->setSizePolicy(sizePolicy); vboxLayout->addWidget(leftButton); rightButton = new QToolButton(QtToolBarDialog); - rightButton->setObjectName(QString::fromUtf8("rightButton")); + rightButton->setObjectName(QStringLiteral("rightButton")); sizePolicy.setHeightForWidth(rightButton->sizePolicy().hasHeightForWidth()); rightButton->setSizePolicy(sizePolicy); vboxLayout->addWidget(rightButton); downButton = new QToolButton(QtToolBarDialog); - downButton->setObjectName(QString::fromUtf8("downButton")); + downButton->setObjectName(QStringLiteral("downButton")); sizePolicy.setHeightForWidth(downButton->sizePolicy().hasHeightForWidth()); downButton->setSizePolicy(sizePolicy); @@ -145,22 +145,22 @@ public: gridLayout->addLayout(vboxLayout, 3, 1, 1, 1); currentToolBarList = new QListWidget(QtToolBarDialog); - currentToolBarList->setObjectName(QString::fromUtf8("currentToolBarList")); + currentToolBarList->setObjectName(QStringLiteral("currentToolBarList")); gridLayout->addWidget(currentToolBarList, 3, 2, 1, 1); label_3 = new QLabel(QtToolBarDialog); - label_3->setObjectName(QString::fromUtf8("label_3")); + label_3->setObjectName(QStringLiteral("label_3")); gridLayout->addWidget(label_3, 2, 1, 1, 2); toolBarList = new QListWidget(QtToolBarDialog); - toolBarList->setObjectName(QString::fromUtf8("toolBarList")); + toolBarList->setObjectName(QStringLiteral("toolBarList")); gridLayout->addWidget(toolBarList, 1, 1, 1, 2); buttonBox = new QDialogButtonBox(QtToolBarDialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setStandardButtons(QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults); gridLayout->addWidget(buttonBox, 5, 0, 1, 3); diff --git a/tests/auto/tools/uic/baseline/querywidget.ui.h b/tests/auto/tools/uic/baseline/querywidget.ui.h index c355f7c4f1f..5a2eef793bc 100644 --- a/tests/auto/tools/uic/baseline/querywidget.ui.h +++ b/tests/auto/tools/uic/baseline/querywidget.ui.h @@ -50,13 +50,13 @@ public: void setupUi(QMainWindow *QueryWidget) { if (QueryWidget->objectName().isEmpty()) - QueryWidget->setObjectName(QString::fromUtf8("QueryWidget")); + QueryWidget->setObjectName(QStringLiteral("QueryWidget")); QueryWidget->resize(545, 531); centralwidget = new QWidget(QueryWidget); - centralwidget->setObjectName(QString::fromUtf8("centralwidget")); + centralwidget->setObjectName(QStringLiteral("centralwidget")); centralwidget->setGeometry(QRect(0, 29, 545, 480)); verticalLayout = new QVBoxLayout(centralwidget); - verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); vboxLayout = new QVBoxLayout(); #ifndef Q_OS_MAC vboxLayout->setSpacing(6); @@ -64,12 +64,12 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(0, 0, 0, 0); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); inputGroupBox = new QGroupBox(centralwidget); - inputGroupBox->setObjectName(QString::fromUtf8("inputGroupBox")); + inputGroupBox->setObjectName(QStringLiteral("inputGroupBox")); inputGroupBox->setMinimumSize(QSize(550, 120)); verticalLayout_4 = new QVBoxLayout(inputGroupBox); - verticalLayout_4->setObjectName(QString::fromUtf8("verticalLayout_4")); + verticalLayout_4->setObjectName(QStringLiteral("verticalLayout_4")); _2 = new QVBoxLayout(); #ifndef Q_OS_MAC _2->setSpacing(6); @@ -77,9 +77,9 @@ public: #ifndef Q_OS_MAC _2->setContentsMargins(0, 0, 0, 0); #endif - _2->setObjectName(QString::fromUtf8("_2")); + _2->setObjectName(QStringLiteral("_2")); inputTextEdit = new QTextEdit(inputGroupBox); - inputTextEdit->setObjectName(QString::fromUtf8("inputTextEdit")); + inputTextEdit->setObjectName(QStringLiteral("inputTextEdit")); _2->addWidget(inputTextEdit); @@ -90,17 +90,17 @@ public: vboxLayout->addWidget(inputGroupBox); queryGroupBox = new QGroupBox(centralwidget); - queryGroupBox->setObjectName(QString::fromUtf8("queryGroupBox")); + queryGroupBox->setObjectName(QStringLiteral("queryGroupBox")); queryGroupBox->setMinimumSize(QSize(550, 120)); verticalLayout_5 = new QVBoxLayout(queryGroupBox); - verticalLayout_5->setObjectName(QString::fromUtf8("verticalLayout_5")); + verticalLayout_5->setObjectName(QStringLiteral("verticalLayout_5")); defaultQueries = new QComboBox(queryGroupBox); - defaultQueries->setObjectName(QString::fromUtf8("defaultQueries")); + defaultQueries->setObjectName(QStringLiteral("defaultQueries")); verticalLayout_5->addWidget(defaultQueries); queryTextEdit = new QTextEdit(queryGroupBox); - queryTextEdit->setObjectName(QString::fromUtf8("queryTextEdit")); + queryTextEdit->setObjectName(QStringLiteral("queryTextEdit")); queryTextEdit->setMinimumSize(QSize(400, 60)); queryTextEdit->setReadOnly(true); queryTextEdit->setAcceptRichText(false); @@ -111,10 +111,10 @@ public: vboxLayout->addWidget(queryGroupBox); outputGroupBox = new QGroupBox(centralwidget); - outputGroupBox->setObjectName(QString::fromUtf8("outputGroupBox")); + outputGroupBox->setObjectName(QStringLiteral("outputGroupBox")); outputGroupBox->setMinimumSize(QSize(550, 120)); verticalLayout_6 = new QVBoxLayout(outputGroupBox); - verticalLayout_6->setObjectName(QString::fromUtf8("verticalLayout_6")); + verticalLayout_6->setObjectName(QStringLiteral("verticalLayout_6")); _3 = new QVBoxLayout(); #ifndef Q_OS_MAC _3->setSpacing(6); @@ -122,9 +122,9 @@ public: #ifndef Q_OS_MAC _3->setContentsMargins(0, 0, 0, 0); #endif - _3->setObjectName(QString::fromUtf8("_3")); + _3->setObjectName(QStringLiteral("_3")); outputTextEdit = new QTextEdit(outputGroupBox); - outputTextEdit->setObjectName(QString::fromUtf8("outputTextEdit")); + outputTextEdit->setObjectName(QStringLiteral("outputTextEdit")); outputTextEdit->setMinimumSize(QSize(500, 80)); outputTextEdit->setReadOnly(true); outputTextEdit->setAcceptRichText(false); @@ -142,11 +142,11 @@ public: QueryWidget->setCentralWidget(centralwidget); menubar = new QMenuBar(QueryWidget); - menubar->setObjectName(QString::fromUtf8("menubar")); + menubar->setObjectName(QStringLiteral("menubar")); menubar->setGeometry(QRect(0, 0, 545, 29)); QueryWidget->setMenuBar(menubar); statusbar = new QStatusBar(QueryWidget); - statusbar->setObjectName(QString::fromUtf8("statusbar")); + statusbar->setObjectName(QStringLiteral("statusbar")); statusbar->setGeometry(QRect(0, 509, 545, 22)); QueryWidget->setStatusBar(statusbar); diff --git a/tests/auto/tools/uic/baseline/remotecontrol.ui.h b/tests/auto/tools/uic/baseline/remotecontrol.ui.h index 52ab1678cc8..5a4910d6351 100644 --- a/tests/auto/tools/uic/baseline/remotecontrol.ui.h +++ b/tests/auto/tools/uic/baseline/remotecontrol.ui.h @@ -69,28 +69,28 @@ public: void setupUi(QMainWindow *RemoteControlClass) { if (RemoteControlClass->objectName().isEmpty()) - RemoteControlClass->setObjectName(QString::fromUtf8("RemoteControlClass")); + RemoteControlClass->setObjectName(QStringLiteral("RemoteControlClass")); RemoteControlClass->resize(344, 364); actionQuit = new QAction(RemoteControlClass); - actionQuit->setObjectName(QString::fromUtf8("actionQuit")); + actionQuit->setObjectName(QStringLiteral("actionQuit")); centralWidget = new QWidget(RemoteControlClass); - centralWidget->setObjectName(QString::fromUtf8("centralWidget")); + centralWidget->setObjectName(QStringLiteral("centralWidget")); gridLayout = new QGridLayout(centralWidget); gridLayout->setSpacing(6); gridLayout->setContentsMargins(11, 11, 11, 11); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); label = new QLabel(centralWidget); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 0, 0, 1, 1); startUrlLineEdit = new QLineEdit(centralWidget); - startUrlLineEdit->setObjectName(QString::fromUtf8("startUrlLineEdit")); + startUrlLineEdit->setObjectName(QStringLiteral("startUrlLineEdit")); gridLayout->addWidget(startUrlLineEdit, 0, 1, 1, 2); launchButton = new QPushButton(centralWidget); - launchButton->setObjectName(QString::fromUtf8("launchButton")); + launchButton->setObjectName(QStringLiteral("launchButton")); gridLayout->addWidget(launchButton, 1, 1, 1, 1); @@ -103,27 +103,27 @@ public: gridLayout->addItem(spacerItem1, 2, 1, 1, 1); actionGroupBox = new QGroupBox(centralWidget); - actionGroupBox->setObjectName(QString::fromUtf8("actionGroupBox")); + actionGroupBox->setObjectName(QStringLiteral("actionGroupBox")); actionGroupBox->setEnabled(false); gridLayout1 = new QGridLayout(actionGroupBox); gridLayout1->setSpacing(6); gridLayout1->setContentsMargins(11, 11, 11, 11); - gridLayout1->setObjectName(QString::fromUtf8("gridLayout1")); + gridLayout1->setObjectName(QStringLiteral("gridLayout1")); label_2 = new QLabel(actionGroupBox); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); gridLayout1->addWidget(label_2, 0, 0, 1, 1); hboxLayout = new QHBoxLayout(); hboxLayout->setSpacing(0); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); indexLineEdit = new QLineEdit(actionGroupBox); - indexLineEdit->setObjectName(QString::fromUtf8("indexLineEdit")); + indexLineEdit->setObjectName(QStringLiteral("indexLineEdit")); hboxLayout->addWidget(indexLineEdit); indexButton = new QToolButton(actionGroupBox); - indexButton->setObjectName(QString::fromUtf8("indexButton")); + indexButton->setObjectName(QStringLiteral("indexButton")); const QIcon icon = QIcon(QString::fromUtf8(":/remotecontrol/enter.png")); indexButton->setIcon(icon); @@ -133,20 +133,20 @@ public: gridLayout1->addLayout(hboxLayout, 0, 1, 1, 2); label_4 = new QLabel(actionGroupBox); - label_4->setObjectName(QString::fromUtf8("label_4")); + label_4->setObjectName(QStringLiteral("label_4")); gridLayout1->addWidget(label_4, 1, 0, 1, 1); hboxLayout1 = new QHBoxLayout(); hboxLayout1->setSpacing(0); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); identifierLineEdit = new QLineEdit(actionGroupBox); - identifierLineEdit->setObjectName(QString::fromUtf8("identifierLineEdit")); + identifierLineEdit->setObjectName(QStringLiteral("identifierLineEdit")); hboxLayout1->addWidget(identifierLineEdit); identifierButton = new QToolButton(actionGroupBox); - identifierButton->setObjectName(QString::fromUtf8("identifierButton")); + identifierButton->setObjectName(QStringLiteral("identifierButton")); identifierButton->setIcon(icon); hboxLayout1->addWidget(identifierButton); @@ -155,20 +155,20 @@ public: gridLayout1->addLayout(hboxLayout1, 1, 1, 1, 2); label_3 = new QLabel(actionGroupBox); - label_3->setObjectName(QString::fromUtf8("label_3")); + label_3->setObjectName(QStringLiteral("label_3")); gridLayout1->addWidget(label_3, 2, 0, 1, 1); hboxLayout2 = new QHBoxLayout(); hboxLayout2->setSpacing(0); - hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2")); + hboxLayout2->setObjectName(QStringLiteral("hboxLayout2")); urlLineEdit = new QLineEdit(actionGroupBox); - urlLineEdit->setObjectName(QString::fromUtf8("urlLineEdit")); + urlLineEdit->setObjectName(QStringLiteral("urlLineEdit")); hboxLayout2->addWidget(urlLineEdit); urlButton = new QToolButton(actionGroupBox); - urlButton->setObjectName(QString::fromUtf8("urlButton")); + urlButton->setObjectName(QStringLiteral("urlButton")); urlButton->setIcon(icon); hboxLayout2->addWidget(urlButton); @@ -177,7 +177,7 @@ public: gridLayout1->addLayout(hboxLayout2, 2, 1, 1, 2); syncContentsButton = new QPushButton(actionGroupBox); - syncContentsButton->setObjectName(QString::fromUtf8("syncContentsButton")); + syncContentsButton->setObjectName(QStringLiteral("syncContentsButton")); gridLayout1->addWidget(syncContentsButton, 3, 1, 1, 1); @@ -186,17 +186,17 @@ public: gridLayout1->addItem(spacerItem2, 3, 2, 1, 1); contentsCheckBox = new QCheckBox(actionGroupBox); - contentsCheckBox->setObjectName(QString::fromUtf8("contentsCheckBox")); + contentsCheckBox->setObjectName(QStringLiteral("contentsCheckBox")); gridLayout1->addWidget(contentsCheckBox, 4, 0, 1, 3); indexCheckBox = new QCheckBox(actionGroupBox); - indexCheckBox->setObjectName(QString::fromUtf8("indexCheckBox")); + indexCheckBox->setObjectName(QStringLiteral("indexCheckBox")); gridLayout1->addWidget(indexCheckBox, 5, 0, 1, 1); bookmarksCheckBox = new QCheckBox(actionGroupBox); - bookmarksCheckBox->setObjectName(QString::fromUtf8("bookmarksCheckBox")); + bookmarksCheckBox->setObjectName(QStringLiteral("bookmarksCheckBox")); gridLayout1->addWidget(bookmarksCheckBox, 6, 0, 1, 3); @@ -205,13 +205,13 @@ public: RemoteControlClass->setCentralWidget(centralWidget); menuBar = new QMenuBar(RemoteControlClass); - menuBar->setObjectName(QString::fromUtf8("menuBar")); + menuBar->setObjectName(QStringLiteral("menuBar")); menuBar->setGeometry(QRect(0, 0, 344, 21)); menuFile = new QMenu(menuBar); - menuFile->setObjectName(QString::fromUtf8("menuFile")); + menuFile->setObjectName(QStringLiteral("menuFile")); RemoteControlClass->setMenuBar(menuBar); statusBar = new QStatusBar(RemoteControlClass); - statusBar->setObjectName(QString::fromUtf8("statusBar")); + statusBar->setObjectName(QStringLiteral("statusBar")); RemoteControlClass->setStatusBar(statusBar); menuBar->addAction(menuFile->menuAction()); diff --git a/tests/auto/tools/uic/baseline/saveformastemplate.ui.h b/tests/auto/tools/uic/baseline/saveformastemplate.ui.h index 32597cd6ffd..dba7834c969 100644 --- a/tests/auto/tools/uic/baseline/saveformastemplate.ui.h +++ b/tests/auto/tools/uic/baseline/saveformastemplate.ui.h @@ -84,13 +84,13 @@ public: void setupUi(QDialog *SaveFormAsTemplate) { if (SaveFormAsTemplate->objectName().isEmpty()) - SaveFormAsTemplate->setObjectName(QString::fromUtf8("SaveFormAsTemplate")); + SaveFormAsTemplate->setObjectName(QStringLiteral("SaveFormAsTemplate")); vboxLayout = new QVBoxLayout(SaveFormAsTemplate); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); formLayout = new QFormLayout(); - formLayout->setObjectName(QString::fromUtf8("formLayout")); + formLayout->setObjectName(QStringLiteral("formLayout")); label = new QLabel(SaveFormAsTemplate); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); label->setFrameShape(QFrame::NoFrame); label->setFrameShadow(QFrame::Plain); label->setTextFormat(Qt::AutoText); @@ -98,14 +98,14 @@ public: formLayout->setWidget(0, QFormLayout::LabelRole, label); templateNameEdit = new QLineEdit(SaveFormAsTemplate); - templateNameEdit->setObjectName(QString::fromUtf8("templateNameEdit")); + templateNameEdit->setObjectName(QStringLiteral("templateNameEdit")); templateNameEdit->setMinimumSize(QSize(222, 0)); templateNameEdit->setEchoMode(QLineEdit::Normal); formLayout->setWidget(0, QFormLayout::FieldRole, templateNameEdit); label_2 = new QLabel(SaveFormAsTemplate); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); label_2->setFrameShape(QFrame::NoFrame); label_2->setFrameShadow(QFrame::Plain); label_2->setTextFormat(Qt::AutoText); @@ -113,7 +113,7 @@ public: formLayout->setWidget(1, QFormLayout::LabelRole, label_2); categoryCombo = new QComboBox(SaveFormAsTemplate); - categoryCombo->setObjectName(QString::fromUtf8("categoryCombo")); + categoryCombo->setObjectName(QStringLiteral("categoryCombo")); formLayout->setWidget(1, QFormLayout::FieldRole, categoryCombo); @@ -121,14 +121,14 @@ public: vboxLayout->addLayout(formLayout); horizontalLine = new QFrame(SaveFormAsTemplate); - horizontalLine->setObjectName(QString::fromUtf8("horizontalLine")); + horizontalLine->setObjectName(QStringLiteral("horizontalLine")); horizontalLine->setFrameShape(QFrame::HLine); horizontalLine->setFrameShadow(QFrame::Sunken); vboxLayout->addWidget(horizontalLine); buttonBox = new QDialogButtonBox(SaveFormAsTemplate); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/settings.ui.h b/tests/auto/tools/uic/baseline/settings.ui.h index 0f87a29a65b..3fc9bad7102 100644 --- a/tests/auto/tools/uic/baseline/settings.ui.h +++ b/tests/auto/tools/uic/baseline/settings.ui.h @@ -51,14 +51,14 @@ public: void setupUi(QDialog *Dialog) { if (Dialog->objectName().isEmpty()) - Dialog->setObjectName(QString::fromUtf8("Dialog")); + Dialog->setObjectName(QStringLiteral("Dialog")); Dialog->resize(392, 176); verticalLayout = new QVBoxLayout(Dialog); - verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); hboxLayout = new QHBoxLayout(); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); label = new QLabel(Dialog); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -70,7 +70,7 @@ public: hboxLayout->addWidget(label); deviceCombo = new QComboBox(Dialog); - deviceCombo->setObjectName(QString::fromUtf8("deviceCombo")); + deviceCombo->setObjectName(QStringLiteral("deviceCombo")); QSizePolicy sizePolicy1(QSizePolicy::Minimum, QSizePolicy::Fixed); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); @@ -83,9 +83,9 @@ public: verticalLayout->addLayout(hboxLayout); hboxLayout1 = new QHBoxLayout(); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); label_6 = new QLabel(Dialog); - label_6->setObjectName(QString::fromUtf8("label_6")); + label_6->setObjectName(QStringLiteral("label_6")); sizePolicy.setHeightForWidth(label_6->sizePolicy().hasHeightForWidth()); label_6->setSizePolicy(sizePolicy); label_6->setMinimumSize(QSize(90, 0)); @@ -94,7 +94,7 @@ public: hboxLayout1->addWidget(label_6); audioEffectsCombo = new QComboBox(Dialog); - audioEffectsCombo->setObjectName(QString::fromUtf8("audioEffectsCombo")); + audioEffectsCombo->setObjectName(QStringLiteral("audioEffectsCombo")); sizePolicy1.setHeightForWidth(audioEffectsCombo->sizePolicy().hasHeightForWidth()); audioEffectsCombo->setSizePolicy(sizePolicy1); @@ -104,9 +104,9 @@ public: verticalLayout->addLayout(hboxLayout1); hboxLayout2 = new QHBoxLayout(); - hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2")); + hboxLayout2->setObjectName(QStringLiteral("hboxLayout2")); crossFadeLabel = new QLabel(Dialog); - crossFadeLabel->setObjectName(QString::fromUtf8("crossFadeLabel")); + crossFadeLabel->setObjectName(QStringLiteral("crossFadeLabel")); sizePolicy.setHeightForWidth(crossFadeLabel->sizePolicy().hasHeightForWidth()); crossFadeLabel->setSizePolicy(sizePolicy); crossFadeLabel->setMinimumSize(QSize(90, 0)); @@ -115,9 +115,9 @@ public: hboxLayout2->addWidget(crossFadeLabel); vboxLayout = new QVBoxLayout(); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); crossFadeSlider = new QSlider(Dialog); - crossFadeSlider->setObjectName(QString::fromUtf8("crossFadeSlider")); + crossFadeSlider->setObjectName(QStringLiteral("crossFadeSlider")); sizePolicy1.setHeightForWidth(crossFadeSlider->sizePolicy().hasHeightForWidth()); crossFadeSlider->setSizePolicy(sizePolicy1); crossFadeSlider->setMinimum(-20); @@ -131,9 +131,9 @@ public: vboxLayout->addWidget(crossFadeSlider); hboxLayout3 = new QHBoxLayout(); - hboxLayout3->setObjectName(QString::fromUtf8("hboxLayout3")); + hboxLayout3->setObjectName(QStringLiteral("hboxLayout3")); label_3 = new QLabel(Dialog); - label_3->setObjectName(QString::fromUtf8("label_3")); + label_3->setObjectName(QStringLiteral("label_3")); QFont font; font.setPointSize(9); label_3->setFont(font); @@ -145,7 +145,7 @@ public: hboxLayout3->addItem(spacerItem); label_5 = new QLabel(Dialog); - label_5->setObjectName(QString::fromUtf8("label_5")); + label_5->setObjectName(QStringLiteral("label_5")); label_5->setFont(font); hboxLayout3->addWidget(label_5); @@ -155,7 +155,7 @@ public: hboxLayout3->addItem(spacerItem1); label_4 = new QLabel(Dialog); - label_4->setObjectName(QString::fromUtf8("label_4")); + label_4->setObjectName(QStringLiteral("label_4")); label_4->setFont(font); hboxLayout3->addWidget(label_4); @@ -170,7 +170,7 @@ public: verticalLayout->addLayout(hboxLayout2); buttonBox = new QDialogButtonBox(Dialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/signalslotdialog.ui.h b/tests/auto/tools/uic/baseline/signalslotdialog.ui.h index 3027ac93f20..ea253fa7293 100644 --- a/tests/auto/tools/uic/baseline/signalslotdialog.ui.h +++ b/tests/auto/tools/uic/baseline/signalslotdialog.ui.h @@ -49,33 +49,33 @@ public: void setupUi(QDialog *SignalSlotDialogClass) { if (SignalSlotDialogClass->objectName().isEmpty()) - SignalSlotDialogClass->setObjectName(QString::fromUtf8("SignalSlotDialogClass")); + SignalSlotDialogClass->setObjectName(QStringLiteral("SignalSlotDialogClass")); SignalSlotDialogClass->resize(617, 535); vboxLayout = new QVBoxLayout(SignalSlotDialogClass); vboxLayout->setSpacing(6); vboxLayout->setContentsMargins(11, 11, 11, 11); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); slotGroupBox = new QGroupBox(SignalSlotDialogClass); - slotGroupBox->setObjectName(QString::fromUtf8("slotGroupBox")); + slotGroupBox->setObjectName(QStringLiteral("slotGroupBox")); vboxLayout1 = new QVBoxLayout(slotGroupBox); vboxLayout1->setSpacing(6); vboxLayout1->setContentsMargins(11, 11, 11, 11); - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); slotListView = new QListView(slotGroupBox); - slotListView->setObjectName(QString::fromUtf8("slotListView")); + slotListView->setObjectName(QStringLiteral("slotListView")); vboxLayout1->addWidget(slotListView); hboxLayout = new QHBoxLayout(); hboxLayout->setSpacing(6); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); addSlotButton = new QToolButton(slotGroupBox); - addSlotButton->setObjectName(QString::fromUtf8("addSlotButton")); + addSlotButton->setObjectName(QStringLiteral("addSlotButton")); hboxLayout->addWidget(addSlotButton); removeSlotButton = new QToolButton(slotGroupBox); - removeSlotButton->setObjectName(QString::fromUtf8("removeSlotButton")); + removeSlotButton->setObjectName(QStringLiteral("removeSlotButton")); hboxLayout->addWidget(removeSlotButton); @@ -90,26 +90,26 @@ public: vboxLayout->addWidget(slotGroupBox); signalGroupBox = new QGroupBox(SignalSlotDialogClass); - signalGroupBox->setObjectName(QString::fromUtf8("signalGroupBox")); + signalGroupBox->setObjectName(QStringLiteral("signalGroupBox")); vboxLayout2 = new QVBoxLayout(signalGroupBox); vboxLayout2->setSpacing(6); vboxLayout2->setContentsMargins(11, 11, 11, 11); - vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2")); + vboxLayout2->setObjectName(QStringLiteral("vboxLayout2")); signalListView = new QListView(signalGroupBox); - signalListView->setObjectName(QString::fromUtf8("signalListView")); + signalListView->setObjectName(QStringLiteral("signalListView")); vboxLayout2->addWidget(signalListView); hboxLayout1 = new QHBoxLayout(); hboxLayout1->setSpacing(6); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); addSignalButton = new QToolButton(signalGroupBox); - addSignalButton->setObjectName(QString::fromUtf8("addSignalButton")); + addSignalButton->setObjectName(QStringLiteral("addSignalButton")); hboxLayout1->addWidget(addSignalButton); removeSignalButton = new QToolButton(signalGroupBox); - removeSignalButton->setObjectName(QString::fromUtf8("removeSignalButton")); + removeSignalButton->setObjectName(QStringLiteral("removeSignalButton")); hboxLayout1->addWidget(removeSignalButton); @@ -124,7 +124,7 @@ public: vboxLayout->addWidget(signalGroupBox); buttonBox = new QDialogButtonBox(SignalSlotDialogClass); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); vboxLayout->addWidget(buttonBox); diff --git a/tests/auto/tools/uic/baseline/sslclient.ui.h b/tests/auto/tools/uic/baseline/sslclient.ui.h index 4dce9be2c3b..7d5b83b5dbe 100644 --- a/tests/auto/tools/uic/baseline/sslclient.ui.h +++ b/tests/auto/tools/uic/baseline/sslclient.ui.h @@ -52,29 +52,29 @@ public: void setupUi(QWidget *Form) { if (Form->objectName().isEmpty()) - Form->setObjectName(QString::fromUtf8("Form")); + Form->setObjectName(QStringLiteral("Form")); Form->resize(343, 320); vboxLayout = new QVBoxLayout(Form); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); gridLayout = new QGridLayout(); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); hostNameLabel = new QLabel(Form); - hostNameLabel->setObjectName(QString::fromUtf8("hostNameLabel")); + hostNameLabel->setObjectName(QStringLiteral("hostNameLabel")); gridLayout->addWidget(hostNameLabel, 0, 0, 1, 1); hostNameEdit = new QLineEdit(Form); - hostNameEdit->setObjectName(QString::fromUtf8("hostNameEdit")); + hostNameEdit->setObjectName(QStringLiteral("hostNameEdit")); gridLayout->addWidget(hostNameEdit, 0, 1, 1, 1); portLabel = new QLabel(Form); - portLabel->setObjectName(QString::fromUtf8("portLabel")); + portLabel->setObjectName(QStringLiteral("portLabel")); gridLayout->addWidget(portLabel, 1, 0, 1, 1); portBox = new QSpinBox(Form); - portBox->setObjectName(QString::fromUtf8("portBox")); + portBox->setObjectName(QStringLiteral("portBox")); portBox->setMinimum(1); portBox->setMaximum(65535); portBox->setValue(993); @@ -85,26 +85,26 @@ public: vboxLayout->addLayout(gridLayout); connectButton = new QPushButton(Form); - connectButton->setObjectName(QString::fromUtf8("connectButton")); + connectButton->setObjectName(QStringLiteral("connectButton")); connectButton->setEnabled(true); connectButton->setDefault(true); vboxLayout->addWidget(connectButton); sessionBox = new QGroupBox(Form); - sessionBox->setObjectName(QString::fromUtf8("sessionBox")); + sessionBox->setObjectName(QStringLiteral("sessionBox")); sessionBox->setEnabled(false); vboxLayout1 = new QVBoxLayout(sessionBox); - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); hboxLayout = new QHBoxLayout(); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); cipherText = new QLabel(sessionBox); - cipherText->setObjectName(QString::fromUtf8("cipherText")); + cipherText->setObjectName(QStringLiteral("cipherText")); hboxLayout->addWidget(cipherText); cipherLabel = new QLabel(sessionBox); - cipherLabel->setObjectName(QString::fromUtf8("cipherLabel")); + cipherLabel->setObjectName(QStringLiteral("cipherLabel")); cipherLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); hboxLayout->addWidget(cipherLabel); @@ -113,7 +113,7 @@ public: vboxLayout1->addLayout(hboxLayout); sessionOutput = new QTextEdit(sessionBox); - sessionOutput->setObjectName(QString::fromUtf8("sessionOutput")); + sessionOutput->setObjectName(QStringLiteral("sessionOutput")); sessionOutput->setEnabled(false); sessionOutput->setFocusPolicy(Qt::NoFocus); sessionOutput->setReadOnly(true); @@ -121,20 +121,20 @@ public: vboxLayout1->addWidget(sessionOutput); hboxLayout1 = new QHBoxLayout(); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); sessionInputLabel = new QLabel(sessionBox); - sessionInputLabel->setObjectName(QString::fromUtf8("sessionInputLabel")); + sessionInputLabel->setObjectName(QStringLiteral("sessionInputLabel")); hboxLayout1->addWidget(sessionInputLabel); sessionInput = new QLineEdit(sessionBox); - sessionInput->setObjectName(QString::fromUtf8("sessionInput")); + sessionInput->setObjectName(QStringLiteral("sessionInput")); sessionInput->setEnabled(false); hboxLayout1->addWidget(sessionInput); sendButton = new QPushButton(sessionBox); - sendButton->setObjectName(QString::fromUtf8("sendButton")); + sendButton->setObjectName(QStringLiteral("sendButton")); sendButton->setEnabled(false); sendButton->setFocusPolicy(Qt::TabFocus); sendButton->setDefault(true); diff --git a/tests/auto/tools/uic/baseline/sslerrors.ui.h b/tests/auto/tools/uic/baseline/sslerrors.ui.h index 2c3ade77bc0..c542baab3ca 100644 --- a/tests/auto/tools/uic/baseline/sslerrors.ui.h +++ b/tests/auto/tools/uic/baseline/sslerrors.ui.h @@ -40,25 +40,25 @@ public: void setupUi(QDialog *SslErrors) { if (SslErrors->objectName().isEmpty()) - SslErrors->setObjectName(QString::fromUtf8("SslErrors")); + SslErrors->setObjectName(QStringLiteral("SslErrors")); SslErrors->resize(371, 216); vboxLayout = new QVBoxLayout(SslErrors); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); label = new QLabel(SslErrors); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); label->setWordWrap(true); vboxLayout->addWidget(label); sslErrorList = new QListWidget(SslErrors); - sslErrorList->setObjectName(QString::fromUtf8("sslErrorList")); + sslErrorList->setObjectName(QStringLiteral("sslErrorList")); vboxLayout->addWidget(sslErrorList); hboxLayout = new QHBoxLayout(); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); certificateChainButton = new QPushButton(SslErrors); - certificateChainButton->setObjectName(QString::fromUtf8("certificateChainButton")); + certificateChainButton->setObjectName(QStringLiteral("certificateChainButton")); certificateChainButton->setAutoDefault(false); hboxLayout->addWidget(certificateChainButton); @@ -68,12 +68,12 @@ public: hboxLayout->addItem(spacerItem); pushButton = new QPushButton(SslErrors); - pushButton->setObjectName(QString::fromUtf8("pushButton")); + pushButton->setObjectName(QStringLiteral("pushButton")); hboxLayout->addWidget(pushButton); pushButton_2 = new QPushButton(SslErrors); - pushButton_2->setObjectName(QString::fromUtf8("pushButton_2")); + pushButton_2->setObjectName(QStringLiteral("pushButton_2")); hboxLayout->addWidget(pushButton_2); diff --git a/tests/auto/tools/uic/baseline/statistics.ui.h b/tests/auto/tools/uic/baseline/statistics.ui.h index b6e14b5ddaf..a812fb443f2 100644 --- a/tests/auto/tools/uic/baseline/statistics.ui.h +++ b/tests/auto/tools/uic/baseline/statistics.ui.h @@ -93,24 +93,24 @@ public: void setupUi(QDialog *Statistics) { if (Statistics->objectName().isEmpty()) - Statistics->setObjectName(QString::fromUtf8("Statistics")); - Statistics->setObjectName(QString::fromUtf8("linguist_stats")); + Statistics->setObjectName(QStringLiteral("Statistics")); + Statistics->setObjectName(QStringLiteral("linguist_stats")); Statistics->resize(336, 164); gridLayout = new QGridLayout(Statistics); gridLayout->setSpacing(6); gridLayout->setContentsMargins(11, 11, 11, 11); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); - gridLayout->setObjectName(QString::fromUtf8("unnamed")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); + gridLayout->setObjectName(QStringLiteral("unnamed")); hboxLayout = new QHBoxLayout(); hboxLayout->setSpacing(6); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); - hboxLayout->setObjectName(QString::fromUtf8("unnamed")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("unnamed")); spacer4_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); hboxLayout->addItem(spacer4_2); closeBtn = new QPushButton(Statistics); - closeBtn->setObjectName(QString::fromUtf8("closeBtn")); + closeBtn->setObjectName(QStringLiteral("closeBtn")); hboxLayout->addWidget(closeBtn); @@ -122,66 +122,66 @@ public: gridLayout->addLayout(hboxLayout, 1, 0, 1, 1); frame4 = new QFrame(Statistics); - frame4->setObjectName(QString::fromUtf8("frame4")); + frame4->setObjectName(QStringLiteral("frame4")); frame4->setFrameShape(QFrame::StyledPanel); frame4->setFrameShadow(QFrame::Raised); gridLayout1 = new QGridLayout(frame4); gridLayout1->setSpacing(6); gridLayout1->setContentsMargins(11, 11, 11, 11); - gridLayout1->setObjectName(QString::fromUtf8("gridLayout1")); - gridLayout1->setObjectName(QString::fromUtf8("unnamed")); + gridLayout1->setObjectName(QStringLiteral("gridLayout1")); + gridLayout1->setObjectName(QStringLiteral("unnamed")); textLabel4 = new QLabel(frame4); - textLabel4->setObjectName(QString::fromUtf8("textLabel4")); + textLabel4->setObjectName(QStringLiteral("textLabel4")); gridLayout1->addWidget(textLabel4, 0, 2, 1, 1); textLabel5 = new QLabel(frame4); - textLabel5->setObjectName(QString::fromUtf8("textLabel5")); + textLabel5->setObjectName(QStringLiteral("textLabel5")); gridLayout1->addWidget(textLabel5, 0, 1, 1, 1); untrWords = new QLabel(frame4); - untrWords->setObjectName(QString::fromUtf8("untrWords")); + untrWords->setObjectName(QStringLiteral("untrWords")); gridLayout1->addWidget(untrWords, 1, 1, 1, 1); trWords = new QLabel(frame4); - trWords->setObjectName(QString::fromUtf8("trWords")); + trWords->setObjectName(QStringLiteral("trWords")); gridLayout1->addWidget(trWords, 1, 2, 1, 1); textLabel1 = new QLabel(frame4); - textLabel1->setObjectName(QString::fromUtf8("textLabel1")); + textLabel1->setObjectName(QStringLiteral("textLabel1")); gridLayout1->addWidget(textLabel1, 1, 0, 1, 1); trChars = new QLabel(frame4); - trChars->setObjectName(QString::fromUtf8("trChars")); + trChars->setObjectName(QStringLiteral("trChars")); gridLayout1->addWidget(trChars, 2, 2, 1, 1); untrChars = new QLabel(frame4); - untrChars->setObjectName(QString::fromUtf8("untrChars")); + untrChars->setObjectName(QStringLiteral("untrChars")); gridLayout1->addWidget(untrChars, 2, 1, 1, 1); textLabel3 = new QLabel(frame4); - textLabel3->setObjectName(QString::fromUtf8("textLabel3")); + textLabel3->setObjectName(QStringLiteral("textLabel3")); gridLayout1->addWidget(textLabel3, 2, 0, 1, 1); textLabel6 = new QLabel(frame4); - textLabel6->setObjectName(QString::fromUtf8("textLabel6")); + textLabel6->setObjectName(QStringLiteral("textLabel6")); gridLayout1->addWidget(textLabel6, 3, 0, 1, 1); trCharsSpc = new QLabel(frame4); - trCharsSpc->setObjectName(QString::fromUtf8("trCharsSpc")); + trCharsSpc->setObjectName(QStringLiteral("trCharsSpc")); gridLayout1->addWidget(trCharsSpc, 3, 2, 1, 1); untrCharsSpc = new QLabel(frame4); - untrCharsSpc->setObjectName(QString::fromUtf8("untrCharsSpc")); + untrCharsSpc->setObjectName(QStringLiteral("untrCharsSpc")); gridLayout1->addWidget(untrCharsSpc, 3, 1, 1, 1); diff --git a/tests/auto/tools/uic/baseline/stringlisteditor.ui.h b/tests/auto/tools/uic/baseline/stringlisteditor.ui.h index 7624eaec58f..d3033dc5947 100644 --- a/tests/auto/tools/uic/baseline/stringlisteditor.ui.h +++ b/tests/auto/tools/uic/baseline/stringlisteditor.ui.h @@ -99,7 +99,7 @@ public: void setupUi(QDialog *qdesigner_internal__Dialog) { if (qdesigner_internal__Dialog->objectName().isEmpty()) - qdesigner_internal__Dialog->setObjectName(QString::fromUtf8("qdesigner_internal__Dialog")); + qdesigner_internal__Dialog->setObjectName(QStringLiteral("qdesigner_internal__Dialog")); qdesigner_internal__Dialog->resize(400, 300); vboxLayout = new QVBoxLayout(qdesigner_internal__Dialog); #ifndef Q_OS_MAC @@ -108,9 +108,9 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); groupBox = new QGroupBox(qdesigner_internal__Dialog); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); gridLayout = new QGridLayout(groupBox); #ifndef Q_OS_MAC gridLayout->setSpacing(6); @@ -118,7 +118,7 @@ public: #ifndef Q_OS_MAC gridLayout->setContentsMargins(9, 9, 9, 9); #endif - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); vboxLayout1 = new QVBoxLayout(); #ifndef Q_OS_MAC vboxLayout1->setSpacing(6); @@ -126,7 +126,7 @@ public: #ifndef Q_OS_MAC vboxLayout1->setContentsMargins(0, 0, 0, 0); #endif - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); hboxLayout = new QHBoxLayout(); #ifndef Q_OS_MAC hboxLayout->setSpacing(6); @@ -134,15 +134,15 @@ public: #ifndef Q_OS_MAC hboxLayout->setContentsMargins(0, 0, 0, 0); #endif - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); newButton = new QToolButton(groupBox); - newButton->setObjectName(QString::fromUtf8("newButton")); + newButton->setObjectName(QStringLiteral("newButton")); newButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); hboxLayout->addWidget(newButton); deleteButton = new QToolButton(groupBox); - deleteButton->setObjectName(QString::fromUtf8("deleteButton")); + deleteButton->setObjectName(QStringLiteral("deleteButton")); deleteButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); hboxLayout->addWidget(deleteButton); @@ -159,14 +159,14 @@ public: hboxLayout1->setSpacing(6); #endif hboxLayout1->setContentsMargins(0, 0, 0, 0); - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); label = new QLabel(groupBox); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); hboxLayout1->addWidget(label); valueEdit = new QLineEdit(groupBox); - valueEdit->setObjectName(QString::fromUtf8("valueEdit")); + valueEdit->setObjectName(QStringLiteral("valueEdit")); hboxLayout1->addWidget(valueEdit); @@ -181,18 +181,18 @@ public: vboxLayout2->setSpacing(6); #endif vboxLayout2->setContentsMargins(0, 0, 0, 0); - vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2")); + vboxLayout2->setObjectName(QStringLiteral("vboxLayout2")); spacerItem1 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); vboxLayout2->addItem(spacerItem1); upButton = new QToolButton(groupBox); - upButton->setObjectName(QString::fromUtf8("upButton")); + upButton->setObjectName(QStringLiteral("upButton")); vboxLayout2->addWidget(upButton); downButton = new QToolButton(groupBox); - downButton->setObjectName(QString::fromUtf8("downButton")); + downButton->setObjectName(QStringLiteral("downButton")); vboxLayout2->addWidget(downButton); @@ -204,7 +204,7 @@ public: gridLayout->addLayout(vboxLayout2, 0, 1, 1, 1); listView = new QListView(groupBox); - listView->setObjectName(QString::fromUtf8("listView")); + listView->setObjectName(QStringLiteral("listView")); gridLayout->addWidget(listView, 0, 0, 1, 1); @@ -212,7 +212,7 @@ public: vboxLayout->addWidget(groupBox); buttonBox = new QDialogButtonBox(qdesigner_internal__Dialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h b/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h index f5e8e2ea98b..e4b2deb4982 100644 --- a/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h +++ b/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h @@ -45,7 +45,7 @@ public: void setupUi(QWidget *StyleSheetEditor) { if (StyleSheetEditor->objectName().isEmpty()) - StyleSheetEditor->setObjectName(QString::fromUtf8("StyleSheetEditor")); + StyleSheetEditor->setObjectName(QStringLiteral("StyleSheetEditor")); StyleSheetEditor->resize(445, 289); gridLayout = new QGridLayout(StyleSheetEditor); #ifndef Q_OS_MAC @@ -54,7 +54,7 @@ public: #ifndef Q_OS_MAC gridLayout->setContentsMargins(9, 9, 9, 9); #endif - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); spacerItem = new QSpacerItem(32, 20, QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); gridLayout->addItem(spacerItem, 0, 6, 1, 1); @@ -64,7 +64,7 @@ public: gridLayout->addItem(spacerItem1, 0, 0, 1, 1); styleSheetCombo = new QComboBox(StyleSheetEditor); - styleSheetCombo->setObjectName(QString::fromUtf8("styleSheetCombo")); + styleSheetCombo->setObjectName(QStringLiteral("styleSheetCombo")); gridLayout->addWidget(styleSheetCombo, 0, 5, 1, 1); @@ -73,7 +73,7 @@ public: gridLayout->addItem(spacerItem2, 0, 3, 1, 1); styleCombo = new QComboBox(StyleSheetEditor); - styleCombo->setObjectName(QString::fromUtf8("styleCombo")); + styleCombo->setObjectName(QStringLiteral("styleCombo")); QSizePolicy sizePolicy(static_cast(5), static_cast(0)); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -83,7 +83,7 @@ public: gridLayout->addWidget(styleCombo, 0, 2, 1, 1); label_7 = new QLabel(StyleSheetEditor); - label_7->setObjectName(QString::fromUtf8("label_7")); + label_7->setObjectName(QStringLiteral("label_7")); QSizePolicy sizePolicy1(static_cast(0), static_cast(5)); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); @@ -97,13 +97,13 @@ public: hboxLayout->setSpacing(6); #endif hboxLayout->setContentsMargins(0, 0, 0, 0); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); spacerItem3 = new QSpacerItem(321, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); hboxLayout->addItem(spacerItem3); applyButton = new QPushButton(StyleSheetEditor); - applyButton->setObjectName(QString::fromUtf8("applyButton")); + applyButton->setObjectName(QStringLiteral("applyButton")); applyButton->setEnabled(false); hboxLayout->addWidget(applyButton); @@ -112,12 +112,12 @@ public: gridLayout->addLayout(hboxLayout, 2, 0, 1, 7); styleTextEdit = new QTextEdit(StyleSheetEditor); - styleTextEdit->setObjectName(QString::fromUtf8("styleTextEdit")); + styleTextEdit->setObjectName(QStringLiteral("styleTextEdit")); gridLayout->addWidget(styleTextEdit, 1, 0, 1, 7); label_8 = new QLabel(StyleSheetEditor); - label_8->setObjectName(QString::fromUtf8("label_8")); + label_8->setObjectName(QStringLiteral("label_8")); sizePolicy1.setHeightForWidth(label_8->sizePolicy().hasHeightForWidth()); label_8->setSizePolicy(sizePolicy1); diff --git a/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h b/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h index 424871f688b..1e99c413125 100644 --- a/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h +++ b/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h @@ -93,28 +93,28 @@ public: void setupUi(QWidget *TabbedBrowser) { if (TabbedBrowser->objectName().isEmpty()) - TabbedBrowser->setObjectName(QString::fromUtf8("TabbedBrowser")); + TabbedBrowser->setObjectName(QStringLiteral("TabbedBrowser")); TabbedBrowser->resize(710, 664); vboxLayout = new QVBoxLayout(TabbedBrowser); vboxLayout->setSpacing(0); vboxLayout->setContentsMargins(0, 0, 0, 0); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); tab = new QTabWidget(TabbedBrowser); - tab->setObjectName(QString::fromUtf8("tab")); + tab->setObjectName(QStringLiteral("tab")); frontpage = new QWidget(); - frontpage->setObjectName(QString::fromUtf8("frontpage")); + frontpage->setObjectName(QStringLiteral("frontpage")); gridLayout = new QGridLayout(frontpage); #ifndef Q_OS_MAC gridLayout->setSpacing(6); #endif gridLayout->setContentsMargins(8, 8, 8, 8); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); tab->addTab(frontpage, QString()); vboxLayout->addWidget(tab); frameFind = new QFrame(TabbedBrowser); - frameFind->setObjectName(QString::fromUtf8("frameFind")); + frameFind->setObjectName(QStringLiteral("frameFind")); frameFind->setFrameShape(QFrame::StyledPanel); frameFind->setFrameShadow(QFrame::Raised); hboxLayout = new QHBoxLayout(frameFind); @@ -122,9 +122,9 @@ public: hboxLayout->setSpacing(6); #endif hboxLayout->setContentsMargins(0, 0, 0, 0); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); toolClose = new QToolButton(frameFind); - toolClose->setObjectName(QString::fromUtf8("toolClose")); + toolClose->setObjectName(QStringLiteral("toolClose")); const QIcon icon = QIcon(QString::fromUtf8(":/trolltech/assistant/images/close.png")); toolClose->setIcon(icon); toolClose->setAutoRaise(true); @@ -132,7 +132,7 @@ public: hboxLayout->addWidget(toolClose); editFind = new QLineEdit(frameFind); - editFind->setObjectName(QString::fromUtf8("editFind")); + editFind->setObjectName(QStringLiteral("editFind")); QSizePolicy sizePolicy(static_cast(0), static_cast(0)); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -143,7 +143,7 @@ public: hboxLayout->addWidget(editFind); toolPrevious = new QToolButton(frameFind); - toolPrevious->setObjectName(QString::fromUtf8("toolPrevious")); + toolPrevious->setObjectName(QStringLiteral("toolPrevious")); const QIcon icon1 = QIcon(QString::fromUtf8(":/trolltech/assistant/images/win/previous.png")); toolPrevious->setIcon(icon1); toolPrevious->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); @@ -152,7 +152,7 @@ public: hboxLayout->addWidget(toolPrevious); toolNext = new QToolButton(frameFind); - toolNext->setObjectName(QString::fromUtf8("toolNext")); + toolNext->setObjectName(QStringLiteral("toolNext")); toolNext->setMinimumSize(QSize(0, 0)); const QIcon icon2 = QIcon(QString::fromUtf8(":/trolltech/assistant/images/win/next.png")); toolNext->setIcon(icon2); @@ -163,17 +163,17 @@ public: hboxLayout->addWidget(toolNext); checkCase = new QCheckBox(frameFind); - checkCase->setObjectName(QString::fromUtf8("checkCase")); + checkCase->setObjectName(QStringLiteral("checkCase")); hboxLayout->addWidget(checkCase); checkWholeWords = new QCheckBox(frameFind); - checkWholeWords->setObjectName(QString::fromUtf8("checkWholeWords")); + checkWholeWords->setObjectName(QStringLiteral("checkWholeWords")); hboxLayout->addWidget(checkWholeWords); labelWrapped = new QLabel(frameFind); - labelWrapped->setObjectName(QString::fromUtf8("labelWrapped")); + labelWrapped->setObjectName(QStringLiteral("labelWrapped")); labelWrapped->setMinimumSize(QSize(0, 20)); labelWrapped->setMaximumSize(QSize(105, 20)); labelWrapped->setTextFormat(Qt::RichText); diff --git a/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h b/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h index da5357d1fda..50542353c44 100644 --- a/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h +++ b/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h @@ -120,28 +120,28 @@ public: void setupUi(QDialog *qdesigner_internal__TableWidgetEditor) { if (qdesigner_internal__TableWidgetEditor->objectName().isEmpty()) - qdesigner_internal__TableWidgetEditor->setObjectName(QString::fromUtf8("qdesigner_internal__TableWidgetEditor")); + qdesigner_internal__TableWidgetEditor->setObjectName(QStringLiteral("qdesigner_internal__TableWidgetEditor")); qdesigner_internal__TableWidgetEditor->resize(591, 455); gridLayout_4 = new QGridLayout(qdesigner_internal__TableWidgetEditor); - gridLayout_4->setObjectName(QString::fromUtf8("gridLayout_4")); + gridLayout_4->setObjectName(QStringLiteral("gridLayout_4")); itemsBox = new QGroupBox(qdesigner_internal__TableWidgetEditor); - itemsBox->setObjectName(QString::fromUtf8("itemsBox")); + itemsBox->setObjectName(QStringLiteral("itemsBox")); gridLayout = new QGridLayout(itemsBox); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); tableWidget = new QTableWidget(itemsBox); - tableWidget->setObjectName(QString::fromUtf8("tableWidget")); + tableWidget->setObjectName(QStringLiteral("tableWidget")); gridLayout->addWidget(tableWidget, 0, 0, 1, 1); horizontalLayout_5 = new QHBoxLayout(); - horizontalLayout_5->setObjectName(QString::fromUtf8("horizontalLayout_5")); + horizontalLayout_5->setObjectName(QStringLiteral("horizontalLayout_5")); label_3 = new QLabel(itemsBox); - label_3->setObjectName(QString::fromUtf8("label_3")); + label_3->setObjectName(QStringLiteral("label_3")); horizontalLayout_5->addWidget(label_3); itemIconSelector = new qdesigner_internal::IconSelector(itemsBox); - itemIconSelector->setObjectName(QString::fromUtf8("itemIconSelector")); + itemIconSelector->setObjectName(QStringLiteral("itemIconSelector")); horizontalLayout_5->addWidget(itemIconSelector); @@ -156,14 +156,14 @@ public: gridLayout_4->addWidget(itemsBox, 0, 0, 1, 1); buttonBox = new QDialogButtonBox(qdesigner_internal__TableWidgetEditor); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); gridLayout_4->addWidget(buttonBox, 1, 0, 1, 2); widget = new QWidget(qdesigner_internal__TableWidgetEditor); - widget->setObjectName(QString::fromUtf8("widget")); + widget->setObjectName(QStringLiteral("widget")); QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -171,13 +171,13 @@ public: widget->setSizePolicy(sizePolicy); verticalLayout = new QVBoxLayout(widget); verticalLayout->setContentsMargins(0, 0, 0, 0); - verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); columnsBox = new QGroupBox(widget); - columnsBox->setObjectName(QString::fromUtf8("columnsBox")); + columnsBox->setObjectName(QStringLiteral("columnsBox")); gridLayout_2 = new QGridLayout(columnsBox); - gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2")); + gridLayout_2->setObjectName(QStringLiteral("gridLayout_2")); columnsListWidget = new QListWidget(columnsBox); - columnsListWidget->setObjectName(QString::fromUtf8("columnsListWidget")); + columnsListWidget->setObjectName(QStringLiteral("columnsListWidget")); QSizePolicy sizePolicy1(QSizePolicy::Ignored, QSizePolicy::Expanding); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); @@ -188,14 +188,14 @@ public: gridLayout_2->addWidget(columnsListWidget, 0, 0, 1, 1); horizontalLayout_3 = new QHBoxLayout(); - horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3")); + horizontalLayout_3->setObjectName(QStringLiteral("horizontalLayout_3")); newColumnButton = new QToolButton(columnsBox); - newColumnButton->setObjectName(QString::fromUtf8("newColumnButton")); + newColumnButton->setObjectName(QStringLiteral("newColumnButton")); horizontalLayout_3->addWidget(newColumnButton); deleteColumnButton = new QToolButton(columnsBox); - deleteColumnButton->setObjectName(QString::fromUtf8("deleteColumnButton")); + deleteColumnButton->setObjectName(QStringLiteral("deleteColumnButton")); horizontalLayout_3->addWidget(deleteColumnButton); @@ -204,12 +204,12 @@ public: horizontalLayout_3->addItem(spacerItem); moveColumnUpButton = new QToolButton(columnsBox); - moveColumnUpButton->setObjectName(QString::fromUtf8("moveColumnUpButton")); + moveColumnUpButton->setObjectName(QStringLiteral("moveColumnUpButton")); horizontalLayout_3->addWidget(moveColumnUpButton); moveColumnDownButton = new QToolButton(columnsBox); - moveColumnDownButton->setObjectName(QString::fromUtf8("moveColumnDownButton")); + moveColumnDownButton->setObjectName(QStringLiteral("moveColumnDownButton")); horizontalLayout_3->addWidget(moveColumnDownButton); @@ -217,14 +217,14 @@ public: gridLayout_2->addLayout(horizontalLayout_3, 1, 0, 1, 1); horizontalLayout_2 = new QHBoxLayout(); - horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2")); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); label = new QLabel(columnsBox); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); horizontalLayout_2->addWidget(label); columnIconSelector = new qdesigner_internal::IconSelector(columnsBox); - columnIconSelector->setObjectName(QString::fromUtf8("columnIconSelector")); + columnIconSelector->setObjectName(QStringLiteral("columnIconSelector")); horizontalLayout_2->addWidget(columnIconSelector); @@ -239,11 +239,11 @@ public: verticalLayout->addWidget(columnsBox); rowsBox = new QGroupBox(widget); - rowsBox->setObjectName(QString::fromUtf8("rowsBox")); + rowsBox->setObjectName(QStringLiteral("rowsBox")); gridLayout_3 = new QGridLayout(rowsBox); - gridLayout_3->setObjectName(QString::fromUtf8("gridLayout_3")); + gridLayout_3->setObjectName(QStringLiteral("gridLayout_3")); rowsListWidget = new QListWidget(rowsBox); - rowsListWidget->setObjectName(QString::fromUtf8("rowsListWidget")); + rowsListWidget->setObjectName(QStringLiteral("rowsListWidget")); sizePolicy1.setHeightForWidth(rowsListWidget->sizePolicy().hasHeightForWidth()); rowsListWidget->setSizePolicy(sizePolicy1); rowsListWidget->setFocusPolicy(Qt::TabFocus); @@ -251,14 +251,14 @@ public: gridLayout_3->addWidget(rowsListWidget, 0, 0, 1, 1); horizontalLayout_4 = new QHBoxLayout(); - horizontalLayout_4->setObjectName(QString::fromUtf8("horizontalLayout_4")); + horizontalLayout_4->setObjectName(QStringLiteral("horizontalLayout_4")); newRowButton = new QToolButton(rowsBox); - newRowButton->setObjectName(QString::fromUtf8("newRowButton")); + newRowButton->setObjectName(QStringLiteral("newRowButton")); horizontalLayout_4->addWidget(newRowButton); deleteRowButton = new QToolButton(rowsBox); - deleteRowButton->setObjectName(QString::fromUtf8("deleteRowButton")); + deleteRowButton->setObjectName(QStringLiteral("deleteRowButton")); horizontalLayout_4->addWidget(deleteRowButton); @@ -267,12 +267,12 @@ public: horizontalLayout_4->addItem(spacerItem2); moveRowUpButton = new QToolButton(rowsBox); - moveRowUpButton->setObjectName(QString::fromUtf8("moveRowUpButton")); + moveRowUpButton->setObjectName(QStringLiteral("moveRowUpButton")); horizontalLayout_4->addWidget(moveRowUpButton); moveRowDownButton = new QToolButton(rowsBox); - moveRowDownButton->setObjectName(QString::fromUtf8("moveRowDownButton")); + moveRowDownButton->setObjectName(QStringLiteral("moveRowDownButton")); horizontalLayout_4->addWidget(moveRowDownButton); @@ -280,14 +280,14 @@ public: gridLayout_3->addLayout(horizontalLayout_4, 1, 0, 1, 1); horizontalLayout = new QHBoxLayout(); - horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); label_2 = new QLabel(rowsBox); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); horizontalLayout->addWidget(label_2); rowIconSelector = new qdesigner_internal::IconSelector(rowsBox); - rowIconSelector->setObjectName(QString::fromUtf8("rowIconSelector")); + rowIconSelector->setObjectName(QStringLiteral("rowIconSelector")); horizontalLayout->addWidget(rowIconSelector); diff --git a/tests/auto/tools/uic/baseline/tetrixwindow.ui.h b/tests/auto/tools/uic/baseline/tetrixwindow.ui.h index 7d29265ba30..48d6a4e6a38 100644 --- a/tests/auto/tools/uic/baseline/tetrixwindow.ui.h +++ b/tests/auto/tools/uic/baseline/tetrixwindow.ui.h @@ -46,7 +46,7 @@ public: void setupUi(QWidget *TetrixWindow) { if (TetrixWindow->objectName().isEmpty()) - TetrixWindow->setObjectName(QString::fromUtf8("TetrixWindow")); + TetrixWindow->setObjectName(QStringLiteral("TetrixWindow")); TetrixWindow->resize(537, 475); vboxLayout = new QVBoxLayout(TetrixWindow); #ifndef Q_OS_MAC @@ -55,7 +55,7 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); gridLayout = new QGridLayout(); #ifndef Q_OS_MAC gridLayout->setSpacing(6); @@ -63,39 +63,39 @@ public: #ifndef Q_OS_MAC gridLayout->setContentsMargins(0, 0, 0, 0); #endif - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); startButton = new QPushButton(TetrixWindow); - startButton->setObjectName(QString::fromUtf8("startButton")); + startButton->setObjectName(QStringLiteral("startButton")); startButton->setFocusPolicy(Qt::NoFocus); gridLayout->addWidget(startButton, 4, 0, 1, 1); linesLcd = new QLCDNumber(TetrixWindow); - linesLcd->setObjectName(QString::fromUtf8("linesLcd")); + linesLcd->setObjectName(QStringLiteral("linesLcd")); linesLcd->setSegmentStyle(QLCDNumber::Filled); gridLayout->addWidget(linesLcd, 3, 2, 1, 1); linesRemovedLabel = new QLabel(TetrixWindow); - linesRemovedLabel->setObjectName(QString::fromUtf8("linesRemovedLabel")); + linesRemovedLabel->setObjectName(QStringLiteral("linesRemovedLabel")); linesRemovedLabel->setAlignment(Qt::AlignBottom|Qt::AlignHCenter); gridLayout->addWidget(linesRemovedLabel, 2, 2, 1, 1); pauseButton = new QPushButton(TetrixWindow); - pauseButton->setObjectName(QString::fromUtf8("pauseButton")); + pauseButton->setObjectName(QStringLiteral("pauseButton")); pauseButton->setFocusPolicy(Qt::NoFocus); gridLayout->addWidget(pauseButton, 5, 2, 1, 1); scoreLcd = new QLCDNumber(TetrixWindow); - scoreLcd->setObjectName(QString::fromUtf8("scoreLcd")); + scoreLcd->setObjectName(QStringLiteral("scoreLcd")); scoreLcd->setSegmentStyle(QLCDNumber::Filled); gridLayout->addWidget(scoreLcd, 1, 2, 1, 1); board = new TetrixBoard(TetrixWindow); - board->setObjectName(QString::fromUtf8("board")); + board->setObjectName(QStringLiteral("board")); board->setFocusPolicy(Qt::StrongFocus); board->setFrameShape(QFrame::Panel); board->setFrameShadow(QFrame::Sunken); @@ -103,31 +103,31 @@ public: gridLayout->addWidget(board, 0, 1, 6, 1); levelLabel = new QLabel(TetrixWindow); - levelLabel->setObjectName(QString::fromUtf8("levelLabel")); + levelLabel->setObjectName(QStringLiteral("levelLabel")); levelLabel->setAlignment(Qt::AlignBottom|Qt::AlignHCenter); gridLayout->addWidget(levelLabel, 2, 0, 1, 1); nextLabel = new QLabel(TetrixWindow); - nextLabel->setObjectName(QString::fromUtf8("nextLabel")); + nextLabel->setObjectName(QStringLiteral("nextLabel")); nextLabel->setAlignment(Qt::AlignBottom|Qt::AlignHCenter); gridLayout->addWidget(nextLabel, 0, 0, 1, 1); levelLcd = new QLCDNumber(TetrixWindow); - levelLcd->setObjectName(QString::fromUtf8("levelLcd")); + levelLcd->setObjectName(QStringLiteral("levelLcd")); levelLcd->setSegmentStyle(QLCDNumber::Filled); gridLayout->addWidget(levelLcd, 3, 0, 1, 1); scoreLabel = new QLabel(TetrixWindow); - scoreLabel->setObjectName(QString::fromUtf8("scoreLabel")); + scoreLabel->setObjectName(QStringLiteral("scoreLabel")); scoreLabel->setAlignment(Qt::AlignBottom|Qt::AlignHCenter); gridLayout->addWidget(scoreLabel, 0, 2, 1, 1); nextPieceLabel = new QLabel(TetrixWindow); - nextPieceLabel->setObjectName(QString::fromUtf8("nextPieceLabel")); + nextPieceLabel->setObjectName(QStringLiteral("nextPieceLabel")); nextPieceLabel->setFrameShape(QFrame::Box); nextPieceLabel->setFrameShadow(QFrame::Raised); nextPieceLabel->setAlignment(Qt::AlignCenter); @@ -135,7 +135,7 @@ public: gridLayout->addWidget(nextPieceLabel, 1, 0, 1, 1); quitButton = new QPushButton(TetrixWindow); - quitButton->setObjectName(QString::fromUtf8("quitButton")); + quitButton->setObjectName(QStringLiteral("quitButton")); quitButton->setFocusPolicy(Qt::NoFocus); gridLayout->addWidget(quitButton, 4, 2, 1, 1); diff --git a/tests/auto/tools/uic/baseline/textfinder.ui.h b/tests/auto/tools/uic/baseline/textfinder.ui.h index 4d6e57b3f9a..9a5641c3de9 100644 --- a/tests/auto/tools/uic/baseline/textfinder.ui.h +++ b/tests/auto/tools/uic/baseline/textfinder.ui.h @@ -40,7 +40,7 @@ public: void setupUi(QWidget *Form) { if (Form->objectName().isEmpty()) - Form->setObjectName(QString::fromUtf8("Form")); + Form->setObjectName(QStringLiteral("Form")); Form->resize(378, 158); vboxLayout = new QVBoxLayout(Form); #ifndef Q_OS_MAC @@ -49,7 +49,7 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); gridLayout = new QGridLayout(); #ifndef Q_OS_MAC gridLayout->setSpacing(6); @@ -57,19 +57,19 @@ public: #ifndef Q_OS_MAC gridLayout->setContentsMargins(0, 0, 0, 0); #endif - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); lineEdit = new QLineEdit(Form); - lineEdit->setObjectName(QString::fromUtf8("lineEdit")); + lineEdit->setObjectName(QStringLiteral("lineEdit")); gridLayout->addWidget(lineEdit, 0, 1, 1, 1); searchLabel = new QLabel(Form); - searchLabel->setObjectName(QString::fromUtf8("searchLabel")); + searchLabel->setObjectName(QStringLiteral("searchLabel")); gridLayout->addWidget(searchLabel, 0, 0, 1, 1); findButton = new QPushButton(Form); - findButton->setObjectName(QString::fromUtf8("findButton")); + findButton->setObjectName(QStringLiteral("findButton")); gridLayout->addWidget(findButton, 0, 2, 1, 1); @@ -77,7 +77,7 @@ public: vboxLayout->addLayout(gridLayout); textEdit = new QTextEdit(Form); - textEdit->setObjectName(QString::fromUtf8("textEdit")); + textEdit->setObjectName(QStringLiteral("textEdit")); vboxLayout->addWidget(textEdit); diff --git a/tests/auto/tools/uic/baseline/topicchooser.ui.h b/tests/auto/tools/uic/baseline/topicchooser.ui.h index cf3186c1d93..3b16d5a6271 100644 --- a/tests/auto/tools/uic/baseline/topicchooser.ui.h +++ b/tests/auto/tools/uic/baseline/topicchooser.ui.h @@ -41,7 +41,7 @@ public: void setupUi(QDialog *TopicChooser) { if (TopicChooser->objectName().isEmpty()) - TopicChooser->setObjectName(QString::fromUtf8("TopicChooser")); + TopicChooser->setObjectName(QStringLiteral("TopicChooser")); TopicChooser->resize(391, 223); TopicChooser->setSizeGripEnabled(true); vboxLayout = new QVBoxLayout(TopicChooser); @@ -49,41 +49,41 @@ public: vboxLayout->setSpacing(6); #endif vboxLayout->setContentsMargins(11, 11, 11, 11); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); - vboxLayout->setObjectName(QString::fromUtf8("unnamed")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("unnamed")); label = new QLabel(TopicChooser); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); vboxLayout->addWidget(label); listWidget = new QListWidget(TopicChooser); - listWidget->setObjectName(QString::fromUtf8("listWidget")); + listWidget->setObjectName(QStringLiteral("listWidget")); vboxLayout->addWidget(listWidget); Layout16 = new QWidget(TopicChooser); - Layout16->setObjectName(QString::fromUtf8("Layout16")); + Layout16->setObjectName(QStringLiteral("Layout16")); hboxLayout = new QHBoxLayout(Layout16); #ifndef Q_OS_MAC hboxLayout->setSpacing(6); #endif hboxLayout->setContentsMargins(0, 0, 0, 0); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); - hboxLayout->setObjectName(QString::fromUtf8("unnamed")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("unnamed")); hboxLayout->setContentsMargins(0, 0, 0, 0); Horizontal_Spacing2 = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); hboxLayout->addItem(Horizontal_Spacing2); buttonDisplay = new QPushButton(Layout16); - buttonDisplay->setObjectName(QString::fromUtf8("buttonDisplay")); + buttonDisplay->setObjectName(QStringLiteral("buttonDisplay")); buttonDisplay->setAutoDefault(true); buttonDisplay->setDefault(true); hboxLayout->addWidget(buttonDisplay); buttonCancel = new QPushButton(Layout16); - buttonCancel->setObjectName(QString::fromUtf8("buttonCancel")); + buttonCancel->setObjectName(QStringLiteral("buttonCancel")); buttonCancel->setAutoDefault(true); hboxLayout->addWidget(buttonCancel); diff --git a/tests/auto/tools/uic/baseline/translatedialog.ui.h b/tests/auto/tools/uic/baseline/translatedialog.ui.h index 8ff12becc9b..d811b13720d 100644 --- a/tests/auto/tools/uic/baseline/translatedialog.ui.h +++ b/tests/auto/tools/uic/baseline/translatedialog.ui.h @@ -96,7 +96,7 @@ public: void setupUi(QDialog *TranslateDialog) { if (TranslateDialog->objectName().isEmpty()) - TranslateDialog->setObjectName(QString::fromUtf8("TranslateDialog")); + TranslateDialog->setObjectName(QStringLiteral("TranslateDialog")); TranslateDialog->resize(407, 145); QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); sizePolicy.setHorizontalStretch(0); @@ -106,35 +106,35 @@ public: hboxLayout = new QHBoxLayout(TranslateDialog); hboxLayout->setSpacing(6); hboxLayout->setContentsMargins(11, 11, 11, 11); - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); hboxLayout->setContentsMargins(9, 9, 9, 9); vboxLayout = new QVBoxLayout(); vboxLayout->setSpacing(6); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); vboxLayout->setContentsMargins(0, 0, 0, 0); gridLayout = new QGridLayout(); gridLayout->setSpacing(6); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); gridLayout->setHorizontalSpacing(6); gridLayout->setVerticalSpacing(6); gridLayout->setContentsMargins(0, 0, 0, 0); ledTranslateTo = new QLineEdit(TranslateDialog); - ledTranslateTo->setObjectName(QString::fromUtf8("ledTranslateTo")); + ledTranslateTo->setObjectName(QStringLiteral("ledTranslateTo")); gridLayout->addWidget(ledTranslateTo, 1, 1, 1, 1); findWhat = new QLabel(TranslateDialog); - findWhat->setObjectName(QString::fromUtf8("findWhat")); + findWhat->setObjectName(QStringLiteral("findWhat")); gridLayout->addWidget(findWhat, 0, 0, 1, 1); translateTo = new QLabel(TranslateDialog); - translateTo->setObjectName(QString::fromUtf8("translateTo")); + translateTo->setObjectName(QStringLiteral("translateTo")); gridLayout->addWidget(translateTo, 1, 0, 1, 1); ledFindWhat = new QLineEdit(TranslateDialog); - ledFindWhat->setObjectName(QString::fromUtf8("ledFindWhat")); + ledFindWhat->setObjectName(QStringLiteral("ledFindWhat")); gridLayout->addWidget(ledFindWhat, 0, 1, 1, 1); @@ -142,18 +142,18 @@ public: vboxLayout->addLayout(gridLayout); groupBox = new QGroupBox(TranslateDialog); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); vboxLayout1 = new QVBoxLayout(groupBox); vboxLayout1->setSpacing(6); vboxLayout1->setContentsMargins(11, 11, 11, 11); - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); ckMatchCase = new QCheckBox(groupBox); - ckMatchCase->setObjectName(QString::fromUtf8("ckMatchCase")); + ckMatchCase->setObjectName(QStringLiteral("ckMatchCase")); vboxLayout1->addWidget(ckMatchCase); ckMarkFinished = new QCheckBox(groupBox); - ckMarkFinished->setObjectName(QString::fromUtf8("ckMarkFinished")); + ckMarkFinished->setObjectName(QStringLiteral("ckMarkFinished")); vboxLayout1->addWidget(ckMarkFinished); @@ -169,27 +169,27 @@ public: vboxLayout2 = new QVBoxLayout(); vboxLayout2->setSpacing(6); - vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2")); + vboxLayout2->setObjectName(QStringLiteral("vboxLayout2")); vboxLayout2->setContentsMargins(0, 0, 0, 0); findNxt = new QPushButton(TranslateDialog); - findNxt->setObjectName(QString::fromUtf8("findNxt")); + findNxt->setObjectName(QStringLiteral("findNxt")); findNxt->setDefault(true); findNxt->setFlat(false); vboxLayout2->addWidget(findNxt); translate = new QPushButton(TranslateDialog); - translate->setObjectName(QString::fromUtf8("translate")); + translate->setObjectName(QStringLiteral("translate")); vboxLayout2->addWidget(translate); translateAll = new QPushButton(TranslateDialog); - translateAll->setObjectName(QString::fromUtf8("translateAll")); + translateAll->setObjectName(QStringLiteral("translateAll")); vboxLayout2->addWidget(translateAll); cancel = new QPushButton(TranslateDialog); - cancel->setObjectName(QString::fromUtf8("cancel")); + cancel->setObjectName(QStringLiteral("cancel")); vboxLayout2->addWidget(cancel); diff --git a/tests/auto/tools/uic/baseline/translationsettings.ui.h b/tests/auto/tools/uic/baseline/translationsettings.ui.h index 770d43216be..22d764a67a9 100644 --- a/tests/auto/tools/uic/baseline/translationsettings.ui.h +++ b/tests/auto/tools/uic/baseline/translationsettings.ui.h @@ -40,7 +40,7 @@ public: void setupUi(QDialog *TranslationSettings) { if (TranslationSettings->objectName().isEmpty()) - TranslationSettings->setObjectName(QString::fromUtf8("TranslationSettings")); + TranslationSettings->setObjectName(QStringLiteral("TranslationSettings")); TranslationSettings->resize(346, 125); vboxLayout = new QVBoxLayout(TranslationSettings); #ifndef Q_OS_MAC @@ -49,9 +49,9 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); groupBox = new QGroupBox(TranslationSettings); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); gridLayout = new QGridLayout(groupBox); #ifndef Q_OS_MAC gridLayout->setSpacing(6); @@ -59,24 +59,24 @@ public: #ifndef Q_OS_MAC gridLayout->setContentsMargins(9, 9, 9, 9); #endif - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); cbLanguageList = new QComboBox(groupBox); - cbLanguageList->setObjectName(QString::fromUtf8("cbLanguageList")); + cbLanguageList->setObjectName(QStringLiteral("cbLanguageList")); gridLayout->addWidget(cbLanguageList, 0, 1, 1, 1); label = new QLabel(groupBox); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 0, 0, 1, 1); cbCountryList = new QComboBox(groupBox); - cbCountryList->setObjectName(QString::fromUtf8("cbCountryList")); + cbCountryList->setObjectName(QStringLiteral("cbCountryList")); gridLayout->addWidget(cbCountryList, 1, 1, 1, 1); lblCountry = new QLabel(groupBox); - lblCountry->setObjectName(QString::fromUtf8("lblCountry")); + lblCountry->setObjectName(QStringLiteral("lblCountry")); gridLayout->addWidget(lblCountry, 1, 0, 1, 1); @@ -84,7 +84,7 @@ public: vboxLayout->addWidget(groupBox); buttonBox = new QDialogButtonBox(TranslationSettings); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h b/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h index 843737fe597..3f94c2117e0 100644 --- a/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h +++ b/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h @@ -112,34 +112,34 @@ public: void setupUi(QDialog *qdesigner_internal__TreeWidgetEditor) { if (qdesigner_internal__TreeWidgetEditor->objectName().isEmpty()) - qdesigner_internal__TreeWidgetEditor->setObjectName(QString::fromUtf8("qdesigner_internal__TreeWidgetEditor")); + qdesigner_internal__TreeWidgetEditor->setObjectName(QStringLiteral("qdesigner_internal__TreeWidgetEditor")); qdesigner_internal__TreeWidgetEditor->resize(619, 321); gridLayout_3 = new QGridLayout(qdesigner_internal__TreeWidgetEditor); - gridLayout_3->setObjectName(QString::fromUtf8("gridLayout_3")); + gridLayout_3->setObjectName(QStringLiteral("gridLayout_3")); itemsBox = new QGroupBox(qdesigner_internal__TreeWidgetEditor); - itemsBox->setObjectName(QString::fromUtf8("itemsBox")); + itemsBox->setObjectName(QStringLiteral("itemsBox")); gridLayout = new QGridLayout(itemsBox); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); treeWidget = new QTreeWidget(itemsBox); - treeWidget->setObjectName(QString::fromUtf8("treeWidget")); + treeWidget->setObjectName(QStringLiteral("treeWidget")); treeWidget->setFocusPolicy(Qt::TabFocus); gridLayout->addWidget(treeWidget, 0, 0, 1, 1); horizontalLayout_4 = new QHBoxLayout(); - horizontalLayout_4->setObjectName(QString::fromUtf8("horizontalLayout_4")); + horizontalLayout_4->setObjectName(QStringLiteral("horizontalLayout_4")); newItemButton = new QToolButton(itemsBox); - newItemButton->setObjectName(QString::fromUtf8("newItemButton")); + newItemButton->setObjectName(QStringLiteral("newItemButton")); horizontalLayout_4->addWidget(newItemButton); newSubItemButton = new QToolButton(itemsBox); - newSubItemButton->setObjectName(QString::fromUtf8("newSubItemButton")); + newSubItemButton->setObjectName(QStringLiteral("newSubItemButton")); horizontalLayout_4->addWidget(newSubItemButton); deleteItemButton = new QToolButton(itemsBox); - deleteItemButton->setObjectName(QString::fromUtf8("deleteItemButton")); + deleteItemButton->setObjectName(QStringLiteral("deleteItemButton")); horizontalLayout_4->addWidget(deleteItemButton); @@ -148,22 +148,22 @@ public: horizontalLayout_4->addItem(spacerItem); moveItemLeftButton = new QToolButton(itemsBox); - moveItemLeftButton->setObjectName(QString::fromUtf8("moveItemLeftButton")); + moveItemLeftButton->setObjectName(QStringLiteral("moveItemLeftButton")); horizontalLayout_4->addWidget(moveItemLeftButton); moveItemRightButton = new QToolButton(itemsBox); - moveItemRightButton->setObjectName(QString::fromUtf8("moveItemRightButton")); + moveItemRightButton->setObjectName(QStringLiteral("moveItemRightButton")); horizontalLayout_4->addWidget(moveItemRightButton); moveItemUpButton = new QToolButton(itemsBox); - moveItemUpButton->setObjectName(QString::fromUtf8("moveItemUpButton")); + moveItemUpButton->setObjectName(QStringLiteral("moveItemUpButton")); horizontalLayout_4->addWidget(moveItemUpButton); moveItemDownButton = new QToolButton(itemsBox); - moveItemDownButton->setObjectName(QString::fromUtf8("moveItemDownButton")); + moveItemDownButton->setObjectName(QStringLiteral("moveItemDownButton")); horizontalLayout_4->addWidget(moveItemDownButton); @@ -171,14 +171,14 @@ public: gridLayout->addLayout(horizontalLayout_4, 1, 0, 1, 1); horizontalLayout_2 = new QHBoxLayout(); - horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2")); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); label_2 = new QLabel(itemsBox); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); horizontalLayout_2->addWidget(label_2); itemIconSelector = new qdesigner_internal::IconSelector(itemsBox); - itemIconSelector->setObjectName(QString::fromUtf8("itemIconSelector")); + itemIconSelector->setObjectName(QStringLiteral("itemIconSelector")); horizontalLayout_2->addWidget(itemIconSelector); @@ -193,16 +193,16 @@ public: gridLayout_3->addWidget(itemsBox, 0, 0, 1, 1); columnsBox = new QGroupBox(qdesigner_internal__TreeWidgetEditor); - columnsBox->setObjectName(QString::fromUtf8("columnsBox")); + columnsBox->setObjectName(QStringLiteral("columnsBox")); QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(columnsBox->sizePolicy().hasHeightForWidth()); columnsBox->setSizePolicy(sizePolicy); gridLayout_2 = new QGridLayout(columnsBox); - gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2")); + gridLayout_2->setObjectName(QStringLiteral("gridLayout_2")); listWidget = new QListWidget(columnsBox); - listWidget->setObjectName(QString::fromUtf8("listWidget")); + listWidget->setObjectName(QStringLiteral("listWidget")); QSizePolicy sizePolicy1(QSizePolicy::Ignored, QSizePolicy::Expanding); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); @@ -213,14 +213,14 @@ public: gridLayout_2->addWidget(listWidget, 0, 0, 1, 1); horizontalLayout_3 = new QHBoxLayout(); - horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3")); + horizontalLayout_3->setObjectName(QStringLiteral("horizontalLayout_3")); newColumnButton = new QToolButton(columnsBox); - newColumnButton->setObjectName(QString::fromUtf8("newColumnButton")); + newColumnButton->setObjectName(QStringLiteral("newColumnButton")); horizontalLayout_3->addWidget(newColumnButton); deleteColumnButton = new QToolButton(columnsBox); - deleteColumnButton->setObjectName(QString::fromUtf8("deleteColumnButton")); + deleteColumnButton->setObjectName(QStringLiteral("deleteColumnButton")); horizontalLayout_3->addWidget(deleteColumnButton); @@ -229,12 +229,12 @@ public: horizontalLayout_3->addItem(spacerItem1); moveColumnUpButton = new QToolButton(columnsBox); - moveColumnUpButton->setObjectName(QString::fromUtf8("moveColumnUpButton")); + moveColumnUpButton->setObjectName(QStringLiteral("moveColumnUpButton")); horizontalLayout_3->addWidget(moveColumnUpButton); moveColumnDownButton = new QToolButton(columnsBox); - moveColumnDownButton->setObjectName(QString::fromUtf8("moveColumnDownButton")); + moveColumnDownButton->setObjectName(QStringLiteral("moveColumnDownButton")); horizontalLayout_3->addWidget(moveColumnDownButton); @@ -242,14 +242,14 @@ public: gridLayout_2->addLayout(horizontalLayout_3, 1, 0, 1, 1); horizontalLayout = new QHBoxLayout(); - horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); label = new QLabel(columnsBox); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); horizontalLayout->addWidget(label); columnIconSelector = new qdesigner_internal::IconSelector(columnsBox); - columnIconSelector->setObjectName(QString::fromUtf8("columnIconSelector")); + columnIconSelector->setObjectName(QStringLiteral("columnIconSelector")); horizontalLayout->addWidget(columnIconSelector); @@ -264,7 +264,7 @@ public: gridLayout_3->addWidget(columnsBox, 0, 1, 1, 1); buttonBox = new QDialogButtonBox(qdesigner_internal__TreeWidgetEditor); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); diff --git a/tests/auto/tools/uic/baseline/trpreviewtool.ui.h b/tests/auto/tools/uic/baseline/trpreviewtool.ui.h index a26ff1c8287..6a705ad455c 100644 --- a/tests/auto/tools/uic/baseline/trpreviewtool.ui.h +++ b/tests/auto/tools/uic/baseline/trpreviewtool.ui.h @@ -95,58 +95,58 @@ public: void setupUi(QMainWindow *TrPreviewToolClass) { if (TrPreviewToolClass->objectName().isEmpty()) - TrPreviewToolClass->setObjectName(QString::fromUtf8("TrPreviewToolClass")); + TrPreviewToolClass->setObjectName(QStringLiteral("TrPreviewToolClass")); TrPreviewToolClass->resize(593, 466); actionOpenForm = new QAction(TrPreviewToolClass); - actionOpenForm->setObjectName(QString::fromUtf8("actionOpenForm")); + actionOpenForm->setObjectName(QStringLiteral("actionOpenForm")); const QIcon icon = QIcon(QString::fromUtf8(":/images/open_form.png")); actionOpenForm->setIcon(icon); actionLoadTranslation = new QAction(TrPreviewToolClass); - actionLoadTranslation->setObjectName(QString::fromUtf8("actionLoadTranslation")); + actionLoadTranslation->setObjectName(QStringLiteral("actionLoadTranslation")); const QIcon icon1 = QIcon(QString::fromUtf8(":/images/load_translation.png")); actionLoadTranslation->setIcon(icon1); actionReloadTranslations = new QAction(TrPreviewToolClass); - actionReloadTranslations->setObjectName(QString::fromUtf8("actionReloadTranslations")); + actionReloadTranslations->setObjectName(QStringLiteral("actionReloadTranslations")); const QIcon icon2 = QIcon(QString::fromUtf8(":/images/reload_translations.png")); actionReloadTranslations->setIcon(icon2); actionClose = new QAction(TrPreviewToolClass); - actionClose->setObjectName(QString::fromUtf8("actionClose")); + actionClose->setObjectName(QStringLiteral("actionClose")); actionAbout = new QAction(TrPreviewToolClass); - actionAbout->setObjectName(QString::fromUtf8("actionAbout")); + actionAbout->setObjectName(QStringLiteral("actionAbout")); actionAbout_Qt = new QAction(TrPreviewToolClass); - actionAbout_Qt->setObjectName(QString::fromUtf8("actionAbout_Qt")); + actionAbout_Qt->setObjectName(QStringLiteral("actionAbout_Qt")); centralWidget = new QWidget(TrPreviewToolClass); - centralWidget->setObjectName(QString::fromUtf8("centralWidget")); + centralWidget->setObjectName(QStringLiteral("centralWidget")); TrPreviewToolClass->setCentralWidget(centralWidget); menuBar = new QMenuBar(TrPreviewToolClass); - menuBar->setObjectName(QString::fromUtf8("menuBar")); + menuBar->setObjectName(QStringLiteral("menuBar")); menuBar->setGeometry(QRect(0, 0, 593, 21)); menuView = new QMenu(menuBar); - menuView->setObjectName(QString::fromUtf8("menuView")); + menuView->setObjectName(QStringLiteral("menuView")); menuViewViews = new QMenu(menuView); - menuViewViews->setObjectName(QString::fromUtf8("menuViewViews")); + menuViewViews->setObjectName(QStringLiteral("menuViewViews")); menuHelp = new QMenu(menuBar); - menuHelp->setObjectName(QString::fromUtf8("menuHelp")); + menuHelp->setObjectName(QStringLiteral("menuHelp")); menuFile = new QMenu(menuBar); - menuFile->setObjectName(QString::fromUtf8("menuFile")); + menuFile->setObjectName(QStringLiteral("menuFile")); TrPreviewToolClass->setMenuBar(menuBar); mainToolBar = new QToolBar(TrPreviewToolClass); - mainToolBar->setObjectName(QString::fromUtf8("mainToolBar")); + mainToolBar->setObjectName(QStringLiteral("mainToolBar")); mainToolBar->setOrientation(Qt::Horizontal); TrPreviewToolClass->addToolBar(static_cast(4), mainToolBar); statusBar = new QStatusBar(TrPreviewToolClass); - statusBar->setObjectName(QString::fromUtf8("statusBar")); + statusBar->setObjectName(QStringLiteral("statusBar")); TrPreviewToolClass->setStatusBar(statusBar); dwForms = new QDockWidget(TrPreviewToolClass); - dwForms->setObjectName(QString::fromUtf8("dwForms")); + dwForms->setObjectName(QStringLiteral("dwForms")); dockWidgetContents = new QWidget(); - dockWidgetContents->setObjectName(QString::fromUtf8("dockWidgetContents")); + dockWidgetContents->setObjectName(QStringLiteral("dockWidgetContents")); vboxLayout = new QVBoxLayout(dockWidgetContents); vboxLayout->setSpacing(0); vboxLayout->setContentsMargins(0, 0, 0, 0); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); viewForms = new QListView(dockWidgetContents); - viewForms->setObjectName(QString::fromUtf8("viewForms")); + viewForms->setObjectName(QStringLiteral("viewForms")); viewForms->setEditTriggers(QAbstractItemView::NoEditTriggers); viewForms->setAlternatingRowColors(true); viewForms->setUniformItemSizes(true); diff --git a/tests/auto/tools/uic/baseline/validators.ui.h b/tests/auto/tools/uic/baseline/validators.ui.h index 12b8ff09f3d..374f547cc6a 100644 --- a/tests/auto/tools/uic/baseline/validators.ui.h +++ b/tests/auto/tools/uic/baseline/validators.ui.h @@ -80,7 +80,7 @@ public: void setupUi(QWidget *ValidatorsForm) { if (ValidatorsForm->objectName().isEmpty()) - ValidatorsForm->setObjectName(QString::fromUtf8("ValidatorsForm")); + ValidatorsForm->setObjectName(QStringLiteral("ValidatorsForm")); ValidatorsForm->resize(526, 668); vboxLayout = new QVBoxLayout(ValidatorsForm); #ifndef Q_OS_MAC @@ -89,7 +89,7 @@ public: #ifndef Q_OS_MAC vboxLayout->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); hboxLayout = new QHBoxLayout(); #ifndef Q_OS_MAC hboxLayout->setSpacing(6); @@ -97,9 +97,9 @@ public: #ifndef Q_OS_MAC hboxLayout->setContentsMargins(0, 0, 0, 0); #endif - hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); + hboxLayout->setObjectName(QStringLiteral("hboxLayout")); localeSelector = new LocaleSelector(ValidatorsForm); - localeSelector->setObjectName(QString::fromUtf8("localeSelector")); + localeSelector->setObjectName(QStringLiteral("localeSelector")); hboxLayout->addWidget(localeSelector); @@ -111,7 +111,7 @@ public: vboxLayout->addLayout(hboxLayout); groupBox = new QGroupBox(ValidatorsForm); - groupBox->setObjectName(QString::fromUtf8("groupBox")); + groupBox->setObjectName(QStringLiteral("groupBox")); vboxLayout1 = new QVBoxLayout(groupBox); #ifndef Q_OS_MAC vboxLayout1->setSpacing(6); @@ -119,7 +119,7 @@ public: #ifndef Q_OS_MAC vboxLayout1->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); + vboxLayout1->setObjectName(QStringLiteral("vboxLayout1")); hboxLayout1 = new QHBoxLayout(); #ifndef Q_OS_MAC hboxLayout1->setSpacing(6); @@ -127,7 +127,7 @@ public: #ifndef Q_OS_MAC hboxLayout1->setContentsMargins(0, 0, 0, 0); #endif - hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1")); + hboxLayout1->setObjectName(QStringLiteral("hboxLayout1")); gridLayout = new QGridLayout(); #ifndef Q_OS_MAC gridLayout->setSpacing(6); @@ -135,15 +135,15 @@ public: #ifndef Q_OS_MAC gridLayout->setContentsMargins(0, 0, 0, 0); #endif - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); label = new QLabel(groupBox); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); label->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); gridLayout->addWidget(label, 0, 0, 1, 1); minVal = new QSpinBox(groupBox); - minVal->setObjectName(QString::fromUtf8("minVal")); + minVal->setObjectName(QStringLiteral("minVal")); QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); sizePolicy.setHorizontalStretch(1); sizePolicy.setVerticalStretch(0); @@ -155,13 +155,13 @@ public: gridLayout->addWidget(minVal, 0, 1, 1, 1); label_2 = new QLabel(groupBox); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); label_2->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); gridLayout->addWidget(label_2, 1, 0, 1, 1); maxVal = new QSpinBox(groupBox); - maxVal->setObjectName(QString::fromUtf8("maxVal")); + maxVal->setObjectName(QStringLiteral("maxVal")); sizePolicy.setHeightForWidth(maxVal->sizePolicy().hasHeightForWidth()); maxVal->setSizePolicy(sizePolicy); maxVal->setMinimum(-1000000); @@ -174,7 +174,7 @@ public: hboxLayout1->addLayout(gridLayout); frame = new QFrame(groupBox); - frame->setObjectName(QString::fromUtf8("frame")); + frame->setObjectName(QStringLiteral("frame")); frame->setFrameShape(QFrame::StyledPanel); frame->setFrameShadow(QFrame::Sunken); vboxLayout2 = new QVBoxLayout(frame); @@ -184,9 +184,9 @@ public: #ifndef Q_OS_MAC vboxLayout2->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2")); + vboxLayout2->setObjectName(QStringLiteral("vboxLayout2")); ledWidget = new LEDWidget(frame); - ledWidget->setObjectName(QString::fromUtf8("ledWidget")); + ledWidget->setObjectName(QStringLiteral("ledWidget")); QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Fixed); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); @@ -198,7 +198,7 @@ public: vboxLayout2->addWidget(ledWidget); label_7 = new QLabel(frame); - label_7->setObjectName(QString::fromUtf8("label_7")); + label_7->setObjectName(QStringLiteral("label_7")); vboxLayout2->addWidget(label_7); @@ -213,7 +213,7 @@ public: vboxLayout1->addItem(spacerItem1); editor = new QLineEdit(groupBox); - editor->setObjectName(QString::fromUtf8("editor")); + editor->setObjectName(QStringLiteral("editor")); vboxLayout1->addWidget(editor); @@ -221,7 +221,7 @@ public: vboxLayout->addWidget(groupBox); groupBox_2 = new QGroupBox(ValidatorsForm); - groupBox_2->setObjectName(QString::fromUtf8("groupBox_2")); + groupBox_2->setObjectName(QStringLiteral("groupBox_2")); vboxLayout3 = new QVBoxLayout(groupBox_2); #ifndef Q_OS_MAC vboxLayout3->setSpacing(6); @@ -229,7 +229,7 @@ public: #ifndef Q_OS_MAC vboxLayout3->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout3->setObjectName(QString::fromUtf8("vboxLayout3")); + vboxLayout3->setObjectName(QStringLiteral("vboxLayout3")); hboxLayout2 = new QHBoxLayout(); #ifndef Q_OS_MAC hboxLayout2->setSpacing(6); @@ -237,7 +237,7 @@ public: #ifndef Q_OS_MAC hboxLayout2->setContentsMargins(0, 0, 0, 0); #endif - hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2")); + hboxLayout2->setObjectName(QStringLiteral("hboxLayout2")); gridLayout1 = new QGridLayout(); #ifndef Q_OS_MAC gridLayout1->setSpacing(6); @@ -245,15 +245,15 @@ public: #ifndef Q_OS_MAC gridLayout1->setContentsMargins(0, 0, 0, 0); #endif - gridLayout1->setObjectName(QString::fromUtf8("gridLayout1")); + gridLayout1->setObjectName(QStringLiteral("gridLayout1")); label_3 = new QLabel(groupBox_2); - label_3->setObjectName(QString::fromUtf8("label_3")); + label_3->setObjectName(QStringLiteral("label_3")); label_3->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); gridLayout1->addWidget(label_3, 0, 0, 1, 1); doubleMinVal = new QDoubleSpinBox(groupBox_2); - doubleMinVal->setObjectName(QString::fromUtf8("doubleMinVal")); + doubleMinVal->setObjectName(QStringLiteral("doubleMinVal")); sizePolicy.setHeightForWidth(doubleMinVal->sizePolicy().hasHeightForWidth()); doubleMinVal->setSizePolicy(sizePolicy); doubleMinVal->setMinimum(-100000); @@ -263,24 +263,24 @@ public: gridLayout1->addWidget(doubleMinVal, 0, 1, 1, 1); label_5 = new QLabel(groupBox_2); - label_5->setObjectName(QString::fromUtf8("label_5")); + label_5->setObjectName(QStringLiteral("label_5")); label_5->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); gridLayout1->addWidget(label_5, 0, 2, 1, 1); doubleFormat = new QComboBox(groupBox_2); - doubleFormat->setObjectName(QString::fromUtf8("doubleFormat")); + doubleFormat->setObjectName(QStringLiteral("doubleFormat")); gridLayout1->addWidget(doubleFormat, 0, 3, 1, 1); label_4 = new QLabel(groupBox_2); - label_4->setObjectName(QString::fromUtf8("label_4")); + label_4->setObjectName(QStringLiteral("label_4")); label_4->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); gridLayout1->addWidget(label_4, 1, 0, 1, 1); doubleMaxVal = new QDoubleSpinBox(groupBox_2); - doubleMaxVal->setObjectName(QString::fromUtf8("doubleMaxVal")); + doubleMaxVal->setObjectName(QStringLiteral("doubleMaxVal")); sizePolicy.setHeightForWidth(doubleMaxVal->sizePolicy().hasHeightForWidth()); doubleMaxVal->setSizePolicy(sizePolicy); doubleMaxVal->setMinimum(-100000); @@ -290,13 +290,13 @@ public: gridLayout1->addWidget(doubleMaxVal, 1, 1, 1, 1); label_6 = new QLabel(groupBox_2); - label_6->setObjectName(QString::fromUtf8("label_6")); + label_6->setObjectName(QStringLiteral("label_6")); label_6->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); gridLayout1->addWidget(label_6, 1, 2, 1, 1); doubleDecimals = new QSpinBox(groupBox_2); - doubleDecimals->setObjectName(QString::fromUtf8("doubleDecimals")); + doubleDecimals->setObjectName(QStringLiteral("doubleDecimals")); doubleDecimals->setValue(2); gridLayout1->addWidget(doubleDecimals, 1, 3, 1, 1); @@ -305,7 +305,7 @@ public: hboxLayout2->addLayout(gridLayout1); frame_2 = new QFrame(groupBox_2); - frame_2->setObjectName(QString::fromUtf8("frame_2")); + frame_2->setObjectName(QStringLiteral("frame_2")); frame_2->setFrameShape(QFrame::StyledPanel); frame_2->setFrameShadow(QFrame::Sunken); vboxLayout4 = new QVBoxLayout(frame_2); @@ -315,16 +315,16 @@ public: #ifndef Q_OS_MAC vboxLayout4->setContentsMargins(9, 9, 9, 9); #endif - vboxLayout4->setObjectName(QString::fromUtf8("vboxLayout4")); + vboxLayout4->setObjectName(QStringLiteral("vboxLayout4")); doubleLedWidget = new LEDWidget(frame_2); - doubleLedWidget->setObjectName(QString::fromUtf8("doubleLedWidget")); + doubleLedWidget->setObjectName(QStringLiteral("doubleLedWidget")); doubleLedWidget->setPixmap(QPixmap(QString::fromUtf8(":/ledoff.png"))); doubleLedWidget->setAlignment(Qt::AlignCenter); vboxLayout4->addWidget(doubleLedWidget); label_8 = new QLabel(frame_2); - label_8->setObjectName(QString::fromUtf8("label_8")); + label_8->setObjectName(QStringLiteral("label_8")); vboxLayout4->addWidget(label_8); @@ -339,7 +339,7 @@ public: vboxLayout3->addItem(spacerItem2); doubleEditor = new QLineEdit(groupBox_2); - doubleEditor->setObjectName(QString::fromUtf8("doubleEditor")); + doubleEditor->setObjectName(QStringLiteral("doubleEditor")); vboxLayout3->addWidget(doubleEditor); @@ -355,13 +355,13 @@ public: hboxLayout3->setSpacing(6); #endif hboxLayout3->setContentsMargins(0, 0, 0, 0); - hboxLayout3->setObjectName(QString::fromUtf8("hboxLayout3")); + hboxLayout3->setObjectName(QStringLiteral("hboxLayout3")); spacerItem4 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); hboxLayout3->addItem(spacerItem4); pushButton = new QPushButton(ValidatorsForm); - pushButton->setObjectName(QString::fromUtf8("pushButton")); + pushButton->setObjectName(QStringLiteral("pushButton")); hboxLayout3->addWidget(pushButton); diff --git a/tests/auto/tools/uic/baseline/wateringconfigdialog.ui.h b/tests/auto/tools/uic/baseline/wateringconfigdialog.ui.h index 1a17d16efe8..f03ac32151f 100644 --- a/tests/auto/tools/uic/baseline/wateringconfigdialog.ui.h +++ b/tests/auto/tools/uic/baseline/wateringconfigdialog.ui.h @@ -68,19 +68,19 @@ public: void setupUi(QDialog *WateringConfigDialog) { if (WateringConfigDialog->objectName().isEmpty()) - WateringConfigDialog->setObjectName(QString::fromUtf8("WateringConfigDialog")); + WateringConfigDialog->setObjectName(QStringLiteral("WateringConfigDialog")); WateringConfigDialog->resize(334, 550); vboxLayout = new QVBoxLayout(WateringConfigDialog); - vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); + vboxLayout->setObjectName(QStringLiteral("vboxLayout")); gridLayout = new QGridLayout(); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + gridLayout->setObjectName(QStringLiteral("gridLayout")); label_3 = new QLabel(WateringConfigDialog); - label_3->setObjectName(QString::fromUtf8("label_3")); + label_3->setObjectName(QStringLiteral("label_3")); gridLayout->addWidget(label_3, 0, 0, 1, 1); plantComboBox = new QComboBox(WateringConfigDialog); - plantComboBox->setObjectName(QString::fromUtf8("plantComboBox")); + plantComboBox->setObjectName(QStringLiteral("plantComboBox")); QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -94,12 +94,12 @@ public: gridLayout->addItem(spacerItem, 1, 0, 1, 1); label_2 = new QLabel(WateringConfigDialog); - label_2->setObjectName(QString::fromUtf8("label_2")); + label_2->setObjectName(QStringLiteral("label_2")); gridLayout->addWidget(label_2, 2, 0, 1, 1); temperatureCheckBox = new QCheckBox(WateringConfigDialog); - temperatureCheckBox->setObjectName(QString::fromUtf8("temperatureCheckBox")); + temperatureCheckBox->setObjectName(QStringLiteral("temperatureCheckBox")); gridLayout->addWidget(temperatureCheckBox, 3, 1, 1, 3); @@ -108,7 +108,7 @@ public: gridLayout->addItem(spacerItem1, 4, 1, 1, 1); temperatureSpinBox = new QSpinBox(WateringConfigDialog); - temperatureSpinBox->setObjectName(QString::fromUtf8("temperatureSpinBox")); + temperatureSpinBox->setObjectName(QStringLiteral("temperatureSpinBox")); temperatureSpinBox->setEnabled(false); temperatureSpinBox->setMinimum(10); temperatureSpinBox->setMaximum(60); @@ -121,7 +121,7 @@ public: gridLayout->addItem(spacerItem2, 4, 3, 1, 1); rainCheckBox = new QCheckBox(WateringConfigDialog); - rainCheckBox->setObjectName(QString::fromUtf8("rainCheckBox")); + rainCheckBox->setObjectName(QStringLiteral("rainCheckBox")); gridLayout->addWidget(rainCheckBox, 5, 1, 1, 3); @@ -130,7 +130,7 @@ public: gridLayout->addItem(spacerItem3, 6, 1, 1, 1); rainSpinBox = new QSpinBox(WateringConfigDialog); - rainSpinBox->setObjectName(QString::fromUtf8("rainSpinBox")); + rainSpinBox->setObjectName(QStringLiteral("rainSpinBox")); rainSpinBox->setEnabled(false); rainSpinBox->setMinimum(1); @@ -145,22 +145,22 @@ public: gridLayout->addItem(spacerItem5, 7, 2, 1, 1); label = new QLabel(WateringConfigDialog); - label->setObjectName(QString::fromUtf8("label")); + label->setObjectName(QStringLiteral("label")); gridLayout->addWidget(label, 8, 0, 1, 1); startTimeEdit = new QTimeEdit(WateringConfigDialog); - startTimeEdit->setObjectName(QString::fromUtf8("startTimeEdit")); + startTimeEdit->setObjectName(QStringLiteral("startTimeEdit")); gridLayout->addWidget(startTimeEdit, 8, 1, 1, 3); label_4 = new QLabel(WateringConfigDialog); - label_4->setObjectName(QString::fromUtf8("label_4")); + label_4->setObjectName(QStringLiteral("label_4")); gridLayout->addWidget(label_4, 9, 0, 1, 1); amountSpinBox = new QSpinBox(WateringConfigDialog); - amountSpinBox->setObjectName(QString::fromUtf8("amountSpinBox")); + amountSpinBox->setObjectName(QStringLiteral("amountSpinBox")); amountSpinBox->setMinimum(100); amountSpinBox->setMaximum(10000); amountSpinBox->setSingleStep(100); @@ -169,22 +169,22 @@ public: gridLayout->addWidget(amountSpinBox, 9, 1, 1, 3); label_5 = new QLabel(WateringConfigDialog); - label_5->setObjectName(QString::fromUtf8("label_5")); + label_5->setObjectName(QStringLiteral("label_5")); gridLayout->addWidget(label_5, 10, 0, 1, 1); sourceComboBox = new QComboBox(WateringConfigDialog); - sourceComboBox->setObjectName(QString::fromUtf8("sourceComboBox")); + sourceComboBox->setObjectName(QStringLiteral("sourceComboBox")); gridLayout->addWidget(sourceComboBox, 10, 1, 1, 3); label_6 = new QLabel(WateringConfigDialog); - label_6->setObjectName(QString::fromUtf8("label_6")); + label_6->setObjectName(QStringLiteral("label_6")); gridLayout->addWidget(label_6, 11, 0, 1, 1); filterCheckBox = new QCheckBox(WateringConfigDialog); - filterCheckBox->setObjectName(QString::fromUtf8("filterCheckBox")); + filterCheckBox->setObjectName(QStringLiteral("filterCheckBox")); gridLayout->addWidget(filterCheckBox, 11, 1, 1, 2); @@ -200,18 +200,18 @@ public: vboxLayout->addLayout(gridLayout); gridLayout1 = new QGridLayout(); - gridLayout1->setObjectName(QString::fromUtf8("gridLayout1")); + gridLayout1->setObjectName(QStringLiteral("gridLayout1")); spacerItem8 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); gridLayout1->addItem(spacerItem8, 0, 1, 1, 1); helpBrowser = new HelpBrowser(WateringConfigDialog); - helpBrowser->setObjectName(QString::fromUtf8("helpBrowser")); + helpBrowser->setObjectName(QStringLiteral("helpBrowser")); gridLayout1->addWidget(helpBrowser, 1, 0, 1, 2); helpLabel = new QLabel(WateringConfigDialog); - helpLabel->setObjectName(QString::fromUtf8("helpLabel")); + helpLabel->setObjectName(QStringLiteral("helpLabel")); gridLayout1->addWidget(helpLabel, 0, 0, 1, 1); @@ -219,14 +219,14 @@ public: vboxLayout->addLayout(gridLayout1); line = new QFrame(WateringConfigDialog); - line->setObjectName(QString::fromUtf8("line")); + line->setObjectName(QStringLiteral("line")); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); vboxLayout->addWidget(line); buttonBox = new QDialogButtonBox(WateringConfigDialog); - buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok); From b0a803213ebd1f7bdf9c40070e14a209d96b7e2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 17 Feb 2012 16:58:09 +0100 Subject: [PATCH 379/406] Added note in QPlatformWindow::setGeometry() docs about position policy. Change-Id: I0ac76b7aac1aa717592c34f414b1dd8fbee92be2 Reviewed-by: Friedemann Kleint --- src/gui/kernel/qplatformwindow_qpa.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp index f3f0a558620..e12228d7bd5 100644 --- a/src/gui/kernel/qplatformwindow_qpa.cpp +++ b/src/gui/kernel/qplatformwindow_qpa.cpp @@ -114,6 +114,10 @@ QSurfaceFormat QPlatformWindow::format() const can happen programatically(from ie. user application) or by the window manager. This means that there is no need to call this function specifically from the window manager callback, instead call QWindowSystemInterface::handleGeometryChange(QWindow *w, const QRect &newRect); + + The position(x, y) part of the rect might be inclusive or exclusive of the window frame + as returned by frameMargins(). You can detect this in the plugin by checking + qt_window_private(window())->positionPolicy. */ void QPlatformWindow::setGeometry(const QRect &rect) { From 3c21a62cbe7944e6e65681c50664ca0aacda6e16 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Sat, 4 Feb 2012 14:32:16 +0100 Subject: [PATCH 380/406] Move QTypeInfo out of qglobal.h and into a separate header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qtypeinfo.h is still included from qglobal.h, and defines QTypeInfo as well as all the specializations for built-in and default Qt types. Change-Id: I24116174de288a730cbb7aa2f80d346d2b2f9408 Reviewed-by: Thiago Macieira Reviewed-by: João Abecasis --- src/corelib/global/global.pri | 3 +- src/corelib/global/qglobal.h | 166 +------------------------ src/corelib/global/qtypeinfo.h | 216 +++++++++++++++++++++++++++++++++ 3 files changed, 220 insertions(+), 165 deletions(-) create mode 100644 src/corelib/global/qtypeinfo.h diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index 726a566796b..ddba51950a8 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -9,7 +9,8 @@ HEADERS += \ global/qendian.h \ global/qnumeric_p.h \ global/qnumeric.h \ - global/qlogging.h + global/qlogging.h \ + global/qtypeinfo.h SOURCES += \ global/qglobal.cpp \ diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 7330a49939a..d4d2ffdabb1 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1266,122 +1266,6 @@ static inline bool qIsNull(float f) # define Q_DUMMY_COMPARISON_OPERATOR(C) #endif - -/* - QTypeInfo - type trait functionality - qIsDetached - data sharing functionality -*/ - -/* - The catch-all template. -*/ - -template inline bool qIsDetached(T &) { return true; } - -template -class QTypeInfo -{ -public: - enum { - isPointer = false, - isComplex = true, - isStatic = true, - isLarge = (sizeof(T)>sizeof(void*)), - isDummy = false, - sizeOf = sizeof(T) - }; -}; - -template<> -class QTypeInfo -{ -public: - enum { - isPointer = false, - isComplex = false, - isStatic = false, - isLarge = false, - isDummy = false, - sizeOf = 0 - }; -}; - -template -class QTypeInfo -{ -public: - enum { - isPointer = true, - isComplex = false, - isStatic = false, - isLarge = false, - isDummy = false, - sizeOf = sizeof(T*) - }; -}; - - -#define Q_DECLARE_MOVABLE_CONTAINER(CONTAINER) \ -template class CONTAINER; \ -template \ -class QTypeInfo< CONTAINER > \ -{ \ -public: \ - enum { \ - isPointer = false, \ - isComplex = true, \ - isStatic = false, \ - isLarge = (sizeof(CONTAINER) > sizeof(void*)), \ - isDummy = false, \ - sizeOf = sizeof(CONTAINER) \ - }; \ -}; - -Q_DECLARE_MOVABLE_CONTAINER(QList) -Q_DECLARE_MOVABLE_CONTAINER(QVector) -Q_DECLARE_MOVABLE_CONTAINER(QQueue) -Q_DECLARE_MOVABLE_CONTAINER(QStack) -Q_DECLARE_MOVABLE_CONTAINER(QLinkedList) -Q_DECLARE_MOVABLE_CONTAINER(QSet) - -#undef Q_DECLARE_MOVABLE_CONTAINER - -/* - Specialize a specific type with: - - Q_DECLARE_TYPEINFO(type, flags); - - where 'type' is the name of the type to specialize and 'flags' is - logically-OR'ed combination of the flags below. -*/ -enum { /* TYPEINFO flags */ - Q_COMPLEX_TYPE = 0, - Q_PRIMITIVE_TYPE = 0x1, - Q_STATIC_TYPE = 0, - Q_MOVABLE_TYPE = 0x2, - Q_DUMMY_TYPE = 0x4 -}; - -#define Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS) \ -class QTypeInfo \ -{ \ -public: \ - enum { \ - isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0), \ - isStatic = (((FLAGS) & (Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE)) == 0), \ - isLarge = (sizeof(TYPE)>sizeof(void*)), \ - isPointer = false, \ - isDummy = (((FLAGS) & Q_DUMMY_TYPE) != 0), \ - sizeOf = sizeof(TYPE) \ - }; \ - static inline const char *name() { return #TYPE; } \ -} - -#define Q_DECLARE_TYPEINFO(TYPE, FLAGS) \ -template<> \ -Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS) - - template inline void qSwap(T &value1, T &value2) { @@ -1395,54 +1279,6 @@ inline void qSwap(T &value1, T &value2) #endif } -/* - Specialize a shared type with: - - Q_DECLARE_SHARED(type); - - where 'type' is the name of the type to specialize. NOTE: shared - types must declare a 'bool isDetached(void) const;' member for this - to work. -*/ -#ifdef QT_NO_STL -#define Q_DECLARE_SHARED_STL(TYPE) -#else -#define Q_DECLARE_SHARED_STL(TYPE) \ -QT_END_NAMESPACE \ -namespace std { \ - template<> inline void swap(QT_PREPEND_NAMESPACE(TYPE) &value1, QT_PREPEND_NAMESPACE(TYPE) &value2) \ - { swap(value1.data_ptr(), value2.data_ptr()); } \ -} \ -QT_BEGIN_NAMESPACE -#endif - -#define Q_DECLARE_SHARED(TYPE) \ -template <> inline bool qIsDetached(TYPE &t) { return t.isDetached(); } \ -template <> inline void qSwap(TYPE &value1, TYPE &value2) \ -{ qSwap(value1.data_ptr(), value2.data_ptr()); } \ -Q_DECLARE_SHARED_STL(TYPE) - -/* - QTypeInfo primitive specializations -*/ -Q_DECLARE_TYPEINFO(bool, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(char, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(signed char, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(uchar, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(short, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(ushort, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(int, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(uint, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(long, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(ulong, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(qint64, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(quint64, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(float, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(double, Q_PRIMITIVE_TYPE); -#ifndef Q_OS_DARWIN -Q_DECLARE_TYPEINFO(long double, Q_PRIMITIVE_TYPE); -#endif - /* These functions make it possible to use standard C++ functions with a similar name from Qt header files (especially template classes). @@ -1776,6 +1612,8 @@ QT_END_HEADER // qDebug and friends #include +#include + #endif /* __cplusplus */ #endif /* QGLOBAL_H */ diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h new file mode 100644 index 00000000000..6297b35b9ce --- /dev/null +++ b/src/corelib/global/qtypeinfo.h @@ -0,0 +1,216 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore 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 QTYPEINFO_H +#define QTYPEINFO_H + +#include + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +/* + QTypeInfo - type trait functionality + qIsDetached - data sharing functionality +*/ + +/* + The catch-all template. +*/ + +template inline bool qIsDetached(T &) { return true; } + +template +class QTypeInfo +{ +public: + enum { + isPointer = false, + isComplex = true, + isStatic = true, + isLarge = (sizeof(T)>sizeof(void*)), + isDummy = false, + sizeOf = sizeof(T) + }; +}; + +template<> +class QTypeInfo +{ +public: + enum { + isPointer = false, + isComplex = false, + isStatic = false, + isLarge = false, + isDummy = false, + sizeOf = 0 + }; +}; + +template +class QTypeInfo +{ +public: + enum { + isPointer = true, + isComplex = false, + isStatic = false, + isLarge = false, + isDummy = false, + sizeOf = sizeof(T*) + }; +}; + + +#define Q_DECLARE_MOVABLE_CONTAINER(CONTAINER) \ +template class CONTAINER; \ +template \ +class QTypeInfo< CONTAINER > \ +{ \ +public: \ + enum { \ + isPointer = false, \ + isComplex = true, \ + isStatic = false, \ + isLarge = (sizeof(CONTAINER) > sizeof(void*)), \ + isDummy = false, \ + sizeOf = sizeof(CONTAINER) \ + }; \ +}; + +Q_DECLARE_MOVABLE_CONTAINER(QList) +Q_DECLARE_MOVABLE_CONTAINER(QVector) +Q_DECLARE_MOVABLE_CONTAINER(QQueue) +Q_DECLARE_MOVABLE_CONTAINER(QStack) +Q_DECLARE_MOVABLE_CONTAINER(QLinkedList) +Q_DECLARE_MOVABLE_CONTAINER(QSet) + +#undef Q_DECLARE_MOVABLE_CONTAINER + +/* + Specialize a specific type with: + + Q_DECLARE_TYPEINFO(type, flags); + + where 'type' is the name of the type to specialize and 'flags' is + logically-OR'ed combination of the flags below. +*/ +enum { /* TYPEINFO flags */ + Q_COMPLEX_TYPE = 0, + Q_PRIMITIVE_TYPE = 0x1, + Q_STATIC_TYPE = 0, + Q_MOVABLE_TYPE = 0x2, + Q_DUMMY_TYPE = 0x4 +}; + +#define Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS) \ +class QTypeInfo \ +{ \ +public: \ + enum { \ + isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0), \ + isStatic = (((FLAGS) & (Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE)) == 0), \ + isLarge = (sizeof(TYPE)>sizeof(void*)), \ + isPointer = false, \ + isDummy = (((FLAGS) & Q_DUMMY_TYPE) != 0), \ + sizeOf = sizeof(TYPE) \ + }; \ + static inline const char *name() { return #TYPE; } \ +} + +#define Q_DECLARE_TYPEINFO(TYPE, FLAGS) \ +template<> \ +Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS) + + +/* + Specialize a shared type with: + + Q_DECLARE_SHARED(type); + + where 'type' is the name of the type to specialize. NOTE: shared + types must declare a 'bool isDetached(void) const;' member for this + to work. +*/ +#ifdef QT_NO_STL +#define Q_DECLARE_SHARED_STL(TYPE) +#else +#define Q_DECLARE_SHARED_STL(TYPE) \ +QT_END_NAMESPACE \ +namespace std { \ + template<> inline void swap(QT_PREPEND_NAMESPACE(TYPE) &value1, QT_PREPEND_NAMESPACE(TYPE) &value2) \ + { swap(value1.data_ptr(), value2.data_ptr()); } \ +} \ +QT_BEGIN_NAMESPACE +#endif + +#define Q_DECLARE_SHARED(TYPE) \ +template <> inline bool qIsDetached(TYPE &t) { return t.isDetached(); } \ +template <> inline void qSwap(TYPE &value1, TYPE &value2) \ +{ qSwap(value1.data_ptr(), value2.data_ptr()); } \ +Q_DECLARE_SHARED_STL(TYPE) + +/* + QTypeInfo primitive specializations +*/ +Q_DECLARE_TYPEINFO(bool, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(char, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(signed char, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(uchar, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(short, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(ushort, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(int, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(uint, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(long, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(ulong, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(qint64, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(quint64, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(float, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(double, Q_PRIMITIVE_TYPE); +#ifndef Q_OS_DARWIN +Q_DECLARE_TYPEINFO(long double, Q_PRIMITIVE_TYPE); +#endif + +QT_END_NAMESPACE +QT_END_HEADER + +#endif // QTYPEINFO_H From f9327fecc1dca707a10b52ffe13b0240320b85fe Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 16 Feb 2012 07:42:11 +0100 Subject: [PATCH 381/406] QPoint/QPointF: inline manhattanLength(); QLineF: inline isNull() There's no reason for them not to be, and it's a prerequisite for making these functions constexpr. Change-Id: I03c9965147b51014c7af60a4c2d7f25a3f6e21a7 Reviewed-by: David Faure Reviewed-by: Gunnar Sletta --- src/corelib/tools/qline.cpp | 8 ++------ src/corelib/tools/qline.h | 5 +++++ src/corelib/tools/qpoint.cpp | 11 +++-------- src/corelib/tools/qpoint.h | 8 ++++++++ 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp index 1ca9a59bde1..78f1c442636 100644 --- a/src/corelib/tools/qline.cpp +++ b/src/corelib/tools/qline.cpp @@ -412,16 +412,12 @@ QDataStream &operator>>(QDataStream &stream, QLine &line) */ /*! + \fn bool QLineF::isNull() const + Returns true if the line is not set up with valid start and end point; otherwise returns false. */ -bool QLineF::isNull() const -{ - return (qFuzzyCompare(pt1.x(), pt2.x()) && qFuzzyCompare(pt1.y(), pt2.y())) ? true : false; -} - - /*! \fn QPointF QLineF::p1() const diff --git a/src/corelib/tools/qline.h b/src/corelib/tools/qline.h index 3c7977a207d..58ef0316ad1 100644 --- a/src/corelib/tools/qline.h +++ b/src/corelib/tools/qline.h @@ -310,6 +310,11 @@ inline qreal QLineF::y2() const return pt2.y(); } +inline bool QLineF::isNull() const +{ + return qFuzzyCompare(pt1.x(), pt2.x()) && qFuzzyCompare(pt1.y(), pt2.y()); +} + inline QPointF QLineF::p1() const { return pt1; diff --git a/src/corelib/tools/qpoint.cpp b/src/corelib/tools/qpoint.cpp index 55a2261cb9d..ecbe9deb9fe 100644 --- a/src/corelib/tools/qpoint.cpp +++ b/src/corelib/tools/qpoint.cpp @@ -402,6 +402,8 @@ QDataStream &operator>>(QDataStream &s, QPoint &p) #endif // QT_NO_DATASTREAM /*! + \fn int QPoint::manhattanLength() const + Returns the sum of the absolute values of x() and y(), traditionally known as the "Manhattan length" of the vector from the origin to the point. For example: @@ -417,10 +419,6 @@ QDataStream &operator>>(QDataStream &s, QPoint &p) apply to travelers who can only travel on a rectangular grid, like the streets of Manhattan. */ -int QPoint::manhattanLength() const -{ - return qAbs(x())+qAbs(y()); -} #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug dbg, const QPoint &p) { @@ -505,6 +503,7 @@ QDebug operator<<(QDebug d, const QPointF &p) /*! + \fn qreal QPointF::manhattanLength() const \since 4.6 Returns the sum of the absolute values of x() and y(), @@ -513,10 +512,6 @@ QDebug operator<<(QDebug d, const QPointF &p) \sa QPoint::manhattanLength() */ -qreal QPointF::manhattanLength() const -{ - return qAbs(x())+qAbs(y()); -} /*! \fn qreal QPointF::x() const diff --git a/src/corelib/tools/qpoint.h b/src/corelib/tools/qpoint.h index 827de3936c2..2e987fcf411 100644 --- a/src/corelib/tools/qpoint.h +++ b/src/corelib/tools/qpoint.h @@ -130,6 +130,9 @@ inline void QPoint::setX(int xpos) inline void QPoint::setY(int ypos) { yp = ypos; } +inline int QPoint::manhattanLength() const +{ return qAbs(x())+qAbs(y()); } + inline int &QPoint::rx() { return xp; } @@ -267,6 +270,11 @@ inline QPointF::QPointF(qreal xpos, qreal ypos) : xp(xpos), yp(ypos) { } inline QPointF::QPointF(const QPoint &p) : xp(p.x()), yp(p.y()) { } +inline qreal QPointF::manhattanLength() const +{ + return qAbs(x())+qAbs(y()); +} + inline bool QPointF::isNull() const { return qIsNull(xp) && qIsNull(yp); From 441f89befac959b01e406d3bfae0d8db133a7cf9 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 17 Feb 2012 23:00:41 +0100 Subject: [PATCH 382/406] Remove unused QtDBus meta-object extensions The inputSignature and outputSignature fields were not being used anymore. All tests still pass. Change-Id: Icbc8fdcd5179a2b1b4843d58b90af925f6bef133 Reviewed-by: Thiago Macieira --- src/dbus/qdbusmetaobject.cpp | 35 ++++------------------------------- src/dbus/qdbusmetaobject_p.h | 2 -- 2 files changed, 4 insertions(+), 33 deletions(-) diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp index 734b21c0fbd..bd7b83bf65b 100644 --- a/src/dbus/qdbusmetaobject.cpp +++ b/src/dbus/qdbusmetaobject.cpp @@ -73,8 +73,6 @@ private: QByteArray typeName; QByteArray tag; QByteArray name; - QByteArray inputSignature; - QByteArray outputSignature; QVarLengthArray inputTypes; QVarLengthArray outputTypes; int flags; @@ -108,7 +106,7 @@ private: }; static const int intsPerProperty = 2; -static const int intsPerMethod = 5; +static const int intsPerMethod = 3; struct QDBusMetaObjectPrivate : public QMetaObjectPrivate { @@ -215,7 +213,6 @@ void QDBusMetaObjectGenerator::parseMethods() break; } - mm.inputSignature += arg.type.toLatin1(); mm.inputTypes.append(type.id); mm.parameters.append(arg.name.toLatin1()); @@ -236,7 +233,6 @@ void QDBusMetaObjectGenerator::parseMethods() break; } - mm.outputSignature += arg.type.toLatin1(); mm.outputTypes.append(type.id); if (i == 0) { @@ -297,7 +293,6 @@ void QDBusMetaObjectGenerator::parseSignals() break; } - mm.inputSignature += arg.type.toLatin1(); mm.inputTypes.append(type.id); mm.parameters.append(arg.name.toLatin1()); @@ -444,7 +439,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj) QMap &map = (x == 0) ? signals_ : methods; for (QMap::ConstIterator it = map.constBegin(); it != map.constEnd(); ++it) { - // form "prototype\0parameters\0typeName\0tag\0methodname\0inputSignature\0outputSignature" + // form "prototype\0parameters\0typeName\0tag\0methodname\0" const Method &mm = it.value(); idata[offset++] = strings.enter(it.key()); // prototype @@ -454,8 +449,6 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj) idata[offset++] = mm.flags; idata[signatureOffset++] = strings.enter(mm.name); - idata[signatureOffset++] = strings.enter(mm.inputSignature); - idata[signatureOffset++] = strings.enter(mm.outputSignature); idata[signatureOffset++] = typeidOffset; idata[typeidOffset++] = mm.inputTypes.count(); @@ -630,32 +623,12 @@ const char *QDBusMetaObject::dbusNameForMethod(int id) const return 0; } -const char *QDBusMetaObject::inputSignatureForMethod(int id) const -{ - //id -= methodOffset(); - if (id >= 0 && id < priv(d.data)->methodCount) { - int handle = priv(d.data)->methodDBusData + id*intsPerMethod; - return d.stringdata + d.data[handle + 1]; - } - return 0; -} - -const char *QDBusMetaObject::outputSignatureForMethod(int id) const -{ - //id -= methodOffset(); - if (id >= 0 && id < priv(d.data)->methodCount) { - int handle = priv(d.data)->methodDBusData + id*intsPerMethod; - return d.stringdata + d.data[handle + 2]; - } - return 0; -} - const int *QDBusMetaObject::inputTypesForMethod(int id) const { //id -= methodOffset(); if (id >= 0 && id < priv(d.data)->methodCount) { int handle = priv(d.data)->methodDBusData + id*intsPerMethod; - return reinterpret_cast(d.data + d.data[handle + 3]); + return reinterpret_cast(d.data + d.data[handle + 1]); } return 0; } @@ -665,7 +638,7 @@ const int *QDBusMetaObject::outputTypesForMethod(int id) const //id -= methodOffset(); if (id >= 0 && id < priv(d.data)->methodCount) { int handle = priv(d.data)->methodDBusData + id*intsPerMethod; - return reinterpret_cast(d.data + d.data[handle + 4]); + return reinterpret_cast(d.data + d.data[handle + 2]); } return 0; } diff --git a/src/dbus/qdbusmetaobject_p.h b/src/dbus/qdbusmetaobject_p.h index d8385fbcc79..7a8de41fa06 100644 --- a/src/dbus/qdbusmetaobject_p.h +++ b/src/dbus/qdbusmetaobject_p.h @@ -77,8 +77,6 @@ struct Q_DBUS_EXPORT QDBusMetaObject: public QMetaObject // methods (slots & signals): const char *dbusNameForMethod(int id) const; - const char *inputSignatureForMethod(int id) const; - const char *outputSignatureForMethod(int id) const; const int *inputTypesForMethod(int id) const; const int *outputTypesForMethod(int id) const; From bdc775661733419aeef17e31c934c40d7f065d4e Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Sat, 18 Feb 2012 21:33:28 +0100 Subject: [PATCH 383/406] Port QDBusAdaptorConnector meta-object to revision 6 We want to drop support for old revisions in Qt 5. This commit brings the QDBusAdaptorConnector meta-object in sync with current moc output. The QtDBus implementation was assuming that the relaySlot() slot would be created at index methodOffset() in the meta-object, but since revision 4 that's no longer the case (signals always come first). Made the code more robust by actually querying the meta-object what the index is. Change-Id: Ie0791680cc2e9e5fb1472c4462c391f92ea22ea6 Reviewed-by: Thiago Macieira --- src/dbus/qdbusabstractadaptor.cpp | 71 ++++++++++++++++++++++--------- src/dbus/qdbusabstractadaptor_p.h | 3 ++ 2 files changed, 53 insertions(+), 21 deletions(-) diff --git a/src/dbus/qdbusabstractadaptor.cpp b/src/dbus/qdbusabstractadaptor.cpp index 9eae45b34b1..7bdd947a37f 100644 --- a/src/dbus/qdbusabstractadaptor.cpp +++ b/src/dbus/qdbusabstractadaptor.cpp @@ -57,6 +57,17 @@ QT_BEGIN_NAMESPACE +static int cachedRelaySlotMethodIndex = -1; + +int QDBusAdaptorConnector::relaySlotMethodIndex() +{ + if (cachedRelaySlotMethodIndex == -1) { + cachedRelaySlotMethodIndex = staticMetaObject.indexOfMethod("relaySlot()"); + Q_ASSERT(cachedRelaySlotMethodIndex != -1); + } + return cachedRelaySlotMethodIndex; +} + QDBusAdaptorConnector *qDBusFindAdaptorConnector(QObject *obj) { if (!obj) @@ -237,12 +248,12 @@ void QDBusAdaptorConnector::addAdaptor(QDBusAbstractAdaptor *adaptor) void QDBusAdaptorConnector::disconnectAllSignals(QObject *obj) { - QMetaObject::disconnect(obj, -1, this, metaObject()->methodOffset()); + QMetaObject::disconnect(obj, -1, this, relaySlotMethodIndex()); } void QDBusAdaptorConnector::connectAllSignals(QObject *obj) { - QMetaObject::connect(obj, -1, this, metaObject()->methodOffset(), Qt::DirectConnection); + QMetaObject::connect(obj, -1, this, relaySlotMethodIndex(), Qt::DirectConnection); } void QDBusAdaptorConnector::polish() @@ -310,37 +321,58 @@ void QDBusAdaptorConnector::relay(QObject *senderObj, int lastSignalIdx, void ** // our Meta Object // modify carefully: this has been hand-edited! -// the relaySlot slot has local ID 0 (we use this when calling QMetaObject::connect) -// it also gets called with the void** array +// the relaySlot slot gets called with the void** array static const uint qt_meta_data_QDBusAdaptorConnector[] = { + // content: - 1, // revision + 6, // revision 0, // classname 0, 0, // classinfo - 3, 10, // methods + 3, 14, // methods 0, 0, // properties 0, 0, // enums/sets - - // slots: signature, parameters, type, tag, flags - 106, 22, 22, 22, 0x0a, - 118, 22, 22, 22, 0x0a, + 0, 0, // constructors + 0, // flags + 1, // signalCount // signals: signature, parameters, type, tag, flags 47, 23, 22, 22, 0x05, + // slots: signature, parameters, type, tag, flags + 105, 22, 22, 22, 0x0a, + 117, 22, 22, 22, 0x0a, + 0 // eod }; static const char qt_meta_stringdata_QDBusAdaptorConnector[] = { - "QDBusAdaptorConnector\0\0obj,metaobject,sid,args\0" - "relaySignal(QObject*,const QMetaObject*,int,QVariantList)\0\0relaySlot()\0" - "polish()\0" + "QDBusAdaptorConnector\0\0obj,metaObject,sid,args\0" + "relaySignal(QObject*,const QMetaObject*,int,QVariantList)\0" + "relaySlot()\0polish()\0" +}; + +void QDBusAdaptorConnector::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QDBusAdaptorConnector *_t = static_cast(_o); + switch (_id) { + case 0: _t->relaySignal((*reinterpret_cast< QObject*(*)>(_a[1])),(*reinterpret_cast< const QMetaObject*(*)>(_a[2])),(*reinterpret_cast< int(*)>(_a[3])),(*reinterpret_cast< const QVariantList(*)>(_a[4]))); break; + case 1: _t->relaySlot(_a); break; // HAND EDIT: add the _a parameter + case 2: _t->polish(); break; + default: ; + } + } +} + +const QMetaObjectExtraData QDBusAdaptorConnector::staticMetaObjectExtraData = { + 0, qt_static_metacall }; const QMetaObject QDBusAdaptorConnector::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_QDBusAdaptorConnector, - qt_meta_data_QDBusAdaptorConnector, 0 } + qt_meta_data_QDBusAdaptorConnector, &staticMetaObjectExtraData } }; const QMetaObject *QDBusAdaptorConnector::metaObject() const @@ -352,7 +384,7 @@ void *QDBusAdaptorConnector::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_QDBusAdaptorConnector)) - return static_cast(const_cast(this)); + return static_cast(const_cast< QDBusAdaptorConnector*>(this)); return QObject::qt_metacast(_clname); } @@ -362,11 +394,8 @@ int QDBusAdaptorConnector::qt_metacall(QMetaObject::Call _c, int _id, void **_a) if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { - switch (_id) { - case 0: relaySlot(_a); break; // HAND EDIT: add the _a parameter - case 1: polish(); break; - case 2: relaySignal((*reinterpret_cast< QObject*(*)>(_a[1])),(*reinterpret_cast< const QMetaObject*(*)>(_a[2])),(*reinterpret_cast< int(*)>(_a[3])),(*reinterpret_cast< const QVariantList(*)>(_a[4]))); break; - } + if (_id < 3) + qt_static_metacall(this, _c, _id, _a); _id -= 3; } return _id; @@ -376,7 +405,7 @@ int QDBusAdaptorConnector::qt_metacall(QMetaObject::Call _c, int _id, void **_a) void QDBusAdaptorConnector::relaySignal(QObject * _t1, const QMetaObject * _t2, int _t3, const QVariantList & _t4) { void *_a[] = { 0, const_cast(reinterpret_cast(&_t1)), const_cast(reinterpret_cast(&_t2)), const_cast(reinterpret_cast(&_t3)), const_cast(reinterpret_cast(&_t4)) }; - QMetaObject::activate(this, &staticMetaObject, 2, _a); + QMetaObject::activate(this, &staticMetaObject, 0, _a); } QT_END_NAMESPACE diff --git a/src/dbus/qdbusabstractadaptor_p.h b/src/dbus/qdbusabstractadaptor_p.h index a0b61e18874..9b10f03eda6 100644 --- a/src/dbus/qdbusabstractadaptor_p.h +++ b/src/dbus/qdbusabstractadaptor_p.h @@ -127,6 +127,9 @@ protected: public: // member variables AdaptorMap adaptors; bool waitingForPolish : 1; + +private: + static int relaySlotMethodIndex(); }; extern QDBusAdaptorConnector *qDBusFindAdaptorConnector(QObject *object); From 06ebe5bc8049282c1e25bb5372e0cdc7e028ae2b Mon Sep 17 00:00:00 2001 From: Jan-Arve Saether Date: Mon, 20 Feb 2012 11:19:10 +0100 Subject: [PATCH 384/406] Updated for accessibility Change-Id: I13b5c2f293e9c1c238c7b7c6aae9d26f5c150f24 Reviewed-by: Frederik Gladhorn --- dist/changes-5.0.0 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index 884c3083fcd..662226d30cd 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -93,8 +93,9 @@ information about a particular change. text(Text t, int child) -> text(Text t), rect(int child) -> rect() setText(Text t, int child, const QString &text) -> setText(Text t, const QString &text) role(int child) -> role(), state(int child) -> state() - relationTo(int child, const QAccessibleInterface *other, int otherChild) -> - relationTo(const QAccessibleInterface *other) + * parent() and child() was added in order to do hierarchical navigation. + * relations() was added as a replacement to relationTo() + * As a consequence of the above two points, navigate() was removed. * Accessible-Action related functions have been removed. QAccessibleInterface subclasses are expected to implement the QAccessibleActionInterface instead. These functions have been removed: From d1dd2b2441f727f28817fcbc773c359c0f4e88b0 Mon Sep 17 00:00:00 2001 From: Jan-Arve Saether Date: Mon, 20 Feb 2012 14:42:41 +0100 Subject: [PATCH 385/406] Remove QAccessibleInterface::relationTo(). QAccessibleInterface::relations() replaces both relatedTo() and some of the RelationFlags that navigate() handled before. Change-Id: I4b9d2c28ba3d753efe7cc9bfa0ad68bed3ee02fd Reviewed-by: Frederik Gladhorn --- src/gui/accessible/qaccessible.cpp | 46 +++--------------------------- src/gui/accessible/qaccessible.h | 1 - 2 files changed, 4 insertions(+), 43 deletions(-) diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 6335a3f2494..363c1934c3e 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -359,26 +359,12 @@ QT_BEGIN_NAMESPACE This enum type defines bit flags that can be combined to indicate the relationship between two accessible objects. - \value Unrelated The objects are unrelated. - \value Self The objects are the same. - - \value Up The first object is above the second object. - \value Down The first object is below the second object. - \value Left The first object is left of the second object. - \value Right The first object is right of the second object. - \value Covers The first object covers the second object. - \value Covered The first object is covered by the second object. - - \value FocusChild The first object is the second object's focus child. \value Label The first object is the label of the second object. \value Labelled The first object is labelled by the second object. \value Controller The first object controls the second object. \value Controlled The first object is controlled by the second object. - \omitvalue GeometryMask - \omitvalue LogicalMask - - Implementations of relationTo() return a combination of these flags. + Implementations of relations() return a combination of these flags. Some values are mutually exclusive. */ @@ -779,8 +765,8 @@ QAccessibleInterface *QAccessibleEvent::accessibleInterface() const top-most child. childAt() is used for hit testing (finding the object under the mouse). - The relationTo() function provides information about how two - different objects relate to each other, and parent() and child() allows + The relations() function provides information about the relations an + object has to other objects, and parent() and child() allows traversing from one object to another object. \section1 Properties @@ -870,37 +856,13 @@ QAccessibleInterface *QAccessibleEvent::accessibleInterface() const \sa childCount() */ -/*! - \fn QAccessible::Relation QAccessibleInterface::relationTo(const QAccessibleInterface *other) const - - Returns the relationship between this object and the \a - other object. - - The returned value indicates the relation of the called object to - the \a other object, e.g. if this object is a label for \a other - the return value will be \c Label. - - Usually parent-child relations are not returned. - - The return value is a combination of the bit flags in the - QAccessible::Relation enumeration. - - All objects provide this information. - - \sa relations(), indexOfChild(), parent(), child() -*/ -QAccessible::Relation QAccessibleInterface::relationTo(const QAccessibleInterface *) const -{ - return QAccessible::Relation(); -} - /*! Returns the meaningful relations to other widgets. Usually this will not return parent/child relations, unless they are handled in a specific way such as in tree views. It will typically return the labelled-by and label relations. It should never return itself. - \sa relationTo(), parent(), child() + \sa parent(), child() */ QVector > QAccessibleInterface::relations(QAccessible::Relation /*match = QAccessible::AllRelations*/) const diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index fdf747cef4c..e57033d9bf0 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -378,7 +378,6 @@ public: virtual QWindow *window() const; // relations - virtual QAccessible::Relation relationTo(const QAccessibleInterface *other) const; virtual QVector > relations(QAccessible::Relation match = QAccessible::AllRelations) const; virtual QAccessibleInterface *focusChild() const; From 1baa8d64728f9b72c1c5bae052939be7edb26224 Mon Sep 17 00:00:00 2001 From: Morten Johan Sorvig Date: Mon, 20 Feb 2012 12:05:17 +0100 Subject: [PATCH 386/406] Remove Native Client special casing from configure. Change-Id: I20f044b267b6c18e5a3050de22710c45e7573cc3 Reviewed-by: Oswald Buddenhagen --- configure | 61 ------------------------------------------------------- 1 file changed, 61 deletions(-) diff --git a/configure b/configure index ce7e2fb48a0..22247b3ea38 100755 --- a/configure +++ b/configure @@ -278,12 +278,6 @@ earlyArgParse() VAL=$1 fi ;; - -nacl) - shift; - VAR=nacl - VAL=$1 - ;; - -h|help|--help|-help) if [ "$VAL" = "yes" ]; then OPT_HELP="$VAL" @@ -334,15 +328,6 @@ earlyArgParse() CFG_EMBEDDED=no fi ;; - nacl) - echo "Using NaCl at $VAL." - PLATFORM_X11=no - PLATFORM_MAC=no - PLATFORM_QWS=no - CFG_NACL_PATH=$VAL - CFG_EMBEDDED=nacl - ;; - developer-build) CFG_DEV="yes" ;; @@ -913,36 +898,6 @@ if [ -d "$relpath/src/plugins/imageformats" ]; then done fi -#------------------------------------------------------------------------------- -# Set Default NaCl options -#------------------------------------------------------------------------------- -if [ "$CFG_EMBEDDED" = "nacl" ]; then - echo "Setting NaCl options:" - echo "-static" - CFG_SHARED=no - echo "-qpa nacl" - PLATFORM_QPA=yes - echo "-fast" - OPT_FAST=yes - echo "-qconfig nacl" - CFG_QCONFIG=nacl - - if [ `uname` = "Linux" ]; then - I_FLAGS="$I_FLAGS -I${CFG_NACL_PATH}/toolchain/linux_x86/sdk/nacl-sdk/include" - L_FLAGS="$L_FLAGS -I${CFG_NACL_PATH}/toolchain/linux_x86/sdk/nacl-sdk/lib" - else - I_FLAGS="$I_FLAGS -I${CFG_NACL_PATH}/toolchain/mac_x86/sdk/nacl-sdk/include" - L_FLAGS="$L_FLAGS -I${CFG_NACL_PATH}/toolchain/mac_x86/sdk/nacl-sdk/lib" - fi - - echo "-no-mediaservices -no-sql-sqlite -nomake tests" - CFG_MEDIASERVICES=no - CFG_SQLITE=no - CFG_SQL_sqlite=no - CFG_NOBUILD_PARTS="$CFG_NOBUILD_PARTS tests" - QT_CONFIG="$QT_CONFIG nacl" -fi - #------------------------------------------------------------------------------- # parse command line arguments #------------------------------------------------------------------------------- @@ -1040,10 +995,6 @@ while [ "$#" -gt 0 ]; do VAL=$1 fi ;; - -nacl) - VAR=nacl - shift; - ;; -opengl) VAR=opengl # this option may or may not be followed by an argument @@ -1270,8 +1221,6 @@ while [ "$#" -gt 0 ]; do PLATFORM_QWS=no PLATFORM_QPA=yes ;; - nacl) - ;; sse) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then CFG_SSE="$VAL" @@ -3065,10 +3014,6 @@ if [ "$XPLATFORM_SYMBIAN_SBSV2" = "no" ]; then fi fi -if [ "$CFG_EMBEDDED" = "nacl" ]; then - TEST_COMPILER="nacl-gcc" -fi - SYSROOT_FLAG= if [ -n "$CFG_SYSROOT" ]; then if compilerSupportsFlag --sysroot="$CFG_SYSROOT"; then @@ -6429,12 +6374,6 @@ if [ "$PLATFORM_QPA" = "yes" ]; then rm -f "src/.moc/$QMAKE_OUTDIR/allmoc.cpp" # needs remaking if config changes fi -if [ "$CFG_EMBEDDED" = "nacl" ]; then - QMAKE_CONFIG="$QMAKE_CONFIG nacl pepper" - QT_CONFIG="$QT_CONFIG nacl pepper" - rm -f "src/.moc/$QMAKE_OUTDIR/allmoc.cpp" # needs remaking if config changes -fi - if [ "$XPLATFORM_MINGW" != "yes" ]; then # Do not set this here for Windows. Let qmake do it so # debug and release precompiled headers are kept separate. From 846f2859b58abaa9c243df0d11a9f3e4b6e13ab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 14 Feb 2012 16:38:32 +0100 Subject: [PATCH 387/406] Make sure that we pick up xcb from pkg-config and run the configure checks with the values Change-Id: Ie8e0072c686c6a7dce1d02e25a9c1abce4679d34 Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- configure | 12 ++++++++---- mkspecs/common/linux.conf | 4 ++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 22247b3ea38..20df77f3955 100755 --- a/configure +++ b/configure @@ -5635,18 +5635,22 @@ if [ "$PLATFORM_QPA" = "yes" ]; then fi if [ "$CFG_XCB" != "no" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/xcb "xcb" $L_FLAGS $I_FLAGS $l_FLAGS; then + if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists xcb 2>/dev/null; then + QMAKE_CFLAGS_XCB="`$PKG_CONFIG --cflags xcb 2>/dev/null`" + QMAKE_LIBS_XCB="`$PKG_CONFIG --libs xcb 2>/dev/null`" + fi + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/xcb "xcb" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_CFLAGS_XCB $QMAKE_LIBS_XCB; then CFG_XCB=yes - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/xcb-render "xcb-render" $L_FLAGS $I_FLAGS $l_FLAGS; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/xcb-render "xcb-render" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_CFLAGS_XCB $QMAKE_LIBS_XCB; then QT_CONFIG="$QT_CONFIG xcb-render" fi - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/xcb-poll-for-queued-event "xcb-poll-for-queued-event" $L_FLAGS $I_FLAGS $l_FLAGS; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/xcb-poll-for-queued-event "xcb-poll-for-queued-event" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_CFLAGS_XCB $QMAKE_LIBS_XCB; then CFG_XCB_LIMITED=no QT_CONFIG="$QT_CONFIG xcb-poll-for-queued-event" fi - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/xcb-xlib "xcb-xlib" $L_FLAGS $I_FLAGS $l_FLAGS; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/xcb-xlib "xcb-xlib" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_CFLAGS_XCB $QMAKE_LIBS_XCB; then QT_CONFIG="$QT_CONFIG xcb-xlib" fi diff --git a/mkspecs/common/linux.conf b/mkspecs/common/linux.conf index 0771bb79ebd..f8f007bada6 100644 --- a/mkspecs/common/linux.conf +++ b/mkspecs/common/linux.conf @@ -42,6 +42,10 @@ QMAKE_LIBDIR_WAYLAND = QMAKE_DEFINES_WAYLAND = QMAKE_WAYLAND_SCANNER = wayland-scanner +QMAKE_CFLAGS_XCB = +QMAKE_LIBS_XCB = +QMAKE_DEFINES_XCB = + QMAKE_MOC = $$[QT_INSTALL_BINS]/moc QMAKE_UIC = $$[QT_INSTALL_BINS]/uic From ed9b6086845542381d624c435c35e27a6c968aed Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 20 Feb 2012 15:44:21 +0100 Subject: [PATCH 388/406] Fix warning about converting false to pointer value. Change-Id: I70c324e6fcfd2bba3ab44837c5ce2c007de8896f Reviewed-by: Bradley T. Hughes Reviewed-by: Stephen Kelly --- tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index 6e4bbc75c21..cba8675bee3 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -2064,7 +2064,7 @@ class NoQuitOnHideWidget : public QWidget { Q_OBJECT public: - NoQuitOnHideWidget(QWidget *parent = 0) + explicit NoQuitOnHideWidget(QWidget *parent = 0) : QWidget(parent) { QTimer::singleShot(0, this, SLOT(hide())); @@ -2081,7 +2081,7 @@ void tst_QApplication::noQuitOnHide() { int argc = 0; QApplication app(argc, 0); - QWidget *window1 = new NoQuitOnHideWidget(false); + QWidget *window1 = new NoQuitOnHideWidget; window1->show(); QCOMPARE(app.exec(), 1); } From 054114a459580b71e170dc6bf356e8943d0ed068 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 20 Feb 2012 15:36:57 +0100 Subject: [PATCH 389/406] Remove QPlatformIntegration/QPlatformTheme from QGuiAppPrivate. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Forward-declare instead. Change-Id: I3851994e8bc05b389e94e948478339ba33d521c1 Reviewed-by: Samuel Rødal --- src/gui/accessible/qaccessible.cpp | 1 + src/gui/image/qbitmap.cpp | 1 + src/gui/image/qnativeimage.cpp | 1 + src/gui/image/qplatformpixmap.cpp | 1 + src/gui/kernel/qclipboard_qpa.cpp | 1 + src/gui/kernel/qdnd.cpp | 1 + src/gui/kernel/qguiapplication.cpp | 1 + src/gui/kernel/qguiapplication.h | 1 + src/gui/kernel/qguiapplication_p.h | 4 ++-- src/gui/kernel/qinputmethod_p.h | 1 + src/gui/kernel/qopenglcontext.cpp | 1 + src/gui/kernel/qwindow.cpp | 1 + src/gui/painting/qbackingstore.cpp | 1 + src/gui/text/qfont_qpa.cpp | 1 + src/gui/text/qfontdatabase.cpp | 1 + src/gui/text/qrawfont_qpa.cpp | 1 + src/gui/util/qdesktopservices.cpp | 1 + src/plugins/platforms/cocoa/qcocoahelpers.mm | 1 + src/plugins/platforms/minimal/qminimalbackingstore.cpp | 1 + src/plugins/platforms/xcb/qxcbkeyboard.cpp | 1 + src/plugins/platforms/xcb/qxcbwindow.cpp | 2 ++ src/widgets/dialogs/qdialog.cpp | 1 + src/widgets/kernel/qwhatsthis.cpp | 1 + src/widgets/widgets/qmenu.cpp | 1 + src/widgets/widgets/qmenubar.cpp | 1 + tests/auto/gui/image/qpixmap/tst_qpixmap.cpp | 1 + 26 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 363c1934c3e..0d00df2a17a 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -49,6 +49,7 @@ #include #include #include "qplatformaccessibility_qpa.h" +#include "qplatformintegration_qpa.h" #include #include diff --git a/src/gui/image/qbitmap.cpp b/src/gui/image/qbitmap.cpp index 81842008138..f3c26dd5b2f 100644 --- a/src/gui/image/qbitmap.cpp +++ b/src/gui/image/qbitmap.cpp @@ -41,6 +41,7 @@ #include "qbitmap.h" #include "qplatformpixmap_qpa.h" +#include "qplatformintegration_qpa.h" #include "qimage.h" #include "qscreen.h" #include "qvariant.h" diff --git a/src/gui/image/qnativeimage.cpp b/src/gui/image/qnativeimage.cpp index 45a8e29100b..96d7a0487bf 100644 --- a/src/gui/image/qnativeimage.cpp +++ b/src/gui/image/qnativeimage.cpp @@ -41,6 +41,7 @@ #include #include "qnativeimage_p.h" +#include "qplatformscreen_qpa.h" #include "private/qguiapplication_p.h" #include "qscreen.h" diff --git a/src/gui/image/qplatformpixmap.cpp b/src/gui/image/qplatformpixmap.cpp index 5162ea80d94..30ac6ce30e4 100644 --- a/src/gui/image/qplatformpixmap.cpp +++ b/src/gui/image/qplatformpixmap.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qplatformpixmap_qpa.h" +#include "qplatformintegration_qpa.h" #include #include #include diff --git a/src/gui/kernel/qclipboard_qpa.cpp b/src/gui/kernel/qclipboard_qpa.cpp index ec940385b85..b33ccd42a23 100644 --- a/src/gui/kernel/qclipboard_qpa.cpp +++ b/src/gui/kernel/qclipboard_qpa.cpp @@ -46,6 +46,7 @@ #include "qmimedata.h" #include "private/qguiapplication_p.h" #include "qplatformclipboard_qpa.h" +#include "qplatformintegration_qpa.h" QT_BEGIN_NAMESPACE diff --git a/src/gui/kernel/qdnd.cpp b/src/gui/kernel/qdnd.cpp index b9f0fe4f5b0..2fb250cf18f 100644 --- a/src/gui/kernel/qdnd.cpp +++ b/src/gui/kernel/qdnd.cpp @@ -59,6 +59,7 @@ #include "qimagewriter.h" #include "qdebug.h" #include +#include #include #include diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 625b466233d..7cb3d4b4886 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -49,6 +49,7 @@ #include "qplatformwindow_qpa.h" #include "qplatformnativeinterface_qpa.h" #include "qplatformtheme_qpa.h" +#include "qplatformintegration_qpa.h" #include #include diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h index d853bc14109..c374a05986d 100644 --- a/src/gui/kernel/qguiapplication.h +++ b/src/gui/kernel/qguiapplication.h @@ -56,6 +56,7 @@ QT_BEGIN_NAMESPACE class QGuiApplicationPrivate; class QPlatformNativeInterface; +class QPlatformIntegration; class QPalette; class QScreen; class QStyleHints; diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index f86d8264fab..7e6e0aa8c78 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -51,14 +51,14 @@ #include #include "private/qwindowsysteminterface_qpa_p.h" -#include -#include #include "private/qshortcutmap_p.h" QT_BEGIN_HEADER QT_BEGIN_NAMESPACE +class QPlatformIntegration; +class QPlatformTheme; class Q_GUI_EXPORT QGuiApplicationPrivate : public QCoreApplicationPrivate { diff --git a/src/gui/kernel/qinputmethod_p.h b/src/gui/kernel/qinputmethod_p.h index 862764d1bc3..8a17c859902 100644 --- a/src/gui/kernel/qinputmethod_p.h +++ b/src/gui/kernel/qinputmethod_p.h @@ -47,6 +47,7 @@ #include #include #include +#include #include QT_BEGIN_HEADER diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index debfbe212ba..ba51653fcfb 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qplatformopenglcontext_qpa.h" +#include "qplatformintegration_qpa.h" #include "qopenglcontext.h" #include "qopenglcontext_p.h" #include "qwindow.h" diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 85f12dd023f..9c6b6c4bf72 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -42,6 +42,7 @@ #include "qwindow.h" #include "qplatformwindow_qpa.h" +#include "qplatformintegration_qpa.h" #include "qsurfaceformat.h" #ifndef QT_NO_OPENGL #include "qplatformopenglcontext_qpa.h" diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 37446f4f801..03c2fc8d6a6 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include diff --git a/src/gui/text/qfont_qpa.cpp b/src/gui/text/qfont_qpa.cpp index 7fcbe98b6f4..29ba7767bc8 100644 --- a/src/gui/text/qfont_qpa.cpp +++ b/src/gui/text/qfont_qpa.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include +#include #include QT_BEGIN_NAMESPACE diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 77262d66f0c..7fa486e1ee2 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -50,6 +50,7 @@ #include "qfileinfo.h" #include "private/qunicodetables_p.h" #include "qfontengine_p.h" +#include "qplatformintegration_qpa.h" #include #include diff --git a/src/gui/text/qrawfont_qpa.cpp b/src/gui/text/qrawfont_qpa.cpp index e9515fdf97b..d037d5902d3 100644 --- a/src/gui/text/qrawfont_qpa.cpp +++ b/src/gui/text/qrawfont_qpa.cpp @@ -44,6 +44,7 @@ #if !defined(QT_NO_RAWFONT) #include "qrawfont_p.h" +#include "qplatformintegration_qpa.h" #include #include diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp index 13e2585b885..25fb08f5321 100644 --- a/src/gui/util/qdesktopservices.cpp +++ b/src/gui/util/qdesktopservices.cpp @@ -53,6 +53,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index f9b62c7a71e..29c505e1aba 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -45,6 +45,7 @@ #include #include +#include #include QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/minimal/qminimalbackingstore.cpp b/src/plugins/platforms/minimal/qminimalbackingstore.cpp index 319b55ee670..5336dbf3bd2 100644 --- a/src/plugins/platforms/minimal/qminimalbackingstore.cpp +++ b/src/plugins/platforms/minimal/qminimalbackingstore.cpp @@ -43,6 +43,7 @@ #include "qminimalbackingstore.h" #include "qscreen.h" #include +#include #include QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 1b874e345cd..b682b87bc33 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -50,6 +50,7 @@ #include #include +#include #ifndef XK_ISO_Left_Tab #define XK_ISO_Left_Tab 0xFE20 diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 4f05c4cf5a7..be3d527cfc5 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -50,6 +50,8 @@ #include "qxcbkeyboard.h" #include "qxcbwmsupport.h" +#include + #ifdef XCB_USE_DRI2 #include "qdri2context.h" #endif diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index 41683a261be..49b4dd3a23f 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -52,6 +52,7 @@ #include "qwhatsthis.h" #include "qmenu.h" #include "qcursor.h" +#include "qplatformtheme_qpa.h" #include "private/qdialog_p.h" #include "private/qguiapplication_p.h" #ifndef QT_NO_ACCESSIBILITY diff --git a/src/widgets/kernel/qwhatsthis.cpp b/src/widgets/kernel/qwhatsthis.cpp index 3d8bb5e4bfd..4a6f3518d02 100644 --- a/src/widgets/kernel/qwhatsthis.cpp +++ b/src/widgets/kernel/qwhatsthis.cpp @@ -54,6 +54,7 @@ #include "qcursor.h" #include "qbitmap.h" #include "qtextdocument.h" +#include "qplatformtheme_qpa.h" #include "private/qtextdocumentlayout_p.h" #include "qtoolbutton.h" #include "qdebug.h" diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index a4f9dc9c963..e8415e3a9cb 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -49,6 +49,7 @@ #include "qtimer.h" #include "qlayout.h" #include "qpainter.h" +#include "qplatformtheme_qpa.h" #include "qapplication.h" #include "qdesktopwidget.h" #ifndef QT_NO_ACCESSIBILITY diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 7a8d39f4623..d797a4e315e 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -55,6 +55,7 @@ #include #include #include +#include #include "private/qguiapplication_p.h" #ifndef QT_NO_MENUBAR diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp index c1643ea3552..563baef486b 100644 --- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp @@ -52,6 +52,7 @@ #include #include +#include #include #include From 4bb020f50b5cc8656a17b217c04e662d88cb795c Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 17 Feb 2012 20:33:57 +0000 Subject: [PATCH 390/406] Windows - fix connecting to a socket using IPv4 mapped IPv6 Connecting to an IPv4 mapped IPv6 address (e.g. ::FFFF:127.0.0.1) requires the IPV6_V6ONLY socket option to be cleared. This was causing tst_qtcpserver::ipv6ServerMapped autotest to fail. The same change is not required on MacOS X - the test passes there. Task-number: QTBUG-24351 Change-Id: I6c08b19f0daa12765da2d44792ffb17299322695 Reviewed-by: Markus Goetz Reviewed-by: Thiago Macieira --- src/network/socket/qnativesocketengine_win.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index e57bfcb52be..d7bbe7eb869 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -615,6 +615,16 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin setPortAndAddress(&sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize); +#if defined (IPV6_V6ONLY) + if (socketProtocol == QAbstractSocket::IPv6Protocol && address.toIPv4Address()) { + //IPV6_V6ONLY option must be cleared to connect to a V4 mapped address + if (QSysInfo::windowsVersion() >= QSysInfo::WV_6_0) { + DWORD ipv6only = 0; + ipv6only = ::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only) ); + } + } +#endif + forever { int connectResult = ::WSAConnect(socketDescriptor, sockAddrPtr, sockAddrSize, 0,0,0,0); if (connectResult == SOCKET_ERROR) { From 2597d61175172b387956205ea6837af07b9e1f08 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 3 Feb 2012 22:15:07 +0100 Subject: [PATCH 391/406] don't attempt to build host tools which are gone from qtbase Change-Id: If9a3fb9792fc5d90496ff834b2c3adc177e1311e Reviewed-by: Bradley T. Hughes Reviewed-by: Marius Storm-Olsen --- tools/configure/configureapp.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 3e291c2cd02..b7eeea6b600 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3196,14 +3196,7 @@ void Configure::buildHostTools() QString pwd = QDir::currentPath(); QStringList hostToolsDirs; hostToolsDirs - << "src/tools" - << "tools/linguist/lrelease"; - - if (dictionary["XQMAKESPEC"].startsWith("wince")) - hostToolsDirs << "tools/checksdk"; - - if (dictionary[ "CETEST" ] == "yes") - hostToolsDirs << "tools/qtestlib/wince/cetest"; + << "src/tools"; for (int i = 0; i < hostToolsDirs.count(); ++i) { cout << "Creating " << hostToolsDirs.at(i) << " ..." << endl; From 2b50e205780f007dd5c2955cd7d492d3f5f909b1 Mon Sep 17 00:00:00 2001 From: Xizhi Zhu Date: Sun, 19 Feb 2012 10:15:18 +0100 Subject: [PATCH 392/406] Merges several overloaded functions in QCoreApplication. The source compatibility is kept. Change-Id: If66053b271d65062b3c0ce6ec66c8394a37b4e3e Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- src/corelib/kernel/qcoreapplication.cpp | 58 ++----------------------- src/corelib/kernel/qcoreapplication.h | 11 ++--- 2 files changed, 6 insertions(+), 63 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 80e42336d65..2d49b271ce3 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1011,35 +1011,6 @@ void QCoreApplication::exit(int returnCode) */ /*! - Adds the event \a event, with the object \a receiver as the - receiver of the event, to an event queue and returns immediately. - - The event must be allocated on the heap since the post event queue - will take ownership of the event and delete it once it has been - posted. It is \e {not safe} to access the event after - it has been posted. - - When control returns to the main event loop, all events that are - stored in the queue will be sent using the notify() function. - - Events are processed in the order posted. For more control over - the processing order, use the postEvent() overload below, which - takes a priority argument. This function posts all event with a - Qt::NormalEventPriority. - - \threadsafe - - \sa sendEvent(), notify(), sendPostedEvents() -*/ - -void QCoreApplication::postEvent(QObject *receiver, QEvent *event) -{ - postEvent(receiver, event, Qt::NormalEventPriority); -} - - -/*! - \overload postEvent() \since 4.3 Adds the event \a event, with the object \a receiver as the @@ -1166,13 +1137,6 @@ bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEven return false; } -/*! - \fn void QCoreApplication::sendPostedEvents() - \overload sendPostedEvents() - - Dispatches all posted events, i.e. empties the event queue. -*/ - /*! Immediately dispatches all events which have been previously queued with QCoreApplication::postEvent() and which are for the object \a receiver @@ -1188,7 +1152,6 @@ bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEven \sa flush(), postEvent() */ - void QCoreApplication::sendPostedEvents(QObject *receiver, int event_type) { QThreadData *data = QThreadData::current(); @@ -1343,23 +1306,6 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type } /*! - Removes all events posted using postEvent() for \a receiver. - - The events are \e not dispatched, instead they are removed from the - queue. You should never need to call this function. If you do call it, - be aware that killing events may cause \a receiver to break one or - more invariants. - - \threadsafe -*/ - -void QCoreApplication::removePostedEvents(QObject *receiver) -{ - removePostedEvents(receiver, 0); -} - -/*! - \overload removePostedEvents() \since 4.3 Removes all events of the given \a eventType that were posted @@ -1372,7 +1318,9 @@ void QCoreApplication::removePostedEvents(QObject *receiver) If \a receiver is null, the events of \a eventType are removed for all objects. If \a eventType is 0, all the events are removed for - \a receiver. + \a receiver. You should never call this function with \a eventType + of 0. If you do call it in this way, be aware that killing events + may cause \a receiver to break one or more invariants. \threadsafe */ diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h index d1fba3b63cf..18266a9a2c8 100644 --- a/src/corelib/kernel/qcoreapplication.h +++ b/src/corelib/kernel/qcoreapplication.h @@ -110,12 +110,9 @@ public: static void exit(int retcode=0); static bool sendEvent(QObject *receiver, QEvent *event); - static void postEvent(QObject *receiver, QEvent *event); - static void postEvent(QObject *receiver, QEvent *event, int priority); - static void sendPostedEvents(QObject *receiver, int event_type); - static void sendPostedEvents(); - static void removePostedEvents(QObject *receiver); - static void removePostedEvents(QObject *receiver, int eventType); + static void postEvent(QObject *receiver, QEvent *event, int priority = Qt::NormalEventPriority); + static void sendPostedEvents(QObject *receiver = 0, int event_type = 0); + static void removePostedEvents(QObject *receiver, int eventType = 0); static bool hasPendingEvents(); static QAbstractEventDispatcher *eventDispatcher(); static void setEventDispatcher(QAbstractEventDispatcher *eventDispatcher); @@ -211,8 +208,6 @@ inline bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event) inline bool QCoreApplication::sendSpontaneousEvent(QObject *receiver, QEvent *event) { if (event) event->spont = true; return self ? self->notifyInternal(receiver, event) : false; } -inline void QCoreApplication::sendPostedEvents() { sendPostedEvents(0, 0); } - #ifdef QT_NO_TRANSLATION // Simple versions inline QString QCoreApplication::translate(const char *, const char *sourceText, From a0587f79e55e6291f302be5f62fc2ce22da08e91 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Mon, 20 Feb 2012 14:26:00 +0100 Subject: [PATCH 393/406] Silence warnings/debug output from qobject tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They create noise in the test results. Change-Id: I40e7239ba7cd41bec577fe8220c86476553a6502 Reviewed-by: Olivier Goffart Reviewed-by: João Abecasis Reviewed-by: Bradley T. Hughes --- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 8f4203a2163..a6ad1d53bca 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -3186,6 +3186,14 @@ void tst_QObject::dumpObjectInfo() QObject a, b; QObject::connect(&a, SIGNAL(destroyed(QObject *)), &b, SLOT(deleteLater())); a.disconnect(&b); +#ifdef QT_DEBUG + QTest::ignoreMessage(QtDebugMsg, "OBJECT QObject::unnamed"); + QTest::ignoreMessage(QtDebugMsg, " SIGNALS OUT"); + QTest::ignoreMessage(QtDebugMsg, " signal: destroyed(QObject*)"); + QTest::ignoreMessage(QtDebugMsg, " "); + QTest::ignoreMessage(QtDebugMsg, " SIGNALS IN"); + QTest::ignoreMessage(QtDebugMsg, " "); +#endif a.dumpObjectInfo(); // should not crash } @@ -3813,12 +3821,18 @@ void tst_QObject::sameName() c2.emitSignal1(); QCOMPARE(c1.s, 2); +#ifndef QT_NO_DEBUG + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::indexOfSignal: signal aPublicSlot() from SenderObject redefined in ConfusingObject"); +#endif QVERIFY(connect(&c2, SIGNAL(aPublicSlot()), &c1, SLOT(signal1()))); c2.aPublicSlot(); QCOMPARE(c2.aPublicSlotCalled, 0); QCOMPARE(c1.aPublicSlotCalled, 0); QCOMPARE(c1.s, 3); +#ifndef QT_NO_DEBUG + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::indexOfSignal: signal aPublicSlot() from SenderObject redefined in ConfusingObject"); +#endif QVERIFY(connect(&c2, SIGNAL(aPublicSlot()), &c1, SLOT(aPublicSlot()))); c2.aPublicSlot(); QCOMPARE(c2.aPublicSlotCalled, 0); From 451bc474075aa435e4d97496e32986b76b0f9baa Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Mon, 20 Feb 2012 18:38:52 +0100 Subject: [PATCH 394/406] Include qt_windows.h for Windows CE. The include is needed for OutputDebugString, as it is defined in winbase.h. To include use the centralized header. Change-Id: I486da20d7b054cee352be085e65a0ede1394653d Reviewed-by: Friedemann Kleint --- src/corelib/global/qlogging.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 77c147bc54b..badccc947da 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -49,6 +49,9 @@ #include "qcoreapplication.h" #include "qthread.h" #endif +#ifdef Q_OS_WINCE +#include +#endif #include From 4c05bc811c06afb718ddbf9db1a3a6cf4086cbc5 Mon Sep 17 00:00:00 2001 From: Richard Moore Date: Sun, 19 Feb 2012 13:41:31 +0000 Subject: [PATCH 395/406] Merge overloads. Fix a ### Qt 5 by merging the overloads. Change-Id: If33e7592191c81b32caa6d68c73dbf2282437886 Reviewed-by: David Faure --- src/xml/dom/qdom.cpp | 27 ++++++++++----------------- src/xml/dom/qdom.h | 3 +-- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index 1eaa74a7300..2188b8d6abf 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -2668,23 +2668,16 @@ QDomNode QDomNode::namedItem(const QString& name) const the stream \a str. This function uses \a indent as the amount of space to indent the node. - If this node is a document node, the encoding of text stream \a str's encoding is - set by treating a processing instruction by name "xml" as an XML declaration, if such a one exists, - and otherwise defaults to UTF-8. XML declarations are not processing instructions, but this - behavior exists for historical reasons. If this node is not a document node, - the text stream's encoding is used. - If the document contains invalid XML characters or characters that cannot be encoded in the given encoding, the result and behavior is undefined. -*/ -void QDomNode::save(QTextStream& str, int indent) const -{ - save(str, indent, QDomNode::EncodingFromDocument); -} - -/*! - If \a encodingPolicy is QDomNode::EncodingFromDocument, this function behaves as save(QTextStream &str, int indent). + If \a encodingPolicy is QDomNode::EncodingFromDocument and this node is a + document node, the encoding of text stream \a str's encoding is set by + treating a processing instruction by name "xml" as an XML declaration, if + one exists, and otherwise defaults to UTF-8. XML declarations are not + processing instructions, but this behavior exists for historical + reasons. If this node is not a document node, the text stream's encoding + is used. If \a encodingPolicy is EncodingFromTextStream and this node is a document node, this function behaves as save(QTextStream &str, int indent) with the exception that the encoding @@ -2695,15 +2688,15 @@ void QDomNode::save(QTextStream& str, int indent) const \since 4.2 */ -void QDomNode::save(QTextStream& str, int indent, EncodingPolicy encodingPolicy) const +void QDomNode::save(QTextStream& stream, int indent, EncodingPolicy encodingPolicy) const { if (!impl) return; if(isDocument()) - static_cast(impl)->saveDocument(str, indent, encodingPolicy); + static_cast(impl)->saveDocument(stream, indent, encodingPolicy); else - IMPL->save(str, 1, indent); + IMPL->save(stream, 1, indent); } /*! diff --git a/src/xml/dom/qdom.h b/src/xml/dom/qdom.h index 8b049b211bf..5dafb9e6a34 100644 --- a/src/xml/dom/qdom.h +++ b/src/xml/dom/qdom.h @@ -227,8 +227,7 @@ public: QDomCharacterData toCharacterData() const; QDomComment toComment() const; - void save(QTextStream&, int) const; - void save(QTextStream&, int, EncodingPolicy) const; // ### Qt 5: Merge overload(if we at all keep this) + void save(QTextStream&, int, EncodingPolicy=QDomNode::EncodingFromDocument) const; QDomElement firstChildElement(const QString &tagName = QString()) const; QDomElement lastChildElement(const QString &tagName = QString()) const; From 83176f27a464f3a7c699e52461c784670193aae5 Mon Sep 17 00:00:00 2001 From: Richard Moore Date: Sun, 19 Feb 2012 15:31:44 +0000 Subject: [PATCH 396/406] convert length functions in QDom from uint to int. Fixes a ### Qt 5 Change-Id: I7a385f2b704d38ae626094f27b06a918d4a9bc48 Reviewed-by: David Faure --- src/xml/dom/qdom.cpp | 25 ++++++++++++------------- src/xml/dom/qdom.h | 6 +++--- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index 2188b8d6abf..3a2248619ee 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -219,7 +219,7 @@ public: void createList(); QDomNodePrivate* item(int index); - uint length() const; + int length() const; QAtomicInt ref; /* @@ -244,7 +244,7 @@ public: QDomNodePrivate* setNamedItemNS(QDomNodePrivate* arg); QDomNodePrivate* removeNamedItem(const QString& name); QDomNodePrivate* item(int index) const; - uint length() const; + int length() const; bool contains(const QString& name) const; bool containsNS(const QString& nsURI, const QString & localName) const; @@ -327,7 +327,7 @@ public: QDomCharacterDataPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& data); QDomCharacterDataPrivate(QDomCharacterDataPrivate* n, bool deep); - uint dataLength() const; + int dataLength() const; QString substringData(unsigned long offset, unsigned long count) const; void appendData(const QString& arg); void insertData(unsigned long offset, const QString& arg); @@ -1262,7 +1262,7 @@ QDomNodePrivate* QDomNodeListPrivate::item(int index) return list.at(index); } -uint QDomNodeListPrivate::length() const +int QDomNodeListPrivate::length() const { if (!node_impl) return 0; @@ -1394,7 +1394,7 @@ QDomNode QDomNodeList::item(int index) const /*! Returns the number of nodes in the list. */ -uint QDomNodeList::length() const +int QDomNodeList::length() const { if (!impl) return 0; @@ -3155,13 +3155,12 @@ QDomNodePrivate* QDomNamedNodeMapPrivate::removeNamedItem(const QString& name) QDomNodePrivate* QDomNamedNodeMapPrivate::item(int index) const { - if ((uint)index >= length()) + if (index >= length()) return 0; return *(map.constBegin() + index); } -// ### Qt 5: convert all length/size() functions in QDom to use int instead of uint. -uint QDomNamedNodeMapPrivate::length() const +int QDomNamedNodeMapPrivate::length() const { return map.count(); } @@ -3408,7 +3407,7 @@ QDomNode QDomNamedNodeMap::removeNamedItemNS(const QString& nsURI, const QString \sa item() */ -uint QDomNamedNodeMap::length() const +int QDomNamedNodeMap::length() const { if (!impl) return 0; @@ -3896,7 +3895,7 @@ QDomNodePrivate* QDomCharacterDataPrivate::cloneNode(bool deep) return p; } -uint QDomCharacterDataPrivate::dataLength() const +int QDomCharacterDataPrivate::dataLength() const { return value.length(); } @@ -4020,7 +4019,7 @@ void QDomCharacterData::setData(const QString& v) /*! Returns the length of the stored string. */ -uint QDomCharacterData::length() const +int QDomCharacterData::length() const { if (impl) return IMPL->dataLength(); @@ -5693,8 +5692,8 @@ QDomNodePrivate* QDomEntityPrivate::cloneNode(bool deep) static QByteArray encodeEntity(const QByteArray& str) { QByteArray tmp(str); - uint len = tmp.size(); - uint i = 0; + int len = tmp.size(); + int i = 0; const char* d = tmp.data(); while (i < len) { if (d[i] == '%'){ diff --git a/src/xml/dom/qdom.h b/src/xml/dom/qdom.h index 5dafb9e6a34..34c4b006368 100644 --- a/src/xml/dom/qdom.h +++ b/src/xml/dom/qdom.h @@ -263,7 +263,7 @@ public: inline QDomNode at(int index) const { return item(index); } // Qt API consistency // DOM read only attributes - uint length() const; + int length() const; inline int count() const { return length(); } // Qt API consitancy inline int size() const { return length(); } // Qt API consistency inline bool isEmpty() const { return length() == 0; } // Qt API consistency @@ -377,7 +377,7 @@ public: QDomNode removeNamedItemNS(const QString& nsURI, const QString& localName); // DOM read only attributes - uint length() const; + int length() const; int count() const { return length(); } // Qt API consitancy inline int size() const { return length(); } // Qt API consistency inline bool isEmpty() const { return length() == 0; } // Qt API consistency @@ -426,7 +426,7 @@ public: void replaceData(unsigned long offset, unsigned long count, const QString& arg); // DOM read only attributes - uint length() const; + int length() const; // DOM attributes QString data() const; From 4dabe78387d10495f9f6d0a7395f2ba3c80432bd Mon Sep 17 00:00:00 2001 From: Richard Moore Date: Sun, 19 Feb 2012 15:43:57 +0000 Subject: [PATCH 397/406] Remove many unneeded virtuals. Cleanup a ### Qt 5 TODO. Change-Id: I384e868ecc3ca4d80e4e71bb54d402f4ec1337a8 Reviewed-by: David Faure --- src/xml/dom/qdom.cpp | 44 ++++++++++++++++---------------------------- 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index 3a2248619ee..c16fd036138 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -80,8 +80,6 @@ QT_BEGIN_NAMESPACE Make a lot of the (mostly empty) methods in the public classes inline. Specially constructors assignment operators and comparison operators are candidates. - - The virtual isXxx functions in *Private can probably be replaced by inline methods checking the nodeType(). */ /* @@ -167,19 +165,22 @@ public: } // Dynamic cast - virtual bool isAttr() const { return false; } - virtual bool isCDATASection() const { return false; } - virtual bool isDocumentFragment() const { return false; } - virtual bool isDocument() const { return false; } - virtual bool isDocumentType() const { return false; } - virtual bool isElement() const { return false; } - virtual bool isEntityReference() const { return false; } - virtual bool isText() const { return false; } - virtual bool isEntity() const { return false; } - virtual bool isNotation() const { return false; } - virtual bool isProcessingInstruction() const { return false; } - virtual bool isCharacterData() const { return false; } - virtual bool isComment() const { return false; } + bool isAttr() const { return nodeType() == QDomNode::AttributeNode; } + bool isCDATASection() const { return nodeType() == QDomNode::CDATASectionNode; } + bool isDocumentFragment() const { return nodeType() == QDomNode::DocumentFragmentNode; } + bool isDocument() const { return nodeType() == QDomNode::DocumentNode; } + bool isDocumentType() const { return nodeType() == QDomNode::DocumentTypeNode; } + bool isElement() const { return nodeType() == QDomNode::ElementNode; } + bool isEntityReference() const { return nodeType() == QDomNode::EntityReferenceNode; } + bool isText() const { return (nodeType() == QDomNode::TextNode) + || (nodeType() == QDomNode::CDATASectionNode); } + bool isEntity() const { return nodeType() == QDomNode::EntityNode; } + bool isNotation() const { return nodeType() == QDomNode::NotationNode; } + bool isProcessingInstruction() const { return nodeType() == QDomNode::ProcessingInstructionNode; } + bool isCharacterData() const { return (nodeType() == QDomNode::CharacterDataNode) + || (nodeType() == QDomNode::TextNode) + || (nodeType() == QDomNode::CommentNode); } + bool isComment() const { return nodeType() == QDomNode::CommentNode; } virtual QDomNode::NodeType nodeType() const { return QDomNode::BaseNode; } @@ -296,7 +297,6 @@ public: QDomNodePrivate* removeChild(QDomNodePrivate* oldChild); QDomNodePrivate* appendChild(QDomNodePrivate* newChild); - virtual bool isDocumentType() const { return true; } QDomNode::NodeType nodeType() const { return QDomNode::DocumentTypeNode; } void save(QTextStream& s, int, int) const; @@ -317,7 +317,6 @@ public: // Reimplemented from QDomNodePrivate virtual QDomNodePrivate* cloneNode(bool deep = true); - virtual bool isDocumentFragment() const { return true; } QDomNode::NodeType nodeType() const { return QDomNode::DocumentFragmentNode; } }; @@ -335,7 +334,6 @@ public: void replaceData(unsigned long offset, unsigned long count, const QString& arg); // Reimplemented from QDomNodePrivate - virtual bool isCharacterData() const { return true; } QDomNode::NodeType nodeType() const { return QDomNode::CharacterDataNode; } QDomNodePrivate* cloneNode(bool deep = true); }; @@ -350,7 +348,6 @@ public: // Reimplemented from QDomNodePrivate QDomNodePrivate* cloneNode(bool deep = true); - virtual bool isText() const { return true; } QDomNode::NodeType nodeType() const { return QDomNode::TextNode; } virtual void save(QTextStream& s, int, int) const; }; @@ -367,7 +364,6 @@ public: // Reimplemented from QDomNodePrivate void setNodeValue(const QString& v); QDomNodePrivate* cloneNode(bool deep = true); - virtual bool isAttr() const { return true; } QDomNode::NodeType nodeType() const { return QDomNode::AttributeNode; } virtual void save(QTextStream& s, int, int) const; @@ -401,7 +397,6 @@ public: // Reimplemented from QDomNodePrivate QDomNamedNodeMapPrivate* attributes() { return m_attr; } bool hasAttributes() { return (m_attr->length() > 0); } - virtual bool isElement() const { return true; } QDomNode::NodeType nodeType() const { return QDomNode::ElementNode; } QDomNodePrivate* cloneNode(bool deep = true); virtual void save(QTextStream& s, int, int) const; @@ -419,7 +414,6 @@ public: // Reimplemented from QDomNodePrivate QDomNodePrivate* cloneNode(bool deep = true); - virtual bool isComment() const { return true; } QDomNode::NodeType nodeType() const { return QDomNode::CommentNode; } virtual void save(QTextStream& s, int, int) const; }; @@ -432,7 +426,6 @@ public: // Reimplemented from QDomNodePrivate QDomNodePrivate* cloneNode(bool deep = true); - virtual bool isCDATASection() const { return true; } QDomNode::NodeType nodeType() const { return QDomNode::CDATASectionNode; } virtual void save(QTextStream& s, int, int) const; }; @@ -446,7 +439,6 @@ public: // Reimplemented from QDomNodePrivate QDomNodePrivate* cloneNode(bool deep = true); - virtual bool isNotation() const { return true; } QDomNode::NodeType nodeType() const { return QDomNode::NotationNode; } virtual void save(QTextStream& s, int, int) const; @@ -464,7 +456,6 @@ public: // Reimplemented from QDomNodePrivate QDomNodePrivate* cloneNode(bool deep = true); - virtual bool isEntity() const { return true; } QDomNode::NodeType nodeType() const { return QDomNode::EntityNode; } virtual void save(QTextStream& s, int, int) const; @@ -482,7 +473,6 @@ public: // Reimplemented from QDomNodePrivate QDomNodePrivate* cloneNode(bool deep = true); - bool isEntityReference() const { return true; } QDomNode::NodeType nodeType() const { return QDomNode::EntityReferenceNode; } virtual void save(QTextStream& s, int, int) const; }; @@ -496,7 +486,6 @@ public: // Reimplemented from QDomNodePrivate QDomNodePrivate* cloneNode(bool deep = true); - virtual bool isProcessingInstruction() const { return true; } QDomNode::NodeType nodeType() const { return QDomNode::ProcessingInstructionNode; } virtual void save(QTextStream& s, int, int) const; }; @@ -534,7 +523,6 @@ public: // Reimplemented from QDomNodePrivate QDomNodePrivate* cloneNode(bool deep = true); - bool isDocument() const { return true; } QDomNode::NodeType nodeType() const { return QDomNode::DocumentNode; } void clear(); From e88f9a92b7ab05ea9bc25083de7dee1b67dd673e Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Tue, 14 Feb 2012 12:55:49 +1000 Subject: [PATCH 398/406] Stabilize tst_qdbusabstractinterface and make it XFAIL This test was written incorrectly in a way which happened to allow it to pass most of the time (but not all the time). Reset the state of test objects between each test function, and mark the broken functions with QEXPECT_FAIL and a link to a task. Replace the unusual WaitForPinger construct with the usual QTRY_VERIFY/QTRY_COMPARE method of verifying asynchronous operations. Task-number: QTBUG-24262 Change-Id: I82d09002307c0b500bf60cd5b583674321b37609 Reviewed-by: Thiago Macieira --- .../tst_qdbusabstractinterface.cpp | 78 +++++++++---------- 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp index 28dfd0b63fa..b6962940058 100644 --- a/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp +++ b/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp @@ -89,7 +89,9 @@ public: private slots: void initTestCase(); - void cleanupTestCase(); + + void init(); + void cleanup(); void makeVoidCall(); void makeStringCall(); @@ -194,39 +196,6 @@ private: QProcess proc; }; -class WaitForQPinger: public QObject -{ - Q_OBJECT -public: - WaitForQPinger(); - bool ok(); -public Q_SLOTS: - void ownerChange(const QString &name) - { - if (name == serviceName) - loop.quit(); - } - -private: - QEventLoop loop; -}; - -WaitForQPinger::WaitForQPinger() -{ - QDBusConnection con = QDBusConnection::sessionBus(); - if (!ok()) { - connect(con.interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)), - SLOT(ownerChange(QString))); - QTimer::singleShot(2000, &loop, SLOT(quit())); - loop.exec(); - } -} - -bool WaitForQPinger::ok() -{ - return QDBusConnection::sessionBus().isConnected() && - QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName); -} tst_QDBusAbstractInterface::tst_QDBusAbstractInterface() { @@ -244,6 +213,16 @@ void tst_QDBusAbstractInterface::initTestCase() QDBusConnection con = QDBusConnection::sessionBus(); QVERIFY(con.isConnected()); con.registerObject("/", &targetObj, QDBusConnection::ExportScriptableContents); +} + +void tst_QDBusAbstractInterface::init() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + // verify service isn't registered by something else + // (e.g. a left over qpinger from a previous test run) + QVERIFY(!con.interface()->isServiceRegistered(serviceName)); // start peer server #ifdef Q_OS_WIN @@ -253,9 +232,8 @@ void tst_QDBusAbstractInterface::initTestCase() #endif QVERIFY(proc.waitForStarted()); - WaitForQPinger w; - QVERIFY(w.ok()); - //QTest::qWait(2000); + // verify service is now registered + QTRY_VERIFY(con.interface()->isServiceRegistered(serviceName)); // get peer server address QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "address"); @@ -273,10 +251,24 @@ void tst_QDBusAbstractInterface::initTestCase() QVERIFY(rpl2.arguments().at(0).toBool()); } -void tst_QDBusAbstractInterface::cleanupTestCase() +void tst_QDBusAbstractInterface::cleanup() { - proc.close(); - proc.kill(); + QDBusConnection::disconnectFromPeer("peer"); + + // Kill peer, resetting the object exported by a separate process + proc.terminate(); + QVERIFY(proc.waitForFinished() || proc.state() == QProcess::NotRunning); + + // Reset the object exported by this process + targetObj.m_stringProp = QString(); + targetObj.m_variantProp = QDBusVariant(); + targetObj.m_complexProp = RegisteredType(); + + // Wait until the service is certainly not registered + QDBusConnection con = QDBusConnection::sessionBus(); + if (con.isConnected()) { + QTRY_VERIFY(!con.interface()->isServiceRegistered(serviceName)); + } } void tst_QDBusAbstractInterface::makeVoidCall() @@ -635,6 +627,7 @@ void tst_QDBusAbstractInterface::stringPropWritePeer() QString expectedValue = "This is a value"; QVERIFY(p->setProperty("stringProp", expectedValue)); + QEXPECT_FAIL("", "QTBUG-24262 peer tests are broken", Abort); QCOMPARE(targetObj.m_stringProp, expectedValue); } @@ -660,6 +653,7 @@ void tst_QDBusAbstractInterface::variantPropWritePeer() QDBusVariant expectedValue = QDBusVariant(Q_INT64_C(-47)); QVERIFY(p->setProperty("variantProp", qVariantFromValue(expectedValue))); + QEXPECT_FAIL("", "QTBUG-24262 peer tests are broken", Abort); QCOMPARE(targetObj.m_variantProp.variant(), expectedValue.variant()); } @@ -683,6 +677,7 @@ void tst_QDBusAbstractInterface::complexPropWritePeer() RegisteredType expectedValue = RegisteredType("This is a value"); QVERIFY(p->setProperty("complexProp", qVariantFromValue(expectedValue))); + QEXPECT_FAIL("", "QTBUG-24262 peer tests are broken", Abort); QCOMPARE(targetObj.m_complexProp, expectedValue); } @@ -762,6 +757,7 @@ void tst_QDBusAbstractInterface::stringPropDirectWritePeer() QString expectedValue = "This is a value"; p->setStringProp(expectedValue); + QEXPECT_FAIL("", "QTBUG-24262 peer tests are broken", Abort); QCOMPARE(targetObj.m_stringProp, expectedValue); } @@ -783,6 +779,7 @@ void tst_QDBusAbstractInterface::variantPropDirectWritePeer() QDBusVariant expectedValue = QDBusVariant(Q_INT64_C(-47)); p->setVariantProp(expectedValue); + QEXPECT_FAIL("", "QTBUG-24262 peer tests are broken", Abort); QCOMPARE(targetObj.m_variantProp.variant().userType(), expectedValue.variant().userType()); QCOMPARE(targetObj.m_variantProp.variant(), expectedValue.variant()); } @@ -805,6 +802,7 @@ void tst_QDBusAbstractInterface::complexPropDirectWritePeer() RegisteredType expectedValue = RegisteredType("This is a value"); p->setComplexProp(expectedValue); + QEXPECT_FAIL("", "QTBUG-24262 peer tests are broken", Abort); QCOMPARE(targetObj.m_complexProp, expectedValue); } From 4c56db58a285a7177c735f278f4a6ecd84122e9d Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Mon, 20 Feb 2012 11:36:24 +1000 Subject: [PATCH 399/406] Changed qnetworksession unittest to work from installation dir - Made test depend on subprogram - added install of subprogram Change-Id: Ib263e9e75ed3c900b52fb1c9b6d319e71d19bdbb Reviewed-by: Rohan McGovern --- tests/auto/network/bearer/qnetworksession/qnetworksession.pro | 4 +++- tests/auto/network/bearer/qnetworksession/test/test.pro | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/auto/network/bearer/qnetworksession/qnetworksession.pro b/tests/auto/network/bearer/qnetworksession/qnetworksession.pro index a85925bc171..f1cb47d14ee 100644 --- a/tests/auto/network/bearer/qnetworksession/qnetworksession.pro +++ b/tests/auto/network/bearer/qnetworksession/qnetworksession.pro @@ -1,2 +1,4 @@ TEMPLATE = subdirs -SUBDIRS = lackey test +SUBDIRS = lackey +test.depends = $$SUBDIRS +SUBDIRS += test diff --git a/tests/auto/network/bearer/qnetworksession/test/test.pro b/tests/auto/network/bearer/qnetworksession/test/test.pro index 5567e35b026..2f1a9ba6eaa 100644 --- a/tests/auto/network/bearer/qnetworksession/test/test.pro +++ b/tests/auto/network/bearer/qnetworksession/test/test.pro @@ -14,3 +14,6 @@ CONFIG(debug_and_release) { } else { DESTDIR = .. } + +load(testcase) # for target.path and installTestHelperApp() +installTestHelperApp("../lackey/lackey",lackey,lackey) From 8a182591be39e4c02f8acd907b31e5bebbd828a5 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Mon, 20 Feb 2012 15:12:50 +1000 Subject: [PATCH 400/406] tst_qapplication: mark expected failure on mac The tab key behavior in Qt5 no longer respects the "Text boxes and lists only" tab navigation option in OSX, which is the default. This is a regression since Qt4. Task-number: QTBUG-24372 Change-Id: I54c1663f8fb259dd847083432102a0bfad7dd69c Reviewed-by: Toby Tomkins --- .../widgets/kernel/qapplication/tst_qapplication.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index cba8675bee3..4d52e6215e6 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -69,6 +69,10 @@ #include #endif +QT_BEGIN_NAMESPACE +extern bool Q_GUI_EXPORT qt_tab_all_widgets; // from qapplication.cpp +QT_END_NAMESPACE + class tst_QApplication : public QObject { Q_OBJECT @@ -1525,8 +1529,15 @@ void tst_QApplication::focusChanged() QSettings appleSettings(QLatin1String("apple.com")); QVariant appleValue = appleSettings.value(QLatin1String("AppleKeyboardUIMode"), 0); tabAllControls = (appleValue.toInt() & 0x2); + if (!tabAllControls) { + QEXPECT_FAIL("", "QTBUG-24372 Mac tab key \"Text boxes and lists only\" vs " + "\"All controls\" setting is not respected in Qt5", Abort); + } #endif + // make sure Qt's idea of tabbing between widgets matches what we think it should + QCOMPARE(qt_tab_all_widgets, tabAllControls); + tab.simulate(now); if (!tabAllControls) { QVERIFY(spy.count() == 0); From ca1aa0da03aaf34aac1470bab52ce835a0392bef Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Mon, 20 Feb 2012 16:01:43 +1000 Subject: [PATCH 401/406] Make the QApplication autotest work for shadow builds. Use QFINDTESTDATA to locate the helper applications. Change-Id: I604d10e37c9367f2e95225864edf5bf705f1d961 Reviewed-by: Rohan McGovern --- .../kernel/qapplication/tst_qapplication.cpp | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index 4d52e6215e6..98872cb2f68 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -1398,12 +1398,21 @@ void tst_QApplication::testDeleteLaterProcessEvents() void tst_QApplication::desktopSettingsAware() { #ifndef QT_NO_PROCESS - QProcess testProcess; - const QString path = QStringLiteral("desktopsettingsaware/desktopsettingsaware"); + QString path; + { + // We need an application object for QFINDTESTDATA to work + // properly in all cases. + int argc = 0; + QCoreApplication app(argc, 0); + path = QFINDTESTDATA("desktopsettingsaware/"); + } + QVERIFY2(!path.isEmpty(), "Cannot locate desktopsettingsaware helper application"); + path += "desktopsettingsaware"; #ifdef Q_OS_WINCE int argc = 0; QApplication tmpApp(argc, 0, QApplication::GuiServer); #endif + QProcess testProcess; testProcess.start(path); QVERIFY2(testProcess.waitForStarted(), qPrintable(QString::fromLatin1("Cannot start '%1': %2").arg(path, testProcess.errorString()))); @@ -2061,9 +2070,19 @@ void tst_QApplication::touchEventPropagation() void tst_QApplication::qtbug_12673() { + QString path; + { + // We need an application object for QFINDTESTDATA to work + // properly in all cases. + int argc = 0; + QCoreApplication app(argc, 0); + path = QFINDTESTDATA("modal/"); + } + QVERIFY2(!path.isEmpty(), "Cannot locate modal helper application"); + path += "modal"; + QProcess testProcess; QStringList arguments; - const QString path = QStringLiteral("modal/modal"); testProcess.start(path, arguments); QVERIFY2(testProcess.waitForStarted(), qPrintable(QString::fromLatin1("Cannot start '%1': %2").arg(path, testProcess.errorString()))); From a30f42ddb3701ad90e7f0bb89d4ef435af6b5cf2 Mon Sep 17 00:00:00 2001 From: Toby Tomkins Date: Tue, 21 Feb 2012 11:03:00 +1000 Subject: [PATCH 402/406] Flag two tests (Win+A, Simon+G) in parseString as expect fail on OSX. Remove previously defined insignificant test flag as the number of tests failing has been reduced. Task-number: QTBUG-24406 Task-number: QTBUG-23058 Change-Id: I01b41f30469cf7a440e21195e105cb30a8db76e2 Reviewed-by: Rohan McGovern --- tests/auto/gui/kernel/qkeysequence/qkeysequence.pro | 2 -- tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp | 5 +++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/auto/gui/kernel/qkeysequence/qkeysequence.pro b/tests/auto/gui/kernel/qkeysequence/qkeysequence.pro index c6eb02919e6..1e0baafd09b 100644 --- a/tests/auto/gui/kernel/qkeysequence/qkeysequence.pro +++ b/tests/auto/gui/kernel/qkeysequence/qkeysequence.pro @@ -7,5 +7,3 @@ QT += core-private gui-private SOURCES += tst_qkeysequence.cpp RESOURCES += qkeysequence.qrc - -mac: CONFIG += insignificant_test # QTBUG-23058 diff --git a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp index eed7977c82b..29588e2ee90 100644 --- a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp +++ b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp @@ -576,6 +576,11 @@ void tst_QKeySequence::parseString() QFETCH( QString, strSequence ); QFETCH( QKeySequence, keycode ); +#ifdef Q_OS_MAC + QEXPECT_FAIL("Win+A", "QTBUG-24406 - This test fails on OSX", Abort); + QEXPECT_FAIL("Simon+G", "QTBUG-24406 - This test fails on OSX", Abort); +#endif + QCOMPARE( QKeySequence(strSequence).toString(), keycode.toString() ); QVERIFY( QKeySequence(strSequence) == keycode ); } From 7d44f45fb73e53af948006d72e2a7cefffd2519a Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 21 Feb 2012 12:00:14 +1000 Subject: [PATCH 403/406] Fix warning about unregistered metatype in QWindow autotest. Change-Id: If9d8d7e1cd52815ef7231294e4890dfafcd28ec8 Reviewed-by: Rohan McGovern --- tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index a860793ce45..90c96b40309 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -596,6 +596,8 @@ void tst_QWindow::touchCancelWithTouchToMouse() void tst_QWindow::orientation() { + qRegisterMetaType("Qt::ScreenOrientation"); + QWindow window; window.setGeometry(80, 80, 40, 40); window.create(); From f8c3074faa4d872f0c313bdf27ceb586fa1003e8 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 21 Feb 2012 12:52:15 +1000 Subject: [PATCH 404/406] Allow printer names to contain hyphens in QPrinterInfo test. Change-Id: I473627413d2f1cd5637704f2948eb07a264be49e Reviewed-by: Rohan McGovern --- tests/auto/gui/painting/qprinterinfo/tst_qprinterinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/gui/painting/qprinterinfo/tst_qprinterinfo.cpp b/tests/auto/gui/painting/qprinterinfo/tst_qprinterinfo.cpp index d312469449b..a2cfe7a473b 100644 --- a/tests/auto/gui/painting/qprinterinfo/tst_qprinterinfo.cpp +++ b/tests/auto/gui/painting/qprinterinfo/tst_qprinterinfo.cpp @@ -110,7 +110,7 @@ QString tst_QPrinterInfo::getDefaultPrinterFromSystem() return QString(); } - QRegExp defaultReg("default.*: *([a-zA-Z0-9_]+)"); + QRegExp defaultReg("default.*: *([a-zA-Z0-9_-]+)"); defaultReg.indexIn(output); QString printer = defaultReg.cap(1); macFixNameFormat(&printer); From 4eb54f7f3678fb8b90086453dfc6303b48afe683 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 21 Feb 2012 12:57:27 +1000 Subject: [PATCH 405/406] Improve tst_QPrinterInfo::testForDefaultPrinter(). Be explicit about skipping the test when no default printer is present. Change-Id: If69b275eb0f490411471ec42798d8aefcc57fd83 Reviewed-by: Rohan McGovern --- tests/auto/gui/painting/qprinterinfo/tst_qprinterinfo.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/auto/gui/painting/qprinterinfo/tst_qprinterinfo.cpp b/tests/auto/gui/painting/qprinterinfo/tst_qprinterinfo.cpp index a2cfe7a473b..2323dc8df33 100644 --- a/tests/auto/gui/painting/qprinterinfo/tst_qprinterinfo.cpp +++ b/tests/auto/gui/painting/qprinterinfo/tst_qprinterinfo.cpp @@ -221,7 +221,8 @@ void tst_QPrinterInfo::testForDefaultPrinter() # else QString defSysPrinter = getDefaultPrinterFromSystem(); # endif - if (defSysPrinter == "") return; + if (defSysPrinter == "") + QSKIP("No default printer available"); QList list = QPrinterInfo::availablePrinters(); bool found = false; From 69da8588d41bbf5ab785f5ad7c1fce76deefc7d0 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 21 Feb 2012 08:38:37 +0100 Subject: [PATCH 406/406] Fix qlogging test. Build app sub-process first. Change-Id: I87a11f7fd5d8a82584e496722f79e236191b0fb3 Reviewed-by: Friedemann Kleint --- tests/auto/corelib/global/qlogging/qlogging.pro | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/auto/corelib/global/qlogging/qlogging.pro b/tests/auto/corelib/global/qlogging/qlogging.pro index 449b7dfa5ee..1d5e7681df8 100644 --- a/tests/auto/corelib/global/qlogging/qlogging.pro +++ b/tests/auto/corelib/global/qlogging/qlogging.pro @@ -1,5 +1,6 @@ TEMPLATE = subdirs +CONFIG += ordered SUBDIRS += \ - tst_qlogging.pro \ - app \ No newline at end of file + app \ + tst_qlogging.pro