kaddressbook

cardview.cpp
1/*
2 This file is part of KAddressBook.
3 Copyright (c) 2002 Mike Pilone <mpilone@slac.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19 As a special exception, permission is given to link this program
20 with any edition of TQt, and distribute the resulting executable,
21 without including the source code for TQt in the source distribution.
22*/
23
24
25#include <limits.h>
26
27#include <tqcursor.h>
28#include <tqdatetime.h>
29#include <tqlabel.h>
30#include <tqpainter.h>
31#include <tqstyle.h>
32#include <tqtimer.h>
33#include <tqtooltip.h>
34
35#include <kdebug.h>
36#include <tdeglobalsettings.h>
37
38#include "cardview.h"
39
40#define MIN_ITEM_WIDTH 80
41
42class CardViewTip : public TQLabel
43{
44 public:
45 CardViewTip( TQWidget *parent = 0, const char *name = 0 )
46 : TQLabel( parent, name )
47 {
48 setPalette( TQToolTip::palette() );
49 setFrameStyle( Panel | Plain );
50 setMidLineWidth( 0 );
51 setIndent( 1 );
52 }
53
54 ~CardViewTip() {};
55
56 protected:
57 void leaveEvent( TQEvent* )
58 {
59 hide();
60 }
61};
62
63//
64// Warning: make sure you use findRef() instead of find() to find an
65// item! Only the pointer value is unique in the list.
66//
67class CardViewItemList : public TQPtrList<CardViewItem>
68{
69 protected:
70 virtual int compareItems( TQPtrCollection::Item item1,
71 TQPtrCollection::Item item2 )
72 {
73 CardViewItem *cItem1 = (CardViewItem*)item1;
74 CardViewItem *cItem2 = (CardViewItem*)item2;
75
76 if ( cItem1 == cItem2 )
77 return 0;
78
79 if ( (cItem1 == 0) || (cItem2 == 0) )
80 return cItem1 ? -1 : 1;
81
82 if ( cItem1->caption() < cItem2->caption() )
83 return -1;
84 else if ( cItem1->caption() > cItem2->caption() )
85 return 1;
86
87 return 0;
88 }
89};
90
91class CardViewSeparator
92{
93 friend class CardView;
94
95 public:
96 CardViewSeparator( CardView *view )
97 : mView( view )
98 {
99 mRect = TQRect( 0, 0, view->separatorWidth(), 0 );
100 }
101
102 ~CardViewSeparator() {}
103
104 void paintSeparator( TQPainter *p, TQColorGroup &cg )
105 {
106 p->fillRect( 0, 0, mRect.width(), mRect.height(),
107 cg.brush(TQColorGroup::Button) );
108 }
109
110 void repaintSeparator()
111 {
112 mView->repaintContents( mRect );
113 }
114
115 private:
116 CardView *mView;
117 TQRect mRect;
118};
119
120class CardViewPrivate
121{
122 public:
123 CardViewPrivate()
124 : mSelectionMode( CardView::Multi ),
125 mDrawCardBorder( true ),
126 mDrawFieldLabels( true ),
127 mDrawSeparators( true),
128 mSepWidth( 2 ),
129 mShowEmptyFields( false ),
130 mLayoutDirty( true ),
131 mLastClickOnItem( false ),
132 mItemMargin( 0 ),
133 mItemSpacing( 10 ),
134 mItemWidth( 200 ),
135 mMaxFieldLines( INT_MAX ),
136 mCurrentItem( 0L ),
137 mLastClickPos( TQPoint(0, 0) ),
138 mRubberBandAnchor( 0 ),
139 mCompText( TQString() )
140 {};
141
142 CardViewItemList mItemList;
143 TQPtrList<CardViewSeparator> mSeparatorList;
144 TQFontMetrics *mFm;
145 TQFontMetrics *mBFm;
146 TQFont mHeaderFont;
147 CardView::SelectionMode mSelectionMode;
148 bool mDrawCardBorder;
149 bool mDrawFieldLabels;
150 bool mDrawSeparators;
151 int mSepWidth;
152 bool mShowEmptyFields;
153 bool mLayoutDirty;
154 bool mLastClickOnItem;
155 uint mItemMargin; // internal margin in items
156 uint mItemSpacing; // spacing between items, column seperators and border
157 int mItemWidth; // width of all items
158 uint mMaxFieldLines; // Max lines to dispaly pr field
159 CardViewItem *mCurrentItem;
160 TQPoint mLastClickPos;
161 TQTimer *mTimer; // times out if mouse rests for more than 500 msecs
162 CardViewTip *mTip; // passed to the item under a resting cursor to display full text
163 bool mOnSeparator; // set/reset on mouse movement
164 // for resizing by dragging the separators
165 int mResizeAnchor; // uint, ulong? the mouse down separator left
166 int mRubberBandAnchor; // for erasing rubber bands
167 // data used for resizing.
168 // as they are beeded by each mouse move while resizing, we store them here,
169 // saving 8 calculations in each mouse move.
170 int mColspace; // amount of space between items pr column
171 uint mFirst; // the first col to anchor at for painting rubber bands
172 int mFirstX; // X position of first in pixel
173 int mPressed; // the colummn that was pressed on at resizing start
174 int mSpan; // pressed - first
175 // key completion
176 TQString mCompText; // current completion string
177 TQDateTime mCompUpdated; // ...was updated at this time
178};
179
180class CardViewItemPrivate
181{
182 public:
183 CardViewItemPrivate() {}
184
185 TQString mCaption;
186 TQPtrList< CardViewItem::Field > mFieldList;
187 bool mSelected;
188 int x; // horizontal position, set by the view
189 int y; // vertical position, set by the view
190 int maxLabelWidth; // the width of the widest label, according to the view font.
191 int hcache; // height cache
192};
193
194
195CardViewItem::CardViewItem( CardView *parent, const TQString &caption )
196 : d( new CardViewItemPrivate() ), mView( parent )
197{
198 d->mCaption = caption;
199
200 initialize();
201}
202
203CardViewItem::~CardViewItem()
204{
205 // Remove ourself from the view
206 if ( mView != 0 )
207 mView->takeItem( this );
208
209 delete d;
210 d = 0;
211}
212
213void CardViewItem::initialize()
214{
215 d->mSelected = false;
216 d->mFieldList.setAutoDelete( true );
217 d->maxLabelWidth = 0;
218 d->hcache = 0;
219
220 // Add ourself to the view
221 if ( mView != 0 )
222 mView->insertItem( this );
223}
224
225void CardViewItem::paintCard( TQPainter *p, TQColorGroup &cg )
226{
227 if ( !mView )
228 return;
229
230 TQPen pen;
231 TQBrush brush;
232 TQFontMetrics fm = *(mView->d->mFm);
233 TQFontMetrics bFm = *(mView->d->mBFm);
234 bool drawLabels = mView->d->mDrawFieldLabels;
235 bool drawBorder = mView->d->mDrawCardBorder;
236 int mg = mView->itemMargin();
237 int w = mView->itemWidth() - ( mg * 2 );
238 int h = height() - ( mg * 2 );
239 const int colonWidth( fm.width( ":" ) );
240 int labelXPos = 2 + mg;
241 int labelWidth = TQMIN( w / 2 - 4 - mg, d->maxLabelWidth + colonWidth + 4 );
242 int valueXPos = labelWidth + 4 + mg;
243 int valueWidth = w - labelWidth - 4 - mg;
244
245 p->setFont( mView->font() );
246 labelWidth -= colonWidth; // extra space for the colon
247
248 if ( !drawLabels ) {
249 valueXPos = labelXPos;
250 valueWidth = w - 4;
251 }
252
253 // Draw a simple box
254 if ( isSelected() )
255 pen = TQPen( cg.highlight(), 1 );
256 else
257 pen = TQPen( cg.button(), 1 );
258 p->setPen( pen );
259
260 // Draw the border - this is only draw if the user asks for it.
261 if ( drawBorder )
262 p->drawRect( mg, mg, w, h );
263
264 // set the proper pen color for the caption box
265 if ( isSelected() )
266 brush = cg.brush( TQColorGroup::Highlight );
267 else
268 brush = cg.brush( TQColorGroup::Button );
269
270 p->fillRect( mg, mg, w, 4 + bFm.height(), brush );
271
272 // Now paint the caption
273 p->save();
274 TQFont bFont = mView->headerFont();
275 p->setFont( bFont );
276 if ( isSelected() )
277 p->setPen( cg.highlightedText() );
278 else
279 p->setPen( cg.buttonText() );
280
281 p->drawText( 2 + mg, 2 + mg + bFm.ascent(), trimString( d->mCaption, w - 4, bFm ) );
282 p->restore();
283
284 // Go through the fields and draw them
285 TQPtrListIterator<CardViewItem::Field> iter( d->mFieldList );
286 TQString label, value;
287 int yPos = mg + 4 + bFm.height() + fm.height();
288 p->setPen( cg.text() );
289
290 int fh = fm.height();
291 int cln( 0 );
292 TQString tmp;
293 int maxLines = mView->maxFieldLines();
294 for ( iter.toFirst(); iter.current(); ++iter ) {
295 value = (*iter)->second;
296 if ( value.isEmpty() && ! mView->d->mShowEmptyFields )
297 continue;
298
299 if ( drawLabels ) {
300 label = trimString( (*iter)->first, labelWidth, fm );
301 p->drawText( labelXPos, yPos, label + ":" );
302 }
303
304 for ( cln = 0; cln <= maxLines; cln++ ) {
305 tmp = value.section( '\n', cln, cln );
306 if ( !tmp.isEmpty() )
307 p->drawText( valueXPos, yPos + cln * fh, trimString( tmp, valueWidth, fm ) );
308 else
309 break;
310 }
311
312 if ( cln == 0 )
313 cln = 1;
314 yPos += cln * fh + 2;
315 }
316
317 // if we are the current item and the view has focus, draw focus rect
318 if ( mView->currentItem() == this && mView->hasFocus() ) {
319 mView->style().drawPrimitive( TQStyle::PE_FocusRect, p,
320 TQRect( 0, 0, mView->itemWidth(), h + (2 * mg) ), cg,
321 TQStyle::Style_FocusAtBorder,
322 TQStyleOption( isSelected() ? cg.highlight() : cg.base() ) );
323 }
324}
325
326const TQString &CardViewItem::caption() const
327{
328 return d->mCaption;
329}
330
331
332int CardViewItem::height( bool allowCache ) const
333{
334 // use cache
335 if ( allowCache && d->hcache )
336 return d->hcache;
337
338 // Base height:
339 // 2 for line width
340 // 2 for top caption pad
341 // 2 for bottom caption pad
342 // 2 pad for the end
343 // + 2 times the advised margin
344 int baseHeight = 8 + ( 2 * mView->itemMargin() );
345
346 // size of font for each field
347 // 2 pad for each field
348
349 bool sef = mView->showEmptyFields();
350 int fh = mView->d->mFm->height();
351 int fieldHeight = 0;
352 int lines;
353 int maxLines( mView->maxFieldLines() );
354 TQPtrListIterator<CardViewItem::Field> iter( d->mFieldList );
355 for ( iter.toFirst(); iter.current(); ++iter ) {
356 if ( !sef && (*iter)->second.isEmpty() )
357 continue;
358 lines = TQMIN( (*iter)->second.contains( '\n' ) + 1, maxLines );
359 fieldHeight += ( lines * fh ) + 2;
360 }
361
362 // height of caption font (bold)
363 fieldHeight += mView->d->mBFm->height();
364 d->hcache = baseHeight + fieldHeight;
365 return d->hcache;
366}
367
369{
370 return d->mSelected;
371}
372
373void CardViewItem::setSelected( bool selected )
374{
375 d->mSelected = selected;
376}
377
378void CardViewItem::insertField( const TQString &label, const TQString &value )
379{
380 CardViewItem::Field *f = new CardViewItem::Field( label, value );
381 d->mFieldList.append( f );
382 d->hcache = 0;
383
384 if ( mView ) {
385 mView->setLayoutDirty( true );
386 d->maxLabelWidth = TQMAX( mView->d->mFm->width( label ), d->maxLabelWidth );
387 }
388}
389
390void CardViewItem::removeField( const TQString &label )
391{
393
394 TQPtrListIterator<CardViewItem::Field> iter( d->mFieldList );
395 for ( iter.toFirst(); iter.current(); ++iter ) {
396 f = *iter;
397 if ( f->first == label )
398 break;
399 }
400
401 if (*iter)
402 d->mFieldList.remove( *iter );
403 d->hcache = 0;
404
405 if ( mView )
406 mView->setLayoutDirty( true );
407}
408
410{
411 d->mFieldList.clear();
412 d->hcache = 0;
413
414 if ( mView )
415 mView->setLayoutDirty( true );
416}
417
418TQString CardViewItem::trimString( const TQString &text, int width,
419 TQFontMetrics &fm ) const
420{
421 if ( fm.width( text ) <= width )
422 return text;
423
424 TQString dots = "...";
425 int dotWidth = fm.width( dots );
426 TQString trimmed;
427 int charNum = 0;
428
429 while ( fm.width( trimmed ) + dotWidth < width ) {
430 trimmed += text[ charNum ];
431 charNum++;
432 }
433
434 // Now trim the last char, since it put the width over the top
435 trimmed = trimmed.left( trimmed.length() - 1 );
436 trimmed += dots;
437
438 return trimmed;
439}
440
442{
443 CardViewItem *item = 0;
444
445 if ( mView )
446 item = mView->itemAfter( this );
447
448 return item;
449}
450
452{
453 if ( mView )
454 mView->repaintItem( this );
455}
456
457void CardViewItem::setCaption( const TQString &caption )
458{
459 d->mCaption = caption;
460 repaintCard();
461}
462
463TQString CardViewItem::fieldValue( const TQString &label ) const
464{
465 TQPtrListIterator<CardViewItem::Field> iter( d->mFieldList );
466 for ( iter.toFirst(); iter.current(); ++iter )
467 if ( (*iter)->first == label )
468 return (*iter)->second;
469
470 return TQString();
471}
472
473
474void CardViewItem::showFullString( const TQPoint &itempos, CardViewTip *tip )
475{
476 bool trimmed( false );
477 TQString s;
478 int mrg = mView->itemMargin();
479 int y = mView->d->mBFm->height() + 6 + mrg;
480 int w = mView->itemWidth() - (2 * mrg);
481 int lw;
482 bool drawLabels = mView->drawFieldLabels();
483 bool isLabel = drawLabels && itempos.x() < w / 2 ? true : false;
484
485 if ( itempos.y() < y ) {
486 if ( itempos.y() < 8 + mrg || itempos.y() > y - 4 )
487 return;
488 // this is the caption
489 s = caption();
490 trimmed = mView->d->mBFm->width( s ) > w - 4;
491 y = 2 + mrg;
492 lw = 0;
493 isLabel = true;
494 } else {
495 // find the field
496 Field *f = fieldAt( itempos );
497 if ( !f || ( !mView->showEmptyFields() && f->second.isEmpty() ) )
498 return;
499
500 // y position:
501 // header font height + 4px hader margin + 2px leading + item margin
502 // + actual field index * (fontheight + 2px leading)
503 int maxLines = mView->maxFieldLines();
504 bool se = mView->showEmptyFields();
505 int fh = mView->d->mFm->height();
506
507 Field *_f;
508 for ( _f = d->mFieldList.first(); _f != f; _f = d->mFieldList.next() )
509 if ( se || ! _f->second.isEmpty() )
510 y += ( TQMIN( _f->second.contains( '\n' ) + 1, maxLines ) * fh ) + 2;
511
512 if ( isLabel && itempos.y() > y + fh )
513 return;
514
515 s = isLabel ? f->first : f->second;
516
517 int colonWidth = mView->d->mFm->width(":");
518 lw = drawLabels ? TQMIN( w / 2 - 4 - mrg, d->maxLabelWidth + colonWidth + 4 ) : 0;
519 int mw = isLabel ? lw - colonWidth : w - lw - ( mrg * 2 );
520 if ( isLabel ) {
521 trimmed = mView->d->mFm->width( s ) > mw - colonWidth;
522 } else {
523 TQRect r( mView->d->mFm->boundingRect( 0, 0, INT_MAX, INT_MAX, TQt::AlignTop|TQt::AlignLeft, s ) );
524 trimmed = r.width() > mw || r.height() / fh > TQMIN( s.contains( '\n' ) + 1, maxLines );
525 }
526 }
527
528 if ( trimmed ) {
529 tip->setFont( (isLabel && !lw) ? mView->headerFont() : mView->font() );
530 tip->setText( s );
531 tip->adjustSize();
532 // find a proper position
533 int lx;
534 lx = isLabel || !drawLabels ? mrg : lw + mrg + 2;
535 TQPoint pnt( mView->contentsToViewport( TQPoint( d->x, d->y ) ) );
536 pnt += TQPoint( lx, y );
537 if ( pnt.x() < 0 )
538 pnt.setX( 0 );
539 if ( pnt.x() + tip->width() > mView->visibleWidth() )
540 pnt.setX( mView->visibleWidth() - tip->width() );
541 if ( pnt.y() + tip->height() > mView->visibleHeight() )
542 pnt.setY( TQMAX( 0, mView->visibleHeight() - tip->height() ) );
543 // show
544 tip->move( pnt );
545 tip->show();
546 }
547}
548
549CardViewItem::Field *CardViewItem::fieldAt( const TQPoint & itempos ) const
550{
551 int ypos = mView->d->mBFm->height() + 7 + mView->d->mItemMargin;
552 int iy = itempos.y();
553 // skip below caption
554 if ( iy <= ypos )
555 return 0;
556 // try find a field
557 bool showEmpty = mView->showEmptyFields();
558 int fh = mView->d->mFm->height();
559 int maxLines = mView->maxFieldLines();
560 Field *f;
561 for ( f = d->mFieldList.first(); f; f = d->mFieldList.next() ) {
562 if ( showEmpty || !f->second.isEmpty() )
563 ypos += (TQMIN( f->second.contains( '\n' )+1, maxLines ) * fh) + 2;
564 if ( iy <= ypos )
565 break;
566 }
567
568 return f ? f : 0;
569}
570
571
572CardView::CardView( TQWidget *parent, const char *name )
573 : TQScrollView( parent, name ),
574 d( new CardViewPrivate() )
575{
576 d->mItemList.setAutoDelete( true );
577 d->mSeparatorList.setAutoDelete( true );
578
579 TQFont f = font();
580 d->mFm = new TQFontMetrics( f );
581 f.setBold( true );
582 d->mHeaderFont = f;
583 d->mBFm = new TQFontMetrics( f );
584 d->mTip = new CardViewTip( viewport() );
585 d->mTip->hide();
586 d->mTimer = new TQTimer( this, "mouseTimer" );
587
588 viewport()->setMouseTracking( true );
589 viewport()->setFocusProxy( this );
590 viewport()->setFocusPolicy(TQWidget::WheelFocus );
591 viewport()->setBackgroundMode( PaletteBase );
592
593 connect( d->mTimer, TQ_SIGNAL( timeout() ), this, TQ_SLOT( tryShowFullText() ) );
594
595 setBackgroundMode( PaletteBackground, PaletteBase );
596
597 // no reason for a vertical scrollbar
598 setVScrollBarMode( AlwaysOff );
599}
600
601CardView::~CardView()
602{
603 delete d->mFm;
604 delete d->mBFm;
605 delete d;
606 d = 0;
607}
608
610{
611 d->mItemList.inSort( item );
612 setLayoutDirty( true );
613}
614
616{
617 if ( d->mCurrentItem == item )
618 d->mCurrentItem = item->nextItem();
619 d->mItemList.take( d->mItemList.findRef( item ) );
620
621 setLayoutDirty( true );
622}
623
625{
626 d->mItemList.clear();
627
628 setLayoutDirty( true );
629}
630
632{
633 if ( !d->mCurrentItem && d->mItemList.count() )
634 d->mCurrentItem = d->mItemList.first();
635
636 return d->mCurrentItem;
637}
638
640{
641 if ( !item )
642 return;
643 else if ( item->cardView() != this ) {
644 kdDebug(5720)<<"CardView::setCurrentItem: Item ("<<item<<") not owned! Backing out.."<<endl;
645 return;
646 } else if ( item == currentItem() ) {
647 return;
648 }
649
650 if ( d->mSelectionMode == Single ) {
651 setSelected( item, true );
652 } else {
653 CardViewItem *it = d->mCurrentItem;
654 d->mCurrentItem = item;
655 if ( it )
656 it->repaintCard();
657
658 item->repaintCard();
659 }
660
661 if ( ! d->mOnSeparator )
662 ensureItemVisible( item );
663
664 emit currentChanged( item );
665}
666
667CardViewItem *CardView::itemAt( const TQPoint &viewPos ) const
668{
669 CardViewItem *item = 0;
670 TQPtrListIterator<CardViewItem> iter( d->mItemList );
671 bool found = false;
672 for ( iter.toFirst(); iter.current() && !found; ++iter ) {
673 item = *iter;
674 if ( TQRect( item->d->x, item->d->y, d->mItemWidth, item->height() ).contains( viewPos ) )
675 found = true;
676 }
677
678 if ( found )
679 return item;
680
681 return 0;
682}
683
684TQRect CardView::itemRect( const CardViewItem *item ) const
685{
686 return TQRect( item->d->x, item->d->y, d->mItemWidth, item->height() );
687}
688
690{
691 ensureVisible( item->d->x, item->d->y, d->mItemSpacing, 0 );
692 ensureVisible( item->d->x + d->mItemWidth, item->d->y, d->mItemSpacing, 0 );
693}
694
696{
697 repaintContents( TQRect( item->d->x, item->d->y, d->mItemWidth, item->height() ) );
698}
699
700void CardView::setSelectionMode( CardView::SelectionMode mode )
701{
702 selectAll( false );
703
704 d->mSelectionMode = mode;
705}
706
707CardView::SelectionMode CardView::selectionMode() const
708{
709 return d->mSelectionMode;
710}
711
712void CardView::selectAll( bool state )
713{
714 TQPtrListIterator<CardViewItem> iter( d->mItemList );
715 if ( !state ) {
716 for ( iter.toFirst(); iter.current(); ++iter ) {
717 if ( (*iter)->isSelected() ) {
718 (*iter)->setSelected( false );
719 (*iter)->repaintCard();
720 }
721 }
722
723 emit selectionChanged( 0 );
724 } else if ( d->mSelectionMode != CardView::Single ) {
725 for ( iter.toFirst(); iter.current(); ++iter ) {
726 (*iter)->setSelected( true );
727 }
728
729 if ( d->mItemList.count() > 0 ) {
730 // emit, since there must have been at least one selected
731 emit selectionChanged();
732 viewport()->update();
733 }
734 }
735}
736
737void CardView::setSelected( CardViewItem *item, bool selected )
738{
739 if ( (item == 0) || (item->isSelected() == selected) )
740 return;
741
742 if ( selected && d->mCurrentItem != item ) {
743 CardViewItem *it = d->mCurrentItem;
744 d->mCurrentItem = item;
745 if ( it )
746 it->repaintCard();
747 }
748
749 if ( d->mSelectionMode == CardView::Single ) {
750 bool b = signalsBlocked();
751 blockSignals( true );
752 selectAll( false );
753 blockSignals( b );
754
755 if ( selected ) {
756 item->setSelected( selected );
757 item->repaintCard();
758 emit selectionChanged();
759 emit selectionChanged( item );
760 } else {
761 emit selectionChanged();
762 emit selectionChanged( 0 );
763 }
764 } else if ( d->mSelectionMode == CardView::Multi ) {
765 item->setSelected( selected );
766 item->repaintCard();
767 emit selectionChanged();
768 } else if ( d->mSelectionMode == CardView::Extended ) {
769 bool b = signalsBlocked();
770 blockSignals( true );
771 selectAll( false );
772 blockSignals( b );
773
774 item->setSelected( selected );
775 item->repaintCard();
776 emit selectionChanged();
777 }
778}
779
781{
782 return (item && item->isSelected());
783}
784
786{
787 // find the first selected item
788 TQPtrListIterator<CardViewItem> iter( d->mItemList );
789 for ( iter.toFirst(); iter.current(); ++iter ) {
790 if ( (*iter)->isSelected() )
791 return *iter;
792 }
793
794 return 0;
795}
796
798{
799 return d->mItemList.first();
800}
801
803{
804 return d->mItemList.count();
805}
806
807CardViewItem *CardView::findItem( const TQString &text, const TQString &label,
808 TQt::StringComparisonMode compare ) const
809{
810 // If the text is empty, we will return null, since empty text will
811 // match anything!
812 if ( text.isEmpty() )
813 return 0;
814
815 TQPtrListIterator<CardViewItem> iter( d->mItemList );
816 if ( compare & TQt::BeginsWith ) {
817 TQString value;
818 for ( iter.toFirst(); iter.current(); ++iter ) {
819 value = (*iter)->fieldValue( label ).upper();
820 if ( value.startsWith( text.upper() ) )
821 return *iter;
822 }
823 } else {
824 kdDebug(5720) << "CardView::findItem: search method not implemented" << endl;
825 }
826
827 return 0;
828}
829
831{
832 return d->mDrawSeparators ?
833 d->mItemWidth + ( 2 * d->mItemSpacing ) + d->mSepWidth :
834 d->mItemWidth + d->mItemSpacing;
835}
836
837void CardView::drawContents( TQPainter *p, int clipx, int clipy,
838 int clipw, int cliph )
839{
840 TQScrollView::drawContents( p, clipx, clipy, clipw, cliph );
841
842 if ( d->mLayoutDirty )
843 calcLayout();
844
845 // allow setting costum colors in the viewport pale
846 TQColorGroup cg = viewport()->palette().active();
847
848 TQRect clipRect( clipx, clipy, clipw, cliph );
849 TQRect cardRect;
850 TQRect sepRect;
851 CardViewItem *item;
852 CardViewSeparator *sep;
853
854 // make sure the viewport is a pure background
855 viewport()->erase( clipRect );
856
857 // Now tell the cards to draw, if they are in the clip region
858 TQPtrListIterator<CardViewItem> iter( d->mItemList );
859 for ( iter.toFirst(); iter.current(); ++iter) {
860 item = *iter;
861 cardRect.setRect( item->d->x, item->d->y, d->mItemWidth, item->height() );
862
863 if ( clipRect.intersects( cardRect ) || clipRect.contains( cardRect ) ) {
864 // Tell the card to paint
865 p->save();
866 p->translate( cardRect.x(), cardRect.y() );
867 item->paintCard( p, cg );
868 p->restore();
869 }
870 }
871
872 // Followed by the separators if they are in the clip region
873 TQPtrListIterator<CardViewSeparator> sepIter( d->mSeparatorList );
874 for ( sepIter.toFirst(); sepIter.current(); ++sepIter ) {
875 sep = *sepIter;
876 sepRect = sep->mRect;
877
878 if ( clipRect.intersects( sepRect ) || clipRect.contains( sepRect ) ) {
879 p->save();
880 p->translate( sepRect.x(), sepRect.y() );
881 sep->paintSeparator( p, cg );
882 p->restore();
883 }
884 }
885}
886
887void CardView::resizeEvent( TQResizeEvent *event )
888{
889 TQScrollView::resizeEvent( event );
890
891 setLayoutDirty( true );
892}
893
895{
896 // Start in the upper left corner and layout all the
897 // cars using their height and width
898 int maxWidth = 0;
899 int maxHeight = 0;
900 int xPos = 0;
901 int yPos = 0;
902 int cardSpacing = d->mItemSpacing;
903
904 // delete the old separators
905 d->mSeparatorList.clear();
906
907 TQPtrListIterator<CardViewItem> iter( d->mItemList );
908 CardViewItem *item = 0;
909 CardViewSeparator *sep = 0;
910 xPos += cardSpacing;
911
912 for ( iter.toFirst(); iter.current(); ++iter ) {
913 item = *iter;
914
915 yPos += cardSpacing;
916
917 if ( yPos + item->height() + cardSpacing >= height() - horizontalScrollBar()->height() ) {
918 maxHeight = TQMAX( maxHeight, yPos );
919
920 // Drawing in this column would be greater than the height
921 // of the scroll view, so move to next column
922 yPos = cardSpacing;
923 xPos += cardSpacing + maxWidth;
924 if ( d->mDrawSeparators ) {
925 // Create a separator since the user asked
926 sep = new CardViewSeparator( this );
927 sep->mRect.moveTopLeft( TQPoint( xPos, yPos + d->mItemMargin ) );
928 xPos += d->mSepWidth + cardSpacing;
929 d->mSeparatorList.append( sep );
930 }
931
932 maxWidth = 0;
933 }
934
935 item->d->x = xPos;
936 item->d->y = yPos;
937
938 yPos += item->height();
939 maxWidth = TQMAX( maxWidth, d->mItemWidth );
940 }
941
942 xPos += maxWidth;
943 resizeContents( xPos + cardSpacing, maxHeight );
944
945 // Update the height of all the separators now that we know the
946 // max height of a column
947 TQPtrListIterator<CardViewSeparator> sepIter( d->mSeparatorList );
948 for ( sepIter.toFirst(); sepIter.current(); ++sepIter )
949 (*sepIter)->mRect.setHeight( maxHeight - 2 * cardSpacing - 2 * d->mItemMargin );
950
951 d->mLayoutDirty = false;
952}
953
955{
956 d->mItemList.findRef( item );
957 return d->mItemList.next();
958}
959
961{
962 return d->mItemMargin;
963}
964
965void CardView::setItemMargin( uint margin )
966{
967 if ( margin == d->mItemMargin )
968 return;
969
970 d->mItemMargin = margin;
971 setLayoutDirty( true );
972}
973
975{
976 return d->mItemSpacing;
977}
978
979void CardView::setItemSpacing( uint spacing )
980{
981 if ( spacing == d->mItemSpacing )
982 return;
983
984 d->mItemSpacing = spacing;
985 setLayoutDirty( true );
986}
987
988void CardView::contentsMousePressEvent( TQMouseEvent *e )
989{
990 TQScrollView::contentsMousePressEvent( e );
991
992 TQPoint pos = contentsToViewport( e->pos() );
993 d->mLastClickPos = e->pos();
994
995 CardViewItem *item = itemAt( e->pos() );
996
997 if ( item == 0 ) {
998 d->mLastClickOnItem = false;
999 if ( d->mOnSeparator) {
1000 d->mResizeAnchor = e->x() + contentsX();
1001 d->mColspace = (2 * d->mItemSpacing);
1002 int ccw = d->mItemWidth + d->mColspace + d->mSepWidth;
1003 d->mFirst = (contentsX() + d->mSepWidth) / ccw;
1004 d->mPressed = (d->mResizeAnchor + d->mSepWidth) / ccw;
1005 d->mSpan = d->mPressed - d->mFirst;
1006 d->mFirstX = d->mFirst * ccw;
1007 if ( d->mFirstX )
1008 d->mFirstX -= d->mSepWidth;
1009 } else {
1010 selectAll( false );
1011 }
1012
1013 return;
1014 }
1015
1016 d->mLastClickOnItem = true;
1017
1018 CardViewItem *other = d->mCurrentItem;
1019 setCurrentItem( item );
1020
1021 // Always emit the selection
1022 emit clicked( item );
1023
1024 // The RMB click
1025 if ( e->button() & TQt::RightButton ) {
1026 // clear previous selection
1027 bool blocked = signalsBlocked();
1028 blockSignals( true );
1029 selectAll( false );
1030 blockSignals( blocked );
1031
1032 // select current item
1033 item->setSelected( true );
1034
1035 emit contextMenuRequested( item, mapToGlobal( pos ) );
1036 return;
1037 }
1038
1039 // Check the selection type and update accordingly
1040 if ( d->mSelectionMode == CardView::Single ) {
1041 // make sure it isn't already selected
1042 if ( item->isSelected() )
1043 return;
1044
1045 bool b = signalsBlocked();
1046 blockSignals( true );
1047 selectAll( false );
1048 blockSignals( b );
1049
1050 item->setSelected( true );
1051 item->repaintCard();
1052 emit selectionChanged( item );
1053 } else if ( d->mSelectionMode == CardView::Multi ) {
1054 // toggle the selection
1055 item->setSelected( !item->isSelected() );
1056 item->repaintCard();
1057 emit selectionChanged();
1058 } else if ( d->mSelectionMode == CardView::Extended ) {
1059 if ( (e->button() & TQt::LeftButton) && (e->state() & TQt::ShiftButton) ) {
1060 if ( item == other )
1061 return;
1062
1063 bool s = !item->isSelected();
1064
1065 if ( s && !(e->state() & ControlButton) ) {
1066 bool b = signalsBlocked();
1067 blockSignals( true );
1068 selectAll( false );
1069 blockSignals( b );
1070 }
1071
1072 int from, to, a, b;
1073 a = d->mItemList.findRef( item );
1074 b = d->mItemList.findRef( other );
1075 from = a < b ? a : b;
1076 to = a > b ? a : b;
1077
1078 CardViewItem *aItem;
1079 for ( ; from <= to; from++ ) {
1080 aItem = d->mItemList.at( from );
1081 aItem->setSelected( s );
1082 repaintItem( aItem );
1083 }
1084
1085 emit selectionChanged();
1086 } else if ( (e->button() & TQt::LeftButton) && (e->state() & TQt::ControlButton) ) {
1087 item->setSelected( !item->isSelected() );
1088 item->repaintCard();
1089 emit selectionChanged();
1090 } else if ( e->button() & TQt::LeftButton ) {
1091 bool b = signalsBlocked();
1092 blockSignals( true );
1093 selectAll( false );
1094 blockSignals( b );
1095
1096 item->setSelected( true );
1097 item->repaintCard();
1098 emit selectionChanged();
1099 }
1100 }
1101}
1102
1103void CardView::contentsMouseReleaseEvent( TQMouseEvent *e )
1104{
1105 TQScrollView::contentsMouseReleaseEvent( e );
1106
1107 if ( d->mResizeAnchor && d->mSpan ) {
1108 unsetCursor();
1109 // hide rubber bands
1110 int newiw = d->mItemWidth - ((d->mResizeAnchor - d->mRubberBandAnchor) / d->mSpan);
1111 drawRubberBands( 0 );
1112 // we should move to reflect the new position if we are scrolled.
1113 if ( contentsX() ) {
1114 int newX = TQMAX( 0, ( d->mPressed * ( newiw + d->mColspace + d->mSepWidth ) ) - e->x() );
1115 setContentsPos( newX, contentsY() );
1116 }
1117 // set new item width
1118 setItemWidth( newiw );
1119 // reset anchors
1120 d->mResizeAnchor = 0;
1121 d->mRubberBandAnchor = 0;
1122 return;
1123 }
1124
1125 // If there are accel keys, we will not emit signals
1126 if ( (e->state() & TQt::ShiftButton) || (e->state() & TQt::ControlButton) )
1127 return;
1128
1129 // Get the item at this position
1130 CardViewItem *item = itemAt( e->pos() );
1131
1132 if ( item && TDEGlobalSettings::singleClick() )
1133 emit executed( item );
1134}
1135
1136void CardView::contentsMouseDoubleClickEvent( TQMouseEvent *e )
1137{
1138 TQScrollView::contentsMouseDoubleClickEvent( e );
1139
1140 CardViewItem *item = itemAt( e->pos() );
1141
1142 if ( item )
1143 d->mCurrentItem = item;
1144
1145 if ( item && !TDEGlobalSettings::singleClick() )
1146 emit executed(item);
1147
1148 emit doubleClicked( item );
1149}
1150
1151void CardView::contentsMouseMoveEvent( TQMouseEvent *e )
1152{
1153 // resizing
1154 if ( d->mResizeAnchor ) {
1155 int x = e->x();
1156 if ( x != d->mRubberBandAnchor )
1157 drawRubberBands( x );
1158 return;
1159 }
1160
1161 if ( d->mLastClickOnItem && (e->state() & TQt::LeftButton) &&
1162 ((e->pos() - d->mLastClickPos).manhattanLength() > 4)) {
1163
1164 startDrag();
1165 return;
1166 }
1167
1168 d->mTimer->start( 500 );
1169
1170 // see if we are over a separator
1171 // only if we actually have them painted?
1172 if ( d->mDrawSeparators ) {
1173 int colcontentw = d->mItemWidth + (2 * d->mItemSpacing);
1174 int colw = colcontentw + d->mSepWidth;
1175 int m = e->x() % colw;
1176 if ( m >= colcontentw && m > 0 ) {
1177 setCursor( SplitHCursor );
1178 d->mOnSeparator = true;
1179 } else {
1180 setCursor( ArrowCursor );
1181 d->mOnSeparator = false;
1182 }
1183 }
1184}
1185
1186void CardView::enterEvent( TQEvent* )
1187{
1188 d->mTimer->start( 500 );
1189}
1190
1191void CardView::leaveEvent( TQEvent* )
1192{
1193 d->mTimer->stop();
1194 if ( d->mOnSeparator ) {
1195 d->mOnSeparator = false;
1196 setCursor( ArrowCursor );
1197 }
1198}
1199
1200void CardView::focusInEvent( TQFocusEvent* )
1201{
1202 if ( !d->mCurrentItem && d->mItemList.count() )
1203 setCurrentItem( d->mItemList.first() );
1204 else if ( d->mCurrentItem )
1205 d->mCurrentItem->repaintCard();
1206}
1207
1208void CardView::focusOutEvent( TQFocusEvent* )
1209{
1210 if ( d->mCurrentItem )
1211 d->mCurrentItem->repaintCard();
1212}
1213
1214void CardView::keyPressEvent( TQKeyEvent *e )
1215{
1216 if ( !(childCount() && d->mCurrentItem) ) {
1217 e->ignore();
1218 return;
1219 }
1220
1221 uint pos = d->mItemList.findRef( d->mCurrentItem );
1222 CardViewItem *aItem = 0;
1223 CardViewItem *old = d->mCurrentItem;
1224
1225 switch ( e->key() ) {
1226 case Key_Up:
1227 if ( pos > 0 ) {
1228 aItem = d->mItemList.at( pos - 1 );
1229 setCurrentItem( aItem );
1230 }
1231 break;
1232 case Key_Down:
1233 if ( pos < d->mItemList.count() - 1 ) {
1234 aItem = d->mItemList.at( pos + 1 );
1235 setCurrentItem( aItem );
1236 }
1237 break;
1238 case Key_Left:
1239 {
1240 // look for an item in the previous/next column, starting from
1241 // the vertical middle of the current item.
1242 // FIXME use nice calculatd measures!!!
1243 TQPoint aPoint( d->mCurrentItem->d->x, d->mCurrentItem->d->y );
1244 aPoint -= TQPoint( 30, -(d->mCurrentItem->height() / 2) );
1245 aItem = itemAt( aPoint );
1246 // maybe we hit some space below an item
1247 while ( !aItem && aPoint.y() > 27 ) {
1248 aPoint -= TQPoint( 0, 16 );
1249 aItem = itemAt( aPoint );
1250 }
1251 if ( aItem )
1252 setCurrentItem( aItem );
1253
1254 break;
1255 }
1256 case Key_Right:
1257 {
1258 // FIXME use nice calculated measures!!!
1259 TQPoint aPoint( d->mCurrentItem->d->x + d->mItemWidth, d->mCurrentItem->d->y );
1260 aPoint += TQPoint( 30, (d->mCurrentItem->height() / 2) );
1261 aItem = itemAt( aPoint );
1262 while ( !aItem && aPoint.y() > 27 ) {
1263 aPoint -= TQPoint( 0, 16 );
1264 aItem = itemAt( aPoint );
1265 }
1266 if ( aItem )
1267 setCurrentItem( aItem );
1268
1269 break;
1270 }
1271 case Key_Home:
1272 aItem = d->mItemList.first();
1273 setCurrentItem( aItem );
1274 break;
1275 case Key_End:
1276 aItem = d->mItemList.last();
1277 setCurrentItem( aItem );
1278 break;
1279 case Key_Prior: // PageUp
1280 {
1281 // TQListView: "Make the item above the top visible and current"
1282 // TODO if contentsY(), pick the top item of the leftmost visible column
1283 if ( contentsX() <= 0 )
1284 return;
1285 int cw = columnWidth();
1286 int theCol = ( TQMAX( 0, ( contentsX() / cw) * cw ) ) + d->mItemSpacing;
1287 aItem = itemAt( TQPoint( theCol + 1, d->mItemSpacing + 1 ) );
1288 if ( aItem )
1289 setCurrentItem( aItem );
1290
1291 break;
1292 }
1293 case Key_Next: // PageDown
1294 {
1295 // TQListView: "Make the item below the bottom visible and current"
1296 // find the first not fully visible column.
1297 // TODO: consider if a partly visible (or even hidden) item at the
1298 // bottom of the rightmost column exists
1299 int cw = columnWidth();
1300 int theCol = ( (( contentsX() + visibleWidth() ) / cw) * cw ) + d->mItemSpacing + 1;
1301 // if separators are on, we may need to we may be one column further right if only the spacing/sep is hidden
1302 if ( d->mDrawSeparators && cw - (( contentsX() + visibleWidth() ) % cw) <= int( d->mItemSpacing + d->mSepWidth ) )
1303 theCol += cw;
1304
1305 // make sure this is not too far right
1306 while ( theCol > contentsWidth() )
1307 theCol -= columnWidth();
1308
1309 aItem = itemAt( TQPoint( theCol, d->mItemSpacing + 1 ) );
1310
1311 if ( aItem )
1312 setCurrentItem( aItem );
1313
1314 break;
1315 }
1316 case Key_Space:
1317 setSelected( d->mCurrentItem, !d->mCurrentItem->isSelected() );
1318 emit selectionChanged();
1319 break;
1320 case Key_Return:
1321 case Key_Enter:
1322 emit returnPressed( d->mCurrentItem );
1323 emit executed( d->mCurrentItem );
1324 break;
1325 case Key_Menu:
1326 emit contextMenuRequested( d->mCurrentItem, viewport()->mapToGlobal(
1327 itemRect(d->mCurrentItem).center() ) );
1328 break;
1329 default:
1330 if ( (e->state() & ControlButton) && e->key() == Key_A ) {
1331 // select all
1332 selectAll( true );
1333 break;
1334 } else if ( !e->text().isEmpty() && e->text()[ 0 ].isPrint() ) {
1335 // if we have a string, do autosearch
1336 }
1337 break;
1338 }
1339
1340 // handle selection
1341 if ( aItem ) {
1342 if ( d->mSelectionMode == CardView::Extended ) {
1343 if ( e->state() & ShiftButton ) {
1344 // shift button: toggle range
1345 // if control button is pressed, leave all items
1346 // and toggle selection current->old current
1347 // otherwise, ??????
1348 bool s = ! aItem->isSelected();
1349 int from, to, a, b;
1350 a = d->mItemList.findRef( aItem );
1351 b = d->mItemList.findRef( old );
1352 from = a < b ? a : b;
1353 to = a > b ? a : b;
1354
1355 if ( to - from > 1 ) {
1356 bool b = signalsBlocked();
1357 blockSignals( true );
1358 selectAll( false );
1359 blockSignals( b );
1360 }
1361
1362 CardViewItem *item;
1363 for ( ; from <= to; from++ ) {
1364 item = d->mItemList.at( from );
1365 item->setSelected( s );
1366 repaintItem( item );
1367 }
1368
1369 emit selectionChanged();
1370 } else if ( e->state() & ControlButton ) {
1371 // control button: do nothing
1372 } else {
1373 // no button: move selection to this item
1374 bool b = signalsBlocked();
1375 blockSignals( true );
1376 selectAll( false );
1377 blockSignals( b );
1378
1379 setSelected( aItem, true );
1380 emit selectionChanged();
1381 }
1382 }
1383 }
1384}
1385
1386void CardView::contentsWheelEvent( TQWheelEvent *e )
1387{
1388 scrollBy( 2 * e->delta() / -3, 0 );
1389}
1390
1392{
1393 if ( d->mLayoutDirty != dirty ) {
1394 d->mLayoutDirty = dirty;
1395 repaint();
1396 }
1397}
1398
1400{
1401 if ( enabled != d->mDrawCardBorder ) {
1402 d->mDrawCardBorder = enabled;
1403 repaint();
1404 }
1405}
1406
1408{
1409 return d->mDrawCardBorder;
1410}
1411
1413{
1414 if ( enabled != d->mDrawSeparators ) {
1415 d->mDrawSeparators = enabled;
1416 setLayoutDirty( true );
1417 }
1418}
1419
1421{
1422 return d->mDrawSeparators;
1423}
1424
1426{
1427 if ( enabled != d->mDrawFieldLabels ) {
1428 d->mDrawFieldLabels = enabled;
1429 repaint();
1430 }
1431}
1432
1434{
1435 return d->mDrawFieldLabels;
1436}
1437
1439{
1440 if ( show != d->mShowEmptyFields ) {
1441 d->mShowEmptyFields = show;
1442 setLayoutDirty( true );
1443 }
1444}
1445
1447{
1448 return d->mShowEmptyFields;
1449}
1450
1452{
1453 // The default implementation is a no-op. It must be
1454 // reimplemented in a subclass to be useful
1455}
1456
1457void CardView::tryShowFullText()
1458{
1459 d->mTimer->stop();
1460 // if we have an item
1461 TQPoint cpos = viewportToContents( viewport()->mapFromGlobal( TQCursor::pos() ) );
1462 CardViewItem *item = itemAt( cpos );
1463 if ( item ) {
1464 // query it for a value to display
1465 TQPoint ipos = cpos - itemRect( item ).topLeft();
1466 item->showFullString( ipos, d->mTip );
1467 }
1468}
1469
1470void CardView::drawRubberBands( int pos )
1471{
1472 if ( pos && d &&
1473 (!d->mSpan || ((pos - d->mFirstX) / d->mSpan) - d->mColspace - d->mSepWidth < MIN_ITEM_WIDTH) )
1474 return;
1475
1476 int tmpcw = (d->mRubberBandAnchor - d->mFirstX) / d->mSpan;
1477 int x = d->mFirstX + tmpcw - d->mSepWidth - contentsX();
1478 int h = visibleHeight();
1479
1480 TQPainter p( viewport() );
1481 p.setRasterOp( XorROP );
1482 p.setPen( gray );
1483 p.setBrush( gray );
1484 uint n = d->mFirst;
1485 // erase
1486 if ( d->mRubberBandAnchor )
1487 do {
1488 p.drawRect( x, 0, 2, h );
1489 x += tmpcw;
1490 n++;
1491 } while ( x < visibleWidth() && n < d->mSeparatorList.count() );
1492 // paint new
1493 if ( ! pos )
1494 return;
1495 tmpcw = (pos - d->mFirstX) / d->mSpan;
1496 n = d->mFirst;
1497 x = d->mFirstX + tmpcw - d->mSepWidth - contentsX();
1498 do {
1499 p.drawRect( x, 0, 2, h );
1500 x += tmpcw;
1501 n++;
1502 } while ( x < visibleWidth() && n < d->mSeparatorList.count() );
1503 d->mRubberBandAnchor = pos;
1504}
1505
1507{
1508 return d->mItemWidth;
1509}
1510
1512{
1513 if ( w == d->mItemWidth )
1514 return;
1515 if ( w < MIN_ITEM_WIDTH )
1516 w = MIN_ITEM_WIDTH;
1517 d->mItemWidth = w;
1518 setLayoutDirty( true );
1519 updateContents();
1520}
1521
1522void CardView::setHeaderFont( const TQFont &fnt )
1523{
1524 d->mHeaderFont = fnt;
1525 delete d->mBFm;
1526 d->mBFm = new TQFontMetrics( fnt );
1527}
1528
1530{
1531 return d->mHeaderFont;
1532}
1533
1534void CardView::setFont( const TQFont &fnt )
1535{
1536 TQScrollView::setFont( fnt );
1537 delete d->mFm;
1538 d->mFm = new TQFontMetrics( fnt );
1539}
1540
1542{
1543 return d->mSepWidth;
1544}
1545
1547{
1548 d->mSepWidth = width;
1549 setLayoutDirty( true );
1550}
1551
1553{
1554 return d->mMaxFieldLines;
1555}
1556
1558{
1559 d->mMaxFieldLines = howmany ? howmany : INT_MAX;
1560 // FIXME update, forcing the items to recalc height!!
1561}
1562
1563#include "cardview.moc"
Represents a single card (item) in the card view.
Definition: cardview.h:50
void removeField(const TQString &label)
Removes the field with label label from the card.
Definition: cardview.cpp:390
const TQString & caption() const
Definition: cardview.cpp:326
virtual void paintCard(TQPainter *p, TQColorGroup &cg)
Paints the card using the given painter and color group.
Definition: cardview.cpp:225
CardViewItem * nextItem() const
Definition: cardview.cpp:441
void clearFields()
Removes all the fields from this card.
Definition: cardview.cpp:409
void setSelected(bool selected)
Sets the card as selected.
Definition: cardview.cpp:373
void setCaption(const TQString &caption)
Sets the caption of the card.
Definition: cardview.cpp:457
void showFullString(const TQPoint &pos, CardViewTip *tip)
Called by the parent card view when the mouse has been resting for a certain amount of time.
Definition: cardview.cpp:474
virtual void repaintCard()
Repaints the card.
Definition: cardview.cpp:451
CardViewItem(CardView *parent, const TQString &caption=TQString())
Constructor.
Definition: cardview.cpp:195
TQPair< TQString, TQString > Field
A single field in the card view.
Definition: cardview.h:58
bool isSelected() const
Definition: cardview.cpp:368
int height(bool allowCache=true) const
Definition: cardview.cpp:332
TQString fieldValue(const TQString &label) const
Definition: cardview.cpp:463
void insertField(const TQString &label, const TQString &value)
Adds a field to the card.
Definition: cardview.cpp:378
Field * fieldAt(const TQPoint &itempos) const
Definition: cardview.cpp:549
The CardView is a method of displaying data in cards.
Definition: cardview.h:195
void returnPressed(CardViewItem *)
Emitted when the return key is pressed in an item.
void setDrawColSeparators(bool enabled)
Sets if the column separator should be drawn.
Definition: cardview.cpp:1412
CardViewItem * itemAt(const TQPoint &viewPos) const
Definition: cardview.cpp:667
void setDrawCardBorder(bool enabled)
Sets if the border around a card should be draw.
Definition: cardview.cpp:1399
int separatorWidth() const
Definition: cardview.cpp:1541
void setShowEmptyFields(bool show)
Sets if fields with no value should be drawn (of cause the label only, but it allows for embedded edi...
Definition: cardview.cpp:1438
CardViewItem * itemAfter(const CardViewItem *item) const
Definition: cardview.cpp:954
void setItemSpacing(uint spacing)
Sets the item spacing.
Definition: cardview.cpp:979
void currentChanged(CardViewItem *)
Emitted when the current item changes.
bool drawColSeparators() const
Definition: cardview.cpp:1420
void clear()
Clears the view and deletes all card view items.
Definition: cardview.cpp:624
void setMaxFieldLines(int howmany)
Sets the maximum number of lines to display pr field.
Definition: cardview.cpp:1557
void ensureItemVisible(const CardViewItem *item)
Ensures that the given item is in the viewable area of the widget.
Definition: cardview.cpp:689
void contextMenuRequested(CardViewItem *, const TQPoint &)
Emitted when the context menu is requested in some way.
void setSelectionMode(SelectionMode mode)
Sets the selection mode.
Definition: cardview.cpp:700
CardViewItem * firstItem() const
Definition: cardview.cpp:797
CardViewItem * currentItem() const
Definition: cardview.cpp:631
CardViewItem * findItem(const TQString &text, const TQString &label, TQt::StringComparisonMode compare=TQt::BeginsWith) const
Attempts to find the first item matching the params.
Definition: cardview.cpp:807
void setFont(const TQFont &fnt)
Reimplementation from TQWidget.
Definition: cardview.cpp:1534
TQFont headerFont() const
Definition: cardview.cpp:1529
CardViewItem * selectedItem() const
Definition: cardview.cpp:785
TQRect itemRect(const CardViewItem *item) const
Definition: cardview.cpp:684
void setCurrentItem(CardViewItem *item)
Sets the CardViewItem item to the current item in the view.
Definition: cardview.cpp:639
bool isSelected(CardViewItem *item) const
Definition: cardview.cpp:780
void doubleClicked(CardViewItem *)
Emitted whenever the user double clicks on an item.
void executed(CardViewItem *)
Emitted whenever the user 'executes' an item.
void drawContents(TQPainter *p, int clipx, int clipy, int clipw, int cliph)
Determines which cards intersect that region and tells them to paint themselves.
Definition: cardview.cpp:837
uint columnWidth() const
Returns the amounts of pixels required for one column.
Definition: cardview.cpp:830
void calcLayout()
Does the math based on the bounding rect of the cards to properly lay the cards out on the screen.
Definition: cardview.cpp:894
void contentsWheelEvent(TQWheelEvent *)
Changes the direction the canvas scolls.
Definition: cardview.cpp:1386
void setHeaderFont(const TQFont &fnt)
Sets the header font.
Definition: cardview.cpp:1522
void setSeparatorWidth(int width)
Sets the column separator width.
Definition: cardview.cpp:1546
int maxFieldLines() const
Definition: cardview.cpp:1552
void takeItem(CardViewItem *item)
Takes the item from the view.
Definition: cardview.cpp:615
void setItemMargin(uint margin)
Sets the internal item margin.
Definition: cardview.cpp:965
void setDrawFieldLabels(bool enabled)
Sets if the field labels should be drawn.
Definition: cardview.cpp:1425
void selectAll(bool state)
Selects or deselects all items.
Definition: cardview.cpp:712
uint itemMargin() const
Definition: cardview.cpp:960
bool drawCardBorder() const
Definition: cardview.cpp:1407
void setLayoutDirty(bool dirty)
Sets the layout to dirty and calls for a repaint.
Definition: cardview.cpp:1391
void insertItem(CardViewItem *item)
Inserts the item into the card view.
Definition: cardview.cpp:609
void selectionChanged()
Emitted whenever the selection changes.
void clicked(CardViewItem *)
This method is emitted whenever an item is clicked.
void repaintItem(const CardViewItem *item)
Repaints the given item.
Definition: cardview.cpp:695
void setItemWidth(int width)
Sets the width made available to card items.
Definition: cardview.cpp:1511
uint itemSpacing() const
Definition: cardview.cpp:974
void resizeEvent(TQResizeEvent *)
Sets the layout to dirty and repaints.
Definition: cardview.cpp:887
bool drawFieldLabels() const
Definition: cardview.cpp:1433
int childCount() const
Definition: cardview.cpp:802
SelectionMode selectionMode() const
Definition: cardview.cpp:707
int itemWidth() const
Definition: cardview.cpp:1506
bool showEmptyFields() const
Definition: cardview.cpp:1446
void setSelected(CardViewItem *item, bool selected)
Selects or deselects the given item.
Definition: cardview.cpp:737
CardView(TQWidget *parent, const char *name)
Constructor.
Definition: cardview.cpp:572
virtual void startDrag()
Overload this method to be told when a drag should be started.
Definition: cardview.cpp:1451