summaryrefslogtreecommitdiffstats
path: root/src/widgets/tqiconview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/tqiconview.cpp')
-rw-r--r--src/widgets/tqiconview.cpp6671
1 files changed, 6671 insertions, 0 deletions
diff --git a/src/widgets/tqiconview.cpp b/src/widgets/tqiconview.cpp
new file mode 100644
index 000000000..4ccecfd21
--- /dev/null
+++ b/src/widgets/tqiconview.cpp
@@ -0,0 +1,6671 @@
+/****************************************************************************
+**
+** Implementation of TQIconView widget class
+**
+** Created : 990707
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the iconview module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "ntqglobal.h"
+#if defined(Q_CC_BOR)
+// needed for qsort() because of a std namespace problem on Borland
+#include "qplatformdefs.h"
+#endif
+
+#include "tqiconview.h"
+
+#ifndef TQT_NO_ICONVIEW
+
+#include "ntqfontmetrics.h"
+#include "ntqpainter.h"
+#include "ntqevent.h"
+#include "ntqpalette.h"
+#include "ntqmime.h"
+#include "tqimage.h"
+#include "ntqpen.h"
+#include "ntqbrush.h"
+#include "ntqtimer.h"
+#include "ntqcursor.h"
+#include "ntqapplication.h"
+#include "tqtextedit.h"
+#include "ntqmemarray.h"
+#include "tqptrlist.h"
+#include "ntqvbox.h"
+#include "ntqtooltip.h"
+#include "ntqbitmap.h"
+#include "ntqpixmapcache.h"
+#include "tqptrdict.h"
+#include "tqstringlist.h"
+#include "ntqcleanuphandler.h"
+#include "private/qrichtext_p.h"
+#include "ntqstyle.h"
+
+#include <limits.h>
+#include <stdlib.h>
+
+#define RECT_EXTENSION 300
+
+static const char * const unknown_xpm[] = {
+ "32 32 11 1",
+ "c c #ffffff",
+ "g c #c0c0c0",
+ "a c #c0ffc0",
+ "h c #a0a0a4",
+ "d c #585858",
+ "f c #303030",
+ "i c #400000",
+ "b c #00c000",
+ "e c #000000",
+ "# c #000000",
+ ". c None",
+ "...###..........................",
+ "...#aa##........................",
+ ".###baaa##......................",
+ ".#cde#baaa##....................",
+ ".#cccdeebaaa##..##f.............",
+ ".#cccccdeebaaa##aaa##...........",
+ ".#cccccccdeebaaaaaaaa##.........",
+ ".#cccccccccdeebaaaaaaa#.........",
+ ".#cccccgcgghhebbbbaaaaa#........",
+ ".#ccccccgcgggdebbbbbbaa#........",
+ ".#cccgcgcgcgghdeebiebbba#.......",
+ ".#ccccgcggggggghdeddeeba#.......",
+ ".#cgcgcgcggggggggghghdebb#......",
+ ".#ccgcggggggggghghghghd#b#......",
+ ".#cgcgcggggggggghghghhd#b#......",
+ ".#gcggggggggghghghhhhhd#b#......",
+ ".#cgcggggggggghghghhhhd#b#......",
+ ".#ggggggggghghghhhhhhhdib#......",
+ ".#gggggggggghghghhhhhhd#b#......",
+ ".#hhggggghghghhhhhhhhhd#b#......",
+ ".#ddhhgggghghghhhhhhhhd#b#......",
+ "..##ddhhghghhhhhhhhhhhdeb#......",
+ "....##ddhhhghhhhhhhhhhd#b#......",
+ "......##ddhhhhhhhhhhhhd#b#......",
+ "........##ddhhhhhhhhhhd#b#......",
+ "..........##ddhhhhhhhhd#b#......",
+ "............##ddhhhhhhd#b###....",
+ "..............##ddhhhhd#b#####..",
+ "................##ddhhd#b######.",
+ "..................##dddeb#####..",
+ "....................##d#b###....",
+ "......................####......"};
+
+static TQPixmap *unknown_icon = 0;
+static TQPixmap *qiv_buffer_pixmap = 0;
+#if !defined(TQ_WS_X11)
+static TQPixmap *qiv_selection = 0;
+#endif
+static bool optimize_layout = FALSE;
+
+static TQCleanupHandler<TQPixmap> qiv_cleanup_pixmap;
+
+#if !defined(TQ_WS_X11)
+static void createSelectionPixmap( const TQColorGroup &cg )
+{
+ TQBitmap m( 2, 2 );
+ m.fill( TQt::color1 );
+ TQPainter p( &m );
+ p.setPen( TQt::color0 );
+ for ( int j = 0; j < 2; ++j ) {
+ p.drawPoint( j % 2, j );
+ }
+ p.end();
+
+ qiv_selection = new TQPixmap( 2, 2 );
+ qiv_cleanup_pixmap.add( &qiv_selection );
+ qiv_selection->fill( TQt::color0 );
+ qiv_selection->setMask( m );
+ qiv_selection->fill( cg.highlight() );
+}
+#endif
+
+static TQPixmap *get_qiv_buffer_pixmap( const TQSize &s )
+{
+ if ( !qiv_buffer_pixmap ) {
+ qiv_buffer_pixmap = new TQPixmap( s );
+ qiv_cleanup_pixmap.add( &qiv_buffer_pixmap );
+ return qiv_buffer_pixmap;
+ }
+
+ qiv_buffer_pixmap->resize( s );
+ return qiv_buffer_pixmap;
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+
+class TQ_EXPORT TQIconDragData
+{
+public:
+ TQIconDragData();
+ TQIconDragData( const TQRect &ir, const TQRect &tr );
+
+ TQRect pixmapRect() const;
+ TQRect textRect() const;
+
+ void setPixmapRect( const TQRect &r );
+ void setTextRect( const TQRect &r );
+
+ TQRect iconRect_, textRect_;
+ TQString key_;
+
+ bool operator==( const TQIconDragData &i ) const;
+};
+
+class TQ_EXPORT TQIconDragDataItem
+{
+public:
+ TQIconDragDataItem() {}
+ TQIconDragDataItem( const TQIconDragItem &i1, const TQIconDragData &i2 ) : data( i1 ), item( i2 ) {}
+ TQIconDragItem data;
+ TQIconDragData item;
+ bool operator== ( const TQIconDragDataItem& ) const;
+};
+
+class TQIconDragPrivate
+{
+public:
+ TQValueList<TQIconDragDataItem> items;
+ static bool decode( TQMimeSource* e, TQValueList<TQIconDragDataItem> &lst );
+};
+
+#endif
+
+class TQIconViewToolTip;
+
+class TQIconViewPrivate
+{
+public:
+ TQIconViewItem *firstItem, *lastItem;
+ uint count;
+ TQIconView::SelectionMode selectionMode;
+ TQIconViewItem *currentItem, *tmpCurrentItem, *highlightedItem,
+ *startDragItem, *pressedItem, *selectAnchor, *renamingItem;
+ TQRect *rubber;
+ TQPixmap *backBuffer;
+ TQTimer *scrollTimer, *adjustTimer, *updateTimer, *inputTimer,
+ *fullRedrawTimer;
+ int rastX, rastY, spacing;
+ int dragItems;
+ TQPoint oldDragPos;
+ TQIconView::Arrangement arrangement;
+ TQIconView::ResizeMode resizeMode;
+ TQSize oldSize;
+#ifndef TQT_NO_DRAGANDDROP
+ TQValueList<TQIconDragDataItem> iconDragData;
+#endif
+ int numDragItems, cachedW, cachedH;
+ int maxItemWidth, maxItemTextLength;
+ TQPoint dragStart;
+ TQString currInputString;
+ TQIconView::ItemTextPos itemTextPos;
+#ifndef TQT_NO_CURSOR
+ TQCursor oldCursor;
+#endif
+ int cachedContentsX, cachedContentsY;
+ TQBrush itemTextBrush;
+ TQRegion clipRegion;
+ TQPoint dragStartPos;
+ TQFontMetrics *fm;
+ int minLeftBearing, minRightBearing;
+ int rubberStartX, rubberStartY;
+
+ uint mousePressed :1;
+ uint cleared :1;
+ uint dropped :1;
+ uint clearing :1;
+ uint oldDragAcceptAction :1;
+ uint isIconDrag :1;
+ uint drawDragShapes :1;
+ uint dirty :1;
+ uint rearrangeEnabled :1;
+ uint reorderItemsWhenInsert :1;
+ uint drawAllBack :1;
+ uint resortItemsWhenInsert :1;
+ uint sortDirection :1;
+ uint wordWrapIconText :1;
+ uint containerUpdateLocked :1;
+ uint firstSizeHint : 1;
+ uint showTips :1;
+ uint pressedSelected :1;
+ uint canStartRubber :1;
+ uint dragging :1;
+ uint drawActiveSelection :1;
+ uint inMenuMode :1;
+
+ TQIconViewToolTip *toolTip;
+ TQPixmapCache maskCache;
+ TQPixmap *backrubber;
+ TQPtrDict<TQIconViewItem> selectedItems;
+
+ struct ItemContainer {
+ ItemContainer( ItemContainer *pr, ItemContainer *nx, const TQRect &r )
+ : p( pr ), n( nx ), rect( r ) {
+ items.setAutoDelete( FALSE );
+ if ( p )
+ p->n = this;
+ if ( n )
+ n->p = this;
+ }
+ ItemContainer *p, *n;
+ TQRect rect;
+ TQPtrList<TQIconViewItem> items;
+ } *firstContainer, *lastContainer;
+
+ struct SortableItem {
+ TQIconViewItem *item;
+ };
+};
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+#ifdef Q_OS_TEMP
+static int _cdecl cmpIconViewItems( const void *n1, const void *n2 )
+#else
+static int cmpIconViewItems( const void *n1, const void *n2 )
+#endif
+{
+ if ( !n1 || !n2 )
+ return 0;
+
+ TQIconViewPrivate::SortableItem *i1 = (TQIconViewPrivate::SortableItem *)n1;
+ TQIconViewPrivate::SortableItem *i2 = (TQIconViewPrivate::SortableItem *)n2;
+
+ return i1->item->compare( i2->item );
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+
+#ifndef TQT_NO_TOOLTIP
+class TQIconViewToolTip : public TQToolTip
+{
+public:
+ TQIconViewToolTip( TQWidget *parent, TQIconView *iv );
+ virtual ~TQIconViewToolTip();
+
+ void maybeTip( const TQPoint &pos );
+
+private:
+ TQIconView *view;
+};
+
+TQIconViewToolTip::TQIconViewToolTip( TQWidget *parent, TQIconView *iv )
+ : TQToolTip( parent ), view( iv )
+{
+}
+
+TQIconViewToolTip::~TQIconViewToolTip()
+{
+}
+
+void TQIconViewToolTip::maybeTip( const TQPoint &pos )
+{
+ if ( !parentWidget() || !view || view->wordWrapIconText() || !view->showToolTips() )
+ return;
+
+ TQIconViewItem *item = view->findItem( view->viewportToContents( pos ) );
+ if ( !item || item->tmpText == item->itemText )
+ return;
+
+ TQRect r( item->textRect( FALSE ) );
+ TQRect r2 = item->pixmapRect( FALSE );
+ /* this probably should be | r, but TQToolTip does not handle that
+ * well */
+
+ // At this point the rectangle is too small (it is the width of the icon)
+ // since we need it to be bigger than that, extend it here.
+ r.setWidth( view->d->fm->boundingRect( item->itemText ).width() + 4 );
+ r = TQRect( view->contentsToViewport( TQPoint( r.x(), r.y() ) ), TQSize( r.width(), r.height() ) );
+
+ r2 = TQRect( view->contentsToViewport( TQPoint( r2.x(), r2.y() ) ), TQSize( r2.width(), r2.height() ) );
+ tip( r2, item->itemText, r );
+}
+#endif
+
+
+class TQIconViewItemPrivate
+{
+public:
+ TQIconViewPrivate::ItemContainer *container1, *container2;
+};
+
+#ifndef TQT_NO_TEXTEDIT
+
+class TQIconViewItemLineEdit : public TQTextEdit
+{
+ friend class TQIconViewItem;
+
+public:
+ TQIconViewItemLineEdit( const TQString &text, TQWidget *parent, TQIconViewItem *theItem, const char* name=0 );
+
+protected:
+ void keyPressEvent( TQKeyEvent *e );
+ void focusOutEvent( TQFocusEvent *e );
+
+protected:
+ TQIconViewItem *item;
+ TQString startText;
+private:
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQIconViewItemLineEdit( const TQIconViewItemLineEdit & );
+ TQIconViewItemLineEdit &operator=( const TQIconViewItemLineEdit & );
+#endif
+
+};
+
+TQIconViewItemLineEdit::TQIconViewItemLineEdit( const TQString &text, TQWidget *parent,
+ TQIconViewItem *theItem, const char *name )
+ : TQTextEdit( parent, name ), item( theItem ), startText( text )
+{
+ setFrameStyle( TQFrame::Plain | TQFrame::Box );
+ setLineWidth( 1 );
+
+ setHScrollBarMode( AlwaysOff );
+ setVScrollBarMode( AlwaysOff );
+
+ setWordWrap( WidgetWidth );
+ setWrapColumnOrWidth( item->iconView()->maxItemWidth() -
+ ( item->iconView()->itemTextPos() == TQIconView::Bottom ?
+ 0 : item->pixmapRect().width() ) );
+ document()->formatter()->setAllowBreakInWords( TRUE );
+ resize( 200, 200 ); // ### some size, there should be a forceReformat()
+ setTextFormat( PlainText );
+ setText( text );
+ setAlignment( TQt::AlignCenter );
+
+ resize( wrapColumnOrWidth() + 2, heightForWidth( wrapColumnOrWidth() ) + 2 );
+}
+
+void TQIconViewItemLineEdit::keyPressEvent( TQKeyEvent *e )
+{
+ if ( e->key() == Key_Escape ) {
+ item->TQIconViewItem::setText( startText );
+ item->cancelRenameItem();
+ } else if ( e->key() == Key_Enter ||
+ e->key() == Key_Return ) {
+ item->renameItem();
+ } else {
+ TQTextEdit::keyPressEvent( e );
+ sync();
+ resize( width(), document()->height() + 2 );
+
+ }
+}
+
+void TQIconViewItemLineEdit::focusOutEvent( TQFocusEvent *e )
+{
+ Q_UNUSED(e) // I need this to get rid of a Borland warning
+ if ( e->reason() != TQFocusEvent::Popup )
+ item->cancelRenameItem();
+}
+#endif
+
+#ifndef TQT_NO_DRAGANDDROP
+
+
+/*!
+ \class TQIconDragItem tqiconview.h
+ \ingroup draganddrop
+
+ \brief The TQIconDragItem class encapsulates a drag item.
+
+ \module iconview
+
+ The TQIconDrag class uses a list of TQIconDragItems to support drag
+ and drop operations.
+
+ In practice a TQIconDragItem object (or an object of a class derived
+ from TQIconDragItem) is created for each icon view item which is
+ dragged. Each of these TQIconDragItems is stored in a TQIconDrag
+ object.
+
+ See TQIconView::dragObject() for more information.
+
+ See the \l fileiconview/qfileiconview.cpp and
+ \l iconview/simple_dd/main.cpp examples.
+*/
+
+/*!
+ Constructs a TQIconDragItem with no data.
+*/
+
+TQIconDragItem::TQIconDragItem()
+ : ba( (int)strlen( "no data" ) )
+{
+ memcpy( ba.data(), "no data", strlen( "no data" ) );
+}
+
+/*!
+ Destructor.
+*/
+
+TQIconDragItem::~TQIconDragItem()
+{
+}
+
+/*!
+ Returns the data contained in the TQIconDragItem.
+*/
+
+TQByteArray TQIconDragItem::data() const
+{
+ return ba;
+}
+
+/*!
+ Sets the data for the TQIconDragItem to the data stored in the
+ TQByteArray \a d.
+*/
+
+void TQIconDragItem::setData( const TQByteArray &d )
+{
+ ba = d;
+}
+
+/*!
+ \reimp
+*/
+
+bool TQIconDragItem::operator==( const TQIconDragItem &i ) const
+{
+ return ba == i.ba;
+}
+
+/*!
+ \reimp
+*/
+
+bool TQIconDragDataItem::operator==( const TQIconDragDataItem &i ) const
+{
+ return ( i.item == item &&
+ i.data == data );
+}
+
+/*!
+ \reimp
+*/
+
+bool TQIconDragData::operator==( const TQIconDragData &i ) const
+{
+ return key_ == i.key_;
+}
+
+
+/*!
+ \class TQIconDrag tqiconview.h
+
+ \brief The TQIconDrag class supports drag and drop operations
+ within a TQIconView.
+
+ \ingroup draganddrop
+ \module iconview
+
+ A TQIconDrag object is used to maintain information about the
+ positions of dragged items and the data associated with the
+ dragged items. TQIconViews are able to use this information to
+ paint the dragged items in the correct positions. Internally
+ TQIconDrag stores the data associated with drag items in
+ TQIconDragItem objects.
+
+ If you want to use the extended drag-and-drop functionality of
+ TQIconView, create a TQIconDrag object in a reimplementation of
+ TQIconView::dragObject(). Then create a TQIconDragItem for each item
+ which should be dragged, set the data it represents with
+ TQIconDragItem::setData(), and add each TQIconDragItem to the drag
+ object using append().
+
+ The data in TQIconDragItems is stored in a TQByteArray and is
+ mime-typed (see TQMimeSource and the
+ \link http://doc.trolltech.com/dnd.html Drag and Drop\endlink
+ overview). If you want to use your own mime-types derive a class
+ from TQIconDrag and reimplement format(), encodedData() and
+ canDecode().
+
+ The fileiconview example program demonstrates the use of the
+ TQIconDrag class including subclassing and reimplementing
+ dragObject(), format(), encodedData() and canDecode(). See the files
+ \c qt/examples/fileiconview/qfileiconview.h and
+ \c qt/examples/fileiconview/qfileiconview.cpp.
+
+ \sa TQMimeSource::format()
+*/
+// ### consider using \dontinclude and friends there
+// ### Not here in the module overview instead...
+
+/*!
+ Constructs a drag object called \a name, which is a child of \a
+ dragSource.
+
+ Note that the drag object will be deleted when \a dragSource is deleted.
+*/
+
+TQIconDrag::TQIconDrag( TQWidget * dragSource, const char* name )
+ : TQDragObject( dragSource, name )
+{
+ d = new TQIconDragPrivate;
+}
+
+/*!
+ Destructor.
+*/
+
+TQIconDrag::~TQIconDrag()
+{
+ delete d;
+}
+
+/*!
+ Append the TQIconDragItem, \a i, to the TQIconDrag object's list of
+ items. You must also supply the geometry of the pixmap, \a pr, and
+ the textual caption, \a tr.
+
+ \sa TQIconDragItem
+*/
+
+void TQIconDrag::append( const TQIconDragItem &i, const TQRect &pr, const TQRect &tr )
+{
+ d->items.append( TQIconDragDataItem( i, TQIconDragData( pr, tr ) ) );
+}
+
+/*!
+ \reimp
+*/
+
+const char* TQIconDrag::format( int i ) const
+{
+ if ( i == 0 )
+ return "application/x-qiconlist";
+ return 0;
+}
+
+/*!
+ Returns the encoded data of the drag object if \a mime is
+ application/x-qiconlist.
+*/
+
+TQByteArray TQIconDrag::encodedData( const char* mime ) const
+{
+ if ( d->items.count() <= 0 || TQString( mime ) !=
+ "application/x-qiconlist" )
+ return TQByteArray();
+
+ TQValueList<TQIconDragDataItem>::ConstIterator it = d->items.begin();
+ TQString s;
+ for ( ; it != d->items.end(); ++it ) {
+ TQString k( "%1$@@$%2$@@$%3$@@$%4$@@$%5$@@$%6$@@$%7$@@$%8$@@$" );
+ k = k.arg( (*it).item.pixmapRect().x() ).arg(
+ (*it).item.pixmapRect().y() ).arg( (*it).item.pixmapRect().width() ).
+ arg( (*it).item.pixmapRect().height() ).arg(
+ (*it).item.textRect().x() ).arg( (*it).item.textRect().y() ).
+ arg( (*it).item.textRect().width() ).arg(
+ (*it).item.textRect().height() );
+ k += TQString( (*it).data.data() ) + "$@@$";
+ s += k;
+ }
+
+ TQByteArray a( s.length() + 1 );
+ memcpy( a.data(), s.latin1(), a.size() );
+ return a;
+}
+
+/*!
+ Returns TRUE if \a e can be decoded by the TQIconDrag, otherwise
+ return FALSE.
+*/
+
+bool TQIconDrag::canDecode( TQMimeSource* e )
+{
+ if ( e->provides( "application/x-qiconlist" ) )
+ return TRUE;
+ return FALSE;
+}
+
+/*!
+ Decodes the data which is stored (encoded) in \a e and, if
+ successful, fills the \a list of icon drag items with the decoded
+ data. Returns TRUE if there was some data, FALSE otherwise.
+*/
+
+bool TQIconDragPrivate::decode( TQMimeSource* e, TQValueList<TQIconDragDataItem> &lst )
+{
+ TQByteArray ba = e->encodedData( "application/x-qiconlist" );
+ if ( ba.size() ) {
+ lst.clear();
+ TQString s = ba.data();
+ TQIconDragDataItem item;
+ TQRect ir, tr;
+ TQStringList l = TQStringList::split( "$@@$", s );
+
+ int i = 0;
+ TQStringList::Iterator it = l.begin();
+ for ( ; it != l.end(); ++it ) {
+ if ( i == 0 ) {
+ ir.setX( ( *it ).toInt() );
+ } else if ( i == 1 ) {
+ ir.setY( ( *it ).toInt() );
+ } else if ( i == 2 ) {
+ ir.setWidth( ( *it ).toInt() );
+ } else if ( i == 3 ) {
+ ir.setHeight( ( *it ).toInt() );
+ } else if ( i == 4 ) {
+ tr.setX( ( *it ).toInt() );
+ } else if ( i == 5 ) {
+ tr.setY( ( *it ).toInt() );
+ } else if ( i == 6 ) {
+ tr.setWidth( ( *it ).toInt() );
+ } else if ( i == 7 ) {
+ tr.setHeight( ( *it ).toInt() );
+ } else if ( i == 8 ) {
+ TQByteArray d( ( *it ).length() );
+ memcpy( d.data(), ( *it ).latin1(), ( *it ).length() );
+ item.item.setPixmapRect( ir );
+ item.item.setTextRect( tr );
+ item.data.setData( d );
+ lst.append( item );
+ }
+ ++i;
+ if ( i > 8 )
+ i = 0;
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+TQIconDragData::TQIconDragData()
+ : iconRect_(), textRect_()
+{
+}
+
+TQIconDragData::TQIconDragData( const TQRect &ir, const TQRect &tr )
+ : iconRect_( ir ), textRect_( tr )
+{
+}
+
+TQRect TQIconDragData::textRect() const
+{
+ return textRect_;
+}
+
+TQRect TQIconDragData::pixmapRect() const
+{
+ return iconRect_;
+}
+
+void TQIconDragData::setPixmapRect( const TQRect &r )
+{
+ iconRect_ = r;
+}
+
+void TQIconDragData::setTextRect( const TQRect &r )
+{
+ textRect_ = r;
+}
+
+#endif
+
+
+/*!
+ \class TQIconViewItem tqiconview.h
+ \brief The TQIconViewItem class provides a single item in a TQIconView.
+
+ \ingroup advanced
+ \module iconview
+
+ A TQIconViewItem contains an icon, a string and optionally a sort
+ key, and can display itself in a TQIconView.
+ The class is designed to be very similar to TQListView and TQListBox
+ in use, both via instantiation and subclassing.
+
+ The simplest way to create a TQIconViewItem and insert it into a
+ TQIconView is to construct the item passing the constructor a
+ pointer to the icon view, a string and an icon:
+
+ \code
+ (void) new TQIconViewItem(
+ iconView, // A pointer to a TQIconView
+ "This is the text of the item",
+ aPixmap );
+ \endcode
+
+ By default the text of an icon view item may not be edited by the
+ user but calling setRenameEnabled(TRUE) will allow the user to
+ perform in-place editing of the item's text.
+
+ When the icon view is deleted all items in it are deleted
+ automatically.
+
+ The TQIconView::firstItem() and TQIconViewItem::nextItem() functions
+ provide a means of iterating over all the items in a TQIconView:
+
+ \code
+ TQIconViewItem *item;
+ for ( item = iconView->firstItem(); item; item = item->nextItem() )
+ do_something_with( item );
+ \endcode
+
+ The item's icon view is available from iconView(), and its
+ position in the icon view from index().
+
+ The item's selection status is available from isSelected() and is
+ set and controlled by setSelected() and isSelectable().
+
+ The text and icon can be set with setText() and setPixmap() and
+ retrieved with text() and pixmap(). The item's sort key defaults
+ to text() but may be set with setKey() and retrieved with key().
+ The comparison function, compare() uses key().
+
+ Items may be repositioned with move() and moveBy(). An item's
+ geometry is available from rect(), x(), y(), width(), height(),
+ size(), pos(), textRect() and pixmapRect(). You can also test
+ against the position of a point with contains() and intersects().
+
+ To remove an item from an icon view, just delete the item. The
+ TQIconViewItem destructor removes it cleanly from its icon view.
+
+ Because the icon view is designed to use drag-and-drop, the icon
+ view item also has functions for drag-and-drop which may be
+ reimplemented.
+
+ \target pixmap-size-limit
+ <b>Note:</b> Pixmaps with individual dimensions larger than 300 pixels may
+ not be displayed properly, depending on the \link TQIconView::Arrangement
+ arrangement in use\endlink. For example, pixmaps wider than 300 pixels
+ will not be arranged correctly if the icon view uses a
+ \l TQIconView::TopToBottom arrangement, and pixmaps taller than 300 pixels
+ will not be arranged correctly if the icon view uses a
+ \l TQIconView::LeftToRight arrangement.
+*/
+
+/*!
+ Constructs a TQIconViewItem and inserts it into icon view \a parent
+ with no text and a default icon.
+*/
+
+TQIconViewItem::TQIconViewItem( TQIconView *parent )
+ : view( parent ), itemText(), itemIcon( unknown_icon )
+{
+ init();
+}
+
+/*!
+ Constructs a TQIconViewItem and inserts it into the icon view \a
+ parent with no text and a default icon, after the icon view item
+ \a after.
+*/
+
+TQIconViewItem::TQIconViewItem( TQIconView *parent, TQIconViewItem *after )
+ : view( parent ), itemText(), itemIcon( unknown_icon ),
+ prev( 0 ), next( 0 )
+{
+ init( after );
+}
+
+/*!
+ Constructs an icon view item and inserts it into the icon view \a
+ parent using \a text as the text and a default icon.
+*/
+
+TQIconViewItem::TQIconViewItem( TQIconView *parent, const TQString &text )
+ : view( parent ), itemText( text ), itemIcon( unknown_icon )
+{
+ init( 0 );
+}
+
+/*!
+ Constructs an icon view item and inserts it into the icon view \a
+ parent using \a text as the text and a default icon, after the
+ icon view item \a after.
+*/
+
+TQIconViewItem::TQIconViewItem( TQIconView *parent, TQIconViewItem *after,
+ const TQString &text )
+ : view( parent ), itemText( text ), itemIcon( unknown_icon )
+{
+ init( after );
+}
+
+/*!
+ Constructs an icon view item and inserts it into the icon view \a
+ parent using \a text as the text and \a icon as the icon.
+*/
+
+TQIconViewItem::TQIconViewItem( TQIconView *parent, const TQString &text,
+ const TQPixmap &icon )
+ : view( parent ),
+ itemText( text ), itemIcon( new TQPixmap( icon ) )
+{
+ init( 0 );
+}
+
+
+/*!
+ Constructs an icon view item and inserts it into the icon view \a
+ parent using \a text as the text and \a icon as the icon, after
+ the icon view item \a after.
+
+ \sa setPixmap()
+*/
+
+TQIconViewItem::TQIconViewItem( TQIconView *parent, TQIconViewItem *after,
+ const TQString &text, const TQPixmap &icon )
+ : view( parent ), itemText( text ), itemIcon( new TQPixmap( icon ) )
+{
+ init( after );
+}
+
+/*!
+ Constructs an icon view item and inserts it into the icon view \a
+ parent using \a text as the text and \a picture as the icon.
+*/
+
+#ifndef TQT_NO_PICTURE
+TQIconViewItem::TQIconViewItem( TQIconView *parent, const TQString &text,
+ const TQPicture &picture )
+ : view( parent ), itemText( text ), itemIcon( 0 )
+{
+ init( 0, new TQPicture( picture ) );
+}
+
+/*!
+ Constructs an icon view item and inserts it into the icon view \a
+ parent using \a text as the text and \a picture as the icon, after
+ the icon view item \a after.
+*/
+
+TQIconViewItem::TQIconViewItem( TQIconView *parent, TQIconViewItem *after,
+ const TQString &text, const TQPicture &picture )
+ : view( parent ), itemText( text ), itemIcon( 0 )
+{
+ init( after, new TQPicture( picture ) );
+}
+#endif
+
+/*!
+ This private function initializes the icon view item and inserts it
+ into the icon view.
+*/
+
+void TQIconViewItem::init( TQIconViewItem *after
+#ifndef TQT_NO_PICTURE
+ , TQPicture *pic
+#endif
+ )
+{
+ d = new TQIconViewItemPrivate;
+ d->container1 = 0;
+ d->container2 = 0;
+ prev = next = 0;
+ allow_rename = FALSE;
+ allow_drag = TRUE;
+ allow_drop = TRUE;
+ visible = TRUE;
+ selected = FALSE;
+ selectable = TRUE;
+#ifndef TQT_NO_TEXTEDIT
+ renameBox = 0;
+#endif
+#ifndef TQT_NO_PICTURE
+ itemPic = pic;
+#endif
+ if ( view ) {
+ itemKey = itemText;
+ dirty = TRUE;
+ wordWrapDirty = TRUE;
+ itemRect = TQRect( -1, -1, 0, 0 );
+ calcRect();
+ view->insertItem( this, after );
+ }
+}
+
+/*!
+ Destroys the icon view item and tells the parent icon view that
+ the item has been destroyed.
+*/
+
+TQIconViewItem::~TQIconViewItem()
+{
+#ifndef TQT_NO_TEXTEDIT
+ removeRenameBox();
+#endif
+ if ( view && !view->d->clearing )
+ view->takeItem( this );
+ view = 0;
+ if ( itemIcon && itemIcon->serialNumber() != unknown_icon->serialNumber() )
+ delete itemIcon;
+#ifndef TQT_NO_PICTURE
+ delete itemPic;
+#endif
+ delete d;
+}
+
+int TQIconViewItem::RTTI = 0;
+
+/*!
+ Returns 0.
+
+ Make your derived classes return their own values for rtti(), so
+ that you can distinguish between icon view item types. You should
+ use values greater than 1000, preferably a large random number, to
+ allow for extensions to this class.
+*/
+
+int TQIconViewItem::rtti() const
+{
+ return RTTI;
+}
+
+/*!
+ If \a b is TRUE, the item is made visible; otherwise it is hidden.
+*/
+
+void TQIconViewItem::setVisible( bool b )
+{
+ if ( b == (bool)visible )
+ return;
+ TQIconView *iv = iconView();
+ if ( !iv )
+ return;
+ visible = b;
+ if ( iv )
+ iv->updateContents();
+}
+
+/*!
+ Returns TRUE if the item is visible; otherwise returns FALSE.
+
+ \sa setVisible()
+*/
+
+bool TQIconViewItem::isVisible() const
+{
+ return (bool)visible;
+}
+
+/*!
+ Sets \a text as the text of the icon view item. This function
+ might be a no-op if you reimplement text().
+
+ \sa text()
+*/
+
+void TQIconViewItem::setText( const TQString &text )
+{
+ if ( text == itemText )
+ return;
+
+ wordWrapDirty = TRUE;
+ itemText = text;
+ if ( itemKey.isEmpty() )
+ itemKey = itemText;
+
+ TQRect oR = rect();
+ calcRect();
+ oR = oR.unite( rect() );
+
+ if ( view ) {
+ if ( TQRect( view->contentsX(), view->contentsY(),
+ view->visibleWidthSB(), view->visibleHeightSB() ).
+ intersects( oR ) )
+ view->repaintContents( oR.x() - 1, oR.y() - 1,
+ oR.width() + 2, oR.height() + 2, FALSE );
+ }
+}
+
+/*!
+ Sets \a k as the sort key of the icon view item. By default
+ text() is used for sorting.
+
+ \sa compare()
+*/
+
+void TQIconViewItem::setKey( const TQString &k )
+{
+ if ( k == itemKey )
+ return;
+
+ itemKey = k;
+}
+
+/*!
+ Sets \a icon as the item's icon in the icon view. This function
+ might be a no-op if you reimplement pixmap().
+
+ <b>Note:</b> Pixmaps with individual dimensions larger than 300 pixels may
+ not be displayed properly, depending on the \link TQIconView::Arrangement
+ arrangement in use\endlink. See the \link #pixmap-size-limit main class
+ documentation\endlink for details.
+
+ \sa pixmap()
+*/
+
+void TQIconViewItem::setPixmap( const TQPixmap &icon )
+{
+ if (isVisible() == FALSE)
+ return;
+
+ if ( itemIcon && itemIcon == unknown_icon )
+ itemIcon = 0;
+
+ if ( itemIcon )
+ *itemIcon = icon;
+ else
+ itemIcon = new TQPixmap( icon );
+ TQRect oR = rect();
+ calcRect();
+ oR = oR.unite( rect() );
+
+ if ( view ) {
+ if ( TQRect( view->contentsX(), view->contentsY(),
+ view->visibleWidthSB(), view->visibleHeightSB() ).
+ intersects( oR ) )
+ view->repaintContents( oR.x() - 1, oR.y() - 1,
+ oR.width() + 2, oR.height() + 2, FALSE );
+ }
+}
+
+/*!
+ Sets \a icon as the item's icon in the icon view. This function
+ might be a no-op if you reimplement picture().
+
+ \sa picture()
+*/
+
+#ifndef TQT_NO_PICTURE
+void TQIconViewItem::setPicture( const TQPicture &icon )
+{
+ // clear assigned pixmap if any
+ if ( itemIcon ) {
+ if ( itemIcon == unknown_icon ) {
+ itemIcon = 0;
+ } else {
+ delete itemIcon;
+ itemIcon = 0;
+ }
+ }
+ if ( itemPic )
+ delete itemPic;
+ itemPic = new TQPicture( icon );
+
+ TQRect oR = rect();
+ calcRect();
+ oR = oR.unite( rect() );
+
+ if ( view ) {
+ if ( TQRect( view->contentsX(), view->contentsY(),
+ view->visibleWidthSB(), view->visibleHeightSB() ).
+ intersects( oR ) )
+ view->repaintContents( oR.x() - 1, oR.y() - 1,
+ oR.width() + 2, oR.height() + 2, FALSE );
+ }
+}
+#endif
+
+/*!
+ \overload
+
+ Sets \a text as the text of the icon view item. If \a recalc is
+ TRUE, the icon view's layout is recalculated. If \a redraw is TRUE
+ (the default), the icon view is repainted.
+
+ \sa text()
+*/
+
+void TQIconViewItem::setText( const TQString &text, bool recalc, bool redraw )
+{
+ if ( text == itemText )
+ return;
+
+ wordWrapDirty = TRUE;
+ itemText = text;
+
+ if ( recalc )
+ calcRect();
+ if ( redraw )
+ repaint();
+}
+
+/*!
+ \overload
+
+ Sets \a icon as the item's icon in the icon view. If \a recalc is
+ TRUE, the icon view's layout is recalculated. If \a redraw is TRUE
+ (the default), the icon view is repainted.
+
+ <b>Note:</b> Pixmaps with individual dimensions larger than 300 pixels may
+ not be displayed properly, depending on the \link TQIconView::Arrangement
+ arrangement in use\endlink. See the \link #pixmap-size-limit main class
+ documentation\endlink for details.
+
+ \sa pixmap()
+*/
+
+void TQIconViewItem::setPixmap( const TQPixmap &icon, bool recalc, bool redraw )
+{
+ if (isVisible() == FALSE)
+ return;
+
+ if ( itemIcon && itemIcon == unknown_icon )
+ itemIcon = 0;
+
+ if ( itemIcon )
+ *itemIcon = icon;
+ else
+ itemIcon = new TQPixmap( icon );
+
+ if ( redraw ) {
+ if ( recalc ) {
+ TQRect oR = rect();
+ calcRect();
+ oR = oR.unite( rect() );
+
+ if ( view ) {
+ if ( TQRect( view->contentsX(), view->contentsY(),
+ view->visibleWidthSB(), view->visibleHeightSB() ).
+ intersects( oR ) )
+ view->repaintContents( oR.x() - 1, oR.y() - 1,
+ oR.width() + 2, oR.height() + 2, FALSE );
+ }
+ } else {
+ repaint();
+ }
+ } else if ( recalc ) {
+ calcRect();
+ }
+}
+
+/*!
+ If \a allow is TRUE, the user can rename the icon view item by
+ clicking on the text (or pressing F2) while the item is selected
+ (in-place renaming). If \a allow is FALSE, in-place renaming is
+ not possible.
+*/
+
+void TQIconViewItem::setRenameEnabled( bool allow )
+{
+ allow_rename = (uint)allow;
+}
+
+/*!
+ If \a allow is TRUE, the icon view permits the user to drag the
+ icon view item either to another position within the icon view or
+ to somewhere outside of it. If \a allow is FALSE, the item cannot
+ be dragged.
+*/
+
+void TQIconViewItem::setDragEnabled( bool allow )
+{
+ allow_drag = (uint)allow;
+}
+
+/*!
+ If \a allow is TRUE, the icon view lets the user drop something on
+ this icon view item.
+*/
+
+void TQIconViewItem::setDropEnabled( bool allow )
+{
+ allow_drop = (uint)allow;
+}
+
+/*!
+ Returns the text of the icon view item. Normally you set the text
+ of the item with setText(), but sometimes it's inconvenient to
+ call setText() for every item; so you can subclass TQIconViewItem,
+ reimplement this function, and return the text of the item. If you
+ do this, you must call calcRect() manually each time the text
+ (and therefore its size) changes.
+
+ \sa setText()
+*/
+
+TQString TQIconViewItem::text() const
+{
+ return itemText;
+}
+
+/*!
+ Returns the key of the icon view item or text() if no key has been
+ explicitly set.
+
+ \sa setKey(), compare()
+*/
+
+TQString TQIconViewItem::key() const
+{
+ return itemKey;
+}
+
+/*!
+ Returns the icon of the icon view item if it is a pixmap, or 0 if
+ it is a picture. In the latter case use picture() instead.
+ Normally you set the pixmap of the item with setPixmap(), but
+ sometimes it's inconvenient to call setPixmap() for every item. So
+ you can subclass TQIconViewItem, reimplement this function and
+ return a pointer to the item's pixmap. If you do this, you \e must
+ call calcRect() manually each time the size of this pixmap
+ changes.
+
+ \sa setPixmap()
+*/
+
+TQPixmap *TQIconViewItem::pixmap() const
+{
+ return itemIcon;
+}
+
+/*!
+ Returns the icon of the icon view item if it is a picture, or 0 if
+ it is a pixmap. In the latter case use pixmap() instead. Normally
+ you set the picture of the item with setPicture(), but sometimes
+ it's inconvenient to call setPicture() for every item. So you can
+ subclass TQIconViewItem, reimplement this function and return a
+ pointer to the item's picture. If you do this, you \e must call
+ calcRect() manually each time the size of this picture changes.
+
+ \sa setPicture()
+*/
+
+#ifndef TQT_NO_PICTURE
+TQPicture *TQIconViewItem::picture() const
+{
+ return itemPic;
+}
+#endif
+
+/*!
+ Returns TRUE if the item can be renamed by the user with in-place
+ renaming; otherwise returns FALSE.
+
+ \sa setRenameEnabled()
+*/
+
+bool TQIconViewItem::renameEnabled() const
+{
+ return (bool)allow_rename;
+}
+
+/*!
+ Returns TRUE if the user is allowed to drag the icon view item;
+ otherwise returns FALSE.
+
+ \sa setDragEnabled()
+*/
+
+bool TQIconViewItem::dragEnabled() const
+{
+ return (bool)allow_drag;
+}
+
+/*!
+ Returns TRUE if the user is allowed to drop something onto the
+ item; otherwise returns FALSE.
+
+ \sa setDropEnabled()
+*/
+
+bool TQIconViewItem::dropEnabled() const
+{
+ return (bool)allow_drop;
+}
+
+/*!
+ Returns a pointer to this item's icon view parent.
+*/
+
+TQIconView *TQIconViewItem::iconView() const
+{
+ return view;
+}
+
+/*!
+ Returns a pointer to the previous item, or 0 if this is the first
+ item in the icon view.
+
+ \sa nextItem() TQIconView::firstItem()
+*/
+
+TQIconViewItem *TQIconViewItem::prevItem() const
+{
+ return prev;
+}
+
+/*!
+ Returns a pointer to the next item, or 0 if this is the last item
+ in the icon view.
+
+ To find the first item use TQIconView::firstItem().
+
+ Example:
+ \code
+ TQIconViewItem *item;
+ for ( item = iconView->firstItem(); item; item = item->nextItem() )
+ do_something_with( item );
+ \endcode
+
+ \sa prevItem()
+*/
+
+TQIconViewItem *TQIconViewItem::nextItem() const
+{
+ return next;
+}
+
+/*!
+ Returns the index of this item in the icon view, or -1 if an error
+ occurred.
+*/
+
+int TQIconViewItem::index() const
+{
+ if ( view )
+ return view->index( this );
+
+ return -1;
+}
+
+
+
+/*!
+ \overload
+
+ This variant is equivalent to calling the other variant with \e cb
+ set to FALSE.
+*/
+
+void TQIconViewItem::setSelected( bool s )
+{
+ setSelected( s, FALSE );
+}
+
+/*!
+ Selects or unselects the item, depending on \a s; it may also
+ unselect other items, depending on TQIconView::selectionMode() and
+ \a cb.
+
+ If \a s is FALSE, the item is unselected.
+
+ If \a s is TRUE and TQIconView::selectionMode() is \c Single, the
+ item is selected and the item previously selected is unselected.
+
+ If \a s is TRUE and TQIconView::selectionMode() is \c Extended, the
+ item is selected. If \a cb is TRUE, the selection state of the
+ other items is left unchanged. If \a cb is FALSE (the default) all
+ other items are unselected.
+
+ If \a s is TRUE and TQIconView::selectionMode() is \c Multi, the
+ item is selected.
+
+ Note that \a cb is used only if TQIconView::selectionMode() is \c
+ Extended; cb defaults to FALSE.
+
+ All items whose selection status changes repaint themselves.
+*/
+
+void TQIconViewItem::setSelected( bool s, bool cb )
+{
+ if ( !view )
+ return;
+ if ( view->selectionMode() != TQIconView::NoSelection &&
+ selectable && s != (bool)selected ) {
+
+ if ( view->d->selectionMode == TQIconView::Single && this != view->d->currentItem ) {
+ TQIconViewItem *o = view->d->currentItem;
+ if ( o && o->selected )
+ o->selected = FALSE;
+ view->d->currentItem = this;
+ if ( o )
+ o->repaint();
+ emit view->currentChanged( this );
+ }
+
+ if ( !s ) {
+ selected = FALSE;
+ } else {
+ if ( view->d->selectionMode == TQIconView::Single && view->d->currentItem ) {
+ view->d->currentItem->selected = FALSE;
+ }
+ if ( ( view->d->selectionMode == TQIconView::Extended && !cb ) ||
+ view->d->selectionMode == TQIconView::Single ) {
+ bool b = view->signalsBlocked();
+ view->blockSignals( TRUE );
+ view->selectAll( FALSE );
+ view->blockSignals( b );
+ }
+ selected = s;
+ }
+
+ repaint();
+ if ( !view->signalsBlocked() ) {
+ bool emitIt = view->d->selectionMode == TQIconView::Single && s;
+ TQIconView *v = view;
+ emit v->selectionChanged();
+ if ( emitIt )
+ emit v->selectionChanged( this );
+ }
+ }
+}
+
+/*!
+ Sets this item to be selectable if \a enable is TRUE (the default)
+ or unselectable if \a enable is FALSE.
+
+ The user is unable to select a non-selectable item using either
+ the keyboard or the mouse. (The application programmer can select
+ an item in code regardless of this setting.)
+
+ \sa isSelectable()
+*/
+
+void TQIconViewItem::setSelectable( bool enable )
+{
+ selectable = (uint)enable;
+}
+
+/*!
+ Returns TRUE if the item is selected; otherwise returns FALSE.
+
+ \sa setSelected()
+*/
+
+bool TQIconViewItem::isSelected() const
+{
+ return (bool)selected;
+}
+
+/*!
+ Returns TRUE if the item is selectable; otherwise returns FALSE.
+
+ \sa setSelectable()
+*/
+
+bool TQIconViewItem::isSelectable() const
+{
+ return (bool)selectable;
+}
+
+/*!
+ Repaints the item.
+*/
+
+void TQIconViewItem::repaint()
+{
+ if ( view )
+ view->repaintItem( this );
+}
+
+/*!
+ Moves the item to position (\a x, \a y) in the icon view (these
+ are contents coordinates).
+*/
+
+bool TQIconViewItem::move( int x, int y )
+{
+ if ( x == this->x() && y == this->y() )
+ return FALSE;
+ itemRect.setRect( x, y, itemRect.width(), itemRect.height() );
+ checkRect();
+ if ( view )
+ view->updateItemContainer( this );
+ return TRUE;
+}
+
+/*!
+ Moves the item \a dx pixels in the x-direction and \a dy pixels in
+ the y-direction.
+*/
+
+void TQIconViewItem::moveBy( int dx, int dy )
+{
+ itemRect.moveBy( dx, dy );
+ checkRect();
+ if ( view )
+ view->updateItemContainer( this );
+}
+
+/*!
+ \overload
+
+ Moves the item to the point \a pnt.
+*/
+
+bool TQIconViewItem::move( const TQPoint &pnt )
+{
+ return move( pnt.x(), pnt.y() );
+}
+
+/*!
+ \overload
+
+ Moves the item by the x, y values in point \a pnt.
+*/
+
+void TQIconViewItem::moveBy( const TQPoint &pnt )
+{
+ moveBy( pnt.x(), pnt.y() );
+}
+
+/*!
+ Returns the bounding rectangle of the item (in contents
+ coordinates).
+*/
+
+TQRect TQIconViewItem::rect() const
+{
+ return itemRect;
+}
+
+/*!
+ Returns the x-coordinate of the item (in contents coordinates).
+*/
+
+int TQIconViewItem::x() const
+{
+ return itemRect.x();
+}
+
+/*!
+ Returns the y-coordinate of the item (in contents coordinates).
+*/
+
+int TQIconViewItem::y() const
+{
+ return itemRect.y();
+}
+
+/*!
+ Returns the width of the item.
+*/
+
+int TQIconViewItem::width() const
+{
+ return TQMAX( itemRect.width(), TQApplication::globalStrut().width() );
+}
+
+/*!
+ Returns the height of the item.
+*/
+
+int TQIconViewItem::height() const
+{
+ return TQMAX( itemRect.height(), TQApplication::globalStrut().height() );
+}
+
+/*!
+ Returns the size of the item.
+*/
+
+TQSize TQIconViewItem::size() const
+{
+ return TQSize( itemRect.width(), itemRect.height() );
+}
+
+/*!
+ Returns the position of the item (in contents coordinates).
+*/
+
+TQPoint TQIconViewItem::pos() const
+{
+ return TQPoint( itemRect.x(), itemRect.y() );
+}
+
+/*!
+ Returns the bounding rectangle of the item's text.
+
+ If \a relative is TRUE, (the default), the returned rectangle is
+ relative to the origin of the item's rectangle. If \a relative is
+ FALSE, the returned rectangle is relative to the origin of the
+ icon view's contents coordinate system.
+*/
+
+TQRect TQIconViewItem::textRect( bool relative ) const
+{
+ if ( relative )
+ return itemTextRect;
+ else
+ return TQRect( x() + itemTextRect.x(), y() + itemTextRect.y(), itemTextRect.width(), itemTextRect.height() );
+}
+
+/*!
+ Returns the bounding rectangle of the item's icon.
+
+ If \a relative is TRUE, (the default), the rectangle is relative to
+ the origin of the item's rectangle. If \a relative is FALSE, the
+ returned rectangle is relative to the origin of the icon view's
+ contents coordinate system.
+*/
+
+TQRect TQIconViewItem::pixmapRect( bool relative ) const
+{
+ if ( relative )
+ return itemIconRect;
+ else
+ return TQRect( x() + itemIconRect.x(), y() + itemIconRect.y(), itemIconRect.width(), itemIconRect.height() );
+}
+
+/*!
+ Returns TRUE if the item contains the point \a pnt (in contents
+ coordinates); otherwise returns FALSE.
+*/
+
+bool TQIconViewItem::contains( const TQPoint& pnt ) const
+{
+ TQRect textArea = textRect( FALSE );
+ TQRect pixmapArea = pixmapRect( FALSE );
+ if ( iconView()->itemTextPos() == TQIconView::Bottom )
+ textArea.setTop( pixmapArea.bottom() );
+ else
+ textArea.setLeft( pixmapArea.right() );
+ return textArea.contains( pnt ) || pixmapArea.contains( pnt );
+}
+
+/*!
+ Returns TRUE if the item intersects the rectangle \a r (in
+ contents coordinates); otherwise returns FALSE.
+*/
+
+bool TQIconViewItem::intersects( const TQRect& r ) const
+{
+ return ( textRect( FALSE ).intersects( r ) ||
+ pixmapRect( FALSE ).intersects( r ) );
+}
+
+/*!
+ \fn bool TQIconViewItem::acceptDrop( const TQMimeSource *mime ) const
+
+ Returns TRUE if you can drop things with a TQMimeSource of \a mime
+ onto this item; otherwise returns FALSE.
+
+ The default implementation always returns FALSE. You must subclass
+ TQIconViewItem and reimplement acceptDrop() to accept drops.
+*/
+
+bool TQIconViewItem::acceptDrop( const TQMimeSource * ) const
+{
+ return FALSE;
+}
+
+#ifndef TQT_NO_TEXTEDIT
+/*!
+ Starts in-place renaming of an icon, if allowed.
+
+ This function sets up the icon view so that the user can edit the
+ item text, and then returns. When the user is done, setText() will
+ be called and TQIconView::itemRenamed() will be emitted (unless the
+ user canceled, e.g. by pressing the Escape key).
+
+ \sa setRenameEnabled()
+*/
+
+void TQIconViewItem::rename()
+{
+ if ( !view )
+ return;
+ if ( renameBox )
+ removeRenameBox();
+ oldRect = rect();
+ renameBox = new TQIconViewItemLineEdit( itemText, view->viewport(), this, "qt_renamebox" );
+ iconView()->ensureItemVisible( this );
+ TQRect tr( textRect( FALSE ) );
+ view->addChild( renameBox, tr.x() + ( tr.width() / 2 - renameBox->width() / 2 ), tr.y() - 3 );
+ renameBox->selectAll();
+ view->viewport()->setFocusProxy( renameBox );
+ renameBox->setFocus();
+ renameBox->show();
+ Q_ASSERT( view->d->renamingItem == 0L );
+ view->d->renamingItem = this;
+}
+#endif
+
+/*!
+ Compares this icon view item to \a i. Returns -1 if this item is
+ less than \a i, 0 if they are equal, and 1 if this icon view item
+ is greater than \a i.
+
+ The default implementation compares the item keys (key()) using
+ TQString::localeAwareCompare(). A reimplementation may use
+ different values and a different comparison function. Here is a
+ reimplementation that uses plain Unicode comparison:
+
+ \code
+ int MyIconViewItem::compare( TQIconViewItem *i ) const
+ {
+ return key().compare( i->key() );
+ }
+ \endcode
+
+ \sa key() TQString::localeAwareCompare() TQString::compare()
+*/
+
+int TQIconViewItem::compare( TQIconViewItem *i ) const
+{
+ return key().localeAwareCompare( i->key() );
+}
+
+#ifndef TQT_NO_TEXTEDIT
+/*!
+ This private function is called when the user pressed Return during
+ in-place renaming.
+*/
+
+void TQIconViewItem::renameItem()
+{
+ if ( !renameBox || !view )
+ return;
+
+ if ( !view->d->wordWrapIconText ) {
+ wordWrapDirty = TRUE;
+ calcRect();
+ }
+ TQRect r = itemRect;
+ setText( renameBox->text() );
+ view->repaintContents( oldRect.x() - 1, oldRect.y() - 1, oldRect.width() + 2, oldRect.height() + 2, FALSE );
+ view->repaintContents( r.x() - 1, r.y() - 1, r.width() + 2, r.height() + 2, FALSE );
+ removeRenameBox();
+
+ view->emitRenamed( this );
+}
+
+/*!
+ Cancels in-place renaming.
+*/
+
+void TQIconViewItem::cancelRenameItem()
+{
+ if ( !view )
+ return;
+
+ TQRect r = itemRect;
+ calcRect();
+ view->repaintContents( oldRect.x() - 1, oldRect.y() - 1, oldRect.width() + 2, oldRect.height() + 2, FALSE );
+ view->repaintContents( r.x() - 1, r.y() - 1, r.width() + 2, r.height() + 2, FALSE );
+
+ if ( !renameBox )
+ return;
+
+ removeRenameBox();
+}
+
+/*!
+ Removes the editbox that is used for in-place renaming.
+*/
+
+void TQIconViewItem::removeRenameBox()
+{
+ if ( !renameBox || !view )
+ return;
+
+ bool resetFocus = view->viewport()->focusProxy() == renameBox;
+ renameBox->hide();
+ renameBox->deleteLater();
+ renameBox = 0;
+ if ( resetFocus ) {
+ view->viewport()->setFocusProxy( view );
+ view->setFocus();
+ }
+ Q_ASSERT( view->d->renamingItem == this );
+ view->d->renamingItem = 0L;
+}
+#endif
+
+/*!
+ This virtual function is responsible for calculating the
+ rectangles returned by rect(), textRect() and pixmapRect().
+ setRect(), setTextRect() and setPixmapRect() are provided mainly
+ for reimplementations of this function.
+
+ \a text_ is an internal parameter which defaults to TQString::null.
+*/
+
+void TQIconViewItem::calcRect( const TQString &text_ )
+{
+ if ( !view ) // #####
+ return;
+
+ wordWrapDirty = TRUE;
+ int pw = 0;
+ int ph = 0;
+
+#ifndef TQT_NO_PICTURE
+ if ( picture() ) {
+ TQRect br = picture()->boundingRect();
+ pw = br.width() + 2;
+ ph = br.height() + 2;
+ } else
+#endif
+ {
+ pw = ( pixmap() ? pixmap() : unknown_icon )->width() + 2;
+ ph = ( pixmap() ? pixmap() : unknown_icon )->height() + 2;
+ }
+
+ itemIconRect.setWidth( pw );
+ itemIconRect.setHeight( ph );
+
+ calcTmpText();
+
+ TQString t = text_;
+ if ( t.isEmpty() ) {
+ if ( view->d->wordWrapIconText )
+ t = itemText;
+ else
+ t = tmpText;
+ }
+
+ int tw = 0;
+ int th = 0;
+ // ##### TODO: fix font bearings!
+ TQRect r;
+ if ( view->d->wordWrapIconText ) {
+ r = TQRect( view->d->fm->boundingRect( 0, 0, iconView()->maxItemWidth() -
+ ( iconView()->itemTextPos() == TQIconView::Bottom ? 0 :
+ pixmapRect().width() ),
+ 0xFFFFFFFF, AlignHCenter | WordBreak | BreakAnywhere, t ) );
+ r.setWidth( r.width() + 4 );
+ } else {
+ r = TQRect( 0, 0, view->d->fm->width( t ), view->d->fm->height() );
+ r.setWidth( r.width() + 4 );
+ }
+
+ if ( r.width() > iconView()->maxItemWidth() -
+ ( iconView()->itemTextPos() == TQIconView::Bottom ? 0 :
+ pixmapRect().width() ) )
+ r.setWidth( iconView()->maxItemWidth() - ( iconView()->itemTextPos() == TQIconView::Bottom ? 0 :
+ pixmapRect().width() ) );
+
+ tw = r.width();
+ th = r.height();
+ if ( tw < view->d->fm->width( "X" ) )
+ tw = view->d->fm->width( "X" );
+
+ itemTextRect.setWidth( tw );
+ itemTextRect.setHeight( th );
+
+ int w = 0;
+ int h = 0;
+ if ( view->itemTextPos() == TQIconView::Bottom ) {
+ w = TQMAX( itemTextRect.width(), itemIconRect.width() );
+ h = itemTextRect.height() + itemIconRect.height() + 1;
+
+ itemRect.setWidth( w );
+ itemRect.setHeight( h );
+
+ itemTextRect = TQRect( ( width() - itemTextRect.width() ) / 2, height() - itemTextRect.height(),
+ itemTextRect.width(), itemTextRect.height() );
+ itemIconRect = TQRect( ( width() - itemIconRect.width() ) / 2, 0,
+ itemIconRect.width(), itemIconRect.height() );
+ } else {
+ h = TQMAX( itemTextRect.height(), itemIconRect.height() );
+ w = itemTextRect.width() + itemIconRect.width() + 1;
+
+ itemRect.setWidth( w );
+ itemRect.setHeight( h );
+
+ itemTextRect = TQRect( width() - itemTextRect.width(), ( height() - itemTextRect.height() ) / 2,
+ itemTextRect.width(), itemTextRect.height() );
+ itemIconRect = TQRect( 0, ( height() - itemIconRect.height() ) / 2,
+ itemIconRect.width(), itemIconRect.height() );
+ }
+ if ( view )
+ view->updateItemContainer( this );
+}
+
+/*!
+ Paints the item using the painter \a p and the color group \a cg.
+ If you want the item to be drawn with a different font or color,
+ reimplement this function, change the values of the color group or
+ the painter's font, and then call the TQIconViewItem::paintItem()
+ with the changed values.
+*/
+
+void TQIconViewItem::paintItem( TQPainter *p, const TQColorGroup &cg )
+{
+ if ( !view )
+ return;
+
+ p->save();
+
+ if ( isSelected() ) {
+ p->setPen( cg.highlightedText() );
+ } else {
+ p->setPen( cg.text() );
+ }
+
+ calcTmpText();
+
+#ifndef TQT_NO_PICTURE
+ if ( picture() ) {
+ TQPicture *pic = picture();
+ if ( isSelected() ) {
+ p->setBrush( TQBrush( cg.highlight(), TQBrush::Dense4Pattern ) );
+ p->setPen( TQPen( cg.highlight(), TQBrush::Dense4Pattern ) );
+ p->drawRoundRect( pixmapRect( FALSE ),
+ 1000 / pixmapRect( FALSE ).width(),
+ 1000 / pixmapRect( FALSE ).height() );
+ }
+ p->drawPicture( x()-pic->boundingRect().x(), y()-pic->boundingRect().y(), *pic );
+ if ( isSelected() ) {
+ p->setBrush( TQBrush( cg.highlight() ) );
+ p->setPen( TQPen( cg.highlight() ) );
+ p->drawRoundRect( textRect( FALSE ),
+ 1000 / textRect( FALSE ).width(),
+ 1000 / textRect( FALSE ).height() );
+ p->setPen( TQPen( cg.highlightedText() ) );
+ } else if ( view->d->itemTextBrush != NoBrush ) {
+ p->setBrush( view->d->itemTextBrush );
+ p->setPen( TQPen( view->d->itemTextBrush.color() ) );
+ p->drawRoundRect( textRect( FALSE ),
+ 1000 / textRect( FALSE ).width(),
+ 1000 / textRect( FALSE ).height() );
+ }
+
+ int align = view->itemTextPos() == TQIconView::Bottom ? AlignHCenter : AlignAuto;
+ if ( view->d->wordWrapIconText )
+ align |= WordBreak | BreakAnywhere;
+ p->drawText( textRect( FALSE ), align, view->d->wordWrapIconText ? itemText : tmpText );
+ p->restore();
+ return;
+ }
+#endif
+ bool textOnBottom = ( view->itemTextPos() == TQIconView::Bottom );
+ int dim;
+ if ( textOnBottom )
+ dim = ( pixmap() ? pixmap() : unknown_icon)->width();
+ else
+ dim = ( pixmap() ? pixmap() : unknown_icon)->height();
+ if ( isSelected() ) {
+ TQPixmap *pix = pixmap() ? pixmap() : unknown_icon;
+ if ( pix && !pix->isNull() ) {
+ TQPixmap *buffer = get_qiv_buffer_pixmap( pix->size() );
+ TQBitmap mask = view->mask( pix );
+
+ TQPainter p2( buffer );
+ p2.fillRect( pix->rect(), white );
+ p2.drawPixmap( 0, 0, *pix );
+ p2.end();
+ buffer->setMask( mask );
+ p2.begin( buffer );
+#if defined(TQ_WS_X11)
+ p2.fillRect( pix->rect(), TQBrush( cg.highlight(), TQBrush::Dense4Pattern) );
+#else // in WIN32 Dense4Pattern doesn't work correctly (transparency problem), so work around it
+ if ( iconView()->d->drawActiveSelection ) {
+ if ( !qiv_selection )
+ createSelectionPixmap( cg );
+ p2.drawTiledPixmap( 0, 0, pix->width(), pix->height(),
+ *qiv_selection );
+ }
+#endif
+ p2.end();
+ TQRect cr = pix->rect();
+ if ( textOnBottom )
+ p->drawPixmap( x() + ( width() - dim ) / 2, y(), *buffer, 0, 0,
+ cr.width(), cr.height() );
+ else
+ p->drawPixmap( x() , y() + ( height() - dim ) / 2, *buffer, 0, 0,
+ cr.width(), cr.height() );
+ }
+ } else {
+ if ( textOnBottom )
+ p->drawPixmap( x() + ( width() - dim ) / 2, y(),
+ *( pixmap() ? pixmap() : unknown_icon ) );
+ else
+ p->drawPixmap( x() , y() + ( height() - dim ) / 2,
+ *( pixmap() ? pixmap() : unknown_icon ) );
+ }
+
+ p->save();
+ if ( isSelected() ) {
+ p->setBrush( TQBrush( cg.highlight() ) );
+ p->setPen( TQPen( cg.highlight() ) );
+ p->drawRoundRect( textRect( FALSE ),
+ 1000 / textRect( FALSE ).width(),
+ 1000 / textRect( FALSE ).height() );
+ p->setPen( TQPen( cg.highlightedText() ) );
+ } else if ( view->d->itemTextBrush != NoBrush ) {
+ p->setBrush( view->d->itemTextBrush );
+ p->setPen( TQPen( view->d->itemTextBrush.color() ) );
+ p->drawRoundRect( textRect( FALSE ),
+ 1000 / textRect( FALSE ).width(),
+ 1000 / textRect( FALSE ).height() );
+ }
+
+ int align = AlignHCenter;
+ if ( view->d->wordWrapIconText )
+ align |= WordBreak | BreakAnywhere;
+ p->drawText( textRect( FALSE ), align,
+ view->d->wordWrapIconText ? itemText : tmpText );
+
+ p->restore();
+
+ p->restore();
+}
+
+/*!
+ Paints the focus rectangle of the item using the painter \a p and
+ the color group \a cg.
+
+ The default implementation does nothing; subclasses may
+ reimplement this function.
+*/
+
+void TQIconViewItem::paintFocus( TQPainter *, const TQColorGroup & )
+{
+}
+
+/*!
+ \fn void TQIconViewItem::dropped( TQDropEvent *e, const TQValueList<TQIconDragItem> &lst )
+
+ This function is called when something is dropped on the item. \a
+ e provides all the information about the drop. If the drag object
+ of the drop was a TQIconDrag, \a lst contains the list of the
+ dropped items. You can get the data by calling
+ TQIconDragItem::data() on each item. If the \a lst is empty, i.e.
+ the drag was not a TQIconDrag, you must decode the data in \a e and
+ work with that.
+
+ The default implementation does nothing; subclasses may
+ reimplement this function.
+*/
+
+#ifndef TQT_NO_DRAGANDDROP
+void TQIconViewItem::dropped( TQDropEvent *, const TQValueList<TQIconDragItem> & )
+{
+}
+#endif
+
+/*!
+ This function is called when a drag enters the item's bounding
+ rectangle.
+
+ The default implementation does nothing; subclasses may
+ reimplement this function.
+*/
+
+void TQIconViewItem::dragEntered()
+{
+}
+
+/*!
+ This function is called when a drag leaves the item's bounding
+ rectangle.
+
+ The default implementation does nothing; subclasses may
+ reimplement this function.
+*/
+
+void TQIconViewItem::dragLeft()
+{
+}
+
+/*!
+ Sets the bounding rectangle of the whole item to \a r. This
+ function is provided for subclasses which reimplement calcRect(),
+ so that they can set the calculated rectangle. \e{Any other use is
+ discouraged.}
+
+ \sa calcRect() textRect() setTextRect() pixmapRect() setPixmapRect()
+*/
+
+void TQIconViewItem::setItemRect( const TQRect &r )
+{
+ itemRect = r;
+ checkRect();
+ if ( view )
+ view->updateItemContainer( this );
+}
+
+/*!
+ Sets the bounding rectangle of the item's text to \a r. This
+ function is provided for subclasses which reimplement calcRect(),
+ so that they can set the calculated rectangle. \e{Any other use is
+ discouraged.}
+
+ \sa calcRect() textRect() setItemRect() setPixmapRect()
+*/
+
+void TQIconViewItem::setTextRect( const TQRect &r )
+{
+ itemTextRect = r;
+ if ( view )
+ view->updateItemContainer( this );
+}
+
+/*!
+ Sets the bounding rectangle of the item's icon to \a r. This
+ function is provided for subclasses which reimplement calcRect(),
+ so that they can set the calculated rectangle. \e{Any other use is
+ discouraged.}
+
+ \sa calcRect() pixmapRect() setItemRect() setTextRect()
+*/
+
+void TQIconViewItem::setPixmapRect( const TQRect &r )
+{
+ itemIconRect = r;
+ if ( view )
+ view->updateItemContainer( this );
+}
+
+/*!
+ \internal
+*/
+
+void TQIconViewItem::calcTmpText()
+{
+ if ( !view || view->d->wordWrapIconText || !wordWrapDirty )
+ return;
+ wordWrapDirty = FALSE;
+
+ int w = iconView()->maxItemWidth() - ( iconView()->itemTextPos() == TQIconView::Bottom ? 0 :
+ pixmapRect().width() );
+ if ( view->d->fm->width( itemText ) < w ) {
+ tmpText = itemText;
+ return;
+ }
+
+ tmpText = "...";
+ int i = 0;
+ while ( view->d->fm->width( tmpText + itemText[ i ] ) < w )
+ tmpText += itemText[ i++ ];
+ tmpText.remove( (uint)0, 3 );
+ tmpText += "...";
+}
+
+/*! \internal */
+
+TQString TQIconViewItem::tempText() const
+{
+ return tmpText;
+}
+
+void TQIconViewItem::checkRect()
+{
+ int x = itemRect.x();
+ int y = itemRect.y();
+ int w = itemRect.width();
+ int h = itemRect.height();
+
+ bool changed = FALSE;
+ if ( x < 0 ) {
+ x = 0;
+ changed = TRUE;
+ }
+ if ( y < 0 ) {
+ y = 0;
+ changed = TRUE;
+ }
+
+ if ( changed )
+ itemRect.setRect( x, y, w, h );
+}
+
+
+/*! \file iconview/simple_dd/main.h */
+/*! \file iconview/simple_dd/main.cpp */
+
+
+/*!
+ \class TQIconView tqiconview.h
+ \brief The TQIconView class provides an area with movable labelled icons.
+
+ \module iconview
+ \ingroup advanced
+ \mainclass
+
+ A TQIconView can display and manage a grid or other 2D layout of
+ labelled icons. Each labelled icon is a TQIconViewItem. Items
+ (TQIconViewItems) can be added or deleted at any time; items can be
+ moved within the TQIconView. Single or multiple items can be
+ selected. Items can be renamed in-place. TQIconView also supports
+ \link #draganddrop drag and drop\endlink.
+
+ Each item contains a label string, a pixmap or picture (the icon
+ itself) and optionally a sort key. The sort key is used for
+ sorting the items and defaults to the label string. The label
+ string can be displayed below or to the right of the icon (see \l
+ ItemTextPos).
+
+ The simplest way to create a TQIconView is to create a TQIconView
+ object and create some TQIconViewItems with the TQIconView as their
+ parent, set the icon view's geometry and show it.
+ For example:
+ \code
+ TQIconView *iv = new TQIconView( this );
+ TQDir dir( path, "*.xpm" );
+ for ( uint i = 0; i < dir.count(); i++ ) {
+ (void) new TQIconViewItem( iv, dir[i], TQPixmap( path + dir[i] ) );
+ }
+ iv->resize( 600, 400 );
+ iv->show();
+ \endcode
+
+ The TQIconViewItem call passes a pointer to the TQIconView we wish to
+ populate, along with the label text and a TQPixmap.
+
+ When an item is inserted the TQIconView allocates a position for it.
+ Existing items are rearranged if autoArrange() is TRUE. The
+ default arrangement is \c LeftToRight -- the TQIconView fills
+ the \e top-most row from left to right, then moves one row \e down
+ and fills that row from left to right and so on. The
+ arrangement can be modified with any of the following approaches:
+ \list
+ \i Call setArrangement(), e.g. with \c TopToBottom which will fill up
+ the \e left-most column from top to bottom, then moves one column
+ \e right and fills that from top to bottom and so on.
+
+ \i Construct each TQIconViewItem using a constructor which allows
+ you to specify which item the new one is to follow.
+ \i Call setSorting() or sort() to sort the items.
+ \endlist
+
+ The spacing between items is set with setSpacing(). Items can be
+ laid out using a fixed grid using setGridX() and setGridY(); by
+ default the TQIconView calculates a grid dynamically. The position
+ of items' label text is set with setItemTextPos(). The text's
+ background can be set with setItemTextBackground(). The maximum
+ width of an item and of its text are set with setMaxItemWidth()
+ and setMaxItemTextLength(). The label text will be word-wrapped if
+ it is too long; this is controlled by setWordWrapIconText(). If
+ the label text is truncated, the user can still see the entire
+ text in a tool tip if they hover the mouse over the item. This is
+ controlled with setShowToolTips().
+
+ Items which are \link TQIconViewItem::isSelectable()
+ selectable\endlink may be selected depending on the SelectionMode;
+ the default is \c Single. Because TQIconView offers multiple
+ selection it must display keyboard focus and selection state
+ separately. Therefore there are functions to set the selection
+ state of an item (setSelected()) and to select which item displays
+ keyboard focus (setCurrentItem()). When multiple items may be
+ selected the icon view provides a rubberband, too.
+
+ When in-place renaming is enabled (it is disabled by default), the
+ user may change the item's label. They do this by selecting the item
+ (single clicking it or navigating to it with the arrow keys), then
+ single clicking it (or pressing F2), and entering their text. If no
+ key has been set with TQIconViewItem::setKey() the new text will also
+ serve as the key. (See TQIconViewItem::setRenameEnabled().)
+
+ You can control whether users can move items themselves with
+ setItemsMovable().
+
+ Because the internal structure used to store the icon view items is
+ linear, no iterator class is needed to iterate over all the items.
+ Instead we iterate by getting the first item from the \e{icon view}
+ and then each subsequent (\l TQIconViewItem::nextItem()) from each
+ \e item in turn:
+ \code
+ for ( TQIconViewItem *item = iv->firstItem(); item; item = item->nextItem() )
+ do_something( item );
+ \endcode
+ TQIconView also provides currentItem(). You can search for an item
+ using findItem() (searching by position or for label text) and
+ with findFirstVisibleItem() and findLastVisibleItem(). The number
+ of items is returned by count(). An item can be removed from an
+ icon view using takeItem(); to delete an item use \c delete. All
+ the items can be deleted with clear().
+
+ The TQIconView emits a wide range of useful signals, including
+ selectionChanged(), currentChanged(), clicked(), moved() and
+ itemRenamed().
+
+ \target draganddrop
+ \section1 Drag and Drop
+
+ TQIconView supports the drag and drop of items within the TQIconView
+ itself. It also supports the drag and drop of items out of or into
+ the TQIconView and drag and drop onto items themselves. The drag and
+ drop of items outside the TQIconView can be achieved in a simple way
+ with basic functionality, or in a more sophisticated way which
+ provides more power and control.
+
+ The simple approach to dragging items out of the icon view is to
+ subclass TQIconView and reimplement TQIconView::dragObject().
+
+ \code
+ TQDragObject *MyIconView::dragObject()
+ {
+ return new TQTextDrag( currentItem()->text(), this );
+ }
+ \endcode
+
+ In this example we create a TQTextDrag object, (derived from
+ TQDragObject), containing the item's label and return it as the drag
+ object. We could just as easily have created a TQImageDrag from the
+ item's pixmap and returned that instead.
+
+ TQIconViews and their TQIconViewItems can also be the targets of drag
+ and drops. To make the TQIconView itself able to accept drops connect
+ to the dropped() signal. When a drop occurs this signal will be
+ emitted with a TQDragEvent and a TQValueList of TQIconDragItems. To
+ make a TQIconViewItem into a drop target subclass TQIconViewItem and
+ reimplement TQIconViewItem::acceptDrop() and
+ TQIconViewItem::dropped().
+
+ \code
+ bool MyIconViewItem::acceptDrop( const TQMimeSource *mime ) const
+ {
+ if ( mime->provides( "text/plain" ) )
+ return TRUE;
+ return FALSE;
+ }
+
+ void MyIconViewItem::dropped( TQDropEvent *evt, const TQValueList<TQIconDragItem>& )
+ {
+ TQString label;
+ if ( TQTextDrag::decode( evt, label ) )
+ setText( label );
+ }
+ \endcode
+
+ See \l iconview/simple_dd/main.h and \l
+ iconview/simple_dd/main.cpp for a simple drag and drop example
+ which demonstrates drag and drop between a TQIconView and a
+ TQListBox.
+
+ If you want to use extended drag-and-drop or have drag shapes drawn
+ you must take a more sophisticated approach.
+
+ The first part is starting drags -- you should use a TQIconDrag (or a
+ class derived from it) for the drag object. In dragObject() create the
+ drag object, populate it with TQIconDragItems and return it. Normally
+ such a drag should offer each selected item's data. So in dragObject()
+ you should iterate over all the items, and create a TQIconDragItem for
+ each selected item, and append these items with TQIconDrag::append() to
+ the TQIconDrag object. You can use TQIconDragItem::setData() to set the
+ data of each item that should be dragged. If you want to offer the
+ data in additional mime-types, it's best to use a class derived from
+ TQIconDrag, which implements additional encoding and decoding
+ functions.
+
+ When a drag enters the icon view, there is little to do. Simply
+ connect to the dropped() signal and reimplement
+ TQIconViewItem::acceptDrop() and TQIconViewItem::dropped(). If you've
+ used a TQIconDrag (or a subclass of it) the second argument to the
+ dropped signal contains a TQValueList of TQIconDragItems -- you can
+ access their data by calling TQIconDragItem::data() on each one.
+
+ For an example implementation of complex drag-and-drop look at the
+ fileiconview example (qt/examples/fileiconview).
+
+ \sa TQIconViewItem::setDragEnabled(), TQIconViewItem::setDropEnabled(),
+ TQIconViewItem::acceptDrop(), TQIconViewItem::dropped().
+
+ <img src=tqiconview-m.png> <img src=tqiconview-w.png>
+*/
+
+/*! \enum TQIconView::ResizeMode
+
+ This enum type is used to tell TQIconView how it should treat the
+ positions of its icons when the widget is resized. The modes are:
+
+ \value Fixed The icons' positions are not changed.
+ \value Adjust The icons' positions are adjusted to be within the
+ new geometry, if possible.
+*/
+
+/*!
+ \enum TQIconView::SelectionMode
+
+ This enumerated type is used by TQIconView to indicate how it
+ reacts to selection by the user. It has four values:
+
+ \value Single When the user selects an item, any already-selected
+ item becomes unselected and the user cannot unselect the selected
+ item. This means that the user can never clear the selection. (The
+ application programmer can, using TQIconView::clearSelection().)
+
+ \value Multi When the user selects an item, e.g. by navigating
+ to it with the keyboard arrow keys or by clicking it, the
+ selection status of that item is toggled and the other items are
+ left alone. Also, multiple items can be selected by dragging the
+ mouse while the left mouse button stays pressed.
+
+ \value Extended When the user selects an item the selection is
+ cleared and the new item selected. However, if the user presses
+ the Ctrl key when clicking on an item, the clicked item gets
+ toggled and all other items are left untouched. If the user
+ presses the Shift key while clicking on an item, all items between
+ the current item and the clicked item get selected or unselected,
+ depending on the state of the clicked item. Also, multiple items
+ can be selected by dragging the mouse while the left mouse button
+ stays pressed.
+
+ \value NoSelection Items cannot be selected.
+
+ To summarise: \c Single is a real single-selection icon view; \c
+ Multi a real multi-selection icon view; \c Extended is an icon
+ view in which users can select multiple items but usually want to
+ select either just one or a range of contiguous items; and \c
+ NoSelection mode is for an icon view where the user can look but
+ not touch.
+*/
+
+/*!
+ \enum TQIconView::Arrangement
+
+ This enum type determines in which direction the items flow when
+ the view runs out of space.
+
+ \value LeftToRight Items which don't fit into the view cause the
+ viewport to extend vertically (you get a vertical scrollbar).
+
+ \value TopToBottom Items which don't fit into the view cause the
+ viewport to extend horizontally (you get a horizontal scrollbar).
+*/
+
+/*!
+ \enum TQIconView::ItemTextPos
+
+ This enum type specifies the position of the item text in relation
+ to the icon.
+
+ \value Bottom The text is drawn below the icon.
+ \value Right The text is drawn to the right of the icon.
+*/
+
+/*!
+ \fn void TQIconView::dropped ( TQDropEvent * e, const TQValueList<TQIconDragItem> &lst )
+
+ This signal is emitted when a drop event occurs in the viewport
+ (but not on any icon) which the icon view itself can't handle.
+
+ \a e provides all the information about the drop. If the drag
+ object of the drop was a TQIconDrag, \a lst contains the list of
+ the dropped items. You can get the data using
+ TQIconDragItem::data() on each item. If the \a lst is empty, i.e.
+ the drag was not a TQIconDrag, you have to decode the data in \a e
+ and work with that.
+
+ Note TQIconViewItems may be drop targets; if a drop event occurs on
+ an item the item handles the drop.
+*/
+
+/*!
+ \fn void TQIconView::moved()
+
+ This signal is emitted after successfully dropping one (or more)
+ items of the icon view. If the items should be removed, it's best
+ to do so in a slot connected to this signal.
+*/
+
+/*!
+ \fn void TQIconView::doubleClicked(TQIconViewItem * item)
+
+ This signal is emitted when the user double-clicks on \a item.
+*/
+
+/*!
+ \fn void TQIconView::returnPressed (TQIconViewItem * item)
+
+ This signal is emitted if the user presses the Return or Enter
+ key. \a item is the currentItem() at the time of the keypress.
+*/
+
+/*!
+ \fn void TQIconView::selectionChanged()
+
+ This signal is emitted when the selection has been changed. It's
+ emitted in each selection mode.
+*/
+
+/*!
+ \overload void TQIconView::selectionChanged( TQIconViewItem *item )
+
+ This signal is emitted when the selection changes. \a item is the
+ newly selected item. This signal is emitted only in single
+ selection mode.
+*/
+
+/*!
+ \fn void TQIconView::currentChanged( TQIconViewItem *item )
+
+ This signal is emitted when a new item becomes current. \a item is
+ the new current item (or 0 if no item is now current).
+
+ \sa currentItem()
+*/
+
+/*!
+ \fn void TQIconView::onItem( TQIconViewItem *item )
+
+ This signal is emitted when the user moves the mouse cursor onto
+ an \a item, similar to the TQWidget::enterEvent() function.
+*/
+
+// ### bug here - enter/leave event aren't considered. move the mouse
+// out of the window and back in, to the same item.
+
+/*!
+ \fn void TQIconView::onViewport()
+
+ This signal is emitted when the user moves the mouse cursor from
+ an item to an empty part of the icon view.
+
+ \sa onItem()
+*/
+
+/*!
+ \overload void TQIconView::itemRenamed (TQIconViewItem * item)
+
+ This signal is emitted when \a item has been renamed, usually by
+ in-place renaming.
+
+ \sa TQIconViewItem::setRenameEnabled() TQIconViewItem::rename()
+*/
+
+/*!
+ \fn void TQIconView::itemRenamed (TQIconViewItem * item, const TQString &name)
+
+ This signal is emitted when \a item has been renamed to \a name,
+ usually by in-place renaming.
+
+ \sa TQIconViewItem::setRenameEnabled() TQIconViewItem::rename()
+*/
+
+/*!
+ \fn void TQIconView::rightButtonClicked (TQIconViewItem * item, const TQPoint & pos)
+
+ This signal is emitted when the user clicks the right mouse
+ button. If \a item is non-null, the cursor is on \a item. If \a
+ item is null, the mouse cursor isn't on any item.
+
+ \a pos is the position of the mouse cursor in the global
+ coordinate system (TQMouseEvent::globalPos()). (If the click's
+ press and release differ by a pixel or two, \a pos is the
+ position at release time.)
+
+ \sa rightButtonPressed() mouseButtonClicked() clicked()
+*/
+
+/*!
+ \fn void TQIconView::contextMenuRequested( TQIconViewItem *item, const TQPoint & pos )
+
+ This signal is emitted when the user invokes a context menu with
+ the right mouse button or with special system keys, with \a item
+ being the item under the mouse cursor or the current item,
+ respectively.
+
+ \a pos is the position for the context menu in the global
+ coordinate system.
+*/
+
+/*!
+ \fn void TQIconView::mouseButtonPressed (int button, TQIconViewItem * item, const TQPoint & pos)
+
+ This signal is emitted when the user presses mouse button \a
+ button. If \a item is non-null, the cursor is on \a item. If \a
+ item is null, the mouse cursor isn't on any item.
+
+ \a pos is the position of the mouse cursor in the global
+ coordinate system (TQMouseEvent::globalPos()).
+
+ \sa rightButtonClicked() mouseButtonPressed() pressed()
+*/
+
+/*!
+ \fn void TQIconView::mouseButtonClicked (int button, TQIconViewItem * item, const TQPoint & pos )
+
+ This signal is emitted when the user clicks mouse button \a
+ button. If \a item is non-null, the cursor is on \a item. If \a
+ item is null, the mouse cursor isn't on any item.
+
+ \a pos is the position of the mouse cursor in the global
+ coordinate system (TQMouseEvent::globalPos()). (If the click's
+ press and release differ by a pixel or two, \a pos is the
+ position at release time.)
+
+ \sa mouseButtonPressed() rightButtonClicked() clicked()
+*/
+
+/*!
+ \overload void TQIconView::clicked ( TQIconViewItem * item, const TQPoint & pos )
+
+ This signal is emitted when the user clicks any mouse button on an
+ icon view item. \a item is a pointer to the item that has been
+ clicked.
+
+ \a pos is the position of the mouse cursor in the global coordinate
+ system (TQMouseEvent::globalPos()). (If the click's press and release
+ differ by a pixel or two, \a pos is the position at release time.)
+
+ \sa mouseButtonClicked() rightButtonClicked() pressed()
+*/
+
+/*!
+ \overload void TQIconView::pressed ( TQIconViewItem * item, const TQPoint & pos )
+
+ This signal is emitted when the user presses any mouse button. If
+ \a item is non-null, the cursor is on \a item. If \a item is null,
+ the mouse cursor isn't on any item.
+
+ \a pos is the position of the mouse cursor in the global
+ coordinate system (TQMouseEvent::globalPos()). (If the click's
+ press and release differ by a pixel or two, \a pos is the
+ position at release time.)
+
+ \sa mouseButtonPressed() rightButtonPressed() clicked()
+*/
+
+/*!
+ \fn void TQIconView::clicked ( TQIconViewItem * item )
+
+ This signal is emitted when the user clicks any mouse button. If
+ \a item is non-null, the cursor is on \a item. If \a item is null,
+ the mouse cursor isn't on any item.
+
+ \sa mouseButtonClicked() rightButtonClicked() pressed()
+*/
+
+/*!
+ \fn void TQIconView::pressed ( TQIconViewItem * item )
+
+ This signal is emitted when the user presses any mouse button. If
+ \a item is non-null, the cursor is on \a item. If \a item is null,
+ the mouse cursor isn't on any item.
+
+ \sa mouseButtonPressed() rightButtonPressed() clicked()
+*/
+
+/*!
+ \fn void TQIconView::rightButtonPressed( TQIconViewItem * item, const TQPoint & pos )
+
+ This signal is emitted when the user presses the right mouse
+ button. If \a item is non-null, the cursor is on \a item. If \a
+ item is null, the mouse cursor isn't on any item.
+
+ \a pos is the position of the mouse cursor in the global
+ coordinate system (TQMouseEvent::globalPos()).
+*/
+
+/*!
+ Constructs an empty icon view called \a name, with parent \a
+ parent and using the widget flags \a f.
+*/
+
+TQIconView::TQIconView( TQWidget *parent, const char *name, WFlags f )
+ : TQScrollView( parent, name, WStaticContents | WNoAutoErase | f )
+{
+ if ( !unknown_icon ) {
+ unknown_icon = new TQPixmap( (const char **)unknown_xpm );
+ qiv_cleanup_pixmap.add( &unknown_icon );
+ }
+
+ d = new TQIconViewPrivate;
+ d->dragging = FALSE;
+ d->firstItem = 0;
+ d->lastItem = 0;
+ d->count = 0;
+ d->mousePressed = FALSE;
+ d->selectionMode = Single;
+ d->currentItem = 0;
+ d->highlightedItem = 0;
+ d->rubber = 0;
+ d->canStartRubber = FALSE;
+ d->backBuffer = 0;
+ d->scrollTimer = 0;
+ d->startDragItem = 0;
+ d->tmpCurrentItem = 0;
+ d->rastX = d->rastY = -1;
+ d->spacing = 5;
+ d->cleared = FALSE;
+ d->arrangement = LeftToRight;
+ d->resizeMode = Fixed;
+ d->dropped = FALSE;
+ d->adjustTimer = new TQTimer( this, "iconview adjust timer" );
+ d->isIconDrag = FALSE;
+ d->inMenuMode = FALSE;
+#ifndef TQT_NO_DRAGANDDROP
+ d->iconDragData.clear();
+#endif
+ d->numDragItems = 0;
+ d->updateTimer = new TQTimer( this, "iconview update timer" );
+ d->cachedW = d->cachedH = 0;
+ d->maxItemWidth = 100;
+ d->maxItemTextLength = 255;
+ d->inputTimer = new TQTimer( this, "iconview input timer" );
+ d->currInputString = TQString::null;
+ d->dirty = FALSE;
+ d->rearrangeEnabled = TRUE;
+ d->itemTextPos = Bottom;
+ d->reorderItemsWhenInsert = TRUE;
+#ifndef TQT_NO_CURSOR
+ d->oldCursor = arrowCursor;
+#endif
+ d->resortItemsWhenInsert = FALSE;
+ d->sortDirection = TRUE;
+ d->wordWrapIconText = TRUE;
+ d->cachedContentsX = d->cachedContentsY = -1;
+ d->clearing = FALSE;
+ d->fullRedrawTimer = new TQTimer( this, "iconview full redraw timer" );
+ d->itemTextBrush = NoBrush;
+ d->drawAllBack = TRUE;
+ d->fm = new TQFontMetrics( font() );
+ d->minLeftBearing = d->fm->minLeftBearing();
+ d->minRightBearing = d->fm->minRightBearing();
+ d->firstContainer = d->lastContainer = 0;
+ d->containerUpdateLocked = FALSE;
+ d->firstSizeHint = FALSE;
+ d->selectAnchor = 0;
+ d->renamingItem = 0;
+ d->drawActiveSelection = TRUE;
+ d->drawDragShapes = FALSE;
+ d->backrubber = 0;
+
+ connect( d->adjustTimer, TQ_SIGNAL( timeout() ),
+ this, TQ_SLOT( adjustItems() ) );
+ connect( d->updateTimer, TQ_SIGNAL( timeout() ),
+ this, TQ_SLOT( slotUpdate() ) );
+ connect( d->fullRedrawTimer, TQ_SIGNAL( timeout() ),
+ this, TQ_SLOT( updateContents() ) );
+ connect( this, TQ_SIGNAL( contentsMoving(int,int) ),
+ this, TQ_SLOT( movedContents(int,int) ) );
+
+ setAcceptDrops( TRUE );
+ viewport()->setAcceptDrops( TRUE );
+
+ setMouseTracking( TRUE );
+ viewport()->setMouseTracking( TRUE );
+
+ viewport()->setBackgroundMode( PaletteBase);
+ setBackgroundMode( PaletteBackground, PaletteBase );
+ viewport()->setFocusProxy( this );
+ viewport()->setFocusPolicy( TQWidget::WheelFocus );
+
+#ifndef TQT_NO_TOOLTIP
+ d->toolTip = new TQIconViewToolTip( viewport(), this );
+#endif
+ d->showTips = TRUE;
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::styleChange( TQStyle& old )
+{
+ TQScrollView::styleChange( old );
+ *d->fm = TQFontMetrics( font() );
+ d->minLeftBearing = d->fm->minLeftBearing();
+ d->minRightBearing = d->fm->minRightBearing();
+
+ TQIconViewItem *item = d->firstItem;
+ for ( ; item; item = item->next ) {
+ item->wordWrapDirty = TRUE;
+ item->calcRect();
+ }
+
+#if !defined(TQ_WS_X11)
+ delete qiv_selection;
+ qiv_selection = 0;
+#endif
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::setFont( const TQFont & f )
+{
+ TQScrollView::setFont( f );
+ *d->fm = TQFontMetrics( font() );
+ d->minLeftBearing = d->fm->minLeftBearing();
+ d->minRightBearing = d->fm->minRightBearing();
+
+ TQIconViewItem *item = d->firstItem;
+ for ( ; item; item = item->next ) {
+ item->wordWrapDirty = TRUE;
+ item->calcRect();
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::setPalette( const TQPalette & p )
+{
+ TQScrollView::setPalette( p );
+ *d->fm = TQFontMetrics( font() );
+ d->minLeftBearing = d->fm->minLeftBearing();
+ d->minRightBearing = d->fm->minRightBearing();
+
+ TQIconViewItem *item = d->firstItem;
+ for ( ; item; item = item->next ) {
+ item->wordWrapDirty = TRUE;
+ item->calcRect();
+ }
+}
+
+/*!
+ Destroys the icon view and deletes all items.
+*/
+
+TQIconView::~TQIconView()
+{
+ TQIconViewItem *tmp, *item = d->firstItem;
+ d->clearing = TRUE;
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer, *tmpc;
+ while ( c ) {
+ tmpc = c->n;
+ delete c;
+ c = tmpc;
+ }
+ while ( item ) {
+ tmp = item->next;
+ delete item;
+ item = tmp;
+ }
+ delete d->backBuffer;
+ d->backBuffer = 0;
+ delete d->fm;
+ d->fm = 0;
+#ifndef TQT_NO_TOOLTIP
+ delete d->toolTip;
+ d->toolTip = 0;
+#endif
+ delete d;
+ d = NULL;
+}
+
+/*!
+ Inserts the icon view item \a item after \a after. If \a after is
+ 0, \a item is appended after the last item.
+
+ \e{You should never need to call this function.} Instead create
+ TQIconViewItem's and associate them with your icon view like this:
+
+ \code
+ (void) new TQIconViewItem( myIconview, "The text of the item", aPixmap );
+ \endcode
+*/
+
+void TQIconView::insertItem( TQIconViewItem *item, TQIconViewItem *after )
+{
+ if ( !item )
+ return;
+
+ if ( d->firstItem == item || item->prev || item->next)
+ return;
+
+ if ( !item->view )
+ item->view = this;
+
+ if ( !d->firstItem ) {
+ d->firstItem = d->lastItem = item;
+ item->prev = 0;
+ item->next = 0;
+ } else {
+ if ( !after || after == d->lastItem ) {
+ d->lastItem->next = item;
+ item->prev = d->lastItem;
+ item->next = 0;
+ d->lastItem = item;
+ } else {
+ TQIconViewItem *i = d->firstItem;
+ while ( i != after )
+ i = i->next;
+
+ if ( i ) {
+ TQIconViewItem *next = i->next;
+ item->next = next;
+ item->prev = i;
+ i->next = item;
+ next->prev = item;
+ }
+ }
+ }
+
+ if ( isVisible() ) {
+ if ( d->reorderItemsWhenInsert ) {
+ if ( d->updateTimer->isActive() )
+ d->updateTimer->stop();
+ d->fullRedrawTimer->stop();
+ // #### uncomment this ASA insertInGrid uses cached values and is efficient
+ //insertInGrid( item );
+
+ d->cachedW = TQMAX( d->cachedW, item->x() + item->width() );
+ d->cachedH = TQMAX( d->cachedH, item->y() + item->height() );
+
+ d->updateTimer->start( 0, TRUE );
+ } else {
+ insertInGrid( item );
+
+ viewport()->update(item->x() - contentsX(),
+ item->y() - contentsY(),
+ item->width(), item->height());
+ }
+ } else if ( !autoArrange() ) {
+ item->dirty = FALSE;
+ }
+
+ d->count++;
+ d->dirty = TRUE;
+}
+
+/*!
+ This slot is used for a slightly-delayed update.
+
+ The icon view is not redrawn immediately after inserting a new item
+ but after a very small delay using a TQTimer. This means that when
+ many items are inserted in a loop the icon view is probably redrawn
+ only once at the end of the loop. This makes the insertions both
+ flicker-free and faster.
+*/
+
+void TQIconView::slotUpdate()
+{
+ d->updateTimer->stop();
+ d->fullRedrawTimer->stop();
+
+ if ( !d->firstItem || !d->lastItem )
+ return;
+
+ // #### remove that ASA insertInGrid uses cached values and is efficient
+ if ( d->resortItemsWhenInsert )
+ sort( d->sortDirection );
+ else {
+ int y = d->spacing;
+ TQIconViewItem *item = d->firstItem;
+ int w = 0, h = 0;
+ while ( item ) {
+ bool changed;
+ TQIconViewItem *next = makeRowLayout( item, y, changed );
+ if ( !next || !next->next )
+ break;
+
+ if( !TQApplication::reverseLayout() )
+ item = next;
+ w = TQMAX( w, item->x() + item->width() );
+ h = TQMAX( h, item->y() + item->height() );
+ item = next;
+ if ( d->arrangement == LeftToRight )
+ h = TQMAX( h, y );
+
+ item = item->next;
+ }
+
+ if ( d->lastItem && d->arrangement == TopToBottom ) {
+ item = d->lastItem;
+ int x = item->x();
+ while ( item && item->x() >= x ) {
+ w = TQMAX( w, item->x() + item->width() );
+ h = TQMAX( h, item->y() + item->height() );
+ item = item->prev;
+ }
+ }
+
+ w = TQMAX( TQMAX( d->cachedW, w ), d->lastItem->x() + d->lastItem->width() );
+ h = TQMAX( TQMAX( d->cachedH, h ), d->lastItem->y() + d->lastItem->height() );
+
+ if ( d->arrangement == TopToBottom )
+ w += d->spacing;
+ else
+ h += d->spacing;
+ viewport()->setUpdatesEnabled( FALSE );
+ resizeContents( w, h );
+ viewport()->setUpdatesEnabled( TRUE );
+ viewport()->repaint( FALSE );
+ }
+
+ int cx = d->cachedContentsX == -1 ? contentsX() : d->cachedContentsX;
+ int cy = d->cachedContentsY == -1 ? contentsY() : d->cachedContentsY;
+
+ if ( cx != contentsX() || cy != contentsY() )
+ setContentsPos( cx, cy );
+
+ d->cachedContentsX = d->cachedContentsY = -1;
+ d->cachedW = d->cachedH = 0;
+}
+
+/*!
+ Takes the icon view item \a item out of the icon view and causes
+ an update of the screen display. The item is not deleted. You
+ should normally not need to call this function because
+ TQIconViewItem::~TQIconViewItem() calls it. The normal way to delete
+ an item is to delete it.
+*/
+
+void TQIconView::takeItem( TQIconViewItem *item )
+{
+ if ( !item )
+ return;
+
+ if ( item->d->container1 )
+ item->d->container1->items.removeRef( item );
+ if ( item->d->container2 )
+ item->d->container2->items.removeRef( item );
+ item->d->container2 = 0;
+ item->d->container1 = 0;
+
+ bool block = signalsBlocked();
+ blockSignals( d->clearing );
+
+ TQRect r = item->rect();
+
+ if ( d->currentItem == item ) {
+ if ( item->prev ) {
+ d->currentItem = item->prev;
+ emit currentChanged( d->currentItem );
+ repaintItem( d->currentItem );
+ } else if ( item->next ) {
+ d->currentItem = item->next;
+ emit currentChanged( d->currentItem );
+ repaintItem( d->currentItem );
+ } else {
+ d->currentItem = 0;
+ emit currentChanged( d->currentItem );
+ }
+ }
+ if ( item->isSelected() ) {
+ item->selected = FALSE;
+ emit selectionChanged();
+ }
+
+ if ( item == d->firstItem ) {
+ d->firstItem = d->firstItem->next;
+ if ( d->firstItem )
+ d->firstItem->prev = 0;
+ } else if ( item == d->lastItem ) {
+ d->lastItem = d->lastItem->prev;
+ if ( d->lastItem )
+ d->lastItem->next = 0;
+ } else {
+ TQIconViewItem *i = item;
+ if ( i ) {
+ if ( i->prev )
+ i->prev->next = i->next;
+ if ( i->next )
+ i->next->prev = i->prev;
+ }
+ }
+
+ if ( d->selectAnchor == item )
+ d->selectAnchor = d->currentItem;
+
+ if ( !d->clearing )
+ repaintContents( r.x(), r.y(), r.width(), r.height(), TRUE );
+
+ item->view = 0;
+ item->prev = 0;
+ item->next = 0;
+ d->count--;
+
+ blockSignals( block );
+}
+
+/*!
+ Returns the index of \a item, or -1 if \a item doesn't exist in
+ this icon view.
+*/
+
+int TQIconView::index( const TQIconViewItem *item ) const
+{
+ if ( !item )
+ return -1;
+
+ if ( item == d->firstItem )
+ return 0;
+ else if ( item == d->lastItem )
+ return d->count - 1;
+ else {
+ TQIconViewItem *i = d->firstItem;
+ int j = 0;
+ while ( i && i != item ) {
+ i = i->next;
+ ++j;
+ }
+
+ return i ? j : -1;
+ }
+}
+
+/*!
+ Returns a pointer to the first item of the icon view, or 0 if
+ there are no items in the icon view.
+
+ \sa lastItem() currentItem()
+*/
+
+TQIconViewItem *TQIconView::firstItem() const
+{
+ if (d) {
+ return d->firstItem;
+ }
+ else {
+ return NULL;
+ }
+}
+
+/*!
+ Returns a pointer to the last item of the icon view, or 0 if there
+ are no items in the icon view.
+
+ \sa firstItem() currentItem()
+*/
+
+TQIconViewItem *TQIconView::lastItem() const
+{
+ if (d) {
+ return d->lastItem;
+ }
+ else {
+ return NULL;
+ }
+}
+
+/*!
+ Returns a pointer to the current item of the icon view, or 0 if no
+ item is current.
+
+ \sa setCurrentItem() firstItem() lastItem()
+*/
+
+TQIconViewItem *TQIconView::currentItem() const
+{
+ if (d) {
+ return d->currentItem;
+ }
+ else {
+ return NULL;
+ }
+}
+
+/*!
+ Makes \a item the new current item of the icon view.
+*/
+
+void TQIconView::setCurrentItem( TQIconViewItem *item )
+{
+ if ( !item || item == d->currentItem )
+ return;
+
+ setMicroFocusHint( item->x(), item->y(), item->width(), item->height(), FALSE );
+
+ TQIconViewItem *old = d->currentItem;
+ d->currentItem = item;
+ emit currentChanged( d->currentItem );
+ if ( d->selectionMode == Single ) {
+ bool changed = FALSE;
+ if ( old && old->selected ) {
+ old->selected = FALSE;
+ changed = TRUE;
+ }
+ if ( item && !item->selected && item->isSelectable() && d->selectionMode != NoSelection ) {
+ item->selected = TRUE;
+ changed = TRUE;
+ emit selectionChanged( item );
+ }
+ if ( changed )
+ emit selectionChanged();
+ }
+
+ if ( old )
+ repaintItem( old );
+ repaintItem( d->currentItem );
+}
+
+/*!
+ Selects or unselects \a item depending on \a s, and may also
+ unselect other items, depending on TQIconView::selectionMode() and
+ \a cb.
+
+ If \a s is FALSE, \a item is unselected.
+
+ If \a s is TRUE and TQIconView::selectionMode() is \c Single, \a
+ item is selected, and the item which was selected is unselected.
+
+ If \a s is TRUE and TQIconView::selectionMode() is \c Extended, \a
+ item is selected. If \a cb is TRUE, the selection state of the
+ icon view's other items is left unchanged. If \a cb is FALSE (the
+ default) all other items are unselected.
+
+ If \a s is TRUE and TQIconView::selectionMode() is \c Multi \a item
+ is selected.
+
+ Note that \a cb is used only if TQIconView::selectionMode() is \c
+ Extended. \a cb defaults to FALSE.
+
+ All items whose selection status is changed repaint themselves.
+*/
+
+void TQIconView::setSelected( TQIconViewItem *item, bool s, bool cb )
+{
+ if ( !item )
+ return;
+ item->setSelected( s, cb );
+}
+
+/*!
+ \property TQIconView::count
+ \brief the number of items in the icon view
+*/
+
+uint TQIconView::count() const
+{
+ return d->count;
+}
+
+/*!
+ Performs autoscrolling when selecting multiple icons with the
+ rubber band.
+*/
+
+void TQIconView::doAutoScroll()
+{
+ TQRect oldRubber = *d->rubber;
+
+ TQPoint vp = viewport()->mapFromGlobal( TQCursor::pos() );
+ TQPoint pos = viewportToContents( vp );
+
+ if ( pos == d->rubber->bottomRight() )
+ return;
+
+ d->rubber->setRight( pos.x() );
+ d->rubber->setBottom( pos.y() );
+
+ int minx = contentsWidth(), miny = contentsHeight();
+ int maxx = 0, maxy = 0;
+ bool changed = FALSE;
+ bool block = signalsBlocked();
+
+ TQRect rr;
+
+ blockSignals( TRUE );
+ viewport()->setUpdatesEnabled( FALSE );
+ bool alreadyIntersected = FALSE;
+ TQRect nr = d->rubber->normalize();
+ TQRect rubberUnion = nr.unite( oldRubber.normalize() );
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer;
+ for ( ; c; c = c->n ) {
+ if ( c->rect.intersects( rubberUnion ) ) {
+ alreadyIntersected = TRUE;
+ TQIconViewItem *item = c->items.first();
+ for ( ; item; item = c->items.next() ) {
+ if ( d->selectedItems.find( item ) )
+ continue;
+ if ( !item->intersects( nr ) ) {
+ if ( item->isSelected() ) {
+ item->setSelected( FALSE );
+ changed = TRUE;
+ rr = rr.unite( item->rect() );
+ }
+ } else if ( item->intersects( nr ) ) {
+ if ( !item->isSelected() && item->isSelectable() ) {
+ item->setSelected( TRUE, TRUE );
+ changed = TRUE;
+ rr = rr.unite( item->rect() );
+ }
+
+ minx = TQMIN( minx, item->x() - 1 );
+ miny = TQMIN( miny, item->y() - 1 );
+ maxx = TQMAX( maxx, item->x() + item->width() + 1 );
+ maxy = TQMAX( maxy, item->y() + item->height() + 1 );
+ }
+ }
+ } else {
+ if ( alreadyIntersected )
+ break;
+ }
+ }
+ viewport()->setUpdatesEnabled( TRUE );
+ blockSignals( block );
+
+ // static bool drawAll;
+ if ( d->backrubber == 0 ) {
+ d->backrubber = new TQPixmap( viewport()->rect().size() );
+ d->backrubber->fill( viewport(), viewport()->rect().topLeft() );
+ // drawAll = true;
+ }
+
+ // int oldX = 0, oldY = 0;
+ // if ( !drawAll && d->scrollTimer ) {
+ // oldX = contentsX();
+ // oldY = contentsY();
+ // }
+ ensureVisible( pos.x(), pos.y() );
+ // if ( !drawAll && d->scrollTimer && ( oldX != contentsX() || oldY != contentsY() ) )
+ // drawAll = true;
+
+ TQRect allRect = oldRubber.normalize();
+ if ( changed )
+ allRect |= rr.normalize();
+ allRect |= d->rubber->normalize();
+ TQPoint point = contentsToViewport( allRect.topLeft() );
+ allRect = TQRect( point.x(), point.y(), allRect.width(), allRect.height() );
+ allRect &= viewport()->rect();
+
+ d->dragging = FALSE;
+
+ TQPainter p( d->backrubber );
+ p.translate( -contentsX(), -contentsY() );
+#if 0
+ if ( !drawAll ) {
+ oldRubber = oldRubber.normalize();
+ point = contentsToViewport( oldRubber.topLeft() );
+ oldRubber = TQRect( point.x(), point.y(), oldRubber.width(), oldRubber.height() );
+ oldRubber &= viewport()->rect();
+
+ point = contentsToViewport( nr.topLeft() );
+ nr = TQRect( point.x(), point.y(), nr.width(), nr.height() );
+ nr &= viewport()->rect();
+
+ TQRegion region;
+ if ( allRect != nr )
+ region = TQRegion(allRect).subtract( TQRegion( nr ) );
+ if ( allRect != oldRubber )
+ region += TQRegion(allRect).subtract( TQRegion( oldRubber ) );
+
+ TQMemArray< TQRect > ar = region.rects();
+ for ( uint i = 0; i < ar.size(); ++i ) {
+ ar[i].addCoords( -2, -2, 4, 4 );
+ ar[i] = ar[i].normalize();
+
+ p.setClipRect( ar[i] );
+ drawContents( &p, contentsX() + ar[i].left(), contentsY() + ar[i].top(), ar[i].width(), ar[i].height() );
+ }
+ }
+ else
+#endif
+ {
+ drawContents( &p,
+ contentsX() + allRect.left(), contentsY() + allRect.top(),
+ allRect.width(), allRect.height() );
+ }
+
+ p.end();
+ // drawAll = false;
+ d->dragging = TRUE;
+ bitBlt( viewport(), allRect.topLeft(), d->backrubber, allRect );
+
+ if ( changed ) {
+ emit selectionChanged();
+ if ( d->selectionMode == Single )
+ emit selectionChanged( d->currentItem );
+ }
+
+ if ( !TQRect( 50, 50, viewport()->width()-100, viewport()->height()-100 ).contains( vp ) &&
+ !d->scrollTimer ) {
+ d->scrollTimer = new TQTimer( this );
+
+ connect( d->scrollTimer, TQ_SIGNAL( timeout() ),
+ this, TQ_SLOT( doAutoScroll() ) );
+ d->scrollTimer->start( 100, FALSE );
+ } else if ( TQRect( 50, 50, viewport()->width()-100, viewport()->height()-100 ).contains( vp ) &&
+ d->scrollTimer ) {
+ disconnect( d->scrollTimer, TQ_SIGNAL( timeout() ),
+ this, TQ_SLOT( doAutoScroll() ) );
+ d->scrollTimer->stop();
+ delete d->scrollTimer;
+ d->scrollTimer = 0;
+ }
+
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::drawContents( TQPainter *p, int cx, int cy, int cw, int ch )
+{
+ p->save();
+ TQRect r = TQRect( cx, cy, cw, ch );
+
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer;
+ TQRegion remaining( TQRect( cx, cy, cw, ch ) );
+ bool alreadyIntersected = FALSE;
+ while ( c ) {
+ if ( c->rect.intersects( r ) ) {
+ p->save();
+ p->resetXForm();
+ TQRect r2 = c->rect;
+ r2 = r2.intersect( r );
+ TQRect r3( contentsToViewport( TQPoint( r2.x(), r2.y() ) ), TQSize( r2.width(), r2.height() ) );
+ if ( d->drawAllBack ) {
+ p->setClipRect( r3 );
+ } else {
+ TQRegion reg = d->clipRegion.intersect( r3 );
+ p->setClipRegion( reg );
+ }
+ drawBackground( p, r3 );
+ remaining = remaining.subtract( r3 );
+ p->restore();
+
+ TQColorGroup cg;
+ d->drawActiveSelection = hasFocus() || d->inMenuMode
+ || !style().styleHint( TQStyle::SH_ItemView_ChangeHighlightOnFocus, this );
+
+ if ( !d->drawActiveSelection )
+ cg = palette().inactive();
+ else
+ cg = colorGroup();
+
+ TQIconViewItem *item = c->items.first();
+ // clip items to the container rect by default... this
+ // prevents icons with alpha channels from being painted
+ // twice when they are in 2 containers
+ //
+ // NOTE: the item could override this cliprect in it's
+ // paintItem() implementation, which makes this useless
+ p->setClipRect( TQRect( contentsToViewport( r2.topLeft() ), r2.size() ) );
+ for ( ; item; item = c->items.next() ) {
+ if ( item->rect().intersects( r ) && !item->dirty ) {
+ p->save();
+ p->setFont( font() );
+ item->paintItem( p, cg );
+ p->restore();
+ }
+ }
+ alreadyIntersected = TRUE;
+ } else {
+ if ( alreadyIntersected )
+ break;
+ }
+ c = c->n;
+ }
+
+ if ( !remaining.isNull() && !remaining.isEmpty() ) {
+ p->save();
+ p->resetXForm();
+ if ( d->drawAllBack ) {
+ p->setClipRegion( remaining );
+ } else {
+ remaining = d->clipRegion.intersect( remaining );
+ p->setClipRegion( remaining );
+ }
+ drawBackground( p, remaining.boundingRect() );
+ p->restore();
+ }
+
+ if ( ( hasFocus() || viewport()->hasFocus() ) && d->currentItem &&
+ d->currentItem->rect().intersects( r ) ) {
+ d->currentItem->paintFocus( p, colorGroup() );
+ }
+
+ p->restore();
+ if ( d->rubber ) {
+ p->save();
+ p->translate( contentsX(), contentsY() );
+ p->setRasterOp( NotROP );
+ p->setPen( TQPen( color0, 1 ) );
+ p->setBrush( NoBrush );
+ drawRubber( p );
+ p->restore();
+ }
+}
+
+/*!
+ \overload
+
+ Arranges all the items in the grid given by gridX() and gridY().
+
+ Even if sorting() is enabled, the items are not sorted by this
+ function. If you want to sort or rearrange the items, use
+ iconview->sort(iconview->sortDirection()).
+
+ If \a update is TRUE (the default), the viewport is repainted as
+ well.
+
+ \sa TQIconView::setGridX(), TQIconView::setGridY(), TQIconView::sort()
+*/
+
+void TQIconView::arrangeItemsInGrid( bool update )
+{
+ if ( !d->firstItem || !d->lastItem )
+ return;
+
+ d->containerUpdateLocked = TRUE;
+
+ int w = 0, h = 0, y = d->spacing;
+
+ TQIconViewItem *item = d->firstItem;
+ while (item && (item->isVisible() == FALSE)) {
+ item = item->next;
+ }
+ bool changedLayout = FALSE;
+ while ( item ) {
+ bool changed;
+ TQIconViewItem *next = makeRowLayout( item, y, changed );
+ changedLayout = changed || changedLayout;
+ if( !TQApplication::reverseLayout() )
+ item = next;
+ w = TQMAX( w, item->x() + item->width() );
+ h = TQMAX( h, item->y() + item->height() );
+ item = next;
+ if ( d->arrangement == LeftToRight )
+ h = TQMAX( h, y );
+
+ if ( !item || !item->next )
+ break;
+
+ item = item->next;
+ while (item && (item->isVisible() == FALSE)) {
+ item = item->next;
+ }
+ }
+
+ if ( d->lastItem && d->arrangement == TopToBottom ) {
+ item = d->lastItem;
+ while (item && (item->isVisible() == FALSE)) {
+ item = item->prev;
+ }
+ int x = 0;
+ if (item)
+ x = item->x();
+ while ( item && item->x() >= x ) {
+ w = TQMAX( w, item->x() + item->width() );
+ h = TQMAX( h, item->y() + item->height() );
+ item = item->prev;
+ while (item && (item->isVisible() == FALSE)) {
+ item = item->prev;
+ }
+ }
+ }
+ d->containerUpdateLocked = FALSE;
+
+ TQIconViewItem *lastVisibleItem = d->lastItem;
+ while (lastVisibleItem->prev && (lastVisibleItem->isVisible() == FALSE)) {
+ lastVisibleItem = lastVisibleItem->prev;
+ }
+
+ w = TQMAX( TQMAX( d->cachedW, w ), lastVisibleItem->x() + lastVisibleItem->width() );
+ h = TQMAX( TQMAX( d->cachedH, h ), lastVisibleItem->y() + lastVisibleItem->height() );
+
+ if ( d->arrangement == TopToBottom )
+ w += d->spacing;
+ else
+ h += d->spacing;
+
+ bool ue = isUpdatesEnabled();
+ viewport()->setUpdatesEnabled( FALSE );
+ int vw = visibleWidth();
+ int vh = visibleHeight();
+ resizeContents( w, h );
+ bool doAgain = FALSE;
+ if ( d->arrangement == LeftToRight )
+ doAgain = visibleWidth() != vw;
+ if ( d->arrangement == TopToBottom )
+ doAgain = visibleHeight() != vh;
+ if ( doAgain ) // in the case that the visibleExtend changed because of the resizeContents (scrollbar show/hide), redo layout again
+ arrangeItemsInGrid( FALSE );
+ viewport()->setUpdatesEnabled( ue );
+ d->dirty = !isVisible();
+ rebuildContainers();
+ if ( update && ( !optimize_layout || changedLayout ) )
+ repaintContents( contentsX(), contentsY(), viewport()->width(), viewport()->height(), FALSE );
+}
+
+/*!
+ This variant uses \a grid instead of (gridX(), gridY()). If \a
+ grid is invalid (see TQSize::isValid()), arrangeItemsInGrid()
+ calculates a valid grid itself and uses that.
+
+ If \a update is TRUE (the default) the viewport is repainted.
+*/
+
+void TQIconView::arrangeItemsInGrid( const TQSize &grid, bool update )
+{
+ d->containerUpdateLocked = TRUE;
+ TQSize grid_( grid );
+ if ( !grid_.isValid() ) {
+ int w = 0, h = 0;
+ TQIconViewItem *item = d->firstItem;
+ for ( ; item; item = item->next ) {
+ w = TQMAX( w, item->width() );
+ h = TQMAX( h, item->height() );
+ }
+
+ grid_ = TQSize( TQMAX( d->rastX + d->spacing, w ),
+ TQMAX( d->rastY + d->spacing, h ) );
+ }
+
+ int w = 0, h = 0;
+ TQIconViewItem *item = d->firstItem;
+ for ( ; item; item = item->next ) {
+ int nx = item->x() / grid_.width();
+ int ny = item->y() / grid_.height();
+ item->move( nx * grid_.width(),
+ ny * grid_.height() );
+ w = TQMAX( w, item->x() + item->width() );
+ h = TQMAX( h, item->y() + item->height() );
+ item->dirty = FALSE;
+ }
+ d->containerUpdateLocked = FALSE;
+
+ resizeContents( w, h );
+ rebuildContainers();
+ if ( update )
+ repaintContents( contentsX(), contentsY(), viewport()->width(), viewport()->height(), FALSE );
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::setContentsPos( int x, int y )
+{
+ if ( d->updateTimer->isActive() ) {
+ d->cachedContentsX = x;
+ d->cachedContentsY = y;
+ } else {
+ d->cachedContentsY = d->cachedContentsX = -1;
+ TQScrollView::setContentsPos( x, y );
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::showEvent( TQShowEvent * )
+{
+ if ( d->dirty ) {
+ resizeContents( TQMAX( contentsWidth(), viewport()->width() ),
+ TQMAX( contentsHeight(), viewport()->height() ) );
+ if ( d->resortItemsWhenInsert )
+ sort( d->sortDirection );
+ if ( autoArrange() )
+ arrangeItemsInGrid( FALSE );
+ }
+ TQScrollView::show();
+}
+
+/*!
+ \property TQIconView::selectionMode
+ \brief the selection mode of the icon view
+
+ This can be \c Single (the default), \c Extended, \c Multi or \c
+ NoSelection.
+*/
+
+void TQIconView::setSelectionMode( SelectionMode m )
+{
+ d->selectionMode = m;
+}
+
+TQIconView::SelectionMode TQIconView::selectionMode() const
+{
+ return d->selectionMode;
+}
+
+/*!
+ Returns a pointer to the item that contains point \a pos, which is
+ given in contents coordinates, or 0 if no item contains point \a
+ pos.
+*/
+
+TQIconViewItem *TQIconView::findItem( const TQPoint &pos ) const
+{
+ if ( !d->firstItem )
+ return 0;
+
+ TQIconViewPrivate::ItemContainer *c = d->lastContainer;
+ for ( ; c; c = c->p ) {
+ if ( c->rect.contains( pos ) ) {
+ TQIconViewItem *item = c->items.last();
+ for ( ; item; item = c->items.prev() )
+ if ( item->contains( pos ) )
+ return item;
+ }
+ }
+
+ return 0;
+}
+
+/*!
+ \overload
+
+ Returns a pointer to the first item whose text begins with \a
+ text, or 0 if no such item could be found. Use the \a compare flag
+ to control the comparison behaviour. (See \l
+ {TQt::StringComparisonMode}.)
+*/
+
+TQIconViewItem *TQIconView::findItem( const TQString &text, ComparisonFlags compare ) const
+{
+ if ( !d->firstItem )
+ return 0;
+
+ if ( compare == CaseSensitive || compare == 0 )
+ compare |= ExactMatch;
+
+ TQString itmtxt;
+ TQString comtxt = text;
+ if ( ! (compare & CaseSensitive) )
+ comtxt = text.lower();
+
+ TQIconViewItem *item;
+ if ( d->currentItem )
+ item = d->currentItem;
+ else
+ item = d->firstItem;
+
+ TQIconViewItem *beginsWithItem = 0;
+ TQIconViewItem *endsWithItem = 0;
+ TQIconViewItem *containsItem = 0;
+
+ if ( item ) {
+ for ( ; item; item = item->next ) {
+ if ( ! (compare & CaseSensitive) )
+ itmtxt = item->text().lower();
+ else
+ itmtxt = item->text();
+
+ if ( compare & ExactMatch && itmtxt == comtxt )
+ return item;
+ if ( compare & BeginsWith && !beginsWithItem && itmtxt.startsWith( comtxt ) )
+ beginsWithItem = containsItem = item;
+ if ( compare & EndsWith && !endsWithItem && itmtxt.endsWith( comtxt ) )
+ endsWithItem = containsItem = item;
+ if ( compare & Contains && !containsItem && itmtxt.contains( comtxt ) )
+ containsItem = item;
+ }
+
+ if ( d->currentItem && d->firstItem ) {
+ item = d->firstItem;
+ for ( ; item && item != d->currentItem; item = item->next ) {
+ if ( ! (compare & CaseSensitive) )
+ itmtxt = item->text().lower();
+ else
+ itmtxt = item->text();
+
+ if ( compare & ExactMatch && itmtxt == comtxt )
+ return item;
+ if ( compare & BeginsWith && !beginsWithItem && itmtxt.startsWith( comtxt ) )
+ beginsWithItem = containsItem = item;
+ if ( compare & EndsWith && !endsWithItem && itmtxt.endsWith( comtxt ) )
+ endsWithItem = containsItem = item;
+ if ( compare & Contains && !containsItem && itmtxt.contains( comtxt ) )
+ containsItem = item;
+ }
+ }
+ }
+
+ // Obey the priorities
+ if ( beginsWithItem )
+ return beginsWithItem;
+ else if ( endsWithItem )
+ return endsWithItem;
+ else if ( containsItem )
+ return containsItem;
+ return 0;
+}
+
+/*!
+ Unselects all the items.
+*/
+
+void TQIconView::clearSelection()
+{
+ selectAll( FALSE );
+}
+
+/*!
+ In Multi and Extended modes, this function sets all items to be
+ selected if \a select is TRUE, and to be unselected if \a select
+ is FALSE.
+
+ In Single and NoSelection modes, this function only changes the
+ selection status of currentItem().
+*/
+
+void TQIconView::selectAll( bool select )
+{
+ if ( d->selectionMode == NoSelection )
+ return;
+
+ if ( d->selectionMode == Single ) {
+ if ( d->currentItem )
+ d->currentItem->setSelected( select );
+ return;
+ }
+
+ bool b = signalsBlocked();
+ blockSignals( TRUE );
+ TQIconViewItem *item = d->firstItem;
+ TQIconViewItem *i = d->currentItem;
+ bool changed = FALSE;
+ bool ue = viewport()->isUpdatesEnabled();
+ viewport()->setUpdatesEnabled( FALSE );
+ TQRect rr;
+ for ( ; item; item = item->next ) {
+ if (item->isVisible()) {
+ if ( select != item->isSelected() ) {
+ item->setSelected( select, TRUE );
+ rr = rr.unite( item->rect() );
+ changed = TRUE;
+ }
+ }
+ else {
+ if ( FALSE != item->isSelected() ) {
+ item->setSelected( FALSE, TRUE );
+ changed = TRUE;
+ }
+ }
+ }
+ viewport()->setUpdatesEnabled( ue );
+ // we call updateContents not repaintContents because of possible previous updateContents
+ TQScrollView::updateContents( rr );
+ TQApplication::sendPostedEvents( viewport(), TQEvent::Paint );
+ if ( i )
+ setCurrentItem( i );
+ blockSignals( b );
+ if ( changed ) {
+ emit selectionChanged();
+ }
+}
+
+/*!
+ Inverts the selection. Works only in Multi and Extended selection
+ mode.
+*/
+
+void TQIconView::invertSelection()
+{
+ if ( d->selectionMode == Single ||
+ d->selectionMode == NoSelection )
+ return;
+
+ bool b = signalsBlocked();
+ blockSignals( TRUE );
+ TQIconViewItem *item = d->firstItem;
+ for ( ; item; item = item->next ) {
+ if (item->isVisible()) {
+ item->setSelected( !item->isSelected(), TRUE );
+ }
+ else {
+ if ( FALSE != item->isSelected() ) {
+ item->setSelected( FALSE, TRUE );
+ }
+ }
+ }
+ blockSignals( b );
+ emit selectionChanged();
+}
+
+/*!
+ Repaints the \a item.
+*/
+
+void TQIconView::repaintItem( TQIconViewItem *item )
+{
+ if ( !item || item->dirty )
+ return;
+
+ if ( TQRect( contentsX(), contentsY(), visibleWidth(), visibleHeight() ).
+ intersects( TQRect( item->x() - 1, item->y() - 1, item->width() + 2, item->height() + 2 ) ) )
+ repaintContents( item->x() - 1, item->y() - 1, item->width() + 2, item->height() + 2, FALSE );
+}
+
+/*!
+ Repaints the selected items.
+*/
+void TQIconView::repaintSelectedItems()
+{
+ if ( selectionMode() == NoSelection )
+ return;
+
+ if ( selectionMode() == Single ) {
+ if ( !currentItem() || !currentItem()->isSelected() )
+ return;
+ TQRect itemRect = currentItem()->rect(); //rect in contents coordinates
+ itemRect.moveBy( -contentsX(), -contentsY() );
+ viewport()->update( itemRect );
+ } else {
+ // check if any selected items are visible
+ TQIconViewItem *item = firstItem();
+ const TQRect vr = TQRect( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
+
+ while ( item ) {
+ if ( item->isSelected() && item->rect().intersects( vr ) )
+ repaintItem( item );
+ item = item->nextItem();
+ }
+ }
+}
+
+/*!
+ Makes sure that \a item is entirely visible. If necessary,
+ ensureItemVisible() scrolls the icon view.
+
+ \sa ensureVisible()
+*/
+
+void TQIconView::ensureItemVisible( TQIconViewItem *item )
+{
+ if ( !item )
+ return;
+
+ if ( (d->updateTimer && d->updateTimer->isActive()) ||
+ (d->fullRedrawTimer && d->fullRedrawTimer->isActive()) )
+ slotUpdate();
+
+ int w = item->width();
+ int h = item->height();
+ ensureVisible( item->x() + w / 2, item->y() + h / 2,
+ w / 2 + 1, h / 2 + 1 );
+}
+
+/*!
+ Finds the first item whose bounding rectangle overlaps \a r and
+ returns a pointer to that item. \a r is given in content
+ coordinates. Returns 0 if no item overlaps \a r.
+
+ If you want to find all items that touch \a r, you will need to
+ use this function and nextItem() in a loop ending at
+ findLastVisibleItem() and test TQIconViewItem::rect() for each of
+ these items.
+
+ \sa findLastVisibleItem() TQIconViewItem::rect()
+*/
+
+TQIconViewItem* TQIconView::findFirstVisibleItem( const TQRect &r ) const
+{
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer;
+ TQIconViewItem *i = 0;
+ bool alreadyIntersected = FALSE;
+ for ( ; c; c = c->n ) {
+ if ( c->rect.intersects( r ) ) {
+ alreadyIntersected = TRUE;
+ TQIconViewItem *item = c->items.first();
+ for ( ; item; item = c->items.next() ) {
+ if ( r.intersects( item->rect() ) ) {
+ if ( !i ) {
+ i = item;
+ } else {
+ TQRect r2 = item->rect();
+ TQRect r3 = i->rect();
+ if ( r2.y() < r3.y() )
+ i = item;
+ else if ( r2.y() == r3.y() &&
+ r2.x() < r3.x() )
+ i = item;
+ }
+ }
+ }
+ } else {
+ if ( alreadyIntersected )
+ break;
+ }
+ }
+
+ return i;
+}
+
+/*!
+ Finds the last item whose bounding rectangle overlaps \a r and
+ returns a pointer to that item. \a r is given in content
+ coordinates. Returns 0 if no item overlaps \a r.
+
+ \sa findFirstVisibleItem()
+*/
+
+TQIconViewItem* TQIconView::findLastVisibleItem( const TQRect &r ) const
+{
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer;
+ TQIconViewItem *i = 0;
+ bool alreadyIntersected = FALSE;
+ for ( ; c; c = c->n ) {
+ if ( c->rect.intersects( r ) ) {
+ alreadyIntersected = TRUE;
+ TQIconViewItem *item = c->items.first();
+ for ( ; item; item = c->items.next() ) {
+ if ( r.intersects( item->rect() ) ) {
+ if ( !i ) {
+ i = item;
+ } else {
+ TQRect r2 = item->rect();
+ TQRect r3 = i->rect();
+ if ( r2.y() > r3.y() )
+ i = item;
+ else if ( r2.y() == r3.y() &&
+ r2.x() > r3.x() )
+ i = item;
+ }
+ }
+ }
+ } else {
+ if ( alreadyIntersected )
+ break;
+ }
+ }
+
+ return i;
+}
+
+/*!
+ Clears the icon view. All items are deleted.
+*/
+
+void TQIconView::clear()
+{
+ setContentsPos( 0, 0 );
+ d->clearing = TRUE;
+ bool block = signalsBlocked();
+ blockSignals( TRUE );
+ clearSelection();
+ blockSignals( block );
+ setContentsPos( 0, 0 );
+ d->currentItem = 0;
+
+ if ( !d->firstItem ) {
+ d->clearing = FALSE;
+ return;
+ }
+
+ TQIconViewItem *item = d->firstItem, *tmp;
+ d->firstItem = 0;
+ while ( item ) {
+ tmp = item->next;
+ delete item;
+ item = tmp;
+ }
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer, *tmpc;
+ while ( c ) {
+ tmpc = c->n;
+ delete c;
+ c = tmpc;
+ }
+ d->firstContainer = d->lastContainer = 0;
+
+ d->count = 0;
+ d->lastItem = 0;
+ setCurrentItem( 0 );
+ d->highlightedItem = 0;
+ d->tmpCurrentItem = 0;
+ d->drawDragShapes = FALSE;
+
+ resizeContents( 0, 0 );
+ // maybe we don�t need this update, so delay it
+ d->fullRedrawTimer->start( 0, TRUE );
+
+ d->cleared = TRUE;
+ d->clearing = FALSE;
+}
+
+/*!
+ \property TQIconView::gridX
+ \brief the horizontal grid of the icon view
+
+ If the value is -1, (the default), TQIconView computes suitable
+ column widths based on the icon view's contents.
+
+ Note that setting a grid width overrides setMaxItemWidth().
+*/
+
+void TQIconView::setGridX( int rx )
+{
+ d->rastX = rx >= 0 ? rx : -1;
+}
+
+/*!
+ \property TQIconView::gridY
+ \brief the vertical grid of the icon view
+
+ If the value is -1, (the default), TQIconView computes suitable
+ column heights based on the icon view's contents.
+*/
+
+void TQIconView::setGridY( int ry )
+{
+ d->rastY = ry >= 0 ? ry : -1;
+}
+
+int TQIconView::gridX() const
+{
+ return d->rastX;
+}
+
+int TQIconView::gridY() const
+{
+ return d->rastY;
+}
+
+/*!
+ \property TQIconView::spacing
+ \brief the space in pixels between icon view items
+
+ The default is 5 pixels.
+
+ Negative values for spacing are illegal.
+*/
+
+void TQIconView::setSpacing( int sp )
+{
+ d->spacing = sp;
+}
+
+int TQIconView::spacing() const
+{
+ return d->spacing;
+}
+
+/*!
+ \property TQIconView::itemTextPos
+ \brief the position where the text of each item is drawn.
+
+ Valid values are \c Bottom or \c Right. The default is \c Bottom.
+*/
+
+void TQIconView::setItemTextPos( ItemTextPos pos )
+{
+ if ( pos == d->itemTextPos || ( pos != Bottom && pos != Right ) )
+ return;
+
+ d->itemTextPos = pos;
+
+ TQIconViewItem *item = d->firstItem;
+ for ( ; item; item = item->next ) {
+ item->wordWrapDirty = TRUE;
+ item->calcRect();
+ }
+
+ arrangeItemsInGrid( TRUE );
+}
+
+TQIconView::ItemTextPos TQIconView::itemTextPos() const
+{
+ return d->itemTextPos;
+}
+
+/*!
+ \property TQIconView::itemTextBackground
+ \brief the brush to use when drawing the background of an item's text.
+
+ By default this brush is set to NoBrush, meaning that only the
+ normal icon view background is used.
+*/
+
+void TQIconView::setItemTextBackground( const TQBrush &brush )
+{
+ d->itemTextBrush = brush;
+}
+
+TQBrush TQIconView::itemTextBackground() const
+{
+ return d->itemTextBrush;
+}
+
+/*!
+ \property TQIconView::arrangement
+ \brief the arrangement mode of the icon view
+
+ This can be \c LeftToRight or \c TopToBottom. The default is \c
+ LeftToRight.
+*/
+
+void TQIconView::setArrangement( Arrangement am )
+{
+ if ( d->arrangement == am )
+ return;
+
+ d->arrangement = am;
+
+ viewport()->setUpdatesEnabled( FALSE );
+ resizeContents( viewport()->width(), viewport()->height() );
+ viewport()->setUpdatesEnabled( TRUE );
+ arrangeItemsInGrid( TRUE );
+}
+
+TQIconView::Arrangement TQIconView::arrangement() const
+{
+ return d->arrangement;
+}
+
+/*!
+ \property TQIconView::resizeMode
+ \brief the resize mode of the icon view
+
+ This can be \c Fixed or \c Adjust. The default is \c Fixed.
+ See \l ResizeMode.
+*/
+
+void TQIconView::setResizeMode( ResizeMode rm )
+{
+ if ( d->resizeMode == rm )
+ return;
+
+ d->resizeMode = rm;
+}
+
+TQIconView::ResizeMode TQIconView::resizeMode() const
+{
+ return d->resizeMode;
+}
+
+/*!
+ \property TQIconView::maxItemWidth
+ \brief the maximum width that an item may have.
+
+ The default is 100 pixels.
+
+ Note that if the gridX() value is set TQIconView will ignore
+ this property.
+*/
+
+void TQIconView::setMaxItemWidth( int w )
+{
+ d->maxItemWidth = w;
+}
+
+/*!
+ \property TQIconView::maxItemTextLength
+ \brief the maximum length (in characters) that an item's text may have.
+
+ The default is 255 characters.
+*/
+
+void TQIconView::setMaxItemTextLength( int w )
+{
+ d->maxItemTextLength = w;
+}
+
+int TQIconView::maxItemWidth() const
+{
+ if ( d->rastX != -1 )
+ return d->rastX - 2;
+ else
+ return d->maxItemWidth;
+}
+
+int TQIconView::maxItemTextLength() const
+{
+ return d->maxItemTextLength;
+}
+
+/*!
+ \property TQIconView::itemsMovable
+ \brief whether the user is allowed to move items around in the icon view
+
+ The default is TRUE.
+*/
+
+void TQIconView::setItemsMovable( bool b )
+{
+ d->rearrangeEnabled = b;
+}
+
+bool TQIconView::itemsMovable() const
+{
+ return d->rearrangeEnabled;
+}
+
+/*!
+ \property TQIconView::autoArrange
+ \brief whether the icon view rearranges its items when a new item is inserted.
+
+ The default is TRUE.
+
+ Note that if the icon view is not visible at the time of
+ insertion, TQIconView defers all position-related work until it is
+ shown and then calls arrangeItemsInGrid().
+*/
+
+void TQIconView::setAutoArrange( bool b )
+{
+ d->reorderItemsWhenInsert = b;
+}
+
+bool TQIconView::autoArrange() const
+{
+ return d->reorderItemsWhenInsert;
+}
+
+/*!
+ If \a sort is TRUE, this function sets the icon view to sort items
+ when a new item is inserted. If \a sort is FALSE, the icon view
+ will not be sorted.
+
+ Note that autoArrange() must be TRUE for sorting to take place.
+
+ If \a ascending is TRUE (the default), items are sorted in
+ ascending order. If \a ascending is FALSE, items are sorted in
+ descending order.
+
+ TQIconViewItem::compare() is used to compare pairs of items. The
+ sorting is based on the items' keys; these default to the items'
+ text unless specifically set to something else.
+
+ \sa TQIconView::setAutoArrange(), TQIconView::autoArrange(),
+ sortDirection(), sort(), TQIconViewItem::setKey()
+*/
+
+void TQIconView::setSorting( bool sort, bool ascending )
+{
+ d->resortItemsWhenInsert = sort;
+ d->sortDirection = ascending;
+}
+
+/*!
+ \property TQIconView::sorting
+ \brief whether the icon view sorts on insertion
+
+ The default is FALSE, i.e. no sorting on insertion.
+
+ To set the sorting, use setSorting().
+*/
+
+bool TQIconView::sorting() const
+{
+ return d->resortItemsWhenInsert;
+}
+
+/*!
+ \property TQIconView::sortDirection
+ \brief whether the sort direction for inserting new items is ascending;
+
+ The default is TRUE (i.e. ascending). This sort direction is only
+ meaningful if both sorting() and autoArrange() are TRUE.
+
+ To set the sort direction, use setSorting()
+*/
+
+bool TQIconView::sortDirection() const
+{
+ return d->sortDirection;
+}
+
+/*!
+ \property TQIconView::wordWrapIconText
+ \brief whether the item text will be word-wrapped if it is too long
+
+ The default is TRUE.
+
+ If this property is FALSE, icon text that is too long is
+ truncated, and an ellipsis (...) appended to indicate that
+ truncation has occurred. The full text can still be seen by the
+ user if they hover the mouse because the full text is shown in a
+ tooltip; see setShowToolTips().
+*/
+
+void TQIconView::setWordWrapIconText( bool b )
+{
+ if ( d->wordWrapIconText == (uint)b )
+ return;
+
+ d->wordWrapIconText = b;
+ for ( TQIconViewItem *item = d->firstItem; item; item = item->next ) {
+ item->wordWrapDirty = TRUE;
+ item->calcRect();
+ }
+ arrangeItemsInGrid( TRUE );
+}
+
+bool TQIconView::wordWrapIconText() const
+{
+ return d->wordWrapIconText;
+}
+
+/*!
+ \property TQIconView::showToolTips
+ \brief whether the icon view will display a tool tip with the complete text for any truncated item text
+
+ The default is TRUE. Note that this has no effect if
+ setWordWrapIconText() is TRUE, as it is by default.
+*/
+
+void TQIconView::setShowToolTips( bool b )
+{
+ d->showTips = b;
+}
+
+bool TQIconView::showToolTips() const
+{
+ return d->showTips;
+}
+
+/*!
+ \reimp
+*/
+void TQIconView::contentsMousePressEvent( TQMouseEvent *e )
+{
+ contentsMousePressEventEx( e );
+}
+
+void TQIconView::contentsMousePressEventEx( TQMouseEvent *e )
+{
+ if ( d->rubber ) {
+ TQRect r( d->rubber->normalize() );
+ delete d->rubber;
+ d->rubber = 0;
+
+ repaintContents( r, FALSE );
+ d->dragging = FALSE;
+
+ delete d->backrubber;
+ d->backrubber = 0;
+
+ if ( d->scrollTimer ) {
+ disconnect( d->scrollTimer, TQ_SIGNAL( timeout() ), this, TQ_SLOT( doAutoScroll() ) );
+ d->scrollTimer->stop();
+ delete d->scrollTimer;
+ d->scrollTimer = 0;
+ }
+ }
+
+ d->dragStartPos = e->pos();
+ TQIconViewItem *item = findItem( e->pos() );
+ d->pressedItem = item;
+
+ if ( item )
+ d->selectAnchor = item;
+
+#ifndef TQT_NO_TEXTEDIT
+ if ( d->renamingItem )
+ d->renamingItem->renameItem();
+#endif
+
+ if ( !d->currentItem && !item && d->firstItem ) {
+ d->currentItem = d->firstItem;
+ repaintItem( d->firstItem );
+ }
+
+ if (item && item->dragEnabled())
+ d->startDragItem = item;
+ else
+ d->startDragItem = 0;
+
+ if ( e->button() == LeftButton && !( e->state() & ShiftButton ) &&
+ !( e->state() & ControlButton ) && item && item->isSelected() &&
+ item->textRect( FALSE ).contains( e->pos() ) ) {
+
+ if ( !item->renameEnabled() ) {
+ d->mousePressed = TRUE;
+#ifndef TQT_NO_TEXTEDIT
+ } else {
+ ensureItemVisible( item );
+ setCurrentItem( item );
+ item->rename();
+ goto emit_signals;
+#endif
+ }
+ }
+
+ d->pressedSelected = item && item->isSelected();
+
+ if ( item && item->isSelectable() ) {
+ if ( d->selectionMode == Single )
+ item->setSelected( TRUE, e->state() & ControlButton );
+ else if ( d->selectionMode == Multi )
+ item->setSelected( !item->isSelected(), e->state() & ControlButton );
+ else if ( d->selectionMode == Extended ) {
+ if ( e->state() & ShiftButton ) {
+ d->pressedSelected = FALSE;
+ bool block = signalsBlocked();
+ blockSignals( TRUE );
+ viewport()->setUpdatesEnabled( FALSE );
+ TQRect r;
+ bool select = TRUE;
+ if ( d->currentItem )
+ r = TQRect( TQMIN( d->currentItem->x(), item->x() ),
+ TQMIN( d->currentItem->y(), item->y() ),
+ 0, 0 );
+ else
+ r = TQRect( 0, 0, 0, 0 );
+ if ( d->currentItem ) {
+ if ( d->currentItem->x() < item->x() )
+ r.setWidth( item->x() - d->currentItem->x() + item->width() );
+ else
+ r.setWidth( d->currentItem->x() - item->x() + d->currentItem->width() );
+ if ( d->currentItem->y() < item->y() )
+ r.setHeight( item->y() - d->currentItem->y() + item->height() );
+ else
+ r.setHeight( d->currentItem->y() - item->y() + d->currentItem->height() );
+ r = r.normalize();
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer;
+ bool alreadyIntersected = FALSE;
+ TQRect redraw;
+ for ( ; c; c = c->n ) {
+ if ( c->rect.intersects( r ) ) {
+ alreadyIntersected = TRUE;
+ TQIconViewItem *i = c->items.first();
+ for ( ; i; i = c->items.next() ) {
+ if ( r.intersects( i->rect() ) ) {
+ redraw = redraw.unite( i->rect() );
+ i->setSelected( select, TRUE );
+ }
+ }
+ } else {
+ if ( alreadyIntersected )
+ break;
+ }
+ }
+ redraw = redraw.unite( item->rect() );
+ viewport()->setUpdatesEnabled( TRUE );
+ repaintContents( redraw, FALSE );
+ }
+ blockSignals( block );
+ viewport()->setUpdatesEnabled( TRUE );
+ item->setSelected( select, TRUE );
+ emit selectionChanged();
+ } else if ( e->state() & ControlButton ) {
+ d->pressedSelected = FALSE;
+ item->setSelected( !item->isSelected(), e->state() & ControlButton );
+ } else {
+ item->setSelected( TRUE, e->state() & ControlButton );
+ }
+ }
+ } else if ( ( d->selectionMode != Single || e->button() == RightButton )
+ && !( e->state() & ControlButton ) )
+ selectAll( FALSE );
+
+ setCurrentItem( item );
+
+ d->canStartRubber = FALSE;
+ if ( e->button() == LeftButton ) {
+ if ( !item && ( d->selectionMode == Multi || d->selectionMode == Extended ) ) {
+ d->canStartRubber = TRUE;
+ d->rubberStartX = e->x();
+ d->rubberStartY = e->y();
+ }
+
+ d->mousePressed = TRUE;
+ }
+
+ emit_signals:
+ if ( !d->canStartRubber ) {
+ emit mouseButtonPressed( e->button(), item, e->globalPos() );
+ emit pressed( item );
+ emit pressed( item, e->globalPos() );
+
+ if ( e->button() == RightButton )
+ emit rightButtonPressed( item, e->globalPos() );
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::contentsContextMenuEvent( TQContextMenuEvent *e )
+{
+ if ( !receivers( TQ_SIGNAL(contextMenuRequested(TQIconViewItem*,const TQPoint&)) ) ) {
+ e->ignore();
+ return;
+ }
+ if ( e->reason() == TQContextMenuEvent::Keyboard ) {
+ TQIconViewItem *item = currentItem();
+ TQRect r = item ? item->rect() : TQRect( 0, 0, visibleWidth(), visibleHeight() );
+ emit contextMenuRequested( item, viewport()->mapToGlobal( contentsToViewport( r.center() ) ) );
+ } else {
+ d->mousePressed = FALSE;
+ TQIconViewItem *item = findItem( e->pos() );
+ emit contextMenuRequested( item, e->globalPos() );
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::contentsMouseReleaseEvent( TQMouseEvent *e )
+{
+ TQIconViewItem *item = findItem( e->pos() );
+ d->selectedItems.clear();
+
+ bool emitClicked = TRUE;
+ d->mousePressed = FALSE;
+ d->startDragItem = 0;
+
+ d->canStartRubber = FALSE;
+ if ( d->rubber ) {
+ TQRect r(d->rubber->normalize());
+
+ if ( ( d->rubber->topLeft() - d->rubber->bottomRight() ).manhattanLength() >
+ TQApplication::startDragDistance() )
+ emitClicked = FALSE;
+ delete d->rubber;
+ d->rubber = 0;
+ repaintContents(r, FALSE);
+ d->dragging = FALSE;
+ delete d->backrubber;
+ d->backrubber = 0;
+ d->currentItem = d->tmpCurrentItem;
+ d->tmpCurrentItem = 0;
+ if ( d->currentItem )
+ repaintItem( d->currentItem );
+ }
+
+ if ( d->scrollTimer ) {
+ disconnect( d->scrollTimer, TQ_SIGNAL( timeout() ), this, TQ_SLOT( doAutoScroll() ) );
+ d->scrollTimer->stop();
+ delete d->scrollTimer;
+ d->scrollTimer = 0;
+ }
+
+ if ( d->selectionMode == Extended &&
+ d->currentItem == d->pressedItem &&
+ d->pressedSelected && d->currentItem ) {
+ bool block = signalsBlocked();
+ blockSignals( TRUE );
+ clearSelection();
+ blockSignals( block );
+ if ( d->currentItem->isSelectable() ) {
+ d->currentItem->selected = TRUE;
+ repaintItem( d->currentItem );
+ }
+ emit selectionChanged();
+ }
+ d->pressedItem = 0;
+
+ if ( emitClicked ) {
+ emit mouseButtonClicked( e->button(), item, e->globalPos() );
+ emit clicked( item );
+ emit clicked( item, e->globalPos() );
+ if ( e->button() == RightButton )
+ emit rightButtonClicked( item, e->globalPos() );
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::contentsMouseMoveEvent( TQMouseEvent *e )
+{
+ TQIconViewItem *item = findItem( e->pos() );
+ if ( d->highlightedItem != item ) {
+ if ( item )
+ emit onItem( item );
+ else
+ emit onViewport();
+ d->highlightedItem = item;
+ }
+
+ if ( d->mousePressed && e->state() == NoButton )
+ d->mousePressed = FALSE;
+
+ if ( d->startDragItem )
+ item = d->startDragItem;
+
+ if ( d->mousePressed && item && item == d->currentItem &&
+ ( item->isSelected() || d->selectionMode == NoSelection ) && item->dragEnabled() ) {
+ if ( !d->startDragItem ) {
+ d->currentItem->setSelected( TRUE, TRUE );
+ d->startDragItem = item;
+ }
+ if ( ( d->dragStartPos - e->pos() ).manhattanLength() > TQApplication::startDragDistance() ) {
+ d->mousePressed = FALSE;
+ d->cleared = FALSE;
+#ifndef TQT_NO_DRAGANDDROP
+ startDrag();
+#endif
+ if ( d->tmpCurrentItem )
+ repaintItem( d->tmpCurrentItem );
+ }
+ } else if ( d->mousePressed && ((!d->currentItem && d->rubber) || d->canStartRubber) ) {
+ if ( d->canStartRubber ) {
+ d->canStartRubber = FALSE;
+ d->tmpCurrentItem = d->currentItem;
+ d->currentItem = 0;
+ repaintItem( d->tmpCurrentItem );
+ delete d->rubber;
+ d->rubber = new TQRect( d->rubberStartX, d->rubberStartY, 0, 0 );
+ d->selectedItems.clear();
+ if ( ( e->state() & ControlButton ) == ControlButton ||
+ ( e->state() & ShiftButton ) == ShiftButton ) {
+ for ( TQIconViewItem *i = firstItem(); i; i = i->nextItem() )
+ if ( i->isSelected() )
+ d->selectedItems.insert( i, i );
+ }
+ }
+ doAutoScroll();
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::contentsMouseDoubleClickEvent( TQMouseEvent *e )
+{
+ TQIconViewItem *item = findItem( e->pos() );
+ if ( item ) {
+ selectAll( FALSE );
+ item->setSelected( TRUE, TRUE );
+ emit doubleClicked( item );
+ }
+}
+
+/*!
+ \reimp
+*/
+
+#ifndef TQT_NO_DRAGANDDROP
+void TQIconView::contentsDragEnterEvent( TQDragEnterEvent *e )
+{
+ d->dragging = TRUE;
+ d->drawDragShapes = TRUE;
+ d->tmpCurrentItem = 0;
+ initDragEnter( e );
+ d->oldDragPos = e->pos();
+ d->oldDragAcceptAction = FALSE;
+ drawDragShapes( e->pos() );
+ d->dropped = FALSE;
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::contentsDragMoveEvent( TQDragMoveEvent *e )
+{
+ if ( e->pos() == d->oldDragPos ) {
+ if (d->oldDragAcceptAction)
+ e->acceptAction();
+ else
+ e->ignore();
+ return;
+ }
+
+ drawDragShapes( d->oldDragPos );
+ d->dragging = FALSE;
+
+ TQIconViewItem *old = d->tmpCurrentItem;
+ d->tmpCurrentItem = 0;
+
+ TQIconViewItem *item = findItem( e->pos() );
+
+ if ( item ) {
+ if ( old &&
+ old->rect().contains(d->oldDragPos) &&
+ !old->rect().contains(e->pos()) ) {
+ old->dragLeft();
+ repaintItem( old );
+ }
+ if ( !item->rect().contains(d->oldDragPos) )
+ item->dragEntered();
+ if (item->acceptDrop(e) || (item->isSelected() && e->source() == viewport())) {
+ d->oldDragAcceptAction = TRUE;
+ e->acceptAction();
+ } else {
+ d->oldDragAcceptAction = FALSE;
+ e->ignore();
+ }
+
+ d->tmpCurrentItem = item;
+ TQPainter p;
+ p.begin( viewport() );
+ p.translate( -contentsX(), -contentsY() );
+ item->paintFocus( &p, colorGroup() );
+ p.end();
+ } else {
+ e->acceptAction();
+ d->oldDragAcceptAction = TRUE;
+ if ( old ) {
+ old->dragLeft();
+ repaintItem( old );
+ }
+ }
+
+ d->oldDragPos = e->pos();
+ drawDragShapes( e->pos() );
+ d->dragging = TRUE;
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::contentsDragLeaveEvent( TQDragLeaveEvent * )
+{
+ if ( !d->dropped )
+ drawDragShapes( d->oldDragPos );
+ d->dragging = FALSE;
+
+ if ( d->tmpCurrentItem ) {
+ repaintItem( d->tmpCurrentItem );
+ d->tmpCurrentItem->dragLeft();
+ }
+
+ d->tmpCurrentItem = 0;
+ d->isIconDrag = FALSE;
+ d->iconDragData.clear();
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::contentsDropEvent( TQDropEvent *e )
+{
+ d->dropped = TRUE;
+ d->dragging = FALSE;
+ drawDragShapes( d->oldDragPos );
+
+ if ( d->tmpCurrentItem )
+ repaintItem( d->tmpCurrentItem );
+
+ TQIconViewItem *i = findItem( e->pos() );
+
+ if ((!i || i->isSelected()) && e->source() == viewport() && d->currentItem && !d->cleared) {
+ if ( !d->rearrangeEnabled )
+ return;
+ TQRect r = d->currentItem->rect();
+
+ d->currentItem->move( e->pos() - d->dragStart );
+
+ int w = d->currentItem->x() + d->currentItem->width() + 1;
+ int h = d->currentItem->y() + d->currentItem->height() + 1;
+
+ repaintItem( d->currentItem );
+ repaintContents( r.x(), r.y(), r.width(), r.height(), FALSE );
+
+ int dx = d->currentItem->x() - r.x();
+ int dy = d->currentItem->y() - r.y();
+
+ TQIconViewItem *item = d->firstItem;
+ TQRect rr;
+ for ( ; item; item = item->next ) {
+ if ( item->isSelected() && item != d->currentItem ) {
+ rr = rr.unite( item->rect() );
+ item->moveBy( dx, dy );
+ rr = rr.unite( item->rect() );
+ }
+ w = TQMAX( w, item->x() + item->width() + 1 );
+ h = TQMAX( h, item->y() + item->height() + 1 );
+ }
+ repaintContents( rr, FALSE );
+ bool fullRepaint = FALSE;
+ if ( w > contentsWidth() ||
+ h > contentsHeight() )
+ fullRepaint = TRUE;
+
+ int oldw = contentsWidth();
+ int oldh = contentsHeight();
+
+ resizeContents( w, h );
+
+
+ if ( fullRepaint ) {
+ repaintContents( oldw, 0, contentsWidth() - oldw, contentsHeight(), FALSE );
+ repaintContents( 0, oldh, contentsWidth(), contentsHeight() - oldh, FALSE );
+ }
+ e->acceptAction();
+ } else if ( !i && ( e->source() != viewport() || d->cleared ) ) {
+ TQValueList<TQIconDragItem> lst;
+ if ( TQIconDrag::canDecode( e ) ) {
+ TQValueList<TQIconDragDataItem> l;
+ TQIconDragPrivate::decode( e, l );
+ TQValueList<TQIconDragDataItem>::Iterator it = l.begin();
+ for ( ; it != l.end(); ++it )
+ lst << ( *it ).data;
+ }
+ emit dropped( e, lst );
+ } else if ( i ) {
+ TQValueList<TQIconDragItem> lst;
+ if ( TQIconDrag::canDecode( e ) ) {
+ TQValueList<TQIconDragDataItem> l;
+ TQIconDragPrivate::decode( e, l );
+ TQValueList<TQIconDragDataItem>::Iterator it = l.begin();
+ for ( ; it != l.end(); ++it )
+ lst << ( *it ).data;
+ }
+ i->dropped( e, lst );
+ }
+ d->isIconDrag = FALSE;
+}
+#endif
+
+/*!
+ This function grabs all paintevents that otherwise would have been
+ processed by the TQScrollView::viewportPaintEvent(). Here we use a
+ doublebuffer to reduce 'on-paint' flickering on TQIconView
+ (and of course its children).
+
+ \sa TQScrollView::viewportPaintEvent(), TQIconView::drawContents()
+*/
+
+void TQIconView::bufferedPaintEvent( TQPaintEvent* pe )
+{
+ TQWidget* vp = viewport();
+ TQRect r = pe->rect() & vp->rect();
+ int ex = r.x() + contentsX();
+ int ey = r.y() + contentsY();
+ int ew = r.width();
+ int eh = r.height();
+
+ if ( !d->backBuffer )
+ d->backBuffer = new TQPixmap(vp->size());
+ if ( d->backBuffer->size() != vp->size() ) {
+ // Resize function (with hysteresis). Uses a good compromise between memory
+ // consumption and speed (number) of resizes.
+ float newWidth = (float)vp->width();
+ float newHeight = (float)vp->height();
+ if ( newWidth > d->backBuffer->width() || newHeight > d->backBuffer->height() )
+ {
+ newWidth *= 1.1892;
+ newHeight *= 1.1892;
+ d->backBuffer->resize( (int)newWidth, (int)newHeight );
+ } else if ( 1.5*newWidth < d->backBuffer->width() || 1.5*newHeight < d->backBuffer->height() )
+ d->backBuffer->resize( (int)newWidth, (int)newHeight );
+ }
+
+ TQPainter p;
+ p.begin(d->backBuffer, vp);
+ drawContentsOffset(&p, contentsX(), contentsY(), ex, ey, ew, eh);
+ p.end();
+ bitBlt(vp, r.x(), r.y(), d->backBuffer, r.x(), r.y(), ew, eh);
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::resizeEvent( TQResizeEvent* e )
+{
+ TQScrollView::resizeEvent( e );
+ if ( d->resizeMode == Adjust ) {
+ optimize_layout = TRUE;
+ adjustItems();
+ optimize_layout = FALSE;
+#if 0 // no need for timer delay anymore
+ d->oldSize = e->oldSize();
+ if ( d->adjustTimer->isActive() )
+ d->adjustTimer->stop();
+ d->adjustTimer->start( 0, TRUE );
+#endif
+ }
+}
+
+/*!
+ Adjusts the positions of the items to the geometry of the icon
+ view.
+*/
+
+void TQIconView::adjustItems()
+{
+ d->adjustTimer->stop();
+ if ( d->resizeMode == Adjust )
+ arrangeItemsInGrid( TRUE );
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::keyPressEvent( TQKeyEvent *e )
+{
+ if ( !d->firstItem )
+ return;
+
+ if ( !d->currentItem ) {
+ setCurrentItem( d->firstItem );
+ if ( d->selectionMode == Single )
+ d->currentItem->setSelected( TRUE, TRUE );
+ return;
+ }
+
+ bool selectCurrent = TRUE;
+
+ switch ( e->key() ) {
+ case Key_Escape:
+ e->ignore();
+ break;
+#ifndef TQT_NO_TEXTEDIT
+ case Key_F2: {
+ if ( d->currentItem->renameEnabled() ) {
+ d->currentItem->renameItem();
+ d->currentItem->rename();
+ return;
+ }
+ } break;
+#endif
+
+ case Key_Home: {
+ d->currInputString = TQString::null;
+ if ( !d->firstItem )
+ break;
+
+ selectCurrent = FALSE;
+
+ TQIconViewItem *item = 0;
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer;
+ while ( !item && c ) {
+ TQPtrList<TQIconViewItem> &list = c->items;
+ TQIconViewItem *i = list.first();
+ while ( i ) {
+ if ( !item ) {
+ item = i;
+ } else {
+ if ( d->arrangement == LeftToRight ) {
+ // we use pixmap so the items textlength are ignored
+ // find topmost, leftmost item
+ if ( i->pixmapRect( FALSE ).y() < item->pixmapRect( FALSE ).y() ||
+ ( i->pixmapRect( FALSE ).y() == item->pixmapRect( FALSE ).y() &&
+ i->pixmapRect( FALSE ).x() < item->pixmapRect( FALSE ).x() ) )
+ item = i;
+ } else {
+ // find leftmost, topmost item
+ if ( i->pixmapRect( FALSE ).x() < item->pixmapRect( FALSE ).x() ||
+ ( i->pixmapRect( FALSE ).x() == item->pixmapRect( FALSE ).x() &&
+ i->pixmapRect( FALSE ).y() < item->pixmapRect( FALSE ).y() ) )
+ item = i;
+ }
+ }
+ i = list.next();
+ }
+ c = c->n;
+ }
+
+ if ( item ) {
+ TQIconViewItem *old = d->currentItem;
+ setCurrentItem( item );
+ ensureItemVisible( item );
+ handleItemChange( old, e->state() & ShiftButton,
+ e->state() & ControlButton, TRUE );
+ }
+ } break;
+
+ case Key_End: {
+ d->currInputString = TQString::null;
+ if ( !d->lastItem )
+ break;
+
+ selectCurrent = FALSE;
+
+ TQIconViewItem *item = 0;
+ TQIconViewPrivate::ItemContainer *c = d->lastContainer;
+ while ( !item && c ) {
+ TQPtrList<TQIconViewItem> &list = c->items;
+ TQIconViewItem *i = list.first();
+ while ( i ) {
+ if ( !item ) {
+ item = i;
+ } else {
+ if ( d->arrangement == LeftToRight ) {
+ // find bottommost, rightmost item
+ if ( i->pixmapRect( FALSE ).bottom() > item->pixmapRect( FALSE ).bottom() ||
+ ( i->pixmapRect( FALSE ).bottom() == item->pixmapRect( FALSE ).bottom() &&
+ i->pixmapRect( FALSE ).right() > item->pixmapRect( FALSE ).right() ) )
+ item = i;
+ } else {
+ // find rightmost, bottommost item
+ if ( i->pixmapRect( FALSE ).right() > item->pixmapRect( FALSE ).right() ||
+ ( i->pixmapRect( FALSE ).right() == item->pixmapRect( FALSE ).right() &&
+ i->pixmapRect( FALSE ).bottom() > item->pixmapRect( FALSE ).bottom() ) )
+ item = i;
+ }
+ }
+ i = list.next();
+ }
+ c = c->p;
+ }
+
+ if ( item ) {
+ TQIconViewItem *old = d->currentItem;
+ setCurrentItem( item );
+ ensureItemVisible( item );
+ handleItemChange( old, e->state() & ShiftButton,
+ e->state() & ControlButton, TRUE );
+ }
+ } break;
+
+ case Key_Space: {
+ d->currInputString = TQString::null;
+ if ( d->selectionMode == Single)
+ break;
+
+ d->currentItem->setSelected( !d->currentItem->isSelected(), TRUE );
+ } break;
+
+ case Key_Enter:
+ case Key_Return:
+ d->currInputString = TQString::null;
+ emit returnPressed( d->currentItem );
+ break;
+
+ case Key_Right: {
+ d->currInputString = TQString::null;
+ selectCurrent = FALSE;
+ Direction dir = DirRight;
+ TQIconViewItem *item = findItem(dir, d->currentItem);
+ if (item) {
+ TQIconViewItem *old=d->currentItem;
+ setCurrentItem(item);
+ ensureItemVisible(item);
+ handleItemChange(old, e->state() & ShiftButton, e->state() & ControlButton );
+ }
+ } break;
+
+ case Key_Left: {
+ d->currInputString = TQString::null;
+ selectCurrent = FALSE;
+ Direction dir = DirLeft;
+ TQIconViewItem *item = findItem(dir, d->currentItem);
+ if (item) {
+ TQIconViewItem *old=d->currentItem;
+ setCurrentItem(item);
+ ensureItemVisible(item);
+ handleItemChange(old, e->state() & ShiftButton, e->state() & ControlButton );
+ }
+ } break;
+
+ case Key_Down: {
+ d->currInputString = TQString::null;
+ selectCurrent = FALSE;
+ Direction dir = DirDown;
+ TQIconViewItem *item = findItem(dir, d->currentItem);
+ if (item) {
+ TQIconViewItem *old=d->currentItem;
+ setCurrentItem(item);
+ ensureItemVisible(item);
+ handleItemChange(old, e->state() & ShiftButton, e->state() & ControlButton );
+ }
+ } break;
+
+ case Key_Up: {
+ d->currInputString = TQString::null;
+ selectCurrent = FALSE;
+ Direction dir = DirUp;
+ TQIconViewItem *item = findItem(dir, d->currentItem);
+ if (item) {
+ TQIconViewItem *old=d->currentItem;
+ setCurrentItem(item);
+ ensureItemVisible(item);
+ handleItemChange(old, e->state() & ShiftButton, e->state() & ControlButton );
+ }
+ } break;
+
+ case Key_Next: {
+ d->currInputString = TQString::null;
+ selectCurrent = FALSE;
+ TQRect r;
+ if ( d->arrangement == LeftToRight )
+ r = TQRect( 0, d->currentItem->y() + visibleHeight(), contentsWidth(), visibleHeight() );
+ else
+ r = TQRect( d->currentItem->x() + visibleWidth(), 0, visibleWidth(), contentsHeight() );
+ TQIconViewItem *item = d->currentItem;
+ TQIconViewItem *ni = findFirstVisibleItem( r );
+ if ( !ni ) {
+ if ( d->arrangement == LeftToRight )
+ r = TQRect( 0, d->currentItem->y() + d->currentItem->height(), contentsWidth(), contentsHeight() );
+ else
+ r = TQRect( d->currentItem->x() + d->currentItem->width(), 0, contentsWidth(), contentsHeight() );
+ ni = findLastVisibleItem( r );
+ }
+ if ( ni ) {
+ setCurrentItem( ni );
+ handleItemChange( item, e->state() & ShiftButton, e->state() & ControlButton );
+ }
+ } break;
+
+ case Key_Prior: {
+ d->currInputString = TQString::null;
+ selectCurrent = FALSE;
+ TQRect r;
+ if ( d->arrangement == LeftToRight )
+ r = TQRect( 0, d->currentItem->y() - visibleHeight(), contentsWidth(), visibleHeight() );
+ else
+ r = TQRect( d->currentItem->x() - visibleWidth(), 0, visibleWidth(), contentsHeight() );
+ TQIconViewItem *item = d->currentItem;
+ TQIconViewItem *ni = findFirstVisibleItem( r );
+ if ( !ni ) {
+ if ( d->arrangement == LeftToRight )
+ r = TQRect( 0, 0, contentsWidth(), d->currentItem->y() );
+ else
+ r = TQRect( 0, 0, d->currentItem->x(), contentsHeight() );
+ ni = findFirstVisibleItem( r );
+ }
+ if ( ni ) {
+ setCurrentItem( ni );
+ handleItemChange( item, e->state() & ShiftButton, e->state() & ControlButton );
+ }
+ } break;
+
+ default:
+ if ( !e->text().isEmpty() && e->text()[ 0 ].isPrint() ) {
+ selectCurrent = FALSE;
+ TQIconViewItem *i = d->currentItem;
+ if ( !i )
+ i = d->firstItem;
+ if ( !d->inputTimer->isActive() ) {
+ d->currInputString = e->text();
+ i = i->next;
+ if ( !i )
+ i = d->firstItem;
+ i = findItemByName( i );
+ } else {
+ d->inputTimer->stop();
+ d->currInputString += e->text();
+ i = findItemByName( i );
+ if ( !i ) {
+ d->currInputString = e->text();
+ if (d->currentItem && d->currentItem->next)
+ i = d->currentItem->next;
+ else
+ i = d->firstItem;
+ i = findItemByName(i);
+ }
+ }
+ if ( i ) {
+ setCurrentItem( i );
+ if ( d->selectionMode == Extended ) {
+ bool changed = FALSE;
+ bool block = signalsBlocked();
+ blockSignals( TRUE );
+ selectAll( FALSE );
+ blockSignals( block );
+ if ( !i->selected && i->isSelectable() ) {
+ changed = TRUE;
+ i->selected = TRUE;
+ repaintItem( i );
+ }
+ if ( changed )
+ emit selectionChanged();
+ }
+ }
+ d->inputTimer->start( 400, TRUE );
+ } else {
+ selectCurrent = FALSE;
+ d->currInputString = TQString::null;
+ if ( e->state() & ControlButton ) {
+ switch ( e->key() ) {
+ case Key_A:
+ selectAll( TRUE );
+ break;
+ }
+ }
+ e->ignore();
+ return;
+ }
+ }
+
+ if ( !( e->state() & ShiftButton ) || !d->selectAnchor )
+ d->selectAnchor = d->currentItem;
+
+ if ( d->currentItem && !d->currentItem->isSelected() &&
+ d->selectionMode == Single && selectCurrent ) {
+ d->currentItem->setSelected( TRUE );
+ }
+
+ ensureItemVisible( d->currentItem );
+}
+
+/*
+ Finds the closest item in the direction \a dir starting from the specified \a fromItem.
+ If the arrangement is LeftToRight (icon view mode): use (center, top) as item reference
+ If the arrangement is TopToBottom (multicolumn view mode): use (left, top) as item reference
+ This is to allow for smooth scrolling when using the keyboard arrow keys.
+*/
+TQIconViewItem* TQIconView::findItem(Direction dir, const TQIconViewItem *fromItem) const
+{
+ TQIconViewItem *closestItem=NULL;
+ int distPri=0, distSec=0;
+ int itemDistancePri=0, itemDistanceSec=0;
+
+ TQPoint pos=fromItem->rect().topLeft();
+ if (d->arrangement == LeftToRight) {
+ pos.setX(fromItem->rect().center().x());
+ }
+
+ TQRect searchRect;
+ switch (dir) {
+ case DirDown:
+ searchRect.setCoords(pos.x(), 0, contentsWidth(), contentsHeight());
+ break;
+
+ case DirUp:
+ searchRect.setCoords(0, 0, pos.x(), contentsHeight());
+ break;
+
+ case DirRight:
+ searchRect.setCoords(0, pos.y(), contentsWidth(), contentsHeight());
+ break;
+
+ case DirLeft:
+ searchRect.setCoords(0, 0, contentsWidth(), pos.y());
+ break;
+ }
+
+ for (TQIconViewPrivate::ItemContainer *c=d->firstContainer; c; c=c->n) {
+ if (c->rect.intersects(searchRect)) {
+ TQPtrList<TQIconViewItem> &list = c->items;
+ for (TQIconViewItem *item=list.first(); item; item=list.next()) {
+ if (item != fromItem) {
+ bool itemOK = true;
+ const TQRect &ir = item->rect();
+ // DirDown/DirUp : primary distance X, secondary distance Y
+ // DirLeft/DirRight: primary distance Y, secondary distance X
+ if (d->arrangement == LeftToRight) {
+ // Left to right arrangement (icon view mode): use (center, top) as item reference
+ switch (dir) {
+ case DirDown:
+ if (ir.center().x() > pos.x()) {
+ distPri = ir.center().x()-pos.x();
+ distSec = ir.top();
+ }
+ else if (ir.center().x() == pos.x() && ir.top() > pos.y()) {
+ distPri = 0;
+ distSec = ir.top()-pos.y();
+ }
+ else {
+ itemOK = false;
+ }
+ break;
+
+ case DirUp:
+ if (ir.center().x() < pos.x()) {
+ distPri = pos.x()-ir.center().x();
+ distSec = contentsHeight()-ir.top();
+ }
+ else if (ir.center().x() == pos.x() && ir.top() < pos.y()) {
+ distPri = 0;
+ distSec = pos.y()-ir.top();
+ }
+ else {
+ itemOK = false;
+ }
+ break;
+
+ case DirRight:
+ if (ir.top() > pos.y()) {
+ distPri = ir.top()-pos.y();
+ distSec = ir.center().x();
+ }
+ else if (ir.top() == pos.y() && ir.center().x() > pos.x()) {
+ distPri = 0;
+ distSec = ir.center().x()-pos.x();
+ }
+ else {
+ itemOK = false;
+ }
+ break;
+
+ case DirLeft:
+ if (ir.top() < pos.y()) {
+ distPri = pos.y()-ir.top();
+ distSec = contentsWidth()-ir.center().x();
+ }
+ else if (ir.top() == pos.y() && ir.center().x() < pos.x()) {
+ distPri = 0;
+ distSec = pos.x()-ir.center().x();
+ }
+ else {
+ itemOK = false;
+ }
+ break;
+
+ default:
+ itemOK = false;
+ break;
+ }
+ }
+ else {
+ // Top to bottom arrangement (multicolumn view mode): use (left, top) as item reference
+ switch (dir) {
+ case DirDown:
+ if (ir.left() > pos.x()) {
+ distPri = ir.left()-pos.x();
+ distSec = ir.top();
+ }
+ else if (ir.left() == pos.x() && ir.top() > pos.y()) {
+ distPri = 0;
+ distSec = ir.top()-pos.y();
+ }
+ else {
+ itemOK = false;
+ }
+ break;
+
+ case DirUp:
+ if (ir.left() < pos.x()) {
+ distPri = pos.x()-ir.left();
+ distSec = contentsHeight()-ir.top();
+ }
+ else if (ir.left() == pos.x() && ir.top() < pos.y()) {
+ distPri = 0;
+ distSec = pos.y()-ir.top();
+ }
+ else {
+ itemOK = false;
+ }
+ break;
+
+ case DirRight:
+ if (ir.top() > pos.y()) {
+ distPri = ir.top()-pos.y();
+ distSec = ir.left();
+ }
+ else if (ir.top() == pos.y() && ir.left() > pos.x()) {
+ distPri = 0;
+ distSec = ir.left()-pos.x();
+ }
+ else {
+ itemOK = false;
+ }
+ break;
+
+ case DirLeft:
+ if (ir.top() < pos.y()) {
+ distPri = pos.y()-ir.top();
+ distSec = contentsWidth()-ir.left();
+ }
+ else if (ir.top() == pos.y() && ir.left() < pos.x()) {
+ distPri = 0;
+ distSec = pos.x()-ir.left();
+ }
+ else {
+ itemOK = false;
+ }
+ break;
+
+ default:
+ itemOK = false;
+ break;
+ }
+ }
+
+ if (itemOK) {
+ if (!closestItem ||
+ ((distPri < itemDistancePri) ||
+ (distPri == itemDistancePri && distSec < itemDistanceSec))) {
+ closestItem = item;
+ itemDistancePri = distPri;
+ itemDistanceSec = distSec;
+ }
+ }
+ }
+ }
+ }
+ }
+ return closestItem;
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::focusInEvent( TQFocusEvent* )
+{
+ d->mousePressed = FALSE;
+ d->inMenuMode = FALSE;
+ if ( d->currentItem ) {
+ repaintItem( d->currentItem );
+ } else if ( d->firstItem && TQFocusEvent::reason() != TQFocusEvent::Mouse ) {
+ d->currentItem = d->firstItem;
+ emit currentChanged( d->currentItem );
+ repaintItem( d->currentItem );
+ }
+
+ if ( style().styleHint( TQStyle::SH_ItemView_ChangeHighlightOnFocus, this ) )
+ repaintSelectedItems();
+
+ if ( d->currentItem )
+ setMicroFocusHint( d->currentItem->x(), d->currentItem->y(), d->currentItem->width(), d->currentItem->height(), FALSE );
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::focusOutEvent( TQFocusEvent* )
+{
+ if (style().styleHint( TQStyle::SH_ItemView_ChangeHighlightOnFocus, this )) {
+ d->inMenuMode =
+ TQFocusEvent::reason() == TQFocusEvent::Popup ||
+ (tqApp->focusWidget() && tqApp->focusWidget()->inherits("TQMenuBar"));
+ if ( !d->inMenuMode )
+ repaintSelectedItems();
+ }
+ if ( d->currentItem )
+ repaintItem( d->currentItem );
+}
+
+/*!
+ Draws the rubber band using the painter \a p.
+*/
+
+void TQIconView::drawRubber( TQPainter *p )
+{
+ if ( !p || !d->rubber )
+ return;
+
+ TQPoint pnt( d->rubber->x(), d->rubber->y() );
+ pnt = contentsToViewport( pnt );
+
+ style().drawPrimitive( TQStyle::PE_RubberBand, p,
+ TQRect( pnt.x(), pnt.y(), d->rubber->width(), d->rubber->height() ).normalize(),
+ colorGroup(), TQStyle::Style_Default, TQStyleOption(colorGroup().base()) );
+}
+
+/*!
+ Returns the TQDragObject that should be used for drag-and-drop.
+ This function is called by the icon view when starting a drag to
+ get the dragobject that should be used for the drag. Subclasses
+ may reimplement this.
+
+ \sa TQIconDrag
+*/
+
+#ifndef TQT_NO_DRAGANDDROP
+TQDragObject *TQIconView::dragObject()
+{
+ if ( !d->currentItem )
+ return 0;
+
+ TQPoint orig = d->dragStartPos;
+
+ TQIconDrag *drag = new TQIconDrag( viewport() );
+ drag->setPixmap( ( d->currentItem->pixmap() ?
+ *d->currentItem->pixmap() : TQPixmap() ), // ### TQPicture
+ TQPoint( d->currentItem->pixmapRect().width() / 2,
+ d->currentItem->pixmapRect().height() / 2 ) );
+
+ if ( d->selectionMode == NoSelection ) {
+ TQIconViewItem *item = d->currentItem;
+ drag->append( TQIconDragItem(),
+ TQRect( item->pixmapRect( FALSE ).x() - orig.x(),
+ item->pixmapRect( FALSE ).y() - orig.y(),
+ item->pixmapRect().width(), item->pixmapRect().height() ),
+ TQRect( item->textRect( FALSE ).x() - orig.x(),
+ item->textRect( FALSE ).y() - orig.y(),
+ item->textRect().width(), item->textRect().height() ) );
+ } else {
+ for ( TQIconViewItem *item = d->firstItem; item; item = item->next ) {
+ if ( item->isSelected() ) {
+ drag->append( TQIconDragItem(),
+ TQRect( item->pixmapRect( FALSE ).x() - orig.x(),
+ item->pixmapRect( FALSE ).y() - orig.y(),
+ item->pixmapRect().width(), item->pixmapRect().height() ),
+ TQRect( item->textRect( FALSE ).x() - orig.x(),
+ item->textRect( FALSE ).y() - orig.y(),
+ item->textRect().width(), item->textRect().height() ) );
+ }
+ }
+ }
+
+ return drag;
+}
+
+/*!
+ Starts a drag.
+*/
+
+void TQIconView::startDrag()
+{
+ if ( !d->startDragItem )
+ return;
+
+ TQPoint orig = d->dragStartPos;
+ d->dragStart = TQPoint( orig.x() - d->startDragItem->x(),
+ orig.y() - d->startDragItem->y() );
+ d->startDragItem = 0;
+ d->mousePressed = FALSE;
+ d->pressedItem = 0;
+ d->pressedSelected = 0;
+
+ TQDragObject *drag = dragObject();
+ if ( !drag )
+ return;
+
+ if ( drag->drag() )
+ if ( drag->target() != viewport() )
+ emit moved();
+}
+
+#endif
+
+/*!
+ Inserts the TQIconViewItem \a item in the icon view's grid. \e{You
+ should never need to call this function.} Instead, insert
+ TQIconViewItems by creating them with a pointer to the TQIconView
+ that they are to be inserted into.
+*/
+
+void TQIconView::insertInGrid( TQIconViewItem *item )
+{
+ if ( !item )
+ return;
+
+ if ( d->reorderItemsWhenInsert ) {
+ // #### make this efficient - but it's not too dramatic
+ int y = d->spacing;
+
+ item->dirty = FALSE;
+ if ( item == d->firstItem ) {
+ bool dummy;
+ makeRowLayout( item, y, dummy );
+ return;
+ }
+
+ TQIconViewItem *begin = rowBegin( item );
+ y = begin->y();
+ while ( begin ) {
+ bool dummy;
+ begin = makeRowLayout( begin, y, dummy );
+
+ if ( !begin || !begin->next )
+ break;
+
+ begin = begin->next;
+ }
+ item->dirty = FALSE;
+ } else {
+ TQRegion r( TQRect( 0, 0, TQMAX( contentsWidth(), visibleWidthSB() ),
+ TQMAX( contentsHeight(), visibleHeightSB() ) ) );
+
+ TQIconViewItem *i = d->firstItem;
+ int y = -1;
+ for ( ; i; i = i->next ) {
+ r = r.subtract( i->rect() );
+ y = TQMAX( y, i->y() + i->height() );
+ }
+
+ TQMemArray<TQRect> rects = r.rects();
+ TQMemArray<TQRect>::Iterator it = rects.begin();
+ bool foundPlace = FALSE;
+ for ( ; it != rects.end(); ++it ) {
+ TQRect rect = *it;
+ if ( rect.width() >= item->width() &&
+ rect.height() >= item->height() ) {
+ int sx = 0, sy = 0;
+ if ( rect.width() >= item->width() + d->spacing )
+ sx = d->spacing;
+ if ( rect.height() >= item->height() + d->spacing )
+ sy = d->spacing;
+ item->move( rect.x() + sx, rect.y() + sy );
+ foundPlace = TRUE;
+ break;
+ }
+ }
+
+ if ( !foundPlace )
+ item->move( d->spacing, y + d->spacing );
+
+ resizeContents( TQMAX( contentsWidth(), item->x() + item->width() ),
+ TQMAX( contentsHeight(), item->y() + item->height() ) );
+ item->dirty = FALSE;
+ }
+}
+
+/*!
+ Emits a signal to indicate selection changes. \a i is the
+ TQIconViewItem that was selected or de-selected.
+
+ \e{You should never need to call this function.}
+*/
+
+void TQIconView::emitSelectionChanged( TQIconViewItem *i )
+{
+ emit selectionChanged();
+ if ( d->selectionMode == Single )
+ emit selectionChanged( i ? i : d->currentItem );
+}
+
+/*!
+ \internal
+*/
+
+void TQIconView::emitRenamed( TQIconViewItem *item )
+{
+ if ( !item )
+ return;
+
+ emit itemRenamed( item, item->text() );
+ emit itemRenamed( item );
+}
+
+/*!
+ If a drag enters the icon view the shapes of the objects which the
+ drag contains are drawn, usnig \a pos as origin.
+*/
+
+void TQIconView::drawDragShapes( const TQPoint &pos )
+{
+#ifndef TQT_NO_DRAGANDDROP
+ if ( pos == TQPoint( -1, -1 ) )
+ return;
+
+ if ( !d->drawDragShapes ) {
+ d->drawDragShapes = TRUE;
+ return;
+ }
+
+ TQStyleOption opt(colorGroup().base());
+
+ TQPainter p;
+ p.begin( viewport() );
+ p.translate( -contentsX(), -contentsY() );
+ p.setRasterOp( NotROP );
+ p.setPen( TQPen( color0 ) );
+
+ if ( d->isIconDrag ) {
+ TQValueList<TQIconDragDataItem>::Iterator it = d->iconDragData.begin();
+ for ( ; it != d->iconDragData.end(); ++it ) {
+ TQRect ir = (*it).item.pixmapRect();
+ TQRect tr = (*it).item.textRect();
+ tr.moveBy( pos.x(), pos.y() );
+ ir.moveBy( pos.x(), pos.y() );
+ if ( !ir.intersects( TQRect( contentsX(), contentsY(), visibleWidth(), visibleHeight() ) ) )
+ continue;
+
+ style().drawPrimitive(TQStyle::PE_FocusRect, &p, ir, colorGroup(),
+ TQStyle::Style_Default, opt);
+ style().drawPrimitive(TQStyle::PE_FocusRect, &p, tr, colorGroup(),
+ TQStyle::Style_Default, opt);
+ }
+ } else if ( d->numDragItems > 0 ) {
+ for ( int i = 0; i < d->numDragItems; ++i ) {
+ TQRect r( pos.x() + i * 40, pos.y(), 35, 35 );
+ style().drawPrimitive(TQStyle::PE_FocusRect, &p, r, colorGroup(),
+ TQStyle::Style_Default, opt);
+ }
+
+ }
+ p.end();
+#endif
+}
+
+/*!
+ When a drag enters the icon view, this function is called to
+ initialize it. Initializing in this context means getting
+ information about the drag, for example so that the icon view
+ knows enough about the drag to be able to draw drag shapes for the
+ drag data (e.g. shapes of icons which are dragged), etc.
+*/
+
+#ifndef TQT_NO_DRAGANDDROP
+void TQIconView::initDragEnter( TQDropEvent *e )
+{
+ if ( TQIconDrag::canDecode( e ) ) {
+ TQIconDragPrivate::decode( e, d->iconDragData );
+ d->isIconDrag = TRUE;
+ } else if ( TQUriDrag::canDecode( e ) ) {
+ TQStrList lst;
+ TQUriDrag::decode( e, lst );
+ d->numDragItems = lst.count();
+ } else {
+ d->numDragItems = 0;
+ }
+
+}
+#endif
+
+/*!
+ This function is called to draw the rectangle \a r of the
+ background using the painter \a p.
+
+ The default implementation fills \a r with the viewport's
+ backgroundBrush(). Subclasses may reimplement this to draw custom
+ backgrounds.
+
+ \sa contentsX() contentsY() drawContents()
+*/
+
+void TQIconView::drawBackground( TQPainter *p, const TQRect &r )
+{
+ p->fillRect( r, viewport()->backgroundBrush() );
+}
+
+/*!
+ \reimp
+*/
+
+bool TQIconView::eventFilter( TQObject * o, TQEvent * e )
+{
+ if ( o == viewport() ) {
+ switch( e->type() ) {
+ case TQEvent::FocusIn:
+ focusInEvent( (TQFocusEvent*)e );
+ return TRUE;
+ case TQEvent::FocusOut:
+ focusOutEvent( (TQFocusEvent*)e );
+ return TRUE;
+ case TQEvent::Enter:
+ enterEvent( e );
+ return TRUE;
+ case TQEvent::Paint:
+ if ( o == viewport() ) {
+ if ( d->dragging ) {
+ if ( !d->rubber )
+ drawDragShapes( d->oldDragPos );
+ viewportPaintEvent( (TQPaintEvent*)e );
+ if ( !d->rubber )
+ drawDragShapes( d->oldDragPos );
+ } else {
+ bufferedPaintEvent( (TQPaintEvent*)e );
+ }
+ }
+ return TRUE;
+ default:
+ // nothing
+ break;
+ }
+ }
+
+ return TQScrollView::eventFilter( o, e );
+}
+
+
+/*!
+ \reimp
+*/
+
+TQSize TQIconView::minimumSizeHint() const
+{
+ return TQScrollView::minimumSizeHint();
+}
+
+/*!
+ \internal
+ Finds the next item after the start item beginning
+ with \a text.
+*/
+
+TQIconViewItem* TQIconView::findItemByName( TQIconViewItem *start )
+{
+ if ( !start )
+ return 0;
+ TQString match = d->currInputString.lower();
+ if ( match.length() < 1 )
+ return start;
+ TQString curText;
+ TQIconViewItem *i = start;
+ do {
+ curText = i->text().lower();
+ if ( curText.startsWith( match ) )
+ return i;
+ i = i->next;
+ if ( !i )
+ i = d->firstItem;
+ } while ( i != start );
+ return 0;
+}
+
+/*!
+ Lays out a row of icons (if Arrangement == \c TopToBottom this is
+ a column). Starts laying out with the item \a begin. \a y is the
+ starting coordinate. Returns the last item of the row (column) and
+ sets the new starting coordinate to \a y. The \a changed parameter
+ is used internally.
+
+ \warning This function may be made private in a future version of
+ TQt. We do not recommend calling it.
+*/
+
+TQIconViewItem *TQIconView::makeRowLayout( TQIconViewItem *begin, int &y, bool &changed )
+{
+ TQIconViewItem *end = 0;
+
+ // Find the first visible item
+ while (begin->next && (begin->isVisible() == FALSE)) {
+ begin = begin->next;
+ }
+
+ bool reverse = TQApplication::reverseLayout();
+ changed = FALSE;
+
+ if ( d->arrangement == LeftToRight ) {
+
+ if ( d->rastX == -1 ) {
+ // first calculate the row height
+ int h = 0;
+ int x = 0;
+ int ih = 0;
+ TQIconViewItem *item = begin;
+ for (;;) {
+ x += d->spacing + item->width();
+ if ( x > visibleWidthSB() && item != begin ) {
+ item = item->prev;
+ while (item && (item->isVisible() == FALSE)) {
+ item = item->prev;
+ }
+ break;
+ }
+ h = TQMAX( h, item->height() );
+ ih = TQMAX( ih, item->pixmapRect().height() );
+ TQIconViewItem *old = item;
+ item = item->next;
+ while (item && (item->isVisible() == FALSE)) {
+ item = item->next;
+ }
+ if ( !item ) {
+ item = old;
+ break;
+ }
+ }
+ end = item;
+
+ if ( d->rastY != -1 )
+ h = TQMAX( h, d->rastY );
+
+ // now move the items
+ item = begin;
+ for (;;) {
+ item->dirty = FALSE;
+ int x;
+ if ( item == begin ) {
+ if ( reverse )
+ x = visibleWidthSB() - d->spacing - item->width();
+ else
+ x = d->spacing;
+ } else {
+ if ( reverse )
+ x = item->prev->x() - item->width() - d->spacing;
+ else
+ x = item->prev->x() + item->prev->width() + d->spacing;
+ }
+ changed = item->move( x, y + ih - item->pixmapRect().height() ) || changed;
+ if ( y + h < item->y() + item->height() )
+ h = TQMAX( h, ih + item->textRect().height() );
+ if ( item == end )
+ break;
+ item = item->next;
+ }
+ y += h + d->spacing;
+ } else {
+ // first calculate the row height
+ int h = begin->height();
+ int x = d->spacing;
+ int ih = begin->pixmapRect().height();
+ TQIconViewItem *item = begin;
+ int i = 0;
+ int sp = 0;
+ for (;;) {
+ int r = calcGridNum( item->width(), d->rastX );
+ if ( item == begin ) {
+ i += r;
+ sp += r;
+ x = d->spacing + d->rastX * r;
+ } else {
+ sp += r;
+ i += r;
+ x = i * d->rastX + sp * d->spacing;
+ }
+ if ( x > visibleWidthSB() && item != begin ) {
+ item = item->prev;
+ while (item && (item->isVisible() == FALSE)) {
+ item = item->prev;
+ }
+ break;
+ }
+ h = TQMAX( h, item->height() );
+ ih = TQMAX( ih, item->pixmapRect().height() );
+ TQIconViewItem *old = item;
+ item = item->next;
+ while (item && (item->isVisible() == FALSE)) {
+ item = item->next;
+ }
+ if ( !item ) {
+ item = old;
+ break;
+ }
+ }
+ end = item;
+
+ if ( d->rastY != -1 )
+ h = TQMAX( h, d->rastY );
+
+ // now move the items
+ item = begin;
+ i = 0;
+ sp = 0;
+ for (;;) {
+ item->dirty = FALSE;
+ int r = calcGridNum( item->width(), d->rastX );
+ if ( item == begin ) {
+ if ( d->itemTextPos == Bottom )
+ changed = item->move( d->spacing + ( r * d->rastX - item->width() ) / 2,
+ y + ih - item->pixmapRect().height() ) || changed;
+ else
+ changed = item->move( d->spacing, y + ih - item->pixmapRect().height() ) || changed;
+ i += r;
+ sp += r;
+ } else {
+ sp += r;
+ int x = i * d->rastX + sp * d->spacing;
+ if ( d->itemTextPos == Bottom )
+ changed = item->move( x + ( r * d->rastX - item->width() ) / 2,
+ y + ih - item->pixmapRect().height() ) || changed;
+ else
+ changed = item->move( x, y + ih - item->pixmapRect().height() ) || changed;
+ i += r;
+ }
+ if ( y + h < item->y() + item->height() )
+ h = TQMAX( h, ih + item->textRect().height() );
+ if ( item == end )
+ break;
+ item = item->next;
+ while (item && (item->isVisible() == FALSE)) {
+ item = item->next;
+ }
+ }
+ y += h + d->spacing;
+ }
+
+
+ } else { // -------------------------------- TopToBottom ------------------------------
+
+ int x = y;
+
+ {
+ int w = 0;
+ int y = 0;
+ TQIconViewItem *item = begin;
+ for (;;) {
+ y += d->spacing + item->height();
+ if ( y > visibleHeightSB() && item != begin ) {
+ item = item->prev;
+ while (item && (item->isVisible() == FALSE)) {
+ item = item->prev;
+ }
+ break;
+ }
+ w = TQMAX( w, item->width() );
+ TQIconViewItem *old = item;
+ item = item->next;
+ while (item && (item->isVisible() == FALSE)) {
+ item = item->next;
+ }
+ if ( !item ) {
+ item = old;
+ break;
+ }
+ }
+ end = item;
+
+ if ( d->rastX != -1 )
+ w = TQMAX( w, d->rastX );
+
+ // now move the items
+ item = begin;
+ TQIconViewItem *prevVisibleItem = NULL;
+ for (;;) {
+ item->dirty = FALSE;
+ if ( d->itemTextPos == Bottom ) {
+ if ( item == begin )
+ changed = item->move( x + ( w - item->width() ) / 2, d->spacing ) || changed;
+ else
+ changed = item->move( x + ( w - item->width() ) / 2,
+ prevVisibleItem->y() + prevVisibleItem->height() + d->spacing ) || changed;
+ } else {
+ if ( item == begin )
+ changed = item->move( x, d->spacing ) || changed;
+ else
+ changed = item->move( x, prevVisibleItem->y() + prevVisibleItem->height() + d->spacing ) || changed;
+ }
+ if ( item == end )
+ break;
+ prevVisibleItem = item;
+ item = item->next;
+ while (item && (item->isVisible() == FALSE)) {
+ item = item->next;
+ }
+ }
+ x += w + d->spacing;
+ }
+
+ y = x;
+ }
+
+ return end;
+}
+
+/*!
+ \internal
+ Calculates how many cells an item of width \a w needs in a grid with of
+ \a x and returns the result.
+*/
+
+int TQIconView::calcGridNum( int w, int x ) const
+{
+ float r = (float)w / (float)x;
+ if ( ( w / x ) * x != w )
+ r += 1.0;
+ return (int)r;
+}
+
+/*!
+ \internal
+ Returns the first item of the row which contains \a item.
+*/
+
+TQIconViewItem *TQIconView::rowBegin( TQIconViewItem * ) const
+{
+ // #### todo
+ return d->firstItem;
+}
+
+/*!
+ Sorts and rearranges all the items in the icon view. If \a
+ ascending is TRUE, the items are sorted in increasing order,
+ otherwise they are sorted in decreasing order.
+
+ TQIconViewItem::compare() is used to compare pairs of items. The
+ sorting is based on the items' keys; these default to the items'
+ text unless specifically set to something else.
+
+ Note that this function sets the sort order to \a ascending.
+
+ \sa TQIconViewItem::key(), TQIconViewItem::setKey(),
+ TQIconViewItem::compare(), TQIconView::setSorting(),
+ TQIconView::sortDirection()
+*/
+
+void TQIconView::sort( bool ascending )
+{
+ if ( count() == 0 )
+ return;
+
+ d->sortDirection = ascending;
+ TQIconViewPrivate::SortableItem *items = new TQIconViewPrivate::SortableItem[ count() ];
+
+ TQIconViewItem *item = d->firstItem;
+ int i = 0;
+ for ( ; item; item = item->next )
+ items[ i++ ].item = item;
+
+ qsort( items, count(), sizeof( TQIconViewPrivate::SortableItem ), cmpIconViewItems );
+
+ TQIconViewItem *prev = 0;
+ item = 0;
+ if ( ascending ) {
+ for ( i = 0; i < (int)count(); ++i ) {
+ item = items[ i ].item;
+ if ( item ) {
+ item->prev = prev;
+ if ( item->prev )
+ item->prev->next = item;
+ item->next = 0;
+ }
+ if ( i == 0 )
+ d->firstItem = item;
+ if ( i == (int)count() - 1 )
+ d->lastItem = item;
+ prev = item;
+ }
+ } else {
+ for ( i = (int)count() - 1; i >= 0 ; --i ) {
+ item = items[ i ].item;
+ if ( item ) {
+ item->prev = prev;
+ if ( item->prev )
+ item->prev->next = item;
+ item->next = 0;
+ }
+ if ( i == (int)count() - 1 )
+ d->firstItem = item;
+ if ( i == 0 )
+ d->lastItem = item;
+ prev = item;
+ }
+ }
+
+ delete [] items;
+
+ arrangeItemsInGrid( TRUE );
+}
+
+/*!
+ \reimp
+*/
+
+TQSize TQIconView::sizeHint() const
+{
+ constPolish();
+
+ if ( !d->firstItem )
+ return TQScrollView::sizeHint();
+
+ if ( d->dirty && d->firstSizeHint ) {
+ ( (TQIconView*)this )->resizeContents( TQMAX( 400, contentsWidth() ),
+ TQMAX( 400, contentsHeight() ) );
+ if ( autoArrange() )
+ ( (TQIconView*)this )->arrangeItemsInGrid( FALSE );
+ d->firstSizeHint = FALSE;
+ }
+
+ d->dirty = TRUE; // ######## warwick: I'm sure this is wrong. Fixed in 2.3.
+ int extra = style().pixelMetric(TQStyle::PM_ScrollBarExtent,
+ verticalScrollBar()) + 2*frameWidth();
+ TQSize s( TQMIN(400, contentsWidth() + extra),
+ TQMIN(400, contentsHeight() + extra) );
+ return s;
+}
+
+/*!
+ \internal
+*/
+
+void TQIconView::updateContents()
+{
+ viewport()->update();
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::enterEvent( TQEvent *e )
+{
+ TQScrollView::enterEvent( e );
+ emit onViewport();
+}
+
+/*!
+ \internal
+ This function is always called when the geometry of an item changes.
+ This function moves the item into the correct area in the internal
+ data structure.
+*/
+
+void TQIconView::updateItemContainer( TQIconViewItem *item )
+{
+ if ( !item || d->containerUpdateLocked || (!isVisible() && autoArrange()) )
+ return;
+
+ if ( item->d->container1 && d->firstContainer ) {
+ //Special-case to check if we can use removeLast otherwise use removeRef (slower)
+ if (item->d->container1->items.last() == item)
+ item->d->container1->items.removeLast();
+ else
+ item->d->container1->items.removeRef( item );
+ }
+ item->d->container1 = 0;
+ if ( item->d->container2 && d->firstContainer ) {
+ //Special-case to check if we can use removeLast otherwise use removeRef (slower)
+ if (item->d->container2->items.last() == item)
+ item->d->container2->items.removeLast();
+ else
+ item->d->container2->items.removeRef( item );
+ }
+ item->d->container2 = 0;
+
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer;
+ if ( !c ) {
+ appendItemContainer();
+ c = d->firstContainer;
+ }
+
+ const TQRect irect = item->rect();
+ bool contains = FALSE;
+ for (;;) {
+ if ( c->rect.intersects( irect ) ) {
+ contains = c->rect.contains( irect );
+ break;
+ }
+
+ c = c->n;
+ if ( !c ) {
+ appendItemContainer();
+ c = d->lastContainer;
+ }
+ }
+
+ if ( !c ) {
+#if defined(QT_CHECK_RANGE)
+ tqWarning( "TQIconViewItem::updateItemContainer(): No fitting container found!" );
+#endif
+ return;
+ }
+
+ if (item->isVisible()) {
+ c->items.append( item );
+ item->d->container1 = c;
+
+ if ( !contains ) {
+ c = c->n;
+ if ( !c ) {
+ appendItemContainer();
+ c = d->lastContainer;
+ }
+ c->items.append( item );
+ item->d->container2 = c;
+ }
+ }
+ if ( contentsWidth() < irect.right() || contentsHeight() < irect.bottom() )
+ resizeContents( TQMAX( contentsWidth(), irect.right() ), TQMAX( contentsHeight(), irect.bottom() ) );
+}
+
+/*!
+ \internal
+ Appends a new rect area to the internal data structure of the items.
+*/
+
+void TQIconView::appendItemContainer()
+{
+ TQSize s;
+ // #### We have to find out which value is best here
+ if ( d->arrangement == LeftToRight )
+ s = TQSize( INT_MAX - 1, RECT_EXTENSION );
+ else
+ s = TQSize( RECT_EXTENSION, INT_MAX - 1 );
+
+ if ( !d->firstContainer ) {
+ d->firstContainer = new TQIconViewPrivate::ItemContainer( 0, 0, TQRect( TQPoint( 0, 0 ), s ) );
+ d->lastContainer = d->firstContainer;
+ } else {
+ if ( d->arrangement == LeftToRight )
+ d->lastContainer = new TQIconViewPrivate::ItemContainer(
+ d->lastContainer, 0, TQRect( d->lastContainer->rect.bottomLeft(), s ) );
+ else
+ d->lastContainer = new TQIconViewPrivate::ItemContainer(
+ d->lastContainer, 0, TQRect( d->lastContainer->rect.topRight(), s ) );
+ }
+}
+
+/*! \internal
+
+ Rebuilds the whole internal data structure. This is done when it's
+ likely that most/all items change their geometry (e.g. in
+ arrangeItemsInGrid()), because calling this is then more efficient
+ than calling updateItemContainer() for each item.
+*/
+
+void TQIconView::rebuildContainers()
+{
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer, *tmpc;
+ while ( c ) {
+ tmpc = c->n;
+ delete c;
+ c = tmpc;
+ }
+ d->firstContainer = d->lastContainer = 0;
+
+ TQIconViewItem *item = d->firstItem;
+ appendItemContainer();
+ c = d->lastContainer;
+ while ( item ) {
+ if (item->isVisible()) {
+ if ( c->rect.contains( item->rect() ) ) {
+ item->d->container1 = c;
+ item->d->container2 = 0;
+ c->items.append( item );
+ item = item->next;
+ } else if ( c->rect.intersects( item->rect() ) ) {
+ item->d->container1 = c;
+ c->items.append( item );
+ c = c->n;
+ if ( !c ) {
+ appendItemContainer();
+ c = d->lastContainer;
+ }
+ c->items.append( item );
+ item->d->container2 = c;
+ item = item->next;
+ c = c->p;
+ } else {
+ if ( d->arrangement == LeftToRight ) {
+ if ( item->y() < c->rect.y() && c->p ) {
+ c = c->p;
+ continue;
+ }
+ } else {
+ if ( item->x() < c->rect.x() && c->p ) {
+ c = c->p;
+ continue;
+ }
+ }
+
+ c = c->n;
+ if ( !c ) {
+ appendItemContainer();
+ c = d->lastContainer;
+ }
+ }
+ }
+ else {
+ // Skip this hidden item
+ item = item->next;
+ }
+ }
+}
+
+/*!
+ \internal
+*/
+
+void TQIconView::movedContents( int, int )
+{
+ if ( d->drawDragShapes ) {
+ drawDragShapes( d->oldDragPos );
+ d->oldDragPos = TQPoint( -1, -1 );
+ }
+}
+
+void TQIconView::handleItemChange( TQIconViewItem *old, bool shift,
+ bool control, bool homeend )
+{
+ if ( d->selectionMode == Single ) {
+ bool block = signalsBlocked();
+ blockSignals( TRUE );
+ if ( old )
+ old->setSelected( FALSE );
+ blockSignals( block );
+ d->currentItem->setSelected( TRUE, TRUE );
+ } else if ( d->selectionMode == Extended ) {
+ if ( shift ) {
+ if ( !d->selectAnchor ) {
+ if ( old && !old->selected && old->isSelectable() ) {
+ old->selected = TRUE;
+ repaintItem( old );
+ }
+ d->currentItem->setSelected( TRUE, TRUE );
+ } else {
+ TQIconViewItem *from = d->selectAnchor, *to = d->currentItem;
+ if ( !from || !to )
+ return;
+
+ // checking if it's downwards and if we span rows
+ bool downwards = FALSE;
+ bool spanning = FALSE;
+ if ( d->arrangement == LeftToRight) {
+ if ( from->rect().center().y() < to->rect().center().y() )
+ downwards = TRUE;
+ } else {
+ if ( from->rect().center().x() < to->rect().center().x() )
+ downwards = TRUE;
+ }
+
+ TQRect fr = from->rect();
+ TQRect tr = to->rect();
+ if ( d->arrangement == LeftToRight ) {
+ fr.moveTopLeft( TQPoint( tr.x(), fr.y() ) );
+ if ( !tr.intersects( fr ) )
+ spanning = TRUE;
+ } else {
+ fr.moveTopLeft( TQPoint( fr.x(), tr.y() ) );
+ if ( !tr.intersects( fr ) )
+ spanning = TRUE;
+ }
+
+
+ // finding the rectangles
+ TQRect topRect, bottomRect, midRect;
+ if ( !spanning ) {
+ midRect = from->rect().unite( to->rect() );
+ } else {
+ if ( downwards ) {
+ topRect = from->rect();
+ bottomRect = to->rect();
+ } else {
+ topRect = to->rect();
+ bottomRect = from->rect();
+ }
+ if ( d->arrangement == LeftToRight ) {
+ topRect.setRight( contentsWidth() );
+ bottomRect.setLeft( 0 );
+ midRect.setRect( 0, topRect.bottom(),
+ contentsWidth(),
+ bottomRect.top() - topRect.bottom() );
+ } else {
+ topRect.setBottom( contentsHeight() );
+ bottomRect.setTop( 0 );
+ midRect.setRect( topRect.right(),
+ 0,
+ bottomRect.left() - topRect.right(),
+ contentsHeight() );
+ }
+ }
+
+ // finding contained items and selecting them
+ TQIconViewItem *item = 0;
+ bool changed = FALSE;
+ bool midValid = midRect.isValid();
+ bool topValid = topRect.isValid();
+ bool bottomValid = bottomRect.isValid();
+ TQRect selectedRect, unselectedRect;
+ for ( item = d->firstItem; item; item = item->next ) {
+ bool contained = FALSE;
+ TQPoint itemCenter = item->rect().center();
+ if ( midValid && midRect.contains( itemCenter ) )
+ contained = TRUE;
+ if ( !contained && topValid && topRect.contains( itemCenter ) )
+ contained = TRUE;
+ if ( !contained && bottomValid && bottomRect.contains( itemCenter ) )
+ contained = TRUE;
+
+ if ( contained ) {
+ if ( !item->selected && item->isSelectable() ) {
+ changed = TRUE;
+ item->selected = TRUE;
+ selectedRect = selectedRect.unite( item->rect() );
+ }
+ } else if ( item->selected && !control ) {
+ item->selected = FALSE;
+ unselectedRect = unselectedRect.unite( item->rect() );
+ changed = TRUE;
+ }
+ }
+
+ TQRect viewRect( contentsX(), contentsY(),
+ visibleWidth(), visibleHeight() );
+
+ if ( viewRect.intersects( selectedRect ) ) {
+ if ( homeend )
+ TQScrollView::updateContents( viewRect.intersect( selectedRect ) );
+ else
+ repaintContents( viewRect.intersect( selectedRect ) );
+ }
+ if ( viewRect.intersects( unselectedRect ) ) {
+ if ( homeend )
+ TQScrollView::updateContents( viewRect.intersect( unselectedRect ) );
+ else
+ repaintContents( viewRect.intersect( unselectedRect ) );
+ }
+
+ if ( changed )
+ emit selectionChanged();
+ }
+ } else if ( !control ) {
+ blockSignals( TRUE );
+ selectAll( FALSE );
+ blockSignals( FALSE );
+ d->currentItem->setSelected( TRUE, TRUE );
+ }
+ } else {
+ if ( shift )
+ d->currentItem->setSelected( !d->currentItem->isSelected(), TRUE );
+ }
+}
+
+TQBitmap TQIconView::mask( TQPixmap *pix ) const
+{
+ TQBitmap m;
+ if ( d->maskCache.find( TQString::number( pix->serialNumber() ), m ) )
+ return m;
+ m = pix->createHeuristicMask();
+ d->maskCache.insert( TQString::number( pix->serialNumber() ), m );
+ return m;
+}
+
+/*!
+ \reimp
+ \internal
+
+ (Implemented to get rid of a compiler warning.)
+*/
+void TQIconView::drawContents( TQPainter * )
+{
+}
+
+/*!
+ \reimp
+*/
+void TQIconView::windowActivationChange( bool oldActive )
+{
+ if ( oldActive && d->scrollTimer )
+ d->scrollTimer->stop();
+
+ if ( !isVisible() )
+ return;
+
+ if ( palette().active() == palette().inactive() )
+ return;
+
+ repaintSelectedItems();
+}
+
+/*!
+ Returns TRUE if an iconview item is being renamed; otherwise
+ returns FALSE.
+*/
+
+bool TQIconView::isRenaming() const
+{
+#ifndef TQT_NO_TEXTEDIT
+ return d->renamingItem && d->renamingItem->renameBox;
+#else
+ return FALSE;
+#endif
+}
+
+int TQIconView::visibleWidthSB() const
+{
+ if ( vScrollBarMode() != Auto )
+ return visibleWidth();
+
+ int offset = verticalScrollBar()->isVisible() ? 0
+ : style().pixelMetric( TQStyle::PM_ScrollBarExtent, verticalScrollBar() );
+ return TQMAX( 0, visibleWidth() - offset );
+}
+
+int TQIconView::visibleHeightSB() const
+{
+ if ( hScrollBarMode() != Auto )
+ return visibleHeight();
+
+ int offset = horizontalScrollBar()->isVisible() ? 0
+ : style().pixelMetric( TQStyle::PM_ScrollBarExtent, horizontalScrollBar() );
+ return TQMAX( 0, visibleHeight() - offset );
+}
+
+#endif // TQT_NO_ICONVIEW