|
|
|
/*
|
|
|
|
* qps.cpp
|
|
|
|
* This file is part of qps -- Qt-based visual process status monitor
|
|
|
|
*
|
|
|
|
* Copyright 1997-1999 Mattias Engdegård
|
|
|
|
* Copyright 2005-2012 fasthyun@magicn.com
|
|
|
|
* Copyright 2015- daehyun.yang@gmail.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; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* 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, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
|
|
* MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// TODO & MEMO
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* For easy maintance
|
|
|
|
* 1. F_CMDLINE should be rightmost field
|
|
|
|
* 2. F_PROCESSNAME shoud be leftmost field and NEVER removed!
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
// . Memory Hole or Qt's string allocate bug?
|
|
|
|
// . clipboard copy [CMDLINE,PID,USERNAME...]
|
|
|
|
// . [klog] table cache.
|
|
|
|
// . save sort of tree, linear
|
|
|
|
// . watchdog showmsg substitude
|
|
|
|
// . history system
|
|
|
|
// . cmd [w] analsys: [IDLE] [WHAT]
|
|
|
|
// . ExecWindow - [running] finish.
|
|
|
|
// . UNIX Domain SOCKET
|
|
|
|
// . COLOR : orange FF5d00
|
|
|
|
// . P_MEM -> P_%MEM or P_PMEM
|
|
|
|
|
|
|
|
#include "../icon/icon.xpm"
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/resource.h>
|
|
|
|
#include <sys/utsname.h> // uname
|
|
|
|
#include <signal.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <sched.h>
|
|
|
|
#include <unistd.h> //for sleep
|
|
|
|
|
|
|
|
#include "qps.h"
|
|
|
|
#include "qpsapp.h"
|
|
|
|
#include "dialogs.h"
|
|
|
|
#include "commanddialog.h"
|
|
|
|
#include "commandutils.h"
|
|
|
|
#include "watchcond.h"
|
|
|
|
#include "watchdogdialog.h"
|
|
|
|
#include "lookup.h"
|
|
|
|
#include "misc.h"
|
|
|
|
|
|
|
|
#ifndef USING_PCH
|
|
|
|
#include <QBitmap>
|
|
|
|
#include <QTimerEvent>
|
|
|
|
#include <QVBoxLayout>
|
|
|
|
#include <QShortcut>
|
|
|
|
#include <QMenuBar>
|
|
|
|
#include <QFont>
|
|
|
|
#include <QFontComboBox>
|
|
|
|
#include <QToolTip>
|
|
|
|
#include <QTabWidget>
|
|
|
|
#include <QApplication>
|
|
|
|
#include <QCheckBox>
|
|
|
|
#include <QToolButton>
|
|
|
|
#include <QMessageBox>
|
|
|
|
#include <QSessionManager>
|
|
|
|
#include <QTextEdit>
|
|
|
|
#include <QSystemTrayIcon>
|
|
|
|
#include <QSplitter>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <QDockWidget>
|
|
|
|
#include <QSplitter>
|
|
|
|
/* --------------------- Global Variable START ---------------------- */
|
|
|
|
QList<Command *> commands;
|
|
|
|
|
|
|
|
bool previous_flag_show_thread_prev = false; // previous state
|
|
|
|
bool flag_show_thread = false; // to see informations at the thread level
|
|
|
|
int flag_thread_ok = true; // we presume a kernel 2.6.x using NPTL
|
|
|
|
bool flag_session_start = false;
|
|
|
|
bool flag_start_mini = false; // Need for Xorg.Session
|
|
|
|
bool flag_refresh = true; // DEL
|
|
|
|
bool flag_xcompmgr = false; // DEL test.compiz..
|
|
|
|
bool flag_devel = false;
|
|
|
|
bool flag_schedstat = false;
|
|
|
|
bool flag_smallscreen = false;
|
|
|
|
bool flag_firstRun = true; // test
|
|
|
|
|
|
|
|
Qps *qps;
|
|
|
|
// ControlBar *controlbar=NULL;
|
|
|
|
SearchBox *search_box = NULL;
|
|
|
|
TFrame *infobox = NULL; // testing
|
|
|
|
// DEL Screenshot *screenshot=NULL;
|
|
|
|
QFontComboBox *font_cb = NULL;
|
|
|
|
WatchdogDialog *watchdogDialog = NULL;
|
|
|
|
|
|
|
|
/// PDisplay *pdisplay;
|
|
|
|
|
|
|
|
QList<Procview *> proclist;
|
|
|
|
|
|
|
|
#include "trayicon.h"
|
|
|
|
TrayIcon *trayicon = NULL;
|
|
|
|
|
|
|
|
// for Non-ASCII Languages (CJK:chinese,japanese,korean, arabic ...)
|
|
|
|
#include <QTextCodec>
|
|
|
|
QTextCodec *codec = NULL;
|
|
|
|
#define UniString(str) str // codec->toUnicode(str)
|
|
|
|
/* ------------------------ END global variables -------------------------- */
|
|
|
|
|
|
|
|
// default values of settings, overridden by $HOME/.qpsrc if present
|
|
|
|
bool Qps::flag_show =
|
|
|
|
true; // window state of last run : mini(iconic) or normal window
|
|
|
|
bool Qps::flag_exit = true;
|
|
|
|
bool Qps::flag_qps_hide = true; // TEST
|
|
|
|
bool Qps::flag_useTabView = false;
|
|
|
|
bool Qps::show_file_path = false;
|
|
|
|
bool Qps::show_cmd_path = true;
|
|
|
|
bool Qps::show_infobar = true;
|
|
|
|
bool Qps::show_ctrlbar = true;
|
|
|
|
bool Qps::show_cpu_bar = true;
|
|
|
|
bool Qps::show_load_graph = true; // DEL
|
|
|
|
bool Qps::show_statusbar = true;
|
|
|
|
bool Qps::load_in_icon = true;
|
|
|
|
bool Qps::auto_save_options = true;
|
|
|
|
#ifdef LINUX
|
|
|
|
bool Qps::hostname_lookup = true;
|
|
|
|
bool Qps::service_lookup = true;
|
|
|
|
#endif
|
|
|
|
bool Qps::pids_to_selection = true;
|
|
|
|
bool Qps::vertical_cpu_bar = false; // not used
|
|
|
|
#ifdef SOLARIS
|
|
|
|
bool Qps::normalize_nice = true;
|
|
|
|
bool Qps::use_pmap = true;
|
|
|
|
#endif
|
|
|
|
bool Qps::tree_gadgets = true;
|
|
|
|
bool Qps::tree_lines = true;
|
|
|
|
int Qps::swaplimit = 5; // default: warn when less than 10% swap left
|
|
|
|
bool Qps::swaplim_percent = true;
|
|
|
|
|
|
|
|
QThread *thread_main = 0;
|
|
|
|
|
|
|
|
Qps::Qps()
|
|
|
|
{
|
|
|
|
setObjectName("qps_main_window");
|
|
|
|
timer_id = 0;
|
|
|
|
field_win = 0;
|
|
|
|
prefs_win = 0;
|
|
|
|
command_win = 0;
|
|
|
|
default_icon = 0;
|
|
|
|
default_icon_set = false;
|
|
|
|
|
|
|
|
setIconSize(24, 24); // Important!!
|
|
|
|
// setMouseTracking(true); // no need?
|
|
|
|
|
|
|
|
if (flag_devel)
|
|
|
|
{
|
|
|
|
thread_main = thread(); // Test
|
|
|
|
printf("qps thread =%p , qApp thread =%p\n", thread(),
|
|
|
|
QApplication::instance()->thread());
|
|
|
|
}
|
|
|
|
|
|
|
|
// watchdogDialog = new WatchdogDialog; //Memory Leak
|
|
|
|
|
|
|
|
// font_cb=new QFontComboBox(this); // preload
|
|
|
|
// font_cb->setWritingSystem ( QFontDatabase::Latin );
|
|
|
|
// font_cb->hide();
|
|
|
|
|
|
|
|
make_signal_popup_menu();
|
|
|
|
|
|
|
|
// MOVETO Pstable !!
|
|
|
|
m_headpopup = new QMenu("header_popup", this);
|
|
|
|
m_headpopup->addAction("Remove Field", this, SLOT(menu_remove_field()));
|
|
|
|
m_fields = new QMenu("Add Field", this);
|
|
|
|
m_headpopup->addMenu(m_fields);
|
|
|
|
// connect(m_fields, SIGNAL(activated(int)),
|
|
|
|
// SLOT(add_fields_menu(int)));
|
|
|
|
// m_headpopup->addAction("Select Field", this, SLOT(menu_custom()) );
|
|
|
|
|
|
|
|
m_command = new QMenu("Command", this); // filled in later
|
|
|
|
|
|
|
|
QAction *act;
|
|
|
|
|
|
|
|
m_view = new QMenu("View", this);
|
|
|
|
act = m_view->addAction("Process"); // act->setData(Procview::CUSTOM);
|
|
|
|
act = m_view->addAction("Log"); // act->setData(Procview::CUSTOM);
|
|
|
|
// m_view->hide();
|
|
|
|
|
|
|
|
m_field = new QMenu("Field", this);
|
|
|
|
act = m_field->addAction("Custom Fields");
|
|
|
|
act->setData(Procview::CUSTOM);
|
|
|
|
act = m_field->addAction("Basic Fields ");
|
|
|
|
act->setData(Procview::USER);
|
|
|
|
act = m_field->addAction("Jobs Fields ");
|
|
|
|
act->setData(Procview::JOBS);
|
|
|
|
act = m_field->addAction("Memory Fields ");
|
|
|
|
act->setData(Procview::MEM);
|
|
|
|
#ifdef LINUX
|
|
|
|
act = m_field->addAction("Scheduling Fields ");
|
|
|
|
act->setData(Procview::SCHED);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
m_field->addSeparator();
|
|
|
|
act = m_field->addAction(QIcon::fromTheme(QStringLiteral("edit-find-replace")),
|
|
|
|
"Select Custom Fields...", this,
|
|
|
|
SLOT(menu_custom()));
|
|
|
|
act->setData(MENU_CUSTOM);
|
|
|
|
|
|
|
|
connect(m_field, SIGNAL(triggered(QAction *)), this,
|
|
|
|
SLOT(view_menu(QAction *)));
|
|
|
|
connect(m_field, SIGNAL(aboutToShow()), SLOT(update_menu_status()));
|
|
|
|
|
|
|
|
/// connect(m_view, SIGNAL(triggered(QAction *)),this,
|
|
|
|
/// SLOT(view_menu(QAction
|
|
|
|
/// *)));
|
|
|
|
/// connect(m_view, SIGNAL(aboutToShow ()), SLOT(update_menu_status()));
|
|
|
|
|
|
|
|
m_options = new QMenu("Option", this);
|
|
|
|
m_options->addAction("Update Period...", this, SLOT(menu_update()));
|
|
|
|
m_options->addSeparator();
|
|
|
|
act = m_options->addAction("", /* MENU_PATH */ this,
|
|
|
|
SLOT(menu_toggle_path()));
|
|
|
|
act->setData(QVariant(MENU_PATH));
|
|
|
|
act = m_options->addAction("", this, SLOT(menu_toggle_infobar()));
|
|
|
|
act->setData(QVariant(MENU_INFOBAR));
|
|
|
|
act = m_options->addAction("", this, SLOT(menu_toggle_ctrlbar()));
|
|
|
|
act->setData(QVariant(MENU_CTRLBAR));
|
|
|
|
act = m_options->addAction("Show Status bar", this,
|
|
|
|
SLOT(menu_toggle_statusbar()));
|
|
|
|
act->setData(QVariant(MENU_STATUS));
|
|
|
|
act = m_options->addAction("", this, SLOT(menu_toggle_cumul()));
|
|
|
|
act->setData(QVariant(MENU_CUMUL));
|
|
|
|
|
|
|
|
m_options->addSeparator();
|
|
|
|
m_options->addAction(QIcon::fromTheme(QStringLiteral("preferences-system")),
|
|
|
|
"Preferences...", this,
|
|
|
|
SLOT(menu_prefs())); // MENU_PREFS
|
|
|
|
|
|
|
|
connect(m_options, SIGNAL(aboutToShow()), SLOT(update_menu_status()));
|
|
|
|
|
|
|
|
QMenu *m_help = new QMenu("&Help", this);
|
|
|
|
// m_help->addAction("FAQ", this, SLOT(license()));
|
|
|
|
m_help->addAction(QIcon::fromTheme("help-about"), "&About", this,
|
|
|
|
SLOT(about()));
|
|
|
|
|
|
|
|
// menu = new QMenuBar(this);
|
|
|
|
menubar = new QMenuBar;
|
|
|
|
menubar->addMenu(m_command);
|
|
|
|
// am_view=menubar->addMenu(m_view);
|
|
|
|
menubar->addMenu(m_field);
|
|
|
|
menubar->addMenu(m_options);
|
|
|
|
menubar->addSeparator();
|
|
|
|
menubar->addMenu(m_help);
|
|
|
|
|
|
|
|
ctrlbar = new ControlBar(this);
|
|
|
|
// controlbar=ctrlbar;
|
|
|
|
|
|
|
|
connect(ctrlbar, SIGNAL(need_refresh()), SLOT(refresh()));
|
|
|
|
connect(ctrlbar, SIGNAL(viewChange(QAction *)),
|
|
|
|
SLOT(view_menu(QAction *))); //?????
|
|
|
|
|
|
|
|
context_col = -1;
|
|
|
|
|
|
|
|
procview = new Procview(); // refresh() only not rebuild()
|
|
|
|
/// procview = new Procview("localhost"); // refresh() only not rebuild()
|
|
|
|
/// procview->refresh(); // TODO
|
|
|
|
/// proclist.append(procview);
|
|
|
|
/// procview->start(); // thread start
|
|
|
|
|
|
|
|
#ifdef HTABLE2
|
|
|
|
pstable = new Pstable2(this, procview); //
|
|
|
|
#else
|
|
|
|
pstable = new Pstable(this, procview); // no refresh()
|
|
|
|
#endif
|
|
|
|
PDisplay *display = new PDisplay(this);
|
|
|
|
infobar = display->addSystem(procview);
|
|
|
|
//. infobar = new Infobar(this,procview); // graph_bar
|
|
|
|
// infobar = new Infobar(procview); // graph_bar
|
|
|
|
statusBar = new StatusBar(this);
|
|
|
|
|
|
|
|
if (!read_settings())
|
|
|
|
{
|
|
|
|
// printf("default value\n");
|
|
|
|
set_update_period(1300); // default
|
|
|
|
resize(640, 370); // default initial size
|
|
|
|
}
|
|
|
|
|
|
|
|
set_table_mode(procview->treeview); // Pstable::refresh() occur
|
|
|
|
make_command_menu(); // after qpsrc reading
|
|
|
|
|
|
|
|
// misc. accelerators
|
|
|
|
QShortcut *c1 =
|
|
|
|
new QShortcut(Qt::CTRL + Qt::Key_Q, this, SLOT(save_quit()));
|
|
|
|
QShortcut *c3 = new QShortcut(Qt::CTRL + Qt::Key_Space,
|
|
|
|
ctrlbar->pauseButton, SLOT(click()));
|
|
|
|
QShortcut *c2 =
|
|
|
|
new QShortcut(Qt::CTRL + Qt::Key_L, pstable, SLOT(repaintAll()));
|
|
|
|
|
|
|
|
// MOVETO : pstable better? hmmm...
|
|
|
|
// where is leftClick?
|
|
|
|
connect(pstable, SIGNAL(doubleClicked(int)), SLOT(open_details(int)));
|
|
|
|
connect(pstable, SIGNAL(rightClicked(QPoint)), this,
|
|
|
|
SLOT(show_popup_menu(QPoint)));
|
|
|
|
connect(pstable->header(), SIGNAL(rightClicked(QPoint, int)), this,
|
|
|
|
SLOT(context_heading_menu(QPoint, int)));
|
|
|
|
// connect(netable, SIGNAL(rightClicked(QPoint)), this,
|
|
|
|
// SLOT(context_row_menu(QPoint)));
|
|
|
|
|
|
|
|
selection_items_enabled = true; // ????
|
|
|
|
update_load_time = 0;
|
|
|
|
//// update_menu_status();
|
|
|
|
|
|
|
|
QVBoxLayout *vlayout = new QVBoxLayout;
|
|
|
|
vlayout->setMargin(0);
|
|
|
|
if (flag_useTabView)
|
|
|
|
vlayout->setSpacing(0);
|
|
|
|
else
|
|
|
|
vlayout->setSpacing(1);
|
|
|
|
|
|
|
|
// vlayout->addWidget(menu);
|
|
|
|
vlayout->setMenuBar(menubar);
|
|
|
|
vlayout->addWidget(display);
|
|
|
|
// vlayout->addWidget( infobar);
|
|
|
|
vlayout->addWidget(ctrlbar);
|
|
|
|
|
|
|
|
/// vlayout->addSpacing(5);
|
|
|
|
|
|
|
|
// if(flag_devel){
|
|
|
|
if (0)
|
|
|
|
{
|
|
|
|
if (0)
|
|
|
|
{
|
|
|
|
QSplitter *splitter = new QSplitter(Qt::Vertical);
|
|
|
|
QDockWidget *dock = new QDockWidget(tr("Detail"), this);
|
|
|
|
dock->setFeatures(QDockWidget::DockWidgetClosable);
|
|
|
|
// dock->setWidget();
|
|
|
|
// dock->setAllowedAreas(Qt::LeftDockWidgetArea |
|
|
|
|
// Qt::RightDockWidgetArea);
|
|
|
|
// customerList = new QListWidget(dock);
|
|
|
|
// vlayout->addStretch();
|
|
|
|
splitter->addWidget(pstable);
|
|
|
|
splitter->addWidget(dock);
|
|
|
|
vlayout->addWidget(splitter);
|
|
|
|
vlayout->addWidget(statusBar);
|
|
|
|
setLayout(vlayout);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
logbox = new QTextEdit(this);
|
|
|
|
logbox->setReadOnly(true);
|
|
|
|
|
|
|
|
if (0) // if(flag_smallscreen==false)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vlayout->addWidget(pstable);
|
|
|
|
vlayout->addWidget(logbox);
|
|
|
|
logbox->hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
vlayout->addWidget(statusBar);
|
|
|
|
setLayout(vlayout);
|
|
|
|
|
|
|
|
infobox = new TFrame(this);
|
|
|
|
// setAttribute(Qt::WA_ShowWithoutActivating);
|
|
|
|
if (update_period != eternity)
|
|
|
|
Qps::update_timer(); // startTimer(update_period);
|
|
|
|
/// setFocusPolicy (Qt::WheelFocus);
|
|
|
|
|
|
|
|
bar_visibility(); // need
|
|
|
|
|
|
|
|
// testing
|
|
|
|
popupx = new QMenu("test", this);
|
|
|
|
popupx->addAction("Copied to Clipboard");
|
|
|
|
}
|
|
|
|
|
|
|
|
// explicit destructor needed for gcc
|
|
|
|
Qps::~Qps() {}
|
|
|
|
void Qps::tabChanged(int idx)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
for(int i; i<1024;i++)
|
|
|
|
{
|
|
|
|
QFont font;
|
|
|
|
if(font_cb)
|
|
|
|
font=font_cb->currentFont();
|
|
|
|
//font=font_cb->currentFont();
|
|
|
|
QApplication::setFont(font);
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("tab\n");
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (idx == 0)
|
|
|
|
{
|
|
|
|
procview->viewproc = Procview::ALL;
|
|
|
|
pstable->refresh();
|
|
|
|
// pstable->update();
|
|
|
|
}
|
|
|
|
else if (idx == 1)
|
|
|
|
{
|
|
|
|
// procview->viewproc=Procview::NETWORK;
|
|
|
|
// netable->refresh();
|
|
|
|
// netable->update();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// return true if all selected processes are stopped
|
|
|
|
bool Qps::all_selected_stopped()
|
|
|
|
{
|
|
|
|
for (int i = 0; i < procview->linear_procs.size(); i++)
|
|
|
|
{
|
|
|
|
Procinfo *p = procview->linear_procs[i];
|
|
|
|
if (p->selected && p->state != 'T')
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Adjust menu to contain Stop or Continue
|
|
|
|
void Qps::adjust_popup_menu(QMenu *m, bool cont)
|
|
|
|
{
|
|
|
|
// int idx = m->indexOf(MENU_DETAILS);
|
|
|
|
if (procview->treeview == true)
|
|
|
|
{
|
|
|
|
// m->setItemVisible (MENU_PARENT,false);
|
|
|
|
// m->setItemVisible (MENU_CHILD,false);
|
|
|
|
// m->setItemVisible (MENU_DYNASTY,false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// m->setItemVisible (MENU_PARENT,true);
|
|
|
|
// m->setItemVisible (MENU_CHILD,true);
|
|
|
|
// m->setItemVisible (MENU_DYNASTY,true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (procview->viewproc == Procview::HIDDEN)
|
|
|
|
{
|
|
|
|
// m->setItemVisible (MENU_ADD_HIDDEN,false);
|
|
|
|
// m->setItemVisible (MENU_REMOVE_HIDDEN,true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// m->setItemVisible (MENU_ADD_HIDDEN,true);
|
|
|
|
// m->setItemVisible (MENU_REMOVE_HIDDEN,false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
void Qps::adjust_popup_menu()
|
|
|
|
{
|
|
|
|
bool allstop = all_selected_stopped();
|
|
|
|
QList<QAction *> list = m_popup->actions();
|
|
|
|
// printf("adjust_popup_menu () size=%d \n",list.size());
|
|
|
|
|
|
|
|
if (allstop)
|
|
|
|
for (int i = 0; i < list.size() - 1; i++)
|
|
|
|
{
|
|
|
|
QAction *act = list[i];
|
|
|
|
int id = act->data().toInt();
|
|
|
|
if (id == MENU_SIGCONT)
|
|
|
|
act->setVisible(true);
|
|
|
|
if (id == MENU_SIGSTOP)
|
|
|
|
act->setVisible(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
for (int i = 0; i < list.size() - 1; i++)
|
|
|
|
{
|
|
|
|
QAction *act = list[i];
|
|
|
|
int id = act->data().toInt();
|
|
|
|
if (id == MENU_SIGCONT)
|
|
|
|
act->setVisible(false);
|
|
|
|
if (id == MENU_SIGSTOP)
|
|
|
|
act->setVisible(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// build signal menu (used in two places)
|
|
|
|
QMenu *Qps::make_signal_popup_menu()
|
|
|
|
{
|
|
|
|
|
|
|
|
// move to pstable?
|
|
|
|
QAction *act; // show_popup_menu() callback
|
|
|
|
m_popup = new QMenu("context popup", this);
|
|
|
|
m_popup->addAction("Renice...", this, SLOT(menu_renice()));
|
|
|
|
m_popup->addAction("Scheduling...", this, SLOT(menu_sched()));
|
|
|
|
m_popup->addSeparator();
|
|
|
|
m_popup->addAction("Terminate", this, SLOT(sig_term()),
|
|
|
|
Qt::Key_Delete); // better
|
|
|
|
m_popup->addAction("Hangup", this, SLOT(sig_hup()), Qt::ALT + Qt::Key_H);
|
|
|
|
m_popup->addAction("Kill", this, SLOT(sig_kill()), Qt::ALT + Qt::Key_K);
|
|
|
|
act = m_popup->addAction("Stop", this, SLOT(sig_stop()));
|
|
|
|
act->setData(MENU_SIGSTOP);
|
|
|
|
act = m_popup->addAction("Continue", this, SLOT(sig_cont()));
|
|
|
|
act->setData(MENU_SIGCONT);
|
|
|
|
|
|
|
|
// connect(m_popup, SIGNAL(aboutToShow ()),this,
|
|
|
|
// SLOT(adjust_popup_menu()));
|
|
|
|
/// m_popup->addAction("Find Parent", this,
|
|
|
|
/// SLOT(menu_parent()),0,MENU_PARENT);
|
|
|
|
/// m_popup->addAction("Find Children", this,
|
|
|
|
/// SLOT(menu_children()),0,MENU_CHILD);
|
|
|
|
/// m_popup->addAction("Find Descendants", this,
|
|
|
|
/// SLOT(menu_dynasty()),0,MENU_DYNASTY);
|
|
|
|
|
|
|
|
QMenu *m = new QMenu("Other Signals");
|
|
|
|
act = m->addAction("SIGINT (interrupt)");
|
|
|
|
act->setData(SIGINT);
|
|
|
|
act = m->addAction("SIGCONT (continue)");
|
|
|
|
act->setData(SIGCONT);
|
|
|
|
act = m->addAction("SIGSTOP (stop)");
|
|
|
|
act->setData(SIGSTOP);
|
|
|
|
act = m->addAction("SIGQUIT (quit)");
|
|
|
|
act->setData(SIGQUIT);
|
|
|
|
act = m->addAction("SIGILL (illegal instruction)");
|
|
|
|
act->setData(SIGILL);
|
|
|
|
act = m->addAction("SIGABRT (abort)");
|
|
|
|
act->setData(SIGABRT);
|
|
|
|
act = m->addAction("SIGFPE (floating point exception)");
|
|
|
|
act->setData(SIGFPE);
|
|
|
|
act = m->addAction("SIGSEGV (segmentation violation)");
|
|
|
|
act->setData(SIGSEGV);
|
|
|
|
act = m->addAction("SIGPIPE (broken pipe)");
|
|
|
|
act->setData(SIGPIPE);
|
|
|
|
act = m->addAction("SIGALRM (timer signal)");
|
|
|
|
act->setData(SIGALRM);
|
|
|
|
act = m->addAction("SIGUSR1 (user-defined 1)");
|
|
|
|
act->setData(SIGUSR1);
|
|
|
|
act = m->addAction("SIGUSR2 (user-defined 2)");
|
|
|
|
act->setData(SIGUSR2);
|
|
|
|
act = m->addAction("SIGCHLD (child death)");
|
|
|
|
act->setData(SIGCHLD);
|
|
|
|
act = m->addAction("SIGTSTP (stop from tty)");
|
|
|
|
act->setData(SIGTSTP);
|
|
|
|
act = m->addAction("SIGTTIN (tty input)");
|
|
|
|
act->setData(SIGTTIN);
|
|
|
|
act = m->addAction("SIGTTOU (tty output)");
|
|
|
|
act->setData(SIGTTOU);
|
|
|
|
|
|
|
|
connect(m, SIGNAL(triggered(QAction *)), SLOT(signal_menu(QAction *)));
|
|
|
|
|
|
|
|
m_popup->addMenu(m);
|
|
|
|
m_popup->addSeparator();
|
|
|
|
m_popup->addAction("View Details", this, SLOT(Action_Detail()));
|
|
|
|
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::signal_menu(QAction *act)
|
|
|
|
{
|
|
|
|
int signal = act->data().toInt();
|
|
|
|
send_to_selected(signal);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef MOSIX
|
|
|
|
|
|
|
|
// build migrate menu
|
|
|
|
static int intcmp(const int *a, const int *b) { return *a - *b; }
|
|
|
|
|
|
|
|
QMenu *Qps::make_migrate_menu()
|
|
|
|
{
|
|
|
|
QString buf;
|
|
|
|
QMenu *m = new QMenu;
|
|
|
|
Svec<int> lst = Procinfo::mosix_nodes();
|
|
|
|
lst.sort(intcmp); /// sort
|
|
|
|
m->insertItem("Home", 1);
|
|
|
|
m->insertItem("Find Best", 0);
|
|
|
|
for (int i = 0; i < lst.size(); i++)
|
|
|
|
{
|
|
|
|
buf.sprintf("to node %d", lst[i]);
|
|
|
|
m->insertItem(buf, lst[i] + 1);
|
|
|
|
}
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
#endif // MOSIX
|
|
|
|
|
|
|
|
// update the visibility of the {info, control, status} bar
|
|
|
|
void Qps::bar_visibility()
|
|
|
|
{
|
|
|
|
|
|
|
|
if (show_infobar)
|
|
|
|
infobar->show();
|
|
|
|
else
|
|
|
|
infobar->hide();
|
|
|
|
|
|
|
|
if (show_ctrlbar)
|
|
|
|
ctrlbar->show();
|
|
|
|
else
|
|
|
|
ctrlbar->hide();
|
|
|
|
|
|
|
|
if (show_statusbar)
|
|
|
|
statusBar->show();
|
|
|
|
else
|
|
|
|
statusBar->hide();
|
|
|
|
|
|
|
|
if (flag_useTabView)
|
|
|
|
{
|
|
|
|
// DEL tbar->showTab(true);
|
|
|
|
/// am_view->setVisible(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// DEL tbar->showTab(false);
|
|
|
|
// am_view->setVisible(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::timerEvent(QTimerEvent *e) { Qps::refresh(); }
|
|
|
|
//
|
|
|
|
// dialogs.cpp: qps->update_timer();
|
|
|
|
void Qps::update_timer()
|
|
|
|
{
|
|
|
|
if (timer_id)
|
|
|
|
killTimer(timer_id);
|
|
|
|
timer_id = startTimer(update_period); // *** important !!!
|
|
|
|
}
|
|
|
|
|
|
|
|
// change the update period, recomputing the averaging factor
|
|
|
|
void Qps::set_update_period(int milliseconds)
|
|
|
|
{
|
|
|
|
if (milliseconds == 0)
|
|
|
|
{
|
|
|
|
qDebug("DEBUG: set_update_period(): update= %dms \n", milliseconds);
|
|
|
|
milliseconds = 1000;
|
|
|
|
}
|
|
|
|
update_period = milliseconds;
|
|
|
|
Proc::update_msec = milliseconds; // testing transfer...
|
|
|
|
Procview::avg_factor = exp(-(float)update_period / Procview::cpu_avg_time);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::refresh()
|
|
|
|
{
|
|
|
|
if (flag_refresh == false)
|
|
|
|
return;
|
|
|
|
|
|
|
|
procview->refresh(); // important
|
|
|
|
// infobar->update_load(); // add_point and drawGraphOnPixmap();
|
|
|
|
infobar->updatePixmap(); // add_point and drawGraphOnPixmap();
|
|
|
|
|
|
|
|
if (isVisible())
|
|
|
|
{ // infobar->isVisible()
|
|
|
|
// printf("paint\n");
|
|
|
|
// if(search_box and !search_box->hasFocus())
|
|
|
|
// search_box->setFocus(Qt::OtherFocusReason);
|
|
|
|
pstable->refresh();
|
|
|
|
// if(netable and netable->isVisible())netable->refresh();
|
|
|
|
if (show_infobar) // if(Qps::show_load_graph)
|
|
|
|
infobar->update(); // TODO: thread update or
|
|
|
|
// infobar->repaint();
|
|
|
|
//==> pdisplay->update();
|
|
|
|
// DEL update_menu_selection_status(); // update pop menu
|
|
|
|
}
|
|
|
|
|
|
|
|
if (trayicon)
|
|
|
|
update_icon(); // make icon for systray
|
|
|
|
refresh_details();
|
|
|
|
}
|
|
|
|
|
|
|
|
// make next timer_refresh happen a little earlier to remove processes that
|
|
|
|
// might have died after a signal
|
|
|
|
void Qps::earlier_refresh()
|
|
|
|
{
|
|
|
|
const int delay = 500; // wait no more than this period (ms)
|
|
|
|
if (update_period > delay && update_period != eternity)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::resizeEvent(QResizeEvent *e)
|
|
|
|
{
|
|
|
|
// DEBUG("Qps::resize() w=%d\n",e->size().width());
|
|
|
|
// QWidget::resizeEvent(event);
|
|
|
|
|
|
|
|
int w;
|
|
|
|
return;
|
|
|
|
|
|
|
|
// search_box->isVisible(true); // imidiate
|
|
|
|
w = ctrlbar->sizeHint().width();
|
|
|
|
if (!search_box->isVisible())
|
|
|
|
w += search_box->sizeHint().width();
|
|
|
|
|
|
|
|
if (e->size().width() < w)
|
|
|
|
{
|
|
|
|
// ctrlbar->
|
|
|
|
search_box->hide();
|
|
|
|
}
|
|
|
|
// else search_box->show();
|
|
|
|
|
|
|
|
return;
|
|
|
|
if (e->size().width() < 639)
|
|
|
|
{
|
|
|
|
// tbar->setDrawBase (false);
|
|
|
|
flag_smallscreen = true;
|
|
|
|
statusBar->hide();
|
|
|
|
// void QTabWidget::setTabEnabled ( int index, bool enable
|
|
|
|
//)
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
flag_smallscreen = false;
|
|
|
|
statusBar->show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Description :
|
|
|
|
1. called when visible() or hide() state. QT4
|
|
|
|
2. called when clicked WINDOW_EXIT_X_BUTTON
|
|
|
|
3. NOT called when user logout (session manager)
|
|
|
|
*/
|
|
|
|
void Qps::closeEvent(QCloseEvent *e)
|
|
|
|
{
|
|
|
|
// DEBUG("DEBUG: closeEvent()....\n");
|
|
|
|
// sleep(2);
|
|
|
|
if ((Qps::flag_exit == false) and trayicon->hasSysTray())
|
|
|
|
{
|
|
|
|
e->ignore(); // dont close window!
|
|
|
|
hide();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
e->accept(); // ok. I will be exit Now !!
|
|
|
|
save_quit();
|
|
|
|
}
|
|
|
|
|
|
|
|
// call by void Qps::make_command_menu()
|
|
|
|
// void signal_handler(int sig)
|
|
|
|
void Qps::save_quit() // will be removed !
|
|
|
|
{
|
|
|
|
// printf("DEBUG: save_quit()....\n");
|
|
|
|
close(); // if another window exists, then no exit. // occurs
|
|
|
|
// QCoseEvent!
|
|
|
|
save_settings();
|
|
|
|
qApp->quit(); // MACRO
|
|
|
|
}
|
|
|
|
|
|
|
|
// NEW Version !
|
|
|
|
// : write geometry, visible fields and other settings to $HOME/.qpsrc
|
|
|
|
void Qps::save_settings()
|
|
|
|
{
|
|
|
|
if (Qps::auto_save_options)
|
|
|
|
write_settings();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::leaveEvent(QEvent *event)
|
|
|
|
{
|
|
|
|
// printf("out!xx\n"); //works well
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::enterEvent(QEvent *event)
|
|
|
|
{
|
|
|
|
// printf("in!\n"); // works well
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::showEvent(QShowEvent *event)
|
|
|
|
{
|
|
|
|
// printf("showEvent()\n");
|
|
|
|
// event->accept();
|
|
|
|
}
|
|
|
|
void Qps::mouseMoveEvent(QMouseEvent *event)
|
|
|
|
{
|
|
|
|
// printf("Qps::mouseMoveEvent\n"); //work in child surface without
|
|
|
|
// setMouseTracking(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// setFocusPolicy() should on
|
|
|
|
void Qps::focusInEvent(QFocusEvent *event)
|
|
|
|
{
|
|
|
|
// printf("focusIn\n"); // not work in compiz,Metacity
|
|
|
|
// infobar->showup();
|
|
|
|
// event->accept();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::focusOutEvent(QFocusEvent *event)
|
|
|
|
{
|
|
|
|
// printf("focusOut\n"); // not work in compiz,Metacity
|
|
|
|
// event->accept();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::keyPressEvent(QKeyEvent *event)
|
|
|
|
{
|
|
|
|
// printf("Qps::key\n"); // not work in compiz
|
|
|
|
if (search_box)
|
|
|
|
{
|
|
|
|
if (!search_box->hasFocus())
|
|
|
|
search_box->setFocus(Qt::OtherFocusReason);
|
|
|
|
search_box->keyPressEvent(event);
|
|
|
|
}
|
|
|
|
// search_box->setFocusProxy(pstable);
|
|
|
|
}
|
|
|
|
void Qps::moveEvent(QMoveEvent *event)
|
|
|
|
{
|
|
|
|
////infobar->refresh();
|
|
|
|
// printf("move\n");
|
|
|
|
}
|
|
|
|
void Qps::paintEvent(QPaintEvent *event)
|
|
|
|
{
|
|
|
|
// printf("paintEvent : Qps\n");
|
|
|
|
// update_icon();
|
|
|
|
}
|
|
|
|
void Qps::update_icon()
|
|
|
|
{
|
|
|
|
if (load_in_icon)
|
|
|
|
set_load_icon(); // always true
|
|
|
|
else
|
|
|
|
set_default_icon();
|
|
|
|
}
|
|
|
|
// called by update_icon()
|
|
|
|
void Qps::set_default_icon()
|
|
|
|
{
|
|
|
|
if (!default_icon_set)
|
|
|
|
{
|
|
|
|
if (!default_icon)
|
|
|
|
default_icon = new QPixmap((const char **)icon_xpm);
|
|
|
|
setWindowIcon(*default_icon);
|
|
|
|
default_icon_set = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::set_load_icon()
|
|
|
|
{
|
|
|
|
QPixmap *pm = infobar->load_icon(icon_width, icon_height);
|
|
|
|
if (!pm->mask())
|
|
|
|
{
|
|
|
|
// avoid a fvwm/Qt 1.30 problem and create a filled mask for the
|
|
|
|
// icon
|
|
|
|
// (without mask, Qt would attempt to use a heuristically
|
|
|
|
// created mask)
|
|
|
|
QBitmap bm(pm->size());
|
|
|
|
bm.fill(Qt::color1);
|
|
|
|
pm->setMask(bm);
|
|
|
|
}
|
|
|
|
// QApplication::setWindowIcon(*pm);
|
|
|
|
if (trayicon->hasSysTray())
|
|
|
|
{
|
|
|
|
trayicon->setIcon(*pm);
|
|
|
|
// str.sprintf("Qps %2.2f%",Procinfo::loadQps);
|
|
|
|
// trayicon->setToolTip(str);
|
|
|
|
// trayicon->showMessage("str",str);
|
|
|
|
}
|
|
|
|
// else
|
|
|
|
setWindowIcon(*pm);
|
|
|
|
// QApplication::setWindowIcon(*pm);
|
|
|
|
default_icon_set = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
QPixmap *Qps::get_load_icon()
|
|
|
|
{
|
|
|
|
return infobar->load_icon(icon_width, icon_height);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
void Qps::refresh_details()
|
|
|
|
{
|
|
|
|
//// details.first();
|
|
|
|
////Details d;
|
|
|
|
#ifdef LINUX
|
|
|
|
// Proc::invalidate_sockets();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
for (int i = 0; i < details.size(); ++i)
|
|
|
|
{
|
|
|
|
/////Details *d=details[i]
|
|
|
|
////if(details[i].isVisible())
|
|
|
|
/////details[i].refresh();
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
while((d = details.current()) != 0) {
|
|
|
|
if(d->isVisible())
|
|
|
|
d->refresh();
|
|
|
|
details.next();
|
|
|
|
} */
|
|
|
|
}
|
|
|
|
|
|
|
|
// called by
|
|
|
|
// 1.void Qps::field_removed(int index)
|
|
|
|
// ====> QMenu::aboutToShow ()
|
|
|
|
void Qps::update_menu_status()
|
|
|
|
{
|
|
|
|
// printf("update_menu_status\n");
|
|
|
|
update_menu_selection_status();
|
|
|
|
// ctrlbar->view->setCurrentItem (procview->viewproc); //???
|
|
|
|
|
|
|
|
// Field Menu
|
|
|
|
QList<QAction *> list = m_field->actions();
|
|
|
|
for (int i = 0; i < list.size() - 1; i++)
|
|
|
|
{
|
|
|
|
QAction *act = list[i];
|
|
|
|
act->setCheckable(true);
|
|
|
|
int id = act->data().toInt();
|
|
|
|
if (id == procview->viewfields)
|
|
|
|
act->setChecked(true);
|
|
|
|
else
|
|
|
|
act->setChecked(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// View Menu temporary
|
|
|
|
/*
|
|
|
|
QString str=tbar->tabText(tbar->currentIndex());
|
|
|
|
list=m_view->actions();
|
|
|
|
for(int i =0 ;i< list.size() ;i++)
|
|
|
|
{
|
|
|
|
QAction *act=list[i];
|
|
|
|
act->setCheckable(true);
|
|
|
|
|
|
|
|
if(act->text()==str)
|
|
|
|
{
|
|
|
|
act->setChecked(true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
act->setChecked(false);
|
|
|
|
} */
|
|
|
|
|
|
|
|
// Option Menu
|
|
|
|
list = m_options->actions();
|
|
|
|
for (int i = 0; i < list.size() - 1; i++)
|
|
|
|
{
|
|
|
|
QAction *act = list[i];
|
|
|
|
int id = act->data().toInt();
|
|
|
|
|
|
|
|
if (id == MENU_PATH)
|
|
|
|
{
|
|
|
|
act->setCheckable(true);
|
|
|
|
act->setChecked(Procview::flag_show_file_path);
|
|
|
|
act->setText("Show File Path");
|
|
|
|
// act->setText(Procview::flag_show_file_path?
|
|
|
|
//"Hide File Path" :
|
|
|
|
//"Show File Path");
|
|
|
|
}
|
|
|
|
else if (id == MENU_INFOBAR)
|
|
|
|
{
|
|
|
|
act->setCheckable(true);
|
|
|
|
act->setChecked(show_infobar);
|
|
|
|
act->setText("Show Graph");
|
|
|
|
// act->setText(show_infobar ? "Hide Graph" : "Show
|
|
|
|
// Graph");
|
|
|
|
}
|
|
|
|
else if (id == MENU_CTRLBAR)
|
|
|
|
{
|
|
|
|
act->setCheckable(true);
|
|
|
|
act->setChecked(show_ctrlbar);
|
|
|
|
act->setText("Show Control Bar");
|
|
|
|
// act->setText(show_ctrlbar ? "Hide Control bar" :
|
|
|
|
// "Show Control
|
|
|
|
// Bar");
|
|
|
|
}
|
|
|
|
else if (id == MENU_STATUS)
|
|
|
|
{
|
|
|
|
act->setCheckable(true);
|
|
|
|
act->setChecked(show_statusbar);
|
|
|
|
}
|
|
|
|
else if (id == MENU_CUMUL)
|
|
|
|
{
|
|
|
|
act->setCheckable(true);
|
|
|
|
act->setChecked(Procview::flag_cumulative);
|
|
|
|
act->setText("Include Child Times");
|
|
|
|
// act->setText(Procview::flag_cumulative ?
|
|
|
|
// "Exclude Child Times" :
|
|
|
|
// "Include Child Times");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// need to change name , redesign
|
|
|
|
void Qps::view_menu(QAction *act)
|
|
|
|
{
|
|
|
|
int id = act->data().toInt();
|
|
|
|
if (act->text() == "Process")
|
|
|
|
{
|
|
|
|
// tbar->setCurrentIndex(0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (act->text() == "Log")
|
|
|
|
{
|
|
|
|
// tbar->setCurrentIndex(1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int state = id;
|
|
|
|
if (id >= Procview::ALL && id <= Procview::HIDDEN)
|
|
|
|
{
|
|
|
|
if (procview->viewproc != state)
|
|
|
|
{
|
|
|
|
procview->viewproc = state;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (id >= Procview::USER && id <= Procview::CUSTOM)
|
|
|
|
{
|
|
|
|
if (procview->viewfields != state)
|
|
|
|
{
|
|
|
|
procview->viewfields = state;
|
|
|
|
procview->set_fields();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pstable->refresh(); // layout
|
|
|
|
/// update_menu_status();
|
|
|
|
}
|
|
|
|
|
|
|
|
// called when selection changed & update time
|
|
|
|
// void Qps::update_menu_status()
|
|
|
|
// void Qps::make_command_menu()
|
|
|
|
// DEL.
|
|
|
|
// -> show_popup_menu()
|
|
|
|
void Qps::update_menu_selection_status()
|
|
|
|
{
|
|
|
|
|
|
|
|
// bool enabled = (pstable->numSelected() > 0);
|
|
|
|
// if(enabled)
|
|
|
|
if (0)
|
|
|
|
{
|
|
|
|
bool cont = all_selected_stopped();
|
|
|
|
adjust_popup_menu(m_popup, cont);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < commands.size(); i++)
|
|
|
|
{
|
|
|
|
/* if (commands[i]->IsNeedProc()==false)
|
|
|
|
m_command->setItemEnabled(MENU_FIRST_COMMAND + i, true);
|
|
|
|
else m_command->setItemEnabled(MENU_FIRST_COMMAND + i, enabled);
|
|
|
|
*/}
|
|
|
|
}
|
|
|
|
|
|
|
|
// call by SearchBox::keyPressEvent
|
|
|
|
|
|
|
|
// slot
|
|
|
|
void Qps::sig_term() { send_to_selected(SIGTERM); }
|
|
|
|
|
|
|
|
void Qps::sig_hup() { send_to_selected(SIGHUP); }
|
|
|
|
|
|
|
|
// need
|
|
|
|
void Qps::sig_stop()
|
|
|
|
{
|
|
|
|
send_to_selected(SIGSTOP);
|
|
|
|
|
|
|
|
// test
|
|
|
|
for (int i = 0; i < procview->linear_procs.size(); i++)
|
|
|
|
{
|
|
|
|
Procinfo *p = procview->linear_procs[i];
|
|
|
|
if (p->selected)
|
|
|
|
{
|
|
|
|
p->test_stop = 1; // who ??
|
|
|
|
// sendsig(p, sig);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::sig_cont()
|
|
|
|
{
|
|
|
|
send_to_selected(SIGCONT);
|
|
|
|
|
|
|
|
// test
|
|
|
|
for (int i = 0; i < procview->linear_procs.size(); i++)
|
|
|
|
{
|
|
|
|
Procinfo *p = procview->linear_procs[i];
|
|
|
|
if (p->selected)
|
|
|
|
p->test_stop = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::sig_kill() { send_to_selected(SIGKILL); }
|
|
|
|
|
|
|
|
void Qps::menu_custom()
|
|
|
|
{
|
|
|
|
//// view_menu(Procview::CUSTOM); // should !!
|
|
|
|
if (field_win)
|
|
|
|
{
|
|
|
|
field_win->show();
|
|
|
|
field_win->raise();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
field_win = new FieldSelect(procview);
|
|
|
|
setWindowGroup(field_win);
|
|
|
|
field_win->show();
|
|
|
|
connect(field_win, SIGNAL(added_field(int)), this,
|
|
|
|
SLOT(field_added(int)));
|
|
|
|
connect(field_win, SIGNAL(removed_field(int)), this,
|
|
|
|
SLOT(field_removed(int)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MOVE TO PSTABlE ? hmmm wait...
|
|
|
|
// Interface for reading_setting()
|
|
|
|
// SLOT:
|
|
|
|
//
|
|
|
|
// called by
|
|
|
|
// 1.click Tree_checkbox
|
|
|
|
// 2.void Qps::view_menu(int id)
|
|
|
|
void Qps::set_table_mode(bool treemode)
|
|
|
|
{
|
|
|
|
// qDebug("set_table_mode()\n");
|
|
|
|
ctrlbar->setMode(treemode); // toggle checkbox
|
|
|
|
pstable->setTreeMode(treemode); // first pstable->refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Slot:
|
|
|
|
// SEGFAULT CODE: MOVETO Pstable
|
|
|
|
// called by
|
|
|
|
// 1. void Qps::add_fields_menu(int id)
|
|
|
|
// 2. field_win
|
|
|
|
void Qps::field_added(int field_id)
|
|
|
|
{
|
|
|
|
int where = -1;
|
|
|
|
where = pstable->clickedColumn();
|
|
|
|
procview->addField(field_id, where);
|
|
|
|
pstable->refresh(); // pstable->update(); // repaint
|
|
|
|
// update_menu_status();
|
|
|
|
}
|
|
|
|
|
|
|
|
// MOVETO Proview
|
|
|
|
// what this hell? SEGFAULT!
|
|
|
|
// call by
|
|
|
|
// 1. FieldSelect
|
|
|
|
// 2. void Qps::menu_remove_field()
|
|
|
|
void Qps::field_removed(int index)
|
|
|
|
{
|
|
|
|
/// printf("field_removed() index=%d\n",index);
|
|
|
|
procview->removeField(index);
|
|
|
|
if (procview->treeview and index == F_CMD)
|
|
|
|
set_table_mode(false);
|
|
|
|
// should be changed to linear mode !!
|
|
|
|
|
|
|
|
/// update_menu_status(); // ???
|
|
|
|
|
|
|
|
// pstable->update(); // no
|
|
|
|
pstable->refresh();
|
|
|
|
context_col = -1; // *** important **** : right clicked column removed
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// moveto command?
|
|
|
|
void Qps::menu_edit_cmd()
|
|
|
|
{
|
|
|
|
if (command_win)
|
|
|
|
{
|
|
|
|
command_win->show();
|
|
|
|
command_win->raise();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
command_win = new CommandDialog();
|
|
|
|
setWindowGroup(command_win);
|
|
|
|
command_win->show();
|
|
|
|
connect(command_win, SIGNAL(command_change()),
|
|
|
|
SLOT(make_command_menu()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// init command menu
|
|
|
|
// callback by CommandDialog::add_new()
|
|
|
|
void Qps::make_command_menu()
|
|
|
|
{
|
|
|
|
// should clear SIGNAL!!!
|
|
|
|
QAction *act;
|
|
|
|
m_command->clear();
|
|
|
|
m_command->disconnect();
|
|
|
|
|
|
|
|
if (flag_devel)
|
|
|
|
{
|
|
|
|
m_command->addAction("WatchDog", watchdogDialog,
|
|
|
|
SLOT(show())); //, m_event);
|
|
|
|
// m_command->addAction("ScreenShot", screenshot,
|
|
|
|
// SLOT(show()) );
|
|
|
|
act = m_command->addAction("Edit Commands...", this,
|
|
|
|
SLOT(menu_edit_cmd()));
|
|
|
|
// act->setEnabled(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// if(commands.size()) m_command->addSeparator();
|
|
|
|
add_default_command();
|
|
|
|
|
|
|
|
for (int i = 0; i < commands.size(); i++)
|
|
|
|
{
|
|
|
|
// commands[i]->menu = m_command->insertItem(commands[i]->name,
|
|
|
|
// MENU_FIRST_COMMAND + i);
|
|
|
|
// commands[i]->menu =
|
|
|
|
act = m_command->addAction(commands[i]->name);
|
|
|
|
// connect(act, SIGNAL(triggered(bool )),
|
|
|
|
// SLOT(signal_menu(bool)));
|
|
|
|
}
|
|
|
|
connect(m_command, SIGNAL(triggered(QAction *)),
|
|
|
|
SLOT(run_command(QAction *)));
|
|
|
|
|
|
|
|
update_menu_selection_status(); // DEL
|
|
|
|
//#ifdef SOLARIS
|
|
|
|
/* Solaris CDE don't have a tray, so we need a method to terminate */
|
|
|
|
m_command->addSeparator();
|
|
|
|
m_command->addAction(QIcon::fromTheme(QStringLiteral("application-exit")), "&Quit", this,
|
|
|
|
SLOT(save_quit()), Qt::ALT + Qt::Key_Q);
|
|
|
|
//#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
// run by MENU_ID ? qt slot?
|
|
|
|
// void Qps::run_command(int command_id)
|
|
|
|
void Qps::run_command(QAction *act)
|
|
|
|
{
|
|
|
|
int command_id;
|
|
|
|
int i, j, idx = -1;
|
|
|
|
// FUNC_START
|
|
|
|
|
|
|
|
// printf("%s\n",qPrintable(act->text()));
|
|
|
|
AddLog(act->text());
|
|
|
|
|
|
|
|
// find_command
|
|
|
|
for (i = 0; i < commands.size(); i++)
|
|
|
|
{
|
|
|
|
// if(commands[i]->menu==command_id)
|
|
|
|
if (commands[i]->name == act->text())
|
|
|
|
{
|
|
|
|
if (commands[idx]->IsNeedProc() == false)
|
|
|
|
{
|
|
|
|
commands[idx]->call(NULL);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < procview->linear_procs.size(); i++)
|
|
|
|
{
|
|
|
|
Procinfo *p = procview->linear_procs[i];
|
|
|
|
if (p->selected)
|
|
|
|
commands[idx]->call(p);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// detail
|
|
|
|
void Qps::Action_Detail()
|
|
|
|
{
|
|
|
|
for (int i = 0; i < procview->linear_procs.size(); i++)
|
|
|
|
{
|
|
|
|
Procinfo *p = procview->linear_procs[i];
|
|
|
|
if (p->selected)
|
|
|
|
open_details(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MOVETO : pstable.cpp
|
|
|
|
void Qps::open_details(int row)
|
|
|
|
{
|
|
|
|
Procinfo *p = procview->linear_procs[row];
|
|
|
|
if (p->detail)
|
|
|
|
{
|
|
|
|
// p->detail->raise();
|
|
|
|
p->detail->show();
|
|
|
|
printf("show detail \n");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Details *d = new Details(p, procview);
|
|
|
|
// details.append(*d);
|
|
|
|
// setWindowGroup(d);
|
|
|
|
d->show();
|
|
|
|
/// connect(d, SIGNAL(closed(Details *)), this,
|
|
|
|
/// SLOT(details_closed(Details
|
|
|
|
///*)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::details_closed(Details *d)
|
|
|
|
{
|
|
|
|
// printf("details_closed()\n");
|
|
|
|
// disconnect
|
|
|
|
|
|
|
|
// This is potentially dangerous, since this is called in response to a
|
|
|
|
// signal sent by the widget that is about to be deleted here. Better
|
|
|
|
// hope
|
|
|
|
// that nobody references the object down the call chain!
|
|
|
|
// what ??????
|
|
|
|
|
|
|
|
//////details.removeAt(*d); // deletes window
|
|
|
|
// details.removeAt(*d); // deletes window
|
|
|
|
}
|
|
|
|
|
|
|
|
// find parents of selected processes
|
|
|
|
void Qps::menu_parent() { locate_relatives(&Procinfo::ppid, &Procinfo::pid); }
|
|
|
|
|
|
|
|
void Qps::menu_children() { locate_relatives(&Procinfo::pid, &Procinfo::ppid); }
|
|
|
|
|
|
|
|
// Find processes whose attribute b is equal to the attribute a of
|
|
|
|
// selected processes. Center around topmost found.
|
|
|
|
// This is quadratic in worst case (shouldn't be a problem)
|
|
|
|
// called by
|
|
|
|
// 1.menu_children()
|
|
|
|
// 2.menu_parent()
|
|
|
|
void Qps::locate_relatives(int Procinfo::*a, int Procinfo::*b)
|
|
|
|
{
|
|
|
|
QList<int> relatives;
|
|
|
|
const int infinity = 2000000000;
|
|
|
|
int topmost = infinity;
|
|
|
|
for (int i = 0; i < procview->linear_procs.size(); i++)
|
|
|
|
{
|
|
|
|
Procinfo *p = procview->linear_procs[i];
|
|
|
|
if (p->selected)
|
|
|
|
{
|
|
|
|
pstable->setSelected(i, false);
|
|
|
|
for (int j = 0; j < procview->linear_procs.size(); j++)
|
|
|
|
{
|
|
|
|
Procinfo *q = procview->linear_procs[j];
|
|
|
|
if (p->*a == q->*b)
|
|
|
|
{
|
|
|
|
relatives.append(j);
|
|
|
|
if (j < topmost)
|
|
|
|
topmost = j;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int i = 0; i < relatives.size(); i++)
|
|
|
|
pstable->setSelected(relatives[i], true);
|
|
|
|
/// if(topmost < infinity) pstable->centerVertically(topmost);
|
|
|
|
//// pstable->selectionNotify();
|
|
|
|
}
|
|
|
|
|
|
|
|
// select all (direct and indirect) offsprings of currently selected
|
|
|
|
// processes, without deselecting them
|
|
|
|
void Qps::menu_dynasty()
|
|
|
|
{
|
|
|
|
QList<int> family;
|
|
|
|
for (int i = 0; i < procview->linear_procs.size(); i++)
|
|
|
|
if (pstable->isSelected(i))
|
|
|
|
family.append(i);
|
|
|
|
for (int i = 0, j = family.size(); i < j;)
|
|
|
|
{
|
|
|
|
for (int k = 0; k < procview->linear_procs.size(); k++)
|
|
|
|
{
|
|
|
|
Procinfo *p = procview->linear_procs[k];
|
|
|
|
for (int m = i; m < j; m++)
|
|
|
|
{
|
|
|
|
Procinfo *q = procview->linear_procs[family[m]];
|
|
|
|
if (q->pid == p->ppid)
|
|
|
|
family.append(k);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
i = j;
|
|
|
|
j = family.size();
|
|
|
|
}
|
|
|
|
const int infinity = 2000000000;
|
|
|
|
int topmost = infinity;
|
|
|
|
for (int i = 0; i < family.size(); i++)
|
|
|
|
{
|
|
|
|
pstable->setSelected(family[i], true);
|
|
|
|
if (family[i] < topmost)
|
|
|
|
topmost = family[i];
|
|
|
|
}
|
|
|
|
////if(topmost < infinity) pstable->centerVertically(topmost);
|
|
|
|
////pstable->selectionNotify();
|
|
|
|
}
|
|
|
|
|
|
|
|
// CALLBACK: called when right button is clicked in table
|
|
|
|
void Qps::show_popup_menu(QPoint p)
|
|
|
|
{
|
|
|
|
#ifdef MOSIX
|
|
|
|
bool may_migrate = false;
|
|
|
|
for (int i = 0; i < procview->linear_procs.size(); i++)
|
|
|
|
{
|
|
|
|
Procinfo *p = procview->linear_procs[i];
|
|
|
|
if (p->selected && p->cantmove.isEmpty())
|
|
|
|
{
|
|
|
|
may_migrate = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_popup->setItemEnabled(POPUP_MIGRATE, may_migrate);
|
|
|
|
#endif
|
|
|
|
adjust_popup_menu();
|
|
|
|
m_popup->popup(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
// called when right button is clicked in heading
|
|
|
|
//
|
|
|
|
void Qps::context_heading_menu(QPoint p, int col)
|
|
|
|
{
|
|
|
|
context_col = col; // ****
|
|
|
|
////printf("context_col=%d\n",col);
|
|
|
|
static int init = 0;
|
|
|
|
// rebuild the submenu: only include non-displayed fields
|
|
|
|
int ncats = procview->categories.size();
|
|
|
|
|
|
|
|
if (init == 0)
|
|
|
|
{
|
|
|
|
/* #ifdef SHash
|
|
|
|
SHash<int,Category *>::const_iterator it=procview->categories.begin();
|
|
|
|
QList<int> keys;
|
|
|
|
for ( ; it != procview->categories.end(); it++ )
|
|
|
|
keys.append((*it).first);
|
|
|
|
#else
|
|
|
|
*/ QList<int> keys = procview->categories.keys();
|
|
|
|
// #endif
|
|
|
|
for (int i = 0; i < ncats; i++)
|
|
|
|
{
|
|
|
|
Category *cat = procview->categories[keys.takeFirst()];
|
|
|
|
QAction *act = m_fields->addAction(cat->name);
|
|
|
|
act->setData(cat->id); // index==key
|
|
|
|
}
|
|
|
|
connect(m_fields, SIGNAL(triggered(QAction *)), this,
|
|
|
|
SLOT(add_fields_menu(QAction *)));
|
|
|
|
init = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
QBitArray displayed(64); // MAX_FIELDS
|
|
|
|
displayed.fill(false);
|
|
|
|
// printf("categories.size=%d cats.size=%d\n",ncats,
|
|
|
|
// procview->cats.size());
|
|
|
|
|
|
|
|
for (int i = 0; i < procview->cats.size(); i++)
|
|
|
|
{
|
|
|
|
// printf("cat id=%d \n",procview->cats[i]->id);
|
|
|
|
displayed.setBit(procview->cats[i]->id);
|
|
|
|
}
|
|
|
|
|
|
|
|
QList<QAction *> la = m_fields->actions();
|
|
|
|
for (int j = 0; j < la.size(); j++)
|
|
|
|
{
|
|
|
|
QAction *act = la[j];
|
|
|
|
int id = act->data().toInt();
|
|
|
|
if (!displayed.testBit(id))
|
|
|
|
act->setVisible(true);
|
|
|
|
else
|
|
|
|
act->setVisible(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_headpopup->popup(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::add_fields_menu(QAction *act)
|
|
|
|
{
|
|
|
|
// act->text();
|
|
|
|
int id = act->data().toInt();
|
|
|
|
field_added(id);
|
|
|
|
// add_fields_menu(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
// called when field is added from heading context menu
|
|
|
|
// called by 1. context_heading_menu
|
|
|
|
void Qps::add_fields_menu(int cat_id)
|
|
|
|
{
|
|
|
|
field_added(cat_id);
|
|
|
|
context_col = -1;
|
|
|
|
// if(field_win) field_win->update_boxes(); // change to showEvent. !!!!
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
void Qps::menu_remove_field()
|
|
|
|
{
|
|
|
|
if (context_col < 0)
|
|
|
|
return;
|
|
|
|
/// printf("cats.size=%d , context_col=%d
|
|
|
|
/// \n",procview->cats.size(),context_col);
|
|
|
|
field_removed(procview->cats[context_col]->index);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::menu_update()
|
|
|
|
{
|
|
|
|
|
|
|
|
QString txt;
|
|
|
|
if (update_period == eternity)
|
|
|
|
txt = "1 s";
|
|
|
|
else if (update_period % 1000 == 0)
|
|
|
|
txt.sprintf("%d s", update_period / 1000);
|
|
|
|
else
|
|
|
|
txt.sprintf("%d ms", update_period);
|
|
|
|
IntervalDialog id(txt.toUtf8().data(), update_period != eternity);
|
|
|
|
id.exec();
|
|
|
|
/// save_settings();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::menu_toggle_path()
|
|
|
|
{
|
|
|
|
Procview::flag_show_file_path = !Procview::flag_show_file_path;
|
|
|
|
/// table refresh() !
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::menu_toggle_infobar()
|
|
|
|
{
|
|
|
|
show_infobar = !show_infobar;
|
|
|
|
bar_visibility();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::menu_toggle_ctrlbar()
|
|
|
|
{
|
|
|
|
show_ctrlbar = !show_ctrlbar;
|
|
|
|
bar_visibility();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::menu_toggle_statusbar()
|
|
|
|
{
|
|
|
|
show_statusbar = !show_statusbar;
|
|
|
|
bar_visibility();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::menu_toggle_cumul()
|
|
|
|
{
|
|
|
|
Procview::flag_cumulative = !Procview::flag_cumulative;
|
|
|
|
// refresh() !!
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::menu_prefs()
|
|
|
|
{
|
|
|
|
if (prefs_win)
|
|
|
|
{
|
|
|
|
prefs_win->show();
|
|
|
|
prefs_win->raise();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
prefs_win = new Preferences();
|
|
|
|
setWindowGroup(prefs_win);
|
|
|
|
prefs_win->show();
|
|
|
|
prefs_win->raise();
|
|
|
|
|
|
|
|
connect(prefs_win, SIGNAL(prefs_change()), this, SLOT(config_change()));
|
|
|
|
/// connect(infobar, SIGNAL(config_change()), prefs_win,
|
|
|
|
/// SLOT(update_boxes())); // doesnt need !! --> aboutToShow()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if "Preferences" changed
|
|
|
|
void Qps::config_change()
|
|
|
|
{
|
|
|
|
|
|
|
|
write_settings();
|
|
|
|
bar_visibility();
|
|
|
|
// DEL infobar->configure();
|
|
|
|
/// resizeEvent(0); // in case it caused geometry change
|
|
|
|
|
|
|
|
for (int i = 0; i < details.size(); ++i)
|
|
|
|
{
|
|
|
|
///// details[i].config_change();
|
|
|
|
}
|
|
|
|
/* while((d = details.current()) != 0) {
|
|
|
|
d->config_change();
|
|
|
|
details.next();
|
|
|
|
} */
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::menu_renice()
|
|
|
|
{
|
|
|
|
// if(pstable->hasSelection() == 0) return;
|
|
|
|
|
|
|
|
int defnice = -1000;
|
|
|
|
|
|
|
|
// use nice of first selected process as default, and check permission
|
|
|
|
bool possible = true;
|
|
|
|
int euid = geteuid();
|
|
|
|
Procinfo *p = 0;
|
|
|
|
|
|
|
|
for (int i = 0; i < procview->linear_procs.size(); i++)
|
|
|
|
{
|
|
|
|
p = procview->linear_procs[i];
|
|
|
|
if (p->selected)
|
|
|
|
{
|
|
|
|
if (defnice == -1000)
|
|
|
|
defnice = p->nice;
|
|
|
|
if (euid != 0 && euid != p->uid && euid != p->euid)
|
|
|
|
possible = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!possible)
|
|
|
|
{
|
|
|
|
QString s;
|
|
|
|
s.sprintf("You do not have permission to renice the\n"
|
|
|
|
"selected process%s.\n"
|
|
|
|
"Only the process owner and the super-user\n"
|
|
|
|
"are allowed to do that.",
|
|
|
|
(pstable->hasSelection() == 1) ? "" : "es");
|
|
|
|
QMessageBox::warning(this, "Permission denied", s);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int new_nice;
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
SliderDialog sd(defnice, -20, 19); // Linux kernel : -20 ~ 19
|
|
|
|
if (!sd.exec())
|
|
|
|
return;
|
|
|
|
bool ok;
|
|
|
|
new_nice = sd.ed_result.toInt(&ok);
|
|
|
|
if (ok && new_nice >= -20 && new_nice <= 19)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
int nicecol = procview->findCol(F_NICE);
|
|
|
|
int statcol = procview->findCol(F_STAT);
|
|
|
|
#ifdef LINUX
|
|
|
|
int tmscol = procview->findCol(F_TMS);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// do the actual renicing
|
|
|
|
for (int i = 0; i < procview->linear_procs.size(); i++)
|
|
|
|
{
|
|
|
|
Procinfo *p = procview->linear_procs[i];
|
|
|
|
if (p->selected)
|
|
|
|
{
|
|
|
|
if (setpriority(PRIO_PROCESS, p->pid, new_nice) < 0)
|
|
|
|
{
|
|
|
|
QString s;
|
|
|
|
switch (errno)
|
|
|
|
{
|
|
|
|
case EPERM:
|
|
|
|
// this shouldn't happen, but (e)uid
|
|
|
|
// could be changed...
|
|
|
|
s.sprintf("You do not have permission "
|
|
|
|
"to renice"
|
|
|
|
" process %d (",
|
|
|
|
p->pid);
|
|
|
|
s.append(p->command);
|
|
|
|
s.append(").\n"
|
|
|
|
"Only the process owner and "
|
|
|
|
"the super-user are"
|
|
|
|
" allowed to do that.");
|
|
|
|
QMessageBox::warning(this, "Permission denied", s);
|
|
|
|
break;
|
|
|
|
case EACCES:
|
|
|
|
QMessageBox::warning(this, "Permission denied",
|
|
|
|
"Only the super-user may lower"
|
|
|
|
" the nice value of a process.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p->nice = new_nice; // don't wait for update
|
|
|
|
#ifdef LINUX
|
|
|
|
p->tms = p->get_tms(); // ditto
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::menu_sched()
|
|
|
|
{
|
|
|
|
// if(pstable->hasSelection()==false) return;
|
|
|
|
if (geteuid() != 0)
|
|
|
|
{
|
|
|
|
QMessageBox::warning(this, "Permission denied",
|
|
|
|
"Only the super-user may change the\n"
|
|
|
|
"scheduling policy and static priority.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// provide reasonable defaults (first selected process)
|
|
|
|
Procinfo *p = 0;
|
|
|
|
for (int i = 0; i < procview->linear_procs.size(); i++)
|
|
|
|
{
|
|
|
|
p = procview->linear_procs[i];
|
|
|
|
if (p->selected)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
int pol = p->get_policy();
|
|
|
|
int pri = p->get_rtprio();
|
|
|
|
SchedDialog sd(pol, pri);
|
|
|
|
if (!sd.exec())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (sd.out_policy == SCHED_OTHER)
|
|
|
|
sd.out_prio = 0; // only allowed value
|
|
|
|
int plcycol = procview->findCol(F_PLCY);
|
|
|
|
int rpricol = procview->findCol(F_RPRI);
|
|
|
|
#ifdef LINUX
|
|
|
|
int tmscol = procview->findCol(F_TMS);
|
|
|
|
#endif
|
|
|
|
for (int i = 0; i < procview->linear_procs.size(); i++)
|
|
|
|
{
|
|
|
|
Procinfo *p = procview->linear_procs[i];
|
|
|
|
if (p->selected)
|
|
|
|
{
|
|
|
|
struct sched_param sp;
|
|
|
|
sp.sched_priority = sd.out_prio;
|
|
|
|
if (sched_setscheduler(p->pid, sd.out_policy, &sp) < 0)
|
|
|
|
{
|
|
|
|
QString s;
|
|
|
|
if (errno == EPERM)
|
|
|
|
{
|
|
|
|
s.sprintf("You do not have permission to "
|
|
|
|
"change the\n"
|
|
|
|
"scheduling and/or priority of"
|
|
|
|
" process %d (",
|
|
|
|
p->pid);
|
|
|
|
s.append(p->command);
|
|
|
|
s.append(").\n"
|
|
|
|
"Only the super-user may do that.");
|
|
|
|
QMessageBox::warning(this, "Permission denied", s);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p->policy = sd.out_policy; // don't wait for update
|
|
|
|
p->rtprio = sd.out_prio;
|
|
|
|
#ifdef LINUX
|
|
|
|
p->tms = p->get_tms();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef MOSIX
|
|
|
|
|
|
|
|
void Qps::mig_menu(int id) { migrate_selected(id - 1); }
|
|
|
|
|
|
|
|
void Qps::migrate_selected(int migto)
|
|
|
|
{
|
|
|
|
// User wants to migrate a process somewhere
|
|
|
|
// Write destination into /proc/XX/goto
|
|
|
|
int warnremote = 0;
|
|
|
|
for (int i = 0; i < procview->linear_procs.size(); i++)
|
|
|
|
{
|
|
|
|
Procinfo *p = procview->linear_procs[i];
|
|
|
|
if (p->selected)
|
|
|
|
{
|
|
|
|
if (p->isremote)
|
|
|
|
++warnremote;
|
|
|
|
char buf[80];
|
|
|
|
sprintf(buf, "/proc/%d/goto", p->pid);
|
|
|
|
FILE *f = fopen(buf, "w");
|
|
|
|
if (f)
|
|
|
|
{
|
|
|
|
fprintf(f, "%d", migto);
|
|
|
|
fclose(f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (warnremote)
|
|
|
|
QMessageBox::warning(this, "Remote migration attempt",
|
|
|
|
"You can only migrate an immigrated process "
|
|
|
|
"using qps on the home node.");
|
|
|
|
earlier_refresh();
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
|
|
|
|
// Since this is a slot, at least a stub must be defined even when it isn't
|
|
|
|
// used (moc ignores preprocessor directives)
|
|
|
|
void Qps::mig_menu(int) {}
|
|
|
|
|
|
|
|
#endif // MOSIX
|
|
|
|
|
|
|
|
void Qps::send_to_selected(int sig)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < procview->linear_procs.size(); i++)
|
|
|
|
{
|
|
|
|
Procinfo *p = procview->linear_procs[i];
|
|
|
|
if (p->selected)
|
|
|
|
sendsig(p, sig);
|
|
|
|
}
|
|
|
|
earlier_refresh(); // in case we killed one
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::sendsig(Procinfo *p, int sig)
|
|
|
|
{
|
|
|
|
if (kill(p->pid, sig) < 0)
|
|
|
|
{
|
|
|
|
// if the process is gone, do nothing - no need to alert the
|
|
|
|
// user
|
|
|
|
if (errno == EPERM)
|
|
|
|
{
|
|
|
|
QString s;
|
|
|
|
s.sprintf("You do not have permission to send a signal to"
|
|
|
|
" process %d (",
|
|
|
|
p->pid);
|
|
|
|
s.append(p->command);
|
|
|
|
s.append(").\n"
|
|
|
|
"Only the super-user and the owner of the process"
|
|
|
|
" may send signals to it.");
|
|
|
|
QMessageBox::warning(this, "Permission denied", s);
|
|
|
|
// PermissionDialog *pd = new
|
|
|
|
// PermissionDialog(s,supasswd);
|
|
|
|
// pd->exec();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// write geometry, visible fields and other settings to $HOME/.qps-settings
|
|
|
|
#define SETTINGS_FILE ".qpsrc"
|
|
|
|
// If the file format is changed in any way (including adding new
|
|
|
|
// viewable fields), QPS_FILE_VERSION must be incremented to prevent
|
|
|
|
// version mismatches and core dumps
|
|
|
|
|
|
|
|
#ifdef LINUX
|
|
|
|
#define QPS_FILE_VERSION 40 // version of .qps-linux file format
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef SOLARIS
|
|
|
|
#define QPS_FILE_VERSION 24 // version of .qps-solaris file format
|
|
|
|
#endif
|
|
|
|
|
|
|
|
struct Sflagvar
|
|
|
|
{
|
|
|
|
const char *name;
|
|
|
|
bool *var;
|
|
|
|
};
|
|
|
|
static Sflagvar flagvars[] = {{"ExitOnClose", &Qps::flag_exit},
|
|
|
|
{"TabView", &Qps::flag_useTabView},
|
|
|
|
{"SingleCPU", &Procview::flag_pcpu_single},
|
|
|
|
{"devel", &flag_devel},
|
|
|
|
{"cmdpath", &Procview::flag_show_file_path},
|
|
|
|
{"infobar", &Qps::show_infobar},
|
|
|
|
{"ctrlbar", &Qps::show_ctrlbar},
|
|
|
|
{"statbar", &Qps::show_statusbar},
|
|
|
|
{"autosave", &Qps::auto_save_options},
|
|
|
|
{"cpubar", &Qps::show_cpu_bar},
|
|
|
|
{"loadgraph", &Qps::show_load_graph},
|
|
|
|
{"loadicon", &Qps::load_in_icon},
|
|
|
|
{"selectpids", &Qps::pids_to_selection},
|
|
|
|
{"tree", &Procview::treeview},
|
|
|
|
{"cumulative", &Procview::flag_cumulative},
|
|
|
|
#ifdef LINUX
|
|
|
|
{"hostname", &Qps::hostname_lookup},
|
|
|
|
{"service", &Qps::service_lookup}
|
|
|
|
#endif
|
|
|
|
#ifdef SOLARIS
|
|
|
|
{"normalize", &Qps::normalize_nice},
|
|
|
|
{"pmap", &Qps::use_pmap}
|
|
|
|
#endif
|
|
|
|
,
|
|
|
|
{0, 0}};
|
|
|
|
|
|
|
|
char *settings_path(char *name)
|
|
|
|
{
|
|
|
|
char *home = getenv("HOME");
|
|
|
|
if (!home)
|
|
|
|
return 0;
|
|
|
|
strcpy(name, home);
|
|
|
|
strcat(name, "/" SETTINGS_FILE);
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
#include <QSettings>
|
|
|
|
extern QList<watchCond *> watchlist;
|
|
|
|
// 1.Procview should be contstructed !
|
|
|
|
// 2.
|
|
|
|
bool Qps::read_settings()
|
|
|
|
{
|
|
|
|
char path[512];
|
|
|
|
if (settings_path(path) == NULL)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
QSettings set(path, QSettings::NativeFormat);
|
|
|
|
|
|
|
|
int v = set.value("version", 0).toInt();
|
|
|
|
if (v == 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
int x, y, w, h;
|
|
|
|
x = set.value("geometry/x").toInt();
|
|
|
|
y = set.value("geometry/y").toInt();
|
|
|
|
w = set.value("geometry/width").toInt();
|
|
|
|
h = set.value("geometry/height").toInt();
|
|
|
|
// set.value("geometry/visiable",isVisible());
|
|
|
|
Qps::flag_show = true;
|
|
|
|
setGeometry(x, y, w, h);
|
|
|
|
|
|
|
|
if (set.value("font/name") != QVariant() and
|
|
|
|
set.value("font/size") != QVariant())
|
|
|
|
{
|
|
|
|
QString fname = set.value("font/name").toString();
|
|
|
|
int fsize = set.value("font/size").toInt(); // if not exist then 0
|
|
|
|
QFont font;
|
|
|
|
font.setFamily(fname);
|
|
|
|
font.setPointSize(fsize);
|
|
|
|
QApplication::setFont(font);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Field
|
|
|
|
procview->cats.clear();
|
|
|
|
QStringList sl = set.value("field").toStringList();
|
|
|
|
for (int i = 0; i < sl.size(); i++)
|
|
|
|
{
|
|
|
|
QString str = sl[i];
|
|
|
|
procview->addField(str.toUtf8().data());
|
|
|
|
}
|
|
|
|
/// procview->saveCOMMANDFIELD(); // TMP
|
|
|
|
|
|
|
|
// procview->idxF_CMD=set.value("F_CMD").toInt();
|
|
|
|
|
|
|
|
if (sl.size() ==
|
|
|
|
0) // *** for safe , if there is no field. this happen when no qpsrc
|
|
|
|
{
|
|
|
|
procview->viewfields = Procview::USER;
|
|
|
|
procview->set_fields(); ///
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
procview->viewfields = Procview::CUSTOM;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString str = set.value("sort/field").toString(); // procview->sortcat->name
|
|
|
|
int fid = procview->field_id_by_name(str.toUtf8().data());
|
|
|
|
int col = procview->findCol(fid);
|
|
|
|
if (col >= 0)
|
|
|
|
// pstable->setSortColumn(col); // Pstable::refresh()
|
|
|
|
procview->setSortColumn(col); // Pstable::refresh()
|
|
|
|
// pstable -> procview
|
|
|
|
procview->reversed = set.value("sort/reversed").toBool(); // tmp
|
|
|
|
|
|
|
|
sl = set.value("flags").toStringList();
|
|
|
|
// for(int i=0;i<sl.size();i++)
|
|
|
|
for (Sflagvar *fs = flagvars; fs->name; fs++)
|
|
|
|
{
|
|
|
|
if (sl.contains(fs->name))
|
|
|
|
*(fs->var) = true;
|
|
|
|
else
|
|
|
|
*(fs->var) = false;
|
|
|
|
}
|
|
|
|
// procview->treeview=set.value("treeview").toBool();
|
|
|
|
|
|
|
|
int i = set.value("interval").toInt();
|
|
|
|
set_update_period(i);
|
|
|
|
i = set.value("viewproc").toInt();
|
|
|
|
procview->viewproc = i;
|
|
|
|
ctrlbar->view->setCurrentIndex(
|
|
|
|
i); // procview->viewproc=set.value("viewproc").toInt();
|
|
|
|
|
|
|
|
int size = set.beginReadArray("watchdog");
|
|
|
|
for (int i = 0; i < size; i++)
|
|
|
|
{
|
|
|
|
set.setArrayIndex(i);
|
|
|
|
watchCond *w = new watchCond;
|
|
|
|
w->putstring(set.value("cat").toString());
|
|
|
|
watchlist.append(w);
|
|
|
|
}
|
|
|
|
set.endArray();
|
|
|
|
size = set.beginReadArray("commands");
|
|
|
|
for (int i = 0; i < size; i++)
|
|
|
|
{
|
|
|
|
set.setArrayIndex(i);
|
|
|
|
Command *c = new Command;
|
|
|
|
c->putString(set.value("cmd").toString());
|
|
|
|
commands.append(c);
|
|
|
|
}
|
|
|
|
set.endArray();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
/*
|
|
|
|
} else if(strcmp(buf, "swaplim") == 0) {
|
|
|
|
swaplimit = atoi(p);
|
|
|
|
swaplim_percent = false;
|
|
|
|
if(swaplimit < 0) {
|
|
|
|
swaplimit = -swaplimit;
|
|
|
|
swaplim_percent = true;
|
|
|
|
}
|
|
|
|
fclose(f); */
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// USING :
|
|
|
|
// write geometry, visible fields and other settings to $HOME/.qps-settings
|
|
|
|
void Qps::write_settings() // save setting
|
|
|
|
{
|
|
|
|
char path[512];
|
|
|
|
if (settings_path(path) == NULL)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
QSettings set(path, QSettings::NativeFormat);
|
|
|
|
|
|
|
|
set.setValue("version", QPS_FILE_VERSION);
|
|
|
|
// set.beginGroup("");
|
|
|
|
// set.endGroup();
|
|
|
|
set.setValue("geometry/x",
|
|
|
|
geometry().x()); // if hide then, wrong value saved!!
|
|
|
|
set.setValue("geometry/y", geometry().y());
|
|
|
|
set.setValue("geometry/width", geometry().width());
|
|
|
|
set.setValue("geometry/height", geometry().height());
|
|
|
|
set.setValue("geometry/visiable",
|
|
|
|
isVisible()); // isVisible() ? "show":"hide");
|
|
|
|
set.setValue("viewproc",
|
|
|
|
procview->viewproc); // All, your , running process...
|
|
|
|
/// set.setValue("treeview",procview->treeview);
|
|
|
|
|
|
|
|
QStringList sl;
|
|
|
|
// printf("procview cats.size=%d\n",procview->cats.size());
|
|
|
|
procview->update_customfield();
|
|
|
|
set.setValue("field", procview->customfields);
|
|
|
|
// set.setValue("F_CMD",procview->idxF_CMD);
|
|
|
|
|
|
|
|
if (procview->sortcat) // sometimes, sortcat==NULL.
|
|
|
|
{
|
|
|
|
set.setValue("sort/field", procview->sortcat->name);
|
|
|
|
set.setValue("sort/reversed", procview->reversed);
|
|
|
|
}
|
|
|
|
// return;
|
|
|
|
sl.clear();
|
|
|
|
for (Sflagvar *fs = flagvars; fs->name; fs++)
|
|
|
|
{
|
|
|
|
if (*(fs->var))
|
|
|
|
sl.append(fs->name); // fprintf(f, " %s", fs->name);
|
|
|
|
}
|
|
|
|
set.setValue("flags", sl);
|
|
|
|
|
|
|
|
// fprintf(f, "swaplim: %d\n" "interval: %d\n",
|
|
|
|
// swaplim_percent ? -swaplimit :
|
|
|
|
// swaplimit,
|
|
|
|
// update_period);
|
|
|
|
|
|
|
|
sl.clear();
|
|
|
|
set.setValue("font/name", QApplication::font().family());
|
|
|
|
set.setValue("font/size", QApplication::font().pointSize());
|
|
|
|
|
|
|
|
set.setValue("interval", update_period);
|
|
|
|
|
|
|
|
set.beginWriteArray("watchdog");
|
|
|
|
for (int i = 0; i < watchlist.size(); i++)
|
|
|
|
{
|
|
|
|
set.setArrayIndex(i);
|
|
|
|
set.setValue("cat", watchlist[i]->getstring());
|
|
|
|
}
|
|
|
|
set.endArray();
|
|
|
|
|
|
|
|
set.beginWriteArray("commands");
|
|
|
|
for (int i = 0; i < commands.size(); i++)
|
|
|
|
{
|
|
|
|
set.setArrayIndex(i);
|
|
|
|
set.setValue("cmd", commands[i]->getString());
|
|
|
|
}
|
|
|
|
set.endArray();
|
|
|
|
|
|
|
|
/*
|
|
|
|
fprintf(f, "hidden_process:");
|
|
|
|
for(int i = 0; i < hidden_process.size(); i++) {
|
|
|
|
if(i!=0) fprintf(f,",");
|
|
|
|
fprintf(f,"%s",(const char *)hidden_process[i]);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/// printf("Qps: setting saved !\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
// set the window_group hint to that of the main (qps) window
|
|
|
|
// DELETE ? -> need function , why?
|
|
|
|
void Qps::setWindowGroup(QWidget *w)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
XWMHints wmh;
|
|
|
|
|
|
|
|
wmh.flags = WindowGroupHint;
|
|
|
|
wmh.window_group = handle();
|
|
|
|
XSetWMHints(w->x11Display(), w->handle(), &wmh);
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
// DEL
|
|
|
|
void Qps::setCommand(int argc, char **argv)
|
|
|
|
{
|
|
|
|
// bug: argv[0] should really be frobbed into an absolute path name here
|
|
|
|
/// XSetCommand(x11Display(), handle(), argv, argc);
|
|
|
|
}
|
|
|
|
|
|
|
|
// return host name with domain stripped
|
|
|
|
QString short_hostname()
|
|
|
|
{
|
|
|
|
//// int gethostname(char *name, size_t len); // hyun?
|
|
|
|
struct utsname u;
|
|
|
|
uname(&u);
|
|
|
|
char *p = strchr(u.nodename, '.');
|
|
|
|
if (p)
|
|
|
|
*p = '\0';
|
|
|
|
QString s(u.nodename);
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool opt_eq(const char *arg, const char *opt)
|
|
|
|
{
|
|
|
|
if (arg[0] == '-')
|
|
|
|
arg++;
|
|
|
|
if (arg[0] == '-')
|
|
|
|
arg++;
|
|
|
|
|
|
|
|
return strncmp(arg, opt, strlen(opt)) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// print some help to stdout and exit
|
|
|
|
void print_help(char *cmdname)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "Usage: qps [options]\n"
|
|
|
|
"Options:\n"
|
|
|
|
" -version\t\tversion\n"
|
|
|
|
" -mini \t\tstart Minimized\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/// #include <QX11Info>
|
|
|
|
QByteArray geo;
|
|
|
|
void Qps::clicked_trayicon()
|
|
|
|
{
|
|
|
|
// QT 4.5 bug : hide(), then show() window's pos will be changed a
|
|
|
|
// little.
|
|
|
|
if (isMinimized() or (isVisible() == false)) // if hidden
|
|
|
|
{
|
|
|
|
// printf("showNormal\n");
|
|
|
|
// show(); // works..
|
|
|
|
showNormal(); // works..
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// METACITY- focus stealing prevention : XRaiseWindow() not work.
|
|
|
|
// Compiz works well !!
|
|
|
|
if (isActiveWindow() == false) // if lower than other windows
|
|
|
|
{
|
|
|
|
raise();
|
|
|
|
activateWindow(); // for WindowMaker
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::clicked_trayicon(QSystemTrayIcon::ActivationReason r)
|
|
|
|
{
|
|
|
|
// printf("ActivationReason = %d\n",r);
|
|
|
|
if (r == QSystemTrayIcon::Trigger)
|
|
|
|
{
|
|
|
|
if (!isHidden())
|
|
|
|
{
|
|
|
|
hide();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
showNormal();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (r == QSystemTrayIcon::Context)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
void Qps::hideEvent(QHideEvent *event)
|
|
|
|
{
|
|
|
|
// printf("hideEvent()\n");
|
|
|
|
if (trayicon->hasSysTray())
|
|
|
|
{
|
|
|
|
// event->accept();
|
|
|
|
}
|
|
|
|
// geo=saveGeometry();
|
|
|
|
}
|
|
|
|
|
|
|
|
#include <signal.h>
|
|
|
|
void signal_handler(int sig)
|
|
|
|
{
|
|
|
|
// if(sig==SIGINT) printf("DEBUG: catched SIGINT \n");
|
|
|
|
// if(sig==SIGTERM)printf("DEBUG: catched SIGTERM \n");
|
|
|
|
qps->save_quit();
|
|
|
|
// printf("Qps: suiciding.... wait \n");
|
|
|
|
printf("Qps: terminating...\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char **argv, char **envp)
|
|
|
|
{
|
|
|
|
signal(SIGTERM, signal_handler);
|
|
|
|
signal(SIGINT, signal_handler);
|
|
|
|
signal(SIGKILL, signal_handler);
|
|
|
|
|
|
|
|
Lookup::initproctitle(argv, envp); // will be REMOVEd
|
|
|
|
|
|
|
|
for (int i = 1; i < argc; i++)
|
|
|
|
{
|
|
|
|
if (opt_eq(argv[i], "version"))
|
|
|
|
{
|
|
|
|
fprintf(stderr,
|
|
|
|
"qps version " QPS_VERSION ", using Qt library %s\n",
|
|
|
|
qVersion());
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
else if (opt_eq(argv[i], "help") || opt_eq(argv[i], "h"))
|
|
|
|
{
|
|
|
|
print_help(argv[0]);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
else if (opt_eq(argv[i], "session") or opt_eq(argv[i], "sm"))
|
|
|
|
{
|
|
|
|
flag_session_start = true;
|
|
|
|
sleep(2); // **** important !! maybe systray runs later
|
|
|
|
}
|
|
|
|
else if (opt_eq(argv[i], "min")) // mini
|
|
|
|
{
|
|
|
|
flag_start_mini = true;
|
|
|
|
}
|
|
|
|
else if (strstr(argv[i], "screen"))
|
|
|
|
{
|
|
|
|
// int screenshot_main(int argc, char **argv);
|
|
|
|
// screenshot_main(argc,argv);
|
|
|
|
// return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// codec = QTextCodec::codecForLocale(); // for Local locale
|
|
|
|
check_system_requirement(); // check kernel version.. etc in proc.cpp
|
|
|
|
check_qps_running(); // check already qps running. in misc.cpp
|
|
|
|
|
|
|
|
QpsApp app(argc, argv);
|
|
|
|
|
|
|
|
init_misc(0); // init misc, some test code runs ...
|
|
|
|
qps = new Qps();
|
|
|
|
// sleep(20);
|
|
|
|
|
|
|
|
QString caption = "";
|
|
|
|
caption.append(getenv("USER"));
|
|
|
|
caption.append("@");
|
|
|
|
caption.append(short_hostname()); // geteuid()
|
|
|
|
|
|
|
|
qps->setWindowTitle(UniString(caption));
|
|
|
|
qps->setWindowIcon(QPixmap((const char **)icon_xpm));
|
|
|
|
|
|
|
|
// MOVETO Systray
|
|
|
|
QMenu *menu = new QMenu(qps);
|
|
|
|
/// menu->addAction( UniString("About"), qps, SLOT(about()) );
|
|
|
|
menu->addAction("Show", qps, SLOT(showNormal()));
|
|
|
|
menu->addAction("Hide", qps, SLOT(hide()));
|
|
|
|
menu->addSeparator();
|
|
|
|
if (flag_devel)
|
|
|
|
menu->addAction("ScreenShot", qps, SLOT(start_screenshot()));
|
|
|
|
menu->addAction("&Quit", qps, SLOT(save_quit()), Qt::ALT + Qt::Key_Q);
|
|
|
|
|
|
|
|
trayicon = new TrayIcon(QPixmap((const char **)icon_xpm /* init icon */),
|
|
|
|
"qps", menu);
|
|
|
|
QObject::connect(trayicon, SIGNAL(clicked(const QPoint &)), qps,
|
|
|
|
SLOT(clicked_trayicon()));
|
|
|
|
QObject::connect(trayicon, SIGNAL(doubleClicked(const QPoint &)), qps,
|
|
|
|
SLOT(clicked_trayicon()));
|
|
|
|
QObject::connect(trayicon,
|
|
|
|
SIGNAL(activated(QSystemTrayIcon::ActivationReason)), qps,
|
|
|
|
SLOT(clicked_trayicon(QSystemTrayIcon::ActivationReason)));
|
|
|
|
|
|
|
|
trayicon->sysInstall(); // ok
|
|
|
|
|
|
|
|
if (flag_session_start or flag_start_mini)
|
|
|
|
{
|
|
|
|
if (trayicon->hasSysTray())
|
|
|
|
{
|
|
|
|
qps->hide(); // qps->setHidden(true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
qps->showMinimized();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
qps->show();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Testing
|
|
|
|
// app.setStyleSheet(" QToolTip { opacity: 100;" "border-width:
|
|
|
|
// 1px;
|
|
|
|
// border-style: solid; border-color: rgb(50,110,80); border-radius:
|
|
|
|
// 4px ;"
|
|
|
|
//"background-color : rgba(0,0,0); padding: 3px; color: rgb(0,255,150);
|
|
|
|
//}");
|
|
|
|
QString str;
|
|
|
|
str.append("Qps ");
|
|
|
|
str.append(QPS_VERSION);
|
|
|
|
str.append(" launched.");
|
|
|
|
AddLog(str);
|
|
|
|
|
|
|
|
return app.exec();
|
|
|
|
}
|
|
|
|
|
|
|
|
#include <QDialog>
|
|
|
|
#include <QTextBrowser>
|
|
|
|
#include <QDesktopServices>
|
|
|
|
#include <QDialogButtonBox>
|
|
|
|
#include <QClipboard>
|
|
|
|
|
|
|
|
void Qps::test_popup(const QUrl &link)
|
|
|
|
{
|
|
|
|
|
|
|
|
QClipboard *clipboard = QApplication::clipboard();
|
|
|
|
clipboard->setText(link.toString(), QClipboard::Clipboard);
|
|
|
|
popupx->popup(QCursor::pos());
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::about()
|
|
|
|
{
|
|
|
|
QDialog *diag = new QDialog(this);
|
|
|
|
diag->setWindowTitle("About");
|
|
|
|
QVBoxLayout *lay = new QVBoxLayout(diag);
|
|
|
|
|
|
|
|
QLabel *label = new QLabel(diag);
|
|
|
|
// label->setMinimumSize( 400,200 );
|
|
|
|
label->setOpenExternalLinks(true);
|
|
|
|
// QLabel::setOpenExternalLinks ( bool open );
|
|
|
|
QTextBrowser *browser = new QTextBrowser(diag);
|
|
|
|
browser->setOpenExternalLinks(false);
|
|
|
|
browser->setOpenLinks(false);
|
|
|
|
|
|
|
|
connect(browser, SIGNAL(anchorClicked(const QUrl &)), this,
|
|
|
|
SLOT(test_popup(const QUrl &)));
|
|
|
|
|
|
|
|
lay->addWidget(label);
|
|
|
|
lay->addWidget(browser);
|
|
|
|
|
|
|
|
// QDesktopServices::openUrl(QUrl("file:///", QUrl::TolerantMode));
|
|
|
|
//
|
|
|
|
|
|
|
|
QString str("<h2> qps " QPS_VERSION " - A Visual Process Manager </h2> "
|
|
|
|
#ifdef SOLARIS
|
|
|
|
#ifdef _LP64
|
|
|
|
"64-bit "
|
|
|
|
#else
|
|
|
|
"32-bit "
|
|
|
|
#endif
|
|
|
|
"Solaris version "
|
|
|
|
#endif // SOLARIS
|
|
|
|
"using Qt library ");
|
|
|
|
|
|
|
|
str.append(qVersion());
|
|
|
|
str.append("<br><br>"
|
|
|
|
"<b>Source: </b><a href=\"https://github.com/QtDesktop/qps\">http://github.com/QtDesktop/qps/</a>"
|
|
|
|
"<br>"
|
|
|
|
"<b>Bugtracker: </b><a href=\"https://github.com/QtDesktop/qps/issues\">https://github.com/QtDesktop/qps/issues</a>"
|
|
|
|
);
|
|
|
|
|
|
|
|
label->setText(str);
|
|
|
|
|
|
|
|
str = "";
|
|
|
|
str.append("<b>Original Qps by</b><br>"
|
|
|
|
"Mattias Engdegård (f91-men@nada.kth.se)<br><br>"
|
|
|
|
"<b>Contributors</b><br>"
|
|
|
|
"Olivier.Daudel@u-paris10.fr<br>"
|
|
|
|
"jsanchez@todounix.homeip.net <br>"
|
|
|
|
"daehyun.yang@gmail.com <br>"
|
|
|
|
"Luís Pereira (luis.artur.pereira@gmail.com)<br>"
|
|
|
|
"Alf Gaida (agaida@siduction.org)<br>"
|
|
|
|
"Paulo Lieuthier (paulolieuthier@gmail.com)<br>"
|
|
|
|
"Jerome Leclanche (jerome@leclan.ch)<br>"
|
|
|
|
);
|
|
|
|
|
|
|
|
browser->setText(str);
|
|
|
|
|
|
|
|
QDialogButtonBox *bbox =
|
|
|
|
new QDialogButtonBox(QDialogButtonBox::Ok, Qt::Horizontal, diag);
|
|
|
|
|
|
|
|
lay->addWidget(bbox);
|
|
|
|
|
|
|
|
connect(bbox, SIGNAL(accepted()), diag, SLOT(accept()));
|
|
|
|
|
|
|
|
diag->exec();
|
|
|
|
|
|
|
|
// mb.setIconPixmap(QPixmap((const char **)icon_xpm));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qps::license() // -> help()
|
|
|
|
{
|
|
|
|
|
|
|
|
QDialog *diag = new QDialog(this);
|
|
|
|
diag->setWindowTitle("Quick Help");
|
|
|
|
// diag->setSizeGripEnabled(true) ;
|
|
|
|
QHBoxLayout *lay = new QHBoxLayout(diag);
|
|
|
|
|
|
|
|
QTextBrowser *browser = new QTextBrowser(diag);
|
|
|
|
browser->setMinimumSize(400, 200);
|
|
|
|
|
|
|
|
lay->addWidget(browser);
|
|
|
|
|
|
|
|
// QDesktopServices::openUrl(QUrl("file:///", QUrl::TolerantMode));
|
|
|
|
// QLabel::setOpenExternalLinks ( bool open );
|
|
|
|
browser->setOpenExternalLinks(true);
|
|
|
|
browser->setOpenLinks(true);
|
|
|
|
browser->setText(
|
|
|
|
"<H1>QPS Help</H1>"
|
|
|
|
"Updated: May 24 2005<BR>"
|
|
|
|
"<A "
|
|
|
|
"HREF=\"http://kldp.net/projects/qps\">http://kldp.net/projects/"
|
|
|
|
"qps</"
|
|
|
|
"A><HR>"
|
|
|
|
|
|
|
|
"<table style=\"text-align: center; width: 100%;\" border=\"1\""
|
|
|
|
" cellpadding=\"1\" cellspacing=\"0\">"
|
|
|
|
" <tbody>"
|
|
|
|
" <tr>"
|
|
|
|
" <td"
|
|
|
|
" style=\"vertical-align: top; background-color: rgb(204, 204, "
|
|
|
|
"204);\">Quit"
|
|
|
|
" </td>"
|
|
|
|
" <td > CTRL + q , CTRL + x"
|
|
|
|
" </td>"
|
|
|
|
" </tr>"
|
|
|
|
" <tr>"
|
|
|
|
" <td"
|
|
|
|
" style=\"vertical-align: top; background-color: rgb(204, 204, "
|
|
|
|
"204);\">Update"
|
|
|
|
" </td>"
|
|
|
|
" <td> Space , Enter "
|
|
|
|
" </td>"
|
|
|
|
" </tr>"
|
|
|
|
" <tr><td> process Terminate </td> <td> ALT + T , DELETE </td> "
|
|
|
|
"</tr>"
|
|
|
|
" <tr><td> process Kill </td> <td> ALT + K </td> </tr>"
|
|
|
|
" </tbody>"
|
|
|
|
"</table>");
|
|
|
|
diag->exec();
|
|
|
|
}
|
|
|
|
|
|
|
|
// slot
|
|
|
|
void Qps::start_screenshot() {}
|
|
|
|
|
|
|
|
// MOVETO qps::keyPressEvent()
|
|
|
|
void SearchBox::keyPressEvent(QKeyEvent *e)
|
|
|
|
{
|
|
|
|
if (e->key() == Qt::Key_Delete)
|
|
|
|
{
|
|
|
|
qps->sig_term();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e->key() == Qt::Key_Escape)
|
|
|
|
{
|
|
|
|
|
|
|
|
clear(); // clear searchbox
|
|
|
|
|
|
|
|
qps->pstable->clearAllSelections(); // TEMP
|
|
|
|
|
|
|
|
// xb->setDown(true);
|
|
|
|
// event_xbutton_clicked();
|
|
|
|
// xb->setDown(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
QLineEdit::keyPressEvent(e);
|
|
|
|
|
|
|
|
qps->procview->filterstr = text();
|
|
|
|
qps->pstable->refresh(); /// qps->refresh(); // better ?
|
|
|
|
}
|
|
|
|
|
|
|
|
void STATUSBAR_COUNT_UPDATE() {}
|
|
|
|
|
|
|
|
void STATUSBAR_SETCOUNT(int n)
|
|
|
|
{
|
|
|
|
if (qps)
|
|
|
|
qps->statusBar->update(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PSTABLE_SETTREEMODE(bool mode)
|
|
|
|
{
|
|
|
|
if (qps)
|
|
|
|
qps->pstable->setTreeMode(mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
void QPS_SHOW()
|
|
|
|
{
|
|
|
|
if (qps)
|
|
|
|
qps->showNormal();
|
|
|
|
}
|
|
|
|
|
|
|
|
// TESTING
|
|
|
|
int QPS_PROCVIEW_CPU_NUM()
|
|
|
|
{
|
|
|
|
if (qps)
|
|
|
|
return qps->procview->num_cpus;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AddLog(QString str)
|
|
|
|
{
|
|
|
|
qDebug() << qps;
|
|
|
|
if (qps && qps->logbox)
|
|
|
|
{
|
|
|
|
qps->logbox->append(str);
|
|
|
|
}
|
|
|
|
}
|