kiconview.cpp
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 1999 Torben Weis <weis@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2 as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "config.h" 00020 00021 #include <qtimer.h> 00022 #include <qpainter.h> 00023 #include <qpixmapcache.h> 00024 #include <qcleanuphandler.h> 00025 00026 #include "kiconview.h" 00027 #include "kwordwrap.h" 00028 #include <kconfig.h> 00029 #include <kdebug.h> 00030 #include <kglobal.h> 00031 #include <kglobalsettings.h> 00032 #include <kapplication.h> 00033 #include <kipc.h> 00034 00035 #include <kcursor.h> 00036 #include <kpixmap.h> 00037 #include <kpixmapeffect.h> 00038 00039 class KIconView::KIconViewPrivate 00040 { 00041 public: 00042 KIconViewPrivate() { 00043 mode = KIconView::Execute; 00044 fm = 0L; 00045 doAutoSelect = true; 00046 textHeight = 0; 00047 dragHoldItem = 0L; 00048 } 00049 KIconView::Mode mode; 00050 bool doAutoSelect; 00051 QFontMetrics *fm; 00052 QPixmapCache maskCache; 00053 int textHeight; 00054 QIconViewItem *dragHoldItem; 00055 QTimer dragHoldTimer; 00056 QTimer doubleClickIgnoreTimer; 00057 }; 00058 00059 KIconView::KIconView( QWidget *parent, const char *name, WFlags f ) 00060 : QIconView( parent, name, f ) 00061 { 00062 d = new KIconViewPrivate; 00063 00064 connect( this, SIGNAL( onViewport() ), 00065 this, SLOT( slotOnViewport() ) ); 00066 connect( this, SIGNAL( onItem( QIconViewItem * ) ), 00067 this, SLOT( slotOnItem( QIconViewItem * ) ) ); 00068 slotSettingsChanged( KApplication::SETTINGS_MOUSE ); 00069 if ( kapp ) { // maybe null when used inside designer 00070 connect( kapp, SIGNAL( settingsChanged(int) ), SLOT( slotSettingsChanged(int) ) ); 00071 kapp->addKipcEventMask( KIPC::SettingsChanged ); 00072 } 00073 00074 m_pCurrentItem = 0L; 00075 00076 m_pAutoSelect = new QTimer( this ); 00077 connect( m_pAutoSelect, SIGNAL( timeout() ), 00078 this, SLOT( slotAutoSelect() ) ); 00079 00080 connect( &d->dragHoldTimer, SIGNAL(timeout()), this, SLOT(slotDragHoldTimeout()) ); 00081 } 00082 00083 KIconView::~KIconView() 00084 { 00085 delete d->fm; 00086 delete d; 00087 } 00088 00089 00090 void KIconView::setMode( KIconView::Mode mode ) 00091 { 00092 d->mode = mode; 00093 } 00094 00095 KIconView::Mode KIconView::mode() const 00096 { 00097 return d->mode; 00098 } 00099 00100 void KIconView::slotOnItem( QIconViewItem *item ) 00101 { 00102 if ( item ) { 00103 if ( m_bUseSingle ) { 00104 if ( m_bChangeCursorOverItem ) 00105 viewport()->setCursor( KCursor().handCursor() ); 00106 00107 if ( (m_autoSelectDelay > -1) ) { 00108 m_pAutoSelect->start( m_autoSelectDelay, true ); 00109 } 00110 } 00111 m_pCurrentItem = item; 00112 } 00113 } 00114 00115 void KIconView::slotOnViewport() 00116 { 00117 if ( m_bUseSingle && m_bChangeCursorOverItem ) 00118 viewport()->unsetCursor(); 00119 00120 m_pAutoSelect->stop(); 00121 m_pCurrentItem = 0L; 00122 } 00123 00124 void KIconView::slotSettingsChanged(int category) 00125 { 00126 if ( category != KApplication::SETTINGS_MOUSE ) 00127 return; 00128 m_bUseSingle = KGlobalSettings::singleClick(); 00129 //kdDebug() << "KIconView::slotSettingsChanged for mouse, usesingle=" << m_bUseSingle << endl; 00130 00131 disconnect( this, SIGNAL( mouseButtonClicked( int, QIconViewItem *, 00132 const QPoint & ) ), 00133 this, SLOT( slotMouseButtonClicked( int, QIconViewItem *, 00134 const QPoint & ) ) ); 00135 // disconnect( this, SIGNAL( doubleClicked( QIconViewItem *, 00136 // const QPoint & ) ), 00137 // this, SLOT( slotExecute( QIconViewItem *, 00138 // const QPoint & ) ) ); 00139 00140 if( m_bUseSingle ) { 00141 connect( this, SIGNAL( mouseButtonClicked( int, QIconViewItem *, 00142 const QPoint & ) ), 00143 this, SLOT( slotMouseButtonClicked( int, QIconViewItem *, 00144 const QPoint & ) ) ); 00145 } 00146 else { 00147 // connect( this, SIGNAL( doubleClicked( QIconViewItem *, 00148 // const QPoint & ) ), 00149 // this, SLOT( slotExecute( QIconViewItem *, 00150 // const QPoint & ) ) ); 00151 } 00152 00153 m_bChangeCursorOverItem = KGlobalSettings::changeCursorOverIcon(); 00154 m_autoSelectDelay = m_bUseSingle ? KGlobalSettings::autoSelectDelay() : -1; 00155 00156 if( !m_bUseSingle || !m_bChangeCursorOverItem ) 00157 viewport()->unsetCursor(); 00158 } 00159 00160 void KIconView::slotAutoSelect() 00161 { 00162 // check that the item still exists 00163 if( index( m_pCurrentItem ) == -1 || !d->doAutoSelect ) 00164 return; 00165 00166 //Give this widget the keyboard focus. 00167 if( !hasFocus() ) 00168 setFocus(); 00169 00170 ButtonState keybstate = KApplication::keyboardMouseState(); 00171 QIconViewItem* previousItem = currentItem(); 00172 setCurrentItem( m_pCurrentItem ); 00173 00174 if( m_pCurrentItem ) { 00175 //Shift pressed? 00176 if( (keybstate & ShiftButton) ) { 00177 //Temporary implementation of the selection until QIconView supports it 00178 bool block = signalsBlocked(); 00179 blockSignals( true ); 00180 00181 //No Ctrl? Then clear before! 00182 if( !(keybstate & ControlButton) ) 00183 clearSelection(); 00184 00185 bool select = !m_pCurrentItem->isSelected(); 00186 bool update = viewport()->isUpdatesEnabled(); 00187 viewport()->setUpdatesEnabled( false ); 00188 00189 //Calculate the smallest rectangle that contains the current Item 00190 //and the one that got the autoselect event 00191 QRect r; 00192 QRect redraw; 00193 if ( previousItem ) 00194 r = QRect( QMIN( previousItem->x(), m_pCurrentItem->x() ), 00195 QMIN( previousItem->y(), m_pCurrentItem->y() ), 00196 0, 0 ); 00197 else 00198 r = QRect( 0, 0, 0, 0 ); 00199 if ( previousItem->x() < m_pCurrentItem->x() ) 00200 r.setWidth( m_pCurrentItem->x() - previousItem->x() + m_pCurrentItem->width() ); 00201 else 00202 r.setWidth( previousItem->x() - m_pCurrentItem->x() + previousItem->width() ); 00203 if ( previousItem->y() < m_pCurrentItem->y() ) 00204 r.setHeight( m_pCurrentItem->y() - previousItem->y() + m_pCurrentItem->height() ); 00205 else 00206 r.setHeight( previousItem->y() - m_pCurrentItem->y() + previousItem->height() ); 00207 r = r.normalize(); 00208 00209 //Check for each item whether it is within the rectangle. 00210 //If yes, select it 00211 for( QIconViewItem* i = firstItem(); i; i = i->nextItem() ) { 00212 if( i->intersects( r ) ) { 00213 redraw = redraw.unite( i->rect() ); 00214 setSelected( i, select, true ); 00215 } 00216 } 00217 00218 blockSignals( block ); 00219 viewport()->setUpdatesEnabled( update ); 00220 repaintContents( redraw, false ); 00221 00222 emit selectionChanged(); 00223 00224 if( selectionMode() == QIconView::Single ) 00225 emit selectionChanged( m_pCurrentItem ); 00226 00227 //setSelected( m_pCurrentItem, true, (keybstate & ControlButton), (keybstate & ShiftButton) ); 00228 } 00229 else if( (keybstate & ControlButton) ) 00230 setSelected( m_pCurrentItem, !m_pCurrentItem->isSelected(), true ); 00231 else 00232 setSelected( m_pCurrentItem, true ); 00233 } 00234 else 00235 kdDebug() << "KIconView: That's not supposed to happen!!!!" << endl; 00236 } 00237 00238 void KIconView::emitExecute( QIconViewItem *item, const QPoint &pos ) 00239 { 00240 if ( d->mode != Execute ) 00241 { 00242 // kdDebug() << "KIconView::emitExecute : not in execute mode !" << endl; 00243 return; 00244 } 00245 00246 ButtonState keybstate = KApplication::keyboardMouseState(); 00247 00248 m_pAutoSelect->stop(); 00249 00250 //Donīt emit executed if in SC mode and Shift or Ctrl are pressed 00251 if( !( m_bUseSingle && ((keybstate & ShiftButton) || (keybstate & ControlButton)) ) ) { 00252 setSelected( item, false ); 00253 viewport()->unsetCursor(); 00254 emit executed( item ); 00255 emit executed( item, pos ); 00256 } 00257 } 00258 00259 void KIconView::updateDragHoldItem( QDropEvent *e ) 00260 { 00261 QIconViewItem *item = findItem( e->pos() ); 00262 00263 if ( d->dragHoldItem != item) 00264 { 00265 d->dragHoldItem = item; 00266 if( item ) 00267 { 00268 d->dragHoldTimer.start( 1000, true ); 00269 } 00270 else 00271 { 00272 d->dragHoldTimer.stop(); 00273 } 00274 } 00275 } 00276 00277 void KIconView::focusOutEvent( QFocusEvent *fe ) 00278 { 00279 m_pAutoSelect->stop(); 00280 00281 QIconView::focusOutEvent( fe ); 00282 } 00283 00284 void KIconView::leaveEvent( QEvent *e ) 00285 { 00286 m_pAutoSelect->stop(); 00287 00288 QIconView::leaveEvent( e ); 00289 } 00290 00291 void KIconView::contentsMousePressEvent( QMouseEvent *e ) 00292 { 00293 if( (selectionMode() == Extended) && (e->state() & ShiftButton) && !(e->state() & ControlButton) ) { 00294 bool block = signalsBlocked(); 00295 blockSignals( true ); 00296 00297 clearSelection(); 00298 00299 blockSignals( block ); 00300 } 00301 00302 QIconView::contentsMousePressEvent( e ); 00303 d->doAutoSelect = false; 00304 } 00305 00306 void KIconView::contentsMouseDoubleClickEvent ( QMouseEvent * e ) 00307 { 00308 QIconView::contentsMouseDoubleClickEvent( e ); 00309 00310 QIconViewItem* item = findItem( e->pos() ); 00311 00312 if( item ) { 00313 if( (e->button() == LeftButton) && !m_bUseSingle ) 00314 emitExecute( item, e->globalPos() ); 00315 00316 emit doubleClicked( item, e->globalPos() ); 00317 } 00318 d->doubleClickIgnoreTimer.start(0, true); 00319 } 00320 00321 void KIconView::slotMouseButtonClicked( int btn, QIconViewItem *item, const QPoint &pos ) 00322 { 00323 //kdDebug() << " KIconView::slotMouseButtonClicked() item=" << item << endl; 00324 if( d->doubleClickIgnoreTimer.isActive() ) 00325 return; // Ignore double click 00326 00327 if( (btn == LeftButton) && item ) 00328 emitExecute( item, pos ); 00329 } 00330 00331 void KIconView::contentsMouseReleaseEvent( QMouseEvent *e ) 00332 { 00333 d->doAutoSelect = true; 00334 QIconView::contentsMouseReleaseEvent( e ); 00335 } 00336 00337 void KIconView::contentsDragEnterEvent( QDragEnterEvent *e ) 00338 { 00339 updateDragHoldItem( e ); 00340 QIconView::contentsDragEnterEvent( e ); 00341 } 00342 00343 void KIconView::contentsDragLeaveEvent( QDragLeaveEvent *e ) 00344 { 00345 d->dragHoldTimer.stop(); 00346 d->dragHoldItem = 0L; 00347 QIconView::contentsDragLeaveEvent( e ); 00348 } 00349 00350 00351 void KIconView::contentsDragMoveEvent( QDragMoveEvent *e ) 00352 { 00353 updateDragHoldItem( e ); 00354 QIconView::contentsDragMoveEvent( e ); 00355 } 00356 00357 void KIconView::contentsDropEvent( QDropEvent* e ) 00358 { 00359 d->dragHoldTimer.stop(); 00360 QIconView::contentsDropEvent( e ); 00361 } 00362 00363 void KIconView::slotDragHoldTimeout() 00364 { 00365 QIconViewItem *tmp = d->dragHoldItem; 00366 d->dragHoldItem = 0L; 00367 00368 emit held( tmp ); 00369 } 00370 00371 void KIconView::takeItem( QIconViewItem * item ) 00372 { 00373 if ( item == d->dragHoldItem ) 00374 { 00375 d->dragHoldTimer.stop(); 00376 d->dragHoldItem = 0L; 00377 } 00378 00379 QIconView::takeItem( item ); 00380 } 00381 00382 void KIconView::cancelPendingHeldSignal() 00383 { 00384 d->dragHoldTimer.stop(); 00385 d->dragHoldItem = 0L; 00386 } 00387 00388 void KIconView::wheelEvent( QWheelEvent *e ) 00389 { 00390 if (horizontalScrollBar() && (arrangement() == QIconView::TopToBottom)) { 00391 QWheelEvent ce(e->pos(), e->delta(), e->state(), Qt::Horizontal); 00392 QApplication::sendEvent( horizontalScrollBar(), &ce); 00393 if (ce.isAccepted()) { 00394 e->accept(); 00395 return; 00396 } 00397 } 00398 QIconView::wheelEvent(e); 00399 } 00400 00401 void KIconView::setFont( const QFont &font ) 00402 { 00403 delete d->fm; 00404 d->fm = 0L; 00405 QIconView::setFont( font ); 00406 } 00407 00408 QFontMetrics *KIconView::itemFontMetrics() const 00409 { 00410 if (!d->fm) { 00411 // QIconView creates one too, but we can't access it 00412 d->fm = new QFontMetrics( font() ); 00413 } 00414 return d->fm; 00415 } 00416 00417 QPixmap KIconView::selectedIconPixmap( QPixmap *pix, const QColor &col ) const 00418 { 00419 QPixmap m; 00420 if ( d->maskCache.find( QString::number( pix->serialNumber() ), m ) ) 00421 return m; 00422 m = KPixmapEffect::selectedPixmap( KPixmap(*pix), col ); 00423 d->maskCache.insert( QString::number( pix->serialNumber() ), m ); 00424 return m; 00425 } 00426 00427 int KIconView::iconTextHeight() const 00428 { 00429 return d->textHeight > 0 ? d->textHeight : ( wordWrapIconText() ? 99 : 1 ); 00430 } 00431 00432 void KIconView::setIconTextHeight( int n ) 00433 { 00434 int oldHeight = iconTextHeight(); 00435 if ( n > 1 ) 00436 d->textHeight = n; 00437 else 00438 d->textHeight = 1; 00439 00440 // so that Qt still shows the tooltip when even a wrapped text is too long 00441 setWordWrapIconText( false ); 00442 00443 // update view if needed 00444 if ( iconTextHeight() != oldHeight ) 00445 setFont( font() ); // hack to recalc items 00446 } 00447 00449 00450 struct KIconViewItem::KIconViewItemPrivate 00451 { 00452 QSize m_pixmapSize; 00453 }; 00454 00455 void KIconViewItem::init() 00456 { 00457 m_wordWrap = 0L; 00458 d = 0L; 00459 calcRect(); 00460 } 00461 00462 KIconViewItem::~KIconViewItem() 00463 { 00464 delete m_wordWrap; 00465 delete d; 00466 } 00467 00468 void KIconViewItem::calcRect( const QString& text_ ) 00469 { 00470 Q_ASSERT( iconView() ); 00471 if ( !iconView() ) 00472 return; 00473 delete m_wordWrap; 00474 m_wordWrap = 0L; 00475 #ifndef NDEBUG // be faster for the end-user, such a bug will have been fixed before hand :) 00476 if ( !iconView()->inherits("KIconView") ) 00477 { 00478 kdWarning() << "KIconViewItem used in a " << iconView()->className() << " !!" << endl; 00479 return; 00480 } 00481 #endif 00482 //kdDebug() << "KIconViewItem::calcRect - " << text() << endl; 00483 KIconView *view = static_cast<KIconView *>(iconView()); 00484 QRect itemIconRect = pixmapRect(); 00485 QRect itemTextRect = textRect(); 00486 QRect itemRect = rect(); 00487 00488 int pw = 0; 00489 int ph = 0; 00490 00491 #ifndef QT_NO_PICTURE 00492 if ( picture() ) { 00493 QRect br = picture()->boundingRect(); 00494 pw = br.width() + 2; 00495 ph = br.height() + 2; 00496 } else 00497 #endif 00498 { 00499 // Qt uses unknown_icon if no pixmap. Let's see if we need that - I doubt it 00500 if (!pixmap()) 00501 return; 00502 pw = pixmap()->width() + 2; 00503 ph = pixmap()->height() + 2; 00504 } 00505 itemIconRect.setWidth( pw ); 00506 #if 1 // FIXME 00507 // There is a bug in Qt which prevents the item from being placed 00508 // properly when the pixmapRect is not at the top of the itemRect, so we 00509 // have to increase the height of the pixmapRect and leave it at the top 00510 // of the itemRect... 00511 if ( d && !d->m_pixmapSize.isNull() ) 00512 itemIconRect.setHeight( d->m_pixmapSize.height() + 2 ); 00513 else 00514 #endif 00515 itemIconRect.setHeight( ph ); 00516 00517 int tw = 0; 00518 if ( d && !d->m_pixmapSize.isNull() ) 00519 tw = view->maxItemWidth() - ( view->itemTextPos() == QIconView::Bottom ? 0 : 00520 d->m_pixmapSize.width() + 2 ); 00521 else 00522 tw = view->maxItemWidth() - ( view->itemTextPos() == QIconView::Bottom ? 0 : 00523 itemIconRect.width() ); 00524 00525 QFontMetrics *fm = view->itemFontMetrics(); 00526 QString t; 00527 QRect r; 00528 00529 // When is text_ set ? Doesn't look like it's ever set. 00530 t = text_.isEmpty() ? text() : text_; 00531 00532 // Max text height 00533 int nbLines = static_cast<KIconView*>( iconView() )->iconTextHeight(); 00534 int height = nbLines > 0 ? fm->height() * nbLines : 0xFFFFFFFF; 00535 00536 // Should not be higher than pixmap if text is alongside icons 00537 if ( view->itemTextPos() != QIconView::Bottom ) { 00538 if ( d && !d->m_pixmapSize.isNull() ) 00539 height = QMIN( d->m_pixmapSize.height() + 2, height ); 00540 else 00541 height = QMIN( itemIconRect.height(), height ); 00542 height = QMAX( height, fm->height() ); 00543 } 00544 00545 // Calculate the word-wrap 00546 QRect outerRect( 0, 0, tw - 6, height ); 00547 m_wordWrap = KWordWrap::formatText( *fm, outerRect, 0, t ); 00548 r = m_wordWrap->boundingRect(); 00549 00550 int realWidth = QMAX( QMIN( r.width() + 4, tw ), fm->width( "X" ) ); 00551 itemTextRect.setWidth( realWidth ); 00552 itemTextRect.setHeight( r.height() ); 00553 00554 int w = 0; int h = 0; int y = 0; 00555 if ( view->itemTextPos() == QIconView::Bottom ) { 00556 // If the pixmap size has been specified, use it 00557 if ( d && !d->m_pixmapSize.isNull() ) 00558 { 00559 w = QMAX( itemTextRect.width(), d->m_pixmapSize.width() + 2 ); 00560 h = itemTextRect.height() + d->m_pixmapSize.height() + 2 + 1; 00561 #if 0 // FIXME 00562 // Waiting for the qt bug to be solved, the pixmapRect must 00563 // stay on the top... 00564 y = d->m_pixmapSize.height() + 2 - itemIconRect.height(); 00565 #endif 00566 } 00567 else { 00568 w = QMAX( itemTextRect.width(), itemIconRect.width() ); 00569 h = itemTextRect.height() + itemIconRect.height() + 1; 00570 } 00571 00572 itemRect.setWidth( w ); 00573 itemRect.setHeight( h ); 00574 int width = QMAX( w, QApplication::globalStrut().width() ); // see QIconViewItem::width() 00575 int height = QMAX( h, QApplication::globalStrut().height() ); // see QIconViewItem::height() 00576 itemTextRect = QRect( ( width - itemTextRect.width() ) / 2, height - itemTextRect.height(), 00577 itemTextRect.width(), itemTextRect.height() ); 00578 itemIconRect = QRect( ( width - itemIconRect.width() ) / 2, y, 00579 itemIconRect.width(), itemIconRect.height() ); 00580 } else { 00581 // If the pixmap size has been specified, use it 00582 if ( d && !d->m_pixmapSize.isNull() ) 00583 { 00584 h = QMAX( itemTextRect.height(), d->m_pixmapSize.height() + 2 ); 00585 #if 0 // FIXME 00586 // Waiting for the qt bug to be solved, the pixmapRect must 00587 // stay on the top... 00588 y = ( d->m_pixmapSize.height() + 2 - itemIconRect.height() ) / 2; 00589 #endif 00590 } 00591 else 00592 h = QMAX( itemTextRect.height(), itemIconRect.height() ); 00593 w = itemTextRect.width() + itemIconRect.width() + 1; 00594 00595 itemRect.setWidth( w ); 00596 itemRect.setHeight( h ); 00597 int width = QMAX( w, QApplication::globalStrut().width() ); // see QIconViewItem::width() 00598 int height = QMAX( h, QApplication::globalStrut().height() ); // see QIconViewItem::height() 00599 00600 itemTextRect = QRect( width - itemTextRect.width(), ( height - itemTextRect.height() ) / 2, 00601 itemTextRect.width(), itemTextRect.height() ); 00602 if ( itemIconRect.height() > itemTextRect.height() ) // icon bigger than text -> center vertically 00603 itemIconRect = QRect( 0, ( height - itemIconRect.height() ) / 2, 00604 itemIconRect.width(), itemIconRect.height() ); 00605 else // icon smaller than text -> place in top or center with first line 00606 itemIconRect = QRect( 0, QMAX(( fm->height() - itemIconRect.height() ) / 2 + y, 0), 00607 itemIconRect.width(), itemIconRect.height() ); 00608 if ( ( itemIconRect.height() <= 20 ) && ( itemTextRect.height() < itemIconRect.height() ) ) 00609 { 00610 itemTextRect.setHeight( itemIconRect.height() - 2 ); 00611 itemTextRect.setY( itemIconRect.y() ); 00612 } 00613 } 00614 00615 if ( itemIconRect != pixmapRect() ) 00616 setPixmapRect( itemIconRect ); 00617 if ( itemTextRect != textRect() ) 00618 setTextRect( itemTextRect ); 00619 if ( itemRect != rect() ) 00620 setItemRect( itemRect ); 00621 00622 // Done by setPixmapRect, setTextRect and setItemRect ! [and useless if no rect changed] 00623 //view->updateItemContainer( this ); 00624 00625 } 00626 00627 void KIconViewItem::paintItem( QPainter *p, const QColorGroup &cg ) 00628 { 00629 QIconView* view = iconView(); 00630 Q_ASSERT( view ); 00631 if ( !view ) 00632 return; 00633 #ifndef NDEBUG // be faster for the end-user, such a bug will have been fixed before hand :) 00634 if ( !view->inherits("KIconView") ) 00635 { 00636 kdWarning() << "KIconViewItem used in a " << view->className() << " !!" << endl; 00637 return; 00638 } 00639 #endif 00640 00641 p->save(); 00642 00643 paintPixmap(p, cg); 00644 paintText(p, cg); 00645 00646 p->restore(); 00647 } 00648 00649 KWordWrap * KIconViewItem::wordWrap() 00650 { 00651 return m_wordWrap; 00652 } 00653 00654 void KIconViewItem::paintPixmap( QPainter *p, const QColorGroup &cg ) 00655 { 00656 KIconView *kview = static_cast<KIconView *>(iconView()); 00657 00658 #ifndef QT_NO_PICTURE 00659 if ( picture() ) { 00660 QPicture *pic = picture(); 00661 if ( isSelected() ) { 00662 // TODO something as nice as selectedIconPixmap if possible ;) 00663 p->fillRect( pixmapRect( false ), QBrush( cg.highlight(), QBrush::Dense4Pattern) ); 00664 } 00665 p->drawPicture( x()-pic->boundingRect().x(), y()-pic->boundingRect().y(), *pic ); 00666 } else 00667 #endif 00668 { 00669 int iconX = pixmapRect( false ).x(); 00670 int iconY = pixmapRect( false ).y(); 00671 00672 QPixmap *pix = pixmap(); 00673 if ( !pix || pix->isNull() ) 00674 return; 00675 00676 #if 1 // FIXME 00677 // Move the pixmap manually because the pixmapRect is at the 00678 // top of the itemRect 00679 // (won't be needed anymore in future versions of qt) 00680 if ( d && !d->m_pixmapSize.isNull() ) 00681 { 00682 int offset = 0; 00683 if ( kview->itemTextPos() == QIconView::Bottom ) 00684 offset = d->m_pixmapSize.height() - pix->height(); 00685 else 00686 offset = ( d->m_pixmapSize.height() - pix->height() ) / 2; 00687 if ( offset > 0 ) 00688 iconY += offset; 00689 } 00690 #endif 00691 if ( isSelected() ) { 00692 QPixmap selectedPix = kview->selectedIconPixmap( pix, cg.highlight() ); 00693 p->drawPixmap( iconX, iconY, selectedPix ); 00694 } else { 00695 p->drawPixmap( iconX, iconY, *pix ); 00696 } 00697 } 00698 } 00699 00700 void KIconViewItem::paintText( QPainter *p, const QColorGroup &cg ) 00701 { 00702 int textX = textRect( false ).x() + 2; 00703 int textY = textRect( false ).y(); 00704 00705 if ( isSelected() ) { 00706 p->fillRect( textRect( false ), cg.highlight() ); 00707 p->setPen( QPen( cg.highlightedText() ) ); 00708 } else { 00709 if ( iconView()->itemTextBackground() != NoBrush ) 00710 p->fillRect( textRect( false ), iconView()->itemTextBackground() ); 00711 p->setPen( cg.text() ); 00712 } 00713 00714 int align = iconView()->itemTextPos() == QIconView::Bottom ? AlignHCenter : AlignAuto; 00715 m_wordWrap->drawText( p, textX, textY, align | KWordWrap::Truncate ); 00716 } 00717 00718 QSize KIconViewItem::pixmapSize() const 00719 { 00720 return d ? d->m_pixmapSize : QSize( 0, 0 ); 00721 } 00722 00723 void KIconViewItem::setPixmapSize( const QSize& size ) 00724 { 00725 if ( !d ) 00726 d = new KIconViewItemPrivate; 00727 00728 d->m_pixmapSize = size; 00729 } 00730 00731 void KIconView::virtual_hook( int, void* ) 00732 { /*BASE::virtual_hook( id, data );*/ } 00733 00734 #include "kiconview.moc"