kaddressbook

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 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 <qdragobject.h>
00026 #include <qevent.h>
00027 #include <qiconview.h>
00028 #include <qlayout.h>
00029 #include <qstringlist.h>
00030 
00031 #include <kabc/addressbook.h>
00032 #include <kabc/addressee.h>
00033 #include <kconfig.h>
00034 #include <kdebug.h>
00035 #include <klocale.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, QWidget *parent, const char *name )
00047     {
00048       return new KAddressBookCardView( core, parent, name );
00049     }
00050 
00051     QString type() const { return I18N_NOOP("Card"); }
00052 
00053     QString description() const { return i18n( "Rolodex style cards represent contacts." ); }
00054 
00055     ViewConfigureWidget *configureWidget( KABC::AddressBook *ab, QWidget *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 KABC::Field::List &fields,
00073                            bool showEmptyFields,
00074                            KABC::AddressBook *doc, const KABC::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 = KABC::Field::defaultFields();
00082 
00083         refresh();
00084       }
00085 
00086     const KABC::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         KABC::Field::List::ConstIterator it( mFields.begin() );
00096         const KABC::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     KABC::Field::List mFields;
00113     bool mShowEmptyFields;
00114     KABC::AddressBook *mDocument;
00115     KABC::Addressee mAddressee;
00116 };
00117 
00118 
00119 AddresseeCardView::AddresseeCardView( QWidget *parent, const char *name )
00120   : CardView( parent, name )
00121 {
00122   setAcceptDrops( true );
00123 }
00124 
00125 AddresseeCardView::~AddresseeCardView()
00126 {
00127 }
00128 
00129 void AddresseeCardView::dragEnterEvent( QDragEnterEvent *event )
00130 {
00131   if ( QTextDrag::canDecode( event ) )
00132     event->accept();
00133 }
00134 
00135 void AddresseeCardView::dropEvent( QDropEvent *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                                             QWidget *parent, const char *name )
00148     : KAddressBookView( core, parent, name )
00149 {
00150   mShowEmptyFields = false;
00151 
00152   QVBoxLayout *layout = new QVBoxLayout( 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, SIGNAL( executed( CardViewItem* ) ),
00160            this, SLOT( addresseeExecuted( CardViewItem* ) ) );
00161   connect( mCardView, SIGNAL( selectionChanged() ),
00162            this, SLOT( addresseeSelected() ) );
00163   connect( mCardView, SIGNAL( addresseeDropped( QDropEvent* ) ),
00164            this, SIGNAL( dropped( QDropEvent* ) ) );
00165   connect( mCardView, SIGNAL( startAddresseeDrag() ),
00166            this, SIGNAL( startDrag() ) );
00167   connect( mCardView, SIGNAL( contextMenuRequested( CardViewItem*, const QPoint& ) ),
00168            this, SLOT( rmbClicked( CardViewItem*, const QPoint& ) ) );
00169 }
00170 
00171 KAddressBookCardView::~KAddressBookCardView()
00172 {
00173 }
00174 
00175 KABC::Field *KAddressBookCardView::sortField() const
00176 {
00177   // we have hardcoded sorting, so we have to return a hardcoded field :(
00178   return KABC::Field::allFields()[ 0 ];
00179 }
00180 
00181 void KAddressBookCardView::readConfig( KConfig *config )
00182 {
00183   KAddressBookView::readConfig( config );
00184 
00185   // costum colors?
00186   if ( config->readBoolEntry( "EnableCustomColors", false ) ) {
00187     QPalette p( mCardView->palette() );
00188     QColor c = p.color( QPalette::Normal, QColorGroup::Base );
00189     p.setColor( QPalette::Normal, QColorGroup::Base, config->readColorEntry( "BackgroundColor", &c ) );
00190     c = p.color( QPalette::Normal, QColorGroup::Text );
00191     p.setColor( QPalette::Normal, QColorGroup::Text, config->readColorEntry( "TextColor", &c ) );
00192     c = p.color( QPalette::Normal, QColorGroup::Button );
00193     p.setColor( QPalette::Normal, QColorGroup::Button, config->readColorEntry( "HeaderColor", &c ) );
00194     c = p.color( QPalette::Normal, QColorGroup::ButtonText );
00195     p.setColor( QPalette::Normal, QColorGroup::ButtonText, config->readColorEntry( "HeaderTextColor", &c ) );
00196     c = p.color( QPalette::Normal, QColorGroup::Highlight );
00197     p.setColor( QPalette::Normal, QColorGroup::Highlight, config->readColorEntry( "HighlightColor", &c ) );
00198     c = p.color( QPalette::Normal, QColorGroup::HighlightedText );
00199     p.setColor( QPalette::Normal, QColorGroup::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   QFont 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, SIGNAL( executed( CardViewItem* ) ),
00231               this, SLOT( addresseeExecuted( CardViewItem* ) ) );
00232 
00233   if ( KABPrefs::instance()->honorSingleClick() )
00234     connect( mCardView, SIGNAL( executed( CardViewItem* ) ),
00235              this, SLOT( addresseeExecuted( CardViewItem* ) ) );
00236   else
00237     connect( mCardView, SIGNAL( doubleClicked( CardViewItem* ) ),
00238              this, SLOT( addresseeExecuted( CardViewItem* ) ) );
00239 }
00240 
00241 void KAddressBookCardView::writeConfig( KConfig *config )
00242 {
00243   config->writeEntry( "ItemWidth", mCardView->itemWidth() );
00244   KAddressBookView::writeConfig( config );
00245 }
00246 
00247 QStringList KAddressBookCardView::selectedUids()
00248 {
00249   QStringList 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 QString &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 KABC::Addressee::List addresseeList( addressees() );
00275     KABC::Addressee::List::ConstIterator it( addresseeList.begin() );
00276     const KABC::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( QString::null );
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 QString &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( QString::null );
00353 }
00354 
00355 void KAddressBookCardView::rmbClicked( CardViewItem*, const QPoint &point )
00356 {
00357   popup( point );
00358 }
00359 
00360 void KAddressBookCardView::scrollUp()
00361 {
00362   QApplication::postEvent( mCardView, new QKeyEvent( QEvent::KeyPress, Qt::Key_Up, 0, 0 ) );
00363 }
00364 
00365 void KAddressBookCardView::scrollDown()
00366 {
00367   QApplication::postEvent( mCardView, new QKeyEvent( QEvent::KeyPress, Qt::Key_Down, 0, 0 ) );
00368 }
00369 
00370 #include "kaddressbookcardview.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys