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 "hotkeys_context_menu.h"
23
#include "ui_kcm_hotkeys.h"
24
#include "kcm_module_factory.h"
30
#include "action_data/action_data_group.h"
32
#include "action_group_widget.h"
33
#include "simple_action_data_widget.h"
34
#include "global_settings_widget.h"
36
#include "daemon/daemon.h"
37
#include "khotkeys_interface.h"
38
#include "hotkeys_model.h"
39
#include "hotkeys_proxy_model.h"
40
#include "hotkeys_tree_view.h"
41
#include "khotkeysglobal.h"
43
#include <QtDBus/QtDBus>
45
#include <KDE/KAboutData>
47
#include <KDE/KLocale>
48
#include <KDE/KMessageBox>
49
#include <KDE/KPluginLoader>
53
class KCMHotkeysPrivate : public Ui::KCMHotkeysWidget
57
KCMHotkeysPrivate( KCMHotkeys *host );
59
/** The model holding the shortcut settings. Beware! There is a proxy
60
* model between us and that model */
66
//! The currently shown dialog
67
HotkeysWidgetIFace *current;
69
//! The currently shown item
70
QModelIndex currentIndex;
73
* Show the widget. If the current widget has changes allow
74
* cancelation ! of this action
76
bool maybeShowWidget(const QModelIndex &next);
79
* Applies the changes from the current item
81
void applyCurrentItem();
84
* A Hotkey was changed. Update the treeview.
86
void _k_hotkeyChanged(KHotKeys::ActionDataBase*);
89
* Activate the current item. The method is needed because of qt bug
91
void _k_activateCurrentItem();
98
KCMHotkeys::KCMHotkeys( QWidget *parent, const QVariantList & /* args */ )
99
: KCModule( KCMModuleFactory::componentData(), parent )
100
,d( new KCMHotkeysPrivate(this) )
102
// Inform KCModule of the buttons we support
103
KCModule::setButtons(KCModule::Buttons(KCModule::Default | KCModule::Apply));
105
// Add the about data
106
KAboutData *about = new KAboutData(
109
ki18n("KDE Hotkeys Configuration Module"),
112
KAboutData::License_GPL,
113
ki18n("Copyright 2008 (c) Michael Jansen")
116
ki18n("Michael Jansen"),
118
"kde@michael-jansen.biz" );
121
// Tell KCModule we were changed.
123
d->action_group, SIGNAL(changed(bool)),
124
this, SIGNAL(changed(bool)) );
126
d->simple_action, SIGNAL(changed(bool)),
127
this, SIGNAL(changed(bool)) );
129
d->global_settings, SIGNAL(changed(bool)),
130
this, SIGNAL(changed(bool)) );
131
// Update TreeView if hotkeys was changed
133
d->simple_action, SIGNAL(changed(KHotKeys::ActionDataBase*)),
134
this, SLOT(_k_hotkeyChanged(KHotKeys::ActionDataBase*)));
136
d->action_group, SIGNAL(changed(KHotKeys::ActionDataBase*)),
137
this, SLOT(_k_hotkeyChanged(KHotKeys::ActionDataBase*)));
139
// Show the context menu
140
d->menu_button->setMenu(new HotkeysTreeViewContextMenu(d->tree_view));
142
// Switch to the global settings dialog
143
connect(d->settings_button, SIGNAL(clicked(bool)),
144
SLOT(showGlobalSettings()));
148
void KCMHotkeys::currentChanged( const QModelIndex &pCurrent, const QModelIndex &pPrevious )
150
// We're not interested in changes of columns. Just compare the rows
151
QModelIndex current =
153
? pCurrent.sibling( pCurrent.row(), 0 )
155
QModelIndex previous =
157
? pPrevious.sibling( pPrevious.row(), 0 )
160
// Now it's possible for previous and current to be the same
161
if (current==previous || current==d->currentIndex)
166
// Current and previous differ. Ask user if there are unsaved changes
167
if ( !d->maybeShowWidget(current) )
169
// Bring focus back to the current item
170
d->tree_view->selectionModel()->setCurrentIndex(
172
QItemSelectionModel::SelectCurrent);
174
// See http://www.qtsoftware.com/developer/task-tracker/index_html?method=entry&id=132516
175
QTimer::singleShot(0, this, SLOT(_k_activateCurrentItem()));
179
if (!current.isValid())
181
return showGlobalSettings();
184
// Now go on and activate the new item;
185
KHotKeys::ActionDataBase *item = d->model->indexToActionDataBase( current );
186
QModelIndex typeOfIndex = d->model->index( current.row(), KHotkeysModel::TypeColumn, current.parent() );
188
switch (d->model->data( typeOfIndex ).toInt())
191
case KHotkeysModel::SimpleActionData:
193
KHotKeys::SimpleActionData *data = dynamic_cast<KHotKeys::SimpleActionData*>(item);
196
d->simple_action->setActionData( data );
197
d->current = d->simple_action;
202
case KHotkeysModel::ActionDataGroup:
204
KHotKeys::ActionDataGroup *group = dynamic_cast<KHotKeys::ActionDataGroup*>(item);
207
d->action_group->setActionData( group );
208
d->current = d->action_group;
215
const std::type_info &ti = typeid(*item);
216
kDebug() << "##### Unknown ActionDataType " << ti.name();
221
d->currentIndex = current;
222
d->stack->setCurrentWidget( d->current );
226
KCMHotkeys::~KCMHotkeys()
232
void KCMHotkeys::defaults()
234
kWarning() << "not yet implemented!";
238
void KCMHotkeys::load()
240
showGlobalSettings();
245
void KCMHotkeys::showGlobalSettings()
247
d->current = d->global_settings;
248
d->currentIndex = QModelIndex();
250
d->tree_view->setCurrentIndex(d->currentIndex);
251
d->global_settings->copyFromObject();
252
d->stack->setCurrentWidget( d->global_settings );
256
void KCMHotkeys::slotChanged()
262
void KCMHotkeys::slotReset()
264
showGlobalSettings();
268
void KCMHotkeys::save()
275
// ==========================================================================
279
KCMHotkeysPrivate::KCMHotkeysPrivate( KCMHotkeys *host )
280
: Ui::KCMHotkeysWidget()
287
// Initialize the global part of the khotkeys lib ( handler ... )
288
KHotKeys::init_global_data(false, q);
292
void KCMHotkeysPrivate::load()
295
KHotKeys::Daemon::start();
297
// disconnect the signals
298
if (tree_view->selectionModel())
301
tree_view->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
302
q, SLOT(currentChanged(QModelIndex,QModelIndex)) );
305
// Create a new model;
306
tree_view->setModel(new KHotkeysModel);
310
model = tree_view->model();
313
global_settings->setModel(model);
316
model, SIGNAL( rowsRemoved( QModelIndex, int, int )),
317
q, SLOT( slotChanged() ));
319
model, SIGNAL( rowsInserted( QModelIndex, int, int )),
320
q, SLOT( slotChanged() ));
322
model, SIGNAL( dataChanged( QModelIndex, QModelIndex )),
323
q, SLOT( slotChanged() ));
326
model, SIGNAL( modelAboutToBeReset()),
327
q, SLOT( slotReset() ));
329
// reconnect the signals
331
tree_view->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
332
q, SLOT(currentChanged(QModelIndex,QModelIndex)) );
336
bool KCMHotkeysPrivate::maybeShowWidget(const QModelIndex &nextIndex)
340
// If the current widget is changed, ask user if switch is ok
341
if (current && (currentIndex != nextIndex) && current->isChanged())
343
int choice = KMessageBox::warningContinueCancel(
345
i18n("The current action has unsaved changes. If you continue these changes will be lost."),
346
i18n("Save changes") );
347
if (choice != KMessageBox::Continue)
351
// Apply the changes from the current item
352
//applyCurrentItem();
359
void KCMHotkeysPrivate::save()
364
// Write the settings
367
if (!KHotKeys::Daemon::isRunning())
369
if (!KHotKeys::Daemon::start())
371
// On startup the demon does the updating stuff, therefore reload
379
"<qt>" + i18n("Unable to contact khotkeys. Your changes are saved, but they could not be activated.") + "</qt>" );
385
// Inform kdedkhotkeys demon to reload settings
386
QDBusConnection bus = QDBusConnection::sessionBus();
387
QPointer<OrgKdeKhotkeysInterface> iface = new OrgKdeKhotkeysInterface(
394
if(!iface->isValid())
396
err = iface->lastError();
399
kError() << err.name() << ":" << err.message();
403
"<qt>" + i18n("Unable to contact khotkeys. Your changes are saved, but they could not be activated.") + "</qt>" );
407
// Reread the configuration. We have no possibility to check if it worked.
408
iface->reread_configuration();
412
void KCMHotkeysPrivate::applyCurrentItem()
415
// Only save when really changed
416
if (current->isChanged())
423
void KCMHotkeysPrivate::_k_hotkeyChanged(KHotKeys::ActionDataBase* hotkey)
425
model->emitChanged(hotkey);
429
void KCMHotkeysPrivate::_k_activateCurrentItem()
431
tree_view->selectionModel()->setCurrentIndex(
432
tree_view->selectionModel()->currentIndex(),
433
QItemSelectionModel::SelectCurrent);
436
#include "moc_kcm_hotkeys.cpp"