24 #include "addresslineedit.h"
26 #include <QApplication>
28 #include <QMouseEvent>
29 #include <QtCore/QObject>
30 #include <QtCore/QRegExp>
32 #include <kcompletionbox.h>
36 #include <kstandarddirs.h>
37 #include <kstandardshortcut.h>
39 #include "stdaddressbook.h"
49 class 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;
76 bool AddressLineEdit::Private::initialized =
false;
77 K_GLOBAL_STATIC( KCompletion, sCompletion )
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;
106 QStringList 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();
166 QStringList 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 );
185 void AddressLineEdit::Private::slotPopupCompletion(
const QString &completion )
187 mParent->setText( mPreviousAddresses + completion );
188 mParent->cursorAtEnd();
191 bool 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"
ConstIterator end() const
Returns an iterator pointing to the last addressee of address book.
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.
void addAddress(const QString &addr)
Adds a new address to the line edit.
QStringList allDistributionListNames() const
Returns a list of names of all distribution lists of all resources of this address book...
virtual void loadAddresses()
Always call AddressLineEdit::loadAddresses() as the first thing.
virtual void paste()
Pastes the clipboard content.
virtual ~AddressLineEdit()
Destroys the instance.
ConstIterator begin() const
Returns an iterator pointing to the first addressee of address book.
A lineedit with kabc completion.
AddressLineEdit(QWidget *parent, bool useCompletion=true)
Creates the line edit instance.
void cursorAtEnd()
Set cursor to end of line.
virtual void keyPressEvent(QKeyEvent *e)
Handles KDE completion short cuts.
virtual void setFont(const QFont &font)
Reimplemented for internal reasons.
virtual void dropEvent(QDropEvent *e)
Handles drop events.
static StdAddressBook * self()
Returns the standard addressbook object.
virtual void insert(const QString &addr)
Inserts the given string.
void enableCompletion(bool enable)
Toggle completion.