src/qt3support/itemviews/q3iconview.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt3Support module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qglobal.h"
       
    43 #if defined(Q_CC_BOR)
       
    44 // needed for qsort() because of a std namespace problem on Borland
       
    45 #include "qplatformdefs.h"
       
    46 #endif
       
    47 
       
    48 #include "q3iconview.h"
       
    49 
       
    50 #ifndef QT_NO_ICONVIEW
       
    51 
       
    52 #include "private/q3richtext_p.h"
       
    53 #include "q3textedit.h"
       
    54 #include "qapplication.h"
       
    55 #include "qbitmap.h"
       
    56 #include "qbrush.h"
       
    57 #include "q3cleanuphandler.h"
       
    58 #include "qcursor.h"
       
    59 #include "qevent.h"
       
    60 #include "qfontmetrics.h"
       
    61 #include "qhash.h"
       
    62 #include "qimage.h"
       
    63 #include "qmime.h"
       
    64 #include "qpainter.h"
       
    65 #include "qpalette.h"
       
    66 #include "qpen.h"
       
    67 #include "qpixmapcache.h"
       
    68 #include "qstringlist.h"
       
    69 #include "qstyle.h"
       
    70 #include "qstyleoption.h"
       
    71 #include "qtimer.h"
       
    72 #include "qtooltip.h"
       
    73 #include "q3strlist.h"
       
    74 
       
    75 #include <limits.h>
       
    76 #include <stdlib.h>
       
    77 
       
    78 QT_BEGIN_NAMESPACE
       
    79 
       
    80 #define RECT_EXTENSION 300
       
    81 
       
    82 static const char * const unknown_xpm[] = {
       
    83     "32 32 11 1",
       
    84     "c c #ffffff",
       
    85     "g c #c0c0c0",
       
    86     "a c #c0ffc0",
       
    87     "h c #a0a0a4",
       
    88     "d c #585858",
       
    89     "f c #303030",
       
    90     "i c #400000",
       
    91     "b c #00c000",
       
    92     "e c #000000",
       
    93     "# c #000000",
       
    94     ". c None",
       
    95     "...###..........................",
       
    96     "...#aa##........................",
       
    97     ".###baaa##......................",
       
    98     ".#cde#baaa##....................",
       
    99     ".#cccdeebaaa##..##f.............",
       
   100     ".#cccccdeebaaa##aaa##...........",
       
   101     ".#cccccccdeebaaaaaaaa##.........",
       
   102     ".#cccccccccdeebaaaaaaa#.........",
       
   103     ".#cccccgcgghhebbbbaaaaa#........",
       
   104     ".#ccccccgcgggdebbbbbbaa#........",
       
   105     ".#cccgcgcgcgghdeebiebbba#.......",
       
   106     ".#ccccgcggggggghdeddeeba#.......",
       
   107     ".#cgcgcgcggggggggghghdebb#......",
       
   108     ".#ccgcggggggggghghghghd#b#......",
       
   109     ".#cgcgcggggggggghghghhd#b#......",
       
   110     ".#gcggggggggghghghhhhhd#b#......",
       
   111     ".#cgcggggggggghghghhhhd#b#......",
       
   112     ".#ggggggggghghghhhhhhhdib#......",
       
   113     ".#gggggggggghghghhhhhhd#b#......",
       
   114     ".#hhggggghghghhhhhhhhhd#b#......",
       
   115     ".#ddhhgggghghghhhhhhhhd#b#......",
       
   116     "..##ddhhghghhhhhhhhhhhdeb#......",
       
   117     "....##ddhhhghhhhhhhhhhd#b#......",
       
   118     "......##ddhhhhhhhhhhhhd#b#......",
       
   119     "........##ddhhhhhhhhhhd#b#......",
       
   120     "..........##ddhhhhhhhhd#b#......",
       
   121     "............##ddhhhhhhd#b###....",
       
   122     "..............##ddhhhhd#b#####..",
       
   123     "................##ddhhd#b######.",
       
   124     "..................##dddeb#####..",
       
   125     "....................##d#b###....",
       
   126     "......................####......"};
       
   127 
       
   128 static QPixmap *unknown_icon = 0;
       
   129 static QPixmap *qiv_buffer_pixmap = 0;
       
   130 #if !defined(Q_WS_X11)
       
   131 static QPixmap *qiv_selection = 0;
       
   132 #endif
       
   133 static bool optimize_layout = false;
       
   134 
       
   135 static Q3CleanupHandler<QPixmap> qiv_cleanup_pixmap;
       
   136 
       
   137 
       
   138 static QPixmap *get_qiv_buffer_pixmap(const QSize &s)
       
   139 {
       
   140     if (!qiv_buffer_pixmap) {
       
   141         qiv_buffer_pixmap = new QPixmap(s);
       
   142         qiv_cleanup_pixmap.add(&qiv_buffer_pixmap);
       
   143         return qiv_buffer_pixmap;
       
   144     }
       
   145 
       
   146     qiv_buffer_pixmap->resize(s);
       
   147     return qiv_buffer_pixmap;
       
   148 }
       
   149 
       
   150 #ifndef QT_NO_DRAGANDDROP
       
   151 
       
   152 class Q_COMPAT_EXPORT Q3IconDragData
       
   153 {
       
   154 public:
       
   155     Q3IconDragData();
       
   156     Q3IconDragData(const QRect &ir, const QRect &tr);
       
   157 
       
   158     QRect pixmapRect() const;
       
   159     QRect textRect() const;
       
   160 
       
   161     void setPixmapRect(const QRect &r);
       
   162     void setTextRect(const QRect &r);
       
   163 
       
   164     QRect iconRect_, textRect_;
       
   165     QString key_;
       
   166 
       
   167     bool operator==(const Q3IconDragData &i) const;
       
   168 };
       
   169 
       
   170 class Q_COMPAT_EXPORT Q3IconDragDataItem
       
   171 {
       
   172 public:
       
   173     Q3IconDragDataItem() {}
       
   174     Q3IconDragDataItem(const Q3IconDragItem &i1, const Q3IconDragData &i2) : data(i1), item(i2) {}
       
   175     Q3IconDragItem data;
       
   176     Q3IconDragData item;
       
   177     bool operator== (const Q3IconDragDataItem&) const;
       
   178 };
       
   179 
       
   180 class Q3IconDragPrivate
       
   181 {
       
   182 public:
       
   183     QLinkedList<Q3IconDragDataItem> items;
       
   184     static bool decode(QMimeSource* e, QLinkedList<Q3IconDragDataItem> &lst);
       
   185 };
       
   186 
       
   187 #endif
       
   188 
       
   189 class Q3IconViewPrivate
       
   190 {
       
   191 public:
       
   192     Q3IconViewItem *firstItem, *lastItem;
       
   193     uint count;
       
   194     Q3IconView::SelectionMode selectionMode;
       
   195     Q3IconViewItem *currentItem, *tmpCurrentItem, *highlightedItem,
       
   196         *startDragItem, *pressedItem, *selectAnchor, *renamingItem;
       
   197     QRect *rubber;
       
   198     QTimer *scrollTimer, *adjustTimer, *updateTimer, *inputTimer,
       
   199         *fullRedrawTimer;
       
   200     int rastX, rastY, spacing;
       
   201     int dragItems;
       
   202     QPoint oldDragPos;
       
   203     Q3IconView::Arrangement arrangement;
       
   204     Q3IconView::ResizeMode resizeMode;
       
   205     QSize oldSize;
       
   206 #ifndef QT_NO_DRAGANDDROP
       
   207     QLinkedList<Q3IconDragDataItem> iconDragData;
       
   208 #endif
       
   209     int numDragItems, cachedW, cachedH;
       
   210     int maxItemWidth, maxItemTextLength;
       
   211     QPoint dragStart;
       
   212     QString currInputString;
       
   213     Q3IconView::ItemTextPos itemTextPos;
       
   214 #ifndef QT_NO_CURSOR
       
   215     QCursor oldCursor;
       
   216 #endif
       
   217     int cachedContentsX, cachedContentsY;
       
   218     QBrush itemTextBrush;
       
   219     QRegion clipRegion;
       
   220     QPoint dragStartPos;
       
   221     QFontMetrics *fm;
       
   222     int minLeftBearing, minRightBearing;
       
   223 
       
   224     uint mousePressed : 1;
       
   225     uint cleared : 1;
       
   226     uint dropped : 1;
       
   227     uint clearing : 1;
       
   228     uint oldDragAcceptAction : 1;
       
   229     uint isIconDrag : 1;
       
   230     uint drawDragShapes : 1;
       
   231     uint dirty : 1;
       
   232     uint rearrangeEnabled : 1;
       
   233     uint reorderItemsWhenInsert : 1;
       
   234     uint drawAllBack : 1;
       
   235     uint resortItemsWhenInsert : 1;
       
   236     uint sortDirection : 1;
       
   237     uint wordWrapIconText : 1;
       
   238     uint containerUpdateLocked : 1;
       
   239     uint firstSizeHint : 1;
       
   240     uint showTips : 1;
       
   241     uint pressedSelected : 1;
       
   242     uint dragging : 1;
       
   243     uint drawActiveSelection : 1;
       
   244     uint inMenuMode : 1;
       
   245 
       
   246     QPoint dragPos;
       
   247     QPixmapCache maskCache;
       
   248     QHash<Q3IconViewItem *, Q3IconViewItem *> selectedItems;
       
   249 
       
   250     struct ItemContainer {
       
   251         ItemContainer(ItemContainer *pr, ItemContainer *nx, const QRect &r)
       
   252             : p(pr), n(nx), rect(r)
       
   253         {
       
   254             if (p)
       
   255                 p->n = this;
       
   256             if (n)
       
   257                 n->p = this;
       
   258         }
       
   259         ItemContainer *p, *n;
       
   260         QRect rect;
       
   261         QList<Q3IconViewItem*> items;
       
   262     } *firstContainer, *lastContainer;
       
   263 
       
   264     struct SortableItem {
       
   265         Q3IconViewItem *item;
       
   266     };
       
   267 
       
   268 public:
       
   269 
       
   270     /* finds the containers that intersect with \a searchRect in the direction \a dir relative to \a relativeTo */
       
   271     QList<ItemContainer* >* findContainers(
       
   272         Q3IconView:: Direction dir,
       
   273         const QPoint &relativeTo,
       
   274         const QRect &searchRect) const;
       
   275     //    friend int cmpIconViewItems(const void *n1, const void *n2);
       
   276 };
       
   277 
       
   278 
       
   279 QList<Q3IconViewPrivate::ItemContainer *>* Q3IconViewPrivate::findContainers(
       
   280         Q3IconView:: Direction dir,
       
   281         const QPoint &relativeTo,
       
   282         const QRect &searchRect) const
       
   283 {
       
   284 
       
   285     QList<Q3IconViewPrivate::ItemContainer *>* list =
       
   286         new QList<Q3IconViewPrivate::ItemContainer*>();
       
   287 
       
   288     if (arrangement == Q3IconView::LeftToRight) {
       
   289         if (dir == Q3IconView::DirLeft || dir == Q3IconView::DirRight) {
       
   290             ItemContainer *c = firstContainer;
       
   291             for (; c; c = c->n)
       
   292                 if (c->rect.intersects(searchRect))
       
   293                     list->append(c);
       
   294         } else {
       
   295             if (dir == Q3IconView::DirDown) {
       
   296                 ItemContainer *c = firstContainer;
       
   297                 for (; c; c = c->n)
       
   298                     if (c->rect.intersects(searchRect) &&
       
   299                          c->rect.bottom() >= relativeTo.y())
       
   300                         list->append(c);
       
   301             } else {
       
   302                 ItemContainer *c = lastContainer;
       
   303                 for (; c; c = c->p)
       
   304                     if (c->rect.intersects(searchRect) &&
       
   305                          c->rect.top() <= relativeTo.y())
       
   306                         list->append(c);
       
   307             }
       
   308         }
       
   309     } else {
       
   310         if (dir == Q3IconView::DirUp || dir == Q3IconView::DirDown) {
       
   311             ItemContainer *c = firstContainer;
       
   312             for (; c; c = c->n)
       
   313                 if (c->rect.intersects(searchRect))
       
   314                     list->append(c);
       
   315         } else {
       
   316             if (dir == Q3IconView::DirRight) {
       
   317                 ItemContainer *c = firstContainer;
       
   318                 for (; c; c = c->n)
       
   319                     if (c->rect.intersects(searchRect) &&
       
   320                          c->rect.right() >= relativeTo.x())
       
   321                         list->append(c);
       
   322             } else {
       
   323                 ItemContainer *c = lastContainer;
       
   324                 for (; c; c = c->p)
       
   325                     if (c->rect.intersects(searchRect) &&
       
   326                          c->rect.left() <= relativeTo.x())
       
   327                         list->append(c);
       
   328             }
       
   329         }
       
   330     }
       
   331     return list;
       
   332 }
       
   333 
       
   334 
       
   335 #if defined(Q_C_CALLBACKS)
       
   336 extern "C" {
       
   337 #endif
       
   338 
       
   339 #ifdef Q_OS_WINCE
       
   340 static int _cdecl cmpIconViewItems(const void *n1, const void *n2)
       
   341 #else
       
   342 static int cmpIconViewItems(const void *n1, const void *n2)
       
   343 #endif
       
   344 {
       
   345     if (!n1 || !n2)
       
   346         return 0;
       
   347 
       
   348     Q3IconViewPrivate::SortableItem *i1 = (Q3IconViewPrivate::SortableItem *)n1;
       
   349     Q3IconViewPrivate::SortableItem *i2 = (Q3IconViewPrivate::SortableItem *)n2;
       
   350 
       
   351     return i1->item->compare(i2->item);
       
   352 }
       
   353 
       
   354 #if defined(Q_C_CALLBACKS)
       
   355 }
       
   356 #endif
       
   357 
       
   358 class Q3IconViewItemPrivate
       
   359 {
       
   360 public:
       
   361     Q3IconViewPrivate::ItemContainer *container1, *container2;
       
   362 };
       
   363 
       
   364 #ifndef QT_NO_TEXTEDIT
       
   365 
       
   366 class Q3IconViewItemLineEdit : public Q3TextEdit
       
   367 {
       
   368     friend class Q3IconViewItem;
       
   369 
       
   370 public:
       
   371     Q3IconViewItemLineEdit(const QString &text, QWidget *parent, Q3IconViewItem *theItem, const char* name=0);
       
   372 
       
   373 protected:
       
   374     void keyPressEvent(QKeyEvent *e);
       
   375     void focusOutEvent(QFocusEvent *e);
       
   376 
       
   377 protected:
       
   378     Q3IconViewItem *item;
       
   379     QString startText;
       
   380 
       
   381 private:
       
   382     Q_DISABLE_COPY(Q3IconViewItemLineEdit)
       
   383 };
       
   384 
       
   385 Q3IconViewItemLineEdit::Q3IconViewItemLineEdit(const QString &text, QWidget *parent,
       
   386                                               Q3IconViewItem *theItem, const char *name)
       
   387     : Q3TextEdit(parent, name), item(theItem), startText(text)
       
   388 {
       
   389     setFrameStyle(QFrame::Plain | QFrame::Box);
       
   390     setLineWidth(1);
       
   391 
       
   392     setHScrollBarMode(AlwaysOff);
       
   393     setVScrollBarMode(AlwaysOff);
       
   394 
       
   395     setWordWrap(WidgetWidth);
       
   396     setWrapColumnOrWidth(item->iconView()->maxItemWidth() -
       
   397                           (item->iconView()->itemTextPos() == Q3IconView::Bottom ?
       
   398                             0 : item->pixmapRect().width()));
       
   399     document()->formatter()->setAllowBreakInWords(true);
       
   400     resize(200, 200); // ### some size, there should be a forceReformat()
       
   401     setTextFormat(Qt::PlainText);
       
   402     setText(text);
       
   403     setAlignment(Qt::AlignCenter);
       
   404 
       
   405     resize(wrapColumnOrWidth() + 2, heightForWidth(wrapColumnOrWidth()) + 2);
       
   406 }
       
   407 
       
   408 void Q3IconViewItemLineEdit::keyPressEvent(QKeyEvent *e)
       
   409 {
       
   410     if (e->key()  == Qt::Key_Escape) {
       
   411         item->Q3IconViewItem::setText(startText);
       
   412         item->cancelRenameItem();
       
   413     } else if (e->key() == Qt::Key_Enter ||
       
   414                 e->key() == Qt::Key_Return) {
       
   415         item->renameItem();
       
   416     } else {
       
   417         Q3TextEdit::keyPressEvent(e);
       
   418         sync();
       
   419         resize(width(), document()->height() + 2);
       
   420 
       
   421     }
       
   422 }
       
   423 
       
   424 void Q3IconViewItemLineEdit::focusOutEvent(QFocusEvent *e)
       
   425 {
       
   426     Q_UNUSED(e) // I need this to get rid of a Borland warning
       
   427     if (e->reason() != Qt::PopupFocusReason)
       
   428         item->cancelRenameItem();
       
   429 }
       
   430 #endif
       
   431 
       
   432 #ifndef QT_NO_DRAGANDDROP
       
   433 
       
   434 
       
   435 /*!
       
   436     \class Q3IconDragItem
       
   437     \brief The Q3IconDragItem class encapsulates a drag item.
       
   438     \compat
       
   439 
       
   440     The Q3IconDrag class uses a list of Q3IconDragItems to support drag
       
   441     and drop operations.
       
   442 
       
   443     In practice a Q3IconDragItem object (or an object of a class derived
       
   444     from Q3IconDragItem) is created for each icon view item which is
       
   445     dragged. Each of these Q3IconDragItems is stored in a Q3IconDrag
       
   446     object.
       
   447 
       
   448     See Q3IconView::dragObject() for more information.
       
   449 */
       
   450 
       
   451 /*!
       
   452     Constructs a Q3IconDragItem with no data.
       
   453 */
       
   454 
       
   455 Q3IconDragItem::Q3IconDragItem()
       
   456 {
       
   457     ba = "no data";
       
   458 }
       
   459 
       
   460 /*!
       
   461     Destructor.
       
   462 */
       
   463 
       
   464 Q3IconDragItem::~Q3IconDragItem()
       
   465 {
       
   466 }
       
   467 
       
   468 /*!
       
   469     Returns the data contained in the Q3IconDragItem.
       
   470 */
       
   471 
       
   472 QByteArray Q3IconDragItem::data() const
       
   473 {
       
   474     return ba;
       
   475 }
       
   476 
       
   477 /*!
       
   478     Sets the data for the Q3IconDragItem to the data stored in the
       
   479     QByteArray \a d.
       
   480 */
       
   481 
       
   482 void Q3IconDragItem::setData(const QByteArray &d)
       
   483 {
       
   484     ba = d;
       
   485 }
       
   486 
       
   487 /*!
       
   488     \internal
       
   489 */
       
   490 
       
   491 bool Q3IconDragItem::operator==(const Q3IconDragItem &i) const
       
   492 {
       
   493     return ba == i.ba;
       
   494 }
       
   495 
       
   496 /*!
       
   497     \reimp
       
   498 */
       
   499 
       
   500 bool Q3IconDragDataItem::operator==(const Q3IconDragDataItem &i) const
       
   501 {
       
   502     return (i.item == item &&
       
   503              i.data == data);
       
   504 }
       
   505 
       
   506 /*!
       
   507     \reimp
       
   508 */
       
   509 
       
   510 bool Q3IconDragData::operator==(const Q3IconDragData &i) const
       
   511 {
       
   512     return key_ == i.key_;
       
   513 }
       
   514 
       
   515 
       
   516 /*!
       
   517     \class Q3IconDrag
       
   518     \brief The Q3IconDrag class supports drag and drop operations
       
   519     within a Q3IconView.
       
   520 
       
   521     \compat
       
   522 
       
   523     A Q3IconDrag object is used to maintain information about the
       
   524     positions of dragged items and the data associated with them.
       
   525     Q3IconViews are able to use this information to paint the dragged
       
   526     items in the correct positions. Internally, Q3IconDrag stores the
       
   527     data associated with drag items in Q3IconDragItem objects.
       
   528 
       
   529     If you want to use the extended drag and drop functionality of
       
   530     Q3IconView, create a Q3IconDrag object in a reimplementation of
       
   531     Q3IconView::dragObject(). Then create a Q3IconDragItem for each item
       
   532     which should be dragged, set the data it represents with
       
   533     Q3IconDragItem::setData(), and add each Q3IconDragItem to the drag
       
   534     object using append().
       
   535 
       
   536     The data in Q3IconDragItems is stored in a QByteArray and is
       
   537     mime-typed (see QMimeSource and the
       
   538     \link http://qt.nokia.com/doc/dnd.html Drag and Drop\endlink
       
   539     overview). If you want to use your own mime-types derive a class
       
   540     from Q3IconDrag and reimplement format(), encodedData() and
       
   541     canDecode().
       
   542 
       
   543     The fileiconview example program demonstrates the use of the
       
   544     Q3IconDrag class including subclassing and reimplementing
       
   545     dragObject(), format(), encodedData() and canDecode().
       
   546 
       
   547     \sa QMimeSource::format()
       
   548 */
       
   549 
       
   550 /*!
       
   551     Constructs a drag object called \a name, which is a child of \a
       
   552     dragSource.
       
   553 
       
   554     Note that the drag object will be deleted when \a dragSource is deleted.
       
   555 */
       
   556 
       
   557 Q3IconDrag::Q3IconDrag(QWidget * dragSource, const char* name)
       
   558     : Q3DragObject(dragSource, name)
       
   559 {
       
   560     d = new Q3IconDragPrivate;
       
   561 }
       
   562 
       
   563 /*!
       
   564     Destructor.
       
   565 */
       
   566 
       
   567 Q3IconDrag::~Q3IconDrag()
       
   568 {
       
   569     delete d;
       
   570 }
       
   571 
       
   572 /*!
       
   573     Append the Q3IconDragItem, \a i, to the Q3IconDrag object's list of
       
   574     items. You must also supply the geometry of the pixmap, \a pr, and
       
   575     the textual caption, \a tr.
       
   576 
       
   577     \sa Q3IconDragItem
       
   578 */
       
   579 
       
   580 void Q3IconDrag::append(const Q3IconDragItem &i, const QRect &pr, const QRect &tr)
       
   581 {
       
   582     d->items.append(Q3IconDragDataItem(i, Q3IconDragData(pr, tr)));
       
   583 }
       
   584 
       
   585 /*!
       
   586     \reimp
       
   587 */
       
   588 
       
   589 const char* Q3IconDrag::format(int i) const
       
   590 {
       
   591     if (i == 0)
       
   592         return "application/x-qiconlist";
       
   593     return 0;
       
   594 }
       
   595 
       
   596 /*!
       
   597     Returns the encoded data of the drag object if \a mime is
       
   598     application/x-qiconlist.
       
   599 */
       
   600 
       
   601 QByteArray Q3IconDrag::encodedData(const char* mime) const
       
   602 {
       
   603     if (d->items.size() <= 0 || QString::fromLatin1(mime) !=
       
   604          QString::fromLatin1("application/x-qiconlist"))
       
   605         return QByteArray();
       
   606 
       
   607     QLinkedList<Q3IconDragDataItem>::ConstIterator it = d->items.begin();
       
   608     QString s;
       
   609     for (; it != d->items.end(); ++it) {
       
   610         QString k(QLatin1String("%1$@@$%2$@@$%3$@@$%4$@@$%5$@@$%6$@@$%7$@@$%8$@@$"));
       
   611         k = k.arg((*it).item.pixmapRect().x()).arg(
       
   612             (*it).item.pixmapRect().y()).arg((*it).item.pixmapRect().width()).
       
   613             arg((*it).item.pixmapRect().height()).arg(
       
   614                 (*it).item.textRect().x()).arg((*it).item.textRect().y()).
       
   615             arg((*it).item.textRect().width()).arg(
       
   616                 (*it).item.textRect().height());
       
   617         k += QString::fromLatin1((*it).data.data()) + QLatin1String("$@@$");
       
   618         s += k;
       
   619     }
       
   620 
       
   621     QByteArray a;
       
   622     a.resize(s.length() + 1);
       
   623     memcpy(a.data(), s.latin1(), a.size());
       
   624     return a;
       
   625 }
       
   626 
       
   627 /*!
       
   628     Returns true if \a e can be decoded by the Q3IconDrag, otherwise
       
   629     return false.
       
   630 */
       
   631 
       
   632 bool Q3IconDrag::canDecode(QMimeSource* e)
       
   633 {
       
   634     if (e->provides("application/x-qiconlist"))
       
   635         return true;
       
   636     return false;
       
   637 }
       
   638 
       
   639 /*!
       
   640     Decodes the data which is stored (encoded) in \a e and, if
       
   641     successful, fills the \a list of icon drag items with the decoded
       
   642     data. Returns true if there was some data, false otherwise.
       
   643 */
       
   644 
       
   645 bool Q3IconDragPrivate::decode(QMimeSource* e, QLinkedList<Q3IconDragDataItem> &lst)
       
   646 {
       
   647     QByteArray ba = e->encodedData("application/x-qiconlist");
       
   648     if (ba.size()) {
       
   649         lst.clear();
       
   650         // #### unicode clean????
       
   651         QString s = QString::fromLatin1(ba);
       
   652         Q3IconDragDataItem item;
       
   653         QRect ir, tr;
       
   654         QStringList l = QStringList::split(QLatin1String("$@@$"), s);
       
   655 
       
   656         int i = 0;
       
   657         QStringList::Iterator it = l.begin();
       
   658         for (; it != l.end(); ++it) {
       
   659             if (i == 0) {
       
   660                 ir.setX((*it).toInt());
       
   661             } else if (i == 1) {
       
   662                 ir.setY((*it).toInt());
       
   663             } else if (i == 2) {
       
   664                 ir.setWidth((*it).toInt());
       
   665             } else if (i == 3) {
       
   666                 ir.setHeight((*it).toInt());
       
   667             } else if (i == 4) {
       
   668                 tr.setX((*it).toInt());
       
   669             } else if (i == 5) {
       
   670                 tr.setY((*it).toInt());
       
   671             } else if (i == 6) {
       
   672                 tr.setWidth((*it).toInt());
       
   673             } else if (i == 7) {
       
   674                 tr.setHeight((*it).toInt());
       
   675             } else if (i == 8) {
       
   676                 QByteArray d;
       
   677                 d.resize((*it).length());
       
   678                 memcpy(d.data(), (*it).latin1(), (*it).length());
       
   679                 item.item.setPixmapRect(ir);
       
   680                 item.item.setTextRect(tr);
       
   681                 item.data.setData(d);
       
   682                 lst.append(item);
       
   683             }
       
   684             ++i;
       
   685             if (i > 8)
       
   686                 i = 0;
       
   687         }
       
   688         return true;
       
   689     }
       
   690 
       
   691     return false;
       
   692 }
       
   693 
       
   694 Q3IconDragData::Q3IconDragData()
       
   695     : iconRect_(), textRect_()
       
   696 {
       
   697 }
       
   698 
       
   699 Q3IconDragData::Q3IconDragData(const QRect &ir, const QRect &tr)
       
   700     : iconRect_(ir), textRect_(tr)
       
   701 {
       
   702 }
       
   703 
       
   704 QRect Q3IconDragData::textRect() const
       
   705 {
       
   706     return textRect_;
       
   707 }
       
   708 
       
   709 QRect Q3IconDragData::pixmapRect() const
       
   710 {
       
   711     return iconRect_;
       
   712 }
       
   713 
       
   714 void Q3IconDragData::setPixmapRect(const QRect &r)
       
   715 {
       
   716     iconRect_ = r;
       
   717 }
       
   718 
       
   719 void Q3IconDragData::setTextRect(const QRect &r)
       
   720 {
       
   721     textRect_ = r;
       
   722 }
       
   723 
       
   724 #endif
       
   725 
       
   726 
       
   727 /*!
       
   728     \class Q3IconViewItem
       
   729     \brief The Q3IconViewItem class provides a single item in a Q3IconView.
       
   730 
       
   731     \compat
       
   732 
       
   733     A Q3IconViewItem contains an icon, a string and optionally a sort
       
   734     key, and can display itself in a Q3IconView.
       
   735 
       
   736     The simplest way to create a Q3IconViewItem and insert it into a
       
   737     Q3IconView is to construct the item passing the constructor a
       
   738     pointer to the icon view, a string and an icon:
       
   739 
       
   740     \snippet doc/src/snippets/code/src_qt3support_itemviews_q3iconview.cpp 0
       
   741 
       
   742     By default the text of an icon view item may not be edited by the
       
   743     user but calling setRenameEnabled(true) will allow the user to
       
   744     perform in-place editing of the item's text.
       
   745 
       
   746     When the icon view is deleted all items in it are deleted
       
   747     automatically.
       
   748 
       
   749     The Q3IconView::firstItem() and Q3IconViewItem::nextItem() functions
       
   750     provide a means of iterating over all the items in a Q3IconView:
       
   751 
       
   752     \snippet doc/src/snippets/code/src_qt3support_itemviews_q3iconview.cpp 1
       
   753 
       
   754     The item's icon view is available from iconView(), and its
       
   755     position in the icon view from index().
       
   756 
       
   757     The item's selection status is available from isSelected() and is
       
   758     set and controlled by setSelected() and isSelectable().
       
   759 
       
   760     The text and icon can be set with setText() and setPixmap() and
       
   761     retrieved with text() and pixmap(). The item's sort key defaults
       
   762     to text() but may be set with setKey() and retrieved with key().
       
   763     The comparison function, compare() uses key().
       
   764 
       
   765     Items may be repositioned with move() and moveBy(). An item's
       
   766     geometry is available from rect(), x(), y(), width(), height(),
       
   767     size(), pos(), textRect() and pixmapRect(). You can also test
       
   768     against the position of a point with contains() and intersects().
       
   769 
       
   770     To remove an item from an icon view, just delete the item. The
       
   771     Q3IconViewItem destructor removes it cleanly from its icon view.
       
   772 
       
   773     Because the icon view is designed to use drag-and-drop, the icon
       
   774     view item also has functions for drag-and-drop which may be
       
   775     reimplemented.
       
   776 
       
   777     The class is designed to be very similar to Q3ListView and Q3ListBox
       
   778     in use, both via instantiation and subclassing.
       
   779 */
       
   780 
       
   781 /*!
       
   782     Constructs a Q3IconViewItem and inserts it into icon view \a parent
       
   783     with no text and a default icon.
       
   784 */
       
   785 
       
   786 Q3IconViewItem::Q3IconViewItem(Q3IconView *parent)
       
   787     : view(parent), itemText(), itemIcon(unknown_icon)
       
   788 {
       
   789     init();
       
   790 }
       
   791 
       
   792 /*!
       
   793     Constructs a Q3IconViewItem and inserts it into the icon view \a
       
   794     parent with no text and a default icon, after the icon view item
       
   795     \a after.
       
   796 */
       
   797 
       
   798 Q3IconViewItem::Q3IconViewItem(Q3IconView *parent, Q3IconViewItem *after)
       
   799     : view(parent), itemText(), itemIcon(unknown_icon),
       
   800       prev(0), next(0)
       
   801 {
       
   802     init(after);
       
   803 }
       
   804 
       
   805 /*!
       
   806     Constructs an icon view item  and inserts it into the icon view \a
       
   807     parent using \a text as the text and a default icon.
       
   808 */
       
   809 
       
   810 Q3IconViewItem::Q3IconViewItem(Q3IconView *parent, const QString &text)
       
   811     : view(parent), itemText(text), itemIcon(unknown_icon)
       
   812 {
       
   813     init(0);
       
   814 }
       
   815 
       
   816 /*!
       
   817     Constructs an icon view item and inserts it into the icon view \a
       
   818     parent using \a text as the text and a default icon, after the
       
   819     icon view item \a after.
       
   820 */
       
   821 
       
   822 Q3IconViewItem::Q3IconViewItem(Q3IconView *parent, Q3IconViewItem *after,
       
   823                               const QString &text)
       
   824     : view(parent), itemText(text), itemIcon(unknown_icon)
       
   825 {
       
   826     init(after);
       
   827 }
       
   828 
       
   829 /*!
       
   830     Constructs an icon view item and inserts it into the icon view \a
       
   831     parent using \a text as the text and \a icon as the icon.
       
   832 */
       
   833 
       
   834 Q3IconViewItem::Q3IconViewItem(Q3IconView *parent, const QString &text,
       
   835                               const QPixmap &icon)
       
   836     : view(parent),
       
   837       itemText(text), itemIcon(new QPixmap(icon))
       
   838 {
       
   839     init(0);
       
   840 }
       
   841 
       
   842 
       
   843 /*!
       
   844     Constructs an icon view item and inserts it into the icon view \a
       
   845     parent using \a text as the text and \a icon as the icon, after
       
   846     the icon view item \a after.
       
   847 */
       
   848 
       
   849 Q3IconViewItem::Q3IconViewItem(Q3IconView *parent, Q3IconViewItem *after,
       
   850                               const QString &text, const QPixmap &icon)
       
   851     : view(parent), itemText(text), itemIcon(new QPixmap(icon))
       
   852 {
       
   853     init(after);
       
   854 }
       
   855 
       
   856 /*!
       
   857     Constructs an icon view item and inserts it into the icon view \a
       
   858     parent using \a text as the text and \a picture as the icon.
       
   859 */
       
   860 
       
   861 #ifndef QT_NO_PICTURE
       
   862 Q3IconViewItem::Q3IconViewItem(Q3IconView *parent, const QString &text,
       
   863                               const QPicture &picture)
       
   864     : view(parent), itemText(text), itemIcon(0)
       
   865 {
       
   866     init(0, new QPicture(picture));
       
   867 }
       
   868 
       
   869 /*!
       
   870     Constructs an icon view item and inserts it into the icon view \a
       
   871     parent using \a text as the text and \a picture as the icon, after
       
   872     the icon view item \a after.
       
   873 */
       
   874 
       
   875 Q3IconViewItem::Q3IconViewItem(Q3IconView *parent, Q3IconViewItem *after,
       
   876                               const QString &text, const QPicture &picture)
       
   877     : view(parent), itemText(text), itemIcon(0)
       
   878 {
       
   879     init(after, new QPicture(picture));
       
   880 }
       
   881 #endif
       
   882 
       
   883 /*!
       
   884   This private function initializes the icon view item and inserts it
       
   885   into the icon view.
       
   886 */
       
   887 
       
   888 void Q3IconViewItem::init(Q3IconViewItem *after
       
   889 #ifndef QT_NO_PICTURE
       
   890                           , QPicture *pic
       
   891 #endif
       
   892                          )
       
   893 {
       
   894     d = new Q3IconViewItemPrivate;
       
   895     d->container1 = 0;
       
   896     d->container2 = 0;
       
   897     prev = next = 0;
       
   898     allow_rename = false;
       
   899     allow_drag = true;
       
   900     allow_drop = true;
       
   901     selected = false;
       
   902     selectable = true;
       
   903 #ifndef QT_NO_TEXTEDIT
       
   904     renameBox = 0;
       
   905 #endif
       
   906 #ifndef QT_NO_PICTURE
       
   907     itemPic = pic;
       
   908 #endif
       
   909     if (view) {
       
   910         itemKey = itemText;
       
   911         dirty = true;
       
   912         wordWrapDirty = true;
       
   913         itemRect = QRect(-1, -1, 0, 0);
       
   914         calcRect();
       
   915         view->insertItem(this, after);
       
   916     }
       
   917 }
       
   918 
       
   919 /*!
       
   920     Destroys the icon view item and tells the parent icon view that
       
   921     the item has been destroyed.
       
   922 */
       
   923 
       
   924 Q3IconViewItem::~Q3IconViewItem()
       
   925 {
       
   926 #ifndef QT_NO_TEXTEDIT
       
   927     removeRenameBox();
       
   928 #endif
       
   929     if (view && !view->d->clearing)
       
   930         view->takeItem(this);
       
   931     view = 0;
       
   932     if (itemIcon && itemIcon->serialNumber() != unknown_icon->serialNumber())
       
   933         delete itemIcon;
       
   934 #ifndef QT_NO_PICTURE
       
   935     delete itemPic;
       
   936 #endif
       
   937     delete d;
       
   938 }
       
   939 
       
   940 int Q3IconViewItem::RTTI = 0;
       
   941 
       
   942 /*!
       
   943     Returns 0.
       
   944 
       
   945     Make your derived classes return their own values for rtti(), so
       
   946     that you can distinguish between icon view item types. You should
       
   947     use values greater than 1000, preferably a large random number, to
       
   948     allow for extensions to this class.
       
   949 */
       
   950 
       
   951 int Q3IconViewItem::rtti() const
       
   952 {
       
   953     return RTTI;
       
   954 }
       
   955 
       
   956 
       
   957 /*!
       
   958     Sets \a text as the text of the icon view item. This function
       
   959     might be a no-op if you reimplement text().
       
   960 
       
   961     \sa text()
       
   962 */
       
   963 
       
   964 void Q3IconViewItem::setText(const QString &text)
       
   965 {
       
   966     if (text == itemText)
       
   967         return;
       
   968 
       
   969     wordWrapDirty = true;
       
   970     itemText = text;
       
   971     if (itemKey.isEmpty())
       
   972         itemKey = itemText;
       
   973 
       
   974     QRect oR = rect();
       
   975     calcRect();
       
   976     oR = oR.united(rect());
       
   977 
       
   978     if (view) {
       
   979         if (QRect(view->contentsX(), view->contentsY(),
       
   980                     view->visibleWidth(), view->visibleHeight()).
       
   981              intersects(oR))
       
   982             view->repaintContents(oR.x() - 1, oR.y() - 1, oR.width() + 2, oR.height() + 2);
       
   983     }
       
   984 }
       
   985 
       
   986 /*!
       
   987     Sets \a k as the sort key of the icon view item. By default
       
   988     text() is used for sorting.
       
   989 
       
   990     \sa compare()
       
   991 */
       
   992 
       
   993 void Q3IconViewItem::setKey(const QString &k)
       
   994 {
       
   995     if (k == itemKey)
       
   996         return;
       
   997 
       
   998     itemKey = k;
       
   999 }
       
  1000 
       
  1001 /*!
       
  1002     Sets \a icon as the item's icon in the icon view. This function
       
  1003     might be a no-op if you reimplement pixmap().
       
  1004 
       
  1005     \sa pixmap()
       
  1006 */
       
  1007 
       
  1008 void Q3IconViewItem::setPixmap(const QPixmap &icon)
       
  1009 {
       
  1010     if (itemIcon && itemIcon == unknown_icon)
       
  1011         itemIcon = 0;
       
  1012 
       
  1013     if (itemIcon)
       
  1014         *itemIcon = icon;
       
  1015     else
       
  1016         itemIcon = new QPixmap(icon);
       
  1017     QRect oR = rect();
       
  1018     calcRect();
       
  1019     oR = oR.united(rect());
       
  1020 
       
  1021     if (view) {
       
  1022         if (QRect(view->contentsX(), view->contentsY(),
       
  1023                     view->visibleWidth(), view->visibleHeight()).
       
  1024              intersects(oR))
       
  1025             view->repaintContents(oR.x() - 1, oR.y() - 1, oR.width() + 2, oR.height() + 2);
       
  1026     }
       
  1027 }
       
  1028 
       
  1029 /*!
       
  1030     Sets \a icon as the item's icon in the icon view. This function
       
  1031     might be a no-op if you reimplement picture().
       
  1032 
       
  1033     \sa picture()
       
  1034 */
       
  1035 
       
  1036 #ifndef QT_NO_PICTURE
       
  1037 void Q3IconViewItem::setPicture(const QPicture &icon)
       
  1038 {
       
  1039     // clear assigned pixmap if any
       
  1040     if (itemIcon) {
       
  1041         if (itemIcon == unknown_icon) {
       
  1042             itemIcon = 0;
       
  1043         } else {
       
  1044             delete itemIcon;
       
  1045             itemIcon = 0;
       
  1046         }
       
  1047     }
       
  1048     if (itemPic)
       
  1049         delete itemPic;
       
  1050     itemPic = new QPicture(icon);
       
  1051 
       
  1052     QRect oR = rect();
       
  1053     calcRect();
       
  1054     oR = oR.united(rect());
       
  1055 
       
  1056     if (view) {
       
  1057         if (QRect(view->contentsX(), view->contentsY(),
       
  1058                     view->visibleWidth(), view->visibleHeight()).
       
  1059              intersects(oR))
       
  1060             view->repaintContents(oR.x() - 1, oR.y() - 1, oR.width() + 2, oR.height() + 2);
       
  1061     }
       
  1062 }
       
  1063 #endif
       
  1064 
       
  1065 /*!
       
  1066     \overload
       
  1067 
       
  1068     Sets \a text as the text of the icon view item. If \a recalc is
       
  1069     true, the icon view's layout is recalculated. If \a redraw is true
       
  1070     (the default), the icon view is repainted.
       
  1071 
       
  1072     \sa text()
       
  1073 */
       
  1074 
       
  1075 void Q3IconViewItem::setText(const QString &text, bool recalc, bool redraw)
       
  1076 {
       
  1077     if (text == itemText)
       
  1078         return;
       
  1079 
       
  1080     wordWrapDirty = true;
       
  1081     itemText = text;
       
  1082 
       
  1083     if (recalc)
       
  1084         calcRect();
       
  1085     if (redraw)
       
  1086         repaint();
       
  1087 }
       
  1088 
       
  1089 /*!
       
  1090     \overload
       
  1091 
       
  1092     Sets \a icon as the item's icon in the icon view. If \a recalc is
       
  1093     true, the icon view's layout is recalculated. If \a redraw is true
       
  1094     (the default), the icon view is repainted.
       
  1095 
       
  1096     \sa pixmap()
       
  1097 */
       
  1098 
       
  1099 void Q3IconViewItem::setPixmap(const QPixmap &icon, bool recalc, bool redraw)
       
  1100 {
       
  1101     if (itemIcon && itemIcon == unknown_icon)
       
  1102         itemIcon = 0;
       
  1103 
       
  1104     if (itemIcon)
       
  1105         *itemIcon = icon;
       
  1106     else
       
  1107         itemIcon = new QPixmap(icon);
       
  1108 
       
  1109     if (redraw) {
       
  1110         if (recalc) {
       
  1111             QRect oR = rect();
       
  1112             calcRect();
       
  1113             oR = oR.united(rect());
       
  1114 
       
  1115             if (view) {
       
  1116                 if (QRect(view->contentsX(), view->contentsY(),
       
  1117                             view->visibleWidth(), view->visibleHeight()).
       
  1118                      intersects(oR))
       
  1119                     view->repaintContents(oR.x() - 1, oR.y() - 1, oR.width() + 2, oR.height() + 2);
       
  1120             }
       
  1121         } else {
       
  1122             repaint();
       
  1123         }
       
  1124     } else if (recalc) {
       
  1125         calcRect();
       
  1126     }
       
  1127 }
       
  1128 
       
  1129 /*!
       
  1130     If \a allow is true, the user can rename the icon view item by
       
  1131     clicking on the text (or pressing F2) while the item is selected
       
  1132     (in-place renaming). If \a allow is false, in-place renaming is
       
  1133     not possible.
       
  1134 */
       
  1135 
       
  1136 void Q3IconViewItem::setRenameEnabled(bool allow)
       
  1137 {
       
  1138     allow_rename = (uint)allow;
       
  1139 }
       
  1140 
       
  1141 /*!
       
  1142     If \a allow is true, the icon view permits the user to drag the
       
  1143     icon view item either to another position within the icon view or
       
  1144     to somewhere outside of it. If \a allow is false, the item cannot
       
  1145     be dragged.
       
  1146 */
       
  1147 
       
  1148 void Q3IconViewItem::setDragEnabled(bool allow)
       
  1149 {
       
  1150     allow_drag = (uint)allow;
       
  1151 }
       
  1152 
       
  1153 /*!
       
  1154     If \a allow is true, the icon view lets the user drop something on
       
  1155     this icon view item.
       
  1156 */
       
  1157 
       
  1158 void Q3IconViewItem::setDropEnabled(bool allow)
       
  1159 {
       
  1160     allow_drop = (uint)allow;
       
  1161 }
       
  1162 
       
  1163 /*!
       
  1164     Returns the text of the icon view item. Normally you set the text
       
  1165     of the item with setText(), but sometimes it's inconvenient to
       
  1166     call setText() for every item; so you can subclass Q3IconViewItem,
       
  1167     reimplement this function, and return the text of the item. If you
       
  1168     do this, you must call calcRect() manually each time the text
       
  1169     (and therefore its size) changes.
       
  1170 
       
  1171     \sa setText()
       
  1172 */
       
  1173 
       
  1174 QString Q3IconViewItem::text() const
       
  1175 {
       
  1176     return itemText;
       
  1177 }
       
  1178 
       
  1179 /*!
       
  1180     Returns the key of the icon view item or text() if no key has been
       
  1181     explicitly set.
       
  1182 
       
  1183     \sa setKey(), compare()
       
  1184 */
       
  1185 
       
  1186 QString Q3IconViewItem::key() const
       
  1187 {
       
  1188     return itemKey;
       
  1189 }
       
  1190 
       
  1191 /*!
       
  1192     Returns the icon of the icon view item if it is a pixmap, or 0 if
       
  1193     it is a picture. In the latter case use picture() instead.
       
  1194     Normally you set the pixmap of the item with setPixmap(), but
       
  1195     sometimes it's inconvenient to call setPixmap() for every item. So
       
  1196     you can subclass Q3IconViewItem, reimplement this function and
       
  1197     return a pointer to the item's pixmap. If you do this, you \e must
       
  1198     call calcRect() manually each time the size of this pixmap
       
  1199     changes.
       
  1200 
       
  1201     \sa setPixmap()
       
  1202 */
       
  1203 
       
  1204 QPixmap *Q3IconViewItem::pixmap() const
       
  1205 {
       
  1206     return itemIcon;
       
  1207 }
       
  1208 
       
  1209 /*!
       
  1210     Returns the icon of the icon view item if it is a picture, or 0 if
       
  1211     it is a pixmap. In the latter case use pixmap() instead. Normally
       
  1212     you set the picture of the item with setPicture(), but sometimes
       
  1213     it's inconvenient to call setPicture() for every item. So you can
       
  1214     subclass Q3IconViewItem, reimplement this function and return a
       
  1215     pointer to the item's picture. If you do this, you \e must call
       
  1216     calcRect() manually each time the size of this picture changes.
       
  1217 
       
  1218     \sa setPicture()
       
  1219 */
       
  1220 
       
  1221 #ifndef QT_NO_PICTURE
       
  1222 QPicture *Q3IconViewItem::picture() const
       
  1223 {
       
  1224     return itemPic;
       
  1225 }
       
  1226 #endif
       
  1227 
       
  1228 /*!
       
  1229     Returns true if the item can be renamed by the user with in-place
       
  1230     renaming; otherwise returns false.
       
  1231 
       
  1232     \sa setRenameEnabled()
       
  1233 */
       
  1234 
       
  1235 bool Q3IconViewItem::renameEnabled() const
       
  1236 {
       
  1237     return (bool)allow_rename;
       
  1238 }
       
  1239 
       
  1240 /*!
       
  1241     Returns true if the user is allowed to drag the icon view item;
       
  1242     otherwise returns false.
       
  1243 
       
  1244     \sa setDragEnabled()
       
  1245 */
       
  1246 
       
  1247 bool Q3IconViewItem::dragEnabled() const
       
  1248 {
       
  1249     return (bool)allow_drag;
       
  1250 }
       
  1251 
       
  1252 /*!
       
  1253     Returns true if the user is allowed to drop something onto the
       
  1254     item; otherwise returns false.
       
  1255 
       
  1256     \sa setDropEnabled()
       
  1257 */
       
  1258 
       
  1259 bool Q3IconViewItem::dropEnabled() const
       
  1260 {
       
  1261     return (bool)allow_drop;
       
  1262 }
       
  1263 
       
  1264 /*!
       
  1265     Returns a pointer to this item's icon view parent.
       
  1266 */
       
  1267 
       
  1268 Q3IconView *Q3IconViewItem::iconView() const
       
  1269 {
       
  1270     return view;
       
  1271 }
       
  1272 
       
  1273 /*!
       
  1274     Returns a pointer to the previous item, or 0 if this is the first
       
  1275     item in the icon view.
       
  1276 
       
  1277     \sa nextItem() Q3IconView::firstItem()
       
  1278 */
       
  1279 
       
  1280 Q3IconViewItem *Q3IconViewItem::prevItem() const
       
  1281 {
       
  1282     return prev;
       
  1283 }
       
  1284 
       
  1285 /*!
       
  1286     Returns a pointer to the next item, or 0 if this is the last item
       
  1287     in the icon view.
       
  1288 
       
  1289     To find the first item use Q3IconView::firstItem().
       
  1290 
       
  1291     Example:
       
  1292     \snippet doc/src/snippets/code/src_qt3support_itemviews_q3iconview.cpp 2
       
  1293 
       
  1294     \sa prevItem()
       
  1295 */
       
  1296 
       
  1297 Q3IconViewItem *Q3IconViewItem::nextItem() const
       
  1298 {
       
  1299     return next;
       
  1300 }
       
  1301 
       
  1302 /*!
       
  1303     Returns the index of this item in the icon view, or -1 if an error
       
  1304     occurred.
       
  1305 */
       
  1306 
       
  1307 int Q3IconViewItem::index() const
       
  1308 {
       
  1309     if (view)
       
  1310         return view->index(this);
       
  1311 
       
  1312     return -1;
       
  1313 }
       
  1314 
       
  1315 
       
  1316 
       
  1317 /*!
       
  1318     \overload
       
  1319 
       
  1320     This variant is equivalent to calling the other variant with \e cb
       
  1321     set to false.
       
  1322 */
       
  1323 
       
  1324 void Q3IconViewItem::setSelected(bool s)
       
  1325 {
       
  1326     setSelected(s, false);
       
  1327 }
       
  1328 
       
  1329 /*!
       
  1330     Selects or unselects the item, depending on \a s; it may also
       
  1331     unselect other items, depending on Q3IconView::selectionMode() and
       
  1332     \a cb.
       
  1333 
       
  1334     If \a s is false, the item is unselected.
       
  1335 
       
  1336     If \a s is true and Q3IconView::selectionMode() is
       
  1337     Q3IconView::Single, the item is selected and the item previously
       
  1338     selected is unselected.
       
  1339 
       
  1340     If \a s is true and Q3IconView::selectionMode() is
       
  1341     Q3IconView::Extended, the item is selected. If \a cb is true, the
       
  1342     selection state of the other items is left unchanged. If \a cb is
       
  1343     false (the default) all other items are unselected.
       
  1344 
       
  1345     If \a s is true and Q3IconView::selectionMode() is
       
  1346     Q3IconView::Multi, the item is selected.
       
  1347 
       
  1348     Note that \a cb is used only if Q3IconView::selectionMode() is
       
  1349     Q3IconView::Extended; cb defaults to false.
       
  1350 
       
  1351     All items whose selection status changes repaint themselves.
       
  1352 */
       
  1353 
       
  1354 void Q3IconViewItem::setSelected(bool s, bool cb)
       
  1355 {
       
  1356     if (!view)
       
  1357         return;
       
  1358     if (view->selectionMode() != Q3IconView::NoSelection &&
       
  1359          selectable && s != (bool)selected) {
       
  1360 
       
  1361         if (view->d->selectionMode == Q3IconView::Single && this != view->d->currentItem) {
       
  1362             Q3IconViewItem *o = view->d->currentItem;
       
  1363             if (o && o->selected)
       
  1364                 o->selected = false;
       
  1365             view->d->currentItem = this;
       
  1366             if (o)
       
  1367                 o->repaint();
       
  1368             emit view->currentChanged(this);
       
  1369         }
       
  1370 
       
  1371         if (!s) {
       
  1372             selected = false;
       
  1373         } else {
       
  1374             if (view->d->selectionMode == Q3IconView::Single && view->d->currentItem) {
       
  1375                 view->d->currentItem->selected = false;
       
  1376             }
       
  1377             if ((view->d->selectionMode == Q3IconView::Extended && !cb) ||
       
  1378                  view->d->selectionMode == Q3IconView::Single) {
       
  1379                 bool b = view->signalsBlocked();
       
  1380                 view->blockSignals(true);
       
  1381                 view->selectAll(false);
       
  1382                 view->blockSignals(b);
       
  1383             }
       
  1384             selected = s;
       
  1385         }
       
  1386 
       
  1387         repaint();
       
  1388         if (!view->signalsBlocked()) {
       
  1389             bool emitIt = view->d->selectionMode == Q3IconView::Single && s;
       
  1390             Q3IconView *v = view;
       
  1391             emit v->selectionChanged();
       
  1392             if (emitIt)
       
  1393                 emit v->selectionChanged(this);
       
  1394         }
       
  1395     }
       
  1396 }
       
  1397 
       
  1398 /*!
       
  1399     Sets this item to be selectable if \a enable is true (the default)
       
  1400     or unselectable if \a enable is false.
       
  1401 
       
  1402     The user is unable to select a non-selectable item using either
       
  1403     the keyboard or the mouse. (The application programmer can select
       
  1404     an item in code regardless of this setting.)
       
  1405 
       
  1406     \sa isSelectable()
       
  1407 */
       
  1408 
       
  1409 void Q3IconViewItem::setSelectable(bool enable)
       
  1410 {
       
  1411     selectable = (uint)enable;
       
  1412 }
       
  1413 
       
  1414 /*!
       
  1415     Returns true if the item is selected; otherwise returns false.
       
  1416 
       
  1417     \sa setSelected()
       
  1418 */
       
  1419 
       
  1420 bool Q3IconViewItem::isSelected() const
       
  1421 {
       
  1422     return (bool)selected;
       
  1423 }
       
  1424 
       
  1425 /*!
       
  1426     Returns true if the item is selectable; otherwise returns false.
       
  1427 
       
  1428     \sa setSelectable()
       
  1429 */
       
  1430 
       
  1431 bool Q3IconViewItem::isSelectable() const
       
  1432 {
       
  1433     return (bool)selectable;
       
  1434 }
       
  1435 
       
  1436 /*!
       
  1437     Repaints the item.
       
  1438 */
       
  1439 
       
  1440 void Q3IconViewItem::repaint()
       
  1441 {
       
  1442     if (view)
       
  1443         view->repaintItem(this);
       
  1444 }
       
  1445 
       
  1446 /*!
       
  1447     Moves the item to position (\a x, \a y) in the icon view (these
       
  1448     are contents coordinates). Returns true if the item is moved.
       
  1449     Returns false if the item is already at the specified position.
       
  1450 */
       
  1451 
       
  1452 bool Q3IconViewItem::move(int x, int y)
       
  1453 {
       
  1454     if (x == this->x() && y == this->y())
       
  1455         return false;
       
  1456     itemRect.setRect(x, y, itemRect.width(), itemRect.height());
       
  1457     checkRect();
       
  1458     if (view)
       
  1459         view->updateItemContainer(this);
       
  1460     return true;
       
  1461 }
       
  1462 
       
  1463 /*!
       
  1464     Moves the item \a dx pixels in the x-direction and \a dy pixels in
       
  1465     the y-direction.
       
  1466 */
       
  1467 
       
  1468 void Q3IconViewItem::moveBy(int dx, int dy)
       
  1469 {
       
  1470     itemRect.moveBy(dx, dy);
       
  1471     checkRect();
       
  1472     if (view)
       
  1473         view->updateItemContainer(this);
       
  1474 }
       
  1475 
       
  1476 /*!
       
  1477     \overload
       
  1478 
       
  1479     Moves the item to the point \a pnt.
       
  1480 */
       
  1481 
       
  1482 bool Q3IconViewItem::move(const QPoint &pnt)
       
  1483 {
       
  1484     return move(pnt.x(), pnt.y());
       
  1485 }
       
  1486 
       
  1487 /*!
       
  1488     \overload
       
  1489 
       
  1490     Moves the item by the x, y values in point \a pnt.
       
  1491 */
       
  1492 
       
  1493 void Q3IconViewItem::moveBy(const QPoint &pnt)
       
  1494 {
       
  1495     moveBy(pnt.x(), pnt.y());
       
  1496 }
       
  1497 
       
  1498 /*!
       
  1499     Returns the bounding rectangle of the item (in contents
       
  1500     coordinates).
       
  1501 */
       
  1502 
       
  1503 QRect Q3IconViewItem::rect() const
       
  1504 {
       
  1505     return itemRect;
       
  1506 }
       
  1507 
       
  1508 /*!
       
  1509     Returns the x-coordinate of the item (in contents coordinates).
       
  1510 */
       
  1511 
       
  1512 int Q3IconViewItem::x() const
       
  1513 {
       
  1514     return itemRect.x();
       
  1515 }
       
  1516 
       
  1517 /*!
       
  1518     Returns the y-coordinate of the item (in contents coordinates).
       
  1519 */
       
  1520 
       
  1521 int Q3IconViewItem::y() const
       
  1522 {
       
  1523     return itemRect.y();
       
  1524 }
       
  1525 
       
  1526 /*!
       
  1527     Returns the width of the item.
       
  1528 */
       
  1529 
       
  1530 int Q3IconViewItem::width() const
       
  1531 {
       
  1532     return qMax(itemRect.width(), QApplication::globalStrut().width());
       
  1533 }
       
  1534 
       
  1535 /*!
       
  1536     Returns the height of the item.
       
  1537 */
       
  1538 
       
  1539 int Q3IconViewItem::height() const
       
  1540 {
       
  1541     return qMax(itemRect.height(), QApplication::globalStrut().height());
       
  1542 }
       
  1543 
       
  1544 /*!
       
  1545     Returns the size of the item.
       
  1546 */
       
  1547 
       
  1548 QSize Q3IconViewItem::size() const
       
  1549 {
       
  1550     return QSize(itemRect.width(), itemRect.height());
       
  1551 }
       
  1552 
       
  1553 /*!
       
  1554     Returns the position of the item (in contents coordinates).
       
  1555 */
       
  1556 
       
  1557 QPoint Q3IconViewItem::pos() const
       
  1558 {
       
  1559     return QPoint(itemRect.x(), itemRect.y());
       
  1560 }
       
  1561 
       
  1562 /*!
       
  1563     Returns the bounding rectangle of the item's text.
       
  1564 
       
  1565     If \a relative is true, (the default), the returned rectangle is
       
  1566     relative to the origin of the item's rectangle. If \a relative is
       
  1567     false, the returned rectangle is relative to the origin of the
       
  1568     icon view's contents coordinate system.
       
  1569 */
       
  1570 
       
  1571 QRect Q3IconViewItem::textRect(bool relative) const
       
  1572 {
       
  1573     if (relative)
       
  1574         return itemTextRect;
       
  1575     else
       
  1576         return QRect(x() + itemTextRect.x(), y() + itemTextRect.y(), itemTextRect.width(), itemTextRect.height());
       
  1577 }
       
  1578 
       
  1579 /*!
       
  1580     Returns the bounding rectangle of the item's icon.
       
  1581 
       
  1582     If \a relative is true, (the default), the rectangle is relative to
       
  1583     the origin of the item's rectangle. If \a relative is false, the
       
  1584     returned rectangle is relative to the origin of the icon view's
       
  1585     contents coordinate system.
       
  1586 */
       
  1587 
       
  1588 QRect Q3IconViewItem::pixmapRect(bool relative) const
       
  1589 {
       
  1590     if (relative)
       
  1591         return itemIconRect;
       
  1592     else
       
  1593         return QRect(x() + itemIconRect.x(), y() + itemIconRect.y(), itemIconRect.width(), itemIconRect.height());
       
  1594 }
       
  1595 
       
  1596 /*!
       
  1597     Returns true if the item contains the point \a pnt (in contents
       
  1598     coordinates); otherwise returns false.
       
  1599 */
       
  1600 
       
  1601 bool Q3IconViewItem::contains(const QPoint& pnt) const
       
  1602 {
       
  1603     QRect textArea = textRect(false);
       
  1604     QRect pixmapArea = pixmapRect(false);
       
  1605     if (iconView()->itemTextPos() == Q3IconView::Bottom)
       
  1606         textArea.setTop(pixmapArea.bottom());
       
  1607     else
       
  1608         textArea.setLeft(pixmapArea.right());
       
  1609     return textArea.contains(pnt) || pixmapArea.contains(pnt);
       
  1610 }
       
  1611 
       
  1612 /*!
       
  1613     Returns true if the item intersects the rectangle \a r (in
       
  1614     contents coordinates); otherwise returns false.
       
  1615 */
       
  1616 
       
  1617 bool Q3IconViewItem::intersects(const QRect& r) const
       
  1618 {
       
  1619     return (textRect(false).intersects(r) ||
       
  1620              pixmapRect(false).intersects(r));
       
  1621 }
       
  1622 
       
  1623 /*!
       
  1624     \fn bool Q3IconViewItem::acceptDrop(const QMimeSource *mime) const
       
  1625 
       
  1626     Returns true if you can drop things with a QMimeSource of \a mime
       
  1627     onto this item; otherwise returns false.
       
  1628 
       
  1629     The default implementation always returns false. You must subclass
       
  1630     Q3IconViewItem and reimplement acceptDrop() to accept drops.
       
  1631 */
       
  1632 
       
  1633 bool Q3IconViewItem::acceptDrop(const QMimeSource *) const
       
  1634 {
       
  1635     return false;
       
  1636 }
       
  1637 
       
  1638 #ifndef QT_NO_TEXTEDIT
       
  1639 /*!
       
  1640     Starts in-place renaming of an icon, if allowed.
       
  1641 
       
  1642     This function sets up the icon view so that the user can edit the
       
  1643     item text, and then returns. When the user is done, setText() will
       
  1644     be called and Q3IconView::itemRenamed() will be emitted (unless the
       
  1645     user canceled, e.g. by pressing the Escape key).
       
  1646 
       
  1647     \sa setRenameEnabled()
       
  1648 */
       
  1649 
       
  1650 void Q3IconViewItem::rename()
       
  1651 {
       
  1652     if (!view)
       
  1653         return;
       
  1654     if (renameBox)
       
  1655         removeRenameBox();
       
  1656     oldRect = rect();
       
  1657     renameBox = new Q3IconViewItemLineEdit(itemText, view->viewport(), this, "qt_renamebox");
       
  1658     iconView()->ensureItemVisible(this);
       
  1659     QRect tr(textRect(false));
       
  1660     view->addChild(renameBox, tr.x() + (tr.width() / 2 - renameBox->width() / 2), tr.y() - 3);
       
  1661     renameBox->selectAll();
       
  1662     view->viewport()->setFocusProxy(renameBox);
       
  1663     renameBox->setFocus();
       
  1664     renameBox->show();
       
  1665     Q_ASSERT(view->d->renamingItem == 0L);
       
  1666     view->d->renamingItem = this;
       
  1667 }
       
  1668 #endif
       
  1669 
       
  1670 /*!
       
  1671     Compares this icon view item to \a i. Returns -1 if this item is
       
  1672     less than \a i, 0 if they are equal, and 1 if this icon view item
       
  1673     is greater than \a i.
       
  1674 
       
  1675     The default implementation compares the item keys (key()) using
       
  1676     QString::localeAwareCompare(). A reimplementation may use
       
  1677     different values and a different comparison function. Here is a
       
  1678     reimplementation that uses plain Unicode comparison:
       
  1679 
       
  1680     \snippet doc/src/snippets/code/src_qt3support_itemviews_q3iconview.cpp 3
       
  1681 
       
  1682     \sa key() QString::localeAwareCompare() QString::compare()
       
  1683 */
       
  1684 
       
  1685 int Q3IconViewItem::compare(Q3IconViewItem *i) const
       
  1686 {
       
  1687     return key().localeAwareCompare(i->key());
       
  1688 }
       
  1689 
       
  1690 #ifndef QT_NO_TEXTEDIT
       
  1691 /*!
       
  1692   This private function is called when the user pressed Return during
       
  1693   in-place renaming.
       
  1694 */
       
  1695 
       
  1696 void Q3IconViewItem::renameItem()
       
  1697 {
       
  1698     if (!renameBox || !view)
       
  1699         return;
       
  1700 
       
  1701     if (!view->d->wordWrapIconText) {
       
  1702         wordWrapDirty = true;
       
  1703         calcRect();
       
  1704     }
       
  1705     QRect r = itemRect;
       
  1706     setText(renameBox->text());
       
  1707     view->repaintContents(oldRect.x() - 1, oldRect.y() - 1, oldRect.width() + 2, oldRect.height() + 2);
       
  1708     view->repaintContents(r.x() - 1, r.y() - 1, r.width() + 2, r.height() + 2);
       
  1709     removeRenameBox();
       
  1710 
       
  1711     view->emitRenamed(this);
       
  1712 }
       
  1713 
       
  1714 /*!
       
  1715     Cancels in-place renaming.
       
  1716 */
       
  1717 
       
  1718 void Q3IconViewItem::cancelRenameItem()
       
  1719 {
       
  1720     if (!view)
       
  1721         return;
       
  1722 
       
  1723     QRect r = itemRect;
       
  1724     calcRect();
       
  1725     view->repaintContents(oldRect.x() - 1, oldRect.y() - 1, oldRect.width() + 2, oldRect.height() + 2);
       
  1726     view->repaintContents(r.x() - 1, r.y() - 1, r.width() + 2, r.height() + 2);
       
  1727 
       
  1728     if (!renameBox)
       
  1729         return;
       
  1730 
       
  1731     removeRenameBox();
       
  1732 }
       
  1733 
       
  1734 /*!
       
  1735     Removes the editbox that is used for in-place renaming.
       
  1736 */
       
  1737 
       
  1738 void Q3IconViewItem::removeRenameBox()
       
  1739 {
       
  1740     if (!renameBox || !view)
       
  1741         return;
       
  1742 
       
  1743     bool resetFocus = view->viewport()->focusProxy() == renameBox;
       
  1744     renameBox->hide();
       
  1745     renameBox->deleteLater();
       
  1746     renameBox = 0;
       
  1747     if (resetFocus) {
       
  1748         view->viewport()->setFocusProxy(view);
       
  1749         view->setFocus();
       
  1750     }
       
  1751     Q_ASSERT(view->d->renamingItem == this);
       
  1752     view->d->renamingItem = 0L;
       
  1753 }
       
  1754 #endif
       
  1755 
       
  1756 /*!
       
  1757     This virtual function is responsible for calculating the
       
  1758     rectangles returned by rect(), textRect() and pixmapRect().
       
  1759     setRect(), setTextRect() and setPixmapRect() are provided mainly
       
  1760     for reimplementations of this function.
       
  1761 
       
  1762     \a text_ is an internal parameter which defaults to an empty
       
  1763     string.
       
  1764 */
       
  1765 
       
  1766 void Q3IconViewItem::calcRect(const QString &text_)
       
  1767 {
       
  1768     if (!view) // #####
       
  1769         return;
       
  1770 
       
  1771     wordWrapDirty = true;
       
  1772     int pw = 0;
       
  1773     int ph = 0;
       
  1774 
       
  1775 #ifndef QT_NO_PICTURE
       
  1776     if (picture()) {
       
  1777         QRect br = picture()->boundingRect();
       
  1778         pw = br.width() + 2;
       
  1779         ph = br.height() + 2;
       
  1780     } else
       
  1781 #endif
       
  1782     {
       
  1783         pw = (pixmap() ? pixmap() : unknown_icon)->width() + 2;
       
  1784         ph = (pixmap() ? pixmap() : unknown_icon)->height() + 2;
       
  1785     }
       
  1786 
       
  1787     itemIconRect.setWidth(pw);
       
  1788     itemIconRect.setHeight(ph);
       
  1789 
       
  1790     calcTmpText();
       
  1791 
       
  1792     QString t = text_;
       
  1793     if (t.isEmpty()) {
       
  1794         if (view->d->wordWrapIconText)
       
  1795             t = itemText;
       
  1796         else
       
  1797             t = tmpText;
       
  1798     }
       
  1799 
       
  1800     int tw = 0;
       
  1801     int th = 0;
       
  1802     // ##### TODO: fix font bearings!
       
  1803     QRect r;
       
  1804     if (view->d->wordWrapIconText) {
       
  1805         r = QRect(view->d->fm->boundingRect(0, 0, iconView()->maxItemWidth() -
       
  1806                                               (iconView()->itemTextPos() == Q3IconView::Bottom ? 0 :
       
  1807                                                 pixmapRect().width()),
       
  1808                                               0xFFFFFFFF, Qt::AlignHCenter | Qt::WordBreak | Qt::BreakAnywhere, t));
       
  1809         r.setWidth(r.width() + 4);
       
  1810     } else {
       
  1811         r = QRect(0, 0, view->d->fm->width(t), view->d->fm->height());
       
  1812         r.setWidth(r.width() + 4);
       
  1813     }
       
  1814 
       
  1815     if (r.width() > iconView()->maxItemWidth() -
       
  1816          (iconView()->itemTextPos() == Q3IconView::Bottom ? 0 :
       
  1817            pixmapRect().width()))
       
  1818         r.setWidth(iconView()->maxItemWidth() - (iconView()->itemTextPos() == Q3IconView::Bottom ? 0 :
       
  1819                                                    pixmapRect().width()));
       
  1820 
       
  1821     tw = r.width();
       
  1822     th = r.height();
       
  1823     if (tw < view->d->fm->width(QLatin1Char('X')))
       
  1824         tw = view->d->fm->width(QLatin1Char('X'));
       
  1825 
       
  1826     itemTextRect.setWidth(tw);
       
  1827     itemTextRect.setHeight(th);
       
  1828 
       
  1829     int w = 0;
       
  1830     int h = 0;
       
  1831     if (view->itemTextPos() == Q3IconView::Bottom) {
       
  1832         w = qMax(itemTextRect.width(), itemIconRect.width());
       
  1833         h = itemTextRect.height() + itemIconRect.height() + 1;
       
  1834 
       
  1835         itemRect.setWidth(w);
       
  1836         itemRect.setHeight(h);
       
  1837 
       
  1838         itemTextRect = QRect((width() - itemTextRect.width()) / 2, height() - itemTextRect.height(),
       
  1839                               itemTextRect.width(), itemTextRect.height());
       
  1840         itemIconRect = QRect((width() - itemIconRect.width()) / 2, 0,
       
  1841                               itemIconRect.width(), itemIconRect.height());
       
  1842     } else {
       
  1843         h = qMax(itemTextRect.height(), itemIconRect.height());
       
  1844         w = itemTextRect.width() + itemIconRect.width() + 1;
       
  1845 
       
  1846         itemRect.setWidth(w);
       
  1847         itemRect.setHeight(h);
       
  1848 
       
  1849         itemTextRect = QRect(width() - itemTextRect.width(), (height() - itemTextRect.height()) / 2,
       
  1850                               itemTextRect.width(), itemTextRect.height());
       
  1851         itemIconRect = QRect(0, (height() - itemIconRect.height()) / 2,
       
  1852                               itemIconRect.width(), itemIconRect.height());
       
  1853     }
       
  1854     if (view)
       
  1855         view->updateItemContainer(this);
       
  1856 }
       
  1857 
       
  1858 /*!
       
  1859     Paints the item using the painter \a p and the color group \a cg.
       
  1860     If you want the item to be drawn with a different font or color,
       
  1861     reimplement this function, change the values of the color group or
       
  1862     the painter's font, and then call the Q3IconViewItem::paintItem()
       
  1863     with the changed values.
       
  1864 */
       
  1865 
       
  1866 void Q3IconViewItem::paintItem(QPainter *p, const QColorGroup &cg)
       
  1867 {
       
  1868     if (!view)
       
  1869         return;
       
  1870 
       
  1871     p->save();
       
  1872 
       
  1873     if (isSelected()) {
       
  1874         p->setPen(cg.highlightedText());
       
  1875     } else {
       
  1876         p->setPen(cg.text());
       
  1877     }
       
  1878 
       
  1879     calcTmpText();
       
  1880 
       
  1881 #ifndef QT_NO_PICTURE
       
  1882     if (picture()) {
       
  1883         QPicture *pic = picture();
       
  1884         if (isSelected()) {
       
  1885             p->fillRect(pixmapRect(false), QBrush(cg.highlight(), Qt::Dense4Pattern));
       
  1886         }
       
  1887         p->drawPicture(x()-pic->boundingRect().x(), y()-pic->boundingRect().y(), *pic);
       
  1888         if (isSelected()) {
       
  1889             p->fillRect(textRect(false), cg.highlight());
       
  1890             p->setPen(QPen(cg.highlightedText()));
       
  1891         } else if (view->d->itemTextBrush != QBrush(Qt::NoBrush))
       
  1892             p->fillRect(textRect(false), view->d->itemTextBrush);
       
  1893 
       
  1894         int align = view->itemTextPos() == Q3IconView::Bottom ? Qt::AlignHCenter : Qt::AlignAuto;
       
  1895         if (view->d->wordWrapIconText)
       
  1896             align |= Qt::WordBreak | Qt::BreakAnywhere;
       
  1897         p->drawText(textRect(false), align, view->d->wordWrapIconText ? itemText : tmpText);
       
  1898         p->restore();
       
  1899         return;
       
  1900     }
       
  1901 #endif
       
  1902     bool textOnBottom = (view->itemTextPos() == Q3IconView::Bottom);
       
  1903     int dim;
       
  1904     if (textOnBottom)
       
  1905         dim = (pixmap() ? pixmap() : unknown_icon)->width();
       
  1906     else
       
  1907         dim = (pixmap() ? pixmap() : unknown_icon)->height();
       
  1908     if (isSelected()) {
       
  1909         QPixmap *pix = pixmap() ? pixmap() : unknown_icon;
       
  1910         if (pix && !pix->isNull()) {
       
  1911             QPixmap *buffer = get_qiv_buffer_pixmap(pix->size());
       
  1912             QBitmap mask = view->mask(pix);
       
  1913 
       
  1914             QPainter p2(buffer);
       
  1915             p2.fillRect(pix->rect(), Qt::white);
       
  1916             p2.drawPixmap(0, 0, *pix);
       
  1917             p2.end();
       
  1918 
       
  1919             p2.begin(buffer);
       
  1920             p2.fillRect(pix->rect(), QBrush(cg.highlight(), Qt::Dense4Pattern));
       
  1921             p2.end();
       
  1922             buffer->setMask(mask);
       
  1923 
       
  1924             QRect cr = pix->rect();
       
  1925             if (textOnBottom)
       
  1926                 p->drawPixmap(x() + (width() - dim) / 2, y(), *buffer, 0, 0,
       
  1927                                cr.width(), cr.height());
       
  1928             else
       
  1929                 p->drawPixmap(x() , y() + (height() - dim) / 2, *buffer, 0, 0,
       
  1930                                cr.width(), cr.height());
       
  1931         }
       
  1932     } else {
       
  1933         if (textOnBottom)
       
  1934             p->drawPixmap(x() + (width() - dim) / 2, y(),
       
  1935                            *(pixmap() ? pixmap() : unknown_icon));
       
  1936         else
       
  1937             p->drawPixmap(x() , y() + (height() - dim) / 2,
       
  1938                            *(pixmap() ? pixmap() : unknown_icon));
       
  1939     }
       
  1940 
       
  1941     p->save();
       
  1942     if (isSelected()) {
       
  1943         p->fillRect(textRect(false), cg.highlight());
       
  1944         p->setPen(QPen(cg.highlightedText()));
       
  1945     } else if (view->d->itemTextBrush != QBrush(Qt::NoBrush))
       
  1946         p->fillRect(textRect(false), view->d->itemTextBrush);
       
  1947 
       
  1948     int align = Qt::AlignHCenter;
       
  1949     if (view->d->wordWrapIconText)
       
  1950         align |= Qt::WordBreak | Qt::BreakAnywhere;
       
  1951     p->drawText(textRect(false), align,
       
  1952                  view->d->wordWrapIconText ? itemText : tmpText);
       
  1953 
       
  1954     p->restore();
       
  1955 
       
  1956     p->restore();
       
  1957 }
       
  1958 
       
  1959 /*!
       
  1960     Paints the focus rectangle of the item using the painter \a p and
       
  1961     the color group \a cg.
       
  1962 */
       
  1963 
       
  1964 void Q3IconViewItem::paintFocus(QPainter *p, const QColorGroup &cg)
       
  1965 {
       
  1966     if (!view)
       
  1967         return;
       
  1968 
       
  1969     QStyleOptionFocusRect opt;
       
  1970     opt.rect = textRect(false);
       
  1971     opt.palette = cg;
       
  1972     if (isSelected()) {
       
  1973         opt.state = QStyle::State_FocusAtBorder;
       
  1974         opt.backgroundColor = cg.highlight();
       
  1975     } else {
       
  1976         opt.state = QStyle::State_None;
       
  1977         opt.backgroundColor = cg.base();
       
  1978     }
       
  1979     view->style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p);
       
  1980 
       
  1981     if (this != view->d->currentItem) {
       
  1982         opt.rect = pixmapRect(false);
       
  1983         opt.backgroundColor = cg.base();
       
  1984         opt.state = QStyle::State_None;
       
  1985         view->style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p);
       
  1986     }
       
  1987 }
       
  1988 
       
  1989 #ifndef QT_NO_DRAGANDDROP
       
  1990 /*!
       
  1991     \fn void Q3IconViewItem::dropped(QDropEvent *e, const Q3ValueList<Q3IconDragItem> &lst)
       
  1992 
       
  1993     This function is called when something is dropped on the item. \a
       
  1994     e provides all the information about the drop. If the drag object
       
  1995     of the drop was a Q3IconDrag, \a lst contains the list of the
       
  1996     dropped items. You can get the data by calling
       
  1997     Q3IconDragItem::data() on each item. If the \a lst is empty, i.e.
       
  1998     the drag was not a Q3IconDrag, you must decode the data in \a e and
       
  1999     work with that.
       
  2000 
       
  2001     The default implementation does nothing; subclasses may
       
  2002     reimplement this function.
       
  2003 */
       
  2004 
       
  2005 void Q3IconViewItem::dropped(QDropEvent *, const Q3ValueList<Q3IconDragItem> &)
       
  2006 {
       
  2007 }
       
  2008 #endif
       
  2009 
       
  2010 /*!
       
  2011     This function is called when a drag enters the item's bounding
       
  2012     rectangle.
       
  2013 
       
  2014     The default implementation does nothing; subclasses may
       
  2015     reimplement this function.
       
  2016 */
       
  2017 
       
  2018 void Q3IconViewItem::dragEntered()
       
  2019 {
       
  2020 }
       
  2021 
       
  2022 /*!
       
  2023     This function is called when a drag leaves the item's bounding
       
  2024     rectangle.
       
  2025 
       
  2026     The default implementation does nothing; subclasses may
       
  2027     reimplement this function.
       
  2028 */
       
  2029 
       
  2030 void Q3IconViewItem::dragLeft()
       
  2031 {
       
  2032 }
       
  2033 
       
  2034 /*!
       
  2035     Sets the bounding rectangle of the whole item to \a r. This
       
  2036     function is provided for subclasses which reimplement calcRect(),
       
  2037     so that they can set the calculated rectangle. \e{Any other use is
       
  2038     discouraged.}
       
  2039 
       
  2040     \sa calcRect() textRect() setTextRect() pixmapRect() setPixmapRect()
       
  2041 */
       
  2042 
       
  2043 void Q3IconViewItem::setItemRect(const QRect &r)
       
  2044 {
       
  2045     itemRect = r;
       
  2046     checkRect();
       
  2047     if (view)
       
  2048         view->updateItemContainer(this);
       
  2049 }
       
  2050 
       
  2051 /*!
       
  2052     Sets the bounding rectangle of the item's text to \a r. This
       
  2053     function is provided for subclasses which reimplement calcRect(),
       
  2054     so that they can set the calculated rectangle. \e{Any other use is
       
  2055     discouraged.}
       
  2056 
       
  2057     \sa calcRect() textRect() setItemRect() setPixmapRect()
       
  2058 */
       
  2059 
       
  2060 void Q3IconViewItem::setTextRect(const QRect &r)
       
  2061 {
       
  2062     itemTextRect = r;
       
  2063     if (view)
       
  2064         view->updateItemContainer(this);
       
  2065 }
       
  2066 
       
  2067 /*!
       
  2068     Sets the bounding rectangle of the item's icon to \a r. This
       
  2069     function is provided for subclasses which reimplement calcRect(),
       
  2070     so that they can set the calculated rectangle. \e{Any other use is
       
  2071     discouraged.}
       
  2072 
       
  2073     \sa calcRect() pixmapRect() setItemRect() setTextRect()
       
  2074 */
       
  2075 
       
  2076 void Q3IconViewItem::setPixmapRect(const QRect &r)
       
  2077 {
       
  2078     itemIconRect = r;
       
  2079     if (view)
       
  2080         view->updateItemContainer(this);
       
  2081 }
       
  2082 
       
  2083 /*!
       
  2084     \internal
       
  2085 */
       
  2086 
       
  2087 void Q3IconViewItem::calcTmpText()
       
  2088 {
       
  2089     if (!view || view->d->wordWrapIconText || !wordWrapDirty)
       
  2090         return;
       
  2091     wordWrapDirty = false;
       
  2092 
       
  2093     int w = iconView()->maxItemWidth() - (iconView()->itemTextPos() == Q3IconView::Bottom ? 0 :
       
  2094                                            pixmapRect().width());
       
  2095     if (view->d->fm->width(itemText) < w) {
       
  2096         tmpText = itemText;
       
  2097         return;
       
  2098     }
       
  2099 
       
  2100     tmpText = QLatin1String("...");
       
  2101     int i = 0;
       
  2102     while (view->d->fm->width(tmpText + itemText[i]) < w)
       
  2103         tmpText += itemText[i++];
       
  2104     tmpText.remove((uint)0, 3);
       
  2105     tmpText += QLatin1String("...");
       
  2106 }
       
  2107 
       
  2108 /*! \internal */
       
  2109 
       
  2110 QString Q3IconViewItem::tempText() const
       
  2111 {
       
  2112     return tmpText;
       
  2113 }
       
  2114 
       
  2115 void Q3IconViewItem::checkRect()
       
  2116 {
       
  2117     int x = itemRect.x();
       
  2118     int y = itemRect.y();
       
  2119     int w = itemRect.width();
       
  2120     int h = itemRect.height();
       
  2121 
       
  2122     bool changed = false;
       
  2123     if (x < 0) {
       
  2124         x = 0;
       
  2125         changed = true;
       
  2126     }
       
  2127     if (y < 0) {
       
  2128         y = 0;
       
  2129         changed = true;
       
  2130     }
       
  2131 
       
  2132     if (changed)
       
  2133         itemRect.setRect(x, y, w, h);
       
  2134 }
       
  2135 
       
  2136 
       
  2137 /*!
       
  2138     \class Q3IconView
       
  2139     \brief The Q3IconView class provides an area with movable labelled icons.
       
  2140 
       
  2141     \compat
       
  2142 
       
  2143     A Q3IconView can display and manage a grid or other 2D layout of
       
  2144     labelled icons. Each labelled icon is a Q3IconViewItem. Items
       
  2145     (Q3IconViewItems) can be added or deleted at any time; items can be
       
  2146     moved within the Q3IconView. Single or multiple items can be
       
  2147     selected. Items can be renamed in-place. Q3IconView also supports
       
  2148     \link #draganddrop drag and drop\endlink.
       
  2149 
       
  2150     Each item contains a label string, a pixmap or picture (the icon
       
  2151     itself) and optionally a sort key. The sort key is used for
       
  2152     sorting the items and defaults to the label string. The label
       
  2153     string can be displayed below or to the right of the icon (see \l
       
  2154     ItemTextPos).
       
  2155 
       
  2156     The simplest way to create a Q3IconView is to create a Q3IconView
       
  2157     object and create some Q3IconViewItems with the Q3IconView as their
       
  2158     parent, set the icon view's geometry and show it.
       
  2159     For example:
       
  2160     \snippet doc/src/snippets/code/src_qt3support_itemviews_q3iconview.cpp 4
       
  2161 
       
  2162     The Q3IconViewItem call passes a pointer to the Q3IconView we wish to
       
  2163     populate, along with the label text and a QPixmap.
       
  2164 
       
  2165     When an item is inserted the Q3IconView allocates a position for it.
       
  2166     Existing items are rearranged if autoArrange() is true. The
       
  2167     default arrangement is \l LeftToRight -- the Q3IconView fills up
       
  2168     the \e left-most column from top to bottom, then moves one column
       
  2169     \e right and fills that from top to bottom and so on. The
       
  2170     arrangement can be modified with any of the following approaches:
       
  2171     \list
       
  2172     \i Call setArrangement(), e.g. with \l TopToBottom which will fill
       
  2173     the \e top-most row from left to right, then moves one row \e down
       
  2174     and fills that row from left to right and so on.
       
  2175     \i Construct each Q3IconViewItem using a constructor which allows
       
  2176     you to specify which item the new one is to follow.
       
  2177     \i Call setSorting() or sort() to sort the items.
       
  2178     \endlist
       
  2179 
       
  2180     The spacing between items is set with setSpacing(). Items can be
       
  2181     laid out using a fixed grid using setGridX() and setGridY(); by
       
  2182     default the Q3IconView calculates a grid dynamically. The position
       
  2183     of items' label text is set with setItemTextPos(). The text's
       
  2184     background can be set with setItemTextBackground(). The maximum
       
  2185     width of an item and of its text are set with setMaxItemWidth()
       
  2186     and setMaxItemTextLength(). The label text will be word-wrapped if
       
  2187     it is too long; this is controlled by setWordWrapIconText(). If
       
  2188     the label text is truncated, the user can still see the entire
       
  2189     text in a tool tip if they hover the mouse over the item. This is
       
  2190     controlled with setShowToolTips().
       
  2191 
       
  2192     Items which are \link Q3IconViewItem::isSelectable()
       
  2193     selectable\endlink may be selected depending on the SelectionMode;
       
  2194     the default is \l Single. Because Q3IconView offers multiple
       
  2195     selection it must display keyboard focus and selection state
       
  2196     separately. Therefore there are functions to set the selection
       
  2197     state of an item (setSelected()) and to select which item displays
       
  2198     keyboard focus (setCurrentItem()). When multiple items may be
       
  2199     selected the icon view provides a rubberband, too.
       
  2200 
       
  2201     When in-place renaming is enabled (it is disabled by default), the
       
  2202     user may change the item's label. They do this by selecting the item
       
  2203     (single clicking it or navigating to it with the arrow keys), then
       
  2204     single clicking it (or pressing F2), and entering their text. If no
       
  2205     key has been set with Q3IconViewItem::setKey() the new text will also
       
  2206     serve as the key. (See Q3IconViewItem::setRenameEnabled().)
       
  2207 
       
  2208     You can control whether users can move items themselves with
       
  2209     setItemsMovable().
       
  2210 
       
  2211     Because the internal structure used to store the icon view items is
       
  2212     linear, no iterator class is needed to iterate over all the items.
       
  2213     Instead we iterate by getting the first item from the \e{icon view}
       
  2214     and then each subsequent (\l Q3IconViewItem::nextItem()) from each
       
  2215     \e item in turn:
       
  2216     \snippet doc/src/snippets/code/src_qt3support_itemviews_q3iconview.cpp 5
       
  2217     Q3IconView also provides currentItem(). You can search for an item
       
  2218     using findItem() (searching by position or for label text) and
       
  2219     with findFirstVisibleItem() and findLastVisibleItem(). The number
       
  2220     of items is returned by count(). An item can be removed from an
       
  2221     icon view using takeItem(); to delete an item use \c delete. All
       
  2222     the items can be deleted with clear().
       
  2223 
       
  2224     The Q3IconView emits a wide range of useful signals, including
       
  2225     selectionChanged(), currentChanged(), clicked(), moved() and
       
  2226     itemRenamed().
       
  2227 
       
  2228     \target draganddrop
       
  2229     \section1 Drag and Drop
       
  2230 
       
  2231     Q3IconView supports the drag and drop of items within the Q3IconView
       
  2232     itself. It also supports the drag and drop of items out of or into
       
  2233     the Q3IconView and drag and drop onto items themselves. The drag and
       
  2234     drop of items outside the Q3IconView can be achieved in a simple way
       
  2235     with basic functionality, or in a more sophisticated way which
       
  2236     provides more power and control.
       
  2237 
       
  2238     The simple approach to dragging items out of the icon view is to
       
  2239     subclass Q3IconView and reimplement Q3IconView::dragObject().
       
  2240 
       
  2241     \snippet doc/src/snippets/code/src_qt3support_itemviews_q3iconview.cpp 6
       
  2242 
       
  2243     In this example we create a Q3TextDrag object, (derived from
       
  2244     Q3DragObject), containing the item's label and return it as the drag
       
  2245     object. We could just as easily have created a Q3ImageDrag from the
       
  2246     item's pixmap and returned that instead.
       
  2247 
       
  2248     Q3IconViews and their Q3IconViewItems can also be the targets of drag
       
  2249     and drops. To make the Q3IconView itself able to accept drops connect
       
  2250     to the dropped() signal. When a drop occurs this signal will be
       
  2251     emitted with a QDragEvent and a QLinkedList of Q3IconDragItems. To
       
  2252     make a Q3IconViewItem into a drop target subclass Q3IconViewItem and
       
  2253     reimplement Q3IconViewItem::acceptDrop() and
       
  2254     Q3IconViewItem::dropped().
       
  2255 
       
  2256     \snippet doc/src/snippets/code/src_qt3support_itemviews_q3iconview.cpp 7
       
  2257 
       
  2258     If you want to use extended drag-and-drop or have drag shapes drawn
       
  2259     you must take a more sophisticated approach.
       
  2260 
       
  2261     The first part is starting drags -- you should use a Q3IconDrag (or a
       
  2262     class derived from it) for the drag object. In dragObject() create the
       
  2263     drag object, populate it with Q3IconDragItems and return it. Normally
       
  2264     such a drag should offer each selected item's data. So in dragObject()
       
  2265     you should iterate over all the items, and create a Q3IconDragItem for
       
  2266     each selected item, and append these items with Q3IconDrag::append() to
       
  2267     the Q3IconDrag object. You can use Q3IconDragItem::setData() to set the
       
  2268     data of each item that should be dragged. If you want to offer the
       
  2269     data in additional mime-types, it's best to use a class derived from
       
  2270     Q3IconDrag, which implements additional encoding and decoding
       
  2271     functions.
       
  2272 
       
  2273     When a drag enters the icon view, there is little to do. Simply
       
  2274     connect to the dropped() signal and reimplement
       
  2275     Q3IconViewItem::acceptDrop() and Q3IconViewItem::dropped(). If you've
       
  2276     used a Q3IconDrag (or a subclass of it) the second argument to the
       
  2277     dropped signal contains a QLinkedList of Q3IconDragItems -- you can
       
  2278     access their data by calling Q3IconDragItem::data() on each one.
       
  2279 
       
  2280     For an example implementation of complex drag-and-drop look at the
       
  2281     fileiconview example (qt/examples/fileiconview).
       
  2282 
       
  2283     \sa Q3IconViewItem::setDragEnabled(), Q3IconViewItem::setDropEnabled(),
       
  2284         Q3IconViewItem::acceptDrop(), Q3IconViewItem::dropped()
       
  2285 */
       
  2286 
       
  2287 /*! \enum Q3IconView::ResizeMode
       
  2288 
       
  2289     This enum type is used to tell Q3IconView how it should treat the
       
  2290     positions of its icons when the widget is resized. The modes are:
       
  2291 
       
  2292     \value Fixed  The icons' positions are not changed.
       
  2293     \value Adjust  The icons' positions are adjusted to be within the
       
  2294     new geometry, if possible.
       
  2295 */
       
  2296 
       
  2297 /*!
       
  2298     \enum Q3IconView::SelectionMode
       
  2299 
       
  2300     This enumerated type is used by Q3IconView to indicate how it
       
  2301     reacts to selection by the user. It has four values:
       
  2302 
       
  2303     \value Single  When the user selects an item, any already-selected
       
  2304     item becomes unselected and the user cannot unselect the selected
       
  2305     item. This means that the user can never clear the selection. (The
       
  2306     application programmer can, using Q3IconView::clearSelection().)
       
  2307 
       
  2308     \value Multi  When the user selects an item, e.g. by navigating to
       
  2309     it with the keyboard arrow keys or by clicking it, the selection
       
  2310     status of that item is toggled and the other items are left alone.
       
  2311 
       
  2312     \value Extended  When the user selects an item the selection is
       
  2313     cleared and the new item selected. However, if the user presses
       
  2314     the Ctrl key when clicking on an item, the clicked item gets
       
  2315     toggled and all other items are left untouched. If the user
       
  2316     presses the Shift key while clicking on an item, all items between
       
  2317     the current item and the clicked item get selected or unselected,
       
  2318     depending on the state of the clicked item. Also, multiple items
       
  2319     can be selected by dragging the mouse while the left mouse button
       
  2320     stays pressed.
       
  2321 
       
  2322     \value NoSelection  Items cannot be selected.
       
  2323 
       
  2324     To summarize: \c Single is a real single-selection icon view; \c
       
  2325     Multi a real multi-selection icon view; \c Extended is an icon
       
  2326     view in which users can select multiple items but usually want to
       
  2327     select either just one or a range of contiguous items; and \c
       
  2328     NoSelection mode is for an icon view where the user can look but
       
  2329     not touch.
       
  2330 */
       
  2331 
       
  2332 /*!
       
  2333     \enum Q3IconView::Arrangement
       
  2334 
       
  2335     This enum type determines in which direction the items flow when
       
  2336     the view runs out of space.
       
  2337 
       
  2338     \value LeftToRight  Items which don't fit into the view go further
       
  2339     down (you get a vertical scroll bar)
       
  2340 
       
  2341     \value TopToBottom  Items which don't fit into the view go further
       
  2342     right (you get a horizontal scroll bar)
       
  2343 */
       
  2344 
       
  2345 /*!
       
  2346     \enum Q3IconView::ItemTextPos
       
  2347 
       
  2348     This enum type specifies the position of the item text in relation
       
  2349     to the icon.
       
  2350 
       
  2351     \value Bottom  The text is drawn below the icon.
       
  2352     \value Right  The text is drawn to the right of the icon.
       
  2353 */
       
  2354 
       
  2355 /*!
       
  2356     \fn void Q3IconView::dropped(QDropEvent *e, const Q3ValueList<Q3IconDragItem> &lst)
       
  2357 
       
  2358     This signal is emitted when a drop event occurs in the viewport
       
  2359     (but not on any icon) which the icon view itself can't handle.
       
  2360 
       
  2361     \a e provides all the information about the drop. If the drag
       
  2362     object of the drop was a Q3IconDrag, \a lst contains the list of
       
  2363     the dropped items. You can get the data using
       
  2364     Q3IconDragItem::data() on each item. If the \a lst is empty, i.e.
       
  2365     the drag was not a Q3IconDrag, you have to decode the data in \a e
       
  2366     and work with that.
       
  2367 
       
  2368     Note Q3IconViewItems may be drop targets; if a drop event occurs on
       
  2369     an item the item handles the drop.
       
  2370 */
       
  2371 
       
  2372 /*!
       
  2373     \fn void Q3IconView::moved()
       
  2374 
       
  2375     This signal is emitted after successfully dropping one (or more)
       
  2376     items of the icon view. If the items should be removed, it's best
       
  2377     to do so in a slot connected to this signal.
       
  2378 */
       
  2379 
       
  2380 /*!
       
  2381     \fn void  Q3IconView::doubleClicked(Q3IconViewItem * item)
       
  2382 
       
  2383     This signal is emitted when the user double-clicks on \a item.
       
  2384 */
       
  2385 
       
  2386 /*!
       
  2387     \fn void  Q3IconView::returnPressed (Q3IconViewItem * item)
       
  2388 
       
  2389     This signal is emitted if the user presses the Return or Enter
       
  2390     key. \a item is the currentItem() at the time of the keypress.
       
  2391 */
       
  2392 
       
  2393 /*!
       
  2394     \fn void  Q3IconView::selectionChanged()
       
  2395 
       
  2396     This signal is emitted when the selection has been changed. It's
       
  2397     emitted in each selection mode.
       
  2398 */
       
  2399 
       
  2400 /*!
       
  2401     \fn void Q3IconView::selectionChanged(Q3IconViewItem *item)
       
  2402     \overload
       
  2403 
       
  2404     This signal is emitted when the selection changes. \a item is the
       
  2405     newly selected item. This signal is emitted only in single
       
  2406     selection mode.
       
  2407 */
       
  2408 
       
  2409 /*!
       
  2410     \fn void Q3IconView::currentChanged(Q3IconViewItem *item)
       
  2411 
       
  2412     This signal is emitted when a new item becomes current. \a item is
       
  2413     the new current item (or 0 if no item is now current).
       
  2414 
       
  2415     \sa currentItem()
       
  2416 */
       
  2417 
       
  2418 /*!
       
  2419     \fn void  Q3IconView::onItem(Q3IconViewItem *item)
       
  2420 
       
  2421     This signal is emitted when the user moves the mouse cursor onto
       
  2422     an \a item, similar to the QWidget::enterEvent() function.
       
  2423 */
       
  2424 
       
  2425 // ### bug here - enter/leave event aren't considered. move the mouse
       
  2426 // out of the window and back in, to the same item.
       
  2427 
       
  2428 /*!
       
  2429     \fn void Q3IconView::onViewport()
       
  2430 
       
  2431     This signal is emitted when the user moves the mouse cursor from
       
  2432     an item to an empty part of the icon view.
       
  2433 
       
  2434     \sa onItem()
       
  2435 */
       
  2436 
       
  2437 /*!
       
  2438     \fn void Q3IconView::itemRenamed (Q3IconViewItem * item)
       
  2439     \overload
       
  2440 
       
  2441     This signal is emitted when \a item has been renamed, usually by
       
  2442     in-place renaming.
       
  2443 
       
  2444     \sa Q3IconViewItem::setRenameEnabled() Q3IconViewItem::rename()
       
  2445 */
       
  2446 
       
  2447 /*!
       
  2448     \fn void Q3IconView::itemRenamed (Q3IconViewItem * item, const QString &name)
       
  2449 
       
  2450     This signal is emitted when \a item has been renamed to \a name,
       
  2451     usually by in-place renaming.
       
  2452 
       
  2453     \sa Q3IconViewItem::setRenameEnabled() Q3IconViewItem::rename()
       
  2454 */
       
  2455 
       
  2456 /*!
       
  2457     \fn void Q3IconView::rightButtonClicked (Q3IconViewItem * item, const QPoint & pos)
       
  2458 
       
  2459     This signal is emitted when the user clicks the right mouse
       
  2460     button. If \a item is non-null, the cursor is on \a item. If \a
       
  2461     item is null, the mouse cursor isn't on any item.
       
  2462 
       
  2463     \a pos is the position of the mouse cursor in the global
       
  2464     coordinate system (QMouseEvent::globalPos()). (If the click's
       
  2465     press and release differ by a pixel or two, \a pos is the
       
  2466     position at release time.)
       
  2467 
       
  2468     \sa rightButtonPressed() mouseButtonClicked() clicked()
       
  2469 */
       
  2470 
       
  2471 /*!
       
  2472     \fn void Q3IconView::contextMenuRequested(Q3IconViewItem *item, const QPoint & pos)
       
  2473 
       
  2474     This signal is emitted when the user invokes a context menu with
       
  2475     the right mouse button or with special system keys, with \a item
       
  2476     being the item under the mouse cursor or the current item,
       
  2477     respectively.
       
  2478 
       
  2479     \a pos is the position for the context menu in the global
       
  2480     coordinate system.
       
  2481 */
       
  2482 
       
  2483 /*!
       
  2484     \fn void Q3IconView::mouseButtonPressed(int button, Q3IconViewItem *item, const QPoint &pos)
       
  2485 
       
  2486     This signal is emitted when the user presses mouse button \a
       
  2487     button. If \a item is non-null, the cursor is on \a item. If \a
       
  2488     item is null, the mouse cursor isn't on any item.
       
  2489 
       
  2490     \a pos is the position of the mouse cursor in the global
       
  2491     coordinate system (QMouseEvent::globalPos()).
       
  2492 
       
  2493     \sa rightButtonClicked() mouseButtonClicked() pressed()
       
  2494 */
       
  2495 
       
  2496 /*!
       
  2497     \fn void Q3IconView::mouseButtonClicked (int button, Q3IconViewItem * item, const QPoint & pos)
       
  2498 
       
  2499     This signal is emitted when the user clicks mouse button \a
       
  2500     button. If \a item is non-null, the cursor is on \a item. If \a
       
  2501     item is null, the mouse cursor isn't on any item.
       
  2502 
       
  2503     \a pos is the position of the mouse cursor in the global
       
  2504     coordinate system (QMouseEvent::globalPos()). (If the click's
       
  2505     press and release differ by a pixel or two, \a pos is the
       
  2506     position at release time.)
       
  2507 
       
  2508     \sa mouseButtonPressed() rightButtonClicked() clicked()
       
  2509 */
       
  2510 
       
  2511 /*!
       
  2512     \fn void Q3IconView::clicked (Q3IconViewItem * item, const QPoint & pos)
       
  2513     \overload
       
  2514 
       
  2515     This signal is emitted when the user clicks any mouse button on an
       
  2516     icon view item. \a item is a pointer to the item that has been
       
  2517     clicked.
       
  2518 
       
  2519     \a pos is the position of the mouse cursor in the global coordinate
       
  2520     system (QMouseEvent::globalPos()). (If the click's press and release
       
  2521     differ by a pixel or two, \a pos is the  position at release time.)
       
  2522 
       
  2523     \sa mouseButtonClicked() rightButtonClicked() pressed()
       
  2524 */
       
  2525 
       
  2526 /*!
       
  2527     \fn void Q3IconView::pressed (Q3IconViewItem * item, const QPoint & pos)
       
  2528     \overload
       
  2529 
       
  2530     This signal is emitted when the user presses any mouse button. If
       
  2531     \a item is non-null, the cursor is on \a item. If \a item is null,
       
  2532     the mouse cursor isn't on any item.
       
  2533 
       
  2534     \a pos is the position of the mouse cursor in the global
       
  2535     coordinate system (QMouseEvent::globalPos()). (If the click's
       
  2536     press and release differ by a pixel or two, \a pos is the
       
  2537     position at release time.)
       
  2538 
       
  2539     \sa mouseButtonPressed() rightButtonPressed() clicked()
       
  2540 */
       
  2541 
       
  2542 /*!
       
  2543     \fn void Q3IconView::clicked (Q3IconViewItem * item)
       
  2544 
       
  2545     This signal is emitted when the user clicks any mouse button. If
       
  2546     \a item is non-null, the cursor is on \a item. If \a item is null,
       
  2547     the mouse cursor isn't on any item.
       
  2548 
       
  2549     \sa mouseButtonClicked() rightButtonClicked() pressed()
       
  2550 */
       
  2551 
       
  2552 /*!
       
  2553     \fn void Q3IconView::pressed (Q3IconViewItem * item)
       
  2554 
       
  2555     This signal is emitted when the user presses any mouse button. If
       
  2556     \a item is non-null, the cursor is on \a item. If \a item is null,
       
  2557     the mouse cursor isn't on any item.
       
  2558 
       
  2559     \sa mouseButtonPressed() rightButtonPressed() clicked()
       
  2560 */
       
  2561 
       
  2562 /*!
       
  2563     \fn void Q3IconView::rightButtonPressed(Q3IconViewItem * item, const QPoint & pos)
       
  2564 
       
  2565     This signal is emitted when the user presses the right mouse
       
  2566     button. If \a item is non-null, the cursor is on \a item. If \a
       
  2567     item is null, the mouse cursor isn't on any item.
       
  2568 
       
  2569     \a pos is the position of the mouse cursor in the global
       
  2570     coordinate system (QMouseEvent::globalPos()).
       
  2571 */
       
  2572 
       
  2573 /*!
       
  2574     Constructs an empty icon view called \a name, with parent \a
       
  2575     parent and using the widget flags \a f.
       
  2576 */
       
  2577 
       
  2578 Q3IconView::Q3IconView(QWidget *parent, const char *name, Qt::WindowFlags f)
       
  2579     : Q3ScrollView(parent, name, Qt::WStaticContents | Qt::WNoAutoErase  | f)
       
  2580 {
       
  2581     if (!unknown_icon) {
       
  2582         unknown_icon = new QPixmap((const char **)unknown_xpm);
       
  2583         qiv_cleanup_pixmap.add(&unknown_icon);
       
  2584     }
       
  2585 
       
  2586     d = new Q3IconViewPrivate;
       
  2587     d->dragging = false;
       
  2588     d->firstItem = 0;
       
  2589     d->lastItem = 0;
       
  2590     d->count = 0;
       
  2591     d->mousePressed = false;
       
  2592     d->selectionMode = Single;
       
  2593     d->currentItem = 0;
       
  2594     d->highlightedItem = 0;
       
  2595     d->rubber = 0;
       
  2596     d->scrollTimer = 0;
       
  2597     d->startDragItem = 0;
       
  2598     d->tmpCurrentItem = 0;
       
  2599     d->rastX = d->rastY = -1;
       
  2600     d->spacing = 5;
       
  2601     d->cleared = false;
       
  2602     d->arrangement = LeftToRight;
       
  2603     d->resizeMode = Fixed;
       
  2604     d->dropped = false;
       
  2605     d->adjustTimer = new QTimer(this, "iconview adjust timer");
       
  2606     d->isIconDrag = false;
       
  2607     d->inMenuMode = false;
       
  2608 #ifndef QT_NO_DRAGANDDROP
       
  2609     d->iconDragData.clear();
       
  2610 #endif
       
  2611     d->numDragItems = 0;
       
  2612     d->updateTimer = new QTimer(this, "iconview update timer");
       
  2613     d->cachedW = d->cachedH = 0;
       
  2614     d->maxItemWidth = 100;
       
  2615     d->maxItemTextLength = 255;
       
  2616     d->inputTimer = new QTimer(this, "iconview input timer");
       
  2617     d->currInputString.clear();
       
  2618     d->dirty = false;
       
  2619     d->rearrangeEnabled = true;
       
  2620     d->itemTextPos = Bottom;
       
  2621     d->reorderItemsWhenInsert = true;
       
  2622 #ifndef QT_NO_CURSOR
       
  2623     d->oldCursor = Qt::ArrowCursor;
       
  2624 #endif
       
  2625     d->resortItemsWhenInsert = false;
       
  2626     d->sortDirection = true;
       
  2627     d->wordWrapIconText = true;
       
  2628     d->cachedContentsX = d->cachedContentsY = -1;
       
  2629     d->clearing = false;
       
  2630     d->fullRedrawTimer = new QTimer(this, "iconview full redraw timer");
       
  2631     d->itemTextBrush = Qt::NoBrush;
       
  2632     d->drawAllBack = true;
       
  2633     d->fm = new QFontMetrics(font());
       
  2634     d->minLeftBearing = d->fm->minLeftBearing();
       
  2635     d->minRightBearing = d->fm->minRightBearing();
       
  2636     d->firstContainer = d->lastContainer = 0;
       
  2637     d->containerUpdateLocked = false;
       
  2638     d->firstSizeHint = false;
       
  2639     d->selectAnchor = 0;
       
  2640     d->renamingItem = 0;
       
  2641     d->drawActiveSelection = true;
       
  2642     d->drawDragShapes = false;
       
  2643 
       
  2644     connect(d->adjustTimer, SIGNAL(timeout()),
       
  2645              this, SLOT(adjustItems()));
       
  2646     connect(d->updateTimer, SIGNAL(timeout()),
       
  2647              this, SLOT(slotUpdate()));
       
  2648     connect(d->fullRedrawTimer, SIGNAL(timeout()),
       
  2649              this, SLOT(updateContents()));
       
  2650     connect(this, SIGNAL(contentsMoving(int,int)),
       
  2651              this, SLOT(movedContents(int,int)));
       
  2652 
       
  2653     setAcceptDrops(true);
       
  2654     viewport()->setAcceptDrops(true);
       
  2655 
       
  2656     setMouseTracking(true);
       
  2657     viewport()->setMouseTracking(true);
       
  2658 
       
  2659     viewport()->setBackgroundRole(QPalette::Base);
       
  2660     viewport()->setFocusProxy(this);
       
  2661     viewport()->setFocusPolicy(Qt::WheelFocus);
       
  2662     setFocusPolicy(Qt::WheelFocus);
       
  2663 
       
  2664     d->showTips = true;
       
  2665 }
       
  2666 
       
  2667 /*!
       
  2668     \reimp
       
  2669 */
       
  2670 void Q3IconView::changeEvent(QEvent *ev)
       
  2671 {
       
  2672     if(ev->type() == QEvent::StyleChange) {
       
  2673         *d->fm = QFontMetrics(font());
       
  2674         d->minLeftBearing = d->fm->minLeftBearing();
       
  2675         d->minRightBearing = d->fm->minRightBearing();
       
  2676 
       
  2677         Q3IconViewItem *item = d->firstItem;
       
  2678         for (; item; item = item->next) {
       
  2679             item->wordWrapDirty = true;
       
  2680             item->calcRect();
       
  2681         }
       
  2682 
       
  2683 #if !defined(Q_WS_X11)
       
  2684         delete qiv_selection;
       
  2685         qiv_selection = 0;
       
  2686 #endif
       
  2687     } else if(ev->type() == QEvent::ActivationChange) {
       
  2688         if (!isActiveWindow() && d->scrollTimer)
       
  2689             d->scrollTimer->stop();
       
  2690         if(isVisible() && !palette().isEqual(QPalette::Active, QPalette::Inactive))
       
  2691             repaintSelectedItems();
       
  2692     }
       
  2693 
       
  2694     Q3ScrollView::changeEvent(ev);
       
  2695 
       
  2696     if (ev->type() == QEvent::ApplicationFontChange || ev->type() == QEvent::FontChange) {
       
  2697          *d->fm = QFontMetrics(font());
       
  2698          d->minLeftBearing = d->fm->minLeftBearing();
       
  2699          d->minRightBearing = d->fm->minRightBearing();
       
  2700 
       
  2701          Q3IconViewItem *item = d->firstItem;
       
  2702          for (; item; item = item->next) {
       
  2703              item->wordWrapDirty = true;
       
  2704              item->calcRect();
       
  2705          }
       
  2706     }
       
  2707 }
       
  2708 
       
  2709 /*!
       
  2710     Destroys the icon view and deletes all items.
       
  2711 */
       
  2712 
       
  2713 Q3IconView::~Q3IconView()
       
  2714 {
       
  2715     Q3IconViewItem *tmp, *item = d->firstItem;
       
  2716     d->clearing = true;
       
  2717     Q3IconViewPrivate::ItemContainer *c = d->firstContainer, *tmpc;
       
  2718     while (c) {
       
  2719         tmpc = c->n;
       
  2720         delete c;
       
  2721         c = tmpc;
       
  2722     }
       
  2723     while (item) {
       
  2724         tmp = item->next;
       
  2725         delete item;
       
  2726         item = tmp;
       
  2727     }
       
  2728     delete d->fm;
       
  2729     d->fm = 0;
       
  2730     delete d;
       
  2731 }
       
  2732 
       
  2733 /*!
       
  2734     Inserts the icon view item \a item after \a after. If \a after is
       
  2735     0, \a item is appended after the last item.
       
  2736 
       
  2737     \e{You should never need to call this function.} Instead create
       
  2738     Q3IconViewItem's and associate them with your icon view like this:
       
  2739 
       
  2740     \snippet doc/src/snippets/code/src_qt3support_itemviews_q3iconview.cpp 8
       
  2741 */
       
  2742 
       
  2743 void Q3IconView::insertItem(Q3IconViewItem *item, Q3IconViewItem *after)
       
  2744 {
       
  2745     if (!item)
       
  2746         return;
       
  2747 
       
  2748     if (d->firstItem == item || item->prev || item->next)
       
  2749         return;
       
  2750 
       
  2751     if (!item->view)
       
  2752         item->view = this;
       
  2753 
       
  2754     if (!d->firstItem) {
       
  2755         d->firstItem = d->lastItem = item;
       
  2756         item->prev = 0;
       
  2757         item->next = 0;
       
  2758     } else {
       
  2759         if (!after || after == d->lastItem) {
       
  2760             d->lastItem->next = item;
       
  2761             item->prev = d->lastItem;
       
  2762             item->next = 0;
       
  2763             d->lastItem = item;
       
  2764         } else {
       
  2765             Q3IconViewItem *i = d->firstItem;
       
  2766             while (i != after)
       
  2767                 i = i->next;
       
  2768 
       
  2769             if (i) {
       
  2770                 Q3IconViewItem *next = i->next;
       
  2771                 item->next = next;
       
  2772                 item->prev = i;
       
  2773                 i->next = item;
       
  2774                 next->prev = item;
       
  2775             }
       
  2776         }
       
  2777     }
       
  2778 
       
  2779     if (isVisible()) {
       
  2780         if (d->reorderItemsWhenInsert) {
       
  2781             if (d->updateTimer->isActive())
       
  2782                 d->updateTimer->stop();
       
  2783             d->fullRedrawTimer->stop();
       
  2784             // #### uncomment this ASA insertInGrid uses cached values and is efficient
       
  2785             //insertInGrid(item);
       
  2786 
       
  2787             d->cachedW = qMax(d->cachedW, item->x() + item->width());
       
  2788             d->cachedH= qMax(d->cachedH, item->y() + item->height());
       
  2789 
       
  2790             d->updateTimer->start(0, true);
       
  2791         } else {
       
  2792             insertInGrid(item);
       
  2793 
       
  2794             viewport()->update(item->x() - contentsX(),
       
  2795                                item->y() - contentsY(),
       
  2796                                item->width(), item->height());
       
  2797         }
       
  2798     } else if (!autoArrange()) {
       
  2799         item->dirty = false;
       
  2800     }
       
  2801 
       
  2802     d->count++;
       
  2803     d->dirty = true;
       
  2804 }
       
  2805 
       
  2806 /*!
       
  2807     This slot is used for a slightly-delayed update.
       
  2808 
       
  2809     The icon view is not redrawn immediately after inserting a new item
       
  2810     but after a very small delay using a QTimer. This means that when
       
  2811     many items are inserted in a loop the icon view is probably redrawn
       
  2812     only once at the end of the loop. This makes the insertions both
       
  2813     flicker-free and faster.
       
  2814 */
       
  2815 
       
  2816 void Q3IconView::slotUpdate()
       
  2817 {
       
  2818     d->updateTimer->stop();
       
  2819     d->fullRedrawTimer->stop();
       
  2820 
       
  2821     if (!d->firstItem || !d->lastItem)
       
  2822         return;
       
  2823 
       
  2824     // #### remove that ASA insertInGrid uses cached values and is efficient
       
  2825     if (d->resortItemsWhenInsert)
       
  2826         sort(d->sortDirection);
       
  2827     else {
       
  2828         int y = d->spacing;
       
  2829         Q3IconViewItem *item = d->firstItem;
       
  2830         int w = 0, h = 0;
       
  2831         while (item) {
       
  2832             bool changed;
       
  2833             Q3IconViewItem *next = makeRowLayout(item, y, changed);
       
  2834             if (!next || !next->next)
       
  2835                 break;
       
  2836 
       
  2837             if(!QApplication::reverseLayout())
       
  2838                 item = next;
       
  2839             w = qMax(w, item->x() + item->width());
       
  2840             h = qMax(h, item->y() + item->height());
       
  2841             item = next;
       
  2842             if (d->arrangement == LeftToRight)
       
  2843                 h = qMax(h, y);
       
  2844 
       
  2845             item = item->next;
       
  2846         }
       
  2847 
       
  2848         if (d->lastItem && d->arrangement == TopToBottom) {
       
  2849             item = d->lastItem;
       
  2850             int x = item->x();
       
  2851             while (item && item->x() >= x) {
       
  2852                 w = qMax(w, item->x() + item->width());
       
  2853                 h = qMax(h, item->y() + item->height());
       
  2854                 item = item->prev;
       
  2855             }
       
  2856         }
       
  2857 
       
  2858         w = qMax(qMax(d->cachedW, w), d->lastItem->x() + d->lastItem->width());
       
  2859         h = qMax(qMax(d->cachedH, h), d->lastItem->y() + d->lastItem->height());
       
  2860 
       
  2861         if (d->arrangement == TopToBottom)
       
  2862             w += d->spacing;
       
  2863         else
       
  2864             h += d->spacing;
       
  2865         viewport()->setUpdatesEnabled(false);
       
  2866         resizeContents(w, h);
       
  2867         viewport()->setUpdatesEnabled(true);
       
  2868         viewport()->repaint();
       
  2869     }
       
  2870 
       
  2871     int cx = d->cachedContentsX == -1 ? contentsX() : d->cachedContentsX;
       
  2872     int cy = d->cachedContentsY == -1 ? contentsY() : d->cachedContentsY;
       
  2873 
       
  2874     if (cx != contentsX() || cy != contentsY())
       
  2875         setContentsPos(cx, cy);
       
  2876 
       
  2877     d->cachedContentsX = d->cachedContentsY = -1;
       
  2878     d->cachedW = d->cachedH = 0;
       
  2879 }
       
  2880 
       
  2881 /*!
       
  2882     Takes the icon view item \a item out of the icon view and causes
       
  2883     an update of the screen display. The item is not deleted. You
       
  2884     should normally not need to call this function because
       
  2885     Q3IconViewItem::~Q3IconViewItem() calls it. The normal way to delete
       
  2886     an item is to delete it.
       
  2887 */
       
  2888 
       
  2889 void Q3IconView::takeItem(Q3IconViewItem *item)
       
  2890 {
       
  2891     if (!item)
       
  2892         return;
       
  2893 
       
  2894     if (item->d->container1)
       
  2895         item->d->container1->items.removeAll(item);
       
  2896     if (item->d->container2)
       
  2897         item->d->container2->items.removeAll(item);
       
  2898     item->d->container2 = 0;
       
  2899     item->d->container1 = 0;
       
  2900 
       
  2901     bool block = signalsBlocked();
       
  2902     blockSignals(d->clearing);
       
  2903 
       
  2904     QRect r = item->rect();
       
  2905 
       
  2906     if (d->currentItem == item) {
       
  2907         if (item->prev) {
       
  2908             d->currentItem = item->prev;
       
  2909             emit currentChanged(d->currentItem);
       
  2910             repaintItem(d->currentItem);
       
  2911         } else if (item->next) {
       
  2912             d->currentItem = item->next;
       
  2913             emit currentChanged(d->currentItem);
       
  2914             repaintItem(d->currentItem);
       
  2915         } else {
       
  2916             d->currentItem = 0;
       
  2917             emit currentChanged(d->currentItem);
       
  2918         }
       
  2919     }
       
  2920     if (item->isSelected()) {
       
  2921         item->selected = false;
       
  2922         emit selectionChanged();
       
  2923     }
       
  2924 
       
  2925     if (item == d->firstItem) {
       
  2926         d->firstItem = d->firstItem->next;
       
  2927         if (d->firstItem)
       
  2928             d->firstItem->prev = 0;
       
  2929     } else if (item == d->lastItem) {
       
  2930         d->lastItem = d->lastItem->prev;
       
  2931         if (d->lastItem)
       
  2932             d->lastItem->next = 0;
       
  2933     } else {
       
  2934         Q3IconViewItem *i = item;
       
  2935         if (i) {
       
  2936             if (i->prev)
       
  2937                 i->prev->next = i->next;
       
  2938             if (i->next)
       
  2939                 i->next->prev = i->prev;
       
  2940         }
       
  2941     }
       
  2942 
       
  2943     if (d->selectAnchor == item)
       
  2944         d->selectAnchor = d->currentItem;
       
  2945 
       
  2946     if (!d->clearing)
       
  2947         repaintContents(r.x(), r.y(), r.width(), r.height());
       
  2948 
       
  2949     item->view = 0;
       
  2950     item->prev = 0;
       
  2951     item->next = 0;
       
  2952     d->count--;
       
  2953 
       
  2954     blockSignals(block);
       
  2955 }
       
  2956 
       
  2957 /*!
       
  2958     Returns the index of \a item, or -1 if \a item doesn't exist in
       
  2959     this icon view.
       
  2960 */
       
  2961 
       
  2962 int Q3IconView::index(const Q3IconViewItem *item) const
       
  2963 {
       
  2964     if (!item)
       
  2965         return -1;
       
  2966 
       
  2967     if (item == d->firstItem)
       
  2968         return 0;
       
  2969     else if (item == d->lastItem)
       
  2970         return d->count - 1;
       
  2971     else {
       
  2972         Q3IconViewItem *i = d->firstItem;
       
  2973         int j = 0;
       
  2974         while (i && i != item) {
       
  2975             i = i->next;
       
  2976             ++j;
       
  2977         }
       
  2978 
       
  2979         return i ? j : -1;
       
  2980     }
       
  2981 }
       
  2982 
       
  2983 /*!
       
  2984     Returns a pointer to the first item of the icon view, or 0 if
       
  2985     there are no items in the icon view.
       
  2986 
       
  2987     \sa lastItem() currentItem()
       
  2988 */
       
  2989 
       
  2990 Q3IconViewItem *Q3IconView::firstItem() const
       
  2991 {
       
  2992     return d->firstItem;
       
  2993 }
       
  2994 
       
  2995 /*!
       
  2996     Returns a pointer to the last item of the icon view, or 0 if there
       
  2997     are no items in the icon view.
       
  2998 
       
  2999     \sa firstItem() currentItem()
       
  3000 */
       
  3001 
       
  3002 Q3IconViewItem *Q3IconView::lastItem() const
       
  3003 {
       
  3004     return d->lastItem;
       
  3005 }
       
  3006 
       
  3007 /*!
       
  3008     Returns a pointer to the current item of the icon view, or 0 if no
       
  3009     item is current.
       
  3010 
       
  3011     \sa setCurrentItem() firstItem() lastItem()
       
  3012 */
       
  3013 
       
  3014 Q3IconViewItem *Q3IconView::currentItem() const
       
  3015 {
       
  3016     return d->currentItem;
       
  3017 }
       
  3018 
       
  3019 /*!
       
  3020     \reimp
       
  3021 */
       
  3022 QVariant Q3IconView::inputMethodQuery(Qt::InputMethodQuery query) const
       
  3023 {
       
  3024     if (query == Qt::ImMicroFocus) {
       
  3025         return d->currentItem ? d->currentItem->rect() : QRect();
       
  3026     }
       
  3027     return QWidget::inputMethodQuery(query);
       
  3028 }
       
  3029 
       
  3030 /*!
       
  3031     Makes \a item the new current item of the icon view.
       
  3032 */
       
  3033 
       
  3034 void Q3IconView::setCurrentItem(Q3IconViewItem *item)
       
  3035 {
       
  3036     if (!item || item == d->currentItem)
       
  3037         return;
       
  3038 
       
  3039     Q3IconViewItem *old = d->currentItem;
       
  3040     d->currentItem = item;
       
  3041     emit currentChanged(d->currentItem);
       
  3042     if (d->selectionMode == Single) {
       
  3043         bool changed = false;
       
  3044         if (old && old->selected) {
       
  3045             old->selected = false;
       
  3046             changed = true;
       
  3047         }
       
  3048         if (item && !item->selected && item->isSelectable() && d->selectionMode != NoSelection) {
       
  3049             item->selected = true;
       
  3050             changed = true;
       
  3051             emit selectionChanged(item);
       
  3052         }
       
  3053         if (changed)
       
  3054             emit selectionChanged();
       
  3055     }
       
  3056 
       
  3057     if (old)
       
  3058         repaintItem(old);
       
  3059     repaintItem(d->currentItem);
       
  3060 }
       
  3061 
       
  3062 /*!
       
  3063     Selects or unselects \a item depending on \a s, and may also
       
  3064     unselect other items, depending on Q3IconView::selectionMode() and
       
  3065     \a cb.
       
  3066 
       
  3067     If \a s is false, \a item is unselected.
       
  3068 
       
  3069     If \a s is true and Q3IconView::selectionMode() is \l Single, \a
       
  3070     item is selected, and the item which was selected is unselected.
       
  3071 
       
  3072     If \a s is true and Q3IconView::selectionMode() is \l Extended, \a
       
  3073     item is selected. If \a cb is true, the selection state of the
       
  3074     icon view's other items is left unchanged. If \a cb is false (the
       
  3075     default) all other items are unselected.
       
  3076 
       
  3077     If \a s is true and Q3IconView::selectionMode() is \l Multi \a item
       
  3078     is selected.
       
  3079 
       
  3080     Note that \a cb is used only if Q3IconView::selectionMode() is \l
       
  3081     Extended. \a cb defaults to false.
       
  3082 
       
  3083     All items whose selection status is changed repaint themselves.
       
  3084 */
       
  3085 
       
  3086 void Q3IconView::setSelected(Q3IconViewItem *item, bool s, bool cb)
       
  3087 {
       
  3088     if (!item)
       
  3089         return;
       
  3090     item->setSelected(s, cb);
       
  3091 }
       
  3092 
       
  3093 /*!
       
  3094     \property Q3IconView::count
       
  3095     \brief the number of items in the icon view
       
  3096 */
       
  3097 
       
  3098 uint Q3IconView::count() const
       
  3099 {
       
  3100     return d->count;
       
  3101 }
       
  3102 
       
  3103 /*!
       
  3104     Performs autoscrolling when selecting multiple icons with the
       
  3105     rubber band.
       
  3106 */
       
  3107 
       
  3108 void Q3IconView::doAutoScroll()
       
  3109 {
       
  3110     QRect oldRubber = QRect(*d->rubber);
       
  3111 
       
  3112     QPoint vp = viewport()->mapFromGlobal(QCursor::pos());
       
  3113     QPoint pos = viewportToContents(vp);
       
  3114 
       
  3115     if (pos == d->rubber->bottomRight())
       
  3116         return;
       
  3117 
       
  3118     d->rubber->setRight(pos.x());
       
  3119     d->rubber->setBottom(pos.y());
       
  3120 
       
  3121     int minx = contentsWidth(), miny = contentsHeight();
       
  3122     int maxx = 0, maxy = 0;
       
  3123     bool changed = false;
       
  3124     bool block = signalsBlocked();
       
  3125 
       
  3126     QRect rr;
       
  3127     QRegion region(0, 0, visibleWidth(), visibleHeight());
       
  3128 
       
  3129     blockSignals(true);
       
  3130     viewport()->setUpdatesEnabled(false);
       
  3131     bool alreadyIntersected = false;
       
  3132     QRect nr = d->rubber->normalized();
       
  3133     QRect rubberUnion = nr.united(oldRubber.normalized());
       
  3134     Q3IconViewPrivate::ItemContainer *c = d->firstContainer;
       
  3135     for (; c; c = c->n) {
       
  3136         if (c->rect.intersects(rubberUnion)) {
       
  3137             alreadyIntersected = true;
       
  3138             for (int i = 0; i < c->items.size(); ++i) {
       
  3139                 Q3IconViewItem *item = c->items.at(i);
       
  3140                 if (d->selectedItems.contains(item))
       
  3141                     continue;
       
  3142                 if (!item->intersects(nr)) {
       
  3143                     if (item->isSelected()) {
       
  3144                         item->setSelected(false);
       
  3145                         changed = true;
       
  3146                         rr = rr.united(item->rect());
       
  3147                     }
       
  3148                 } else if (item->intersects(nr)) {
       
  3149                     if (!item->isSelected() && item->isSelectable()) {
       
  3150                         item->setSelected(true, true);
       
  3151                         changed = true;
       
  3152                         rr = rr.united(item->rect());
       
  3153                     } else {
       
  3154                         region = region.subtracted(QRect(contentsToViewport(item->pos()),
       
  3155                                                          item->size()));
       
  3156                     }
       
  3157 
       
  3158                     minx = qMin(minx, item->x() - 1);
       
  3159                     miny = qMin(miny, item->y() - 1);
       
  3160                     maxx = qMax(maxx, item->x() + item->width() + 1);
       
  3161                     maxy = qMax(maxy, item->y() + item->height() + 1);
       
  3162                 }
       
  3163             }
       
  3164         } else {
       
  3165             if (alreadyIntersected)
       
  3166                 break;
       
  3167         }
       
  3168     }
       
  3169     viewport()->setUpdatesEnabled(true);
       
  3170     blockSignals(block);
       
  3171 
       
  3172     QRect r = *d->rubber;
       
  3173     *d->rubber = oldRubber;
       
  3174     d->dragging = false;
       
  3175     *d->rubber = r;
       
  3176     if (changed) {
       
  3177         d->drawAllBack = false;
       
  3178         d->clipRegion = region;
       
  3179         repaintContents(rr);
       
  3180         d->drawAllBack = true;
       
  3181     }
       
  3182     ensureVisible(pos.x(), pos.y());
       
  3183     d->dragging = true;
       
  3184 
       
  3185     if (changed) {
       
  3186         emit selectionChanged();
       
  3187         if (d->selectionMode == Single)
       
  3188             emit selectionChanged(d->currentItem);
       
  3189     }
       
  3190 
       
  3191     if (!QRect(50, 50, viewport()->width()-100, viewport()->height()-100).contains(vp) &&
       
  3192          !d->scrollTimer) {
       
  3193         d->scrollTimer = new QTimer(this);
       
  3194 
       
  3195         connect(d->scrollTimer, SIGNAL(timeout()),
       
  3196                  this, SLOT(doAutoScroll()));
       
  3197         d->scrollTimer->start(100, false);
       
  3198     } else if (QRect(50, 50, viewport()->width()-100, viewport()->height()-100).contains(vp) &&
       
  3199                 d->scrollTimer) {
       
  3200         disconnect(d->scrollTimer, SIGNAL(timeout()),
       
  3201                     this, SLOT(doAutoScroll()));
       
  3202         d->scrollTimer->stop();
       
  3203         delete d->scrollTimer;
       
  3204         d->scrollTimer = 0;
       
  3205     }
       
  3206 
       
  3207 }
       
  3208 
       
  3209 /*!
       
  3210     \reimp
       
  3211 */
       
  3212 
       
  3213 void Q3IconView::drawContents(QPainter *p, int cx, int cy, int cw, int ch)
       
  3214 {
       
  3215     if (d->dragging && d->rubber)
       
  3216         drawRubber(p);
       
  3217 
       
  3218     QRect r = QRect(cx, cy, cw, ch);
       
  3219 
       
  3220     Q3IconViewPrivate::ItemContainer *c = d->firstContainer;
       
  3221     QRegion remaining(QRect(cx, cy, cw, ch));
       
  3222     bool alreadyIntersected = false;
       
  3223     while (c) {
       
  3224         if (c->rect.intersects(r)) {
       
  3225             p->save();
       
  3226             p->resetXForm();
       
  3227             QRect r2 = c->rect;
       
  3228             r2 = r2.intersected(r);
       
  3229             QRect r3(contentsToViewport(QPoint(r2.x(), r2.y())), QSize(r2.width(), r2.height()));
       
  3230             if (d->drawAllBack) {
       
  3231                 p->setClipRect(r3);
       
  3232             } else {
       
  3233                 QRegion reg = d->clipRegion.intersected(r3);
       
  3234                 p->setClipRegion(reg);
       
  3235             }
       
  3236             drawBackground(p, r3);
       
  3237             remaining = remaining.subtracted(r3);
       
  3238             p->restore();
       
  3239 
       
  3240             QPalette pal = palette();
       
  3241             d->drawActiveSelection = hasFocus() || d->inMenuMode
       
  3242                 || !style()->styleHint(QStyle::SH_ItemView_ChangeHighlightOnFocus, 0, this);
       
  3243             if (!d->drawActiveSelection)
       
  3244                 pal.setCurrentColorGroup(QPalette::Inactive);
       
  3245 
       
  3246             // clip items to the container rect by default... this
       
  3247             // prevents icons with alpha channels from being painted
       
  3248             // twice when they are in 2 containers
       
  3249             //
       
  3250             // NOTE: the item could override this cliprect in its
       
  3251             // paintItem() implementation, which makes this useless
       
  3252             p->setClipRect(r2);
       
  3253             for (int i = 0; i < c->items.size(); ++i) {
       
  3254                 Q3IconViewItem *item = c->items.at(i);
       
  3255                 if (item->rect().intersects(r) && !item->dirty) {
       
  3256                     p->save();
       
  3257                     p->setFont(font());
       
  3258                     item->paintItem(p, pal);
       
  3259                     p->restore();
       
  3260                 }
       
  3261             }
       
  3262             alreadyIntersected = true;
       
  3263         } else {
       
  3264             if (alreadyIntersected)
       
  3265                 break;
       
  3266         }
       
  3267         c = c->n;
       
  3268     }
       
  3269 
       
  3270     if (!remaining.isEmpty()) {
       
  3271         p->save();
       
  3272         p->resetXForm();
       
  3273         if (d->drawAllBack) {
       
  3274             p->setClipRegion(remaining);
       
  3275         } else {
       
  3276             remaining = d->clipRegion.intersected(remaining);
       
  3277             p->setClipRegion(remaining);
       
  3278         }
       
  3279         drawBackground(p, remaining.boundingRect());
       
  3280         p->restore();
       
  3281     }
       
  3282 
       
  3283     if ((hasFocus() || viewport()->hasFocus()) && d->currentItem &&
       
  3284          d->currentItem->rect().intersects(r)) {
       
  3285         d->currentItem->paintFocus(p, palette());
       
  3286     }
       
  3287 
       
  3288     if (d->dragging && d->rubber)
       
  3289         drawRubber(p);
       
  3290 }
       
  3291 
       
  3292 /*!
       
  3293     \overload
       
  3294 
       
  3295     Arranges all the items in the grid specified by gridX() and gridY().
       
  3296 
       
  3297     Even if sorting() is enabled, the items are not sorted by this
       
  3298     function. If you want to sort or rearrange the items, use
       
  3299     iconview->sort(iconview->sortDirection()).
       
  3300 
       
  3301     If \a update is true (the default), the viewport is repainted as
       
  3302     well.
       
  3303 
       
  3304     \sa Q3IconView::setGridX(), Q3IconView::setGridY(), Q3IconView::sort()
       
  3305 */
       
  3306 
       
  3307 void Q3IconView::arrangeItemsInGrid(bool update)
       
  3308 {
       
  3309     if (!d->firstItem || !d->lastItem)
       
  3310         return;
       
  3311 
       
  3312     d->containerUpdateLocked = true;
       
  3313 
       
  3314     int w = 0, h = 0, y = d->spacing;
       
  3315 
       
  3316     Q3IconViewItem *item = d->firstItem;
       
  3317     bool changedLayout = false;
       
  3318     while (item) {
       
  3319         bool changed;
       
  3320         Q3IconViewItem *next = makeRowLayout(item, y, changed);
       
  3321         changedLayout = changed || changedLayout;
       
  3322         if(!QApplication::reverseLayout())
       
  3323             item = next;
       
  3324         w = qMax(w, item->x() + item->width());
       
  3325         h = qMax(h, item->y() + item->height());
       
  3326         item = next;
       
  3327         if (d->arrangement == LeftToRight)
       
  3328             h = qMax(h, y);
       
  3329 
       
  3330         if (!item || !item->next)
       
  3331             break;
       
  3332 
       
  3333         item = item->next;
       
  3334     }
       
  3335 
       
  3336     if (d->lastItem && d->arrangement == TopToBottom) {
       
  3337         item = d->lastItem;
       
  3338         int x = item->x();
       
  3339         while (item && item->x() >= x) {
       
  3340             w = qMax(w, item->x() + item->width());
       
  3341             h = qMax(h, item->y() + item->height());
       
  3342             item = item->prev;
       
  3343         }
       
  3344     }
       
  3345     d->containerUpdateLocked = false;
       
  3346 
       
  3347     w = qMax(qMax(d->cachedW, w), d->lastItem->x() + d->lastItem->width());
       
  3348     h = qMax(qMax(d->cachedH, h), d->lastItem->y() + d->lastItem->height());
       
  3349 
       
  3350     if (d->arrangement == TopToBottom)
       
  3351         w += d->spacing;
       
  3352     else
       
  3353         h += d->spacing;
       
  3354 
       
  3355     bool ue = updatesEnabled();
       
  3356     if (ue)
       
  3357         viewport()->setUpdatesEnabled(false);
       
  3358     int vw = visibleWidth();
       
  3359     int vh = visibleHeight();
       
  3360     resizeContents(w, h);
       
  3361     bool doAgain = false;
       
  3362     if (d->arrangement == LeftToRight)
       
  3363         doAgain = visibleWidth() != vw;
       
  3364     if (d->arrangement == TopToBottom)
       
  3365         doAgain = visibleHeight() != vh;
       
  3366     if (doAgain) // in the case that the visibleExtend changed because of the resizeContents (scroll bar show/hide), redo layout again
       
  3367         arrangeItemsInGrid(false);
       
  3368     if (ue)
       
  3369         viewport()->setUpdatesEnabled(true);
       
  3370     d->dirty = !isVisible();
       
  3371     rebuildContainers();
       
  3372     if (update && (!optimize_layout || changedLayout))
       
  3373         repaintContents(contentsX(), contentsY(), viewport()->width(), viewport()->height());
       
  3374 }
       
  3375 
       
  3376 /*!
       
  3377     This variant uses \a grid instead of (gridX(), gridY()). If \a
       
  3378     grid is invalid (see QSize::isValid()), arrangeItemsInGrid()
       
  3379     calculates a valid grid itself and uses that.
       
  3380 
       
  3381     If \a update is true (the default) the viewport is repainted.
       
  3382 */
       
  3383 
       
  3384 void Q3IconView::arrangeItemsInGrid(const QSize &grid, bool update)
       
  3385 {
       
  3386     d->containerUpdateLocked = true;
       
  3387     QSize grid_(grid);
       
  3388     if (!grid_.isValid()) {
       
  3389         int w = 0, h = 0;
       
  3390         Q3IconViewItem *item = d->firstItem;
       
  3391         for (; item; item = item->next) {
       
  3392             w = qMax(w, item->width());
       
  3393             h = qMax(h, item->height());
       
  3394         }
       
  3395 
       
  3396         grid_ = QSize(qMax(d->rastX + d->spacing, w),
       
  3397                        qMax(d->rastY + d->spacing, h));
       
  3398     }
       
  3399 
       
  3400     int w = 0, h = 0;
       
  3401     Q3IconViewItem *item = d->firstItem;
       
  3402     for (; item; item = item->next) {
       
  3403         int nx = item->x() / grid_.width();
       
  3404         int ny = item->y() / grid_.height();
       
  3405         item->move(nx * grid_.width(),
       
  3406                     ny * grid_.height());
       
  3407         w = qMax(w, item->x() + item->width());
       
  3408         h = qMax(h, item->y() + item->height());
       
  3409         item->dirty = false;
       
  3410     }
       
  3411     d->containerUpdateLocked = false;
       
  3412 
       
  3413     resizeContents(w, h);
       
  3414     rebuildContainers();
       
  3415     if (update)
       
  3416         repaintContents(contentsX(), contentsY(), viewport()->width(), viewport()->height());
       
  3417 }
       
  3418 
       
  3419 /*!
       
  3420     \reimp
       
  3421 */
       
  3422 
       
  3423 void Q3IconView::setContentsPos(int x, int y)
       
  3424 {
       
  3425     if (d->updateTimer->isActive()) {
       
  3426         d->cachedContentsX = x;
       
  3427         d->cachedContentsY = y;
       
  3428     } else {
       
  3429         d->cachedContentsY = d->cachedContentsX = -1;
       
  3430         Q3ScrollView::setContentsPos(x, y);
       
  3431     }
       
  3432 }
       
  3433 
       
  3434 /*!
       
  3435     \reimp
       
  3436 */
       
  3437 
       
  3438 void Q3IconView::showEvent(QShowEvent *)
       
  3439 {
       
  3440     if (d->dirty) {
       
  3441         resizeContents(qMax(contentsWidth(), viewport()->width()),
       
  3442                         qMax(contentsHeight(), viewport()->height()));
       
  3443         if (d->resortItemsWhenInsert)
       
  3444             sort(d->sortDirection);
       
  3445         if (autoArrange())
       
  3446             arrangeItemsInGrid(false);
       
  3447     }
       
  3448     Q3ScrollView::show();
       
  3449 }
       
  3450 
       
  3451 /*!
       
  3452     \property Q3IconView::selectionMode
       
  3453     \brief the selection mode of the icon view
       
  3454 
       
  3455     This can be \l Single (the default), \l Extended, \l Multi or \l
       
  3456     NoSelection.
       
  3457 */
       
  3458 
       
  3459 void Q3IconView::setSelectionMode(SelectionMode m)
       
  3460 {
       
  3461     d->selectionMode = m;
       
  3462 }
       
  3463 
       
  3464 Q3IconView::SelectionMode Q3IconView::selectionMode() const
       
  3465 {
       
  3466     return d->selectionMode;
       
  3467 }
       
  3468 
       
  3469 /*!
       
  3470     Returns a pointer to the item that contains point \a pos, which is
       
  3471     given in contents coordinates, or 0 if no item contains point \a
       
  3472     pos.
       
  3473 */
       
  3474 
       
  3475 Q3IconViewItem *Q3IconView::findItem(const QPoint &pos) const
       
  3476 {
       
  3477     if (!d->firstItem)
       
  3478         return 0;
       
  3479 
       
  3480     Q3IconViewPrivate::ItemContainer *c = d->lastContainer;
       
  3481     for (; c; c = c->p) {
       
  3482         if (c->rect.contains(pos))
       
  3483             for (int i = c->items.size()-1; i >= 0; --i)
       
  3484                 if (c->items.at(i)->contains(pos))
       
  3485                     return c->items.at(i);
       
  3486     }
       
  3487 
       
  3488     return 0;
       
  3489 }
       
  3490 
       
  3491 /*!
       
  3492     \overload
       
  3493 
       
  3494     Returns a pointer to the first item whose text begins with \a
       
  3495     text, or 0 if no such item could be found. Use the \a compare flag
       
  3496     to control the comparison behavior.
       
  3497 */
       
  3498 
       
  3499 Q3IconViewItem *Q3IconView::findItem(const QString &text, ComparisonFlags compare) const
       
  3500 {
       
  3501     if (!d->firstItem)
       
  3502         return 0;
       
  3503 
       
  3504     if (compare == CaseSensitive || compare == 0)
       
  3505         compare |= ExactMatch;
       
  3506 
       
  3507     QString itmtxt;
       
  3508     QString comtxt = text;
       
  3509     if (! (compare & CaseSensitive))
       
  3510         comtxt = text.toLower();
       
  3511 
       
  3512     Q3IconViewItem *item;
       
  3513     if (d->currentItem)
       
  3514         item = d->currentItem;
       
  3515     else
       
  3516         item = d->firstItem;
       
  3517 
       
  3518     Q3IconViewItem *beginsWithItem = 0;
       
  3519     Q3IconViewItem *endsWithItem = 0;
       
  3520     Q3IconViewItem *containsItem = 0;
       
  3521 
       
  3522     if (item) {
       
  3523         for (; item; item = item->next) {
       
  3524             if (!(compare & CaseSensitive))
       
  3525                 itmtxt = item->text().toLower();
       
  3526             else
       
  3527                 itmtxt = item->text();
       
  3528 
       
  3529             if ((compare & ExactMatch)==ExactMatch && itmtxt == comtxt)
       
  3530                 return item;
       
  3531             if (compare & BeginsWith && !beginsWithItem && itmtxt.startsWith(comtxt))
       
  3532                 beginsWithItem = containsItem = item;
       
  3533             if (compare & EndsWith && !endsWithItem && itmtxt.endsWith(comtxt))
       
  3534                 endsWithItem = containsItem = item;
       
  3535             if ((compare & ExactMatch)==0 && !containsItem && itmtxt.contains(comtxt))
       
  3536                 containsItem = item;
       
  3537         }
       
  3538 
       
  3539         if (d->currentItem && d->firstItem) {
       
  3540             item = d->firstItem;
       
  3541             for (; item && item != d->currentItem; item = item->next) {
       
  3542                 if (!(compare & CaseSensitive))
       
  3543                     itmtxt = item->text().toLower();
       
  3544                 else
       
  3545                     itmtxt = item->text();
       
  3546 
       
  3547                 if ((compare & ExactMatch)==ExactMatch && itmtxt == comtxt)
       
  3548                     return item;
       
  3549                 if (compare & BeginsWith && !beginsWithItem && itmtxt.startsWith(comtxt))
       
  3550                     beginsWithItem = containsItem = item;
       
  3551                 if (compare & EndsWith && !endsWithItem && itmtxt.endsWith(comtxt))
       
  3552                     endsWithItem = containsItem = item;
       
  3553                 if ((compare & ExactMatch)==0 && !containsItem && itmtxt.contains(comtxt))
       
  3554                     containsItem = item;
       
  3555             }
       
  3556         }
       
  3557     }
       
  3558 
       
  3559     // Obey the priorities
       
  3560     if (beginsWithItem)
       
  3561         return beginsWithItem;
       
  3562     else if (endsWithItem)
       
  3563         return endsWithItem;
       
  3564     else if (containsItem)
       
  3565         return containsItem;
       
  3566     return 0;
       
  3567 }
       
  3568 
       
  3569 /*!
       
  3570     Unselects all the items.
       
  3571 */
       
  3572 
       
  3573 void Q3IconView::clearSelection()
       
  3574 {
       
  3575     selectAll(false);
       
  3576 }
       
  3577 
       
  3578 /*!
       
  3579     In Multi and Extended modes, this function sets all items to be
       
  3580     selected if \a select is true, and to be unselected if \a select
       
  3581     is false.
       
  3582 
       
  3583     In Single and NoSelection modes, this function only changes the
       
  3584     selection status of currentItem().
       
  3585 */
       
  3586 
       
  3587 void Q3IconView::selectAll(bool select)
       
  3588 {
       
  3589     if (d->selectionMode == NoSelection)
       
  3590         return;
       
  3591 
       
  3592     if (d->selectionMode == Single) {
       
  3593         if (d->currentItem)
       
  3594             d->currentItem->setSelected(select);
       
  3595         return;
       
  3596     }
       
  3597 
       
  3598     bool b = signalsBlocked();
       
  3599     blockSignals(true);
       
  3600     Q3IconViewItem *item = d->firstItem;
       
  3601     Q3IconViewItem *i = d->currentItem;
       
  3602     bool changed = false;
       
  3603     bool ue = viewport()->updatesEnabled();
       
  3604     if (ue)
       
  3605         viewport()->setUpdatesEnabled(false);
       
  3606     QRect rr;
       
  3607     for (; item; item = item->next) {
       
  3608         if (select != item->isSelected()) {
       
  3609             item->setSelected(select, true);
       
  3610             rr = rr.united(item->rect());
       
  3611             changed = true;
       
  3612         }
       
  3613     }
       
  3614     if (ue)
       
  3615         viewport()->setUpdatesEnabled(true);
       
  3616     // we call updateContents not repaintContents because of possible previous updateContents
       
  3617     Q3ScrollView::updateContents(rr);
       
  3618     QApplication::sendPostedEvents(viewport(), QEvent::Paint);
       
  3619     if (i)
       
  3620         setCurrentItem(i);
       
  3621     blockSignals(b);
       
  3622     if (changed) {
       
  3623         emit selectionChanged();
       
  3624     }
       
  3625 }
       
  3626 
       
  3627 /*!
       
  3628     Inverts the selection. Works only in Multi and Extended selection
       
  3629     mode.
       
  3630 */
       
  3631 
       
  3632 void Q3IconView::invertSelection()
       
  3633 {
       
  3634     if (d->selectionMode == Single ||
       
  3635          d->selectionMode == NoSelection)
       
  3636         return;
       
  3637 
       
  3638     bool b = signalsBlocked();
       
  3639     blockSignals(true);
       
  3640     Q3IconViewItem *item = d->firstItem;
       
  3641     for (; item; item = item->next)
       
  3642         item->setSelected(!item->isSelected(), true);
       
  3643     blockSignals(b);
       
  3644     emit selectionChanged();
       
  3645 }
       
  3646 
       
  3647 /*!
       
  3648     Repaints the \a item.
       
  3649 */
       
  3650 
       
  3651 void Q3IconView::repaintItem(Q3IconViewItem *item)
       
  3652 {
       
  3653     if (!item || item->dirty)
       
  3654         return;
       
  3655 
       
  3656     if (QRect(contentsX(), contentsY(), visibleWidth(), visibleHeight()).
       
  3657          intersects(QRect(item->x() - 1, item->y() - 1, item->width() + 2, item->height() + 2)))
       
  3658         repaintContents(item->x() - 1, item->y() - 1, item->width() + 2, item->height() + 2);
       
  3659 }
       
  3660 
       
  3661 /*!
       
  3662     Repaints the selected items.
       
  3663 */
       
  3664 void Q3IconView::repaintSelectedItems()
       
  3665 {
       
  3666     if (selectionMode() == NoSelection)
       
  3667         return;
       
  3668 
       
  3669     if (selectionMode() == Single) {
       
  3670         if (!currentItem() || !currentItem()->isSelected())
       
  3671             return;
       
  3672         QRect itemRect = currentItem()->rect(); //rect in contents coordinates
       
  3673         itemRect.moveBy(-contentsX(), -contentsY());
       
  3674         viewport()->update(itemRect);
       
  3675     } else {
       
  3676         // check if any selected items are visible
       
  3677         Q3IconViewItem *item = firstItem();
       
  3678         const QRect vr = QRect(contentsX(), contentsY(), visibleWidth(), visibleHeight());
       
  3679 
       
  3680         while (item) {
       
  3681             if (item->isSelected() && item->rect().intersects(vr))
       
  3682                 repaintItem(item);
       
  3683             item = item->nextItem();
       
  3684         }
       
  3685     }
       
  3686 }
       
  3687 
       
  3688 /*!
       
  3689     Makes sure that \a item is entirely visible. If necessary,
       
  3690     ensureItemVisible() scrolls the icon view.
       
  3691 
       
  3692     \sa ensureVisible()
       
  3693 */
       
  3694 
       
  3695 void Q3IconView::ensureItemVisible(Q3IconViewItem *item)
       
  3696 {
       
  3697     if (!item)
       
  3698         return;
       
  3699 
       
  3700     if ((d->updateTimer && d->updateTimer->isActive())
       
  3701         || (d->fullRedrawTimer && d->fullRedrawTimer->isActive()))
       
  3702         slotUpdate();
       
  3703 
       
  3704     int w = item->width();
       
  3705     int h = item->height();
       
  3706     ensureVisible(item->x() + w / 2, item->y() + h / 2,
       
  3707                    w / 2 + 1, h / 2 + 1);
       
  3708 }
       
  3709 
       
  3710 /*!
       
  3711     Finds the first item whose bounding rectangle overlaps \a r and
       
  3712     returns a pointer to that item. \a r is given in content
       
  3713     coordinates. Returns 0 if no item overlaps \a r.
       
  3714 
       
  3715     If you want to find all items that touch \a r, you will need to
       
  3716     use this function and nextItem() in a loop ending at
       
  3717     findLastVisibleItem() and test Q3IconViewItem::rect() for each of
       
  3718     these items.
       
  3719 
       
  3720     \sa findLastVisibleItem() Q3IconViewItem::rect()
       
  3721 */
       
  3722 
       
  3723 Q3IconViewItem* Q3IconView::findFirstVisibleItem(const QRect &r) const
       
  3724 {
       
  3725     Q3IconViewPrivate::ItemContainer *c = d->firstContainer;
       
  3726     Q3IconViewItem *i = 0;
       
  3727     bool alreadyIntersected = false;
       
  3728     for (; c; c = c->n) {
       
  3729         if (c->rect.intersects(r)) {
       
  3730             alreadyIntersected = true;
       
  3731             for (int j = 0; j < c->items.size(); ++j) {
       
  3732                 Q3IconViewItem *item = c->items.at(j);
       
  3733                 if (r.intersects(item->rect())) {
       
  3734                     if (!i) {
       
  3735                         i = item;
       
  3736                     } else {
       
  3737                         QRect r2 = item->rect();
       
  3738                         QRect r3 = i->rect();
       
  3739                         if (r2.y() < r3.y())
       
  3740                             i = item;
       
  3741                         else if (r2.y() == r3.y() &&
       
  3742                                   r2.x() < r3.x())
       
  3743                             i = item;
       
  3744                     }
       
  3745                 }
       
  3746             }
       
  3747         } else {
       
  3748             if (alreadyIntersected)
       
  3749                 break;
       
  3750         }
       
  3751     }
       
  3752 
       
  3753     return i;
       
  3754 }
       
  3755 
       
  3756 /*!
       
  3757     Finds the last item whose bounding rectangle overlaps \a r and
       
  3758     returns a pointer to that item. \a r is given in content
       
  3759     coordinates. Returns 0 if no item overlaps \a r.
       
  3760 
       
  3761     \sa findFirstVisibleItem()
       
  3762 */
       
  3763 
       
  3764 Q3IconViewItem* Q3IconView::findLastVisibleItem(const QRect &r) const
       
  3765 {
       
  3766     Q3IconViewPrivate::ItemContainer *c = d->firstContainer;
       
  3767     Q3IconViewItem *i = 0;
       
  3768     bool alreadyIntersected = false;
       
  3769     for (; c; c = c->n) {
       
  3770         if (c->rect.intersects(r)) {
       
  3771             alreadyIntersected = true;
       
  3772             for (int j = 0; j < c->items.size(); ++j) {
       
  3773                 Q3IconViewItem *item = c->items.at(j);
       
  3774                 if (r.intersects(item->rect())) {
       
  3775                     if (!i) {
       
  3776                         i = item;
       
  3777                     } else {
       
  3778                         QRect r2 = item->rect();
       
  3779                         QRect r3 = i->rect();
       
  3780                         if (r2.y() > r3.y())
       
  3781                             i = item;
       
  3782                         else if (r2.y() == r3.y() &&
       
  3783                                   r2.x() > r3.x())
       
  3784                             i = item;
       
  3785                     }
       
  3786                 }
       
  3787             }
       
  3788         } else {
       
  3789             if (alreadyIntersected)
       
  3790                 break;
       
  3791         }
       
  3792     }
       
  3793 
       
  3794     return i;
       
  3795 }
       
  3796 
       
  3797 /*!
       
  3798     Clears the icon view. All items are deleted.
       
  3799 */
       
  3800 
       
  3801 void Q3IconView::clear()
       
  3802 {
       
  3803     setContentsPos(0, 0);
       
  3804     d->clearing = true;
       
  3805     bool block = signalsBlocked();
       
  3806     blockSignals(true);
       
  3807     clearSelection();
       
  3808     blockSignals(block);
       
  3809     setContentsPos(0, 0);
       
  3810     d->currentItem = 0;
       
  3811 
       
  3812     if (!d->firstItem) {
       
  3813         d->clearing = false;
       
  3814         return;
       
  3815     }
       
  3816 
       
  3817     Q3IconViewItem *item = d->firstItem, *tmp;
       
  3818     d->firstItem = 0;
       
  3819     while (item) {
       
  3820         tmp = item->next;
       
  3821         delete item;
       
  3822         item = tmp;
       
  3823     }
       
  3824     Q3IconViewPrivate::ItemContainer *c = d->firstContainer, *tmpc;
       
  3825     while (c) {
       
  3826         tmpc = c->n;
       
  3827         delete c;
       
  3828         c = tmpc;
       
  3829     }
       
  3830     d->firstContainer = d->lastContainer = 0;
       
  3831 
       
  3832     d->count = 0;
       
  3833     d->lastItem = 0;
       
  3834     setCurrentItem(0);
       
  3835     d->highlightedItem = 0;
       
  3836     d->tmpCurrentItem = 0;
       
  3837     d->drawDragShapes = false;
       
  3838 
       
  3839     resizeContents(0, 0);
       
  3840     // maybe we don't need this update, so delay it
       
  3841     d->fullRedrawTimer->start(0, true);
       
  3842 
       
  3843     d->cleared = true;
       
  3844     d->clearing = false;
       
  3845 }
       
  3846 
       
  3847 /*!
       
  3848     \property Q3IconView::gridX
       
  3849     \brief the horizontal grid  of the icon view
       
  3850 
       
  3851     If the value is -1, (the default), Q3IconView computes suitable
       
  3852     column widths based on the icon view's contents.
       
  3853 
       
  3854     Note that setting a grid width overrides setMaxItemWidth().
       
  3855 */
       
  3856 
       
  3857 void Q3IconView::setGridX(int rx)
       
  3858 {
       
  3859     d->rastX = rx >= 0 ? rx : -1;
       
  3860 }
       
  3861 
       
  3862 /*!
       
  3863     \property Q3IconView::gridY
       
  3864     \brief the vertical grid  of the icon view
       
  3865 
       
  3866     If the value is -1, (the default), Q3IconView computes suitable
       
  3867     column heights based on the icon view's contents.
       
  3868 */
       
  3869 
       
  3870 void Q3IconView::setGridY(int ry)
       
  3871 {
       
  3872     d->rastY = ry >= 0 ? ry : -1;
       
  3873 }
       
  3874 
       
  3875 int Q3IconView::gridX() const
       
  3876 {
       
  3877     return d->rastX;
       
  3878 }
       
  3879 
       
  3880 int Q3IconView::gridY() const
       
  3881 {
       
  3882     return d->rastY;
       
  3883 }
       
  3884 
       
  3885 /*!
       
  3886     \property Q3IconView::spacing
       
  3887     \brief the space in pixels between icon view items
       
  3888 
       
  3889     The default is 5 pixels.
       
  3890 
       
  3891     Negative values for spacing are illegal.
       
  3892 */
       
  3893 
       
  3894 void Q3IconView::setSpacing(int sp)
       
  3895 {
       
  3896     d->spacing = sp;
       
  3897 }
       
  3898 
       
  3899 int Q3IconView::spacing() const
       
  3900 {
       
  3901     return d->spacing;
       
  3902 }
       
  3903 
       
  3904 /*!
       
  3905     \property Q3IconView::itemTextPos
       
  3906     \brief the position where the text of each item is drawn.
       
  3907 
       
  3908     Valid values are \l Bottom or \l Right. The default is \l Bottom.
       
  3909 */
       
  3910 
       
  3911 void Q3IconView::setItemTextPos(ItemTextPos pos)
       
  3912 {
       
  3913     if (pos == d->itemTextPos || (pos != Bottom && pos != Right))
       
  3914         return;
       
  3915 
       
  3916     d->itemTextPos = pos;
       
  3917 
       
  3918     Q3IconViewItem *item = d->firstItem;
       
  3919     for (; item; item = item->next) {
       
  3920         item->wordWrapDirty = true;
       
  3921         item->calcRect();
       
  3922     }
       
  3923 
       
  3924     arrangeItemsInGrid(true);
       
  3925 }
       
  3926 
       
  3927 Q3IconView::ItemTextPos Q3IconView::itemTextPos() const
       
  3928 {
       
  3929     return d->itemTextPos;
       
  3930 }
       
  3931 
       
  3932 /*!
       
  3933     \property Q3IconView::itemTextBackground
       
  3934     \brief the brush to use when drawing the background of an item's text.
       
  3935 
       
  3936     By default this brush is set to Qt::NoBrush, meaning that only the
       
  3937     normal icon view background is used.
       
  3938 */
       
  3939 
       
  3940 void Q3IconView::setItemTextBackground(const QBrush &brush)
       
  3941 {
       
  3942     d->itemTextBrush = brush;
       
  3943 }
       
  3944 
       
  3945 QBrush Q3IconView::itemTextBackground() const
       
  3946 {
       
  3947     return d->itemTextBrush;
       
  3948 }
       
  3949 
       
  3950 /*!
       
  3951     \property Q3IconView::arrangement
       
  3952     \brief the arrangement mode of the icon view
       
  3953 
       
  3954     This can be \l LeftToRight or \l TopToBottom. The default is \l
       
  3955     LeftToRight.
       
  3956 */
       
  3957 
       
  3958 void Q3IconView::setArrangement(Arrangement am)
       
  3959 {
       
  3960     if (d->arrangement == am)
       
  3961         return;
       
  3962 
       
  3963     d->arrangement = am;
       
  3964 
       
  3965     viewport()->setUpdatesEnabled(false);
       
  3966     resizeContents(viewport()->width(), viewport()->height());
       
  3967     viewport()->setUpdatesEnabled(true);
       
  3968     arrangeItemsInGrid(true);
       
  3969 }
       
  3970 
       
  3971 Q3IconView::Arrangement Q3IconView::arrangement() const
       
  3972 {
       
  3973     return d->arrangement;
       
  3974 }
       
  3975 
       
  3976 /*!
       
  3977     \property Q3IconView::resizeMode
       
  3978     \brief the resize mode of the icon view
       
  3979 
       
  3980     This can be \l Fixed or \l Adjust. The default is \l Fixed.
       
  3981     See \l ResizeMode.
       
  3982 */
       
  3983 
       
  3984 void Q3IconView::setResizeMode(ResizeMode rm)
       
  3985 {
       
  3986     if (d->resizeMode == rm)
       
  3987         return;
       
  3988 
       
  3989     d->resizeMode = rm;
       
  3990 }
       
  3991 
       
  3992 Q3IconView::ResizeMode Q3IconView::resizeMode() const
       
  3993 {
       
  3994     return d->resizeMode;
       
  3995 }
       
  3996 
       
  3997 /*!
       
  3998     \property Q3IconView::maxItemWidth
       
  3999     \brief the maximum width that an item may have.
       
  4000 
       
  4001     The default is 100 pixels.
       
  4002 
       
  4003     Note that if the gridX() value is set Q3IconView will ignore
       
  4004     this property.
       
  4005 */
       
  4006 
       
  4007 void Q3IconView::setMaxItemWidth(int w)
       
  4008 {
       
  4009     d->maxItemWidth = w;
       
  4010 }
       
  4011 
       
  4012 /*!
       
  4013     \property Q3IconView::maxItemTextLength
       
  4014     \brief the maximum length (in characters) that an item's text may have.
       
  4015 
       
  4016     The default is 255 characters.
       
  4017 */
       
  4018 
       
  4019 void Q3IconView::setMaxItemTextLength(int w)
       
  4020 {
       
  4021     d->maxItemTextLength = w;
       
  4022 }
       
  4023 
       
  4024 int Q3IconView::maxItemWidth() const
       
  4025 {
       
  4026     if (d->rastX != -1)
       
  4027         return d->rastX - 2;
       
  4028     else
       
  4029         return d->maxItemWidth;
       
  4030 }
       
  4031 
       
  4032 int Q3IconView::maxItemTextLength() const
       
  4033 {
       
  4034     return d->maxItemTextLength;
       
  4035 }
       
  4036 
       
  4037 /*!
       
  4038     \property Q3IconView::itemsMovable
       
  4039     \brief whether the user is allowed to move items around in the icon view
       
  4040 
       
  4041     The default is true.
       
  4042 */
       
  4043 
       
  4044 void Q3IconView::setItemsMovable(bool b)
       
  4045 {
       
  4046     d->rearrangeEnabled = b;
       
  4047 }
       
  4048 
       
  4049 bool Q3IconView::itemsMovable() const
       
  4050 {
       
  4051     return d->rearrangeEnabled;
       
  4052 }
       
  4053 
       
  4054 /*!
       
  4055     \property Q3IconView::autoArrange
       
  4056     \brief whether the icon view rearranges its items when a new item is inserted.
       
  4057 
       
  4058     The default is true.
       
  4059 
       
  4060     Note that if the icon view is not visible at the time of
       
  4061     insertion, Q3IconView defers all position-related work until it is
       
  4062     shown and then calls arrangeItemsInGrid().
       
  4063 */
       
  4064 
       
  4065 void Q3IconView::setAutoArrange(bool b)
       
  4066 {
       
  4067     d->reorderItemsWhenInsert = b;
       
  4068 }
       
  4069 
       
  4070 bool Q3IconView::autoArrange() const
       
  4071 {
       
  4072     return d->reorderItemsWhenInsert;
       
  4073 }
       
  4074 
       
  4075 /*!
       
  4076     If \a sort is true, this function sets the icon view to sort items
       
  4077     when a new item is inserted. If \a sort is false, the icon view
       
  4078     will not be sorted.
       
  4079 
       
  4080     Note that autoArrange() must be true for sorting to take place.
       
  4081 
       
  4082     If \a ascending is true (the default), items are sorted in
       
  4083     ascending order. If \a ascending is false, items are sorted in
       
  4084     descending order.
       
  4085 
       
  4086     Q3IconViewItem::compare() is used to compare pairs of items. The
       
  4087     sorting is based on the items' keys; these default to the items'
       
  4088     text unless specifically set to something else.
       
  4089 
       
  4090     \sa Q3IconView::setAutoArrange(), Q3IconView::autoArrange(),
       
  4091     sortDirection(), sort(), Q3IconViewItem::setKey()
       
  4092 */
       
  4093 
       
  4094 void Q3IconView::setSorting(bool sort, bool ascending)
       
  4095 {
       
  4096     d->resortItemsWhenInsert = sort;
       
  4097     d->sortDirection = ascending;
       
  4098 }
       
  4099 
       
  4100 /*!
       
  4101     \property Q3IconView::sorting
       
  4102     \brief whether the icon view sorts on insertion
       
  4103 
       
  4104     The default is false, i.e. no sorting on insertion.
       
  4105 
       
  4106     To set the sorting, use setSorting().
       
  4107 */
       
  4108 
       
  4109 bool Q3IconView::sorting() const
       
  4110 {
       
  4111     return d->resortItemsWhenInsert;
       
  4112 }
       
  4113 
       
  4114 /*!
       
  4115     \property Q3IconView::sortDirection
       
  4116     \brief whether the sort direction for inserting new items is ascending;
       
  4117 
       
  4118     The default is true (i.e. ascending). This sort direction is only
       
  4119     meaningful if both sorting() and autoArrange() are true.
       
  4120 
       
  4121     To set the sort direction, use setSorting()
       
  4122 */
       
  4123 
       
  4124 bool Q3IconView::sortDirection() const
       
  4125 {
       
  4126     return d->sortDirection;
       
  4127 }
       
  4128 
       
  4129 /*!
       
  4130     \property Q3IconView::wordWrapIconText
       
  4131     \brief whether the item text will be word-wrapped if it is too long
       
  4132 
       
  4133     The default is true.
       
  4134 
       
  4135     If this property is false, icon text that is too long is
       
  4136     truncated, and an ellipsis (...) appended to indicate that
       
  4137     truncation has occurred. The full text can still be seen by the
       
  4138     user if they hover the mouse because the full text is shown in a
       
  4139     tooltip; see setShowToolTips().
       
  4140 */
       
  4141 
       
  4142 void Q3IconView::setWordWrapIconText(bool b)
       
  4143 {
       
  4144     if (d->wordWrapIconText == (uint)b)
       
  4145         return;
       
  4146 
       
  4147     d->wordWrapIconText = b;
       
  4148     for (Q3IconViewItem *item = d->firstItem; item; item = item->next) {
       
  4149         item->wordWrapDirty = true;
       
  4150         item->calcRect();
       
  4151     }
       
  4152     arrangeItemsInGrid(true);
       
  4153 }
       
  4154 
       
  4155 bool Q3IconView::wordWrapIconText() const
       
  4156 {
       
  4157     return d->wordWrapIconText;
       
  4158 }
       
  4159 
       
  4160 /*!
       
  4161     \property Q3IconView::showToolTips
       
  4162     \brief whether the icon view will display a tool tip with the complete text for any truncated item text
       
  4163 
       
  4164     The default is true. Note that this has no effect if
       
  4165     setWordWrapIconText() is true, as it is by default.
       
  4166 */
       
  4167 
       
  4168 void Q3IconView::setShowToolTips(bool b)
       
  4169 {
       
  4170     d->showTips = b;
       
  4171 }
       
  4172 
       
  4173 bool Q3IconView::showToolTips() const
       
  4174 {
       
  4175     return d->showTips;
       
  4176 }
       
  4177 
       
  4178 /*!
       
  4179     \reimp
       
  4180 */
       
  4181 void Q3IconView::contentsMousePressEvent(QMouseEvent *e)
       
  4182 {
       
  4183     contentsMousePressEventEx(e);
       
  4184 }
       
  4185 
       
  4186 void Q3IconView::contentsMousePressEventEx(QMouseEvent *e)
       
  4187 {
       
  4188     if (d->rubber) {
       
  4189         d->dragging = false;
       
  4190         delete d->rubber;
       
  4191         d->rubber = 0;
       
  4192         viewport()->update();
       
  4193 
       
  4194         if (d->scrollTimer) {
       
  4195             disconnect(d->scrollTimer, SIGNAL(timeout()), this, SLOT(doAutoScroll()));
       
  4196             d->scrollTimer->stop();
       
  4197             delete d->scrollTimer;
       
  4198             d->scrollTimer = 0;
       
  4199         }
       
  4200     }
       
  4201 
       
  4202     d->dragStartPos = e->pos();
       
  4203     Q3IconViewItem *item = findItem(e->pos());
       
  4204     d->pressedItem = item;
       
  4205 
       
  4206     if (item)
       
  4207         d->selectAnchor = item;
       
  4208 
       
  4209 #ifndef QT_NO_TEXTEDIT
       
  4210     if (d->renamingItem)
       
  4211         d->renamingItem->renameItem();
       
  4212 #endif
       
  4213 
       
  4214     if (!d->currentItem && !item && d->firstItem) {
       
  4215         d->currentItem = d->firstItem;
       
  4216         repaintItem(d->firstItem);
       
  4217     }
       
  4218 
       
  4219     if (item && item->dragEnabled())
       
  4220         d->startDragItem = item;
       
  4221     else
       
  4222         d->startDragItem = 0;
       
  4223 
       
  4224     if (e->button() == Qt::LeftButton && !(e->state() & Qt::ShiftButton) &&
       
  4225          !(e->state() & Qt::ControlButton) && item && item->isSelected() &&
       
  4226          item->textRect(false).contains(e->pos())) {
       
  4227 
       
  4228         if (!item->renameEnabled()) {
       
  4229             d->mousePressed = true;
       
  4230 #ifndef QT_NO_TEXTEDIT
       
  4231         } else {
       
  4232             ensureItemVisible(item);
       
  4233             setCurrentItem(item);
       
  4234             item->rename();
       
  4235             goto emit_signals;
       
  4236 #endif
       
  4237         }
       
  4238     }
       
  4239 
       
  4240     d->pressedSelected = item && item->isSelected();
       
  4241 
       
  4242     if (item && item->isSelectable()) {
       
  4243         if (d->selectionMode == Single)
       
  4244             item->setSelected(true, e->state() & Qt::ControlButton);
       
  4245         else if (d->selectionMode == Multi && !item->isSelected())
       
  4246             item->setSelected(true, e->state() & Qt::ControlButton);
       
  4247         else if (d->selectionMode == Extended) {
       
  4248             if (e->state() & Qt::ShiftButton) {
       
  4249                 d->pressedSelected = false;
       
  4250                 bool block = signalsBlocked();
       
  4251                 blockSignals(true);
       
  4252                 viewport()->setUpdatesEnabled(false);
       
  4253                 QRect r;
       
  4254                 bool select = true;
       
  4255                 if (d->currentItem)
       
  4256                     r = QRect(qMin(d->currentItem->x(), item->x()),
       
  4257                                qMin(d->currentItem->y(), item->y()),
       
  4258                                0, 0);
       
  4259                 else
       
  4260                     r = QRect(0, 0, 0, 0);
       
  4261                 if (d->currentItem) {
       
  4262                     if (d->currentItem->x() < item->x())
       
  4263                         r.setWidth(item->x() - d->currentItem->x() + item->width());
       
  4264                     else
       
  4265                         r.setWidth(d->currentItem->x() - item->x() + d->currentItem->width());
       
  4266                     if (d->currentItem->y() < item->y())
       
  4267                         r.setHeight(item->y() - d->currentItem->y() + item->height());
       
  4268                     else
       
  4269                         r.setHeight(d->currentItem->y() - item->y() + d->currentItem->height());
       
  4270                     r = r.normalized();
       
  4271                     Q3IconViewPrivate::ItemContainer *c = d->firstContainer;
       
  4272                     bool alreadyIntersected = false;
       
  4273                     QRect redraw;
       
  4274                     for (; c; c = c->n) {
       
  4275                         if (c->rect.intersects(r)) {
       
  4276                             alreadyIntersected = true;
       
  4277                             for (int i = 0; i < c->items.size(); ++i) {
       
  4278                                 Q3IconViewItem *item = c->items.at(i);
       
  4279                                 if (r.intersects(item->rect())) {
       
  4280                                     redraw = redraw.united(item->rect());
       
  4281                                     item->setSelected(select, true);
       
  4282                                 }
       
  4283                             }
       
  4284                         } else {
       
  4285                             if (alreadyIntersected)
       
  4286                                 break;
       
  4287                         }
       
  4288                     }
       
  4289                     redraw = redraw.united(item->rect());
       
  4290                     viewport()->setUpdatesEnabled(true);
       
  4291                     repaintContents(redraw);
       
  4292                 }
       
  4293                 blockSignals(block);
       
  4294                 viewport()->setUpdatesEnabled(true);
       
  4295                 item->setSelected(select, true);
       
  4296                 emit selectionChanged();
       
  4297             } else if (e->state() & Qt::ControlButton) {
       
  4298                 d->pressedSelected = false;
       
  4299                 item->setSelected(!item->isSelected(), e->state() & Qt::ControlButton);
       
  4300             } else {
       
  4301                 item->setSelected(true, e->state() & Qt::ControlButton);
       
  4302             }
       
  4303         }
       
  4304     } else if ((d->selectionMode != Single || e->button() == Qt::RightButton)
       
  4305                 && !(e->state() & Qt::ControlButton))
       
  4306         selectAll(false);
       
  4307 
       
  4308     setCurrentItem(item);
       
  4309 
       
  4310     if (e->button() == Qt::LeftButton) {
       
  4311         if (!item && (d->selectionMode == Multi ||
       
  4312                                   d->selectionMode == Extended)) {
       
  4313             d->tmpCurrentItem = d->currentItem;
       
  4314             d->currentItem = 0;
       
  4315             repaintItem(d->tmpCurrentItem);
       
  4316             if (d->rubber)
       
  4317                 delete d->rubber;
       
  4318             d->rubber = 0;
       
  4319             d->rubber = new QRect(e->x(), e->y(), 0, 0);
       
  4320             d->selectedItems.clear();
       
  4321             if ((e->state() & Qt::ControlButton) == Qt::ControlButton) {
       
  4322                 for (Q3IconViewItem *i = firstItem(); i; i = i->nextItem())
       
  4323                     if (i->isSelected())
       
  4324                         d->selectedItems.insert(i, i);
       
  4325             }
       
  4326         }
       
  4327 
       
  4328         d->mousePressed = true;
       
  4329     }
       
  4330 
       
  4331  emit_signals:
       
  4332     if (!d->rubber) {
       
  4333         emit mouseButtonPressed(e->button(), item, e->globalPos());
       
  4334         emit pressed(item);
       
  4335         emit pressed(item, e->globalPos());
       
  4336 
       
  4337         if (e->button() == Qt::RightButton)
       
  4338             emit rightButtonPressed(item, e->globalPos());
       
  4339     }
       
  4340 }
       
  4341 
       
  4342 /*!
       
  4343     \reimp
       
  4344 */
       
  4345 
       
  4346 void Q3IconView::contentsContextMenuEvent(QContextMenuEvent *e)
       
  4347 {
       
  4348     if (!receivers(SIGNAL(contextMenuRequested(Q3IconViewItem*,QPoint)))) {
       
  4349         e->ignore();
       
  4350         return;
       
  4351     }
       
  4352     if (e->reason() == QContextMenuEvent::Keyboard) {
       
  4353         Q3IconViewItem *item = currentItem();
       
  4354         QRect r = item ? item->rect() : QRect(0, 0, visibleWidth(), visibleHeight());
       
  4355         emit contextMenuRequested(item, viewport()->mapToGlobal(contentsToViewport(r.center())));
       
  4356     } else {
       
  4357         d->mousePressed = false;
       
  4358         Q3IconViewItem *item = findItem(e->pos());
       
  4359         emit contextMenuRequested(item, e->globalPos());
       
  4360     }
       
  4361 }
       
  4362 
       
  4363 /*!
       
  4364     \reimp
       
  4365 */
       
  4366 
       
  4367 void Q3IconView::contentsMouseReleaseEvent(QMouseEvent *e)
       
  4368 {
       
  4369     Q3IconViewItem *item = findItem(e->pos());
       
  4370     d->selectedItems.clear();
       
  4371 
       
  4372     bool emitClicked = true;
       
  4373     d->mousePressed = false;
       
  4374     d->startDragItem = 0;
       
  4375 
       
  4376     if (d->rubber) {
       
  4377         d->dragging = false;
       
  4378         viewport()->update();
       
  4379 
       
  4380         if ((d->rubber->topLeft() - d->rubber->bottomRight()).manhattanLength() >
       
  4381              QApplication::startDragDistance())
       
  4382             emitClicked = false;
       
  4383         delete d->rubber;
       
  4384         d->rubber = 0;
       
  4385         d->currentItem = d->tmpCurrentItem;
       
  4386         d->tmpCurrentItem = 0;
       
  4387         if (d->currentItem)
       
  4388             repaintItem(d->currentItem);
       
  4389     }
       
  4390 
       
  4391     if (d->scrollTimer) {
       
  4392         disconnect(d->scrollTimer, SIGNAL(timeout()), this, SLOT(doAutoScroll()));
       
  4393         d->scrollTimer->stop();
       
  4394         delete d->scrollTimer;
       
  4395         d->scrollTimer = 0;
       
  4396     }
       
  4397 
       
  4398     if ((d->selectionMode == Extended || d->selectionMode == Multi) &&
       
  4399          d->currentItem == d->pressedItem &&
       
  4400          d->pressedSelected && d->currentItem) {
       
  4401         if (d->selectionMode == Extended) {
       
  4402             bool block = signalsBlocked();
       
  4403             blockSignals(true);
       
  4404             clearSelection();
       
  4405             blockSignals(block);
       
  4406         }
       
  4407         if (d->currentItem->isSelectable()) {
       
  4408             d->currentItem->selected = (d->selectionMode == Extended);
       
  4409             repaintItem(d->currentItem);
       
  4410         }
       
  4411         emit selectionChanged();
       
  4412     }
       
  4413     d->pressedItem = 0;
       
  4414 
       
  4415     if (emitClicked) {
       
  4416         emit mouseButtonClicked(e->button(), item, e->globalPos());
       
  4417         emit clicked(item);
       
  4418         emit clicked(item, e->globalPos());
       
  4419         if (e->button() == Qt::RightButton)
       
  4420             emit rightButtonClicked(item, e->globalPos());
       
  4421     }
       
  4422 }
       
  4423 
       
  4424 /*!
       
  4425     \reimp
       
  4426 */
       
  4427 
       
  4428 void Q3IconView::contentsMouseMoveEvent(QMouseEvent *e)
       
  4429 {
       
  4430     Q3IconViewItem *item = findItem(e->pos());
       
  4431     if (d->highlightedItem != item) {
       
  4432         if (item)
       
  4433             emit onItem(item);
       
  4434         else
       
  4435             emit onViewport();
       
  4436         d->highlightedItem = item;
       
  4437     }
       
  4438 
       
  4439     if (d->mousePressed && e->state() == Qt::NoButton)
       
  4440         d->mousePressed = false;
       
  4441 
       
  4442     if (d->startDragItem)
       
  4443         item = d->startDragItem;
       
  4444 
       
  4445     if (d->mousePressed && d->startDragItem && item && item == d->currentItem &&
       
  4446         (item->isSelected() || d->selectionMode == NoSelection) && item->dragEnabled()) {
       
  4447         if ((d->dragStartPos - e->pos()).manhattanLength() > QApplication::startDragDistance()) {
       
  4448             d->mousePressed = false;
       
  4449             d->cleared = false;
       
  4450 #ifndef QT_NO_DRAGANDDROP
       
  4451             startDrag();
       
  4452 #endif
       
  4453             if (d->tmpCurrentItem)
       
  4454                 repaintItem(d->tmpCurrentItem);
       
  4455         }
       
  4456     } else if (d->mousePressed && !d->currentItem && d->rubber) {
       
  4457         doAutoScroll();
       
  4458     }
       
  4459 }
       
  4460 
       
  4461 /*!
       
  4462     \reimp
       
  4463 */
       
  4464 
       
  4465 void Q3IconView::contentsMouseDoubleClickEvent(QMouseEvent *e)
       
  4466 {
       
  4467     Q3IconViewItem *item = findItem(e->pos());
       
  4468     if (item) {
       
  4469         selectAll(false);
       
  4470         item->setSelected(true, true);
       
  4471         emit doubleClicked(item);
       
  4472     }
       
  4473 }
       
  4474 
       
  4475 /*!
       
  4476     \reimp
       
  4477 */
       
  4478 
       
  4479 #ifndef QT_NO_DRAGANDDROP
       
  4480 void Q3IconView::contentsDragEnterEvent(QDragEnterEvent *e)
       
  4481 {
       
  4482     d->dragging = true;
       
  4483     d->drawDragShapes = true;
       
  4484     d->tmpCurrentItem = 0;
       
  4485     initDragEnter(e);
       
  4486     d->oldDragPos = e->pos();
       
  4487     d->oldDragAcceptAction = false;
       
  4488     drawDragShapes(e->pos());
       
  4489     d->dropped = false;
       
  4490     e->accept();
       
  4491 }
       
  4492 
       
  4493 /*!
       
  4494     \reimp
       
  4495 */
       
  4496 
       
  4497 void Q3IconView::contentsDragMoveEvent(QDragMoveEvent *e)
       
  4498 {
       
  4499     if (e->pos() == d->oldDragPos) {
       
  4500         if (d->oldDragAcceptAction)
       
  4501             e->acceptAction();
       
  4502         else
       
  4503             e->ignore();
       
  4504         return;
       
  4505     }
       
  4506 
       
  4507     drawDragShapes(d->oldDragPos);
       
  4508     d->dragging = false;
       
  4509 
       
  4510     Q3IconViewItem *old = d->tmpCurrentItem;
       
  4511     d->tmpCurrentItem = 0;
       
  4512 
       
  4513     Q3IconViewItem *item = findItem(e->pos());
       
  4514 
       
  4515     if (item) {
       
  4516         if (old &&
       
  4517              old->rect().contains(d->oldDragPos) &&
       
  4518              !old->rect().contains(e->pos())) {
       
  4519             old->dragLeft();
       
  4520             repaintItem(old);
       
  4521         }
       
  4522         if (!item->rect().contains(d->oldDragPos))
       
  4523             item->dragEntered();
       
  4524         if (item->acceptDrop(e) || (item->isSelected() && e->source() == viewport())) {
       
  4525             d->oldDragAcceptAction = true;
       
  4526             e->acceptAction();
       
  4527         } else {
       
  4528             d->oldDragAcceptAction = false;
       
  4529             e->ignore();
       
  4530         }
       
  4531 
       
  4532         d->tmpCurrentItem = item;
       
  4533         viewport()->update();
       
  4534     } else {
       
  4535         e->acceptAction();
       
  4536         d->oldDragAcceptAction = true;
       
  4537         if (old) {
       
  4538             old->dragLeft();
       
  4539             repaintItem(old);
       
  4540         }
       
  4541     }
       
  4542 
       
  4543     d->oldDragPos = e->pos();
       
  4544     drawDragShapes(e->pos());
       
  4545     d->dragging = true;
       
  4546 }
       
  4547 
       
  4548 /*!
       
  4549     \reimp
       
  4550 */
       
  4551 
       
  4552 void Q3IconView::contentsDragLeaveEvent(QDragLeaveEvent *)
       
  4553 {
       
  4554     if (!d->dropped)
       
  4555         drawDragShapes(d->oldDragPos);
       
  4556     d->dragging = false;
       
  4557 
       
  4558     if (d->tmpCurrentItem) {
       
  4559         repaintItem(d->tmpCurrentItem);
       
  4560         d->tmpCurrentItem->dragLeft();
       
  4561     }
       
  4562 
       
  4563     d->tmpCurrentItem = 0;
       
  4564     d->isIconDrag = false;
       
  4565     d->iconDragData.clear();
       
  4566 }
       
  4567 
       
  4568 /*!
       
  4569     \reimp
       
  4570 */
       
  4571 
       
  4572 void Q3IconView::contentsDropEvent(QDropEvent *e)
       
  4573 {
       
  4574     d->dropped = true;
       
  4575     d->dragging = false;
       
  4576     drawDragShapes(d->oldDragPos);
       
  4577 
       
  4578     if (d->tmpCurrentItem)
       
  4579         repaintItem(d->tmpCurrentItem);
       
  4580 
       
  4581     Q3IconViewItem *i = findItem(e->pos());
       
  4582 
       
  4583     if ((!i || i->isSelected()) && e->source() == viewport() && d->currentItem && !d->cleared) {
       
  4584         if (!d->rearrangeEnabled)
       
  4585             return;
       
  4586         QRect r = d->currentItem->rect();
       
  4587 
       
  4588         d->currentItem->move(e->pos() - d->dragStart);
       
  4589 
       
  4590         int w = d->currentItem->x() + d->currentItem->width() + 1;
       
  4591         int h = d->currentItem->y() + d->currentItem->height() + 1;
       
  4592 
       
  4593         repaintItem(d->currentItem);
       
  4594         repaintContents(r.x(), r.y(), r.width(), r.height());
       
  4595 
       
  4596         int dx = d->currentItem->x() - r.x();
       
  4597         int dy = d->currentItem->y() - r.y();
       
  4598 
       
  4599         Q3IconViewItem *item = d->firstItem;
       
  4600         QRect rr;
       
  4601         for (; item; item = item->next) {
       
  4602             if (item->isSelected() && item != d->currentItem) {
       
  4603                 rr = rr.united(item->rect());
       
  4604                 item->moveBy(dx, dy);
       
  4605                 rr = rr.united(item->rect());
       
  4606             }
       
  4607             w = qMax(w, item->x() + item->width() + 1);
       
  4608             h = qMax(h, item->y() + item->height() + 1);
       
  4609         }
       
  4610         repaintContents(rr);
       
  4611         bool fullRepaint = false;
       
  4612         if (w > contentsWidth() ||
       
  4613              h > contentsHeight())
       
  4614             fullRepaint = true;
       
  4615 
       
  4616         int oldw = contentsWidth();
       
  4617         int oldh = contentsHeight();
       
  4618 
       
  4619         resizeContents(w, h);
       
  4620 
       
  4621 
       
  4622         if (fullRepaint) {
       
  4623             repaintContents(oldw, 0, contentsWidth() - oldw, contentsHeight());
       
  4624             repaintContents(0, oldh, contentsWidth(), contentsHeight() - oldh);
       
  4625         }
       
  4626         e->acceptAction();
       
  4627     } else if (!i && (e->source() != viewport() || d->cleared)) {
       
  4628         QLinkedList<Q3IconDragItem> lst;
       
  4629         if (Q3IconDrag::canDecode(e)) {
       
  4630             QLinkedList<Q3IconDragDataItem> l;
       
  4631             Q3IconDragPrivate::decode(e, l);
       
  4632             QLinkedList<Q3IconDragDataItem>::Iterator it = l.begin();
       
  4633             for (; it != l.end(); ++it)
       
  4634                 lst << (*it).data;
       
  4635         }
       
  4636         emit dropped(e, lst);
       
  4637     } else if (i) {
       
  4638         QLinkedList<Q3IconDragItem> lst;
       
  4639         if (Q3IconDrag::canDecode(e)) {
       
  4640             QLinkedList<Q3IconDragDataItem> l;
       
  4641             Q3IconDragPrivate::decode(e, l);
       
  4642             QLinkedList<Q3IconDragDataItem>::Iterator it = l.begin();
       
  4643             for (; it != l.end(); ++it)
       
  4644                 lst << (*it).data;
       
  4645         }
       
  4646         i->dropped(e, lst);
       
  4647     }
       
  4648     d->isIconDrag = false;
       
  4649 }
       
  4650 #endif
       
  4651 
       
  4652 /*!
       
  4653     \reimp
       
  4654 */
       
  4655 
       
  4656 void Q3IconView::resizeEvent(QResizeEvent* e)
       
  4657 {
       
  4658     Q3ScrollView::resizeEvent(e);
       
  4659     if (d->resizeMode == Adjust) {
       
  4660         optimize_layout = true;
       
  4661         adjustItems();
       
  4662         optimize_layout = false;
       
  4663 #if 0 // no need for timer delay anymore
       
  4664         d->oldSize = e->oldSize();
       
  4665         if (d->adjustTimer->isActive())
       
  4666             d->adjustTimer->stop();
       
  4667         d->adjustTimer->start(0, true);
       
  4668 #endif
       
  4669     }
       
  4670 }
       
  4671 
       
  4672 /*!
       
  4673     Adjusts the positions of the items to the geometry of the icon
       
  4674     view.
       
  4675 */
       
  4676 
       
  4677 void Q3IconView::adjustItems()
       
  4678 {
       
  4679     d->adjustTimer->stop();
       
  4680     if (d->resizeMode == Adjust)
       
  4681             arrangeItemsInGrid(true);
       
  4682 }
       
  4683 
       
  4684 /*!
       
  4685     \reimp
       
  4686 */
       
  4687 
       
  4688 void Q3IconView::keyPressEvent(QKeyEvent *e)
       
  4689 {
       
  4690     if (!d->firstItem)
       
  4691         return;
       
  4692 
       
  4693     if (!d->currentItem) {
       
  4694         setCurrentItem(d->firstItem);
       
  4695         if (d->selectionMode == Single)
       
  4696             d->currentItem->setSelected(true, true);
       
  4697         return;
       
  4698     }
       
  4699 
       
  4700     bool selectCurrent = true;
       
  4701 
       
  4702     switch (e->key()) {
       
  4703     case Qt::Key_Escape:
       
  4704         e->ignore();
       
  4705         break;
       
  4706 #ifndef QT_NO_TEXTEDIT
       
  4707     case Qt::Key_F2: {
       
  4708         if (d->currentItem->renameEnabled()) {
       
  4709             d->currentItem->renameItem();
       
  4710             d->currentItem->rename();
       
  4711             return;
       
  4712         }
       
  4713     } break;
       
  4714 #endif
       
  4715     case Qt::Key_Home: {
       
  4716         d->currInputString.clear();
       
  4717         if (!d->firstItem)
       
  4718             break;
       
  4719 
       
  4720         selectCurrent = false;
       
  4721 
       
  4722         Q3IconViewItem *item = 0;
       
  4723         Q3IconViewPrivate::ItemContainer *c = d->firstContainer;
       
  4724         while (!item && c) {
       
  4725             QList<Q3IconViewItem*> &list = c->items;
       
  4726             for (int j = 0; j < list.size(); ++j) {
       
  4727                 Q3IconViewItem *i = list.at(j);
       
  4728                 if (!item) {
       
  4729                     item = i;
       
  4730                 } else {
       
  4731                     if (d->arrangement == LeftToRight) {
       
  4732                         // we use pixmap so the items textlength are ignored
       
  4733                         // find topmost, leftmost item
       
  4734                         if (i->pixmapRect(false).y() < item->pixmapRect(false).y() ||
       
  4735                              (i->pixmapRect(false).y() == item->pixmapRect(false).y() &&
       
  4736                                i->pixmapRect(false).x() < item->pixmapRect(false).x()))
       
  4737                             item = i;
       
  4738                     } else {
       
  4739                         // find leftmost, topmost item
       
  4740                         if (i->pixmapRect(false).x() < item->pixmapRect(false).x() ||
       
  4741                              (i->pixmapRect(false).x() == item->pixmapRect(false).x() &&
       
  4742                                i->pixmapRect(false).y() < item->pixmapRect(false).y()))
       
  4743                             item = i;
       
  4744                     }
       
  4745                 }
       
  4746             }
       
  4747             c = c->n;
       
  4748         }
       
  4749 
       
  4750         if (item) {
       
  4751             Q3IconViewItem *old = d->currentItem;
       
  4752             setCurrentItem(item);
       
  4753             ensureItemVisible(item);
       
  4754             handleItemChange(old, e->state() & Qt::ShiftButton,
       
  4755                               e->state() & Qt::ControlButton, true);
       
  4756         }
       
  4757     } break;
       
  4758     case Qt::Key_End: {
       
  4759         d->currInputString.clear();
       
  4760         if (!d->lastItem)
       
  4761             break;
       
  4762 
       
  4763         selectCurrent = false;
       
  4764 
       
  4765         Q3IconViewItem *item = 0;
       
  4766         Q3IconViewPrivate::ItemContainer *c = d->lastContainer;
       
  4767         while (!item && c) {
       
  4768             QList<Q3IconViewItem*> &list = c->items;
       
  4769             for (int j = 0; j < list.size(); ++j) {
       
  4770                 Q3IconViewItem *i = list.at(j);
       
  4771                 if (!item) {
       
  4772                     item = i;
       
  4773                 } else {
       
  4774                     if (d->arrangement == LeftToRight) {
       
  4775                         // find bottommost, rightmost item
       
  4776                         if (i->pixmapRect(false).bottom() > item->pixmapRect(false).bottom() ||
       
  4777                              (i->pixmapRect(false).bottom() == item->pixmapRect(false).bottom() &&
       
  4778                                i->pixmapRect(false).right() > item->pixmapRect(false).right()))
       
  4779                             item = i;
       
  4780                     } else {
       
  4781                         // find rightmost, bottommost item
       
  4782                         if (i->pixmapRect(false).right() > item->pixmapRect(false).right() ||
       
  4783                              (i->pixmapRect(false).right() == item->pixmapRect(false).right() &&
       
  4784                                i->pixmapRect(false).bottom() > item->pixmapRect(false).bottom()))
       
  4785                             item = i;
       
  4786                     }
       
  4787                 }
       
  4788             }
       
  4789             c = c->p;
       
  4790         }
       
  4791 
       
  4792         if (item) {
       
  4793             Q3IconViewItem *old = d->currentItem;
       
  4794             setCurrentItem(item);
       
  4795             ensureItemVisible(item);
       
  4796             handleItemChange(old, e->state() & Qt::ShiftButton,
       
  4797                               e->state() & Qt::ControlButton, true);
       
  4798         }
       
  4799     } break;
       
  4800     case Qt::Key_Right: {
       
  4801         d->currInputString.clear();
       
  4802         Q3IconViewItem *item;
       
  4803         selectCurrent = false;
       
  4804         Direction dir = DirRight;
       
  4805 
       
  4806         QRect r(0, d->currentItem->y(), contentsWidth(), d->currentItem->height());
       
  4807         item = findItem(dir, d->currentItem->rect().center(), r);
       
  4808 
       
  4809         // search the row below from the right
       
  4810         while (!item && r.y() < contentsHeight()) {
       
  4811             r.moveBy(0, d->currentItem->height());
       
  4812             item = findItem(dir, QPoint(0, r.center().y()), r);
       
  4813         }
       
  4814 
       
  4815         if (item) {
       
  4816             Q3IconViewItem *old = d->currentItem;
       
  4817             setCurrentItem(item);
       
  4818             ensureItemVisible(item);
       
  4819             handleItemChange(old, e->state() & Qt::ShiftButton, e->state() & Qt::ControlButton);
       
  4820         }
       
  4821     } break;
       
  4822     case Qt::Key_Left: {
       
  4823         d->currInputString.clear();
       
  4824         Q3IconViewItem *item;
       
  4825         selectCurrent = false;
       
  4826         Direction dir = DirLeft;
       
  4827 
       
  4828         QRect r(0, d->currentItem->y(), contentsWidth(), d->currentItem->height());
       
  4829         item = findItem(dir, d->currentItem->rect().center(), r);
       
  4830 
       
  4831         // search the row above from the left
       
  4832         while (!item && r.y() >= 0) {
       
  4833             r.moveBy(0, - d->currentItem->height());
       
  4834             item = findItem(dir, QPoint(contentsWidth(), r.center().y()), r);
       
  4835         }
       
  4836 
       
  4837         if (item) {
       
  4838             Q3IconViewItem *old = d->currentItem;
       
  4839             setCurrentItem(item);
       
  4840             ensureItemVisible(item);
       
  4841             handleItemChange(old, e->state() & Qt::ShiftButton, e->state() & Qt::ControlButton);
       
  4842         }
       
  4843     } break;
       
  4844     case Qt::Key_Space: {
       
  4845         d->currInputString.clear();
       
  4846         if (d->selectionMode == Single)
       
  4847             break;
       
  4848 
       
  4849         d->currentItem->setSelected(!d->currentItem->isSelected(), true);
       
  4850     } break;
       
  4851     case Qt::Key_Enter: case Qt::Key_Return:
       
  4852         d->currInputString.clear();
       
  4853         emit returnPressed(d->currentItem);
       
  4854         break;
       
  4855     case Qt::Key_Down: {
       
  4856         d->currInputString.clear();
       
  4857         Q3IconViewItem *item;
       
  4858         selectCurrent = false;
       
  4859         Direction dir = DirDown;
       
  4860 
       
  4861         QRect r(d->currentItem->x(), 0, d->currentItem->width(), contentsHeight());
       
  4862         item = findItem(dir, d->currentItem->rect().center(), r);
       
  4863 
       
  4864         // finding the closest item below and to the right
       
  4865         while (!item && r.x() < contentsWidth()) {
       
  4866             r.moveBy(r.width() , 0);
       
  4867             item = findItem(dir, QPoint(r.center().x(), 0), r);
       
  4868         }
       
  4869 
       
  4870 
       
  4871         Q3IconViewItem *i = d->currentItem;
       
  4872         setCurrentItem(item);
       
  4873         item = i;
       
  4874         handleItemChange(item, e->state() & Qt::ShiftButton, e->state() & Qt::ControlButton);
       
  4875     } break;
       
  4876     case Qt::Key_Up: {
       
  4877         d->currInputString.clear();
       
  4878         Q3IconViewItem *item;
       
  4879         selectCurrent = false;
       
  4880         Direction dir = DirUp;
       
  4881 
       
  4882         QRect r(d->currentItem->x(), 0, d->currentItem->width(), contentsHeight());
       
  4883         item = findItem(dir, d->currentItem->rect().center(), r);
       
  4884 
       
  4885         // finding the closest item above and to the left
       
  4886         while (!item && r.x() >= 0) {
       
  4887             r.moveBy(- r.width(), 0);
       
  4888             item = findItem(dir, QPoint(r.center().x(), contentsHeight()), r);
       
  4889         }
       
  4890 
       
  4891         Q3IconViewItem *i = d->currentItem;
       
  4892         setCurrentItem(item);
       
  4893         item = i;
       
  4894         handleItemChange(item, e->state() & Qt::ShiftButton, e->state() & Qt::ControlButton);
       
  4895     } break;
       
  4896     case Qt::Key_Next: {
       
  4897         d->currInputString.clear();
       
  4898         selectCurrent = false;
       
  4899         QRect r;
       
  4900         if (d->arrangement == LeftToRight)
       
  4901             r = QRect(0, d->currentItem->y() + visibleHeight(), contentsWidth(), visibleHeight());
       
  4902         else
       
  4903             r = QRect(d->currentItem->x() + visibleWidth(), 0, visibleWidth(), contentsHeight());
       
  4904         Q3IconViewItem *item = d->currentItem;
       
  4905         Q3IconViewItem *ni = findFirstVisibleItem(r );
       
  4906         if (!ni) {
       
  4907             if (d->arrangement == LeftToRight)
       
  4908                 r = QRect(0, d->currentItem->y() + d->currentItem->height(), contentsWidth(), contentsHeight());
       
  4909             else
       
  4910                 r = QRect(d->currentItem->x() + d->currentItem->width(), 0, contentsWidth(), contentsHeight());
       
  4911             ni = findLastVisibleItem(r );
       
  4912         }
       
  4913         if (ni) {
       
  4914             setCurrentItem(ni);
       
  4915             handleItemChange(item, e->state() & Qt::ShiftButton, e->state() & Qt::ControlButton);
       
  4916         }
       
  4917     } break;
       
  4918     case Qt::Key_Prior: {
       
  4919         d->currInputString.clear();
       
  4920         selectCurrent = false;
       
  4921         QRect r;
       
  4922         if (d->arrangement == LeftToRight)
       
  4923             r = QRect(0, d->currentItem->y() - visibleHeight(), contentsWidth(), visibleHeight());
       
  4924         else
       
  4925             r = QRect(d->currentItem->x() - visibleWidth(), 0, visibleWidth(), contentsHeight());
       
  4926         Q3IconViewItem *item = d->currentItem;
       
  4927         Q3IconViewItem *ni = findFirstVisibleItem(r );
       
  4928         if (!ni) {
       
  4929             if (d->arrangement == LeftToRight)
       
  4930                 r = QRect(0, 0, contentsWidth(), d->currentItem->y());
       
  4931             else
       
  4932                 r = QRect(0, 0, d->currentItem->x(), contentsHeight());
       
  4933             ni = findFirstVisibleItem(r );
       
  4934         }
       
  4935         if (ni) {
       
  4936             setCurrentItem(ni);
       
  4937             handleItemChange(item, e->state() & Qt::ShiftButton, e->state() & Qt::ControlButton);
       
  4938         }
       
  4939     } break;
       
  4940     default:
       
  4941         if (!e->text().isEmpty() && e->text()[0].isPrint()) {
       
  4942             selectCurrent = false;
       
  4943             Q3IconViewItem *i = d->currentItem;
       
  4944             if (!i)
       
  4945                 i = d->firstItem;
       
  4946             if (!d->inputTimer->isActive()) {
       
  4947                 d->currInputString = e->text();
       
  4948                 i = i->next;
       
  4949                 if (!i)
       
  4950                     i = d->firstItem;
       
  4951                 i = findItemByName(i);
       
  4952             } else {
       
  4953                 d->inputTimer->stop();
       
  4954                 d->currInputString += e->text();
       
  4955                 i = findItemByName(i);
       
  4956                 if (!i) {
       
  4957                     d->currInputString = e->text();
       
  4958                     if (d->currentItem && d->currentItem->next)
       
  4959                         i = d->currentItem->next;
       
  4960                     else
       
  4961                         i = d->firstItem;
       
  4962                     i = findItemByName(i);
       
  4963                 }
       
  4964             }
       
  4965             if (i) {
       
  4966                 setCurrentItem(i);
       
  4967                 if (d->selectionMode == Extended) {
       
  4968                     bool changed = false;
       
  4969                     bool block = signalsBlocked();
       
  4970                     blockSignals(true);
       
  4971                     selectAll(false);
       
  4972                     blockSignals(block);
       
  4973                     if (!i->selected && i->isSelectable()) {
       
  4974                         changed = true;
       
  4975                         i->selected = true;
       
  4976                         repaintItem(i);
       
  4977                     }
       
  4978                     if (changed)
       
  4979                         emit selectionChanged();
       
  4980                 }
       
  4981             }
       
  4982             d->inputTimer->start(400, true);
       
  4983         } else {
       
  4984             selectCurrent = false;
       
  4985             d->currInputString.clear();
       
  4986             if (e->state() & Qt::ControlButton) {
       
  4987                 switch (e->key()) {
       
  4988                 case Qt::Key_A:
       
  4989                     selectAll(true);
       
  4990                     break;
       
  4991                 }
       
  4992             }
       
  4993             e->ignore();
       
  4994             return;
       
  4995         }
       
  4996     }
       
  4997 
       
  4998     if (!(e->state() & Qt::ShiftButton) || !d->selectAnchor)
       
  4999         d->selectAnchor = d->currentItem;
       
  5000 
       
  5001     if (d->currentItem && !d->currentItem->isSelected() &&
       
  5002          d->selectionMode == Single && selectCurrent) {
       
  5003         d->currentItem->setSelected(true);
       
  5004     }
       
  5005 
       
  5006     ensureItemVisible(d->currentItem);
       
  5007 }
       
  5008 
       
  5009 /*
       
  5010   Finds the closest item in the Direction \a dir relative from the point \a relativeTo
       
  5011   which intersects with the searchRect.
       
  5012 
       
  5013   The function chooses the closest item with its center in the \a searchRect.
       
  5014 */
       
  5015 Q3IconViewItem* Q3IconView::findItem(Direction dir,
       
  5016                                     const QPoint &relativeTo,
       
  5017                                     const QRect &searchRect) const
       
  5018 {
       
  5019     Q3IconViewItem *centerMatch = 0;
       
  5020     int centerMatchML = 0;
       
  5021 
       
  5022     // gets list of containers with potential items
       
  5023     QList<Q3IconViewPrivate::ItemContainer * >* cList =
       
  5024         d->findContainers(dir, relativeTo, searchRect);
       
  5025 
       
  5026     for (int i = 0; i < cList->size() && !centerMatch; ++i) {
       
  5027         QList<Q3IconViewItem *> &list = (cList->at(i))->items;
       
  5028         for (int j = 0; j < list.size(); ++j) {
       
  5029             Q3IconViewItem *item = list.at(j);
       
  5030             if (neighbourItem(dir, relativeTo, item) &&
       
  5031                  searchRect.contains(item->rect().center()) && item != currentItem()) {
       
  5032                 int ml = (relativeTo - item->rect().center()).manhattanLength();
       
  5033                 if (centerMatch) {
       
  5034                     if (ml < centerMatchML) {
       
  5035                         centerMatch = item;
       
  5036                         centerMatchML = ml;
       
  5037                     }
       
  5038                 } else {
       
  5039                     centerMatch = item;
       
  5040                     centerMatchML = ml;
       
  5041                 }
       
  5042             }
       
  5043         }
       
  5044     }
       
  5045     return centerMatch;
       
  5046 }
       
  5047 
       
  5048 
       
  5049 /*
       
  5050   Returns true if the items orientation compared to
       
  5051   the point \a relativeTo is correct.
       
  5052 */
       
  5053 bool Q3IconView::neighbourItem(Direction dir,
       
  5054                                const QPoint &relativeTo,
       
  5055                                const Q3IconViewItem *item) const
       
  5056 {
       
  5057     switch (dir) {
       
  5058     case DirUp:
       
  5059         if (item->rect().center().y() < relativeTo.y())
       
  5060             return true;
       
  5061         break;
       
  5062     case DirDown:
       
  5063         if (item->rect().center().y() > relativeTo.y())
       
  5064             return true;
       
  5065         break;
       
  5066     case DirLeft:
       
  5067         if (item->rect().center().x() < relativeTo.x())
       
  5068             return true;
       
  5069         break;
       
  5070     case DirRight:
       
  5071         if (item->rect().center().x() > relativeTo.x())
       
  5072             return true;
       
  5073         break;
       
  5074     default:
       
  5075         // nothing
       
  5076         break;
       
  5077     }
       
  5078     return false;
       
  5079 }
       
  5080 
       
  5081 /*!
       
  5082     \reimp
       
  5083 */
       
  5084 
       
  5085 void Q3IconView::focusInEvent(QFocusEvent *e)
       
  5086 {
       
  5087     d->mousePressed = false;
       
  5088     d->inMenuMode = false;
       
  5089     if (d->currentItem) {
       
  5090         repaintItem(d->currentItem);
       
  5091     } else if (d->firstItem && e->reason() != Qt::MouseFocusReason) {
       
  5092         d->currentItem = d->firstItem;
       
  5093         emit currentChanged(d->currentItem);
       
  5094         repaintItem(d->currentItem);
       
  5095     }
       
  5096 
       
  5097     if (style()->styleHint(QStyle::SH_ItemView_ChangeHighlightOnFocus, 0, this))
       
  5098         repaintSelectedItems();
       
  5099 }
       
  5100 
       
  5101 /*!
       
  5102     \reimp
       
  5103 */
       
  5104 
       
  5105 void Q3IconView::focusOutEvent(QFocusEvent *e)
       
  5106 {
       
  5107     if (style()->styleHint(QStyle::SH_ItemView_ChangeHighlightOnFocus, 0, this)) {
       
  5108         d->inMenuMode =
       
  5109             e->reason() == Qt::PopupFocusReason ||
       
  5110             (qApp->focusWidget() && qApp->focusWidget()->inherits("QMenuBar"));
       
  5111         if (!d->inMenuMode)
       
  5112             repaintSelectedItems();
       
  5113     }
       
  5114     if (d->currentItem)
       
  5115         repaintItem(d->currentItem);
       
  5116 }
       
  5117 
       
  5118 /*!
       
  5119     Draws the rubber band using the painter \a p.
       
  5120 */
       
  5121 
       
  5122 void Q3IconView::drawRubber(QPainter *p)
       
  5123 {
       
  5124     if (!p || !d->rubber)
       
  5125         return;
       
  5126     QStyleOptionRubberBand opt;
       
  5127     opt.rect = d->rubber->normalized();
       
  5128     opt.shape = QRubberBand::Rectangle;
       
  5129     opt.palette = palette();
       
  5130     opt.state = QStyle::State_None;
       
  5131     style()->drawControl(QStyle::CE_RubberBand, &opt, p, this);
       
  5132 }
       
  5133 
       
  5134 /*!
       
  5135     Returns the Q3DragObject that should be used for drag-and-drop.
       
  5136     This function is called by the icon view when starting a drag to
       
  5137     get the dragobject that should be used for the drag. Subclasses
       
  5138     may reimplement this.
       
  5139 
       
  5140     \sa Q3IconDrag
       
  5141 */
       
  5142 
       
  5143 #ifndef QT_NO_DRAGANDDROP
       
  5144 Q3DragObject *Q3IconView::dragObject()
       
  5145 {
       
  5146     if (!d->currentItem)
       
  5147         return 0;
       
  5148 
       
  5149     QPoint orig = d->dragStartPos;
       
  5150 
       
  5151     Q3IconDrag *drag = new Q3IconDrag(viewport());
       
  5152     drag->setPixmap((d->currentItem->pixmap() ?
       
  5153                      *d->currentItem->pixmap() : QPixmap()), // ### QPicture
       
  5154                      QPoint(d->currentItem->pixmapRect().width() / 2,
       
  5155                              d->currentItem->pixmapRect().height() / 2));
       
  5156 
       
  5157     if (d->selectionMode == NoSelection) {
       
  5158         Q3IconViewItem *item = d->currentItem;
       
  5159         drag->append(Q3IconDragItem(),
       
  5160                       QRect(item->pixmapRect(false).x() - orig.x(),
       
  5161                              item->pixmapRect(false).y() - orig.y(),
       
  5162                              item->pixmapRect().width(), item->pixmapRect().height()),
       
  5163                       QRect(item->textRect(false).x() - orig.x(),
       
  5164                              item->textRect(false).y() - orig.y(),
       
  5165                              item->textRect().width(), item->textRect().height()));
       
  5166     } else {
       
  5167         for (Q3IconViewItem *item = d->firstItem; item; item = item->next) {
       
  5168             if (item->isSelected()) {
       
  5169                 drag->append(Q3IconDragItem(),
       
  5170                               QRect(item->pixmapRect(false).x() - orig.x(),
       
  5171                                      item->pixmapRect(false).y() - orig.y(),
       
  5172                                      item->pixmapRect().width(), item->pixmapRect().height()),
       
  5173                               QRect(item->textRect(false).x() - orig.x(),
       
  5174                                      item->textRect(false).y() - orig.y(),
       
  5175                                      item->textRect().width(), item->textRect().height()));
       
  5176             }
       
  5177         }
       
  5178     }
       
  5179 
       
  5180     return drag;
       
  5181 }
       
  5182 
       
  5183 /*!
       
  5184     Starts a drag.
       
  5185 */
       
  5186 
       
  5187 void Q3IconView::startDrag()
       
  5188 {
       
  5189     if (!d->startDragItem)
       
  5190         return;
       
  5191 
       
  5192     QPoint orig = d->dragStartPos;
       
  5193     d->dragStart = QPoint(orig.x() - d->startDragItem->x(),
       
  5194                            orig.y() - d->startDragItem->y());
       
  5195     d->startDragItem = 0;
       
  5196     d->mousePressed = false;
       
  5197     d->pressedItem = 0;
       
  5198     d->pressedSelected = 0;
       
  5199 
       
  5200     Q3DragObject *drag = dragObject();
       
  5201     if (!drag)
       
  5202         return;
       
  5203 
       
  5204     if (drag->drag())
       
  5205         if (drag->target() != viewport())
       
  5206             emit moved();
       
  5207 }
       
  5208 
       
  5209 #endif
       
  5210 
       
  5211 /*!
       
  5212     Inserts the Q3IconViewItem \a item in the icon view's grid. \e{You
       
  5213     should never need to call this function.} Instead, insert
       
  5214     Q3IconViewItems by creating them with a pointer to the Q3IconView
       
  5215     that they are to be inserted into.
       
  5216 */
       
  5217 
       
  5218 void Q3IconView::insertInGrid(Q3IconViewItem *item)
       
  5219 {
       
  5220     if (!item)
       
  5221         return;
       
  5222 
       
  5223     if (d->reorderItemsWhenInsert) {
       
  5224         // #### make this efficient - but it's not too dramatic
       
  5225         int y = d->spacing;
       
  5226 
       
  5227         item->dirty = false;
       
  5228         if (item == d->firstItem) {
       
  5229             bool dummy;
       
  5230             makeRowLayout(item, y, dummy);
       
  5231             return;
       
  5232         }
       
  5233 
       
  5234         Q3IconViewItem *begin = rowBegin(item);
       
  5235         y = begin->y();
       
  5236         while (begin) {
       
  5237             bool dummy;
       
  5238             begin = makeRowLayout(begin, y, dummy);
       
  5239 
       
  5240             if (!begin || !begin->next)
       
  5241                 break;
       
  5242 
       
  5243             begin = begin->next;
       
  5244         }
       
  5245         item->dirty = false;
       
  5246     } else {
       
  5247         QRegion r(QRect(0, 0, qMax(contentsWidth(), visibleWidth()),
       
  5248                           qMax(contentsHeight(), visibleHeight())));
       
  5249 
       
  5250         int y = -1;
       
  5251         for (Q3IconViewItem *i = d->firstItem; i; i = i->next) {
       
  5252             r = r.subtracted(i->rect());
       
  5253             y = qMax(y, i->y() + i->height());
       
  5254         }
       
  5255 
       
  5256         QVector<QRect> rects = r.rects();
       
  5257         bool foundPlace = false;
       
  5258         for (int j = 0; j < rects.size(); ++j) {
       
  5259             const QRect rect = rects.at(j);
       
  5260             if (rect.width() >= item->width() &&
       
  5261                  rect.height() >= item->height()) {
       
  5262                 int sx = 0, sy = 0;
       
  5263                 if (rect.width() >= item->width() + d->spacing)
       
  5264                     sx = d->spacing;
       
  5265                 if (rect.height() >= item->height() + d->spacing)
       
  5266                     sy = d->spacing;
       
  5267                 item->move(rect.x() + sx, rect.y() + sy);
       
  5268                 foundPlace = true;
       
  5269                 break;
       
  5270             }
       
  5271         }
       
  5272 
       
  5273         if (!foundPlace)
       
  5274             item->move(d->spacing, y + d->spacing);
       
  5275 
       
  5276         resizeContents(qMax(contentsWidth(), item->x() + item->width()),
       
  5277                         qMax(contentsHeight(), item->y() + item->height()));
       
  5278         item->dirty = false;
       
  5279     }
       
  5280 }
       
  5281 
       
  5282 /*!
       
  5283     Emits a signal to indicate selection changes. \a i is the
       
  5284     Q3IconViewItem that was selected or de-selected.
       
  5285 
       
  5286     \e{You should never need to call this function.}
       
  5287 */
       
  5288 
       
  5289 void Q3IconView::emitSelectionChanged(Q3IconViewItem *i)
       
  5290 {
       
  5291     emit selectionChanged();
       
  5292     if (d->selectionMode == Single)
       
  5293         emit selectionChanged(i ? i : d->currentItem);
       
  5294 }
       
  5295 
       
  5296 /*!
       
  5297     \internal
       
  5298 */
       
  5299 
       
  5300 void Q3IconView::emitRenamed(Q3IconViewItem *item)
       
  5301 {
       
  5302     if (!item)
       
  5303         return;
       
  5304 
       
  5305     emit itemRenamed(item, item->text());
       
  5306     emit itemRenamed(item);
       
  5307 }
       
  5308 
       
  5309 /*!
       
  5310     If a drag enters the icon view the shapes of the objects which the
       
  5311     drag contains are drawn, usnig \a pos as origin.
       
  5312 */
       
  5313 
       
  5314 void Q3IconView::drawDragShapes(const QPoint &pos)
       
  5315 {
       
  5316 #ifndef QT_NO_DRAGANDDROP
       
  5317     if (pos == QPoint(-1, -1))
       
  5318         return;
       
  5319 
       
  5320     if (!d->drawDragShapes) {
       
  5321         d->drawDragShapes = true;
       
  5322         return;
       
  5323     }
       
  5324 
       
  5325     d->dragPos = pos;
       
  5326     viewport()->update();
       
  5327 #endif
       
  5328 }
       
  5329 
       
  5330 /*!
       
  5331     When a drag enters the icon view, this function is called to
       
  5332     initialize it. Initializing in this context means getting
       
  5333     information about the drag, for example so that the icon view
       
  5334     knows enough about the drag to be able to draw drag shapes for the
       
  5335     drag data (e.g. shapes of icons which are dragged), etc.
       
  5336 */
       
  5337 
       
  5338 #ifndef QT_NO_DRAGANDDROP
       
  5339 void Q3IconView::initDragEnter(QDropEvent *e)
       
  5340 {
       
  5341     if (Q3IconDrag::canDecode(e)) {
       
  5342         Q3IconDragPrivate::decode(e, d->iconDragData);
       
  5343         d->isIconDrag = true;
       
  5344     } else if (Q3UriDrag::canDecode(e)) {
       
  5345         Q3StrList lst;
       
  5346         Q3UriDrag::decode(e, lst);
       
  5347         d->numDragItems = lst.count();
       
  5348     } else {
       
  5349         d->numDragItems = 0;
       
  5350     }
       
  5351 
       
  5352 }
       
  5353 #endif
       
  5354 
       
  5355 /*!
       
  5356     This function is called to draw the rectangle \a r of the
       
  5357     background using the painter \a p.
       
  5358 
       
  5359     The default implementation fills \a r with the viewport's
       
  5360     backgroundBrush(). Subclasses can reimplement this to draw custom
       
  5361     backgrounds.
       
  5362 
       
  5363     \sa drawContents()
       
  5364 */
       
  5365 
       
  5366 void Q3IconView::drawBackground(QPainter *p, const QRect &r)
       
  5367 {
       
  5368     p->fillRect(r, viewport()->backgroundBrush());
       
  5369 }
       
  5370 
       
  5371 /*!
       
  5372     \reimp
       
  5373 */
       
  5374 
       
  5375 bool Q3IconView::eventFilter(QObject * o, QEvent * e)
       
  5376 {
       
  5377     if (o == viewport()) {
       
  5378         switch(e->type()) {
       
  5379         case QEvent::FocusIn:
       
  5380             focusInEvent((QFocusEvent*)e);
       
  5381             return true;
       
  5382         case QEvent::FocusOut:
       
  5383             focusOutEvent((QFocusEvent*)e);
       
  5384             return true;
       
  5385         case QEvent::Enter:
       
  5386             enterEvent(e);
       
  5387             return true;
       
  5388         case QEvent::Paint:
       
  5389             if (o == viewport()) {
       
  5390                 viewportPaintEvent((QPaintEvent*)e);
       
  5391                 QPainter p(viewport());
       
  5392                 if (d->dragging) {
       
  5393                     if (!d->rubber && d->drawDragShapes) {
       
  5394                         p.setPen(QPen(Qt::color0));
       
  5395                         QStyleOptionFocusRect opt;
       
  5396                         opt.palette = palette();
       
  5397                         opt.state = QStyle::State_KeyboardFocusChange;
       
  5398                         opt.backgroundColor = palette().base().color();
       
  5399                         if (d->isIconDrag) {
       
  5400                             d->dragPos = contentsToViewport(d->dragPos);
       
  5401                             QLinkedList<Q3IconDragDataItem>::Iterator it = d->iconDragData.begin();
       
  5402                             for (; it != d->iconDragData.end(); ++it) {
       
  5403                                 QRect ir = (*it).item.pixmapRect();
       
  5404                                 QRect tr = (*it).item.textRect();
       
  5405                                 tr.moveBy(d->dragPos.x(), d->dragPos.y());
       
  5406                                 ir.moveBy(d->dragPos.x(), d->dragPos.y());
       
  5407                                 if (!ir.intersects(QRect(0, 0, visibleWidth(), visibleHeight())))
       
  5408                                     continue;
       
  5409                                 opt.rect = ir;
       
  5410                                 style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, &p, this);
       
  5411                                 opt.rect = tr;
       
  5412                                 p.drawRect(tr);
       
  5413                                 style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, &p, this);
       
  5414                             }
       
  5415                         } else if (d->numDragItems > 0) {
       
  5416                             for (int i = 0; i < d->numDragItems; ++i) {
       
  5417                                 opt.rect.setRect(d->dragPos.x() + i * 40, d->dragPos.y(), 35, 35);
       
  5418                                 style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, &p, this);
       
  5419                             }
       
  5420 
       
  5421                         }
       
  5422                         p.end();
       
  5423                     }
       
  5424                 } else {
       
  5425                     p.translate(-contentsX(), -contentsY());
       
  5426                     drawRubber(&p);
       
  5427                 }
       
  5428             }
       
  5429             return true;
       
  5430 #ifndef QT_NO_TOOLTIP
       
  5431         case QHelpEvent::ToolTip:
       
  5432         {
       
  5433             if (wordWrapIconText() || !showToolTips())
       
  5434                 return false;
       
  5435 
       
  5436             QHelpEvent *he = static_cast<QHelpEvent *>(e);
       
  5437             Q3IconViewItem *item = findItem(viewportToContents(he->pos()));
       
  5438             if (!item || item->tmpText == item->itemText) {
       
  5439                 QToolTip::showText(he->globalPos(), QString(), viewport());
       
  5440                 return true;
       
  5441             }
       
  5442 
       
  5443             QToolTip::showText(he->globalPos(), item->itemText, viewport());
       
  5444             return true;
       
  5445         }
       
  5446 #endif
       
  5447         default:
       
  5448             // nothing
       
  5449             break;
       
  5450         }
       
  5451     }
       
  5452 
       
  5453     return Q3ScrollView::eventFilter(o, e);
       
  5454 }
       
  5455 
       
  5456 
       
  5457 /*!
       
  5458     \reimp
       
  5459 */
       
  5460 
       
  5461 QSize Q3IconView::minimumSizeHint() const
       
  5462 {
       
  5463     return Q3ScrollView::minimumSizeHint();
       
  5464 }
       
  5465 
       
  5466 /*!
       
  5467   \internal
       
  5468   Finds the next item after the start item beginning
       
  5469   with \a text.
       
  5470 */
       
  5471 
       
  5472 Q3IconViewItem* Q3IconView::findItemByName(Q3IconViewItem *start)
       
  5473 {
       
  5474     if (!start)
       
  5475         return 0;
       
  5476     QString match = d->currInputString.toLower();
       
  5477     if (match.length() < 1)
       
  5478         return start;
       
  5479     QString curText;
       
  5480     Q3IconViewItem *i = start;
       
  5481     do {
       
  5482         curText = i->text().toLower();
       
  5483         if (curText.startsWith(match))
       
  5484             return i;
       
  5485         i = i->next;
       
  5486         if (!i)
       
  5487             i = d->firstItem;
       
  5488     } while (i != start);
       
  5489     return 0;
       
  5490 }
       
  5491 
       
  5492 /*!
       
  5493     Lays out a row of icons (if Arrangement == \l TopToBottom this is
       
  5494     a column). Starts laying out with the item \a begin. \a y is the
       
  5495     starting coordinate. Returns the last item of the row (column) and
       
  5496     sets the new starting coordinate to \a y. The \a changed parameter
       
  5497     is used internally.
       
  5498 
       
  5499     \warning This function may be made private in a future version of
       
  5500     Qt. We do not recommend calling it.
       
  5501 */
       
  5502 
       
  5503 Q3IconViewItem *Q3IconView::makeRowLayout(Q3IconViewItem *begin, int &y, bool &changed)
       
  5504 {
       
  5505     Q3IconViewItem *end = 0;
       
  5506 
       
  5507     bool reverse = QApplication::reverseLayout();
       
  5508     changed = false;
       
  5509 
       
  5510     if (d->arrangement == LeftToRight) {
       
  5511 
       
  5512         if (d->rastX == -1) {
       
  5513             // first calculate the row height
       
  5514             int h = 0;
       
  5515             int x = 0;
       
  5516             int ih = 0;
       
  5517             Q3IconViewItem *item = begin;
       
  5518             for (;;) {
       
  5519                 x += d->spacing + item->width();
       
  5520                 if (x > visibleWidth() && item != begin) {
       
  5521                     item = item->prev;
       
  5522                     break;
       
  5523                 }
       
  5524                 h = qMax(h, item->height());
       
  5525                 ih = qMax(ih, item->pixmapRect().height());
       
  5526                 Q3IconViewItem *old = item;
       
  5527                 item = item->next;
       
  5528                 if (!item) {
       
  5529                     item = old;
       
  5530                     break;
       
  5531                 }
       
  5532             }
       
  5533             end = item;
       
  5534 
       
  5535             if (d->rastY != -1)
       
  5536                 h = qMax(h, d->rastY);
       
  5537 
       
  5538             // now move the items
       
  5539             item = begin;
       
  5540             for (;;) {
       
  5541                 item->dirty = false;
       
  5542                 int x;
       
  5543                 if (item == begin) {
       
  5544                     if (reverse)
       
  5545                         x = visibleWidth() - d->spacing - item->width();
       
  5546                     else
       
  5547                         x = d->spacing;
       
  5548                 } else {
       
  5549                     if (reverse)
       
  5550                         x = item->prev->x() - item->width() - d->spacing;
       
  5551                     else
       
  5552                         x = item->prev->x() + item->prev->width() + d->spacing;
       
  5553                 }
       
  5554                 changed = item->move(x, y + ih - item->pixmapRect().height()) || changed;
       
  5555                 if (y + h < item->y() + item->height())
       
  5556                     h = qMax(h, ih + item->textRect().height());
       
  5557                 if (item == end)
       
  5558                     break;
       
  5559                 item = item->next;
       
  5560             }
       
  5561             y += h + d->spacing;
       
  5562         } else {
       
  5563             // first calculate the row height
       
  5564             int h = begin->height();
       
  5565             int x = d->spacing;
       
  5566             int ih = begin->pixmapRect().height();
       
  5567             Q3IconViewItem *item = begin;
       
  5568             int i = 0;
       
  5569             int sp = 0;
       
  5570             for (;;) {
       
  5571                 int r = calcGridNum(item->width(), d->rastX);
       
  5572                 if (item == begin) {
       
  5573                     i += r;
       
  5574                     sp += r;
       
  5575                     x = d->spacing + d->rastX * r;
       
  5576                 } else {
       
  5577                     sp += r;
       
  5578                     i += r;
       
  5579                     x = i * d->rastX + sp * d->spacing;
       
  5580                 }
       
  5581                 if (x > visibleWidth() && item != begin) {
       
  5582                     item = item->prev;
       
  5583                     break;
       
  5584                 }
       
  5585                 h = qMax(h, item->height());
       
  5586                 ih = qMax(ih, item->pixmapRect().height());
       
  5587                 Q3IconViewItem *old = item;
       
  5588                 item = item->next;
       
  5589                 if (!item) {
       
  5590                     item = old;
       
  5591                     break;
       
  5592                 }
       
  5593             }
       
  5594             end = item;
       
  5595 
       
  5596             if (d->rastY != -1)
       
  5597                 h = qMax(h, d->rastY);
       
  5598 
       
  5599             // now move the items
       
  5600             item = begin;
       
  5601             i = 0;
       
  5602             sp = 0;
       
  5603             for (;;) {
       
  5604                 item->dirty = false;
       
  5605                 int r = calcGridNum(item->width(), d->rastX);
       
  5606                 if (item == begin) {
       
  5607                     if (d->itemTextPos == Bottom)
       
  5608                         changed = item->move(d->spacing + (r * d->rastX - item->width()) / 2,
       
  5609                                               y + ih - item->pixmapRect().height()) || changed;
       
  5610                     else
       
  5611                         changed = item->move(d->spacing, y + ih - item->pixmapRect().height()) || changed;
       
  5612                     i += r;
       
  5613                     sp += r;
       
  5614                 } else {
       
  5615                     sp += r;
       
  5616                     int x = i * d->rastX + sp * d->spacing;
       
  5617                     if (d->itemTextPos == Bottom)
       
  5618                         changed = item->move(x + (r * d->rastX - item->width()) / 2,
       
  5619                                               y + ih - item->pixmapRect().height()) || changed;
       
  5620                     else
       
  5621                         changed = item->move(x, y + ih - item->pixmapRect().height()) || changed;
       
  5622                     i += r;
       
  5623                 }
       
  5624                 if (y + h < item->y() + item->height())
       
  5625                     h = qMax(h, ih + item->textRect().height());
       
  5626                 if (item == end)
       
  5627                     break;
       
  5628                 item = item->next;
       
  5629             }
       
  5630             y += h + d->spacing;
       
  5631         }
       
  5632 
       
  5633 
       
  5634     } else { // -------------------------------- SOUTH ------------------------------
       
  5635 
       
  5636         int x = y;
       
  5637 
       
  5638         {
       
  5639             int w = 0;
       
  5640             int y = 0;
       
  5641             Q3IconViewItem *item = begin;
       
  5642             for (;;) {
       
  5643                 y += d->spacing + item->height();
       
  5644                 if (y > visibleHeight() && item != begin) {
       
  5645                     item = item->prev;
       
  5646                     break;
       
  5647                 }
       
  5648                 w = qMax(w, item->width());
       
  5649                 Q3IconViewItem *old = item;
       
  5650                 item = item->next;
       
  5651                 if (!item) {
       
  5652                     item = old;
       
  5653                     break;
       
  5654                 }
       
  5655             }
       
  5656             end = item;
       
  5657 
       
  5658             if (d->rastX != -1)
       
  5659                 w = qMax(w, d->rastX);
       
  5660 
       
  5661             // now move the items
       
  5662             item = begin;
       
  5663             for (;;) {
       
  5664                 item->dirty = false;
       
  5665                 if (d->itemTextPos == Bottom) {
       
  5666                     if (item == begin)
       
  5667                         changed = item->move(x + (w - item->width()) / 2, d->spacing)  || changed;
       
  5668                     else
       
  5669                         changed = item->move(x + (w - item->width()) / 2,
       
  5670                                               item->prev->y() + item->prev->height() + d->spacing) || changed;
       
  5671                 } else {
       
  5672                     if (item == begin)
       
  5673                         changed = item->move(x, d->spacing) || changed;
       
  5674                     else
       
  5675                         changed = item->move(x, item->prev->y() + item->prev->height() + d->spacing) || changed;
       
  5676                 }
       
  5677                 if (item == end)
       
  5678                     break;
       
  5679                 item = item->next;
       
  5680             }
       
  5681             x += w + d->spacing;
       
  5682         }
       
  5683 
       
  5684         y = x;
       
  5685     }
       
  5686 
       
  5687     return end;
       
  5688 }
       
  5689 
       
  5690 /*!
       
  5691   \internal
       
  5692   Calculates how many cells an item of width \a w needs in a grid with of
       
  5693   \a x and returns the result.
       
  5694 */
       
  5695 
       
  5696 int Q3IconView::calcGridNum(int w, int x) const
       
  5697 {
       
  5698     float r = (float)w / (float)x;
       
  5699     if ((w / x) * x != w)
       
  5700         r += 1.0;
       
  5701     return (int)r;
       
  5702 }
       
  5703 
       
  5704 /*!
       
  5705   \internal
       
  5706   Returns the first item of the row which contains \a item.
       
  5707 */
       
  5708 
       
  5709 Q3IconViewItem *Q3IconView::rowBegin(Q3IconViewItem *) const
       
  5710 {
       
  5711     // #### todo
       
  5712     return d->firstItem;
       
  5713 }
       
  5714 
       
  5715 /*!
       
  5716     Sorts and rearranges all the items in the icon view. If \a
       
  5717     ascending is true, the items are sorted in increasing order,
       
  5718     otherwise they are sorted in decreasing order.
       
  5719 
       
  5720     Q3IconViewItem::compare() is used to compare pairs of items. The
       
  5721     sorting is based on the items' keys; these default to the items'
       
  5722     text unless specifically set to something else.
       
  5723 
       
  5724     Note that this function sets the sort order to \a ascending.
       
  5725 
       
  5726     \sa Q3IconViewItem::key(), Q3IconViewItem::setKey(),
       
  5727     Q3IconViewItem::compare(), Q3IconView::setSorting(),
       
  5728     Q3IconView::sortDirection()
       
  5729 */
       
  5730 
       
  5731 void Q3IconView::sort(bool ascending)
       
  5732 {
       
  5733     if (count() == 0)
       
  5734         return;
       
  5735 
       
  5736     d->sortDirection = ascending;
       
  5737     Q3IconViewPrivate::SortableItem *items = new Q3IconViewPrivate::SortableItem[count()];
       
  5738 
       
  5739     Q3IconViewItem *item = d->firstItem;
       
  5740     int i = 0;
       
  5741     for (; item; item = item->next)
       
  5742         items[i++].item = item;
       
  5743 
       
  5744     qsort(items, count(), sizeof(Q3IconViewPrivate::SortableItem), cmpIconViewItems);
       
  5745 
       
  5746     Q3IconViewItem *prev = 0;
       
  5747     item = 0;
       
  5748     if (ascending) {
       
  5749         for (i = 0; i < (int)count(); ++i) {
       
  5750             item = items[i].item;
       
  5751             if (item) {
       
  5752                 item->prev = prev;
       
  5753                 if (item->prev)
       
  5754                     item->prev->next = item;
       
  5755                 item->next = 0;
       
  5756             }
       
  5757             if (i == 0)
       
  5758                 d->firstItem = item;
       
  5759             if (i == (int)count() - 1)
       
  5760                 d->lastItem = item;
       
  5761             prev = item;
       
  5762         }
       
  5763     } else {
       
  5764         for (i = (int)count() - 1; i >= 0 ; --i) {
       
  5765             item = items[i].item;
       
  5766             if (item) {
       
  5767                 item->prev = prev;
       
  5768                 if (item->prev)
       
  5769                     item->prev->next = item;
       
  5770                 item->next = 0;
       
  5771             }
       
  5772             if (i == (int)count() - 1)
       
  5773                 d->firstItem = item;
       
  5774             if (i == 0)
       
  5775                 d->lastItem = item;
       
  5776             prev = item;
       
  5777         }
       
  5778     }
       
  5779 
       
  5780     delete [] items;
       
  5781 
       
  5782     arrangeItemsInGrid(true);
       
  5783 }
       
  5784 
       
  5785 /*!
       
  5786     \reimp
       
  5787 */
       
  5788 
       
  5789 QSize Q3IconView::sizeHint() const
       
  5790 {
       
  5791     ensurePolished();
       
  5792 
       
  5793     if (!d->firstItem)
       
  5794         return Q3ScrollView::sizeHint();
       
  5795 
       
  5796     if (d->dirty && d->firstSizeHint) {
       
  5797         ((Q3IconView*)this)->resizeContents(qMax(400, contentsWidth()),
       
  5798                                               qMax(400, contentsHeight()));
       
  5799         if (autoArrange())
       
  5800             ((Q3IconView*)this)->arrangeItemsInGrid(false);
       
  5801         d->firstSizeHint = false;
       
  5802     }
       
  5803 
       
  5804     d->dirty = true;
       
  5805     const QScrollBar *sb = verticalScrollBar();
       
  5806     QStyleOptionSlider opt;
       
  5807     opt.init(sb);
       
  5808     opt.orientation = sb->orientation();
       
  5809     int extra = style()->pixelMetric(QStyle::PM_ScrollBarExtent, &opt, sb) + 2 * frameWidth();
       
  5810     QSize s(qMin(400, contentsWidth() + extra),
       
  5811              qMin(400, contentsHeight() + extra));
       
  5812     return s;
       
  5813 }
       
  5814 
       
  5815 /*!
       
  5816   \internal
       
  5817 */
       
  5818 
       
  5819 void Q3IconView::updateContents()
       
  5820 {
       
  5821     viewport()->update();
       
  5822 }
       
  5823 
       
  5824 /*!
       
  5825     \reimp
       
  5826 */
       
  5827 
       
  5828 void Q3IconView::enterEvent(QEvent *e)
       
  5829 {
       
  5830     Q3ScrollView::enterEvent(e);
       
  5831     emit onViewport();
       
  5832 }
       
  5833 
       
  5834 /*!
       
  5835   \internal
       
  5836   This function is always called when the geometry of an item changes.
       
  5837   This function moves the item into the correct area in the internal
       
  5838   data structure.
       
  5839 */
       
  5840 
       
  5841 void Q3IconView::updateItemContainer(Q3IconViewItem *item)
       
  5842 {
       
  5843     if (!item || d->containerUpdateLocked || (!isVisible() && autoArrange()))
       
  5844         return;
       
  5845 
       
  5846     if (item->d->container1 && d->firstContainer) {
       
  5847         //Special-case to check if we can use removeLast otherwise use removeAll (slower)
       
  5848         if (item->d->container1->items.last() == item)
       
  5849             item->d->container1->items.removeLast();
       
  5850         else
       
  5851             item->d->container1->items.removeAll(item);
       
  5852     }
       
  5853     item->d->container1 = 0;
       
  5854     if (item->d->container2 && d->firstContainer) {
       
  5855         //Special-case to check if we can use removeLast otherwise use removeAll (slower)
       
  5856         if (item->d->container2->items.last() == item)
       
  5857             item->d->container2->items.removeLast();
       
  5858         else
       
  5859             item->d->container2->items.removeAll(item);
       
  5860     }
       
  5861     item->d->container2 = 0;
       
  5862 
       
  5863     Q3IconViewPrivate::ItemContainer *c = d->firstContainer;
       
  5864     if (!c) {
       
  5865         appendItemContainer();
       
  5866         c = d->firstContainer;
       
  5867     }
       
  5868 
       
  5869     const QRect irect = item->rect();
       
  5870     bool contains = false;
       
  5871     for (;;) {
       
  5872         if (c->rect.intersects(irect)) {
       
  5873             contains = c->rect.contains(irect);
       
  5874             break;
       
  5875         }
       
  5876 
       
  5877         c = c->n;
       
  5878         if (!c) {
       
  5879             appendItemContainer();
       
  5880             c = d->lastContainer;
       
  5881         }
       
  5882     }
       
  5883 
       
  5884     if (!c) {
       
  5885         qWarning("Q3IconViewItem::updateItemContainer(): No fitting container found!");
       
  5886         return;
       
  5887     }
       
  5888 
       
  5889     c->items.append(item);
       
  5890     item->d->container1 = c;
       
  5891 
       
  5892     if (!contains) {
       
  5893         c = c->n;
       
  5894         if (!c) {
       
  5895             appendItemContainer();
       
  5896             c = d->lastContainer;
       
  5897         }
       
  5898         c->items.append(item);
       
  5899         item->d->container2 = c;
       
  5900     }
       
  5901     if (contentsWidth() < irect.right() || contentsHeight() < irect.bottom())
       
  5902         resizeContents(qMax(contentsWidth(), irect.right()), qMax(contentsHeight(), irect.bottom()));
       
  5903 }
       
  5904 
       
  5905 /*!
       
  5906   \internal
       
  5907   Appends a new rect area to the internal data structure of the items.
       
  5908 */
       
  5909 
       
  5910 void Q3IconView::appendItemContainer()
       
  5911 {
       
  5912     QSize s;
       
  5913     // #### We have to find out which value is best here
       
  5914     if (d->arrangement == LeftToRight)
       
  5915         s = QSize(INT_MAX - 1, RECT_EXTENSION);
       
  5916     else
       
  5917         s = QSize(RECT_EXTENSION, INT_MAX - 1);
       
  5918 
       
  5919     if (!d->firstContainer) {
       
  5920         d->firstContainer = new Q3IconViewPrivate::ItemContainer(0, 0, QRect(QPoint(0, 0), s));
       
  5921         d->lastContainer = d->firstContainer;
       
  5922     } else {
       
  5923         if (d->arrangement == LeftToRight)
       
  5924             d->lastContainer = new Q3IconViewPrivate::ItemContainer(
       
  5925                 d->lastContainer, 0, QRect(d->lastContainer->rect.bottomLeft(), s));
       
  5926         else
       
  5927             d->lastContainer = new Q3IconViewPrivate::ItemContainer(
       
  5928                 d->lastContainer, 0, QRect(d->lastContainer->rect.topRight(), s));
       
  5929     }
       
  5930 }
       
  5931 
       
  5932 /*!  \internal
       
  5933 
       
  5934   Rebuilds the whole internal data structure. This is done when it's
       
  5935   likely that most/all items change their geometry (e.g. in
       
  5936   arrangeItemsInGrid()), because calling this is then more efficient
       
  5937   than calling updateItemContainer() for each item.
       
  5938 */
       
  5939 
       
  5940 void Q3IconView::rebuildContainers()
       
  5941 {
       
  5942     Q3IconViewPrivate::ItemContainer *c = d->firstContainer, *tmpc;
       
  5943     while (c) {
       
  5944         tmpc = c->n;
       
  5945         delete c;
       
  5946         c = tmpc;
       
  5947     }
       
  5948     d->firstContainer = d->lastContainer = 0;
       
  5949 
       
  5950     Q3IconViewItem *item = d->firstItem;
       
  5951     appendItemContainer();
       
  5952     c = d->lastContainer;
       
  5953     while (item) {
       
  5954         if (c->rect.contains(item->rect())) {
       
  5955             item->d->container1 = c;
       
  5956             item->d->container2 = 0;
       
  5957             c->items.append(item);
       
  5958             item = item->next;
       
  5959         } else if (c->rect.intersects(item->rect())) {
       
  5960             item->d->container1 = c;
       
  5961             c->items.append(item);
       
  5962             c = c->n;
       
  5963             if (!c) {
       
  5964                 appendItemContainer();
       
  5965                 c = d->lastContainer;
       
  5966             }
       
  5967             c->items.append(item);
       
  5968             item->d->container2 = c;
       
  5969             item = item->next;
       
  5970             c = c->p;
       
  5971         } else {
       
  5972             if (d->arrangement == LeftToRight) {
       
  5973                 if (item->y() < c->rect.y() && c->p) {
       
  5974                     c = c->p;
       
  5975                     continue;
       
  5976                 }
       
  5977             } else {
       
  5978                 if (item->x() < c->rect.x() && c->p) {
       
  5979                     c = c->p;
       
  5980                     continue;
       
  5981                 }
       
  5982             }
       
  5983 
       
  5984             c = c->n;
       
  5985             if (!c) {
       
  5986                 appendItemContainer();
       
  5987                 c = d->lastContainer;
       
  5988             }
       
  5989         }
       
  5990     }
       
  5991 }
       
  5992 
       
  5993 /*!
       
  5994   \internal
       
  5995 */
       
  5996 
       
  5997 void Q3IconView::movedContents(int, int)
       
  5998 {
       
  5999     if (d->drawDragShapes) {
       
  6000         drawDragShapes(d->oldDragPos);
       
  6001         d->oldDragPos = QPoint(-1, -1);
       
  6002     }
       
  6003 }
       
  6004 
       
  6005 void Q3IconView::handleItemChange(Q3IconViewItem *old, bool shift,
       
  6006                                   bool control, bool homeend)
       
  6007 {
       
  6008     if (d->selectionMode == Single) {
       
  6009         bool block = signalsBlocked();
       
  6010         blockSignals(true);
       
  6011         if (old)
       
  6012             old->setSelected(false);
       
  6013         blockSignals(block);
       
  6014         d->currentItem->setSelected(true, true);
       
  6015     } else if (d->selectionMode == Extended) {
       
  6016          if (shift) {
       
  6017             if (!d->selectAnchor) {
       
  6018                 if (old && !old->selected && old->isSelectable()) {
       
  6019                     old->selected = true;
       
  6020                     repaintItem(old);
       
  6021                 }
       
  6022                 d->currentItem->setSelected(true, true);
       
  6023             } else {
       
  6024                 Q3IconViewItem *from = d->selectAnchor, *to = d->currentItem;
       
  6025                 if (!from || !to)
       
  6026                     return;
       
  6027 
       
  6028                 // checking if it's downwards and if we span rows
       
  6029                 bool downwards = false;
       
  6030                 bool spanning = false;
       
  6031                 if (d->arrangement == LeftToRight) {
       
  6032                     if (from->rect().center().y() < to->rect().center().y())
       
  6033                         downwards = true;
       
  6034                 } else {
       
  6035                     if (from->rect().center().x() < to->rect().center().x())
       
  6036                         downwards = true;
       
  6037                 }
       
  6038 
       
  6039                 QRect fr = from->rect();
       
  6040                 QRect tr = to->rect();
       
  6041                 if (d->arrangement == LeftToRight) {
       
  6042                     fr.moveTopLeft(QPoint(tr.x(), fr.y()));
       
  6043                     if (!tr.intersects(fr))
       
  6044                         spanning = true;
       
  6045                 } else {
       
  6046                     fr.moveTopLeft(QPoint(fr.x(), tr.y()));
       
  6047                     if (!tr.intersects(fr))
       
  6048                         spanning = true;
       
  6049                 }
       
  6050 
       
  6051 
       
  6052                 // finding the rectangles
       
  6053                 QRect topRect, bottomRect, midRect;
       
  6054                 if (!spanning) {
       
  6055                     midRect = from->rect().united(to->rect());
       
  6056                 } else {
       
  6057                     if (downwards) {
       
  6058                         topRect = from->rect();
       
  6059                         bottomRect = to->rect();
       
  6060                     } else {
       
  6061                         topRect = to->rect();
       
  6062                         bottomRect = from->rect();
       
  6063                     }
       
  6064                     if (d->arrangement == LeftToRight) {
       
  6065                         topRect.setRight(contentsWidth());
       
  6066                         bottomRect.setLeft(0);
       
  6067                         midRect.setRect(0, topRect.bottom(),
       
  6068                                          contentsWidth(),
       
  6069                                          bottomRect.top() - topRect.bottom());
       
  6070                     } else {
       
  6071                         topRect.setBottom(contentsHeight());
       
  6072                         bottomRect.setTop(0);
       
  6073                         midRect.setRect(topRect.right(),
       
  6074                                          0,
       
  6075                                          bottomRect.left() - topRect.right(),
       
  6076                                          contentsHeight());
       
  6077                     }
       
  6078                 }
       
  6079 
       
  6080                 // finding contained items and selecting them
       
  6081                 Q3IconViewItem *item = 0;
       
  6082                 bool changed = false;
       
  6083                 bool midValid = midRect.isValid();
       
  6084                 bool topValid = topRect.isValid();
       
  6085                 bool bottomValid = bottomRect.isValid();
       
  6086                 QRect selectedRect, unselectedRect;
       
  6087                 for (item = d->firstItem; item; item = item->next) {
       
  6088                     bool contained = false;
       
  6089                     QPoint itemCenter = item->rect().center();
       
  6090                     if (midValid && midRect.contains(itemCenter))
       
  6091                         contained = true;
       
  6092                     if (!contained && topValid && topRect.contains(itemCenter))
       
  6093                         contained = true;
       
  6094                     if (!contained && bottomValid && bottomRect.contains(itemCenter))
       
  6095                         contained = true;
       
  6096 
       
  6097                     if (contained) {
       
  6098                         if (!item->selected && item->isSelectable()) {
       
  6099                             changed = true;
       
  6100                             item->selected = true;
       
  6101                             selectedRect = selectedRect.united(item->rect());
       
  6102                         }
       
  6103                     } else if (item->selected && !control) {
       
  6104                         item->selected = false;
       
  6105                         unselectedRect = unselectedRect.united(item->rect());
       
  6106                         changed = true;
       
  6107                     }
       
  6108                 }
       
  6109 
       
  6110                 QRect viewRect(contentsX(), contentsY(),
       
  6111                                 visibleWidth(), visibleHeight());
       
  6112 
       
  6113                 if (viewRect.intersects(selectedRect)) {
       
  6114                     if (homeend)
       
  6115                         Q3ScrollView::updateContents(viewRect.intersected(selectedRect));
       
  6116                     else
       
  6117                         repaintContents(viewRect.intersected(selectedRect));
       
  6118                 }
       
  6119                 if (viewRect.intersects(unselectedRect)) {
       
  6120                     if (homeend)
       
  6121                         Q3ScrollView::updateContents(viewRect.intersected(unselectedRect));
       
  6122                     else
       
  6123                         repaintContents(viewRect.intersected(unselectedRect));
       
  6124                 }
       
  6125 
       
  6126                 if (changed)
       
  6127                     emit selectionChanged();
       
  6128             }
       
  6129         } else if (!control) {
       
  6130             blockSignals(true);
       
  6131             selectAll(false);
       
  6132             blockSignals(false);
       
  6133             d->currentItem->setSelected(true, true);
       
  6134         }
       
  6135     } else {
       
  6136         if (shift)
       
  6137             d->currentItem->setSelected(!d->currentItem->isSelected(), true);
       
  6138     }
       
  6139 }
       
  6140 
       
  6141 QBitmap Q3IconView::mask(QPixmap *pix) const
       
  6142 {
       
  6143     QBitmap m;
       
  6144     if (d->maskCache.find(QString::number(pix->serialNumber()), m))
       
  6145         return m;
       
  6146     if (pix->hasAlphaChannel())
       
  6147        m = pix->mask();
       
  6148     else
       
  6149        m = pix->createHeuristicMask();
       
  6150     d->maskCache.insert(QString::number(pix->serialNumber()), m);
       
  6151     return m;
       
  6152 }
       
  6153 
       
  6154 /*!
       
  6155     Returns true if an iconview item is being renamed; otherwise
       
  6156     returns false.
       
  6157 */
       
  6158 
       
  6159 bool Q3IconView::isRenaming() const
       
  6160 {
       
  6161 #ifndef QT_NO_TEXTEDIT
       
  6162     return d->renamingItem && d->renamingItem->renameBox;
       
  6163 #else
       
  6164     return false;
       
  6165 #endif
       
  6166 }
       
  6167 
       
  6168 /*!
       
  6169     \enum Q3IconView::StringComparisonMode
       
  6170 
       
  6171     This enum type is used to set the string comparison mode when
       
  6172     searching for an item. We'll refer to the string being searched
       
  6173     as the 'target' string.
       
  6174 
       
  6175     \value CaseSensitive The strings must match case sensitively.
       
  6176     \value ExactMatch The target and search strings must match exactly.
       
  6177     \value BeginsWith The target string begins with the search string.
       
  6178     \value EndsWith The target string ends with the search string.
       
  6179     \value Contains The target string contains the search string.
       
  6180 
       
  6181     If you OR these flags together (excluding \c CaseSensitive), the
       
  6182     search criteria be applied in the following order: \c ExactMatch,
       
  6183     \c BeginsWith, \c EndsWith, \c Contains.
       
  6184 
       
  6185     Matching is case-insensitive unless \c CaseSensitive is set. \c
       
  6186     CaseSensitive can be OR-ed with any combination of the other
       
  6187     flags.
       
  6188 
       
  6189     \sa ComparisonFlags
       
  6190 */
       
  6191 
       
  6192 /*!
       
  6193     \typedef Q3IconView::ComparisonFlags
       
  6194 
       
  6195     This typedef is used in Q3IconView's API for values that are OR'd
       
  6196     combinations of \l StringComparisonMode values.
       
  6197 
       
  6198     \sa StringComparisonMode
       
  6199 */
       
  6200 
       
  6201 QT_END_NAMESPACE
       
  6202 
       
  6203 #endif // QT_NO_ICONVIEW