summaryrefslogtreecommitdiffstats
path: root/src/gui/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/util')
-rw-r--r--src/gui/util/qabstractlayoutstyleinfo.cpp40
-rw-r--r--src/gui/util/qabstractlayoutstyleinfo_p.h40
-rw-r--r--src/gui/util/qastchandler.cpp53
-rw-r--r--src/gui/util/qastchandler_p.h41
-rw-r--r--src/gui/util/qdesktopservices.cpp230
-rw-r--r--src/gui/util/qdesktopservices.h68
-rw-r--r--src/gui/util/qedidparser.cpp256
-rw-r--r--src/gui/util/qedidparser_p.h57
-rw-r--r--src/gui/util/qedidvendortable_p.h2507
-rw-r--r--src/gui/util/qgraphicsframecapture.cpp123
-rw-r--r--src/gui/util/qgraphicsframecapture_p.h55
-rw-r--r--src/gui/util/qgraphicsframecapture_p_p.h67
-rw-r--r--src/gui/util/qgraphicsframecapturemetal.mm169
-rw-r--r--src/gui/util/qgraphicsframecapturemetal_p_p.h57
-rw-r--r--src/gui/util/qgraphicsframecapturerenderdoc.cpp310
-rw-r--r--src/gui/util/qgraphicsframecapturerenderdoc_p_p.h53
-rw-r--r--src/gui/util/qgridlayoutengine.cpp356
-rw-r--r--src/gui/util/qgridlayoutengine_p.h212
-rw-r--r--src/gui/util/qhexstring_p.h42
-rw-r--r--src/gui/util/qktxhandler.cpp305
-rw-r--r--src/gui/util/qktxhandler_p.h46
-rw-r--r--src/gui/util/qlayoutpolicy.cpp42
-rw-r--r--src/gui/util/qlayoutpolicy_p.h70
-rw-r--r--src/gui/util/qpkmhandler.cpp53
-rw-r--r--src/gui/util/qpkmhandler_p.h41
-rw-r--r--src/gui/util/qshaderformat.cpp145
-rw-r--r--src/gui/util/qshaderformat_p.h122
-rw-r--r--src/gui/util/qshadergenerator.cpp594
-rw-r--r--src/gui/util/qshadergenerator_p.h79
-rw-r--r--src/gui/util/qshadergraph.cpp262
-rw-r--r--src/gui/util/qshadergraph_p.h123
-rw-r--r--src/gui/util/qshadergraphloader.cpp269
-rw-r--r--src/gui/util/qshadergraphloader_p.h99
-rw-r--r--src/gui/util/qshaderlanguage.cpp54
-rw-r--r--src/gui/util/qshaderlanguage_p.h164
-rw-r--r--src/gui/util/qshadernode.cpp172
-rw-r--r--src/gui/util/qshadernode_p.h128
-rw-r--r--src/gui/util/qshadernodeport.cpp55
-rw-r--r--src/gui/util/qshadernodeport_p.h88
-rw-r--r--src/gui/util/qshadernodesloader.cpp289
-rw-r--r--src/gui/util/qshadernodesloader_p.h96
-rw-r--r--src/gui/util/qtexturefiledata.cpp211
-rw-r--r--src/gui/util/qtexturefiledata_p.h65
-rw-r--r--src/gui/util/qtexturefilehandler_p.h42
-rw-r--r--src/gui/util/qtexturefilereader.cpp42
-rw-r--r--src/gui/util/qtexturefilereader_p.h40
-rw-r--r--src/gui/util/qundogroup.cpp479
-rw-r--r--src/gui/util/qundogroup.h64
-rw-r--r--src/gui/util/qundostack.cpp1354
-rw-r--r--src/gui/util/qundostack.h121
-rw-r--r--src/gui/util/qundostack_p.h68
-rw-r--r--src/gui/util/qvalidator.cpp459
-rw-r--r--src/gui/util/qvalidator.h80
-rw-r--r--src/gui/util/util.pri48
54 files changed, 6778 insertions, 4327 deletions
diff --git a/src/gui/util/qabstractlayoutstyleinfo.cpp b/src/gui/util/qabstractlayoutstyleinfo.cpp
index 40ad51452a..51d569f814 100644
--- a/src/gui/util/qabstractlayoutstyleinfo.cpp
+++ b/src/gui/util/qabstractlayoutstyleinfo.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qabstractlayoutstyleinfo_p.h"
diff --git a/src/gui/util/qabstractlayoutstyleinfo_p.h b/src/gui/util/qabstractlayoutstyleinfo_p.h
index bf1e1fc852..42578c58ca 100644
--- a/src/gui/util/qabstractlayoutstyleinfo_p.h
+++ b/src/gui/util/qabstractlayoutstyleinfo_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTLAYOUTSTYLEINFO_P_H
#define QABSTRACTLAYOUTSTYLEINFO_P_H
diff --git a/src/gui/util/qastchandler.cpp b/src/gui/util/qastchandler.cpp
index 6d163c6701..ec8b92f557 100644
--- a/src/gui/util/qastchandler.cpp
+++ b/src/gui/util/qastchandler.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qastchandler_p.h"
#include "qtexturefiledata_p.h"
@@ -59,9 +23,11 @@ struct AstcHeader
quint8 zSize[3];
};
+QAstcHandler::~QAstcHandler() = default;
+
bool QAstcHandler::canRead(const QByteArray &suffix, const QByteArray &block)
{
- Q_UNUSED(suffix)
+ Q_UNUSED(suffix);
return block.startsWith("\x13\xAB\xA1\x5C");
}
@@ -71,7 +37,7 @@ quint32 QAstcHandler::astcGLFormat(quint8 xBlockDim, quint8 yBlockDim) const
static const quint32 glFormatRGBABase = 0x93B0; // GL_COMPRESSED_RGBA_ASTC_4x4_KHR
static const quint32 glFormatSRGBBase = 0x93D0; // GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR
- static QSize dims[14] = {
+ Q_CONSTINIT static QSize dims[14] = {
{ 4, 4 }, // GL_COMPRESSED_xxx_ASTC_4x4_KHR
{ 5, 4 }, // GL_COMPRESSED_xxx_ASTC_5x4_KHR
{ 5, 5 }, // GL_COMPRESSED_xxx_ASTC_5x5_KHR
@@ -143,13 +109,14 @@ QTextureFileData QAstcHandler::read()
int zBlocks = (zSz + header->blockDimZ - 1) / header->blockDimZ;
int byteCount = 0;
- bool oob = mul_overflow(xBlocks, yBlocks, &byteCount)
- || mul_overflow(byteCount, zBlocks, &byteCount)
- || mul_overflow(byteCount, 16, &byteCount);
+ bool oob = qMulOverflow(xBlocks, yBlocks, &byteCount)
+ || qMulOverflow(byteCount, zBlocks, &byteCount)
+ || qMulOverflow(byteCount, 16, &byteCount);
res.setDataOffset(sizeof(AstcHeader));
res.setNumLevels(1);
+ res.setNumFaces(1);
res.setDataLength(byteCount);
if (oob || !res.isValid()) {
diff --git a/src/gui/util/qastchandler_p.h b/src/gui/util/qastchandler_p.h
index 398f1833b6..5dd7f7a524 100644
--- a/src/gui/util/qastchandler_p.h
+++ b/src/gui/util/qastchandler_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QASTCHANDLER_H
#define QASTCHANDLER_H
@@ -59,6 +23,7 @@ class QAstcHandler : public QTextureFileHandler
{
public:
using QTextureFileHandler::QTextureFileHandler;
+ ~QAstcHandler() override;
static bool canRead(const QByteArray &suffix, const QByteArray &block);
diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp
index 763f309fc7..4d98faf398 100644
--- a/src/gui/util/qdesktopservices.cpp
+++ b/src/gui/util/qdesktopservices.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qdesktopservices.h"
@@ -56,9 +20,8 @@
QT_BEGIN_NAMESPACE
-class QOpenUrlHandlerRegistry : public QObject
+class QOpenUrlHandlerRegistry
{
- Q_OBJECT
public:
QOpenUrlHandlerRegistry() = default;
@@ -71,26 +34,10 @@ public:
};
typedef QHash<QString, Handler> HandlerHash;
HandlerHash handlers;
-
-public Q_SLOTS:
- void handlerDestroyed(QObject *handler);
-
};
Q_GLOBAL_STATIC(QOpenUrlHandlerRegistry, handlerRegistry)
-void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler)
-{
- HandlerHash::Iterator it = handlers.begin();
- while (it != handlers.end()) {
- if (it->receiver == handler) {
- it = handlers.erase(it);
- } else {
- ++it;
- }
- }
-}
-
/*!
\class QDesktopServices
\brief The QDesktopServices class provides methods for accessing common desktop services.
@@ -135,6 +82,7 @@ void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler)
inside the application:
\snippet code/src_gui_util_qdesktopservices.cpp 0
+ \snippet code/src_gui_util_qdesktopservices.cpp setUrlHandler
If inside the handler you decide that you can't open the requested
URL, you can just call QDesktopServices::openUrl() again with the
@@ -145,9 +93,6 @@ void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler)
openUrl() function can also be exposed to other applications, opening up
for application deep linking or a very basic URL-based IPC mechanism.
- \note Since Qt 5, storageLocation() and displayName() are replaced by functionality
- provided by the QStandardPaths class.
-
\sa QSystemTrayIcon, QProcess, QStandardPaths
*/
@@ -184,11 +129,18 @@ void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler)
\warning URLs passed to this function on iOS will not load unless their schemes are
listed in the \c LSApplicationQueriesSchemes key of the application's Info.plist file.
For more information, see the Apple Developer Documentation for
- \l{https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl}{canOpenURL(_:)}.
+ \l {iOS: canOpenURL:}{canOpenURL:}.
For example, the following lines enable URLs with the HTTPS scheme:
\snippet code/src_gui_util_qdesktopservices.cpp 3
+ \note For Android Nougat (SDK 24) and above, URLs with a \c file scheme
+ are opened using \l {Android: FileProvider}{FileProvider} which tries to obtain
+ a shareable \c content scheme URI first. For that reason, Qt for Android defines
+ a file provider with the authority \c ${applicationId}.qtprovider, with \c applicationId
+ being the app's package name to avoid name conflicts. For more information, also see
+ \l {Android: Setting up file sharing}{Setting up file sharing}.
+
\sa setUrlHandler()
*/
bool QDesktopServices::openUrl(const QUrl &url)
@@ -246,14 +198,6 @@ bool QDesktopServices::openUrl(const QUrl &url)
\snippet code/src_gui_util_qdesktopservices.cpp 0
- To use this function for receiving data from other apps on iOS you also need to
- add the custom scheme to the \c CFBundleURLSchemes list in your Info.plist file:
-
- \snippet code/src_gui_util_qdesktopservices.cpp 4
-
- For more information, see the Apple Developer Documentation for
- \l{https://developer.apple.com/documentation/uikit/core_app/allowing_apps_and_websites_to_link_to_your_content/communicating_with_other_apps_using_custom_urls?language=objc}{Communicating with Other Apps Using Custom URLs}.
-
If setUrlHandler() is used to set a new handler for a scheme which already
has a handler, the existing handler is simply replaced with the new one.
Since QDesktopServices does not take ownership of handlers, no objects are
@@ -262,6 +206,65 @@ bool QDesktopServices::openUrl(const QUrl &url)
Note that the handler will always be called from within the same thread that
calls QDesktopServices::openUrl().
+ You must call unsetUrlHandler() before destroying the handler object, so
+ the destruction of the handler object does not overlap with concurrent
+ invocations of openUrl() using it.
+
+ \section1 iOS and \macos
+
+ To use this function for receiving data from other apps on iOS/\macos
+ you also need to add the custom scheme to the \c CFBundleURLSchemes
+ list in your Info.plist file:
+
+ \snippet code/src_gui_util_qdesktopservices.cpp 4
+
+ For more information, see the Apple Developer Documentation for
+ \l {iOS: Defining a Custom URL Scheme for Your App}{Defining a Custom URL Scheme for Your App}.
+ \warning It is not possible to claim support for some well known URL schemes, including http and
+ https. This is only allowed for Universal Links.
+
+ To claim support for http and https the above entry in the Info.plist file
+ is not allowed. This is only possible when you add your domain to the
+ Entitlements file:
+
+ \snippet code/src_gui_util_qdesktopservices.cpp 7
+
+ iOS/\macos will search for /.well-known/apple-app-site-association on your domain,
+ when the application is installed. If you want to listen to
+ \c{https://your.domain.com/help?topic=ABCDEF} you need to provide the following
+ content there:
+
+ \snippet code/src_gui_util_qdesktopservices.cpp 8
+
+ For more information, see the Apple Developer Documentation for
+ \l {iOS: Supporting Associated Domains}{Supporting Associated Domains}.
+
+ \section1 Android
+
+ To use this function for receiving data from other apps on Android, you
+ need to add one or more intent filter to the \c activity in your app manifest:
+
+ \snippet code/src_gui_util_qdesktopservices.cpp 9
+
+ For more information, see the Android Developer Documentation for
+ \l {Android: Create Deep Links to App Content}{Create Deep Links to App Content}.
+
+ To immediately open the corresponding content in your Android app, without
+ requiring the user to select the app, you need to verify your link. To
+ enable the verification, add an additional parameter to your intent filter:
+
+ \snippet code/src_gui_util_qdesktopservices.cpp 10
+
+ Android will look for \c{https://your.domain.com/.well-known/assetlinks.json},
+ when the application is installed. If you want to listen to
+ \c{https://your.domain.com:1337/help}, you need to provide the following
+ content there:
+
+ \snippet code/src_gui_util_qdesktopservices.cpp 11
+
+ For more information, see the Android Developer Documentation for
+ \l {Android: Verify Android App Links}{Verify Android App Links}.
+
\sa openUrl(), unsetUrlHandler()
*/
void QDesktopServices::setUrlHandler(const QString &scheme, QObject *receiver, const char *method)
@@ -276,13 +279,15 @@ void QDesktopServices::setUrlHandler(const QString &scheme, QObject *receiver, c
h.receiver = receiver;
h.name = method;
registry->handlers.insert(scheme.toLower(), h);
- QObject::connect(receiver, SIGNAL(destroyed(QObject*)),
- registry, SLOT(handlerDestroyed(QObject*)));
}
/*!
Removes a previously set URL handler for the specified \a scheme.
+ Call this function before the handler object that was registered for \a scheme
+ is destroyed, to prevent concurrent openUrl() calls from continuing to call
+ the destroyed handler object.
+
\sa setUrlHandler()
*/
void QDesktopServices::unsetUrlHandler(const QString &scheme)
@@ -290,91 +295,6 @@ void QDesktopServices::unsetUrlHandler(const QString &scheme)
setUrlHandler(scheme, nullptr, nullptr);
}
-#if QT_DEPRECATED_SINCE(5, 0)
-/*!
- \enum QDesktopServices::StandardLocation
- \since 4.4
- \obsolete
- Use QStandardPaths::StandardLocation (see storageLocation() for porting notes)
-
- This enum describes the different locations that can be queried by
- QDesktopServices::storageLocation and QDesktopServices::displayName.
-
- \value DesktopLocation Returns the user's desktop directory.
- \value DocumentsLocation Returns the user's document.
- \value FontsLocation Returns the user's fonts.
- \value ApplicationsLocation Returns the user's applications.
- \value MusicLocation Returns the users music.
- \value MoviesLocation Returns the user's movies.
- \value PicturesLocation Returns the user's pictures.
- \value TempLocation Returns the system's temporary directory.
- \value HomeLocation Returns the user's home directory.
- \value DataLocation Returns a directory location where persistent
- application data can be stored. QCoreApplication::applicationName
- and QCoreApplication::organizationName should work on all
- platforms.
- \value CacheLocation Returns a directory location where user-specific
- non-essential (cached) data should be written.
-
- \sa storageLocation(), displayName()
-*/
-
-/*!
- \fn QString QDesktopServices::storageLocation(StandardLocation type)
- \obsolete
- Use QStandardPaths::writableLocation()
-
- \note when porting QDesktopServices::DataLocation to QStandardPaths::DataLocation,
- a different path will be returned.
-
- \c{QDesktopServices::DataLocation} was \c{GenericDataLocation + "/data/organization/application"},
- while QStandardPaths::DataLocation is \c{GenericDataLocation + "/organization/application"}.
-
- Also note that \c{application} could be empty in Qt 4, if QCoreApplication::setApplicationName()
- wasn't called, while in Qt 5 it defaults to the name of the executable.
-
- Therefore, if you still need to access the Qt 4 path (for example for data migration to Qt 5), replace
- \snippet code/src_gui_util_qdesktopservices.cpp 5
- with
- \snippet code/src_gui_util_qdesktopservices.cpp 6
- (assuming an organization name and an application name were set).
-*/
-
-/*!
- \fn QString QDesktopServices::displayName(StandardLocation type)
- \obsolete
- Use QStandardPaths::displayName()
-*/
-#endif
-
-extern Q_CORE_EXPORT QString qt_applicationName_noFallback();
-
-QString QDesktopServices::storageLocationImpl(QStandardPaths::StandardLocation type)
-{
- if (type == QStandardPaths::AppLocalDataLocation) {
- // Preserve Qt 4 compatibility:
- // * QCoreApplication::applicationName() must default to empty
- // * Unix data location is under the "data/" subdirectory
- const QString compatAppName = qt_applicationName_noFallback();
- const QString baseDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
- const QString organizationName = QCoreApplication::organizationName();
-#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
- QString result = baseDir;
- if (!organizationName.isEmpty())
- result += QLatin1Char('/') + organizationName;
- if (!compatAppName.isEmpty())
- result += QLatin1Char('/') + compatAppName;
- return result;
-#elif defined(Q_OS_UNIX)
- return baseDir + QLatin1String("/data/")
- + organizationName + QLatin1Char('/') + compatAppName;
-#endif
- }
- return QStandardPaths::writableLocation(type);
-}
-
QT_END_NAMESPACE
-#include "qdesktopservices.moc"
-
#endif // QT_NO_DESKTOPSERVICES
diff --git a/src/gui/util/qdesktopservices.h b/src/gui/util/qdesktopservices.h
index 21705e2757..476b84691e 100644
--- a/src/gui/util/qdesktopservices.h
+++ b/src/gui/util/qdesktopservices.h
@@ -1,55 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDESKTOPSERVICES_H
#define QDESKTOPSERVICES_H
#include <QtGui/qtguiglobal.h>
#include <QtCore/qstring.h>
-#include <QtCore/qstandardpaths.h>
QT_BEGIN_NAMESPACE
#ifndef QT_NO_DESKTOPSERVICES
-class QStringList;
class QUrl;
class QObject;
@@ -59,32 +21,6 @@ public:
static bool openUrl(const QUrl &url);
static void setUrlHandler(const QString &scheme, QObject *receiver, const char *method);
static void unsetUrlHandler(const QString &scheme);
-
-#if QT_DEPRECATED_SINCE(5, 0)
- //Must match QStandardPaths::StandardLocation
- enum StandardLocation {
- DesktopLocation,
- DocumentsLocation,
- FontsLocation,
- ApplicationsLocation,
- MusicLocation,
- MoviesLocation,
- PicturesLocation,
- TempLocation,
- HomeLocation,
- DataLocation,
- CacheLocation
- };
-
- QT_DEPRECATED static QString storageLocation(StandardLocation type) {
- return storageLocationImpl(static_cast<QStandardPaths::StandardLocation>(type));
- }
- QT_DEPRECATED static QString displayName(StandardLocation type) {
- return QStandardPaths::displayName(static_cast<QStandardPaths::StandardLocation>(type));
- }
-#endif
-private:
- static QString storageLocationImpl(QStandardPaths::StandardLocation type);
};
#endif // QT_NO_DESKTOPSERVICES
diff --git a/src/gui/util/qedidparser.cpp b/src/gui/util/qedidparser.cpp
new file mode 100644
index 0000000000..4dae151e6a
--- /dev/null
+++ b/src/gui/util/qedidparser.cpp
@@ -0,0 +1,256 @@
+// Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+// Copyright (C) 2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <QtCore/QFile>
+#include <QtCore/QByteArrayView>
+
+#include "qedidparser_p.h"
+#include "qedidvendortable_p.h"
+
+#define EDID_DESCRIPTOR_ALPHANUMERIC_STRING 0xfe
+#define EDID_DESCRIPTOR_PRODUCT_NAME 0xfc
+#define EDID_DESCRIPTOR_SERIAL_NUMBER 0xff
+
+#define EDID_DATA_BLOCK_COUNT 4
+#define EDID_OFFSET_DATA_BLOCKS 0x36
+#define EDID_OFFSET_LAST_BLOCK 0x6c
+#define EDID_OFFSET_PNP_ID 0x08
+#define EDID_OFFSET_SERIAL 0x0c
+#define EDID_PHYSICAL_WIDTH 0x15
+#define EDID_OFFSET_PHYSICAL_HEIGHT 0x16
+#define EDID_TRANSFER_FUNCTION 0x17
+#define EDID_FEATURE_SUPPORT 0x18
+#define EDID_CHROMATICITIES_BLOCK 0x19
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt::StringLiterals;
+
+static QString lookupVendorIdInSystemDatabase(QByteArrayView id)
+{
+ QString result;
+
+ const QString fileName = "/usr/share/hwdata/pnp.ids"_L1;
+ QFile file(fileName);
+ if (!file.open(QFile::ReadOnly))
+ return result;
+
+ // On Ubuntu 20.04 the longest line in the file is 85 bytes, so this
+ // leaves plenty of room...
+ constexpr int MaxLineSize = 512;
+ char buf[MaxLineSize];
+
+ while (!file.atEnd()) {
+ auto read = file.readLine(buf, MaxLineSize);
+ if (read < 0 || read == MaxLineSize) // read error
+ break;
+
+ QByteArrayView line(buf, read - 1); // -1 to remove the trailing newline
+ if (line.isEmpty())
+ continue;
+
+ if (line.startsWith('#'))
+ continue;
+
+ auto tabPosition = line.indexOf('\t');
+ if (tabPosition <= 0) // no vendor id
+ continue;
+ if (tabPosition + 1 == line.size()) // no vendor name
+ continue;
+
+ if (line.first(tabPosition) == id) {
+ auto vendor = line.sliced(tabPosition + 1);
+ result = QString::fromUtf8(vendor.data(), vendor.size());
+ break;
+ }
+ }
+
+ return result;
+}
+
+bool QEdidParser::parse(const QByteArray &blob)
+{
+ const quint8 *data = reinterpret_cast<const quint8 *>(blob.constData());
+ const size_t length = blob.size();
+
+ // Verify header
+ if (length < 128)
+ return false;
+ if (data[0] != 0x00 || data[1] != 0xff)
+ return false;
+
+ /* Decode the PNP ID from three 5 bit words packed into 2 bytes
+ * /--08--\/--09--\
+ * 7654321076543210
+ * |\---/\---/\---/
+ * R C1 C2 C3 */
+ char pnpId[3];
+ pnpId[0] = 'A' + ((data[EDID_OFFSET_PNP_ID] & 0x7c) / 4) - 1;
+ pnpId[1] = 'A' + ((data[EDID_OFFSET_PNP_ID] & 0x3) * 8) + ((data[EDID_OFFSET_PNP_ID + 1] & 0xe0) / 32) - 1;
+ pnpId[2] = 'A' + (data[EDID_OFFSET_PNP_ID + 1] & 0x1f) - 1;
+
+ // Clear manufacturer
+ manufacturer = QString();
+
+ // Serial number, will be overwritten by an ASCII descriptor
+ // when and if it will be found
+ quint32 serial = data[EDID_OFFSET_SERIAL]
+ + (data[EDID_OFFSET_SERIAL + 1] << 8)
+ + (data[EDID_OFFSET_SERIAL + 2] << 16)
+ + (data[EDID_OFFSET_SERIAL + 3] << 24);
+ if (serial > 0)
+ serialNumber = QString::number(serial);
+ else
+ serialNumber = QString();
+
+ // Parse EDID data
+ for (int i = 0; i < EDID_DATA_BLOCK_COUNT; ++i) {
+ const uint offset = EDID_OFFSET_DATA_BLOCKS + i * 18;
+
+ if (data[offset] != 0 || data[offset + 1] != 0 || data[offset + 2] != 0)
+ continue;
+
+ if (data[offset + 3] == EDID_DESCRIPTOR_PRODUCT_NAME)
+ model = parseEdidString(&data[offset + 5]);
+ else if (data[offset + 3] == EDID_DESCRIPTOR_ALPHANUMERIC_STRING)
+ identifier = parseEdidString(&data[offset + 5]);
+ else if (data[offset + 3] == EDID_DESCRIPTOR_SERIAL_NUMBER)
+ serialNumber = parseEdidString(&data[offset + 5]);
+ }
+
+ // Try to use cache first because it is potentially more updated
+ manufacturer = lookupVendorIdInSystemDatabase(pnpId);
+
+ if (manufacturer.isEmpty()) {
+ // Find the manufacturer from the vendor lookup table
+ const auto compareVendorId = [](const VendorTable &vendor, const char *str)
+ {
+ return strncmp(vendor.id, str, 3) < 0;
+ };
+
+ const auto b = std::begin(q_edidVendorTable);
+ const auto e = std::end(q_edidVendorTable);
+ auto it = std::lower_bound(b,
+ e,
+ pnpId,
+ compareVendorId);
+
+ if (it != e && strncmp(it->id, pnpId, 3) == 0)
+ manufacturer = QString::fromUtf8(it->name);
+ }
+
+ // If we don't know the manufacturer, fallback to PNP ID
+ if (manufacturer.isEmpty())
+ manufacturer = QString::fromUtf8(pnpId, std::size(pnpId));
+
+ // Physical size
+ physicalSize = QSizeF(data[EDID_PHYSICAL_WIDTH], data[EDID_OFFSET_PHYSICAL_HEIGHT]) * 10;
+
+ // Gamma and transfer function
+ const uint igamma = data[EDID_TRANSFER_FUNCTION];
+ if (igamma != 0xff) {
+ gamma = 1.0 + (igamma / 100.0f);
+ useTables = false;
+ } else {
+ gamma = 0.0; // Defined in DI-EXT
+ useTables = true;
+ }
+ sRgb = data[EDID_FEATURE_SUPPORT] & 0x04;
+
+ // Chromaticities
+ int rx = (data[EDID_CHROMATICITIES_BLOCK] >> 6) & 0x03;
+ int ry = (data[EDID_CHROMATICITIES_BLOCK] >> 4) & 0x03;
+ int gx = (data[EDID_CHROMATICITIES_BLOCK] >> 2) & 0x03;
+ int gy = (data[EDID_CHROMATICITIES_BLOCK] >> 0) & 0x03;
+ int bx = (data[EDID_CHROMATICITIES_BLOCK + 1] >> 6) & 0x03;
+ int by = (data[EDID_CHROMATICITIES_BLOCK + 1] >> 4) & 0x03;
+ int wx = (data[EDID_CHROMATICITIES_BLOCK + 1] >> 2) & 0x03;
+ int wy = (data[EDID_CHROMATICITIES_BLOCK + 1] >> 0) & 0x03;
+ rx |= data[EDID_CHROMATICITIES_BLOCK + 2] << 2;
+ ry |= data[EDID_CHROMATICITIES_BLOCK + 3] << 2;
+ gx |= data[EDID_CHROMATICITIES_BLOCK + 4] << 2;
+ gy |= data[EDID_CHROMATICITIES_BLOCK + 5] << 2;
+ bx |= data[EDID_CHROMATICITIES_BLOCK + 6] << 2;
+ by |= data[EDID_CHROMATICITIES_BLOCK + 7] << 2;
+ wx |= data[EDID_CHROMATICITIES_BLOCK + 8] << 2;
+ wy |= data[EDID_CHROMATICITIES_BLOCK + 9] << 2;
+
+ redChromaticity.setX(rx * (1.0f / 1024.0f));
+ redChromaticity.setY(ry * (1.0f / 1024.0f));
+ greenChromaticity.setX(gx * (1.0f / 1024.0f));
+ greenChromaticity.setY(gy * (1.0f / 1024.0f));
+ blueChromaticity.setX(bx * (1.0f / 1024.0f));
+ blueChromaticity.setY(by * (1.0f / 1024.0f));
+ whiteChromaticity.setX(wx * (1.0f / 1024.0f));
+ whiteChromaticity.setY(wy * (1.0f / 1024.0f));
+
+ // Find extensions
+ for (uint i = 1; i < length / 128; ++i) {
+ uint extensionId = data[i * 128];
+ if (extensionId == 0x40) { // DI-EXT
+ // 0x0E (sub-pixel layout)
+ // 0x20->0x22 (bits per color)
+ // 0x51->0x7e Transfer characteristics
+ const uchar desc = data[i * 128 + 0x51];
+ const uchar len = desc & 0x3f;
+ if ((desc & 0xc0) == 0x40) {
+ if (len > 45)
+ return false;
+ QList<uint16_t> whiteTRC;
+ whiteTRC.reserve(len + 1);
+ for (uint j = 0; j < len; ++j)
+ whiteTRC[j] = data[0x52 + j] * 0x101;
+ whiteTRC[len] = 0xffff;
+ tables.append(whiteTRC);
+ } else if ((desc & 0xc0) == 0x80) {
+ if (len > 15)
+ return false;
+ QList<uint16_t> redTRC;
+ QList<uint16_t> greenTRC;
+ QList<uint16_t> blueTRC;
+ blueTRC.reserve(len + 1);
+ greenTRC.reserve(len + 1);
+ redTRC.reserve(len + 1);
+ for (uint j = 0; j < len; ++j)
+ blueTRC[j] = data[0x52 + j] * 0x101;
+ blueTRC[len] = 0xffff;
+ for (uint j = 0; j < len; ++j)
+ greenTRC[j] = data[0x61 + j] * 0x101;
+ greenTRC[len] = 0xffff;
+ for (uint j = 0; j < len; ++j)
+ redTRC[j] = data[0x70 + j] * 0x101;
+ redTRC[len] = 0xffff;
+ tables.append(redTRC);
+ tables.append(greenTRC);
+ tables.append(blueTRC);
+ }
+ }
+ }
+
+ return true;
+}
+
+QString QEdidParser::parseEdidString(const quint8 *data)
+{
+ QByteArray buffer(reinterpret_cast<const char *>(data), 13);
+
+ for (int i = 0; i < buffer.size(); ++i) {
+ // If there are less than 13 characters in the string, the string
+ // is terminated with the ASCII code ‘0Ah’ (line feed) and padded
+ // with ASCII code ‘20h’ (space). See EDID 1.4, sections 3.10.3.1,
+ // 3.10.3.2, and 3.10.3.4.
+ if (buffer[i] == '\n') {
+ buffer.truncate(i);
+ break;
+ }
+
+ // Replace non-printable characters with dash
+ if (buffer[i] < '\040' || buffer[i] > '\176')
+ buffer[i] = '-';
+ }
+
+ return QString::fromLatin1(buffer);
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/util/qedidparser_p.h b/src/gui/util/qedidparser_p.h
new file mode 100644
index 0000000000..99352b03b0
--- /dev/null
+++ b/src/gui/util/qedidparser_p.h
@@ -0,0 +1,57 @@
+// Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+// Copyright (C) 2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QEDIDPARSER_P_H
+#define QEDIDPARSER_P_H
+
+#include <QtCore/QMap>
+#include <QtCore/QPointF>
+#include <QtCore/QSize>
+
+//
+// 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 <QtGui/qtguiglobal.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qsize.h>
+#include <QtCore/qstring.h>
+#include <QtCore/private/qglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_GUI_EXPORT QEdidParser
+{
+public:
+ bool parse(const QByteArray &blob);
+
+ QString identifier;
+ QString manufacturer;
+ QString model;
+ QString serialNumber;
+ QSizeF physicalSize;
+ qreal gamma;
+ QPointF redChromaticity;
+ QPointF greenChromaticity;
+ QPointF blueChromaticity;
+ QPointF whiteChromaticity;
+ QList<QList<uint16_t>> tables;
+ bool sRgb;
+ bool useTables;
+
+private:
+ QString parseEdidString(const quint8 *data);
+};
+
+QT_END_NAMESPACE
+
+#endif // QEDIDPARSER_P_H
diff --git a/src/gui/util/qedidvendortable_p.h b/src/gui/util/qedidvendortable_p.h
new file mode 100644
index 0000000000..0a6132e4d7
--- /dev/null
+++ b/src/gui/util/qedidvendortable_p.h
@@ -0,0 +1,2507 @@
+// Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+/*
+ * This lookup table was generated from https://github.com/vcrhonek/hwdata/raw/master/pnp.ids
+ *
+ * Do not change this file directly, instead edit the
+ * qtbase/util/edid/qedidvendortable.py script and regenerate this file.
+ */
+
+#ifndef QEDIDVENDORTABLE_P_H
+#define QEDIDVENDORTABLE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/private/qglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+struct VendorTable {
+ const char id[4];
+ const char name[78];
+};
+
+static const VendorTable q_edidVendorTable[] = {
+ { "AAA", "Avolites Ltd" },
+ { "AAE", "Anatek Electronics Inc." },
+ { "AAM", "Aava Mobile Oy" },
+ { "AAN", "AAEON Technology Inc." },
+ { "AAT", "Ann Arbor Technologies" },
+ { "ABA", "ABBAHOME INC." },
+ { "ABC", "AboCom System Inc." },
+ { "ABD", "Allen Bradley Company" },
+ { "ABE", "Alcatel Bell" },
+ { "ABO", "D-Link Systems Inc" },
+ { "ABS", "Abaco Systems, Inc." },
+ { "ABT", "Anchor Bay Technologies, Inc." },
+ { "ABV", "Advanced Research Technology" },
+ { "ACA", "Ariel Corporation" },
+ { "ACB", "Aculab Ltd" },
+ { "ACC", "Accton Technology Corporation" },
+ { "ACD", "AWETA BV" },
+ { "ACE", "Actek Engineering Pty Ltd" },
+ { "ACG", "A&R Cambridge Ltd." },
+ { "ACH", "Archtek Telecom Corporation" },
+ { "ACI", "Ancor Communications Inc" },
+ { "ACK", "Acksys" },
+ { "ACL", "Apricot Computers" },
+ { "ACM", "Acroloop Motion Control Systems Inc" },
+ { "ACO", "Allion Computer Inc." },
+ { "ACP", "Aspen Tech Inc" },
+ { "ACR", "Acer Technologies" },
+ { "ACS", "Altos Computer Systems" },
+ { "ACT", "Applied Creative Technology" },
+ { "ACU", "Acculogic" },
+ { "ACV", "ActivCard S.A" },
+ { "ADA", "Addi-Data GmbH" },
+ { "ADB", "Aldebbaron" },
+ { "ADC", "Acnhor Datacomm" },
+ { "ADD", "Advanced Peripheral Devices Inc" },
+ { "ADE", "Arithmos, Inc." },
+ { "ADH", "Aerodata Holdings Ltd" },
+ { "ADI", "ADI Systems Inc" },
+ { "ADK", "Adtek System Science Company Ltd" },
+ { "ADL", "ASTRA Security Products Ltd" },
+ { "ADM", "Ad Lib MultiMedia Inc" },
+ { "ADN", "Analog & Digital Devices Tel. Inc" },
+ { "ADP", "Adaptec Inc" },
+ { "ADR", "Nasa Ames Research Center" },
+ { "ADS", "Analog Devices Inc" },
+ { "ADT", "Adtek" },
+ { "ADV", "Advanced Micro Devices Inc" },
+ { "ADX", "Adax Inc" },
+ { "ADZ", "ADDER TECHNOLOGY LTD" },
+ { "AEC", "Antex Electronics Corporation" },
+ { "AED", "Advanced Electronic Designs, Inc." },
+ { "AEI", "Actiontec Electric Inc" },
+ { "AEJ", "Alpha Electronics Company" },
+ { "AEM", "ASEM S.p.A." },
+ { "AEN", "Avencall" },
+ { "AEP", "Aetas Peripheral International" },
+ { "AET", "Aethra Telecomunicazioni S.r.l." },
+ { "AFA", "Alfa Inc" },
+ { "AGC", "Beijing Aerospace Golden Card Electronic Engineering Co.,Ltd." },
+ { "AGI", "Artish Graphics Inc" },
+ { "AGL", "Argolis" },
+ { "AGM", "Advan Int'l Corporation" },
+ { "AGO", "AlgolTek, Inc." },
+ { "AGT", "Agilent Technologies" },
+ { "AHC", "Advantech Co., Ltd." },
+ { "AHQ", "Astro HQ LLC" },
+ { "AHS", "Beijing AnHeng SecoTech Information Technology Co., Ltd." },
+ { "AIC", "Arnos Insturments & Computer Systems" },
+ { "AIE", "Altmann Industrieelektronik" },
+ { "AII", "Amptron International Inc." },
+ { "AIK", "Dongguan Alllike Electronics Co., Ltd." },
+ { "AIL", "Altos India Ltd" },
+ { "AIM", "AIMS Lab Inc" },
+ { "AIR", "Advanced Integ. Research Inc" },
+ { "AIS", "Alien Internet Services" },
+ { "AIW", "Aiwa Company Ltd" },
+ { "AIX", "ALTINEX, INC." },
+ { "AJA", "AJA Video Systems, Inc." },
+ { "AKB", "Akebia Ltd" },
+ { "AKE", "AKAMI Electric Co.,Ltd" },
+ { "AKI", "AKIA Corporation" },
+ { "AKL", "AMiT Ltd" },
+ { "AKM", "Asahi Kasei Microsystems Company Ltd" },
+ { "AKP", "Atom Komplex Prylad" },
+ { "AKY", "Askey Computer Corporation" },
+ { "ALA", "Alacron Inc" },
+ { "ALC", "Altec Corporation" },
+ { "ALD", "In4S Inc" },
+ { "ALE", "Alenco BV" },
+ { "ALG", "Realtek Semiconductor Corp." },
+ { "ALH", "AL Systems" },
+ { "ALI", "Acer Labs" },
+ { "ALJ", "Altec Lansing" },
+ { "ALK", "Acrolink Inc" },
+ { "ALL", "Alliance Semiconductor Corporation" },
+ { "ALM", "Acutec Ltd." },
+ { "ALN", "Alana Technologies" },
+ { "ALO", "Algolith Inc." },
+ { "ALP", "ALPS ALPINE CO., LTD." },
+ { "ALR", "Advanced Logic" },
+ { "ALS", "Avance Logic Inc" },
+ { "ALT", "Altra" },
+ { "ALV", "AlphaView LCD" },
+ { "ALX", "ALEXON Co.,Ltd." },
+ { "AMA", "Asia Microelectronic Development Inc" },
+ { "AMB", "Ambient Technologies, Inc." },
+ { "AMC", "Attachmate Corporation" },
+ { "AMD", "Amdek Corporation" },
+ { "AMI", "American Megatrends Inc" },
+ { "AML", "Anderson Multimedia Communications (HK) Limited" },
+ { "AMN", "Amimon LTD." },
+ { "AMO", "Amino Technologies PLC and Amino Communications Limited" },
+ { "AMP", "AMP Inc" },
+ { "AMR", "AmTRAN Technology Co., Ltd." },
+ { "AMS", "ARMSTEL, Inc." },
+ { "AMT", "AMT International Industry" },
+ { "AMX", "AMX LLC" },
+ { "ANA", "Anakron" },
+ { "ANC", "Ancot" },
+ { "AND", "Adtran Inc" },
+ { "ANI", "Anigma Inc" },
+ { "ANK", "Anko Electronic Company Ltd" },
+ { "ANL", "Analogix Semiconductor, Inc" },
+ { "ANO", "Anorad Corporation" },
+ { "ANP", "Andrew Network Production" },
+ { "ANR", "ANR Ltd" },
+ { "ANS", "Ansel Communication Company" },
+ { "ANT", "Ace CAD Enterprise Company Ltd" },
+ { "ANV", "Beijing ANTVR Technology Co., Ltd." },
+ { "ANW", "Analog Way SAS" },
+ { "ANX", "Acer Netxus Inc" },
+ { "AOA", "AOpen Inc." },
+ { "AOE", "Advanced Optics Electronics, Inc." },
+ { "AOL", "America OnLine" },
+ { "AOT", "Alcatel" },
+ { "APC", "American Power Conversion" },
+ { "APD", "AppliAdata" },
+ { "APE", "ALPS ALPINE CO., LTD." },
+ { "APG", "Horner Electric Inc" },
+ { "API", "A Plus Info Corporation" },
+ { "APL", "Aplicom Oy" },
+ { "APM", "Applied Memory Tech" },
+ { "APN", "Appian Tech Inc" },
+ { "APP", "Apple Computer Inc" },
+ { "APR", "Aprilia s.p.a." },
+ { "APS", "Autologic Inc" },
+ { "APT", "Audio Processing Technology Ltd" },
+ { "APV", "A+V Link" },
+ { "APX", "AP Designs Ltd" },
+ { "ARC", "Alta Research Corporation" },
+ { "ARD", "AREC Inc." },
+ { "ARE", "ICET S.p.A." },
+ { "ARG", "Argus Electronics Co., LTD" },
+ { "ARI", "Argosy Research Inc" },
+ { "ARK", "Ark Logic Inc" },
+ { "ARL", "Arlotto Comnet Inc" },
+ { "ARM", "Arima" },
+ { "ARO", "Poso International B.V." },
+ { "ARR", "ARRIS Group, Inc." },
+ { "ARS", "Arescom Inc" },
+ { "ART", "Corion Industrial Corporation" },
+ { "ASC", "Ascom Strategic Technology Unit" },
+ { "ASD", "USC Information Sciences Institute" },
+ { "ASE", "AseV Display Labs" },
+ { "ASH", "Ashton Bentley Concepts" },
+ { "ASI", "Ahead Systems" },
+ { "ASK", "Ask A/S" },
+ { "ASL", "AccuScene Corporation Ltd" },
+ { "ASM", "ASEM S.p.A." },
+ { "ASN", "Asante Tech Inc" },
+ { "ASP", "ASP Microelectronics Ltd" },
+ { "AST", "AST Research Inc" },
+ { "ASU", "Asuscom Network Inc" },
+ { "ASX", "AudioScience" },
+ { "ASY", "Rockwell Collins / Airshow Systems" },
+ { "ATA", "Allied Telesyn International (Asia) Pte Ltd" },
+ { "ATC", "Ably-Tech Corporation" },
+ { "ATD", "Alpha Telecom Inc" },
+ { "ATE", "Innovate Ltd" },
+ { "ATH", "Athena Informatica S.R.L." },
+ { "ATI", "Allied Telesis KK" },
+ { "ATJ", "ArchiTek Corporation" },
+ { "ATK", "Allied Telesyn Int'l" },
+ { "ATL", "Arcus Technology Ltd" },
+ { "ATM", "ATM Ltd" },
+ { "ATN", "Athena Smartcard Solutions Ltd." },
+ { "ATO", "ASTRO DESIGN, INC." },
+ { "ATP", "Alpha-Top Corporation" },
+ { "ATT", "AT&T" },
+ { "ATV", "Office Depot, Inc." },
+ { "ATX", "Athenix Corporation" },
+ { "AUG", "August Home, Inc." },
+ { "AUI", "ALPS ALPINE CO., LTD." },
+ { "AUO", "AU Optronics" },
+ { "AUR", "Aureal Semiconductor" },
+ { "AUS", "ASUSTek COMPUTER INC" },
+ { "AUT", "Autotime Corporation" },
+ { "AUV", "Auvidea GmbH" },
+ { "AVA", "Avaya Communication" },
+ { "AVC", "Auravision Corporation" },
+ { "AVD", "Avid Electronics Corporation" },
+ { "AVE", "Add Value Enterpises (Asia) Pte Ltd" },
+ { "AVG", "Avegant Corporation" },
+ { "AVI", "Nippon Avionics Co.,Ltd" },
+ { "AVJ", "Atelier Vision Corporation" },
+ { "AVL", "Avalue Technology Inc." },
+ { "AVM", "AVM GmbH" },
+ { "AVN", "Advance Computer Corporation" },
+ { "AVO", "Avocent Corporation" },
+ { "AVR", "AVer Information Inc." },
+ { "AVS", "Avatron Software Inc." },
+ { "AVT", "Avtek (Electronics) Pty Ltd" },
+ { "AVV", "SBS Technologies (Canada), Inc. (was Avvida Systems, Inc.)" },
+ { "AVX", "A/Vaux Electronics" },
+ { "AWC", "Access Works Comm Inc" },
+ { "AWL", "Aironet Wireless Communications, Inc" },
+ { "AWS", "Wave Systems" },
+ { "AXB", "Adrienne Electronics Corporation" },
+ { "AXC", "AXIOMTEK CO., LTD." },
+ { "AXE", "Axell Corporation" },
+ { "AXI", "American Magnetics" },
+ { "AXL", "Axel" },
+ { "AXO", "Axonic Labs LLC" },
+ { "AXP", "American Express" },
+ { "AXT", "Axtend Technologies Inc" },
+ { "AXX", "Axxon Computer Corporation" },
+ { "AXY", "AXYZ Automation Services, Inc" },
+ { "AYD", "Aydin Displays" },
+ { "AYR", "Airlib, Inc" },
+ { "AZH", "Shenzhen three Connaught Information Technology Co., Ltd. (3nod Group)" },
+ { "AZM", "AZ Middelheim - Radiotherapy" },
+ { "AZT", "Aztech Systems Ltd" },
+ { "BAC", "Biometric Access Corporation" },
+ { "BAN", "Banyan" },
+ { "BBB", "an-najah university" },
+ { "BBH", "B&Bh" },
+ { "BBL", "Brain Boxes Limited" },
+ { "BBV", "BlueBox Video Limited" },
+ { "BBX", "Black Box Corporation" },
+ { "BCC", "Beaver Computer Corporaton" },
+ { "BCD", "Barco GmbH" },
+ { "BCI", "Broadata Communications Inc." },
+ { "BCM", "Broadcom" },
+ { "BCQ", "Deutsche Telekom Berkom GmbH" },
+ { "BCS", "Booria CAD/CAM systems" },
+ { "BDO", "Brahler ICS" },
+ { "BDR", "Blonder Tongue Labs, Inc." },
+ { "BDS", "Barco Display Systems" },
+ { "BEC", "Beckhoff Automation" },
+ { "BEI", "Beckworth Enterprises Inc" },
+ { "BEK", "Beko Elektronik A.S." },
+ { "BEL", "Beltronic Industrieelektronik GmbH" },
+ { "BEO", "Baug & Olufsen" },
+ { "BFE", "B.F. Engineering Corporation" },
+ { "BGB", "Barco Graphics N.V" },
+ { "BGT", "Budzetron Inc" },
+ { "BHZ", "BitHeadz, Inc." },
+ { "BIA", "Biamp Systems Corporation" },
+ { "BIC", "Big Island Communications" },
+ { "BII", "Boeckeler Instruments Inc" },
+ { "BIL", "Billion Electric Company Ltd" },
+ { "BIO", "BioLink Technologies International, Inc." },
+ { "BIT", "Bit 3 Computer" },
+ { "BLD", "BILD INNOVATIVE TECHNOLOGY LLC" },
+ { "BLI", "Busicom" },
+ { "BLN", "BioLink Technologies" },
+ { "BLP", "Bloomberg L.P." },
+ { "BMD", "Blackmagic Design" },
+ { "BMI", "Benson Medical Instruments Company" },
+ { "BML", "BIOMED Lab" },
+ { "BMS", "BIOMEDISYS" },
+ { "BNE", "Bull AB" },
+ { "BNK", "Banksia Tech Pty Ltd" },
+ { "BNO", "Bang & Olufsen" },
+ { "BNS", "Boulder Nonlinear Systems" },
+ { "BOB", "Rainy Orchard" },
+ { "BOE", "BOE" },
+ { "BOI", "NINGBO BOIGLE DIGITAL TECHNOLOGY CO.,LTD" },
+ { "BOS", "BOS" },
+ { "BPD", "Micro Solutions, Inc." },
+ { "BPS", "Barco, N.V." },
+ { "BPU", "Best Power" },
+ { "BRA", "Braemac Pty Ltd" },
+ { "BRC", "BARC" },
+ { "BRG", "Bridge Information Co., Ltd" },
+ { "BRI", "Boca Research Inc" },
+ { "BRM", "Braemar Inc" },
+ { "BRO", "BROTHER INDUSTRIES,LTD." },
+ { "BSE", "Bose Corporation" },
+ { "BSG", "Robert Bosch GmbH" },
+ { "BSL", "Biomedical Systems Laboratory" },
+ { "BSN", "BRIGHTSIGN, LLC" },
+ { "BST", "BodySound Technologies, Inc." },
+ { "BTC", "Bit 3 Computer" },
+ { "BTE", "Brilliant Technology" },
+ { "BTF", "Bitfield Oy" },
+ { "BTI", "BusTech Inc" },
+ { "BTO", "BioTao Ltd" },
+ { "BUF", "Yasuhiko Shirai Melco Inc" },
+ { "BUG", "B.U.G., Inc." },
+ { "BUJ", "ATI Tech Inc" },
+ { "BUL", "Bull" },
+ { "BUR", "Bernecker & Rainer Ind-Eletronik GmbH" },
+ { "BUS", "BusTek" },
+ { "BUT", "21ST CENTURY ENTERTAINMENT" },
+ { "BWK", "Bitworks Inc." },
+ { "BXE", "Buxco Electronics" },
+ { "BYD", "byd:sign corporation" },
+ { "CAA", "Castles Automation Co., Ltd" },
+ { "CAC", "CA & F Elettronica" },
+ { "CAG", "CalComp" },
+ { "CAI", "Canon Inc." },
+ { "CAL", "Acon" },
+ { "CAM", "Cambridge Audio" },
+ { "CAN", "Canopus Company Ltd" },
+ { "CAR", "Cardinal Company Ltd" },
+ { "CAS", "CASIO COMPUTER CO.,LTD" },
+ { "CAT", "Consultancy in Advanced Technology" },
+ { "CAV", "Cavium Networks, Inc" },
+ { "CBI", "ComputerBoards Inc" },
+ { "CBR", "Cebra Tech A/S" },
+ { "CBT", "Cabletime Ltd" },
+ { "CBX", "Cybex Computer Products Corporation" },
+ { "CCC", "C-Cube Microsystems" },
+ { "CCI", "Cache" },
+ { "CCJ", "CONTEC CO.,LTD." },
+ { "CCL", "CCL/ITRI" },
+ { "CCP", "Capetronic USA Inc" },
+ { "CDC", "Core Dynamics Corporation" },
+ { "CDD", "Convergent Data Devices" },
+ { "CDE", "Colin.de" },
+ { "CDG", "Christie Digital Systems Inc" },
+ { "CDI", "Concept Development Inc" },
+ { "CDK", "Cray Communications" },
+ { "CDN", "Codenoll Technical Corporation" },
+ { "CDP", "CalComp" },
+ { "CDS", "Computer Diagnostic Systems" },
+ { "CDT", "IBM Corporation" },
+ { "CDV", "Convergent Design Inc." },
+ { "CEA", "Consumer Electronics Association" },
+ { "CEC", "Chicony Electronics Company Ltd" },
+ { "CED", "Cambridge Electronic Design Ltd" },
+ { "CEF", "Cefar Digital Vision" },
+ { "CEI", "Crestron Electronics, Inc." },
+ { "CEM", "MEC Electronics GmbH" },
+ { "CEN", "Centurion Technologies P/L" },
+ { "CEP", "C-DAC" },
+ { "CER", "Ceronix" },
+ { "CET", "TEC CORPORATION" },
+ { "CFG", "Atlantis" },
+ { "CFR", "Meta View, Inc." },
+ { "CGA", "Chunghwa Picture Tubes, LTD" },
+ { "CGS", "Chyron Corp" },
+ { "CGT", "congatec AG" },
+ { "CHA", "Chase Research PLC" },
+ { "CHD", "ChangHong Electric Co.,Ltd" },
+ { "CHE", "Acer Inc" },
+ { "CHG", "Sichuan Changhong Electric CO, LTD." },
+ { "CHI", "Chrontel Inc" },
+ { "CHL", "Chloride-R&D" },
+ { "CHM", "CHIC TECHNOLOGY CORP." },
+ { "CHO", "Sichuang Changhong Corporation" },
+ { "CHP", "CH Products" },
+ { "CHR", "christmann informationstechnik + medien GmbH & Co. KG" },
+ { "CHS", "Agentur Chairos" },
+ { "CHT", "Chunghwa Picture Tubes,LTD." },
+ { "CHY", "Cherry GmbH" },
+ { "CIC", "Comm. Intelligence Corporation" },
+ { "CIE", "Convergent Engineering, Inc." },
+ { "CII", "Cromack Industries Inc" },
+ { "CIL", "Citicom Infotech Private Limited" },
+ { "CIN", "Citron GmbH" },
+ { "CIP", "Ciprico Inc" },
+ { "CIR", "Cirrus Logic Inc" },
+ { "CIS", "Cisco Systems Inc" },
+ { "CIT", "Citifax Limited" },
+ { "CKC", "The Concept Keyboard Company Ltd" },
+ { "CKJ", "Carina System Co., Ltd." },
+ { "CLA", "Clarion Company Ltd" },
+ { "CLD", "COMMAT L.t.d." },
+ { "CLE", "Classe Audio" },
+ { "CLG", "CoreLogic" },
+ { "CLI", "Cirrus Logic Inc" },
+ { "CLM", "CrystaLake Multimedia" },
+ { "CLO", "Clone Computers" },
+ { "CLR", "Clover Electronics" },
+ { "CLT", "automated computer control systems" },
+ { "CLV", "Clevo Company" },
+ { "CLX", "CardLogix" },
+ { "CMC", "CMC Ltd" },
+ { "CMD", "Colorado MicroDisplay, Inc." },
+ { "CMG", "Chenming Mold Ind. Corp." },
+ { "CMI", "C-Media Electronics" },
+ { "CMK", "Comark LLC" },
+ { "CMM", "Comtime GmbH" },
+ { "CMN", "Chimei Innolux Corporation" },
+ { "CMO", "Chi Mei Optoelectronics corp." },
+ { "CMR", "Cambridge Research Systems Ltd" },
+ { "CMS", "CompuMaster Srl" },
+ { "CMX", "Comex Electronics AB" },
+ { "CNB", "American Power Conversion" },
+ { "CNC", "Alvedon Computers Ltd" },
+ { "CND", "Micro-Star Int'l Co., Ltd." },
+ { "CNE", "Cine-tal" },
+ { "CNI", "Connect Int'l A/S" },
+ { "CNN", "Canon Inc" },
+ { "CNT", "COINT Multimedia Systems" },
+ { "COB", "COBY Electronics Co., Ltd" },
+ { "COD", "CODAN Pty. Ltd." },
+ { "COI", "Codec Inc." },
+ { "COL", "Rockwell Collins, Inc." },
+ { "COM", "Comtrol Corporation" },
+ { "CON", "Contec Company Ltd" },
+ { "COO", "coolux GmbH" },
+ { "COR", "Corollary Inc" },
+ { "COS", "CoStar Corporation" },
+ { "COT", "Core Technology Inc" },
+ { "COW", "Polycow Productions" },
+ { "COX", "Comrex" },
+ { "CPC", "Ciprico Inc" },
+ { "CPD", "CompuAdd" },
+ { "CPI", "Computer Peripherals Inc" },
+ { "CPL", "Compal Electronics Inc" },
+ { "CPM", "Capella Microsystems Inc." },
+ { "CPP", "Compound Photonics" },
+ { "CPQ", "Compaq Computer Company" },
+ { "CPT", "cPATH" },
+ { "CPX", "Powermatic Data Systems" },
+ { "CRA", "CRALTECH ELECTRONICA, S.L." },
+ { "CRC", "CONRAC GmbH" },
+ { "CRD", "Cardinal Technical Inc" },
+ { "CRE", "Creative Labs Inc" },
+ { "CRH", "Contemporary Research Corp." },
+ { "CRI", "Crio Inc." },
+ { "CRL", "Creative Logic" },
+ { "CRM", "CORSAIR MEMORY Inc." },
+ { "CRN", "Cornerstone Imaging" },
+ { "CRO", "Extraordinary Technologies PTY Limited" },
+ { "CRQ", "Cirque Corporation" },
+ { "CRS", "Crescendo Communication Inc" },
+ { "CRV", "Cerevo Inc." },
+ { "CRW", "Cammegh Limited" },
+ { "CRX", "Cyrix Corporation" },
+ { "CSB", "Transtex SA" },
+ { "CSC", "Crystal Semiconductor" },
+ { "CSD", "Cresta Systems Inc" },
+ { "CSE", "Concept Solutions & Engineering" },
+ { "CSI", "Cabletron System Inc" },
+ { "CSL", "Cloudium Systems Ltd." },
+ { "CSM", "Cosmic Engineering Inc." },
+ { "CSO", "California Institute of Technology" },
+ { "CSS", "CSS Laboratories" },
+ { "CST", "CSTI Inc" },
+ { "CTA", "CoSystems Inc" },
+ { "CTC", "CTC Communication Development Company Ltd" },
+ { "CTE", "Chunghwa Telecom Co., Ltd." },
+ { "CTL", "Creative Technology Ltd" },
+ { "CTM", "Computerm Corporation" },
+ { "CTN", "Computone Products" },
+ { "CTP", "Computer Technology Corporation" },
+ { "CTR", "Control4 Corporation" },
+ { "CTS", "Comtec Systems Co., Ltd." },
+ { "CTX", "Creatix Polymedia GmbH" },
+ { "CUB", "Cubix Corporation" },
+ { "CUK", "Calibre UK Ltd" },
+ { "CVA", "Covia Inc." },
+ { "CVI", "Colorado Video, Inc." },
+ { "CVP", "Chromatec Video Products Ltd" },
+ { "CVS", "Clarity Visual Systems" },
+ { "CWC", "Curtiss-Wright Controls, Inc." },
+ { "CWR", "Connectware Inc" },
+ { "CXT", "Conexant Systems" },
+ { "CYB", "CyberVision" },
+ { "CYC", "Cylink Corporation" },
+ { "CYD", "Cyclades Corporation" },
+ { "CYL", "Cyberlabs" },
+ { "CYP", "CYPRESS SEMICONDUCTOR CORPORATION" },
+ { "CYT", "Cytechinfo Inc" },
+ { "CYV", "Cyviz AS" },
+ { "CYW", "Cyberware" },
+ { "CYX", "Cyrix Corporation" },
+ { "CZC", "Shenzhen ChuangZhiCheng Technology Co., Ltd." },
+ { "CZE", "Carl Zeiss AG" },
+ { "DAC", "Digital Acoustics Corporation" },
+ { "DAE", "Digatron Industrie Elektronik GmbH" },
+ { "DAI", "DAIS SET Ltd." },
+ { "DAK", "Daktronics" },
+ { "DAL", "Digital Audio Labs Inc" },
+ { "DAN", "Danelec Marine A/S" },
+ { "DAS", "DAVIS AS" },
+ { "DAT", "Datel Inc" },
+ { "DAU", "Daou Tech Inc" },
+ { "DAV", "Davicom Semiconductor Inc" },
+ { "DAW", "DA2 Technologies Inc" },
+ { "DAX", "Data Apex Ltd" },
+ { "DBD", "Diebold Inc." },
+ { "DBI", "DigiBoard Inc" },
+ { "DBK", "Databook Inc" },
+ { "DBL", "Doble Engineering Company" },
+ { "DBN", "DB Networks Inc" },
+ { "DCA", "Digital Communications Association" },
+ { "DCC", "Dale Computer Corporation" },
+ { "DCD", "Datacast LLC" },
+ { "DCE", "dSPACE GmbH" },
+ { "DCI", "Concepts Inc" },
+ { "DCL", "Dynamic Controls Ltd" },
+ { "DCM", "DCM Data Products" },
+ { "DCO", "Dialogue Technology Corporation" },
+ { "DCR", "Decros Ltd" },
+ { "DCS", "Diamond Computer Systems Inc" },
+ { "DCT", "Dancall Telecom A/S" },
+ { "DCV", "Datatronics Technology Inc" },
+ { "DDA", "DA2 Technologies Corporation" },
+ { "DDD", "Danka Data Devices" },
+ { "DDE", "Datasat Digital Entertainment" },
+ { "DDI", "Data Display AG" },
+ { "DDS", "Barco, N.V." },
+ { "DDT", "Datadesk Technologies Inc" },
+ { "DDV", "Delta Information Systems, Inc" },
+ { "DEC", "Digital Equipment Corporation" },
+ { "DEI", "Deico Electronics" },
+ { "DEL", "Dell Inc." },
+ { "DEN", "Densitron Computers Ltd" },
+ { "DEX", "idex displays" },
+ { "DFI", "DFI" },
+ { "DFK", "SharkTec A/S" },
+ { "DFT", "DEI Holdings dba Definitive Technology" },
+ { "DGA", "Digiital Arts Inc" },
+ { "DGC", "Data General Corporation" },
+ { "DGI", "DIGI International" },
+ { "DGK", "DugoTech Co., LTD" },
+ { "DGP", "Digicorp European sales S.A." },
+ { "DGS", "Diagsoft Inc" },
+ { "DGT", "Dearborn Group Technology" },
+ { "DHD", "Dension Audio Systems" },
+ { "DHP", "DH Print" },
+ { "DHQ", "Quadram" },
+ { "DHT", "Projectavision Inc" },
+ { "DIA", "Diadem" },
+ { "DIG", "Digicom S.p.A." },
+ { "DII", "Dataq Instruments Inc" },
+ { "DIM", "dPict Imaging, Inc." },
+ { "DIN", "Daintelecom Co., Ltd" },
+ { "DIS", "Diseda S.A." },
+ { "DIT", "Dragon Information Technology" },
+ { "DJE", "Capstone Visual Product Development" },
+ { "DJP", "Maygay Machines, Ltd" },
+ { "DKY", "Datakey Inc" },
+ { "DLB", "Dolby Laboratories Inc." },
+ { "DLC", "Diamond Lane Comm. Corporation" },
+ { "DLG", "Digital-Logic GmbH" },
+ { "DLK", "D-Link Systems Inc" },
+ { "DLL", "Dell Inc" },
+ { "DLO", "Shenzhen Dlodlo Technologies Co., Ltd." },
+ { "DLT", "Digitelec Informatique Park Cadera" },
+ { "DMB", "Digicom Systems Inc" },
+ { "DMC", "Dune Microsystems Corporation" },
+ { "DMM", "Dimond Multimedia Systems Inc" },
+ { "DMN", "Dimension Engineering LLC" },
+ { "DMO", "Data Modul AG" },
+ { "DMP", "D&M Holdings Inc, Professional Business Company" },
+ { "DMS", "DOME imaging systems" },
+ { "DMT", "Distributed Management Task Force, Inc. (DMTF)" },
+ { "DMV", "NDS Ltd" },
+ { "DNA", "DNA Enterprises, Inc." },
+ { "DNG", "Apache Micro Peripherals Inc" },
+ { "DNI", "Deterministic Networks Inc." },
+ { "DNT", "Dr. Neuhous Telekommunikation GmbH" },
+ { "DNV", "DiCon" },
+ { "DOL", "Dolman Technologies Group Inc" },
+ { "DOM", "Dome Imaging Systems" },
+ { "DON", "DENON, Ltd." },
+ { "DOT", "Dotronic Mikroelektronik GmbH" },
+ { "DPA", "DigiTalk Pro AV" },
+ { "DPC", "Delta Electronics Inc" },
+ { "DPH", "Delphi Automotive LLP" },
+ { "DPI", "DocuPoint" },
+ { "DPL", "Digital Projection Limited" },
+ { "DPM", "ADPM Synthesis sas" },
+ { "DPN", "Shanghai Lexiang Technology Limited" },
+ { "DPS", "Digital Processing Systems" },
+ { "DPT", "DPT" },
+ { "DPX", "DpiX, Inc." },
+ { "DQB", "Datacube Inc" },
+ { "DRB", "Dr. Bott KG" },
+ { "DRC", "Data Ray Corp." },
+ { "DRD", "DIGITAL REFLECTION INC." },
+ { "DRI", "Data Race Inc" },
+ { "DRS", "DRS Defense Solutions, LLC" },
+ { "DSA", "Display Solution AG" },
+ { "DSD", "DS Multimedia Pte Ltd" },
+ { "DSG", "Disguise Technologies" },
+ { "DSI", "Digitan Systems Inc" },
+ { "DSJ", "VR Technology Holdings Limited" },
+ { "DSM", "DSM Digital Services GmbH" },
+ { "DSP", "Domain Technology Inc" },
+ { "DTA", "DELTATEC" },
+ { "DTC", "DTC Tech Corporation" },
+ { "DTE", "Dimension Technologies, Inc." },
+ { "DTI", "Diversified Technology, Inc." },
+ { "DTK", "Dynax Electronics (HK) Ltd" },
+ { "DTL", "e-Net Inc" },
+ { "DTN", "Datang Telephone Co" },
+ { "DTO", "Deutsche Thomson OHG" },
+ { "DTT", "Design & Test Technology, Inc." },
+ { "DTX", "Data Translation" },
+ { "DUA", "Dosch & Amand GmbH & Company KG" },
+ { "DUN", "NCR Corporation" },
+ { "DVD", "Dictaphone Corporation" },
+ { "DVL", "Devolo AG" },
+ { "DVS", "Digital Video System" },
+ { "DVT", "Data Video" },
+ { "DWE", "Daewoo Electronics Company Ltd" },
+ { "DXC", "Digipronix Control Systems" },
+ { "DXD", "DECIMATOR DESIGN PTY LTD" },
+ { "DXL", "Dextera Labs Inc" },
+ { "DXP", "Data Expert Corporation" },
+ { "DXS", "Signet" },
+ { "DYC", "Dycam Inc" },
+ { "DYM", "Dymo-CoStar Corporation" },
+ { "DYN", "Askey Computer Corporation" },
+ { "DYX", "Dynax Electronics (HK) Ltd" },
+ { "EAG", "ELTEC Elektronik AG" },
+ { "EAS", "Evans and Sutherland Computer" },
+ { "EBH", "Data Price Informatica" },
+ { "EBS", "EBS Euchner Büro- und Schulsysteme GmbH" },
+ { "EBT", "HUALONG TECHNOLOGY CO., LTD" },
+ { "ECA", "Electro Cam Corp." },
+ { "ECC", "ESSential Comm. Corporation" },
+ { "ECH", "EchoStar Corporation" },
+ { "ECI", "Enciris Technologies" },
+ { "ECK", "Eugene Chukhlomin Sole Proprietorship, d.b.a." },
+ { "ECL", "Excel Company Ltd" },
+ { "ECM", "E-Cmos Tech Corporation" },
+ { "ECO", "Echo Speech Corporation" },
+ { "ECP", "Elecom Company Ltd" },
+ { "ECS", "Elitegroup Computer Systems Company Ltd" },
+ { "ECT", "Enciris Technologies" },
+ { "EDC", "e.Digital Corporation" },
+ { "EDG", "Electronic-Design GmbH" },
+ { "EDI", "Edimax Tech. Company Ltd" },
+ { "EDM", "EDMI" },
+ { "EDT", "Emerging Display Technologies Corp" },
+ { "EEE", "ET&T Technology Company Ltd" },
+ { "EEH", "EEH Datalink GmbH" },
+ { "EEP", "E.E.P.D. GmbH" },
+ { "EES", "EE Solutions, Inc." },
+ { "EGA", "Elgato Systems LLC" },
+ { "EGD", "EIZO GmbH Display Technologies" },
+ { "EGL", "Eagle Technology" },
+ { "EGN", "Egenera, Inc." },
+ { "EGO", "Ergo Electronics" },
+ { "EHJ", "Epson Research" },
+ { "EHN", "Enhansoft" },
+ { "EIC", "Eicon Technology Corporation" },
+ { "EIN", "Elegant Invention" },
+ { "EKA", "MagTek Inc." },
+ { "EKC", "Eastman Kodak Company" },
+ { "EKS", "EKSEN YAZILIM" },
+ { "ELA", "ELAD srl" },
+ { "ELC", "Electro Scientific Ind" },
+ { "ELD", "Express Luck, Inc." },
+ { "ELE", "Elecom Company Ltd" },
+ { "ELG", "Elmeg GmbH Kommunikationstechnik" },
+ { "ELI", "Edsun Laboratories" },
+ { "ELL", "Electrosonic Ltd" },
+ { "ELM", "Elmic Systems Inc" },
+ { "ELO", "Elo TouchSystems Inc" },
+ { "ELS", "ELSA GmbH" },
+ { "ELT", "Element Labs, Inc." },
+ { "ELU", "Express Industrial, Ltd." },
+ { "ELX", "Elonex PLC" },
+ { "EMB", "Embedded computing inc ltd" },
+ { "EMC", "eMicro Corporation" },
+ { "EMD", "Embrionix Design Inc." },
+ { "EME", "EMiNE TECHNOLOGY COMPANY, LTD." },
+ { "EMG", "EMG Consultants Inc" },
+ { "EMI", "Ex Machina Inc" },
+ { "EMK", "Emcore Corporation" },
+ { "EMO", "ELMO COMPANY, LIMITED" },
+ { "EMU", "Emulex Corporation" },
+ { "ENC", "Eizo Nanao Corporation" },
+ { "END", "ENIDAN Technologies Ltd" },
+ { "ENE", "ENE Technology Inc." },
+ { "ENI", "Efficient Networks" },
+ { "ENS", "Ensoniq Corporation" },
+ { "ENT", "Enterprise Comm. & Computing Inc" },
+ { "EON", "Eon Instrumentation, Inc." },
+ { "EPC", "Empac" },
+ { "EPH", "Epiphan Systems Inc." },
+ { "EPI", "Envision Peripherals, Inc" },
+ { "EPN", "EPiCON Inc." },
+ { "EPS", "KEPS" },
+ { "EQP", "Equipe Electronics Ltd." },
+ { "EQX", "Equinox Systems Inc" },
+ { "ERG", "Ergo System" },
+ { "ERI", "Ericsson Mobile Communications AB" },
+ { "ERN", "Ericsson, Inc." },
+ { "ERP", "Euraplan GmbH" },
+ { "ERS", "Eizo Rugged Solutions" },
+ { "ERT", "Escort Insturments Corporation" },
+ { "ESA", "Elbit Systems of America" },
+ { "ESB", "Esterline Belgium BVBA" },
+ { "ESC", "Eden Sistemas de Computacao S/A" },
+ { "ESD", "Ensemble Designs, Inc" },
+ { "ESG", "ELCON Systemtechnik GmbH" },
+ { "ESI", "Extended Systems, Inc." },
+ { "ESK", "ES&S" },
+ { "ESL", "Esterline Technologies" },
+ { "ESN", "eSATURNUS" },
+ { "ESS", "ESS Technology Inc" },
+ { "EST", "Embedded Solution Technology" },
+ { "ESY", "E-Systems Inc" },
+ { "ETC", "Everton Technology Company Ltd" },
+ { "ETD", "ELAN MICROELECTRONICS CORPORATION" },
+ { "ETH", "Etherboot Project" },
+ { "ETI", "Eclipse Tech Inc" },
+ { "ETK", "eTEK Labs Inc." },
+ { "ETL", "Evertz Microsystems Ltd." },
+ { "ETS", "Electronic Trade Solutions Ltd" },
+ { "ETT", "E-Tech Inc" },
+ { "EUT", "Ericsson Mobile Networks B.V." },
+ { "EVE", "Advanced Micro Peripherals Ltd" },
+ { "EVI", "eviateg GmbH" },
+ { "EVX", "Everex" },
+ { "EXA", "Exabyte" },
+ { "EXC", "Excession Audio" },
+ { "EXI", "Exide Electronics" },
+ { "EXN", "RGB Systems, Inc. dba Extron Electronics" },
+ { "EXP", "Data Export Corporation" },
+ { "EXR", "Explorer Inc." },
+ { "EXT", "Exatech Computadores & Servicos Ltda" },
+ { "EXX", "Exxact GmbH" },
+ { "EXY", "Exterity Ltd" },
+ { "EYE", "eyevis GmbH" },
+ { "EYF", "eyefactive Gmbh" },
+ { "EZE", "EzE Technologies" },
+ { "EZP", "Storm Technology" },
+ { "FAN", "Fantalooks Co., Ltd." },
+ { "FAR", "Farallon Computing" },
+ { "FBI", "Interface Corporation" },
+ { "FCB", "Furukawa Electric Company Ltd" },
+ { "FCG", "First International Computer Ltd" },
+ { "FCS", "Focus Enhancements, Inc." },
+ { "FDC", "Future Domain" },
+ { "FDD", "Forth Dimension Displays Ltd" },
+ { "FDI", "Future Designs, Inc." },
+ { "FDT", "Fujitsu Display Technologies Corp." },
+ { "FDX", "Findex, Inc." },
+ { "FEC", "FURUNO ELECTRIC CO., LTD." },
+ { "FEL", "Fellowes & Questec" },
+ { "FEN", "Fen Systems Ltd." },
+ { "FER", "Ferranti Int'L" },
+ { "FFC", "FUJIFILM Corporation" },
+ { "FFI", "Fairfield Industries" },
+ { "FGD", "Lisa Draexlmaier GmbH" },
+ { "FGL", "Fujitsu General Limited." },
+ { "FHL", "FHLP" },
+ { "FIC", "Formosa Industrial Computing Inc" },
+ { "FIL", "Forefront Int'l Ltd" },
+ { "FIN", "Finecom Co., Ltd." },
+ { "FIR", "Chaplet Systems Inc" },
+ { "FIS", "FLY-IT Simulators" },
+ { "FIT", "Feature Integration Technology Inc." },
+ { "FJC", "Fujitsu Takamisawa Component Limited" },
+ { "FJS", "Fujitsu Spain" },
+ { "FJT", "F.J. Tieman BV" },
+ { "FLE", "ADTI Media, Inc" },
+ { "FLI", "Faroudja Laboratories" },
+ { "FLY", "Butterfly Communications" },
+ { "FMA", "Fast Multimedia AG" },
+ { "FMC", "Ford Microelectronics Inc" },
+ { "FMI", "Fellowes, Inc." },
+ { "FML", "Fujitsu Microelect Ltd" },
+ { "FMZ", "Formoza-Altair" },
+ { "FNC", "Fanuc LTD" },
+ { "FNI", "Funai Electric Co., Ltd." },
+ { "FOA", "FOR-A Company Limited" },
+ { "FOK", "Fokus Technologies GmbH" },
+ { "FOS", "Foss Tecator" },
+ { "FOV", "FOVE INC" },
+ { "FOX", "HON HAI PRECISON IND.CO.,LTD." },
+ { "FPC", "Fingerprint Cards AB" },
+ { "FPE", "Fujitsu Peripherals Ltd" },
+ { "FPS", "Deltec Corporation" },
+ { "FPX", "Cirel Systemes" },
+ { "FRC", "Force Computers" },
+ { "FRD", "Freedom Scientific BLV" },
+ { "FRE", "Forvus Research Inc" },
+ { "FRI", "Fibernet Research Inc" },
+ { "FRO", "FARO Technologies" },
+ { "FRS", "South Mountain Technologies, LTD" },
+ { "FSC", "Future Systems Consulting KK" },
+ { "FSI", "Fore Systems Inc" },
+ { "FST", "Modesto PC Inc" },
+ { "FTC", "Futuretouch Corporation" },
+ { "FTE", "Frontline Test Equipment Inc." },
+ { "FTG", "FTG Data Systems" },
+ { "FTI", "FastPoint Technologies, Inc." },
+ { "FTL", "FUJITSU TEN LIMITED" },
+ { "FTN", "Fountain Technologies Inc" },
+ { "FTR", "Mediasonic" },
+ { "FTS", "FocalTech Systems Co., Ltd." },
+ { "FTW", "MindTribe Product Engineering, Inc." },
+ { "FUJ", "Fujitsu Ltd" },
+ { "FUN", "sisel muhendislik" },
+ { "FUS", "Fujitsu Siemens Computers GmbH" },
+ { "FVC", "First Virtual Corporation" },
+ { "FVX", "C-C-C Group Plc" },
+ { "FWA", "Attero Tech, LLC" },
+ { "FWR", "Flat Connections Inc" },
+ { "FXX", "Fuji Xerox" },
+ { "FZC", "Founder Group Shenzhen Co." },
+ { "FZI", "FZI Forschungszentrum Informatik" },
+ { "GAC", "GreenArrays, Inc." },
+ { "GAG", "Gage Applied Sciences Inc" },
+ { "GAL", "Galil Motion Control" },
+ { "GAU", "Gaudi Co., Ltd." },
+ { "GBT", "GIGA-BYTE TECHNOLOGY CO., LTD." },
+ { "GCC", "GCC Technologies Inc" },
+ { "GCI", "Gateway Comm. Inc" },
+ { "GCS", "Grey Cell Systems Ltd" },
+ { "GDC", "General Datacom" },
+ { "GDI", "G. Diehl ISDN GmbH" },
+ { "GDS", "GDS" },
+ { "GDT", "Vortex Computersysteme GmbH" },
+ { "GEC", "Gechic Corporation" },
+ { "GED", "General Dynamics C4 Systems" },
+ { "GEF", "GE Fanuc Embedded Systems" },
+ { "GEH", "Abaco Systems, Inc." },
+ { "GEM", "Gem Plus" },
+ { "GEN", "Genesys ATE Inc" },
+ { "GEO", "GEO Sense" },
+ { "GER", "GERMANEERS GmbH" },
+ { "GES", "GES Singapore Pte Ltd" },
+ { "GET", "Getac Technology Corporation" },
+ { "GFM", "GFMesstechnik GmbH" },
+ { "GFN", "Gefen Inc." },
+ { "GGL", "Google Inc." },
+ { "GGT", "G2TOUCH KOREA" },
+ { "GIC", "General Inst. Corporation" },
+ { "GIM", "Guillemont International" },
+ { "GIP", "GI Provision Ltd" },
+ { "GIS", "AT&T Global Info Solutions" },
+ { "GJN", "Grand Junction Networks" },
+ { "GLD", "Goldmund - Digital Audio SA" },
+ { "GLE", "AD electronics" },
+ { "GLM", "Genesys Logic" },
+ { "GLS", "Gadget Labs LLC" },
+ { "GMK", "GMK Electronic Design GmbH" },
+ { "GML", "General Information Systems" },
+ { "GMM", "GMM Research Inc" },
+ { "GMN", "GEMINI 2000 Ltd" },
+ { "GMX", "GMX Inc" },
+ { "GND", "Gennum Corporation" },
+ { "GNN", "GN Nettest Inc" },
+ { "GNZ", "Gunze Ltd" },
+ { "GOE", "GOEPEL electronic GmbH" },
+ { "GPR", "GoPro, Inc." },
+ { "GRA", "Graphica Computer" },
+ { "GRE", "GOLD RAIN ENTERPRISES CORP." },
+ { "GRH", "Granch Ltd" },
+ { "GRM", "Garmin International" },
+ { "GRV", "Advanced Gravis" },
+ { "GRY", "Robert Gray Company" },
+ { "GSB", "NIPPONDENCHI CO,.LTD" },
+ { "GSC", "General Standards Corporation" },
+ { "GSM", "LG Electronics" },
+ { "GSN", "Grandstream Networks, Inc." },
+ { "GST", "Graphic SystemTechnology" },
+ { "GSY", "Grossenbacher Systeme AG" },
+ { "GTC", "Graphtec Corporation" },
+ { "GTI", "Goldtouch" },
+ { "GTK", "G-Tech Corporation" },
+ { "GTM", "Garnet System Company Ltd" },
+ { "GTS", "Geotest Marvin Test Systems Inc" },
+ { "GTT", "General Touch Technology Co., Ltd." },
+ { "GUD", "Guntermann & Drunck GmbH" },
+ { "GUZ", "Guzik Technical Enterprises" },
+ { "GVC", "GVC Corporation" },
+ { "GVL", "Global Village Communication" },
+ { "GWI", "GW Instruments" },
+ { "GWK", "Gateworks Corporation" },
+ { "GWY", "Gateway 2000" },
+ { "GZE", "GUNZE Limited" },
+ { "HAE", "Haider electronics" },
+ { "HAI", "Haivision Systems Inc." },
+ { "HAL", "Halberthal" },
+ { "HAN", "Hanchang System Corporation" },
+ { "HAR", "Harris Corporation" },
+ { "HAY", "Hayes Microcomputer Products Inc" },
+ { "HCA", "DAT" },
+ { "HCE", "Hitachi Consumer Electronics Co., Ltd" },
+ { "HCL", "HCL America Inc" },
+ { "HCM", "HCL Peripherals" },
+ { "HCP", "Hitachi Computer Products Inc" },
+ { "HCW", "Hauppauge Computer Works Inc" },
+ { "HDC", "HardCom Elektronik & Datateknik" },
+ { "HDI", "HD-INFO d.o.o." },
+ { "HDV", "Holografika kft." },
+ { "HEC", "Hisense Electric Co., Ltd." },
+ { "HEL", "Hitachi Micro Systems Europe Ltd" },
+ { "HER", "Ascom Business Systems" },
+ { "HET", "HETEC Datensysteme GmbH" },
+ { "HHC", "HIRAKAWA HEWTECH CORP." },
+ { "HHI", "Fraunhofer Heinrich-Hertz-Institute" },
+ { "HIB", "Hibino Corporation" },
+ { "HIC", "Hitachi Information Technology Co., Ltd." },
+ { "HII", "Harman International Industries, Inc" },
+ { "HIK", "Hikom Co., Ltd." },
+ { "HIL", "Hilevel Technology" },
+ { "HIQ", "Kaohsiung Opto Electronics Americas, Inc." },
+ { "HIS", "Hope Industrial Systems, Inc." },
+ { "HIT", "Hitachi America Ltd" },
+ { "HJI", "Harris & Jeffries Inc" },
+ { "HKA", "HONKO MFG. CO., LTD." },
+ { "HKC", "HKC OVERSEAS LIMITED" },
+ { "HKG", "Josef Heim KG" },
+ { "HLG", "China Hualu Group Co., Ltd." },
+ { "HMC", "Hualon Microelectric Corporation" },
+ { "HMK", "hmk Daten-System-Technik BmbH" },
+ { "HMX", "HUMAX Co., Ltd." },
+ { "HNS", "Hughes Network Systems" },
+ { "HOB", "HOB Electronic GmbH" },
+ { "HOE", "Hosiden Corporation" },
+ { "HOL", "Holoeye Photonics AG" },
+ { "HON", "Sonitronix" },
+ { "HPA", "Zytor Communications" },
+ { "HPC", "Hewlett-Packard Co." },
+ { "HPD", "Hewlett Packard" },
+ { "HPE", "Hewlett Packard Enterprise" },
+ { "HPI", "Headplay, Inc." },
+ { "HPK", "HAMAMATSU PHOTONICS K.K." },
+ { "HPN", "HP Inc." },
+ { "HPQ", "Hewlett-Packard Co." },
+ { "HPR", "H.P.R. Electronics GmbH" },
+ { "HRC", "Hercules" },
+ { "HRE", "Qingdao Haier Electronics Co., Ltd." },
+ { "HRI", "Hall Research" },
+ { "HRL", "Herolab GmbH" },
+ { "HRS", "Harris Semiconductor" },
+ { "HRT", "HERCULES" },
+ { "HSC", "Hagiwara Sys-Com Company Ltd" },
+ { "HSD", "HannStar Display Corp" },
+ { "HSM", "AT&T Microelectronics" },
+ { "HSP", "HannStar Display Corp" },
+ { "HST", "Horsent Technology Co., Ltd." },
+ { "HTC", "Hitachi Ltd" },
+ { "HTI", "Hampshire Company, Inc." },
+ { "HTK", "Holtek Microelectronics Inc" },
+ { "HTL", "HTBLuVA Mödling" },
+ { "HTR", "Shenzhen ZhuoYi HengTong Computer Technology Limited" },
+ { "HTX", "Hitex Systementwicklung GmbH" },
+ { "HUB", "GAI-Tronics, A Hubbell Company" },
+ { "HUK", "Hoffmann + Krippner GmbH" },
+ { "HUM", "IMP Electronics Ltd." },
+ { "HVR", "HTC Corportation" },
+ { "HWA", "Harris Canada Inc" },
+ { "HWC", "DBA Hans Wedemeyer" },
+ { "HWD", "Highwater Designs Ltd" },
+ { "HWP", "Hewlett Packard" },
+ { "HWV", "Huawei Technologies Co., Inc." },
+ { "HXM", "Hexium Ltd." },
+ { "HYC", "Hypercope Gmbh Aachen" },
+ { "HYD", "Hydis Technologies.Co.,LTD" },
+ { "HYL", "Shanghai Chai Ming Huang Info&Tech Co, Ltd" },
+ { "HYO", "HYC CO., LTD." },
+ { "HYP", "Hyphen Ltd" },
+ { "HYR", "Hypertec Pty Ltd" },
+ { "HYT", "Heng Yu Technology (HK) Limited" },
+ { "HYV", "Hynix Semiconductor" },
+ { "IAD", "IAdea Corporation" },
+ { "IAF", "Institut f r angewandte Funksystemtechnik GmbH" },
+ { "IAI", "Integration Associates, Inc." },
+ { "IAT", "IAT Germany GmbH" },
+ { "IBC", "Integrated Business Systems" },
+ { "IBI", "INBINE.CO.LTD" },
+ { "IBM", "IBM Brasil" },
+ { "IBP", "IBP Instruments GmbH" },
+ { "IBR", "IBR GmbH" },
+ { "ICA", "ICA Inc" },
+ { "ICC", "BICC Data Networks Ltd" },
+ { "ICD", "ICD Inc" },
+ { "ICE", "IC Ensemble" },
+ { "ICI", "Infotek Communication Inc" },
+ { "ICM", "Intracom SA" },
+ { "ICN", "Sanyo Icon" },
+ { "ICO", "Intel Corp" },
+ { "ICP", "ICP Electronics, Inc./iEi Technology Corp." },
+ { "ICR", "Icron" },
+ { "ICS", "Integrated Circuit Systems" },
+ { "ICV", "Inside Contactless" },
+ { "ICX", "ICCC A/S" },
+ { "IDC", "International Datacasting Corporation" },
+ { "IDE", "IDE Associates" },
+ { "IDK", "IDK Corporation" },
+ { "IDN", "Idneo Technologies" },
+ { "IDO", "IDEO Product Development" },
+ { "IDP", "Integrated Device Technology, Inc." },
+ { "IDS", "Interdigital Sistemas de Informacao" },
+ { "IDT", "International Display Technology" },
+ { "IDX", "IDEXX Labs" },
+ { "IEC", "Interlace Engineering Corporation" },
+ { "IEE", "IEE" },
+ { "IEI", "Interlink Electronics" },
+ { "IFS", "In Focus Systems Inc" },
+ { "IFT", "Informtech" },
+ { "IFX", "Infineon Technologies AG" },
+ { "IFZ", "Infinite Z" },
+ { "IGC", "Intergate Pty Ltd" },
+ { "IGM", "IGM Communi" },
+ { "IHE", "InHand Electronics" },
+ { "IIC", "ISIC Innoscan Industrial Computers A/S" },
+ { "III", "Intelligent Instrumentation" },
+ { "IIN", "IINFRA Co., Ltd" },
+ { "IIT", "Informatik Information Technologies" },
+ { "IKE", "Ikegami Tsushinki Co. Ltd." },
+ { "IKS", "Ikos Systems Inc" },
+ { "ILC", "Image Logic Corporation" },
+ { "ILS", "Innotech Corporation" },
+ { "IMA", "Imagraph" },
+ { "IMB", "ART s.r.l." },
+ { "IMC", "IMC Networks" },
+ { "IMD", "ImasDe Canarias S.A." },
+ { "IME", "Imagraph" },
+ { "IMF", "Immersive Audio Technologies France" },
+ { "IMG", "IMAGENICS Co., Ltd." },
+ { "IMI", "International Microsystems Inc" },
+ { "IMM", "Immersion Corporation" },
+ { "IMN", "Impossible Production" },
+ { "IMP", "Impinj" },
+ { "IMT", "Inmax Technology Corporation" },
+ { "INA", "Inventec Corporation" },
+ { "INC", "Home Row Inc" },
+ { "IND", "ILC" },
+ { "INE", "Inventec Electronics (M) Sdn. Bhd." },
+ { "INF", "Inframetrics Inc" },
+ { "ING", "Integraph Corporation" },
+ { "INI", "Initio Corporation" },
+ { "INK", "Indtek Co., Ltd." },
+ { "INL", "InnoLux Display Corporation" },
+ { "INM", "InnoMedia Inc" },
+ { "INN", "Innovent Systems, Inc." },
+ { "INO", "Innolab Pte Ltd" },
+ { "INP", "Interphase Corporation" },
+ { "INS", "Ines GmbH" },
+ { "INT", "Interphase Corporation" },
+ { "INU", "Inovatec S.p.A." },
+ { "INV", "Inviso, Inc." },
+ { "INX", "Communications Supply Corporation (A division of WESCO)" },
+ { "INZ", "Best Buy" },
+ { "IOA", "CRE Technology Corporation" },
+ { "IOD", "I-O Data Device Inc" },
+ { "IOM", "Iomega" },
+ { "ION", "Inside Out Networks" },
+ { "IOS", "i-O Display System" },
+ { "IOT", "I/OTech Inc" },
+ { "IPC", "IPC Corporation" },
+ { "IPD", "Industrial Products Design, Inc." },
+ { "IPI", "Intelligent Platform Management Interface (IPMI) forum (Intel, HP, NEC, Dell)" },
+ { "IPM", "IPM Industria Politecnica Meridionale SpA" },
+ { "IPN", "Performance Technologies" },
+ { "IPP", "IP Power Technologies GmbH" },
+ { "IPQ", "IP3 Technology Ltd." },
+ { "IPR", "Ithaca Peripherals" },
+ { "IPS", "IPS, Inc. (Intellectual Property Solutions, Inc.)" },
+ { "IPT", "International Power Technologies" },
+ { "IPW", "IPWireless, Inc" },
+ { "IQI", "IneoQuest Technologies, Inc" },
+ { "IQT", "IMAGEQUEST Co., Ltd" },
+ { "IRD", "Irdata" },
+ { "ISA", "Symbol Technologies" },
+ { "ISC", "Id3 Semiconductors" },
+ { "ISG", "Insignia Solutions Inc" },
+ { "ISI", "Interface Solutions" },
+ { "ISL", "Isolation Systems" },
+ { "ISM", "Image Stream Medical" },
+ { "ISP", "IntreSource Systems Pte Ltd" },
+ { "ISR", "INSIS Co., LTD." },
+ { "ISS", "ISS Inc" },
+ { "IST", "Intersolve Technologies" },
+ { "ISY", "International Integrated Systems,Inc.(IISI)" },
+ { "ITA", "Itausa Export North America" },
+ { "ITC", "Intercom Inc" },
+ { "ITD", "Internet Technology Corporation" },
+ { "ITE", "Integrated Tech Express Inc" },
+ { "ITI", "VanErum Group" },
+ { "ITK", "ITK Telekommunikation AG" },
+ { "ITL", "Inter-Tel" },
+ { "ITM", "ITM inc." },
+ { "ITN", "The NTI Group" },
+ { "ITP", "IT-PRO Consulting und Systemhaus GmbH" },
+ { "ITR", "Infotronic America, Inc." },
+ { "ITS", "IDTECH" },
+ { "ITT", "I&T Telecom." },
+ { "ITX", "integrated Technology Express Inc" },
+ { "IUC", "ICSL" },
+ { "IVI", "Intervoice Inc" },
+ { "IVM", "Iiyama North America" },
+ { "IVR", "Inlife-Handnet Co., Ltd." },
+ { "IVS", "Intevac Photonics Inc." },
+ { "IWR", "Icuiti Corporation" },
+ { "IWX", "Intelliworxx, Inc." },
+ { "IXD", "Intertex Data AB" },
+ { "IXN", "Shenzhen Inet Mobile Internet Technology Co., LTD" },
+ { "JAC", "Astec Inc" },
+ { "JAE", "Japan Aviation Electronics Industry, Limited" },
+ { "JAS", "Janz Automationssysteme AG" },
+ { "JAT", "Jaton Corporation" },
+ { "JAZ", "Carrera Computer Inc" },
+ { "JCE", "Jace Tech Inc" },
+ { "JDI", "Japan Display Inc." },
+ { "JDL", "Japan Digital Laboratory Co.,Ltd." },
+ { "JEM", "Japan E.M.Solutions Co., Ltd." },
+ { "JEN", "N-Vision" },
+ { "JET", "JET POWER TECHNOLOGY CO., LTD." },
+ { "JFX", "Jones Futurex Inc" },
+ { "JGD", "University College" },
+ { "JIC", "Jaeik Information & Communication Co., Ltd." },
+ { "JKC", "JVC KENWOOD Corporation" },
+ { "JMT", "Micro Technical Company Ltd" },
+ { "JPC", "JPC Technology Limited" },
+ { "JPW", "Wallis Hamilton Industries" },
+ { "JQE", "CNet Technical Inc" },
+ { "JSD", "JS DigiTech, Inc" },
+ { "JSI", "Jupiter Systems, Inc." },
+ { "JSK", "SANKEN ELECTRIC CO., LTD" },
+ { "JTS", "JS Motorsports" },
+ { "JTY", "jetway security micro,inc" },
+ { "JUK", "Janich & Klass Computertechnik GmbH" },
+ { "JUP", "Jupiter Systems" },
+ { "JVC", "JVC" },
+ { "JWD", "Video International Inc." },
+ { "JWL", "Jewell Instruments, LLC" },
+ { "JWS", "JWSpencer & Co." },
+ { "JWY", "Jetway Information Co., Ltd" },
+ { "KAR", "Karna" },
+ { "KBI", "Kidboard Inc" },
+ { "KBL", "Kobil Systems GmbH" },
+ { "KCD", "Chunichi Denshi Co.,LTD." },
+ { "KCL", "Keycorp Ltd" },
+ { "KDE", "KDE" },
+ { "KDK", "Kodiak Tech" },
+ { "KDM", "Korea Data Systems Co., Ltd." },
+ { "KDS", "KDS USA" },
+ { "KDT", "KDDI Technology Corporation" },
+ { "KEC", "Kyushu Electronics Systems Inc" },
+ { "KEM", "Kontron Embedded Modules GmbH" },
+ { "KES", "Kesa Corporation" },
+ { "KEU", "Kontron Europe GmbH" },
+ { "KEY", "Key Tech Inc" },
+ { "KFC", "SCD Tech" },
+ { "KFE", "Komatsu Forest" },
+ { "KFX", "Kofax Image Products" },
+ { "KGI", "Klipsch Group, Inc" },
+ { "KGL", "KEISOKU GIKEN Co.,Ltd." },
+ { "KIO", "Kionix, Inc." },
+ { "KIS", "KiSS Technology A/S" },
+ { "KMC", "Mitsumi Company Ltd" },
+ { "KME", "KIMIN Electronics Co., Ltd." },
+ { "KML", "Kensington Microware Ltd" },
+ { "KMR", "Kramer Electronics Ltd. International" },
+ { "KNC", "Konica corporation" },
+ { "KNX", "Nutech Marketing PTL" },
+ { "KOB", "Kobil Systems GmbH" },
+ { "KOD", "Eastman Kodak Company" },
+ { "KOE", "KOLTER ELECTRONIC" },
+ { "KOL", "Kollmorgen Motion Technologies Group" },
+ { "KOM", "Kontron GmbH" },
+ { "KOU", "KOUZIRO Co.,Ltd." },
+ { "KOW", "KOWA Company,LTD." },
+ { "KPC", "King Phoenix Company" },
+ { "KPT", "TPK Holding Co., Ltd" },
+ { "KRL", "Krell Industries Inc." },
+ { "KRM", "Kroma Telecom" },
+ { "KRY", "Kroy LLC" },
+ { "KSC", "Kinetic Systems Corporation" },
+ { "KSG", "KUPA China Shenzhen Micro Technology Co., Ltd. Gold Institute" },
+ { "KSL", "Karn Solutions Ltd." },
+ { "KSX", "King Tester Corporation" },
+ { "KTC", "Kingston Tech Corporation" },
+ { "KTD", "Takahata Electronics Co.,Ltd." },
+ { "KTE", "K-Tech" },
+ { "KTG", "Kayser-Threde GmbH" },
+ { "KTI", "Konica Technical Inc" },
+ { "KTK", "Key Tronic Corporation" },
+ { "KTN", "Katron Tech Inc" },
+ { "KTS", "Kyokko Communication System Co., Ltd." },
+ { "KUR", "Kurta Corporation" },
+ { "KVA", "Kvaser AB" },
+ { "KVX", "KeyView" },
+ { "KWD", "Kenwood Corporation" },
+ { "KYC", "Kyocera Corporation" },
+ { "KYE", "KYE Syst Corporation" },
+ { "KYK", "Samsung Electronics America Inc" },
+ { "KYN", "KEYENCE CORPORATION" },
+ { "KZI", "K-Zone International co. Ltd." },
+ { "KZN", "K-Zone International" },
+ { "LAB", "ACT Labs Ltd" },
+ { "LAC", "LaCie" },
+ { "LAF", "Microline" },
+ { "LAG", "Laguna Systems" },
+ { "LAN", "Sodeman Lancom Inc" },
+ { "LAS", "LASAT Comm. A/S" },
+ { "LAV", "Lava Computer MFG Inc" },
+ { "LBO", "Lubosoft" },
+ { "LCC", "LCI" },
+ { "LCD", "Toshiba Matsushita Display Technology Co., Ltd" },
+ { "LCE", "La Commande Electronique" },
+ { "LCI", "Lite-On Communication Inc" },
+ { "LCM", "Latitude Comm." },
+ { "LCN", "LEXICON" },
+ { "LCS", "Longshine Electronics Company" },
+ { "LCT", "Labcal Technologies" },
+ { "LDN", "Laserdyne Technologies" },
+ { "LDT", "LogiDataTech Electronic GmbH" },
+ { "LEC", "Lectron Company Ltd" },
+ { "LED", "Long Engineering Design Inc" },
+ { "LEG", "Legerity, Inc" },
+ { "LEN", "Lenovo Group Limited" },
+ { "LEO", "First International Computer Inc" },
+ { "LEX", "Lexical Ltd" },
+ { "LGC", "Logic Ltd" },
+ { "LGI", "Logitech Inc" },
+ { "LGS", "LG Semicom Company Ltd" },
+ { "LGX", "Lasergraphics, Inc." },
+ { "LHA", "Lars Haagh ApS" },
+ { "LHC", "Beihai Century Joint Innovation Technology Co.,Ltd" },
+ { "LHE", "Lung Hwa Electronics Company Ltd" },
+ { "LHT", "Lighthouse Technologies Limited" },
+ { "LIN", "Lenovo Beijing Co. Ltd." },
+ { "LIP", "Linked IP GmbH" },
+ { "LIT", "Lithics Silicon Technology" },
+ { "LJX", "Datalogic Corporation" },
+ { "LKM", "Likom Technology Sdn. Bhd." },
+ { "LLL", "L-3 Communications" },
+ { "LMG", "Lucent Technologies" },
+ { "LMI", "Lexmark Int'l Inc" },
+ { "LMP", "Leda Media Products" },
+ { "LMT", "Laser Master" },
+ { "LND", "Land Computer Company Ltd" },
+ { "LNK", "Link Tech Inc" },
+ { "LNR", "Linear Systems Ltd." },
+ { "LNT", "LANETCO International" },
+ { "LNV", "Lenovo" },
+ { "LNX", "The Linux Foundation" },
+ { "LOC", "Locamation B.V." },
+ { "LOE", "Loewe Opta GmbH" },
+ { "LOG", "Logicode Technology Inc" },
+ { "LOL", "Litelogic Operations Ltd" },
+ { "LPE", "El-PUSK Co., Ltd." },
+ { "LPI", "Design Technology" },
+ { "LPL", "LG Philips" },
+ { "LSC", "LifeSize Communications" },
+ { "LSD", "Intersil Corporation" },
+ { "LSI", "Loughborough Sound Images" },
+ { "LSJ", "LSI Japan Company Ltd" },
+ { "LSL", "Logical Solutions" },
+ { "LSP", "Lightspace Technologies" },
+ { "LSY", "LSI Systems Inc" },
+ { "LTC", "Labtec Inc" },
+ { "LTI", "Jongshine Tech Inc" },
+ { "LTK", "Lucidity Technology Company Ltd" },
+ { "LTN", "Litronic Inc" },
+ { "LTS", "LTS Scale LLC" },
+ { "LTV", "Leitch Technology International Inc." },
+ { "LTW", "Lightware, Inc" },
+ { "LUC", "Lucent Technologies" },
+ { "LUM", "Lumagen, Inc." },
+ { "LUX", "Luxxell Research Inc" },
+ { "LVI", "LVI Low Vision International AB" },
+ { "LWC", "Labway Corporation" },
+ { "LWR", "Lightware Visual Engineering" },
+ { "LWW", "Lanier Worldwide" },
+ { "LXC", "LXCO Technologies AG" },
+ { "LXN", "Luxeon" },
+ { "LXS", "ELEA CardWare" },
+ { "LZX", "Lightwell Company Ltd" },
+ { "MAC", "MAC System Company Ltd" },
+ { "MAD", "Xedia Corporation" },
+ { "MAE", "Maestro Pty Ltd" },
+ { "MAG", "MAG InnoVision" },
+ { "MAI", "Mutoh America Inc" },
+ { "MAL", "Meridian Audio Ltd" },
+ { "MAN", "LGIC" },
+ { "MAS", "Mass Inc." },
+ { "MAT", "Matsushita Electric Ind. Company Ltd" },
+ { "MAX", "Rogen Tech Distribution Inc" },
+ { "MAY", "Maynard Electronics" },
+ { "MAZ", "MAZeT GmbH" },
+ { "MBC", "MBC" },
+ { "MBD", "Microbus PLC" },
+ { "MBM", "Marshall Electronics" },
+ { "MBV", "Moreton Bay" },
+ { "MCA", "American Nuclear Systems Inc" },
+ { "MCC", "Micro Industries" },
+ { "MCD", "McDATA Corporation" },
+ { "MCE", "Metz-Werke GmbH & Co KG" },
+ { "MCG", "Motorola Computer Group" },
+ { "MCI", "Micronics Computers" },
+ { "MCJ", "Medicaroid Corporation" },
+ { "MCL", "Motorola Communications Israel" },
+ { "MCM", "Metricom Inc" },
+ { "MCN", "Micron Electronics Inc" },
+ { "MCO", "Motion Computing Inc." },
+ { "MCP", "Magni Systems Inc" },
+ { "MCQ", "Mat's Computers" },
+ { "MCR", "Marina Communicaitons" },
+ { "MCS", "Micro Computer Systems" },
+ { "MCT", "Microtec" },
+ { "MCX", "Millson Custom Solutions Inc." },
+ { "MDA", "Media4 Inc" },
+ { "MDC", "Midori Electronics" },
+ { "MDD", "MODIS" },
+ { "MDF", "MILDEF AB" },
+ { "MDG", "Madge Networks" },
+ { "MDI", "Micro Design Inc" },
+ { "MDK", "Mediatek Corporation" },
+ { "MDO", "Panasonic" },
+ { "MDR", "Medar Inc" },
+ { "MDS", "Micro Display Systems Inc" },
+ { "MDT", "Magus Data Tech" },
+ { "MDV", "MET Development Inc" },
+ { "MDX", "MicroDatec GmbH" },
+ { "MDY", "Microdyne Inc" },
+ { "MEC", "Mega System Technologies Inc" },
+ { "MED", "Messeltronik Dresden GmbH" },
+ { "MEE", "Mitsubishi Electric Engineering Co., Ltd." },
+ { "MEG", "Abeam Tech Ltd." },
+ { "MEI", "Panasonic Industry Company" },
+ { "MEJ", "Mac-Eight Co., LTD." },
+ { "MEK", "Mediaedge Corporation" },
+ { "MEL", "Mitsubishi Electric Corporation" },
+ { "MEN", "MEN Mikroelectronik Nueruberg GmbH" },
+ { "MEP", "Meld Technology" },
+ { "MEQ", "Matelect Ltd." },
+ { "MET", "Metheus Corporation" },
+ { "MEU", "MPL AG, Elektronik-Unternehmen" },
+ { "MEX", "MSC Vertriebs GmbH" },
+ { "MFG", "MicroField Graphics Inc" },
+ { "MFI", "Micro Firmware" },
+ { "MFR", "MediaFire Corp." },
+ { "MGA", "Mega System Technologies, Inc." },
+ { "MGC", "Mentor Graphics Corporation" },
+ { "MGE", "Schneider Electric S.A." },
+ { "MGL", "M-G Technology Ltd" },
+ { "MGT", "Megatech R & D Company" },
+ { "MHQ", "Moxa Inc." },
+ { "MIC", "Micom Communications Inc" },
+ { "MID", "miro Displays" },
+ { "MII", "Mitec Inc" },
+ { "MIL", "Marconi Instruments Ltd" },
+ { "MIM", "Mimio – A Newell Rubbermaid Company" },
+ { "MIN", "Minicom Digital Signage" },
+ { "MIP", "micronpc.com" },
+ { "MIR", "Miro Computer Prod." },
+ { "MIS", "Modular Industrial Solutions Inc" },
+ { "MIT", "MCM Industrial Technology GmbH" },
+ { "MIV", "MicroImage Video Systems" },
+ { "MJI", "MARANTZ JAPAN, INC." },
+ { "MJS", "MJS Designs" },
+ { "MKC", "Media Tek Inc." },
+ { "MKS", "MK Seiko Co., Ltd." },
+ { "MKT", "MICROTEK Inc." },
+ { "MKV", "Trtheim Technology" },
+ { "MLC", "MILCOTS" },
+ { "MLD", "Deep Video Imaging Ltd" },
+ { "MLG", "Micrologica AG" },
+ { "MLI", "McIntosh Laboratory Inc." },
+ { "MLL", "Millogic Ltd." },
+ { "MLM", "Millennium Engineering Inc" },
+ { "MLN", "Mark Levinson" },
+ { "MLP", "Magic Leap" },
+ { "MLS", "Milestone EPE" },
+ { "MLT", "Wanlida Group Co., Ltd." },
+ { "MLX", "Mylex Corporation" },
+ { "MMA", "Micromedia AG" },
+ { "MMD", "Micromed Biotecnologia Ltd" },
+ { "MMF", "Minnesota Mining and Manufacturing" },
+ { "MMI", "Multimax" },
+ { "MMM", "Electronic Measurements" },
+ { "MMN", "MiniMan Inc" },
+ { "MMS", "MMS Electronics" },
+ { "MMT", "MIMO Monitors" },
+ { "MNC", "Mini Micro Methods Ltd" },
+ { "MNI", "Marseille, Inc." },
+ { "MNL", "Monorail Inc" },
+ { "MNP", "Microcom" },
+ { "MOC", "Matrix Orbital Corporation" },
+ { "MOD", "Modular Technology" },
+ { "MOM", "Momentum Data Systems" },
+ { "MOS", "Moses Corporation" },
+ { "MOT", "Motorola UDS" },
+ { "MPC", "M-Pact Inc" },
+ { "MPI", "Mediatrix Peripherals Inc" },
+ { "MPJ", "Microlab" },
+ { "MPL", "Maple Research Inst. Company Ltd" },
+ { "MPN", "Mainpine Limited" },
+ { "MPS", "mps Software GmbH" },
+ { "MPV", "Megapixel Visual Realty" },
+ { "MPX", "Micropix Technologies, Ltd." },
+ { "MQP", "MultiQ Products AB" },
+ { "MRA", "Miranda Technologies Inc" },
+ { "MRC", "Marconi Simulation & Ty-Coch Way Training" },
+ { "MRD", "MicroDisplay Corporation" },
+ { "MRK", "Maruko & Company Ltd" },
+ { "MRL", "Miratel" },
+ { "MRO", "Medikro Oy" },
+ { "MRT", "Merging Technologies" },
+ { "MSA", "Micro Systemation AB" },
+ { "MSC", "Mouse Systems Corporation" },
+ { "MSD", "Datenerfassungs- und Informationssysteme" },
+ { "MSF", "M-Systems Flash Disk Pioneers" },
+ { "MSG", "MSI GmbH" },
+ { "MSH", "Microsoft" },
+ { "MSI", "Microstep" },
+ { "MSK", "Megasoft Inc" },
+ { "MSL", "MicroSlate Inc." },
+ { "MSM", "Advanced Digital Systems" },
+ { "MSP", "Mistral Solutions [P] Ltd." },
+ { "MSR", "MASPRO DENKOH Corp." },
+ { "MST", "MS Telematica" },
+ { "MSU", "motorola" },
+ { "MSV", "Mosgi Corporation" },
+ { "MSX", "Micomsoft Co., Ltd." },
+ { "MSY", "MicroTouch Systems Inc" },
+ { "MTA", "Meta Watch Ltd" },
+ { "MTB", "Media Technologies Ltd." },
+ { "MTC", "Mars-Tech Corporation" },
+ { "MTD", "MindTech Display Co. Ltd" },
+ { "MTE", "MediaTec GmbH" },
+ { "MTH", "Micro-Tech Hearing Instruments" },
+ { "MTI", "MaxCom Technical Inc" },
+ { "MTJ", "MicroTechnica Co.,Ltd." },
+ { "MTK", "Microtek International Inc." },
+ { "MTL", "Mitel Corporation" },
+ { "MTM", "Motium" },
+ { "MTN", "Mtron Storage Technology Co., Ltd." },
+ { "MTR", "Mitron computer Inc" },
+ { "MTS", "Multi-Tech Systems" },
+ { "MTU", "Mark of the Unicorn Inc" },
+ { "MTX", "Matrox" },
+ { "MUD", "Multi-Dimension Institute" },
+ { "MUK", "Mainpine Limited" },
+ { "MVD", "Microvitec PLC" },
+ { "MVI", "Media Vision Inc" },
+ { "MVM", "SOBO VISION" },
+ { "MVN", "Meta Company" },
+ { "MVR", "MediCapture, Inc." },
+ { "MVS", "Microvision" },
+ { "MVX", "COM 1" },
+ { "MWI", "Multiwave Innovation Pte Ltd" },
+ { "MWR", "mware" },
+ { "MWY", "Microway Inc" },
+ { "MXD", "MaxData Computer GmbH & Co.KG" },
+ { "MXI", "Macronix Inc" },
+ { "MXL", "Hitachi Maxell, Ltd." },
+ { "MXP", "Maxpeed Corporation" },
+ { "MXT", "Maxtech Corporation" },
+ { "MXV", "MaxVision Corporation" },
+ { "MYA", "Monydata" },
+ { "MYR", "Myriad Solutions Ltd" },
+ { "MYX", "Micronyx Inc" },
+ { "NAC", "Ncast Corporation" },
+ { "NAD", "NAD Electronics" },
+ { "NAK", "Nakano Engineering Co.,Ltd." },
+ { "NAL", "Network Alchemy" },
+ { "NAT", "NaturalPoint Inc." },
+ { "NAV", "Navigation Corporation" },
+ { "NAX", "Naxos Tecnologia" },
+ { "NBL", "N*Able Technologies Inc" },
+ { "NBS", "National Key Lab. on ISN" },
+ { "NBT", "NingBo Bestwinning Technology CO., Ltd" },
+ { "NCA", "Nixdorf Company" },
+ { "NCC", "NCR Corporation" },
+ { "NCE", "Norcent Technology, Inc." },
+ { "NCI", "NewCom Inc" },
+ { "NCL", "NetComm Ltd" },
+ { "NCP", "Najing CEC Panda FPD Technology CO. ltd" },
+ { "NCR", "NCR Electronics" },
+ { "NCS", "Northgate Computer Systems" },
+ { "NCT", "NEC CustomTechnica, Ltd." },
+ { "NDC", "National DataComm Corporaiton" },
+ { "NDF", "NDF Special Light Products B.V." },
+ { "NDI", "National Display Systems" },
+ { "NDK", "Naitoh Densei CO., LTD." },
+ { "NDL", "Network Designers" },
+ { "NDS", "Nokia Data" },
+ { "NEC", "NEC Corporation" },
+ { "NEO", "NEO TELECOM CO.,LTD." },
+ { "NES", "INNES" },
+ { "NET", "Mettler Toledo" },
+ { "NEU", "NEUROTEC - EMPRESA DE PESQUISA E DESENVOLVIMENTO EM BIOMEDICINA" },
+ { "NEX", "Nexgen Mediatech Inc.," },
+ { "NFC", "BTC Korea Co., Ltd" },
+ { "NFS", "Number Five Software" },
+ { "NGC", "Network General" },
+ { "NGS", "A D S Exports" },
+ { "NHT", "Vinci Labs" },
+ { "NIC", "National Instruments Corporation" },
+ { "NIS", "Nissei Electric Company" },
+ { "NIT", "Network Info Technology" },
+ { "NIX", "Seanix Technology Inc" },
+ { "NLC", "Next Level Communications" },
+ { "NME", "Navico, Inc." },
+ { "NMP", "Nokia Mobile Phones" },
+ { "NMS", "Natural Micro System" },
+ { "NMV", "NEC-Mitsubishi Electric Visual Systems Corporation" },
+ { "NMX", "Neomagic" },
+ { "NNC", "NNC" },
+ { "NOD", "3NOD Digital Technology Co. Ltd." },
+ { "NOE", "NordicEye AB" },
+ { "NOI", "North Invent A/S" },
+ { "NOK", "Nokia Display Products" },
+ { "NOR", "Norand Corporation" },
+ { "NOT", "Not Limited Inc" },
+ { "NPA", "Arvanics" },
+ { "NPI", "Network Peripherals Inc" },
+ { "NRI", "Noritake Itron Corporation" },
+ { "NRL", "U.S. Naval Research Lab" },
+ { "NRT", "Beijing Northern Radiantelecom Co." },
+ { "NRV", "Taugagreining hf" },
+ { "NSA", "NeuroSky, Inc." },
+ { "NSC", "National Semiconductor Corporation" },
+ { "NSI", "NISSEI ELECTRIC CO.,LTD" },
+ { "NSP", "Nspire System Inc." },
+ { "NSS", "Newport Systems Solutions" },
+ { "NST", "Network Security Technology Co" },
+ { "NTC", "NeoTech S.R.L" },
+ { "NTI", "New Tech Int'l Company" },
+ { "NTK", "NewTek" },
+ { "NTL", "National Transcomm. Ltd" },
+ { "NTN", "Nuvoton Technology Corporation" },
+ { "NTR", "N-trig Innovative Technologies, Inc." },
+ { "NTS", "Nits Technology Inc." },
+ { "NTT", "NTT Advanced Technology Corporation" },
+ { "NTW", "Networth Inc" },
+ { "NTX", "Netaccess Inc" },
+ { "NUG", "NU Technology, Inc." },
+ { "NUI", "NU Inc." },
+ { "NVC", "NetVision Corporation" },
+ { "NVD", "Nvidia" },
+ { "NVI", "NuVision US, Inc." },
+ { "NVL", "Novell Inc" },
+ { "NVT", "Navatek Engineering Corporation" },
+ { "NWC", "NW Computer Engineering" },
+ { "NWL", "Newline Interactive Inc." },
+ { "NWP", "NovaWeb Technologies Inc" },
+ { "NWS", "Newisys, Inc." },
+ { "NXC", "NextCom K.K." },
+ { "NXG", "Nexgen" },
+ { "NXP", "NXP Semiconductors bv." },
+ { "NXQ", "Nexiq Technologies, Inc." },
+ { "NXS", "Technology Nexus Secure Open Systems AB" },
+ { "NXT", "NZXT (PNP same EDID)_" },
+ { "NYC", "Nakayo Relecommunications, Inc." },
+ { "OAK", "Oak Tech Inc" },
+ { "OAS", "Oasys Technology Company" },
+ { "OBS", "Optibase Technologies" },
+ { "OCD", "Macraigor Systems Inc" },
+ { "OCN", "Olfan" },
+ { "OCS", "Open Connect Solutions" },
+ { "ODM", "ODME Inc." },
+ { "ODR", "Odrac" },
+ { "OEC", "ORION ELECTRIC CO.,LTD" },
+ { "OEI", "Optum Engineering Inc." },
+ { "OHW", "M-Labs Limited" },
+ { "OIC", "Option Industrial Computers" },
+ { "OIM", "Option International" },
+ { "OIN", "Option International" },
+ { "OKI", "OKI Electric Industrial Company Ltd" },
+ { "OLC", "Olicom A/S" },
+ { "OLD", "Olidata S.p.A." },
+ { "OLI", "Olivetti" },
+ { "OLT", "Olitec S.A." },
+ { "OLV", "Olitec S.A." },
+ { "OLY", "OLYMPUS CORPORATION" },
+ { "OMC", "OBJIX Multimedia Corporation" },
+ { "OMN", "Omnitel" },
+ { "OMR", "Omron Corporation" },
+ { "ONE", "Oneac Corporation" },
+ { "ONK", "ONKYO Corporation" },
+ { "ONL", "OnLive, Inc" },
+ { "ONS", "On Systems Inc" },
+ { "ONW", "OPEN Networks Ltd" },
+ { "ONX", "SOMELEC Z.I. Du Vert Galanta" },
+ { "OOS", "OSRAM" },
+ { "OPC", "Opcode Inc" },
+ { "OPI", "D.N.S. Corporation" },
+ { "OPP", "OPPO Digital, Inc." },
+ { "OPT", "OPTi Inc" },
+ { "OPV", "Optivision Inc" },
+ { "OQI", "Oksori Company Ltd" },
+ { "ORG", "ORGA Kartensysteme GmbH" },
+ { "ORI", "OSR Open Systems Resources, Inc." },
+ { "ORN", "ORION ELECTRIC CO., LTD." },
+ { "OSA", "OSAKA Micro Computer, Inc." },
+ { "OSD", "Optical Systems Design Pty Ltd" },
+ { "OSI", "Open Stack, Inc." },
+ { "OSP", "OPTI-UPS Corporation" },
+ { "OSR", "Oksori Company Ltd" },
+ { "OTB", "outsidetheboxstuff.com" },
+ { "OTI", "Orchid Technology" },
+ { "OTK", "OmniTek" },
+ { "OTM", "Optoma Corporation" },
+ { "OTT", "OPTO22, Inc." },
+ { "OUK", "OUK Company Ltd" },
+ { "OVR", "Oculus VR, Inc." },
+ { "OWL", "Mediacom Technologies Pte Ltd" },
+ { "OXU", "Oxus Research S.A." },
+ { "OYO", "Shadow Systems" },
+ { "OZC", "OZ Corporation" },
+ { "OZO", "Tribe Computer Works Inc" },
+ { "PAC", "Pacific Avionics Corporation" },
+ { "PAD", "Promotion and Display Technology Ltd." },
+ { "PAK", "Many CNC System Co., Ltd." },
+ { "PAM", "Peter Antesberger Messtechnik" },
+ { "PAN", "The Panda Project" },
+ { "PAR", "Parallan Comp Inc" },
+ { "PBI", "Pitney Bowes" },
+ { "PBL", "Packard Bell Electronics" },
+ { "PBN", "Packard Bell NEC" },
+ { "PBV", "Pitney Bowes" },
+ { "PCA", "Philips BU Add On Card" },
+ { "PCB", "OCTAL S.A." },
+ { "PCC", "PowerCom Technology Company Ltd" },
+ { "PCG", "First Industrial Computer Inc" },
+ { "PCI", "Pioneer Computer Inc" },
+ { "PCK", "PCBANK21" },
+ { "PCL", "pentel.co.,ltd" },
+ { "PCM", "PCM Systems Corporation" },
+ { "PCO", "Performance Concepts Inc.," },
+ { "PCP", "Procomp USA Inc" },
+ { "PCS", "TOSHIBA PERSONAL COMPUTER SYSTEM CORPRATION" },
+ { "PCT", "PC-Tel Inc" },
+ { "PCW", "Pacific CommWare Inc" },
+ { "PCX", "PC Xperten" },
+ { "PDM", "Psion Dacom Plc." },
+ { "PDN", "AT&T Paradyne" },
+ { "PDR", "Pure Data Inc" },
+ { "PDS", "PD Systems International Ltd" },
+ { "PDT", "PDTS - Prozessdatentechnik und Systeme" },
+ { "PDV", "Prodrive B.V." },
+ { "PEC", "POTRANS Electrical Corp." },
+ { "PEG", "Pegatron Corporation" },
+ { "PEI", "PEI Electronics Inc" },
+ { "PEL", "Primax Electric Ltd" },
+ { "PEN", "Interactive Computer Products Inc" },
+ { "PEP", "Peppercon AG" },
+ { "PER", "Perceptive Signal Technologies" },
+ { "PET", "Practical Electronic Tools" },
+ { "PFT", "Telia ProSoft AB" },
+ { "PGI", "PACSGEAR, Inc." },
+ { "PGM", "Paradigm Advanced Research Centre" },
+ { "PGP", "propagamma kommunikation" },
+ { "PGS", "Princeton Graphic Systems" },
+ { "PHC", "Pijnenburg Beheer N.V." },
+ { "PHE", "Philips Medical Systems Boeblingen GmbH" },
+ { "PHI", "DO NOT USE - PHI" },
+ { "PHL", "Philips Consumer Electronics Company" },
+ { "PHO", "Photonics Systems Inc." },
+ { "PHS", "Philips Communication Systems" },
+ { "PHY", "Phylon Communications" },
+ { "PIC", "Picturall Ltd." },
+ { "PIE", "Pacific Image Electronics Company Ltd" },
+ { "PIM", "Prism, LLC" },
+ { "PIO", "Pioneer Electronic Corporation" },
+ { "PIS", "TECNART CO.,LTD." },
+ { "PIX", "Pixie Tech Inc" },
+ { "PJA", "Projecta" },
+ { "PJD", "Projectiondesign AS" },
+ { "PJT", "Pan Jit International Inc." },
+ { "PKA", "Acco UK Ltd." },
+ { "PLC", "Pro-Log Corporation" },
+ { "PLF", "Panasonic Avionics Corporation" },
+ { "PLM", "PROLINK Microsystems Corp." },
+ { "PLT", "PT Hartono Istana Teknologi" },
+ { "PLV", "PLUS Vision Corp." },
+ { "PLX", "Parallax Graphics" },
+ { "PLY", "Polycom Inc." },
+ { "PMC", "PMC Consumer Electronics Ltd" },
+ { "PMD", "TDK USA Corporation" },
+ { "PMM", "Point Multimedia System" },
+ { "PMS", "Pabian Embedded Systems" },
+ { "PMT", "Promate Electronic Co., Ltd." },
+ { "PMX", "Photomatrix" },
+ { "PNG", "Microsoft" },
+ { "PNL", "Panelview, Inc." },
+ { "PNP", "Microsoft" },
+ { "PNR", "Planar Systems, Inc." },
+ { "PNS", "PanaScope" },
+ { "PNT", "HOYA Corporation PENTAX Lifecare Division" },
+ { "PNX", "Phoenix Technologies, Ltd." },
+ { "POL", "PolyComp (PTY) Ltd." },
+ { "PON", "Perpetual Technologies, LLC" },
+ { "POR", "Portalis LC" },
+ { "POS", "Positivo Tecnologia S.A." },
+ { "POT", "Parrot" },
+ { "PPC", "Phoenixtec Power Company Ltd" },
+ { "PPD", "MEPhI" },
+ { "PPI", "Practical Peripherals" },
+ { "PPM", "Clinton Electronics Corp." },
+ { "PPP", "Purup Prepress AS" },
+ { "PPR", "PicPro" },
+ { "PPX", "Perceptive Pixel Inc." },
+ { "PQI", "Pixel Qi" },
+ { "PRA", "PRO/AUTOMATION" },
+ { "PRC", "PerComm" },
+ { "PRD", "Praim S.R.L." },
+ { "PRF", "Schneider Electric Japan Holdings, Ltd." },
+ { "PRG", "The Phoenix Research Group Inc" },
+ { "PRI", "Priva Hortimation BV" },
+ { "PRM", "Prometheus" },
+ { "PRO", "Proteon" },
+ { "PRP", "UEFI Forum" },
+ { "PRS", "Leutron Vision" },
+ { "PRT", "Parade Technologies, Ltd." },
+ { "PRX", "Proxima Corporation" },
+ { "PSA", "Advanced Signal Processing Technologies" },
+ { "PSC", "Philips Semiconductors" },
+ { "PSD", "Peus-Systems GmbH" },
+ { "PSE", "Practical Solutions Pte., Ltd." },
+ { "PSI", "PSI-Perceptive Solutions Inc" },
+ { "PSL", "Perle Systems Limited" },
+ { "PSM", "Prosum" },
+ { "PST", "Global Data SA" },
+ { "PSY", "Prodea Systems Inc." },
+ { "PTA", "PAR Tech Inc." },
+ { "PTC", "PS Technology Corporation" },
+ { "PTG", "Cipher Systems Inc" },
+ { "PTH", "Pathlight Technology Inc" },
+ { "PTI", "Promise Technology Inc" },
+ { "PTL", "Pantel Inc" },
+ { "PTS", "Plain Tree Systems Inc" },
+ { "PTW", "DO NOT USE - PTW" },
+ { "PUL", "Pulse-Eight Ltd" },
+ { "PVC", "DO NOT USE - PVC" },
+ { "PVG", "Proview Global Co., Ltd" },
+ { "PVI", "Prime view international Co., Ltd" },
+ { "PVM", "Penta Studiotechnik GmbH" },
+ { "PVN", "Pixel Vision" },
+ { "PVP", "Klos Technologies, Inc." },
+ { "PVR", "Pimax Tech. CO., LTD" },
+ { "PXC", "Phoenix Contact" },
+ { "PXE", "PIXELA CORPORATION" },
+ { "PXL", "The Moving Pixel Company" },
+ { "PXM", "Proxim Inc" },
+ { "PXN", "PixelNext Inc" },
+ { "QCC", "QuakeCom Company Ltd" },
+ { "QCH", "Metronics Inc" },
+ { "QCI", "Quanta Computer Inc" },
+ { "QCK", "Quick Corporation" },
+ { "QCL", "Quadrant Components Inc" },
+ { "QCP", "Qualcomm Inc" },
+ { "QDI", "Quantum Data Incorporated" },
+ { "QDL", "QD Laser, Inc." },
+ { "QDM", "Quadram" },
+ { "QDS", "Quanta Display Inc." },
+ { "QFF", "Padix Co., Inc." },
+ { "QFI", "Quickflex, Inc" },
+ { "QLC", "Q-Logic" },
+ { "QQQ", "Chuomusen Co., Ltd." },
+ { "QSC", "QSC, LLC" },
+ { "QSI", "Quantum Solutions, Inc." },
+ { "QTD", "Quantum 3D Inc" },
+ { "QTH", "Questech Ltd" },
+ { "QTI", "Quicknet Technologies Inc" },
+ { "QTM", "Quantum" },
+ { "QTR", "Qtronix Corporation" },
+ { "QUA", "Quatographic AG" },
+ { "QUE", "Questra Consulting" },
+ { "QVU", "Quartics" },
+ { "RAC", "Racore Computer Products Inc" },
+ { "RAD", "Radisys Corporation" },
+ { "RAI", "Rockwell Automation/Intecolor" },
+ { "RAN", "Rancho Tech Inc" },
+ { "RAR", "Raritan, Inc." },
+ { "RAS", "RAScom Inc" },
+ { "RAT", "Rent-A-Tech" },
+ { "RAY", "Raylar Design, Inc." },
+ { "RCE", "Parc d'Activite des Bellevues" },
+ { "RCH", "Reach Technology Inc" },
+ { "RCI", "RC International" },
+ { "RCN", "Radio Consult SRL" },
+ { "RCO", "Rockwell Collins" },
+ { "RDI", "Rainbow Displays, Inc." },
+ { "RDM", "Tremon Enterprises Company Ltd" },
+ { "RDN", "RADIODATA GmbH" },
+ { "RDS", "Radius Inc" },
+ { "REA", "Real D" },
+ { "REC", "ReCom" },
+ { "RED", "Research Electronics Development Inc" },
+ { "REF", "Reflectivity, Inc." },
+ { "REH", "Rehan Electronics Ltd." },
+ { "REL", "Reliance Electric Ind Corporation" },
+ { "REM", "SCI Systems Inc." },
+ { "REN", "Renesas Technology Corp." },
+ { "RES", "ResMed Pty Ltd" },
+ { "RET", "Resonance Technology, Inc." },
+ { "REV", "Revolution Display, Inc." },
+ { "REX", "RATOC Systems, Inc." },
+ { "RFI", "RAFI GmbH & Co. KG" },
+ { "RFX", "Redfox Technologies Inc." },
+ { "RGB", "RGB Spectrum" },
+ { "RGL", "Robertson Geologging Ltd" },
+ { "RHD", "RightHand Technologies" },
+ { "RHM", "Rohm Company Ltd" },
+ { "RHT", "Red Hat, Inc." },
+ { "RIC", "RICOH COMPANY, LTD." },
+ { "RII", "Racal Interlan Inc" },
+ { "RIO", "Rios Systems Company Ltd" },
+ { "RIT", "Ritech Inc" },
+ { "RIV", "Rivulet Communications" },
+ { "RJA", "Roland Corporation" },
+ { "RJS", "Advanced Engineering" },
+ { "RKC", "Reakin Technolohy Corporation" },
+ { "RLD", "MEPCO" },
+ { "RLN", "RadioLAN Inc" },
+ { "RMC", "Raritan Computer, Inc" },
+ { "RMP", "Research Machines" },
+ { "RMS", "Shenzhen Ramos Digital Technology Co., Ltd" },
+ { "RMT", "Roper Mobile" },
+ { "RNB", "Rainbow Technologies" },
+ { "ROB", "Robust Electronics GmbH" },
+ { "ROH", "Rohm Co., Ltd." },
+ { "ROK", "Rockwell International" },
+ { "ROP", "Roper International Ltd" },
+ { "ROS", "Rohde & Schwarz" },
+ { "RPI", "RoomPro Technologies" },
+ { "RPT", "R.P.T.Intergroups" },
+ { "RRI", "Radicom Research Inc" },
+ { "RSC", "PhotoTelesis" },
+ { "RSH", "ADC-Centre" },
+ { "RSI", "Rampage Systems Inc" },
+ { "RSN", "Radiospire Networks, Inc." },
+ { "RSQ", "R Squared" },
+ { "RSR", "Zhong Shan City Richsound Electronic Industrial Ltd." },
+ { "RSS", "Rockwell Semiconductor Systems" },
+ { "RSV", "Ross Video Ltd" },
+ { "RSX", "Rapid Tech Corporation" },
+ { "RTC", "Relia Technologies" },
+ { "RTI", "Rancho Tech Inc" },
+ { "RTK", "DO NOT USE - RTK" },
+ { "RTL", "Realtek Semiconductor Company Ltd" },
+ { "RTS", "Raintree Systems" },
+ { "RUN", "RUNCO International" },
+ { "RUP", "Ups Manufactoring s.r.l." },
+ { "RVC", "RSI Systems Inc" },
+ { "RVI", "Realvision Inc" },
+ { "RVL", "Reveal Computer Prod" },
+ { "RWC", "Red Wing Corporation" },
+ { "RXT", "Tectona SoftSolutions (P) Ltd.," },
+ { "RZR", "Razer Taiwan Co. Ltd." },
+ { "RZS", "Rozsnyó, s.r.o." },
+ { "SAA", "Sanritz Automation Co.,Ltd." },
+ { "SAE", "Saab Aerotech" },
+ { "SAG", "Sedlbauer" },
+ { "SAI", "Sage Inc" },
+ { "SAK", "Saitek Ltd" },
+ { "SAM", "Samsung Electric Company" },
+ { "SAN", "Sanyo Electric Co.,Ltd." },
+ { "SAS", "Stores Automated Systems Inc" },
+ { "SAT", "Shuttle Tech" },
+ { "SBC", "Shanghai Bell Telephone Equip Mfg Co" },
+ { "SBD", "Softbed - Consulting & Development Ltd" },
+ { "SBI", "SMART Technologies Inc." },
+ { "SBS", "SBS-or Industrial Computers GmbH" },
+ { "SBT", "Senseboard Technologies AB" },
+ { "SCB", "SeeCubic B.V." },
+ { "SCC", "SORD Computer Corporation" },
+ { "SCD", "Sanyo Electric Company Ltd" },
+ { "SCE", "Sun Corporation" },
+ { "SCH", "Schlumberger Cards" },
+ { "SCI", "System Craft" },
+ { "SCL", "Sigmacom Co., Ltd." },
+ { "SCM", "SCM Microsystems Inc" },
+ { "SCN", "Scanport, Inc." },
+ { "SCO", "SORCUS Computer GmbH" },
+ { "SCP", "Scriptel Corporation" },
+ { "SCR", "Systran Corporation" },
+ { "SCS", "Nanomach Anstalt" },
+ { "SCT", "Smart Card Technology" },
+ { "SCX", "Socionext Inc." },
+ { "SDA", "SAT (Societe Anonyme)" },
+ { "SDD", "Intrada-SDD Ltd" },
+ { "SDE", "Sherwood Digital Electronics Corporation" },
+ { "SDF", "SODIFF E&T CO., Ltd." },
+ { "SDH", "Communications Specialies, Inc." },
+ { "SDI", "Samtron Displays Inc" },
+ { "SDK", "SAIT-Devlonics" },
+ { "SDR", "SDR Systems" },
+ { "SDS", "SunRiver Data System" },
+ { "SDT", "Siemens AG" },
+ { "SDX", "SDX Business Systems Ltd" },
+ { "SEA", "Seanix Technology Inc." },
+ { "SEB", "system elektronik GmbH" },
+ { "SEC", "Seiko Epson Corporation" },
+ { "SEE", "SeeColor Corporation" },
+ { "SEG", "DO NOT USE - SEG" },
+ { "SEI", "Seitz & Associates Inc" },
+ { "SEL", "Way2Call Communications" },
+ { "SEM", "Samsung Electronics Company Ltd" },
+ { "SEN", "Sencore" },
+ { "SEO", "SEOS Ltd" },
+ { "SEP", "SEP Eletronica Ltda." },
+ { "SER", "Sony Ericsson Mobile Communications Inc." },
+ { "SES", "Session Control LLC" },
+ { "SET", "SendTek Corporation" },
+ { "SFM", "TORNADO Company" },
+ { "SFT", "Mikroforum Ring 3" },
+ { "SGC", "Spectragraphics Corporation" },
+ { "SGD", "Sigma Designs, Inc." },
+ { "SGE", "Kansai Electric Company Ltd" },
+ { "SGI", "Scan Group Ltd" },
+ { "SGL", "Super Gate Technology Company Ltd" },
+ { "SGM", "SAGEM" },
+ { "SGO", "Logos Design A/S" },
+ { "SGT", "Stargate Technology" },
+ { "SGW", "Shanghai Guowei Science and Technology Co., Ltd." },
+ { "SGX", "Silicon Graphics Inc" },
+ { "SGZ", "Systec Computer GmbH" },
+ { "SHC", "ShibaSoku Co., Ltd." },
+ { "SHG", "Soft & Hardware development Goldammer GmbH" },
+ { "SHI", "Jiangsu Shinco Electronic Group Co., Ltd" },
+ { "SHP", "Sharp Corporation" },
+ { "SHR", "Digital Discovery" },
+ { "SHT", "Shin Ho Tech" },
+ { "SIA", "SIEMENS AG" },
+ { "SIB", "Sanyo Electric Company Ltd" },
+ { "SIC", "Sysmate Corporation" },
+ { "SID", "Seiko Instruments Information Devices Inc" },
+ { "SIE", "Siemens" },
+ { "SIG", "Sigma Designs Inc" },
+ { "SII", "Silicon Image, Inc." },
+ { "SIL", "Silicon Laboratories, Inc" },
+ { "SIM", "S3 Inc" },
+ { "SIN", "Singular Technology Co., Ltd." },
+ { "SIR", "Sirius Technologies Pty Ltd" },
+ { "SIS", "Silicon Integrated Systems Corporation" },
+ { "SIT", "Sitintel" },
+ { "SIU", "Seiko Instruments USA Inc" },
+ { "SIX", "Zuniq Data Corporation" },
+ { "SJE", "Sejin Electron Inc" },
+ { "SKD", "Schneider & Koch" },
+ { "SKI", "LLC SKTB “SKIT”" },
+ { "SKM", "Guangzhou Teclast Information Technology Limited" },
+ { "SKT", "Samsung Electro-Mechanics Company Ltd" },
+ { "SKW", "Skyworth" },
+ { "SKY", "SKYDATA S.P.A." },
+ { "SLA", "Systeme Lauer GmbH&Co KG" },
+ { "SLB", "Shlumberger Ltd" },
+ { "SLC", "Syslogic Datentechnik AG" },
+ { "SLF", "StarLeaf" },
+ { "SLH", "Silicon Library Inc." },
+ { "SLI", "Symbios Logic Inc" },
+ { "SLK", "Silitek Corporation" },
+ { "SLM", "Solomon Technology Corporation" },
+ { "SLR", "Schlumberger Technology Corporate" },
+ { "SLS", "Schnick-Schnack-Systems GmbH" },
+ { "SLT", "Salt Internatioinal Corp." },
+ { "SLX", "Specialix" },
+ { "SMA", "SMART Modular Technologies" },
+ { "SMB", "Schlumberger" },
+ { "SMC", "Standard Microsystems Corporation" },
+ { "SME", "Sysmate Company" },
+ { "SMI", "SpaceLabs Medical Inc" },
+ { "SMK", "SMK CORPORATION" },
+ { "SML", "Sumitomo Metal Industries, Ltd." },
+ { "SMM", "Shark Multimedia Inc" },
+ { "SMO", "STMicroelectronics" },
+ { "SMP", "Simple Computing" },
+ { "SMR", "B.& V. s.r.l." },
+ { "SMS", "Silicom Multimedia Systems Inc" },
+ { "SMT", "Silcom Manufacturing Tech Inc" },
+ { "SNC", "Sentronic International Corp." },
+ { "SNI", "Siemens Microdesign GmbH" },
+ { "SNK", "S&K Electronics" },
+ { "SNN", "SUNNY ELEKTRONIK" },
+ { "SNO", "SINOSUN TECHNOLOGY CO., LTD" },
+ { "SNP", "Siemens Nixdorf Info Systems" },
+ { "SNS", "Cirtech (UK) Ltd" },
+ { "SNT", "SuperNet Inc" },
+ { "SNV", "SONOVE GmbH" },
+ { "SNW", "Snell & Wilcox" },
+ { "SNX", "Sonix Comm. Ltd" },
+ { "SNY", "Sony" },
+ { "SOC", "Santec Corporation" },
+ { "SOI", "Silicon Optix Corporation" },
+ { "SOL", "Solitron Technologies Inc" },
+ { "SON", "Sony" },
+ { "SOR", "Sorcus Computer GmbH" },
+ { "SOT", "Sotec Company Ltd" },
+ { "SOY", "SOYO Group, Inc" },
+ { "SPC", "SpinCore Technologies, Inc" },
+ { "SPE", "SPEA Software AG" },
+ { "SPH", "G&W Instruments GmbH" },
+ { "SPI", "SPACE-I Co., Ltd." },
+ { "SPK", "SpeakerCraft" },
+ { "SPL", "Smart Silicon Systems Pty Ltd" },
+ { "SPN", "Sapience Corporation" },
+ { "SPR", "pmns GmbH" },
+ { "SPS", "Synopsys Inc" },
+ { "SPT", "Sceptre Tech Inc" },
+ { "SPU", "SIM2 Multimedia S.P.A." },
+ { "SPX", "Simplex Time Recorder Co." },
+ { "SQT", "Sequent Computer Systems Inc" },
+ { "SRC", "Integrated Tech Express Inc" },
+ { "SRD", "Setred" },
+ { "SRF", "Surf Communication Solutions Ltd" },
+ { "SRG", "Intuitive Surgical, Inc." },
+ { "SRS", "SR-Systems e.K." },
+ { "SRT", "SeeReal Technologies GmbH" },
+ { "SSC", "Sierra Semiconductor Inc" },
+ { "SSD", "FlightSafety International" },
+ { "SSE", "Samsung Electronic Co." },
+ { "SSI", "S-S Technology Inc" },
+ { "SSJ", "Sankyo Seiki Mfg.co., Ltd" },
+ { "SSL", "Shenzhen South-Top Computer Co., Ltd." },
+ { "SSP", "Spectrum Signal Proecessing Inc" },
+ { "SSS", "S3 Inc" },
+ { "SST", "SystemSoft Corporation" },
+ { "STA", "ST Electronics Systems Assembly Pte Ltd" },
+ { "STB", "STB Systems Inc" },
+ { "STC", "STAC Electronics" },
+ { "STD", "STD Computer Inc" },
+ { "STE", "SII Ido-Tsushin Inc" },
+ { "STF", "Starflight Electronics" },
+ { "STG", "StereoGraphics Corp." },
+ { "STH", "Semtech Corporation" },
+ { "STI", "Smart Tech Inc" },
+ { "STK", "SANTAK CORP." },
+ { "STL", "SigmaTel Inc" },
+ { "STM", "SGS Thomson Microelectronics" },
+ { "STN", "Samsung Electronics America" },
+ { "STO", "Stollmann E+V GmbH" },
+ { "STP", "StreamPlay Ltd" },
+ { "STQ", "Synthetel Corporation" },
+ { "STR", "Starlight Networks Inc" },
+ { "STS", "SITECSYSTEM CO., LTD." },
+ { "STT", "Star Paging Telecom Tech (Shenzhen) Co. Ltd." },
+ { "STU", "Sentelic Corporation" },
+ { "STW", "Starwin Inc." },
+ { "STX", "ST-Ericsson" },
+ { "STY", "SDS Technologies" },
+ { "SUB", "Subspace Comm. Inc" },
+ { "SUM", "Summagraphics Corporation" },
+ { "SUN", "Sun Electronics Corporation" },
+ { "SUP", "Supra Corporation" },
+ { "SUR", "Surenam Computer Corporation" },
+ { "SVA", "SGEG" },
+ { "SVC", "Intellix Corp." },
+ { "SVD", "SVD Computer" },
+ { "SVI", "Sun Microsystems" },
+ { "SVR", "Sensics, Inc." },
+ { "SVS", "SVSI" },
+ { "SVT", "SEVIT Co., Ltd." },
+ { "SWC", "Software Café" },
+ { "SWI", "Sierra Wireless Inc." },
+ { "SWL", "Sharedware Ltd" },
+ { "SWO", "Guangzhou Shirui Electronics Co., Ltd." },
+ { "SWS", "Static" },
+ { "SWT", "Software Technologies Group,Inc." },
+ { "SXB", "Syntax-Brillian" },
+ { "SXD", "Silex technology, Inc." },
+ { "SXG", "SELEX GALILEO" },
+ { "SXI", "Silex Inside" },
+ { "SXL", "SolutionInside" },
+ { "SXT", "SHARP TAKAYA ELECTRONIC INDUSTRY CO.,LTD." },
+ { "SYC", "Sysmic" },
+ { "SYE", "SY Electronics Ltd" },
+ { "SYK", "Stryker Communications" },
+ { "SYL", "Sylvania Computer Products" },
+ { "SYM", "Symicron Computer Communications Ltd." },
+ { "SYN", "Synaptics Inc" },
+ { "SYP", "SYPRO Co Ltd" },
+ { "SYS", "Sysgration Ltd" },
+ { "SYT", "Seyeon Tech Company Ltd" },
+ { "SYV", "SYVAX Inc" },
+ { "SYX", "Prime Systems, Inc." },
+ { "SZM", "Shenzhen MTC Co., Ltd" },
+ { "TAA", "Tandberg" },
+ { "TAB", "Todos Data System AB" },
+ { "TAG", "Teles AG" },
+ { "TAI", "Toshiba America Info Systems Inc" },
+ { "TAM", "Tamura Seisakusyo Ltd" },
+ { "TAS", "Taskit Rechnertechnik GmbH" },
+ { "TAT", "Teleliaison Inc" },
+ { "TAV", "Thales Avionics" },
+ { "TAX", "Taxan (Europe) Ltd" },
+ { "TBB", "Triple S Engineering Inc" },
+ { "TBC", "Turbo Communication, Inc" },
+ { "TBS", "Turtle Beach System" },
+ { "TCC", "Tandon Corporation" },
+ { "TCD", "Taicom Data Systems Co., Ltd." },
+ { "TCE", "Century Corporation" },
+ { "TCF", "Televic Conference" },
+ { "TCH", "Interaction Systems, Inc" },
+ { "TCI", "Tulip Computers Int'l B.V." },
+ { "TCJ", "TEAC America Inc" },
+ { "TCL", "Technical Concepts Ltd" },
+ { "TCM", "3Com Corporation" },
+ { "TCN", "Tecnetics (PTY) Ltd" },
+ { "TCO", "Thomas-Conrad Corporation" },
+ { "TCR", "Thomson Consumer Electronics" },
+ { "TCS", "Tatung Company of America Inc" },
+ { "TCT", "Telecom Technology Centre Co. Ltd." },
+ { "TCX", "FREEMARS Heavy Industries" },
+ { "TDC", "Teradici" },
+ { "TDD", "Tandberg Data Display AS" },
+ { "TDG", "Six15 Technologies" },
+ { "TDM", "Tandem Computer Europe Inc" },
+ { "TDP", "3D Perception" },
+ { "TDS", "Tri-Data Systems Inc" },
+ { "TDT", "TDT" },
+ { "TDV", "TDVision Systems, Inc." },
+ { "TDY", "Tandy Electronics" },
+ { "TEA", "TEAC System Corporation" },
+ { "TEC", "Tecmar Inc" },
+ { "TEK", "Tektronix Inc" },
+ { "TEL", "Promotion and Display Technology Ltd." },
+ { "TEN", "Tencent" },
+ { "TER", "TerraTec Electronic GmbH" },
+ { "TET", "TETRADYNE CO., LTD." },
+ { "TEV", "Televés, S.A." },
+ { "TEZ", "Tech Source Inc." },
+ { "TGC", "Toshiba Global Commerce Solutions, Inc." },
+ { "TGI", "TriGem Computer Inc" },
+ { "TGM", "TriGem Computer,Inc." },
+ { "TGS", "Torus Systems Ltd" },
+ { "TGV", "Grass Valley Germany GmbH" },
+ { "TGW", "TECHNOGYM S.p.A." },
+ { "THN", "Thundercom Holdings Sdn. Bhd." },
+ { "TIC", "Trigem KinfoComm" },
+ { "TIL", "Technical Illusions Inc." },
+ { "TIP", "TIPTEL AG" },
+ { "TIV", "OOO Technoinvest" },
+ { "TIX", "Tixi.Com GmbH" },
+ { "TKC", "Taiko Electric Works.LTD" },
+ { "TKG", "Tek Gear" },
+ { "TKN", "Teknor Microsystem Inc" },
+ { "TKO", "TouchKo, Inc." },
+ { "TKS", "TimeKeeping Systems, Inc." },
+ { "TLA", "Ferrari Electronic GmbH" },
+ { "TLD", "Telindus" },
+ { "TLE", "Zhejiang Tianle Digital Electric Co., Ltd." },
+ { "TLF", "Teleforce.,co,ltd" },
+ { "TLI", "TOSHIBA TELI CORPORATION" },
+ { "TLK", "Telelink AG" },
+ { "TLL", "Thinklogical" },
+ { "TLN", "Techlogix Networx" },
+ { "TLS", "Teleste Educational OY" },
+ { "TLT", "Dai Telecom S.p.A." },
+ { "TLV", "S3 Inc" },
+ { "TLX", "Telxon Corporation" },
+ { "TMC", "Techmedia Computer Systems Corporation" },
+ { "TME", "AT&T Microelectronics" },
+ { "TMI", "Texas Microsystem" },
+ { "TMM", "Time Management, Inc." },
+ { "TMO", "Terumo Corporation" },
+ { "TMR", "Taicom International Inc" },
+ { "TMS", "Trident Microsystems Ltd" },
+ { "TMT", "T-Metrics Inc." },
+ { "TMX", "Thermotrex Corporation" },
+ { "TNC", "TNC Industrial Company Ltd" },
+ { "TNJ", "DO NOT USE - TNJ" },
+ { "TNM", "TECNIMAGEN SA" },
+ { "TNY", "Tennyson Tech Pty Ltd" },
+ { "TOE", "TOEI Electronics Co., Ltd." },
+ { "TOG", "The OPEN Group" },
+ { "TOL", "TCL Corporation" },
+ { "TOM", "Ceton Corporation" },
+ { "TON", "TONNA" },
+ { "TOP", "Orion Communications Co., Ltd." },
+ { "TOS", "Dynabook Inc." },
+ { "TOU", "Touchstone Technology" },
+ { "TPC", "Touch Panel Systems Corporation" },
+ { "TPD", "Times (Shanghai) Computer Co., Ltd." },
+ { "TPE", "Technology Power Enterprises Inc" },
+ { "TPJ", "Junnila" },
+ { "TPK", "TOPRE CORPORATION" },
+ { "TPR", "Topro Technology Inc" },
+ { "TPS", "Teleprocessing Systeme GmbH" },
+ { "TPT", "Thruput Ltd" },
+ { "TPV", "Top Victory Electronics ( Fujian ) Company Ltd" },
+ { "TPZ", "Ypoaz Systems Inc" },
+ { "TRA", "TriTech Microelectronics International" },
+ { "TRB", "Triumph Board a.s." },
+ { "TRC", "Trioc AB" },
+ { "TRD", "Trident Microsystem Inc" },
+ { "TRE", "Tremetrics" },
+ { "TRI", "Tricord Systems" },
+ { "TRL", "Royal Information" },
+ { "TRM", "Tekram Technology Company Ltd" },
+ { "TRN", "Datacommunicatie Tron B.V." },
+ { "TRP", "TRAPEZE GROUP" },
+ { "TRS", "Torus Systems Ltd" },
+ { "TRT", "Tritec Electronic AG" },
+ { "TRU", "Aashima Technology B.V." },
+ { "TRV", "Trivisio Prototyping GmbH" },
+ { "TRX", "Trex Enterprises" },
+ { "TSB", "Toshiba America Info Systems Inc" },
+ { "TSC", "Sanyo Electric Company Ltd" },
+ { "TSD", "TechniSat Digital GmbH" },
+ { "TSE", "Tottori Sanyo Electric" },
+ { "TSF", "Racal-Airtech Software Forge Ltd" },
+ { "TSG", "The Software Group Ltd" },
+ { "TSH", "ELAN MICROELECTRONICS CORPORATION" },
+ { "TSI", "TeleVideo Systems" },
+ { "TSL", "Tottori SANYO Electric Co., Ltd." },
+ { "TSP", "U.S. Navy" },
+ { "TST", "Transtream Inc" },
+ { "TSV", "TRANSVIDEO" },
+ { "TSW", "VRSHOW Technology Limited" },
+ { "TSY", "TouchSystems" },
+ { "TTA", "Topson Technology Co., Ltd." },
+ { "TTB", "National Semiconductor Japan Ltd" },
+ { "TTC", "Telecommunications Techniques Corporation" },
+ { "TTE", "TTE, Inc." },
+ { "TTI", "Trenton Terminals Inc" },
+ { "TTK", "Totoku Electric Company Ltd" },
+ { "TTL", "2-Tel B.V" },
+ { "TTP", "Toshiba Corporation" },
+ { "TTS", "TechnoTrend Systemtechnik GmbH" },
+ { "TTX", "Taitex Corporation" },
+ { "TTY", "TRIDELITY Display Solutions GmbH" },
+ { "TUA", "T+A elektroakustik GmbH" },
+ { "TUT", "Tut Systems" },
+ { "TVD", "Tecnovision" },
+ { "TVI", "Truevision" },
+ { "TVL", "Total Vision LTD" },
+ { "TVM", "Taiwan Video & Monitor Corporation" },
+ { "TVO", "TV One Ltd" },
+ { "TVR", "TV Interactive Corporation" },
+ { "TVS", "TVS Electronics Limited" },
+ { "TVV", "TV1 GmbH" },
+ { "TWA", "Tidewater Association" },
+ { "TWE", "Kontron Electronik" },
+ { "TWH", "Twinhead International Corporation" },
+ { "TWI", "Easytel oy" },
+ { "TWK", "TOWITOKO electronics GmbH" },
+ { "TWX", "TEKWorx Limited" },
+ { "TXL", "Trixel Ltd" },
+ { "TXN", "Texas Insturments" },
+ { "TXT", "Textron Defense System" },
+ { "TYN", "Tyan Computer Corporation" },
+ { "UAS", "Ultima Associates Pte Ltd" },
+ { "UBI", "Ungermann-Bass Inc" },
+ { "UBL", "Ubinetics Ltd." },
+ { "UBU", "Canonical Ltd." },
+ { "UDN", "Uniden Corporation" },
+ { "UEC", "Ultima Electronics Corporation" },
+ { "UEG", "Elitegroup Computer Systems Company Ltd" },
+ { "UEI", "Universal Electronics Inc" },
+ { "UET", "Universal Empowering Technologies" },
+ { "UFG", "UNIGRAF-USA" },
+ { "UFO", "UFO Systems Inc" },
+ { "UHB", "XOCECO" },
+ { "UIC", "Uniform Industrial Corporation" },
+ { "UJR", "Ueda Japan Radio Co., Ltd." },
+ { "ULT", "Ultra Network Tech" },
+ { "UMC", "United Microelectr Corporation" },
+ { "UMG", "Umezawa Giken Co.,Ltd" },
+ { "UMM", "Universal Multimedia" },
+ { "UMT", "UltiMachine" },
+ { "UNA", "Unisys DSD" },
+ { "UNB", "Unisys Corporation" },
+ { "UNC", "Unisys Corporation" },
+ { "UND", "Unisys Corporation" },
+ { "UNE", "Unisys Corporation" },
+ { "UNF", "Unisys Corporation" },
+ { "UNI", "Uniform Industry Corp." },
+ { "UNM", "Unisys Corporation" },
+ { "UNO", "Unisys Corporation" },
+ { "UNP", "Unitop" },
+ { "UNS", "Unisys Corporation" },
+ { "UNT", "Unisys Corporation" },
+ { "UNY", "Unicate" },
+ { "UPP", "UPPI" },
+ { "UPS", "Systems Enhancement" },
+ { "URD", "Video Computer S.p.A." },
+ { "USA", "Utimaco Safeware AG" },
+ { "USD", "U.S. Digital Corporation" },
+ { "USE", "U. S. Electronics Inc." },
+ { "USI", "Universal Scientific Industrial Co., Ltd." },
+ { "USR", "U.S. Robotics Inc" },
+ { "UTC", "Unicompute Technology Co., Ltd." },
+ { "UTD", "Up to Date Tech" },
+ { "UWC", "Uniwill Computer Corp." },
+ { "VAD", "Vaddio, LLC" },
+ { "VAI", "VAIO Corporation" },
+ { "VAL", "Valence Computing Corporation" },
+ { "VAR", "Varian Australia Pty Ltd" },
+ { "VAT", "VADATECH INC" },
+ { "VBR", "VBrick Systems Inc." },
+ { "VBT", "Valley Board Ltda" },
+ { "VCC", "Virtual Computer Corporation" },
+ { "VCI", "VistaCom Inc" },
+ { "VCJ", "Victor Company of Japan, Limited" },
+ { "VCM", "Vector Magnetics, LLC" },
+ { "VCX", "VCONEX" },
+ { "VDA", "Victor Data Systems" },
+ { "VDC", "VDC Display Systems" },
+ { "VDM", "Vadem" },
+ { "VDO", "Video & Display Oriented Corporation" },
+ { "VDS", "Vidisys GmbH & Company" },
+ { "VDT", "Viditec, Inc." },
+ { "VEC", "Vector Informatik GmbH" },
+ { "VEK", "Vektrex" },
+ { "VES", "Vestel Elektronik Sanayi ve Ticaret A. S." },
+ { "VFI", "VeriFone Inc" },
+ { "VHI", "Macrocad Development Inc." },
+ { "VIA", "VIA Tech Inc" },
+ { "VIB", "Tatung UK Ltd" },
+ { "VIC", "Victron B.V." },
+ { "VID", "Ingram Macrotron Germany" },
+ { "VIK", "Viking Connectors" },
+ { "VIM", "Via Mons Ltd." },
+ { "VIN", "Vine Micros Ltd" },
+ { "VIR", "Visual Interface, Inc" },
+ { "VIS", "Visioneer" },
+ { "VIT", "Visitech AS" },
+ { "VIZ", "VIZIO, Inc" },
+ { "VLB", "ValleyBoard Ltda." },
+ { "VLC", "VersaLogic Corporation" },
+ { "VLK", "Vislink International Ltd" },
+ { "VLM", "LENOVO BEIJING CO. LTD." },
+ { "VLT", "VideoLan Technologies" },
+ { "VLV", "Valve Corporation" },
+ { "VMI", "Vermont Microsystems" },
+ { "VML", "Vine Micros Limited" },
+ { "VMW", "VMware Inc.," },
+ { "VNC", "Vinca Corporation" },
+ { "VOB", "MaxData Computer AG" },
+ { "VPI", "Video Products Inc" },
+ { "VPR", "Best Buy" },
+ { "VPX", "VPixx Technologies Inc." },
+ { "VQ@", "Vision Quest" },
+ { "VRC", "Virtual Resources Corporation" },
+ { "VRG", "VRgineers, Inc." },
+ { "VRM", "VRmagic Holding AG" },
+ { "VRS", "VRstudios, Inc." },
+ { "VRT", "Varjo Technologies" },
+ { "VSC", "ViewSonic Corporation" },
+ { "VSD", "3M" },
+ { "VSI", "VideoServer" },
+ { "VSN", "Ingram Macrotron" },
+ { "VSP", "Vision Systems GmbH" },
+ { "VSR", "V-Star Electronics Inc." },
+ { "VTB", "Videotechnik Breithaupt" },
+ { "VTC", "VTel Corporation" },
+ { "VTG", "Voice Technologies Group Inc" },
+ { "VTI", "VLSI Tech Inc" },
+ { "VTK", "Viewteck Co., Ltd." },
+ { "VTL", "Vivid Technology Pte Ltd" },
+ { "VTM", "Miltope Corporation" },
+ { "VTN", "VIDEOTRON CORP." },
+ { "VTS", "VTech Computers Ltd" },
+ { "VTV", "VATIV Technologies" },
+ { "VTX", "Vestax Corporation" },
+ { "VUT", "Vutrix (UK) Ltd" },
+ { "VWB", "Vweb Corp." },
+ { "WAC", "Wacom Tech" },
+ { "WAL", "Wave Access" },
+ { "WAN", "DO NOT USE - WAN" },
+ { "WAV", "Wavephore" },
+ { "WBN", "MicroSoftWare" },
+ { "WBS", "WB Systemtechnik GmbH" },
+ { "WCI", "Wisecom Inc" },
+ { "WCS", "Woodwind Communications Systems Inc" },
+ { "WDC", "Western Digital" },
+ { "WDE", "Westinghouse Digital Electronics" },
+ { "WEB", "WebGear Inc" },
+ { "WEC", "Winbond Electronics Corporation" },
+ { "WEL", "W-DEV" },
+ { "WEY", "WEY Design AG" },
+ { "WHI", "Whistle Communications" },
+ { "WII", "Innoware Inc" },
+ { "WIL", "WIPRO Information Technology Ltd" },
+ { "WIN", "Wintop Technology Inc" },
+ { "WIP", "Wipro Infotech" },
+ { "WKH", "Uni-Take Int'l Inc." },
+ { "WLD", "Wildfire Communications Inc" },
+ { "WLF", "WOLF Advanced Technology" },
+ { "WML", "Wolfson Microelectronics Ltd" },
+ { "WMO", "Westermo Teleindustri AB" },
+ { "WMT", "Winmate Communication Inc" },
+ { "WNI", "WillNet Inc." },
+ { "WNV", "Winnov L.P." },
+ { "WNX", "Diebold Nixdorf Systems GmbH" },
+ { "WPA", "Matsushita Communication Industrial Co., Ltd." },
+ { "WPI", "Wearnes Peripherals International (Pte) Ltd" },
+ { "WRC", "WiNRADiO Communications" },
+ { "WSC", "CIS Technology Inc" },
+ { "WSP", "Wireless And Smart Products Inc." },
+ { "WST", "Wistron Corporation" },
+ { "WTC", "ACC Microelectronics" },
+ { "WTI", "WorkStation Tech" },
+ { "WTK", "Wearnes Thakral Pte" },
+ { "WTS", "Restek Electric Company Ltd" },
+ { "WVM", "Wave Systems Corporation" },
+ { "WVV", "WolfVision GmbH" },
+ { "WWP", "Wipotec Wiege- und Positioniersysteme GmbH" },
+ { "WWV", "World Wide Video, Inc." },
+ { "WXT", "Woxter Technology Co. Ltd" },
+ { "WYR", "WyreStorm Technologies LLC" },
+ { "WYS", "Wyse Technology" },
+ { "WYT", "Wooyoung Image & Information Co.,Ltd." },
+ { "XAC", "XAC Automation Corp" },
+ { "XAD", "Alpha Data" },
+ { "XDM", "XDM Ltd." },
+ { "XER", "DO NOT USE - XER" },
+ { "XES", "Extreme Engineering Solutions, Inc." },
+ { "XFG", "Jan Strapko - FOTO" },
+ { "XFO", "EXFO Electro Optical Engineering" },
+ { "XIN", "Xinex Networks Inc" },
+ { "XIO", "Xiotech Corporation" },
+ { "XIR", "Xirocm Inc" },
+ { "XIT", "Xitel Pty ltd" },
+ { "XLX", "Xilinx, Inc." },
+ { "XMM", "C3PO S.L." },
+ { "XNT", "XN Technologies, Inc." },
+ { "XOC", "DO NOT USE - XOC" },
+ { "XQU", "SHANGHAI SVA-DAV ELECTRONICS CO., LTD" },
+ { "XRC", "Xircom Inc" },
+ { "XRO", "XORO ELECTRONICS (CHENGDU) LIMITED" },
+ { "XSN", "Xscreen AS" },
+ { "XST", "XS Technologies Inc" },
+ { "XSY", "XSYS" },
+ { "XTD", "Icuiti Corporation" },
+ { "XTE", "X2E GmbH" },
+ { "XTL", "Crystal Computer" },
+ { "XTN", "X-10 (USA) Inc" },
+ { "XYC", "Xycotec Computer GmbH" },
+ { "XYE", "Shenzhen Zhuona Technology Co., Ltd." },
+ { "YED", "Y-E Data Inc" },
+ { "YHQ", "Yokogawa Electric Corporation" },
+ { "YHW", "Exacom SA" },
+ { "YMH", "Yamaha Corporation" },
+ { "YOW", "American Biometric Company" },
+ { "ZAN", "Zandar Technologies plc" },
+ { "ZAX", "Zefiro Acoustics" },
+ { "ZAZ", "ZeeVee, Inc." },
+ { "ZBR", "Zebra Technologies International, LLC" },
+ { "ZBX", "Zebax Technologies" },
+ { "ZCT", "ZeitControl cardsystems GmbH" },
+ { "ZDS", "Zenith Data Systems" },
+ { "ZEN", "ZENIC Inc." },
+ { "ZGT", "Zenith Data Systems" },
+ { "ZIC", "Nationz Technologies Inc." },
+ { "ZMC", "HangZhou ZMCHIVIN" },
+ { "ZMT", "Zalman Tech Co., Ltd." },
+ { "ZMZ", "Z Microsystems" },
+ { "ZNI", "Zetinet Inc" },
+ { "ZNX", "Znyx Adv. Systems" },
+ { "ZOW", "Zowie Intertainment, Inc" },
+ { "ZRN", "Zoran Corporation" },
+ { "ZSE", "Zenith Data Systems" },
+ { "ZTC", "ZyDAS Technology Corporation" },
+ { "ZTE", "ZTE Corporation" },
+ { "ZTI", "Zoom Telephonics Inc" },
+ { "ZTM", "ZT Group Int'l Inc." },
+ { "ZTT", "Z3 Technology" },
+ { "ZWE", "Shenzhen Zowee Technology Co., LTD" },
+ { "ZYD", "Zydacron Inc" },
+ { "ZYP", "Zypcom Inc" },
+ { "ZYT", "Zytex Computers" },
+ { "ZYX", "Zyxel" },
+ { "ZZZ", "Boca Research Inc" },
+};
+
+QT_END_NAMESPACE
+
+#endif // QEDIDVENDORTABLE_P_H
diff --git a/src/gui/util/qgraphicsframecapture.cpp b/src/gui/util/qgraphicsframecapture.cpp
new file mode 100644
index 0000000000..e49fb83008
--- /dev/null
+++ b/src/gui/util/qgraphicsframecapture.cpp
@@ -0,0 +1,123 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qgraphicsframecapture_p.h"
+#if (defined (Q_OS_WIN) || defined(Q_OS_LINUX)) && QT_CONFIG(library)
+#include "qgraphicsframecapturerenderdoc_p_p.h"
+#elif QT_CONFIG(metal)
+#include "qgraphicsframecapturemetal_p_p.h"
+#else
+#include "qgraphicsframecapture_p_p.h"
+#endif
+
+#include <QtCore/qstandardpaths.h>
+#include <QtCore/qcoreapplication.h>
+
+QT_BEGIN_NAMESPACE
+
+QGraphicsFrameCapturePrivate::QGraphicsFrameCapturePrivate()
+ : m_capturePath(QStandardPaths::writableLocation(QStandardPaths::TempLocation) +
+ QStringLiteral("/") + QCoreApplication::applicationName() +
+ QStringLiteral("/captures")),
+ m_capturePrefix(QCoreApplication::applicationName())
+{
+
+}
+
+QGraphicsFrameCapture::QGraphicsFrameCapture()
+{
+#if (defined (Q_OS_WIN) || defined(Q_OS_LINUX)) && QT_CONFIG(library)
+ d.reset(new QGraphicsFrameCaptureRenderDoc);
+#elif QT_CONFIG(metal)
+ d.reset(new QGraphicsFrameCaptureMetal);
+#endif
+}
+
+QGraphicsFrameCapture::~QGraphicsFrameCapture()
+{
+
+}
+
+void QGraphicsFrameCapture::setRhi(QRhi *rhi)
+{
+ if (!d.isNull())
+ d->setRhi(rhi);
+}
+
+void QGraphicsFrameCapture::startCaptureFrame()
+{
+ if (!d.isNull())
+ d->startCaptureFrame();
+}
+
+void QGraphicsFrameCapture::endCaptureFrame()
+{
+ if (!d.isNull())
+ d->endCaptureFrame();
+}
+
+QString QGraphicsFrameCapture::capturePath() const
+{
+ if (!d.isNull())
+ return d->capturePath();
+ return QString();
+}
+
+void QGraphicsFrameCapture::setCapturePath(const QString &path)
+{
+ if (!d.isNull())
+ d->setCapturePath(path);
+}
+
+QString QGraphicsFrameCapture::capturePrefix() const
+{
+ if (!d.isNull())
+ return d->capturePrefix();
+ return QString();
+}
+
+void QGraphicsFrameCapture::setCapturePrefix(const QString &prefix)
+{
+ if (!d.isNull())
+ d->setCapturePrefix(prefix);
+}
+
+QString QGraphicsFrameCapture::capturedFileName()
+{
+ if (!d.isNull())
+ return d->capturedFileName();
+
+ return QString();
+}
+
+QStringList QGraphicsFrameCapture::capturedFilesNames()
+{
+ if (!d.isNull())
+ return d->capturedFilesNames();
+
+ return QStringList();
+}
+
+bool QGraphicsFrameCapture::isLoaded() const
+{
+ if (!d.isNull())
+ return d->initialized();
+
+ return false;
+}
+
+bool QGraphicsFrameCapture::isCapturing() const
+{
+ if (!d.isNull())
+ return d->isCapturing();
+
+ return false;
+}
+
+void QGraphicsFrameCapture::openCapture() const
+{
+ if (!d.isNull())
+ d->openCapture();
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/util/qgraphicsframecapture_p.h b/src/gui/util/qgraphicsframecapture_p.h
new file mode 100644
index 0000000000..fef37d2869
--- /dev/null
+++ b/src/gui/util/qgraphicsframecapture_p.h
@@ -0,0 +1,55 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QGRAPHICSFRAMECAPTURE_P_H
+#define QGRAPHICSFRAMECAPTURE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qscopedpointer.h>
+#include <QtGui/qtguiglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QGraphicsFrameCapturePrivate;
+class QRhi;
+
+class Q_GUI_EXPORT QGraphicsFrameCapture
+{
+public:
+ QGraphicsFrameCapture();
+ ~QGraphicsFrameCapture();
+
+ void setRhi(QRhi *rhi);
+ void startCaptureFrame();
+ void endCaptureFrame();
+
+ QString capturePath() const;
+ void setCapturePath(const QString &path);
+
+ QString capturePrefix() const;
+ void setCapturePrefix(const QString &prefix);
+
+ QString capturedFileName();
+ QStringList capturedFilesNames();
+
+ bool isLoaded() const;
+ bool isCapturing() const;
+ void openCapture() const;
+
+private:
+ QScopedPointer<QGraphicsFrameCapturePrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QGRAPHICSFRAMECAPTURE_P_H
diff --git a/src/gui/util/qgraphicsframecapture_p_p.h b/src/gui/util/qgraphicsframecapture_p_p.h
new file mode 100644
index 0000000000..f8dbd2ca1d
--- /dev/null
+++ b/src/gui/util/qgraphicsframecapture_p_p.h
@@ -0,0 +1,67 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QGRAPHICSFRAMECAPTURE_P_P_H
+#define QGRAPHICSFRAMECAPTURE_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qnamespace.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qstringlist.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(lcGraphicsFrameCapture)
+
+class QRhi;
+struct QRhiNativeHandles;
+
+class QGraphicsFrameCapturePrivate
+{
+public:
+ QGraphicsFrameCapturePrivate() ;
+ virtual ~QGraphicsFrameCapturePrivate() = default;
+
+ virtual void setRhi(QRhi *rhi) = 0;
+ virtual void startCaptureFrame() = 0;
+ virtual void endCaptureFrame() = 0;
+
+ QString capturePath() const { return m_capturePath; };
+ virtual void setCapturePath(const QString &path) { m_capturePath = path; }
+
+ QString capturePrefix() const { return m_capturePrefix; }
+ virtual void setCapturePrefix(const QString &prefix) { m_capturePrefix = prefix; }
+
+ virtual QString capturedFileName() const
+ {
+ return !m_capturedFilesNames.isEmpty() ? m_capturedFilesNames.last() : QString();
+ }
+ virtual QStringList capturedFilesNames() const { return m_capturedFilesNames; }
+
+ virtual bool initialized() const = 0;
+ virtual bool isCapturing() const = 0;
+ virtual void openCapture() = 0;
+
+protected:
+ QRhi *m_rhi = nullptr;
+ QRhiNativeHandles *m_rhiHandles = nullptr;
+ void *m_nativeHandle = nullptr;
+ QString m_capturePath;
+ QString m_capturePrefix;
+ QStringList m_capturedFilesNames;
+};
+
+QT_END_NAMESPACE
+
+#endif // QGRAPHICSFRAMECAPTURE_P_P_H
diff --git a/src/gui/util/qgraphicsframecapturemetal.mm b/src/gui/util/qgraphicsframecapturemetal.mm
new file mode 100644
index 0000000000..b0ff0bab2b
--- /dev/null
+++ b/src/gui/util/qgraphicsframecapturemetal.mm
@@ -0,0 +1,169 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qgraphicsframecapturemetal_p_p.h"
+#include <QtCore/qurl.h>
+#include "Metal/Metal.h"
+#include "qglobal.h"
+#include <QtGui/rhi/qrhi.h>
+#include <QtGui/rhi/qrhi_platform.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcGraphicsFrameCapture, "qt.gui.graphicsframecapture")
+
+#if __has_feature(objc_arc)
+#error ARC not supported
+#endif
+
+uint QGraphicsFrameCaptureMetal::frameNumber = 0;
+
+QGraphicsFrameCaptureMetal::QGraphicsFrameCaptureMetal()
+{
+ qputenv("METAL_CAPTURE_ENABLED", QByteArrayLiteral("1"));
+
+ m_captureDescriptor = [MTLCaptureDescriptor new];
+}
+
+QGraphicsFrameCaptureMetal::~QGraphicsFrameCaptureMetal()
+{
+#if defined(Q_OS_MACOS) && QT_CONFIG(process)
+ if (m_process) {
+ m_process->terminate();
+ delete m_process;
+ }
+#endif
+ [m_captureDescriptor release];
+}
+
+void QGraphicsFrameCaptureMetal::setRhi(QRhi *rhi)
+{
+ if (!rhi)
+ return;
+
+ QRhi::Implementation backend = rhi->backend();
+ const QRhiNativeHandles *nh = rhi->nativeHandles();
+
+ switch (backend) {
+ case QRhi::Implementation::Metal: {
+ const QRhiMetalNativeHandles *mtlnh = static_cast<const QRhiMetalNativeHandles *>(nh);
+ if (mtlnh->cmdQueue) {
+ m_captureDescriptor.captureObject = mtlnh->cmdQueue;
+ } else if (mtlnh->dev) {
+ m_captureDescriptor.captureObject = mtlnh->dev;
+ } else {
+ qCWarning(lcGraphicsFrameCapture) << "No valid Metal Device or Metal Command Queue found";
+ m_initialized = false;
+ return;
+ }
+ break;
+ }
+ default: {
+ qCWarning(lcGraphicsFrameCapture) << "Invalid handles were provided. MTLCaptureManager works only with Metal API";
+ m_initialized = false;
+ return;
+ break;
+ }
+ }
+
+ if (!m_captureManager) {
+ m_captureManager = MTLCaptureManager.sharedCaptureManager;
+ bool supportDocs = [m_captureManager supportsDestination:MTLCaptureDestinationGPUTraceDocument];
+ if (supportDocs) {
+ m_captureDescriptor.destination = MTLCaptureDestinationGPUTraceDocument;
+ m_initialized = true;
+ }
+ }
+}
+
+void QGraphicsFrameCaptureMetal::startCaptureFrame()
+{
+ if (!initialized()) {
+ qCWarning(lcGraphicsFrameCapture) << "Capturing on Metal was not initialized. Starting capturing can not be done.";
+ return;
+ }
+
+ if (isCapturing()) {
+ qCWarning(lcGraphicsFrameCapture) << "A frame capture is already in progress,"
+ "will not initiate another one until QGraphicsFrameCapture::endCaptureFrame is called.";
+ return;
+ }
+
+ updateCaptureFileName();
+ NSError *error;
+ if (![m_captureManager startCaptureWithDescriptor:m_captureDescriptor error:&error]) {
+ QString errorMsg = QString::fromNSString(error.localizedDescription);
+ qCWarning(lcGraphicsFrameCapture, "Failed to start capture : %s", qPrintable(errorMsg));
+ }
+}
+
+void QGraphicsFrameCaptureMetal::endCaptureFrame()
+{
+ if (!initialized()) {
+ qCWarning(lcGraphicsFrameCapture) << "Capturing on Metal was not initialized. End capturing can not be done.";
+ return;
+ }
+
+ if (!isCapturing()) {
+ qCWarning(lcGraphicsFrameCapture) << "A call to QGraphicsFrameCapture::endCaptureFrame can not be done"
+ " without a call to QGraphicsFrameCapture::startCaptureFrame";
+ return;
+ }
+
+ [m_captureManager stopCapture];
+ m_capturedFilesNames.append(QString::fromNSString(m_traceURL.path));
+ frameNumber++;
+}
+
+bool QGraphicsFrameCaptureMetal::initialized() const
+{
+ return m_initialized;
+}
+
+bool QGraphicsFrameCaptureMetal::isCapturing() const
+{
+ if (!initialized()) {
+ qCWarning(lcGraphicsFrameCapture) << "Capturing on Metal was not initialized. Can not query if capturing is in progress or not.";
+ return false;
+ }
+
+ return [m_captureManager isCapturing];
+}
+
+void QGraphicsFrameCaptureMetal::openCapture()
+{
+#if defined(Q_OS_MACOS)
+#if !QT_CONFIG(process)
+ qFatal("QGraphicsFrameCapture requires QProcess on macOS");
+#else
+ if (!initialized()) {
+ qCWarning(lcGraphicsFrameCapture) << "Capturing on Metal was not initialized. Can not open XCode with a valid capture.";
+ return;
+ }
+
+ if (!m_process) {
+ m_process = new QProcess();
+ m_process->setProgram(QStringLiteral("xed"));
+ QStringList args;
+ args.append(QUrl::fromNSURL(m_traceURL).toLocalFile());
+ m_process->setArguments(args);
+ }
+
+ m_process->kill();
+ m_process->start();
+#endif
+#endif
+}
+
+void QGraphicsFrameCaptureMetal::updateCaptureFileName()
+{
+ m_traceURL = QUrl::fromLocalFile(m_capturePath + "/" + m_capturePrefix + "_" + QString::number(frameNumber) + ".gputrace").toNSURL();
+ // We need to remove the trace file if it already existed else MTLCaptureManager
+ // will fail to.
+ if ([NSFileManager.defaultManager fileExistsAtPath:m_traceURL.path])
+ [NSFileManager.defaultManager removeItemAtURL:m_traceURL error:nil];
+
+ m_captureDescriptor.outputURL = m_traceURL;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/util/qgraphicsframecapturemetal_p_p.h b/src/gui/util/qgraphicsframecapturemetal_p_p.h
new file mode 100644
index 0000000000..d703949de2
--- /dev/null
+++ b/src/gui/util/qgraphicsframecapturemetal_p_p.h
@@ -0,0 +1,57 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QGRAPHICSFRAMEDECAPTUREMETAL_P_P_H
+#define QGRAPHICSFRAMEDECAPTUREMETAL_P_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 "qgraphicsframecapture_p_p.h"
+#include <QtCore/qmutex.h>
+#ifdef Q_OS_MACOS
+#include <QtCore/qprocess.h>
+#endif
+
+Q_FORWARD_DECLARE_OBJC_CLASS(MTLCaptureManager);
+Q_FORWARD_DECLARE_OBJC_CLASS(MTLCaptureDescriptor);
+Q_FORWARD_DECLARE_OBJC_CLASS(NSURL);
+
+QT_BEGIN_NAMESPACE
+
+class QGraphicsFrameCaptureMetal : public QGraphicsFrameCapturePrivate
+{
+public:
+ QGraphicsFrameCaptureMetal();
+ ~QGraphicsFrameCaptureMetal();
+
+ void setRhi(QRhi *rhi) override;
+ void startCaptureFrame() override;
+ void endCaptureFrame() override;
+ bool initialized() const override;
+ bool isCapturing() const override;
+ void openCapture() override;
+
+private:
+ void updateCaptureFileName();
+#if defined(Q_OS_MACOS) && QT_CONFIG(process)
+ QProcess *m_process = nullptr;
+#endif
+ MTLCaptureManager *m_captureManager = nullptr;
+ MTLCaptureDescriptor *m_captureDescriptor = nullptr;
+ NSURL *m_traceURL = nullptr;
+ bool m_initialized = false;
+ static uint frameNumber;
+};
+
+QT_END_NAMESPACE
+
+#endif // QGRAPHICSFRAMEDECAPTUREMETAL_P_P_H
diff --git a/src/gui/util/qgraphicsframecapturerenderdoc.cpp b/src/gui/util/qgraphicsframecapturerenderdoc.cpp
new file mode 100644
index 0000000000..88ba9d839f
--- /dev/null
+++ b/src/gui/util/qgraphicsframecapturerenderdoc.cpp
@@ -0,0 +1,310 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qgraphicsframecapturerenderdoc_p_p.h"
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qlibrary.h>
+#include <QtCore/qmutex.h>
+#include "QtGui/rhi/qrhi.h"
+#include "QtGui/rhi/qrhi_platform.h"
+#include "QtGui/qopenglcontext.h"
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcGraphicsFrameCapture, "qt.gui.graphicsframecapture")
+
+RENDERDOC_API_1_6_0 *QGraphicsFrameCaptureRenderDoc::s_rdocApi = nullptr;
+#if QT_CONFIG(thread)
+QBasicMutex QGraphicsFrameCaptureRenderDoc::s_frameCaptureMutex;
+#endif
+
+#if QT_CONFIG(opengl)
+static void *glNativeContext(QOpenGLContext *context) {
+ void *nctx = nullptr;
+ if (context != nullptr && context->isValid()) {
+#ifdef Q_OS_WIN
+ nctx = context->nativeInterface<QNativeInterface::QWGLContext>()->nativeContext();
+#endif
+
+#ifdef Q_OS_LINUX
+#if QT_CONFIG(egl)
+ QNativeInterface::QEGLContext *eglItf = context->nativeInterface<QNativeInterface::QEGLContext>();
+ if (eglItf)
+ nctx = eglItf->nativeContext();
+#endif
+
+#if QT_CONFIG(xcb_glx_plugin)
+ QNativeInterface::QGLXContext *glxItf = context->nativeInterface<QNativeInterface::QGLXContext>();
+ if (glxItf)
+ nctx = glxItf->nativeContext();
+#endif
+#endif
+
+#if QT_CONFIG(metal)
+ nctx = context->nativeInterface<QNativeInterface::QCocoaGLContext>()->nativeContext();
+#endif
+ }
+ return nctx;
+}
+#endif // QT_CONFIG(opengl)
+
+/*!
+ \class QGraphicsFrameCaptureRenderDoc
+ \internal
+ \brief The QGraphicsFrameCaptureRenderDoc class provides a way to capture a record of draw calls
+ for different graphics APIs.
+ \since 6.6
+ \inmodule QtGui
+
+ For applications that render using graphics APIs like Vulkan or OpenGL, it would be
+ convenient to have a way to check the draw calls done by the application. Specially
+ for applications that make a large amount of draw calls and the output is different
+ from what is expected.
+
+ This class acts as a wrapper over \l {https://renderdoc.org/}{RenderDoc} that allows
+ applications to capture a rendered frame either programmatically, by clicking a key
+ on the keyboard or both. The captured frame could be viewed later using RenderDoc GUI.
+
+ Read the \l {https://renderdoc.org/docs/index.html} {RenderDoc Documentation}
+ for more information.
+
+ \section1 API device handle
+
+ The functions that capture a frame like QGraphicsFrameCaptureRenderDoc::startCaptureFrame takes a device
+ pointer as argument. This pointer is unique for each graphics API and is associated
+ with the window that will be captured. This pointer has a default value of \c nullptr.
+ If no value is passed to the function the underlying API will try to find the device to
+ use, but it is not guaranteed specially in a multi-window applications.
+
+ For OpenGL, the pointer should be the OpenGL context on the platform OpenGL is being
+ used. For example, on Windows it should be \c HGLRC.
+
+ For Vulkan, the pointer should point to the dispatch table within the \c VkInstance.
+*/
+
+
+
+/*!
+ Creates a new object of this class. The constructor will load RenderDoc library
+ from the default path.
+
+ Only one instance of RenderDoc library is loaded at runtime which means creating
+ several instances of this class will not affect the RenderDoc initialization.
+*/
+
+QGraphicsFrameCaptureRenderDoc::QGraphicsFrameCaptureRenderDoc()
+ : m_nativeHandlesSet(false)
+{
+ if (!s_rdocApi)
+ init();
+}
+
+void QGraphicsFrameCaptureRenderDoc::setRhi(QRhi *rhi)
+{
+ if (!rhi)
+ return;
+
+ QRhi::Implementation backend = rhi->backend();
+ const QRhiNativeHandles *nh = rhi->nativeHandles();
+
+ switch (backend) {
+ case QRhi::Implementation::D3D11: {
+#ifdef Q_OS_WIN
+ const QRhiD3D11NativeHandles *d3d11nh = static_cast<const QRhiD3D11NativeHandles *>(nh);
+ m_nativeHandle = d3d11nh->dev;
+ break;
+#endif
+ qCWarning(lcGraphicsFrameCapture) << "Could not find valid handles for D3D11. Check platform support";
+ break;
+ }
+ case QRhi::Implementation::D3D12: {
+#ifdef Q_OS_WIN
+ const QRhiD3D12NativeHandles *d3d12nh = static_cast<const QRhiD3D12NativeHandles *>(nh);
+ m_nativeHandle = d3d12nh->dev;
+ break;
+#endif
+ qCWarning(lcGraphicsFrameCapture) << "Could not find valid handles for D3D12. Check platform support";
+ break;
+ }
+ case QRhi::Implementation::Vulkan: {
+#if QT_CONFIG(vulkan)
+ const QRhiVulkanNativeHandles *vknh = static_cast<const QRhiVulkanNativeHandles *>(nh);
+ m_nativeHandle = RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(vknh->inst->vkInstance());
+ break;
+#endif
+ qCWarning(lcGraphicsFrameCapture) << "Could not find valid handles for Vulkan. Check platform support";
+ break;
+ }
+ case QRhi::Implementation::OpenGLES2: {
+#ifndef QT_NO_OPENGL
+ const QRhiGles2NativeHandles *glnh = static_cast<const QRhiGles2NativeHandles *>(nh);
+ m_nativeHandle = glNativeContext(glnh->context);
+ if (m_nativeHandle)
+ break;
+#endif
+ qCWarning(lcGraphicsFrameCapture) << "Could not find valid handles for OpenGL. Check platform support";
+ break;
+ }
+ case QRhi::Implementation::Metal:
+ case QRhi::Implementation::Null:
+ qCWarning(lcGraphicsFrameCapture) << "Invalid handles were provided."
+ " Metal and Null backends are not supported with RenderDoc";
+ break;
+ }
+
+ if (m_nativeHandle)
+ m_nativeHandlesSet = true;
+}
+
+/*!
+ Starts a frame capture using the set native handles provided through QGraphicsFrameCaptureRenderDoc::setRhi
+ \a device. This function must be called before QGraphicsFrameCaptureRenderDoc::endCaptureFrame.
+ \sa {API device handle}
+*/
+void QGraphicsFrameCaptureRenderDoc::startCaptureFrame()
+{
+
+ if (!initialized()) {
+ qCWarning(lcGraphicsFrameCapture) << "RenderDoc was not initialized."
+ " Starting capturing can not be done.";
+ return;
+ }
+
+#if QT_CONFIG(thread)
+ // There is a single instance of RenderDoc library and it needs mutex for multithreading access.
+ QMutexLocker locker(&s_frameCaptureMutex);
+#endif
+ if (s_rdocApi->IsFrameCapturing()) {
+ qCWarning(lcGraphicsFrameCapture) << "A frame capture is already in progress, "
+ "will not initiate another one until"
+ " QGraphicsFrameCapture::endCaptureFrame is called.";
+ return;
+ }
+
+ qCInfo(lcGraphicsFrameCapture) << "A frame capture is going to start.";
+ updateCapturePathAndTemplate();
+ s_rdocApi->StartFrameCapture(m_nativeHandle, nullptr);
+}
+
+/*!
+ Ends a frame capture started by a call to QGraphicsFrameCaptureRenderDoc::startCaptureFrame
+ using the set native handles provided through QGraphicsFrameCaptureRenderDoc::setRhi.
+ This function must be called after QGraphicsFrameCaptureRenderDoc::startCaptureFrame.
+ Otherwise, a warning message will be printend and nothing will happen.
+ \sa {API device handle}
+*/
+void QGraphicsFrameCaptureRenderDoc::endCaptureFrame()
+{
+ if (!initialized()) {
+ qCWarning(lcGraphicsFrameCapture) << "RenderDoc was not initialized."
+ " End capturing can not be done.";
+ return;
+ }
+
+#if QT_CONFIG(thread)
+ // There is a single instance of RenderDoc library and it needs mutex for multithreading access.
+ QMutexLocker locker(&s_frameCaptureMutex);
+#endif
+ if (!s_rdocApi->IsFrameCapturing()) {
+ qCWarning(lcGraphicsFrameCapture) << "A call to QGraphicsFrameCapture::endCaptureFrame can not be done"
+ " without a call to QGraphicsFrameCapture::startCaptureFrame";
+ return;
+ }
+
+ qCInfo(lcGraphicsFrameCapture) << "A frame capture is going to end.";
+ uint32_t result = s_rdocApi->EndFrameCapture(m_nativeHandle, nullptr);
+
+ if (result) {
+ uint32_t count = s_rdocApi->GetNumCaptures();
+ uint32_t pathLength = 0;
+ s_rdocApi->GetCapture(count - 1, nullptr, &pathLength, nullptr);
+ if (pathLength > 0) {
+ QVarLengthArray<char> name(pathLength, 0);
+ s_rdocApi->GetCapture(count - 1, name.data(), &pathLength, nullptr);
+ m_capturedFilesNames.append(QString::fromUtf8(name.data(), -1));
+ }
+ }
+}
+
+void QGraphicsFrameCaptureRenderDoc::updateCapturePathAndTemplate()
+{
+ if (!initialized()) {
+ qCWarning(lcGraphicsFrameCapture) << "RenderDoc was not initialized."
+ " Updating save location can not be done.";
+ return;
+ }
+
+
+ QString rdocFilePathTemplate = m_capturePath + QStringLiteral("/") + m_capturePrefix;
+ s_rdocApi->SetCaptureFilePathTemplate(rdocFilePathTemplate.toUtf8().constData());
+}
+
+/*!
+ Returns true if the API is loaded and can capture frames or not.
+*/
+bool QGraphicsFrameCaptureRenderDoc::initialized() const
+{
+ return s_rdocApi && m_nativeHandlesSet;
+}
+
+bool QGraphicsFrameCaptureRenderDoc::isCapturing() const
+{
+ if (!initialized()) {
+ qCWarning(lcGraphicsFrameCapture) << "RenderDoc was not initialized."
+ " Can not query if capturing is in progress or not.";
+ return false;
+ }
+
+ return s_rdocApi->IsFrameCapturing();
+}
+
+void QGraphicsFrameCaptureRenderDoc::openCapture()
+{
+ if (!initialized()) {
+ qCWarning(lcGraphicsFrameCapture) << "RenderDoc was not initialized."
+ " Can not open RenderDoc UI tool.";
+ return;
+ }
+
+#if QT_CONFIG(thread)
+ // There is a single instance of RenderDoc library and it needs mutex for multithreading access.
+ QMutexLocker locker(&s_frameCaptureMutex);
+#endif
+ if (s_rdocApi->IsTargetControlConnected())
+ s_rdocApi->ShowReplayUI();
+ else
+ s_rdocApi->LaunchReplayUI(1, nullptr);
+}
+
+void QGraphicsFrameCaptureRenderDoc::init()
+{
+#if QT_CONFIG(thread)
+ // There is a single instance of RenderDoc library and it needs mutex for multithreading access.
+ QMutexLocker locker(&s_frameCaptureMutex);
+#endif
+
+ QLibrary renderDocLib(QStringLiteral("renderdoc"));
+ pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI) renderDocLib.resolve("RENDERDOC_GetAPI");
+ if (!renderDocLib.isLoaded() || (RENDERDOC_GetAPI == nullptr)) {
+ qCWarning(lcGraphicsFrameCapture) << renderDocLib.errorString().toLatin1();
+ return;
+ }
+
+ int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_6_0, static_cast<void **>(static_cast<void *>(&s_rdocApi)));
+
+ if (ret == 0) {
+ qCWarning(lcGraphicsFrameCapture) << "The requested RenderDoc API is invalid or not supported";
+ return;
+ }
+
+ s_rdocApi->MaskOverlayBits(RENDERDOC_OverlayBits::eRENDERDOC_Overlay_None,
+ RENDERDOC_OverlayBits::eRENDERDOC_Overlay_None);
+ s_rdocApi->SetCaptureKeys(nullptr, 0);
+ s_rdocApi->SetFocusToggleKeys(nullptr, 0);
+
+ QString rdocFilePathTemplate = m_capturePath + QStringLiteral("/") + m_capturePrefix;
+ s_rdocApi->SetCaptureFilePathTemplate(rdocFilePathTemplate.toUtf8().constData());
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/util/qgraphicsframecapturerenderdoc_p_p.h b/src/gui/util/qgraphicsframecapturerenderdoc_p_p.h
new file mode 100644
index 0000000000..c0d92ea733
--- /dev/null
+++ b/src/gui/util/qgraphicsframecapturerenderdoc_p_p.h
@@ -0,0 +1,53 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QGRAPHICSFRAMECAPTURERENDERDOC_P_P_H
+#define QGRAPHICSFRAMECAPTURERENDERDOC_P_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 <renderdoc_app.h>
+#include "qgraphicsframecapture_p_p.h"
+
+QT_BEGIN_NAMESPACE
+
+#if QT_CONFIG(thread)
+class QBasicMutex;
+#endif
+
+class QGraphicsFrameCaptureRenderDoc : public QGraphicsFrameCapturePrivate
+{
+public:
+ QGraphicsFrameCaptureRenderDoc();
+ ~QGraphicsFrameCaptureRenderDoc() = default;
+
+ void setRhi(QRhi *rhi) override;
+ void startCaptureFrame() override;
+ void endCaptureFrame() override;
+ bool initialized() const override;
+ bool isCapturing() const override;
+ void openCapture() override;
+
+private:
+ void init();
+ void updateCapturePathAndTemplate();
+ static RENDERDOC_API_1_5_0 *s_rdocApi;
+#if QT_CONFIG(thread)
+ static QBasicMutex s_frameCaptureMutex;
+#endif
+ bool m_nativeHandlesSet;
+};
+
+QT_END_NAMESPACE
+
+#endif // QGRAPHICSFRAMECAPTURERENDERDOC_P_P_H
diff --git a/src/gui/util/qgridlayoutengine.cpp b/src/gui/util/qgridlayoutengine.cpp
index 2b81d34848..07981e8388 100644
--- a/src/gui/util/qgridlayoutengine.cpp
+++ b/src/gui/util/qgridlayoutengine.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qglobal.h"
@@ -47,10 +11,14 @@
QT_BEGIN_NAMESPACE
-template <typename T>
-static void insertOrRemoveItems(QVector<T> &items, int index, int delta)
+using namespace Qt::StringLiterals;
+
+#define LAYOUTITEMSIZE_MAX (1 << 24)
+
+template<typename T>
+static void insertOrRemoveItems(QList<T> &items, int index, int delta)
{
- int count = items.count();
+ int count = items.size();
if (index < count) {
if (delta > 0) {
items.insert(index, delta, T());
@@ -228,7 +196,8 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz
sumAvailable = targetSize - totalBox.q_minimumSize;
if (sumAvailable > 0.0) {
- qreal sumDesired = totalBox.q_preferredSize - totalBox.q_minimumSize;
+ const qreal totalBox_preferredSize = qMin(totalBox.q_preferredSize, qreal(LAYOUTITEMSIZE_MAX));
+ qreal sumDesired = totalBox_preferredSize - totalBox.q_minimumSize;
for (int i = 0; i < n; ++i) {
if (ignore.testBit(start + i)) {
@@ -237,7 +206,8 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz
}
const QGridLayoutBox &box = boxes.at(start + i);
- qreal desired = box.q_preferredSize - box.q_minimumSize;
+ const qreal box_preferredSize = qMin(box.q_preferredSize, qreal(LAYOUTITEMSIZE_MAX));
+ qreal desired = box_preferredSize - box.q_minimumSize;
factors[i] = growthFactorBelowPreferredSize(desired, sumAvailable, sumDesired);
sumFactors += factors[i];
}
@@ -355,7 +325,7 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz
if (newSizes[i] >= 0.0)
continue;
- const QVector<QGridLayoutBox> &rBoxes = isLargerThanMaximum ? rowInfo.boxes : boxes;
+ const QList<QGridLayoutBox> &rBoxes = isLargerThanMaximum ? rowInfo.boxes : boxes;
const QGridLayoutBox &box = rBoxes.value(start + i);
qreal maxBoxSize = box.q_maximumSize;
@@ -507,24 +477,21 @@ void QGridLayoutRowData::dump(int indent) const
QGridLayoutItem::QGridLayoutItem(int row, int column, int rowSpan, int columnSpan,
Qt::Alignment alignment)
- : q_alignment(alignment)
+ : q_firstRows{column, row},
+ q_rowSpans{columnSpan, rowSpan},
+ q_stretches{-1, -1},
+ q_alignment(alignment)
{
- q_firstRows[Hor] = column;
- q_firstRows[Ver] = row;
- q_rowSpans[Hor] = columnSpan;
- q_rowSpans[Ver] = rowSpan;
- q_stretches[Hor] = -1;
- q_stretches[Ver] = -1;
}
int QGridLayoutItem::firstRow(Qt::Orientation orientation) const
{
- return q_firstRows[orientation == Qt::Vertical];
+ return q_firstRows[orientation];
}
int QGridLayoutItem::firstColumn(Qt::Orientation orientation) const
{
- return q_firstRows[orientation == Qt::Horizontal];
+ return q_firstRows.transposed()[orientation];
}
int QGridLayoutItem::lastRow(Qt::Orientation orientation) const
@@ -539,27 +506,27 @@ int QGridLayoutItem::lastColumn(Qt::Orientation orientation) const
int QGridLayoutItem::rowSpan(Qt::Orientation orientation) const
{
- return q_rowSpans[orientation == Qt::Vertical];
+ return q_rowSpans[orientation];
}
int QGridLayoutItem::columnSpan(Qt::Orientation orientation) const
{
- return q_rowSpans[orientation == Qt::Horizontal];
+ return q_rowSpans.transposed()[orientation];
}
void QGridLayoutItem::setFirstRow(int row, Qt::Orientation orientation)
{
- q_firstRows[orientation == Qt::Vertical] = row;
+ q_firstRows[orientation] = row;
}
void QGridLayoutItem::setRowSpan(int rowSpan, Qt::Orientation orientation)
{
- q_rowSpans[orientation == Qt::Vertical] = rowSpan;
+ q_rowSpans[orientation] = rowSpan;
}
int QGridLayoutItem::stretchFactor(Qt::Orientation orientation) const
{
- int stretch = q_stretches[orientation == Qt::Vertical];
+ int stretch = q_stretches[orientation];
if (stretch >= 0)
return stretch;
@@ -577,7 +544,7 @@ int QGridLayoutItem::stretchFactor(Qt::Orientation orientation) const
void QGridLayoutItem::setStretchFactor(int stretch, Qt::Orientation orientation)
{
Q_ASSERT(stretch >= 0); // ### deal with too big stretches
- q_stretches[orientation == Qt::Vertical] = stretch;
+ q_stretches[orientation] = stretch;
}
QLayoutPolicy::ControlTypes QGridLayoutItem::controlTypes(LayoutSide /*side*/) const
@@ -695,9 +662,9 @@ QRectF QGridLayoutItem::geometryWithin(qreal x, qreal y, qreal width, qreal heig
void QGridLayoutItem::transpose()
{
- qSwap(q_firstRows[Hor], q_firstRows[Ver]);
- qSwap(q_rowSpans[Hor], q_rowSpans[Ver]);
- qSwap(q_stretches[Hor], q_stretches[Ver]);
+ q_firstRows.transpose();
+ q_rowSpans.transpose();
+ q_stretches.transpose();
}
void QGridLayoutItem::insertOrRemoveRows(int row, int delta, Qt::Orientation orientation)
@@ -746,14 +713,14 @@ void QGridLayoutItem::dump(int indent) const
qDebug("%*s (%d, %d) %d x %d", indent, "", firstRow(), firstColumn(), //###
rowSpan(), columnSpan());
- if (q_stretches[Hor] >= 0)
- qDebug("%*s Horizontal stretch: %d", indent, "", q_stretches[Hor]);
- if (q_stretches[Ver] >= 0)
- qDebug("%*s Vertical stretch: %d", indent, "", q_stretches[Ver]);
+ if (q_stretches[Qt::Horizontal] >= 0)
+ qDebug("%*s Horizontal stretch: %d", indent, "", q_stretches[Qt::Horizontal]);
+ if (q_stretches[Qt::Vertical] >= 0)
+ qDebug("%*s Vertical stretch: %d", indent, "", q_stretches[Qt::Vertical]);
if (q_alignment != 0)
qDebug("%*s Alignment: %x", indent, "", uint(q_alignment));
qDebug("%*s Horizontal size policy: %x Vertical size policy: %x",
- indent, "", sizePolicy(Qt::Horizontal), sizePolicy(Qt::Vertical));
+ indent, "", (unsigned int)sizePolicy(Qt::Horizontal), (unsigned int)sizePolicy(Qt::Vertical));
}
#endif
@@ -795,22 +762,24 @@ QGridLayoutEngine::QGridLayoutEngine(Qt::Alignment defaultAlignment, bool snapTo
m_visualDirection = Qt::LeftToRight;
m_defaultAlignment = defaultAlignment;
m_snapToPixelGrid = snapToPixelGrid;
+ m_uniformCellWidths = false;
+ m_uniformCellHeights = false;
invalidate();
}
int QGridLayoutEngine::rowCount(Qt::Orientation orientation) const
{
- return q_infos[orientation == Qt::Vertical].count;
+ return q_infos[orientation].count;
}
int QGridLayoutEngine::columnCount(Qt::Orientation orientation) const
{
- return q_infos[orientation == Qt::Horizontal].count;
+ return q_infos.transposed()[orientation].count;
}
int QGridLayoutEngine::itemCount() const
{
- return q_items.count();
+ return q_items.size();
}
QGridLayoutItem *QGridLayoutEngine::itemAt(int index) const
@@ -822,40 +791,40 @@ QGridLayoutItem *QGridLayoutEngine::itemAt(int index) const
int QGridLayoutEngine::effectiveFirstRow(Qt::Orientation orientation) const
{
ensureEffectiveFirstAndLastRows();
- return q_cachedEffectiveFirstRows[orientation == Qt::Vertical];
+ return q_cachedEffectiveFirstRows[orientation];
}
int QGridLayoutEngine::effectiveLastRow(Qt::Orientation orientation) const
{
ensureEffectiveFirstAndLastRows();
- return q_cachedEffectiveLastRows[orientation == Qt::Vertical];
+ return q_cachedEffectiveLastRows[orientation];
}
void QGridLayoutEngine::setSpacing(qreal spacing, Qt::Orientations orientations)
{
if (orientations & Qt::Horizontal)
- q_defaultSpacings[Hor].setUserValue(spacing);
+ q_defaultSpacings[Qt::Horizontal].setUserValue(spacing);
if (orientations & Qt::Vertical)
- q_defaultSpacings[Ver].setUserValue(spacing);
+ q_defaultSpacings[Qt::Vertical].setUserValue(spacing);
invalidate();
}
qreal QGridLayoutEngine::spacing(Qt::Orientation orientation, const QAbstractLayoutStyleInfo *styleInfo) const
{
- if (!q_defaultSpacings[orientation == Qt::Vertical].isUser()) {
+ if (!q_defaultSpacings[orientation].isUser()) {
qreal defaultSpacing = styleInfo->spacing(orientation);
- q_defaultSpacings[orientation == Qt::Vertical].setCachedValue(defaultSpacing);
+ q_defaultSpacings[orientation].setCachedValue(defaultSpacing);
}
- return q_defaultSpacings[orientation == Qt::Vertical].value();
+ return q_defaultSpacings[orientation].value();
}
void QGridLayoutEngine::setRowSpacing(int row, qreal spacing, Qt::Orientation orientation)
{
Q_ASSERT(row >= 0);
- QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
- if (row >= rowInfo.spacings.count())
+ QGridLayoutRowInfo &rowInfo = q_infos[orientation];
+ if (row >= rowInfo.spacings.size())
rowInfo.spacings.resize(row + 1);
if (spacing >= 0)
rowInfo.spacings[row].setUserValue(spacing);
@@ -866,10 +835,10 @@ void QGridLayoutEngine::setRowSpacing(int row, qreal spacing, Qt::Orientation or
qreal QGridLayoutEngine::rowSpacing(int row, Qt::Orientation orientation) const
{
- QLayoutParameter<qreal> spacing = q_infos[orientation == Qt::Vertical].spacings.value(row);
+ QLayoutParameter<qreal> spacing = q_infos[orientation].spacings.value(row);
if (!spacing.isDefault())
return spacing.value();
- return q_defaultSpacings[orientation == Qt::Vertical].value();
+ return q_defaultSpacings[orientation].value();
}
void QGridLayoutEngine::setRowStretchFactor(int row, int stretch, Qt::Orientation orientation)
@@ -879,15 +848,15 @@ void QGridLayoutEngine::setRowStretchFactor(int row, int stretch, Qt::Orientatio
maybeExpandGrid(row, -1, orientation);
- QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
- if (row >= rowInfo.stretches.count())
+ QGridLayoutRowInfo &rowInfo = q_infos[orientation];
+ if (row >= rowInfo.stretches.size())
rowInfo.stretches.resize(row + 1);
rowInfo.stretches[row].setUserValue(stretch);
}
int QGridLayoutEngine::rowStretchFactor(int row, Qt::Orientation orientation) const
{
- QStretchParameter stretch = q_infos[orientation == Qt::Vertical].stretches.value(row);
+ QStretchParameter stretch = q_infos[orientation].stretches.value(row);
if (!stretch.isDefault())
return stretch.value();
return 0;
@@ -901,15 +870,43 @@ void QGridLayoutEngine::setRowSizeHint(Qt::SizeHint which, int row, qreal size,
maybeExpandGrid(row, -1, orientation);
- QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
- if (row >= rowInfo.boxes.count())
+ QGridLayoutRowInfo &rowInfo = q_infos[orientation];
+ if (row >= rowInfo.boxes.size())
rowInfo.boxes.resize(row + 1);
rowInfo.boxes[row].q_sizes(which) = size;
}
qreal QGridLayoutEngine::rowSizeHint(Qt::SizeHint which, int row, Qt::Orientation orientation) const
{
- return q_infos[orientation == Qt::Vertical].boxes.value(row).q_sizes(which);
+ return q_infos[orientation].boxes.value(row).q_sizes(which);
+}
+
+bool QGridLayoutEngine::uniformCellWidths() const
+{
+ return m_uniformCellWidths;
+}
+
+void QGridLayoutEngine::setUniformCellWidths(bool uniformCellWidths)
+{
+ if (m_uniformCellWidths == uniformCellWidths)
+ return;
+
+ m_uniformCellWidths = uniformCellWidths;
+ invalidate();
+}
+
+bool QGridLayoutEngine::uniformCellHeights() const
+{
+ return m_uniformCellHeights;
+}
+
+void QGridLayoutEngine::setUniformCellHeights(bool uniformCellHeights)
+{
+ if (m_uniformCellHeights == uniformCellHeights)
+ return;
+
+ m_uniformCellHeights = uniformCellHeights;
+ invalidate();
}
void QGridLayoutEngine::setRowAlignment(int row, Qt::Alignment alignment,
@@ -919,8 +916,8 @@ void QGridLayoutEngine::setRowAlignment(int row, Qt::Alignment alignment,
maybeExpandGrid(row, -1, orientation);
- QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
- if (row >= rowInfo.alignments.count())
+ QGridLayoutRowInfo &rowInfo = q_infos[orientation];
+ if (row >= rowInfo.alignments.size())
rowInfo.alignments.resize(row + 1);
rowInfo.alignments[row] = alignment;
}
@@ -928,7 +925,7 @@ void QGridLayoutEngine::setRowAlignment(int row, Qt::Alignment alignment,
Qt::Alignment QGridLayoutEngine::rowAlignment(int row, Qt::Orientation orientation) const
{
Q_ASSERT(row >= 0);
- return q_infos[orientation == Qt::Vertical].alignments.value(row);
+ return q_infos[orientation].alignments.value(row);
}
Qt::Alignment QGridLayoutEngine::effectiveAlignment(const QGridLayoutItem *layoutItem) const
@@ -967,8 +964,11 @@ void QGridLayoutEngine::insertItem(QGridLayoutItem *item, int index)
for (int i = item->firstRow(); i <= item->lastRow(); ++i) {
for (int j = item->firstColumn(); j <= item->lastColumn(); ++j) {
- if (itemAt(i, j))
- qWarning("QGridLayoutEngine::addItem: Cell (%d, %d) already taken", i, j);
+ const auto existingItem = itemAt(i, j);
+ if (existingItem) {
+ qWarning("QGridLayoutEngine::addItem: Can't add %s at cell (%d, %d) because it's already taken by %s",
+ qPrintable(item->toString()), i, j, qPrintable(existingItem->toString()));
+ }
setItemAt(i, j, item);
}
}
@@ -1007,13 +1007,10 @@ QGridLayoutItem *QGridLayoutEngine::itemAt(int row, int column, Qt::Orientation
void QGridLayoutEngine::invalidate()
{
- q_cachedEffectiveFirstRows[Hor] = -1;
- q_cachedEffectiveFirstRows[Ver] = -1;
- q_cachedEffectiveLastRows[Hor] = -1;
- q_cachedEffectiveLastRows[Ver] = -1;
+ q_cachedEffectiveFirstRows = {-1, -1};
+ q_cachedEffectiveLastRows = {-1, -1};
- q_totalBoxCachedConstraints[Hor] = NotCached;
- q_totalBoxCachedConstraints[Ver] = NotCached;
+ q_totalBoxCachedConstraints = {NotCached, NotCached};
q_cachedSize = QSizeF();
q_cachedConstraintOrientation = UnknownConstraint;
@@ -1032,7 +1029,7 @@ void QGridLayoutEngine::setGeometries(const QRectF &contentsGeometry, const QAbs
ensureGeometries(contentsGeometry.size(), styleInfo);
- for (int i = q_items.count() - 1; i >= 0; --i) {
+ for (int i = q_items.size() - 1; i >= 0; --i) {
QGridLayoutItem *item = q_items.at(i);
qreal x = q_xx.at(item->firstColumn());
@@ -1095,14 +1092,14 @@ QSizeF QGridLayoutEngine::sizeHint(Qt::SizeHint which, const QSizeF &constraint,
if (hasDynamicConstraint() && rowCount() > 0 && columnCount() > 0) {
- QGridLayoutBox sizehint_totalBoxes[NOrientations];
+ QHVContainer<QGridLayoutBox> sizehint_totalBoxes;
bool sizeHintCalculated = false;
if (constraintOrientation() == Qt::Vertical) {
//We have items whose height depends on their width
if (constraint.width() >= 0) {
- ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], nullptr, nullptr, Qt::Horizontal, styleInfo);
- QVector<qreal> sizehint_xx;
- QVector<qreal> sizehint_widths;
+ ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Qt::Horizontal], nullptr, nullptr, Qt::Horizontal, styleInfo);
+ QList<qreal> sizehint_xx;
+ QList<qreal> sizehint_widths;
sizehint_xx.resize(columnCount());
sizehint_widths.resize(columnCount());
@@ -1110,16 +1107,16 @@ QSizeF QGridLayoutEngine::sizeHint(Qt::SizeHint which, const QSizeF &constraint,
//Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as
//constraints to find the row heights
q_columnData.calculateGeometries(0, columnCount(), width, sizehint_xx.data(), sizehint_widths.data(),
- nullptr, sizehint_totalBoxes[Hor], q_infos[Hor], m_snapToPixelGrid);
- ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], sizehint_xx.data(), sizehint_widths.data(), Qt::Vertical, styleInfo);
+ nullptr, sizehint_totalBoxes[Qt::Horizontal], q_infos[Qt::Horizontal], m_snapToPixelGrid);
+ ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Qt::Vertical], sizehint_xx.data(), sizehint_widths.data(), Qt::Vertical, styleInfo);
sizeHintCalculated = true;
}
} else {
if (constraint.height() >= 0) {
//We have items whose width depends on their height
- ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], nullptr, nullptr, Qt::Vertical, styleInfo);
- QVector<qreal> sizehint_yy;
- QVector<qreal> sizehint_heights;
+ ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Qt::Vertical], nullptr, nullptr, Qt::Vertical, styleInfo);
+ QList<qreal> sizehint_yy;
+ QList<qreal> sizehint_heights;
sizehint_yy.resize(rowCount());
sizehint_heights.resize(rowCount());
@@ -1127,19 +1124,20 @@ QSizeF QGridLayoutEngine::sizeHint(Qt::SizeHint which, const QSizeF &constraint,
//Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as
//constraints to find the column widths
q_rowData.calculateGeometries(0, rowCount(), height, sizehint_yy.data(), sizehint_heights.data(),
- nullptr, sizehint_totalBoxes[Ver], q_infos[Ver], m_snapToPixelGrid);
- ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], sizehint_yy.data(), sizehint_heights.data(), Qt::Horizontal, styleInfo);
+ nullptr, sizehint_totalBoxes[Qt::Vertical], q_infos[Qt::Vertical], m_snapToPixelGrid);
+ ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Qt::Horizontal], sizehint_yy.data(), sizehint_heights.data(), Qt::Horizontal, styleInfo);
sizeHintCalculated = true;
}
}
if (sizeHintCalculated)
- return QSizeF(sizehint_totalBoxes[Hor].q_sizes(which), sizehint_totalBoxes[Ver].q_sizes(which));
+ return QSizeF{sizehint_totalBoxes[Qt::Horizontal].q_sizes(which),
+ sizehint_totalBoxes[Qt::Vertical].q_sizes(which)};
}
//No items with height for width, so it doesn't matter which order we do these in
- ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], nullptr, nullptr, Qt::Horizontal, styleInfo);
- ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], nullptr, nullptr, Qt::Vertical, styleInfo);
- return QSizeF(q_totalBoxes[Hor].q_sizes(which), q_totalBoxes[Ver].q_sizes(which));
+ ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Qt::Horizontal], nullptr, nullptr, Qt::Horizontal, styleInfo);
+ ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Qt::Vertical], nullptr, nullptr, Qt::Vertical, styleInfo);
+ return QSizeF(q_totalBoxes[Qt::Horizontal].q_sizes(which), q_totalBoxes[Qt::Vertical].q_sizes(which));
}
QLayoutPolicy::ControlTypes QGridLayoutEngine::controlTypes(LayoutSide side) const
@@ -1160,11 +1158,11 @@ void QGridLayoutEngine::transpose()
{
invalidate();
- for (int i = q_items.count() - 1; i >= 0; --i)
+ for (int i = q_items.size() - 1; i >= 0; --i)
q_items.at(i)->transpose();
- qSwap(q_defaultSpacings[Hor], q_defaultSpacings[Ver]);
- qSwap(q_infos[Hor], q_infos[Ver]);
+ q_defaultSpacings.transpose();
+ q_infos.transpose();
regenerateGrid();
}
@@ -1184,7 +1182,7 @@ void QGridLayoutEngine::dump(int indent) const
{
qDebug("%*sEngine", indent, "");
- qDebug("%*s Items (%d)", indent, "", q_items.count());
+ qDebug("%*s Items (%lld)", indent, "", q_items.count());
int i;
for (i = 0; i < q_items.count(); ++i)
q_items.at(i)->dump(indent + 2);
@@ -1192,36 +1190,37 @@ void QGridLayoutEngine::dump(int indent) const
qDebug("%*s Grid (%d x %d)", indent, "", internalGridRowCount(),
internalGridColumnCount());
for (int row = 0; row < internalGridRowCount(); ++row) {
- QString message = QLatin1String("[ ");
+ QString message = "[ "_L1;
for (int column = 0; column < internalGridColumnCount(); ++column) {
message += QString::number(q_items.indexOf(itemAt(row, column))).rightJustified(3);
- message += QLatin1Char(' ');
+ message += u' ';
}
- message += QLatin1Char(']');
+ message += u']';
qDebug("%*s %s", indent, "", qPrintable(message));
}
- if (q_defaultSpacings[Hor].value() >= 0.0 || q_defaultSpacings[Ver].value() >= 0.0)
- qDebug("%*s Default spacings: %g %g", indent, "", q_defaultSpacings[Hor].value(),
- q_defaultSpacings[Ver].value());
+ if (q_defaultSpacings[Qt::Horizontal].value() >= 0.0 || q_defaultSpacings[Qt::Vertical].value() >= 0.0)
+ qDebug("%*s Default spacings: %g %g", indent, "",
+ q_defaultSpacings[Qt::Horizontal].value(),
+ q_defaultSpacings[Qt::Vertical].value());
qDebug("%*s Column and row info", indent, "");
- q_infos[Hor].dump(indent + 2);
- q_infos[Ver].dump(indent + 2);
+ q_infos[Qt::Horizontal].dump(indent + 2);
+ q_infos[Qt::Vertical].dump(indent + 2);
qDebug("%*s Column and row data", indent, "");
q_columnData.dump(indent + 2);
q_rowData.dump(indent + 2);
qDebug("%*s Geometries output", indent, "");
- QVector<qreal> *cellPos = &q_yy;
+ QList<qreal> *cellPos = &q_yy;
for (int pass = 0; pass < 2; ++pass) {
QString message;
for (i = 0; i < cellPos->count(); ++i) {
- message += QLatin1String((message.isEmpty() ? "[" : ", "));
+ message += (message.isEmpty() ? "["_L1 : ", "_L1);
message += QString::number(cellPos->at(i));
}
- message += QLatin1Char(']');
+ message += u']';
qDebug("%*s %s %s", indent, "", (pass == 0 ? "rows:" : "columns:"), qPrintable(message));
cellPos = &q_xx;
}
@@ -1241,14 +1240,14 @@ void QGridLayoutEngine::maybeExpandGrid(int row, int column, Qt::Orientation ori
int oldGridRowCount = internalGridRowCount();
int oldGridColumnCount = internalGridColumnCount();
- q_infos[Ver].count = qMax(row + 1, rowCount());
- q_infos[Hor].count = qMax(column + 1, columnCount());
+ q_infos[Qt::Vertical].count = qMax(row + 1, rowCount());
+ q_infos[Qt::Horizontal].count = qMax(column + 1, columnCount());
int newGridRowCount = internalGridRowCount();
int newGridColumnCount = internalGridColumnCount();
int newGridSize = newGridRowCount * newGridColumnCount;
- if (newGridSize != q_grid.count()) {
+ if (newGridSize != q_grid.size()) {
q_grid.resize(newGridSize);
if (newGridColumnCount != oldGridColumnCount) {
@@ -1259,7 +1258,7 @@ void QGridLayoutEngine::maybeExpandGrid(int row, int column, Qt::Orientation ori
Q_ASSERT(newIndex > oldIndex);
q_grid[newIndex] = q_grid[oldIndex];
- q_grid[oldIndex] = 0;
+ q_grid[oldIndex] = nullptr;
}
}
}
@@ -1268,9 +1267,9 @@ void QGridLayoutEngine::maybeExpandGrid(int row, int column, Qt::Orientation ori
void QGridLayoutEngine::regenerateGrid()
{
- q_grid.fill(0);
+ q_grid.fill(nullptr);
- for (int i = q_items.count() - 1; i >= 0; --i) {
+ for (int i = q_items.size() - 1; i >= 0; --i) {
QGridLayoutItem *item = q_items.at(i);
for (int j = item->firstRow(); j <= item->lastRow(); ++j) {
@@ -1301,9 +1300,9 @@ void QGridLayoutEngine::insertOrRemoveRows(int row, int delta, Qt::Orientation o
return;
}
- q_infos[orientation == Qt::Vertical].insertOrRemoveRows(row, delta);
+ q_infos[orientation].insertOrRemoveRows(row, delta);
- for (int i = q_items.count() - 1; i >= 0; --i)
+ for (int i = q_items.size() - 1; i >= 0; --i)
q_items.at(i)->insertOrRemoveRows(row, delta, orientation);
q_grid.resize(internalGridRowCount() * internalGridColumnCount());
@@ -1316,12 +1315,12 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData,
const QAbstractLayoutStyleInfo *styleInfo) const
{
const int ButtonMask = QLayoutPolicy::ButtonBox | QLayoutPolicy::PushButton;
- const QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
- const QGridLayoutRowInfo &columnInfo = q_infos[orientation == Qt::Horizontal];
+ const QGridLayoutRowInfo &rowInfo = q_infos[orientation];
+ const QGridLayoutRowInfo &columnInfo = q_infos.other(orientation);
LayoutSide top = (orientation == Qt::Vertical) ? Top : Left;
LayoutSide bottom = (orientation == Qt::Vertical) ? Bottom : Right;
- const QLayoutParameter<qreal> &defaultSpacing = q_defaultSpacings[orientation == Qt::Vertical];
+ const QLayoutParameter<qreal> &defaultSpacing = q_defaultSpacings[orientation];
qreal innerSpacing = styleInfo->spacing(orientation);
if (innerSpacing >= 0.0)
defaultSpacing.setCachedValue(innerSpacing);
@@ -1336,7 +1335,7 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData,
if (rowIsIdenticalToPrevious && item != itemAt(row - 1, column, orientation))
rowIsIdenticalToPrevious = false;
- if (item && !item->isIgnored())
+ if (item && !item->isEmpty())
rowIsEmpty = false;
}
@@ -1444,7 +1443,7 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData,
}
}
}
- if (row < rowInfo.boxes.count()) {
+ if (row < rowInfo.boxes.size()) {
QGridLayoutBox rowBoxInfo = rowInfo.boxes.at(row);
rowBoxInfo.normalize();
rowBox.q_minimumSize = qMax(rowBox.q_minimumSize, rowBoxInfo.q_minimumSize);
@@ -1537,28 +1536,46 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData,
rowSpacing = qMax(windowMargin, rowSpacing);
}
}
+
+ if (rowData->boxes.size() > 1 &&
+ ((orientation == Qt::Horizontal && m_uniformCellWidths) ||
+ (orientation == Qt::Vertical && m_uniformCellHeights))) {
+ qreal averagePreferredSize = 0.;
+ qreal minimumMaximumSize = std::numeric_limits<qreal>::max();
+ qreal maximumMinimumSize = 0.;
+ for (const auto &box : rowData->boxes) {
+ averagePreferredSize += box.q_preferredSize;
+ minimumMaximumSize = qMin(minimumMaximumSize, box.q_maximumSize);
+ maximumMinimumSize = qMax(maximumMinimumSize, box.q_minimumSize);
+ }
+ averagePreferredSize /= rowData->boxes.size();
+ minimumMaximumSize = qMax(minimumMaximumSize, maximumMinimumSize);
+ averagePreferredSize = qBound(maximumMinimumSize, averagePreferredSize, minimumMaximumSize);
+ for (auto &box : rowData->boxes) {
+ box.q_preferredSize = averagePreferredSize;
+ box.q_minimumSize = maximumMinimumSize;
+ box.q_maximumSize = minimumMaximumSize;
+ }
+ }
}
void QGridLayoutEngine::ensureEffectiveFirstAndLastRows() const
{
- if (q_cachedEffectiveFirstRows[Hor] == -1 && !q_items.isEmpty()) {
+ if (q_cachedEffectiveFirstRows[Qt::Horizontal] == -1 && !q_items.isEmpty()) {
int rowCount = this->rowCount();
int columnCount = this->columnCount();
- q_cachedEffectiveFirstRows[Ver] = rowCount;
- q_cachedEffectiveFirstRows[Hor] = columnCount;
- q_cachedEffectiveLastRows[Ver] = -1;
- q_cachedEffectiveLastRows[Hor] = -1;
+ q_cachedEffectiveFirstRows = {columnCount, rowCount};
+ q_cachedEffectiveLastRows = {-1, -1};
- for (int i = q_items.count() - 1; i >= 0; --i) {
+ for (int i = q_items.size() - 1; i >= 0; --i) {
const QGridLayoutItem *item = q_items.at(i);
- for (int j = 0; j < NOrientations; ++j) {
- Qt::Orientation orientation = (j == Hor) ? Qt::Horizontal : Qt::Vertical;
- if (item->firstRow(orientation) < q_cachedEffectiveFirstRows[j])
- q_cachedEffectiveFirstRows[j] = item->firstRow(orientation);
- if (item->lastRow(orientation) > q_cachedEffectiveLastRows[j])
- q_cachedEffectiveLastRows[j] = item->lastRow(orientation);
+ for (Qt::Orientation o : {Qt::Horizontal, Qt::Vertical}) {
+ if (item->firstRow(o) < q_cachedEffectiveFirstRows[o])
+ q_cachedEffectiveFirstRows[o] = item->firstRow(o);
+ if (item->lastRow(o) > q_cachedEffectiveLastRows[o])
+ q_cachedEffectiveLastRows[o] = item->lastRow(o);
}
}
}
@@ -1569,24 +1586,23 @@ void QGridLayoutEngine::ensureColumnAndRowData(QGridLayoutRowData *rowData, QGri
Qt::Orientation orientation,
const QAbstractLayoutStyleInfo *styleInfo) const
{
- const int o = (orientation == Qt::Vertical ? Ver : Hor);
const int cc = columnCount(orientation);
const qreal constraint = (colPositions && colSizes && hasDynamicConstraint()) ? (colPositions[cc - 1] + colSizes[cc - 1]) : qreal(CachedWithNoConstraint);
- qreal &cachedConstraint = q_totalBoxCachedConstraints[o];
+ qreal &cachedConstraint = q_totalBoxCachedConstraints[orientation];
if (cachedConstraint == constraint) {
- if (totalBox != &q_totalBoxes[o])
- *totalBox = q_totalBoxes[o];
+ if (totalBox != &q_totalBoxes[orientation])
+ *totalBox = q_totalBoxes[orientation];
return;
}
rowData->reset(rowCount(orientation));
fillRowData(rowData, colPositions, colSizes, orientation, styleInfo);
- const QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
+ const QGridLayoutRowInfo &rowInfo = q_infos[orientation];
rowData->distributeMultiCells(rowInfo, m_snapToPixelGrid);
*totalBox = rowData->totalBox(0, rowCount(orientation));
- if (totalBox != &q_totalBoxes[o])
- q_totalBoxes[o] = *totalBox;
+ if (totalBox != &q_totalBoxes[orientation])
+ q_totalBoxes[orientation] = *totalBox;
cachedConstraint = constraint;
}
@@ -1598,7 +1614,7 @@ void QGridLayoutEngine::ensureColumnAndRowData(QGridLayoutRowData *rowData, QGri
bool QGridLayoutEngine::ensureDynamicConstraint() const
{
if (q_cachedConstraintOrientation == UnknownConstraint) {
- for (int i = q_items.count() - 1; i >= 0; --i) {
+ for (int i = q_items.size() - 1; i >= 0; --i) {
QGridLayoutItem *item = q_items.at(i);
if (item->hasDynamicConstraint()) {
Qt::Orientation itemConstraintOrientation = item->dynamicConstraintOrientation();
@@ -1650,26 +1666,26 @@ void QGridLayoutEngine::ensureGeometries(const QSizeF &size,
if (constraintOrientation() != Qt::Horizontal) {
//We might have items whose height depends on their width (HFW)
- ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], nullptr, nullptr, Qt::Horizontal, styleInfo);
+ ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Qt::Horizontal], nullptr, nullptr, Qt::Horizontal, styleInfo);
//Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as
//constraints to find the row heights
q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(),
- nullptr, q_totalBoxes[Hor], q_infos[Hor], m_snapToPixelGrid);
- ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], q_xx.data(), q_widths.data(), Qt::Vertical, styleInfo);
+ nullptr, q_totalBoxes[Qt::Horizontal], q_infos[Qt::Horizontal], m_snapToPixelGrid);
+ ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Qt::Vertical], q_xx.data(), q_widths.data(), Qt::Vertical, styleInfo);
//Calculate row heights and positions, and put results in q_yy.data() and q_heights.data()
q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(),
- q_descents.data(), q_totalBoxes[Ver], q_infos[Ver], m_snapToPixelGrid);
+ q_descents.data(), q_totalBoxes[Qt::Vertical], q_infos[Qt::Vertical], m_snapToPixelGrid);
} else {
//We have items whose width depends on their height (WFH)
- ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], nullptr, nullptr, Qt::Vertical, styleInfo);
+ ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Qt::Vertical], nullptr, nullptr, Qt::Vertical, styleInfo);
//Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as
//constraints to find the column widths
q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(),
- q_descents.data(), q_totalBoxes[Ver], q_infos[Ver], m_snapToPixelGrid);
- ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], q_yy.data(), q_heights.data(), Qt::Horizontal, styleInfo);
+ q_descents.data(), q_totalBoxes[Qt::Vertical], q_infos[Qt::Vertical], m_snapToPixelGrid);
+ ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Qt::Horizontal], q_yy.data(), q_heights.data(), Qt::Horizontal, styleInfo);
//Calculate row heights and positions, and put results in q_yy.data() and q_heights.data()
q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(),
- nullptr, q_totalBoxes[Hor], q_infos[Hor], m_snapToPixelGrid);
+ nullptr, q_totalBoxes[Qt::Horizontal], q_infos[Qt::Horizontal], m_snapToPixelGrid);
}
}
diff --git a/src/gui/util/qgridlayoutengine_p.h b/src/gui/util/qgridlayoutengine_p.h
index 181326103b..2f60cb99fd 100644
--- a/src/gui/util/qgridlayoutengine_p.h
+++ b/src/gui/util/qgridlayoutengine_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QGRIDLAYOUTENGINE_P_H
#define QGRIDLAYOUTENGINE_P_H
@@ -52,14 +16,16 @@
//
#include <QtGui/private/qtguiglobal_p.h>
-#include "qalgorithms.h"
-#include "qbitarray.h"
-#include "qlist.h"
-#include "qmap.h"
-#include "qpair.h"
-#include <QtCore/qvector.h>
+
+#include <QtCore/qalgorithms.h>
+#include <QtCore/qbitarray.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qmap.h>
+#include <QtCore/qpair.h>
#include <QtCore/qsize.h>
#include <QtCore/qrect.h>
+#include <QtCore/qdebug.h>
+
#include <float.h>
#include "qlayoutpolicy_p.h"
#include "qabstractlayoutstyleinfo_p.h"
@@ -80,13 +46,6 @@ enum {
};
// do not reorder
-enum {
- Hor,
- Ver,
- NOrientations
-};
-
-// do not reorder
enum LayoutSide {
Left,
Top,
@@ -102,6 +61,44 @@ enum {
UnfeasibleConstraint // not feasible, it be has some items with Vertical and others with Horizontal constraints
};
+/*
+ Minimal container to store Qt::Orientation-discriminated values.
+
+ The salient feature is the indexing operator, which takes
+ Qt::Orientation (and assumes it's passed only Qt::Horizontal or Qt::Vertical).
+*/
+template <typename T>
+class QHVContainer {
+ T m_data[2];
+
+ static_assert(Qt::Horizontal == 0x1);
+ static_assert(Qt::Vertical == 0x2);
+ static constexpr int map(Qt::Orientation o) noexcept
+ {
+ return int(o) - 1;
+ }
+ static constexpr int mapOther(Qt::Orientation o) noexcept
+ {
+ return 2 - int(o);
+ }
+public:
+ constexpr QHVContainer(const T &h, const T &v)
+ noexcept(std::is_nothrow_copy_constructible_v<T>)
+ : m_data{h, v} {}
+ QHVContainer() = default;
+
+ constexpr T &operator[](Qt::Orientation o) noexcept { return m_data[map(o)]; }
+ constexpr const T &operator[](Qt::Orientation o) const noexcept { return m_data[map(o)]; }
+
+ constexpr T &other(Qt::Orientation o) noexcept { return m_data[mapOther(o)]; }
+ constexpr const T &other(Qt::Orientation o) const noexcept { return m_data[mapOther(o)]; }
+
+ constexpr void transpose() noexcept { qSwap(m_data[0], m_data[1]); }
+ constexpr QHVContainer transposed() const
+ noexcept(std::is_nothrow_copy_constructible_v<T>)
+ { return {m_data[1], m_data[0]}; }
+};
+
template <typename T>
class QLayoutParameter
{
@@ -162,56 +159,27 @@ public:
qreal q_minimumAscent;
inline qreal &q_sizes(int which)
{
- qreal *t;
- switch (which) {
- case Qt::MinimumSize:
- t = &q_minimumSize;
- break;
- case Qt::PreferredSize:
- t = &q_preferredSize;
- break;
- case Qt::MaximumSize:
- t = &q_maximumSize;
- break;
- case Qt::MinimumDescent:
- t = &q_minimumDescent;
- break;
- case (Qt::MinimumDescent + 1):
- t = &q_minimumAscent;
- break;
- default:
- t = nullptr;
- break;
- }
- return *t;
+ return const_cast<qreal&>(static_cast<const QGridLayoutBox*>(this)->q_sizes(which));
}
inline const qreal &q_sizes(int which) const
{
- const qreal *t;
switch (which) {
case Qt::MinimumSize:
- t = &q_minimumSize;
- break;
+ return q_minimumSize;
case Qt::PreferredSize:
- t = &q_preferredSize;
- break;
+ return q_preferredSize;
case Qt::MaximumSize:
- t = &q_maximumSize;
- break;
+ return q_maximumSize;
case Qt::MinimumDescent:
- t = &q_minimumDescent;
- break;
+ return q_minimumDescent;
case (Qt::MinimumDescent + 1):
- t = &q_minimumAscent;
- break;
+ return q_minimumAscent;
default:
- t = nullptr;
- break;
+ Q_UNREACHABLE();
}
- return *t;
}
};
-Q_DECLARE_TYPEINFO(QGridLayoutBox, Q_MOVABLE_TYPE); // cannot be Q_PRIMITIVE_TYPE, as q_maximumSize, say, is != 0
+Q_DECLARE_TYPEINFO(QGridLayoutBox, Q_RELOCATABLE_TYPE); // cannot be Q_PRIMITIVE_TYPE, as q_maximumSize, say, is != 0
bool operator==(const QGridLayoutBox &box1, const QGridLayoutBox &box2);
inline bool operator!=(const QGridLayoutBox &box1, const QGridLayoutBox &box2)
@@ -246,10 +214,10 @@ public:
#endif
QBitArray ignore; // ### rename q_
- QVector<QGridLayoutBox> boxes;
+ QList<QGridLayoutBox> boxes;
MultiCellMap multiCellMap;
- QVector<int> stretches;
- QVector<qreal> spacings;
+ QList<int> stretches;
+ QList<qreal> spacings;
bool hasIgnoreFlag;
};
@@ -265,10 +233,10 @@ public:
#endif
int count;
- QVector<QStretchParameter> stretches;
- QVector<QLayoutParameter<qreal> > spacings;
- QVector<Qt::Alignment> alignments;
- QVector<QGridLayoutBox> boxes;
+ QList<QStretchParameter> stretches;
+ QList<QLayoutParameter<qreal>> spacings;
+ QList<Qt::Alignment> alignments;
+ QList<QGridLayoutBox> boxes;
};
@@ -279,10 +247,10 @@ public:
Qt::Alignment alignment = { });
virtual ~QGridLayoutItem() {}
- inline int firstRow() const { return q_firstRows[Ver]; }
- inline int firstColumn() const { return q_firstRows[Hor]; }
- inline int rowSpan() const { return q_rowSpans[Ver]; }
- inline int columnSpan() const { return q_rowSpans[Hor]; }
+ inline int firstRow() const { return q_firstRows[Qt::Vertical]; }
+ inline int firstColumn() const { return q_firstRows[Qt::Horizontal]; }
+ inline int rowSpan() const { return q_rowSpans[Qt::Vertical]; }
+ inline int columnSpan() const { return q_rowSpans[Qt::Horizontal]; }
inline int lastRow() const { return firstRow() + rowSpan() - 1; }
inline int lastColumn() const { return firstColumn() + columnSpan() - 1; }
@@ -303,7 +271,7 @@ public:
virtual QLayoutPolicy::Policy sizePolicy(Qt::Orientation orientation) const = 0;
virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const = 0;
- virtual bool isIgnored() const { return false; }
+ virtual bool isEmpty() const { return false; }
virtual void setGeometry(const QRectF &rect) = 0;
/*
@@ -316,6 +284,8 @@ public:
virtual QLayoutPolicy::ControlTypes controlTypes(LayoutSide side) const;
+ inline virtual QString toString() const { return QDebug::toString(this); }
+
QRectF geometryWithin(qreal x, qreal y, qreal width, qreal height, qreal rowDescent, Qt::Alignment align, bool snapToPixelGrid) const;
QGridLayoutBox box(Qt::Orientation orientation, bool snapToPixelGrid, qreal constraint = -1.0) const;
@@ -329,9 +299,9 @@ public:
#endif
private:
- int q_firstRows[NOrientations];
- int q_rowSpans[NOrientations];
- int q_stretches[NOrientations];
+ QHVContainer<int> q_firstRows;
+ QHVContainer<int> q_rowSpans;
+ QHVContainer<int> q_stretches;
Qt::Alignment q_alignment;
};
@@ -344,8 +314,8 @@ public:
int rowCount(Qt::Orientation orientation) const;
int columnCount(Qt::Orientation orientation) const;
- inline int rowCount() const { return q_infos[Ver].count; }
- inline int columnCount() const { return q_infos[Hor].count; }
+ inline int rowCount() const { return q_infos[Qt::Vertical].count; }
+ inline int columnCount() const { return q_infos[Qt::Horizontal].count; }
// returns the number of items inserted, which may be less than (rowCount * columnCount)
int itemCount() const;
QGridLayoutItem *itemAt(int index) const;
@@ -367,6 +337,12 @@ public:
qreal rowSizeHint(Qt::SizeHint which, int row,
Qt::Orientation orientation = Qt::Vertical) const;
+ bool uniformCellWidths() const;
+ void setUniformCellWidths(bool uniformCellWidths);
+
+ bool uniformCellHeights() const;
+ void setUniformCellHeights(bool uniformCellHeights);
+
void setRowAlignment(int row, Qt::Alignment alignment, Qt::Orientation orientation);
Qt::Alignment rowAlignment(int row, Qt::Orientation orientation) const;
@@ -440,28 +416,30 @@ protected:
QList<QGridLayoutItem *> q_items;
private:
// User input
- QVector<QGridLayoutItem *> q_grid;
- QLayoutParameter<qreal> q_defaultSpacings[NOrientations];
- QGridLayoutRowInfo q_infos[NOrientations];
+ QList<QGridLayoutItem *> q_grid;
+ QHVContainer<QLayoutParameter<qreal>> q_defaultSpacings;
+ QHVContainer<QGridLayoutRowInfo> q_infos;
Qt::LayoutDirection m_visualDirection;
// Configuration
Qt::Alignment m_defaultAlignment;
unsigned m_snapToPixelGrid : 1;
+ unsigned m_uniformCellWidths : 1;
+ unsigned m_uniformCellHeights : 1;
// Lazily computed from the above user input
- mutable int q_cachedEffectiveFirstRows[NOrientations];
- mutable int q_cachedEffectiveLastRows[NOrientations];
+ mutable QHVContainer<int> q_cachedEffectiveFirstRows;
+ mutable QHVContainer<int> q_cachedEffectiveLastRows;
mutable quint8 q_cachedConstraintOrientation : 3;
// this is useful to cache
- mutable QGridLayoutBox q_totalBoxes[NOrientations];
+ mutable QHVContainer<QGridLayoutBox> q_totalBoxes;
enum {
NotCached = -2, // Cache is empty. Happens when the engine is invalidated.
CachedWithNoConstraint = -1 // cache has a totalBox without any HFW/WFH constraints.
// >= 0 // cache has a totalBox with this specific constraint.
};
- mutable qreal q_totalBoxCachedConstraints[NOrientations]; // holds the constraint used for the cached totalBox
+ mutable QHVContainer<qreal> q_totalBoxCachedConstraints; // holds the constraint used for the cached totalBox
// Layout item input
mutable QGridLayoutRowData q_columnData;
@@ -469,11 +447,11 @@ private:
// Output
mutable QSizeF q_cachedSize;
- mutable QVector<qreal> q_xx;
- mutable QVector<qreal> q_yy;
- mutable QVector<qreal> q_widths;
- mutable QVector<qreal> q_heights;
- mutable QVector<qreal> q_descents;
+ mutable QList<qreal> q_xx;
+ mutable QList<qreal> q_yy;
+ mutable QList<qreal> q_widths;
+ mutable QList<qreal> q_heights;
+ mutable QList<qreal> q_descents;
friend class QGridLayoutItem;
};
diff --git a/src/gui/util/qhexstring_p.h b/src/gui/util/qhexstring_p.h
index d30a8eeee8..2b42e6c43e 100644
--- a/src/gui/util/qhexstring_p.h
+++ b/src/gui/util/qhexstring_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtGui/private/qtguiglobal_p.h>
#include <QtCore/qpoint.h>
@@ -69,7 +33,7 @@ template <typename T>
inline void write(QChar *&dest) const
{
- const ushort hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+ const char16_t hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
const char *c = reinterpret_cast<const char *>(&val);
for (uint i = 0; i < sizeof(T); ++i) {
*dest++ = hexChars[*c & 0xf];
diff --git a/src/gui/util/qktxhandler.cpp b/src/gui/util/qktxhandler.cpp
index 7eda4c46fb..35f1df1185 100644
--- a/src/gui/util/qktxhandler.cpp
+++ b/src/gui/util/qktxhandler.cpp
@@ -1,46 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qktxhandler_p.h"
#include "qtexturefiledata_p.h"
#include <QtEndian>
#include <QSize>
+#include <QMap>
+#include <QtCore/qiodevice.h>
//#define KTX_DEBUG
#ifdef KTX_DEBUG
@@ -51,6 +17,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
#define KTX_IDENTIFIER_LENGTH 12
static const char ktxIdentifier[KTX_IDENTIFIER_LENGTH] = { '\xAB', 'K', 'T', 'X', ' ', '1', '1', '\xBB', '\r', '\n', '\x1A', '\n' };
static const quint32 platformEndianIdentifier = 0x04030201;
@@ -73,7 +41,7 @@ struct KTXHeader {
quint32 bytesOfKeyValueData;
};
-static const quint32 headerSize = sizeof(KTXHeader);
+static constexpr quint32 qktxh_headerSize = sizeof(KTXHeader);
// Currently unused, declared for future reference
struct KTXKeyValuePairItem {
@@ -103,11 +71,32 @@ struct KTXMipmapLevel {
*/
};
-bool QKtxHandler::canRead(const QByteArray &suffix, const QByteArray &block)
+// Returns the nearest multiple of 4 greater than or equal to 'value'
+static const std::optional<quint32> nearestMultipleOf4(quint32 value)
{
- Q_UNUSED(suffix)
+ constexpr quint32 rounding = 4;
+ quint32 result = 0;
+ if (qAddOverflow(value, rounding - 1, &result))
+ return std::nullopt;
+ result &= ~(rounding - 1);
+ return result;
+}
- return (qstrncmp(block.constData(), ktxIdentifier, KTX_IDENTIFIER_LENGTH) == 0);
+// Returns a view with prechecked bounds
+static QByteArrayView safeView(QByteArrayView view, quint32 start, quint32 length)
+{
+ quint32 end = 0;
+ if (qAddOverflow(start, length, &end) || end > quint32(view.length()))
+ return {};
+ return view.sliced(start, length);
+}
+
+QKtxHandler::~QKtxHandler() = default;
+
+bool QKtxHandler::canRead(const QByteArray &suffix, const QByteArray &block)
+{
+ Q_UNUSED(suffix);
+ return block.startsWith(ktxIdentifier);
}
QTextureFileData QKtxHandler::read()
@@ -115,42 +104,123 @@ QTextureFileData QKtxHandler::read()
if (!device())
return QTextureFileData();
- QByteArray buf = device()->readAll();
- const quint32 dataSize = quint32(buf.size());
- if (dataSize < headerSize || !canRead(QByteArray(), buf)) {
- qCDebug(lcQtGuiTextureIO, "Invalid KTX file %s", logName().constData());
+ const QByteArray buf = device()->readAll();
+ if (static_cast<size_t>(buf.size()) > std::numeric_limits<quint32>::max()) {
+ qWarning(lcQtGuiTextureIO, "Too big KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ if (!canRead(QByteArray(), buf)) {
+ qWarning(lcQtGuiTextureIO, "Invalid KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ if (buf.size() < qsizetype(qktxh_headerSize)) {
+ qWarning(lcQtGuiTextureIO, "Invalid KTX header size in %s", logName().constData());
return QTextureFileData();
}
- const KTXHeader *header = reinterpret_cast<const KTXHeader *>(buf.constData());
- if (!checkHeader(*header)) {
- qCDebug(lcQtGuiTextureIO, "Unsupported KTX file format in %s", logName().constData());
+ KTXHeader header;
+ memcpy(&header, buf.data(), qktxh_headerSize);
+ if (!checkHeader(header)) {
+ qWarning(lcQtGuiTextureIO, "Unsupported KTX file format in %s", logName().constData());
return QTextureFileData();
}
QTextureFileData texData;
texData.setData(buf);
- texData.setSize(QSize(decode(header->pixelWidth), decode(header->pixelHeight)));
- texData.setGLFormat(decode(header->glFormat));
- texData.setGLInternalFormat(decode(header->glInternalFormat));
- texData.setGLBaseInternalFormat(decode(header->glBaseInternalFormat));
-
- texData.setNumLevels(decode(header->numberOfMipmapLevels));
- quint32 offset = headerSize + decode(header->bytesOfKeyValueData);
- const int maxLevels = qMin(texData.numLevels(), 32); // Cap iterations in case of corrupt file.
- for (int i = 0; i < maxLevels; i++) {
- if (offset + sizeof(KTXMipmapLevel) > dataSize) // Corrupt file; avoid oob read
- break;
- const KTXMipmapLevel *level = reinterpret_cast<const KTXMipmapLevel *>(buf.constData() + offset);
- quint32 levelLen = decode(level->imageSize);
- texData.setDataOffset(offset + sizeof(KTXMipmapLevel::imageSize), i);
- texData.setDataLength(levelLen, i);
- offset += sizeof(KTXMipmapLevel::imageSize) + levelLen + (3 - ((levelLen + 3) % 4));
+ texData.setSize(QSize(decode(header.pixelWidth), decode(header.pixelHeight)));
+ texData.setGLFormat(decode(header.glFormat));
+ texData.setGLInternalFormat(decode(header.glInternalFormat));
+ texData.setGLBaseInternalFormat(decode(header.glBaseInternalFormat));
+
+ texData.setNumLevels(decode(header.numberOfMipmapLevels));
+ texData.setNumFaces(decode(header.numberOfFaces));
+
+ const quint32 bytesOfKeyValueData = decode(header.bytesOfKeyValueData);
+ quint32 headerKeyValueSize;
+ if (qAddOverflow(qktxh_headerSize, bytesOfKeyValueData, &headerKeyValueSize)) {
+ qWarning(lcQtGuiTextureIO, "Overflow in size of key value data in header of KTX file %s",
+ logName().constData());
+ return QTextureFileData();
+ }
+
+ if (headerKeyValueSize >= quint32(buf.size())) {
+ qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ // File contains key/values
+ if (bytesOfKeyValueData > 0) {
+ auto keyValueDataView = safeView(buf, qktxh_headerSize, bytesOfKeyValueData);
+ if (keyValueDataView.isEmpty()) {
+ qWarning(lcQtGuiTextureIO, "Invalid view in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ auto keyValues = decodeKeyValues(keyValueDataView);
+ if (!keyValues) {
+ qWarning(lcQtGuiTextureIO, "Could not parse key values in KTX file %s",
+ logName().constData());
+ return QTextureFileData();
+ }
+
+ texData.setKeyValueMetadata(*keyValues);
+ }
+
+ // Technically, any number of levels is allowed but if the value is bigger than
+ // what is possible in KTX V2 (and what makes sense) we return an error.
+ // maxLevels = log2(max(width, height, depth))
+ const int maxLevels = (sizeof(quint32) * 8)
+ - qCountLeadingZeroBits(std::max(
+ { header.pixelWidth, header.pixelHeight, header.pixelDepth }));
+
+ if (texData.numLevels() > maxLevels) {
+ qWarning(lcQtGuiTextureIO, "Too many levels in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ if (texData.numFaces() != 1 && texData.numFaces() != 6) {
+ qWarning(lcQtGuiTextureIO, "Invalid number of faces in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ quint32 offset = headerKeyValueSize;
+ for (int level = 0; level < texData.numLevels(); level++) {
+ const auto imageSizeView = safeView(buf, offset, sizeof(quint32));
+ if (imageSizeView.isEmpty()) {
+ qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ const quint32 imageSize = decode(qFromUnaligned<quint32>(imageSizeView.data()));
+ offset += sizeof(quint32); // overflow checked indirectly above
+
+ for (int face = 0; face < texData.numFaces(); face++) {
+ texData.setDataOffset(offset, level, face);
+ texData.setDataLength(imageSize, level, face);
+
+ // Add image data and padding to offset
+ const auto padded = nearestMultipleOf4(imageSize);
+ if (!padded) {
+ qWarning(lcQtGuiTextureIO, "Overflow in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ quint32 offsetNext;
+ if (qAddOverflow(offset, *padded, &offsetNext)) {
+ qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ offset = offsetNext;
+ }
}
if (!texData.isValid()) {
- qCDebug(lcQtGuiTextureIO, "Invalid values in header of KTX file %s", logName().constData());
+ qWarning(lcQtGuiTextureIO, "Invalid values in header of KTX file %s",
+ logName().constData());
return QTextureFileData();
}
@@ -174,9 +244,12 @@ bool QKtxHandler::checkHeader(const KTXHeader &header)
qDebug("Header of %s:", logName().constData());
qDebug(" glType: 0x%x (%s)", decode(header.glType), ptme.valueToKey(decode(header.glType)));
qDebug(" glTypeSize: %u", decode(header.glTypeSize));
- qDebug(" glFormat: 0x%x (%s)", decode(header.glFormat), tfme.valueToKey(decode(header.glFormat)));
- qDebug(" glInternalFormat: 0x%x (%s)", decode(header.glInternalFormat), tfme.valueToKey(decode(header.glInternalFormat)));
- qDebug(" glBaseInternalFormat: 0x%x (%s)", decode(header.glBaseInternalFormat), tfme.valueToKey(decode(header.glBaseInternalFormat)));
+ qDebug(" glFormat: 0x%x (%s)", decode(header.glFormat),
+ tfme.valueToKey(decode(header.glFormat)));
+ qDebug(" glInternalFormat: 0x%x (%s)", decode(header.glInternalFormat),
+ tfme.valueToKey(decode(header.glInternalFormat)));
+ qDebug(" glBaseInternalFormat: 0x%x (%s)", decode(header.glBaseInternalFormat),
+ tfme.valueToKey(decode(header.glBaseInternalFormat)));
qDebug(" pixelWidth: %u", decode(header.pixelWidth));
qDebug(" pixelHeight: %u", decode(header.pixelHeight));
qDebug(" pixelDepth: %u", decode(header.pixelDepth));
@@ -185,13 +258,97 @@ bool QKtxHandler::checkHeader(const KTXHeader &header)
qDebug(" numberOfMipmapLevels: %u", decode(header.numberOfMipmapLevels));
qDebug(" bytesOfKeyValueData: %u", decode(header.bytesOfKeyValueData));
#endif
- return ((decode(header.glType) == 0) &&
- (decode(header.glFormat) == 0) &&
- (decode(header.pixelDepth) == 0) &&
- (decode(header.numberOfFaces) == 1));
+ const bool isCompressedImage = decode(header.glType) == 0 && decode(header.glFormat) == 0
+ && decode(header.pixelDepth) == 0;
+ const bool isCubeMap = decode(header.numberOfFaces) == 6;
+ const bool is2D = decode(header.pixelDepth) == 0 && decode(header.numberOfArrayElements) == 0;
+
+ return is2D && (isCubeMap || isCompressedImage);
+}
+
+std::optional<QMap<QByteArray, QByteArray>> QKtxHandler::decodeKeyValues(QByteArrayView view) const
+{
+ QMap<QByteArray, QByteArray> output;
+ quint32 offset = 0;
+ while (offset < quint32(view.size())) {
+ const auto keyAndValueByteSizeView = safeView(view, offset, sizeof(quint32));
+ if (keyAndValueByteSizeView.isEmpty()) {
+ qWarning(lcQtGuiTextureIO, "Invalid view in KTX key-value");
+ return std::nullopt;
+ }
+
+ const quint32 keyAndValueByteSize =
+ decode(qFromUnaligned<quint32>(keyAndValueByteSizeView.data()));
+
+ quint32 offsetKeyAndValueStart;
+ if (qAddOverflow(offset, quint32(sizeof(quint32)), &offsetKeyAndValueStart)) {
+ qWarning(lcQtGuiTextureIO, "Overflow in KTX key-value");
+ return std::nullopt;
+ }
+
+ quint32 offsetKeyAndValueEnd;
+ if (qAddOverflow(offsetKeyAndValueStart, keyAndValueByteSize, &offsetKeyAndValueEnd)) {
+ qWarning(lcQtGuiTextureIO, "Overflow in KTX key-value");
+ return std::nullopt;
+ }
+
+ const auto keyValueView = safeView(view, offsetKeyAndValueStart, keyAndValueByteSize);
+ if (keyValueView.isEmpty()) {
+ qWarning(lcQtGuiTextureIO, "Invalid view in KTX key-value");
+ return std::nullopt;
+ }
+
+ // 'key' is a UTF-8 string ending with a null terminator, 'value' is the rest.
+ // To separate the key and value we convert the complete data to utf-8 and find the first
+ // null terminator from the left, here we split the data into two.
+
+ const int idx = keyValueView.indexOf('\0');
+ if (idx == -1) {
+ qWarning(lcQtGuiTextureIO, "Invalid key in KTX key-value");
+ return std::nullopt;
+ }
+
+ const QByteArrayView keyView = safeView(view, offsetKeyAndValueStart, idx);
+ if (keyView.isEmpty()) {
+ qWarning(lcQtGuiTextureIO, "Overflow in KTX key-value");
+ return std::nullopt;
+ }
+
+ const quint32 keySize = idx + 1; // Actual data size
+
+ quint32 offsetValueStart;
+ if (qAddOverflow(offsetKeyAndValueStart, keySize, &offsetValueStart)) {
+ qWarning(lcQtGuiTextureIO, "Overflow in KTX key-value");
+ return std::nullopt;
+ }
+
+ quint32 valueSize;
+ if (qSubOverflow(keyAndValueByteSize, keySize, &valueSize)) {
+ qWarning(lcQtGuiTextureIO, "Underflow in KTX key-value");
+ return std::nullopt;
+ }
+
+ const QByteArrayView valueView = safeView(view, offsetValueStart, valueSize);
+ if (valueView.isEmpty()) {
+ qWarning(lcQtGuiTextureIO, "Invalid view in KTX key-value");
+ return std::nullopt;
+ }
+
+ output.insert(keyView.toByteArray(), valueView.toByteArray());
+
+ const auto offsetNext = nearestMultipleOf4(offsetKeyAndValueEnd);
+ if (!offsetNext) {
+ qWarning(lcQtGuiTextureIO, "Overflow in KTX key-value");
+ return std::nullopt;
+ }
+
+ offset = *offsetNext;
+ }
+
+ return output;
}
-quint32 QKtxHandler::decode(quint32 val)
+quint32 QKtxHandler::decode(quint32 val) const
{
return inverseEndian ? qbswap<quint32>(val) : val;
}
diff --git a/src/gui/util/qktxhandler_p.h b/src/gui/util/qktxhandler_p.h
index 19f7b0e79a..3a0b8fcf7e 100644
--- a/src/gui/util/qktxhandler_p.h
+++ b/src/gui/util/qktxhandler_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QKTXHANDLER_H
#define QKTXHANDLER_H
@@ -53,6 +17,8 @@
#include "qtexturefilehandler_p.h"
+#include <optional>
+
QT_BEGIN_NAMESPACE
struct KTXHeader;
@@ -61,6 +27,7 @@ class QKtxHandler : public QTextureFileHandler
{
public:
using QTextureFileHandler::QTextureFileHandler;
+ ~QKtxHandler() override;
static bool canRead(const QByteArray &suffix, const QByteArray &block);
@@ -68,7 +35,8 @@ public:
private:
bool checkHeader(const KTXHeader &header);
- quint32 decode(quint32 val);
+ std::optional<QMap<QByteArray, QByteArray>> decodeKeyValues(QByteArrayView view) const;
+ quint32 decode(quint32 val) const;
bool inverseEndian = false;
};
diff --git a/src/gui/util/qlayoutpolicy.cpp b/src/gui/util/qlayoutpolicy.cpp
index 507df44a45..2e3a0b32cb 100644
--- a/src/gui/util/qlayoutpolicy.cpp
+++ b/src/gui/util/qlayoutpolicy.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qlayoutpolicy_p.h"
#include <QtCore/qdebug.h>
@@ -133,3 +97,5 @@ QDebug operator<<(QDebug dbg, const QLayoutPolicy &p)
#endif
QT_END_NAMESPACE
+
+#include "moc_qlayoutpolicy_p.cpp"
diff --git a/src/gui/util/qlayoutpolicy_p.h b/src/gui/util/qlayoutpolicy_p.h
index 6457aeb653..bbdabd0c7b 100644
--- a/src/gui/util/qlayoutpolicy_p.h
+++ b/src/gui/util/qlayoutpolicy_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QLAYOUTPOLICY_H
#define QLAYOUTPOLICY_H
@@ -64,10 +28,9 @@ QT_BEGIN_NAMESPACE
class QVariant;
-class Q_GUI_EXPORT QLayoutPolicy
+class QLayoutPolicy
{
- Q_GADGET
- Q_ENUMS(Policy)
+ Q_GADGET_EXPORT(Q_GUI_EXPORT)
public:
enum PolicyFlag {
@@ -76,16 +39,16 @@ public:
ShrinkFlag = 4,
IgnoreFlag = 8
};
+ Q_DECLARE_FLAGS(Policy, PolicyFlag)
+ Q_FLAG(Policy)
- enum Policy {
- Fixed = 0,
- Minimum = GrowFlag,
- Maximum = ShrinkFlag,
- Preferred = GrowFlag | ShrinkFlag,
- MinimumExpanding = GrowFlag | ExpandFlag,
- Expanding = GrowFlag | ShrinkFlag | ExpandFlag,
- Ignored = ShrinkFlag | GrowFlag | IgnoreFlag
- };
+ static constexpr inline Policy Fixed = {};
+ static constexpr inline Policy Minimum = GrowFlag;
+ static constexpr inline Policy Maximum = ShrinkFlag;
+ static constexpr inline Policy Preferred = Minimum | Maximum;
+ static constexpr inline Policy MinimumExpanding = Minimum | ExpandFlag;
+ static constexpr inline Policy Expanding = Preferred | ExpandFlag;
+ static constexpr inline Policy Ignored = Preferred | IgnoreFlag;
enum ControlType {
DefaultType = 0x00000001,
@@ -116,11 +79,11 @@ public:
}
Policy horizontalPolicy() const { return static_cast<Policy>(bits.horPolicy); }
Policy verticalPolicy() const { return static_cast<Policy>(bits.verPolicy); }
- ControlType controlType() const;
+ Q_GUI_EXPORT ControlType controlType() const;
void setHorizontalPolicy(Policy d) { bits.horPolicy = d; }
void setVerticalPolicy(Policy d) { bits.verPolicy = d; }
- void setControlType(ControlType type);
+ Q_GUI_EXPORT void setControlType(ControlType type);
Qt::Orientations expandingDirections() const {
Qt::Orientations result;
@@ -144,7 +107,7 @@ public:
void setHorizontalStretch(int stretchFactor) { bits.horStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
void setVerticalStretch(int stretchFactor) { bits.verStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
- void transpose();
+ inline void transpose();
private:
@@ -169,6 +132,7 @@ private:
};
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QLayoutPolicy::Policy)
Q_DECLARE_OPERATORS_FOR_FLAGS(QLayoutPolicy::ControlTypes)
#ifndef QT_NO_DATASTREAM
diff --git a/src/gui/util/qpkmhandler.cpp b/src/gui/util/qpkmhandler.cpp
index e0c3b75efe..d84ce2ce7f 100644
--- a/src/gui/util/qpkmhandler.cpp
+++ b/src/gui/util/qpkmhandler.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qpkmhandler_p.h"
#include "qtexturefiledata_p.h"
@@ -49,7 +13,7 @@
QT_BEGIN_NAMESPACE
-static const int headerSize = 16;
+static const int qpkmh_headerSize = 16;
struct PkmType
{
@@ -57,7 +21,7 @@ struct PkmType
quint32 bytesPerBlock;
};
-static PkmType typeMap[5] = {
+static constexpr PkmType typeMap[5] = {
{ 0x8D64, 8 }, // GL_ETC1_RGB8_OES
{ 0x9274, 8 }, // GL_COMPRESSED_RGB8_ETC2
{ 0, 0 }, // unused (obsolete)
@@ -65,9 +29,11 @@ static PkmType typeMap[5] = {
{ 0x9276, 8 } // GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
};
+QPkmHandler::~QPkmHandler() = default;
+
bool QPkmHandler::canRead(const QByteArray &suffix, const QByteArray &block)
{
- Q_UNUSED(suffix)
+ Q_UNUSED(suffix);
return block.startsWith("PKM ");
}
@@ -80,7 +46,7 @@ QTextureFileData QPkmHandler::read()
return texData;
QByteArray fileData = device()->readAll();
- if (fileData.size() < headerSize || !canRead(QByteArray(), fileData)) {
+ if (fileData.size() < qpkmh_headerSize || !canRead(QByteArray(), fileData)) {
qCDebug(lcQtGuiTextureIO, "Invalid PKM file %s", logName().constData());
return QTextureFileData();
}
@@ -102,13 +68,14 @@ QTextureFileData QPkmHandler::read()
// texture size
texData.setNumLevels(1);
+ texData.setNumFaces(1);
const int bpb = typeMap[type].bytesPerBlock;
QSize paddedSize(qFromBigEndian<quint16>(rawData + 8), qFromBigEndian<quint16>(rawData + 10));
texData.setDataLength((paddedSize.width() / 4) * (paddedSize.height() / 4) * bpb);
QSize texSize(qFromBigEndian<quint16>(rawData + 12), qFromBigEndian<quint16>(rawData + 14));
texData.setSize(texSize);
- texData.setDataOffset(headerSize);
+ texData.setDataOffset(qpkmh_headerSize);
if (!texData.isValid()) {
qCDebug(lcQtGuiTextureIO, "Invalid values in header of PKM file %s", logName().constData());
diff --git a/src/gui/util/qpkmhandler_p.h b/src/gui/util/qpkmhandler_p.h
index 2f7618bc53..a773b44fb2 100644
--- a/src/gui/util/qpkmhandler_p.h
+++ b/src/gui/util/qpkmhandler_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPKMHANDLER_H
#define QPKMHANDLER_H
@@ -59,6 +23,7 @@ class QPkmHandler : public QTextureFileHandler
{
public:
using QTextureFileHandler::QTextureFileHandler;
+ ~QPkmHandler() override;
static bool canRead(const QByteArray &suffix, const QByteArray &block);
diff --git a/src/gui/util/qshaderformat.cpp b/src/gui/util/qshaderformat.cpp
deleted file mode 100644
index ea86dd6ca5..0000000000
--- a/src/gui/util/qshaderformat.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qshaderformat_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QShaderFormat::QShaderFormat() noexcept
- : m_api(NoApi)
- , m_shaderType(Fragment)
-{
-}
-
-QShaderFormat::Api QShaderFormat::api() const noexcept
-{
- return m_api;
-}
-
-void QShaderFormat::setApi(QShaderFormat::Api api) noexcept
-{
- m_api = api;
-}
-
-QVersionNumber QShaderFormat::version() const noexcept
-{
- return m_version;
-}
-
-void QShaderFormat::setVersion(const QVersionNumber &version) noexcept
-{
- m_version = version;
-}
-
-QStringList QShaderFormat::extensions() const noexcept
-{
- return m_extensions;
-}
-
-void QShaderFormat::setExtensions(const QStringList &extensions) noexcept
-{
- m_extensions = extensions;
- m_extensions.sort();
-}
-
-QString QShaderFormat::vendor() const noexcept
-{
- return m_vendor;
-}
-
-void QShaderFormat::setVendor(const QString &vendor) noexcept
-{
- m_vendor = vendor;
-}
-
-bool QShaderFormat::isValid() const noexcept
-{
- return m_api != NoApi && m_version.majorVersion() > 0;
-}
-
-bool QShaderFormat::supports(const QShaderFormat &other) const noexcept
-{
- if (!isValid() || !other.isValid())
- return false;
-
- if (m_api == OpenGLES && m_api != other.m_api)
- return false;
-
- if (m_api == OpenGLCoreProfile && m_api != other.m_api)
- return false;
-
- if (m_version < other.m_version)
- return false;
-
- if (m_shaderType != other.m_shaderType)
- return false;
-
- const auto containsAllExtensionsFromOther = std::includes(m_extensions.constBegin(),
- m_extensions.constEnd(),
- other.m_extensions.constBegin(),
- other.m_extensions.constEnd());
- if (!containsAllExtensionsFromOther)
- return false;
-
- if (!other.m_vendor.isEmpty() && m_vendor != other.m_vendor)
- return false;
-
- return true;
-}
-
-QShaderFormat::ShaderType QShaderFormat::shaderType() const Q_DECL_NOTHROW
-{
- return m_shaderType;
-}
-
-void QShaderFormat::setShaderType(QShaderFormat::ShaderType shaderType) Q_DECL_NOTHROW
-{
- m_shaderType = shaderType;
-}
-
-bool operator==(const QShaderFormat &lhs, const QShaderFormat &rhs) noexcept
-{
- return lhs.api() == rhs.api()
- && lhs.version() == rhs.version()
- && lhs.extensions() == rhs.extensions()
- && lhs.vendor() == rhs.vendor()
- && lhs.shaderType() == rhs.shaderType();
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/util/qshaderformat_p.h b/src/gui/util/qshaderformat_p.h
deleted file mode 100644
index c50d7d5729..0000000000
--- a/src/gui/util/qshaderformat_p.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSHADERFORMAT_P_H
-#define QSHADERFORMAT_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 <QtGui/private/qtguiglobal_p.h>
-
-#include <QtCore/qstringlist.h>
-#include <QtCore/qversionnumber.h>
-
-QT_BEGIN_NAMESPACE
-
-class QShaderFormat
-{
-public:
- enum Api : int {
- NoApi,
- OpenGLNoProfile,
- OpenGLCoreProfile,
- OpenGLCompatibilityProfile,
- OpenGLES
- };
-
- enum ShaderType : int {
- Vertex = 0,
- TessellationControl,
- TessellationEvaluation,
- Geometry,
- Fragment,
- Compute
- };
-
- Q_GUI_EXPORT QShaderFormat() noexcept;
-
- Q_GUI_EXPORT Api api() const noexcept;
- Q_GUI_EXPORT void setApi(Api api) noexcept;
-
- Q_GUI_EXPORT QVersionNumber version() const noexcept;
- Q_GUI_EXPORT void setVersion(const QVersionNumber &version) noexcept;
-
- Q_GUI_EXPORT QStringList extensions() const noexcept;
- Q_GUI_EXPORT void setExtensions(const QStringList &extensions) noexcept;
-
- Q_GUI_EXPORT QString vendor() const noexcept;
- Q_GUI_EXPORT void setVendor(const QString &vendor) noexcept;
-
- Q_GUI_EXPORT bool isValid() const noexcept;
- Q_GUI_EXPORT bool supports(const QShaderFormat &other) const noexcept;
-
- Q_GUI_EXPORT ShaderType shaderType() const Q_DECL_NOTHROW;
- Q_GUI_EXPORT void setShaderType(ShaderType shaderType) Q_DECL_NOTHROW;
-
-private:
- Api m_api;
- QVersionNumber m_version;
- QStringList m_extensions;
- QString m_vendor;
- ShaderType m_shaderType;
-};
-
-Q_GUI_EXPORT bool operator==(const QShaderFormat &lhs, const QShaderFormat &rhs) noexcept;
-
-inline bool operator!=(const QShaderFormat &lhs, const QShaderFormat &rhs) noexcept
-{
- return !(lhs == rhs);
-}
-
-Q_DECLARE_TYPEINFO(QShaderFormat, Q_MOVABLE_TYPE);
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QShaderFormat)
-
-#endif // QSHADERFORMAT_P_H
diff --git a/src/gui/util/qshadergenerator.cpp b/src/gui/util/qshadergenerator.cpp
deleted file mode 100644
index 4beed8ed25..0000000000
--- a/src/gui/util/qshadergenerator.cpp
+++ /dev/null
@@ -1,594 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qshadergenerator_p.h"
-
-#include "qshaderlanguage_p.h"
-#include <QRegularExpression>
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(ShaderGenerator, "ShaderGenerator", QtWarningMsg)
-
-namespace
-{
- QByteArray toGlsl(QShaderLanguage::StorageQualifier qualifier, const QShaderFormat &format)
- {
- if (format.version().majorVersion() <= 2) {
- // Note we're assuming fragment shader only here, it'd be different
- // values for vertex shader, will need to be fixed properly at some
- // point but isn't necessary yet (this problem already exists in past
- // commits anyway)
- switch (qualifier) {
- case QShaderLanguage::Const:
- return "const";
- case QShaderLanguage::Input:
- if (format.shaderType() == QShaderFormat::Vertex)
- return "attribute";
- else
- return "varying";
- case QShaderLanguage::Output:
- return ""; // Although fragment shaders for <=2 only have fixed outputs
- case QShaderLanguage::Uniform:
- return "uniform";
- case QShaderLanguage::BuiltIn:
- return "//";
- }
- } else {
- switch (qualifier) {
- case QShaderLanguage::Const:
- return "const";
- case QShaderLanguage::Input:
- return "in";
- case QShaderLanguage::Output:
- return "out";
- case QShaderLanguage::Uniform:
- return "uniform";
- case QShaderLanguage::BuiltIn:
- return "//";
- }
- }
-
- Q_UNREACHABLE();
- }
-
- QByteArray toGlsl(QShaderLanguage::VariableType type)
- {
- switch (type) {
- case QShaderLanguage::Bool:
- return "bool";
- case QShaderLanguage::Int:
- return "int";
- case QShaderLanguage::Uint:
- return "uint";
- case QShaderLanguage::Float:
- return "float";
- case QShaderLanguage::Double:
- return "double";
- case QShaderLanguage::Vec2:
- return "vec2";
- case QShaderLanguage::Vec3:
- return "vec3";
- case QShaderLanguage::Vec4:
- return "vec4";
- case QShaderLanguage::DVec2:
- return "dvec2";
- case QShaderLanguage::DVec3:
- return "dvec3";
- case QShaderLanguage::DVec4:
- return "dvec4";
- case QShaderLanguage::BVec2:
- return "bvec2";
- case QShaderLanguage::BVec3:
- return "bvec3";
- case QShaderLanguage::BVec4:
- return "bvec4";
- case QShaderLanguage::IVec2:
- return "ivec2";
- case QShaderLanguage::IVec3:
- return "ivec3";
- case QShaderLanguage::IVec4:
- return "ivec4";
- case QShaderLanguage::UVec2:
- return "uvec2";
- case QShaderLanguage::UVec3:
- return "uvec3";
- case QShaderLanguage::UVec4:
- return "uvec4";
- case QShaderLanguage::Mat2:
- return "mat2";
- case QShaderLanguage::Mat3:
- return "mat3";
- case QShaderLanguage::Mat4:
- return "mat4";
- case QShaderLanguage::Mat2x2:
- return "mat2x2";
- case QShaderLanguage::Mat2x3:
- return "mat2x3";
- case QShaderLanguage::Mat2x4:
- return "mat2x4";
- case QShaderLanguage::Mat3x2:
- return "mat3x2";
- case QShaderLanguage::Mat3x3:
- return "mat3x3";
- case QShaderLanguage::Mat3x4:
- return "mat3x4";
- case QShaderLanguage::Mat4x2:
- return "mat4x2";
- case QShaderLanguage::Mat4x3:
- return "mat4x3";
- case QShaderLanguage::Mat4x4:
- return "mat4x4";
- case QShaderLanguage::DMat2:
- return "dmat2";
- case QShaderLanguage::DMat3:
- return "dmat3";
- case QShaderLanguage::DMat4:
- return "dmat4";
- case QShaderLanguage::DMat2x2:
- return "dmat2x2";
- case QShaderLanguage::DMat2x3:
- return "dmat2x3";
- case QShaderLanguage::DMat2x4:
- return "dmat2x4";
- case QShaderLanguage::DMat3x2:
- return "dmat3x2";
- case QShaderLanguage::DMat3x3:
- return "dmat3x3";
- case QShaderLanguage::DMat3x4:
- return "dmat3x4";
- case QShaderLanguage::DMat4x2:
- return "dmat4x2";
- case QShaderLanguage::DMat4x3:
- return "dmat4x3";
- case QShaderLanguage::DMat4x4:
- return "dmat4x4";
- case QShaderLanguage::Sampler1D:
- return "sampler1D";
- case QShaderLanguage::Sampler2D:
- return "sampler2D";
- case QShaderLanguage::Sampler3D:
- return "sampler3D";
- case QShaderLanguage::SamplerCube:
- return "samplerCube";
- case QShaderLanguage::Sampler2DRect:
- return "sampler2DRect";
- case QShaderLanguage::Sampler2DMs:
- return "sampler2DMS";
- case QShaderLanguage::SamplerBuffer:
- return "samplerBuffer";
- case QShaderLanguage::Sampler1DArray:
- return "sampler1DArray";
- case QShaderLanguage::Sampler2DArray:
- return "sampler2DArray";
- case QShaderLanguage::Sampler2DMsArray:
- return "sampler2DMSArray";
- case QShaderLanguage::SamplerCubeArray:
- return "samplerCubeArray";
- case QShaderLanguage::Sampler1DShadow:
- return "sampler1DShadow";
- case QShaderLanguage::Sampler2DShadow:
- return "sampler2DShadow";
- case QShaderLanguage::Sampler2DRectShadow:
- return "sampler2DRectShadow";
- case QShaderLanguage::Sampler1DArrayShadow:
- return "sampler1DArrayShadow";
- case QShaderLanguage::Sampler2DArrayShadow:
- return "sample2DArrayShadow";
- case QShaderLanguage::SamplerCubeShadow:
- return "samplerCubeShadow";
- case QShaderLanguage::SamplerCubeArrayShadow:
- return "samplerCubeArrayShadow";
- case QShaderLanguage::ISampler1D:
- return "isampler1D";
- case QShaderLanguage::ISampler2D:
- return "isampler2D";
- case QShaderLanguage::ISampler3D:
- return "isampler3D";
- case QShaderLanguage::ISamplerCube:
- return "isamplerCube";
- case QShaderLanguage::ISampler2DRect:
- return "isampler2DRect";
- case QShaderLanguage::ISampler2DMs:
- return "isampler2DMS";
- case QShaderLanguage::ISamplerBuffer:
- return "isamplerBuffer";
- case QShaderLanguage::ISampler1DArray:
- return "isampler1DArray";
- case QShaderLanguage::ISampler2DArray:
- return "isampler2DArray";
- case QShaderLanguage::ISampler2DMsArray:
- return "isampler2DMSArray";
- case QShaderLanguage::ISamplerCubeArray:
- return "isamplerCubeArray";
- case QShaderLanguage::USampler1D:
- return "usampler1D";
- case QShaderLanguage::USampler2D:
- return "usampler2D";
- case QShaderLanguage::USampler3D:
- return "usampler3D";
- case QShaderLanguage::USamplerCube:
- return "usamplerCube";
- case QShaderLanguage::USampler2DRect:
- return "usampler2DRect";
- case QShaderLanguage::USampler2DMs:
- return "usampler2DMS";
- case QShaderLanguage::USamplerBuffer:
- return "usamplerBuffer";
- case QShaderLanguage::USampler1DArray:
- return "usampler1DArray";
- case QShaderLanguage::USampler2DArray:
- return "usampler2DArray";
- case QShaderLanguage::USampler2DMsArray:
- return "usampler2DMSArray";
- case QShaderLanguage::USamplerCubeArray:
- return "usamplerCubeArray";
- }
-
- Q_UNREACHABLE();
- }
-
- QByteArray replaceParameters(const QByteArray &original, const QShaderNode &node, const QShaderFormat &format)
- {
- QByteArray result = original;
-
- const QStringList parameterNames = node.parameterNames();
- for (const QString &parameterName : parameterNames) {
- const QByteArray placeholder = QByteArray(QByteArrayLiteral("$") + parameterName.toUtf8());
- const QVariant parameter = node.parameter(parameterName);
- if (parameter.userType() == qMetaTypeId<QShaderLanguage::StorageQualifier>()) {
- const QShaderLanguage::StorageQualifier qualifier = qvariant_cast<QShaderLanguage::StorageQualifier>(parameter);
- const QByteArray value = toGlsl(qualifier, format);
- result.replace(placeholder, value);
- } else if (parameter.userType() == qMetaTypeId<QShaderLanguage::VariableType>()) {
- const QShaderLanguage::VariableType type = qvariant_cast<QShaderLanguage::VariableType>(parameter);
- const QByteArray value = toGlsl(type);
- result.replace(placeholder, value);
- } else {
- const QByteArray value = parameter.toString().toUtf8();
- result.replace(placeholder, value);
- }
- }
-
- return result;
- }
-}
-
-QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers) const
-{
- auto code = QByteArrayList();
-
- if (format.isValid()) {
- const bool isGLES = format.api() == QShaderFormat::OpenGLES;
- const int major = format.version().majorVersion();
- const int minor = format.version().minorVersion();
-
- const int version = major == 2 && isGLES ? 100
- : major == 3 && isGLES ? 300
- : major == 2 ? 100 + 10 * (minor + 1)
- : major == 3 && minor <= 2 ? 100 + 10 * (minor + 3)
- : major * 100 + minor * 10;
-
- const QByteArray profile = isGLES && version > 100 ? QByteArrayLiteral(" es")
- : version >= 150 && format.api() == QShaderFormat::OpenGLCoreProfile ? QByteArrayLiteral(" core")
- : version >= 150 && format.api() == QShaderFormat::OpenGLCompatibilityProfile ? QByteArrayLiteral(" compatibility")
- : QByteArray();
-
- code << (QByteArrayLiteral("#version ") + QByteArray::number(version) + profile);
- code << QByteArray();
- }
-
- const auto intersectsEnabledLayers = [enabledLayers] (const QStringList &layers) {
- return layers.isEmpty()
- || std::any_of(layers.cbegin(), layers.cend(),
- [enabledLayers] (const QString &s) { return enabledLayers.contains(s); });
- };
-
- QVector<QString> globalInputVariables;
- const QRegularExpression globalInputExtractRegExp(QStringLiteral("^.*\\s+(\\w+).*;$"));
-
- const QVector<QShaderNode> nodes = graph.nodes();
- for (const QShaderNode &node : nodes) {
- if (intersectsEnabledLayers(node.layers())) {
- const QByteArrayList headerSnippets = node.rule(format).headerSnippets;
- for (const QByteArray &snippet : headerSnippets) {
- code << replaceParameters(snippet, node, format);
-
- // If node is an input, record the variable name into the globalInputVariables vector
- if (node.type() == QShaderNode::Input) {
- const QRegularExpressionMatch match = globalInputExtractRegExp.match(QString::fromUtf8(code.last()));
- if (match.hasMatch())
- globalInputVariables.push_back(match.captured(1));
- }
- }
- }
- }
-
- code << QByteArray();
- code << QByteArrayLiteral("void main()");
- code << QByteArrayLiteral("{");
-
- const QRegularExpression localToGlobalRegExp(QStringLiteral("^.*\\s+(\\w+)\\s*=\\s*((?:\\w+\\(.*\\))|(?:\\w+)).*;$"));
- const QRegularExpression temporaryVariableToAssignmentRegExp(QStringLiteral("^(.*\\s+(v\\d+))\\s*=\\s*(.*);$"));
- const QRegularExpression temporaryVariableInAssignmentRegExp(QStringLiteral("\\W*(v\\d+)\\W*"));
- const QRegularExpression outputToTemporaryAssignmentRegExp(QStringLiteral("^\\s*(\\w+)\\s*=\\s*(.*);$"));
-
- struct Variable;
-
- struct Assignment
- {
- QString expression;
- QVector<Variable *> referencedVariables;
- };
-
- struct Variable
- {
- enum Type {
- GlobalInput,
- TemporaryAssignment,
- Output
- };
-
- QString name;
- QString declaration;
- int referenceCount = 0;
- Assignment assignment;
- Type type = TemporaryAssignment;
- bool substituted = false;
-
- static void substitute(Variable *v)
- {
- if (v->substituted)
- return;
-
- qCDebug(ShaderGenerator) << "Begin Substituting " << v->name << " = " << v->assignment.expression;
- for (Variable *ref : qAsConst(v->assignment.referencedVariables)) {
- // Recursively substitute
- Variable::substitute(ref);
-
- // Replace all variables referenced only once in the assignment
- // by their actual expression
- if (ref->referenceCount == 1 || ref->type == Variable::GlobalInput) {
- const QRegularExpression r(QStringLiteral("(.*\\b)(%1)(\\b.*)").arg(ref->name));
- if (v->assignment.referencedVariables.size() == 1)
- v->assignment.expression.replace(r,
- QStringLiteral("\\1%2\\3").arg(ref->assignment.expression));
- else
- v->assignment.expression.replace(r,
- QStringLiteral("(\\1%2\\3)").arg(ref->assignment.expression));
- }
- }
- qCDebug(ShaderGenerator) << "Done Substituting " << v->name << " = " << v->assignment.expression;
- v->substituted = true;
- }
- };
-
- struct LineContent
- {
- QByteArray rawContent;
- Variable *var = nullptr;
- };
-
- // Table to store temporary variables that should be replaced:
- // - If variable references a a global variables
- // -> we will use the global variable directly
- // - If variable references a function results
- // -> will be kept only if variable is referenced more than once.
- // This avoids having vec3 v56 = vertexPosition; when we could
- // just use vertexPosition directly.
- // The added benefit is when having arrays, we don't try to create
- // mat4 v38 = skinningPalelette[100] which would be invalid
- QVector<Variable> temporaryVariables;
- // Reserve more than enough space to ensure no reallocation will take place
- temporaryVariables.reserve(nodes.size() * 8);
-
- QVector<LineContent> lines;
-
- auto createVariable = [&] () -> Variable * {
- Q_ASSERT(temporaryVariables.capacity() > 0);
- temporaryVariables.resize(temporaryVariables.size() + 1);
- return &temporaryVariables.last();
- };
-
- auto findVariable = [&] (const QString &name) -> Variable * {
- const auto end = temporaryVariables.end();
- auto it = std::find_if(temporaryVariables.begin(), end,
- [=] (const Variable &a) { return a.name == name; });
- if (it != end)
- return &(*it);
- return nullptr;
- };
-
- auto gatherTemporaryVariablesFromAssignment = [&] (Variable *v, const QString &assignmentContent) {
- QRegularExpressionMatchIterator subMatchIt = temporaryVariableInAssignmentRegExp.globalMatch(assignmentContent);
- while (subMatchIt.hasNext()) {
- const QRegularExpressionMatch subMatch = subMatchIt.next();
- const QString variableName = subMatch.captured(1);
-
- // Variable we care about should already exists -> an expression cannot reference a variable that hasn't been defined
- Variable *u = findVariable(variableName);
- Q_ASSERT(u);
-
- // Increase reference count for u
- ++u->referenceCount;
- // Insert u as reference for variable v
- v->assignment.referencedVariables.push_back(u);
- }
- };
-
- for (const QShaderGraph::Statement &statement : graph.createStatements(enabledLayers)) {
- const QShaderNode node = statement.node;
- QByteArray line = node.rule(format).substitution;
- const QVector<QShaderNodePort> ports = node.ports();
-
- // Generate temporary variable names vN
- for (const QShaderNodePort &port : ports) {
- const QString portName = port.name;
- const QShaderNodePort::Direction portDirection = port.direction;
- const bool isInput = port.direction == QShaderNodePort::Input;
-
- const int portIndex = statement.portIndex(portDirection, portName);
-
- Q_ASSERT(portIndex >= 0);
-
- const int variableIndex = isInput ? statement.inputs.at(portIndex)
- : statement.outputs.at(portIndex);
- if (variableIndex < 0)
- continue;
-
- const auto placeholder = QByteArray(QByteArrayLiteral("$") + portName.toUtf8());
- const auto variable = QByteArray(QByteArrayLiteral("v") + QByteArray::number(variableIndex));
-
- line.replace(placeholder, variable);
- }
-
- // Substitute variable names by generated vN variable names
- const QByteArray substitutionedLine = replaceParameters(line, node, format);
-
- Variable *v = nullptr;
-
- switch (node.type()) {
- // Record name of temporary variable that possibly references a global input
- // We will replace the temporary variables by the matching global variables later
- case QShaderNode::Input: {
- const QRegularExpressionMatch match = localToGlobalRegExp.match(QString::fromUtf8(substitutionedLine));
- if (match.hasMatch()) {
- const QString localVariable = match.captured(1);
- const QString globalVariable = match.captured(2);
-
- v = createVariable();
- v->name = localVariable;
- v->type = Variable::GlobalInput;
-
- Assignment assignment;
- assignment.expression = globalVariable;
- v->assignment = assignment;
- }
- break;
- }
-
- case QShaderNode::Function: {
- const QRegularExpressionMatch match = temporaryVariableToAssignmentRegExp.match(QString::fromUtf8(substitutionedLine));
- if (match.hasMatch()) {
- const QString localVariableDeclaration = match.captured(1);
- const QString localVariableName = match.captured(2);
- const QString assignmentContent = match.captured(3);
-
- // Add new variable -> it cannot exist already
- v = createVariable();
- v->name = localVariableName;
- v->declaration = localVariableDeclaration;
- v->assignment.expression = assignmentContent;
-
- // Find variables that may be referenced in the assignment
- gatherTemporaryVariablesFromAssignment(v, assignmentContent);
- }
- break;
- }
-
- case QShaderNode::Output: {
- const QRegularExpressionMatch match = outputToTemporaryAssignmentRegExp.match(QString::fromUtf8(substitutionedLine));
- if (match.hasMatch()) {
- const QString outputDeclaration = match.captured(1);
- const QString assignmentContent = match.captured(2);
-
- v = createVariable();
- v->name = outputDeclaration;
- v->declaration = outputDeclaration;
- v->type = Variable::Output;
-
- Assignment assignment;
- assignment.expression = assignmentContent;
- v->assignment = assignment;
-
- // Find variables that may be referenced in the assignment
- gatherTemporaryVariablesFromAssignment(v, assignmentContent);
- }
- break;
- }
- case QShaderNode::Invalid:
- break;
- }
-
- LineContent lineContent;
- lineContent.rawContent = QByteArray(QByteArrayLiteral(" ") + substitutionedLine);
- lineContent.var = v;
- lines << lineContent;
- }
-
- // Go through all lines
- // Perform substitution of line with temporary variables substitution
- for (LineContent &lineContent : lines) {
- Variable *v = lineContent.var;
- qCDebug(ShaderGenerator) << lineContent.rawContent;
- if (v != nullptr) {
- Variable::substitute(v);
-
- qCDebug(ShaderGenerator) << "Line " << lineContent.rawContent << "is assigned to temporary" << v->name;
-
- // Check number of occurrences a temporary variable is referenced
- if (v->referenceCount == 1 || v->type == Variable::GlobalInput) {
- // If it is referenced only once, no point in creating a temporary
- // Clear content for current line
- lineContent.rawContent.clear();
- // We assume expression that were referencing vN will have vN properly substituted
- } else {
- lineContent.rawContent = QStringLiteral(" %1 = %2;").arg(v->declaration)
- .arg(v->assignment.expression)
- .toUtf8();
- }
-
- qCDebug(ShaderGenerator) << "Updated Line is " << lineContent.rawContent;
- }
- }
-
- // Go throug all lines and insert content
- for (const LineContent &lineContent : qAsConst(lines)) {
- if (!lineContent.rawContent.isEmpty()) {
- code << lineContent.rawContent;
- }
- }
-
- code << QByteArrayLiteral("}");
- code << QByteArray();
-
- return code.join('\n');
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/util/qshadergenerator_p.h b/src/gui/util/qshadergenerator_p.h
deleted file mode 100644
index 1f6f9d2532..0000000000
--- a/src/gui/util/qshadergenerator_p.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSHADERGENERATOR_P_H
-#define QSHADERGENERATOR_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 <QtGui/private/qtguiglobal_p.h>
-
-#include <QtGui/private/qshadergraph_p.h>
-#include <QtCore/QLoggingCategory>
-
-
-QT_BEGIN_NAMESPACE
-
-Q_DECLARE_LOGGING_CATEGORY(ShaderGenerator)
-
-class QShaderGenerator
-{
-public:
- Q_GUI_EXPORT QByteArray createShaderCode(const QStringList &enabledLayers = QStringList()) const;
-
- QShaderGraph graph;
- QShaderFormat format;
-};
-
-Q_DECLARE_TYPEINFO(QShaderGenerator, Q_MOVABLE_TYPE);
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QShaderGenerator)
-
-#endif // QSHADERGENERATOR_P_H
diff --git a/src/gui/util/qshadergraph.cpp b/src/gui/util/qshadergraph.cpp
deleted file mode 100644
index b05b710713..0000000000
--- a/src/gui/util/qshadergraph.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qshadergraph_p.h"
-
-QT_BEGIN_NAMESPACE
-
-
-namespace
-{
- QVector<QShaderNode> copyOutputNodes(const QVector<QShaderNode> &nodes)
- {
- auto res = QVector<QShaderNode>();
- std::copy_if(nodes.cbegin(), nodes.cend(),
- std::back_inserter(res),
- [] (const QShaderNode &node) {
- return node.type() == QShaderNode::Output;
- });
- return res;
- }
-
- QVector<QShaderGraph::Edge> incomingEdges(const QVector<QShaderGraph::Edge> &edges, const QUuid &uuid)
- {
- auto res = QVector<QShaderGraph::Edge>();
- std::copy_if(edges.cbegin(), edges.cend(),
- std::back_inserter(res),
- [uuid] (const QShaderGraph::Edge &edge) {
- return edge.sourceNodeUuid == uuid;
- });
- return res;
- }
-
- QVector<QShaderGraph::Edge> outgoingEdges(const QVector<QShaderGraph::Edge> &edges, const QUuid &uuid)
- {
- auto res = QVector<QShaderGraph::Edge>();
- std::copy_if(edges.cbegin(), edges.cend(),
- std::back_inserter(res),
- [uuid] (const QShaderGraph::Edge &edge) {
- return edge.targetNodeUuid == uuid;
- });
- return res;
- }
-
- QShaderGraph::Statement nodeToStatement(const QShaderNode &node, int &nextVarId)
- {
- auto statement = QShaderGraph::Statement();
- statement.node = node;
-
- const QVector<QShaderNodePort> ports = node.ports();
- for (const QShaderNodePort &port : ports) {
- if (port.direction == QShaderNodePort::Input) {
- statement.inputs.append(-1);
- } else {
- statement.outputs.append(nextVarId);
- nextVarId++;
- }
- }
- return statement;
- }
-
- QShaderGraph::Statement completeStatement(const QHash<QUuid, QShaderGraph::Statement> &idHash,
- const QVector<QShaderGraph::Edge> edges,
- const QUuid &uuid)
- {
- auto targetStatement = idHash.value(uuid);
- for (const QShaderGraph::Edge &edge : edges) {
- if (edge.targetNodeUuid != uuid)
- continue;
-
- const QShaderGraph::Statement sourceStatement = idHash.value(edge.sourceNodeUuid);
- const int sourcePortIndex = sourceStatement.portIndex(QShaderNodePort::Output, edge.sourcePortName);
- const int targetPortIndex = targetStatement.portIndex(QShaderNodePort::Input, edge.targetPortName);
-
- if (sourcePortIndex < 0 || targetPortIndex < 0)
- continue;
-
- const QVector<int> sourceOutputs = sourceStatement.outputs;
- QVector<int> &targetInputs = targetStatement.inputs;
- targetInputs[targetPortIndex] = sourceOutputs[sourcePortIndex];
- }
- return targetStatement;
- }
-}
-
-QUuid QShaderGraph::Statement::uuid() const noexcept
-{
- return node.uuid();
-}
-
-int QShaderGraph::Statement::portIndex(QShaderNodePort::Direction direction, const QString &portName) const noexcept
-{
- const QVector<QShaderNodePort> ports = node.ports();
- int index = 0;
- for (const QShaderNodePort &port : ports) {
- if (port.name == portName && port.direction == direction)
- return index;
- else if (port.direction == direction)
- index++;
- }
- return -1;
-}
-
-void QShaderGraph::addNode(const QShaderNode &node)
-{
- removeNode(node);
- m_nodes.append(node);
-}
-
-void QShaderGraph::removeNode(const QShaderNode &node)
-{
- const auto it = std::find_if(m_nodes.begin(), m_nodes.end(),
- [node] (const QShaderNode &n) { return n.uuid() == node.uuid(); });
- if (it != m_nodes.end())
- m_nodes.erase(it);
-}
-
-QVector<QShaderNode> QShaderGraph::nodes() const noexcept
-{
- return m_nodes;
-}
-
-void QShaderGraph::addEdge(const QShaderGraph::Edge &edge)
-{
- if (m_edges.contains(edge))
- return;
- m_edges.append(edge);
-}
-
-void QShaderGraph::removeEdge(const QShaderGraph::Edge &edge)
-{
- m_edges.removeAll(edge);
-}
-
-QVector<QShaderGraph::Edge> QShaderGraph::edges() const noexcept
-{
- return m_edges;
-}
-
-QVector<QShaderGraph::Statement> QShaderGraph::createStatements(const QStringList &enabledLayers) const
-{
- const auto intersectsEnabledLayers = [enabledLayers] (const QStringList &layers) {
- return layers.isEmpty()
- || std::any_of(layers.cbegin(), layers.cend(),
- [enabledLayers] (const QString &s) { return enabledLayers.contains(s); });
- };
-
- const QVector<QShaderNode> enabledNodes = [this, intersectsEnabledLayers] {
- auto res = QVector<QShaderNode>();
- std::copy_if(m_nodes.cbegin(), m_nodes.cend(),
- std::back_inserter(res),
- [intersectsEnabledLayers] (const QShaderNode &node) {
- return intersectsEnabledLayers(node.layers());
- });
- return res;
- }();
-
- const QVector<Edge> enabledEdges = [this, intersectsEnabledLayers] {
- auto res = QVector<Edge>();
- std::copy_if(m_edges.cbegin(), m_edges.cend(),
- std::back_inserter(res),
- [intersectsEnabledLayers] (const Edge &edge) {
- return intersectsEnabledLayers(edge.layers);
- });
- return res;
- }();
-
- const QHash<QUuid, Statement> idHash = [enabledNodes] {
- auto nextVarId = 0;
- auto res = QHash<QUuid, Statement>();
- for (const QShaderNode &node : enabledNodes)
- res.insert(node.uuid(), nodeToStatement(node, nextVarId));
- return res;
- }();
-
- auto result = QVector<Statement>();
- QVector<Edge> currentEdges = enabledEdges;
- QVector<QUuid> currentUuids = [enabledNodes] {
- const QVector<QShaderNode> inputs = copyOutputNodes(enabledNodes);
- auto res = QVector<QUuid>();
- std::transform(inputs.cbegin(), inputs.cend(),
- std::back_inserter(res),
- [](const QShaderNode &node) { return node.uuid(); });
- return res;
- }();
-
- // Implements Kahn's algorithm to flatten the graph
- // https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm
- //
- // We implement it with a small twist though, we follow the edges backward
- // because we want to track the dependencies from the output nodes and not the
- // input nodes
- while (!currentUuids.isEmpty()) {
- const QUuid uuid = currentUuids.takeFirst();
- result.append(completeStatement(idHash, enabledEdges, uuid));
-
- const QVector<QShaderGraph::Edge> outgoing = outgoingEdges(currentEdges, uuid);
- for (const QShaderGraph::Edge &outgoingEdge : outgoing) {
- currentEdges.removeAll(outgoingEdge);
- const QUuid nextUuid = outgoingEdge.sourceNodeUuid;
- const QVector<QShaderGraph::Edge> incoming = incomingEdges(currentEdges, nextUuid);
- if (incoming.isEmpty()) {
- currentUuids.append(nextUuid);
- }
- }
- }
-
- std::reverse(result.begin(), result.end());
- return result;
-}
-
-bool operator==(const QShaderGraph::Edge &lhs, const QShaderGraph::Edge &rhs) noexcept
-{
- return lhs.sourceNodeUuid == rhs.sourceNodeUuid
- && lhs.sourcePortName == rhs.sourcePortName
- && lhs.targetNodeUuid == rhs.targetNodeUuid
- && lhs.targetPortName == rhs.targetPortName;
-}
-
-bool operator==(const QShaderGraph::Statement &lhs, const QShaderGraph::Statement &rhs) noexcept
-{
- return lhs.inputs == rhs.inputs
- && lhs.outputs == rhs.outputs
- && lhs.node.uuid() == rhs.node.uuid();
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/util/qshadergraph_p.h b/src/gui/util/qshadergraph_p.h
deleted file mode 100644
index 9367a3783c..0000000000
--- a/src/gui/util/qshadergraph_p.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSHADERGRAPH_P_H
-#define QSHADERGRAPH_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 <QtGui/private/qtguiglobal_p.h>
-
-#include <QtGui/private/qshadernode_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QShaderGraph
-{
-public:
- class Edge
- {
- public:
- QStringList layers;
- QUuid sourceNodeUuid;
- QString sourcePortName;
- QUuid targetNodeUuid;
- QString targetPortName;
- };
-
- class Statement
- {
- public:
- Q_GUI_EXPORT QUuid uuid() const noexcept;
- Q_GUI_EXPORT int portIndex(QShaderNodePort::Direction direction, const QString &portName) const noexcept;
-
- QShaderNode node;
- QVector<int> inputs;
- QVector<int> outputs;
- };
-
- Q_GUI_EXPORT void addNode(const QShaderNode &node);
- Q_GUI_EXPORT void removeNode(const QShaderNode &node);
- Q_GUI_EXPORT QVector<QShaderNode> nodes() const noexcept;
-
- Q_GUI_EXPORT void addEdge(const Edge &edge);
- Q_GUI_EXPORT void removeEdge(const Edge &edge);
- Q_GUI_EXPORT QVector<Edge> edges() const noexcept;
-
- Q_GUI_EXPORT QVector<Statement> createStatements(const QStringList &enabledLayers = QStringList()) const;
-
-private:
- QVector<QShaderNode> m_nodes;
- QVector<Edge> m_edges;
-};
-
-Q_GUI_EXPORT bool operator==(const QShaderGraph::Edge &lhs, const QShaderGraph::Edge &rhs) noexcept;
-
-inline bool operator!=(const QShaderGraph::Edge &lhs, const QShaderGraph::Edge &rhs) noexcept
-{
- return !(lhs == rhs);
-}
-
-Q_GUI_EXPORT bool operator==(const QShaderGraph::Statement &lhs, const QShaderGraph::Statement &rhs) noexcept;
-
-inline bool operator!=(const QShaderGraph::Statement &lhs, const QShaderGraph::Statement &rhs) noexcept
-{
- return !(lhs == rhs);
-}
-
-Q_DECLARE_TYPEINFO(QShaderGraph, Q_MOVABLE_TYPE);
-Q_DECLARE_TYPEINFO(QShaderGraph::Edge, Q_MOVABLE_TYPE);
-Q_DECLARE_TYPEINFO(QShaderGraph::Statement, Q_MOVABLE_TYPE);
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QShaderGraph)
-Q_DECLARE_METATYPE(QShaderGraph::Edge)
-Q_DECLARE_METATYPE(QShaderGraph::Statement)
-
-#endif // QSHADERGRAPH_P_H
diff --git a/src/gui/util/qshadergraphloader.cpp b/src/gui/util/qshadergraphloader.cpp
deleted file mode 100644
index 26848020f2..0000000000
--- a/src/gui/util/qshadergraphloader.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qshadergraphloader_p.h"
-
-#include "qshadernodesloader_p.h"
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qiodevice.h>
-#include <QtCore/qjsonarray.h>
-#include <QtCore/qjsondocument.h>
-#include <QtCore/qjsonobject.h>
-#include <QtCore/qmetaobject.h>
-
-QT_BEGIN_NAMESPACE
-
-void qt_register_ShaderLanguage_enums();
-
-QShaderGraphLoader::QShaderGraphLoader() noexcept
- : m_status(Null),
- m_device(nullptr)
-{
- qt_register_ShaderLanguage_enums();
-}
-
-QShaderGraphLoader::Status QShaderGraphLoader::status() const noexcept
-{
- return m_status;
-}
-
-QShaderGraph QShaderGraphLoader::graph() const noexcept
-{
- return m_graph;
-}
-
-QIODevice *QShaderGraphLoader::device() const noexcept
-{
- return m_device;
-}
-
-void QShaderGraphLoader::setDevice(QIODevice *device) noexcept
-{
- m_device = device;
- m_graph = QShaderGraph();
- m_status = !m_device ? Null
- : (m_device->openMode() & QIODevice::ReadOnly) ? Waiting
- : Error;
-}
-
-QHash<QString, QShaderNode> QShaderGraphLoader::prototypes() const noexcept
-{
- return m_prototypes;
-}
-
-void QShaderGraphLoader::setPrototypes(const QHash<QString, QShaderNode> &prototypes) noexcept
-{
- m_prototypes = prototypes;
-}
-
-void QShaderGraphLoader::load()
-{
- if (m_status == Error)
- return;
-
- auto error = QJsonParseError();
- const QJsonDocument document = QJsonDocument::fromJson(m_device->readAll(), &error);
-
- if (error.error != QJsonParseError::NoError) {
- qWarning() << "Invalid JSON document:" << error.errorString();
- m_status = Error;
- return;
- }
-
- if (document.isEmpty() || !document.isObject()) {
- qWarning() << "Invalid JSON document, root should be an object";
- m_status = Error;
- return;
- }
-
- const QJsonObject root = document.object();
-
- const QJsonValue nodesValue = root.value(QStringLiteral("nodes"));
- if (!nodesValue.isArray()) {
- qWarning() << "Invalid nodes property, should be an array";
- m_status = Error;
- return;
- }
-
- const QJsonValue edgesValue = root.value(QStringLiteral("edges"));
- if (!edgesValue.isArray()) {
- qWarning() << "Invalid edges property, should be an array";
- m_status = Error;
- return;
- }
-
- bool hasError = false;
-
- const QJsonValue prototypesValue = root.value(QStringLiteral("prototypes"));
- if (!prototypesValue.isUndefined()) {
- if (prototypesValue.isObject()) {
- QShaderNodesLoader loader;
- loader.load(prototypesValue.toObject());
- m_prototypes.insert(loader.nodes());
- } else {
- qWarning() << "Invalid prototypes property, should be an object";
- m_status = Error;
- return;
- }
- }
-
- const QJsonArray nodes = nodesValue.toArray();
- for (const QJsonValue &nodeValue : nodes) {
- if (!nodeValue.isObject()) {
- qWarning() << "Invalid node found";
- hasError = true;
- continue;
- }
-
- const QJsonObject nodeObject = nodeValue.toObject();
-
- const QString uuidString = nodeObject.value(QStringLiteral("uuid")).toString();
- const QUuid uuid = QUuid(uuidString);
- if (uuid.isNull()) {
- qWarning() << "Invalid UUID found in node:" << uuidString;
- hasError = true;
- continue;
- }
-
- const QString type = nodeObject.value(QStringLiteral("type")).toString();
- if (!m_prototypes.contains(type)) {
- qWarning() << "Unsupported node type found:" << type;
- hasError = true;
- continue;
- }
-
- const QJsonArray layersArray = nodeObject.value(QStringLiteral("layers")).toArray();
- auto layers = QStringList();
- for (const QJsonValue &layerValue : layersArray) {
- layers.append(layerValue.toString());
- }
-
- QShaderNode node = m_prototypes.value(type);
- node.setUuid(uuid);
- node.setLayers(layers);
-
- const QJsonValue parametersValue = nodeObject.value(QStringLiteral("parameters"));
- if (parametersValue.isObject()) {
- const QJsonObject parametersObject = parametersValue.toObject();
- for (const QString &parameterName : parametersObject.keys()) {
- const QJsonValue parameterValue = parametersObject.value(parameterName);
- if (parameterValue.isObject()) {
- const QJsonObject parameterObject = parameterValue.toObject();
- const QString type = parameterObject.value(QStringLiteral("type")).toString();
- const int typeId = QMetaType::type(type.toUtf8());
-
- const QString value = parameterObject.value(QStringLiteral("value")).toString();
- auto variant = QVariant(value);
-
- if (QMetaType::typeFlags(typeId) & QMetaType::IsEnumeration) {
- const QMetaObject *metaObject = QMetaType::metaObjectForType(typeId);
- const char *className = metaObject->className();
- const QByteArray enumName = type.mid(static_cast<int>(qstrlen(className)) + 2).toUtf8();
- const QMetaEnum metaEnum = metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
- const int enumValue = metaEnum.keyToValue(value.toUtf8());
- variant = QVariant(enumValue);
- variant.convert(typeId);
- } else {
- variant.convert(typeId);
- }
- node.setParameter(parameterName, variant);
- } else {
- node.setParameter(parameterName, parameterValue.toVariant());
- }
- }
- }
-
- m_graph.addNode(node);
- }
-
- const QJsonArray edges = edgesValue.toArray();
- for (const QJsonValue &edgeValue : edges) {
- if (!edgeValue.isObject()) {
- qWarning() << "Invalid edge found";
- hasError = true;
- continue;
- }
-
- const QJsonObject edgeObject = edgeValue.toObject();
-
- const QString sourceUuidString = edgeObject.value(QStringLiteral("sourceUuid")).toString();
- const QUuid sourceUuid = QUuid(sourceUuidString);
- if (sourceUuid.isNull()) {
- qWarning() << "Invalid source UUID found in edge:" << sourceUuidString;
- hasError = true;
- continue;
- }
-
- const QString sourcePort = edgeObject.value(QStringLiteral("sourcePort")).toString();
-
- const QString targetUuidString = edgeObject.value(QStringLiteral("targetUuid")).toString();
- const QUuid targetUuid = QUuid(targetUuidString);
- if (targetUuid.isNull()) {
- qWarning() << "Invalid target UUID found in edge:" << targetUuidString;
- hasError = true;
- continue;
- }
-
- const QString targetPort = edgeObject.value(QStringLiteral("targetPort")).toString();
-
- const QJsonArray layersArray = edgeObject.value(QStringLiteral("layers")).toArray();
- auto layers = QStringList();
- for (const QJsonValue &layerValue : layersArray) {
- layers.append(layerValue.toString());
- }
-
- auto edge = QShaderGraph::Edge();
- edge.sourceNodeUuid = sourceUuid;
- edge.sourcePortName = sourcePort;
- edge.targetNodeUuid = targetUuid;
- edge.targetPortName = targetPort;
- edge.layers = layers;
- m_graph.addEdge(edge);
- }
-
- if (hasError) {
- m_status = Error;
- m_graph = QShaderGraph();
- } else {
- m_status = Ready;
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/util/qshadergraphloader_p.h b/src/gui/util/qshadergraphloader_p.h
deleted file mode 100644
index e7aa19fa2d..0000000000
--- a/src/gui/util/qshadergraphloader_p.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSHADERGRAPHLOADER_P_H
-#define QSHADERGRAPHLOADER_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 <QtGui/private/qtguiglobal_p.h>
-
-#include <QtGui/private/qshadergraph_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QIODevice;
-
-class QShaderGraphLoader
-{
-public:
- enum Status : char {
- Null,
- Waiting,
- Ready,
- Error
- };
-
- Q_GUI_EXPORT QShaderGraphLoader() noexcept;
-
- Q_GUI_EXPORT Status status() const noexcept;
- Q_GUI_EXPORT QShaderGraph graph() const noexcept;
-
- Q_GUI_EXPORT QIODevice *device() const noexcept;
- Q_GUI_EXPORT void setDevice(QIODevice *device) noexcept;
-
- Q_GUI_EXPORT QHash<QString, QShaderNode> prototypes() const noexcept;
- Q_GUI_EXPORT void setPrototypes(const QHash<QString, QShaderNode> &prototypes) noexcept;
-
- Q_GUI_EXPORT void load();
-
-private:
- Status m_status;
- QIODevice *m_device;
- QHash<QString, QShaderNode> m_prototypes;
- QShaderGraph m_graph;
-};
-
-Q_DECLARE_TYPEINFO(QShaderGraphLoader, Q_MOVABLE_TYPE);
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QShaderGraphLoader)
-Q_DECLARE_METATYPE(QShaderGraphLoader::Status)
-
-#endif // QSHADERGRAPHLOADER_P_H
diff --git a/src/gui/util/qshaderlanguage.cpp b/src/gui/util/qshaderlanguage.cpp
deleted file mode 100644
index efd607ba60..0000000000
--- a/src/gui/util/qshaderlanguage.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qshaderlanguage_p.h"
-
-#include <QtCore/qcoreapplication.h>
-
-QT_BEGIN_NAMESPACE
-
-// Note: to be invoked explicitly. Relying for example on
-// Q_COREAPP_STARTUP_FUNCTION would not be acceptable in static builds.
-void qt_register_ShaderLanguage_enums()
-{
- qRegisterMetaType<QShaderLanguage::StorageQualifier>();
- qRegisterMetaType<QShaderLanguage::VariableType>();
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/util/qshaderlanguage_p.h b/src/gui/util/qshaderlanguage_p.h
deleted file mode 100644
index 193f797cc3..0000000000
--- a/src/gui/util/qshaderlanguage_p.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSHADERLANGUAGE_P_H
-#define QSHADERLANGUAGE_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 <QtGui/private/qtguiglobal_p.h>
-
-#include <QtCore/qmetatype.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace QShaderLanguage
-{
- Q_NAMESPACE_EXPORT(Q_GUI_EXPORT)
-
- enum StorageQualifier : char {
- Const = 1,
- Input,
- BuiltIn,
- Output,
- Uniform
- };
- Q_ENUM_NS(StorageQualifier)
-
- enum VariableType : int {
- Bool = 1,
- Int,
- Uint,
- Float,
- Double,
- Vec2,
- Vec3,
- Vec4,
- DVec2,
- DVec3,
- DVec4,
- BVec2,
- BVec3,
- BVec4,
- IVec2,
- IVec3,
- IVec4,
- UVec2,
- UVec3,
- UVec4,
- Mat2,
- Mat3,
- Mat4,
- Mat2x2,
- Mat2x3,
- Mat2x4,
- Mat3x2,
- Mat3x3,
- Mat3x4,
- Mat4x2,
- Mat4x3,
- Mat4x4,
- DMat2,
- DMat3,
- DMat4,
- DMat2x2,
- DMat2x3,
- DMat2x4,
- DMat3x2,
- DMat3x3,
- DMat3x4,
- DMat4x2,
- DMat4x3,
- DMat4x4,
- Sampler1D,
- Sampler2D,
- Sampler3D,
- SamplerCube,
- Sampler2DRect,
- Sampler2DMs,
- SamplerBuffer,
- Sampler1DArray,
- Sampler2DArray,
- Sampler2DMsArray,
- SamplerCubeArray,
- Sampler1DShadow,
- Sampler2DShadow,
- Sampler2DRectShadow,
- Sampler1DArrayShadow,
- Sampler2DArrayShadow,
- SamplerCubeShadow,
- SamplerCubeArrayShadow,
- ISampler1D,
- ISampler2D,
- ISampler3D,
- ISamplerCube,
- ISampler2DRect,
- ISampler2DMs,
- ISamplerBuffer,
- ISampler1DArray,
- ISampler2DArray,
- ISampler2DMsArray,
- ISamplerCubeArray,
- USampler1D,
- USampler2D,
- USampler3D,
- USamplerCube,
- USampler2DRect,
- USampler2DMs,
- USamplerBuffer,
- USampler1DArray,
- USampler2DArray,
- USampler2DMsArray,
- USamplerCubeArray
- };
- Q_ENUM_NS(VariableType)
-}
-
-QT_END_NAMESPACE
-
-#endif // QSHADERLANGUAGE_P_H
diff --git a/src/gui/util/qshadernode.cpp b/src/gui/util/qshadernode.cpp
deleted file mode 100644
index 547e5c51a8..0000000000
--- a/src/gui/util/qshadernode.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qshadernode_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QShaderNode::Type QShaderNode::type() const noexcept
-{
- int inputCount = 0;
- int outputCount = 0;
- for (const auto &port : qAsConst(m_ports)) {
- switch (port.direction) {
- case QShaderNodePort::Input:
- inputCount++;
- break;
- case QShaderNodePort::Output:
- outputCount++;
- break;
- }
- }
-
- return (inputCount == 0 && outputCount == 0) ? Invalid
- : (inputCount > 0 && outputCount == 0) ? Output
- : (inputCount == 0 && outputCount > 0) ? Input
- : Function;
-}
-
-QUuid QShaderNode::uuid() const noexcept
-{
- return m_uuid;
-}
-
-void QShaderNode::setUuid(const QUuid &uuid) noexcept
-{
- m_uuid = uuid;
-}
-
-QStringList QShaderNode::layers() const noexcept
-{
- return m_layers;
-}
-
-void QShaderNode::setLayers(const QStringList &layers) noexcept
-{
- m_layers = layers;
-}
-
-QVector<QShaderNodePort> QShaderNode::ports() const noexcept
-{
- return m_ports;
-}
-
-void QShaderNode::addPort(const QShaderNodePort &port)
-{
- removePort(port);
- m_ports.append(port);
-}
-
-void QShaderNode::removePort(const QShaderNodePort &port)
-{
- const auto it = std::find_if(m_ports.begin(), m_ports.end(),
- [port](const QShaderNodePort &p) {
- return p.name == port.name;
- });
- if (it != m_ports.end())
- m_ports.erase(it);
-}
-
-QStringList QShaderNode::parameterNames() const
-{
- return m_parameters.keys();
-}
-
-QVariant QShaderNode::parameter(const QString &name) const
-{
- return m_parameters.value(name);
-}
-
-void QShaderNode::setParameter(const QString &name, const QVariant &value)
-{
- m_parameters.insert(name, value);
-}
-
-void QShaderNode::clearParameter(const QString &name)
-{
- m_parameters.remove(name);
-}
-
-void QShaderNode::addRule(const QShaderFormat &format, const QShaderNode::Rule &rule)
-{
- removeRule(format);
- m_rules << qMakePair(format, rule);
-}
-
-void QShaderNode::removeRule(const QShaderFormat &format)
-{
- const auto it = std::find_if(m_rules.begin(), m_rules.end(),
- [format](const QPair<QShaderFormat, Rule> &entry) {
- return entry.first == format;
- });
- if (it != m_rules.end())
- m_rules.erase(it);
-}
-
-QVector<QShaderFormat> QShaderNode::availableFormats() const
-{
- auto res = QVector<QShaderFormat>();
- std::transform(m_rules.cbegin(), m_rules.cend(),
- std::back_inserter(res),
- [](const QPair<QShaderFormat, Rule> &entry) { return entry.first; });
- return res;
-}
-
-QShaderNode::Rule QShaderNode::rule(const QShaderFormat &format) const
-{
- const auto it = std::find_if(m_rules.crbegin(), m_rules.crend(),
- [format](const QPair<QShaderFormat, Rule> &entry) {
- return format.supports(entry.first);
- });
- return it != m_rules.crend() ? it->second : Rule();
-}
-
-QShaderNode::Rule::Rule(const QByteArray &subs, const QByteArrayList &snippets) noexcept
- : substitution(subs),
- headerSnippets(snippets)
-{
-}
-
-bool operator==(const QShaderNode::Rule &lhs, const QShaderNode::Rule &rhs) noexcept
-{
- return lhs.substitution == rhs.substitution
- && lhs.headerSnippets == rhs.headerSnippets;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/util/qshadernode_p.h b/src/gui/util/qshadernode_p.h
deleted file mode 100644
index c3d149d8a5..0000000000
--- a/src/gui/util/qshadernode_p.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSHADERNODE_P_H
-#define QSHADERNODE_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 <QtGui/private/qtguiglobal_p.h>
-
-#include <QtGui/private/qshaderformat_p.h>
-#include <QtGui/private/qshadernodeport_p.h>
-
-#include <QtCore/quuid.h>
-
-QT_BEGIN_NAMESPACE
-
-class QShaderNode
-{
-public:
- enum Type : char {
- Invalid,
- Input,
- Output,
- Function
- };
-
- class Rule
- {
- public:
- Q_GUI_EXPORT Rule(const QByteArray &substitution = QByteArray(), const QByteArrayList &headerSnippets = QByteArrayList()) noexcept;
-
- QByteArray substitution;
- QByteArrayList headerSnippets;
- };
-
- Q_GUI_EXPORT Type type() const noexcept;
-
- Q_GUI_EXPORT QUuid uuid() const noexcept;
- Q_GUI_EXPORT void setUuid(const QUuid &uuid) noexcept;
-
- Q_GUI_EXPORT QStringList layers() const noexcept;
- Q_GUI_EXPORT void setLayers(const QStringList &layers) noexcept;
-
- Q_GUI_EXPORT QVector<QShaderNodePort> ports() const noexcept;
- Q_GUI_EXPORT void addPort(const QShaderNodePort &port);
- Q_GUI_EXPORT void removePort(const QShaderNodePort &port);
-
- Q_GUI_EXPORT QStringList parameterNames() const;
- Q_GUI_EXPORT QVariant parameter(const QString &name) const;
- Q_GUI_EXPORT void setParameter(const QString &name, const QVariant &value);
- Q_GUI_EXPORT void clearParameter(const QString &name);
-
- Q_GUI_EXPORT void addRule(const QShaderFormat &format, const Rule &rule);
- Q_GUI_EXPORT void removeRule(const QShaderFormat &format);
-
- Q_GUI_EXPORT QVector<QShaderFormat> availableFormats() const;
- Q_GUI_EXPORT Rule rule(const QShaderFormat &format) const;
-
-private:
- QUuid m_uuid;
- QStringList m_layers;
- QVector<QShaderNodePort> m_ports;
- QHash<QString, QVariant> m_parameters;
- QVector<QPair<QShaderFormat, QShaderNode::Rule>> m_rules;
-};
-
-Q_GUI_EXPORT bool operator==(const QShaderNode::Rule &lhs, const QShaderNode::Rule &rhs) noexcept;
-
-inline bool operator!=(const QShaderNode::Rule &lhs, const QShaderNode::Rule &rhs) noexcept
-{
- return !(lhs == rhs);
-}
-
-Q_DECLARE_TYPEINFO(QShaderNode, Q_MOVABLE_TYPE);
-Q_DECLARE_TYPEINFO(QShaderNode::Rule, Q_MOVABLE_TYPE);
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QShaderNode)
-Q_DECLARE_METATYPE(QShaderNode::Rule)
-
-#endif // QSHADERNODE_P_H
diff --git a/src/gui/util/qshadernodeport.cpp b/src/gui/util/qshadernodeport.cpp
deleted file mode 100644
index 15dbc4160e..0000000000
--- a/src/gui/util/qshadernodeport.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qshadernodeport_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QShaderNodePort::QShaderNodePort() noexcept
- : direction(Output)
-{
-}
-
-bool operator==(const QShaderNodePort &lhs, const QShaderNodePort &rhs) noexcept
-{
- return lhs.direction == rhs.direction
- && lhs.name == rhs.name;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/util/qshadernodeport_p.h b/src/gui/util/qshadernodeport_p.h
deleted file mode 100644
index c69ba23a3f..0000000000
--- a/src/gui/util/qshadernodeport_p.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSHADERNODEPORT_P_H
-#define QSHADERNODEPORT_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 <QtGui/private/qtguiglobal_p.h>
-
-#include <QtCore/qstring.h>
-#include <QtCore/qvariant.h>
-
-QT_BEGIN_NAMESPACE
-
-class QShaderNodePort
-{
-public:
- enum Direction : char {
- Input,
- Output
- };
-
- Q_GUI_EXPORT QShaderNodePort() noexcept;
-
- QShaderNodePort::Direction direction;
- QString name;
-};
-
-Q_GUI_EXPORT bool operator==(const QShaderNodePort &lhs, const QShaderNodePort &rhs) noexcept;
-
-inline bool operator!=(const QShaderNodePort &lhs, const QShaderNodePort &rhs) noexcept
-{
- return !(lhs == rhs);
-}
-
-Q_DECLARE_TYPEINFO(QShaderNodePort, Q_MOVABLE_TYPE);
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QShaderNodePort)
-
-#endif // QSHADERNODEPORT_P_H
diff --git a/src/gui/util/qshadernodesloader.cpp b/src/gui/util/qshadernodesloader.cpp
deleted file mode 100644
index 922479332c..0000000000
--- a/src/gui/util/qshadernodesloader.cpp
+++ /dev/null
@@ -1,289 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qshadernodesloader_p.h"
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qiodevice.h>
-#include <QtCore/qjsonarray.h>
-#include <QtCore/qjsondocument.h>
-#include <QtCore/qjsonobject.h>
-#include <QtCore/qmetaobject.h>
-
-QT_BEGIN_NAMESPACE
-
-QShaderNodesLoader::QShaderNodesLoader() noexcept
- : m_status(Null),
- m_device(nullptr)
-{
-}
-
-QShaderNodesLoader::Status QShaderNodesLoader::status() const noexcept
-{
- return m_status;
-}
-
-QHash<QString, QShaderNode> QShaderNodesLoader::nodes() const noexcept
-{
- return m_nodes;
-}
-
-QIODevice *QShaderNodesLoader::device() const noexcept
-{
- return m_device;
-}
-
-void QShaderNodesLoader::setDevice(QIODevice *device) noexcept
-{
- m_device = device;
- m_nodes.clear();
- m_status = !m_device ? Null
- : (m_device->openMode() & QIODevice::ReadOnly) ? Waiting
- : Error;
-}
-
-void QShaderNodesLoader::load()
-{
- if (m_status == Error)
- return;
-
- auto error = QJsonParseError();
- const QJsonDocument document = QJsonDocument::fromJson(m_device->readAll(), &error);
-
- if (error.error != QJsonParseError::NoError) {
- qWarning() << "Invalid JSON document:" << error.errorString();
- m_status = Error;
- return;
- }
-
- if (document.isEmpty() || !document.isObject()) {
- qWarning() << "Invalid JSON document, root should be an object";
- m_status = Error;
- return;
- }
-
- const QJsonObject root = document.object();
- load(root);
-}
-
-void QShaderNodesLoader::load(const QJsonObject &prototypesObject)
-{
- bool hasError = false;
-
- for (const QString &property : prototypesObject.keys()) {
- const QJsonValue nodeValue = prototypesObject.value(property);
- if (!nodeValue.isObject()) {
- qWarning() << "Invalid node found";
- hasError = true;
- break;
- }
-
- const QJsonObject nodeObject = nodeValue.toObject();
-
- auto node = QShaderNode();
-
- const QJsonValue inputsValue = nodeObject.value(QStringLiteral("inputs"));
- if (inputsValue.isArray()) {
- const QJsonArray inputsArray = inputsValue.toArray();
- for (const QJsonValue &inputValue : inputsArray) {
- if (!inputValue.isString()) {
- qWarning() << "Non-string value in inputs";
- hasError = true;
- break;
- }
-
- auto input = QShaderNodePort();
- input.direction = QShaderNodePort::Input;
- input.name = inputValue.toString();
- node.addPort(input);
- }
- }
-
- const QJsonValue outputsValue = nodeObject.value(QStringLiteral("outputs"));
- if (outputsValue.isArray()) {
- const QJsonArray outputsArray = outputsValue.toArray();
- for (const QJsonValue &outputValue : outputsArray) {
- if (!outputValue.isString()) {
- qWarning() << "Non-string value in outputs";
- hasError = true;
- break;
- }
-
- auto output = QShaderNodePort();
- output.direction = QShaderNodePort::Output;
- output.name = outputValue.toString();
- node.addPort(output);
- }
- }
-
- const QJsonValue parametersValue = nodeObject.value(QStringLiteral("parameters"));
- if (parametersValue.isObject()) {
- const QJsonObject parametersObject = parametersValue.toObject();
- for (const QString &parameterName : parametersObject.keys()) {
- const QJsonValue parameterValue = parametersObject.value(parameterName);
- if (parameterValue.isObject()) {
- const QJsonObject parameterObject = parameterValue.toObject();
- const QString type = parameterObject.value(QStringLiteral("type")).toString();
- const int typeId = QMetaType::type(type.toUtf8());
-
- const QString value = parameterObject.value(QStringLiteral("value")).toString();
- auto variant = QVariant(value);
-
- if (QMetaType::typeFlags(typeId) & QMetaType::IsEnumeration) {
- const QMetaObject *metaObject = QMetaType::metaObjectForType(typeId);
- const char *className = metaObject->className();
- const QByteArray enumName = type.mid(static_cast<int>(qstrlen(className)) + 2).toUtf8();
- const QMetaEnum metaEnum = metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
- const int enumValue = metaEnum.keyToValue(value.toUtf8());
- variant = QVariant(enumValue);
- variant.convert(typeId);
- } else {
- variant.convert(typeId);
- }
- node.setParameter(parameterName, variant);
- } else {
- node.setParameter(parameterName, parameterValue.toVariant());
- }
- }
- }
-
- const QJsonValue rulesValue = nodeObject.value(QStringLiteral("rules"));
- if (rulesValue.isArray()) {
- const QJsonArray rulesArray = rulesValue.toArray();
- for (const QJsonValue &ruleValue : rulesArray) {
- if (!ruleValue.isObject()) {
- qWarning() << "Rules should be objects";
- hasError = true;
- break;
- }
-
- const QJsonObject ruleObject = ruleValue.toObject();
-
- const QJsonValue formatValue = ruleObject.value(QStringLiteral("format"));
- if (!formatValue.isObject()) {
- qWarning() << "Format is mandatory in rules and should be an object";
- hasError = true;
- break;
- }
-
- const QJsonObject formatObject = formatValue.toObject();
- auto format = QShaderFormat();
-
- const QJsonValue apiValue = formatObject.value(QStringLiteral("api"));
- if (!apiValue.isString()) {
- qWarning() << "Format API must be a string";
- hasError = true;
- break;
- }
-
- const QString api = apiValue.toString();
- format.setApi(api == QStringLiteral("OpenGLES") ? QShaderFormat::OpenGLES
- : api == QStringLiteral("OpenGLNoProfile") ? QShaderFormat::OpenGLNoProfile
- : api == QStringLiteral("OpenGLCoreProfile") ? QShaderFormat::OpenGLCoreProfile
- : api == QStringLiteral("OpenGLCompatibilityProfile") ? QShaderFormat::OpenGLCompatibilityProfile
- : QShaderFormat::NoApi);
- if (format.api() == QShaderFormat::NoApi) {
- qWarning() << "Format API must be one of: OpenGLES, OpenGLNoProfile, OpenGLCoreProfile or OpenGLCompatibilityProfile";
- hasError = true;
- break;
- }
-
- const QJsonValue majorValue = formatObject.value(QStringLiteral("major"));
- const QJsonValue minorValue = formatObject.value(QStringLiteral("minor"));
- if (!majorValue.isDouble() || !minorValue.isDouble()) {
- qWarning() << "Format major and minor version must be values";
- hasError = true;
- break;
- }
- format.setVersion(QVersionNumber(majorValue.toInt(), minorValue.toInt()));
-
- const QJsonValue extensionsValue = formatObject.value(QStringLiteral("extensions"));
- const QJsonArray extensionsArray = extensionsValue.toArray();
- auto extensions = QStringList();
- std::transform(extensionsArray.constBegin(), extensionsArray.constEnd(),
- std::back_inserter(extensions),
- [] (const QJsonValue &extensionValue) { return extensionValue.toString(); });
- format.setExtensions(extensions);
-
- const QString vendor = formatObject.value(QStringLiteral("vendor")).toString();
- format.setVendor(vendor);
-
- const QJsonValue substitutionValue = ruleObject.value(QStringLiteral("substitution"));
- if (!substitutionValue.isString()) {
- qWarning() << "Substitution needs to be a string";
- hasError = true;
- break;
- }
-
- // We default out to a Fragment ShaderType if nothing is specified
- // as that was the initial behavior we introduced
- const QString shaderType = formatObject.value(QStringLiteral("shaderType")).toString();
- format.setShaderType(shaderType == QStringLiteral("Fragment") ? QShaderFormat::Fragment
- : shaderType == QStringLiteral("Vertex") ? QShaderFormat::Vertex
- : shaderType == QStringLiteral("TessellationControl") ? QShaderFormat::TessellationControl
- : shaderType == QStringLiteral("TessellationEvaluation") ? QShaderFormat::TessellationEvaluation
- : shaderType == QStringLiteral("Geometry") ? QShaderFormat::Geometry
- : shaderType == QStringLiteral("Compute") ? QShaderFormat::Compute
- : QShaderFormat::Fragment);
-
- const QByteArray substitution = substitutionValue.toString().toUtf8();
-
- const QJsonValue snippetsValue = ruleObject.value(QStringLiteral("headerSnippets"));
- const QJsonArray snippetsArray = snippetsValue.toArray();
- auto snippets = QByteArrayList();
- std::transform(snippetsArray.constBegin(), snippetsArray.constEnd(),
- std::back_inserter(snippets),
- [] (const QJsonValue &snippetValue) { return snippetValue.toString().toUtf8(); });
-
- node.addRule(format, QShaderNode::Rule(substitution, snippets));
- }
- }
-
- m_nodes.insert(property, node);
- }
-
- if (hasError) {
- m_status = Error;
- m_nodes.clear();
- } else {
- m_status = Ready;
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/util/qshadernodesloader_p.h b/src/gui/util/qshadernodesloader_p.h
deleted file mode 100644
index 432d7d4494..0000000000
--- a/src/gui/util/qshadernodesloader_p.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSHADERNODESLOADER_P_H
-#define QSHADERNODESLOADER_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 <QtGui/private/qtguiglobal_p.h>
-
-#include <QtGui/private/qshadergraph_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QIODevice;
-
-class QShaderNodesLoader
-{
-public:
- enum Status : char {
- Null,
- Waiting,
- Ready,
- Error
- };
-
- Q_GUI_EXPORT QShaderNodesLoader() noexcept;
-
- Q_GUI_EXPORT Status status() const noexcept;
- Q_GUI_EXPORT QHash<QString, QShaderNode> nodes() const noexcept;
-
- Q_GUI_EXPORT QIODevice *device() const noexcept;
- Q_GUI_EXPORT void setDevice(QIODevice *device) noexcept;
-
- Q_GUI_EXPORT void load();
- Q_GUI_EXPORT void load(const QJsonObject &prototypesObject);
-
-private:
- Status m_status;
- QIODevice *m_device;
- QHash<QString, QShaderNode> m_nodes;
-};
-
-Q_DECLARE_TYPEINFO(QShaderNodesLoader, Q_MOVABLE_TYPE);
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QShaderNodesLoader)
-Q_DECLARE_METATYPE(QShaderNodesLoader::Status)
-
-#endif // QSHADERNODESLOADER_P_H
diff --git a/src/gui/util/qtexturefiledata.cpp b/src/gui/util/qtexturefiledata.cpp
index 3c8130c229..e1fa900b84 100644
--- a/src/gui/util/qtexturefiledata.cpp
+++ b/src/gui/util/qtexturefiledata.cpp
@@ -1,49 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#include "QtGui/qimage.h"
#include "qtexturefiledata_p.h"
-#include <QSize>
+#include <QtCore/qsize.h>
+#include <QtCore/qvarlengtharray.h>
+#include <QtCore/qmap.h>
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQtGuiTextureIO, "qt.gui.textureio");
+constexpr size_t MAX_FACES = 6;
+
class QTextureFileDataPrivate : public QSharedData
{
public:
@@ -53,12 +22,17 @@ public:
QTextureFileDataPrivate(const QTextureFileDataPrivate &other)
: QSharedData(other),
+ mode(other.mode),
logName(other.logName),
data(other.data),
offsets(other.offsets),
lengths(other.lengths),
+ images(other.images),
size(other.size),
- format(other.format)
+ format(other.format),
+ numFaces(other.numFaces),
+ numLevels(other.numLevels),
+ keyValues(other.keyValues)
{
}
@@ -66,27 +40,50 @@ public:
{
}
- void ensureLevels(int num, bool force = false)
+ void ensureSize(int levels, int faces, bool force = false)
{
- const int newSize = force ? num : qMax(offsets.size(), num);
- offsets.resize(newSize);
- lengths.resize(newSize);
+ numLevels = force ? levels : qMax(numLevels, levels);
+ numFaces = force ? faces : qMax(numFaces, faces);
+ if (mode == QTextureFileData::ByteArrayMode) {
+ offsets.resize(numFaces);
+ lengths.resize(numFaces);
+
+ for (auto faceList : { &offsets, &lengths })
+ for (auto &levelList : *faceList)
+ levelList.resize(numLevels);
+ } else {
+ images.resize(numFaces);
+ for (auto &levelList : images)
+ levelList.resize(numLevels);
+ }
}
+ bool isValid(int level, int face) const { return level < numLevels && face < numFaces; }
+
+ int getOffset(int level, int face) const { return offsets[face][level]; }
+ void setOffset(int value, int level, int face) { offsets[face][level] = value; }
+ int getLength(int level, int face) const { return lengths[face][level]; }
+ void setLength(int value, int level, int face) { lengths[face][level] = value; }
+
+ QTextureFileData::Mode mode = QTextureFileData::ByteArrayMode;
QByteArray logName;
QByteArray data;
- QVector<int> offsets;
- QVector<int> lengths;
+ QVarLengthArray<QList<int>, MAX_FACES> offsets; // [Face][Level] = offset
+ QVarLengthArray<QList<int>, MAX_FACES> lengths; // [Face][Level] = length
+ QVarLengthArray<QList<QImage>, MAX_FACES> images; // [Face][Level] = length
QSize size;
quint32 format = 0;
quint32 internalFormat = 0;
quint32 baseInternalFormat = 0;
+ int numFaces = 0;
+ int numLevels = 0;
+ QMap<QByteArray, QByteArray> keyValues;
};
-
-
-QTextureFileData::QTextureFileData()
+QTextureFileData::QTextureFileData(Mode mode)
{
+ d = new QTextureFileDataPrivate;
+ d->mode = mode;
}
QTextureFileData::QTextureFileData(const QTextureFileData &other)
@@ -114,19 +111,34 @@ bool QTextureFileData::isValid() const
if (!d)
return false;
+ if (d->mode == ImageMode)
+ return true; // Manually populated: the caller needs to do verification at that time.
+
if (d->data.isEmpty() || d->size.isEmpty() || (!d->format && !d->internalFormat))
return false;
- const int numChunks = d->offsets.size();
- if (numChunks == 0 || (d->lengths.size() != numChunks))
- return false;
+ const int numFacesOffset = d->offsets.size();
+ const int numFacesLength = d->lengths.size();
+ if (numFacesOffset == 0 || numFacesLength == 0 || d->numFaces != numFacesOffset
+ || d->numFaces != numFacesLength)
+ return false;
+
+ const qint64 dataSize = d->data.size();
- const qint64 sz = d->data.size();
- for (int i = 0; i < numChunks; i++) {
- qint64 offi = d->offsets.at(i);
- qint64 leni = d->lengths.at(i);
- if (offi < 0 || offi >= sz || leni <= 0 || (offi + leni > sz))
+ // Go through all faces and levels and check that the range is inside the data size.
+ for (int face = 0; face < d->numFaces; face++) {
+ const int numLevelsOffset = d->offsets.at(face).size();
+ const int numLevelsLength = d->lengths.at(face).size();
+ if (numLevelsOffset == 0 || numLevelsLength == 0 || d->numLevels != numLevelsOffset
+ || d->numLevels != numLevelsLength)
return false;
+
+ for (int level = 0; level < d->numLevels; level++) {
+ const qint64 offset = d->getOffset(level, face);
+ const qint64 length = d->getLength(level, face);
+ if (offset < 0 || offset >= dataSize || length <= 0 || (offset + length > dataSize))
+ return false;
+ }
}
return true;
}
@@ -143,47 +155,85 @@ QByteArray QTextureFileData::data() const
void QTextureFileData::setData(const QByteArray &data)
{
- if (!d.constData()) //### uh think about this design, this is the only way to create; should be constructor instead at least
- d = new QTextureFileDataPrivate;
-
+ Q_ASSERT(d->mode == ByteArrayMode);
d->data = data;
}
-int QTextureFileData::dataOffset(int level) const
+void QTextureFileData::setData(const QImage &image, int level, int face)
+{
+ Q_ASSERT(d->mode == ImageMode);
+ d->ensureSize(level + 1, face + 1);
+ d->images[face][level] = image;
+}
+
+int QTextureFileData::dataOffset(int level, int face) const
{
- return (d && d->offsets.size() > level) ? d->offsets.at(level) : 0;
+ Q_ASSERT(d->mode == ByteArrayMode);
+ return (d && d->isValid(level, face)) ? d->getOffset(level, face) : 0;
}
-void QTextureFileData::setDataOffset(int offset, int level)
+void QTextureFileData::setDataOffset(int offset, int level, int face)
{
+ Q_ASSERT(d->mode == ByteArrayMode);
if (d.constData() && level >= 0) {
- d->ensureLevels(level + 1);
- d->offsets[level] = offset;
+ d->ensureSize(level + 1, face + 1);
+ d->setOffset(offset, level, face);
}
}
-int QTextureFileData::dataLength(int level) const
+int QTextureFileData::dataLength(int level, int face) const
+{
+ Q_ASSERT(d->mode == ByteArrayMode);
+ return (d && d->isValid(level, face)) ? d->getLength(level, face) : 0;
+}
+
+QByteArrayView QTextureFileData::getDataView(int level, int face) const
{
- return (d && d->lengths.size() > level) ? d->lengths.at(level) : 0;
+ if (d->mode == ByteArrayMode) {
+ const int dataLength = this->dataLength(level, face);
+ const int dataOffset = this->dataOffset(level, face);
+
+ if (d == nullptr || dataLength == 0)
+ return QByteArrayView();
+
+ return QByteArrayView(d->data.constData() + dataOffset, dataLength);
+ } else {
+ if (!d->isValid(level, face))
+ return QByteArrayView();
+ const QImage &img = d->images[face][level];
+ return img.isNull() ? QByteArrayView() : QByteArrayView(img.constBits(), img.sizeInBytes());
+ }
}
-void QTextureFileData::setDataLength(int length, int level)
+void QTextureFileData::setDataLength(int length, int level, int face)
{
+ Q_ASSERT(d->mode == ByteArrayMode);
if (d.constData() && level >= 0) {
- d->ensureLevels(level + 1);
- d->lengths[level] = length;
+ d->ensureSize(level + 1, face + 1);
+ d->setLength(length, level, face);
}
}
int QTextureFileData::numLevels() const
{
- return d ? d->offsets.size() : 0;
+ return d ? d->numLevels : 0;
+}
+
+void QTextureFileData::setNumLevels(int numLevels)
+{
+ if (d && numLevels >= 0)
+ d->ensureSize(numLevels, d->numFaces, true);
+}
+
+int QTextureFileData::numFaces() const
+{
+ return d ? d->numFaces : 0;
}
-void QTextureFileData::setNumLevels(int num)
+void QTextureFileData::setNumFaces(int numFaces)
{
- if (d && num >= 0)
- d->ensureLevels(num, true);
+ if (d && numFaces >= 0)
+ d->ensureSize(d->numLevels, numFaces, true);
}
QSize QTextureFileData::size() const
@@ -241,6 +291,17 @@ void QTextureFileData::setLogName(const QByteArray &name)
d->logName = name;
}
+QMap<QByteArray, QByteArray> QTextureFileData::keyValueMetadata() const
+{
+ return d ? d->keyValues : QMap<QByteArray, QByteArray>();
+}
+
+void QTextureFileData::setKeyValueMetadata(const QMap<QByteArray, QByteArray> &keyValues)
+{
+ if (d)
+ d->keyValues = keyValues;
+}
+
static QByteArray glFormatName(quint32 fmt)
{
return QByteArray("0x" + QByteArray::number(fmt, 16).rightJustified(4, '0'));
@@ -257,9 +318,11 @@ QDebug operator<<(QDebug dbg, const QTextureFileData &d)
dbg << "glInternalFormat:" << glFormatName(d.glInternalFormat());
dbg << "glBaseInternalFormat:" << glFormatName(d.glBaseInternalFormat());
dbg.nospace() << "Levels: " << d.numLevels();
+ dbg.nospace() << "Faces: " << d.numFaces();
if (!d.isValid())
dbg << " {Invalid}";
dbg << ")";
+ dbg << (d.d->mode ? "[bytearray-based]" : "[image-based]");
} else {
dbg << "null)";
}
diff --git a/src/gui/util/qtexturefiledata_p.h b/src/gui/util/qtexturefiledata_p.h
index 2df23de33c..cd0dbe171c 100644
--- a/src/gui/util/qtexturefiledata_p.h
+++ b/src/gui/util/qtexturefiledata_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTEXTUREFILEDATA_P_H
#define QTEXTUREFILEDATA_P_H
@@ -55,6 +19,7 @@
#include <QSharedDataPointer>
#include <QLoggingCategory>
#include <QDebug>
+#include <private/qglobal_p.h>
QT_BEGIN_NAMESPACE
@@ -65,7 +30,9 @@ class QTextureFileDataPrivate;
class Q_GUI_EXPORT QTextureFileData
{
public:
- QTextureFileData();
+ enum Mode { ByteArrayMode, ImageMode };
+
+ QTextureFileData(Mode mode = ByteArrayMode);
QTextureFileData(const QTextureFileData &other);
QTextureFileData &operator=(const QTextureFileData &other);
~QTextureFileData();
@@ -77,16 +44,22 @@ public:
QByteArray data() const;
void setData(const QByteArray &data);
+ void setData(const QImage &image, int level = 0, int face = 0);
+
+ int dataOffset(int level = 0, int face = 0) const;
+ void setDataOffset(int offset, int level = 0, int face = 0);
- int dataOffset(int level = 0) const;
- void setDataOffset(int offset, int level = 0);
+ int dataLength(int level = 0, int face = 0) const;
+ void setDataLength(int length, int level = 0, int face = 0);
- int dataLength(int level = 0) const;
- void setDataLength(int length, int level = 0);
+ QByteArrayView getDataView(int level = 0, int face = 0) const;
int numLevels() const;
void setNumLevels(int num);
+ int numFaces() const;
+ void setNumFaces(int num);
+
QSize size() const;
void setSize(const QSize &size);
@@ -102,11 +75,15 @@ public:
QByteArray logName() const;
void setLogName(const QByteArray &name);
+ QMap<QByteArray, QByteArray> keyValueMetadata() const;
+ void setKeyValueMetadata(const QMap<QByteArray, QByteArray> &keyValues);
+
private:
QSharedDataPointer<QTextureFileDataPrivate> d;
+ friend Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QTextureFileData &d);
};
-Q_DECLARE_TYPEINFO(QTextureFileData, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(QTextureFileData, Q_RELOCATABLE_TYPE);
Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QTextureFileData &d);
diff --git a/src/gui/util/qtexturefilehandler_p.h b/src/gui/util/qtexturefilehandler_p.h
index 3d4f42526f..9fb3130f0b 100644
--- a/src/gui/util/qtexturefilehandler_p.h
+++ b/src/gui/util/qtexturefilehandler_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTEXTUREFILEHANDLER_P_H
#define QTEXTUREFILEHANDLER_P_H
@@ -63,7 +27,7 @@ public:
{
m_logName = !logName.isEmpty() ? logName : QByteArrayLiteral("(unknown)");
}
- virtual ~QTextureFileHandler() {}
+ virtual ~QTextureFileHandler();
virtual QTextureFileData read() = 0;
QIODevice *device() const { return m_device; }
diff --git a/src/gui/util/qtexturefilereader.cpp b/src/gui/util/qtexturefilereader.cpp
index fefb957323..596c30d2f7 100644
--- a/src/gui/util/qtexturefilereader.cpp
+++ b/src/gui/util/qtexturefilereader.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtexturefilereader_p.h"
@@ -47,6 +11,8 @@
QT_BEGIN_NAMESPACE
+QTextureFileHandler::~QTextureFileHandler() = default;
+
QTextureFileReader::QTextureFileReader(QIODevice *device, const QString &fileName)
: m_device(device), m_fileName(fileName)
{
diff --git a/src/gui/util/qtexturefilereader_p.h b/src/gui/util/qtexturefilereader_p.h
index 2ec0b0cc49..5f7b31ee32 100644
--- a/src/gui/util/qtexturefilereader_p.h
+++ b/src/gui/util/qtexturefilereader_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTEXTUREFILEREADER_H
#define QTEXTUREFILEREADER_H
diff --git a/src/gui/util/qundogroup.cpp b/src/gui/util/qundogroup.cpp
new file mode 100644
index 0000000000..db5d009ca6
--- /dev/null
+++ b/src/gui/util/qundogroup.cpp
@@ -0,0 +1,479 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qundogroup.h"
+#include "qundostack.h"
+#include "qundostack_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QUndoGroupPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QUndoGroup)
+public:
+ QUndoGroupPrivate() : active(nullptr) {}
+
+ QUndoStack *active;
+ QList<QUndoStack*> stack_list;
+};
+
+/*!
+ \class QUndoGroup
+ \brief The QUndoGroup class is a group of QUndoStack objects.
+ \since 4.2
+ \inmodule QtGui
+
+ For an overview of the Qt's undo framework, see the
+ \l{qundo.html}{overview}.
+
+ An application often has multiple undo stacks, one for each opened document. At the
+ same time, an application usually has one undo action and one redo action, which
+ triggers undo or redo in the active document.
+
+ QUndoGroup is a group of QUndoStack objects, one of which may be active. It has
+ an undo() and redo() slot, which calls QUndoStack::undo() and QUndoStack::redo()
+ for the active stack. It also has the functions createUndoAction() and createRedoAction().
+ The actions returned by these functions behave in the same way as those returned by
+ QUndoStack::createUndoAction() and QUndoStack::createRedoAction() of the active
+ stack.
+
+ Stacks are added to a group with addStack() and removed with removeStack(). A stack
+ is implicitly added to a group when it is created with the group as its parent
+ QObject.
+
+ It is the programmer's responsibility to specify which stack is active by
+ calling QUndoStack::setActive(), usually when the associated document window receives focus.
+ The active stack may also be set with setActiveStack(), and is returned by activeStack().
+
+ When a stack is added to a group using addStack(), the group does not take ownership
+ of the stack. This means the stack has to be deleted separately from the group. When
+ a stack is deleted, it is automatically removed from a group. A stack may belong to
+ only one group. Adding it to another group will cause it to be removed from the previous
+ group.
+
+ A QUndoGroup is also useful in conjunction with QUndoView. If a QUndoView is
+ set to watch a group using QUndoView::setGroup(), it will update itself to display
+ the active stack.
+*/
+
+/*!
+ Creates an empty QUndoGroup object with parent \a parent.
+
+ \sa addStack()
+*/
+
+QUndoGroup::QUndoGroup(QObject *parent)
+ : QObject(*new QUndoGroupPrivate(), parent)
+{
+}
+
+/*!
+ Destroys the QUndoGroup.
+*/
+QUndoGroup::~QUndoGroup()
+{
+ // Ensure all QUndoStacks no longer refer to this group.
+ Q_D(QUndoGroup);
+ QList<QUndoStack *>::iterator it = d->stack_list.begin();
+ QList<QUndoStack *>::iterator end = d->stack_list.end();
+ while (it != end) {
+ (*it)->d_func()->group = nullptr;
+ ++it;
+ }
+}
+
+/*!
+ Adds \a stack to this group. The group does not take ownership of the stack. Another
+ way of adding a stack to a group is by specifying the group as the stack's parent
+ QObject in QUndoStack::QUndoStack(). In this case, the stack is deleted when the
+ group is deleted, in the usual manner of QObjects.
+
+ \sa removeStack(), stacks(), QUndoStack::QUndoStack()
+*/
+
+void QUndoGroup::addStack(QUndoStack *stack)
+{
+ Q_D(QUndoGroup);
+
+ if (d->stack_list.contains(stack))
+ return;
+ d->stack_list.append(stack);
+
+ if (QUndoGroup *other = stack->d_func()->group)
+ other->removeStack(stack);
+ stack->d_func()->group = this;
+}
+
+/*!
+ Removes \a stack from this group. If the stack was the active stack in the group,
+ the active stack becomes 0.
+
+ \sa addStack(), stacks(), QUndoStack::~QUndoStack()
+*/
+
+void QUndoGroup::removeStack(QUndoStack *stack)
+{
+ Q_D(QUndoGroup);
+
+ if (d->stack_list.removeAll(stack) == 0)
+ return;
+ if (stack == d->active)
+ setActiveStack(nullptr);
+ stack->d_func()->group = nullptr;
+}
+
+/*!
+ Returns a list of stacks in this group.
+
+ \sa addStack(), removeStack()
+*/
+
+QList<QUndoStack*> QUndoGroup::stacks() const
+{
+ Q_D(const QUndoGroup);
+ return d->stack_list;
+}
+
+/*!
+ Sets the active stack of this group to \a stack.
+
+ If the stack is not a member of this group, this function does nothing.
+
+ Synonymous with calling QUndoStack::setActive() on \a stack.
+
+ The actions returned by createUndoAction() and createRedoAction() will now behave
+ in the same way as those returned by \a stack's QUndoStack::createUndoAction()
+ and QUndoStack::createRedoAction().
+
+ \sa QUndoStack::setActive(), activeStack()
+*/
+
+void QUndoGroup::setActiveStack(QUndoStack *stack)
+{
+ Q_D(QUndoGroup);
+ if (d->active == stack)
+ return;
+
+ if (d->active != nullptr) {
+ disconnect(d->active, SIGNAL(canUndoChanged(bool)),
+ this, SIGNAL(canUndoChanged(bool)));
+ disconnect(d->active, SIGNAL(undoTextChanged(QString)),
+ this, SIGNAL(undoTextChanged(QString)));
+ disconnect(d->active, SIGNAL(canRedoChanged(bool)),
+ this, SIGNAL(canRedoChanged(bool)));
+ disconnect(d->active, SIGNAL(redoTextChanged(QString)),
+ this, SIGNAL(redoTextChanged(QString)));
+ disconnect(d->active, SIGNAL(indexChanged(int)),
+ this, SIGNAL(indexChanged(int)));
+ disconnect(d->active, SIGNAL(cleanChanged(bool)),
+ this, SIGNAL(cleanChanged(bool)));
+ }
+
+ d->active = stack;
+
+ if (d->active == nullptr) {
+ emit canUndoChanged(false);
+ emit undoTextChanged(QString());
+ emit canRedoChanged(false);
+ emit redoTextChanged(QString());
+ emit cleanChanged(true);
+ emit indexChanged(0);
+ } else {
+ connect(d->active, SIGNAL(canUndoChanged(bool)),
+ this, SIGNAL(canUndoChanged(bool)));
+ connect(d->active, SIGNAL(undoTextChanged(QString)),
+ this, SIGNAL(undoTextChanged(QString)));
+ connect(d->active, SIGNAL(canRedoChanged(bool)),
+ this, SIGNAL(canRedoChanged(bool)));
+ connect(d->active, SIGNAL(redoTextChanged(QString)),
+ this, SIGNAL(redoTextChanged(QString)));
+ connect(d->active, SIGNAL(indexChanged(int)),
+ this, SIGNAL(indexChanged(int)));
+ connect(d->active, SIGNAL(cleanChanged(bool)),
+ this, SIGNAL(cleanChanged(bool)));
+ emit canUndoChanged(d->active->canUndo());
+ emit undoTextChanged(d->active->undoText());
+ emit canRedoChanged(d->active->canRedo());
+ emit redoTextChanged(d->active->redoText());
+ emit cleanChanged(d->active->isClean());
+ emit indexChanged(d->active->index());
+ }
+
+ emit activeStackChanged(d->active);
+}
+
+/*!
+ Returns the active stack of this group.
+
+ If none of the stacks are active, or if the group is empty, this function
+ returns \nullptr.
+
+ \sa setActiveStack(), QUndoStack::setActive()
+*/
+
+QUndoStack *QUndoGroup::activeStack() const
+{
+ Q_D(const QUndoGroup);
+ return d->active;
+}
+
+#ifndef QT_NO_ACTION
+
+/*!
+ Creates an undo QAction object with parent \a parent.
+
+ Triggering this action will cause a call to QUndoStack::undo() on the active stack.
+ The text of this action will always be the text of the command which will be undone
+ in the next call to undo(), prefixed by \a prefix. If there is no command available
+ for undo, if the group is empty or if none of the stacks are active, this action will
+ be disabled.
+
+ If \a prefix is empty, the default template "Undo %1" is used instead of prefix.
+ Before Qt 4.8, the prefix "Undo" was used by default.
+
+ \sa createRedoAction(), canUndo(), QUndoCommand::text()
+*/
+
+QAction *QUndoGroup::createUndoAction(QObject *parent, const QString &prefix) const
+{
+ QAction *action = new QAction(parent);
+ action->setEnabled(canUndo());
+
+ QString effectivePrefix = prefix;
+ QString defaultText;
+ if (prefix.isEmpty()) {
+ effectivePrefix = tr("Undo %1");
+ defaultText = tr("Undo", "Default text for undo action");
+ }
+
+ QUndoStackPrivate::setPrefixedText(action, effectivePrefix, defaultText, undoText());
+
+ connect(this, &QUndoGroup::canUndoChanged, action, &QAction::setEnabled);
+ connect(this, &QUndoGroup::undoTextChanged, action, [=](const QString &text) {
+ QUndoStackPrivate::setPrefixedText(action, effectivePrefix, defaultText, text);
+ });
+ connect(action, &QAction::triggered, this, &QUndoGroup::undo);
+
+ return action;
+}
+
+/*!
+ Creates an redo QAction object with parent \a parent.
+
+ Triggering this action will cause a call to QUndoStack::redo() on the active stack.
+ The text of this action will always be the text of the command which will be redone
+ in the next call to redo(), prefixed by \a prefix. If there is no command available
+ for redo, if the group is empty or if none of the stacks are active, this action will
+ be disabled.
+
+ If \a prefix is empty, the default template "Redo %1" is used instead of prefix.
+ Before Qt 4.8, the prefix "Redo" was used by default.
+
+ \sa createUndoAction(), canRedo(), QUndoCommand::text()
+*/
+
+QAction *QUndoGroup::createRedoAction(QObject *parent, const QString &prefix) const
+{
+ QAction *action = new QAction(parent);
+ action->setEnabled(canRedo());
+
+ QString effectivePrefix = prefix;
+ QString defaultText;
+ if (prefix.isEmpty()) {
+ effectivePrefix = tr("Redo %1");
+ defaultText = tr("Redo", "Default text for redo action");
+ }
+
+ QUndoStackPrivate::setPrefixedText(action, effectivePrefix, defaultText, redoText());
+
+ connect(this, &QUndoGroup::canRedoChanged, action, &QAction::setEnabled);
+ connect(this, &QUndoGroup::redoTextChanged, action, [=](const QString &text) {
+ QUndoStackPrivate::setPrefixedText(action, effectivePrefix, defaultText, text);
+ });
+ connect(action, &QAction::triggered, this, &QUndoGroup::redo);
+ return action;
+}
+
+#endif // QT_NO_ACTION
+
+/*!
+ Calls QUndoStack::undo() on the active stack.
+
+ If none of the stacks are active, or if the group is empty, this function
+ does nothing.
+
+ \sa redo(), canUndo(), setActiveStack()
+*/
+
+void QUndoGroup::undo()
+{
+ Q_D(QUndoGroup);
+ if (d->active != nullptr)
+ d->active->undo();
+}
+
+/*!
+ Calls QUndoStack::redo() on the active stack.
+
+ If none of the stacks are active, or if the group is empty, this function
+ does nothing.
+
+ \sa undo(), canRedo(), setActiveStack()
+*/
+
+
+void QUndoGroup::redo()
+{
+ Q_D(QUndoGroup);
+ if (d->active != nullptr)
+ d->active->redo();
+}
+
+/*!
+ Returns the value of the active stack's QUndoStack::canUndo().
+
+ If none of the stacks are active, or if the group is empty, this function
+ returns \c false.
+
+ \sa canRedo(), setActiveStack()
+*/
+
+bool QUndoGroup::canUndo() const
+{
+ Q_D(const QUndoGroup);
+ return d->active != nullptr && d->active->canUndo();
+}
+
+/*!
+ Returns the value of the active stack's QUndoStack::canRedo().
+
+ If none of the stacks are active, or if the group is empty, this function
+ returns \c false.
+
+ \sa canUndo(), setActiveStack()
+*/
+
+bool QUndoGroup::canRedo() const
+{
+ Q_D(const QUndoGroup);
+ return d->active != nullptr && d->active->canRedo();
+}
+
+/*!
+ Returns the value of the active stack's QUndoStack::undoText().
+
+ If none of the stacks are active, or if the group is empty, this function
+ returns an empty string.
+
+ \sa redoText(), setActiveStack()
+*/
+
+QString QUndoGroup::undoText() const
+{
+ Q_D(const QUndoGroup);
+ return d->active == nullptr ? QString() : d->active->undoText();
+}
+
+/*!
+ Returns the value of the active stack's QUndoStack::redoText().
+
+ If none of the stacks are active, or if the group is empty, this function
+ returns an empty string.
+
+ \sa undoText(), setActiveStack()
+*/
+
+QString QUndoGroup::redoText() const
+{
+ Q_D(const QUndoGroup);
+ return d->active == nullptr ? QString() : d->active->redoText();
+}
+
+/*!
+ Returns the value of the active stack's QUndoStack::isClean().
+
+ If none of the stacks are active, or if the group is empty, this function
+ returns \c true.
+
+ \sa setActiveStack()
+*/
+
+bool QUndoGroup::isClean() const
+{
+ Q_D(const QUndoGroup);
+ return d->active == nullptr || d->active->isClean();
+}
+
+/*! \fn void QUndoGroup::activeStackChanged(QUndoStack *stack)
+
+ This signal is emitted whenever the active stack of the group changes. This can happen
+ when setActiveStack() or QUndoStack::setActive() is called, or when the active stack
+ is removed form the group. \a stack is the new active stack. If no stack is active,
+ \a stack is 0.
+
+ \sa setActiveStack(), QUndoStack::setActive()
+*/
+
+/*! \fn void QUndoGroup::indexChanged(int idx)
+
+ This signal is emitted whenever the active stack emits QUndoStack::indexChanged()
+ or the active stack changes.
+
+ \a idx is the new current index, or 0 if the active stack is 0.
+
+ \sa QUndoStack::indexChanged(), setActiveStack()
+*/
+
+/*! \fn void QUndoGroup::cleanChanged(bool clean)
+
+ This signal is emitted whenever the active stack emits QUndoStack::cleanChanged()
+ or the active stack changes.
+
+ \a clean is the new state, or true if the active stack is 0.
+
+ \sa QUndoStack::cleanChanged(), setActiveStack()
+*/
+
+/*! \fn void QUndoGroup::canUndoChanged(bool canUndo)
+
+ This signal is emitted whenever the active stack emits QUndoStack::canUndoChanged()
+ or the active stack changes.
+
+ \a canUndo is the new state, or false if the active stack is 0.
+
+ \sa QUndoStack::canUndoChanged(), setActiveStack()
+*/
+
+/*! \fn void QUndoGroup::canRedoChanged(bool canRedo)
+
+ This signal is emitted whenever the active stack emits QUndoStack::canRedoChanged()
+ or the active stack changes.
+
+ \a canRedo is the new state, or false if the active stack is 0.
+
+ \sa QUndoStack::canRedoChanged(), setActiveStack()
+*/
+
+/*! \fn void QUndoGroup::undoTextChanged(const QString &undoText)
+
+ This signal is emitted whenever the active stack emits QUndoStack::undoTextChanged()
+ or the active stack changes.
+
+ \a undoText is the new state, or an empty string if the active stack is 0.
+
+ \sa QUndoStack::undoTextChanged(), setActiveStack()
+*/
+
+/*! \fn void QUndoGroup::redoTextChanged(const QString &redoText)
+
+ This signal is emitted whenever the active stack emits QUndoStack::redoTextChanged()
+ or the active stack changes.
+
+ \a redoText is the new state, or an empty string if the active stack is 0.
+
+ \sa QUndoStack::redoTextChanged(), setActiveStack()
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qundogroup.cpp"
diff --git a/src/gui/util/qundogroup.h b/src/gui/util/qundogroup.h
new file mode 100644
index 0000000000..e92f4f46b0
--- /dev/null
+++ b/src/gui/util/qundogroup.h
@@ -0,0 +1,64 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QUNDOGROUP_H
+#define QUNDOGROUP_H
+
+#include <QtGui/qtguiglobal.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qstring.h>
+
+QT_REQUIRE_CONFIG(undogroup);
+
+QT_BEGIN_NAMESPACE
+
+class QUndoGroupPrivate;
+class QUndoStack;
+class QAction;
+
+class Q_GUI_EXPORT QUndoGroup : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QUndoGroup)
+
+public:
+ explicit QUndoGroup(QObject *parent = nullptr);
+ ~QUndoGroup();
+
+ void addStack(QUndoStack *stack);
+ void removeStack(QUndoStack *stack);
+ QList<QUndoStack*> stacks() const;
+ QUndoStack *activeStack() const;
+
+#ifndef QT_NO_ACTION
+ QAction *createUndoAction(QObject *parent, const QString &prefix = QString()) const;
+ QAction *createRedoAction(QObject *parent, const QString &prefix = QString()) const;
+#endif // QT_NO_ACTION
+
+ bool canUndo() const;
+ bool canRedo() const;
+ QString undoText() const;
+ QString redoText() const;
+ bool isClean() const;
+
+public Q_SLOTS:
+ void undo();
+ void redo();
+ void setActiveStack(QUndoStack *stack);
+
+Q_SIGNALS:
+ void activeStackChanged(QUndoStack *stack);
+ void indexChanged(int idx);
+ void cleanChanged(bool clean);
+ void canUndoChanged(bool canUndo);
+ void canRedoChanged(bool canRedo);
+ void undoTextChanged(const QString &undoText);
+ void redoTextChanged(const QString &redoText);
+
+private:
+ Q_DISABLE_COPY(QUndoGroup)
+};
+
+QT_END_NAMESPACE
+
+#endif // QUNDOGROUP_H
diff --git a/src/gui/util/qundostack.cpp b/src/gui/util/qundostack.cpp
new file mode 100644
index 0000000000..403833d421
--- /dev/null
+++ b/src/gui/util/qundostack.cpp
@@ -0,0 +1,1354 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <QtCore/qdebug.h>
+#include "qundostack.h"
+#if QT_CONFIG(undogroup)
+#include "qundogroup.h"
+#endif
+#include "qundostack_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QUndoCommand
+ \brief The QUndoCommand class is the base class of all commands stored on a QUndoStack.
+ \since 4.2
+
+ \inmodule QtGui
+
+ For an overview of Qt's Undo Framework, see the
+ \l{Overview of Qt's Undo Framework}{overview document}.
+
+ A QUndoCommand represents a single editing action on a document; for example,
+ inserting or deleting a block of text in a text editor. QUndoCommand can apply
+ a change to the document with redo() and undo the change with undo(). The
+ implementations for these functions must be provided in a derived class.
+
+ \snippet code/src_gui_util_qundostack.cpp 0
+
+ A QUndoCommand has an associated text(). This is a short string
+ describing what the command does. It is used to update the text
+ properties of the stack's undo and redo actions; see
+ QUndoStack::createUndoAction() and QUndoStack::createRedoAction().
+
+ QUndoCommand objects are owned by the stack they were pushed on.
+ QUndoStack deletes a command if it has been undone and a new command is pushed. For example:
+
+\snippet code/src_gui_util_qundostack.cpp 1
+
+ In effect, when a command is pushed, it becomes the top-most command
+ on the stack.
+
+ To support command compression, QUndoCommand has an id() and the virtual function
+ mergeWith(). These functions are used by QUndoStack::push().
+
+ To support command macros, a QUndoCommand object can have any number of child
+ commands. Undoing or redoing the parent command will cause the child
+ commands to be undone or redone. A command can be assigned
+ to a parent explicitly in the constructor. In this case, the command
+ will be owned by the parent.
+
+ The parent in this case is usually an empty command, in that it doesn't
+ provide its own implementation of undo() and redo(). Instead, it uses
+ the base implementations of these functions, which simply call undo() or
+ redo() on all its children. The parent should, however, have a meaningful
+ text().
+
+ \snippet code/src_gui_util_qundostack.cpp 2
+
+ Another way to create macros is to use the convenience functions
+ QUndoStack::beginMacro() and QUndoStack::endMacro().
+
+ \sa QUndoStack
+*/
+
+/*!
+ Constructs a QUndoCommand object with the given \a parent and \a text.
+
+ If \a parent is not \nullptr, this command is appended to parent's
+ child list. The parent command then owns this command and will delete
+ it in its destructor.
+
+ \sa ~QUndoCommand()
+*/
+
+QUndoCommand::QUndoCommand(const QString &text, QUndoCommand *parent)
+ : QUndoCommand(parent)
+{
+ setText(text);
+}
+
+/*!
+ Constructs a QUndoCommand object with parent \a parent.
+
+ If \a parent is not \nullptr, this command is appended to parent's
+ child list. The parent command then owns this command and will delete
+ it in its destructor.
+
+ \sa ~QUndoCommand()
+*/
+
+QUndoCommand::QUndoCommand(QUndoCommand *parent)
+{
+ d = new QUndoCommandPrivate;
+ if (parent != nullptr)
+ parent->d->child_list.append(this);
+}
+
+/*!
+ Destroys the QUndoCommand object and all child commands.
+
+ \sa QUndoCommand()
+*/
+
+QUndoCommand::~QUndoCommand()
+{
+ qDeleteAll(d->child_list);
+ delete d;
+}
+
+/*!
+ \since 5.9
+
+ Returns whether the command is obsolete.
+
+ The boolean is used for the automatic removal of commands that are not necessary in the
+ stack anymore. The isObsolete function is checked in the functions QUndoStack::push(),
+ QUndoStack::undo(), QUndoStack::redo(), and QUndoStack::setIndex().
+
+ \sa setObsolete(), mergeWith(), QUndoStack::push(), QUndoStack::undo(), QUndoStack::redo()
+*/
+
+bool QUndoCommand::isObsolete() const
+{
+ return d->obsolete;
+}
+
+/*!
+ \since 5.9
+
+ Sets whether the command is obsolete to \a obsolete.
+
+ \sa isObsolete(), mergeWith(), QUndoStack::push(), QUndoStack::undo(), QUndoStack::redo()
+*/
+
+void QUndoCommand::setObsolete(bool obsolete)
+{
+ d->obsolete = obsolete;
+}
+
+/*!
+ Returns the ID of this command.
+
+ A command ID is used in command compression. It must be an integer unique to
+ this command's class, or -1 if the command doesn't support compression.
+
+ If the command supports compression this function must be overridden in the
+ derived class to return the correct ID. The base implementation returns -1.
+
+ QUndoStack::push() will only try to merge two commands if they have the
+ same ID, and the ID is not -1.
+
+ \sa mergeWith(), QUndoStack::push()
+*/
+
+int QUndoCommand::id() const
+{
+ return -1;
+}
+
+/*!
+ Attempts to merge this command with \a command. Returns \c true on
+ success; otherwise returns \c false.
+
+ If this function returns \c true, calling this command's redo() must have the same
+ effect as redoing both this command and \a command.
+ Similarly, calling this command's undo() must have the same effect as undoing
+ \a command and this command.
+
+ QUndoStack will only try to merge two commands if they have the same id, and
+ the id is not -1.
+
+ The default implementation returns \c false.
+
+ \snippet code/src_gui_util_qundostack.cpp 3
+
+ \sa id(), QUndoStack::push()
+*/
+
+bool QUndoCommand::mergeWith(const QUndoCommand *command)
+{
+ Q_UNUSED(command);
+ return false;
+}
+
+/*!
+ Applies a change to the document. This function must be implemented in
+ the derived class. Calling QUndoStack::push(),
+ QUndoStack::undo() or QUndoStack::redo() from this function leads to
+ undefined beahavior.
+
+ The default implementation calls redo() on all child commands.
+
+ \sa undo()
+*/
+
+void QUndoCommand::redo()
+{
+ for (int i = 0; i < d->child_list.size(); ++i)
+ d->child_list.at(i)->redo();
+}
+
+/*!
+ Reverts a change to the document. After undo() is called, the state of
+ the document should be the same as before redo() was called. This function must
+ be implemented in the derived class. Calling QUndoStack::push(),
+ QUndoStack::undo() or QUndoStack::redo() from this function leads to
+ undefined beahavior.
+
+ The default implementation calls undo() on all child commands in reverse order.
+
+ \sa redo()
+*/
+
+void QUndoCommand::undo()
+{
+ for (int i = d->child_list.size() - 1; i >= 0; --i)
+ d->child_list.at(i)->undo();
+}
+
+/*!
+ Returns a short text string describing what this command does; for example,
+ "insert text".
+
+ The text is used for names of items in QUndoView.
+
+ \sa actionText(), setText(), QUndoStack::createUndoAction(), QUndoStack::createRedoAction()
+*/
+
+QString QUndoCommand::text() const
+{
+ return d->text;
+}
+
+/*!
+ \since 4.8
+
+ Returns a short text string describing what this command does; for example,
+ "insert text".
+
+ The text is used when the text properties of the stack's undo and redo
+ actions are updated.
+
+ \sa text(), setText(), QUndoStack::createUndoAction(), QUndoStack::createRedoAction()
+*/
+
+QString QUndoCommand::actionText() const
+{
+ return d->actionText;
+}
+
+/*!
+ Sets the command's text to be the \a text specified.
+
+ The specified text should be a short user-readable string describing what this
+ command does.
+
+ If you need to have two different strings for text() and actionText(), separate
+ them with "\\n" and pass into this function. Even if you do not use this feature
+ for English strings during development, you can still let translators use two
+ different strings in order to match specific languages' needs.
+ The described feature and the function actionText() are available since Qt 4.8.
+
+ \sa text(), actionText(), QUndoStack::createUndoAction(), QUndoStack::createRedoAction()
+*/
+
+void QUndoCommand::setText(const QString &text)
+{
+ int cdpos = text.indexOf(u'\n');
+ if (cdpos > 0) {
+ d->text = text.left(cdpos);
+ d->actionText = text.mid(cdpos + 1);
+ } else {
+ d->text = text;
+ d->actionText = text;
+ }
+}
+
+/*!
+ \since 4.4
+
+ Returns the number of child commands in this command.
+
+ \sa child()
+*/
+
+int QUndoCommand::childCount() const
+{
+ return d->child_list.size();
+}
+
+/*!
+ \since 4.4
+
+ Returns the child command at \a index.
+
+ \sa childCount(), QUndoStack::command()
+*/
+
+const QUndoCommand *QUndoCommand::child(int index) const
+{
+ if (index < 0 || index >= d->child_list.size())
+ return nullptr;
+ return d->child_list.at(index);
+}
+
+#if QT_CONFIG(undostack)
+
+/*!
+ \class QUndoStack
+ \brief The QUndoStack class is a stack of QUndoCommand objects.
+ \since 4.2
+
+ \inmodule QtGui
+
+ For an overview of Qt's Undo Framework, see the
+ \l{Overview of Qt's Undo Framework}{overview document}.
+
+ An undo stack maintains a stack of commands that have been applied to a
+ document.
+
+ New commands are pushed on the stack using push(). Commands can be
+ undone and redone using undo() and redo(), or by triggering the
+ actions returned by createUndoAction() and createRedoAction().
+
+ QUndoStack keeps track of the \a current command. This is the command
+ which will be executed by the next call to redo(). The index of this
+ command is returned by index(). The state of the edited object can be
+ rolled forward or back using setIndex(). If the top-most command on the
+ stack has already been redone, index() is equal to count().
+
+ QUndoStack provides support for undo and redo actions, command
+ compression, command macros, and supports the concept of a
+ \e{clean state}.
+
+ \section1 Undo and Redo Actions
+
+ QUndoStack provides convenient undo and redo QAction objects, which
+ can be inserted into a menu or a toolbar. When commands are undone or
+ redone, QUndoStack updates the text properties of these actions
+ to reflect what change they will trigger. The actions are also disabled
+ when no command is available for undo or redo. These actions
+ are returned by QUndoStack::createUndoAction() and QUndoStack::createRedoAction().
+
+ \section1 Command Compression and Macros
+
+ Command compression is useful when several commands can be compressed
+ into a single command that can be undone and redone in a single operation.
+ For example, when a user types a character in a text editor, a new command
+ is created. This command inserts the character into the document at the
+ cursor position. However, it is more convenient for the user to be able
+ to undo or redo typing of whole words, sentences, or paragraphs.
+ Command compression allows these single-character commands to be merged
+ into a single command which inserts or deletes sections of text.
+ For more information, see QUndoCommand::mergeWith() and push().
+
+ A command macro is a sequence of commands, all of which are undone and
+ redone in one go. Command macros are created by giving a command a list
+ of child commands.
+ Undoing or redoing the parent command will cause the child commands to
+ be undone or redone. Command macros may be created explicitly
+ by specifying a parent in the QUndoCommand constructor, or by using the
+ convenience functions beginMacro() and endMacro().
+
+ Although command compression and macros appear to have the same effect to the
+ user, they often have different uses in an application. Commands that
+ perform small changes to a document may be usefully compressed if there is
+ no need to individually record them, and if only larger changes are relevant
+ to the user.
+ However, for commands that need to be recorded individually, or those that
+ cannot be compressed, it is useful to use macros to provide a more convenient
+ user experience while maintaining a record of each command.
+
+ \section1 Clean State
+
+ QUndoStack supports the concept of a clean state. When the
+ document is saved to disk, the stack can be marked as clean using
+ setClean(). Whenever the stack returns to this state through undoing and
+ redoing commands, it emits the signal cleanChanged(). This signal
+ is also emitted when the stack leaves the clean state. This signal is
+ usually used to enable and disable the save actions in the application,
+ and to update the document's title to reflect that it contains unsaved
+ changes.
+
+ \section1 Obsolete Commands
+
+ QUndoStack is able to delete commands from the stack if the command is no
+ longer needed. One example may be to delete a command when two commands are
+ merged together in such a way that the merged command has no function. This
+ can be seen with move commands where the user moves their mouse to one part
+ of the screen and then moves it to the original position. The merged command
+ results in a mouse movement of 0. This command can be deleted since it serves
+ no purpose. Another example is with networking commands that fail due to connection
+ issues. In this case, the command is to be removed from the stack because the redo()
+ and undo() functions have no function since there was connection issues.
+
+ A command can be marked obsolete with the QUndoCommand::setObsolete() function.
+ The QUndoCommand::isObsolete() flag is checked in QUndoStack::push(),
+ QUndoStack::undo(), QUndoStack::redo(), and QUndoStack::setIndex() after calling
+ QUndoCommand::undo(), QUndoCommand::redo() and QUndoCommand:mergeWith() where
+ applicable.
+
+ If a command is set obsolete and the clean index is greater than or equal to the
+ current command index, then the clean index will be reset when the command is
+ deleted from the stack.
+
+ \sa QUndoCommand, QUndoView
+*/
+
+/*! \internal
+ Sets the current index to \a idx, emitting appropriate signals. If \a clean is true,
+ makes \a idx the clean index as well.
+*/
+
+void QUndoStackPrivate::setIndex(int idx, bool clean)
+{
+ Q_Q(QUndoStack);
+
+ bool was_clean = index == clean_index;
+
+ if (idx != index) {
+ index = idx;
+ emit q->indexChanged(index);
+ emit q->canUndoChanged(q->canUndo());
+ emit q->undoTextChanged(q->undoText());
+ emit q->canRedoChanged(q->canRedo());
+ emit q->redoTextChanged(q->redoText());
+ }
+
+ if (clean)
+ clean_index = index;
+
+ bool is_clean = index == clean_index;
+ if (is_clean != was_clean)
+ emit q->cleanChanged(is_clean);
+}
+
+/*! \internal
+ If the number of commands on the stack exceedes the undo limit, deletes commands from
+ the bottom of the stack.
+
+ Returns \c true if commands were deleted.
+*/
+
+bool QUndoStackPrivate::checkUndoLimit()
+{
+ if (undo_limit <= 0 || !macro_stack.isEmpty() || undo_limit >= command_list.size())
+ return false;
+
+ int del_count = command_list.size() - undo_limit;
+
+ for (int i = 0; i < del_count; ++i)
+ delete command_list.takeFirst();
+
+ index -= del_count;
+ if (clean_index != -1) {
+ if (clean_index < del_count)
+ clean_index = -1; // we've deleted the clean command
+ else
+ clean_index -= del_count;
+ }
+
+ return true;
+}
+
+/*!
+ Constructs an empty undo stack with the parent \a parent. The
+ stack will initially be in the clean state. If \a parent is a
+ QUndoGroup object, the stack is automatically added to the group.
+
+ \sa push()
+*/
+
+QUndoStack::QUndoStack(QObject *parent)
+ : QObject(*(new QUndoStackPrivate), parent)
+{
+#if QT_CONFIG(undogroup)
+ if (QUndoGroup *group = qobject_cast<QUndoGroup*>(parent))
+ group->addStack(this);
+#endif
+}
+
+/*!
+ Destroys the undo stack, deleting any commands that are on it. If the
+ stack is in a QUndoGroup, the stack is automatically removed from the group.
+
+ \sa QUndoStack()
+*/
+
+QUndoStack::~QUndoStack()
+{
+#if QT_CONFIG(undogroup)
+ Q_D(QUndoStack);
+ if (d->group != nullptr)
+ d->group->removeStack(this);
+#endif
+ clear();
+}
+
+/*!
+ Clears the command stack by deleting all commands on it, and returns the stack
+ to the clean state.
+
+ Commands are not undone or redone; the state of the edited object remains
+ unchanged.
+
+ This function is usually used when the contents of the document are
+ abandoned.
+
+ \sa QUndoStack()
+*/
+
+void QUndoStack::clear()
+{
+ Q_D(QUndoStack);
+
+ if (d->command_list.isEmpty())
+ return;
+
+ bool was_clean = isClean();
+
+ d->macro_stack.clear();
+ qDeleteAll(d->command_list);
+ d->command_list.clear();
+
+ d->index = 0;
+ d->clean_index = 0;
+
+ emit indexChanged(0);
+ emit canUndoChanged(false);
+ emit undoTextChanged(QString());
+ emit canRedoChanged(false);
+ emit redoTextChanged(QString());
+
+ if (!was_clean)
+ emit cleanChanged(true);
+}
+
+/*!
+ Pushes \a cmd on the stack or merges it with the most recently executed command.
+ In either case, executes \a cmd by calling its redo() function.
+
+ If \a cmd's id is not -1, and if the id is the same as that of the
+ most recently executed command, QUndoStack will attempt to merge the two
+ commands by calling QUndoCommand::mergeWith() on the most recently executed
+ command. If QUndoCommand::mergeWith() returns \c true, \a cmd is deleted.
+
+ After calling QUndoCommand::redo() and, if applicable, QUndoCommand::mergeWith(),
+ QUndoCommand::isObsolete() will be called for \a cmd or the merged command.
+ If QUndoCommand::isObsolete() returns \c true, then \a cmd or the merged command
+ will be deleted from the stack.
+
+ In all other cases \a cmd is simply pushed on the stack.
+
+ If commands were undone before \a cmd was pushed, the current command and
+ all commands above it are deleted. Hence \a cmd always ends up being the
+ top-most on the stack.
+
+ Once a command is pushed, the stack takes ownership of it. There
+ are no getters to return the command, since modifying it after it has
+ been executed will almost always lead to corruption of the document's
+ state.
+
+ \sa QUndoCommand::id(), QUndoCommand::mergeWith()
+*/
+
+void QUndoStack::push(QUndoCommand *cmd)
+{
+ Q_D(QUndoStack);
+ if (!cmd->isObsolete())
+ cmd->redo();
+
+ bool macro = !d->macro_stack.isEmpty();
+
+ QUndoCommand *cur = nullptr;
+ if (macro) {
+ QUndoCommand *macro_cmd = d->macro_stack.constLast();
+ if (!macro_cmd->d->child_list.isEmpty())
+ cur = macro_cmd->d->child_list.constLast();
+ } else {
+ if (d->index > 0)
+ cur = d->command_list.at(d->index - 1);
+ while (d->index < d->command_list.size())
+ delete d->command_list.takeLast();
+ if (d->clean_index > d->index)
+ d->clean_index = -1; // we've deleted the clean state
+ }
+
+ bool try_merge = cur != nullptr
+ && cur->id() != -1
+ && cur->id() == cmd->id()
+ && (macro || d->index != d->clean_index);
+
+ if (try_merge && cur->mergeWith(cmd)) {
+ delete cmd;
+
+ if (macro) {
+ if (cur->isObsolete())
+ delete d->macro_stack.constLast()->d->child_list.takeLast();
+ } else {
+ if (cur->isObsolete()) {
+ delete d->command_list.takeLast();
+
+ d->setIndex(d->index - 1, false);
+ } else {
+ emit indexChanged(d->index);
+ emit canUndoChanged(canUndo());
+ emit undoTextChanged(undoText());
+ emit canRedoChanged(canRedo());
+ emit redoTextChanged(redoText());
+ }
+ }
+ } else if (cmd->isObsolete()) {
+ delete cmd; // command should be deleted and NOT added to the stack
+ } else {
+ if (macro) {
+ d->macro_stack.constLast()->d->child_list.append(cmd);
+ } else {
+ d->command_list.append(cmd);
+ d->checkUndoLimit();
+ d->setIndex(d->index + 1, false);
+ }
+ }
+}
+
+/*!
+ Marks the stack as clean and emits cleanChanged() if the stack was
+ not already clean.
+
+ This is typically called when a document is saved, for example.
+
+ Whenever the stack returns to this state through the use of undo/redo
+ commands, it emits the signal cleanChanged(). This signal is also
+ emitted when the stack leaves the clean state.
+
+ \sa isClean(), resetClean(), cleanIndex()
+*/
+
+void QUndoStack::setClean()
+{
+ Q_D(QUndoStack);
+ if (Q_UNLIKELY(!d->macro_stack.isEmpty())) {
+ qWarning("QUndoStack::setClean(): cannot set clean in the middle of a macro");
+ return;
+ }
+
+ d->setIndex(d->index, true);
+}
+
+/*!
+ \since 5.8
+
+ Leaves the clean state and emits cleanChanged() if the stack was clean.
+ This method resets the clean index to -1.
+
+ This is typically called in the following cases, when a document has been:
+ \list
+ \li created basing on some template and has not been saved,
+ so no filename has been associated with the document yet.
+ \li restored from a backup file.
+ \li changed outside of the editor and the user did not reload it.
+ \endlist
+
+ \sa isClean(), setClean(), cleanIndex()
+*/
+
+void QUndoStack::resetClean()
+{
+ Q_D(QUndoStack);
+ const bool was_clean = isClean();
+ d->clean_index = -1;
+ if (was_clean)
+ emit cleanChanged(false);
+}
+
+/*!
+ \since 5.12
+ \property QUndoStack::clean
+ \brief the clean status of this stack.
+
+ This property indicates whether or not the stack is clean. For example, a
+ stack is clean when a document has been saved.
+
+ \sa isClean(), setClean(), resetClean(), cleanIndex()
+*/
+
+/*!
+ If the stack is in the clean state, returns \c true; otherwise returns \c false.
+
+ \sa setClean(), cleanIndex()
+*/
+
+bool QUndoStack::isClean() const
+{
+ Q_D(const QUndoStack);
+ if (!d->macro_stack.isEmpty())
+ return false;
+ return d->clean_index == d->index;
+}
+
+/*!
+ Returns the clean index. This is the index at which setClean() was called.
+
+ A stack may not have a clean index. This happens if a document is saved,
+ some commands are undone, then a new command is pushed. Since
+ push() deletes all the undone commands before pushing the new command, the stack
+ can't return to the clean state again. In this case, this function returns -1.
+ The -1 may also be returned after an explicit call to resetClean().
+
+ \sa isClean(), setClean()
+*/
+
+int QUndoStack::cleanIndex() const
+{
+ Q_D(const QUndoStack);
+ return d->clean_index;
+}
+
+/*!
+ Undoes the command below the current command by calling QUndoCommand::undo().
+ Decrements the current command index.
+
+ If the stack is empty, or if the bottom command on the stack has already been
+ undone, this function does nothing.
+
+ After the command is undone, if QUndoCommand::isObsolete() returns \c true,
+ then the command will be deleted from the stack. Additionally, if the clean
+ index is greater than or equal to the current command index, then the clean
+ index is reset.
+
+ \sa redo(), index()
+*/
+
+void QUndoStack::undo()
+{
+ Q_D(QUndoStack);
+ if (d->index == 0)
+ return;
+
+ if (Q_UNLIKELY(!d->macro_stack.isEmpty())) {
+ qWarning("QUndoStack::undo(): cannot undo in the middle of a macro");
+ return;
+ }
+
+ int idx = d->index - 1;
+ QUndoCommand *cmd = d->command_list.at(idx);
+
+ if (!cmd->isObsolete())
+ cmd->undo();
+
+ if (cmd->isObsolete()) { // A separate check is done b/c the undo command may set obsolete flag
+ delete d->command_list.takeAt(idx);
+
+ if (d->clean_index > idx)
+ resetClean();
+ }
+
+ d->setIndex(idx, false);
+}
+
+/*!
+ Redoes the current command by calling QUndoCommand::redo(). Increments the current
+ command index.
+
+ If the stack is empty, or if the top command on the stack has already been
+ redone, this function does nothing.
+
+ If QUndoCommand::isObsolete() returns true for the current command, then
+ the command will be deleted from the stack. Additionally, if the clean
+ index is greater than or equal to the current command index, then the clean
+ index is reset.
+
+ \sa undo(), index()
+*/
+
+void QUndoStack::redo()
+{
+ Q_D(QUndoStack);
+ if (d->index == d->command_list.size())
+ return;
+
+ if (Q_UNLIKELY(!d->macro_stack.isEmpty())) {
+ qWarning("QUndoStack::redo(): cannot redo in the middle of a macro");
+ return;
+ }
+
+ int idx = d->index;
+ QUndoCommand *cmd = d->command_list.at(idx);
+
+ if (!cmd->isObsolete())
+ cmd->redo(); // A separate check is done b/c the undo command may set obsolete flag
+
+ if (cmd->isObsolete()) {
+ delete d->command_list.takeAt(idx);
+
+ if (d->clean_index > idx)
+ resetClean();
+ } else {
+ d->setIndex(d->index + 1, false);
+ }
+}
+
+/*!
+ Returns the number of commands on the stack. Macro commands are counted as
+ one command.
+
+ \sa index(), setIndex(), command()
+*/
+
+int QUndoStack::count() const
+{
+ Q_D(const QUndoStack);
+ return d->command_list.size();
+}
+
+/*!
+ Returns the index of the current command. This is the command that will be
+ executed on the next call to redo(). It is not always the top-most command
+ on the stack, since a number of commands may have been undone.
+
+ \sa undo(), redo(), count()
+*/
+
+int QUndoStack::index() const
+{
+ Q_D(const QUndoStack);
+ return d->index;
+}
+
+/*!
+ Repeatedly calls undo() or redo() until the current command index reaches
+ \a idx. This function can be used to roll the state of the document forwards
+ of backwards. indexChanged() is emitted only once.
+
+ \sa index(), count(), undo(), redo()
+*/
+
+void QUndoStack::setIndex(int idx)
+{
+ Q_D(QUndoStack);
+ if (Q_UNLIKELY(!d->macro_stack.isEmpty())) {
+ qWarning("QUndoStack::setIndex(): cannot set index in the middle of a macro");
+ return;
+ }
+
+ if (idx < 0)
+ idx = 0;
+ else if (idx > d->command_list.size())
+ idx = d->command_list.size();
+
+ int i = d->index;
+ while (i < idx) {
+ QUndoCommand *cmd = d->command_list.at(i);
+
+ if (!cmd->isObsolete())
+ cmd->redo(); // A separate check is done b/c the undo command may set obsolete flag
+
+ if (cmd->isObsolete()) {
+ delete d->command_list.takeAt(i);
+
+ if (d->clean_index > i)
+ resetClean();
+
+ idx--; // Subtract from idx because we removed a command
+ } else {
+ i++;
+ }
+ }
+
+ while (i > idx) {
+ QUndoCommand *cmd = d->command_list.at(--i);
+
+ cmd->undo();
+ if (cmd->isObsolete()) {
+ delete d->command_list.takeAt(i);
+
+ if (d->clean_index > i)
+ resetClean();
+ }
+ }
+
+ d->setIndex(idx, false);
+}
+
+/*!
+ \since 5.12
+ \property QUndoStack::canUndo
+ \brief whether this stack can undo.
+
+ This property indicates whether or not there is a command that can be
+ undone.
+
+ \sa canUndo(), index(), canRedo()
+*/
+
+/*!
+ Returns \c true if there is a command available for undo; otherwise returns \c false.
+
+ This function returns \c false if the stack is empty, or if the bottom command
+ on the stack has already been undone.
+
+ Synonymous with index() == 0.
+
+ \sa index(), canRedo()
+*/
+
+bool QUndoStack::canUndo() const
+{
+ Q_D(const QUndoStack);
+ if (!d->macro_stack.isEmpty())
+ return false;
+ return d->index > 0;
+}
+
+/*!
+ \since 5.12
+ \property QUndoStack::canRedo
+ \brief whether this stack can redo.
+
+ This property indicates whether or not there is a command that can be
+ redone.
+
+ \sa canRedo(), index(), canUndo()
+*/
+
+/*!
+ Returns \c true if there is a command available for redo; otherwise returns \c false.
+
+ This function returns \c false if the stack is empty or if the top command
+ on the stack has already been redone.
+
+ Synonymous with index() == count().
+
+ \sa index(), canUndo()
+*/
+
+bool QUndoStack::canRedo() const
+{
+ Q_D(const QUndoStack);
+ if (!d->macro_stack.isEmpty())
+ return false;
+ return d->index < d->command_list.size();
+}
+
+/*!
+ \since 5.12
+ \property QUndoStack::undoText
+ \brief the undo text of the next command that is undone.
+
+ This property holds the text of the command which will be undone in the
+ next call to undo().
+
+ \sa undoText(), QUndoCommand::actionText(), redoText()
+*/
+
+/*!
+ Returns the text of the command which will be undone in the next call to undo().
+
+ \sa QUndoCommand::actionText(), redoText()
+*/
+
+QString QUndoStack::undoText() const
+{
+ Q_D(const QUndoStack);
+ if (!d->macro_stack.isEmpty())
+ return QString();
+ if (d->index > 0)
+ return d->command_list.at(d->index - 1)->actionText();
+ return QString();
+}
+
+/*!
+ \since 5.12
+ \property QUndoStack::redoText
+ \brief the redo text of the next command that is redone.
+
+ This property holds the text of the command which will be redone in the
+ next call to redo().
+
+ \sa redoText(), QUndoCommand::actionText(), undoText()
+*/
+
+/*!
+ Returns the text of the command which will be redone in the next call to redo().
+
+ \sa QUndoCommand::actionText(), undoText()
+*/
+
+QString QUndoStack::redoText() const
+{
+ Q_D(const QUndoStack);
+ if (!d->macro_stack.isEmpty())
+ return QString();
+ if (d->index < d->command_list.size())
+ return d->command_list.at(d->index)->actionText();
+ return QString();
+}
+
+#ifndef QT_NO_ACTION
+
+/*!
+ \internal
+
+ Sets the text property of \a action to \a text, applying \a prefix, and falling back to \a defaultText if \a text is empty.
+*/
+void QUndoStackPrivate::setPrefixedText(QAction *action, const QString &prefix, const QString &defaultText, const QString &text)
+{
+ if (defaultText.isEmpty()) {
+ QString s = prefix;
+ if (!prefix.isEmpty() && !text.isEmpty())
+ s.append(u' ');
+ s.append(text);
+ action->setText(s);
+ } else {
+ if (text.isEmpty())
+ action->setText(defaultText);
+ else
+ action->setText(prefix.arg(text));
+ }
+};
+
+/*!
+ Creates an undo QAction object with the given \a parent.
+
+ Triggering this action will cause a call to undo(). The text of this action
+ is the text of the command which will be undone in the next call to undo(),
+ prefixed by the specified \a prefix. If there is no command available for undo,
+ this action will be disabled.
+
+ If \a prefix is empty, the default template "Undo %1" is used instead of prefix.
+ Before Qt 4.8, the prefix "Undo" was used by default.
+
+ \sa createRedoAction(), canUndo(), QUndoCommand::text()
+*/
+
+QAction *QUndoStack::createUndoAction(QObject *parent, const QString &prefix) const
+{
+ QAction *action = new QAction(parent);
+ action->setEnabled(canUndo());
+
+ QString effectivePrefix = prefix;
+ QString defaultText;
+ if (prefix.isEmpty()) {
+ effectivePrefix = tr("Undo %1");
+ defaultText = tr("Undo", "Default text for undo action");
+ }
+
+ QUndoStackPrivate::setPrefixedText(action, effectivePrefix, defaultText, undoText());
+
+ connect(this, &QUndoStack::canUndoChanged, action, &QAction::setEnabled);
+ connect(this, &QUndoStack::undoTextChanged, action, [=](const QString &text) {
+ QUndoStackPrivate::setPrefixedText(action, effectivePrefix, defaultText, text);
+ });
+ connect(action, &QAction::triggered, this, &QUndoStack::undo);
+
+ return action;
+}
+
+/*!
+ Creates an redo QAction object with the given \a parent.
+
+ Triggering this action will cause a call to redo(). The text of this action
+ is the text of the command which will be redone in the next call to redo(),
+ prefixed by the specified \a prefix. If there is no command available for redo,
+ this action will be disabled.
+
+ If \a prefix is empty, the default template "Redo %1" is used instead of prefix.
+ Before Qt 4.8, the prefix "Redo" was used by default.
+
+ \sa createUndoAction(), canRedo(), QUndoCommand::text()
+*/
+
+QAction *QUndoStack::createRedoAction(QObject *parent, const QString &prefix) const
+{
+ QAction *action = new QAction(parent);
+ action->setEnabled(canRedo());
+
+ QString effectivePrefix = prefix;
+ QString defaultText;
+ if (prefix.isEmpty()) {
+ effectivePrefix = tr("Redo %1");
+ defaultText = tr("Redo", "Default text for redo action");
+ }
+
+ QUndoStackPrivate::setPrefixedText(action, effectivePrefix, defaultText, redoText());
+
+ connect(this, &QUndoStack::canRedoChanged, action, &QAction::setEnabled);
+ connect(this, &QUndoStack::redoTextChanged, action, [=](const QString &text) {
+ QUndoStackPrivate::setPrefixedText(action, effectivePrefix, defaultText, text);
+ });
+ connect(action, &QAction::triggered, this, &QUndoStack::redo);
+
+ return action;
+}
+
+#endif // QT_NO_ACTION
+
+/*!
+ Begins composition of a macro command with the given \a text description.
+
+ An empty command described by the specified \a text is pushed on the stack.
+ Any subsequent commands pushed on the stack will be appended to the empty
+ command's children until endMacro() is called.
+
+ Calls to beginMacro() and endMacro() may be nested, but every call to
+ beginMacro() must have a matching call to endMacro().
+
+ While a macro is being composed, the stack is disabled. This means that:
+ \list
+ \li indexChanged() and cleanChanged() are not emitted,
+ \li canUndo() and canRedo() return false,
+ \li calling undo() or redo() has no effect,
+ \li the undo/redo actions are disabled.
+ \endlist
+
+ The stack becomes enabled and appropriate signals are emitted when endMacro()
+ is called for the outermost macro.
+
+ \snippet code/src_gui_util_qundostack.cpp 4
+
+ This code is equivalent to:
+
+ \snippet code/src_gui_util_qundostack.cpp 5
+
+ \sa endMacro()
+*/
+
+void QUndoStack::beginMacro(const QString &text)
+{
+ Q_D(QUndoStack);
+ QUndoCommand *cmd = new QUndoCommand();
+ cmd->setText(text);
+
+ if (d->macro_stack.isEmpty()) {
+ while (d->index < d->command_list.size())
+ delete d->command_list.takeLast();
+ if (d->clean_index > d->index)
+ d->clean_index = -1; // we've deleted the clean state
+ d->command_list.append(cmd);
+ } else {
+ d->macro_stack.constLast()->d->child_list.append(cmd);
+ }
+ d->macro_stack.append(cmd);
+
+ if (d->macro_stack.size() == 1) {
+ emit canUndoChanged(false);
+ emit undoTextChanged(QString());
+ emit canRedoChanged(false);
+ emit redoTextChanged(QString());
+ }
+}
+
+/*!
+ Ends composition of a macro command.
+
+ If this is the outermost macro in a set nested macros, this function emits
+ indexChanged() once for the entire macro command.
+
+ \sa beginMacro()
+*/
+
+void QUndoStack::endMacro()
+{
+ Q_D(QUndoStack);
+ if (Q_UNLIKELY(d->macro_stack.isEmpty())) {
+ qWarning("QUndoStack::endMacro(): no matching beginMacro()");
+ return;
+ }
+
+ d->macro_stack.removeLast();
+
+ if (d->macro_stack.isEmpty()) {
+ d->checkUndoLimit();
+ d->setIndex(d->index + 1, false);
+ }
+}
+
+/*!
+ \since 4.4
+
+ Returns a const pointer to the command at \a index.
+
+ This function returns a const pointer, because modifying a command,
+ once it has been pushed onto the stack and executed, almost always
+ causes corruption of the state of the document, if the command is
+ later undone or redone.
+
+ \sa QUndoCommand::child()
+*/
+const QUndoCommand *QUndoStack::command(int index) const
+{
+ Q_D(const QUndoStack);
+
+ if (index < 0 || index >= d->command_list.size())
+ return nullptr;
+ return d->command_list.at(index);
+}
+
+/*!
+ Returns the text of the command at index \a idx.
+
+ \sa beginMacro()
+*/
+
+QString QUndoStack::text(int idx) const
+{
+ Q_D(const QUndoStack);
+
+ if (idx < 0 || idx >= d->command_list.size())
+ return QString();
+ return d->command_list.at(idx)->text();
+}
+
+/*!
+ \property QUndoStack::undoLimit
+ \brief the maximum number of commands on this stack.
+ \since 4.3
+
+ When the number of commands on a stack exceedes the stack's undoLimit, commands are
+ deleted from the bottom of the stack. Macro commands (commands with child commands)
+ are treated as one command. The default value is 0, which means that there is no
+ limit.
+
+ This property may only be set when the undo stack is empty, since setting it on a
+ non-empty stack might delete the command at the current index. Calling setUndoLimit()
+ on a non-empty stack prints a warning and does nothing.
+*/
+
+void QUndoStack::setUndoLimit(int limit)
+{
+ Q_D(QUndoStack);
+
+ if (Q_UNLIKELY(!d->command_list.isEmpty())) {
+ qWarning("QUndoStack::setUndoLimit(): an undo limit can only be set when the stack is empty");
+ return;
+ }
+
+ if (limit == d->undo_limit)
+ return;
+ d->undo_limit = limit;
+ d->checkUndoLimit();
+}
+
+int QUndoStack::undoLimit() const
+{
+ Q_D(const QUndoStack);
+
+ return d->undo_limit;
+}
+
+/*!
+ \property QUndoStack::active
+ \brief the active status of this stack.
+
+ An application often has multiple undo stacks, one for each opened document. The active
+ stack is the one associated with the currently active document. If the stack belongs
+ to a QUndoGroup, calls to QUndoGroup::undo() or QUndoGroup::redo() will be forwarded
+ to this stack when it is active. If the QUndoGroup is watched by a QUndoView, the view
+ will display the contents of this stack when it is active. If the stack does not belong to
+ a QUndoGroup, making it active has no effect.
+
+ It is the programmer's responsibility to specify which stack is active by
+ calling setActive(), usually when the associated document window receives focus.
+
+ \sa QUndoGroup
+*/
+
+void QUndoStack::setActive(bool active)
+{
+#if !QT_CONFIG(undogroup)
+ Q_UNUSED(active);
+#else
+ Q_D(QUndoStack);
+
+ if (d->group != nullptr) {
+ if (active)
+ d->group->setActiveStack(this);
+ else if (d->group->activeStack() == this)
+ d->group->setActiveStack(nullptr);
+ }
+#endif
+}
+
+bool QUndoStack::isActive() const
+{
+#if !QT_CONFIG(undogroup)
+ return true;
+#else
+ Q_D(const QUndoStack);
+ return d->group == nullptr || d->group->activeStack() == this;
+#endif
+}
+
+/*!
+ \fn void QUndoStack::indexChanged(int idx)
+
+ This signal is emitted whenever a command modifies the state of the document.
+ This happens when a command is undone or redone. When a macro
+ command is undone or redone, or setIndex() is called, this signal
+ is emitted only once.
+
+ \a idx specifies the index of the current command, ie. the command which will be
+ executed on the next call to redo().
+
+ \sa index(), setIndex()
+*/
+
+/*!
+ \fn void QUndoStack::cleanChanged(bool clean)
+
+ This signal is emitted whenever the stack enters or leaves the clean state.
+ If \a clean is true, the stack is in a clean state; otherwise this signal
+ indicates that it has left the clean state.
+
+ \sa isClean(), setClean()
+*/
+
+/*!
+ \fn void QUndoStack::undoTextChanged(const QString &undoText)
+
+ This signal is emitted whenever the value of undoText() changes. It is
+ used to update the text property of the undo action returned by createUndoAction().
+ \a undoText specifies the new text.
+*/
+
+/*!
+ \fn void QUndoStack::canUndoChanged(bool canUndo)
+
+ This signal is emitted whenever the value of canUndo() changes. It is
+ used to enable or disable the undo action returned by createUndoAction().
+ \a canUndo specifies the new value.
+*/
+
+/*!
+ \fn void QUndoStack::redoTextChanged(const QString &redoText)
+
+ This signal is emitted whenever the value of redoText() changes. It is
+ used to update the text property of the redo action returned by createRedoAction().
+ \a redoText specifies the new text.
+*/
+
+/*!
+ \fn void QUndoStack::canRedoChanged(bool canRedo)
+
+ This signal is emitted whenever the value of canRedo() changes. It is
+ used to enable or disable the redo action returned by createRedoAction().
+ \a canRedo specifies the new value.
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qundostack.cpp"
+
+#endif // QT_CONFIG(undostack)
diff --git a/src/gui/util/qundostack.h b/src/gui/util/qundostack.h
new file mode 100644
index 0000000000..7b18485509
--- /dev/null
+++ b/src/gui/util/qundostack.h
@@ -0,0 +1,121 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QUNDOSTACK_H
+#define QUNDOSTACK_H
+
+#include <QtGui/qtguiglobal.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qstring.h>
+
+QT_REQUIRE_CONFIG(undocommand);
+
+QT_BEGIN_NAMESPACE
+
+class QAction;
+class QUndoCommandPrivate;
+class QUndoStackPrivate;
+
+class Q_GUI_EXPORT QUndoCommand
+{
+ QUndoCommandPrivate *d;
+
+public:
+ explicit QUndoCommand(QUndoCommand *parent = nullptr);
+ explicit QUndoCommand(const QString &text, QUndoCommand *parent = nullptr);
+ virtual ~QUndoCommand();
+
+ virtual void undo();
+ virtual void redo();
+
+ QString text() const;
+ QString actionText() const;
+ void setText(const QString &text);
+
+ bool isObsolete() const;
+ void setObsolete(bool obsolete);
+
+ virtual int id() const;
+ virtual bool mergeWith(const QUndoCommand *other);
+
+ int childCount() const;
+ const QUndoCommand *child(int index) const;
+
+private:
+ Q_DISABLE_COPY(QUndoCommand)
+ friend class QUndoStack;
+};
+
+#if QT_CONFIG(undostack)
+
+class Q_GUI_EXPORT QUndoStack : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QUndoStack)
+ Q_PROPERTY(bool active READ isActive WRITE setActive)
+ Q_PROPERTY(int undoLimit READ undoLimit WRITE setUndoLimit)
+ Q_PROPERTY(bool canUndo READ canUndo NOTIFY canUndoChanged)
+ Q_PROPERTY(bool canRedo READ canRedo NOTIFY canRedoChanged)
+ Q_PROPERTY(QString undoText READ undoText NOTIFY undoTextChanged)
+ Q_PROPERTY(QString redoText READ redoText NOTIFY redoTextChanged)
+ Q_PROPERTY(bool clean READ isClean NOTIFY cleanChanged)
+
+public:
+ explicit QUndoStack(QObject *parent = nullptr);
+ ~QUndoStack();
+ void clear();
+
+ void push(QUndoCommand *cmd);
+
+ bool canUndo() const;
+ bool canRedo() const;
+ QString undoText() const;
+ QString redoText() const;
+
+ int count() const;
+ int index() const;
+ QString text(int idx) const;
+
+#ifndef QT_NO_ACTION
+ QAction *createUndoAction(QObject *parent, const QString &prefix = QString()) const;
+ QAction *createRedoAction(QObject *parent, const QString &prefix = QString()) const;
+#endif // QT_NO_ACTION
+
+ bool isActive() const;
+ bool isClean() const;
+ int cleanIndex() const;
+
+ void beginMacro(const QString &text);
+ void endMacro();
+
+ void setUndoLimit(int limit);
+ int undoLimit() const;
+
+ const QUndoCommand *command(int index) const;
+
+public Q_SLOTS:
+ void setClean();
+ void resetClean();
+ void setIndex(int idx);
+ void undo();
+ void redo();
+ void setActive(bool active = true);
+
+Q_SIGNALS:
+ void indexChanged(int idx);
+ void cleanChanged(bool clean);
+ void canUndoChanged(bool canUndo);
+ void canRedoChanged(bool canRedo);
+ void undoTextChanged(const QString &undoText);
+ void redoTextChanged(const QString &redoText);
+
+private:
+ Q_DISABLE_COPY(QUndoStack)
+ friend class QUndoGroup;
+};
+
+#endif // QT_CONFIG(undostack)
+
+QT_END_NAMESPACE
+
+#endif // QUNDOSTACK_H
diff --git a/src/gui/util/qundostack_p.h b/src/gui/util/qundostack_p.h
new file mode 100644
index 0000000000..d655d5fdf5
--- /dev/null
+++ b/src/gui/util/qundostack_p.h
@@ -0,0 +1,68 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QUNDOSTACK_P_H
+#define QUNDOSTACK_P_H
+
+#include <QtGui/private/qtguiglobal_p.h>
+#include <private/qobject_p.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qstring.h>
+#if QT_CONFIG(action)
+# include <QtGui/qaction.h>
+#endif
+
+#include "qundostack.h"
+
+QT_BEGIN_NAMESPACE
+class QUndoCommand;
+class QUndoGroup;
+
+//
+// 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.
+//
+
+class QUndoCommandPrivate
+{
+public:
+ QUndoCommandPrivate() : id(-1), obsolete(false) {}
+ QList<QUndoCommand*> child_list;
+ QString text;
+ QString actionText;
+ int id;
+ bool obsolete;
+};
+
+#if QT_CONFIG(undostack)
+
+class QUndoStackPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QUndoStack)
+public:
+ QUndoStackPrivate() : index(0), clean_index(0), group(nullptr), undo_limit(0) {}
+
+ QList<QUndoCommand*> command_list;
+ QList<QUndoCommand*> macro_stack;
+ int index;
+ int clean_index;
+ QUndoGroup *group;
+ int undo_limit;
+
+ void setIndex(int idx, bool clean);
+ bool checkUndoLimit();
+
+#ifndef QT_NO_ACTION
+ static void setPrefixedText(QAction *action, const QString &prefix, const QString &defaultText, const QString &text);
+#endif
+};
+
+QT_END_NAMESPACE
+#endif // QT_CONFIG(undostack)
+#endif // QUNDOSTACK_P_H
diff --git a/src/gui/util/qvalidator.cpp b/src/gui/util/qvalidator.cpp
index 54cbb28ffa..2a81006657 100644
--- a/src/gui/util/qvalidator.cpp
+++ b/src/gui/util/qvalidator.cpp
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <qdebug.h>
@@ -58,7 +22,7 @@ QT_BEGIN_NAMESPACE
The class itself is abstract. Two subclasses, \l QIntValidator and
\l QDoubleValidator, provide basic numeric-range checking, and \l
- QRegExpValidator provides general checking using a custom regular
+ QRegularExpressionValidator provides general checking using a custom regular
expression.
If the built-in validators aren't sufficient, you can subclass
@@ -84,8 +48,8 @@ QT_BEGIN_NAMESPACE
\list
\li For a line edit that accepts integers from 10 to 1000 inclusive,
- 42 and 123 are \l Acceptable, the empty string and 5 are \l
- Intermediate, and "asdf" and 1114 is \l Invalid.
+ 42 and 123 are \l Acceptable, the empty string, 5, or 1234 are \l
+ Intermediate, and "asdf" and 10114 is \l Invalid.
\li For an editable combobox that accepts URLs, any well-formed URL
is \l Acceptable, "http://example.com/," is \l Intermediate
@@ -114,7 +78,7 @@ QT_BEGIN_NAMESPACE
QValidator is typically used with QLineEdit, QSpinBox and
QComboBox.
- \sa QIntValidator, QDoubleValidator, QRegExpValidator, {Line Edits Example}
+ \sa QIntValidator, QDoubleValidator, QRegularExpressionValidator, {Line Edits Example}
*/
@@ -192,13 +156,6 @@ QT_BEGIN_NAMESPACE
\internal
*/
-/*!
- \fn void QRegExpValidator::regExpChanged(const QRegExp &regExp)
-
- This signal is emitted after the regExp property changed.
- \internal
-*/
-
class QValidatorPrivate : public QObjectPrivate{
Q_DECLARE_PUBLIC(QValidator)
public:
@@ -328,7 +285,7 @@ void QValidator::fixup(QString &) const
is not set by default, the validator will accept group separators. It is thus
recommended to use QLocale::toInt() to obtain the numeric value.
- \sa QDoubleValidator, QRegExpValidator, QLocale::toInt(), {Line Edits Example}
+ \sa QDoubleValidator, QRegularExpressionValidator, QLocale::toInt(), {Line Edits Example}
*/
/*!
@@ -370,15 +327,20 @@ QIntValidator::~QIntValidator()
\fn QValidator::State QIntValidator::validate(QString &input, int &pos) const
Returns \l Acceptable if the \a input is an integer within the
- valid range, \l Intermediate if the \a input is a prefix of an integer in the
- valid range, and \l Invalid otherwise.
+ valid range. If \a input has at most as many digits as the top of the range,
+ or is a prefix of an integer in the valid range, returns \l Intermediate.
+ Otherwise, returns \l Invalid.
- If the valid range consists of just positive integers (e.g., 32 to 100)
- and \a input is a negative integer, then Invalid is returned. (On the other
- hand, if the range consists of negative integers (e.g., -100 to -32) and
- \a input is a positive integer, then Intermediate is returned, because
- the user might be just about to type the minus (especially for right-to-left
- languages).
+ If the valid range consists of just positive integers (e.g., 32 to 100) and
+ \a input is a negative integer, then Invalid is returned. (On the other
+ hand, if the range consists of negative integers (e.g., -100 to -32) and \a
+ input is a positive integer without leading plus sign, then Intermediate is
+ returned, because the user might be just about to type the minus (especially
+ for right-to-left languages).
+
+ Similarly, if the valid range is between 46 and 53, then 41 and 59 will be
+ evaluated as \l Intermediate, as otherwise the user wouldn't be able to
+ change a value from 49 to 51.
\snippet code/src_gui_util_qvalidator.cpp 2
@@ -400,34 +362,45 @@ static qlonglong pow10(int exp)
return result;
}
-QValidator::State QIntValidator::validate(QString & input, int&) const
+template <typename T> static inline
+std::optional<QValidator::State> initialResultCheck(T min, T max, const ParsingResult &result)
{
- QByteArray buff;
- if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff, -1,
- locale().numberOptions())) {
- return Invalid;
- }
+ if (result.state == ParsingResult::Invalid)
+ return QValidator::Invalid;
+ const CharBuff &buff = result.buff;
if (buff.isEmpty())
- return Intermediate;
+ return QValidator::Intermediate;
- const bool startsWithMinus(buff[0] == '-');
- if (b >= 0 && startsWithMinus)
- return Invalid;
+ char ch = buff[0];
+ const bool signConflicts = (min >= 0 && ch == '-') || (max < 0 && ch == '+');
+ if (signConflicts)
+ return QValidator::Invalid;
- const bool startsWithPlus(buff[0] == '+');
- if (t < 0 && startsWithPlus)
- return Invalid;
+ if (result.state == ParsingResult::Intermediate)
+ return QValidator::Intermediate;
- if (buff.size() == 1 && (startsWithPlus || startsWithMinus))
- return Intermediate;
+ return std::nullopt;
+}
- bool ok;
- qlonglong entered = QLocaleData::bytearrayToLongLong(buff.constData(), 10, &ok);
- if (!ok)
+QValidator::State QIntValidator::validate(QString & input, int&) const
+{
+ ParsingResult result =
+ locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, -1,
+ locale().numberOptions());
+
+ std::optional<State> opt = initialResultCheck(b, t, result);
+ if (opt)
+ return *opt;
+
+ const CharBuff &buff = result.buff;
+ QSimpleParsedNumber r = QLocaleData::bytearrayToLongLong(buff, 10);
+ if (!r.ok())
return Invalid;
+ qint64 entered = r.result;
if (entered >= b && entered <= t) {
+ bool ok = false;
locale().toInt(input, &ok);
return ok ? Acceptable : Intermediate;
}
@@ -439,7 +412,7 @@ QValidator::State QIntValidator::validate(QString & input, int&) const
// of a number of digits equal to or less than the max value as intermediate.
int buffLength = buff.size();
- if (startsWithPlus)
+ if (buff[0] == '+')
buffLength--;
const int tLength = t != 0 ? static_cast<int>(std::log10(qAbs(t))) + 1 : 1;
@@ -452,18 +425,16 @@ QValidator::State QIntValidator::validate(QString & input, int&) const
/*! \reimp */
void QIntValidator::fixup(QString &input) const
{
- QByteArray buff;
- if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff, -1,
- locale().numberOptions())) {
+ auto [parseState, buff] =
+ locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, -1,
+ locale().numberOptions());
+ if (parseState == ParsingResult::Invalid)
return;
- }
- bool ok;
- qlonglong entered = QLocaleData::bytearrayToLongLong(buff.constData(), 10, &ok);
- if (ok)
- input = locale().toString(entered);
-}
-// FIXME: Qt 6: Make QIntValidator::setRange() non-virtual
+ QSimpleParsedNumber r = QLocaleData::bytearrayToLongLong(buff, 10);
+ if (r.ok())
+ input = locale().toString(r.result);
+}
/*!
Sets the range of the validator to only accept integers between \a
@@ -495,7 +466,7 @@ void QIntValidator::setRange(int bottom, int top)
\brief the validator's lowest acceptable value
By default, this property's value is derived from the lowest signed
- integer available (typically -2147483647).
+ integer available (-2147483648).
\sa setRange()
*/
@@ -509,7 +480,7 @@ void QIntValidator::setBottom(int bottom)
\brief the validator's highest acceptable value
By default, this property's value is derived from the highest signed
- integer available (typically 2147483647).
+ integer available (2147483647).
\sa setRange()
*/
@@ -534,8 +505,6 @@ QValidator::QValidator(QValidatorPrivate &d, QObject *parent)
{
}
-#ifndef QT_NO_REGEXP
-
class QDoubleValidatorPrivate : public QValidatorPrivate
{
Q_DECLARE_PUBLIC(QDoubleValidator)
@@ -549,6 +518,8 @@ public:
QDoubleValidator::Notation notation;
QValidator::State validateWithLocale(QString & input, QLocaleData::NumberMode numMode, const QLocale &locale) const;
+ void fixupWithLocale(QString &input, QLocaleData::NumberMode numMode,
+ const QLocale &locale) const;
};
@@ -560,8 +531,7 @@ public:
\inmodule QtGui
QDoubleValidator provides an upper bound, a lower bound, and a
- limit on the number of digits after the decimal point. It does not
- provide a fixup() function.
+ limit on the number of digits after the decimal point.
You can set the acceptable range in one call with setRange(), or
with setBottom() and setTop(). Set the number of decimal places
@@ -572,12 +542,13 @@ public:
in the German locale, "1,234" will be accepted as the fractional number
1.234. In Arabic locales, QDoubleValidator will accept Arabic digits.
- \note The QLocale::NumberOptions set on the locale() also affect the
- way the number is interpreted. For example, since QLocale::RejectGroupSeparator
- is not set by default, the validator will accept group separators. It is thus
- recommended to use QLocale::toDouble() to obtain the numeric value.
+ \note The QLocale::NumberOptions set on the locale() also affect the way the
+ number is interpreted. For example, since QLocale::RejectGroupSeparator is
+ not set by default (except on the \c "C" locale), the validator will accept
+ group separators. If the string passes validation, pass it to
+ locale().toDouble() to obtain its numeric value.
- \sa QIntValidator, QRegExpValidator, QLocale::toDouble(), {Line Edits Example}
+ \sa QIntValidator, QRegularExpressionValidator, QLocale::toDouble(), {Line Edits Example}
*/
/*!
@@ -585,10 +556,23 @@ public:
\since 4.3
This enum defines the allowed notations for entering a double.
- \value StandardNotation The string is written as a standard number
- (i.e. 0.015).
- \value ScientificNotation The string is written in scientific
- form. It may have an exponent part(i.e. 1.5E-2).
+ \value StandardNotation The string is written in the standard format, a
+ whole number part optionally followed by a separator
+ and fractional part, for example \c{"0.015"}.
+
+ \value ScientificNotation The string is written in scientific form, which
+ optionally appends an exponent part to the
+ standard format, for example \c{"1.5E-2"}.
+
+ The whole number part may, as usual, include a sign. This, along with the
+ separators for fractional part, exponent and any digit-grouping, depend on
+ locale. QDoubleValidator doesn't check the placement (which would also
+ depend on locale) of any digit-grouping separators it finds, but it will
+ reject input that contains them if \l QLocale::RejectGroupSeparator is set
+ in \c locale().numberOptions().
+
+ \sa QLocale::numberOptions(), QLocale::decimalPoint(),
+ QLocale::exponential(), QLocale::negativeSign()
*/
/*!
@@ -596,8 +580,8 @@ public:
that accepts any double.
*/
-QDoubleValidator::QDoubleValidator(QObject * parent)
- : QDoubleValidator(-HUGE_VAL, HUGE_VAL, 1000, parent)
+QDoubleValidator::QDoubleValidator(QObject *parent)
+ : QDoubleValidator(-HUGE_VAL, HUGE_VAL, -1, parent)
{
}
@@ -630,14 +614,14 @@ QDoubleValidator::~QDoubleValidator()
/*!
\fn QValidator::State QDoubleValidator::validate(QString &input, int &pos) const
- Returns \l Acceptable if the string \a input contains a double
- that is within the valid range and is in the correct format.
+ Returns \l Acceptable if the string \a input is in the correct format and
+ contains a double within the valid range.
- Returns \l Intermediate if \a input contains a double that is
- outside the range or is in the wrong format; e.g. is empty.
+ Returns \l Intermediate if \a input is in the wrong format or contains a
+ double outside the range.
- Returns \l Invalid if the \a input is not a double or with too many
- digits after the decimal point.
+ Returns \l Invalid if the \a input doesn't represent a double or has too
+ many digits after the decimal point.
Note: If the valid range consists of just positive doubles (e.g. 0.0 to 100.0)
and \a input is a negative double then \l Invalid is returned. If notation()
@@ -673,24 +657,16 @@ QValidator::State QDoubleValidator::validate(QString & input, int &) const
QValidator::State QDoubleValidatorPrivate::validateWithLocale(QString &input, QLocaleData::NumberMode numMode, const QLocale &locale) const
{
Q_Q(const QDoubleValidator);
- QByteArray buff;
- if (!locale.d->m_data->validateChars(input, numMode, &buff, q->dec, locale.numberOptions())) {
- return QValidator::Invalid;
- }
+ ParsingResult result =
+ locale.d->m_data->validateChars(input, numMode, q->dec, locale.numberOptions());
- if (buff.isEmpty())
- return QValidator::Intermediate;
-
- if (q->b >= 0 && buff.startsWith('-'))
- return QValidator::Invalid;
-
- if (q->t < 0 && buff.startsWith('+'))
- return QValidator::Invalid;
+ std::optional<QValidator::State> opt = initialResultCheck(q->b, q->t, result);
+ if (opt)
+ return *opt;
bool ok = false;
double i = locale.toDouble(input, &ok); // returns 0.0 if !ok
- if (i == qt_qnan())
- return QValidator::Invalid;
+ Q_ASSERT(!qIsNaN(i)); // Would be caught by validateChars()
if (!ok)
return QValidator::Intermediate;
@@ -699,8 +675,13 @@ QValidator::State QDoubleValidatorPrivate::validateWithLocale(QString &input, QL
if (notation == QDoubleValidator::StandardNotation) {
double max = qMax(qAbs(q->b), qAbs(q->t));
- if (max < LLONG_MAX) {
- qlonglong n = pow10(numDigits(qlonglong(max)));
+ qlonglong v;
+ // Need a whole number to pass to convertDoubleTo() or it fails. Use
+ // floor, as max is positive so this has the same number of digits
+ // before the decimal point, where qCeil() might take us up to a power
+ // of ten, adding a digit.
+ if (convertDoubleTo(qFloor(max), &v)) {
+ qlonglong n = pow10(numDigits(v));
// In order to get the highest possible number in the intermediate
// range we need to get 10 to the power of the number of digits
// after the decimal's and subtract that from the top number.
@@ -717,12 +698,99 @@ QValidator::State QDoubleValidatorPrivate::validateWithLocale(QString &input, QL
return QValidator::Intermediate;
}
-// FIXME: Qt 6: Make QDoubleValidator::setRange() non-virtual
+/*!
+ \since 6.3
+ \overload
+
+ Attempts to fix the \a input string to an \l Acceptable representation of a
+ double.
+
+ The format of the number is determined by \l notation(), \l decimals(),
+ \l locale() and the latter's \l {QLocale::}{numberOptions()}.
+
+ To comply with \l notation(), when \l ScientificNotation is used, the fixed
+ value will be represented in its normalized form, which means that any
+ non-zero value will have one non-zero digit before the decimal point.
+
+ \snippet code/src_gui_util_qvalidator.cpp 7
+
+ To comply with \l decimals(), when it is \c {-1} the number of digits used
+ will be determined by \l QLocale::FloatingPointShortest. Otherwise, the
+ fractional part of the number is truncated (with rounding, as appropriate)
+ if its length exceeds \l decimals(). When \l notation() is
+ \l ScientificNotation this is done after the number has been put into its
+ normalized form.
+
+ \snippet code/src_gui_util_qvalidator.cpp 8
+
+ \note If \l decimals() is set to, and the string provides, more than
+ \c {std::numeric_limits<double>::digits10}, digits beyond that many in the
+ fractional part may be changed. The resulting string shall encode the same
+ floating-point number, when parsed to a \c double.
+*/
+void QDoubleValidator::fixup(QString &input) const
+{
+ Q_D(const QDoubleValidator);
+ const auto numberMode = d->notation == StandardNotation ? QLocaleData::DoubleStandardMode
+ : QLocaleData::DoubleScientificMode;
+
+ d->fixupWithLocale(input, numberMode, locale());
+}
+
+void QDoubleValidatorPrivate::fixupWithLocale(QString &input, QLocaleData::NumberMode numMode,
+ const QLocale &locale) const
+{
+ Q_Q(const QDoubleValidator);
+ // Passing -1 as the number of decimals, because fixup() exists to improve
+ // an Intermediate value, if it can.
+ auto [parseState, buff] =
+ locale.d->m_data->validateChars(input, numMode, -1, locale.numberOptions());
+ if (parseState == ParsingResult::Invalid)
+ return;
+
+ // buff contains data in C locale.
+ bool ok = false;
+ const double entered = QByteArrayView(buff).toDouble(&ok);
+ if (ok) {
+ // Here we need to adjust the output format accordingly
+ char mode;
+ if (numMode == QLocaleData::DoubleStandardMode) {
+ mode = 'f';
+ } else {
+ // scientific mode can be either 'e' or 'E'
+ mode = input.contains(QChar::fromLatin1('E')) ? 'E' : 'e';
+ }
+ int precision;
+ if (q->dec < 0) {
+ precision = QLocale::FloatingPointShortest;
+ } else {
+ if (mode == 'f') {
+ const auto decimalPointIndex = buff.indexOf('.');
+ precision = decimalPointIndex >= 0 ? buff.size() - decimalPointIndex - 1 : 0;
+ } else {
+ auto eIndex = buff.indexOf('e');
+ // No need to check for 'E' because we can get only 'e' after a
+ // call to validateChars()
+ if (eIndex < 0)
+ eIndex = buff.size();
+ precision = eIndex - (buff.contains('.') ? 1 : 0)
+ - (buff[0] == '-' || buff[0] == '+' ? 1 : 0);
+ }
+ // Use q->dec to limit the number of decimals, because we want the
+ // fixup() result to pass validate().
+ precision = qMin(precision, q->dec);
+ }
+ input = locale.toString(entered, mode, precision);
+ }
+}
/*!
Sets the validator to accept doubles from \a minimum to \a maximum
inclusive, with at most \a decimals digits after the decimal
point.
+
+ \note Setting the number of decimals to -1 effectively sets it to unlimited.
+ This is also the value used by a default-constructed validator.
*/
void QDoubleValidator::setRange(double minimum, double maximum, int decimals)
@@ -750,6 +818,17 @@ void QDoubleValidator::setRange(double minimum, double maximum, int decimals)
}
/*!
+ \overload
+
+ Sets the validator to accept doubles from \a minimum to \a maximum
+ inclusive without changing the number of digits after the decimal point.
+*/
+void QDoubleValidator::setRange(double minimum, double maximum)
+{
+ setRange(minimum, maximum, decimals());
+}
+
+/*!
\property QDoubleValidator::bottom
\brief the validator's minimum acceptable value
@@ -782,7 +861,8 @@ void QDoubleValidator::setTop(double top)
\property QDoubleValidator::decimals
\brief the validator's maximum number of digits after the decimal point
- By default, this property contains a value of 1000.
+ By default, this property contains a value of -1, which means any number
+ of digits is accepted.
\sa setRange()
*/
@@ -818,126 +898,11 @@ QDoubleValidator::Notation QDoubleValidator::notation() const
return d->notation;
}
-/*!
- \class QRegExpValidator
- \brief The QRegExpValidator class is used to check a string
- against a regular expression.
- \inmodule QtGui
-
- QRegExpValidator uses a regular expression (regexp) to
- determine whether an input string is \l Acceptable, \l
- Intermediate, or \l Invalid. The regexp can either be supplied
- when the QRegExpValidator is constructed, or at a later time.
-
- When QRegExpValidator determines whether a string is \l Acceptable
- or not, the regexp is treated as if it begins with the start of string
- assertion (\b{^}) and ends with the end of string assertion
- (\b{$}); the match is against the entire input string, or from
- the given position if a start position greater than zero is given.
-
- If a string is a prefix of an \l Acceptable string, it is considered
- \l Intermediate. For example, "" and "A" are \l Intermediate for the
- regexp \b{[A-Z][0-9]} (whereas "_" would be \l Invalid).
-
- For a brief introduction to Qt's regexp engine, see \l QRegExp.
-
- Example of use:
- \snippet code/src_gui_util_qvalidator.cpp 3
-
- Below we present some examples of validators. In practice they would
- normally be associated with a widget as in the example above.
-
- \snippet code/src_gui_util_qvalidator.cpp 4
-
- \sa QRegExp, QIntValidator, QDoubleValidator, {Settings Editor Example}
-*/
-
-/*!
- Constructs a validator with a \a parent object that accepts
- any string (including an empty one) as valid.
-*/
-
-QRegExpValidator::QRegExpValidator(QObject *parent)
- : QRegExpValidator(QRegExp(QString::fromLatin1(".*")), parent)
-{
-}
-
-/*!
- Constructs a validator with a \a parent object that
- accepts all strings that match the regular expression \a rx.
-
- The match is made against the entire string; e.g. if the regexp is
- \b{[A-Fa-f0-9]+} it will be treated as \b{^[A-Fa-f0-9]+$}.
-*/
-
-QRegExpValidator::QRegExpValidator(const QRegExp& rx, QObject *parent)
- : QValidator(parent), r(rx)
-{
-}
-
-
-/*!
- Destroys the validator.
-*/
-
-QRegExpValidator::~QRegExpValidator()
-{
-}
-
-/*!
- Returns \l Acceptable if \a input is matched by the regular
- expression for this validator, \l Intermediate if it has matched
- partially (i.e. could be a valid match if additional valid
- characters are added), and \l Invalid if \a input is not matched.
-
- Additionally, if \a input is not matched, the \a pos parameter is set to
- the length of the \a input parameter.
-
- For example, if the regular expression is \b{\\w\\d\\d}
- (word-character, digit, digit) then "A57" is \l Acceptable,
- "E5" is \l Intermediate, and "+9" is \l Invalid.
-
- \sa QRegExp::exactMatch()
-*/
-
-QValidator::State QRegExpValidator::validate(QString &input, int& pos) const
-{
- QRegExp copy = r;
- if (copy.exactMatch(input)) {
- return Acceptable;
- } else {
- if (copy.matchedLength() == input.size()) {
- return Intermediate;
- } else {
- pos = input.size();
- return Invalid;
- }
- }
-}
-
-/*!
- \property QRegExpValidator::regExp
- \brief the regular expression used for validation
-
- By default, this property contains a regular expression with the pattern \c{.*}
- that matches any string.
-*/
-
-void QRegExpValidator::setRegExp(const QRegExp& rx)
-{
- if (r != rx) {
- r = rx;
- emit regExpChanged(r);
- emit changed();
- }
-}
-
-#endif
-
#if QT_CONFIG(regularexpression)
/*!
\class QRegularExpressionValidator
+ \inmodule QtGui
\brief The QRegularExpressionValidator class is used to check a string
against a regular expression.
@@ -964,7 +929,7 @@ void QRegExpValidator::setRegExp(const QRegExp& rx)
\snippet code/src_gui_util_qvalidator.cpp 6
- \sa QRegularExpression, QIntValidator, QDoubleValidator, QRegExpValidator
+ \sa QRegularExpression, QIntValidator, QDoubleValidator
*/
class QRegularExpressionValidatorPrivate : public QValidatorPrivate
@@ -1089,4 +1054,6 @@ void QRegularExpressionValidatorPrivate::setRegularExpression(const QRegularExpr
QT_END_NAMESPACE
+#include "moc_qvalidator.cpp"
+
#endif // QT_NO_VALIDATOR
diff --git a/src/gui/util/qvalidator.h b/src/gui/util/qvalidator.h
index f0e72e3814..cd757c612d 100644
--- a/src/gui/util/qvalidator.h
+++ b/src/gui/util/qvalidator.h
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QVALIDATOR_H
#define QVALIDATOR_H
@@ -44,7 +8,6 @@
#include <QtGui/qtguiglobal.h>
#include <QtCore/qobject.h>
#include <QtCore/qstring.h>
-#include <QtCore/qregexp.h>
#if QT_CONFIG(regularexpression)
# include <QtCore/qregularexpression.h>
#endif
@@ -105,7 +68,7 @@ public:
void setBottom(int);
void setTop(int);
- virtual void setRange(int bottom, int top);
+ void setRange(int bottom, int top);
int bottom() const { return b; }
int top() const { return t; }
@@ -120,8 +83,6 @@ private:
int t;
};
-#ifndef QT_NO_REGEXP
-
class QDoubleValidatorPrivate;
class Q_GUI_EXPORT QDoubleValidator : public QValidator
@@ -143,8 +104,10 @@ public:
};
Q_ENUM(Notation)
QValidator::State validate(QString &, int &) const override;
+ void fixup(QString &input) const override;
- virtual void setRange(double bottom, double top, int decimals = 0);
+ void setRange(double bottom, double top, int decimals);
+ void setRange(double bottom, double top);
void setBottom(double);
void setTop(double);
void setDecimals(int);
@@ -170,33 +133,6 @@ private:
int dec;
};
-
-class Q_GUI_EXPORT QRegExpValidator : public QValidator
-{
- Q_OBJECT
- Q_PROPERTY(QRegExp regExp READ regExp WRITE setRegExp NOTIFY regExpChanged)
-
-public:
- explicit QRegExpValidator(QObject *parent = nullptr);
- explicit QRegExpValidator(const QRegExp& rx, QObject *parent = nullptr);
- ~QRegExpValidator();
-
- virtual QValidator::State validate(QString& input, int& pos) const override;
-
- void setRegExp(const QRegExp& rx);
- const QRegExp& regExp() const { return r; }
-
-Q_SIGNALS:
- void regExpChanged(const QRegExp& regExp);
-
-private:
- Q_DISABLE_COPY(QRegExpValidator)
-
- QRegExp r;
-};
-
-#endif // QT_NO_REGEXP
-
#if QT_CONFIG(regularexpression)
class QRegularExpressionValidatorPrivate;
@@ -211,7 +147,7 @@ public:
explicit QRegularExpressionValidator(const QRegularExpression &re, QObject *parent = nullptr);
~QRegularExpressionValidator();
- virtual QValidator::State validate(QString &input, int &pos) const override;
+ QValidator::State validate(QString &input, int &pos) const override;
QRegularExpression regularExpression() const;
diff --git a/src/gui/util/util.pri b/src/gui/util/util.pri
deleted file mode 100644
index d3402133d6..0000000000
--- a/src/gui/util/util.pri
+++ /dev/null
@@ -1,48 +0,0 @@
-# Qt util module
-
-HEADERS += \
- util/qdesktopservices.h \
- util/qhexstring_p.h \
- util/qvalidator.h \
- util/qgridlayoutengine_p.h \
- util/qabstractlayoutstyleinfo_p.h \
- util/qlayoutpolicy_p.h \
- util/qshaderformat_p.h \
- util/qshadergraph_p.h \
- util/qshadergraphloader_p.h \
- util/qshaderlanguage_p.h \
- util/qshadernode_p.h \
- util/qshadernodeport_p.h \
- util/qshadernodesloader_p.h \
- util/qtexturefiledata_p.h \
- util/qtexturefilereader_p.h \
- util/qtexturefilehandler_p.h \
- util/qpkmhandler_p.h \
- util/qktxhandler_p.h \
- util/qastchandler_p.h
-
-SOURCES += \
- util/qdesktopservices.cpp \
- util/qvalidator.cpp \
- util/qgridlayoutengine.cpp \
- util/qabstractlayoutstyleinfo.cpp \
- util/qlayoutpolicy.cpp \
- util/qshaderformat.cpp \
- util/qshadergraph.cpp \
- util/qshadergraphloader.cpp \
- util/qshaderlanguage.cpp \
- util/qshadernode.cpp \
- util/qshadernodeport.cpp \
- util/qshadernodesloader.cpp \
- util/qtexturefiledata.cpp \
- util/qtexturefilereader.cpp \
- util/qpkmhandler.cpp \
- util/qktxhandler.cpp \
- util/qastchandler.cpp
-
-qtConfig(regularexpression) {
- HEADERS += \
- util/qshadergenerator_p.h
- SOURCES += \
- util/qshadergenerator.cpp
-}