add system monitor plugin

This commit is contained in:
李 翔 2018-01-04 09:50:32 +08:00
parent fb42218642
commit 4814677d74
104 changed files with 7096 additions and 267990 deletions

View File

@ -36,7 +36,7 @@ public:
};
//Q_DECLARE_INTERFACE定义在在qobject.h中用来告诉Qt meta-object system 这个接口名称
Q_DECLARE_INTERFACE(PluginInterface, "com.ubuntukylin.Plugin.PluginInterface")
Q_DECLARE_INTERFACE(PluginInterface, "com.kylin.Plugin.PluginInterface")
#endif // PLUGININTERFACE_H

View File

@ -1,8 +1,7 @@
TEMPLATE = subdirs
SUBDIRS = \
src \
shredmanager \
processmanager \
plugins \
backends
TRANSLATIONS += \

4
plugins/plugins.pro Normal file
View File

@ -0,0 +1,4 @@
TEMPLATE = subdirs
SUBDIRS = \
shredmanager \
systemmonitor

View File

@ -19,10 +19,10 @@
#include <QDialog>
#include <QSettings>
#include "../component/kylineditbutton.h"
#include "../component/kylintitlebar.h"
#include "../component/toolkits.h"
#include "../component/utils.h"
#include "../../component/kylineditbutton.h"
#include "../../component/kylintitlebar.h"
#include "../../component/toolkits.h"
#include "../../component/utils.h"
class QLabel;
class QPushButton;

View File

@ -19,7 +19,7 @@
#include <QObject>
#include <QString>
#include "../component/plugininterface.h"
#include "../../component/plugininterface.h"
#include "shreddialog.h"
//插件入口
@ -28,7 +28,7 @@ class ShredManager : public QObject , PluginInterface
Q_OBJECT
Q_INTERFACES(PluginInterface)
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
Q_PLUGIN_METADATA(IID "com.ubuntukylin.Plugin.PluginInterface" FILE "shred.json")//指定IID和.json文件
Q_PLUGIN_METADATA(IID "com.kylin.Plugin.PluginInterface" FILE "shred.json")//指定IID和.json文件
#endif
public:

View File

@ -0,0 +1,65 @@
#-------------------------------------------------
#
# Project created by QtCreator 2015-01-26T09:16:38
#
#-------------------------------------------------
#QT += core
isEqual(QT_MAJOR_VERSION, 5) {
QT += widgets gui
}
#greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = shredmanager
TEMPLATE = lib
CONFIG += plugin c++11
#INCLUDEPATH += ../shredmanager
#DESTDIR = ../libs
DESTDIR = $$_PRO_FILE_PWD_/../
#UI_DIR += $$PWD/../tmp/shredmanager/
#RCC_DIR += $$PWD/../tmp/shredmanager/
#MOC_DIR += $$PWD/../tmp/shredmanager/
#OBJECTS_DIR = $$PWD/../obj/shredmanager
unix {
UI_DIR = .ui
MOC_DIR = .moc
OBJECTS_DIR = .obj
}
#target.source += $$TARGET
#target.path = /var/lib/kylin-assistant-daemon/libs/
target.path = $${PREFIX}/lib/kylin-assistant/plugins/
INSTALLS += target
HEADERS += \
filewipe.h \
../../component/plugininterface.h \
shredmanager.h \
shreddialog.h \
../../component/toolkits.h \
../../component/alertdialog.h \
../../component/utils.h \
../../component/toolkits.h \
../../component/kylintitlebar.h \
../../component/systembutton.h \
../../component/kylineditbutton.h
SOURCES += \
filewipe.cpp \
shredmanager.cpp \
shreddialog.cpp \
../../component/alertdialog.cpp \
../../component/toolkits.cpp \
../../component/kylintitlebar.cpp \
../../component/systembutton.cpp \
../../component/kylineditbutton.cpp
OTHER_FILES += \
shred.json
FORMS += \
../../component/alertdialog.ui
RESOURCES += \
../../src/img.qrc

View File

@ -0,0 +1,64 @@
#include "diskinfo.h"
#include <QDebug>
DiskInfo::DiskInfo(QObject *parent)
: QObject(parent)
{
}
const QString DiskInfo::devname() const
{
return m_devName;
}
void DiskInfo::setDevName(const QString &name)
{
if (name != m_devName)
m_devName = name;
}
const QString DiskInfo::mountdir() const
{
return m_mountDir;
}
const QString DiskInfo::disktype() const
{
return m_diskType;
}
const QString DiskInfo::totalcapacity() const
{
return m_totalCapacity;
}
const QString DiskInfo::availcapacity() const
{
return m_availCapacity;
}
const QString DiskInfo::usedcapactiy() const
{
return m_usedCapactiy;
}
const QString DiskInfo::percentage() const
{
return m_percentage;
}
void DiskInfo::setOtherDiskInfo(QString mountDir, QString diskType, QString totalCapacity, QString availCapacity, QString usedCapactiy, QString percentage)
{
if (mountDir != m_mountDir)
m_mountDir = mountDir;
if (diskType != m_diskType)
m_diskType = diskType;
if (totalCapacity != m_totalCapacity)
m_totalCapacity = totalCapacity;
if (availCapacity != m_availCapacity)
m_availCapacity = availCapacity;
if (usedCapactiy != m_usedCapactiy)
m_usedCapactiy = usedCapactiy;
if (percentage != m_percentage)
m_percentage = percentage;
}

View File

@ -0,0 +1,37 @@
#ifndef DISKINFO_H
#define DISKINFO_H
#include <QObject>
#include <QString>
class DiskInfo : public QObject
{
Q_OBJECT
public:
explicit DiskInfo(QObject *parent = 0);
const QString devname() const;
void setDevName(const QString &name);
const QString mountdir() const;
const QString disktype() const;
const QString totalcapacity() const;
const QString availcapacity() const;
const QString usedcapactiy() const;
const QString percentage() const;
void setOtherDiskInfo(QString mountDir, QString diskType, QString totalCapacity, QString availCapacity, QString usedCapactiy, QString percentage);
private:
QString m_devName;
QString m_mountDir;
QString m_diskType;
QString m_totalCapacity;
QString m_availCapacity;
QString m_usedCapactiy;
QString m_percentage;
};
#endif // DISKINFO_H

View File

@ -0,0 +1,121 @@
#include "diskitem.h"
#include "myimagebutton.h"
#include <QHBoxLayout>
#include <QMouseEvent>
#include <QStyle>
DiskItem::DiskItem(QWidget *parent)
: QFrame(parent)
,m_isHead(false)
,m_isTail(false)
,m_nameLabel(new QLabel)
,m_mountLabel(new QLabel)
,m_typeLabel(new QLabel)
,m_totoalLabel(new QLabel)
,m_availLabel(new QLabel)
,m_usedLabel(new QLabel)
,m_percentageLabel(new QLabel)
,m_detailBtn(new MyImageButton)
{
this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
this->setFixedHeight(36);
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->setSpacing(0);
mainLayout->setMargin(0);
mainLayout->setContentsMargins(20, 0, 10, 0);
mainLayout->addWidget(m_nameLabel);
mainLayout->addWidget(m_mountLabel);
mainLayout->addWidget(m_typeLabel);
mainLayout->addWidget(m_totoalLabel);
mainLayout->addWidget(m_availLabel);
mainLayout->addWidget(m_usedLabel);
mainLayout->addWidget(m_percentageLabel);
mainLayout->addSpacing(8);
// mainLayout->addStretch();
mainLayout->addWidget(m_detailBtn);
setLayout(mainLayout);
m_detailBtn->setObjectName("DiskDetailButton");
connect(m_detailBtn, &MyImageButton::clicked, this, [=] {
//TODO: show detail dialog
});
}
DiskItem::~DiskItem()
{
delete m_nameLabel;
delete m_mountLabel;
delete m_typeLabel;
delete m_totoalLabel;
delete m_availLabel;
delete m_usedLabel;
delete m_percentageLabel;
delete m_detailBtn;
}
void DiskItem::setIsHead(bool head)
{
if (head == m_isHead) return;
m_isHead = head;
style()->unpolish(this);
style()->polish(this);
}
void DiskItem::setIsTail(bool tail)
{
if (tail == m_isTail) return;
m_isTail = tail;
style()->unpolish(this);
style()->polish(this);
}
void DiskItem::setDevName(const QString &name)
{
m_nameLabel->setText(name);
setAccessibleName(name);
}
void DiskItem::setMountDir(const QString &mountdir)
{
m_mountLabel->setText(mountdir);
}
void DiskItem::setDiskType(const QString &disktype)
{
m_typeLabel->setText(disktype);
}
void DiskItem::setTotalCapacity(const QString &totalcapacity)
{
m_totoalLabel->setText(totalcapacity);
}
void DiskItem::setAvailCapacity(const QString &availcapacity)
{
m_availLabel->setText(availcapacity);
}
void DiskItem::setUsedCapactiy(const QString &usedcapactiy)
{
m_usedLabel->setText(usedcapactiy);
}
void DiskItem::setPercentage(const QString &percentage)
{
m_percentageLabel->setText(percentage);
}
void DiskItem::mouseReleaseEvent(QMouseEvent *e)
{
e->accept();
emit selected();
emit clicked();
}

View File

@ -0,0 +1,52 @@
#ifndef DISKITEM_H
#define DISKITEM_H
#include <QFrame>
#include <QMap>
#include <QMapNode>
#include <QLabel>
class MyImageButton;
class DiskItem : public QFrame
{
Q_OBJECT
public:
explicit DiskItem(QWidget *parent = 0);
~DiskItem();
inline QString devName() const { return m_nameLabel->text(); }
void setDevName(const QString &name);
void setMountDir(const QString &mountdir);
void setDiskType(const QString &disktype);
void setTotalCapacity(const QString &totalcapacity);
void setAvailCapacity(const QString &availcapacity);
void setUsedCapactiy(const QString &usedcapactiy);
void setPercentage(const QString &percentage);
void setIsHead(bool head = true);
void setIsTail(bool tail = true);
protected:
void mouseReleaseEvent(QMouseEvent *e);
signals:
void clicked() const;
void selected() const;
void acceptNextPage() const;
private:
QLabel *m_nameLabel;
QLabel *m_mountLabel;
QLabel *m_typeLabel;
QLabel *m_totoalLabel;
QLabel *m_availLabel;
QLabel *m_usedLabel;
QLabel *m_percentageLabel;
MyImageButton *m_detailBtn;
bool m_isHead;
bool m_isTail;
};
#endif // DISKITEM_H

View File

@ -0,0 +1,156 @@
#include "diskitemlist.h"
#include "diskitem.h"
#include <QVBoxLayout>
#include <QEvent>
#include <QDebug>
DiskItemList::DiskItemList(QFrame *parent) :
QWidget(parent),
m_layout(new QVBoxLayout),
m_updateHTimer(new QTimer(this)),
m_updateHeadTimer(new QTimer(this))
{
m_layout->setMargin(0);
m_layout->setSpacing(1);
m_updateHTimer->setSingleShot(true);
m_updateHTimer->setInterval(10);
m_updateHeadTimer->setSingleShot(true);
m_updateHeadTimer->setInterval(10);
connect(m_updateHTimer, &QTimer::timeout, this, &DiskItemList::updateHeight, Qt::QueuedConnection);
connect(m_updateHeadTimer, &QTimer::timeout, this, &DiskItemList::updateHeadTail, Qt::QueuedConnection);
setLayout(m_layout);
}
DiskItemList::~DiskItemList()
{
}
void DiskItemList::appendItem(DiskItem *item)
{
m_layout->insertWidget(m_layout->count(), item);
item->installEventFilter(this);
m_updateHeadTimer->start();
m_updateHTimer->start();
}
void DiskItemList::removeItem(DiskItem *item)
{
m_layout->removeWidget(item);
item->removeEventFilter(this);
m_updateHeadTimer->start();
m_updateHTimer->start();
}
void DiskItemList::moveItem(DiskItem *item, const int index)
{
const int oldIndex = m_layout->indexOf(item);
if (oldIndex == index)
return;
m_layout->removeWidget(item);
m_layout->insertWidget(index, item);
const int max = m_layout->count() - 1;
if (index == 0 || index == max ||
oldIndex == 0 || oldIndex == max)
m_updateHeadTimer->start();
}
void DiskItemList::setSpacing(const int spaceing)
{
m_layout->setSpacing(spaceing);
m_updateHTimer->start();
}
int DiskItemList::itemCount() const
{
return m_layout->count();
}
void DiskItemList::clear()
{
const int index = 0;
const int count = m_layout->count();
for (int i(index); i != count; ++i)
{
QLayoutItem *item = m_layout->takeAt(index);
QWidget *w = item->widget();
w->removeEventFilter(this);
w->setParent(nullptr);
delete item;
}
m_updateHeadTimer->start();
m_updateHTimer->start();
}
DiskItem *DiskItemList::getItem(int index)
{
if(index < 0)
return NULL;
if(index < itemCount())
{
return qobject_cast<DiskItem *>(m_layout->itemAt(index)->widget());
}
return NULL;
}
bool DiskItemList::eventFilter(QObject *, QEvent *event)
{
switch (event->type())
{
case QEvent::Show:
case QEvent::Hide: m_updateHeadTimer->start();
case QEvent::Resize: m_updateHTimer->start(); break;
default:;
}
return false;
}
void DiskItemList::updateHeadTail()
{
DiskItem *head = nullptr;
DiskItem *tail = nullptr;
const int count = m_layout->count();
for (int i(0); i != count; ++i)
{
DiskItem *item = qobject_cast<DiskItem *>(m_layout->itemAt(i)->widget());
Q_ASSERT(item);
if (!item->isVisible())
continue;
item->setIsHead(false);
item->setIsTail(false);
if (!head)
head = item;
tail = item;
}
if (head)
head->setIsHead();
if (tail)
tail->setIsTail();
}
void DiskItemList::updateHeight()
{
Q_ASSERT(sender() == m_updateHTimer);
setFixedHeight(m_layout->sizeHint().height());
}

View File

@ -0,0 +1,43 @@
#ifndef DISKITEMLIST_H
#define DISKITEMLIST_H
#include <QFrame>
#include <QTimer>
class QVBoxLayout;
class DiskItem;
class DiskItemList : public QWidget
{
Q_OBJECT
public:
explicit DiskItemList(QFrame *parent = 0);
explicit DiskItemList(const QString &title, QFrame *parent = 0);
~DiskItemList();
DiskItem* getItem(int index);
void appendItem(DiskItem * item);
void removeItem(DiskItem * item);
void moveItem(DiskItem *item, const int index);
void setSpacing(const int spaceing);
int itemCount() const;
void clear();
private:
bool eventFilter(QObject *, QEvent *event);
void updateHeadTail();
private slots:
void updateHeight();
private:
QVBoxLayout *m_layout;
QTimer *m_updateHTimer;
QTimer *m_updateHeadTimer;
};
#endif // DISKITEMLIST_H

View File

@ -0,0 +1,46 @@
#include "diskmodel.h"
#include <QDebug>
DiskModel::DiskModel(QObject *parent) :
QObject(parent)
{
}
DiskModel::~DiskModel()
{
}
DiskInfo *DiskModel::getDiskInfo(const QString &devname)
{
return m_diskInfoList.value(devname, nullptr);
}
QList<DiskInfo *> DiskModel::diskInfoList() const
{
return m_diskInfoList.values();
}
void DiskModel::addDiskInfo(const QString &devname, DiskInfo *info)
{
if (!m_diskInfoList.contains(devname)) {
m_diskInfoList[devname] = info;
emit oneDiskInfoAdded(info);
}
}
void DiskModel::removeDiskInfo(const QString &devname)
{
DiskInfo *info = getDiskInfo(devname);
m_diskInfoList.remove(devname);
if (info)
emit oneDiskInfoRemoved(info);
}
bool DiskModel::contains(const QString &devname)
{
return m_diskInfoList.contains(devname);
}

View File

@ -0,0 +1,31 @@
#ifndef DISKMODEL_H
#define DISKMODEL_H
#include <QObject>
#include <QMap>
#include "diskinfo.h"
class DiskModel : public QObject
{
Q_OBJECT
public:
explicit DiskModel(QObject *parent = 0);
~DiskModel();
DiskInfo *getDiskInfo(const QString &devname);
QList<DiskInfo *> diskInfoList() const;
void addDiskInfo(const QString &devname, DiskInfo *info);
void removeDiskInfo(const QString &devname);
bool contains(const QString &devname);
signals:
void oneDiskInfoAdded(DiskInfo *info);
void oneDiskInfoRemoved(DiskInfo *info);
private:
QMap<QString, DiskInfo *> m_diskInfoList;
};
#endif // DISKMODEL_H

View File

@ -0,0 +1,105 @@
/*
* Copyright (C) 2013 ~ 2015 National University of Defense Technology(NUDT) & Kylin Ltd.
*
* Authors:
* Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "filesystemdialog.h"
#include <QApplication>
#include <QVBoxLayout>
#include <QEvent>
#include "diskitemlist.h"
#include "diskitem.h"
#include "diskmodel.h"
#include "diskinfo.h"
#include "filesystemworker.h"
FileSystemDialog::FileSystemDialog(QWidget *parent)
:QWidget(parent)
,m_diskItemList(new DiskItemList)
{
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
setAcceptDrops(true);
setAttribute(Qt::WA_NoMousePropagation);
// setAttribute(Qt::WA_TranslucentBackground);
this->setObjectName("FileSystemDialog");
m_centralLayout = new QVBoxLayout;
m_centralLayout->addWidget(m_diskItemList);
m_centralLayout->setSpacing(10);
m_centralLayout->setMargin(0);
setLayout(m_centralLayout);
m_diskModelList = new DiskModel;
connect(m_diskModelList, SIGNAL(oneDiskInfoAdded(DiskInfo*)), this, SLOT(addDiskInfoItem(DiskInfo*)));
connect(m_diskModelList, SIGNAL(oneDiskInfoRemoved(DiskInfo*)), this, SLOT(removeDiskInfoItemByDevName(DiskInfo*)));
m_fileSystemWorker = new FileSystemWorker(m_diskModelList);
m_fileSystemWorker->moveToThread(qApp->thread());
m_diskModelList->moveToThread(qApp->thread());
}
FileSystemDialog::~FileSystemDialog()
{
m_diskModelList->deleteLater();
m_fileSystemWorker->deleteLater();
QList<DiskItem *> items = findChildren<DiskItem*>();
for (DiskItem *item : items) {
m_diskItemList->removeItem(item);
item->deleteLater();
}
if (m_diskItemList) {
delete m_diskItemList;
m_diskItemList = 0;
}
}
void FileSystemDialog::addDiskInfoItem(DiskInfo *info)
{
DiskItem *w = new DiskItem;
m_diskItemList->appendItem(w);
w->setDevName(info->devname());
w->setMountDir(info->mountdir());
w->setDiskType(info->disktype());
w->setTotalCapacity(info->totalcapacity());
w->setAvailCapacity(info->availcapacity());
w->setUsedCapactiy(info->usedcapactiy());
w->setPercentage(info->percentage());
}
void FileSystemDialog::removeDiskInfoItemByDevName(DiskInfo *info)
{
QList<DiskItem *> items = findChildren<DiskItem*>();
for (DiskItem *item : items) {
if (item->devName() == info->devname()) {
m_diskItemList->removeItem(item);
item->deleteLater();
break;
}
}
}
bool FileSystemDialog::event(QEvent *event)
{
if (event->type() == QEvent::LayoutRequest)
setFixedHeight(m_centralLayout->sizeHint().height());
return QWidget::event(event);
}

View File

@ -17,24 +17,32 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __FILELIST_H__
#define __FILELIST_H__
#include <QWidget>
#include <glib.h>
#include <stdlib.h>
class DiskItemList;
class DiskModel;
class DiskInfo;
class FileSystemWorker;
class QVBoxLayout;
#ifdef __cplusplus
extern "C"{
#endif
class FileSystemDialog : public QWidget
{
Q_OBJECT
void filelist_init(GPtrArray**);
int filelist_append(GPtrArray*, char * value);
int filelist_length(GPtrArray*);
char * filelist_index(GPtrArray *filelist, int index);
void filelist_destroy(GPtrArray *filelist);
public:
explicit FileSystemDialog(QWidget* parent = 0);
~FileSystemDialog();
#ifdef __cplusplus
}
#endif
public slots:
void addDiskInfoItem(DiskInfo *info);
void removeDiskInfoItemByDevName(DiskInfo *info);
#endif
private:
bool event(QEvent *event);
private:
QVBoxLayout *m_centralLayout = nullptr;
DiskItemList *m_diskItemList;
DiskModel *m_diskModelList;
FileSystemWorker *m_fileSystemWorker;
};

View File

@ -0,0 +1,123 @@
#include "filesystemworker.h"
#include "diskinfo.h"
#include <stddef.h>
#include <glibtop/mountlist.h>
#include <glibtop/fsusage.h>
/*For PRIu64*/
#include <inttypes.h>
typedef struct _DISK_INFO
{
char devname[256];
char mountdir[256];
char type[256];
gint percentage;
guint64 btotal;
guint64 bavail;
guint64 bused;
gint valid;
} DISK_INFO;
static void fsusage_stats(const glibtop_fsusage *buf,
guint64 *bused, guint64 *bfree, guint64 *bavail, guint64 *btotal,
gint *percentage)
{
guint64 total = buf->blocks * buf->block_size;
if (!total) {
/* not a real device */
*btotal = *bfree = *bavail = *bused = 0ULL;
*percentage = 0;
} else {
int percent;
*btotal = total;
*bfree = buf->bfree * buf->block_size;
*bavail = buf->bavail * buf->block_size;
*bused = *btotal - *bfree;
/* percent = 100.0f * *bused / *btotal; */
percent = 100 * *bused / (*bused + *bavail);
*percentage = CLAMP(percent, 0, 100);
}
}
DISK_INFO add_disk(const glibtop_mountentry *entry, gboolean show_all_fs)
{
DISK_INFO disk;
memset(&disk, 0, sizeof(disk));
disk.valid = 0;
glibtop_fsusage usage;
guint64 bused, bfree, bavail, btotal;
gint percentage;
glibtop_get_fsusage(&usage, entry->mountdir);
if (usage.blocks == 0) {
return disk;
}
if(strcmp(entry->devname,"none")==0 || strcmp(entry->devname,"tmpfs")==0){
return disk;
}
if(strstr(entry->type, "tmpfs")) {
return disk;
}
fsusage_stats(&usage, &bused, &bfree, &bavail, &btotal, &percentage);
memcpy(disk.devname, entry->devname, strlen(entry->devname));
memcpy(disk.mountdir, entry->mountdir, strlen(entry->mountdir));
memcpy(disk.type, entry->type, strlen(entry->type));
disk.percentage = percentage;
disk.btotal = btotal;
disk.bavail = bavail;
disk.bused = bused;
disk.valid = 1;
// qDebug() << disk.devname;//设备
// qDebug() << disk.mountdir;//目录
// qDebug() << disk.type;//类型
// qDebug() << disk.percentage;
// qDebug() << g_format_size_full(disk.btotal, G_FORMAT_SIZE_DEFAULT);//总数
// qDebug() << g_format_size_full(disk.bavail, G_FORMAT_SIZE_DEFAULT);//可用
// qDebug() << g_format_size_full(disk.bused, G_FORMAT_SIZE_DEFAULT);//已用
return disk;
}
FileSystemWorker::FileSystemWorker(DiskModel *diskList, QObject *parent)
: QObject(parent),
m_diskModel(diskList)
{
onFileSystemListChanged();
}
void FileSystemWorker::onFileSystemListChanged()
{
glibtop_mountentry *entries;
glibtop_mountlist mountlist;
guint i;
gboolean show_all_fs = TRUE;
entries = glibtop_get_mountlist(&mountlist, show_all_fs);
for (i = 0; i < mountlist.number; i++) {
DISK_INFO disk = add_disk(&entries[i], show_all_fs);
if (disk.valid == 1) {
QString dev_name = QString(QLatin1String(disk.devname));
if (!m_diskModel->contains(dev_name)) {
DiskInfo *info = new DiskInfo(this);
info->setDevName(dev_name);
info->setOtherDiskInfo(QString(QLatin1String(disk.mountdir)), QString(QLatin1String(disk.type)), QString(QLatin1String(g_format_size_full(disk.btotal, G_FORMAT_SIZE_DEFAULT))), QString(QLatin1String(g_format_size_full(disk.bavail, G_FORMAT_SIZE_DEFAULT))), QString(QLatin1String(g_format_size_full(disk.bused, G_FORMAT_SIZE_DEFAULT))), QString::number(disk.percentage).append("%"));
m_diskModel->addDiskInfo(dev_name, info);
}
else {//update info which had exists
DiskInfo *info = m_diskModel->getDiskInfo(dev_name);
if (info) {
info->setOtherDiskInfo(QString(QLatin1String(disk.mountdir)), QString(QLatin1String(disk.type)), QString(QLatin1String(g_format_size_full(disk.btotal, G_FORMAT_SIZE_DEFAULT))), QString(QLatin1String(g_format_size_full(disk.bavail, G_FORMAT_SIZE_DEFAULT))), QString(QLatin1String(g_format_size_full(disk.bused, G_FORMAT_SIZE_DEFAULT))), QString::number(disk.percentage).append("%"));
}
// for (DiskInfo *info : m_diskModel->diskInfoList()) {
// }
}
}
}
g_free(entries);
}
void FileSystemWorker::removeDiskItem(const QString &devname)
{
m_diskModel->removeDiskInfo(devname);
}

View File

@ -0,0 +1,27 @@
#ifndef FILESYSTEMWORKER_H
#define FILESYSTEMWORKER_H
#include <QObject>
#include "diskinfo.h"
#include "diskmodel.h"
class FileSystemWorker : public QObject
{
Q_OBJECT
public:
explicit FileSystemWorker(DiskModel *diskList, QObject *parent = 0);
void removeDiskItem(const QString &devname);
public slots:
void onFileSystemListChanged();
void removeUserByName(const QString &name);
private:
DiskModel *m_diskModel;
};
#endif // FILESYSTEMWORKER_H

View File

@ -0,0 +1,85 @@
#include "myaction.h"
#include <QWidget>
MyAction::MyAction (QObject * parent, const char * name, bool autoadd)
: QAction(parent)
{
setObjectName(name);
if (autoadd) addActionToParent();
}
MyAction::MyAction(QObject * parent, bool autoadd)
: QAction(parent)
{
if (autoadd) addActionToParent();
}
MyAction::MyAction(const QString & text, QKeySequence accel,
QObject * parent, const char * name, bool autoadd )
: QAction(parent)
{
setObjectName(name);
setText(text);
setShortcut(accel);
if (autoadd) addActionToParent();
}
MyAction::MyAction(QKeySequence accel, QObject * parent, const char * name,
bool autoadd )
: QAction(parent)
{
setObjectName(name);
setShortcut(accel);
if (autoadd) addActionToParent();
}
MyAction::~MyAction() {
}
void MyAction::addShortcut(QKeySequence key) {
setShortcuts( shortcuts() << key);
}
void MyAction::addActionToParent() {
if (parent()) {
if (parent()->inherits("QWidget")) {
QWidget *w = static_cast<QWidget*> (parent());
w->addAction(this);
}
}
}
void MyAction::change(const QIcon & icon, const QString & text) {
setIcon( icon );
change(text);
}
void MyAction::change(const QString & text ) {
setText( text );
QString accel_text = shortcut().toString();
QString s = text;
s.replace("&","");
if (!accel_text.isEmpty()) {
setToolTip( s + " ("+ accel_text +")");
setIconText( s );
}
/*
if (text.isEmpty()) {
QString s = menuText;
s = s.replace("&","");
setText( s );
if (!accel_text.isEmpty())
setToolTip( s + " ("+ accel_text +")");
} else {
setText( text );
if (!accel_text.isEmpty())
setToolTip( text + " ("+ accel_text +")");
}
*/
}

View File

@ -0,0 +1,31 @@
#ifndef _MYACTION_H_
#define _MYACTION_H_
#include <QAction>
#include <QString>
#include <QIcon>
#include <QKeySequence>
class MyAction : public QAction
{
public:
MyAction (QObject * parent, const char * name, bool autoadd = true );
MyAction (QObject * parent, bool autoadd = true );
MyAction (const QString & text, QKeySequence accel,
QObject * parent, const char * name = "",
bool autoadd = true );
MyAction (QKeySequence accel, QObject * parent,
const char * name = "", bool autoadd = true );
~MyAction();
void addShortcut(QKeySequence key);
void change(const QIcon & icon, const QString & text );
void change(const QString & text);
protected:
void addActionToParent();
};
#endif

View File

@ -0,0 +1,68 @@
#include "myactiongroup.h"
#include <QAction>
#include <QList>
#include <QWidget>
MyActionGroup::MyActionGroup( QObject * parent ) : QActionGroup(parent)
{
setExclusive(true);
connect(this, SIGNAL(triggered(QAction *)), this, SLOT(itemTriggered(QAction *)) );
}
void MyActionGroup::setChecked(int ID) {
QList <QAction *> l = actions();
for (int n=0; n < l.count(); n++) {
if ( (!l[n]->isSeparator()) && (l[n]->data().toInt() == ID) ) {
l[n]->setChecked(true);
return;
}
}
}
int MyActionGroup::checked() {
QAction * a = checkedAction();
if (a)
return a->data().toInt();
else
return -1;
}
void MyActionGroup::uncheckAll() {
QList <QAction *> l = actions();
for (int n=0; n < l.count(); n++) {
l[n]->setChecked(false);
}
}
void MyActionGroup::setActionsEnabled(bool b) {
QList <QAction *> l = actions();
for (int n=0; n < l.count(); n++) {
l[n]->setEnabled(b);
}
}
void MyActionGroup::clear(bool remove) {
while (actions().count() > 0) {
QAction * a = actions()[0];
if (a) {
removeAction(a);
if (remove) a->deleteLater();
}
}
}
void MyActionGroup::itemTriggered(QAction *a) {
int value = a->data().toInt();
emit activated(value);
}
void MyActionGroup::addTo(QWidget *w) {
w->addActions( actions() );
}
void MyActionGroup::removeFrom(QWidget *w) {
for (int n=0; n < actions().count(); n++) {
w->removeAction( actions()[n] );
}
}

View File

@ -0,0 +1,30 @@
#ifndef _MYACTIONGROUP_H_
#define _MYACTIONGROUP_H_
#include <QActionGroup>
#include <QWidget>
#include "myaction.h"
class MyActionGroup : public QActionGroup
{
Q_OBJECT
public:
MyActionGroup ( QObject * parent );
void setChecked(int ID);
int checked();
void clear(bool remove);
void setActionsEnabled(bool);
void addTo(QWidget *);
void removeFrom(QWidget *);
void uncheckAll();
signals:
void activated(int);
protected slots:
void itemTriggered(QAction *);
};
#endif

View File

@ -0,0 +1,13 @@
#include "myactiongroupitem.h"
#include "myactiongroup.h"
MyActionGroupItem::MyActionGroupItem(QObject * parent, MyActionGroup *group,
const char * name,
int data, bool autoadd)
: MyAction(parent, name, autoadd)
{
setData(data);
setCheckable(true);
if (group) group->addAction(this);
}

View File

@ -0,0 +1,17 @@
#ifndef _MYACTIONGROUPITEM_H_
#define _MYACTIONGROUPITEM_H_
#include "myaction.h"
#include <QObject>
class MyActionGroup;
class MyActionGroupItem : public MyAction
{
public:
MyActionGroupItem( QObject * parent, MyActionGroup *group,
const char * name, int data, bool autoadd = true );
};
#endif // _MYACTIONGROUPITEM_H_

View File

@ -0,0 +1,337 @@
#include "mydialog.h"
#include "myimagebutton.h"
#include <QLabel>
#include <QButtonGroup>
#include <QDebug>
#include <QCloseEvent>
#include <QApplication>
#include <QDesktopWidget>
#include <QScreen>
#include <QAction>
#include <QPushButton>
#include <QAbstractButton>
#include <QPainter>
MyDialog::MyDialog(const QString &title, const QString &message, QWidget *parent) :
QDialog(parent)
{
this->setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint | Qt::WindowCloseButtonHint);
this->setAttribute(Qt::WA_TranslucentBackground);
// this->setAttribute(Qt::WA_DeleteOnClose, false);
this->setAttribute(Qt::WA_Resized, false);
topLayout = new QHBoxLayout;
topLayout->setContentsMargins(20, 14, 20, 14);
topLayout->setSpacing(20);
titleLabel = new QLabel;
titleLabel->setStyleSheet("QLabel{padding-top: 2px;padding-bottom: 2px;font-size: 12px;color: #000000;}");
titleLabel->hide();
titleLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
messageLabel = new QLabel;
messageLabel->setStyleSheet("QLabel{padding-top: 2px;padding-bottom: 2px;font-size: 11px;color: #444444;}");
messageLabel->hide();
messageLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
QVBoxLayout *textLayout = new QVBoxLayout;
textLayout->setContentsMargins(0, 0, 0, 0);
textLayout->setSpacing(5);
textLayout->addStretch();
textLayout->addWidget(titleLabel, 0, Qt::AlignLeft);
textLayout->addWidget(messageLabel, 0, Qt::AlignLeft);
textLayout->addStretch();
contentLayout = new QVBoxLayout;
contentLayout->setContentsMargins(0, 0, 0, 0);
contentLayout->setSpacing(0);
contentLayout->addLayout(textLayout);
topLayout->addLayout(contentLayout);
closeButton = new MyImageButton(this);
closeButton->setObjectName("CloseButton");
// closeButton->setNormalPic(":/res/tool/close_normal.png");
// closeButton->setHoverPic(":/res/tool/close_hover.png");
// closeButton->setPressPic(":/res/tool/close_press.png");
connect(closeButton, &MyImageButton::clicked, this, [=] {
this->close();
});
closeButton->setAttribute(Qt::WA_NoMousePropagation);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setSpacing(0);
mainLayout->addWidget(closeButton, 0, Qt::AlignTop | Qt::AlignRight);
mainLayout->addLayout(topLayout);
buttonLayout = new QHBoxLayout;
buttonLayout->setMargin(0);
buttonLayout->setSpacing(0);
buttonLayout->setContentsMargins(20, 14, 20, 14);
mainLayout->addLayout(buttonLayout);
QAction *button_action = new QAction(this);
button_action->setShortcuts(QKeySequence::InsertParagraphSeparator);
button_action->setAutoRepeat(false);
QObject::connect(button_action, SIGNAL(triggered(bool)), this, SLOT(onDefaultButtonTriggered()));
this->setLayout(mainLayout);
this->addAction(button_action);
this->setFocusPolicy(Qt::ClickFocus);
this->setFocus();
setTitle(title);
setMessage(message);
this->moveToCenter();
}
MyDialog::~MyDialog()
{
this->clearButtons();
}
void MyDialog::updateSize()
{
if (!this->testAttribute(Qt::WA_Resized)) {
QSize size = this->sizeHint();
size.setWidth(qMax(size.width(), 440));
size.setHeight(qMax(size.height(), 200));
this->resize(size);
this->setAttribute(Qt::WA_Resized, false);
}
}
void MyDialog::onButtonClicked()
{
QAbstractButton *button = qobject_cast<QAbstractButton*>(this->sender());
if(button) {
clickedButtonIndex = buttonList.indexOf(button);
emit this->buttonClicked(clickedButtonIndex, button->text());
this->done(clickedButtonIndex);//cancel:0 ok:1
}
}
void MyDialog::onDefaultButtonTriggered()
{
QAbstractButton *button = qobject_cast<QAbstractButton*>(this->focusWidget());
if (button)
button->click();
else if (defaultButton)
defaultButton->click();
}
int MyDialog::buttonCount() const
{
return this->buttonList.count();
}
int MyDialog::addButton(const QString &text, bool isDefault/*, ButtonType type*/)
{
int index = buttonCount();
QAbstractButton *button = new QPushButton(text);
button->setStyleSheet("QPushButton{font-size:12px;background:#ffffff;border:1px solid #bebebe;color:#000000;}QPushButton:hover{background-color:#ffffff;border:1px solid #3f96e4;color:#000000;}QPushButton:pressed{background-color:#ffffff;border:1px solid #3f96e4;color:#000000;}");
button->setAttribute(Qt::WA_NoMousePropagation);
button->setFixedHeight(24);
QLabel* label = new QLabel;
label->setStyleSheet("QLabel{background-color:rgba(0, 0, 0, 0.1);}");
label->setFixedWidth(1);
label->hide();
if(index > 0 && index >= buttonCount()) {
QLabel *label = qobject_cast<QLabel*>(this->buttonLayout->itemAt(this->buttonLayout->count() - 1)->widget());
if(label)
label->show();
}
this->buttonLayout->insertWidget(index * 2, button);
this->buttonList << button;
this->buttonLayout->insertWidget(index * 2 + 1, label);
connect(button, SIGNAL(clicked(bool)), this, SLOT(onButtonClicked()));
if(isDefault) {
setDefaultButton(button);
}
return index;
}
void MyDialog::clearButtons()
{
this->buttonList.clear();
while(this->buttonLayout->count()) {
QLayoutItem *item = this->buttonLayout->takeAt(0);
item->widget()->deleteLater();
delete item;
}
}
void MyDialog::setDefaultButton(QAbstractButton *button)
{
this->defaultButton = button;
}
void MyDialog::setTitle(const QString &title)
{
if (this->m_title == title)
return;
this->m_title = title;
this->titleLabel->setText(title);
this->titleLabel->setHidden(title.isEmpty());
}
void MyDialog::setMessage(const QString &message)
{
if (this->m_message == message)
return;
this->m_message = message;
this->messageLabel->setText(message);
this->messageLabel->setHidden(message.isEmpty());
}
int MyDialog::exec()
{
this->clickedButtonIndex = -1;
int code = QDialog::exec();
return this->clickedButtonIndex >= 0 ? this->clickedButtonIndex : code;
}
void MyDialog::showEvent(QShowEvent *event)
{
QDialog::showEvent(event);
setAttribute(Qt::WA_Resized, false);
this->updateSize();
}
void MyDialog::hideEvent(QHideEvent *event)
{
QDialog::hideEvent(event);
done(-1);
}
void MyDialog::childEvent(QChildEvent *event)
{
QDialog::childEvent(event);
if (event->added()) {
if (this->closeButton) {
this->closeButton->raise();
}
}
}
QRect MyDialog::getParentGeometry() const
{
if (this->parentWidget()) {
return this->parentWidget()->window()->geometry();
} else {
QPoint pos = QCursor::pos();
for (QScreen *screen : qApp->screens()) {
if (screen->geometry().contains(pos)) {
return screen->geometry();
}
}
}
return qApp->primaryScreen()->geometry();
}
void MyDialog::moveToCenter()
{
QRect qr = geometry();
qr.moveCenter(this->getParentGeometry().center());
move(qr.topLeft());
}
void MyDialog::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
this->dragPosition = event->globalPos() - frameGeometry().topLeft();
this->mousePressed = true;
}
QDialog::mousePressEvent(event);
}
void MyDialog::mouseReleaseEvent(QMouseEvent *event)
{
this->mousePressed = false;
QDialog::mouseReleaseEvent(event);
}
void MyDialog::mouseMoveEvent(QMouseEvent *event)
{
if (this->mousePressed) {
move(event->globalPos() - this->dragPosition);
}
QDialog::mouseMoveEvent(event);
}
void MyDialog::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
//绘制圆角矩形
painter.setPen(QPen(QColor("#0d87ca"), 0));//边框颜色 QColor(255, 255, 255, 153)
painter.setBrush(QColor("#e9eef0"));//背景色 #0d87ca
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setOpacity(1);
QRectF r(0 / 2.0, 0 / 2.0, width() - 0, height() - 0);//左边 上边 右边 下边
painter.drawRoundedRect(r, 4, 4);
//绘制背景色
// QPainterPath path;
// path.addRect(QRectF(rect()));
// painter.setOpacity(1);
// painter.fillPath(path, QColor("#ffffff"));
QDialog::paintEvent(event);
}
void MyDialog::resizeEvent(QResizeEvent *event)
{
QDialog::resizeEvent(event);
this->titleLabel->setWordWrap(false);
int labelMaxWidth = maximumWidth() - this->closeButton->width() - this->titleLabel->x();
if (this->titleLabel->sizeHint().width() > labelMaxWidth) {
this->titleLabel->setFixedWidth(labelMaxWidth);
this->titleLabel->setWordWrap(true);
this->titleLabel->setFixedHeight(this->titleLabel->sizeHint().height());
}
this->messageLabel->setWordWrap(false);
labelMaxWidth = maximumWidth() - this->closeButton->width() - this->messageLabel->x();
if (this->messageLabel->sizeHint().width() > labelMaxWidth) {
this->messageLabel->setFixedWidth(labelMaxWidth);
this->messageLabel->setWordWrap(true);
this->messageLabel->setFixedHeight(this->messageLabel->sizeHint().height());
}
}

View File

@ -0,0 +1,77 @@
#ifndef MYDIALOG_H
#define MYDIALOG_H
#include <QIcon>
#include <QDialog>
#include <QPointer>
#include <QAbstractButton>
class QAbstractButton;
class QButtonGroup;
class QLabel;
class QCloseEvent;
class QVBoxLayout;
class MyImageButton;
#include <QBoxLayout>
class MyDialog : public QDialog
{
Q_OBJECT
public:
explicit MyDialog(const QString &title, const QString& message, QWidget *parent = 0);
~MyDialog();
int buttonCount() const;
QRect getParentGeometry() const;
void moveToCenter();
signals:
void buttonClicked(int index, const QString &text);
public slots:
int addButton(const QString &text, bool isDefault = false);
void clearButtons();
void setDefaultButton(QAbstractButton *button);
void setTitle(const QString &title);
void setMessage(const QString& message);
int exec() Q_DECL_OVERRIDE;
public slots:
void onButtonClicked();
void onDefaultButtonTriggered();
protected:
void showEvent(QShowEvent *event) Q_DECL_OVERRIDE;
void hideEvent(QHideEvent *event) Q_DECL_OVERRIDE;
void childEvent(QChildEvent *event) Q_DECL_OVERRIDE;
void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
private:
QString m_title;
QString m_message;
QLabel* messageLabel;
QLabel* titleLabel;
MyImageButton* closeButton = nullptr;
QHBoxLayout *iconLayout;
QVBoxLayout *contentLayout;
QHBoxLayout *buttonLayout;
QHBoxLayout *topLayout;
QList<QAbstractButton*> buttonList;
QList<QWidget*> contentList;
QPointer<QAbstractButton> defaultButton;
int clickedButtonIndex;
void updateSize();
QPoint dragPosition;
bool mousePressed;
};
#endif // MYDIALOG_H

View File

@ -0,0 +1,165 @@
#include "myimagebutton.h"
#include <QMouseEvent>
#include <QEvent>
MyImageButton::MyImageButton(QWidget *parent)
: QLabel(parent)
{
setCheckable(false);//setCheckable(true);
updateIcon();
}
MyImageButton::~MyImageButton()
{
}
void MyImageButton::enterEvent(QEvent *event)
{
setCursor(Qt::PointingHandCursor);
if (!m_isChecked){
setState(Hover);
}
event->accept();
//QLabel::enterEvent(event);
}
void MyImageButton::leaveEvent(QEvent *event)
{
if (!m_isChecked){
setState(Normal);
}
event->accept();
//QLabel::leaveEvent(event);
}
void MyImageButton::mousePressEvent(QMouseEvent *event)
{
if (event->button() != Qt::LeftButton)
return;
setState(Press);
event->accept();
//QLabel::mousePressEvent(event);
}
void MyImageButton::mouseReleaseEvent(QMouseEvent *event)
{
if (!rect().contains(event->pos()))
return;
if (m_isCheckable){
m_isChecked = !m_isChecked;
if (m_isChecked){
setState(Checked);
} else {
setState(Normal);
}
} else {
setState(Hover);
}
event->accept();
//QLabel::mouseReleaseEvent(event);
if (event->button() == Qt::LeftButton)
emit clicked();
}
void MyImageButton::mouseMoveEvent(QMouseEvent *event)
{
if (!m_isCheckable && !rect().contains(event->pos())) {
setState(Normal);
}
}
void MyImageButton::updateIcon()
{
switch (m_state) {
case Hover: if (!m_hoverPic.isEmpty()) setPixmap(QPixmap(m_hoverPic)); break;
case Press: if (!m_pressPic.isEmpty()) setPixmap(QPixmap(m_pressPic)); break;
case Checked: if (!m_checkedPic.isEmpty()) setPixmap(QPixmap(m_checkedPic)); break;
default: if (!m_normalPic.isEmpty()) setPixmap(QPixmap(m_normalPic)); break;
}
setAlignment(Qt::AlignCenter);
emit stateChanged();
}
void MyImageButton::setState(MyImageButton::ButtonState state)
{
if (m_state == state)
return;
m_state = state;
updateIcon();
}
void MyImageButton::setCheckable(bool flag)
{
m_isCheckable = flag;
if (!m_isCheckable){
setState(Normal);
}
}
void MyImageButton::setChecked(bool flag)
{
if (m_isCheckable == false){
return;
}
m_isChecked = flag;
if (m_isChecked){
setState(Checked);
} else {
setState(Normal);
}
}
bool MyImageButton::isChecked()
{
return m_isChecked;
}
bool MyImageButton::isCheckable()
{
return m_isCheckable;
}
void MyImageButton::setNormalPic(const QString &normalPicPixmap)
{
m_normalPic = normalPicPixmap;
updateIcon();
}
void MyImageButton::setHoverPic(const QString &hoverPicPixmap)
{
m_hoverPic = hoverPicPixmap;
updateIcon();
}
void MyImageButton::setPressPic(const QString &pressPicPixmap)
{
m_pressPic = pressPicPixmap;
updateIcon();
}
void MyImageButton::setCheckedPic(const QString &checkedPicPixmap)
{
m_checkedPic = checkedPicPixmap;
updateIcon();
}
MyImageButton::ButtonState MyImageButton::getButtonState() const
{
return m_state;
}

View File

@ -0,0 +1,66 @@
#ifndef MYIMAGEBUTTON_H
#define MYIMAGEBUTTON_H
#include <QObject>
#include <QWidget>
#include <QLabel>
#include <QPixmap>
class MyImageButton : public QLabel
{
Q_OBJECT
Q_PROPERTY(QString normalPic READ getNormalPic WRITE setNormalPic DESIGNABLE true)
Q_PROPERTY(QString hoverPic READ getHoverPic WRITE setHoverPic DESIGNABLE true)
Q_PROPERTY(QString pressPic READ getPressPic WRITE setPressPic DESIGNABLE true)
Q_PROPERTY(QString checkedPic READ getCheckedPic WRITE setCheckedPic DESIGNABLE true)
public:
MyImageButton(QWidget * parent=0);
~MyImageButton();
void setChecked(bool flag);
void setCheckable(bool flag);
bool isChecked();
bool isCheckable();
void setNormalPic(const QString & normalPic);
void setHoverPic(const QString & hoverPic);
void setPressPic(const QString & pressPic);
void setCheckedPic(const QString & checkedPic);
inline const QString getNormalPic() const {return m_normalPic;}
inline const QString getHoverPic() const {return m_hoverPic;}
inline const QString getPressPic() const {return m_pressPic;}
inline const QString getCheckedPic() const {return m_checkedPic;}
enum ButtonState {Normal, Hover, Press, Checked};
ButtonState getButtonState() const;
signals:
void clicked();
void stateChanged();
protected:
void enterEvent(QEvent * event) Q_DECL_OVERRIDE;
void leaveEvent(QEvent * event) Q_DECL_OVERRIDE;
void mousePressEvent(QMouseEvent * event) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QMouseEvent * event) Q_DECL_OVERRIDE;
void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
private:
void updateIcon();
void setState(ButtonState state);
private:
ButtonState m_state = Normal;
bool m_isChecked = false;
bool m_isCheckable = false;
QString m_normalPic;
QString m_hoverPic;
QString m_pressPic;
QString m_checkedPic;
};
#endif // MYIMAGEBUTTON_H

View File

@ -0,0 +1,155 @@
#include "mysearchedit.h"
#include <QHBoxLayout>
#include <QSpacerItem>
#include <QPropertyAnimation>
#include <QDebug>
#include <QEvent>
#include <QFocusEvent>
#include <QResizeEvent>
#include <QTimer>
MySearchEdit::MySearchEdit(QWidget *parent)
: QFrame(parent)
{
this->setStyleSheet("QFrame{border-radius: 4px;}");
initInsideFrame();
m_searchBtn = new QLabel;
m_searchBtn->setStyleSheet("QLabel{background-color:transparent;margin: 2 -1 2 4 px;border-image:url(:/res/search.png);}");
m_searchBtn->setFixedSize(16, 16);
m_clearBtn = new MyImageButton;
m_clearBtn->setObjectName("ClearIcon");
m_clearBtn->hide();
m_edit = new QLineEdit;
m_edit->setStyleSheet("QLineEdit{background-color:transparent;border-radius:0px;color:#303030;padding-right:15px;padding-bottom: 3px;}");
m_animation = new QPropertyAnimation(m_edit, "minimumWidth");
m_size = QSize(m_searchBtn->sizeHint().width() + m_edit->sizeHint().width() + m_clearBtn->sizeHint().width() + 6,
qMax(m_searchBtn->sizeHint().height(), m_edit->sizeHint().height()));
m_edit->setFixedWidth(0);
m_edit->installEventFilter(this);
QHBoxLayout *layout = new QHBoxLayout(m_insideFrame);
layout->addStretch();
layout->addWidget(m_searchBtn);
layout->setAlignment(m_searchBtn, Qt::AlignCenter);
layout->addWidget(m_edit);
layout->setAlignment(m_edit, Qt::AlignCenter);
layout->addStretch();
layout->addWidget(m_clearBtn);
layout->setAlignment(m_clearBtn, Qt::AlignCenter);
layout->setSpacing(0);
layout->setContentsMargins(3, 0, 3, 0);
setAutoFillBackground(true);
setFocusPolicy(Qt::StrongFocus);
connect(m_clearBtn, &MyImageButton::clicked, m_edit, static_cast<void (QLineEdit::*)()>(&QLineEdit::setFocus));
connect(m_clearBtn, &MyImageButton::clicked, this, &MySearchEdit::clear);
connect(m_edit, &QLineEdit::textChanged, [this] {m_clearBtn->setVisible(!m_edit->text().isEmpty());});
connect(m_edit, &QLineEdit::textChanged, this, &MySearchEdit::textChanged, Qt::DirectConnection);
connect(m_edit, &QLineEdit::editingFinished, this, &MySearchEdit::editingFinished, Qt::DirectConnection);
connect(m_edit, &QLineEdit::returnPressed, this, &MySearchEdit::returnPressed, Qt::DirectConnection);
}
MySearchEdit::~MySearchEdit()
{
m_animation->deleteLater();
}
const QString MySearchEdit::text() const
{
return m_edit->text();
}
void MySearchEdit::mousePressEvent(QMouseEvent *e)
{
if (e->button() != Qt::LeftButton)
return QFrame::mousePressEvent(e);
toEditMode();
e->accept();
}
void MySearchEdit::mouseReleaseEvent(QMouseEvent *e)
{
e->accept();
}
bool MySearchEdit::eventFilter(QObject *o, QEvent *e)
{
if (o == m_edit && e->type() == QEvent::FocusOut && m_edit->text().isEmpty()) {
auto fe = dynamic_cast<QFocusEvent *>(e);
if (fe && fe->reason() != Qt::PopupFocusReason) {
m_animation->stop();
m_animation->setStartValue(m_edit->width());
m_animation->setEndValue(0);
m_animation->setEasingCurve(m_hideCurve);
m_animation->start();
}
}
if (o == m_edit) {
if (e->type() == QEvent::FocusOut) {
emit focusOut();
}
if (e->type() == QEvent::FocusIn) {
emit focusIn();
}
}
return QFrame::eventFilter(o, e);
}
QLineEdit *MySearchEdit::getLineEdit() const
{
return m_edit;
}
void MySearchEdit::toEditMode()
{
m_animation->stop();
m_animation->setStartValue(0);
m_animation->setEndValue(m_size.width() - m_searchBtn->width() - 6);
m_animation->setEasingCurve(m_showCurve);
m_animation->start();
m_edit->setFocus();
}
void MySearchEdit::initInsideFrame()
{
m_insideFrame = new QFrame(this);
m_insideFrame->raise();
m_insideFrame->setStyleSheet("QFrame{background-color: white;border: 1px solid;border-radius: 4px;border-color: rgba(0, 0, 0, 0.08);}");
QHBoxLayout *insideLayout = new QHBoxLayout(this);
insideLayout->setContentsMargins(0, 0, 0, 1);
insideLayout->setSpacing(0);
insideLayout->addWidget(m_insideFrame);
}
void MySearchEdit::resizeEvent(QResizeEvent *e)
{
m_size = e->size();
m_edit->setFixedHeight(m_size.height());
}
bool MySearchEdit::event(QEvent *e)
{
if (e->type() == QEvent::FocusIn) {
const QFocusEvent *event = static_cast<QFocusEvent*>(e);
if (event->reason() == Qt::TabFocusReason
|| event->reason() == Qt::BacktabFocusReason
|| event->reason() == Qt::OtherFocusReason
|| event->reason() == Qt::ShortcutFocusReason) {
toEditMode();
}
}
return QFrame::event(e);
}

