diff --git a/doc/images/cpu-usage-analyzer.png b/doc/images/cpu-usage-analyzer.png new file mode 100644 index 00000000000..0a9085c6c75 Binary files /dev/null and b/doc/images/cpu-usage-analyzer.png differ diff --git a/doc/src/analyze/cpu-usage-analyzer.qdoc b/doc/src/analyze/cpu-usage-analyzer.qdoc new file mode 100644 index 00000000000..5db12465b50 --- /dev/null +++ b/doc/src/analyze/cpu-usage-analyzer.qdoc @@ -0,0 +1,249 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing +** +** This file is part of Qt Creator +** +** +** GNU Free Documentation License +** +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of this +** file. +** +** +****************************************************************************/ + +// ********************************************************************** +// NOTE: the sections are not ordered by their logical order to avoid +// reshuffling the file each time the index order changes (i.e., often). +// Run the fixnavi.pl script to adjust the links to the index order. +// ********************************************************************** + +/*! + \contentspage {Qt Creator Manual} + \previouspage creator-clang-static-analyzer.html + \page creator-cpu-usage-analyzer.html + \nextpage creator-advanced.html + + \title Analyzing CPU Usage + + \QC is integrated with the Linux Perf tool (commercial only) that can be + used to analyze the CPU usage of an application on embedded devices and, to + a limited extent, on Linux desktop platforms. The CPU Usage Analyzer uses + the Perf tool bundled with the Linux kernel to take periodic snapshots of + the call chain of an application and visualizes them in a timeline view. + + \section1 Using the CPU Usage Analyzer + + The CPU Usage Analyzer needs to be able to locate debug symbols for the + binaries involved. For debug builds, debug symbols are always generated. + Edit the project build settings to generate debug symbols also for release + builds. + + To use the CPU Usage Analyzer: + + \list 1 + \li To generate debug symbols also for applications compiled in release + mode, select \uicontrol {Projects}, and then select + \uicontrol Details next to \uicontrol {Build Steps} to view the + build steps. + + \li Select the \uicontrol {Generate separate debug info} check box, and + then select \uicontrol Yes to recompile the project. + + \li Select \uicontrol {Analyze > CPU Usage Analyzer} to profile the + current application. + + \li Select the + \inlineimage qtcreator-analyze-start-button.png + (\uicontrol Start) button to start the application from the + CPU Usage Analyzer. + + \note If data collection does not start automatically, select the + \inlineimage qtcreator-analyzer-button.png + (\uicontrol {Collect profile data}) button. + + \endlist + + When you start analyzing an application, the application is launched, and + the CPU Usage Analyzer immediately begins to collect data. This is indicated + by the time running in the \uicontrol Recorded field. However, as the data + is passed through the Perf tool and an extra helper program bundled with + \QC, and both buffer and process it on the fly, data may arrive in \QC + several seconds after it was generated. An estimate for this delay is given + in the \uicontrol {Processing delay} field. + + Data is collected until you select the + \uicontrol {Stop collecting profile data} button or terminate the + application. + + Select the \uicontrol {Stop collecting profile data} button to disable the + automatic start of the data collection when an application is launched. + Profile data will still be generated, but \QC will discard it until you + select the button again. + + \section1 Specifying CPU Usage Analyzer Settings + + To specify global settings for the CPU Usage Analyzer, select + \uicontrol Tools > \uicontrol Options > \uicontrol Analyzer > + \uicontrol {CPU Usage Analyzer}. For each run configuration, you can also + use specialized settings. Select \uicontrol Projects > \uicontrol Run, and + then select \uicontrol Details next to + \uicontrol {CPU Usage Analyzer Settings}. + + \section2 Selecting Call Graph Mode + + Select the command to invoke Perf in the \uicontrol {Call graph mode} field. + The \uicontrol {Frame Pointer}, or \c fp, mode relies on frame pointers + being available in the profiled application. + + The \uicontrol {Dwarf} mode works also without frame pointers, but + generates significantly more data. Qt and most system libraries are + compiled without frame pointers by default, so the frame pointer mode is + only useful with customized systems. + + \section2 Setting Stack Snapshot Size + + In the dwarf mode, Perf takes periodic snapshots of the application stack, + which are then analyzed and \e unwound by the CPU Usage Analyzer. Set the + size of the stack snapshots in the \uicontrol {Stack snapshot size} field. + Large stack snapshots result in a larger volume of data to be transferred + and processed. Small stack snapshots may fail to capture call chains of + highly recursive applications or other intense stack usage. + + \section2 Setting Sampling Frequency + + Set the sampling frequency for Perf in the \uicontrol {Sampling frequency} + field. High sampling frequencies result in more accurate data, at the + expense of a higher overhead and a larger volume of profiling data being + generated. The actual sampling frequency is determined by the Linux kernel + on the target device, which takes the frequency set for Perf merely as + advice. There may be a significant difference between the sampling frequency + you request and the actual result. + + In general, if you configure the CPU Usage Analyzer to collect more data + than it can transmit over the connection between the target and the host + device, the application may get blocked while Perf is trying to send the + data, and the processing delay may grow excessively. You should then lower + the \uicontrol {Sampling frequency} or the \uicontrol {Stack snapshot size}. + + \section1 Analyzing Collected Data + + The \uicontrol Timeline view displays a graphical representation of CPU + usage per thread and a condensed view of all recorded events. + + \image cpu-usage-analyzer.png "CPU Usage Analyzer" + + Each category in the timeline describes a thread in the application. Move + the cursor on an event (6) on a row to see how long it takes and which + function in the source it represents. To display the information only when + an event is selected, disable the + \uicontrol {View Event Information on Mouseover} button (5). + + The outline (10) summarizes the period for which data was collected. Drag + the zoom range (8) or click the outline to move on the outline. You can + also move between events by selecting the + \uicontrol {Jump to Previous Event} (1) and \uicontrol {Jump to Next Event} + (2) buttons. + + Select the \uicontrol {Show Zoom Slider} button (3) to open a slider that + you can use to set the zoom level. You can also drag the zoom handles (9). + To reset the default zoom level, right-click the timeline to open the + context menu, and select \uicontrol {Reset Zoom}. + + \section2 Selecting Event Ranges + + You can select an event range (7) to view the time it represents or to zoom + into a specific region of the trace. Select the \uicontrol {Select Range} + button (4) to activate the selection tool. Then click in the timeline to + specify the beginning of the event range. Drag the selection handle to + define the end of the range. + + You can use event ranges also to measure delays between two subsequent + events. Place a range between the end of the first event and the beginning + of the second event. The \uicontrol Duration field displays the delay + between the events in milliseconds. + + To zoom into an event range, double-click it. + + To remove an event range, close the \uicontrol Selection dialog. + + \section2 Understanding the Data + + Generally, events in the timeline view indicate how long a function call + took. Move the mouse over them to see details. The details always include + the address of the function, the approximate duration of the call, the ELF + file the function resides in, the number of samples collected with this + function call active, the total number of times this function was + encountered in the thread, and the number of samples this function was + encountered in at least once. + + For functions with debug information available, the details include the + location in source code and the name of the function. You can click on such + events to move the cursor in the code editor to the part of the code the + event is associated with. + + As the Perf tool only provides periodic samples, the CPU Usage Analyzer + cannot determine the exact time when a function was called or when it + returned. You can, however, see exactly when a sample was taken on the + second row of each thread. The CPU Usage Analyzer assumes that if the same + function is present in the same place in the call chain in multiple samples + on a row, then this represents a single call to the respective function. + This is, of course, a simplification. Also, there may be other functions + being called between the samples taken, which do not show up in the profile + data. However, statistically, the data is likely to show the functions that + spend the most CPU time most prominently. + + If a function without debug information is encountered, further unwinding + of the stack may fail. Unwinding will also fail if a QML or JavaScript + function is encountered, and for some symbols implemented in assembler. If + unwinding fails, only part of the call chain is displayed, and the + surrounding functions may seem to be interrupted. This does not necessarily + mean they were actually interrupted during the execution of the + application, but only that they could not be found in the stacks where the + unwinding failed. + + Kernel functions included in call chains are shown on the third row of each + thread. All kernel functions are summarized and not differentiated any + further, because most of the time kernel symbols cannot be resolved when the + data is analyzed. + + The coloring of the events represents the actual sample rate for the + specific thread they belong to, across their duration. The Linux kernel + will only take a sample of a thread if the thread is active. At the same + time, the kernel tries to maintain a constant overall sampling frequency. + Thus, differences in the sampling frequency between different threads + indicate that the thread with more samples taken is more likely to be the + overall bottleneck, and the thread with less samples taken has likely spent + time waiting for external events such as I/O or a mutex. + + \section1 Loading Perf Data Files + + You can load any \c perf.data files generated by recent versions of the + Linux Perf tool and view them in \QC. Select \uicontrol Analyze > + \uicontrol {Load Trace} to load a file. The CPU Usage Analyzer needs to know + the context in which the data was recorded to find the debug symbols. + Therefore, you have to specify the kit that the application was built with + and the folder where the application executable is located. + + The Perf data files are generated by calling \c {perf record}. Make sure to + generate call graphs when recording data by starting Perf with the + \c {--call-graph} option. Also check that the necessary debug symbols are + available to the CPU Usage Analyzer, either at a standard location + (\c /usr/lib/debug or next to the binaries), or as part of the Qt package + you are using. + + The CPU Usage Analyzer can read Perf data files generated in either frame + pointer or dwarf mode. However, to generate the files correctly, numerous + preconditions have to be met. All system images for the + \l{http://doc.qt.io/QtForDeviceCreation/qtee-supported-platforms.html} + {Qt for Device Creation reference devices}, except for Freescale iMX53 Quick + Start Board and SILICA Architect Tibidabo, are correctly set up for + profiling in the dwarf mode. For other devices, check whether Perf can read + back its own data in a sensible way by checking the output of + \c {perf report} or \c {perf script} in the recorded Perf data files. + +*/ diff --git a/doc/src/analyze/creator-analyze.qdoc b/doc/src/analyze/creator-analyze.qdoc index 4cb521f4250..cb4593e8b5d 100644 --- a/doc/src/analyze/creator-analyze.qdoc +++ b/doc/src/analyze/creator-analyze.qdoc @@ -66,6 +66,12 @@ integrates the Clang Static Analyzer source code analysis tool (commercial only). + \li \l{Analyzing CPU Usage}{CPU Usage Analyzer} + + You can analyze the CPU usage of embedded applications and Linux + desktop applications with the CPU Usage Analyzer (commercial only) + that integrates the Linux Perf tool. + \endlist */ diff --git a/doc/src/analyze/creator-clang-static-analyzer.qdoc b/doc/src/analyze/creator-clang-static-analyzer.qdoc index 821e78fd532..3485be704fa 100644 --- a/doc/src/analyze/creator-clang-static-analyzer.qdoc +++ b/doc/src/analyze/creator-clang-static-analyzer.qdoc @@ -27,7 +27,7 @@ \contentspage {Qt Creator Manual} \previouspage creator-running-valgrind-remotely.html \page creator-clang-static-analyzer.html - \nextpage creator-advanced.html + \nextpage creator-cpu-usage-analyzer.html \title Using Clang Static Analyzer diff --git a/doc/src/overview/creator-advanced.qdoc b/doc/src/overview/creator-advanced.qdoc index 4feca1df25f..8a198eba7fd 100644 --- a/doc/src/overview/creator-advanced.qdoc +++ b/doc/src/overview/creator-advanced.qdoc @@ -24,7 +24,7 @@ /*! \contentspage {Qt Creator Manual} - \previouspage creator-clang-static-analyzer.html + \previouspage creator-cpu-usage-analyzer.html \page creator-advanced.html \nextpage creator-os-supported-platforms.html diff --git a/doc/src/overview/creator-commercial-overview.qdoc b/doc/src/overview/creator-commercial-overview.qdoc index 47f3cb2d1d0..b4c393c4c05 100644 --- a/doc/src/overview/creator-commercial-overview.qdoc +++ b/doc/src/overview/creator-commercial-overview.qdoc @@ -41,6 +41,7 @@ \li Memory usage \li Input events \endlist + \li \l{Analyzing CPU Usage}{CPU Usage Analyzer} \li \l{http://doc.qt.io/QtQuickCompiler/}{Qt Quick Compiler} integration \li \l{Using Qt Quick Designer Extensions} diff --git a/doc/src/qtcreator.qdoc b/doc/src/qtcreator.qdoc index 0e4c2f0e5ab..a5b4b632fdc 100644 --- a/doc/src/qtcreator.qdoc +++ b/doc/src/qtcreator.qdoc @@ -268,6 +268,7 @@ \li \l{Running Valgrind Tools on External Applications} \endlist \li \l{Using Clang Static Analyzer} + \li \l{Analyzing CPU Usage} \endlist \endlist diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 6b588165eac..be1968733eb 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -705,8 +705,8 @@ void ClassOrNamespace::lookup_helper(const Name *name, ClassOrNamespace *binding foreach (ClassOrNamespace *u, binding->usings()) lookup_helper(name, u, result, processed, binding->_templateId); - Anonymouses::const_iterator cit = binding->_anonymouses.begin(); - Anonymouses::const_iterator citEnd = binding->_anonymouses.end(); + Anonymouses::const_iterator cit = binding->_anonymouses.constBegin(); + Anonymouses::const_iterator citEnd = binding->_anonymouses.constEnd(); for (; cit != citEnd; ++cit) { const AnonymousNameId *anonymousNameId = cit.key(); ClassOrNamespace *a = cit.value(); @@ -802,8 +802,8 @@ ClassOrNamespace *ClassOrNamespace::lookupType(const Name *name, Block *block) { flush(); - QHash::const_iterator citBlock = _blocks.find(block); - if (citBlock != _blocks.end()) { + QHash::const_iterator citBlock = _blocks.constFind(block); + if (citBlock != _blocks.constEnd()) { ClassOrNamespace *nestedBlock = citBlock.value(); QSet processed; if (ClassOrNamespace *foundInNestedBlock @@ -815,7 +815,7 @@ ClassOrNamespace *ClassOrNamespace::lookupType(const Name *name, Block *block) } } - for (citBlock = _blocks.begin(); citBlock != _blocks.end(); ++citBlock) { + for (citBlock = _blocks.constBegin(); citBlock != _blocks.constEnd(); ++citBlock) { if (ClassOrNamespace *foundNestedBlock = citBlock.value()->lookupType(name, block)) return foundNestedBlock; } @@ -1027,8 +1027,8 @@ ClassOrNamespace *ClassOrNamespace::findOrCreateNestedAnonymousType( const AnonymousNameId *anonymousNameId) { QHash::const_iterator cit - = _anonymouses.find(anonymousNameId); - if (cit != _anonymouses.end()) { + = _anonymouses.constFind(anonymousNameId); + if (cit != _anonymouses.constEnd()) { return cit.value(); } else { ClassOrNamespace *newAnonymous = _factory->allocClassOrNamespace(this); @@ -1083,8 +1083,8 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac } } else { QMap::const_iterator citInstantiation - = reference->_instantiations.find(templId); - if (citInstantiation != reference->_instantiations.end()) + = reference->_instantiations.constFind(templId); + if (citInstantiation != reference->_instantiations.constEnd()) return citInstantiation.value(); TemplateNameId *nonConstTemplId = const_cast(templId); // make this instantiation looks like specialization which help to find diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp index 8f0100e4b80..82515c24846 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -1589,8 +1589,8 @@ void PluginManagerPrivate::profilingSummary() const total += it1.value(); } - Sorter::ConstIterator it2 = sorter.begin(); - Sorter::ConstIterator et2 = sorter.end(); + Sorter::ConstIterator it2 = sorter.constBegin(); + Sorter::ConstIterator et2 = sorter.constEnd(); for (; it2 != et2; ++it2) qDebug("%-22s %8dms ( %5.2f%% )", qPrintable(it2.value()->name()), it2.key(), 100.0 * it2.key() / total); diff --git a/src/libs/extensionsystem/pluginview.cpp b/src/libs/extensionsystem/pluginview.cpp index a918c5facb7..7bec48cce1b 100644 --- a/src/libs/extensionsystem/pluginview.cpp +++ b/src/libs/extensionsystem/pluginview.cpp @@ -83,6 +83,8 @@ enum Columns { NameColumn, LoadedColumn, VersionColumn, VendorColumn, }; enum IconIndex { OkIcon, ErrorIcon, NotLoadedIcon }; +static const int SortRole = Qt::UserRole + 1; + static const QIcon &icon(int num) { static QIcon icons[] = { @@ -106,7 +108,7 @@ public: { switch (column) { case NameColumn: - if (role == Qt::DisplayRole) + if (role == Qt::DisplayRole || role == SortRole) return m_spec->name(); if (role == Qt::ToolTipRole) { QString toolTip; @@ -133,17 +135,17 @@ public: case LoadedColumn: if (!m_spec->isAvailableForHostPlatform()) { - if (role == Qt::CheckStateRole) + if (role == Qt::CheckStateRole || role == SortRole) return Qt::Unchecked; if (role == Qt::ToolTipRole) return PluginView::tr("Plugin is not available on this platform."); } else if (m_spec->isRequired()) { - if (role == Qt::CheckStateRole) + if (role == Qt::CheckStateRole || role == SortRole) return Qt::Checked; if (role == Qt::ToolTipRole) return PluginView::tr("Plugin is required."); } else { - if (role == Qt::CheckStateRole) + if (role == Qt::CheckStateRole || role == SortRole) return m_spec->isEnabledBySettings() ? Qt::Checked : Qt::Unchecked; if (role == Qt::ToolTipRole) return PluginView::tr("Load on startup"); @@ -151,12 +153,12 @@ public: break; case VersionColumn: - if (role == Qt::DisplayRole) + if (role == Qt::DisplayRole || role == SortRole) return QString::fromLatin1("%1 (%2)").arg(m_spec->version(), m_spec->compatVersion()); break; case VendorColumn: - if (role == Qt::DisplayRole) + if (role == Qt::DisplayRole || role == SortRole) return m_spec->vendor(); break; } @@ -211,7 +213,7 @@ public: QVariant data(int column, int role) const { if (column == NameColumn) { - if (role == Qt::DisplayRole) + if (role == Qt::DisplayRole || role == SortRole) return m_name; if (role == Qt::DecorationRole) { foreach (PluginSpec *spec, m_plugins) { @@ -227,7 +229,7 @@ public: if (column == LoadedColumn) { if (role == Qt::ToolTipRole) return PluginView::tr("Load on Startup"); - if (role == Qt::CheckStateRole) { + if (role == Qt::CheckStateRole || role == SortRole) { int checkedCount = 0; foreach (PluginSpec *spec, m_plugins) { if (spec->isEnabledBySettings()) @@ -298,6 +300,7 @@ PluginView::PluginView(QWidget *parent) m_sortModel = new QSortFilterProxyModel(this); m_sortModel->setSourceModel(m_model); + m_sortModel->setSortRole(SortRole); m_categoryView->setModel(m_sortModel); QGridLayout *gridLayout = new QGridLayout(this); diff --git a/src/libs/ssh/sshconnection.cpp b/src/libs/ssh/sshconnection.cpp index 956e45a0fbd..d86cc562e2f 100644 --- a/src/libs/ssh/sshconnection.cpp +++ b/src/libs/ssh/sshconnection.cpp @@ -438,7 +438,7 @@ void SshConnectionPrivate::handleCurrentPacket() } QHash::ConstIterator it - = m_packetHandlers.find(m_incomingPacket.type()); + = m_packetHandlers.constFind(m_incomingPacket.type()); if (it == m_packetHandlers.constEnd()) { m_sendFacility.sendMsgUnimplementedPacket(m_incomingPacket.serverSeqNr()); return; diff --git a/src/libs/ssh/sshhostkeydatabase.cpp b/src/libs/ssh/sshhostkeydatabase.cpp index c06edd22962..efec5f764f1 100644 --- a/src/libs/ssh/sshhostkeydatabase.cpp +++ b/src/libs/ssh/sshhostkeydatabase.cpp @@ -104,7 +104,7 @@ bool SshHostKeyDatabase::store(const QString &filePath, QString *error) const SshHostKeyDatabase::KeyLookupResult SshHostKeyDatabase::matchHostKey(const QString &hostName, const QByteArray &key) const { - auto it = d->hostKeys.find(hostName); + auto it = d->hostKeys.constFind(hostName); if (it == d->hostKeys.constEnd()) return KeyLookupNoMatch; if (it.value() == key) diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index 3c2625c8604..ab071b70894 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -681,7 +681,8 @@ static bool mergeGradleProperties(const QString &path, GradleProperties properti } - for (GradleProperties::const_iterator it = properties.begin(); it != properties.end(); ++it) + for (GradleProperties::const_iterator it = properties.constBegin(); it != properties.constEnd(); + ++it) file.write(it.key() + '=' + it.value() + '\n'); file.close(); diff --git a/src/plugins/classview/classviewparser.cpp b/src/plugins/classview/classviewparser.cpp index 27734c12cd7..5a2eabb4efb 100644 --- a/src/plugins/classview/classviewparser.cpp +++ b/src/plugins/classview/classviewparser.cpp @@ -521,9 +521,9 @@ ParserTreeItem::ConstPtr Parser::getCachedOrParseDocumentTree(const CPlusPlus::D const QString &fileName = doc->fileName(); d->docLocker.lockForRead(); ParserTreeItem::ConstPtr item = d->cachedDocTrees.value(fileName); - CitCachedDocTreeRevision citCachedDocTreeRevision = d->cachedDocTreesRevision.find(fileName); + CitCachedDocTreeRevision citCachedDocTreeRevision = d->cachedDocTreesRevision.constFind(fileName); if (!item.isNull() - && citCachedDocTreeRevision != d->cachedDocTreesRevision.end() + && citCachedDocTreeRevision != d->cachedDocTreesRevision.constEnd() && citCachedDocTreeRevision.value() == doc->revision()) { d->docLocker.unlock(); return item; @@ -759,9 +759,9 @@ QStringList Parser::addProjectNode(const ParserTreeItem::Ptr &item, const Projec // our own files QStringList fileList; - CitCachedPrjFileLists cit = d->cachedPrjFileLists.find(nodePath); + CitCachedPrjFileLists cit = d->cachedPrjFileLists.constFind(nodePath); // try to improve parsing speed by internal cache - if (cit != d->cachedPrjFileLists.end()) { + if (cit != d->cachedPrjFileLists.constEnd()) { fileList = cit.value(); } else { fileList = projectNodeFileList(node); @@ -800,9 +800,9 @@ QStringList Parser::getAllFiles(const ProjectNode *node) const QString nodePath = node->path().toString(); - CitCachedPrjFileLists cit = d->cachedPrjFileLists.find(nodePath); + CitCachedPrjFileLists cit = d->cachedPrjFileLists.constFind(nodePath); // try to improve parsing speed by internal cache - if (cit != d->cachedPrjFileLists.end()) { + if (cit != d->cachedPrjFileLists.constEnd()) { fileList = cit.value(); } else { fileList = projectNodeFileList(node); diff --git a/src/plugins/clearcase/clearcasesync.cpp b/src/plugins/clearcase/clearcasesync.cpp index 2cd4de67f37..a86ff669f6e 100644 --- a/src/plugins/clearcase/clearcasesync.cpp +++ b/src/plugins/clearcase/clearcasesync.cpp @@ -80,8 +80,8 @@ void ClearCaseSync::invalidateStatus(const QDir &viewRootDir, void ClearCaseSync::invalidateStatusAllFiles() { - const StatusMap::ConstIterator send = m_statusMap->end(); - for (StatusMap::ConstIterator it = m_statusMap->begin(); it != send; ++it) + const StatusMap::ConstIterator send = m_statusMap->constEnd(); + for (StatusMap::ConstIterator it = m_statusMap->constBegin(); it != send; ++it) m_plugin->setStatus(it.key(), FileStatus::Unknown, false); } diff --git a/src/plugins/cpptools/cppsourceprocessor.cpp b/src/plugins/cpptools/cppsourceprocessor.cpp index df792c3bcd8..85332575649 100644 --- a/src/plugins/cpptools/cppsourceprocessor.cpp +++ b/src/plugins/cpptools/cppsourceprocessor.cpp @@ -249,8 +249,8 @@ bool CppSourceProcessor::checkFile(const QString &absoluteFilePath) const QString CppSourceProcessor::resolveFile(const QString &fileName, IncludeType type) { if (type == IncludeGlobal) { - QHash::ConstIterator it = m_fileNameCache.find(fileName); - if (it != m_fileNameCache.end()) + QHash::ConstIterator it = m_fileNameCache.constFind(fileName); + if (it != m_fileNameCache.constEnd()) return it.value(); const QString fn = resolveFile_helper(fileName, type); m_fileNameCache.insert(fileName, fn); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index f2f683454d3..521d92280e5 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -1850,8 +1850,8 @@ QString GdbEngine::cleanupFullName(const QString &fileName) cleanFilePath.clear(); const QString base = FileName::fromString(fileName).fileName(); - QMap::const_iterator jt = m_baseNameToFullName.find(base); - while (jt != m_baseNameToFullName.end() && jt.key() == base) { + QMap::const_iterator jt = m_baseNameToFullName.constFind(base); + while (jt != m_baseNameToFullName.constEnd() && jt.key() == base) { // FIXME: Use some heuristics to find the "best" match. return jt.value(); //++jt; @@ -4018,7 +4018,7 @@ bool GdbEngine::handleCliDisassemblerResult(const QByteArray &output, Disassembl currentFunction = -1; DisassemblerLines result; result.setBytesLength(dlines.bytesLength()); - for (LineMap::const_iterator it = lineMap.begin(), et = lineMap.end(); it != et; ++it) { + for (LineMap::const_iterator it = lineMap.constBegin(), et = lineMap.constEnd(); it != et; ++it) { LineData d = *it; if (d.function != currentFunction) { if (d.function != -1) { diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp index 65b02fbfe47..811f00bc46f 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp @@ -1510,8 +1510,8 @@ void QmlV8DebuggerClient::setCurrentFrameDetails(const QVariant &bodyVal, const d->engine->gotoLocation(stackHandler->currentFrame()); // Expand watch data that were previously expanded - QHash::const_iterator itEnd = handlesToLookup.end(); - for (QHash::const_iterator it = handlesToLookup.begin(); it != itEnd; ++it) + QHash::const_iterator itEnd = handlesToLookup.constEnd(); + for (QHash::const_iterator it = handlesToLookup.constBegin(); it != itEnd; ++it) expandObject(it.value(), it.key()); emit stackFrameCompleted(); } diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp index 83eb457f1d7..9503c2db236 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp @@ -124,6 +124,7 @@ const char KeyFileKey[] = "KeyFile"; const char PasswordKey[] = "Password"; const char TimeoutKey[] = "Timeout"; const char HostKeyCheckingKey[] = "HostKeyChecking"; +const char SshOptionsKey[] = "SshOptions"; const char DebugServerKey[] = "DebugServerKey"; @@ -328,6 +329,8 @@ void IDevice::fromMap(const QVariantMap &map) d->sshParameters.timeout = map.value(QLatin1String(TimeoutKey), DefaultTimeout).toInt(); d->sshParameters.hostKeyCheckingMode = static_cast (map.value(QLatin1String(HostKeyCheckingKey), QSsh::SshHostKeyCheckingNone).toInt()); + d->sshParameters.options + = QSsh::SshConnectionOptions(map.value(QLatin1String(SshOptionsKey)).toInt()); d->freePorts = Utils::PortList::fromString(map.value(QLatin1String(PortsSpecKey), QLatin1String("10000-10100")).toString()); @@ -360,6 +363,7 @@ QVariantMap IDevice::toMap() const map.insert(QLatin1String(KeyFileKey), d->sshParameters.privateKeyFile); map.insert(QLatin1String(TimeoutKey), d->sshParameters.timeout); map.insert(QLatin1String(HostKeyCheckingKey), d->sshParameters.hostKeyCheckingMode); + map.insert(QLatin1String(SshOptionsKey), static_cast(d->sshParameters.options)); map.insert(QLatin1String(PortsSpecKey), d->freePorts.toString()); map.insert(QLatin1String(VersionKey), d->version); diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index 05e1de44e8a..8a035417120 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -317,7 +317,7 @@ Utils::Environment MsvcToolChain::readEnvironmentSetting(Utils::Environment& env // Now loop through and process them QMap::const_iterator envIter; - for (envIter = envPairs.begin(); envIter!=envPairs.end(); ++envIter) { + for (envIter = envPairs.constBegin(); envIter!=envPairs.constEnd(); ++envIter) { const QString expandedValue = winExpandDelayedEnvReferences(envIter.value(), env); if (!expandedValue.isEmpty()) result.set(envIter.key(), expandedValue); diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp index a4feac93632..74e9e8f0dc4 100644 --- a/src/plugins/projectexplorer/session.cpp +++ b/src/plugins/projectexplorer/session.cpp @@ -692,7 +692,7 @@ void SessionManager::setValue(const QString &name, const QVariant &value) QVariant SessionManager::value(const QString &name) { - QMap::const_iterator it = d->m_values.find(name); + QMap::const_iterator it = d->m_values.constFind(name); return (it == d->m_values.constEnd()) ? QVariant() : *it; } diff --git a/src/plugins/projectexplorer/wincetoolchain.cpp b/src/plugins/projectexplorer/wincetoolchain.cpp index a2fea38db70..4a12ae2a06f 100644 --- a/src/plugins/projectexplorer/wincetoolchain.cpp +++ b/src/plugins/projectexplorer/wincetoolchain.cpp @@ -127,7 +127,7 @@ Utils::Environment WinCEToolChain::readEnvironmentSetting(Utils::Environment &en return result; QMap::const_iterator envPairIter; - for (envPairIter = envPairs.begin(); envPairIter!=envPairs.end(); ++envPairIter) { + for (envPairIter = envPairs.constBegin(); envPairIter!=envPairs.constEnd(); ++envPairIter) { // Replace the env values with those from the WinCE SDK QString varValue = envPairIter.value(); if (envPairIter.key() == QLatin1String("PATH")) diff --git a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp index 4292b49c48f..92c1df8b4b5 100644 --- a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp +++ b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp @@ -103,7 +103,10 @@ public: { QString componentName = m_componentName; QString path = QFileInfo(fileName()).path(); - ComponentNameDialog::go(&componentName, &path, Core::ICore::dialogParent()); + bool confirm = ComponentNameDialog::go(&componentName, &path, Core::ICore::dialogParent()); + + if (!confirm) + return; if (componentName.isEmpty() || path.isEmpty()) return; diff --git a/src/plugins/qmljseditor/qmljscomponentnamedialog.cpp b/src/plugins/qmljseditor/qmljscomponentnamedialog.cpp index cdab84acfd1..85048aeacdc 100644 --- a/src/plugins/qmljseditor/qmljscomponentnamedialog.cpp +++ b/src/plugins/qmljseditor/qmljscomponentnamedialog.cpp @@ -54,7 +54,7 @@ ComponentNameDialog::~ComponentNameDialog() delete ui; } -void ComponentNameDialog::go(QString *proposedName, +bool ComponentNameDialog::go(QString *proposedName, QString *proposedPath, QWidget *parent) { @@ -73,7 +73,10 @@ void ComponentNameDialog::go(QString *proposedName, if (QDialog::Accepted == d.exec()) { *proposedName = d.ui->componentNameEdit->text(); *proposedPath = d.ui->pathEdit->path(); + return true; } + + return false; } void ComponentNameDialog::choosePath() diff --git a/src/plugins/qmljseditor/qmljscomponentnamedialog.h b/src/plugins/qmljseditor/qmljscomponentnamedialog.h index 30bb2b8ced3..4a6cd0938b7 100644 --- a/src/plugins/qmljseditor/qmljscomponentnamedialog.h +++ b/src/plugins/qmljseditor/qmljscomponentnamedialog.h @@ -46,7 +46,7 @@ public: explicit ComponentNameDialog(QWidget *parent = 0); ~ComponentNameDialog(); - static void go(QString *proposedName, QString *proposedPath, QWidget *parent = 0); + static bool go(QString *proposedName, QString *proposedPath, QWidget *parent = 0); public slots: void choosePath(); diff --git a/src/plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp b/src/plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp index b34a510a8cb..ab46db0c06f 100644 --- a/src/plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp +++ b/src/plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp @@ -154,7 +154,7 @@ void QmlProfilerEventsModelProxy::notesChanged(int typeIndex) } } else { d->notes.remove(typeIndex); - QVariantList changedNotes = notesModel->byTypeId(typeIndex); + const QVariantList changedNotes = notesModel->byTypeId(typeIndex); if (!changedNotes.isEmpty()) { QStringList newNotes; for (QVariantList::ConstIterator it = changedNotes.begin(); it != changedNotes.end(); diff --git a/src/plugins/qtsupport/qtversionmanager.cpp b/src/plugins/qtsupport/qtversionmanager.cpp index 7513ad40e3f..f4daf2a5e14 100644 --- a/src/plugins/qtsupport/qtversionmanager.cpp +++ b/src/plugins/qtsupport/qtversionmanager.cpp @@ -495,7 +495,7 @@ bool QtVersionManager::isValidId(int id) BaseQtVersion *QtVersionManager::version(int id) { QTC_ASSERT(isLoaded(), return 0); - QMap::const_iterator it = m_versions.find(id); + QMap::const_iterator it = m_versions.constFind(id); if (it == m_versions.constEnd()) return 0; return it.value(); diff --git a/src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp b/src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp index 4beb300217e..77291080be8 100644 --- a/src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp +++ b/src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp @@ -230,7 +230,7 @@ QVariantMap AbstractRemoteLinuxDeployService::exportDeployTimes() const QVariantList remotePathList; QVariantList timeList; typedef QHash::ConstIterator DepIt; - for (DepIt it = d->lastDeployed.begin(); it != d->lastDeployed.end(); ++it) { + for (DepIt it = d->lastDeployed.constBegin(); it != d->lastDeployed.constEnd(); ++it) { fileList << it.key().file.localFilePath().toString(); remotePathList << it.key().file.remoteDirectory(); hostList << it.key().host; diff --git a/src/plugins/texteditor/snippets/snippetscollection.cpp b/src/plugins/texteditor/snippets/snippetscollection.cpp index 44ceb92c6fb..235eff9989e 100644 --- a/src/plugins/texteditor/snippets/snippetscollection.cpp +++ b/src/plugins/texteditor/snippets/snippetscollection.cpp @@ -207,7 +207,7 @@ int SnippetsCollection::totalActiveSnippets(const QString &groupId) const { const int group = groupIndex(groupId); return std::distance::const_iterator>(m_snippets.at(group).begin(), - m_activeSnippetsEnd.at(group)); + QList::const_iterator(m_activeSnippetsEnd.at(group))); } int SnippetsCollection::totalSnippets(const QString &groupId) const diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 2c62abbed00..907a3787445 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -3271,7 +3271,7 @@ void TextEditorWidgetPrivate::insertIntoBlockSelection(const QString &text) const QStringList::const_iterator endLine = textLines.constEnd(); for (QStringList::const_iterator textLine = textLines.constBegin(); textLine != endLine; ++textLine) textLength += qMax(0, ts.columnCountForText(*textLine, column) - textLength); - for (QStringList::iterator textLine = textLines.begin(); textLine != endLine; ++textLine) + for (QStringList::iterator textLine = textLines.begin(); textLine != textLines.end(); ++textLine) textLine->append(QString(qMax(0, textLength - ts.columnCountForText(*textLine, column)), QLatin1Char(' '))); // insert Text diff --git a/src/plugins/texteditor/texteditoroverlay.cpp b/src/plugins/texteditor/texteditoroverlay.cpp index 88cffa471c2..025b3206386 100644 --- a/src/plugins/texteditor/texteditoroverlay.cpp +++ b/src/plugins/texteditor/texteditoroverlay.cpp @@ -499,8 +499,9 @@ void TextEditorOverlay::mapEquivalentSelections() const QList &uniqueKeys = all.uniqueKeys(); foreach (const QString &key, uniqueKeys) { QList indexes; - QMap::const_iterator lbit = all.lowerBound(key); - QMap::const_iterator ubit = all.upperBound(key); + const auto cAll = all; + QMap::const_iterator lbit = cAll.lowerBound(key); + QMap::const_iterator ubit = cAll.upperBound(key); while (lbit != ubit) { indexes.append(lbit.value()); ++lbit; diff --git a/src/plugins/valgrind/valgrindsettings.cpp b/src/plugins/valgrind/valgrindsettings.cpp index 7668f51288e..dbf6eda3a70 100644 --- a/src/plugins/valgrind/valgrindsettings.cpp +++ b/src/plugins/valgrind/valgrindsettings.cpp @@ -434,7 +434,7 @@ void ValgrindGlobalSettings::writeSettings() const settings->beginGroup(QLatin1String(groupC)); QVariantMap map; toMap(map); - for (QVariantMap::ConstIterator it = map.begin(); it != map.end(); ++it) + for (QVariantMap::ConstIterator it = map.constBegin(); it != map.constEnd(); ++it) settings->setValue(it.key(), it.value()); settings->endGroup(); } diff --git a/src/plugins/valgrind/xmlprotocol/parser.cpp b/src/plugins/valgrind/xmlprotocol/parser.cpp index 924e363cd9b..95114578bdd 100644 --- a/src/plugins/valgrind/xmlprotocol/parser.cpp +++ b/src/plugins/valgrind/xmlprotocol/parser.cpp @@ -294,7 +294,7 @@ void Parser::Private::checkProtocolVersion(const QString &versionStr) void Parser::Private::checkTool(const QString &reportedStr) { - const QHash::ConstIterator reported = toolsByName.find(reportedStr); + const QHash::ConstIterator reported = toolsByName.constFind(reportedStr); if (reported == toolsByName.constEnd()) throw ParserException(QCoreApplication::translate("Valgrind::XmlProtocol::Parser", @@ -353,7 +353,7 @@ XauxWhat Parser::Private::parseXauxWhat() MemcheckErrorKind Parser::Private::parseMemcheckErrorKind(const QString &kind) { - const QHash::ConstIterator it = errorKindsByName_memcheck.find(kind); + const QHash::ConstIterator it = errorKindsByName_memcheck.constFind(kind); if (it != errorKindsByName_memcheck.constEnd()) return *it; else @@ -363,7 +363,7 @@ MemcheckErrorKind Parser::Private::parseMemcheckErrorKind(const QString &kind) HelgrindErrorKind Parser::Private::parseHelgrindErrorKind(const QString &kind) { - const QHash::ConstIterator it = errorKindsByName_helgrind.find(kind); + const QHash::ConstIterator it = errorKindsByName_helgrind.constFind(kind); if (it != errorKindsByName_helgrind.constEnd()) return *it; else @@ -373,7 +373,7 @@ HelgrindErrorKind Parser::Private::parseHelgrindErrorKind(const QString &kind) PtrcheckErrorKind Parser::Private::parsePtrcheckErrorKind(const QString &kind) { - const QHash::ConstIterator it = errorKindsByName_ptrcheck.find(kind); + const QHash::ConstIterator it = errorKindsByName_ptrcheck.constFind(kind); if (it != errorKindsByName_ptrcheck.constEnd()) return *it; else diff --git a/src/tools/sdktool/findkeyoperation.cpp b/src/tools/sdktool/findkeyoperation.cpp index 9bee22681fc..3ad44f2ba6e 100644 --- a/src/tools/sdktool/findkeyoperation.cpp +++ b/src/tools/sdktool/findkeyoperation.cpp @@ -139,7 +139,7 @@ QStringList FindKeyOperation::findKey(const QVariant &in, const QString &key, co { QStringList result; if (in.type() == QVariant::Map) { - QVariantMap map = in.toMap(); + const QVariantMap map = in.toMap(); for (QVariantMap::const_iterator i = map.begin(); i != map.end(); ++i) { QString pfx = prefix; if (!pfx.isEmpty()) diff --git a/src/tools/sdktool/findvalueoperation.cpp b/src/tools/sdktool/findvalueoperation.cpp index a8d1f66a6a0..cb98b673edc 100644 --- a/src/tools/sdktool/findvalueoperation.cpp +++ b/src/tools/sdktool/findvalueoperation.cpp @@ -152,7 +152,7 @@ QStringList FindValueOperation::findValue(const QVariant &in, const QVariant &va if (in.type() == value.type() && in == value) { result << prefix; } else if (in.type() == QVariant::Map) { - QVariantMap map = in.toMap(); + const QVariantMap map = in.toMap(); for (QVariantMap::const_iterator i = map.begin(); i != map.end(); ++i) { QString pfx = prefix; if (!pfx.isEmpty()) diff --git a/tests/system/suite_debugger/tst_qml_js_console/test.py b/tests/system/suite_debugger/tst_qml_js_console/test.py index 482677e6d2f..c149eeb4a23 100644 --- a/tests/system/suite_debugger/tst_qml_js_console/test.py +++ b/tests/system/suite_debugger/tst_qml_js_console/test.py @@ -142,6 +142,10 @@ def main(): rootIndex = getQModelIndexStr("text='Rectangle'", ":Locals and Expressions_Debugger::Internal::WatchTreeView") # make sure the items inside the root item are visible + if JIRA.isBugStillOpen(14210): + doubleClick(waitForObject(rootIndex)) + else: + test.warning("QTCREATORBUG-14210 is not open anymore. Can the workaround be removed?") doubleClick(waitForObject(rootIndex)) if not object.exists(":DebugModeWidget_QmlJSTools::Internal::QmlConsoleView"): invokeMenuItem("Window", "Output Panes", "QML/JS Console") diff --git a/tests/system/suite_debugger/tst_qml_locals/test.py b/tests/system/suite_debugger/tst_qml_locals/test.py index 1658302ba7c..a9010d00a37 100644 --- a/tests/system/suite_debugger/tst_qml_locals/test.py +++ b/tests/system/suite_debugger/tst_qml_locals/test.py @@ -108,7 +108,16 @@ def main(): def __unfoldTree__(): rootIndex = getQModelIndexStr("text='Rectangle'", ':Locals and Expressions_Debugger::Internal::WatchTreeView') + if JIRA.isBugStillOpen(14210): + doubleClick(waitForObject(rootIndex)) + else: + test.warning("QTCREATORBUG-14210 is not open anymore. Can the workaround be removed?") unfoldQModelIndexIncludingProperties(rootIndex) + if JIRA.isBugStillOpen(14210): + for item in ["text='Rectangle' occurrence='2'", "text='Rectangle' occurrence='2'", "text='Text'"]: + # both Rectangles will be clicked because they change their order + doubleClick(waitForObject(getQModelIndexStr(item, rootIndex))) + snooze(1) subItems = ["text='Rectangle' occurrence='2'", "text='Rectangle'", "text='Text'"] for item in subItems: unfoldQModelIndexIncludingProperties(getQModelIndexStr(item, rootIndex))