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 } 00296 00297 //----------------------------------------------------------------------------- 00298 void KFolderTree::setStyleDependantFrameWidth() 00299 { 00300 // set the width of the frame to a reasonable value for the current GUI style 00301 int frameWidth; 00302 if( style().isA("KeramikStyle") ) 00303 frameWidth = style().pixelMetric( QStyle::PM_DefaultFrameWidth ) - 1; 00304 else 00305 frameWidth = style().pixelMetric( QStyle::PM_DefaultFrameWidth ); 00306 if ( frameWidth < 0 ) 00307 frameWidth = 0; 00308 if ( frameWidth != lineWidth() ) 00309 setLineWidth( frameWidth ); 00310 } 00311 00312 //----------------------------------------------------------------------------- 00313 void KFolderTree::styleChange( QStyle& oldStyle ) 00314 { 00315 setStyleDependantFrameWidth(); 00316 KListView::styleChange( oldStyle ); 00317 } 00318 00319 //----------------------------------------------------------------------------- 00320 void KFolderTree::drawContentsOffset( QPainter * p, int ox, int oy, 00321 int cx, int cy, int cw, int ch ) 00322 { 00323 bool oldUpdatesEnabled = isUpdatesEnabled(); 00324 setUpdatesEnabled(false); 00325 KListView::drawContentsOffset( p, ox, oy, cx, cy, cw, ch ); 00326 setUpdatesEnabled(oldUpdatesEnabled); 00327 } 00328 00329 //----------------------------------------------------------------------------- 00330 void KFolderTree::contentsMousePressEvent( QMouseEvent *e ) 00331 { 00332 setSelectionModeExt(Single); 00333 KListView::contentsMousePressEvent(e); 00334 } 00335 00336 //----------------------------------------------------------------------------- 00337 void KFolderTree::contentsMouseReleaseEvent( QMouseEvent *e ) 00338 { 00339 KListView::contentsMouseReleaseEvent(e); 00340 setSelectionModeExt(Extended); 00341 } 00342 00343 //----------------------------------------------------------------------------- 00344 void KFolderTree::addAcceptableDropMimetype( const char *mimeType, bool outsideOk ) 00345 { 00346 int oldSize = mAcceptableDropMimetypes.size(); 00347 mAcceptableDropMimetypes.resize(oldSize+1); 00348 mAcceptOutside.resize(oldSize+1); 00349 00350 mAcceptableDropMimetypes.at(oldSize) = mimeType; 00351 mAcceptOutside.setBit(oldSize, outsideOk); 00352 } 00353 00354 //----------------------------------------------------------------------------- 00355 bool KFolderTree::acceptDrag( QDropEvent* event ) const 00356 { 00357 QListViewItem* item = itemAt(contentsToViewport(event->pos())); 00358 00359 for (uint i = 0; i < mAcceptableDropMimetypes.size(); i++) 00360 { 00361 if (event->provides(mAcceptableDropMimetypes[i])) 00362 { 00363 if (item) 00364 return (static_cast<KFolderTreeItem*>(item))->acceptDrag(event); 00365 else 00366 return mAcceptOutside[i]; 00367 } 00368 } 00369 return false; 00370 } 00371 00372 //----------------------------------------------------------------------------- 00373 void KFolderTree::addUnreadColumn( const QString & name, int width ) 00374 { 00375 mUnreadIndex = addColumn( name, width ); 00376 setColumnAlignment( mUnreadIndex, qApp->reverseLayout() ? Qt::AlignLeft : Qt::AlignRight ); 00377 header()->adjustHeaderSize(); 00378 } 00379 00380 //----------------------------------------------------------------------------- 00381 void KFolderTree::addTotalColumn( const QString & name, int width ) 00382 { 00383 mTotalIndex = addColumn( name, width ); 00384 setColumnAlignment( mTotalIndex, qApp->reverseLayout() ? Qt::AlignLeft : Qt::AlignRight ); 00385 header()->adjustHeaderSize(); 00386 } 00387 00388 //----------------------------------------------------------------------------- 00389 void KFolderTree::removeUnreadColumn() 00390 { 00391 if ( !isUnreadActive() ) return; 00392 removeColumn( mUnreadIndex ); 00393 if ( isTotalActive() && mTotalIndex > mUnreadIndex ) 00394 mTotalIndex--; 00395 mUnreadIndex = -1; 00396 header()->adjustHeaderSize(); 00397 } 00398 00399 //----------------------------------------------------------------------------- 00400 void KFolderTree::removeTotalColumn() 00401 { 00402 if ( !isTotalActive() ) return; 00403 removeColumn( mTotalIndex ); 00404 if ( isUnreadActive() && mTotalIndex < mUnreadIndex ) 00405 mUnreadIndex--; 00406 mTotalIndex = -1; 00407 header()->adjustHeaderSize(); 00408 } 00409 00410 //----------------------------------------------------------------------------- 00411 void KFolderTree::setFullWidth( bool fullWidth ) 00412 { 00413 if (fullWidth) 00414 header()->setStretchEnabled( true, 0 ); 00415 } 00416 00417 #include "kfoldertree.moc"
KDE Logo
This file is part of the documentation for libkdenetwork Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Oct 21 19:46:16 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003