diff --git a/akonadi/contact/CMakeLists.txt b/akonadi/contact/CMakeLists.txt index 1b2f31860..1b422a1e1 100644 --- a/akonadi/contact/CMakeLists.txt +++ b/akonadi/contact/CMakeLists.txt @@ -1,63 +1,64 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII ${KDE4_ENABLE_EXCEPTIONS}") ########### next target ############### set(akonadicontact_editor_SRCS editor/addresseditwidget.cpp editor/contacteditorwidget.cpp editor/dateeditwidget.cpp editor/displaynameeditwidget.cpp editor/emaileditwidget.cpp editor/freebusyeditwidget.cpp editor/imagewidget.cpp editor/imeditwidget.cpp editor/nameeditwidget.cpp editor/phoneeditwidget.cpp editor/secrecyeditwidget.cpp editor/soundeditwidget.cpp ) set(akonadicontact_LIB_SRC addressbookcombobox.cpp addressbookselectiondialog.cpp attributeregistrar.cpp collectionfiltermodel.cpp + contactcompletionmodel.cpp contacteditor.cpp contacteditordialog.cpp contactgroupeditor.cpp contactgroupeditordialog.cpp contactgroupexpandjob.cpp contactgrouplineedit.cpp contactgroupsearchjob.cpp contactgroupviewer.cpp contactgroupviewerdialog.cpp contactmetadata.cpp contactmetadataattribute.cpp contactsearchjob.cpp contactviewer.cpp contactviewerdialog.cpp waitingoverlay.cpp ${akonadicontact_editor_SRCS} ) qt4_wrap_ui(akonadicontact_LIB_SRC contactgroupeditor.ui) kde4_add_library(akonadi-contact SHARED ${akonadicontact_LIB_SRC}) target_link_libraries(akonadi-contact ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_KABC_LIBS} ${KDEPIMLIBS_KCAL_LIBS} ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${KDE4_PHONON_LIBS} kdepim-copy) target_link_libraries(akonadi-contact LINK_INTERFACE_LIBRARIES ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_KABC_LIBS} ${KDE4_KDEUI_LIBS}) set_target_properties(akonadi-contact PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION}) install(TARGETS akonadi-contact ${INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/akonadi/contact/contactcompletionmodel.cpp b/akonadi/contact/contactcompletionmodel.cpp new file mode 100644 index 000000000..92b986f90 --- /dev/null +++ b/akonadi/contact/contactcompletionmodel.cpp @@ -0,0 +1,115 @@ +/* + This file is part of Akonadi Contact. + + Copyright (c) 2009 Tobias Koenig + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "contactcompletionmodel_p.h" + +#include +#include +#include +#include +#include + +#include + +using namespace Akonadi; + +QAbstractItemModel* ContactCompletionModel::mSelf = 0; + +QAbstractItemModel* ContactCompletionModel::self() +{ + if ( mSelf ) + return mSelf; + + Monitor *monitor = new Monitor; + monitor->fetchCollection( true ); + monitor->itemFetchScope().fetchFullPayload(); + monitor->setCollectionMonitored( Akonadi::Collection::root() ); + monitor->setMimeTypeMonitored( KABC::Addressee::mimeType() ); + + ContactCompletionModel *model = new ContactCompletionModel( Session::defaultSession(), monitor ); + + Akonadi::DescendantsProxyModel *descModel = new DescendantsProxyModel( model ); + descModel->setSourceModel( model ); + + EntityFilterProxyModel *filter = new Akonadi::EntityFilterProxyModel( model ); + filter->setSourceModel( descModel ); + filter->addMimeTypeExclusionFilter( Akonadi::Collection::mimeType() ); + filter->setHeaderSet( Akonadi::EntityTreeModel::ItemListHeaders ); + + mSelf = filter; + + return mSelf; +} + +ContactCompletionModel::ContactCompletionModel( Session *session, Monitor *monitor, QObject *parent ) + : EntityTreeModel( session, monitor, parent ) +{ +} + +ContactCompletionModel::~ContactCompletionModel() +{ +} + +QVariant ContactCompletionModel::getData( const Item &item, int column, int role ) const +{ + if ( !item.hasPayload() ) { + // Pass modeltest + if ( role == Qt::DisplayRole ) + return item.remoteId(); + + return QVariant(); + } + + if ( role == Qt::DisplayRole || role == Qt::EditRole ) { + const KABC::Addressee contact = item.payload(); + + switch ( column ) { + case NameColumn: + if ( !contact.formattedName().isEmpty() ) + return contact.formattedName(); + else + return contact.assembledName(); + break; + case NameAndEmailColumn: + return contact.fullEmail(); + break; + case EmailColumn: + return contact.preferredEmail(); + break; + } + } + + return EntityTreeModel::getData( item, column, role ); +} + +int ContactCompletionModel::columnCount( const QModelIndex &parent ) const +{ + if ( !parent.isValid() ) + return 3; + else + return 0; +} + +int ContactCompletionModel::getColumnCount( int ) const +{ + return 3; +} + +#include "contactcompletionmodel_p.moc" diff --git a/akonadi/contact/contactcompletionmodel_p.h b/akonadi/contact/contactcompletionmodel_p.h new file mode 100644 index 000000000..f5c20e7b6 --- /dev/null +++ b/akonadi/contact/contactcompletionmodel_p.h @@ -0,0 +1,55 @@ +/* + This file is part of Akonadi Contact. + + Copyright (c) 2009 Tobias Koenig + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef AKONADI_CONTACTCOMPLETIONMODEL_H +#define AKONADI_CONTACTCOMPLETIONMODEL_H + +#include + +namespace Akonadi { + +class ContactCompletionModel : public EntityTreeModel +{ + Q_OBJECT + + public: + enum Columns + { + NameColumn, ///< The name of the contact. + NameAndEmailColumn, ///< The name and the email of the contact. + EmailColumn ///< The preferred email of the contact. + }; + + ContactCompletionModel( Session *session, Monitor *monitor, QObject *parent = 0 ); + virtual ~ContactCompletionModel(); + + virtual QVariant getData( const Item &item, int column, int role = Qt::DisplayRole ) const; + virtual int columnCount( const QModelIndex &parent ) const; + virtual int getColumnCount( int ) const; + + static QAbstractItemModel* self(); + + private: + static QAbstractItemModel* mSelf; +}; + +} + +#endif diff --git a/akonadi/contact/contactgroupeditor.cpp b/akonadi/contact/contactgroupeditor.cpp index f061d2d69..ad3e22262 100644 --- a/akonadi/contact/contactgroupeditor.cpp +++ b/akonadi/contact/contactgroupeditor.cpp @@ -1,353 +1,349 @@ /* Copyright (c) 2007 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "contactgroupeditor.h" #include #include #include #include #include #include #include #include #include #include #include #include #include +#include "contactcompletionmodel_p.h" #include "contactgrouplineedit_p.h" #include "ui_contactgroupeditor.h" #include "waitingoverlay_p.h" namespace Akonadi { class ContactGroupEditor::Private { public: Private( ContactGroupEditor *parent ) - : mParent( parent ), mMonitor( 0 ), mCompletionModel( 0 ) + : mParent( parent ), mMonitor( 0 ), mCompletionModel( 0 ), mReadOnly( false ) { + mCompletionModel = ContactCompletionModel::self(); } ~Private() { delete mMonitor; } void fetchDone( KJob* ); void storeDone( KJob* ); void itemChanged( const Akonadi::Item &item, const QSet& ); void memberChanged(); void setReadOnly( bool ); void loadContactGroup( const KABC::ContactGroup &group ); bool storeContactGroup( KABC::ContactGroup &group ); void setupMonitor(); ContactGroupLineEdit* addMemberEdit(); ContactGroupEditor *mParent; ContactGroupEditor::Mode mMode; Item mItem; Monitor *mMonitor; Collection mDefaultCollection; Ui::ContactGroupEditor mGui; QVBoxLayout *mMembersLayout; QList mMembers; QAbstractItemModel *mCompletionModel; bool mReadOnly; }; } using namespace Akonadi; void ContactGroupEditor::Private::fetchDone( KJob *job ) { if ( job->error() ) return; ItemFetchJob *fetchJob = qobject_cast( job ); if ( !fetchJob ) return; if ( fetchJob->items().isEmpty() ) return; mItem = fetchJob->items().first(); if ( mMode == ContactGroupEditor::EditMode ) { mReadOnly = false; const Akonadi::Collection parentCollection = mItem.parentCollection(); if ( parentCollection.isValid() ) - mReadOnly = (parentCollection.rights() & Collection::CanChangeItem); + mReadOnly = !(parentCollection.rights() & Collection::CanChangeItem); } const KABC::ContactGroup group = mItem.payload(); loadContactGroup( group ); setReadOnly( mReadOnly ); } void ContactGroupEditor::Private::storeDone( KJob *job ) { if ( job->error() ) { emit mParent->error( job->errorString() ); return; } if ( mMode == EditMode ) emit mParent->contactGroupStored( mItem ); else if ( mMode == CreateMode ) emit mParent->contactGroupStored( static_cast( job )->item() ); } void ContactGroupEditor::Private::itemChanged( const Item&, const QSet& ) { QMessageBox dlg( mParent ); dlg.setInformativeText( QLatin1String( "The contact group has been changed by anyone else\nWhat shall be done?" ) ); dlg.addButton( i18n( "Take over changes" ), QMessageBox::AcceptRole ); dlg.addButton( i18n( "Ignore and Overwrite changes" ), QMessageBox::RejectRole ); if ( dlg.exec() == QMessageBox::AcceptRole ) { ItemFetchJob *job = new ItemFetchJob( mItem ); job->fetchScope().fetchFullPayload(); job->fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent ); mParent->connect( job, SIGNAL( result( KJob* ) ), mParent, SLOT( fetchDone( KJob* ) ) ); new WaitingOverlay( job, mParent ); } } void ContactGroupEditor::Private::loadContactGroup( const KABC::ContactGroup &group ) { mGui.groupName->setText( group.name() ); qDeleteAll( mMembers ); for ( unsigned int i = 0; i < group.dataCount(); ++i ) { const KABC::ContactGroup::Data data = group.data( i ); ContactGroupLineEdit *lineEdit = addMemberEdit(); mParent->disconnect( lineEdit, SIGNAL( textChanged( const QString& ) ), mParent, SLOT( memberChanged() ) ); lineEdit->setContactData( data ); mParent->connect( lineEdit, SIGNAL( textChanged( const QString& ) ), SLOT( memberChanged() ) ); } for ( unsigned int i = 0; i < group.contactReferenceCount(); ++i ) { const KABC::ContactGroup::ContactReference reference = group.contactReference( i ); ContactGroupLineEdit *lineEdit = addMemberEdit(); mParent->disconnect( lineEdit, SIGNAL( textChanged( const QString& ) ), mParent, SLOT( memberChanged() ) ); lineEdit->setContactReference( reference ); mParent->connect( lineEdit, SIGNAL( textChanged( const QString& ) ), SLOT( memberChanged() ) ); } addMemberEdit(); } bool ContactGroupEditor::Private::storeContactGroup( KABC::ContactGroup &group ) { if ( mGui.groupName->text().isEmpty() ) { KMessageBox::error( mParent, i18n( "The name of the contact group must not be empty." ) ); return false; } group.setName( mGui.groupName->text() ); group.removeAllContactData(); group.removeAllContactReferences(); // Iterate over all members except the last one, as this is always empty anyway for ( int i = 0; i < (mMembers.count() - 1); ++i ) { if ( mMembers.at( i )->containsReference() ) { const KABC::ContactGroup::ContactReference reference = mMembers.at( i )->contactReference(); if ( !(reference == KABC::ContactGroup::ContactReference()) ) group.append( reference ); } else { const KABC::ContactGroup::Data data = mMembers.at( i )->contactData(); if ( data == KABC::ContactGroup::Data() ) { const QString text = mMembers.at( i )->text(); QString fullName, email; KABC::Addressee::parseEmailAddress( text, fullName, email ); if ( fullName.isEmpty() ) { KMessageBox::error( mParent, i18n( "The contact '%1' is missing a name.", text ) ); return false; } if ( email.isEmpty() ) { KMessageBox::error( mParent, i18n( "The contact '%1' is missing an email address.", text ) ); return false; } } else { group.append( data ); } } } return true; } void ContactGroupEditor::Private::setupMonitor() { delete mMonitor; mMonitor = new Monitor; mMonitor->ignoreSession( Session::defaultSession() ); connect( mMonitor, SIGNAL( itemChanged( const Akonadi::Item&, const QSet& ) ), mParent, SLOT( itemChanged( const Akonadi::Item&, const QSet& ) ) ); } ContactGroupLineEdit* ContactGroupEditor::Private::addMemberEdit() { ContactGroupLineEdit *lineEdit = new ContactGroupLineEdit( mParent ); lineEdit->setCompletionModel( mCompletionModel ); lineEdit->setToolTip( i18n( "Enter member in format: name " ) ); mMembers.append( lineEdit ); mMembersLayout->addWidget( lineEdit ); mParent->connect( lineEdit, SIGNAL( textChanged( const QString& ) ), SLOT( memberChanged() ) ); return lineEdit; } void ContactGroupEditor::Private::memberChanged() { // remove last line edit iff last and second last line edits are both empty if ( mMembers.count() >= 2 ) { // only if more than 1 line edit available if ( mMembers.at( mMembers.count() - 1 )->text().isEmpty() && mMembers.at( mMembers.count() - 2 )->text().isEmpty() ) { // delete line edit with deleteLater as this slot might be called by // that line edit mMembers.at( mMembers.count() - 1 )->deleteLater(); // remove line edit from list of known line edits mMembers.removeAt( mMembers.count() - 1 ); } } // add new line edit if the last one contains text if ( !mMembers.last()->text().isEmpty() ) addMemberEdit(); } void ContactGroupEditor::Private::setReadOnly( bool readOnly ) { mGui.groupName->setReadOnly( readOnly ); for ( int i = 0; i < mMembers.count(); ++i ) mMembers.at( i )->setReadOnly( readOnly ); } ContactGroupEditor::ContactGroupEditor( Mode mode, QWidget *parent ) : QWidget( parent ), d( new Private( this ) ) { d->mMode = mode; d->mGui.setupUi( this ); d->mGui.gridLayout->setRowStretch( 2, 1 ); QVBoxLayout *layout = new QVBoxLayout( d->mGui.memberWidget ); d->mMembersLayout = new QVBoxLayout(); layout->addLayout( d->mMembersLayout ); layout->addStretch(); + + if ( d->mMode == CreateMode ) + d->addMemberEdit(); } ContactGroupEditor::~ContactGroupEditor() { delete d; } -void ContactGroupEditor::setCompletionModel( QAbstractItemModel *model ) -{ - d->mCompletionModel = model; - - // We have to add the initial member edit here as it depends on the completion model - if ( d->mMode == CreateMode ) - d->addMemberEdit(); -} - void ContactGroupEditor::loadContactGroup( const Akonadi::Item &item ) { if ( d->mMode == CreateMode ) Q_ASSERT_X( false, "ContactGroupEditor::loadContactGroup", "You are calling loadContactGroup in CreateMode!" ); if ( !d->mCompletionModel ) Q_ASSERT_X( false, "ContactGroupEditor::loadContactGroup", "You have no completion model set yet!" ); ItemFetchJob *job = new ItemFetchJob( item ); job->fetchScope().fetchFullPayload(); job->fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent ); connect( job, SIGNAL( result( KJob* ) ), SLOT( fetchDone( KJob* ) ) ); d->setupMonitor(); d->mMonitor->setItemMonitored( item ); new WaitingOverlay( job, this ); } bool ContactGroupEditor::saveContactGroup() { if ( d->mMode == EditMode ) { if ( !d->mItem.isValid() ) return false; if ( d->mReadOnly ) return true; KABC::ContactGroup group = d->mItem.payload(); if ( !d->storeContactGroup( group ) ) return false; d->mItem.setPayload( group ); ItemModifyJob *job = new ItemModifyJob( d->mItem ); connect( job, SIGNAL( result( KJob* ) ), SLOT( storeDone( KJob* ) ) ); } else if ( d->mMode == CreateMode ) { Q_ASSERT_X( d->mDefaultCollection.isValid(), "ContactGroupEditor::saveContactGroup", "Using invalid default collection for saving!" ); KABC::ContactGroup group; if ( !d->storeContactGroup( group ) ) return false; Item item; item.setPayload( group ); item.setMimeType( KABC::ContactGroup::mimeType() ); ItemCreateJob *job = new ItemCreateJob( item, d->mDefaultCollection ); connect( job, SIGNAL( result( KJob* ) ), SLOT( storeDone( KJob* ) ) ); } return true; } void ContactGroupEditor::setDefaultCollection( const Akonadi::Collection &collection ) { d->mDefaultCollection = collection; } #include "contactgroupeditor.moc" diff --git a/akonadi/contact/contactgroupeditor.h b/akonadi/contact/contactgroupeditor.h index 2522151d0..8f5026c42 100644 --- a/akonadi/contact/contactgroupeditor.h +++ b/akonadi/contact/contactgroupeditor.h @@ -1,125 +1,116 @@ /* This file is part of Akonadi Contact. Copyright (c) 2009 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef AKONADI_CONTACTGROUPEDITOR_H #define AKONADI_CONTACTGROUPEDITOR_H #include "akonadi-contact_export.h" #include -class QAbstractItemModel; - namespace Akonadi { class Collection; class Item; /** * @short An editor for contact groups. * * @author Tobias Koenig * @since 4.3 */ class AKONADI_CONTACT_EXPORT ContactGroupEditor : public QWidget { Q_OBJECT public: /** * Describes the mode of the contact group editor. */ enum Mode { CreateMode, ///< Creates a new contact group EditMode ///< Edits an existing contact group }; /** * Creates a new contact group editor. * * @param mode The mode of the editor. * @param parent The parent widget of the editor. */ explicit ContactGroupEditor( Mode mode, QWidget *parent = 0 ); /** * Destroys the contact group editor. */ virtual ~ContactGroupEditor(); - /** - * Sets the contact completion @p model. - * - * @note Must be called before the first loadContactGroup() call. - */ - void setCompletionModel( QAbstractItemModel *model ); - public Q_SLOTS: /** * Loads the contact @p group into the editor. */ void loadContactGroup( const Akonadi::Item &group ); /** * Saves the contact group from the editor back to the storage. * * @returns @c true if the contact group has been saved successfully, false otherwise. */ bool saveContactGroup(); /** * Sets the @p collection which shall be used to store new * contact groups. */ void setDefaultCollection( const Akonadi::Collection &collection ); Q_SIGNALS: /** * This signal is emitted when the contact @p group has been saved back * to the storage. */ void contactGroupStored( const Akonadi::Item &group ); /** * This signal is emitted when an error occurred during the save. * * @p errorMsg The error message. */ void error( const QString &errorMsg ); private: //@cond PRIVATE class Private; Private* const d; Q_DISABLE_COPY( ContactGroupEditor ) Q_PRIVATE_SLOT( d, void fetchDone( KJob* ) ) Q_PRIVATE_SLOT( d, void storeDone( KJob* ) ) Q_PRIVATE_SLOT( d, void itemChanged( const Akonadi::Item&, const QSet& ) ) Q_PRIVATE_SLOT( d, void memberChanged() ) //@endcond }; } #endif diff --git a/akonadi/contact/contactgroupeditordialog.cpp b/akonadi/contact/contactgroupeditordialog.cpp index 7d6ef5593..0d37661be 100644 --- a/akonadi/contact/contactgroupeditordialog.cpp +++ b/akonadi/contact/contactgroupeditordialog.cpp @@ -1,108 +1,103 @@ /* This file is part of Akonadi Contact. Copyright (c) 2007-2009 Tobias Koenig This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "contactgroupeditordialog.h" #include "addressbookcombobox.h" #include "contactgroupeditor.h" #include #include #include #include #include using namespace Akonadi; class ContactGroupEditorDialog::Private { public: Private() : mAddressBookBox( 0 ) { } AddressBookComboBox *mAddressBookBox; ContactGroupEditor *mEditor; }; ContactGroupEditorDialog::ContactGroupEditorDialog( Mode mode, QWidget *parent ) : KDialog( parent ), d( new Private ) { setCaption( mode == CreateMode ? i18n( "New Contact Group" ) : i18n( "Edit Contact Group" ) ); setButtons( Ok | Cancel ); QWidget *mainWidget = new QWidget( this ); setMainWidget( mainWidget ); QGridLayout *layout = new QGridLayout( mainWidget ); d->mEditor = new Akonadi::ContactGroupEditor( mode == CreateMode ? Akonadi::ContactGroupEditor::CreateMode : Akonadi::ContactGroupEditor::EditMode, this ); if ( mode == CreateMode ) { QLabel *label = new QLabel( i18n( "Add to:" ), mainWidget ); d->mAddressBookBox = new AddressBookComboBox( AddressBookComboBox::ContactGroupsOnly, mainWidget ); layout->addWidget( label, 0, 0 ); layout->addWidget( d->mAddressBookBox, 0, 1 ); } layout->addWidget( d->mEditor, 1, 0, 1, 2 ); layout->setColumnStretch( 1, 1 ); connect( d->mEditor, SIGNAL( contactGroupStored( const Akonadi::Item& ) ), this, SIGNAL( contactGroupStored( const Akonadi::Item& ) ) ); setInitialSize( QSize( 420, 120 ) ); } ContactGroupEditorDialog::~ContactGroupEditorDialog() { delete d; } -void ContactGroupEditorDialog::setCompletionModel( QAbstractItemModel *model ) -{ - d->mEditor->setCompletionModel( model ); -} - void ContactGroupEditorDialog::setContactGroup( const Akonadi::Item &group ) { d->mEditor->loadContactGroup( group ); } void ContactGroupEditorDialog::slotButtonClicked( int button ) { if ( button == KDialog::Ok ) { if ( d->mAddressBookBox ) d->mEditor->setDefaultCollection( d->mAddressBookBox->selectedAddressBook() ); if ( d->mEditor->saveContactGroup() ) accept(); } else if ( button == KDialog::Cancel ) { reject(); } } #include "contactgroupeditordialog.moc" diff --git a/akonadi/contact/contactgroupeditordialog.h b/akonadi/contact/contactgroupeditordialog.h index d31db5859..dd5d5db3e 100644 --- a/akonadi/contact/contactgroupeditordialog.h +++ b/akonadi/contact/contactgroupeditordialog.h @@ -1,97 +1,92 @@ /* This file is part of Akonadi Contact. Copyright (c) 2009 Tobias Koenig This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef AKONADI_CONTACTGROUPEDITORDIALOG_H #define AKONADI_CONTACTGROUPEDITORDIALOG_H #include "akonadi-contact_export.h" #include class QAbstractItemModel; namespace Akonadi { class Item; class ContactGroupEditor; /** * @short A dialog for editing a contact group. * * @author Tobias Koenig */ class AKONADI_CONTACT_EXPORT ContactGroupEditorDialog : public KDialog { Q_OBJECT public: /** * Describes the mode of the contact group editor. */ enum Mode { CreateMode, ///< Creates a new contact group EditMode ///< Edits an existing contact group }; /** * Creates a new contact group editor dialog. * * @param mode The mode of the dialog. * @param parent The parent widget of the dialog. */ ContactGroupEditorDialog( Mode mode, QWidget *parent = 0 ); /** * Destroys the contact group editor dialog. */ ~ContactGroupEditorDialog(); - /** - * Sets the contact completion @p model that shall be used. - */ - void setCompletionModel( QAbstractItemModel *model ); - /** * Sets the contact @p group to edit when in EditMode. */ void setContactGroup( const Akonadi::Item &group ); Q_SIGNALS: /** * This signal is emitted whenever a contact group was updated or stored. * * @param group The contact group. */ void contactGroupStored( const Akonadi::Item &group ); protected Q_SLOTS: virtual void slotButtonClicked( int button ); private: //@cond PRIVATE class Private; Private* const d; //@endcond }; } #endif diff --git a/akonadi/contact/contactgrouplineedit.cpp b/akonadi/contact/contactgrouplineedit.cpp index 8ef358120..3c1af8224 100644 --- a/akonadi/contact/contactgrouplineedit.cpp +++ b/akonadi/contact/contactgrouplineedit.cpp @@ -1,184 +1,185 @@ /* Copyright (c) 2009 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "contactgrouplineedit_p.h" +#include "contactcompletionmodel_p.h" + #include #include #include #include #include #include ContactGroupLineEdit::ContactGroupLineEdit( QWidget *parent ) : QLineEdit( parent ), mCompleter( 0 ), mModel( 0 ), mContainsReference( false ) { } void ContactGroupLineEdit::setCompletionModel( QAbstractItemModel *model ) { mModel = model; mCompleter = new QCompleter( mModel, this ); - mCompleter->setCompletionColumn( 0 ); - mCompleter->setCompletionRole( Qt::DisplayRole ); + mCompleter->setCompletionColumn( Akonadi::ContactCompletionModel::NameAndEmailColumn ); connect( mCompleter, SIGNAL( activated( const QModelIndex& ) ), this, SLOT( autoCompleted( const QModelIndex& ) ) ); setCompleter( mCompleter ); } bool ContactGroupLineEdit::containsReference() const { return mContainsReference; } void ContactGroupLineEdit::setContactData( const KABC::ContactGroup::Data &data ) { mContactData = data; mContainsReference = false; setText( QString::fromLatin1( "%1 <%2>" ).arg( data.name() ).arg( data.email() ) ); } KABC::ContactGroup::Data ContactGroupLineEdit::contactData() const { QString fullName, email; KABC::Addressee::parseEmailAddress( text(), fullName, email ); if ( fullName.isEmpty() || email.isEmpty() ) return KABC::ContactGroup::Data(); KABC::ContactGroup::Data data( mContactData ); data.setName( fullName ); data.setEmail( email ); return data; } void ContactGroupLineEdit::setContactReference( const KABC::ContactGroup::ContactReference &reference ) { mContactReference = reference; mContainsReference = true; updateView( reference.uid(), reference.preferredEmail() ); } KABC::ContactGroup::ContactReference ContactGroupLineEdit::contactReference() const { return mContactReference; } void ContactGroupLineEdit::autoCompleted( const QModelIndex &index ) { if ( !index.isValid() ) return; const Akonadi::Item item = index.data( Akonadi::EntityTreeModel::ItemRole ).value(); if ( !item.isValid() ) return; mContainsReference = true; updateView( item ); } void ContactGroupLineEdit::updateView( const QString &uid, const QString &preferredEmail ) { if ( !mModel ) { qDebug( "ContactGroupLineEdit::updateView(): Warning!!! no model set" ); return; } const Akonadi::Item::Id updateId = uid.toLongLong(); for ( int i = 0; i < mModel->rowCount(); ++i ) { const QModelIndex index = mModel->index( i, 0 ); if ( !index.isValid() ) continue; const Akonadi::Item item = index.data( Akonadi::EntityTreeModel::ItemRole ).value(); if ( !item.isValid() ) continue; if ( item.id() == updateId ) { updateView( item, preferredEmail ); break; } } } void ContactGroupLineEdit::updateView( const Akonadi::Item &item, const QString &preferredEmail ) { if ( !item.hasPayload() ) return; const KABC::Addressee contact = item.payload(); QString email( preferredEmail ); if ( email.isEmpty() ) email = requestPreferredEmail( contact ); QString name = contact.formattedName(); if ( name.isEmpty() ) name = contact.assembledName(); if ( email.isEmpty() ) setText( QString::fromLatin1( "%1" ).arg( name ) ); else setText( QString::fromLatin1( "%1 <%2>" ).arg( name ).arg( email ) ); mContactReference.setUid( QString::number( item.id() ) ); if ( contact.preferredEmail() != email ) mContactReference.setPreferredEmail( email ); } QString ContactGroupLineEdit::requestPreferredEmail( const KABC::Addressee &contact ) const { const QStringList emails = contact.emails(); if ( emails.isEmpty() ) { qDebug( "ContactGroupLineEdit::requestPreferredEmail(): Warning!!! no email addresses available" ); return QString(); } if ( emails.count() == 1 ) return emails.first(); QAction *action = 0; QMenu menu; menu.setTitle( i18n( "Select preferred email address" ) ); for ( int i = 0; i < emails.count(); ++i ) { action = menu.addAction( emails.at( i ) ); action->setData( i ); } action = menu.exec( mapToGlobal( QPoint( x() + width()/2, y() + height()/2 ) ) ); if ( !action ) return emails.first(); // use preferred email return emails.at( action->data().toInt() ); } #include "contactgrouplineedit_p.moc"