kaddressbook

kaddressbooktableview.cpp

00001 /*
00002     This file is part of KAddressBook.
00003     Copyright (c) 2002 Mike Pilone <mpilone@slac.com>
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018 
00019     As a special exception, permission is given to link this program
00020     with any edition of Qt, and distribute the resulting executable,
00021     without including the source code for Qt in the source distribution.
00022 */
00023 
00024 #include <qapplication.h>
00025 #include <qlayout.h>
00026 #include <qheader.h>
00027 #include <qvbox.h>
00028 #include <qlistbox.h>
00029 #include <qwidget.h>
00030 #include <qfile.h>
00031 #include <qimage.h>
00032 #include <qcombobox.h>
00033 #include <qapplication.h>
00034 #include <qdragobject.h>
00035 #include <qevent.h>
00036 #include <qurl.h>
00037 #include <qpixmap.h>
00038 
00039 #include <kabc/addressbook.h>
00040 #include <kapplication.h>
00041 #include <kconfig.h>
00042 #include <kcolorbutton.h>
00043 #include <kdebug.h>
00044 #include <kglobal.h>
00045 #include <kiconloader.h>
00046 #include <klineedit.h>
00047 #include <klocale.h>
00048 #include <kmessagebox.h>
00049 #include <kurl.h>
00050 #include <kurlrequester.h>
00051 #include <kimproxy.h>
00052 
00053 #include "configuretableviewdialog.h"
00054 #include "contactlistview.h"
00055 #include "core.h"
00056 #include "kabprefs.h"
00057 #include "undocmds.h"
00058 
00059 #include "kaddressbooktableview.h"
00060 
00061 class TableViewFactory : public ViewFactory
00062 {
00063   public:
00064     KAddressBookView *view( KAB::Core *core, QWidget *parent, const char *name )
00065     {
00066       return new KAddressBookTableView( core, parent, name );
00067     }
00068 
00069     QString type() const { return I18N_NOOP( "Table" ); }
00070 
00071     QString description() const { return i18n( "A listing of contacts in a table. Each cell of "
00072                                   "the table holds a field of the contact." ); }
00073 
00074     ViewConfigureWidget *configureWidget( KABC::AddressBook *ab, QWidget *parent,
00075                                           const char *name = 0 )
00076     {
00077       return new ConfigureTableViewWidget( ab, parent, name );
00078     }
00079 };
00080 
00081 extern "C" {
00082   void *init_libkaddrbk_tableview()
00083   {
00084     return ( new TableViewFactory );
00085   }
00086 }
00087 
00088 KAddressBookTableView::KAddressBookTableView( KAB::Core *core,
00089                                               QWidget *parent, const char *name )
00090   : KAddressBookView( core, parent, name )
00091 {
00092   mMainLayout = new QVBoxLayout( viewWidget(), 2 );
00093 
00094   // The list view will be created when the config is read.
00095   mListView = 0;
00096   mIMProxy = 0;
00097 }
00098 
00099 KAddressBookTableView::~KAddressBookTableView()
00100 {
00101 }
00102 
00103 void KAddressBookTableView::reconstructListView()
00104 {
00105   if ( mListView ) {
00106     disconnect( mListView, SIGNAL( selectionChanged() ),
00107                 this, SLOT( addresseeSelected() ) );
00108     disconnect( mListView, SIGNAL( executed( QListViewItem* ) ),
00109                 this, SLOT( addresseeExecuted( QListViewItem* ) ) );
00110     disconnect( mListView, SIGNAL( doubleClicked( QListViewItem* ) ),
00111                 this, SLOT( addresseeExecuted( QListViewItem* ) ) );
00112     disconnect( mListView, SIGNAL( startAddresseeDrag() ),
00113                 this, SIGNAL( startDrag() ) );
00114     disconnect( mListView, SIGNAL( addresseeDropped( QDropEvent* ) ),
00115                 this, SIGNAL( dropped( QDropEvent* ) ) );
00116     delete mListView;
00117   }
00118 
00119   mListView = new ContactListView( this, core()->addressBook(), viewWidget() );
00120 
00121   mListView->setShowIM( mIMProxy != 0 );
00122 
00123   // Add the columns
00124   const KABC::Field::List fieldList( fields() );
00125   KABC::Field::List::ConstIterator it;
00126 
00127   int c = 0;
00128   for ( it = fieldList.begin(); it != fieldList.end(); ++it ) {
00129     mListView->addColumn( (*it)->label() );
00130     mListView->setColumnWidthMode( c++, QListView::Manual );
00131   }
00132 
00133   if ( mListView->showIM() ) {
00134     // IM presence is added separately, because it's not a KABC field.
00135     // If you want to make this appear as the leftmost column by default, move
00136     // this block immediately before the preceding for loop
00137     // after the declaration of c.
00138     mListView->addColumn( i18n( "Presence" ) );
00139     mListView->setIMColumn( c++ );
00140   }
00141 
00142   mListView->setFullWidth( true );
00143 
00144   connect( mListView, SIGNAL( selectionChanged() ),
00145            this, SLOT( addresseeSelected() ) );
00146   connect( mListView, SIGNAL( startAddresseeDrag() ),
00147            this, SIGNAL( startDrag() ) );
00148   connect( mListView, SIGNAL( addresseeDropped( QDropEvent* ) ),
00149            this, SIGNAL( dropped( QDropEvent* ) ) );
00150   connect( mListView, SIGNAL( contextMenu( KListView*, QListViewItem*, const QPoint& ) ),
00151            this, SLOT( rmbClicked( KListView*, QListViewItem*, const QPoint& ) ) );
00152   connect( mListView->header(), SIGNAL( clicked( int ) ),
00153            this, SIGNAL( sortFieldChanged() ) );
00154 
00155   if ( KABPrefs::instance()->honorSingleClick() )
00156     connect( mListView, SIGNAL( executed( QListViewItem* ) ),
00157              this, SLOT( addresseeExecuted( QListViewItem* ) ) );
00158   else
00159     connect( mListView, SIGNAL( doubleClicked( QListViewItem* ) ),
00160              this, SLOT( addresseeExecuted( QListViewItem* ) ) );
00161 
00162   refresh();
00163 
00164   mListView->setSorting( 0, true );
00165   mMainLayout->addWidget( mListView );
00166   mMainLayout->activate();
00167   mListView->show();
00168 }
00169 
00170 KABC::Field *KAddressBookTableView::sortField() const
00171 {
00172   // we have hardcoded sorting, so we have to return a hardcoded field :(
00173   return ( mListView->sortColumn() == -1 ? fields()[ 0 ] : fields()[ mListView->sortColumn() ] );
00174 }
00175 
00176 void KAddressBookTableView::writeConfig( KConfig *config )
00177 {
00178   KAddressBookView::writeConfig( config );
00179 
00180   mListView->saveLayout( config, config->group() );
00181 }
00182 
00183 void KAddressBookTableView::readConfig( KConfig *config )
00184 {
00185   KAddressBookView::readConfig( config );
00186 
00187   if ( config->readBoolEntry( "InstantMessagingPresence", false ) ) {
00188     if ( !mIMProxy ) {
00189       mIMProxy = KIMProxy::instance( kapp->dcopClient() );
00190       connect( mIMProxy, SIGNAL( sigContactPresenceChanged( const QString& ) ),
00191                this, SLOT( updatePresence( const QString& ) ) );
00192     }
00193   } else {
00194     if ( mIMProxy ) {
00195       disconnect( mIMProxy, SIGNAL( sigContactPresenceChanged( const QString& ) ),
00196                   this, SLOT( updatePresence( const QString& ) ) );
00197       mIMProxy = 0;
00198     }
00199   }
00200 
00201   // The config could have changed the fields, so we need to reconstruct
00202   // the listview.
00203   reconstructListView();
00204 
00205   // Set the list view options
00206   mListView->setAlternateBackgroundEnabled( config->readBoolEntry( "ABackground", true ) );
00207   mListView->setSingleLineEnabled( config->readBoolEntry( "SingleLine", false ) );
00208   mListView->setToolTipsEnabled( config->readBoolEntry( "ToolTips", true ) );
00209 
00210   if ( config->readBoolEntry( "Background", false ) )
00211     mListView->setBackgroundPixmap( config->readPathEntry( "BackgroundName" ) );
00212 
00213   // Restore the layout of the listview
00214   mListView->restoreLayout( config, config->group() );
00215 }
00216 
00217 void KAddressBookTableView::refresh( const QString &uid )
00218 {
00219   if ( uid.isEmpty() ) {
00220     // Clear the list view
00221     QString currentUID, nextUID;
00222     ContactListViewItem *currentItem = dynamic_cast<ContactListViewItem*>( mListView->currentItem() );
00223     if ( currentItem ) {
00224       ContactListViewItem *nextItem = dynamic_cast<ContactListViewItem*>( currentItem->itemBelow() );
00225       if ( nextItem )
00226         nextUID = nextItem->addressee().uid();
00227       currentUID = currentItem->addressee().uid();
00228     }
00229 
00230     mListView->clear();
00231 
00232     currentItem = 0;
00233     const KABC::Addressee::List addresseeList( addressees() );
00234     KABC::Addressee::List::ConstIterator it( addresseeList.begin() );
00235     const KABC::Addressee::List::ConstIterator endIt( addresseeList.end() );
00236     for ( ; it != endIt; ++it ) {
00237       ContactListViewItem *item = new ContactListViewItem( *it, mListView,
00238                                         core()->addressBook(), fields(), mIMProxy );
00239       if ( (*it).uid() == currentUID )
00240         currentItem = item;
00241       else if ( (*it).uid() == nextUID && !currentItem )
00242         currentItem = item;
00243     }
00244 
00245     // Sometimes the background pixmap gets messed up when we add lots
00246     // of items.
00247     mListView->repaint();
00248 
00249     if ( currentItem ) {
00250       mListView->setCurrentItem( currentItem );
00251       mListView->ensureItemVisible( currentItem );
00252     }
00253   } else {
00254     // Only need to update on entry. Iterate through and try to find it
00255     ContactListViewItem *ceItem;
00256     QPtrList<QListViewItem> selectedItems( mListView->selectedItems() );
00257     QListViewItem *it;
00258     for ( it = selectedItems.first(); it; it = selectedItems.next() ) {
00259       ceItem = dynamic_cast<ContactListViewItem*>( it );
00260       if ( ceItem && ceItem->addressee().uid() == uid ) {
00261         ceItem->refresh();
00262         return;
00263       }
00264     }
00265     refresh( QString::null );
00266   }
00267 }
00268 
00269 QStringList KAddressBookTableView::selectedUids()
00270 {
00271   QStringList uidList;
00272   ContactListViewItem *item;
00273 
00274   QListViewItemIterator it( mListView, QListViewItemIterator::Selected );
00275   while ( it.current() ) {
00276     item = dynamic_cast<ContactListViewItem*>( it.current() );
00277     if ( item )
00278       uidList << item->addressee().uid();
00279 
00280     ++it;
00281   }
00282 
00283   return uidList;
00284 }
00285 
00286 void KAddressBookTableView::setSelected( const QString &uid, bool selected )
00287 {
00288   if ( uid.isEmpty() )
00289     mListView->selectAll( selected );
00290   else {
00291     QListViewItemIterator it( mListView );
00292     while ( it.current() ) {
00293       ContactListViewItem *item = dynamic_cast<ContactListViewItem*>( it.current() );
00294       if ( item && (item->addressee().uid() == uid) ) {
00295         mListView->setSelected( item, selected );
00296 
00297         if ( selected )
00298           mListView->ensureItemVisible( item );
00299       }
00300 
00301       ++it;
00302     }
00303   }
00304 }
00305 
00306 void KAddressBookTableView::setFirstSelected( bool selected )
00307 {
00308   if ( mListView->firstChild() ) {
00309     mListView->setSelected( mListView->firstChild(), selected );
00310     mListView->ensureItemVisible( mListView->firstChild() );
00311   }
00312 }
00313 
00314 void KAddressBookTableView::addresseeSelected()
00315 {
00316   // We need to try to find the first selected item. This might not be the
00317   // last selected item, but when QListView is in multiselection mode,
00318   // there is no way to figure out which one was
00319   // selected last.
00320   bool found =false;
00321 
00322   QListViewItemIterator it( mListView, QListViewItemIterator::Selected );
00323   while ( it.current() && !found ) {
00324     found = true;
00325     ContactListViewItem *item = dynamic_cast<ContactListViewItem*>( it.current() );
00326     if ( item )
00327       emit selected( item->addressee().uid() );
00328 
00329     ++it;
00330   }
00331 
00332   if ( !found )
00333       emit selected( QString::null );
00334 }
00335 
00336 void KAddressBookTableView::addresseeExecuted( QListViewItem *item )
00337 {
00338   if ( item ) {
00339     ContactListViewItem *ceItem = dynamic_cast<ContactListViewItem*>( item );
00340 
00341     if ( ceItem )
00342       emit executed( ceItem->addressee().uid() );
00343     else
00344       emit executed( QString::null );
00345   } else {
00346     emit executed( QString::null );
00347   }
00348 }
00349 
00350 void KAddressBookTableView::rmbClicked( KListView*, QListViewItem*, const QPoint &point )
00351 {
00352   popup( point );
00353 }
00354 
00355 void KAddressBookTableView::updatePresence( const QString &uid )
00356 {
00357   // find the LVI to update and refresh() it
00358   QListViewItem *item;
00359   ContactListViewItem *ceItem;
00360   for ( item = mListView->firstChild(); item; item = item->itemBelow() ) {
00361     ceItem = dynamic_cast<ContactListViewItem*>( item );
00362     if ( ( ceItem != 0L ) && ( ceItem->addressee().uid() == uid ) ) {
00363       ceItem->setHasIM( true );
00364       ceItem->refresh();
00365       break;
00366     }
00367   }
00368 
00369   if ( mListView->sortColumn() == mListView->imColumn() )
00370     mListView->sort();
00371 }
00372 
00373 void KAddressBookTableView::scrollUp()
00374 {
00375   QApplication::postEvent( mListView, new QKeyEvent( QEvent::KeyPress, Qt::Key_Up, 0, 0 ) );
00376 }
00377 
00378 void KAddressBookTableView::scrollDown()
00379 {
00380   QApplication::postEvent( mListView, new QKeyEvent( QEvent::KeyPress, Qt::Key_Down, 0, 0 ) );
00381 }
00382 
00383 
00384 #include "kaddressbooktableview.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys