akonadi
entityorderproxymodel.cpp
00001 /* 00002 Copyright (C) 2010 Klarälvdalens Datakonsult AB, 00003 a KDAB Group company, info@kdab.net, 00004 author Stephen Kelly <stephen@kdab.com> 00005 00006 This library is free software; you can redistribute it and/or modify it 00007 under the terms of the GNU Library General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or (at your 00009 option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, but WITHOUT 00012 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00013 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00014 License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to the 00018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00019 02110-1301, USA. 00020 */ 00021 00022 00023 #include "entityorderproxymodel.h" 00024 00025 #include <QMimeData> 00026 00027 #include <KDE/KConfigGroup> 00028 00029 #include "collection.h" 00030 #include "item.h" 00031 #include "entitytreemodel.h" 00032 00033 namespace Akonadi 00034 { 00035 00036 class EntityOrderProxyModelPrivate 00037 { 00038 public: 00039 EntityOrderProxyModelPrivate( EntityOrderProxyModel *qq ) 00040 : q_ptr( qq ) 00041 { 00042 00043 } 00044 00045 void saveOrder( const QModelIndex &index ); 00046 00047 KConfigGroup m_orderConfig; 00048 00049 Q_DECLARE_PUBLIC(EntityOrderProxyModel) 00050 EntityOrderProxyModel * const q_ptr; 00051 00052 }; 00053 00054 } 00055 00056 using namespace Akonadi; 00057 00058 EntityOrderProxyModel::EntityOrderProxyModel( QObject* parent ) 00059 : QSortFilterProxyModel(parent), d_ptr( new EntityOrderProxyModelPrivate( this ) ) 00060 { 00061 setDynamicSortFilter(true); 00062 //setSortCaseSensitivity( Qt::CaseInsensitive ); 00063 } 00064 00065 EntityOrderProxyModel::~EntityOrderProxyModel() 00066 { 00067 delete d_ptr; 00068 } 00069 00070 void EntityOrderProxyModel::setOrderConfig( KConfigGroup& configGroup ) 00071 { 00072 Q_D( EntityOrderProxyModel ); 00073 layoutAboutToBeChanged(); 00074 d->m_orderConfig = configGroup; 00075 layoutChanged(); 00076 } 00077 00078 bool EntityOrderProxyModel::lessThan( const QModelIndex& left, const QModelIndex& right ) const 00079 { 00080 Q_D( const EntityOrderProxyModel ); 00081 00082 if ( !d->m_orderConfig.isValid() ) { 00083 return QSortFilterProxyModel::lessThan( left, right ); 00084 } 00085 Collection col = left.data( EntityTreeModel::ParentCollectionRole ).value<Collection>(); 00086 00087 if ( !d->m_orderConfig.hasKey( QString::number( col.id() ) ) ) 00088 return QSortFilterProxyModel::lessThan( left, right ); 00089 00090 const QStringList list = d->m_orderConfig.readEntry( QString::number( col.id() ), QStringList() ); 00091 00092 if ( list.isEmpty() ) 00093 return QSortFilterProxyModel::lessThan( left, right ); 00094 00095 const QString leftValue = configString( left ); 00096 const QString rightValue = configString( right ); 00097 00098 const int leftPosition = list.indexOf( leftValue ); 00099 const int rightPosition = list.indexOf( rightValue ); 00100 00101 if ( leftPosition < 0 || rightPosition < 0 ) 00102 return QSortFilterProxyModel::lessThan( left, right ); 00103 00104 return leftPosition < rightPosition; 00105 } 00106 00107 bool EntityOrderProxyModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent ) 00108 { 00109 Q_D( EntityOrderProxyModel ); 00110 00111 if ( !d->m_orderConfig.isValid() ) 00112 return QSortFilterProxyModel::dropMimeData( data, action, row, column, parent ); 00113 00114 if ( !data->hasFormat( QLatin1String( "text/uri-list" ) ) ) 00115 return QSortFilterProxyModel::dropMimeData( data, action, row, column, parent ); 00116 00117 if ( row == -1 ) 00118 return QSortFilterProxyModel::dropMimeData( data, action, row, column, parent ); 00119 00120 bool containsMove = false; 00121 00122 const KUrl::List urls = KUrl::List::fromMimeData( data ); 00123 00124 Collection parentCol; 00125 00126 if (parent.isValid()) 00127 parentCol = parent.data( EntityTreeModel::CollectionRole ).value<Collection>(); 00128 else 00129 { 00130 if (!hasChildren(parent)) 00131 return QSortFilterProxyModel::dropMimeData( data, action, row, column, parent ); 00132 00133 const QModelIndex targetIndex = index( 0, column, parent ); 00134 00135 parentCol = targetIndex.data( EntityTreeModel::ParentCollectionRole ).value<Collection>(); 00136 } 00137 00138 QStringList droppedList; 00139 foreach ( const KUrl &url, urls ) { 00140 Collection col = Collection::fromUrl( url ); 00141 00142 if ( !col.isValid() ) 00143 { 00144 Item item = Item::fromUrl( url ); 00145 if ( !item.isValid() ) 00146 continue; 00147 00148 const QModelIndexList list = EntityTreeModel::modelIndexesForItem( this, item ); 00149 if ( list.isEmpty() ) 00150 continue; 00151 00152 if ( !containsMove && list.first().data( EntityTreeModel::ParentCollectionRole ).value<Collection>().id() != parentCol.id() ) 00153 containsMove = true; 00154 00155 droppedList << configString( list.first() ); 00156 } else { 00157 const QModelIndex idx = EntityTreeModel::modelIndexForCollection( this, col ); 00158 if ( !idx.isValid() ) 00159 continue; 00160 00161 if ( !containsMove && idx.data( EntityTreeModel::ParentCollectionRole ).value<Collection>().id() != parentCol.id() ) 00162 containsMove = true; 00163 00164 droppedList << configString( idx ); 00165 } 00166 } 00167 00168 QStringList existingList; 00169 if ( d->m_orderConfig.hasKey( QString::number( parentCol.id() ) ) ) { 00170 existingList = d->m_orderConfig.readEntry( QString::number( parentCol.id() ), QStringList() ); 00171 } else { 00172 const int rowCount = this->rowCount( parent ); 00173 for (int row = 0; row < rowCount; ++row) { 00174 static const int column = 0; 00175 const QModelIndex idx = this->index( row, column, parent ); 00176 existingList.append(configString( idx )); 00177 } 00178 } 00179 const int numberOfDroppedElement( droppedList.size() ); 00180 for ( int i = 0; i < numberOfDroppedElement; ++i ) 00181 { 00182 const QString droppedItem = droppedList.at( i ); 00183 const int existingIndex = existingList.indexOf( droppedItem ); 00184 existingList.removeAt( existingIndex ); 00185 existingList.insert( row + i - (existingIndex > row ? 0 : 1), droppedList.at( i ) ); 00186 } 00187 00188 d->m_orderConfig.writeEntry( QString::number( parentCol.id() ), existingList ); 00189 00190 if ( containsMove ) 00191 { 00192 bool result = QSortFilterProxyModel::dropMimeData( data, action, row, column, parent ); 00193 invalidate(); 00194 return result; 00195 } 00196 invalidate(); 00197 return true; 00198 } 00199 00200 QModelIndexList EntityOrderProxyModel::match( const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags ) const 00201 { 00202 if ( role < Qt::UserRole ) 00203 return QSortFilterProxyModel::match( start, role, value, hits, flags ); 00204 00205 QModelIndexList list; 00206 QModelIndex proxyIndex; 00207 foreach ( const QModelIndex &idx, sourceModel()->match( mapToSource( start ), role, value, hits, flags ) ) { 00208 proxyIndex = mapFromSource( idx ); 00209 if ( proxyIndex.isValid() ) 00210 list << proxyIndex; 00211 } 00212 00213 return list; 00214 } 00215 00216 void EntityOrderProxyModelPrivate::saveOrder( const QModelIndex &parent ) 00217 { 00218 Q_Q( const EntityOrderProxyModel ); 00219 int rowCount = q->rowCount( parent ); 00220 00221 if ( rowCount == 0 ) 00222 return; 00223 00224 static const int column = 0; 00225 QModelIndex childIndex = q->index( 0, column, parent ); 00226 00227 QString parentKey = q->parentConfigString( childIndex ); 00228 00229 if ( parentKey.isEmpty() ) 00230 return; 00231 00232 QStringList list; 00233 00234 list << q->configString( childIndex ); 00235 saveOrder( childIndex ); 00236 00237 for ( int row = 1; row < rowCount; ++row ) 00238 { 00239 childIndex = q->index( row, column, parent ); 00240 list << q->configString( childIndex ); 00241 saveOrder( childIndex ); 00242 } 00243 00244 m_orderConfig.writeEntry( parentKey, list ); 00245 } 00246 00247 QString EntityOrderProxyModel::parentConfigString( const QModelIndex& index ) const 00248 { 00249 const Collection col = index.data( EntityTreeModel::ParentCollectionRole ).value<Collection>(); 00250 00251 Q_ASSERT( col.isValid() ); 00252 if ( !col.isValid() ) 00253 return QString(); 00254 00255 return QString::number( col.id() ); 00256 } 00257 00258 QString EntityOrderProxyModel::configString( const QModelIndex& index ) const 00259 { 00260 Entity::Id eId = index.data( EntityTreeModel::ItemIdRole ).toLongLong(); 00261 if ( eId != -1 ) 00262 { 00263 return QString::fromLatin1( "i" ) + QString::number( eId ); 00264 } 00265 eId = index.data( EntityTreeModel::CollectionIdRole ).toLongLong(); 00266 if ( eId != -1 ) 00267 { 00268 return QString::fromLatin1( "c" ) + QString::number( eId ); 00269 } 00270 Q_ASSERT( !"Invalid entity" ); 00271 return QString(); 00272 } 00273 00274 void EntityOrderProxyModel::saveOrder() 00275 { 00276 Q_D( EntityOrderProxyModel ); 00277 d->saveOrder( QModelIndex() ); 00278 d->m_orderConfig.sync(); 00279 } 00280 00281 void EntityOrderProxyModel::clearOrder( const QModelIndex& parent ) 00282 { 00283 Q_D( EntityOrderProxyModel ); 00284 00285 const QString parentKey = parentConfigString( index( 0, 0, parent ) ); 00286 00287 if ( parentKey.isEmpty() ) 00288 return; 00289 00290 d->m_orderConfig.deleteEntry( parentKey ); 00291 invalidate(); 00292 } 00293 00294 void EntityOrderProxyModel::clearTreeOrder() 00295 { 00296 Q_D( EntityOrderProxyModel ); 00297 d->m_orderConfig.deleteGroup(); 00298 invalidate(); 00299 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:09:22 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:09:22 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.