00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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( const QModelIndex& ) ), SLOT( completed( const QModelIndex& ) ) );
00077
00078 setCompleter( completer );
00079
00080 connect( this, SIGNAL( textEdited( const 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
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"