summaryrefslogtreecommitdiffabout
path: root/kaddressbook
Unidiff
Diffstat (limited to 'kaddressbook') (more/less context) (ignore whitespace changes)
-rw-r--r--kaddressbook/views/cardview.cpp9
1 files changed, 4 insertions, 5 deletions
diff --git a/kaddressbook/views/cardview.cpp b/kaddressbook/views/cardview.cpp
index 84d3116..b6e053f 100644
--- a/kaddressbook/views/cardview.cpp
+++ b/kaddressbook/views/cardview.cpp
@@ -171,1554 +171,1553 @@ class CardViewPrivate
171 bool mDrawSeparators; 171 bool mDrawSeparators;
172 int mSepWidth; 172 int mSepWidth;
173 bool mShowEmptyFields; 173 bool mShowEmptyFields;
174 bool mLayoutDirty; 174 bool mLayoutDirty;
175 bool mLastClickOnItem; 175 bool mLastClickOnItem;
176 uint mItemMargin; // internal margin in items 176 uint mItemMargin; // internal margin in items
177 uint mItemSpacing; // spacing between items, column seperators and border 177 uint mItemSpacing; // spacing between items, column seperators and border
178 int mItemWidth; // width of all items 178 int mItemWidth; // width of all items
179 uint mMaxFieldLines; // Max lines to dispaly pr field 179 uint mMaxFieldLines; // Max lines to dispaly pr field
180 CardViewItem *mCurrentItem; 180 CardViewItem *mCurrentItem;
181 QPoint mLastClickPos; 181 QPoint mLastClickPos;
182 QTimer *mTimer; // times out if mouse rests for more than 500 msecs 182 QTimer *mTimer; // times out if mouse rests for more than 500 msecs
183 CardViewTip *mTip; // passed to the item under a resting cursor to display full text 183 CardViewTip *mTip; // passed to the item under a resting cursor to display full text
184 bool mOnSeparator; // set/reset on mouse movement 184 bool mOnSeparator; // set/reset on mouse movement
185 // for resizing by dragging the separators 185 // for resizing by dragging the separators
186 int mResizeAnchor; // uint, ulong? the mouse down separator left 186 int mResizeAnchor; // uint, ulong? the mouse down separator left
187 int mRubberBandAnchor; // for erasing rubber bands 187 int mRubberBandAnchor; // for erasing rubber bands
188 // data used for resizing. 188 // data used for resizing.
189 // as they are beeded by each mouse move while resizing, we store them here, 189 // as they are beeded by each mouse move while resizing, we store them here,
190 // saving 8 calculations in each mouse move. 190 // saving 8 calculations in each mouse move.
191 int colspace; // amount of space between items pr column 191 int colspace; // amount of space between items pr column
192 uint first; // the first col to anchor at for painting rubber bands 192 uint first; // the first col to anchor at for painting rubber bands
193 int firstX; // X position of first in pixel 193 int firstX; // X position of first in pixel
194 int pressed; // the colummn that was pressed on at resizing start 194 int pressed; // the colummn that was pressed on at resizing start
195 int span; // pressed - first 195 int span; // pressed - first
196 // key completion 196 // key completion
197 QString mCompText; // current completion string 197 QString mCompText; // current completion string
198 QDateTime mCompUpdated; // ...was updated at this time 198 QDateTime mCompUpdated; // ...was updated at this time
199}; 199};
200 200
201class CardViewItemPrivate 201class CardViewItemPrivate
202{ 202{
203 public: 203 public:
204 CardViewItemPrivate() : 204 CardViewItemPrivate() :
205 mSelected( false ), 205 mSelected( false ),
206 x( 0 ), 206 x( 0 ),
207 y( 0 ){}; 207 y( 0 ){};
208 208
209 209
210 QString mCaption; 210 QString mCaption;
211 QPtrList< CardViewItem::Field > mFieldList; 211 QPtrList< CardViewItem::Field > mFieldList;
212 bool mSelected; 212 bool mSelected;
213 int x; // horizontal position, set by the view 213 int x; // horizontal position, set by the view
214 int y; // vertical position, set by the view 214 int y; // vertical position, set by the view
215 int maxLabelWidth; // the width of the widest label, according to the view font. 215 int maxLabelWidth; // the width of the widest label, according to the view font.
216 int hcache; // height cache 216 int hcache; // height cache
217}; 217};
218//END Private Data 218//END Private Data
219 219
220//BEGIN CardViewItem 220//BEGIN CardViewItem
221 221
222CardViewItem::CardViewItem(CardView *parent, QString caption) 222CardViewItem::CardViewItem(CardView *parent, QString caption)
223 : d(new CardViewItemPrivate()), mView(parent) 223 : d(new CardViewItemPrivate()), mView(parent)
224{ 224{
225 d->mCaption = caption; 225 d->mCaption = caption;
226 226
227 initialize(); 227 initialize();
228} 228}
229 229
230CardViewItem::~CardViewItem() 230CardViewItem::~CardViewItem()
231{ 231{
232 // Remove ourself from the view 232 // Remove ourself from the view
233 if (mView != 0) 233 if (mView != 0)
234 mView->takeItem(this); 234 mView->takeItem(this);
235 235
236 delete d; 236 delete d;
237 d = 0; 237 d = 0;
238} 238}
239 239
240void CardViewItem::initialize() 240void CardViewItem::initialize()
241{ 241{
242 d->mSelected = false; 242 d->mSelected = false;
243 d->mFieldList.setAutoDelete(true); 243 d->mFieldList.setAutoDelete(true);
244 d->maxLabelWidth = 0; 244 d->maxLabelWidth = 0;
245 d->hcache=0; 245 d->hcache=0;
246 246
247 //calcRect(); 247 //calcRect();
248 248
249 // Add ourself to the view 249 // Add ourself to the view
250 if (mView != 0) 250 if (mView != 0)
251 mView->insertItem(this); 251 mView->insertItem(this);
252} 252}
253 253
254void CardViewItem::paintCard(QPainter *p, QColorGroup &cg) 254void CardViewItem::paintCard(QPainter *p, QColorGroup &cg)
255{ 255{
256 256
257 if (!mView) 257 if (!mView)
258 return; 258 return;
259 259
260 QPen pen; 260 QPen pen;
261 QBrush brush; 261 QBrush brush;
262 QFontMetrics fm = *(mView->d->mFm); 262 QFontMetrics fm = *(mView->d->mFm);
263 QFontMetrics bFm = *(mView->d->mBFm); 263 QFontMetrics bFm = *(mView->d->mBFm);
264 bool drawLabels = mView->d->mDrawFieldLabels; 264 bool drawLabels = mView->d->mDrawFieldLabels;
265 bool drawBorder = mView->d->mDrawCardBorder; 265 bool drawBorder = mView->d->mDrawCardBorder;
266 int mg = mView->itemMargin(); 266 int mg = mView->itemMargin();
267 int w = mView->itemWidth() - (mg*2); 267 int w = mView->itemWidth() - (mg*2);
268 int h = height() - (mg*2); 268 int h = height() - (mg*2);
269 const int colonWidth( fm.width(":") ); 269 const int colonWidth( fm.width(":") );
270 int labelXPos = 2 + mg; 270 int labelXPos = 2 + mg;
271 int labelWidth = QMIN( w/2 - 4 - mg, d->maxLabelWidth + colonWidth + 4 ); 271 int labelWidth = QMIN( w/2 - 4 - mg, d->maxLabelWidth + colonWidth + 4 );
272 int valueXPos = labelWidth + 4 + mg; 272 int valueXPos = labelWidth + 4 + mg;
273 int valueWidth = w - labelWidth - 4 - mg; 273 int valueWidth = w - labelWidth - 4 - mg;
274 274
275 p->setFont( mView->font() ); 275 p->setFont( mView->font() );
276 labelWidth -= colonWidth; // extra space for the colon 276 labelWidth -= colonWidth; // extra space for the colon
277 277
278 if (!drawLabels) 278 if (!drawLabels)
279 { 279 {
280 valueXPos = labelXPos; 280 valueXPos = labelXPos;
281 valueWidth = w - 4; 281 valueWidth = w - 4;
282 } 282 }
283 283
284 // Draw a simple box 284 // Draw a simple box
285 if (isSelected()) 285 if (isSelected())
286 pen = QPen(cg.highlight(), 1); 286 pen = QPen(cg.highlight(), 1);
287 else 287 else
288 pen = QPen(cg.button(), 1); 288 pen = QPen(cg.button(), 1);
289 p->setPen(pen); 289 p->setPen(pen);
290 290
291 // Draw the border - this is only draw if the user asks for it. 291 // Draw the border - this is only draw if the user asks for it.
292 if (drawBorder) 292 if (drawBorder)
293 p->drawRect( mg, mg, w, h ); 293 p->drawRect( mg, mg, w, h );
294 294
295 // set the proper pen color for the caption box 295 // set the proper pen color for the caption box
296 if (isSelected()) 296 if (isSelected())
297 brush = cg.brush(QColorGroup::Highlight); 297 brush = cg.brush(QColorGroup::Highlight);
298 else 298 else
299 brush = cg.brush(QColorGroup::Button); 299 brush = cg.brush(QColorGroup::Button);
300 300
301 p->fillRect(mg, mg, w, 4 + bFm.height(), brush); 301 p->fillRect(mg, mg, w, 4 + bFm.height(), brush);
302 302
303 // Now paint the caption 303 // Now paint the caption
304 p->save(); 304 p->save();
305 QFont bFont = mView->headerFont(); 305 QFont bFont = mView->headerFont();
306 //bFont.setBold(true); 306 //bFont.setBold(true);
307 p->setFont(bFont); 307 p->setFont(bFont);
308 if (isSelected()) 308 if (isSelected())
309 p->setPen(cg.highlightedText()); 309 p->setPen(cg.highlightedText());
310 else 310 else
311 p->setPen(cg.buttonText()); 311 p->setPen(cg.buttonText());
312 p->drawText(2+mg, 2+mg + bFm.ascent()/*bFm.height()*//*-bFm.descent()*//*-bFm.leading()*/, trimString(d->mCaption, w-4, bFm)); 312 p->drawText(2+mg, 2+mg + bFm.ascent()/*bFm.height()*//*-bFm.descent()*//*-bFm.leading()*/, trimString(d->mCaption, w-4, bFm));
313 p->restore(); 313 p->restore();
314 314
315 // Go through the fields and draw them 315 // Go through the fields and draw them
316 QPtrListIterator< CardViewItem::Field > iter(d->mFieldList); 316 QPtrListIterator< CardViewItem::Field > iter(d->mFieldList);
317 QString label, value; 317 QString label, value;
318 int yPos = mg + 4 + bFm.height()/* + 1*/ + fm.height(); // why the + 1 ??? (anders) 318 int yPos = mg + 4 + bFm.height()/* + 1*/ + fm.height(); // why the + 1 ??? (anders)
319 p->setPen(cg.text()); 319 p->setPen(cg.text());
320 320
321 int fh = fm.height(); 321 int fh = fm.height();
322 int cln( 0 ); 322 int cln( 0 );
323 QString tmp; 323 QString tmp;
324 int maxLines = mView->maxFieldLines(); 324 int maxLines = mView->maxFieldLines();
325 for (iter.toFirst(); iter.current(); ++iter) 325 for (iter.toFirst(); iter.current(); ++iter)
326 { 326 {
327 value = (*iter)->second; 327 value = (*iter)->second;
328 if ( value.isEmpty() && ! mView->d->mShowEmptyFields ) 328 if ( value.isEmpty() && ! mView->d->mShowEmptyFields )
329 continue; 329 continue;
330 330
331 if (drawLabels) 331 if (drawLabels)
332 { 332 {
333 label = trimString((*iter)->first, labelWidth, fm); 333 label = trimString((*iter)->first, labelWidth, fm);
334 p->drawText(labelXPos, yPos, label + ":"); 334 p->drawText(labelXPos, yPos, label + ":");
335 } 335 }
336/* US original 336/* US original
337 for (cln=0; cln <= maxLines; cln++) 337 for (cln=0; cln <= maxLines; cln++)
338 { 338 {
339 tmp = value.section('\n',cln,cln); 339 tmp = value.section('\n',cln,cln);
340 if ( !tmp.isEmpty() ) p->drawText( valueXPos, yPos + cln*fh, trimString( tmp, valueWidth, fm ) ); 340 if ( !tmp.isEmpty() ) p->drawText( valueXPos, yPos + cln*fh, trimString( tmp, valueWidth, fm ) );
341 else break; 341 else break;
342 } 342 }
343*/ 343*/
344 344
345//US new implementation 345//US new implementation
346 QStringList strlst = QStringList::split('\n', value, true); 346 QStringList strlst = QStringList::split('\n', value, true);
347 347
348 for (cln=0; cln <= maxLines && cln <= (int)strlst.count(); cln++) 348 for (cln=0; cln <= maxLines && cln <= (int)strlst.count(); cln++)
349 { 349 {
350 tmp = strlst[cln]; 350 tmp = strlst[cln];
351 351
352 if ( !tmp.isEmpty() ) 352 if ( !tmp.isEmpty() )
353 p->drawText( valueXPos, yPos + cln*fh, trimString( tmp, valueWidth, fm ) ); 353 p->drawText( valueXPos, yPos + cln*fh, trimString( tmp, valueWidth, fm ) );
354 else 354 else
355 break; 355 break;
356 356
357 } 357 }
358 358
359 if ( cln == 0 ) cln = 1; 359 if ( cln == 0 ) cln = 1;
360 yPos += cln * fh + 2; 360 yPos += cln * fh + 2;
361 } 361 }
362 362
363 // if we are the current item and the view has focus, draw focus rect 363 // if we are the current item and the view has focus, draw focus rect
364 if ( mView->currentItem() == this && mView->hasFocus() ) 364 if ( mView->currentItem() == this && mView->hasFocus() )
365 { 365 {
366/*US 366/*US
367 mView->style().drawPrimitive( QStyle::PE_FocusRect, p, 367 mView->style().drawPrimitive( QStyle::PE_FocusRect, p,
368 QRect(0, 0, mView->itemWidth(), h+(2*mg)), cg, 368 QRect(0, 0, mView->itemWidth(), h+(2*mg)), cg,
369 QStyle::Style_FocusAtBorder, 369 QStyle::Style_FocusAtBorder,
370 QStyleOption( isSelected() ? cg.highlight() : cg.base() ) ); 370 QStyleOption( isSelected() ? cg.highlight() : cg.base() ) );
371*/ 371*/
372 372
373 const QColor pHighl = isSelected() ? cg.highlight() : cg.base(); 373 const QColor pHighl = isSelected() ? cg.highlight() : cg.base();
374 const QRect r(0, 0, mView->itemWidth(), h+(2*mg)); 374 const QRect r(0, 0, mView->itemWidth(), h+(2*mg));
375#ifndef DESKTOP_VERSION 375#ifndef DESKTOP_VERSION
376 mView->style().drawFocusRect(p, r, cg, &pHighl, true); 376 mView->style().drawFocusRect(p, r, cg, &pHighl, true);
377#endif 377#endif
378 } 378 }
379} 379}
380 380
381const QString &CardViewItem::caption() const 381const QString &CardViewItem::caption() const
382{ 382{
383 return d->mCaption; 383 return d->mCaption;
384} 384}
385 385
386 386
387int CardViewItem::height( bool allowCache ) const 387int CardViewItem::height( bool allowCache ) const
388{ 388{
389 // use cache 389 // use cache
390 if ( allowCache && d->hcache ) 390 if ( allowCache && d->hcache )
391 return d->hcache; 391 return d->hcache;
392 392
393 // Base height: 393 // Base height:
394 // 2 for line width 394 // 2 for line width
395 // 2 for top caption pad 395 // 2 for top caption pad
396 // 2 for bottom caption pad 396 // 2 for bottom caption pad
397 // 2 pad for the end 397 // 2 pad for the end
398 // + 2 times the advised margin 398 // + 2 times the advised margin
399 int baseHeight = 8 + ( 2 * mView->itemMargin() ); 399 int baseHeight = 8 + ( 2 * mView->itemMargin() );
400 400
401 // size of font for each field 401 // size of font for each field
402 // 2 pad for each field 402 // 2 pad for each field
403 403
404 // anders: if the view does not show empty fields, check for value 404 // anders: if the view does not show empty fields, check for value
405 bool sef = mView->showEmptyFields(); 405 bool sef = mView->showEmptyFields();
406 int fh = mView->d->mFm->height();//lineSpacing(); // font height 406 int fh = mView->d->mFm->height();//lineSpacing(); // font height
407 //int sp = QMAX( 0, 2- mView->d->mFm->leading() ); // field spacing NOTE make a property 407 //int sp = QMAX( 0, 2- mView->d->mFm->leading() ); // field spacing NOTE make a property
408 int fieldHeight = 0; 408 int fieldHeight = 0;
409 int lines; 409 int lines;
410 int maxLines( mView->maxFieldLines() ); 410 int maxLines( mView->maxFieldLines() );
411 QPtrListIterator< CardViewItem::Field > iter(d->mFieldList); 411 QPtrListIterator< CardViewItem::Field > iter(d->mFieldList);
412 for (iter.toFirst(); iter.current(); ++iter) 412 for (iter.toFirst(); iter.current(); ++iter)
413 { 413 {
414 if ( !sef && (*iter)->second.isEmpty() ) 414 if ( !sef && (*iter)->second.isEmpty() )
415 continue; 415 continue;
416 lines = QMIN( (*iter)->second.contains('\n') + 1, maxLines ); 416 lines = QMIN( (*iter)->second.contains('\n') + 1, maxLines );
417 fieldHeight += ( lines * fh ) + 2;//sp; 417 fieldHeight += ( lines * fh ) + 2;//sp;
418 } 418 }
419 419
420 // height of caption font (bold) 420 // height of caption font (bold)
421 fieldHeight += mView->d->mBFm->height(); 421 fieldHeight += mView->d->mBFm->height();
422 d->hcache = baseHeight + fieldHeight; 422 d->hcache = baseHeight + fieldHeight;
423 return d->hcache; 423 return d->hcache;
424} 424}
425 425
426bool CardViewItem::isSelected() const 426bool CardViewItem::isSelected() const
427{ 427{
428 return d->mSelected; 428 return d->mSelected;
429} 429}
430 430
431void CardViewItem::setSelected(bool selected) 431void CardViewItem::setSelected(bool selected)
432{ 432{
433 d->mSelected = selected; 433 d->mSelected = selected;
434} 434}
435 435
436void CardViewItem::insertField(const QString &label, const QString &value) 436void CardViewItem::insertField(const QString &label, const QString &value)
437{ 437{
438 CardViewItem::Field *f = new CardViewItem::Field(label, value); 438 CardViewItem::Field *f = new CardViewItem::Field(label, value);
439 d->mFieldList.append(f); 439 d->mFieldList.append(f);
440 d->hcache=0; 440 d->hcache=0;
441 441
442 if (mView) 442 if (mView)
443 { 443 {
444 mView->setLayoutDirty(true); 444 mView->setLayoutDirty(true);
445 d->maxLabelWidth = QMAX( mView->d->mFm->width( label ), d->maxLabelWidth ); 445 d->maxLabelWidth = QMAX( mView->d->mFm->width( label ), d->maxLabelWidth );
446 } 446 }
447} 447}
448 448
449void CardViewItem::removeField(const QString &label) 449void CardViewItem::removeField(const QString &label)
450{ 450{
451 CardViewItem::Field *f; 451 CardViewItem::Field *f;
452 452
453 QPtrListIterator< CardViewItem::Field > iter(d->mFieldList); 453 QPtrListIterator< CardViewItem::Field > iter(d->mFieldList);
454 for (iter.toFirst(); iter.current(); ++iter) 454 for (iter.toFirst(); iter.current(); ++iter)
455 { 455 {
456 f = *iter; 456 f = *iter;
457 if (f->first == label) 457 if (f->first == label)
458 break; 458 break;
459 } 459 }
460 460
461 if (*iter) 461 if (*iter)
462 d->mFieldList.remove(*iter); 462 d->mFieldList.remove(*iter);
463 d->hcache = 0; 463 d->hcache = 0;
464 464
465 if (mView) 465 if (mView)
466 mView->setLayoutDirty(true); 466 mView->setLayoutDirty(true);
467} 467}
468 468
469void CardViewItem::clearFields() 469void CardViewItem::clearFields()
470{ 470{
471 d->mFieldList.clear(); 471 d->mFieldList.clear();
472 d->hcache = 0; 472 d->hcache = 0;
473 473
474 if (mView) 474 if (mView)
475 mView->setLayoutDirty(true); 475 mView->setLayoutDirty(true);
476} 476}
477 477
478QString CardViewItem::trimString(const QString &text, int width, 478QString CardViewItem::trimString(const QString &text, int width,
479 QFontMetrics &fm) 479 QFontMetrics &fm)
480{ 480{
481 if (fm.width(text) <= width) 481 if (fm.width(text) <= width)
482 return text; 482 return text;
483 483
484 QString dots = "..."; 484 QString dots = "...";
485 int dotWidth = fm.width(dots); 485 int dotWidth = fm.width(dots);
486 QString trimmed; 486 QString trimmed;
487 int charNum = 0; 487 int charNum = 0;
488 488
489 while (fm.width(trimmed) + dotWidth < width) 489 while (fm.width(trimmed) + dotWidth < width)
490 { 490 {
491 trimmed += text[charNum]; 491 trimmed += text[charNum];
492 charNum++; 492 charNum++;
493 } 493 }
494 494
495 // Now trim the last char, since it put the width over the top 495 // Now trim the last char, since it put the width over the top
496 trimmed = trimmed.left(trimmed.length()-1); 496 trimmed = trimmed.left(trimmed.length()-1);
497 trimmed += dots; 497 trimmed += dots;
498 498
499 return trimmed; 499 return trimmed;
500} 500}
501 501
502CardViewItem *CardViewItem::nextItem() 502CardViewItem *CardViewItem::nextItem()
503{ 503{
504 CardViewItem *item = 0; 504 CardViewItem *item = 0;
505 505
506 if (mView) 506 if (mView)
507 item = mView->itemAfter(this); 507 item = mView->itemAfter(this);
508 508
509 return item; 509 return item;
510} 510}
511 511
512void CardViewItem::repaintCard() 512void CardViewItem::repaintCard()
513{ 513{
514 if (mView) 514 if (mView)
515 mView->repaintItem(this); 515 mView->repaintItem(this);
516} 516}
517 517
518void CardViewItem::setCaption(const QString &caption) 518void CardViewItem::setCaption(const QString &caption)
519{ 519{
520 d->mCaption = caption; 520 d->mCaption = caption;
521 repaintCard(); 521 repaintCard();
522} 522}
523 523
524QString CardViewItem::fieldValue(const QString &label) 524QString CardViewItem::fieldValue(const QString &label)
525{ 525{
526 QPtrListIterator< CardViewItem::Field > iter(d->mFieldList); 526 QPtrListIterator< CardViewItem::Field > iter(d->mFieldList);
527 for (iter.toFirst(); iter.current(); ++iter) 527 for (iter.toFirst(); iter.current(); ++iter)
528 if ((*iter)->first == label) 528 if ((*iter)->first == label)
529 return (*iter)->second; 529 return (*iter)->second;
530 530
531 return QString(); 531 return QString();
532} 532}
533 533
534 534
535void CardViewItem::showFullString( const QPoint &itempos, CardViewTip *tip ) 535void CardViewItem::showFullString( const QPoint &itempos, CardViewTip *tip )
536{ 536{
537 bool trimmed( false ); 537 bool trimmed( false );
538 QString s; 538 QString s;
539 int mrg = mView->itemMargin(); 539 int mrg = mView->itemMargin();
540 int y = mView->d->mBFm->height() + 6 + mrg; 540 int y = mView->d->mBFm->height() + 6 + mrg;
541 int w = mView->itemWidth() - (2*mrg); 541 int w = mView->itemWidth() - (2*mrg);
542 int lw; 542 int lw;
543 bool drawLabels = mView->drawFieldLabels(); 543 bool drawLabels = mView->drawFieldLabels();
544 bool isLabel = drawLabels && itempos.x() < w/2 ? true : false; 544 bool isLabel = drawLabels && itempos.x() < w/2 ? true : false;
545 545
546 if ( itempos.y() < y ) 546 if ( itempos.y() < y )
547 { 547 {
548 if ( itempos.y() < 8 + mrg || itempos.y() > y - 4 ) 548 if ( itempos.y() < 8 + mrg || itempos.y() > y - 4 )
549 return; 549 return;
550 // this is the caption 550 // this is the caption
551 s = caption(); 551 s = caption();
552 trimmed = mView->d->mBFm->width( s ) > w - 4; 552 trimmed = mView->d->mBFm->width( s ) > w - 4;
553 y = 2 + mrg; 553 y = 2 + mrg;
554 lw = 0; 554 lw = 0;
555 isLabel=true; 555 isLabel=true;
556 } else { 556 } else {
557 // find the field 557 // find the field
558 Field *f = fieldAt( itempos ); 558 Field *f = fieldAt( itempos );
559 if ( !f || ( !mView->showEmptyFields() && f->second.isEmpty() ) ) 559 if ( !f || ( !mView->showEmptyFields() && f->second.isEmpty() ) )
560 return; 560 return;
561 561
562 // y position: 562 // y position:
563 // header font height + 4px hader margin + 2px leading + item margin 563 // header font height + 4px hader margin + 2px leading + item margin
564 // + actual field index * (fontheight + 2px leading) 564 // + actual field index * (fontheight + 2px leading)
565 int maxLines = mView->maxFieldLines(); 565 int maxLines = mView->maxFieldLines();
566 bool se = mView->showEmptyFields(); 566 bool se = mView->showEmptyFields();
567 int fh = mView->d->mFm->height(); 567 int fh = mView->d->mFm->height();
568// { 568// {
569 Field *_f; 569 Field *_f;
570 for (_f = d->mFieldList.first(); _f != f; _f = d->mFieldList.next()) 570 for (_f = d->mFieldList.first(); _f != f; _f = d->mFieldList.next())
571 if ( se || ! _f->second.isEmpty() ) 571 if ( se || ! _f->second.isEmpty() )
572 y += ( QMIN(_f->second.contains('\n')+1, maxLines) * fh ) + 2; 572 y += ( QMIN(_f->second.contains('\n')+1, maxLines) * fh ) + 2;
573// } 573// }
574 if ( isLabel && itempos.y() > y + fh ) 574 if ( isLabel && itempos.y() > y + fh )
575 return; 575 return;
576 // label or data? 576 // label or data?
577 s = isLabel ? f->first : f->second; 577 s = isLabel ? f->first : f->second;
578 // trimmed? 578 // trimmed?
579 int colonWidth = mView->d->mFm->width(":"); 579 int colonWidth = mView->d->mFm->width(":");
580 lw = drawLabels ? // label width 580 lw = drawLabels ? // label width
581 QMIN( w/2 - 4 - mrg, d->maxLabelWidth + colonWidth + 4 ) : 581 QMIN( w/2 - 4 - mrg, d->maxLabelWidth + colonWidth + 4 ) :
582 0; 582 0;
583 int mw = isLabel ? lw - colonWidth : w - lw - (mrg*2); // max width for string 583 int mw = isLabel ? lw - colonWidth : w - lw - (mrg*2); // max width for string
584 if ( isLabel ) 584 if ( isLabel )
585 { 585 {
586 trimmed = mView->d->mFm->width( s ) > mw - colonWidth; 586 trimmed = mView->d->mFm->width( s ) > mw - colonWidth;
587 } else { 587 } else {
588 QRect r( mView->d->mFm->boundingRect( 0, 0, INT_MAX, INT_MAX, Qt::AlignTop|Qt::AlignLeft, s ) ); 588 QRect r( mView->d->mFm->boundingRect( 0, 0, INT_MAX, INT_MAX, Qt::AlignTop|Qt::AlignLeft, s ) );
589 trimmed = r.width() > mw || r.height()/fh > QMIN(s.contains('\n') + 1, maxLines); 589 trimmed = r.width() > mw || r.height()/fh > QMIN(s.contains('\n') + 1, maxLines);
590 } 590 }
591 } 591 }
592 if ( trimmed ) 592 if ( trimmed )
593 { 593 {
594 tip->setFont( (isLabel && !lw) ? mView->headerFont() : mView->font() ); // if condition is true, a header 594 tip->setFont( (isLabel && !lw) ? mView->headerFont() : mView->font() ); // if condition is true, a header
595 tip->setText( s ); 595 tip->setText( s );
596 tip->adjustSize(); 596 tip->adjustSize();
597 // find a proper position 597 // find a proper position
598 int lx; 598 int lx;
599 lx = isLabel || !drawLabels ? mrg : lw + mrg + 2 /*-1*/; 599 lx = isLabel || !drawLabels ? mrg : lw + mrg + 2 /*-1*/;
600 QPoint pnt(mView->contentsToViewport( QPoint(d->x, d->y) )); 600 QPoint pnt(mView->contentsToViewport( QPoint(d->x, d->y) ));
601 pnt += QPoint(lx, y); 601 pnt += QPoint(lx, y);
602 if ( pnt.x() < 0 ) 602 if ( pnt.x() < 0 )
603 pnt.setX( 0 ); 603 pnt.setX( 0 );
604 if ( pnt.x() + tip->width() > mView->visibleWidth() ) 604 if ( pnt.x() + tip->width() > mView->visibleWidth() )
605 pnt.setX( mView->visibleWidth() - tip->width() ); 605 pnt.setX( mView->visibleWidth() - tip->width() );
606 if ( pnt.y() + tip->height() > mView->visibleHeight() ) 606 if ( pnt.y() + tip->height() > mView->visibleHeight() )
607 pnt.setY( QMAX( 0, mView->visibleHeight() - tip->height() ) ); 607 pnt.setY( QMAX( 0, mView->visibleHeight() - tip->height() ) );
608 // show 608 // show
609 tip->move( pnt ); 609 tip->move( pnt );
610 tip->show(); 610 tip->show();
611 } 611 }
612} 612}
613 613
614CardViewItem::Field *CardViewItem::fieldAt( const QPoint & itempos ) const 614CardViewItem::Field *CardViewItem::fieldAt( const QPoint & itempos ) const
615{ 615{
616 int ypos = mView->d->mBFm->height() + 7 + mView->d->mItemMargin; 616 int ypos = mView->d->mBFm->height() + 7 + mView->d->mItemMargin;
617 int iy = itempos.y(); 617 int iy = itempos.y();
618 // skip below caption 618 // skip below caption
619 if ( iy <= ypos ) 619 if ( iy <= ypos )
620 return 0; 620 return 0;
621 // try find a field 621 // try find a field
622 bool showEmpty = mView->showEmptyFields(); 622 bool showEmpty = mView->showEmptyFields();
623 int fh = mView->d->mFm->height(); 623 int fh = mView->d->mFm->height();
624 int maxLines = mView->maxFieldLines(); 624 int maxLines = mView->maxFieldLines();
625 Field *f; 625 Field *f;
626 for ( f = d->mFieldList.first(); f; f = d->mFieldList.next() ) 626 for ( f = d->mFieldList.first(); f; f = d->mFieldList.next() )
627 { 627 {
628 if ( showEmpty || !f->second.isEmpty() ) 628 if ( showEmpty || !f->second.isEmpty() )
629 ypos += ( QMIN( f->second.contains('\n')+1, maxLines ) *fh)+2; 629 ypos += ( QMIN( f->second.contains('\n')+1, maxLines ) *fh)+2;
630 if ( iy <= ypos ) 630 if ( iy <= ypos )
631 break; 631 break;
632 } 632 }
633 return f ? f : 0; 633 return f ? f : 0;
634} 634}
635//END CardViewItem 635//END CardViewItem
636 636
637//BEGIN CardView 637//BEGIN CardView
638 638
639CardView::CardView(QWidget *parent, const char *name) 639CardView::CardView(QWidget *parent, const char *name)
640 : QScrollView(parent, name), 640 : QScrollView(parent, name),
641 d(new CardViewPrivate()) 641 d(new CardViewPrivate())
642{ 642{
643 mFlagKeyPressed = false; 643 mFlagKeyPressed = false;
644 mFlagBlockKeyPressed = false; 644 mFlagBlockKeyPressed = false;
645 d->mItemList.setAutoDelete(true); 645 d->mItemList.setAutoDelete(true);
646 d->mSeparatorList.setAutoDelete(true); 646 d->mSeparatorList.setAutoDelete(true);
647 647
648 QFont f = font(); 648 QFont f = font();
649 d->mFm = new QFontMetrics(f); 649 d->mFm = new QFontMetrics(f);
650 f.setBold(true); 650 f.setBold(true);
651 d->mHeaderFont = f; 651 d->mHeaderFont = f;
652 d->mBFm = new QFontMetrics(f); 652 d->mBFm = new QFontMetrics(f);
653 d->mTip = ( new CardViewTip( viewport() ) ), 653 d->mTip = ( new CardViewTip( viewport() ) ),
654 d->mTip->hide(); 654 d->mTip->hide();
655 d->mTimer = ( new QTimer(this, "mouseTimer") ), 655 d->mTimer = ( new QTimer(this, "mouseTimer") ),
656 656
657 viewport()->setMouseTracking( true ); 657 viewport()->setMouseTracking( true );
658 viewport()->setFocusProxy(this); 658 viewport()->setFocusProxy(this);
659 viewport()->setFocusPolicy(WheelFocus); 659 viewport()->setFocusPolicy(WheelFocus);
660 viewport()->setBackgroundMode(PaletteBase); 660 viewport()->setBackgroundMode(PaletteBase);
661 661
662 connect( d->mTimer, SIGNAL(timeout()), this, SLOT(tryShowFullText()) ); 662 connect( d->mTimer, SIGNAL(timeout()), this, SLOT(tryShowFullText()) );
663 663
664//US setBackgroundMode(PaletteBackground, PaletteBase); 664//US setBackgroundMode(PaletteBackground, PaletteBase);
665 setBackgroundMode(PaletteBackground); 665 setBackgroundMode(PaletteBackground);
666 666
667 // no reason for a vertical scrollbar 667 // no reason for a vertical scrollbar
668 setVScrollBarMode(AlwaysOff); 668 setVScrollBarMode(AlwaysOff);
669} 669}
670 670
671CardView::~CardView() 671CardView::~CardView()
672{ 672{
673 delete d->mFm; 673 delete d->mFm;
674 delete d->mBFm; 674 delete d->mBFm;
675 delete d; 675 delete d;
676 d = 0; 676 d = 0;
677} 677}
678 678
679void CardView::insertItem(CardViewItem *item) 679void CardView::insertItem(CardViewItem *item)
680{ 680{
681 d->mItemList.inSort(item); 681 d->mItemList.inSort(item);
682 setLayoutDirty(true); 682 setLayoutDirty(true);
683} 683}
684 684
685void CardView::takeItem(CardViewItem *item) 685void CardView::takeItem(CardViewItem *item)
686{ 686{
687 if ( d->mCurrentItem == item ) 687 if ( d->mCurrentItem == item )
688 d->mCurrentItem = item->nextItem(); 688 d->mCurrentItem = item->nextItem();
689 d->mItemList.take(d->mItemList.findRef(item)); 689 d->mItemList.take(d->mItemList.findRef(item));
690 690
691 setLayoutDirty(true); 691 setLayoutDirty(true);
692} 692}
693 693
694void CardView::clear() 694void CardView::clear()
695{ 695{
696 d->mItemList.clear(); 696 d->mItemList.clear();
697 697
698 setLayoutDirty(true); 698 setLayoutDirty(true);
699} 699}
700 700
701CardViewItem *CardView::currentItem() 701CardViewItem *CardView::currentItem()
702{ 702{
703 if ( ! d->mCurrentItem && d->mItemList.count() ) 703 if ( ! d->mCurrentItem && d->mItemList.count() )
704 d->mCurrentItem = d->mItemList.first(); 704 d->mCurrentItem = d->mItemList.first();
705 return d->mCurrentItem; 705 return d->mCurrentItem;
706} 706}
707 707
708void CardView::setCurrentItem( CardViewItem *item ) 708void CardView::setCurrentItem( CardViewItem *item )
709{ 709{
710 if ( !item ) 710 if ( !item )
711 return; 711 return;
712 else if ( item->cardView() != this ) 712 else if ( item->cardView() != this )
713 { 713 {
714 kdDebug(5720)<<"CardView::setCurrentItem: Item ("<<item<<") not owned! Backing out.."<<endl; 714 kdDebug(5720)<<"CardView::setCurrentItem: Item ("<<item<<") not owned! Backing out.."<<endl;
715 return; 715 return;
716 } 716 }
717 else if ( item == currentItem() ) 717 else if ( item == currentItem() )
718 { 718 {
719 return; 719 return;
720 } 720 }
721 721
722 if ( d->mSelectionMode == Single ) 722 if ( d->mSelectionMode == Single )
723 { 723 {
724 setSelected( item, true ); 724 setSelected( item, true );
725 } 725 }
726 else 726 else
727 { 727 {
728 CardViewItem *it = d->mCurrentItem; 728 CardViewItem *it = d->mCurrentItem;
729 d->mCurrentItem = item; 729 d->mCurrentItem = item;
730 if ( it ) 730 if ( it )
731 it->repaintCard(); 731 it->repaintCard();
732 item->repaintCard(); 732 item->repaintCard();
733 } 733 }
734 if ( ! d->mOnSeparator ) 734 if ( ! d->mOnSeparator )
735 ensureItemVisible( item ); 735 ensureItemVisible( item );
736 emit currentChanged( item ); 736 emit currentChanged( item );
737} 737}
738 738
739CardViewItem *CardView::itemAt(const QPoint &viewPos) 739CardViewItem *CardView::itemAt(const QPoint &viewPos)
740{ 740{
741 CardViewItem *item = 0; 741 CardViewItem *item = 0;
742 QPtrListIterator<CardViewItem> iter(d->mItemList); 742 QPtrListIterator<CardViewItem> iter(d->mItemList);
743 bool found = false; 743 bool found = false;
744 for (iter.toFirst(); iter.current() && !found; ++iter) 744 for (iter.toFirst(); iter.current() && !found; ++iter)
745 { 745 {
746 item = *iter; 746 item = *iter;
747 //if (item->d->mRect.contains(viewPos)) 747 //if (item->d->mRect.contains(viewPos))
748 if (QRect(item->d->x, item->d->y, d->mItemWidth, item->height()).contains(viewPos)) 748 if (QRect(item->d->x, item->d->y, d->mItemWidth, item->height()).contains(viewPos))
749 found = true; 749 found = true;
750 } 750 }
751 751
752 if (found) 752 if (found)
753 return item; 753 return item;
754 754
755 return 0; 755 return 0;
756} 756}
757 757
758QRect CardView::itemRect(const CardViewItem *item) 758QRect CardView::itemRect(const CardViewItem *item)
759{ 759{
760 //return item->d->mRect; 760 //return item->d->mRect;
761 return QRect(item->d->x, item->d->y, d->mItemWidth, item->height()); 761 return QRect(item->d->x, item->d->y, d->mItemWidth, item->height());
762} 762}
763 763
764void CardView::ensureItemVisible(const CardViewItem *item) 764void CardView::ensureItemVisible(const CardViewItem *item)
765{ 765{
766 ensureVisible(item->d->x , item->d->y, d->mItemSpacing, 0); 766 ensureVisible(item->d->x , item->d->y, d->mItemSpacing, 0);
767 ensureVisible(item->d->x + d->mItemWidth, item->d->y, d->mItemSpacing, 0); 767 ensureVisible(item->d->x + d->mItemWidth, item->d->y, d->mItemSpacing, 0);
768} 768}
769 769
770void CardView::repaintItem(const CardViewItem *item) 770void CardView::repaintItem(const CardViewItem *item)
771{ 771{
772 //repaintContents(item->d->mRect); 772 //repaintContents(item->d->mRect);
773 repaintContents( QRect(item->d->x, item->d->y, d->mItemWidth, item->height()) ); 773 repaintContents( QRect(item->d->x, item->d->y, d->mItemWidth, item->height()) );
774} 774}
775 775
776void CardView::setSelectionMode(CardView::SelectionMode mode) 776void CardView::setSelectionMode(CardView::SelectionMode mode)
777{ 777{
778 selectAll(false); 778 selectAll(false);
779 779
780 d->mSelectionMode = mode; 780 d->mSelectionMode = mode;
781} 781}
782 782
783CardView::SelectionMode CardView::selectionMode() const 783CardView::SelectionMode CardView::selectionMode() const
784{ 784{
785 return d->mSelectionMode; 785 return d->mSelectionMode;
786} 786}
787 787
788void CardView::selectAll(bool state) 788void CardView::selectAll(bool state)
789{ 789{
790 QPtrListIterator<CardViewItem> iter(d->mItemList); 790 QPtrListIterator<CardViewItem> iter(d->mItemList);
791 if (!state) 791 if (!state)
792 { 792 {
793 for (iter.toFirst(); iter.current(); ++iter) 793 for (iter.toFirst(); iter.current(); ++iter)
794 { 794 {
795 if ((*iter)->isSelected()) 795 if ((*iter)->isSelected())
796 { 796 {
797 (*iter)->setSelected(false); 797 (*iter)->setSelected(false);
798 (*iter)->repaintCard(); 798 (*iter)->repaintCard();
799 } 799 }
800 } 800 }
801 //emit selectionChanged(); // WARNING FIXME 801 //emit selectionChanged(); // WARNING FIXME
802 emit selectionChanged(0); 802 emit selectionChanged(0);
803 } 803 }
804 else if (d->mSelectionMode != CardView::Single) 804 else if (d->mSelectionMode != CardView::Single)
805 { 805 {
806 for (iter.toFirst(); iter.current(); ++iter) 806 for (iter.toFirst(); iter.current(); ++iter)
807 { 807 {
808 (*iter)->setSelected(true); 808 (*iter)->setSelected(true);
809 } 809 }
810 810
811 if (d->mItemList.count() > 0) 811 if (d->mItemList.count() > 0)
812 { 812 {
813 // emit, since there must have been at least one selected 813 // emit, since there must have been at least one selected
814 emit selectionChanged(); 814 emit selectionChanged();
815 //repaint();//??? 815 //repaint();//???
816 viewport()->update(); 816 viewport()->update();
817 } 817 }
818 } 818 }
819} 819}
820 820
821void CardView::setSelected(CardViewItem *item, bool selected) 821void CardView::setSelected(CardViewItem *item, bool selected)
822{ 822{
823 if ((item == 0) || (item->isSelected() == selected)) 823 if ((item == 0) || (item->isSelected() == selected))
824 return; 824 return;
825 825
826 if ( selected && d->mCurrentItem != item ) 826 if ( selected && d->mCurrentItem != item )
827 { 827 {
828 CardViewItem *it = d->mCurrentItem; 828 CardViewItem *it = d->mCurrentItem;
829 d->mCurrentItem = item; 829 d->mCurrentItem = item;
830 if ( it ) 830 if ( it )
831 it->repaintCard(); 831 it->repaintCard();
832 } 832 }
833 833
834 if (d->mSelectionMode == CardView::Single) 834 if (d->mSelectionMode == CardView::Single)
835 { 835 {
836 bool b = signalsBlocked(); 836 bool b = signalsBlocked();
837 blockSignals(true); 837 blockSignals(true);
838 selectAll(false); 838 selectAll(false);
839 blockSignals(b); 839 blockSignals(b);
840 840
841 if (selected) 841 if (selected)
842 { 842 {
843 item->setSelected(selected); 843 item->setSelected(selected);
844 item->repaintCard(); 844 item->repaintCard();
845 emit selectionChanged(); 845 emit selectionChanged();
846 emit selectionChanged(item); 846 emit selectionChanged(item);
847 } 847 }
848 else 848 else
849 { 849 {
850 emit selectionChanged(); 850 emit selectionChanged();
851 emit selectionChanged(0); 851 emit selectionChanged(0);
852 } 852 }
853 } 853 }
854 else if (d->mSelectionMode == CardView::Multi) 854 else if (d->mSelectionMode == CardView::Multi)
855 { 855 {
856 item->setSelected(selected); 856 item->setSelected(selected);
857 item->repaintCard(); 857 item->repaintCard();
858 emit selectionChanged(); 858 emit selectionChanged();
859 } 859 }
860 else if (d->mSelectionMode == CardView::Extended) 860 else if (d->mSelectionMode == CardView::Extended)
861 { 861 {
862 bool b = signalsBlocked(); 862 bool b = signalsBlocked();
863 blockSignals(true); 863 blockSignals(true);
864 selectAll(false); 864 selectAll(false);
865 blockSignals(b); 865 blockSignals(b);
866 866
867 item->setSelected(selected); 867 item->setSelected(selected);
868 item->repaintCard(); 868 item->repaintCard();
869 emit selectionChanged(); 869 emit selectionChanged();
870 } 870 }
871} 871}
872 872
873bool CardView::isSelected(CardViewItem *item) const 873bool CardView::isSelected(CardViewItem *item) const
874{ 874{
875 return (item && item->isSelected()); 875 return (item && item->isSelected());
876} 876}
877 877
878CardViewItem *CardView::selectedItem() const 878CardViewItem *CardView::selectedItem() const
879{ 879{
880 // find the first selected item 880 // find the first selected item
881 QPtrListIterator<CardViewItem> iter(d->mItemList); 881 QPtrListIterator<CardViewItem> iter(d->mItemList);
882 for (iter.toFirst(); iter.current(); ++iter) 882 for (iter.toFirst(); iter.current(); ++iter)
883 { 883 {
884 if ((*iter)->isSelected()) 884 if ((*iter)->isSelected())
885 return *iter; 885 return *iter;
886 } 886 }
887 887
888 return 0; 888 return 0;
889} 889}
890 890
891CardViewItem *CardView::firstItem() const 891CardViewItem *CardView::firstItem() const
892{ 892{
893 return d->mItemList.first(); 893 return d->mItemList.first();
894} 894}
895 895
896int CardView::childCount() const 896int CardView::childCount() const
897{ 897{
898 return d->mItemList.count(); 898 return d->mItemList.count();
899} 899}
900/*US 900/*US
901CardViewItem *CardView::findItem(const QString &text, const QString &label, 901CardViewItem *CardView::findItem(const QString &text, const QString &label,
902 Qt::StringComparisonMode compare) 902 Qt::StringComparisonMode compare)
903{ 903{
904 // IF the text is empty, we will return null, since empty text will 904 // IF the text is empty, we will return null, since empty text will
905 // match anything! 905 // match anything!
906 if (text.isEmpty()) 906 if (text.isEmpty())
907 return 0; 907 return 0;
908 908
909 QPtrListIterator<CardViewItem> iter(d->mItemList); 909 QPtrListIterator<CardViewItem> iter(d->mItemList);
910 if (compare & Qt::BeginsWith) 910 if (compare & Qt::BeginsWith)
911 { 911 {
912 QString value; 912 QString value;
913 for (iter.toFirst(); iter.current(); ++iter) 913 for (iter.toFirst(); iter.current(); ++iter)
914 { 914 {
915 value = (*iter)->fieldValue(label).upper(); 915 value = (*iter)->fieldValue(label).upper();
916 if (value.startsWith(text.upper())) 916 if (value.startsWith(text.upper()))
917 return *iter; 917 return *iter;
918 } 918 }
919 } 919 }
920 else 920 else
921 { 921 {
922 kdDebug(5720) << "CardView::findItem: search method not implemented" << endl; 922 kdDebug(5720) << "CardView::findItem: search method not implemented" << endl;
923 } 923 }
924 924
925 return 0; 925 return 0;
926} 926}
927*/ 927*/
928 928
929uint CardView::columnWidth() 929uint CardView::columnWidth()
930{ 930{
931 return d->mDrawSeparators ? 931 return d->mDrawSeparators ?
932 d->mItemWidth + ( 2 * d->mItemSpacing ) + d->mSepWidth : 932 d->mItemWidth + ( 2 * d->mItemSpacing ) + d->mSepWidth :
933 d->mItemWidth + d->mItemSpacing; 933 d->mItemWidth + d->mItemSpacing;
934} 934}
935 935
936void CardView::drawContents(QPainter *p, int clipx, int clipy, 936void CardView::drawContents(QPainter *p, int clipx, int clipy,
937 int clipw, int cliph) 937 int clipw, int cliph)
938{ 938{
939 QScrollView::drawContents(p, clipx, clipy, clipw, cliph); 939 //QScrollView::drawContents(p, clipx, clipy, clipw, cliph);
940
941 if (d->mLayoutDirty) 940 if (d->mLayoutDirty)
942 calcLayout(); 941 calcLayout();
943 942
944 //kdDebug() << "CardView::drawContents: " << clipx << ", " << clipy 943 //kdDebug() << "CardView::drawContents: " << clipx << ", " << clipy
945 // << ", " << clipw << ", " << cliph << endl; 944 // << ", " << clipw << ", " << cliph << endl;
946 945
947 QColorGroup cg = viewport()->palette().active(); // allow setting costum colors in the viewport pale 946 QColorGroup cg = viewport()->palette().active(); // allow setting costum colors in the viewport pale
948 947 int cX, cY;
948 contentsToViewport ( clipx, clipy, cX, cY );
949 QRect clipRect(clipx, clipy, clipw, cliph); 949 QRect clipRect(clipx, clipy, clipw, cliph);
950 QRect cardRect; 950 QRect cardRect;
951 QRect sepRect; 951 QRect sepRect;
952 CardViewItem *item; 952 CardViewItem *item;
953 CardViewSeparator *sep; 953 CardViewSeparator *sep;
954
955 // make sure the viewport is a pure background 954 // make sure the viewport is a pure background
956 viewport()->erase(clipRect); 955 viewport()->erase( QRect ( cX, cY , clipw, cliph ) );
957 956
958 // Now tell the cards to draw, if they are in the clip region 957 // Now tell the cards to draw, if they are in the clip region
959 QPtrListIterator<CardViewItem> iter(d->mItemList); 958 QPtrListIterator<CardViewItem> iter(d->mItemList);
960 for (iter.toFirst(); iter.current(); ++iter) 959 for (iter.toFirst(); iter.current(); ++iter)
961 { 960 {
962 item = *iter; 961 item = *iter;
963 cardRect.setRect( item->d->x, item->d->y, d->mItemWidth, item->height() ); 962 cardRect.setRect( item->d->x, item->d->y, d->mItemWidth, item->height() );
964 963
965 if (clipRect.intersects(cardRect) || clipRect.contains(cardRect)) 964 if (clipRect.intersects(cardRect) || clipRect.contains(cardRect))
966 { 965 {
967 //kdDebug() << "\trepainting card at: " << cardRect.x() << ", " 966 //kdDebug() << "\trepainting card at: " << cardRect.x() << ", "
968 // << cardRect.y() << endl; 967 // << cardRect.y() << endl;
969 968
970 // Tell the card to paint 969 // Tell the card to paint
971 p->save(); 970 p->save();
972 p->translate(cardRect.x(), cardRect.y()); 971 p->translate(cardRect.x(), cardRect.y());
973 item->paintCard(p, cg); 972 item->paintCard(p, cg);
974 p->restore(); 973 p->restore();
975 } 974 }
976 } 975 }
977 976
978 // Followed by the separators if they are in the clip region 977 // Followed by the separators if they are in the clip region
979 QPtrListIterator<CardViewSeparator> sepIter(d->mSeparatorList); 978 QPtrListIterator<CardViewSeparator> sepIter(d->mSeparatorList);
980 for (sepIter.toFirst(); sepIter.current(); ++sepIter) 979 for (sepIter.toFirst(); sepIter.current(); ++sepIter)
981 { 980 {
982 sep = *sepIter; 981 sep = *sepIter;
983 sepRect = sep->mRect; 982 sepRect = sep->mRect;
984 983
985 if (clipRect.intersects(sepRect) || clipRect.contains(sepRect)) 984 if (clipRect.intersects(sepRect) || clipRect.contains(sepRect))
986 { 985 {
987 p->save(); 986 p->save();
988 p->translate(sepRect.x(), sepRect.y()); 987 p->translate(sepRect.x(), sepRect.y());
989 sep->paintSeparator(p, cg); 988 sep->paintSeparator(p, cg);
990 p->restore(); 989 p->restore();
991 } 990 }
992 } 991 }
993} 992}
994 993
995void CardView::resizeEvent(QResizeEvent *e) 994void CardView::resizeEvent(QResizeEvent *e)
996{ 995{
997 QScrollView::resizeEvent(e); 996 QScrollView::resizeEvent(e);
998 997
999 setLayoutDirty(true); 998 setLayoutDirty(true);
1000} 999}
1001 1000
1002void CardView::calcLayout() 1001void CardView::calcLayout()
1003{ 1002{
1004 //kdDebug() << "CardView::calcLayout:" << endl; 1003 //kdDebug() << "CardView::calcLayout:" << endl;
1005 1004
1006 // Start in the upper left corner and layout all the 1005 // Start in the upper left corner and layout all the
1007 // cars using their height and width 1006 // cars using their height and width
1008 int maxWidth = 0; 1007 int maxWidth = 0;
1009 int maxHeight = 0; 1008 int maxHeight = 0;
1010 int xPos = 0; 1009 int xPos = 0;
1011 int yPos = 0; 1010 int yPos = 0;
1012 int cardSpacing = d->mItemSpacing; 1011 int cardSpacing = d->mItemSpacing;
1013 1012
1014 // delete the old separators 1013 // delete the old separators
1015 d->mSeparatorList.clear(); 1014 d->mSeparatorList.clear();
1016 1015
1017 QPtrListIterator<CardViewItem> iter(d->mItemList); 1016 QPtrListIterator<CardViewItem> iter(d->mItemList);
1018 CardViewItem *item = 0; 1017 CardViewItem *item = 0;
1019 CardViewSeparator *sep = 0; 1018 CardViewSeparator *sep = 0;
1020 xPos += cardSpacing; 1019 xPos += cardSpacing;
1021 1020
1022 for (iter.toFirst(); iter.current(); ++iter) 1021 for (iter.toFirst(); iter.current(); ++iter)
1023 { 1022 {
1024 item = *iter; 1023 item = *iter;
1025 1024
1026 yPos += cardSpacing; 1025 yPos += cardSpacing;
1027 1026
1028 if (yPos + item->height() + cardSpacing >= height() - horizontalScrollBar()->height()) 1027 if (yPos + item->height() + cardSpacing >= height() - horizontalScrollBar()->height())
1029 { 1028 {
1030 maxHeight = QMAX(maxHeight, yPos); 1029 maxHeight = QMAX(maxHeight, yPos);
1031 1030
1032 // Drawing in this column would be greater than the height 1031 // Drawing in this column would be greater than the height
1033 // of the scroll view, so move to next column 1032 // of the scroll view, so move to next column
1034 yPos = cardSpacing; 1033 yPos = cardSpacing;
1035 xPos += cardSpacing + maxWidth; 1034 xPos += cardSpacing + maxWidth;
1036 if (d->mDrawSeparators) 1035 if (d->mDrawSeparators)
1037 { 1036 {
1038 // Create a separator since the user asked 1037 // Create a separator since the user asked
1039 sep = new CardViewSeparator(this); 1038 sep = new CardViewSeparator(this);
1040 sep->mRect.moveTopLeft(QPoint(xPos, yPos+d->mItemMargin)); 1039 sep->mRect.moveTopLeft(QPoint(xPos, yPos+d->mItemMargin));
1041 xPos += d->mSepWidth + cardSpacing; 1040 xPos += d->mSepWidth + cardSpacing;
1042 d->mSeparatorList.append(sep); 1041 d->mSeparatorList.append(sep);
1043 } 1042 }
1044 1043
1045 maxWidth = 0; 1044 maxWidth = 0;
1046 } 1045 }
1047 1046
1048 item->d->x = xPos; 1047 item->d->x = xPos;
1049 item->d->y = yPos; 1048 item->d->y = yPos;
1050 1049
1051 yPos += item->height(); 1050 yPos += item->height();
1052 maxWidth = QMAX(maxWidth, d->mItemWidth); 1051 maxWidth = QMAX(maxWidth, d->mItemWidth);
1053 } 1052 }
1054 1053
1055 xPos += maxWidth; 1054 xPos += maxWidth;
1056 resizeContents( xPos + cardSpacing, maxHeight ); 1055 resizeContents( xPos + cardSpacing, maxHeight );
1057 1056
1058 // Update the height of all the separators now that we know the 1057 // Update the height of all the separators now that we know the
1059 // max height of a column 1058 // max height of a column
1060 QPtrListIterator<CardViewSeparator> sepIter(d->mSeparatorList); 1059 QPtrListIterator<CardViewSeparator> sepIter(d->mSeparatorList);
1061 for (sepIter.toFirst(); sepIter.current(); ++sepIter) 1060 for (sepIter.toFirst(); sepIter.current(); ++sepIter)
1062 { 1061 {
1063 (*sepIter)->mRect.setHeight(maxHeight - 2*cardSpacing - 2*d->mItemMargin); 1062 (*sepIter)->mRect.setHeight(maxHeight - 2*cardSpacing - 2*d->mItemMargin);
1064 } 1063 }
1065 1064
1066 d->mLayoutDirty = false; 1065 d->mLayoutDirty = false;
1067} 1066}
1068 1067
1069CardViewItem *CardView::itemAfter(CardViewItem *item) 1068CardViewItem *CardView::itemAfter(CardViewItem *item)
1070{ 1069{
1071 /*int pos = */d->mItemList.findRef(item); 1070 /*int pos = */d->mItemList.findRef(item);
1072 return d->mItemList.next();//at(pos+1); 1071 return d->mItemList.next();//at(pos+1);
1073} 1072}
1074 1073
1075uint CardView::itemMargin() 1074uint CardView::itemMargin()
1076{ 1075{
1077 return d->mItemMargin; 1076 return d->mItemMargin;
1078} 1077}
1079 1078
1080void CardView::setItemMargin( uint margin ) 1079void CardView::setItemMargin( uint margin )
1081{ 1080{
1082 if ( margin == d->mItemMargin ) 1081 if ( margin == d->mItemMargin )
1083 return; 1082 return;
1084 1083
1085 d->mItemMargin = margin; 1084 d->mItemMargin = margin;
1086 setLayoutDirty( true ); 1085 setLayoutDirty( true );
1087} 1086}
1088 1087
1089uint CardView::itemSpacing() 1088uint CardView::itemSpacing()
1090{ 1089{
1091 return d->mItemSpacing; 1090 return d->mItemSpacing;
1092} 1091}
1093 1092
1094void CardView::setItemSpacing( uint spacing ) 1093void CardView::setItemSpacing( uint spacing )
1095{ 1094{
1096 if ( spacing == d->mItemSpacing ) 1095 if ( spacing == d->mItemSpacing )
1097 return; 1096 return;
1098 1097
1099 d->mItemSpacing = spacing; 1098 d->mItemSpacing = spacing;
1100 setLayoutDirty( true ); 1099 setLayoutDirty( true );
1101} 1100}
1102 1101
1103void CardView::contentsMousePressEvent(QMouseEvent *e) 1102void CardView::contentsMousePressEvent(QMouseEvent *e)
1104{ 1103{
1105 QScrollView::contentsMousePressEvent(e); 1104 QScrollView::contentsMousePressEvent(e);
1106 1105
1107 QPoint pos = e->pos(); 1106 QPoint pos = e->pos();
1108 d->mLastClickPos = pos; 1107 d->mLastClickPos = pos;
1109 1108
1110 CardViewItem *item = itemAt(pos); 1109 CardViewItem *item = itemAt(pos);
1111 1110
1112 if (item == 0) 1111 if (item == 0)
1113 { 1112 {
1114 d->mLastClickOnItem = false; 1113 d->mLastClickOnItem = false;
1115 if ( d->mOnSeparator) 1114 if ( d->mOnSeparator)
1116 { 1115 {
1117 d->mResizeAnchor = e->x()+contentsX(); 1116 d->mResizeAnchor = e->x()+contentsX();
1118 d->colspace = (2*d->mItemSpacing) /*+ (2*d->mItemMargin)*/; 1117 d->colspace = (2*d->mItemSpacing) /*+ (2*d->mItemMargin)*/;
1119 int ccw = d->mItemWidth + d->colspace + d->mSepWidth; 1118 int ccw = d->mItemWidth + d->colspace + d->mSepWidth;
1120 d->first = (contentsX()+d->mSepWidth)/ccw; 1119 d->first = (contentsX()+d->mSepWidth)/ccw;
1121 d->pressed = (d->mResizeAnchor+d->mSepWidth)/ccw; 1120 d->pressed = (d->mResizeAnchor+d->mSepWidth)/ccw;
1122 d->span = d->pressed - d->first; 1121 d->span = d->pressed - d->first;
1123 d->firstX = d->first * ccw; 1122 d->firstX = d->first * ccw;
1124 if ( d->firstX ) d->firstX -= d->mSepWidth; // (no sep in col 0) 1123 if ( d->firstX ) d->firstX -= d->mSepWidth; // (no sep in col 0)
1125 } 1124 }
1126 else 1125 else
1127 { 1126 {
1128 selectAll(false); 1127 selectAll(false);
1129 } 1128 }
1130 return; 1129 return;
1131 } 1130 }
1132 1131
1133 d->mLastClickOnItem = true; 1132 d->mLastClickOnItem = true;
1134 1133
1135 CardViewItem *other = d->mCurrentItem; 1134 CardViewItem *other = d->mCurrentItem;
1136 setCurrentItem( item ); 1135 setCurrentItem( item );
1137 1136
1138 // Always emit the selection 1137 // Always emit the selection
1139 emit clicked(item); 1138 emit clicked(item);
1140 1139
1141 // Check the selection type and update accordingly 1140 // Check the selection type and update accordingly
1142 if (d->mSelectionMode == CardView::Single) 1141 if (d->mSelectionMode == CardView::Single)
1143 { 1142 {
1144 // make sure it isn't already selected 1143 // make sure it isn't already selected
1145 if (item->isSelected()) 1144 if (item->isSelected())
1146 return; 1145 return;
1147 1146
1148 bool b = signalsBlocked(); 1147 bool b = signalsBlocked();
1149 blockSignals(true); 1148 blockSignals(true);
1150 selectAll(false); 1149 selectAll(false);
1151 blockSignals(b); 1150 blockSignals(b);
1152 1151
1153 item->setSelected(true); 1152 item->setSelected(true);
1154 item->repaintCard(); 1153 item->repaintCard();
1155 emit selectionChanged(item); 1154 emit selectionChanged(item);
1156 } 1155 }
1157 1156
1158 else if (d->mSelectionMode == CardView::Multi) 1157 else if (d->mSelectionMode == CardView::Multi)
1159 { 1158 {
1160 // toggle the selection 1159 // toggle the selection
1161 item->setSelected(!item->isSelected()); 1160 item->setSelected(!item->isSelected());
1162 item->repaintCard(); 1161 item->repaintCard();
1163 emit selectionChanged(); 1162 emit selectionChanged();
1164 } 1163 }
1165 1164
1166 else if (d->mSelectionMode == CardView::Extended) 1165 else if (d->mSelectionMode == CardView::Extended)
1167 { 1166 {
1168 if ((e->button() & Qt::LeftButton) && 1167 if ((e->button() & Qt::LeftButton) &&
1169 (e->state() & Qt::ShiftButton)) 1168 (e->state() & Qt::ShiftButton))
1170 { 1169 {
1171 if ( item == other ) return; 1170 if ( item == other ) return;
1172 1171
1173 bool s = ! item->isSelected(); 1172 bool s = ! item->isSelected();
1174 1173
1175 if ( s && ! (e->state() & ControlButton) ) 1174 if ( s && ! (e->state() & ControlButton) )
1176 { 1175 {
1177 bool b = signalsBlocked(); 1176 bool b = signalsBlocked();
1178 blockSignals(true); 1177 blockSignals(true);
1179 selectAll(false); 1178 selectAll(false);
1180 blockSignals(b); 1179 blockSignals(b);
1181 } 1180 }
1182 1181
1183 int from, to, a, b; 1182 int from, to, a, b;
1184 a = d->mItemList.findRef( item ); 1183 a = d->mItemList.findRef( item );
1185 b = d->mItemList.findRef( other ); 1184 b = d->mItemList.findRef( other );
1186 from = a < b ? a : b; 1185 from = a < b ? a : b;
1187 to = a > b ? a : b; 1186 to = a > b ? a : b;
1188 //kdDebug()<<"selecting items "<<from<<" - "<<to<<" ( "<<s<<" )"<<endl; 1187 //kdDebug()<<"selecting items "<<from<<" - "<<to<<" ( "<<s<<" )"<<endl;
1189 CardViewItem *aItem; 1188 CardViewItem *aItem;
1190 for ( ; from <= to; from++ ) 1189 for ( ; from <= to; from++ )
1191 { 1190 {
1192 aItem = d->mItemList.at( from ); 1191 aItem = d->mItemList.at( from );
1193 aItem->setSelected( s ); 1192 aItem->setSelected( s );
1194 repaintItem( aItem ); 1193 repaintItem( aItem );
1195 } 1194 }
1196 emit selectionChanged(); 1195 emit selectionChanged();
1197 } 1196 }
1198 else if ((e->button() & Qt::LeftButton) && 1197 else if ((e->button() & Qt::LeftButton) &&
1199 (e->state() & Qt::ControlButton)) 1198 (e->state() & Qt::ControlButton))
1200 { 1199 {
1201 item->setSelected(!item->isSelected()); 1200 item->setSelected(!item->isSelected());
1202 item->repaintCard(); 1201 item->repaintCard();
1203 emit selectionChanged(); 1202 emit selectionChanged();
1204 } 1203 }
1205 1204
1206 else if (e->button() & Qt::LeftButton) 1205 else if (e->button() & Qt::LeftButton)
1207 { 1206 {
1208 bool b = signalsBlocked(); 1207 bool b = signalsBlocked();
1209 blockSignals(true); 1208 blockSignals(true);
1210 selectAll(false); 1209 selectAll(false);
1211 blockSignals(b); 1210 blockSignals(b);
1212 1211
1213 item->setSelected(true); 1212 item->setSelected(true);
1214 item->repaintCard(); 1213 item->repaintCard();
1215 emit selectionChanged(); 1214 emit selectionChanged();
1216 } 1215 }
1217 } 1216 }
1218 1217
1219} 1218}
1220 1219
1221void CardView::contentsMouseReleaseEvent(QMouseEvent *e) 1220void CardView::contentsMouseReleaseEvent(QMouseEvent *e)
1222{ 1221{
1223 QScrollView::contentsMouseReleaseEvent(e); 1222 QScrollView::contentsMouseReleaseEvent(e);
1224 1223
1225 if ( d->mResizeAnchor ) 1224 if ( d->mResizeAnchor )
1226 { 1225 {
1227 // finish the resizing: 1226 // finish the resizing:
1228 unsetCursor(); 1227 unsetCursor();
1229 // hide rubber bands 1228 // hide rubber bands
1230 int newiw = d->mItemWidth - ((d->mResizeAnchor - d->mRubberBandAnchor)/d->span); 1229 int newiw = d->mItemWidth - ((d->mResizeAnchor - d->mRubberBandAnchor)/d->span);
1231 drawRubberBands( 0 ); 1230 drawRubberBands( 0 );
1232 // we should move to reflect the new position if we are scrolled. 1231 // we should move to reflect the new position if we are scrolled.
1233 if ( contentsX() ) 1232 if ( contentsX() )
1234 { 1233 {
1235 int newX = QMAX( 0, ( d->pressed * ( newiw + d->colspace + d->mSepWidth ) ) - e->x() ); 1234 int newX = QMAX( 0, ( d->pressed * ( newiw + d->colspace + d->mSepWidth ) ) - e->x() );
1236 setContentsPos( newX, contentsY() ); 1235 setContentsPos( newX, contentsY() );
1237 } 1236 }
1238 // set new item width 1237 // set new item width
1239 setItemWidth( newiw ); 1238 setItemWidth( newiw );
1240 // reset anchors 1239 // reset anchors
1241 d->mResizeAnchor = 0; 1240 d->mResizeAnchor = 0;
1242 d->mRubberBandAnchor = 0; 1241 d->mRubberBandAnchor = 0;
1243 return; 1242 return;
1244 } 1243 }
1245 1244
1246 // If there are accel keys, we will not emit signals 1245 // If there are accel keys, we will not emit signals
1247 if ((e->state() & Qt::ShiftButton) || (e->state() & Qt::ControlButton)) 1246 if ((e->state() & Qt::ShiftButton) || (e->state() & Qt::ControlButton))
1248 return; 1247 return;
1249 1248
1250 // Get the item at this position 1249 // Get the item at this position
1251 CardViewItem *item = itemAt(e->pos()); 1250 CardViewItem *item = itemAt(e->pos());
1252 1251
1253 if (item && KABPrefs::instance()->mHonorSingleClick) 1252 if (item && KABPrefs::instance()->mHonorSingleClick)
1254 { 1253 {
1255 emit executed(item); 1254 emit executed(item);
1256 } 1255 }
1257} 1256}
1258 1257
1259void CardView::contentsMouseDoubleClickEvent(QMouseEvent *e) 1258void CardView::contentsMouseDoubleClickEvent(QMouseEvent *e)
1260{ 1259{
1261 QScrollView::contentsMouseDoubleClickEvent(e); 1260 QScrollView::contentsMouseDoubleClickEvent(e);
1262 1261
1263 CardViewItem *item = itemAt(e->pos()); 1262 CardViewItem *item = itemAt(e->pos());
1264 1263
1265 if (item) 1264 if (item)
1266 { 1265 {
1267 d->mCurrentItem = item; 1266 d->mCurrentItem = item;
1268 } 1267 }
1269 1268
1270 if (item && !KABPrefs::instance()->mHonorSingleClick) 1269 if (item && !KABPrefs::instance()->mHonorSingleClick)
1271 { 1270 {
1272 emit executed(item); 1271 emit executed(item);
1273 } else 1272 } else
1274 emit doubleClicked(item); 1273 emit doubleClicked(item);
1275} 1274}
1276 1275
1277void CardView::contentsMouseMoveEvent( QMouseEvent *e ) 1276void CardView::contentsMouseMoveEvent( QMouseEvent *e )
1278{ 1277{
1279 // resizing 1278 // resizing
1280 if ( d->mResizeAnchor ) 1279 if ( d->mResizeAnchor )
1281 { 1280 {
1282 int x = e->x(); 1281 int x = e->x();
1283 if ( x != d->mRubberBandAnchor ) 1282 if ( x != d->mRubberBandAnchor )
1284 drawRubberBands( x ); 1283 drawRubberBands( x );
1285 return; 1284 return;
1286 } 1285 }
1287 1286
1288 if (d->mLastClickOnItem && (e->state() & Qt::LeftButton) && 1287 if (d->mLastClickOnItem && (e->state() & Qt::LeftButton) &&
1289 ((e->pos() - d->mLastClickPos).manhattanLength() > 4)) { 1288 ((e->pos() - d->mLastClickPos).manhattanLength() > 4)) {
1290 1289
1291 startDrag(); 1290 startDrag();
1292 return; 1291 return;
1293 } 1292 }
1294 1293
1295 d->mTimer->start( 500 ); 1294 d->mTimer->start( 500 );
1296 1295
1297 // see if we are over a separator 1296 // see if we are over a separator
1298 // only if we actually have them painted? 1297 // only if we actually have them painted?
1299 if ( d->mDrawSeparators ) 1298 if ( d->mDrawSeparators )
1300 { 1299 {
1301 int colcontentw = d->mItemWidth + (2*d->mItemSpacing); 1300 int colcontentw = d->mItemWidth + (2*d->mItemSpacing);
1302 int colw = colcontentw + d->mSepWidth; 1301 int colw = colcontentw + d->mSepWidth;
1303 int m = e->x()%colw; 1302 int m = e->x()%colw;
1304 if ( m >= colcontentw && m > 0 ) 1303 if ( m >= colcontentw && m > 0 )
1305 { 1304 {
1306 setCursor( SplitVCursor ); // Why does this fail sometimes? 1305 setCursor( SplitVCursor ); // Why does this fail sometimes?
1307 d->mOnSeparator = true; 1306 d->mOnSeparator = true;
1308 } 1307 }
1309 else 1308 else
1310 { 1309 {
1311 setCursor( ArrowCursor ); 1310 setCursor( ArrowCursor );
1312 d->mOnSeparator = false; 1311 d->mOnSeparator = false;
1313 } 1312 }
1314 } 1313 }
1315} 1314}
1316 1315
1317void CardView::enterEvent( QEvent * ) 1316void CardView::enterEvent( QEvent * )
1318{ 1317{
1319 d->mTimer->start( 500 ); 1318 d->mTimer->start( 500 );
1320} 1319}
1321 1320
1322void CardView::leaveEvent( QEvent * ) 1321void CardView::leaveEvent( QEvent * )
1323{ 1322{
1324 d->mTimer->stop(); 1323 d->mTimer->stop();
1325 if (d->mOnSeparator) 1324 if (d->mOnSeparator)
1326 { 1325 {
1327 d->mOnSeparator = false; 1326 d->mOnSeparator = false;
1328 setCursor( ArrowCursor ); 1327 setCursor( ArrowCursor );
1329 } 1328 }
1330} 1329}
1331 1330
1332void CardView::focusInEvent( QFocusEvent * ) 1331void CardView::focusInEvent( QFocusEvent * )
1333{ 1332{
1334 if (!d->mCurrentItem && d->mItemList.count() ) 1333 if (!d->mCurrentItem && d->mItemList.count() )
1335 { 1334 {
1336 setCurrentItem( d->mItemList.first() ); 1335 setCurrentItem( d->mItemList.first() );
1337 } 1336 }
1338 else if ( d->mCurrentItem ) 1337 else if ( d->mCurrentItem )
1339 { 1338 {
1340 d->mCurrentItem->repaintCard(); 1339 d->mCurrentItem->repaintCard();
1341 } 1340 }
1342} 1341}
1343 1342
1344void CardView::focusOutEvent( QFocusEvent * ) 1343void CardView::focusOutEvent( QFocusEvent * )
1345{ 1344{
1346 if (d->mCurrentItem) 1345 if (d->mCurrentItem)
1347 d->mCurrentItem->repaintCard(); 1346 d->mCurrentItem->repaintCard();
1348} 1347}
1349 1348
1350void CardView::keyPressEvent( QKeyEvent *e ) 1349void CardView::keyPressEvent( QKeyEvent *e )
1351{ 1350{
1352 if ( ! ( childCount() && d->mCurrentItem ) ) 1351 if ( ! ( childCount() && d->mCurrentItem ) )
1353 { 1352 {
1354 e->ignore(); 1353 e->ignore();
1355 return; 1354 return;
1356 } 1355 }
1357 if ( mFlagBlockKeyPressed ) 1356 if ( mFlagBlockKeyPressed )
1358 return; 1357 return;
1359 qApp->processEvents(); 1358 qApp->processEvents();
1360 if ( e->isAutoRepeat() && !mFlagKeyPressed ) { 1359 if ( e->isAutoRepeat() && !mFlagKeyPressed ) {
1361 e->accept(); 1360 e->accept();
1362 return; 1361 return;
1363 } 1362 }
1364 if (! e->isAutoRepeat() ) 1363 if (! e->isAutoRepeat() )
1365 mFlagKeyPressed = true; 1364 mFlagKeyPressed = true;
1366 uint pos = d->mItemList.findRef( d->mCurrentItem ); 1365 uint pos = d->mItemList.findRef( d->mCurrentItem );
1367 CardViewItem *aItem = 0L; // item that gets the focus 1366 CardViewItem *aItem = 0L; // item that gets the focus
1368 CardViewItem *old = d->mCurrentItem; 1367 CardViewItem *old = d->mCurrentItem;
1369 1368
1370 switch ( e->key() ) 1369 switch ( e->key() )
1371 { 1370 {
1372 case Key_Up: 1371 case Key_Up:
1373 if ( pos > 0 ) 1372 if ( pos > 0 )
1374 { 1373 {
1375 aItem = d->mItemList.at( pos - 1 ); 1374 aItem = d->mItemList.at( pos - 1 );
1376 setCurrentItem( aItem ); 1375 setCurrentItem( aItem );
1377 } 1376 }
1378 break; 1377 break;
1379 case Key_Down: 1378 case Key_Down:
1380 if ( pos < d->mItemList.count() - 1 ) 1379 if ( pos < d->mItemList.count() - 1 )
1381 { 1380 {
1382 aItem = d->mItemList.at( pos + 1 ); 1381 aItem = d->mItemList.at( pos + 1 );
1383 setCurrentItem( aItem ); 1382 setCurrentItem( aItem );
1384 } 1383 }
1385 break; 1384 break;
1386 case Key_Left: 1385 case Key_Left:
1387 { 1386 {
1388 // look for an item in the previous/next column, starting from 1387 // look for an item in the previous/next column, starting from
1389 // the vertical middle of the current item. 1388 // the vertical middle of the current item.
1390 // FIXME use nice calculatd measures!!! 1389 // FIXME use nice calculatd measures!!!
1391 QPoint aPoint( d->mCurrentItem->d->x, d->mCurrentItem->d->y ); 1390 QPoint aPoint( d->mCurrentItem->d->x, d->mCurrentItem->d->y );
1392 aPoint -= QPoint( 30,-(d->mCurrentItem->height()/2) ); 1391 aPoint -= QPoint( 30,-(d->mCurrentItem->height()/2) );
1393 aItem = itemAt( aPoint ); 1392 aItem = itemAt( aPoint );
1394 // maybe we hit some space below an item 1393 // maybe we hit some space below an item
1395 while ( !aItem && aPoint.y() > 27 ) 1394 while ( !aItem && aPoint.y() > 27 )
1396 { 1395 {
1397 aPoint -= QPoint( 0, 16 ); 1396 aPoint -= QPoint( 0, 16 );
1398 aItem = itemAt( aPoint ); 1397 aItem = itemAt( aPoint );
1399 } 1398 }
1400 if ( aItem ) 1399 if ( aItem )
1401 setCurrentItem( aItem ); 1400 setCurrentItem( aItem );
1402 } 1401 }
1403 break; 1402 break;
1404 case Key_Right: 1403 case Key_Right:
1405 { 1404 {
1406 // FIXME use nice calculated measures!!! 1405 // FIXME use nice calculated measures!!!
1407 QPoint aPoint( d->mCurrentItem->d->x + d->mItemWidth, d->mCurrentItem->d->y ); 1406 QPoint aPoint( d->mCurrentItem->d->x + d->mItemWidth, d->mCurrentItem->d->y );
1408 aPoint += QPoint( 30,(d->mCurrentItem->height()/2) ); 1407 aPoint += QPoint( 30,(d->mCurrentItem->height()/2) );
1409 aItem = itemAt( aPoint ); 1408 aItem = itemAt( aPoint );
1410 while ( !aItem && aPoint.y() > 27 ) 1409 while ( !aItem && aPoint.y() > 27 )
1411 { 1410 {
1412 aPoint -= QPoint( 0, 16 ); 1411 aPoint -= QPoint( 0, 16 );
1413 aItem = itemAt( aPoint ); 1412 aItem = itemAt( aPoint );
1414 } 1413 }
1415 if ( aItem ) 1414 if ( aItem )
1416 setCurrentItem( aItem ); 1415 setCurrentItem( aItem );
1417 } 1416 }
1418 break; 1417 break;
1419 case Key_Home: 1418 case Key_Home:
1420 aItem = d->mItemList.first(); 1419 aItem = d->mItemList.first();
1421 setCurrentItem( aItem ); 1420 setCurrentItem( aItem );
1422 break; 1421 break;
1423 case Key_End: 1422 case Key_End:
1424 aItem = d->mItemList.last(); 1423 aItem = d->mItemList.last();
1425 setCurrentItem( aItem ); 1424 setCurrentItem( aItem );
1426 break; 1425 break;
1427 case Key_Prior: // PageUp 1426 case Key_Prior: // PageUp
1428 { 1427 {
1429 // QListView: "Make the item above the top visible and current" 1428 // QListView: "Make the item above the top visible and current"
1430 // TODO if contentsY(), pick the top item of the leftmost visible column 1429 // TODO if contentsY(), pick the top item of the leftmost visible column
1431 if ( contentsX() <= 0 ) 1430 if ( contentsX() <= 0 )
1432 return; 1431 return;
1433 int cw = columnWidth(); 1432 int cw = columnWidth();
1434 int theCol = ( QMAX( 0, ( contentsX()/cw) * cw ) ) + d->mItemSpacing; 1433 int theCol = ( QMAX( 0, ( contentsX()/cw) * cw ) ) + d->mItemSpacing;
1435 aItem = itemAt( QPoint( theCol + 1, d->mItemSpacing + 1 ) ); 1434 aItem = itemAt( QPoint( theCol + 1, d->mItemSpacing + 1 ) );
1436 if ( aItem ) 1435 if ( aItem )
1437 setCurrentItem( aItem ); 1436 setCurrentItem( aItem );
1438 } 1437 }
1439 break; 1438 break;
1440 case Key_Next: // PageDown 1439 case Key_Next: // PageDown
1441 { 1440 {
1442 // QListView: "Make the item below the bottom visible and current" 1441 // QListView: "Make the item below the bottom visible and current"
1443 // find the first not fully visible column. 1442 // find the first not fully visible column.
1444 // TODO: consider if a partly visible (or even hidden) item at the 1443 // TODO: consider if a partly visible (or even hidden) item at the
1445 // bottom of the rightmost column exists 1444 // bottom of the rightmost column exists
1446 int cw = columnWidth(); 1445 int cw = columnWidth();
1447 int theCol = ( (( contentsX() + visibleWidth() )/cw) * cw ) + d->mItemSpacing + 1; 1446 int theCol = ( (( contentsX() + visibleWidth() )/cw) * cw ) + d->mItemSpacing + 1;
1448 // if separators are on, we may need to we may be one column further right if only the spacing/sep is hidden 1447 // if separators are on, we may need to we may be one column further right if only the spacing/sep is hidden
1449 if ( d->mDrawSeparators && cw - (( contentsX() + visibleWidth() )%cw) <= int( d->mItemSpacing + d->mSepWidth ) ) 1448 if ( d->mDrawSeparators && cw - (( contentsX() + visibleWidth() )%cw) <= int( d->mItemSpacing + d->mSepWidth ) )
1450 theCol += cw; 1449 theCol += cw;
1451 1450
1452 // make sure this is not too far right 1451 // make sure this is not too far right
1453 while ( theCol > contentsWidth() ) 1452 while ( theCol > contentsWidth() )
1454 theCol -= columnWidth(); 1453 theCol -= columnWidth();
1455 1454
1456 aItem = itemAt( QPoint( theCol, d->mItemSpacing + 1 ) ); 1455 aItem = itemAt( QPoint( theCol, d->mItemSpacing + 1 ) );
1457 1456
1458 if ( aItem ) 1457 if ( aItem )
1459 setCurrentItem( aItem ); 1458 setCurrentItem( aItem );
1460 } 1459 }
1461 break; 1460 break;
1462 case Key_Space: 1461 case Key_Space:
1463 setSelected( d->mCurrentItem, !d->mCurrentItem->isSelected() ); 1462 setSelected( d->mCurrentItem, !d->mCurrentItem->isSelected() );
1464 emit selectionChanged(); 1463 emit selectionChanged();
1465 break; 1464 break;
1466 case Key_Return: 1465 case Key_Return:
1467 case Key_Enter: 1466 case Key_Enter:
1468 { 1467 {
1469 emit returnPressed( d->mCurrentItem ); 1468 emit returnPressed( d->mCurrentItem );
1470 emit executed( d->mCurrentItem ); 1469 emit executed( d->mCurrentItem );
1471 } 1470 }
1472 break; 1471 break;
1473 default: 1472 default:
1474 if ( (e->state() & ControlButton) && e->key() == Key_A ) 1473 if ( (e->state() & ControlButton) && e->key() == Key_A )
1475 { 1474 {
1476 // select all 1475 // select all
1477 selectAll( true ); 1476 selectAll( true );
1478 break; 1477 break;
1479 } 1478 }
1480 // if we have a string, do autosearch 1479 // if we have a string, do autosearch
1481 else if ( ! e->text().isEmpty() && e->text()[0].isPrint() ) 1480 else if ( ! e->text().isEmpty() && e->text()[0].isPrint() )
1482 { 1481 {
1483 1482
1484 } 1483 }
1485 break; 1484 break;
1486 } 1485 }
1487 // handle selection 1486 // handle selection
1488 if ( aItem ) 1487 if ( aItem )
1489 { 1488 {
1490 if ( d->mSelectionMode == CardView::Extended ) 1489 if ( d->mSelectionMode == CardView::Extended )
1491 { 1490 {
1492 if ( (e->state() & ShiftButton) ) 1491 if ( (e->state() & ShiftButton) )
1493 { 1492 {
1494 // shift button: toggle range 1493 // shift button: toggle range
1495 // if control button is pressed, leave all items 1494 // if control button is pressed, leave all items
1496 // and toggle selection current->old current 1495 // and toggle selection current->old current
1497 // otherwise, ?????? 1496 // otherwise, ??????
1498 bool s = ! aItem->isSelected(); 1497 bool s = ! aItem->isSelected();
1499 int from, to, a, b; 1498 int from, to, a, b;
1500 a = d->mItemList.findRef( aItem ); 1499 a = d->mItemList.findRef( aItem );
1501 b = d->mItemList.findRef( old ); 1500 b = d->mItemList.findRef( old );
1502 from = a < b ? a : b; 1501 from = a < b ? a : b;
1503 to = a > b ? a : b; 1502 to = a > b ? a : b;
1504 1503
1505 if ( to - from > 1 ) 1504 if ( to - from > 1 )
1506 { 1505 {
1507 bool b = signalsBlocked(); 1506 bool b = signalsBlocked();
1508 blockSignals(true); 1507 blockSignals(true);
1509 selectAll(false); 1508 selectAll(false);
1510 blockSignals(b); 1509 blockSignals(b);
1511 } 1510 }
1512 1511
1513 //kdDebug()<<"selecting items "<<from<<" - "<<to<<" ( "<<s<<" )"<<endl; 1512 //kdDebug()<<"selecting items "<<from<<" - "<<to<<" ( "<<s<<" )"<<endl;
1514 CardViewItem *item; 1513 CardViewItem *item;
1515 for ( ; from <= to; from++ ) 1514 for ( ; from <= to; from++ )
1516 { 1515 {
1517 item = d->mItemList.at( from ); 1516 item = d->mItemList.at( from );
1518 item->setSelected( s ); 1517 item->setSelected( s );
1519 repaintItem( item ); 1518 repaintItem( item );
1520 } 1519 }
1521 emit selectionChanged(); 1520 emit selectionChanged();
1522 } 1521 }
1523 else if ( (e->state() & ControlButton) ) 1522 else if ( (e->state() & ControlButton) )
1524 { 1523 {
1525 // control button: do nothing 1524 // control button: do nothing
1526 } 1525 }
1527 else 1526 else
1528 { 1527 {
1529 // no button: move selection to this item 1528 // no button: move selection to this item
1530 bool b = signalsBlocked(); 1529 bool b = signalsBlocked();
1531 blockSignals(true); 1530 blockSignals(true);
1532 selectAll(false); 1531 selectAll(false);
1533 blockSignals(b); 1532 blockSignals(b);
1534 1533
1535 setSelected( aItem, true ); 1534 setSelected( aItem, true );
1536 emit selectionChanged(); 1535 emit selectionChanged();
1537 } 1536 }
1538 } 1537 }
1539 } 1538 }
1540} 1539}
1541 1540
1542void CardView::contentsWheelEvent( QWheelEvent * e ) 1541void CardView::contentsWheelEvent( QWheelEvent * e )
1543{ 1542{
1544 scrollBy(2*e->delta()/-3, 0); 1543 scrollBy(2*e->delta()/-3, 0);
1545} 1544}
1546 1545
1547void CardView::setLayoutDirty(bool dirty) 1546void CardView::setLayoutDirty(bool dirty)
1548{ 1547{
1549 if (d->mLayoutDirty != dirty) 1548 if (d->mLayoutDirty != dirty)
1550 { 1549 {
1551 d->mLayoutDirty = dirty; 1550 d->mLayoutDirty = dirty;
1552 repaint(); 1551 repaint();
1553 } 1552 }
1554} 1553}
1555 1554
1556void CardView::setDrawCardBorder(bool enabled) 1555void CardView::setDrawCardBorder(bool enabled)
1557{ 1556{
1558 if (enabled != d->mDrawCardBorder) 1557 if (enabled != d->mDrawCardBorder)
1559 { 1558 {
1560 d->mDrawCardBorder = enabled; 1559 d->mDrawCardBorder = enabled;
1561 repaint(); 1560 repaint();
1562 } 1561 }
1563} 1562}
1564 1563
1565bool CardView::drawCardBorder() const 1564bool CardView::drawCardBorder() const
1566{ 1565{
1567 return d->mDrawCardBorder; 1566 return d->mDrawCardBorder;
1568} 1567}
1569 1568
1570void CardView::setDrawColSeparators(bool enabled) 1569void CardView::setDrawColSeparators(bool enabled)
1571{ 1570{
1572 if (enabled != d->mDrawSeparators) 1571 if (enabled != d->mDrawSeparators)
1573 { 1572 {
1574 d->mDrawSeparators = enabled; 1573 d->mDrawSeparators = enabled;
1575 setLayoutDirty(true); 1574 setLayoutDirty(true);
1576 } 1575 }
1577} 1576}
1578 1577
1579bool CardView::drawColSeparators() const 1578bool CardView::drawColSeparators() const
1580{ 1579{
1581 return d->mDrawSeparators; 1580 return d->mDrawSeparators;
1582} 1581}
1583 1582
1584void CardView::setDrawFieldLabels(bool enabled) 1583void CardView::setDrawFieldLabels(bool enabled)
1585{ 1584{
1586 if (enabled != d->mDrawFieldLabels) 1585 if (enabled != d->mDrawFieldLabels)
1587 { 1586 {
1588 d->mDrawFieldLabels = enabled; 1587 d->mDrawFieldLabels = enabled;
1589 repaint(); 1588 repaint();
1590 } 1589 }
1591} 1590}
1592 1591
1593bool CardView::drawFieldLabels() const 1592bool CardView::drawFieldLabels() const
1594{ 1593{
1595 return d->mDrawFieldLabels; 1594 return d->mDrawFieldLabels;
1596} 1595}
1597 1596
1598void CardView::setShowEmptyFields(bool show) 1597void CardView::setShowEmptyFields(bool show)
1599{ 1598{
1600 if (show != d->mShowEmptyFields) 1599 if (show != d->mShowEmptyFields)
1601 { 1600 {
1602 d->mShowEmptyFields = show; 1601 d->mShowEmptyFields = show;
1603 setLayoutDirty(true); 1602 setLayoutDirty(true);
1604 } 1603 }
1605} 1604}
1606 1605
1607bool CardView::showEmptyFields() const 1606bool CardView::showEmptyFields() const
1608{ 1607{
1609 return d->mShowEmptyFields; 1608 return d->mShowEmptyFields;
1610} 1609}
1611 1610
1612void CardView::startDrag() 1611void CardView::startDrag()
1613{ 1612{
1614 // The default implementation is a no-op. It must be 1613 // The default implementation is a no-op. It must be
1615 // reimplemented in a subclass to be useful 1614 // reimplemented in a subclass to be useful
1616} 1615}
1617void CardView::tryShowFullText() 1616void CardView::tryShowFullText()
1618{ 1617{
1619 d->mTimer->stop(); 1618 d->mTimer->stop();
1620 // if we have an item 1619 // if we have an item
1621 QPoint cpos = viewportToContents( viewport()->mapFromGlobal( QCursor::pos() ) ); 1620 QPoint cpos = viewportToContents( viewport()->mapFromGlobal( QCursor::pos() ) );
1622 CardViewItem *item = itemAt( cpos ); 1621 CardViewItem *item = itemAt( cpos );
1623 if ( item ) 1622 if ( item )
1624 { 1623 {
1625 // query it for a value to display 1624 // query it for a value to display
1626 //QString s = item ? item->caption() : "(no item)"; 1625 //QString s = item ? item->caption() : "(no item)";
1627 //kdDebug()<<"MOUSE REST: "<<s<<endl; 1626 //kdDebug()<<"MOUSE REST: "<<s<<endl;
1628 QPoint ipos = cpos - itemRect( item ).topLeft(); 1627 QPoint ipos = cpos - itemRect( item ).topLeft();
1629 item->showFullString( ipos, d->mTip ); 1628 item->showFullString( ipos, d->mTip );
1630 } 1629 }
1631} 1630}
1632 1631
1633void CardView::drawRubberBands( int pos ) 1632void CardView::drawRubberBands( int pos )
1634{ 1633{
1635 if ( pos && ((pos-d->firstX)/d->span) - d->colspace - d->mSepWidth < MIN_ITEM_WIDTH ) return; 1634 if ( pos && ((pos-d->firstX)/d->span) - d->colspace - d->mSepWidth < MIN_ITEM_WIDTH ) return;
1636 1635
1637 int tmpcw = (d->mRubberBandAnchor-d->firstX)/d->span; 1636 int tmpcw = (d->mRubberBandAnchor-d->firstX)/d->span;
1638 int x = d->firstX + tmpcw - d->mSepWidth - contentsX(); 1637 int x = d->firstX + tmpcw - d->mSepWidth - contentsX();
1639 int h = visibleHeight(); 1638 int h = visibleHeight();
1640 1639
1641 QPainter p( viewport() ); 1640 QPainter p( viewport() );
1642 p.setRasterOp( XorROP ); 1641 p.setRasterOp( XorROP );
1643 p.setPen( gray ); 1642 p.setPen( gray );
1644 p.setBrush( gray ); 1643 p.setBrush( gray );
1645 uint n = d->first; 1644 uint n = d->first;
1646 // erase 1645 // erase
1647 if ( d->mRubberBandAnchor ) 1646 if ( d->mRubberBandAnchor )
1648 do { 1647 do {
1649 p.drawRect( x, 0, 2, h ); 1648 p.drawRect( x, 0, 2, h );
1650 x += tmpcw; 1649 x += tmpcw;
1651 n++; 1650 n++;
1652 } while ( x < visibleWidth() && n < d->mSeparatorList.count() ); 1651 } while ( x < visibleWidth() && n < d->mSeparatorList.count() );
1653 // paint new 1652 // paint new
1654 if ( ! pos ) return; 1653 if ( ! pos ) return;
1655 tmpcw = (pos - d->firstX)/d->span; 1654 tmpcw = (pos - d->firstX)/d->span;
1656 n = d->first; 1655 n = d->first;
1657 x = d->firstX + tmpcw - d->mSepWidth - contentsX(); 1656 x = d->firstX + tmpcw - d->mSepWidth - contentsX();
1658 do { 1657 do {
1659 p.drawRect( x, 0, 2, h ); 1658 p.drawRect( x, 0, 2, h );
1660 x += tmpcw; 1659 x += tmpcw;
1661 n++; 1660 n++;
1662 } while ( x < visibleWidth() && n < d->mSeparatorList.count() ); 1661 } while ( x < visibleWidth() && n < d->mSeparatorList.count() );
1663 d->mRubberBandAnchor = pos; 1662 d->mRubberBandAnchor = pos;
1664} 1663}
1665 1664
1666 1665
1667int CardView::itemWidth() const 1666int CardView::itemWidth() const
1668{ 1667{
1669 return d->mItemWidth; 1668 return d->mItemWidth;
1670} 1669}
1671 1670
1672void CardView::setItemWidth( int w ) 1671void CardView::setItemWidth( int w )
1673{ 1672{
1674 if ( w == d->mItemWidth ) 1673 if ( w == d->mItemWidth )
1675 return; 1674 return;
1676 if ( w < MIN_ITEM_WIDTH ) 1675 if ( w < MIN_ITEM_WIDTH )
1677 w = MIN_ITEM_WIDTH; 1676 w = MIN_ITEM_WIDTH;
1678 d->mItemWidth = w; 1677 d->mItemWidth = w;
1679 setLayoutDirty( true ); 1678 setLayoutDirty( true );
1680#ifndef KAB_EMBEDDED 1679#ifndef KAB_EMBEDDED
1681 updateContents(); 1680 updateContents();
1682#else //KAB_EMBEDDED 1681#else //KAB_EMBEDDED
1683//US updateContents( d->contentsX(), d->contentsY(), visibleWidth(), visibleHeight() ); 1682//US updateContents( d->contentsX(), d->contentsY(), visibleWidth(), visibleHeight() );
1684qDebug("CardView::setItemWidth has to be verified"); 1683qDebug("CardView::setItemWidth has to be verified");
1685 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); 1684 updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
1686#endif //KAB_EMBEDDED 1685#endif //KAB_EMBEDDED
1687} 1686}
1688 1687
1689void CardView::setHeaderFont( const QFont &fnt ) 1688void CardView::setHeaderFont( const QFont &fnt )
1690{ 1689{
1691 d->mHeaderFont = fnt; 1690 d->mHeaderFont = fnt;
1692 delete d->mBFm; 1691 delete d->mBFm;
1693 d->mBFm = new QFontMetrics( fnt ); 1692 d->mBFm = new QFontMetrics( fnt );
1694} 1693}
1695 1694
1696QFont CardView::headerFont() const 1695QFont CardView::headerFont() const
1697{ 1696{
1698 return d->mHeaderFont; 1697 return d->mHeaderFont;
1699} 1698}
1700 1699
1701void CardView::setFont( const QFont &fnt ) 1700void CardView::setFont( const QFont &fnt )
1702{ 1701{
1703 QScrollView::setFont( fnt ); 1702 QScrollView::setFont( fnt );
1704 delete d->mFm; 1703 delete d->mFm;
1705 d->mFm = new QFontMetrics( fnt ); 1704 d->mFm = new QFontMetrics( fnt );
1706} 1705}
1707 1706
1708int CardView::separatorWidth() 1707int CardView::separatorWidth()
1709{ 1708{
1710 return d->mSepWidth; 1709 return d->mSepWidth;
1711} 1710}
1712 1711
1713void CardView::setSeparatorWidth( int width ) 1712void CardView::setSeparatorWidth( int width )
1714{ 1713{
1715 d->mSepWidth = width; 1714 d->mSepWidth = width;
1716 setLayoutDirty( true ); // hmm, actually I could just adjust the x'es... 1715 setLayoutDirty( true ); // hmm, actually I could just adjust the x'es...
1717} 1716}
1718 1717
1719int CardView::maxFieldLines() const 1718int CardView::maxFieldLines() const
1720{ 1719{
1721 return d->mMaxFieldLines; 1720 return d->mMaxFieldLines;
1722} 1721}
1723 1722
1724void CardView::setMaxFieldLines( int howmany ) 1723void CardView::setMaxFieldLines( int howmany )