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 QWidget *parent );
00047
00048 QString firstChar() const { return mChar; }
00049
00050 private:
00051 QString mChar;
00052 };
00053
00054 JumpButton::JumpButton( const QString &firstChar, const QString &lastChar,
00055 QWidget *parent )
00056 : QPushButton( "", parent ), mChar( firstChar )
00057 {
00058 setToggleButton( true );
00059 if ( !lastChar.isEmpty() )
00060 setText( QString( "%1 - %2" ).arg( firstChar.upper() ).arg( lastChar.upper() ) );
00061 else
00062 setText( firstChar.upper() );
00063 }
00064
00065 JumpButtonBar::JumpButtonBar( KAB::Core *core, QWidget *parent, const char *name )
00066 : QWidget( parent, name ), mCore( core )
00067 {
00068 setMinimumSize( 1, 1 );
00069
00070 QVBoxLayout *layout = new QVBoxLayout( this, 0, 0 );
00071 layout->setAlignment( Qt::AlignTop );
00072 layout->setAutoAdd( true );
00073 layout->setResizeMode( QLayout::FreeResize );
00074
00075 mGroupBox = new QButtonGroup( 1, Qt::Horizontal, this );
00076 mGroupBox->setExclusive( true );
00077 mGroupBox->layout()->setSpacing( 0 );
00078 mGroupBox->layout()->setMargin( 0 );
00079 mGroupBox->setFrameStyle( QFrame::NoFrame );
00080 }
00081
00082 JumpButtonBar::~JumpButtonBar()
00083 {
00084 }
00085
00086 void JumpButtonBar::updateButtons()
00087 {
00088 int currentButton = mGroupBox->selectedId();
00089
00090
00091 mButtons.setAutoDelete( true );
00092 mButtons.clear();
00093 mButtons.setAutoDelete( false );
00094
00095 QStringList characters;
00096
00097
00098 QFontMetrics fm = fontMetrics();
00099 QPushButton *btn = new QPushButton( "", this );
00100 btn->hide();
00101 QSize buttonSize = style().sizeFromContents( QStyle::CT_PushButton, btn,
00102 fm.size( ShowPrefix, "X - X") ).
00103 expandedTo( QApplication::globalStrut() );
00104 delete btn;
00105
00106 int buttonHeight = buttonSize.height() + 8;
00107 uint possibleButtons = (height() / buttonHeight) - 1;
00108
00109 QString character;
00110 KABC::AddressBook *ab = mCore->addressBook();
00111 KABC::AddressBook::Iterator it;
00112 for ( it = ab->begin(); it != ab->end(); ++it ) {
00113 KABC::Field *field = 0;
00114 field = mCore->currentSortField();
00115 if ( field ) {
00116 setEnabled( true );
00117 if ( !field->value( *it ).isEmpty() )
00118 character = field->value( *it )[ 0 ].lower();
00119 } else {
00120 setEnabled( false );
00121 return;
00122 }
00123
00124 if ( !character.isEmpty() && !characters.contains( character ) )
00125 characters.append( character );
00126 }
00127
00128 sortListLocaleAware( characters );
00129
00130 if ( characters.count() <= possibleButtons ) {
00131
00132 for ( uint i = 0; i < characters.count(); ++i ) {
00133 JumpButton *button = new JumpButton( characters[ i ], QString::null,
00134 mGroupBox );
00135 connect( button, SIGNAL( clicked() ), this, SLOT( letterClicked() ) );
00136 mButtons.append( button );
00137 button->show();
00138 }
00139 } else {
00140 if ( possibleButtons == 0 )
00141 return;
00142 int offset = characters.count() / possibleButtons;
00143 int odd = characters.count() % possibleButtons;
00144 if ( odd )
00145 offset++;
00146
00147 int current = 0;
00148 for ( uint i = 0; i < possibleButtons; ++i ) {
00149 if ( characters.count() - current == 0 )
00150 continue;
00151 if ( characters.count() - current <= possibleButtons - i ) {
00152 JumpButton *button = new JumpButton( characters[ current ],
00153 QString::null, mGroupBox );
00154 connect( button, SIGNAL( clicked() ), this, SLOT( letterClicked() ) );
00155 mButtons.append( button );
00156 button->show();
00157 current++;
00158 } else {
00159 int pos = ( current + offset >= (int)characters.count() ?
00160 characters.count() - 1 : current + offset - 1 );
00161 QString range;
00162 for ( int j = current; j < pos + 1; ++j )
00163 range.append( characters[ j ] );
00164 JumpButton *button = new JumpButton( characters[ current ],
00165 characters[ pos ], mGroupBox );
00166 connect( button, SIGNAL( clicked() ), this, SLOT( letterClicked() ) );
00167 mButtons.append( button );
00168 button->show();
00169 current = ( i + 1 ) * offset;
00170 }
00171 }
00172 }
00173
00174 if ( currentButton != -1 )
00175 mGroupBox->setButton( currentButton );
00176 else
00177 mGroupBox->setButton( 0 );
00178
00179 int maxWidth = 0;
00180 QPushButton *button;
00181 for ( button = mButtons.first(); button; button = mButtons.next() )
00182 maxWidth = QMAX( maxWidth, button->sizeHint().width() );
00183
00184 setFixedWidth( maxWidth );
00185 }
00186
00187 void JumpButtonBar::letterClicked()
00188 {
00189 JumpButton *button = (JumpButton*)sender();
00190 QString character = button->firstChar();
00191
00192 emit jumpToLetter( character );
00193 }
00194
00195 void JumpButtonBar::resizeEvent( QResizeEvent* )
00196 {
00197 updateButtons();
00198 }
00199
00200 class SortContainer
00201 {
00202 public:
00203 SortContainer() {}
00204 SortContainer( const QString &string )
00205 : mString( string )
00206 {
00207 }
00208
00209 bool operator< ( const SortContainer &cnt )
00210 {
00211 return ( QString::localeAwareCompare( mString, cnt.mString ) < 0 );
00212 }
00213
00214 QString data() const
00215 {
00216 return mString;
00217 }
00218
00219 private:
00220 QString mString;
00221 };
00222
00223 void JumpButtonBar::sortListLocaleAware( QStringList &list )
00224 {
00225 QValueList<SortContainer> sortList;
00226
00227 QStringList::ConstIterator it;
00228 for ( it = list.begin(); it != list.end(); ++it )
00229 sortList.append( SortContainer( *it ) );
00230
00231 qHeapSort( sortList );
00232 list.clear();
00233
00234 QValueList<SortContainer>::ConstIterator sortIt;
00235 for ( sortIt = sortList.begin(); sortIt != sortList.end(); ++sortIt )
00236 list.append( (*sortIt).data() );
00237 }
00238
00239 #include "jumpbuttonbar.moc"