/* This file is part of libtdeabc. Copyright (c) 2002 Jost Schenck 2003 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "addresseelist.h" #include "field.h" #include "sortmode.h" using namespace TDEABC; // // // Traits // // bool SortingTraits::Uid::eq( const Addressee &a1, const Addressee &a2 ) { // locale awareness doesn't make sense sorting ids return ( TQString::compare( a1.uid(), a2.uid() ) == 0 ); } bool SortingTraits::Uid::lt( const Addressee &a1, const Addressee &a2 ) { // locale awareness doesn't make sense sorting ids return ( TQString::compare( a1.uid(), a2.uid() ) < 0 ); } bool SortingTraits::Name::eq( const Addressee &a1, const Addressee &a2 ) { return ( TQString::localeAwareCompare( a1.name(), a2.name() ) == 0 ); } bool SortingTraits::Name::lt( const Addressee &a1, const Addressee &a2 ) { return ( TQString::localeAwareCompare( a1.name(), a2.name() ) < 0 ); } bool SortingTraits::FormattedName::eq( const Addressee &a1, const Addressee &a2 ) { return ( TQString::localeAwareCompare( a1.formattedName(), a2.formattedName() ) == 0 ); } bool SortingTraits::FormattedName::lt( const Addressee &a1, const Addressee &a2 ) { return ( TQString::localeAwareCompare( a1.formattedName(), a2.formattedName() ) < 0 ); } bool SortingTraits::FamilyName::eq( const Addressee &a1, const Addressee &a2 ) { return ( TQString::localeAwareCompare( a1.familyName(), a2.familyName() ) == 0 && TQString::localeAwareCompare( a1.givenName(), a2.givenName() ) == 0 ); } bool SortingTraits::FamilyName::lt( const Addressee &a1, const Addressee &a2 ) { int family = TQString::localeAwareCompare( a1.familyName(), a2.familyName() ); if ( 0 == family ) { return ( TQString::localeAwareCompare( a1.givenName(), a2.givenName() ) < 0 ); } else { return family < 0; } } bool SortingTraits::GivenName::eq( const Addressee &a1, const Addressee &a2 ) { return ( TQString::localeAwareCompare( a1.givenName(), a2.givenName() ) == 0 && TQString::localeAwareCompare( a1.familyName(), a2.familyName() ) == 0 ); } bool SortingTraits::GivenName::lt( const Addressee &a1, const Addressee &a2 ) { int given = TQString::localeAwareCompare( a1.givenName(), a2.givenName() ); if ( 0 == given ) { return ( TQString::localeAwareCompare( a1.familyName(), a2.familyName() ) < 0 ); } else { return given < 0; } } // // // AddresseeList // // static Field *sActiveField=0; AddresseeList::AddresseeList() : TQValueList() { mReverseSorting = false; mActiveSortingCriterion = FormattedName; } AddresseeList::~AddresseeList() { } AddresseeList::AddresseeList( const AddresseeList &l ) : TQValueList( l ) { mReverseSorting = l.reverseSorting(); mActiveSortingCriterion = l.sortingCriterion(); } AddresseeList::AddresseeList( const TQValueList &l ) : TQValueList( l ) { mReverseSorting = false; } void AddresseeList::dump() const { kdDebug(5700) << "AddresseeList {" << endl; kdDebug(5700) << "reverse order: " << ( mReverseSorting ? "true" : "false" ) << endl; TQString crit; if ( Uid == mActiveSortingCriterion ) { crit = "Uid"; } else if ( Name == mActiveSortingCriterion ) { crit = "Name"; } else if ( FormattedName == mActiveSortingCriterion ) { crit = "FormattedName"; } else if ( FamilyName == mActiveSortingCriterion ) { crit = "FamilyName"; } else if ( GivenName == mActiveSortingCriterion ) { crit = "GivenName"; } else { crit = "unknown -- update dump method"; } kdDebug(5700) << "sorting criterion: " << crit << endl; for ( const_iterator it = begin(); it != end(); ++it ) { (*it).dump(); } kdDebug(5700) << "}" << endl; } void AddresseeList::sortBy( SortingCriterion c ) { mActiveSortingCriterion = c; if ( Uid == c ) { sortByTrait(); } else if ( Name == c ) { sortByTrait(); } else if ( FormattedName == c ) { sortByTrait(); } else if ( FamilyName == c ) { sortByTrait(); } else if ( GivenName==c ) { sortByTrait(); } else { kdError(5700) << "AddresseeList sorting criterion passed for which a trait is not known. No sorting done." << endl; } } void AddresseeList::sort() { sortBy( mActiveSortingCriterion ); } template void AddresseeList::sortByTrait() { // FIXME: better sorting algorithm, bubblesort is not acceptable for larger lists. // // for i := 1 to n - 1 // do for j := 1 to n - i // do if A[j] > A[j+1] // then temp := A[j] // A[j] := A[j + 1] // A[j + 1 ] := temp iterator i1 = begin(); iterator endIt = end(); --endIt; if ( i1 == endIt ) // don't need sorting return; iterator i2 = endIt; while( i1 != endIt ) { iterator j1 = begin(); iterator j2 = j1; ++j2; while( j1 != i2 ) { if ( !mReverseSorting && Trait::lt( *j2, *j1 ) || mReverseSorting && Trait::lt( *j1, *j2 ) ) { tqSwap( *j1, *j2 ); } ++j1; ++j2; } ++i1; --i2; } } void AddresseeList::sortByField( Field *field ) { if ( !field ) { kdWarning(5700) << "sortByField called with no active sort field" << endl; return; } sActiveField = field; if ( count() == 0 ) return; TDEABC::FieldSortMode *mode = new TDEABC::FieldSortMode( sActiveField, !mReverseSorting ); TDEABC::Addressee::setSortMode( mode ); qHeapSort( *this ); TDEABC::Addressee::setSortMode( 0 ); delete mode; } void AddresseeList::sortByMode( SortMode *mode ) { if ( count() == 0 ) return; TDEABC::Addressee::setSortMode( mode ); qHeapSort( *this ); TDEABC::Addressee::setSortMode( 0 ); } Field* AddresseeList::sortingField() const { return sActiveField; }