kde-playground/kdepim-runtime/kresources/kcal/resourceakonadi.cpp
2015-04-14 22:08:21 +00:00

452 lines
12 KiB
C++

/*
This file is part of libkcal.
Copyright (c) 2008-2009 Kevin Krammer <kevin.krammer@gmx.at>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "resourceakonadi.h"
#include "resourceakonadi_p.h"
#include "resourceakonadiconfig.h"
#include <kabc/locknull.h>
#include <kcal/calendarlocal.h>
#include <akonadi/agentfilterproxymodel.h>
#include <akonadi/agentinstance.h>
#include <akonadi/agentinstancemodel.h>
#include <KDebug>
using namespace Akonadi;
using namespace KCal;
typedef boost::shared_ptr<Incidence> IncidencePtr;
ResourceAkonadi::ResourceAkonadi()
: ResourceCalendar(), d( new Private( this ) )
{
}
ResourceAkonadi::ResourceAkonadi( const KConfigGroup &group )
: ResourceCalendar( group ), d( new Private( group, this ) )
{
KGlobal::locale()->insertCatalog("kresources_shared_akonadi");
}
ResourceAkonadi::~ResourceAkonadi()
{
delete d;
}
void ResourceAkonadi::writeConfig( KConfigGroup &group )
{
ResourceCalendar::writeConfig( group );
d->writeConfig( group );
}
StoreConfigIface &ResourceAkonadi::storeConfig()
{
return *d;
}
KABC::Lock *ResourceAkonadi::lock()
{
return d->mLock;
}
bool ResourceAkonadi::addEvent( Event *event )
{
const QString uid = event->uid();
const QString mimeType = d->mMimeVisitor.mimeType( event );
kDebug( 5800 ) << "Event (uid=" << uid
<< ", summary=" << event->summary()
<< ")";
if ( d->addLocalItem( uid, mimeType ) ) {
return d->mCalendar.addEvent( event );
}
return false;
}
bool ResourceAkonadi::deleteEvent( Event *event )
{
return d->mCalendar.deleteEvent( event );
}
void ResourceAkonadi::deleteAllEvents()
{
d->mCalendar.deleteAllEvents();
}
Event *ResourceAkonadi::event( const QString &uid )
{
return d->mCalendar.event( uid );
}
Event::List ResourceAkonadi::rawEvents( EventSortField sortField,
SortDirection sortDirection )
{
return d->mCalendar.rawEvents( sortField, sortDirection );
}
Event::List ResourceAkonadi::rawEventsForDate( const QDate &date,
const KDateTime::Spec &timespec,
EventSortField sortField,
SortDirection sortDirection )
{
return d->mCalendar.rawEventsForDate( date, timespec, sortField, sortDirection );
}
Event::List ResourceAkonadi::rawEventsForDate( const KDateTime &date )
{
return d->mCalendar.rawEventsForDate( date );
}
Event::List ResourceAkonadi::rawEvents( const QDate &start, const QDate &end,
const KDateTime::Spec &timespec,
bool inclusive )
{
return d->mCalendar.rawEvents( start, end, timespec, inclusive );
}
bool ResourceAkonadi::addTodo( Todo *todo )
{
const QString uid = todo->uid();
const QString mimeType = d->mMimeVisitor.mimeType( todo );
kDebug( 5800 ) << "Todo (uid=" << uid
<< ", summary=" << todo->summary()
<< ")";
if ( d->addLocalItem( uid, mimeType ) ) {
return d->mCalendar.addTodo( todo );
}
return false;
}
bool ResourceAkonadi::deleteTodo( Todo *todo )
{
return d->mCalendar.deleteTodo( todo );
}
void ResourceAkonadi::deleteAllTodos()
{
d->mCalendar.deleteAllTodos();
}
Todo *ResourceAkonadi::todo( const QString &uid )
{
return d->mCalendar.todo( uid );
}
Todo::List ResourceAkonadi::rawTodos( TodoSortField sortField,
SortDirection sortDirection )
{
return d->mCalendar.rawTodos( sortField, sortDirection );
}
Todo::List ResourceAkonadi::rawTodosForDate( const QDate &date )
{
return d->mCalendar.rawTodosForDate( date );
}
bool ResourceAkonadi::addJournal( Journal *journal )
{
const QString uid = journal->uid();
const QString mimeType = d->mMimeVisitor.mimeType( journal );
kDebug( 5800 ) << "Journal (uid=" << uid
<< ", summary=" << journal->summary()
<< ")";
if ( d->addLocalItem( uid, mimeType ) ) {
return d->mCalendar.addJournal( journal );
}
return false;
}
bool ResourceAkonadi::deleteJournal( Journal *journal )
{
return d->mCalendar.deleteJournal( journal );
}
void ResourceAkonadi::deleteAllJournals()
{
d->mCalendar.deleteAllJournals();
}
Journal *ResourceAkonadi::journal( const QString &uid )
{
return d->mCalendar.journal( uid );
}
Journal::List ResourceAkonadi::rawJournals( JournalSortField sortField,
SortDirection sortDirection )
{
return d->mCalendar.rawJournals( sortField, sortDirection );
}
Journal::List ResourceAkonadi::rawJournalsForDate( const QDate &date )
{
return d->mCalendar.rawJournalsForDate( date );
}
Alarm::List ResourceAkonadi::alarms( const KDateTime &from, const KDateTime &to )
{
return d->mCalendar.alarms( from, to );
}
Alarm::List ResourceAkonadi::alarmsTo( const KDateTime &to )
{
return d->mCalendar.alarmsTo( to );
}
void ResourceAkonadi::setTimeSpec( const KDateTime::Spec &timeSpec )
{
d->mCalendar.setTimeSpec( timeSpec );
}
KDateTime::Spec ResourceAkonadi::timeSpec() const
{
return d->mCalendar.timeSpec();
}
void ResourceAkonadi::setTimeZoneId( const QString &timeZoneId )
{
d->mCalendar.setTimeZoneId( timeZoneId );
}
QString ResourceAkonadi::timeZoneId() const
{
return d->mCalendar.timeZoneId();
}
void ResourceAkonadi::shiftTimes( const KDateTime::Spec &oldSpec,
const KDateTime::Spec &newSpec )
{
d->mCalendar.shiftTimes( oldSpec, newSpec );
}
bool ResourceAkonadi::canHaveSubresources() const
{
return true;
}
QString ResourceAkonadi::labelForSubresource( const QString &subResource ) const
{
kDebug( 5800 ) << "subresource=" << subResource;
QString label;
SubResource *resource = d->subResource( subResource );
if ( resource != 0 ) {
label = resource->label();
}
return label;
}
void ResourceAkonadi::setSubresourceActive( const QString &subResource, bool active )
{
kDebug( 5800 ) << "subResource" << subResource << ", active" << active;
// TODO might no longer be necessary
bool changed = false;
SubResource *resource = d->subResource( subResource );
if ( resource != 0 ) {
if ( active != resource->isActive() ) {
resource->setActive( active );
changed = true;
}
}
if ( changed ) {
emit resourceChanged( this );
}
}
bool ResourceAkonadi::subresourceActive( const QString &subResource ) const
{
bool active = false;
SubResource *resource = d->subResource( subResource );
if ( resource != 0 ) {
active = resource->isActive();
}
return active;
}
bool ResourceAkonadi::subresourceWritable( const QString &subResource ) const
{
bool writable = false;
SubResource *resource = d->subResource( subResource );
if ( resource != 0 ) {
writable = resource->isWritable();
}
return writable;
}
bool ResourceAkonadi::addSubresource( const QString &resource, const QString &parent )
{
kDebug( 5800 ) << "resource=" << resource << ", parent=" << parent;
Q_ASSERT( !resource.isEmpty() );
if ( parent.isEmpty() ) {
kError( 5800 ) << "Cannot create Akonadi toplevel collection";
// TODO probably display a dialog working on the agent filter proxy model
// and then create and name the resource appropriately.
return false;
}
SubResource *subResource = d->subResource( parent );
if ( subResource == 0 ) {
kError( 5800 ) << "No such parent subresource/collection:" << parent;
return false;
}
return subResource->createChildSubResource( resource );
}
bool ResourceAkonadi::removeSubresource( const QString &resource )
{
kDebug( 5800 ) << "resource=" << resource;
Q_ASSERT( !resource.isEmpty() );
SubResource *subResource = d->subResource( resource );
if ( subResource == 0 ) {
kError( 5800 ) << "No such subresource: " << resource;
return false;
}
return subResource->remove();
}
QString ResourceAkonadi::subresourceType( const QString &resource )
{
kDebug( 5800 ) << "resource=" << resource;
QString type;
SubResource *subResource = d->subResource( resource );
if ( subResource != 0 ) {
type = subResource->subResourceType();
}
return type;
}
QString ResourceAkonadi::subresourceIdentifier( Incidence *incidence )
{
return d->subResourceIdentifier( incidence->uid() );
}
QStringList ResourceAkonadi::subresources() const
{
kDebug( 5800 ) << d->subResourceIdentifiers();
return d->subResourceIdentifiers();
}
QString ResourceAkonadi::infoText() const
{
const QString online = i18nc( "@info access to the source's backend possible", "Online" );
const QString offline = i18nc( "@info currently no access to the source's backend possible",
"Offline" );
const QLatin1String br( "<br>" );
QString text = i18nc( "@info:tooltip visible name of the resource",
"<title>%1</title>", resourceName() );
text += i18nc( "@info:tooltip resource type", "Type: Akonadi Calendar Resource" ) + br;
const int rowCount = d->mAgentFilterModel->rowCount();
for ( int row = 0; row < rowCount; ++row ) {
QModelIndex index = d->mAgentFilterModel->index( row, 0 );
if ( index.isValid() ) {
QVariant data = d->mAgentFilterModel->data( index, AgentInstanceModel::InstanceRole );
if ( data.isValid() ) {
AgentInstance instance = data.value<AgentInstance>();
if ( instance.isValid() ) {
// TODO probably add progress if "Running"
QString status = instance.statusMessage();
text += br;
text += i18nc( "@info:tooltip name of a calendar data source",
"<resource>%1</resource>", instance.name() ) + br;
text += i18nc( "@info:tooltip status of a calendar data source and its "
"online/offline state",
"Status: %1 (%2)", status,
( instance.isOnline() ? online : offline ) ) + br;
}
}
}
}
return text;
}
bool ResourceAkonadi::doLoad( bool syncCache )
{
kDebug( 5800 ) << "syncCache=" << syncCache;
d->clear();
return d->doLoad();
}
bool ResourceAkonadi::doSave( bool syncCache )
{
kDebug( 5800 ) << "syncCache=" << syncCache;
return d->doSave();
}
bool ResourceAkonadi::doSave( bool syncCache, Incidence *incidence )
{
kDebug( 5800 ) << "syncCache=" << syncCache
<< ", incidence" << incidence->uid();
return d->doSaveIncidence( incidence );
}
bool ResourceAkonadi::doOpen()
{
return d->doOpen();
}
void ResourceAkonadi::doClose()
{
// this clear() should not emit resourceChanged inspite of incidence pointers becoming
// invalid. None of the other resources to it and bug 196215 suggests it can even lead
// to crashes
bool blocked = blockSignals( true );
d->clear();
blockSignals( blocked );
d->doClose();
}
bool ResourceAkonadi::readOnly() const
{
return d->isReadOnly();
}
// kate: space-indent on; indent-width 2; replace-tabs on;