[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kdepim/KDE/4.14] libkdepim/addressline: Split code
From:       Montel Laurent <montel () kde ! org>
Date:       2015-02-12 21:20:05
Message-ID: E1YM1B7-0003WP-VN () scm ! kde ! org
[Download RAW message or body]

Git commit 1565bda3b6c7ef20bd252d8098c9f0358b2f77d0 by Montel Laurent.
Committed on 12/02/2015 at 21:18.
Pushed by mlaurent into branch 'KDE/4.14'.

Split code

M  +1    -956  libkdepim/addressline/addresseelineedit.cpp
C  +16   -626  libkdepim/addressline/addresseelineedit_p.cpp [from: \
libkdepim/addressline/addresseelineedit.cpp - 060% similarity]

http://commits.kde.org/kdepim/1565bda3b6c7ef20bd252d8098c9f0358b2f77d0

diff --git a/libkdepim/addressline/addresseelineedit.cpp \
b/libkdepim/addressline/addresseelineedit.cpp index f46deaa..df64db2 100644
--- a/libkdepim/addressline/addresseelineedit.cpp
+++ b/libkdepim/addressline/addresseelineedit.cpp
@@ -71,965 +71,10 @@
 #include <QMenu>
 #include <QTimer>
 #include <QtDBus/QDBusConnection>
+#include "addresseelineedit_p.cpp"
 
 using namespace KPIM;
 
-namespace KPIM {
-typedef QMap< QString, QPair<int,int> > CompletionItemsMap;
-}
-
-class AddresseeLineEditStatic
-{
-public:
-
-    AddresseeLineEditStatic()
-        : completion( new KMailCompletion ),
-          ldapTimer( 0 ),
-          ldapSearch( 0 ),
-          ldapLineEdit( 0 ),
-          akonadiSession( new Akonadi::Session("contactsCompletionSession") ),
-          balooCompletionSource( 0 )
-    {
-    }
-
-    ~AddresseeLineEditStatic()
-    {
-        delete completion;
-        delete ldapTimer;
-        delete ldapSearch;
-    }
-
-    void slotEditCompletionOrder()
-    {
-        CompletionOrderEditor editor( ldapSearch, 0 );
-        if( editor.exec() ) {
-            updateLDAPWeights();
-            updateCollectionWeights();
-        }
-    }
-
-    void updateCollectionWeights()
-    {
-        akonadiCollectionToCompletionSourceMap.clear();
-    }
-
-    void updateLDAPWeights()
-    {
-        /* Add completion sources for all ldap server, 0 to n. Added first so
-       * that they map to the LdapClient::clientNumber() */
-        ldapSearch->updateCompletionWeights();
-        int clientIndex = 0;
-        foreach ( const KLDAP::LdapClient *client, ldapSearch->clients() ) {
-            const int sourceIndex =
-                    addCompletionSource( i18n( "LDAP server: %1" \
                ,client->server().host()),
-                                         client->completionWeight() );
-
-            ldapClientToCompletionSourceMap.insert( clientIndex, sourceIndex );
-
-            ++clientIndex;
-        }
-    }
-
-    int addCompletionSource( const QString &source, int weight )
-    {
-        QMap<QString,int>::iterator it = completionSourceWeights.find( source );
-        if ( it == completionSourceWeights.end() ) {
-            completionSourceWeights.insert( source, weight );
-        } else {
-            completionSourceWeights[source] = weight;
-        }
-
-        const int sourceIndex = completionSources.indexOf( source );
-        if ( sourceIndex == -1 ) {
-            completionSources.append( source );
-            return completionSources.size() - 1;
-        } else {
-            return sourceIndex;
-        }
-    }
-
-    void removeCompletionSource( const QString &source )
-    {
-        QMap<QString,int>::iterator it = completionSourceWeights.find( source );
-        if ( it != completionSourceWeights.end() ) {
-            completionSourceWeights.remove(source);
-            completion->clear();
-        }
-    }
-
-    KMailCompletion *completion;
-    KPIM::CompletionItemsMap completionItemMap;
-    QStringList completionSources;
-    QTimer *ldapTimer;
-    KLDAP::LdapClientSearch *ldapSearch;
-    QString ldapText;
-    AddresseeLineEdit *ldapLineEdit;
-    // The weights associated with the completion sources in \
                s_static->completionSources.
-    // Both are maintained by addCompletionSource(), don't attempt to modifiy those \
                yourself.
-    QMap<QString, int> completionSourceWeights;
-    // maps LDAP client indices to completion source indices
-    // the assumption that they are always the first n indices in \
                s_static->completion
-    // does not hold when clients are added later on
-    QMap<int, int> ldapClientToCompletionSourceMap;
-    // holds the cached mapping from akonadi collection id to the completion source \
                index
-    QMap<Akonadi::Collection::Id, int> akonadiCollectionToCompletionSourceMap;
-    // a list of akonadi items (contacts) that have not had their collection fetched \
                yet
-    Akonadi::Item::List akonadiPendingItems;
-    Akonadi::Session *akonadiSession;
-    QVector<QWeakPointer<Akonadi::Job> > akonadiJobsInFlight;
-    int balooCompletionSource;
-};
-
-K_GLOBAL_STATIC( AddresseeLineEditStatic, s_static )
-
-// needs to be unique, but the actual name doesn't matter much
-static QString newLineEditObjectName()
-{
-    static int s_count = 0;
-    QString name( QLatin1String("KPIM::AddresseeLineEdit") );
-    if ( s_count++ ) {
-        name += QLatin1Char('-');
-        name += QString::number( s_count );
-    }
-    return name;
-}
-
-static const QString s_completionItemIndentString = QLatin1String("     ");
-
-static bool itemIsHeader( const QListWidgetItem *item )
-{
-    return item && !item->text().startsWith( s_completionItemIndentString );
-}
-
-class SourceWithWeight
-{
-public:
-    int weight;           // the weight of the source
-    QString sourceName;   // the name of the source, e.g. "LDAP Server"
-    int index;            // index into s_static->completionSources
-
-    bool operator< ( const SourceWithWeight &other ) const
-    {
-        if ( weight > other.weight ) {
-            return true;
-        }
-
-        if ( weight < other.weight ) {
-            return false;
-        }
-
-        return sourceName < other.sourceName;
-    }
-};
-
-class AddresseeLineEdit::Private
-{
-public:
-    Private( AddresseeLineEdit *qq, bool enableCompletion )
-        : q( qq ),
-          m_useCompletion( enableCompletion ),
-          m_completionInitialized( false ),
-          m_smartPaste( false ),
-          m_addressBookConnected( false ),
-          m_lastSearchMode( false ),
-          m_searchExtended( false ),
-          m_useSemicolonAsSeparator( false ),
-          m_showOU(false),
-          m_enableBalooSearch(true)
-    {
-        m_delayedQueryTimer.setSingleShot(true);
-        connect( &m_delayedQueryTimer, SIGNAL(timeout()), q, \
                SLOT(slotTriggerDelayedQueries()) );
-    }
-    QStringList cleanupEmailList(const QStringList &inputList);
-    void loadBalooBlackList();
-    void alternateColor();
-    void init();
-    void startLoadingLDAPEntries();
-    void stopLDAPLookup();
-    void setCompletedItems( const QStringList &items, bool autoSuggest );
-    void addCompletionItem( const QString &string, int weight, int source,
-                            const QStringList *keyWords = 0 );
-    const QStringList adjustedCompletionItems( bool fullSearch );
-    void updateSearchString();
-    void startSearches();
-    void akonadiPerformSearch();
-    void akonadiHandlePending();
-    void doCompletion( bool ctrlT );
-
-    void slotCompletion();
-    void slotPopupCompletion( const QString & );
-    void slotReturnPressed( const QString & );
-    void slotStartLDAPLookup();
-    void slotLDAPSearchData( const KLDAP::LdapResult::List & );
-    void slotEditCompletionOrder();
-    void slotUserCancelled( const QString & );
-    void slotAkonadiHandleItems( const Akonadi::Item::List &items );
-    void slotAkonadiSearchResult( KJob * );
-    void slotAkonadiCollectionsReceived( const Akonadi::Collection::List & );
-    void searchInBaloo();
-    void slotTriggerDelayedQueries();
-    void slotShowOUChanged( bool );
-    void slotConfigureBalooBlackList();
-
-    AddresseeLineEdit *q;
-    QStringList m_balooBlackList;
-    QStringList m_domainExcludeList;
-    QString m_previousAddresses;
-    QString m_searchString;
-    bool m_useCompletion;
-    bool m_completionInitialized;
-    bool m_smartPaste;
-    bool m_addressBookConnected;
-    bool m_lastSearchMode;
-    bool m_searchExtended; //has \" been added?
-    bool m_useSemicolonAsSeparator;
-    bool m_showOU;
-    bool m_enableBalooSearch;
-    QTimer m_delayedQueryTimer;
-    QColor m_alternateColor;
-};
-
-void AddresseeLineEdit::Private::init()
-{
-    if ( !s_static.exists() ) {
-        s_static->completion->setOrder( KCompletion::Weighted );
-        s_static->completion->setIgnoreCase( true );
-    }
-
-    if ( m_useCompletion ) {
-        if ( !s_static->ldapTimer ) {
-            s_static->ldapTimer = new QTimer;
-            s_static->ldapSearch = new KLDAP::LdapClientSearch;
-
-            /* The reasoning behind this filter is:
-             * If it's a person, or a distlist, show it, even if it doesn't have an \
                email address.
-             * If it's not a person, or a distlist, only show it if it has an email \
                attribute.
-             * This allows both resource accounts with an email address which are \
                not a person and
-             * person entries without an email address to show up, while still not \
                showing things
-             * like structural entries in the ldap tree.
-             */
-
-            #if 0
-                s_static->ldapSearch->setFilter(QString::fromLatin1("&(|(objectclass=person)(objectclass=groupOfNames)(mail=*))"
                
-                                                          \
                "(|(cn=%1*)(mail=%1*)(mail=*@%1*)(givenName=%1*)(sn=%1*))"));
-            #endif
-            //Fix bug 323272 "Exchange doesn't like any queries beginning with *."
-            s_static->ldapSearch->setFilter(QString::fromLatin1( \
                "&(|(objectclass=person)(objectclass=groupOfNames)(mail=*))"
-                                "(|(cn=%1*)(mail=%1*)(givenName=%1*)(sn=%1*))" ));
-
-        }
-
-        s_static->balooCompletionSource = q->addCompletionSource( i18nc( \
                "@title:group", "Contacts found in your data"), -1 );
-
-        s_static->updateLDAPWeights();
-
-        if ( !m_completionInitialized ) {
-            q->setCompletionObject( s_static->completion, false );
-            q->connect( q, SIGNAL(completion(QString)),
-                        q, SLOT(slotCompletion()) );
-            q->connect( q, SIGNAL(returnPressed(QString)),
-                        q, SLOT(slotReturnPressed(QString)) );
-
-            KCompletionBox *box = q->completionBox();
-            q->connect( box, SIGNAL(activated(QString)),
-                        q, SLOT(slotPopupCompletion(QString)) );
-            q->connect( box, SIGNAL(userCancelled(QString)),
-                        q, SLOT(slotUserCancelled(QString)) );
-
-            q->connect( s_static->ldapTimer, SIGNAL(timeout()), \
                SLOT(slotStartLDAPLookup()) );
-            q->connect( s_static->ldapSearch, \
                SIGNAL(searchData(KLDAP::LdapResult::List)),
-                        SLOT(slotLDAPSearchData(KLDAP::LdapResult::List)) );
-
-            m_completionInitialized = true;
-        }
-
-        KConfigGroup group( KGlobal::config(), "AddressLineEdit" );
-        m_showOU = group.readEntry( "ShowOU", false );
-        loadBalooBlackList();
-    }
-}
-
-void AddresseeLineEdit::Private::startLoadingLDAPEntries()
-{
-    QString text( s_static->ldapText );
-
-    // TODO cache last?
-    QString prevAddr;
-    const int index = text.lastIndexOf( QLatin1Char( ',' ) );
-    if ( index >= 0 ) {
-        prevAddr = text.left( index + 1 ) + QLatin1Char( ' ' );
-        text = text.mid( index + 1, 255 ).trimmed();
-    }
-
-    if ( text.isEmpty() ) {
-        return;
-    }
-
-    s_static->ldapSearch->startSearch( text );
-}
-
-void AddresseeLineEdit::Private::stopLDAPLookup()
-{
-    s_static->ldapSearch->cancelSearch();
-    s_static->ldapLineEdit = 0;
-}
-
-QStringList AddresseeLineEdit::cleanupEmailList(const QStringList &inputList)
-{
-    return d->cleanupEmailList(inputList);
-}
-
-QStringList AddresseeLineEdit::Private::cleanupEmailList(const QStringList \
                &inputList)
-{
-    KPIM::BalooCompletionEmail completionEmail;
-    completionEmail.setEmailList(inputList);
-    completionEmail.setBlackList(m_balooBlackList);
-    completionEmail.setExcludeDomain(m_domainExcludeList);
-    const QStringList listEmail = completionEmail.cleanupEmailList();
-    return listEmail;
-}
-
-void AddresseeLineEdit::Private::searchInBaloo()
-{
-    const QString trimmedString = m_searchString.trimmed();
-    Baloo::PIM::ContactCompleter com(trimmedString, 20);
-    const QStringList listEmail = cleanupEmailList(com.complete());
-    Q_FOREACH (const QString& email, listEmail) {
-        addCompletionItem(email, 1, s_static->balooCompletionSource);
-    }
-    doCompletion( m_lastSearchMode );
-    //  if ( q->hasFocus() || q->completionBox()->hasFocus() ) {
-    //}
-}
-
-void AddresseeLineEdit::Private::alternateColor()
-{
-    const KColorScheme colorScheme( QPalette::Active, KColorScheme::View );
-    m_alternateColor = \
                colorScheme.background(KColorScheme::AlternateBackground).color();
-}
-
-void AddresseeLineEdit::Private::setCompletedItems( const QStringList &items, bool \
                autoSuggest )
-{
-    KCompletionBox *completionBox = q->completionBox();
-
-    if ( !items.isEmpty() &&
-         !( items.count() == 1 && m_searchString == items.first() ) ) {
-
-        completionBox->clear();
-        const int numberOfItems( items.count() );
-        for ( int i = 0; i< numberOfItems; ++i )
-        {
-            QListWidgetItem *item =new QListWidgetItem(items.at( i ), \
                completionBox);
-            if ( !items.at( i ).startsWith( s_completionItemIndentString ) ) {
-                if (!m_alternateColor.isValid()) {
-                    alternateColor();
-                }
-                item->setBackgroundColor(m_alternateColor);
-            }
-            completionBox->addItem( item );
-        }
-        if ( !completionBox->isVisible() ) {
-            if ( !m_searchString.isEmpty() ) {
-                completionBox->setCancelledText( m_searchString );
-            }
-            completionBox->popup();
-            // we have to install the event filter after popup(), since that
-            // calls show(), and that's where KCompletionBox installs its filter.
-            // We want to be first, though, so do it now.
-            if ( s_static->completion->order() == KCompletion::Weighted ) {
-                qApp->installEventFilter( q );
-            }
-        }
-
-        QListWidgetItem *item = completionBox->item( 1 );
-        if ( item ) {
-            completionBox->blockSignals( true );
-            completionBox->setCurrentItem( item );
-            item->setSelected( true );
-            completionBox->blockSignals( false );
-        }
-
-        if ( autoSuggest ) {
-            const int index = items.first().indexOf( m_searchString );
-            const QString newText = items.first().mid( index );
-            q->setUserSelection( false );
-            q->setCompletedText( newText, true );
-        }
-    } else {
-        if ( completionBox && completionBox->isVisible() ) {
-            completionBox->hide();
-            completionBox->setItems( QStringList() );
-        }
-    }
-}
-
-void AddresseeLineEdit::Private::addCompletionItem( const QString &string, int \
                weight,
-                                                    int completionItemSource,
-                                                    const QStringList *keyWords )
-{
-    // Check if there is an exact match for item already, and use the
-    // maximum weight if so. Since there's no way to get the information
-    // from KCompletion, we have to keep our own QMap.
-    // We also update the source since the item should always be shown from the \
                source with the highest weight
-
-    CompletionItemsMap::iterator it = s_static->completionItemMap.find( string );
-    if ( it != s_static->completionItemMap.end() ) {
-        weight = qMax( ( *it ).first, weight );
-        ( *it ).first = weight;
-        ( *it ).second = completionItemSource;
-    } else {
-        s_static->completionItemMap.insert( string, qMakePair( weight, \
                completionItemSource ) );
-    }
-
-    s_static->completion->addItem(string, weight);
-    if (keyWords && !keyWords->isEmpty())
-        s_static->completion->addItemWithKeys(string, weight, keyWords); // see \
                kmailcompletion.cpp
-}
-
-const QStringList KPIM::AddresseeLineEdit::Private::adjustedCompletionItems( bool \
                fullSearch )
-{
-    QStringList items = fullSearch ?
-                s_static->completion->allMatches( m_searchString ) :
-                s_static->completion->substringCompletion( m_searchString );
-
-    //force items to be sorted by email
-    items.sort();
-
-    // For weighted mode, the algorithm is the following:
-    // In the first loop, we add each item to its section (there is one section per \
                completion source)
-    // We also add spaces in front of the items.
-    // The sections are appended to the items list.
-    // In the second loop, we then walk through the sections and add all the items \
                in there to the
-    // sorted item list, which is the final result.
-    //
-    // The algo for non-weighted mode is different.
-
-    int lastSourceIndex = -1;
-    unsigned int i = 0;
-
-    // Maps indices of the items list, which are section headers/source items,
-    // to a QStringList which are the items of that section/source.
-    QMap<int, QStringList> sections;
-    QStringList sortedItems;
-    for ( QStringList::Iterator it = items.begin(); it != items.end(); ++it, ++i ) {
-        CompletionItemsMap::const_iterator cit = \
                s_static->completionItemMap.constFind( *it );
-        if ( cit == s_static->completionItemMap.constEnd() ) {
-            continue;
-        }
-
-        const int index = (*cit).second;
-
-        if ( s_static->completion->order() == KCompletion::Weighted ) {
-            if ( lastSourceIndex == -1 || lastSourceIndex != index ) {
-                const QString sourceLabel( s_static->completionSources.at( index ) \
                );
-                if ( sections.find( index ) == sections.end() ) {
-                    it = items.insert( it, sourceLabel );
-                    ++it; //skip new item
-                }
-                lastSourceIndex = index;
-            }
-
-            (*it) = (*it).prepend( s_completionItemIndentString );
-            // remove preferred email sort <blank> added in  addContact()
-            (*it).replace( QLatin1String( "  <" ), QLatin1String( " <" ) );
-        }
-        sections[ index ].append( *it );
-
-        if ( s_static->completion->order() == KCompletion::Sorted ) {
-            sortedItems.append( *it );
-        }
-    }
-
-    if ( s_static->completion->order() == KCompletion::Weighted ) {
-
-        // Sort the sections
-        QList<SourceWithWeight> sourcesAndWeights;
-        const int numberOfCompletionSources(s_static->completionSources.size());
-        for ( int i = 0; i < numberOfCompletionSources; ++i ) {
-            SourceWithWeight sww;
-            sww.sourceName = s_static->completionSources.at(i);
-            sww.weight = s_static->completionSourceWeights[sww.sourceName];
-            sww.index = i;
-            sourcesAndWeights.append( sww );
-        }
-
-        qSort( sourcesAndWeights.begin(), sourcesAndWeights.end() );
-        // Add the sections and their items to the final sortedItems result list
-        const int numberOfSources(sourcesAndWeights.size());
-        for ( int i = 0; i < numberOfSources; ++i ) {
-            const SourceWithWeight source = sourcesAndWeights.at(i);
-            const QStringList sectionItems = sections[source.index];
-            if ( !sectionItems.isEmpty() ) {
-                sortedItems.append( source.sourceName );
-                foreach ( const QString &itemInSection, sectionItems ) {
-                    sortedItems.append( itemInSection );
-                }
-            }
-        }
-    } else {
-        sortedItems.sort();
-    }
-
-    return sortedItems;
-}
-
-void AddresseeLineEdit::Private::updateSearchString()
-{
-    m_searchString = q->text();
-
-    int n = -1;
-    bool inQuote = false;
-    const int searchStringLength = m_searchString.length();
-    for ( int i = 0; i < searchStringLength; ++i ) {
-        const QChar searchChar = m_searchString.at( i );
-        if ( searchChar == QLatin1Char( '"' ) ) {
-            inQuote = !inQuote;
-        }
-
-        if ( searchChar == QLatin1Char('\\') &&
-             ( i + 1 ) < searchStringLength && m_searchString.at( i + 1 ) == \
                QLatin1Char( '"' ) ) {
-            ++i;
-        }
-
-        if ( inQuote ) {
-            continue;
-        }
-
-        if ( i < searchStringLength &&
-             ( searchChar == QLatin1Char(',') ||
-               ( m_useSemicolonAsSeparator && searchChar == QLatin1Char(';') ) ) ) {
-            n = i;
-        }
-    }
-
-    if ( n >= 0 ) {
-        ++n; // Go past the ","
-
-        const int len = m_searchString.length();
-
-        // Increment past any whitespace...
-        while ( n < len && m_searchString.at( n ).isSpace() ) {
-            ++n;
-        }
-
-        m_previousAddresses = m_searchString.left( n );
-        m_searchString = m_searchString.mid( n ).trimmed();
-    } else {
-        m_previousAddresses.clear();
-    }
-}
-
-void AddresseeLineEdit::Private::slotTriggerDelayedQueries()
-{
-    if (m_searchString.isEmpty() || m_searchString.trimmed().size() <= 2)
-        return;
-
-    if (m_enableBalooSearch) {
-       searchInBaloo();
-    }
-
-    // We send a contactsearch job through akonadi.
-    // This not only searches baloo but also servers if remote search is enabled
-    akonadiPerformSearch();
-}
-
-void AddresseeLineEdit::Private::startSearches()
-{
-    if (!m_delayedQueryTimer.isActive())
-        m_delayedQueryTimer.start(50);
-}
-
-void AddresseeLineEdit::Private::akonadiPerformSearch()
-{
-    kDebug() << "searching akonadi with:" << m_searchString;
-
-    // first, kill all job still in flight, they are no longer current
-    Q_FOREACH( QWeakPointer<Akonadi::Job> job, s_static->akonadiJobsInFlight ) {
-        if ( !job.isNull() ) {
-            job.data()->kill();
-        }
-    }
-    s_static->akonadiJobsInFlight.clear();
-
-    // now start new jobs
-    Akonadi::ContactSearchJob *contactJob = new Akonadi::ContactSearchJob( \
                s_static->akonadiSession );
-    contactJob->fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent \
                );
-    contactJob->setQuery( Akonadi::ContactSearchJob::NameOrEmail, m_searchString,
-                          Akonadi::ContactSearchJob::ContainsWordBoundaryMatch );
-    q->connect( contactJob, SIGNAL(itemsReceived(Akonadi::Item::List)),
-                q, SLOT(slotAkonadiHandleItems(Akonadi::Item::List)) );
-    q->connect( contactJob, SIGNAL(result(KJob*)),
-                q, SLOT(slotAkonadiSearchResult(KJob*)) );
-
-    Akonadi::ContactGroupSearchJob *groupJob = new Akonadi::ContactGroupSearchJob( \
                s_static->akonadiSession );
-    groupJob->fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
-    groupJob->setQuery( Akonadi::ContactGroupSearchJob::Name, m_searchString,
-                        Akonadi::ContactGroupSearchJob::ContainsMatch );
-    q->connect( contactJob, SIGNAL(itemsReceived(Akonadi::Item::List)),
-                q, SLOT(slotAkonadiHandleItems(Akonadi::Item::List)) );
-    q->connect( groupJob, SIGNAL(result(KJob*)),
-                q, SLOT(slotAkonadiSearchResult(KJob*)) );
-
-    s_static->akonadiJobsInFlight.append( contactJob );
-    s_static->akonadiJobsInFlight.append( groupJob );
-    akonadiHandlePending();
-}
-
-void AddresseeLineEdit::Private::akonadiHandlePending()
-{
-    kDebug() << "Pending items: " << s_static->akonadiPendingItems.size();
-    Akonadi::Item::List::iterator it = s_static->akonadiPendingItems.begin();
-    while ( it != s_static->akonadiPendingItems.end() ) {
-        const Akonadi::Item item = *it;
-
-        const int sourceIndex =
-                s_static->akonadiCollectionToCompletionSourceMap.value( \
                item.parentCollection().id(), -1 );
-        if ( sourceIndex >= 0 ) {
-            kDebug() << "identified collection: " << \
                s_static->completionSources[sourceIndex];
-            q->addItem( item, 1, sourceIndex );
-
-            // remove from the pending
-            it = s_static->akonadiPendingItems.erase( it );
-        } else {
-            ++it;
-        }
-    }
-}
-
-void AddresseeLineEdit::Private::doCompletion( bool ctrlT )
-{
-    m_lastSearchMode = ctrlT;
-
-    const KGlobalSettings::Completion mode = q->completionMode();
-
-    if ( mode == KGlobalSettings::CompletionNone ) {
-        return;
-    }
-
-    s_static->completion->setOrder( KCompletion::Weighted );
-
-    // cursor at end of string - or Ctrl+T pressed for substring completion?
-    if ( ctrlT ) {
-        const QStringList completions = adjustedCompletionItems( false );
-
-        if ( completions.count() > 1 ) {
-            ; //m_previousAddresses = prevAddr;
-        } else if ( completions.count() == 1 ) {
-            q->setText( m_previousAddresses + completions.first().trimmed() );
-        }
-
-        // Make sure the completion popup is closed if no matching items were found
-        setCompletedItems( completions, true );
-
-        q->cursorAtEnd();
-        q->setCompletionMode( mode ); //set back to previous mode
-        return;
-    }
-
-    switch ( mode ) {
-    case KGlobalSettings::CompletionPopupAuto:
-    {
-        if ( m_searchString.isEmpty() ) {
-            break;
-        }
-        //else: fall-through to the CompletionPopup case
-    }
-
-    case KGlobalSettings::CompletionPopup:
-    {
-        const QStringList items = adjustedCompletionItems( false );
-        setCompletedItems( items, false );
-    }
-        break;
-
-    case KGlobalSettings::CompletionShell:
-    {
-        const QString match = s_static->completion->makeCompletion( m_searchString \
                );
-        if ( !match.isNull() && match != m_searchString ) {
-            q->setText( m_previousAddresses + match );
-            q->setModified( true );
-            q->cursorAtEnd();
-        }
-    }
-        break;
-
-    case KGlobalSettings::CompletionMan: // Short-Auto in fact
-    case KGlobalSettings::CompletionAuto:
-    {
-        //force autoSuggest in KLineEdit::keyPressed or setCompletedText will have \
                no effect
-        q->setCompletionMode( q->completionMode() );
-
-        if ( !m_searchString.isEmpty() ) {
-
-            //if only our \" is left, remove it since user has not typed it either
-            if ( m_searchExtended && m_searchString == QLatin1String( "\"" ) ) {
-                m_searchExtended = false;
-                m_searchString.clear();
-                q->setText( m_previousAddresses );
-                break;
-            }
-
-            QString match = s_static->completion->makeCompletion( m_searchString );
-
-            if ( !match.isEmpty() ) {
-                if ( match != m_searchString ) {
-                    QString adds = m_previousAddresses + match;
-                    q->setCompletedText( adds );
-                }
-            } else {
-                if ( !m_searchString.startsWith( QLatin1Char( '\"' ) ) ) {
-                    //try with quoted text, if user has not type one already
-                    match = s_static->completion->makeCompletion( QLatin1String( \
                "\"" ) + m_searchString );
-                    if ( !match.isEmpty() && match != m_searchString ) {
-                        m_searchString = QLatin1String( "\"" ) + m_searchString;
-                        m_searchExtended = true;
-                        q->setText( m_previousAddresses + m_searchString );
-                        q->setCompletedText( m_previousAddresses + match );
-                    }
-                } else if ( m_searchExtended ) {
-                    //our added \" does not work anymore, remove it
-                    m_searchString = m_searchString.mid( 1 );
-                    m_searchExtended = false;
-                    q->setText( m_previousAddresses + m_searchString );
-                    //now try again
-                    match = s_static->completion->makeCompletion( m_searchString );
-                    if ( !match.isEmpty() && match != m_searchString ) {
-                        const QString adds = m_previousAddresses + match;
-                        q->setCompletedText( adds );
-                    }
-                }
-            }
-        }
-    }
-        break;
-
-    case KGlobalSettings::CompletionNone:
-    default: // fall through
-        break;
-    }
-}
-
-void AddresseeLineEdit::Private::slotCompletion()
-{
-    // Called by KLineEdit's keyPressEvent for CompletionModes
-    // Auto,Popup -> new text, update search string.
-    // not called for CompletionShell, this is been taken care of
-    // in AddresseeLineEdit::keyPressEvent
-
-    updateSearchString();
-    if ( q->completionBox() ) {
-        q->completionBox()->setCancelledText( m_searchString );
-    }
-
-    startSearches();
-    doCompletion( false );
-}
-
-void AddresseeLineEdit::Private::slotPopupCompletion( const QString &completion )
-{
-    QString c = completion.trimmed();
-    if ( c.endsWith( QLatin1Char( ')' ) ) ) {
-        c = completion.mid( 0, completion.lastIndexOf( QLatin1String( " (" )) \
                ).trimmed();
-    }
-    q->setText( m_previousAddresses + c );
-    q->cursorAtEnd();
-    updateSearchString();
-    q->emitTextCompleted();
-}
-
-void AddresseeLineEdit::Private::slotReturnPressed( const QString & )
-{
-    if ( !q->completionBox()->selectedItems().isEmpty() ) {
-        slotPopupCompletion( q->completionBox()->selectedItems().first()->text() );
-    }
-}
-
-void AddresseeLineEdit::Private::slotStartLDAPLookup()
-{
-    if ( Solid::Networking::status() == Solid::Networking::Unconnected ) {
-        return;
-    }
-
-    const KGlobalSettings::Completion mode = q->completionMode();
-
-    if ( mode == KGlobalSettings::CompletionNone ) {
-        return;
-    }
-
-    if ( !s_static->ldapSearch->isAvailable() ) {
-        return;
-    }
-
-    if ( s_static->ldapLineEdit != q ) {
-        return;
-    }
-
-    startLoadingLDAPEntries();
-}
-
-void AddresseeLineEdit::Private::slotLDAPSearchData( const KLDAP::LdapResult::List \
                &results )
-{
-    if ( results.isEmpty() || s_static->ldapLineEdit != q ) {
-        return;
-    }
-
-    foreach ( const KLDAP::LdapResult &result, results ) {
-        KABC::Addressee contact;
-        contact.setNameFromString( result.name );
-        contact.setEmails( result.email );
-        QString ou;
-
-        if ( m_showOU ) {
-            const int depth = result.dn.depth();
-            for ( int i = 0; i < depth; ++i ) {
-                const QString rdnStr = result.dn.rdnString( i );
-                if ( rdnStr.startsWith( QLatin1String( "ou=" ), Qt::CaseInsensitive \
                ) ) {
-                    ou = rdnStr.mid( 3 );
-                    break;
-                }
-            }
-        }
-
-        if ( !s_static->ldapClientToCompletionSourceMap.contains( \
                result.clientNumber ) ) {
-            s_static->updateLDAPWeights(); // we got results from a new source, so \
                update the completion sources
-        }
-
-        q->addContact( contact, result.completionWeight,
-                       s_static->ldapClientToCompletionSourceMap[ \
                result.clientNumber ], ou );
-    }
-
-    if ( ( q->hasFocus() || q->completionBox()->hasFocus() ) &&
-         q->completionMode() != KGlobalSettings::CompletionNone &&
-         q->completionMode() != KGlobalSettings::CompletionShell ) {
-        q->setText( m_previousAddresses + m_searchString );
-        // only complete again if the user didn't change the selection while
-        // we were waiting; otherwise the completion box will be closed
-        const QListWidgetItem *current = q->completionBox()->currentItem();
-        if ( !current || m_searchString.trimmed() != current->text().trimmed() ) {
-            doCompletion( m_lastSearchMode );
-        }
-    }
-}
-
-void AddresseeLineEdit::Private::slotEditCompletionOrder()
-{
-    init(); // for s_static->ldapSearch
-    if(m_useCompletion){
-        s_static->slotEditCompletionOrder();
-    }
-}
-
-void AddresseeLineEdit::Private::slotUserCancelled( const QString &cancelText )
-{
-    if ( s_static->ldapSearch && s_static->ldapLineEdit == q ) {
-        stopLDAPLookup();
-    }
-
-    q->userCancelled( m_previousAddresses + cancelText ); // in KLineEdit
-}
-
-void AddresseeLineEdit::Private::slotAkonadiHandleItems( const Akonadi::Item::List \
                &items )
-{
-    /* We have to fetch the collections of the items, so that
-       the source name can be correctly labeled.*/
-    foreach ( const Akonadi::Item &item, items ) {
-
-        // check the local cache of collections
-        const int sourceIndex =
-                s_static->akonadiCollectionToCompletionSourceMap.value( \
                item.parentCollection().id(), -1 );
-        if ( sourceIndex == -1 ) {
-            kDebug() << "Fetching New collection: " << item.parentCollection().id();
-            // the collection isn't there, start the fetch job.
-            Akonadi::CollectionFetchJob *collectionJob =
-                    new Akonadi::CollectionFetchJob( item.parentCollection(),
-                                                     \
                Akonadi::CollectionFetchJob::Base,
-                                                     s_static->akonadiSession );
-            connect( collectionJob, \
                SIGNAL(collectionsReceived(Akonadi::Collection::List)),
-                     q, \
                SLOT(slotAkonadiCollectionsReceived(Akonadi::Collection::List)) );
-            /* we don't want to start multiple fetch jobs for the same collection,
-           so insert the collection with an index value of -2 */
-            s_static->akonadiCollectionToCompletionSourceMap.insert( \
                item.parentCollection().id(), -2 );
-            s_static->akonadiPendingItems.append( item );
-        } else if ( sourceIndex == -2 ) {
-            /* fetch job already started, don't need to start another one,
-           so just append the item as pending */
-            s_static->akonadiPendingItems.append( item );
-        } else {
-            q->addItem( item, 1, sourceIndex );
-        }
-    }
-
-    if ( !items.isEmpty() ) {
-        const QListWidgetItem *current = q->completionBox()->currentItem();
-        if ( !current || m_searchString.trimmed() != current->text().trimmed() ) {
-            doCompletion( m_lastSearchMode );
-        }
-    }
-}
-
-void AddresseeLineEdit::Private::slotAkonadiSearchResult( KJob *job )
-{
-    if ( job->error() ) {
-        kWarning() << "Akonadi search job failed: " << job->errorString();
-    } else {
-        Akonadi::ItemSearchJob *searchJob = \
                static_cast<Akonadi::ItemSearchJob*>(job);
-        kDebug() << "Found" << searchJob->items().size() << "items";
-    }
-    const int index = s_static->akonadiJobsInFlight.indexOf( \
                qobject_cast<Akonadi::Job*>( job ) );
-    if( index != -1 )
-        s_static->akonadiJobsInFlight.remove( index );
-}
-
-void AddresseeLineEdit::Private::slotAkonadiCollectionsReceived(
-        const Akonadi::Collection::List &collections )
-{
-    KSharedConfig::Ptr config = KSharedConfig::openConfig( \
                QLatin1String("kpimcompletionorder") );
-    KConfigGroup group( config, "CompletionWeights" );
-    foreach ( const Akonadi::Collection &collection, collections ) {
-        if ( collection.isValid() ) {
-            const QString sourceString = collection.displayName();
-            const int weight = group.readEntry( QString::number(collection.id()), 1 \
                );
-            const int index = q->addCompletionSource( sourceString, weight );
-            kDebug() << "\treceived: " << sourceString << "index: " << index;
-            s_static->akonadiCollectionToCompletionSourceMap.insert( \
                collection.id(), index );
-        }
-    }
-
-    // now that we have added the new collections, recheck our list of pending \
                contacts
-    akonadiHandlePending();
-    // do completion
-    const QListWidgetItem *current = q->completionBox()->currentItem();
-    if ( !current || m_searchString.trimmed() != current->text().trimmed() ) {
-        doCompletion( m_lastSearchMode );
-    }
-}
-
-void AddresseeLineEdit::Private::slotShowOUChanged(bool checked)
-{
-    if ( checked != m_showOU ) {
-        KConfigGroup group( KGlobal::config(), "AddressLineEdit" );
-        group.writeEntry( "ShowOU", checked );
-        m_showOU = checked;
-    }
-}
-
-void AddresseeLineEdit::Private::slotConfigureBalooBlackList()
-{
-    QPointer<KPIM::BlackListBalooEmailCompletionDialog> dlg = new \
                KPIM::BlackListBalooEmailCompletionDialog(q);
-    dlg->setEmailBlackList(m_balooBlackList);
-    if (dlg->exec()) {
-        loadBalooBlackList();
-    }
-    delete dlg;
-}
-
-void AddresseeLineEdit::Private::loadBalooBlackList()
-{
-    KSharedConfig::Ptr config = KSharedConfig::openConfig( \
                QLatin1String("kpimbalooblacklist") );
-    KConfigGroup group( config, "AddressLineEdit" );
-    m_balooBlackList = group.readEntry( "BalooBackList", QStringList() );
-    m_domainExcludeList = group.readEntry("ExcludeDomain", QStringList());
-}
 
 AddresseeLineEdit::AddresseeLineEdit( QWidget *parent, bool enableCompletion )
     : KLineEdit( parent ), d( new Private( this, enableCompletion ) )
