22 #include <tqpainter.h>
23 #include <tqpixmapcache.h>
24 #include <tqcleanuphandler.h>
26 #include "kiconview.h"
27 #include "kwordwrap.h"
31 #include <kglobalsettings.h>
32 #include <kapplication.h>
37 #include <kpixmapeffect.h>
39 class KIconView::KIconViewPrivate
43 mode = KIconView::Execute;
52 TQPixmapCache maskCache;
54 TQIconViewItem *dragHoldItem;
55 TQTimer dragHoldTimer;
56 TQTimer doubleClickIgnoreTimer;
59 KIconView::KIconView( TQWidget *parent,
const char *name, WFlags f )
60 : TQIconView( parent, name, f )
62 d =
new KIconViewPrivate;
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( KApplication::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 KIconView::~KIconView()
100 void KIconView::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 KIconView::slotOnViewport()
117 if ( m_bUseSingle && m_bChangeCursorOverItem )
118 viewport()->unsetCursor();
120 m_pAutoSelect->stop();
124 void KIconView::slotSettingsChanged(
int category)
126 if ( category != KApplication::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( QMIN( previousItem->x(), m_pCurrentItem->x() ),
195 QMIN( 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() <<
"KIconView: That's not supposed to happen!!!!" <<
endl;
238 void KIconView::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 KIconView::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 KIconView::focusOutEvent( TQFocusEvent *fe )
279 m_pAutoSelect->stop();
281 TQIconView::focusOutEvent( fe );
284 void KIconView::leaveEvent( TQEvent *e )
286 m_pAutoSelect->stop();
288 TQIconView::leaveEvent( e );
291 void KIconView::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 KIconView::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 KIconView::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 KIconView::contentsMouseReleaseEvent( TQMouseEvent *e )
333 d->doAutoSelect =
true;
334 TQIconView::contentsMouseReleaseEvent( e );
337 void KIconView::contentsDragEnterEvent( TQDragEnterEvent *e )
339 updateDragHoldItem( e );
340 TQIconView::contentsDragEnterEvent( e );
343 void KIconView::contentsDragLeaveEvent( TQDragLeaveEvent *e )
345 d->dragHoldTimer.stop();
346 d->dragHoldItem = 0L;
347 TQIconView::contentsDragLeaveEvent( e );
351 void KIconView::contentsDragMoveEvent( TQDragMoveEvent *e )
353 updateDragHoldItem( e );
354 TQIconView::contentsDragMoveEvent( e );
357 void KIconView::contentsDropEvent( TQDropEvent* e )
359 d->dragHoldTimer.stop();
360 TQIconView::contentsDropEvent( e );
363 void KIconView::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 KIconView::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 *KIconView::itemFontMetrics()
const
412 d->fm =
new TQFontMetrics( font() );
417 TQPixmap KIconView::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 KIconViewItem::KIconViewItemPrivate
453 KIconViewItemPrivate() {
454 m_pixmapSize = TQSize(0,0);
462 void KIconViewItem::init()
469 KIconViewItem::~KIconViewItem()
477 void KIconViewItem::calcRect(
const TQString& text_ )
480 d =
new KIconViewItemPrivate;
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(
"KIconView") )
494 kdWarning() <<
"KIconViewItem 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<KIconView*
>( 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 = QMIN( d->m_pixmapSize.height() + 2, height );
560 height = QMIN( itemIconRect.height(), height );
561 height = QMAX( height, fm->height() );
565 TQRect outerRect( 0, 0, tw - 6, height );
569 int realWidth = QMAX( QMIN( 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 = QMAX( 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 = QMAX( itemTextRect.width(), itemIconRect.width() );
593 h = itemTextRect.height() + itemIconRect.height() + 1;
596 itemRect.setWidth( w );
597 itemRect.setHeight( h );
598 int width = QMAX( w, TQApplication::globalStrut().width() );
599 int height = QMAX( 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 = QMAX( itemTextRect.height(), d->m_pixmapSize.height() + 2 );
612 y = ( d->m_pixmapSize.height() + 2 - itemIconRect.height() ) / 2;
616 h = QMAX( itemTextRect.height(), itemIconRect.height() );
618 w = itemTextRect.width() + itemIconRect.width() + 1;
620 itemRect.setWidth( w );
621 itemRect.setHeight( h );
622 int width = QMAX( w, TQApplication::globalStrut().width() );
623 int height = QMAX( 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, QMAX(( 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 KIconViewItem::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(
"KIconView") )
666 kdWarning() <<
"KIconViewItem used in a " << view->className() <<
" !!" <<
endl;
684 void KIconViewItem::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 KIconViewItem::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 KIconViewItemPrivate;
781 d->m_pixmapSize = size;
784 void KIconView::virtual_hook(
int,
void* )
787 #include "kiconview.moc"
static KWordWrap * formatText(TQFontMetrics &fm, const TQRect &r, int flags, const TQString &str, int len=-1)
Main method for wrapping text.
void executed(TQIconViewItem *item)
This signal is emitted whenever the user executes an iconview item.
void setIconTextHeight(int n)
Set the maximum number of lines that will be used to display icon text.
void drawText(TQPainter *painter, int x, int y, int flags=TQt::AlignAuto) const
Draw the text that has been previously wrapped, at position x,y.
static bool singleClick()
void setPixmapSize(const TQSize &size)
Using this function, you can specify a custom size for the pixmap.
TQSize pixmapSize() const
kdbgstream kdDebug(int area=0)
Mode
KIconView has two different operating modes.
A variant of TQIconView that honors KDE's system-wide settings.
virtual void setFont(const TQFont &)
Reimplemented for internal purposes.
void held(TQIconViewItem *item)
This signal is emitted whenever the user hold something on an iconview during a drag'n'drop.
int iconTextHeight() const
kdbgstream kdWarning(int area=0)
void setMode(Mode m)
Sets the mode to Execute or Select.
Word-wrap algorithm that takes into account beautifulness ;)
virtual void takeItem(TQIconViewItem *item)
Reimplemented for held() signal behavior internal purposes.
static bool changeCursorOverIcon()
void doubleClicked(TQIconViewItem *item, const TQPoint &pos)
This signal gets emitted whenever the user double clicks into the iconview.
static KPixmap selectedPixmap(const KPixmap &pixmap, const TQColor &col)
void slotAutoSelect()
Auto selection happend.
static int autoSelectDelay()
A TQCursor wrapper allowing "themed" cursors and auto-hiding cursors.
void cancelPendingHeldSignal()
This method allows to handle correctly cases where a subclass needs the held() signal to not be trigg...
static bool iconUseRoundedRect()
kndbgstream & endl(kndbgstream &s)
TQRect boundingRect() const
static ButtonState keyboardMouseState()