not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / systemsettings / kcmultiwidget.cpp
blobf006996401e22345df5f04ab1fe0f9bfdd8e10d5
1 /*
2 Copyright (c) 2000 Matthias Elter <elter@kde.org>
3 Copyright (c) 2003 Daniel Molkentin <molkentin@kde.org>
4 Copyright (c) 2003 Matthias Kretz <kretz@kde.org>
5 Copyright (c) 2004 Frans Englich <englich@kde.org>
6 Copyright (c) 2008 Michael Jansen <kde@michael-jansen.biz>
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA.
25 #include "kcmultiwidget.h"
27 #include <QLayout>
28 #include <QProcess>
29 #include <QScrollArea>
31 #include <kdebug.h>
32 #include <kiconloader.h>
33 #include <klibloader.h>
34 #include <klocale.h>
35 #include <kmessagebox.h>
36 #include <krun.h>
37 #include <kstandardguiitem.h>
38 #include <kuser.h>
39 #include <kauthorized.h>
40 #include <ktoolinvocation.h>
42 #include "kcmoduleloader.h"
43 #include "kcmoduleproxy.h"
46 Button usage:
48 User1 => Close
49 User2 => Admin (dead in KDE 4)
52 class KCMultiWidget::KCMultiWidgetPrivate
54 public:
55 KCMultiWidgetPrivate()
56 : hasRootKCM( false )
59 bool hasRootKCM;
62 KCMultiWidget::KCMultiWidget(QWidget *parent, Qt::WindowModality modality)
63 : KPageDialog( parent ),
64 d( new KCMultiWidgetPrivate )
66 InitKIconDialog(i18n("Configure"), modality);
67 init();
70 // Maybe move into init()?
71 void KCMultiWidget::InitKIconDialog(const QString& caption,
72 Qt::WindowModality modality)
74 setCaption(caption);
75 setButtons(KDialog::Help |
76 KDialog::Default |
77 KDialog::Apply |
78 KDialog::Reset );
79 setDefaultButton(KDialog::Reset);
81 setWindowModality(modality);
85 inline void KCMultiWidget::init()
87 // A bit hackish: KCMultiWidget inherits from KPageDialog, but it really is
88 // a widget...
89 setWindowFlags(Qt::Widget);
91 enableButton(Apply, false);
92 enableButton(Reset, false);
93 enableButton(Default, false);
94 enableButton(Help, false);
96 connect(
97 this, SIGNAL(currentPageChanged(KPageWidgetItem*, KPageWidgetItem*)),
98 this, SLOT(slotAboutToShow(KPageWidgetItem*, KPageWidgetItem* )) );
99 setInitialSize(QSize(640,480));
100 setFaceType( Auto );
101 connect( this, SIGNAL(helpClicked()), this, SLOT(slotHelp()) );
102 connect( this, SIGNAL(defaultClicked()), this, SLOT(slotDefault()) );
103 connect( this, SIGNAL(applyClicked()), this, SLOT(slotApply()) );
104 connect( this, SIGNAL(resetClicked()), this, SLOT(slotReset()) );
107 KCMultiWidget::~KCMultiWidget()
109 delete d;
112 void KCMultiWidget::slotDefault()
114 defaults(currentModule());
118 void KCMultiWidget::slotReset()
120 reset(currentModule());
124 void KCMultiWidget::slotApply()
126 apply(currentModule());
130 void KCMultiWidget::slotHelp()
132 QString docPath = currentModule()->moduleInfo().docPath();
133 if(docPath.isEmpty())
134 return;
135 KUrl url( KUrl("help:/"), docPath );
137 if (url.protocol() == "help" || url.protocol() == "man" || url.protocol() == "info") {
138 QProcess::startDetached("khelpcenter", QStringList() << url.url());
139 } else {
140 KToolInvocation::invokeBrowser( url.url() );
145 void KCMultiWidget::clientChanged(bool state)
147 kDebug( 710 ) << state;
148 foreach( const CreatedModule &it, m_modules )
149 if( it.kcm->changed() ) {
150 enableButton( Apply, true );
151 enableButton( Reset, true);
152 return;
154 enableButton( Apply, false );
155 enableButton( Reset, false);
159 void KCMultiWidget::addModule(const KCModuleInfo& moduleinfo)
161 if( !moduleinfo.service() ) {
162 kWarning() << "ModuleInfo has no associated KService" ;
163 return;
166 if ( !KAuthorized::authorizeControlModule( moduleinfo.service()->menuId() )) {
167 kWarning() << "Not authorised to load module" ;
168 return;
171 if(moduleinfo.service()->noDisplay()) {
172 return;
175 QScrollArea* moduleScrollArea = new QScrollArea( this );
176 KCModuleProxy *module = new KCModuleProxy( moduleinfo, moduleScrollArea );
177 moduleScrollArea->setWidget( module );
178 moduleScrollArea->setWidgetResizable( true );
179 moduleScrollArea->setFrameStyle( QFrame::NoFrame );
180 moduleScrollArea->viewport()->setAutoFillBackground(false);
181 module->setAutoFillBackground(false);
182 QStringList parentComponents = moduleinfo.service()->property(
183 "X-KDE-System-Settings-Parent-Category" ).toStringList();
184 moduleParentComponents.insert( module, parentComponents );
186 connect(module, SIGNAL(changed(bool)), this, SLOT(clientChanged(bool)));
188 CreatedModule cm;
189 cm.kcm = module;
190 cm.service = moduleinfo.service();
191 cm.adminmode = false;
193 // "root KCMs are gone" says KControl
194 // if ( moduleinfo.needsRootPrivileges() && !d->hasRootKCM &&
195 // !KUser().isSuperUser() ) {/* If we're embedded, it's true */
196 // d->hasRootKCM = true;
197 // cm.adminmode = true;
198 // m_modules.append( cm );
199 // if( dialogface==Plain ) {
200 // slotAboutToShow( page ); // Won't be called otherwise, necessary for adminMode button
201 // }
202 // } else {
203 // m_modules.append( cm );
204 // }
206 m_modules.append( cm );
207 if( m_modules.count() == 1 ) {
208 slotAboutToShow( module );
210 KPageWidgetItem* page = addPage(moduleScrollArea, moduleinfo.moduleName());
211 page->setIcon( KIcon(moduleinfo.icon()) );
212 page->setHeader(moduleinfo.comment());
216 KCModuleProxy* KCMultiWidget::currentModule()
218 KPageWidgetItem *pageWidget = currentPage();
219 if ( pageWidget == 0 )
220 return 0;
222 QScrollArea *scrollArea = qobject_cast<QScrollArea*>( pageWidget->widget() );
223 KCModuleProxy *module = qobject_cast<KCModuleProxy*>( scrollArea->widget() );
225 return module;
229 void KCMultiWidget::slotAboutToShow(KPageWidgetItem* current, KPageWidgetItem* before)
231 if( before != 0 ) {
232 QScrollArea *scrollArea = qobject_cast<QScrollArea*>( before->widget() );
233 KCModuleProxy *module = qobject_cast<KCModuleProxy*>( scrollArea->widget() );
234 if (!queryClose(module)) {
235 setCurrentPage(before);
236 return;
240 QWidget* sendingWidget = current->widget();
241 slotAboutToShow(sendingWidget);
245 void KCMultiWidget::slotAboutToShow(QWidget *page)
247 QList<KCModuleProxy*> objects = page->findChildren<KCModuleProxy*>();
249 // add fall back
250 objects.append( qobject_cast<KCModuleProxy*>(page) );
252 KCModuleProxy *module = objects.first();
253 if( ! module ) {
254 return;
257 emit ( aboutToShow( module ) );
259 int buttons = 0;
260 bool found = false;
261 foreach( const CreatedModule &it, m_modules ) {
262 if( it.kcm==module) {
263 showButton(User2, it.adminmode);
264 buttons = it.kcm->buttons();
265 found = true;
268 if (!found) {
269 buttons = module->buttons();
272 showButton(Apply, buttons & KCModule::Apply);
273 showButton(Reset, buttons & KCModule::Apply);
275 enableButton( KDialog::Help, buttons & KCModule::Help );
276 enableButton( KDialog::Default, buttons & KCModule::Default );
278 disconnect( this, SIGNAL(user3Clicked()), 0, 0 );
280 // if (module->moduleInfo().needsRootPrivileges() &&
281 // !module->rootMode() )
282 // { /* Enable the Admin Mode button */
283 // enableButton( User2, true );
284 // connect( this, SIGNAL(user3Clicked()), module, SLOT( runAsRoot() ));
285 // connect( this, SIGNAL(user3Clicked()), SLOT( disableRModeButton() ));
286 // } else {
287 // enableButton( User2, false );
288 // }
291 // Currently unused. Whenever root mode comes back
292 #if 0
293 void KCMultiWidget::rootExit()
295 enableButton( User2, true);
298 void KCMultiWidget::disableRModeButton()
300 enableButton( User2, false );
301 connect ( currentModule(), SIGNAL( childClosed() ), SLOT( rootExit() ) );
303 #endif
306 void KCMultiWidget::apply(KCModuleProxy *module)
308 module->save();
309 emit configCommitted();
311 // TODO: check what that stuff does! I think it's not needed
312 QStringList updatedModules;
313 QStringList names = moduleParentComponents[ module ];
314 foreach ( const QString &name , names )
316 if ( updatedModules.indexOf(name) == -1 )
317 updatedModules.append(name);
320 foreach( const QString &it, updatedModules )
322 emit configCommitted( it.toLatin1() );
325 clientChanged(false);
329 void KCMultiWidget::defaults(KCModuleProxy *module)
331 module->defaults();
332 clientChanged( true );
336 bool KCMultiWidget::queryClose()
338 return queryClose(currentModule());
342 bool KCMultiWidget::queryClose(KCModuleProxy *module)
344 if( !module || !module->changed() )
345 return true;
347 // Let the user decide
348 int res = KMessageBox::warningYesNoCancel(
349 this,
350 i18n("There are unsaved changes in the active module.\n"
351 "Do you want to apply the changes or discard them?"),
352 i18n("Unsaved Changes"),
353 KStandardGuiItem::save(),
354 KStandardGuiItem::discard(),
355 KStandardGuiItem::cancel() );
357 switch (res) {
359 case KMessageBox::Yes:
360 apply(module);
361 return true;
363 case KMessageBox::No:
364 reset(module);
365 return true;
367 case KMessageBox::Cancel:
368 return false;
370 default:
371 Q_ASSERT(false);
372 return false;
377 void KCMultiWidget::reset(KCModuleProxy *module)
379 module->load();
380 clientChanged(false);
384 #include "kcmultiwidget.moc"