mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-23 18:32:51 +00:00
353 lines
12 KiB
C++
353 lines
12 KiB
C++
/*
|
|
* itemlistmodel.cpp - Akonadi item models
|
|
* Program: kalarm
|
|
* Copyright © 2007-2012 by David Jarvie <djarvie@kde.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "itemlistmodel.h"
|
|
#include "collectionmodel.h"
|
|
|
|
#include <kalarmcal/kaevent.h>
|
|
|
|
#include <kselectionproxymodel.h>
|
|
|
|
using namespace Akonadi;
|
|
|
|
|
|
/*=============================================================================
|
|
= Class: ItemListModel
|
|
= Filter proxy model containing all items (alarms/templates) of specified mime
|
|
= types in enabled collections.
|
|
=============================================================================*/
|
|
ItemListModel::ItemListModel(CalEvent::Types allowed, QObject* parent)
|
|
: EntityMimeTypeFilterModel(parent),
|
|
mAllowedTypes(allowed),
|
|
mHaveEvents(false)
|
|
{
|
|
KSelectionProxyModel* selectionModel = new KSelectionProxyModel(CollectionControlModel::instance()->selectionModel(), this);
|
|
selectionModel->setSourceModel(AkonadiModel::instance());
|
|
selectionModel->setFilterBehavior(KSelectionProxyModel::ChildrenOfExactSelection);
|
|
setSourceModel(selectionModel);
|
|
|
|
addMimeTypeExclusionFilter(Collection::mimeType());
|
|
setHeaderGroup(EntityTreeModel::ItemListHeaders);
|
|
if (allowed)
|
|
{
|
|
QStringList mimeTypes = CalEvent::mimeTypes(allowed);
|
|
foreach (const QString& mime, mimeTypes)
|
|
addMimeTypeInclusionFilter(mime);
|
|
}
|
|
setHeaderGroup(EntityTreeModel::ItemListHeaders);
|
|
setSortRole(AkonadiModel::SortRole);
|
|
setDynamicSortFilter(true);
|
|
connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(slotRowsInserted()));
|
|
connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(slotRowsRemoved()));
|
|
connect(AkonadiModel::instance(), SIGNAL(collectionStatusChanged(Akonadi::Collection,AkonadiModel::Change,QVariant,bool)),
|
|
SLOT(collectionStatusChanged(Akonadi::Collection,AkonadiModel::Change,QVariant,bool)));
|
|
}
|
|
|
|
int ItemListModel::columnCount(const QModelIndex& /*parent*/) const
|
|
{
|
|
return AkonadiModel::ColumnCount;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Called when rows have been inserted into the model.
|
|
*/
|
|
void ItemListModel::slotRowsInserted()
|
|
{
|
|
if (!mHaveEvents && rowCount())
|
|
{
|
|
mHaveEvents = true;
|
|
emit haveEventsStatus(true);
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Called when rows have been deleted from the model.
|
|
*/
|
|
void ItemListModel::slotRowsRemoved()
|
|
{
|
|
if (mHaveEvents && !rowCount())
|
|
{
|
|
mHaveEvents = false;
|
|
emit haveEventsStatus(false);
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Called when a collection parameter or status has changed.
|
|
* If the collection's enabled status has changed, re-filter the list to add or
|
|
* remove its alarms.
|
|
*/
|
|
void ItemListModel::collectionStatusChanged(const Collection& collection, AkonadiModel::Change change, const QVariant&, bool inserted)
|
|
{
|
|
Q_UNUSED(inserted);
|
|
if (!collection.isValid())
|
|
return;
|
|
if (change == AkonadiModel::Enabled)
|
|
{
|
|
// Ensure that items for a newly enabled collection are always ordered
|
|
// correctly. Note that invalidateFilter() is not adequate for this.
|
|
invalidate();
|
|
}
|
|
}
|
|
|
|
bool ItemListModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
|
|
{
|
|
if (!EntityMimeTypeFilterModel::filterAcceptsRow(sourceRow, sourceParent))
|
|
return false;
|
|
// Get the alarm type of the item
|
|
QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent);
|
|
CalEvent::Type type = static_cast<CalEvent::Type>(sourceModel()->data(sourceIndex, AkonadiModel::StatusRole).toInt());
|
|
Collection parent = sourceIndex.data(AkonadiModel::ParentCollectionRole).value<Collection>();
|
|
return CollectionControlModel::isEnabled(parent, type);
|
|
}
|
|
|
|
#if 0
|
|
QModelIndex ItemListModel::index(int row, int column, const QModelIndex& parent) const
|
|
{
|
|
if (parent.isValid())
|
|
return QModelIndex();
|
|
return createIndex(row, column, mEvents[row]);
|
|
}
|
|
|
|
bool ItemListModel::setData(const QModelIndex& ix, const QVariant&, int role)
|
|
{
|
|
if (ix.isValid() && role == Qt::EditRole)
|
|
{
|
|
//??? update event
|
|
int row = ix.row();
|
|
emit dataChanged(index(row, 0), index(row, AkonadiModel::ColumnCount - 1));
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
Qt::ItemFlags ItemListModel::flags(const QModelIndex& index) const
|
|
{
|
|
if (!index.isValid())
|
|
return Qt::ItemIsEnabled;
|
|
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Return the index to a specified event.
|
|
*/
|
|
QModelIndex ItemListModel::eventIndex(Entity::Id itemId) const
|
|
{
|
|
QModelIndexList list = match(QModelIndex(), AkonadiModel::ItemIdRole, itemId, 1, Qt::MatchExactly | Qt::MatchRecursive);
|
|
if (list.isEmpty())
|
|
return QModelIndex();
|
|
return index(list[0].row(), 0, list[0].parent());
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Return the event in a specified row.
|
|
*/
|
|
KAEvent ItemListModel::event(int row) const
|
|
{
|
|
return event(index(row, 0));
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Return the event referred to by an index.
|
|
*/
|
|
KAEvent ItemListModel::event(const QModelIndex& index) const
|
|
{
|
|
return static_cast<AkonadiModel*>(sourceModel())->event(mapToSource(index));
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Check whether the model contains any events.
|
|
*/
|
|
bool ItemListModel::haveEvents() const
|
|
{
|
|
return rowCount();
|
|
}
|
|
|
|
|
|
/*=============================================================================
|
|
= Class: AlarmListModel
|
|
= Filter proxy model containing all alarms (not templates) of specified mime
|
|
= types in enabled collections.
|
|
Equivalent to AlarmListFilterModel
|
|
=============================================================================*/
|
|
AlarmListModel* AlarmListModel::mAllInstance = 0;
|
|
|
|
AlarmListModel::AlarmListModel(QObject* parent)
|
|
: ItemListModel(CalEvent::ACTIVE | CalEvent::ARCHIVED, parent),
|
|
mFilterTypes(CalEvent::ACTIVE | CalEvent::ARCHIVED)
|
|
{
|
|
}
|
|
|
|
AlarmListModel::~AlarmListModel()
|
|
{
|
|
if (this == mAllInstance)
|
|
mAllInstance = 0;
|
|
}
|
|
|
|
AlarmListModel* AlarmListModel::all()
|
|
{
|
|
if (!mAllInstance)
|
|
{
|
|
mAllInstance = new AlarmListModel(AkonadiModel::instance());
|
|
mAllInstance->sort(TimeColumn, Qt::AscendingOrder);
|
|
}
|
|
return mAllInstance;
|
|
}
|
|
|
|
void AlarmListModel::setEventTypeFilter(CalEvent::Types types)
|
|
{
|
|
// Ensure that the filter isn't applied to the 'all' instance, and that
|
|
// 'types' doesn't include any disallowed alarm types
|
|
if (!types)
|
|
types = includedTypes();
|
|
if (this != mAllInstance
|
|
&& types != mFilterTypes && (types & includedTypes()) == types)
|
|
{
|
|
mFilterTypes = types;
|
|
invalidateFilter();
|
|
}
|
|
}
|
|
|
|
bool AlarmListModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
|
|
{
|
|
if (!ItemListModel::filterAcceptsRow(sourceRow, sourceParent))
|
|
return false;
|
|
if (mFilterTypes == CalEvent::EMPTY)
|
|
return false;
|
|
int type = sourceModel()->data(sourceModel()->index(sourceRow, 0, sourceParent), AkonadiModel::StatusRole).toInt();
|
|
return static_cast<CalEvent::Type>(type) & mFilterTypes;
|
|
}
|
|
|
|
bool AlarmListModel::filterAcceptsColumn(int sourceCol, const QModelIndex&) const
|
|
{
|
|
return (sourceCol != AkonadiModel::TemplateNameColumn);
|
|
}
|
|
|
|
QVariant AlarmListModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
{
|
|
if (orientation == Qt::Horizontal)
|
|
{
|
|
if (section < 0 || section >= ColumnCount)
|
|
return QVariant();
|
|
}
|
|
return ItemListModel::headerData(section, orientation, role);
|
|
}
|
|
|
|
|
|
/*=============================================================================
|
|
= Class: TemplateListModel
|
|
= Filter proxy model containing all alarm templates for specified alarm types
|
|
= in enabled collections.
|
|
Equivalent to TemplateListFilterModel
|
|
=============================================================================*/
|
|
TemplateListModel* TemplateListModel::mAllInstance = 0;
|
|
|
|
TemplateListModel::TemplateListModel(QObject* parent)
|
|
: ItemListModel(CalEvent::TEMPLATE, parent),
|
|
mActionsEnabled(KAEvent::ACT_ALL),
|
|
mActionsFilter(KAEvent::ACT_ALL)
|
|
{
|
|
}
|
|
|
|
TemplateListModel::~TemplateListModel()
|
|
{
|
|
if (this == mAllInstance)
|
|
mAllInstance = 0;
|
|
}
|
|
|
|
TemplateListModel* TemplateListModel::all()
|
|
{
|
|
if (!mAllInstance)
|
|
{
|
|
mAllInstance = new TemplateListModel(AkonadiModel::instance());
|
|
mAllInstance->sort(TemplateNameColumn, Qt::AscendingOrder);
|
|
}
|
|
return mAllInstance;
|
|
}
|
|
|
|
void TemplateListModel::setAlarmActionFilter(KAEvent::Actions types)
|
|
{
|
|
// Ensure that the filter isn't applied to the 'all' instance.
|
|
if (this != mAllInstance && types != mActionsFilter)
|
|
{
|
|
mActionsFilter = types;
|
|
filterChanged();
|
|
}
|
|
}
|
|
|
|
void TemplateListModel::setAlarmActionsEnabled(KAEvent::Actions types)
|
|
{
|
|
// Ensure that the setting isn't applied to the 'all' instance.
|
|
if (this != mAllInstance && types != mActionsEnabled)
|
|
{
|
|
mActionsEnabled = types;
|
|
filterChanged();
|
|
}
|
|
}
|
|
|
|
bool TemplateListModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
|
|
{
|
|
if (!ItemListModel::filterAcceptsRow(sourceRow, sourceParent))
|
|
return false;
|
|
if (mActionsFilter == KAEvent::ACT_ALL)
|
|
return true;
|
|
QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent);
|
|
KAEvent::Actions actions = static_cast<KAEvent::Actions>(sourceModel()->data(sourceIndex, AkonadiModel::AlarmActionsRole).toInt());
|
|
return actions & mActionsFilter;
|
|
}
|
|
|
|
bool TemplateListModel::filterAcceptsColumn(int sourceCol, const QModelIndex&) const
|
|
{
|
|
return sourceCol == AkonadiModel::TemplateNameColumn
|
|
|| sourceCol == AkonadiModel::TypeColumn;
|
|
}
|
|
|
|
QVariant TemplateListModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
{
|
|
if (orientation == Qt::Horizontal)
|
|
{
|
|
switch (section)
|
|
{
|
|
case TypeColumn:
|
|
section = AkonadiModel::TypeColumn;
|
|
break;
|
|
case TemplateNameColumn:
|
|
section = AkonadiModel::TemplateNameColumn;
|
|
break;
|
|
default:
|
|
return QVariant();
|
|
}
|
|
}
|
|
return ItemListModel::headerData(section, orientation, role);
|
|
}
|
|
|
|
Qt::ItemFlags TemplateListModel::flags(const QModelIndex& index) const
|
|
{
|
|
Qt::ItemFlags f = sourceModel()->flags(mapToSource(index));
|
|
if (mActionsEnabled == KAEvent::ACT_ALL)
|
|
return f;
|
|
KAEvent::Actions actions = static_cast<KAEvent::Actions>(ItemListModel::data(index, AkonadiModel::AlarmActionsRole).toInt());
|
|
if (!(actions & mActionsEnabled))
|
|
f = static_cast<Qt::ItemFlags>(f & ~(Qt::ItemIsEnabled | Qt::ItemIsSelectable));
|
|
return f;
|
|
}
|
|
|
|
// vim: et sw=4:
|