1 /*
2     KSysGuard, the KDE System Guard
3 
4     SPDX-FileCopyrightText: 1999, 2000 Chris Schlaeger <cs@kde.org>
5     SPDX-FileCopyrightText: 2006 John Tapsell <john.tapsell@kde.org>
6 
7     SPDX-License-Identifier: LGPL-2.0-or-later
8 
9 */
10 
11 #ifndef PROCESSMODEL_H_
12 #define PROCESSMODEL_H_
13 
14 #include <QAbstractItemModel>
15 
16 #include <processcore/processes.h>
17 
18 namespace KSysGuard
19 {
20 class Processes;
21 class Process;
22 class ProcessAttribute;
23 }
24 
25 class ProcessModelPrivate;
26 
27 #ifdef Q_OS_WIN
28 // this workaround is needed to make krunner link under msvc
29 // please keep it this way even if you port this library to have a _export.h header file
30 #define KSYSGUARD_EXPORT
31 #else
32 #define KSYSGUARD_EXPORT Q_DECL_EXPORT
33 #endif
34 
35 class KSYSGUARD_EXPORT ProcessModel : public QAbstractItemModel
36 {
37     Q_OBJECT
38     Q_ENUMS(Units)
39 
40 public:
41     /** Storage for history values. PercentageHistoryRole returns a QVector of this. */
42     struct PercentageHistoryEntry {
43         unsigned long timestamp; // in ms, origin undefined as only the delta matters
44         float value;
45     };
46 
47     explicit ProcessModel(QObject *parent = nullptr, const QString &host = QString());
48     ~ProcessModel() override;
49 
50     /* Functions for our Model for QAbstractItemModel*/
51     int rowCount(const QModelIndex &parent = QModelIndex()) const override;
52     int columnCount(const QModelIndex &parent = QModelIndex()) const override;
53     QVariant data(const QModelIndex &index, int role) const override;
54     QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
55     QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
56     QModelIndex parent(const QModelIndex &index) const override;
57 
58     bool hasChildren(const QModelIndex &parent) const override;
59     /** Returns if (left < right), used by the sort-filter proxy model to sort the columns */
60     bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
61 
62     /* Functions for drag and drop and copying to clipboard, inherited from QAbstractItemModel */
63     QStringList mimeTypes() const override;
64     QMimeData *mimeData(const QModelIndexList &indexes) const override;
65     Qt::ItemFlags flags(const QModelIndex &index) const override;
66 
67     /* Functions for setting the model */
68 
69     /** Setup the column headings by inserting the appropriate headings into the model.
70      *  Can be called more than once to retranslate the headings if the system language changes.
71      */
72     void setupHeader();
73 
74     /** Update data.  You can pass in the time between updates to only update if there hasn't
75      *  been an update within the last @p updateDurationMSecs milliseconds.  0 indicate to update
76      *  regardless of when the last update was.
77      *  The updateFlags indicates what to additional update, as well as the usual details. */
78     void update(long updateDurationMSecs = 0, KSysGuard::Processes::UpdateFlags updateFlags = KSysGuard::Processes::IOStatistics);
79     /** Return a string with the pid of the process and the name of the process.  E.g.  13343: ksysguard
80      */
81     QString getStringForProcess(KSysGuard::Process *process) const;
82     KSysGuard::Process *getProcess(qlonglong pid);
83 
84     /** This is used from ProcessFilter to get the process at a given index when in flat mode */
85     KSysGuard::Process *getProcessAtIndex(int index) const;
86 
87     /** Returns whether this user can log in or not.
88      *  @see mUidCanLogin
89      */
90     bool canUserLogin(long uid) const;
91     /** In simple mode, everything is flat, with no icons, few if any colors, no xres etc.
92      *  This can be changed at any time.  It is a fairly quick operation.  Basically it resets the model
93      */
94     void setSimpleMode(bool simple);
95     /** In simple mode, everything is flat, with no icons, few if any colors, no xres etc
96      */
97     bool isSimpleMode() const;
98 
99     /** Returns the total amount of physical memory in the machine. */
100     qlonglong totalMemory() const;
101 
102     /** This returns a QModelIndex for the given process.  It has to look up the parent for this pid, find the offset this
103      *  pid is from the parent, and return that.  It's not that slow, but does involve a couple of hash table lookups.
104      */
105     QModelIndex getQModelIndex(KSysGuard::Process *process, int column) const;
106 
107     /** Whether this is showing the processes for the current machine
108      */
109     bool isLocalhost() const;
110 
111     /** The host name that this widget is showing the processes of */
112     QString hostName() const;
113 
114     /** Whether this process has a GUI window */
115     bool hasGUIWindow(qlonglong pid) const;
116 
117     /** Returns for process controller pointer for this model */
118     KSysGuard::Processes *processController() const; // The processes instance
119 
120     /** Returns the list of extra attributes provided by plugins */
121     const QVector<KSysGuard::ProcessAttribute *> extraAttributes() const;
122 
123     /** Convenience function to get the number of processes.
124      *
125      *  Equivalent to processController->processCount() */
processCount()126     int processCount() const
127     {
128         return processController()->processCount();
129     }
130 
131     /** The headings in the model.  The order here is the order that they are shown
132      *  in.  If you change this, make sure you also change the
133      *  setup header function, and make sure you increase PROCESSHEADERVERSION.  This will ensure
134      *  that old saved settings won't be used
135      */
136 #define PROCESSHEADERVERSION 10
137     enum {
138         HeadingName = 0,
139         HeadingUser,
140         HeadingPid,
141         HeadingTty,
142         HeadingNiceness,
143         HeadingCPUUsage,
144         HeadingCPUTime,
145         HeadingIoRead,
146         HeadingIoWrite,
147         HeadingVmSize,
148         HeadingMemory,
149         HeadingSharedMemory,
150         HeadingStartTime,
151         HeadingNoNewPrivileges,
152         HeadingCommand,
153         HeadingXMemory,
154         HeadingXTitle,
155         HeadingCGroup,
156         HeadingMACContext,
157         HeadingVmPSS,
158         // This entry should always match the actual last entry in this enum + 1.
159         // It is used to determine where plugin-provided headings start.
160         HeadingPluginStart = HeadingVmPSS + 1,
161     };
162 
163     enum { UidRole = Qt::UserRole, SortingValueRole, WindowIdRole, PlainValueRole, PercentageRole, PercentageHistoryRole };
164 
165     bool showTotals() const;
166 
167     /** When displaying memory sizes, this is the units it should be displayed in */
168     enum Units { UnitsAuto, UnitsKB, UnitsMB, UnitsGB, UnitsTB, UnitsPB, UnitsPercentage };
169     /** Set the units memory sizes etc should be displayed in */
170     void setUnits(Units units);
171     /** The units memory sizes etc should be displayed in */
172     Units units() const;
173     /** Set the I/O units sizes etc should be displayed in */
174     void setIoUnits(Units units);
175     /** The units I/O sizes etc should be displayed in */
176     Units ioUnits() const;
177 
178     enum IoInformation { Bytes, Syscalls, ActualBytes, BytesRate, SyscallsRate, ActualBytesRate };
179     /** Set the information to show in the Io Read and Io Write columns */
180     void setIoInformation(IoInformation ioInformation);
181     /** The information to show in the Io Read and Io Write columns */
182     IoInformation ioInformation() const;
183 
184     /** Take an amount in kb, and return a string in the units set by setUnits() */
185     QString formatMemoryInfo(qlonglong amountInKB, Units units, bool returnEmptyIfValueIsZero = false) const;
186     /** Whether to show the command line options in the process name column */
187     bool isShowCommandLineOptions() const;
188     /** Set whether to show the command line options in the process name column */
189     void setShowCommandLineOptions(bool showCommandLineOptions);
190 
191     /** Whether to show tooltips when the mouse hovers over a process */
192     bool isShowingTooltips() const;
193     /** Set whether to show tooltips when the mouse hovers over a process */
194     void setShowingTooltips(bool showTooltips);
195     /** Whether to divide CPU usage by the number of CPUs */
196     bool isNormalizedCPUUsage() const;
197     /** Set whether to divide CPU usage by the number of CPUs */
198     void setNormalizedCPUUsage(bool normalizeCPUUsage);
199 
200     /** Retranslate the GUI, for when the system language changes */
201     void retranslateUi();
202 
203 public Q_SLOTS:
204     /** Whether to show the total cpu for the process plus all of its children */
205     void setShowTotals(bool showTotals);
206 
207 private:
208     ProcessModelPrivate *const d;
209     friend class ProcessModelPrivate;
210 };
211 
212 Q_DECLARE_METATYPE(QVector<ProcessModel::PercentageHistoryEntry>);
213 Q_DECLARE_TYPEINFO(ProcessModel::PercentageHistoryEntry, Q_PRIMITIVE_TYPE);
214 
215 #endif
216