20 #include "blockalarmsattribute.h"
21 #include "etmcalendar.h"
22 #include "etmcalendar_p.h"
23 #include "incidencefetchjob_p.h"
24 #include "calendarmodel_p.h"
25 #include "kcolumnfilterproxymodel_p.h"
27 #include <akonadi/item.h>
28 #include <akonadi/session.h>
29 #include <akonadi/collection.h>
30 #include <akonadi/changerecorder.h>
31 #include <akonadi/itemfetchscope.h>
32 #include <akonadi/entitydisplayattribute.h>
33 #include <akonadi/entitymimetypefiltermodel.h>
34 #include <akonadi/entitytreemodel.h>
35 #include <KSelectionProxyModel>
36 #include <kcheckableproxymodel.h>
38 #include <QSortFilterProxyModel>
39 #include <QItemSelectionModel>
41 using namespace Akonadi;
42 using namespace KCalCore;
46 ETMCalendarPrivate::ETMCalendarPrivate( ETMCalendar *qq ) : CalendarBasePrivate( qq )
49 , mCheckableProxyModel( 0 )
54 void ETMCalendarPrivate::init()
73 mETM =
new CalendarModel( monitor, q );
74 mETM->setObjectName(
"ETM" );
78 connect( mETM, SIGNAL(rowsInserted(QModelIndex,
int,
int)),
79 SLOT(onRowsInserted(QModelIndex,
int,
int)) );
80 connect( mETM, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
81 SLOT(onDataChanged(QModelIndex,QModelIndex)) );
82 connect( mETM, SIGNAL(rowsMoved(QModelIndex,
int,
int,QModelIndex,
int)),
83 SLOT(onRowsMoved(QModelIndex,
int,
int,QModelIndex,
int)) );
84 connect( mETM, SIGNAL(rowsRemoved(QModelIndex,
int,
int)),
85 SLOT(onRowsRemoved(QModelIndex,
int,
int)) );
87 connect( mFilteredETM, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
88 SLOT(onDataChangedInFilteredModel(QModelIndex,QModelIndex)) );
89 connect( mFilteredETM, SIGNAL(layoutChanged()),
90 SLOT(onLayoutChangedInFilteredModel()) );
91 connect( mFilteredETM, SIGNAL(modelReset()),
92 SLOT(onModelResetInFilteredModel()) );
93 connect( mFilteredETM, SIGNAL(rowsInserted(QModelIndex,
int,
int)),
94 SLOT(onRowsInsertedInFilteredModel(QModelIndex,
int,
int)) );
95 connect( mFilteredETM, SIGNAL(rowsAboutToBeRemoved(QModelIndex,
int,
int)),
96 SLOT(onRowsAboutToBeRemovedInFilteredModel(QModelIndex,
int,
int)) );
101 void ETMCalendarPrivate::setupFilteredETM()
104 QSortFilterProxyModel *sortFilterProxy =
new QSortFilterProxyModel(
this );
105 sortFilterProxy->setObjectName(
"Sort" );
106 sortFilterProxy->setDynamicSortFilter(
true );
107 sortFilterProxy->setSortCaseSensitivity( Qt::CaseInsensitive );
108 sortFilterProxy->setSourceModel( mETM );
112 columnFilterProxy->setSourceModel( sortFilterProxy );
114 columnFilterProxy->setObjectName(
"Remove columns" );
117 QItemSelectionModel* selectionModel =
new QItemSelectionModel( columnFilterProxy );
118 selectionModel->setObjectName(
"Calendar Selection Model" );
121 mCheckableProxyModel =
new KCheckableProxyModel(
this );
122 mCheckableProxyModel->setSelectionModel( selectionModel );
123 mCheckableProxyModel->setSourceModel( columnFilterProxy );
124 mCheckableProxyModel->setObjectName(
"Add checkboxes" );
126 KSelectionProxyModel* selectionProxy =
new KSelectionProxyModel( selectionModel,
this );
127 selectionProxy->setObjectName(
"Only show items of selected collection" );
128 selectionProxy->setFilterBehavior( KSelectionProxyModel::ChildrenOfExactSelection );
129 selectionProxy->setSourceModel( mETM );
133 mFilteredETM->setSourceModel( selectionProxy );
134 mFilteredETM->setSortRole( CalendarModel::SortRole );
135 mFilteredETM->setObjectName(
"Show headers" );
138 ETMCalendarPrivate::~ETMCalendarPrivate()
142 void ETMCalendarPrivate::loadFromETM()
144 itemsAdded( itemsFromModel( mETM ) );
147 void ETMCalendarPrivate::clear()
149 mCollectionMap.clear();
151 itemsRemoved( mItemById.values() );
152 Q_ASSERT( mItemById.isEmpty() );
153 Q_ASSERT( mItemIdByUid.isEmpty() );
159 const QModelIndex &parentIndex,
162 const int endRow = end >= 0 ? end : model->rowCount( parentIndex ) - 1;
165 QModelIndex i = model->index( row, 0, parentIndex );
166 while ( row <= endRow ) {
168 if ( item.
hasPayload<KCalCore::Incidence::Ptr>() ) {
171 const QModelIndex childIndex = i.child( 0, 0 );
172 if ( childIndex.isValid() ) {
173 items << itemsFromModel( model, i );
177 i = i.sibling( row, 0 );
183 const QModelIndex &parentIndex,
186 const int endRow = end >= 0 ? end : model->rowCount( parentIndex ) - 1;
189 QModelIndex i = model->index( row, 0, parentIndex );
190 while ( row <= endRow ) {
193 collections << collection;
194 QModelIndex childIndex = i.child( 0, 0 );
195 if ( childIndex.isValid() ) {
196 collections << collectionsFromModel( model, i );
200 i = i.sibling( row, 0 );
205 Akonadi::Item ETMCalendarPrivate::itemFromIndex(
const QModelIndex &idx )
216 internalInsert( item );
218 emit q->calendarChanged();
224 internalRemove( item );
226 emit q->calendarChanged();
234 void ETMCalendarPrivate::onRowsInserted(
const QModelIndex &index,
241 mCollectionMap[collection.
id()] = collection;
244 if ( !collections.isEmpty() )
245 emit q->collectionsAdded( collections );
248 void ETMCalendarPrivate::onRowsRemoved(
const QModelIndex &index,
int start,
int end )
252 mCollectionMap.remove( collection.
id() );
255 if ( !collections.isEmpty() )
256 emit q->collectionsRemoved( collections );
259 void ETMCalendarPrivate::onDataChanged(
const QModelIndex &topLeft,
260 const QModelIndex &bottomRight )
263 Q_ASSERT( topLeft.row() <= bottomRight.row() );
264 const int endRow = bottomRight.row();
265 QModelIndex i( topLeft );
267 while ( row <= endRow ) {
271 mCollectionMap.insert( col.
id(), col );
277 void ETMCalendarPrivate::onRowsMoved(
const QModelIndex &sourceParent,
280 const QModelIndex &destinationParent,
284 Q_UNUSED( sourceParent );
285 Q_UNUSED( sourceStart );
286 Q_UNUSED( sourceEnd );
287 Q_UNUSED( destinationParent );
288 Q_UNUSED( destinationRow );
291 void ETMCalendarPrivate::onLayoutChangedInFilteredModel()
297 void ETMCalendarPrivate::onModelResetInFilteredModel()
303 void ETMCalendarPrivate::onDataChangedInFilteredModel(
const QModelIndex &topLeft,
304 const QModelIndex &bottomRight )
306 Q_ASSERT( topLeft.row() <= bottomRight.row() );
307 const int endRow = bottomRight.row();
308 QModelIndex i( topLeft );
310 while ( row <= endRow ) {
313 Incidence::Ptr newIncidence = item.
payload<KCalCore::Incidence::Ptr>();
314 Q_ASSERT( newIncidence );
315 Q_ASSERT( !newIncidence->uid().isEmpty() );
316 IncidenceBase::Ptr existingIncidence = q->incidence( newIncidence->uid() );
317 Q_ASSERT( existingIncidence );
320 mItemById.insert( item.
id(), item );
322 *(existingIncidence.data()) = *( newIncidence.data() );
325 i = i.sibling( row, topLeft.column() );
327 emit q->calendarChanged();
330 void ETMCalendarPrivate::onRowsInsertedInFilteredModel(
const QModelIndex &index,
333 itemsAdded( itemsFromModel( mFilteredETM, index, start, end ) );
336 void ETMCalendarPrivate::onRowsAboutToBeRemovedInFilteredModel(
const QModelIndex &index,
339 itemsRemoved( itemsFromModel( mFilteredETM, index, start, end ) );
342 ETMCalendar::ETMCalendar() :
CalendarBase( new ETMCalendarPrivate( this ) )
348 ETMCalendar::~ETMCalendar()
355 Q_D(
const ETMCalendar );
356 return d->mCollectionMap.value(
id );
361 return hasRight( item( uid ), right );
370 return col.
rights() & right;
373 QAbstractItemModel *ETMCalendar::filteredModel()
const
375 Q_D(
const ETMCalendar );
376 return d->mFilteredETM;
379 QAbstractItemModel *ETMCalendar::unfilteredModel()
const
381 Q_D(
const ETMCalendar );
385 KCheckableProxyModel *ETMCalendar::checkableProxyModel()
const
387 Q_D(
const ETMCalendar );
388 return d->mCheckableProxyModel;
391 KCalCore::Alarm::List ETMCalendar::alarms(
const KDateTime &from,
393 bool excludeBlockedAlarms )
const
395 Q_D(
const ETMCalendar );
396 KCalCore::Alarm::List alarmList;
397 QHashIterator<Akonadi::Item::Id, Akonadi::Item> i( d->mItemById );
398 while ( i.hasNext() ) {
401 if ( excludeBlockedAlarms ) {
409 KCalCore::Incidence::Ptr incidence;
411 incidence = item.
payload<KCalCore::Incidence::Ptr>();
420 if ( incidence->recurs() ) {
421 appendRecurringAlarms( alarmList, incidence, from, to );
423 appendAlarms( alarmList, incidence, from, to );
429 #include "etmcalendar.moc"
430 #include "etmcalendar_p.moc"