mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-24 10:52:52 +00:00
352 lines
12 KiB
C++
352 lines
12 KiB
C++
/*
|
|
Copyright (c) 2010 Volker Krause <vkrause@kde.org>
|
|
This file was part of KMail.
|
|
Copyright (c) 2005 Cornelius Schumacher <schumacher@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 "distributionlistdialog.h"
|
|
|
|
#include <akonadi/collectiondialog.h>
|
|
#include <akonadi/contact/contactgroupsearchjob.h>
|
|
#include <akonadi/contact/contactsearchjob.h>
|
|
#include <akonadi/itemcreatejob.h>
|
|
#include <kpimutils/email.h>
|
|
|
|
#include <KLocalizedString>
|
|
#include <KDebug>
|
|
#include <KLineEdit>
|
|
#include <KMessageBox>
|
|
#include <KInputDialog>
|
|
|
|
#include <QLabel>
|
|
#include <QTreeWidget>
|
|
#include <QTreeWidgetItem>
|
|
#include <QVBoxLayout>
|
|
#include <QHBoxLayout>
|
|
#include <QHeaderView>
|
|
|
|
using namespace MessageComposer;
|
|
|
|
namespace MessageComposer {
|
|
class DistributionListItem : public QTreeWidgetItem
|
|
{
|
|
public:
|
|
DistributionListItem( QTreeWidget *tree )
|
|
: QTreeWidgetItem( tree )
|
|
{
|
|
setFlags( flags() | Qt::ItemIsUserCheckable );
|
|
}
|
|
|
|
void setAddressee( const KABC::Addressee &a, const QString &email )
|
|
{
|
|
init( a, email );
|
|
}
|
|
|
|
void init( const KABC::Addressee &a, const QString &email )
|
|
{
|
|
mAddressee = a;
|
|
mEmail = email;
|
|
mId = -1;
|
|
setText( 0, mAddressee.realName() );
|
|
setText( 1, mEmail );
|
|
}
|
|
|
|
KABC::Addressee addressee() const
|
|
{
|
|
return mAddressee;
|
|
}
|
|
|
|
QString email() const
|
|
{
|
|
return mEmail;
|
|
}
|
|
|
|
bool isTransient() const
|
|
{
|
|
return mId == -1;
|
|
}
|
|
|
|
void setId( Akonadi::Entity::Id id )
|
|
{
|
|
mId = id;
|
|
}
|
|
|
|
Akonadi::Entity::Id id() const
|
|
{
|
|
return mId;
|
|
}
|
|
|
|
private:
|
|
KABC::Addressee mAddressee;
|
|
QString mEmail;
|
|
Akonadi::Entity::Id mId;
|
|
};
|
|
}
|
|
|
|
|
|
DistributionListDialog::DistributionListDialog( QWidget *parent )
|
|
: KDialog( parent )
|
|
{
|
|
QFrame *topFrame = new QFrame( this );
|
|
setMainWidget( topFrame );
|
|
setCaption( i18nc("@title:window", "Save Distribution List") );
|
|
setButtons( User1 | Cancel );
|
|
setDefaultButton( User1 );
|
|
setModal( false );
|
|
setButtonText( User1, i18nc("@action:button","Save List") );
|
|
enableButton( User1, false );
|
|
|
|
QBoxLayout *topLayout = new QVBoxLayout( topFrame );
|
|
topLayout->setSpacing( spacingHint() );
|
|
|
|
QBoxLayout *titleLayout = new QHBoxLayout();
|
|
titleLayout->setSpacing( spacingHint() );
|
|
topLayout->addItem( titleLayout );
|
|
|
|
QLabel *label = new QLabel(
|
|
i18nc("@label:textbox Name of the distribution list.", "&Name:"), topFrame );
|
|
titleLayout->addWidget( label );
|
|
|
|
mTitleEdit = new KLineEdit( topFrame );
|
|
titleLayout->addWidget( mTitleEdit );
|
|
mTitleEdit->setFocus();
|
|
mTitleEdit->setClearButtonShown( true );
|
|
label->setBuddy( mTitleEdit );
|
|
|
|
mRecipientsList = new QTreeWidget( topFrame );
|
|
mRecipientsList->setHeaderLabels(
|
|
QStringList() << i18nc( "@title:column Name of the recipient","Name" )
|
|
<< i18nc( "@title:column Email of the recipient", "Email" )
|
|
);
|
|
mRecipientsList->setRootIsDecorated( false );
|
|
mRecipientsList->header()->setMovable(false);
|
|
topLayout->addWidget( mRecipientsList );
|
|
connect( this, SIGNAL(user1Clicked()),
|
|
this, SLOT(slotUser1()) );
|
|
connect( mTitleEdit, SIGNAL(textChanged(QString)),
|
|
this, SLOT(slotTitleChanged(QString)) );
|
|
readConfig();
|
|
}
|
|
|
|
DistributionListDialog::~DistributionListDialog()
|
|
{
|
|
writeConfig();
|
|
}
|
|
|
|
// This starts one ContactSearchJob for each of the specified recipients.
|
|
void DistributionListDialog::setRecipients( const Recipient::List &recipients )
|
|
{
|
|
Recipient::List::ConstIterator end( recipients.constEnd() );
|
|
for( Recipient::List::ConstIterator it = recipients.constBegin(); it != end; ++it ) {
|
|
const QStringList emails = KPIMUtils::splitAddressList( (*it)->email() );
|
|
QStringList::ConstIterator end2( emails.constEnd() );
|
|
for( QStringList::ConstIterator it2 = emails.constBegin(); it2 != end2; ++it2 ) {
|
|
QString name;
|
|
QString email;
|
|
KABC::Addressee::parseEmailAddress( *it2, name, email );
|
|
if ( !email.isEmpty() ) {
|
|
Akonadi::ContactSearchJob *job = new Akonadi::ContactSearchJob(this);
|
|
job->setQuery( Akonadi::ContactSearchJob::Email, email.toLower(), Akonadi::ContactSearchJob::ExactMatch );
|
|
job->setProperty( "name", name );
|
|
job->setProperty( "email", email );
|
|
connect( job, SIGNAL(result(KJob*)), SLOT(slotDelayedSetRecipients(KJob*)) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// This result slot will be called once for each of the original recipients.
|
|
// There could potentially be more than one Akonadi item returned per
|
|
// recipient, in the case where email addresses are duplicated between contacts.
|
|
void DistributionListDialog::slotDelayedSetRecipients( KJob *job )
|
|
{
|
|
const Akonadi::ContactSearchJob *searchJob = qobject_cast<Akonadi::ContactSearchJob*>( job );
|
|
const Akonadi::Item::List akItems = searchJob->items();
|
|
|
|
const QString email = searchJob->property( "email" ).toString();
|
|
QString name = searchJob->property( "name" ).toString();
|
|
if ( name.isEmpty() ) {
|
|
const int index = email.indexOf( QLatin1Char( '@' ) );
|
|
if ( index != -1 ) {
|
|
name = email.left( index );
|
|
} else {
|
|
name = email;
|
|
}
|
|
}
|
|
|
|
if ( akItems.isEmpty() ) {
|
|
KABC::Addressee contact;
|
|
contact.setNameFromString( name );
|
|
contact.insertEmail( email );
|
|
|
|
DistributionListItem *item = new DistributionListItem( mRecipientsList );
|
|
item->setAddressee( contact, email );
|
|
item->setCheckState( 0, Qt::Checked );
|
|
} else {
|
|
bool isFirst = true;
|
|
foreach ( const Akonadi::Item &akItem, akItems ) {
|
|
if ( akItem.hasPayload<KABC::Addressee>() ) {
|
|
const KABC::Addressee contact = akItem.payload<KABC::Addressee>();
|
|
|
|
DistributionListItem *item = new DistributionListItem( mRecipientsList );
|
|
item->setAddressee( contact, email );
|
|
|
|
// Need to record the Akonadi ID of the contact, so that
|
|
// it can be added as a reference later. Setting an ID
|
|
// makes the item non-transient.
|
|
item->setId( akItem.id() );
|
|
|
|
// If there were multiple contacts returned for an email address,
|
|
// then check the first one and uncheck any subsequent ones.
|
|
if ( isFirst ) {
|
|
item->setCheckState( 0, Qt::Checked );
|
|
isFirst = false;
|
|
} else {
|
|
// Need this to create an unchecked item, as otherwise the
|
|
// item will have no checkbox at all.
|
|
item->setCheckState( 0, Qt::Unchecked );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void DistributionListDialog::slotUser1()
|
|
{
|
|
bool isEmpty = true;
|
|
const int numberOfTopLevel( mRecipientsList->topLevelItemCount() );
|
|
for (int i = 0; i < numberOfTopLevel; ++i) {
|
|
DistributionListItem *item = static_cast<DistributionListItem *>(
|
|
mRecipientsList->topLevelItem( i ));
|
|
if ( item && item->checkState( 0 ) == Qt::Checked ) {
|
|
isEmpty = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( isEmpty ) {
|
|
KMessageBox::information( this,
|
|
i18nc("@info", "There are no recipients in your list. "
|
|
"First select some recipients, "
|
|
"then try again.") );
|
|
return;
|
|
}
|
|
|
|
QString name = mTitleEdit->text();
|
|
|
|
if ( name.isEmpty() ) {
|
|
bool ok = false;
|
|
name = KInputDialog::getText( i18nc("@title:window","New Distribution List"),
|
|
i18nc("@label:textbox","Please enter name:"), QString(), &ok, this );
|
|
if ( !ok || name.isEmpty() )
|
|
return;
|
|
}
|
|
|
|
Akonadi::ContactGroupSearchJob *job = new Akonadi::ContactGroupSearchJob();
|
|
job->setQuery( Akonadi::ContactGroupSearchJob::Name, name );
|
|
job->setProperty( "name", name );
|
|
connect( job, SIGNAL(result(KJob*)), SLOT(slotDelayedUser1(KJob*)) );
|
|
}
|
|
|
|
void DistributionListDialog::slotDelayedUser1( KJob *job )
|
|
{
|
|
const Akonadi::ContactGroupSearchJob *searchJob = qobject_cast<Akonadi::ContactGroupSearchJob*>( job );
|
|
const QString name = searchJob->property( "name" ).toString();
|
|
|
|
if ( !searchJob->contactGroups().isEmpty() ) {
|
|
KMessageBox::information( this,
|
|
i18nc( "@info", "<para>Distribution list with the given name <resource>%1</resource> "
|
|
"already exists. Please select a different name.</para>", name ) );
|
|
return;
|
|
}
|
|
|
|
QPointer<Akonadi::CollectionDialog> dlg =
|
|
new Akonadi::CollectionDialog( Akonadi::CollectionDialog::KeepTreeExpanded, 0, this );
|
|
dlg->setMimeTypeFilter( QStringList() << KABC::Addressee::mimeType()
|
|
<< KABC::ContactGroup::mimeType() );
|
|
dlg->setAccessRightsFilter( Akonadi::Collection::CanCreateItem );
|
|
dlg->setCaption( i18nc( "@title:window", "Select Address Book" ) );
|
|
dlg->setDescription( i18n( "Select the address book folder to store the contact group in:" ) );
|
|
if ( dlg->exec() ) {
|
|
const Akonadi::Collection targetCollection = dlg->selectedCollection();
|
|
delete dlg;
|
|
|
|
KABC::ContactGroup group( name );
|
|
const int numberOfTopLevel( mRecipientsList->topLevelItemCount() );
|
|
for ( int i = 0; i < numberOfTopLevel; ++i ) {
|
|
DistributionListItem *item = static_cast<DistributionListItem *>( mRecipientsList->topLevelItem( i ) );
|
|
if ( item && item->checkState( 0 ) == Qt::Checked ) {
|
|
kDebug() << item->addressee().fullEmail() << item->addressee().uid();
|
|
if ( item->isTransient() ) {
|
|
group.append( KABC::ContactGroup::Data( item->addressee().realName(), item->email() ) );
|
|
} else {
|
|
KABC::ContactGroup::ContactReference reference( QString::number( item->id() ) );
|
|
if ( item->email() != item->addressee().preferredEmail() ) {
|
|
reference.setPreferredEmail( item->email() );
|
|
}
|
|
group.append( reference );
|
|
}
|
|
}
|
|
}
|
|
|
|
Akonadi::Item groupItem( KABC::ContactGroup::mimeType() );
|
|
groupItem.setPayload<KABC::ContactGroup>( group );
|
|
|
|
Akonadi::Job *createJob = new Akonadi::ItemCreateJob( groupItem, targetCollection );
|
|
connect( createJob, SIGNAL(result(KJob*)), this, SLOT(slotContactGroupCreateJobResult(KJob*)) );
|
|
}
|
|
|
|
delete dlg;
|
|
}
|
|
|
|
void DistributionListDialog::slotContactGroupCreateJobResult( KJob *job )
|
|
{
|
|
if ( job->error() ) {
|
|
KMessageBox::information( this, i18n("Unable to create distribution list: %1", job->errorString() ));
|
|
kWarning() << "Unable to create distribution list:" << job->errorText();
|
|
} else {
|
|
accept();
|
|
}
|
|
}
|
|
|
|
void DistributionListDialog::slotTitleChanged( const QString& text )
|
|
{
|
|
enableButton( KDialog::User1, !text.trimmed().isEmpty() );
|
|
}
|
|
|
|
void DistributionListDialog::readConfig()
|
|
{
|
|
KSharedConfig::Ptr cfg = KGlobal::config();
|
|
KConfigGroup group( cfg, "DistributionListDialog" );
|
|
const QSize size = group.readEntry( "Size", QSize() );
|
|
if ( !size.isEmpty() ) {
|
|
resize( size );
|
|
}
|
|
mRecipientsList->header()->restoreState(group.readEntry("Header", QByteArray()));
|
|
}
|
|
|
|
void DistributionListDialog::writeConfig()
|
|
{
|
|
KSharedConfig::Ptr cfg = KGlobal::config();
|
|
KConfigGroup group( cfg, "DistributionListDialog" );
|
|
group.writeEntry( "Size", size() );
|
|
group.writeEntry( "Header", mRecipientsList->header()->saveState() );
|
|
}
|
|
|
|
|