kmail

kmlineeditspell.cpp
00001 // -*- mode: C++; c-file-style: "gnu" -*-
00002 // kmcomposewin.cpp
00003 // Author: Markus Wuebben <markus.wuebben@kde.org>
00004 // This code is published under the GPL.
00005 
00006 #include "kmlineeditspell.h"
00007 
00008 #include "recentaddresses.h"
00009 #include "kmkernel.h"
00010 #include "globalsettings.h"
00011 #include "stringutil.h"
00012 
00013 #include <libtdepim/kvcarddrag.h>
00014 #include <libemailfunctions/email.h>
00015 
00016 #include <tdeabc/vcardconverter.h>
00017 #include <tdeio/netaccess.h>
00018 
00019 #include <tdepopupmenu.h>
00020 #include <kurl.h>
00021 #include <kurldrag.h>
00022 #include <tdemessagebox.h>
00023 #include <tdecompletionbox.h>
00024 #include <tdelocale.h>
00025 
00026 #include <tqevent.h>
00027 #include <tqfile.h>
00028 #include <tqcstring.h>
00029 #include <tqcursor.h>
00030 
00031 
00032 KMLineEdit::KMLineEdit(bool useCompletion,
00033                        TQWidget *parent, const char *name)
00034     : KPIM::AddresseeLineEdit(parent,useCompletion,name)
00035 {
00036    allowSemiColonAsSeparator( GlobalSettings::allowSemicolonAsAddressSeparator() );
00037 }
00038 
00039 
00040 //-----------------------------------------------------------------------------
00041 void KMLineEdit::keyPressEvent(TQKeyEvent *e)
00042 {
00043   if ((e->key() == Key_Enter || e->key() == Key_Return) &&
00044       !completionBox()->isVisible())
00045   {
00046     emit focusDown();
00047     AddresseeLineEdit::keyPressEvent(e);
00048     return;
00049   }
00050   if (e->key() == Key_Up)
00051   {
00052     emit focusUp();
00053     return;
00054   }
00055   if (e->key() == Key_Down)
00056   {
00057     emit focusDown();
00058     return;
00059   }
00060   AddresseeLineEdit::keyPressEvent(e);
00061 }
00062 
00063 
00064 void KMLineEdit::insertEmails( const TQStringList & emails )
00065 {
00066   if ( emails.empty() )
00067     return;
00068 
00069   TQString contents = text();
00070   if ( !contents.isEmpty() )
00071     contents += ',';
00072   // only one address, don't need tdepopup to choose
00073   if ( emails.size() == 1 ) {
00074     setText( contents + emails.front() );
00075     return;
00076   }
00077   //multiple emails, let the user choose one
00078   TDEPopupMenu menu( this, "Addresschooser" );
00079   for ( TQStringList::const_iterator it = emails.begin(), end = emails.end() ; it != end; ++it )
00080     menu.insertItem( *it );
00081   const int result = menu.exec( TQCursor::pos() );
00082   if ( result == -1 )
00083     return;
00084   setText( contents + menu.text( result ) );
00085 }
00086 
00087 void KMLineEdit::dropEvent( TQDropEvent *event )
00088 {
00089   KURL::List urls;
00090 
00091   // Case one: The user dropped a text/directory (i.e. vcard), so decode its
00092   //           contents
00093   if ( KVCardDrag::canDecode( event ) ) {
00094    TDEABC::Addressee::List list;
00095     KVCardDrag::decode( event, list );
00096 
00097     TDEABC::Addressee::List::Iterator ait;
00098     for ( ait = list.begin(); ait != list.end(); ++ait ){
00099       insertEmails( (*ait).emails() );
00100     }
00101   }
00102 
00103   // Case two: The user dropped a list or Urls.
00104   // Iterate over that list. For mailto: Urls, just add the addressee to the list,
00105   // and for other Urls, download the Url and assume it points to a vCard
00106   else if ( KURLDrag::decode( event, urls ) ) {
00107     KURL::List::Iterator it = urls.begin();
00108     TDEABC::Addressee::List list;
00109     for ( it = urls.begin(); it != urls.end(); ++it ) {
00110 
00111       // First, let's deal with mailto Urls. The path() part contains the
00112       // email-address.
00113       if ( (*it).protocol() == "mailto" ) {
00114         TDEABC::Addressee addressee;
00115         addressee.insertEmail( KMail::StringUtil::decodeMailtoUrl( (*it).path() ), true /* preferred */ );
00116         list += addressee;
00117       }
00118       // Otherwise, download the vCard to which the Url points
00119       else {
00120         TDEABC::VCardConverter converter;
00121         TQString fileName;
00122         if ( TDEIO::NetAccess::download( (*it), fileName, parentWidget() ) ) {
00123           TQFile file( fileName );
00124           file.open( IO_ReadOnly );
00125           const TQByteArray data = file.readAll();
00126           file.close();
00127 #if defined(KABC_VCARD_ENCODING_FIX)
00128           list += converter.parseVCardsRaw( data.data() );
00129 #else
00130           list += converter.parseVCards( data );
00131 #endif
00132           TDEIO::NetAccess::removeTempFile( fileName );
00133         } else {
00134           TQString caption( i18n( "vCard Import Failed" ) );
00135           TQString text = i18n( "<qt>Unable to access <b>%1</b>.</qt>" ).arg( (*it).url() );
00136           KMessageBox::error( parentWidget(), text, caption );
00137         }
00138       }
00139       // Now, let the user choose which addressee to add.
00140       TDEABC::Addressee::List::Iterator ait;
00141       for ( ait = list.begin(); ait != list.end(); ++ait )
00142         insertEmails( (*ait).emails() );
00143     }
00144   }
00145 
00146   // Case three: Let AddresseeLineEdit deal with the rest
00147   else {
00148     KPIM::AddresseeLineEdit::dropEvent( event );
00149   }
00150 }
00151 
00152 TQPopupMenu *KMLineEdit::createPopupMenu()
00153 {
00154     TQPopupMenu *menu = KPIM::AddresseeLineEdit::createPopupMenu();
00155     if ( !menu )
00156         return 0;
00157 
00158     menu->insertSeparator();
00159     menu->insertItem( i18n( "Edit Recent Addresses..." ),
00160                       this, TQT_SLOT( editRecentAddresses() ) );
00161 
00162     return menu;
00163 }
00164 
00165 void KMLineEdit::editRecentAddresses()
00166 {
00167   TDERecentAddress::RecentAddressDialog dlg( this );
00168   dlg.setAddresses( TDERecentAddress::RecentAddresses::self( KMKernel::config() )->addresses() );
00169   if ( !dlg.exec() )
00170     return;
00171   TDERecentAddress::RecentAddresses::self( KMKernel::config() )->clear();
00172   const TQStringList addrList = dlg.addresses();
00173   for ( TQStringList::const_iterator it = addrList.begin(), end = addrList.end() ; it != end ; ++it )
00174     TDERecentAddress::RecentAddresses::self( KMKernel::config() )->add( *it );
00175   loadContacts();
00176 }
00177 
00178 
00179 //-----------------------------------------------------------------------------
00180 void KMLineEdit::loadContacts()
00181 {
00182   AddresseeLineEdit::loadContacts();
00183 
00184   if ( GlobalSettings::self()->showRecentAddressesInComposer() ){
00185     if ( KMKernel::self() ) {
00186       TQStringList recent =
00187         TDERecentAddress::RecentAddresses::self( KMKernel::config() )->addresses();
00188       TQStringList::Iterator it = recent.begin();
00189       TQString name, email;
00190 
00191       TDEConfig config( "kpimcompletionorder" );
00192       config.setGroup( "CompletionWeights" );
00193       int weight = config.readEntry( "Recent Addresses", "10" ).toInt();
00194       int idx = addCompletionSource( i18n( "Recent Addresses" ), weight );
00195       for ( ; it != recent.end(); ++it ) {
00196         TDEABC::Addressee addr;
00197         KPIM::getNameAndMail(*it, name, email);
00198         name = KPIM::quoteNameIfNecessary( name );
00199         if ( ( name[0] == '"' ) && ( name[name.length() - 1] == '"' ) ) {
00200           name.remove( 0, 1 );
00201           name.truncate( name.length() - 1 );
00202         }
00203         addr.setNameFromString( name );
00204         addr.insertEmail( email, true );
00205         addContact( addr, weight, idx );
00206       }
00207     }
00208   }
00209 }
00210 
00211 
00212 KMLineEditSpell::KMLineEditSpell(bool useCompletion,
00213                        TQWidget *parent, const char *name)
00214     : KMLineEdit(useCompletion,parent,name)
00215 {
00216 }
00217 
00218 
00219 void KMLineEditSpell::highLightWord( unsigned int length, unsigned int pos )
00220 {
00221     setSelection ( pos, length );
00222 }
00223 
00224 void KMLineEditSpell::spellCheckDone( const TQString &s )
00225 {
00226     if( s != text() )
00227         setText( s );
00228 }
00229 
00230 void KMLineEditSpell::spellCheckerMisspelling( const TQString &_text, const TQStringList&, unsigned int pos)
00231 {
00232      highLightWord( _text.length(),pos );
00233 }
00234 
00235 void KMLineEditSpell::spellCheckerCorrected( const TQString &old, const TQString &corr, unsigned int pos)
00236 {
00237     if( old!= corr )
00238     {
00239         setSelection ( pos, old.length() );
00240         insert( corr );
00241         setSelection ( pos, corr.length() );
00242         emit subjectTextSpellChecked();
00243     }
00244 }
00245 
00246 
00247 #include "kmlineeditspell.moc"