Commit ceb97c90 authored by Tobias Koenig's avatar Tobias Koenig

Extract the formatting of a contact group into its own class.

This is symetric to the contact formatter

svn path=/trunk/KDE/kdepimlibs/; revision=1156619
parent 65df9ae0
......@@ -53,6 +53,7 @@ set(akonadicontact_editor_SRCS
set(akonadicontact_LIB_SRC
abstractcontactformatter.cpp
abstractcontactgroupformatter.cpp
attributeregistrar.cpp
collectionfiltermodel.cpp
contactcompletionmodel.cpp
......@@ -85,6 +86,7 @@ set(akonadicontact_LIB_SRC
recentcontactscollections.cpp
recentcontactscollectionrequestjob.cpp
standardcontactformatter.cpp
standardcontactgroupformatter.cpp
waitingoverlay.cpp
${akonadicontact_actions_SRCS}
)
......@@ -138,6 +140,7 @@ install(FILES recentcontactscollections.kcfg DESTINATION ${KCFG_INSTALL_DIR} )
install( FILES
abstractcontactformatter.h
abstractcontactgroupformatter.h
akonadi-contact_export.h
contactdefaultactions.h
contacteditor.h
......@@ -159,5 +162,6 @@ install( FILES
emailaddressselectionwidget.h
recentcontactscollectionrequestjob.h
standardcontactformatter.h
standardcontactgroupformatter.h
DESTINATION ${INCLUDE_INSTALL_DIR}/akonadi/contact COMPONENT Devel
)
/*
This file is part of Akonadi Contact.
Copyright (c) 2010 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 "abstractcontactgroupformatter.h"
#include <akonadi/item.h>
#include <kabc/contactgroup.h>
using namespace Akonadi;
class AbstractContactGroupFormatter::Private
{
public:
KABC::ContactGroup mContactGroup;
Akonadi::Item mItem;
QList<QVariantMap> mAdditionalFields;
};
AbstractContactGroupFormatter::AbstractContactGroupFormatter()
: d( new Private )
{
}
AbstractContactGroupFormatter::~AbstractContactGroupFormatter()
{
delete d;
}
void AbstractContactGroupFormatter::setContactGroup( const KABC::ContactGroup &group )
{
d->mContactGroup = group;
}
KABC::ContactGroup AbstractContactGroupFormatter::contactGroup() const
{
return d->mContactGroup;
}
void AbstractContactGroupFormatter::setItem( const Akonadi::Item &item )
{
d->mItem = item;
}
Akonadi::Item AbstractContactGroupFormatter::item() const
{
return d->mItem;
}
void AbstractContactGroupFormatter::setAdditionalFields( const QList<QVariantMap> &fields )
{
d->mAdditionalFields = fields;
}
QList<QVariantMap> AbstractContactGroupFormatter::additionalFields() const
{
return d->mAdditionalFields;
}
/*
This file is part of Akonadi Contact.
Copyright (c) 2010 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_ABSTRACTCONTACTGROUPFORMATTER_H
#define AKONADI_ABSTRACTCONTACTGROUPFORMATTER_H
#include "akonadi-contact_export.h"
#include <QtCore/QVariant>
namespace KABC {
class ContactGroup;
}
namespace Akonadi {
class Item;
/**
* @short The interface for all contact group formatters.
*
* This is the interface that can be used to format an Akonadi
* item with a contact group payload or a contact group itself as HTML.
*
* @see StandardContactGroupFormatter
* @author Tobias Koenig <tokoe@kde.org>
* @since 4.6
*/
class AKONADI_CONTACT_EXPORT AbstractContactGroupFormatter
{
public:
/**
* Describes the form of the HTML that is created.
*/
enum HtmlForm
{
SelfcontainedForm, ///< Creates a complete HTML document
EmbeddableForm, ///< Creates a div HTML element that can be embedded.
UserForm = SelfcontainedForm + 42 ///< Point for extension
};
/**
* Creates a new abstract contact group formatter.
*/
AbstractContactGroupFormatter();
/**
* Destroys the abstract contact group formatter.
*/
virtual ~AbstractContactGroupFormatter();
/**
* Sets the contact @p group that will be formatted.
*/
void setContactGroup( const KABC::ContactGroup &group );
/**
* Returns the contact group that will be formatted.
*/
KABC::ContactGroup contactGroup() const;
/**
* Sets the @p item who's payload will be formatted.
*
* @note The payload must be a valid KABC::ContactGroup object.
*/
void setItem( const Akonadi::Item &item );
/**
* Returns the item who's payload will be formatted.
*/
Akonadi::Item item() const;
/**
* Sets the additional @p fields that will be shown.
*
* The fields list contains a QVariantMap for each additional field
* with the following keys:
* - key (string) The identifier of the field
* - title (string) The i18n'ed title of the field
* - value (string) The value of the field
*/
void setAdditionalFields( const QList<QVariantMap> &fields );
/**
* Returns the additional fields that will be shown.
*/
QList<QVariantMap> additionalFields() const;
/**
* This method must be reimplemented to return the contact group formatted as HTML
* according to the requested @p form.
*/
virtual QString toHtml( HtmlForm form = SelfcontainedForm ) const = 0;
private:
//@cond PRIVATE
Q_DISABLE_COPY( AbstractContactGroupFormatter )
class Private;
Private* const d;
//@endcond
};
}
#endif
......@@ -22,6 +22,7 @@
#include "contactgroupviewer.h"
#include "contactgroupexpandjob.h"
#include "standardcontactgroupformatter.h"
#include "textbrowser_p.h"
#include <akonadi/collectionfetchjob.h>
......@@ -41,9 +42,6 @@
using namespace Akonadi;
static QString contactsAsHtml( const QString &groupName, const KABC::Addressee::List &contacts,
const QString &addressBookName );
class ContactGroupViewer::Private
{
public:
......@@ -56,12 +54,40 @@ class ContactGroupViewer::Private
mBrowser->document()->addResource( QTextDocument::ImageResource,
QUrl( QLatin1String( "group_photo" ) ),
groupPixmap );
mStandardContactGroupFormatter = new StandardContactGroupFormatter;
mContactGroupFormatter = mStandardContactGroupFormatter;
}
~Private()
{
delete mStandardContactGroupFormatter;
}
void updateView()
{
mParent->setWindowTitle( i18n( "Contact Group %1", mCurrentGroupName ) );
mBrowser->setHtml( contactsAsHtml( mCurrentGroupName, mCurrentContacts, mCurrentAddressBookName ) );
KABC::ContactGroup group;
group.setName( mCurrentGroupName );
foreach ( const KABC::Addressee &contact, mCurrentContacts )
group.append( KABC::ContactGroup::Data( contact.realName(), contact.preferredEmail() ) );
mContactGroupFormatter->setContactGroup( group );
QList<QVariantMap> additionalFields;
if ( !mCurrentAddressBookName.isEmpty() ) {
QVariantMap addressBookName;
addressBookName.insert( QLatin1String( "title" ), i18n( "Address Book" ) );
addressBookName.insert( QLatin1String( "value" ), mCurrentAddressBookName );
additionalFields << addressBookName;
}
mContactGroupFormatter->setAdditionalFields( additionalFields );
mBrowser->setHtml( mContactGroupFormatter->toHtml() );
}
void slotMailClicked( const QString&, const QString &email )
......@@ -121,6 +147,8 @@ class ContactGroupViewer::Private
Item mCurrentItem;
ContactGroupExpandJob *mExpandJob;
CollectionFetchJob *mParentCollectionFetchJob;
AbstractContactGroupFormatter *mStandardContactGroupFormatter;
AbstractContactGroupFormatter *mContactGroupFormatter;
};
ContactGroupViewer::ContactGroupViewer( QWidget *parent )
......@@ -156,6 +184,14 @@ void ContactGroupViewer::setContactGroup( const Akonadi::Item &group )
ItemMonitor::setItem( group );
}
void ContactGroupViewer::setContactGroupFormatter( AbstractContactGroupFormatter *formatter )
{
if ( formatter == 0 )
d->mContactGroupFormatter = d->mStandardContactGroupFormatter;
else
d->mContactGroupFormatter = formatter;
}
void ContactGroupViewer::itemChanged( const Item &item )
{
if ( !item.hasPayload<KABC::ContactGroup>() )
......@@ -180,65 +216,4 @@ void ContactGroupViewer::itemRemoved()
d->mBrowser->clear();
}
static QString contactsAsHtml( const QString &groupName, const KABC::Addressee::List &contacts,
const QString &addressBookName )
{
// Assemble all parts
QString strGroup = QString::fromLatin1(
"<table cellpadding=\"1\" cellspacing=\"0\" width=\"100%\">"
"<tr>"
"<td align=\"right\" valign=\"top\" width=\"30%\">"
"<img src=\"%1\" width=\"75\" height=\"105\" vspace=\"1\">" // image
"</td>"
"<td align=\"left\" width=\"70%\"><font size=\"+2\"><b>%2</b></font></td>" // name
"</tr>"
"</table>" )
.arg( QLatin1String( "group_photo" ) )
.arg( groupName );
strGroup += QLatin1String( "<table width=\"100%\">" );
foreach ( const KABC::Addressee &contact, contacts ) {
if ( contact.preferredEmail().isEmpty() ) {
strGroup.append( QString::fromLatin1( "<tr><td align=\"right\" width=\"50%\"><b><font size=\"-1\" color=\"grey\">%1</font></b></td>"
"<td width=\"50%\"></td></tr>" )
.arg( contact.realName() ) );
} else {
const QString fullEmail = QLatin1String( "<a href=\"mailto:" ) + QString::fromLatin1( KUrl::toPercentEncoding( contact.fullEmail() ) ) + QString::fromLatin1( "\">%1</a>" ).arg( contact.preferredEmail() );
strGroup.append( QString::fromLatin1( "<tr><td align=\"right\" width=\"50%\"><b><font size=\"-1\" color=\"grey\">%1</font></b></td>"
"<td valign=\"bottom\" align=\"left\" width=\"50%\"><font size=\"-1\">&lt;%2&gt;</font></td></tr>" )
.arg( contact.realName() )
.arg( fullEmail ) );
}
}
if ( !addressBookName.isEmpty() ) {
strGroup.append( QString::fromLatin1( "<tr><td colspan=\"2\">&nbsp;</td></tr><tr><td align=\"right\" width=\"30%\"><b><font size=\"-1\" color=\"grey\">%1</font></b></td>"
"<td valign=\"bottom\" align=\"left\" width=\"50%\"><font size=\"-1\">%2</font></td></tr>" )
.arg( i18n( "Address Book" ) )
.arg( addressBookName ) );
}
strGroup.append( QString::fromLatin1( "</table>\n" ) );
const QString document = QString::fromLatin1(
"<html>"
"<head>"
" <style type=\"text/css\">"
" a {text-decoration:none; color:%1}"
" </style>"
"</head>"
"<body text=\"%1\" bgcolor=\"%2\">" // text and background color
"%3" // contact part
"</body>"
"</html>" )
.arg( KColorScheme( QPalette::Active, KColorScheme::View ).foreground().color().name() )
.arg( KColorScheme( QPalette::Active, KColorScheme::View ).background().color().name() )
.arg( strGroup );
return document;
}
#include "contactgroupviewer.moc"
......@@ -30,6 +30,8 @@
namespace Akonadi {
class AbstractContactGroupFormatter;
/**
* @short A viewer component for contact groups in Akonadi.
*
......@@ -74,6 +76,16 @@ class AKONADI_CONTACT_EXPORT ContactGroupViewer : public QWidget, public Akonadi
*/
Akonadi::Item contactGroup() const;
/**
* Sets the contact group @p formatter that should be used for formatting the
* contact group. If formatter is @c 0, the standard formatter will be used.
*
* @note The contact viewer won't take ownership of the formatter.
*
* @since 4.6
*/
void setContactGroupFormatter( AbstractContactGroupFormatter *formatter );
public Q_SLOTS:
/**
* Sets the contact @p group that shall be displayed in the viewer.
......
......@@ -64,7 +64,7 @@ class AKONADI_CONTACT_EXPORT StandardContactFormatter : public AbstractContactFo
virtual ~StandardContactFormatter();
/**
* Returns the contact formatted as HTML
* Returns the contact formatted as HTML.
*/
virtual QString toHtml( HtmlForm form = SelfcontainedForm ) const;
......
/*
This file is part of Akonadi Contact.
Copyright (c) 2010 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 "standardcontactgroupformatter.h"
#include <akonadi/contact/contactgroupexpandjob.h>
#include <akonadi/item.h>
#include <kabc/addressee.h>
#include <kcolorscheme.h>
#include <kglobal.h>
#include <klocale.h>
#include <kstringhandler.h>
using namespace Akonadi;
StandardContactGroupFormatter::StandardContactGroupFormatter()
: d( 0 )
{
}
StandardContactGroupFormatter::~StandardContactGroupFormatter()
{
}
QString StandardContactGroupFormatter::toHtml( HtmlForm form ) const
{
KABC::ContactGroup group;
const Akonadi::Item localItem = item();
if ( localItem.isValid() && localItem.hasPayload<KABC::ContactGroup>() )
group = localItem.payload<KABC::ContactGroup>();
else
group = contactGroup();
if ( group.name().isEmpty() && group.count() == 0 ) // empty group
return QString();
if ( group.contactReferenceCount() != 0 ) {
// we got a contact group with unresolved references -> we have to resolve it ourself
// this shouldn't be the normal case, actually the calling code should pass in an already resolved
// contact group
ContactGroupExpandJob *job = new ContactGroupExpandJob( group );
if ( job->exec() ) {
group.removeAllContactData();
foreach ( const KABC::Addressee &contact, job->contacts() ) {
group.append( KABC::ContactGroup::Data( contact.realName(), contact.preferredEmail() ) );
}
}
}
// Assemble all parts
QString strGroup = QString::fromLatin1(
"<table cellpadding=\"1\" cellspacing=\"0\" width=\"100%\">"
"<tr>"
"<td align=\"right\" valign=\"top\" width=\"30%\">"
"<img src=\"%1\" width=\"75\" height=\"105\" vspace=\"1\">" // image
"</td>"
"<td align=\"left\" width=\"70%\"><font size=\"+2\"><b>%2</b></font></td>" // name
"</tr>"
"</table>" )
.arg( QLatin1String( "group_photo" ) )
.arg( group.name() );
strGroup += QLatin1String( "<table width=\"100%\">" );
for ( uint i = 0; i < group.dataCount(); ++i ) {
const KABC::ContactGroup::Data data = group.data( i );
if ( data.email().isEmpty() ) {
strGroup.append( QString::fromLatin1( "<tr><td align=\"right\" width=\"50%\"><b><font size=\"-1\" color=\"grey\">%1</font></b></td>"
"<td width=\"50%\"></td></tr>" )
.arg( data.name() ) );
} else {
KABC::Addressee contact;
contact.setFormattedName( data.name() );
contact.insertEmail( data.email() );
const QString fullEmail = QLatin1String( "<a href=\"mailto:" ) + QString::fromLatin1( KUrl::toPercentEncoding( contact.fullEmail() ) ) + QString::fromLatin1( "\">%1</a>" ).arg( contact.preferredEmail() );
strGroup.append( QString::fromLatin1( "<tr><td align=\"right\" width=\"50%\"><b><font size=\"-1\" color=\"grey\">%1</font></b></td>"
"<td valign=\"bottom\" align=\"left\" width=\"50%\"><font size=\"-1\">&lt;%2&gt;</font></td></tr>" )
.arg( contact.realName() )
.arg( fullEmail ) );
}
}
foreach ( const QVariantMap &map, additionalFields() ) {
strGroup.append( QString::fromLatin1( "<tr><td colspan=\"2\">&nbsp;</td></tr><tr><td align=\"right\" width=\"30%\"><b><font size=\"-1\" color=\"grey\">%1</font></b></td>"
"<td valign=\"bottom\" align=\"left\" width=\"50%\"><font size=\"-1\">%2</font></td></tr>" )
.arg( map.value( QLatin1String( "title" ) ).toString() )
.arg( map.value( QLatin1String( "value" ) ).toString() ) );
}
strGroup.append( QString::fromLatin1( "</table>\n" ) );
QString document = QString::fromLatin1( "<div align=\"center\">%1</div>" ).arg( strGroup );
if ( form == EmbeddableForm )
return document;
document = QString::fromLatin1(
"<html>"
"<head>"
" <style type=\"text/css\">"
" a {text-decoration:none; color:%1}"
" </style>"
"</head>"
"<body text=\"%1\" bgcolor=\"%2\">" // text and background color
"%3" // contact group part
"</body>"
"</html>" )
.arg( KColorScheme( QPalette::Active, KColorScheme::View ).foreground().color().name() )
.arg( KColorScheme( QPalette::Active, KColorScheme::View ).background().color().name() )
.arg( document );
return document;
}
/*
This file is part of Akonadi Contact.
Copyright (c) 2010 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_STANDARDCONTACTGROUPFORMATTER_H
#define AKONADI_STANDARDCONTACTGROUPFORMATTER_H
#include "akonadi-contact_export.h"
#include "abstractcontactgroupformatter.h"
namespace Akonadi {
/**
* @short A class that formats a contact group as HTML code.
*
* Examples:
*
* @code
*
* using namespace Akonadi;
*
* const KABC::ContactGroup group = ...
*
* StandardContactGroupFormatter formatter;
* formatter.setContactGroup( group );
*
* QTextBrowser *view = new QTextBrowser;
* view->setHtml( formatter.toHtml() );
*
* @endcode
*
* @author Tobias Koenig <tokoe@kde.org>
* @since 4.6
*/
class AKONADI_CONTACT_EXPORT StandardContactGroupFormatter : public AbstractContactGroupFormatter
{
public:
/**
* Creates a new standard contact group formatter.
*/
StandardContactGroupFormatter();
/**
* Destroys the standard contact group formatter.