2018-01-04 09:50:32 +08:00
/*
2018-01-17 11:45:16 +08:00
* Copyright ( C ) 2013 ~ 2018 National University of Defense Technology ( NUDT ) & Tianjin Kylin Ltd .
2018-01-04 09:50:32 +08:00
*
* 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"
2018-01-23 18:44:44 +08:00
# include "processcategory.h"
2018-01-04 09:50:32 +08:00
# include "util.h"
# include <QStringList>
# include <QCloseEvent>
# include <QBitmap>
# include <QPainter>
# include <QFileDialog>
# include <QDir>
# include <QDebug>
# include <QHeaderView>
# include <QDesktopServices>
# include <QApplication>
2018-01-23 18:44:44 +08:00
# include <QHBoxLayout>
2018-01-04 09:50:32 +08:00
# include <QDebug>
# include <QDir>
# include <QList>
# include <QProcess>
# include <QStyleFactory>
# include <QToolTip>
2018-01-17 11:45:16 +08:00
# include <QProcess>
2018-01-04 09:50:32 +08:00
# 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 ;
}
2018-01-22 16:37:35 +08:00
ProcessDialog : : ProcessDialog ( QList < bool > toBeDisplayedColumns , int currentSortIndex , bool isSort , QSettings * settings , QWidget * parent )
2018-01-04 09:50:32 +08:00
: QWidget ( parent )
, num_cpus ( 0 )
, frequency ( 0U )
, proSettings ( settings )
{
2018-01-17 11:45:16 +08:00
setSizePolicy ( QSizePolicy : : Preferred , QSizePolicy : : Preferred ) ;
2018-01-04 09:50:32 +08:00
setAttribute ( Qt : : WA_NoMousePropagation ) ;
qRegisterMetaType < ProcDataPtr > ( ) ;
qRegisterMetaTypeStreamOperators < ProcDataPtr > ( ) ;
qRegisterMetaType < ProcDataPtrList > ( ) ;
qRegisterMetaType < QList < ProcData > > ( ) ;
2018-01-22 16:37:35 +08:00
actionPids = new QList < pid_t > ( ) ;
2018-01-23 18:44:44 +08:00
m_layout = new QVBoxLayout ( this ) ;
m_layout - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
m_layout - > setSpacing ( 0 ) ;
2018-01-04 09:50:32 +08:00
2018-01-22 16:37:35 +08:00
m_processListWidget = new ProcessListWidget ( toBeDisplayedColumns ) ;
2018-01-04 09:50:32 +08:00
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 ) ) ) ;
2018-01-22 16:37:35 +08:00
connect ( m_processListWidget , & ProcessListWidget : : rightMouseClickedItems , this , & ProcessDialog : : popupMenu , Qt : : QueuedConnection ) ;
2018-01-23 18:44:44 +08:00
m_layout - > addWidget ( m_processListWidget ) ;
2018-01-04 09:50:32 +08:00
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 ;
}
2018-01-23 18:44:44 +08:00
QWidget * w = new QWidget ;
w - > setFixedHeight ( 50 ) ;
m_categoryLayout = new QHBoxLayout ( w ) ;
m_categoryLayout - > setContentsMargins ( 0 , 0 , 6 , 3 ) ;
m_categoryLayout - > setSpacing ( 10 ) ;
processCategory = new ProcessCategory ( tabIndex ) ;
connect ( processCategory , SIGNAL ( activeWhoseProcessList ( int ) ) , this , SLOT ( onActiveWhoseProcess ( int ) ) ) ;
m_categoryLayout - > addWidget ( processCategory , 0 , Qt : : AlignRight ) ;
m_layout - > addWidget ( w ) ;
2018-01-04 09:50:32 +08:00
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 ) ;
2018-01-22 16:37:35 +08:00
m_processListWidget - > setProcessSortFunctions ( sortFuncList , currentSortIndex , isSort ) ;
2018-01-04 09:50:32 +08:00
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. \n Are 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. \n Are 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 ) ;
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 ) ;
2018-01-04 17:00:23 +08:00
// 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"));
2018-01-04 09:50:32 +08:00
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 ) ; //杀死
2018-01-04 17:00:23 +08:00
// m_menu->addSeparator();
// m_menu->addMenu(m_priorityMenu);
2018-01-04 09:50:32 +08:00
m_menu - > addSeparator ( ) ;
m_menu - > addAction ( m_propertiyAction ) ;
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 ;
}
2018-01-23 18:44:44 +08:00
delete processCategory ;
2018-01-04 09:50:32 +08:00
delete endProcessDialog ;
delete killProcessDialog ;
delete m_processListWidget ;
delete m_stopAction ;
delete m_continueAction ;
delete m_endAction ;
delete m_killAction ;
2018-01-04 17:00:23 +08:00
// delete veryHighAction;
// delete highAction;
// delete normalAction;
// delete lowAction;
// delete veryLowAction;
// delete customAction;
// delete m_priorityMenu;
2018-01-04 09:50:32 +08:00
delete m_propertiyAction ;
delete m_menu ;
delete actionPids ;
2018-01-23 18:44:44 +08:00
QLayoutItem * child ;
while ( ( child = m_categoryLayout - > takeAt ( 0 ) ) ! = 0 ) {
if ( child - > widget ( ) )
child - > widget ( ) - > deleteLater ( ) ;
delete child ;
}
delete m_layout ;
2018-01-04 09:50:32 +08:00
}
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 ( ) ;
}
2018-01-17 11:45:16 +08:00
QString rootCommand ( QString command , int value , pid_t pid )
{
return QString ( " gksu \" %1 %1 %1 \" " ) . arg ( command , value , pid ) ;
}
void startRenice ( QString command , int value , pid_t pid )
{
QProcess : : startDetached ( rootCommand ( command , value , pid ) ) ;
}
2018-01-04 09:50:32 +08:00
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 ;
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!!! " ;
2018-01-17 11:45:16 +08:00
//kobe test
//startRenice("renice", nice, cur_pid);
2018-01-04 09:50:32 +08:00
bool success = false ;
QString command = QString ( " renice %1 %1 " ) . arg ( nice ) . arg ( cur_pid ) ;
QFile file ( " /usr/bin/pkexec " ) ;
if ( file . exists ( ) ) {
2018-01-22 16:37:35 +08:00
// gint *exit_status = NULL;
// GError *error = NULL;
2018-01-04 09:50:32 +08:00
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 ) ;
//---------------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 ( ) ) {
addition . remove ( info ) ;
ProcessWorker : : all . erase ( it ) ;
delete info ;
}
it = next ;
}
QList < ProcessListItem * > items ;
for ( ProcessWorker : : Iterator it ( ProcessWorker : : begin ( ) ) ; it ! = ProcessWorker : : end ( ) ; + + it ) {
QString username = QString : : fromStdString ( it - > second - > user ) ;
long nice = it - > second - > nice ;
QString name = QString : : fromStdString ( it - > second - > name ) ;
QString session ;
if ( it - > second - > session ) {
session = QString ( it - > second - > session ) ;
}
QString status = formatProcessState ( it - > second - > status ) ;
2018-01-24 18:30:21 +08:00
2018-01-04 09:50:32 +08:00
uint cpu = it - > second - > pcpu ;
long memory = it - > second - > mem ;
pid_t pid = it - > second - > pid ;
/*---------------------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 ) ;
}
2018-01-04 17:00:23 +08:00
/*if (count == 1) {
2018-01-04 09:50:32 +08:00
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 ) ;
2018-01-04 17:00:23 +08:00
} */
2018-01-04 09:50:32 +08:00
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 ) ;
}
2018-01-24 18:30:21 +08:00
/*void ProcessDialog::paintEvent(QPaintEvent *event)
{
QPainter painter ( this ) ;
painter . setRenderHint ( QPainter : : Antialiasing , true ) ;
//绘制背景色
// QPainterPath path;
// path.addRect(QRectF(rect()));
// painter.setOpacity(1);
// painter.fillPath(path, QColor("#FFFFFF"));
//绘制圆角矩形
// painter.setPen(QPen(QColor("#0d87ca"), 0));//边框颜色 QColor(255, 255, 255, 153)
// painter.setBrush(QColor("#e9eef0"));//背景色 #0d87ca
painter . setPen ( QPen ( QColor ( " #0000FF " ) , 0 ) ) ; //边框颜色 QColor(255, 255, 255, 153)
painter . setBrush ( QColor ( " #B22222 " ) ) ; //背景色 #0d87ca
painter . setOpacity ( 1 ) ;
// QRectF r(0 / 2.0, 0 / 2.0, width() - 0, height() - 0);//左边 上边 右边 下边
QRectF r ( 2 , 2 , width ( ) - 0 , height ( ) - 0 ) ; //左边 上边 右边 下边
painter . drawRoundedRect ( r , 10 , 10 ) ;
QWidget : : paintEvent ( event ) ;
} */