akonadi
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"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:09:21 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:09:21 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.