Paste P470

Masterwork From Distant Lands
ActivePublic

Authored by davidedmundson on Sep 18 2019, 12:31 PM.
diff --git a/processcore/extended_process_list.cpp b/processcore/extended_process_list.cpp
index b01aff4..6ebe54c 100644
--- a/processcore/extended_process_list.cpp
+++ b/processcore/extended_process_list.cpp
@@ -21,10 +21,13 @@
#include <KPluginLoader>
#include <KPluginFactory>
#include <KPluginMetaData>
+#include <KLocalizedString>
+#include <KUser>
#include "process_data_provider.h"
#include "process_attribute.h"
#include "processcore_debug.h"
+#include "process.h"
using namespace KSysGuard;
@@ -35,9 +38,38 @@ public:
void loadPlugins();
ExtendedProcesses *q;
+ QVector<ProcessAttribute *> m_coreAttributes;
QVector<ProcessDataProvider *> m_providers;
};
+template <class T>
+class ProcessSensor : public KSysGuard::ProcessAttribute
+{
+public:
+ ProcessSensor(ExtendedProcesses *parent, const QString &id, const QString &name, std::function<T(KSysGuard::Process *)> extractFunc, KSysGuard::Process::Change changeFlag = KSysGuard::Process::Nothing)
+ : KSysGuard::ProcessAttribute(id, name, parent)
+ , m_extractFunc(extractFunc)
+ , m_changeFlag(changeFlag)
+ {
+ if (m_changeFlag != 0) {
+ connect(parent, &ExtendedProcesses::processChanged, this, [=](KSysGuard::Process *process) {
+ if (!process->changes().testFlag(m_changeFlag)) {
+ return;
+ }
+ emit dataChanged(process);
+ });
+ }
+ }
+
+ QVariant data(KSysGuard::Process *process) const override
+ {
+ return QVariant::fromValue(m_extractFunc(process));
+ }
+
+ std::function<T(KSysGuard::Process *)> m_extractFunc;
+ KSysGuard::Process::Change m_changeFlag;
+};
+
ExtendedProcesses::Private::Private(ExtendedProcesses *_q)
: q(_q)
{
@@ -49,6 +81,257 @@ ExtendedProcesses::ExtendedProcesses(QObject *parent)
{
d->loadPlugins();
+ auto pidSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/pid"), i18n("PID"), &KSysGuard::Process::pid, KSysGuard::Process::Status);
+ pidSensor->setDescription(i18n("The unique Process ID that identifies this process."));
+ d->m_coreAttributes << pidSensor;
+
+ auto parentPidSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/parentPid"), i18n("Parent PID"), &KSysGuard::Process::parentPid);
+ d->m_coreAttributes << parentPidSensor;
+
+ auto loginSensor = new ProcessSensor<QString>(this, QStringLiteral("process/login"), i18n("Login"), &KSysGuard::Process::login, KSysGuard::Process::Login);
+ loginSensor->setDescription(i18n("The user who owns this process."));
+ d->m_coreAttributes << loginSensor;
+
+ auto uidSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/uid"), i18n("UID"), &KSysGuard::Process::uid, KSysGuard::Process::Uids);
+ d->m_coreAttributes << uidSensor;
+
+ auto userNameSensor = new ProcessSensor<QString>(this, QStringLiteral("process/username"), i18n("Username"), [](KSysGuard::Process *p) {
+ KUser user(p->uid());
+ QString username;
+ if (user.isValid()) {
+ username = user.loginName();
+ }
+ return username;
+ }, KSysGuard::Process::Uids);
+ d->m_coreAttributes << userNameSensor;
+
+ auto canUserLoginSensor = new ProcessSensor<bool>(this, QStringLiteral("process/canUserLogin"), i18n("Can Login"), [](KSysGuard::Process *p) {
+ K_UID uid = p->uid();
+ if (uid == 65534) {
+ return false;
+ }
+
+ KUser user(uid);
+ if (!user.isValid()) {
+ //for some reason the user isn't recognised. This might happen under certain security situations.
+ //Just return true to be safe
+ return true;
+ }
+ const QString shell = user.shell();
+ if (shell == QLatin1String("/bin/false")) { //FIXME - add in any other shells it could be for false
+ return false;
+ }
+ return true;
+ }, KSysGuard::Process::Uids);
+ d->m_coreAttributes << canUserLoginSensor;
+
+ auto euidSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/euid"), i18n("EUID"), &KSysGuard::Process::euid, KSysGuard::Process::Uids);
+ d->m_coreAttributes << euidSensor;
+
+ auto suidSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/suid"),
+ i18n("suid"), &KSysGuard::Process::suid, KSysGuard::Process::Uids);
+ d->m_coreAttributes << suidSensor;
+
+ auto fsuidSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/fsuid"), i18n("fsuid"), &KSysGuard::Process::fsuid, KSysGuard::Process::Uids);
+ d->m_coreAttributes << fsuidSensor;
+
+ auto gidSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/gid"), i18n("gid"), &KSysGuard::Process::gid, KSysGuard::Process::Gids);
+ d->m_coreAttributes << gidSensor;
+
+ auto egidSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/egid"), i18n("egid"), &KSysGuard::Process::egid, KSysGuard::Process::Gids);
+ d->m_coreAttributes << egidSensor;
+
+ auto sgidSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/sgid"), i18n("sgid"), &KSysGuard::Process::sgid, KSysGuard::Process::Gids);
+ d->m_coreAttributes << sgidSensor;
+
+ auto fsgidSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/fsgid"), i18n("fsgid"), &KSysGuard::Process::fsgid, KSysGuard::Process::Gids);
+ d->m_coreAttributes << fsgidSensor;
+
+ auto tracerpidSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/tracerpid"), i18n("Tracer Pid"), &KSysGuard::Process::tracerpid);
+ d->m_coreAttributes << tracerpidSensor;
+
+
+ auto ttySensor = new ProcessSensor<QByteArray>(this, QStringLiteral("process/tty"), i18n("tty"), &KSysGuard::Process::tty, KSysGuard::Process::Tty);
+ ttySensor->setDescription(i18n("The controlling terminal on which this process is running."));
+ d->m_coreAttributes << ttySensor;
+
+ auto userTimeSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/userTime"), i18n("User Time"), &KSysGuard::Process::userTime);
+ d->m_coreAttributes << userTimeSensor;
+
+ auto sysTimeSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/sysTime"), i18n("System Time"), &KSysGuard::Process::sysTime);
+ sysTimeSensor->setUnit(KSysGuard::UnitSecond);
+ d->m_coreAttributes << sysTimeSensor;
+
+ auto timeSensor = new ProcessSensor<qlonglong>(
+ this, QStringLiteral("process/totalUsage"), i18n("Total Time"), [](KSysGuard::Process *p) {
+ return p->userTime() + p->sysTime();
+ },
+ KSysGuard::Process::Usage);
+ timeSensor->setShortName(i18n("Time"));
+ timeSensor->setUnit(KSysGuard::UnitSecond);
+ timeSensor->setDescription(i18n("The total user and system time that this process has been running for"));
+ d->m_coreAttributes << timeSensor;
+
+ auto startTimeSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/startTime"), i18n("Start Time"), &KSysGuard::Process::startTime);
+ startTimeSensor->setDescription(i18n("The elapsed time since the process was started."));
+ startTimeSensor->setUnit(KSysGuard::UnitTime);
+ d->m_coreAttributes << startTimeSensor;
+
+ auto userUsageSensor = new ProcessSensor<int>(this, QStringLiteral("process/userUsage"), i18n("User CPU Usage"), &KSysGuard::Process::userUsage, KSysGuard::Process::Usage);
+ userUsageSensor->setShortName(i18n("User CPU"));
+ userUsageSensor->setMin(0);
+ userUsageSensor->setMax(100);
+ userUsageSensor->setUnit(KSysGuard::UnitPercent);
+ d->m_coreAttributes << userUsageSensor;
+
+ auto sysUsageSensor = new ProcessSensor<int>(this, QStringLiteral("process/sysUsage"), i18n("System CPU Usage"), &KSysGuard::Process::sysUsage, KSysGuard::Process::Usage);
+ sysUsageSensor->setShortName(i18n("System CPU"));
+ sysUsageSensor->setMin(0);
+ sysUsageSensor->setMax(100);
+ sysUsageSensor->setUnit(KSysGuard::UnitPercent);
+ d->m_coreAttributes << sysUsageSensor;
+
+ auto usageSensor = new ProcessSensor<int>(
+ this, QStringLiteral("process/usage"), i18n("Total CPU Usage"), [](KSysGuard::Process *p) {
+ return p->userUsage() + p->sysUsage();
+ },
+ KSysGuard::Process::Usage);
+ usageSensor->setShortName(i18n("CPU"));
+ usageSensor->setMin(0);
+ usageSensor->setMax(100);
+ usageSensor->setUnit(KSysGuard::UnitPercent);
+ usageSensor->setDescription(i18n("The current total CPU usage of the process."));
+ d->m_coreAttributes << usageSensor;
+
+ auto totalUserUsageSensor = new ProcessSensor<int>(this, QStringLiteral("process/totalUserUsage"), i18n("Group User CPU Usage"), &KSysGuard::Process::totalUserUsage, KSysGuard::Process::TotalUsage);
+ totalUserUsageSensor->setDescription(i18n("The amount of userspace CPU used by this process and all its children."));
+ totalUserUsageSensor->setMin(0);
+ totalUserUsageSensor->setMax(100);
+ totalUserUsageSensor->setUnit(KSysGuard::UnitPercent);
+ d->m_coreAttributes << totalUserUsageSensor;
+
+ auto totalSysUsageSensor = new ProcessSensor<int>(this, QStringLiteral("process/totalSysUsage"), i18n("Group System CPU Usage"), &KSysGuard::Process::totalSysUsage, KSysGuard::Process::TotalUsage);
+ totalUserUsageSensor->setDescription(i18n("The amount of system CPU used by this process and all its children."));
+ totalSysUsageSensor->setMin(0);
+ totalSysUsageSensor->setMax(100);
+ totalSysUsageSensor->setUnit(KSysGuard::UnitPercent);
+ d->m_coreAttributes << totalSysUsageSensor;
+
+ auto totalUsageSensor = new ProcessSensor<int>(
+ this, QStringLiteral("process/totalUsage"), i18n("Group Total CPU Usage"), [](KSysGuard::Process *p) {
+ return p->totalUserUsage() + p->totalSysUsage();
+ },
+ KSysGuard::Process::TotalUsage);
+ totalUsageSensor->setShortName(i18n("Group CPU"));
+ totalUserUsageSensor->setDescription(i18n("The total amount of CPU used by this process and all its children."));
+ totalUsageSensor->setMin(0);
+ totalUsageSensor->setMax(100);
+ totalUsageSensor->setUnit(KSysGuard::UnitPercent);
+ d->m_coreAttributes << totalUsageSensor;
+
+ auto niceLevelSensor = new ProcessSensor<int>(this, QStringLiteral("process/niceLevel"), i18n("Nice Level"), &KSysGuard::Process::niceLevel, KSysGuard::Process::NiceLevels);
+ niceLevelSensor->setDescription(i18n("The priority with which this process is being run. For the normal scheduler, this ranges from 19 (very nice, least priority) to -19 (top priority)."));
+ d->m_coreAttributes << niceLevelSensor;
+
+ auto schedulerSensor = new ProcessSensor<uint>(this, QStringLiteral("process/scheduler"), i18n("Scheduler"), &KSysGuard::Process::scheduler, KSysGuard::Process::NiceLevels);
+ d->m_coreAttributes << schedulerSensor;
+
+ auto ioPriorityClassSensor = new ProcessSensor<uint>(this, QStringLiteral("process/ioPriorityClass"), i18n("IO Priority Class"),
+ &KSysGuard::Process::ioPriorityClass, KSysGuard::Process::NiceLevels);
+ d->m_coreAttributes << ioPriorityClassSensor;
+
+ auto ioniceLevelSensor = new ProcessSensor<int>(this, QStringLiteral("process/ioniceLevel"), i18n("IO Nice Level"), &KSysGuard::Process::ioniceLevel, KSysGuard::Process::NiceLevels);
+ ioniceLevelSensor->setUnit(KSysGuard::UnitNone);
+ d->m_coreAttributes << ioniceLevelSensor;
+
+ auto vmSizeSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/vmSize"), i18n("VM Size"), &KSysGuard::Process::vmSize, KSysGuard::Process::VmSize);
+ vmSizeSensor->setUnit(KSysGuard::UnitKiloByte);
+ vmSizeSensor->setDescription(i18n("This is the amount of virtual memory space that the process is using, included shared libraries, graphics memory, files on disk, and so on. This number is almost meaningless."));
+ d->m_coreAttributes << vmSizeSensor;
+
+ auto vmRSSSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/vmRSS"), i18n("RSS Memory Usage"), &KSysGuard::Process::vmRSS, KSysGuard::Process::VmRSS);
+ vmRSSSensor->setUnit(KSysGuard::UnitKiloByte);
+ vmRSSSensor->setDescription(i18n("This is the amount of physical memory that this process is using and includes the amount of memory used by shared libraries."));
+
+ auto vmURSSSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/vmURSS"), i18n("Private Memory Usage"), &KSysGuard::Process::vmURSS, KSysGuard::Process::VmURSS);
+ vmURSSSensor->setUnit(KSysGuard::UnitKiloByte);
+ vmURSSSensor->setShortName(i18n("Private"));
+ vmURSSSensor->setDescription(i18n("This is the amount of physical memory that this process is using by itself, and approximates the Private memory usage of the process.<br>It does not include any swapped out memory, nor the code size of its shared libraries."));
+ d->m_coreAttributes << vmURSSSensor;
+
+ auto sharedMemorySensor = new ProcessSensor<qlonglong>(
+ this, QStringLiteral("process/vmShared"), i18n("Shared Memory Usage"), [](KSysGuard::Process *p) -> qlonglong {
+ if (p->vmRSS() - p->vmURSS() < 0 || p->vmURSS() == -1) {
+ return 0;
+ }
+ return (qlonglong)(p->vmRSS() - p->vmURSS());
+ },
+ KSysGuard::Process::VmRSS);
+ d->m_coreAttributes << sharedMemorySensor;
+ sharedMemorySensor->setShortName(i18n("Shared"));
+ sharedMemorySensor->setDescription(i18n("This is approximately the amount of real physical memory that this process's shared libraries are using.<br>This memory is shared among all processes that use this library."));
+ sharedMemorySensor->setUnit(KSysGuard::UnitKiloByte);
+
+ auto vmPSSSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/vmPSS"), i18n("Memory Usage"), &KSysGuard::Process::vmPSS, KSysGuard::Process::VmPSS);
+ vmPSSSensor->setShortName(i18n("Memory"));
+ vmPSSSensor->setUnit(KSysGuard::UnitKiloByte);
+ vmPSSSensor->setDescription(i18n("This is an approximation of the real amount of physical memory that this process is using. It is calculated by dividing the process' shared memory usage by the amount of processes sharing that memory, then adding the process' private memory."));
+ d->m_coreAttributes << vmPSSSensor;
+
+ auto nameSensor = new ProcessSensor<QString>(this, QStringLiteral("process/name"), i18n("Name"), &KSysGuard::Process::name, KSysGuard::Process::Name);
+ nameSensor->setDescription(i18n("The process name."));
+ d->m_coreAttributes << nameSensor;
+
+ auto commandSensor = new ProcessSensor<QString>(this, QStringLiteral("process/command"), i18n("Command"), &KSysGuard::Process::command, KSysGuard::Process::Command);
+ commandSensor->setDescription(i18n("The command with which this process was launched."));
+ d->m_coreAttributes << commandSensor;
+
+ auto statusSensor = new ProcessSensor<uint>(this, QStringLiteral("process/status"), i18n("Status"), &KSysGuard::Process::status, KSysGuard::Process::Status);
+ d->m_coreAttributes << statusSensor;
+
+ auto ioCharactersReadSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/ioCharactersRead"), i18n("IO Characters Read"), &KSysGuard::Process::ioCharactersRead, KSysGuard::Process::IO);
+ ioCharactersReadSensor->setUnit(KSysGuard::UnitByteRate);
+ d->m_coreAttributes << ioCharactersReadSensor;
+
+ auto ioCharactersWrittenSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/ioCharactersWritten"), i18n("IO Characters Written"), &KSysGuard::Process::ioCharactersWritten, KSysGuard::Process::IO);
+ ioCharactersWrittenSensor->setUnit(KSysGuard::UnitByteRate);
+ d->m_coreAttributes << ioCharactersWrittenSensor;
+
+ auto ioReadSyscallsSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/ioReadSyscalls"), i18n("IO Read Syscalls"), &KSysGuard::Process::ioReadSyscalls, KSysGuard::Process::IO);
+ ioReadSyscallsSensor->setUnit(KSysGuard::UnitRate);
+ d->m_coreAttributes << ioReadSyscallsSensor;
+
+ auto ioReadSyscallsRateSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/ioReadSyscallsRate"), i18n("IO Read Syscalls Rate"), &KSysGuard::Process::ioReadSyscallsRate, KSysGuard::Process::IO);
+ ioReadSyscallsRateSensor->setUnit(KSysGuard::UnitRate);
+ d->m_coreAttributes << ioReadSyscallsSensor;
+
+ auto ioWriteSyscallsSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/ioWriteSyscalls"), i18n("IO Write Syscalls"), &KSysGuard::Process::ioWriteSyscalls, KSysGuard::Process::IO);
+ ioWriteSyscallsSensor->setUnit(KSysGuard::UnitRate);
+ d->m_coreAttributes << ioWriteSyscallsSensor;
+
+ auto ioWriteSyscallsRateSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/ioReadSyscallsRate"), i18n("IO Write Syscalls Rate"), &KSysGuard::Process::ioWriteSyscallsRate, KSysGuard::Process::IO);
+ ioWriteSyscallsRateSensor->setUnit(KSysGuard::UnitRate);
+ d->m_coreAttributes << ioWriteSyscallsRateSensor;
+
+ auto ioCharactersActuallyReadSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/ioCharactersActuallyRead"), i18n("IO Characters Actually Read"), &KSysGuard::Process::ioCharactersActuallyRead, KSysGuard::Process::IO);
+ d->m_coreAttributes << ioCharactersActuallyReadSensor;
+
+ auto ioCharactersReadRateSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/ioCharactersReadRate"), i18n("IO Characters Read Rate"), &KSysGuard::Process::ioCharactersReadRate, KSysGuard::Process::IO);
+ ioCharactersReadRateSensor->setDescription(i18n("The rate of bytes read"));
+ d->m_coreAttributes << ioCharactersReadRateSensor;
+
+ auto ioCharactersWrittenRateSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/ioCharactersWrittenRate"), i18n("IO Characters Written Rate"), &KSysGuard::Process::ioCharactersWrittenRate, KSysGuard::Process::IO);
+ ioCharactersWrittenRateSensor->setDescription(i18n("The rate of bytes written"));
+ d->m_coreAttributes << ioCharactersWrittenRateSensor;
+
+ auto ioCharactersActuallyReadRateSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/ioCharactersActuallyReadRate"), i18n("IO Characters Actually Read Rate"), &KSysGuard::Process::ioCharactersActuallyReadRate, KSysGuard::Process::IO);
+ d->m_coreAttributes << ioCharactersActuallyReadRateSensor;
+
+ auto ioCharactersActuallyWrittenRateSensor = new ProcessSensor<qlonglong>(this, QStringLiteral("process/ioCharactersActuallyWrittenRate"), i18n("IO Characters Actually Written Rate"), &KSysGuard::Process::ioCharactersActuallyWrittenRate, KSysGuard::Process::IO);
+ d->m_coreAttributes << ioCharactersActuallyWrittenRateSensor;
+
+ auto numThreadsSensor = new ProcessSensor<int>(this, QStringLiteral("process/numThreads"), i18n("Threads"), &KSysGuard::Process::numThreads, KSysGuard::Process::NumThreads);
+
connect(this, &KSysGuard::Processes::beginRemoveProcess, this, [this](KSysGuard::Process *process) {
const auto attrs = attributes();
for (auto a : attrs) {
@@ -75,7 +358,7 @@ QVector<ProcessAttribute *> ExtendedProcesses::attributes() const
for (auto p : qAsConst(d->m_providers)) {
rc << p->attributes();
}
- return rc;
+ return d->m_coreAttributes + rc;
}
void ExtendedProcesses::Private::loadPlugins()
diff --git a/processcore/process_attribute.cpp b/processcore/process_attribute.cpp
index 272ca9c..128ac52 100644
--- a/processcore/process_attribute.cpp
+++ b/processcore/process_attribute.cpp
@@ -134,7 +134,7 @@ void ProcessAttribute::setUnit(KSysGuard::Unit unit)
d->m_unit = unit;
}
-QVariant ProcessAttribute::data(KSysGuard::Process *process)
+QVariant ProcessAttribute::data(KSysGuard::Process *process) const
{
return d->m_data.value(process);
}
diff --git a/processcore/process_attribute.h b/processcore/process_attribute.h
index af3b2c2..5196d99 100644
--- a/processcore/process_attribute.h
+++ b/processcore/process_attribute.h
@@ -88,7 +88,7 @@ public:
/**
* The last stored value for a given process
*/
- QVariant data(KSysGuard::Process *process);
+ virtual QVariant data(KSysGuard::Process *process) const;
/**
* Updates the stored value for a given process
diff --git a/processui/CMakeLists.txt b/processui/CMakeLists.txt
index c3cbd1e..f3af417 100644
--- a/processui/CMakeLists.txt
+++ b/processui/CMakeLists.txt
@@ -9,6 +9,7 @@ set(processui_LIB_SRCS
ksysguardprocesslist.cpp
ProcessFilter.cpp
ProcessModel.cpp
+ ProcessDataModel.cpp
ReniceDlg.cpp
KTextEditVT.cpp
scripting.cpp
diff --git a/processui/ProcessDataModel.cpp b/processui/ProcessDataModel.cpp
new file mode 100644
index 0000000..c207ace
--- /dev/null
+++ b/processui/ProcessDataModel.cpp
@@ -0,0 +1,270 @@
+#include "ProcessDataModel.h"
+
+#include "processcore/extended_process_list.h"
+#include "processcore/formatter.h"
+#include "processcore/process.h"
+#include "processcore/process_attribute.h"
+#include "processcore/process_data_provider.h"
+
+#include <QMetaEnum>
+
+using namespace KSysGuard;
+
+class KSysGuard::ProcessDataModelPrivate: public QObject
+{
+ Q_OBJECT
+public:
+ ProcessDataModelPrivate(ProcessDataModel *q);
+ void beginInsertRow( KSysGuard::Process *parent);
+ /** Called from KSysGuard::Processes
+ * We have finished inserting a process
+ */
+ void endInsertRow();
+ /** Called from KSysGuard::Processes
+ * This indicates we are about to remove a process in the model. Emit the appropriate signals
+ */
+ void beginRemoveRow( KSysGuard::Process *process);
+ /** Called from KSysGuard::Processes
+ * We have finished removing a process
+ */
+ void endRemoveRow();
+ /** Called from KSysGuard::Processes
+ * This indicates we are about to move a process in the model from one parent process to another. Emit the appropriate signals
+ */
+ void beginMoveProcess(KSysGuard::Process *process, KSysGuard::Process *new_parent);
+ /** Called from KSysGuard::Processes
+ * We have finished moving a process
+ */
+ void endMoveRow();
+
+ KSysGuard::ExtendedProcesses *m_processes;
+ QVector<KSysGuard::ProcessAttribute* > m_extraAttributes;
+ ProcessDataModel *q;
+};
+
+ProcessDataModel::ProcessDataModel(QObject *parent)
+ : QAbstractItemModel(parent)
+ , d(new ProcessDataModelPrivate(this))
+{
+ update();
+}
+
+ProcessDataModel::~ProcessDataModel()
+{}
+
+void ProcessDataModel::update(long updateDurationMSecs, KSysGuard::Processes::UpdateFlags updateFlags) {
+ d->m_processes->updateAllProcesses(updateDurationMSecs, updateFlags);
+}
+
+ProcessDataModelPrivate::ProcessDataModelPrivate(ProcessDataModel *_q):
+ q(_q)
+{
+ m_processes = new KSysGuard::ExtendedProcesses(this);
+
+// connect( m_processes, &KSysGuard::Processes::processChanged, this, &ProcessDataModelPrivate::processChanged);
+ connect( m_processes, &KSysGuard::Processes::beginAddProcess, this, &ProcessDataModelPrivate::beginInsertRow);
+ connect( m_processes, &KSysGuard::Processes::endAddProcess, this, &ProcessDataModelPrivate::endInsertRow);
+ connect( m_processes, &KSysGuard::Processes::beginRemoveProcess, this, &ProcessDataModelPrivate::beginRemoveRow);
+ connect( m_processes, &KSysGuard::Processes::endRemoveProcess, this, &ProcessDataModelPrivate::endRemoveRow);
+ connect( m_processes, &KSysGuard::Processes::beginMoveProcess, this,
+ &ProcessDataModelPrivate::beginMoveProcess);
+ connect( m_processes, &KSysGuard::Processes::endMoveProcess, this, &ProcessDataModelPrivate::endMoveRow);
+
+ m_extraAttributes = m_processes->attributes();
+ for (int i = 0 ; i < m_extraAttributes.count(); i ++) {
+ m_extraAttributes[i]->setEnabled(true); // In future we will toggle this based on column visibility
+
+ connect(m_extraAttributes[i], &KSysGuard::ProcessAttribute::dataChanged, this, [this, i](KSysGuard::Process *process) {
+ const QModelIndex index = q->getQModelIndex(process, i);
+ emit q->dataChanged(index, index);
+ });
+ }
+
+}
+
+QVariant ProcessDataModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid()) {
+ return QVariant();
+ }
+
+ if (index.column() > columnCount()) {
+ return QVariant();
+ }
+
+ int attr = index.column();
+ switch (role) {
+ case ProcessDataModel::PlainValue: {
+ KSysGuard::Process *process = reinterpret_cast< KSysGuard::Process * > (index.internalPointer());
+ const QVariant value = d->m_extraAttributes[attr]->data(process);
+ return value;
+ }
+ case Qt::DisplayRole: {
+ KSysGuard::Process *process = reinterpret_cast< KSysGuard::Process * > (index.internalPointer());
+ const QVariant value = d->m_extraAttributes[attr]->data(process);
+ return KSysGuard::Formatter::formatValue(value, d->m_extraAttributes[attr]->unit());
+ }
+ case Qt::TextAlignmentRole: {
+ KSysGuard::Process *process = reinterpret_cast< KSysGuard::Process * > (index.internalPointer());
+ const QVariant value = d->m_extraAttributes[attr]->data(process);
+ if (value.canConvert(QMetaType::LongLong)
+ && static_cast<QMetaType::Type>(value.type()) != QMetaType::QString) {
+ return Qt::AlignRight + Qt::AlignVCenter;
+ }
+ return Qt::AlignLeft + Qt::AlignVCenter;
+ }
+ }
+ return QVariant();
+ }
+
+int ProcessDataModel::rowCount(const QModelIndex &parent) const
+{
+ if(parent.isValid()) return 0; //In flat mode, none of the processes have children
+ return d->m_processes->processCount();
+}
+
+QModelIndex ProcessDataModel::parent (const QModelIndex &index) const
+{
+ return QModelIndex();
+}
+
+QModelIndex ProcessDataModel::index(int row, int column, const QModelIndex &parent) const
+{
+ if(row<0) return QModelIndex();
+ if(column<0 || column >= columnCount() ) return QModelIndex();
+
+ if( parent.isValid()) return QModelIndex();
+ if( d->m_processes->processCount() <= row) return QModelIndex();
+ return createIndex( row, column, d->m_processes->getAllProcesses().at(row));
+}
+
+
+void ProcessDataModelPrivate::beginInsertRow( KSysGuard::Process *process)
+{
+ Q_ASSERT(process);
+ int row = m_processes->processCount();
+ q->beginInsertRows( QModelIndex(), row, row );
+}
+
+void ProcessDataModelPrivate::endInsertRow()
+{
+ q->endInsertRows();
+}
+
+void ProcessDataModelPrivate::beginRemoveRow( KSysGuard::Process *process )
+{
+ return q->beginRemoveRows(QModelIndex(), process->index(), process->index());
+}
+
+void ProcessDataModelPrivate::endRemoveRow()
+{
+ q->endRemoveRows();
+}
+
+void ProcessDataModelPrivate::beginMoveProcess(KSysGuard::Process *process, KSysGuard::Process *new_parent)
+{
+}
+
+void ProcessDataModelPrivate::endMoveRow()
+{
+}
+
+QModelIndex ProcessDataModel::getQModelIndex( KSysGuard::Process *process, int column) const
+{
+ Q_ASSERT(process);
+ int pid = process->pid();
+ if (pid == -1) return QModelIndex(); //pid -1 is our fake process meaning the very root (never drawn). To represent that, we return QModelIndex() which also means the top element
+ int row = 0;
+// if(d->mSimple) {
+ row = process->index();
+// } else {
+// row = process->parent()->children().indexOf(process);
+// }
+ Q_ASSERT(row != -1);
+ return createIndex(row, column, process);
+}
+
+int ProcessDataModel::columnCount(const QModelIndex &parent) const
+{
+ if (parent.isValid()) {
+ return 0;
+ }
+
+ return d->m_extraAttributes.count();
+}
+
+QHash<int, QByteArray> ProcessDataModel::roleNames() const
+{
+ QHash<int, QByteArray> roles = QAbstractItemModel::roleNames();
+
+ QMetaEnum e = metaObject()->enumerator(metaObject()->indexOfEnumerator("AdditionalRoles"));
+
+ for (int i = 0; i < e.keyCount(); ++i) {
+ roles.insert(e.value(i), e.key(i));
+ }
+
+ roles[Qt::TextAlignmentRole] = "alignment";
+
+ return roles;
+}
+
+
+QVariant ProcessDataModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (orientation == Qt::Vertical) {
+ return QVariant();
+ }
+
+ if (section < 0 || section >= columnCount()) {
+ return QVariant();
+ }
+
+ auto attribute = d->m_extraAttributes[section];
+
+ switch (role) {
+ case Qt::DisplayRole: {
+ return attribute->shortName();
+ }
+ case PlainValue: {
+ return attribute->id();
+ }
+ case Qt::TextAlignmentRole: {
+ switch (attribute->unit()) {
+ case KSysGuard::UnitByte:
+ case KSysGuard::UnitKiloByte:
+ case KSysGuard::UnitMegaByte:
+ case KSysGuard::UnitGigaByte:
+ case KSysGuard::UnitTeraByte:
+ case KSysGuard::UnitPetaByte:
+ case KSysGuard::UnitByteRate:
+ case KSysGuard::UnitKiloByteRate:
+ case KSysGuard::UnitMegaByteRate:
+ case KSysGuard::UnitGigaByteRate:
+ case KSysGuard::UnitTeraByteRate:
+ case KSysGuard::UnitPetaByteRate:
+ case KSysGuard::UnitHertz:
+ case KSysGuard::UnitKiloHertz:
+ case KSysGuard::UnitMegaHertz:
+ case KSysGuard::UnitGigaHertz:
+ case KSysGuard::UnitTeraHertz:
+ case KSysGuard::UnitPetaHertz:
+ case KSysGuard::UnitPercent:
+ case KSysGuard::UnitRate:
+ return Qt::AlignCenter;
+ default: break;
+ }
+
+ return Qt::AlignLeft;
+ }
+ case Unit: {
+ auto attribute = d->m_extraAttributes[section];
+ return attribute->unit();
+ }
+ default:
+ break;
+ }
+
+ return QVariant();
+}
+
+#include "ProcessDataModel.moc"
diff --git a/processui/ProcessDataModel.h b/processui/ProcessDataModel.h
new file mode 100644
index 0000000..ffc152a
--- /dev/null
+++ b/processui/ProcessDataModel.h
@@ -0,0 +1,56 @@
+#pragma once
+
+#include <QAbstractItemModel>
+#include <processcore/processes.h>
+
+namespace KSysGuard {
+
+class Process;
+class ProcessDataModelPrivate;
+
+class ProcessDataModel : public QAbstractItemModel
+{
+ Q_OBJECT
+
+public:
+ enum AdditionalRoles {
+ PlainValue = Qt::UserRole + 1,
+ PlainValueHistory,
+ Timestamp,
+ Entity,
+ Unit,
+ Name,
+ ShortName,
+ };
+ Q_ENUM(AdditionalRoles)
+
+ ProcessDataModel(QObject *parent = nullptr);
+ ~ProcessDataModel() override;
+ QHash<int, QByteArray> roleNames() const override;
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const override;
+
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
+ QModelIndex parent(const QModelIndex &index) const override;
+
+ QStringList enabledSensors();
+ void setEnabledSensors();
+
+ QModelIndex getQModelIndex(Process *process, int column) const;
+
+ /** Update data. You can pass in the time between updates to only update if there hasn't
+ * been an update within the last @p updateDurationMSecs milliseconds. 0 indicate to update
+ * regardless of when the last update was.
+ * The updateFlags indicates what to additional update, as well as the usual details. */
+ void update(long updateDurationMSecs = 0, KSysGuard::Processes::UpdateFlags updateFlags = KSysGuard::Processes::IOStatistics);
+
+private:
+ QScopedPointer<ProcessDataModelPrivate> d;
+ friend class ProcessDataModelPrivate;
+};
+
+}
diff --git a/processui/ksysguardprocesslist.cpp b/processui/ksysguardprocesslist.cpp
index f999b94..f56c47f 100644
--- a/processui/ksysguardprocesslist.cpp
+++ b/processui/ksysguardprocesslist.cpp
@@ -65,6 +65,8 @@
#include "scripting.h"
#include "process_controller.h"
+#include "ProcessDataModel.h"
+
#include <sys/types.h>
#include <unistd.h>
@@ -311,6 +313,9 @@ KSysGuardProcessList::KSysGuardProcessList(QWidget* parent, const QString &hostN
#ifdef DO_MODELCHECK
new ModelTest(&d->mModel, this);
#endif
+
+ new KSysGuard::ProcessDataModel(this);
+
d->mUi->treeView->setItemDelegate(new ProgressBarItemDelegate(d->mUi->treeView));
d->mUi->treeView->header()->setContextMenuPolicy(Qt::CustomContextMenu);
davidedmundson edited the content of this paste. (Show Details)Sep 18 2019, 12:31 PM
davidedmundson changed the title of this paste from untitled to Masterwork From Distant Lands.