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

List:       kmail-devel
Subject:    Re: Address completion (Re: Duplicates)
From:       Christian <schaarsc () gmx ! de>
Date:       2006-09-23 23:56:18
Message-ID: 200609240156.19186.schaarsc () gmx ! de
[Download RAW message or body]

Hi David and Ingo!

thanks for your comments. I have put some more thoughts into the problem and 
fixed some other stuff that came up during testing. From my point of view the 
patch is complete and can be committed. What do you think?

Regards
Christian

kdepim.diff contains the following changes:
1) RecipientsEditor, RecipientsView RecipientsLine ... KMComposeWin
store and keep track of completionMode
I have made View and Line friends, IMHO makes the code easier to read than the  
alternative: forward signals from and  to 
RecipientsLineEdit->RecipientsView->RecipientsEditor->...

2) AddresseeLineEdit
- CompletionAuto will use these strings for lookup
nickname <email>
given last <email>
last given <email>
email
- Other CompletionModes (Popup) will use KMailCompletion
same lookups but popup contains always addr.fullEmail()
- removed PopupAuto and CompletionMan from RMB-menu

3) LDAP will repeat last doComplete instead of new one

4) Cancel should no longer delete line

I think that there is a bug in KCompletion::substringCompletion, fix is 
included in kcompletion_substringCompletion.diff
I am not sure if this should go into 3.5, as it can break other peoples 
workarounds. mine for example :-)

and then there are the double quotes from Addressee::setNameFromString
This method cannot handle strings with quotes 
"last, first" --> givenName = first"; familyName="last
fixed in addressee_setNameFromString.diff

["kcompletion_substringCompletion.diff" (text/x-diff)]

Index: kdecore/kcompletion.cpp
===================================================================
--- kdecore/kcompletion.cpp	(revision 585505)
+++ kdecore/kcompletion.cpp	(working copy)
@@ -275,7 +275,6 @@
     for( ; it != list.end(); ++it ) {
         QString item = *it;
         if ( item.find( string, 0, false ) != -1 ) { // always case insensitive
-            postProcessMatch( &item );
             matches.append( item );
         }
     }
@@ -283,6 +282,7 @@
     if ( matches.isEmpty() )
         doBeep( NoMatch );
 
+    postProcessMatches( &matches );
     return matches;
 }
 

["addressee_setNameFromString.diff" (text/x-diff)]

Index: kabc/scripts/addressee.src.cpp
===================================================================
--- kabc/scripts/addressee.src.cpp	(revision 585505)
+++ kabc/scripts/addressee.src.cpp	(working copy)
@@ -182,8 +182,12 @@
 
 --DEFINITIONS--
 
-void Addressee::setNameFromString( const QString &str )
+void Addressee::setNameFromString( const QString &s )
 {
+  QString str = s;
+  if ( !str.isEmpty() && s[ 0 ] == '"' && s[ s.length() - 1 ] == '"' )
+    str = s.mid( 1, s.length() - 2 );
+
   setFormattedName( str );
   setName( str );
 

["kdepim.diff" (text/x-diff)]

Index: kmail/recipientseditor.h
===================================================================
--- kmail/recipientseditor.h	(revision 585502)
+++ kmail/recipientseditor.h	(working copy)
@@ -158,6 +158,7 @@
     void slotTypeModified();
 
   private:
+    friend class RecipientsView;
     QComboBox *mCombo;
     RecipientLineEdit *mEdit;
     QPushButton *mRemoveButton;
@@ -205,9 +206,11 @@
       */
     int setFirstColumnWidth( int );
 
+    void setCompletionMode ( KGlobalSettings::Completion );
+
   public slots:
     RecipientLine *addLine();
-
+    void slotCompletionModeChanged ( KGlobalSettings::Completion );
     void setFocus();
     void setFocusTop();
     void setFocusBottom();
@@ -217,6 +220,7 @@
     void focusUp();
     void focusDown();
     void focusRight();
+    void completionModeChanged( KGlobalSettings::Completion );
 
   protected:
     void viewportResizeEvent( QResizeEvent * );
@@ -237,6 +241,7 @@
     int mLineHeight;
     int mFirstColumnWidth;
     bool mModified;
+    KGlobalSettings::Completion mCompletionMode;
 };
 
 class RecipientsToolTip : public QToolTip
@@ -328,6 +333,11 @@
       */
     int setFirstColumnWidth( int );
 
+    /**
+     * Set completion mode for lines
+     */
+    void setCompletionMode( KGlobalSettings::Completion );
+
   public slots:
     void setFocus();
     void setFocusTop();
@@ -339,6 +349,7 @@
   signals:
     void focusUp();
     void focusDown();
+    void completionModeChanged( KGlobalSettings::Completion );
 
   protected slots:
     void slotPickedRecipient( const Recipient & );
@@ -347,6 +358,10 @@
     RecipientsView *mRecipientsView;
     SideWidget* mSideWidget;
     bool mModified;
+  
+  private slots:
+    // forward completionModeChanged from RecipientsView to outside world
+    void slotCompletionModeChanged( KGlobalSettings::Completion );
 };
 
 #endif
Index: kmail/kmcomposewin.cpp
===================================================================
--- kmail/kmcomposewin.cpp	(revision 585502)
+++ kmail/kmcomposewin.cpp	(working copy)
@@ -255,6 +255,8 @@
     //mBtnFrom = 0;
 
     mRecipientsEditor = new RecipientsEditor( mMainWidget );
+    connect(mRecipientsEditor,SIGNAL(completionModeChanged(KGlobalSettings::Completion)),
 +          SLOT(slotCompletionModeChanged(KGlobalSettings::Completion)));
 
     mRecipientsEditor->setFocus();
   }
@@ -581,6 +583,8 @@
     mEdtCc->setCompletionMode( \
                (KGlobalSettings::Completion)GlobalSettings::self()->completionMode() \
                );
     mEdtBcc->setCompletionMode( \
(KGlobalSettings::Completion)GlobalSettings::self()->completionMode() );  }
+  else
+    mRecipientsEditor->setCompletionMode( \
(KGlobalSettings::Completion)GlobalSettings::self()->completionMode() );  
   readColorConfig();
 
Index: kmail/recipientseditor.cpp
===================================================================
--- kmail/recipientseditor.cpp	(revision 585502)
+++ kmail/recipientseditor.cpp	(working copy)
@@ -327,6 +327,8 @@
   addLine();
   setResizePolicy( QScrollView::Manual );
   setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
+
+  mCompletionMode = KGlobalSettings::completionMode();
 }
 
 RecipientLine *RecipientsView::activeLine()
