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
;
66 q
->enableButton(KDialog::Help
, currentModule
->buttons() & KCModule::Help
);
67 q
->enableButton(KDialog::Default
, currentModule
->buttons() & KCModule::Default
);
70 void KCMultiDialogPrivate::_k_clientChanged()
73 for ( int i
= 0; i
< modules
.count(); ++i
) {
74 if ( modules
[ i
].kcm
->changed() ) {
75 q
->enableButton(KDialog::Apply
, true);
80 q
->enableButton(KDialog::Apply
, false);
83 void KCMultiDialogPrivate::_k_dialogClosed()
88 * If we don't delete them, the DBUS registration stays, and trying to load the KCMs
89 * in other situations will lead to "module already loaded in Foo," while to the user
90 * doesn't appear so(the dialog is hidden)
92 for ( int i
= 0; i
< modules
.count(); ++i
)
93 modules
[ i
].kcm
->deleteClient();
96 void KCMultiDialogPrivate::init()
99 q
->setFaceType(KPageDialog::Auto
);
100 q
->setCaption(i18n("Configure"));
101 q
->setButtons(KDialog::Help
| KDialog::Default
|KDialog::Cancel
| KDialog::Apply
| KDialog::Ok
| KDialog::User1
);
102 q
->setButtonGuiItem(KDialog::User1
, KStandardGuiItem::reset());
103 q
->setDefaultButton(KDialog::Ok
);
105 q
->showButtonSeparator(true);
107 q
->connect(q
, SIGNAL(finished()), SLOT(_k_dialogClosed()));
109 q
->showButton(KDialog::User1
, false);
110 q
->enableButton(KDialog::Apply
, false);
112 q
->connect(q
, SIGNAL(currentPageChanged(KPageWidgetItem
*, KPageWidgetItem
*)),
113 SLOT(_k_slotCurrentPageChanged(KPageWidgetItem
*)));
115 q
->connect(q
, SIGNAL(applyClicked()), SLOT(slotApplyClicked()));
116 q
->connect(q
, SIGNAL(okClicked()), SLOT(slotOkClicked()));
117 q
->connect(q
, SIGNAL(defaultClicked()), SLOT(slotDefaultClicked()));
118 q
->connect(q
, SIGNAL(helpClicked()), SLOT(slotHelpClicked()));
119 q
->connect(q
, SIGNAL(user1Clicked()), SLOT(slotUser1Clicked()));
121 q
->setInitialSize(QSize(640, 480));
124 KCMultiDialog::KCMultiDialog( QWidget
*parent
)
125 : KPageDialog(*new KCMultiDialogPrivate
, NULL
, parent
)
130 KCMultiDialog::KCMultiDialog(KPageWidget
*pageWidget
, QWidget
*parent
, Qt::WFlags flags
)
131 : KPageDialog(*new KCMultiDialogPrivate
, pageWidget
, parent
, flags
)
136 KCMultiDialog::KCMultiDialog(KCMultiDialogPrivate
&dd
, KPageWidget
*pageWidget
, QWidget
*parent
, Qt::WFlags flags
)
137 : KPageDialog(dd
, pageWidget
, parent
, flags
)
142 KCMultiDialog::~KCMultiDialog()
146 void KCMultiDialog::slotDefaultClicked()
149 const KPageWidgetItem
*item
= currentPage();
153 for ( int i
= 0; i
< d
->modules
.count(); ++i
) {
154 if ( d
->modules
[ i
].item
== item
) {
155 d
->modules
[ i
].kcm
->defaults();
156 d
->_k_clientChanged();
162 void KCMultiDialog::slotUser1Clicked()
164 const KPageWidgetItem
*item
= currentPage();
169 for ( int i
= 0; i
< d
->modules
.count(); ++i
) {
170 if ( d
->modules
[ i
].item
== item
) {
171 d
->modules
[ i
].kcm
->load();
172 d
->_k_clientChanged();
178 void KCMultiDialogPrivate::apply()
181 QStringList updatedComponents
;
183 foreach (const CreatedModule
&module
, modules
) {
184 KCModuleProxy
*proxy
= module
.kcm
;
186 if (proxy
->changed()) {
190 * Add name of the components the kcm belongs to the list
191 * of updated components.
193 const QStringList componentNames
= module
.componentNames
;
194 foreach (const QString
&componentName
, module
.componentNames
) {
195 if (!updatedComponents
.contains(componentName
)) {
196 updatedComponents
.append(componentName
);
202 // Send the configCommitted signal for every updated component.
203 foreach (const QString
&name
, updatedComponents
) {
204 emit q
->configCommitted(name
.toLatin1());
207 emit q
->configCommitted();
210 void KCMultiDialog::slotApplyClicked()
212 setButtonFocus( Apply
);
218 void KCMultiDialog::slotOkClicked()
220 setButtonFocus( Ok
);
226 void KCMultiDialog::slotHelpClicked()
228 const KPageWidgetItem
*item
= currentPage();
234 for ( int i
= 0; i
< d
->modules
.count(); ++i
) {
235 if ( d
->modules
[ i
].item
== item
) {
236 docPath
= d
->modules
[ i
].kcm
->moduleInfo().docPath();
241 KUrl
docUrl( KUrl( "help:/" ), docPath
);
242 if ( docUrl
.protocol() == "help" || docUrl
.protocol() == "man" || docUrl
.protocol() == "info" ) {
243 QProcess::startDetached("khelpcenter", QStringList() << docUrl
.url());
245 KToolInvocation::invokeBrowser( docUrl
.url() );
250 KPageWidgetItem
* KCMultiDialog::addModule( const QString
& path
, const QStringList
& args
)
252 QString complete
= path
;
254 if ( !path
.endsWith( ".desktop" ) )
255 complete
+= ".desktop";
257 KService::Ptr service
= KService::serviceByStorageId( complete
);
259 return addModule( KCModuleInfo( service
), 0, args
);
262 KPageWidgetItem
* KCMultiDialog::addModule( const KCModuleInfo
& moduleInfo
,
263 KPageWidgetItem
*parentItem
, const QStringList
& args
)
265 if ( !moduleInfo
.service() )
268 //KAuthorized::authorizeControlModule( moduleInfo.service()->menuId() ) is
269 //checked in noDisplay already
270 if ( moduleInfo
.service()->noDisplay() )
273 KCModuleProxy
*kcm
= new KCModuleProxy(moduleInfo
, 0, args
);
275 kDebug(710) << moduleInfo
.moduleName();
276 KPageWidgetItem
*item
= new KPageWidgetItem(kcm
, moduleInfo
.moduleName());
277 item
->setHeader( moduleInfo
.comment() );
278 item
->setIcon( KIcon( moduleInfo
.icon() ) );
279 item
->setProperty("_k_weight", moduleInfo
.weight());
281 bool updateCurrentPage
= false;
282 const KPageWidgetModel
*model
= qobject_cast
<const KPageWidgetModel
*>(pageWidget()->model());
285 const QModelIndex parentIndex
= model
->index(parentItem
);
286 const int siblingCount
= model
->rowCount(parentIndex
);
288 for (; row
< siblingCount
; ++row
) {
289 KPageWidgetItem
*siblingItem
= model
->item(parentIndex
.child(row
, 0));
290 if (siblingItem
->property("_k_weight").toInt() > moduleInfo
.weight()) {
291 // the item we found is heavier than the new module
292 kDebug(710) << "adding KCM " << item
->name() << " before " << siblingItem
->name();
293 insertPage(siblingItem
, item
);
297 if (row
>= siblingCount
) {
298 // the new module is either the first or the heaviest item
299 kDebug(710) << "adding KCM " << item
->name() << " with parent " << parentItem
->name();
300 addSubPage(parentItem
, item
);
303 const int siblingCount
= model
->rowCount();
305 for (; row
< siblingCount
; ++row
) {
306 KPageWidgetItem
*siblingItem
= model
->item(model
->index(row
, 0));
307 if (siblingItem
->property("_k_weight").toInt() > moduleInfo
.weight()) {
308 // the item we found is heavier than the new module
309 kDebug(710) << "adding KCM " << item
->name() << " before " << siblingItem
->name();
310 insertPage(siblingItem
, item
);
311 if ( siblingItem
== currentPage() )
312 updateCurrentPage
= true;
317 if (row
== siblingCount
) {
318 // the new module is either the first or the heaviest item
319 kDebug(710) << "adding KCM " << item
->name() << " at the top level";
324 connect(kcm
, SIGNAL(changed(bool)), this, SLOT(_k_clientChanged()));
328 KCMultiDialogPrivate::CreatedModule cm
;
331 cm
.componentNames
= moduleInfo
.service()->property( "X-KDE-ParentComponents" ).toStringList();
332 d
->modules
.append( cm
);
334 if ( d
->modules
.count() == 1 || updateCurrentPage
)
335 setCurrentPage( item
);
340 void KCMultiDialog::clear()
345 for ( int i
= 0; i
< d
->modules
.count(); ++i
) {
346 removePage( d
->modules
[ i
].item
);
347 delete d
->modules
[ i
].kcm
;
352 d
->_k_clientChanged();
357 #include "kcmultidialog.moc"