summaryrefslogtreecommitdiffstats
path: root/kutils/kcmultidialog.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch)
tree5ac38a06f3dde268dc7927dc155896926aaf7012 /kutils/kcmultidialog.cpp
downloadtdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz
tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kutils/kcmultidialog.cpp')
-rw-r--r--kutils/kcmultidialog.cpp411
1 files changed, 411 insertions, 0 deletions
diff --git a/kutils/kcmultidialog.cpp b/kutils/kcmultidialog.cpp
new file mode 100644
index 000000000..f64a9e139
--- /dev/null
+++ b/kutils/kcmultidialog.cpp
@@ -0,0 +1,411 @@
+/*
+ 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 Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#include <qcursor.h>
+#include <qhbox.h>
+#include <qlayout.h>
+#include <qpushbutton.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 "kcmultidialog.h"
+#include "kcmultidialog.moc"
+
+class KCMultiDialog::KCMultiDialogPrivate
+{
+ public:
+ KCMultiDialogPrivate()
+ : hasRootKCM( false ), currentModule( 0 )
+ {}
+
+ bool hasRootKCM;
+ KCModuleProxy* currentModule;
+};
+
+
+KCMultiDialog::KCMultiDialog(QWidget *parent, const char *name, bool modal)
+ : KDialogBase(IconList, i18n("Configure"), Help | Default |Cancel | Apply |
+ Ok | User1 | User2, Ok, parent, name, modal, true,
+ KStdGuiItem::reset(), KStdGuiItem::adminMode())
+ , dialogface( IconList ), d( new KCMultiDialogPrivate )
+{
+ init();
+}
+
+KCMultiDialog::KCMultiDialog( int dialogFace, const QString & caption, QWidget * parent, const char * name, bool modal )
+ : KDialogBase( dialogFace, caption, Help | Default | Cancel | Apply | Ok |
+ User1 | User2, Ok, parent, name, modal, true,
+ KStdGuiItem::reset(), KStdGuiItem::adminMode())
+ , dialogface( dialogFace ), d( new KCMultiDialogPrivate )
+{
+ init();
+}
+
+KCMultiDialog::KCMultiDialog( int dialogFace, const KGuiItem &user2,
+ const KGuiItem &user3, int buttonMask, const QString &caption,
+ QWidget *parent, const char *name, bool modal )
+ : KDialogBase( dialogFace, caption, buttonMask | Help | Default | Cancel |
+ Apply | Ok | User1, Ok, parent, name, modal, true,
+ KStdGuiItem::reset(), user2, user3 )
+ , dialogface( dialogFace ), d( new KCMultiDialogPrivate )
+{
+ kdDebug( 710 ) << "Root modules will not work with this constructor. See the API documentation." << endl;
+ init();
+ if ( buttonMask & User2 )
+ showButton( User2, true );
+}
+
+inline void KCMultiDialog::init()
+{
+ connect( this, SIGNAL( finished()), SLOT( dialogClosed()));
+ showButton( User1, false );
+ showButton( User2, false );
+ enableButton(Apply, false);
+ connect(this, SIGNAL(aboutToShowPage(QWidget *)), this, SLOT(slotAboutToShow(QWidget *)));
+ setInitialSize(QSize(640,480));
+ moduleParentComponents.setAutoDelete( true );
+
+}
+
+KCMultiDialog::~KCMultiDialog()
+{
+ OrphanMap::Iterator end2 = m_orphanModules.end();
+ for( OrphanMap::Iterator it = m_orphanModules.begin(); it != end2; ++it )
+ delete ( *it );
+ delete d;
+}
+
+void KCMultiDialog::slotDefault()
+{
+ int curPageIndex = activePageIndex();
+
+ ModuleList::Iterator end = m_modules.end();
+ for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
+ if( pageIndex( ( QWidget * )( *it ).kcm->parent() ) == curPageIndex )
+ {
+ ( *it ).kcm->defaults();
+ clientChanged( true );
+ return;
+ }
+}
+
+void KCMultiDialog::slotUser1()
+{
+ int curPageIndex = activePageIndex();
+
+ ModuleList::Iterator end = m_modules.end();
+ for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
+ if( pageIndex( ( QWidget * )( *it ).kcm->parent() ) == curPageIndex )
+ {
+ ( *it ).kcm->load();
+ clientChanged( false );
+ return;
+ }
+}
+
+void KCMultiDialog::apply()
+{
+ QStringList updatedModules;
+ ModuleList::Iterator end = m_modules.end();
+ for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
+ {
+ KCModuleProxy * m = ( *it ).kcm;
+ if( m->changed() )
+ {
+ m->save();
+ QStringList * names = moduleParentComponents[ m ];
+ kdDebug(710) << k_funcinfo << *names << " saved and added to the list" << endl;
+ for( QStringList::ConstIterator it = names->begin(); it != names->end(); ++it )
+ if( updatedModules.find( *it ) == updatedModules.end() )
+ updatedModules.append( *it );
+ }
+ }
+ for( QStringList::const_iterator it = updatedModules.begin(); it != updatedModules.end(); ++it )
+ {
+ kdDebug(710) << k_funcinfo << *it << " " << ( *it ).latin1() << endl;
+ emit configCommitted( ( *it ).latin1() );
+ }
+ emit configCommitted();
+}
+
+void KCMultiDialog::slotApply()
+{
+ QPushButton *button = actionButton(Apply);
+ if (button)
+ button->setFocus();
+ emit applyClicked();
+ apply();
+}
+
+
+void KCMultiDialog::slotOk()
+{
+ QPushButton *button = actionButton(Ok);
+ if (button)
+ button->setFocus();
+ emit okClicked();
+ apply();
+ accept();
+}
+
+void KCMultiDialog::slotHelp()
+{
+ QString docPath;
+
+ int curPageIndex = activePageIndex();
+ ModuleList::Iterator end = m_modules.end();
+ for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
+ if( pageIndex( ( QWidget * )( *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);
+ }
+}
+
+void KCMultiDialog::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 );
+ return;
+ }
+ enableButton( Apply, false );
+}
+
+void KCMultiDialog::addModule(const QString& path, bool withfallback)
+{
+ QString complete = path;
+
+ if( !path.endsWith( ".desktop" ))
+ complete += ".desktop";
+
+ KService::Ptr service = KService::serviceByStorageId( complete );
+
+ addModule( KCModuleInfo( service ), QStringList(), withfallback);
+}
+
+void KCMultiDialog::addModule(const KCModuleInfo& moduleinfo,
+ QStringList parentmodulenames, bool withfallback)
+{
+ kdDebug(710) << "KCMultiDialog::addModule "
+ << moduleinfo.moduleName() << endl;
+
+ if( !moduleinfo.service() )
+ return;
+
+ if ( !kapp->authorizeControlModule( moduleinfo.service()->menuId() ))
+ return;
+
+ if( !KCModuleLoader::testModule( moduleinfo ))
+ return;
+
+ QFrame* 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 IconList:
+ page = addHBoxPage( moduleinfo.moduleName(),
+ moduleinfo.comment(), DesktopIcon( moduleinfo.icon(),
+ KIcon::SizeMedium ) );
+ break;
+ case Plain:
+ page = plainPage();
+ ( new QHBoxLayout( page ) )->setAutoAdd( true );
+ break;
+ default:
+ kdError( 710 ) << "unsupported dialog face for KCMultiDialog"
+ << 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, QPoint( 0, 0 ), true );
+
+ if( module->changed() )
+ clientChanged( true );
+
+ if( activePageIndex() == -1 )
+ showPage( pageIndex( page ) );
+ }
+ else
+ {
+ module = new KCModuleProxy( moduleinfo, withfallback, page );
+ QStringList parentComponents = moduleinfo.service()->property(
+ "X-KDE-ParentComponents" ).toStringList();
+ moduleParentComponents.insert( module,
+ new QStringList( parentComponents ) );
+
+ connect(module, SIGNAL(changed(bool)), this, SLOT(clientChanged(bool)));
+
+ if( m_modules.count() == 0 )
+ aboutToShowPage( page );
+ }
+ CreatedModule cm;
+ cm.kcm = module;
+ cm.service = moduleinfo.service();
+ m_modules.append( cm );
+ if ( moduleinfo.needsRootPrivileges() &&
+ !d->hasRootKCM &&
+ !KUser().isSuperUser() ) /* If we're embedded, it's true */
+ {
+ d->hasRootKCM = true;
+ showButton( User2, true );
+ if( plainPage() ) // returns 0 if we're not a Plain dialog
+ slotAboutToShow( page ); // Won't be called otherwise, necessary for adminMode button
+ }
+}
+
+void KCMultiDialog::removeAllModules()
+{
+ kdDebug( 710 ) << k_funcinfo << endl;
+ ModuleList::Iterator end = m_modules.end();
+ for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
+ {
+ kdDebug( 710 ) << "remove 2" << endl;
+ KCModuleProxy * kcm = ( *it ).kcm;
+ QObject * page = kcm->parent();
+ kcm->hide();
+ if( page )
+ {
+ // I hate this
+ kcm->reparent( 0, QPoint( 0, 0 ), false );
+ delete page;
+ }
+ m_orphanModules[ ( *it ).service ] = kcm;
+ kdDebug( 710 ) << "added KCModule to the list of orphans: " <<
+ kcm << endl;
+ }
+ m_modules.clear();
+ // all modules are gone, none can be changed
+ clientChanged( false );
+}
+
+void KCMultiDialog::show()
+{ /* KDE 4 Remove..? */
+ KDialogBase::show();
+}
+
+void KCMultiDialog::slotAboutToShow(QWidget *page)
+{
+ kdDebug(710) << k_funcinfo << endl;
+
+ QObject * obj = page->child( 0, "KCModuleProxy" );
+ if( ! obj )
+ return;
+
+ KCModuleProxy * module = ( KCModuleProxy* )obj->qt_cast(
+ "KCModuleProxy" );
+ if( ! module )
+ return;
+ d->currentModule = module;
+
+ enableButton( KDialogBase::Help,
+ d->currentModule->buttons() & KCModule::Help );
+ enableButton( KDialogBase::Default,
+ d->currentModule->buttons() & KCModule::Default );
+
+ disconnect( this, SIGNAL(user2Clicked()), 0, 0 );
+
+ if (d->currentModule->moduleInfo().needsRootPrivileges())
+ {
+ if ( !d->currentModule->rootMode() )
+ { /* Enable the Admin Mode button */
+ enableButton( User2, true );
+ connect( this, SIGNAL(user2Clicked()), d->currentModule, SLOT( runAsRoot() ));
+ connect( this, SIGNAL(user2Clicked()), SLOT( disableRModeButton() ));
+ }
+ else
+ enableButton( User2, false);
+ }
+}
+
+void KCMultiDialog::rootExit()
+{
+ enableButton( User2, true);
+}
+
+void KCMultiDialog::disableRModeButton()
+{
+ enableButton( User2, false );
+ connect ( d->currentModule, SIGNAL( childClosed() ), SLOT( rootExit() ));
+}
+
+void KCMultiDialog::dialogClosed()
+{
+ kdDebug(710) << k_funcinfo << endl;
+
+ /* If we don't delete them, the DCOP registration stays, and trying to load the KCMs
+ * in other situations will lead to "module already loaded in Foo," while to the user
+ * doesn't appear so(the dialog is hidden) */
+ ModuleList::Iterator end = m_modules.end();
+ for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
+ ( *it ).kcm->deleteClient();
+}
+
+
+// vim: sw=4 et sts=4