src/gui/itemviews/qabstractitemview.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
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 QtGui 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 "qabstractitemview.h"
       
    43 
       
    44 #ifndef QT_NO_ITEMVIEWS
       
    45 #include <qpointer.h>
       
    46 #include <qapplication.h>
       
    47 #include <qclipboard.h>
       
    48 #include <qpainter.h>
       
    49 #include <qstyle.h>
       
    50 #include <qdrag.h>
       
    51 #include <qevent.h>
       
    52 #include <qscrollbar.h>
       
    53 #include <qwhatsthis.h>
       
    54 #include <qtooltip.h>
       
    55 #include <qdatetime.h>
       
    56 #include <qlineedit.h>
       
    57 #include <qspinbox.h>
       
    58 #include <qstyleditemdelegate.h>
       
    59 #include <private/qabstractitemview_p.h>
       
    60 #include <private/qabstractitemmodel_p.h>
       
    61 #ifndef QT_NO_ACCESSIBILITY
       
    62 #include <qaccessible.h>
       
    63 #endif
       
    64 #include <private/qsoftkeymanager_p.h>
       
    65 
       
    66 QT_BEGIN_NAMESPACE
       
    67 
       
    68 QAbstractItemViewPrivate::QAbstractItemViewPrivate()
       
    69     :   model(QAbstractItemModelPrivate::staticEmptyModel()),
       
    70         itemDelegate(0),
       
    71         selectionModel(0),
       
    72         ctrlDragSelectionFlag(QItemSelectionModel::NoUpdate),
       
    73         selectionMode(QAbstractItemView::ExtendedSelection),
       
    74         selectionBehavior(QAbstractItemView::SelectItems),
       
    75         currentlyCommittingEditor(0),
       
    76         pressedModifiers(Qt::NoModifier),
       
    77         pressedPosition(QPoint(-1, -1)),
       
    78         pressedAlreadySelected(false),
       
    79         viewportEnteredNeeded(false),
       
    80         state(QAbstractItemView::NoState),
       
    81         editTriggers(QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed),
       
    82         lastTrigger(QAbstractItemView::NoEditTriggers),
       
    83         tabKeyNavigation(false),
       
    84 #ifndef QT_NO_DRAGANDDROP
       
    85         showDropIndicator(true),
       
    86         dragEnabled(false),
       
    87         dragDropMode(QAbstractItemView::NoDragDrop),
       
    88         overwrite(false),
       
    89         dropIndicatorPosition(QAbstractItemView::OnItem),
       
    90         defaultDropAction(Qt::IgnoreAction),
       
    91 #endif
       
    92 #ifdef QT_SOFTKEYS_ENABLED
       
    93         doneSoftKey(0),
       
    94 #endif
       
    95         autoScroll(true),
       
    96         autoScrollMargin(16),
       
    97         autoScrollCount(0),
       
    98         shouldScrollToCurrentOnShow(false),
       
    99         alternatingColors(false),
       
   100         textElideMode(Qt::ElideRight),
       
   101         verticalScrollMode(QAbstractItemView::ScrollPerItem),
       
   102         horizontalScrollMode(QAbstractItemView::ScrollPerItem),
       
   103         currentIndexSet(false),
       
   104         wrapItemText(false),
       
   105         delayedPendingLayout(false)
       
   106 {
       
   107 }
       
   108 
       
   109 QAbstractItemViewPrivate::~QAbstractItemViewPrivate()
       
   110 {
       
   111 }
       
   112 
       
   113 void QAbstractItemViewPrivate::init()
       
   114 {
       
   115     Q_Q(QAbstractItemView);
       
   116     q->setItemDelegate(new QStyledItemDelegate(q));
       
   117 
       
   118     vbar->setRange(0, 0);
       
   119     hbar->setRange(0, 0);
       
   120 
       
   121     QObject::connect(vbar, SIGNAL(actionTriggered(int)),
       
   122                      q, SLOT(verticalScrollbarAction(int)));
       
   123     QObject::connect(hbar, SIGNAL(actionTriggered(int)),
       
   124                      q, SLOT(horizontalScrollbarAction(int)));
       
   125     QObject::connect(vbar, SIGNAL(valueChanged(int)),
       
   126                      q, SLOT(verticalScrollbarValueChanged(int)));
       
   127     QObject::connect(hbar, SIGNAL(valueChanged(int)),
       
   128                      q, SLOT(horizontalScrollbarValueChanged(int)));
       
   129 
       
   130     viewport->setBackgroundRole(QPalette::Base);
       
   131 
       
   132     doDelayedItemsLayout();
       
   133 
       
   134     q->setAttribute(Qt::WA_InputMethodEnabled);
       
   135 
       
   136 #ifdef QT_SOFTKEYS_ENABLED
       
   137     doneSoftKey = QSoftKeyManager::createKeyedAction(QSoftKeyManager::DoneSoftKey, Qt::Key_Back, q);
       
   138 #endif
       
   139 }
       
   140 
       
   141 void QAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index)
       
   142 {
       
   143     //we take a persistent model index because the model might change by emitting signals
       
   144     Q_Q(QAbstractItemView);
       
   145     if (viewportEnteredNeeded || enteredIndex != index) {
       
   146         viewportEnteredNeeded = false;
       
   147 
       
   148         if (index.isValid()) {
       
   149             emit q->entered(index);
       
   150 #ifndef QT_NO_STATUSTIP
       
   151             QString statustip = model->data(index, Qt::StatusTipRole).toString();
       
   152             if (parent && !statustip.isEmpty()) {
       
   153                 QStatusTipEvent tip(statustip);
       
   154                 QApplication::sendEvent(parent, &tip);
       
   155             }
       
   156 #endif
       
   157         } else {
       
   158 #ifndef QT_NO_STATUSTIP
       
   159             if (parent) {
       
   160                 QString emptyString;
       
   161                 QStatusTipEvent tip( emptyString );
       
   162                 QApplication::sendEvent(parent, &tip);
       
   163             }
       
   164 #endif
       
   165             emit q->viewportEntered();
       
   166         }
       
   167         enteredIndex = index;
       
   168     }
       
   169 }
       
   170 
       
   171 
       
   172 /*!
       
   173     \class QAbstractItemView
       
   174 
       
   175     \brief The QAbstractItemView class provides the basic functionality for
       
   176     item view classes.
       
   177 
       
   178     \ingroup model-view
       
   179 
       
   180 
       
   181     QAbstractItemView class is the base class for every standard view
       
   182     that uses a QAbstractItemModel. QAbstractItemView is an abstract
       
   183     class and cannot itself be instantiated. It provides a standard
       
   184     interface for interoperating with models through the signals and
       
   185     slots mechanism, enabling subclasses to be kept up-to-date with
       
   186     changes to their models.  This class provides standard support for
       
   187     keyboard and mouse navigation, viewport scrolling, item editing,
       
   188     and selections. The keyboard navigation implements this
       
   189     functionality:
       
   190 
       
   191     \table
       
   192         \header
       
   193             \o Keys
       
   194             \o Functionality
       
   195         \row
       
   196             \o Arrow keys
       
   197             \o Changes the current item and selects it.
       
   198         \row
       
   199             \o Ctrl+Arrow keys
       
   200             \o Changes the current item but does not select it.
       
   201         \row
       
   202             \o Shift+Arrow keys
       
   203             \o Changes the current item and selects it. The previously
       
   204                selected item(s) is not deselected.
       
   205         \row
       
   206             \o Ctr+Space
       
   207             \o Toggles selection of the current item.
       
   208         \row
       
   209             \o Tab/Backtab
       
   210             \o Changes the current item to the next/previous item.
       
   211         \row
       
   212             \o Home/End
       
   213             \o Selects the first/last item in the model.
       
   214         \row
       
   215             \o Page up/Page down
       
   216             \o Scrolls the rows shown up/down by the number of
       
   217                visible rows in the view.
       
   218         \row
       
   219             \o Ctrl+A
       
   220             \o Selects all items in the model.
       
   221     \endtable
       
   222 
       
   223     Note that the above table assumes that the
       
   224     \l{selectionMode}{selection mode} allows the operations. For
       
   225     instance, you cannot select items if the selection mode is
       
   226     QAbstractItemView::NoSelection.
       
   227 
       
   228     The QAbstractItemView class is one of the \l{Model/View Classes}
       
   229     and is part of Qt's \l{Model/View Programming}{model/view framework}.
       
   230 
       
   231     The view classes that inherit QAbstractItemView only need
       
   232     to implement their own view-specific functionality, such as
       
   233     drawing items, returning the geometry of items, finding items,
       
   234     etc.
       
   235 
       
   236     QAbstractItemView provides common slots such as edit() and
       
   237     setCurrentIndex(). Many protected slots are also provided, including
       
   238     dataChanged(), rowsInserted(), rowsAboutToBeRemoved(), selectionChanged(),
       
   239     and currentChanged().
       
   240 
       
   241     The root item is returned by rootIndex(), and the current item by
       
   242     currentIndex(). To make sure that an item is visible use
       
   243     scrollTo().
       
   244 
       
   245     Some of QAbstractItemView's functions are concerned with
       
   246     scrolling, for example setHorizontalScrollMode() and
       
   247     setVerticalScrollMode(). To set the range of the scroll bars, you
       
   248     can, for example, reimplement the view's resizeEvent() function:
       
   249 
       
   250     \snippet doc/src/snippets/code/src_gui_itemviews_qabstractitemview.cpp 0
       
   251 
       
   252     Note that the range is not updated until the widget is shown.
       
   253 
       
   254     Several other functions are concerned with selection control; for
       
   255     example setSelectionMode(), and setSelectionBehavior(). This class
       
   256     provides a default selection model to work with
       
   257     (selectionModel()), but this can be replaced by using
       
   258     setSelectionModel() with an instance of QItemSelectionModel.
       
   259 
       
   260     For complete control over the display and editing of items you can
       
   261     specify a delegate with setItemDelegate().
       
   262 
       
   263     QAbstractItemView provides a lot of protected functions. Some are
       
   264     concerned with editing, for example, edit(), and commitData(),
       
   265     whilst others are keyboard and mouse event handlers.
       
   266 
       
   267     \note If you inherit QAbstractItemView and intend to update the contents
       
   268     of the viewport, you should use viewport->update() instead of
       
   269     \l{QWidget::update()}{update()} as all painting operations take place on the
       
   270     viewport.
       
   271 
       
   272     \sa {View Classes}, {Model/View Programming}, QAbstractItemModel, {Chart Example}
       
   273 */
       
   274 
       
   275 /*!
       
   276     \enum QAbstractItemView::SelectionMode
       
   277 
       
   278     This enum indicates how the view responds to user selections:
       
   279 
       
   280     \value SingleSelection  When the user selects an item, any already-selected
       
   281     item becomes unselected, and the user cannot unselect the selected item by
       
   282     clicking on it.
       
   283 
       
   284     \value ContiguousSelection When the user selects an item in the usual way,
       
   285     the selection is cleared and the new item selected. However, if the user
       
   286     presses the Shift key while clicking on an item, all items between the
       
   287     current item and the clicked item are selected or unselected, depending on
       
   288     the state of the clicked item.
       
   289 
       
   290     \value ExtendedSelection When the user selects an item in the usual way,
       
   291     the selection is cleared and the new item selected. However, if the user
       
   292     presses the Ctrl key when clicking on an item, the clicked item gets
       
   293     toggled and all other items are left untouched. If the user presses the
       
   294     Shift key while clicking on an item, all items between the current item
       
   295     and the clicked item are selected or unselected, depending on the state of
       
   296     the clicked item. Multiple items can be selected by dragging the mouse over
       
   297     them.
       
   298 
       
   299     \value MultiSelection When the user selects an item in the usual way, the
       
   300     selection status of that item is toggled and the other items are left
       
   301     alone. Multiple items can be toggled by dragging the mouse over them.
       
   302 
       
   303     \value NoSelection Items cannot be selected.
       
   304 
       
   305     The most commonly used modes are SingleSelection and ExtendedSelection.
       
   306 */
       
   307 
       
   308 /*!
       
   309     \enum QAbstractItemView::SelectionBehavior
       
   310 
       
   311     \value SelectItems   Selecting single items.
       
   312     \value SelectRows    Selecting only rows.
       
   313     \value SelectColumns Selecting only columns.
       
   314 */
       
   315 
       
   316 /*!
       
   317     \enum QAbstractItemView::ScrollHint
       
   318 
       
   319     \value EnsureVisible  Scroll to ensure that the item is visible.
       
   320     \value PositionAtTop  Scroll to position the item at the top of the
       
   321            viewport.
       
   322     \value PositionAtBottom  Scroll to position the item at the bottom of the
       
   323            viewport.
       
   324     \value PositionAtCenter  Scroll to position the item at the center of the
       
   325            viewport.
       
   326 */
       
   327 
       
   328 
       
   329 /*!
       
   330     \enum QAbstractItemView::EditTrigger
       
   331 
       
   332     This enum describes actions which will initiate item editing.
       
   333 
       
   334     \value NoEditTriggers  No editing possible.
       
   335     \value CurrentChanged  Editing start whenever current item changes.
       
   336     \value DoubleClicked   Editing starts when an item is double clicked.
       
   337     \value SelectedClicked Editing starts when clicking on an already selected
       
   338            item.
       
   339     \value EditKeyPressed  Editing starts when the platform edit key has been
       
   340            pressed over an item.
       
   341     \value AnyKeyPressed   Editing starts when any key is pressed over an item.
       
   342     \value AllEditTriggers Editing starts for all above actions.
       
   343 */
       
   344 
       
   345 /*!
       
   346     \enum QAbstractItemView::CursorAction
       
   347 
       
   348     This enum describes the different ways to navigate between items,
       
   349     \sa moveCursor()
       
   350 
       
   351     \value MoveUp       Move to the item above the current item.
       
   352     \value MoveDown     Move to the item below the current item.
       
   353     \value MoveLeft     Move to the item left of the current item.
       
   354     \value MoveRight    Move to the item right of the current item.
       
   355     \value MoveHome     Move to the top-left corner item.
       
   356     \value MoveEnd      Move to the bottom-right corner item.
       
   357     \value MovePageUp   Move one page up above the current item.
       
   358     \value MovePageDown Move one page down below the current item.
       
   359     \value MoveNext     Move to the item after the current item.
       
   360     \value MovePrevious Move to the item before the current item.
       
   361 */
       
   362 
       
   363 /*!
       
   364     \enum QAbstractItemView::State
       
   365 
       
   366     Describes the different states the view can be in. This is usually
       
   367     only interesting when reimplementing your own view.
       
   368 
       
   369     \value NoState        The is the default state.
       
   370     \value DraggingState  The user is dragging items.
       
   371     \value DragSelectingState The user is selecting items.
       
   372     \value EditingState   The user is editing an item in a widget editor.
       
   373     \value ExpandingState   The user is opening a branch of items.
       
   374     \value CollapsingState   The user is closing a branch of items.
       
   375     \value AnimatingState The item view is performing an animation.
       
   376 */
       
   377 
       
   378 /*!
       
   379     \since 4.2
       
   380     \enum QAbstractItemView::ScrollMode
       
   381 
       
   382     \value ScrollPerItem    The view will scroll the contents one item at a time.
       
   383     \value ScrollPerPixel   The view will scroll the contents one pixel at a time.
       
   384 */
       
   385 
       
   386 /*!
       
   387     \fn QRect QAbstractItemView::visualRect(const QModelIndex &index) const = 0
       
   388     Returns the rectangle on the viewport occupied by the item at \a index.
       
   389 
       
   390     If your item is displayed in several areas then visualRect should return
       
   391     the primary area that contains index and not the complete area that index
       
   392     might encompasses, touch or cause drawing.
       
   393 
       
   394     In the base class this is a pure virtual function.
       
   395 
       
   396     \sa indexAt(), visualRegionForSelection()
       
   397 */
       
   398 
       
   399 /*!
       
   400     \fn void QAbstractItemView::scrollTo(const QModelIndex &index, ScrollHint hint) = 0
       
   401 
       
   402     Scrolls the view if necessary to ensure that the item at \a index
       
   403     is visible. The view will try to position the item according to the given \a hint.
       
   404 
       
   405     In the base class this is a pure virtual function.
       
   406 */
       
   407 
       
   408 /*!
       
   409     \fn QModelIndex QAbstractItemView::indexAt(const QPoint &point) const = 0
       
   410 
       
   411     Returns the model index of the item at the viewport coordinates \a point.
       
   412 
       
   413     In the base class this is a pure virtual function.
       
   414 
       
   415     \sa visualRect()
       
   416 */
       
   417 
       
   418 /*!
       
   419     \fn void QAbstractItemView::activated(const QModelIndex &index)
       
   420 
       
   421     This signal is emitted when the item specified by \a index is
       
   422     activated by the user. How to activate items depends on the
       
   423     platform; e.g., by single- or double-clicking the item, or by
       
   424     pressing the Return or Enter key when the item is current.
       
   425 
       
   426     \sa clicked(), doubleClicked(), entered(), pressed()
       
   427 */
       
   428 
       
   429 /*!
       
   430     \fn void QAbstractItemView::entered(const QModelIndex &index)
       
   431 
       
   432     This signal is emitted when the mouse cursor enters the item
       
   433     specified by \a index.
       
   434     Mouse tracking needs to be enabled for this feature to work.
       
   435 
       
   436     \sa viewportEntered(), activated(), clicked(), doubleClicked(), pressed()
       
   437 */
       
   438 
       
   439 /*!
       
   440     \fn void QAbstractItemView::viewportEntered()
       
   441 
       
   442     This signal is emitted when the mouse cursor enters the viewport.
       
   443     Mouse tracking needs to be enabled for this feature to work.
       
   444 
       
   445     \sa entered()
       
   446 */
       
   447 
       
   448 /*!
       
   449     \fn void QAbstractItemView::pressed(const QModelIndex &index)
       
   450 
       
   451     This signal is emitted when a mouse button is pressed. The item
       
   452     the mouse was pressed on is specified by \a index. The signal is
       
   453     only emitted when the index is valid.
       
   454 
       
   455     Use the QApplication::mouseButtons() function to get the state
       
   456     of the mouse buttons.
       
   457 
       
   458     \sa activated(), clicked(), doubleClicked(), entered()
       
   459 */
       
   460 
       
   461 /*!
       
   462     \fn void QAbstractItemView::clicked(const QModelIndex &index)
       
   463 
       
   464     This signal is emitted when a mouse button is clicked. The item
       
   465     the mouse was clicked on is specified by \a index. The signal is
       
   466     only emitted when the index is valid.
       
   467 
       
   468     \sa activated(), doubleClicked(), entered(), pressed()
       
   469 */
       
   470 
       
   471 /*!
       
   472     \fn void QAbstractItemView::doubleClicked(const QModelIndex &index)
       
   473 
       
   474     This signal is emitted when a mouse button is double-clicked. The
       
   475     item the mouse was double-clicked on is specified by \a index.
       
   476     The signal is only emitted when the index is valid.
       
   477 
       
   478     \sa clicked(), activated()
       
   479 */
       
   480 
       
   481 /*!
       
   482     \fn QModelIndex QAbstractItemView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) = 0
       
   483 
       
   484     Returns a QModelIndex object pointing to the next object in the view,
       
   485     based on the given \a cursorAction and keyboard modifiers specified
       
   486     by \a modifiers.
       
   487 
       
   488     In the base class this is a pure virtual function.
       
   489 */
       
   490 
       
   491 /*!
       
   492     \fn int QAbstractItemView::horizontalOffset() const = 0
       
   493 
       
   494     Returns the horizontal offset of the view.
       
   495 
       
   496     In the base class this is a pure virtual function.
       
   497 
       
   498     \sa verticalOffset()
       
   499 */
       
   500 
       
   501 /*!
       
   502     \fn int QAbstractItemView::verticalOffset() const = 0
       
   503 
       
   504     Returns the vertical offset of the view.
       
   505 
       
   506     In the base class this is a pure virtual function.
       
   507 
       
   508     \sa horizontalOffset()
       
   509 */
       
   510 
       
   511 /*!
       
   512     \fn bool QAbstractItemView::isIndexHidden(const QModelIndex &index) const
       
   513 
       
   514     Returns true if the item referred to by the given \a index is hidden in the view,
       
   515     otherwise returns false.
       
   516 
       
   517     Hiding is a view specific feature.  For example in TableView a column can be marked
       
   518     as hidden or a row in the TreeView.
       
   519 
       
   520     In the base class this is a pure virtual function.
       
   521 */
       
   522 
       
   523 /*!
       
   524     \fn void QAbstractItemView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags flags)
       
   525 
       
   526     Applies the selection \a flags to the items in or touched by the
       
   527     rectangle, \a rect.
       
   528 
       
   529     When implementing your own itemview setSelection should call
       
   530     selectionModel()->select(selection, flags) where selection
       
   531     is either an empty QModelIndex or a QItemSelection that contains
       
   532     all items that are contained in \a rect.
       
   533 
       
   534     \sa selectionCommand(), selectedIndexes()
       
   535 */
       
   536 
       
   537 /*!
       
   538     \fn QRegion QAbstractItemView::visualRegionForSelection(const QItemSelection &selection) const = 0
       
   539 
       
   540     Returns the region from the viewport of the items in the given
       
   541     \a selection.
       
   542 
       
   543     In the base class this is a pure virtual function.
       
   544 
       
   545     \sa visualRect(), selectedIndexes()
       
   546 */
       
   547 
       
   548 /*!
       
   549     \fn void QAbstractItemView::update()
       
   550     \internal
       
   551 */
       
   552 
       
   553 /*!
       
   554     Constructs an abstract item view with the given \a parent.
       
   555 */
       
   556 QAbstractItemView::QAbstractItemView(QWidget *parent)
       
   557     : QAbstractScrollArea(*(new QAbstractItemViewPrivate), parent)
       
   558 {
       
   559     d_func()->init();
       
   560 }
       
   561 
       
   562 /*!
       
   563     \internal
       
   564 */
       
   565 QAbstractItemView::QAbstractItemView(QAbstractItemViewPrivate &dd, QWidget *parent)
       
   566     : QAbstractScrollArea(dd, parent)
       
   567 {
       
   568     d_func()->init();
       
   569 }
       
   570 
       
   571 /*!
       
   572     Destroys the view.
       
   573 */
       
   574 QAbstractItemView::~QAbstractItemView()
       
   575 {
       
   576 }
       
   577 
       
   578 /*!
       
   579     Sets the \a model for the view to present.
       
   580 
       
   581     This function will create and set a new selection model, replacing any
       
   582     model that was previously set with setSelectionModel(). However, the old
       
   583     selection model will not be deleted as it may be shared between several
       
   584     views. We recommend that you delete the old selection model if it is no
       
   585     longer required. This is done with the following code:
       
   586 
       
   587     \snippet doc/src/snippets/code/src_gui_itemviews_qabstractitemview.cpp 2
       
   588 
       
   589     If both the old model and the old selection model do not have parents, or
       
   590     if their parents are long-lived objects, it may be preferable to call their
       
   591     deleteLater() functions to explicitly delete them.
       
   592 
       
   593     The view \e{does not} take ownership of the model unless it is the model's
       
   594     parent object because the view may be shared between many different views.
       
   595 
       
   596   \sa selectionModel(), setSelectionModel()
       
   597 */
       
   598 void QAbstractItemView::setModel(QAbstractItemModel *model)
       
   599 {
       
   600     Q_D(QAbstractItemView);
       
   601     if (model == d->model)
       
   602         return;
       
   603     if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
       
   604         disconnect(d->model, SIGNAL(destroyed()),
       
   605                    this, SLOT(_q_modelDestroyed()));
       
   606         disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
       
   607                    this, SLOT(dataChanged(QModelIndex,QModelIndex)));
       
   608         disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
       
   609                    this, SLOT(rowsInserted(QModelIndex,int,int)));
       
   610         disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
       
   611                    this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
       
   612         disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
       
   613                    this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
       
   614         disconnect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
       
   615                    this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)));
       
   616         disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
       
   617                    this, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
       
   618         disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
       
   619                    this, SLOT(_q_columnsInserted(QModelIndex,int,int)));
       
   620 
       
   621         disconnect(d->model, SIGNAL(modelReset()), this, SLOT(reset()));
       
   622         disconnect(d->model, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
       
   623     }
       
   624     d->model = (model ? model : QAbstractItemModelPrivate::staticEmptyModel());
       
   625 
       
   626     // These asserts do basic sanity checking of the model
       
   627     Q_ASSERT_X(d->model->index(0,0) == d->model->index(0,0),
       
   628                "QAbstractItemView::setModel",
       
   629                "A model should return the exact same index "
       
   630                "(including its internal id/pointer) when asked for it twice in a row.");
       
   631     Q_ASSERT_X(d->model->index(0,0).parent() == QModelIndex(),
       
   632                "QAbstractItemView::setModel",
       
   633                "The parent of a top level index should be invalid");
       
   634 
       
   635     if (d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
       
   636         connect(d->model, SIGNAL(destroyed()),
       
   637                 this, SLOT(_q_modelDestroyed()));
       
   638         connect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
       
   639                 this, SLOT(dataChanged(QModelIndex,QModelIndex)));
       
   640         connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
       
   641                 this, SLOT(rowsInserted(QModelIndex,int,int)));
       
   642         connect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
       
   643                 this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
       
   644         connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
       
   645                 this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
       
   646         connect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
       
   647                 this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)));
       
   648         connect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
       
   649                 this, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
       
   650         connect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
       
   651                 this, SLOT(_q_columnsInserted(QModelIndex,int,int)));
       
   652 
       
   653         connect(d->model, SIGNAL(modelReset()), this, SLOT(reset()));
       
   654         connect(d->model, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
       
   655     }
       
   656     setSelectionModel(new QItemSelectionModel(d->model, this));
       
   657     reset(); // kill editors, set new root and do layout
       
   658 }
       
   659 
       
   660 /*!
       
   661     Returns the model that this view is presenting.
       
   662 */
       
   663 QAbstractItemModel *QAbstractItemView::model() const
       
   664 {
       
   665     Q_D(const QAbstractItemView);
       
   666     return (d->model == QAbstractItemModelPrivate::staticEmptyModel() ? 0 : d->model);
       
   667 }
       
   668 
       
   669 /*!
       
   670     Sets the current selection model to the given \a selectionModel.
       
   671 
       
   672     Note that, if you call setModel() after this function, the given \a selectionModel
       
   673     will be replaced by one created by the view.
       
   674 
       
   675     \note It is up to the application to delete the old selection model if it is no
       
   676     longer needed; i.e., if it is not being used by other views. This will happen
       
   677     automatically when its parent object is deleted. However, if it does not have a
       
   678     parent, or if the parent is a long-lived object, it may be preferable to call its
       
   679     deleteLater() function to explicitly delete it.
       
   680 
       
   681     \sa selectionModel(), setModel(), clearSelection()
       
   682 */
       
   683 void QAbstractItemView::setSelectionModel(QItemSelectionModel *selectionModel)
       
   684 {
       
   685     // ### if the given model is null, we should use the original selection model
       
   686     Q_ASSERT(selectionModel);
       
   687     Q_D(QAbstractItemView);
       
   688 
       
   689     if (selectionModel->model() != d->model) {
       
   690         qWarning("QAbstractItemView::setSelectionModel() failed: "
       
   691                  "Trying to set a selection model, which works on "
       
   692                  "a different model than the view.");
       
   693         return;
       
   694     }
       
   695 
       
   696     if (d->selectionModel) {
       
   697         disconnect(d->selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
       
   698                    this, SLOT(selectionChanged(QItemSelection,QItemSelection)));
       
   699         disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
       
   700                    this, SLOT(currentChanged(QModelIndex,QModelIndex)));
       
   701     }
       
   702 
       
   703     d->selectionModel = selectionModel;
       
   704 
       
   705     if (d->selectionModel) {
       
   706         connect(d->selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
       
   707                 this, SLOT(selectionChanged(QItemSelection,QItemSelection)));
       
   708         connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
       
   709                 this, SLOT(currentChanged(QModelIndex,QModelIndex)));
       
   710     }
       
   711 }
       
   712 
       
   713 /*!
       
   714     Returns the current selection model.
       
   715 
       
   716     \sa setSelectionModel(), selectedIndexes()
       
   717 */
       
   718 QItemSelectionModel* QAbstractItemView::selectionModel() const
       
   719 {
       
   720     Q_D(const QAbstractItemView);
       
   721     return d->selectionModel;
       
   722 }
       
   723 
       
   724 /*!
       
   725     Sets the item delegate for this view and its model to \a delegate.
       
   726     This is useful if you want complete control over the editing and
       
   727     display of items.
       
   728 
       
   729     Any existing delegate will be removed, but not deleted. QAbstractItemView
       
   730     does not take ownership of \a delegate.
       
   731 
       
   732     \warning You should not share the same instance of a delegate between views.
       
   733     Doing so can cause incorrect or unintuitive editing behavior since each
       
   734     view connected to a given delegate may receive the \l{QAbstractItemDelegate::}{closeEditor()}
       
   735     signal, and attempt to access, modify or close an editor that has already been closed.
       
   736 
       
   737     \sa itemDelegate()
       
   738 */
       
   739 void QAbstractItemView::setItemDelegate(QAbstractItemDelegate *delegate)
       
   740 {
       
   741     Q_D(QAbstractItemView);
       
   742     if (delegate == d->itemDelegate)
       
   743         return;
       
   744 
       
   745     if (d->itemDelegate) {
       
   746         if (d->delegateRefCount(d->itemDelegate) == 1) {
       
   747             disconnect(d->itemDelegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
       
   748                        this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
       
   749             disconnect(d->itemDelegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
       
   750             disconnect(d->itemDelegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(doItemsLayout()));
       
   751         }
       
   752     }
       
   753 
       
   754     if (delegate) {
       
   755         if (d->delegateRefCount(delegate) == 0) {
       
   756             connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
       
   757                     this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
       
   758             connect(delegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
       
   759             qRegisterMetaType<QModelIndex>("QModelIndex");
       
   760             connect(delegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(doItemsLayout()), Qt::QueuedConnection);
       
   761         }
       
   762     }
       
   763     d->itemDelegate = delegate;
       
   764     viewport()->update();
       
   765 }
       
   766 
       
   767 /*!
       
   768     Returns the item delegate used by this view and model. This is
       
   769     either one set with setItemDelegate(), or the default one.
       
   770 
       
   771     \sa setItemDelegate()
       
   772 */
       
   773 QAbstractItemDelegate *QAbstractItemView::itemDelegate() const
       
   774 {
       
   775     return d_func()->itemDelegate;
       
   776 }
       
   777 
       
   778 /*!
       
   779     \reimp
       
   780 */
       
   781 QVariant QAbstractItemView::inputMethodQuery(Qt::InputMethodQuery query) const
       
   782 {
       
   783     const QModelIndex current = currentIndex();
       
   784     if (!current.isValid() || query != Qt::ImMicroFocus)
       
   785         return QAbstractScrollArea::inputMethodQuery(query);
       
   786     return visualRect(current);
       
   787 }
       
   788 
       
   789 /*!
       
   790     \since 4.2
       
   791 
       
   792     Sets the given item \a delegate used by this view and model for the given
       
   793     \a row. All items on \a row will be drawn and managed by \a delegate
       
   794     instead of using the default delegate (i.e., itemDelegate()).
       
   795 
       
   796     Any existing row delegate for \a row will be removed, but not
       
   797     deleted. QAbstractItemView does not take ownership of \a delegate.
       
   798 
       
   799     \note If a delegate has been assigned to both a row and a column, the row
       
   800     delegate (i.e., this delegate) will take presedence and manage the
       
   801     intersecting cell index.
       
   802 
       
   803     \warning You should not share the same instance of a delegate between views.
       
   804     Doing so can cause incorrect or unintuitive editing behavior since each
       
   805     view connected to a given delegate may receive the \l{QAbstractItemDelegate::}{closeEditor()}
       
   806     signal, and attempt to access, modify or close an editor that has already been closed.
       
   807 
       
   808     \sa itemDelegateForRow(), setItemDelegateForColumn(), itemDelegate()
       
   809 */
       
   810 void QAbstractItemView::setItemDelegateForRow(int row, QAbstractItemDelegate *delegate)
       
   811 {
       
   812     Q_D(QAbstractItemView);
       
   813     if (QAbstractItemDelegate *rowDelegate = d->rowDelegates.value(row, 0)) {
       
   814         if (d->delegateRefCount(rowDelegate) == 1) {
       
   815             disconnect(rowDelegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
       
   816                        this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
       
   817             disconnect(rowDelegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
       
   818         }
       
   819         d->rowDelegates.remove(row);
       
   820     }
       
   821     if (delegate) {
       
   822         if (d->delegateRefCount(delegate) == 0) {
       
   823             connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
       
   824                     this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
       
   825             connect(delegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
       
   826         }
       
   827         d->rowDelegates.insert(row, delegate);
       
   828     }
       
   829     viewport()->update();
       
   830 }
       
   831 
       
   832 /*!
       
   833    \since 4.2
       
   834 
       
   835    Returns the item delegate used by this view and model for the given \a row,
       
   836    or 0 if no delegate has been assigned. You can call itemDelegate() to get a
       
   837    pointer to the current delegate for a given index.
       
   838 
       
   839    \sa setItemDelegateForRow(), itemDelegateForColumn(), setItemDelegate()
       
   840 */
       
   841 QAbstractItemDelegate *QAbstractItemView::itemDelegateForRow(int row) const
       
   842 {
       
   843     Q_D(const QAbstractItemView);
       
   844     return d->rowDelegates.value(row, 0);
       
   845 }
       
   846 
       
   847 /*!
       
   848     \since 4.2
       
   849 
       
   850     Sets the given item \a delegate used by this view and model for the given
       
   851     \a column. All items on \a column will be drawn and managed by \a delegate
       
   852     instead of using the default delegate (i.e., itemDelegate()).
       
   853 
       
   854     Any existing column delegate for \a column will be removed, but not
       
   855     deleted. QAbstractItemView does not take ownership of \a delegate.
       
   856 
       
   857     \note If a delegate has been assigned to both a row and a column, the row
       
   858     delegate will take presedence and manage the intersecting cell index.
       
   859 
       
   860     \warning You should not share the same instance of a delegate between views.
       
   861     Doing so can cause incorrect or unintuitive editing behavior since each
       
   862     view connected to a given delegate may receive the \l{QAbstractItemDelegate::}{closeEditor()}
       
   863     signal, and attempt to access, modify or close an editor that has already been closed.
       
   864 
       
   865     \sa itemDelegateForColumn(), setItemDelegateForRow(), itemDelegate()
       
   866 */
       
   867 void QAbstractItemView::setItemDelegateForColumn(int column, QAbstractItemDelegate *delegate)
       
   868 {
       
   869     Q_D(QAbstractItemView);
       
   870     if (QAbstractItemDelegate *columnDelegate = d->columnDelegates.value(column, 0)) {
       
   871         if (d->delegateRefCount(columnDelegate) == 1) {
       
   872             disconnect(columnDelegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
       
   873                        this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
       
   874             disconnect(columnDelegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
       
   875         }
       
   876         d->columnDelegates.remove(column);
       
   877     }
       
   878     if (delegate) {
       
   879         if (d->delegateRefCount(delegate) == 0) {
       
   880             connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
       
   881                     this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
       
   882             connect(delegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
       
   883         }
       
   884         d->columnDelegates.insert(column, delegate);
       
   885     }
       
   886     viewport()->update();
       
   887 }
       
   888 
       
   889 /*!
       
   890     \since 4.2
       
   891 
       
   892     Returns the item delegate used by this view and model for the given \a
       
   893     column.  You can call itemDelegate() to get a pointer to the current delegate
       
   894     for a given index.
       
   895 
       
   896     \sa setItemDelegateForColumn(), itemDelegateForRow(), itemDelegate()
       
   897 */
       
   898 QAbstractItemDelegate *QAbstractItemView::itemDelegateForColumn(int column) const
       
   899 {
       
   900     Q_D(const QAbstractItemView);
       
   901     return d->columnDelegates.value(column, 0);
       
   902 }
       
   903 
       
   904 /*!
       
   905     Returns the item delegate used by this view and model for
       
   906     the given \a index.
       
   907 */
       
   908 QAbstractItemDelegate *QAbstractItemView::itemDelegate(const QModelIndex &index) const
       
   909 {
       
   910     Q_D(const QAbstractItemView);
       
   911     return d->delegateForIndex(index);
       
   912 }
       
   913 
       
   914 /*!
       
   915     \property QAbstractItemView::selectionMode
       
   916     \brief which selection mode the view operates in
       
   917 
       
   918     This property controls whether the user can select one or many items
       
   919     and, in many-item selections, whether the selection must be a
       
   920     continuous range of items.
       
   921 
       
   922     \sa SelectionMode SelectionBehavior
       
   923 */
       
   924 void QAbstractItemView::setSelectionMode(SelectionMode mode)
       
   925 {
       
   926     Q_D(QAbstractItemView);
       
   927     d->selectionMode = mode;
       
   928 }
       
   929 
       
   930 QAbstractItemView::SelectionMode QAbstractItemView::selectionMode() const
       
   931 {
       
   932     Q_D(const QAbstractItemView);
       
   933     return d->selectionMode;
       
   934 }
       
   935 
       
   936 /*!
       
   937     \property QAbstractItemView::selectionBehavior
       
   938     \brief which selection behavior the view uses
       
   939 
       
   940     This property holds whether selections are done
       
   941     in terms of single items, rows or columns.
       
   942 
       
   943     \sa SelectionMode SelectionBehavior
       
   944 */
       
   945 
       
   946 void QAbstractItemView::setSelectionBehavior(QAbstractItemView::SelectionBehavior behavior)
       
   947 {
       
   948     Q_D(QAbstractItemView);
       
   949     d->selectionBehavior = behavior;
       
   950 }
       
   951 
       
   952 QAbstractItemView::SelectionBehavior QAbstractItemView::selectionBehavior() const
       
   953 {
       
   954     Q_D(const QAbstractItemView);
       
   955     return d->selectionBehavior;
       
   956 }
       
   957 
       
   958 /*!
       
   959     Sets the current item to be the item at \a index.
       
   960 
       
   961     Unless the current selection mode is
       
   962     \l{QAbstractItemView::}{NoSelection}, the item is also be selected.
       
   963     Note that this function also updates the starting position for any
       
   964     new selections the user performs.
       
   965 
       
   966     To set an item as the current item without selecting it, call
       
   967 
       
   968     \c{selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);}
       
   969 
       
   970     \sa currentIndex(), currentChanged(), selectionMode
       
   971 */
       
   972 void QAbstractItemView::setCurrentIndex(const QModelIndex &index)
       
   973 {
       
   974     Q_D(QAbstractItemView);
       
   975     if (d->selectionModel && (!index.isValid() || d->isIndexEnabled(index))) {
       
   976         QItemSelectionModel::SelectionFlags command = selectionCommand(index, 0);
       
   977         d->selectionModel->setCurrentIndex(index, command);
       
   978         d->currentIndexSet = true;
       
   979         if ((command & QItemSelectionModel::Current) == 0)
       
   980             d->pressedPosition = visualRect(currentIndex()).center() + d->offset();
       
   981     }
       
   982 }
       
   983 
       
   984 /*!
       
   985     Returns the model index of the current item.
       
   986 
       
   987     \sa setCurrentIndex()
       
   988 */
       
   989 QModelIndex QAbstractItemView::currentIndex() const
       
   990 {
       
   991     Q_D(const QAbstractItemView);
       
   992     return d->selectionModel ? d->selectionModel->currentIndex() : QModelIndex();
       
   993 }
       
   994 
       
   995 
       
   996 /*!
       
   997     Reset the internal state of the view.
       
   998 
       
   999     \warning This function will reset open editors, scroll bar positions,
       
  1000     selections, etc. Existing changes will not be committed. If you would like
       
  1001     to save your changes when resetting the view, you can reimplement this
       
  1002     function, commit your changes, and then call the superclass'
       
  1003     implementation.
       
  1004 */
       
  1005 void QAbstractItemView::reset()
       
  1006 {
       
  1007     Q_D(QAbstractItemView);
       
  1008     d->delayedReset.stop(); //make sure we stop the timer
       
  1009     QList<QEditorInfo>::const_iterator it = d->editors.constBegin();
       
  1010     for (; it != d->editors.constEnd(); ++it)
       
  1011         d->releaseEditor(it->editor);
       
  1012     d->editors.clear();
       
  1013     d->persistent.clear();
       
  1014     d->currentIndexSet = false;
       
  1015     setState(NoState);
       
  1016     setRootIndex(QModelIndex());
       
  1017     if (d->selectionModel)
       
  1018         d->selectionModel->reset();
       
  1019 }
       
  1020 
       
  1021 /*!
       
  1022     Sets the root item to the item at the given \a index.
       
  1023 
       
  1024     \sa rootIndex()
       
  1025 */
       
  1026 void QAbstractItemView::setRootIndex(const QModelIndex &index)
       
  1027 {
       
  1028     Q_D(QAbstractItemView);
       
  1029     if (index.isValid() && index.model() != d->model) {
       
  1030         qWarning("QAbstractItemView::setRootIndex failed : index must be from the currently set model");
       
  1031         return;
       
  1032     }
       
  1033     d->root = index;
       
  1034     d->doDelayedItemsLayout();
       
  1035 }
       
  1036 
       
  1037 /*!
       
  1038     Returns the model index of the model's root item. The root item is
       
  1039     the parent item to the view's toplevel items. The root can be invalid.
       
  1040 
       
  1041     \sa setRootIndex()
       
  1042 */
       
  1043 QModelIndex QAbstractItemView::rootIndex() const
       
  1044 {
       
  1045     return QModelIndex(d_func()->root);
       
  1046 }
       
  1047 
       
  1048 /*!
       
  1049     Selects all items in the view.
       
  1050     This function will use the selection behavior
       
  1051     set on the view when selecting.
       
  1052 
       
  1053     \sa setSelection(), selectedIndexes(), clearSelection()
       
  1054 */
       
  1055 void QAbstractItemView::selectAll()
       
  1056 {
       
  1057     Q_D(QAbstractItemView);
       
  1058     SelectionMode mode = d->selectionMode;
       
  1059     if (mode == MultiSelection || mode == ExtendedSelection)
       
  1060         d->selectAll(QItemSelectionModel::ClearAndSelect
       
  1061                      |d->selectionBehaviorFlags());
       
  1062     else if (mode != SingleSelection)
       
  1063         d->selectAll(selectionCommand(d->model->index(0, 0, d->root)));
       
  1064 }
       
  1065 
       
  1066 /*!
       
  1067     Starts editing the item corresponding to the given \a index if it is
       
  1068     editable.
       
  1069 
       
  1070     Note that this function does not change the current index. Since the current
       
  1071     index defines the next and previous items to edit, users may find that
       
  1072     keyboard navigation does not work as expected. To provide consistent navigation
       
  1073     behavior, call setCurrentIndex() before this function with the same model
       
  1074     index.
       
  1075 
       
  1076     \sa QModelIndex::flags()
       
  1077 */
       
  1078 void QAbstractItemView::edit(const QModelIndex &index)
       
  1079 {
       
  1080     Q_D(QAbstractItemView);
       
  1081     if (!d->isIndexValid(index))
       
  1082         qWarning("edit: index was invalid");
       
  1083     if (!edit(index, AllEditTriggers, 0))
       
  1084         qWarning("edit: editing failed");
       
  1085 }
       
  1086 
       
  1087 /*!
       
  1088     Deselects all selected items. The current index will not be changed.
       
  1089 
       
  1090     \sa setSelection(), selectAll()
       
  1091 */
       
  1092 void QAbstractItemView::clearSelection()
       
  1093 {
       
  1094     Q_D(QAbstractItemView);
       
  1095     if (d->selectionModel)
       
  1096         d->selectionModel->clearSelection();
       
  1097 }
       
  1098 
       
  1099 /*!
       
  1100     \internal
       
  1101 
       
  1102     This function is intended to lay out the items in the view.
       
  1103     The default implementation just calls updateGeometries() and updates the viewport.
       
  1104 */
       
  1105 void QAbstractItemView::doItemsLayout()
       
  1106 {
       
  1107     Q_D(QAbstractItemView);
       
  1108     d->interruptDelayedItemsLayout();
       
  1109     updateGeometries();
       
  1110     d->viewport->update();
       
  1111 }
       
  1112 
       
  1113 /*!
       
  1114     \property QAbstractItemView::editTriggers
       
  1115     \brief which actions will initiate item editing
       
  1116 
       
  1117     This property is a selection of flags defined by
       
  1118     \l{EditTrigger}, combined using the OR
       
  1119     operator. The view will only initiate the editing of an item if the
       
  1120     action performed is set in this property.
       
  1121 */
       
  1122 void QAbstractItemView::setEditTriggers(EditTriggers actions)
       
  1123 {
       
  1124     Q_D(QAbstractItemView);
       
  1125     d->editTriggers = actions;
       
  1126 }
       
  1127 
       
  1128 QAbstractItemView::EditTriggers QAbstractItemView::editTriggers() const
       
  1129 {
       
  1130     Q_D(const QAbstractItemView);
       
  1131     return d->editTriggers;
       
  1132 }
       
  1133 
       
  1134 /*!
       
  1135     \since 4.2
       
  1136     \property QAbstractItemView::verticalScrollMode
       
  1137     \brief how the view scrolls its contents in the vertical direction
       
  1138 
       
  1139     This property controlls how the view scroll its contents vertically.
       
  1140     Scrolling can be done either per pixel or per item.
       
  1141 */
       
  1142 
       
  1143 void QAbstractItemView::setVerticalScrollMode(ScrollMode mode)
       
  1144 {
       
  1145     Q_D(QAbstractItemView);
       
  1146     if (mode == d->verticalScrollMode)
       
  1147         return;
       
  1148     QModelIndex topLeft = indexAt(QPoint(0, 0));
       
  1149     d->verticalScrollMode = mode;
       
  1150     updateGeometries(); // update the scroll bars
       
  1151     scrollTo(topLeft, QAbstractItemView::PositionAtTop);
       
  1152 }
       
  1153 
       
  1154 QAbstractItemView::ScrollMode QAbstractItemView::verticalScrollMode() const
       
  1155 {
       
  1156     Q_D(const QAbstractItemView);
       
  1157     return d->verticalScrollMode;
       
  1158 }
       
  1159 
       
  1160 /*!
       
  1161     \since 4.2
       
  1162     \property QAbstractItemView::horizontalScrollMode
       
  1163     \brief how the view scrolls its contents in the horizontal direction
       
  1164 
       
  1165     This property controlls how the view scroll its contents horizontally.
       
  1166     Scrolling can be done either per pixel or per item.
       
  1167 */
       
  1168 
       
  1169 void QAbstractItemView::setHorizontalScrollMode(ScrollMode mode)
       
  1170 {
       
  1171     Q_D(QAbstractItemView);
       
  1172     d->horizontalScrollMode = mode;
       
  1173     updateGeometries(); // update the scroll bars
       
  1174 }
       
  1175 
       
  1176 QAbstractItemView::ScrollMode QAbstractItemView::horizontalScrollMode() const
       
  1177 {
       
  1178     Q_D(const QAbstractItemView);
       
  1179     return d->horizontalScrollMode;
       
  1180 }
       
  1181 
       
  1182 #ifndef QT_NO_DRAGANDDROP
       
  1183 /*!
       
  1184     \since 4.2
       
  1185     \property QAbstractItemView::dragDropOverwriteMode
       
  1186     \brief the view's drag and drop behavior
       
  1187 
       
  1188     If its value is \c true, the selected data will overwrite the
       
  1189     existing item data when dropped, while moving the data will clear
       
  1190     the item. If its value is \c false, the selected data will be
       
  1191     inserted as a new item when the data is dropped. When the data is
       
  1192     moved, the item is removed as well.
       
  1193 
       
  1194     The default value is \c false, as in the QListView and QTreeView
       
  1195     subclasses. In the QTableView subclass, on the other hand, the
       
  1196     property has been set to \c true.
       
  1197 
       
  1198     Note: This is not intended to prevent overwriting of items.
       
  1199     The model's implementation of flags() should do that by not
       
  1200     returning Qt::ItemIsDropEnabled.
       
  1201 
       
  1202     \sa dragDropMode
       
  1203 */
       
  1204 void QAbstractItemView::setDragDropOverwriteMode(bool overwrite)
       
  1205 {
       
  1206     Q_D(QAbstractItemView);
       
  1207     d->overwrite = overwrite;
       
  1208 }
       
  1209 
       
  1210 bool QAbstractItemView::dragDropOverwriteMode() const
       
  1211 {
       
  1212     Q_D(const QAbstractItemView);
       
  1213     return d->overwrite;
       
  1214 }
       
  1215 #endif
       
  1216 
       
  1217 /*!
       
  1218     \property QAbstractItemView::autoScroll
       
  1219     \brief whether autoscrolling in drag move events is enabled
       
  1220 
       
  1221     If this property is set to true (the default), the
       
  1222     QAbstractItemView automatically scrolls the contents of the view
       
  1223     if the user drags within 16 pixels of the viewport edge. If the current
       
  1224     item changes, then the view will scroll automatically to ensure that the
       
  1225     current item is fully visible.
       
  1226 
       
  1227     This property only works if the viewport accepts drops. Autoscroll is
       
  1228     switched off by setting this property to false.
       
  1229 */
       
  1230 
       
  1231 void QAbstractItemView::setAutoScroll(bool enable)
       
  1232 {
       
  1233     Q_D(QAbstractItemView);
       
  1234     d->autoScroll = enable;
       
  1235 }
       
  1236 
       
  1237 bool QAbstractItemView::hasAutoScroll() const
       
  1238 {
       
  1239     Q_D(const QAbstractItemView);
       
  1240     return d->autoScroll;
       
  1241 }
       
  1242 
       
  1243 /*!
       
  1244     \since 4.4
       
  1245     \property QAbstractItemView::autoScrollMargin
       
  1246     \brief the size of the area when auto scrolling is triggered
       
  1247 
       
  1248     This property controlls the size of the area at the edge of the viewport that
       
  1249     triggers autoscrolling. The default value is 16 pixels.
       
  1250 */
       
  1251 void QAbstractItemView::setAutoScrollMargin(int margin)
       
  1252 {
       
  1253     Q_D(QAbstractItemView);
       
  1254     d->autoScrollMargin = margin;
       
  1255 }
       
  1256 
       
  1257 int QAbstractItemView::autoScrollMargin() const
       
  1258 {
       
  1259     Q_D(const QAbstractItemView);
       
  1260     return d->autoScrollMargin;
       
  1261 }
       
  1262 
       
  1263 /*!
       
  1264   \property QAbstractItemView::tabKeyNavigation
       
  1265   \brief whether item navigation with tab and backtab is enabled.
       
  1266 */
       
  1267 
       
  1268 void QAbstractItemView::setTabKeyNavigation(bool enable)
       
  1269 {
       
  1270     Q_D(QAbstractItemView);
       
  1271     d->tabKeyNavigation = enable;
       
  1272 }
       
  1273 
       
  1274 bool QAbstractItemView::tabKeyNavigation() const
       
  1275 {
       
  1276     Q_D(const QAbstractItemView);
       
  1277     return d->tabKeyNavigation;
       
  1278 }
       
  1279 
       
  1280 #ifndef QT_NO_DRAGANDDROP
       
  1281 /*!
       
  1282     \property QAbstractItemView::showDropIndicator
       
  1283     \brief whether the drop indicator is shown when dragging items and dropping.
       
  1284 
       
  1285     \sa dragEnabled DragDropMode dragDropOverwriteMode acceptDrops
       
  1286 */
       
  1287 
       
  1288 void QAbstractItemView::setDropIndicatorShown(bool enable)
       
  1289 {
       
  1290     Q_D(QAbstractItemView);
       
  1291     d->showDropIndicator = enable;
       
  1292 }
       
  1293 
       
  1294 bool QAbstractItemView::showDropIndicator() const
       
  1295 {
       
  1296     Q_D(const QAbstractItemView);
       
  1297     return d->showDropIndicator;
       
  1298 }
       
  1299 
       
  1300 /*!
       
  1301     \property QAbstractItemView::dragEnabled
       
  1302     \brief whether the view supports dragging of its own items
       
  1303 
       
  1304     \sa showDropIndicator DragDropMode dragDropOverwriteMode acceptDrops
       
  1305 */
       
  1306 
       
  1307 void QAbstractItemView::setDragEnabled(bool enable)
       
  1308 {
       
  1309     Q_D(QAbstractItemView);
       
  1310     d->dragEnabled = enable;
       
  1311 }
       
  1312 
       
  1313 bool QAbstractItemView::dragEnabled() const
       
  1314 {
       
  1315     Q_D(const QAbstractItemView);
       
  1316     return d->dragEnabled;
       
  1317 }
       
  1318 
       
  1319 /*!
       
  1320     \since 4.2
       
  1321     \enum QAbstractItemView::DragDropMode
       
  1322 
       
  1323     Describes the various drag and drop events the view can act upon.
       
  1324     By default the view does not support dragging or dropping (\c
       
  1325     NoDragDrop).
       
  1326 
       
  1327     \value NoDragDrop Does not support dragging or dropping.
       
  1328     \value DragOnly The view supports dragging of its own items
       
  1329     \value DropOnly The view accepts drops
       
  1330     \value DragDrop The view supports both dragging and dropping
       
  1331     \value InternalMove The view accepts move (\bold{not copy}) operations only
       
  1332            from itself.
       
  1333 
       
  1334     Note that the model used needs to provide support for drag and drop operations.
       
  1335 
       
  1336     \sa setDragDropMode() {Using Drag and Drop with Item Views}
       
  1337 */
       
  1338 
       
  1339 /*!
       
  1340     \property QAbstractItemView::dragDropMode
       
  1341     \brief the drag and drop event the view will act upon
       
  1342 
       
  1343     \since 4.2
       
  1344     \sa showDropIndicator dragDropOverwriteMode
       
  1345 */
       
  1346 void QAbstractItemView::setDragDropMode(DragDropMode behavior)
       
  1347 {
       
  1348     Q_D(QAbstractItemView);
       
  1349     d->dragDropMode = behavior;
       
  1350     setDragEnabled(behavior == DragOnly || behavior == DragDrop || behavior == InternalMove);
       
  1351     setAcceptDrops(behavior == DropOnly || behavior == DragDrop || behavior == InternalMove);
       
  1352 }
       
  1353 
       
  1354 QAbstractItemView::DragDropMode QAbstractItemView::dragDropMode() const
       
  1355 {
       
  1356     Q_D(const QAbstractItemView);
       
  1357     DragDropMode setBehavior = d->dragDropMode;
       
  1358     if (!dragEnabled() && !acceptDrops())
       
  1359         return NoDragDrop;
       
  1360 
       
  1361     if (dragEnabled() && !acceptDrops())
       
  1362         return DragOnly;
       
  1363 
       
  1364     if (!dragEnabled() && acceptDrops())
       
  1365         return DropOnly;
       
  1366 
       
  1367     if (dragEnabled() && acceptDrops()) {
       
  1368         if (setBehavior == InternalMove)
       
  1369             return setBehavior;
       
  1370         else
       
  1371             return DragDrop;
       
  1372     }
       
  1373 
       
  1374     return NoDragDrop;
       
  1375 }
       
  1376 
       
  1377 /*!
       
  1378     \property QAbstractItemView::defaultDropAction
       
  1379     \brief the drop action that will be used by default in QAbstractItemView::drag()
       
  1380 
       
  1381     If the property is not set, the drop action is CopyAction when the supported
       
  1382     actions support CopyAction.
       
  1383 
       
  1384     \since 4.6
       
  1385     \sa showDropIndicator dragDropOverwriteMode
       
  1386 */
       
  1387 void QAbstractItemView::setDefaultDropAction(Qt::DropAction dropAction)
       
  1388 {
       
  1389     Q_D(QAbstractItemView);
       
  1390     d->defaultDropAction = dropAction;
       
  1391 }
       
  1392 
       
  1393 Qt::DropAction QAbstractItemView::defaultDropAction() const
       
  1394 {
       
  1395     Q_D(const QAbstractItemView);
       
  1396     return d->defaultDropAction;
       
  1397 }
       
  1398 
       
  1399 #endif // QT_NO_DRAGANDDROP
       
  1400 
       
  1401 /*!
       
  1402     \property QAbstractItemView::alternatingRowColors
       
  1403     \brief whether to draw the background using alternating colors
       
  1404 
       
  1405     If this property is true, the item background will be drawn using
       
  1406     QPalette::Base and QPalette::AlternateBase; otherwise the background
       
  1407     will be drawn using the QPalette::Base color.
       
  1408 
       
  1409     By default, this property is false.
       
  1410 */
       
  1411 void QAbstractItemView::setAlternatingRowColors(bool enable)
       
  1412 {
       
  1413     Q_D(QAbstractItemView);
       
  1414     d->alternatingColors = enable;
       
  1415     if (isVisible())
       
  1416         d->viewport->update();
       
  1417 }
       
  1418 
       
  1419 bool QAbstractItemView::alternatingRowColors() const
       
  1420 {
       
  1421     Q_D(const QAbstractItemView);
       
  1422     return d->alternatingColors;
       
  1423 }
       
  1424 
       
  1425 /*!
       
  1426     \property QAbstractItemView::iconSize
       
  1427     \brief the size of items' icons
       
  1428 
       
  1429     Setting this property when the view is visible will cause the
       
  1430     items to be laid out again.
       
  1431 */
       
  1432 void QAbstractItemView::setIconSize(const QSize &size)
       
  1433 {
       
  1434     Q_D(QAbstractItemView);
       
  1435     if (size == d->iconSize)
       
  1436         return;
       
  1437     d->iconSize = size;
       
  1438     d->doDelayedItemsLayout();
       
  1439 }
       
  1440 
       
  1441 QSize QAbstractItemView::iconSize() const
       
  1442 {
       
  1443     Q_D(const QAbstractItemView);
       
  1444     return d->iconSize;
       
  1445 }
       
  1446 
       
  1447 /*!
       
  1448     \property QAbstractItemView::textElideMode
       
  1449 
       
  1450     \brief the position of the "..." in elided text.
       
  1451 
       
  1452     The default value for all item views is Qt::ElideRight.
       
  1453 */
       
  1454 void QAbstractItemView::setTextElideMode(Qt::TextElideMode mode)
       
  1455 {
       
  1456     Q_D(QAbstractItemView);
       
  1457     d->textElideMode = mode;
       
  1458 }
       
  1459 
       
  1460 Qt::TextElideMode QAbstractItemView::textElideMode() const
       
  1461 {
       
  1462     return d_func()->textElideMode;
       
  1463 }
       
  1464 
       
  1465 /*!
       
  1466   \reimp
       
  1467 */
       
  1468 bool QAbstractItemView::focusNextPrevChild(bool next)
       
  1469 {
       
  1470     Q_D(QAbstractItemView);
       
  1471     if (d->tabKeyNavigation && isEnabled() && d->viewport->isEnabled()) {
       
  1472         QKeyEvent event(QEvent::KeyPress, next ? Qt::Key_Tab : Qt::Key_Backtab, Qt::NoModifier);
       
  1473         keyPressEvent(&event);
       
  1474         if (event.isAccepted())
       
  1475             return true;
       
  1476     }
       
  1477     return QAbstractScrollArea::focusNextPrevChild(next);
       
  1478 }
       
  1479 
       
  1480 /*!
       
  1481   \reimp
       
  1482 */
       
  1483 bool QAbstractItemView::event(QEvent *event)
       
  1484 {
       
  1485     Q_D(QAbstractItemView);
       
  1486     switch (event->type()) {
       
  1487     case QEvent::Paint:
       
  1488         //we call this here because the scrollbars' visibility might be altered
       
  1489         //so this can't be done in the paintEvent method
       
  1490         d->executePostedLayout(); //make sure we set the layout properly
       
  1491         break;
       
  1492     case QEvent::Show:
       
  1493         d->executePostedLayout(); //make sure we set the layout properly
       
  1494         if (d->shouldScrollToCurrentOnShow) {
       
  1495             d->shouldScrollToCurrentOnShow = false;
       
  1496             const QModelIndex current = currentIndex();
       
  1497             if (current.isValid() && (d->state == QAbstractItemView::EditingState || d->autoScroll))
       
  1498                 scrollTo(current);
       
  1499         }
       
  1500         break;
       
  1501     case QEvent::LocaleChange:
       
  1502         viewport()->update();
       
  1503         break;
       
  1504     case QEvent::LayoutDirectionChange:
       
  1505     case QEvent::ApplicationLayoutDirectionChange:
       
  1506         updateGeometries();
       
  1507         break;
       
  1508     case QEvent::StyleChange:
       
  1509         doItemsLayout();
       
  1510         break;
       
  1511     case QEvent::FocusOut:
       
  1512         d->checkPersistentEditorFocus();
       
  1513         break;
       
  1514     case QEvent::FontChange:
       
  1515         d->doDelayedItemsLayout(); // the size of the items will change
       
  1516         break;
       
  1517     default:
       
  1518         break;
       
  1519     }
       
  1520     return QAbstractScrollArea::event(event);
       
  1521 }
       
  1522 
       
  1523 /*!
       
  1524     \fn bool QAbstractItemView::viewportEvent(QEvent *event)
       
  1525 
       
  1526     This function is used to handle tool tips, and What's
       
  1527     This? mode, if the given \a event is a QEvent::ToolTip,or a
       
  1528     QEvent::WhatsThis. It passes all other
       
  1529     events on to its base class viewportEvent() handler.
       
  1530 */
       
  1531 bool QAbstractItemView::viewportEvent(QEvent *event)
       
  1532 {
       
  1533     Q_D(QAbstractItemView);
       
  1534     switch (event->type()) {
       
  1535     case QEvent::HoverEnter: {
       
  1536         QHoverEvent *he = static_cast<QHoverEvent*>(event);
       
  1537         d->hover = indexAt(he->pos());
       
  1538         update(d->hover);
       
  1539         break; }
       
  1540     case QEvent::HoverLeave: {
       
  1541         update(d->hover); // update old
       
  1542         d->hover = QModelIndex();
       
  1543         break; }
       
  1544     case QEvent::HoverMove: {
       
  1545         QHoverEvent *he = static_cast<QHoverEvent*>(event);
       
  1546         QModelIndex old = d->hover;
       
  1547         d->hover = indexAt(he->pos());
       
  1548         if (d->hover != old)
       
  1549             d->viewport->update(visualRect(old)|visualRect(d->hover));
       
  1550         break; }
       
  1551     case QEvent::Enter:
       
  1552         d->viewportEnteredNeeded = true;
       
  1553         break;
       
  1554     case QEvent::Leave:
       
  1555         d->enteredIndex = QModelIndex();
       
  1556         break;
       
  1557     case QEvent::ToolTip:
       
  1558     case QEvent::QueryWhatsThis:
       
  1559     case QEvent::WhatsThis: {
       
  1560         QHelpEvent *he = static_cast<QHelpEvent*>(event);
       
  1561         const QModelIndex index = indexAt(he->pos());
       
  1562         QStyleOptionViewItemV4 option = d->viewOptionsV4();
       
  1563         option.rect = visualRect(index);
       
  1564         option.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
       
  1565         bool retval = false;
       
  1566         // ### Qt 5: make this a normal function call to a virtual function
       
  1567         QMetaObject::invokeMethod(d->delegateForIndex(index), "helpEvent",
       
  1568                                   Q_RETURN_ARG(bool, retval),
       
  1569                                   Q_ARG(QHelpEvent *, he),
       
  1570                                   Q_ARG(QAbstractItemView *, this),
       
  1571                                   Q_ARG(QStyleOptionViewItem, option),
       
  1572                                   Q_ARG(QModelIndex, index));
       
  1573         return retval;
       
  1574     }
       
  1575     case QEvent::FontChange:
       
  1576         d->doDelayedItemsLayout(); // the size of the items will change
       
  1577         break;
       
  1578     case QEvent::WindowActivate:
       
  1579     case QEvent::WindowDeactivate:
       
  1580         d->viewport->update();
       
  1581         break;
       
  1582     default:
       
  1583         break;
       
  1584     }
       
  1585     return QAbstractScrollArea::viewportEvent(event);
       
  1586 }
       
  1587 
       
  1588 /*!
       
  1589     This function is called with the given \a event when a mouse button is pressed
       
  1590     while the cursor is inside the widget. If a valid item is pressed on it is made
       
  1591     into the current item. This function emits the pressed() signal.
       
  1592 */
       
  1593 void QAbstractItemView::mousePressEvent(QMouseEvent *event)
       
  1594 {
       
  1595     Q_D(QAbstractItemView);
       
  1596     d->delayedAutoScroll.stop(); //any interaction with the view cancel the auto scrolling
       
  1597     QPoint pos = event->pos();
       
  1598     QPersistentModelIndex index = indexAt(pos);
       
  1599 
       
  1600     if (!d->selectionModel
       
  1601         || (d->state == EditingState && d->hasEditor(index)))
       
  1602         return;
       
  1603 
       
  1604     d->pressedAlreadySelected = d->selectionModel->isSelected(index);
       
  1605     d->pressedIndex = index;
       
  1606     d->pressedModifiers = event->modifiers();
       
  1607     QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
       
  1608     QPoint offset = d->offset();
       
  1609     if ((command & QItemSelectionModel::Current) == 0)
       
  1610         d->pressedPosition = pos + offset;
       
  1611     else if (!indexAt(d->pressedPosition).isValid())
       
  1612         d->pressedPosition = visualRect(currentIndex()).center() + offset;
       
  1613 
       
  1614     if (edit(index, NoEditTriggers, event))
       
  1615         return;
       
  1616 
       
  1617     if (index.isValid() && d->isIndexEnabled(index)) {
       
  1618         // we disable scrollTo for mouse press so the item doesn't change position
       
  1619         // when the user is interacting with it (ie. clicking on it)
       
  1620         bool autoScroll = d->autoScroll;
       
  1621         d->autoScroll = false;
       
  1622         d->selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
       
  1623         d->autoScroll = autoScroll;
       
  1624         QRect rect(d->pressedPosition - offset, pos);
       
  1625         if (command.testFlag(QItemSelectionModel::Toggle)) {
       
  1626             command &= ~QItemSelectionModel::Toggle;
       
  1627             d->ctrlDragSelectionFlag = d->selectionModel->isSelected(index) ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
       
  1628             command |= d->ctrlDragSelectionFlag;
       
  1629         }
       
  1630         setSelection(rect, command);
       
  1631 
       
  1632         // signal handlers may change the model
       
  1633         emit pressed(index);
       
  1634         if (d->autoScroll) {
       
  1635             //we delay the autoscrolling to filter out double click event
       
  1636             //100 is to be sure that there won't be a double-click misinterpreted as a 2 single clicks
       
  1637             d->delayedAutoScroll.start(QApplication::doubleClickInterval()+100, this);
       
  1638         }
       
  1639 
       
  1640     } else {
       
  1641         // Forces a finalize() even if mouse is pressed, but not on a item
       
  1642         d->selectionModel->select(QModelIndex(), QItemSelectionModel::Select);
       
  1643     }
       
  1644 }
       
  1645 
       
  1646 /*!
       
  1647     This function is called with the given \a event when a mouse move event is
       
  1648     sent to the widget. If a selection is in progress and new items are moved
       
  1649     over the selection is extended; if a drag is in progress it is continued.
       
  1650 */
       
  1651 void QAbstractItemView::mouseMoveEvent(QMouseEvent *event)
       
  1652 {
       
  1653     Q_D(QAbstractItemView);
       
  1654     QPoint topLeft;
       
  1655     QPoint bottomRight = event->pos();
       
  1656 
       
  1657     if (state() == ExpandingState || state() == CollapsingState)
       
  1658         return;
       
  1659 
       
  1660 #ifndef QT_NO_DRAGANDDROP
       
  1661     if (state() == DraggingState) {
       
  1662         topLeft = d->pressedPosition - d->offset();
       
  1663         if ((topLeft - bottomRight).manhattanLength() > QApplication::startDragDistance()) {
       
  1664             d->pressedIndex = QModelIndex();
       
  1665             startDrag(d->model->supportedDragActions());
       
  1666             setState(NoState); // the startDrag will return when the dnd operation is done
       
  1667             stopAutoScroll();
       
  1668         }
       
  1669         return;
       
  1670     }
       
  1671 #endif // QT_NO_DRAGANDDROP
       
  1672 
       
  1673     QPersistentModelIndex index = indexAt(bottomRight);
       
  1674     QModelIndex buddy = d->model->buddy(d->pressedIndex);
       
  1675     if ((state() == EditingState && d->hasEditor(buddy))
       
  1676         || edit(index, NoEditTriggers, event))
       
  1677         return;
       
  1678 
       
  1679     if (d->selectionMode != SingleSelection)
       
  1680         topLeft = d->pressedPosition - d->offset();
       
  1681     else
       
  1682         topLeft = bottomRight;
       
  1683 
       
  1684     d->checkMouseMove(index);
       
  1685 
       
  1686 #ifndef QT_NO_DRAGANDDROP
       
  1687     if (d->pressedIndex.isValid()
       
  1688         && d->dragEnabled
       
  1689         && (state() != DragSelectingState)
       
  1690         && (event->buttons() != Qt::NoButton)
       
  1691         && !d->selectedDraggableIndexes().isEmpty()) {
       
  1692             setState(DraggingState);
       
  1693             return;
       
  1694     }
       
  1695 #endif
       
  1696 
       
  1697     if ((event->buttons() & Qt::LeftButton) && d->selectionAllowed(index) && d->selectionModel) {
       
  1698         setState(DragSelectingState);
       
  1699         QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
       
  1700         if (d->ctrlDragSelectionFlag != QItemSelectionModel::NoUpdate && command.testFlag(QItemSelectionModel::Toggle)) {
       
  1701             command &= ~QItemSelectionModel::Toggle;
       
  1702             command |= d->ctrlDragSelectionFlag;
       
  1703         }
       
  1704 
       
  1705         // Do the normalize ourselves, since QRect::normalized() is flawed
       
  1706         QRect selectionRect = QRect(topLeft, bottomRight);
       
  1707         setSelection(selectionRect, command);
       
  1708 
       
  1709         // set at the end because it might scroll the view
       
  1710         if (index.isValid()
       
  1711             && (index != d->selectionModel->currentIndex())
       
  1712             && d->isIndexEnabled(index))
       
  1713             d->selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
       
  1714     }
       
  1715 }
       
  1716 
       
  1717 /*!
       
  1718     This function is called with the given \a event when a mouse button is released,
       
  1719     after a mouse press event on the widget. If a user presses the mouse inside your
       
  1720     widget and then drags the mouse to another location before releasing the mouse button,
       
  1721     your widget receives the release event. The function will emit the clicked() signal if an
       
  1722     item was being pressed.
       
  1723 */
       
  1724 void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event)
       
  1725 {
       
  1726     Q_D(QAbstractItemView);
       
  1727 
       
  1728     QPoint pos = event->pos();
       
  1729     QPersistentModelIndex index = indexAt(pos);
       
  1730 
       
  1731     if (state() == EditingState) {
       
  1732         if (d->isIndexValid(index)
       
  1733             && d->isIndexEnabled(index)
       
  1734             && d->sendDelegateEvent(index, event))
       
  1735             update(index);
       
  1736         return;
       
  1737     }
       
  1738 
       
  1739     bool click = (index == d->pressedIndex && index.isValid());
       
  1740     bool selectedClicked = click && (event->button() & Qt::LeftButton) && d->pressedAlreadySelected;
       
  1741     EditTrigger trigger = (selectedClicked ? SelectedClicked : NoEditTriggers);
       
  1742     bool edited = edit(index, trigger, event);
       
  1743 
       
  1744     d->ctrlDragSelectionFlag = QItemSelectionModel::NoUpdate;
       
  1745 
       
  1746     //in the case the user presses on no item we might decide to clear the selection
       
  1747     if (d->selectionModel && !index.isValid())
       
  1748         d->selectionModel->select(QModelIndex(), selectionCommand(index, event));
       
  1749 
       
  1750     setState(NoState);
       
  1751 
       
  1752     if (click) {
       
  1753         emit clicked(index);
       
  1754         if (edited)
       
  1755             return;
       
  1756         if (style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, 0, this))
       
  1757             emit activated(index);
       
  1758     }
       
  1759 }
       
  1760 
       
  1761 /*!
       
  1762     This function is called with the given \a event when a mouse button is
       
  1763     double clicked inside the widget. If the double-click is on a valid item it
       
  1764     emits the doubleClicked() signal and calls edit() on the item.
       
  1765 */
       
  1766 void QAbstractItemView::mouseDoubleClickEvent(QMouseEvent *event)
       
  1767 {
       
  1768     Q_D(QAbstractItemView);
       
  1769 
       
  1770     QModelIndex index = indexAt(event->pos());
       
  1771     if (!index.isValid()
       
  1772         || !d->isIndexEnabled(index)
       
  1773         || (d->pressedIndex != index)) {
       
  1774         QMouseEvent me(QEvent::MouseButtonPress,
       
  1775                        event->pos(), event->button(),
       
  1776                        event->buttons(), event->modifiers());
       
  1777         mousePressEvent(&me);
       
  1778         return;
       
  1779     }
       
  1780     // signal handlers may change the model
       
  1781     QPersistentModelIndex persistent = index;
       
  1782     emit doubleClicked(persistent);
       
  1783     if ((event->button() & Qt::LeftButton) && !edit(persistent, DoubleClicked, event)
       
  1784         && !style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, 0, this))
       
  1785         emit activated(persistent);
       
  1786 }
       
  1787 
       
  1788 #ifndef QT_NO_DRAGANDDROP
       
  1789 
       
  1790 /*!
       
  1791     This function is called with the given \a event when a drag and drop operation enters
       
  1792     the widget. If the drag is over a valid dropping place (e.g. over an item that
       
  1793     accepts drops), the event is accepted; otherwise it is ignored.
       
  1794 
       
  1795     \sa dropEvent() startDrag()
       
  1796 */
       
  1797 void QAbstractItemView::dragEnterEvent(QDragEnterEvent *event)
       
  1798 {
       
  1799     if (dragDropMode() == InternalMove
       
  1800         && (event->source() != this|| !(event->possibleActions() & Qt::MoveAction)))
       
  1801         return;
       
  1802 
       
  1803     if (d_func()->canDecode(event)) {
       
  1804         event->accept();
       
  1805         setState(DraggingState);
       
  1806     } else {
       
  1807         event->ignore();
       
  1808     }
       
  1809 }
       
  1810 
       
  1811 /*!
       
  1812     This function is called continuously with the given \a event during a drag and
       
  1813     drop operation over the widget. It can cause the view to scroll if, for example,
       
  1814     the user drags a selection to view's right or bottom edge. In this case, the
       
  1815     event will be accepted; otherwise it will be ignored.
       
  1816 
       
  1817     \sa dropEvent() startDrag()
       
  1818 */
       
  1819 void QAbstractItemView::dragMoveEvent(QDragMoveEvent *event)
       
  1820 {
       
  1821     Q_D(QAbstractItemView);
       
  1822     if (dragDropMode() == InternalMove
       
  1823         && (event->source() != this || !(event->possibleActions() & Qt::MoveAction)))
       
  1824         return;
       
  1825 
       
  1826     // ignore by default
       
  1827     event->ignore();
       
  1828 
       
  1829     QModelIndex index = indexAt(event->pos());
       
  1830     d->hover = index;
       
  1831     if (!d->droppingOnItself(event, index)
       
  1832         && d->canDecode(event)) {
       
  1833 
       
  1834         if (index.isValid() && d->showDropIndicator) {
       
  1835             QRect rect = visualRect(index);
       
  1836             d->dropIndicatorPosition = d->position(event->pos(), rect, index);
       
  1837             switch (d->dropIndicatorPosition) {
       
  1838             case AboveItem:
       
  1839                 if (d->isIndexDropEnabled(index.parent())) {
       
  1840                     d->dropIndicatorRect = QRect(rect.left(), rect.top(), rect.width(), 0);
       
  1841                     event->accept();
       
  1842                 } else {
       
  1843                     d->dropIndicatorRect = QRect();
       
  1844                 }
       
  1845                 break;
       
  1846             case BelowItem:
       
  1847                 if (d->isIndexDropEnabled(index.parent())) {
       
  1848                     d->dropIndicatorRect = QRect(rect.left(), rect.bottom(), rect.width(), 0);
       
  1849                     event->accept();
       
  1850                 } else {
       
  1851                     d->dropIndicatorRect = QRect();
       
  1852                 }
       
  1853                 break;
       
  1854             case OnItem:
       
  1855                 if (d->isIndexDropEnabled(index)) {
       
  1856                     d->dropIndicatorRect = rect;
       
  1857                     event->accept();
       
  1858                 } else {
       
  1859                     d->dropIndicatorRect = QRect();
       
  1860                 }
       
  1861                 break;
       
  1862             case OnViewport:
       
  1863                 d->dropIndicatorRect = QRect();
       
  1864                 if (d->isIndexDropEnabled(rootIndex())) {
       
  1865                     event->accept(); // allow dropping in empty areas
       
  1866                 }
       
  1867                 break;
       
  1868             }
       
  1869         } else {
       
  1870             d->dropIndicatorRect = QRect();
       
  1871             d->dropIndicatorPosition = OnViewport;
       
  1872             if (d->isIndexDropEnabled(rootIndex())) {
       
  1873                 event->accept(); // allow dropping in empty areas
       
  1874             }
       
  1875         }
       
  1876         d->viewport->update();
       
  1877     } // can decode
       
  1878 
       
  1879     if (d->shouldAutoScroll(event->pos()))
       
  1880         startAutoScroll();
       
  1881 }
       
  1882 
       
  1883 /*!
       
  1884     \internal
       
  1885     Return true if this is a move from ourself and \a index is a child of the selection that
       
  1886     is being moved.
       
  1887  */
       
  1888 bool QAbstractItemViewPrivate::droppingOnItself(QDropEvent *event, const QModelIndex &index)
       
  1889 {
       
  1890     Q_Q(QAbstractItemView);
       
  1891     Qt::DropAction dropAction = event->dropAction();
       
  1892     if (q->dragDropMode() == QAbstractItemView::InternalMove)
       
  1893         dropAction = Qt::MoveAction;
       
  1894     if (event->source() == q
       
  1895         && event->possibleActions() & Qt::MoveAction
       
  1896         && dropAction == Qt::MoveAction) {
       
  1897         QModelIndexList selectedIndexes = q->selectedIndexes();
       
  1898         QModelIndex child = index;
       
  1899         while (child.isValid() && child != root) {
       
  1900             if (selectedIndexes.contains(child))
       
  1901                 return true;
       
  1902             child = child.parent();
       
  1903         }
       
  1904     }
       
  1905     return false;
       
  1906 }
       
  1907 
       
  1908 /*!
       
  1909     \fn void QAbstractItemView::dragLeaveEvent(QDragLeaveEvent *event)
       
  1910 
       
  1911     This function is called when the item being dragged leaves the view.
       
  1912     The \a event describes the state of the drag and drop operation.
       
  1913 */
       
  1914 void QAbstractItemView::dragLeaveEvent(QDragLeaveEvent *)
       
  1915 {
       
  1916     Q_D(QAbstractItemView);
       
  1917     stopAutoScroll();
       
  1918     setState(NoState);
       
  1919     d->hover = QModelIndex();
       
  1920     d->viewport->update();
       
  1921 }
       
  1922 
       
  1923 /*!
       
  1924     This function is called with the given \a event when a drop event occurs over
       
  1925     the widget. If the model accepts the even position the drop event is accepted;
       
  1926     otherwise it is ignored.
       
  1927 
       
  1928     \sa startDrag()
       
  1929 */
       
  1930 void QAbstractItemView::dropEvent(QDropEvent *event)
       
  1931 {
       
  1932     Q_D(QAbstractItemView);
       
  1933     if (dragDropMode() == InternalMove) {
       
  1934         if (event->source() != this || !(event->possibleActions() & Qt::MoveAction))
       
  1935             return;
       
  1936     }
       
  1937 
       
  1938     QModelIndex index;
       
  1939     int col = -1;
       
  1940     int row = -1;
       
  1941     if (d->dropOn(event, &row, &col, &index)) {
       
  1942         if (d->model->dropMimeData(event->mimeData(),
       
  1943             dragDropMode() == InternalMove ? Qt::MoveAction : event->dropAction(), row, col, index)) {
       
  1944                 if (dragDropMode() == InternalMove)
       
  1945                     event->setDropAction(Qt::MoveAction);
       
  1946                 event->accept();
       
  1947         }
       
  1948     }
       
  1949     stopAutoScroll();
       
  1950     setState(NoState);
       
  1951     d->viewport->update();
       
  1952 }
       
  1953 
       
  1954 /*!
       
  1955     If the event hasn't already been accepted, determines the index to drop on.
       
  1956 
       
  1957     if (row == -1 && col == -1)
       
  1958         // append to this drop index
       
  1959     else
       
  1960         // place at row, col in drop index
       
  1961 
       
  1962     If it returns true a drop can be done, and dropRow, dropCol and dropIndex reflects the position of the drop.
       
  1963     \internal
       
  1964   */
       
  1965 bool QAbstractItemViewPrivate::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QModelIndex *dropIndex)
       
  1966 {
       
  1967     Q_Q(QAbstractItemView);
       
  1968     if (event->isAccepted())
       
  1969         return false;
       
  1970 
       
  1971     QModelIndex index;
       
  1972     // rootIndex() (i.e. the viewport) might be a valid index
       
  1973     if (viewport->rect().contains(event->pos())) {
       
  1974         index = q->indexAt(event->pos());
       
  1975         if (!index.isValid() || !q->visualRect(index).contains(event->pos()))
       
  1976             index = root;
       
  1977     }
       
  1978 
       
  1979     // If we are allowed to do the drop
       
  1980     if (model->supportedDropActions() & event->dropAction()) {
       
  1981         int row = -1;
       
  1982         int col = -1;
       
  1983         if (index != root) {
       
  1984             dropIndicatorPosition = position(event->pos(), q->visualRect(index), index);
       
  1985             switch (dropIndicatorPosition) {
       
  1986             case QAbstractItemView::AboveItem:
       
  1987                 row = index.row();
       
  1988                 col = index.column();
       
  1989                 index = index.parent();
       
  1990                 break;
       
  1991             case QAbstractItemView::BelowItem:
       
  1992                 row = index.row() + 1;
       
  1993                 col = index.column();
       
  1994                 index = index.parent();
       
  1995                 break;
       
  1996             case QAbstractItemView::OnItem:
       
  1997             case QAbstractItemView::OnViewport:
       
  1998                 break;
       
  1999             }
       
  2000         } else {
       
  2001             dropIndicatorPosition = QAbstractItemView::OnViewport;
       
  2002         }
       
  2003         *dropIndex = index;
       
  2004         *dropRow = row;
       
  2005         *dropCol = col;
       
  2006         if (!droppingOnItself(event, index))
       
  2007             return true;
       
  2008     }
       
  2009     return false;
       
  2010 }
       
  2011 
       
  2012 QAbstractItemView::DropIndicatorPosition
       
  2013 QAbstractItemViewPrivate::position(const QPoint &pos, const QRect &rect, const QModelIndex &index) const
       
  2014 {
       
  2015     QAbstractItemView::DropIndicatorPosition r = QAbstractItemView::OnViewport;
       
  2016     if (!overwrite) {
       
  2017         const int margin = 2;
       
  2018         if (pos.y() - rect.top() < margin) {
       
  2019             r = QAbstractItemView::AboveItem;
       
  2020         } else if (rect.bottom() - pos.y() < margin) {
       
  2021             r = QAbstractItemView::BelowItem;
       
  2022         } else if (rect.contains(pos, true)) {
       
  2023             r = QAbstractItemView::OnItem;
       
  2024         }
       
  2025     } else {
       
  2026         QRect touchingRect = rect;
       
  2027         touchingRect.adjust(-1, -1, 1, 1);
       
  2028         if (touchingRect.contains(pos, false)) {
       
  2029             r = QAbstractItemView::OnItem;
       
  2030         }
       
  2031     }
       
  2032 
       
  2033     if (r == QAbstractItemView::OnItem && (!(model->flags(index) & Qt::ItemIsDropEnabled)))
       
  2034         r = pos.y() < rect.center().y() ? QAbstractItemView::AboveItem : QAbstractItemView::BelowItem;
       
  2035 
       
  2036     return r;
       
  2037 }
       
  2038 
       
  2039 #endif // QT_NO_DRAGANDDROP
       
  2040 
       
  2041 /*!
       
  2042     This function is called with the given \a event when the widget obtains the focus.
       
  2043     By default, the event is ignored.
       
  2044 
       
  2045     \sa setFocus(), focusOutEvent()
       
  2046 */
       
  2047 void QAbstractItemView::focusInEvent(QFocusEvent *event)
       
  2048 {
       
  2049     Q_D(QAbstractItemView);
       
  2050     QAbstractScrollArea::focusInEvent(event);
       
  2051     if (selectionModel()
       
  2052         && !d->currentIndexSet
       
  2053         && !currentIndex().isValid()) {
       
  2054         bool autoScroll = d->autoScroll;
       
  2055         d->autoScroll = false;
       
  2056         QModelIndex index = moveCursor(MoveNext, Qt::NoModifier); // first visible index
       
  2057         if (index.isValid() && d->isIndexEnabled(index))
       
  2058             selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
       
  2059         d->autoScroll = autoScroll;
       
  2060     }
       
  2061     d->viewport->update();
       
  2062 }
       
  2063 
       
  2064 /*!
       
  2065     This function is called with the given \a event when the widget
       
  2066     looses the focus. By default, the event is ignored.
       
  2067 
       
  2068     \sa clearFocus(), focusInEvent()
       
  2069 */
       
  2070 void QAbstractItemView::focusOutEvent(QFocusEvent *event)
       
  2071 {
       
  2072     Q_D(QAbstractItemView);
       
  2073     QAbstractScrollArea::focusOutEvent(event);
       
  2074     d->viewport->update();
       
  2075 }
       
  2076 
       
  2077 /*!
       
  2078     This function is called with the given \a event when a key event is sent to
       
  2079     the widget. The default implementation handles basic cursor movement, e.g. Up,
       
  2080     Down, Left, Right, Home, PageUp, and PageDown; the activated() signal is
       
  2081     emitted if the current index is valid and the activation key is pressed
       
  2082     (e.g. Enter or Return, depending on the platform).
       
  2083     This function is where editing is initiated by key press, e.g. if F2 is
       
  2084     pressed.
       
  2085 
       
  2086     \sa edit(), moveCursor(), keyboardSearch(), tabKeyNavigation
       
  2087 */
       
  2088 void QAbstractItemView::keyPressEvent(QKeyEvent *event)
       
  2089 {
       
  2090     Q_D(QAbstractItemView);
       
  2091     d->delayedAutoScroll.stop(); //any interaction with the view cancel the auto scrolling
       
  2092 
       
  2093 #ifdef QT_KEYPAD_NAVIGATION
       
  2094     switch (event->key()) {
       
  2095     case Qt::Key_Select:
       
  2096         if (QApplication::keypadNavigationEnabled()) {
       
  2097             if (!hasEditFocus()) {
       
  2098                 setEditFocus(true);
       
  2099 #ifdef QT_SOFTKEYS_ENABLED
       
  2100                 addAction(d->doneSoftKey);
       
  2101 #endif
       
  2102                 return;
       
  2103             }
       
  2104         }
       
  2105         break;
       
  2106     case Qt::Key_Back:
       
  2107         if (QApplication::keypadNavigationEnabled() && hasEditFocus()) {
       
  2108 #ifdef QT_SOFTKEYS_ENABLED
       
  2109             removeAction(d->doneSoftKey);
       
  2110 #endif
       
  2111             setEditFocus(false);
       
  2112         } else {
       
  2113             event->ignore();
       
  2114         }
       
  2115         return;
       
  2116     default:
       
  2117         if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
       
  2118             event->ignore();
       
  2119             return;
       
  2120         }
       
  2121     }
       
  2122 #endif
       
  2123 
       
  2124 #if !defined(QT_NO_CLIPBOARD) && !defined(QT_NO_SHORTCUT)
       
  2125     if (event == QKeySequence::Copy) {
       
  2126         QVariant variant;
       
  2127         if (d->model)
       
  2128             variant = d->model->data(currentIndex(), Qt::DisplayRole);
       
  2129         if (variant.type() == QVariant::String)
       
  2130             QApplication::clipboard()->setText(variant.toString());
       
  2131         event->accept();
       
  2132     }
       
  2133 #endif
       
  2134 
       
  2135     QPersistentModelIndex newCurrent;
       
  2136     switch (event->key()) {
       
  2137     case Qt::Key_Down:
       
  2138         newCurrent = moveCursor(MoveDown, event->modifiers());
       
  2139         break;
       
  2140     case Qt::Key_Up:
       
  2141         newCurrent = moveCursor(MoveUp, event->modifiers());
       
  2142         break;
       
  2143     case Qt::Key_Left:
       
  2144         newCurrent = moveCursor(MoveLeft, event->modifiers());
       
  2145         break;
       
  2146     case Qt::Key_Right:
       
  2147         newCurrent = moveCursor(MoveRight, event->modifiers());
       
  2148         break;
       
  2149     case Qt::Key_Home:
       
  2150         newCurrent = moveCursor(MoveHome, event->modifiers());
       
  2151         break;
       
  2152     case Qt::Key_End:
       
  2153         newCurrent = moveCursor(MoveEnd, event->modifiers());
       
  2154         break;
       
  2155     case Qt::Key_PageUp:
       
  2156         newCurrent = moveCursor(MovePageUp, event->modifiers());
       
  2157         break;
       
  2158     case Qt::Key_PageDown:
       
  2159         newCurrent = moveCursor(MovePageDown, event->modifiers());
       
  2160         break;
       
  2161     case Qt::Key_Tab:
       
  2162         if (d->tabKeyNavigation)
       
  2163             newCurrent = moveCursor(MoveNext, event->modifiers());
       
  2164         break;
       
  2165     case Qt::Key_Backtab:
       
  2166         if (d->tabKeyNavigation)
       
  2167             newCurrent = moveCursor(MovePrevious, event->modifiers());
       
  2168         break;
       
  2169     }
       
  2170 
       
  2171     QPersistentModelIndex oldCurrent = currentIndex();
       
  2172     if (newCurrent != oldCurrent && newCurrent.isValid() && d->isIndexEnabled(newCurrent)) {
       
  2173         if (!hasFocus() && QApplication::focusWidget() == indexWidget(oldCurrent))
       
  2174             setFocus();
       
  2175         QItemSelectionModel::SelectionFlags command = selectionCommand(newCurrent, event);
       
  2176         if (command != QItemSelectionModel::NoUpdate
       
  2177              || style()->styleHint(QStyle::SH_ItemView_MovementWithoutUpdatingSelection, 0, this)) {
       
  2178             // note that we don't check if the new current index is enabled because moveCursor() makes sure it is
       
  2179             if (command & QItemSelectionModel::Current) {
       
  2180                 d->selectionModel->setCurrentIndex(newCurrent, QItemSelectionModel::NoUpdate);
       
  2181                 if (!indexAt(d->pressedPosition).isValid())
       
  2182                     d->pressedPosition = visualRect(oldCurrent).center() + d->offset();
       
  2183                 QRect rect(d->pressedPosition - d->offset(), visualRect(newCurrent).center());
       
  2184                 setSelection(rect, command);
       
  2185             } else {
       
  2186                 d->selectionModel->setCurrentIndex(newCurrent, command);
       
  2187                 d->pressedPosition = visualRect(newCurrent).center() + d->offset();
       
  2188                 // We copy the same behaviour as for mousePressEvent().
       
  2189                 QRect rect(d->pressedPosition - d->offset(), QSize(1, 1));
       
  2190                 setSelection(rect, command);
       
  2191             }
       
  2192             return;
       
  2193         }
       
  2194     }
       
  2195 
       
  2196     switch (event->key()) {
       
  2197     // ignored keys
       
  2198     case Qt::Key_Down:
       
  2199     case Qt::Key_Up:
       
  2200 #ifdef QT_KEYPAD_NAVIGATION
       
  2201         if (QApplication::keypadNavigationEnabled()) {
       
  2202             event->accept(); // don't change focus
       
  2203             break;
       
  2204         }
       
  2205 #endif
       
  2206     case Qt::Key_Left:
       
  2207     case Qt::Key_Right:
       
  2208 #ifdef QT_KEYPAD_NAVIGATION
       
  2209         if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
       
  2210             event->accept(); // don't change horizontal focus in directional mode
       
  2211             break;
       
  2212         }
       
  2213 #endif // QT_KEYPAD_NAVIGATION
       
  2214     case Qt::Key_Home:
       
  2215     case Qt::Key_End:
       
  2216     case Qt::Key_PageUp:
       
  2217     case Qt::Key_PageDown:
       
  2218     case Qt::Key_Escape:
       
  2219     case Qt::Key_Shift:
       
  2220     case Qt::Key_Control:
       
  2221         event->ignore();
       
  2222         break;
       
  2223     case Qt::Key_Space:
       
  2224     case Qt::Key_Select:
       
  2225         if (!edit(currentIndex(), AnyKeyPressed, event) && d->selectionModel)
       
  2226             d->selectionModel->select(currentIndex(), selectionCommand(currentIndex(), event));
       
  2227 #ifdef QT_KEYPAD_NAVIGATION
       
  2228         if ( event->key()==Qt::Key_Select ) {
       
  2229             // Also do Key_Enter action.
       
  2230             if (currentIndex().isValid()) {
       
  2231                 if (state() != EditingState)
       
  2232                     emit activated(currentIndex());
       
  2233             } else {
       
  2234                 event->ignore();
       
  2235             }
       
  2236         }
       
  2237 #endif
       
  2238         break;
       
  2239 #ifdef Q_WS_MAC
       
  2240     case Qt::Key_Enter:
       
  2241     case Qt::Key_Return:
       
  2242         // Propagate the enter if you couldn't edit the item and there are no
       
  2243         // current editors (if there are editors, the event was most likely propagated from it).
       
  2244         if (!edit(currentIndex(), EditKeyPressed, event) && d->editors.isEmpty())
       
  2245             event->ignore();
       
  2246         break;
       
  2247 #else
       
  2248     case Qt::Key_F2:
       
  2249         if (!edit(currentIndex(), EditKeyPressed, event))
       
  2250             event->ignore();
       
  2251         break;
       
  2252     case Qt::Key_Enter:
       
  2253     case Qt::Key_Return:
       
  2254         // ### we can't open the editor on enter, becuse
       
  2255         // some widgets will forward the enter event back
       
  2256         // to the viewport, starting an endless loop
       
  2257         if (state() != EditingState || hasFocus()) {
       
  2258             if (currentIndex().isValid())
       
  2259                 emit activated(currentIndex());
       
  2260             event->ignore();
       
  2261         }
       
  2262         break;
       
  2263 #endif
       
  2264     case Qt::Key_A:
       
  2265         if (event->modifiers() & Qt::ControlModifier) {
       
  2266             selectAll();
       
  2267             break;
       
  2268         }
       
  2269     default: {
       
  2270 #ifdef Q_WS_MAC
       
  2271         if (event->key() == Qt::Key_O && event->modifiers() & Qt::ControlModifier && currentIndex().isValid()) {
       
  2272             emit activated(currentIndex());
       
  2273             break;
       
  2274         }
       
  2275 #endif
       
  2276         bool modified = (event->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier));
       
  2277         if (!event->text().isEmpty() && !modified && !edit(currentIndex(), AnyKeyPressed, event)) {
       
  2278             keyboardSearch(event->text());
       
  2279             event->accept();
       
  2280         } else {
       
  2281             event->ignore();
       
  2282         }
       
  2283         break; }
       
  2284     }
       
  2285 }
       
  2286 
       
  2287 /*!
       
  2288     This function is called with the given \a event when a resize event is sent to
       
  2289     the widget.
       
  2290 
       
  2291     \sa QWidget::resizeEvent()
       
  2292 */
       
  2293 void QAbstractItemView::resizeEvent(QResizeEvent *event)
       
  2294 {
       
  2295     QAbstractScrollArea::resizeEvent(event);
       
  2296     updateGeometries();
       
  2297 }
       
  2298 
       
  2299 /*!
       
  2300   This function is called with the given \a event when a timer event is sent
       
  2301   to the widget.
       
  2302 
       
  2303   \sa QObject::timerEvent()
       
  2304 */
       
  2305 void QAbstractItemView::timerEvent(QTimerEvent *event)
       
  2306 {
       
  2307     Q_D(QAbstractItemView);
       
  2308     if (event->timerId() == d->fetchMoreTimer.timerId())
       
  2309         d->fetchMore();
       
  2310     else if (event->timerId() == d->delayedReset.timerId())
       
  2311         reset();
       
  2312     else if (event->timerId() == d->autoScrollTimer.timerId())
       
  2313         doAutoScroll();
       
  2314     else if (event->timerId() == d->updateTimer.timerId())
       
  2315         d->updateDirtyRegion();
       
  2316     else if (event->timerId() == d->delayedEditing.timerId()) {
       
  2317         d->delayedEditing.stop();
       
  2318         edit(currentIndex());
       
  2319     } else if (event->timerId() == d->delayedLayout.timerId()) {
       
  2320         d->delayedLayout.stop();
       
  2321         if (isVisible()) {
       
  2322             d->interruptDelayedItemsLayout();
       
  2323             doItemsLayout();
       
  2324             const QModelIndex current = currentIndex();
       
  2325             if (current.isValid() && d->state == QAbstractItemView::EditingState)
       
  2326                 scrollTo(current);
       
  2327         }
       
  2328     } else if (event->timerId() == d->delayedAutoScroll.timerId()) {
       
  2329         d->delayedAutoScroll.stop();
       
  2330         //end of the timer: if the current item is still the same as the one when the mouse press occurred
       
  2331         //we only get here if there was no double click
       
  2332         if (d->pressedIndex.isValid() && d->pressedIndex == currentIndex())
       
  2333             scrollTo(d->pressedIndex);
       
  2334     }
       
  2335 }
       
  2336 
       
  2337 /*!
       
  2338     \reimp
       
  2339 */
       
  2340 void QAbstractItemView::inputMethodEvent(QInputMethodEvent *event)
       
  2341 {
       
  2342     if (event->commitString().isEmpty() && event->preeditString().isEmpty()) {
       
  2343         event->ignore();
       
  2344         return;
       
  2345     }
       
  2346     if (!edit(currentIndex(), AnyKeyPressed, event)) {
       
  2347         if (!event->commitString().isEmpty())
       
  2348             keyboardSearch(event->commitString());
       
  2349         event->ignore();
       
  2350     }
       
  2351 }
       
  2352 
       
  2353 #ifndef QT_NO_DRAGANDDROP
       
  2354 /*!
       
  2355     \enum QAbstractItemView::DropIndicatorPosition
       
  2356 
       
  2357     This enum indicates the position of the drop indicator in
       
  2358     relation to the index at the current mouse position:
       
  2359 
       
  2360     \value OnItem  The item will be dropped on the index.
       
  2361 
       
  2362     \value AboveItem  The item will be dropped above the index.
       
  2363 
       
  2364     \value BelowItem  The item will be dropped below the index.
       
  2365 
       
  2366     \value OnViewport  The item will be dropped onto a region of the viewport with
       
  2367     no items. The way each view handles items dropped onto the viewport depends on
       
  2368     the behavior of the underlying model in use.
       
  2369 */
       
  2370 
       
  2371 
       
  2372 /*!
       
  2373     \since 4.1
       
  2374 
       
  2375     Returns the position of the drop indicator in relation to the closest item.
       
  2376 */
       
  2377 QAbstractItemView::DropIndicatorPosition QAbstractItemView::dropIndicatorPosition() const
       
  2378 {
       
  2379     Q_D(const QAbstractItemView);
       
  2380     return d->dropIndicatorPosition;
       
  2381 }
       
  2382 #endif
       
  2383 
       
  2384 /*!
       
  2385     This convenience function returns a list of all selected and
       
  2386     non-hidden item indexes in the view. The list contains no
       
  2387     duplicates, and is not sorted.
       
  2388 
       
  2389     \sa QItemSelectionModel::selectedIndexes()
       
  2390 */
       
  2391 QModelIndexList QAbstractItemView::selectedIndexes() const
       
  2392 {
       
  2393     Q_D(const QAbstractItemView);
       
  2394     QModelIndexList indexes;
       
  2395     if (d->selectionModel) {
       
  2396         indexes = d->selectionModel->selectedIndexes();
       
  2397         QList<QModelIndex>::iterator it = indexes.begin();
       
  2398         while (it != indexes.end())
       
  2399             if (isIndexHidden(*it))
       
  2400                 it = indexes.erase(it);
       
  2401             else
       
  2402                 ++it;
       
  2403     }
       
  2404     return indexes;
       
  2405 }
       
  2406 
       
  2407 /*!
       
  2408     Starts editing the item at \a index, creating an editor if
       
  2409     necessary, and returns true if the view's \l{State} is now
       
  2410     EditingState; otherwise returns false.
       
  2411 
       
  2412     The action that caused the editing process is described by
       
  2413     \a trigger, and the associated event is specified by \a event.
       
  2414 
       
  2415     Editing can be forced by specifying the \a trigger to be
       
  2416     QAbstractItemView::AllEditTriggers.
       
  2417 
       
  2418     \sa closeEditor()
       
  2419 */
       
  2420 bool QAbstractItemView::edit(const QModelIndex &index, EditTrigger trigger, QEvent *event)
       
  2421 {
       
  2422     Q_D(QAbstractItemView);
       
  2423 
       
  2424     if (!d->isIndexValid(index))
       
  2425         return false;
       
  2426 
       
  2427     if (QWidget *w = (d->persistent.isEmpty() ? static_cast<QWidget*>(0) : d->editorForIndex(index).editor.data())) {
       
  2428         if (w->focusPolicy() == Qt::NoFocus)
       
  2429             return false;
       
  2430         w->setFocus();
       
  2431         return true;
       
  2432     }
       
  2433 
       
  2434     if (trigger == DoubleClicked) {
       
  2435         d->delayedEditing.stop();
       
  2436         d->delayedAutoScroll.stop();
       
  2437     } else if (trigger == CurrentChanged) {
       
  2438         d->delayedEditing.stop();
       
  2439     }
       
  2440 
       
  2441     if (d->sendDelegateEvent(index, event)) {
       
  2442         update(index);
       
  2443         return true;
       
  2444     }
       
  2445 
       
  2446     // save the previous trigger before updating
       
  2447     EditTriggers lastTrigger = d->lastTrigger;
       
  2448     d->lastTrigger = trigger;
       
  2449 
       
  2450     if (!d->shouldEdit(trigger, d->model->buddy(index)))
       
  2451         return false;
       
  2452 
       
  2453     if (d->delayedEditing.isActive())
       
  2454         return false;
       
  2455 
       
  2456     // we will receive a mouseButtonReleaseEvent after a
       
  2457     // mouseDoubleClickEvent, so we need to check the previous trigger
       
  2458     if (lastTrigger == DoubleClicked && trigger == SelectedClicked)
       
  2459         return false;
       
  2460 
       
  2461     // we may get a double click event later
       
  2462     if (trigger == SelectedClicked)
       
  2463         d->delayedEditing.start(QApplication::doubleClickInterval(), this);
       
  2464     else
       
  2465         d->openEditor(index, d->shouldForwardEvent(trigger, event) ? event : 0);
       
  2466 
       
  2467     return true;
       
  2468 }
       
  2469 
       
  2470 /*!
       
  2471     \internal
       
  2472     Updates the data shown in the open editor widgets in the view.
       
  2473 */
       
  2474 void QAbstractItemView::updateEditorData()
       
  2475 {
       
  2476     Q_D(QAbstractItemView);
       
  2477     d->updateEditorData(QModelIndex(), QModelIndex());
       
  2478 }
       
  2479 
       
  2480 /*!
       
  2481     \internal
       
  2482     Updates the geometry of the open editor widgets in the view.
       
  2483 */
       
  2484 void QAbstractItemView::updateEditorGeometries()
       
  2485 {
       
  2486     Q_D(QAbstractItemView);
       
  2487     if(d->editors.isEmpty())
       
  2488         return;
       
  2489     QStyleOptionViewItemV4 option = d->viewOptionsV4();
       
  2490     QList<QEditorInfo>::iterator it = d->editors.begin();
       
  2491     QWidgetList editorsToRelease;
       
  2492     while (it != d->editors.end()) {
       
  2493         QModelIndex index = it->index;
       
  2494         QWidget *editor = it->editor;
       
  2495         if (index.isValid() && editor) {
       
  2496             option.rect = visualRect(index);
       
  2497             if (option.rect.isValid()) {
       
  2498                 editor->show();
       
  2499                 QAbstractItemDelegate *delegate = d->delegateForIndex(index);
       
  2500                 if (delegate)
       
  2501                     delegate->updateEditorGeometry(editor, option, index);
       
  2502             } else {
       
  2503                 editor->hide();
       
  2504             }
       
  2505             ++it;
       
  2506         } else {
       
  2507             it = d->editors.erase(it);
       
  2508             editorsToRelease << editor;
       
  2509         }
       
  2510     }
       
  2511 
       
  2512     //we release the editor outside of the loop because it might change the focus and try
       
  2513     //to change the d->editors list.
       
  2514     for (int i = 0; i < editorsToRelease.count(); ++i) {
       
  2515         d->releaseEditor(editorsToRelease.at(i));
       
  2516     }
       
  2517 }
       
  2518 
       
  2519 /*!
       
  2520     \since 4.4
       
  2521 
       
  2522     Updates the geometry of the child widgets of the view.
       
  2523 */
       
  2524 void QAbstractItemView::updateGeometries()
       
  2525 {
       
  2526     updateEditorGeometries();
       
  2527     d_func()->fetchMoreTimer.start(0, this); //fetch more later
       
  2528 }
       
  2529 
       
  2530 /*!
       
  2531     \internal
       
  2532 */
       
  2533 void QAbstractItemView::verticalScrollbarValueChanged(int value)
       
  2534 {
       
  2535     Q_D(QAbstractItemView);
       
  2536     if (verticalScrollBar()->maximum() == value && d->model->canFetchMore(d->root))
       
  2537         d->model->fetchMore(d->root);
       
  2538     d->checkMouseMove(viewport()->mapFromGlobal(QCursor::pos()));
       
  2539 }
       
  2540 
       
  2541 /*!
       
  2542     \internal
       
  2543 */
       
  2544 void QAbstractItemView::horizontalScrollbarValueChanged(int value)
       
  2545 {
       
  2546     Q_D(QAbstractItemView);
       
  2547     if (horizontalScrollBar()->maximum() == value && d->model->canFetchMore(d->root))
       
  2548         d->model->fetchMore(d->root);
       
  2549     d->checkMouseMove(viewport()->mapFromGlobal(QCursor::pos()));
       
  2550 }
       
  2551 
       
  2552 /*!
       
  2553     \internal
       
  2554 */
       
  2555 void QAbstractItemView::verticalScrollbarAction(int)
       
  2556 {
       
  2557     //do nothing
       
  2558 }
       
  2559 
       
  2560 /*!
       
  2561     \internal
       
  2562 */
       
  2563 void QAbstractItemView::horizontalScrollbarAction(int)
       
  2564 {
       
  2565     //do nothing
       
  2566 }
       
  2567 
       
  2568 /*!
       
  2569     Closes the given \a editor, and releases it. The \a hint is
       
  2570     used to specify how the view should respond to the end of the editing
       
  2571     operation. For example, the hint may indicate that the next item in
       
  2572     the view should be opened for editing.
       
  2573 
       
  2574     \sa edit(), commitData()
       
  2575 */
       
  2576 
       
  2577 void QAbstractItemView::closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint)
       
  2578 {
       
  2579     Q_D(QAbstractItemView);
       
  2580 
       
  2581     // Close the editor
       
  2582     if (editor) {
       
  2583         bool isPersistent = d->persistent.contains(editor);
       
  2584         bool hadFocus = editor->hasFocus();
       
  2585         QModelIndex index = d->indexForEditor(editor);
       
  2586         if (!index.isValid())
       
  2587             return; // the editor was not registered
       
  2588 
       
  2589         if (!isPersistent) {
       
  2590             setState(NoState);
       
  2591             QModelIndex index = d->indexForEditor(editor);
       
  2592             editor->removeEventFilter(d->delegateForIndex(index));
       
  2593             d->removeEditor(editor);
       
  2594         }
       
  2595         if (hadFocus)
       
  2596             setFocus(); // this will send a focusLost event to the editor
       
  2597         else
       
  2598             d->checkPersistentEditorFocus();
       
  2599 
       
  2600         QPointer<QWidget> ed = editor;
       
  2601         QApplication::sendPostedEvents(editor, 0);
       
  2602         editor = ed;
       
  2603 
       
  2604         if (!isPersistent && editor)
       
  2605             d->releaseEditor(editor);
       
  2606     }
       
  2607 
       
  2608     // The EndEditHint part
       
  2609     QItemSelectionModel::SelectionFlags flags = QItemSelectionModel::ClearAndSelect
       
  2610                                                 | d->selectionBehaviorFlags();
       
  2611     switch (hint) {
       
  2612     case QAbstractItemDelegate::EditNextItem: {
       
  2613         QModelIndex index = moveCursor(MoveNext, Qt::NoModifier);
       
  2614         if (index.isValid()) {
       
  2615             QPersistentModelIndex persistent(index);
       
  2616             d->selectionModel->setCurrentIndex(persistent, flags);
       
  2617             // currentChanged signal would have already started editing
       
  2618             if (index.flags() & Qt::ItemIsEditable
       
  2619                 && (!(editTriggers() & QAbstractItemView::CurrentChanged)))
       
  2620                 edit(persistent);
       
  2621         } break; }
       
  2622     case QAbstractItemDelegate::EditPreviousItem: {
       
  2623         QModelIndex index = moveCursor(MovePrevious, Qt::NoModifier);
       
  2624         if (index.isValid()) {
       
  2625             QPersistentModelIndex persistent(index);
       
  2626             d->selectionModel->setCurrentIndex(persistent, flags);
       
  2627             // currentChanged signal would have already started editing
       
  2628             if (index.flags() & Qt::ItemIsEditable
       
  2629                 && (!(editTriggers() & QAbstractItemView::CurrentChanged)))
       
  2630                 edit(persistent);
       
  2631         } break; }
       
  2632     case QAbstractItemDelegate::SubmitModelCache:
       
  2633         d->model->submit();
       
  2634         break;
       
  2635     case QAbstractItemDelegate::RevertModelCache:
       
  2636         d->model->revert();
       
  2637         break;
       
  2638     default:
       
  2639         break;
       
  2640     }
       
  2641 }
       
  2642 
       
  2643 /*!
       
  2644     Commit the data in the \a editor to the model.
       
  2645 
       
  2646     \sa closeEditor()
       
  2647 */
       
  2648 void QAbstractItemView::commitData(QWidget *editor)
       
  2649 {
       
  2650     Q_D(QAbstractItemView);
       
  2651     if (!editor || !d->itemDelegate || d->currentlyCommittingEditor)
       
  2652         return;
       
  2653     QModelIndex index = d->indexForEditor(editor);
       
  2654     if (!index.isValid())
       
  2655         return;
       
  2656     d->currentlyCommittingEditor = editor;
       
  2657     QAbstractItemDelegate *delegate = d->delegateForIndex(index);
       
  2658     editor->removeEventFilter(delegate);
       
  2659     delegate->setModelData(editor, d->model, index);
       
  2660     editor->installEventFilter(delegate);
       
  2661     d->currentlyCommittingEditor = 0;
       
  2662 }
       
  2663 
       
  2664 /*!
       
  2665     This function is called when the given \a editor has been destroyed.
       
  2666 
       
  2667     \sa closeEditor()
       
  2668 */
       
  2669 void QAbstractItemView::editorDestroyed(QObject *editor)
       
  2670 {
       
  2671     Q_D(QAbstractItemView);
       
  2672     QWidget *w = qobject_cast<QWidget*>(editor);
       
  2673     d->removeEditor(w);
       
  2674     d->persistent.remove(w);
       
  2675     if (state() == EditingState)
       
  2676         setState(NoState);
       
  2677 }
       
  2678 
       
  2679 /*!
       
  2680     \obsolete
       
  2681     Sets the horizontal scroll bar's steps per item to \a steps.
       
  2682 
       
  2683     This is the number of steps used by the horizontal scroll bar to
       
  2684     represent the width of an item.
       
  2685 
       
  2686     Note that if the view has a horizontal header, the item steps
       
  2687     will be ignored and the header section size will be used instead.
       
  2688 
       
  2689     \sa horizontalStepsPerItem() setVerticalStepsPerItem()
       
  2690 */
       
  2691 void QAbstractItemView::setHorizontalStepsPerItem(int steps)
       
  2692 {
       
  2693     Q_UNUSED(steps);
       
  2694     // do nothing
       
  2695 }
       
  2696 
       
  2697 /*!
       
  2698     \obsolete
       
  2699     Returns the horizontal scroll bar's steps per item.
       
  2700 
       
  2701     \sa setHorizontalStepsPerItem() verticalStepsPerItem()
       
  2702 */
       
  2703 int QAbstractItemView::horizontalStepsPerItem() const
       
  2704 {
       
  2705     return 1;
       
  2706 }
       
  2707 
       
  2708 /*!
       
  2709     \obsolete
       
  2710     Sets the vertical scroll bar's steps per item to \a steps.
       
  2711 
       
  2712     This is the number of steps used by the vertical scroll bar to
       
  2713     represent the height of an item.
       
  2714 
       
  2715     Note that if the view has a vertical header, the item steps
       
  2716     will be ignored and the header section size will be used instead.
       
  2717 
       
  2718     \sa verticalStepsPerItem() setHorizontalStepsPerItem()
       
  2719 */
       
  2720 void QAbstractItemView::setVerticalStepsPerItem(int steps)
       
  2721 {
       
  2722     Q_UNUSED(steps);
       
  2723     // do nothing
       
  2724 }
       
  2725 
       
  2726 /*!
       
  2727     \obsolete
       
  2728     Returns the vertical scroll bar's steps per item.
       
  2729 
       
  2730     \sa setVerticalStepsPerItem() horizontalStepsPerItem()
       
  2731 */
       
  2732 int QAbstractItemView::verticalStepsPerItem() const
       
  2733 {
       
  2734     return 1;
       
  2735 }
       
  2736 
       
  2737 /*!
       
  2738     Moves to and selects the item best matching the string \a search.
       
  2739     If no item is found nothing happens.
       
  2740 
       
  2741     In the default implementation, the search is reset if \a search is empty, or
       
  2742     the time interval since the last search has exceeded
       
  2743     QApplication::keyboardInputInterval().
       
  2744 */
       
  2745 void QAbstractItemView::keyboardSearch(const QString &search)
       
  2746 {
       
  2747     Q_D(QAbstractItemView);
       
  2748     if (!d->model->rowCount(d->root) || !d->model->columnCount(d->root))
       
  2749         return;
       
  2750 
       
  2751     QModelIndex start = currentIndex().isValid() ? currentIndex()
       
  2752                         : d->model->index(0, 0, d->root);
       
  2753     QTime now(QTime::currentTime());
       
  2754     bool skipRow = false;
       
  2755     if (search.isEmpty()
       
  2756         || (d->keyboardInputTime.msecsTo(now) > QApplication::keyboardInputInterval())) {
       
  2757         d->keyboardInput = search;
       
  2758         skipRow = currentIndex().isValid(); //if it is not valid we should really start at QModelIndex(0,0)
       
  2759     } else {
       
  2760         d->keyboardInput += search;
       
  2761     }
       
  2762     d->keyboardInputTime = now;
       
  2763 
       
  2764     // special case for searches with same key like 'aaaaa'
       
  2765     bool sameKey = false;
       
  2766     if (d->keyboardInput.length() > 1) {
       
  2767         int c = d->keyboardInput.count(d->keyboardInput.at(d->keyboardInput.length() - 1));
       
  2768         sameKey = (c == d->keyboardInput.length());
       
  2769         if (sameKey)
       
  2770             skipRow = true;
       
  2771     }
       
  2772 
       
  2773     // skip if we are searching for the same key or a new search started
       
  2774     if (skipRow) {
       
  2775         QModelIndex parent = start.parent();
       
  2776         int newRow = (start.row() < d->model->rowCount(parent) - 1) ? start.row() + 1 : 0;
       
  2777         start = d->model->index(newRow, start.column(), parent);
       
  2778     }
       
  2779 
       
  2780     // search from start with wraparound
       
  2781     const QString searchString = sameKey ? QString(d->keyboardInput.at(0)) : d->keyboardInput;
       
  2782     QModelIndex current = start;
       
  2783     QModelIndexList match;
       
  2784     QModelIndex firstMatch;
       
  2785     QModelIndex startMatch;
       
  2786     QModelIndexList previous;
       
  2787     do {
       
  2788         match = d->model->match(current, Qt::DisplayRole, searchString);
       
  2789         if (match == previous)
       
  2790             break;
       
  2791         firstMatch = match.value(0);
       
  2792         previous = match;
       
  2793         if (firstMatch.isValid()) {
       
  2794             if (d->isIndexEnabled(firstMatch)) {
       
  2795                 setCurrentIndex(firstMatch);
       
  2796                 break;
       
  2797             }
       
  2798             int row = firstMatch.row() + 1;
       
  2799             if (row >= d->model->rowCount(firstMatch.parent()))
       
  2800                 row = 0;
       
  2801             current = firstMatch.sibling(row, firstMatch.column());
       
  2802 
       
  2803             //avoid infinite loop if all the matching items are disabled.
       
  2804             if (!startMatch.isValid())
       
  2805                 startMatch = firstMatch;
       
  2806             else if (startMatch == firstMatch)
       
  2807                 break;
       
  2808         }
       
  2809     } while (current != start && firstMatch.isValid());
       
  2810 }
       
  2811 
       
  2812 /*!
       
  2813     Returns the size hint for the item with the specified \a index or
       
  2814     an invalid size for invalid indexes.
       
  2815 
       
  2816     \sa sizeHintForRow(), sizeHintForColumn()
       
  2817 */
       
  2818 QSize QAbstractItemView::sizeHintForIndex(const QModelIndex &index) const
       
  2819 {
       
  2820     Q_D(const QAbstractItemView);
       
  2821     if (!d->isIndexValid(index) || !d->itemDelegate)
       
  2822         return QSize();
       
  2823     return d->delegateForIndex(index)->sizeHint(d->viewOptionsV4(), index);
       
  2824 }
       
  2825 
       
  2826 /*!
       
  2827     Returns the height size hint for the specified \a row or -1 if
       
  2828     there is no model.
       
  2829 
       
  2830     The returned height is calculated using the size hints of the
       
  2831     given \a row's items, i.e. the returned value is the maximum
       
  2832     height among the items. Note that to control the height of a row,
       
  2833     you must reimplement the QAbstractItemDelegate::sizeHint()
       
  2834     function.
       
  2835 
       
  2836     This function is used in views with a vertical header to find the
       
  2837     size hint for a header section based on the contents of the given
       
  2838     \a row.
       
  2839 
       
  2840     \sa sizeHintForColumn()
       
  2841 */
       
  2842 int QAbstractItemView::sizeHintForRow(int row) const
       
  2843 {
       
  2844     Q_D(const QAbstractItemView);
       
  2845 
       
  2846     if (row < 0 || row >= d->model->rowCount() || !model())
       
  2847         return -1;
       
  2848 
       
  2849     QStyleOptionViewItemV4 option = d->viewOptionsV4();
       
  2850     int height = 0;
       
  2851     int colCount = d->model->columnCount(d->root);
       
  2852     QModelIndex index;
       
  2853     for (int c = 0; c < colCount; ++c) {
       
  2854         index = d->model->index(row, c, d->root);
       
  2855         if (QWidget *editor = d->editorForIndex(index).editor)
       
  2856             height = qMax(height, editor->size().height());
       
  2857         int hint = d->delegateForIndex(index)->sizeHint(option, index).height();
       
  2858         height = qMax(height, hint);
       
  2859     }
       
  2860     return height;
       
  2861 }
       
  2862 
       
  2863 /*!
       
  2864     Returns the width size hint for the specified \a column or -1 if there is no model.
       
  2865 
       
  2866     This function is used in views with a horizontal header to find the size hint for
       
  2867     a header section based on the contents of the given \a column.
       
  2868 
       
  2869     \sa sizeHintForRow()
       
  2870 */
       
  2871 int QAbstractItemView::sizeHintForColumn(int column) const
       
  2872 {
       
  2873     Q_D(const QAbstractItemView);
       
  2874 
       
  2875     if (column < 0 || column >= d->model->columnCount() || !model())
       
  2876         return -1;
       
  2877 
       
  2878     QStyleOptionViewItemV4 option = d->viewOptionsV4();
       
  2879     int width = 0;
       
  2880     int rows = d->model->rowCount(d->root);
       
  2881     QModelIndex index;
       
  2882     for (int r = 0; r < rows; ++r) {
       
  2883         index = d->model->index(r, column, d->root);
       
  2884         if (QWidget *editor = d->editorForIndex(index).editor)
       
  2885             width = qMax(width, editor->sizeHint().width());
       
  2886         int hint = d->delegateForIndex(index)->sizeHint(option, index).width();
       
  2887         width = qMax(width, hint);
       
  2888     }
       
  2889     return width;
       
  2890 }
       
  2891 
       
  2892 /*!
       
  2893     Opens a persistent editor on the item at the given \a index.
       
  2894     If no editor exists, the delegate will create a new editor.
       
  2895 
       
  2896     \sa closePersistentEditor()
       
  2897 */
       
  2898 void QAbstractItemView::openPersistentEditor(const QModelIndex &index)
       
  2899 {
       
  2900     Q_D(QAbstractItemView);
       
  2901     QStyleOptionViewItemV4 options = d->viewOptionsV4();
       
  2902     options.rect = visualRect(index);
       
  2903     options.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
       
  2904 
       
  2905     QWidget *editor = d->editor(index, options);
       
  2906     if (editor) {
       
  2907         editor->show();
       
  2908         d->persistent.insert(editor);
       
  2909     }
       
  2910 }
       
  2911 
       
  2912 /*!
       
  2913     Closes the persistent editor for the item at the given \a index.
       
  2914 
       
  2915     \sa openPersistentEditor()
       
  2916 */
       
  2917 void QAbstractItemView::closePersistentEditor(const QModelIndex &index)
       
  2918 {
       
  2919     Q_D(QAbstractItemView);
       
  2920     QWidget *editor = d->editorForIndex(index).editor;
       
  2921     if (editor) {
       
  2922         if (index == selectionModel()->currentIndex())
       
  2923             closeEditor(editor, QAbstractItemDelegate::RevertModelCache);
       
  2924         d->persistent.remove(editor);
       
  2925         d->removeEditor(editor);
       
  2926         d->releaseEditor(editor);
       
  2927     }
       
  2928 }
       
  2929 
       
  2930 /*!
       
  2931     \since 4.1
       
  2932 
       
  2933     Sets the given \a widget on the item at the given \a index, passing the
       
  2934     ownership of the widget to the viewport.
       
  2935 
       
  2936     If \a index is invalid (e.g., if you pass the root index), this function
       
  2937     will do nothing.
       
  2938 
       
  2939     The given \a widget's \l{QWidget}{autoFillBackground} property must be set
       
  2940     to true, otherwise the widget's background will be transparent, showing
       
  2941     both the model data and the item at the given \a index.
       
  2942 
       
  2943     If index widget A is replaced with index widget B, index widget A will be
       
  2944     deleted. For example, in the code snippet below, the QLineEdit object will
       
  2945     be deleted.
       
  2946 
       
  2947     \snippet doc/src/snippets/code/src_gui_itemviews_qabstractitemview.cpp 1
       
  2948 
       
  2949     This function should only be used to display static content within the
       
  2950     visible area corresponding to an item of data. If you want to display
       
  2951     custom dynamic content or implement a custom editor widget, subclass
       
  2952     QItemDelegate instead.
       
  2953 
       
  2954     \sa {Delegate Classes}
       
  2955 */
       
  2956 void QAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget)
       
  2957 {
       
  2958     Q_D(QAbstractItemView);
       
  2959     if (!d->isIndexValid(index))
       
  2960         return;
       
  2961     if (QWidget *oldWidget = indexWidget(index)) {
       
  2962         d->removeEditor(oldWidget);
       
  2963         oldWidget->deleteLater();
       
  2964     }
       
  2965     if (widget) {
       
  2966         widget->setParent(viewport());
       
  2967         d->persistent.insert(widget);
       
  2968         d->addEditor(index, widget, true);
       
  2969         widget->show();
       
  2970         dataChanged(index, index); // update the geometry
       
  2971         if (!d->delayedPendingLayout)
       
  2972             widget->setGeometry(visualRect(index));
       
  2973     }
       
  2974 }
       
  2975 
       
  2976 /*!
       
  2977     \since 4.1
       
  2978 
       
  2979     Returns the widget for the item at the given \a index.
       
  2980 */
       
  2981 QWidget* QAbstractItemView::indexWidget(const QModelIndex &index) const
       
  2982 {
       
  2983     Q_D(const QAbstractItemView);
       
  2984     if (!d->isIndexValid(index))
       
  2985         return 0;
       
  2986     return d->editorForIndex(index).editor;
       
  2987 }
       
  2988 
       
  2989 /*!
       
  2990     \since 4.1
       
  2991 
       
  2992     Scrolls the view to the top.
       
  2993 
       
  2994     \sa scrollTo(), scrollToBottom()
       
  2995 */
       
  2996 void QAbstractItemView::scrollToTop()
       
  2997 {
       
  2998     verticalScrollBar()->setValue(verticalScrollBar()->minimum());
       
  2999 }
       
  3000 
       
  3001 /*!
       
  3002     \since 4.1
       
  3003 
       
  3004     Scrolls the view to the bottom.
       
  3005 
       
  3006     \sa scrollTo(), scrollToTop()
       
  3007 */
       
  3008 void QAbstractItemView::scrollToBottom()
       
  3009 {
       
  3010     Q_D(QAbstractItemView);
       
  3011     if (d->delayedPendingLayout) {
       
  3012         d->executePostedLayout();
       
  3013         updateGeometries();
       
  3014     }
       
  3015     verticalScrollBar()->setValue(verticalScrollBar()->maximum());
       
  3016 }
       
  3017 
       
  3018 /*!
       
  3019     \since 4.3
       
  3020 
       
  3021     Updates the area occupied by the given \a index.
       
  3022 
       
  3023 */
       
  3024 void QAbstractItemView::update(const QModelIndex &index)
       
  3025 {
       
  3026     Q_D(QAbstractItemView);
       
  3027     if (index.isValid()) {
       
  3028         const QRect rect = visualRect(index);
       
  3029         //this test is important for peformance reason
       
  3030         //For example in dataChanged we simply update all the cells without checking
       
  3031         //it can be a major bottleneck to update rects that aren't even part of the viewport
       
  3032         if (d->viewport->rect().intersects(rect))
       
  3033             d->viewport->update(rect);
       
  3034     }
       
  3035 }
       
  3036 
       
  3037 /*!
       
  3038     This slot is called when items are changed in the model. The
       
  3039     changed items are those from \a topLeft to \a bottomRight
       
  3040     inclusive. If just one item is changed \a topLeft == \a
       
  3041     bottomRight.
       
  3042 */
       
  3043 void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
       
  3044 {
       
  3045     // Single item changed
       
  3046     Q_D(QAbstractItemView);
       
  3047     if (topLeft == bottomRight && topLeft.isValid()) {
       
  3048         const QEditorInfo editorInfo = d->editorForIndex(topLeft);
       
  3049         //we don't update the edit data if it is static
       
  3050         if (!editorInfo.isStatic && editorInfo.editor) {
       
  3051             QAbstractItemDelegate *delegate = d->delegateForIndex(topLeft);
       
  3052             if (delegate) {
       
  3053                 delegate->setEditorData(editorInfo.editor, topLeft);
       
  3054             }
       
  3055         }
       
  3056         if (isVisible() && !d->delayedPendingLayout) {
       
  3057             // otherwise the items will be update later anyway
       
  3058             update(topLeft);
       
  3059         }
       
  3060         return;
       
  3061     }
       
  3062     d->updateEditorData(topLeft, bottomRight);
       
  3063     if (!isVisible() || d->delayedPendingLayout)
       
  3064         return; // no need to update
       
  3065     d->viewport->update();
       
  3066 }
       
  3067 
       
  3068 /*!
       
  3069     This slot is called when rows are inserted. The new rows are those
       
  3070     under the given \a parent from \a start to \a end inclusive. The
       
  3071     base class implementation calls fetchMore() on the model to check
       
  3072     for more data.
       
  3073 
       
  3074     \sa rowsAboutToBeRemoved()
       
  3075 */
       
  3076 void QAbstractItemView::rowsInserted(const QModelIndex &, int, int)
       
  3077 {
       
  3078     if (!isVisible())
       
  3079         d_func()->fetchMoreTimer.start(0, this); //fetch more later
       
  3080     else
       
  3081         updateEditorGeometries();
       
  3082 }
       
  3083 
       
  3084 /*!
       
  3085     This slot is called when rows are about to be removed. The deleted rows are
       
  3086     those under the given \a parent from \a start to \a end inclusive.
       
  3087 
       
  3088     \sa rowsInserted()
       
  3089 */
       
  3090 void QAbstractItemView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
       
  3091 {
       
  3092     Q_D(QAbstractItemView);
       
  3093 
       
  3094     setState(CollapsingState);
       
  3095 
       
  3096     // Ensure one selected item in single selection mode.
       
  3097     QModelIndex current = currentIndex();
       
  3098     if (d->selectionMode == SingleSelection
       
  3099         && current.isValid()
       
  3100         && current.row() >= start
       
  3101         && current.row() <= end
       
  3102         && current.parent() == parent) {
       
  3103         int totalToRemove = end - start + 1;
       
  3104         if (d->model->rowCount(parent) <= totalToRemove) { // no more children
       
  3105             QModelIndex index = parent;
       
  3106             while (index != d->root && !d->isIndexEnabled(index))
       
  3107                 index = index.parent();
       
  3108             if (index != d->root)
       
  3109                 setCurrentIndex(index);
       
  3110         } else {
       
  3111             int row = end + 1;
       
  3112             QModelIndex next;
       
  3113             do { // find the next visible and enabled item
       
  3114                 next = d->model->index(row++, current.column(), current.parent());
       
  3115             } while (next.isValid() && (isIndexHidden(next) || !d->isIndexEnabled(next)));
       
  3116             if (row > d->model->rowCount(parent)) {
       
  3117                 row = start - 1;
       
  3118                 do { // find the previous visible and enabled item
       
  3119                     next = d->model->index(row--, current.column(), current.parent());
       
  3120                 } while (next.isValid() && (isIndexHidden(next) || !d->isIndexEnabled(next)));
       
  3121             }
       
  3122             setCurrentIndex(next);
       
  3123         }
       
  3124     }
       
  3125 
       
  3126     // Remove all affected editors; this is more efficient than waiting for updateGeometries() to clean out editors for invalid indexes
       
  3127     for (int i = d->editors.size() - 1; i >= 0; --i) {
       
  3128         const QModelIndex index = d->editors.at(i).index;
       
  3129         QWidget *editor = d->editors.at(i).editor;
       
  3130         if (index.row() >= start && index.row() <= end && d->model->parent(index) == parent) {
       
  3131             d->editors.removeAt(i);
       
  3132             d->releaseEditor(editor);
       
  3133         }
       
  3134     }
       
  3135 }
       
  3136 
       
  3137 /*!
       
  3138     \internal
       
  3139 
       
  3140     This slot is called when rows have been removed. The deleted
       
  3141     rows are those under the given \a parent from \a start to \a end
       
  3142     inclusive.
       
  3143 */
       
  3144 void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &, int, int)
       
  3145 {
       
  3146     Q_Q(QAbstractItemView);
       
  3147     if (q->isVisible())
       
  3148         q->updateEditorGeometries();
       
  3149     q->setState(QAbstractItemView::NoState);
       
  3150 }
       
  3151 
       
  3152 /*!
       
  3153     \internal
       
  3154 
       
  3155     This slot is called when columns are about to be removed. The deleted
       
  3156     columns are those under the given \a parent from \a start to \a end
       
  3157     inclusive.
       
  3158 */
       
  3159 void QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
       
  3160 {
       
  3161     Q_Q(QAbstractItemView);
       
  3162 
       
  3163     q->setState(QAbstractItemView::CollapsingState);
       
  3164 
       
  3165     // Ensure one selected item in single selection mode.
       
  3166     QModelIndex current = q->currentIndex();
       
  3167     if (current.isValid()
       
  3168         && selectionMode == QAbstractItemView::SingleSelection
       
  3169         && current.column() >= start
       
  3170         && current.column() <= end) {
       
  3171         int totalToRemove = end - start + 1;
       
  3172         if (model->columnCount(parent) < totalToRemove) { // no more columns
       
  3173             QModelIndex index = parent;
       
  3174             while (index.isValid() && !isIndexEnabled(index))
       
  3175                 index = index.parent();
       
  3176             if (index.isValid())
       
  3177                 q->setCurrentIndex(index);
       
  3178         } else {
       
  3179             int column = end;
       
  3180             QModelIndex next;
       
  3181             do { // find the next visible and enabled item
       
  3182                 next = model->index(current.row(), column++, current.parent());
       
  3183             } while (next.isValid() && (q->isIndexHidden(next) || !isIndexEnabled(next)));
       
  3184             q->setCurrentIndex(next);
       
  3185         }
       
  3186     }
       
  3187 
       
  3188     // Remove all affected editors; this is more efficient than waiting for updateGeometries() to clean out editors for invalid indexes
       
  3189     QList<QEditorInfo>::iterator it = editors.begin();
       
  3190     while (it != editors.end()) {
       
  3191         QModelIndex index = it->index;
       
  3192         if (index.column() <= start && index.column() >= end && model->parent(index) == parent) {
       
  3193             QWidget *editor = it->editor;
       
  3194             it = editors.erase(it);
       
  3195             releaseEditor(editor);
       
  3196         } else {
       
  3197             ++it;
       
  3198         }
       
  3199     }
       
  3200 }
       
  3201 
       
  3202 /*!
       
  3203     \internal
       
  3204 
       
  3205     This slot is called when columns have been removed. The deleted
       
  3206     rows are those under the given \a parent from \a start to \a end
       
  3207     inclusive.
       
  3208 */
       
  3209 void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &, int, int)
       
  3210 {
       
  3211     Q_Q(QAbstractItemView);
       
  3212     if (q->isVisible())
       
  3213         q->updateEditorGeometries();
       
  3214     q->setState(QAbstractItemView::NoState);
       
  3215 }
       
  3216 
       
  3217 /*!
       
  3218     \internal
       
  3219 
       
  3220     This slot is called when rows have been inserted.
       
  3221 */
       
  3222 void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &, int, int)
       
  3223 {
       
  3224     Q_Q(QAbstractItemView);
       
  3225     if (q->isVisible())
       
  3226         q->updateEditorGeometries();
       
  3227 }
       
  3228 
       
  3229 
       
  3230 
       
  3231 /*!
       
  3232     \internal
       
  3233 */
       
  3234 void QAbstractItemViewPrivate::_q_modelDestroyed()
       
  3235 {
       
  3236     model = QAbstractItemModelPrivate::staticEmptyModel();
       
  3237     doDelayedReset();
       
  3238 }
       
  3239 
       
  3240 /*!
       
  3241     \internal
       
  3242 
       
  3243     This slot is called when the layout is changed.
       
  3244 */
       
  3245 void QAbstractItemViewPrivate::_q_layoutChanged()
       
  3246 {
       
  3247     doDelayedItemsLayout();
       
  3248 }
       
  3249 
       
  3250 /*!
       
  3251     This slot is called when the selection is changed. The previous
       
  3252     selection (which may be empty), is specified by \a deselected, and the
       
  3253     new selection by \a selected.
       
  3254 
       
  3255     \sa setSelection()
       
  3256 */
       
  3257 void QAbstractItemView::selectionChanged(const QItemSelection &selected,
       
  3258                                          const QItemSelection &deselected)
       
  3259 {
       
  3260     Q_D(QAbstractItemView);
       
  3261     if (isVisible() && updatesEnabled()) {
       
  3262         d->viewport->update(visualRegionForSelection(deselected) | visualRegionForSelection(selected));
       
  3263     }
       
  3264 }
       
  3265 
       
  3266 /*!
       
  3267     This slot is called when a new item becomes the current item.
       
  3268     The previous current item is specified by the \a previous index, and the new
       
  3269     item by the \a current index.
       
  3270 
       
  3271     If you want to know about changes to items see the
       
  3272     dataChanged() signal.
       
  3273 */
       
  3274 void QAbstractItemView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
       
  3275 {
       
  3276     Q_D(QAbstractItemView);
       
  3277     Q_ASSERT(d->model);
       
  3278 
       
  3279     if (previous.isValid()) {
       
  3280         QModelIndex buddy = d->model->buddy(previous);
       
  3281         QWidget *editor = d->editorForIndex(buddy).editor;
       
  3282         if (editor && !d->persistent.contains(editor)) {
       
  3283             commitData(editor);
       
  3284             if (current.row() != previous.row())
       
  3285                 closeEditor(editor, QAbstractItemDelegate::SubmitModelCache);
       
  3286             else
       
  3287                 closeEditor(editor, QAbstractItemDelegate::NoHint);
       
  3288         }
       
  3289         if (isVisible()) {
       
  3290             update(previous);
       
  3291         }
       
  3292     }
       
  3293 
       
  3294     if (current.isValid() && !d->autoScrollTimer.isActive()) {
       
  3295         if (isVisible()) {
       
  3296             if (d->autoScroll)
       
  3297                 scrollTo(current);
       
  3298             update(current);
       
  3299             edit(current, CurrentChanged, 0);
       
  3300             if (current.row() == (d->model->rowCount(d->root) - 1))
       
  3301                 d->fetchMore();
       
  3302         } else {
       
  3303             d->shouldScrollToCurrentOnShow = d->autoScroll;
       
  3304         }
       
  3305     }
       
  3306 }
       
  3307 
       
  3308 #ifndef QT_NO_DRAGANDDROP
       
  3309 /*!
       
  3310     Starts a drag by calling drag->exec() using the given \a supportedActions.
       
  3311 */
       
  3312 void QAbstractItemView::startDrag(Qt::DropActions supportedActions)
       
  3313 {
       
  3314     Q_D(QAbstractItemView);
       
  3315     QModelIndexList indexes = d->selectedDraggableIndexes();
       
  3316     if (indexes.count() > 0) {
       
  3317         QMimeData *data = d->model->mimeData(indexes);
       
  3318         if (!data)
       
  3319             return;
       
  3320         QRect rect;
       
  3321         QPixmap pixmap = d->renderToPixmap(indexes, &rect);
       
  3322         rect.adjust(horizontalOffset(), verticalOffset(), 0, 0);
       
  3323         QDrag *drag = new QDrag(this);
       
  3324         drag->setPixmap(pixmap);
       
  3325         drag->setMimeData(data);
       
  3326         drag->setHotSpot(d->pressedPosition - rect.topLeft());
       
  3327         Qt::DropAction defaultDropAction = Qt::IgnoreAction;
       
  3328         if (d->defaultDropAction != Qt::IgnoreAction && (supportedActions & d->defaultDropAction))
       
  3329             defaultDropAction = d->defaultDropAction;
       
  3330         else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
       
  3331             defaultDropAction = Qt::CopyAction;
       
  3332         if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction)
       
  3333             d->clearOrRemove();
       
  3334     }
       
  3335 }
       
  3336 #endif // QT_NO_DRAGANDDROP
       
  3337 
       
  3338 /*!
       
  3339     Returns a QStyleOptionViewItem structure populated with the view's
       
  3340     palette, font, state, alignments etc.
       
  3341 */
       
  3342 QStyleOptionViewItem QAbstractItemView::viewOptions() const
       
  3343 {
       
  3344     Q_D(const QAbstractItemView);
       
  3345     QStyleOptionViewItem option;
       
  3346     option.init(this);
       
  3347     option.state &= ~QStyle::State_MouseOver;
       
  3348     option.font = font();
       
  3349 
       
  3350 #ifndef Q_WS_MAC
       
  3351     // On mac the focus appearance follows window activation
       
  3352     // not widget activation
       
  3353     if (!hasFocus())
       
  3354         option.state &= ~QStyle::State_Active;
       
  3355 #endif
       
  3356 
       
  3357     option.state &= ~QStyle::State_HasFocus;
       
  3358     if (d->iconSize.isValid()) {
       
  3359         option.decorationSize = d->iconSize;
       
  3360     } else {
       
  3361         int pm = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
       
  3362         option.decorationSize = QSize(pm, pm);
       
  3363     }
       
  3364     option.decorationPosition = QStyleOptionViewItem::Left;
       
  3365     option.decorationAlignment = Qt::AlignCenter;
       
  3366     option.displayAlignment = Qt::AlignLeft|Qt::AlignVCenter;
       
  3367     option.textElideMode = d->textElideMode;
       
  3368     option.rect = QRect();
       
  3369     option.showDecorationSelected = style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, 0, this);
       
  3370     return option;
       
  3371 }
       
  3372 
       
  3373 QStyleOptionViewItemV4 QAbstractItemViewPrivate::viewOptionsV4() const
       
  3374 {
       
  3375     Q_Q(const QAbstractItemView);
       
  3376     QStyleOptionViewItemV4 option = q->viewOptions();
       
  3377     if (wrapItemText)
       
  3378         option.features = QStyleOptionViewItemV2::WrapText;
       
  3379     option.locale = q->locale();
       
  3380     option.locale.setNumberOptions(QLocale::OmitGroupSeparator);
       
  3381     option.widget = q;
       
  3382     return option;
       
  3383 }
       
  3384 
       
  3385 /*!
       
  3386     Returns the item view's state.
       
  3387 
       
  3388     \sa setState()
       
  3389 */
       
  3390 QAbstractItemView::State QAbstractItemView::state() const
       
  3391 {
       
  3392     Q_D(const QAbstractItemView);
       
  3393     return d->state;
       
  3394 }
       
  3395 
       
  3396 /*!
       
  3397     Sets the item view's state to the given \a state.
       
  3398 
       
  3399     \sa state()
       
  3400 */
       
  3401 void QAbstractItemView::setState(State state)
       
  3402 {
       
  3403     Q_D(QAbstractItemView);
       
  3404     d->state = state;
       
  3405 }
       
  3406 
       
  3407 /*!
       
  3408   Schedules a layout of the items in the view to be executed when the
       
  3409   event processing starts.
       
  3410 
       
  3411   Even if scheduleDelayedItemsLayout() is called multiple times before
       
  3412   events are processed, the view will only do the layout once.
       
  3413 
       
  3414   \sa executeDelayedItemsLayout()
       
  3415 */
       
  3416 void QAbstractItemView::scheduleDelayedItemsLayout()
       
  3417 {
       
  3418     Q_D(QAbstractItemView);
       
  3419     d->doDelayedItemsLayout();
       
  3420 }
       
  3421 
       
  3422 /*!
       
  3423   Executes the scheduled layouts without waiting for the event processing
       
  3424   to begin.
       
  3425 
       
  3426   \sa scheduleDelayedItemsLayout()
       
  3427 */
       
  3428 void QAbstractItemView::executeDelayedItemsLayout()
       
  3429 {
       
  3430     Q_D(QAbstractItemView);
       
  3431     d->executePostedLayout();
       
  3432 }
       
  3433 
       
  3434 /*!
       
  3435     \since 4.1
       
  3436 
       
  3437     Marks the given \a region as dirty and schedules it to be updated.
       
  3438     You only need to call this function if you are implementing
       
  3439     your own view subclass.
       
  3440 
       
  3441     \sa scrollDirtyRegion(), dirtyRegionOffset()
       
  3442 */
       
  3443 
       
  3444 void QAbstractItemView::setDirtyRegion(const QRegion &region)
       
  3445 {
       
  3446     Q_D(QAbstractItemView);
       
  3447     d->setDirtyRegion(region);
       
  3448 }
       
  3449 
       
  3450 /*!
       
  3451     Prepares the view for scrolling by (\a{dx},\a{dy}) pixels by moving the dirty regions in the
       
  3452     opposite direction. You only need to call this function if you are implementing a scrolling
       
  3453     viewport in your view subclass.
       
  3454 
       
  3455     If you implement scrollContentsBy() in a subclass of QAbstractItemView, call this function
       
  3456     before you call QWidget::scroll() on the viewport. Alternatively, just call update().
       
  3457 
       
  3458     \sa scrollContentsBy(), dirtyRegionOffset(), setDirtyRegion()
       
  3459 */
       
  3460 void QAbstractItemView::scrollDirtyRegion(int dx, int dy)
       
  3461 {
       
  3462     Q_D(QAbstractItemView);
       
  3463     d->scrollDirtyRegion(dx, dy);
       
  3464 }
       
  3465 
       
  3466 /*!
       
  3467     Returns the offset of the dirty regions in the view.
       
  3468 
       
  3469     If you use scrollDirtyRegion() and implement a paintEvent() in a subclass of
       
  3470     QAbstractItemView, you should translate the area given by the paint event with
       
  3471     the offset returned from this function.
       
  3472 
       
  3473     \sa scrollDirtyRegion(), setDirtyRegion()
       
  3474 */
       
  3475 QPoint QAbstractItemView::dirtyRegionOffset() const
       
  3476 {
       
  3477     Q_D(const QAbstractItemView);
       
  3478     return d->scrollDelayOffset;
       
  3479 }
       
  3480 
       
  3481 /*!
       
  3482   \internal
       
  3483 */
       
  3484 void QAbstractItemView::startAutoScroll()
       
  3485 {
       
  3486     d_func()->startAutoScroll();
       
  3487 }
       
  3488 
       
  3489 /*!
       
  3490   \internal
       
  3491 */
       
  3492 void QAbstractItemView::stopAutoScroll()
       
  3493 {
       
  3494     d_func()->stopAutoScroll();
       
  3495 }
       
  3496 
       
  3497 /*!
       
  3498   \internal
       
  3499 */
       
  3500 void QAbstractItemView::doAutoScroll()
       
  3501 {
       
  3502     // find how much we should scroll with
       
  3503     Q_D(QAbstractItemView);
       
  3504     int verticalStep = verticalScrollBar()->pageStep();
       
  3505     int horizontalStep = horizontalScrollBar()->pageStep();
       
  3506     if (d->autoScrollCount < qMax(verticalStep, horizontalStep))
       
  3507         ++d->autoScrollCount;
       
  3508 
       
  3509     int margin = d->autoScrollMargin;
       
  3510     int verticalValue = verticalScrollBar()->value();
       
  3511     int horizontalValue = horizontalScrollBar()->value();
       
  3512 
       
  3513     QPoint pos = d->viewport->mapFromGlobal(QCursor::pos());
       
  3514     QRect area = static_cast<QAbstractItemView*>(d->viewport)->d_func()->clipRect(); // access QWidget private by bending C++ rules
       
  3515 
       
  3516     // do the scrolling if we are in the scroll margins
       
  3517     if (pos.y() - area.top() < margin)
       
  3518         verticalScrollBar()->setValue(verticalValue - d->autoScrollCount);
       
  3519     else if (area.bottom() - pos.y() < margin)
       
  3520         verticalScrollBar()->setValue(verticalValue + d->autoScrollCount);
       
  3521     if (pos.x() - area.left() < margin)
       
  3522         horizontalScrollBar()->setValue(horizontalValue - d->autoScrollCount);
       
  3523     else if (area.right() - pos.x() < margin)
       
  3524         horizontalScrollBar()->setValue(horizontalValue + d->autoScrollCount);
       
  3525     // if nothing changed, stop scrolling
       
  3526     bool verticalUnchanged = (verticalValue == verticalScrollBar()->value());
       
  3527     bool horizontalUnchanged = (horizontalValue == horizontalScrollBar()->value());
       
  3528     if (verticalUnchanged && horizontalUnchanged) {
       
  3529         stopAutoScroll();
       
  3530     } else {
       
  3531 #ifndef QT_NO_DRAGANDDROP
       
  3532         d->dropIndicatorRect = QRect();
       
  3533         d->dropIndicatorPosition = QAbstractItemView::OnViewport;
       
  3534 #endif
       
  3535         d->viewport->update();
       
  3536     }
       
  3537 }
       
  3538 
       
  3539 /*!
       
  3540     Returns the SelectionFlags to be used when updating a selection with
       
  3541     to include the \a index specified. The \a event is a user input event,
       
  3542     such as a mouse or keyboard event.
       
  3543 
       
  3544     Reimplement this function to define your own selection behavior.
       
  3545 
       
  3546     \sa setSelection()
       
  3547 */
       
  3548 QItemSelectionModel::SelectionFlags QAbstractItemView::selectionCommand(const QModelIndex &index,
       
  3549                                                                         const QEvent *event) const
       
  3550 {
       
  3551     Q_D(const QAbstractItemView);
       
  3552     switch (d->selectionMode) {
       
  3553         case NoSelection: // Never update selection model
       
  3554             return QItemSelectionModel::NoUpdate;
       
  3555         case SingleSelection: // ClearAndSelect on valid index otherwise NoUpdate
       
  3556             if (event && event->type() == QEvent::MouseButtonRelease)
       
  3557                 return QItemSelectionModel::NoUpdate;
       
  3558             return QItemSelectionModel::ClearAndSelect|d->selectionBehaviorFlags();
       
  3559         case MultiSelection:
       
  3560             return d->multiSelectionCommand(index, event);
       
  3561         case ExtendedSelection:
       
  3562             return d->extendedSelectionCommand(index, event);
       
  3563         case ContiguousSelection:
       
  3564             return d->contiguousSelectionCommand(index, event);
       
  3565     }
       
  3566     return QItemSelectionModel::NoUpdate;
       
  3567 }
       
  3568 
       
  3569 QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::multiSelectionCommand(
       
  3570     const QModelIndex &index, const QEvent *event) const
       
  3571 {
       
  3572     Q_UNUSED(index);
       
  3573 
       
  3574     if (event) {
       
  3575         switch (event->type()) {
       
  3576         case QEvent::KeyPress:
       
  3577             if (static_cast<const QKeyEvent*>(event)->key() == Qt::Key_Space
       
  3578              || static_cast<const QKeyEvent*>(event)->key() == Qt::Key_Select)
       
  3579                 return QItemSelectionModel::Toggle|selectionBehaviorFlags();
       
  3580             break;
       
  3581         case QEvent::MouseButtonPress:
       
  3582             if (static_cast<const QMouseEvent*>(event)->button() == Qt::LeftButton)
       
  3583                 return QItemSelectionModel::Toggle|selectionBehaviorFlags(); // toggle
       
  3584             break;
       
  3585         case QEvent::MouseButtonRelease:
       
  3586             if (static_cast<const QMouseEvent*>(event)->button() == Qt::LeftButton)
       
  3587                 return QItemSelectionModel::NoUpdate|selectionBehaviorFlags(); // finalize
       
  3588             break;
       
  3589         case QEvent::MouseMove:
       
  3590             if (static_cast<const QMouseEvent*>(event)->buttons() & Qt::LeftButton)
       
  3591                 return QItemSelectionModel::ToggleCurrent|selectionBehaviorFlags(); // toggle drag select
       
  3592         default:
       
  3593             break;
       
  3594         }
       
  3595         return QItemSelectionModel::NoUpdate;
       
  3596     }
       
  3597 
       
  3598     return QItemSelectionModel::Toggle|selectionBehaviorFlags();
       
  3599 }
       
  3600 
       
  3601 QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::extendedSelectionCommand(
       
  3602     const QModelIndex &index, const QEvent *event) const
       
  3603 {
       
  3604     Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
       
  3605     if (event) {
       
  3606         switch (event->type()) {
       
  3607         case QEvent::MouseMove: {
       
  3608             // Toggle on MouseMove
       
  3609             modifiers = static_cast<const QMouseEvent*>(event)->modifiers();
       
  3610             if (modifiers & Qt::ControlModifier)
       
  3611                 return QItemSelectionModel::ToggleCurrent|selectionBehaviorFlags();
       
  3612             break;
       
  3613         }
       
  3614         case QEvent::MouseButtonPress: {
       
  3615             modifiers = static_cast<const QMouseEvent*>(event)->modifiers();
       
  3616             const Qt::MouseButton button = static_cast<const QMouseEvent*>(event)->button();
       
  3617             const bool rightButtonPressed = button & Qt::RightButton;
       
  3618             const bool shiftKeyPressed = modifiers & Qt::ShiftModifier;
       
  3619             const bool controlKeyPressed = modifiers & Qt::ControlModifier;
       
  3620             const bool indexIsSelected = selectionModel->isSelected(index);
       
  3621             if ((shiftKeyPressed || controlKeyPressed) && rightButtonPressed)
       
  3622                 return QItemSelectionModel::NoUpdate;
       
  3623             if (!shiftKeyPressed && !controlKeyPressed && indexIsSelected)
       
  3624                 return QItemSelectionModel::NoUpdate;
       
  3625             if (!index.isValid() && !rightButtonPressed && !shiftKeyPressed && !controlKeyPressed)
       
  3626                 return QItemSelectionModel::Clear;
       
  3627             if (!index.isValid())
       
  3628                 return QItemSelectionModel::NoUpdate;
       
  3629             break;
       
  3630         }
       
  3631         case QEvent::MouseButtonRelease: {
       
  3632             // ClearAndSelect on MouseButtonRelease if MouseButtonPress on selected item or empty area
       
  3633             modifiers = static_cast<const QMouseEvent*>(event)->modifiers();
       
  3634             const Qt::MouseButton button = static_cast<const QMouseEvent*>(event)->button();
       
  3635             const bool rightButtonPressed = button & Qt::RightButton;
       
  3636             const bool shiftKeyPressed = modifiers & Qt::ShiftModifier;
       
  3637             const bool controlKeyPressed = modifiers & Qt::ControlModifier;
       
  3638             if (((index == pressedIndex && selectionModel->isSelected(index))
       
  3639                 || !index.isValid()) && state != QAbstractItemView::DragSelectingState
       
  3640                 && !shiftKeyPressed && !controlKeyPressed && !rightButtonPressed)
       
  3641                 return QItemSelectionModel::ClearAndSelect|selectionBehaviorFlags();
       
  3642             return QItemSelectionModel::NoUpdate;
       
  3643         }
       
  3644         case QEvent::KeyPress: {
       
  3645             // NoUpdate on Key movement and Ctrl
       
  3646             modifiers = static_cast<const QKeyEvent*>(event)->modifiers();
       
  3647             switch (static_cast<const QKeyEvent*>(event)->key()) {
       
  3648             case Qt::Key_Backtab:
       
  3649                 modifiers = modifiers & ~Qt::ShiftModifier; // special case for backtab
       
  3650             case Qt::Key_Down:
       
  3651             case Qt::Key_Up:
       
  3652             case Qt::Key_Left:
       
  3653             case Qt::Key_Right:
       
  3654             case Qt::Key_Home:
       
  3655             case Qt::Key_End:
       
  3656             case Qt::Key_PageUp:
       
  3657             case Qt::Key_PageDown:
       
  3658             case Qt::Key_Tab:
       
  3659                 if (modifiers & Qt::ControlModifier
       
  3660 #ifdef QT_KEYPAD_NAVIGATION
       
  3661                     // Preserve historical tab order navigation behavior
       
  3662                     || QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
       
  3663 #endif
       
  3664                     )
       
  3665                     return QItemSelectionModel::NoUpdate;
       
  3666                 break;
       
  3667             case Qt::Key_Select:
       
  3668                 return QItemSelectionModel::Toggle|selectionBehaviorFlags();
       
  3669             case Qt::Key_Space:// Toggle on Ctrl-Qt::Key_Space, Select on Space
       
  3670                 if (modifiers & Qt::ControlModifier)
       
  3671                     return QItemSelectionModel::Toggle|selectionBehaviorFlags();
       
  3672                 return QItemSelectionModel::Select|selectionBehaviorFlags();
       
  3673             default:
       
  3674                 break;
       
  3675             }
       
  3676         }
       
  3677         default:
       
  3678             break;
       
  3679         }
       
  3680     }
       
  3681 
       
  3682     if (modifiers & Qt::ShiftModifier)
       
  3683         return QItemSelectionModel::SelectCurrent|selectionBehaviorFlags();
       
  3684     if (modifiers & Qt::ControlModifier)
       
  3685         return QItemSelectionModel::Toggle|selectionBehaviorFlags();
       
  3686     if (state == QAbstractItemView::DragSelectingState) {
       
  3687         //when drag-selecting we need to clear any previous selection and select the current one
       
  3688         return QItemSelectionModel::Clear|QItemSelectionModel::SelectCurrent|selectionBehaviorFlags();
       
  3689     }
       
  3690 
       
  3691     return QItemSelectionModel::ClearAndSelect|selectionBehaviorFlags();
       
  3692 }
       
  3693 
       
  3694 QItemSelectionModel::SelectionFlags
       
  3695 QAbstractItemViewPrivate::contiguousSelectionCommand(const QModelIndex &index,
       
  3696                                                      const QEvent *event) const
       
  3697 {
       
  3698     QItemSelectionModel::SelectionFlags flags = extendedSelectionCommand(index, event);
       
  3699     const int Mask = QItemSelectionModel::Clear | QItemSelectionModel::Select
       
  3700                      | QItemSelectionModel::Deselect | QItemSelectionModel::Toggle
       
  3701                      | QItemSelectionModel::Current;
       
  3702 
       
  3703     switch (flags & Mask) {
       
  3704     case QItemSelectionModel::Clear:
       
  3705     case QItemSelectionModel::ClearAndSelect:
       
  3706     case QItemSelectionModel::SelectCurrent:
       
  3707         return flags;
       
  3708     case QItemSelectionModel::NoUpdate:
       
  3709         if (event &&
       
  3710             (event->type() == QEvent::MouseButtonPress
       
  3711              || event->type() == QEvent::MouseButtonRelease))
       
  3712             return flags;
       
  3713         return QItemSelectionModel::ClearAndSelect|selectionBehaviorFlags();
       
  3714     default:
       
  3715         return QItemSelectionModel::SelectCurrent|selectionBehaviorFlags();
       
  3716     }
       
  3717 }
       
  3718 
       
  3719 void QAbstractItemViewPrivate::fetchMore()
       
  3720 {
       
  3721     fetchMoreTimer.stop();
       
  3722     if (!model->canFetchMore(root))
       
  3723         return;
       
  3724     int last = model->rowCount(root) - 1;
       
  3725     if (last < 0) {
       
  3726         model->fetchMore(root);
       
  3727         return;
       
  3728     }
       
  3729 
       
  3730     QModelIndex index = model->index(last, 0, root);
       
  3731     QRect rect = q_func()->visualRect(index);
       
  3732     if (viewport->rect().intersects(rect))
       
  3733         model->fetchMore(root);
       
  3734 }
       
  3735 
       
  3736 bool QAbstractItemViewPrivate::shouldEdit(QAbstractItemView::EditTrigger trigger,
       
  3737                                           const QModelIndex &index) const
       
  3738 {
       
  3739     if (!index.isValid())
       
  3740         return false;
       
  3741     Qt::ItemFlags flags = model->flags(index);
       
  3742     if (((flags & Qt::ItemIsEditable) == 0) || ((flags & Qt::ItemIsEnabled) == 0))
       
  3743         return false;
       
  3744     if (state == QAbstractItemView::EditingState)
       
  3745         return false;
       
  3746     if (hasEditor(index))
       
  3747         return false;
       
  3748     if (trigger == QAbstractItemView::AllEditTriggers) // force editing
       
  3749         return true;
       
  3750     if ((trigger & editTriggers) == QAbstractItemView::SelectedClicked
       
  3751         && !selectionModel->isSelected(index))
       
  3752         return false;
       
  3753     return (trigger & editTriggers);
       
  3754 }
       
  3755 
       
  3756 bool QAbstractItemViewPrivate::shouldForwardEvent(QAbstractItemView::EditTrigger trigger,
       
  3757                                                   const QEvent *event) const
       
  3758 {
       
  3759     if (!event || (trigger & editTriggers) != QAbstractItemView::AnyKeyPressed)
       
  3760         return false;
       
  3761 
       
  3762     switch (event->type()) {
       
  3763         case QEvent::KeyPress:
       
  3764         case QEvent::MouseButtonDblClick:
       
  3765         case QEvent::MouseButtonPress:
       
  3766         case QEvent::MouseButtonRelease:
       
  3767         case QEvent::MouseMove:
       
  3768             return true;
       
  3769         default:
       
  3770             break;
       
  3771     };
       
  3772 
       
  3773     return false;
       
  3774 }
       
  3775 
       
  3776 bool QAbstractItemViewPrivate::shouldAutoScroll(const QPoint &pos) const
       
  3777 {
       
  3778     if (!autoScroll)
       
  3779         return false;
       
  3780     QRect area = static_cast<QAbstractItemView*>(viewport)->d_func()->clipRect(); // access QWidget private by bending C++ rules
       
  3781     return (pos.y() - area.top() < autoScrollMargin)
       
  3782         || (area.bottom() - pos.y() < autoScrollMargin)
       
  3783         || (pos.x() - area.left() < autoScrollMargin)
       
  3784         || (area.right() - pos.x() < autoScrollMargin);
       
  3785 }
       
  3786 
       
  3787 void QAbstractItemViewPrivate::doDelayedItemsLayout(int delay)
       
  3788 {
       
  3789     if (!delayedPendingLayout) {
       
  3790         delayedPendingLayout = true;
       
  3791         delayedLayout.start(delay, q_func());
       
  3792     }
       
  3793 }
       
  3794 
       
  3795 void QAbstractItemViewPrivate::interruptDelayedItemsLayout() const
       
  3796 {
       
  3797     delayedLayout.stop();
       
  3798     delayedPendingLayout = false;
       
  3799 }
       
  3800 
       
  3801 
       
  3802 
       
  3803 QWidget *QAbstractItemViewPrivate::editor(const QModelIndex &index,
       
  3804                                           const QStyleOptionViewItem &options)
       
  3805 {
       
  3806     Q_Q(QAbstractItemView);
       
  3807     QWidget *w = editorForIndex(index).editor;
       
  3808     if (!w) {
       
  3809         QAbstractItemDelegate *delegate = delegateForIndex(index);
       
  3810         if (!delegate)
       
  3811             return 0;
       
  3812         w = delegate->createEditor(viewport, options, index);
       
  3813         if (w) {
       
  3814             w->installEventFilter(delegate);
       
  3815             QObject::connect(w, SIGNAL(destroyed(QObject*)), q, SLOT(editorDestroyed(QObject*)));
       
  3816             delegate->updateEditorGeometry(w, options, index);
       
  3817             delegate->setEditorData(w, index);
       
  3818             addEditor(index, w, false);
       
  3819             if (w->parent() == viewport)
       
  3820                 QWidget::setTabOrder(q, w);
       
  3821 
       
  3822             // Special cases for some editors containing QLineEdit
       
  3823             QWidget *focusWidget = w;
       
  3824             while (QWidget *fp = focusWidget->focusProxy())
       
  3825                 focusWidget = fp;
       
  3826 #ifndef QT_NO_LINEEDIT
       
  3827             if (QLineEdit *le = qobject_cast<QLineEdit*>(focusWidget))
       
  3828                 le->selectAll();
       
  3829 #endif
       
  3830 #ifndef QT_NO_SPINBOX
       
  3831             if (QSpinBox *sb = qobject_cast<QSpinBox*>(focusWidget))
       
  3832                 sb->selectAll();
       
  3833             else if (QDoubleSpinBox *dsb = qobject_cast<QDoubleSpinBox*>(focusWidget))
       
  3834                 dsb->selectAll();
       
  3835 #endif
       
  3836         }
       
  3837     }
       
  3838     return w;
       
  3839 }
       
  3840 
       
  3841 void QAbstractItemViewPrivate::updateEditorData(const QModelIndex &tl, const QModelIndex &br)
       
  3842 {
       
  3843     // we are counting on having relatively few editors
       
  3844     const bool checkIndexes = tl.isValid() && br.isValid();
       
  3845     const QModelIndex parent = tl.parent();
       
  3846     QList<QEditorInfo>::const_iterator it = editors.constBegin();
       
  3847     for (; it != editors.constEnd(); ++it) {
       
  3848         QWidget *editor = it->editor;
       
  3849         const QModelIndex index = it->index;
       
  3850         if (it->isStatic || editor == 0 || !index.isValid() ||
       
  3851             (checkIndexes
       
  3852                 && (index.row() < tl.row() || index.row() > br.row()
       
  3853                     || index.column() < tl.column() || index.column() > br.column()
       
  3854                     || index.parent() != parent)))
       
  3855             continue;
       
  3856 
       
  3857         QAbstractItemDelegate *delegate = delegateForIndex(index);
       
  3858         if (delegate) {
       
  3859             delegate->setEditorData(editor, index);
       
  3860         }
       
  3861     }
       
  3862 }
       
  3863 
       
  3864 /*!
       
  3865     \internal
       
  3866 
       
  3867     In DND if something has been moved then this is called.
       
  3868     Typically this means you should "remove" the selected item or row,
       
  3869     but the behavior is view dependant (table just clears the selected indexes for example).
       
  3870 
       
  3871     Either remove the selected rows or clear them
       
  3872 */
       
  3873 void QAbstractItemViewPrivate::clearOrRemove()
       
  3874 {
       
  3875 #ifndef QT_NO_DRAGANDDROP
       
  3876     const QItemSelection selection = selectionModel->selection();
       
  3877     QList<QItemSelectionRange>::const_iterator it = selection.constBegin();
       
  3878 
       
  3879     if (!overwrite) {
       
  3880         for (; it != selection.constEnd(); ++it) {
       
  3881             QModelIndex parent = (*it).parent();
       
  3882             if ((*it).left() != 0)
       
  3883                 continue;
       
  3884             if ((*it).right() != (model->columnCount(parent) - 1))
       
  3885                 continue;
       
  3886             int count = (*it).bottom() - (*it).top() + 1;
       
  3887             model->removeRows((*it).top(), count, parent);
       
  3888         }
       
  3889     } else {
       
  3890         // we can't remove the rows so reset the items (i.e. the view is like a table)
       
  3891         QModelIndexList list = selection.indexes();
       
  3892         for (int i=0; i < list.size(); ++i) {
       
  3893             QModelIndex index = list.at(i);
       
  3894             QMap<int, QVariant> roles = model->itemData(index);
       
  3895             for (QMap<int, QVariant>::Iterator it = roles.begin(); it != roles.end(); ++it)
       
  3896                 it.value() = QVariant();
       
  3897             model->setItemData(index, roles);
       
  3898         }
       
  3899     }
       
  3900 #endif
       
  3901 }
       
  3902 
       
  3903 /*!
       
  3904     \internal
       
  3905 
       
  3906     When persistent aeditor gets/loses focus, we need to check
       
  3907     and setcorrectly the current index.
       
  3908 */
       
  3909 void QAbstractItemViewPrivate::checkPersistentEditorFocus()
       
  3910 {
       
  3911     Q_Q(QAbstractItemView);
       
  3912     if (QWidget *widget = QApplication::focusWidget()) {
       
  3913         if (persistent.contains(widget)) {
       
  3914             //a persistent editor has gained the focus
       
  3915             QModelIndex index = indexForEditor(widget);
       
  3916             if (selectionModel->currentIndex() != index)
       
  3917                 q->setCurrentIndex(index);
       
  3918         }
       
  3919     }
       
  3920 }
       
  3921 
       
  3922 
       
  3923 QEditorInfo QAbstractItemViewPrivate::editorForIndex(const QModelIndex &index) const
       
  3924 {
       
  3925     QList<QEditorInfo>::const_iterator it = editors.constBegin();
       
  3926     for (; it != editors.constEnd(); ++it) {
       
  3927         if (it->index == index)
       
  3928             return *it;
       
  3929     }
       
  3930 
       
  3931     return QEditorInfo();
       
  3932 }
       
  3933 
       
  3934 QModelIndex QAbstractItemViewPrivate::indexForEditor(QWidget *editor) const
       
  3935 {
       
  3936     QList<QEditorInfo>::const_iterator it = editors.constBegin();
       
  3937     for (; it != editors.constEnd(); ++it) {
       
  3938         if (it->editor == editor)
       
  3939             return it->index;
       
  3940     }
       
  3941     return QModelIndex();
       
  3942 }
       
  3943 
       
  3944 void QAbstractItemViewPrivate::removeEditor(QWidget *editor)
       
  3945 {
       
  3946     QList<QEditorInfo>::iterator it = editors.begin();
       
  3947     for (; it != editors.end(); ) {
       
  3948         if (it->editor == editor)
       
  3949             it = editors.erase(it);
       
  3950         else
       
  3951             ++it;
       
  3952     }
       
  3953 }
       
  3954 
       
  3955 void QAbstractItemViewPrivate::addEditor(const QModelIndex &index, QWidget *editor, bool isStatic)
       
  3956 {
       
  3957     editors.append(QEditorInfo(index, editor, isStatic));
       
  3958 }
       
  3959 
       
  3960 bool QAbstractItemViewPrivate::sendDelegateEvent(const QModelIndex &index, QEvent *event) const
       
  3961 {
       
  3962     Q_Q(const QAbstractItemView);
       
  3963     QModelIndex buddy = model->buddy(index);
       
  3964     QStyleOptionViewItemV4 options = viewOptionsV4();
       
  3965     options.rect = q->visualRect(buddy);
       
  3966     options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
       
  3967     QAbstractItemDelegate *delegate = delegateForIndex(index);
       
  3968     return (event && delegate && delegate->editorEvent(event, model, options, buddy));
       
  3969 }
       
  3970 
       
  3971 bool QAbstractItemViewPrivate::openEditor(const QModelIndex &index, QEvent *event)
       
  3972 {
       
  3973     Q_Q(QAbstractItemView);
       
  3974 
       
  3975     QModelIndex buddy = model->buddy(index);
       
  3976     QStyleOptionViewItemV4 options = viewOptionsV4();
       
  3977     options.rect = q->visualRect(buddy);
       
  3978     options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
       
  3979 
       
  3980     QWidget *w = editor(buddy, options);
       
  3981     if (!w)
       
  3982         return false;
       
  3983 
       
  3984     if (event)
       
  3985         QApplication::sendEvent(w->focusProxy() ? w->focusProxy() : w, event);
       
  3986 
       
  3987     q->setState(QAbstractItemView::EditingState);
       
  3988     w->show();
       
  3989     w->setFocus();
       
  3990 
       
  3991     return true;
       
  3992 }
       
  3993 
       
  3994 /*
       
  3995     \internal
       
  3996 
       
  3997     returns the pair QRect/QModelIndex that should be painted on the viewports's rect
       
  3998 */
       
  3999 
       
  4000 QItemViewPaintPairs QAbstractItemViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const
       
  4001 {
       
  4002     Q_ASSERT(r);
       
  4003     Q_Q(const QAbstractItemView);
       
  4004     QRect &rect = *r;
       
  4005     const QRect viewportRect = viewport->rect();
       
  4006     QItemViewPaintPairs ret;
       
  4007     for (int i = 0; i < indexes.count(); ++i) {
       
  4008         const QModelIndex &index = indexes.at(i);
       
  4009         const QRect current = q->visualRect(index);
       
  4010         if (current.intersects(viewportRect)) {
       
  4011             ret += qMakePair(current, index);
       
  4012             rect |= current;
       
  4013         }
       
  4014     }
       
  4015     rect &= viewportRect;
       
  4016     return ret;
       
  4017 }
       
  4018 
       
  4019 QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, QRect *r) const
       
  4020 {
       
  4021     Q_ASSERT(r);
       
  4022     QItemViewPaintPairs paintPairs = draggablePaintPairs(indexes, r);
       
  4023     if (paintPairs.isEmpty())
       
  4024         return QPixmap();
       
  4025     QPixmap pixmap(r->size());
       
  4026     pixmap.fill(Qt::transparent);
       
  4027     QPainter painter(&pixmap);
       
  4028     QStyleOptionViewItemV4 option = viewOptionsV4();
       
  4029     option.state |= QStyle::State_Selected;
       
  4030     for (int j = 0; j < paintPairs.count(); ++j) {
       
  4031         option.rect = paintPairs.at(j).first.translated(-r->topLeft());
       
  4032         const QModelIndex &current = paintPairs.at(j).second;
       
  4033         delegateForIndex(current)->paint(&painter, option, current);
       
  4034     }
       
  4035     return pixmap;
       
  4036 }
       
  4037 
       
  4038 void QAbstractItemViewPrivate::selectAll(QItemSelectionModel::SelectionFlags command)
       
  4039 {
       
  4040     if (!selectionModel)
       
  4041         return;
       
  4042 
       
  4043     QItemSelection selection;
       
  4044     QModelIndex tl = model->index(0, 0, root);
       
  4045     QModelIndex br = model->index(model->rowCount(root) - 1,
       
  4046                                   model->columnCount(root) - 1,
       
  4047                                   root);
       
  4048     selection.append(QItemSelectionRange(tl, br));
       
  4049     selectionModel->select(selection, command);
       
  4050 }
       
  4051 
       
  4052 QModelIndexList QAbstractItemViewPrivate::selectedDraggableIndexes() const
       
  4053 {
       
  4054     Q_Q(const QAbstractItemView);
       
  4055     QModelIndexList indexes = q->selectedIndexes();
       
  4056     for(int i = indexes.count() - 1 ; i >= 0; --i) {
       
  4057         if (!isIndexDragEnabled(indexes.at(i)))
       
  4058             indexes.removeAt(i);
       
  4059     }
       
  4060     return indexes;
       
  4061 }
       
  4062 
       
  4063 
       
  4064 QT_END_NAMESPACE
       
  4065 
       
  4066 #include "moc_qabstractitemview.cpp"
       
  4067 
       
  4068 #endif // QT_NO_ITEMVIEWS