add more spacing
[personal-kdebase.git] / workspace / khotkeys / kcm_hotkeys / kcm_gestures.cpp
blob98acc2b0a68faf5d9f385f75c20b07b76d930082
1 /*
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"
23 #include <typeinfo>
25 // ACTION_DATAS
26 #include "action_data_group.h"
27 // OUR ACTION WIDGETS
28 #include "action_group_widget.h"
29 #include "simple_action_data_widget.h"
30 // REST
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>
44 #include <KDE/KDebug>
45 #include <KDE/KLocale>
46 #include <KDE/KMessageBox>
48 class KCMGesturesPrivate
50 public:
52 KCMGesturesPrivate( KCMGestures *host );
54 // Treeview displaying the shortcuts
55 QTreeView *treeView;
57 /** The model holding the shortcut settings. Beware! There a proxy
58 * between us and that model */
59 KHotkeysModel *model;
61 //! Our host
62 KCMGestures *q;
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;
75 /**
76 * Show the widget. If the current widget has changes allow
77 * cancelation ! of this action
79 bool maybeShowWidget();
81 /**
82 * Save the currentely shown item
84 void saveCurrentItem();
86 void load();
87 void save();
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));
98 // Add the about data
99 KAboutData *about = new KAboutData(
100 "khotkeys",
102 ki18n("KDE Hotkeys Configuration Module"),
103 KDE_VERSION_STRING,
104 KLocalizedString(),
105 KAboutData::License_GPL,
106 ki18n("Copyright 2008 (c) Michael Jansen")
108 about->addAuthor(
109 ki18n("Michael Jansen"),
110 ki18n("Maintainer"),
111 "kde@michael-jansen.biz" );
112 setAboutData(about);
114 // Tell KCModule we were changed.
115 connect(
116 d->action_group, SIGNAL(changed(bool)),
117 this, SIGNAL(changed(bool)) );
118 connect(
119 d->simple_action, SIGNAL(changed(bool)),
120 this, SIGNAL(changed(bool)) );
122 // Load the settings
123 load();
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 =
131 pCurrent.isValid()
132 ? pCurrent.sibling( pCurrent.row(), 0 )
133 : QModelIndex();
134 QModelIndex previous =
135 pPrevious.isValid()
136 ? pPrevious.sibling( pPrevious.row(), 0 )
137 : QModelIndex();
139 // Now it's possible for previous and current to be the same
140 if (current==previous)
142 return;
145 // Current and previous differ. Ask user if there are unsaved changes
146 if ( !d->maybeShowWidget() )
148 return;
151 Q_ASSERT(current.isValid());
152 if (!current.isValid())
154 return;
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);
167 if (data)
169 d->simple_action->setActionData( data );
170 d->current = d->simple_action;
173 break;
175 case KHotkeysModel::ActionDataGroup:
177 KHotKeys::ActionDataGroup *group = dynamic_cast<KHotKeys::ActionDataGroup*>(item);
178 if (group)
180 d->action_group->setActionData( group );
181 d->current = d->action_group;
184 break;
186 default:
188 const std::type_info &ti = typeid(*item);
189 kDebug() << "##### Unknown ActionDataType " << ti.name();
192 } // switch
194 d->stack->setCurrentWidget( d->current );
198 KCMGestures::~KCMGestures()
200 delete d; d=0;
204 void KCMGestures::defaults()
206 kWarning() << "not yet implemented!";
210 void KCMGestures::load()
212 d->load();
216 void KCMGestures::slotChanged()
218 emit changed(true);
222 void KCMGestures::save()
224 d->save();
228 // ==========================================================================
229 // KCMGesturesPrivate
232 KCMGesturesPrivate::KCMGesturesPrivate( KCMGestures *host )
233 : treeView( new HotkeysTreeView )
234 ,model(new KHotkeysModel)
235 ,q(host)
236 ,stack(0)
237 ,action_group(0)
238 ,current(0)
239 ,simple_action(0)
241 action_group = new ActionGroupWidget(q);
242 simple_action = new SimpleActionDataWidget(q);
244 // Setup the stack
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 );
254 // The global layout
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())
271 QObject::disconnect(
272 treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
273 q, SLOT(currentChanged(QModelIndex,QModelIndex)) );
276 model->load();
278 QObject::connect(
279 model, SIGNAL( rowsRemoved( QModelIndex, int, int )),
280 q, SLOT( slotChanged() ));
281 QObject::connect(
282 model, SIGNAL( rowsInserted( QModelIndex, int, int )),
283 q, SLOT( slotChanged() ));
284 QObject::connect(
285 model, SIGNAL( dataChanged( QModelIndex, QModelIndex )),
286 q, SLOT( slotChanged() ));
288 // reconnect the signals
289 QObject::connect(
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)
306 return false;
308 // Save the current Item
309 saveCurrentItem();
311 return true;
315 void KCMGesturesPrivate::save()
317 if ( current && current->isChanged() )
319 saveCurrentItem();
322 // Write the settings
323 model->save();
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();
332 if (err.isValid())
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();
339 if (err.isValid())
341 kError() << err.name() << ":" << err.message();
344 if ( reply.isValid() )
346 if ( reply.value() )
347 KMessageBox::error(q, "<qt>" + i18n("Started server <em>org.kde.khotkeys</em>.") + "</qt>");
348 else
349 KMessageBox::error(q, "<qt>" + i18n("Unable to start server <em>org.kde.khotkeys</em>.") + "</qt>");
351 else
353 KMessageBox::error(
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" );
362 else
364 kDebug() << "Pinging khotkeys demon";
365 QDBusMessage reply = iface->call("reread_configuration");
366 QDBusError err = iface->lastError();
367 if (err.isValid())
369 kError() << err.name() << ":" << err.message();
376 void KCMGesturesPrivate::saveCurrentItem()
378 Q_ASSERT( current );
379 // Only save when really changed
380 if (current->isChanged())
382 current->copyToObject();
383 model->emitChanged(current->data());
384 save();
389 #include "moc_kcm_gestures.cpp"