00001
00002
00003 #include "kfoldertree.h"
00004 #include <tdelocale.h>
00005 #include <tdeio/global.h>
00006 #include <kiconloader.h>
00007 #include <kdebug.h>
00008 #include <kstringhandler.h>
00009 #include <tqpainter.h>
00010 #include <tqapplication.h>
00011 #include <tqheader.h>
00012 #include <tqstyle.h>
00013
00014
00015 KFolderTreeItem::KFolderTreeItem( KFolderTree *parent, const TQString & label,
00016 Protocol protocol, Type type )
00017 : TDEListViewItem( parent, label ), mProtocol( protocol ), mType( type ),
00018 mUnread(-1), mTotal(0), mSize(0), mFolderIsCloseToQuota( false )
00019 {
00020 }
00021
00022
00023 KFolderTreeItem::KFolderTreeItem( KFolderTreeItem *parent,
00024 const TQString & label, Protocol protocol, Type type,
00025 int unread, int total )
00026 : TDEListViewItem( parent, label ), mProtocol( protocol ), mType( type ),
00027 mUnread( unread ), mTotal( total ), mSize(0), mFolderIsCloseToQuota( false )
00028 {
00029 }
00030
00031
00032 int KFolderTreeItem::protocolSortingKey() const
00033 {
00034
00035
00036 switch ( mProtocol ) {
00037 case Local:
00038 return 1;
00039 case CachedImap:
00040 case Imap:
00041 return 2;
00042 case News:
00043 return 3;
00044 case Search:
00045 return 4;
00046 default:
00047 return 42;
00048 }
00049 }
00050
00051
00052 int KFolderTreeItem::typeSortingKey() const
00053 {
00054
00055
00056
00057
00058 switch ( mType ) {
00059 case Inbox:
00060 return 1;
00061 case Outbox:
00062 return 2;
00063 case SentMail:
00064 return 3;
00065 case Trash:
00066 return 4;
00067 case Drafts:
00068 return 5;
00069 case Templates:
00070 return 6;
00071 case Calendar:
00072 return 7;
00073 case Contacts:
00074 return 8;
00075 case Notes:
00076 return 9;
00077 case Tasks:
00078 return 10;
00079 default:
00080 return 42;
00081 }
00082 }
00083
00084
00085 int KFolderTreeItem::compare( TQListViewItem * i, int col, bool ) const
00086 {
00087 KFolderTreeItem* other = static_cast<KFolderTreeItem*>( i );
00088
00089 if (col == 0)
00090 {
00091
00092
00093
00094 if ( depth() == 0 && mProtocol == NONE )
00095 return -1;
00096 if ( other->depth() == 0 && other->protocol() == NONE )
00097 return 1;
00098
00099
00100 int thisKey = protocolSortingKey();
00101 int thatKey = other->protocolSortingKey();
00102 if ( thisKey < thatKey )
00103 return -1;
00104 if ( thisKey > thatKey )
00105 return 1;
00106
00107
00108 thisKey = typeSortingKey();
00109 thatKey = other->typeSortingKey();
00110 if ( thisKey < thatKey )
00111 return -1;
00112 if ( thisKey > thatKey )
00113 return 1;
00114
00115
00116 return text( 0 ).localeAwareCompare( other->text( 0 ) );
00117 }
00118 else
00119 {
00120
00121 TQ_INT64 a = 0, b = 0;
00122 if (col == static_cast<KFolderTree*>(listView())->unreadIndex())
00123 {
00124 a = mUnread;
00125 b = other->unreadCount();
00126 }
00127 else if (col == static_cast<KFolderTree*>(listView())->totalIndex())
00128 {
00129 a = mTotal;
00130 b = other->totalCount();
00131 }
00132 else if (col == static_cast<KFolderTree*>(listView())->sizeIndex())
00133 {
00134 a = mSize;
00135 b = other->folderSize();
00136 }
00137
00138 if ( a == b )
00139 return 0;
00140 else
00141 return (a < b ? -1 : 1);
00142 }
00143 }
00144
00145
00146 void KFolderTreeItem::setUnreadCount( int aUnread )
00147 {
00148 if ( aUnread < 0 ) return;
00149
00150 mUnread = aUnread;
00151
00152 TQString unread = TQString();
00153 if (mUnread == 0)
00154 unread = "- ";
00155 else {
00156 unread.setNum(mUnread);
00157 unread += " ";
00158 }
00159
00160 setText( static_cast<KFolderTree*>(listView())->unreadIndex(),
00161 unread );
00162 }
00163
00164
00165 void KFolderTreeItem::setTotalCount( int aTotal )
00166 {
00167 if ( aTotal < 0 ) return;
00168
00169 mTotal = aTotal;
00170
00171 TQString total = TQString();
00172 if (mTotal == 0)
00173 total = "- ";
00174 else {
00175 total.setNum(mTotal);
00176 total += " ";
00177 }
00178
00179 setText( static_cast<KFolderTree*>(listView())->totalIndex(),
00180 total );
00181 }
00182
00183
00184 void KFolderTreeItem::setFolderSize( TQ_INT64 aSize )
00185 {
00186 if ( aSize < 0 ) return;
00187
00188 mSize = aSize;
00189
00190 TQString size;
00191 if (mType != Root) {
00192 if (mSize == 0 && (childCount() == 0 || isOpen() ) )
00193 size = "- ";
00194 else
00195 size = TDEIO::convertSize(mSize);
00196 }
00197 if ( childCount() > 0 && !isOpen() ) {
00198 TQ_INT64 recursiveSize = recursiveFolderSize();
00199 if ( recursiveSize != mSize ) {
00200 if ( mType != Root )
00201 size += TQString::fromLatin1(" + %1").arg( TDEIO::convertSize( recursiveSize - mSize ) );
00202 else
00203 size = TDEIO::convertSize( recursiveSize );
00204 }
00205 }
00206 size += " ";
00207
00208 setText( static_cast<KFolderTree*>(listView())->sizeIndex(), size );
00209 }
00210
00211
00212 TQ_INT64 KFolderTreeItem::recursiveFolderSize() const
00213 {
00214 TQ_INT64 size = mSize;
00215
00216 for ( TQListViewItem *item = firstChild() ;
00217 item ; item = item->nextSibling() )
00218 {
00219 size += static_cast<KFolderTreeItem*>(item)->recursiveFolderSize();
00220 }
00221 return size;
00222 }
00223
00224
00225
00226
00227 int KFolderTreeItem::countUnreadRecursive()
00228 {
00229 int count = (mUnread > 0) ? mUnread : 0;
00230
00231 for ( TQListViewItem *item = firstChild() ;
00232 item ; item = item->nextSibling() )
00233 {
00234 count += static_cast<KFolderTreeItem*>(item)->countUnreadRecursive();
00235 }
00236
00237 return count;
00238 }
00239
00240
00241 void KFolderTreeItem::paintCell( TQPainter * p, const TQColorGroup & cg,
00242 int column, int width, int align )
00243 {
00244 KFolderTree *ft = static_cast<KFolderTree*>(listView());
00245
00246 const int unreadRecursiveCount = countUnreadRecursive();
00247 const int unreadCount = ( mUnread > 0 ) ? mUnread : 0;
00248
00249
00250
00251 TQColorGroup mycg = cg;
00252 if ( ( column == 0 || column == ft->sizeIndex() ) && folderIsCloseToQuota() )
00253 {
00254 mycg.setColor( TQColorGroup::Text, ft->paintInfo().colCloseToQuota );
00255 }
00256
00257
00258 if ( (column == 0 || column == ft->unreadIndex())
00259 && ( unreadCount > 0
00260 || ( !isOpen() && unreadRecursiveCount > 0 ) ) )
00261 {
00262 TQFont f = p->font();
00263 f.setWeight(TQFont::Bold);
00264 p->setFont(f);
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 if ( ft->isUnreadActive() || column != 0 ) {
00277 TDEListViewItem::paintCell( p, mycg, column, width, align );
00278 } else {
00279 TQListView *lv = listView();
00280 TQString oldText = text(column);
00281
00282
00283
00284 setText( column, "" );
00285
00286 TDEListViewItem::paintCell( p, mycg, column, width, align );
00287
00288 const TQPixmap *icon = pixmap( column );
00289 int marg = lv ? lv->itemMargin() : 1;
00290 int r = marg;
00291
00292 setText( column, oldText );
00293 if ( isSelected() )
00294 p->setPen( mycg.highlightedText() );
00295 else
00296 p->setPen( mycg.color( TQColorGroup::Text ) );
00297
00298 if ( icon ) {
00299 r += icon->width() + marg;
00300 }
00301 TQString t = text( column );
00302 if (t.isEmpty())
00303 return;
00304
00305
00306 TQString unread;
00307
00308 if ( unreadCount > 0 || ( !isOpen() && unreadRecursiveCount > 0 ) ) {
00309 if ( isOpen() )
00310 unread = " (" + TQString::number( unreadCount ) + ")";
00311 else if ( unreadRecursiveCount == unreadCount || mType == Root )
00312 unread = " (" + TQString::number( unreadRecursiveCount ) + ")";
00313 else
00314 unread = " (" + TQString::number( unreadCount ) + " + " +
00315 TQString::number( unreadRecursiveCount-unreadCount ) + ")";
00316 }
00317
00318
00319 TQFontMetrics fm( p->fontMetrics() );
00320 int unreadWidth = fm.width( unread );
00321 if ( fm.width( t ) + marg + r + unreadWidth > width )
00322 t = squeezeFolderName( t, fm, width - marg - r - unreadWidth );
00323
00324 TQRect br;
00325 p->drawText( r, 0, width-marg-r, height(),
00326 align | AlignVCenter, t, -1, &br );
00327
00328 if ( !unread.isEmpty() ) {
00329 if (!isSelected())
00330 p->setPen( ft->paintInfo().colUnread );
00331 p->drawText( br.right(), 0, width-marg-br.right(), height(),
00332 align | AlignVCenter, unread );
00333 }
00334 }
00335 }
00336
00337
00338 TQString KFolderTreeItem::squeezeFolderName( const TQString &text,
00339 const TQFontMetrics &fm,
00340 uint width ) const
00341 {
00342 return KStringHandler::rPixelSqueeze( text, fm, width );
00343 }
00344
00345 bool KFolderTreeItem::folderIsCloseToQuota() const
00346 {
00347 return mFolderIsCloseToQuota;
00348 }
00349
00350 void KFolderTreeItem::setFolderIsCloseToQuota( bool v )
00351 {
00352 if ( mFolderIsCloseToQuota != v) {
00353 mFolderIsCloseToQuota = v;
00354 repaint();
00355 }
00356 }
00357
00358
00359
00360
00361
00362 KFolderTree::KFolderTree( TQWidget *parent, const char* name )
00363 : TDEListView( parent, name ), mUnreadIndex(-1), mTotalIndex(-1), mSizeIndex(-1)
00364 {
00365
00366 setStyleDependantFrameWidth();
00367 setAcceptDrops(true);
00368 setDropVisualizer(false);
00369 setAllColumnsShowFocus(true);
00370 setShowSortIndicator(true);
00371 setUpdatesEnabled(true);
00372 setItemsRenameable(false);
00373 setRootIsDecorated(true);
00374 setSelectionModeExt(Extended);
00375 setAlternateBackground(TQColor());
00376 #if KDE_IS_VERSION( 3, 3, 90 )
00377 setShadeSortColumn ( false );
00378 #endif
00379 setFullWidth(true);
00380 disableAutoSelection();
00381 setColumnWidth( 0, 120 );
00382
00383 disconnect( header(), TQT_SIGNAL( sizeChange( int, int, int ) ) );
00384 connect( header(), TQT_SIGNAL( sizeChange( int, int, int ) ),
00385 TQT_SLOT( slotSizeChanged( int, int, int ) ) );
00386 }
00387
00388
00389 void KFolderTree::setStyleDependantFrameWidth()
00390 {
00391
00392 int frameWidth;
00393 if( style().isA("KeramikStyle") )
00394 frameWidth = style().pixelMetric( TQStyle::PM_DefaultFrameWidth ) - 1;
00395 else
00396 frameWidth = style().pixelMetric( TQStyle::PM_DefaultFrameWidth );
00397 if ( frameWidth < 0 )
00398 frameWidth = 0;
00399 if ( frameWidth != lineWidth() )
00400 setLineWidth( frameWidth );
00401 }
00402
00403
00404 void KFolderTree::styleChange( TQStyle& oldStyle )
00405 {
00406 setStyleDependantFrameWidth();
00407 TDEListView::styleChange( oldStyle );
00408 }
00409
00410
00411 void KFolderTree::drawContentsOffset( TQPainter * p, int ox, int oy,
00412 int cx, int cy, int cw, int ch )
00413 {
00414 bool oldUpdatesEnabled = isUpdatesEnabled();
00415 setUpdatesEnabled(false);
00416 TDEListView::drawContentsOffset( p, ox, oy, cx, cy, cw, ch );
00417 setUpdatesEnabled(oldUpdatesEnabled);
00418 }
00419
00420
00421 void KFolderTree::contentsMousePressEvent( TQMouseEvent *e )
00422 {
00423 setSelectionModeExt(Single);
00424 TDEListView::contentsMousePressEvent(e);
00425 }
00426
00427
00428 void KFolderTree::contentsMouseReleaseEvent( TQMouseEvent *e )
00429 {
00430 TDEListView::contentsMouseReleaseEvent(e);
00431 setSelectionModeExt(Extended);
00432 }
00433
00434
00435 void KFolderTree::addAcceptableDropMimetype( const char *mimeType, bool outsideOk )
00436 {
00437 int oldSize = mAcceptableDropMimetypes.size();
00438 mAcceptableDropMimetypes.resize(oldSize+1);
00439 mAcceptOutside.resize(oldSize+1);
00440
00441 mAcceptableDropMimetypes.at(oldSize) = mimeType;
00442 mAcceptOutside.setBit(oldSize, outsideOk);
00443 }
00444
00445
00446 bool KFolderTree::acceptDrag( TQDropEvent* event ) const
00447 {
00448 TQListViewItem* item = itemAt(contentsToViewport(event->pos()));
00449
00450 for (uint i = 0; i < mAcceptableDropMimetypes.size(); i++)
00451 {
00452 if (event->provides(mAcceptableDropMimetypes[i]))
00453 {
00454 if (item)
00455 return (static_cast<KFolderTreeItem*>(item))->acceptDrag(event);
00456 else
00457 return mAcceptOutside[i];
00458 }
00459 }
00460 return false;
00461 }
00462
00463
00464 void KFolderTree::addUnreadColumn( const TQString & name, int width )
00465 {
00466 mUnreadIndex = addColumn( name, width );
00467 setColumnAlignment( mUnreadIndex, tqApp->reverseLayout() ? TQt::AlignLeft : TQt::AlignRight );
00468 header()->adjustHeaderSize();
00469 }
00470
00471
00472 void KFolderTree::addTotalColumn( const TQString & name, int width )
00473 {
00474 mTotalIndex = addColumn( name, width );
00475 setColumnAlignment( mTotalIndex, tqApp->reverseLayout() ? TQt::AlignLeft : TQt::AlignRight );
00476 header()->adjustHeaderSize();
00477 }
00478
00479
00480 void KFolderTree::removeUnreadColumn()
00481 {
00482 if ( !isUnreadActive() ) return;
00483 removeColumn( mUnreadIndex );
00484 if ( isTotalActive() && mTotalIndex > mUnreadIndex )
00485 mTotalIndex--;
00486 if ( isSizeActive() && mSizeIndex > mUnreadIndex )
00487 mSizeIndex--;
00488
00489 mUnreadIndex = -1;
00490 header()->adjustHeaderSize();
00491 }
00492
00493
00494 void KFolderTree::removeTotalColumn()
00495 {
00496 if ( !isTotalActive() ) return;
00497 removeColumn( mTotalIndex );
00498 if ( isUnreadActive() && mTotalIndex < mUnreadIndex )
00499 mUnreadIndex--;
00500 if ( isSizeActive() && mTotalIndex < mSizeIndex )
00501 mSizeIndex--;
00502 mTotalIndex = -1;
00503 header()->adjustHeaderSize();
00504 }
00505
00506
00507 void KFolderTree::addSizeColumn( const TQString & name, int width )
00508 {
00509 mSizeIndex = addColumn( name, width );
00510 setColumnAlignment( mSizeIndex, tqApp->reverseLayout() ? TQt::AlignLeft : TQt::AlignRight );
00511 header()->adjustHeaderSize();
00512 }
00513
00514
00515 void KFolderTree::removeSizeColumn()
00516 {
00517 if ( !isSizeActive() ) return;
00518 removeColumn( mSizeIndex );
00519 if ( isUnreadActive() && mSizeIndex < mUnreadIndex )
00520 mUnreadIndex--;
00521 if ( isTotalActive() && mSizeIndex < mTotalIndex )
00522 mTotalIndex--;
00523 mSizeIndex = -1;
00524 header()->adjustHeaderSize();
00525 }
00526
00527
00528
00529 void KFolderTree::setFullWidth( bool fullWidth )
00530 {
00531 if (fullWidth)
00532 header()->setStretchEnabled( true, 0 );
00533 }
00534
00535
00536 void KFolderTree::slotSizeChanged( int section, int, int newSize )
00537 {
00538 viewport()->repaint(
00539 header()->sectionPos(section), 0, newSize, visibleHeight(), false );
00540 }
00541
00542 #include "kfoldertree.moc"