00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00105 mButtons.setAutoDelete( true );
00106 mButtons.clear();
00107 mButtons.setAutoDelete( false );
00108
00109 QStringList characters;
00110
00111
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
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 )
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"