mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-24 19:02:51 +00:00
268 lines
9.4 KiB
C++
268 lines
9.4 KiB
C++
/* -*- mode: C++; c-file-style: "gnu" -*-
|
|
Copyright (c) 2010 Volker Krause <vkrause@kde.org>
|
|
|
|
Based on kmail/kmlineeditspell.h/cpp
|
|
Copyright (c) 1997 Markus Wuebben <markus.wuebben@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 "composerlineedit.h"
|
|
|
|
#include "addressline/recentaddresses.h"
|
|
#include "settings/messagecomposersettings.h"
|
|
#include "messageviewer/utils/autoqpointer.h"
|
|
|
|
#include <messagecore/utils/stringutil.h>
|
|
|
|
#include <kpimutils/email.h>
|
|
#include <kabc/vcarddrag.h>
|
|
#include <kabc/contactgroup.h>
|
|
#include <kabc/vcardconverter.h>
|
|
|
|
#include <kio/netaccess.h>
|
|
#include <kmenu.h>
|
|
#include <kurl.h>
|
|
#include <kmessagebox.h>
|
|
#include <kcompletionbox.h>
|
|
#include <klocale.h>
|
|
|
|
#include <QFile>
|
|
#include <QCursor>
|
|
#include <QKeyEvent>
|
|
#include <QDropEvent>
|
|
#include <kabc/contactgrouptool.h>
|
|
#include <Akonadi/Contact/ContactGroupExpandJob>
|
|
#include <QtCore/QBuffer>
|
|
|
|
using namespace MessageComposer;
|
|
|
|
ComposerLineEdit::ComposerLineEdit(bool useCompletion, QWidget *parent)
|
|
: KPIM::AddresseeLineEdit(parent, useCompletion),
|
|
m_recentAddressConfig( MessageComposerSettings::self()->config() )
|
|
{
|
|
allowSemicolonAsSeparator( MessageComposerSettings::allowSemicolonAsAddressSeparator() );
|
|
loadContacts();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ComposerLineEdit::keyPressEvent(QKeyEvent *e)
|
|
{
|
|
if ((e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) &&
|
|
!completionBox()->isVisible())
|
|
{
|
|
emit focusDown();
|
|
AddresseeLineEdit::keyPressEvent(e);
|
|
return;
|
|
} else if (e->key() == Qt::Key_Up) {
|
|
emit focusUp();
|
|
return;
|
|
} else if (e->key() == Qt::Key_Down) {
|
|
emit focusDown();
|
|
return;
|
|
}
|
|
AddresseeLineEdit::keyPressEvent(e);
|
|
}
|
|
|
|
|
|
void ComposerLineEdit::insertEmails( const QStringList & emails )
|
|
{
|
|
if ( emails.empty() )
|
|
return;
|
|
|
|
QString contents = text();
|
|
if ( !contents.isEmpty() )
|
|
contents += QLatin1Char(',');
|
|
// only one address, don't need kpopup to choose
|
|
if ( emails.size() == 1 ) {
|
|
setText( contents + emails.front() );
|
|
return;
|
|
}
|
|
//multiple emails, let the user choose one
|
|
KMenu menu( this );
|
|
menu.setObjectName( QLatin1String("Addresschooser") );
|
|
for ( QStringList::const_iterator it = emails.constBegin(), end = emails.constEnd() ; it != end; ++it )
|
|
menu.addAction( *it );
|
|
const QAction *result = menu.exec( QCursor::pos() );
|
|
if ( !result )
|
|
return;
|
|
setText( contents + KGlobal::locale()->removeAcceleratorMarker( result->text() ) );
|
|
}
|
|
|
|
#ifndef QT_NO_DRAGANDDROP
|
|
void ComposerLineEdit::dropEvent(QDropEvent *event)
|
|
{
|
|
const QMimeData *md = event->mimeData();
|
|
|
|
// Case one: The user dropped a text/directory (i.e. vcard), so decode its
|
|
// contents
|
|
if ( KABC::VCardDrag::canDecode( md ) ) {
|
|
KABC::Addressee::List list;
|
|
KABC::VCardDrag::fromMimeData( md, list );
|
|
|
|
KABC::Addressee::List::ConstIterator ait;
|
|
KABC::Addressee::List::ConstIterator end( list.constEnd() );
|
|
for ( ait = list.constBegin(); ait != end; ++ait ){
|
|
insertEmails( (*ait).emails() );
|
|
}
|
|
}
|
|
|
|
// Case two: The user dropped a list or Urls.
|
|
// Iterate over that list. For mailto: Urls, just add the addressee to the list,
|
|
// and for other Urls, download the Url and assume it points to a vCard
|
|
else if ( KUrl::List::canDecode( md ) ) {
|
|
KUrl::List urls = KUrl::List::fromMimeData( md );
|
|
KABC::Addressee::List list;
|
|
|
|
foreach ( const KUrl& url, urls ) {
|
|
|
|
// First, let's deal with mailto Urls. The path() part contains the
|
|
// email-address.
|
|
if ( url.protocol() == QLatin1String("mailto") ) {
|
|
KABC::Addressee addressee;
|
|
addressee.insertEmail( KPIMUtils::decodeMailtoUrl( url ), true /* preferred */ );
|
|
list += addressee;
|
|
}
|
|
|
|
// Otherwise, download the vCard to which the Url points
|
|
else {
|
|
KABC::VCardConverter converter;
|
|
QString fileName;
|
|
if ( KIO::NetAccess::download( url, fileName, parentWidget() ) ) {
|
|
QFile file( fileName );
|
|
if (file.open( QIODevice::ReadOnly ) ) {
|
|
QByteArray data = file.readAll();
|
|
file.close();
|
|
list += converter.parseVCards( data );
|
|
KIO::NetAccess::removeTempFile( fileName );
|
|
|
|
if( list.isEmpty() ) { // try to parse a contact group
|
|
KABC::ContactGroup group;
|
|
QBuffer dataStream( &data );
|
|
dataStream.open( QIODevice::ReadOnly );
|
|
QString error;
|
|
if( KABC::ContactGroupTool::convertFromXml( &dataStream, group, &error ) ) {
|
|
Akonadi::ContactGroupExpandJob* expandJob = new Akonadi::ContactGroupExpandJob( group );
|
|
connect( expandJob, SIGNAL(result(KJob*)), this, SLOT(groupDropExpandResult(KJob*)) );
|
|
expandJob->start();
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
const QString caption( i18n( "vCard Import Failed" ) );
|
|
const QString text = i18n( "<qt>Unable to access <b>%1</b>.</qt>", url.url() );
|
|
KMessageBox::error( parentWidget(), text, caption );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Now, let the user choose which addressee to add.
|
|
foreach( const KABC::Addressee& addressee, list ) {
|
|
insertEmails( addressee.emails() );
|
|
}
|
|
}
|
|
|
|
// Case three: Let AddresseeLineEdit deal with the rest
|
|
else {
|
|
KPIM::AddresseeLineEdit::dropEvent( event );
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void ComposerLineEdit::groupDropExpandResult( KJob* job )
|
|
{
|
|
Akonadi::ContactGroupExpandJob *expandJob = qobject_cast<Akonadi::ContactGroupExpandJob*>( job );
|
|
|
|
if( !expandJob )
|
|
return;
|
|
|
|
const KABC::Addressee::List contacts = expandJob->contacts();
|
|
foreach( const KABC::Addressee& addressee, contacts )
|
|
insertEmails( addressee.emails() );
|
|
|
|
job->deleteLater();
|
|
}
|
|
|
|
|
|
#ifndef QT_NO_CONTEXTMENU
|
|
void ComposerLineEdit::contextMenuEvent( QContextMenuEvent*e )
|
|
{
|
|
QPointer<QMenu> popup = createStandardContextMenu();
|
|
if ( popup ) { // can be 0 on platforms with only a touch interface
|
|
popup->addSeparator();
|
|
QAction* act = popup->addAction( i18n( "Edit Recent Addresses..." ));
|
|
connect(act,SIGNAL(triggered(bool)), SLOT(editRecentAddresses()) );
|
|
popup->exec( e->globalPos() );
|
|
delete popup;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void ComposerLineEdit::editRecentAddresses()
|
|
{
|
|
MessageViewer::AutoQPointer<KPIM::RecentAddressDialog> dlg( new KPIM::RecentAddressDialog( this ) );
|
|
dlg->setAddresses( KPIM::RecentAddresses::self( m_recentAddressConfig )->addresses() );
|
|
if ( dlg->exec() && dlg ) {
|
|
KPIM::RecentAddresses::self( m_recentAddressConfig )->clear();
|
|
dlg->addAddresses(m_recentAddressConfig);
|
|
loadContacts();
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ComposerLineEdit::loadContacts()
|
|
{
|
|
//AddresseeLineEdit::loadContacts();
|
|
|
|
const QString recentAddressGroupName = i18n( "Recent Addresses" );
|
|
if ( MessageComposerSettings::self()->showRecentAddressesInComposer() ){
|
|
const QStringList recent =
|
|
KPIM::RecentAddresses::self( m_recentAddressConfig )->addresses();
|
|
QStringList::ConstIterator it = recent.constBegin();
|
|
QString name, email;
|
|
|
|
KSharedConfig::Ptr config = KSharedConfig::openConfig( QLatin1String("kpimcompletionorder") );
|
|
KConfigGroup group( config, "CompletionWeights" );
|
|
const int weight = group.readEntry( "Recent Addresses", 10 );
|
|
removeCompletionSource(recentAddressGroupName);
|
|
const int idx = addCompletionSource( recentAddressGroupName, weight );
|
|
|
|
QStringList::ConstIterator end = recent.constEnd();
|
|
for ( ; it != end; ++it ) {
|
|
KABC::Addressee addr;
|
|
KPIMUtils::extractEmailAddressAndName( *it, email, name );
|
|
name = KPIMUtils::quoteNameIfNecessary( name );
|
|
if ( ( name[0] == QLatin1Char('"') ) && ( name[name.length() - 1] == QLatin1Char('"') ) ) {
|
|
name.remove( 0, 1 );
|
|
name.truncate( name.length() - 1 );
|
|
}
|
|
addr.setNameFromString( name );
|
|
addr.insertEmail( email, true );
|
|
addContact( addr, weight, idx );
|
|
}
|
|
} else {
|
|
removeCompletionSource( recentAddressGroupName );
|
|
}
|
|
}
|
|
|
|
void ComposerLineEdit::setRecentAddressConfig ( KConfig* config )
|
|
{
|
|
m_recentAddressConfig = config;
|
|
}
|
|
|
|
|