@@ -348,6 +350,7 @@
 {
   RecipientLine *line = new RecipientLine( viewport() );
   addChild( line, 0, mLines.count() * mLineHeight );
+  line->mEdit->setCompletionMode( mCompletionMode );
   line->show();
   connect( line, SIGNAL( returnPressed( RecipientLine * ) ),
     SLOT( slotReturnPressed( RecipientLine * ) ) );
@@ -361,6 +364,8 @@
   connect( line, SIGNAL( countChanged() ), SLOT( calculateTotal() ) );
   connect( line, SIGNAL( typeModified( RecipientLine * ) ),
     SLOT( slotTypeModified( RecipientLine * ) ) );
+  connect( line->mEdit, SIGNAL( completionModeChanged( KGlobalSettings::Completion ) \
), +    SLOT( slotCompletionModeChanged( KGlobalSettings::Completion ) ) );
 
   if ( mLines.last() ) {
     if ( mLines.count() == 1 ) {
@@ -574,6 +579,23 @@
   return recipients;
 }
 
+void RecipientsView::slotCompletionModeChanged ( KGlobalSettings::Completion mode )
+{
+	setCompletionMode( mode ); //change alle lines
+	emit completionModeChanged( mode ); //report change to RecipientsEditor
+}
+
+void RecipientsView::setCompletionMode ( KGlobalSettings::Completion mode )
+{
+	mCompletionMode = mode;
+	QPtrListIterator<RecipientLine> it( mLines );
+	RecipientLine *line;
+	while( ( line = it.current() ) ) {
+	  line->mEdit->setCompletionMode( mode );
+	  ++it;
+	}
+}
+
 void RecipientsView::removeRecipient( const QString & recipient,
                                       Recipient::Type type )
 {
@@ -804,6 +826,8 @@
   topLayout->addWidget( mRecipientsView );
   connect( mRecipientsView, SIGNAL( focusUp() ), SIGNAL( focusUp() ) );
   connect( mRecipientsView, SIGNAL( focusDown() ), SIGNAL( focusDown() ) );
+  connect( mRecipientsView, SIGNAL( completionModeChanged( \
KGlobalSettings::Completion ) ), +    SLOT( slotCompletionModeChanged( \
KGlobalSettings::Completion ) ) );  
   mSideWidget = new SideWidget( mRecipientsView, this );
   topLayout->addWidget( mSideWidget );
@@ -944,4 +968,13 @@
   mSideWidget->pickRecipient();
 }
 
+void RecipientsEditor::slotCompletionModeChanged( KGlobalSettings::Completion mode )
+{
+  emit completionModeChanged( mode ); //forward change from view to kmcomposer
+}
+
+void RecipientsEditor::setCompletionMode( KGlobalSettings::Completion mode )
+{
+  mRecipientsView->setCompletionMode( mode );
+}
 #include "recipientseditor.moc"
Index: libkdepim/addresseelineedit.h
===================================================================
--- libkdepim/addresseelineedit.h	(revision 585502)
+++ libkdepim/addresseelineedit.h	(working copy)
@@ -50,6 +50,22 @@
 
 namespace KPIM {
 
+class KMailCompletion : public KCompletion
+{
+  Q_OBJECT
+
+  public:
+    KMailCompletion();
+    virtual void clear();
+    QString makeCompletion( const QString &string );
+    QStringList substringCompletion( const QString &string ) const;
+    void addItemWithKeys( const QString& item, int weight, const QStringList * \
keyWords); +    virtual void postProcessMatches( QStringList * pMatches )const;
+
+  private:
+    QMap< QString, QStringList > m_keyMap;
+};
+					 
 class KDE_EXPORT AddresseeLineEdit : public ClickLineEdit, public DCOPObject
 {
   K_DCOP
@@ -120,9 +136,10 @@
     void stopLDAPLookup();
 
     void setCompletedItems( const QStringList& items, bool autoSuggest );
-    void addCompletionItem( const QString& string, int weight, int source );
+    void addCompletionItem( const QString& string, int weight, int source, const \
QStringList * keyWords=0 );  QString completionSearchText( QString& );
     const QStringList getAdjustedCompletionItems( bool fullSearch );
+    void updateSearchString();
 
     QString m_previousAddresses;
     QString m_searchString;
@@ -130,11 +147,12 @@
     bool m_completionInitialized;
     bool m_smartPaste;
     bool m_addressBookConnected;
+    bool m_lastSearchMode;
 
     //QMap<QString, KABC::Addressee> m_contactMap;
 
     static bool s_addressesDirty;
-    static KCompletion *s_completion;
+    static KMailCompletion *s_completion;
     static CompletionItemsMap* s_completionItemMap;
     static QTimer *s_LDAPTimer;
     static KPIM::LdapSearch *s_LDAPSearch;
Index: libkdepim/addresseelineedit.cpp
===================================================================
--- libkdepim/addresseelineedit.cpp	(revision 585502)
+++ libkdepim/addresseelineedit.cpp	(working copy)
@@ -43,7 +43,7 @@
 
 #include <kcompletionbox.h>
 #include <kcursor.h>
-#include <kdebug.h>
+#include <kde/kdebug.h>
 #include <kstandarddirs.h>
 #include <kstaticdeleter.h>
 #include <kstdaccel.h>
@@ -61,7 +61,7 @@
 
 using namespace KPIM;
 
-KCompletion * AddresseeLineEdit::s_completion = 0L;
+KMailCompletion * AddresseeLineEdit::s_completion = 0L;
 KPIM::CompletionItemsMap* AddresseeLineEdit::s_completionItemMap = 0L;
 QStringList* AddresseeLineEdit::s_completionSources = 0L;
 bool AddresseeLineEdit::s_addressesDirty = false;
@@ -70,7 +70,7 @@
 QString* AddresseeLineEdit::s_LDAPText = 0L;
 AddresseeLineEdit* AddresseeLineEdit::s_LDAPLineEdit = 0L;
 
-static KStaticDeleter<KCompletion> completionDeleter;
+static KStaticDeleter<KMailCompletion> completionDeleter;
 static KStaticDeleter<KPIM::CompletionItemsMap> completionItemsDeleter;
 static KStaticDeleter<QTimer> ldapTimerDeleter;
 static KStaticDeleter<KPIM::LdapSearch> ldapSearchDeleter;
@@ -110,7 +110,7 @@
 void AddresseeLineEdit::init()
 {
   if ( !s_completion ) {
-    completionDeleter.setObject( s_completion, new KCompletion() );
+    completionDeleter.setObject( s_completion, new KMailCompletion() );
     s_completion->setOrder( completionOrder() );
     s_completion->setIgnoreCase( true );
 
@@ -177,12 +177,15 @@
   bool accept = false;
 
   if ( KStdAccel::shortcut( KStdAccel::SubstringCompletion ).contains( KKey( e ) ) ) \
{ +    //TODO: add LDAP substring lookup, when it becomes available in \
KPIM::LDAPSearch +    updateSearchString();
     doCompletion( true );
     accept = true;
   } else if ( KStdAccel::shortcut( KStdAccel::TextCompletion ).contains( KKey( e ) ) \
) {  int len = text().length();
 
     if ( len == cursorPosition() ) { // at End?
+      updateSearchString();
       doCompletion( true );
       accept = true;
     }
@@ -350,7 +353,11 @@
 
 void AddresseeLineEdit::doCompletion( bool ctrlT )
 {
-  if ( !m_useCompletion )
+  m_lastSearchMode = ctrlT;
+
+  KGlobalSettings::Completion  mode = completionMode();
+
+  if ( mode == KGlobalSettings::CompletionNone  )
     return;
 
   if ( s_addressesDirty ) {
@@ -358,6 +365,7 @@
     s_completion->setOrder( completionOrder() );
   }
 
+
   // cursor at end of string - or Ctrl+T pressed for substring completion?
   if ( ctrlT ) {
     const QStringList completions = getAdjustedCompletionItems( false );
@@ -370,10 +378,10 @@
     setCompletedItems( completions, true ); // this makes sure the completion popup \
is closed if no matching items were found  
     cursorAtEnd();
+    setCompletionMode( mode ); //set back to previous mode
     return;
   }
 
-  KGlobalSettings::Completion  mode = completionMode();
 
   switch ( mode ) {
     case KGlobalSettings::CompletionPopupAuto:
@@ -385,15 +393,7 @@
     case KGlobalSettings::CompletionPopup:
     {
       const QStringList items = getAdjustedCompletionItems( true );
-      bool autoSuggest = !items.isEmpty() && (mode != \
                KGlobalSettings::CompletionPopupAuto);
-      setCompletedItems( items, autoSuggest );
-
-      if ( !autoSuggest ) {
-        int index = items.first().find( m_searchString );
-        QString newText = m_previousAddresses + items.first().mid( index \
                ).stripWhiteSpace();
-        setUserSelection( false );
-        setCompletedText( newText, true );
-      }
+      setCompletedItems( items, false );
       break;
     }
 
@@ -413,12 +413,12 @@
     {
       if ( !m_searchString.isEmpty() ) {
         QString match = s_completion->makeCompletion( m_searchString );
-        if ( !match.isNull() && match != m_searchString ) {
+        if ( !match.isEmpty() && match != m_searchString ) {
           QString adds = m_previousAddresses + match;
           setCompletedText( adds );
         }
-        break;
       }
+      break;
     }
 
     case KGlobalSettings::CompletionNone:
@@ -486,7 +486,14 @@
   QStringList::const_iterator listIt;
   int idx = addCompletionSource( i18n( "Distribution Lists" ) );
   for ( listIt = distLists.begin(); listIt != distLists.end(); ++listIt ) {
+
+    //for KGlobalSettings::CompletionAuto
     addCompletionItem( (*listIt).simplifyWhiteSpace(), weight, idx );
+
+    //for CompletionShell, CompletionPopup
+    QStringList sl( (*listIt).simplifyWhiteSpace() );
+    addCompletionItem( (*listIt).simplifyWhiteSpace(), weight, idx, &sl );
+
   }
 #endif
 
@@ -503,7 +510,14 @@
 #ifdef KDEPIM_NEW_DISTRLISTS
   if ( KPIM::DistributionList::isDistributionList( addr ) ) {
     //kdDebug(5300) << "AddresseeLineEdit::addContact() distribution list \"" << \
addr.formattedName() << "\" weight=" << weight << endl; + 
+    //for CompletionAuto
     addCompletionItem( addr.formattedName(), weight, source );
+
+    //for CompletionShell, CompletionPopup
+    QStringList sl( addr.formattedName() );
+    addCompletionItem( addr.formattedName(), weight, idx, &sl );
+
     return;
   }
 #endif
@@ -511,17 +525,42 @@
   const QStringList emails = addr.emails();
   QStringList::ConstIterator it;
   for ( it = emails.begin(); it != emails.end(); ++it ) {
+    //TODO: when Bug 131796 is solved, use default address if show-only-prefered is \
set +    //TODO: let user decide what fields to use in lookup, e.g. company, city, \
...  
+    //for CompletionAuto
     if ( addr.givenName().isEmpty() && addr.familyName().isEmpty() ) {
       addCompletionItem( addr.fullEmail( (*it) ), weight, source ); // use whatever \
is there  } else {
       const QString byFirstName= KPIM::quoteNameIfNecessary( addr.givenName() + " " \
                + addr.familyName() ) + " <" + (*it) + ">";
-      const QString byLastName= "\"" + addr.familyName() + ", " + addr.givenName() + \
                "\" "  + "<" + (*it) + ">";
-      const QString byEmail= (*it) + " (" + KPIM::quoteNameIfNecessary( \
addr.realName() ) + ")"; +      const QString byLastName = \
KPIM::quoteNameIfNecessary( addr.familyName() + " " + addr.givenName() ) + " <" + \
(*it) + ">"; +      const QString byEmail    = (*it) ;
+      const QString byNick     = KPIM::quoteNameIfNecessary( addr.nickName() ) + " \
<" + (*it) + ">";  addCompletionItem( byFirstName, weight, source );
       addCompletionItem( byLastName, weight, source );
       addCompletionItem( byEmail, weight, source );
+      addCompletionItem( byNick, weight, source );
     }
+    
+    //for CompletionShell, CompletionPopup
+    QStringList keyWords;
+    QString givenName = addr.givenName();
+    QString familyName= addr.familyName();
+    QString nickName  = addr.nickName();
+    QString realName  = addr.realName();
+    QString target    = addr.fullEmail( (*it) );
+    if( !givenName.isEmpty() && !familyName.isEmpty() ) {
+      keyWords.append(givenName);
+      keyWords.append(familyName);
+      keyWords.append(givenName+" "+familyName);
+      keyWords.append(familyName+" "+givenName);
+    }
+    if( !nickName.isEmpty() )
+      keyWords.append(nickName);
+    if( !realName.isEmpty() )
+      keyWords.append(realName);
+    keyWords.append( (*it) );
+    addCompletionItem( target, weight, source, &keyWords );
 
 #if 0
     int len = (*it).length();
@@ -574,7 +613,7 @@
   }
 }
 
-void AddresseeLineEdit::addCompletionItem( const QString& string, int weight, int \
completionItemSource ) +void AddresseeLineEdit::addCompletionItem( const QString& \
string, int weight, int completionItemSource, const QStringList * keyWords )  {
   // Check if there is an exact match for item already, and use the max weight if \
so.  // Since there's no way to get the information from KCompletion, we have to keep \
our own QMap @@ -585,7 +624,10 @@
   } else {
     s_completionItemMap->insert( string, qMakePair( weight, completionItemSource ) \
);  }
-  s_completion->addItem( string, weight );
+  if( keyWords == 0 )
+    s_completion->addItem( string, weight );
+  else
+    s_completion->addItemWithKeys( string, weight, keyWords );
 }
 
 void AddresseeLineEdit::slotStartLDAPLookup()
@@ -636,9 +678,10 @@
     addContact( addr, (*it).completionWeight, (*it ).clientNumber  );
   }
 
-  if ( hasFocus() || completionBox()->hasFocus() )
-    if ( completionMode() != KGlobalSettings::CompletionNone )
-      doCompletion( false );
+  if ( (hasFocus() || completionBox()->hasFocus() )
+    && completionMode() != KGlobalSettings::CompletionNone 
+    && completionMode() != KGlobalSettings::CompletionShell)
+      doCompletion( m_lastSearchMode );
 }
 
 void AddresseeLineEdit::setCompletedItems( const QStringList& items, bool \
autoSuggest ) @@ -697,9 +740,13 @@
   if ( !menu )
     return 0;
 
-  if ( m_useCompletion )
+  if ( m_useCompletion ){
+    QPopupMenu *subMenu = menu->findItem( menu->idAt(12) )->popup();
+    subMenu->setItemVisible( subMenu->idAt(4), false ); // \
KGlobalSettings::CompletionMan +    subMenu->setItemVisible( subMenu->idAt(5), false \
); // KGlobalSettings::CompletionPopupAuto   menu->insertItem( i18n( "Configure \
Completion Order..." ),  this, SLOT( slotEditCompletionOrder() ) );
+  }
   return menu;
 }
 
@@ -720,12 +767,11 @@
 {
   if ( s_LDAPSearch && s_LDAPLineEdit == this )
     stopLDAPLookup();
-  userCancelled( cancelText ); // in KLineEdit
+  userCancelled( m_previousAddresses + cancelText ); // in KLineEdit
 }
 
-void KPIM::AddresseeLineEdit::slotCompletion()
+void KPIM::AddresseeLineEdit::updateSearchString()
 {
-  // Called by KLineEdit's keyPressEvent -> new text, update search string
   m_searchString = text();
   int n = m_searchString.findRev(',');
   if ( n >= 0 ) {
@@ -744,6 +790,13 @@
   {
     m_previousAddresses = QString::null;
   }
+}
+
+void KPIM::AddresseeLineEdit::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 ( completionBox() )
     completionBox()->setCancelledText( m_searchString );
   doCompletion( false );
@@ -865,15 +918,7 @@
   QStringList items = fullSearch ?
     s_completion->allMatches( m_searchString )
     : s_completion->substringCompletion( m_searchString );
-  if ( fullSearch )
-    items += s_completion->allMatches( "\"" + m_searchString );
-  unsigned int beforeDollarCompletionCount = items.count();
-
-  if ( fullSearch && m_searchString.find( ' ' ) == -1 ) // one word, possibly given \
                name
-    items += s_completion->allMatches( "$$" + m_searchString );
-
-  // kdDebug(5300) << "     AddresseeLineEdit::doCompletion() found: " << \
                items.join(" AND ") << endl;
-
+ 
   int lastSourceIndex = -1;
   unsigned int i = 0;
   QMap<int, QStringList> sections;
@@ -894,13 +939,6 @@
     }
     sections[idx].append( *it );
 
-      if ( i > beforeDollarCompletionCount ) { 
-      // remove the '$$whatever$' part
-      int pos = (*it).find( '$', 2 );
-      if ( pos < 0 ) // ???
-        continue;
-      (*it) = (*it).mid( pos + 1 );
-    }
     if ( s_completion->order() == KCompletion::Sorted ) {
       sortedItems.append( *it );
     }
@@ -917,4 +955,75 @@
   }
   return sortedItems;
 }
+
+//-------------------- KMailCompletion -------------------
+KMailCompletion::KMailCompletion(){
+	setIgnoreCase( true );
+}
+
+void KMailCompletion::clear(){
+  m_keyMap.clear();
+  KCompletion::clear();
+}
+
+QStringList KMailCompletion::substringCompletion( const QString & string ) const{
+	QStringList list = KCompletion::substringCompletion( string );
+	//work around possible bug in KCompletion
+	//KCompletion::substringCompletion calls postProcessMatches only if \
string.isEmpty() ?!? +	postProcessMatches( &list );
+	return list;
+}
+
+QString KMailCompletion::makeCompletion( const QString &string ){
+  QString match = KCompletion::makeCompletion( string );
+
+  if ( match.isEmpty() ){
+    //KCompletion.ignoreCase does not work, bug or feature?
+    match = KCompletion::makeCompletion( string.left(1).upper() + string.mid(1) );
+  }
+
+  if ( !match.isEmpty() ){
+    //KCompletion::substring calls postProcessMatch, if this code is in \
postProcessMatch +    //(were it belongs), calling nextMatch is undefined, as list is \
not finished jet. +    while( match.find( QRegExp( "(@)|(<.*>)" ) ) == -1 ){
+      const QStringList &mailAddr = m_keyMap[ match ]; //get all mailAddr for this \
keyword +      bool isEmail = false;
+      for( QStringList::ConstIterator sit (mailAddr.begin()), sEnd(mailAddr.end()); \
sit != sEnd; ++sit ) +        if( (*sit).find( "<"+match+">" ) != -1 ){
+	  isEmail = true;
+          break;
+	}
+      if( !isEmail )
+        match = nextMatch();
+      else
+        break;
+    }
+  }
+
+  return match;
+}
+
+void KMailCompletion::addItemWithKeys( const QString& item, int weight, const \
QStringList*  keyWords){ +  for( QStringList::ConstIterator it( keyWords->begin() ); \
it != keyWords->end(); ++it){ +    QStringList &emailList = m_keyMap[(*it)];     \
//lookup email-list for given keyword +    if( emailList.find(item) == \
emailList.end() ) //add email if not there +      emailList.append(item);
+    addItem((*it),weight);                        //inform KCompletion about keyword
+    }
+}
+
+void KMailCompletion::postProcessMatches( QStringList * pMatches )const{
+  if( pMatches->isEmpty() )
+    return;
+  //KCompletion has found the keywords for us, we can now map them to mail-addr
+  QMap<QString,bool> mailAddrDistinct; //TODO replace with QSet in KDE4
+  for( QStringList::ConstIterator sit (pMatches->begin()), sEnd(pMatches->end()); \
sit != sEnd; ++sit){ +    const QStringList &mailAddr = m_keyMap[(*sit)]; //get all \
mailAddr for this keyword +    for( QStringList::ConstIterator sit \
(mailAddr.begin()), sEnd(mailAddr.end()); sit != sEnd; ++sit){ +      \
mailAddrDistinct[(*sit)] = true;  //store mailAddr, QMap will make them unique +    }
+  }
+  pMatches->clear();                      //delete keywords
+  (*pMatches) += mailAddrDistinct.keys(); //add emailAddr
+}
 #include "addresseelineedit.moc"



_______________________________________________
KMail developers mailing list
KMail-devel@kde.org
https://mail.kde.org/mailman/listinfo/kmail-devel


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

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