Commit 8c5207b6 authored by Tobias Koenig's avatar Tobias Koenig

Create new library akonadi-contact

This library will contain a contact editor, a contact viewer
and several contact specific commands. It is supposed to be
moved to kdepimlibs/akonadi/kabc/ later on

svn path=/trunk/KDE/kdepim/akonadi/contact/; revision=1010350
parent 1ebc682c
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII ${KDE4_ENABLE_EXCEPTIONS}")
########### next target ###############
set(akonadicontact_editor_SRCS
editor/addresseditwidget.cpp
editor/contacteditorwidget.cpp
editor/dateeditwidget.cpp
editor/displaynameeditwidget.cpp
editor/emaileditwidget.cpp
editor/freebusyeditwidget.cpp
editor/imagewidget.cpp
editor/imeditwidget.cpp
editor/nameeditwidget.cpp
editor/phoneeditwidget.cpp
editor/secrecyeditwidget.cpp
editor/soundeditwidget.cpp
)
set(akonadicontact_LIB_SRC
collectioncombobox.cpp
collectionfiltermodel.cpp
contacteditor.cpp
contacteditordialog.cpp
contactgroupeditor.cpp
contactgroupeditordialog.cpp
contactgrouplineedit.cpp
waitingoverlay.cpp
${akonadicontact_editor_SRCS}
)
qt4_wrap_ui(akonadicontact_LIB_SRC contactgroupeditor.ui)
kde4_add_library(akonadi-contact SHARED ${akonadicontact_LIB_SRC})
target_link_libraries(akonadi-contact ${KDEPIMLIBS_AKONADI_LIBS}
${KDEPIMLIBS_KABC_LIBS}
${KDEPIMLIBS_KCAL_LIBS}
${KDE4_KDEUI_LIBS}
${KDE4_KIO_LIBS}
${KDE4_PHONON_LIBS}
kdepim-copy)
target_link_libraries(akonadi-contact LINK_INTERFACE_LIBRARIES ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_KABC_LIBS} ${KDE4_KDEUI_LIBS})
set_target_properties(akonadi-contact PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION})
install(TARGETS akonadi-contact ${INSTALL_TARGETS_DEFAULT_ARGS})
/*
This file is part of Akonadi Contact.
Copyright (c) 2009 Tobias Koenig <tokoe@kde.org>
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.
*/
#ifndef AKONADI_ABSTRACTCONTACTEDITORWIDGET_H
#define AKONADI_ABSTRACTCONTACTEDITORWIDGET_H
#include <QtGui/QWidget>
namespace KABC
{
class Addressee;
}
namespace Akonadi
{
class AbstractContactEditorWidget : public QWidget
{
public:
virtual void loadContact( const KABC::Addressee &contact ) = 0;
virtual void storeContact( KABC::Addressee &contact ) const = 0;
};
}
#endif
/* This file is part of the KDE project
Copyright (C) 2007 David Faure <faure@kde.org>
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.
*/
#ifndef AKONADI_CONTACT_EXPORT_H
#define AKONADI_CONTACT_EXPORT_H
/* needed for KDE_EXPORT and KDE_IMPORT macros */
#include <kdemacros.h>
#ifndef AKONADI_CONTACT_EXPORT
# if defined(MAKE_AKONADI_CONTACT_LIB)
/* We are building this library */
# define AKONADI_CONTACT_EXPORT KDE_EXPORT
# else
/* We are using this library */
# define AKONADI_CONTACT_EXPORT KDE_IMPORT
# endif
#endif
#endif
/*
Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
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 "collectioncombobox.h"
#include <QtCore/QAbstractItemModel>
#include <QtGui/QComboBox>
#include <QtGui/QVBoxLayout>
#include <akonadi/entitytreemodel.h>
using namespace Akonadi;
class CollectionComboBox::Private
{
public:
Private( CollectionComboBox *parent )
: mParent( parent )
{
}
void activated( int index );
CollectionComboBox *mParent;
QComboBox *mComboBox;
};
void CollectionComboBox::Private::activated( int index )
{
if ( !mComboBox->model() )
return;
const QModelIndex modelIndex = mComboBox->model()->index( index, 0 );
if ( modelIndex.isValid() )
emit mParent->selectionChanged( modelIndex.data( EntityTreeModel::CollectionRole).value<Collection>() );
}
CollectionComboBox::CollectionComboBox( QWidget *parent )
: QWidget( parent ), d( new Private( this ) )
{
QVBoxLayout *layout = new QVBoxLayout( this );
layout->setMargin( 0 );
layout->setSpacing( 0 );
d->mComboBox = new QComboBox( this );
layout->addWidget( d->mComboBox );
connect( d->mComboBox, SIGNAL( activated( int ) ), SLOT( activated( int ) ) );
}
CollectionComboBox::~CollectionComboBox()
{
delete d;
}
void CollectionComboBox::setModel( QAbstractItemModel *model )
{
d->mComboBox->setModel( model );
}
Akonadi::Collection CollectionComboBox::selectedCollection() const
{
Q_ASSERT_X( d->mComboBox->model() != 0, "CollectionComboBox::selectionChanged", "No model set!" );
int index = d->mComboBox->currentIndex();
const QModelIndex modelIndex = d->mComboBox->model()->index( index, 0 );
if ( modelIndex.isValid() )
return modelIndex.data( Akonadi::EntityTreeModel::CollectionRole ).value<Collection>();
else
return Akonadi::Collection();
}
#include "collectioncombobox.moc"
/*
Copyright (c) 2007-2009 Tobias Koenig <tokoe@kde.org>
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.
*/
#ifndef AKONADI_COLLECTIONCOMBOBOX_H
#define AKONADI_COLLECTIONCOMBOBOX_H
#include "akonadi-contact_export.h"
#include <QtGui/QWidget>
#include <akonadi/collection.h>
class QAbstractItemModel;
namespace Akonadi {
/**
* @short A combobox for selecting an Akonadi collection.
*
* @author Tobias Koenig <tokoe@kde.org>
*/
class AKONADI_CONTACT_EXPORT CollectionComboBox : public QWidget
{
Q_OBJECT
public:
/**
* Creates a new collection combobox.
*
* @param parent The parent widget.
*/
CollectionComboBox( QWidget *parent = 0 );
/**
* Destroys the collection combobox.
*/
~CollectionComboBox();
/**
* Sets the collection model.
*/
void setModel( QAbstractItemModel *model );
/**
* Returns the identifier of the selected collection
*/
Akonadi::Collection selectedCollection() const;
Q_SIGNALS:
/**
* This signal is emitted whenever the selected collection changed.
*
* @param identifier The identifier of the selected collection.
*/
void selectionChanged( const Akonadi::Collection &identifier );
private:
//@cond PRIVATE
class Private;
Private* const d;
Q_PRIVATE_SLOT( d, void activated( int ) )
//@endcond
};
}
#endif
/*
Copyright (c) 2009 Tobias Koenig <tokoe@kde.org>
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 "collectionfiltermodel_p.h"
#include <akonadi/entitytreemodel.h>
CollectionFilterModel::CollectionFilterModel( QObject *parent )
: QSortFilterProxyModel( parent ), mRights( Akonadi::Collection::ReadOnly )
{
}
void CollectionFilterModel::addContentMimeTypeFilter( const QString &mimeType )
{
mContentMimeTypes.insert( mimeType );
invalidateFilter();
}
void CollectionFilterModel::setRightsFilter( Akonadi::Collection::Rights rights )
{
mRights = rights;
invalidateFilter();
}
bool CollectionFilterModel::filterAcceptsRow( int row, const QModelIndex &parent ) const
{
bool accepted = true;
const QModelIndex index = sourceModel()->index( row, 0, parent );
const Akonadi::Collection collection = index.data( Akonadi::EntityTreeModel::CollectionRole ).value<Akonadi::Collection>();
if ( !collection.isValid() )
return false;
if ( !mContentMimeTypes.isEmpty() ) {
QSet<QString> contentMimeTypes = collection.contentMimeTypes().toSet();
qDebug() << collection.name() << "contentMimeTypes" << contentMimeTypes;
accepted = accepted && !(contentMimeTypes.intersect( mContentMimeTypes ).isEmpty());
}
accepted = accepted && (collection.rights() & mRights);
return accepted;
}
#include "collectionfiltermodel_p.moc"
/*
Copyright (c) 2009 Tobias Koenig <tokoe@kde.org>
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.
*/
#ifndef COLLECTIONFILTERMODEL_H
#define COLLECTIONFILTERMODEL_H
#include <QtGui/QSortFilterProxyModel>
#include <akonadi/collection.h>
/**
* @short A filter model for Akonadi collections.
*
* This proxy model filters Akonadi collections by content
* mime type and rights.
* It works on a flat list of collections, so a EntityTreeModel
* has to be adapted by using Akonadi::DescendantsProxyModel.
*
* @author Tobias Koenig <tokoe@kde.org>
*/
class CollectionFilterModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
/**
* Creates a new collection filter model.
*
* @param parent The parent object.
*/
CollectionFilterModel( QObject *parent );
/**
* Adds a mime type to the content mime type filter list.
*
* If a mime type has been added, only collections that contain
* this mime type in their content mime types will be listed by
* this proxy model.
*/
void addContentMimeTypeFilter( const QString &mimeType );
/**
* Sets the collection @p rights filter.
*
* Only collections that allows this rights combination
* will be listed by this proxy model.
*/
void setRightsFilter( Akonadi::Collection::Rights rights );
protected:
virtual bool filterAcceptsRow( int row, const QModelIndex &parent ) const;
private:
QSet<QString> mContentMimeTypes;
Akonadi::Collection::Rights mRights;
};
#endif
/*
This file is part of Akonadi Contact.
Copyright (c) 2009 Tobias Koenig <tokoe@kde.org>
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 "contacteditor.h"
#include "abstractcontacteditorwidget.h"
#include <akonadi/itemcreatejob.h>
#include <akonadi/itemfetchjob.h>
#include <akonadi/itemfetchscope.h>
#include <akonadi/itemmodifyjob.h>
#include <akonadi/monitor.h>
#include <akonadi/session.h>
#include <kabc/addressee.h>
#include <klocale.h>
#include <QtGui/QVBoxLayout>
#include <QtGui/QMessageBox>
using namespace Akonadi;
class ContactEditor::Private
{
public:
Private( ContactEditor *parent )
: mParent( parent ), mMonitor( 0 )
{
}
~Private()
{
delete mMonitor;
}
void fetchDone( KJob* );
void storeDone( KJob* );
void itemChanged( const Akonadi::Item &item, const QSet<QByteArray>& );
void loadContact( const KABC::Addressee &addr );
void storeContact( KABC::Addressee &addr );
void setupMonitor();
ContactEditor *mParent;
ContactEditor::Mode mMode;
Akonadi::Item mItem;
Akonadi::Monitor *mMonitor;
Akonadi::Collection mDefaultCollection;
AbstractContactEditorWidget *mEditorWidget;
};
void ContactEditor::Private::fetchDone( KJob *job )
{
if ( job->error() != KJob::NoError )
return;
Akonadi::ItemFetchJob *fetchJob = qobject_cast<Akonadi::ItemFetchJob*>( job );
if ( !fetchJob )
return;
if ( fetchJob->items().isEmpty() )
return;
mItem = fetchJob->items().first();
const KABC::Addressee addr = mItem.payload<KABC::Addressee>();
loadContact( addr );
}
void ContactEditor::Private::storeDone( KJob *job )
{
if ( job->error() != KJob::NoError ) {
emit mParent->error( job->errorString() );
return;
}
if ( mMode == EditMode )
emit mParent->contactStored( mItem );
else if ( mMode == CreateMode )
emit mParent->contactStored( static_cast<Akonadi::ItemCreateJob*>( job )->item() );
}
void ContactEditor::Private::itemChanged( const Akonadi::Item&, const QSet<QByteArray>& )
{
QMessageBox dlg( mParent );
dlg.setInformativeText( QLatin1String( "The contact has been changed by anyone else\nWhat shall be done?" ) );
dlg.addButton( i18n( "Take over changes" ), QMessageBox::AcceptRole );
dlg.addButton( i18n( "Ignore and Overwrite changes" ), QMessageBox::RejectRole );
if ( dlg.exec() == QMessageBox::AcceptRole ) {
Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( mItem );
job->fetchScope().fetchFullPayload();
mParent->connect( job, SIGNAL( result( KJob* ) ), mParent, SLOT( fetchDone( KJob* ) ) );
}
}
void ContactEditor::Private::loadContact( const KABC::Addressee &addr )
{
mEditorWidget->loadContact( addr );
}
void ContactEditor::Private::storeContact( KABC::Addressee &addr )
{
mEditorWidget->storeContact( addr );
}
void ContactEditor::Private::setupMonitor()
{
delete mMonitor;
mMonitor = new Akonadi::Monitor;
mMonitor->ignoreSession( Akonadi::Session::defaultSession() );
connect( mMonitor, SIGNAL( itemChanged( const Akonadi::Item&, const QSet<QByteArray>& ) ),
mParent, SLOT( itemChanged( const Akonadi::Item&, const QSet<QByteArray>& ) ) );
}
ContactEditor::ContactEditor( Mode mode, AbstractContactEditorWidget *editorWidget, QWidget *parent )
: QWidget( parent ), d( new Private( this ) )
{
d->mMode = mode;
d->mEditorWidget = editorWidget;
QVBoxLayout *layout = new QVBoxLayout( this );
layout->setMargin( 0 );
layout->setSpacing( 0 );
layout->addWidget( d->mEditorWidget );
}
ContactEditor::~ContactEditor()
{
delete d;
}
void ContactEditor::loadContact( const Akonadi::Item &item )
{
if ( d->mMode == CreateMode )
Q_ASSERT_X( false, "ContactEditor::loadContact", "You are calling loadContact in CreateMode!" );
Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( item );
job->fetchScope().fetchFullPayload();
connect( job, SIGNAL( result( KJob* ) ), SLOT( fetchDone( KJob* ) ) );
d->setupMonitor();
d->mMonitor->setItemMonitored( item );
}
void ContactEditor::saveContact()
{
if ( d->mMode == EditMode ) {
if ( !d->mItem.isValid() )
return;
KABC::Addressee addr = d->mItem.payload<KABC::Addressee>();
d->storeContact( addr );
d->mItem.setPayload<KABC::Addressee>( addr );
Akonadi::ItemModifyJob *job = new Akonadi::ItemModifyJob( d->mItem );
connect( job, SIGNAL( result( KJob* ) ), SLOT( storeDone( KJob* ) ) );
} else if ( d->mMode == CreateMode ) {