SVN_SILENT made messages (after extraction)
[kdepim.git] / kalarm / itemlistmodel.cpp
blobe0b8e6c042eb99304dee5aed7894747b02370ada
1 /*
2 * itemlistmodel.cpp - Akonadi item models
3 * Program: kalarm
4 * Copyright © 2007-2012 by David Jarvie <djarvie@kde.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "itemlistmodel.h"
22 #include "collectionmodel.h"
24 #include <kalarmcal/kaevent.h>
26 #include <kselectionproxymodel.h>
28 using namespace Akonadi;
31 /*=============================================================================
32 = Class: ItemListModel
33 = Filter proxy model containing all items (alarms/templates) of specified mime
34 = types in enabled collections.
35 =============================================================================*/
36 ItemListModel::ItemListModel(CalEvent::Types allowed, QObject* parent)
37 : EntityMimeTypeFilterModel(parent),
38 mAllowedTypes(allowed),
39 mHaveEvents(false)
41 KSelectionProxyModel* selectionModel = new KSelectionProxyModel(CollectionControlModel::instance()->selectionModel(), this);
42 selectionModel->setSourceModel(AkonadiModel::instance());
43 selectionModel->setFilterBehavior(KSelectionProxyModel::ChildrenOfExactSelection);
44 setSourceModel(selectionModel);
46 addMimeTypeExclusionFilter(Collection::mimeType());
47 setHeaderGroup(EntityTreeModel::ItemListHeaders);
48 if (allowed)
50 QStringList mimeTypes = CalEvent::mimeTypes(allowed);
51 foreach (const QString& mime, mimeTypes)
52 addMimeTypeInclusionFilter(mime);
54 setHeaderGroup(EntityTreeModel::ItemListHeaders);
55 setSortRole(AkonadiModel::SortRole);
56 setDynamicSortFilter(true);
57 connect(this, &ItemListModel::rowsInserted, this, &ItemListModel::slotRowsInserted);
58 connect(this, &ItemListModel::rowsRemoved, this, &ItemListModel::slotRowsRemoved);
59 connect(AkonadiModel::instance(), &AkonadiModel::collectionStatusChanged,
60 this, &ItemListModel::collectionStatusChanged);
63 int ItemListModel::columnCount(const QModelIndex& /*parent*/) const
65 return AkonadiModel::ColumnCount;
68 /******************************************************************************
69 * Called when rows have been inserted into the model.
71 void ItemListModel::slotRowsInserted()
73 if (!mHaveEvents && rowCount())
75 mHaveEvents = true;
76 Q_EMIT haveEventsStatus(true);
80 /******************************************************************************
81 * Called when rows have been deleted from the model.
83 void ItemListModel::slotRowsRemoved()
85 if (mHaveEvents && !rowCount())
87 mHaveEvents = false;
88 Q_EMIT haveEventsStatus(false);
92 /******************************************************************************
93 * Called when a collection parameter or status has changed.
94 * If the collection's enabled status has changed, re-filter the list to add or
95 * remove its alarms.
97 void ItemListModel::collectionStatusChanged(const Collection& collection, AkonadiModel::Change change, const QVariant&, bool inserted)
99 Q_UNUSED(inserted);
100 if (!collection.isValid())
101 return;
102 if (change == AkonadiModel::Enabled)
104 // Ensure that items for a newly enabled collection are always ordered
105 // correctly. Note that invalidateFilter() is not adequate for this.
106 invalidate();
110 bool ItemListModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
112 if (!EntityMimeTypeFilterModel::filterAcceptsRow(sourceRow, sourceParent))
113 return false;
114 // Get the alarm type of the item
115 QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent);
116 CalEvent::Type type = static_cast<CalEvent::Type>(sourceModel()->data(sourceIndex, AkonadiModel::StatusRole).toInt());
117 Collection parent = sourceIndex.data(AkonadiModel::ParentCollectionRole).value<Collection>();
118 return CollectionControlModel::isEnabled(parent, type);
121 #if 0
122 QModelIndex ItemListModel::index(int row, int column, const QModelIndex& parent) const
124 if (parent.isValid())
125 return QModelIndex();
126 return createIndex(row, column, mEvents[row]);
129 bool ItemListModel::setData(const QModelIndex& ix, const QVariant&, int role)
131 if (ix.isValid() && role == Qt::EditRole)
133 //??? update event
134 int row = ix.row();
135 Q_EMIT dataChanged(index(row, 0), index(row, AkonadiModel::ColumnCount - 1));
136 return true;
138 return false;
140 #endif
142 Qt::ItemFlags ItemListModel::flags(const QModelIndex& index) const
144 if (!index.isValid())
145 return Qt::ItemIsEnabled;
146 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
149 /******************************************************************************
150 * Return the index to a specified event.
152 QModelIndex ItemListModel::eventIndex(Item::Id itemId) const
154 QModelIndexList list = match(QModelIndex(), AkonadiModel::ItemIdRole, itemId, 1, Qt::MatchExactly | Qt::MatchRecursive);
155 if (list.isEmpty())
156 return QModelIndex();
157 return index(list[0].row(), 0, list[0].parent());
160 /******************************************************************************
161 * Return the event in a specified row.
163 KAEvent ItemListModel::event(int row) const
165 return event(index(row, 0));
168 /******************************************************************************
169 * Return the event referred to by an index.
171 KAEvent ItemListModel::event(const QModelIndex& index) const
173 return static_cast<AkonadiModel*>(sourceModel())->event(mapToSource(index));
176 /******************************************************************************
177 * Check whether the model contains any events.
179 bool ItemListModel::haveEvents() const
181 return rowCount();
185 /*=============================================================================
186 = Class: AlarmListModel
187 = Filter proxy model containing all alarms (not templates) of specified mime
188 = types in enabled collections.
189 Equivalent to AlarmListFilterModel
190 =============================================================================*/
191 AlarmListModel* AlarmListModel::mAllInstance = Q_NULLPTR;
193 AlarmListModel::AlarmListModel(QObject* parent)
194 : ItemListModel(CalEvent::ACTIVE | CalEvent::ARCHIVED, parent),
195 mFilterTypes(CalEvent::ACTIVE | CalEvent::ARCHIVED)
199 AlarmListModel::~AlarmListModel()
201 if (this == mAllInstance)
202 mAllInstance = Q_NULLPTR;
205 AlarmListModel* AlarmListModel::all()
207 if (!mAllInstance)
209 mAllInstance = new AlarmListModel(AkonadiModel::instance());
210 mAllInstance->sort(TimeColumn, Qt::AscendingOrder);
212 return mAllInstance;
215 void AlarmListModel::setEventTypeFilter(CalEvent::Types types)
217 // Ensure that the filter isn't applied to the 'all' instance, and that
218 // 'types' doesn't include any disallowed alarm types
219 if (!types)
220 types = includedTypes();
221 if (this != mAllInstance
222 && types != mFilterTypes && (types & includedTypes()) == types)
224 mFilterTypes = types;
225 invalidateFilter();
229 bool AlarmListModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
231 if (!ItemListModel::filterAcceptsRow(sourceRow, sourceParent))
232 return false;
233 if (mFilterTypes == CalEvent::EMPTY)
234 return false;
235 int type = sourceModel()->data(sourceModel()->index(sourceRow, 0, sourceParent), AkonadiModel::StatusRole).toInt();
236 return static_cast<CalEvent::Type>(type) & mFilterTypes;
239 bool AlarmListModel::filterAcceptsColumn(int sourceCol, const QModelIndex&) const
241 return (sourceCol != AkonadiModel::TemplateNameColumn);
244 QVariant AlarmListModel::headerData(int section, Qt::Orientation orientation, int role) const
246 if (orientation == Qt::Horizontal)
248 if (section < 0 || section >= ColumnCount)
249 return QVariant();
251 return ItemListModel::headerData(section, orientation, role);
255 /*=============================================================================
256 = Class: TemplateListModel
257 = Filter proxy model containing all alarm templates for specified alarm types
258 = in enabled collections.
259 Equivalent to TemplateListFilterModel
260 =============================================================================*/
261 TemplateListModel* TemplateListModel::mAllInstance = Q_NULLPTR;
263 TemplateListModel::TemplateListModel(QObject* parent)
264 : ItemListModel(CalEvent::TEMPLATE, parent),
265 mActionsEnabled(KAEvent::ACT_ALL),
266 mActionsFilter(KAEvent::ACT_ALL)
270 TemplateListModel::~TemplateListModel()
272 if (this == mAllInstance)
273 mAllInstance = Q_NULLPTR;
276 TemplateListModel* TemplateListModel::all()
278 if (!mAllInstance)
280 mAllInstance = new TemplateListModel(AkonadiModel::instance());
281 mAllInstance->sort(TemplateNameColumn, Qt::AscendingOrder);
283 return mAllInstance;
286 void TemplateListModel::setAlarmActionFilter(KAEvent::Actions types)
288 // Ensure that the filter isn't applied to the 'all' instance.
289 if (this != mAllInstance && types != mActionsFilter)
291 mActionsFilter = types;
292 filterChanged();
296 void TemplateListModel::setAlarmActionsEnabled(KAEvent::Actions types)
298 // Ensure that the setting isn't applied to the 'all' instance.
299 if (this != mAllInstance && types != mActionsEnabled)
301 mActionsEnabled = types;
302 filterChanged();
306 bool TemplateListModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
308 if (!ItemListModel::filterAcceptsRow(sourceRow, sourceParent))
309 return false;
310 if (mActionsFilter == KAEvent::ACT_ALL)
311 return true;
312 QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent);
313 KAEvent::Actions actions = static_cast<KAEvent::Actions>(sourceModel()->data(sourceIndex, AkonadiModel::AlarmActionsRole).toInt());
314 return actions & mActionsFilter;
317 bool TemplateListModel::filterAcceptsColumn(int sourceCol, const QModelIndex&) const
319 return sourceCol == AkonadiModel::TemplateNameColumn
320 || sourceCol == AkonadiModel::TypeColumn;
323 QVariant TemplateListModel::headerData(int section, Qt::Orientation orientation, int role) const
325 if (orientation == Qt::Horizontal)
327 switch (section)
329 case TypeColumn:
330 section = AkonadiModel::TypeColumn;
331 break;
332 case TemplateNameColumn:
333 section = AkonadiModel::TemplateNameColumn;
334 break;
335 default:
336 return QVariant();
339 return ItemListModel::headerData(section, orientation, role);
342 Qt::ItemFlags TemplateListModel::flags(const QModelIndex& index) const
344 Qt::ItemFlags f = sourceModel()->flags(mapToSource(index));
345 if (mActionsEnabled == KAEvent::ACT_ALL)
346 return f;
347 KAEvent::Actions actions = static_cast<KAEvent::Actions>(ItemListModel::data(index, AkonadiModel::AlarmActionsRole).toInt());
348 if (!(actions & mActionsEnabled))
349 f = static_cast<Qt::ItemFlags>(f & ~(Qt::ItemIsEnabled | Qt::ItemIsSelectable));
350 return f;
353 // vim: et sw=4: