From 8635ad1b59d49dfdc20132d5d12dbd7e6e478214 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 17 Jan 2018 09:02:29 +0100 Subject: psql: Add expected failures where the table name is case sensitive Currently there is a bug in Qt regarding the PostgreSQL driver as it does not correctly escape the table names when constructing queries internally. Therefore, these tests are marked as expected failures until the bug itself is fixed in Qt. Change-Id: I74dadc187f8a08509128dfea27be99787e57ea51 Reviewed-by: Edward Welbourne --- tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp | 5 +++-- .../qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp | 2 ++ tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp | 11 +++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index aba99a9e20..a51865897f 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -2711,10 +2711,9 @@ void tst_QSqlQuery::lastInsertId() QSqlQuery q( db ); - const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db); // PostgreSQL >= 8.1 relies on lastval() which does not work if a value is // manually inserted to the serial field, so we create a table specifically - if (dbType == QSqlDriver::PostgreSQL) { + if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL) { const auto tst_lastInsertId = qTableName("tst_lastInsertId", __FILE__, db); tst_Databases::safeDropTable(db, tst_lastInsertId); QVERIFY_SQL(q, exec(QStringLiteral("create table ") + tst_lastInsertId + @@ -3681,6 +3680,8 @@ void tst_QSqlQuery::QTBUG_5251() QSqlTableModel timetestModel(0,db); timetestModel.setEditStrategy(QSqlTableModel::OnManualSubmit); timetestModel.setTable(timetest); + if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL) + QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort); QVERIFY_SQL(timetestModel, select()); QCOMPARE(timetestModel.record(0).field(0).value().toTime().toString("HH:mm:ss.zzz"), QString("01:02:03.666")); diff --git a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp index f1c55df1ef..e4a277e096 100644 --- a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp +++ b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp @@ -1547,6 +1547,8 @@ void tst_QSqlRelationalTableModel::relationOnFirstColumn() //modify the model data QVERIFY_SQL(model, setData(model.index(0, 0), 40)); + if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL) + QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort); QVERIFY_SQL(model, submit()); QVERIFY_SQL(model, setData(model.index(1, 0), 50)); QVERIFY_SQL(model, submit()); diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp index ded360ef8d..430fa981d5 100644 --- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp @@ -360,6 +360,8 @@ void tst_QSqlTableModel::selectRow() q.exec("UPDATE " + tbl + " SET a = 'Qt' WHERE id = 1"); QCOMPARE(model.data(idx).toString(), QString("b")); model.selectRow(1); + if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL) + QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort); QCOMPARE(model.data(idx).toString(), QString("Qt")); // Check if selectRow() refreshes a changed row. @@ -416,6 +418,8 @@ void tst_QSqlTableModel::selectRowOverride() // both rows should have changed QCOMPARE(model.data(idx).toString(), QString("Qt")); idx = model.index(2, 1); + if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL) + QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort); QCOMPARE(model.data(idx).toString(), QString("Qt")); q.exec("DELETE FROM " + tbl); @@ -826,6 +830,9 @@ void tst_QSqlTableModel::insertRowFailure() values.setGenerated(1, true); // populate 1 row + const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriver::PostgreSQL && submitpolicy != QSqlTableModel::OnManualSubmit) + QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort); QVERIFY_SQL(model, insertRecord(0, values)); QVERIFY_SQL(model, submitAll()); QVERIFY_SQL(model, select()); @@ -869,6 +876,8 @@ void tst_QSqlTableModel::insertRowFailure() // restore empty table model.revertAll(); QVERIFY_SQL(model, removeRow(0)); + if (dbType == QSqlDriver::PostgreSQL) + QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort); QVERIFY_SQL(model, submitAll()); QVERIFY_SQL(model, select()); QCOMPARE(model.rowCount(), 0); @@ -1977,6 +1986,8 @@ void tst_QSqlTableModel::tableModifyWithBlank() //Should be equivalent to QSqlQuery INSERT INTO... command) QVERIFY_SQL(model, insertRow(0)); QVERIFY_SQL(model, setData(model.index(0,0),timeString)); + if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL) + QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort); QVERIFY_SQL(model, submitAll()); //set a filter on the table so the only record we get is the one we just made -- cgit v1.2.3 From 89053e224f296a19c107ea7925539d5125dac5c0 Mon Sep 17 00:00:00 2001 From: Jani Heikkinen Date: Tue, 6 Feb 2018 08:50:43 +0200 Subject: Bump copyright year Task-number: QTBUG-65810 Change-Id: Ib6f87a126f64c2e4b2e924b97af4c2b2d10dd29e Reviewed-by: Friedemann Kleint --- src/widgets/dialogs/qmessagebox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index cb8ac1ccbf..52ca88891e 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -1836,7 +1836,7 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title) "

Qt and the Qt logo are trademarks of The Qt Company Ltd.

" "

Qt is The Qt Company Ltd product developed as an open source " "project. See %3 for more information.

