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

kopete/kopete

  • sources
  • kde-4.14
  • kdenetwork
  • kopete
  • kopete
  • contactlist
kopetecontactlistview.cpp
Go to the documentation of this file.
1 /*
2  Kopete Contact List View
3 
4  Copyright (c) 2001-2002 by Duncan Mac-Vicar Prett <duncan@kde.org>
5  Copyright (c) 2002 by Nick Betcher <nbetcher@usinternet.com>
6  Copyright (c) 2002 by Stefan Gehn <metz@gehn.net>
7  Copyright (c) 2002-2005 by Olivier Goffart <ogoffart@kde.org>
8  Copyright (c) 2002-2003 by Martijn Klingens <klingens@kde.org>
9  Copyright (c) 2004 by Richard Smith <kde@metafoo.co.uk>
10  Copyright 2007 by Matt Rogers <mattr@kde.org>
11  Copyright 2009 by Roman Jarosz <kedgedev@gmail.com>
12 
13  Kopete (c) 2002-2009 by the Kopete developers <kopete-devel@kde.org>
14 
15  *************************************************************************
16  * *
17  * This program is free software; you can redistribute it and/or modify *
18  * it under the terms of the GNU General Public License as published by *
19  * the Free Software Foundation; either version 2 of the License, or *
20  * (at your option) any later version. *
21  * *
22  *************************************************************************
23 */
24 
25 #include "kopetecontactlistview.h"
26 
27 #include <QHeaderView>
28 #include <QScrollBar>
29 
30 #include <KDebug>
31 #include <KIcon>
32 #include <KMenu>
33 #include <KStandardAction>
34 #include <KActionMenu>
35 #include <KActionCollection>
36 #include <KXmlGuiWindow>
37 #include <KLocalizedString>
38 #include <KInputDialog>
39 #include <KMessageBox>
40 #include <KToolInvocation>
41 #include <kxmlguifactory.h>
42 #include <kabc/stdaddressbook.h>
43 
44 #include "kopeteuiglobal.h"
45 #include "kopetecontactlistelement.h"
46 #include "kopetemetacontact.h"
47 #include "kopeteaccountmanager.h"
48 #include "kopetecontact.h"
49 #include "kopetegroup.h"
50 #include "kopetecontactlist.h"
51 #include "kopetestdaction.h"
52 #include "kopetegrouplistaction.h"
53 #include "kopetelviprops.h"
54 #include "contactlistlayoutmanager.h"
55 #include "kopeteaccount.h"
56 #include "addcontactpage.h"
57 #include "kopeteappearancesettings.h"
58 #include "kopetebehaviorsettings.h"
59 
60 #include "contactlistmodel.h"
61 #include "kopeteitembase.h"
62 #include "kopeteitemdelegate.h"
63 
64 class KopeteContactListViewPrivate
65 {
66 public:
67  KopeteContactListViewPrivate()
68  : controlPressed( false ),
69  scrollAutoHideTimer(0),
70  scrollAutoHideCounter(10),
71  scrollAutoHideTimeout(10),
72  scrollAutoHide(false),
73  scrollHide(false)
74  {}
75  //QRect m_onItem;
76 
77  // HACK: Used to update the KMEnu title - DarkShock
78  QMap<KMenu*, QAction*> menuTitleMap;
79 
80  /* ACTIONS */
81  KAction *actionSendMessage;
82  KAction *actionStartChat;
83  KAction *actionSendFile;
84  KActionMenu *actionAddContact;
85  KAction *actionSendEmail;
86  KSelectAction *actionMove;
87  KSelectAction *actionCopy;
88  KAction *actionRename;
89  KAction *actionRemove;
90  KAction *actionAddTemporaryContact;
91  KAction *actionProperties;
92  KAction *actionUndo;
93  KAction *actionRedo;
94  KAction *actionMakeMetaContact;
95 
96  QMap<KAction*, Kopete::Account*> addContactAccountMap;
97  QPointer<Kopete::MetaContact> selectedMetaContact;
98 
99  QPointer<Kopete::Contact> pressedContact;
100  bool controlPressed;
101 
103  int scrollAutoHideTimer;
105  int scrollAutoHideCounter;
107  int scrollAutoHideTimeout;
109  bool scrollAutoHide;
111  bool scrollHide;
112 };
113 
114 KopeteContactListView::KopeteContactListView( QWidget *parent )
115 : QTreeView( parent ), d( new KopeteContactListViewPrivate() )
116 {
117  header()->hide();
118 
119  setSelectionMode( QAbstractItemView::ExtendedSelection );
120  setDragEnabled( true );
121  setDragDropMode( QAbstractItemView::DragDrop );
122  setAcceptDrops( true );
123  setAlternatingRowColors( true );
124  setAnimated( true );
125  setDropIndicatorShown( true );
126  setItemDelegate( new KopeteItemDelegate( this ) );
127  setExpandsOnDoubleClick( true );
128  setEditTriggers(QAbstractItemView::EditKeyPressed);
129 
130  connect( this, SIGNAL(activated(QModelIndex)),
131  this, SLOT(contactActivated(QModelIndex)));
132  connect( this, SIGNAL(expanded(QModelIndex)),
133  this, SLOT(itemExpanded(QModelIndex)));
134  connect( this, SIGNAL(collapsed(QModelIndex)),
135  this, SLOT(itemCollapsed(QModelIndex)));
136  connect( ContactList::LayoutManager::instance(), SIGNAL(activeLayoutChanged()),
137  this, SLOT(reset()) );
138  connect( Kopete::BehaviorSettings::self(), SIGNAL(configChanged()), SLOT(slotSettingsChanged()) );
139  connect( Kopete::AppearanceSettings::self(), SIGNAL(configChanged()), SLOT(slotSettingsChanged()) );
140 
141  setEditTriggers( NoEditTriggers );
142  // Load in the user's initial settings
143  slotSettingsChanged();
144 }
145 
146 KopeteContactListView::~KopeteContactListView()
147 {
148  delete d;
149 }
150 
151 void KopeteContactListView::initActions( KActionCollection *ac )
152 {
153 // d->actionUndo = KStandardAction::undo( this , SLOT(slotUndo()) , ac );
154 // d->actionRedo = KStandardAction::redo( this , SLOT(slotRedo()) , ac );
155 // d->actionUndo->setEnabled(false);
156 // d->actionRedo->setEnabled(false);
157 
158 
159  KAction *actionCreateNewGroup = new KAction( i18n( "Create New Group..." ), ac );
160  actionCreateNewGroup->setIcon( KIcon( "user-group-new" ) );
161  connect( actionCreateNewGroup, SIGNAL(triggered(bool)), this, SLOT(addGroup()) );
162  ac->addAction( "AddGroup", actionCreateNewGroup );
163 
164  d->actionSendMessage = KopeteStdAction::sendMessage( this, SLOT(sendMessage()), ac );
165  ac->addAction( "contactSendMessage", d->actionSendMessage );
166  d->actionStartChat = KopeteStdAction::chat( this, SLOT(startChat()), ac );
167  ac->addAction( "contactStartChat", d->actionStartChat );
168 
169  d->actionMove = new KopeteGroupListAction( i18n( "&Move To" ), QLatin1String( "edit-cut" ),
170  KShortcut(), this, SLOT(moveToGroup()), ac );
171  ac->addAction( "contactMove", d->actionMove );
172  d->actionCopy = new KopeteGroupListAction( i18n( "&Copy To" ), QLatin1String( "edit-copy" ),
173  KShortcut(), this, SLOT(copyToGroup()), ac );
174  ac->addAction( "contactCopy", d->actionCopy );
175 
176  d->actionMakeMetaContact = new KAction(KIcon("list-add-user"), i18n("Merge Meta Contacts"), ac);
177  ac->addAction( "makeMetaContact", d->actionMakeMetaContact );
178  connect (d->actionMakeMetaContact, SIGNAL(triggered(bool)), this, SLOT(mergeMetaContact()));
179 
180  d->actionRemove = KopeteStdAction::deleteContact( this, SLOT(removeGroupOrMetaContact()), ac );
181  ac->addAction( "contactRemove", d->actionRemove );
182 
183  d->actionSendEmail = new KAction( KIcon("mail-send"), i18n( "Send Email..." ), ac );
184  ac->addAction( "contactSendEmail", d->actionSendEmail );
185  connect( d->actionSendEmail, SIGNAL(triggered(bool)), this, SLOT(sendEmail()) );
186 
187  d->actionRename = new KAction( KIcon("edit-rename"), i18nc( "verb, rename a contact", "Rename" ), ac );
188  d->actionRename->setShortcut( KShortcut(Qt::Key_F2) );
189  ac->addAction( "contactRename", d->actionRename );
190  connect( d->actionRename, SIGNAL(triggered(bool)), this, SLOT(rename()) );
191 
192  d->actionSendFile = KopeteStdAction::sendFile( this, SLOT(sendFile()), ac );
193  ac->addAction( "contactSendFile", d->actionSendFile );
194 
195  d->actionAddContact = new KActionMenu( KIcon( QLatin1String("list-add-user") ), i18n( "&Add Contact" ), ac );
196  ac->addAction( "contactAddContact", d->actionAddContact );
197  d->actionAddContact->menu()->addTitle( i18n("Select Account") );
198 
199  d->actionAddTemporaryContact = new KAction( KIcon("list-add-user"), i18n( "Add to Your Contact List" ), ac );
200  ac->addAction( "contactAddTemporaryContact", d->actionAddTemporaryContact );
201  connect( d->actionAddTemporaryContact, SIGNAL(triggered(bool)), this, SLOT(addTemporaryContact()) );
202 
203 // connect( Kopete::ContactList::self(), SIGNAL(metaContactSelected(bool)), this, SLOT(slotMetaContactSelected(bool)) );
204 
205  connect( Kopete::AccountManager::self(), SIGNAL(accountRegistered(Kopete::Account*)),
206  this, SLOT(addToAddContactMenu(Kopete::Account*)) );
207  connect( Kopete::AccountManager::self(), SIGNAL(accountUnregistered(const Kopete::Account*)),
208  this, SLOT(removeToAddContactMenu(const Kopete::Account*)) );
209 
210  d->actionProperties = new KAction( KIcon("user-properties"), i18n( "&Properties" ), ac );
211  ac->addAction( "contactProperties", d->actionProperties );
212  d->actionProperties->setShortcut( KShortcut(Qt::Key_Alt + Qt::Key_Return) );
213  connect( d->actionProperties, SIGNAL(triggered(bool)), this, SLOT(showItemProperties()) );
214 
215  // Update enabled/disabled actions
216  // slotViewSelectionChanged();
217 }
218 
219 Kopete::MetaContact* KopeteContactListView::metaContactFromIndex( const QModelIndex& index ) const
220 {
221  QObject* metaContactObject = qVariantValue<QObject*>( index.data( Kopete::Items::ObjectRole ) );
222  return qobject_cast<Kopete::MetaContact*>(metaContactObject);
223 }
224 
225 Kopete::Group* KopeteContactListView::groupFromIndex( const QModelIndex& index ) const
226 {
227  QObject* groupObject = qVariantValue<QObject*>( index.data( Kopete::Items::ObjectRole ) );
228  return qobject_cast<Kopete::Group*>(groupObject);
229 }
230 
231 void KopeteContactListView::contactActivated( const QModelIndex& index )
232 {
233  QVariant v = index.data( Kopete::Items::ElementRole );
234  if ( index.data( Kopete::Items::TypeRole ) == Kopete::Items::MetaContact )
235  {
236  if ( !d->controlPressed )
237  {
238  if ( d->pressedContact )
239  {
240  d->pressedContact->execute();
241  }
242  else
243  {
244  Kopete::MetaContact* mc = metaContactFromIndex( index );
245  if ( mc )
246  mc->execute();
247  }
248  }
249  }
250 
251 
252 }
253 
254 void KopeteContactListView::setModel( QAbstractItemModel *newModel )
255 {
256  if ( model() )
257  {
258  disconnect( model(), SIGNAL(layoutChanged()), this, SLOT(reexpandGroups()) );
259  disconnect( model(), SIGNAL(layoutChanged()), this, SIGNAL(visibleContentHeightChanged()) );
260  }
261 
262  QTreeView::setModel( newModel );
263 
264  // TODO: This is not the best approach as this is emitted often, find a better way.
265  connect( newModel, SIGNAL(layoutChanged()), this, SLOT(reexpandGroups()) );
266  connect( newModel, SIGNAL(layoutChanged()), this, SIGNAL(visibleContentHeightChanged()) );
267 }
268 
269 int KopeteContactListView::visibleContentHeight() const
270 {
271  QModelIndex parent = rootIndex();
272 
273  int height = 0;
274  int rows = model()->rowCount( parent );
275  for ( int i = 0; i < rows; ++i )
276  height += visibleContentHeight( model()->index( i, 0, parent ) );
277 
278  return height;
279 }
280 
281 void KopeteContactListView::keyboardSearch( const QString &search )
282 {
283  // FIXME: Why QTreeView::keyboardSearch updates selection only when selectionMode is SingleSelection?
284  setSelectionMode( QAbstractItemView::SingleSelection );
285  QTreeView::keyboardSearch( search );
286  setSelectionMode( QAbstractItemView::ExtendedSelection );
287 }
288 
289 void KopeteContactListView::reset()
290 {
291  QTreeView::reset();
292 
293  if ( Kopete::AppearanceSettings::self()->groupContactByGroup() )
294  setRootIndex( model()->index( 0, 0 ) );
295 
296  reexpandGroups();
297  emit visibleContentHeightChanged();
298 }
299 
300 void KopeteContactListView::showItemProperties()
301 {
302  QModelIndex index = currentIndex();
303  if ( !index.isValid() )
304  return;
305 
306  if ( index.data( Kopete::Items::TypeRole ) == Kopete::Items::MetaContact )
307  {
308  QPointer <KopeteMetaLVIProps> propsDialog = new KopeteMetaLVIProps( metaContactFromIndex( index ), 0L );
309  propsDialog->exec(); // modal
310  delete propsDialog;
311  }
312  else if ( index.data( Kopete::Items::TypeRole ) == Kopete::Items::Group )
313  {
314  QPointer <KopeteGVIProps> propsDialog = new KopeteGVIProps( groupFromIndex( index ), 0L );
315  propsDialog->exec(); // modal
316  delete propsDialog;
317  }
318 }
319 
320 void KopeteContactListView::mergeMetaContact()
321 {
322  Kopete::MetaContact* destMetaContact = metaContactFromIndex( currentIndex() );
323  if ( !destMetaContact )
324  return;
325 
326  // Get metaContacts as indexes could change during merge.
327  QList<Kopete::MetaContact *> metaContactList;
328  foreach ( QModelIndex index, selectedIndexes() )
329  {
330  Kopete::MetaContact* mc = metaContactFromIndex( index );
331  if ( mc && mc != destMetaContact )
332  metaContactList.append( mc );
333  }
334 
335  if ( metaContactList.isEmpty() )
336  return;
337 
338  Kopete::ContactList::self()->mergeMetaContacts( metaContactList, destMetaContact );
339 }
340 
341 void KopeteContactListView::addGroup()
342 {
343  QString groupName = KInputDialog::getText( i18n( "New Group" ),
344  i18n( "Please enter the name for the new group:" ) );
345 
346  if ( !groupName.isEmpty() )
347  Kopete::ContactList::self()->findGroup( groupName );
348 }
349 
350 void KopeteContactListView::removeGroupOrMetaContact()
351 {
352  QList<Kopete::MetaContact *> metaContactList;
353  QList<Kopete::Group *> groupList;
354  QStringList displayNameList;
355 
356  foreach ( const QModelIndex& index, selectedIndexes() )
357  {
358  if ( Kopete::MetaContact* metaContact = metaContactFromIndex( index ) )
359  {
360  metaContactList.append( metaContact );
361 
362  if( !metaContact->displayName().isEmpty() )
363  displayNameList.append( metaContact->displayName() );
364  }
365  else if ( Kopete::Group* group = groupFromIndex( index ) )
366  {
367  // Can't remove topLevel group
368  if ( group == Kopete::Group::topLevel() )
369  continue;
370 
371  // Can't remove the offline group
372  if ( group == Kopete::Group::offline() )
373  continue;
374 
375  groupList.append( group );
376 
377  if( !group->displayName().isEmpty() )
378  displayNameList.append( group->displayName() );
379  }
380  }
381 
382  if ( groupList.isEmpty() && metaContactList.isEmpty() )
383  return;
384 
385  if( (groupList.count() + metaContactList.count()) == 1 )
386  {
387  QString msg;
388  if( !metaContactList.isEmpty() )
389  {
390  msg = i18n( "<qt>Are you sure you want to remove the contact <b>%1</b>" \
391  " from your contact list?</qt>" ,
392  metaContactList.first()->displayName() ) ;
393  }
394  else if( !groupList.isEmpty() )
395  {
396  msg = i18n( "<qt>Are you sure you want to remove the group <b>%1</b> " \
397  "and all contacts that are contained within it?</qt>" ,
398  groupList.first()->displayName() );
399  }
400 
401  if( KMessageBox::warningContinueCancel( this, msg, i18n( "Remove" ), KGuiItem( i18n( "Remove" ), "edit-delete" ),
402  KStandardGuiItem::cancel(), "askRemovingContactOrGroup" ,
403  KMessageBox::Notify | KMessageBox::Dangerous ) != KMessageBox::Continue )
404  {
405  return;
406  }
407  }
408  else
409  {
410  QString msg = groupList.isEmpty() ?
411  i18n( "Are you sure you want to remove these contacts " \
412  "from your contact list?" ) :
413  i18n( "Are you sure you want to remove these groups and " \
414  "contacts from your contact list?" );
415 
416  if( KMessageBox::warningContinueCancelList( this, msg, displayNameList, i18n("Remove"), KGuiItem( i18n( "Remove" ), "edit-delete" ),
417  KStandardGuiItem::cancel(), "askRemovingContactOrGroup",
418  KMessageBox::Notify | KMessageBox::Dangerous ) != KMessageBox::Continue )
419  {
420  return;
421  }
422  }
423 
424  foreach ( Kopete::MetaContact* metaContact, metaContactList )
425  Kopete::ContactList::self()->removeMetaContact( metaContact );
426 
427  foreach ( Kopete::Group* group, groupList )
428  Kopete::ContactList::self()->removeGroup( group );
429 }
430 
431 void KopeteContactListView::moveToGroup()
432 {
433  Q_ASSERT(model());
434  QModelIndexList indexList = selectedIndexes();
435  if ( indexList.count() != 1 )
436  return;
437 
438  QModelIndex index = indexList.first();
439  if ( index.data( Kopete::Items::TypeRole ) == Kopete::Items::MetaContact && d->actionMove->currentAction() )
440  {
441  Kopete::MetaContact* metaContact = metaContactFromIndex( index );
442  foreach( Kopete::Contact *c, metaContact->contacts() )
443  {
444  if ( !c->account()->isConnected() )
445  { // Some accounts are offline we can't move it
446  const QString msg = i18n( "Account %1 is offline. Do you really want to move this metacontact?", c->account()->accountLabel() );
447  if ( KMessageBox::warningYesNo( this, msg, i18n( "Move contact" ), KStandardGuiItem::yes(), KStandardGuiItem::no(),
448  "askMoveMetaContactToGroup", KMessageBox::Notify | KMessageBox::Dangerous ) == KMessageBox::No )
449  return;
450  }
451  }
452 
453  bool ok = false;
454  uint groupId = d->actionMove->currentAction()->data().toUInt( &ok );
455  if ( !ok )
456  return;
457 
458  Kopete::Group *toGroup = Kopete::ContactList::self()->group( groupId );
459  if ( !toGroup )
460  return;
461 
462  QObject* groupObject = qVariantValue<QObject*>( index.data( Kopete::Items::MetaContactGroupRole ) );
463  Kopete::Group* fromGroup = qobject_cast<Kopete::Group*>(groupObject);
464 
465  // Can't move to the offline group manually
466  if ( toGroup == Kopete::Group::offline() )
467  return;
468 
469  metaContact->moveToGroup( fromGroup, toGroup );
470  }
471 }
472 
473 void KopeteContactListView::copyToGroup()
474 {
475  Q_ASSERT(model());
476  QModelIndexList indexList = selectedIndexes();
477  if ( indexList.count() != 1 )
478  return;
479 
480  QModelIndex index = indexList.first();
481  if ( index.data( Kopete::Items::TypeRole ) == Kopete::Items::MetaContact && d->actionCopy->currentAction() )
482  {
483  Kopete::MetaContact* metaContact = metaContactFromIndex( index );
484  foreach( Kopete::Contact *c, metaContact->contacts() )
485  {
486  if ( !c->account()->isConnected() )
487  return; // Some contact is offline we can't copy it
488  }
489 
490  bool ok = false;
491  uint groupId = d->actionCopy->currentAction()->data().toUInt( &ok );
492  if ( !ok )
493  return;
494 
495  Kopete::Group *toGroup = Kopete::ContactList::self()->group( groupId );
496  if ( !toGroup )
497  return;
498 
499  // Can't copy to the offline group manually
500  if ( toGroup == Kopete::Group::offline() )
501  return;
502 
503  metaContact->addToGroup( toGroup );
504  }
505 }
506 
507 void KopeteContactListView::startChat()
508 {
509  Kopete::MetaContact* metaContact = metaContactFromIndex( currentIndex() );
510  if ( metaContact )
511  metaContact->startChat();
512 }
513 
514 void KopeteContactListView::sendFile()
515 {
516  Kopete::MetaContact* metaContact = metaContactFromIndex( currentIndex() );
517  if ( metaContact )
518  metaContact->sendFile( KUrl() );
519 }
520 
521 void KopeteContactListView::sendMessage()
522 {
523  if ( Kopete::MetaContact* metaContact = metaContactFromIndex( currentIndex() ) )
524  metaContact->sendMessage();
525  else if ( Kopete::Group* group = groupFromIndex( currentIndex() ) )
526  group->sendMessage();
527 }
528 
529 void KopeteContactListView::sendEmail()
530 {
531  Kopete::MetaContact* metaContact = metaContactFromIndex( currentIndex() );
532  if ( metaContact )
533  {
534  KABC::Addressee addressee = KABC::StdAddressBook::self()->findByUid( metaContact->kabcId() );
535  if ( !addressee.isEmpty() )
536  {
537  QString emailAddr = addressee.fullEmail();
538 
539  kDebug( 14000 ) << "Email: " << emailAddr << "!";
540  if ( !emailAddr.isEmpty() )
541  KToolInvocation::invokeMailer( emailAddr, QString::null ); //krazy:exclude=nullstrassign for old broken gcc
542  else
543  KMessageBox::queuedMessageBox( this, KMessageBox::Sorry, i18n( "There is no email address set for this contact in the KDE address book." ), i18n( "No Email Address in Address Book" ) );
544  }
545  else
546  {
547  KMessageBox::queuedMessageBox( this, KMessageBox::Sorry, i18n( "This contact was not found in the KDE address book. Check that a contact is selected in the properties dialog." ), i18n( "Not Found in Address Book" ) );
548  }
549  }
550 }
551 
552 void KopeteContactListView::rename()
553 {
554  Kopete::MetaContact* metaContact = metaContactFromIndex( currentIndex() );
555  if ( metaContact )
556  {
557  edit(currentIndex());
558  }
559 }
560 
561 void KopeteContactListView::addTemporaryContact()
562 {
563  Kopete::MetaContact* metaContact = metaContactFromIndex( currentIndex() );
564  if ( metaContact && metaContact->isTemporary() )
565  metaContact->setTemporary( false );
566 }
567 
568 void KopeteContactListView::contextMenuEvent( QContextMenuEvent* event )
569 {
570  Q_ASSERT(model());
571  QModelIndexList indexList = selectedIndexes();
572  if ( indexList.isEmpty() )
573  return;
574 
575  if ( indexList.count() > 1 )
576  {
577  miscPopup( indexList, event->globalPos() );
578  }
579  else
580  {
581  QModelIndex index = indexList.first();
582  if ( index.data( Kopete::Items::TypeRole ) == Kopete::Items::MetaContact )
583  {
584  Kopete::Contact* contact = contactAt( event->pos() );
585  if ( contact )
586  {
587  KMenu *menu = contact->popupMenu();
588  connect( menu, SIGNAL(aboutToHide()), menu, SLOT(deleteLater()) );
589  menu->popup( event->globalPos() );
590  }
591  else
592  {
593  metaContactPopup( metaContactFromIndex( index ), event->globalPos() );
594  }
595  }
596  else if ( index.data( Kopete::Items::TypeRole ) == Kopete::Items::Group )
597  groupPopup( groupFromIndex( index ), event->globalPos() );
598  }
599  event->accept();
600 }
601 
602 void KopeteContactListView::mouseReleaseEvent(QMouseEvent *event)
603 {
604  if ( (event->modifiers() & Qt::ControlModifier) == Qt::ControlModifier )
605  d->controlPressed = true;
606 
607  d->pressedContact = contactAt( event->pos() );
608 
609  QTreeView::mouseReleaseEvent( event );
610  d->pressedContact = 0;
611  d->controlPressed = false;
612 }
613 
614 void KopeteContactListView::startDrag( Qt::DropActions supportedActions )
615 {
616  QModelIndexList indexes = selectedIndexes();
617  for ( int i = indexes.count() - 1 ; i >= 0; --i )
618  {
619  if ( !(model()->flags( indexes.at(i) ) & Qt::ItemIsDragEnabled) )
620  indexes.removeAt(i);
621  }
622 
623  if (indexes.count() > 0)
624  {
625  QMimeData *data = model()->mimeData( indexes );
626  if ( !data )
627  return;
628 
629  QDrag *drag = new QDrag( this );
630  drag->setMimeData( data );
631 
632  Qt::DropAction defaultDropAction = Qt::MoveAction;
633  drag->exec( supportedActions, defaultDropAction );
634  }
635 }
636 
637 void KopeteContactListView::dragMoveEvent ( QDragMoveEvent * event )
638 {
639  const QMimeData *data = event->mimeData();
640 
641  QTreeView::dragMoveEvent ( event );
642  if ( !event->isAccepted() )
643  return;
644 
645  QModelIndex index;
646  switch ( dropIndicatorPosition() )
647  {
648  case QAbstractItemView::AboveItem:
649  case QAbstractItemView::BelowItem:
650  index = indexAt( event->pos() ).parent();
651  break;
652  case QAbstractItemView::OnItem:
653  index = indexAt( event->pos() );
654  break;
655  case QAbstractItemView::OnViewport:
656  index = rootIndex();
657  break;
658  default: // Should not happen
659  event->ignore();
660  return;
661  }
662 
663  Kopete::AppearanceSettings* as = Kopete::AppearanceSettings::self();
664  bool groupContactByGroup = as->groupContactByGroup();
665 
666  bool accept = false;
667  if ( data->hasFormat( "application/kopete.metacontacts.list" ) )
668  {
669  if ( index.data( Kopete::Items::TypeRole ) == Kopete::Items::MetaContact )
670  accept = (event->proposedAction() & Qt::MoveAction); // MetaContact merge (copy&merge not supported)
671  else if ( index.data( Kopete::Items::TypeRole ) == Kopete::Items::Group )
672  accept = (event->proposedAction() & (Qt::MoveAction | Qt::CopyAction)); // Move/copy between groups
673  else if ( !groupContactByGroup && !index.isValid() )
674  accept = (event->proposedAction() & Qt::MoveAction); // In plain view metaContact can only be moved
675  else
676  accept = false;
677  }
678  else if ( data->hasFormat( "application/kopete.group" ) )
679  {
680  if ( !groupContactByGroup )
681  accept = false; // Plain view doesn't support groups
682  else if ( !index.parent().isValid() )
683  accept = (event->proposedAction() & Qt::MoveAction); // In tree view groups can only be moved
684  else
685  accept = false;
686  }
687  else
688  accept = true; // Accept by default (e.g. urls)
689 
690  if ( !accept )
691  {
692  event->ignore();
693  return;
694  }
695 
696  event->acceptProposedAction();
697 }
698 
699 void KopeteContactListView::timerEvent( QTimerEvent *event )
700 {
701  QTreeView::timerEvent( event );
702 
703  if ( event->timerId() == d->scrollAutoHideTimer )
704  {
705  if ( !d->scrollAutoHideCounter-- )
706  setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
707  }
708 }
709 
710 bool KopeteContactListView::eventFilter( QObject *object, QEvent *event )
711 {
712  if ( d->scrollAutoHide && object == verticalScrollBar() )
713  {
714  if ( event->type() == QEvent::MouseMove )
715  d->scrollAutoHideCounter = 9999;
716  else if ( event->type() == QEvent::Enter )
717  d->scrollAutoHideCounter = 9999;
718  else if ( event->type() == QEvent::Leave )
719  d->scrollAutoHideCounter = d->scrollAutoHideTimeout;
720  }
721  else if ( d->scrollAutoHide && object == viewport() )
722  {
723  if ( event->type() == QEvent::MouseMove )
724  {
725  setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
726  d->scrollAutoHideCounter = 9999; // Mouse is on the contact list, so don't hide it
727  }
728  else if ( event->type() == QEvent::Leave )
729  {
730  d->scrollAutoHideCounter = d->scrollAutoHideTimeout; // Mouse left the contact list, hide it after timeout
731  }
732  }
733 
734  return QTreeView::eventFilter( object, event );
735 }
736 
737 bool KopeteContactListView::viewportEvent( QEvent *event )
738 {
739  // FIXME: Fix for crash, easily reproducible by assigning shortcut to show offline users action
740  // and holding down that action and moving mouse over contact list.
741  // Is this a Qt bug or are we using invalidate() in ContactListProxyModel wrongly?
742  // The same crash was in KTorrent bug 172198.
743  executeDelayedItemsLayout();
744  return QTreeView::viewportEvent( event );
745 }
746 
747 void KopeteContactListView::rowsInserted( const QModelIndex &parent, int start, int end )
748 {
749  QTreeView::rowsInserted( parent, start, end );
750 
751  const int delta = end - start + 1;
752  for (int i = 0; i < delta; ++i)
753  {
754  QModelIndex index = model()->index( i + start, 0, parent );
755  if ( index.isValid() && index.data( Kopete::Items::TypeRole ) == Kopete::Items::Group )
756  setExpanded( index , index.data( Kopete::Items::ExpandStateRole ).toBool() );
757  }
758 }
759 
760 void KopeteContactListView::selectionChanged( const QItemSelection& selected, const QItemSelection& deselected )
761 {
762  QTreeView::selectionChanged( selected, deselected );
763 
764  QSet<Kopete::MetaContact*> contacts;
765  QSet<Kopete::Group*> groups;
766 
767  foreach ( const QModelIndex& index, selected.indexes() )
768  {
769  if ( index.data( Kopete::Items::TypeRole ) == Kopete::Items::MetaContact )
770  contacts.insert( metaContactFromIndex( index ) );
771  else if ( index.data( Kopete::Items::TypeRole ) == Kopete::Items::Group )
772  groups.insert( groupFromIndex( index ) );
773  }
774 
775  Kopete::ContactList::self()->setSelectedItems( contacts.toList(), groups.toList() );
776 
777  updateActions();
778 
779  if ( d->selectedMetaContact )
780  { // Delete previous connection
781  disconnect( d->selectedMetaContact, SIGNAL(onlineStatusChanged(Kopete::MetaContact*,Kopete::OnlineStatus::StatusType)),
782  this, SLOT(updateMetaContactActions()) );
783  d->selectedMetaContact = 0;
784  }
785 
786  if ( contacts.count() == 1 && groups.empty() )
787  {
788  d->selectedMetaContact = contacts.values().first();
789  connect( d->selectedMetaContact, SIGNAL(onlineStatusChanged(Kopete::MetaContact*,Kopete::OnlineStatus::StatusType)),
790  this, SLOT(updateMetaContactActions()) );
791  }
792 
793  updateMetaContactActions();
794 }
795 
796 void KopeteContactListView::reexpandGroups()
797 {
798  // Set expanded state of groups
799  QModelIndex parent = rootIndex();
800  for (int i = 0; i < model()->rowCount( parent ); ++i)
801  {
802  QModelIndex index = model()->index( i, 0, parent );
803  if ( index.isValid() && index.data( Kopete::Items::TypeRole ) == Kopete::Items::Group )
804  setExpanded( index, model()->data( index, Kopete::Items::ExpandStateRole ).toBool() );
805  }
806 }
807 
808 void KopeteContactListView::itemExpanded( const QModelIndex& index )
809 {
810  Q_ASSERT(model());
811  if ( index.data( Kopete::Items::TypeRole ) == Kopete::Items::Group )
812  model()->setData( index, true, Kopete::Items::ExpandStateRole );
813 }
814 
815 void KopeteContactListView::itemCollapsed( const QModelIndex& index )
816 {
817  Q_ASSERT(model());
818  if ( index.data( Kopete::Items::TypeRole ) == Kopete::Items::Group )
819  model()->setData( index, false, Kopete::Items::ExpandStateRole );
820 }
821 
822 void KopeteContactListView::updateActions()
823 {
824  QModelIndexList selected = selectedIndexes();
825 
826  bool singleContactSelected = (selected.count() == 1 && selected.first().data( Kopete::Items::TypeRole ) == Kopete::Items::MetaContact);
827  bool singleGroupSelected = (selected.count() == 1 && selected.first().data( Kopete::Items::TypeRole ) == Kopete::Items::Group);
828  Kopete::MetaContact* metaContact = ( singleContactSelected ) ? metaContactFromIndex( selected.first() ) : 0;
829  Kopete::Group* group = ( singleGroupSelected ) ? groupFromIndex( selected.first() ) : 0;
830 
831  bool inkabc = false;
832  if ( singleContactSelected )
833  {
834  QString kabcid = metaContact->kabcId();
835  inkabc = !kabcid.isEmpty() && !kabcid.contains(":");
836  }
837  d->actionSendEmail->setEnabled( inkabc );
838 
839  if ( singleContactSelected )
840  {
841  d->actionRename->setText( i18n("Rename Contact") );
842  d->actionRemove->setText( i18n("Remove Contact") );
843  d->actionSendMessage->setText( i18n("Send Single Message...") );
844  d->actionRename->setEnabled( true );
845  d->actionRemove->setEnabled( true );
846  d->actionAddContact->setText( i18n("&Add Subcontact") );
847  d->actionAddContact->setEnabled( !metaContact->isTemporary() );
848  }
849  else if ( singleGroupSelected )
850  {
851  d->actionRename->setText( i18n("Rename Group") );
852  d->actionRemove->setText( i18n("Remove Group") );
853  d->actionSendMessage->setText( i18n("Send Message to Group") );
854  d->actionRename->setEnabled( true );
855  d->actionRemove->setEnabled( true );
856  d->actionSendMessage->setEnabled( true );
857  d->actionAddContact->setText( i18n("&Add Contact to Group") );
858  d->actionAddContact->setEnabled( group->type() == Kopete::Group::Normal );
859  }
860  else
861  {
862  d->actionRename->setText( i18n("Rename") );
863  d->actionRemove->setText( i18n("Remove") );
864  d->actionRename->setEnabled( false );
865  d->actionRemove->setEnabled( !selected.isEmpty() );
866  d->actionAddContact->setEnabled( false );
867  d->actionMakeMetaContact->setText( i18n("Make Meta Contact") );
868 
869  bool hasContactInSelection = false;
870  foreach ( const QModelIndex& index, selected )
871  {
872  if ( index.data( Kopete::Items::TypeRole ) == Kopete::Items::MetaContact )
873  {
874  hasContactInSelection = true;
875  break;
876  }
877  }
878  d->actionMakeMetaContact->setEnabled( hasContactInSelection ); // Specifically for multiple contacts, not groups.
879  }
880 
881  d->actionProperties->setEnabled( selected.count() == 1 );
882 }
883 
884 void KopeteContactListView::updateMetaContactActions()
885 {
886  bool reachable = false;
887 
888  if( d->selectedMetaContact )
889  {
890  reachable = d->selectedMetaContact->isReachable();
891  d->actionAddTemporaryContact->setEnabled( d->selectedMetaContact->isTemporary() );
892  d->actionSendFile->setEnabled( reachable && d->selectedMetaContact->canAcceptFiles() );
893  d->actionSendMessage->setEnabled( reachable );
894  d->actionStartChat->setEnabled( reachable );
895  }
896  else
897  {
898  QModelIndexList selected = selectedIndexes();
899  bool singleGroupSelected = (selected.count() == 1 && selected.first().data( Kopete::Items::TypeRole ) == Kopete::Items::Group);
900 
901  d->actionAddTemporaryContact->setEnabled( false );
902  d->actionSendFile->setEnabled( false );
903  d->actionSendMessage->setEnabled( singleGroupSelected );
904  d->actionStartChat->setEnabled( false );
905  }
906 
907 }
908 
909 void KopeteContactListView::slotSettingsChanged()
910 {
911  if ( Kopete::AppearanceSettings::self()->contactListTreeView() )
912  {
913  setRootIsDecorated( true );
914  setIndentation( 20 );
915  }
916  else
917  {
918  setRootIsDecorated( false );
919  setIndentation( Kopete::AppearanceSettings::self()->contactListIndentContact() ? 20 : 0 );
920  }
921 
922  if( Kopete::AppearanceSettings::self()->contactListHideVerticalScrollBar() )
923  {
924  setScrollAutoHide( false );
925  setScrollHide( true );
926  }
927  else
928  {
929  setScrollHide( false );
930  setScrollAutoHide( Kopete::AppearanceSettings::self()->contactListAutoHideVScroll() );
931  }
932 
933  d->scrollAutoHideTimeout = Kopete::AppearanceSettings::self()->contactListAutoHideTimeout();
934 
935  //FIXME: I don't see it in any UI
936 // setMouseNavigation( Kopete::BehaviorSettings::self()->contactListMouseNavigation() );
937 
938  setAnimated( Kopete::AppearanceSettings::self()->contactListAnimateChange() );
939 /* Kopete::UI::ListView::Item::setEffects( Kopete::AppearanceSettings::self()->contactListAnimateChange(),
940  Kopete::AppearanceSettings::self()->contactListFading(),
941  Kopete::AppearanceSettings::self()->contactListFolding() );*/
942 
943 }
944 
945 void KopeteContactListView::addToAddContactMenu( Kopete::Account* account )
946 {
947  KAction *action = new KAction( KIcon( QIcon( account->accountIcon() ) ), account->accountLabel(), this );
948  connect( action, SIGNAL(triggered(bool)), this, SLOT(addContact()) );
949  d->addContactAccountMap.insert( action, account );
950  d->actionAddContact->addAction( action );
951 }
952 
953 void KopeteContactListView::removeToAddContactMenu( const Kopete::Account *account )
954 {
955  QMapIterator<KAction *, Kopete::Account *> it( d->addContactAccountMap );
956  while ( it.hasNext() )
957  {
958  it.next();
959  if ( it.value() == account )
960  {
961  KAction *action = it.key();
962  d->addContactAccountMap.remove( action );
963  d->actionAddContact->removeAction( action );
964  }
965  }
966 }
967 
968 void KopeteContactListView::addContact()
969 {
970  if( !sender() )
971  return;
972 
973  Kopete::MetaContact* metaContact = metaContactFromIndex( currentIndex() );
974  Kopete::Group *group = groupFromIndex( currentIndex() );
975  Kopete::Account *account = d->addContactAccountMap.value( dynamic_cast<KAction*>( sender() ) );
976 
977  if ( (metaContact && metaContact->isTemporary() ) ||
978  (group && group->type() == Kopete::Group::Temporary) )
979  return;
980 
981  if( !account || !(metaContact || group) )
982  return;
983 
984  QPointer <KDialog> addDialog = new KDialog( this );
985  addDialog->setCaption( i18n( "Add Contact" ) );
986  addDialog->setButtons( KDialog::Ok | KDialog::Cancel );
987 
988  AddContactPage *addContactPage = account->protocol()->createAddContactWidget( addDialog, account );
989 
990  if ( !addContactPage )
991  {
992  kDebug(14000) << "Error while creating addcontactpage";
993  return;
994  }
995 
996  addDialog->setMainWidget( addContactPage );
997  if( addDialog->exec() == QDialog::Accepted )
998  {
999  if( addContactPage->validateData() )
1000  {
1001  if( !metaContact )
1002  {
1003  metaContact = new Kopete::MetaContact();
1004  metaContact->addToGroup( group );
1005  if ( addContactPage->apply( account, metaContact ) )
1006  Kopete::ContactList::self()->addMetaContact( metaContact );
1007  else
1008  delete metaContact;
1009  }
1010  else
1011  {
1012  addContactPage->apply( account, metaContact );
1013  }
1014  }
1015  }
1016  if ( addDialog )
1017  addDialog->deleteLater();
1018 }
1019 
1020 void KopeteContactListView::groupPopup( Kopete::Group *group, const QPoint& pos )
1021 {
1022  Q_ASSERT(group);
1023  KXmlGuiWindow *window = dynamic_cast<KXmlGuiWindow *>(topLevelWidget());
1024  if ( !window )
1025  {
1026  kError( 14000 ) << "Main window not found, unable to display context-menu; "
1027  << "Kopete::UI::Global::mainWidget() = " << Kopete::UI::Global::mainWidget() << endl;
1028  return;
1029  }
1030 
1031  if ( group == Kopete::Group::offline() )
1032  return;
1033 
1034  KMenu *popup = dynamic_cast<KMenu *>( window->factory()->container( "group_popup", window ) );
1035  if ( popup )
1036  {
1037  QString title = group->displayName();
1038  if ( title.length() > 32 )
1039  title = title.left( 30 ) + QLatin1String( "..." );
1040 
1041  // HACK: Used to update the KMenu title -DarkShock
1042  if( d->menuTitleMap.contains(popup) )
1043  {
1044  QAction *action = d->menuTitleMap[popup];
1045  popup->removeAction( action );
1046  delete action;
1047  }
1048  d->menuTitleMap.insert( popup, popup->addTitle(title, popup->actions().first()) );
1049  popup->popup( pos );
1050  }
1051 }
1052 
1053 void KopeteContactListView::metaContactPopup( Kopete::MetaContact *metaContact, const QPoint& pos )
1054 {
1055  Q_ASSERT(metaContact);
1056  KXmlGuiWindow *window = dynamic_cast<KXmlGuiWindow *>(topLevelWidget());
1057  if ( !window )
1058  {
1059  kError( 14000 ) << "Main window not found, unable to display context-menu; "
1060  << "Kopete::UI::Global::mainWidget() = " << Kopete::UI::Global::mainWidget() << endl;
1061  return;
1062  }
1063 
1064  KMenu *popup = dynamic_cast<KMenu *>( window->factory()->container( "contact_popup", window ) );
1065  if ( popup )
1066  {
1067  QString title = i18nc( "Translators: format: '<nickname> (<online status>)'", "%1 (%2)",
1068  metaContact->displayName(), metaContact->statusString() );
1069 
1070  if ( title.length() > 43 )
1071  title = title.left( 40 ) + QLatin1String( "..." );
1072 
1073  // HACK: Used to update the KMenu title -DarkShock
1074  if( d->menuTitleMap.contains(popup) )
1075  {
1076  QAction *action = d->menuTitleMap[popup];
1077  popup->removeAction( action );
1078  delete action;
1079  }
1080  d->menuTitleMap.insert( popup, popup->addTitle(title, popup->actions().first()) );
1081 
1082  // Submenus for separate contact actions
1083  bool sep = false; //FIXME: find if there is already a separator in the end - Olivier
1084  foreach( Kopete::Contact* c , metaContact->contacts() )
1085  {
1086  if( sep )
1087  {
1088  popup->addSeparator();
1089  sep = false;
1090  }
1091 
1092  KMenu *contactMenu = c->popupMenu();
1093  connect( popup, SIGNAL(aboutToHide()), contactMenu, SLOT(deleteLater()) );
1094  QString text = i18nc( "Translators: format: '<displayName> (<id>)'", "%2 <%1>", c->contactId(), c->nickName() );
1095  text=text.replace('&',"&&"); // cf BUG 115449
1096 
1097  if ( text.length() > 41 )
1098  text = text.left( 38 ) + QLatin1String( "..." );
1099 
1100  contactMenu->setTitle(text);
1101  contactMenu->setIcon(c->onlineStatus().iconFor( c ));
1102  popup->addMenu( contactMenu );
1103  }
1104  popup->popup( pos );
1105  }
1106 }
1107 
1108 void KopeteContactListView::miscPopup( QModelIndexList indexes, const QPoint& pos )
1109 {
1110  Q_ASSERT(indexes.count() > 1);
1111  KXmlGuiWindow *window = dynamic_cast<KXmlGuiWindow *>(topLevelWidget());
1112  if ( !window )
1113  {
1114  kError( 14000 ) << "Main window not found, unable to display context-menu; "
1115  << "Kopete::UI::Global::mainWidget() = " << Kopete::UI::Global::mainWidget() << endl;
1116  return;
1117  }
1118 
1119  bool onlyMetaContacts = true;
1120  foreach ( QModelIndex index, indexes )
1121  {
1122  if ( index.data( Kopete::Items::TypeRole ) != Kopete::Items::MetaContact )
1123  {
1124  onlyMetaContacts = false;
1125  break;
1126  }
1127  }
1128 
1129  KMenu *popup = 0;
1130  if ( onlyMetaContacts )
1131  popup = dynamic_cast<KMenu *>( window->factory()->container( "contactlistitems_popup", window ) );
1132 
1133  if ( popup )
1134  popup->popup( pos );
1135 }
1136 
1137 Kopete::Contact* KopeteContactListView::contactAt( const QPoint& point ) const
1138 {
1139  QModelIndex index = indexAt( point );
1140  if ( !index.isValid() )
1141  return 0;
1142 
1143  QRect rect = visualRect( index );
1144  if ( rect.width() <= 0 || rect.height() <= 0 )
1145  return 0;
1146 
1147  KopeteItemDelegate* delegate = dynamic_cast<KopeteItemDelegate*>(itemDelegate( index ));
1148  if ( !delegate )
1149  return 0;
1150 
1151  QStyleOptionViewItem option = viewOptions();
1152  option.rect = rect;
1153  return delegate->contactAt( option, index, point );
1154 }
1155 
1156 
1157 void KopeteContactListView::setScrollAutoHide( bool autoHide )
1158 {
1159  if ( d->scrollAutoHide == autoHide )
1160  return;
1161 
1162  if ( autoHide )
1163  {
1164  viewport()->installEventFilter( this );
1165  viewport()->setMouseTracking( true );
1166  verticalScrollBar()->installEventFilter( this );
1167  verticalScrollBar()->setMouseTracking( true );
1168 
1169  // Set scrollbar auto-hiding state true
1170  d->scrollAutoHide = true;
1171  // Turn of the bar now
1172  setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
1173  // Start the timer to handle auto-hide
1174  killTimer( d->scrollAutoHideTimer );
1175  d->scrollAutoHideTimer = startTimer( 1000 );
1176  }
1177  else
1178  {
1179  viewport()->removeEventFilter( this );
1180  viewport()->setMouseTracking( false );
1181  verticalScrollBar()->removeEventFilter( this );
1182  verticalScrollBar()->setMouseTracking( false );
1183 
1184  d->scrollAutoHide = false;
1185  setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
1186  killTimer( d->scrollAutoHideTimer );
1187  }
1188 }
1189 
1190 void KopeteContactListView::setScrollHide( bool hide )
1191 {
1192  if ( d->scrollHide == hide )
1193  return;
1194 
1195  d->scrollHide = hide;
1196  if ( hide )
1197  setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
1198  else
1199  setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
1200 }
1201 
1202 int KopeteContactListView::visibleContentHeight( const QModelIndex& parent ) const
1203 {
1204  if ( !parent.isValid() )
1205  return 0;
1206 
1207  int height = rowHeight( parent );
1208  if ( height <= 0 ) // Assume that items is invisible
1209  return 0;
1210 
1211  int rows = model()->rowCount( parent );
1212  for ( int i = 0; i < rows; ++i )
1213  height += visibleContentHeight( model()->index( i, 0, parent ) );
1214 
1215  return height;
1216 }
1217 
1218 #include "kopetecontactlistview.moc"
1219 
1220 // vim: set noet ts=4 sts=4 sw=4:
QItemSelection::indexes
QModelIndexList indexes() const
QModelIndex
QEvent
QWidget
QAbstractItemModel::rowCount
virtual int rowCount(const QModelIndex &parent) const =0
QEvent::type
Type type() const
QTreeView::dragMoveEvent
virtual void dragMoveEvent(QDragMoveEvent *event)
KopeteContactListView::viewportEvent
virtual bool viewportEvent(QEvent *event)
Definition: kopetecontactlistview.cpp:737
QAbstractItemModel::index
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const =0
QAbstractItemView::setAlternatingRowColors
void setAlternatingRowColors(bool enable)
KopeteContactListView::eventFilter
virtual bool eventFilter(QObject *object, QEvent *event)
Definition: kopetecontactlistview.cpp:710
QAbstractItemView::dropIndicatorPosition
DropIndicatorPosition dropIndicatorPosition() const
KopeteContactListView::mouseReleaseEvent
virtual void mouseReleaseEvent(QMouseEvent *event)
Definition: kopetecontactlistview.cpp:602
QAbstractItemView::setSelectionMode
void setSelectionMode(QAbstractItemView::SelectionMode mode)
kopeteitembase.h
Contains definitions common between model items.
contactlistlayoutmanager.h
QWidget::window
QWidget * window() const
QDrag::setMimeData
void setMimeData(QMimeData *data)
QDropEvent::proposedAction
Qt::DropAction proposedAction() const
QDragMoveEvent
KopeteContactListView::initActions
void initActions(KActionCollection *ac)
Definition: kopetecontactlistview.cpp:151
QMimeData::hasFormat
virtual bool hasFormat(const QString &mimeType) const
QObject::sender
QObject * sender() const
QTreeView::collapsed
void collapsed(const QModelIndex &index)
QMap< KMenu *, QAction * >
KopeteContactListView::sendMessage
void sendMessage()
Definition: kopetecontactlistview.cpp:521
QPointer< Kopete::MetaContact >
QDropEvent::pos
const QPoint & pos() const
QAbstractItemView::setDragDropMode
void setDragDropMode(DragDropMode behavior)
KopeteContactListView::mergeMetaContact
void mergeMetaContact()
Definition: kopetecontactlistview.cpp:320
QAbstractScrollArea::viewport
QWidget * viewport() const
QRect::height
int height() const
KopeteContactListView::addTemporaryContact
void addTemporaryContact()
Definition: kopetecontactlistview.cpp:561
QTreeView::setAnimated
void setAnimated(bool enable)
KopeteContactListView::rowsInserted
virtual void rowsInserted(const QModelIndex &parent, int start, int end)
Definition: kopetecontactlistview.cpp:747
QPoint
KDialog
QMouseEvent
contactlistmodel.h
QTreeView::visualRect
virtual QRect visualRect(const QModelIndex &index) const
QSet::insert
const_iterator insert(const T &value)
kopetelviprops.h
Kopete::Items::MetaContactGroupRole
const int MetaContactGroupRole
Definition: kopeteitembase.h:53
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QContextMenuEvent::globalPos
const QPoint & globalPos() const
QMimeData
kopetegrouplistaction.h
QTreeView::keyboardSearch
virtual void keyboardSearch(const QString &search)
QTreeView::setRootIndex
virtual void setRootIndex(const QModelIndex &index)
kopetecontactlistview.h
QTreeView::rowHeight
int rowHeight(const QModelIndex &index) const
KopeteContactListView::~KopeteContactListView
~KopeteContactListView()
Definition: kopetecontactlistview.cpp:146
KSelectAction
QDrag::exec
Qt::DropAction exec(QFlags< Qt::DropAction > supportedActions)
QTreeView::setExpanded
void setExpanded(const QModelIndex &index, bool expanded)
KopeteContactListView::dragMoveEvent
virtual void dragMoveEvent(QDragMoveEvent *event)
Definition: kopetecontactlistview.cpp:637
Kopete::Items::MetaContact
Definition: kopeteitembase.h:57
QTimerEvent
QRect
QModelIndex::isValid
bool isValid() const
QTreeView::viewportEvent
virtual bool viewportEvent(QEvent *event)
QList::count
int count(const T &value) const
QList::append
void append(const T &value)
KopeteContactListView::showItemProperties
void showItemProperties()
Definition: kopetecontactlistview.cpp:300
Kopete::Items::Group
Definition: kopeteitembase.h:57
QMapIterator
QEvent::isAccepted
bool isAccepted() const
KXmlGuiWindow
QTreeView::timerEvent
virtual void timerEvent(QTimerEvent *event)
QObject::installEventFilter
void installEventFilter(QObject *filterObj)
QWidget::topLevelWidget
QWidget * topLevelWidget() const
QSet::values
QList< T > values() const
QStyleOptionViewItem
QContextMenuEvent
ContactList::LayoutManager::instance
static LayoutManager * instance()
Definition: contactlistlayoutmanager.cpp:47
QObject
QTreeView::rowsInserted
virtual void rowsInserted(const QModelIndex &parent, int start, int end)
QList::isEmpty
bool isEmpty() const
QDrag
KopeteItemDelegate
Definition: kopeteitemdelegate.h:34
QString::isEmpty
bool isEmpty() const
QAbstractItemView::executeDelayedItemsLayout
void executeDelayedItemsLayout()
QAbstractItemView::setItemDelegate
void setItemDelegate(QAbstractItemDelegate *delegate)
KopeteContactListView::removeGroupOrMetaContact
void removeGroupOrMetaContact()
Definition: kopetecontactlistview.cpp:350
QAbstractItemView::itemDelegate
QAbstractItemDelegate * itemDelegate() const
KopeteGroupListAction
Action used for Copy To and Move To.
Definition: kopetegrouplistaction.h:26
Kopete::Items::TypeRole
const int TypeRole
Qt Model Role Definitions.
Definition: kopeteitembase.h:34
KopeteContactListView::copyToGroup
void copyToGroup()
Definition: kopetecontactlistview.cpp:473
KopeteItemDelegate::contactAt
Kopete::Contact * contactAt(const QStyleOptionViewItem &option, const QModelIndex &index, const QPoint &point) const
Definition: kopeteitemdelegate.cpp:97
QAbstractItemView::setEditTriggers
void setEditTriggers(QFlags< QAbstractItemView::EditTrigger > triggers)
QObject::eventFilter
virtual bool eventFilter(QObject *watched, QEvent *event)
QSet
QAbstractItemModel::data
virtual QVariant data(const QModelIndex &index, int role) const =0
QObject::deleteLater
void deleteLater()
QList::first
T & first()
KopeteContactListView::sendEmail
void sendEmail()
Definition: kopetecontactlistview.cpp:529
QString
KopeteContactListView::contactActivated
void contactActivated(const QModelIndex &index)
Definition: kopetecontactlistview.cpp:231
QList< Kopete::MetaContact * >
QWidget::hide
void hide()
QAbstractItemModel::mimeData
virtual QMimeData * mimeData(const QModelIndexList &indexes) const
QSet::count
int count() const
QModelIndex::parent
QModelIndex parent() const
QAbstractScrollArea::verticalScrollBar
QScrollBar * verticalScrollBar() const
QTreeView::setIndentation
void setIndentation(int i)
QTreeView::mouseReleaseEvent
virtual void mouseReleaseEvent(QMouseEvent *event)
KopeteContactListView::visibleContentHeightChanged
void visibleContentHeightChanged()
QStringList
QWidget::rect
QRect rect() const
QWidget::setAcceptDrops
void setAcceptDrops(bool on)
QInputEvent::modifiers
Qt::KeyboardModifiers modifiers() const
KopeteContactListView::addGroup
void addGroup()
Definition: kopetecontactlistview.cpp:341
QString::contains
bool contains(QChar ch, Qt::CaseSensitivity cs) const
KopeteContactListView::moveToGroup
void moveToGroup()
Definition: kopetecontactlistview.cpp:431
KopeteContactListView::startChat
void startChat()
Definition: kopetecontactlistview.cpp:507
KopeteContactListView::timerEvent
virtual void timerEvent(QTimerEvent *event)
Definition: kopetecontactlistview.cpp:699
QAbstractItemView::rootIndex
QModelIndex rootIndex() const
KopeteContactListView::sendFile
void sendFile()
Definition: kopetecontactlistview.cpp:514
KopeteContactListView::rename
void rename()
Definition: kopetecontactlistview.cpp:552
KopeteGVIProps
Definition: kopetelviprops.h:42
QAbstractItemView::activated
void activated(const QModelIndex &index)
QItemSelection
QString::replace
QString & replace(int position, int n, QChar after)
QTreeView::setExpandsOnDoubleClick
void setExpandsOnDoubleClick(bool enable)
QSet::empty
bool empty() const
QObject::startTimer
int startTimer(int interval)
KActionMenu
QContextMenuEvent::pos
const QPoint & pos() const
KopeteContactListView::setModel
virtual void setModel(QAbstractItemModel *newModel)
Definition: kopetecontactlistview.cpp:254
QRect::width
int width() const
KopeteMetaLVIProps
Definition: kopetelviprops.h:64
QModelIndex::data
QVariant data(int role) const
QLatin1String
QTreeView
Qt::DropActions
typedef DropActions
Kopete::Items::ElementRole
const int ElementRole
Definition: kopeteitembase.h:35
KopeteContactListView::KopeteContactListView
KopeteContactListView(QWidget *parent=0)
Definition: kopetecontactlistview.cpp:114
QTreeView::setModel
virtual void setModel(QAbstractItemModel *model)
QTreeView::selectionChanged
virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
Kopete::Items::ExpandStateRole
const int ExpandStateRole
Definition: kopeteitembase.h:51
QAction
KAction
KopeteContactListView::contextMenuEvent
virtual void contextMenuEvent(QContextMenuEvent *event)
Definition: kopetecontactlistview.cpp:568
KopeteContactListView::visibleContentHeight
int visibleContentHeight() const
Definition: kopetecontactlistview.cpp:269
QString::length
int length() const
KopeteContactListView::startDrag
virtual void startDrag(Qt::DropActions supportedActions)
Definition: kopetecontactlistview.cpp:614
QVariant::toBool
bool toBool() const
QWidget::setMouseTracking
void setMouseTracking(bool enable)
QTimerEvent::timerId
int timerId() const
QAbstractItemView::viewOptions
virtual QStyleOptionViewItem viewOptions() const
QTreeView::selectedIndexes
virtual QModelIndexList selectedIndexes() const
KopeteContactListView::keyboardSearch
virtual void keyboardSearch(const QString &search)
Definition: kopetecontactlistview.cpp:281
QAbstractItemModel
QAbstractItemModel::setData
virtual bool setData(const QModelIndex &index, const QVariant &value, int role)
QString::left
QString left(int n) const
QAbstractItemView::edit
void edit(const QModelIndex &index)
QSet::toList
QList< T > toList() const
QTreeView::header
QHeaderView * header() const
QTreeView::expanded
void expanded(const QModelIndex &index)
QMouseEvent::pos
const QPoint & pos() const
QAbstractItemView::defaultDropAction
Qt::DropAction defaultDropAction() const
QAbstractItemView::model
QAbstractItemModel * model() const
Kopete::Items::ObjectRole
const int ObjectRole
Definition: kopeteitembase.h:50
QAbstractItemView::currentIndex
QModelIndex currentIndex() const
QTreeView::setRootIsDecorated
void setRootIsDecorated(bool show)
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject::parent
QObject * parent() const
QTreeView::reset
virtual void reset()
QAbstractScrollArea::setVerticalScrollBarPolicy
void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy)
QObject::killTimer
void killTimer(int id)
KopeteContactListView::reset
virtual void reset()
Definition: kopetecontactlistview.cpp:289
QObject::removeEventFilter
void removeEventFilter(QObject *obj)
QWidget::height
int height() const
QTreeView::indexAt
virtual QModelIndex indexAt(const QPoint &point) const
QIcon
kopeteitemdelegate.h
QAbstractItemView::setDropIndicatorShown
void setDropIndicatorShown(bool enable)
KopeteContactListView::selectionChanged
virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
Definition: kopetecontactlistview.cpp:760
QAbstractItemView::setDragEnabled
void setDragEnabled(bool enable)
QVariant
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:29:08 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kopete/kopete

Skip menu "kopete/kopete"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdenetwork API Reference

Skip menu "kdenetwork API Reference"
  • kget
  • kopete
  •   kopete
  •   libkopete
  • krdc
  • krfb

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