• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

Kross

model.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  * model.cpp
00003  * This file is part of the KDE project
00004  * copyright (C) 2006-2007 by Sebastian Sauer (mail@dipe.org)
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  * You should have received a copy of the GNU Library General Public License
00015  * along with this program; see the file COPYING.  If not, write to
00016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018  ***************************************************************************/
00019 
00020 #include "model.h"
00021 
00022 #include <kross/core/action.h>
00023 #include <kross/core/actioncollection.h>
00024 #include <kross/core/manager.h>
00025 
00026 #include <QtCore/QEvent>
00027 #include <QtCore/QMimeData>
00028 
00029 using namespace Kross;
00030 
00031 /******************************************************************************
00032  * ActionCollectionModel
00033  */
00034 
00035 namespace Kross {
00036 
00038     class ActionCollectionModelItem : public QObject
00039     {
00040         public:
00041             enum Type { ActionType, CollectionType };
00042             const Type type;
00043             union {
00044                 Action* action;
00045                 ActionCollection* collection;
00046             };
00047             QVector<ActionCollectionModelItem*> children;
00048             const QModelIndex parent;
00049 
00050             QString name() const { return type == ActionType ? action->name() : collection->name(); }
00051 
00052             explicit ActionCollectionModelItem(Action* a, const QModelIndex& p = QModelIndex(), ActionCollectionModelItem* parentitem = 0)
00053                 : QObject(parentitem), type(ActionType), action(a), parent(p)
00054             {
00055             }
00056 
00057             explicit ActionCollectionModelItem(ActionCollection* c, const QModelIndex& p = QModelIndex(), ActionCollectionModelItem* parentitem = 0)
00058                 : QObject(parentitem), type(CollectionType), collection(c), parent(p)
00059             {
00060             }
00061     };
00062 
00064     class ActionCollectionModel::Private
00065     {
00066         public:
00067             ActionCollection* collection;
00068             ActionCollectionModelItem* item;
00069             Mode mode;
00070 
00071             template <class T>
00072             ActionCollectionModelItem* childItem( ActionCollectionModelItem* item,
00073                                                   const QModelIndex& parent,
00074                                                   int row,
00075                                                   int column,
00076                                                   T value );
00077     };
00078 
00079 }
00080 
00081 template <class T>
00082 ActionCollectionModelItem* ActionCollectionModel::Private::childItem(
00083     ActionCollectionModelItem* item,
00084     const QModelIndex& parent,
00085     int row,
00086     int column,
00087     T value )
00088 {
00089     Q_UNUSED(column);
00090     ActionCollectionModelItem* childItem = 0;
00091     if ( row < item->children.count() && item->children.at(row) != 0 ) {
00092         childItem = item->children.at(row);
00093     }
00094     else {
00095         childItem = new ActionCollectionModelItem(value,parent,item);
00096         item->children.resize(row+1);
00097         item->children[row] = childItem;
00098     }
00099     return childItem;
00100 }
00101 
00102 ActionCollectionModel::ActionCollectionModel(QObject* parent, ActionCollection* collection, Mode mode)
00103     : QAbstractItemModel(parent)
00104     , d( new Private() )
00105 {
00106     d->collection = collection ? collection : Kross::Manager::self().actionCollection();
00107     //d->item = 0;
00108     d->item = new ActionCollectionModelItem( d->collection );
00109     d->mode = mode;
00110     //setSupportedDragActions(Qt::MoveAction);
00111     QObject::connect(d->collection, SIGNAL(updated()), this, SLOT(slotUpdated()));
00112 }
00113 
00114 ActionCollectionModel::~ActionCollectionModel()
00115 {
00116     delete d->item;
00117     delete d;
00118 }
00119 
00120 void ActionCollectionModel::slotUpdated()
00121 {
00122     emit layoutAboutToBeChanged();
00123     emit layoutChanged();
00124 }
00125 
00126 Action* ActionCollectionModel::action(const QModelIndex& index)
00127 {
00128     ActionCollectionModelItem* item = index.isValid() ? static_cast<ActionCollectionModelItem*>(index.internalPointer()) : 0;
00129     return (item && item->type == ActionCollectionModelItem::ActionType) ? item->action : 0;
00130 }
00131 
00132 ActionCollection* ActionCollectionModel::collection(const QModelIndex& index)
00133 {
00134     ActionCollectionModelItem* item = index.isValid() ? static_cast<ActionCollectionModelItem*>(index.internalPointer()) : 0;
00135     return (item && item->type == ActionCollectionModelItem::CollectionType) ? item->collection : 0;
00136 }
00137 
00138 int ActionCollectionModel::columnCount(const QModelIndex&) const
00139 {
00140     return 1;
00141 }
00142 
00143 int ActionCollectionModel::rowCount(const QModelIndex& index) const
00144 {
00145     ActionCollectionModelItem* item = index.isValid() ? static_cast<ActionCollectionModelItem*>(index.internalPointer()) : d->item;
00146     Q_ASSERT( item );
00147     if( item->type == ActionCollectionModelItem::CollectionType )
00148         return item->collection->actions().count() + item->collection->collections().count();
00149     return 0;
00150 }
00151 
00152 QModelIndex ActionCollectionModel::index(int row, int column, const QModelIndex& parent) const
00153 {
00154     ActionCollectionModelItem* item = parent.isValid() ? static_cast<ActionCollectionModelItem*>(parent.internalPointer()) : d->item;
00155     Q_ASSERT( item && item->type == ActionCollectionModelItem::CollectionType );
00156     const int count = item->collection->actions().count();
00157     if( row < count ) {
00158         Action* action = dynamic_cast< Action* >( item->collection->actions().value(row) );
00159         if( action )
00160         {
00161             return createIndex(row, column,d->childItem(item,parent,row,column,action));
00162         }
00163     }
00164     else {
00165         QString name = item->collection->collections().value(row - count);
00166         ActionCollection* collection = item->collection->collection(name);
00167         if( collection )
00168         {
00169             return createIndex(row, column,d->childItem(item,parent,row,column,collection));
00170         }
00171     }
00172     return QModelIndex();
00173 }
00174 
00175 QModelIndex ActionCollectionModel::parent(const QModelIndex& index) const
00176 {
00177     if( ! index.isValid() )
00178         return QModelIndex();
00179     return static_cast<ActionCollectionModelItem*>(index.internalPointer())->parent;
00180 }
00181 
00182 Qt::ItemFlags ActionCollectionModel::flags(const QModelIndex &index) const
00183 {
00184     Qt::ItemFlags flags = QAbstractItemModel::flags(index);
00185     if( ! index.isValid() )
00186         return Qt::ItemIsDropEnabled | flags;
00187 
00188     flags |= Qt::ItemIsSelectable;
00189     //flags |= Qt::ItemIsEditable;
00190     flags |= Qt::ItemIsDragEnabled;
00191     flags |= Qt::ItemIsDropEnabled;
00192 
00193     if( (index.column() == 0) && (d->mode & UserCheckable) )
00194         flags |= Qt::ItemIsUserCheckable;
00195     return flags;
00196 }
00197 
00198 QVariant ActionCollectionModel::data(const QModelIndex& index, int role) const
00199 {
00200     if( index.isValid() ) {
00201         ActionCollectionModelItem* item = static_cast<ActionCollectionModelItem*>(index.internalPointer());
00202         switch( item->type ) {
00203             case ActionCollectionModelItem::ActionType: {
00204                 switch( role ) {
00205                     case Qt::DecorationRole: {
00206                         if( d->mode & Icons )
00207                             if( ! item->action->iconName().isEmpty() )
00208                                 return item->action->icon();
00209                     } break;
00210                     case Qt::DisplayRole:
00211                         return item->action->text().remove("&");
00212                     case Qt::ToolTipRole: // fall through
00213                     case Qt::WhatsThisRole: {
00214                         if( d->mode & ToolTips ) {
00215                             const QString file = QFileInfo( item->action->file() ).fileName();
00216                             return QString("<qt><b>%1</b><br>%2</qt>")
00217                                 .arg( file.isEmpty() ? item->action->name() : file )
00218                                 .arg( item->action->description() );
00219                         }
00220                     } break;
00221                     case Qt::CheckStateRole: {
00222                         if( d->mode & UserCheckable )
00223                             return item->action->isEnabled();
00224                     } break;
00225                     default: break;
00226                 }
00227             } break;
00228             case ActionCollectionModelItem::CollectionType: {
00229                 switch( role ) {
00230                     case Qt::DecorationRole: {
00231                         if( d->mode & Icons )
00232                             if( ! item->collection->iconName().isEmpty() )
00233                                 return item->collection->icon();
00234                     } break;
00235                     case Qt::DisplayRole:
00236                         return item->collection->text();
00237                     case Qt::ToolTipRole: // fall through
00238                     case Qt::WhatsThisRole: {
00239                         if( d->mode & ToolTips )
00240                             return QString("<qt><b>%1</b><br>%2</qt>").arg(item->collection->text()).arg(item->collection->description());
00241                     } break;
00242                     case Qt::CheckStateRole: {
00243                         if( d->mode & UserCheckable )
00244                             return item->collection->isEnabled();
00245                     } break;
00246                     default: break;
00247                 }
00248             } break;
00249             default: break;
00250         }
00251     }
00252     return QVariant();
00253 }
00254 
00255 bool ActionCollectionModel::setData(const QModelIndex &index, const QVariant &value, int role)
00256 {
00257     Q_UNUSED(value);
00258     if( ! index.isValid() /*|| ! (d->mode & UserCheckable)*/ )
00259         return false;
00260     ActionCollectionModelItem* item = static_cast<ActionCollectionModelItem*>(index.internalPointer());
00261     switch( item->type ) {
00262         case ActionCollectionModelItem::ActionType: {
00263             switch( role ) {
00264                 //case Qt::EditRole: item->action->setText( value.toString() ); break;
00265                 case Qt::CheckStateRole: item->action->setEnabled( ! item->action->isEnabled() ); break;
00266                 default: return false;
00267             }
00268         } break;
00269         case ActionCollectionModelItem::CollectionType: {
00270             switch( role ) {
00271                 //case Qt::EditRole: item->collection->setText( value.toString() ); break;
00272                 case Qt::CheckStateRole: item->collection->setEnabled( ! item->collection->isEnabled() ); break;
00273                 default: return false;
00274             }
00275         } break;
00276         default: return false;
00277     }
00278     //emit dataChanged(index, index);
00279     return true;
00280 }
00281 
00282 bool ActionCollectionModel::insertRows(int row, int count, const QModelIndex& parent)
00283 {
00284     krossdebug( QString("ActionCollectionModel::insertRows: row=%1 count=%2").arg(row).arg(count) );
00285     if( ! parent.isValid() )
00286         return false;
00287 
00288     ActionCollectionModelItem* parentitem = static_cast<ActionCollectionModelItem*>(parent.internalPointer());
00289     switch( parentitem->type ) {
00290         case ActionCollectionModelItem::ActionType: {
00291             krossdebug( QString("ActionCollectionModel::insertRows: parentindex is Action with name=%1").arg(parentitem->action->name()) );
00292         } break;
00293         case ActionCollectionModelItem::CollectionType: {
00294             krossdebug( QString("ActionCollectionModel::insertRows: parentindex is ActionCollection with name=%1").arg(parentitem->collection->name()) );
00295         } break;
00296         default: break;
00297     }
00298 
00299     return QAbstractItemModel::insertRows(row, count, parent);
00300 }
00301 
00302 bool ActionCollectionModel::removeRows(int row, int count, const QModelIndex& parent)
00303 {
00304     krossdebug( QString("ActionCollectionModel::removeRows: row=%1 count=%2").arg(row).arg(count) );
00305     return QAbstractItemModel::removeRows(row, count, parent);
00306 }
00307 
00308 bool ActionCollectionModel::insertColumns(int column, int count, const QModelIndex& parent)
00309 {
00310     krossdebug( QString("ActionCollectionModel::insertColumns: column=%1 count=%2").arg(column).arg(count) );
00311     return QAbstractItemModel::insertColumns(column, count, parent);
00312 }
00313 
00314 bool ActionCollectionModel::removeColumns(int column, int count, const QModelIndex& parent)
00315 {
00316     krossdebug( QString("ActionCollectionModel::removeColumns: column=%1 count=%2").arg(column).arg(count) );
00317     return QAbstractItemModel::removeColumns(column, count, parent);
00318 }
00319 
00320 QStringList ActionCollectionModel::mimeTypes() const
00321 {
00322     //krossdebug( QString("ActionCollectionModel::mimeTypes") );
00323     return QStringList() << "application/vnd.text.list";
00324 }
00325 
00326 QString fullPath(const QModelIndex& index)
00327 {
00328     if( ! index.isValid() ) return QString();
00329     ActionCollectionModelItem* item = static_cast<ActionCollectionModelItem*>(index.internalPointer());
00330     QString n = item->name();
00331     if( item->type == ActionCollectionModelItem::CollectionType ) n += '/';
00332     QString p = fullPath( item->parent ); //recursive
00333     return p.isNull() ? n : ( p.endsWith('/') ? p + n : p + '/' + n );
00334 }
00335 
00336 QMimeData* ActionCollectionModel::mimeData(const QModelIndexList& indexes) const
00337 {
00338     //krossdebug( QString("ActionCollectionModel::mimeData") );
00339     QMimeData* mimeData = new QMimeData();
00340     QByteArray encodedData;
00341 
00342     QDataStream stream(&encodedData, QIODevice::WriteOnly);
00343     foreach(const QModelIndex &index, indexes) {
00344         //if( ! index.isValid() ) continue;
00345         //QString text = data(index, Qt::DisplayRole).toString();
00346         QString path = fullPath(index);
00347         if( ! path.isNull() )
00348             stream << path;
00349     }
00350 
00351     mimeData->setData("application/vnd.text.list", encodedData);
00352     return mimeData;
00353 }
00354 
00355 bool ActionCollectionModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent)
00356 {
00357     krossdebug( QString("ActionCollectionModel::dropMimeData: row=%1 col=%2").arg(row).arg(column) );
00358     if( action == Qt::IgnoreAction ) return true;
00359     if( ! data->hasFormat("application/vnd.text.list") ) return false;
00360     if( column > 0 ) return false;
00361 
00362     krossdebug( QString("ActionCollectionModel::dropMimeData: ENCODED DATA:") );
00363     QByteArray encodedData = data->data("application/vnd.text.list");
00364     QDataStream stream(&encodedData, QIODevice::ReadOnly);
00365     QStringList newItems;
00366     int rows = 0;
00367     while( ! stream.atEnd() ) {
00368         QString text;
00369         stream >> text;
00370         newItems << text;
00371         krossdebug( QString("  %1 \"%2\"").arg(rows).arg(text) );
00372         ++rows;
00373     }
00374 
00375     //FIXME: return false for now since insertRows/removeRows need to be implemented before!
00376     //return false;
00377 
00378     /*
00379     int beginRow;
00380     if( row != -1 )
00381         beginRow = row;
00382     else if( parent.isValid() )
00383         beginRow = parent.row();
00384     else
00385         beginRow = rowCount( QModelIndex() );
00386     krossdebug( QString("ActionCollectionModel::dropMimeData: beginRow=%1").arg(beginRow) );
00387     */
00388 
00389     ActionCollectionModelItem* targetparentitem = parent.isValid() ? static_cast<ActionCollectionModelItem*>(parent.internalPointer()) : d->item;
00390     switch( targetparentitem->type ) {
00391         case ActionCollectionModelItem::ActionType: {
00392             krossdebug( QString("ActionCollectionModel::dropMimeData: parentindex is Action with name=%1").arg(targetparentitem->action->name()) );
00393         } break;
00394         case ActionCollectionModelItem::CollectionType: {
00395             krossdebug( QString("ActionCollectionModel::dropMimeData: parentindex is ActionCollection with name=%1").arg(targetparentitem->collection->name()) );
00396         } break;
00397         default: break;
00398     }
00399 
00400 
00401 
00402     return false;
00403     //return QAbstractItemModel::dropMimeData(data, action, row, column, parent);
00404 }
00405 
00406 Qt::DropActions ActionCollectionModel::supportedDropActions() const
00407 {
00408     return Qt::CopyAction | Qt::MoveAction | Qt::TargetMoveAction;
00409     //return Qt::CopyAction | Qt::MoveAction | Qt::TargetMoveAction | Qt::LinkAction;
00410 }
00411 
00412 /******************************************************************************
00413  * ActionCollectionProxyModel
00414  */
00415 
00416 ActionCollectionProxyModel::ActionCollectionProxyModel(QObject* parent, ActionCollectionModel* model)
00417     : QSortFilterProxyModel(parent)
00418 {
00419     setSourceModel( model ? model : new ActionCollectionModel(this) );
00420     setFilterCaseSensitivity(Qt::CaseInsensitive);
00421 }
00422 
00423 ActionCollectionProxyModel::~ActionCollectionProxyModel()
00424 {
00425 }
00426 
00427 void ActionCollectionProxyModel::setSourceModel(QAbstractItemModel* sourceModel)
00428 {
00429     Q_ASSERT( dynamic_cast< ActionCollectionModel* >(sourceModel) );
00430     QSortFilterProxyModel::setSourceModel(sourceModel);
00431 }
00432 
00433 bool ActionCollectionProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
00434 {
00435     QModelIndex index = sourceModel()->index(source_row, 0, source_parent);
00436     if( ! index.isValid() )
00437         return false;
00438     ActionCollectionModelItem* item = static_cast<ActionCollectionModelItem*>(index.internalPointer());
00439     switch( item->type ) {
00440             case ActionCollectionModelItem::ActionType: {
00441                 if( ! item->action->isEnabled() )
00442                     return false;
00443                 return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
00444             } break;
00445             case ActionCollectionModelItem::CollectionType: {
00446                 if( ! item->collection->isEnabled() )
00447                     return false;
00448             } break;
00449             default: break;
00450     }
00451     return true;
00452 }
00453 
00454 #include "model.moc"

Kross

Skip menu "Kross"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal