Waste less space in nested layouts.
[kdepim.git] / messagecomposer / composerlineedit.cpp
blob87970282cdc96329b89e2c26dcc602108f797b73
1 /* -*- mode: C++; c-file-style: "gnu" -*-
2 Copyright (c) 2010 Volker Krause <vkrause@kde.org>
4 Based on kmail/kmlineeditspell.h/cpp
5 Copyright (c) 1997 Markus Wuebben <markus.wuebben@kde.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include "composerlineedit.h"
25 #include "recentaddresses.h"
26 #include "messagecomposersettings.h"
27 #include "messageviewer/autoqpointer.h"
29 #include <messagecore/stringutil.h>
31 #include <kpimutils/email.h>
32 #include <kabc/vcarddrag.h>
33 #include <kabc/vcardconverter.h>
35 #include <kio/netaccess.h>
36 #include <kmenu.h>
37 #include <kurl.h>
38 #include <kmessagebox.h>
39 #include <kcompletionbox.h>
40 #include <klocale.h>
42 #include <QFile>
43 #include <QCursor>
44 #include <QKeyEvent>
45 #include <QDropEvent>
47 using namespace MessageComposer;
49 ComposerLineEdit::ComposerLineEdit(bool useCompletion, QWidget *parent)
50 : KPIM::AddresseeLineEdit(parent, useCompletion),
51 m_recentAddressConfig( MessageComposerSettings::self()->config() )
53 allowSemicolonAsSeparator( MessageComposerSettings::allowSemicolonAsAddressSeparator() );
54 loadContacts();
58 //-----------------------------------------------------------------------------
59 void ComposerLineEdit::keyPressEvent(QKeyEvent *e)
61 if ((e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) &&
62 !completionBox()->isVisible())
64 emit focusDown();
65 AddresseeLineEdit::keyPressEvent(e);
66 return;
68 if (e->key() == Qt::Key_Up)
70 emit focusUp();
71 return;
73 if (e->key() == Qt::Key_Down)
75 emit focusDown();
76 return;
78 AddresseeLineEdit::keyPressEvent(e);
82 void ComposerLineEdit::insertEmails( const QStringList & emails )
84 if ( emails.empty() )
85 return;
87 QString contents = text();
88 if ( !contents.isEmpty() )
89 contents += QLatin1Char(',');
90 // only one address, don't need kpopup to choose
91 if ( emails.size() == 1 ) {
92 setText( contents + emails.front() );
93 return;
95 //multiple emails, let the user choose one
96 KMenu menu( this );
97 menu.setObjectName( QLatin1String("Addresschooser") );
98 for ( QStringList::const_iterator it = emails.begin(), end = emails.end() ; it != end; ++it )
99 menu.addAction( *it );
100 const QAction *result = menu.exec( QCursor::pos() );
101 if ( !result )
102 return;
103 setText( contents + KGlobal::locale()->removeAcceleratorMarker( result->text() ) );
106 void ComposerLineEdit::dropEvent(QDropEvent *event)
108 const QMimeData *md = event->mimeData();
110 // Case one: The user dropped a text/directory (i.e. vcard), so decode its
111 // contents
112 if ( KABC::VCardDrag::canDecode( md ) ) {
113 KABC::Addressee::List list;
114 KABC::VCardDrag::fromMimeData( md, list );
116 KABC::Addressee::List::Iterator ait;
117 for ( ait = list.begin(); ait != list.end(); ++ait ){
118 insertEmails( (*ait).emails() );
122 // Case two: The user dropped a list or Urls.
123 // Iterate over that list. For mailto: Urls, just add the addressee to the list,
124 // and for other Urls, download the Url and assume it points to a vCard
125 else if ( KUrl::List::canDecode( md ) ) {
126 KUrl::List urls = KUrl::List::fromMimeData( md );
127 KABC::Addressee::List list;
129 foreach ( const KUrl& url, urls ) {
131 // First, let's deal with mailto Urls. The path() part contains the
132 // email-address.
133 if ( url.protocol() == QLatin1String("mailto") ) {
134 KABC::Addressee addressee;
135 addressee.insertEmail( KPIMUtils::decodeMailtoUrl( url ), true /* preferred */ );
136 list += addressee;
139 // Otherwise, download the vCard to which the Url points
140 else {
141 KABC::VCardConverter converter;
142 QString fileName;
143 if ( KIO::NetAccess::download( url, fileName, parentWidget() ) ) {
144 QFile file( fileName );
145 file.open( QIODevice::ReadOnly );
146 const QByteArray data = file.readAll();
147 file.close();
148 list += converter.parseVCards( data );
149 KIO::NetAccess::removeTempFile( fileName );
150 } else {
151 QString caption( i18n( "vCard Import Failed" ) );
152 QString text = i18n( "<qt>Unable to access <b>%1</b>.</qt>", url.url() );
153 KMessageBox::error( parentWidget(), text, caption );
156 // Now, let the user choose which addressee to add.
157 KABC::Addressee::List::Iterator ait;
158 foreach( const KABC::Addressee& addressee, list )
159 insertEmails( addressee.emails() );
163 // Case three: Let AddresseeLineEdit deal with the rest
164 else {
165 KPIM::AddresseeLineEdit::dropEvent( event );
169 void ComposerLineEdit::contextMenuEvent( QContextMenuEvent*e )
171 QMenu *popup = createStandardContextMenu();
172 popup->addSeparator();
173 QAction* act = popup->addAction( i18n( "Edit Recent Addresses..." ));
174 connect(act,SIGNAL(triggered(bool)), SLOT( editRecentAddresses() ) );
175 popup->exec( e->globalPos() );
176 delete popup;
179 void ComposerLineEdit::editRecentAddresses()
181 MessageViewer::AutoQPointer<KPIM::RecentAddressDialog> dlg( new KPIM::RecentAddressDialog( this ) );
182 dlg->setAddresses( KPIM::RecentAddresses::self( m_recentAddressConfig )->addresses() );
183 if ( dlg->exec() && dlg ) {
184 KPIM::RecentAddresses::self( m_recentAddressConfig )->clear();
185 const QStringList addrList = dlg->addresses();
186 for ( QStringList::const_iterator it = addrList.begin(), end = addrList.end() ; it != end ; ++it )
187 KPIM::RecentAddresses::self( MessageComposerSettings::self()->config() )->add( *it );
188 loadContacts();
193 //-----------------------------------------------------------------------------
194 void ComposerLineEdit::loadContacts()
196 //AddresseeLineEdit::loadContacts();
198 if ( MessageComposerSettings::self()->showRecentAddressesInComposer() ){
199 QStringList recent =
200 KPIM::RecentAddresses::self( m_recentAddressConfig )->addresses();
201 QStringList::Iterator it = recent.begin();
202 QString name, email;
204 KSharedConfig::Ptr config = KSharedConfig::openConfig( QLatin1String("kpimcompletionorder") );
205 KConfigGroup group( config, "CompletionWeights" );
206 int weight = group.readEntry( "Recent Addresses", 10 );
207 int idx = addCompletionSource( i18n( "Recent Addresses" ), weight );
208 for ( ; it != recent.end(); ++it ) {
209 KABC::Addressee addr;
210 KPIMUtils::extractEmailAddressAndName( *it, email, name );
211 name = KPIMUtils::quoteNameIfNecessary( name );
212 if ( ( name[0] == QLatin1Char('"') ) && ( name[name.length() - 1] == QLatin1Char('"') ) ) {
213 name.remove( 0, 1 );
214 name.truncate( name.length() - 1 );
216 addr.setNameFromString( name );
217 addr.insertEmail( email, true );
218 addContact( addr, weight, idx );
223 void ComposerLineEdit::setRecentAddressConfig ( KConfig* config )
225 m_recentAddressConfig = config;
229 #include "composerlineedit.moc"