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