View File

@ -0,0 +1,62 @@
#ifndef MYSEARCHEDIT_H
#define MYSEARCHEDIT_H
#include <QFrame>
#include <QSize>
#include <QLineEdit>
#include <QPropertyAnimation>
#include <QLabel>
#include "myimagebutton.h"
class MySearchEdit : public QFrame
{
Q_OBJECT
public:
explicit MySearchEdit(QWidget *parent = 0);
~MySearchEdit();
void initInsideFrame();
QSize sizeHint() const {return m_size;}
QSize minimumSizeHint() const {return m_size;}
const QString text() const;
void mousePressEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
bool eventFilter(QObject *o, QEvent *e);
inline void setAniDuration(const int duration) {m_animation->setDuration(duration);}
inline void setAniShowCurve(const QEasingCurve curve) {m_showCurve = curve;}
inline void setAniHideCurve(const QEasingCurve curve) {m_hideCurve = curve;}
QLineEdit *getLineEdit() const;
public slots:
void toEditMode();
void setText(const QString & text) {if (m_edit) m_edit->setText(text);}
inline void clear() {m_edit->clear();}
signals:
void textChanged();
void returnPressed();
void editingFinished();
void focusOut();
void focusIn();
protected:
void resizeEvent(QResizeEvent *e);
bool event(QEvent *e);
private:
QSize m_size;
QLineEdit *m_edit;
QLabel *m_searchBtn;
MyImageButton *m_clearBtn;
QFrame *m_insideFrame = NULL;
QPropertyAnimation *m_animation;
QEasingCurve m_showCurve = QEasingCurve::OutCubic;
QEasingCurve m_hideCurve = QEasingCurve::InCubic;
};
#endif // MYSEARCHEDIT_H

View File

@ -0,0 +1,72 @@
#include "mytipimagebutton.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QDebug>
#include <QHBoxLayout>
#include <QTimer>
#include <QHelpEvent>
MyTipImageButton::MyTipImageButton(QWidget *parent)
: MyImageButton(parent)
{
}
bool MyTipImageButton::event(QEvent *e)
{
if (e->type() == QEvent::ToolTip) {
if (QHelpEvent *he = static_cast<QHelpEvent *>(e)) {
showTooltip(he->globalPos());
return false;
}
}
else if (e->type() == QEvent::Leave) {
emit mouseLeave();
MyImageButton::leaveEvent(e);
}
else if (e->type() == QEvent::MouseButtonPress) {
emit mouseLeave();
}
return MyImageButton::event(e);
}
void MyTipImageButton::enterEvent(QEvent *e)
{
if (isEnabled()) {
MyImageButton::enterEvent(e);
}
}
void MyTipImageButton::showTooltip(const QPoint &gPos)
{
if (toolTip().trimmed().isEmpty()) {
return;
}
QFrame *tf = new QFrame();
tf->setStyleSheet(this->styleSheet());
tf->setWindowFlags(Qt::ToolTip);
tf->setAttribute(Qt::WA_TranslucentBackground);
QLabel *tl = new QLabel(tf);
tl->setObjectName("TooltipLabel");
tl->setText(toolTip());
QHBoxLayout *layout = new QHBoxLayout(tf);
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(tl);
tf->show();
QRect dr = qApp->desktop()->geometry();
int y = gPos.y() + tf->height();
if (y > dr.y() + dr.height()) {
y = gPos.y() - tf->height() - 10;
}
tf->move(gPos.x() - tf->width()/3, y - tf->height()/3);
QTimer::singleShot(5000, tf, SLOT(deleteLater()));
connect(this, &MyTipImageButton::mouseLeave, tf, &QFrame::deleteLater);
}

View File

@ -0,0 +1,27 @@
#ifndef MYTIPIMAGEBUTTON_H
#define MYTIPIMAGEBUTTON_H
#include <QEvent>
#include <QLabel>
#include "myimagebutton.h"
class MyTipImageButton : public MyImageButton
{
Q_OBJECT
public:
explicit MyTipImageButton(QWidget *parent = 0);
signals:
void mouseLeave();
protected:
void enterEvent(QEvent *e) Q_DECL_OVERRIDE;
bool event(QEvent *e) Q_DECL_OVERRIDE;
private:
void showTooltip(const QPoint &gPos);
};
#endif // MYTIPIMAGEBUTTON_H

View File

@ -0,0 +1,79 @@
#include "processcategory.h"
#include "myimagebutton.h"
ProcessCategory::ProcessCategory(int tabIndex, QWidget *parent)
: QWidget(parent)
,width(26)
,height(26)
,activeIndex(tabIndex)
{
setFixedSize(width * 3, height);
layout = new QHBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
activeProcessButton = new MyImageButton(this);
activeProcessButton->setCheckable(true);
activeProcessButton->setObjectName("ActiveProcessBtn");
userProcessButton = new MyImageButton(this);
userProcessButton->setCheckable(true);
userProcessButton->setObjectName("UserProcessBtn");
allProcessButton = new MyImageButton(this);
allProcessButton->setCheckable(true);
allProcessButton->setObjectName("AllProcessBtn");
if (activeIndex == 0) {
activeProcessButton->setChecked(true);
userProcessButton->setChecked(false);
allProcessButton->setChecked(false);
}
else if (activeIndex == 2) {
activeProcessButton->setChecked(false);
userProcessButton->setChecked(false);
allProcessButton->setChecked(true);
}
else {
activeProcessButton->setChecked(false);
userProcessButton->setChecked(true);
allProcessButton->setChecked(false);
}
connect(activeProcessButton, &MyImageButton::clicked, this, [=] {
activeIndex = 0;
emit this->activeWhoseProcessList(activeIndex);
activeProcessButton->setChecked(true);
userProcessButton->setChecked(false);
allProcessButton->setChecked(false);
});
connect(userProcessButton, &MyImageButton::clicked, this, [=] {
activeIndex = 1;
emit this->activeWhoseProcessList(activeIndex);
activeProcessButton->setChecked(false);
userProcessButton->setChecked(true);
allProcessButton->setChecked(false);
});
connect(allProcessButton, &MyImageButton::clicked, this, [=] {
activeIndex = 2;
emit this->activeWhoseProcessList(activeIndex);
activeProcessButton->setChecked(false);
userProcessButton->setChecked(false);
allProcessButton->setChecked(true);
});
layout->addWidget(activeProcessButton);
layout->addWidget(userProcessButton);
layout->addWidget(allProcessButton);
this->setLayout(layout);
}
ProcessCategory::~ProcessCategory()
{
delete activeProcessButton;
delete userProcessButton;
delete allProcessButton;
delete layout;
}

View File

@ -0,0 +1,30 @@
#ifndef PROCESSCATEGORY_H
#define PROCESSCATEGORY_H
#include <QWidget>
#include <QHBoxLayout>
class MyImageButton;
class ProcessCategory : public QWidget
{
Q_OBJECT
public:
explicit ProcessCategory(int tabIndex, QWidget *parent = 0);
~ProcessCategory();
signals:
void activeWhoseProcessList(int index);
private:
int width;
int height;
int activeIndex;
QHBoxLayout *layout;
MyImageButton *activeProcessButton;
MyImageButton *userProcessButton;
MyImageButton *allProcessButton;
};
#endif // PROCESSCATEGORY_H

View File

@ -0,0 +1,36 @@
#ifndef PROCESSDATA_H
#define PROCESSDATA_H
#include <QObject>
#include <QString>
#include <QMap>
#include <QSharedPointer>
class ProcData
{
public:
pid_t pid;
uint cpu;
long m_memory;
long m_nice;
QPixmap iconPixmap;
QString processName;
QString displayName;
QString commandLine;
QString path;
QString user;
QString m_status;
QString m_session;
QString cpu_duration_time;
};
typedef QSharedPointer<ProcData> ProcDataPtr;
typedef QList<ProcDataPtr> ProcDataPtrList;
Q_DECLARE_METATYPE(ProcData)
Q_DECLARE_METATYPE(ProcDataPtr)
Q_DECLARE_METATYPE(ProcDataPtrList)
#endif // PROCESSDATA_H

View File

@ -0,0 +1,868 @@
/*
* Copyright (C) 2013 ~ 2015 National University of Defense Technology(NUDT) & Kylin Ltd.
*
* Authors:
* Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "processdialog.h"
#include "propertiesdialog.h"
#include "processdata.h"
#include "util.h"
#include <QStringList>
#include <QCloseEvent>
#include <QBitmap>
#include <QPainter>
#include <QFileDialog>
#include <QDir>
#include <QDebug>
#include <QHeaderView>
#include <QDesktopServices>
#include <QApplication>
#include <QDebug>
#include <QDir>
#include <QList>
#include <QProcess>
#include <QStyleFactory>
#include <QToolTip>
#include <unistd.h>
#include <systemd/sd-login.h>
#include <set>
#include <list>
#include <glibtop.h>
#include <glibtop/proclist.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gprintf.h>
#include <glibtop/procstate.h>
#include <glibtop/procmem.h>
#include <glibtop/procmap.h>
#include <glibtop/proctime.h>
#include <glibtop/procuid.h>
#include <glibtop/procargs.h>
#include <glibtop/prockernel.h>
#include <glibtop/sysinfo.h>
#include <pwd.h>
#include <glibtop/mem.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/resource.h> //for setpriority
using std::string;
QDataStream &operator<<(QDataStream &dataStream, const ProcDataPtr &object)
{
auto ptr = object.data();
auto ptrval = reinterpret_cast<qulonglong>(ptr);
auto var = QVariant::fromValue(ptrval);
dataStream << var;
return dataStream;
}
QDataStream &operator>>(QDataStream &dataStream, ProcDataPtr &object)
{
QVariant var;
dataStream >> var;
qulonglong ptrval = var.toULongLong();
auto ptr = reinterpret_cast<ProcData *>(ptrval);
object = ProcDataPtr(ptr);
return dataStream;
}
ProcessDialog::ProcessDialog(QList<bool> columnShowOrHideFlags, int sortIndex, bool sortOrder, QSettings *settings, QWidget *parent)
:QWidget(parent)
,num_cpus(0)
,frequency(0U)
,proSettings(settings)
{
setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred);
setAcceptDrops(true);
setAttribute(Qt::WA_NoMousePropagation);
this->setObjectName("ProcessDialog");
qRegisterMetaType<ProcDataPtr>();
qRegisterMetaTypeStreamOperators<ProcDataPtr>();
qRegisterMetaType<ProcDataPtrList>();
qRegisterMetaType<QList<ProcData>>();
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
m_processListWidget = new ProcessListWidget(columnShowOrHideFlags);
connect(m_processListWidget, SIGNAL(changeColumnVisible(int,bool,QList<bool>)), this, SIGNAL(changeColumnVisible(int,bool,QList<bool>)));
connect(m_processListWidget, SIGNAL(changeSortStatus(int,bool)), this, SIGNAL(changeSortStatus(int,bool)));
layout->addWidget(m_processListWidget);
whose_processes = "user";
proSettings->beginGroup("PROCESS");
whose_processes = proSettings->value("WhoseProcesses", whose_processes).toString();
proSettings->endGroup();
int tabIndex = 1;
if (whose_processes == "active") {
tabIndex = 0;
}
else if (whose_processes == "all") {
tabIndex = 2;
}
else {
tabIndex = 1;
}
QList<SortFunction> *sortFuncList = new QList<SortFunction>();
sortFuncList->append(&ProcessListItem::sortByName);
sortFuncList->append(&ProcessListItem::sortByUser);
sortFuncList->append(&ProcessListItem::sortByStatus);
sortFuncList->append(&ProcessListItem::sortByCPU);
sortFuncList->append(&ProcessListItem::sortByPid);
sortFuncList->append(&ProcessListItem::sortByCommand);
sortFuncList->append(&ProcessListItem::sortByMemory);
sortFuncList->append(&ProcessListItem::sortByPriority);
m_processListWidget->setColumnSortingAlgorithms(sortFuncList, sortIndex, sortOrder);
m_processListWidget->setSearchFunction(&ProcessListItem::doSearch);
endProcessDialog = new MyDialog(QString(tr("End process")), QString(tr("Ending a process may destroy data, break the session or introduce a security risk. Only unresponsive processes should be ended.\nAre you sure to continue?")));
endProcessDialog->setWindowFlags(endProcessDialog->windowFlags() | Qt::WindowStaysOnTopHint);
endProcessDialog->addButton(QString(tr("Cancel")), false);
endProcessDialog->addButton(QString(tr("End process")), true);
connect(endProcessDialog, &MyDialog::buttonClicked, this, &ProcessDialog::endDialogButtonClicked);
killProcessDialog = new MyDialog(QString(tr("Kill process")), QString(tr("Killing a process may destroy data, break the session or introduce a security risk. Only unresponsive processes should be killed.\nAre you sure to continue?")));
killProcessDialog->setWindowFlags(killProcessDialog->windowFlags() | Qt::WindowStaysOnTopHint);
killProcessDialog->addButton(QString(tr("Cancel")), false);
killProcessDialog->addButton(QString(tr("Kill process")), true);
connect(killProcessDialog, &MyDialog::buttonClicked, this, &ProcessDialog::killDialogButtonClicked);
actionPids = new QList<pid_t>();
m_menu = new QMenu();
m_stopAction = new QAction(tr("Stop process"), this);
connect(m_stopAction, &QAction::triggered, this, &ProcessDialog::stopProcesses);
m_continueAction = new QAction(tr("Continue process"), this);
connect(m_continueAction, &QAction::triggered, this, &ProcessDialog::continueProcesses);
m_endAction = new QAction(tr("End process"), this);
connect(m_endAction, &QAction::triggered, this, &ProcessDialog::showEndProcessDialog);
m_killAction = new QAction(tr("Kill process"), this);
connect(m_killAction, &QAction::triggered, this, &ProcessDialog::showKillProcessDialog);
priorityGroup = new MyActionGroup(this);
veryHighAction = new MyActionGroupItem(this, priorityGroup, "very_high_action", -20);
highAction = new MyActionGroupItem(this, priorityGroup, "high_action", -5);
normalAction = new MyActionGroupItem(this, priorityGroup, "normal_action", 0);
lowAction = new MyActionGroupItem(this, priorityGroup, "low_action", 5);
veryLowAction = new MyActionGroupItem(this, priorityGroup, "very_low_action", 19);
customAction = new MyActionGroupItem(this, priorityGroup, "custom_action", 32);
{
QAction *sep = new QAction(priorityGroup);
sep->setSeparator(true);
}
veryHighAction->change(tr("Very High"));
highAction->change(tr("High"));
normalAction->change(tr("Normal"));
lowAction->change(tr("Low"));
veryLowAction->change(tr("Very Low"));
customAction->change(tr("Custom"));
connect(priorityGroup, SIGNAL(activated(int)), this, SLOT(changeProcPriority(int)));
m_priorityMenu = new QMenu();
m_priorityMenu->addActions(priorityGroup->actions());
m_priorityMenu->menuAction()->setText(tr("Change Priority"));
m_propertiyAction = new QAction(tr("Properties"), this);
connect(m_propertiyAction, &QAction::triggered, this, &ProcessDialog::showPropertiesDialog);
m_menu->addAction(m_stopAction);//停止
m_menu->addAction(m_continueAction);//继续进程
m_menu->addAction(m_endAction);//结束
m_menu->addAction(m_killAction);//杀死
m_menu->addSeparator();
m_menu->addMenu(m_priorityMenu);
m_menu->addSeparator();
m_menu->addAction(m_propertiyAction);
connect(m_processListWidget, &ProcessListWidget::rightBtnClickedItems, this, &ProcessDialog::popupMenu, Qt::QueuedConnection);
glibtop_init();
this->num_cpus = glibtop_get_sysinfo()->ncpu;
this->refreshProcessList();
timer = new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(refreshProcessList()));
timer->start(3000);
}
ProcessDialog::~ProcessDialog()
{
glibtop_close();
this->clearOriginProcList();
if (timer != NULL) {
disconnect(timer,SIGNAL(timeout()),this,SLOT(refreshProcessList()));
if(timer->isActive()) {
timer->stop();
}
delete timer;
timer = NULL;
}
delete endProcessDialog;
delete killProcessDialog;
delete m_processListWidget;
delete m_stopAction;
delete m_continueAction;
delete m_endAction;
delete m_killAction;
delete veryHighAction;
delete highAction;
delete normalAction;
delete lowAction;
delete veryLowAction;
delete customAction;
delete m_priorityMenu;
delete m_propertiyAction;
delete m_menu;
delete actionPids;
}
void ProcessDialog::displayAllProcess()
{
timer->stop();
this->clearOriginProcList();
whose_processes = "all";
this->refreshProcessList();
timer->start(3000);
}
void ProcessDialog::displayActiveProcess()
{
timer->stop();
this->clearOriginProcList();
whose_processes = "active";
this->refreshProcessList();
timer->start(3000);
}
void ProcessDialog::displayCurrentUserProcess()
{
timer->stop();
this->clearOriginProcList();
whose_processes = "user";
this->refreshProcessList();
timer->start(3000);
}
void ProcessDialog::onActiveWhoseProcess(int index)
{
if (index == 0) {
if (this->whose_processes != "active")
this->displayActiveProcess();
} else if (index == 1) {
if (this->whose_processes != "user")
this->displayCurrentUserProcess();
} else {
if (this->whose_processes != "all")
this->displayAllProcess();
}
proSettings->beginGroup("PROCESS");
proSettings->setValue("WhoseProcesses", whose_processes);
proSettings->endGroup();
proSettings->sync();
}
void ProcessDialog::clearOriginProcList()
{
for (ProcessWorker::Iterator it(ProcessWorker::begin()); it != ProcessWorker::end(); ++it)
delete it->second;
ProcessWorker::all.clear();
}
void ProcessDialog::changeProcPriority(int nice)
{
if (nice == 32) {
//show renice dialog
}
else {
pid_t cur_pid = -1;
for (pid_t pid : *actionPids) {
cur_pid = pid;
qDebug() << "******************"<<cur_pid;
break;
}
if (cur_pid > -1) {
ProcessWorker *info = ProcessWorker::find(cur_pid);
if (!info) {
actionPids->clear();
return;
}
if (info->nice == nice) {
actionPids->clear();
return;
}
int saved_errno;
int error = setpriority(PRIO_PROCESS, cur_pid, nice);
//success
if(error != -1) {
actionPids->clear();
return;
}
saved_errno = errno;
//need to be root
if(errno == EPERM || errno == EACCES) {
qDebug() << "Change priority need to be root!!!";
bool success = false;
QString command = QString("renice %1 %1").arg(nice).arg(cur_pid);
QFile file("/usr/bin/pkexec");
if(file.exists()) {
gint *exit_status = NULL;
GError *error = NULL;
QString cmd = QString("pkexec --disable-internal-agent /usr/lib/gnome-system-monitor/gnome-system-monitor/gsm-%1").arg(command);//gsm-renice
qDebug() << "cmd="<<cmd;
// if (!g_spawn_command_line_sync(command_line, NULL, NULL, exit_status, &error)) {
// g_critical("Could not run pkexec(\"%s\") : %s\n",
// command, error->message);
// g_error_free(error);
// }
// else
// {
// g_debug("pkexec did fine\n");
// ret = TRUE;
// }
}
else {
qDebug() << "change to root failed......";
}
/*gboolean success;
success = procdialog_create_root_password_dialog (
PROCMAN_ACTION_RENICE, args->app, info->pid,
nice);
if(success) return;
if(errno) {
saved_errno = errno;
}*/
// static char *
// procman_action_to_command(ProcmanActionType type,
// gint pid,
// gint extra_value)
// {
// switch (type) {
// case PROCMAN_ACTION_KILL:
// return g_strdup_printf("kill -s %d %d", extra_value, pid);
// case PROCMAN_ACTION_RENICE:
// return g_strdup_printf("renice %d %d", extra_value, pid);
// default:
// g_assert_not_reached();
// }
// }
// gboolean procdialog_create_root_password_dialog(ProcmanActionType type,
// GsmApplication *app,
// gint pid,
// gint nice)
// {
// char * command;
// gboolean ret = FALSE;
// command = g_strdup_printf("renice %d %d", nice, pid);
// //command = procman_action_to_command(type, pid, nice);
// procman_debug("Trying to run '%s' as root", command);
// if (g_file_test("/usr/bin/pkexec", G_FILE_TEST_EXISTS)) {
// gboolean ret = FALSE;
// gint *exit_status = NULL;
// GError *error = NULL;
// gchar *command_line = g_strdup_printf("pkexec --disable-internal-agent %s/gsm-%s",
// GSM_LIBEXEC_DIR, command);
// if (!g_spawn_command_line_sync(command_line, NULL, NULL, exit_status, &error)) {
// g_critical("Could not run pkexec(\"%s\") : %s\n",
// command, error->message);
// g_error_free(error);
// }
// else
// {
// g_debug("pkexec did fine\n");
// ret = TRUE;
// }
// g_free (command_line);
// return ret;
// }
// if (procman_has_pkexec())
// ret = gsm_pkexec_create_root_password_dialog(command);
// else if (procman_has_gksu())
// ret = gsm_gksu_create_root_password_dialog(command);
// else if (procman_has_gnomesu())
// ret = gsm_gnomesu_create_root_password_dialog(command);
// g_free(command);
// return ret;
// }
}
}
}
actionPids->clear();
// static void
// renice_scale_changed (GtkAdjustment *adj, gpointer data)
// {
// GtkWidget *label = GTK_WIDGET (data);
// new_nice_value = int(gtk_adjustment_get_value (adj));
// gchar* text = g_strdup(procman::get_nice_level_with_priority (new_nice_value));
// gtk_label_set_text (GTK_LABEL (label), text);
// g_free(text);
// }
// static void
// renice_dialog_button_pressed (GtkDialog *dialog, gint id, gpointer data)
// {
// GsmApplication *app = static_cast<GsmApplication *>(data);
// if (id == 100) {
// if (new_nice_value == -100)
// return;
// renice(app, new_nice_value);
// }
// gtk_widget_destroy (GTK_WIDGET (dialog));
// renice_dialog = NULL;
// }
//renice_scale_changed
//renice_dialog_button_pressed
}
//void ProcessDialog::onCloseButtonClicked()
//{
// this->close();
//}
//void ProcessDialog::closeEvent(QCloseEvent *event)
//{
// event->accept();
//}
void ProcessDialog::refreshProcessList()
{
pid_t* pid_list;
glibtop_proclist proclist;
glibtop_cpu cpu;
int which = 0;
int arg = 0;
if (whose_processes == "all") {
which = GLIBTOP_KERN_PROC_ALL;
arg = 0;
} else if (whose_processes == "active") {
which = GLIBTOP_KERN_PROC_ALL | GLIBTOP_EXCLUDE_IDLE;
arg = 0;
} else if (whose_processes == "user") {
which = GLIBTOP_KERN_PROC_UID;
arg = getuid();
}
pid_list = glibtop_get_proclist(&proclist, which, arg);
/* FIXME: total cpu time elapsed should be calculated on an individual basis here
** should probably have a total_time_last gint in the ProcInfo structure */
glibtop_get_cpu(&cpu);
this->frequency = cpu.frequency;
this->cpu_total_time = MAX(cpu.total - this->cpu_total_time_last, 1);
this->cpu_total_time_last = cpu.total;
// FIXME: not sure if glibtop always returns a sorted list of pid
// but it is important otherwise refresh_list won't find the parent
std::sort(pid_list, pid_list + proclist.number);
// qDebug() << "proclist.number="<<proclist.number;
//---------------start----------------------
typedef std::list<ProcessWorker*> ProcList;
ProcList addition;
guint i;
for(i = 0; i < proclist.number; ++i) {
ProcessWorker *info = ProcessWorker::find(pid_list[i]);
if (!info) {//不存在时创建该进程的对象
info = new ProcessWorker(pid_list[i], this->num_cpus, this->cpu_total_time);
ProcessWorker::all[info->pid] = info;
}
//当进程对象存在时,更新该进程对象的相关数据信息
glibtop_proc_state procstate;
glibtop_proc_uid procuid;
glibtop_proc_time proctime;
glibtop_get_proc_state (&procstate, info->pid);
info->status = procstate.state;
glibtop_get_proc_uid (&procuid, info->pid);
glibtop_get_proc_time (&proctime, info->pid);
glibtop_proc_mem procmem;
glibtop_get_proc_mem(&procmem, info->pid);
info->mem = procmem.resident - procmem.share;
glibtop_get_proc_state(&procstate, info->pid);
info->status = procstate.state;
info->set_user(procstate.uid);
guint64 difference = proctime.rtime - info->cpu_time;
if (difference > 0)
info->status = GLIBTOP_PROCESS_RUNNING;
info->pcpu = difference * 100 / this->cpu_total_time;
info->pcpu = MIN(info->pcpu, 100);
//CPU 百分比使用 Solaris 模式工作在“Solaris 模式”,其中任务的 CPU 使用量将被除以总的 CPU 数目。否则它将工作在“Irix 模式”。
info->pcpu *= this->num_cpus;
info->frequency = this->frequency;
ProcessWorker::cpu_times[info->pid] = info->cpu_time = proctime.rtime;
info->nice = procuid.nice;
}
// Remove dead processes from the process list and from the
// tree. children are queued to be readded at the right place
// in the tree.
const std::set<pid_t> pids(pid_list, pid_list + proclist.number);
ProcessWorker::Iterator it(ProcessWorker::begin());
while (it != ProcessWorker::end()) {
ProcessWorker * const info = it->second;
ProcessWorker::Iterator next(it);
++next;
if (pids.find(info->pid) == pids.end()) {
// qDebug() << "ripping ====" << info->pid;
addition.remove(info);
ProcessWorker::all.erase(it);
delete info;
}
it = next;
}
QList<ProcessListItem*> items;
for (ProcessWorker::Iterator it(ProcessWorker::begin()); it != ProcessWorker::end(); ++it) {
//qDebug() <<"it->second->pid="<< it->second->pid;
QString username = QString::fromStdString(it->second->user);
//qDebug() << "username=" << username;
long nice = it->second->nice;
// QString session = "c2";
QString name = QString::fromStdString(it->second->name);
// qDebug() << "pcpu="<<it->second->pcpu;
// qDebug() << "mem="<<it->second->mem;
QString session;
if (it->second->session) {
session = QString(it->second->session);
}
QString status = formatProcessState(it->second->status);
// qDebug() <<"status="<<it->second->status;
// qDebug() <<"name================"<<name;
uint cpu = it->second->pcpu;
long memory = it->second->mem;
pid_t pid = it->second->pid;
// if (pid == 16280) {
// qDebug() << "--------------------------"<<name << it->second->pid << "===" << it->second->uid;
// }
// if (pid == 6924) {
// qDebug() << "--------------------------"<<name << it->second->mem;
// }
/*---------------------kobe test string---------------------
//QString to std:string
QString test_QString = "lixiang";
std::string test_string = test_QString.toStdString();
//std::string to QString
QString result = QString::fromStdString(test_string)
QString::fromStdString(test_QString.toStdString());
----------------------------------------------------------*/
std::string desktopFile;
desktopFile = getDesktopFileFromName(pid, name, "");
// qDebug() << "****************"<< QString::fromStdString(desktopFile);
QPixmap icon_pixmap;
int iconSize = 24 * qApp->devicePixelRatio();
QPixmap defaultPixmap = QIcon::fromTheme("application-x-executable").pixmap(iconSize, iconSize);
if (desktopFile.size() == 0) {
icon_pixmap = defaultPixmap;
icon_pixmap.setDevicePixelRatio(qApp->devicePixelRatio());
} else {
icon_pixmap = getDesktopFileIcon(desktopFile, 24);
if (icon_pixmap.isNull()) {
icon_pixmap = defaultPixmap;
icon_pixmap.setDevicePixelRatio(qApp->devicePixelRatio());
}
//QPixmap pixmap = QPixmap::fromImage(img).scaled(iconSize, iconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
QString title = getDisplayNameFromName(name, desktopFile);
QString displayName;
if (whose_processes == "all") {
displayName = QString("[%1] %2").arg(username).arg(title);
} else {
displayName = title;
}
ProcData info;
// info.pidt = it->second->pid;
info.user = username;
info.iconPixmap = icon_pixmap;
info.displayName = displayName;
info.cpu = cpu;
info.m_memory = memory;
info.pid = pid;
info.m_status = status;
info.m_nice = nice;
info.m_session = session;
info.cpu_duration_time = formatDurationForDisplay(100 * it->second->cpu_time / this->frequency);
info.processName = QString::fromStdString(it->second->name);
info.commandLine = QString::fromStdString(it->second->arguments);
ProcessListItem *item = new ProcessListItem(info);
items << item;
}
this->updateStatus(items);
g_free (pid_list);
//---------------end----------------------
}
ProcessListWidget* ProcessDialog::getProcessView()
{
return m_processListWidget;
}
void ProcessDialog::endDialogButtonClicked(int index, QString)
{
if (index == 1) {//cancel:0 ok:1
endProcesses();
}
}
void ProcessDialog::killDialogButtonClicked(int index, QString)
{
if (index == 1) {//cancel:0 ok:1
killProcesses();
}
}
void ProcessDialog::focusProcessView()
{
QTimer::singleShot(100, m_processListWidget, SLOT(setFocus()));
}
void ProcessDialog::onSearch(QString text)
{
m_processListWidget->doSearch(text);
}
//杀死
void ProcessDialog::killProcesses()
{
int error;
// int saved_errno;
for (pid_t pid : *actionPids) {
// Resume process first, otherwise kill process too slow.
kill(pid, SIGCONT);
// if (kill(pid, SIGKILL) != 0) {
// qDebug() << QString("Kill process %1 failed, permission denied.").arg(pid);
// }
error = kill(pid, SIGKILL);
if(error != -1) {
qDebug() << "success.....";
}
else {
//need to be root
if(errno == EPERM) {
qDebug() << QString("Kill process %1 failed, permission denied.").arg(pid);
/*gboolean success;
success = procdialog_create_root_password_dialog (
PROCMAN_ACTION_KILL, args->app, info->pid,
args->arg_value);
if(success) {
actionPids->clear();
return;
}
if(errno) {
saved_errno = errno;
}*/
}
}
}
actionPids->clear();
}
//结束
void ProcessDialog::endProcesses()
{
int error;
// int saved_errno;
for (pid_t pid : *actionPids) {
// if (kill(pid, SIGTERM) != 0) {
// qDebug() << QString("Kill process %1 failed, permission denied.").arg(pid);
// }
error = kill(pid, SIGTERM);
if(error != -1) {
qDebug() << "success.....";
}
else {
//need to be root
if(errno == EPERM) {
qDebug() << QString("End process %1 failed, permission denied.").arg(pid);
/*gboolean success;
success = procdialog_create_root_password_dialog (
PROCMAN_ACTION_KILL, args->app, info->pid,
args->arg_value);
if(success) {
actionPids->clear();
return;
}
if(errno) {
saved_errno = errno;
}*/
}
}
}
actionPids->clear();
}
void ProcessDialog::popupMenu(QPoint pos, QList<ProcessListItem*> items)
{
actionPids->clear();
int count = 0;
pid_t cur_pid = -1;
for (ProcessListItem *item : items) {
count ++;
ProcessListItem *procItem = static_cast<ProcessListItem*>(item);
cur_pid = procItem->getPid();
// qDebug() << "HAHAHAH===========" << cur_pid;
actionPids->append(cur_pid);
}
if (count == 1) {
ProcessWorker *info = ProcessWorker::find(cur_pid);
if (!info) {
priorityGroup->setActionsEnabled(false);
}
else {
priorityGroup->setActionsEnabled(true);
gint nice = info->nice;
int priority;
if (nice < -7)
priority = -20;
else if (nice < -2)
priority = -5;
else if (nice < 3)
priority = 0;
else if (nice < 7)
priority = 5;
else
priority = 19;
priorityGroup->setChecked(priority);
}
}
else {
priorityGroup->setActionsEnabled(false);
}
m_menu->exec(pos);
}
void ProcessDialog::continueProcesses()
{
for (pid_t pid : *actionPids) {
if (kill(pid, SIGCONT) != 0) {
qDebug() << QString("Resume process %1 failed, permission denied.").arg(pid);
}
}
actionPids->clear();
}
void ProcessDialog::showPropertiesDialog()
{
for (pid_t pid : *actionPids) {
foreach (QWidget *widget, QApplication::topLevelWidgets()) {
// Show attribute dialog if it has create, avoid create attribute dialog duplicate.
if (qobject_cast<const PropertiesDialog*>(widget) != 0) {
PropertiesDialog *dialog = qobject_cast<PropertiesDialog*>(widget);
if (dialog->getPid() == pid) {
dialog->show();
actionPids->clear();
return;
}
}
}
PropertiesDialog *dialog = new PropertiesDialog(this, pid);
dialog->show();
}
actionPids->clear();
}
void ProcessDialog::showKillProcessDialog()
{
killProcessDialog->exec();
}
void ProcessDialog::showEndProcessDialog()
{
endProcessDialog->exec();
}
//停止
void ProcessDialog::stopProcesses()
{
pid_t currentPid = getpid();
for (pid_t pid : *actionPids) {
if (pid != currentPid) {
if (kill(pid, SIGSTOP) != 0) {
qDebug() << QString("Stop process %1 failed, permission denied.").arg(pid);
}
}
}
actionPids->clear();
}
void ProcessDialog::updateStatus(QList<ProcessListItem*> items)
{
m_processListWidget->refreshItems(items);
}

View File

@ -0,0 +1,110 @@
/*
* Copyright (C) 2013 ~ 2015 National University of Defense Technology(NUDT) & Kylin Ltd.
*
* Authors:
* Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "processworker.h"
#include "../../component/utils.h"
#include "mydialog.h"
#include "processlistitem.h"
#include "myactiongroup.h"
#include "myactiongroupitem.h"
#include "myaction.h"
#include "processlistwidget.h"
#include <QLabel>
#include <QMap>
#include <QMenu>
#include <QPixmap>
#include <QString>
#include <QWidget>
#include <QDialog>
#include <QTimer>
#include <QDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QTableWidget>
#include <QDebug>
#include <QHeaderView>
#include <QSettings>
class ProcessManager;
class ProcessDialog : public QWidget
{
Q_OBJECT
public:
explicit ProcessDialog(QList<bool> columnShowOrHideFlags, int sortIndex, bool sortOrder, QSettings *settings, QWidget* parent = 0);
~ProcessDialog();
ProcessListWidget* getProcessView();
void displayAllProcess();
void displayActiveProcess();
void displayCurrentUserProcess();
void clearOriginProcList();
signals:
void changeColumnVisible(int index, bool visible, QList<bool> columnVisible);
void changeSortStatus(int index, bool sortOrder);
public slots:
void focusProcessView();
void onSearch(QString text);
void stopProcesses();
void continueProcesses();
void endProcesses();
void killProcesses();
void popupMenu(QPoint pos, QList<ProcessListItem*> items);
void showPropertiesDialog();
void showEndProcessDialog();
void showKillProcessDialog();
void endDialogButtonClicked(int index, QString buttonText);
void killDialogButtonClicked(int index, QString buttonText);
void updateStatus(QList<ProcessListItem*> items);
void onActiveWhoseProcess(int index);
void changeProcPriority(int nice);
void refreshProcessList();
private:
QTimer *timer;
QSettings *proSettings;
guint64 cpu_total_time;
guint64 cpu_total_time_last;
MyDialog *killProcessDialog;
MyDialog *endProcessDialog;
ProcessListWidget *m_processListWidget;
QAction *m_propertiyAction;
QAction *m_stopAction;//停止
QAction *m_continueAction;//继续进程
QAction *m_endAction;//结束
QAction *m_killAction;//杀死
QMenu *m_priorityMenu;
MyActionGroup * priorityGroup;
MyAction *veryHighAction;
MyAction *highAction;
MyAction *normalAction;
MyAction *lowAction;
MyAction *veryLowAction;
MyAction *customAction;
QList<pid_t> *actionPids;
QMenu *m_menu;
QString whose_processes;
gint num_cpus;
unsigned frequency;
};

View File

@ -0,0 +1,334 @@
#include "processlistitem.h"
#include <QCollator>
#include <QDebug>
#include <QLocale>
#include "util.h"
ProcessListItem::ProcessListItem(ProcData info)
{
m_data = info;
iconSize = 24;
padding = 14;
textPadding = 5;
}
bool ProcessListItem::isSameItem(ProcessListItem *item)
{
return m_data.pid == ((static_cast<ProcessListItem*>(item)))->m_data.pid;
}
void ProcessListItem::drawBackground(QRect rect, QPainter *painter, int index, bool isSelect)
{
QPainterPath path;
path.addRect(QRectF(rect));
if (isSelect) {
painter->setOpacity(1.0);
painter->fillPath(path, QColor("#3f96e4"));
}
else {
painter->setOpacity(0.02);
if (index % 2 == 0) {
painter->fillPath(path, QColor("#000000"));
} else {
painter->fillPath(path, QColor("#e9eef0"));
}
}
}
void ProcessListItem::drawForeground(QRect rect, QPainter *painter, int column, int, bool isSelect)
{
setFontSize(*painter, 9);
painter->setOpacity(1);
if (isSelect) {
// //this->setToolTip();//kobe neet to draw tooltip
painter->setPen(QPen(QColor("#ffffff")));
} else {
painter->setPen(QPen(QColor("#000000")));
}
// Draw icon and process's name
if (column == 0) {
painter->drawPixmap(QRect(rect.x() + padding, rect.y() + (rect.height() - iconSize) / 2, iconSize, iconSize), m_data.iconPixmap);
QString name = m_data.processName;
if (m_data.m_status == tr("Stopped")) {//已停止
painter->setPen(QPen(QColor("#FA7053")));
name = QString("(%1) %2").arg(tr("Suspend")).arg(m_data.processName);
}
else if (m_data.m_status == tr("Zombie")) {//僵死
painter->setPen(QPen(QColor("#808080")));
name = QString("(%1) %2").arg(tr("No response")).arg(m_data.processName);
}
else if (m_data.m_status == tr("Uninterruptible")) {//不可中断
painter->setPen(QPen(QColor("#A52A2A")));
name = QString("(%1) %2").arg(tr("Uninterruptible")).arg(m_data.processName);
}
else {//Sleeping 睡眠中 Running 运行中
}
int nameMaxWidth = rect.width() - iconSize - padding * 3;
QFont font = painter->font();
QFontMetrics fm(font);
QString procName = fm.elidedText(name, Qt::ElideRight, nameMaxWidth);
painter->drawText(QRect(rect.x() + iconSize + padding * 2, rect.y(), nameMaxWidth, rect.height()), Qt::AlignLeft | Qt::AlignVCenter, procName);
}
// Draw User.
else if (column == 1) {
if (!m_data.user.isEmpty()) {
painter->drawText(QRect(rect.x(), rect.y(), rect.width() - textPadding, rect.height()), Qt::AlignCenter, m_data.user);
}
}
// Draw Status.
else if (column == 2) {
if (!m_data.m_status.isEmpty()) {
painter->drawText(QRect(rect.x(), rect.y(), rect.width() - textPadding, rect.height()), Qt::AlignCenter, m_data.m_status);
}
}
// Draw CPU.
else if (column == 3) {
painter->drawText(QRect(rect.x(), rect.y(), rect.width() - textPadding, rect.height()), Qt::AlignCenter, QString("%1%").arg(m_data.cpu));
}
// Draw pid.
else if (column == 4) {
painter->drawText(QRect(rect.x(), rect.y(), rect.width() - padding, rect.height()), Qt::AlignCenter, QString("%1").arg(m_data.pid));
}
// Draw Command.
else if (column == 5) {
int commandMaxWidth = rect.width();
QFont font = painter->font();
QFontMetrics fm(font);
QString command = fm.elidedText(m_data.commandLine, Qt::ElideRight, commandMaxWidth);
painter->drawText(QRect(rect.x(), rect.y(), commandMaxWidth, rect.height()), Qt::AlignLeft | Qt::AlignVCenter, command);
}
// Draw memory.
else if (column == 6) {
if (m_data.m_memory > 0) {
QString memory = QString(g_format_size_full(m_data.m_memory, G_FORMAT_SIZE_IEC_UNITS));
painter->drawText(QRect(rect.x(), rect.y(), rect.width() - textPadding, rect.height()), Qt::AlignCenter, memory);
}
}
// Draw Priority.
else if (column == 7) {
painter->drawText(QRect(rect.x(), rect.y(), rect.width() - textPadding, rect.height()), Qt::AlignLeft | Qt::AlignVCenter, getNiceLevel(m_data.m_nice));
}
}
bool ProcessListItem::doSearch(const ProcessListItem *item, QString text)
{
const ProcessListItem *procItem = static_cast<const ProcessListItem*>(item);
QString content = text.toLower();
return procItem->getProcessName().toLower().contains(content) || QString::number(procItem->getPid()).contains(content) || procItem->getDisplayName().toLower().contains(content) || procItem->getUser().toLower().contains(content);
}
bool ProcessListItem::sortByName(const ProcessListItem *item1, const ProcessListItem *item2, bool descendingSort)
{
QString name1 = (static_cast<const ProcessListItem*>(item1))->getDisplayName();
QString name2 = (static_cast<const ProcessListItem*>(item2))->getDisplayName();
bool sortOrder;
// Sort item with cpu if name is same.
if (name1 == name2) {
double cpu1 = static_cast<const ProcessListItem*>(item1)->getCPU();
double cpu2 = (static_cast<const ProcessListItem*>(item2))->getCPU();
sortOrder = cpu1 > cpu2;
}
// Otherwise sort by name.
else {
QCollator qco(QLocale::system());
int result = qco.compare(name1, name2);
sortOrder = result < 0;
}
return descendingSort ? sortOrder : !sortOrder;
}
bool ProcessListItem::sortByUser(const ProcessListItem *item1, const ProcessListItem *item2, bool descendingSort)
{
QString user1 = (static_cast<const ProcessListItem*>(item1))->getUser();
QString user2 = (static_cast<const ProcessListItem*>(item2))->getUser();
bool sortOrder;
// Sort item with cpu if user is same.
if (user1 == user2) {
double cpu1 = static_cast<const ProcessListItem*>(item1)->getCPU();
double cpu2 = (static_cast<const ProcessListItem*>(item2))->getCPU();
sortOrder = cpu1 > cpu2;
}
// Otherwise sort by user.
else {
QCollator qco(QLocale::system());
int result = qco.compare(user1, user2);
sortOrder = result < 0;
}
return descendingSort ? sortOrder : !sortOrder;
}
bool ProcessListItem::sortByStatus(const ProcessListItem *item1, const ProcessListItem *item2, bool descendingSort)
{
QString status1 = (static_cast<const ProcessListItem*>(item1))->getStatus();
QString status2 = (static_cast<const ProcessListItem*>(item2))->getStatus();
bool sortOrder;
// Sort item with cpu if status is same.
if (status1 == status2) {
double cpu1 = static_cast<const ProcessListItem*>(item1)->getCPU();
double cpu2 = (static_cast<const ProcessListItem*>(item2))->getCPU();
sortOrder = cpu1 > cpu2;
}
// Otherwise sort by status.
else {
QCollator qco(QLocale::system());
int result = qco.compare(status1, status2);
sortOrder = result < 0;
}
return descendingSort ? sortOrder : !sortOrder;
}
bool ProcessListItem::sortByCPU(const ProcessListItem *item1, const ProcessListItem *item2, bool descendingSort)
{
double cpu1 = (static_cast<const ProcessListItem*>(item1))->getCPU();
double cpu2 = (static_cast<const ProcessListItem*>(item2))->getCPU();
bool sortOrder;
// Sort item with memory if cpu is same.
if (cpu1 == cpu2) {
long memory1 = static_cast<const ProcessListItem*>(item1)->getMemory();
long memory2 = (static_cast<const ProcessListItem*>(item2))->getMemory();
sortOrder = memory1 > memory2;
}
// Otherwise sort by cpu.
else {
sortOrder = cpu1 > cpu2;
}
return descendingSort ? sortOrder : !sortOrder;
}
bool ProcessListItem::sortByPid(const ProcessListItem *item1, const ProcessListItem *item2, bool descendingSort)
{
bool sortOrder = (static_cast<const ProcessListItem*>(item1))->getPid() > (static_cast<const ProcessListItem*>(item2))->getPid();
return descendingSort ? sortOrder : !sortOrder;
}
bool ProcessListItem::sortByCommand(const ProcessListItem *item1, const ProcessListItem *item2, bool descendingSort)
{
QString command1 = (static_cast<const ProcessListItem*>(item1))->getCommandLine();
QString command2 = (static_cast<const ProcessListItem*>(item2))->getCommandLine();
bool sortOrder;
// Sort item with cpu if command is same.
if (command1 == command2) {
double cpu1 = static_cast<const ProcessListItem*>(item1)->getCPU();
double cpu2 = (static_cast<const ProcessListItem*>(item2))->getCPU();
sortOrder = cpu1 > cpu2;
}
// Otherwise sort by command.
else {
QCollator qco(QLocale::system());
int result = qco.compare(command1, command2);
sortOrder = result < 0;
}
return descendingSort ? sortOrder : !sortOrder;
}
bool ProcessListItem::sortByMemory(const ProcessListItem *item1, const ProcessListItem *item2, bool descendingSort)
{
long memory1 = (static_cast<const ProcessListItem*>(item1))->getMemory();
long memory2 = (static_cast<const ProcessListItem*>(item2))->getMemory();
bool sortOrder;
// Sort item with cpu if memory is same.
if (memory1 == memory2) {
double cpu1 = static_cast<const ProcessListItem*>(item1)->getCPU();
double cpu2 = (static_cast<const ProcessListItem*>(item2))->getCPU();
sortOrder = cpu1 > cpu2;
}
// Otherwise sort by memory.
else {
sortOrder = memory1 > memory2;
}
return descendingSort ? sortOrder : !sortOrder;
}
bool ProcessListItem::sortByPriority(const ProcessListItem *item1, const ProcessListItem *item2, bool descendingSort)
{
long nice1 = (static_cast<const ProcessListItem*>(item1))->getNice();
long nice2 = (static_cast<const ProcessListItem*>(item2))->getNice();
bool sortOrder;
// Sort item with cpu if nice is same.
if (nice1 == nice2) {
double cpu1 = static_cast<const ProcessListItem*>(item1)->getCPU();
double cpu2 = (static_cast<const ProcessListItem*>(item2))->getCPU();
sortOrder = cpu1 > cpu2;
}
// Otherwise sort by nice.
else {
sortOrder = nice1 > nice2;
}
return descendingSort ? sortOrder : !sortOrder;
}
QString ProcessListItem::getProcessName() const
{
return m_data.processName;
}
QString ProcessListItem::getDisplayName() const
{
return m_data.displayName;
}
QString ProcessListItem::getUser() const
{
return m_data.user;
}
QString ProcessListItem::getStatus() const
{
return m_data.m_status;
}
double ProcessListItem::getCPU() const
{
return m_data.cpu;
}
pid_t ProcessListItem::getPid() const
{
return m_data.pid;
}
long ProcessListItem::getMemory() const
{
return m_data.m_memory;
}
long ProcessListItem::getNice() const
{
return m_data.m_nice;
}
QString ProcessListItem::getCommandLine() const
{
return m_data.commandLine;
}

View File

@ -0,0 +1,46 @@
#ifndef PROCESSLISTITEM_H
#define PROCESSLISTITEM_H
#include <QObject>
#include <QPainter>
#include <QPen>
#include "processdata.h"
class ProcessListItem : public QObject
{
Q_OBJECT
public:
ProcessListItem(ProcData info);
bool isSameItem(ProcessListItem *item);
void drawBackground(QRect rect, QPainter *painter, int index, bool isSelect);
void drawForeground(QRect rect, QPainter *painter, int column, int index, bool isSelect);
static bool doSearch(const ProcessListItem *item, QString text);
static bool sortByName(const ProcessListItem *item1, const ProcessListItem *item2, bool descendingSort);
static bool sortByUser(const ProcessListItem *item1, const ProcessListItem *item2, bool descendingSort);
static bool sortByStatus(const ProcessListItem *item1, const ProcessListItem *item2, bool descendingSort);
static bool sortByCPU(const ProcessListItem *item1, const ProcessListItem *item2, bool descendingSort);
static bool sortByPid(const ProcessListItem *item1, const ProcessListItem *item2, bool descendingSort);
static bool sortByCommand(const ProcessListItem *item1, const ProcessListItem *item2, bool descendingSort);
static bool sortByMemory(const ProcessListItem *item1, const ProcessListItem *item2, bool descendingSort);
static bool sortByPriority(const ProcessListItem *item1, const ProcessListItem *item2, bool descendingSort);
QString getProcessName() const;
QString getDisplayName() const;
QString getUser() const;
double getCPU() const;
pid_t getPid() const;
long getMemory() const;
QString getStatus() const;
long getNice() const;
QString getCommandLine() const;
private:
ProcData m_data;
int iconSize;
int padding;
int textPadding;
};
#endif // PROCESSLISTITEM_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,112 @@
#ifndef PROCESSLISTWIDGET_H
#define PROCESSLISTWIDGET_H
#include "processlistitem.h"
#include <QList>
#include <QPixmap>
#include <QTimer>
#include <QWidget>
typedef bool (* SortFunction) (const ProcessListItem *item1, const ProcessListItem *item2, bool sort);
typedef bool (* SearchFunction) (const ProcessListItem *item, QString text);
class ProcessListWidget : public QWidget
{
Q_OBJECT
public:
~ProcessListWidget();
ProcessListWidget(QList<bool> columnShowOrHideFlags, QWidget *parent = 0);
void setColumnSortingAlgorithms(QList<SortFunction> *list, int sortColumn=-1, bool sortOrder=false);
void setSearchFunction(SearchFunction func);
void addItems(QList<ProcessListItem*> items);
void clearItems();
void addSelectedItems(QList<ProcessListItem*> items, bool recordLastSelection=true);
void clearSelectedItems(bool clearTheLast=true);
void refreshItems(QList<ProcessListItem*> items);
void doSearch(QString text);
void selectAllItems();
void selectFirstItem();
void selectLastItem();
void shiftSelectToEnd();
void shiftSelectToHome();
int getItemsTotalHeight();
QList<ProcessListItem*> getSearchedItems(QList<ProcessListItem*> items);
void sortItemsByColumn(int column, bool sortOrder);
void selectPrevItem(int offset);
void selectNextItem(int offset);
void shiftSelectNextItem(int offset);
void shiftSelectPrevItem(int offset);
int getTopOffset();
int getBottomOffset();
int getScrollbarY();
int getScrollbarH();
int getScrollAreaH();
QList<int> getTitleItemsWidths();
void shiftSelectItemsWithBound(int startIndex, int endIndex);
int setOffset(int offset);
void startScrollbarHideTimer();
bool mouseAtScrollArea(int x);
bool mouseAtTitleArea(int y);
signals:
void rightBtnClickedItems(QPoint pos, QList<ProcessListItem*> items);
void changeColumnVisible(int index, bool visible, QList<bool> columnVisible);
void changeSortStatus(int index, bool sortOrder);
public slots:
void hideScrollbar();
protected:
virtual void leaveEvent(QEvent *event);
void keyPressEvent(QKeyEvent *keyEvent);
void mouseMoveEvent(QMouseEvent *mouseEvent);
void mousePressEvent(QMouseEvent *mouseEvent);
void mouseReleaseEvent(QMouseEvent *mouseEvent);
void paintEvent(QPaintEvent *);
void wheelEvent(QWheelEvent *event);
void paintScrollbar(QPainter *painter);
private:
ProcessListItem *lastSelectItem;
QList<ProcessListItem*> *m_listItems;
QList<ProcessListItem*> *m_searchedItems;
QList<ProcessListItem*> *m_selectedItems;
QList<QString> columnTitles;
QList<SortFunction> *m_sortFuncList;
QList<bool> *m_sortOrderes;
QList<int> m_columnWidths;
QList<bool> m_columnVisibles;
QString m_searchText;
QTimer *m_hideScrollbarTimer = nullptr;
SearchFunction m_searchFunc;
bool m_defaultSortOrder;
bool m_mouseAtScrollArea;
bool m_mouseDragScrollbar;
int m_defaultSortColumn;
int m_origOffset;
int m_offSet;
int m_rowHeight;
int m_scrollbarDragW;
int m_scrollbarMinH;
int m_arrowPadding;
int m_titleHeight;
int m_titleHoverColumn;
int m_titlePadding;
int m_titlePressColumn;
QPixmap downArrowHoverPixmap;
QPixmap downArrowNormalPixmap;
QPixmap downArrowPressPixmap;
QPixmap upArrowHoverPixmap;
QPixmap upArrowNormalPixmap;
QPixmap upArrowPressPixmap;
};
#endif // PROCESSLISTWIDGET_H

View File

@ -18,26 +18,16 @@
*/
#include "processmanager.h"
#include <QDebug>
#include <QApplication>
#include <QDesktopWidget>
#include <QStackedLayout>
//ProcessManager::ProcessManager(QObject *parent)
//:QObject(parent), process_dialog(this)
ProcessManager::ProcessManager(QObject *parent)
: QObject(parent)
// ,m_view(new QFrame)
{
/*ProcessDialog *process_dialog = new ProcessDialog;
QStackedLayout *layout = new QStackedLayout;
layout->setSpacing(0);
layout->setMargin(0);
layout->addWidget(process_dialog);
m_view->setLayout(layout);*/
process_dialog = new ProcessDialog;
process_dialog = new SystemMonitor;
}
ProcessManager::~ProcessManager()
@ -72,7 +62,7 @@ void ProcessManager::doAction()
{
int windowWidth = QApplication::desktop()->width();
int windowHeight = QApplication::desktop()->height();
process_dialog->resetSkin();
// process_dialog->resetSkin();
process_dialog->move((windowWidth - 850) / 2,(windowHeight - 476) / 2);
process_dialog->show();
process_dialog->raise();
@ -81,7 +71,6 @@ void ProcessManager::doAction()
QWidget *ProcessManager::centralWidget()
{
// return m_view;
return process_dialog;
}

View File

@ -19,8 +19,8 @@
#include <QObject>
#include <QString>
#include "../component/plugininterface.h"
#include "processdialog.h"
#include "../../component/plugininterface.h"
#include "systemmonitor.h"
//插件入口
class ProcessManager : public QObject , PluginInterface
@ -29,7 +29,7 @@ class ProcessManager : public QObject , PluginInterface
Q_INTERFACES(PluginInterface)
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
Q_PLUGIN_METADATA(IID "com.ubuntukylin.Plugin.PluginInterface" FILE "process.json")//指定IID和.json文件
Q_PLUGIN_METADATA(IID "com.kylin.Plugin.PluginInterface" FILE "systemmonitor.json")//指定IID和.json文件
#endif
public:
@ -37,8 +37,6 @@ public:
virtual ~ProcessManager();
QWidget *centralWidget();
public slots:
public:
virtual QString getGuid();
virtual QString getName();
@ -47,6 +45,5 @@ public:
virtual void doAction();
private:
ProcessDialog *process_dialog = nullptr;
// QWidget *m_view;
SystemMonitor *process_dialog = nullptr;
};

View File

@ -0,0 +1,405 @@
/*
* Copyright (C) 2013 ~ 2015 National University of Defense Technology(NUDT) & Kylin Ltd.
*
* Authors:
* Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "processworker.h"
#include "util.h"
#include <glibtop.h>
#include <glibtop/proclist.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gprintf.h>
#include <glibtop/procstate.h>
#include <glibtop/procmem.h>
#include <glibtop/procmap.h>
#include <glibtop/proctime.h>
#include <glibtop/procuid.h>
#include <glibtop/procargs.h>
#include <glibtop/prockernel.h>
#include <pwd.h>
#include <glibtop/mem.h>
#include <time.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <systemd/sd-login.h>
using std::string;
ProcessWorker::UserMap ProcessWorker::users;
ProcessWorker::List ProcessWorker::all;
std::map<pid_t, guint64> ProcessWorker::cpu_times;
static bool init;
static bool is_running;
static size_t e_strftime(char *s, size_t max, const char *fmt, const struct tm *tm)
{
char *c, *ffmt, *ff;
size_t ret;
ffmt = g_strdup(fmt);
ff = ffmt;
while ((c = strstr(ff, "%l")) != NULL) {
c[1] = 'I';
ff = c;
}
ff = ffmt;
while ((c = strstr(ff, "%k")) != NULL) {
c[1] = 'H';
ff = c;
}
ret = strftime(s, max, ffmt, tm);
g_free(ffmt);
return ret;
}
static size_t e_strftime_fix_am_pm(char *s, size_t max, const char *fmt, const struct tm *tm)
{
char buf[10];
char *sp;
char *ffmt;
size_t ret;
if (strstr(fmt, "%p")==NULL && strstr(fmt, "%P")==NULL) {
/* No AM/PM involved - can use the fmt string directly */
ret=e_strftime(s, max, fmt, tm);
} else {
/* Get the AM/PM symbol from the locale */
e_strftime (buf, 10, "%p", tm);
if (buf[0]) {
/**
* AM/PM have been defined in the locale
* so we can use the fmt string directly
**/
ret=e_strftime(s, max, fmt, tm);
} else {
/**
* No AM/PM defined by locale
* must change to 24 hour clock
**/
ffmt=g_strdup(fmt);
for (sp=ffmt; (sp=strstr(sp, "%l")); sp++) {
/**
* Maybe this should be 'k', but I have never
* seen a 24 clock actually use that format
**/
sp[1]='H';
}
for (sp=ffmt; (sp=strstr(sp, "%I")); sp++) {
sp[1]='H';
}
ret=e_strftime(s, max, ffmt, tm);
g_free(ffmt);
}
}
return(ret);
}
static size_t e_utf8_strftime_fix_am_pm(char *s, size_t max, const char *fmt, const struct tm *tm)
{
size_t sz, ret;
char *locale_fmt, *buf;
locale_fmt = g_locale_from_utf8(fmt, -1, NULL, &sz, NULL);
if (!locale_fmt)
return 0;
ret = e_strftime_fix_am_pm(s, max, locale_fmt, tm);
if (!ret) {
g_free (locale_fmt);
return 0;
}
buf = g_locale_to_utf8(s, ret, NULL, &sz, NULL);
if (!buf) {
g_free (locale_fmt);
return 0;
}
if (sz >= max) {
char *tmp = buf + max - 1;
tmp = g_utf8_find_prev_char(buf, tmp);
if (tmp)
sz = tmp - buf;
else
sz = 0;
}
memcpy(s, buf, sz);
s[sz] = '\0';
g_free(locale_fmt);
g_free(buf);
return sz;
}
static char *format_start_datetime_for_display(time_t date)
{
time_t nowdate = time(NULL);
time_t yesdate;
struct tm then, now, yesterday;
char buf[26];
gboolean done = FALSE;
if (date == 0)
return g_strdup ("?");
localtime_r (&date, &then);
localtime_r (&nowdate, &now);
if (then.tm_mday == now.tm_mday &&
then.tm_mon == now.tm_mon &&
then.tm_year == now.tm_year) {
e_utf8_strftime_fix_am_pm (buf, 26, _("Today %l:%M %p"), &then);
done = TRUE;
}
if (!done) {
yesdate = nowdate - 60 * 60 * 24;
localtime_r (&yesdate, &yesterday);
if (then.tm_mday == yesterday.tm_mday &&
then.tm_mon == yesterday.tm_mon &&
then.tm_year == yesterday.tm_year) {
e_utf8_strftime_fix_am_pm (buf, 26, _("Yesterday %l:%M %p"), &then);
done = TRUE;
}
}
if (!done) {
int i;
for (i = 2; i < 7; i++) {
yesdate = nowdate - 60 * 60 * 24 * i;
localtime_r (&yesdate, &yesterday);
if (then.tm_mday == yesterday.tm_mday &&
then.tm_mon == yesterday.tm_mon &&
then.tm_year == yesterday.tm_year) {
e_utf8_strftime_fix_am_pm (buf, 26, _("%a %l:%M %p"), &then);
done = TRUE;
break;
}
}
}
if (!done) {
if (then.tm_year == now.tm_year) {
e_utf8_strftime_fix_am_pm (buf, 26, _("%b %d %l:%M %p"), &then);
} else {
e_utf8_strftime_fix_am_pm (buf, 26, _("%b %d %Y"), &then);
}
}
return g_strdup (buf);
}
static void get_process_name (ProcessWorker *info, const gchar *cmd, const GStrv args)
{
if (args) {
// look for /usr/bin/very_long_name
// and also /usr/bin/interpreter /usr/.../very_long_name
// which may have use prctl to alter 'cmd' name
for (int i = 0; i != 2 && args[i]; ++i) {
char* basename;
basename = g_path_get_basename(args[i]);
if (g_str_has_prefix(basename, cmd)) {
info->name = basename;
return;
}
g_free(basename);
}
}
info->name = g_strdup(cmd);
}
static void get_process_systemd_info(ProcessWorker *info)
{
// uid_t uid;
if (!init) {
if (access("/run/systemd/seats/", F_OK) >= 0) {
is_running = true;
}
init = true;
}
if (is_running) {
free(info->unit);
info->unit = NULL;
sd_pid_get_unit(info->pid, &info->unit);
free(info->session);
info->session = NULL;
sd_pid_get_session(info->pid, &info->session);
free(info->seat);
info->seat = NULL;
if (info->session != NULL)
sd_session_get_seat(info->session, &info->seat);
// if (sd_pid_get_owner_uid(info->pid, &uid) >= 0)
// info->owner = info->lookup_user(uid);
// else
// info->owner = "";
}
}
ProcessWorker::ProcessWorker(pid_t pid, gint cpus, guint64 cpu_time)
: tooltip(NULL),
name(NULL),
arguments(NULL),
// security_context(NULL),
// cgroup_name(NULL),
unit(NULL),
session(NULL),
seat(NULL),
pid(pid),
uid(-1),
mem(0UL),
status(0U),
pcpu(0U),
nice(0),
num_cpus(cpus),
cpu_total_time(cpu_time),
frequency(0U)
{
this->setProcData();
}
ProcessWorker::~ProcessWorker()
{
g_free(this->name);
g_free(this->tooltip);
g_free(this->arguments);
// g_free(this->security_context);
// g_free(this->cgroup_name);
g_free(this->unit);
g_free(this->session);
g_free(this->seat);
}
void ProcessWorker::setProcData()
{
//init
ProcessWorker * const info = this;
glibtop_proc_state procstate;
glibtop_proc_time proctime;
glibtop_proc_args procargs;
gchar** args;
glibtop_get_proc_state(&procstate, pid);
glibtop_get_proc_time(&proctime, pid);
args = glibtop_get_proc_argv(&procargs, pid, 0);
get_process_name(info, procstate.cmd, static_cast<const GStrv>(args));
std::string tooltip = make_string(g_strjoinv(" ", args));
if (tooltip.empty())
tooltip = procstate.cmd;
info->tooltip = g_markup_escape_text(tooltip.c_str(), -1);
info->arguments = g_strescape(tooltip.c_str(), "\\\"");
g_strfreev(args);
guint64 cpu_time = proctime.rtime;
std::map<pid_t, guint64>::iterator it(ProcessWorker::cpu_times.find(pid));
if (it != ProcessWorker::cpu_times.end())
{
if (proctime.rtime >= it->second)
cpu_time = it->second;
}
info->cpu_time = cpu_time;
info->start_time = proctime.start_time;
// get_process_selinux_context (info);
// info->cgroup_name = NULL;
// get_process_cgroup_info(info);
info->unit = info->session = info->seat = NULL;
get_process_systemd_info(info);
/*
// glibtop_proc_state procstate;
glibtop_proc_uid procuid;
// glibtop_proc_time proctime;
// glibtop_get_proc_state (&procstate, pid);
// info->status = procstate.state;
glibtop_get_proc_uid (&procuid, pid);
// glibtop_get_proc_time (&proctime, pid);
glibtop_proc_mem procmem;
glibtop_get_proc_mem(&procmem, pid);
info->mem = procmem.resident - procmem.share;
glibtop_get_proc_state (&procstate, pid);
info->status = procstate.state;
this->set_user(procstate.uid);
guint64 difference = proctime.rtime - info->cpu_time;
if (difference > 0)
info->status = GLIBTOP_PROCESS_RUNNING;
info->pcpu = difference * 100 / this->cpu_total_time;
info->pcpu = MIN(info->pcpu, 100);
//CPU 百分比使用 Solaris 模式工作在“Solaris 模式”,其中任务的 CPU 使用量将被除以总的 CPU 数目。否则它将工作在“Irix 模式”。
info->pcpu *= this->num_cpus;
ProcessWorker::cpu_times[info->pid] = info->cpu_time = proctime.rtime;
info->nice = procuid.nice;*/
}
ProcessWorker* ProcessWorker::find(pid_t pid)
{
Iterator it(ProcessWorker::all.find(pid));
return (it == ProcessWorker::all.end() ? NULL : it->second);
}
std::string ProcessWorker::lookup_user(guint uid)
{
typedef std::pair<ProcessWorker::UserMap::iterator, bool> Pair;
ProcessWorker::UserMap::value_type hint(uid, "");
Pair p(ProcessWorker::users.insert(hint));
if (p.second) {
struct passwd* pwd;
pwd = getpwuid(uid);
if (pwd && pwd->pw_name)
p.first->second = pwd->pw_name;
else {
char username[16];
g_sprintf(username, "%u", uid);
p.first->second = username;
}
}
return p.first->second;
}
void ProcessWorker::set_user(guint uid)
{
if (G_LIKELY(this->uid == uid))
return;
this->uid = uid;
this->user = lookup_user(uid);
}

