File indexing completed on 2024-05-05 17:39:54

0001 /*
0002  *  KSysGuard, the KDE System Guard
0003  *
0004  *  SPDX-FileCopyrightText: 2022 Eugene Popov <popov895@ukr.net>
0005  *
0006  *  SPDX-License-Identifier: LGPL-2.0-or-later
0007  */
0008 
0009 #include "ProcessDetailsDialog.h"
0010 
0011 #include <QLayout>
0012 #include <QTabWidget>
0013 
0014 #include <KLocalizedString>
0015 #include <KMessageWidget>
0016 
0017 #include "processcore/extended_process_list.h"
0018 
0019 #include "GeneralTab.h"
0020 #include "MemoryMapsTab.h"
0021 #include "OpenFilesTab.h"
0022 
0023 ProcessDetailsDialog::ProcessDetailsDialog(QWidget *parent)
0024     : QDialog(parent)
0025 {
0026     setAttribute(Qt::WA_DeleteOnClose);
0027     setWindowTitle(i18nc("@title:window", "Process Details"));
0028     resize(900, 600);
0029 
0030     m_warningWidget = new KMessageWidget;
0031     m_warningWidget->setMessageType(KMessageWidget::Warning);
0032     m_warningWidget->setCloseButtonVisible(false);
0033     m_warningWidget->setWordWrap(true);
0034     m_warningWidget->hide();
0035 
0036     QTabWidget *tabWidget = new QTabWidget;
0037 
0038     m_generalTab = new GeneralTab;
0039     tabWidget->addTab(m_generalTab, i18nc("@title:tab", "General"));
0040 
0041     m_memoryMapsTab = new MemoryMapsTab;
0042     tabWidget->addTab(m_memoryMapsTab, i18nc("@title:tab", "Memory Maps"));
0043 
0044     m_openFilesTab = new OpenFilesTab;
0045     tabWidget->addTab(m_openFilesTab, i18nc("@title:tab", "Open Files"));
0046 
0047     QVBoxLayout *rootLayout = new QVBoxLayout;
0048     rootLayout->addWidget(m_warningWidget);
0049     rootLayout->addWidget(tabWidget);
0050     setLayout(rootLayout);
0051 
0052     const QSharedPointer<KSysGuard::ExtendedProcesses> processes = KSysGuard::ExtendedProcesses::instance();
0053     connect(processes.get(), &KSysGuard::ExtendedProcesses::beginRemoveProcess, this, &ProcessDetailsDialog::onBeginRemoveProcess);
0054     connect(processes.get(), &KSysGuard::ExtendedProcesses::processChanged, this, &ProcessDetailsDialog::onProcessChanged);
0055 }
0056 
0057 void ProcessDetailsDialog::setModelIndex(const QModelIndex &index)
0058 {
0059     if (m_index != index) {
0060         m_index = index;
0061 
0062         if (m_index.isValid()) {
0063             m_warningWidget->animatedHide();
0064         }
0065 
0066         m_generalTab->setData(getProcessData());
0067 
0068         const long processId = getProcessId();
0069         m_memoryMapsTab->setProcessId(processId);
0070         m_openFilesTab->setProcessId(processId);
0071     }
0072 }
0073 
0074 void ProcessDetailsDialog::onBeginRemoveProcess(KSysGuard::Process *process)
0075 {
0076     if (getProcessId() == process->pid()) {
0077         setModelIndex(QModelIndex());
0078 
0079         m_warningWidget->setText(i18nc("@info:status", "The \"%1\" (PID: %2) process has stopped executing", process->name(), process->pid()));
0080         m_warningWidget->animatedShow();
0081     }
0082 }
0083 
0084 void ProcessDetailsDialog::onProcessChanged(KSysGuard::Process *process)
0085 {
0086     if (getProcessId() == process->pid()) {
0087         m_generalTab->setData(getProcessData());
0088     }
0089 }
0090 
0091 const KSysGuard::Process* ProcessDetailsDialog::getProcess() const
0092 {
0093     if (m_index.isValid()) {
0094         return reinterpret_cast<const KSysGuard::Process*>(m_index.internalPointer());
0095     }
0096 
0097     return nullptr;
0098 }
0099 
0100 long ProcessDetailsDialog::getProcessId() const
0101 {
0102     if (const KSysGuard::Process *process = getProcess()) {
0103         return process->pid();
0104     }
0105 
0106     return 0;
0107 }
0108 
0109 QVariantMap ProcessDetailsDialog::getProcessData() const
0110 {
0111     QVariantMap processData;
0112 
0113     if (m_index.isValid()) {
0114         const QAbstractItemModel *model = m_index.model();
0115         const int row = m_index.row();
0116         const int column = m_index.column();
0117         for (int i = 0, n = model->columnCount(); i < n; ++i) {
0118             const QString columnTitle = model->headerData(i, Qt::Horizontal).toString();
0119             if (i == column) {
0120                 processData.insert(columnTitle, m_index.data());
0121             } else {
0122                 processData.insert(columnTitle, m_index.sibling(row, i).data());
0123             }
0124         }
0125 
0126         processData.insert(i18nc("@title:column Process I/O priority", "IO Priority"), getProcess()->ioPriorityClassAsString());
0127     }
0128 
0129     return processData;
0130 }