From 1d0e61a52c405213e92273bbbde62878695abd37 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Mon, 30 Mar 2015 13:35:03 +0200 Subject: [PATCH 1/6] Squish: Work around items not expanding Task-number: QTCREATORBUG-14210 Change-Id: I64e5b53c5cb82b961ec100d73f0987d79d68f5b4 Reviewed-by: Christian Stenger --- tests/system/suite_debugger/tst_qml_js_console/test.py | 4 ++++ tests/system/suite_debugger/tst_qml_locals/test.py | 9 +++++++++ 2 files changed, 13 insertions(+) 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)) From 7aa8ae54ae6bf12fa69302ec4325b3a23dfd3b2d Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 27 Mar 2015 20:25:41 +0100 Subject: [PATCH 2/6] Device support: Serialize SSH options. We forgot to do the serialization when the options member was added to the SshConnectionParameters class. Task-number: QTCREATORBUG-14205 Change-Id: Id79a2b585d8e00abd5389ccf40821af342a30c30 Reviewed-by: Tobias Hunger --- src/plugins/projectexplorer/devicesupport/idevice.cpp | 4 ++++ 1 file changed, 4 insertions(+) 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); From a212b1f745f660c3fe74be520f5b360c573f46f8 Mon Sep 17 00:00:00 2001 From: Marco Benelli Date: Mon, 23 Mar 2015 15:53:23 +0100 Subject: [PATCH 3/6] Fixed wrong behavior of "Move Component in Separate File" for qml. The dialog accepted/rejected value is now checked. Task-number: QTCREATORBUG-14175 Change-Id: I9a39c0cf87b7e11613a333b2d3a63b77e39b6d97 Reviewed-by: Eike Ziller --- src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp | 5 ++++- src/plugins/qmljseditor/qmljscomponentnamedialog.cpp | 5 ++++- src/plugins/qmljseditor/qmljscomponentnamedialog.h | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) 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(); From 87e01423c90e6ada4b0388f7a7ee3ba83567fd2f Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 1 Apr 2015 14:37:28 +0200 Subject: [PATCH 4/6] Doc: Add documentation for CPU Usage Analyzer Change-Id: I306a009dceba74707b5802b18451c7ae912adac9 Reviewed-by: Leena Miettinen --- doc/images/cpu-usage-analyzer.png | Bin 0 -> 48824 bytes doc/src/analyze/cpu-usage-analyzer.qdoc | 249 ++++++++++++++++++ doc/src/analyze/creator-analyze.qdoc | 6 + .../creator-clang-static-analyzer.qdoc | 2 +- doc/src/overview/creator-advanced.qdoc | 2 +- .../overview/creator-commercial-overview.qdoc | 1 + doc/src/qtcreator.qdoc | 1 + 7 files changed, 259 insertions(+), 2 deletions(-) create mode 100644 doc/images/cpu-usage-analyzer.png create mode 100644 doc/src/analyze/cpu-usage-analyzer.qdoc diff --git a/doc/images/cpu-usage-analyzer.png b/doc/images/cpu-usage-analyzer.png new file mode 100644 index 0000000000000000000000000000000000000000..0a9085c6c75e03ff0873ed4dca035831286a3a5b GIT binary patch literal 48824 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 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 From 46fc33d9147c843d122d8384ab9c1465ef716ee1 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 1 Apr 2015 11:19:32 +0200 Subject: [PATCH 5/6] Don't mix iterator and const_iterator This avoids unnecessary detaches of the Qt container data. The mismatches where detected by defining QT_STRICT_ITERATORS; however, this define violates the ODR (causing linker errors), and therefore is not added permanently. Change-Id: Idd336a9c8b394214a820437ef1b92d2101f6101c GPush-Base: 62b0848b9cf357bcded4184c71d490bae56c773b Reviewed-by: Daniel Teske --- src/libs/cplusplus/LookupContext.cpp | 18 +++++++++--------- src/libs/extensionsystem/pluginmanager.cpp | 4 ++-- src/libs/ssh/sshconnection.cpp | 2 +- src/libs/ssh/sshhostkeydatabase.cpp | 2 +- src/plugins/android/androidmanager.cpp | 3 ++- src/plugins/classview/classviewparser.cpp | 12 ++++++------ src/plugins/clearcase/clearcasesync.cpp | 4 ++-- src/plugins/cpptools/cppsourceprocessor.cpp | 4 ++-- src/plugins/debugger/gdb/gdbengine.cpp | 6 +++--- .../debugger/qml/qmlv8debuggerclient.cpp | 4 ++-- src/plugins/projectexplorer/msvctoolchain.cpp | 2 +- src/plugins/projectexplorer/session.cpp | 2 +- src/plugins/projectexplorer/wincetoolchain.cpp | 2 +- .../qmlprofilereventsmodelproxy.cpp | 2 +- src/plugins/qtsupport/qtversionmanager.cpp | 2 +- .../abstractremotelinuxdeployservice.cpp | 2 +- .../texteditor/snippets/snippetscollection.cpp | 2 +- src/plugins/texteditor/texteditor.cpp | 2 +- src/plugins/texteditor/texteditoroverlay.cpp | 5 +++-- src/plugins/valgrind/valgrindsettings.cpp | 2 +- src/plugins/valgrind/xmlprotocol/parser.cpp | 8 ++++---- src/tools/sdktool/findkeyoperation.cpp | 2 +- src/tools/sdktool/findvalueoperation.cpp | 2 +- 23 files changed, 48 insertions(+), 46 deletions(-) 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 d34db47d255..5bf467e7314 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -1527,8 +1527,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/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/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/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 04d6cfa5774..af407726bc4 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()) From fd0b383932452ae20fa83e9224d473014dedc841 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 1 Apr 2015 16:49:43 +0200 Subject: [PATCH 6/6] About Plugins: Fix sorting by "Load" column Change-Id: I705a717ff13e23bafcffb0d41edceab95d3607e6 Task-number: QTCREATORBUG-14107 Reviewed-by: Eike Ziller --- src/libs/extensionsystem/pluginview.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/libs/extensionsystem/pluginview.cpp b/src/libs/extensionsystem/pluginview.cpp index 97b87f84db9..9875a3d5d3b 100644 --- a/src/libs/extensionsystem/pluginview.cpp +++ b/src/libs/extensionsystem/pluginview.cpp @@ -81,6 +81,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[] = { @@ -104,7 +106,7 @@ public: { switch (column) { case NameColumn: - if (role == Qt::DisplayRole) + if (role == Qt::DisplayRole || role == SortRole) return m_spec->name(); if (role == Qt::ToolTipRole) return QDir::toNativeSeparators(m_spec->filePath()); @@ -119,17 +121,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->isEnabledInSettings() ? Qt::Checked : Qt::Unchecked; if (role == Qt::ToolTipRole) return PluginView::tr("Load on startup"); @@ -137,12 +139,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; } @@ -207,7 +209,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) { @@ -223,7 +225,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->isEnabledInSettings()) @@ -291,6 +293,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);