From c36aa886833cee26a929a531326c814ba94decf8 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 13 Jan 2014 21:44:27 +0100 Subject: Fix the docs on when setDocument() deletes the previous document MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I08d162a1c1e1765213205e63183ed75b2491374d Reviewed-by: Jerome Pasion Reviewed-by: Topi Reiniö --- src/widgets/widgets/qtextedit.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp index e47abace4d..29538e1b70 100644 --- a/src/widgets/widgets/qtextedit.cpp +++ b/src/widgets/widgets/qtextedit.cpp @@ -755,8 +755,8 @@ Qt::Alignment QTextEdit::alignment() const \note The editor \e{does not take ownership of the document} unless it is the document's parent object. The parent object of the provided document - remains the owner of the object. The editor does not delete any previously - assigned document, even if it is a child of the editor. + remains the owner of the object. If the previously assigned document is a + child of the editor then it will be deleted. */ void QTextEdit::setDocument(QTextDocument *document) { -- cgit v1.2.3 From 845716d629cbb66d646cd61e8d3dc3acfe503889 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Tue, 28 Jan 2014 12:57:27 +0100 Subject: Doc: corrected description of QTableWidget::clear() Task-number: QTBUG-36329 Change-Id: I3a78311bcb076b414ecf1ecf866e4ed60c391126 Reviewed-by: Jerome Pasion --- src/widgets/itemviews/qtablewidget.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp index 71034f6165..bec690d0d0 100644 --- a/src/widgets/itemviews/qtablewidget.cpp +++ b/src/widgets/itemviews/qtablewidget.cpp @@ -2515,7 +2515,9 @@ void QTableWidget::removeColumn(int column) /*! Removes all items in the view. - This will also remove all selections. + This will also remove all selections and headers. + If you don't want to remove the headers, use + QTableWidget::clearContents(). The table dimensions stay the same. */ -- cgit v1.2.3 From c8172953ed6d3776178b9a37c0773d648cfdd9f2 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 31 Jan 2014 13:11:34 +0100 Subject: Fix printing with a custom paper specified. If DMPAPER_USER is set from the print dialog then it is expected that the specific member variables to get the custom width and length are used. The size returned by querying the DC_PAPERSIZE is some random default and is not the one actually requested by the user. Also ensure that when it is a custom paper size from the driver itself that we store the right paper size. Change-Id: I760b8429ca1b01f5e303f2111b8d7ca1795c8ab8 Reviewed-by: Friedemann Kleint --- src/printsupport/kernel/qprintengine_win.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp index fc462e9a0a..6fa75338aa 100644 --- a/src/printsupport/kernel/qprintengine_win.cpp +++ b/src/printsupport/kernel/qprintengine_win.cpp @@ -1959,13 +1959,17 @@ static void draw_text_item_win(const QPointF &pos, const QTextItemInt &ti, HDC h void QWin32PrintEnginePrivate::updateCustomPaperSize() { const uint paperSize = devMode->dmPaperSize; + const double multiplier = qt_multiplierForUnit(QPrinter::Millimeter, resolution); has_custom_paper_size = false; - if (paperSize > 0 && mapDevmodePaperSize(paperSize) == QPrinter::Custom) { + if (paperSize == DMPAPER_USER) { + has_custom_paper_size = true; + paper_size = QSizeF((devMode->dmPaperWidth / 10.0) * multiplier, (devMode->dmPaperLength / 10.0) * multiplier); + } else if (mapDevmodePaperSize(paperSize) == QPrinter::Custom) { has_custom_paper_size = true; const QList > paperSizes = printerPaperSizes(name); for (int i=0; i Date: Fri, 7 Feb 2014 10:21:49 +0100 Subject: Small doc fix. Change-Id: If700cce1b39342ca2b1027e2c10711ea45c3dd9c Reviewed-by: Oliver Wolff --- src/corelib/io/qurlidna.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qurlidna.cpp b/src/corelib/io/qurlidna.cpp index 988d076025..890a2260a2 100644 --- a/src/corelib/io/qurlidna.cpp +++ b/src/corelib/io/qurlidna.cpp @@ -2603,7 +2603,7 @@ QStringList QUrl::idnWhitelist() Note that if you call this function, you need to do so \e before you start any threads that might access idnWhitelist(). - Qt has comes a default list that contains the Internet top-level domains + Qt comes with a default list that contains the Internet top-level domains that have published support for Internationalized Domain Names (IDNs) and rules to guarantee that no deception can happen between similarly-looking characters (such as the Latin lowercase letter \c 'a' and the Cyrillic -- cgit v1.2.3 From 3f5060a60129225d8860b16953038fc9a214c1c1 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 3 Feb 2014 13:08:48 +0100 Subject: Compose: Fix assert for non-UTF8 locales in table generator Task-number: QTBUG-35770 Change-Id: I8aaea66e8d70edf7ab401f2c6dfb849d309ff6af Reviewed-by: Gatis Paeglis --- src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp index 11545b16c3..817c3f11bc 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp @@ -350,7 +350,7 @@ ushort TableGenerator::keysymToUtf8(quint32 sym) qDebug() << QString("keysym - 0x%1 : utf8 - %2").arg(QString::number(sym, 16)) .arg(codec->toUnicode(chars)); #endif - return QString::fromLocal8Bit(chars).at(0).unicode(); + return QString::fromUtf8(chars).at(0).unicode(); } static inline int fromBase8(const char *s, const char *end) -- cgit v1.2.3 From 99979159a404df09495c8ddd6a052837f66b8739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20K=C3=BCmmel?= Date: Fri, 7 Feb 2014 13:12:37 +0100 Subject: Fix linuxfb argument 'mmsize' parsing Parse first for 'mmsize' because the regex for 'size' also fits to 'mmsize'. Task-number: QTBUG-29133 Change-Id: Idc4950270818e496d5d94a97a172b7c780f069b1 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp index 735a43daf7..33a9523568 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp @@ -333,6 +333,8 @@ bool QLinuxFbScreen::initialize() foreach (const QString &arg, mArgs) { if (arg == QLatin1String("nographicsmodeswitch")) doSwitchToGraphicsMode = false; + else if (mmSizeRx.indexIn(arg) != -1) + userMmSize = QSize(mmSizeRx.cap(1).toInt(), mmSizeRx.cap(2).toInt()); else if (sizeRx.indexIn(arg) != -1) userGeometry.setSize(QSize(sizeRx.cap(1).toInt(), sizeRx.cap(2).toInt())); else if (offsetRx.indexIn(arg) != -1) @@ -341,8 +343,6 @@ bool QLinuxFbScreen::initialize() ttyDevice = ttyRx.cap(1); else if (fbRx.indexIn(arg) != -1) fbDevice = fbRx.cap(1); - else if (mmSizeRx.indexIn(arg) != -1) - userMmSize = QSize(mmSizeRx.cap(1).toInt(), mmSizeRx.cap(2).toInt()); } if (fbDevice.isEmpty()) { -- cgit v1.2.3 From b6b503fb6839de44530c4b88417f722c67570722 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 3 Feb 2014 16:14:53 +0100 Subject: Accessibility Win: handle disabled state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ChangeLog][QtGui] Windows Accessibility now handles the disabled state of widgets correctly. Task-number: QTBUG-36603 Change-Id: Ifebcf44320072089da66e81728de94e8f12a3354 Reviewed-by: Friedemann Kleint Reviewed-by: Jan Arve Sæther --- src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp index 8bb7646258..7c7c33616e 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp @@ -1027,6 +1027,8 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accState(VARIANT varID, VA st |= STATE_SYSTEM_SIZEABLE; if (state.traversed) st |= STATE_SYSTEM_TRAVERSED; + if (state.disabled) + st |= STATE_SYSTEM_UNAVAILABLE; (*pvarState).vt = VT_I4; (*pvarState).lVal = st; -- cgit v1.2.3 From 3e8af132dfaac5e16d5a2e3759aecc96726d8314 Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 7 Feb 2014 10:28:04 +0100 Subject: QStandardPaths: ensure that paths use '/' on all platforms, as the comment said Change-Id: Id70b5e92c07f63e71e7a1a8fb229f927d352ebdd Reviewed-by: Thiago Macieira --- tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index 21dfa5a962..5c0485d228 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -475,6 +475,8 @@ void tst_qstandardpaths::testAllWritableLocations() QString loc = QStandardPaths::writableLocation(location); if (loc.size() > 1) // workaround for unlikely case of locations that return '/' QCOMPARE(loc.endsWith(QLatin1Char('/')), false); + QVERIFY(loc.contains(QLatin1Char('/'))); + QVERIFY(!loc.contains(QLatin1Char('\\'))); } void tst_qstandardpaths::testCleanPath() -- cgit v1.2.3 From 85498fdedefdaaf0a6275bcb123d867a8509d643 Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 7 Feb 2014 10:25:31 +0100 Subject: QStandardPaths: remove trailing slash when reading from user-dirs.dirs For consistency with all other sources of paths, which do not return a trailing slash, as tested by the unittest. This avoids double slashes in paths, after apps append something to the path. Change-Id: Iabcde11eee27df0b185780e2b655fbbb02ed63b5 Reviewed-by: Thiago Macieira --- src/corelib/io/qstandardpaths_unix.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp index 1b9078f712..10ca20629e 100644 --- a/src/corelib/io/qstandardpaths_unix.cpp +++ b/src/corelib/io/qstandardpaths_unix.cpp @@ -205,6 +205,8 @@ QString QStandardPaths::writableLocation(StandardLocation type) // value can start with $HOME if (value.startsWith(QLatin1String("$HOME"))) value = QDir::homePath() + value.mid(5); + if (value.length() > 1 && value.endsWith(QLatin1Char('/'))) + value.chop(1); return value; } } -- cgit v1.2.3 From f34b7f42e5c9d2a50da51dbba5fa18467d0262c0 Mon Sep 17 00:00:00 2001 From: Dominik Haumann Date: Tue, 4 Feb 2014 19:00:09 +0100 Subject: QPA fix: allow setting the initially selected name filter (KDE) In KDE, without this patch, the Q_ASSERT in the following code fragment fails: QFileDialog dialog; QStringList list = QStringList() << "c (*.cpp)" << "h (*.h)"; dialog.setNameFilters(list); QString filter("h (*.h)"); dialog.selectNameFilter(filter); dialog.show(); Q_ASSERT(dialog.selectedNameFilter() == filter); The reason for the fail is that the selectNameFilter() does not properly propagate the filter to the QPA plugin. So the first part of this patch adds d->options->setInitiallySelectedNameFilter(filter); in the function QFileDialog::selectNameFilter(). The second part of this patch makes sure that the initially set name filter in the QFileDialogOptions "options" is not overwritten in the helperPrepareShow() function. This is achieved by adding an if(), following the if() for the initiallySelectedfiles() the line below. With this patch, the Q_ASSERT() holds true in KDE Framework 5's file dialog integration. Change-Id: I15d8c88a0fa3cdc03e3330f3458bbad139a71212 Reviewed-by: Kevin Ottens Reviewed-by: Friedemann Kleint Reviewed-by: Shawn Rutledge --- src/widgets/dialogs/qfiledialog.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index cd95b824a6..998866c039 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -627,7 +627,8 @@ void QFileDialogPrivate::helperPrepareShow(QPlatformDialogHelper *) options->setInitialDirectory(directory.exists() ? QUrl::fromLocalFile(directory.absolutePath()) : QUrl()); - options->setInitiallySelectedNameFilter(q->selectedNameFilter()); + if (options->initiallySelectedNameFilter().isEmpty()) + options->setInitiallySelectedNameFilter(q->selectedNameFilter()); if (options->initiallySelectedFiles().isEmpty()) options->setInitiallySelectedFiles(userSelectedFiles()); } @@ -1450,6 +1451,7 @@ QStringList QFileDialog::nameFilters() const void QFileDialog::selectNameFilter(const QString &filter) { Q_D(QFileDialog); + d->options->setInitiallySelectedNameFilter(filter); if (!d->usingWidgets()) { d->selectNameFilter_sys(filter); return; -- cgit v1.2.3 From 6f5db32abee3826151b9230ee7dca56ada4a3a89 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Wed, 5 Feb 2014 16:58:24 +0100 Subject: Don't deadlock when deleting slot objects in QMetaObject::activate() The slot object was deleted after the mutex was relocked, which caused a deadlock in case the functor destructor locked the same mutex again. Change-Id: I5b4fb22fdb4483f91c89915872bfd548c31b0eea Reviewed-by: Olivier Goffart --- src/corelib/kernel/qobject.cpp | 8 ++++- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 42 +++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 43b88d21b5..4cbb618233 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3561,9 +3561,15 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i const int method_relative = c->method_relative; if (c->isSlotObject) { c->slotObj->ref(); - const QScopedPointer obj(c->slotObj); + QScopedPointer obj(c->slotObj); locker.unlock(); obj->call(receiver, argv ? argv : empty_argv); + + // Make sure the slot object gets destroyed before the mutex is locked again, as the + // destructor of the slot object might also lock a mutex from the signalSlotLock() mutex pool, + // and that would deadlock if the pool happens to return the same mutex. + obj.reset(); + locker.relock(); } else if (callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) { //we compare the vtable to make sure we are not in the destructor of the object. diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index f1e04511cd..f0df10744d 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -146,6 +146,7 @@ private slots: void connectFunctorOverloads(); void connectFunctorQueued(); void connectFunctorWithContext(); + void connectFunctorDeadlock(); void connectStaticSlotWithObject(); void disconnectDoesNotLeakFunctor(); void contextDoesNotLeakFunctor(); @@ -5698,6 +5699,47 @@ void tst_QObject::connectFunctorWithContext() context->deleteLater(); } +class MyFunctor +{ +public: + explicit MyFunctor(QObject *objectToDisconnect) + : m_objectToDisconnect(objectToDisconnect) + {} + + ~MyFunctor() { + // Do operations that will lock the internal signalSlotLock mutex on many QObjects. + // The more QObjects, the higher the chance that the signalSlotLock mutex used + // is already in use. If the number of objects is higher than the number of mutexes in + // the pool (currently 131), the deadlock should always trigger. Use an even higher number + // to be on the safe side. + const int objectCount = 1024; + SenderObject lotsOfObjects[objectCount]; + for (int i = 0; i < objectCount; ++i) { + QObject::connect(&lotsOfObjects[i], &SenderObject::signal1, + &lotsOfObjects[i], &SenderObject::aPublicSlot); + } + } + + void operator()() { + // This will cause the slot object associated with this functor to be destroyed after + // this function returns. That in turn will destroy this functor. + // If our dtor runs with the signalSlotLock held, the bunch of connect() + // performed there will deadlock trying to lock that lock again. + m_objectToDisconnect->disconnect(); + } + +private: + QObject *m_objectToDisconnect; +}; + +void tst_QObject::connectFunctorDeadlock() +{ + SenderObject sender; + MyFunctor functor(&sender); + QObject::connect(&sender, &SenderObject::signal1, functor); + sender.emitSignal1(); +} + static int s_static_slot_checker = 1; class StaticSlotChecker : public QObject -- cgit v1.2.3 From 36af7fe678f41bbff2598b1e681a4a02ec3e2291 Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 7 Feb 2014 14:14:25 +0100 Subject: QDir::tempPath: make fallback code more readable. This is a no-op because QDir::cleanPath() already takes care of removing the trailing slash. Change-Id: Ic19d9a9dd7e377e04447c3ebc776b025f5f0c43a Reviewed-by: Friedemann Kleint --- src/corelib/io/qfilesystemengine_unix.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index e6b4e5f754..2327c11c69 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -721,13 +721,13 @@ QString QFileSystemEngine::tempPath() if (temp.isEmpty()) { qWarning("Neither the TEMP nor the TMPDIR environment variable is set, falling back to /tmp."); - temp = QLatin1String("/tmp/"); + temp = QLatin1String("/tmp"); } return QDir::cleanPath(temp); #else QString temp = QFile::decodeName(qgetenv("TMPDIR")); if (temp.isEmpty()) - temp = QLatin1String("/tmp/"); + temp = QLatin1String("/tmp"); return QDir::cleanPath(temp); #endif } -- cgit v1.2.3 From 4965cf78c1d9800944cec53babcf6be1cadf5940 Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 7 Feb 2014 14:16:19 +0100 Subject: QDir::tempPath: clarify trailing-slash situation. tst_QDir::tempPath already checks that there is no trailing slash. Except of course when the path is "/" or "C:/", but we can't do much about that unlikely corner case. Change-Id: If71d5de1aeebc6720348cecbf659b7fceb83fb0e Reviewed-by: Friedemann Kleint --- src/corelib/io/qdir.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index b704126efa..797dbbc0ec 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -1944,8 +1944,8 @@ QString QDir::homePath() On Unix/Linux systems this is the path in the \c TMPDIR environment variable or \c{/tmp} if \c TMPDIR is not defined. On Windows this is usually the path in the \c TEMP or \c TMP environment - variable. Whether a directory separator is added to the end or - not, depends on the operating system. + variable. + The path returned by this method doesn't end with a directory separator. \sa temp(), currentPath(), homePath(), rootPath() */ -- cgit v1.2.3 From 5c9d671bfb5b5111069aadc9bf3f742f369c74ae Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 7 Feb 2014 11:20:58 +0100 Subject: QStandardPaths: fix empty path in XDG_DATA_DIRS being treated as '/'. The basedir xdg spec says: "All paths set in these environment variables must be absolute. If an implementation encounters a relative path in any of these variables it should consider the path invalid and ignore it." Therefore we ignore relative paths including the empty string. Change-Id: I8f779b78981018051b16de23b2514f2e62b7ab39 Reviewed-by: Thiago Macieira --- src/corelib/io/qstandardpaths_unix.cpp | 15 +++++++++++---- .../auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp index 10ca20629e..e2ed7c3766 100644 --- a/src/corelib/io/qstandardpaths_unix.cpp +++ b/src/corelib/io/qstandardpaths_unix.cpp @@ -259,10 +259,17 @@ static QStringList xdgDataDirs() dirs.append(QString::fromLatin1("/usr/local/share")); dirs.append(QString::fromLatin1("/usr/share")); } else { - dirs = xdgDataDirsEnv.split(QLatin1Char(':')); - // Normalize paths - for (int i = 0; i < dirs.count(); i++) - dirs[i] = QDir::cleanPath(dirs.at(i)); + dirs = xdgDataDirsEnv.split(QLatin1Char(':'), QString::SkipEmptyParts); + + // Normalize paths, skip relative paths + QMutableListIterator it(dirs); + while (it.hasNext()) { + const QString dir = it.next(); + if (!dir.startsWith(QLatin1Char('/'))) + it.remove(); + else + it.setValue(QDir::cleanPath(dir)); + } // Remove duplicates from the list, there's no use for duplicated // paths in XDG_DATA_DIRS - if it's not found in the given diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index 5c0485d228..4503f6fcbc 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -77,6 +77,7 @@ private slots: void testAllWritableLocations_data(); void testAllWritableLocations(); void testCleanPath(); + void testXdgPathCleanup(); private: #ifdef Q_XDG_PLATFORM @@ -491,6 +492,19 @@ void tst_qstandardpaths::testCleanPath() } } +void tst_qstandardpaths::testXdgPathCleanup() +{ +#ifdef Q_XDG_PLATFORM + setCustomLocations(); + const QString uncleanGlobalAppDir = "/./" + QFile::encodeName(m_globalAppDir); + qputenv("XDG_DATA_DIRS", QFile::encodeName(uncleanGlobalAppDir) + "::relative/path"); + const QStringList appsDirs = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation); + QVERIFY(!appsDirs.contains("/applications")); + QVERIFY(!appsDirs.contains(uncleanGlobalAppDir + "/applications")); + QVERIFY(!appsDirs.contains("relative/path/applications")); +#endif +} + QTEST_MAIN(tst_qstandardpaths) #include "tst_qstandardpaths.moc" -- cgit v1.2.3 From 9ce3b0d9535a666ff05dea9bd4a6982c162ca9f8 Mon Sep 17 00:00:00 2001 From: David Faure Date: Sat, 1 Feb 2014 10:57:36 +0100 Subject: qdoc: fix memory leaks, unchecked open(), hardcoded path - in debugging code Change-Id: I3b065dd18f60214a858543d062dfb2f0f1dc1b36 Reviewed-by: Laurent Montel Reviewed-by: Oswald Buddenhagen Reviewed-by: Martin Smith --- src/tools/qdoc/generator.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/tools/qdoc/generator.cpp b/src/tools/qdoc/generator.cpp index b14a79dfab..71c550d4ab 100644 --- a/src/tools/qdoc/generator.cpp +++ b/src/tools/qdoc/generator.cpp @@ -246,16 +246,15 @@ QMultiMap outFileNames; */ void Generator::writeOutFileNames() { - QFile* files = new QFile("/Users/msmith/depot/qt5/qtdoc/outputlist.txt"); - files->open(QFile::WriteOnly); - QTextStream* filesout = new QTextStream(files); + QFile files("outputlist.txt"); + if (!files.open(QFile::WriteOnly)) + return; + QTextStream filesout(&files); QMultiMap::ConstIterator i = outFileNames.begin(); while (i != outFileNames.end()) { - (*filesout) << i.key() << "\n"; + filesout << i.key() << "\n"; ++i; } - filesout->flush(); - files->close(); } /*! -- cgit v1.2.3 From c8eb6d99d4bdb8a0549f1baf460c6a4b7aaf7045 Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 7 Feb 2014 15:56:19 +0100 Subject: Doc: fix typo in QDebugStateSaver docu Change-Id: I12e0a725141a570903004c63369c991d383ac82c Reviewed-by: Jerome Pasion --- src/corelib/io/qdebug.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp index 05920f4575..3370cce6d5 100644 --- a/src/corelib/io/qdebug.cpp +++ b/src/corelib/io/qdebug.cpp @@ -383,7 +383,7 @@ QDebugStateSaver::QDebugStateSaver(QDebug &dbg) } /*! - Destroyes a QDebugStateSaver instance, which restores the settings + Destroys a QDebugStateSaver instance, which restores the settings used when the QDebugStateSaver instance was created. \sa QDebug::setAutoInsertSpaces(), QDebug::autoInsertSpaces() -- cgit v1.2.3 From b96c075d22ce38048bedb860c04b74125720fb30 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 6 Feb 2014 11:46:03 +0100 Subject: Accessibility: Fix reporting the same name/value twice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NVDA for example reads name and value, so that most of our accessibles would lead to the same text being read twice in a row. Instead use Name as that's best supported on all platforms. [ChangedLog][QtWidgets] Fixed accessibility issues that would lead to screen readers reading the same text twice. Task-number: QTBUG-36678 Change-Id: I6c5c9cdcf5392c7135a65bd30f87a590c3c07fb4 Reviewed-by: Jan Arve Sæther --- src/plugins/accessible/widgets/itemviews.cpp | 2 -- src/plugins/accessible/widgets/qaccessiblewidgets.cpp | 2 +- src/plugins/accessible/widgets/simplewidgets.cpp | 4 +++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp index b477a6acb7..b24106d223 100644 --- a/src/plugins/accessible/widgets/itemviews.cpp +++ b/src/plugins/accessible/widgets/itemviews.cpp @@ -1068,7 +1068,6 @@ QString QAccessibleTableCell::text(QAccessible::Text t) const QAbstractItemModel *model = view->model(); QString value; switch (t) { - case QAccessible::Value: case QAccessible::Name: value = model->data(m_index, Qt::AccessibleTextRole).toString(); if (value.isEmpty()) @@ -1160,7 +1159,6 @@ QString QAccessibleTableHeaderCell::text(QAccessible::Text t) const QAbstractItemModel *model = view->model(); QString value; switch (t) { - case QAccessible::Value: case QAccessible::Name: value = model->headerData(index, orientation, Qt::AccessibleTextRole).toString(); if (value.isEmpty()) diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp index 79a5c82fe0..71d22eabc4 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp @@ -631,7 +631,7 @@ QDockWidget *QAccessibleDockWidget::dockWidget() const QString QAccessibleDockWidget::text(QAccessible::Text t) const { - if (t == QAccessible::Name || t == QAccessible::Value) { + if (t == QAccessible::Name) { return qt_accStripAmp(dockWidget()->windowTitle()); } return QString(); diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp index c275ec071d..893be2df04 100644 --- a/src/plugins/accessible/widgets/simplewidgets.cpp +++ b/src/plugins/accessible/widgets/simplewidgets.cpp @@ -507,8 +507,10 @@ QString QAccessibleGroupBox::text(QAccessible::Text t) const switch (t) { case QAccessible::Name: txt = qt_accStripAmp(groupBox()->title()); + break; case QAccessible::Description: - txt = qt_accStripAmp(groupBox()->title()); + txt = qt_accStripAmp(groupBox()->toolTip()); + break; default: break; } -- cgit v1.2.3 From 7f0d6c4529a7446e64d579514c3ab793517a457a Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Tue, 4 Feb 2014 14:51:58 +0100 Subject: Remove useless if MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ide9f06b71159e86fdd2aa178cd3aa0ab2faf5d2c Reviewed-by: Jan Arve Sæther --- src/widgets/accessible/qaccessiblewidget.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index 7b32cae54f..4e5fade3f4 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -425,10 +425,9 @@ QString QAccessibleWidget::text(QAccessible::Text t) const } break; case QAccessible::Description: - if (!widget()->accessibleDescription().isEmpty()) - str = widget()->accessibleDescription(); + str = widget()->accessibleDescription(); #ifndef QT_NO_TOOLTIP - else + if (str.isEmpty()) str = widget()->toolTip(); #endif break; -- cgit v1.2.3 From fbc554b42c6a1d0c06d39a54b991513d7ce2db12 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Jan 2014 14:45:44 -0800 Subject: Make QUrl::isLocalFile fast by storing a flag The XDG specification for file URIs requires us to use triple slashes in file:/// for URLs with absolute paths. I don't like special-casing any particular scheme, but we've done it for file for many years now. Since we need to test this situation in a couple of places, it's easier to just cache the result once, in setScheme (both functions). Change-Id: I078b45b5b6c861f4caee082b4730fd6f67684ae4 Reviewed-by: David Faure --- src/corelib/io/qurl.cpp | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index eac5a0b738..f17215964f 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -414,10 +414,16 @@ static inline QString fileScheme() return QStringLiteral("file"); } +#ifdef Q_COMPILER_CLASS_ENUM +# define colon_uchar : uchar +#else +# define colon_uchar +#endif + class QUrlPrivate { public: - enum Section { + enum Section colon_uchar { Scheme = 0x01, UserName = 0x02, Password = 0x04, @@ -432,6 +438,10 @@ public: FullUrl = 0xff }; + enum Flags colon_uchar { + IsLocalFile = 0x01 + }; + enum ErrorCode { // the high byte of the error code matches the Section // the first item in each value must be the generic "Invalid xxx Error" @@ -519,6 +529,8 @@ public: inline bool hasQuery() const { return sectionIsPresent & Query; } inline bool hasFragment() const { return sectionIsPresent & Fragment; } + inline bool isLocalFile() const { return flags & IsLocalFile; } + QString mergePaths(const QString &relativePath) const; QAtomicInt ref; @@ -539,12 +551,18 @@ public: // - Path (there's no path delimiter, so we optimize its use out of existence) // Schemes are never supposed to be empty, but we keep the flag anyway uchar sectionIsPresent; + uchar flags; + + // 32-bit: 2 bytes tail padding available + // 64-bit: 6 bytes tail padding available }; +#undef colon_uchar inline QUrlPrivate::QUrlPrivate() : ref(1), port(-1), error(0), - sectionIsPresent(0) + sectionIsPresent(0), + flags(0) { } @@ -558,7 +576,8 @@ inline QUrlPrivate::QUrlPrivate(const QUrlPrivate ©) query(copy.query), fragment(copy.fragment), error(copy.cloneError()), - sectionIsPresent(copy.sectionIsPresent) + sectionIsPresent(copy.sectionIsPresent), + flags(copy.flags) { } @@ -956,6 +975,12 @@ inline bool QUrlPrivate::setScheme(const QString &value, int len, bool doSetErro schemeData[i] = c + 0x20; } } + + // did we set to the file protocol? + if (scheme == fileScheme()) + flags |= IsLocalFile; + else + flags &= ~IsLocalFile; return true; } @@ -1312,6 +1337,7 @@ inline void QUrlPrivate::parse(const QString &url, QUrl::ParsingMode parsingMode // / other path types here sectionIsPresent = 0; + flags = 0; clearError(); // find the important delimiters @@ -1867,6 +1893,7 @@ void QUrl::setScheme(const QString &scheme) if (scheme.isEmpty()) { // schemes are not allowed to be empty d->sectionIsPresent &= ~QUrlPrivate::Scheme; + d->flags &= ~QUrlPrivate::IsLocalFile; d->scheme.clear(); } else { d->setScheme(scheme, scheme.length(), /* do set error */ true); @@ -3104,6 +3131,7 @@ QUrl QUrl::resolved(const QUrl &relative) const t.d->sectionIsPresent |= QUrlPrivate::Scheme; else t.d->sectionIsPresent &= ~QUrlPrivate::Scheme; + t.d->flags |= d->flags & QUrlPrivate::IsLocalFile; } t.d->fragment = relative.d->fragment; if (relative.d->hasFragment()) @@ -3177,7 +3205,6 @@ QString QUrl::toString(FormattingOptions options) const // - there's no query or fragment to return // that is, either they aren't present, or we're removing them // - it's a local file - // (test done last since it's the most expensive) if (options.testFlag(QUrl::PreferLocalFile) && !options.testFlag(QUrl::RemovePath) && (!d->hasQuery() || options.testFlag(QUrl::RemoveQuery)) && (!d->hasFragment() || options.testFlag(QUrl::RemoveFragment)) @@ -3201,6 +3228,7 @@ QString QUrl::toString(FormattingOptions options) const url += QLatin1String("//"); d->appendAuthority(url, options, QUrlPrivate::FullUrl); } else if (isLocalFile() && pathIsAbsolute) { + // Comply with the XDG file URI spec, which requires triple slashes. url += QLatin1String("//"); } @@ -3755,11 +3783,7 @@ QString QUrl::toLocalFile() const */ bool QUrl::isLocalFile() const { - if (!d) return false; - - if (d->scheme != fileScheme()) - return false; // not file - return true; + return d && d->isLocalFile(); } /*! -- cgit v1.2.3 From 2a3f6359537f0c975d9bb90bba208236bcecca8b Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 7 Feb 2014 14:35:04 +0100 Subject: Fix assert when converting RGBx8888 to ARGB32_PM RGBx8888 to ARGB32_PM is incorrectly using the RGBA8888 to ARGB32_PM which asserts the input format is RGBA8888. Since the routine also performs an unnecessy premul, we should be using a the generic rgba2argb routine. Change-Id: I7b67328f804f5f2a9664a35c04836679e8c8b8e5 Reviewed-by: Gunnar Sletta --- src/gui/image/qimage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 70fe7b783f..0b2211defc 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -3663,7 +3663,7 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, convert_RGBA_to_RGB, convert_RGBA_to_ARGB, - convert_RGBA_to_ARGB_PM, + convert_RGBA_to_ARGB, 0, 0, 0, -- cgit v1.2.3 From 15f3191981908b786b93e1e0dd7d6828e2bf18f9 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 7 Feb 2014 14:38:47 +0100 Subject: Fix drawing vertical gradients in RGBA8888 formats The RGBA8888 formats was incorrectly using the qt_gradient_quint32 which is argb specific. This caused vertical gradients but only vertical gradients to be drawn incorrectly. This changes the RGBA8888 formats formats to use the generic gradient method and renames qt_gradient_quint32 to qt_gradient_argb32 to indicate its limitation. Change-Id: Ia1cd48ca7f4f78b64f31d6263e81cd8ac3b0954e Reviewed-by: Gunnar Sletta --- src/gui/painting/qdrawhelper.cpp | 14 +++---- tests/auto/gui/painting/qpainter/tst_qpainter.cpp | 46 +++++++++++++++++++++++ 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index d3e5b645c4..c71d75cf94 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -5507,7 +5507,7 @@ inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer, } } -static void qt_gradient_quint32(int count, const QSpan *spans, void *userData) +static void qt_gradient_argb32(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); @@ -5964,7 +5964,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGB32, { blend_color_argb, - qt_gradient_quint32, + qt_gradient_argb32, qt_bitmapblit_quint32, qt_alphamapblit_quint32, qt_alphargbblit_quint32, @@ -5973,7 +5973,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_ARGB32, { blend_color_generic, - qt_gradient_quint32, + qt_gradient_argb32, qt_bitmapblit_quint32, qt_alphamapblit_quint32, qt_alphargbblit_quint32, @@ -5982,7 +5982,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_ARGB32_Premultiplied { blend_color_argb, - qt_gradient_quint32, + qt_gradient_argb32, qt_bitmapblit_quint32, qt_alphamapblit_quint32, qt_alphargbblit_quint32, @@ -6048,7 +6048,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGBX8888 { blend_color_generic, - qt_gradient_quint32, + blend_src_generic, qt_bitmapblit_quint32, #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN qt_alphamapblit_quint32, @@ -6062,7 +6062,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGBA8888 { blend_color_generic, - qt_gradient_quint32, + blend_src_generic, qt_bitmapblit_quint32, #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN qt_alphamapblit_quint32, @@ -6076,7 +6076,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGB8888_Premultiplied { blend_color_generic, - qt_gradient_quint32, + blend_src_generic, qt_bitmapblit_quint32, #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN qt_alphamapblit_quint32, diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 27c0f6e66a..4c4e46de05 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -201,6 +201,9 @@ private slots: void linearGradientSymmetry(); void gradientInterpolation(); + void gradientPixelFormat_data(); + void gradientPixelFormat(); + void fpe_pixmapTransform(); void fpe_zeroLengthLines(); void fpe_divByZero(); @@ -3723,6 +3726,49 @@ void tst_QPainter::linearGradientSymmetry() QCOMPARE(a, b); } +void tst_QPainter::gradientPixelFormat_data() +{ + QTest::addColumn("format"); + + QTest::newRow("argb32") << QImage::Format_ARGB32; + QTest::newRow("rgb32") << QImage::Format_RGB32; + QTest::newRow("rgb888") << QImage::Format_RGB888; + QTest::newRow("rgbx8888") << QImage::Format_RGBX8888; + QTest::newRow("rgba8888") << QImage::Format_RGBA8888; + QTest::newRow("rgba8888_pm") << QImage::Format_RGBA8888_Premultiplied; +} + +void tst_QPainter::gradientPixelFormat() +{ + QFETCH(QImage::Format, format); + + QImage a(8, 64, QImage::Format_ARGB32_Premultiplied); + QImage b(8, 64, format); + + + QGradientStops stops; + stops << qMakePair(qreal(0.0), QColor(Qt::blue)); + stops << qMakePair(qreal(0.3), QColor(Qt::red)); + stops << qMakePair(qreal(0.6), QColor(Qt::green)); + stops << qMakePair(qreal(1.0), QColor(Qt::black)); + + a.fill(0); + b.fill(0); + + QLinearGradient gradient(QRectF(b.rect()).topLeft(), QRectF(b.rect()).bottomLeft()); + gradient.setStops(stops); + + QPainter pa(&a); + pa.fillRect(a.rect(), gradient); + pa.end(); + + QPainter pb(&b); + pb.fillRect(b.rect(), gradient); + pb.end(); + + QCOMPARE(a, b.convertToFormat(QImage::Format_ARGB32_Premultiplied)); +} + void tst_QPainter::gradientInterpolation() { QImage image(256, 8, QImage::Format_ARGB32_Premultiplied); -- cgit v1.2.3 From c77222c0e711d584bec880222412fc50d044005f Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sun, 9 Feb 2014 00:46:40 +0200 Subject: Fix log_clusters calculation in HarfBuzz-NG code path The old code wasn't good enough to catch all the glyph (de)composition cases, thus leading to an assertion in QTextLayout's addNextCluster() helper. The new code catches all the corner cases and introduces somewhat better performance to the HB-NG shaper backend. Change-Id: I5b6c673395a4a039dc55b200abbf74b0ba5d0829 Reviewed-by: Ahmed Saidi Reviewed-by: Lars Knoll --- src/gui/text/qtextengine.cpp | 53 +++++++++++++------------------------------- 1 file changed, 16 insertions(+), 37 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index c2e352eff4..607fe95ab1 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1105,18 +1105,6 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st buffer_flags |= HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES; hb_buffer_set_flags(buffer, hb_buffer_flags_t(buffer_flags)); - const uint num_codes = hb_buffer_get_length(buffer); - { - // adjust clusters - hb_glyph_info_t *infos = hb_buffer_get_glyph_infos(buffer, 0); - const ushort *uc = string + item_pos; - for (uint i = 0, code_pos = 0; i < item_length; ++i, ++code_pos) { - if (QChar::isHighSurrogate(uc[i]) && i + 1 < item_length && QChar::isLowSurrogate(uc[i + 1])) - ++i; - infos[code_pos].cluster = code_pos + item_glyph_pos; - } - } - // shape bool shapedOk = false; @@ -1139,8 +1127,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st if (si.analysis.bidiLevel % 2) hb_buffer_reverse(buffer); - - remaining_glyphs -= num_codes; + remaining_glyphs -= item_glyph_pos; // ensure we have enough space for shaped glyphs and metrics const uint num_glyphs = hb_buffer_get_length(buffer); @@ -1151,44 +1138,36 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st // fetch the shaped glyphs and metrics QGlyphLayout g = availableGlyphs(&si).mid(glyphs_shaped, num_glyphs); - if (num_glyphs > num_codes) - moveGlyphData(g.mid(num_glyphs), g.mid(num_codes), remaining_glyphs); + if (num_glyphs != item_glyph_pos) + moveGlyphData(g.mid(num_glyphs), g.mid(item_glyph_pos), remaining_glyphs); ushort *log_clusters = logClusters(&si) + item_pos; hb_glyph_info_t *infos = hb_buffer_get_glyph_infos(buffer, 0); hb_glyph_position_t *positions = hb_buffer_get_glyph_positions(buffer, 0); - uint last_cluster = -1; + uint str_pos = 0; + uint last_cluster = ~0u; + uint last_glyph_pos = glyphs_shaped; for (uint i = 0; i < num_glyphs; ++i) { g.glyphs[i] = infos[i].codepoint; - log_clusters[i] = infos[i].cluster; g.advances_x[i] = QFixed::fromFixed(positions[i].x_advance); g.advances_y[i] = QFixed::fromFixed(positions[i].y_advance); g.offsets[i].x = QFixed::fromFixed(positions[i].x_offset); g.offsets[i].y = QFixed::fromFixed(positions[i].y_offset); - if (infos[i].cluster != last_cluster) { - last_cluster = infos[i].cluster; + uint cluster = infos[i].cluster; + if (last_cluster != cluster) { + // fix up clusters so that the cluster indices will be monotonic + // and thus we never return out-of-order indices + while (last_cluster++ < cluster && str_pos < item_length) + log_clusters[str_pos++] = last_glyph_pos; + last_glyph_pos = i + glyphs_shaped; + last_cluster = cluster; g.attributes[i].clusterStart = true; } } - - { - // adjust clusters - uint glyph_pos = 0; - for (uint i = 0; i < item_length; ++i) { - if (i + item_pos != infos[glyph_pos].cluster) { - for (uint j = glyph_pos + 1; j < num_glyphs; ++j) { - if (i + item_pos <= infos[j].cluster) { - if (i + item_pos == infos[j].cluster) - glyph_pos = j; - break; - } - } - } - log_clusters[i] = glyph_pos + item_glyph_pos; - } - } + while (str_pos < item_length) + log_clusters[str_pos++] = last_glyph_pos; if (engineIdx != 0) { for (quint32 i = 0; i < num_glyphs; ++i) -- cgit v1.2.3 From bbdea065aaad89de5b2f9e32ffbacd40abf5173a Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sun, 9 Feb 2014 06:37:51 +0200 Subject: Minor optimization for QTextEngine::shapeText() Remember the engine index for each sub-item and avoid moveGlyphData() where possible (ie. when there are no glyph indexes to care about). Also don't memmove data we didn't ever initialize. Change-Id: Ib8e5fd937a10e4e3c8c0e18961a2e2c1a4167924 Reviewed-by: Ahmed Saidi Reviewed-by: Lars Knoll --- src/gui/text/qtextengine.cpp | 79 ++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 43 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 607fe95ab1..febdaaa86c 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -918,12 +918,9 @@ void QTextEngine::shapeText(int item) const QFontEngine *fontEngine = this->fontEngine(si, &si.ascent, &si.descent, &si.leading); // split up the item into parts that come from different font engines + // k * 3 entries, array[k] == index in string, array[k + 1] == index in glyphs, array[k + 2] == engine index QVector itemBoundaries; - itemBoundaries.reserve(16); - // k * 2 entries, array[k] == index in string, array[k + 1] == index in glyphs - itemBoundaries.append(0); - itemBoundaries.append(0); - + itemBoundaries.reserve(24); if (fontEngine->type() == QFontEngine::Multi) { // ask the font engine to find out which glyphs (as an index in the specific font) // to use for the text in one item. @@ -947,22 +944,31 @@ void QTextEngine::shapeText(int item) const } } - uint lastEngine = 0; + uint lastEngine = ~0u; for (int i = 0, glyph_pos = 0; i < itemLength; ++i, ++glyph_pos) { const uint engineIdx = initialGlyphs.glyphs[glyph_pos] >> 24; - if (lastEngine != engineIdx && glyph_pos > 0) { + if (lastEngine != engineIdx) { itemBoundaries.append(i); itemBoundaries.append(glyph_pos); + itemBoundaries.append(engineIdx); + + if (engineIdx != 0) { + QFontEngine *actualFontEngine = static_cast(fontEngine)->engine(engineIdx); + si.ascent = qMax(actualFontEngine->ascent(), si.ascent); + si.descent = qMax(actualFontEngine->descent(), si.descent); + si.leading = qMax(actualFontEngine->leading(), si.leading); + } - QFontEngine *actualFontEngine = static_cast(fontEngine)->engine(engineIdx); - si.ascent = qMax(actualFontEngine->ascent(), si.ascent); - si.descent = qMax(actualFontEngine->descent(), si.descent); - si.leading = qMax(actualFontEngine->leading(), si.leading); + lastEngine = engineIdx; } - lastEngine = engineIdx; + if (QChar::isHighSurrogate(string[i]) && i + 1 < itemLength && QChar::isLowSurrogate(string[i + 1])) ++i; } + } else { + itemBoundaries.append(0); + itemBoundaries.append(0); + itemBoundaries.append(0); } bool kerningEnabled; @@ -1039,16 +1045,6 @@ void QTextEngine::shapeText(int item) const si.width += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint; } -static inline void moveGlyphData(const QGlyphLayout &destination, const QGlyphLayout &source, int num) -{ - if (num > 0 && destination.glyphs != source.glyphs) { - memmove(destination.glyphs, source.glyphs, num * sizeof(glyph_t)); - memmove(destination.attributes, source.attributes, num * sizeof(QGlyphAttributes)); - memmove(destination.advances_x, source.advances_x, num * sizeof(QFixed)); - memmove(destination.offsets, source.offsets, num * sizeof(QFixedPoint)); - } -} - #ifdef QT_ENABLE_HARFBUZZ_NG QT_BEGIN_INCLUDE_NAMESPACE @@ -1075,20 +1071,15 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st uint glyphs_shaped = 0; int remaining_glyphs = itemLength; - for (int k = 0; k < itemBoundaries.size(); k += 2) { // for the +2, see the comment at the definition of itemBoundaries + for (int k = 0; k < itemBoundaries.size(); k += 3) { uint item_pos = itemBoundaries[k]; - uint item_length = itemLength; + uint item_length = (k + 4 < itemBoundaries.size() ? itemBoundaries[k + 3] : itemLength) - item_pos; uint item_glyph_pos = itemBoundaries[k + 1]; - if (k + 3 < itemBoundaries.size()) - item_length = itemBoundaries[k + 2]; - item_length -= item_pos; + uint engineIdx = itemBoundaries[k + 2]; QFontEngine *actualFontEngine = fontEngine; - uint engineIdx = 0; - if (fontEngine->type() == QFontEngine::Multi) { - engineIdx = availableGlyphs(&si).glyphs[glyphs_shaped] >> 24; + if (fontEngine->type() == QFontEngine::Multi) actualFontEngine = static_cast(fontEngine)->engine(engineIdx); - } // prepare buffer @@ -1138,8 +1129,6 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st // fetch the shaped glyphs and metrics QGlyphLayout g = availableGlyphs(&si).mid(glyphs_shaped, num_glyphs); - if (num_glyphs != item_glyph_pos) - moveGlyphData(g.mid(num_glyphs), g.mid(item_glyph_pos), remaining_glyphs); ushort *log_clusters = logClusters(&si) + item_pos; hb_glyph_info_t *infos = hb_buffer_get_glyph_infos(buffer, 0); @@ -1196,6 +1185,12 @@ Q_STATIC_ASSERT(sizeof(HB_GlyphAttributes) == sizeof(QGlyphAttributes)); Q_STATIC_ASSERT(sizeof(HB_Fixed) == sizeof(QFixed)); Q_STATIC_ASSERT(sizeof(HB_FixedPoint) == sizeof(QFixedPoint)); +static inline void moveGlyphData(const QGlyphLayout &destination, const QGlyphLayout &source, int num) +{ + if (num > 0 && destination.glyphs != source.glyphs) + memmove(destination.glyphs, source.glyphs, num * sizeof(glyph_t)); +} + int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector &itemBoundaries, bool kerningEnabled) const { HB_ShaperItem entire_shaper_item; @@ -1224,14 +1219,12 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri int remaining_glyphs = entire_shaper_item.num_glyphs; int glyph_pos = 0; // for each item shape using harfbuzz and store the results in our layoutData's glyphs array. - for (int k = 0; k < itemBoundaries.size(); k += 2) { // for the +2, see the comment at the definition of itemBoundaries - + for (int k = 0; k < itemBoundaries.size(); k += 3) { HB_ShaperItem shaper_item = entire_shaper_item; - shaper_item.item.pos = itemBoundaries[k]; - if (k < itemBoundaries.size() - 3) { - shaper_item.item.length = itemBoundaries[k + 2] - shaper_item.item.pos; - shaper_item.num_glyphs = itemBoundaries[k + 3] - itemBoundaries[k + 1]; + if (k + 4 < itemBoundaries.size()) { + shaper_item.item.length = itemBoundaries[k + 3] - shaper_item.item.pos; + shaper_item.num_glyphs = itemBoundaries[k + 4] - itemBoundaries[k + 1]; } else { // last combo in the list, avoid out of bounds access. shaper_item.item.length -= shaper_item.item.pos - entire_shaper_item.item.pos; shaper_item.num_glyphs -= itemBoundaries[k + 1]; @@ -1240,10 +1233,9 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri if (shaper_item.num_glyphs < shaper_item.item.length) shaper_item.num_glyphs = shaper_item.item.length; + uint engineIdx = itemBoundaries[k + 2]; QFontEngine *actualFontEngine = fontEngine; - uint engineIdx = 0; if (fontEngine->type() == QFontEngine::Multi) { - engineIdx = uint(availableGlyphs(&si).glyphs[glyph_pos] >> 24); actualFontEngine = static_cast(fontEngine)->engine(engineIdx); shaper_item.glyphIndicesPresent = true; @@ -1259,7 +1251,7 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri return 0; const QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos); - if (shaper_item.num_glyphs > shaper_item.item.length) + if (fontEngine->type() == QFontEngine::Multi && shaper_item.num_glyphs > shaper_item.item.length) moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs); shaper_item.glyphs = reinterpret_cast(g.glyphs); @@ -1276,7 +1268,8 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri } while (!qShapeItem(&shaper_item)); // this does the actual shaping via harfbuzz. QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos, shaper_item.num_glyphs); - moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs); + if (fontEngine->type() == QFontEngine::Multi) + moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs); for (quint32 i = 0; i < shaper_item.item.length; ++i) shaper_item.log_clusters[i] += glyph_pos; -- cgit v1.2.3 From dc05fe7a5b0ca1dda691f5ec04b91800c93adbb5 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 10 Feb 2014 11:53:46 +0100 Subject: Fix out-of-tree compilation of widget examples 'styles' are only defined in the qt build internals, when the examples are compiled inside a configured Qt source. That's not the case for the examples e.g. in the Qt SDK. (windows is a default style on all platforms, anyway. So I think the check is superfluous in the first place.) Task-number: QTBUG-36655 Change-Id: I7114619efd479408dad99c8514f8e33ddcab7c7c Reviewed-by: Marc Mutz --- examples/widgets/widgets/styles/styles.pro | 2 -- examples/widgets/widgets/widgets.pro | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/widgets/widgets/styles/styles.pro b/examples/widgets/widgets/styles/styles.pro index e326991535..235642f270 100644 --- a/examples/widgets/widgets/styles/styles.pro +++ b/examples/widgets/widgets/styles/styles.pro @@ -7,8 +7,6 @@ SOURCES = main.cpp \ widgetgallery.cpp RESOURCES = styles.qrc -REQUIRES += "contains(styles, windows)" - # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/styles INSTALLS += target diff --git a/examples/widgets/widgets/widgets.pro b/examples/widgets/widgets/widgets.pro index 8d9e15a7e8..fe3e289944 100644 --- a/examples/widgets/widgets/widgets.pro +++ b/examples/widgets/widgets/widgets.pro @@ -16,6 +16,7 @@ SUBDIRS = analogclock \ shapedclock \ sliders \ spinboxes \ + styles \ stylesheet \ tablet \ tetrix \ @@ -23,5 +24,3 @@ SUBDIRS = analogclock \ validators \ wiggly \ windowflags - -contains(styles, windows): SUBDIRS += styles -- cgit v1.2.3 From 1865104d9e937a6fa643a20f68a7b13f2acb0319 Mon Sep 17 00:00:00 2001 From: David Faure Date: Mon, 10 Feb 2014 14:16:16 +0100 Subject: Doc: Adjust QDir::tempPath docu as recommended by Ossi. Change-Id: I709d8ce8151f2bb480865067a3e80ed838b26e4a Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qdir.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 797dbbc0ec..c5a0db310a 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -1945,7 +1945,8 @@ QString QDir::homePath() variable or \c{/tmp} if \c TMPDIR is not defined. On Windows this is usually the path in the \c TEMP or \c TMP environment variable. - The path returned by this method doesn't end with a directory separator. + The path returned by this method doesn't end with a directory separator + unless it is the root directory (of a drive). \sa temp(), currentPath(), homePath(), rootPath() */ -- cgit v1.2.3 From 5428db88de40378d0419aea40515d98241d733bc Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 7 Feb 2014 14:42:05 +0100 Subject: Document `moc -f<...>` behavior change in Qt-5.2.0 Better late than never :) Task-number: QTBUG-33749 Change-Id: I5035255e66a56754b609441f5b81ab119565a7cb Reviewed-by: Olivier Goffart --- dist/changes-5.2.0 | 7 +++++++ src/tools/moc/main.cpp | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/dist/changes-5.2.0 b/dist/changes-5.2.0 index 0e3f18929a..56997a11d4 100644 --- a/dist/changes-5.2.0 +++ b/dist/changes-5.2.0 @@ -768,3 +768,10 @@ X11 * [QTBUG-34392][MSVS] Fixed /SAFESEH:NO with VS2010+. * [QTBUG-34357][MSVS] Fixed breakage with multiple VS versions in PATH. * [MSVS] Fixed sub-project dependency generation. + +- moc + * Porting moc to QCommandLineParser has changed one specific option in its + command line handling: using the -f option without argument + is not supported anymore (it wasn't necessary, since including the header + file is the default behavior). + diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp index 0a5f6ec241..9f5bd46ef4 100644 --- a/src/tools/moc/main.cpp +++ b/src/tools/moc/main.cpp @@ -258,7 +258,7 @@ int runMoc(int argc, char **argv) parser.addOption(pathPrefixOption); QCommandLineOption forceIncludeOption(QStringLiteral("f")); - forceIncludeOption.setDescription(QStringLiteral("Force #include [optional ] (overwrite default).")); + forceIncludeOption.setDescription(QStringLiteral("Force #include (overwrite default).")); forceIncludeOption.setValueName(QStringLiteral("file")); parser.addOption(forceIncludeOption); -- cgit v1.2.3 From cbc6387a2885b17c372d14ceee87c1fba893b97b Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 10 Feb 2014 17:11:08 +0100 Subject: support c'tor as second parameter in foreach macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Passing a constructor as second argument to foreach didn't work when building with gcc. For MSVC this already worked as a different foreach implementation is used. Change-Id: Id98444c699b4cebc14ea62076c5f7cba33ffb824 Reviewed-by: hjk Reviewed-by: Jędrzej Nowacki --- src/corelib/global/qglobal.h | 2 +- tests/auto/corelib/global/qglobal/tst_qglobal.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 30db4e75cf..cd3b0fe71c 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -858,7 +858,7 @@ public: }; #define Q_FOREACH(variable, container) \ -for (QForeachContainer<__typeof__(container)> _container_(container); \ +for (QForeachContainer<__typeof__((container))> _container_((container)); \ !_container_.brk && _container_.i != _container_.e; \ __extension__ ({ ++_container_.brk; ++_container_.i; })) \ for (variable = *_container_.i;; __extension__ ({--_container_.brk; break;})) diff --git a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp index 0d08e912f8..4eb3e4fc98 100644 --- a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp +++ b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp @@ -101,6 +101,13 @@ void tst_QGlobal::for_each() QCOMPARE(i, counter++); } QCOMPARE(counter, list.count()); + + // check whether we can pass a constructor as container argument + counter = 0; + foreach (int i, QList(list)) { + QCOMPARE(i, counter++); + } + QCOMPARE(counter, list.count()); } void tst_QGlobal::qassert() -- cgit v1.2.3 From 12769d539cbade306b0b18840d131064b7e50c77 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Tue, 14 Jan 2014 12:48:10 +0100 Subject: Doc: Fix issues with QOpenGLTexture enumerations Use correct parameters for \enum commands, and add documentation for QOpenGLTexture::Filter enumeration. Task-number: QTBUG-35576 Change-Id: If7099da0b2b570c28e683126f0ba3a885d80f741 Reviewed-by: Sean Harmer --- src/gui/opengl/qopengltexture.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index e3fffe5a1c..d9b2e82d0b 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -1098,6 +1098,17 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target would be to transform your texture coordinates. */ +/*! + \enum QOpenGLTexture::Filter + This enum defines the filtering parameters for a QOpenGLTexture object. + \value Nearest Equivalent to GL_NEAREST + \value Linear Equivalent to GL_LINEAR + \value NearestMipMapNearest Equivalent to GL_NEAREST_MIPMAP_NEAREST + \value NearestMipMapLinear Equivalent to GL_NEAREST_MIPMAP_LINEAR + \value LinearMipMapNearest Equivalent to GL_LINEAR_MIPMAP_NEAREST + \value LinearMipMapLinear Equivalent to GL_LINEAR_MIPMAP_LINEAR +*/ + /*! \enum QOpenGLTexture::Target This enum defines the texture target of a QOpenGLTexture object. @@ -1152,7 +1163,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target */ /*! - \enum TextureUnitReset + \enum QOpenGLTexture::TextureUnitReset This enum defines options ot control texture unit activation. \value ResetTextureUnit The previous active texture unit will be reset @@ -1308,7 +1319,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target */ /*! - \enum PixelType + \enum QOpenGLTexture::PixelType This enum defines the possible pixel data types for a pixel transfer operation \value NoPixelType Equivalent to GL_NONE @@ -1381,7 +1392,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target */ /*! - \enum WrapMode + \enum QOpenGLTexture::WrapMode This enum defines the possible texture coordinate wrapping modes. \value Repeat Texture coordinate is repeated. Equivalent to GL_REPEAT @@ -1392,7 +1403,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target */ /*! - \enum CoordinateDirection + \enum QOpenGLTexture::CoordinateDirection This enum defines the possible texture coordinate directions \value DirectionS The horizontal direction. Equivalent to GL_TEXTURE_WRAP_S -- cgit v1.2.3 From c5042d68eaf8ca360c3183e284b200d58d1a0479 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Fri, 7 Feb 2014 15:06:53 +0100 Subject: network tests: do not rely on external servers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They cause test failures from time to time. Change-Id: I917bef340401d25bf54e133be9d9562b3b133c9f Reviewed-by: Jędrzej Nowacki Reviewed-by: Niels Weber Reviewed-by: Thiago Macieira Reviewed-by: Richard J. Moore --- .../access/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/auto/network/access/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp b/tests/auto/network/access/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp index 47ab7c2e99..8e0090e486 100644 --- a/tests/auto/network/access/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp +++ b/tests/auto/network/access/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp @@ -160,7 +160,6 @@ void tst_QHttpNetworkConnection::head_data() QTest::addColumn("contentLength"); QTest::newRow("success-internal") << "http://" << QtNetworkSettings::serverName() << "/qtest/rfc3252.txt" << ushort(80) << false << 200 << "OK" << 25962; - QTest::newRow("success-external") << "http://" << "www.ietf.org" << "/rfc/rfc3252.txt" << ushort(80) << false << 200 << "OK" << 25962; QTest::newRow("failure-path") << "http://" << QtNetworkSettings::serverName() << "/t" << ushort(80) << false << 404 << "Not Found" << -1; QTest::newRow("failure-protocol") << "" << QtNetworkSettings::serverName() << "/qtest/rfc3252.txt" << ushort(80) << false << 400 << "Bad Request" << -1; @@ -217,7 +216,6 @@ void tst_QHttpNetworkConnection::get_data() QTest::addColumn("downloadSize"); QTest::newRow("success-internal") << "http://" << QtNetworkSettings::serverName() << "/qtest/rfc3252.txt" << ushort(80) << false << 200 << "OK" << 25962 << 25962; - QTest::newRow("success-external") << "http://" << "www.ietf.org" << "/rfc/rfc3252.txt" << ushort(80) << false << 200 << "OK" << 25962 << 25962; QTest::newRow("failure-path") << "http://" << QtNetworkSettings::serverName() << "/t" << ushort(80) << false << 404 << "Not Found" << -1 << -1; QTest::newRow("failure-protocol") << "" << QtNetworkSettings::serverName() << "/qtest/rfc3252.txt" << ushort(80) << false << 400 << "Bad Request" << -1 << -1; -- cgit v1.2.3 From 2a68cffa843572b2a90780758c5c4eaa7c694c48 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Fri, 7 Feb 2014 17:55:08 +0100 Subject: Accessibility Linux: Report Active state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The fixme comment is invalid since QAccessibleWidget actually checks for isWindow and sets the active state. This is messed up because in Qt 4 there was a work-around to set active for windows in a different code path. [ChangeLog][QtGui] Accessibility on Linux now reports the active state correctly. Change-Id: I9e2cf436b3ffa7ef28286ee49d6e582f179930c6 Reviewed-by: Jan Arve Sæther --- src/platformsupport/linuxaccessibility/atspiadaptor.cpp | 7 ------- src/platformsupport/linuxaccessibility/constant_mappings.cpp | 2 ++ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp index 8850f18bab..1ccab0a859 100644 --- a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp +++ b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp @@ -1391,13 +1391,6 @@ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QS if (interface->tableInterface()) { setSpiStateBit(&spiState, ATSPI_STATE_MANAGES_DESCENDANTS); } -// FIXME: figure out if this is a top level window and set its active state accordingly -// if (interface->object() && interface->object()->isWidgetType()) { -// QWidget *w = qobject_cast(interface->object()); -// if (w->topLevelWidget() && w->isActiveWindow()) { -// setSpiStateBit(&spiState, ATSPI_STATE_ACTIVE); -// } -// } QAccessible::Role role = interface->role(); if (role == QAccessible::TreeItem || role == QAccessible::ListItem) { diff --git a/src/platformsupport/linuxaccessibility/constant_mappings.cpp b/src/platformsupport/linuxaccessibility/constant_mappings.cpp index f8bfaf4753..9de667158b 100644 --- a/src/platformsupport/linuxaccessibility/constant_mappings.cpp +++ b/src/platformsupport/linuxaccessibility/constant_mappings.cpp @@ -61,6 +61,8 @@ quint64 spiStatesFromQState(QAccessible::State state) { quint64 spiState = 0; + if (state.active) + setSpiStateBit(&spiState, ATSPI_STATE_ACTIVE); if (state.editable) setSpiStateBit(&spiState, ATSPI_STATE_EDITABLE); if (!state.disabled) { -- cgit v1.2.3 From be51772d023161c81978b3a63b6379d4ebb8013f Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Mon, 10 Feb 2014 11:00:00 +0100 Subject: Cleanup TSLib plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch cleans up the coding style and includes Change-Id: I710d4a60795e9975d4f8ee79599018e05d85debe Reviewed-by: Jørgen Lind Reviewed-by: Laszlo Agocs --- src/plugins/generic/tslib/qtslib.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/plugins/generic/tslib/qtslib.cpp b/src/plugins/generic/tslib/qtslib.cpp index 773939b485..9905d9cc9e 100644 --- a/src/plugins/generic/tslib/qtslib.cpp +++ b/src/plugins/generic/tslib/qtslib.cpp @@ -48,8 +48,6 @@ #include #include -#include - #include #include @@ -65,21 +63,21 @@ QTsLibMouseHandler::QTsLibMouseHandler(const QString &key, setObjectName(QLatin1String("TSLib Mouse Handler")); QByteArray device = qgetenv("TSLIB_TSDEVICE"); - if (device.isEmpty()) - device = QByteArrayLiteral("/dev/input/event1"); if (specification.startsWith("/dev/")) device = specification.toLocal8Bit(); + if (device.isEmpty()) + device = QByteArrayLiteral("/dev/input/event1"); + m_dev = ts_open(device.constData(), 1); if (!m_dev) { qErrnoWarning(errno, "ts_open() failed"); return; } - if (ts_config(m_dev)) { + if (ts_config(m_dev)) perror("Error configuring\n"); - } m_rawMode = !key.compare(QLatin1String("TslibRaw"), Qt::CaseInsensitive); @@ -89,7 +87,6 @@ QTsLibMouseHandler::QTsLibMouseHandler(const QString &key, connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData())); } else { qWarning("Cannot open mouse input device '%s': %s", device.constData(), strerror(errno)); - return; } } @@ -103,12 +100,10 @@ QTsLibMouseHandler::~QTsLibMouseHandler() static bool get_sample(struct tsdev *dev, struct ts_sample *sample, bool rawMode) { - if (rawMode) { + if (rawMode) return (ts_read_raw(dev, sample, 1) == 1); - } else { - int ret = ts_read(dev, sample, 1); - return ( ret == 1); - } + else + return (ts_read(dev, sample, 1) == 1); } -- cgit v1.2.3 From 4d6cb199b828256cb78ff986f2c1a508b339d2ee Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 5 Feb 2014 11:48:51 +0100 Subject: Make QToolButtonPrivate::popupTimerDone() more robust MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid dereferencing the q-pointer if the button has been destructed meanwhile popup was open. Task-number: QTBUG-26956 Change-Id: I68190e9fe84c669229ae0ce4d573ee7a02a8a141 Reviewed-by: Ivan Komissarov Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/widgets/qtoolbutton.cpp | 7 ++++--- tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp | 10 ++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/widgets/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp index f08689cb9b..497bc52109 100644 --- a/src/widgets/widgets/qtoolbutton.cpp +++ b/src/widgets/widgets/qtoolbutton.cpp @@ -778,15 +778,16 @@ void QToolButtonPrivate::popupTimerDone() actualMenu->d_func()->causedPopup.action = defaultAction; actionsCopy = q->actions(); //(the list of action may be modified in slots) actualMenu->exec(p); + + if (!that) + return; + QObject::disconnect(actualMenu, SIGNAL(aboutToHide()), q, SLOT(_q_updateButtonDown())); if (mustDeleteActualMenu) delete actualMenu; else QObject::disconnect(actualMenu, SIGNAL(triggered(QAction*)), q, SLOT(_q_menuTriggered(QAction*))); - if (!that) - return; - actionsCopy.clear(); if (repeat) diff --git a/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp b/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp index cebd4883a4..aaff322c4b 100644 --- a/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp +++ b/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp @@ -63,6 +63,7 @@ private slots: void collapseTextOnPriority(); void task230994_iconSize(); void task176137_autoRepeatOfAction(); + void qtbug_26956_popupTimerDone(); protected slots: void sendMouseClick(); @@ -223,5 +224,14 @@ void tst_QToolButton::sendMouseClick() QTest::mouseClick(w, Qt::LeftButton, 0, QPoint(7,7)); } +void tst_QToolButton::qtbug_26956_popupTimerDone() +{ + QToolButton *tb = new QToolButton; + tb->setMenu(new QMenu(tb)); + tb->menu()->addAction("Qt"); + tb->deleteLater(); + tb->showMenu(); +} + QTEST_MAIN(tst_QToolButton) #include "tst_qtoolbutton.moc" -- cgit v1.2.3 From 8f899cd19837e91b52fbeef184a21423bd27815e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Sat, 8 Feb 2014 00:11:56 +0000 Subject: Fix build with QT_NO_GRAPHICSEFFECT Change-Id: Iadc78c270f541067dbbebcf77748077cc3a8be13 Reviewed-by: Marc Mutz --- src/opengl/qgraphicsshadereffect.cpp | 5 +++++ src/opengl/qgraphicsshadereffect_p.h | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/opengl/qgraphicsshadereffect.cpp b/src/opengl/qgraphicsshadereffect.cpp index 739be17ef3..736bf10f2e 100644 --- a/src/opengl/qgraphicsshadereffect.cpp +++ b/src/opengl/qgraphicsshadereffect.cpp @@ -40,6 +40,9 @@ ****************************************************************************/ #include "qgraphicsshadereffect_p.h" + +#ifndef QT_NO_GRAPHICSEFFECT + #include "qglshaderprogram.h" #include "gl2paintengineex/qglcustomshaderstage_p.h" #define QGL_HAVE_CUSTOM_SHADERS 1 @@ -311,3 +314,5 @@ void QGraphicsShaderEffect::setUniforms(QGLShaderProgram *program) } QT_END_NAMESPACE + +#endif // QT_NO_GRAPHICSEFFECT diff --git a/src/opengl/qgraphicsshadereffect_p.h b/src/opengl/qgraphicsshadereffect_p.h index 8a7c082afa..3f879fc2d2 100644 --- a/src/opengl/qgraphicsshadereffect_p.h +++ b/src/opengl/qgraphicsshadereffect_p.h @@ -54,6 +54,9 @@ // #include + +#ifndef QT_NO_GRAPHICSEFFECT + #include QT_BEGIN_NAMESPACE @@ -87,4 +90,6 @@ private: QT_END_NAMESPACE +#endif // QT_NO_GRAPHICSEFFECT + #endif // QGRAPHICSSHADEREFFECT_P_H -- cgit v1.2.3 From fd00bfc788f23518ae68293d5b97cf9361a9d2a9 Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Sun, 9 Feb 2014 17:52:22 +0000 Subject: Correct the documentation of the return types of subjectInfo and issuerInfo. These functions now return a QStringList to reflect the possibility of there being more than one entry of a given type, but the documentation did not reflect this. Task-Number: QTBUG-36304 Change-Id: Iba2eda5e2c3174c8dcea640b5aed9cdc9a432392 Reviewed-by: Peter Hartmann --- src/network/ssl/qsslcertificate.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index b4c593fa73..3b7fa4da09 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -341,8 +341,9 @@ static QByteArray _q_SubjectInfoToString(QSslCertificate::SubjectInfo info) \fn QString QSslCertificate::issuerInfo(SubjectInfo subject) const Returns the issuer information for the \a subject from the - certificate, or an empty string if there is no information for - \a subject in the certificate. + certificate, or an empty list if there is no information for + \a subject in the certificate. There can be more than one entry + of each type. \sa subjectInfo() */ @@ -359,8 +360,8 @@ QStringList QSslCertificate::issuerInfo(SubjectInfo info) const /*! Returns the issuer information for \a attribute from the certificate, - or an empty string if there is no information for \a attribute in the - certificate. + or an empty list if there is no information for \a attribute in the + certificate. There can be more than one entry for an attribute. \sa subjectInfo() */ @@ -379,8 +380,9 @@ QStringList QSslCertificate::issuerInfo(const QByteArray &attribute) const \fn QString QSslCertificate::subjectInfo(SubjectInfo subject) const - Returns the information for the \a subject, or an empty string if - there is no information for \a subject in the certificate. + Returns the information for the \a subject, or an empty list if + there is no information for \a subject in the certificate. There + can be more than one entry of each type. \sa issuerInfo() */ @@ -396,8 +398,9 @@ QStringList QSslCertificate::subjectInfo(SubjectInfo info) const } /*! - Returns the subject information for \a attribute, or an empty string if - there is no information for \a attribute in the certificate. + Returns the subject information for \a attribute, or an empty list if + there is no information for \a attribute in the certificate. There + can be more than one entry for an attribute. \sa issuerInfo() */ -- cgit v1.2.3 From 8e22d71b225576ae7ccd6ed349c05219bae7689e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 11 Feb 2014 11:19:32 -0800 Subject: Disable disabling exceptions with ICC There's a bug found in ICC 14.0 that causes the compiler to assert when compiling QtDeclarative. Let's leave this here until at least one year after the fix is released. Intel task: DPD200253124 Task-number: QTBUG-36577 Change-Id: I76d4b41da7e60397dac65862a3a6ec024b840744 Reviewed-by: Simon Hausmann --- mkspecs/linux-icc/qmake.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mkspecs/linux-icc/qmake.conf b/mkspecs/linux-icc/qmake.conf index ee5f1f0ea4..000632069a 100644 --- a/mkspecs/linux-icc/qmake.conf +++ b/mkspecs/linux-icc/qmake.conf @@ -44,7 +44,8 @@ QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD -QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions +# Disabling exceptions disabled - workaround for QTBUG-36577 +#QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions QMAKE_CXXFLAGS_CXX11 = -std=c++0x QMAKE_INCDIR = -- cgit v1.2.3