View File

@ -17,46 +17,40 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PROCESSWORKER_H
#define PROCESSWORKER_H
#include <glib.h>
#include <iostream>
#include <map>
#include <QString>
#include <QPainter>
using std::string;
inline string make_string(char *c_str)
class ProcessWorker
{
if (!c_str) {
return string();
}
string s(c_str);
g_free(c_str);
return s;
}
const char* format_process_state(guint state);
const gchar* get_nice_level (gint nice);
class ProcessInfo
{
ProcessInfo& operator=(const ProcessInfo&);
ProcessInfo(const ProcessInfo&);
ProcessWorker& operator=(const ProcessWorker&);
ProcessWorker(const ProcessWorker&);
typedef std::map<guint, std::string> UserMap;
static UserMap users;
public:
ProcessInfo(pid_t pid);
~ProcessInfo();
typedef std::map<pid_t, ProcessInfo*> List;
ProcessWorker(pid_t pid, gint cpus, guint64 cpu_time);
~ProcessWorker();
typedef std::map<pid_t, ProcessWorker*> List;
typedef List::iterator Iterator;
static ProcessInfo* find(pid_t pid);
static Iterator begin() { return ProcessInfo::all.begin(); }
static Iterator end() { return ProcessInfo::all.end(); }
static ProcessWorker* find(pid_t pid);
static Iterator begin() { return ProcessWorker::all.begin(); }
static Iterator end() { return ProcessWorker::all.end(); }
static List all;
void setProcData();
void set_user(guint uid);
std::string lookup_user(guint uid);
std::string user;
float mem;
gulong mem;
gulong start_time;
guint64 cpu_time;
guint status;
@ -65,7 +59,17 @@ class ProcessInfo
gchar *tooltip;
gchar *name;
gchar *arguments;
const guint pid;
const pid_t pid;
guint uid;
static std::map<pid_t, guint64> cpu_times;
gchar *unit;
gchar *session;
gchar *seat;
// gchar *security_context;
// gchar *cgroup_name;
gint num_cpus;
guint64 cpu_total_time;
unsigned frequency;
};
#endif // PROCESSWORKER_H

View File

@ -0,0 +1,309 @@
#include "propertiesdialog.h"
#include "processworker.h"
#include "myimagebutton.h"
#include "util.h"
#include <QApplication>
#include <QDateTime>
#include <QDebug>
#include <QPainter>
#include <QMouseEvent>
#include <QDesktopWidget>
#include <QScreen>
#include <QWidget>
#include <QFileInfo>
#include <QIcon>
PropertiesDialog::PropertiesDialog(QWidget *parent, pid_t processId) : QDialog(parent)
{
this->setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint | Qt::WindowCloseButtonHint);
this->setAttribute(Qt::WA_TranslucentBackground);
// this->setAttribute(Qt::WA_DeleteOnClose, false);
this->setAttribute(Qt::WA_Resized, false);
this->setMaximumSize(480, 600);
this->setMinimumWidth(320);
this->resize(380, 120);
pid = processId;
layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
userLayout = new QHBoxLayout();
userLayout->setContentsMargins(0, 0, 0, 0);
nameLayout = new QHBoxLayout();
nameLayout->setContentsMargins(0, 0, 0, 0);
cmdlineLayout = new QHBoxLayout();
cmdlineLayout->setContentsMargins(0, 0, 0, 0);
cpuDurationLayout = new QHBoxLayout();
cpuDurationLayout->setContentsMargins(0, 0, 0, 0);
startTimeLayout = new QHBoxLayout();
startTimeLayout->setContentsMargins(0, 0, 0, 0);
closeButton = new MyImageButton();
closeButton->setObjectName("CloseButton");
connect(closeButton, &MyImageButton::clicked, this, [=] {
this->close();
});
iconLabel = new QLabel();
iconLabel->setFixedSize(96, 96);
titleLabel = new QLabel();
titleLabel->setStyleSheet("QLabel { background-color : transparent; font-size: 14px; font-weight: 500; color : #303030; }");
userTitleLabel = new QLabel(QString("%1:").arg(tr("User name")));
userTitleLabel->setStyleSheet("QLabel { background-color : transparent; color : #666666; }");
userTitleLabel->setFixedWidth(100);
userTitleLabel->setAlignment(Qt::AlignRight);
userLabel = new QLabel();
userLabel->setStyleSheet("QLabel { background-color : transparent; color : #000000; }");
userLayout->addWidget(userTitleLabel);
userLayout->addWidget(userLabel);
userLayout->addSpacing(20);
nameTitleLabel = new QLabel(QString("%1:").arg(tr("Process name")));
nameTitleLabel->setStyleSheet("QLabel { background-color : transparent; color : #666666; }");
nameTitleLabel->setFixedWidth(100);
nameTitleLabel->setAlignment(Qt::AlignRight);
nameLabel = new QLabel();
nameLabel->setStyleSheet("QLabel { background-color : transparent; color : #000000; }");
nameLayout->addWidget(nameTitleLabel);
nameLayout->addWidget(nameLabel);
nameLayout->addSpacing(20);
cmdlineTitleLabel = new QLabel(QString("%1:").arg(tr("Command line")));
cmdlineTitleLabel->setStyleSheet("QLabel { background-color : transparent; color : #666666; }");
cmdlineTitleLabel->setFixedWidth(100);
cmdlineTitleLabel->setAlignment(Qt::AlignRight);
cmdlineLabel = new QLabel();
cmdlineLabel->setStyleSheet("QLabel { background-color : transparent; color : #000000; }");
cmdlineLabel->setWordWrap(true);
cmdlineLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
cmdlineLayout->addWidget(cmdlineTitleLabel);
cmdlineLayout->addWidget(cmdlineLabel);
cmdlineLayout->addSpacing(20);
cpuDurationTitleLabel = new QLabel(QString("%1:").arg(tr("CPU Time")));
cpuDurationTitleLabel->setStyleSheet("QLabel { background-color : transparent; color : #666666; }");
cpuDurationTitleLabel->setFixedWidth(100);
cpuDurationTitleLabel->setAlignment(Qt::AlignRight);
cpuDurationLabel = new QLabel();
cpuDurationLabel->setStyleSheet("QLabel { background-color : transparent; color : #000000; }");
cpuDurationLabel->setWordWrap(true);
cpuDurationLayout->addWidget(cpuDurationTitleLabel);
cpuDurationLayout->addWidget(cpuDurationLabel);
cpuDurationLayout->addSpacing(20);
startTimeTitleLabel = new QLabel(QString("%1:").arg(tr("Started Time")));
startTimeTitleLabel->setStyleSheet("QLabel { background-color : transparent; color : #666666; }");
startTimeTitleLabel->setFixedWidth(100);
startTimeTitleLabel->setAlignment(Qt::AlignRight);
startTimeLabel = new QLabel();
startTimeLabel->setStyleSheet("QLabel { background-color : transparent; color : #000000; }");
startTimeLabel->setWordWrap(true);
startTimeLayout->addWidget(startTimeTitleLabel);
startTimeLayout->addWidget(startTimeLabel);
startTimeLayout->addSpacing(20);
layout->addWidget(closeButton, 0, Qt::AlignTop | Qt::AlignRight);
layout->addSpacing(20);
layout->addWidget(iconLabel, 0, Qt::AlignHCenter);
layout->addSpacing(14);
layout->addWidget(titleLabel, 0, Qt::AlignHCenter);
layout->addSpacing(20);
layout->addLayout(userLayout);
layout->addLayout(nameLayout);
layout->addLayout(cmdlineLayout);
layout->addLayout(cpuDurationLayout);
layout->addLayout(startTimeLayout);
layout->addSpacing(20);
this->moveToCenter();
this->initProcproperties();
timer = new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(refreshProcproperties()));
timer->start(3000);
}
PropertiesDialog::~PropertiesDialog()
{
if (timer != NULL) {
disconnect(timer,SIGNAL(timeout()),this,SLOT(refreshProcproperties()));
if(timer->isActive()) {
timer->stop();
}
delete timer;
timer = NULL;
}
delete closeButton;
delete iconLabel;
delete userTitleLabel;
delete userLabel;
delete nameTitleLabel;
delete nameLabel;
delete titleLabel;
delete cmdlineTitleLabel;
delete cpuDurationLabel;
delete cpuDurationTitleLabel;
delete startTimeLabel;
delete startTimeTitleLabel;
delete cmdlineLabel;
delete userLayout;
delete nameLayout;
delete cmdlineLayout;
delete cpuDurationLayout;
delete startTimeLayout;
delete layout;
}
void PropertiesDialog::initProcproperties()
{
ProcessWorker *info;
info = ProcessWorker::find(pid);
if (info) {
QString username = QString::fromStdString(info->user);
// long nice = info->nice;
QString name = QString::fromStdString(info->name);
// QString status = formatProcessState(info->status);
// uint cpu = info->pcpu;
// long memory = info->mem;
std::string desktopFile;
desktopFile = getDesktopFileFromName(pid, name, "");
QPixmap icon_pixmap;
int iconSize = 96 * qApp->devicePixelRatio();
QPixmap defaultPixmap = QIcon::fromTheme("application-x-executable").pixmap(iconSize, iconSize);
if (desktopFile.size() == 0) {
icon_pixmap = defaultPixmap;
icon_pixmap.setDevicePixelRatio(qApp->devicePixelRatio());
} else {
icon_pixmap = getDesktopFileIcon(desktopFile, 96);
if (icon_pixmap.isNull()) {
icon_pixmap = defaultPixmap;
icon_pixmap.setDevicePixelRatio(qApp->devicePixelRatio());
}
//QPixmap pixmap = QPixmap::fromImage(img).scaled(iconSize, iconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
QString displayName = getDisplayNameFromName(name, desktopFile);
iconLabel->setPixmap(icon_pixmap);
titleLabel->setText(displayName);
userLabel->setText(username);
nameLabel->setText(QString(info->name));
cmdlineLabel->setText(QString(info->arguments));
startTimeLabel->setText(QFileInfo(QString("/proc/%1").arg(pid)).created().toString("yyyy-MM-dd hh:mm:ss"));
cpuDurationLabel->setText(formatDurationForDisplay(100 * info->cpu_time / info->frequency));
}
}
void PropertiesDialog::refreshProcproperties()
{
ProcessWorker *info;
info = ProcessWorker::find(pid);
if (info) {
startTimeLabel->setText(QFileInfo(QString("/proc/%1").arg(pid)).created().toString("yyyy-MM-dd hh:mm:ss"));
cpuDurationLabel->setText(formatDurationForDisplay(100 * info->cpu_time / info->frequency));
}
}
pid_t PropertiesDialog::getPid()
{
return pid;
}
QRect PropertiesDialog::getParentGeometry() const
{
if (this->parentWidget()) {
return this->parentWidget()->window()->geometry();
} else {
QPoint pos = QCursor::pos();
for (QScreen *screen : qApp->screens()) {
if (screen->geometry().contains(pos)) {
return screen->geometry();
}
}
}
return qApp->primaryScreen()->geometry();
}
void PropertiesDialog::moveToCenter()
{
QRect qr = geometry();
qr.moveCenter(this->getParentGeometry().center());
move(qr.topLeft());
}
void PropertiesDialog::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
this->dragPosition = event->globalPos() - frameGeometry().topLeft();
this->mousePressed = true;
}
QDialog::mousePressEvent(event);
}
void PropertiesDialog::mouseReleaseEvent(QMouseEvent *event)
{
this->mousePressed = false;
QDialog::mouseReleaseEvent(event);
}
void PropertiesDialog::mouseMoveEvent(QMouseEvent *event)
{
if (this->mousePressed) {
move(event->globalPos() - this->dragPosition);
}
QDialog::mouseMoveEvent(event);
}
void PropertiesDialog::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
//绘制圆角矩形
painter.setPen(QPen(QColor("#0d87ca"), 0));//边框颜色 QColor(255, 255, 255, 153)
painter.setBrush(QColor("#e9eef0"));//背景色 #0d87ca
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setOpacity(1);
QRectF r(0 / 2.0, 0 / 2.0, width() - 0, height() - 0);//左边 上边 右边 下边
painter.drawRoundedRect(r, 4, 4);
//绘制背景色
// QPainterPath path;
// path.addRect(QRectF(rect()));
// painter.setOpacity(1);
// painter.fillPath(path, QColor("#ffffff"));
QDialog::paintEvent(event);
}
/*void PropertiesDialog::resizeEvent(QResizeEvent *event)
{
if (event->size().width() >= maximumWidth()) {
setFixedWidth(maximumWidth());
}
QDialog::resizeEvent(event);
}*/

