diff options
15 files changed, 163 insertions, 251 deletions
diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index da05ff570f3..05446d3760c 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -828,7 +828,7 @@ ProcessInterface *DockerDevice::createProcessInterface() const return new DockerProcessImpl(this->sharedFromThis(), d); } -DeviceProcessList *DockerDevice::createProcessListModel(QObject *parent) const +ProcessList *DockerDevice::createProcessListModel(QObject *parent) const { return new ProcessList(sharedFromThis(), parent); } diff --git a/src/plugins/docker/dockerdevice.h b/src/plugins/docker/dockerdevice.h index bd0ce29d9d4..e3e7bbf6b4b 100644 --- a/src/plugins/docker/dockerdevice.h +++ b/src/plugins/docker/dockerdevice.h @@ -74,7 +74,7 @@ public: Utils::ProcessInterface *createProcessInterface() const override; bool canCreateProcessModel() const override { return true; } - ProjectExplorer::DeviceProcessList *createProcessListModel(QObject *parent) const override; + ProjectExplorer::ProcessList *createProcessListModel(QObject *parent) const override; bool hasDeviceTester() const override { return false; } ProjectExplorer::DeviceTester *createDeviceTester() const override; bool usableAsBuildDevice() const override; diff --git a/src/plugins/projectexplorer/CMakeLists.txt b/src/plugins/projectexplorer/CMakeLists.txt index d16e868a5cc..b9758fbfe7e 100644 --- a/src/plugins/projectexplorer/CMakeLists.txt +++ b/src/plugins/projectexplorer/CMakeLists.txt @@ -55,7 +55,6 @@ add_qtc_plugin(ProjectExplorer devicesupport/devicemanager.cpp devicesupport/devicemanager.h devicesupport/devicemanagermodel.cpp devicesupport/devicemanagermodel.h devicesupport/deviceprocessesdialog.cpp devicesupport/deviceprocessesdialog.h - devicesupport/deviceprocesslist.cpp devicesupport/deviceprocesslist.h devicesupport/devicesettingspage.cpp devicesupport/devicesettingspage.h devicesupport/devicesettingswidget.cpp devicesupport/devicesettingswidget.h devicesupport/devicetestdialog.cpp devicesupport/devicetestdialog.h diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp index 33ed3287cf0..bcd133488d7 100644 --- a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp @@ -6,7 +6,6 @@ #include "../projectexplorerconstants.h" #include "../projectexplorertr.h" #include "desktopprocesssignaloperation.h" -#include "deviceprocesslist.h" #include "processlist.h" #include <coreplugin/fileutils.h> @@ -90,7 +89,7 @@ bool DesktopDevice::canCreateProcessModel() const return true; } -DeviceProcessList *DesktopDevice::createProcessListModel(QObject *parent) const +ProcessList *DesktopDevice::createProcessListModel(QObject *parent) const { return new ProcessList(sharedFromThis(), parent); } diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.h b/src/plugins/projectexplorer/devicesupport/desktopdevice.h index bc4c353b465..bf5566d568c 100644 --- a/src/plugins/projectexplorer/devicesupport/desktopdevice.h +++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.h @@ -26,7 +26,7 @@ public: IDeviceWidget *createWidget() override; bool canCreateProcessModel() const override; - DeviceProcessList *createProcessListModel(QObject *parent) const override; + ProcessList *createProcessListModel(QObject *parent) const override; DeviceProcessSignalOperation::Ptr signalOperation() const override; QUrl toolControlChannel(const ControlChannelHint &) const override; bool usableAsBuildDevice() const override; diff --git a/src/plugins/projectexplorer/devicesupport/deviceprocessesdialog.cpp b/src/plugins/projectexplorer/devicesupport/deviceprocessesdialog.cpp index 4c75ea39899..67545e6329c 100644 --- a/src/plugins/projectexplorer/devicesupport/deviceprocessesdialog.cpp +++ b/src/plugins/projectexplorer/devicesupport/deviceprocessesdialog.cpp @@ -3,8 +3,8 @@ #include "deviceprocessesdialog.h" -#include "deviceprocesslist.h" #include "idevice.h" +#include "processlist.h" #include "../kitchooser.h" #include "../kitinformation.h" #include "../projectexplorertr.h" @@ -84,7 +84,7 @@ public: ProcessInfo selectedProcess() const; QDialog *q; - std::unique_ptr<DeviceProcessList> processList; + std::unique_ptr<ProcessList> processList; ProcessListFilterModel proxyModel; QLabel *kitLabel; KitChooser *kitChooser; @@ -191,11 +191,11 @@ void DeviceProcessesDialogPrivate::setDevice(const IDevice::ConstPtr &device) QTC_ASSERT(processList, return); proxyModel.setSourceModel(processList->model()); - connect(processList.get(), &DeviceProcessList::error, + connect(processList.get(), &ProcessList::error, this, &DeviceProcessesDialogPrivate::handleRemoteError); - connect(processList.get(), &DeviceProcessList::processListUpdated, + connect(processList.get(), &ProcessList::processListUpdated, this, &DeviceProcessesDialogPrivate::handleProcessListUpdated); - connect(processList.get(), &DeviceProcessList::processKilled, + connect(processList.get(), &ProcessList::processKilled, this, &DeviceProcessesDialogPrivate::handleProcessKilled, Qt::QueuedConnection); updateButtons(); diff --git a/src/plugins/projectexplorer/devicesupport/deviceprocesslist.cpp b/src/plugins/projectexplorer/devicesupport/deviceprocesslist.cpp deleted file mode 100644 index 6645a478ecb..00000000000 --- a/src/plugins/projectexplorer/devicesupport/deviceprocesslist.cpp +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include "deviceprocesslist.h" - -#include "idevice.h" -#include "../projectexplorertr.h" - -#include <utils/processinfo.h> -#include <utils/qtcassert.h> -#include <utils/treemodel.h> - -using namespace Utils; - -namespace ProjectExplorer { -namespace Internal { - -enum State { Inactive, Listing, Killing }; - -class DeviceProcessTreeItem : public TreeItem -{ -public: - DeviceProcessTreeItem(const ProcessInfo &p, Qt::ItemFlags f) : process(p), fl(f) {} - - QVariant data(int column, int role) const final; - Qt::ItemFlags flags(int) const final { return fl; } - - ProcessInfo process; - Qt::ItemFlags fl; -}; - -class DeviceProcessListPrivate -{ -public: - DeviceProcessListPrivate(const IDevice::ConstPtr &device) - : device(device) - { } - - qint64 ownPid = -1; - const IDevice::ConstPtr device; - State state = Inactive; - TreeModel<TypedTreeItem<DeviceProcessTreeItem>, DeviceProcessTreeItem> model; -}; - -} // namespace Internal - -using namespace Internal; - -DeviceProcessList::DeviceProcessList(const IDevice::ConstPtr &device, QObject *parent) - : QObject(parent), d(std::make_unique<DeviceProcessListPrivate>(device)) -{ - d->model.setHeader({Tr::tr("Process ID"), Tr::tr("Command Line")}); -} - -DeviceProcessList::~DeviceProcessList() = default; - -void DeviceProcessList::update() -{ - QTC_ASSERT(d->state == Inactive, return); - QTC_ASSERT(device(), return); - - d->model.clear(); - d->model.rootItem()->appendChild( - new DeviceProcessTreeItem( - {0, Tr::tr("Fetching process list. This might take a while."), ""}, - Qt::NoItemFlags)); - d->state = Listing; - doUpdate(); -} - -void DeviceProcessList::reportProcessListUpdated(const QList<ProcessInfo> &processes) -{ - QTC_ASSERT(d->state == Listing, return); - setFinished(); - d->model.clear(); - for (const ProcessInfo &process : processes) { - Qt::ItemFlags fl; - if (process.processId != d->ownPid) - fl = Qt::ItemIsEnabled | Qt::ItemIsSelectable; - d->model.rootItem()->appendChild(new DeviceProcessTreeItem(process, fl)); - } - - emit processListUpdated(); -} - -void DeviceProcessList::killProcess(int row) -{ - QTC_ASSERT(row >= 0 && row < d->model.rootItem()->childCount(), return); - QTC_ASSERT(d->state == Inactive, return); - QTC_ASSERT(device(), return); - - d->state = Killing; - doKillProcess(at(row)); -} - -void DeviceProcessList::setOwnPid(qint64 pid) -{ - d->ownPid = pid; -} - -void DeviceProcessList::reportProcessKilled() -{ - QTC_ASSERT(d->state == Killing, return); - setFinished(); - emit processKilled(); -} - -ProcessInfo DeviceProcessList::at(int row) const -{ - return d->model.rootItem()->childAt(row)->process; -} - -QAbstractItemModel *DeviceProcessList::model() const -{ - return &d->model; -} - -QVariant DeviceProcessTreeItem::data(int column, int role) const -{ - if (role == Qt::DisplayRole || role == Qt::ToolTipRole) { - if (column == 0) - return process.processId ? process.processId : QVariant(); - else - return process.commandLine; - } - return QVariant(); -} - -void DeviceProcessList::setFinished() -{ - d->state = Inactive; -} - -IDevice::ConstPtr DeviceProcessList::device() const -{ - return d->device; -} - -void DeviceProcessList::reportError(const QString &message) -{ - QTC_ASSERT(d->state != Inactive, return); - setFinished(); - emit error(message); -} - -} // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/devicesupport/deviceprocesslist.h b/src/plugins/projectexplorer/devicesupport/deviceprocesslist.h deleted file mode 100644 index 1faa5c19881..00000000000 --- a/src/plugins/projectexplorer/devicesupport/deviceprocesslist.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include "../projectexplorer_export.h" -#include "idevicefwd.h" - -#include <QAbstractItemModel> -#include <QList> - -#include <memory> - -namespace Utils { class ProcessInfo; } - -namespace ProjectExplorer { - -namespace Internal { class DeviceProcessListPrivate; } - -class PROJECTEXPLORER_EXPORT DeviceProcessList : public QObject -{ - Q_OBJECT - -public: - DeviceProcessList(const IDeviceConstPtr &device, QObject *parent = nullptr); - ~DeviceProcessList() override; - - void update(); - void killProcess(int row); - void setOwnPid(qint64 pid); - - Utils::ProcessInfo at(int row) const; - QAbstractItemModel *model() const; - -signals: - void processListUpdated(); - void error(const QString &errorMsg); - void processKilled(); - -protected: - void reportError(const QString &message); - void reportProcessKilled(); - void reportProcessListUpdated(const QList<Utils::ProcessInfo> &processes); - - IDeviceConstPtr device() const; - -private: - virtual void doUpdate() = 0; - virtual void doKillProcess(const Utils::ProcessInfo &process) = 0; - - void setFinished(); - - const std::unique_ptr<Internal::DeviceProcessListPrivate> d; -}; - -} // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp index 12ff8e3cac3..b35f8be9785 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp @@ -4,8 +4,8 @@ #include "idevice.h" #include "devicemanager.h" -#include "deviceprocesslist.h" #include "idevicefactory.h" +#include "processlist.h" #include "sshparameters.h" #include "../kit.h" @@ -393,7 +393,7 @@ PortsGatheringMethod IDevice::portsGatheringMethod() const &Port::parseFromCommandOutput}; }; -DeviceProcessList *IDevice::createProcessListModel(QObject *parent) const +ProcessList *IDevice::createProcessListModel(QObject *parent) const { Q_UNUSED(parent) QTC_ASSERT(false, qDebug("This should not have been called..."); return nullptr); diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h index e28f88aaf46..845acb94f83 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.h +++ b/src/plugins/projectexplorer/devicesupport/idevice.h @@ -41,7 +41,7 @@ class Process; namespace ProjectExplorer { -class DeviceProcessList; +class ProcessList; class FileTransferInterface; class FileTransferSetupData; class Kit; @@ -142,7 +142,7 @@ public: virtual PortsGatheringMethod portsGatheringMethod() const; virtual bool canCreateProcessModel() const { return false; } - virtual DeviceProcessList *createProcessListModel(QObject *parent = nullptr) const; + virtual ProcessList *createProcessListModel(QObject *parent = nullptr) const; virtual bool hasDeviceTester() const { return false; } virtual DeviceTester *createDeviceTester() const; diff --git a/src/plugins/projectexplorer/devicesupport/processlist.cpp b/src/plugins/projectexplorer/devicesupport/processlist.cpp index 11e0932832d..2d69fb404ec 100644 --- a/src/plugins/projectexplorer/devicesupport/processlist.cpp +++ b/src/plugins/projectexplorer/devicesupport/processlist.cpp @@ -3,8 +3,12 @@ #include "processlist.h" -#include <projectexplorer/devicesupport/idevice.h> +#include "idevice.h" +#include "../projectexplorertr.h" + #include <utils/processinfo.h> +#include <utils/qtcassert.h> +#include <utils/treemodel.h> #include <QTimer> @@ -17,45 +21,140 @@ using namespace Utils; namespace ProjectExplorer { +namespace Internal { -ProcessList::ProcessList(const IDevice::ConstPtr &device, QObject *parent) - : DeviceProcessList(device, parent) +enum State { Inactive, Listing, Killing }; + +class DeviceProcessTreeItem : public TreeItem { +public: + DeviceProcessTreeItem(const ProcessInfo &p, Qt::ItemFlags f) : process(p), fl(f) {} + + QVariant data(int column, int role) const final; + Qt::ItemFlags flags(int) const final { return fl; } + + ProcessInfo process; + Qt::ItemFlags fl; +}; + +class DeviceProcessListPrivate +{ +public: + DeviceProcessListPrivate(const IDevice::ConstPtr &device) + : device(device) + { + // FIXME: This should not be used for non-desktop cases. #if defined(Q_OS_UNIX) - setOwnPid(getpid()); + ownPid = getpid(); #elif defined(Q_OS_WIN) - setOwnPid(GetCurrentProcessId()); + ownPid = GetCurrentProcessId(); #endif + } + + qint64 ownPid = -1; + const IDevice::ConstPtr device; + State state = Inactive; + TreeModel<TypedTreeItem<DeviceProcessTreeItem>, DeviceProcessTreeItem> model; + DeviceProcessSignalOperation::Ptr signalOperation; +}; + +} // namespace Internal + +using namespace Internal; + +ProcessList::ProcessList(const IDevice::ConstPtr &device, QObject *parent) + : QObject(parent), d(std::make_unique<DeviceProcessListPrivate>(device)) +{ + d->model.setHeader({Tr::tr("Process ID"), Tr::tr("Command Line")}); } -void ProcessList::doKillProcess(const ProcessInfo &processInfo) +ProcessList::~ProcessList() = default; + +void ProcessList::update() { - m_signalOperation = device()->signalOperation(); - connect(m_signalOperation.data(), - &DeviceProcessSignalOperation::finished, - this, - &ProcessList::reportDelayedKillStatus); - m_signalOperation->killProcess(processInfo.processId); + QTC_ASSERT(d->state == Inactive, return); + QTC_ASSERT(d->device, return); + + d->model.clear(); + d->model.rootItem()->appendChild( + new DeviceProcessTreeItem( + {0, Tr::tr("Fetching process list. This might take a while."), ""}, + Qt::NoItemFlags)); + d->state = Listing; + + QTimer::singleShot(0, this, &ProcessList::handleUpdate); } -void ProcessList::handleUpdate() +void ProcessList::killProcess(int row) { - reportProcessListUpdated(ProcessInfo::processInfoList(DeviceProcessList::device()->rootPath())); + QTC_ASSERT(row >= 0 && row < d->model.rootItem()->childCount(), return); + QTC_ASSERT(d->state == Inactive, return); + QTC_ASSERT(d->device, return); + + d->state = Killing; + + const ProcessInfo processInfo = at(row); + d->signalOperation = d->device->signalOperation(); + connect(d->signalOperation.data(), &DeviceProcessSignalOperation::finished, + this, &ProcessList::reportDelayedKillStatus); + d->signalOperation->killProcess(processInfo.processId); } -void ProcessList::doUpdate() +ProcessInfo ProcessList::at(int row) const { - QTimer::singleShot(0, this, &ProcessList::handleUpdate); + return d->model.rootItem()->childAt(row)->process; +} + +QAbstractItemModel *ProcessList::model() const +{ + return &d->model; +} + +QVariant DeviceProcessTreeItem::data(int column, int role) const +{ + if (role == Qt::DisplayRole || role == Qt::ToolTipRole) { + if (column == 0) + return process.processId ? process.processId : QVariant(); + else + return process.commandLine; + } + return QVariant(); +} + +void ProcessList::setFinished() +{ + d->state = Inactive; +} + +void ProcessList::handleUpdate() +{ + const QList<ProcessInfo> processes = ProcessInfo::processInfoList(d->device->rootPath()); + QTC_ASSERT(d->state == Listing, return); + setFinished(); + d->model.clear(); + for (const ProcessInfo &process : processes) { + Qt::ItemFlags fl; + if (process.processId != d->ownPid) + fl = Qt::ItemIsEnabled | Qt::ItemIsSelectable; + d->model.rootItem()->appendChild(new DeviceProcessTreeItem(process, fl)); + } + + emit processListUpdated(); } void ProcessList::reportDelayedKillStatus(const QString &errorMessage) { - if (errorMessage.isEmpty()) - reportProcessKilled(); - else - reportError(errorMessage); + if (errorMessage.isEmpty()) { + QTC_CHECK(d->state == Killing); + setFinished(); + emit processKilled(); + } else { + QTC_CHECK(d->state != Inactive); + setFinished(); + emit error(errorMessage); + } - m_signalOperation.reset(); + d->signalOperation.reset(); } -} // namespace ProjectExplorer +} // ProjectExplorer diff --git a/src/plugins/projectexplorer/devicesupport/processlist.h b/src/plugins/projectexplorer/devicesupport/processlist.h index caebaf22f97..6b9f9b9cc5f 100644 --- a/src/plugins/projectexplorer/devicesupport/processlist.h +++ b/src/plugins/projectexplorer/devicesupport/processlist.h @@ -3,28 +3,46 @@ #pragma once -#include "deviceprocesslist.h" -#include "idevice.h" +#include "../projectexplorer_export.h" +#include "idevicefwd.h" + +#include <QAbstractItemModel> +#include <QList> + +#include <memory> + +namespace Utils { class ProcessInfo; } namespace ProjectExplorer { -class PROJECTEXPLORER_EXPORT ProcessList : public DeviceProcessList +namespace Internal { class DeviceProcessListPrivate; } + +class PROJECTEXPLORER_EXPORT ProcessList : public QObject { Q_OBJECT public: - explicit ProcessList(const IDeviceConstPtr &device, QObject *parent = nullptr); + ProcessList(const IDeviceConstPtr &device, QObject *parent = nullptr); + ~ProcessList() override; -private: - void doUpdate() override; - void doKillProcess(const Utils::ProcessInfo &process) override; + void update(); + void killProcess(int row); + + Utils::ProcessInfo at(int row) const; + QAbstractItemModel *model() const; + +signals: + void processListUpdated(); + void error(const QString &errorMsg); + void processKilled(); private: void handleUpdate(); void reportDelayedKillStatus(const QString &errorMessage); -private: - DeviceProcessSignalOperation::Ptr m_signalOperation; + void setFinished(); + + const std::unique_ptr<Internal::DeviceProcessListPrivate> d; }; } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs index c955a485905..420296a306b 100644 --- a/src/plugins/projectexplorer/projectexplorer.qbs +++ b/src/plugins/projectexplorer/projectexplorer.qbs @@ -210,7 +210,6 @@ Project { "devicemanager.cpp", "devicemanager.h", "devicemanagermodel.cpp", "devicemanagermodel.h", "deviceprocessesdialog.cpp", "deviceprocessesdialog.h", - "deviceprocesslist.cpp", "deviceprocesslist.h", "devicesettingspage.cpp", "devicesettingspage.h", "devicesettingswidget.cpp", "devicesettingswidget.h", "devicetestdialog.cpp", "devicetestdialog.h", diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index 61939f20954..a38f1c081a1 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -995,7 +995,7 @@ IDeviceWidget *LinuxDevice::createWidget() return new Internal::GenericLinuxDeviceConfigurationWidget(sharedFromThis()); } -DeviceProcessList *LinuxDevice::createProcessListModel(QObject *parent) const +ProcessList *LinuxDevice::createProcessListModel(QObject *parent) const { return new ProcessList(sharedFromThis(), parent); } diff --git a/src/plugins/remotelinux/linuxdevice.h b/src/plugins/remotelinux/linuxdevice.h index 2094b426b4c..36179c83ea8 100644 --- a/src/plugins/remotelinux/linuxdevice.h +++ b/src/plugins/remotelinux/linuxdevice.h @@ -23,7 +23,7 @@ public: ProjectExplorer::IDeviceWidget *createWidget() override; bool canCreateProcessModel() const override { return true; } - ProjectExplorer::DeviceProcessList *createProcessListModel(QObject *parent) const override; + ProjectExplorer::ProcessList *createProcessListModel(QObject *parent) const override; bool hasDeviceTester() const override { return true; } ProjectExplorer::DeviceTester *createDeviceTester() const override; ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const override; |