00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
#include "cardview.h"
00026
00027
#include <limits.h>
00028
00029
#include <qpainter.h>
00030
#include <qtimer.h>
00031
#include <qdatetime.h>
00032
#include <qlabel.h>
00033
#include <qstyle.h>
00034
#include <qcursor.h>
00035
#include <qtooltip.h>
00036
00037
#include <kdebug.h>
00038
#include <kglobalsettings.h>
00039
00040
00041
#define MIN_ITEM_WIDTH 80
00042
00043
00045
00046
class CardViewTip :
public QLabel {
00047
public:
00048 CardViewTip(
QWidget *parent=0,
const char *name=0) :
QLabel( parent, name )
00049 {
00050 setPalette( QToolTip::palette() );
00051 setFrameStyle( Panel|Plain );
00052 setMidLineWidth(0);
00053 setIndent(1);
00054 }
00055
00056 ~CardViewTip() {};
00057
protected:
00058
void leaveEvent(
QEvent * )
00059 {
00060 hide();
00061 }
00062 };
00063
00065
00066
00067
00068
00069
00070
00071
00072
class CardViewItemList :
public QPtrList<CardViewItem>
00073 {
00074
protected:
00075
virtual int compareItems(QPtrCollection::Item item1,
00076 QPtrCollection::Item item2)
00077 {
00078
CardViewItem *cItem1 = (
CardViewItem*)item1;
00079
CardViewItem *cItem2 = (
CardViewItem*)item2;
00080
00081
if ( cItem1 == cItem2 )
00082
return 0;
00083
00084
if ((cItem1 == 0) || (cItem2 == 0))
00085
return cItem1 ? -1 : 1;
00086
00087
if (cItem1->
caption() < cItem2->
caption())
00088
return -1;
00089
00090
else if (cItem1->
caption() > cItem2->
caption())
00091
return 1;
00092
00093
return 0;
00094 }
00095
00096
private:
00097
00098
00099
00100
00101 };
00102
00104
00105
class CardViewSeparator
00106 {
00107
friend class CardView;
00108
00109
public:
00110 CardViewSeparator(
CardView *view)
00111 : mView(view)
00112 {
00113 mRect =
QRect(0, 0, view->
separatorWidth(), 0);
00114 }
00115
00116 ~CardViewSeparator() {}
00117
00118
void paintSeparator(
QPainter *p,
QColorGroup &cg)
00119 {
00120 p->fillRect(0, 0, mRect.width(), mRect.height(),
00121 cg.brush(QColorGroup::Button));
00122 }
00123
00124
void repaintSeparator()
00125 {
00126 mView->repaintContents(mRect);
00127 }
00128
00129
private:
00130
CardView *mView;
00131
QRect mRect;
00132 };
00133
00134
00135
00136
00137
00138
class CardViewPrivate
00139 {
00140
public:
00141 CardViewPrivate()
00142 : mSelectionMode(
CardView::Multi ),
00143 mDrawCardBorder( true ),
00144 mDrawFieldLabels( true ),
00145 mDrawSeparators( true),
00146 mSepWidth( 2 ),
00147 mShowEmptyFields( false ),
00148 mLayoutDirty( true ),
00149 mLastClickOnItem( false ),
00150 mItemMargin( 0 ),
00151 mItemSpacing( 10 ),
00152 mItemWidth( 200 ),
00153 mMaxFieldLines( INT_MAX ),
00154 mCurrentItem( 0L ),
00155 mLastClickPos(
QPoint(0, 0) ),
00156 mRubberBandAnchor( 0 ),
00157 mCompText(
QString::null )
00158 {};
00159
00160 CardViewItemList mItemList;
00161
QPtrList<CardViewSeparator> mSeparatorList;
00162
QFontMetrics *mFm;
00163
QFontMetrics *mBFm;
00164
QFont mHeaderFont;
00165 CardView::SelectionMode mSelectionMode;
00166
bool mDrawCardBorder;
00167
bool mDrawFieldLabels;
00168
bool mDrawSeparators;
00169
int mSepWidth;
00170
bool mShowEmptyFields;
00171
bool mLayoutDirty;
00172
bool mLastClickOnItem;
00173 uint mItemMargin;
00174 uint mItemSpacing;
00175
int mItemWidth;
00176 uint mMaxFieldLines;
00177
CardViewItem *mCurrentItem;
00178
QPoint mLastClickPos;
00179
QTimer *mTimer;
00180 CardViewTip *mTip;
00181
bool mOnSeparator;
00182
00183
int mResizeAnchor;
00184
int mRubberBandAnchor;
00185
00186
00187
00188
int colspace;
00189 uint first;
00190
int firstX;
00191
int pressed;
00192
int span;
00193
00194
QString mCompText;
00195
QDateTime mCompUpdated;
00196 };
00197
00198
class CardViewItemPrivate
00199 {
00200
public:
00201 CardViewItemPrivate() {}
00202
00203
QString mCaption;
00204
QPtrList< CardViewItem::Field > mFieldList;
00205
bool mSelected;
00206
int x;
00207
int y;
00208
int maxLabelWidth;
00209
int hcache;
00210 };
00211
00212
00213
00214
00215 CardViewItem::CardViewItem(
CardView *parent,
QString caption)
00216 : d(new CardViewItemPrivate()), mView(parent)
00217 {
00218 d->mCaption = caption;
00219
00220 initialize();
00221 }
00222
00223 CardViewItem::~CardViewItem()
00224 {
00225
00226
if (mView != 0)
00227 mView->
takeItem(
this);
00228
00229
delete d;
00230 d = 0;
00231 }
00232
00233
void CardViewItem::initialize()
00234 {
00235 d->mSelected =
false;
00236 d->mFieldList.setAutoDelete(
true);
00237 d->maxLabelWidth = 0;
00238 d->hcache=0;
00239
00240
00241
00242
00243
if (mView != 0)
00244 mView->
insertItem(
this);
00245 }
00246
00247 void CardViewItem::paintCard(
QPainter *p,
QColorGroup &cg)
00248 {
00249
00250
if (!mView)
00251
return;
00252
00253
QPen pen;
00254
QBrush brush;
00255
QFontMetrics fm = *(mView->
d->mFm);
00256
QFontMetrics bFm = *(mView->
d->mBFm);
00257
bool drawLabels = mView->
d->mDrawFieldLabels;
00258
bool drawBorder = mView->
d->mDrawCardBorder;
00259
int mg = mView->
itemMargin();
00260
int w = mView->
itemWidth() - (mg*2);
00261
int h =
height() - (mg*2);
00262
const int colonWidth( fm.width(
":") );
00263
int labelXPos = 2 + mg;
00264
int labelWidth = QMIN( w/2 - 4 - mg, d->maxLabelWidth + colonWidth + 4 );
00265
int valueXPos = labelWidth + 4 + mg;
00266
int valueWidth = w - labelWidth - 4 - mg;
00267
00268 p->setFont( mView->font() );
00269 labelWidth -= colonWidth;
00270
00271
if (!drawLabels)
00272 {
00273 valueXPos = labelXPos;
00274 valueWidth = w - 4;
00275 }
00276
00277
00278
if (
isSelected())
00279 pen =
QPen(cg.highlight(), 1);
00280
else
00281 pen =
QPen(cg.button(), 1);
00282 p->setPen(pen);
00283
00284
00285
if (drawBorder)
00286 p->drawRect( mg, mg, w, h );
00287
00288
00289
if (
isSelected())
00290 brush = cg.brush(QColorGroup::Highlight);
00291
else
00292 brush = cg.brush(QColorGroup::Button);
00293
00294 p->fillRect(mg, mg, w, 4 + bFm.height(), brush);
00295
00296
00297 p->save();
00298
QFont bFont = mView->
headerFont();
00299
00300 p->setFont(bFont);
00301
if (
isSelected())
00302 p->setPen(cg.highlightedText());
00303
else
00304 p->setPen(cg.buttonText());
00305 p->drawText(2+mg, 2+mg + bFm.ascent(), trimString(d->mCaption, w-4, bFm));
00306 p->restore();
00307
00308
00309
QPtrListIterator< CardViewItem::Field > iter(d->mFieldList);
00310
QString label, value;
00311
int yPos = mg + 4 + bFm.height() + fm.height();
00312 p->setPen(cg.text());
00313
00314
int fh = fm.height();
00315
int cln( 0 );
00316
QString tmp;
00317
int maxLines = mView->
maxFieldLines();
00318
for (iter.toFirst(); iter.current(); ++iter)
00319 {
00320 value = (*iter)->second;
00321
if ( value.isEmpty() && ! mView->
d->mShowEmptyFields )
00322
continue;
00323
00324
if (drawLabels)
00325 {
00326 label = trimString((*iter)->first, labelWidth, fm);
00327 p->drawText(labelXPos, yPos, label +
":");
00328 }
00329
00330
for (cln=0; cln <= maxLines; cln++)
00331 {
00332 tmp = value.section(
'\n',cln,cln);
00333
if ( !tmp.isEmpty() ) p->drawText( valueXPos, yPos + cln*fh, trimString( tmp, valueWidth, fm ) );
00334
else break;
00335 }
00336
00337
if ( cln == 0 ) cln = 1;
00338 yPos += cln * fh + 2;
00339 }
00340
00341
00342
if ( mView->
currentItem() ==
this && mView->hasFocus() )
00343 {
00344 mView->style().drawPrimitive( QStyle::PE_FocusRect, p,
00345
QRect(0, 0, mView->
itemWidth(), h+(2*mg)), cg,
00346 QStyle::Style_FocusAtBorder,
00347
QStyleOption(
isSelected() ? cg.highlight() : cg.base() ) );
00348 }
00349 }
00350
00351 const QString &
CardViewItem::caption()
const
00352
{
00353
return d->mCaption;
00354 }
00355
00356
00357 int CardViewItem::height(
bool allowCache )
const
00358
{
00359
00360
if ( allowCache && d->hcache )
00361
return d->hcache;
00362
00363
00364
00365
00366
00367
00368
00369
int baseHeight = 8 + ( 2 * mView->
itemMargin() );
00370
00371
00372
00373
00374
00375
bool sef = mView->
showEmptyFields();
00376
int fh = mView->
d->mFm->height();
00377
00378
int fieldHeight = 0;
00379
int lines;
00380
int maxLines( mView->
maxFieldLines() );
00381
QPtrListIterator< CardViewItem::Field > iter(d->mFieldList);
00382
for (iter.toFirst(); iter.current(); ++iter)
00383 {
00384
if ( !sef && (*iter)->second.isEmpty() )
00385
continue;
00386 lines = QMIN( (*iter)->second.contains(
'\n') + 1, maxLines );
00387 fieldHeight += ( lines * fh ) + 2;
00388 }
00389
00390
00391 fieldHeight += mView->
d->mBFm->height();
00392 d->hcache = baseHeight + fieldHeight;
00393
return d->hcache;
00394 }
00395
00396 bool CardViewItem::isSelected()
const
00397
{
00398
return d->mSelected;
00399 }
00400
00401 void CardViewItem::setSelected(
bool selected)
00402 {
00403 d->mSelected = selected;
00404 }
00405
00406 void CardViewItem::insertField(
const QString &label,
const QString &value)
00407 {
00408
CardViewItem::Field *f =
new CardViewItem::Field(label, value);
00409 d->mFieldList.append(f);
00410 d->hcache=0;
00411
00412
if (mView)
00413 {
00414 mView->
setLayoutDirty(
true);
00415 d->maxLabelWidth = QMAX( mView->
d->mFm->width( label ), d->maxLabelWidth );
00416 }
00417 }
00418
00419 void CardViewItem::removeField(
const QString &label)
00420 {
00421
CardViewItem::Field *f;
00422
00423
QPtrListIterator< CardViewItem::Field > iter(d->mFieldList);
00424
for (iter.toFirst(); iter.current(); ++iter)
00425 {
00426 f = *iter;
00427
if (f->first == label)
00428
break;
00429 }
00430
00431
if (*iter)
00432 d->mFieldList.remove(*iter);
00433 d->hcache = 0;
00434
00435
if (mView)
00436 mView->
setLayoutDirty(
true);
00437 }
00438
00439 void CardViewItem::clearFields()
00440 {
00441 d->mFieldList.clear();
00442 d->hcache = 0;
00443
00444
if (mView)
00445 mView->
setLayoutDirty(
true);
00446 }
00447
00448
QString CardViewItem::trimString(
const QString &text,
int width,
00449
QFontMetrics &fm)
00450 {
00451
if (fm.width(text) <= width)
00452
return text;
00453
00454
QString dots =
"...";
00455
int dotWidth = fm.width(dots);
00456
QString trimmed;
00457
int charNum = 0;
00458
00459
while (fm.width(trimmed) + dotWidth < width)
00460 {
00461 trimmed += text[charNum];
00462 charNum++;
00463 }
00464
00465
00466 trimmed = trimmed.left(trimmed.length()-1);
00467 trimmed += dots;
00468
00469
return trimmed;
00470 }
00471
00472 CardViewItem *
CardViewItem::nextItem()
00473 {
00474
CardViewItem *item = 0;
00475
00476
if (mView)
00477 item = mView->
itemAfter(
this);
00478
00479
return item;
00480 }
00481
00482 void CardViewItem::repaintCard()
00483 {
00484
if (mView)
00485 mView->
repaintItem(
this);
00486 }
00487
00488 void CardViewItem::setCaption(
const QString &caption)
00489 {
00490 d->mCaption = caption;
00491
repaintCard();
00492 }
00493
00494 QString CardViewItem::fieldValue(
const QString &label)
00495 {
00496
QPtrListIterator< CardViewItem::Field > iter(d->mFieldList);
00497
for (iter.toFirst(); iter.current(); ++iter)
00498
if ((*iter)->first == label)
00499
return (*iter)->second;
00500
00501
return QString();
00502 }
00503
00504
00505 void CardViewItem::showFullString(
const QPoint &itempos, CardViewTip *tip )
00506 {
00507
bool trimmed(
false );
00508
QString s;
00509
int mrg = mView->
itemMargin();
00510
int y = mView->
d->mBFm->height() + 6 + mrg;
00511
int w = mView->
itemWidth() - (2*mrg);
00512
int lw;
00513
bool drawLabels = mView->
drawFieldLabels();
00514
bool isLabel = drawLabels && itempos.x() < w/2 ?
true :
false;
00515
00516
if ( itempos.y() < y )
00517 {
00518
if ( itempos.y() < 8 + mrg || itempos.y() > y - 4 )
00519
return;
00520
00521 s =
caption();
00522 trimmed = mView->
d->mBFm->width( s ) > w - 4;
00523 y = 2 + mrg;
00524 lw = 0;
00525 isLabel=
true;
00526 }
else {
00527
00528
Field *f =
fieldAt( itempos );
00529
if ( !f || ( !mView->
showEmptyFields() && f->second.isEmpty() ) )
00530
return;
00531
00532
00533
00534
00535
int maxLines = mView->
maxFieldLines();
00536
bool se = mView->
showEmptyFields();
00537
int fh = mView->
d->mFm->height();
00538
00539
Field *_f;
00540
for (_f = d->mFieldList.first(); _f != f; _f = d->mFieldList.next())
00541
if ( se || ! _f->second.isEmpty() )
00542 y += ( QMIN(_f->second.contains(
'\n')+1, maxLines) * fh ) + 2;
00543
00544
if ( isLabel && itempos.y() > y + fh )
00545
return;
00546
00547 s = isLabel ? f->first : f->second;
00548
00549
int colonWidth = mView->
d->mFm->width(
":");
00550 lw = drawLabels ?
00551 QMIN( w/2 - 4 - mrg, d->maxLabelWidth + colonWidth + 4 ) :
00552 0;
00553
int mw = isLabel ? lw - colonWidth : w - lw - (mrg*2);
00554
if ( isLabel )
00555 {
00556 trimmed = mView->
d->mFm->width( s ) > mw - colonWidth;
00557 }
else {
00558
QRect r( mView->
d->mFm->boundingRect( 0, 0, INT_MAX, INT_MAX, Qt::AlignTop|Qt::AlignLeft, s ) );
00559 trimmed = r.width() > mw || r.height()/fh > QMIN(s.contains(
'\n') + 1, maxLines);
00560 }
00561 }
00562
if ( trimmed )
00563 {
00564 tip->setFont( (isLabel && !lw) ? mView->
headerFont() : mView->font() );
00565 tip->setText( s );
00566 tip->adjustSize();
00567
00568
int lx;
00569 lx = isLabel || !drawLabels ? mrg : lw + mrg + 2 ;
00570
QPoint pnt(mView->contentsToViewport(
QPoint(d->x, d->y) ));
00571 pnt +=
QPoint(lx, y);
00572
if ( pnt.x() < 0 )
00573 pnt.setX( 0 );
00574
if ( pnt.x() + tip->width() > mView->visibleWidth() )
00575 pnt.setX( mView->visibleWidth() - tip->width() );
00576
if ( pnt.y() + tip->height() > mView->visibleHeight() )
00577 pnt.setY( QMAX( 0, mView->visibleHeight() - tip->height() ) );
00578
00579 tip->move( pnt );
00580 tip->show();
00581 }
00582 }
00583
00584 CardViewItem::Field *
CardViewItem::fieldAt(
const QPoint & itempos )
const
00585
{
00586
int ypos = mView->
d->mBFm->height() + 7 + mView->
d->mItemMargin;
00587
int iy = itempos.y();
00588
00589
if ( iy <= ypos )
00590
return 0;
00591
00592
bool showEmpty = mView->
showEmptyFields();
00593
int fh = mView->
d->mFm->height();
00594
int maxLines = mView->
maxFieldLines();
00595
Field *f;
00596
for ( f = d->mFieldList.first(); f; f = d->mFieldList.next() )
00597 {
00598
if ( showEmpty || !f->second.isEmpty() )
00599 ypos += ( QMIN( f->second.contains(
'\n')+1, maxLines ) *fh)+2;
00600
if ( iy <= ypos )
00601
break;
00602 }
00603
return f ? f : 0;
00604 }
00605
00606
00607
00608
00609 CardView::CardView(
QWidget *parent,
const char *name)
00610 :
QScrollView(parent, name),
00611 d(new CardViewPrivate())
00612 {
00613 d->mItemList.setAutoDelete(
true);
00614 d->mSeparatorList.setAutoDelete(
true);
00615
00616
QFont f = font();
00617 d->mFm =
new QFontMetrics(f);
00618 f.setBold(
true);
00619 d->mHeaderFont = f;
00620 d->mBFm =
new QFontMetrics(f);
00621 d->mTip = (
new CardViewTip( viewport() ) ),
00622 d->mTip->hide();
00623 d->mTimer = (
new QTimer(
this,
"mouseTimer") ),
00624
00625 viewport()->setMouseTracking(
true );
00626 viewport()->setFocusProxy(
this);
00627 viewport()->setFocusPolicy(WheelFocus);
00628 viewport()->setBackgroundMode(PaletteBase);
00629
00630 connect( d->mTimer, SIGNAL(timeout()),
this, SLOT(tryShowFullText()) );
00631
00632 setBackgroundMode(PaletteBackground, PaletteBase);
00633
00634
00635 setVScrollBarMode(AlwaysOff);
00636 }
00637
00638 CardView::~CardView()
00639 {
00640
delete d->mFm;
00641
delete d->mBFm;
00642
delete d;
00643 d = 0;
00644 }
00645
00646 void CardView::insertItem(
CardViewItem *item)
00647 {
00648 d->mItemList.inSort(item);
00649
setLayoutDirty(
true);
00650 }
00651
00652 void CardView::takeItem(
CardViewItem *item)
00653 {
00654
if ( d->mCurrentItem == item )
00655 d->mCurrentItem = item->
nextItem();
00656 d->mItemList.take(d->mItemList.findRef(item));
00657
00658
setLayoutDirty(
true);
00659 }
00660
00661 void CardView::clear()
00662 {
00663 d->mItemList.clear();
00664
00665
setLayoutDirty(
true);
00666 }
00667
00668 CardViewItem *
CardView::currentItem()
00669 {
00670
if ( ! d->mCurrentItem && d->mItemList.count() )
00671 d->mCurrentItem = d->mItemList.first();
00672
return d->mCurrentItem;
00673 }
00674
00675 void CardView::setCurrentItem(
CardViewItem *item )
00676 {
00677
if ( !item )
00678
return;
00679
else if ( item->
cardView() !=
this )
00680 {
00681 kdDebug(5720)<<
"CardView::setCurrentItem: Item ("<<item<<
") not owned! Backing out.."<<endl;
00682
return;
00683 }
00684
else if ( item ==
currentItem() )
00685 {
00686
return;
00687 }
00688
00689
if ( d->mSelectionMode == Single )
00690 {
00691
setSelected( item,
true );
00692 }
00693
else
00694 {
00695
CardViewItem *it = d->mCurrentItem;
00696 d->mCurrentItem = item;
00697
if ( it )
00698 it->
repaintCard();
00699 item->
repaintCard();
00700 }
00701
if ( ! d->mOnSeparator )
00702
ensureItemVisible( item );
00703 emit
currentChanged( item );
00704 }
00705
00706 CardViewItem *
CardView::itemAt(
const QPoint &viewPos)
00707 {
00708
CardViewItem *item = 0;
00709
QPtrListIterator<CardViewItem> iter(d->mItemList);
00710
bool found =
false;
00711
for (iter.toFirst(); iter.current() && !found; ++iter)
00712 {
00713 item = *iter;
00714
00715
if (
QRect(item->
d->x, item->
d->y, d->mItemWidth, item->
height()).contains(viewPos))
00716 found =
true;
00717 }
00718
00719
if (found)
00720
return item;
00721
00722
return 0;
00723 }
00724
00725 QRect CardView::itemRect(
const CardViewItem *item)
00726 {
00727
00728
return QRect(item->
d->x, item->
d->y, d->mItemWidth, item->
height());
00729 }
00730
00731 void CardView::ensureItemVisible(
const CardViewItem *item)
00732 {
00733 ensureVisible(item->
d->x , item->
d->y, d->mItemSpacing, 0);
00734 ensureVisible(item->
d->x + d->mItemWidth, item->
d->y, d->mItemSpacing, 0);
00735 }
00736
00737 void CardView::repaintItem(
const CardViewItem *item)
00738 {
00739
00740 repaintContents(
QRect(item->
d->x, item->
d->y, d->mItemWidth, item->
height()) );
00741 }
00742
00743 void CardView::setSelectionMode(CardView::SelectionMode mode)
00744 {
00745
selectAll(
false);
00746
00747 d->mSelectionMode = mode;
00748 }
00749
00750 CardView::SelectionMode
CardView::selectionMode()
const
00751
{
00752
return d->mSelectionMode;
00753 }
00754
00755 void CardView::selectAll(
bool state)
00756 {
00757
QPtrListIterator<CardViewItem> iter(d->mItemList);
00758
if (!state)
00759 {
00760
for (iter.toFirst(); iter.current(); ++iter)
00761 {
00762
if ((*iter)->isSelected())
00763 {
00764 (*iter)->setSelected(
false);
00765 (*iter)->repaintCard();
00766 }
00767 }
00768
00769 emit
selectionChanged(0);
00770 }
00771
else if (d->mSelectionMode != CardView::Single)
00772 {
00773
for (iter.toFirst(); iter.current(); ++iter)
00774 {
00775 (*iter)->setSelected(
true);
00776 }
00777
00778
if (d->mItemList.count() > 0)
00779 {
00780
00781 emit
selectionChanged();
00782
00783 viewport()->update();
00784 }
00785 }
00786 }
00787
00788 void CardView::setSelected(
CardViewItem *item,
bool selected)
00789 {
00790
if ((item == 0) || (item->
isSelected() == selected))
00791
return;
00792
00793
if ( selected && d->mCurrentItem != item )
00794 {
00795
CardViewItem *it = d->mCurrentItem;
00796 d->mCurrentItem = item;
00797
if ( it )
00798 it->
repaintCard();
00799 }
00800
00801
if (d->mSelectionMode == CardView::Single)
00802 {
00803
bool b = signalsBlocked();
00804 blockSignals(
true);
00805
selectAll(
false);
00806 blockSignals(b);
00807
00808
if (selected)
00809 {
00810 item->
setSelected(selected);
00811 item->
repaintCard();
00812 emit
selectionChanged();
00813 emit
selectionChanged(item);
00814 }
00815
else
00816 {
00817 emit
selectionChanged();
00818 emit
selectionChanged(0);
00819 }
00820 }
00821
else if (d->mSelectionMode == CardView::Multi)
00822 {
00823 item->
setSelected(selected);
00824 item->
repaintCard();
00825 emit
selectionChanged();
00826 }
00827
else if (d->mSelectionMode == CardView::Extended)
00828 {
00829
bool b = signalsBlocked();
00830 blockSignals(
true);
00831
selectAll(
false);
00832 blockSignals(b);
00833
00834 item->
setSelected(selected);
00835 item->
repaintCard();
00836 emit
selectionChanged();
00837 }
00838 }
00839
00840 bool CardView::isSelected(
CardViewItem *item)
const
00841
{
00842
return (item && item->
isSelected());
00843 }
00844
00845 CardViewItem *
CardView::selectedItem()
const
00846
{
00847
00848
QPtrListIterator<CardViewItem> iter(d->mItemList);
00849
for (iter.toFirst(); iter.current(); ++iter)
00850 {
00851
if ((*iter)->isSelected())
00852
return *iter;
00853 }
00854
00855
return 0;
00856 }
00857
00858 CardViewItem *
CardView::firstItem()
const
00859
{
00860
return d->mItemList.first();
00861 }
00862
00863 int CardView::childCount()
const
00864
{
00865
return d->mItemList.count();
00866 }
00867
00868 CardViewItem *
CardView::findItem(
const QString &text,
const QString &label,
00869 Qt::StringComparisonMode compare)
00870 {
00871
00872
00873
if (text.isEmpty())
00874
return 0;
00875
00876
QPtrListIterator<CardViewItem> iter(d->mItemList);
00877
if (compare & Qt::BeginsWith)
00878 {
00879
QString value;
00880
for (iter.toFirst(); iter.current(); ++iter)
00881 {
00882 value = (*iter)->fieldValue(label).upper();
00883
if (value.startsWith(text.upper()))
00884
return *iter;
00885 }
00886 }
00887
else
00888 {
00889 kdDebug(5720) <<
"CardView::findItem: search method not implemented" << endl;
00890 }
00891
00892
return 0;
00893 }
00894
00895 uint
CardView::columnWidth()
00896 {
00897
return d->mDrawSeparators ?
00898 d->mItemWidth + ( 2 * d->mItemSpacing ) + d->mSepWidth :
00899 d->mItemWidth + d->mItemSpacing;
00900 }
00901
00902 void CardView::drawContents(
QPainter *p,
int clipx,
int clipy,
00903
int clipw,
int cliph)
00904 {
00905 QScrollView::drawContents(p, clipx, clipy, clipw, cliph);
00906
00907
if (d->mLayoutDirty)
00908
calcLayout();
00909
00910
00911
00912
00913
QColorGroup cg = viewport()->palette().active();
00914
00915
QRect clipRect(clipx, clipy, clipw, cliph);
00916
QRect cardRect;
00917
QRect sepRect;
00918
CardViewItem *item;
00919 CardViewSeparator *sep;
00920
00921
00922 viewport()->erase(clipRect);
00923
00924
00925
QPtrListIterator<CardViewItem> iter(d->mItemList);
00926
for (iter.toFirst(); iter.current(); ++iter)
00927 {
00928 item = *iter;
00929 cardRect.setRect( item->
d->x, item->
d->y, d->mItemWidth, item->
height() );
00930
00931
if (clipRect.intersects(cardRect) || clipRect.contains(cardRect))
00932 {
00933
00934
00935
00936
00937 p->save();
00938 p->
translate(cardRect.x(), cardRect.y());
00939 item->
paintCard(p, cg);
00940 p->restore();
00941 }
00942 }
00943
00944
00945
QPtrListIterator<CardViewSeparator> sepIter(d->mSeparatorList);
00946
for (sepIter.toFirst(); sepIter.current(); ++sepIter)
00947 {
00948 sep = *sepIter;
00949 sepRect = sep->mRect;
00950
00951
if (clipRect.intersects(sepRect) || clipRect.contains(sepRect))
00952 {
00953 p->save();
00954 p->
translate(sepRect.x(), sepRect.y());
00955 sep->paintSeparator(p, cg);
00956 p->restore();
00957 }
00958 }
00959 }
00960
00961 void CardView::resizeEvent(
QResizeEvent *e)
00962 {
00963 QScrollView::resizeEvent(e);
00964
00965
setLayoutDirty(
true);
00966 }
00967
00968 void CardView::calcLayout()
00969 {
00970
00971
00972
00973
00974
int maxWidth = 0;
00975
int maxHeight = 0;
00976
int xPos = 0;
00977
int yPos = 0;
00978
int cardSpacing = d->mItemSpacing;
00979
00980
00981 d->mSeparatorList.clear();
00982
00983
QPtrListIterator<CardViewItem> iter(d->mItemList);
00984
CardViewItem *item = 0;
00985 CardViewSeparator *sep = 0;
00986 xPos += cardSpacing;
00987
00988
for (iter.toFirst(); iter.current(); ++iter)
00989 {
00990 item = *iter;
00991
00992 yPos += cardSpacing;
00993
00994
if (yPos + item->
height() + cardSpacing >= height() - horizontalScrollBar()->height())
00995 {
00996 maxHeight = QMAX(maxHeight, yPos);
00997
00998
00999
01000 yPos = cardSpacing;
01001 xPos += cardSpacing + maxWidth;
01002
if (d->mDrawSeparators)
01003 {
01004
01005 sep =
new CardViewSeparator(
this);
01006 sep->mRect.moveTopLeft(
QPoint(xPos, yPos+d->mItemMargin));
01007 xPos += d->mSepWidth + cardSpacing;
01008 d->mSeparatorList.append(sep);
01009 }
01010
01011 maxWidth = 0;
01012 }
01013
01014 item->
d->x = xPos;
01015 item->
d->y = yPos;
01016
01017 yPos += item->
height();
01018 maxWidth = QMAX(maxWidth, d->mItemWidth);
01019 }
01020
01021 xPos += maxWidth;
01022 resizeContents( xPos + cardSpacing, maxHeight );
01023
01024
01025
01026
QPtrListIterator<CardViewSeparator> sepIter(d->mSeparatorList);
01027
for (sepIter.toFirst(); sepIter.current(); ++sepIter)
01028 {
01029 (*sepIter)->mRect.setHeight(maxHeight - 2*cardSpacing - 2*d->mItemMargin);
01030 }
01031
01032 d->mLayoutDirty =
false;
01033 }
01034
01035 CardViewItem *
CardView::itemAfter(
CardViewItem *item)
01036 {
01037 d->mItemList.findRef(item);
01038
return d->mItemList.next();
01039 }
01040
01041 uint
CardView::itemMargin()
01042 {
01043
return d->mItemMargin;
01044 }
01045
01046 void CardView::setItemMargin( uint margin )
01047 {
01048
if ( margin == d->mItemMargin )
01049
return;
01050
01051 d->mItemMargin = margin;
01052
setLayoutDirty(
true );
01053 }
01054
01055 uint
CardView::itemSpacing()
01056 {
01057
return d->mItemSpacing;
01058 }
01059
01060 void CardView::setItemSpacing( uint spacing )
01061 {
01062
if ( spacing == d->mItemSpacing )
01063
return;
01064
01065 d->mItemSpacing = spacing;
01066
setLayoutDirty(
true );
01067 }
01068
01069
void CardView::contentsMousePressEvent(
QMouseEvent *e)
01070 {
01071 QScrollView::contentsMousePressEvent(e);
01072
01073
QPoint pos = e->pos();
01074 d->mLastClickPos = pos;
01075
01076
CardViewItem *item =
itemAt(pos);
01077
01078
if (item == 0)
01079 {
01080 d->mLastClickOnItem =
false;
01081
if ( d->mOnSeparator)
01082 {
01083 d->mResizeAnchor = e->x()+contentsX();
01084 d->colspace = (2*d->mItemSpacing) ;
01085
int ccw = d->mItemWidth + d->colspace + d->mSepWidth;
01086 d->first = (contentsX()+d->mSepWidth)/ccw;
01087 d->pressed = (d->mResizeAnchor+d->mSepWidth)/ccw;
01088 d->span = d->pressed - d->first;
01089 d->firstX = d->first * ccw;
01090
if ( d->firstX ) d->firstX -= d->mSepWidth;
01091 }
01092
else
01093 {
01094
selectAll(
false);
01095 }
01096
return;
01097 }
01098
01099 d->mLastClickOnItem =
true;
01100
01101
CardViewItem *other = d->mCurrentItem;
01102
setCurrentItem( item );
01103
01104
01105 emit
clicked(item);
01106
01107
01108
if ( e->button() & Qt::RightButton ) {
01109
01110
bool blocked = signalsBlocked();
01111 blockSignals(
true );
01112
selectAll(
false );
01113 blockSignals( blocked );
01114
01115
01116 item->
setSelected(
true );
01117
01118 emit
contextMenuRequested( item, mapToGlobal( e->pos() ) );
01119
return;
01120 }
01121
01122
01123
if (d->mSelectionMode == CardView::Single)
01124 {
01125
01126
if (item->
isSelected())
01127
return;
01128
01129
bool b = signalsBlocked();
01130 blockSignals(
true);
01131
selectAll(
false);
01132 blockSignals(b);
01133
01134 item->
setSelected(
true);
01135 item->
repaintCard();
01136 emit
selectionChanged(item);
01137 }
01138
01139
else if (d->mSelectionMode == CardView::Multi)
01140 {
01141
01142 item->
setSelected(!item->
isSelected());
01143 item->
repaintCard();
01144 emit
selectionChanged();
01145 }
01146
01147
else if (d->mSelectionMode == CardView::Extended)
01148 {
01149
if ((e->button() & Qt::LeftButton) &&
01150 (e->state() & Qt::ShiftButton))
01151 {
01152
if ( item == other )
return;
01153
01154
bool s = ! item->
isSelected();
01155
01156
if ( s && ! (e->state() & ControlButton) )
01157 {
01158
bool b = signalsBlocked();
01159 blockSignals(
true);
01160
selectAll(
false);
01161 blockSignals(b);
01162 }
01163
01164
int from, to, a, b;
01165 a = d->mItemList.findRef( item );
01166 b = d->mItemList.findRef( other );
01167 from = a < b ? a : b;
01168 to = a > b ? a : b;
01169
01170
CardViewItem *aItem;
01171
for ( ; from <= to; from++ )
01172 {
01173 aItem = d->mItemList.at( from );
01174 aItem->
setSelected( s );
01175
repaintItem( aItem );
01176 }
01177 emit
selectionChanged();
01178 }
01179
else if ((e->button() & Qt::LeftButton) &&
01180 (e->state() & Qt::ControlButton))
01181 {
01182 item->
setSelected(!item->
isSelected());
01183 item->
repaintCard();
01184 emit
selectionChanged();
01185 }
01186
01187
else if (e->button() & Qt::LeftButton)
01188 {
01189
bool b = signalsBlocked();
01190 blockSignals(
true);
01191
selectAll(
false);
01192 blockSignals(b);
01193
01194 item->
setSelected(
true);
01195 item->
repaintCard();
01196 emit
selectionChanged();
01197 }
01198 }
01199 }
01200
01201
void CardView::contentsMouseReleaseEvent(
QMouseEvent *e)
01202 {
01203 QScrollView::contentsMouseReleaseEvent(e);
01204
01205
if ( d->mResizeAnchor && d->span )
01206 {
01207
01208 unsetCursor();
01209
01210
int newiw = d->mItemWidth - ((d->mResizeAnchor - d->mRubberBandAnchor)/d->span);
01211 drawRubberBands( 0 );
01212
01213
if ( contentsX() )
01214 {
01215
int newX = QMAX( 0, ( d->pressed * ( newiw + d->colspace + d->mSepWidth ) ) - e->x() );
01216 setContentsPos( newX, contentsY() );
01217 }
01218
01219
setItemWidth( newiw );
01220
01221 d->mResizeAnchor = 0;
01222 d->mRubberBandAnchor = 0;
01223
return;
01224 }
01225
01226
01227
if ((e->state() & Qt::ShiftButton) || (e->state() & Qt::ControlButton))
01228
return;
01229
01230
01231
CardViewItem *item =
itemAt(e->pos());
01232
01233
if (item && KGlobalSettings::singleClick())
01234 {
01235 emit
executed(item);
01236 }
01237 }
01238
01239
void CardView::contentsMouseDoubleClickEvent(
QMouseEvent *e)
01240 {
01241 QScrollView::contentsMouseDoubleClickEvent(e);
01242
01243
CardViewItem *item =
itemAt(e->pos());
01244
01245
if (item)
01246 {
01247 d->mCurrentItem = item;
01248 }
01249
01250
if (item && !KGlobalSettings::singleClick())
01251 {
01252 emit
executed(item);
01253 }
01254 emit
doubleClicked(item);
01255 }
01256
01257
void CardView::contentsMouseMoveEvent(
QMouseEvent *e )
01258 {
01259
01260
if ( d->mResizeAnchor )
01261 {
01262
int x = e->x();
01263
if ( x != d->mRubberBandAnchor )
01264 drawRubberBands( x );
01265
return;
01266 }
01267
01268
if (d->mLastClickOnItem && (e->state() & Qt::LeftButton) &&
01269 ((e->pos() - d->mLastClickPos).manhattanLength() > 4)) {
01270
01271
startDrag();
01272
return;
01273 }
01274
01275 d->mTimer->start( 500 );
01276
01277
01278
01279
if ( d->mDrawSeparators )
01280 {
01281
int colcontentw = d->mItemWidth + (2*d->mItemSpacing);
01282
int colw = colcontentw + d->mSepWidth;
01283
int m = e->x()%colw;
01284
if ( m >= colcontentw && m > 0 )
01285 {
01286 setCursor( SplitHCursor );
01287 d->mOnSeparator =
true;
01288 }
01289
else
01290 {
01291 setCursor( ArrowCursor );
01292 d->mOnSeparator =
false;
01293 }
01294 }
01295 }
01296
01297
void CardView::enterEvent(
QEvent * )
01298 {
01299 d->mTimer->start( 500 );
01300 }
01301
01302
void CardView::leaveEvent(
QEvent * )
01303 {
01304 d->mTimer->stop();
01305
if (d->mOnSeparator)
01306 {
01307 d->mOnSeparator =
false;
01308 setCursor( ArrowCursor );
01309 }
01310 }
01311
01312
void CardView::focusInEvent(
QFocusEvent * )
01313 {
01314
if (!d->mCurrentItem && d->mItemList.count() )
01315 {
01316
setCurrentItem( d->mItemList.first() );
01317 }
01318
else if ( d->mCurrentItem )
01319 {
01320 d->mCurrentItem->repaintCard();
01321 }
01322 }
01323
01324
void CardView::focusOutEvent(
QFocusEvent * )
01325 {
01326
if (d->mCurrentItem)
01327 d->mCurrentItem->repaintCard();
01328 }
01329
01330
void CardView::keyPressEvent(
QKeyEvent *e )
01331 {
01332
if ( ! (
childCount() && d->mCurrentItem ) )
01333 {
01334 e->ignore();
01335
return;
01336 }
01337
01338 uint pos = d->mItemList.findRef( d->mCurrentItem );
01339
CardViewItem *aItem = 0L;
01340
CardViewItem *old = d->mCurrentItem;
01341
01342
switch ( e->key() )
01343 {
01344
case Key_Up:
01345
if ( pos > 0 )
01346 {
01347 aItem = d->mItemList.at( pos - 1 );
01348
setCurrentItem( aItem );
01349 }
01350
break;
01351
case Key_Down:
01352
if ( pos < d->mItemList.count() - 1 )
01353 {
01354 aItem = d->mItemList.at( pos + 1 );
01355
setCurrentItem( aItem );
01356 }
01357
break;
01358
case Key_Left:
01359 {
01360
01361
01362
01363
QPoint aPoint( d->mCurrentItem->d->x, d->mCurrentItem->d->y );
01364 aPoint -=
QPoint( 30,-(d->mCurrentItem->height()/2) );
01365 aItem =
itemAt( aPoint );
01366
01367
while ( !aItem && aPoint.y() > 27 )
01368 {
01369 aPoint -=
QPoint( 0, 16 );
01370 aItem =
itemAt( aPoint );
01371 }
01372
if ( aItem )
01373
setCurrentItem( aItem );
01374 }
01375
break;
01376
case Key_Right:
01377 {
01378
01379
QPoint aPoint( d->mCurrentItem->d->x + d->mItemWidth, d->mCurrentItem->d->y );
01380 aPoint +=
QPoint( 30,(d->mCurrentItem->height()/2) );
01381 aItem =
itemAt( aPoint );
01382
while ( !aItem && aPoint.y() > 27 )
01383 {
01384 aPoint -=
QPoint( 0, 16 );
01385 aItem =
itemAt( aPoint );
01386 }
01387
if ( aItem )
01388
setCurrentItem( aItem );
01389 }
01390
break;
01391
case Key_Home:
01392 aItem = d->mItemList.first();
01393
setCurrentItem( aItem );
01394
break;
01395
case Key_End:
01396 aItem = d->mItemList.last();
01397
setCurrentItem( aItem );
01398
break;
01399
case Key_Prior:
01400 {
01401
01402
01403
if ( contentsX() <= 0 )
01404
return;
01405
int cw =
columnWidth();
01406
int theCol = ( QMAX( 0, ( contentsX()/cw) * cw ) ) + d->mItemSpacing;
01407 aItem =
itemAt(
QPoint( theCol + 1, d->mItemSpacing + 1 ) );
01408
if ( aItem )
01409
setCurrentItem( aItem );
01410 }
01411
break;
01412
case Key_Next:
01413 {
01414
01415
01416
01417
01418
int cw =
columnWidth();
01419
int theCol = ( (( contentsX() + visibleWidth() )/cw) * cw ) + d->mItemSpacing + 1;
01420
01421
if ( d->mDrawSeparators && cw - (( contentsX() + visibleWidth() )%cw) <= int( d->mItemSpacing + d->mSepWidth ) )
01422 theCol += cw;
01423
01424
01425
while ( theCol > contentsWidth() )
01426 theCol -=
columnWidth();
01427
01428 aItem =
itemAt(
QPoint( theCol, d->mItemSpacing + 1 ) );
01429
01430
if ( aItem )
01431
setCurrentItem( aItem );
01432 }
01433
break;
01434
case Key_Space:
01435
setSelected( d->mCurrentItem, !d->mCurrentItem->isSelected() );
01436 emit
selectionChanged();
01437
break;
01438
case Key_Return:
01439
case Key_Enter:
01440 emit
returnPressed( d->mCurrentItem );
01441 emit
executed( d->mCurrentItem );
01442
break;
01443
case Key_Menu:
01444 emit
contextMenuRequested( d->mCurrentItem, viewport()->mapToGlobal(
01445
itemRect(d->mCurrentItem).center() ) );
01446
break;
01447
default:
01448
if ( (e->state() & ControlButton) && e->key() == Key_A )
01449 {
01450
01451
selectAll(
true );
01452
break;
01453 }
01454
01455
else if ( ! e->text().isEmpty() && e->text()[0].isPrint() )
01456 {
01457
01458 }
01459
break;
01460 }
01461
01462
if ( aItem )
01463 {
01464
if ( d->mSelectionMode == CardView::Extended )
01465 {
01466
if ( (e->state() & ShiftButton) )
01467 {
01468
01469
01470
01471
01472
bool s = ! aItem->
isSelected();
01473
int from, to, a, b;
01474 a = d->mItemList.findRef( aItem );
01475 b = d->mItemList.findRef( old );
01476 from = a < b ? a : b;
01477 to = a > b ? a : b;
01478
01479
if ( to - from > 1 )
01480 {
01481
bool b = signalsBlocked();
01482 blockSignals(
true);
01483
selectAll(
false);
01484 blockSignals(b);
01485 }
01486
01487
01488
CardViewItem *item;
01489
for ( ; from <= to; from++ )
01490 {
01491 item = d->mItemList.at( from );
01492 item->
setSelected( s );
01493
repaintItem( item );
01494 }
01495 emit
selectionChanged();
01496 }
01497
else if ( (e->state() & ControlButton) )
01498 {
01499
01500 }
01501
else
01502 {
01503
01504
bool b = signalsBlocked();
01505 blockSignals(
true);
01506
selectAll(
false);
01507 blockSignals(b);
01508
01509
setSelected( aItem,
true );
01510 emit
selectionChanged();
01511 }
01512 }
01513 }
01514 }
01515
01516 void CardView::contentsWheelEvent(
QWheelEvent * e )
01517 {
01518 scrollBy(2*e->delta()/-3, 0);
01519 }
01520
01521 void CardView::setLayoutDirty(
bool dirty)
01522 {
01523
if (d->mLayoutDirty != dirty)
01524 {
01525 d->mLayoutDirty = dirty;
01526 repaint();
01527 }
01528 }
01529
01530 void CardView::setDrawCardBorder(
bool enabled)
01531 {
01532
if (enabled != d->mDrawCardBorder)
01533 {
01534 d->mDrawCardBorder = enabled;
01535 repaint();
01536 }
01537 }
01538
01539 bool CardView::drawCardBorder()
const
01540
{
01541
return d->mDrawCardBorder;
01542 }
01543
01544 void CardView::setDrawColSeparators(
bool enabled)
01545 {
01546
if (enabled != d->mDrawSeparators)
01547 {
01548 d->mDrawSeparators = enabled;
01549
setLayoutDirty(
true);
01550 }
01551 }
01552
01553 bool CardView::drawColSeparators()
const
01554
{
01555
return d->mDrawSeparators;
01556 }
01557
01558 void CardView::setDrawFieldLabels(
bool enabled)
01559 {
01560
if (enabled != d->mDrawFieldLabels)
01561 {
01562 d->mDrawFieldLabels = enabled;
01563 repaint();
01564 }
01565 }
01566
01567 bool CardView::drawFieldLabels()
const
01568
{
01569
return d->mDrawFieldLabels;
01570 }
01571
01572 void CardView::setShowEmptyFields(
bool show)
01573 {
01574
if (show != d->mShowEmptyFields)
01575 {
01576 d->mShowEmptyFields = show;
01577
setLayoutDirty(
true);
01578 }
01579 }
01580
01581 bool CardView::showEmptyFields()
const
01582
{
01583
return d->mShowEmptyFields;
01584 }
01585
01586 void CardView::startDrag()
01587 {
01588
01589
01590 }
01591
void CardView::tryShowFullText()
01592 {
01593 d->mTimer->stop();
01594
01595
QPoint cpos = viewportToContents( viewport()->mapFromGlobal( QCursor::pos() ) );
01596
CardViewItem *item =
itemAt( cpos );
01597
if ( item )
01598 {
01599
01600
01601
01602
QPoint ipos = cpos -
itemRect( item ).topLeft();
01603 item->
showFullString( ipos, d->mTip );
01604 }
01605 }
01606
01607
void CardView::drawRubberBands(
int pos )
01608 {
01609
if ( pos && d &&
01610 (!d->span || ((pos-d->firstX)/d->span) - d->colspace - d->mSepWidth < MIN_ITEM_WIDTH) )
01611
return;
01612
01613
int tmpcw = (d->mRubberBandAnchor-d->firstX)/d->span;
01614
int x = d->firstX + tmpcw - d->mSepWidth - contentsX();
01615
int h = visibleHeight();
01616
01617
QPainter p( viewport() );
01618 p.setRasterOp( XorROP );
01619 p.setPen( gray );
01620 p.setBrush( gray );
01621 uint n = d->first;
01622
01623
if ( d->mRubberBandAnchor )
01624
do {
01625 p.drawRect( x, 0, 2, h );
01626 x += tmpcw;
01627 n++;
01628 }
while ( x < visibleWidth() && n < d->mSeparatorList.count() );
01629
01630
if ( ! pos )
return;
01631 tmpcw = (pos - d->firstX)/d->span;
01632 n = d->first;
01633 x = d->firstX + tmpcw - d->mSepWidth - contentsX();
01634
do {
01635 p.drawRect( x, 0, 2, h );
01636 x += tmpcw;
01637 n++;
01638 }
while ( x < visibleWidth() && n < d->mSeparatorList.count() );
01639 d->mRubberBandAnchor = pos;
01640 }
01641
01642
01643 int CardView::itemWidth()
const
01644
{
01645
return d->mItemWidth;
01646 }
01647
01648 void CardView::setItemWidth(
int w )
01649 {
01650
if ( w == d->mItemWidth )
01651
return;
01652
if ( w < MIN_ITEM_WIDTH )
01653 w = MIN_ITEM_WIDTH;
01654 d->mItemWidth = w;
01655
setLayoutDirty(
true );
01656 updateContents();
01657 }
01658
01659 void CardView::setHeaderFont(
const QFont &fnt )
01660 {
01661 d->mHeaderFont = fnt;
01662
delete d->mBFm;
01663 d->mBFm =
new QFontMetrics( fnt );
01664 }
01665
01666 QFont CardView::headerFont()
const
01667
{
01668
return d->mHeaderFont;
01669 }
01670
01671 void CardView::setFont(
const QFont &fnt )
01672 {
01673 QScrollView::setFont( fnt );
01674
delete d->mFm;
01675 d->mFm =
new QFontMetrics( fnt );
01676 }
01677
01678 int CardView::separatorWidth()
01679 {
01680
return d->mSepWidth;
01681 }
01682
01683 void CardView::setSeparatorWidth(
int width )
01684 {
01685 d->mSepWidth = width;
01686
setLayoutDirty(
true );
01687 }
01688
01689 int CardView::maxFieldLines()
const
01690
{
01691
return d->mMaxFieldLines;
01692 }
01693
01694 void CardView::setMaxFieldLines(
int howmany )
01695 {
01696 d->mMaxFieldLines = howmany ? howmany : INT_MAX;
01697
01698 }
01699
01700
01701
#include "cardview.moc"