2 Copyright (C) 2008 Michael Jansen <kde@michael-jansen.biz>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
20 #include "kcm_gestures.h"
21 #include "kcm_module_factory.h"
26 #include "action_data_group.h"
28 #include "action_group_widget.h"
29 #include "simple_action_data_widget.h"
31 #include "hotkeys_model.h"
32 #include "hotkeys_proxy_model.h"
33 #include "hotkeys_tree_view.h"
34 #include "khotkeysglobal.h"
36 #include <QtGui/QHBoxLayout>
37 #include <QtGui/QSplitter>
38 #include <QtGui/QStackedWidget>
39 #include <QtGui/QWidget>
41 #include <QtDBus/QtDBus>
43 #include <KDE/KAboutData>
45 #include <KDE/KLocale>
46 #include <KDE/KMessageBox>
48 class KCMGesturesPrivate
52 KCMGesturesPrivate( KCMGestures
*host
);
54 // Treeview displaying the shortcuts
57 /** The model holding the shortcut settings. Beware! There a proxy
58 * between us and that model */
64 //! Container for all editing widgets
65 QStackedWidget
*stack
;
67 //! Widget to edit an action group
68 ActionGroupWidget
*action_group
;
70 //! The currently shown dialog
71 HotkeysWidgetBase
*current
;
73 SimpleActionDataWidget
*simple_action
;
76 * Show the widget. If the current widget has changes allow
77 * cancelation ! of this action
79 bool maybeShowWidget();
82 * Save the currentely shown item
84 void saveCurrentItem();
91 KCMGestures::KCMGestures( QWidget
*parent
, const QVariantList
& /* args */ )
92 : KCModule( KCMModuleFactory::componentData(), parent
)
93 ,d( new KCMGesturesPrivate(this) )
95 // Inform KCModule of the buttons we support
96 KCModule::setButtons(KCModule::Buttons(KCModule::Default
| KCModule::Apply
));
99 KAboutData
*about
= new KAboutData(
102 ki18n("KDE Hotkeys Configuration Module"),
105 KAboutData::License_GPL
,
106 ki18n("Copyright 2008 (c) Michael Jansen")
109 ki18n("Michael Jansen"),
111 "kde@michael-jansen.biz" );
114 // Tell KCModule we were changed.
116 d
->action_group
, SIGNAL(changed(bool)),
117 this, SIGNAL(changed(bool)) );
119 d
->simple_action
, SIGNAL(changed(bool)),
120 this, SIGNAL(changed(bool)) );
127 void KCMGestures::currentChanged( const QModelIndex
&pCurrent
, const QModelIndex
&pPrevious
)
129 // We're not interested in changes of columns. Just compare the rows
130 QModelIndex current
=
132 ? pCurrent
.sibling( pCurrent
.row(), 0 )
134 QModelIndex previous
=
136 ? pPrevious
.sibling( pPrevious
.row(), 0 )
139 // Now it's possible for previous and current to be the same
140 if (current
==previous
)
145 // Current and previous differ. Ask user if there are unsaved changes
146 if ( !d
->maybeShowWidget() )
151 Q_ASSERT(current
.isValid());
152 if (!current
.isValid())
157 // Now go on and activate the new item;
158 KHotKeys::ActionDataBase
*item
= d
->model
->indexToActionDataBase( current
);
159 QModelIndex typeOfIndex
= d
->model
->index( current
.row(), KHotkeysModel::TypeColumn
, current
.parent() );
161 switch (d
->model
->data( typeOfIndex
).toInt())
164 case KHotkeysModel::SimpleActionData
:
166 KHotKeys::SimpleActionData
*data
= dynamic_cast<KHotKeys::SimpleActionData
*>(item
);
169 d
->simple_action
->setActionData( data
);
170 d
->current
= d
->simple_action
;
175 case KHotkeysModel::ActionDataGroup
:
177 KHotKeys::ActionDataGroup
*group
= dynamic_cast<KHotKeys::ActionDataGroup
*>(item
);
180 d
->action_group
->setActionData( group
);
181 d
->current
= d
->action_group
;
188 const std::type_info
&ti
= typeid(*item
);
189 kDebug() << "##### Unknown ActionDataType " << ti
.name();
194 d
->stack
->setCurrentWidget( d
->current
);
198 KCMGestures::~KCMGestures()
204 void KCMGestures::defaults()
206 kWarning() << "not yet implemented!";
210 void KCMGestures::load()
216 void KCMGestures::slotChanged()
222 void KCMGestures::save()
228 // ==========================================================================
229 // KCMGesturesPrivate
232 KCMGesturesPrivate::KCMGesturesPrivate( KCMGestures
*host
)
233 : treeView( new HotkeysTreeView
)
234 ,model(new KHotkeysModel
)
241 action_group
= new ActionGroupWidget(q
);
242 simple_action
= new SimpleActionDataWidget(q
);
245 stack
= new QStackedWidget
;
246 stack
->addWidget( action_group
);
247 stack
->addWidget( simple_action
);
249 // A splitter for the treeview and the stack
250 QSplitter
*splitter
= new QSplitter
;
251 splitter
->addWidget( treeView
);
252 splitter
->addWidget( stack
);
255 QHBoxLayout
*layout
= new QHBoxLayout
;
256 layout
->addWidget( splitter
);
257 q
->setLayout( layout
);
259 // Initialize the global part of the khotkeys lib ( handler ... )
260 KHotKeys::init_global_data(false, q
);
262 treeView
->setModel(model
);
266 void KCMGesturesPrivate::load()
268 // disconnect the signals
269 if (treeView
->selectionModel())
272 treeView
->selectionModel(), SIGNAL(currentChanged(QModelIndex
,QModelIndex
)),
273 q
, SLOT(currentChanged(QModelIndex
,QModelIndex
)) );
279 model
, SIGNAL( rowsRemoved( QModelIndex
, int, int )),
280 q
, SLOT( slotChanged() ));
282 model
, SIGNAL( rowsInserted( QModelIndex
, int, int )),
283 q
, SLOT( slotChanged() ));
285 model
, SIGNAL( dataChanged( QModelIndex
, QModelIndex
)),
286 q
, SLOT( slotChanged() ));
288 // reconnect the signals
290 treeView
->selectionModel(), SIGNAL(currentChanged(QModelIndex
,QModelIndex
)),
291 q
, SLOT(currentChanged(QModelIndex
,QModelIndex
)) );
295 bool KCMGesturesPrivate::maybeShowWidget()
297 // If the current widget is changed, ask user if switch is ok
298 if (current
&& current
->isChanged())
300 int choice
= KMessageBox::warningContinueCancel(
302 i18n("The current action has unsaved changes. If you continue those changes will be lost!"),
303 i18n("Save changes") );
304 if (choice
!= KMessageBox::Continue
)
308 // Save the current Item
315 void KCMGesturesPrivate::save()
317 if ( current
&& current
->isChanged() )
322 // Write the settings
325 // Inform kdedkhotkeys demon to reload settings
326 QDBusConnection bus
= QDBusConnection::sessionBus();
327 QPointer
<QDBusInterface
> iface
= new QDBusInterface("org.kde.kded", "/modules/khotkeys",
328 "org.kde.khotkeys", bus
, q
);
329 if(!iface
->isValid())
331 QDBusError err
= iface
->lastError();
334 kError() << err
.name() << ":" << err
.message();
336 QDBusInterface
kdedInterface( "org.kde.kded", "/kded","org.kde.kded" );
337 QDBusReply
<bool> reply
= kdedInterface
.call( "loadModule", "khotkeys" );
338 err
= iface
->lastError();
341 kError() << err
.name() << ":" << err
.message();
344 if ( reply
.isValid() )
347 KMessageBox::error(q
, "<qt>" + i18n("Started server <em>org.kde.khotkeys</em>.") + "</qt>");
349 KMessageBox::error(q
, "<qt>" + i18n("Unable to start server <em>org.kde.khotkeys</em>.") + "</qt>");
355 "<qt>" + i18n("Unable to start service <em>org.kde.khotkeys</em>.<br /><br /><i>Error: %1</i>",
356 reply
.error().message()) + "</qt>" );
359 // kDebug() << "Starting khotkeys demon";
360 // KToolInvocation::kdeinitExec( "khotkeys" );
364 kDebug() << "Pinging khotkeys demon";
365 QDBusMessage reply
= iface
->call("reread_configuration");
366 QDBusError err
= iface
->lastError();
369 kError() << err
.name() << ":" << err
.message();
376 void KCMGesturesPrivate::saveCurrentItem()
379 // Only save when really changed
380 if (current
->isChanged())
382 current
->copyToObject();
383 model
->emitChanged(current
->data());
389 #include "moc_kcm_gestures.cpp"