Sisyphus repositório
Última atualização: 25 setembro 2023 | SRPMs: 18620 | Visitas: 30266898
en ru br
ALT Linux repositórios
S:5.27.8-alt1

Group :: Sistema/Bibliotecas
RPM: plasma5-libksysguard

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs e FR  Repocop 

Patch: alt-killbtn.patch
Download


commit 8de2ffd5ebfc0ba90cf829675e07ae35ff2ea82a
Author: Oleg Solovyov <mcpain@altlinux.org>
Date:   Wed Oct 24 09:59:54 2018 +0300
    - processui: implement a killbutton
diff --git a/libksysguard/processui/ProcessModel.cpp b/libksysguard/processui/ProcessModel.cpp
--- a/libksysguard/processui/ProcessModel.cpp
+++ b/libksysguard/processui/ProcessModel.cpp
@@ -1004,6 +1004,7 @@ static inline QVariant columnAlignment(c
         case ProcessModel::HeadingVmSize:
         case ProcessModel::HeadingIoWrite:
         case ProcessModel::HeadingIoRead:
+        case ProcessModel::HeadingKillBtn:
         case ProcessModel::HeadingVmPSS:
             return QVariant(Qt::AlignRight | Qt::AlignVCenter);
         case ProcessModel::HeadingTty:
@@ -2077,6 +2078,7 @@ void ProcessModel::setupHeader() {
     headings << i18nc("process heading", "Relative Start Time");
     headings << i18nc("process heading", "NNP");
     headings << i18nc("process heading", "Command");
+    headings << i18nc("process heading", "Kill Button");
 #if HAVE_X11
     if (d->mIsX11) {
         headings << i18nc("process heading", "X11 Memory");
diff --git a/libksysguard/processui/ProcessModel.h b/libksysguard/processui/ProcessModel.h
--- a/libksysguard/processui/ProcessModel.h
+++ b/libksysguard/processui/ProcessModel.h
@@ -142,7 +142,7 @@ class KSYSGUARD_EXPORT ProcessModel : pu
          *  setup header function, and make sure you increase PROCESSHEADERVERSION.  This will ensure
          *  that old saved settings won't be used
          */
-#define PROCESSHEADERVERSION 10
+#define PROCESSHEADERVERSION 11
         enum { HeadingName=0,
             HeadingUser,
             HeadingPid,
@@ -158,6 +158,7 @@ class KSYSGUARD_EXPORT ProcessModel : pu
             HeadingStartTime,
             HeadingNoNewPrivileges,
             HeadingCommand,
+            HeadingKillBtn,
             HeadingXMemory,
             HeadingXTitle,
             HeadingCGroup,
diff --git a/libksysguard/processui/ksysguardprocesslist.cpp b/libksysguard/processui/ksysguardprocesslist.cpp
--- a/libksysguard/processui/ksysguardprocesslist.cpp
+++ b/libksysguard/processui/ksysguardprocesslist.cpp
@@ -74,6 +74,97 @@
 #ifdef DO_MODELCHECK
 #include "modeltest.h"
 #endif
+KillButtonDelegate::KillButtonDelegate(QObject *parent) {
+    if(QTreeView *treeView = qobject_cast<QTreeView*>(parent))
+    {
+        m_treeView = treeView;
+        m_btn = new QPushButton(i18n("Terminate process"), treeView);
+        m_btn->hide();
+        m_counter = 0;
+    }
+}
+
+void KillButtonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt, const QModelIndex &index) const
+{
+    m_btn->setGeometry(opt.rect);
+    m_btn->setText(i18n("Terminate process"));
+    if(opt.state == QStyle::State_Selected)
+    {
+        painter->fillRect(opt.rect, opt.palette.highlight());
+    }
+    QPixmap map = m_btn->grab();
+    painter->drawPixmap(opt.rect.x(), opt.rect.y(), map);
+}
+
+QSize KillButtonDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+    return m_btn->sizeHint();
+}
+
+bool KillButtonDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
+{
+    if (event->type() == QEvent::MouseMove) {
+        if (index != m_lastUnderMouse) {
+            if (m_lastUnderMouse.isValid()) {
+                //model->setData(m_lastUnderMouse, (int)Normal, Qt::UserRole);
+                //emit needsUpdate(m_lastUnderMouse);
+            }
+            if (index.isValid() && index.column() == ProcessModel::HeadingKillBtn) {
+                //model->setData(index, (int)Hovered, Qt::UserRole);
+                //emit needsUpdate(index);
+                m_lastUnderMouse = index;
+            } else {
+                m_lastUnderMouse = QModelIndex();
+            }
+        }
+    }
+    if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) {
+        if (index != m_lastUnderMouse) {
+            if (m_lastUnderMouse.isValid()) {
+                //model->setData(m_lastUnderMouse, (int)Normal, Qt::UserRole);
+                //emit needsUpdate(m_lastUnderMouse);
+            }
+            if (index.isValid() && index.column() == ProcessModel::HeadingKillBtn) {
+                //model->setData(index, (int)Pressed, Qt::UserRole);
+                //emit needsUpdate(index);
+                qDebug() << "Emitting clicked and changing m_lastUnderMouse";
+                emit clicked(index);
+                m_lastUnderMouse = index;
+            } else {
+                m_lastUnderMouse = QModelIndex();
+            }
+        } else {
+            if (m_lastUnderMouse.isValid()) {
+                //model->setData(m_lastUnderMouse, (int)Pressed, Qt::UserRole);
+                //emit needsUpdate(m_lastUnderMouse);
+                qDebug() << "Emitting clicked";
+                emit clicked(m_lastUnderMouse);
+            }
+        }
+    }
+    if (event->type() == QEvent::MouseButtonRelease) {
+        if (index != m_lastUnderMouse) {
+            if (m_lastUnderMouse.isValid()) {
+                //model->setData(m_lastUnderMouse, (int)Normal, Qt::UserRole);
+                //emit needsUpdate(m_lastUnderMouse);
+            }
+            if (index.isValid() && index.column() == ProcessModel::HeadingKillBtn) {
+                //model->setData(index, (int)Hovered, Qt::UserRole);
+                //emit needsUpdate(index);
+                m_lastUnderMouse = index;
+            } else {
+                m_lastUnderMouse = QModelIndex();
+            }
+        } else {
+            if (m_lastUnderMouse.isValid()) {
+                //model->setData(m_lastUnderMouse, (int)Hovered, Qt::UserRole);
+                //emit needsUpdate(m_lastUnderMouse);
+            }
+        }
+    }
+    return QStyledItemDelegate::editorEvent(event, model, option, index);
+}
+
 class ProgressBarItemDelegate : public QStyledItemDelegate
 {
     public:
@@ -313,6 +404,9 @@ KSysGuardProcessList::KSysGuardProcessLi
     new ModelTest(&d->mModel, this);
 #endif
     d->mUi->treeView->setItemDelegate(new ProgressBarItemDelegate(d->mUi->treeView));
+    KillButtonDelegate *delegate = new KillButtonDelegate(d->mUi->treeView);
+    d->mUi->treeView->setItemDelegateForColumn(ProcessModel::HeadingKillBtn, delegate);
+    connect(delegate, &KillButtonDelegate::clicked, this, &KSysGuardProcessList::killProcess);
 
     d->mUi->treeView->header()->setContextMenuPolicy(Qt::CustomContextMenu);
     connect(d->mUi->treeView->header(), &QWidget::customContextMenuRequested, this, &KSysGuardProcessList::showColumnContextMenu);
@@ -347,6 +441,7 @@ KSysGuardProcessList::KSysGuardProcessLi
     d->mUi->treeView->header()->hideSection(ProcessModel::HeadingIoRead);
     d->mUi->treeView->header()->hideSection(ProcessModel::HeadingIoWrite);
     d->mUi->treeView->header()->hideSection(ProcessModel::HeadingXMemory);
+    d->mUi->treeView->header()->hideSection(ProcessModel::HeadingKillBtn);
     d->mUi->treeView->header()->hideSection(ProcessModel::HeadingCGroup);
     d->mUi->treeView->header()->hideSection(ProcessModel::HeadingMACContext);
     d->mUi->treeView->header()->hideSection(ProcessModel::HeadingVmPSS);
@@ -736,7 +831,7 @@ void KSysGuardProcessList::showColumnCon
                 break;
             }
         }
