2021-10-16 18:37:11 -05:00
|
|
|
#include "SeerSlashProcWidget.h"
|
|
|
|
|
#include "QProcessInfo.h"
|
|
|
|
|
#include <QtWidgets/QTreeWidget>
|
|
|
|
|
#include <QtWidgets/QTreeWidgetItemIterator>
|
|
|
|
|
#include <QtWidgets/QApplication>
|
2021-11-08 10:22:40 -06:00
|
|
|
#include <QtGui/QFont>
|
2021-10-16 18:37:11 -05:00
|
|
|
#include <QtCore/QDebug>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Custom tree item with numeric ordering on column 0.
|
|
|
|
|
//
|
|
|
|
|
class QProcessInfoWidgetItem : public QTreeWidgetItem {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
QProcessInfoWidgetItem(QTreeWidget* parent = 0) : QTreeWidgetItem(parent) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
bool operator< (const QTreeWidgetItem& other) const {
|
|
|
|
|
|
|
|
|
|
int column = treeWidget()->sortColumn();
|
|
|
|
|
|
|
|
|
|
if (column == 0) {
|
|
|
|
|
return text(column).toLong() < other.text(column).toLong();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return text(column) < other.text(column);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// The main widget starts here.
|
|
|
|
|
//
|
|
|
|
|
SeerSlashProcWidget::SeerSlashProcWidget (QWidget* parent) : QWidget(parent) {
|
|
|
|
|
|
|
|
|
|
// Construct the UI.
|
|
|
|
|
setupUi(this);
|
|
|
|
|
|
|
|
|
|
// Setup the widgets
|
|
|
|
|
processTreeWidget->setMouseTracking(true);
|
|
|
|
|
processTreeWidget->resizeColumnToContents(0);
|
|
|
|
|
processTreeWidget->resizeColumnToContents(1);
|
|
|
|
|
processTreeWidget->resizeColumnToContents(2);
|
2021-11-25 21:59:03 -06:00
|
|
|
processTreeWidget->resizeColumnToContents(3);
|
2021-10-16 18:37:11 -05:00
|
|
|
processTreeWidget->setSortingEnabled(true);
|
|
|
|
|
processTreeWidget->clear();
|
2021-11-21 12:00:15 -06:00
|
|
|
systemProcessesCheckBox->setChecked(false);
|
2021-10-16 18:37:11 -05:00
|
|
|
|
|
|
|
|
// Connect things.
|
2021-11-25 21:59:03 -06:00
|
|
|
QObject::connect(programNameLineEdit, &QLineEdit::textChanged, this, &SeerSlashProcWidget::refreshView);
|
|
|
|
|
QObject::connect(userNameLineEdit, &QLineEdit::textChanged, this, &SeerSlashProcWidget::refreshView);
|
|
|
|
|
QObject::connect(systemProcessesCheckBox, &QCheckBox::clicked, this, &SeerSlashProcWidget::refreshView);
|
|
|
|
|
QObject::connect(refreshToolButton, &QToolButton::clicked, this, &SeerSlashProcWidget::refreshList);
|
2021-11-28 07:28:07 -06:00
|
|
|
QObject::connect(processTreeWidget, &QTreeWidget::itemDoubleClicked, this, &SeerSlashProcWidget::handleDoubleClicked);
|
2021-10-16 18:37:11 -05:00
|
|
|
|
|
|
|
|
// Load the initial process list.
|
2021-11-25 21:59:03 -06:00
|
|
|
refreshList();
|
2021-10-16 18:37:11 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SeerSlashProcWidget::~SeerSlashProcWidget () {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int SeerSlashProcWidget::selectedPid () const {
|
|
|
|
|
|
|
|
|
|
QList<QTreeWidgetItem*> items = processTreeWidget->selectedItems();
|
|
|
|
|
|
|
|
|
|
if (items.size() == 0) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return items[0]->text(0).toLong();
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
QString SeerSlashProcWidget::selectedUsername () const {
|
2021-10-16 18:37:11 -05:00
|
|
|
|
|
|
|
|
QList<QTreeWidgetItem*> items = processTreeWidget->selectedItems();
|
|
|
|
|
|
|
|
|
|
if (items.size() == 0) {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return items[0]->text(1);
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
QString SeerSlashProcWidget::selectedName () const {
|
2021-10-16 18:37:11 -05:00
|
|
|
|
|
|
|
|
QList<QTreeWidgetItem*> items = processTreeWidget->selectedItems();
|
|
|
|
|
|
|
|
|
|
if (items.size() == 0) {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return items[0]->text(2);
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
QString SeerSlashProcWidget::selectedCommandLine () const {
|
|
|
|
|
|
|
|
|
|
QList<QTreeWidgetItem*> items = processTreeWidget->selectedItems();
|
|
|
|
|
|
|
|
|
|
if (items.size() == 0) {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return items[0]->text(3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SeerSlashProcWidget::refreshList () {
|
2021-10-16 18:37:11 -05:00
|
|
|
|
|
|
|
|
QApplication::setOverrideCursor(Qt::BusyCursor);
|
|
|
|
|
|
|
|
|
|
// Scan the /proc file system.
|
2021-11-25 21:59:03 -06:00
|
|
|
QProcessList list = QProcessInfo::populate();
|
2021-10-16 18:37:11 -05:00
|
|
|
|
|
|
|
|
// Loop through each entry and add it to our view.
|
|
|
|
|
processTreeWidget->clear();
|
|
|
|
|
|
|
|
|
|
for (const QProcessInfo& info : list) {
|
|
|
|
|
|
|
|
|
|
QTreeWidgetItem* item = new QProcessInfoWidgetItem;
|
|
|
|
|
item->setText(0, QString::number(info.pid()));
|
2021-11-25 21:59:03 -06:00
|
|
|
item->setText(1, info.username());
|
|
|
|
|
item->setText(2, info.name());
|
|
|
|
|
item->setText(3, info.commandLine());
|
2021-10-16 18:37:11 -05:00
|
|
|
|
|
|
|
|
processTreeWidget->addTopLevelItem(item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Adjust the column widths.
|
|
|
|
|
processTreeWidget->clearSelection();
|
|
|
|
|
processTreeWidget->resizeColumnToContents(0);
|
|
|
|
|
processTreeWidget->resizeColumnToContents(1);
|
|
|
|
|
processTreeWidget->resizeColumnToContents(2);
|
2021-11-25 21:59:03 -06:00
|
|
|
processTreeWidget->resizeColumnToContents(3);
|
2021-10-16 18:37:11 -05:00
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
// Don't clear the line edits.
|
|
|
|
|
// programNameLineEdit->clear();
|
|
|
|
|
// userNameLineEdit->clear();
|
|
|
|
|
|
|
|
|
|
refreshView();
|
2021-10-16 18:37:11 -05:00
|
|
|
|
|
|
|
|
QApplication::restoreOverrideCursor();
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
void SeerSlashProcWidget::refreshView () {
|
2021-10-16 18:37:11 -05:00
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
// Get this list of program name matches. Or all if there is no program name provided.
|
|
|
|
|
QList<QTreeWidgetItem*> programNameMatches;
|
2021-10-16 18:37:11 -05:00
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
if (programNameLineEdit->text() == "") {
|
|
|
|
|
programNameMatches = processTreeWidget->findItems("*", Qt::MatchWildcard | Qt::MatchRecursive, 2);
|
2021-10-16 18:37:11 -05:00
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
}else{
|
|
|
|
|
if (programNameLineEdit->text().contains('*')) {
|
|
|
|
|
programNameMatches = processTreeWidget->findItems(programNameLineEdit->text(), Qt::MatchWildcard | Qt::MatchRecursive, 2);
|
2021-10-16 18:37:11 -05:00
|
|
|
}else{
|
2021-11-25 21:59:03 -06:00
|
|
|
programNameMatches = processTreeWidget->findItems(programNameLineEdit->text(), Qt::MatchStartsWith | Qt::MatchRecursive, 2);
|
2021-10-16 18:37:11 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
// Get this list of user name matches. Or all if there is no user name provided.
|
|
|
|
|
QList<QTreeWidgetItem*> userNameMatches;
|
2021-10-16 18:37:11 -05:00
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
if (userNameLineEdit->text() == "") {
|
|
|
|
|
userNameMatches = processTreeWidget->findItems("*", Qt::MatchWildcard | Qt::MatchRecursive, 1);
|
2021-10-16 18:37:11 -05:00
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
}else{
|
|
|
|
|
if (userNameLineEdit->text().contains('*')) {
|
|
|
|
|
userNameMatches = processTreeWidget->findItems(userNameLineEdit->text(), Qt::MatchWildcard | Qt::MatchRecursive, 1);
|
2021-10-16 18:37:11 -05:00
|
|
|
}else{
|
2021-11-25 21:59:03 -06:00
|
|
|
userNameMatches = processTreeWidget->findItems(userNameLineEdit->text(), Qt::MatchStartsWith | Qt::MatchRecursive, 1);
|
2021-10-16 18:37:11 -05:00
|
|
|
}
|
2021-11-25 21:59:03 -06:00
|
|
|
}
|
2021-10-16 18:37:11 -05:00
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
// Get this list of process matches. Include one's with [xxx]) or not.
|
|
|
|
|
QList<QTreeWidgetItem*> processMatches;
|
2021-10-16 18:37:11 -05:00
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
if (systemProcessesCheckBox->isChecked() == true) {
|
|
|
|
|
processMatches = processTreeWidget->findItems("*", Qt::MatchWildcard | Qt::MatchRecursive, 2);
|
|
|
|
|
//qDebug() << __PRETTY_FUNCTION__ << ": Checkbox is on." << processMatches.size();
|
2021-10-16 18:37:11 -05:00
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
}else{
|
|
|
|
|
// To find [xxx] processes : "^(\\[).*(\\])$"
|
|
|
|
|
// To exclude [xxx] processes: "^(?!\\[).*(?!\\])$"
|
|
|
|
|
processMatches = processTreeWidget->findItems("^(?!\\[).*(?!\\])$", Qt::MatchRegExp | Qt::MatchRecursive, 2);
|
|
|
|
|
//qDebug() << __PRETTY_FUNCTION__ << ": Checkbox is off." << processMatches.size();
|
|
|
|
|
}
|
2021-10-16 18:37:11 -05:00
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
// Go through each item in the tree. If it's in the user, program, and process matches, show it.
|
|
|
|
|
// Otherwise, hide it.
|
|
|
|
|
QTreeWidgetItemIterator it(processTreeWidget);
|
2021-10-16 18:37:11 -05:00
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
while (*it) {
|
2021-10-16 18:37:11 -05:00
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
if (programNameMatches.contains(*it) && userNameMatches.contains(*it) && processMatches.contains(*it)) {
|
|
|
|
|
(*it)->setHidden(false);
|
2021-10-16 18:37:11 -05:00
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
}else{
|
|
|
|
|
(*it)->setHidden(true);
|
2021-10-16 18:37:11 -05:00
|
|
|
}
|
|
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
++it;
|
2021-10-16 18:37:11 -05:00
|
|
|
}
|
|
|
|
|
|
2021-11-25 21:59:03 -06:00
|
|
|
// Resize the columns.
|
2021-10-16 18:37:11 -05:00
|
|
|
processTreeWidget->resizeColumnToContents(0);
|
|
|
|
|
processTreeWidget->resizeColumnToContents(1);
|
|
|
|
|
processTreeWidget->resizeColumnToContents(2);
|
2021-11-25 21:59:03 -06:00
|
|
|
processTreeWidget->resizeColumnToContents(3);
|
2021-10-16 18:37:11 -05:00
|
|
|
}
|
|
|
|
|
|
2021-11-28 07:28:07 -06:00
|
|
|
void SeerSlashProcWidget::handleDoubleClicked () {
|
|
|
|
|
emit pidSelected();
|
|
|
|
|
}
|
|
|
|
|
|