kaddressbook Library API Documentation

jumpbuttonbar.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 <qbuttongroup.h>
00026 #include <qevent.h>
00027 #include <qlayout.h>
00028 #include <qpushbutton.h>
00029 #include <qstring.h>
00030 #include <qstyle.h>
00031 
00032 #include <kabc/addressbook.h>
00033 #include <kabc/field.h>
00034 #include <kdebug.h>
00035 #include <kdialog.h>
00036 #include <klocale.h>
00037 
00038 #include "core.h"
00039 
00040 #include "jumpbuttonbar.h"
00041 
00042 class JumpButton : public QPushButton
00043 {
00044   public:
00045     JumpButton( const QString &firstChar, const QString &lastChar,
00046                 const QString &charRange, QWidget *parent );
00047     JumpButton( const QString &text, QWidget *parent );
00048 
00049     QString charRange() const { return mCharRange; }
00050 
00051   private:
00052     QString mCharRange;
00053 };
00054 
00055 JumpButton::JumpButton( const QString &firstChar, const QString &lastChar,
00056                         const QString &charRange, QWidget *parent )
00057   : QPushButton( "", parent ), mCharRange( charRange )
00058 {
00059   if ( !lastChar.isEmpty() )
00060     setText( QString( "%1 - %2" ).arg( firstChar.upper() ).arg( lastChar.upper() ) );
00061   else
00062     setText( firstChar.upper() );
00063 
00064   setToggleType( QButton::Toggle );
00065 }
00066 
00067 JumpButton::JumpButton( const QString &text, QWidget *parent )
00068   : QPushButton( text, parent ), mCharRange( "" )
00069 {
00070   setToggleType( QButton::Toggle );
00071 }
00072 
00073 JumpButtonBar::JumpButtonBar( KAB::Core *core, QWidget *parent, const char *name )
00074   : QWidget( parent, name ), mCore( core )
00075 {
00076   setMinimumSize( 1, 1 );
00077 
00078   QVBoxLayout *layout = new QVBoxLayout( this, 0, 0 );
00079   layout->setAlignment( Qt::AlignTop );
00080   layout->setAutoAdd( true );
00081   layout->setResizeMode( QLayout::FreeResize );
00082 
00083   mGroupBox = new QButtonGroup( 1, Qt::Horizontal, this );
00084   mGroupBox->layout()->setSpacing( 0 );
00085   mGroupBox->layout()->setMargin( 0 );
00086   mGroupBox->setFrameStyle( QFrame::NoFrame );
00087   mGroupBox->setExclusive( true );
00088 }
00089 
00090 JumpButtonBar::~JumpButtonBar()
00091 {
00092 }
00093 
00094 QSizePolicy JumpButtonBar::sizePolicy() const
00095 {
00096   return QSizePolicy( QSizePolicy::Maximum, QSizePolicy::Minimum,
00097                       QSizePolicy::Vertically );
00098 }
00099 
00100 void JumpButtonBar::updateButtons()
00101 {
00102   int currentButton = mGroupBox->selectedId();
00103 
00104   // the easiest way to remove all buttons ;)
00105   mButtons.setAutoDelete( true );
00106   mButtons.clear();
00107   mButtons.setAutoDelete( false );
00108 
00109   QStringList characters;
00110 
00111   // calculate how many buttons are possible
00112   QFontMetrics fm = fontMetrics();
00113   QPushButton *btn = new QPushButton( "", this );
00114   btn->hide();
00115   QSize buttonSize = style().sizeFromContents( QStyle::CT_PushButton, btn,
00116                      fm.size( ShowPrefix, "X - X") ).
00117                      expandedTo( QApplication::globalStrut() );
00118   delete btn;
00119 
00120   mAllButton = new JumpButton( i18n( "All" ), mGroupBox );
00121   connect( mAllButton, SIGNAL( clicked() ), this, SLOT( reset() ) );
00122   mButtons.append( mAllButton );
00123   mAllButton->show();
00124 
00125   int buttonHeight = buttonSize.height() + 12;
00126   uint possibleButtons = (height() / buttonHeight) - 1;
00127 
00128   QString character;
00129   KABC::AddressBook *ab = mCore->addressBook();
00130   KABC::AddressBook::Iterator it;
00131   for ( it = ab->begin(); it != ab->end(); ++it ) {
00132     KABC::Field *field = 0;
00133     field = mCore->currentSortField();
00134     if ( field ) {
00135       setEnabled( true );
00136       if ( !field->value( *it ).isEmpty() )
00137         character = field->value( *it )[ 0 ].lower();
00138     } else {
00139       setEnabled( false );
00140       return;
00141     }
00142 
00143     if ( !character.isEmpty() && !characters.contains( character ) )
00144       characters.append( character );
00145   }
00146 
00147   sortListLocaleAware( characters );
00148 
00149   if ( characters.count() <= possibleButtons ) {
00150     // at first the easy case: all buttons fits in window
00151     for ( uint i = 0; i < characters.count(); ++i ) {
00152       JumpButton *button = new JumpButton( characters[ i ], QString::null,
00153                                            characters[ i ], mGroupBox );
00154       connect( button, SIGNAL( clicked() ), this, SLOT( letterClicked() ) );
00155       mButtons.append( button );
00156       button->show();
00157     }
00158   } else {
00159     if ( possibleButtons == 0 ) // to avoid crashes on startup
00160       return;
00161     int offset = characters.count() / possibleButtons;
00162     int odd = characters.count() % possibleButtons;
00163     if ( odd )
00164       offset++;
00165 
00166     int current = 0;
00167     for ( uint i = 0; i < possibleButtons; ++i ) {
00168       if ( characters.count() - current == 0 )
00169         continue;
00170       if ( characters.count() - current <= possibleButtons - i ) {
00171         JumpButton *button = new JumpButton( characters[ current ],
00172                                              QString::null,
00173                                              characters[ current ], mGroupBox );
00174         connect( button, SIGNAL( clicked() ), this, SLOT( letterClicked() ) );
00175         mButtons.append( button );
00176         button->show();
00177         current++;
00178       } else {
00179         int pos = ( current + offset >= (int)characters.count() ?
00180                     characters.count() - 1 : current + offset - 1 );
00181         QString range;
00182         for ( int j = current; j < pos + 1; ++j )
00183           range.append( characters[ j ] );
00184         JumpButton *button = new JumpButton( characters[ current ],
00185                                              characters[ pos ], range, mGroupBox );
00186         connect( button, SIGNAL( clicked() ), this, SLOT( letterClicked() ) );
00187         mButtons.append( button );
00188         button->show();
00189         current = ( i + 1 ) * offset;
00190       }
00191     }
00192   }
00193 
00194   if ( currentButton != -1 )
00195     mGroupBox->setButton( currentButton );
00196   else
00197     mGroupBox->setButton( 0 );
00198 }
00199 
00200 void JumpButtonBar::reset()
00201 {
00202   mGroupBox->setButton( 0 );
00203 
00204   QStringList list;
00205   list.append( "" );
00206   emit jumpToLetter( list );
00207 }
00208 
00209 void JumpButtonBar::letterClicked()
00210 {
00211   JumpButton *button = (JumpButton*)sender();
00212   QString characters = button->charRange();
00213 
00214   QStringList charList;
00215   for ( uint i = 0; i < characters.length(); ++i )
00216     charList.append( QString( characters[ i ] ) );
00217 
00218   emit jumpToLetter( charList );
00219 }
00220 
00221 void JumpButtonBar::resizeEvent( QResizeEvent* )
00222 {
00223   updateButtons();
00224 }
00225 
00226 class SortContainer
00227 {
00228   public:
00229     SortContainer() {}
00230     SortContainer( const QString &string )
00231       : mString( string )
00232     {
00233     }
00234 
00235     bool operator< ( const SortContainer &cnt )
00236     {
00237       return ( QString::localeAwareCompare( mString, cnt.mString ) < 0 );
00238     }
00239 
00240     QString data() const
00241     {
00242       return mString;
00243     }
00244 
00245   private:
00246     QString mString;
00247 };
00248 
00249 void JumpButtonBar::sortListLocaleAware( QStringList &list )
00250 {
00251   QValueList<SortContainer> sortList;
00252 
00253   QStringList::ConstIterator it;
00254   for ( it = list.begin(); it != list.end(); ++it )
00255     sortList.append( SortContainer( *it ) );
00256 
00257   qHeapSort( sortList );
00258   list.clear();
00259 
00260   QValueList<SortContainer>::Iterator sortIt;
00261   for ( sortIt = sortList.begin(); sortIt != sortList.end(); ++sortIt )
00262     list.append( (*sortIt).data() );
00263 }
00264 
00265 #include "jumpbuttonbar.moc"
KDE Logo
This file is part of the documentation for kaddressbook Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Apr 4 04:47:50 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003