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/action_data_group.h"
30 #include <KDE/KLocale>
33 static KHotKeys::ActionDataBase
*findElement(
35 ,KHotKeys::ActionDataGroup
*root
)
38 if (!root
) return NULL
;
40 KHotKeys::ActionDataBase
*match
= NULL
;
42 Q_FOREACH( KHotKeys::ActionDataBase
*element
, root
->children())
50 if (KHotKeys::ActionDataGroup
*subGroup
= dynamic_cast<KHotKeys::ActionDataGroup
*>(element
))
52 match
= findElement(ptr
, subGroup
);
62 KHotkeysModel::KHotkeysModel( QObject
*parent
)
63 : QAbstractItemModel(parent
)
69 KHotkeysModel::~KHotkeysModel()
74 QModelIndex
KHotkeysModel::addGroup( const QModelIndex
& parent
)
76 KHotKeys::ActionDataGroup
*list
;
79 list
= indexToActionDataGroup(parent
);
87 beginInsertRows( parent
, list
->size(), list
->size() );
89 /* KHotKeys:: ActionDataGroup *action = */
90 new KHotKeys::ActionDataGroup( list
, i18n("New Group"), i18n("Comment"));
93 return index( list
->size()-1, NameColumn
, parent
);
98 QModelIndex
KHotkeysModel::insertActionData( KHotKeys::ActionDataBase
*data
, const QModelIndex
& parent
)
102 KHotKeys::ActionDataGroup
*list
;
103 if (parent
.isValid())
105 list
= indexToActionDataGroup(parent
);
113 beginInsertRows( parent
, list
->size(), list
->size() );
115 data
->reparent(list
);
118 return index( list
->size()-1, NameColumn
, parent
);
122 int KHotkeysModel::columnCount( const QModelIndex
& ) const
128 QVariant
KHotkeysModel::data( const QModelIndex
&index
, int role
) const
130 // Check that the index is valid
131 if (!index
.isValid())
136 // Get the item behind the index
137 KHotKeys::ActionDataBase
*action
= indexToActionDataBase(index
);
140 // Handle CheckStateRole
141 if (role
==Qt::CheckStateRole
)
143 switch(index
.column())
146 // If the parent is enabled we display the state of the object.
147 // If the parent is disabled this object is disabled too.
148 if (action
->parent() && !action
->parent()->enabled())
150 return Qt::Unchecked
;
152 return action
->enabled()
161 // Display and Tooltip. Tooltip displays the complete name. That's nice if
162 // there is not enough space
163 if (role
==Qt::DisplayRole
|| role
==Qt::ToolTipRole
)
165 switch (index
.column())
168 return action
->name();
174 return indexToActionDataGroup(index
)!=0;
178 const std::type_info
&ti
= typeid(*action
);
179 if (ti
==typeid(KHotKeys::SimpleActionData
))
180 return KHotkeysModel::SimpleActionData
;
181 else if (ti
==typeid(KHotKeys::ActionDataGroup
))
182 return KHotkeysModel::ActionDataGroup
;
184 return KHotkeysModel::Other
;
193 if (role
==Qt::DecorationRole
)
195 switch (index
.column())
198 return dynamic_cast<KHotKeys::ActionDataGroup
*>(action
)
208 // For everything else
213 bool KHotkeysModel::dropMimeData(
214 const QMimeData
*data
215 ,Qt::DropAction action
218 ,const QModelIndex
&parent
)
221 << parent
.data(Qt::DisplayRole
) << ","
225 // We only support move actions and our own mime type
226 if ( (action
!=Qt::CopyAction
)
227 || !data
->hasFormat("application/x-pointer"))
229 kDebug() << "Drop not supported " << data
->formats();
234 QByteArray encodedData
= data
->data("application/x-pointer");
235 QDataStream
stream(&encodedData
, QIODevice::ReadOnly
);
236 QList
<quintptr
> ptrs
;
237 while (!stream
.atEnd())
244 // No pointers, nothing to do
245 if (ptrs
.empty()) return false;
247 // Get the group we have to drop into
248 QModelIndex dropIndex
= parent
;
249 KHotKeys::ActionDataGroup
*dropToGroup
= indexToActionDataGroup(dropIndex
);
252 dropIndex
= parent
.parent();
253 dropToGroup
= indexToActionDataGroup(dropIndex
);
256 kDebug() << "dropping to " << dropToGroup
->name();
259 Q_FOREACH(quintptr ptr
, ptrs
)
261 KHotKeys::ActionDataBase
*element
= findElement(
262 reinterpret_cast<void*>(ptr
),
265 if (element
) moveElement(element
, dropToGroup
);
272 void KHotkeysModel::emitChanged(KHotKeys::ActionDataBase
*item
)
276 KHotKeys::ActionDataGroup
*parent
= item
->parent();
278 QModelIndex bottomRight
;
281 topLeft
= createIndex( 0, 0, _actions
);
282 bottomRight
= createIndex( 0, 0, _actions
);
286 int row
= parent
->children().indexOf(item
);
287 topLeft
= createIndex( row
, 0, parent
);
288 bottomRight
= createIndex( row
, columnCount(topLeft
), parent
);
291 emit
dataChanged( topLeft
, bottomRight
);
295 Qt::ItemFlags
KHotkeysModel::flags( const QModelIndex
&index
) const
297 Qt::ItemFlags flags
= QAbstractItemModel::flags(index
);
299 if (!index
.isValid())
301 return flags
| Qt::ItemIsDropEnabled
;
304 switch (index
.column())
308 | Qt::ItemIsUserCheckable
309 | Qt::ItemIsDragEnabled
310 | Qt::ItemIsDropEnabled
;
315 | Qt::ItemIsDragEnabled
316 | Qt::ItemIsDropEnabled
;
321 // Get header data for section
322 QVariant
KHotkeysModel::headerData( int section
, Qt::Orientation
, int role
) const
324 if (role
!=Qt::DisplayRole
)
332 return QVariant(i18n("Name"));
335 return QVariant(i18n("Enabled"));
338 return QVariant(i18n("Type"));
346 QModelIndex
KHotkeysModel::index( int row
, int column
, const QModelIndex
&parent
) const
348 KHotKeys::ActionDataGroup
*actionGroup
= indexToActionDataGroup(parent
);
349 if (!actionGroup
|| row
>=actionGroup
->children().size() )
351 return QModelIndex();
354 KHotKeys::ActionDataBase
*action
= actionGroup
->children().at(row
);
356 return createIndex( row
, column
, action
);
360 // Convert index to ActionDataBase
361 KHotKeys::ActionDataBase
*KHotkeysModel::indexToActionDataBase( const QModelIndex
&index
) const
363 if (!index
.isValid())
367 return static_cast<KHotKeys::ActionDataBase
*>( index
.internalPointer() );
371 // Convert index to ActionDataGroup
372 KHotKeys::ActionDataGroup
*KHotkeysModel::indexToActionDataGroup( const QModelIndex
&index
) const
374 if (!index
.isValid())
378 return dynamic_cast<KHotKeys::ActionDataGroup
*>( indexToActionDataBase(index
) );
382 void KHotkeysModel::load()
384 _settings
.read_settings(true);
385 _actions
= _settings
.actions();
390 QMimeData
*KHotkeysModel::mimeData(const QModelIndexList
&indexes
) const
392 QMimeData
* mimeData
= new QMimeData();
393 QByteArray encodedData
;
395 QDataStream
stream(&encodedData
, QIODevice::WriteOnly
);
397 Q_FOREACH (QModelIndex index
, indexes
)
399 if (index
.isValid() and index
.column() == 0)
401 KHotKeys::ActionDataBase
*element
= indexToActionDataBase(index
);
402 // We use the pointer as id.
403 stream
<< reinterpret_cast<quintptr
>(element
);
407 mimeData
->setData("application/x-pointer", encodedData
);
412 QStringList
KHotkeysModel::mimeTypes() const
415 types
<< "application/x-pointer";
420 bool KHotkeysModel::moveElement(
421 KHotKeys::ActionDataBase
*element
422 ,KHotKeys::ActionDataGroup
*newGroup
425 Q_ASSERT(element
&& newGroup
);
426 if (!element
|| !newGroup
) return false;
428 // TODO: Make this logic more advanced
429 // We do not allow moving into our systemgroup
430 if (newGroup
->is_system_group()) return false;
432 // Make sure we don't move a group to one of it's children or
434 KHotKeys::ActionDataGroup
*tmp
= newGroup
;
438 kDebug() << "Forbidden move" << tmp
->name();
442 while((tmp
= tmp
->parent()));
444 KHotKeys::ActionDataGroup
*oldParent
= element
->parent();
446 // TODO: Make this logic more advanced
447 // We do not allow moving from our systemgroup
448 if (oldParent
->is_system_group()) return false;
450 // Remove it from it's current place
451 kDebug() << "Removing from";
452 kDebug() << KHotkeysModel::data(createIndex(0, 0, oldParent
), Qt::DisplayRole
);
453 kDebug() << "item " << oldParent
->children().indexOf(element
);
454 kDebug() << "from " << oldParent
->children().size();
456 createIndex(0, 0, oldParent
),
457 oldParent
->children().indexOf(element
),
458 oldParent
->children().indexOf(element
));
459 element
->reparent(0);
463 kDebug() << "Adding to";
464 kDebug() << KHotkeysModel::data(createIndex(0, 0, newGroup
), Qt::DisplayRole
);
465 kDebug() << "from " << newGroup
->children().size();
467 createIndex(0, 0, newGroup
),
468 newGroup
->children().size(),
469 newGroup
->children().size());
470 element
->reparent(newGroup
);
477 // Get parent object for index
478 QModelIndex
KHotkeysModel::parent( const QModelIndex
&index
) const
480 KHotKeys::ActionDataBase
*action
= indexToActionDataBase(index
);
483 return QModelIndex();
486 KHotKeys::ActionDataGroup
*parent
= action
->parent();
489 return QModelIndex();
492 KHotKeys::ActionDataGroup
*grandparent
= parent
->parent();
495 return QModelIndex();
498 int row
= grandparent
->children().indexOf(parent
);
499 return createIndex( row
, 0, parent
);
503 // Remove rows ( items )
504 bool KHotkeysModel::removeRows( int row
, int count
, const QModelIndex
&parent
)
506 Q_ASSERT( count
== 1 );
508 beginRemoveRows( parent
, row
, row
+count
-1 );
510 KHotKeys::ActionDataGroup
*list
;
511 if (parent
.isValid())
513 list
= indexToActionDataGroup(parent
);
521 KHotKeys::ActionDataBase
*action
= indexToActionDataBase(index(row
,0,parent
));
523 action
->aboutToBeErased();
531 // Number of rows for index
532 int KHotkeysModel::rowCount( const QModelIndex
&index
) const
534 KHotKeys::ActionDataGroup
*group
= indexToActionDataGroup(index
);
540 return group
->children().count();
544 void KHotkeysModel::save()
546 _settings
.write_settings();
551 bool KHotkeysModel::setData( const QModelIndex
&index
, const QVariant
&value
, int role
)
554 if ( !index
.isValid() || role
!= Qt::EditRole
)
559 KHotKeys::ActionDataBase
*action
= indexToActionDataBase(index
);
562 switch ( index
.column() )
566 action
->set_name( value
.toString() );
574 emit
dataChanged( index
, index
);
578 #include "moc_hotkeys_model.cpp"