kaddressbookcardview.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 TQt, and distribute the resulting executable, 00021 without including the source code for TQt in the source distribution. 00022 */ 00023 00024 #include <tqapplication.h> 00025 #include <tqdragobject.h> 00026 #include <tqevent.h> 00027 #include <tqiconview.h> 00028 #include <tqlayout.h> 00029 #include <tqstringlist.h> 00030 00031 #include <tdeabc/addressbook.h> 00032 #include <tdeabc/addressee.h> 00033 #include <tdeconfig.h> 00034 #include <kdebug.h> 00035 #include <tdelocale.h> 00036 00037 #include "core.h" 00038 #include "configurecardviewdialog.h" 00039 #include "kabprefs.h" 00040 00041 #include "kaddressbookcardview.h" 00042 00043 class CardViewFactory : public ViewFactory 00044 { 00045 public: 00046 KAddressBookView *view( KAB::Core *core, TQWidget *parent, const char *name ) 00047 { 00048 return new KAddressBookCardView( core, parent, name ); 00049 } 00050 00051 TQString type() const { return I18N_NOOP("Card"); } 00052 00053 TQString description() const { return i18n( "Rolodex style cards represent contacts." ); } 00054 00055 ViewConfigureWidget *configureWidget( TDEABC::AddressBook *ab, TQWidget *parent, 00056 const char *name = 0 ) 00057 { 00058 return new ConfigureCardViewWidget( ab, parent, name ); 00059 } 00060 }; 00061 00062 extern "C" { 00063 void *init_libkaddrbk_cardview() 00064 { 00065 return ( new CardViewFactory ); 00066 } 00067 } 00068 00069 class AddresseeCardViewItem : public CardViewItem 00070 { 00071 public: 00072 AddresseeCardViewItem( const TDEABC::Field::List &fields, 00073 bool showEmptyFields, 00074 TDEABC::AddressBook *doc, const TDEABC::Addressee &addr, 00075 CardView *parent ) 00076 : CardViewItem( parent, addr.realName() ), 00077 mFields( fields ), mShowEmptyFields( showEmptyFields ), 00078 mDocument( doc ), mAddressee( addr ) 00079 { 00080 if ( mFields.isEmpty() ) 00081 mFields = TDEABC::Field::defaultFields(); 00082 00083 refresh(); 00084 } 00085 00086 const TDEABC::Addressee &addressee() const { return mAddressee; } 00087 00088 void refresh() 00089 { 00090 mAddressee = mDocument->findByUid( mAddressee.uid() ); 00091 00092 if ( !mAddressee.isEmpty() ) { 00093 clearFields(); 00094 00095 TDEABC::Field::List::ConstIterator it( mFields.begin() ); 00096 const TDEABC::Field::List::ConstIterator endIt( mFields.end() ); 00097 for ( ; it != endIt; ++it ) { 00098 // insert empty fields or not? not doing so saves a bit of memory and CPU 00099 // (during geometry calculations), but prevents having equally 00100 // wide label columns in all cards, unless CardViewItem/CardView search 00101 // globally for the widest label. (anders) 00102 00103 // if ( mShowEmptyFields || !(*it)->value( mAddressee ).isEmpty() ) 00104 insertField( (*it)->label(), (*it)->value( mAddressee ) ); 00105 } 00106 00107 setCaption( mAddressee.realName() ); 00108 } 00109 } 00110 00111 private: 00112 TDEABC::Field::List mFields; 00113 bool mShowEmptyFields; 00114 TDEABC::AddressBook *mDocument; 00115 TDEABC::Addressee mAddressee; 00116 }; 00117 00118 00119 AddresseeCardView::AddresseeCardView( TQWidget *parent, const char *name ) 00120 : CardView( parent, name ) 00121 { 00122 setAcceptDrops( true ); 00123 } 00124 00125 AddresseeCardView::~AddresseeCardView() 00126 { 00127 } 00128 00129 void AddresseeCardView::dragEnterEvent( TQDragEnterEvent *event ) 00130 { 00131 if ( TQTextDrag::canDecode( event ) ) 00132 event->accept(); 00133 } 00134 00135 void AddresseeCardView::dropEvent( TQDropEvent *event ) 00136 { 00137 emit addresseeDropped( event ); 00138 } 00139 00140 void AddresseeCardView::startDrag() 00141 { 00142 emit startAddresseeDrag(); 00143 } 00144 00145 00146 KAddressBookCardView::KAddressBookCardView( KAB::Core *core, 00147 TQWidget *parent, const char *name ) 00148 : KAddressBookView( core, parent, name ) 00149 { 00150 mShowEmptyFields = false; 00151 00152 TQVBoxLayout *layout = new TQVBoxLayout( viewWidget() ); 00153 00154 mCardView = new AddresseeCardView( viewWidget(), "mCardView" ); 00155 mCardView->setSelectionMode( CardView::Extended ); 00156 layout->addWidget( mCardView ); 00157 00158 // Connect up the signals 00159 connect( mCardView, TQT_SIGNAL( executed( CardViewItem* ) ), 00160 this, TQT_SLOT( addresseeExecuted( CardViewItem* ) ) ); 00161 connect( mCardView, TQT_SIGNAL( selectionChanged() ), 00162 this, TQT_SLOT( addresseeSelected() ) ); 00163 connect( mCardView, TQT_SIGNAL( addresseeDropped( TQDropEvent* ) ), 00164 this, TQT_SIGNAL( dropped( TQDropEvent* ) ) ); 00165 connect( mCardView, TQT_SIGNAL( startAddresseeDrag() ), 00166 this, TQT_SIGNAL( startDrag() ) ); 00167 connect( mCardView, TQT_SIGNAL( contextMenuRequested( CardViewItem*, const TQPoint& ) ), 00168 this, TQT_SLOT( rmbClicked( CardViewItem*, const TQPoint& ) ) ); 00169 } 00170 00171 KAddressBookCardView::~KAddressBookCardView() 00172 { 00173 } 00174 00175 TDEABC::Field *KAddressBookCardView::sortField() const 00176 { 00177 // we have hardcoded sorting, so we have to return a hardcoded field :( 00178 return TDEABC::Field::allFields()[ 0 ]; 00179 } 00180 00181 void KAddressBookCardView::readConfig( TDEConfig *config ) 00182 { 00183 KAddressBookView::readConfig( config ); 00184 00185 // costum colors? 00186 if ( config->readBoolEntry( "EnableCustomColors", false ) ) { 00187 TQPalette p( mCardView->palette() ); 00188 TQColor c = p.color( TQPalette::Normal, TQColorGroup::Base ); 00189 p.setColor( TQPalette::Normal, TQColorGroup::Base, config->readColorEntry( "BackgroundColor", &c ) ); 00190 c = p.color( TQPalette::Normal, TQColorGroup::Text ); 00191 p.setColor( TQPalette::Normal, TQColorGroup::Text, config->readColorEntry( "TextColor", &c ) ); 00192 c = p.color( TQPalette::Normal, TQColorGroup::Button ); 00193 p.setColor( TQPalette::Normal, TQColorGroup::Button, config->readColorEntry( "HeaderColor", &c ) ); 00194 c = p.color( TQPalette::Normal, TQColorGroup::ButtonText ); 00195 p.setColor( TQPalette::Normal, TQColorGroup::ButtonText, config->readColorEntry( "HeaderTextColor", &c ) ); 00196 c = p.color( TQPalette::Normal, TQColorGroup::Highlight ); 00197 p.setColor( TQPalette::Normal, TQColorGroup::Highlight, config->readColorEntry( "HighlightColor", &c ) ); 00198 c = p.color( TQPalette::Normal, TQColorGroup::HighlightedText ); 00199 p.setColor( TQPalette::Normal, TQColorGroup::HighlightedText, config->readColorEntry( "HighlightedTextColor", &c ) ); 00200 mCardView->viewport()->setPalette( p ); 00201 } else { 00202 // needed if turned off during a session. 00203 mCardView->viewport()->setPalette( mCardView->palette() ); 00204 } 00205 00206 //custom fonts? 00207 TQFont f( font() ); 00208 if ( config->readBoolEntry( "EnableCustomFonts", false ) ) { 00209 mCardView->setFont( config->readFontEntry( "TextFont", &f ) ); 00210 f.setBold( true ); 00211 mCardView->setHeaderFont( config->readFontEntry( "HeaderFont", &f ) ); 00212 } else { 00213 mCardView->setFont( f ); 00214 f.setBold( true ); 00215 mCardView->setHeaderFont( f ); 00216 } 00217 00218 mCardView->setDrawCardBorder( config->readBoolEntry( "DrawBorder", true ) ); 00219 mCardView->setDrawColSeparators( config->readBoolEntry( "DrawSeparators", true ) ); 00220 mCardView->setDrawFieldLabels( config->readBoolEntry( "DrawFieldLabels", false ) ); 00221 mShowEmptyFields = config->readBoolEntry( "ShowEmptyFields", false ); 00222 00223 mCardView->setShowEmptyFields( mShowEmptyFields ); 00224 00225 mCardView->setItemWidth( config->readNumEntry( "ItemWidth", 200 ) ); 00226 mCardView->setItemMargin( config->readNumEntry( "ItemMargin", 0 ) ); 00227 mCardView->setItemSpacing( config->readNumEntry( "ItemSpacing", 10 ) ); 00228 mCardView->setSeparatorWidth( config->readNumEntry( "SeparatorWidth", 2 ) ); 00229 00230 disconnect( mCardView, TQT_SIGNAL( executed( CardViewItem* ) ), 00231 this, TQT_SLOT( addresseeExecuted( CardViewItem* ) ) ); 00232 00233 if ( KABPrefs::instance()->honorSingleClick() ) 00234 connect( mCardView, TQT_SIGNAL( executed( CardViewItem* ) ), 00235 this, TQT_SLOT( addresseeExecuted( CardViewItem* ) ) ); 00236 else 00237 connect( mCardView, TQT_SIGNAL( doubleClicked( CardViewItem* ) ), 00238 this, TQT_SLOT( addresseeExecuted( CardViewItem* ) ) ); 00239 } 00240 00241 void KAddressBookCardView::writeConfig( TDEConfig *config ) 00242 { 00243 config->writeEntry( "ItemWidth", mCardView->itemWidth() ); 00244 KAddressBookView::writeConfig( config ); 00245 } 00246 00247 TQStringList KAddressBookCardView::selectedUids() 00248 { 00249 TQStringList uidList; 00250 CardViewItem *item; 00251 AddresseeCardViewItem *aItem; 00252 00253 for ( item = mCardView->firstItem(); item; item = item->nextItem() ) { 00254 if ( item->isSelected() ) { 00255 aItem = dynamic_cast<AddresseeCardViewItem*>( item ); 00256 if ( aItem ) 00257 uidList << aItem->addressee().uid(); 00258 } 00259 } 00260 00261 return uidList; 00262 } 00263 00264 void KAddressBookCardView::refresh( const TQString &uid ) 00265 { 00266 CardViewItem *item; 00267 AddresseeCardViewItem *aItem; 00268 00269 if ( uid.isEmpty() ) { 00270 // Rebuild the view 00271 mCardView->viewport()->setUpdatesEnabled( false ); 00272 mCardView->clear(); 00273 00274 const TDEABC::Addressee::List addresseeList( addressees() ); 00275 TDEABC::Addressee::List::ConstIterator it( addresseeList.begin() ); 00276 const TDEABC::Addressee::List::ConstIterator endIt( addresseeList.end() ); 00277 for ( ; it != endIt; ++it ) { 00278 aItem = new AddresseeCardViewItem( fields(), mShowEmptyFields, 00279 core()->addressBook(), *it, mCardView ); 00280 } 00281 mCardView->viewport()->setUpdatesEnabled( true ); 00282 mCardView->viewport()->update(); 00283 00284 // by default nothing is selected 00285 emit selected( TQString() ); 00286 } else { 00287 // Try to find the one to refresh 00288 bool found = false; 00289 for ( item = mCardView->firstItem(); item && !found; item = item->nextItem() ) { 00290 aItem = dynamic_cast<AddresseeCardViewItem*>( item ); 00291 if ( aItem && (aItem->addressee().uid() == uid) ) { 00292 aItem->refresh(); 00293 found = true; 00294 } 00295 } 00296 } 00297 } 00298 00299 void KAddressBookCardView::setSelected( const TQString &uid, bool selected ) 00300 { 00301 CardViewItem *item; 00302 AddresseeCardViewItem *aItem; 00303 00304 if ( uid.isEmpty() ) { 00305 mCardView->selectAll( selected ); 00306 } else { 00307 bool found = false; 00308 for ( item = mCardView->firstItem(); item && !found; item = item->nextItem() ) { 00309 aItem = dynamic_cast<AddresseeCardViewItem*>( item ); 00310 00311 if ( aItem && (aItem->addressee().uid() == uid) ) { 00312 mCardView->setSelected( aItem, selected ); 00313 mCardView->ensureItemVisible( item ); 00314 found = true; 00315 } 00316 } 00317 } 00318 } 00319 00320 void KAddressBookCardView::setFirstSelected( bool selected ) 00321 { 00322 if ( mCardView->firstItem() ) { 00323 mCardView->setSelected( mCardView->firstItem(), selected ); 00324 mCardView->ensureItemVisible( mCardView->firstItem() ); 00325 } 00326 } 00327 00328 void KAddressBookCardView::addresseeExecuted( CardViewItem *item ) 00329 { 00330 AddresseeCardViewItem *aItem = dynamic_cast<AddresseeCardViewItem*>( item ); 00331 if ( aItem ) 00332 emit executed( aItem->addressee().uid() ); 00333 } 00334 00335 void KAddressBookCardView::addresseeSelected() 00336 { 00337 CardViewItem *item; 00338 AddresseeCardViewItem *aItem; 00339 00340 bool found = false; 00341 for ( item = mCardView->firstItem(); item && !found; item = item->nextItem() ) { 00342 if ( item->isSelected() ) { 00343 aItem = dynamic_cast<AddresseeCardViewItem*>( item ); 00344 if ( aItem ) { 00345 emit selected( aItem->addressee().uid() ); 00346 found = true; 00347 } 00348 } 00349 } 00350 00351 if ( !found ) 00352 emit selected( TQString() ); 00353 } 00354 00355 void KAddressBookCardView::rmbClicked( CardViewItem*, const TQPoint &point ) 00356 { 00357 popup( point ); 00358 } 00359 00360 void KAddressBookCardView::scrollUp() 00361 { 00362 TQApplication::postEvent( mCardView, new TQKeyEvent( TQEvent::KeyPress, TQt::Key_Up, 0, 0 ) ); 00363 } 00364 00365 void KAddressBookCardView::scrollDown() 00366 { 00367 TQApplication::postEvent( mCardView, new TQKeyEvent( TQEvent::KeyPress, TQt::Key_Down, 0, 0 ) ); 00368 } 00369 00370 #include "kaddressbookcardview.moc"