24#include "addresslineedit.h"
26#include <QApplication>
29#include <QtCore/QObject>
30#include <QtCore/QRegExp>
32#include <kcompletionbox.h>
36#include <kstandarddirs.h>
37#include <kstandardshortcut.h>
39#include "stdaddressbook.h"
49class AddressLineEdit::Private
54 mCompletionInitialized( false ),
61 QStringList addresses();
62 QStringList removeMailDupes(
const QStringList &adrs );
64 void slotCompletion() { mParent->doCompletion(
false ); }
65 void slotPopupCompletion(
const QString &completion );
68 QString mPreviousAddresses;
70 bool mCompletionInitialized;
73 static bool sAddressesDirty;
74 static bool initialized;
76bool AddressLineEdit::Private::initialized =
false;
77K_GLOBAL_STATIC( KCompletion, sCompletion )
79void AddressLineEdit::Private::init()
81 if ( !Private::initialized ) {
82 Private::initialized =
true;
83 sCompletion->setOrder( KCompletion::Sorted );
84 sCompletion->setIgnoreCase(
true );
87 if ( mUseCompletion && !mCompletionInitialized ) {
88 mParent->setCompletionObject( sCompletion,
false );
89 mParent->connect( mParent, SIGNAL(completion(QString)),
90 mParent, SLOT(slotCompletion()) );
92 KCompletionBox *box = mParent->completionBox();
93 mParent->connect( box, SIGNAL(currentTextChanged(QString)),
94 mParent, SLOT(slotPopupCompletion(QString)) );
95 mParent->connect( box, SIGNAL(userCancelled(QString)),
96 SLOT(userCancelled(QString)) );
98 mCompletionInitialized =
true;
106QStringList AddressLineEdit::Private::addresses()
108 QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
111 QLatin1String space(
" " );
112 QRegExp needQuotes( QLatin1String(
"[^ 0-9A-Za-z\\x0080-\\xFFFF]" ) );
113 QLatin1String endQuote(
"\" " );
118 for ( it = addressBook->
begin(); it != addressBook->
end(); ++it ) {
119 QStringList emails = ( *it ).emails();
121 QString n = ( *it ).prefix() + space +
122 ( *it ).givenName() + space +
123 ( *it ).additionalName() + space +
124 ( *it ).familyName() + space +
129 QStringList::ConstIterator mit;
130 QStringList::ConstIterator end( emails.constEnd() );
132 for ( mit = emails.constBegin(); mit != end; ++mit ) {
134 if ( !email.isEmpty() ) {
135 if ( n.isEmpty() || ( email.indexOf( QLatin1Char(
'<' ) ) != -1 ) ) {
138 if ( n.indexOf( needQuotes ) != -1 ) {
139 addr = QLatin1Char(
'"' ) + n + endQuote;
145 if ( !addr.isEmpty() &&
146 ( email.indexOf( QLatin1Char(
'<' ) ) == -1 ) &&
147 ( email.indexOf( QLatin1Char(
'>' ) ) == -1 ) &&
148 ( email.indexOf( QLatin1Char(
',' ) ) == -1 ) ) {
149 addr += QLatin1Char(
'<' ) + email + QLatin1Char(
'>' );
153 addr = addr.trimmed();
154 result.append( addr );
161 QApplication::restoreOverrideCursor();
166QStringList AddressLineEdit::Private::removeMailDupes(
const QStringList &addrs )
168 QStringList src( addrs );
172 for ( QStringList::Iterator it = src.begin(); it != src.end(); ) {
174 it = src.erase( it );
185void AddressLineEdit::Private::slotPopupCompletion(
const QString &completion )
187 mParent->setText( mPreviousAddresses + completion );
188 mParent->cursorAtEnd();
191bool AddressLineEdit::Private::sAddressesDirty =
false;
194 : KLineEdit( parent ), d( new Private( this ) )
196 d->mUseCompletion = useCompletion;
202 if ( d->mUseCompletion ) {
203 d->sAddressesDirty =
true;
217 KLineEdit::setFont( font );
218 if ( d->mUseCompletion ) {
219 completionBox()->setFont( font );
228 if ( KStandardShortcut::shortcut( KStandardShortcut::SubstringCompletion ).
229 contains( event->key() | event->modifiers() ) ) {
232 }
else if ( KStandardShortcut::shortcut( KStandardShortcut::TextCompletion ).
233 contains( event->key() | event->modifiers() ) ) {
234 int len = text().length();
236 if ( len == cursorPosition() ) {
243 KLineEdit::keyPressEvent( event );
249 if ( d->mUseCompletion && ( event->button() == Qt::MidButton ) ) {
250 d->mSmartPaste =
true;
251 KLineEdit::mouseReleaseEvent( event );
252 d->mSmartPaste =
false;
256 KLineEdit::mouseReleaseEvent( event );
261 if ( !d->mSmartPaste ) {
262 KLineEdit::insert( oldText );
266 QString newText = oldText.trimmed();
267 if ( newText.isEmpty() ) {
273 newText.replace( QRegExp( QLatin1String(
"\r?\n" ) ), QLatin1String(
", " ) );
274 if ( newText.startsWith( QLatin1String(
"mailto:" ) ) ) {
277 }
else if ( newText.indexOf( QLatin1String(
" at " ) ) != -1 ) {
279 newText.replace( QLatin1String(
" at " ), QLatin1String(
"@" ) );
280 newText.replace( QLatin1String(
" dot " ), QLatin1String(
"." ) );
281 }
else if ( newText.indexOf( QLatin1String(
"(at)" ) ) != -1 ) {
282 newText.replace( QRegExp( QLatin1String(
"\\s*\\(at\\)\\s*" ) ), QLatin1String(
"@" ) );
285 QString contents = text();
288 int pos = cursorPosition();
289 if ( !selectedText().isEmpty() ) {
291 if ( pos > end_sel ) {
292 pos -= ( end_sel - start_sel );
293 }
else if ( pos > start_sel ) {
296 contents = contents.left( start_sel ) + contents.right( end_sel + 1 );
299 int eot = contents.length();
300 while ( ( eot > 0 ) && contents[ eot - 1 ].isSpace() ) {
306 }
else if ( pos >= eot ) {
307 if ( contents[ eot - 1 ] == QLatin1Char(
',' ) ) {
310 contents.truncate( eot );
311 contents += QLatin1String(
", " );
315 contents = contents.left( pos ) + newText + contents.mid( pos );
317 setCursorPosition( pos + newText.length() );
322 if ( d->mUseCompletion ) {
323 d->mSmartPaste =
true;
327 d->mSmartPaste =
false;
333 setCursorPosition( text().length() );
339 d->mUseCompletion = enable;
345 if ( !d->mUseCompletion ) {
352 int n = s.lastIndexOf( QLatin1Char(
',' ) );
357 int len = s.length();
360 while ( n < len && s[ n ].isSpace() ) {
364 prevAddr = s.left( n );
365 s = s.mid( n, 255 ).trimmed();
368 if ( d->sAddressesDirty ) {
373 QStringList completions = sCompletion->substringCompletion( s );
374 if ( completions.count() > 1 ) {
375 d->mPreviousAddresses = prevAddr;
376 setCompletedItems( completions );
377 }
else if ( completions.count() == 1 ) {
378 setText( prevAddr + completions.first() );
385 KGlobalSettings::Completion mode = completionMode();
388 case KGlobalSettings::CompletionPopupAuto:
394 case KGlobalSettings::CompletionPopup:
396 d->mPreviousAddresses = prevAddr;
397 QStringList items = sCompletion->allMatches( s );
398 items += sCompletion->allMatches( QLatin1String(
"\"" ) + s );
399 items += sCompletion->substringCompletion( QLatin1Char(
'<' ) + s );
400 int beforeDollarCompletionCount = items.count();
402 if ( s.indexOf( QLatin1Char(
' ' ) ) == -1 ) {
403 items += sCompletion->allMatches( QLatin1String(
"$$" ) + s );
406 if ( !items.isEmpty() ) {
407 if ( items.count() > beforeDollarCompletionCount ) {
409 for ( QStringList::Iterator it = items.begin();
410 it != items.end(); ++it ) {
411 int pos = ( *it ).indexOf( QLatin1Char(
'$' ), 2 );
415 ( *it ) = ( *it ).mid( pos + 1 );
419 items = d->removeMailDupes( items );
425 bool autoSuggest = ( mode != KGlobalSettings::CompletionPopupAuto );
426 setCompletedItems( items, autoSuggest );
428 if ( !autoSuggest ) {
429 int index = items.first().indexOf( s );
430 QString newText = prevAddr + items.first().mid( index );
433 setUserSelection(
false );
434 setCompletedText( newText,
true );
441 case KGlobalSettings::CompletionShell:
443 QString match = sCompletion->makeCompletion( s );
444 if ( !match.isNull() && match != s ) {
445 setText( prevAddr + match );
451 case KGlobalSettings::CompletionMan:
452 case KGlobalSettings::CompletionAuto:
454 if ( !s.isEmpty() ) {
455 QString match = sCompletion->makeCompletion( s );
456 if ( !match.isNull() && match != s ) {
457 setCompletedText( prevAddr + match );
463 case KGlobalSettings::CompletionNone:
472 sCompletion->clear();
473 d->sAddressesDirty =
false;
475 const QStringList addrs = d->addresses();
476 QStringList::ConstIterator end( addrs.end() );
477 for ( QStringList::ConstIterator it = addrs.begin(); it != end; ++it ) {
484 sCompletion->addItem( addr );
486 int pos = addr.indexOf( QLatin1Char(
'<' ) );
489 int pos2 = addr.indexOf( QLatin1Char(
'>' ), pos );
491 sCompletion->addItem( addr.mid( pos, pos2 - pos ) );
499 const KUrl::List uriList = KUrl::List::fromMimeData( event->mimeData() );
500 if ( !uriList.isEmpty() ) {
502 KUrl::List::ConstIterator it = uriList.begin();
503 for ( ; it != uriList.end(); ++it ) {
504 if ( !ct.isEmpty() ) {
505 ct.append( QLatin1String(
", " ) );
509 if ( ( *it ).protocol() == QLatin1String(
"mailto" ) ) {
510 ct.append( ( *it ).path() );
512 ct.append( ( *it ).url() );
518 if ( d->mUseCompletion ) {
519 d->mSmartPaste =
true;
522 KLineEdit::dropEvent( event );
523 d->mSmartPaste =
false;
527#include "moc_addresslineedit.cpp"
QStringList allDistributionListNames() const
Returns a list of names of all distribution lists of all resources of this address book.
ConstIterator begin() const
Returns an iterator pointing to the first addressee of address book.
ConstIterator end() const
Returns an iterator pointing to the last addressee of address book.
A lineedit with kabc completion.
virtual void insert(const QString &addr)
Inserts the given string.
void doCompletion(bool)
Triggers looking for a completion of the address or the last address if there are already more than o...
virtual void mouseReleaseEvent(QMouseEvent *e)
Enables smart paste for X11 middle mouse text paste if completion is enabled.
virtual void paste()
Pastes the clipboard content.
void addAddress(const QString &addr)
Adds a new address to the line edit.
void cursorAtEnd()
Set cursor to end of line.
virtual void loadAddresses()
Always call AddressLineEdit::loadAddresses() as the first thing.
void enableCompletion(bool enable)
Toggle completion.
virtual void dropEvent(QDropEvent *e)
Handles drop events.
AddressLineEdit(QWidget *parent, bool useCompletion=true)
Creates the line edit instance.
virtual void setFont(const QFont &font)
Reimplemented for internal reasons.
virtual void keyPressEvent(QKeyEvent *e)
Handles KDE completion short cuts.
virtual ~AddressLineEdit()
Destroys the instance.
static StdAddressBook * self()
Returns the standard addressbook object.
Class that holds a Calendar Url (FBURL/CALADRURI/CALURI)