View File

@ -0,0 +1,66 @@
#ifndef PROPERTIESSDIALOG_H
#define PROPERTIESSDIALOG_H
#include <QLabel>
#include <QPaintEvent>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QDialog>
#include <QPoint>
#include <QTimer>
class QMouseEvent;
class MyImageButton;
//TODO: add timer to refresh
class PropertiesDialog : public QDialog
{
Q_OBJECT
public:
PropertiesDialog(QWidget *parent = 0, pid_t pid=-1);
~PropertiesDialog();
pid_t getPid();
QRect getParentGeometry() const;
void moveToCenter();
void initProcproperties();
public slots:
void refreshProcproperties();
protected:
void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
// void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
private:
MyImageButton *closeButton;
QHBoxLayout *cmdlineLayout;
QHBoxLayout *userLayout;
QHBoxLayout *nameLayout;
QHBoxLayout *cpuDurationLayout;
QHBoxLayout *startTimeLayout;
QLabel *cmdlineLabel;
QLabel *cmdlineTitleLabel;
QLabel *userLabel;
QLabel *userTitleLabel;
QLabel *iconLabel;
QLabel *nameLabel;
QLabel *nameTitleLabel;
QLabel *cpuDurationLabel;
QLabel *cpuDurationTitleLabel;
QLabel *startTimeLabel;
QLabel *startTimeTitleLabel;
QLabel *titleLabel;
QVBoxLayout *layout;
pid_t pid;
QPoint dragPosition;
bool mousePressed;
QTimer *timer;
};
#endif // PROPERTIESSDIALOG_H

View File

@ -17,21 +17,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PROCAPP_H
#define PROCAPP_H
#include "resourcesdialog.h"
#include <glib.h>
#include <iostream>
#include <map>
ResouresDialog::ResouresDialog(QWidget *parent)
:QWidget(parent)
{
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
setAcceptDrops(true);
setAttribute(Qt::WA_NoMousePropagation);
using std::string;
this->setObjectName("ResouresDialog");
}
class ProcApp {
public:
GPtrArray * filelist;
guint64 cpu_total_time;
guint64 cpu_total_time_last;
gint num_cpus;
};
ResouresDialog::~ResouresDialog()
{
#endif // PROCAPP_H
}

View File

@ -17,8 +17,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "procapp.h"
#include <QWidget>
#define HZ 100
class ResouresDialog : public QWidget
{
Q_OBJECT
void list_whose_proc_info(ProcApp *app);
public:
explicit ResouresDialog(QWidget* parent = 0);
~ResouresDialog();
};

View File

@ -0,0 +1,407 @@
#include "systemmonitor.h"
#include "util.h"
#include <QFileSystemWatcher>
#include <QLabel>
#include <QDebug>
#include <QMouseEvent>
#include <QDesktopWidget>
#include <QFile>
#include <QHBoxLayout>
#include <QApplication>
#include <QScreen>
namespace {
const int MAINWIDGET_MINIMUN_HEIGHT = 480;
const int MAINWIDGET_MINIMUN_WIDTH = 640;
}
SystemMonitor::SystemMonitor(QWidget *parent)
: QFrame(parent)
, drag_state(NOT_PDRAGGING)
, start_drag(QPoint(0,0))
{
/*this->setAutoFillBackground(true);
QPalette palette;
palette.setColor(QPalette::Background, QColor("#0d87ca"));
this->setPalette(palette);*/
// this->setStyleSheet("QFrame{border: 1px solid #121212;border-radius:1px;background-color:#1f1f1f;}");
// this->setAttribute(Qt::WA_DeleteOnClose);
this->setWindowFlags(Qt::FramelessWindowHint);
this->setAutoFillBackground(true);
this->setMouseTracking(true);
installEventFilter(this);
this->resize(900, 600);
setMinimumSize(MAINWIDGET_MINIMUN_WIDTH, MAINWIDGET_MINIMUN_HEIGHT);
proSettings = new QSettings(KYLIN_COMPANY_SETTING, KYLIN_SETTING_FILE_NAME_SETTING);
proSettings->setIniCodec("UTF-8");
this->initTitleWidget();
this->initToolBar();
this->initPanelStack();
this->initConnections();
this->moveCenter();
}
SystemMonitor::~SystemMonitor()
{
if (m_sysMonitorStack) {
foreach (QObject *child, m_sysMonitorStack->children()) {
QWidget *widget = static_cast<QWidget *>(child);
widget->deleteLater();
}
}
if (m_titleWidget) {
delete m_titleWidget;
m_titleWidget = nullptr;
}
if (m_toolBar) {
delete m_toolBar;
m_toolBar = nullptr;
}
if (process_dialog) {
delete process_dialog;
process_dialog = nullptr;
}
if (resources_dialog) {
delete resources_dialog;
resources_dialog = nullptr;
}
if (filesystem_dialog) {
delete filesystem_dialog;
filesystem_dialog = nullptr;
}
if (proSettings != NULL) {
delete proSettings;
proSettings = NULL;
}
}
void SystemMonitor::resizeEvent(QResizeEvent *e)
{
if (m_titleWidget) {
m_titleWidget->resize(width(), TOP_TITLE_WIDGET_HEIGHT);
if (e->oldSize() != e->size()) {
emit m_titleWidget->updateMaxBtn();
}
}
if (m_toolBar) {
m_toolBar->resize(width(), TOP_TITLE_WIDGET_HEIGHT);
m_toolBar->move(0, TOP_TITLE_WIDGET_HEIGHT);
}
if (m_sysMonitorStack) {
m_sysMonitorStack->resize(width(), this->height() - TOP_TITLE_WIDGET_HEIGHT*2);
m_sysMonitorStack->move(0, TOP_TITLE_WIDGET_HEIGHT*2);
}
}
void SystemMonitor::recordVisibleColumn(int, bool, QList<bool> columnVisible)
{
QList<QString> m_visibleColumns;
m_visibleColumns << "name";
if (columnVisible[1]) {
m_visibleColumns << "user";
}
if (columnVisible[2]) {
m_visibleColumns << "status";
}
if (columnVisible[3]) {
m_visibleColumns << "cpu";
}
if (columnVisible[4]) {
m_visibleColumns << "pid";
}
if (columnVisible[5]) {
m_visibleColumns << "command";
}
if (columnVisible[6]) {
m_visibleColumns << "memory";
}
if (columnVisible[7]) {
m_visibleColumns << "priority";
}
QString processColumns = "";
for (int i = 0; i < m_visibleColumns.length(); i++) {
if (i != m_visibleColumns.length() - 1) {
processColumns += QString("%1,").arg(m_visibleColumns[i]);
} else {
processColumns += m_visibleColumns[i];
}
}
proSettings->beginGroup("PROCESS");
proSettings->setValue("ProcessDisplayColumns", processColumns);
proSettings->endGroup();
proSettings->sync();
}
void SystemMonitor::recordSortStatus(int index, bool sortOrder)
{
QList<QString> columnNames = { "name", "user", "status", "cpu", "pid", "command", "memory", "priority"};
proSettings->beginGroup("PROCESS");
proSettings->setValue("ProcessCurrentSortColumn", columnNames[index]);
proSettings->setValue("ProcessSortOrder", sortOrder);
proSettings->endGroup();
proSettings->sync();
}
void SystemMonitor::initPanelStack()
{
m_sysMonitorStack = new QStackedWidget(this);
m_sysMonitorStack->setStyleSheet("QStackedWidget{background: rgb(255, 255, 255);}");
m_sysMonitorStack->setObjectName("SystemMonitorStack");
m_sysMonitorStack->resize(width(), this->height() - TOP_TITLE_WIDGET_HEIGHT);
m_sysMonitorStack->move(0, TOP_TITLE_WIDGET_HEIGHT);
m_sysMonitorStack->setMouseTracking(false);
m_sysMonitorStack->installEventFilter(this);
process_dialog = new ProcessDialog(getColumnHideFlags(), getSortIndex(), getSortOrder(), proSettings);
process_dialog->getProcessView()->installEventFilter(this);
connect(process_dialog, &ProcessDialog::changeColumnVisible, this, &SystemMonitor::recordVisibleColumn);
connect(process_dialog, &ProcessDialog::changeSortStatus, this, &SystemMonitor::recordSortStatus);
connect(m_toolBar, SIGNAL(activeWhoseProcessList(int)), process_dialog, SLOT(onActiveWhoseProcess(int)));
resources_dialog = new ResouresDialog;
filesystem_dialog = new FileSystemDialog;
m_sysMonitorStack->addWidget(process_dialog);
m_sysMonitorStack->addWidget(resources_dialog);
m_sysMonitorStack->addWidget(filesystem_dialog);
m_sysMonitorStack->setCurrentWidget(process_dialog);
}
void SystemMonitor::initTitleWidget()
{
m_titleWidget = new TitleWidget(this);
m_titleWidget->resize(width(), TOP_TITLE_WIDGET_HEIGHT);
m_titleWidget->move(0, 0);
}
void SystemMonitor::initToolBar()
{
m_toolBar = new ToolBar(proSettings, this);
m_toolBar->resize(width(), TOP_TITLE_WIDGET_HEIGHT);
m_toolBar->move(0, TOP_TITLE_WIDGET_HEIGHT);
}
void SystemMonitor::initConnections()
{
connect(m_toolBar, SIGNAL(changePage(int)), this, SLOT(onChangePage(int)));
connect(m_toolBar, SIGNAL(pressEsc()), process_dialog, SLOT(focusProcessView()));
connect(m_toolBar, SIGNAL(pressTab()), process_dialog, SLOT(focusProcessView()));
connect(m_toolBar, SIGNAL(searchSignal(QString)), process_dialog, SLOT(onSearch(QString)), Qt::QueuedConnection);
}
void SystemMonitor::onChangePage(int index)
{
if (m_sysMonitorStack) {
m_sysMonitorStack->setCurrentIndex(index);
}
}
int SystemMonitor::getSortIndex()
{
proSettings->beginGroup("PROCESS");
QString sortingName = proSettings->value("ProcessCurrentSortColumn").toString();
proSettings->endGroup();
QList<QString> columnNames = {
"name", "user", "status", "cpu", "pid", "command", "memory", "priority"
};
return columnNames.indexOf(sortingName);
}
bool SystemMonitor::getSortOrder()
{
proSettings->beginGroup("PROCESS");
bool value = proSettings->value("ProcessSortOrder", true).toBool();
proSettings->endGroup();
return value;
}
QList<bool> SystemMonitor::getColumnHideFlags()
{
proSettings->beginGroup("PROCESS");
QString processColumns = proSettings->value("ProcessDisplayColumns", "name,user,status,cpu,pid,command,memory,priority").toString();
proSettings->endGroup();
if (processColumns.isEmpty()) {
proSettings->beginGroup("PROCESS");
processColumns = "name,user,status,cpu,pid,command,memory,priority";
proSettings->setValue("ProcessDisplayColumns", processColumns);
proSettings->endGroup();
proSettings->sync();
}
QList<bool> toggleHideFlags;
toggleHideFlags << processColumns.contains("name");
toggleHideFlags << processColumns.contains("user");
toggleHideFlags << processColumns.contains("status");
toggleHideFlags << processColumns.contains("cpu");
toggleHideFlags << processColumns.contains("pid");
toggleHideFlags << processColumns.contains("command");
toggleHideFlags << processColumns.contains("memory");
toggleHideFlags << processColumns.contains("priority");
return toggleHideFlags;
}
void SystemMonitor::moveCenter()
{
QPoint pos = QCursor::pos();
QRect primaryGeometry;
for (QScreen *screen : qApp->screens()) {
if (screen->geometry().contains(pos)) {
primaryGeometry = screen->geometry();
}
}
if (primaryGeometry.isEmpty()) {
primaryGeometry = qApp->primaryScreen()->geometry();
}
this->move(primaryGeometry.x() + (primaryGeometry.width() - this->width())/2,
primaryGeometry.y() + (primaryGeometry.height() - this->height())/2);
}
void SystemMonitor::closeEvent(QCloseEvent *event)
{
event->accept();
}
void SystemMonitor::moveDialog(QPoint diff)
{
#if QT_VERSION >= 0x050000
// Move the window with some delay.
// Seems to work better with Qt 5
static QPoint d;
static int count = 0;
d += diff;
count++;
if (count > 3) {
QPoint new_pos = pos() + d;
if (new_pos.y() < 0) new_pos.setY(0);
if (new_pos.x() < 0) new_pos.setX(0);
move(new_pos);
count = 0;
d = QPoint(0,0);
}
#else
move(pos() + diff);
#endif
}
bool SystemMonitor::eventFilter(QObject *object, QEvent *event)
{
if (object->objectName() == "SystemMonitorStack") {//让滚动条可以鼠标拖动
drag_state = NOT_PDRAGGING;
return false;
}
QEvent::Type type = event->type();
if (type == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_F) {
if (keyEvent->modifiers() == Qt::ControlModifier) {
m_toolBar->focusInput();
return false;
}
}
}
if (type != QEvent::MouseButtonPress
&& type != QEvent::MouseButtonRelease
&& type != QEvent::MouseMove)
return false;
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(event);
if (!mouseEvent) {
return false;
}
if (mouseEvent->modifiers() != Qt::NoModifier) {
drag_state = NOT_PDRAGGING;
return false;
}
if (type == QEvent::MouseButtonPress) {
if (mouseEvent->button() != Qt::LeftButton) {
drag_state = NOT_PDRAGGING;
return false;
}
drag_state = START_PDRAGGING;
start_drag = mouseEvent->globalPos();
// Don't filter, so others can have a look at it too
return false;
}
if (type == QEvent::MouseButtonRelease) {
if (drag_state != PDRAGGING || mouseEvent->button() != Qt::LeftButton) {
drag_state = NOT_PDRAGGING;
return false;
}
// Stop dragging and eat event
drag_state = NOT_PDRAGGING;
event->accept();
return true;
}
// type == QEvent::MouseMove
if (drag_state == NOT_PDRAGGING)
return false;
// buttons() note the s
if (mouseEvent->buttons() != Qt::LeftButton) {
drag_state = NOT_PDRAGGING;
return false;
}
QPoint pos = mouseEvent->globalPos();
QPoint diff = pos - start_drag;
if (drag_state == START_PDRAGGING) {
// Don't start dragging before moving at least DRAG_THRESHOLD pixels
if (abs(diff.x()) < 4 && abs(diff.y()) < 4)
return false;
drag_state = PDRAGGING;
}
this->moveDialog(diff);
start_drag = pos;
event->accept();
return true;
}
void SystemMonitor::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPainterPath path;
path.addRect(QRectF(rect()));
painter.setOpacity(1);
painter.fillPath(path, QColor("#FFFFFF"));
}

View File

@ -0,0 +1,59 @@
#ifndef SYSTEMMONITOR_H
#define SYSTEMMONITOR_H
#include "titlewidget.h"
#include "toolbar.h"
#include "processdialog.h"
#include "resourcesdialog.h"
#include "filesystemdialog.h"
#include <QFrame>
#include <QStackedWidget>
#include <QLabel>
#include <QSettings>
enum PDragState {NOT_PDRAGGING, START_PDRAGGING, PDRAGGING};
class SystemMonitor : public QFrame
{
Q_OBJECT
public:
SystemMonitor(QWidget *parent = 0);
~SystemMonitor();
void initTitleWidget();
void initToolBar();
void initPanelStack();
void initConnections();
QList<bool> getColumnHideFlags();
bool getSortOrder();
int getSortIndex();
void moveCenter();
void moveDialog(QPoint diff);
public slots:
void recordVisibleColumn(int, bool, QList<bool> columnVisible);
void recordSortStatus(int index, bool sortOrder);
void onChangePage(int index);
protected:
void resizeEvent(QResizeEvent *e) override;
bool eventFilter(QObject *, QEvent *);
void paintEvent(QPaintEvent *);
void closeEvent(QCloseEvent *event);
private:
QStackedWidget *m_sysMonitorStack = nullptr;
TitleWidget *m_titleWidget = nullptr;
ToolBar *m_toolBar = nullptr;
ProcessDialog *process_dialog = nullptr;
ResouresDialog *resources_dialog = nullptr;
FileSystemDialog *filesystem_dialog = nullptr;
PDragState drag_state;
QPoint start_drag;
QSettings *proSettings;
};
#endif // SYSTEMMONITOR_H

View File

@ -0,0 +1,99 @@
#-------------------------------------------------
#
# Project created by QtCreator 2015-01-26T09:16:38
#
#-------------------------------------------------
isEqual(QT_MAJOR_VERSION, 5) {
QT += widgets gui
}
TARGET = systemmonitor
TEMPLATE = lib
#INCLUDEPATH += ../systemmonitor
#DESTDIR = ../libs
DESTDIR = $$_PRO_FILE_PWD_/../
CONFIG += plugin c++11 link_pkgconfig
PKGCONFIG += libgtop-2.0 libsystemd
#target.source += $$TARGET
#target.path = /var/lib/kylin-assistant-daemon/libs/
target.path = $${PREFIX}/lib/kylin-assistant/plugins/
INSTALLS += target
#LIBS += -lprocps
#UI_DIR += $$PWD/../tmp/systemmonitor/
#RCC_DIR += $$PWD/../tmp/systemmonitor/
#MOC_DIR += $$PWD/../tmp/systemmonitor/
#OBJECTS_DIR = $$PWD/../obj/systemmonitor
unix {
UI_DIR = .ui
MOC_DIR = .moc
OBJECTS_DIR = .obj
}
HEADERS += \
systemmonitor.h \
../../component/plugininterface.h \
processmanager.h \
processdialog.h \
processlistwidget.h \
processlistitem.h \
processworker.h \
util.h \
../../component/utils.h \
mydialog.h \
myimagebutton.h \
propertiesdialog.h \
processcategory.h \
processdata.h \
myactiongroup.h \
myactiongroupitem.h \
myaction.h \
titlewidget.h \
toolbar.h \
mytipimagebutton.h \
resourcesdialog.h \
filesystemdialog.h \
diskitemlist.h \
diskitem.h \
filesystemworker.h \
diskmodel.h \
diskinfo.h \
mysearchedit.h
SOURCES += \
systemmonitor.cpp \
processmanager.cpp \
processdialog.cpp \
processlistwidget.cpp \
processlistitem.cpp \
processworker.cpp \
util.cpp \
mydialog.cpp \
myimagebutton.cpp \
propertiesdialog.cpp \
processcategory.cpp \
myactiongroup.cpp \
myactiongroupitem.cpp \
myaction.cpp \
titlewidget.cpp \
toolbar.cpp \
mytipimagebutton.cpp \
resourcesdialog.cpp \
filesystemdialog.cpp \
diskitemlist.cpp \
diskitem.cpp \
filesystemworker.cpp \
diskmodel.cpp \
diskinfo.cpp \
mysearchedit.cpp
OTHER_FILES += \
systemmonitor.json
RESOURCES += \
../../src/img.qrc

View File

@ -0,0 +1,152 @@
#include "titlewidget.h"
#include "myimagebutton.h"
#include "mytipimagebutton.h"
#include "util.h"
#include <QApplication>
#include <QDebug>
#include <QHBoxLayout>
#include <QPainter>
#include <QResizeEvent>
#include <QStyleFactory>
TitleWidget::TitleWidget(QWidget *parent)
:QFrame(parent)
{
installEventFilter(this);
setMouseTracking(true);
setFixedHeight(TOP_TITLE_WIDGET_HEIGHT);
m_topBorderColor = QColor(255, 255, 255, 153);
this->setAutoFillBackground(true);
QPalette palette;
palette.setColor(QPalette::Background, QColor("#0d87ca"));
this->setPalette(palette);
initWidgets();
}
TitleWidget::~TitleWidget()
{
//Segmentation fault
QLayoutItem *child;
while ((child = m_lLayout->takeAt(0)) != 0) {
if (child->widget())
child->widget()->deleteLater();
delete child;
}
while ((child = m_rLayout->takeAt(0)) != 0) {
if (child->widget())
child->widget()->deleteLater();
delete child;
}
delete m_layout;
}
void TitleWidget::mouseDoubleClickEvent(QMouseEvent *e)
{
if (e->button() == Qt::LeftButton) {
if (window()->isMaximized())
window()->showNormal();
else if (! window()->isFullScreen())
window()->showMaximized();
}
QFrame::mouseDoubleClickEvent(e);
}
void TitleWidget::paintEvent(QPaintEvent *e)
{
QFrame::paintEvent(e);
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
const QColor tc(m_topBorderColor);
int borderHeight = 1;
QPainterPath tPath;
tPath.moveTo(QPointF(x(), y() + borderHeight - 0.5));
tPath.lineTo(QPointF(x() + width(), y() + borderHeight - 0.5));
p.setPen(QPen(tc));
p.drawPath(tPath);
}
void TitleWidget::initLeftContent()
{
QWidget *w = new QWidget;
m_lLayout = new QHBoxLayout(w);
m_lLayout->setContentsMargins(6, 0, 0, 0);
m_lLayout->setSpacing(0);
QLabel *label = new QLabel;
label->setStyleSheet("QLabel{border-image: url(:/res/kylin-assistant.png);}");
label->setFixedSize(24, 24);
m_lLayout->addWidget(label);
QLabel *titleLabel = new QLabel;
titleLabel->setStyleSheet("QLabel{background-color:transparent;color:#ffffff; font-size:12px;}");
titleLabel->setText("Kyliln System Monitor");
m_lLayout->addSpacing(5);
m_lLayout->addWidget(titleLabel);
m_layout->addWidget(w, 1, Qt::AlignLeft);
}
void TitleWidget::initRightContent()
{
QWidget *w = new QWidget;
m_rLayout = new QHBoxLayout(w);
m_rLayout->setContentsMargins(0, 0, 6, 0);
m_rLayout->setSpacing(0);
m_layout->addWidget(w, 1, Qt::AlignRight);
MyImageButton *minBtn = new MyImageButton;
minBtn->setObjectName("MinButton");
connect(minBtn, &MyImageButton::clicked, this, [=] {
if (parentWidget() && parentWidget()->parentWidget()) {
parentWidget()->parentWidget()->showMinimized();
}
});
MyImageButton *maxBtn = new MyImageButton;
maxBtn->setObjectName("MaxButton");
connect(maxBtn, &MyImageButton::clicked, this, [=] {
if (window()->isMaximized()) {
window()->showNormal();
maxBtn->setObjectName("MaxButton");
}
else {
window()->showMaximized();
maxBtn->setObjectName("UnMaxButton");
}
});
connect(this, &TitleWidget::updateMaxBtn, this, [=]{
if (window()->isMaximized()) {
maxBtn->setObjectName("UnMaxButton");
} else {
maxBtn->setObjectName("MaxButton");
}
});
MyImageButton *closeBtn = new MyImageButton;
closeBtn->setObjectName("CloseButton");
connect(closeBtn, &MyImageButton::clicked, this, [=] {
window()->close();
});
m_rLayout->addWidget(minBtn);
m_rLayout->addWidget(maxBtn);
m_rLayout->addWidget(closeBtn);
}
void TitleWidget::initWidgets()
{
m_layout = new QHBoxLayout(this);
m_layout->setContentsMargins(0, 0, 0, 0);
m_layout->setSpacing(0);
this->setLayout(m_layout);
initLeftContent();
initRightContent();
}