diff --git a/libkdepim/addressline/addresseelineedit.cpp \
b/libkdepim/addressline/addresseelineedit_p.cpp similarity index 60%
copy from libkdepim/addressline/addresseelineedit.cpp
copy to libkdepim/addressline/addresseelineedit_p.cpp
index f46deaa..bb1b2ee 100644
--- a/libkdepim/addressline/addresseelineedit.cpp
+++ b/libkdepim/addressline/addresseelineedit_p.cpp
@@ -1,83 +1,31 @@
 /*
-  This file is part of libkdepim.
-
-  Copyright (c) 2002 Helge Deller <deller@gmx.de>
-  Copyright (c) 2002 Lubos Lunak <llunak@suse.cz>
-  Copyright (c) 2001,2003 Carsten Pfeiffer <pfeiffer@kde.org>
-  Copyright (c) 2001 Waldo Bastian <bastian@kde.org>
-  Copyright (c) 2004 Daniel Molkentin <danimo@klaralvdalens-datakonsult.se>
-  Copyright (c) 2004 Karl-Heinz Zimmer <khz@klaralvdalens-datakonsult.se>
-
-  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
+  Copyright (c) 2015 Montel Laurent <montel@kde.org>
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License, version 2, as
+  published by the Free Software Foundation.
+
+  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
-  Library General Public License for more details.
+  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.
+  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 "addresseelineedit.h"
-#include "ldap/ldapclientsearch.h"
 #include "completionordereditor.h"
-#include "addressline/blacklistbaloocompletion/blacklistbalooemailcompletiondialog.h"
  #include "kmailcompletion.h"
-#include "baloocompletionemail.h"
-
-#include <Akonadi/Contact/ContactSearchJob>
-#include <Akonadi/Contact/ContactGroupSearchJob>
-#include <Akonadi/CollectionFetchJob>
-#include <Akonadi/EntityDisplayAttribute>
-#include <Akonadi/ItemFetchScope>
-#include <Akonadi/RecursiveItemFetchJob>
-#include <Akonadi/Session>
-#include <Akonadi/Job>
-
-#include <baloo/pim/contactcompleter.h>
-
-#include <KPIMUtils/Email>
-#include <KColorScheme>
-
-#include <KLDAP/LdapServer>
-
-#include <KMime/Util>
-
-#include <KConfigGroup>
-#include <KCompletionBox>
-#include <KDebug>
-#include <KLocale>
-#include <KStandardDirs>
-#include <KStandardShortcut>
-#include <KUrl>
-
-#include <solid/networking.h>
-
-#include <QApplication>
-#include <QCursor>
-#include <QObject>
-#include <QRegExp>
-#include <QEvent>
-#include <QClipboard>
-#include <QKeyEvent>
-#include <QDropEvent>
-#include <QMouseEvent>
-#include <QMenu>
-#include <QTimer>
-#include <QtDBus/QDBusConnection>
-
-using namespace KPIM;
+
+#include <QMap>
+
 
 namespace KPIM {
 typedef QMap< QString, QPair<int,int> > CompletionItemsMap;
 }
 
+namespace KPIM {
 class AddresseeLineEditStatic
 {
 public:
@@ -1030,562 +978,4 @@ void AddresseeLineEdit::Private::loadBalooBlackList()
     m_balooBlackList = group.readEntry( "BalooBackList", QStringList() );
     m_domainExcludeList = group.readEntry("ExcludeDomain", QStringList());
 }
-
-AddresseeLineEdit::AddresseeLineEdit( QWidget *parent, bool enableCompletion )
-    : KLineEdit( parent ), d( new Private( this, enableCompletion ) )
-{
-    setObjectName( newLineEditObjectName() );
-    setClickMessage( QString() );
-
-    d->init();
-}
-
-AddresseeLineEdit::~AddresseeLineEdit()
-{
-    if ( s_static->ldapSearch && s_static->ldapLineEdit == this ) {
-        d->stopLDAPLookup();
-    }
-    delete d;
-}
-
-void AddresseeLineEdit::setFont( const QFont &font )
-{
-    KLineEdit::setFont( font );
-
-    if ( d->m_useCompletion ) {
-        completionBox()->setFont( font );
-    }
-}
-
-void AddresseeLineEdit::setEnableBalooSearch(bool enable)
-{
-    d->m_enableBalooSearch = enable;
-}
-
-void AddresseeLineEdit::allowSemicolonAsSeparator( bool useSemicolonAsSeparator )
-{
-    d->m_useSemicolonAsSeparator = useSemicolonAsSeparator;
-}
-
-void AddresseeLineEdit::keyPressEvent( QKeyEvent *event )
-{
-    bool accept = false;
-
-    const int key = event->key() | event->modifiers();
-
-    if ( KStandardShortcut::shortcut( KStandardShortcut::SubstringCompletion \
                ).contains( key ) ) {
-        //TODO: add LDAP substring lookup, when it becomes available in \
                KPIM::LDAPSearch
-        d->updateSearchString();
-        d->startSearches();
-        d->doCompletion( true );
-        accept = true;
-    } else if ( KStandardShortcut::shortcut( KStandardShortcut::TextCompletion \
                ).contains( key ) ) {
-        const int len = text().length();
-
-        if ( len == cursorPosition() ) { // at End?
-            d->updateSearchString();
-            d->startSearches();
-            d->doCompletion( true );
-            accept = true;
-        }
-    }
-
-    const QString oldContent = text();
-    if ( !accept ) {
-        KLineEdit::keyPressEvent( event );
-    }
-
-    // if the text didn't change (eg. because a cursor navigation key was pressed)
-    // we don't need to trigger a new search
-    if ( oldContent == text() ) {
-        return;
-    }
-
-    if ( event->isAccepted() ) {
-        d->updateSearchString();
-
-        QString searchString( d->m_searchString );
-        //LDAP does not know about our string manipulation, remove it
-        if ( d->m_searchExtended ) {
-            searchString = d->m_searchString.mid( 1 );
-        }
-
-        if ( d->m_useCompletion && s_static->ldapTimer ) {
-            if ( s_static->ldapText != searchString || s_static->ldapLineEdit != \
                this ) {
-                d->stopLDAPLookup();
-            }
-
-            s_static->ldapText = searchString;
-            s_static->ldapLineEdit = this;
-            s_static->ldapTimer->setSingleShot( true );
-            s_static->ldapTimer->start( 500 );
-        }
-    }
-}
-
-void AddresseeLineEdit::insert( const QString &t )
-{
-    if ( !d->m_smartPaste ) {
-        KLineEdit::insert( t );
-        return;
-    }
-
-    QString newText = t.trimmed();
-    if ( newText.isEmpty() ) {
-        return;
-    }
-
-    // remove newlines in the to-be-pasted string
-    QStringList lines = newText.split( QRegExp( QLatin1String( "\r?\n" ) ), \
                QString::SkipEmptyParts );
-    QStringList::iterator end( lines.end() );
-    for ( QStringList::iterator it = lines.begin(); it != end; ++it ) {
-        // remove trailing commas and whitespace
-        (*it).remove( QRegExp( QLatin1String( ",?\\s*$" ) ) );
-    }
-    newText = lines.join( QLatin1String( ", " ) );
-
-    if ( newText.startsWith( QLatin1String( "mailto:" ) ) ) {
-        const KUrl url( newText );
-        newText = url.path();
-    } else if ( newText.indexOf( QLatin1String( " at " ) ) != -1 ) {
-        // Anti-spam stuff
-        newText.replace( QLatin1String( " at " ), QLatin1String( "@" ) );
-        newText.replace( QLatin1String( " dot " ), QLatin1String( "." ) );
-    } else if ( newText.indexOf( QLatin1String( "(at)" ) ) != -1 ) {
-        newText.replace( QRegExp( QLatin1String( "\\s*\\(at\\)\\s*" ) ), \
                QLatin1String( "@" ) );
-    }
-
-    QString contents = text();
-    int start_sel = 0;
-    int pos = cursorPosition();
-
-    if ( hasSelectedText() ) {
-        // Cut away the selection.
-        start_sel = selectionStart();
-        pos = start_sel;
-        contents = contents.left( start_sel ) + contents.mid( start_sel + \
                selectedText().length() );
-    }
-
-    int eot = contents.length();
-    while ( ( eot > 0 ) && contents.at( eot - 1 ).isSpace() ) {
-        --eot;
-    }
-    if ( eot == 0 ) {
-        contents.clear();
-    } else if ( pos >= eot ) {
-        if ( contents.at( eot - 1 ) == QLatin1Char( ',' ) ) {
-            --eot;
-        }
-        contents.truncate( eot );
-        contents += QLatin1String( ", " );
-        pos = eot + 2;
-    }
-
-    contents = contents.left( pos ) + newText + contents.mid( pos );
-    setText( contents );
-    setModified( true );
-    setCursorPosition( pos + newText.length() );
-}
-
-void AddresseeLineEdit::setText( const QString & text )
-{
-    const int cursorPos = cursorPosition();
-    KLineEdit::setText( text.trimmed() );
-    setCursorPosition( cursorPos );
-}
-
-void AddresseeLineEdit::paste()
-{
-    if ( d->m_useCompletion ) {
-        d->m_smartPaste = true;
-    }
-
-    KLineEdit::paste();
-    d->m_smartPaste = false;
-}
-
-void AddresseeLineEdit::mouseReleaseEvent( QMouseEvent *event )
-{
-    // reimplemented from QLineEdit::mouseReleaseEvent()
-#ifndef QT_NO_CLIPBOARD
-    if ( d->m_useCompletion &&
-         QApplication::clipboard()->supportsSelection() &&
-         !isReadOnly() &&
-         event->button() == Qt::MidButton ) {
-        d->m_smartPaste = true;
-    }
-#endif
-
-    KLineEdit::mouseReleaseEvent( event );
-    d->m_smartPaste = false;
-}
-
-#ifndef QT_NO_DRAGANDDROP
-void AddresseeLineEdit::dropEvent( QDropEvent *event )
-{
-    if ( !isReadOnly() ) {
-        const KUrl::List uriList = KUrl::List::fromMimeData( event->mimeData() );
-        if ( !uriList.isEmpty() ) {
-            QString contents = text();
-            // remove trailing white space and comma
-            int eot = contents.length();
-            while ( ( eot > 0 ) && contents.at( eot - 1 ).isSpace() ) {
-                --eot;
-            }
-            if ( eot == 0 ) {
-                contents.clear();
-            } else if ( contents.at( eot - 1 ) == QLatin1Char(',') ) {
-                --eot;
-                contents.truncate( eot );
-            }
-            bool mailtoURL = false;
-            // append the mailto URLs
-            foreach ( const KUrl &url, uriList ) {
-                if ( url.protocol() == QLatin1String( "mailto" ) ) {
-                    mailtoURL = true;
-                    QString address;
-                    address = KUrl::fromPercentEncoding( url.path().toLatin1() );
-                    address = KMime::decodeRFC2047String( address.toLatin1() );
-                    if ( !contents.isEmpty() ) {
-                        contents.append( QLatin1String( ", " ) );
-                    }
-                    contents.append( address );
-                }
-            }
-            if ( mailtoURL ) {
-                setText( contents );
-                setModified( true );
-                return;
-            }
-        } else {
-            // Let's see if this drop contains a comma separated list of emails
-            const QString dropData = QString::fromUtf8( event->encodedData( \
                "text/plain" ) );
-            const QStringList addrs = KPIMUtils::splitAddressList( dropData );
-            if ( !addrs.isEmpty() ) {
-                setText( KPIMUtils::normalizeAddressesAndDecodeIdn( dropData ) );
-                setModified( true );
-                return;
-            }
-        }
-    }
-
-    if ( d->m_useCompletion ) {
-        d->m_smartPaste = true;
-    }
-
-    QLineEdit::dropEvent( event );
-    d->m_smartPaste = false;
-}
-#endif // QT_NO_DRAGANDDROP
-
-void AddresseeLineEdit::cursorAtEnd()
-{
-    setCursorPosition( text().length() );
-}
-
-void AddresseeLineEdit::enableCompletion( bool enable )
-{
-    d->m_useCompletion = enable;
 }
-
-void AddresseeLineEdit::addItem( const Akonadi::Item &item, int weight, int source )
-{
-    //Let Akonadi results always have a higher weight than baloo results
-    if ( item.hasPayload<KABC::Addressee>() ) {
-        addContact( item.payload<KABC::Addressee>(), weight + 1, source );
-    } else if ( item.hasPayload<KABC::ContactGroup>() ) {
-        addContactGroup( item.payload<KABC::ContactGroup>(), weight + 1, source );
-    }
-}
-
-void AddresseeLineEdit::addContactGroup( const KABC::ContactGroup &group, int \
                weight, int source )
-{
-    d->addCompletionItem( group.name(), weight, source );
-}
-
-void AddresseeLineEdit::addContact( const KABC::Addressee &addr, int weight, int \
                source, QString append )
-{
-    const QStringList emails = addr.emails();
-    QStringList::ConstIterator it;
-    int isPrefEmail = 1; //first in list is preferredEmail
-    QStringList::ConstIterator end( emails.constEnd() );
-    for ( it = emails.constBegin(); it != end; ++it ) {
-        //TODO: highlight preferredEmail
-        const QString email( (*it) );
-        const QString givenName = addr.givenName();
-        const QString familyName= addr.familyName();
-        const QString nickName  = addr.nickName();
-        QString fullEmail       = addr.fullEmail( email );
-
-        QString appendix;
-
-        if ( !append.isEmpty() ) {
-            appendix = QLatin1String( " (%1)" );
-            append = append.replace( QLatin1String("("), QLatin1String("[") );
-            append = append.replace( QLatin1String(")"), QLatin1String("]") );
-            appendix = appendix.arg( append );
-        }
-
-        // Prepare "givenName" + ' ' + "familyName"
-        QString fullName = givenName;
-        if (!familyName.isEmpty()) {
-            if (!fullName.isEmpty())
-                fullName += QLatin1Char(' ');
-            fullName += familyName;
-        }
-
-        // Finally, we can add the completion items
-        if (!fullName.isEmpty()) {
-            const QString address = KPIMUtils::normalizedAddress(fullName, email, \
                QString());
-            if (fullEmail != address) {
-                // This happens when fullEmail contains a middle name, while our own \
                fullName+email only has "first last".
-                // Let's offer both, the fullEmail with 3 parts, looks a tad formal.
-                d->addCompletionItem(address + appendix, weight + isPrefEmail, \
                source);
-            }
-        }
-
-        QStringList keyWords;
-        if (!nickName.isEmpty()) {
-            keyWords.append(nickName);
-        }
-
-        d->addCompletionItem( fullEmail + appendix, weight + isPrefEmail, source, \
                &keyWords );
-
-        isPrefEmail = 0;
-    }
-}
-
-#ifndef QT_NO_CONTEXTMENU
-void AddresseeLineEdit::contextMenuEvent( QContextMenuEvent *event )
-{
-    QMenu *menu = createStandardContextMenu();
-    if ( menu ) { // can be 0 on platforms with only a touch interface
-        menu->exec( event->globalPos() );
-        delete menu;
-    }
-}
-
-QMenu *AddresseeLineEdit::createStandardContextMenu()
-{
-    // disable modes not supported by KMailCompletion
-    setCompletionModeDisabled( KGlobalSettings::CompletionMan );
-    setCompletionModeDisabled( KGlobalSettings::CompletionPopupAuto );
-
-    QMenu *menu = KLineEdit::createStandardContextMenu();
-    if ( !menu ) {
-        return 0;
-    }
-
-    if ( d->m_useCompletion ) {
-        menu->addAction( i18n( "Configure Completion Order..." ),
-                         this, SLOT(slotEditCompletionOrder()) );
-
-        QAction *showOU = new QAction(i18n( "Show Organization Unit for LDAP \
                results" ),menu);
-        showOU->setCheckable(true);
-
-        showOU->setChecked( d->m_showOU );
-        connect(showOU, SIGNAL(triggered(bool)), this, \
                SLOT(slotShowOUChanged(bool)));
-        menu->addAction(showOU);
-    }
-
-    //Add i18n in kf5
-    QAction *configureBalooBlackList = new QAction(QLatin1String( "Configure Email \
                Blacklist" ),menu);
-    connect(configureBalooBlackList, SIGNAL(triggered(bool)), this, \
                SLOT(slotConfigureBalooBlackList()));
-    menu->addAction(configureBalooBlackList);
-
-    return menu;
-}
-#endif
-
-void KPIM::AddresseeLineEdit::removeCompletionSource(const QString &source)
-{
-    s_static->removeCompletionSource(source);
-}
-
-int KPIM::AddresseeLineEdit::addCompletionSource( const QString &source, int weight \
                )
-{
-    return s_static->addCompletionSource(source,weight);
-}
-
-bool KPIM::AddresseeLineEdit::eventFilter( QObject *object, QEvent *event )
-{
-    if ( d->m_completionInitialized &&
-         ( object == completionBox() ||
-           completionBox()->findChild<QWidget*>( object->objectName() ) == object ) \
                ) {
-        if ( event->type() == QEvent::MouseButtonPress ||
-             event->type() == QEvent::MouseMove ||
-             event->type() == QEvent::MouseButtonRelease ||
-             event->type() == QEvent::MouseButtonDblClick ) {
-
-            const QMouseEvent* mouseEvent = static_cast<QMouseEvent*>( event );
-            // find list box item at the event position
-            QListWidgetItem *item = completionBox()->itemAt( mouseEvent->pos() );
-            if ( !item ) {
-                // In the case of a mouse move outside of the box we don't want
-                // the parent to fuzzy select a header by mistake.
-                bool eat = event->type() == QEvent::MouseMove;
-                return eat;
-            }
-            // avoid selection of headers on button press, or move or release while
-            // a button is pressed
-            const Qt::MouseButtons buttons = mouseEvent->buttons();
-            if ( event->type() == QEvent::MouseButtonPress ||
-                 event->type() == QEvent::MouseButtonDblClick ||
-                 buttons & Qt::LeftButton || buttons & Qt::MidButton ||
-                 buttons & Qt::RightButton ) {
-                if ( itemIsHeader( item ) ) {
-                    return true; // eat the event, we don't want anything to happen
-                } else {
-                    // if we are not on one of the group heading, make sure the item
-                    // below or above is selected, not the heading, inadvertedly, \
                due
-                    // to fuzzy auto-selection from QListBox
-                    completionBox()->setCurrentItem( item );
-                    item->setSelected( true );
-                    if ( event->type() == QEvent::MouseMove ) {
-                        return true; // avoid fuzzy selection behavior
-                    }
-                }
-            }
-        }
-    }
-
-    if ( ( object == this ) &&
-         ( event->type() == QEvent::ShortcutOverride ) ) {
-        QKeyEvent *keyEvent = static_cast<QKeyEvent*>( event );
-        if ( keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down ||
-             keyEvent->key() == Qt::Key_Tab ) {
-            keyEvent->accept();
-            return true;
-        }
-    }
-
-    if ( ( object == this ) &&
-         ( event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease \
                ) &&
-         completionBox()->isVisible() ) {
-        const QKeyEvent *keyEvent = static_cast<QKeyEvent*>( event );
-        int currentIndex = completionBox()->currentRow();
-        if ( currentIndex < 0 ) {
-            return true;
-        }
-        if ( keyEvent->key() == Qt::Key_Up ) {
-            //kDebug() <<"EVENTFILTER: Qt::Key_Up currentIndex=" << currentIndex;
-            // figure out if the item we would be moving to is one we want
-            // to ignore. If so, go one further
-            const QListWidgetItem *itemAbove = completionBox()->item( currentIndex \
                );
-            if ( itemAbove && itemIsHeader( itemAbove ) ) {
-                // there is a header above is, check if there is even further up
-                // and if so go one up, so it'll be selected
-                if ( currentIndex > 0 && completionBox()->item( currentIndex - 1 ) ) \
                {
-                    //kDebug() <<"EVENTFILTER: Qt::Key_Up -> skipping" << \
                currentIndex - 1;
-                    completionBox()->setCurrentRow( currentIndex - 1 );
-                    completionBox()->item( currentIndex - 1 )->setSelected( true );
-                } else if ( currentIndex == 0 ) {
-                    // nothing to skip to, let's stay where we are, but make sure \
                the
-                    // first header becomes visible, if we are the first real entry
-                    completionBox()->scrollToItem( completionBox()->item( 0 ) );
-                    QListWidgetItem *item = completionBox()->item( currentIndex );
-                    if ( item ) {
-                        if ( itemIsHeader( item ) ) {
-                            currentIndex++;
-                            item = completionBox()->item( currentIndex );
-                        }
-                        completionBox()->setCurrentItem( item );
-                        item->setSelected( true );
-                    }
-                }
-
-                return true;
-            }
-        } else if ( keyEvent->key() == Qt::Key_Down ) {
-            // same strategy for downwards
-            //kDebug() <<"EVENTFILTER: Qt::Key_Down. currentIndex=" << currentIndex;
-            const QListWidgetItem *itemBelow = completionBox()->item( currentIndex \
                );
-            if ( itemBelow && itemIsHeader( itemBelow ) ) {
-                if ( completionBox()->item( currentIndex + 1 ) ) {
-                    //kDebug() <<"EVENTFILTER: Qt::Key_Down -> skipping" << \
                currentIndex+1;
-                    completionBox()->setCurrentRow( currentIndex + 1 );
-                    completionBox()->item( currentIndex + 1 )->setSelected( true );
-                } else {
-                    // nothing to skip to, let's stay where we are
-                    QListWidgetItem *item = completionBox()->item( currentIndex );
-                    if ( item ) {
-                        completionBox()->setCurrentItem( item );
-                        item->setSelected( true );
-                    }
-                }
-
-                return true;
-            }
-            // special case of the initial selection, which is unfortunately a \
                header.
-            // Setting it to selected tricks KCompletionBox into not treating is \
                special
-            // and selecting making it current, instead of the one below.
-            QListWidgetItem *item = completionBox()->item( currentIndex );
-            if ( item && itemIsHeader( item ) ) {
-                completionBox()->setCurrentItem( item );
-                item->setSelected( true );
-            }
-        } else if ( event->type() == QEvent::KeyRelease &&
-                    ( keyEvent->key() == Qt::Key_Tab || keyEvent->key() == \
                Qt::Key_Backtab ) ) {
-            /// first, find the header of the current section
-            QListWidgetItem *myHeader = 0;
-            int myHeaderIndex = -1;
-            const int iterationStep = keyEvent->key() == Qt::Key_Tab ?  1 : -1;
-            int index = qMin( qMax( currentIndex - iterationStep, 0 ), \
                completionBox()->count() - 1 );
-            while ( index >= 0 ) {
-                if ( itemIsHeader( completionBox()->item( index ) ) ) {
-                    myHeader = completionBox()->item( index );
-                    myHeaderIndex = index;
-                    break;
-                }
-
-                index--;
-            }
-            Q_ASSERT( myHeader ); // we should always be able to find a header
-
-            // find the next header (searching backwards, for Qt::Key_Backtab)
-            QListWidgetItem *nextHeader = 0;
-
-            // when iterating forward, start at the currentindex, when backwards,
-            // one up from our header, or at the end
-            uint j;
-            if ( keyEvent->key() == Qt::Key_Tab ) {
-                j = currentIndex;
-            } else {
-                index = myHeaderIndex;
-                if ( index == 0 ) {
-                    j = completionBox()->count() - 1;
-                } else {
-                    j = ( index - 1 ) % completionBox()->count();
-                }
-            }
-            while ( ( nextHeader = completionBox()->item( j ) ) && nextHeader != \
                myHeader ) {
-                if ( itemIsHeader( nextHeader ) ) {
-                    break;
-                }
-                j = ( j + iterationStep ) % completionBox()->count();
-            }
-
-            if ( nextHeader && nextHeader != myHeader ) {
-                QListWidgetItem *item = completionBox()->item( j + 1 );
-                if ( item && !itemIsHeader( item ) ) {
-                    completionBox()->setCurrentItem( item );
-                    item->setSelected( true );
-                }
-            }
-
-            return true;
-        }
-    }
-
-    return KLineEdit::eventFilter( object, event );
-}
-
-void AddresseeLineEdit::emitTextCompleted()
-{
-    emit textCompleted();
-}
-
-
-
-
-#include "moc_addresseelineedit.cpp"


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic