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