libkdenetwork Library API Documentation

kfoldertree.cpp

00001 // -*- c-basic-offset: 2 -*-
00002 
00003 #include "kfoldertree.h"
00004 #include <klocale.h>
00005 #include <kiconloader.h>
00006 #include <kdebug.h>
00007 #include <qpainter.h>
00008 #include <qapplication.h>
00009 #include <qheader.h>
00010 #include <qstyle.h>
00011 
00012 //-----------------------------------------------------------------------------
00013 KFolderTreeItem::KFolderTreeItem( KFolderTree *parent, const QString & label,
00014                   Protocol protocol, Type type )
00015   : KListViewItem( parent, label ), mProtocol( protocol ), mType( type ),
00016     mUnread(-1), mTotal(0)
00017 {
00018 }
00019 
00020 //-----------------------------------------------------------------------------
00021 KFolderTreeItem::KFolderTreeItem( KFolderTreeItem *parent,
00022                   const QString & label, Protocol protocol, Type type,
00023           int unread, int total )
00024     : KListViewItem( parent, label ), mProtocol( protocol ), mType( type ),
00025       mUnread( unread ), mTotal( total )
00026 {
00027 }
00028 
00029 //-----------------------------------------------------------------------------
00030 int KFolderTreeItem::protocolSortingKey() const
00031 {
00032   // protocol dependant sorting order:
00033   // local < imap < news < search < other
00034   switch ( mProtocol ) {
00035   case Local:
00036     return 1;
00037   case CachedImap:
00038   case Imap:
00039     return 2;
00040   case News:
00041     return 3;
00042   case Search:
00043     return 4;
00044   default:
00045     return 42;
00046   }
00047 }
00048 
00049 //-----------------------------------------------------------------------------
00050 int KFolderTreeItem::typeSortingKey() const
00051 {
00052   // type dependant sorting order:
00053   // inbox < outbox < sent-mail < trash < drafts
00054   // < calendar < contacts < notes < tasks
00055   // < normal folders
00056   switch ( mType ) {
00057   case Inbox:
00058     return 1;
00059   case Outbox:
00060     return 2;
00061   case SentMail:
00062     return 3;
00063   case Trash:
00064     return 4;
00065   case Drafts:
00066     return 5;
00067   case Calendar:
00068     return 6;
00069   case Contacts:
00070     return 7;
00071   case Notes:
00072     return 8;
00073   case Tasks:
00074     return 9;
00075   default:
00076     return 42;
00077   }
00078 }
00079 
00080 //-----------------------------------------------------------------------------
00081 int KFolderTreeItem::compare( QListViewItem * i, int col, bool ) const
00082 {
00083   KFolderTreeItem* other = static_cast<KFolderTreeItem*>( i );
00084 
00085   if (col == 0)
00086   {
00087     // sort by folder
00088 
00089     // local root-folder
00090     if ( depth() == 0 && mProtocol == NONE )
00091       return -1;
00092     if ( other->depth() == 0 && other->protocol() == NONE )
00093       return 1;
00094 
00095     // first compare by protocol
00096     int thisKey = protocolSortingKey();
00097     int thatKey = other->protocolSortingKey();
00098     if ( thisKey < thatKey )
00099       return -1;
00100     if ( thisKey > thatKey )
00101       return 1;
00102 
00103     // then compare by type
00104     thisKey = typeSortingKey();
00105     thatKey = other->typeSortingKey();
00106     if ( thisKey < thatKey )
00107       return -1;
00108     if ( thisKey > thatKey )
00109       return 1;
00110 
00111     // and finally compare by name
00112     return text( 0 ).localeAwareCompare( other->text( 0 ) );
00113   }
00114   else
00115   {
00116     // sort by unread or total-column
00117     int a = 0, b = 0;
00118     if (col == static_cast<KFolderTree*>(listView())->unreadIndex())
00119     {
00120       a = mUnread;
00121       b = other->unreadCount();
00122     }
00123     else if (col == static_cast<KFolderTree*>(listView())->totalIndex())
00124     {
00125       a = mTotal;
00126       b = other->totalCount();
00127     }
00128 
00129     if ( a == b )
00130       return 0;
00131     else
00132       return (a < b ? -1 : 1);
00133   }
00134 }
00135 
00136 //-----------------------------------------------------------------------------
00137 void KFolderTreeItem::setUnreadCount( int aUnread )
00138 {
00139   if ( aUnread < 0 ) return;
00140 
00141   mUnread = aUnread;
00142 
00143   QString unread = QString::null;
00144   if (mUnread == 0)
00145     unread = "- ";
00146   else {
00147     unread.setNum(mUnread);
00148     unread += " ";
00149   }
00150 
00151   setText( static_cast<KFolderTree*>(listView())->unreadIndex(),
00152       unread );
00153 }
00154 
00155 //-----------------------------------------------------------------------------
00156 void KFolderTreeItem::setTotalCount( int aTotal )
00157 {
00158   if ( aTotal < 0 ) return;
00159 
00160   mTotal = aTotal;
00161 
00162   QString total = QString::null;
00163   if (mTotal == 0)
00164     total = "- ";
00165   else {
00166     total.setNum(mTotal);
00167     total += " ";
00168   }
00169 
00170   setText( static_cast<KFolderTree*>(listView())->totalIndex(),
00171       total );
00172 }
00173 
00174 //-----------------------------------------------------------------------------
00175 int KFolderTreeItem::countUnreadRecursive()
00176 {
00177   int count = (mUnread > 0) ? mUnread : 0;
00178 
00179   for ( QListViewItem *item = firstChild() ;
00180       item ; item = item->nextSibling() )
00181   {
00182     count += static_cast<KFolderTreeItem*>(item)->countUnreadRecursive();
00183   }
00184 
00185   return count;
00186 }
00187 
00188 //-----------------------------------------------------------------------------
00189 void KFolderTreeItem::paintCell( QPainter * p, const QColorGroup & cg,
00190                                   int column, int width, int align )
00191 {
00192   KFolderTree *ft = static_cast<KFolderTree*>(listView());
00193 
00194   const int unreadRecursiveCount = countUnreadRecursive();
00195   const int unreadCount = ( mUnread > 0 ) ? mUnread : 0;
00196 
00197   /* The below is exceedingly silly, but Ingo insists that the unread
00198    * count that is shown in parenthesis after the folder name must
00199    * be configurable in color. That means that paintCell needs to do
00200    * two painting passes which flickers. Since that flicker is not
00201    * needed when there is the unread column, special case that. */
00202   if ( ft->isUnreadActive() ) {
00203     if ( (column == 0 || column == ft->unreadIndex())
00204           && ( unreadCount > 0 || ( !isOpen() && unreadRecursiveCount > 0 ) ) )
00205     {
00206       QFont f = p->font();
00207       f.setWeight(QFont::Bold);
00208       p->setFont(f);
00209     }
00210     KListViewItem::paintCell( p, cg, column, width, align );
00211   } else {
00212     QListView *lv = listView();
00213     QString oldText = text(column);
00214 
00215     // set an empty text so that we can have our own implementation (see further down)
00216     // but still benefit from KListView::paintCell
00217     setText( column, "" );
00218 
00219     KListViewItem::paintCell( p, cg, column, width, align );
00220 
00221     int r = lv ? lv->itemMargin() : 1;
00222     const QPixmap *icon = pixmap( column );
00223     int marg = lv ? lv->itemMargin() : 1;
00224 
00225     QString t;
00226     QRect br;
00227     setText( column, oldText );
00228     if ( isSelected() )
00229       p->setPen( cg.highlightedText() );
00230     else
00231       p->setPen( ft->paintInfo().colFore );
00232 
00233     if ( icon ) {
00234       r += icon->width() + lv->itemMargin();
00235     }
00236     t = text( column );
00237     if ( !t.isEmpty() )
00238     {
00239       // use a bold-font for the folder- and the unread-columns
00240       if ( (column == 0 || column == ft->unreadIndex())
00241             && ( unreadCount > 0
00242                  || ( !isOpen() && unreadRecursiveCount > 0 ) ) )
00243       {
00244         QFont f = p->font();
00245         f.setWeight(QFont::Bold);
00246         p->setFont(f);
00247       }
00248       p->drawText( r, 0, width-marg-r, height(),
00249           align | AlignVCenter, t, -1, &br );
00250       if (!isSelected())
00251         p->setPen( ft->paintInfo().colUnread );
00252       if (column == 0) {
00253         // draw the unread-count if the unread-column is not active
00254         QString unread;
00255 
00256         if ( !ft->isUnreadActive()
00257              && ( unreadCount > 0
00258                   || ( !isOpen() && unreadRecursiveCount > 0 ) ) ) {
00259           if ( isOpen() )
00260             unread = " (" + QString::number( unreadCount ) + ")";
00261           else if ( unreadRecursiveCount == unreadCount || mType == Root )
00262             unread = " (" + QString::number( unreadRecursiveCount ) + ")";
00263           else
00264             unread = " (" + QString::number( unreadCount ) + " + " +
00265                      QString::number( unreadRecursiveCount-unreadCount ) + ")";
00266 
00267           p->drawText( br.right(), 0, width-marg-br.right(), height(),
00268                        align | AlignVCenter, unread );
00269         }
00270       }
00271     } // end !t.isEmpty()
00272   }
00273 }
00274 
00275 
00276 //=============================================================================
00277 
00278 
00279 KFolderTree::KFolderTree( QWidget *parent, const char* name )
00280   : KListView( parent, name ), mUnreadIndex(-1), mTotalIndex(-1)
00281 {
00282   // GUI-options
00283   setStyleDependantFrameWidth();
00284   setAcceptDrops(true);
00285   setDropVisualizer(false);
00286   setAllColumnsShowFocus(true);
00287   setShowSortIndicator(true);
00288   setUpdatesEnabled(true);
00289   setItemsRenameable(false);
00290   setRootIsDecorated(true);
00291   setSelectionModeExt(Extended);
00292   setAlternateBackground(QColor());
00293   setFullWidth(true);
00294   disableAutoSelection();
00295   setColumnWidth( 0, 120 ); //reasonable default size
00296 }
00297 
00298 //-----------------------------------------------------------------------------
00299 void KFolderTree::setStyleDependantFrameWidth()
00300 {
00301   // set the width of the frame to a reasonable value for the current GUI style
00302   int frameWidth;
00303   if( style().isA("KeramikStyle") )
00304     frameWidth = style().pixelMetric( QStyle::PM_DefaultFrameWidth ) - 1;
00305   else
00306     frameWidth = style().pixelMetric( QStyle::PM_DefaultFrameWidth );
00307   if ( frameWidth < 0 )
00308     frameWidth = 0;
00309   if ( frameWidth != lineWidth() )
00310     setLineWidth( frameWidth );
00311 }
00312 
00313 //-----------------------------------------------------------------------------
00314 void KFolderTree::styleChange( QStyle& oldStyle )
00315 {
00316   setStyleDependantFrameWidth();
00317   KListView::styleChange( oldStyle );
00318 }
00319 
00320 //-----------------------------------------------------------------------------
00321 void KFolderTree::drawContentsOffset( QPainter * p, int ox, int oy,
00322                                        int cx, int cy, int cw, int ch )
00323 {
00324   bool oldUpdatesEnabled = isUpdatesEnabled();
00325   setUpdatesEnabled(false);
00326   KListView::drawContentsOffset( p, ox, oy, cx, cy, cw, ch );
00327   setUpdatesEnabled(oldUpdatesEnabled);
00328 }
00329 
00330 //-----------------------------------------------------------------------------
00331 void KFolderTree::contentsMousePressEvent( QMouseEvent *e )
00332 {
00333     setSelectionModeExt(Single);
00334     KListView::contentsMousePressEvent(e);
00335 }
00336 
00337 //-----------------------------------------------------------------------------
00338 void KFolderTree::contentsMouseReleaseEvent( QMouseEvent *e )
00339 {
00340     KListView::contentsMouseReleaseEvent(e);
00341     setSelectionModeExt(Extended);
00342 }
00343 
00344 //-----------------------------------------------------------------------------
00345 void KFolderTree::addAcceptableDropMimetype( const char *mimeType, bool outsideOk )
00346 {
00347   int oldSize = mAcceptableDropMimetypes.size();
00348   mAcceptableDropMimetypes.resize(oldSize+1);
00349   mAcceptOutside.resize(oldSize+1);
00350 
00351   mAcceptableDropMimetypes.at(oldSize) =  mimeType;
00352   mAcceptOutside.setBit(oldSize, outsideOk);
00353 }
00354 
00355 //-----------------------------------------------------------------------------
00356 bool KFolderTree::acceptDrag( QDropEvent* event ) const
00357 {
00358   QListViewItem* item = itemAt(contentsToViewport(event->pos()));
00359 
00360   for (uint i = 0; i < mAcceptableDropMimetypes.size(); i++)
00361   {
00362     if (event->provides(mAcceptableDropMimetypes[i]))
00363     {
00364       if (item)
00365         return (static_cast<KFolderTreeItem*>(item))->acceptDrag(event);
00366       else
00367         return mAcceptOutside[i];
00368     }
00369   }
00370   return false;
00371 }
00372 
00373 //-----------------------------------------------------------------------------
00374 void KFolderTree::addUnreadColumn( const QString & name, int width )
00375 {
00376   mUnreadIndex = addColumn( name, width );
00377   setColumnAlignment( mUnreadIndex, qApp->reverseLayout() ? Qt::AlignLeft : Qt::AlignRight );
00378   header()->adjustHeaderSize();
00379 }
00380 
00381 //-----------------------------------------------------------------------------
00382 void KFolderTree::addTotalColumn( const QString & name, int width )
00383 {
00384   mTotalIndex = addColumn( name, width );
00385   setColumnAlignment( mTotalIndex, qApp->reverseLayout() ? Qt::AlignLeft : Qt::AlignRight );
00386   header()->adjustHeaderSize();
00387 }
00388 
00389 //-----------------------------------------------------------------------------
00390 void KFolderTree::removeUnreadColumn()
00391 {
00392   if ( !isUnreadActive() ) return;
00393   removeColumn( mUnreadIndex );
00394   if ( isTotalActive() && mTotalIndex > mUnreadIndex )
00395     mTotalIndex--;
00396   mUnreadIndex = -1;
00397   header()->adjustHeaderSize();
00398 }
00399 
00400 //-----------------------------------------------------------------------------
00401 void KFolderTree::removeTotalColumn()
00402 {
00403   if ( !isTotalActive() ) return;
00404   removeColumn( mTotalIndex );
00405   if ( isUnreadActive() && mTotalIndex < mUnreadIndex )
00406     mUnreadIndex--;
00407   mTotalIndex = -1;
00408   header()->adjustHeaderSize();
00409 }
00410 
00411 //-----------------------------------------------------------------------------
00412 void KFolderTree::setFullWidth( bool fullWidth )
00413 {
00414   if (fullWidth)
00415     header()->setStretchEnabled( true, 0 );
00416 }
00417 
00418 #include "kfoldertree.moc"
KDE Logo
This file is part of the documentation for libkdenetwork Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Dec 21 14:21:38 2007 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003