23 #include <QtCore/QTimer>
24 #include <QtGui/QPainter>
25 #include <QtGui/QPixmapCache>
26 #include <QtGui/QActionEvent>
36 #include <QApplication>
38 class K3IconView::K3IconViewPrivate
51 QPixmapCache maskCache;
55 QTimer doubleClickIgnoreTimer;
61 d =
new K3IconViewPrivate;
63 connect(
this, SIGNAL(onViewport()),
72 m_pAutoSelect =
new QTimer(
this );
73 connect( m_pAutoSelect, SIGNAL(
timeout()),
76 connect( &d->dragHoldTimer, SIGNAL(
timeout()),
this, SLOT(slotDragHoldTimeout()) );
100 if ( m_bChangeCursorOverItem )
101 viewport()->setCursor(
QCursor(Qt::PointingHandCursor));
103 if ( (m_autoSelectDelay > -1) ) {
104 m_pAutoSelect->setSingleShot(
true );
105 m_pAutoSelect->start( m_autoSelectDelay );
108 m_pCurrentItem = item;
114 if ( m_bUseSingle && m_bChangeCursorOverItem )
115 viewport()->unsetCursor();
117 m_pAutoSelect->stop();
128 disconnect(
this, SIGNAL( mouseButtonClicked(
int,
Q3IconViewItem *,
153 if( !m_bUseSingle || !m_bChangeCursorOverItem )
154 viewport()->unsetCursor();
160 if( index( m_pCurrentItem ) == -1 || !d->doAutoSelect )
167 Qt::KeyboardModifiers keybstate = QApplication::keyboardModifiers();
169 setCurrentItem( m_pCurrentItem );
171 if( m_pCurrentItem ) {
173 if( (keybstate & Qt::ShiftModifier) ) {
175 bool block = signalsBlocked();
176 blockSignals(
true );
179 if( !(keybstate & Qt::ControlModifier) )
182 bool select = !m_pCurrentItem->isSelected();
183 bool update = viewport()->updatesEnabled();
184 viewport()->setUpdatesEnabled(
false );
190 if ( previousItem ) {
191 r =
QRect( qMin( previousItem->x(), m_pCurrentItem->x() ),
192 qMin( previousItem->y(), m_pCurrentItem->y() ),
194 if ( previousItem->x() < m_pCurrentItem->x() )
195 r.setWidth( m_pCurrentItem->x() - previousItem->x() + m_pCurrentItem->width() );
197 r.setWidth( previousItem->x() - m_pCurrentItem->x() + previousItem->width() );
198 if ( previousItem->y() < m_pCurrentItem->y() )
199 r.setHeight( m_pCurrentItem->y() - previousItem->y() + m_pCurrentItem->height() );
201 r.setHeight( previousItem->y() - m_pCurrentItem->y() + previousItem->height() );
205 r =
QRect( 0, 0, 0, 0 );
210 if( i->intersects( r ) ) {
211 redraw = redraw.unite( i->rect() );
212 setSelected( i, select,
true );
216 blockSignals( block );
217 viewport()->setUpdatesEnabled( update );
218 repaintContents( redraw,
false );
220 emit selectionChanged();
222 if( selectionMode() == Q3IconView::Single )
223 emit selectionChanged( m_pCurrentItem );
227 else if( (keybstate & Qt::ControlModifier) )
228 setSelected( m_pCurrentItem, !m_pCurrentItem->isSelected(), true );
230 setSelected( m_pCurrentItem,
true );
233 kDebug() <<
"K3IconView: That's not supposed to happen!!!!";
244 Qt::KeyboardModifiers keybstate = QApplication::keyboardModifiers();
246 m_pAutoSelect->stop();
249 if( !( m_bUseSingle && ((keybstate & Qt::ShiftModifier) || (keybstate & Qt::ControlModifier)) ) ) {
250 setSelected( item,
false );
251 viewport()->unsetCursor();
261 if ( d->dragHoldItem != item)
263 d->dragHoldItem = item;
266 d->dragHoldTimer.setSingleShot(
true );
267 d->dragHoldTimer.start( 1000 );
271 d->dragHoldTimer.stop();
278 m_pAutoSelect->stop();
280 Q3IconView::focusOutEvent( fe );
285 m_pAutoSelect->stop();
287 Q3IconView::leaveEvent( e );
292 if( (selectionMode() == Extended) && (e->modifiers() & Qt::ShiftModifier) && !(e->modifiers() & Qt::ControlModifier) ) {
293 bool block = signalsBlocked();
294 blockSignals(
true );
298 blockSignals( block );
301 Q3IconView::contentsMousePressEvent( e );
302 d->doAutoSelect =
false;
307 Q3IconView::contentsMouseDoubleClickEvent( e );
312 if( (e->button() == Qt::LeftButton) && !m_bUseSingle )
317 d->doubleClickIgnoreTimer.setSingleShot(
true);
318 d->doubleClickIgnoreTimer.start(0);
324 if( d->doubleClickIgnoreTimer.isActive() )
327 if( (btn == Qt::LeftButton) && item )
333 d->doAutoSelect =
true;
334 Q3IconView::contentsMouseReleaseEvent( e );
340 Q3IconView::contentsDragEnterEvent( e );
345 d->dragHoldTimer.stop();
346 d->dragHoldItem = 0L;
347 Q3IconView::contentsDragLeaveEvent( e );
354 Q3IconView::contentsDragMoveEvent( e );
359 d->dragHoldTimer.stop();
360 Q3IconView::contentsDropEvent( e );
363 void K3IconView::slotDragHoldTimeout()
366 d->dragHoldItem = 0L;
373 if ( item == d->dragHoldItem )
375 d->dragHoldTimer.stop();
376 d->dragHoldItem = 0L;
379 Q3IconView::takeItem( item );
384 d->dragHoldTimer.stop();
385 d->dragHoldItem = 0L;
390 if (horizontalScrollBar() && (arrangement() == Q3IconView::TopToBottom)) {
391 QWheelEvent ce(e->pos(), e->delta(), e->buttons(), e->modifiers(), Qt::Horizontal);
392 QApplication::sendEvent( horizontalScrollBar(), &ce);
393 if (ce.isAccepted()) {
398 Q3IconView::wheelEvent(e);
405 Q3IconView::setFont( font );
408 QFontMetrics *K3IconView::itemFontMetrics()
const
412 d->fm =
new QFontMetrics( font() );
417 QPixmap K3IconView::selectedIconPixmap( QPixmap *pix,
const QColor &col )
const
420 if ( d->maskCache.find( QString::number( pix->serialNumber() ), m ) )
427 p.setCompositionMode(QPainter::CompositionMode_SourceAtop);
428 p.fillRect(m.rect(), h);
431 d->maskCache.insert( QString::number( pix->serialNumber() ), m );
437 return d->textHeight > 0 ? d->textHeight : ( wordWrapIconText() ? 99 : 1 );
449 setWordWrapIconText(
false );
458 struct K3IconViewItem::K3IconViewItemPrivate
478 Q_ASSERT( iconView() );
483 #ifndef NDEBUG // be faster for the end-user, such a bug will have been fixed before hand :)
484 if ( !qobject_cast<K3IconView*>(iconView()) )
486 kWarning() <<
"K3IconViewItem used in a " << iconView()->metaObject()->className() <<
" !!";
492 QRect itemIconRect = pixmapRect();
493 QRect itemTextRect = textRect();
494 QRect itemRect = rect();
499 #ifndef QT_NO_PICTURE
501 QRect br = picture()->boundingRect();
503 ph = br.height() + 2;
510 pw = pixmap()->width() + 2;
511 ph = pixmap()->height() + 2;
513 itemIconRect.setWidth( pw );
519 if ( d && !d->m_pixmapSize.isNull() )
520 itemIconRect.setHeight( d->m_pixmapSize.height() + 2 );
523 itemIconRect.setHeight( ph );
526 if ( d && !d->m_pixmapSize.isNull() )
527 tw = view->maxItemWidth() - ( view->itemTextPos() == Q3IconView::Bottom ? 0 :
528 d->m_pixmapSize.width() + 2 );
530 tw = view->maxItemWidth() - ( view->itemTextPos() == Q3IconView::Bottom ? 0 :
531 itemIconRect.width() );
533 QFontMetrics *fm = view->itemFontMetrics();
538 t = text_.isEmpty() ? text() : text_;
541 int nbLines =
static_cast<K3IconView*
>( iconView() )->iconTextHeight();
542 int height = nbLines > 0 ? fm->height() * nbLines : 0xFFFFFFFF;
545 if ( view->itemTextPos() != Q3IconView::Bottom ) {
546 if ( d && !d->m_pixmapSize.isNull() )
547 height = qMin( d->m_pixmapSize.height() + 2, height );
549 height = qMin( itemIconRect.height(), height );
550 height = qMax( height, fm->height() );
554 QRect outerRect( 0, 0, tw - 6, height );
558 int realWidth = qMax( qMin( r.width() + 4, tw ), fm->width(
"X" ) );
559 itemTextRect.setWidth( realWidth );
560 itemTextRect.setHeight( r.height() );
562 int w = 0;
int h = 0;
int y = 0;
563 if ( view->itemTextPos() == Q3IconView::Bottom ) {
565 if ( d && !d->m_pixmapSize.isNull() )
567 w = qMax( itemTextRect.width(), d->m_pixmapSize.width() + 2 );
568 h = itemTextRect.height() + d->m_pixmapSize.height() + 2 + 1;
572 y = d->m_pixmapSize.height() + 2 - itemIconRect.height();
576 w = qMax( itemTextRect.width(), itemIconRect.width() );
577 h = itemTextRect.height() + itemIconRect.height() + 1;
580 itemRect.setWidth( w );
581 itemRect.setHeight( h );
582 int width = qMax( w, QApplication::globalStrut().width() );
583 int height = qMax( h, QApplication::globalStrut().height() );
584 itemTextRect =
QRect( ( width - itemTextRect.width() ) / 2, height - itemTextRect.height(),
585 itemTextRect.width(), itemTextRect.height() );
586 itemIconRect =
QRect( ( width - itemIconRect.width() ) / 2, y,
587 itemIconRect.width(), itemIconRect.height() );
590 if ( d && !d->m_pixmapSize.isNull() )
592 h = qMax( itemTextRect.height(), d->m_pixmapSize.height() + 2 );
596 y = ( d->m_pixmapSize.height() + 2 - itemIconRect.height() ) / 2;
600 h = qMax( itemTextRect.height(), itemIconRect.height() );
601 w = itemTextRect.width() + itemIconRect.width() + 1;
603 itemRect.setWidth( w );
604 itemRect.setHeight( h );
605 int width = qMax( w, QApplication::globalStrut().width() );
606 int height = qMax( h, QApplication::globalStrut().height() );
608 itemTextRect =
QRect( width - itemTextRect.width(), ( height - itemTextRect.height() ) / 2,
609 itemTextRect.width(), itemTextRect.height() );
610 if ( itemIconRect.height() > itemTextRect.height() )
611 itemIconRect =
QRect( 0, ( height - itemIconRect.height() ) / 2,
612 itemIconRect.width(), itemIconRect.height() );
614 itemIconRect =
QRect( 0, qMax(( fm->height() - itemIconRect.height() ) / 2 + y, 0),
615 itemIconRect.width(), itemIconRect.height() );
616 if ( ( itemIconRect.height() <= 20 ) && ( itemTextRect.height() < itemIconRect.height() ) )
618 itemTextRect.setHeight( itemIconRect.height() - 2 );
619 itemTextRect.setY( itemIconRect.y() );
623 if ( itemIconRect != pixmapRect() )
624 setPixmapRect( itemIconRect );
625 if ( itemTextRect != textRect() )
626 setTextRect( itemTextRect );
627 if ( itemRect != rect() )
628 setItemRect( itemRect );
641 #ifndef NDEBUG // be faster for the end-user, such a bug will have been fixed before hand :)
642 if ( !qobject_cast<K3IconView*>(view) )
644 kWarning() <<
"K3IconViewItem used in a " << view->metaObject()->className() <<
" !!";
666 #ifndef QT_NO_PICTURE
668 QPicture *pic = picture();
669 if ( isSelected() ) {
671 p->fillRect( pixmapRect(
false ), QBrush( cg.color(QPalette::Highlight), Qt::Dense4Pattern) );
673 p->drawPicture( x()-pic->boundingRect().x(), y()-pic->boundingRect().y(), *pic );
677 int iconX = pixmapRect(
false ).x();
678 int iconY = pixmapRect(
false ).y();
680 QPixmap *pix = pixmap();
681 if ( !pix || pix->isNull() )
688 if ( d && !d->m_pixmapSize.isNull() )
691 if ( kview->itemTextPos() == Q3IconView::Bottom )
692 offset = d->m_pixmapSize.height() - pix->height();
694 offset = ( d->m_pixmapSize.height() - pix->height() ) / 2;
699 if ( isSelected() ) {
700 QPixmap selectedPix = kview->selectedIconPixmap( pix, cg.color( QPalette::Highlight ) );
701 p->drawPixmap( iconX, iconY, selectedPix );
703 p->drawPixmap( iconX, iconY, *pix );
710 int textX = textRect(
false ).x() + 2;
711 int textY = textRect(
false ).y();
713 if ( isSelected() ) {
714 p->fillRect( textRect(
false ), cg.color( QPalette::Highlight ) );
715 p->setPen( QPen( cg.color( QPalette::HighlightedText ) ) );
717 if ( iconView()->itemTextBackground() != Qt::NoBrush )
718 p->fillRect( textRect(
false ), iconView()->itemTextBackground() );
719 p->setPen( cg.color( QPalette::Text ) );
722 int align = iconView()->itemTextPos() == Q3IconView::Bottom ? Qt::AlignHCenter : Qt::AlignLeft;
728 return d ? d->m_pixmapSize :
QSize( 0, 0 );
734 d =
new K3IconViewItemPrivate;
736 d->m_pixmapSize = size;
739 #include "k3iconview.moc"
void slotSettingsChanged(int)
virtual void paintItem(QPainter *p, const QColorGroup &c)
static bool singleClick()
virtual void contentsDragLeaveEvent(QDragLeaveEvent *e)
void cancelPendingHeldSignal()
This method allows to handle correctly cases where a subclass needs the held() signal to not be trigg...
virtual void contentsDropEvent(QDropEvent *e)
void executed(Q3IconViewItem *item)
This signal is emitted whenever the user executes an iconview item.
virtual void takeItem(Q3IconViewItem *item)
Reimplemented for held() signal behavior internal purposes.
QRect boundingRect() const
static KGlobalSettings * self()
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
virtual void focusOutEvent(QFocusEvent *fe)
void paintText(QPainter *p, const QColorGroup &c)
virtual void leaveEvent(QEvent *e)
virtual void contentsMouseReleaseEvent(QMouseEvent *e)
virtual void wheelEvent(QWheelEvent *e)
virtual void contentsDragEnterEvent(QDragEnterEvent *e)
void emitExecute(Q3IconViewItem *item, const QPoint &pos)
void held(Q3IconViewItem *item)
This signal is emitted whenever the user hold something on an iconview during a drag'n'drop.
void paintPixmap(QPainter *p, const QColorGroup &c)
void slotAutoSelect()
Auto selection happend.
void slotOnItem(Q3IconViewItem *item)
virtual void calcRect(const QString &text_=QString())
virtual void setFont(const QFont &)
Reimplemented for internal purposes.
void setMode(Mode m)
Sets the mode to Execute or Select.
static bool changeCursorOverIcon()
virtual void contentsMouseDoubleClickEvent(QMouseEvent *e)
A variant of QIconView that honors KDE's system-wide settings.
virtual ~K3IconViewItem()
Mode
K3IconView has two different operating modes.
void drawText(QPainter *painter, int x, int y, int flags=Qt::AlignLeft) const
K3IconView(QWidget *parent=0, const char *name=0, Qt::WindowFlags f=0)
static int autoSelectDelay()
void doubleClicked(Q3IconViewItem *item, const QPoint &pos)
This signal gets emitted whenever the user double clicks into the iconview.
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
virtual void contentsDragMoveEvent(QDragMoveEvent *e)
void setIconTextHeight(int n)
Set the maximum number of lines that will be used to display icon text.
static KWordWrap * formatText(QFontMetrics &fm, const QRect &r, int flags, const QString &str, int len=-1)
void setPixmapSize(const QSize &size)
Using this function, you can specify a custom size for the pixmap.
virtual void contentsMousePressEvent(QMouseEvent *e)
int iconTextHeight() const
void updateDragHoldItem(QDropEvent *e)