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