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

List:       kde-usability
Subject:    KMail Intelligently reading emails...
From:       John Tapsell <john () geola ! co ! uk>
Date:       2005-03-19 6:14:05
Message-ID: 200503190614.05486.john () geola ! co ! uk
[Download RAW message or body]

Hi all,
  I was bored and decided to get kmail to read emails for you, try to 
recognise when someone is saying "my phone number is xxxx xxxx" and then 
insert a pretty icon for you to click to add that phone number to the contact 
in the addressbook that has the same email address as the person who sent the 
email.
  Follow?  Good. :)

  If you apply this patch to kmail/   then view, for example, this email where 
I say I wish I had the mobile number 01273 555 2234 or even tell everyone 
that my work fax number is 01273 555 3232 ext. 234

  I'm interested in what people think of it.  (I won't apply as-is , so no 
comments on the crappiness of the code.  Proof of concept only :) )

JohnFlux

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

? read_email_numbers.diff
Index: kmfolderimap.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/kmfolderimap.cpp,v
retrieving revision 1.255
diff -u -p -r1.255 kmfolderimap.cpp
--- kmfolderimap.cpp	22 Feb 2005 22:26:20 -0000	1.255
+++ kmfolderimap.cpp	19 Mar 2005 06:07:01 -0000
@@ -227,7 +227,7 @@ void KMFolderImap::slotRemoveFolderResul
 {
   ImapAccountBase::JobIterator it = mAccount->findJob(job);
   if ( it == mAccount->jobsEnd() ) return;
-  if (job->error())
+  if (job->error() /*&& job->error() != ERR_DOES_NOT_EXIST*/)
   {
     mAccount->handleJobError( job, i18n("Error while removing a folder.") );
     emit removed(folder(), false);
Index: kmfoldertree.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/kmfoldertree.cpp,v
retrieving revision 1.353
diff -u -p -r1.353 kmfoldertree.cpp
--- kmfoldertree.cpp	23 Feb 2005 21:55:55 -0000	1.353
+++ kmfoldertree.cpp	19 Mar 2005 06:07:02 -0000
@@ -978,9 +978,8 @@ void KMFolderTree::slotContextMenuReques
     if (!fti->folder()->noContent())
     {
       mMainWidget->action("search_messages")->plug(folderMenu);
-
-      mMainWidget->action("compact")->plug(folderMenu);
-
+      if ( fti->folder()->folderType() != KMFolderTypeSearch )
+        mMainWidget->action("compact")->plug(folderMenu);
       if ( !fti->folder()->isSystemFolder() )
         mMainWidget->action("delete_folder")->plug(folderMenu);
 
Index: kmmainwidget.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/kmmainwidget.cpp,v
retrieving revision 1.323
diff -u -p -r1.323 kmmainwidget.cpp
--- kmmainwidget.cpp	17 Mar 2005 19:07:12 -0000	1.323
+++ kmmainwidget.cpp	19 Mar 2005 06:07:04 -0000
@@ -3030,7 +3030,7 @@ void KMMainWidget::updateFolderMenu()
   bool folderWithContent = mFolder && !mFolder->noContent();
   mModifyFolderAction->setEnabled( folderWithContent );
   mFolderMailingListPropertiesAction->setEnabled( folderWithContent );
-  mCompactFolderAction->setEnabled( folderWithContent );
+  mCompactFolderAction->setEnabled( folderWithContent && mFolder->folderType() != \
KMFolderTypeSearch );  
   // This is the refresh-folder action in the menu. See kmfoldertree for the one in \
the RMB...  bool imap = mFolder && mFolder->folderType() == KMFolderTypeImap;
Index: objecttreeparser.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/objecttreeparser.cpp,v
retrieving revision 1.129
diff -u -p -r1.129 objecttreeparser.cpp
--- objecttreeparser.cpp	30 Jan 2005 23:58:15 -0000	1.129
+++ objecttreeparser.cpp	19 Mar 2005 06:07:05 -0000
@@ -75,6 +75,9 @@
 #include <ktempfile.h>
 #include <kstandarddirs.h>
 #include <kapplication.h>
+#include <kabc/stdaddressbook.h>
+#include <kabc/addresseelist.h>
+#include <kabc/addressee.h>
 #include <kmessagebox.h>
 
 // other Qt headers
@@ -2283,7 +2286,7 @@ void ObjectTreeParser::writeBodyStr( con
           // insert the next Non-OpenPGP block
           QCString str( *npbit );
           if( !str.isEmpty() ) {
-            htmlStr += quotedHTML( aCodec->toUnicode( str ), decorate );
+            htmlStr += quotedHTML( aCodec->toUnicode( str ), decorate, fromAddress \
                );
             kdDebug( 5006 ) << "Non-empty Non-OpenPGP block found: '" << str
                             << "'" << endl;
             // treat messages with empty lines before the first clearsigned
@@ -2373,18 +2376,18 @@ void ObjectTreeParser::writeBodyStr( con
 
               htmlStr += writeSigstatHeader( messagePart, 0, fromAddress );
 
-              htmlStr += quotedHTML( aCodec->toUnicode( block->text() ), decorate );
+              htmlStr += quotedHTML( aCodec->toUnicode( block->text() ), decorate, \
fromAddress );  htmlStr += writeSigstatFooter( messagePart );
           }
           else // block is neither message block nor clearsigned block
             htmlStr += quotedHTML( aCodec->toUnicode( block->text() ),
-                                   decorate );
+                                   decorate, fromAddress );
       }
 
       // add the last Non-OpenPGP block
       QCString str( nonPgpBlocks.last() );
       if( !str.isEmpty() ) {
-        htmlStr += quotedHTML( aCodec->toUnicode( str ), decorate );
+        htmlStr += quotedHTML( aCodec->toUnicode( str ), decorate, fromAddress );
         // Even if the trailing Non-OpenPGP block isn't empty we still
         // consider the message part fully signed/encrypted because else
         // all inline signed mailing list messages would only be partially
@@ -2400,10 +2403,10 @@ void ObjectTreeParser::writeBodyStr( con
       htmlWriter()->queue( htmlStr );
   }
   else
-    htmlWriter()->queue( quotedHTML( aCodec->toUnicode( aStr ), decorate ) );
+    htmlWriter()->queue( quotedHTML( aCodec->toUnicode( aStr ), decorate, \
fromAddress) );  }
 
-QString ObjectTreeParser::quotedHTML( const QString& s, bool decorate )
+QString ObjectTreeParser::quotedHTML( const QString& s, bool decorate, const \
QString& fromAddress)  {
   assert( mReader );
   assert( cssHelper() );
@@ -2440,6 +2443,7 @@ QString ObjectTreeParser::quotedHTML( co
         pos = length;
 
     line = s.mid(beg,pos-beg);
+    
     beg = pos+1;
 
     /* calculate line's current quoting depth */
@@ -2483,7 +2487,37 @@ QString ObjectTreeParser::quotedHTML( co
         htmlStr += QString( "<div dir=\"rtl\">" );
       else
         htmlStr += QString( "<div dir=\"ltr\">" );
-      htmlStr += LinkLocator::convertToHtml( line, convertFlags );
+      QString linehtml = LinkLocator::convertToHtml( line, convertFlags );
+
+      
+      QString phonenumber;
+      if( actQuoteLevel == -1 )
+        phonenumber = QString(linehtml).replace( QRegExp("^.*(([+][\\d][\\d] \
?(\\(0\\))?|1[-.])?([(][\\d]{3,7}[ ]?[)][ ]?)?([]?[\\d]{3,7}[.- ]){1,2}(\\d{3,7})( \
ex[t]?[.]? \\d{3,5})?).*$"), "\\1"); +      if( !phonenumber.isEmpty() ) {
+
+        KABC::AddressBook *addressBook = KABC::StdAddressBook::self();
+        KABC::Addressee addressee = addressBook->findByEmail( \
KPIM::getFirstEmailAddress( fromAddress ) ).first(); +	if( !addressee.isEmpty() ) {
+	  //loop through all phone numbers and check if we know about them already
+	  QString justNumber = phonenumber.replace( QRegExp( "[^\\d]" ), "");
+
+          KABC::PhoneNumber::List addresseeNumbers = addressee.phoneNumbers();
+	  KABC::PhoneNumber::List::iterator it;
+	  bool found = false;
+          for ( it = addresseeNumbers.begin(); it != addresseeNumbers.end(); ++it ) \
{ +	    if( (*it).number().replace( QRegExp( "[^\\d]" ), "") == justNumber ) {
+	  	  
+              linehtml.replace( QRegExp("((mobile |mob.? |home |house |work |home \
fax |house fax |fax |work fax )(no.? |number )?[^\\d]*|[: ])(([+][\\d][\\d] \
?(\\(0\\))?|1[-.])?([(][\\d]{3,7}[ ]?[)][ ]?)?([]?[\\d]{3,7}[.- ]){1,2}(\\d{3,7})( \
ex[t]?[.]? \\d{3,5})?)"), "\\1\\4 [Contact already has this number listed]"); +	      \
found = true; +	      break;
+	    }
+	  }
+          if(!found)
+            linehtml.replace( QRegExp("((mobile |mob.? |home |house |work |home fax \
|house fax |fax |work fax )(no.? |number )?[^\\d]*|[: ])(([+][\\d][\\d] \
?(\\(0\\))?|1[-.])?([(][\\d]{3,7}[ ]?[)][ ]?)?([]?[\\d]{3,7}[.- ]){1,2}(\\d{3,7})( \
ex[t]?[.]? \\d{3,5})?)"), "\\1\\4 [<a href=\"kmail:associate-\\2-\\4\">Associate this \
\\2 number to contact</a>]"); +	}
+      
+      }
+      htmlStr += linehtml;
       htmlStr += QString( "</div>" );
     }
     else
Index: objecttreeparser.h
===================================================================
RCS file: /home/kde/kdepim/kmail/objecttreeparser.h,v
retrieving revision 1.44
diff -u -p -r1.44 objecttreeparser.h
--- objecttreeparser.h	30 Jan 2005 23:58:15 -0000	1.44
+++ objecttreeparser.h	19 Mar 2005 06:07:06 -0000
@@ -256,7 +256,7 @@ namespace KMail {
   private:
     /** Change the string to `quoted' html (meaning, that the quoted
         part of the message get italized */
-    QString quotedHTML(const QString& pos, bool decorate);
+    QString quotedHTML( const QString& s, bool decorate, const QString& \
fromAddress);  
     const QTextCodec * codecFor( partNode * node ) const;
 
Index: searchjob.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/searchjob.cpp,v
retrieving revision 1.6
diff -u -p -r1.6 searchjob.cpp
--- searchjob.cpp	21 Feb 2005 19:54:53 -0000	1.6
+++ searchjob.cpp	19 Mar 2005 06:07:06 -0000
@@ -87,6 +87,8 @@ void SearchJob::searchCompleteFolder()
       SLOT(slotSearchData(KIO::Job*,const QString&)) );
   connect( job, SIGNAL(result(KIO::Job *)),
       SLOT(slotSearchResult(KIO::Job *)) );
+
+  kdDebug() << "Searching for: " << url.url() << endl;
 }
 
 //-----------------------------------------------------------------------------
Index: urlhandlermanager.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/urlhandlermanager.cpp,v
retrieving revision 1.19
diff -u -p -r1.19 urlhandlermanager.cpp
--- urlhandlermanager.cpp	3 Mar 2005 17:31:12 -0000	1.19
+++ urlhandlermanager.cpp	19 Mar 2005 06:07:06 -0000
@@ -47,6 +47,10 @@
 #include "stl_util.h"
 #include <kurl.h>
 
+#include <kabc/stdaddressbook.h>
+#include <kabc/addresseelist.h>
+#include <kabc/addressee.h>
+
 #include <algorithm>
 using std::for_each;
 using std::remove;
@@ -322,6 +326,8 @@ QString KMail::URLHandlerManager::status
 #include <khtml_part.h>
 
 #include <qstring.h>
+ 
+#include <kabc/phonenumber.h>
 
 namespace {
   bool ShowHtmlSwitchURLHandler::handleClick( const KURL & url, KMReaderWin * w ) \
const { @@ -340,6 +346,49 @@ namespace {
         w->update( true );
         return true;
       }
+      if ( url.path().section('-', 0,0) == "associate" ) {
+	      
+        KABC::AddressBook *addressBook = KABC::StdAddressBook::self();
+        KABC::Addressee addressee = addressBook->findByEmail( \
KPIM::getFirstEmailAddress( w->message()->from() ) ).first(); +
+	//loop through all phone numbers and check no dups
+	QString phoneNumber = url.path().section('-',2).simplifyWhiteSpace();
+	QString justNumber = QString(phoneNumber).replace( QRegExp( "[^\\d]" ), "");
+
+	KABC::PhoneNumber::List addresseeNumbers = addressee.phoneNumbers();
+	KABC::PhoneNumber::List::iterator it;
+        for ( it = addresseeNumbers.begin(); it != addresseeNumbers.end(); ++it ) {
+	  if( (*it).number().replace( QRegExp( "[^\\d]" ), "") == justNumber ) {
+	    KMessageBox::information(w, i18n("The contact %1 already has the number %2 \
listed.").arg(addressee.realName()).arg((*it).number())); +	    return false;
+	  }
+	}
+
+	QString strPhoneType = url.path().section('-', 1, 1).lower().simplifyWhiteSpace();
+	int phoneType = 0;
+	if( strPhoneType.contains("home") || strPhoneType.contains("house") ) phoneType = \
KABC::PhoneNumber::Home; +	else if( strPhoneType.contains("work") ) phoneType = \
KABC::PhoneNumber::Work; +	
+	if( strPhoneType.contains("mob")) phoneType += KABC::PhoneNumber::Cell;
+	else if( strPhoneType == "fax") phoneType += KABC::PhoneNumber::Fax;
+
+	
+	int result = KMessageBox::questionYesNo(w, i18n("Add the %1 number '%2' to the list \
of phone numbers for contact %3?").arg(KABC::PhoneNumber::typeLabel(phoneType)) +		   \
.arg(phoneNumber) +		                                       \
.arg(addressee.realName()) +		                               );
+	if( result == KMessageBox::Yes ) {
+	  addressee.insertPhoneNumber( KABC::PhoneNumber(phoneNumber, phoneType) );
+          KABC::Ticket* ticket = addressBook->requestSaveTicket();
+	  if(!ticket) {
+	    KMessageBox::sorry(w, i18n("The addressbook is locked by another application.  \
Try again later.")); +	    return false;
+	  }
+	  addressBook->insertAddressee(addressee);
+	  return addressBook->save(ticket); 
+	}
+        return false;
+      }
 //       if ( url.path() == "startIMApp" )
 //       {
 //         kmkernel->imProxy()->startPreferredApp();



_______________________________________________
kde-usability mailing list
kde-usability@kde.org
https://mail.kde.org/mailman/listinfo/kde-usability


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

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