Add (and install) svg for the new krunner interface.
[kdebase/uwolfer.git] / workspace / systemsettings / kcmultiwidget.cpp
blobda4f31c666c801ebccb63c9bbe02e782c815f2cb
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>
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
24 #include "kcmultiwidget.h"
26 #include <QLayout>
27 #include <QProcess>
28 #include <QScrollArea>
30 #include <kdebug.h>
31 #include <kiconloader.h>
32 #include <klibloader.h>
33 #include <klocale.h>
34 #include <kmessagebox.h>
35 #include <krun.h>
36 #include <kstandardguiitem.h>
37 #include <kuser.h>
38 #include <kauthorized.h>
39 #include <ktoolinvocation.h>
41 #include "kcmoduleloader.h"
42 #include "kcmoduleproxy.h"
45 Button usage:
47 User1 => Close
48 User2 => Admin (dead in KDE 4)
51 class KCMultiWidget::KCMultiWidgetPrivate
53 public:
54 KCMultiWidgetPrivate()
55 : hasRootKCM( false )
58 bool hasRootKCM;
61 KCMultiWidget::KCMultiWidget(QWidget *parent, Qt::WindowModality modality)
62 : KPageDialog( parent ),
63 d( new KCMultiWidgetPrivate )
65 InitKIconDialog(i18n("Configure"), modality);
66 init();
69 // Maybe move into init()?
70 void KCMultiWidget::InitKIconDialog(const QString& caption,
71 Qt::WindowModality modality)
73 setCaption(caption);
74 setButtons(KDialog::Help |
75 KDialog::Default |
76 KDialog::Apply |
77 KDialog::Reset );
78 setDefaultButton(KDialog::Reset);
80 setWindowModality(modality);
84 inline void KCMultiWidget::init()
86 // A bit hackish: KCMultiWidget inherits from KPageDialog, but it really is
87 // a widget...
88 setWindowFlags(Qt::Widget);
90 enableButton(Apply, false);
91 enableButton(Reset, false);
92 enableButton(Default, false);
93 enableButton(Help, false);
95 connect(
96 this, SIGNAL(currentPageChanged(KPageWidgetItem*, KPageWidgetItem*)),
97 this, SLOT(slotAboutToShow(KPageWidgetItem*, KPageWidgetItem* )) );
98 setInitialSize(QSize(640,480));
99 setFaceType( Auto );
100 connect( this, SIGNAL(helpClicked()), this, SLOT(slotHelp()) );
101 connect( this, SIGNAL(defaultClicked()), this, SLOT(slotDefault()) );
102 connect( this, SIGNAL(applyClicked()), this, SLOT(slotApply()) );
103 connect( this, SIGNAL(resetClicked()), this, SLOT(slotReset()) );
106 KCMultiWidget::~KCMultiWidget()
108 delete d;
111 void KCMultiWidget::slotDefault()
113 defaults(currentModule());
117 void KCMultiWidget::slotReset()
119 reset(currentModule());
123 void KCMultiWidget::slotApply()
125 apply(currentModule());
129 void KCMultiWidget::slotHelp()
131 QString docPath = currentModule()->moduleInfo().docPath();
132 if(docPath.isEmpty())
133 return;
134 KUrl url( KUrl("help:/"), docPath );
136 if (url.protocol() == "help" || url.protocol() == "man" || url.protocol() == "info") {
137 QProcess::startDetached("khelpcenter", QStringList() << url.url());
138 } else {
139 KToolInvocation::invokeBrowser( url.url() );
144 void KCMultiWidget::clientChanged(bool state)
146 kDebug( 710 ) << state;
147 foreach( const CreatedModule &it, m_modules )
148 if( it.kcm->changed() ) {
149 enableButton( Apply, true );
150 enableButton( Reset, true);
151 return;
153 enableButton( Apply, false );
154 enableButton( Reset, false);
158 void KCMultiWidget::addModule(const KCModuleInfo& moduleinfo)
160 if( !moduleinfo.service() ) {
161 kWarning() << "ModuleInfo has no associated KService" ;
162 return;
165 if ( !KAuthorized::authorizeControlModule( moduleinfo.service()->menuId() )) {
166 kWarning() << "Not authorised to load module" ;
167 return;
170 if(moduleinfo.service()->noDisplay()) {
171 return;
174 QScrollArea * moduleScrollArea = new QScrollArea( this );
175 KCModuleProxy *module = new KCModuleProxy( moduleinfo, moduleScrollArea );
176 moduleScrollArea->setWidget( module );
177 moduleScrollArea->setWidgetResizable( true );
178 moduleScrollArea->setFrameStyle( QFrame::NoFrame );
179 moduleScrollArea->viewport()->setAutoFillBackground(false);
180 module->setAutoFillBackground(false);
181 QStringList parentComponents = moduleinfo.service()->property(
182 "X-KDE-System-Settings-Parent-Category" ).toStringList();
183 moduleParentComponents.insert( module, parentComponents );
185 connect(module, SIGNAL(changed(bool)), this, SLOT(clientChanged(bool)));
187 CreatedModule cm;
188 cm.kcm = module;
189 cm.service = moduleinfo.service();
190 cm.adminmode = false;
191 cm.buttons = module->buttons();
192 // "root KCMs are gone" says KControl
193 // if ( moduleinfo.needsRootPrivileges() && !d->hasRootKCM &&
194 // !KUser().isSuperUser() ) {/* If we're embedded, it's true */
195 // d->hasRootKCM = true;
196 // cm.adminmode = true;
197 // m_modules.append( cm );
198 // if( dialogface==Plain ) {
199 // slotAboutToShow( page ); // Won't be called otherwise, necessary for adminMode button
200 // }
201 // } else {
202 // m_modules.append( cm );
203 // }
205 m_modules.append( cm );
206 if( m_modules.count() == 1 ) {
207 slotAboutToShow( module );
209 KPageWidgetItem* page = addPage(moduleScrollArea, moduleinfo.moduleName());
210 page->setIcon( KIcon(moduleinfo.icon()) );
211 page->setHeader(moduleinfo.comment());
215 KCModuleProxy* KCMultiWidget::currentModule()
217 KPageWidgetItem *pageWidget = currentPage();
218 if ( pageWidget == 0 )
219 return 0;
221 QScrollArea *scrollArea = qobject_cast<QScrollArea*>( pageWidget->widget() );
222 KCModuleProxy *module = qobject_cast<KCModuleProxy*>( scrollArea->widget() );
224 return module;
228 void KCMultiWidget::slotAboutToShow(KPageWidgetItem* current, KPageWidgetItem* before)
230 if( before != 0 ) {
231 QScrollArea *scrollArea = qobject_cast<QScrollArea*>( before->widget() );
232 KCModuleProxy *module = qobject_cast<KCModuleProxy*>( scrollArea->widget() );
233 if (!queryClose(module)) {
234 setCurrentPage(before);
235 return;
239 QWidget* sendingWidget = current->widget();
240 slotAboutToShow(sendingWidget);
244 void KCMultiWidget::slotAboutToShow(QWidget *page)
246 QList<KCModuleProxy*> objects = page->findChildren<KCModuleProxy*>();
248 // add fall back
249 objects.append( qobject_cast<KCModuleProxy*>(page) );
251 KCModuleProxy *module = objects.first();
252 if( ! module ) {
253 return;
256 emit ( aboutToShow( module ) );
258 int buttons = 0;
259 bool found = false;
260 foreach( const CreatedModule &it, m_modules ) {
261 if( it.kcm==module) {
262 showButton(User2, it.adminmode);
263 buttons = it.buttons;
264 found = true;
267 if (!found) {
268 buttons = module->buttons();
271 showButton(Apply, buttons & KCModule::Apply);
272 showButton(Reset, buttons & KCModule::Apply);
274 enableButton( KDialog::Help, buttons & KCModule::Help );
275 enableButton( KDialog::Default, buttons & KCModule::Default );
277 disconnect( this, SIGNAL(user3Clicked()), 0, 0 );
279 // if (module->moduleInfo().needsRootPrivileges() &&
280 // !module->rootMode() )
281 // { /* Enable the Admin Mode button */
282 // enableButton( User2, true );
283 // connect( this, SIGNAL(user3Clicked()), module, SLOT( runAsRoot() ));
284 // connect( this, SIGNAL(user3Clicked()), SLOT( disableRModeButton() ));
285 // } else {
286 // enableButton( User2, false );
287 // }
290 // Currently unused. Whenever root mode comes back
291 #if 0
292 void KCMultiWidget::rootExit()
294 enableButton( User2, true);
297 void KCMultiWidget::disableRModeButton()
299 enableButton( User2, false );
300 connect ( currentModule(), SIGNAL( childClosed() ), SLOT( rootExit() ) );
302 #endif
305 void KCMultiWidget::apply(KCModuleProxy *module)
307 module->save();
308 emit configCommitted();
310 // TODO: check what that stuff does! I think it's not needed
311 QStringList updatedModules;
312 QStringList names = moduleParentComponents[ module ];
313 foreach ( const QString &name , names )
315 if ( updatedModules.indexOf(name) == -1 )
316 updatedModules.append(name);
319 foreach( const QString &it, updatedModules )
321 emit configCommitted( it.toLatin1() );
324 clientChanged(false);
328 void KCMultiWidget::defaults(KCModuleProxy *module)
330 module->defaults();
331 clientChanged( true );
335 bool KCMultiWidget::queryClose()
337 return queryClose(currentModule());
341 bool KCMultiWidget::queryClose(KCModuleProxy *module)
343 if( !module || !module->changed() )
344 return true;
346 // Let the user decide
347 int res = KMessageBox::warningYesNoCancel(
348 this,
349 i18n("There are unsaved changes in the active module.\n"
350 "Do you want to apply the changes or discard them?"),
351 i18n("Unsaved Changes"),
352 KStandardGuiItem::save(),
353 KStandardGuiItem::discard(),
354 KStandardGuiItem::cancel() );
356 switch (res) {
358 case KMessageBox::Yes:
359 apply(module);
360 return true;
362 case KMessageBox::No:
363 reset(module);
364 return true;
366 case KMessageBox::Cancel:
367 return false;
369 default:
370 Q_ASSERT(false);
371 return false;
376 void KCMultiWidget::reset(KCModuleProxy *module)
378 module->load();
379 clientChanged(false);
383 #include "kcmultiwidget.moc"