add system monitor plugin
|
@ -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
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
TEMPLATE = subdirs
|
||||
SUBDIRS = \
|
||||
src \
|
||||
shredmanager \
|
||||
processmanager \
|
||||
plugins \
|
||||
backends
|
||||
|
||||
TRANSLATIONS += \
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
TEMPLATE = subdirs
|
||||
SUBDIRS = \
|
||||
shredmanager \
|
||||
systemmonitor
|
|
@ -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;
|
|
@ -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:
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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());
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 +")");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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] );
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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_
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}*/
|
|
@ -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
|
|
@ -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
|
||||
}
|
|
@ -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();
|
||||
};
|
|
@ -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"));
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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, ¢iseconds, 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]));
|
||||
}
|
||||
|
|
@ -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);
|
|
@ -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);
|
||||
}
|
|
@ -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();//获取内容
|
||||
// }
|
||||
}
|
|
@ -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;
|
||||
};
|
|
@ -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>
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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");
|
||||
}
|
|
@ -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
|
23
src/img.qrc
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
266892
src/qrc_img.cpp
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
|
@ -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);
|
||||
}
|
||||
|
|
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.2 KiB |