/* This file is part of KAddressBook. Copyright (c) 2002 Mike Pilone This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of TQt, and distribute the resulting executable, without including the source code for TQt in the source distribution. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "configuretableviewdialog.h" #include "contactlistview.h" #include "core.h" #include "kabprefs.h" #include "undocmds.h" #include "kaddressbooktableview.h" class TableViewFactory : public ViewFactory { public: KAddressBookView *view( KAB::Core *core, TQWidget *parent, const char *name ) { return new KAddressBookTableView( core, parent, name ); } TQString type() const { return I18N_NOOP( "Table" ); } TQString description() const { return i18n( "A listing of contacts in a table. Each cell of " "the table holds a field of the contact." ); } ViewConfigureWidget *configureWidget( TDEABC::AddressBook *ab, TQWidget *parent, const char *name = 0 ) { return new ConfigureTableViewWidget( ab, parent, name ); } }; extern "C" { void *init_libkaddrbk_tableview() { return ( new TableViewFactory ); } } KAddressBookTableView::KAddressBookTableView( KAB::Core *core, TQWidget *parent, const char *name ) : KAddressBookView( core, parent, name ) { mMainLayout = new TQVBoxLayout( viewWidget(), 2 ); // The list view will be created when the config is read. mListView = 0; mIMProxy = 0; } KAddressBookTableView::~KAddressBookTableView() { } void KAddressBookTableView::reconstructListView() { if ( mListView ) { disconnect( mListView, TQT_SIGNAL( selectionChanged() ), this, TQT_SLOT( addresseeSelected() ) ); disconnect( mListView, TQT_SIGNAL( executed( TQListViewItem* ) ), this, TQT_SLOT( addresseeExecuted( TQListViewItem* ) ) ); disconnect( mListView, TQT_SIGNAL( doubleClicked( TQListViewItem* ) ), this, TQT_SLOT( addresseeExecuted( TQListViewItem* ) ) ); disconnect( mListView, TQT_SIGNAL( startAddresseeDrag() ), this, TQT_SIGNAL( startDrag() ) ); disconnect( mListView, TQT_SIGNAL( addresseeDropped( TQDropEvent* ) ), this, TQT_SIGNAL( dropped( TQDropEvent* ) ) ); delete mListView; } mListView = new ContactListView( this, core()->addressBook(), viewWidget() ); mListView->setShowIM( mIMProxy != 0 ); // Add the columns const TDEABC::Field::List fieldList( fields() ); TDEABC::Field::List::ConstIterator it; int c = 0; for ( it = fieldList.begin(); it != fieldList.end(); ++it ) { mListView->addColumn( (*it)->label() ); mListView->setColumnWidthMode( c++, TQListView::Manual ); } if ( mListView->showIM() ) { // IM presence is added separately, because it's not a KABC field. // If you want to make this appear as the leftmost column by default, move // this block immediately before the preceding for loop // after the declaration of c. mListView->addColumn( i18n( "Presence" ) ); mListView->setIMColumn( c++ ); } mListView->setFullWidth( true ); connect( mListView, TQT_SIGNAL( selectionChanged() ), this, TQT_SLOT( addresseeSelected() ) ); connect( mListView, TQT_SIGNAL( startAddresseeDrag() ), this, TQT_SIGNAL( startDrag() ) ); connect( mListView, TQT_SIGNAL( addresseeDropped( TQDropEvent* ) ), this, TQT_SIGNAL( dropped( TQDropEvent* ) ) ); connect( mListView, TQT_SIGNAL( contextMenu( TDEListView*, TQListViewItem*, const TQPoint& ) ), this, TQT_SLOT( rmbClicked( TDEListView*, TQListViewItem*, const TQPoint& ) ) ); connect( mListView->header(), TQT_SIGNAL( clicked( int ) ), this, TQT_SIGNAL( sortFieldChanged() ) ); if ( KABPrefs::instance()->honorSingleClick() ) connect( mListView, TQT_SIGNAL( executed( TQListViewItem* ) ), this, TQT_SLOT( addresseeExecuted( TQListViewItem* ) ) ); else connect( mListView, TQT_SIGNAL( doubleClicked( TQListViewItem* ) ), this, TQT_SLOT( addresseeExecuted( TQListViewItem* ) ) ); refresh(); mListView->setSorting( 0, true ); mMainLayout->addWidget( mListView ); mMainLayout->activate(); mListView->show(); } TDEABC::Field *KAddressBookTableView::sortField() const { // we have hardcoded sorting, so we have to return a hardcoded field :( return ( mListView->sortColumn() == -1 ? fields()[ 0 ] : fields()[ mListView->sortColumn() ] ); } void KAddressBookTableView::writeConfig( TDEConfig *config ) { KAddressBookView::writeConfig( config ); mListView->saveLayout( config, config->group() ); } void KAddressBookTableView::readConfig( TDEConfig *config ) { KAddressBookView::readConfig( config ); if ( config->readBoolEntry( "InstantMessagingPresence", false ) ) { if ( !mIMProxy ) { mIMProxy = KIMProxy::instance( kapp->dcopClient() ); connect( mIMProxy, TQT_SIGNAL( sigContactPresenceChanged( const TQString& ) ), this, TQT_SLOT( updatePresence( const TQString& ) ) ); } } else { if ( mIMProxy ) { disconnect( mIMProxy, TQT_SIGNAL( sigContactPresenceChanged( const TQString& ) ), this, TQT_SLOT( updatePresence( const TQString& ) ) ); mIMProxy = 0; } } // The config could have changed the fields, so we need to reconstruct // the listview. reconstructListView(); // Set the list view options mListView->setAlternateBackgroundEnabled( config->readBoolEntry( "ABackground", true ) ); mListView->setSingleLineEnabled( config->readBoolEntry( "SingleLine", false ) ); mListView->setToolTipsEnabled( config->readBoolEntry( "ToolTips", true ) ); if ( config->readBoolEntry( "Background", false ) ) mListView->setBackgroundPixmap( config->readPathEntry( "BackgroundName" ) ); // Restore the layout of the listview mListView->restoreLayout( config, config->group() ); } void KAddressBookTableView::refresh( const TQString &uid ) { if ( uid.isEmpty() ) { // Clear the list view TQString currentUID, nextUID; ContactListViewItem *currentItem = dynamic_cast( mListView->currentItem() ); if ( currentItem ) { ContactListViewItem *nextItem = dynamic_cast( currentItem->itemBelow() ); if ( nextItem ) nextUID = nextItem->addressee().uid(); currentUID = currentItem->addressee().uid(); } mListView->clear(); currentItem = 0; const TDEABC::Addressee::List addresseeList( addressees() ); TDEABC::Addressee::List::ConstIterator it( addresseeList.begin() ); const TDEABC::Addressee::List::ConstIterator endIt( addresseeList.end() ); for ( ; it != endIt; ++it ) { ContactListViewItem *item = new ContactListViewItem( *it, mListView, core()->addressBook(), fields(), mIMProxy ); if ( (*it).uid() == currentUID ) currentItem = item; else if ( (*it).uid() == nextUID && !currentItem ) currentItem = item; } // Sometimes the background pixmap gets messed up when we add lots // of items. mListView->repaint(); if ( currentItem ) { mListView->setCurrentItem( currentItem ); mListView->ensureItemVisible( currentItem ); } } else { // Only need to update on entry. Iterate through and try to find it ContactListViewItem *ceItem; TQPtrList selectedItems( mListView->selectedItems() ); TQListViewItem *it; for ( it = selectedItems.first(); it; it = selectedItems.next() ) { ceItem = dynamic_cast( it ); if ( ceItem && ceItem->addressee().uid() == uid ) { ceItem->refresh(); return; } } refresh( TQString() ); } } TQStringList KAddressBookTableView::selectedUids() { TQStringList uidList; ContactListViewItem *item; TQListViewItemIterator it( mListView, TQListViewItemIterator::Selected ); while ( it.current() ) { item = dynamic_cast( it.current() ); if ( item ) uidList << item->addressee().uid(); ++it; } return uidList; } void KAddressBookTableView::setSelected( const TQString &uid, bool selected ) { if ( uid.isEmpty() ) mListView->selectAll( selected ); else { TQListViewItemIterator it( mListView ); while ( it.current() ) { ContactListViewItem *item = dynamic_cast( it.current() ); if ( item && (item->addressee().uid() == uid) ) { mListView->setSelected( item, selected ); if ( selected ) mListView->ensureItemVisible( item ); } ++it; } } } void KAddressBookTableView::setFirstSelected( bool selected ) { if ( mListView->firstChild() ) { mListView->setSelected( mListView->firstChild(), selected ); mListView->ensureItemVisible( mListView->firstChild() ); } } void KAddressBookTableView::addresseeSelected() { // We need to try to find the first selected item. This might not be the // last selected item, but when TQListView is in multiselection mode, // there is no way to figure out which one was // selected last. bool found =false; TQListViewItemIterator it( mListView, TQListViewItemIterator::Selected ); while ( it.current() && !found ) { found = true; ContactListViewItem *item = dynamic_cast( it.current() ); if ( item ) emit selected( item->addressee().uid() ); ++it; } if ( !found ) emit selected( TQString() ); } void KAddressBookTableView::addresseeExecuted( TQListViewItem *item ) { if ( item ) { ContactListViewItem *ceItem = dynamic_cast( item ); if ( ceItem ) emit executed( ceItem->addressee().uid() ); else emit executed( TQString() ); } else { emit executed( TQString() ); } } void KAddressBookTableView::rmbClicked( TDEListView*, TQListViewItem*, const TQPoint &point ) { popup( point ); } void KAddressBookTableView::updatePresence( const TQString &uid ) { // find the LVI to update and refresh() it TQListViewItem *item; ContactListViewItem *ceItem; for ( item = mListView->firstChild(); item; item = item->itemBelow() ) { ceItem = dynamic_cast( item ); if ( ( ceItem != 0L ) && ( ceItem->addressee().uid() == uid ) ) { ceItem->setHasIM( true ); ceItem->refresh(); break; } } if ( mListView->sortColumn() == mListView->imColumn() ) mListView->sort(); } void KAddressBookTableView::scrollUp() { TQApplication::postEvent( mListView, new TQKeyEvent( TQEvent::KeyPress, TQt::Key_Up, 0, 0 ) ); } void KAddressBookTableView::scrollDown() { TQApplication::postEvent( mListView, new TQKeyEvent( TQEvent::KeyPress, TQt::Key_Down, 0, 0 ) ); } #include "kaddressbooktableview.moc"