mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-23 18:32:50 +00:00

to what degree session management is supported is different story, e.g. if there is no kRestoreMainWindows<T>() call (or other method that actually restores state) then the application is simply started again on login and placed where it was in the window state it was by the window manager Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
577 lines
18 KiB
C++
577 lines
18 KiB
C++
/*
|
|
KSysGuard, the KDE System Guard
|
|
|
|
Copyright (c) 2006 - 2008 John Tapsell <john.tapsell@kde.org>
|
|
Copyright (c) 1999 - 2001 Chris Schlaeger <cs@kde.org>
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public
|
|
License version 2 or at your option version 3 as published by
|
|
the Free Software Foundation.
|
|
|
|
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.
|
|
|
|
KSysGuard has been written with some source code and ideas from
|
|
ktop (<1.0). Early versions of ktop have been written by Bernd
|
|
Johannes Wuebben <wuebben@math.cornell.edu> and Nicolas Leclercq
|
|
<nicknet@planete.net>.
|
|
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <ctype.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
#include <kaboutdata.h>
|
|
#include <kaction.h>
|
|
#include <kactioncollection.h>
|
|
#include <kapplication.h>
|
|
#include <kcmdlineargs.h>
|
|
#include <kdebug.h>
|
|
#include <kedittoolbar.h>
|
|
#include <kglobal.h>
|
|
#include <kglobalsettings.h>
|
|
#include <kicon.h>
|
|
#include <klocale.h>
|
|
#include <kmessagebox.h>
|
|
#include <ksgrd/SensorAgent.h>
|
|
#include <ksgrd/SensorManager.h>
|
|
#include <kstatusbar.h>
|
|
#include <kstandardaction.h>
|
|
#include <ktoggleaction.h>
|
|
#include <kurl.h>
|
|
#include <kwindowsystem.h>
|
|
#include <kdeversion.h>
|
|
#include <QSplitter>
|
|
|
|
#include <config-workspace.h>
|
|
#include "SensorBrowser.h"
|
|
#include "Workspace.h"
|
|
#include "WorkSheet.h"
|
|
#include "StyleEngine.h"
|
|
#include "HostConnector.h"
|
|
#include "ProcessController.h"
|
|
#include "processui/ksysguardprocesslist.h"
|
|
|
|
#include "ksysguard.h"
|
|
|
|
//Comment out to stop ksysguard from forking. Good for debugging
|
|
//#define FORK_KSYSGUARD
|
|
|
|
static const char Description[] = I18N_NOOP( "KDE System Monitor" );
|
|
TopLevel* Toplevel;
|
|
|
|
TopLevel::TopLevel()
|
|
: KXmlGuiWindow( NULL, Qt::WindowContextHelpButtonHint)
|
|
{
|
|
QDBusConnection::sessionBus().registerObject("/", this, QDBusConnection::ExportScriptableSlots);
|
|
mTimerId = -1;
|
|
mLocalProcessController = NULL;
|
|
|
|
mSplitter = new QSplitter( this );
|
|
mSplitter->setOrientation( Qt::Horizontal );
|
|
mSplitter->setOpaqueResize( KGlobalSettings::opaqueResize() );
|
|
setCentralWidget( mSplitter );
|
|
|
|
mSensorBrowser = 0;
|
|
|
|
mWorkSpace = new Workspace( mSplitter );
|
|
connect( mWorkSpace, SIGNAL(setCaption(QString)),
|
|
SLOT(setCaption(QString)) );
|
|
connect( mWorkSpace, SIGNAL(currentChanged(int)),
|
|
SLOT(currentTabChanged(int)) );
|
|
|
|
/* Create the status bar. It displays some information about the
|
|
* number of processes and the memory consumption of the local
|
|
* host. */
|
|
const int STATUSBAR_STRETCH=1;
|
|
|
|
sbProcessCount = new QLabel();
|
|
statusBar()->addWidget( sbProcessCount, STATUSBAR_STRETCH );
|
|
|
|
sbCpuStat = new QLabel();
|
|
statusBar()->addWidget( sbCpuStat, STATUSBAR_STRETCH );
|
|
|
|
sbMemTotal = new QLabel();
|
|
statusBar()->addWidget( sbMemTotal, STATUSBAR_STRETCH );
|
|
|
|
sbSwapTotal = new QLabel();
|
|
statusBar()->addWidget( sbSwapTotal, STATUSBAR_STRETCH );
|
|
|
|
statusBar()->hide();
|
|
|
|
// create actions for menu entries
|
|
mRefreshTabAction = KStandardAction::redisplay(mWorkSpace,SLOT(refreshActiveWorksheet()),actionCollection());
|
|
mNewWorksheetAction = actionCollection()->addAction("new_worksheet");
|
|
mNewWorksheetAction->setIcon(KIcon("tab-new"));
|
|
connect(mNewWorksheetAction, SIGNAL(triggered(bool)), mWorkSpace, SLOT(newWorkSheet()));
|
|
mInsertWorksheetAction = actionCollection()->addAction("import_worksheet");
|
|
mInsertWorksheetAction->setIcon(KIcon("document-open") );
|
|
connect(mInsertWorksheetAction, SIGNAL(triggered(bool)), mWorkSpace, SLOT(importWorkSheet()));
|
|
mTabExportAction = actionCollection()->addAction( "export_worksheet" );
|
|
mTabExportAction->setIcon( KIcon("document-save-as") );
|
|
connect(mTabExportAction, SIGNAL(triggered(bool)), mWorkSpace, SLOT(exportWorkSheet()));
|
|
mTabRemoveAction = actionCollection()->addAction( "remove_worksheet" );
|
|
mTabRemoveAction->setIcon( KIcon("tab-close") );
|
|
connect(mTabRemoveAction, SIGNAL(triggered(bool)), mWorkSpace, SLOT(removeWorkSheet()));
|
|
mMonitorRemoteAction = actionCollection()->addAction( "connect_host" );
|
|
mMonitorRemoteAction->setIcon( KIcon("network-connect") );
|
|
connect(mMonitorRemoteAction, SIGNAL(triggered(bool)), SLOT(connectHost()));
|
|
|
|
mQuitAction = NULL;
|
|
|
|
mConfigureSheetAction = actionCollection()->addAction( "configure_sheet" );
|
|
mConfigureSheetAction->setIcon( KIcon("configure") );
|
|
connect(mConfigureSheetAction, SIGNAL(triggered(bool)), SLOT(configureCurrentSheet()));
|
|
|
|
retranslateUi();
|
|
}
|
|
|
|
void TopLevel::setLocalProcessController(ProcessController * localProcessController)
|
|
{
|
|
Q_ASSERT(!mLocalProcessController);
|
|
mLocalProcessController = localProcessController;
|
|
connect( mLocalProcessController, SIGNAL(processListChanged()), this, SLOT(updateProcessCount()));
|
|
for(int i = 0; i < mLocalProcessController->actions().size(); i++) {
|
|
actionCollection()->addAction("processAction" + QString::number(i), mLocalProcessController->actions().at(i));
|
|
}
|
|
}
|
|
|
|
void TopLevel::retranslateUi()
|
|
{
|
|
setWindowTitle( i18n( "System Monitor" ) );
|
|
mRefreshTabAction->setText(i18n("&Refresh Tab"));
|
|
mNewWorksheetAction->setText(i18n( "&New Tab..." ));
|
|
mInsertWorksheetAction->setText(i18n( "Import Tab Fr&om File..." ));
|
|
mTabExportAction->setText( i18n( "Save Tab &As..." ) );
|
|
mTabRemoveAction->setText( i18n( "&Close Tab" ) );
|
|
mMonitorRemoteAction->setText( i18n( "Monitor &Remote Machine..." ) );
|
|
|
|
mConfigureSheetAction->setText( i18n( "Tab &Properties" ) );
|
|
if(mQuitAction) {
|
|
KAction *tmpQuitAction = KStandardAction::quit( NULL, NULL, NULL );
|
|
mQuitAction->setText(tmpQuitAction->text());
|
|
mQuitAction->setWhatsThis(tmpQuitAction->whatsThis());
|
|
mQuitAction->setToolTip(tmpQuitAction->toolTip());
|
|
delete tmpQuitAction;
|
|
} else
|
|
mQuitAction = KStandardAction::quit( this, SLOT(close()), actionCollection() );
|
|
}
|
|
|
|
void TopLevel::configureCurrentSheet() {
|
|
mWorkSpace->configure();
|
|
mRefreshTabAction->setVisible( mWorkSpace->currentWorkSheet()->updateInterval() == 0 );
|
|
}
|
|
void TopLevel::currentTabChanged(int index)
|
|
{
|
|
QWidget *wdg = mWorkSpace->widget(index);
|
|
WorkSheet *sheet = (WorkSheet *)(wdg);
|
|
Q_ASSERT(sheet);
|
|
bool locked = !sheet || sheet->isLocked();
|
|
mTabRemoveAction->setVisible(!locked);
|
|
mTabExportAction->setVisible(!locked);
|
|
mMonitorRemoteAction->setVisible(!locked);
|
|
|
|
//only show refresh option is update interval is 0 (manual)
|
|
mRefreshTabAction->setVisible( sheet->updateInterval() == 0 );
|
|
|
|
if(!locked && !mSensorBrowser) {
|
|
startSensorBrowserWidget();
|
|
}
|
|
if(mSensorBrowser) {
|
|
if(mSensorBrowser->isVisible() && locked) //going from visible to not visible to save the state
|
|
mSplitterSize = mSplitter->sizes();
|
|
mSensorBrowser->setVisible(!locked);
|
|
|
|
}
|
|
}
|
|
void TopLevel::startSensorBrowserWidget()
|
|
{
|
|
if(mSensorBrowser) return;
|
|
mSensorBrowser = new SensorBrowserWidget( 0, KSGRD::SensorMgr );
|
|
mSplitter->insertWidget(2,mSensorBrowser);
|
|
mSplitter->setSizes( mSplitterSize );
|
|
}
|
|
|
|
/*
|
|
* DBUS Interface functions
|
|
*/
|
|
|
|
void TopLevel::showOnCurrentDesktop()
|
|
{
|
|
KWindowSystem::setOnDesktop( winId(), KWindowSystem::currentDesktop() );
|
|
kapp->updateUserTimestamp();
|
|
KWindowSystem::forceActiveWindow( winId() );
|
|
}
|
|
|
|
void TopLevel::importWorkSheet( const QString &fileName )
|
|
{
|
|
mWorkSpace->importWorkSheet( KUrl( fileName ) );
|
|
}
|
|
|
|
void TopLevel::removeWorkSheet( const QString &fileName )
|
|
{
|
|
mWorkSpace->removeWorkSheet( fileName );
|
|
}
|
|
|
|
QStringList TopLevel::listSensors( const QString &hostName )
|
|
{
|
|
if(!mSensorBrowser) {
|
|
setUpdatesEnabled(false);
|
|
startSensorBrowserWidget();
|
|
mSensorBrowser->setVisible(false);
|
|
setUpdatesEnabled(true);
|
|
}
|
|
return mSensorBrowser->listSensors( hostName );
|
|
}
|
|
|
|
QStringList TopLevel::listHosts()
|
|
{
|
|
if(!mSensorBrowser) {
|
|
setUpdatesEnabled(false);
|
|
startSensorBrowserWidget();
|
|
mSensorBrowser->setVisible(false);
|
|
setUpdatesEnabled(true);
|
|
}
|
|
return mSensorBrowser->listHosts();
|
|
}
|
|
|
|
void TopLevel::initStatusBar()
|
|
{
|
|
KSGRD::SensorMgr->engage( "localhost", "", "ksysguardd" );
|
|
/* Request info about the swap space size and the units it is
|
|
* measured in. The requested info will be received by
|
|
* answerReceived(). */
|
|
KSGRD::SensorMgr->sendRequest( "localhost", "mem/swap/used?",
|
|
(KSGRD::SensorClient*)this, 7 );
|
|
|
|
KToggleAction *sb = qobject_cast<KToggleAction*>(action("options_show_statusbar"));
|
|
if (sb)
|
|
connect(sb, SIGNAL(toggled(bool)), this, SLOT(updateStatusBar()));
|
|
setupGUI(QSize(800,600), ToolBar | Keys | StatusBar | Save | Create);
|
|
|
|
updateStatusBar();
|
|
}
|
|
|
|
void TopLevel::updateStatusBar()
|
|
{
|
|
if ( mTimerId == -1 )
|
|
mTimerId = startTimer( 2000 );
|
|
|
|
// call timerEvent to fill the status bar with real values
|
|
timerEvent( 0 );
|
|
}
|
|
|
|
void TopLevel::connectHost()
|
|
{
|
|
HostConnector hostConnector( this );
|
|
|
|
// hostConnector.setHostNames( mHostList );
|
|
// hostConnector.setCommands( mCommandList );
|
|
|
|
// hostConnector.setCurrentHostName( "" );
|
|
|
|
if ( !hostConnector.exec() )
|
|
return;
|
|
|
|
// mHostList = hostConnector.hostNames();
|
|
// mCommandList = hostConnector.commands();
|
|
|
|
QString shell = "";
|
|
QString command = "";
|
|
int port = -1;
|
|
|
|
/* Check which radio button is selected and set parameters
|
|
* appropriately. */
|
|
if ( hostConnector.useSsh() )
|
|
shell = "ssh";
|
|
else if ( hostConnector.useRsh() )
|
|
shell = "rsh";
|
|
else if ( hostConnector.useDaemon() )
|
|
port = hostConnector.port();
|
|
else
|
|
command = hostConnector.currentCommand();
|
|
|
|
KSGRD::SensorMgr->engage( hostConnector.currentHostName(), shell, command, port );
|
|
}
|
|
|
|
void TopLevel::disconnectHost()
|
|
{
|
|
if(mSensorBrowser)
|
|
mSensorBrowser->disconnect();
|
|
}
|
|
|
|
bool TopLevel::event( QEvent *e )
|
|
{
|
|
if ( e->type() == QEvent::User ) {
|
|
/* Due to the asynchronous communication between ksysguard and its
|
|
* back-ends, we sometimes need to show message boxes that were
|
|
* triggered by objects that have died already. */
|
|
KMessageBox::error( this, static_cast<KSGRD::SensorManager::MessageEvent*>(e)->message() );
|
|
|
|
return true;
|
|
}
|
|
|
|
return KXmlGuiWindow::event( e );
|
|
}
|
|
|
|
void TopLevel::timerEvent( QTimerEvent* )
|
|
{
|
|
if ( statusBar()->isVisibleTo( this ) ) {
|
|
/* Request some info about the memory status. The requested
|
|
* information will be received by answerReceived(). */
|
|
KSGRD::SensorMgr->sendRequest( "localhost", "cpu/idle",
|
|
(KSGRD::SensorClient*)this, 1 );
|
|
KSGRD::SensorMgr->sendRequest( "localhost", "mem/physical/free",
|
|
(KSGRD::SensorClient*)this, 2 );
|
|
KSGRD::SensorMgr->sendRequest( "localhost", "mem/physical/used",
|
|
(KSGRD::SensorClient*)this, 3 );
|
|
KSGRD::SensorMgr->sendRequest( "localhost", "mem/physical/application",
|
|
(KSGRD::SensorClient*)this, 4 );
|
|
KSGRD::SensorMgr->sendRequest( "localhost", "mem/swap/free",
|
|
(KSGRD::SensorClient*)this, 5 );
|
|
KSGRD::SensorMgr->sendRequest( "localhost", "mem/swap/used",
|
|
(KSGRD::SensorClient*)this, 6 );
|
|
}
|
|
}
|
|
|
|
void TopLevel::updateProcessCount() {
|
|
const QString s = i18np( "1 process" "\xc2\x9c" "1", "%1 processes" "\xc2\x9c" "%1", mLocalProcessController->processList()->visibleProcessesCount() );
|
|
sbProcessCount->setText( s );
|
|
}
|
|
void TopLevel::changeEvent( QEvent * event )
|
|
{
|
|
if (event->type() == QEvent::LanguageChange) {
|
|
KSGRD::SensorMgr->retranslate();
|
|
setUpdatesEnabled(false);
|
|
setupGUI(ToolBar | Keys | StatusBar | Create);
|
|
retranslateUi();
|
|
setUpdatesEnabled(true);
|
|
}
|
|
KXmlGuiWindow::changeEvent(event);
|
|
}
|
|
|
|
bool TopLevel::queryClose()
|
|
{
|
|
if ( !mWorkSpace->saveOnQuit() )
|
|
return false;
|
|
|
|
KConfigGroup cg( KGlobal::config(), "MainWindow" );
|
|
saveProperties( cg );
|
|
KGlobal::config()->sync();
|
|
|
|
return true;
|
|
}
|
|
|
|
void TopLevel::readProperties( const KConfigGroup& cfg )
|
|
{
|
|
|
|
/* we can ignore 'isMaximized' because we can't set the window
|
|
maximized, so we save the coordinates instead */
|
|
// if ( cfg.readEntry( "isMinimized" , false) == true )
|
|
// showMinimized();
|
|
|
|
mSplitterSize = cfg.readEntry( "SplitterSizeList",QList<int>() );
|
|
if ( mSplitterSize.isEmpty() ) {
|
|
// start with a 30/70 ratio
|
|
mSplitterSize.append( 10 );
|
|
mSplitterSize.append( 90 );
|
|
}
|
|
|
|
KSGRD::SensorMgr->readProperties( cfg );
|
|
KSGRD::Style->readProperties( cfg );
|
|
|
|
mWorkSpace->readProperties( cfg );
|
|
}
|
|
|
|
void TopLevel::saveProperties( KConfigGroup& cfg )
|
|
{
|
|
cfg.writeEntry( "isMinimized", isMinimized() );
|
|
|
|
if(mSensorBrowser && mSensorBrowser->isVisible())
|
|
cfg.writeEntry( "SplitterSizeList", mSplitter->sizes());
|
|
else if(mSplitterSize.size() == 2 && mSplitterSize.value(0) != 0 && mSplitterSize.value(1) != 0)
|
|
cfg.writeEntry( "SplitterSizeList", mSplitterSize );
|
|
|
|
KSGRD::Style->saveProperties( cfg );
|
|
KSGRD::SensorMgr->saveProperties( cfg );
|
|
|
|
saveMainWindowSettings( cfg );
|
|
mWorkSpace->saveProperties( cfg );
|
|
}
|
|
|
|
void TopLevel::answerReceived( int id, const QList<QByteArray> &answerList )
|
|
{
|
|
// we have received an answer from the daemon.
|
|
QByteArray answer;
|
|
if(!answerList.isEmpty()) answer = answerList[0];
|
|
QString s;
|
|
static QString unit;
|
|
static qlonglong mFree = 0;
|
|
static qlonglong mUsedApplication = 0;
|
|
static qlonglong mUsedTotal = 0;
|
|
static qlonglong sUsed = 0;
|
|
static qlonglong sFree = 0;
|
|
|
|
switch ( id ) {
|
|
case 1:
|
|
s = i18n( "CPU: %1%\xc2\x9c%1%", (int) (100 - answer.toFloat()) );
|
|
sbCpuStat->setText( s );
|
|
break;
|
|
|
|
case 2:
|
|
mFree = answer.toLongLong();
|
|
break;
|
|
|
|
case 3:
|
|
mUsedTotal = answer.toLongLong();
|
|
break;
|
|
|
|
case 4:
|
|
mUsedApplication = answer.toLongLong();
|
|
//Use a multi-length string
|
|
s = i18nc( "Arguments are formatted byte sizes (used/total)", "Memory: %1 / %2" "\xc2\x9c" "Mem: %1 / %2" "\xc2\x9c" "Mem: %1" "\xc2\x9c" "%1",
|
|
KGlobal::locale()->formatByteSize( mUsedApplication*1024),
|
|
KGlobal::locale()->formatByteSize( (mFree+mUsedTotal)*1024 ) );
|
|
sbMemTotal->setText( s );
|
|
break;
|
|
|
|
case 5:
|
|
sFree = answer.toLongLong();
|
|
break;
|
|
|
|
case 6:
|
|
sUsed = answer.toLongLong();
|
|
setSwapInfo( sUsed, sFree, unit );
|
|
break;
|
|
|
|
case 7: {
|
|
KSGRD::SensorIntegerInfo info( answer );
|
|
unit = KSGRD::SensorMgr->translateUnit( info.unit() );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TopLevel::setSwapInfo( qlonglong used, qlonglong free, const QString & )
|
|
{
|
|
QString msg;
|
|
if ( used == 0 && free == 0 ) // no swap available
|
|
msg = i18n( " No swap space available " );
|
|
else {
|
|
msg = i18nc( "Arguments are formatted byte sizes (used/total)", "Swap: %1 / %2" "\xc2\x9c" "Swap: %1" "\xc2\x9c" "%1" ,
|
|
KGlobal::locale()->formatByteSize( used*1024 ),
|
|
KGlobal::locale()->formatByteSize( (free+used)*1024) );
|
|
}
|
|
|
|
sbSwapTotal->setText( msg );
|
|
}
|
|
|
|
/*
|
|
* Once upon a time...
|
|
*/
|
|
int main( int argc, char** argv )
|
|
{
|
|
// initpipe is used to keep the parent process around till the child
|
|
// has registered with dbus
|
|
#ifdef FORK_KSYSGUARD
|
|
int initpipe[ 2 ];
|
|
pipe( initpipe );
|
|
/* This forking will put ksysguard in it's own session not having a
|
|
* controlling terminal attached to it. This prevents ssh from
|
|
* using this terminal for password requests. Thus, you
|
|
* need a ssh with ssh-askpass support to popup an X dialog to
|
|
* enter the password. */
|
|
pid_t pid;
|
|
if ( ( pid = fork() ) < 0 )
|
|
return -1;
|
|
else
|
|
if ( pid != 0 ) {
|
|
close( initpipe[ 1 ] );
|
|
|
|
// wait till init is complete
|
|
char c;
|
|
while( read( initpipe[ 0 ], &c, 1 ) < 0 );
|
|
|
|
// then exit
|
|
close( initpipe[ 0 ] );
|
|
exit( 0 );
|
|
}
|
|
|
|
close( initpipe[ 0 ] );
|
|
setsid();
|
|
#endif
|
|
|
|
KAboutData aboutData( "ksysguard", 0, ki18n( "System Monitor" ),
|
|
KDE_VERSION_STRING, ki18n(Description), KAboutData::License_GPL,
|
|
ki18n( "(c) 1996-2008 The KDE System Monitor Developers" ) );
|
|
aboutData.addAuthor( ki18n("John Tapsell"), ki18n("Current Maintainer"), "john.tapsell@kde.org" );
|
|
aboutData.addAuthor( ki18n("Chris Schlaeger"), ki18n("Previous Maintainer"), "cs@kde.org" );
|
|
aboutData.addAuthor( ki18n("Greg Martyn"), KLocalizedString(), "greg.martyn@gmail.com" );
|
|
aboutData.addAuthor( ki18n("Tobias Koenig"), KLocalizedString(), "tokoe@kde.org" );
|
|
aboutData.addAuthor( ki18n("Nicolas Leclercq"), KLocalizedString(), "nicknet@planete.net" );
|
|
aboutData.addAuthor( ki18n("Alex Sanda"), KLocalizedString(), "alex@darkstart.ping.at" );
|
|
aboutData.addAuthor( ki18n("Bernd Johannes Wuebben"), KLocalizedString(), "wuebben@math.cornell.edu" );
|
|
aboutData.addAuthor( ki18n("Ralf Mueller"), KLocalizedString(), "rlaf@bj-ig.de" );
|
|
aboutData.addAuthor( ki18n("Hamish Rodda"), KLocalizedString(), "rodda@kde.org" );
|
|
aboutData.addAuthor( ki18n("Torsten Kasch"), ki18n( "Solaris Support\n"
|
|
"Parts derived (by permission) from the sunos5\n"
|
|
"module of William LeFebvre's \"top\" utility." ),
|
|
"tk@Genetik.Uni-Bielefeld.DE" );
|
|
aboutData.setProgramIconName("utilities-system-monitor");
|
|
|
|
KCmdLineArgs::init( argc, argv, &aboutData );
|
|
|
|
KCmdLineOptions options;
|
|
options.add("+[worksheet]", ki18n( "Optional worksheet files to load" ));
|
|
KCmdLineArgs::addCmdLineOptions( options );
|
|
// initialize KDE application
|
|
KApplication *app = new KApplication();
|
|
app->enableSessionManagement();
|
|
|
|
KSGRD::SensorMgr = new KSGRD::SensorManager();
|
|
KSGRD::Style = new KSGRD::StyleEngine();
|
|
|
|
#ifdef FORK_KSYSGUARD
|
|
char c = 0;
|
|
write( initpipe[ 1 ], &c, 1 );
|
|
close( initpipe[ 1 ] );
|
|
#endif
|
|
Toplevel = new TopLevel();
|
|
|
|
|
|
// create top-level widget
|
|
Toplevel->readProperties( KConfigGroup( KGlobal::config(), "MainWindow" ) );
|
|
// setup the statusbar, toolbar etc.
|
|
// Note that this comes after creating the top-level widgets whcih also
|
|
// sets up the various QActions that the user may have added to the toolbar
|
|
Toplevel->initStatusBar();
|
|
|
|
//There seems to be some serious bugs with the session restore code. Disabling
|
|
// if ( app->isSessionRestored() )
|
|
// Toplevel->restore( 1 );
|
|
|
|
Toplevel->show();
|
|
KSGRD::SensorMgr->setBroadcaster( Toplevel ); // SensorMgr uses a QPointer for toplevel, so it is okay if Toplevel is deleted first
|
|
|
|
// run the application
|
|
int result = app->exec();
|
|
|
|
delete app;
|
|
delete KSGRD::SensorMgr;
|
|
delete KSGRD::Style;
|
|
|
|
return result;
|
|
}
|
|
|
|
#include "moc_ksysguard.cpp"
|