author | zautrix <zautrix> | 2004-06-26 19:01:18 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-06-26 19:01:18 (UTC) |
commit | b9aad1f15dc600e4dbe4c62d3fcced6363188ba3 (patch) (unidiff) | |
tree | 2c3d4004fb21c72cba65793859f9bcd8ffd3a49c /kabc/addresseelist.cpp | |
download | kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.zip kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.tar.gz kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.tar.bz2 |
Initial revision
-rw-r--r-- | kabc/addresseelist.cpp | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/kabc/addresseelist.cpp b/kabc/addresseelist.cpp new file mode 100644 index 0000000..097e162 --- a/dev/null +++ b/kabc/addresseelist.cpp | |||
@@ -0,0 +1,292 @@ | |||
1 | /* | ||
2 | This file is part of libkabc. | ||
3 | Copyright (c) 2002 Jost Schenck <jost@schenck.de> | ||
4 | 2003 Tobias Koenig <tokoe@kde.org> | ||
5 | |||
6 | This library is free software; you can redistribute it and/or | ||
7 | modify it under the terms of the GNU Library General Public | ||
8 | License as published by the Free Software Foundation; either | ||
9 | version 2 of the License, or (at your option) any later version. | ||
10 | |||
11 | This library is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | Library General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU Library General Public License | ||
17 | along with this library; see the file COPYING.LIB. If not, write to | ||
18 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
19 | Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | Enhanced Version of the file for platform independent KDE tools. | ||
24 | Copyright (c) 2004 Ulf Schenk | ||
25 | |||
26 | $Id$ | ||
27 | */ | ||
28 | |||
29 | #include <kdebug.h> | ||
30 | //US | ||
31 | #include <qtl.h> | ||
32 | |||
33 | |||
34 | #include "addresseelist.h" | ||
35 | #include "field.h" | ||
36 | |||
37 | using namespace KABC; | ||
38 | |||
39 | // | ||
40 | // | ||
41 | // Traits | ||
42 | // | ||
43 | // | ||
44 | |||
45 | bool SortingTraits::Uid::eq( const Addressee &a1, const Addressee &a2 ) | ||
46 | { | ||
47 | // locale awareness doesn't make sense sorting ids | ||
48 | return ( QString::compare( a1.uid(), a2.uid() ) == 0 ); | ||
49 | } | ||
50 | |||
51 | bool SortingTraits::Uid::lt( const Addressee &a1, const Addressee &a2 ) | ||
52 | { | ||
53 | // locale awareness doesn't make sense sorting ids | ||
54 | return ( QString::compare( a1.uid(), a2.uid() ) < 0 ); | ||
55 | } | ||
56 | |||
57 | bool SortingTraits::Name::eq( const Addressee &a1, const Addressee &a2 ) | ||
58 | { | ||
59 | //US QString::localeAwareCompare is not available in my distribution. Redefine it to compare | ||
60 | return ( QString::compare( a1.name(), a2.name() ) == 0 ); | ||
61 | } | ||
62 | |||
63 | bool SortingTraits::Name::lt( const Addressee &a1, const Addressee &a2 ) | ||
64 | { | ||
65 | //US QString::localeAwareCompare is not available in my distribution. Redefine it to compare | ||
66 | return ( QString::compare( a1.name(), a2.name() ) < 0 ); | ||
67 | } | ||
68 | |||
69 | bool SortingTraits::FormattedName::eq( const Addressee &a1, const Addressee &a2 ) | ||
70 | { | ||
71 | //US QString::localeAwareCompare is not available in my distribution. Redefine it to compare | ||
72 | return ( QString::compare( a1.formattedName(), a2.formattedName() ) == 0 ); | ||
73 | } | ||
74 | |||
75 | bool SortingTraits::FormattedName::lt( const Addressee &a1, const Addressee &a2 ) | ||
76 | { | ||
77 | //US QString::localeAwareCompare is not available in my distribution. Redefine it to compare | ||
78 | return ( QString::compare( a1.formattedName(), a2.formattedName() ) < 0 ); | ||
79 | } | ||
80 | |||
81 | bool SortingTraits::FamilyName::eq( const Addressee &a1, const Addressee &a2 ) | ||
82 | { | ||
83 | //US QString::localeAwareCompare is not available in my distribution. Redefine it to compare | ||
84 | return ( QString::compare( a1.familyName(), a2.familyName() ) == 0 | ||
85 | && QString::compare( a1.givenName(), a2.givenName() ) == 0 ); | ||
86 | } | ||
87 | |||
88 | bool SortingTraits::FamilyName::lt( const Addressee &a1, const Addressee &a2 ) | ||
89 | { | ||
90 | //US QString::localeAwareCompare is not available in my distribution. Redefine it to compare | ||
91 | int family = QString::compare( a1.familyName(), a2.familyName() ); | ||
92 | if ( 0 == family ) { | ||
93 | return ( QString::compare( a1.givenName(), a2.givenName() ) < 0 ); | ||
94 | } else { | ||
95 | return family < 0; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | bool SortingTraits::GivenName::eq( const Addressee &a1, const Addressee &a2 ) | ||
100 | { | ||
101 | //US QString::localeAwareCompare is not available in my distribution. Redefine it to compare | ||
102 | return ( QString::compare( a1.givenName(), a2.givenName() ) == 0 | ||
103 | && QString::compare( a1.familyName(), a2.familyName() ) == 0 ); | ||
104 | } | ||
105 | |||
106 | bool SortingTraits::GivenName::lt( const Addressee &a1, const Addressee &a2 ) | ||
107 | { | ||
108 | //US QString::localeAwareCompare is not available in my distribution. Redefine it to compare | ||
109 | int given = QString::compare( a1.givenName(), a2.givenName() ); | ||
110 | if ( 0 == given ) { | ||
111 | return ( QString::compare( a1.familyName(), a2.familyName() ) < 0 ); | ||
112 | } else { | ||
113 | return given < 0; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | // | ||
118 | // | ||
119 | // AddresseeList | ||
120 | // | ||
121 | // | ||
122 | |||
123 | AddresseeList::AddresseeList() | ||
124 | : QValueList<Addressee>() | ||
125 | { | ||
126 | mReverseSorting = false; | ||
127 | mActiveSortingCriterion = FormattedName; | ||
128 | mActiveSortingField = 0; | ||
129 | } | ||
130 | |||
131 | AddresseeList::~AddresseeList() | ||
132 | { | ||
133 | } | ||
134 | |||
135 | AddresseeList::AddresseeList( const AddresseeList &l ) | ||
136 | : QValueList<Addressee>( l ) | ||
137 | { | ||
138 | mReverseSorting = l.reverseSorting(); | ||
139 | mActiveSortingCriterion = l.sortingCriterion(); | ||
140 | } | ||
141 | |||
142 | AddresseeList::AddresseeList( const QValueList<Addressee> &l ) | ||
143 | : QValueList<Addressee>( l ) | ||
144 | { | ||
145 | mReverseSorting = false; | ||
146 | } | ||
147 | |||
148 | void AddresseeList::dump() const | ||
149 | { | ||
150 | kdDebug(5700) << "AddresseeList {" << endl; | ||
151 | kdDebug(5700) << "reverse order: " << ( mReverseSorting ? "true" : "false" ) << endl; | ||
152 | |||
153 | QString crit; | ||
154 | if ( Uid == mActiveSortingCriterion ) { | ||
155 | crit = "Uid"; | ||
156 | } else if ( Name == mActiveSortingCriterion ) { | ||
157 | crit = "Name"; | ||
158 | } else if ( FormattedName == mActiveSortingCriterion ) { | ||
159 | crit = "FormattedName"; | ||
160 | } else if ( FamilyName == mActiveSortingCriterion ) { | ||
161 | crit = "FamilyName"; | ||
162 | } else if ( GivenName == mActiveSortingCriterion ) { | ||
163 | crit = "GivenName"; | ||
164 | } else { | ||
165 | crit = "unknown -- update dump method"; | ||
166 | } | ||
167 | |||
168 | kdDebug(5700) << "sorting criterion: " << crit << endl; | ||
169 | |||
170 | //US | ||
171 | //US for ( const_iterator it = begin(); it != end(); ++it ) | ||
172 | for ( ConstIterator it = begin(); it != end(); ++it ) | ||
173 | (*it).dump(); | ||
174 | |||
175 | kdDebug(5700) << "}" << endl; | ||
176 | } | ||
177 | |||
178 | void AddresseeList::sortBy( SortingCriterion c ) | ||
179 | { | ||
180 | mActiveSortingCriterion = c; | ||
181 | if ( Uid == c ) { | ||
182 | sortByTrait<SortingTraits::Uid>(); | ||
183 | } else if ( Name == c ) { | ||
184 | sortByTrait<SortingTraits::Name>(); | ||
185 | } else if ( FormattedName == c ) { | ||
186 | sortByTrait<SortingTraits::FormattedName>(); | ||
187 | } else if ( FamilyName == c ) { | ||
188 | sortByTrait<SortingTraits::FamilyName>(); | ||
189 | } else if ( GivenName==c ) { | ||
190 | sortByTrait<SortingTraits::GivenName>(); | ||
191 | } else { | ||
192 | kdError(5700) << "AddresseeList sorting criterion passed for which a trait is not known. No sorting done." << endl; | ||
193 | } | ||
194 | } | ||
195 | |||
196 | void AddresseeList::sort() | ||
197 | { | ||
198 | sortBy( mActiveSortingCriterion ); | ||
199 | } | ||
200 | |||
201 | template<class Trait> | ||
202 | void AddresseeList::sortByTrait() | ||
203 | { | ||
204 | // FIXME: better sorting algorithm, bubblesort is not acceptable for larger lists. | ||
205 | // | ||
206 | // for i := 1 to n - 1 | ||
207 | // do for j := 1 to n - i | ||
208 | // do if A[j] > A[j+1] | ||
209 | // then temp := A[j] | ||
210 | // A[j] := A[j + 1] | ||
211 | // A[j + 1 ] := temp | ||
212 | |||
213 | //US iterator i1 = begin(); | ||
214 | Iterator i1 = begin(); | ||
215 | //US iterator endIt = end(); | ||
216 | Iterator endIt = end(); | ||
217 | --endIt; | ||
218 | if ( i1 == endIt ) // don't need sorting | ||
219 | return; | ||
220 | |||
221 | //US iterator i2 = endIt; | ||
222 | Iterator i2 = endIt; | ||
223 | while( i1 != endIt ) { | ||
224 | //US iterator j1 = begin(); | ||
225 | Iterator j1 = begin(); | ||
226 | //US iterator j2 = j1; | ||
227 | Iterator j2 = j1; | ||
228 | ++j2; | ||
229 | while( j1 != i2 ) { | ||
230 | if ( !mReverseSorting && Trait::lt( *j2, *j1 ) | ||
231 | || mReverseSorting && Trait::lt( *j1, *j2 ) ) { | ||
232 | qSwap( *j1, *j2 ); | ||
233 | } | ||
234 | ++j1; | ||
235 | ++j2; | ||
236 | } | ||
237 | ++i1; | ||
238 | --i2; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | void AddresseeList::sortByField( Field *field ) | ||
243 | { | ||
244 | if ( field ) | ||
245 | mActiveSortingField = field; | ||
246 | |||
247 | if ( !mActiveSortingField ) { | ||
248 | kdWarning(5700) << "sortByField called with no active sort field" << endl; | ||
249 | return; | ||
250 | } | ||
251 | |||
252 | if ( count() == 0 ) | ||
253 | return; | ||
254 | |||
255 | quickSortByField( 0, count() - 1 ); | ||
256 | } | ||
257 | |||
258 | void AddresseeList::quickSortByField( int left, int right ) | ||
259 | { | ||
260 | int i = left; | ||
261 | int j = right; | ||
262 | int mid = ( left + right ) / 2; | ||
263 | |||
264 | //US iterator x = at( mid ); | ||
265 | ConstIterator x = at( mid ); | ||
266 | |||
267 | do { | ||
268 | if ( !mReverseSorting ) { | ||
269 | //US QString::localeAwareCompare was not available. Used compare instead. | ||
270 | while ( QString::compare( mActiveSortingField->value( *at( i ) ).upper(), mActiveSortingField->value( *x ).upper() ) < 0 ) | ||
271 | i++; | ||
272 | //US QString::localeAwareCompare was not available. Used compare instead. | ||
273 | while ( QString::compare( mActiveSortingField->value( *at( j ) ).upper(), mActiveSortingField->value( *x ).upper() ) > 0 ) | ||
274 | j--; | ||
275 | } else { | ||
276 | //US QString::localeAwareCompare was not available. Used compare instead. | ||
277 | while ( QString::compare( mActiveSortingField->value( *at( i ) ).upper(), mActiveSortingField->value( *x ).upper() ) > 0 ) | ||
278 | i++; | ||
279 | //US QString::localeAwareCompare was not available. Used compare instead. | ||
280 | while ( QString::compare( mActiveSortingField->value( *at( j ) ).upper(), mActiveSortingField->value( *x ).upper() ) < 0 ) | ||
281 | j--; | ||
282 | } | ||
283 | if ( i <= j ) { | ||
284 | qSwap( *at( i ), *at( j ) ); | ||
285 | i++; | ||
286 | j--; | ||
287 | } | ||
288 | } while ( i <= j ); | ||
289 | |||
290 | if ( left < j ) quickSortByField( left, j ); | ||
291 | if ( right > i ) quickSortByField( i, right ); | ||
292 | } | ||