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 "hotkeys_model.h"
22
#include "action_data/simple_action_data.h"
23
#include "action_data/menuentry_shortcut_action_data.h"
24
#include "action_data/action_data_group.h"
31
#include <KDE/KLocale>
35
static KHotKeys::ActionDataBase *findElement(
37
,KHotKeys::ActionDataGroup *root)
40
if (!root) return NULL;
42
KHotKeys::ActionDataBase *match = NULL;
44
Q_FOREACH( KHotKeys::ActionDataBase *element, root->children())
52
if (KHotKeys::ActionDataGroup *subGroup = dynamic_cast<KHotKeys::ActionDataGroup*>(element))
54
match = findElement(ptr, subGroup);
64
KHotkeysModel::KHotkeysModel( QObject *parent )
65
: QAbstractItemModel(parent)
71
KHotkeysModel::~KHotkeysModel()
76
QModelIndex KHotkeysModel::addGroup( const QModelIndex & parent )
78
KHotKeys::ActionDataGroup *list;
81
list = indexToActionDataGroup(parent);
89
beginInsertRows( parent, list->size(), list->size() );
91
/* KHotKeys:: ActionDataGroup *action = */
92
new KHotKeys::ActionDataGroup( list, i18n("New Group"), i18n("Comment"));
95
return index( list->size()-1, NameColumn, parent );
100
QModelIndex KHotkeysModel::insertActionData( KHotKeys::ActionDataBase *data, const QModelIndex & parent )
104
KHotKeys::ActionDataGroup *list;
105
if (parent.isValid())
107
list = indexToActionDataGroup(parent);
115
beginInsertRows( parent, list->size(), list->size() );
117
list->add_child(data);
120
return index( list->size()-1, NameColumn, parent );
124
int KHotkeysModel::columnCount( const QModelIndex & ) const
130
QVariant KHotkeysModel::data( const QModelIndex &index, int role ) const
132
// Check that the index is valid
133
if (!index.isValid())
138
// Get the item behind the index
139
KHotKeys::ActionDataBase *action = indexToActionDataBase(index);
142
// Handle CheckStateRole
143
if (role==Qt::CheckStateRole)
145
switch(index.column())
148
// If the parent is enabled we display the state of the object.
149
// If the parent is disabled this object is disabled too.
150
if (action->parent() && !action->parent()->isEnabled())
152
return Qt::Unchecked;
154
return action->isEnabled()
163
// Display and Tooltip. Tooltip displays the complete name. That's nice if
164
// there is not enough space
165
else if (role==Qt::DisplayRole || role==Qt::ToolTipRole)
167
switch (index.column())
170
return action->name();
176
return indexToActionDataGroup(index)!=0;
180
const std::type_info &ti = typeid(*action);
181
if (ti==typeid(KHotKeys::SimpleActionData))
182
return KHotkeysModel::SimpleActionData;
183
else if (ti==typeid(KHotKeys::MenuEntryShortcutActionData))
184
return KHotkeysModel::SimpleActionData;
185
else if (ti==typeid(KHotKeys::ActionDataGroup))
186
return KHotkeysModel::ActionDataGroup;
188
return KHotkeysModel::Other;
197
else if (role==Qt::DecorationRole)
199
switch (index.column())
201
// The 0 is correct here. We want to decorate that column
202
// regardless of the content it has
204
return dynamic_cast<KHotKeys::ActionDataGroup*>(action)
213
//Providing the current action name on edit
214
else if (role==Qt::EditRole)
216
switch (index.column())
219
return action->name();
226
else if (role==Qt::ForegroundRole)
229
switch (index.column())
232
if (!action->isEnabled())
234
return pal.color(QPalette::Disabled, QPalette::Foreground);
242
// For everything else
247
bool KHotkeysModel::dropMimeData(
248
const QMimeData *data
249
,Qt::DropAction action
252
,const QModelIndex &parent)
256
// We only support move actions and our own mime type
257
if ( (action!=Qt::CopyAction)
258
|| !data->hasFormat("application/x-pointer"))
260
kDebug() << "Drop not supported " << data->formats();
265
QByteArray encodedData = data->data("application/x-pointer");
266
QDataStream stream(&encodedData, QIODevice::ReadOnly);
267
QList<quintptr> ptrs;
268
while (!stream.atEnd())
275
// No pointers, nothing to do
276
if (ptrs.empty()) return false;
278
// Get the group we have to drop into. If the drop target is no group get
279
// it's parent and drop behind it
281
QModelIndex dropIndex = parent;
282
KHotKeys::ActionDataGroup *dropToGroup = indexToActionDataGroup(dropIndex);
285
dropIndex = parent.parent();
286
dropToGroup = indexToActionDataGroup(dropIndex);
287
position = dropToGroup->children().indexOf(indexToActionDataBase(parent));
292
position = dropToGroup->size();
296
Q_FOREACH(quintptr ptr, ptrs)
298
KHotKeys::ActionDataBase *element = findElement(
299
reinterpret_cast<void*>(ptr),
302
if (element) moveElement(element, dropToGroup, position);
309
void KHotkeysModel::emitChanged(KHotKeys::ActionDataBase *item)
313
KHotKeys::ActionDataGroup *parent = item->parent();
315
QModelIndex bottomRight;
318
topLeft = createIndex( 0, 0, _actions );
319
bottomRight = createIndex( 0, 0, _actions );
323
int row = parent->children().indexOf(item);
324
topLeft = createIndex( row, 0, parent );
325
bottomRight = createIndex( row, columnCount(topLeft), parent );
328
emit dataChanged( topLeft, bottomRight );
332
void KHotkeysModel::exportInputActions(
333
const QModelIndex &index,
336
const KHotKeys::ActionState state,
339
KHotKeys::ActionDataBase *element = indexToActionDataBase(index);
340
KHotKeys::ActionDataGroup *group = indexToActionDataGroup(index);
342
settings()->exportTo(
343
group ? group : element->parent(),
351
Qt::ItemFlags KHotkeysModel::flags( const QModelIndex &index ) const
353
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
355
Q_ASSERT(!(flags & Qt::ItemIsDropEnabled));
356
Q_ASSERT(!(flags & Qt::ItemIsDragEnabled));
358
if (!index.isValid())
360
return flags | Qt::ItemIsDropEnabled;
363
KHotKeys::ActionDataBase *element = indexToActionDataBase(index);
364
KHotKeys::ActionDataGroup *actionGroup = indexToActionDataGroup(index);
365
if (!actionGroup) actionGroup = element->parent();
368
Q_ASSERT(actionGroup);
370
// We do not allow dragging for system groups and their elements
371
// We do not allow dropping into systemgroups
372
if (!actionGroup->is_system_group())
374
flags |= Qt::ItemIsDragEnabled;
375
flags |= Qt::ItemIsDropEnabled;
378
// Show a checkbox in column 1 whatever is shown there.
379
switch (index.column())
383
| Qt::ItemIsUserCheckable;
387
| Qt::ItemIsEditable;
392
// Get header data for section
393
QVariant KHotkeysModel::headerData( int section, Qt::Orientation, int role ) const
395
if (role!=Qt::DisplayRole)
403
return QVariant(i18nc("action name", "Name"));
407
return QVariant(i18nc("action enabled", "Enabled"));
410
return QVariant(i18n("Type"));
418
void KHotkeysModel::importInputActions(const QModelIndex &index, KConfigBase const &config)
420
KHotKeys::ActionDataGroup *group = indexToActionDataGroup(index);
421
QModelIndex groupIndex = index;
424
group = indexToActionDataBase(index)->parent();
425
groupIndex = index.parent();
428
if (settings()->importFrom(group, config, KHotKeys::ImportAsk, KHotKeys::Retain))
437
QModelIndex KHotkeysModel::index( int row, int column, const QModelIndex &parent ) const
439
KHotKeys::ActionDataGroup *actionGroup = indexToActionDataGroup(parent);
440
if (!actionGroup || row>=actionGroup->children().size() )
442
return QModelIndex();
445
KHotKeys::ActionDataBase *action = actionGroup->children().at(row);
447
return createIndex( row, column, action );
451
// Convert index to ActionDataBase
452
KHotKeys::ActionDataBase *KHotkeysModel::indexToActionDataBase( const QModelIndex &index ) const
454
if (!index.isValid())
458
return static_cast<KHotKeys::ActionDataBase*>( index.internalPointer() );
462
// Convert index to ActionDataGroup
463
KHotKeys::ActionDataGroup *KHotkeysModel::indexToActionDataGroup( const QModelIndex &index ) const
465
if (!index.isValid())
469
return dynamic_cast<KHotKeys::ActionDataGroup*>( indexToActionDataBase(index) );
473
void KHotkeysModel::load()
475
_settings.reread_settings(true);
476
_actions = _settings.actions();
481
QMimeData *KHotkeysModel::mimeData(const QModelIndexList &indexes) const
483
QMimeData * mimeData = new QMimeData();
484
QByteArray encodedData;
486
QDataStream stream(&encodedData, QIODevice::WriteOnly);
488
Q_FOREACH (const QModelIndex &index, indexes)
490
if (index.isValid() and index.column() == 0)
492
KHotKeys::ActionDataBase *element = indexToActionDataBase(index);
493
// We use the pointer as id.
494
stream << reinterpret_cast<quintptr>(element);
498
mimeData->setData("application/x-pointer", encodedData);
503
QStringList KHotkeysModel::mimeTypes() const
506
types << "application/x-pointer";
511
bool KHotkeysModel::moveElement(
512
KHotKeys::ActionDataBase *element
513
,KHotKeys::ActionDataGroup *newGroup
516
Q_ASSERT(element && newGroup);
517
if (!element || !newGroup) return false;
519
// TODO: Make this logic more advanced
520
// We do not allow moving into our systemgroup
521
if (newGroup->is_system_group()) return false;
523
// Make sure we don't move a group to one of it's children or
525
KHotKeys::ActionDataGroup *tmp = newGroup;
529
kDebug() << "Forbidden move" << tmp->name();
533
while((tmp = tmp->parent()));
535
KHotKeys::ActionDataGroup *oldParent = element->parent();
537
// TODO: Make this logic more advanced
538
// We do not allow moving from our systemgroup
539
if (oldParent->is_system_group()) return false;
541
// Adjust position if oldParent and newGroup are identical
542
if (oldParent == newGroup)
544
if (oldParent->children().indexOf(element) < position)
550
emit layoutAboutToBeChanged();
552
// Remove it from it's current place
553
oldParent->remove_child(element);
554
newGroup->add_child(element, position);
556
emit layoutChanged();
562
// Get parent object for index
563
QModelIndex KHotkeysModel::parent( const QModelIndex &index ) const
565
KHotKeys::ActionDataBase *action = indexToActionDataBase(index);
568
return QModelIndex();
571
KHotKeys::ActionDataGroup *parent = action->parent();
574
return QModelIndex();
577
KHotKeys::ActionDataGroup *grandparent = parent->parent();
580
return QModelIndex();
583
int row = grandparent->children().indexOf(parent);
584
return createIndex( row, 0, parent );
588
// Remove rows ( items )
589
bool KHotkeysModel::removeRows( int row, int count, const QModelIndex &parent )
591
Q_ASSERT( count == 1 );
593
beginRemoveRows( parent, row, row+count-1 );
595
KHotKeys::ActionDataGroup *list;
596
if (parent.isValid())
598
list = indexToActionDataGroup(parent);
606
KHotKeys::ActionDataBase *action = indexToActionDataBase(index(row,0,parent));
608
action->aboutToBeErased();
616
// Number of rows for index
617
int KHotkeysModel::rowCount( const QModelIndex &index ) const
619
KHotKeys::ActionDataGroup *group = indexToActionDataGroup(index);
625
return group->children().count();
629
void KHotkeysModel::save()
636
bool KHotkeysModel::setData( const QModelIndex &index, const QVariant &value, int role )
639
if ( !index.isValid() )
644
KHotKeys::ActionDataBase *action = indexToActionDataBase(index);
647
// Handle CheckStateRole
648
if ( role == Qt::CheckStateRole )
650
switch(index.column())
654
// If the parent is enabled we display the state of the object.
655
// If the parent is disabled this object is disabled too.
656
if (action->parent() && !action->parent()->isEnabled())
658
// TODO: Either show a message box or enhance the gui to
659
// show this item cannot be enabled
663
value.toInt() == Qt::Checked
667
// If this is a group we have to inform the view that all our
668
// childs have changed. They are all disabled now
669
KHotKeys::ActionDataGroup *actionGroup = indexToActionDataGroup(index);
670
if (actionGroup && actionGroup->size())
673
createIndex(0, 0, actionGroup),
674
createIndex(actionGroup->size(), columnCount(index), actionGroup));
683
else if ( role == Qt::EditRole )
685
switch ( index.column() )
689
action->set_name( value.toString() );
700
emit dataChanged( index, index );
705
KHotKeys::Settings *KHotkeysModel::settings()
711
#include "moc_hotkeys_model.cpp"