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 <tqtimer.h> 00022 #include <tqpainter.h> 00023 #include <tqpixmapcache.h> 00024 #include <tqcleanuphandler.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 TQFontMetrics *fm; 00052 TQPixmapCache maskCache; 00053 int textHeight; 00054 TQIconViewItem *dragHoldItem; 00055 TQTimer dragHoldTimer; 00056 TQTimer doubleClickIgnoreTimer; 00057 }; 00058 00059 KIconView::KIconView( TQWidget *parent, const char *name, WFlags f ) 00060 : TQIconView( parent, name, f ) 00061 { 00062 d = new KIconViewPrivate; 00063 00064 connect( this, TQT_SIGNAL( onViewport() ), 00065 this, TQT_SLOT( slotOnViewport() ) ); 00066 connect( this, TQT_SIGNAL( onItem( TQIconViewItem * ) ), 00067 this, TQT_SLOT( slotOnItem( TQIconViewItem * ) ) ); 00068 slotSettingsChanged( KApplication::SETTINGS_MOUSE ); 00069 if ( kapp ) { // maybe null when used inside designer 00070 connect( kapp, TQT_SIGNAL( settingsChanged(int) ), TQT_SLOT( slotSettingsChanged(int) ) ); 00071 kapp->addKipcEventMask( KIPC::SettingsChanged ); 00072 } 00073 00074 m_pCurrentItem = 0L; 00075 00076 m_pAutoSelect = new TQTimer( this ); 00077 connect( m_pAutoSelect, TQT_SIGNAL( timeout() ), 00078 this, TQT_SLOT( slotAutoSelect() ) ); 00079 00080 connect( &d->dragHoldTimer, TQT_SIGNAL(timeout()), this, TQT_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( TQIconViewItem *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, TQT_SIGNAL( mouseButtonClicked( int, TQIconViewItem *, 00132 const TQPoint & ) ), 00133 this, TQT_SLOT( slotMouseButtonClicked( int, TQIconViewItem *, 00134 const TQPoint & ) ) ); 00135 // disconnect( this, TQT_SIGNAL( doubleClicked( TQIconViewItem *, 00136 // const TQPoint & ) ), 00137 // this, TQT_SLOT( slotExecute( TQIconViewItem *, 00138 // const TQPoint & ) ) ); 00139 00140 if( m_bUseSingle ) { 00141 connect( this, TQT_SIGNAL( mouseButtonClicked( int, TQIconViewItem *, 00142 const TQPoint & ) ), 00143 this, TQT_SLOT( slotMouseButtonClicked( int, TQIconViewItem *, 00144 const TQPoint & ) ) ); 00145 } 00146 else { 00147 // connect( this, TQT_SIGNAL( doubleClicked( TQIconViewItem *, 00148 // const TQPoint & ) ), 00149 // this, TQT_SLOT( slotExecute( TQIconViewItem *, 00150 // const TQPoint & ) ) ); 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 TQIconViewItem* 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 TQIconView 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 TQRect r; 00192 TQRect redraw; 00193 if ( previousItem ) 00194 r = TQRect( QMIN( previousItem->x(), m_pCurrentItem->x() ), 00195 QMIN( previousItem->y(), m_pCurrentItem->y() ), 00196 0, 0 ); 00197 else 00198 r = TQRect( 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( TQIconViewItem* 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() == TQIconView::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( TQIconViewItem *item, const TQPoint &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( TQDropEvent *e ) 00260 { 00261 TQIconViewItem *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( TQFocusEvent *fe ) 00278 { 00279 m_pAutoSelect->stop(); 00280 00281 TQIconView::focusOutEvent( fe ); 00282 } 00283 00284 void KIconView::leaveEvent( TQEvent *e ) 00285 { 00286 m_pAutoSelect->stop(); 00287 00288 TQIconView::leaveEvent( e ); 00289 } 00290 00291 void KIconView::contentsMousePressEvent( TQMouseEvent *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 TQIconView::contentsMousePressEvent( e ); 00303 d->doAutoSelect = false; 00304 } 00305 00306 void KIconView::contentsMouseDoubleClickEvent ( TQMouseEvent * e ) 00307 { 00308 TQIconView::contentsMouseDoubleClickEvent( e ); 00309 00310 TQIconViewItem* item = findItem( e->pos() ); 00311 00312 if( item ) { 00313 if( (e->button() == Qt::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, TQIconViewItem *item, const TQPoint &pos ) 00322 { 00323 //kdDebug() << " KIconView::slotMouseButtonClicked() item=" << item << endl; 00324 if( d->doubleClickIgnoreTimer.isActive() ) 00325 return; // Ignore double click 00326 00327 if( (btn == Qt::LeftButton) && item ) 00328 emitExecute( item, pos ); 00329 } 00330 00331 void KIconView::contentsMouseReleaseEvent( TQMouseEvent *e ) 00332 { 00333 d->doAutoSelect = true; 00334 TQIconView::contentsMouseReleaseEvent( e ); 00335 } 00336 00337 void KIconView::contentsDragEnterEvent( TQDragEnterEvent *e ) 00338 { 00339 updateDragHoldItem( e ); 00340 TQIconView::contentsDragEnterEvent( e ); 00341 } 00342 00343 void KIconView::contentsDragLeaveEvent( TQDragLeaveEvent *e ) 00344 { 00345 d->dragHoldTimer.stop(); 00346 d->dragHoldItem = 0L; 00347 TQIconView::contentsDragLeaveEvent( e ); 00348 } 00349 00350 00351 void KIconView::contentsDragMoveEvent( TQDragMoveEvent *e ) 00352 { 00353 updateDragHoldItem( e ); 00354 TQIconView::contentsDragMoveEvent( e ); 00355 } 00356 00357 void KIconView::contentsDropEvent( TQDropEvent* e ) 00358 { 00359 d->dragHoldTimer.stop(); 00360 TQIconView::contentsDropEvent( e ); 00361 } 00362 00363 void KIconView::slotDragHoldTimeout() 00364 { 00365 TQIconViewItem *tmp = d->dragHoldItem; 00366 d->dragHoldItem = 0L; 00367 00368 emit held( tmp ); 00369 } 00370 00371 void KIconView::takeItem( TQIconViewItem * item ) 00372 { 00373 if ( item == d->dragHoldItem ) 00374 { 00375 d->dragHoldTimer.stop(); 00376 d->dragHoldItem = 0L; 00377 } 00378 00379 TQIconView::takeItem( item ); 00380 } 00381 00382 void KIconView::cancelPendingHeldSignal() 00383 { 00384 d->dragHoldTimer.stop(); 00385 d->dragHoldItem = 0L; 00386 } 00387 00388 void KIconView::wheelEvent( TQWheelEvent *e ) 00389 { 00390 if (horizontalScrollBar() && (arrangement() == TQIconView::TopToBottom)) { 00391 TQWheelEvent ce(e->pos(), e->delta(), e->state(), Qt::Horizontal); 00392 TQApplication::sendEvent( horizontalScrollBar(), &ce); 00393 if (ce.isAccepted()) { 00394 e->accept(); 00395 return; 00396 } 00397 } 00398 TQIconView::wheelEvent(e); 00399 } 00400 00401 void KIconView::setFont( const TQFont &font ) 00402 { 00403 delete d->fm; 00404 d->fm = 0L; 00405 TQIconView::setFont( font ); 00406 } 00407 00408 TQFontMetrics *KIconView::itemFontMetrics() const 00409 { 00410 if (!d->fm) { 00411 // TQIconView creates one too, but we can't access it 00412 d->fm = new TQFontMetrics( font() ); 00413 } 00414 return d->fm; 00415 } 00416 00417 TQPixmap KIconView::selectedIconPixmap( TQPixmap *pix, const TQColor &col ) const 00418 { 00419 TQPixmap m; 00420 if ( d->maskCache.find( TQString::number( pix->serialNumber() ), m ) ) 00421 return m; 00422 m = KPixmapEffect::selectedPixmap( KPixmap(*pix), col ); 00423 d->maskCache.insert( TQString::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 class KIconViewItem::KIconViewItemPrivate 00451 { 00452 public: 00453 KIconViewItemPrivate() { 00454 m_pixmapSize = TQSize(0,0); 00455 } 00456 00457 public: 00458 TQSize m_pixmapSize; 00459 int realTextHeight; 00460 }; 00461 00462 void KIconViewItem::init() 00463 { 00464 m_wordWrap = 0L; 00465 d = 0L; 00466 calcRect(); 00467 } 00468 00469 KIconViewItem::~KIconViewItem() 00470 { 00471 delete m_wordWrap; 00472 if (d) { 00473 delete d; 00474 } 00475 } 00476 00477 void KIconViewItem::calcRect( const TQString& text_ ) 00478 { 00479 if ( !d ) { 00480 d = new KIconViewItemPrivate; 00481 } 00482 d->realTextHeight = -1; 00483 00484 bool drawRoundedRect = KGlobalSettings::iconUseRoundedRect(); 00485 00486 Q_ASSERT( iconView() ); 00487 if ( !iconView() ) 00488 return; 00489 delete m_wordWrap; 00490 m_wordWrap = 0L; 00491 #ifndef NDEBUG // be faster for the end-user, such a bug will have been fixed before hand :) 00492 if ( !iconView()->inherits("KIconView") ) 00493 { 00494 kdWarning() << "KIconViewItem used in a " << iconView()->className() << " !!" << endl; 00495 return; 00496 } 00497 #endif 00498 //kdDebug() << "KIconViewItem::calcRect - " << text() << endl; 00499 KIconView *view = static_cast<KIconView *>(iconView()); 00500 TQRect itemIconRect = pixmapRect(); 00501 TQRect itemTextRect = textRect(); 00502 TQRect itemRect = rect(); 00503 00504 int pw = 0; 00505 int ph = 0; 00506 00507 #ifndef QT_NO_PICTURE 00508 if ( picture() ) { 00509 TQRect br = picture()->boundingRect(); 00510 pw = br.width() + 2; 00511 ph = br.height() + 2; 00512 } else 00513 #endif 00514 { 00515 // Qt uses unknown_icon if no pixmap. Let's see if we need that - I doubt it 00516 if (!pixmap()) 00517 return; 00518 pw = pixmap()->width() + 2; 00519 ph = pixmap()->height() + 2; 00520 } 00521 itemIconRect.setWidth( pw ); 00522 #if 1 // FIXME 00523 // There is a bug in Qt which prevents the item from being placed 00524 // properly when the pixmapRect is not at the top of the itemRect, so we 00525 // have to increase the height of the pixmapRect and leave it at the top 00526 // of the itemRect... 00527 if ( d && !d->m_pixmapSize.isNull() ) { 00528 itemIconRect.setHeight( d->m_pixmapSize.height() + 2 ); 00529 } 00530 else 00531 #endif 00532 itemIconRect.setHeight( ph ); 00533 00534 int tw = 0; 00535 if ( d && !d->m_pixmapSize.isNull() ) { 00536 tw = view->maxItemWidth() - ( view->itemTextPos() == TQIconView::Bottom ? 0 : 00537 d->m_pixmapSize.width() + 2 ); 00538 } 00539 else { 00540 tw = view->maxItemWidth() - ( view->itemTextPos() == TQIconView::Bottom ? 0 : 00541 itemIconRect.width() ); 00542 } 00543 00544 TQFontMetrics *fm = view->itemFontMetrics(); 00545 TQString t; 00546 TQRect r; 00547 00548 // When is text_ set ? Doesn't look like it's ever set. 00549 t = text_.isEmpty() ? text() : text_; 00550 00551 // Max text height 00552 int nbLines = static_cast<KIconView*>( iconView() )->iconTextHeight(); 00553 int height = nbLines > 0 ? fm->height() * nbLines : 0xFFFFFFFF; 00554 00555 // Should not be higher than pixmap if text is alongside icons 00556 if ( view->itemTextPos() != TQIconView::Bottom ) { 00557 if ( d && !d->m_pixmapSize.isNull() ) 00558 height = QMIN( d->m_pixmapSize.height() + 2, height ); 00559 else 00560 height = QMIN( itemIconRect.height(), height ); 00561 height = QMAX( height, fm->height() ); 00562 } 00563 00564 // Calculate the word-wrap 00565 TQRect outerRect( 0, 0, tw - 6, height ); 00566 m_wordWrap = KWordWrap::formatText( *fm, outerRect, 0, t ); 00567 r = m_wordWrap->boundingRect(); 00568 00569 int realWidth = QMAX( QMIN( r.width() + 4, tw ), fm->width( "X" ) ); 00570 if (drawRoundedRect == true) { 00571 itemTextRect.setWidth( realWidth + 2); 00572 } 00573 else { 00574 itemTextRect.setWidth( realWidth ); 00575 } 00576 itemTextRect.setHeight( r.height() ); 00577 00578 int w = 0; int h = 0; int y = 0; 00579 if ( view->itemTextPos() == TQIconView::Bottom ) { 00580 // If the pixmap size has been specified, use it 00581 if ( d && !d->m_pixmapSize.isNull() ) 00582 { 00583 w = QMAX( itemTextRect.width(), d->m_pixmapSize.width() + 2 ); 00584 h = itemTextRect.height() + d->m_pixmapSize.height() + 2 + 1; 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(); 00589 #endif 00590 } 00591 else { 00592 w = QMAX( itemTextRect.width(), itemIconRect.width() ); 00593 h = itemTextRect.height() + itemIconRect.height() + 1; 00594 } 00595 00596 itemRect.setWidth( w ); 00597 itemRect.setHeight( h ); 00598 int width = QMAX( w, TQApplication::globalStrut().width() ); // see TQIconViewItem::width() 00599 int height = QMAX( h, TQApplication::globalStrut().height() ); // see TQIconViewItem::height() 00600 itemTextRect = TQRect( ( width - itemTextRect.width() ) / 2, height - itemTextRect.height(), 00601 itemTextRect.width(), itemTextRect.height() ); 00602 itemIconRect = TQRect( ( width - itemIconRect.width() ) / 2, y, 00603 itemIconRect.width(), itemIconRect.height() ); 00604 } 00605 else { 00606 // If the pixmap size has been specified, use it 00607 if ( d && !d->m_pixmapSize.isNull() ) { 00608 h = QMAX( itemTextRect.height(), d->m_pixmapSize.height() + 2 ); 00609 #if 0 // FIXME 00610 // Waiting for the qt bug to be solved, the pixmapRect must 00611 // stay on the top... 00612 y = ( d->m_pixmapSize.height() + 2 - itemIconRect.height() ) / 2; 00613 #endif 00614 } 00615 else { 00616 h = QMAX( itemTextRect.height(), itemIconRect.height() ); 00617 } 00618 w = itemTextRect.width() + itemIconRect.width() + 1; 00619 00620 itemRect.setWidth( w ); 00621 itemRect.setHeight( h ); 00622 int width = QMAX( w, TQApplication::globalStrut().width() ); // see TQIconViewItem::width() 00623 int height = QMAX( h, TQApplication::globalStrut().height() ); // see TQIconViewItem::height() 00624 00625 itemTextRect = TQRect( width - itemTextRect.width(), ( height - itemTextRect.height() ) / 2, 00626 itemTextRect.width(), itemTextRect.height() ); 00627 if ( itemIconRect.height() > itemTextRect.height() ) { // icon bigger than text -> center vertically 00628 itemIconRect = TQRect( 0, ( height - itemIconRect.height() ) / 2, 00629 itemIconRect.width(), itemIconRect.height() ); 00630 } 00631 else { // icon smaller than text -> place in top or center with first line 00632 itemIconRect = TQRect( 0, QMAX(( fm->height() - itemIconRect.height() ) / 2 + y, 0), 00633 itemIconRect.width(), itemIconRect.height() ); 00634 } 00635 if ( ( itemIconRect.height() <= 20 ) && ( itemTextRect.height() < itemIconRect.height() ) ) { 00636 d->realTextHeight = itemTextRect.height(); 00637 itemTextRect.setY( itemIconRect.y() ); 00638 itemTextRect.setHeight( itemIconRect.height() - 2 ); 00639 } 00640 } 00641 00642 if ( itemIconRect != pixmapRect() ) { 00643 setPixmapRect( itemIconRect ); 00644 } 00645 if ( itemTextRect != textRect() ) { 00646 setTextRect( itemTextRect ); 00647 } 00648 if ( itemRect != rect() ) { 00649 setItemRect( itemRect ); 00650 } 00651 00652 // Done by setPixmapRect, setTextRect and setItemRect ! [and useless if no rect changed] 00653 //view->updateItemContainer( this ); 00654 00655 } 00656 00657 void KIconViewItem::paintItem( TQPainter *p, const TQColorGroup &cg ) 00658 { 00659 TQIconView* view = iconView(); 00660 Q_ASSERT( view ); 00661 if ( !view ) 00662 return; 00663 #ifndef NDEBUG // be faster for the end-user, such a bug will have been fixed before hand :) 00664 if ( !view->inherits("KIconView") ) 00665 { 00666 kdWarning() << "KIconViewItem used in a " << view->className() << " !!" << endl; 00667 return; 00668 } 00669 #endif 00670 00671 p->save(); 00672 00673 paintPixmap(p, cg); 00674 paintText(p, cg); 00675 00676 p->restore(); 00677 } 00678 00679 KWordWrap * KIconViewItem::wordWrap() 00680 { 00681 return m_wordWrap; 00682 } 00683 00684 void KIconViewItem::paintPixmap( TQPainter *p, const TQColorGroup &cg ) 00685 { 00686 KIconView *kview = static_cast<KIconView *>(iconView()); 00687 00688 #ifndef QT_NO_PICTURE 00689 if ( picture() ) { 00690 TQPicture *pic = picture(); 00691 if ( isSelected() ) { 00692 // TODO something as nice as selectedIconPixmap if possible ;) 00693 p->fillRect( pixmapRect( false ), TQBrush( cg.highlight(), TQBrush::Dense4Pattern) ); 00694 } 00695 p->drawPicture( x()-pic->boundingRect().x(), y()-pic->boundingRect().y(), *pic ); 00696 } else 00697 #endif 00698 { 00699 int iconX = pixmapRect( false ).x(); 00700 int iconY = pixmapRect( false ).y(); 00701 00702 TQPixmap *pix = pixmap(); 00703 if ( !pix || pix->isNull() ) 00704 return; 00705 00706 #if 1 // FIXME 00707 // Move the pixmap manually because the pixmapRect is at the 00708 // top of the itemRect 00709 // (won't be needed anymore in future versions of qt) 00710 if ( d && !d->m_pixmapSize.isNull() ) 00711 { 00712 int offset = 0; 00713 if ( kview->itemTextPos() == TQIconView::Bottom ) 00714 offset = d->m_pixmapSize.height() - pix->height(); 00715 else 00716 offset = ( d->m_pixmapSize.height() - pix->height() ) / 2; 00717 if ( offset > 0 ) 00718 iconY += offset; 00719 } 00720 #endif 00721 if ( isSelected() ) { 00722 TQPixmap selectedPix = kview->selectedIconPixmap( pix, cg.highlight() ); 00723 p->drawPixmap( iconX, iconY, selectedPix ); 00724 } else { 00725 p->drawPixmap( iconX, iconY, *pix ); 00726 } 00727 } 00728 } 00729 00730 void KIconViewItem::paintText( TQPainter *p, const TQColorGroup &cg ) 00731 { 00732 bool drawRoundedRect = KGlobalSettings::iconUseRoundedRect(); 00733 int textX; 00734 if (drawRoundedRect == true) { 00735 textX = textRect( false ).x() + 4; 00736 } 00737 else { 00738 textX = textRect( false ).x() + 2; 00739 } 00740 int textY; 00741 if ( d && (d->realTextHeight != -1) ) { 00742 textY = textRect( false ).y() + ((rect().height() - d->realTextHeight) / 2); 00743 } 00744 else { 00745 textY = textRect( false ).y(); 00746 } 00747 00748 if ( isSelected() ) { 00749 if (drawRoundedRect == true) { 00750 p->setBrush(TQBrush(cg.highlight())); 00751 p->setPen(TQPen(cg.highlight())); 00752 p->drawRoundRect( textRect( false ) ,1000/textRect(false).width(),1000/textRect(false).height() ); 00753 } 00754 else { 00755 p->fillRect( textRect( false ), cg.highlight() ); 00756 } 00757 p->setPen( TQPen( cg.highlightedText() ) ); 00758 } 00759 else { 00760 if ( iconView()->itemTextBackground() != Qt::NoBrush ) { 00761 p->fillRect( textRect( false ), iconView()->itemTextBackground() ); 00762 } 00763 p->setPen( cg.text() ); 00764 } 00765 00766 int align = iconView()->itemTextPos() == TQIconView::Bottom ? AlignHCenter : AlignAuto; 00767 m_wordWrap->drawText( p, textX, textY, align | KWordWrap::Truncate ); 00768 } 00769 00770 TQSize KIconViewItem::pixmapSize() const 00771 { 00772 return d ? d->m_pixmapSize : TQSize( 0, 0 ); 00773 } 00774 00775 void KIconViewItem::setPixmapSize( const TQSize& size ) 00776 { 00777 if ( !d ) { 00778 d = new KIconViewItemPrivate; 00779 } 00780 00781 d->m_pixmapSize = size; 00782 } 00783 00784 void KIconView::virtual_hook( int, void* ) 00785 { /*BASE::virtual_hook( id, data );*/ } 00786 00787 #include "kiconview.moc"