22 #include <tqpainter.h>
23 #include <tqpixmapcache.h>
24 #include <tqcleanuphandler.h>
26 #include "kiconview.h"
27 #include "kwordwrap.h"
28 #include <tdeconfig.h>
30 #include <tdeglobal.h>
31 #include <tdeglobalsettings.h>
32 #include <tdeapplication.h>
37 #include <kpixmapeffect.h>
39 class TDEIconView::TDEIconViewPrivate
42 TDEIconViewPrivate() {
43 mode = TDEIconView::Execute;
52 TQPixmapCache maskCache;
54 TQIconViewItem *dragHoldItem;
55 TQTimer dragHoldTimer;
56 TQTimer doubleClickIgnoreTimer;
59 TDEIconView::TDEIconView( TQWidget *parent,
const char *name, WFlags f )
60 : TQIconView( parent,
name, f )
62 d =
new TDEIconViewPrivate;
64 connect(
this, TQT_SIGNAL( onViewport() ),
65 this, TQT_SLOT( slotOnViewport() ) );
66 connect(
this, TQT_SIGNAL( onItem( TQIconViewItem * ) ),
67 this, TQT_SLOT( slotOnItem( TQIconViewItem * ) ) );
68 slotSettingsChanged( TDEApplication::SETTINGS_MOUSE );
70 connect( kapp, TQT_SIGNAL( settingsChanged(
int) ), TQT_SLOT( slotSettingsChanged(
int) ) );
71 kapp->addKipcEventMask( KIPC::SettingsChanged );
76 m_pAutoSelect =
new TQTimer(
this );
77 connect( m_pAutoSelect, TQT_SIGNAL( timeout() ),
78 this, TQT_SLOT( slotAutoSelect() ) );
80 connect( &d->dragHoldTimer, TQT_SIGNAL(timeout()),
this, TQT_SLOT(slotDragHoldTimeout()) );
83 TDEIconView::~TDEIconView()
100 void TDEIconView::slotOnItem( TQIconViewItem *item )
103 if ( m_bUseSingle ) {
104 if ( m_bChangeCursorOverItem )
105 viewport()->setCursor(
KCursor().handCursor() );
107 if ( (m_autoSelectDelay > -1) ) {
108 m_pAutoSelect->start( m_autoSelectDelay,
true );
111 m_pCurrentItem = item;
115 void TDEIconView::slotOnViewport()
117 if ( m_bUseSingle && m_bChangeCursorOverItem )
118 viewport()->unsetCursor();
120 m_pAutoSelect->stop();
124 void TDEIconView::slotSettingsChanged(
int category)
126 if ( category != TDEApplication::SETTINGS_MOUSE )
131 disconnect(
this, TQT_SIGNAL( mouseButtonClicked(
int, TQIconViewItem *,
133 this, TQT_SLOT( slotMouseButtonClicked(
int, TQIconViewItem *,
134 const TQPoint & ) ) );
141 connect(
this, TQT_SIGNAL( mouseButtonClicked(
int, TQIconViewItem *,
143 this, TQT_SLOT( slotMouseButtonClicked(
int, TQIconViewItem *,
144 const TQPoint & ) ) );
156 if( !m_bUseSingle || !m_bChangeCursorOverItem )
157 viewport()->unsetCursor();
163 if( index( m_pCurrentItem ) == -1 || !d->doAutoSelect )
171 TQIconViewItem* previousItem = currentItem();
172 setCurrentItem( m_pCurrentItem );
174 if( m_pCurrentItem ) {
176 if( (keybstate & ShiftButton) ) {
178 bool block = signalsBlocked();
179 blockSignals(
true );
182 if( !(keybstate & ControlButton) )
185 bool select = !m_pCurrentItem->isSelected();
186 bool update = viewport()->isUpdatesEnabled();
187 viewport()->setUpdatesEnabled(
false );
194 r = TQRect( TQMIN( previousItem->x(), m_pCurrentItem->x() ),
195 TQMIN( previousItem->y(), m_pCurrentItem->y() ),
198 r = TQRect( 0, 0, 0, 0 );
199 if ( previousItem->x() < m_pCurrentItem->x() )
200 r.setWidth( m_pCurrentItem->x() - previousItem->x() + m_pCurrentItem->width() );
202 r.setWidth( previousItem->x() - m_pCurrentItem->x() + previousItem->width() );
203 if ( previousItem->y() < m_pCurrentItem->y() )
204 r.setHeight( m_pCurrentItem->y() - previousItem->y() + m_pCurrentItem->height() );
206 r.setHeight( previousItem->y() - m_pCurrentItem->y() + previousItem->height() );
211 for( TQIconViewItem* i = firstItem(); i; i = i->nextItem() ) {
212 if( i->intersects( r ) ) {
213 redraw = redraw.unite( i->rect() );
214 setSelected( i, select,
true );
218 blockSignals( block );
219 viewport()->setUpdatesEnabled( update );
220 repaintContents( redraw,
false );
222 emit selectionChanged();
224 if( selectionMode() == TQIconView::Single )
225 emit selectionChanged( m_pCurrentItem );
229 else if( (keybstate & ControlButton) )
230 setSelected( m_pCurrentItem, !m_pCurrentItem->isSelected(),
true );
232 setSelected( m_pCurrentItem,
true );
235 kdDebug() <<
"TDEIconView: That's not supposed to happen!!!!" <<
endl;
238 void TDEIconView::emitExecute( TQIconViewItem *item,
const TQPoint &pos )
240 if ( d->mode != Execute )
248 m_pAutoSelect->stop();
251 if( !( m_bUseSingle && ((keybstate & ShiftButton) || (keybstate & ControlButton)) ) ) {
252 setSelected( item,
false );
253 viewport()->unsetCursor();
259 void TDEIconView::updateDragHoldItem( TQDropEvent *e )
261 TQIconViewItem *item = findItem( e->pos() );
263 if ( d->dragHoldItem != item)
265 d->dragHoldItem = item;
268 d->dragHoldTimer.start( 1000,
true );
272 d->dragHoldTimer.stop();
277 void TDEIconView::focusOutEvent( TQFocusEvent *fe )
279 m_pAutoSelect->stop();
281 TQIconView::focusOutEvent( fe );
284 void TDEIconView::leaveEvent( TQEvent *e )
286 m_pAutoSelect->stop();
288 TQIconView::leaveEvent( e );
291 void TDEIconView::contentsMousePressEvent( TQMouseEvent *e )
293 if( (selectionMode() == Extended) && (e->state() & ShiftButton) && !(e->state() & ControlButton) ) {
294 bool block = signalsBlocked();
295 blockSignals(
true );
299 blockSignals( block );
302 TQIconView::contentsMousePressEvent( e );
303 d->doAutoSelect =
false;
306 void TDEIconView::contentsMouseDoubleClickEvent ( TQMouseEvent * e )
308 TQIconView::contentsMouseDoubleClickEvent( e );
310 TQIconViewItem* item = findItem( e->pos() );
313 if( (e->button() == Qt::LeftButton) && !m_bUseSingle )
314 emitExecute( item, e->globalPos() );
318 d->doubleClickIgnoreTimer.start(0,
true);
321 void TDEIconView::slotMouseButtonClicked(
int btn, TQIconViewItem *item,
const TQPoint &pos )
324 if( d->doubleClickIgnoreTimer.isActive() )
327 if( (btn == Qt::LeftButton) && item )
328 emitExecute( item, pos );
331 void TDEIconView::contentsMouseReleaseEvent( TQMouseEvent *e )
333 d->doAutoSelect =
true;
334 TQIconView::contentsMouseReleaseEvent( e );
337 void TDEIconView::contentsDragEnterEvent( TQDragEnterEvent *e )
339 updateDragHoldItem( e );
340 TQIconView::contentsDragEnterEvent( e );
343 void TDEIconView::contentsDragLeaveEvent( TQDragLeaveEvent *e )
345 d->dragHoldTimer.stop();
346 d->dragHoldItem = 0L;
347 TQIconView::contentsDragLeaveEvent( e );
351 void TDEIconView::contentsDragMoveEvent( TQDragMoveEvent *e )
353 updateDragHoldItem( e );
354 TQIconView::contentsDragMoveEvent( e );
357 void TDEIconView::contentsDropEvent( TQDropEvent* e )
359 d->dragHoldTimer.stop();
360 TQIconView::contentsDropEvent( e );
363 void TDEIconView::slotDragHoldTimeout()
365 TQIconViewItem *tmp = d->dragHoldItem;
366 d->dragHoldItem = 0L;
373 if ( item == d->dragHoldItem )
375 d->dragHoldTimer.stop();
376 d->dragHoldItem = 0L;
379 TQIconView::takeItem( item );
384 d->dragHoldTimer.stop();
385 d->dragHoldItem = 0L;
388 void TDEIconView::wheelEvent( TQWheelEvent *e )
390 if (horizontalScrollBar() && (arrangement() == TQIconView::TopToBottom)) {
391 TQWheelEvent ce(e->pos(), e->delta(), e->state(), Qt::Horizontal);
392 TQApplication::sendEvent( horizontalScrollBar(), &ce);
393 if (ce.isAccepted()) {
398 TQIconView::wheelEvent(e);
405 TQIconView::setFont( font );
408 TQFontMetrics *TDEIconView::itemFontMetrics()
const
412 d->fm =
new TQFontMetrics( font() );
417 TQPixmap TDEIconView::selectedIconPixmap( TQPixmap *pix,
const TQColor &col )
const
420 if ( d->maskCache.find( TQString::number( pix->serialNumber() ), m ) )
423 d->maskCache.insert( TQString::number( pix->serialNumber() ), m );
429 return d->textHeight > 0 ? d->textHeight : ( wordWrapIconText() ? 99 : 1 );
441 setWordWrapIconText(
false );
450 class TDEIconViewItem::TDEIconViewItemPrivate
453 TDEIconViewItemPrivate() {
454 m_pixmapSize = TQSize(0,0);
462 void TDEIconViewItem::init()
469 TDEIconViewItem::~TDEIconViewItem()
477 void TDEIconViewItem::calcRect(
const TQString& text_ )
480 d =
new TDEIconViewItemPrivate;
482 d->realTextHeight = -1;
486 Q_ASSERT( iconView() );
491 #ifndef NDEBUG // be faster for the end-user, such a bug will have been fixed before hand :)
492 if ( !iconView()->inherits(
"TDEIconView") )
494 kdWarning() <<
"TDEIconViewItem used in a " << iconView()->className() <<
" !!" <<
endl;
500 TQRect itemIconRect = pixmapRect();
501 TQRect itemTextRect = textRect();
502 TQRect itemRect = rect();
507 #ifndef QT_NO_PICTURE
509 TQRect br = picture()->boundingRect();
511 ph = br.height() + 2;
518 pw = pixmap()->width() + 2;
519 ph = pixmap()->height() + 2;
521 itemIconRect.setWidth( pw );
527 if ( d && !d->m_pixmapSize.isNull() ) {
528 itemIconRect.setHeight( d->m_pixmapSize.height() + 2 );
532 itemIconRect.setHeight( ph );
535 if ( d && !d->m_pixmapSize.isNull() ) {
536 tw = view->maxItemWidth() - ( view->itemTextPos() == TQIconView::Bottom ? 0 :
537 d->m_pixmapSize.width() + 2 );
540 tw = view->maxItemWidth() - ( view->itemTextPos() == TQIconView::Bottom ? 0 :
541 itemIconRect.width() );
544 TQFontMetrics *fm = view->itemFontMetrics();
549 t = text_.isEmpty() ? text() : text_;
552 int nbLines =
static_cast<TDEIconView*
>( iconView() )->iconTextHeight();
553 int height = nbLines > 0 ? fm->height() * nbLines : 0xFFFFFFFF;
556 if ( view->itemTextPos() != TQIconView::Bottom ) {
557 if ( d && !d->m_pixmapSize.isNull() )
558 height = TQMIN( d->m_pixmapSize.height() + 2, height );
560 height = TQMIN( itemIconRect.height(), height );
561 height = TQMAX( height, fm->height() );
565 TQRect outerRect( 0, 0, tw - 6, height );
569 int realWidth = TQMAX( TQMIN( r.width() + 4, tw ), fm->width(
"X" ) );
570 if (drawRoundedRect ==
true) {
571 itemTextRect.setWidth( realWidth + 2);
574 itemTextRect.setWidth( realWidth );
576 itemTextRect.setHeight( r.height() );
578 int w = 0;
int h = 0;
int y = 0;
579 if ( view->itemTextPos() == TQIconView::Bottom ) {
581 if ( d && !d->m_pixmapSize.isNull() )
583 w = TQMAX( itemTextRect.width(), d->m_pixmapSize.width() + 2 );
584 h = itemTextRect.height() + d->m_pixmapSize.height() + 2 + 1;
588 y = d->m_pixmapSize.height() + 2 - itemIconRect.height();
592 w = TQMAX( itemTextRect.width(), itemIconRect.width() );
593 h = itemTextRect.height() + itemIconRect.height() + 1;
596 itemRect.setWidth( w );
597 itemRect.setHeight( h );
598 int width = TQMAX( w, TQApplication::globalStrut().width() );
599 int height = TQMAX( h, TQApplication::globalStrut().height() );
600 itemTextRect = TQRect( ( width - itemTextRect.width() ) / 2, height - itemTextRect.height(),
601 itemTextRect.width(), itemTextRect.height() );
602 itemIconRect = TQRect( ( width - itemIconRect.width() ) / 2, y,
603 itemIconRect.width(), itemIconRect.height() );
607 if ( d && !d->m_pixmapSize.isNull() ) {
608 h = TQMAX( itemTextRect.height(), d->m_pixmapSize.height() + 2 );
612 y = ( d->m_pixmapSize.height() + 2 - itemIconRect.height() ) / 2;
616 h = TQMAX( itemTextRect.height(), itemIconRect.height() );
618 w = itemTextRect.width() + itemIconRect.width() + 1;
620 itemRect.setWidth( w );
621 itemRect.setHeight( h );
622 int width = TQMAX( w, TQApplication::globalStrut().width() );
623 int height = TQMAX( h, TQApplication::globalStrut().height() );
625 itemTextRect = TQRect( width - itemTextRect.width(), ( height - itemTextRect.height() ) / 2,
626 itemTextRect.width(), itemTextRect.height() );
627 if ( itemIconRect.height() > itemTextRect.height() ) {
628 itemIconRect = TQRect( 0, ( height - itemIconRect.height() ) / 2,
629 itemIconRect.width(), itemIconRect.height() );
632 itemIconRect = TQRect( 0, TQMAX(( fm->height() - itemIconRect.height() ) / 2 + y, 0),
633 itemIconRect.width(), itemIconRect.height() );
635 if ( ( itemIconRect.height() <= 20 ) && ( itemTextRect.height() < itemIconRect.height() ) ) {
636 d->realTextHeight = itemTextRect.height();
637 itemTextRect.setY( itemIconRect.y() );
638 itemTextRect.setHeight( itemIconRect.height() - 2 );
642 if ( itemIconRect != pixmapRect() ) {
643 setPixmapRect( itemIconRect );
645 if ( itemTextRect != textRect() ) {
646 setTextRect( itemTextRect );
648 if ( itemRect != rect() ) {
649 setItemRect( itemRect );
657 void TDEIconViewItem::paintItem( TQPainter *p,
const TQColorGroup &cg )
659 TQIconView* view = iconView();
663 #ifndef NDEBUG // be faster for the end-user, such a bug will have been fixed before hand :)
664 if ( !view->inherits(
"TDEIconView") )
666 kdWarning() <<
"TDEIconViewItem used in a " << view->className() <<
" !!" <<
endl;
684 void TDEIconViewItem::paintPixmap( TQPainter *p,
const TQColorGroup &cg )
688 #ifndef QT_NO_PICTURE
690 TQPicture *pic = picture();
691 if ( isSelected() ) {
693 p->fillRect( pixmapRect(
false ), TQBrush( cg.highlight(), TQBrush::Dense4Pattern) );
695 p->drawPicture( x()-pic->boundingRect().x(), y()-pic->boundingRect().y(), *pic );
699 int iconX = pixmapRect(
false ).x();
700 int iconY = pixmapRect(
false ).y();
702 TQPixmap *pix = pixmap();
703 if ( !pix || pix->isNull() )
710 if ( d && !d->m_pixmapSize.isNull() )
713 if ( kview->itemTextPos() == TQIconView::Bottom )
714 offset = d->m_pixmapSize.height() - pix->height();
716 offset = ( d->m_pixmapSize.height() - pix->height() ) / 2;
721 if ( isSelected() ) {
722 TQPixmap selectedPix = kview->selectedIconPixmap( pix, cg.highlight() );
723 p->drawPixmap( iconX, iconY, selectedPix );
725 p->drawPixmap( iconX, iconY, *pix );
730 void TDEIconViewItem::paintText( TQPainter *p,
const TQColorGroup &cg )
734 if (drawRoundedRect ==
true) {
735 textX = textRect(
false ).x() + 4;
738 textX = textRect(
false ).x() + 2;
741 if ( d && (d->realTextHeight != -1) ) {
742 textY = textRect(
false ).y() + ((rect().height() - d->realTextHeight) / 2);
745 textY = textRect(
false ).y();
748 if ( isSelected() ) {
749 if (drawRoundedRect ==
true) {
750 p->setBrush(TQBrush(cg.highlight()));
751 p->setPen(TQPen(cg.highlight()));
752 p->drawRoundRect( textRect(
false ) ,1000/textRect(
false).width(),1000/textRect(
false).height() );
755 p->fillRect( textRect(
false ), cg.highlight() );
757 p->setPen( TQPen( cg.highlightedText() ) );
760 if ( iconView()->itemTextBackground() != Qt::NoBrush ) {
761 p->fillRect( textRect(
false ), iconView()->itemTextBackground() );
763 p->setPen( cg.text() );
766 int align = iconView()->itemTextPos() == TQIconView::Bottom ? AlignHCenter : AlignAuto;
767 m_wordWrap->
drawText( p, textX, textY, align | KWordWrap::Truncate );
772 return d ? d->m_pixmapSize : TQSize( 0, 0 );
778 d =
new TDEIconViewItemPrivate;
781 d->m_pixmapSize = size;
784 void TDEIconView::virtual_hook(
int,
void* )
787 #include "kiconview.moc"