ProjectExplorer: Use Utils::TreeModel for DeviceProcessList

Cuts down boilerplate.

Change-Id: Ia75e6aec481fbb00b388c6c99b2833723d63bed8
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
hjk
2019-02-27 14:56:19 +01:00
parent 0523a7f38b
commit ce9b3358fb
5 changed files with 53 additions and 86 deletions

View File

@@ -215,7 +215,7 @@ void DeviceProcessesDialogPrivate::setDevice(const IDevice::ConstPtr &device)
processList = device->createProcessListModel();
QTC_ASSERT(processList, return);
proxyModel.setSourceModel(processList);
proxyModel.setSourceModel(processList->model());
connect(processList, &DeviceProcessList::error,
this, &DeviceProcessesDialogPrivate::handleRemoteError);

View File

@@ -27,23 +27,38 @@
#include "localprocesslist.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 DeviceProcessItem &p, Qt::ItemFlags f) : process(p), fl(f) {}
QVariant data(int column, int role) const final;
Qt::ItemFlags flags(int) const final { return fl; }
DeviceProcessItem process;
Qt::ItemFlags fl;
};
class DeviceProcessListPrivate
{
public:
DeviceProcessListPrivate(const IDevice::ConstPtr &device)
: device(device),
state(Inactive)
: device(device)
{ }
qint64 ownPid = -1;
const IDevice::ConstPtr device;
QList<DeviceProcessItem> remoteProcesses;
State state;
State state = Inactive;
TreeModel<TypedTreeItem<DeviceProcessTreeItem>, DeviceProcessTreeItem> model;
};
} // namespace Internal
@@ -51,39 +66,19 @@ public:
using namespace Internal;
DeviceProcessList::DeviceProcessList(const IDevice::ConstPtr &device, QObject *parent)
: QAbstractItemModel(parent), d(std::make_unique<DeviceProcessListPrivate>(device))
{ }
: QObject(parent), d(std::make_unique<DeviceProcessListPrivate>(device))
{
d->model.setHeader({tr("Process ID"), tr("Command Line")});
}
DeviceProcessList::~DeviceProcessList() = default;
QModelIndex DeviceProcessList::parent(const QModelIndex &) const
{
return QModelIndex();
}
bool DeviceProcessList::hasChildren(const QModelIndex &parent) const
{
if (!parent.isValid())
return rowCount(parent) > 0 && columnCount(parent) > 0;
return false;
}
QModelIndex DeviceProcessList::index(int row, int column, const QModelIndex &parent) const
{
return hasIndex(row, column, parent) ? createIndex(row, column) : QModelIndex();
}
void DeviceProcessList::update()
{
QTC_ASSERT(d->state == Inactive, return);
QTC_ASSERT(device(), return);
if (!d->remoteProcesses.isEmpty()) {
beginRemoveRows(QModelIndex(), 0, d->remoteProcesses.count() - 1);
d->remoteProcesses.clear();
endRemoveRows();
}
d->model.clear();
d->state = Listing;
doUpdate();
}
@@ -92,22 +87,29 @@ void DeviceProcessList::reportProcessListUpdated(const QList<DeviceProcessItem>
{
QTC_ASSERT(d->state == Listing, return);
setFinished();
if (!processes.isEmpty()) {
beginInsertRows(QModelIndex(), 0, processes.count() - 1);
d->remoteProcesses = processes;
endInsertRows();
for (const DeviceProcessItem &process : processes) {
Qt::ItemFlags fl;
if (process.pid != 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->remoteProcesses.count(), return);
QTC_ASSERT(row >= 0 && row < d->model.rootItem()->childCount(), return);
QTC_ASSERT(d->state == Inactive, return);
QTC_ASSERT(device(), return);
d->state = Killing;
doKillProcess(d->remoteProcesses.at(row));
doKillProcess(at(row));
}
void DeviceProcessList::setOwnPid(qint64 pid)
{
d->ownPid = pid;
}
void DeviceProcessList::reportProcessKilled()
@@ -119,40 +121,21 @@ void DeviceProcessList::reportProcessKilled()
DeviceProcessItem DeviceProcessList::at(int row) const
{
return d->remoteProcesses.at(row);
return d->model.rootItem()->childAt(row)->process;
}
int DeviceProcessList::rowCount(const QModelIndex &parent) const
QAbstractItemModel *DeviceProcessList::model() const
{
return parent.isValid() ? 0 : d->remoteProcesses.count();
return &d->model;
}
int DeviceProcessList::columnCount(const QModelIndex &) const
QVariant DeviceProcessTreeItem::data(int column, int role) const
{
return 2;
}
QVariant DeviceProcessList::headerData(int section, Qt::Orientation orientation,
int role) const
{
if (orientation != Qt::Horizontal || role != Qt::DisplayRole || section < 0
|| section >= columnCount())
return QVariant();
return section == 0? tr("Process ID") : tr("Command Line");
}
QVariant DeviceProcessList::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() >= rowCount(index.parent())
|| index.column() >= columnCount())
return QVariant();
if (role == Qt::DisplayRole || role == Qt::ToolTipRole) {
const DeviceProcessItem &proc = d->remoteProcesses.at(index.row());
if (index.column() == 0)
return proc.pid;
if (column == 0)
return process.pid;
else
return proc.cmdLine;
return process.cmdLine;
}
return QVariant();
}

View File

@@ -46,7 +46,7 @@ public:
QString exe;
};
class PROJECTEXPLORER_EXPORT DeviceProcessList : public QAbstractItemModel
class PROJECTEXPLORER_EXPORT DeviceProcessList : public QObject
{
Q_OBJECT
@@ -56,7 +56,10 @@ public:
void update();
void killProcess(int row);
void setOwnPid(qint64 pid);
DeviceProcessItem at(int row) const;
QAbstractItemModel *model() const;
static QList<DeviceProcessItem> localProcesses();
@@ -73,15 +76,6 @@ protected:
IDevice::ConstPtr device() const;
private:
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QModelIndex parent(const QModelIndex &) const override;
bool hasChildren(const QModelIndex &parent) const override;
virtual void doUpdate() = 0;
virtual void doKillProcess(const DeviceProcessItem &process) = 0;

View File

@@ -56,8 +56,8 @@ namespace Internal {
LocalProcessList::LocalProcessList(const IDevice::ConstPtr &device, QObject *parent)
: DeviceProcessList(device, parent)
, m_myPid(GetCurrentProcessId())
{
setOwnPid(GetCurrentProcessId())
}
QList<DeviceProcessItem> LocalProcessList::getLocalProcesses()
@@ -89,8 +89,9 @@ QList<DeviceProcessItem> LocalProcessList::getLocalProcesses()
#ifdef Q_OS_UNIX
LocalProcessList::LocalProcessList(const IDevice::ConstPtr &device, QObject *parent)
: DeviceProcessList(device, parent)
, m_myPid(getpid())
{}
{
setOwnPid(getpid());
}
static bool isUnixProcessId(const QString &procname)
{
@@ -206,14 +207,6 @@ void LocalProcessList::doKillProcess(const DeviceProcessItem &process)
signalOperation->killProcess(process.pid);
}
Qt::ItemFlags LocalProcessList::flags(const QModelIndex &index) const
{
Qt::ItemFlags flags = DeviceProcessList::flags(index);
if (index.isValid() && at(index.row()).pid == m_myPid)
flags &= ~(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
return flags;
}
void LocalProcessList::handleUpdate()
{
reportProcessListUpdated(getLocalProcesses());

View File

@@ -36,7 +36,6 @@ class LocalProcessList : public DeviceProcessList
public:
explicit LocalProcessList(const IDevice::ConstPtr &device, QObject *parent = nullptr);
Qt::ItemFlags flags(const QModelIndex &index) const override;
static QList<DeviceProcessItem> getLocalProcesses();
@@ -47,8 +46,6 @@ private:
private:
void handleUpdate();
void reportDelayedKillStatus(const QString &errorMessage);
const qint64 m_myPid;
};
} // namespace Internal