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/QToolButton>
00037
00038 using namespace Akonadi;
00039
00040 ContactLineEdit::ContactLineEdit( bool isReference, QWidget *parent )
00041 : KLineEdit( parent ), mIsReference( isReference )
00042 {
00043 setFrame( false );
00044
00045 QCompleter *completer = new QCompleter( Akonadi::ContactCompletionModel::self(), this );
00046 completer->setCompletionColumn( Akonadi::ContactCompletionModel::NameColumn );
00047 completer->setCaseSensitivity( Qt::CaseInsensitive );
00048 connect( completer, SIGNAL( activated( const QModelIndex& ) ), SLOT( completed( const QModelIndex& ) ) );
00049
00050 setCompleter( completer );
00051
00052 connect( this, SIGNAL( textEdited( const QString& ) ), SLOT( slotTextEdited() ) );
00053 }
00054
00055 bool ContactLineEdit::isReference() const
00056 {
00057 return mIsReference;
00058 }
00059
00060 Akonadi::Item ContactLineEdit::completedItem() const
00061 {
00062 return mItem;
00063 }
00064
00065 void ContactLineEdit::completed( const QModelIndex &index )
00066 {
00067 if ( index.isValid() ) {
00068 mItem = index.data( Akonadi::EntityTreeModel::ItemRole ).value<Akonadi::Item>();
00069 mIsReference = true;
00070 } else {
00071 mItem = Item();
00072 mIsReference = false;
00073 }
00074
00075 emit completed( this );
00076 }
00077
00078 void ContactLineEdit::slotTextEdited()
00079 {
00080
00081 mIsReference = false;
00082 }
00083
00084 class ContactGroupEditorDelegate::Private
00085 {
00086 public:
00087 Private()
00088 : mButtonSize( 16, 16 ), mIcon( QLatin1String( "list-remove" ) )
00089 {
00090 }
00091
00092 QSize mButtonSize;
00093 const KIcon mIcon;
00094 QAbstractItemView *mItemView;
00095 };
00096
00097 ContactGroupEditorDelegate::ContactGroupEditorDelegate( QAbstractItemView *view, QObject *parent )
00098 : QStyledItemDelegate( parent ), d( new Private )
00099 {
00100 d->mItemView = view;
00101 }
00102
00103 ContactGroupEditorDelegate::~ContactGroupEditorDelegate()
00104 {
00105 delete d;
00106 }
00107
00108 QWidget* ContactGroupEditorDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem&,
00109 const QModelIndex &index ) const
00110 {
00111 if ( index.column() == 0 ) {
00112 ContactLineEdit *edit = 0;
00113 if ( index.data( ContactGroupModel::IsReferenceRole ).toBool() ) {
00114 edit = new ContactLineEdit( true, parent );
00115 } else {
00116 edit = new ContactLineEdit( false, parent );
00117 }
00118
00119 connect( edit, SIGNAL( completed( QWidget* ) ), SLOT( completed( QWidget* ) ) );
00120
00121 return edit;
00122 } else {
00123 if ( index.data( ContactGroupModel::IsReferenceRole ).toBool() ) {
00124 KComboBox *comboBox = new KComboBox( parent );
00125 comboBox->setFrame( false );
00126 return comboBox;
00127 } else {
00128 KLineEdit *lineEdit = new KLineEdit( parent );
00129 lineEdit->setFrame( false );
00130 return lineEdit;
00131 }
00132 }
00133 }
00134
00135 void ContactGroupEditorDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
00136 {
00137 if ( index.data( ContactGroupModel::IsReferenceRole ).toBool() ) {
00138 if ( index.column() == 0 ) {
00139 KLineEdit *lineEdit = qobject_cast<KLineEdit*>( editor );
00140 if ( !lineEdit )
00141 return;
00142
00143 lineEdit->setText( index.data( Qt::EditRole ).toString() );
00144 } else {
00145 KComboBox *comboBox = qobject_cast<KComboBox*>( editor );
00146 if ( !comboBox )
00147 return;
00148
00149 const QStringList emails = index.data( ContactGroupModel::AllEmailsRole ).toStringList();
00150 comboBox->clear();
00151 comboBox->addItems( emails );
00152 comboBox->setCurrentIndex( comboBox->findText( index.data( Qt::EditRole ).toString() ) );
00153 }
00154 } else {
00155 if ( index.column() == 0 ) {
00156
00157 KLineEdit *lineEdit = qobject_cast<KLineEdit*>( editor );
00158 if ( !lineEdit )
00159 return;
00160
00161 lineEdit->setText( index.data( Qt::EditRole ).toString() );
00162
00163 } else {
00164 KLineEdit *lineEdit = qobject_cast<KLineEdit*>( editor );
00165 if ( !lineEdit )
00166 return;
00167
00168 lineEdit->setText( index.data( Qt::EditRole ).toString() );
00169 }
00170 }
00171 }
00172
00173 void ContactGroupEditorDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
00174 {
00175 if ( index.data( ContactGroupModel::IsReferenceRole ).toBool() ) {
00176 if ( index.column() == 0 ) {
00177 ContactLineEdit *lineEdit = static_cast<ContactLineEdit*>( editor );
00178
00179 const bool isReference = lineEdit->isReference();
00180 const Item item = lineEdit->completedItem();
00181 model->setData( index, isReference, ContactGroupModel::IsReferenceRole );
00182 if ( isReference ) {
00183 if ( item.isValid() )
00184 model->setData( index, item.id(), Qt::EditRole );
00185 } else
00186 model->setData( index, lineEdit->text(), Qt::EditRole );
00187 }
00188
00189 if ( index.column() == 1 ) {
00190 KComboBox *comboBox = qobject_cast<KComboBox*>( editor );
00191 if ( !comboBox )
00192 return;
00193
00194 model->setData( index, comboBox->currentText(), Qt::EditRole );
00195 }
00196 } else {
00197 if ( index.column() == 0 ) {
00198 ContactLineEdit *lineEdit = static_cast<ContactLineEdit*>( editor );
00199
00200 const bool isReference = lineEdit->isReference();
00201 const Item item = lineEdit->completedItem();
00202 model->setData( index, isReference, ContactGroupModel::IsReferenceRole );
00203 if ( isReference ) {
00204 if ( item.isValid() )
00205 model->setData( index, item.id(), Qt::EditRole );
00206 } else
00207 model->setData( index, lineEdit->text(), Qt::EditRole );
00208 }
00209
00210 if ( index.column() == 1 ) {
00211 KLineEdit *lineEdit = qobject_cast<KLineEdit*>( editor );
00212 if ( !lineEdit )
00213 return;
00214
00215 model->setData( index, lineEdit->text(), Qt::EditRole );
00216 }
00217 }
00218 }
00219
00220 static bool isLastRow( const QModelIndex &index )
00221 {
00222 return (index.row() == (index.model()->rowCount() - 1));
00223 }
00224
00225 void ContactGroupEditorDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
00226 {
00227 QStyledItemDelegate::paint( painter, option, index );
00228
00229 if ( index.column() == 1 && !isLastRow( index ) )
00230 d->mIcon.paint( painter, option.rect, Qt::AlignRight );
00231 }
00232
00233 QSize ContactGroupEditorDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
00234 {
00235 Q_UNUSED( option );
00236
00237 QSize hint = QStyledItemDelegate::sizeHint( option, index );
00238 hint.setHeight( qMax( hint.height(), d->mButtonSize.height() ) );
00239
00240 if ( index.column() == 1 )
00241 hint.setWidth( hint.width() + d->mButtonSize.width() );
00242
00243 return hint;
00244 }
00245
00246 bool ContactGroupEditorDelegate::editorEvent( QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index )
00247 {
00248 if ( index.column() == 1 && !isLastRow( index ) ) {
00249 if ( event->type() == QEvent::MouseButtonRelease ) {
00250 const QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event );
00251 QRect buttonRect = d->mItemView->visualRect( index );
00252 buttonRect.setLeft( buttonRect.right() - d->mButtonSize.width() );
00253
00254 if ( buttonRect.contains( mouseEvent->pos() ) ) {
00255 model->removeRows( index.row(), 1 );
00256 QTimer::singleShot( 0, this, SLOT( setLastRowAsCurrent() ) );
00257 return true;
00258 }
00259 }
00260 }
00261 return QStyledItemDelegate::editorEvent( event, model, option, index );
00262 }
00263
00264 void ContactGroupEditorDelegate::completed( QWidget *widget )
00265 {
00266 emit commitData( widget );
00267 emit closeEditor( widget );
00268 }
00269
00270 void ContactGroupEditorDelegate::setLastRowAsCurrent()
00271 {
00272 d->mItemView->setCurrentIndex( d->mItemView->model()->index( d->mItemView->model()->rowCount() - 1, 0 ) );
00273 }
00274
00275 #include "contactgroupeditordelegate_p.moc"