• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepimlibs API Reference
  • KDE Home
  • Contact Us
 

akonadi

  • sources
  • kde-4.12
  • kdepimlibs
  • akonadi
  • contact
contactgroupeditordelegate.cpp
1 /*
2  This file is part of Akonadi Contact.
3 
4  Copyright (c) 2009 Tobias Koenig <tokoe@kde.org>
5 
6  This library is free software; you can redistribute it and/or modify it
7  under the terms of the GNU Library General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or (at your
9  option) any later version.
10 
11  This library is distributed in the hope that it will be useful, but WITHOUT
12  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14  License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to the
18  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  02110-1301, USA.
20 */
21 
22 #include "contactgroupeditordelegate_p.h"
23 
24 #include "contactcompletionmodel_p.h"
25 #include "contactgroupmodel_p.h"
26 
27 #include <akonadi/entitytreemodel.h>
28 #include <kcombobox.h>
29 #include <kicon.h>
30 #include <klocalizedstring.h>
31 
32 #include <QtCore/QTimer>
33 #include <QAbstractItemView>
34 #include <QCompleter>
35 #include <QMouseEvent>
36 #include <QSortFilterProxyModel>
37 #include <QToolButton>
38 
39 using namespace Akonadi;
40 
44 class ContactsWithEmailFilterModel : public QSortFilterProxyModel
45 {
46  public:
47  ContactsWithEmailFilterModel( QObject *parent )
48  : QSortFilterProxyModel( parent )
49  {
50  // contact names should be sorted correctly
51  setSortLocaleAware( true );
52  }
53 
54  protected:
55  virtual bool filterAcceptsRow( int row, const QModelIndex &parent ) const
56  {
57  const QModelIndex index = sourceModel()->index( row, Akonadi::ContactCompletionModel::EmailColumn, parent );
58  if ( !index.isValid() ) {
59  return false;
60  }
61 
62  return !index.data().toString().isEmpty();
63  }
64 };
65 
66 ContactLineEdit::ContactLineEdit( bool isReference, QWidget *parent )
67  : KLineEdit( parent ), mIsReference( isReference )
68 {
69  setFrame( false );
70 
71  ContactsWithEmailFilterModel *filter = new ContactsWithEmailFilterModel( this );
72  filter->setSourceModel( Akonadi::ContactCompletionModel::self() );
73 
74  QCompleter *completer = new QCompleter( filter, this );
75  completer->setCompletionColumn( Akonadi::ContactCompletionModel::NameColumn );
76  completer->setCaseSensitivity( Qt::CaseInsensitive );
77  connect( completer, SIGNAL(activated(QModelIndex)), SLOT(completed(QModelIndex)) );
78 
79  setCompleter( completer );
80 
81  connect( this, SIGNAL(textEdited(QString)), SLOT(slotTextEdited()) );
82 }
83 
84 bool ContactLineEdit::isReference() const
85 {
86  return mIsReference;
87 }
88 
89 Akonadi::Item ContactLineEdit::completedItem() const
90 {
91  return mItem;
92 }
93 
94 void ContactLineEdit::completed( const QModelIndex &index )
95 {
96  if ( index.isValid() ) {
97  mItem = index.data( Akonadi::EntityTreeModel::ItemRole ).value<Akonadi::Item>();
98  mIsReference = true;
99  } else {
100  mItem = Item();
101  mIsReference = false;
102  }
103 
104  emit completed( this );
105 }
106 
107 void ContactLineEdit::slotTextEdited()
108 {
109  // if the user has edited the text, we break up the reference
110  mIsReference = false;
111 }
112 
113 class ContactGroupEditorDelegate::Private
114 {
115  public:
116  Private()
117  : mButtonSize( 16, 16 ), mIcon( QLatin1String( "list-remove" ) ), mItemView( 0 )
118  {
119  }
120 
121  QSize mButtonSize;
122  const KIcon mIcon;
123  QAbstractItemView *mItemView;
124 };
125 
126 ContactGroupEditorDelegate::ContactGroupEditorDelegate( QAbstractItemView *view, QObject *parent )
127  : QStyledItemDelegate( parent ), d( new Private )
128 {
129  d->mItemView = view;
130 }
131 
132 ContactGroupEditorDelegate::~ContactGroupEditorDelegate()
133 {
134  delete d;
135 }
136 
137 QWidget* ContactGroupEditorDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem&,
138  const QModelIndex &index ) const
139 {
140  if ( index.column() == 0 ) {
141  ContactLineEdit *edit = 0;
142  if ( index.data( ContactGroupModel::IsReferenceRole ).toBool() ) {
143  edit = new ContactLineEdit( true, parent );
144  } else {
145  edit = new ContactLineEdit( false, parent );
146  }
147 
148  connect( edit, SIGNAL(completed(QWidget*)), SLOT(completed(QWidget*)) );
149 
150  return edit;
151  } else {
152  if ( index.data( ContactGroupModel::IsReferenceRole ).toBool() ) {
153  KComboBox *comboBox = new KComboBox( parent );
154  comboBox->setFrame( false );
155  comboBox->setAutoFillBackground( true );
156  return comboBox;
157  } else {
158  KLineEdit *lineEdit = new KLineEdit( parent );
159  lineEdit->setFrame( false );
160  return lineEdit;
161  }
162  }
163 }
164 
165 void ContactGroupEditorDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
166 {
167  if ( index.data( ContactGroupModel::IsReferenceRole ).toBool() ) {
168  if ( index.column() == 0 ) {
169  KLineEdit *lineEdit = qobject_cast<KLineEdit*>( editor );
170  if ( !lineEdit ) {
171  return;
172  }
173 
174  lineEdit->setText( index.data( Qt::EditRole ).toString() );
175  } else {
176  KComboBox *comboBox = qobject_cast<KComboBox*>( editor );
177  if ( !comboBox ) {
178  return;
179  }
180 
181  const QStringList emails = index.data( ContactGroupModel::AllEmailsRole ).toStringList();
182  comboBox->clear();
183  comboBox->addItems( emails );
184  comboBox->setCurrentIndex( comboBox->findText( index.data( Qt::EditRole ).toString() ) );
185  }
186  } else {
187  KLineEdit *lineEdit = qobject_cast<KLineEdit*>( editor );
188  if ( !lineEdit ) {
189  return;
190  }
191 
192  lineEdit->setText( index.data( Qt::EditRole ).toString() );
193  }
194 }
195 
196 void ContactGroupEditorDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
197 {
198  if ( index.data( ContactGroupModel::IsReferenceRole ).toBool() ) {
199  if ( index.column() == 0 ) {
200  ContactLineEdit *lineEdit = static_cast<ContactLineEdit*>( editor );
201 
202  const bool isReference = lineEdit->isReference();
203  const Item item = lineEdit->completedItem();
204  model->setData( index, isReference, ContactGroupModel::IsReferenceRole );
205  if ( isReference ) {
206  if ( item.isValid() ) {
207  model->setData( index, item.id(), Qt::EditRole );
208  }
209  } else {
210  model->setData( index, lineEdit->text(), Qt::EditRole );
211  }
212  }
213 
214  if ( index.column() == 1 ) {
215  KComboBox *comboBox = qobject_cast<KComboBox*>( editor );
216  if ( !comboBox ) {
217  return;
218  }
219 
220  model->setData( index, comboBox->currentText(), Qt::EditRole );
221  }
222  } else {
223  if ( index.column() == 0 ) {
224  ContactLineEdit *lineEdit = static_cast<ContactLineEdit*>( editor );
225 
226  const bool isReference = lineEdit->isReference();
227  const Item item = lineEdit->completedItem();
228  model->setData( index, isReference, ContactGroupModel::IsReferenceRole );
229  if ( isReference ) {
230  if ( item.isValid() ) {
231  model->setData( index, item.id(), Qt::EditRole );
232  }
233  } else
234  model->setData( index, lineEdit->text(), Qt::EditRole );
235  }
236 
237  if ( index.column() == 1 ) {
238  KLineEdit *lineEdit = qobject_cast<KLineEdit*>( editor );
239  if ( !lineEdit ) {
240  return;
241  }
242 
243  model->setData( index, lineEdit->text(), Qt::EditRole );
244  }
245  }
246 }
247 
248 static bool isLastRow( const QModelIndex &index )
249 {
250  return ( index.row() == ( index.model()->rowCount() - 1 ) );
251 }
252 
253 void ContactGroupEditorDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
254 {
255  QStyledItemDelegate::paint( painter, option, index );
256 
257  if ( index.column() == 1 && !isLastRow( index ) ) {
258  d->mIcon.paint( painter, option.rect, Qt::AlignRight );
259  }
260 }
261 
262 QSize ContactGroupEditorDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
263 {
264  Q_UNUSED( option );
265 
266  QSize hint = QStyledItemDelegate::sizeHint( option, index );
267  hint.setHeight( qMax( hint.height(), d->mButtonSize.height() ) );
268 
269  if ( index.column() == 1 ) {
270  hint.setWidth( hint.width() + d->mButtonSize.width() );
271  }
272 
273  return hint;
274 }
275 
276 bool ContactGroupEditorDelegate::editorEvent( QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index )
277 {
278  if ( index.column() == 1 && !isLastRow( index ) ) {
279  if ( event->type() == QEvent::MouseButtonRelease ) {
280  const QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event );
281  QRect buttonRect = d->mItemView->visualRect( index );
282  buttonRect.setLeft( buttonRect.right() - d->mButtonSize.width() );
283 
284  if ( buttonRect.contains( mouseEvent->pos() ) ) {
285  model->removeRows( index.row(), 1 );
286  QTimer::singleShot( 0, this, SLOT(setFirstColumnAsCurrent()) );
287  return true;
288  }
289  }
290  }
291  return QStyledItemDelegate::editorEvent( event, model, option, index );
292 }
293 
294 void ContactGroupEditorDelegate::completed( QWidget *widget )
295 {
296  emit commitData( widget );
297  emit closeEditor( widget );
298 }
299 
300 void ContactGroupEditorDelegate::setFirstColumnAsCurrent()
301 {
302  d->mItemView->setCurrentIndex( d->mItemView->model()->index( d->mItemView->currentIndex().row(), 0 ) );
303 }
304 
305 #include "moc_contactgroupeditordelegate_p.cpp"
Akonadi::EntityTreeModel::ItemRole
The Item.
Definition: entitytreemodel.h:331
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:00:27 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

Skip menu "akonadi"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Modules
  • Related Pages

kdepimlibs API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kldap
  • kmbox
  • kmime
  • kpimidentities
  • kpimtextedit
  • kresources
  • ktnef
  • kxmlrpcclient
  • microblog

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal