00001
00002
00003 #include "kfoldertree.h"
00004 #include <klocale.h>
00005 #include <kiconloader.h>
00006 #include <kdebug.h>
00007 #include <kstringhandler.h>
00008 #include <qpainter.h>
00009 #include <qapplication.h>
00010 #include <qheader.h>
00011 #include <qstyle.h>
00012
00013
00014 KFolderTreeItem::KFolderTreeItem( KFolderTree *parent, const QString & label,
00015 Protocol protocol, Type type )
00016 : KListViewItem( parent, label ), mProtocol( protocol ), mType( type ),
00017 mUnread(-1), mTotal(0)
00018 {
00019 }
00020
00021
00022 KFolderTreeItem::KFolderTreeItem( KFolderTreeItem *parent,
00023 const QString & label, Protocol protocol, Type type,
00024 int unread, int total )
00025 : KListViewItem( parent, label ), mProtocol( protocol ), mType( type ),
00026 mUnread( unread ), mTotal( total )
00027 {
00028 }
00029
00030
00031 int KFolderTreeItem::protocolSortingKey() const
00032 {
00033
00034
00035 switch ( mProtocol ) {
00036 case Local:
00037 return 1;
00038 case CachedImap:
00039 case Imap:
00040 return 2;
00041 case News:
00042 return 3;
00043 case Search:
00044 return 4;
00045 default:
00046 return 42;
00047 }
00048 }
00049
00050
00051 int KFolderTreeItem::typeSortingKey() const
00052 {
00053
00054
00055
00056
00057 switch ( mType ) {
00058 case Inbox:
00059 return 1;
00060 case Outbox:
00061 return 2;
00062 case SentMail:
00063 return 3;
00064 case Trash:
00065 return 4;
00066 case Drafts:
00067 return 5;
00068 case Calendar:
00069 return 6;
00070 case Contacts:
00071 return 7;
00072 case Notes:
00073 return 8;
00074 case Tasks:
00075 return 9;
00076 default:
00077 return 42;
00078 }
00079 }
00080
00081
00082 int KFolderTreeItem::compare( QListViewItem * i, int col, bool ) const
00083 {
00084 KFolderTreeItem* other = static_cast<KFolderTreeItem*>( i );
00085
00086 if (col == 0)
00087 {
00088
00089
00090
00091 if ( depth() == 0 && mProtocol == NONE )
00092 return -1;
00093 if ( other->depth() == 0 && other->protocol() == NONE )
00094 return 1;
00095
00096
00097 int thisKey = protocolSortingKey();
00098 int thatKey = other->protocolSortingKey();
00099 if ( thisKey < thatKey )
00100 return -1;
00101 if ( thisKey > thatKey )
00102 return 1;
00103
00104
00105 thisKey = typeSortingKey();
00106 thatKey = other->typeSortingKey();
00107 if ( thisKey < thatKey )
00108 return -1;
00109 if ( thisKey > thatKey )
00110 return 1;
00111
00112
00113 return text( 0 ).localeAwareCompare( other->text( 0 ) );
00114 }
00115 else
00116 {
00117
00118 int a = 0, b = 0;
00119 if (col == static_cast<KFolderTree*>(listView())->unreadIndex())
00120 {
00121 a = mUnread;
00122 b = other->unreadCount();
00123 }
00124 else if (col == static_cast<KFolderTree*>(listView())->totalIndex())
00125 {
00126 a = mTotal;
00127 b = other->totalCount();
00128 }
00129
00130 if ( a == b )
00131 return 0;
00132 else
00133 return (a < b ? -1 : 1);
00134 }
00135 }
00136
00137
00138 void KFolderTreeItem::setUnreadCount( int aUnread )
00139 {
00140 if ( aUnread < 0 ) return;
00141
00142 mUnread = aUnread;
00143
00144 QString unread = QString::null;
00145 if (mUnread == 0)
00146 unread = "- ";
00147 else {
00148 unread.setNum(mUnread);
00149 unread += " ";
00150 }
00151
00152 setText( static_cast<KFolderTree*>(listView())->unreadIndex(),
00153 unread );
00154 }
00155
00156
00157 void KFolderTreeItem::setTotalCount( int aTotal )
00158 {
00159 if ( aTotal < 0 ) return;
00160
00161 mTotal = aTotal;
00162
00163 QString total = QString::null;
00164 if (mTotal == 0)
00165 total = "- ";
00166 else {
00167 total.setNum(mTotal);
00168 total += " ";
00169 }
00170
00171 setText( static_cast<KFolderTree*>(listView())->totalIndex(),
00172 total );
00173 }
00174
00175
00176 int KFolderTreeItem::countUnreadRecursive()
00177 {
00178 int count = (mUnread > 0) ? mUnread : 0;
00179
00180 for ( QListViewItem *item = firstChild() ;
00181 item ; item = item->nextSibling() )
00182 {
00183 count += static_cast<KFolderTreeItem*>(item)->countUnreadRecursive();
00184 }
00185
00186 return count;
00187 }
00188
00189
00190 void KFolderTreeItem::paintCell( QPainter * p, const QColorGroup & cg,
00191 int column, int width, int align )
00192 {
00193 KFolderTree *ft = static_cast<KFolderTree*>(listView());
00194
00195 const int unreadRecursiveCount = countUnreadRecursive();
00196 const int unreadCount = ( mUnread > 0 ) ? mUnread : 0;
00197
00198
00199 if ( (column == 0 || column == ft->unreadIndex())
00200 && ( unreadCount > 0
00201 || ( !isOpen() && unreadRecursiveCount > 0 ) ) )
00202 {
00203 QFont f = p->font();
00204 f.setWeight(QFont::Bold);
00205 p->setFont(f);
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 if ( ft->isUnreadActive() || column != 0 ) {
00217 KListViewItem::paintCell( p, cg, column, width, align );
00218 } else {
00219 QListView *lv = listView();
00220 QString oldText = text(column);
00221
00222
00223
00224 setText( column, "" );
00225
00226 KListViewItem::paintCell( p, cg, column, width, align );
00227
00228 const QPixmap *icon = pixmap( column );
00229 int marg = lv ? lv->itemMargin() : 1;
00230 int r = marg;
00231
00232 QString t;
00233 QRect br;
00234 setText( column, oldText );
00235 if ( isSelected() )
00236 p->setPen( cg.highlightedText() );
00237 else
00238 p->setPen( ft->paintInfo().colFore );
00239
00240 if ( icon ) {
00241 r += icon->width() + marg;
00242 }
00243 t = text( column );
00244 if ( !t.isEmpty() )
00245 {
00246
00247 QString unread;
00248
00249 if ( unreadCount > 0 || ( !isOpen() && unreadRecursiveCount > 0 ) ) {
00250 if ( isOpen() )
00251 unread = " (" + QString::number( unreadCount ) + ")";
00252 else if ( unreadRecursiveCount == unreadCount || mType == Root )
00253 unread = " (" + QString::number( unreadRecursiveCount ) + ")";
00254 else
00255 unread = " (" + QString::number( unreadCount ) + " + " +
00256 QString::number( unreadRecursiveCount-unreadCount ) + ")";
00257 }
00258
00259
00260 QFontMetrics fm( p->fontMetrics() );
00261 int unreadWidth = fm.width( unread );
00262 if ( fm.width( t ) + marg + r + unreadWidth > width )
00263 t = squeezeFolderName( t, fm, width - marg - r - unreadWidth );
00264
00265 p->drawText( r, 0, width-marg-r, height(),
00266 align | AlignVCenter, t, -1, &br );
00267
00268 if ( !unread.isEmpty() ) {
00269 if (!isSelected())
00270 p->setPen( ft->paintInfo().colUnread );
00271 p->drawText( br.right(), 0, width-marg-br.right(), height(),
00272 align | AlignVCenter, unread );
00273 }
00274 }
00275 }
00276 }
00277
00278
00279 QString KFolderTreeItem::squeezeFolderName( const QString &text,
00280 const QFontMetrics &fm,
00281 uint width ) const
00282 {
00283 return KStringHandler::rPixelSqueeze( text, fm, width );
00284 }
00285
00286
00287
00288
00289
00290 KFolderTree::KFolderTree( QWidget *parent, const char* name )
00291 : KListView( parent, name ), mUnreadIndex(-1), mTotalIndex(-1)
00292 {
00293
00294 setStyleDependantFrameWidth();
00295 setAcceptDrops(true);
00296 setDropVisualizer(false);
00297 setAllColumnsShowFocus(true);
00298 setShowSortIndicator(true);
00299 setUpdatesEnabled(true);
00300 setItemsRenameable(false);
00301 setRootIsDecorated(true);
00302 setSelectionModeExt(Extended);
00303 setAlternateBackground(QColor());
00304 #if KDE_IS_VERSION( 3, 3, 90 )
00305 setShadeSortColumn ( false );
00306 #endif
00307 setFullWidth(true);
00308 disableAutoSelection();
00309
00310 disconnect( header(), SIGNAL( sizeChange( int, int, int ) ) );
00311 connect( header(), SIGNAL( sizeChange( int, int, int ) ),
00312 SLOT( slotSizeChanged( int, int, int ) ) );
00313 }
00314
00315
00316 void KFolderTree::setStyleDependantFrameWidth()
00317 {
00318
00319 int frameWidth;
00320 if( style().isA("KeramikStyle") )
00321 frameWidth = style().pixelMetric( QStyle::PM_DefaultFrameWidth ) - 1;
00322 else
00323 frameWidth = style().pixelMetric( QStyle::PM_DefaultFrameWidth );
00324 if ( frameWidth < 0 )
00325 frameWidth = 0;
00326 if ( frameWidth != lineWidth() )
00327 setLineWidth( frameWidth );
00328 }
00329
00330
00331 void KFolderTree::styleChange( QStyle& oldStyle )
00332 {
00333 setStyleDependantFrameWidth();
00334 KListView::styleChange( oldStyle );
00335 }
00336
00337
00338 void KFolderTree::drawContentsOffset( QPainter * p, int ox, int oy,
00339 int cx, int cy, int cw, int ch )
00340 {
00341 bool oldUpdatesEnabled = isUpdatesEnabled();
00342 setUpdatesEnabled(false);
00343 KListView::drawContentsOffset( p, ox, oy, cx, cy, cw, ch );
00344 setUpdatesEnabled(oldUpdatesEnabled);
00345 }
00346
00347
00348 void KFolderTree::contentsMousePressEvent( QMouseEvent *e )
00349 {
00350 setSelectionModeExt(Single);
00351 KListView::contentsMousePressEvent(e);
00352 }
00353
00354
00355 void KFolderTree::contentsMouseReleaseEvent( QMouseEvent *e )
00356 {
00357 KListView::contentsMouseReleaseEvent(e);
00358 setSelectionModeExt(Extended);
00359 }
00360
00361
00362 void KFolderTree::addAcceptableDropMimetype( const char *mimeType, bool outsideOk )
00363 {
00364 int oldSize = mAcceptableDropMimetypes.size();
00365 mAcceptableDropMimetypes.resize(oldSize+1);
00366 mAcceptOutside.resize(oldSize+1);
00367
00368 mAcceptableDropMimetypes.at(oldSize) = mimeType;
00369 mAcceptOutside.setBit(oldSize, outsideOk);
00370 }
00371
00372
00373 bool KFolderTree::acceptDrag( QDropEvent* event ) const
00374 {
00375 QListViewItem* item = itemAt(contentsToViewport(event->pos()));
00376
00377 for (uint i = 0; i < mAcceptableDropMimetypes.size(); i++)
00378 {
00379 if (event->provides(mAcceptableDropMimetypes[i]))
00380 {
00381 if (item)
00382 return (static_cast<KFolderTreeItem*>(item))->acceptDrag(event);
00383 else
00384 return mAcceptOutside[i];
00385 }
00386 }
00387 return false;
00388 }
00389
00390
00391 void KFolderTree::addUnreadColumn( const QString & name, int width )
00392 {
00393 mUnreadIndex = addColumn( name, width );
00394 setColumnAlignment( mUnreadIndex, qApp->reverseLayout() ? Qt::AlignLeft : Qt::AlignRight );
00395 header()->adjustHeaderSize();
00396 }
00397
00398
00399 void KFolderTree::addTotalColumn( const QString & name, int width )
00400 {
00401 mTotalIndex = addColumn( name, width );
00402 setColumnAlignment( mTotalIndex, qApp->reverseLayout() ? Qt::AlignLeft : Qt::AlignRight );
00403 header()->adjustHeaderSize();
00404 }
00405
00406
00407 void KFolderTree::removeUnreadColumn()
00408 {
00409 if ( !isUnreadActive() ) return;
00410 removeColumn( mUnreadIndex );
00411 if ( isTotalActive() && mTotalIndex > mUnreadIndex )
00412 mTotalIndex--;
00413 mUnreadIndex = -1;
00414 header()->adjustHeaderSize();
00415 }
00416
00417
00418 void KFolderTree::removeTotalColumn()
00419 {
00420 if ( !isTotalActive() ) return;
00421 removeColumn( mTotalIndex );
00422 if ( isUnreadActive() && mTotalIndex < mUnreadIndex )
00423 mUnreadIndex--;
00424 mTotalIndex = -1;
00425 header()->adjustHeaderSize();
00426 }
00427
00428
00429 void KFolderTree::setFullWidth( bool fullWidth )
00430 {
00431 if (fullWidth)
00432 header()->setStretchEnabled( true, 0 );
00433 }
00434
00435
00436 void KFolderTree::slotSizeChanged( int section, int, int newSize )
00437 {
00438 viewport()->repaint(
00439 header()->sectionPos(section), 0, newSize, visibleHeight(), false );
00440 }
00441
00442 #include "kfoldertree.moc"