summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/pim/addressbook/abtable.cpp1
1 files changed, 1 insertions, 0 deletions
diff --git a/core/pim/addressbook/abtable.cpp b/core/pim/addressbook/abtable.cpp
index 124ff6c..e9e6a0b 100644
--- a/core/pim/addressbook/abtable.cpp
+++ b/core/pim/addressbook/abtable.cpp
@@ -1,1200 +1,1201 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qt Palmtop Environment. 4** This file is part of Qt Palmtop Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#define QTOPIA_INTERNAL_CONTACT_MRE 21#define QTOPIA_INTERNAL_CONTACT_MRE
22 22
23#include <qpe/categoryselect.h> 23#include <qpe/categoryselect.h>
24#include <qpe/config.h> 24#include <qpe/config.h>
25#include <qpe/stringutil.h> 25#include <qpe/stringutil.h>
26#include <qpe/qcopenvelope_qws.h> 26#include <qpe/qcopenvelope_qws.h>
27 27
28#include <qasciidict.h> 28#include <qasciidict.h>
29#include <qdatetime.h> 29#include <qdatetime.h>
30#include <qfile.h> 30#include <qfile.h>
31#include <qregexp.h>
31 32
32#include "abtable.h" 33#include "abtable.h"
33 34
34#include <errno.h> 35#include <errno.h>
35#include <fcntl.h> 36#include <fcntl.h>
36#include <unistd.h> 37#include <unistd.h>
37#include <stdlib.h> 38#include <stdlib.h>
38 39
39#include <ctype.h> //toupper() for key hack 40#include <ctype.h> //toupper() for key hack
40 41
41static bool contactCompare( const Contact &cnt, const QRegExp &r, int category ); 42static bool contactCompare( const Contact &cnt, const QRegExp &r, int category );
42 43
43//### qtmail/addresslist.cpp hardcodes this filename as well 44//### qtmail/addresslist.cpp hardcodes this filename as well
44static QString journalFileName() 45static QString journalFileName()
45{ 46{
46 QString str = getenv("HOME"); 47 QString str = getenv("HOME");
47 str +="/.abjournal"; 48 str +="/.abjournal";
48 return str; 49 return str;
49} 50}
50 51
51 52
52 53
53/*! 54/*!
54 \class AbTableItem abtable.h 55 \class AbTableItem abtable.h
55 56
56 \brief QTableItem based class for showing a field of an entry 57 \brief QTableItem based class for showing a field of an entry
57*/ 58*/
58 59
59AbTableItem::AbTableItem( QTable *t, EditType et, const QString &s, 60AbTableItem::AbTableItem( QTable *t, EditType et, const QString &s,
60 const QString &secondSortKey) 61 const QString &secondSortKey)
61 : QTableItem( t, et, s ) 62 : QTableItem( t, et, s )
62{ 63{
63 // sortKey = s.lower() + QChar( '\0' ) + secondSortKey.lower(); 64 // sortKey = s.lower() + QChar( '\0' ) + secondSortKey.lower();
64 sortKey = Qtopia::buildSortKey( s, secondSortKey ); 65 sortKey = Qtopia::buildSortKey( s, secondSortKey );
65} 66}
66 67
67int AbTableItem::alignment() const 68int AbTableItem::alignment() const
68{ 69{
69 return AlignLeft|AlignVCenter; 70 return AlignLeft|AlignVCenter;
70} 71}
71 72
72QString AbTableItem::key() const 73QString AbTableItem::key() const
73{ 74{
74 return sortKey; 75 return sortKey;
75} 76}
76 77
77// A way to reset the item, without out doing a delete or a new... 78// A way to reset the item, without out doing a delete or a new...
78void AbTableItem::setItem( const QString &txt, const QString &secondKey ) 79void AbTableItem::setItem( const QString &txt, const QString &secondKey )
79{ 80{
80 setText( txt ); 81 setText( txt );
81 sortKey = Qtopia::buildSortKey( txt, secondKey ); 82 sortKey = Qtopia::buildSortKey( txt, secondKey );
82 83
83 // sortKey = txt.lower() + QChar( '\0' ) + secondKey.lower(); 84 // sortKey = txt.lower() + QChar( '\0' ) + secondKey.lower();
84} 85}
85 86
86/*! 87/*!
87 \class AbPickItem abtable.h 88 \class AbPickItem abtable.h
88 89
89 \brief QTableItem based class for showing slection of an entry 90 \brief QTableItem based class for showing slection of an entry
90*/ 91*/
91 92
92AbPickItem::AbPickItem( QTable *t ) : 93AbPickItem::AbPickItem( QTable *t ) :
93 QTableItem(t, WhenCurrent, "?") 94 QTableItem(t, WhenCurrent, "?")
94{ 95{
95} 96}
96 97
97QWidget *AbPickItem::createEditor() const 98QWidget *AbPickItem::createEditor() const
98{ 99{
99 QComboBox* combo = new QComboBox( table()->viewport() ); 100 QComboBox* combo = new QComboBox( table()->viewport() );
100 ( (AbPickItem*)this )->cb = combo; 101 ( (AbPickItem*)this )->cb = combo;
101 AbTable* t = static_cast<AbTable*>(table()); 102 AbTable* t = static_cast<AbTable*>(table());
102 QStringList c = t->choiceNames(); 103 QStringList c = t->choiceNames();
103 int cur = 0; 104 int cur = 0;
104 for (QStringList::ConstIterator it = c.begin(); it!=c.end(); ++it) { 105 for (QStringList::ConstIterator it = c.begin(); it!=c.end(); ++it) {
105 if ( *it == text() ) 106 if ( *it == text() )
106 cur = combo->count(); 107 cur = combo->count();
107 combo->insertItem(*it); 108 combo->insertItem(*it);
108 } 109 }
109 combo->setCurrentItem(cur); 110 combo->setCurrentItem(cur);
110 return combo; 111 return combo;
111} 112}
112 113
113void AbPickItem::setContentFromEditor( QWidget *w ) 114void AbPickItem::setContentFromEditor( QWidget *w )
114{ 115{
115 if ( w->inherits("QComboBox") ) 116 if ( w->inherits("QComboBox") )
116 setText( ( (QComboBox*)w )->currentText() ); 117 setText( ( (QComboBox*)w )->currentText() );
117 else 118 else
118 QTableItem::setContentFromEditor( w ); 119 QTableItem::setContentFromEditor( w );
119} 120}
120 121
121/*! 122/*!
122 \class AbTable abtable.h 123 \class AbTable abtable.h
123 124
124 \brief QTable based class for showing a list of entries 125 \brief QTable based class for showing a list of entries
125*/ 126*/
126 127
127AbTable::AbTable( const QValueList<int> *order, QWidget *parent, const char *name ) 128AbTable::AbTable( const QValueList<int> *order, QWidget *parent, const char *name )
128// #ifdef QT_QTABLE_NOHEADER_CONSTRUCTOR 129// #ifdef QT_QTABLE_NOHEADER_CONSTRUCTOR
129// : QTable( 0, 0, parent, name, TRUE ), 130// : QTable( 0, 0, parent, name, TRUE ),
130// #else 131// #else
131 : QTable( parent, name ), 132 : QTable( parent, name ),
132// #endif 133// #endif
133 lastSortCol( -1 ), 134 lastSortCol( -1 ),
134 asc( TRUE ), 135 asc( TRUE ),
135 intFields( order ), 136 intFields( order ),
136 currFindRow( -2 ), 137 currFindRow( -2 ),
137 mCat( 0 ) 138 mCat( 0 )
138{ 139{
139 mCat.load( categoryFileName() ); 140 mCat.load( categoryFileName() );
140 setSelectionMode( NoSelection ); 141 setSelectionMode( NoSelection );
141 init(); 142 init();
142 setSorting( TRUE ); 143 setSorting( TRUE );
143 connect( this, SIGNAL(clicked(int,int,int,const QPoint &)), 144 connect( this, SIGNAL(clicked(int,int,int,const QPoint &)),
144 this, SLOT(itemClicked(int,int)) ); 145 this, SLOT(itemClicked(int,int)) );
145} 146}
146 147
147AbTable::~AbTable() 148AbTable::~AbTable()
148{ 149{
149} 150}
150 151
151void AbTable::init() 152void AbTable::init()
152{ 153{
153 showChar = '\0'; 154 showChar = '\0';
154 setNumRows( 0 ); 155 setNumRows( 0 );
155 setNumCols( 2 ); 156 setNumCols( 2 );
156 157
157 horizontalHeader()->setLabel( 0, tr( "Full Name" )); 158 horizontalHeader()->setLabel( 0, tr( "Full Name" ));
158 horizontalHeader()->setLabel( 1, tr( "Contact" )); 159 horizontalHeader()->setLabel( 1, tr( "Contact" ));
159 setLeftMargin( 0 ); 160 setLeftMargin( 0 );
160 verticalHeader()->hide(); 161 verticalHeader()->hide();
161} 162}
162 163
163void AbTable::columnClicked( int col ) 164void AbTable::columnClicked( int col )
164{ 165{
165 if ( !sorting() ) 166 if ( !sorting() )
166 return; 167 return;
167 168
168 if ( lastSortCol == -1 ) 169 if ( lastSortCol == -1 )
169 lastSortCol = col; 170 lastSortCol = col;
170 171
171 if ( col == lastSortCol ) { 172 if ( col == lastSortCol ) {
172 asc = !asc; 173 asc = !asc;
173 } else { 174 } else {
174 lastSortCol = col; 175 lastSortCol = col;
175 asc = TRUE; 176 asc = TRUE;
176 } 177 }
177 resort(); 178 resort();
178} 179}
179 180
180void AbTable::resort() 181void AbTable::resort()
181{ 182{
182 if ( sorting() ) { 183 if ( sorting() ) {
183 if ( lastSortCol == -1 ) 184 if ( lastSortCol == -1 )
184 lastSortCol = 0; 185 lastSortCol = 0;
185 sortColumn( lastSortCol, asc, TRUE ); 186 sortColumn( lastSortCol, asc, TRUE );
186 updateVisible(); 187 updateVisible();
187 } 188 }
188} 189}
189 190
190Contact AbTable::currentEntry() 191Contact AbTable::currentEntry()
191{ 192{
192 Contact cnt; 193 Contact cnt;
193 AbTableItem *abItem; 194 AbTableItem *abItem;
194 abItem = static_cast<AbTableItem*>(item( currentRow(), 0 )); 195 abItem = static_cast<AbTableItem*>(item( currentRow(), 0 ));
195 if ( abItem ) { 196 if ( abItem ) {
196 cnt = contactList[abItem]; 197 cnt = contactList[abItem];
197 } 198 }
198 return cnt; 199 return cnt;
199} 200}
200 201
201void AbTable::replaceCurrentEntry( const Contact &newContact ) 202void AbTable::replaceCurrentEntry( const Contact &newContact )
202{ 203{
203 int row = currentRow(); 204 int row = currentRow();
204 updateJournal( newContact, Contact::ACTION_REPLACE, row ); 205 updateJournal( newContact, Contact::ACTION_REPLACE, row );
205 updateVisible(); 206 updateVisible();
206 207
207 journalFreeReplace( newContact, row ); 208 journalFreeReplace( newContact, row );
208} 209}
209 210
210void AbTable::deleteCurrentEntry() 211void AbTable::deleteCurrentEntry()
211{ 212{
212 int row = currentRow(); 213 int row = currentRow();
213 AbTableItem *abItem; 214 AbTableItem *abItem;
214 abItem = static_cast<AbTableItem*>(item( row, 0 )); 215 abItem = static_cast<AbTableItem*>(item( row, 0 ));
215 Contact oldContact; 216 Contact oldContact;
216 oldContact = contactList[abItem]; 217 oldContact = contactList[abItem];
217 updateJournal( oldContact, Contact::ACTION_REMOVE, row ); 218 updateJournal( oldContact, Contact::ACTION_REMOVE, row );
218 219
219 // a little wasteful, but it ensure's there is only one place 220 // a little wasteful, but it ensure's there is only one place
220 // where we delete. 221 // where we delete.
221 journalFreeRemove( row ); 222 journalFreeRemove( row );
222 updateVisible(); 223 updateVisible();
223 224
224 if ( numRows() == 0 ) 225 if ( numRows() == 0 )
225 emit empty( TRUE ); 226 emit empty( TRUE );
226} 227}
227 228
228void AbTable::clear() 229void AbTable::clear()
229{ 230{
230 contactList.clear(); 231 contactList.clear();
231 for ( int r = 0; r < numRows(); ++r ) { 232 for ( int r = 0; r < numRows(); ++r ) {
232 for ( int c = 0; c < numCols(); ++c ) { 233 for ( int c = 0; c < numCols(); ++c ) {
233 if ( cellWidget( r, c ) ) 234 if ( cellWidget( r, c ) )
234 clearCellWidget( r, c ); 235 clearCellWidget( r, c );
235 clearCell( r, c ); 236 clearCell( r, c );
236 } 237 }
237 } 238 }
238 setNumRows( 0 ); 239 setNumRows( 0 );
239} 240}
240 241
241void AbTable::refresh() 242void AbTable::refresh()
242{ 243{
243 int rows = numRows(); 244 int rows = numRows();
244 QString value; 245 QString value;
245 AbTableItem *abi; 246 AbTableItem *abi;
246 for ( int r = 0; r < rows; ++r ) { 247 for ( int r = 0; r < rows; ++r ) {
247 abi = static_cast<AbTableItem*>( item(r, 0) ); 248 abi = static_cast<AbTableItem*>( item(r, 0) );
248 value = findContactContact( contactList[abi] ); 249 value = findContactContact( contactList[abi] );
249 static_cast<AbTableItem*>( item(r, 1) )->setItem( value, abi->text() ); 250 static_cast<AbTableItem*>( item(r, 1) )->setItem( value, abi->text() );
250 } 251 }
251 resort(); 252 resort();
252} 253}
253 254
254void AbTable::keyPressEvent( QKeyEvent *e ) 255void AbTable::keyPressEvent( QKeyEvent *e )
255{ 256{
256 char key = toupper( e->ascii() ); 257 char key = toupper( e->ascii() );
257 258
258 if ( key >= 'A' && key <= 'Z' ) 259 if ( key >= 'A' && key <= 'Z' )
259 moveTo( key ); 260 moveTo( key );
260 261
261 switch( e->key() ) { 262 switch( e->key() ) {
262 case Qt::Key_Space: 263 case Qt::Key_Space:
263 case Qt::Key_Return: 264 case Qt::Key_Return:
264 case Qt::Key_Enter: 265 case Qt::Key_Enter:
265 emit details(); 266 emit details();
266 break; 267 break;
267 default: 268 default:
268 QTable::keyPressEvent( e ); 269 QTable::keyPressEvent( e );
269 } 270 }
270} 271}
271 272
272void AbTable::moveTo( char c ) 273void AbTable::moveTo( char c )
273{ 274{
274 275
275 int rows = numRows(); 276 int rows = numRows();
276 QString value; 277 QString value;
277 AbTableItem *abi; 278 AbTableItem *abi;
278 int r; 279 int r;
279 if ( asc ) { 280 if ( asc ) {
280 r = 0; 281 r = 0;
281 while ( r < rows-1) { 282 while ( r < rows-1) {
282 abi = static_cast<AbTableItem*>( item(r, 0) ); 283 abi = static_cast<AbTableItem*>( item(r, 0) );
283 QChar first = abi->key()[0]; 284 QChar first = abi->key()[0];
284 //### is there a bug in QChar to char comparison??? 285 //### is there a bug in QChar to char comparison???
285 if ( first.row() || first.cell() >= c ) 286 if ( first.row() || first.cell() >= c )
286 break; 287 break;
287 r++; 288 r++;
288 } 289 }
289 } else { 290 } else {
290 //### should probably disable reverse sorting instead 291 //### should probably disable reverse sorting instead
291 r = rows - 1; 292 r = rows - 1;
292 while ( r > 0 ) { 293 while ( r > 0 ) {
293 abi = static_cast<AbTableItem*>( item(r, 0) ); 294 abi = static_cast<AbTableItem*>( item(r, 0) );
294 QChar first = abi->key()[0]; 295 QChar first = abi->key()[0];
295 //### is there a bug in QChar to char comparison??? 296 //### is there a bug in QChar to char comparison???
296 if ( first.row() || first.cell() >= c ) 297 if ( first.row() || first.cell() >= c )
297 break; 298 break;
298 r--; 299 r--;
299 } 300 }
300 } 301 }
301 setCurrentCell( r, currentColumn() ); 302 setCurrentCell( r, currentColumn() );
302} 303}
303 304
304 305
305QString AbTable::findContactName( const Contact &entry ) 306QString AbTable::findContactName( const Contact &entry )
306{ 307{
307 // We use the fileAs, then company, defaultEmail 308 // We use the fileAs, then company, defaultEmail
308 QString str; 309 QString str;
309 str = entry.fileAs(); 310 str = entry.fileAs();
310 if ( str.isEmpty() ) { 311 if ( str.isEmpty() ) {
311 str = entry.company(); 312 str = entry.company();
312 if ( str.isEmpty() ) { 313 if ( str.isEmpty() ) {
313 str = entry.defaultEmail(); 314 str = entry.defaultEmail();
314 } 315 }
315 } 316 }
316 return str; 317 return str;
317} 318}
318 319
319QString AbTable::findContactContact( const Contact &entry ) 320QString AbTable::findContactContact( const Contact &entry )
320{ 321{
321 QString value; 322 QString value;
322 value = ""; 323 value = "";
323 for ( QValueList<int>::ConstIterator it = intFields->begin(); 324 for ( QValueList<int>::ConstIterator it = intFields->begin();
324 it != intFields->end(); ++it ) { 325 it != intFields->end(); ++it ) {
325 switch ( *it ) { 326 switch ( *it ) {
326 default: 327 default:
327 break; 328 break;
328 case Qtopia::Title: 329 case Qtopia::Title:
329 value = entry.title(); 330 value = entry.title();
330 break; 331 break;
331 case Qtopia::Suffix: 332 case Qtopia::Suffix:
332 value = entry.suffix(); 333 value = entry.suffix();
333 break; 334 break;
334 case Qtopia::FileAs: 335 case Qtopia::FileAs:
335 value = entry.fileAs(); 336 value = entry.fileAs();
336 break; 337 break;
337 case Qtopia::DefaultEmail: 338 case Qtopia::DefaultEmail:
338 value = entry.defaultEmail(); 339 value = entry.defaultEmail();
339 case Qtopia::Emails: 340 case Qtopia::Emails:
340 value = entry.emails(); 341 value = entry.emails();
341 break; 342 break;
342 case Qtopia::HomeStreet: 343 case Qtopia::HomeStreet:
343 value = entry.homeStreet(); 344 value = entry.homeStreet();
344 break; 345 break;
345 case Qtopia::HomeCity: 346 case Qtopia::HomeCity:
346 value = entry.homeCity(); 347 value = entry.homeCity();
347 break; 348 break;
348 case Qtopia::HomeState: 349 case Qtopia::HomeState:
349 value = entry.homeState(); 350 value = entry.homeState();
350 break; 351 break;
351 case Qtopia::HomeZip: 352 case Qtopia::HomeZip:
352 value = entry.homeZip(); 353 value = entry.homeZip();
353 break; 354 break;
354 case Qtopia::HomeCountry: 355 case Qtopia::HomeCountry:
355 value = entry.homeCountry(); 356 value = entry.homeCountry();
356 break; 357 break;
357 case Qtopia::HomePhone: 358 case Qtopia::HomePhone:
358 value = entry.homePhone(); 359 value = entry.homePhone();
359 break; 360 break;
360 case Qtopia::HomeFax: 361 case Qtopia::HomeFax:
361 value = entry.homeFax(); 362 value = entry.homeFax();
362 break; 363 break;
363 case Qtopia::HomeMobile: 364 case Qtopia::HomeMobile:
364 value = entry.homeMobile(); 365 value = entry.homeMobile();
365 break; 366 break;
366 case Qtopia::HomeWebPage: 367 case Qtopia::HomeWebPage:
367 value = entry.homeWebpage(); 368 value = entry.homeWebpage();
368 break; 369 break;
369 case Qtopia::Company: 370 case Qtopia::Company:
370 value = entry.company(); 371 value = entry.company();
371 break; 372 break;
372 case Qtopia::BusinessCity: 373 case Qtopia::BusinessCity:
373 value = entry.businessCity(); 374 value = entry.businessCity();
374 break; 375 break;
375 case Qtopia::BusinessStreet: 376 case Qtopia::BusinessStreet:
376 value = entry.businessStreet(); 377 value = entry.businessStreet();
377 break; 378 break;
378 case Qtopia::BusinessZip: 379 case Qtopia::BusinessZip:
379 value = entry.businessZip(); 380 value = entry.businessZip();
380 break; 381 break;
381 case Qtopia::BusinessCountry: 382 case Qtopia::BusinessCountry:
382 value = entry.businessCountry(); 383 value = entry.businessCountry();
383 break; 384 break;
384 case Qtopia::BusinessWebPage: 385 case Qtopia::BusinessWebPage:
385 value = entry.businessWebpage(); 386 value = entry.businessWebpage();
386 break; 387 break;
387 case Qtopia::JobTitle: 388 case Qtopia::JobTitle:
388 value = entry.jobTitle(); 389 value = entry.jobTitle();
389 break; 390 break;
390 case Qtopia::Department: 391 case Qtopia::Department:
391 value = entry.department(); 392 value = entry.department();
392 break; 393 break;
393 case Qtopia::Office: 394 case Qtopia::Office:
394 value = entry.office(); 395 value = entry.office();
395 break; 396 break;
396 case Qtopia::BusinessPhone: 397 case Qtopia::BusinessPhone:
397 value = entry.businessPhone(); 398 value = entry.businessPhone();
398 break; 399 break;
399 case Qtopia::BusinessFax: 400 case Qtopia::BusinessFax:
400 value = entry.businessFax(); 401 value = entry.businessFax();
401 break; 402 break;
402 case Qtopia::BusinessMobile: 403 case Qtopia::BusinessMobile:
403 value = entry.businessMobile(); 404 value = entry.businessMobile();
404 break; 405 break;
405 case Qtopia::BusinessPager: 406 case Qtopia::BusinessPager:
406 value = entry.businessPager(); 407 value = entry.businessPager();
407 break; 408 break;
408 case Qtopia::Profession: 409 case Qtopia::Profession:
409 value = entry.profession(); 410 value = entry.profession();
410 break; 411 break;
411 case Qtopia::Assistant: 412 case Qtopia::Assistant:
412 value = entry.assistant(); 413 value = entry.assistant();
413 break; 414 break;
414 case Qtopia::Manager: 415 case Qtopia::Manager:
415 value = entry.manager(); 416 value = entry.manager();
416 break; 417 break;
417 case Qtopia::Spouse: 418 case Qtopia::Spouse:
418 value = entry.spouse(); 419 value = entry.spouse();
419 break; 420 break;
420 case Qtopia::Gender: 421 case Qtopia::Gender:
421 value = entry.gender(); 422 value = entry.gender();
422 break; 423 break;
423 case Qtopia::Birthday: 424 case Qtopia::Birthday:
424 value = entry.birthday(); 425 value = entry.birthday();
425 break; 426 break;
426 case Qtopia::Anniversary: 427 case Qtopia::Anniversary:
427 value = entry.anniversary(); 428 value = entry.anniversary();
428 break; 429 break;
429 case Qtopia::Nickname: 430 case Qtopia::Nickname:
430 value = entry.nickname(); 431 value = entry.nickname();
431 break; 432 break;
432 case Qtopia::Children: 433 case Qtopia::Children:
433 value = entry.children(); 434 value = entry.children();
434 break; 435 break;
435 case Qtopia::Notes: 436 case Qtopia::Notes:
436 value = entry.notes(); 437 value = entry.notes();
437 break; 438 break;
438 } 439 }
439 if ( !value.isEmpty() ) 440 if ( !value.isEmpty() )
440 break; 441 break;
441 } 442 }
442 return value; 443 return value;
443} 444}
444 445
445void AbTable::addEntry( const Contact &newCnt ) 446void AbTable::addEntry( const Contact &newCnt )
446{ 447{
447 int row = numRows(); 448 int row = numRows();
448 setNumRows( row + 1 ); 449 setNumRows( row + 1 );
449 updateJournal( newCnt, Contact::ACTION_ADD ); 450 updateJournal( newCnt, Contact::ACTION_ADD );
450 insertIntoTable( newCnt, row ); 451 insertIntoTable( newCnt, row );
451 setCurrentCell( row, 0 ); 452 setCurrentCell( row, 0 );
452 updateVisible(); 453 updateVisible();
453} 454}
454 455
455void AbTable::resizeRows( int size ) { 456void AbTable::resizeRows( int size ) {
456/* 457/*
457 if (numRows()) { 458 if (numRows()) {
458 for (int i = 0; i < numRows(); i++) { 459 for (int i = 0; i < numRows(); i++) {
459 setRowHeight( i, size ); 460 setRowHeight( i, size );
460 } 461 }
461 }*/ 462 }*/
462 updateVisible(); 463 updateVisible();
463} 464}
464 465
465void AbTable::updateJournal( const Contact &cnt, 466void AbTable::updateJournal( const Contact &cnt,
466 Contact::journal_action action, int row ) 467 Contact::journal_action action, int row )
467{ 468{
468 QFile f( journalFileName() ); 469 QFile f( journalFileName() );
469 if ( !f.open(IO_WriteOnly|IO_Append) ) 470 if ( !f.open(IO_WriteOnly|IO_Append) )
470 return; 471 return;
471 QString buf; 472 QString buf;
472 QCString str; 473 QCString str;
473 buf = "<Contact "; 474 buf = "<Contact ";
474 cnt.save( buf ); 475 cnt.save( buf );
475 buf += " action=\"" + QString::number( (int)action ) + "\" "; 476 buf += " action=\"" + QString::number( (int)action ) + "\" ";
476 if ( action == Contact::ACTION_REMOVE || action == Contact::ACTION_REPLACE) 477 if ( action == Contact::ACTION_REMOVE || action == Contact::ACTION_REPLACE)
477 buf += " actionrow=\"" + QString::number(row) + "\" "; 478 buf += " actionrow=\"" + QString::number(row) + "\" ";
478 buf += "/>\n"; 479 buf += "/>\n";
479 QCString cstr = buf.utf8(); 480 QCString cstr = buf.utf8();
480 f.writeBlock( cstr.data(), cstr.length() ); 481 f.writeBlock( cstr.data(), cstr.length() );
481 QCopEnvelope( "QPE/PIM", "addressbookUpdated()" ); 482 QCopEnvelope( "QPE/PIM", "addressbookUpdated()" );
482} 483}
483 484
484bool AbTable::save( const QString &fn ) 485bool AbTable::save( const QString &fn )
485{ 486{
486// QTime t; 487// QTime t;
487// t.start(); 488// t.start();
488 489
489 QString strNewFile = fn + ".new"; 490 QString strNewFile = fn + ".new";
490 QFile f( strNewFile ); 491 QFile f( strNewFile );
491 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 492 if ( !f.open( IO_WriteOnly|IO_Raw ) )
492 return false; 493 return false;
493 494
494 int total_written; 495 int total_written;
495 QString out; 496 QString out;
496 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" 497 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
497 " <Groups>\n" 498 " <Groups>\n"
498 " </Groups>\n" 499 " </Groups>\n"
499 " <Contacts>\n"; 500 " <Contacts>\n";
500 QMapIterator<AbTableItem*, Contact> it; 501 QMapIterator<AbTableItem*, Contact> it;
501 for ( it = contactList.begin(); it != contactList.end(); ++it ) { 502 for ( it = contactList.begin(); it != contactList.end(); ++it ) {
502 out += "<Contact "; 503 out += "<Contact ";
503 it.data().save( out ); 504 it.data().save( out );
504 out += "/>\n"; 505 out += "/>\n";
505 QCString cstr = out.utf8(); 506 QCString cstr = out.utf8();
506 total_written = f.writeBlock( cstr.data(), cstr.length() ); 507 total_written = f.writeBlock( cstr.data(), cstr.length() );
507 if ( total_written != int(cstr.length()) ) { 508 if ( total_written != int(cstr.length()) ) {
508 f.close(); 509 f.close();
509 QFile::remove( strNewFile ); 510 QFile::remove( strNewFile );
510 return false; 511 return false;
511 } 512 }
512 out = ""; 513 out = "";
513 } 514 }
514 out += " </Contacts>\n</AddressBook>\n"; 515 out += " </Contacts>\n</AddressBook>\n";
515 516
516 QCString cstr = out.utf8(); 517 QCString cstr = out.utf8();
517 total_written = f.writeBlock( cstr.data(), cstr.length() ); 518 total_written = f.writeBlock( cstr.data(), cstr.length() );
518 if ( total_written != int(cstr.length()) ) { 519 if ( total_written != int(cstr.length()) ) {
519 f.close(); 520 f.close();
520 QFile::remove( strNewFile ); 521 QFile::remove( strNewFile );
521 return false; 522 return false;
522 } 523 }
523 f.close(); 524 f.close();
524 525
525// qDebug("saving: %d", t.elapsed() ); 526// qDebug("saving: %d", t.elapsed() );
526 527
527 // move the file over, I'm just going to use the system call 528 // move the file over, I'm just going to use the system call
528 // because, I don't feel like using QDir. 529 // because, I don't feel like using QDir.
529 if ( ::rename( strNewFile.latin1(), fn.latin1() ) < 0 ) { 530 if ( ::rename( strNewFile.latin1(), fn.latin1() ) < 0 ) {
530 qWarning( "problem renaming file %s to %s, errno: %d", 531 qWarning( "problem renaming file %s to %s, errno: %d",
531 strNewFile.latin1(), fn.latin1(), errno ); 532 strNewFile.latin1(), fn.latin1(), errno );
532 // remove the tmp file... 533 // remove the tmp file...
533 QFile::remove( strNewFile ); 534 QFile::remove( strNewFile );
534 } 535 }
535 // remove the journal... 536 // remove the journal...
536 QFile::remove( journalFileName() ); 537 QFile::remove( journalFileName() );
537 return true; 538 return true;
538} 539}
539 540
540void AbTable::load( const QString &fn ) 541void AbTable::load( const QString &fn )
541{ 542{
542 setSorting( false ); 543 setSorting( false );
543 loadFile( fn, false ); 544 loadFile( fn, false );
544 // merge in the journal 545 // merge in the journal
545 if ( QFile::exists( journalFileName() ) ) { 546 if ( QFile::exists( journalFileName() ) ) {
546 loadFile( journalFileName(), true ); 547 loadFile( journalFileName(), true );
547 save( fn ); 548 save( fn );
548 } 549 }
549 setSorting( true ); 550 setSorting( true );
550 resort(); 551 resort();
551} 552}
552 553
553void AbTable::loadFile( const QString &strFile, bool journalFile ) 554void AbTable::loadFile( const QString &strFile, bool journalFile )
554{ 555{
555// QTime t; 556// QTime t;
556// t.start(); 557// t.start();
557 QFile f( strFile ); 558 QFile f( strFile );
558 if ( !f.open(IO_ReadOnly) ) 559 if ( !f.open(IO_ReadOnly) )
559 return; 560 return;
560 QList<Contact> list; 561 QList<Contact> list;
561 list.setAutoDelete( TRUE ); 562 list.setAutoDelete( TRUE );
562 QByteArray ba = f.readAll(); 563 QByteArray ba = f.readAll();
563 f.close(); 564 f.close();
564 char *uc = ba.data();//(QChar *)data.unicode(); 565 char *uc = ba.data();//(QChar *)data.unicode();
565 int len = ba.size();//data.length(); 566 int len = ba.size();//data.length();
566 bool foundAction = false; 567 bool foundAction = false;
567 Contact::journal_action action; 568 Contact::journal_action action;
568 bool foundKey = false; 569 bool foundKey = false;
569 int journalKey = 0; 570 int journalKey = 0;
570 571
571 const int JOURNALACTION = Qtopia::Notes + 1; 572 const int JOURNALACTION = Qtopia::Notes + 1;
572 const int JOURNALROW = JOURNALACTION + 1; 573 const int JOURNALROW = JOURNALACTION + 1;
573 574
574 // ********************************** 575 // **********************************
575 // CHANGE THE SIZE OF THE DICT IF YOU ADD ANY MORE FIELDS!!!! 576 // CHANGE THE SIZE OF THE DICT IF YOU ADD ANY MORE FIELDS!!!!
576 // ********************************** 577 // **********************************
577 QAsciiDict<int> dict( 47 ); 578 QAsciiDict<int> dict( 47 );
578 dict.setAutoDelete( TRUE ); 579 dict.setAutoDelete( TRUE );
579 dict.insert( "Uid", new int(Qtopia::AddressUid) ); 580 dict.insert( "Uid", new int(Qtopia::AddressUid) );
580 dict.insert( "Title", new int(Qtopia::Title) ); 581 dict.insert( "Title", new int(Qtopia::Title) );
581 dict.insert( "FirstName", new int(Qtopia::FirstName) ); 582 dict.insert( "FirstName", new int(Qtopia::FirstName) );
582 dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); 583 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
583 dict.insert( "LastName", new int(Qtopia::LastName) ); 584 dict.insert( "LastName", new int(Qtopia::LastName) );
584 dict.insert( "Suffix", new int(Qtopia::Suffix) ); 585 dict.insert( "Suffix", new int(Qtopia::Suffix) );
585 dict.insert( "FileAs", new int(Qtopia::FileAs) ); 586 dict.insert( "FileAs", new int(Qtopia::FileAs) );
586 dict.insert( "Categories", new int(Qtopia::AddressCategory) ); 587 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
587 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); 588 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
588 dict.insert( "Emails", new int(Qtopia::Emails) ); 589 dict.insert( "Emails", new int(Qtopia::Emails) );
589 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); 590 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
590 dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); 591 dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
591 dict.insert( "HomeState", new int(Qtopia::HomeState) ); 592 dict.insert( "HomeState", new int(Qtopia::HomeState) );
592 dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); 593 dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
593 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); 594 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
594 dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); 595 dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
595 dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); 596 dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
596 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); 597 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
597 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); 598 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
598 dict.insert( "Company", new int(Qtopia::Company) ); 599 dict.insert( "Company", new int(Qtopia::Company) );
599 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); 600 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) );
600 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); 601 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) );
601 dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); 602 dict.insert( "BusinessState", new int(Qtopia::BusinessState) );
602 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); 603 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) );
603 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); 604 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) );
604 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); 605 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) );
605 dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); 606 dict.insert( "JobTitle", new int(Qtopia::JobTitle) );
606 dict.insert( "Department", new int(Qtopia::Department) ); 607 dict.insert( "Department", new int(Qtopia::Department) );
607 dict.insert( "Office", new int(Qtopia::Office) ); 608 dict.insert( "Office", new int(Qtopia::Office) );
608 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); 609 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) );
609 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); 610 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) );
610 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); 611 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) );
611 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); 612 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) );
612 dict.insert( "Profession", new int(Qtopia::Profession) ); 613 dict.insert( "Profession", new int(Qtopia::Profession) );
613 dict.insert( "Assistant", new int(Qtopia::Assistant) ); 614 dict.insert( "Assistant", new int(Qtopia::Assistant) );
614 dict.insert( "Manager", new int(Qtopia::Manager) ); 615 dict.insert( "Manager", new int(Qtopia::Manager) );
615 dict.insert( "Spouse", new int(Qtopia::Spouse) ); 616 dict.insert( "Spouse", new int(Qtopia::Spouse) );
616 dict.insert( "Children", new int(Qtopia::Children) ); 617 dict.insert( "Children", new int(Qtopia::Children) );
617 dict.insert( "Gender", new int(Qtopia::Gender) ); 618 dict.insert( "Gender", new int(Qtopia::Gender) );
618 dict.insert( "Birthday", new int(Qtopia::Birthday) ); 619 dict.insert( "Birthday", new int(Qtopia::Birthday) );
619 dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); 620 dict.insert( "Anniversary", new int(Qtopia::Anniversary) );
620 dict.insert( "Nickname", new int(Qtopia::Nickname) ); 621 dict.insert( "Nickname", new int(Qtopia::Nickname) );
621 dict.insert( "Notes", new int(Qtopia::Notes) ); 622 dict.insert( "Notes", new int(Qtopia::Notes) );
622 dict.insert( "action", new int(JOURNALACTION) ); 623 dict.insert( "action", new int(JOURNALACTION) );
623 dict.insert( "actionrow", new int(JOURNALROW) ); 624 dict.insert( "actionrow", new int(JOURNALROW) );
624 625
625 int i = 0; 626 int i = 0;
626 int num = 0; 627 int num = 0;
627 char *point; 628 char *point;
628 while ( (point = strstr( uc+i, "<Contact " ) ) != NULL ) { 629 while ( (point = strstr( uc+i, "<Contact " ) ) != NULL ) {
629 i = point - uc; 630 i = point - uc;
630 // if we are reading the standard file, we just need to 631 // if we are reading the standard file, we just need to
631 // insert info, so just say we'll do an insert... 632 // insert info, so just say we'll do an insert...
632 action = Contact::ACTION_ADD; 633 action = Contact::ACTION_ADD;
633 // new Contact 634 // new Contact
634 Contact *cnt = new Contact; 635 Contact *cnt = new Contact;
635 i += 9; 636 i += 9;
636 while ( 1 ) { 637 while ( 1 ) {
637 while ( i < len && (uc[i] == ' ' || uc[i] == '\n' || uc[i] == '\r') ) 638 while ( i < len && (uc[i] == ' ' || uc[i] == '\n' || uc[i] == '\r') )
638 i++; 639 i++;
639 if ( i >= len-2 || (uc[i] == '/' && uc[i+1] == '>') ) 640 if ( i >= len-2 || (uc[i] == '/' && uc[i+1] == '>') )
640 break; 641 break;
641 // we have another attribute read it. 642 // we have another attribute read it.
642 int j = i; 643 int j = i;
643 while ( j < len && uc[j] != '=' ) 644 while ( j < len && uc[j] != '=' )
644 j++; 645 j++;
645 char *attr = uc+i; 646 char *attr = uc+i;
646 uc[j] = '\0'; 647 uc[j] = '\0';
647 //qDebug("attr=%s", attr.latin1() ); 648 //qDebug("attr=%s", attr.latin1() );
648 i = ++j; // skip = 649 i = ++j; // skip =
649 while ( i < len && uc[i] != '"' ) 650 while ( i < len && uc[i] != '"' )
650 i++; 651 i++;
651 j = ++i; 652 j = ++i;
652 bool haveEnt = FALSE; 653 bool haveEnt = FALSE;
653 bool haveUtf = FALSE; 654 bool haveUtf = FALSE;
654 while ( j < len && uc[j] != '"' ) { 655 while ( j < len && uc[j] != '"' ) {
655 if ( uc[j] == '&' ) 656 if ( uc[j] == '&' )
656 haveEnt = TRUE; 657 haveEnt = TRUE;
657 if ( ((unsigned char)uc[j]) > 0x7f ) 658 if ( ((unsigned char)uc[j]) > 0x7f )
658 haveUtf = TRUE; 659 haveUtf = TRUE;
659 j++; 660 j++;
660 } 661 }
661 662
662 if ( j == i ) { 663 if ( j == i ) {
663 // empty value 664 // empty value
664 i = j + 1; 665 i = j + 1;
665 continue; 666 continue;
666 } 667 }
667 668
668 QString value = haveUtf ? QString::fromUtf8( uc+i, j-i ) 669 QString value = haveUtf ? QString::fromUtf8( uc+i, j-i )
669 : QString::fromLatin1( uc+i, j-i ); 670 : QString::fromLatin1( uc+i, j-i );
670 if ( haveEnt ) 671 if ( haveEnt )
671 value = Qtopia::plainString( value ); 672 value = Qtopia::plainString( value );
672 i = j + 1; 673 i = j + 1;
673 674
674 int *find = dict[ attr ]; 675 int *find = dict[ attr ];
675 if ( !find ) { 676 if ( !find ) {
676 cnt->setCustomField(attr, value); 677 cnt->setCustomField(attr, value);
677 continue; 678 continue;
678 } 679 }
679#if 1 680#if 1
680 switch( *find ) { 681 switch( *find ) {
681 case Qtopia::AddressUid: 682 case Qtopia::AddressUid:
682 cnt->setUid( value.toInt() ); 683 cnt->setUid( value.toInt() );
683 break; 684 break;
684 case Qtopia::AddressCategory: 685 case Qtopia::AddressCategory:
685 cnt->setCategories( Qtopia::Record::idsFromString( value )); 686 cnt->setCategories( Qtopia::Record::idsFromString( value ));
686 break; 687 break;
687 case JOURNALACTION: 688 case JOURNALACTION:
688 action = Contact::journal_action(value.toInt()); 689 action = Contact::journal_action(value.toInt());
689 break; 690 break;
690 case JOURNALROW: 691 case JOURNALROW:
691 journalKey = value.toInt(); 692 journalKey = value.toInt();
692 break; 693 break;
693 694
694 default: 695 default:
695 cnt->insert( *find, value ); 696 cnt->insert( *find, value );
696 break; 697 break;
697 } 698 }
698#endif 699#endif
699 } 700 }
700 701
701 // sadly we can't delay adding of items from the journal to get 702 // sadly we can't delay adding of items from the journal to get
702 // the proper effect, but then, the journal should _never_ be 703 // the proper effect, but then, the journal should _never_ be
703 // that huge, and recovering from a crash is not necessarily 704 // that huge, and recovering from a crash is not necessarily
704 // a *fast* thing. 705 // a *fast* thing.
705 switch ( action ) { 706 switch ( action ) {
706 case Contact::ACTION_ADD: 707 case Contact::ACTION_ADD:
707 if ( journalFile ) { 708 if ( journalFile ) {
708 int myrows = numRows(); 709 int myrows = numRows();
709 setNumRows( myrows + 1 ); 710 setNumRows( myrows + 1 );
710 insertIntoTable( *cnt, myrows ); 711 insertIntoTable( *cnt, myrows );
711 delete cnt; 712 delete cnt;
712 } 713 }
713 else 714 else
714 list.append( cnt ); 715 list.append( cnt );
715 break; 716 break;
716 case Contact::ACTION_REMOVE: 717 case Contact::ACTION_REMOVE:
717 // yup, we don't use the entry to remove the object... 718 // yup, we don't use the entry to remove the object...
718 journalFreeRemove( journalKey ); 719 journalFreeRemove( journalKey );
719 delete cnt; 720 delete cnt;
720 break; 721 break;
721 case Contact::ACTION_REPLACE: 722 case Contact::ACTION_REPLACE:
722 journalFreeReplace( *cnt, journalKey ); 723 journalFreeReplace( *cnt, journalKey );
723 delete cnt; 724 delete cnt;
724 break; 725 break;
725 default: 726 default:
726 break; 727 break;
727 } 728 }
728 num++; 729 num++;
729 foundAction = false; 730 foundAction = false;
730 foundKey = false; 731 foundKey = false;
731 // if ( num % 100 == 0 ) { 732 // if ( num % 100 == 0 ) {
732 // qDebug("loading file, num=%d, t=%d", num, t.elapsed() ); 733 // qDebug("loading file, num=%d, t=%d", num, t.elapsed() );
733 // } 734 // }
734 } 735 }
735 if ( list.count() > 0 ) { 736 if ( list.count() > 0 ) {
736 internalAddEntries( list ); 737 internalAddEntries( list );
737 } 738 }
738// qDebug("done loading %d, t=%d", num, t.elapsed() ); 739// qDebug("done loading %d, t=%d", num, t.elapsed() );
739 740
740} 741}
741 742
742void AbTable::realignTable( int row ) 743void AbTable::realignTable( int row )
743{ 744{
744 QTableItem *ti1, 745 QTableItem *ti1,
745 *ti2; 746 *ti2;
746 int totalRows = numRows(); 747 int totalRows = numRows();
747 for ( int curr = row; curr < totalRows - 1; curr++ ) { 748 for ( int curr = row; curr < totalRows - 1; curr++ ) {
748 // the same info from the todo list still applies, but I 749 // the same info from the todo list still applies, but I
749 // don't think it is _too_ bad. 750 // don't think it is _too_ bad.
750 ti1 = item( curr + 1, 0 ); 751 ti1 = item( curr + 1, 0 );
751 ti2 = item( curr + 1, 1 ); 752 ti2 = item( curr + 1, 1 );
752 takeItem( ti1 ); 753 takeItem( ti1 );
753 takeItem( ti2 ); 754 takeItem( ti2 );
754 setItem( curr, 0, ti1 ); 755 setItem( curr, 0, ti1 );
755 setItem( curr, 1, ti2 ); 756 setItem( curr, 1, ti2 );
756 } 757 }
757 setNumRows( totalRows - 1 ); 758 setNumRows( totalRows - 1 );
758 resort(); 759 resort();
759} 760}
760 761
761void AbTable::insertIntoTable( const Contact &cnt, int row ) 762void AbTable::insertIntoTable( const Contact &cnt, int row )
762{ 763{
763 QString strName, 764 QString strName,
764 strContact; 765 strContact;
765 766
766 strName = findContactName( cnt ); 767 strName = findContactName( cnt );
767 strContact = findContactContact( cnt ); 768 strContact = findContactContact( cnt );
768 769
769 AbTableItem *ati; 770 AbTableItem *ati;
770 ati = new AbTableItem( this, QTableItem::Never, strName, strContact); 771 ati = new AbTableItem( this, QTableItem::Never, strName, strContact);
771 contactList.insert( ati, cnt ); 772 contactList.insert( ati, cnt );
772 setItem( row, 0, ati ); 773 setItem( row, 0, ati );
773 ati = new AbTableItem( this, QTableItem::Never, strContact, strName); 774 ati = new AbTableItem( this, QTableItem::Never, strContact, strName);
774 setItem( row, 1, ati ); 775 setItem( row, 1, ati );
775 776
776 //### cannot do this; table only has two columns at this point 777 //### cannot do this; table only has two columns at this point
777 // setItem( row, 2, new AbPickItem( this ) ); 778 // setItem( row, 2, new AbPickItem( this ) );
778 779
779 // resort at some point? 780 // resort at some point?
780} 781}
781 782
782void AbTable::internalAddEntries( QList<Contact> &list ) 783void AbTable::internalAddEntries( QList<Contact> &list )
783{ 784{
784 setUpdatesEnabled( FALSE ); 785 setUpdatesEnabled( FALSE );
785 setNumRows( list.count() ); 786 setNumRows( list.count() );
786 int row = 0; 787 int row = 0;
787 Contact *it; 788 Contact *it;
788 for ( it = list.first(); it; it = list.next() ) 789 for ( it = list.first(); it; it = list.next() )
789 insertIntoTable( *it, row++ ); 790 insertIntoTable( *it, row++ );
790 resort(); 791 resort();
791 setUpdatesEnabled( TRUE ); 792 setUpdatesEnabled( TRUE );
792} 793}
793 794
794 795
795void AbTable::journalFreeReplace( const Contact &cnt, int row ) 796void AbTable::journalFreeReplace( const Contact &cnt, int row )
796{ 797{
797 QString strName, 798 QString strName,
798 strContact; 799 strContact;
799 AbTableItem *ati; 800 AbTableItem *ati;
800 801
801 strName = findContactName( cnt ); 802 strName = findContactName( cnt );
802 strContact = findContactContact( cnt ); 803 strContact = findContactContact( cnt );
803 ati = static_cast<AbTableItem*>(item(row, 0)); 804 ati = static_cast<AbTableItem*>(item(row, 0));
804 contactList.remove( ati ); 805 contactList.remove( ati );
805 ati->setItem( strName, strContact ); 806 ati->setItem( strName, strContact );
806 contactList.insert( ati, cnt ); 807 contactList.insert( ati, cnt );
807 808
808 ati = static_cast<AbTableItem*>(item(row, 1)); 809 ati = static_cast<AbTableItem*>(item(row, 1));
809 ati->setItem( strContact, strName ); 810 ati->setItem( strContact, strName );
810} 811}
811 812
812void AbTable::journalFreeRemove( int row ) 813void AbTable::journalFreeRemove( int row )
813{ 814{
814 AbTableItem *ati; 815 AbTableItem *ati;
815 ati = static_cast<AbTableItem*>(item(row, 0)); 816 ati = static_cast<AbTableItem*>(item(row, 0));
816 if ( !ati ) 817 if ( !ati )
817 return; 818 return;
818 contactList.remove( ati ); 819 contactList.remove( ati );
819 realignTable( row ); 820 realignTable( row );
820} 821}
821 822
822#if QT_VERSION <= 230 823#if QT_VERSION <= 230
823#ifndef SINGLE_APP 824#ifndef SINGLE_APP
824void QTable::paintEmptyArea( QPainter *p, int cx, int cy, int cw, int ch ) 825void QTable::paintEmptyArea( QPainter *p, int cx, int cy, int cw, int ch )
825{ 826{
826 // Region of the rect we should draw 827 // Region of the rect we should draw
827 QRegion reg( QRect( cx, cy, cw, ch ) ); 828 QRegion reg( QRect( cx, cy, cw, ch ) );
828 // Subtract the table from it 829 // Subtract the table from it
829 reg = reg.subtract( QRect( QPoint( 0, 0 ), tableSize() ) ); 830 reg = reg.subtract( QRect( QPoint( 0, 0 ), tableSize() ) );
830 // And draw the rectangles (transformed as needed) 831 // And draw the rectangles (transformed as needed)
831 QArray<QRect> r = reg.rects(); 832 QArray<QRect> r = reg.rects();
832 for (unsigned int i=0; i<r.count(); i++) 833 for (unsigned int i=0; i<r.count(); i++)
833 p->fillRect( r[i], colorGroup().brush( QColorGroup::Base ) ); 834 p->fillRect( r[i], colorGroup().brush( QColorGroup::Base ) );
834} 835}
835#endif 836#endif
836#endif 837#endif
837 838
838 839
839// int AbTable::rowHeight( int ) const 840// int AbTable::rowHeight( int ) const
840// { 841// {
841// return 18; 842// return 18;
842// } 843// }
843 844
844// int AbTable::rowPos( int row ) const 845// int AbTable::rowPos( int row ) const
845// { 846// {
846// return 18*row; 847// return 18*row;
847// } 848// }
848 849
849// int AbTable::rowAt( int pos ) const 850// int AbTable::rowAt( int pos ) const
850// { 851// {
851// return QMIN( pos/18, numRows()-1 ); 852// return QMIN( pos/18, numRows()-1 );
852// } 853// }
853 854
854void AbTable::slotDoFind( const QString &findString, bool caseSensitive, 855void AbTable::slotDoFind( const QString &findString, bool caseSensitive,
855 bool backwards, int category ) 856 bool backwards, int category )
856{ 857{
857 if ( currFindRow < -1 ) 858 if ( currFindRow < -1 )
858 currFindRow = currentRow() - 1; 859 currFindRow = currentRow() - 1;
859 clearSelection( TRUE ); 860 clearSelection( TRUE );
860 int rows, 861 int rows,
861 row; 862 row;
862 AbTableItem *ati; 863 AbTableItem *ati;
863 QRegExp r( findString ); 864 QRegExp r( findString );
864 r.setCaseSensitive( caseSensitive ); 865 r.setCaseSensitive( caseSensitive );
865 rows = numRows(); 866 rows = numRows();
866 static bool wrapAround = true; 867 static bool wrapAround = true;
867 868
868 if ( !backwards ) { 869 if ( !backwards ) {
869 for ( row = currFindRow + 1; row < rows; row++ ) { 870 for ( row = currFindRow + 1; row < rows; row++ ) {
870 ati = static_cast<AbTableItem*>( item(row, 0) ); 871 ati = static_cast<AbTableItem*>( item(row, 0) );
871 if ( contactCompare( contactList[ati], r, category ) ) 872 if ( contactCompare( contactList[ati], r, category ) )
872 break; 873 break;
873 874
874 } 875 }
875 } else { 876 } else {
876 for ( row = currFindRow - 1; row > -1; row-- ) { 877 for ( row = currFindRow - 1; row > -1; row-- ) {
877 ati = static_cast<AbTableItem*>( item(row, 0) ); 878 ati = static_cast<AbTableItem*>( item(row, 0) );
878 if ( contactCompare( contactList[ati], r, category ) ) 879 if ( contactCompare( contactList[ati], r, category ) )
879 break; 880 break;
880 } 881 }
881 } 882 }
882 if ( row >= rows || row < 0 ) { 883 if ( row >= rows || row < 0 ) {
883 if ( row < 0 ) 884 if ( row < 0 )
884 currFindRow = rows; 885 currFindRow = rows;
885 else 886 else
886 currFindRow = -1; 887 currFindRow = -1;
887 888
888 if ( wrapAround ) 889 if ( wrapAround )
889 emit signalWrapAround(); 890 emit signalWrapAround();
890 else 891 else
891 emit signalNotFound(); 892 emit signalNotFound();
892 893
893 wrapAround = !wrapAround; 894 wrapAround = !wrapAround;
894 } else { 895 } else {
895 currFindRow = row; 896 currFindRow = row;
896 QTableSelection foundSelection; 897 QTableSelection foundSelection;
897 foundSelection.init( currFindRow, 0 ); 898 foundSelection.init( currFindRow, 0 );
898 foundSelection.expandTo( currFindRow, numCols() - 1 ); 899 foundSelection.expandTo( currFindRow, numCols() - 1 );
899 addSelection( foundSelection ); 900 addSelection( foundSelection );
900 setCurrentCell( currFindRow, numCols() - 1 ); 901 setCurrentCell( currFindRow, numCols() - 1 );
901 wrapAround = true; 902 wrapAround = true;
902 } 903 }
903} 904}
904 905
905static bool contactCompare( const Contact &cnt, const QRegExp &r, int category ) 906static bool contactCompare( const Contact &cnt, const QRegExp &r, int category )
906{ 907{
907 bool returnMe; 908 bool returnMe;
908 QArray<int> cats; 909 QArray<int> cats;
909 cats = cnt.categories(); 910 cats = cnt.categories();
910 911
911 returnMe = false; 912 returnMe = false;
912 if ( (category == -1 && cats.count() == 0) || category == -2 ) 913 if ( (category == -1 && cats.count() == 0) || category == -2 )
913 returnMe = cnt.match( r ); 914 returnMe = cnt.match( r );
914 else { 915 else {
915 int i; 916 int i;
916 for ( i = 0; i < int(cats.count()); i++ ) { 917 for ( i = 0; i < int(cats.count()); i++ ) {
917 if ( cats[i] == category ) { 918 if ( cats[i] == category ) {
918 returnMe = cnt.match( r ); 919 returnMe = cnt.match( r );
919 break; 920 break;
920 } 921 }
921 } 922 }
922 } 923 }
923 return returnMe; 924 return returnMe;
924} 925}
925 926
926void AbTable::fitColumns() 927void AbTable::fitColumns()
927{ 928{
928 int contentsWidth = visibleWidth(); 929 int contentsWidth = visibleWidth();
929 int n = numCols(); 930 int n = numCols();
930 int pw = n == 3 ? columnWidth(2) : 0; 931 int pw = n == 3 ? columnWidth(2) : 0;
931 setColumnWidth( 0, contentsWidth - contentsWidth / 2 ); 932 setColumnWidth( 0, contentsWidth - contentsWidth / 2 );
932 setColumnWidth( 1, contentsWidth / 2 - pw ); 933 setColumnWidth( 1, contentsWidth / 2 - pw );
933} 934}
934 935
935void AbTable::show() 936void AbTable::show()
936{ 937{
937 fitColumns(); 938 fitColumns();
938 QTable::show(); 939 QTable::show();
939} 940}
940 941
941void AbTable::setChoiceNames( const QStringList& list) 942void AbTable::setChoiceNames( const QStringList& list)
942{ 943{
943 choicenames = list; 944 choicenames = list;
944 if ( choicenames.isEmpty() ) { 945 if ( choicenames.isEmpty() ) {
945 // hide pick column 946 // hide pick column
946 setNumCols( 2 ); 947 setNumCols( 2 );
947 } else { 948 } else {
948 // show pick column 949 // show pick column
949 setNumCols( 3 ); 950 setNumCols( 3 );
950 setColumnWidth( 2, fontMetrics().width(tr( "Pick" ))+8 ); 951 setColumnWidth( 2, fontMetrics().width(tr( "Pick" ))+8 );
951 horizontalHeader()->setLabel( 2, tr( "Pick" )); 952 horizontalHeader()->setLabel( 2, tr( "Pick" ));
952 } 953 }
953 fitColumns(); 954 fitColumns();
954} 955}
955 956
956void AbTable::itemClicked(int,int col) 957void AbTable::itemClicked(int,int col)
957{ 958{
958 if ( col == 2 ) { 959 if ( col == 2 ) {
959 return; 960 return;
960 } else { 961 } else {
961 emit details(); 962 emit details();
962 } 963 }
963} 964}
964 965
965QStringList AbTable::choiceNames() const 966QStringList AbTable::choiceNames() const
966{ 967{
967 return choicenames; 968 return choicenames;
968} 969}
969 970
970void AbTable::setChoiceSelection(int /*index*/, const QStringList& /*list*/) 971void AbTable::setChoiceSelection(int /*index*/, const QStringList& /*list*/)
971{ 972{
972 /* ###### 973 /* ######
973 974
974 QString selname = choicenames.at(index); 975 QString selname = choicenames.at(index);
975 for (each row) { 976 for (each row) {
976 Contact *c = contactForRow(row); 977 Contact *c = contactForRow(row);
977 if ( list.contains(c->email) ) { 978 if ( list.contains(c->email) ) {
978 list.remove(c->email); 979 list.remove(c->email);
979 setText(row, 2, selname); 980 setText(row, 2, selname);
980 } 981 }
981 } 982 }
982 for (remaining list items) { 983 for (remaining list items) {
983 Contact *c = new contact(item); 984 Contact *c = new contact(item);
984 setText(newrow, 2, selname); 985 setText(newrow, 2, selname);
985 } 986 }
986 987
987 */ 988 */
988} 989}
989 990
990QStringList AbTable::choiceSelection(int /*index*/) const 991QStringList AbTable::choiceSelection(int /*index*/) const
991{ 992{
992 QStringList r; 993 QStringList r;
993 /* ###### 994 /* ######
994 995
995 QString selname = choicenames.at(index); 996 QString selname = choicenames.at(index);
996 for (each row) { 997 for (each row) {
997 Contact *c = contactForRow(row); 998 Contact *c = contactForRow(row);
998 if ( text(row,2) == selname ) { 999 if ( text(row,2) == selname ) {
999 r.append(c->email); 1000 r.append(c->email);
1000 } 1001 }
1001 } 1002 }
1002 1003
1003 */ 1004 */
1004 return r; 1005 return r;
1005} 1006}
1006 1007
1007void AbTable::setShowCategory( const QString &c ) 1008void AbTable::setShowCategory( const QString &c )
1008{ 1009{
1009 showCat = c; 1010 showCat = c;
1010 updateVisible(); 1011 updateVisible();
1011} 1012}
1012 1013
1013void AbTable::setShowByLetter( char c ) 1014void AbTable::setShowByLetter( char c )
1014{ 1015{
1015 showChar = tolower(c); 1016 showChar = tolower(c);
1016 updateVisible(); 1017 updateVisible();
1017} 1018}
1018 1019
1019QString AbTable::showCategory() const 1020QString AbTable::showCategory() const
1020{ 1021{
1021 return showCat; 1022 return showCat;
1022} 1023}
1023 1024
1024 1025
1025QStringList AbTable::categories() 1026QStringList AbTable::categories()
1026{ 1027{
1027 mCat.load( categoryFileName() ); 1028 mCat.load( categoryFileName() );
1028 QStringList categoryList = mCat.labels( "Contacts" ); 1029 QStringList categoryList = mCat.labels( "Contacts" );
1029 return categoryList; 1030 return categoryList;
1030} 1031}
1031 1032
1032void AbTable::updateVisible() 1033void AbTable::updateVisible()
1033{ 1034{
1034 int visible, 1035 int visible,
1035 totalRows, 1036 totalRows,
1036 id, 1037 id,
1037 totalCats, 1038 totalCats,
1038 it, 1039 it,
1039 row; 1040 row;
1040 bool hide; 1041 bool hide;
1041 AbTableItem *ati; 1042 AbTableItem *ati;
1042 Contact *cnt; 1043 Contact *cnt;
1043 QString fileAsName; 1044 QString fileAsName;
1044 QString tmpStr; 1045 QString tmpStr;
1045 visible = 0; 1046 visible = 0;
1046 1047
1047 setPaintingEnabled( FALSE ); 1048 setPaintingEnabled( FALSE );
1048 1049
1049 totalRows = numRows(); 1050 totalRows = numRows();
1050 id = mCat.id( "Contacts", showCat ); 1051 id = mCat.id( "Contacts", showCat );
1051 QArray<int> cats; 1052 QArray<int> cats;
1052 for ( row = 0; row < totalRows; row++ ) { 1053 for ( row = 0; row < totalRows; row++ ) {
1053 ati = static_cast<AbTableItem*>( item(row, 0) ); 1054 ati = static_cast<AbTableItem*>( item(row, 0) );
1054 cnt = &contactList[ati]; 1055 cnt = &contactList[ati];
1055 cats = cnt->categories(); 1056 cats = cnt->categories();
1056 fileAsName = cnt->fileAs(); 1057 fileAsName = cnt->fileAs();
1057 hide = false; 1058 hide = false;
1058 if ( !showCat.isEmpty() ) { 1059 if ( !showCat.isEmpty() ) {
1059 if ( showCat == tr( "Unfiled" ) ) { 1060 if ( showCat == tr( "Unfiled" ) ) {
1060 if ( cats.count() > 0 ) 1061 if ( cats.count() > 0 )
1061 hide = true; 1062 hide = true;
1062 } else { 1063 } else {
1063 // do some comparing 1064 // do some comparing
1064 if ( !hide ) { 1065 if ( !hide ) {
1065 hide = true; 1066 hide = true;
1066 totalCats = int(cats.count()); 1067 totalCats = int(cats.count());
1067 for ( it = 0; it < totalCats; it++ ) { 1068 for ( it = 0; it < totalCats; it++ ) {
1068 if ( cats[it] == id ) { 1069 if ( cats[it] == id ) {
1069 hide = false; 1070 hide = false;
1070 break; 1071 break;
1071 } 1072 }
1072 } 1073 }
1073 } 1074 }
1074 } 1075 }
1075 } 1076 }
1076 if ( showChar != '\0' ) { 1077 if ( showChar != '\0' ) {
1077 tmpStr = fileAsName.left(1); 1078 tmpStr = fileAsName.left(1);
1078 tmpStr = tmpStr.lower(); 1079 tmpStr = tmpStr.lower();
1079 if ( tmpStr != QString(QChar(showChar)) && showChar != '#' ) { 1080 if ( tmpStr != QString(QChar(showChar)) && showChar != '#' ) {
1080 hide = true; 1081 hide = true;
1081 } 1082 }
1082 if ( showChar == '#' ) { 1083 if ( showChar == '#' ) {
1083 if (tmpStr == "a") 1084 if (tmpStr == "a")
1084 hide = true; 1085 hide = true;
1085 1086
1086 if (tmpStr == "b") 1087 if (tmpStr == "b")
1087 hide = true; 1088 hide = true;
1088 1089
1089 if (tmpStr == "c") 1090 if (tmpStr == "c")
1090 hide = true; 1091 hide = true;
1091 1092
1092 if (tmpStr == "d") 1093 if (tmpStr == "d")
1093 hide = true; 1094 hide = true;
1094 1095
1095 if (tmpStr == "e") 1096 if (tmpStr == "e")
1096 hide = true; 1097 hide = true;
1097 1098
1098 if (tmpStr == "f") 1099 if (tmpStr == "f")
1099 hide = true; 1100 hide = true;
1100 1101
1101 if (tmpStr == "g") 1102 if (tmpStr == "g")
1102 hide = true; 1103 hide = true;
1103 1104
1104 if (tmpStr == "h") 1105 if (tmpStr == "h")
1105 hide = true; 1106 hide = true;
1106 1107
1107 if (tmpStr == "i") 1108 if (tmpStr == "i")
1108 hide = true; 1109 hide = true;
1109 1110
1110 if (tmpStr == "j") 1111 if (tmpStr == "j")
1111 hide = true; 1112 hide = true;
1112 1113
1113 if (tmpStr == "k") 1114 if (tmpStr == "k")
1114 hide = true; 1115 hide = true;
1115 1116
1116 if (tmpStr == "l") 1117 if (tmpStr == "l")
1117 hide = true; 1118 hide = true;
1118 1119
1119 if (tmpStr == "m") 1120 if (tmpStr == "m")
1120 hide = true; 1121 hide = true;
1121 1122
1122 if (tmpStr == "n") 1123 if (tmpStr == "n")
1123 hide = true; 1124 hide = true;
1124 1125
1125 if (tmpStr == "o") 1126 if (tmpStr == "o")
1126 hide = true; 1127 hide = true;
1127 1128
1128 if (tmpStr == "p") 1129 if (tmpStr == "p")
1129 hide = true; 1130 hide = true;
1130 1131
1131 if (tmpStr == "q") 1132 if (tmpStr == "q")
1132 hide = true; 1133 hide = true;
1133 1134
1134 if (tmpStr == "r") 1135 if (tmpStr == "r")
1135 hide = true; 1136 hide = true;
1136 1137
1137 if (tmpStr == "s") 1138 if (tmpStr == "s")
1138 hide = true; 1139 hide = true;
1139 1140
1140 if (tmpStr == "t") 1141 if (tmpStr == "t")
1141 hide = true; 1142 hide = true;
1142 1143
1143 if (tmpStr == "u") 1144 if (tmpStr == "u")
1144 hide = true; 1145 hide = true;
1145 1146
1146 if (tmpStr == "v") 1147 if (tmpStr == "v")
1147 hide = true; 1148 hide = true;
1148 1149
1149 if (tmpStr == "w") 1150 if (tmpStr == "w")
1150 hide = true; 1151 hide = true;
1151 1152
1152 if (tmpStr == "x") 1153 if (tmpStr == "x")
1153 hide = true; 1154 hide = true;
1154 1155
1155 if (tmpStr == "y") 1156 if (tmpStr == "y")
1156 hide = true; 1157 hide = true;
1157 1158
1158 if (tmpStr == "z") 1159 if (tmpStr == "z")
1159 hide = true; 1160 hide = true;
1160 } 1161 }
1161 1162
1162 } 1163 }
1163 if ( hide ) { 1164 if ( hide ) {
1164 if ( currentRow() == row ) 1165 if ( currentRow() == row )
1165 setCurrentCell( -1, 0 ); 1166 setCurrentCell( -1, 0 );
1166 if ( rowHeight(row) > 0 ) 1167 if ( rowHeight(row) > 0 )
1167 hideRow( row ); 1168 hideRow( row );
1168 } else { 1169 } else {
1169 if ( rowHeight(row) == 0 ) { 1170 if ( rowHeight(row) == 0 ) {
1170 showRow( row ); 1171 showRow( row );
1171 adjustRow( row ); 1172 adjustRow( row );
1172 } 1173 }
1173 visible++; 1174 visible++;
1174 } 1175 }
1175 } 1176 }
1176 if ( !visible ) 1177 if ( !visible )
1177 setCurrentCell( -1, 0 ); 1178 setCurrentCell( -1, 0 );
1178 1179
1179 setPaintingEnabled( TRUE ); 1180 setPaintingEnabled( TRUE );
1180} 1181}
1181 1182
1182 1183
1183void AbTable::setPaintingEnabled( bool e ) 1184void AbTable::setPaintingEnabled( bool e )
1184{ 1185{
1185 if ( e != enablePainting ) { 1186 if ( e != enablePainting ) {
1186 if ( !enablePainting ) { 1187 if ( !enablePainting ) {
1187 enablePainting = true; 1188 enablePainting = true;
1188 rowHeightChanged( 0 ); 1189 rowHeightChanged( 0 );
1189 viewport()->update(); 1190 viewport()->update();
1190 } else { 1191 } else {
1191 enablePainting = false; 1192 enablePainting = false;
1192 } 1193 }
1193 } 1194 }
1194} 1195}
1195 1196
1196void AbTable::rowHeightChanged( int row ) 1197void AbTable::rowHeightChanged( int row )
1197{ 1198{
1198 if ( enablePainting ) 1199 if ( enablePainting )
1199 QTable::rowHeightChanged( row ); 1200 QTable::rowHeightChanged( row );
1200} 1201}