• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepimlibs API Reference
  • KDE Home
  • Contact Us
 

akonadi

  • sources
  • kde-4.12
  • kdepimlibs
  • akonadi
entityorderproxymodel.cpp
1 /*
2  Copyright (C) 2010 Klarälvdalens Datakonsult AB,
3  a KDAB Group company, info@kdab.net,
4  author Stephen Kelly <stephen@kdab.com>
5 
6  This library is free software; you can redistribute it and/or modify it
7  under the terms of the GNU Library General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or (at your
9  option) any later version.
10 
11  This library is distributed in the hope that it will be useful, but WITHOUT
12  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14  License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to the
18  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  02110-1301, USA.
20 */
21 
22 #include "entityorderproxymodel.h"
23 
24 #include <QMimeData>
25 
26 #include <KDE/KConfigGroup>
27 #include <KUrl>
28 
29 #include "collection.h"
30 #include "item.h"
31 #include "entitytreemodel.h"
32 
33 namespace Akonadi
34 {
35 
36 class EntityOrderProxyModelPrivate
37 {
38 public:
39  EntityOrderProxyModelPrivate( EntityOrderProxyModel *qq )
40  : q_ptr( qq )
41  {
42 
43  }
44 
45  void saveOrder( const QModelIndex &index );
46 
47  KConfigGroup m_orderConfig;
48 
49  Q_DECLARE_PUBLIC( EntityOrderProxyModel )
50  EntityOrderProxyModel * const q_ptr;
51 
52 };
53 
54 }
55 
56 using namespace Akonadi;
57 
58 EntityOrderProxyModel::EntityOrderProxyModel( QObject* parent )
59  : QSortFilterProxyModel(parent), d_ptr( new EntityOrderProxyModelPrivate( this ) )
60 {
61  setDynamicSortFilter( true );
62  //setSortCaseSensitivity( Qt::CaseInsensitive );
63 }
64 
65 EntityOrderProxyModel::~EntityOrderProxyModel()
66 {
67  delete d_ptr;
68 }
69 
70 void EntityOrderProxyModel::setOrderConfig( KConfigGroup& configGroup )
71 {
72  Q_D( EntityOrderProxyModel );
73  layoutAboutToBeChanged();
74  d->m_orderConfig = configGroup;
75  layoutChanged();
76 }
77 
78 bool EntityOrderProxyModel::lessThan( const QModelIndex& left, const QModelIndex& right ) const
79 {
80  Q_D( const EntityOrderProxyModel );
81 
82  if ( !d->m_orderConfig.isValid() ) {
83  return QSortFilterProxyModel::lessThan( left, right );
84  }
85  Collection col = left.data( EntityTreeModel::ParentCollectionRole ).value<Collection>();
86 
87  if ( !d->m_orderConfig.hasKey( QString::number( col.id() ) ) ) {
88  return QSortFilterProxyModel::lessThan( left, right );
89  }
90 
91  const QStringList list = d->m_orderConfig.readEntry( QString::number( col.id() ), QStringList() );
92 
93  if ( list.isEmpty() ) {
94  return QSortFilterProxyModel::lessThan( left, right );
95  }
96 
97  const QString leftValue = configString( left );
98  const QString rightValue = configString( right );
99 
100  const int leftPosition = list.indexOf( leftValue );
101  const int rightPosition = list.indexOf( rightValue );
102 
103  if ( leftPosition < 0 || rightPosition < 0 ) {
104  return QSortFilterProxyModel::lessThan( left, right );
105  }
106 
107  return leftPosition < rightPosition;
108 }
109 
110 bool EntityOrderProxyModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent )
111 {
112  Q_D( EntityOrderProxyModel );
113 
114  if ( !d->m_orderConfig.isValid() ) {
115  return QSortFilterProxyModel::dropMimeData( data, action, row, column, parent );
116  }
117 
118  if ( !data->hasFormat( QLatin1String( "text/uri-list" ) ) ) {
119  return QSortFilterProxyModel::dropMimeData( data, action, row, column, parent );
120  }
121 
122  if ( row == -1 ) {
123  return QSortFilterProxyModel::dropMimeData( data, action, row, column, parent );
124  }
125 
126  bool containsMove = false;
127 
128  const KUrl::List urls = KUrl::List::fromMimeData( data );
129 
130  Collection parentCol;
131 
132  if ( parent.isValid() ) {
133  parentCol = parent.data( EntityTreeModel::CollectionRole ).value<Collection>();
134  } else {
135  if ( !hasChildren( parent ) ) {
136  return QSortFilterProxyModel::dropMimeData( data, action, row, column, parent );
137  }
138 
139  const QModelIndex targetIndex = index( 0, column, parent );
140 
141  parentCol = targetIndex.data( EntityTreeModel::ParentCollectionRole ).value<Collection>();
142  }
143 
144  QStringList droppedList;
145  foreach ( const KUrl &url, urls ) {
146  Collection col = Collection::fromUrl( url );
147 
148  if ( !col.isValid() ) {
149  Item item = Item::fromUrl( url );
150  if ( !item.isValid() ) {
151  continue;
152  }
153 
154  const QModelIndexList list = EntityTreeModel::modelIndexesForItem( this, item );
155  if ( list.isEmpty() ) {
156  continue;
157  }
158 
159  if ( !containsMove && list.first().data( EntityTreeModel::ParentCollectionRole ).value<Collection>().id() != parentCol.id() ) {
160  containsMove = true;
161  }
162 
163  droppedList << configString( list.first() );
164  } else {
165  const QModelIndex idx = EntityTreeModel::modelIndexForCollection( this, col );
166  if ( !idx.isValid() ) {
167  continue;
168  }
169 
170  if ( !containsMove && idx.data( EntityTreeModel::ParentCollectionRole ).value<Collection>().id() != parentCol.id() ) {
171  containsMove = true;
172  }
173 
174  droppedList << configString( idx );
175  }
176  }
177 
178  QStringList existingList;
179  if ( d->m_orderConfig.hasKey( QString::number( parentCol.id() ) ) ) {
180  existingList = d->m_orderConfig.readEntry( QString::number( parentCol.id() ), QStringList() );
181  } else {
182  const int rowCount = this->rowCount( parent );
183  for ( int row = 0; row < rowCount; ++row ) {
184  static const int column = 0;
185  const QModelIndex idx = this->index( row, column, parent );
186  existingList.append( configString( idx ) );
187  }
188  }
189  const int numberOfDroppedElement( droppedList.size() );
190  for ( int i = 0; i < numberOfDroppedElement; ++i ) {
191  const QString droppedItem = droppedList.at( i );
192  const int existingIndex = existingList.indexOf( droppedItem );
193  existingList.removeAt( existingIndex );
194  existingList.insert( row + i - ( existingIndex > row ? 0 : 1 ), droppedList.at( i ) );
195  }
196 
197  d->m_orderConfig.writeEntry( QString::number( parentCol.id() ), existingList );
198 
199  if ( containsMove ) {
200  bool result = QSortFilterProxyModel::dropMimeData( data, action, row, column, parent );
201  invalidate();
202  return result;
203  }
204  invalidate();
205  return true;
206 }
207 
208 QModelIndexList EntityOrderProxyModel::match( const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags ) const
209 {
210  if ( role < Qt::UserRole ) {
211  return QSortFilterProxyModel::match( start, role, value, hits, flags );
212  }
213 
214  QModelIndexList list;
215  QModelIndex proxyIndex;
216  foreach ( const QModelIndex &idx, sourceModel()->match( mapToSource( start ), role, value, hits, flags ) ) {
217  proxyIndex = mapFromSource( idx );
218  if ( proxyIndex.isValid() ) {
219  list << proxyIndex;
220  }
221  }
222 
223  return list;
224 }
225 
226 void EntityOrderProxyModelPrivate::saveOrder( const QModelIndex &parent )
227 {
228  Q_Q( const EntityOrderProxyModel );
229  int rowCount = q->rowCount( parent );
230 
231  if ( rowCount == 0 ) {
232  return;
233  }
234 
235  static const int column = 0;
236  QModelIndex childIndex = q->index( 0, column, parent );
237 
238  QString parentKey = q->parentConfigString( childIndex );
239 
240  if ( parentKey.isEmpty() ) {
241  return;
242  }
243 
244  QStringList list;
245 
246  list << q->configString( childIndex );
247  saveOrder( childIndex );
248 
249  for ( int row = 1; row < rowCount; ++row ) {
250  childIndex = q->index( row, column, parent );
251  list << q->configString( childIndex );
252  saveOrder( childIndex );
253  }
254 
255  m_orderConfig.writeEntry( parentKey, list );
256 }
257 
258 QString EntityOrderProxyModel::parentConfigString( const QModelIndex& index ) const
259 {
260  const Collection col = index.data( EntityTreeModel::ParentCollectionRole ).value<Collection>();
261 
262  Q_ASSERT( col.isValid() );
263  if ( !col.isValid() ) {
264  return QString();
265  }
266 
267  return QString::number( col.id() );
268 }
269 
270 QString EntityOrderProxyModel::configString( const QModelIndex& index ) const
271 {
272  Entity::Id eId = index.data( EntityTreeModel::ItemIdRole ).toLongLong();
273  if ( eId != -1 ) {
274  return QString::fromLatin1( "i" ) + QString::number( eId );
275  }
276  eId = index.data( EntityTreeModel::CollectionIdRole ).toLongLong();
277  if ( eId != -1 ) {
278  return QString::fromLatin1( "c" ) + QString::number( eId );
279  }
280  Q_ASSERT( !"Invalid entity" );
281  return QString();
282 }
283 
284 void EntityOrderProxyModel::saveOrder()
285 {
286  Q_D( EntityOrderProxyModel );
287  d->saveOrder( QModelIndex() );
288  d->m_orderConfig.sync();
289 }
290 
291 void EntityOrderProxyModel::clearOrder( const QModelIndex& parent )
292 {
293  Q_D( EntityOrderProxyModel );
294 
295  const QString parentKey = parentConfigString( index( 0, 0, parent ) );
296 
297  if ( parentKey.isEmpty() ) {
298  return;
299  }
300 
301  d->m_orderConfig.deleteEntry( parentKey );
302  invalidate();
303 }
304 
305 void EntityOrderProxyModel::clearTreeOrder()
306 {
307  Q_D( EntityOrderProxyModel );
308  d->m_orderConfig.deleteGroup();
309  invalidate();
310 }
Akonadi::EntityTreeModel::CollectionIdRole
The collection id.
Definition: entitytreemodel.h:334
Akonadi::Collection
Represents a collection of PIM items.
Definition: collection.h:75
Akonadi::Entity::Id
qint64 Id
Describes the unique id type.
Definition: entity.h:65
Akonadi::EntityOrderProxyModel::setOrderConfig
void setOrderConfig(KConfigGroup &group)
Sets the config group that will be used for storing the order.
Definition: entityorderproxymodel.cpp:70
Akonadi::EntityOrderProxyModel::dropMimeData
virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
Definition: entityorderproxymodel.cpp:110
Akonadi::EntityOrderProxyModel
A model that keeps the order of entities persistent.
Definition: entityorderproxymodel.h:44
Akonadi::EntityOrderProxyModel::match
virtual QModelIndexList match(const QModelIndex &start, int role, const QVariant &value, int hits=1, Qt::MatchFlags flags=Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const
Definition: entityorderproxymodel.cpp:208
Akonadi::EntityTreeModel::CollectionRole
The collection.
Definition: entitytreemodel.h:335
Akonadi::EntityTreeModel::ParentCollectionRole
The parent collection of the entity.
Definition: entitytreemodel.h:340
Akonadi::Entity::id
Id id() const
Returns the unique identifier of the entity.
Definition: entity.cpp:72
Akonadi::EntityTreeModel::modelIndexForCollection
static QModelIndex modelIndexForCollection(const QAbstractItemModel *model, const Collection &collection)
Returns a QModelIndex in model which points to collection.
Definition: entitytreemodel.cpp:1192
Akonadi::EntityOrderProxyModel::saveOrder
void saveOrder()
Saves the order.
Definition: entityorderproxymodel.cpp:284
Akonadi::EntityOrderProxyModel::lessThan
virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const
Definition: entityorderproxymodel.cpp:78
Akonadi::EntityOrderProxyModel::~EntityOrderProxyModel
virtual ~EntityOrderProxyModel()
Destroys the entity order proxy model.
Definition: entityorderproxymodel.cpp:65
Akonadi::EntityTreeModel::modelIndexesForItem
static QModelIndexList modelIndexesForItem(const QAbstractItemModel *model, const Item &item)
Returns a QModelIndex in model which points to item.
Definition: entitytreemodel.cpp:1201
Akonadi::Entity::isValid
bool isValid() const
Returns whether the entity is valid.
Definition: entity.cpp:97
Akonadi::Collection::fromUrl
static Collection fromUrl(const KUrl &url)
Creates a collection from the given url.
Definition: collection.cpp:172
Akonadi::EntityTreeModel::ItemIdRole
The item id.
Definition: entitytreemodel.h:330
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:00:27 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

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

kdepimlibs API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kldap
  • kmbox
  • kmime
  • kpimidentities
  • kpimtextedit
  • kresources
  • ktnef
  • kxmlrpcclient
  • microblog

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal