You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tde-systemsettings/systemsettings/kcmultiwidget.cpp

432 lines
11 KiB

/*
Copyright (c) 2000 Matthias Elter <elter@kde.org>
Copyright (c) 2003 Daniel Molkentin <molkentin@kde.org>
Copyright (c) 2003 Matthias Kretz <kretz@kde.org>
Copyright (c) 2004 Frans Englich <frans.erglich.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <tqcursor.h>
#include <tqhbox.h>
#include <tqlayout.h>
#include <tqpushbutton.h>
#include <kaboutdata.h>
#include <kapplication.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <klibloader.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kprocess.h>
#include <krun.h>
#include <kstdguiitem.h>
#include <kuser.h>
#include "kcmoduleloader.h"
#include "kcmoduleproxy.h"
#include "kcmultiwidget.h"
/*
Button usage:
User1 => Reset
User2 => Close
User3 => Admin
*/
class KCMultiWidget::KCMultiWidgetPrivate
{
public:
KCMultiWidgetPrivate()
: hasRootKCM( false ), currentModule( 0 )
{}
bool hasRootKCM;
KCModuleProxy* currentModule;
};
KCMultiWidget::KCMultiWidget(TQWidget *parent, const char *name, bool modal)
: KDialogBase(IconList, i18n("Configure"), Help | Default |Cancel | Apply |
Ok | User1 | User2 | User3, Ok, parent, name, modal, true,
KStdGuiItem::reset(), KStdGuiItem::close(), KStdGuiItem::adminMode())
, dialogface( IconList ), d( new KCMultiWidgetPrivate )
{
init();
}
KCMultiWidget::KCMultiWidget( int dialogFace, TQWidget * parent, const char * name, bool modal )
: KDialogBase( dialogFace, "Caption", Help | Default | Cancel | Apply | Ok |
User1 | User2 | User3, Ok, parent, name, modal, true,
KStdGuiItem::reset(), KStdGuiItem::close(), KStdGuiItem::adminMode())
, dialogface( dialogFace ), d( new KCMultiWidgetPrivate )
{
init();
}
inline void KCMultiWidget::init()
{
connect( this, TQT_SIGNAL( finished()), TQT_SLOT( dialogClosed()));
showButton( Ok, false );
showButton( Cancel, false );
showButton( User1, true ); // Reset button
showButton( User2, true ); // Close button.
showButton( User3, true); // Admin button.
enableButton(Apply, false);
enableButton(User1, false);
connect(this, TQT_SIGNAL(aboutToShowPage(TQWidget *)), this, TQT_SLOT(slotAboutToShow(TQWidget *)));
setInitialSize(TQSize(640,480));
moduleParentComponents.setAutoDelete( true );
}
#include <kmessagebox.h>
KCMultiWidget::~KCMultiWidget()
{
OrphanMap::Iterator end2 = m_orphanModules.end();
for( OrphanMap::Iterator it = m_orphanModules.begin(); it != end2; ++it )
delete ( *it );
}
void KCMultiWidget::slotDefault()
{
int curPageIndex = activePageIndex();
ModuleList::Iterator end = m_modules.end();
for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
if( pageIndex( ( TQWidget * )( *it ).kcm->parent() ) == curPageIndex )
{
( *it ).kcm->defaults();
clientChanged( true );
return;
}
}
// Reset button.
void KCMultiWidget::slotUser1()
{
int curPageIndex = activePageIndex();
ModuleList::Iterator end = m_modules.end();
for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
if( pageIndex( ( TQWidget * )( *it ).kcm->parent() ) == curPageIndex )
{
( *it ).kcm->load();
clientChanged( false );
return;
}
}
void KCMultiWidget::apply()
{
TQStringList updatedModules;
ModuleList::Iterator end = m_modules.end();
for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
{
KCModuleProxy * m = ( *it ).kcm;
if( m && m->changed() )
{
m->save();
TQStringList * names = moduleParentComponents[ m ];
kdDebug() << k_funcinfo << *names << " saved and added to the list" << endl;
for( TQStringList::ConstIterator it = names->begin(); it != names->end(); ++it )
if( updatedModules.find( *it ) == updatedModules.end() )
updatedModules.append( *it );
}
}
for( TQStringList::const_iterator it = updatedModules.begin(); it != updatedModules.end(); ++it )
{
kdDebug() << k_funcinfo << *it << " " << ( *it ).latin1() << endl;
emit configCommitted( ( *it ).latin1() );
}
emit configCommitted();
}
void KCMultiWidget::slotApply()
{
TQPushButton *button = actionButton(Apply);
if (button)
button->setFocus();
emit applyClicked();
apply();
}
void KCMultiWidget::slotOk()
{
TQPushButton *button = actionButton(Ok);
if (button)
button->setFocus();
emit okClicked();
apply();
accept();
}
void KCMultiWidget::slotHelp()
{
TQString docPath;
int curPageIndex = activePageIndex();
ModuleList::Iterator end = m_modules.end();
for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
if( pageIndex( ( TQWidget * )( *it ).kcm->parent() ) == curPageIndex )
{
docPath = ( *it ).kcm->moduleInfo().docPath();
break;
}
KURL url( KURL("help:/"), docPath );
if (url.protocol() == "help" || url.protocol() == "man" || url.protocol() == "info") {
KProcess process;
process << "khelpcenter"
<< url.url();
process.start(KProcess::DontCare);
process.detach();
} else {
new KRun(url);
}
}
// Close button
void KCMultiWidget::slotUser2() {
emit close();
}
void KCMultiWidget::clientChanged(bool state)
{
kdDebug( 710 ) << k_funcinfo << state << endl;
ModuleList::Iterator end = m_modules.end();
for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
if( ( *it ).kcm->changed() ) {
enableButton( Apply, true );
enableButton( User1, true);
return;
}
enableButton( Apply, false );
enableButton( User1, false);
}
void KCMultiWidget::addModule(const TQString& path, bool withfallback)
{
TQString complete = path;
if( !path.endsWith( ".desktop" ))
complete += ".desktop";
KService::Ptr service = KService::serviceByStorageId( complete );
addModule( KCModuleInfo( service ), TQStringList(), withfallback);
}
void KCMultiWidget::addModule(const KCModuleInfo& moduleinfo,
TQStringList parentmodulenames, bool withfallback)
{
if( !moduleinfo.service() )
return;
if ( !kapp->authorizeControlModule( moduleinfo.service()->menuId() ))
return;
if( !KCModuleLoader::testModule( moduleinfo ))
return;
TQFrame* page = 0;
if (!moduleinfo.service()->noDisplay())
switch( dialogface )
{
case TreeList:
parentmodulenames += moduleinfo.moduleName();
page = addHBoxPage( parentmodulenames, moduleinfo.comment(),
SmallIcon( moduleinfo.icon(),
IconSize( KIcon::Small ) ) );
break;
case Tabbed:
case IconList:
page = addHBoxPage( moduleinfo.moduleName(),
moduleinfo.comment(), DesktopIcon( moduleinfo.icon(),
KIcon::SizeMedium ) );
break;
case Plain:
page = plainPage();
( new TQHBoxLayout( page ) )->setAutoAdd( true );
break;
default:
kdError( 710 ) << "unsupported dialog face for KCMultiWidget"
<< endl;
break;
}
if(!page) {
KCModuleLoader::unloadModule(moduleinfo);
return;
}
KCModuleProxy * module;
if( m_orphanModules.contains( moduleinfo.service() ) )
{
// the KCModule already exists - it was removed from the dialog in
// removeAllModules
module = m_orphanModules[ moduleinfo.service() ];
m_orphanModules.remove( moduleinfo.service() );
kdDebug( 710 ) << "Use KCModule from the list of orphans for " <<
moduleinfo.moduleName() << ": " << module << endl;
module->reparent( page, 0, TQPoint( 0, 0 ), true );
if( module->changed() )
clientChanged( true );
if( activePageIndex() == -1 ) {
showPage( pageIndex( page ) );
}
}
else
{
module = new KCModuleProxy( moduleinfo, withfallback, page );
TQStringList parentComponents = moduleinfo.service()->property(
"X-KDE-ParentComponents" ).toStringList();
moduleParentComponents.insert( module,
new TQStringList( parentComponents ) );
connect(module, TQT_SIGNAL(changed(bool)), this, TQT_SLOT(clientChanged(bool)));
}
CreatedModule cm;
cm.kcm = module;
cm.service = moduleinfo.service();
cm.adminmode = false;
cm.buttons = module->buttons();
if ( moduleinfo.needsRootPrivileges() &&
!KUser().isSuperUser() ) {/* If we're embedded, it's true */
d->hasRootKCM = true;
cm.adminmode = true;
m_modules.append( cm );
if( dialogface==Plain ) {
slotAboutToShow( page ); // Won't be called otherwise, necessary for adminMode button
}
} else {
m_modules.append( cm );
}
if( m_modules.count() == 1 ) {
slotAboutToShow( page );
}
}
KCModuleProxy * KCMultiWidget::currentModule() {
if(d) {
return d->currentModule;
}
return NULL;
}
void KCMultiWidget::applyOrRevert(KCModuleProxy * module){
if( !module || !module->changed() )
return;
int res = KMessageBox::warningYesNo(this,
i18n("There are unsaved changes in the active module.\n"
"Do you want to apply the changes or discard them?"),
i18n("Unsaved Changes"),
KStdGuiItem::apply(),
KStdGuiItem::discard());
if (res == KMessageBox::Yes) {
slotApply();
} else {
module->load();
clientChanged( false );
}
}
void KCMultiWidget::slotAboutToShow(TQWidget *page)
{
TQObject * obj = page->child( 0, "KCModuleProxy" );
if( ! obj )
return;
KCModuleProxy *module = ( KCModuleProxy* )obj->qt_cast( "KCModuleProxy" );
if( ! module )
return;
if( d && d->currentModule )
applyOrRevert( d->currentModule );
d->currentModule = module;
emit ( aboutToShow( d->currentModule ) );
ModuleList::Iterator end = m_modules.end();
int buttons = 0;
for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it ) {
if( ( *it ).kcm==d->currentModule) {
showButton(User3, ( *it ).adminmode);
buttons = ( *it ).buttons;
}
}
showButton(Apply, buttons & KCModule::Apply);
showButton(User1, buttons & KCModule::Apply); // Reset button.
// Close button. No Apply button implies a Close button.
showButton(User2, (buttons & KCModule::Apply)==0);
enableButton( KDialogBase::Help, buttons & KCModule::Help );
enableButton( KDialogBase::Default, buttons & KCModule::Default );
disconnect( this, TQT_SIGNAL(user3Clicked()), 0, 0 );
if (d->currentModule->moduleInfo().needsRootPrivileges() &&
!d->currentModule->rootMode() )
{ /* Enable the Admin Mode button */
enableButton( User3, true );
connect( this, TQT_SIGNAL(user3Clicked()), d->currentModule, TQT_SLOT( runAsRoot() ));
connect( this, TQT_SIGNAL(user3Clicked()), TQT_SLOT( disableRModeButton() ));
} else {
enableButton( User3, false );
}
}
void KCMultiWidget::rootExit()
{
enableButton( User3, true);
}
void KCMultiWidget::disableRModeButton()
{
enableButton( User3, false );
connect ( d->currentModule, TQT_SIGNAL( childClosed() ), TQT_SLOT( rootExit() ) );
}
void KCMultiWidget::slotCancel() {
dialogClosed();
KDialogBase::slotCancel();
}
void KCMultiWidget::dialogClosed()
{
if(d)
{
applyOrRevert(d->currentModule);
}
}
#include "kcmultiwidget.moc"