• Skip to content
  • Skip to link menu
KDE 4.8 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • KDE Home
  • Contact Us
 

akonadi/contact

contactgroupeditordelegate.cpp
00001 /*
00002     This file is part of Akonadi Contact.
00003 
00004     Copyright (c) 2009 Tobias Koenig <tokoe@kde.org>
00005 
00006     This library is free software; you can redistribute it and/or modify it
00007     under the terms of the GNU Library General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or (at your
00009     option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful, but WITHOUT
00012     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00014     License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public License
00017     along with this library; see the file COPYING.LIB.  If not, write to the
00018     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00019     02110-1301, USA.
00020 */
00021 
00022 #include "contactgroupeditordelegate_p.h"
00023 
00024 #include "contactcompletionmodel_p.h"
00025 #include "contactgroupmodel_p.h"
00026 
00027 #include <akonadi/entitytreemodel.h>
00028 #include <kcombobox.h>
00029 #include <kicon.h>
00030 #include <klocale.h>
00031 
00032 #include <QtCore/QTimer>
00033 #include <QtGui/QAbstractItemView>
00034 #include <QtGui/QCompleter>
00035 #include <QtGui/QMouseEvent>
00036 #include <QtGui/QSortFilterProxyModel>
00037 #include <QtGui/QToolButton>
00038 
00039 using namespace Akonadi;
00040 
00044 class ContactsWithEmailFilterModel : public QSortFilterProxyModel
00045 {
00046   public:
00047     ContactsWithEmailFilterModel( QObject *parent )
00048       : QSortFilterProxyModel( parent )
00049     {
00050       // contact names should be sorted correctly
00051       setSortLocaleAware( true );
00052     }
00053 
00054   protected:
00055     virtual bool filterAcceptsRow( int row, const QModelIndex &parent ) const
00056     {
00057       const QModelIndex index = sourceModel()->index( row, Akonadi::ContactCompletionModel::EmailColumn, parent );
00058       if ( !index.isValid() )
00059         return false;
00060 
00061       return !index.data().toString().isEmpty();
00062     }
00063 };
00064 
00065 ContactLineEdit::ContactLineEdit( bool isReference, QWidget *parent )
00066   : KLineEdit( parent ), mIsReference( isReference )
00067 {
00068   setFrame( false );
00069 
00070   ContactsWithEmailFilterModel *filter = new ContactsWithEmailFilterModel( this );
00071   filter->setSourceModel( Akonadi::ContactCompletionModel::self() );
00072 
00073   QCompleter *completer = new QCompleter( filter, this );
00074   completer->setCompletionColumn( Akonadi::ContactCompletionModel::NameColumn );
00075   completer->setCaseSensitivity( Qt::CaseInsensitive );
00076   connect( completer, SIGNAL(activated(QModelIndex)), SLOT(completed(QModelIndex)) );
00077 
00078   setCompleter( completer );
00079 
00080   connect( this, SIGNAL(textEdited(QString)), SLOT(slotTextEdited()) );
00081 }
00082 
00083 bool ContactLineEdit::isReference() const
00084 {
00085   return mIsReference;
00086 }
00087 
00088 Akonadi::Item ContactLineEdit::completedItem() const
00089 {
00090   return mItem;
00091 }
00092 
00093 void ContactLineEdit::completed( const QModelIndex &index )
00094 {
00095   if ( index.isValid() ) {
00096     mItem = index.data( Akonadi::EntityTreeModel::ItemRole ).value<Akonadi::Item>();
00097     mIsReference = true;
00098   } else {
00099     mItem = Item();
00100     mIsReference = false;
00101   }
00102 
00103   emit completed( this );
00104 }
00105 
00106 void ContactLineEdit::slotTextEdited()
00107 {
00108   // if the user has edited the text, we break up the reference
00109   mIsReference = false;
00110 }
00111 
00112 class ContactGroupEditorDelegate::Private
00113 {
00114   public:
00115     Private()
00116       : mButtonSize( 16, 16 ), mIcon( QLatin1String( "list-remove" ) )
00117     {
00118     }
00119 
00120     QSize mButtonSize;
00121     const KIcon mIcon;
00122     QAbstractItemView *mItemView;
00123 };
00124 
00125 ContactGroupEditorDelegate::ContactGroupEditorDelegate( QAbstractItemView *view, QObject *parent )
00126   : QStyledItemDelegate( parent ), d( new Private )
00127 {
00128   d->mItemView = view;
00129 }
00130 
00131 ContactGroupEditorDelegate::~ContactGroupEditorDelegate()
00132 {
00133   delete d;
00134 }
00135 
00136 QWidget* ContactGroupEditorDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem&,
00137                                                    const QModelIndex &index ) const
00138 {
00139   if ( index.column() == 0 ) {
00140     ContactLineEdit *edit = 0;
00141     if ( index.data( ContactGroupModel::IsReferenceRole ).toBool() ) {
00142       edit = new ContactLineEdit( true, parent );
00143     } else {
00144       edit = new ContactLineEdit( false, parent );
00145     }
00146 
00147     connect( edit, SIGNAL(completed(QWidget*)), SLOT(completed(QWidget*)) );
00148 
00149     return edit;
00150   } else {
00151     if ( index.data( ContactGroupModel::IsReferenceRole ).toBool() ) {
00152       KComboBox *comboBox = new KComboBox( parent );
00153       comboBox->setFrame( false );
00154       comboBox->setAutoFillBackground( true );
00155       return comboBox;
00156     } else {
00157       KLineEdit *lineEdit = new KLineEdit( parent );
00158       lineEdit->setFrame( false );
00159       return lineEdit;
00160     }
00161   }
00162 }
00163 
00164 void ContactGroupEditorDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
00165 {
00166   if ( index.data( ContactGroupModel::IsReferenceRole ).toBool() ) {
00167     if ( index.column() == 0 ) {
00168       KLineEdit *lineEdit = qobject_cast<KLineEdit*>( editor );
00169       if ( !lineEdit )
00170         return;
00171 
00172       lineEdit->setText( index.data( Qt::EditRole ).toString() );
00173     } else {
00174       KComboBox *comboBox = qobject_cast<KComboBox*>( editor );
00175       if ( !comboBox )
00176         return;
00177 
00178       const QStringList emails = index.data( ContactGroupModel::AllEmailsRole ).toStringList();
00179       comboBox->clear();
00180       comboBox->addItems( emails );
00181       comboBox->setCurrentIndex( comboBox->findText( index.data( Qt::EditRole ).toString() ) );
00182     }
00183   } else {
00184     if ( index.column() == 0 ) {
00185 
00186       KLineEdit *lineEdit = qobject_cast<KLineEdit*>( editor );
00187       if ( !lineEdit )
00188         return;
00189 
00190       lineEdit->setText( index.data( Qt::EditRole ).toString() );
00191 
00192     } else {
00193       KLineEdit *lineEdit = qobject_cast<KLineEdit*>( editor );
00194       if ( !lineEdit )
00195         return;
00196 
00197       lineEdit->setText( index.data( Qt::EditRole ).toString() );
00198     }
00199   }
00200 }
00201 
00202 void ContactGroupEditorDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
00203 {
00204   if ( index.data( ContactGroupModel::IsReferenceRole ).toBool() ) {
00205     if ( index.column() == 0 ) {
00206       ContactLineEdit *lineEdit = static_cast<ContactLineEdit*>( editor );
00207 
00208       const bool isReference = lineEdit->isReference();
00209       const Item item = lineEdit->completedItem();
00210       model->setData( index, isReference, ContactGroupModel::IsReferenceRole );
00211       if ( isReference ) {
00212         if ( item.isValid() )
00213           model->setData( index, item.id(), Qt::EditRole );
00214       } else
00215         model->setData( index, lineEdit->text(), Qt::EditRole );
00216     }
00217 
00218     if ( index.column() == 1 ) {
00219       KComboBox *comboBox = qobject_cast<KComboBox*>( editor );
00220       if ( !comboBox )
00221         return;
00222 
00223       model->setData( index, comboBox->currentText(), Qt::EditRole );
00224     }
00225   } else {
00226     if ( index.column() == 0 ) {
00227       ContactLineEdit *lineEdit = static_cast<ContactLineEdit*>( editor );
00228 
00229       const bool isReference = lineEdit->isReference();
00230       const Item item = lineEdit->completedItem();
00231       model->setData( index, isReference, ContactGroupModel::IsReferenceRole );
00232       if ( isReference ) {
00233         if ( item.isValid() )
00234           model->setData( index, item.id(), Qt::EditRole );
00235       } else
00236         model->setData( index, lineEdit->text(), Qt::EditRole );
00237     }
00238 
00239     if ( index.column() == 1 ) {
00240       KLineEdit *lineEdit = qobject_cast<KLineEdit*>( editor );
00241       if ( !lineEdit )
00242         return;
00243 
00244       model->setData( index, lineEdit->text(), Qt::EditRole );
00245     }
00246   }
00247 }
00248 
00249 static bool isLastRow( const QModelIndex &index )
00250 {
00251   return (index.row() == (index.model()->rowCount() - 1));
00252 }
00253 
00254 void ContactGroupEditorDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
00255 {
00256   QStyledItemDelegate::paint( painter, option, index );
00257 
00258   if ( index.column() == 1 && !isLastRow( index ) )
00259     d->mIcon.paint( painter, option.rect, Qt::AlignRight );
00260 }
00261 
00262 QSize ContactGroupEditorDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
00263 {
00264   Q_UNUSED( option );
00265 
00266   QSize hint = QStyledItemDelegate::sizeHint( option, index );
00267   hint.setHeight( qMax( hint.height(), d->mButtonSize.height() ) );
00268 
00269   if ( index.column() == 1 )
00270     hint.setWidth( hint.width() + d->mButtonSize.width() );
00271 
00272   return hint;
00273 }
00274 
00275 bool ContactGroupEditorDelegate::editorEvent( QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index )
00276 {
00277   if ( index.column() == 1 && !isLastRow( index ) ) {
00278     if ( event->type() == QEvent::MouseButtonRelease ) {
00279       const QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event );
00280       QRect buttonRect = d->mItemView->visualRect( index );
00281       buttonRect.setLeft( buttonRect.right() - d->mButtonSize.width() );
00282 
00283       if ( buttonRect.contains( mouseEvent->pos() ) ) {
00284         model->removeRows( index.row(), 1 );
00285         QTimer::singleShot( 0, this, SLOT(setFirstColumnAsCurrent()) );
00286         return true;
00287       }
00288     }
00289   }
00290   return QStyledItemDelegate::editorEvent( event, model, option, index );
00291 }
00292 
00293 void ContactGroupEditorDelegate::completed( QWidget *widget )
00294 {
00295   emit commitData( widget );
00296   emit closeEditor( widget );
00297 }
00298 
00299 void ContactGroupEditorDelegate::setFirstColumnAsCurrent()
00300 {
00301   d->mItemView->setCurrentIndex( d->mItemView->model()->index( d->mItemView->currentIndex().row(), 0 ) );
00302 }
00303 
00304 #include "contactgroupeditordelegate_p.moc"

akonadi/contact

Skip menu "akonadi/contact"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.7.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal