some more win32'fication to fix non-ascii filename handling
[kdelibs.git] / kutils / kcmultidialog.cpp
blob6c2f142921aa84bbd1631010b31bb269f9da53a7
1 /*
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>
32 #include <kguiitem.h>
33 #include <khbox.h>
34 #include <kicon.h>
35 #include <klocale.h>
36 #include <kpagewidgetmodel.h>
37 #include <kpushbutton.h>
38 #include <ktoolinvocation.h>
39 #include <kdebug.h>
41 #include "kcmoduleloader.h"
42 #include "kcmoduleproxy.h"
44 void KCMultiDialogPrivate::_k_slotCurrentPageChanged( KPageWidgetItem *item )
46 kDebug(710) ;
48 if ( !item )
49 return;
51 KCModuleProxy *module = 0;
52 for ( int i = 0; i < modules.count(); ++i ) {
53 if ( modules[ i ].item == item ) {
54 module = modules[ i ].kcm;
55 break;
59 if ( !module )
60 return;
61 kDebug(710) << "found module for page: " << module->moduleInfo().moduleName();
63 currentModule = module;
65 updateButtons(currentModule);
68 void KCMultiDialogPrivate::updateButtons(KCModuleProxy *currentModule)
70 Q_Q(KCMultiDialog);
71 q->enableButton(KDialog::Help, currentModule->buttons() & KCModule::Help);
72 q->enableButton(KDialog::Default, currentModule->buttons() & KCModule::Default);
75 void KCMultiDialogPrivate::_k_clientChanged()
77 Q_Q(KCMultiDialog);
78 for ( int i = 0; i < modules.count(); ++i ) {
79 if ( modules[ i ].kcm->changed() ) {
80 q->enableButton(KDialog::Apply, true);
81 return;
85 q->enableButton(KDialog::Apply, false);
88 void KCMultiDialogPrivate::_k_dialogClosed()
90 kDebug(710) ;
92 /**
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()
103 Q_Q(KCMultiDialog);
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);
109 q->setModal(false);
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)
132 d_func()->init();
135 KCMultiDialog::KCMultiDialog(KPageWidget *pageWidget, QWidget *parent, Qt::WFlags flags)
136 : KPageDialog(*new KCMultiDialogPrivate, pageWidget, parent, flags)
138 d_func()->init();
141 KCMultiDialog::KCMultiDialog(KCMultiDialogPrivate &dd, KPageWidget *pageWidget, QWidget *parent, Qt::WFlags flags)
142 : KPageDialog(dd, pageWidget, parent, flags)
144 d_func()->init();
147 KCMultiDialog::~KCMultiDialog()
151 void KCMultiDialog::slotDefaultClicked()
153 Q_D(KCMultiDialog);
154 const KPageWidgetItem *item = currentPage();
155 if ( !item )
156 return;
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();
162 return;
167 void KCMultiDialog::slotUser1Clicked()
169 const KPageWidgetItem *item = currentPage();
170 if ( !item )
171 return;
173 Q_D(KCMultiDialog);
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();
178 return;
183 void KCMultiDialogPrivate::apply()
185 Q_Q(KCMultiDialog);
186 QStringList updatedComponents;
188 foreach (const CreatedModule &module, modules) {
189 KCModuleProxy *proxy = module.kcm;
191 if (proxy->changed()) {
192 proxy->save();
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 );
219 d_func()->apply();
223 void KCMultiDialog::slotOkClicked()
225 setButtonFocus( Ok );
227 d_func()->apply();
228 accept();
231 void KCMultiDialog::slotHelpClicked()
233 const KPageWidgetItem *item = currentPage();
234 if ( !item )
235 return;
237 Q_D(KCMultiDialog);
238 QString docPath;
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();
242 break;
246 KUrl docUrl( KUrl( "help:/" ), docPath );
247 if ( docUrl.protocol() == "help" || docUrl.protocol() == "man" || docUrl.protocol() == "info" ) {
248 QProcess::startDetached("khelpcenter", QStringList() << docUrl.url());
249 } else {
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() )
271 return 0;
273 //KAuthorized::authorizeControlModule( moduleInfo.service()->menuId() ) is
274 //checked in noDisplay already
275 if ( moduleInfo.service()->noDisplay() )
276 return 0;
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());
288 Q_ASSERT(model);
289 if (parentItem) {
290 const QModelIndex parentIndex = model->index(parentItem);
291 const int siblingCount = model->rowCount(parentIndex);
292 int row = 0;
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);
299 break;
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);
307 } else {
308 const int siblingCount = model->rowCount();
309 int row = 0;
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;
319 break;
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";
325 addPage(item);
329 connect(kcm, SIGNAL(changed(bool)), this, SLOT(_k_clientChanged()));
332 Q_D(KCMultiDialog);
333 KCMultiDialogPrivate::CreatedModule cm;
334 cm.kcm = kcm;
335 cm.item = item;
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);
344 return item;
347 void KCMultiDialog::clear()
349 Q_D(KCMultiDialog);
350 kDebug( 710 ) ;
352 for ( int i = 0; i < d->modules.count(); ++i ) {
353 removePage( d->modules[ i ].item );
354 delete d->modules[ i ].kcm;
357 d->modules.clear();
359 d->_k_clientChanged();
364 #include "kcmultidialog.moc"