" - ).arg(QStringLiteral("2017"), + ).arg(QStringLiteral("2018"), QStringLiteral("qt.io/licensing"), QStringLiteral("qt.io")); QMessageBox *msgBox = new QMessageBox(parent); -- cgit v1.2.3 From 27b8e97e4f478211b0da7b4352f0ce3f4557ce12 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 21 Feb 2018 10:37:18 +0100 Subject: Windows QPA: Fix accessibility being triggered by IME Add missing break. Change-Id: Ib17e348e64379abded41f6c044de59f9ee1dd8fc Reviewed-by: Alexandru Croitor --- src/plugins/platforms/windows/qtwindowsglobal.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h index c8bdc1c93e..6c44541314 100644 --- a/src/plugins/platforms/windows/qtwindowsglobal.h +++ b/src/plugins/platforms/windows/qtwindowsglobal.h @@ -237,6 +237,7 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI default: break; } + break; case WM_GETOBJECT: return QtWindows::AccessibleObjectFromWindowRequest; case WM_SETFOCUS: -- cgit v1.2.3 From 1d6d1e680ee1bb6f90328e74ce5e11f8ecb0217e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 21 Feb 2018 11:12:04 +0100 Subject: Fix some qdoc-warnings for 5.11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename example savegame and its snippets following a6b697ca13945a174cff9f3e9b1af1cf61c0bea5. Fix: /qtbase/examples/corelib/serialization/savegame/doc/src/savegame.qdoc:28: warning: Cannot find file 'json/savegame/savegame.pro' or 'json/savegame/savegame.qmlproject' qtbase/examples/corelib/serialization/savegame/doc/src/savegame.qdoc:98: (qdoc) warning: Cannot find file to quote from: 'json/savegame/level.cpp' json qtbase/src/network/ssl/qsslconfiguration.cpp:889: warning: Undocumented parameter 'name' in QSslConfiguration::setBackendConfigOption() qtbase/src/corelib/tools/qbitarray.cpp:314: warning: No such parameter 'len' in QBitArray::fromBits() Change-Id: If59512873ca2116b89490927fdbf9ea1d8b237a8 Reviewed-by: Topi Reiniö Reviewed-by: Martin Smith --- .../serialization/savegame/doc/src/savegame.qdoc | 30 +++++++++++----------- src/corelib/tools/qbitarray.cpp | 2 +- src/network/ssl/qsslconfiguration.cpp | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/examples/corelib/serialization/savegame/doc/src/savegame.qdoc b/examples/corelib/serialization/savegame/doc/src/savegame.qdoc index 06e70680c6..a35f763430 100644 --- a/examples/corelib/serialization/savegame/doc/src/savegame.qdoc +++ b/examples/corelib/serialization/savegame/doc/src/savegame.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! - \example json/savegame + \example serialization/savegame \title JSON Save Game Example \brief The JSON Save Game example demonstrates how to save and load a @@ -50,12 +50,12 @@ It provides read() and write() functions to serialise its member variables. - \snippet json/savegame/character.h 0 + \snippet serialization/savegame/character.h 0 Of particular interest to us are the read and write function implementations: - \snippet json/savegame/character.cpp 0 + \snippet serialization/savegame/character.cpp 0 In the read() function, we assign Character's members values from the QJsonObject argument. You can use either \l QJsonObject::operator[]() or @@ -64,7 +64,7 @@ check if the keys are valid before attempting to read them with QJsonObject::contains(). - \snippet json/savegame/character.cpp 1 + \snippet serialization/savegame/character.cpp 1 In the write() function, we do the reverse of the read() function; assign values from the Character object to the JSON object. As with accessing @@ -74,13 +74,13 @@ Next up is the Level class: - \snippet json/savegame/level.h 0 + \snippet serialization/savegame/level.h 0 We want to have several levels in our game, each with several NPCs, so we keep a QVector of Character objects. We also provide the familiar read() and write() functions. - \snippet json/savegame/level.cpp 0 + \snippet serialization/savegame/level.cpp 0 Containers can be written and read to and from JSON using QJsonArray. In our case, we construct a QJsonArray from the value associated with the key @@ -94,7 +94,7 @@ element is used as the key to construct the container when reading it back in. - \snippet json/savegame/level.cpp 1 + \snippet serialization/savegame/level.cpp 1 Again, the write() function is similar to the read() function, except reversed. @@ -102,7 +102,7 @@ Having established the Character and Level classes, we can move on to the Game class: - \snippet json/savegame/game.h 0 + \snippet serialization/savegame/game.h 0 First of all, we define the \c SaveFormat enum. This will allow us to specify the format in which the game should be saved: \c Json or \c Binary. @@ -112,12 +112,12 @@ The read() and write() functions are used by saveGame() and loadGame(). - \snippet json/savegame/game.cpp 0 + \snippet serialization/savegame/game.cpp 0 To setup a new game, we create the player and populate the levels and their NPCs. - \snippet json/savegame/game.cpp 1 + \snippet serialization/savegame/game.cpp 1 The first thing we do in the read() function is tell the player to read itself. We then clear the level array so that calling loadGame() on the @@ -125,11 +125,11 @@ We then populate the level array by reading each Level from a QJsonArray. - \snippet json/savegame/game.cpp 2 + \snippet serialization/savegame/game.cpp 2 We write the game to JSON similarly to how we write Level. - \snippet json/savegame/game.cpp 3 + \snippet serialization/savegame/game.cpp 3 When loading a saved game in loadGame(), the first thing we do is open the save file based on which format it was saved to; \c "save.json" for JSON, @@ -144,7 +144,7 @@ After constructing the QJsonDocument, we instruct the Game object to read itself and then return \c true to indicate success. - \snippet json/savegame/game.cpp 4 + \snippet serialization/savegame/game.cpp 4 Not surprisingly, saveGame() looks very much like loadGame(). We determine the file extension based on the format, print a warning and return \c false @@ -155,7 +155,7 @@ We are now ready to enter main(): - \snippet json/savegame/main.cpp 0 + \snippet serialization/savegame/main.cpp 0 Since we're only interested in demonstrating \e serialization of a game with JSON, our game is not actually playable. Therefore, we only need @@ -169,7 +169,7 @@ assume that the player had a great time and made lots of progress, altering the internal state of our Character, Level and Game objects. - \snippet json/savegame/main.cpp 1 + \snippet serialization/savegame/main.cpp 1 When the player has finished, we save their game. For demonstration purposes, we can serialize to either JSON or binary. You can examine the diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp index f68a807203..4e8e3c241e 100644 --- a/src/corelib/tools/qbitarray.cpp +++ b/src/corelib/tools/qbitarray.cpp @@ -315,7 +315,7 @@ void QBitArray::fill(bool value, int begin, int end) \since 5.11 Creates a QBitArray with the dense bit array located at \a data, with \a - len bits. The byte array at \a data must be at least \a size / 8 (rounded up) + size bits. The byte array at \a data must be at least \a size / 8 (rounded up) bytes long. If \a size is not a multiple of 8, this function will include the lowest diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp index cbbbac85fe..e0c705f97e 100644 --- a/src/network/ssl/qsslconfiguration.cpp +++ b/src/network/ssl/qsslconfiguration.cpp @@ -889,7 +889,7 @@ QMap QSslConfiguration::backendConfig() const /*! \since 5.11 - Sets an option in the backend-specific configuration. + Sets the option \a name in the backend-specific configuration to \a value. Options supported by the OpenSSL (>= 1.0.2) backend are available in the \l {https://www.openssl.org/docs/manmaster/man3/SSL_CONF_cmd.html#SUPPORTED-CONFIGURATION-FILE-COMMANDS} -- cgit v1.2.3 From c9c9adeef943d8265b2dae57ff48992c23b6725a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 21 Feb 2018 11:24:27 +0100 Subject: Remove left over json/qjsonarray.cpp Complements a6b697ca13945a174cff9f3e9b1af1cf61c0bea5. Change-Id: I96697624aa65a5a45ce91ceaf0e156fd112a8ed0 Reviewed-by: Thiago Macieira --- src/corelib/json/qjsonarray.cpp | 1238 --------------------------------------- 1 file changed, 1238 deletions(-) delete mode 100644 src/corelib/json/qjsonarray.cpp diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp deleted file mode 100644 index 255dc2ee4e..0000000000 --- a/src/corelib/json/qjsonarray.cpp +++ /dev/null @@ -1,1238 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore 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 -#include -#include -#include -#include -#include - -#include "qjsonwriter_p.h" -#include "qjson_p.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QJsonArray - \inmodule QtCore - \ingroup json - \ingroup shared - \reentrant - \since 5.0 - - \brief The QJsonArray class encapsulates a JSON array. - - A JSON array is a list of values. The list can be manipulated by inserting and - removing QJsonValue's from the array. - - A QJsonArray can be converted to and from a QVariantList. You can query the - number of entries with size(), insert(), and removeAt() entries from it - and iterate over its content using the standard C++ iterator pattern. - - QJsonArray is an implicitly shared class and shares the data with the document - it has been created from as long as it is not being modified. - - You can convert the array to and from text based JSON through QJsonDocument. - - \sa {JSON Support in Qt}, {JSON Save Game Example} -*/ - -/*! - \typedef QJsonArray::Iterator - - Qt-style synonym for QJsonArray::iterator. -*/ - -/*! - \typedef QJsonArray::ConstIterator - - Qt-style synonym for QJsonArray::const_iterator. -*/ - -/*! - \typedef QJsonArray::size_type - - Typedef for int. Provided for STL compatibility. -*/ - -/*! - \typedef QJsonArray::value_type - - Typedef for QJsonValue. Provided for STL compatibility. -*/ - -/*! - \typedef QJsonArray::difference_type - - Typedef for int. Provided for STL compatibility. -*/ - -/*! - \typedef QJsonArray::pointer - - Typedef for QJsonValue *. Provided for STL compatibility. -*/ - -/*! - \typedef QJsonArray::const_pointer - - Typedef for const QJsonValue *. Provided for STL compatibility. -*/ - -/*! - \typedef QJsonArray::reference - - Typedef for QJsonValue &. Provided for STL compatibility. -*/ - -/*! - \typedef QJsonArray::const_reference - - Typedef for const QJsonValue &. Provided for STL compatibility. -*/ - -/*! - Creates an empty array. - */ -QJsonArray::QJsonArray() - : d(0), a(0) -{ -} - -/*! - \fn QJsonArray::QJsonArray(std::initializer_list args) - \since 5.4 - Creates an array initialized from \a args initialization list. - - QJsonArray can be constructed in a way similar to JSON notation, - for example: - \code - QJsonArray array = { 1, 2.2, QString() }; - \endcode - */ - -/*! - \internal - */ -QJsonArray::QJsonArray(QJsonPrivate::Data *data, QJsonPrivate::Array *array) - : d(data), a(array) -{ - Q_ASSERT(data); - Q_ASSERT(array); - d->ref.ref(); -} - -/*! - This method replaces part of QJsonArray(std::initializer_list args) . - The constructor needs to be inline, but we do not want to leak implementation details - of this class. - \note this method is called for an uninitialized object - \internal - */ -void QJsonArray::initialize() -{ - d = 0; - a = 0; -} - -/*! - Deletes the array. - */ -QJsonArray::~QJsonArray() -{ - if (d && !d->ref.deref()) - delete d; -} - -/*! - Creates a copy of \a other. - - Since QJsonArray is implicitly shared, the copy is shallow - as long as the object doesn't get modified. - */ -QJsonArray::QJsonArray(const QJsonArray &other) -{ - d = other.d; - a = other.a; - if (d) - d->ref.ref(); -} - -/*! - Assigns \a other to this array. - */ -QJsonArray &QJsonArray::operator =(const QJsonArray &other) -{ - if (d != other.d) { - if (d && !d->ref.deref()) - delete d; - d = other.d; - if (d) - d->ref.ref(); - } - a = other.a; - - return *this; -} - -/*! \fn QJsonArray &QJsonArray::operator+=(const QJsonValue &value) - - Appends \a value to the array, and returns a reference to the array itself. - - \since 5.3 - \sa append(), operator<<() -*/ - -/*! \fn QJsonArray QJsonArray::operator+(const QJsonValue &value) const - - Returns an array that contains all the items in this array followed - by the provided \a value. - - \since 5.3 - \sa operator+=() -*/ - -/*! \fn QJsonArray &QJsonArray::operator<<(const QJsonValue &value) - - Appends \a value to the array, and returns a reference to the array itself. - - \since 5.3 - \sa operator+=(), append() -*/ - -/*! - Converts the string list \a list to a QJsonArray. - - The values in \a list will be converted to JSON values. - - \sa toVariantList(), QJsonValue::fromVariant() - */ -QJsonArray QJsonArray::fromStringList(const QStringList &list) -{ - QJsonArray array; - for (QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it) - array.append(QJsonValue(*it)); - return array; -} - -/*! - Converts the variant list \a list to a QJsonArray. - - The QVariant values in \a list will be converted to JSON values. - - \sa toVariantList(), QJsonValue::fromVariant() - */ -QJsonArray QJsonArray::fromVariantList(const QVariantList &list) -{ - QJsonArray array; - if (list.isEmpty()) - return array; - - array.detach2(1024); - - QVector values; - values.resize(list.size()); - QJsonPrivate::Value *valueData = values.data(); - uint currentOffset = sizeof(QJsonPrivate::Base); - - for (int i = 0; i < list.size(); ++i) { - QJsonValue val = QJsonValue::fromVariant(list.at(i)); - - bool latinOrIntValue; - int valueSize = QJsonPrivate::Value::requiredStorage(val, &latinOrIntValue); - - if (!array.detach2(valueSize)) - return QJsonArray(); - - QJsonPrivate::Value *v = valueData + i; - v->type = (val.t == QJsonValue::Undefined ? QJsonValue::Null : val.t); - v->latinOrIntValue = latinOrIntValue; - v->latinKey = false; - v->value = QJsonPrivate::Value::valueToStore(val, currentOffset); - if (valueSize) - QJsonPrivate::Value::copyData(val, (char *)array.a + currentOffset, latinOrIntValue); - - currentOffset += valueSize; - array.a->size = currentOffset; - } - - // write table - array.a->tableOffset = currentOffset; - if (!array.detach2(sizeof(QJsonPrivate::offset)*values.size())) - return QJsonArray(); - memcpy(static_cast(array.a->table()), - static_cast(values.constData()), values.size()*sizeof(uint)); - array.a->length = values.size(); - array.a->size = currentOffset + sizeof(QJsonPrivate::offset)*values.size(); - - return array; -} - -/*! - Converts this object to a QVariantList. - - Returns the created map. - */ -QVariantList QJsonArray::toVariantList() const -{ - QVariantList list; - - if (a) { - list.reserve(a->length); - for (int i = 0; i < (int)a->length; ++i) - list.append(QJsonValue(d, a, a->at(i)).toVariant()); - } - return list; -} - - -/*! - Returns the number of values stored in the array. - */ -int QJsonArray::size() const -{ - if (!d) - return 0; - - return (int)a->length; -} - -/*! - \fn QJsonArray::count() const - - Same as size(). - - \sa size() -*/ - -/*! - Returns \c true if the object is empty. This is the same as size() == 0. - - \sa size() - */ -bool QJsonArray::isEmpty() const -{ - if (!d) - return true; - - return !a->length; -} - -/*! - Returns a QJsonValue representing the value for index \a i. - - The returned QJsonValue is \c Undefined, if \a i is out of bounds. - - */ -QJsonValue QJsonArray::at(int i) const -{ - if (!a || i < 0 || i >= (int)a->length) - return QJsonValue(QJsonValue::Undefined); - - return QJsonValue(d, a, a->at(i)); -} - -/*! - Returns the first value stored in the array. - - Same as \c at(0). - - \sa at() - */ -QJsonValue QJsonArray::first() const -{ - return at(0); -} - -/*! - Returns the last value stored in the array. - - Same as \c{at(size() - 1)}. - - \sa at() - */ -QJsonValue QJsonArray::last() const -{ - return at(a ? (a->length - 1) : 0); -} - -/*! - Inserts \a value at the beginning of the array. - - This is the same as \c{insert(0, value)} and will prepend \a value to the array. - - \sa append(), insert() - */ -void QJsonArray::prepend(const QJsonValue &value) -{ - insert(0, value); -} - -/*! - Inserts \a value at the end of the array. - - \sa prepend(), insert() - */ -void QJsonArray::append(const QJsonValue &value) -{ - insert(a ? (int)a->length : 0, value); -} - -/*! - Removes the value at index position \a i. \a i must be a valid - index position in the array (i.e., \c{0 <= i < size()}). - - \sa insert(), replace() - */ -void QJsonArray::removeAt(int i) -{ - if (!a || i < 0 || i >= (int)a->length) - return; - - detach2(); - a->removeItems(i, 1); - ++d->compactionCounter; - if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(a->length) / 2u) - compact(); -} - -/*! \fn void QJsonArray::removeFirst() - - Removes the first item in the array. Calling this function is - equivalent to calling \c{removeAt(0)}. The array must not be empty. If - the array can be empty, call isEmpty() before calling this - function. - - \sa removeAt(), removeLast() -*/ - -/*! \fn void QJsonArray::removeLast() - - Removes the last item in the array. Calling this function is - equivalent to calling \c{removeAt(size() - 1)}. The array must not be - empty. If the array can be empty, call isEmpty() before calling - this function. - - \sa removeAt(), removeFirst() -*/ - -/*! - Removes the item at index position \a i and returns it. \a i must - be a valid index position in the array (i.e., \c{0 <= i < size()}). - - If you don't use the return value, removeAt() is more efficient. - - \sa removeAt() - */ -QJsonValue QJsonArray::takeAt(int i) -{ - if (!a || i < 0 || i >= (int)a->length) - return QJsonValue(QJsonValue::Undefined); - - QJsonValue v(d, a, a->at(i)); - removeAt(i); // detaches - return v; -} - -/*! - Inserts \a value at index position \a i in the array. If \a i - is \c 0, the value is prepended to the array. If \a i is size(), the - value is appended to the array. - - \sa append(), prepend(), replace(), removeAt() - */ -void QJsonArray::insert(int i, const QJsonValue &value) -{ - Q_ASSERT (i >= 0 && i <= (a ? (int)a->length : 0)); - QJsonValue val = value; - - bool compressed; - int valueSize = QJsonPrivate::Value::requiredStorage(val, &compressed); - - if (!detach2(valueSize + sizeof(QJsonPrivate::Value))) - return; - - if (!a->length) - a->tableOffset = sizeof(QJsonPrivate::Array); - - int valueOffset = a->reserveSpace(valueSize, i, 1, false); - if (!valueOffset) - return; - - QJsonPrivate::Value &v = (*a)[i]; - v.type = (val.t == QJsonValue::Undefined ? QJsonValue::Null : val.t); - v.latinOrIntValue = compressed; - v.latinKey = false; - v.value = QJsonPrivate::Value::valueToStore(val, valueOffset); - if (valueSize) - QJsonPrivate::Value::copyData(val, (char *)a + valueOffset, compressed); -} - -/*! - \fn QJsonArray::iterator QJsonArray::insert(iterator before, const QJsonValue &value) - - Inserts \a value before the position pointed to by \a before, and returns an iterator - pointing to the newly inserted item. - - \sa erase(), insert() -*/ - -/*! - \fn QJsonArray::iterator QJsonArray::erase(iterator it) - - Removes the item pointed to by \a it, and returns an iterator pointing to the - next item. - - \sa removeAt() -*/ - -/*! - Replaces the item at index position \a i with \a value. \a i must - be a valid index position in the array (i.e., \c{0 <= i < size()}). - - \sa operator[](), removeAt() - */ -void QJsonArray::replace(int i, const QJsonValue &value) -{ - Q_ASSERT (a && i >= 0 && i < (int)(a->length)); - QJsonValue val = value; - - bool compressed; - int valueSize = QJsonPrivate::Value::requiredStorage(val, &compressed); - - if (!detach2(valueSize)) - return; - - if (!a->length) - a->tableOffset = sizeof(QJsonPrivate::Array); - - int valueOffset = a->reserveSpace(valueSize, i, 1, true); - if (!valueOffset) - return; - - QJsonPrivate::Value &v = (*a)[i]; - v.type = (val.t == QJsonValue::Undefined ? QJsonValue::Null : val.t); - v.latinOrIntValue = compressed; - v.latinKey = false; - v.value = QJsonPrivate::Value::valueToStore(val, valueOffset); - if (valueSize) - QJsonPrivate::Value::copyData(val, (char *)a + valueOffset, compressed); - - ++d->compactionCounter; - if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(a->length) / 2u) - compact(); -} - -/*! - Returns \c true if the array contains an occurrence of \a value, otherwise \c false. - - \sa count() - */ -bool QJsonArray::contains(const QJsonValue &value) const -{ - for (int i = 0; i < size(); i++) { - if (at(i) == value) - return true; - } - return false; -} - -/*! - Returns the value at index position \a i as a modifiable reference. - \a i must be a valid index position in the array (i.e., \c{0 <= i < - size()}). - - The return value is of type QJsonValueRef, a helper class for QJsonArray - and QJsonObject. When you get an object of type QJsonValueRef, you can - use it as if it were a reference to a QJsonValue. If you assign to it, - the assignment will apply to the character in the QJsonArray of QJsonObject - from which you got the reference. - - \sa at() - */ -QJsonValueRef QJsonArray::operator [](int i) -{ - Q_ASSERT(a && i >= 0 && i < (int)a->length); - return QJsonValueRef(this, i); -} - -/*! - \overload - - Same as at(). - */ -QJsonValue QJsonArray::operator[](int i) const -{ - return at(i); -} - -/*! - Returns \c true if this array is equal to \a other. - */ -bool QJsonArray::operator==(const QJsonArray &other) const -{ - if (a == other.a) - return true; - - if (!a) - return !other.a->length; - if (!other.a) - return !a->length; - if (a->length != other.a->length) - return false; - - for (int i = 0; i < (int)a->length; ++i) { - if (QJsonValue(d, a, a->at(i)) != QJsonValue(other.d, other.a, other.a->at(i))) - return false; - } - return true; -} - -/*! - Returns \c true if this array is not equal to \a other. - */ -bool QJsonArray::operator!=(const QJsonArray &other) const -{ - return !(*this == other); -} - -/*! \fn QJsonArray::iterator QJsonArray::begin() - - Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first item in - the array. - - \sa constBegin(), end() -*/ - -/*! \fn QJsonArray::const_iterator QJsonArray::begin() const - - \overload -*/ - -/*! \fn QJsonArray::const_iterator QJsonArray::constBegin() const - - Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item - in the array. - - \sa begin(), constEnd() -*/ - -/*! \fn QJsonArray::iterator QJsonArray::end() - - Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item - after the last item in the array. - - \sa begin(), constEnd() -*/ - -/*! \fn const_iterator QJsonArray::end() const - - \overload -*/ - -/*! \fn QJsonArray::const_iterator QJsonArray::constEnd() const - - Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary - item after the last item in the array. - - \sa constBegin(), end() -*/ - -/*! \fn void QJsonArray::push_back(const QJsonValue &value) - - This function is provided for STL compatibility. It is equivalent - to \l{QJsonArray::append()}{append(value)} and will append \a value to the array. -*/ - -/*! \fn void QJsonArray::push_front(const QJsonValue &value) - - This function is provided for STL compatibility. It is equivalent - to \l{QJsonArray::prepend()}{prepend(value)} and will prepend \a value to the array. -*/ - -/*! \fn void QJsonArray::pop_front() - - This function is provided for STL compatibility. It is equivalent - to removeFirst(). The array must not be empty. If the array can be - empty, call isEmpty() before calling this function. -*/ - -/*! \fn void QJsonArray::pop_back() - - This function is provided for STL compatibility. It is equivalent - to removeLast(). The array must not be empty. If the array can be - empty, call isEmpty() before calling this function. -*/ - -/*! \fn bool QJsonArray::empty() const - - This function is provided for STL compatibility. It is equivalent - to isEmpty() and returns \c true if the array is empty. -*/ - -/*! \class QJsonArray::iterator - \inmodule QtCore - \brief The QJsonArray::iterator class provides an STL-style non-const iterator for QJsonArray. - - QJsonArray::iterator allows you to iterate over a QJsonArray - and to modify the array item associated with the - iterator. If you want to iterate over a const QJsonArray, use - QJsonArray::const_iterator instead. It is generally a good practice to - use QJsonArray::const_iterator on a non-const QJsonArray as well, unless - you need to change the QJsonArray through the iterator. Const - iterators are slightly faster and improves code readability. - - The default QJsonArray::iterator constructor creates an uninitialized - iterator. You must initialize it using a QJsonArray function like - QJsonArray::begin(), QJsonArray::end(), or QJsonArray::insert() before you can - start iterating. - - Most QJsonArray functions accept an integer index rather than an - iterator. For that reason, iterators are rarely useful in - connection with QJsonArray. One place where STL-style iterators do - make sense is as arguments to \l{generic algorithms}. - - Multiple iterators can be used on the same array. However, be - aware that any non-const function call performed on the QJsonArray - will render all existing iterators undefined. - - \sa QJsonArray::const_iterator -*/ - -/*! \typedef QJsonArray::iterator::iterator_category - - A synonym for \e {std::random_access_iterator_tag} indicating - this iterator is a random access iterator. -*/ - -/*! \typedef QJsonArray::iterator::difference_type - - \internal -*/ - -/*! \typedef QJsonArray::iterator::value_type - - \internal -*/ - -/*! \typedef QJsonArray::iterator::reference - - \internal -*/ - -/*! \typedef QJsonArray::iterator::pointer - - \internal -*/ - -/*! \fn QJsonArray::iterator::iterator() - - Constructs an uninitialized iterator. - - Functions like operator*() and operator++() should not be called - on an uninitialized iterator. Use operator=() to assign a value - to it before using it. - - \sa QJsonArray::begin(), QJsonArray::end() -*/ - -/*! \fn QJsonArray::iterator::iterator(QJsonArray *array, int index) - \internal -*/ - -/*! \fn QJsonValueRef QJsonArray::iterator::operator*() const - - - Returns a modifiable reference to the current item. - - You can change the value of an item by using operator*() on the - left side of an assignment. - - The return value is of type QJsonValueRef, a helper class for QJsonArray - and QJsonObject. When you get an object of type QJsonValueRef, you can - use it as if it were a reference to a QJsonValue. If you assign to it, - the assignment will apply to the character in the QJsonArray of QJsonObject - from which you got the reference. -*/ - -/*! \fn QJsonValueRef *QJsonArray::iterator::operator->() const - - Returns a pointer to a modifiable reference to the current item. -*/ - -/*! \fn QJsonValueRef QJsonArray::iterator::operator[](int j) const - - Returns a modifiable reference to the item at offset \a j from the - item pointed to by this iterator (the item at position \c{*this + j}). - - This function is provided to make QJsonArray iterators behave like C++ - pointers. - - The return value is of type QJsonValueRef, a helper class for QJsonArray - and QJsonObject. When you get an object of type QJsonValueRef, you can - use it as if it were a reference to a QJsonValue. If you assign to it, - the assignment will apply to the character in the QJsonArray of QJsonObject - from which you got the reference. - - \sa operator+() -*/ - -/*! - \fn bool QJsonArray::iterator::operator==(const iterator &other) const - \fn bool QJsonArray::iterator::operator==(const const_iterator &other) const - - Returns \c true if \a other points to the same item as this - iterator; otherwise returns \c false. - - \sa operator!=() -*/ - -/*! - \fn bool QJsonArray::iterator::operator!=(const iterator &other) const - \fn bool QJsonArray::iterator::operator!=(const const_iterator &other) const - - Returns \c true if \a other points to a different item than this - iterator; otherwise returns \c false. - - \sa operator==() -*/ - -/*! - \fn bool QJsonArray::iterator::operator<(const iterator& other) const - \fn bool QJsonArray::iterator::operator<(const const_iterator& other) const - - Returns \c true if the item pointed to by this iterator is less than - the item pointed to by the \a other iterator. -*/ - -/*! - \fn bool QJsonArray::iterator::operator<=(const iterator& other) const - \fn bool QJsonArray::iterator::operator<=(const const_iterator& other) const - - Returns \c true if the item pointed to by this iterator is less than - or equal to the item pointed to by the \a other iterator. -*/ - -/*! - \fn bool QJsonArray::iterator::operator>(const iterator& other) const - \fn bool QJsonArray::iterator::operator>(const const_iterator& other) const - - Returns \c true if the item pointed to by this iterator is greater - than the item pointed to by the \a other iterator. -*/ - -/*! - \fn bool QJsonArray::iterator::operator>=(const iterator& other) const - \fn bool QJsonArray::iterator::operator>=(const const_iterator& other) const - - Returns \c true if the item pointed to by this iterator is greater - than or equal to the item pointed to by the \a other iterator. -*/ - -/*! \fn QJsonArray::iterator &QJsonArray::iterator::operator++() - - The prefix ++ operator, \c{++it}, advances the iterator to the - next item in the array and returns an iterator to the new current - item. - - Calling this function on QJsonArray::end() leads to undefined results. - - \sa operator--() -*/ - -/*! \fn QJsonArray::iterator QJsonArray::iterator::operator++(int) - - \overload - - The postfix ++ operator, \c{it++}, advances the iterator to the - next item in the array and returns an iterator to the previously - current item. -*/ - -/*! \fn QJsonArray::iterator &QJsonArray::iterator::operator--() - - The prefix -- operator, \c{--it}, makes the preceding item - current and returns an iterator to the new current item. - - Calling this function on QJsonArray::begin() leads to undefined results. - - \sa operator++() -*/ - -/*! \fn QJsonArray::iterator QJsonArray::iterator::operator--(int) - - \overload - - The postfix -- operator, \c{it--}, makes the preceding item - current and returns an iterator to the previously current item. -*/ - -/*! \fn QJsonArray::iterator &QJsonArray::iterator::operator+=(int j) - - Advances the iterator by \a j items. If \a j is negative, the - iterator goes backward. - - \sa operator-=(), operator+() -*/ - -/*! \fn QJsonArray::iterator &QJsonArray::iterator::operator-=(int j) - - Makes the iterator go back by \a j items. If \a j is negative, - the iterator goes forward. - - \sa operator+=(), operator-() -*/ - -/*! \fn QJsonArray::iterator QJsonArray::iterator::operator+(int j) const - - Returns an iterator to the item at \a j positions forward from - this iterator. If \a j is negative, the iterator goes backward. - - \sa operator-(), operator+=() -*/ - -/*! \fn QJsonArray::iterator QJsonArray::iterator::operator-(int j) const - - Returns an iterator to the item at \a j positions backward from - this iterator. If \a j is negative, the iterator goes forward. - - \sa operator+(), operator-=() -*/ - -/*! \fn int QJsonArray::iterator::operator-(iterator other) const - - Returns the number of items between the item pointed to by \a - other and the item pointed to by this iterator. -*/ - -/*! \class QJsonArray::const_iterator - \inmodule QtCore - \brief The QJsonArray::const_iterator class provides an STL-style const iterator for QJsonArray. - - QJsonArray::const_iterator allows you to iterate over a - QJsonArray. If you want to modify the QJsonArray as - you iterate over it, use QJsonArray::iterator instead. It is generally a - good practice to use QJsonArray::const_iterator on a non-const QJsonArray - as well, unless you need to change the QJsonArray through the - iterator. Const iterators are slightly faster and improves - code readability. - - The default QJsonArray::const_iterator constructor creates an - uninitialized iterator. You must initialize it using a QJsonArray - function like QJsonArray::constBegin(), QJsonArray::constEnd(), or - QJsonArray::insert() before you can start iterating. - - Most QJsonArray functions accept an integer index rather than an - iterator. For that reason, iterators are rarely useful in - connection with QJsonArray. One place where STL-style iterators do - make sense is as arguments to \l{generic algorithms}. - - Multiple iterators can be used on the same array. However, be - aware that any non-const function call performed on the QJsonArray - will render all existing iterators undefined. - - \sa QJsonArray::iterator -*/ - -/*! \fn QJsonArray::const_iterator::const_iterator() - - Constructs an uninitialized iterator. - - Functions like operator*() and operator++() should not be called - on an uninitialized iterator. Use operator=() to assign a value - to it before using it. - - \sa QJsonArray::constBegin(), QJsonArray::constEnd() -*/ - -/*! \fn QJsonArray::const_iterator::const_iterator(const QJsonArray *array, int index) - \internal -*/ - -/*! \typedef QJsonArray::const_iterator::iterator_category - - A synonym for \e {std::random_access_iterator_tag} indicating - this iterator is a random access iterator. -*/ - -/*! \typedef QJsonArray::const_iterator::difference_type - - \internal -*/ - -/*! \typedef QJsonArray::const_iterator::value_type - - \internal -*/ - -/*! \typedef QJsonArray::const_iterator::reference - - \internal -*/ - -/*! \typedef QJsonArray::const_iterator::pointer - - \internal -*/ - -/*! \fn QJsonArray::const_iterator::const_iterator(const const_iterator &other) - - Constructs a copy of \a other. -*/ - -/*! \fn QJsonArray::const_iterator::const_iterator(const iterator &other) - - Constructs a copy of \a other. -*/ - -/*! \fn QJsonValue QJsonArray::const_iterator::operator*() const - - Returns the current item. -*/ - -/*! \fn QJsonValue *QJsonArray::const_iterator::operator->() const - - Returns a pointer to the current item. -*/ - -/*! \fn QJsonValue QJsonArray::const_iterator::operator[](int j) const - - Returns the item at offset \a j from the item pointed to by this iterator (the item at - position \c{*this + j}). - - This function is provided to make QJsonArray iterators behave like C++ - pointers. - - \sa operator+() -*/ - -/*! \fn bool QJsonArray::const_iterator::operator==(const const_iterator &other) const - - Returns \c true if \a other points to the same item as this - iterator; otherwise returns \c false. - - \sa operator!=() -*/ - -/*! \fn bool QJsonArray::const_iterator::operator!=(const const_iterator &other) const - - Returns \c true if \a other points to a different item than this - iterator; otherwise returns \c false. - - \sa operator==() -*/ - -/*! - \fn bool QJsonArray::const_iterator::operator<(const const_iterator& other) const - - Returns \c true if the item pointed to by this iterator is less than - the item pointed to by the \a other iterator. -*/ - -/*! - \fn bool QJsonArray::const_iterator::operator<=(const const_iterator& other) const - - Returns \c true if the item pointed to by this iterator is less than - or equal to the item pointed to by the \a other iterator. -*/ - -/*! - \fn bool QJsonArray::const_iterator::operator>(const const_iterator& other) const - - Returns \c true if the item pointed to by this iterator is greater - than the item pointed to by the \a other iterator. -*/ - -/*! - \fn bool QJsonArray::const_iterator::operator>=(const const_iterator& other) const - - Returns \c true if the item pointed to by this iterator is greater - than or equal to the item pointed to by the \a other iterator. -*/ - -/*! \fn QJsonArray::const_iterator &QJsonArray::const_iterator::operator++() - - The prefix ++ operator, \c{++it}, advances the iterator to the - next item in the array and returns an iterator to the new current - item. - - Calling this function on QJsonArray::end() leads to undefined results. - - \sa operator--() -*/ - -/*! \fn QJsonArray::const_iterator QJsonArray::const_iterator::operator++(int) - - \overload - - The postfix ++ operator, \c{it++}, advances the iterator to the - next item in the array and returns an iterator to the previously - current item. -*/ - -/*! \fn QJsonArray::const_iterator &QJsonArray::const_iterator::operator--() - - The prefix -- operator, \c{--it}, makes the preceding item - current and returns an iterator to the new current item. - - Calling this function on QJsonArray::begin() leads to undefined results. - - \sa operator++() -*/ - -/*! \fn QJsonArray::const_iterator QJsonArray::const_iterator::operator--(int) - - \overload - - The postfix -- operator, \c{it--}, makes the preceding item - current and returns an iterator to the previously current item. -*/ - -/*! \fn QJsonArray::const_iterator &QJsonArray::const_iterator::operator+=(int j) - - Advances the iterator by \a j items. If \a j is negative, the - iterator goes backward. - - \sa operator-=(), operator+() -*/ - -/*! \fn QJsonArray::const_iterator &QJsonArray::const_iterator::operator-=(int j) - - Makes the iterator go back by \a j items. If \a j is negative, - the iterator goes forward. - - \sa operator+=(), operator-() -*/ - -/*! \fn QJsonArray::const_iterator QJsonArray::const_iterator::operator+(int j) const - - Returns an iterator to the item at \a j positions forward from - this iterator. If \a j is negative, the iterator goes backward. - - \sa operator-(), operator+=() -*/ - -/*! \fn QJsonArray::const_iterator QJsonArray::const_iterator::operator-(int j) const - - Returns an iterator to the item at \a j positions backward from - this iterator. If \a j is negative, the iterator goes forward. - - \sa operator+(), operator-=() -*/ - -/*! \fn int QJsonArray::const_iterator::operator-(const_iterator other) const - - Returns the number of items between the item pointed to by \a - other and the item pointed to by this iterator. -*/ - - -/*! - \internal - */ -void QJsonArray::detach(uint reserve) -{ - Q_UNUSED(reserve) - Q_ASSERT(!reserve); - detach2(0); -} - -/*! - \internal - */ -bool QJsonArray::detach2(uint reserve) -{ - if (!d) { - if (reserve >= QJsonPrivate::Value::MaxSize) { - qWarning("QJson: Document too large to store in data structure"); - return false; - } - d = new QJsonPrivate::Data(reserve, QJsonValue::Array); - a = static_cast(d->header->root()); - d->ref.ref(); - return true; - } - if (reserve == 0 && d->ref.load() == 1) - return true; - - QJsonPrivate::Data *x = d->clone(a, reserve); - if (!x) - return false; - x->ref.ref(); - if (!d->ref.deref()) - delete d; - d = x; - a = static_cast(d->header->root()); - return true; -} - -/*! - \internal - */ -void QJsonArray::compact() -{ - if (!d || !d->compactionCounter) - return; - - detach2(); - d->compact(); - a = static_cast(d->header->root()); -} - - -#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) -QDebug operator<<(QDebug dbg, const QJsonArray &a) -{ - QDebugStateSaver saver(dbg); - if (!a.a) { - dbg << "QJsonArray()"; - return dbg; - } - QByteArray json; - QJsonPrivate::Writer::arrayToJson(a.a, json, 0, true); - dbg.nospace() << "QJsonArray(" - << json.constData() // print as utf-8 string without extra quotation marks - << ")"; - return dbg; -} -#endif - -QT_END_NAMESPACE - -- cgit v1.2.3 From c0e45ae851c96dfebdebfd1e85b7b7eee6540bd1 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Thu, 15 Feb 2018 20:24:40 +0100 Subject: QHeaderView: properly restore hidden section size on layoutChanged() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During (re)storing the sections within layoutChanged handling, the hidden section size was not properly stored which lead to a section size of 0 when the section was unhided afterwards. Task-number: QTBUG-66413 Task-number: QTBUG-65478 Change-Id: I0b714c7e0530a1eae82b3bb0e0dc80ed576522d0 Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/itemviews/qheaderview.cpp | 10 +++++++--- tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp | 5 +++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index c90a61d4ff..edef2e9bf8 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -2168,15 +2168,19 @@ void QHeaderViewPrivate::_q_sectionsAboutToBeChanged() sectionItems[visual].size = lastSectionSize; } for (int i = 0; i < sectionItems.size(); ++i) { - const auto &s = sectionItems.at(i); + auto s = sectionItems.at(i); // only add if the section is not default and not visually moved if (s.size == defaultSectionSize && !s.isHidden && s.resizeMode == globalResizeMode) continue; + const int logical = logicalIndex(i); + if (s.isHidden) + s.size = hiddenSectionSize.value(logical); + // ### note that we are using column or row 0 layoutChangePersistentSections.append({orientation == Qt::Horizontal - ? model->index(0, logicalIndex(i), root) - : model->index(logicalIndex(i), 0, root), + ? model->index(0, logical, root) + : model->index(logical, 0, root), s}); if (layoutChangePersistentSections.size() > 1000) diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index 3594e7fa01..c69c0de949 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -2286,7 +2286,9 @@ void tst_QHeaderView::QTBUG7833_sectionClicked() tv.setModel(proxyModel); const int section4Size = tv.horizontalHeader()->sectionSize(4) + 1; + const int section5Size = section4Size + 1; tv.horizontalHeader()->resizeSection(4, section4Size); + tv.horizontalHeader()->resizeSection(5, section5Size); tv.setColumnHidden(5, true); tv.setColumnHidden(6, true); tv.horizontalHeader()->swapSections(8, 10); @@ -2298,6 +2300,9 @@ void tst_QHeaderView::QTBUG7833_sectionClicked() QCOMPARE(tv.horizontalHeader()->logicalIndex(8), 10); QCOMPARE(tv.horizontalHeader()->logicalIndex(10), 8); QCOMPARE(tv.horizontalHeader()->sectionSize(4), section4Size); + tv.setColumnHidden(5, false); // unhide, section size must be properly restored + QCOMPARE(tv.horizontalHeader()->sectionSize(5), section5Size); + tv.setColumnHidden(5, true); QSignalSpy clickedSpy(tv.horizontalHeader(), SIGNAL(sectionClicked(int))); QSignalSpy pressedSpy(tv.horizontalHeader(), SIGNAL(sectionPressed(int))); -- cgit v1.2.3 From 9395f35cb18725995910531ca8b09f1d84efa96c Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 17 Feb 2018 10:02:19 +0100 Subject: QHeaderView: Preserve settings on layoutChange with empty model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not clear the settings of QHeaderView during layoutChange when the model is empty and the section count did not change. This will not work when a section is moved or a section is replaced with a new one during layoutChange. But since layoutChanged is also called on sorting, this patch ensures that the settings are not cleared in this case. This restores the behavior to the same as before 5.9.4. Task-number: QTBUG-66444 Task-number: QTBUG-65478 Change-Id: I39989cfd45b42e58f49d18ec014d3a941cadb6c9 Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/itemviews/qheaderview.cpp | 24 ++++++++ .../itemviews/qheaderview/tst_qheaderview.cpp | 71 ++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index edef2e9bf8..b0359de3ea 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -2205,6 +2205,30 @@ void QHeaderViewPrivate::_q_sectionsChanged() return; } + bool hasPersistantIndexes = false; + for (const auto &item : oldPersistentSections) { + if (item.index.isValid()) { + hasPersistantIndexes = true; + break; + } + } + + // Though far from perfect we here try to retain earlier/existing behavior + // ### See QHeaderViewPrivate::_q_layoutAboutToBeChanged() + // When we don't have valid hasPersistantIndexes it can be due to + // - all sections are default sections + // - the row/column 0 which is used for persistent indexes is gone + // - all non-default sections were removed + // case one is trivial, in case two we assume nothing else changed (it's the best + // guess we can do - everything else can not be handled correctly for now) + // case three can not be handled correctly with layoutChanged - removeSections + // should be used instead for this + if (!hasPersistantIndexes) { + if (oldCount != newCount) + q->initializeSections(); + return; + } + // adjust section size if (newCount != oldCount) { const int min = qBound(0, oldCount, newCount - 1); diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index c69c0de949..97aa8a0299 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -206,6 +206,7 @@ private slots: void task248050_hideRow(); void QTBUG6058_reset(); void QTBUG7833_sectionClicked(); + void checkLayoutChangeEmptyModel(); void QTBUG8650_crashOnInsertSections(); void QTBUG12268_hiddenMovedSectionSorting(); void QTBUG14242_hideSectionAutoSize(); @@ -286,6 +287,13 @@ public: endInsertColumns(); } + void removeFirstRow() + { + beginRemoveRows(QModelIndex(), 0, 0); + --rows; + endRemoveRows(); + } + void removeLastRow() { beginRemoveRows(QModelIndex(), rows - 1, rows - 1); @@ -328,6 +336,24 @@ public: emit layoutChanged(); } + void emitLayoutChanged() + { + emit layoutAboutToBeChanged(); + emit layoutChanged(); + } + + void emitLayoutChangedWithRemoveFirstRow() + { + emit layoutAboutToBeChanged(); + QModelIndexList milNew; + const auto milOld = persistentIndexList(); + milNew.reserve(milOld.size()); + for (int i = 0; i < milOld.size(); ++i) + milNew += QModelIndex(); + changePersistentIndexList(milOld, milNew); + emit layoutChanged(); + } + int cols, rows; mutable bool wrongIndex; }; @@ -2332,6 +2358,51 @@ void tst_QHeaderView::QTBUG7833_sectionClicked() QCOMPARE(pressedSpy.at(2).at(0).toInt(), 0); } +void tst_QHeaderView::checkLayoutChangeEmptyModel() +{ + QtTestModel tm; + tm.cols = 11; + QTableView tv; + tv.setModel(&tm); + + const int section4Size = tv.horizontalHeader()->sectionSize(4) + 1; + const int section5Size = section4Size + 1; + tv.horizontalHeader()->resizeSection(4, section4Size); + tv.horizontalHeader()->resizeSection(5, section5Size); + tv.setColumnHidden(5, true); + tv.setColumnHidden(6, true); + tv.horizontalHeader()->swapSections(8, 10); + + tv.sortByColumn(1, Qt::AscendingOrder); + tm.emitLayoutChanged(); + + QCOMPARE(tv.isColumnHidden(5), true); + QCOMPARE(tv.isColumnHidden(6), true); + QCOMPARE(tv.horizontalHeader()->sectionsMoved(), true); + QCOMPARE(tv.horizontalHeader()->logicalIndex(8), 10); + QCOMPARE(tv.horizontalHeader()->logicalIndex(10), 8); + QCOMPARE(tv.horizontalHeader()->sectionSize(4), section4Size); + tv.setColumnHidden(5, false); // unhide, section size must be properly restored + QCOMPARE(tv.horizontalHeader()->sectionSize(5), section5Size); + tv.setColumnHidden(5, true); + + // adjust + tm.rows = 3; + tm.emitLayoutChanged(); + + // remove the row used for QPersistenModelIndexes + tm.emitLayoutChangedWithRemoveFirstRow(); + QCOMPARE(tv.isColumnHidden(5), true); + QCOMPARE(tv.isColumnHidden(6), true); + QCOMPARE(tv.horizontalHeader()->sectionsMoved(), true); + QCOMPARE(tv.horizontalHeader()->logicalIndex(8), 10); + QCOMPARE(tv.horizontalHeader()->logicalIndex(10), 8); + QCOMPARE(tv.horizontalHeader()->sectionSize(4), section4Size); + tv.setColumnHidden(5, false); // unhide, section size must be properly restored + QCOMPARE(tv.horizontalHeader()->sectionSize(5), section5Size); + tv.setColumnHidden(5, true); +} + void tst_QHeaderView::QTBUG8650_crashOnInsertSections() { QStringList headerLabels; -- cgit v1.2.3 From 2acfc48de57162a0cedd14c66b8ea7e5fccb7c0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 9 Feb 2018 15:14:41 +0100 Subject: testlib: Pass on log message context to loggers Change-Id: I1e0bb09d4f96b45f1e9757ea25ae3aba1ae42447 Reviewed-by: Thiago Macieira --- src/testlib/qabstracttestlogger.cpp | 24 ++++++++++++++++++++++++ src/testlib/qabstracttestlogger_p.h | 3 +++ src/testlib/qplaintestlogger.cpp | 5 +++++ src/testlib/qplaintestlogger_p.h | 3 +++ src/testlib/qtestlog.cpp | 32 ++++++++++++-------------------- 5 files changed, 47 insertions(+), 20 deletions(-) diff --git a/src/testlib/qabstracttestlogger.cpp b/src/testlib/qabstracttestlogger.cpp index 8337600fa1..63c165b9dc 100644 --- a/src/testlib/qabstracttestlogger.cpp +++ b/src/testlib/qabstracttestlogger.cpp @@ -41,6 +41,7 @@ #include #include +#include #include #include @@ -121,6 +122,29 @@ void QAbstractTestLogger::stopLogging() { } +void QAbstractTestLogger::addMessage(QtMsgType type, const QMessageLogContext &context, + const QString &message) +{ + QAbstractTestLogger::MessageTypes messageType = [=]() { + switch (type) { + case QtDebugMsg: return QAbstractTestLogger::QDebug; + case QtInfoMsg: return QAbstractTestLogger::QInfo; + case QtCriticalMsg: return QAbstractTestLogger::QSystem; + case QtWarningMsg: return QAbstractTestLogger::QWarning; + case QtFatalMsg: return QAbstractTestLogger::QFatal; + } + Q_UNREACHABLE(); + return QAbstractTestLogger::QFatal; + }(); + + QString formattedMessage = qFormatLogMessage(type, context, message); + + // Note that we explicitly ignore the file and line of the context here, + // as that's what QTest::messageHandler used to do when calling the same + // overload directly. + addMessage(messageType, formattedMessage); +} + namespace QTest { diff --git a/src/testlib/qabstracttestlogger_p.h b/src/testlib/qabstracttestlogger_p.h index e1fd5006b4..c4083b43f4 100644 --- a/src/testlib/qabstracttestlogger_p.h +++ b/src/testlib/qabstracttestlogger_p.h @@ -95,6 +95,9 @@ public: const char *file = 0, int line = 0) = 0; virtual void addBenchmarkResult(const QBenchmarkResult &result) = 0; + virtual void addMessage(QtMsgType, const QMessageLogContext &, + const QString &); + virtual void addMessage(MessageTypes type, const QString &message, const char *file = 0, int line = 0) = 0; diff --git a/src/testlib/qplaintestlogger.cpp b/src/testlib/qplaintestlogger.cpp index 25c9655691..4239882c4d 100644 --- a/src/testlib/qplaintestlogger.cpp +++ b/src/testlib/qplaintestlogger.cpp @@ -399,6 +399,11 @@ void QPlainTestLogger::addBenchmarkResult(const QBenchmarkResult &result) printBenchmarkResult(result); } +void QPlainTestLogger::addMessage(QtMsgType type, const QMessageLogContext &context, const QString &message) +{ + QAbstractTestLogger::addMessage(type, context, message); +} + void QPlainTestLogger::addMessage(MessageTypes type, const QString &message, const char *file, int line) { diff --git a/src/testlib/qplaintestlogger_p.h b/src/testlib/qplaintestlogger_p.h index 93d3c7143a..55755830b2 100644 --- a/src/testlib/qplaintestlogger_p.h +++ b/src/testlib/qplaintestlogger_p.h @@ -71,6 +71,9 @@ public: const char *file = 0, int line = 0) override; void addBenchmarkResult(const QBenchmarkResult &result) override; + void addMessage(QtMsgType, const QMessageLogContext &, + const QString &) override; + void addMessage(MessageTypes type, const QString &message, const char *file = 0, int line = 0) override; diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp index 5bbf2c6458..4964c6538e 100644 --- a/src/testlib/qtestlog.cpp +++ b/src/testlib/qtestlog.cpp @@ -220,6 +220,12 @@ namespace QTest { FOREACH_LOGGER(logger->addBenchmarkResult(result)); } + static void addMessage(QtMsgType type, const QMessageLogContext &context, + const QString &message) + { + FOREACH_LOGGER(logger->addMessage(type, context, message)); + } + static void addMessage(QAbstractTestLogger::MessageTypes type, const QString &message, const char *file = 0, int line = 0) { @@ -289,11 +295,10 @@ namespace QTest { QTEST_ASSERT(QTest::TestLoggers::loggerCount() != 0); } - if (handleIgnoredMessage(type, message)) + if (handleIgnoredMessage(type, message)) { // the message is expected, so just swallow it. return; - - QString msg = qFormatLogMessage(type, context, message); + } if (type != QtFatalMsg) { if (counter.load() <= 0) @@ -306,22 +311,10 @@ namespace QTest { } } - switch (type) { - case QtDebugMsg: - QTest::TestLoggers::addMessage(QAbstractTestLogger::QDebug, msg); - break; - case QtInfoMsg: - QTest::TestLoggers::addMessage(QAbstractTestLogger::QInfo, msg); - break; - case QtCriticalMsg: - QTest::TestLoggers::addMessage(QAbstractTestLogger::QSystem, msg); - break; - case QtWarningMsg: - QTest::TestLoggers::addMessage(QAbstractTestLogger::QWarning, msg); - break; - case QtFatalMsg: - QTest::TestLoggers::addMessage(QAbstractTestLogger::QFatal, msg); - /* Right now, we're inside the custom message handler and we're + QTest::TestLoggers::addMessage(type, context, message); + + if (type == QtFatalMsg) { + /* Right now, we're inside the custom message handler and we're * being qt_message_output in qglobal.cpp. After we return from * this function, it will proceed with calling exit() and abort() * and hence crash. Therefore, we call these logging functions such @@ -329,7 +322,6 @@ namespace QTest { QTestResult::addFailure("Received a fatal error.", "Unknown file", 0); QTestLog::leaveTestFunction(); QTestLog::stopLogging(); - break; } } } -- cgit v1.2.3 From 22d3eeebb0a011a61104de2eb635a3ecf26b58e2 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Wed, 21 Feb 2018 14:33:29 +0300 Subject: fix installation of resources for example sources contains() interprets the regexp as being implicitly anchored, so the leading part of the path needs to be explicitly matched. Change-Id: I1efa07dc99bb2db1717d2a66621899e23c144164 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qt_example_installs.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/qt_example_installs.prf b/mkspecs/features/qt_example_installs.prf index c9ce926b1a..43b58817fe 100644 --- a/mkspecs/features/qt_example_installs.prf +++ b/mkspecs/features/qt_example_installs.prf @@ -44,7 +44,7 @@ contains(TEMPLATE, .*app): \ for(ex, EXAMPLE_FILES): \ sourcefiles += $$files($$absolute_path($$ex, $$_PRO_FILE_PWD_)) for(res, RESOURCES) { - !contains(res, \\.qrc$): \ + !contains(res, .*\\.qrc): \ next() rfile = $$absolute_path($$res, $$_PRO_FILE_PWD_) rpath = $$dirname(rfile) -- cgit v1.2.3 From fa091640134b3ff99a9eb92df8286d15203122bf Mon Sep 17 00:00:00 2001 From: Antonio Larrosa Date: Fri, 16 Feb 2018 13:18:42 +0100 Subject: opengl: Bail if cached shader fails to load QOpenGLProgramBinaryCache::setProgramBinary() should check GL_LINK_STATUS after glProgramBinary(), but doesn't. In practice, this means that SDDM is a white screen, and KDE is just a gray task bar. So far, Qt tries to check this using its internal ::link() function. But in case the cached binary fails to load, Qt currently attempts to link the inexistent program, resulting in a zero-length, fixed pipeline shader. Checking this already in ::setProgramBinary() makes the call to ::link() superfluous, so we remove that as well. Done-with: Max Staudt Done-with: Michal Srb Done-with: Fabian Vogt Task-number: QTBUG-66420 Change-Id: Iabb51d0eb2c0c16bde696efff623e57d15f28d82 Reviewed-by: Jesus Fernandez Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopenglprogrambinarycache.cpp | 20 ++++++++++++++++++-- src/gui/opengl/qopenglshaderprogram.cpp | 8 +------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/gui/opengl/qopenglprogrambinarycache.cpp b/src/gui/opengl/qopenglprogrambinarycache.cpp index 06373e1113..d16173df83 100644 --- a/src/gui/opengl/qopenglprogrambinarycache.cpp +++ b/src/gui/opengl/qopenglprogrambinarycache.cpp @@ -161,10 +161,26 @@ bool QOpenGLProgramBinaryCache::setProgramBinary(uint programId, uint blobFormat QOpenGLExtraFunctions *funcs = QOpenGLContext::currentContext()->extraFunctions(); while (funcs->glGetError() != GL_NO_ERROR) { } funcs->glProgramBinary(programId, blobFormat, p, blobSize); - int err = funcs->glGetError(); + + GLenum err = funcs->glGetError(); + if (err != GL_NO_ERROR) { + qCDebug(DBG_SHADER_CACHE, "Program binary failed to load for program %u, size %d, " + "format 0x%x, err = 0x%x", + programId, blobSize, blobFormat, err); + return false; + } + GLint linkStatus = 0; + funcs->glGetProgramiv(programId, GL_LINK_STATUS, &linkStatus); + if (linkStatus != GL_TRUE) { + qCDebug(DBG_SHADER_CACHE, "Program binary failed to load for program %u, size %d, " + "format 0x%x, linkStatus = 0x%x, err = 0x%x", + programId, blobSize, blobFormat, linkStatus, err); + return false; + } + qCDebug(DBG_SHADER_CACHE, "Program binary set for program %u, size %d, format 0x%x, err = 0x%x", programId, blobSize, blobFormat, err); - return err == 0; + return true; } #ifdef Q_OS_UNIX diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp index b044397f8e..1fe30f7e0e 100644 --- a/src/gui/opengl/qopenglshaderprogram.cpp +++ b/src/gui/opengl/qopenglshaderprogram.cpp @@ -3824,13 +3824,7 @@ bool QOpenGLShaderProgramPrivate::linkBinary() bool needsCompile = true; if (binCache.load(cacheKey, q->programId())) { qCDebug(DBG_SHADER_CACHE, "Program binary received from cache"); - linkBinaryRecursion = true; - bool ok = q->link(); - linkBinaryRecursion = false; - if (ok) - needsCompile = false; - else - qCDebug(DBG_SHADER_CACHE, "Link failed after glProgramBinary"); + needsCompile = false; } bool needsSave = false; -- cgit v1.2.3 From e83ce91c6a8ce094f32dff8efb92074459b050d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 12 Feb 2018 12:13:37 +0200 Subject: mkspecs: Factorize common parts of win32-g++ and win32-clang-g++ Change-Id: I49dc036aedb4290889bce8ef616b4f7291e79d4f Reviewed-by: Oswald Buddenhagen --- mkspecs/common/g++-win32.conf | 82 ++++++++++++++++++++++++++++++++++++++ mkspecs/win32-clang-g++/qmake.conf | 71 ++------------------------------- mkspecs/win32-g++/qmake.conf | 68 +------------------------------ 3 files changed, 88 insertions(+), 133 deletions(-) create mode 100644 mkspecs/common/g++-win32.conf diff --git a/mkspecs/common/g++-win32.conf b/mkspecs/common/g++-win32.conf new file mode 100644 index 0000000000..610503379d --- /dev/null +++ b/mkspecs/common/g++-win32.conf @@ -0,0 +1,82 @@ +# +# This file is used as a basis for the following compilers, when targeting +# MinGW-w64: +# +# - GCC +# - Clang +# +# Compiler-specific settings go into win32-g++/qmake.conf and +# win32-clang-g++/qmake.conf +# + +load(device_config) +include(gcc-base.conf) +include(g++-base.conf) + +# modifications to gcc-base.conf and g++-base.conf + +MAKEFILE_GENERATOR = MINGW +QMAKE_PLATFORM = win32 mingw +CONFIG += debug_and_release debug_and_release_target precompile_header +DEFINES += UNICODE _UNICODE WIN32 +QMAKE_COMPILER_DEFINES += __GNUC__ _WIN32 +# can't add 'DEFINES += WIN64' and 'QMAKE_COMPILER_DEFINES += _WIN64' defines for +# x86_64 platform similar to 'msvc-desktop.conf' toolchain, because, unlike for MSVC, +# 'QMAKE_TARGET.arch' is inherently unavailable. + +QMAKE_LEX = flex +QMAKE_LEXFLAGS = +QMAKE_YACC = bison -y +QMAKE_YACCFLAGS = -d + +QMAKE_CFLAGS_SSE2 += -mstackrealign + +QMAKE_CXXFLAGS_RTTI_ON = -frtti +QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti +QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads + +QMAKE_INCDIR = + +QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src +QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< +QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src +QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +QMAKE_LFLAGS_EXCEPTIONS_ON = -mthreads +QMAKE_LFLAGS_RELEASE = -Wl,-s +QMAKE_LFLAGS_CONSOLE = -Wl,-subsystem,console +QMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows +QMAKE_LFLAGS_DLL = -shared +QMAKE_LFLAGS_GCSECTIONS = -Wl,--gc-sections +equals(QMAKE_HOST.os, Windows) { + QMAKE_LINK_OBJECT_MAX = 10 + QMAKE_LINK_OBJECT_SCRIPT = object_script +} +QMAKE_EXT_OBJ = .o +QMAKE_EXT_RES = _res.o +QMAKE_PREFIX_SHLIB = +QMAKE_EXTENSION_SHLIB = dll +QMAKE_PREFIX_STATICLIB = lib +QMAKE_EXTENSION_STATICLIB = a +QMAKE_LIB_EXTENSIONS = a dll.a + +QMAKE_LIBS = +QMAKE_LIBS_GUI = -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lws2_32 -lole32 -luuid -luser32 -ladvapi32 +QMAKE_LIBS_NETWORK = -lws2_32 +QMAKE_LIBS_OPENGL = -lglu32 -lopengl32 -lgdi32 -luser32 +QMAKE_LIBS_OPENGL_ES2 = -lgdi32 -luser32 +QMAKE_LIBS_OPENGL_ES2_DEBUG = -lgdi32 -luser32 +QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32 +QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain + +QMAKE_IDL = midl +QMAKE_LIB = $${CROSS_COMPILE}ar -rc +QMAKE_RC = $${CROSS_COMPILE}windres + +QMAKE_STRIP = $${CROSS_COMPILE}strip +QMAKE_STRIPFLAGS_LIB += --strip-unneeded +QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy +QMAKE_NM = $${CROSS_COMPILE}nm -P + +include(angle.conf) +include(windows-vulkan.conf) diff --git a/mkspecs/win32-clang-g++/qmake.conf b/mkspecs/win32-clang-g++/qmake.conf index 1cae64ce99..4630ec4602 100644 --- a/mkspecs/win32-clang-g++/qmake.conf +++ b/mkspecs/win32-clang-g++/qmake.conf @@ -7,84 +7,21 @@ # configure -xplatform win32-clang-g++ -device-option CROSS_COMPILE=x86_64-w64-mingw32- # -load(device_config) -include(../common/gcc-base.conf) -include(../common/g++-base.conf) -include(../common/angle.conf) -include(../common/windows-vulkan.conf) +include(../common/g++-win32.conf) -# modifications to gcc-base.conf and g++-base.conf +# modifications to g++-win32.conf -MAKEFILE_GENERATOR = MINGW -QMAKE_PLATFORM = win32 mingw -CONFIG += debug_and_release debug_and_release_target precompile_header -DEFINES += UNICODE _UNICODE WIN32 -QMAKE_COMPILER = gcc clang llvm # clang pretends to be gcc -QMAKE_COMPILER_DEFINES += __GNUC__ _WIN32 -# can't add 'DEFINES += WIN64' and 'QMAKE_COMPILER_DEFINES += _WIN64' defines for -# x86_64 platform similar to 'msvc-desktop.conf' toolchain, because, unlike for MSVC, -# 'QMAKE_TARGET.arch' is inherently unavailable. +QMAKE_COMPILER += clang llvm # clang pretends to be gcc QMAKE_CC = $${CROSS_COMPILE}clang -QMAKE_LEX = flex -QMAKE_LEXFLAGS = -QMAKE_YACC = bison -y -QMAKE_YACCFLAGS = -d QMAKE_CFLAGS += QMAKE_CFLAGS_WARN_ON += -Wextra -Wno-ignored-attributes -QMAKE_CFLAGS_SSE2 += -mstackrealign - QMAKE_CXX = $${CROSS_COMPILE}clang++ -QMAKE_CXXFLAGS = $$QMAKE_CFLAGS +QMAKE_CXXFLAGS += QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -QMAKE_CXXFLAGS_RTTI_ON = -frtti -QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti -QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads - -QMAKE_INCDIR = - -QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src -QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< -QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src -QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< QMAKE_LINK = $${CROSS_COMPILE}clang++ QMAKE_LINK_C = $${CROSS_COMPILE}clang -QMAKE_LFLAGS_EXCEPTIONS_ON = -mthreads -QMAKE_LFLAGS_RELEASE = -Wl,-s -QMAKE_LFLAGS_CONSOLE = -Wl,-subsystem,console -QMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows -QMAKE_LFLAGS_DLL = -shared -QMAKE_LFLAGS_GCSECTIONS = -Wl,--gc-sections -equals(QMAKE_HOST.os, Windows) { - QMAKE_LINK_OBJECT_MAX = 10 - QMAKE_LINK_OBJECT_SCRIPT = object_script -} -QMAKE_EXT_OBJ = .o -QMAKE_EXT_RES = _res.o -QMAKE_PREFIX_SHLIB = -QMAKE_EXTENSION_SHLIB = dll -QMAKE_PREFIX_STATICLIB = lib -QMAKE_EXTENSION_STATICLIB = a -QMAKE_LIB_EXTENSIONS = a dll.a - -QMAKE_LIBS = -QMAKE_LIBS_GUI = -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lws2_32 -lole32 -luuid -luser32 -ladvapi32 -QMAKE_LIBS_NETWORK = -lws2_32 -QMAKE_LIBS_OPENGL = -lglu32 -lopengl32 -lgdi32 -luser32 -QMAKE_LIBS_OPENGL_ES2 = -lgdi32 -luser32 -QMAKE_LIBS_OPENGL_ES2_DEBUG = -lgdi32 -luser32 -QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32 -QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain - -QMAKE_IDL = midl -QMAKE_LIB = $${CROSS_COMPILE}ar -rc -QMAKE_RC = $${CROSS_COMPILE}windres - -QMAKE_STRIP = $${CROSS_COMPILE}strip -QMAKE_STRIPFLAGS_LIB += --strip-unneeded -QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy -QMAKE_NM = $${CROSS_COMPILE}nm -P load(qt_config) diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf index 9f366e08b8..9c289a05f9 100644 --- a/mkspecs/win32-g++/qmake.conf +++ b/mkspecs/win32-g++/qmake.conf @@ -7,83 +7,19 @@ # configure -xplatform win32-g++ -device-option CROSS_COMPILE=i686-w64-mingw32- # -load(device_config) -include(../common/gcc-base.conf) -include(../common/g++-base.conf) -include(../common/angle.conf) -include(../common/windows-vulkan.conf) +include(../common/g++-win32.conf) -# modifications to gcc-base.conf and g++-base.conf - -MAKEFILE_GENERATOR = MINGW -QMAKE_PLATFORM = win32 mingw -CONFIG += debug_and_release debug_and_release_target precompile_header -DEFINES += UNICODE _UNICODE WIN32 -QMAKE_COMPILER_DEFINES += __GNUC__ _WIN32 -# can't add 'DEFINES += WIN64' and 'QMAKE_COMPILER_DEFINES += _WIN64' defines for -# x86_64 platform similar to 'msvc-desktop.conf' toolchain, because, unlike for MSVC, -# 'QMAKE_TARGET.arch' is inherently unavailable. +# modifications to g++-win32.conf QMAKE_CC = $${CROSS_COMPILE}gcc -QMAKE_LEX = flex -QMAKE_LEXFLAGS = -QMAKE_YACC = bison -y -QMAKE_YACCFLAGS = -d QMAKE_CFLAGS += -fno-keep-inline-dllexport QMAKE_CFLAGS_WARN_ON += -Wextra -QMAKE_CFLAGS_SSE2 += -mstackrealign - QMAKE_CXX = $${CROSS_COMPILE}g++ QMAKE_CXXFLAGS = $$QMAKE_CFLAGS QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -QMAKE_CXXFLAGS_RTTI_ON = -frtti -QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti -QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads - -QMAKE_INCDIR = - -QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src -QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< -QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src -QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< QMAKE_LINK = $${CROSS_COMPILE}g++ QMAKE_LINK_C = $${CROSS_COMPILE}gcc -QMAKE_LFLAGS_EXCEPTIONS_ON = -mthreads -QMAKE_LFLAGS_RELEASE = -Wl,-s -QMAKE_LFLAGS_CONSOLE = -Wl,-subsystem,console -QMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows -QMAKE_LFLAGS_DLL = -shared -QMAKE_LFLAGS_GCSECTIONS = -Wl,--gc-sections -equals(QMAKE_HOST.os, Windows) { - QMAKE_LINK_OBJECT_MAX = 10 - QMAKE_LINK_OBJECT_SCRIPT = object_script -} -QMAKE_EXT_OBJ = .o -QMAKE_EXT_RES = _res.o -QMAKE_PREFIX_SHLIB = -QMAKE_EXTENSION_SHLIB = dll -QMAKE_PREFIX_STATICLIB = lib -QMAKE_EXTENSION_STATICLIB = a -QMAKE_LIB_EXTENSIONS = a dll.a - -QMAKE_LIBS = -QMAKE_LIBS_GUI = -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lws2_32 -lole32 -luuid -luser32 -ladvapi32 -QMAKE_LIBS_NETWORK = -lws2_32 -QMAKE_LIBS_OPENGL = -lglu32 -lopengl32 -lgdi32 -luser32 -QMAKE_LIBS_OPENGL_ES2 = -lgdi32 -luser32 -QMAKE_LIBS_OPENGL_ES2_DEBUG = -lgdi32 -luser32 -QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32 -QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain - -QMAKE_IDL = midl -QMAKE_LIB = $${CROSS_COMPILE}ar -rc -QMAKE_RC = $${CROSS_COMPILE}windres - -QMAKE_STRIP = $${CROSS_COMPILE}strip -QMAKE_STRIPFLAGS_LIB += --strip-unneeded -QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy -QMAKE_NM = $${CROSS_COMPILE}nm -P load(qt_config) -- cgit v1.2.3 From bf87e1cfbd6c29a28e4ead8c9b41c578a1a5fba8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 17 Feb 2018 13:57:15 -0800 Subject: tst_QMimeDatabase: detect executables as shared libraries too They can be, if compiled with -Wl,-pie. Example: $ file /usr/bin/ping /usr/bin/ping: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0 And you can't detect via the interpreter, since libraries can have them too: $ file /lib64/libc-2.26.so libQt5Core.so.5.11.0 /lib64/libc-2.26.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2 libQt5Core.so.5.11.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.17.0 Change-Id: I940917d6763842499b18fffd15143bb80ce0e531 Reviewed-by: David Faure --- tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp index e3504de732..995fbc13c0 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp @@ -222,8 +222,10 @@ void tst_QMimeDatabase::mimeTypeForName() qWarning() << "ls not found"; else { const QString executableType = QString::fromLatin1("application/x-executable"); + const QString sharedLibType = QString::fromLatin1("application/x-sharedlib"); //QTest::newRow("executable") << exePath << executableType; - QCOMPARE(db.mimeTypeForFile(exePath).name(), executableType); + QVERIFY(db.mimeTypeForFile(exePath).name() == executableType || + db.mimeTypeForFile(exePath).name() == sharedLibType); } #endif -- cgit v1.2.3 From 604e5e340e63dee490a07b1d366c808dc86f7704 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 18 Feb 2018 09:47:59 -0800 Subject: Revert "JSON doc: update the RFC we link to" This reverts commit 71090f09509d52451e68b33e3e26807822849721. Changing the link was wrong because we do not actually comply with the new RFC. Task-number: QTBUG-66470 Change-Id: I940917d6763842499b18fffd15147cb93c27b7f4 Reviewed-by: Lars Knoll --- src/corelib/doc/src/json.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/doc/src/json.qdoc b/src/corelib/doc/src/json.qdoc index 4c7e62a10a..a32772f910 100644 --- a/src/corelib/doc/src/json.qdoc +++ b/src/corelib/doc/src/json.qdoc @@ -45,7 +45,7 @@ access. More details about the JSON data format can be found at \l{http://json.org}{json.org} - and in \l{https://tools.ietf.org/html/rfc7159}{RFC-7159}. + and in \l{http://tools.ietf.org/html/rfc4627}{RFC-4627}. \tableofcontents -- cgit v1.2.3 From 02eb264aa2db20fac479a749c39044cc9ed304b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pasi=20Pet=C3=A4j=C3=A4j=C3=A4rvi?= Date: Wed, 21 Feb 2018 11:26:09 +0200 Subject: Fix build when ftp feature is disabled Configuring Qt with -no-feature-ftp cause build to fail. Change-Id: I47f1cdc400702d0211a9f620c8606983f08fa70c Reviewed-by: Oswald Buddenhagen --- src/network/access/qnetworkaccessfilebackend.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/access/qnetworkaccessfilebackend.cpp b/src/network/access/qnetworkaccessfilebackend.cpp index a5e7daff11..d4ca9c22fc 100644 --- a/src/network/access/qnetworkaccessfilebackend.cpp +++ b/src/network/access/qnetworkaccessfilebackend.cpp @@ -46,6 +46,7 @@ #include "private/qnoncontiguousbytedevice_p.h" #include +#include QT_BEGIN_NAMESPACE -- cgit v1.2.3 From b97765efd452921f75c1d04820c4b5e9e9d49100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 21 Feb 2018 22:38:15 +0200 Subject: moc: Only use the init_priority attribute when targeting windows While both GCC and the GCC compatible clang support this attribute in general, GCC doesn't support it when targeting macOS, ending up with errors like these: error: 'init_priority' attribute is not supported on this platform This error isn't a property of the platform itself though, since clang supports the attribute just fine on macOS. The attribute is only used to work around an issue with dllimport on windows, so limit its use to that platform, to avoid issues with it potentially being unsupported on platforms other than macOS as well. This fixes compiling with GCC for macOS. Change-Id: I0235e6365635d73233951566c10ad869b26a0fc6 Reviewed-by: Thiago Macieira --- src/corelib/global/qglobal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index aa9446221b..cd4b4a29a9 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -549,7 +549,7 @@ using qsizetype = QIntegerForSizeof::Signed; # define Q_ALWAYS_INLINE inline #endif -#ifdef Q_CC_GNU +#if defined(Q_CC_GNU) && defined(Q_OS_WIN) # define QT_INIT_METAOBJECT __attribute__((init_priority(101))) #else # define QT_INIT_METAOBJECT -- cgit v1.2.3