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.
21 #include "kcm_hotkeys.h"
22 #include "kcm_module_factory.h"
28 #include "action_data/action_data_group.h"
30 #include "action_group_widget.h"
31 #include "simple_action_data_widget.h"
32 #include "global_settings_widget.h"
34 #include "daemon/daemon.h"
35 #include "khotkeys_interface.h"
36 #include "hotkeys_model.h"
37 #include "hotkeys_proxy_model.h"
38 #include "hotkeys_tree_view.h"
39 #include "khotkeysglobal.h"
41 #include <QtGui/QHBoxLayout>
42 #include <QtGui/QSplitter>
43 #include <QtGui/QStackedWidget>
44 #include <QtGui/QWidget>
46 #include <QtDBus/QtDBus>
48 #include <KDE/KAboutData>
50 #include <KDE/KLocale>
51 #include <KDE/KMessageBox>
52 #include <KDE/KPluginLoader>
56 class KCMHotkeysPrivate
60 KCMHotkeysPrivate( KCMHotkeys
*host
);
62 // Treeview displaying the shortcuts
65 /** The model holding the shortcut settings. Beware! There a proxy
66 * between us and that model */
72 //! Container for all editing widgets
73 QStackedWidget
*stack
;
75 //! Widget to edit an action group
76 ActionGroupWidget
*action_group
;
78 //! The currently shown dialog
79 HotkeysWidgetIFace
*current
;
81 //! GlobalSettingsWidget
82 GlobalSettingsWidget
*global_settings
;
84 SimpleActionDataWidget
*simple_action
;
87 * Show the widget. If the current widget has changes allow
88 * cancelation ! of this action
90 bool maybeShowWidget();
93 * Applies the changes from the current item
95 void applyCurrentItem();
98 * A Hotkey was changed. Update the treeview.
100 void slotHotkeyChanged(KHotKeys::ActionDataBase
*);
107 KCMHotkeys::KCMHotkeys( QWidget
*parent
, const QVariantList
& /* args */ )
108 : KCModule( KCMModuleFactory::componentData(), parent
)
109 ,d( new KCMHotkeysPrivate(this) )
111 // Inform KCModule of the buttons we support
112 KCModule::setButtons(KCModule::Buttons(KCModule::Default
| KCModule::Apply
));
114 // Add the about data
115 KAboutData
*about
= new KAboutData(
118 ki18n("KDE Hotkeys Configuration Module"),
121 KAboutData::License_GPL
,
122 ki18n("Copyright 2008 (c) Michael Jansen")
125 ki18n("Michael Jansen"),
127 "kde@michael-jansen.biz" );
130 // Tell KCModule we were changed.
132 d
->action_group
, SIGNAL(changed(bool)),
133 this, SIGNAL(changed(bool)) );
135 d
->simple_action
, SIGNAL(changed(bool)),
136 this, SIGNAL(changed(bool)) );
138 d
->global_settings
, SIGNAL(changed(bool)),
139 this, SIGNAL(changed(bool)) );
140 // Update TreeView if hotkeys was changed
142 d
->simple_action
, SIGNAL(changed(KHotKeys::ActionDataBase
*)),
143 this, SLOT(slotHotkeyChanged(KHotKeys::ActionDataBase
*)));
145 d
->action_group
, SIGNAL(changed(KHotKeys::ActionDataBase
*)),
146 this, SLOT(slotHotkeyChanged(KHotKeys::ActionDataBase
*)));
150 void KCMHotkeys::currentChanged( const QModelIndex
&pCurrent
, const QModelIndex
&pPrevious
)
152 // We're not interested in changes of columns. Just compare the rows
153 QModelIndex current
=
155 ? pCurrent
.sibling( pCurrent
.row(), 0 )
157 QModelIndex previous
=
159 ? pPrevious
.sibling( pPrevious
.row(), 0 )
162 // Now it's possible for previous and current to be the same
163 if (current
==previous
)
168 // Current and previous differ. Ask user if there are unsaved changes
169 if ( !d
->maybeShowWidget() )
174 if (!current
.isValid())
176 d
->current
= d
->global_settings
;
177 d
->global_settings
->copyFromObject();
178 d
->stack
->setCurrentWidget( d
->global_settings
);
182 // Now go on and activate the new item;
183 KHotKeys::ActionDataBase
*item
= d
->model
->indexToActionDataBase( current
);
184 QModelIndex typeOfIndex
= d
->model
->index( current
.row(), KHotkeysModel::TypeColumn
, current
.parent() );
186 switch (d
->model
->data( typeOfIndex
).toInt())
189 case KHotkeysModel::SimpleActionData
:
191 KHotKeys::SimpleActionData
*data
= dynamic_cast<KHotKeys::SimpleActionData
*>(item
);
194 d
->simple_action
->setActionData( data
);
195 d
->current
= d
->simple_action
;
200 case KHotkeysModel::ActionDataGroup
:
202 KHotKeys::ActionDataGroup
*group
= dynamic_cast<KHotKeys::ActionDataGroup
*>(item
);
205 d
->action_group
->setActionData( group
);
206 d
->current
= d
->action_group
;
213 const std::type_info
&ti
= typeid(*item
);
214 kDebug() << "##### Unknown ActionDataType " << ti
.name();
219 d
->stack
->setCurrentWidget( d
->current
);
223 KCMHotkeys::~KCMHotkeys()
229 void KCMHotkeys::defaults()
231 kWarning() << "not yet implemented!";
235 void KCMHotkeys::load()
241 void KCMHotkeys::slotChanged()
247 void KCMHotkeys::save()
253 // ==========================================================================
257 KCMHotkeysPrivate::KCMHotkeysPrivate( KCMHotkeys
*host
)
258 : treeView( new HotkeysTreeView
)
259 ,model(new KHotkeysModel
)
266 // The widget for groups
267 action_group
= new ActionGroupWidget(q
);
269 // The widget for simple hotkeys (one trigger - one action)
270 simple_action
= new SimpleActionDataWidget(q
);
272 // The widget for the global settings
273 global_settings
= new GlobalSettingsWidget(q
);
276 stack
= new QStackedWidget
;
277 stack
->addWidget( global_settings
);
278 stack
->addWidget( action_group
);
279 stack
->addWidget( simple_action
);
281 // A splitter for the treeview and the stack
282 QSplitter
*splitter
= new QSplitter
;
283 splitter
->addWidget( treeView
);
284 splitter
->addWidget( stack
);
287 QHBoxLayout
*layout
= new QHBoxLayout
;
288 layout
->addWidget( splitter
);
289 q
->setLayout( layout
);
291 // Initialize the global part of the khotkeys lib ( handler ... )
292 KHotKeys::init_global_data(false, q
);
294 treeView
->setModel(model
);
296 current
=global_settings
;
297 global_settings
->copyFromObject();
301 void KCMHotkeysPrivate::load()
303 // disconnect the signals
304 if (treeView
->selectionModel())
307 treeView
->selectionModel(), SIGNAL(currentChanged(QModelIndex
,QModelIndex
)),
308 q
, SLOT(currentChanged(QModelIndex
,QModelIndex
)) );
314 model
, SIGNAL( rowsRemoved( QModelIndex
, int, int )),
315 q
, SLOT( slotChanged() ));
317 model
, SIGNAL( rowsInserted( QModelIndex
, int, int )),
318 q
, SLOT( slotChanged() ));
320 model
, SIGNAL( dataChanged( QModelIndex
, QModelIndex
)),
321 q
, SLOT( slotChanged() ));
323 // reconnect the signals
325 treeView
->selectionModel(), SIGNAL(currentChanged(QModelIndex
,QModelIndex
)),
326 q
, SLOT(currentChanged(QModelIndex
,QModelIndex
)) );
329 KHotKeys::Daemon::start();
333 bool KCMHotkeysPrivate::maybeShowWidget()
335 // If the current widget is changed, ask user if switch is ok
336 if (current
&& current
->isChanged())
338 int choice
= KMessageBox::warningContinueCancel(
340 i18n("The current action has unsaved changes. If you continue those changes will be lost!"),
341 i18n("Save changes") );
342 if (choice
!= KMessageBox::Continue
)
346 // Apply the changes from the current item
354 void KCMHotkeysPrivate::save()
359 // Write the settings
362 if (!(KHotKeys::Daemon::isRunning() or KHotKeys::Daemon::start()))
366 "<qt>" + i18n("Unable to contact khotkeys. Your changes are saved but i failed to activate them") + "</qt>" );
370 // Inform kdedkhotkeys demon to reload settings
371 QDBusConnection bus
= QDBusConnection::sessionBus();
372 QPointer
<OrgKdeKhotkeysInterface
> iface
= new OrgKdeKhotkeysInterface(
379 if(!iface
->isValid())
381 err
= iface
->lastError();
384 kError() << err
.name() << ":" << err
.message();
388 "<qt>" + i18n("Unable to contact khotkeys. Your changes are saved but i failed to activate them") + "</qt>" );
392 // Reread the configuration. We have no possibility to check if it worked.
393 iface
->reread_configuration();
398 void KCMHotkeysPrivate::applyCurrentItem()
401 // Only save when really changed
402 if (current
->isChanged())
409 void KCMHotkeysPrivate::slotHotkeyChanged(KHotKeys::ActionDataBase
* hotkey
)
411 model
->emitChanged(hotkey
);
415 #include "moc_kcm_hotkeys.cpp"