-        if(anyOtherVisibleColumns) {
+        if(anyOtherVisibleColumns && index != ProcessModel::HeadingKillBtn) {
             //selected a column.  Give the option to hide it
             action = new QAction(&menu);
             action->setData(-index-1); //We set data to be negative (and minus 1) to hide a column, and positive to show a column
@@ -750,7 +845,7 @@ void KSysGuardProcessList::showColumnCon
 
     if(d->mUi->treeView->header()->sectionsHidden()) {
         for(int i = 0; i < num_headings; ++i) {
-            if(d->mUi->treeView->header()->isSectionHidden(i)) {
+            if(d->mUi->treeView->header()->isSectionHidden(i) && i != ProcessModel::HeadingKillBtn) {
 #ifndef HAVE_XRES
                 if(i == ProcessModel::HeadingXMemory)
                     continue;
@@ -1351,32 +1446,43 @@ bool KSysGuardProcessList::killProcesses
     return false;
 }
 
+void KSysGuardProcessList::killProcess(const QModelIndex index)
+{
+    qDebug() << "Row" << index.row();
+    QModelIndex realIndex = d->mFilterModel.mapToSource(index);
+    KSysGuard::Process *process = d->mModel.getProcessAtIndex(realIndex.row());
+    long long pid = process->pid();
+    qDebug() << "Adding pid" << pid;
+    QList< long long> list;
+    list << pid;
+    sendSignalToProcesses(list, SIGTERM, true);
+    //connect(d->mUi->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &KSysGuardProcessList::killSelectedProcesses);
+    //d->mUi->treeView->selectionModel()->select(index, QItemSelectionModel::Rows);
+}
+
 void KSysGuardProcessList::killSelectedProcesses()
 {
     sendSignalToSelectedProcesses(SIGTERM, true);
+    //disconnect(d->mUi->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &KSysGuardProcessList::killSelectedProcesses);
 }
 
-void KSysGuardProcessList::sendSignalToSelectedProcesses(int sig, bool confirm)
+void KSysGuardProcessList::sendSignalToProcesses(const QList<long long > &pids, int sig, bool confirm)
 {
-    QModelIndexList selectedIndexes = d->mUi->treeView->selectionModel()->selectedRows();
-    QStringList selectedAsStrings;
-    QList< long long> selectedPids;
-
-    QList<KSysGuard::Process *> processes = selectedProcesses();
-    foreach(KSysGuard::Process *process, processes) {
-        selectedPids << process->pid();
+    QStringList asStrings;
+    foreach(long long pid, pids) {
         if (!confirm)
             continue;
-        QString name = d->mModel.getStringForProcess(process);
-        selectedAsStrings << name;
+        QString name = d->mModel.getStringForProcess(d->mModel.getProcess(pid));
+        qDebug() << "String" << name;
+        asStrings << name;
     }
 
-    if (selectedPids.isEmpty()) {
+    if (pids.isEmpty()) {
         if (confirm)
             KMessageBox::sorry(this, i18n("You must select a process first."));
         return;
     } else if (confirm && (sig == SIGTERM || sig == SIGKILL)) {
-        int count = selectedAsStrings.count();
+        int count = asStrings.count();
         QString msg;
         QString title;
         QString dontAskAgainKey;
@@ -1397,7 +1503,7 @@ void KSysGuardProcessList::sendSignalToS
             closeButton = i18n("Kill");
         }
 
-        int res = KMessageBox::warningContinueCancelList(this, msg, selectedAsStrings,
+        int res = KMessageBox::warningContinueCancelList(this, msg, asStrings,
                 title,
                 KGuiItem(closeButton, QStringLiteral("process-stop")),
                 KStandardGuiItem::cancel(),
@@ -1409,10 +1515,10 @@ void KSysGuardProcessList::sendSignalToS
     //We have shown a GUI dialog box, which processes events etc.
     //So processes is NO LONGER VALID
 
-    if (!killProcesses(selectedPids, sig))
+    if (!killProcesses(pids, sig))
         return;
     if (sig == SIGTERM || sig == SIGKILL) {
-        foreach (long long pid, selectedPids) {
+        foreach (long long pid, pids) {
             KSysGuard::Process *process = d->mModel.getProcess(pid);
             if (process)
                 process->timeKillWasSent().start();
@@ -1422,6 +1528,24 @@ void KSysGuardProcessList::sendSignalToS
     updateList();
 }
 
+void KSysGuardProcessList::sendSignalToSelectedProcesses(int sig, bool confirm)
+{
+    QModelIndexList selectedIndexes = d->mUi->treeView->selectionModel()->selectedRows();
+    QStringList selectedAsStrings;
+    QList< long long> selectedPids;
+
+    QList<KSysGuard::Process *> processes = selectedProcesses();
+    foreach(KSysGuard::Process *process, processes) {
+        selectedPids << process->pid();
+        if (!confirm)
+            continue;
+        QString name = d->mModel.getStringForProcess(process);
+        selectedAsStrings << name;
+    }
+
+    sendSignalToProcesses(selectedPids, sig, confirm);
+}
+
 bool KSysGuardProcessList::showTotals() const {
     return d->mModel.showTotals();
 }
diff --git a/libksysguard/processui/ksysguardprocesslist.h b/libksysguard/processui/ksysguardprocesslist.h
index 9e04f19..cbff357 100644
--- a/libksysguard/processui/ksysguardprocesslist.h
+++ b/libksysguard/processui/ksysguardprocesslist.h
@@ -26,6 +26,8 @@
 
 #include <QWidget>
 #include <QMetaType>
+#include <QStyledItemDelegate>
+#include <QPushButton>
 
 #include <KConfigGroup>
 
@@ -46,6 +48,26 @@ struct KSysGuardProcessListPrivate;
  * update rate and the process filter.  The buttons are used to force
  * an immediate update and to kill a process.
  */
+class KillButtonDelegate : public QStyledItemDelegate
+{
+    Q_OBJECT
+    public:
+        KillButtonDelegate(QObject *parent);
+        void paint(QPainter *painter, const QStyleOptionViewItem &opt, const QModelIndex &index) const override;
+        QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
+        bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override;
+
+    Q_SIGNALS:
+        void clicked(QModelIndex index);
+
+    private:
+        QModelIndex m_lastUnderMouse;
+        QPushButton *m_btn;
+        QTreeView *m_treeView;
+        QPersistentModelIndex currentEditedCellIndex;
+        int m_counter;
+};
+
 class Q_DECL_EXPORT KSysGuardProcessList : public QWidget
 {
     Q_OBJECT
@@ -136,6 +158,17 @@ class Q_DECL_EXPORT KSysGuardProcessList : public QWidget
          */
         void sendSignalToSelectedProcesses(int sig, bool confirm);
 
+        /** Send a signal to a given processes.
+         * @p pids      A list of PIDs that should be sent the signal
+         * @p confirm - If true, pops up a dialog box to confirm with the user
+         */
+        void sendSignalToProcesses(const QList< long long> &pids, int sig, bool confirm);
+
+        /** Send a signal to a given process.
+         *   @p index Index of a given process allowing a user to kill it.
+         */
+        void killProcess(const QModelIndex index);
+
         /** Send a signal to a list of given processes.
          *   @p pids A list of PIDs that should be sent the signal
          *   @p sig  The signal to send.
 
projeto & código: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
mantenedor atual: Michael Shigorin
mantenedor da tradução: Fernando Martini aka fmartini © 2009