diff options
Diffstat (limited to 'kcontrol/screensaver/scrnsave.cpp')
-rw-r--r-- | kcontrol/screensaver/scrnsave.cpp | 1019 |
1 files changed, 1019 insertions, 0 deletions
diff --git a/kcontrol/screensaver/scrnsave.cpp b/kcontrol/screensaver/scrnsave.cpp new file mode 100644 index 000000000..a0b26ae46 --- /dev/null +++ b/kcontrol/screensaver/scrnsave.cpp @@ -0,0 +1,1019 @@ +//----------------------------------------------------------------------------- +// +// KDE Display screen saver setup module +// +// Copyright (c) Martin R. Jones 1996,1999,2002 +// +// Converted to a kcc module by Matthias Hoelzer 1997 +// + + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/stat.h> + +#include <tqbuttongroup.h> +#include <tqcheckbox.h> +#include <tqheader.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqlistview.h> +#include <tqpushbutton.h> +#include <tqslider.h> +#include <tqtimer.h> +#include <tqfileinfo.h> +#include <tqwhatsthis.h> + +#include <dcopclient.h> + +#include <tdeaboutdata.h> +#include <tdeapplication.h> +#include <kdebug.h> +#include <kdialog.h> +#include <kdialogbase.h> +#include <kgenericfactory.h> +#include <kiconloader.h> +#include <knuminput.h> +#include <kprocess.h> +#include <kservicegroup.h> +#include <kstandarddirs.h> +#include <ksimpleconfig.h> + +#include <X11/Xlib.h> + +#include "scrnsave.h" + +#include <fixx11h.h> + +#define OPEN_TDMCONFIG_AND_SET_GROUP \ +if( stat( KDE_CONFDIR "/tdm/tdmdistrc" , &st ) == 0) { \ + mTDMConfig = new KSimpleConfig( TQString::fromLatin1( KDE_CONFDIR "/tdm/tdmdistrc" )); \ +} \ +else { \ + mTDMConfig = new KSimpleConfig( TQString::fromLatin1( KDE_CONFDIR "/tdm/tdmrc" )); \ +} \ +mTDMConfig->setGroup("X-:*-Greeter"); + +template class TQPtrList<SaverConfig>; + +const uint widgetEventMask = // X event mask +(uint)( + ExposureMask | + PropertyChangeMask | + StructureNotifyMask + ); + +//=========================================================================== +// DLL Interface for kcontrol +typedef KGenericFactory<KScreenSaver, TQWidget > KSSFactory; +K_EXPORT_COMPONENT_FACTORY (kcm_screensaver, KSSFactory("kcmscreensaver") ) + + +static TQString findExe(const TQString &exe) { + TQString result = locate("exe", exe); + if (result.isEmpty()) + result = TDEStandardDirs::findExe(exe); + return result; +} + +KScreenSaver::KScreenSaver(TQWidget *parent, const char *name, const TQStringList&) + : TDECModule(KSSFactory::instance(), parent, name) +{ + mSetupProc = 0; + mPreviewProc = 0; + mTestWin = 0; + mTestProc = 0; + mPrevSelected = -2; + mMonitor = 0; + mTesting = false; + + struct stat st; + OPEN_TDMCONFIG_AND_SET_GROUP + + // Add non-TDE path + TDEGlobal::dirs()->addResourceType("scrsav", + TDEGlobal::dirs()->kde_default("apps") + + "apps/ScreenSavers/"); + + setQuickHelp( i18n("<h1>Screen Saver</h1> This module allows you to enable and" + " configure a screen saver. Note that you can enable a screen saver" + " even if you have power saving features enabled for your display.<p>" + " Besides providing an endless variety of entertainment and" + " preventing monitor burn-in, a screen saver also gives you a simple" + " way to lock your display if you are going to leave it unattended" + " for a while. If you want the screen saver to lock the session, make sure you enable" + " the \"Require password\" feature of the screen saver; if you do not, you can still" + " explicitly lock the session using the desktop's \"Lock Session\" action.")); + + setButtons( TDECModule::Help | TDECModule::Default | TDECModule::Apply ); + + // Add KDE specific screensaver path + TQString relPath="System/ScreenSavers/"; + KServiceGroup::Ptr servGroup = KServiceGroup::baseGroup( "screensavers" ); + if (servGroup) + { + relPath=servGroup->relPath(); + kdDebug() << "relPath=" << relPath << endl; + } + + TDEGlobal::dirs()->addResourceType("scrsav", + TDEGlobal::dirs()->kde_default("apps") + + relPath); + + readSettings( false ); + + mSetupProc = new TDEProcess; + connect(mSetupProc, TQT_SIGNAL(processExited(TDEProcess *)), + this, TQT_SLOT(slotSetupDone(TDEProcess *))); + + mPreviewProc = new TDEProcess; + connect(mPreviewProc, TQT_SIGNAL(processExited(TDEProcess *)), + this, TQT_SLOT(slotPreviewExited(TDEProcess *))); + + TQBoxLayout *topLayout = new TQHBoxLayout(this, 0, KDialog::spacingHint()); + + // left column + TQVBoxLayout *leftColumnLayout = + new TQVBoxLayout(topLayout, KDialog::spacingHint()); + TQBoxLayout *vLayout = + new TQVBoxLayout(leftColumnLayout, KDialog::spacingHint()); + + mSaverGroup = new TQGroupBox(i18n("Screen Saver"), this ); + mSaverGroup->setColumnLayout( 0, Qt::Horizontal ); + vLayout->addWidget(mSaverGroup); + vLayout->setStretchFactor( mSaverGroup, 10 ); + TQBoxLayout *groupLayout = new TQVBoxLayout( mSaverGroup->layout(), + KDialog::spacingHint() ); + + mSaverListView = new TQListView( mSaverGroup ); + mSaverListView->setMinimumHeight( 120 ); + mSaverListView->setSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Expanding); + mSaverListView->addColumn(""); + mSaverListView->header()->hide(); + mSelected = -1; + groupLayout->addWidget( mSaverListView, 10 ); + connect( mSaverListView, TQT_SIGNAL(doubleClicked ( TQListViewItem *)), this, TQT_SLOT( slotSetup())); + TQWhatsThis::add( mSaverListView, i18n("Select the screen saver to use.") ); + + TQBoxLayout* hlay = new TQHBoxLayout(groupLayout, KDialog::spacingHint()); + mSetupBt = new TQPushButton( i18n("&Setup..."), mSaverGroup ); + connect( mSetupBt, TQT_SIGNAL( clicked() ), TQT_SLOT( slotSetup() ) ); + mSetupBt->setEnabled(false); + hlay->addWidget( mSetupBt ); + TQWhatsThis::add( mSetupBt, i18n("Configure the screen saver's options, if any.") ); + + mTestBt = new TQPushButton( i18n("&Test"), mSaverGroup ); + connect( mTestBt, TQT_SIGNAL( clicked() ), TQT_SLOT( slotTest() ) ); + mTestBt->setEnabled(false); + hlay->addWidget( mTestBt ); + TQWhatsThis::add( mTestBt, i18n("Show a full screen preview of the screen saver.") ); + + mSettingsGroup = new TQGroupBox( i18n("Settings"), this ); + mSettingsGroup->setColumnLayout( 0, Qt::Vertical ); + leftColumnLayout->addWidget( mSettingsGroup ); + TQGridLayout *settingsGroupLayout = new TQGridLayout( mSettingsGroup->layout(), 5, 2, KDialog::spacingHint() ); + + mEnabledCheckBox = new TQCheckBox(i18n("Start a&utomatically"), mSettingsGroup); + mEnabledCheckBox->setChecked(mEnabled); + TQWhatsThis::add( mEnabledCheckBox, i18n("Automatically start the screen saver after a period of inactivity.") ); + connect(mEnabledCheckBox, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotEnable(bool))); + settingsGroupLayout->addWidget(mEnabledCheckBox, 0, 0); + + TQBoxLayout *hbox = new TQHBoxLayout(); + settingsGroupLayout->addLayout(hbox, 1, 0); + hbox->addSpacing(30); + mActivateLbl = new TQLabel(i18n("After:"), mSettingsGroup); + mActivateLbl->setEnabled(mEnabled); + hbox->addWidget(mActivateLbl); + mWaitEdit = new TQSpinBox(mSettingsGroup); + mWaitEdit->setSteps(1, 10); + mWaitEdit->setRange(1, INT_MAX); + mWaitEdit->setSuffix(i18n(" min")); + mWaitEdit->setValue(mTimeout/60); + mWaitEdit->setEnabled(mEnabled); + connect(mWaitEdit, TQT_SIGNAL(valueChanged(int)), + this, TQT_SLOT(slotTimeoutChanged(int))); + mActivateLbl->setBuddy(mWaitEdit); + hbox->addWidget(mWaitEdit); + hbox->addStretch(1); + TQString wtstr = i18n("The period of inactivity after which the screen saver should start."); + TQWhatsThis::add( mActivateLbl, wtstr ); + TQWhatsThis::add( mWaitEdit, wtstr ); + + mLockCheckBox = new TQCheckBox( i18n("&Require password to stop"), mSettingsGroup ); + mLockCheckBox->setEnabled( mEnabled ); + mLockCheckBox->setChecked( mLock ); + connect( mLockCheckBox, TQT_SIGNAL( toggled( bool ) ), this, TQT_SLOT( slotLock( bool ) ) ); + settingsGroupLayout->addWidget(mLockCheckBox, 2, 0); + TQWhatsThis::add( mLockCheckBox, i18n("Prevent potential unauthorized use by requiring a password to stop the screen saver.") ); + + hbox = new TQHBoxLayout(); + settingsGroupLayout->addLayout(hbox, 3, 0); + hbox->addSpacing(30); + mLockLbl = new TQLabel(i18n("After:"), mSettingsGroup); + mLockLbl->setEnabled(mEnabled && mLock); + TQWhatsThis::add( mLockLbl, i18n("The amount of time, after the screen saver has started, to ask for the unlock password.") ); + hbox->addWidget(mLockLbl); + mWaitLockEdit = new TQSpinBox(mSettingsGroup); + mWaitLockEdit->setSteps(1, 10); + mWaitLockEdit->setRange(1, 300); + mWaitLockEdit->setSuffix(i18n(" sec")); + mWaitLockEdit->setValue(mLockTimeout/1000); + mWaitLockEdit->setEnabled(mEnabled && mLock); + if ( mWaitLockEdit->sizeHint().width() < + mWaitEdit->sizeHint().width() ) { + mWaitLockEdit->setFixedWidth( mWaitEdit->sizeHint().width() ); + mWaitEdit->setFixedWidth( mWaitEdit->sizeHint().width() ); + } + else { + mWaitEdit->setFixedWidth( mWaitLockEdit->sizeHint().width() ); + mWaitLockEdit->setFixedWidth( mWaitLockEdit->sizeHint().width() ); + } + connect(mWaitLockEdit, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotLockTimeoutChanged(int))); + mLockLbl->setBuddy(mWaitLockEdit); + hbox->addWidget(mWaitLockEdit); + hbox->addStretch(1); + TQString wltstr = i18n("Choose the period after which the display will be locked. "); + TQWhatsThis::add( mLockLbl, wltstr ); + TQWhatsThis::add( mWaitLockEdit, wltstr ); + + mDelaySaverStartCheckBox = new TQCheckBox( i18n("&Delay saver start after lock"), mSettingsGroup ); + mDelaySaverStartCheckBox->setEnabled( true ); + mDelaySaverStartCheckBox->setChecked( mDelaySaverStart ); + connect( mDelaySaverStartCheckBox, TQT_SIGNAL( toggled( bool ) ), this, TQT_SLOT( slotDelaySaverStart( bool ) ) ); + settingsGroupLayout->addWidget(mDelaySaverStartCheckBox, 0, 1); + TQWhatsThis::add( mDelaySaverStartCheckBox, i18n("When manually locking the screen, wait to start the screen saver until the configured start delay has elapsed.") ); + + mUseTSAKCheckBox = new TQCheckBox( i18n("&Use Secure Attention Key"), mSettingsGroup ); + mUseTSAKCheckBox->setEnabled( true ); + mUseTSAKCheckBox->setChecked( mUseTSAK ); + connect( mUseTSAKCheckBox, TQT_SIGNAL( toggled( bool ) ), this, TQT_SLOT( slotUseTSAK( bool ) ) ); + settingsGroupLayout->addWidget(mUseTSAKCheckBox, 1, 1); + TQWhatsThis::add( mUseTSAKCheckBox, i18n("Require Secure Attention Key prior to displaying the unlock dialog.") ); + + mUseUnmanagedLockWindowsCheckBox = new TQCheckBox( i18n("Use &legacy lock windows"), mSettingsGroup ); + mUseUnmanagedLockWindowsCheckBox->setEnabled( true ); + mUseUnmanagedLockWindowsCheckBox->setChecked( mUseUnmanagedLockWindows ); + connect( mUseUnmanagedLockWindowsCheckBox, TQT_SIGNAL( toggled( bool ) ), this, TQT_SLOT( slotUseUnmanagedLockWindows( bool ) ) ); + settingsGroupLayout->addWidget(mUseUnmanagedLockWindowsCheckBox, 2, 1); + TQWhatsThis::add( mUseUnmanagedLockWindowsCheckBox, i18n("Use old-style unmanaged X11 lock windows.") ); + + mHideActiveWindowsFromSaverCheckBox = new TQCheckBox( i18n("Hide active &windows from saver"), mSettingsGroup ); + mHideActiveWindowsFromSaverCheckBox->setEnabled( true ); + mHideActiveWindowsFromSaverCheckBox->setChecked( mHideActiveWindowsFromSaver ); + connect( mHideActiveWindowsFromSaverCheckBox, TQT_SIGNAL( toggled( bool ) ), this, TQT_SLOT( slotHideActiveWindowsFromSaver( bool ) ) ); + settingsGroupLayout->addWidget(mHideActiveWindowsFromSaverCheckBox, 3, 1); + TQWhatsThis::add( mHideActiveWindowsFromSaverCheckBox, i18n("Hide all active windows from the screen saver and use the desktop background as the screen saver input.") ); + + mHideCancelButtonCheckBox = new TQCheckBox( i18n("Hide &cancel button"), mSettingsGroup ); + mHideCancelButtonCheckBox->setEnabled( true ); + mHideCancelButtonCheckBox->setChecked( mHideCancelButton ); + connect( mHideCancelButtonCheckBox, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotHideCancelButton(bool)) ); + settingsGroupLayout->addWidget(mHideCancelButtonCheckBox, 4, 1); + TQWhatsThis::add(mHideCancelButtonCheckBox, i18n("Hide Cancel button from the \"Desktop Session Locked\" dialog.")); + + // right column + TQBoxLayout* rightColumnLayout = new TQVBoxLayout(topLayout, KDialog::spacingHint()); + + mMonitorLabel = new TQLabel( this ); + mMonitorLabel->setAlignment( AlignCenter ); + mMonitorLabel->setPixmap( TQPixmap(locate("data", "kcontrol/pics/monitor.png"))); + rightColumnLayout->addWidget(mMonitorLabel, 0); + TQWhatsThis::add( mMonitorLabel, i18n("A preview of the selected screen saver.") ); + + TQBoxLayout* advancedLayout = new TQHBoxLayout( rightColumnLayout, 3 ); + advancedLayout->addWidget( new TQWidget( this ) ); + TQPushButton* advancedBt = new TQPushButton( + i18n( "Advanced &Options" ), this, "advancedBtn" ); + advancedBt->setSizePolicy( TQSizePolicy( + TQSizePolicy::Fixed, TQSizePolicy::Fixed) ); + connect( advancedBt, TQT_SIGNAL( clicked() ), + this, TQT_SLOT( slotAdvanced() ) ); + advancedLayout->addWidget( advancedBt ); + advancedLayout->addWidget( new TQWidget( this ) ); + + rightColumnLayout->addStretch(); + + if (mImmutable) + { + setButtons(buttons() & ~Default); + mSettingsGroup->setEnabled(false); + mSaverGroup->setEnabled(false); + } + + // finding the savers can take some time, so defer loading until + // we've started up. + mNumLoaded = 0; + mLoadTimer = new TQTimer( this ); + connect( mLoadTimer, TQT_SIGNAL(timeout()), TQT_SLOT(findSavers()) ); + mLoadTimer->start( 100 ); + mChanged = false; + emit changed(false); + + TDEAboutData *about = + new TDEAboutData(I18N_NOOP("kcmscreensaver"), I18N_NOOP("TDE Screen Saver Control Module"), + 0, 0, TDEAboutData::License_GPL, + I18N_NOOP("(c) 1997-2002 Martin R. Jones\n" + "(c) 2003-2004 Chris Howells")); + about->addAuthor("Chris Howells", 0, "[email protected]"); + about->addAuthor("Martin R. Jones", 0, "[email protected]"); + + setAboutData( about ); + + mSaverList.setAutoDelete(true); + + processLockouts(); +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::resizeEvent( TQResizeEvent * ) +{ + + if (mMonitor) + { + mMonitor->setGeometry( (mMonitorLabel->width()-200)/2+23, + (mMonitorLabel->height()-186)/2+14, 151, 115 ); + } +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::mousePressEvent( TQMouseEvent *) +{ + if ( mTesting ) + slotStopTest(); +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::keyPressEvent( TQKeyEvent *) +{ + if ( mTesting ) + slotStopTest(); +} +//--------------------------------------------------------------------------- +// +KScreenSaver::~KScreenSaver() +{ + if (mPreviewProc) + { + if (mPreviewProc->isRunning()) + { + int pid = mPreviewProc->pid(); + mPreviewProc->kill( ); + waitpid(pid, (int *) 0,0); + } + delete mPreviewProc; + } + + delete mTestProc; + delete mSetupProc; + delete mTestWin; + + delete mTDMConfig; +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::load() +{ + load( false ); +} + +void KScreenSaver::load( bool useDefaults ) +{ + readSettings( useDefaults); + +//with the following line, the Test and Setup buttons are not enabled correctly +//if no saver was selected, the "Reset" and the "Enable screensaver", it is only called when starting and when pressing reset, aleXXX +// mSelected = -1; + int i = 0; + TQListViewItem *selectedItem = 0; + for (SaverConfig* saver = mSaverList.first(); saver != 0; saver = mSaverList.next()) { + if (saver->file() == mSaver) + { + selectedItem = mSaverListView->findItem ( saver->name(), 0 ); + if (selectedItem) { + mSelected = i; + break; + } + } + i++; + } + if ( selectedItem ) + { + mSaverListView->setSelected( selectedItem, true ); + mSaverListView->setCurrentItem( selectedItem ); + slotScreenSaver( selectedItem ); + } + + updateValues(); + mChanged = useDefaults; + emit changed( useDefaults ); +} + +//------------------------------------------------------------After--------------- +// +void KScreenSaver::readSettings( bool useDefaults ) +{ + TDEConfig *config = new TDEConfig( "kdesktoprc"); + + config->setReadDefaults( useDefaults ); + + mImmutable = config->groupIsImmutable("ScreenSaver"); + + config->setGroup( "ScreenSaver" ); + + mEnabled = config->readBoolEntry("Enabled", false); + mTimeout = config->readNumEntry("Timeout", 300); + mLockTimeout = config->readNumEntry("LockGrace", 60000); + mLock = config->readBoolEntry("Lock", false); + mDelaySaverStart = config->readBoolEntry("DelaySaverStart", true); + mUseTSAK = config->readBoolEntry("UseTDESAK", true); + mUseUnmanagedLockWindows = config->readBoolEntry("UseUnmanagedLockWindows", false); + mHideActiveWindowsFromSaver = config->readBoolEntry("HideActiveWindowsFromSaver", true); + mHideCancelButton = config->readBoolEntry("HideCancelButton", false); + mSaver = config->readEntry("Saver"); + + if (mTimeout < 60) mTimeout = 60; + if (mLockTimeout < 0) mLockTimeout = 0; + if (mLockTimeout > 300000) mLockTimeout = 300000; + + mChanged = false; + delete config; +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::updateValues() +{ + if (mEnabled) + { + mWaitEdit->setValue(mTimeout/60); + } + else + { + mWaitEdit->setValue(0); + } + + mWaitLockEdit->setValue(mLockTimeout/1000); + mLockCheckBox->setChecked(mLock); +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::defaults() +{ + load( true ); +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::save() +{ + if ( !mChanged ) + return; + + TDEConfig *config = new TDEConfig( "kdesktoprc"); + config->setGroup( "ScreenSaver" ); + + config->writeEntry("Enabled", mEnabled); + config->writeEntry("Timeout", mTimeout); + config->writeEntry("LockGrace", mLockTimeout); + config->writeEntry("Lock", mLock); + config->writeEntry("DelaySaverStart", mDelaySaverStart); + config->writeEntry("UseTDESAK", mUseTSAK); + config->writeEntry("UseUnmanagedLockWindows", mUseUnmanagedLockWindows); + config->writeEntry("HideActiveWindowsFromSaver", mHideActiveWindowsFromSaver); + config->writeEntry("HideCancelButton", mHideCancelButton); + + if ( !mSaver.isEmpty() ) + config->writeEntry("Saver", mSaver); + config->sync(); + delete config; + + // TODO (GJ): When you changed anything, these two lines will give a segfault + // on exit. I don't know why yet. + + DCOPClient *client = kapp->dcopClient(); + client->send("kdesktop", "KScreensaverIface", "configure()", TQString("")); + + mChanged = false; + emit changed(false); +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::findSavers() +{ + if ( !mNumLoaded ) { + mSaverFileList = TDEGlobal::dirs()->findAllResources("scrsav", + "*.desktop", false, true); + new TQListViewItem ( mSaverListView, i18n("Loading...") ); + if ( mSaverFileList.isEmpty() ) + mLoadTimer->stop(); + else + mLoadTimer->start( 50 ); + } + + for ( int i = 0; i < 5 && + (unsigned)mNumLoaded < mSaverFileList.count(); + i++, mNumLoaded++ ) { + TQString file = mSaverFileList[mNumLoaded]; + SaverConfig *saver = new SaverConfig; + if (saver->read(file)) { + TQString saverexec = TQString("%1/%2").arg(XSCREENSAVER_HACKS_DIR).arg(saver->exec()); + // find the xscreensaver executable + //work around a TDEStandardDirs::findExe() "feature" where it looks in $TDEDIR/bin first no matter what and sometimes finds the wrong executable + TQFileInfo checkExe; + checkExe.setFile(saverexec); + if (checkExe.exists() && checkExe.isExecutable() && checkExe.isFile()) { + mSaverList.append(saver); + } + else { + // Executable not present in XScreenSaver directory! + // Try standard paths + if (TDEStandardDirs::findExe(saver->exec()) != TQString::null) { + mSaverList.append(saver); + } + else { + delete saver; + } + } + } + else { + delete saver; + } + } + + if ( (unsigned)mNumLoaded == mSaverFileList.count() ) { + TQListViewItem *selectedItem = 0; + int categoryCount = 0; + int indx = 0; + + mLoadTimer->stop(); + delete mLoadTimer; + mSaverList.sort(); + + mSelected = -1; + mSaverListView->clear(); + for ( SaverConfig *s = mSaverList.first(); s != 0; s = mSaverList.next()) + { + TQListViewItem *item; + if (s->category().isEmpty()) + item = new TQListViewItem ( mSaverListView, s->name(), "2" + s->name() ); + else + { + TQListViewItem *categoryItem = mSaverListView->findItem( s->category(), 0 ); + if ( !categoryItem ) { + categoryItem = new TQListViewItem ( mSaverListView, s->category(), "1" + s->category() ); + categoryItem->setPixmap ( 0, SmallIcon ( "tdescreensaver" ) ); + } + item = new TQListViewItem ( categoryItem, s->name(), s->name() ); + categoryCount++; + } + if (s->file() == mSaver) { + mSelected = indx; + selectedItem = item; + } + indx++; + } + + // Delete categories with only one item + TQListViewItemIterator it ( mSaverListView ); + for ( ; it.current(); it++ ) + if ( it.current()->childCount() == 1 ) { + TQListViewItem *item = it.current()->firstChild(); + it.current()->takeItem( item ); + mSaverListView->insertItem ( item ); + delete it.current(); + categoryCount--; + } + + mSaverListView->setRootIsDecorated ( categoryCount > 0 ); + mSaverListView->setSorting ( 1 ); + + if ( mSelected > -1 ) + { + mSaverListView->setSelected(selectedItem, true); + mSaverListView->setCurrentItem(selectedItem); + mSaverListView->ensureItemVisible(selectedItem); + mSetupBt->setEnabled(!mSaverList.at(mSelected)->setup().isEmpty()); + mTestBt->setEnabled(true); + } + + connect( mSaverListView, TQT_SIGNAL( currentChanged( TQListViewItem * ) ), + this, TQT_SLOT( slotScreenSaver( TQListViewItem * ) ) ); + + setMonitor(); + } +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::setMonitor() +{ + if (mPreviewProc->isRunning()) + // CC: this will automatically cause a "slotPreviewExited" + // when the viewer exits + mPreviewProc->kill(); + else + slotPreviewExited(mPreviewProc); +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::slotPreviewExited(TDEProcess *) +{ + // Ugly hack to prevent continual respawning of savers that crash + if (mSelected == mPrevSelected) + return; + + if ( mSaverList.isEmpty() ) // safety check + return; + + // Some xscreensaver hacks do something nasty to the window that + // requires a new one to be created (or proper investigation of the + // problem). + delete mMonitor; + + mMonitor = new KSSMonitor(mMonitorLabel); + mMonitor->setBackgroundColor(black); + mMonitor->setGeometry((mMonitorLabel->width()-200)/2+23, + (mMonitorLabel->height()-186)/2+14, 151, 115); + mMonitor->show(); + // So that hacks can XSelectInput ButtonPressMask + XSelectInput(tqt_xdisplay(), mMonitor->winId(), widgetEventMask ); + + if (mSelected >= 0) { + mPreviewProc->clearArguments(); + + TQString saver = mSaverList.at(mSelected)->saver(); + TQTextStream ts(&saver, IO_ReadOnly); + + TQString word; + ts >> word; + TQString path = findExe(word); + + if (!path.isEmpty()) + { + (*mPreviewProc) << path; + + while (!ts.atEnd()) + { + ts >> word; + if (word == "%w") + { + word = word.setNum(mMonitor->winId()); + } + (*mPreviewProc) << word; + } + + mPreviewProc->start(); + } + } + + mPrevSelected = mSelected; +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::slotEnable(bool e) +{ + mEnabled = e; + processLockouts(); + mChanged = true; + emit changed(true); +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::processLockouts() +{ + bool useSAK = mTDMConfig->readBoolEntry("UseSAK", false); + mActivateLbl->setEnabled( mEnabled ); + mWaitEdit->setEnabled( mEnabled ); + mLockCheckBox->setEnabled( mEnabled ); + if (mEnabled && !mUseUnmanagedLockWindows) { + mDelaySaverStartCheckBox->setEnabled( true ); + mDelaySaverStartCheckBox->setChecked( mDelaySaverStart ); + } + else { + mDelaySaverStartCheckBox->setEnabled( false ); + mDelaySaverStartCheckBox->setChecked( false ); + } + if (!mUseUnmanagedLockWindows && useSAK) { + mUseTSAKCheckBox->setEnabled( true ); + mUseTSAKCheckBox->setChecked( mUseTSAK ); + } + else { + mUseTSAKCheckBox->setEnabled( false ); + mUseTSAKCheckBox->setChecked( false ); + } + if (!mUseUnmanagedLockWindows) { + mHideActiveWindowsFromSaverCheckBox->setEnabled( true ); + mHideActiveWindowsFromSaverCheckBox->setChecked( mHideActiveWindowsFromSaver ); + } + else { + mHideActiveWindowsFromSaverCheckBox->setEnabled( false ); + mHideActiveWindowsFromSaverCheckBox->setChecked( false ); + } + if (mUseUnmanagedLockWindows || (useSAK && mUseTSAK)) { + mHideCancelButtonCheckBox->setEnabled( false ); + mHideCancelButtonCheckBox->setChecked( false ); + } + else { + mHideCancelButtonCheckBox->setEnabled( true ); + mHideCancelButtonCheckBox->setChecked( mHideCancelButton ); + } + mLockLbl->setEnabled( mEnabled && mLock ); + mWaitLockEdit->setEnabled( mEnabled && mLock ); +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::slotScreenSaver(TQListViewItem *item) +{ + if (!item) + return; + + int i = 0, indx = -1; + for (SaverConfig* saver = mSaverList.first(); saver != 0; saver = mSaverList.next()) { + if ( item->parent() ) + { + if ( item->parent()->text( 0 ) == saver->category() && saver->name() == item->text (0)) + { + indx = i; + break; + } + } + else + { + if ( saver->name() == item->text (0) ) + { + indx = i; + break; + } + } + i++; + } + if (indx == -1) { + mSelected = -1; + return; + } + + bool bChanged = (indx != mSelected); + + if (!mSetupProc->isRunning()) + mSetupBt->setEnabled(!mSaverList.at(indx)->setup().isEmpty()); + mTestBt->setEnabled(true); + mSaver = mSaverList.at(indx)->file(); + + mSelected = indx; + setMonitor(); + if (bChanged) + { + mChanged = true; + emit changed(true); + } +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::slotSetup() +{ + if ( mSelected < 0 ) + return; + + if (mSetupProc->isRunning()) + return; + + mSetupProc->clearArguments(); + + TQString saver = mSaverList.at(mSelected)->setup(); + if( saver.isEmpty()) + return; + TQTextStream ts(&saver, IO_ReadOnly); + + TQString word; + ts >> word; + bool kxsconfig = word == "kxsconfig"; + TQString path = findExe(word); + + if (!path.isEmpty()) + { + (*mSetupProc) << path; + + // Add caption and icon to about dialog + if (!kxsconfig) { + word = "-caption"; + (*mSetupProc) << word; + word = mSaverList.at(mSelected)->name(); + (*mSetupProc) << word; + word = "-icon"; + (*mSetupProc) << word; + word = "tdescreensaver"; + (*mSetupProc) << word; + } + + while (!ts.atEnd()) + { + ts >> word; + (*mSetupProc) << word; + } + + // Pass translated name to kxsconfig + if (kxsconfig) { + word = mSaverList.at(mSelected)->name(); + (*mSetupProc) << word; + } + + mSetupBt->setEnabled( false ); + kapp->flushX(); + + mSetupProc->start(); + } +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::slotAdvanced() +{ + KScreenSaverAdvancedDialog dlg( topLevelWidget() ); + if ( dlg.exec() ) { + mChanged = true; + emit changed(true); + } +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::slotTest() +{ + if ( mSelected == -1 ) + return; + + if (!mTestProc) { + mTestProc = new TDEProcess; + } + + mTestProc->clearArguments(); + TQString saver = mSaverList.at(mSelected)->saver(); + TQTextStream ts(&saver, IO_ReadOnly); + + TQString word; + ts >> word; + TQString path = findExe(word); + + if (!path.isEmpty()) + { + (*mTestProc) << path; + + if (!mTestWin) + { + mTestWin = new TestWin(); + mTestWin->setBackgroundMode(TQWidget::NoBackground); + mTestWin->setGeometry(0, 0, kapp->desktop()->width(), + kapp->desktop()->height()); + } + + mTestWin->show(); + mTestWin->raise(); + mTestWin->setFocus(); + // So that hacks can XSelectInput ButtonPressMask + XSelectInput(tqt_xdisplay(), mTestWin->winId(), widgetEventMask ); + + grabMouse(); + grabKeyboard(); + + mTestBt->setEnabled( FALSE ); + mPreviewProc->kill(); + + while (!ts.atEnd()) + { + ts >> word; + if (word == "%w") + { + word = word.setNum(mTestWin->winId()); + } + (*mTestProc) << word; + } + + mTesting = true; + mTestProc->start(TDEProcess::NotifyOnExit); + } +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::slotStopTest() +{ + if (mTestProc->isRunning()) { + mTestProc->kill(); + } + releaseMouse(); + releaseKeyboard(); + mTestWin->hide(); + mTestBt->setEnabled(true); + mPrevSelected = -1; + setMonitor(); + mTesting = false; +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::slotTimeoutChanged(int to ) +{ + mTimeout = to * 60; + mChanged = true; + emit changed(true); +} + +//----------------------------------------------------------------------- +// +void KScreenSaver::slotLockTimeoutChanged(int to ) +{ + mLockTimeout = to * 1000; + mChanged = true; + emit changed(true); +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::slotLock( bool l ) +{ + mLock = l; + mLockLbl->setEnabled( l ); + mWaitLockEdit->setEnabled( l ); + mChanged = true; + emit changed(true); +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::slotDelaySaverStart( bool d ) +{ + if (mDelaySaverStartCheckBox->isEnabled()) mDelaySaverStart = d; + processLockouts(); + mChanged = true; + emit changed(true); +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::slotUseTSAK( bool u ) +{ + if (mUseTSAKCheckBox->isEnabled()) mUseTSAK = u; + processLockouts(); + mChanged = true; + emit changed(true); +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::slotUseUnmanagedLockWindows( bool u ) +{ + if (mUseUnmanagedLockWindowsCheckBox->isEnabled()) mUseUnmanagedLockWindows = u; + processLockouts(); + mChanged = true; + emit changed(true); +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::slotHideActiveWindowsFromSaver( bool h ) +{ + if (mHideActiveWindowsFromSaverCheckBox->isEnabled()) mHideActiveWindowsFromSaver = h; + processLockouts(); + mChanged = true; + emit changed(true); +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::slotHideCancelButton( bool h ) +{ + if (mHideCancelButtonCheckBox->isEnabled()) mHideCancelButton = h; + processLockouts(); + mChanged = true; + emit changed(true); +} + +//--------------------------------------------------------------------------- +// +void KScreenSaver::slotSetupDone(TDEProcess *) +{ + mPrevSelected = -1; // see ugly hack in slotPreviewExited() + setMonitor(); + mSetupBt->setEnabled( true ); + emit changed(true); +} + +#include "scrnsave.moc" |