addresseelist.cpp

00001 /*
00002     This file is part of libkabc.
00003     Copyright (c) 2002 Jost Schenck <jost@schenck.de>
00004                   2003 Tobias Koenig <tokoe@kde.org>
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public License
00017     along with this library; see the file COPYING.LIB.  If not, write to
00018     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019     Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include <kdebug.h>
00023 
00024 #include "addresseelist.h"
00025 
00026 #include "field.h"
00027 #include "sortmode.h"
00028 
00029 using namespace KABC;
00030 
00031 //
00032 //
00033 // Traits
00034 //
00035 //
00036 
00037 bool SortingTraits::Uid::eq( const Addressee &a1, const Addressee &a2 )
00038 {
00039   // locale awareness doesn't make sense sorting ids
00040   return ( QString::compare( a1.uid(), a2.uid() ) == 0 );
00041 }
00042 
00043 bool SortingTraits::Uid::lt( const Addressee &a1, const Addressee &a2 )
00044 {
00045   // locale awareness doesn't make sense sorting ids
00046   return ( QString::compare( a1.uid(), a2.uid() ) < 0 );
00047 }
00048 
00049 bool SortingTraits::Name::eq( const Addressee &a1, const Addressee &a2 )
00050 {
00051   return ( QString::localeAwareCompare( a1.name(), a2.name() ) == 0 );
00052 }
00053 
00054 bool SortingTraits::Name::lt( const Addressee &a1, const Addressee &a2 )
00055 {
00056   return ( QString::localeAwareCompare( a1.name(), a2.name() ) < 0 );
00057 }
00058 
00059 bool SortingTraits::FormattedName::eq( const Addressee &a1, const Addressee &a2 )
00060 {
00061   return ( QString::localeAwareCompare( a1.formattedName(), a2.formattedName() ) == 0 );
00062 }
00063 
00064 bool SortingTraits::FormattedName::lt( const Addressee &a1, const Addressee &a2 )
00065 {
00066   return ( QString::localeAwareCompare( a1.formattedName(), a2.formattedName() ) < 0 );
00067 }
00068 
00069 bool SortingTraits::FamilyName::eq( const Addressee &a1, const Addressee &a2 )
00070 {
00071   return ( QString::localeAwareCompare( a1.familyName(), a2.familyName() ) == 0
00072            && QString::localeAwareCompare( a1.givenName(), a2.givenName() ) == 0 );
00073 }
00074 
00075 bool SortingTraits::FamilyName::lt( const Addressee &a1, const Addressee &a2 )
00076 {
00077   int family = QString::localeAwareCompare( a1.familyName(), a2.familyName() );
00078   if ( 0 == family ) {
00079     return ( QString::localeAwareCompare( a1.givenName(), a2.givenName() ) < 0 );
00080   } else {
00081     return family < 0;
00082   }
00083 }
00084 
00085 bool SortingTraits::GivenName::eq( const Addressee &a1, const Addressee &a2 )
00086 {
00087   return ( QString::localeAwareCompare( a1.givenName(), a2.givenName() ) == 0
00088            && QString::localeAwareCompare( a1.familyName(), a2.familyName() ) == 0 );
00089 }
00090 
00091 bool SortingTraits::GivenName::lt( const Addressee &a1, const Addressee &a2 )
00092 {
00093   int given = QString::localeAwareCompare( a1.givenName(), a2.givenName() );
00094   if ( 0 == given ) {
00095     return ( QString::localeAwareCompare( a1.familyName(), a2.familyName() ) < 0 );
00096   } else {
00097     return given < 0;
00098   }
00099 }
00100 
00101 //
00102 //
00103 // AddresseeList
00104 //
00105 //
00106 
00107 static Field *sActiveField=0;
00108 
00109 AddresseeList::AddresseeList()
00110   : QValueList<Addressee>()
00111 {
00112   mReverseSorting = false;
00113   mActiveSortingCriterion = FormattedName;
00114 }
00115 
00116 AddresseeList::~AddresseeList()
00117 {
00118 }
00119 
00120 AddresseeList::AddresseeList( const AddresseeList &l )
00121   : QValueList<Addressee>( l )
00122 {
00123   mReverseSorting = l.reverseSorting();
00124   mActiveSortingCriterion = l.sortingCriterion();
00125 }
00126 
00127 AddresseeList::AddresseeList( const QValueList<Addressee> &l )
00128   : QValueList<Addressee>( l )
00129 {
00130   mReverseSorting = false;
00131 }
00132 
00133 void AddresseeList::dump() const
00134 {
00135   kdDebug(5700) << "AddresseeList {" << endl;
00136   kdDebug(5700) << "reverse order: " << ( mReverseSorting ? "true" : "false" ) << endl;
00137 
00138   QString crit;
00139   if ( Uid == mActiveSortingCriterion ) {
00140     crit = "Uid";
00141   } else if ( Name == mActiveSortingCriterion ) {
00142     crit = "Name";
00143   } else if ( FormattedName == mActiveSortingCriterion ) {
00144     crit = "FormattedName";
00145   } else if ( FamilyName == mActiveSortingCriterion ) {
00146     crit = "FamilyName";
00147   } else if ( GivenName == mActiveSortingCriterion ) {
00148     crit = "GivenName";
00149   } else {
00150     crit = "unknown -- update dump method";
00151   }
00152 
00153   kdDebug(5700) << "sorting criterion: " << crit << endl;
00154 
00155   for ( const_iterator it = begin(); it != end(); ++it ) {
00156     (*it).dump();
00157   }
00158 
00159   kdDebug(5700) << "}" << endl;
00160 }
00161 
00162 void AddresseeList::sortBy( SortingCriterion c )
00163 {
00164   mActiveSortingCriterion = c;
00165   if ( Uid == c ) {
00166     sortByTrait<SortingTraits::Uid>();
00167   } else if ( Name == c ) {
00168     sortByTrait<SortingTraits::Name>();
00169   } else if ( FormattedName == c ) {
00170     sortByTrait<SortingTraits::FormattedName>();
00171   } else if ( FamilyName == c ) {
00172     sortByTrait<SortingTraits::FamilyName>();
00173   } else if ( GivenName==c ) {
00174     sortByTrait<SortingTraits::GivenName>();
00175   } else {
00176     kdError(5700) << "AddresseeList sorting criterion passed for which a trait is not known. No sorting done." << endl;
00177   }
00178 }
00179 
00180 void AddresseeList::sort()
00181 {
00182   sortBy( mActiveSortingCriterion );
00183 }
00184 
00185 template<class Trait>
00186 void AddresseeList::sortByTrait()
00187 {
00188   // FIXME: better sorting algorithm, bubblesort is not acceptable for larger lists.
00189   //
00190   // for i := 1 to n - 1
00191   //   do for j := 1 to n - i
00192   //     do if A[j] > A[j+1]
00193   //       then temp :=  A[j]
00194   //         A[j] := A[j + 1]
00195   //         A[j + 1 ] := temp
00196 
00197   iterator i1 = begin();
00198   iterator endIt = end();
00199   --endIt;
00200   if ( i1 == endIt ) // don't need sorting
00201     return;
00202 
00203   iterator i2 = endIt;
00204   while( i1 != endIt ) {
00205     iterator j1 = begin();
00206     iterator j2 = j1;
00207     ++j2;
00208     while( j1 != i2 ) {
00209       if ( !mReverseSorting && Trait::lt( *j2, *j1 )
00210            || mReverseSorting && Trait::lt( *j1, *j2 ) ) {
00211         qSwap( *j1, *j2 );
00212       }
00213       ++j1;
00214       ++j2;
00215     }
00216     ++i1;
00217     --i2;
00218   }
00219 }
00220 
00221 void AddresseeList::sortByField( Field *field )
00222 {
00223   if ( !field ) {
00224     kdWarning(5700) << "sortByField called with no active sort field" << endl;
00225     return;
00226   }
00227 
00228   sActiveField = field;
00229 
00230   if ( count() == 0 )
00231     return;
00232 
00233   KABC::FieldSortMode *mode = new KABC::FieldSortMode( sActiveField, !mReverseSorting );
00234 
00235   KABC::Addressee::setSortMode( mode );
00236   qHeapSort( *this );
00237   KABC::Addressee::setSortMode( 0 );
00238 
00239   delete mode;
00240 }
00241 
00242 void AddresseeList::sortByMode( SortMode *mode )
00243 {
00244   if ( count() == 0 )
00245     return;
00246 
00247   KABC::Addressee::setSortMode( mode );
00248   qHeapSort( *this );
00249   KABC::Addressee::setSortMode( 0 );
00250 }
00251 
00252 Field*
00253 AddresseeList::sortingField() const
00254 {
00255   return sActiveField;
00256 }
KDE Home | KDE Accessibility Home | Description of Access Keys