File indexing completed on 2024-04-28 05:31:43

0001 /*
0002     KSysGuard, the KDE System Guard
0003 
0004     SPDX-FileCopyrightText: 1999, 2000 Chris Schlaeger <cs@kde.org>
0005     SPDX-FileCopyrightText: 2006 John Tapsell <john.tapsell@kde.org>
0006 
0007     SPDX-License-Identifier: LGPL-2.0-or-later
0008 
0009 */
0010 
0011 #ifndef PROCESSMODEL_H_
0012 #define PROCESSMODEL_H_
0013 
0014 #include <QAbstractItemModel>
0015 
0016 #include <processcore/processes.h>
0017 
0018 #include "processui_export.h"
0019 
0020 namespace KSysGuard
0021 {
0022 class Processes;
0023 class Process;
0024 class ProcessAttribute;
0025 }
0026 
0027 class ProcessModelPrivate;
0028 
0029 #ifdef Q_OS_WIN
0030 // this workaround is needed to make krunner link under msvc
0031 // please keep it this way even if you port this library to have a _export.h header file
0032 #define KSYSGUARD_EXPORT
0033 #else
0034 #define KSYSGUARD_EXPORT PROCESSUI_EXPORT
0035 #endif
0036 
0037 class KSYSGUARD_EXPORT ProcessModel : public QAbstractItemModel
0038 {
0039     Q_OBJECT
0040 
0041 public:
0042     /** Storage for history values. PercentageHistoryRole returns a QList of this. */
0043     struct PercentageHistoryEntry {
0044         unsigned long timestamp; // in ms, origin undefined as only the delta matters
0045         float value;
0046     };
0047 
0048     explicit ProcessModel(QObject *parent = nullptr, const QString &host = QString());
0049     ~ProcessModel() override;
0050 
0051     /* Functions for our Model for QAbstractItemModel*/
0052     int rowCount(const QModelIndex &parent = QModelIndex()) const override;
0053     int columnCount(const QModelIndex &parent = QModelIndex()) const override;
0054     QVariant data(const QModelIndex &index, int role) const override;
0055     QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
0056     QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
0057     QModelIndex parent(const QModelIndex &index) const override;
0058 
0059     bool hasChildren(const QModelIndex &parent) const override;
0060     /** Returns if (left < right), used by the sort-filter proxy model to sort the columns */
0061     bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
0062 
0063     /* Functions for drag and drop and copying to clipboard, inherited from QAbstractItemModel */
0064     QStringList mimeTypes() const override;
0065     QMimeData *mimeData(const QModelIndexList &indexes) const override;
0066     Qt::ItemFlags flags(const QModelIndex &index) const override;
0067 
0068     /* Functions for setting the model */
0069 
0070     /** Setup the column headings by inserting the appropriate headings into the model.
0071      *  Can be called more than once to retranslate the headings if the system language changes.
0072      */
0073     void setupHeader();
0074 
0075     /** Update data.  You can pass in the time between updates to only update if there hasn't
0076      *  been an update within the last @p updateDurationMSecs milliseconds.  0 indicate to update
0077      *  regardless of when the last update was.
0078      *  The updateFlags indicates what to additional update, as well as the usual details. */
0079     void update(long updateDurationMSecs = 0, KSysGuard::Processes::UpdateFlags updateFlags = KSysGuard::Processes::IOStatistics);
0080     /** Return a string with the pid of the process and the name of the process.  E.g.  13343: ksysguard
0081      */
0082     QString getStringForProcess(KSysGuard::Process *process) const;
0083     KSysGuard::Process *getProcess(qlonglong pid);
0084 
0085     /** This is used from ProcessFilter to get the process at a given index when in flat mode */
0086     KSysGuard::Process *getProcessAtIndex(int index) const;
0087 
0088     /** Returns whether this user can log in or not.
0089      *  @see mUidCanLogin
0090      */
0091     bool canUserLogin(long uid) const;
0092     /** In simple mode, everything is flat, with no icons, few if any colors, no xres etc.
0093      *  This can be changed at any time.  It is a fairly quick operation.  Basically it resets the model
0094      */
0095     void setSimpleMode(bool simple);
0096     /** In simple mode, everything is flat, with no icons, few if any colors, no xres etc
0097      */
0098     bool isSimpleMode() const;
0099 
0100     /** Returns the total amount of physical memory in the machine. */
0101     qlonglong totalMemory() const;
0102 
0103     /** This returns a QModelIndex for the given process.  It has to look up the parent for this pid, find the offset this
0104      *  pid is from the parent, and return that.  It's not that slow, but does involve a couple of hash table lookups.
0105      */
0106     QModelIndex getQModelIndex(KSysGuard::Process *process, int column) const;
0107 
0108     /** Whether this is showing the processes for the current machine
0109      */
0110     bool isLocalhost() const;
0111 
0112     /** The host name that this widget is showing the processes of */
0113     QString hostName() const;
0114 
0115     /** Whether this process has a GUI window */
0116     bool hasGUIWindow(qlonglong pid) const;
0117 
0118     /** Returns for process controller pointer for this model */
0119     KSysGuard::Processes *processController() const; // The processes instance
0120 
0121     /** Returns the list of extra attributes provided by plugins */
0122     const QList<KSysGuard::ProcessAttribute *> extraAttributes() const;
0123 
0124     /** Convenience function to get the number of processes.
0125      *
0126      *  Equivalent to processController->processCount() */
0127     int processCount() const
0128     {
0129         return processController()->processCount();
0130     }
0131 
0132     /** The headings in the model.  The order here is the order that they are shown
0133      *  in.  If you change this, make sure you also change the
0134      *  setup header function, and make sure you increase PROCESSHEADERVERSION.  This will ensure
0135      *  that old saved settings won't be used
0136      */
0137 #define PROCESSHEADERVERSION 10
0138     enum {
0139         HeadingName = 0,
0140         HeadingUser,
0141         HeadingPid,
0142         HeadingTty,
0143         HeadingNiceness,
0144         HeadingCPUUsage,
0145         HeadingCPUTime,
0146         HeadingIoRead,
0147         HeadingIoWrite,
0148         HeadingVmSize,
0149         HeadingMemory,
0150         HeadingSharedMemory,
0151         HeadingStartTime,
0152         HeadingNoNewPrivileges,
0153         HeadingCommand,
0154         HeadingXMemory,
0155         HeadingXTitle,
0156         HeadingCGroup,
0157         HeadingMACContext,
0158         HeadingVmPSS,
0159         // This entry should always match the actual last entry in this enum + 1.
0160         // It is used to determine where plugin-provided headings start.
0161         HeadingPluginStart = HeadingVmPSS + 1,
0162     };
0163 
0164     enum { UidRole = Qt::UserRole, SortingValueRole, WindowIdRole, PlainValueRole, PercentageRole, PercentageHistoryRole };
0165 
0166     bool showTotals() const;
0167 
0168     /** When displaying memory sizes, this is the units it should be displayed in */
0169     enum Units { UnitsAuto, UnitsKB, UnitsMB, UnitsGB, UnitsTB, UnitsPB, UnitsPercentage };
0170     Q_ENUM(Units)
0171     /** Set the units memory sizes etc should be displayed in */
0172     void setUnits(Units units);
0173     /** The units memory sizes etc should be displayed in */
0174     Units units() const;
0175     /** Set the I/O units sizes etc should be displayed in */
0176     void setIoUnits(Units units);
0177     /** The units I/O sizes etc should be displayed in */
0178     Units ioUnits() const;
0179 
0180     enum IoInformation { Bytes, Syscalls, ActualBytes, BytesRate, SyscallsRate, ActualBytesRate };
0181     /** Set the information to show in the Io Read and Io Write columns */
0182     void setIoInformation(IoInformation ioInformation);
0183     /** The information to show in the Io Read and Io Write columns */
0184     IoInformation ioInformation() const;
0185 
0186     /** Take an amount in kb, and return a string in the units set by setUnits() */
0187     QString formatMemoryInfo(qlonglong amountInKB, Units units, bool returnEmptyIfValueIsZero = false) const;
0188     /** Whether to show the command line options in the process name column */
0189     bool isShowCommandLineOptions() const;
0190     /** Set whether to show the command line options in the process name column */
0191     void setShowCommandLineOptions(bool showCommandLineOptions);
0192 
0193     /** Whether to show tooltips when the mouse hovers over a process */
0194     bool isShowingTooltips() const;
0195     /** Set whether to show tooltips when the mouse hovers over a process */
0196     void setShowingTooltips(bool showTooltips);
0197     /** Whether to divide CPU usage by the number of CPUs */
0198     bool isNormalizedCPUUsage() const;
0199     /** Set whether to divide CPU usage by the number of CPUs */
0200     void setNormalizedCPUUsage(bool normalizeCPUUsage);
0201 
0202     /** Retranslate the GUI, for when the system language changes */
0203     void retranslateUi();
0204 
0205 public Q_SLOTS:
0206     /** Whether to show the total cpu for the process plus all of its children */
0207     void setShowTotals(bool showTotals);
0208 
0209 private:
0210     ProcessModelPrivate *const d;
0211     friend class ProcessModelPrivate;
0212 };
0213 
0214 Q_DECLARE_METATYPE(QList<ProcessModel::PercentageHistoryEntry>);
0215 Q_DECLARE_TYPEINFO(ProcessModel::PercentageHistoryEntry, Q_PRIMITIVE_TYPE);
0216 
0217 #endif