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

akonadi

  • 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 <klocale.h>
31 
32 #include <QtCore/QTimer>
33 #include <QtGui/QAbstractItemView>
34 #include <QtGui/QCompleter>
35 #include <QtGui/QMouseEvent>
36 #include <QtGui/QSortFilterProxyModel>
37 #include <QtGui/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  return !index.data().toString().isEmpty();
62  }
63 };
64 
65 ContactLineEdit::ContactLineEdit( bool isReference, QWidget *parent )
66  : KLineEdit( parent ), mIsReference( isReference )
67 {
68  setFrame( false );
69 
70  ContactsWithEmailFilterModel *filter = new ContactsWithEmailFilterModel( this );
71  filter->setSourceModel( Akonadi::ContactCompletionModel::self() );
72 
73  QCompleter *completer = new QCompleter( filter, this );
74  completer->setCompletionColumn( Akonadi::ContactCompletionModel::NameColumn );
75  completer->setCaseSensitivity( Qt::CaseInsensitive );
76  connect( completer, SIGNAL(activated(QModelIndex)), SLOT(completed(QModelIndex)) );
77 
78  setCompleter( completer );
79 
80  connect( this, SIGNAL(textEdited(QString)), SLOT(slotTextEdited()) );
81 }
82 
83 bool ContactLineEdit::isReference() const
84 {
85  return mIsReference;
86 }
87 
88 Akonadi::Item ContactLineEdit::completedItem() const
89 {
90  return mItem;
91 }
92 
93 void ContactLineEdit::completed( const QModelIndex &index )
94 {
95  if ( index.isValid() ) {
96  mItem = index.data( Akonadi::EntityTreeModel::ItemRole ).value<Akonadi::Item>();
97  mIsReference = true;
98  } else {
99  mItem = Item();
100  mIsReference = false;
101  }
102 
103  emit completed( this );
104 }
105 
106 void ContactLineEdit::slotTextEdited()
107 {
108  // if the user has edited the text, we break up the reference
109  mIsReference = false;
110 }
111 
112 class ContactGroupEditorDelegate::Private
113 {
114  public:
115  Private()
116  : mButtonSize( 16, 16 ), mIcon( QLatin1String( "list-remove" ) )
117  {
118  }
119 
120  QSize mButtonSize;
121  const KIcon mIcon;
122  QAbstractItemView *mItemView;
123 };
124 
125 ContactGroupEditorDelegate::ContactGroupEditorDelegate( QAbstractItemView *view, QObject *parent )
126  : QStyledItemDelegate( parent ), d( new Private )
127 {
128  d->mItemView = view;
129 }
130 
131 ContactGroupEditorDelegate::~ContactGroupEditorDelegate()
132 {
133  delete d;
134 }
135 
136 QWidget* ContactGroupEditorDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem&,
137  const QModelIndex &index ) const
138 {
139  if ( index.column() == 0 ) {
140  ContactLineEdit *edit = 0;
141  if ( index.data( ContactGroupModel::IsReferenceRole ).toBool() ) {
142  edit = new ContactLineEdit( true, parent );
143  } else {
144  edit = new ContactLineEdit( false, parent );
145  }
146 
147  connect( edit, SIGNAL(completed(QWidget*)), SLOT(completed(QWidget*)) );
148 
149  return edit;
150  } else {
151  if ( index.data( ContactGroupModel::IsReferenceRole ).toBool() ) {
152  KComboBox *comboBox = new KComboBox( parent );
153  comboBox->setFrame( false );
154  comboBox->setAutoFillBackground( true );
155  return comboBox;
156  } else {
157  KLineEdit *lineEdit = new KLineEdit( parent );
158  lineEdit->setFrame( false );
159  return lineEdit;
160  }
161  }
162 }
163 
164 void ContactGroupEditorDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
165 {
166  if ( index.data( ContactGroupModel::IsReferenceRole ).toBool() ) {
167  if ( index.column() == 0 ) {
168  KLineEdit *lineEdit = qobject_cast<KLineEdit*>( editor );
169  if ( !lineEdit )
170  return;
171 
172  lineEdit->setText( index.data( Qt::EditRole ).toString() );
173  } else {
174  KComboBox *comboBox = qobject_cast<KComboBox*>( editor );
175  if ( !comboBox )
176  return;
177 
178  const QStringList emails = index.data( ContactGroupModel::AllEmailsRole ).toStringList();
179  comboBox->clear();
180  comboBox->addItems( emails );
181  comboBox->setCurrentIndex( comboBox->findText( index.data( Qt::EditRole ).toString() ) );
182  }
183  } else {
184  if ( index.column() == 0 ) {
185 
186  KLineEdit *lineEdit = qobject_cast<KLineEdit*>( editor );
187  if ( !lineEdit )
188  return;
189 
190  lineEdit->setText( index.data( Qt::EditRole ).toString() );
191 
192  } else {
193  KLineEdit *lineEdit = qobject_cast<KLineEdit*>( editor );
194  if ( !lineEdit )
195  return;
196 
197  lineEdit->setText( index.data( Qt::EditRole ).toString() );
198  }
199  }
200 }
201 
202 void ContactGroupEditorDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
203 {
204  if ( index.data( ContactGroupModel::IsReferenceRole ).toBool() ) {
205  if ( index.column() == 0 ) {
206  ContactLineEdit *lineEdit = static_cast<ContactLineEdit*>( editor );
207 
208  const bool isReference = lineEdit->isReference();
209  const Item item = lineEdit->completedItem();
210  model->setData( index, isReference, ContactGroupModel::IsReferenceRole );
211  if ( isReference ) {
212  if ( item.isValid() )
213  model->setData( index, item.id(), Qt::EditRole );
214  } else
215  model->setData( index, lineEdit->text(), Qt::EditRole );
216  }
217 
218  if ( index.column() == 1 ) {
219  KComboBox *comboBox = qobject_cast<KComboBox*>( editor );
220  if ( !comboBox )
221  return;
222 
223  model->setData( index, comboBox->currentText(), Qt::EditRole );
224  }
225  } else {
226  if ( index.column() == 0 ) {
227  ContactLineEdit *lineEdit = static_cast<ContactLineEdit*>( editor );
228 
229  const bool isReference = lineEdit->isReference();
230  const Item item = lineEdit->completedItem();
231  model->setData( index, isReference, ContactGroupModel::IsReferenceRole );
232  if ( isReference ) {
233  if ( item.isValid() )
234  model->setData( index, item.id(), Qt::EditRole );
235  } else
236  model->setData( index, lineEdit->text(), Qt::EditRole );
237  }
238 
239  if ( index.column() == 1 ) {
240  KLineEdit *lineEdit = qobject_cast<KLineEdit*>( editor );
241  if ( !lineEdit )
242  return;
243 
244  model->setData( index, lineEdit->text(), Qt::EditRole );
245  }
246  }
247 }
248 
249 static bool isLastRow( const QModelIndex &index )
250 {
251  return (index.row() == (index.model()->rowCount() - 1));
252 }
253 
254 void ContactGroupEditorDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
255 {
256  QStyledItemDelegate::paint( painter, option, index );
257 
258  if ( index.column() == 1 && !isLastRow( index ) )
259  d->mIcon.paint( painter, option.rect, Qt::AlignRight );
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  return hint;
273 }
274 
275 bool ContactGroupEditorDelegate::editorEvent( QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index )
276 {
277  if ( index.column() == 1 && !isLastRow( index ) ) {
278  if ( event->type() == QEvent::MouseButtonRelease ) {
279  const QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event );
280  QRect buttonRect = d->mItemView->visualRect( index );
281  buttonRect.setLeft( buttonRect.right() - d->mButtonSize.width() );
282 
283  if ( buttonRect.contains( mouseEvent->pos() ) ) {
284  model->removeRows( index.row(), 1 );
285  QTimer::singleShot( 0, this, SLOT(setFirstColumnAsCurrent()) );
286  return true;
287  }
288  }
289  }
290  return QStyledItemDelegate::editorEvent( event, model, option, index );
291 }
292 
293 void ContactGroupEditorDelegate::completed( QWidget *widget )
294 {
295  emit commitData( widget );
296  emit closeEditor( widget );
297 }
298 
299 void ContactGroupEditorDelegate::setFirstColumnAsCurrent()
300 {
301  d->mItemView->setCurrentIndex( d->mItemView->model()->index( d->mItemView->currentIndex().row(), 0 ) );
302 }
303 
304 #include "contactgroupeditordelegate_p.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Tue Dec 4 2012 14:36:04 by doxygen 1.8.1.2 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-4.9.4 API Reference

Skip menu "kdepimlibs-4.9.4 API Reference"
  • 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
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