View File

@ -0,0 +1,33 @@
#ifndef MONITORTITLEWIDGET_H
#define MONITORTITLEWIDGET_H
#include <QFrame>
#include <QTimer>
class QHBoxLayout;
class TitleWidget : public QFrame
{
Q_OBJECT
public:
TitleWidget(QWidget *parent);
~TitleWidget();
void initLeftContent();
void initRightContent();
void initWidgets();
protected:
void mouseDoubleClickEvent(QMouseEvent *e) override;
void paintEvent(QPaintEvent *e) override;
signals:
void updateMaxBtn();
private:
QColor m_topBorderColor;
QHBoxLayout *m_layout;
QHBoxLayout *m_lLayout;
QHBoxLayout *m_rLayout;
};
#endif // MONITORTITLEWIDGET_H

View File

@ -0,0 +1,245 @@
#include "toolbar.h"
#include "myimagebutton.h"
#include "mytipimagebutton.h"
#include "processcategory.h"
#include "mysearchedit.h"
#include "util.h"
#include <QApplication>
#include <QDebug>
#include <QHBoxLayout>
#include <QPainter>
#include <QResizeEvent>
#include <QStyleFactory>
ToolBar::ToolBar(QSettings *settings, QWidget *parent)
:QFrame(parent)
,proSettings(settings)
{
installEventFilter(this);
setMouseTracking(true);
setFixedHeight(TOP_TITLE_WIDGET_HEIGHT);
m_topBorderColor = QColor(255, 255, 255, 153);
// this->setAutoFillBackground(true);
// QPalette palette;
// palette.setColor(QPalette::Background, QColor("#0d87ca"));
// this->setPalette(palette);
searchTimer = new QTimer(this);
searchTimer->setSingleShot(true);
connect(searchTimer, SIGNAL(timeout()), this, SLOT(onRefreshSearchResult()));
initWidgets();
}
ToolBar::~ToolBar()
{
delete processLabel;
delete processCategory;
//Segmentation fault
QLayoutItem *child;
while ((child = m_lLayout->takeAt(0)) != 0) {
if (child->widget())
child->widget()->deleteLater();
delete child;
}
while ((child = m_mLayout->takeAt(0)) != 0) {
if (child->widget())
child->widget()->deleteLater();
delete child;
}
while ((child = m_rLayout->takeAt(0)) != 0) {
if (child->widget())
child->widget()->deleteLater();
delete child;
}
delete m_layout;
}
bool ToolBar::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::KeyPress) {
if (obj == this) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Escape) {
searchEdit->clear();
emit pressEsc();
}
}
else if (obj == searchEdit->getLineEdit()) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Tab) {
emit pressTab();
}
}
}
return QFrame::eventFilter(obj, event);
}
void ToolBar::focusInput()
{
if (searchEdit->text() != "") {
searchEdit->getLineEdit()->setFocus();
} else {
searchEdit->setFocus();
}
}
void ToolBar::onRefreshSearchResult()
{
if (searchEdit->text() == searchTextCache) {
emit this->searchSignal(searchTextCache);
}
}
void ToolBar::handleSearchTextChanged()
{
searchTextCache = searchEdit->text();
if (searchTimer->isActive()) {
searchTimer->stop();
}
searchTimer->start(300);
}
void ToolBar::paintEvent(QPaintEvent *e)
{
QFrame::paintEvent(e);
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
const QColor tc(m_topBorderColor);
int borderHeight = 1;
QPainterPath tPath;
tPath.moveTo(QPointF(x(), y() + borderHeight - 0.5));
tPath.lineTo(QPointF(x() + width(), y() + borderHeight - 0.5));
p.setPen(QPen(tc));
p.drawPath(tPath);
}
void ToolBar::initLeftContent()
{
QWidget *w = new QWidget;
m_lLayout = new QHBoxLayout(w);
m_lLayout->setContentsMargins(6, 0, 0, 0);
m_lLayout->setSpacing(0);
processLabel = new QLabel("");
processLabel->setStyleSheet("QLabel { background-color : transparent; color : #505050; }");
m_lLayout->addWidget(processLabel);
m_layout->addWidget(w, 1, Qt::AlignLeft);
}
void ToolBar::initMiddleContent()
{
QWidget *w = new QWidget;
w->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
m_mLayout = new QHBoxLayout(w);
m_mLayout->setContentsMargins(0, 0, 0, 0);
m_mLayout->setSpacing(0);
MyTipImageButton *processButton = new MyTipImageButton();
processButton->setCheckable(true);
processButton->setChecked(true);
processButton->setObjectName("ProcessBtn");
MyTipImageButton *resourcesButton = new MyTipImageButton();
resourcesButton->setCheckable(true);
resourcesButton->setChecked(false);
resourcesButton->setObjectName("ResourcesBtn");
MyTipImageButton *disksButton = new MyTipImageButton();
disksButton->setCheckable(true);
disksButton->setChecked(false);
disksButton->setObjectName("DisksBtn");
connect(processButton, &MyTipImageButton::clicked, this, [=] {
emit this->changePage(0);
processButton->setChecked(true);
resourcesButton->setChecked(false);
disksButton->setChecked(false);
if (!searchEdit->isVisible())
searchEdit->setVisible(true);
});
connect(resourcesButton, &MyTipImageButton::clicked, this, [=] {
emit this->changePage(1);
processButton->setChecked(false);
resourcesButton->setChecked(true);
disksButton->setChecked(false);
if (searchEdit->isVisible())
searchEdit->setVisible(false);
});
connect(disksButton, &MyTipImageButton::clicked, this, [=] {
emit this->changePage(2);
processButton->setChecked(false);
resourcesButton->setChecked(false);
disksButton->setChecked(true);
if (searchEdit->isVisible())
searchEdit->setVisible(false);
});
processButton->setToolTip(tr("Processes"));
resourcesButton->setToolTip(tr("Resources"));
disksButton->setToolTip(tr("File Systems"));
m_mLayout->setContentsMargins(0, 0, 0, 0);
m_mLayout->setSpacing(10);
m_mLayout->addStretch();
m_mLayout->addWidget(processButton);
m_mLayout->addWidget(resourcesButton);
m_mLayout->addWidget(disksButton);
m_mLayout->addStretch();
m_layout->addWidget(w);
}
void ToolBar::initRightContent()
{
QWidget *w = new QWidget;
m_rLayout = new QHBoxLayout(w);
m_rLayout->setContentsMargins(0, 3, 6, 3);
m_rLayout->setSpacing(0);
connect(searchEdit, &MySearchEdit::textChanged, this, &ToolBar::handleSearchTextChanged, Qt::QueuedConnection);
m_rLayout->addWidget(searchEdit);
QString whose_processes = "user";
proSettings->beginGroup("PROCESS");
whose_processes = proSettings->value("WhoseProcesses", whose_processes).toString();
proSettings->endGroup();
int tabIndex = 1;
if (whose_processes == "active") {
tabIndex = 0;
}
else if (whose_processes == "all") {
tabIndex = 2;
}
else {
tabIndex = 1;
}
processCategory = new ProcessCategory(tabIndex);
connect(processCategory, SIGNAL(activeWhoseProcessList(int)), this, SIGNAL(activeWhoseProcessList(int)));
m_rLayout->addSpacing(10);
m_rLayout->addWidget(processCategory, 0, Qt::AlignVCenter);
m_layout->addWidget(w, 1, Qt::AlignRight);
}
void ToolBar::initWidgets()
{
m_layout = new QHBoxLayout(this);
m_layout->setContentsMargins(0, 0, 0, 0);
m_layout->setSpacing(0);
this->setLayout(m_layout);
searchEdit = new MySearchEdit();
searchEdit->setFixedWidth(222);
searchEdit->getLineEdit()->installEventFilter(this);
initLeftContent();
initMiddleContent();
initRightContent();
}

View File

@ -0,0 +1,55 @@
#ifndef TOOLBAR_H
#define TOOLBAR_H
#include <QFrame>
#include <QTimer>
#include <QSettings>
class QHBoxLayout;
class QLabel;
class ProcessCategory;
class MySearchEdit;
class ToolBar : public QFrame
{
Q_OBJECT
public:
ToolBar(QSettings *settings, QWidget *parent);
~ToolBar();
void focusInput();
void initLeftContent();
void initMiddleContent();
void initRightContent();
void initWidgets();
protected:
void paintEvent(QPaintEvent *e) override;
bool eventFilter(QObject *, QEvent *event);
public slots:
void onRefreshSearchResult();
void handleSearchTextChanged();
signals:
void changePage(int index);
void searchSignal(QString searchContent);
void pressEsc();
void pressTab();
void activeWhoseProcessList(int index);
private:
QSettings *proSettings;
QColor m_topBorderColor;
MySearchEdit *searchEdit;
QString searchTextCache;
QTimer *searchTimer;
QLabel *processLabel;
ProcessCategory *processCategory;
QHBoxLayout *m_layout;
QHBoxLayout *m_lLayout;
QHBoxLayout *m_mLayout;
QHBoxLayout *m_rLayout;
};
#endif // TOOLBAR_H

View File

@ -0,0 +1,276 @@
/*
* Copyright (C) 2013 ~ 2015 National University of Defense Technology(NUDT) & Kylin Ltd.
*
* Authors:
* Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QApplication>
#include <QIcon>
#include <glib/gi18n.h>
#include <glib.h>
#include <glibtop/procstate.h>
#include "util.h"
#include <QDirIterator>
#include <fstream>
#include <sstream>
#include <qdiriterator.h>
static inline unsigned divide(unsigned *q, unsigned *r, unsigned d)
{
*q = *r / d;
*r = *r % d;
return *q != 0;
}
QString formatDurationForDisplay(unsigned centiseconds)
{
unsigned weeks = 0, days = 0, hours = 0, minutes = 0, seconds = 0;
(void)(divide(&seconds, &centiseconds, 100)
&& divide(&minutes, &seconds, 60)
&& divide(&hours, &minutes, 60)
&& divide(&days, &hours, 24)
&& divide(&weeks, &days, 7));
QString formatTime;
gchar *duration = NULL;
if (weeks) {
/* xgettext: weeks, days */
duration = g_strdup_printf("%uw%ud", weeks, days);
formatTime = QString(QLatin1String(duration));
if (duration) {
g_free(duration);
duration = NULL;
}
return formatTime;
}
if (days) {
/* xgettext: days, hours (0 -> 23) */
duration = g_strdup_printf("%ud%02uh", days, hours);
formatTime = QString(QLatin1String(duration));
if (duration) {
g_free(duration);
duration = NULL;
}
return formatTime;
}
if (hours) {
/* xgettext: hours (0 -> 23), minutes, seconds */
duration = g_strdup_printf("%u:%02u:%02u", hours, minutes, seconds);
formatTime = QString(QLatin1String(duration));
if (duration) {
g_free(duration);
duration = NULL;
}
return formatTime;
}
/* xgettext: minutes, seconds, centiseconds */
duration = g_strdup_printf("%u:%02u.%02u", minutes, seconds, centiseconds);
formatTime = QString(QLatin1String(duration));
if (duration) {
g_free(duration);
duration = NULL;
}
return formatTime;
}
std::string getDesktopFileFromName(int pid, QString procName, QString cmdline)
{
QDirIterator dir("/usr/share/applications", QDirIterator::Subdirectories);
std::string desktopFile;
// Convert to lower characters.
QString procname = procName.toLower();
// Replace "_" instead "-", avoid some applications desktop file can't found, such as, sublime text.
procname.replace("_", "-");
// Concat desktop file.
QString processFilename = procname + ".desktop";
while(dir.hasNext()) {
if (dir.fileInfo().suffix() == "desktop") {
if (dir.fileName().toLower().contains(processFilename)) {
desktopFile = dir.filePath().toStdString();
break;
}
}
dir.next();
}
return desktopFile;
}
QPixmap getDesktopFileIcon(std::string desktopFile, int iconSize)
{
std::ifstream in;
in.open(desktopFile);
QIcon defaultExecutableIcon = QIcon::fromTheme("application-x-executable");
QIcon icon;
QString iconName;
while(!in.eof()) {
std::string line;
std::getline(in,line);
iconName = QString::fromStdString(line);
if (iconName.startsWith("Icon=")) {
iconName.remove(0,5); // remove the first 5 chars
} else {
continue;
}
if (iconName.contains("/")) {
// this is probably a path to the file, use that instead of the theme icon name
icon = QIcon(iconName);
} else {
icon = QIcon::fromTheme(iconName, defaultExecutableIcon);
break;
}
}
in.close();
qreal devicePixelRatio = qApp->devicePixelRatio();
QPixmap pixmap = icon.pixmap(iconSize * devicePixelRatio, iconSize * devicePixelRatio);
pixmap.setDevicePixelRatio(devicePixelRatio);
return pixmap;
}
QString getDisplayNameFromName(QString procName, std::string desktopFile)
{
if (desktopFile.size() == 0) {
return procName;
}
std::ifstream in;
in.open(desktopFile);
QString displayName = procName;
while(!in.eof()) {
std::string line;
std::getline(in,line);
QString lineContent = QString::fromStdString(line);
QString localNameFlag = QString("Name[%1]=").arg(QLocale::system().name());
QString nameFlag = "Name=";
QString genericNameFlag = QString("GenericName[%1]=").arg(QLocale::system().name());
if (lineContent.startsWith(localNameFlag)) {
displayName = lineContent.remove(0, localNameFlag.size());
break;
} else if (lineContent.startsWith(genericNameFlag)) {
displayName = lineContent.remove(0, genericNameFlag.size());
break;
} else if (lineContent.startsWith(nameFlag)) {
displayName = lineContent.remove(0, nameFlag.size());
continue;
} else {
continue;
}
}
in.close();
return displayName;
}
QString getImagePath(QString imageName)
{
QDir dir(qApp->applicationDirPath());
dir.cdUp();
return QDir(dir.filePath("image")).filePath(imageName);
}
QString formatProcessState(guint state)
{
QString status;
switch (state)
{
case GLIBTOP_PROCESS_RUNNING:
status = QString(QObject::tr("Running"));//运行中
break;
case GLIBTOP_PROCESS_STOPPED:
status = QString(QObject::tr("Stopped"));//已停止
break;
case GLIBTOP_PROCESS_ZOMBIE:
status = QString(QObject::tr("Zombie"));//僵死
break;
case GLIBTOP_PROCESS_UNINTERRUPTIBLE:
status = QString(QObject::tr("Uninterruptible"));//不可中断
break;
default:
status = QString(QObject::tr("Sleeping"));//睡眠中
break;
}
return status;
}
QString getNiceLevel(int nice)
{
if (nice < -7)
return QObject::tr("Very High");
else if (nice < -2)
return QObject::tr("High");
else if (nice < 3)
return QObject::tr("Normal");
else if (nice < 7)
return QObject::tr("Low");
else
return QObject::tr("Very Low");
}
void setFontSize(QPainter &painter, int textSize)
{
QFont font = painter.font() ;
font.setPointSize(textSize);
painter.setFont(font);
}
QString formatUnitSize(double v, const char** orders, int nb_orders)
{
int order = 0;
while (v >= 1024 && order + 1 < nb_orders) {
order++;
v = v/1024;
}
char buffer1[30];
snprintf(buffer1, sizeof(buffer1), "%.1lf %s", v, orders[order]);
return QString(buffer1);
}
QString formatByteCount(double v)
{
static const char* orders[] = { "B", "KB", "MB", "GB", "TB" };
return formatUnitSize(v, orders, sizeof(orders)/sizeof(orders[0]));
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (C) 2013 ~ 2015 National University of Defense Technology(NUDT) & Kylin Ltd.
*
* Authors:
* Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <glib.h>
#include <iostream>
#include <map>
#include <QString>
#include <QObject>
#include <QPainter>
#define TOP_TITLE_WIDGET_HEIGHT 39
using std::string;
std::string getDesktopFileFromName(int pid, QString procName, QString cmdline);
QPixmap getDesktopFileIcon(std::string desktopFile, int iconSize = 24);
QString getDisplayNameFromName(QString procName, std::string desktopFile);
QString getImagePath(QString imageName);
inline string make_string(char *c_str)
{
if (!c_str) {
return string();
}
string s(c_str);
g_free(c_str);
return s;
}
QString formatProcessState(guint state);
QString getNiceLevel(int nice);
QString formatUnitSize(double v, const char** orders, int nb_orders);
QString formatByteCount(double v);
void setFontSize(QPainter &painter, int textSize);
QString formatDurationForDisplay(unsigned centiseconds);

View File

@ -1,54 +0,0 @@
/*
* Copyright (C) 2013 ~ 2015 National University of Defense Technology(NUDT) & Kylin Ltd.
*
* Authors:
* Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "filelist.h"
#include <stdio.h>
void filelist_init(GPtrArray **filelist)
{
*filelist = g_ptr_array_new_full(100, free);
(*filelist)->len = 0;
}
int filelist_append(GPtrArray *filelist, char * value)
{
g_ptr_array_add(filelist, (void*)value);
return 0;
}
int filelist_length(GPtrArray *filelist)
{
if( !filelist ){
printf("it's NULL\n");
return 0;
}
if(filelist->pdata == NULL)
return 0;
return filelist->len;
}
char * filelist_index(GPtrArray *filelist, int index)
{
return (char*)g_ptr_array_index(filelist, index);
}
void filelist_destroy(GPtrArray *filelist)
{
g_ptr_array_free(filelist, TRUE);
}

View File

@ -1,340 +0,0 @@
/*
* Copyright (C) 2013 ~ 2015 National University of Defense Technology(NUDT) & Kylin Ltd.
*
* Authors:
* Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QStringList>
#include <QCloseEvent>
#include <QBitmap>
#include <QPainter>
#include "processmanager.h"
#include <QFileDialog>
#include <QDir>
#include <QProcess>
#include <QDebug>
#include <QHeaderView>
//pkg-config --cflags libgtop-2.0
//pkg-config --libs glib-2.0 libgtop-2.0
//ProcessDialog::ProcessDialog(ProcessManager *plugin, QDialog *parent)
//:QDialog(parent)
ProcessDialog::ProcessDialog(QWidget *parent)
:QWidget(parent)
{
setWindowFlags(Qt::FramelessWindowHint);
this->setStyleSheet("QDialog{border: 1px solid white;border-radius:1px;background-color: #ffffff;}");
this->setWindowIcon(QIcon(":/res/youker-assistant.png"));
title_bar = new KylinTitleBar();
proSettings = new QSettings(KYLIN_COMPANY_SETTING, KYLIN_SETTING_FILE_NAME_SETTING);
proSettings->setIniCodec("UTF-8");
initTitleBar();
// this->setFixedSize(850, 476);
// process_plugin = plugin;
toolkits = new Toolkits(0, this->width(), this->height());
tip_label = new QLabel();
kill_btn = new QPushButton();
kill_btn->setFixedSize(91, 25);
kill_btn->setObjectName("blackButton");
kill_btn->setFocusPolicy(Qt::NoFocus);
tableWidget = new QTableWidget();
tableWidget->setStyleSheet("QTableWidget{border: none}");
QHBoxLayout *h_layout = new QHBoxLayout();
h_layout->addWidget(tip_label);
h_layout->addStretch();
h_layout->addWidget(kill_btn);
h_layout->setMargin(0);
h_layout->setContentsMargins(10, 2, 10, 0);
QVBoxLayout *v_layout = new QVBoxLayout();
v_layout->addWidget(tableWidget);
v_layout->setContentsMargins(10, 0, 10, 10);
QVBoxLayout *main_layout = new QVBoxLayout();
main_layout->addWidget(title_bar);
main_layout->addLayout(h_layout);
main_layout->addLayout(v_layout);
main_layout->setSpacing(20);
main_layout->setMargin(0);
main_layout->setContentsMargins(0, 0, 0, 0);
setLayout(main_layout);
app = new ProcApp();
selected_pid = "";
this->refresh_prolist();
timer=new QTimer(this);
timer->start(3000);
this->setLanguage();
this->initConnect();
}
ProcessDialog::~ProcessDialog()
{
if (app) {
delete app;
}
disconnect(timer,SIGNAL(timeout()),this,SLOT(refresh_prolist()));
if(timer->isActive()) {
timer->stop();
}
if (proSettings != NULL)
{
proSettings->sync();
delete proSettings;
proSettings = NULL;
}
}
void ProcessDialog::setLanguage()
{
this->setWindowTitle(tr("Process Manager"));
tip_label->setText(tr("Help you learn more about the program running on the system."));
kill_btn->setText(tr("Kill Process"));
}
void ProcessDialog::initConnect()
{
connect(timer,SIGNAL(timeout()),this,SLOT(refresh_prolist()));
connect(tableWidget, SIGNAL(cellClicked(int,int)), this, SLOT(handlercellClicked(int,int)));
connect(kill_btn, SIGNAL(clicked()), this, SLOT(killSelectedProcess()));
// connect(title_bar, SIGNAL(showMinDialog()), this, SLOT(onMinButtonClicked()));
connect(title_bar,SIGNAL(closeDialog()), this, SLOT(onCloseButtonClicked()));
}
void ProcessDialog::onCloseButtonClicked()
{
this->close();
}
//void ProcessDialog::onMinButtonClicked()
//{
// this->showMinimized();
//// this->hide();
//}
void ProcessDialog::closeEvent(QCloseEvent *event)
{
event->accept();
// emit SignalClose();
}
QString ProcessDialog::getCurrrentSkinName()
{
proSettings->beginGroup("Background");
QString skin = proSettings->value("Path").toString();
if(skin.isEmpty()) {
skin = ":/background/res/skin/1.png";
}
else {
QStringList skinlist;
QString path = "/var/lib/youker-assistant-daemon/default/";
QDir picdir(path);
picdir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
picdir.setSorting(QDir::Size | QDir::Reversed);
QStringList filters;
filters << "*.jpg" << "*.png";
picdir.setNameFilters(filters);
QFileInfoList list = picdir.entryInfoList();
if(list.size() < 1) {
skinlist << ":/background/res/skin/1.png" << ":/background/res/skin/2.png" << ":/background/res/skin/3.png" << ":/background/res/skin/4.png";
}
else {
for (int j = 0; j < list.size(); ++j) {
QFileInfo fileInfo = list.at(j);
skinlist << path + fileInfo.fileName();
}
skinlist << ":/background/res/skin/1.png" << ":/background/res/skin/2.png" << ":/background/res/skin/3.png" << ":/background/res/skin/4.png";
}
QList<QString>::Iterator it = skinlist.begin(), itend = skinlist.end();
bool flag = false;
for(;it != itend; it++)
{
if(*it == skin) {
flag = true;
break;
}
}
if (flag == false) {
skin = skinlist.at(0);
}
}
proSettings->endGroup();
proSettings->sync();
return skin;
}
void ProcessDialog::initTitleBar()
{
QString skin = this->getCurrrentSkinName();
title_bar->setTitleWidth(850);
title_bar->setTitleName(tr("Process Manager"));
// title_bar->setTitleBackgound(":/background/res/skin/1.png");
title_bar->setTitleBackgound(skin);
}
void ProcessDialog::resetSkin()
{
QString skin = this->getCurrrentSkinName();
title_bar->resetBackground(skin);
}
void ProcessDialog::showProList() {
tableWidget->clearContents();//只清除表中数据,不清除表头内容
tableWidget->setRowCount(0);//连行也清除掉
int num = filelist_length(app->filelist);
// printf("num=%s\n",g_strdup_printf("%d", num));
tableWidget->setColumnCount(COLUMN_NUM);
tableWidget->setRowCount(num);
tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
tableWidget->verticalHeader()->setVisible(false);
tableWidget->setMouseTracking(true);
tableWidget->setSelectionMode(QTableWidget::SingleSelection);
tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
tableWidget->horizontalHeader()->setHighlightSections(false);
tableWidget->setShowGrid(false);
QStringList headers;
// headers << "命令行" << "用户" << "ID" << "优先级" << "状态" << "% 内存" << "% CPU" << "CPU时间" << "开始于";//<< "等候频道";
headers << tr("Command Line") << tr("User") << tr("ID") << tr("Priority") << tr("Status") << tr("% Memory") << tr("% CPU") << tr("CPU Time") << tr("Started");//<< "Waiting Channel";
tableWidget->setHorizontalHeaderLabels(headers);
QTableWidgetItem *columnHeaderItem0 = tableWidget->horizontalHeaderItem(0); //获得水平方向表头的Item对象
QTableWidgetItem *columnHeaderItem1 = tableWidget->horizontalHeaderItem(1);
QTableWidgetItem *columnHeaderItem2 = tableWidget->horizontalHeaderItem(2);
QTableWidgetItem *columnHeaderItem3 = tableWidget->horizontalHeaderItem(3);
QTableWidgetItem *columnHeaderItem4 = tableWidget->horizontalHeaderItem(4);
QTableWidgetItem *columnHeaderItem5 = tableWidget->horizontalHeaderItem(5);
QTableWidgetItem *columnHeaderItem6 = tableWidget->horizontalHeaderItem(6);
QTableWidgetItem *columnHeaderItem7 = tableWidget->horizontalHeaderItem(7);
QTableWidgetItem *columnHeaderItem8 = tableWidget->horizontalHeaderItem(8);
columnHeaderItem0->setFont(QFont("Helvetica")); //设置字体
columnHeaderItem0->setBackgroundColor(QColor(0,60,10)); //设置单元格背景颜色
columnHeaderItem0->setTextColor(QColor(200,111,30)); //设置文字颜色
columnHeaderItem1->setFont(QFont("Helvetica"));
columnHeaderItem1->setBackgroundColor(QColor(0,60,10));
columnHeaderItem1->setTextColor(QColor(200,111,30));
columnHeaderItem2->setFont(QFont("Helvetica"));
columnHeaderItem2->setBackgroundColor(QColor(0,60,10));
columnHeaderItem2->setTextColor(QColor(200,111,30));
columnHeaderItem3->setFont(QFont("Helvetica"));
columnHeaderItem3->setBackgroundColor(QColor(0,60,10));
columnHeaderItem3->setTextColor(QColor(200,111,30));
columnHeaderItem4->setFont(QFont("Helvetica"));
columnHeaderItem4->setBackgroundColor(QColor(0,60,10));
columnHeaderItem4->setTextColor(QColor(200,111,30));
columnHeaderItem5->setFont(QFont("Helvetica"));
columnHeaderItem5->setBackgroundColor(QColor(0,60,10));
columnHeaderItem5->setTextColor(QColor(200,111,30));
columnHeaderItem6->setFont(QFont("Helvetica"));
columnHeaderItem6->setBackgroundColor(QColor(0,60,10));
columnHeaderItem6->setTextColor(QColor(200,111,30));
columnHeaderItem7->setFont(QFont("Helvetica"));
columnHeaderItem7->setBackgroundColor(QColor(0,60,10));
columnHeaderItem7->setTextColor(QColor(200,111,30));
columnHeaderItem8->setFont(QFont("Helvetica"));
columnHeaderItem8->setBackgroundColor(QColor(0,60,10));
columnHeaderItem8->setTextColor(QColor(200,111,30));
//表头设置
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
tableWidget->horizontalHeader()->setClickable(false);
#endif
tableWidget->horizontalHeader()->resizeSection(0,150);
tableWidget->horizontalHeader()->resizeSection(1,80);
tableWidget->horizontalHeader()->resizeSection(2,50);
tableWidget->horizontalHeader()->resizeSection(3,80);
tableWidget->horizontalHeader()->resizeSection(4,80);
tableWidget->horizontalHeader()->resizeSection(5,60);
tableWidget->horizontalHeader()->resizeSection(6,80);
tableWidget->horizontalHeader()->resizeSection(7,80);
tableWidget->horizontalHeader()->setFixedHeight(25);
tableWidget->horizontalHeader()->setStretchLastSection(true);
int index = 0;
char * checkpath = NULL;
for( ; index<num ; index++) {
checkpath = filelist_index(app->filelist, index);
QString pro_line = QString::fromLocal8Bit(checkpath);
QStringList tmp = pro_line.split(";");
if(tmp.length() == COLUMN_NUM) {
if(selected_pid == tmp[2]) {
// tableWidget->selectRow(index);//set current selected row
tableWidget->setCurrentCell(index, QItemSelectionModel::Select);
}
if(index == 0 && selected_pid == "") {
tableWidget->selectRow(0);//set current selected row
selected_pid = tmp[2];
}
for(int i=0;i<COLUMN_NUM;i++) {
if (i == 0 || i == 8) {
tableWidget->setItem(index, i, new QTableWidgetItem(tmp[i]));
}
else {
QTableWidgetItem *newItem = new QTableWidgetItem(tmp[i]);
newItem->setTextAlignment(Qt::AlignCenter);
tableWidget->setItem(index,i,newItem);
}
}
}
}
tableWidget->setFocus(Qt::MouseFocusReason);
filelist_destroy(app->filelist);
app->filelist=NULL;
}
void ProcessDialog::refresh_prolist() {
list_whose_proc_info(app);
this->showProList();
}
void ProcessDialog::handlercellClicked(int row, int column) {
QList<QTableWidgetItem*>items=tableWidget->selectedItems();
QTableWidgetItem*item=items.at(2);
QString name=item->text();//获取内容
selected_pid = name;
}
void ProcessDialog::killSelectedProcess(){
QString pid;
QList<QTableWidgetItem*>items = tableWidget->selectedItems();
QTableWidgetItem* item = items.at(2);
pid = item->text();
QProcess *p = new QProcess();
p->start("kill -9 " + pid);
bool result = p->waitForFinished();
if (result) {
toolkits->alertMSG(this->frameGeometry().topLeft().x(), this->frameGeometry().topLeft().y(), tr("kill process success"));
}
else {
toolkits->alertMSG(this->frameGeometry().topLeft().x(), this->frameGeometry().topLeft().y(), tr("kill process failed"));
}
// int count=items.count();
// for(int i=0;i<count;i++) {
// int row = tableWidget->row(items.at(i));//获取选中的行
// QTableWidgetItem* item = items.at(i);
// QString name=item->text();//获取内容
// }
}

View File

@ -1,79 +0,0 @@
/*
* Copyright (C) 2013 ~ 2015 National University of Defense Technology(NUDT) & Kylin Ltd.
*
* Authors:
* Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QTableWidget>
#include <QDebug>
#include <QHeaderView>
#include <QSettings>
#include "procman.h"
#include "procapp.h"
#include "filelist.h"
#include "../component/utils.h"
#include "../component/toolkits.h"
#include "../component/kylintitlebar.h"
#include <QTimer>
#define COLUMN_NUM 9
class ProcessManager;
//class ProcessDialog : public QDialog
class ProcessDialog : public QWidget
{
Q_OBJECT
public:
// ProcessDialog(ProcessManager *plugin, QDialog *parent = 0);
explicit ProcessDialog(QWidget* parent = 0);
~ProcessDialog();
void setLanguage();
void initConnect();
void initTitleBar();
void showProList();
QString getCurrrentSkinName();
void resetSkin();
ProcApp *app;
protected:
void closeEvent(QCloseEvent *event);
private slots:
void refresh_prolist();
void handlercellClicked(int row, int column);
void killSelectedProcess();
void onCloseButtonClicked();
// void onMinButtonClicked();
private:
// ProcessManager *process_plugin;
QLabel *tip_label;
QPushButton *kill_btn;
QTableWidget *tableWidget;
QString selected_pid;
QTimer *timer;
Toolkits *toolkits;
KylinTitleBar *title_bar;
QSettings *proSettings;
};

View File

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ProcessDialog</class>
<widget class="QDialog" name="ProcessDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>745</width>
<height>435</height>
</rect>
</property>
<property name="windowTitle">
<string/>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,63 +0,0 @@
#-------------------------------------------------
#
# Project created by QtCreator 2015-01-26T09:16:38
#
#-------------------------------------------------
isEqual(QT_MAJOR_VERSION, 5) {
QT += widgets gui
}
TARGET = processmanager
TEMPLATE = lib
INCLUDEPATH += ../processmanager
DESTDIR = ../libs
CONFIG += plugin c++11 link_pkgconfig
PKGCONFIG += libgtop-2.0
UI_DIR += $$PWD/../tmp/processmanager/
RCC_DIR += $$PWD/../tmp/processmanager/
MOC_DIR += $$PWD/../tmp/processmanager/
OBJECTS_DIR = $$PWD/../obj/processmanager
target.source += $$TARGET
target.path = /var/lib/kylin-assistant-daemon/libs/
INSTALLS +=target
HEADERS += \
../component/plugininterface.h \
processmanager.h \
processdialog.h \
procman.h \
procapp.h \
util.h \
filelist.h \
../component/alertdialog.h \
../component/toolkits.h \
../component/utils.h \
../component/kylintitlebar.h \
../component/systembutton.h
SOURCES += \
processmanager.cpp \
processdialog.cpp \
procman.cpp \
util.cpp \
filelist.cc \
../component/alertdialog.cpp \
../component/toolkits.cpp \
../component/kylintitlebar.cpp \
../component/systembutton.cpp
FORMS += \
../component/alertdialog.ui
OTHER_FILES += \
process.json
RESOURCES += \
../src/img.qrc

View File

@ -1,249 +0,0 @@
/*
* Copyright (C) 2013 ~ 2015 National University of Defense Technology(NUDT) & Kylin Ltd.
*
* Authors:
* Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "procman.h"
#include "util.h"
#include "filelist.h"
#include <glibtop.h>
#include <glibtop/proclist.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gprintf.h>
#include <glibtop/procstate.h>
#include <glibtop/procmem.h>
#include <glibtop/procmap.h>
#include <glibtop/proctime.h>
#include <glibtop/procuid.h>
#include <glibtop/procargs.h>
#include <glibtop/prockernel.h>
#include <pwd.h>
#include <glibtop/mem.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
using std::string;
ProcessInfo::UserMap ProcessInfo::users;
ProcessInfo::List ProcessInfo::all;
std::map<pid_t, guint64> ProcessInfo::cpu_times;
ProcessInfo::ProcessInfo(pid_t pid)
: tooltip(NULL),
name(NULL),
arguments(NULL),
status(0),
pid(pid),
uid(-1)
{
ProcessInfo * const info = this;
glibtop_proc_state procstate;
glibtop_proc_time proctime;
glibtop_proc_args procargs;
gchar** arguments;
glibtop_get_proc_state (&procstate, pid);
glibtop_get_proc_time (&proctime, pid);
arguments = glibtop_get_proc_argv (&procargs, pid, 0);
std::string tooltip = make_string(g_strjoinv(" ", arguments));
if (tooltip.empty())
tooltip = procstate.cmd;
info->tooltip = g_markup_escape_text(tooltip.c_str(), -1);
info->arguments = g_strescape(tooltip.c_str(), "\\\"");
g_strfreev(arguments);
guint64 cpu_time = proctime.rtime;
std::map<pid_t, guint64>::iterator it(ProcessInfo::cpu_times.find(pid));
if (it != ProcessInfo::cpu_times.end())
{
if (proctime.rtime >= it->second)
cpu_time = it->second;
}
info->cpu_time = cpu_time;
info->start_time = proctime.start_time;
glibtop_init();
}
ProcessInfo::~ProcessInfo()
{
glibtop_close();
g_free(this->name);
g_free(this->tooltip);
g_free(this->arguments);
}
ProcessInfo* ProcessInfo::find(pid_t pid)
{
Iterator it(ProcessInfo::all.find(pid));
return (it == ProcessInfo::all.end() ? NULL : it->second);
}
std::string ProcessInfo::lookup_user(guint uid)
{
typedef std::pair<ProcessInfo::UserMap::iterator, bool> Pair;
ProcessInfo::UserMap::value_type hint(uid, "");
Pair p(ProcessInfo::users.insert(hint));
if (p.second) {
struct passwd* pwd;
pwd = getpwuid(uid);
if (pwd && pwd->pw_name)
p.first->second = pwd->pw_name;
else {
char username[16];
g_sprintf(username, "%u", uid);
p.first->second = username;
}
}
return p.first->second;
}
void ProcessInfo::set_user(guint uid)
{
if (G_LIKELY(this->uid == uid))
return;
this->uid = uid;
this->user = lookup_user(uid);
}
static void update_info (ProcApp *app, ProcessInfo *info)
{
glibtop_proc_state procstate;
glibtop_proc_uid procuid;
glibtop_proc_time proctime;
glibtop_proc_args procargs;
gchar** arguments;
float memrate;
glibtop_mem memory;
glibtop_proc_mem procmem;
glibtop_get_mem(&memory);
glibtop_get_proc_mem(&procmem,info->pid);
memrate = 100*(procmem.resident) /((memory.total)*1.0);
info->mem = memrate;
glibtop_get_proc_state (&procstate, info->pid);
info->status = procstate.state;
glibtop_get_proc_uid (&procuid, info->pid);
glibtop_get_proc_time (&proctime, info->pid);
arguments = glibtop_get_proc_argv (&procargs, info->pid, 0);
std::string tooltip = make_string(g_strjoinv(" ", arguments));
if (tooltip.empty())
tooltip = procstate.cmd;
g_strfreev(arguments);
info->name = procstate.cmd;
info->set_user(procstate.uid);
guint64 difference = proctime.rtime - info->cpu_time;
if (difference > 0)
info->status = GLIBTOP_PROCESS_RUNNING;
info->pcpu = difference * 100 / app->cpu_total_time;
info->pcpu = MIN(info->pcpu, 100);
ProcessInfo::cpu_times[info->pid] = info->cpu_time = proctime.rtime;
info->nice = procuid.nice;
gchar* str_command = g_strdup_printf("%s", g_strdup_printf("%s", info->arguments));
gchar* str_user = g_strdup_printf("%s", info->user.c_str());
gchar* str_pid = g_strdup_printf("%s", g_strdup_printf("%d", info->pid));
gchar* str_priority = g_strdup_printf("%s", g_strdup_printf("%s", get_nice_level(info->nice)));
gchar* str_status = g_strdup_printf("%s", g_strdup(format_process_state(info->status)));
gchar* str_mem = g_strdup_printf("%s",g_strdup_printf("%0.1f%%", info->mem));
gchar* str_pcpu = g_strdup_printf("%s",g_strdup_printf("%d%%", info->pcpu));
gchar* str_cputime = g_strdup_printf("%s",g_strdup_printf(ngettext("%lld second", "%lld seconds", info->cpu_time/HZ), (unsigned long long)info->cpu_time/HZ));
gchar* str_starttime = g_strdup_printf("%s",g_strdup_printf("%s", ctime((const time_t*)(&info->start_time))));
str_starttime[strlen(str_starttime)-1] = 0;
int info_size = 1024;
// int info_size = strlen(str_name) + strlen(str_user) + strlen(str_uid) + strlen(str_status) + strlen(str_mem) + strlen(str_pcpu) + strlen(str_cputime) + strlen(str_starttime) + strlen(str_nice) + strlen(str_priority) + strlen(str_pid) + strlen(str_command) + strlen(str_wchan) + 1;
char *pro_info;
pro_info = (char*)calloc( info_size, sizeof(char));
memset( pro_info, 0, info_size );
if(!pro_info){
perror("calloc");
}
snprintf( pro_info, info_size, "%s;%s;%s;%s;%s;%s;%s;%s;%s", str_command, str_user, str_pid, str_priority, str_status, str_mem, str_pcpu, str_cputime, str_starttime);
filelist_append(app->filelist, pro_info);
}
static void refresh_whose_processes_list (ProcApp *app, const pid_t* pid_list, const guint n)
{
guint i;
for(i = 0; i < n; ++i) {
ProcessInfo *info = ProcessInfo::find(pid_list[i]);
if (!info) {
info = new ProcessInfo(pid_list[i]);
ProcessInfo::all[info->pid] = info;
}
update_info (app, info);
}
}
void list_whose_proc_info(ProcApp *app) {
// glibtop_init();
pid_t* pid_list;
glibtop_proclist proclist;
glibtop_cpu cpu;
gint which, arg;
gint i;
gint whose_process;
whose_process = 1;
filelist_init(&app->filelist);
app->num_cpus = 0;
i=0;
while (i < GLIBTOP_NCPU && cpu.xcpu_total[i] != 0) {
app->num_cpus ++;
i++;
}
if (app->num_cpus == 0) {
app->num_cpus = 1;
}
switch (whose_process) {
case 0://all processes
which = GLIBTOP_KERN_PROC_ALL;
arg = 0;
break;
case 2://active processes
which = GLIBTOP_KERN_PROC_ALL | GLIBTOP_EXCLUDE_IDLE;
arg = 0;
break;
default:
which = GLIBTOP_KERN_PROC_UID;
arg = getuid ();
break;
}
pid_list = glibtop_get_proclist (&proclist, which, arg);
glibtop_get_cpu (&cpu);
app->cpu_total_time = MAX(cpu.total - app->cpu_total_time_last, 1);
app->cpu_total_time_last = cpu.total;
refresh_whose_processes_list (app, pid_list, proclist.number);
g_free (pid_list);
// glibtop_close();
}

View File

@ -1,67 +0,0 @@
/*
* Copyright (C) 2013 ~ 2015 National University of Defense Technology(NUDT) & Kylin Ltd.
*
* Authors:
* Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <glib/gi18n.h>
#include <glib.h>
#include <glibtop/procstate.h>
#include "util.h"
const char* format_process_state(guint state)
{
const char *status;
switch (state)
{
case GLIBTOP_PROCESS_RUNNING:
status = _("Running");
break;
case GLIBTOP_PROCESS_STOPPED:
status = _("Stopped");
break;
case GLIBTOP_PROCESS_ZOMBIE:
status = _("Zombie");
break;
case GLIBTOP_PROCESS_UNINTERRUPTIBLE:
status = _("Uninterruptible");
break;
default:
status = _("Sleeping");
break;
}
return status;
}
const gchar* get_nice_level (gint nice)
{
if (nice < -7)
return _("Very High");
else if (nice < -2)
return _("High");
else if (nice < 3)
return _("Normal");
else if (nice < 7)
return _("Low");
else
return _("Very Low");
}

View File

@ -1,58 +0,0 @@
#-------------------------------------------------
#
# Project created by QtCreator 2015-01-26T09:16:38
#
#-------------------------------------------------
QT += core
isEqual(QT_MAJOR_VERSION, 5) {
QT += widgets gui
}
#greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = shredmanager
TEMPLATE = lib
CONFIG += plugin c++11
INCLUDEPATH += ../shredmanager
DESTDIR = ../libs
UI_DIR += $$PWD/../tmp/shredmanager/
RCC_DIR += $$PWD/../tmp/shredmanager/
MOC_DIR += $$PWD/../tmp/shredmanager/
OBJECTS_DIR = $$PWD/../obj/shredmanager
target.source += $$TARGET
target.path = /var/lib/kylin-assistant-daemon/libs/
INSTALLS +=target
HEADERS += \
filewipe.h \
../component/plugininterface.h \
shredmanager.h \
shreddialog.h \
../component/toolkits.h \
../component/alertdialog.h \
../component/utils.h \
../component/toolkits.h \
../component/kylintitlebar.h \
../component/systembutton.h \
../component/kylineditbutton.h
SOURCES += \
filewipe.cpp \
shredmanager.cpp \
shreddialog.cpp \
../component/alertdialog.cpp \
../component/toolkits.cpp \
../component/kylintitlebar.cpp \
../component/systembutton.cpp \
../component/kylineditbutton.cpp
FORMS += \
../component/alertdialog.ui
RESOURCES += \
../src/img.qrc

View File

@ -193,6 +193,29 @@
<file>res/camera-error.png</file>
<file>res/catch-disable.png</file>
<file>res/kylin-assistant.png</file>
<file>res/arrow_up_hover.png</file>
<file>res/arrow_up_normal.png</file>
<file>res/arrow_up_press.png</file>
<file>res/arrow_down_hover.png</file>
<file>res/arrow_down_normal.png</file>
<file>res/arrow_down_press.png</file>
<file>res/tool/min_hover.png</file>
<file>res/tool/min_normal.png</file>
<file>res/tool/min_press.png</file>
<file>res/tool/max_normal.png</file>
<file>res/tool/option_normal.png</file>
<file>res/tool/unmax_normal.png</file>
<file>res/tool/max_press.png</file>
<file>res/tool/max_hover.png</file>
<file>res/tool/option_hover.png</file>
<file>res/tool/option_press.png</file>
<file>res/tool/close_normal.png</file>
<file>res/tool/unmax_press.png</file>
<file>res/tool/unmax_hover.png</file>
<file>res/tool/close_hover.png</file>
<file>res/tool/close_press.png</file>
<file>res/arrow_right.png</file>
<file>res/search.png</file>
</qresource>
<qresource prefix="/sys">
<file>res/sysBtn/close_button.png</file>

View File

@ -688,11 +688,11 @@ inline bool isRunningInstalled() {
return installed;
}
inline QString getAppDirectory() {
inline QString getPluginsDirectory() {
if (isRunningInstalled()) {
return QString("/var/lib/kylin-assistant-daemon/");
return QString("/usr/lib/kylin-assistant/plugins/");
} else {
return QString(QCoreApplication::applicationDirPath());
return QString(QCoreApplication::applicationDirPath() + "plugins/");
}
}
@ -799,7 +799,7 @@ void MainWindow::initOtherPages()
bottomStack->addWidget(setting_widget);
if(box_widget == NULL)
box_widget = new BoxWidget(this, this->arch, this->osName, getAppDirectory());
box_widget = new BoxWidget(this, this->arch, this->osName, getPluginsDirectory());
box_widget->setSessionDbusProxy(sessioninterface);
connect(box_widget, SIGNAL(sendSubIndex(int)), this, SLOT(displaySubPage(int)));
bottomStack->addWidget(box_widget);

View File

@ -39,7 +39,7 @@ PluginManager* PluginManager::Instance()
bool PluginManager::loadPlugin(QString plugin_path)
{
QDir pluginsDir(plugin_path + "/libs");
QDir pluginsDir(plugin_path/* + "/libs"*/);
foreach (QString fileName, pluginsDir.entryList(QStringList("*.so"),QDir::Files)) {
QPluginLoader *pluginLoader = new QPluginLoader(pluginsDir.absoluteFilePath(fileName));
QObject *plugin = pluginLoader->instance();
@ -48,9 +48,16 @@ bool PluginManager::loadPlugin(QString plugin_path)
if (interface) {
QString guid = interface->getGuid();
plugin_map.insert(guid, pluginLoader);
qDebug() << "The plugin interface is: " << interface;
}
else {
qWarning() << pluginLoader->errorString();
pluginLoader->unload();
pluginLoader->deleteLater();
}
}
else {
qDebug() << "The plugin is invalid===" << pluginLoader->errorString();
delete pluginLoader;
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/res/arrow_right.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

BIN
src/res/arrow_up_hover.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/res/arrow_up_normal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/res/arrow_up_press.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -692,3 +692,92 @@ QCheckBox::indicator:checked:hover {
QCheckBox::indicator:checked:pressed {
image: url(://res/checkbox-checked.png);
}
QLabel#TooltipLabel {
background-color: rgba(255, 255, 255, .9);
border: 1px solid rgba(0, 0, 0, .1);
border-radius: 3px;
padding: 4px 7px 4px 7px;
color: #303030;
font-size: 12px;
font-weight: light;
}
MyImageButton#ClearIcon {
background-color:transparent;
qproperty-normalPic: url(:/res/delete.png);
qproperty-hoverPic: url(:/res/delete.png);
qproperty-pressPic: url(:/res/delete.png);
}
MyImageButton#DiskDetailButton {
qproperty-normalPic: url(:/res/tool/arrow_right.png);
qproperty-hoverPic: url(:/res/tool/arrow_right.png);
qproperty-pressPic: url(:/res/tool/arrow_right.png);
}
MyImageButton#CloseButton {
qproperty-normalPic: url(:/res/tool/close_normal.png);
qproperty-hoverPic: url(:/res/tool/close_hover.png);
qproperty-pressPic: url(:/res/tool/close_press.png);
}
MyImageButton#MinButton {
qproperty-normalPic: url(:/res/tool/min_normal.png);
qproperty-hoverPic: url(:/res/tool/min_hover.png);
qproperty-pressPic: url(:/res/tool/min_press.png);
}
MyImageButton#MaxButton {
qproperty-normalPic: url(:/res/tool/max_normal.png);
qproperty-hoverPic: url(:/res/tool/max_hover.png);
qproperty-pressPic: url(:/res/tool/max_press.png);
}
MyImageButton#UnMaxButton {
qproperty-normalPic: url(:/res/tool/unmax_normal.png);
qproperty-hoverPic: url(:/res/tool/unmax_hover.png);
qproperty-pressPic: url(:/res/tool/unmax_press.png);
}
MyTipImageButton#ProcessBtn {
qproperty-normalPic: url(:/res/browser_logo_gray.png);
qproperty-hoverPic: url(:/res/browser_logo.png);
qproperty-pressPic: url(:/res/browser_logo.png);
qproperty-checkedPic: url(:/res/browser_logo.png);
}
MyTipImageButton#ResourcesBtn {
qproperty-normalPic: url(:/res/cache_logo_gray.png);
qproperty-hoverPic: url(:/res/cache_logo.png);
qproperty-pressPic: url(:/res/cache_logo.png);
qproperty-checkedPic: url(:/res/cache_logo.png);
}
MyTipImageButton#DisksBtn {
qproperty-normalPic: url(:/res/cookie_logo_gray.png);
qproperty-hoverPic: url(:/res/cookie_logo.png);
qproperty-pressPic: url(:/res/cookie_logo.png);
qproperty-checkedPic: url(:/res/cookie_logo.png);
}
MyImageButton#ActiveProcessBtn {
qproperty-normalPic: url(:/res/browser_logo_gray.png);
qproperty-hoverPic: url(:/res/browser_logo.png);
qproperty-pressPic: url(:/res/browser_logo.png);
qproperty-checkedPic: url(:/res/browser_logo.png);
}
MyImageButton#UserProcessBtn {
qproperty-normalPic: url(:/res/cache_logo_gray.png);
qproperty-hoverPic: url(:/res/cache_logo.png);
qproperty-pressPic: url(:/res/cache_logo.png);
qproperty-checkedPic: url(:/res/cache_logo.png);
}
MyImageButton#AllProcessBtn {
qproperty-normalPic: url(:/res/cookie_logo_gray.png);
qproperty-hoverPic: url(:/res/cookie_logo.png);
qproperty-pressPic: url(:/res/cookie_logo.png);
qproperty-checkedPic: url(:/res/cookie_logo.png);
}

BIN
src/res/search.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/res/tool/max_hover.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
src/res/tool/max_normal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/res/tool/max_press.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
src/res/tool/min_hover.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/res/tool/min_normal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/res/tool/min_press.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Some files were not shown because too many files have changed in this diff Show More