2 Copyright (c) 2000 Matthias Elter <elter@kde.org>
3 Copyright (c) 2003 Daniel Molkentin <molkentin@kde.org>
4 Copyright (c) 2003,2006 Matthias Kretz <kretz@kde.org>
5 Copyright (c) 2004 Frans Englich <frans.englich@telia.com>
6 Copyright (c) 2006 Tobias Koenig <tokoe@kde.org>
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 "kcmultidialog.h"
26 #include "kcmultidialog_p.h"
28 #include <QtCore/QStringList>
29 #include <QtCore/QProcess>
31 #include <kauthorized.h>
36 #include <kpagewidgetmodel.h>
37 #include <kpushbutton.h>
38 #include <ktoolinvocation.h>
41 #include "kcmoduleloader.h"
42 #include "kcmoduleproxy.h"
44 void KCMultiDialogPrivate::_k_slotCurrentPageChanged( KPageWidgetItem
*item
)
51 KCModuleProxy
*module
= 0;
52 for ( int i
= 0; i
< modules
.count(); ++i
) {
53 if ( modules
[ i
].item
== item
) {
54 module
= modules
[ i
].kcm
;
61 kDebug(710) << "found module for page: " << module
->moduleInfo().moduleName();
63 currentModule
= module
;
65 updateButtons(currentModule
);
68 void KCMultiDialogPrivate::updateButtons(KCModuleProxy
*currentModule
)
71 q
->enableButton(KDialog::Help
, currentModule
->buttons() & KCModule::Help
);
72 q
->enableButton(KDialog::Default
, currentModule
->buttons() & KCModule::Default
);
75 void KCMultiDialogPrivate::_k_clientChanged()
78 for ( int i
= 0; i
< modules
.count(); ++i
) {
79 if ( modules
[ i
].kcm
->changed() ) {
80 q
->enableButton(KDialog::Apply
, true);
85 q
->enableButton(KDialog::Apply
, false);
88 void KCMultiDialogPrivate::_k_dialogClosed()
93 * If we don't delete them, the DBUS registration stays, and trying to load the KCMs
94 * in other situations will lead to "module already loaded in Foo," while to the user
95 * doesn't appear so(the dialog is hidden)
97 for ( int i
= 0; i
< modules
.count(); ++i
)
98 modules
[ i
].kcm
->deleteClient();
101 void KCMultiDialogPrivate::init()
104 q
->setFaceType(KPageDialog::Auto
);
105 q
->setCaption(i18n("Configure"));
106 q
->setButtons(KDialog::Help
| KDialog::Default
|KDialog::Cancel
| KDialog::Apply
| KDialog::Ok
| KDialog::User1
);
107 q
->setButtonGuiItem(KDialog::User1
, KStandardGuiItem::reset());
108 q
->setDefaultButton(KDialog::Ok
);
110 q
->showButtonSeparator(true);
112 q
->connect(q
, SIGNAL(finished()), SLOT(_k_dialogClosed()));
114 q
->showButton(KDialog::User1
, false);
115 q
->enableButton(KDialog::Apply
, false);
117 q
->connect(q
, SIGNAL(currentPageChanged(KPageWidgetItem
*, KPageWidgetItem
*)),
118 SLOT(_k_slotCurrentPageChanged(KPageWidgetItem
*)));
120 q
->connect(q
, SIGNAL(applyClicked()), SLOT(slotApplyClicked()));
121 q
->connect(q
, SIGNAL(okClicked()), SLOT(slotOkClicked()));
122 q
->connect(q
, SIGNAL(defaultClicked()), SLOT(slotDefaultClicked()));
123 q
->connect(q
, SIGNAL(helpClicked()), SLOT(slotHelpClicked()));
124 q
->connect(q
, SIGNAL(user1Clicked()), SLOT(slotUser1Clicked()));
126 q
->setInitialSize(QSize(800, 550));
129 KCMultiDialog::KCMultiDialog( QWidget
*parent
)
130 : KPageDialog(*new KCMultiDialogPrivate
, NULL
, parent
)
135 KCMultiDialog::KCMultiDialog(KPageWidget
*pageWidget
, QWidget
*parent
, Qt::WFlags flags
)
136 : KPageDialog(*new KCMultiDialogPrivate
, pageWidget
, parent
, flags
)
141 KCMultiDialog::KCMultiDialog(KCMultiDialogPrivate
&dd
, KPageWidget
*pageWidget
, QWidget
*parent
, Qt::WFlags flags
)
142 : KPageDialog(dd
, pageWidget
, parent
, flags
)
147 KCMultiDialog::~KCMultiDialog()
151 void KCMultiDialog::slotDefaultClicked()
154 const KPageWidgetItem
*item
= currentPage();
158 for ( int i
= 0; i
< d
->modules
.count(); ++i
) {
159 if ( d
->modules
[ i
].item
== item
) {
160 d
->modules
[ i
].kcm
->defaults();
161 d
->_k_clientChanged();
167 void KCMultiDialog::slotUser1Clicked()
169 const KPageWidgetItem
*item
= currentPage();
174 for ( int i
= 0; i
< d
->modules
.count(); ++i
) {
175 if ( d
->modules
[ i
].item
== item
) {
176 d
->modules
[ i
].kcm
->load();
177 d
->_k_clientChanged();
183 void KCMultiDialogPrivate::apply()
186 QStringList updatedComponents
;
188 foreach (const CreatedModule
&module
, modules
) {
189 KCModuleProxy
*proxy
= module
.kcm
;
191 if (proxy
->changed()) {
195 * Add name of the components the kcm belongs to the list
196 * of updated components.
198 const QStringList componentNames
= module
.componentNames
;
199 foreach (const QString
&componentName
, module
.componentNames
) {
200 if (!updatedComponents
.contains(componentName
)) {
201 updatedComponents
.append(componentName
);
207 // Send the configCommitted signal for every updated component.
208 foreach (const QString
&name
, updatedComponents
) {
209 emit q
->configCommitted(name
.toLatin1());
212 emit q
->configCommitted();
215 void KCMultiDialog::slotApplyClicked()
217 setButtonFocus( Apply
);
223 void KCMultiDialog::slotOkClicked()
225 setButtonFocus( Ok
);
231 void KCMultiDialog::slotHelpClicked()
233 const KPageWidgetItem
*item
= currentPage();
239 for ( int i
= 0; i
< d
->modules
.count(); ++i
) {
240 if ( d
->modules
[ i
].item
== item
) {
241 docPath
= d
->modules
[ i
].kcm
->moduleInfo().docPath();
246 KUrl
docUrl( KUrl( "help:/" ), docPath
);
247 if ( docUrl
.protocol() == "help" || docUrl
.protocol() == "man" || docUrl
.protocol() == "info" ) {
248 QProcess::startDetached("khelpcenter", QStringList() << docUrl
.url());
250 KToolInvocation::invokeBrowser( docUrl
.url() );
255 KPageWidgetItem
* KCMultiDialog::addModule( const QString
& path
, const QStringList
& args
)
257 QString complete
= path
;
259 if ( !path
.endsWith( ".desktop" ) )
260 complete
+= ".desktop";
262 KService::Ptr service
= KService::serviceByStorageId( complete
);
264 return addModule( KCModuleInfo( service
), 0, args
);
267 KPageWidgetItem
* KCMultiDialog::addModule( const KCModuleInfo
& moduleInfo
,
268 KPageWidgetItem
*parentItem
, const QStringList
& args
)
270 if ( !moduleInfo
.service() )
273 //KAuthorized::authorizeControlModule( moduleInfo.service()->menuId() ) is
274 //checked in noDisplay already
275 if ( moduleInfo
.service()->noDisplay() )
278 KCModuleProxy
*kcm
= new KCModuleProxy(moduleInfo
, 0, args
);
280 kDebug(710) << moduleInfo
.moduleName();
281 KPageWidgetItem
*item
= new KPageWidgetItem(kcm
, moduleInfo
.moduleName());
282 item
->setHeader( moduleInfo
.comment() );
283 item
->setIcon( KIcon( moduleInfo
.icon() ) );
284 item
->setProperty("_k_weight", moduleInfo
.weight());
286 bool updateCurrentPage
= false;
287 const KPageWidgetModel
*model
= qobject_cast
<const KPageWidgetModel
*>(pageWidget()->model());
290 const QModelIndex parentIndex
= model
->index(parentItem
);
291 const int siblingCount
= model
->rowCount(parentIndex
);
293 for (; row
< siblingCount
; ++row
) {
294 KPageWidgetItem
*siblingItem
= model
->item(parentIndex
.child(row
, 0));
295 if (siblingItem
->property("_k_weight").toInt() > moduleInfo
.weight()) {
296 // the item we found is heavier than the new module
297 kDebug(710) << "adding KCM " << item
->name() << " before " << siblingItem
->name();
298 insertPage(siblingItem
, item
);
302 if (row
>= siblingCount
) {
303 // the new module is either the first or the heaviest item
304 kDebug(710) << "adding KCM " << item
->name() << " with parent " << parentItem
->name();
305 addSubPage(parentItem
, item
);
308 const int siblingCount
= model
->rowCount();
310 for (; row
< siblingCount
; ++row
) {
311 KPageWidgetItem
*siblingItem
= model
->item(model
->index(row
, 0));
312 if (siblingItem
->property("_k_weight").toInt() > moduleInfo
.weight()) {
313 // the item we found is heavier than the new module
314 kDebug(710) << "adding KCM " << item
->name() << " before " << siblingItem
->name();
315 insertPage(siblingItem
, item
);
316 if ( siblingItem
== currentPage() )
317 updateCurrentPage
= true;
322 if (row
== siblingCount
) {
323 // the new module is either the first or the heaviest item
324 kDebug(710) << "adding KCM " << item
->name() << " at the top level";
329 connect(kcm
, SIGNAL(changed(bool)), this, SLOT(_k_clientChanged()));
333 KCMultiDialogPrivate::CreatedModule cm
;
336 cm
.componentNames
= moduleInfo
.service()->property( "X-KDE-ParentComponents" ).toStringList();
337 d
->modules
.append( cm
);
339 if ( d
->modules
.count() == 1 || updateCurrentPage
)
341 setCurrentPage( item
);
342 d
->updateButtons(kcm
);
347 void KCMultiDialog::clear()
352 for ( int i
= 0; i
< d
->modules
.count(); ++i
) {
353 removePage( d
->modules
[ i
].item
);
354 delete d
->modules
[ i
].kcm
;
359 d
->_k_clientChanged();
364 #include "kcmultidialog.moc"