Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
67 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/itemviews/qabstractitemdelegate.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6262
    6363    \ingroup model-view
    64     \mainclass
     64
    6565
    6666    A QAbstractItemDelegate provides the interface and common functionality
  • trunk/src/gui/itemviews/qabstractitemdelegate.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qabstractitemview.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6262#include <qaccessible.h>
    6363#endif
     64#include <private/qsoftkeymanager_p.h>
    6465
    6566QT_BEGIN_NAMESPACE
     
    6970        itemDelegate(0),
    7071        selectionModel(0),
     72        ctrlDragSelectionFlag(QItemSelectionModel::NoUpdate),
     73        noSelectionOnMousePress(false),
    7174        selectionMode(QAbstractItemView::ExtendedSelection),
    7275        selectionBehavior(QAbstractItemView::SelectItems),
     
    7477        pressedModifiers(Qt::NoModifier),
    7578        pressedPosition(QPoint(-1, -1)),
     79        pressedAlreadySelected(false),
    7680        viewportEnteredNeeded(false),
    7781        state(QAbstractItemView::NoState),
     
    8589        overwrite(false),
    8690        dropIndicatorPosition(QAbstractItemView::OnItem),
     91        defaultDropAction(Qt::IgnoreAction),
     92#endif
     93#ifdef QT_SOFTKEYS_ENABLED
     94        doneSoftKey(0),
    8795#endif
    8896        autoScroll(true),
    8997        autoScrollMargin(16),
    9098        autoScrollCount(0),
     99        shouldScrollToCurrentOnShow(false),
     100        shouldClearStatusTip(false),
    91101        alternatingColors(false),
    92102        textElideMode(Qt::ElideRight),
     
    108118    q->setItemDelegate(new QStyledItemDelegate(q));
    109119
    110     q->verticalScrollBar()->setRange(0, 0);
    111     q->horizontalScrollBar()->setRange(0, 0);
    112 
    113     QObject::connect(q->verticalScrollBar(), SIGNAL(actionTriggered(int)),
     120    vbar->setRange(0, 0);
     121    hbar->setRange(0, 0);
     122
     123    QObject::connect(vbar, SIGNAL(actionTriggered(int)),
    114124                     q, SLOT(verticalScrollbarAction(int)));
    115     QObject::connect(q->horizontalScrollBar(), SIGNAL(actionTriggered(int)),
     125    QObject::connect(hbar, SIGNAL(actionTriggered(int)),
    116126                     q, SLOT(horizontalScrollbarAction(int)));
    117     QObject::connect(q->verticalScrollBar(), SIGNAL(valueChanged(int)),
     127    QObject::connect(vbar, SIGNAL(valueChanged(int)),
    118128                     q, SLOT(verticalScrollbarValueChanged(int)));
    119     QObject::connect(q->horizontalScrollBar(), SIGNAL(valueChanged(int)),
     129    QObject::connect(hbar, SIGNAL(valueChanged(int)),
    120130                     q, SLOT(horizontalScrollbarValueChanged(int)));
    121131
     
    125135
    126136    q->setAttribute(Qt::WA_InputMethodEnabled);
    127 }
     137
     138#ifdef QT_SOFTKEYS_ENABLED
     139    doneSoftKey = QSoftKeyManager::createKeyedAction(QSoftKeyManager::DoneSoftKey, Qt::Key_Back, q);
     140#endif
     141}
     142
     143void QAbstractItemViewPrivate::setHoverIndex(const QPersistentModelIndex &index)
     144{
     145    Q_Q(QAbstractItemView);
     146    if (hover == index)
     147        return;
     148
     149    q->update(hover); //update the old one
     150    hover = index;
     151    q->update(hover); //update the new one
     152}
     153
     154void QAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index)
     155{
     156    //we take a persistent model index because the model might change by emitting signals
     157    Q_Q(QAbstractItemView);
     158    setHoverIndex(index);
     159    if (viewportEnteredNeeded || enteredIndex != index) {
     160        viewportEnteredNeeded = false;
     161
     162        if (index.isValid()) {
     163            emit q->entered(index);
     164#ifndef QT_NO_STATUSTIP
     165            QString statustip = model->data(index, Qt::StatusTipRole).toString();
     166            if (parent && (shouldClearStatusTip || !statustip.isEmpty())) {
     167                QStatusTipEvent tip(statustip);
     168                QApplication::sendEvent(parent, &tip);
     169                shouldClearStatusTip = !statustip.isEmpty();
     170            }
     171#endif
     172        } else {
     173#ifndef QT_NO_STATUSTIP
     174            if (parent && shouldClearStatusTip) {
     175                QString emptyString;
     176                QStatusTipEvent tip( emptyString );
     177                QApplication::sendEvent(parent, &tip);
     178            }
     179#endif
     180            emit q->viewportEntered();
     181        }
     182        enteredIndex = index;
     183    }
     184}
     185
    128186
    129187/*!
     
    134192
    135193    \ingroup model-view
    136     \mainclass
     194
    137195
    138196    QAbstractItemView class is the base class for every standard view
     
    143201    changes to their models.  This class provides standard support for
    144202    keyboard and mouse navigation, viewport scrolling, item editing,
    145     and selections.
     203    and selections. The keyboard navigation implements this
     204    functionality:
     205
     206    \table
     207        \header
     208            \o Keys
     209            \o Functionality
     210        \row
     211            \o Arrow keys
     212            \o Changes the current item and selects it.
     213        \row
     214            \o Ctrl+Arrow keys
     215            \o Changes the current item but does not select it.
     216        \row
     217            \o Shift+Arrow keys
     218            \o Changes the current item and selects it. The previously
     219               selected item(s) is not deselected.
     220        \row
     221            \o Ctr+Space
     222            \o Toggles selection of the current item.
     223        \row
     224            \o Tab/Backtab
     225            \o Changes the current item to the next/previous item.
     226        \row
     227            \o Home/End
     228            \o Selects the first/last item in the model.
     229        \row
     230            \o Page up/Page down
     231            \o Scrolls the rows shown up/down by the number of
     232               visible rows in the view.
     233        \row
     234            \o Ctrl+A
     235            \o Selects all items in the model.
     236    \endtable
     237
     238    Note that the above table assumes that the
     239    \l{selectionMode}{selection mode} allows the operations. For
     240    instance, you cannot select items if the selection mode is
     241    QAbstractItemView::NoSelection.
    146242
    147243    The QAbstractItemView class is one of the \l{Model/View Classes}
     
    525621        disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
    526622                   this, SLOT(dataChanged(QModelIndex,QModelIndex)));
     623        disconnect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
     624                   this, SLOT(_q_headerDataChanged()));
    527625        disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
    528626                   this, SLOT(rowsInserted(QModelIndex,int,int)));
     
    552650               "The parent of a top level index should be invalid");
    553651
    554     if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
     652    if (d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
    555653        connect(d->model, SIGNAL(destroyed()),
    556654                this, SLOT(_q_modelDestroyed()));
    557655        connect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
    558656                this, SLOT(dataChanged(QModelIndex,QModelIndex)));
     657        connect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
     658                this, SLOT(_q_headerDataChanged()));
    559659        connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
    560660                this, SLOT(rowsInserted(QModelIndex,int,int)));
     
    671771    }
    672772
    673 
    674773    if (delegate) {
    675774        if (d->delegateRefCount(delegate) == 0) {
     
    682781    }
    683782    d->itemDelegate = delegate;
     783    viewport()->update();
    684784}
    685785
     
    746846        d->rowDelegates.insert(row, delegate);
    747847    }
     848    viewport()->update();
    748849}
    749850
     
    802903        d->columnDelegates.insert(column, delegate);
    803904    }
     905    viewport()->update();
    804906}
    805907
     
    820922
    821923/*!
    822    Returns the item delegate used by this view and model for
    823    the given \a index.
     924    Returns the item delegate used by this view and model for
     925    the given \a index.
    824926*/
    825927QAbstractItemDelegate *QAbstractItemView::itemDelegate(const QModelIndex &index) const
     
    830932
    831933/*!
    832   \property QAbstractItemView::selectionMode
    833   \brief which selection mode the view operates in
    834 
    835   This property controls whether the user can select one or many items
    836   and, in many-item selections, whether the selection must be a
    837   continuous range of items.
    838 
    839   \sa SelectionMode SelectionBehavior
     934    \property QAbstractItemView::selectionMode
     935    \brief which selection mode the view operates in
     936
     937    This property controls whether the user can select one or many items
     938    and, in many-item selections, whether the selection must be a
     939    continuous range of items.
     940
     941    \sa SelectionMode SelectionBehavior
    840942*/
    841943void QAbstractItemView::setSelectionMode(SelectionMode mode)
     
    852954
    853955/*!
    854   \property QAbstractItemView::selectionBehavior
    855   \brief which selection behavior the view uses
    856 
    857   This property holds whether selections are done
    858   in terms of single items, rows or columns.
    859 
    860   \sa SelectionMode SelectionBehavior
     956    \property QAbstractItemView::selectionBehavior
     957    \brief which selection behavior the view uses
     958
     959    This property holds whether selections are done
     960    in terms of single items, rows or columns.
     961
     962    \sa SelectionMode SelectionBehavior
    861963*/
    862964
     
    875977/*!
    876978    Sets the current item to be the item at \a index.
    877     Depending on the current selection mode, the item may also be selected.
     979
     980    Unless the current selection mode is
     981    \l{QAbstractItemView::}{NoSelection}, the item is also be selected.
    878982    Note that this function also updates the starting position for any
    879983    new selections the user performs.
     
    9211025{
    9221026    Q_D(QAbstractItemView);
     1027    d->delayedReset.stop(); //make sure we stop the timer
    9231028    QList<QEditorInfo>::const_iterator it = d->editors.constBegin();
    9241029    for (; it != d->editors.constEnd(); ++it)
     
    9291034    setState(NoState);
    9301035    setRootIndex(QModelIndex());
     1036    if (d->selectionModel)
     1037        d->selectionModel->reset();
    9311038}
    9321039
     
    9591066
    9601067/*!
    961   Selects all item in the view.
    962   This function wil use the selection selection behavior
    963   set on the view when selecting.
    964 
    965   \sa setSelection(), selectedIndexes(), clearSelection()
     1068    Selects all items in the view.
     1069    This function will use the selection behavior
     1070    set on the view when selecting.
     1071
     1072    \sa setSelection(), selectedIndexes(), clearSelection()
    9661073*/
    9671074void QAbstractItemView::selectAll()
     
    11921299#ifndef QT_NO_DRAGANDDROP
    11931300/*!
    1194   \property QAbstractItemView::showDropIndicator
    1195   \brief whether the drop indicator is shown when dragging items and dropping.
    1196 
    1197   \sa dragEnabled DragDropMode dragDropOverwriteMode acceptDrops
     1301    \property QAbstractItemView::showDropIndicator
     1302    \brief whether the drop indicator is shown when dragging items and dropping.
     1303
     1304    \sa dragEnabled DragDropMode dragDropOverwriteMode acceptDrops
    11981305*/
    11991306
     
    12111318
    12121319/*!
    1213   \property QAbstractItemView::dragEnabled
    1214   \brief whether the view supports dragging of its own items
    1215 
    1216   \sa showDropIndicator DragDropMode dragDropOverwriteMode acceptDrops
     1320    \property QAbstractItemView::dragEnabled
     1321    \brief whether the view supports dragging of its own items
     1322
     1323    \sa showDropIndicator DragDropMode dragDropOverwriteMode acceptDrops
    12171324*/
    12181325
     
    12501357
    12511358/*!
    1252   \property QAbstractItemView::dragDropMode
    1253   \brief the drag and drop event the view will act upon
    1254 
    1255   \since 4.2
    1256   \sa showDropIndicator dragDropOverwriteMode
     1359    \property QAbstractItemView::dragDropMode
     1360    \brief the drag and drop event the view will act upon
     1361
     1362    \since 4.2
     1363    \sa showDropIndicator dragDropOverwriteMode
    12571364*/
    12581365void QAbstractItemView::setDragDropMode(DragDropMode behavior)
     
    12871394}
    12881395
     1396/*!
     1397    \property QAbstractItemView::defaultDropAction
     1398    \brief the drop action that will be used by default in QAbstractItemView::drag()
     1399
     1400    If the property is not set, the drop action is CopyAction when the supported
     1401    actions support CopyAction.
     1402
     1403    \since 4.6
     1404    \sa showDropIndicator dragDropOverwriteMode
     1405*/
     1406void QAbstractItemView::setDefaultDropAction(Qt::DropAction dropAction)
     1407{
     1408    Q_D(QAbstractItemView);
     1409    d->defaultDropAction = dropAction;
     1410}
     1411
     1412Qt::DropAction QAbstractItemView::defaultDropAction() const
     1413{
     1414    Q_D(const QAbstractItemView);
     1415    return d->defaultDropAction;
     1416}
     1417
    12891418#endif // QT_NO_DRAGANDDROP
    12901419
    12911420/*!
    1292   \property QAbstractItemView::alternatingRowColors
    1293   \brief whether to draw the background using alternating colors
    1294 
    1295   If this property is true, the item background will be drawn using
    1296   QPalette::Base and QPalette::AlternateBase; otherwise the background
    1297   will be drawn using the QPalette::Base color.
    1298 
    1299   By default, this property is false.
     1421    \property QAbstractItemView::alternatingRowColors
     1422    \brief whether to draw the background using alternating colors
     1423
     1424    If this property is true, the item background will be drawn using
     1425    QPalette::Base and QPalette::AlternateBase; otherwise the background
     1426    will be drawn using the QPalette::Base color.
     1427
     1428    By default, this property is false.
    13001429*/
    13011430void QAbstractItemView::setAlternatingRowColors(bool enable)
     
    13381467    \property QAbstractItemView::textElideMode
    13391468
    1340     \brief the the position of the "..." in elided text.
     1469    \brief the position of the "..." in elided text.
    13411470
    13421471    The default value for all item views is Qt::ElideRight.
     
    13811510        break;
    13821511    case QEvent::Show:
    1383         {
    1384             d->executePostedLayout(); //make sure we set the layout properly
     1512        d->executePostedLayout(); //make sure we set the layout properly
     1513        if (d->shouldScrollToCurrentOnShow) {
     1514            d->shouldScrollToCurrentOnShow = false;
    13851515            const QModelIndex current = currentIndex();
    13861516            if (current.isValid() && (d->state == QAbstractItemView::EditingState || d->autoScroll))
     
    14011531        d->checkPersistentEditorFocus();
    14021532        break;
     1533    case QEvent::FontChange:
     1534        d->doDelayedItemsLayout(); // the size of the items will change
     1535        break;
    14031536    default:
    14041537        break;
     
    14191552    Q_D(QAbstractItemView);
    14201553    switch (event->type()) {
    1421     case QEvent::HoverEnter: {
    1422         QHoverEvent *he = static_cast<QHoverEvent*>(event);
    1423         d->hover = indexAt(he->pos());
    1424         d->viewport->update(visualRect(d->hover));
    1425         break; }
    1426     case QEvent::HoverLeave: {
    1427         d->viewport->update(visualRect(d->hover)); // update old
    1428         d->hover = QModelIndex();
    1429         break; }
    1430     case QEvent::HoverMove: {
    1431         QHoverEvent *he = static_cast<QHoverEvent*>(event);
    1432         QModelIndex old = d->hover;
    1433         d->hover = indexAt(he->pos());
    1434         if (d->hover != old)
    1435             d->viewport->update(visualRect(old)|visualRect(d->hover));
    1436         break; }
     1554    case QEvent::HoverMove:
     1555    case QEvent::HoverEnter:
     1556        d->setHoverIndex(indexAt(static_cast<QHoverEvent*>(event)->pos()));
     1557        break;
     1558    case QEvent::HoverLeave:
     1559        d->setHoverIndex(QModelIndex());
     1560        break;
    14371561    case QEvent::Enter:
    14381562        d->viewportEnteredNeeded = true;
    14391563        break;
    14401564    case QEvent::Leave:
     1565    #ifndef QT_NO_STATUSTIP
     1566        if (d->shouldClearStatusTip && d->parent) {
     1567            QString empty;
     1568            QStatusTipEvent tip(empty);
     1569            QApplication::sendEvent(d->parent, &tip);
     1570            d->shouldClearStatusTip = false;
     1571        }
     1572    #endif
    14411573        d->enteredIndex = QModelIndex();
    14421574        break;
     
    14921624    d->pressedModifiers = event->modifiers();
    14931625    QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
     1626    d->noSelectionOnMousePress = command == QItemSelectionModel::NoUpdate || !index.isValid();
    14941627    QPoint offset = d->offset();
    14951628    if ((command & QItemSelectionModel::Current) == 0)
    14961629        d->pressedPosition = pos + offset;
    1497 
    1498     if (d->pressedPosition == QPoint(-1, -1))
     1630    else if (!indexAt(d->pressedPosition - offset).isValid())
    14991631        d->pressedPosition = visualRect(currentIndex()).center() + offset;
    15001632
     
    15101642        d->autoScroll = autoScroll;
    15111643        QRect rect(d->pressedPosition - offset, pos);
     1644        if (command.testFlag(QItemSelectionModel::Toggle)) {
     1645            command &= ~QItemSelectionModel::Toggle;
     1646            d->ctrlDragSelectionFlag = d->selectionModel->isSelected(index) ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
     1647            command |= d->ctrlDragSelectionFlag;
     1648        }
    15121649        setSelection(rect, command);
    15131650
     
    15531690#endif // QT_NO_DRAGANDDROP
    15541691
    1555     QModelIndex index = indexAt(bottomRight);
     1692    QPersistentModelIndex index = indexAt(bottomRight);
    15561693    QModelIndex buddy = d->model->buddy(d->pressedIndex);
    15571694    if ((state() == EditingState && d->hasEditor(buddy))
     
    15641701        topLeft = bottomRight;
    15651702
    1566     if (d->viewportEnteredNeeded || d->enteredIndex != index) {
    1567         d->viewportEnteredNeeded = false;
    1568 
    1569         // signal handlers may change the model
    1570         QPersistentModelIndex persistent = index;
    1571         if (persistent.isValid()) {
    1572             emit entered(persistent);
    1573 #ifndef QT_NO_STATUSTIP
    1574             QString statustip = d->model->data(persistent, Qt::StatusTipRole).toString();
    1575             if (parent() && !statustip.isEmpty()) {
    1576                 QStatusTipEvent tip(statustip);
    1577                 QApplication::sendEvent(parent(), &tip);
    1578             }
    1579 #endif
    1580         } else {
    1581 #ifndef QT_NO_STATUSTIP
    1582             if (parent()) {
    1583                 QString emptyString;
    1584                 QStatusTipEvent tip(emptyString);
    1585                 QApplication::sendEvent(parent(), &tip);
    1586             }
    1587 #endif
    1588             emit viewportEntered();
    1589         }
    1590         d->enteredIndex = persistent;
    1591         index = persistent;
    1592     }
     1703    d->checkMouseMove(index);
    15931704
    15941705#ifndef QT_NO_DRAGANDDROP
    1595     if (index.isValid()
     1706    if (d->pressedIndex.isValid()
    15961707        && d->dragEnabled
    15971708        && (state() != DragSelectingState)
     
    16061717        setState(DragSelectingState);
    16071718        QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
     1719        if (d->ctrlDragSelectionFlag != QItemSelectionModel::NoUpdate && command.testFlag(QItemSelectionModel::Toggle)) {
     1720            command &= ~QItemSelectionModel::Toggle;
     1721            command |= d->ctrlDragSelectionFlag;
     1722        }
    16081723
    16091724        // Do the normalize ourselves, since QRect::normalized() is flawed
    16101725        QRect selectionRect = QRect(topLeft, bottomRight);
    1611         QPersistentModelIndex persistent = index;
    16121726        setSelection(selectionRect, command);
    16131727
    16141728        // set at the end because it might scroll the view
    1615         if (persistent.isValid()
    1616             && (persistent != d->selectionModel->currentIndex())
    1617             && d->isIndexEnabled(persistent))
    1618             d->selectionModel->setCurrentIndex(persistent, QItemSelectionModel::NoUpdate);
     1729        if (index.isValid()
     1730            && (index != d->selectionModel->currentIndex())
     1731            && d->isIndexEnabled(index))
     1732            d->selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
    16191733    }
    16201734}
     
    16381752            && d->isIndexEnabled(index)
    16391753            && d->sendDelegateEvent(index, event))
    1640             d->viewport->update(visualRect(index));
     1754            update(index);
    16411755        return;
    16421756    }
     
    16471761    bool edited = edit(index, trigger, event);
    16481762
    1649     if (d->selectionModel)
     1763    d->ctrlDragSelectionFlag = QItemSelectionModel::NoUpdate;
     1764
     1765    if (d->selectionModel && d->noSelectionOnMousePress) {
     1766        d->noSelectionOnMousePress = false;
    16501767        d->selectionModel->select(index, selectionCommand(index, event));
     1768    }
    16511769
    16521770    setState(NoState);
     
    19512069    Q_D(QAbstractItemView);
    19522070    QAbstractScrollArea::focusInEvent(event);
    1953     if (selectionModel()
     2071
     2072    const QItemSelectionModel* model = selectionModel();
     2073    const bool currentIndexValid = currentIndex().isValid();
     2074
     2075    if (model
    19542076        && !d->currentIndexSet
    1955         && !currentIndex().isValid()) {
     2077        && !currentIndexValid) {
    19562078        bool autoScroll = d->autoScroll;
    19572079        d->autoScroll = false;
     
    19612083        d->autoScroll = autoScroll;
    19622084    }
     2085
     2086    if (model && currentIndexValid) {
     2087        if (currentIndex().flags() != Qt::ItemIsEditable)
     2088            setAttribute(Qt::WA_InputMethodEnabled, false);
     2089        else
     2090            setAttribute(Qt::WA_InputMethodEnabled);
     2091    }
     2092
     2093    if (!currentIndexValid)
     2094        setAttribute(Qt::WA_InputMethodEnabled, false);
     2095
    19632096    d->viewport->update();
    19642097}
     
    19992132            if (!hasEditFocus()) {
    20002133                setEditFocus(true);
     2134#ifdef QT_SOFTKEYS_ENABLED
     2135                addAction(d->doneSoftKey);
     2136#endif
    20012137                return;
    20022138            }
     
    20042140        break;
    20052141    case Qt::Key_Back:
    2006         if (QApplication::keypadNavigationEnabled() && hasEditFocus())
     2142        if (QApplication::keypadNavigationEnabled() && hasEditFocus()) {
     2143#ifdef QT_SOFTKEYS_ENABLED
     2144            removeAction(d->doneSoftKey);
     2145#endif
    20072146            setEditFocus(false);
    2008         else
     2147        } else {
    20092148            event->ignore();
     2149        }
    20102150        return;
    20112151    default:
     
    20742214            if (command & QItemSelectionModel::Current) {
    20752215                d->selectionModel->setCurrentIndex(newCurrent, QItemSelectionModel::NoUpdate);
    2076                 if (d->pressedPosition == QPoint(-1, -1))
    2077                     d->pressedPosition = visualRect(oldCurrent).center();
     2216                if (!indexAt(d->pressedPosition - d->offset()).isValid())
     2217                    d->pressedPosition = visualRect(oldCurrent).center() + d->offset();
    20782218                QRect rect(d->pressedPosition - d->offset(), visualRect(newCurrent).center());
    20792219                setSelection(rect, command);
     
    20812221                d->selectionModel->setCurrentIndex(newCurrent, command);
    20822222                d->pressedPosition = visualRect(newCurrent).center() + d->offset();
     2223                // We copy the same behaviour as for mousePressEvent().
     2224                QRect rect(d->pressedPosition - d->offset(), QSize(1, 1));
     2225                setSelection(rect, command);
    20832226            }
    20842227            return;
     
    20982241    case Qt::Key_Left:
    20992242    case Qt::Key_Right:
     2243#ifdef QT_KEYPAD_NAVIGATION
     2244        if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
     2245            event->accept(); // don't change horizontal focus in directional mode
     2246            break;
     2247        }
     2248#endif // QT_KEYPAD_NAVIGATION
    21002249    case Qt::Key_Home:
    21012250    case Qt::Key_End:
     
    21612310#endif
    21622311        bool modified = (event->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier));
    2163         if (!event->text().isEmpty() && !modified) {
    2164             if (!edit(currentIndex(), AnyKeyPressed, event))
    2165                 keyboardSearch(event->text());
    2166         }
    2167         event->ignore();
     2312        if (!event->text().isEmpty() && !modified && !edit(currentIndex(), AnyKeyPressed, event)) {
     2313            keyboardSearch(event->text());
     2314            event->accept();
     2315        } else {
     2316            event->ignore();
     2317        }
    21682318        break; }
    21692319    }
     
    21912341{
    21922342    Q_D(QAbstractItemView);
    2193     if (event->timerId() == d->autoScrollTimer.timerId())
     2343    if (event->timerId() == d->fetchMoreTimer.timerId())
     2344        d->fetchMore();
     2345    else if (event->timerId() == d->delayedReset.timerId())
     2346        reset();
     2347    else if (event->timerId() == d->autoScrollTimer.timerId())
    21942348        doAutoScroll();
    21952349    else if (event->timerId() == d->updateTimer.timerId())
     
    22462400
    22472401    \value OnViewport  The item will be dropped onto a region of the viewport with
    2248 no items. The way each view handles items dropped onto the viewport depends on
    2249 the behavior of the underlying model in use.
     2402    no items. The way each view handles items dropped onto the viewport depends on
     2403    the behavior of the underlying model in use.
    22502404*/
    22512405
     
    22642418
    22652419/*!
    2266   This convenience function returns a list of all selected and
    2267   non-hidden item indexes in the view. The list contains no
    2268   duplicates, and is not sorted.
    2269 
    2270   \sa QItemSelectionModel::selectedIndexes()
     2420    This convenience function returns a list of all selected and
     2421    non-hidden item indexes in the view. The list contains no
     2422    duplicates, and is not sorted.
     2423
     2424    \sa QItemSelectionModel::selectedIndexes()
    22712425*/
    22722426QModelIndexList QAbstractItemView::selectedIndexes() const
     
    23212475
    23222476    if (d->sendDelegateEvent(index, event)) {
    2323         d->viewport->update(visualRect(index));
     2477        update(index);
    23242478        return true;
    23252479    }
     
    23502504
    23512505/*!
    2352   \internal
    2353   Updates the data shown in the open editor widgets in the view.
     2506    \internal
     2507    Updates the data shown in the open editor widgets in the view.
    23542508*/
    23552509void QAbstractItemView::updateEditorData()
     
    23602514
    23612515/*!
    2362   \internal
    2363    Updates the geometry of the open editor widgets in the view.
     2516    \internal
     2517    Updates the geometry of the open editor widgets in the view.
    23642518*/
    23652519void QAbstractItemView::updateEditorGeometries()
     
    23932547    //we release the editor outside of the loop because it might change the focus and try
    23942548    //to change the d->editors list.
    2395     foreach(QWidget *editor, editorsToRelease) {
    2396         d->releaseEditor(editor);
     2549    for (int i = 0; i < editorsToRelease.count(); ++i) {
     2550        d->releaseEditor(editorsToRelease.at(i));
    23972551    }
    23982552}
     
    24062560{
    24072561    updateEditorGeometries();
    2408     QMetaObject::invokeMethod(this, "_q_fetchMore", Qt::QueuedConnection);
    2409 }
    2410 
    2411 /*!
    2412   \internal
     2562    d_func()->fetchMoreTimer.start(0, this); //fetch more later
     2563}
     2564
     2565/*!
     2566    \internal
    24132567*/
    24142568void QAbstractItemView::verticalScrollbarValueChanged(int value)
     
    24172571    if (verticalScrollBar()->maximum() == value && d->model->canFetchMore(d->root))
    24182572        d->model->fetchMore(d->root);
    2419 }
    2420 
    2421 /*!
    2422   \internal
     2573    QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos());
     2574    if (viewport()->rect().contains(posInVp))
     2575        d->checkMouseMove(posInVp);
     2576}
     2577
     2578/*!
     2579    \internal
    24232580*/
    24242581void QAbstractItemView::horizontalScrollbarValueChanged(int value)
     
    24272584    if (horizontalScrollBar()->maximum() == value && d->model->canFetchMore(d->root))
    24282585        d->model->fetchMore(d->root);
     2586    QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos());
     2587    if (viewport()->rect().contains(posInVp))
     2588        d->checkMouseMove(posInVp);
    24292589}
    24302590
     
    25212681
    25222682/*!
    2523   Commit the data in the \a editor to the model.
    2524 
    2525   \sa closeEditor()
     2683    Commit the data in the \a editor to the model.
     2684
     2685    \sa closeEditor()
    25262686*/
    25272687void QAbstractItemView::commitData(QWidget *editor)
     
    25422702
    25432703/*!
    2544   This function is called when the given \a editor has been destroyed.
    2545 
    2546   \sa closeEditor()
     2704    This function is called when the given \a editor has been destroyed.
     2705
     2706    \sa closeEditor()
    25472707*/
    25482708void QAbstractItemView::editorDestroyed(QObject *editor)
     
    26152775
    26162776/*!
    2617   Moves to and selects the item best matching the string \a search.
    2618   If no item is found nothing happens.
    2619 
    2620   In the default implementation, the search is reset if \a search is empty, or
    2621   the time interval since the last search has exceeded
    2622   QApplication::keyboardInputInterval().
     2777    Moves to and selects the item best matching the string \a search.
     2778    If no item is found nothing happens.
     2779
     2780    In the default implementation, the search is reset if \a search is empty, or
     2781    the time interval since the last search has exceeded
     2782    QApplication::keyboardInputInterval().
    26232783*/
    26242784void QAbstractItemView::keyboardSearch(const QString &search)
     
    26352795        || (d->keyboardInputTime.msecsTo(now) > QApplication::keyboardInputInterval())) {
    26362796        d->keyboardInput = search;
    2637         skipRow = true;
     2797        skipRow = currentIndex().isValid(); //if it is not valid we should really start at QModelIndex(0,0)
    26382798    } else {
    26392799        d->keyboardInput += search;
     
    26622822    QModelIndexList match;
    26632823    QModelIndex firstMatch;
     2824    QModelIndex startMatch;
    26642825    QModelIndexList previous;
    26652826    do {
     
    26742835                break;
    26752836            }
    2676             int row = firstMatch.row() + 1;
    2677             if (row >= d->model->rowCount(firstMatch.parent()))
    2678                 row = 0;
     2837            int row = firstMatch.row() + 1;
     2838            if (row >= d->model->rowCount(firstMatch.parent()))
     2839                row = 0;
    26792840            current = firstMatch.sibling(row, firstMatch.column());
     2841
     2842            //avoid infinite loop if all the matching items are disabled.
     2843            if (!startMatch.isValid())
     2844                startMatch = firstMatch;
     2845            else if (startMatch == firstMatch)
     2846                break;
    26802847        }
    26812848    } while (current != start && firstMatch.isValid());
     
    27182885    if (row < 0 || row >= d->model->rowCount() || !model())
    27192886        return -1;
     2887
     2888    ensurePolished();
    27202889
    27212890    QStyleOptionViewItemV4 option = d->viewOptionsV4();
     
    27482917        return -1;
    27492918
     2919    ensurePolished();
     2920
    27502921    QStyleOptionViewItemV4 option = d->viewOptionsV4();
    27512922    int width = 0;
     
    27832954
    27842955/*!
    2785   Closes the persistent editor for the item at the given \a index.
    2786 
    2787   \sa openPersistentEditor()
     2956    Closes the persistent editor for the item at the given \a index.
     2957
     2958    \sa openPersistentEditor()
    27882959*/
    27892960void QAbstractItemView::closePersistentEditor(const QModelIndex &index)
     
    28403011        d->addEditor(index, widget, true);
    28413012        widget->show();
     3013        dataChanged(index, index); // update the geometry
    28423014        if (!d->delayedPendingLayout)
    28433015            widget->setGeometry(visualRect(index));
    2844         dataChanged(index, index); // update the geometry
    28453016    }
    28463017}
     
    28973068{
    28983069    Q_D(QAbstractItemView);
    2899     if (index.isValid())
    2900         d->viewport->update(visualRect(index));
     3070    if (index.isValid()) {
     3071        const QRect rect = visualRect(index);
     3072        //this test is important for peformance reason
     3073        //For example in dataChanged we simply update all the cells without checking
     3074        //it can be a major bottleneck to update rects that aren't even part of the viewport
     3075        if (d->viewport->rect().intersects(rect))
     3076            d->viewport->update(rect);
     3077    }
    29013078}
    29023079
     
    29223099        if (isVisible() && !d->delayedPendingLayout) {
    29233100            // otherwise the items will be update later anyway
    2924             d->viewport->update(visualRect(topLeft));
     3101            update(topLeft);
    29253102        }
    29263103        return;
     
    29433120{
    29443121    if (!isVisible())
    2945         QMetaObject::invokeMethod(this, "_q_fetchMore", Qt::QueuedConnection);
     3122        d_func()->fetchMoreTimer.start(0, this); //fetch more later
    29463123    else
    29473124        updateEditorGeometries();
     
    31003277void QAbstractItemViewPrivate::_q_modelDestroyed()
    31013278{
    3102     Q_Q(QAbstractItemView);
    31033279    model = QAbstractItemModelPrivate::staticEmptyModel();
    3104     QMetaObject::invokeMethod(q, "reset", Qt::QueuedConnection);
     3280    doDelayedReset();
    31053281}
    31063282
     
    31273303    Q_D(QAbstractItemView);
    31283304    if (isVisible() && updatesEnabled()) {
    3129         d->setDirtyRegion(visualRegionForSelection(deselected));
    3130         d->setDirtyRegion(visualRegionForSelection(selected));
    3131         d->updateDirtyRegion();
     3305        d->viewport->update(visualRegionForSelection(deselected) | visualRegionForSelection(selected));
    31323306    }
    31333307}
     
    31573331        }
    31583332        if (isVisible()) {
    3159             d->setDirtyRegion(visualRect(previous));
    3160             d->updateDirtyRegion();
    3161         }
    3162     }
    3163     if (isVisible() && current.isValid() && !d->autoScrollTimer.isActive()) {
    3164         if (d->autoScroll)
    3165             scrollTo(current);
    3166         d->setDirtyRegion(visualRect(current));
    3167         d->updateDirtyRegion();
    3168         edit(current, CurrentChanged, 0);
    3169         if (current.row() == (d->model->rowCount(d->root) - 1))
    3170             d->_q_fetchMore();
     3333            update(previous);
     3334        }
     3335    }
     3336
     3337    if (current.isValid() && !d->autoScrollTimer.isActive()) {
     3338        if (isVisible()) {
     3339            if (d->autoScroll)
     3340                scrollTo(current);
     3341            update(current);
     3342            edit(current, CurrentChanged, 0);
     3343            if (current.row() == (d->model->rowCount(d->root) - 1))
     3344                d->fetchMore();
     3345        } else {
     3346            d->shouldScrollToCurrentOnShow = d->autoScroll;
     3347        }
    31713348    }
    31723349}
     
    31923369        drag->setHotSpot(d->pressedPosition - rect.topLeft());
    31933370        Qt::DropAction defaultDropAction = Qt::IgnoreAction;
    3194         if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
     3371        if (d->defaultDropAction != Qt::IgnoreAction && (supportedActions & d->defaultDropAction))
     3372            defaultDropAction = d->defaultDropAction;
     3373        else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
    31953374            defaultDropAction = Qt::CopyAction;
    31963375        if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction)
     
    32123391    option.font = font();
    32133392
    3214 #ifdef Q_WS_WIN
    3215     // Note this is currently required on Windows
    3216     // do give non-focused item views inactive appearance
     3393#ifndef Q_WS_MAC
     3394    // On mac the focus appearance follows window activation
     3395    // not widget activation
    32173396    if (!hasFocus())
    32183397        option.state &= ~QStyle::State_Active;
     
    33133492
    33143493/*!
    3315   Prepares the view for scrolling by (\a{dx},\a{dy}) pixels by moving the dirty regions in the
    3316   opposite direction. You only need to call this function if you are implementing a scrolling
    3317   viewport in your view subclass.
    3318 
    3319   If you implement scrollContentsBy() in a subclass of QAbstractItemView, call this function
    3320   before you call QWidget::scroll() on the viewport. Alternatively, just call update().
    3321 
    3322   \sa scrollContentsBy(), dirtyRegionOffset(), setDirtyRegion()
     3494    Prepares the view for scrolling by (\a{dx},\a{dy}) pixels by moving the dirty regions in the
     3495    opposite direction. You only need to call this function if you are implementing a scrolling
     3496    viewport in your view subclass.
     3497
     3498    If you implement scrollContentsBy() in a subclass of QAbstractItemView, call this function
     3499    before you call QWidget::scroll() on the viewport. Alternatively, just call update().
     3500
     3501    \sa scrollContentsBy(), dirtyRegionOffset(), setDirtyRegion()
    33233502*/
    33243503void QAbstractItemView::scrollDirtyRegion(int dx, int dy)
     
    33293508
    33303509/*!
    3331   Returns the offset of the dirty regions in the view.
    3332 
    3333   If you use scrollDirtyRegion() and implement a paintEvent() in a subclass of
    3334   QAbstractItemView, you should translate the area given by the paint event with
    3335   the offset returned from this function.
    3336 
    3337   \sa scrollDirtyRegion(), setDirtyRegion()
     3510    Returns the offset of the dirty regions in the view.
     3511
     3512    If you use scrollDirtyRegion() and implement a paintEvent() in a subclass of
     3513    QAbstractItemView, you should translate the area given by the paint event with
     3514    the offset returned from this function.
     3515
     3516    \sa scrollDirtyRegion(), setDirtyRegion()
    33383517*/
    33393518QPoint QAbstractItemView::dirtyRegionOffset() const
     
    33483527void QAbstractItemView::startAutoScroll()
    33493528{
    3350     Q_D(QAbstractItemView);
    3351     // ### it would be nice to make this into a style hint one day
    3352     int scrollInterval = (verticalScrollMode() == QAbstractItemView::ScrollPerItem) ? 150 : 50;
    3353     d->autoScrollTimer.start(scrollInterval, this);
    3354     d->autoScrollCount = 0;
     3529    d_func()->startAutoScroll();
    33553530}
    33563531
     
    33603535void QAbstractItemView::stopAutoScroll()
    33613536{
    3362     Q_D(QAbstractItemView);
    3363     d->autoScrollTimer.stop();
    3364     d->autoScrollCount = 0;
     3537    d_func()->stopAutoScroll();
    33653538}
    33663539
     
    35073680            const bool controlKeyPressed = modifiers & Qt::ControlModifier;
    35083681            if (((index == pressedIndex && selectionModel->isSelected(index))
    3509                 || !index.isValid()) && state != QAbstractItemView::DragSelectingState
    3510                 && !shiftKeyPressed && !controlKeyPressed && !rightButtonPressed)
     3682                || !index.isValid()) && state != QAbstractItemView::DragSelectingState
     3683                && !shiftKeyPressed && !controlKeyPressed && (!rightButtonPressed || !index.isValid()))
    35113684                return QItemSelectionModel::ClearAndSelect|selectionBehaviorFlags();
    35123685            return QItemSelectionModel::NoUpdate;
     
    35273700            case Qt::Key_PageDown:
    35283701            case Qt::Key_Tab:
     3702                if (modifiers & Qt::ControlModifier
    35293703#ifdef QT_KEYPAD_NAVIGATION
    3530                 return QItemSelectionModel::NoUpdate;
    3531 #else
    3532                 if (modifiers & Qt::ControlModifier)
     3704                    // Preserve historical tab order navigation behavior
     3705                    || QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
     3706#endif
     3707                    )
    35333708                    return QItemSelectionModel::NoUpdate;
    3534 #endif
    35353709                break;
    35363710            case Qt::Key_Select:
     
    35863760}
    35873761
    3588 void QAbstractItemViewPrivate::_q_fetchMore()
    3589 {
     3762void QAbstractItemViewPrivate::fetchMore()
     3763{
     3764    fetchMoreTimer.stop();
    35903765    if (!model->canFetchMore(root))
    35913766        return;
     
    37383913
    37393914    Either remove the selected rows or clear them
    3740   */
     3915*/
    37413916void QAbstractItemViewPrivate::clearOrRemove()
    37423917{
     
    37743949    When persistent aeditor gets/loses focus, we need to check
    37753950    and setcorrectly the current index.
    3776   */
     3951*/
    37773952void QAbstractItemViewPrivate::checkPersistentEditorFocus()
    37783953{
    37793954    Q_Q(QAbstractItemView);
    3780     if (QWidget *widget = qApp->focusWidget()) {
     3955    if (QWidget *widget = QApplication::focusWidget()) {
    37813956        if (persistent.contains(widget)) {
    37823957            //a persistent editor has gained the focus
     
    38604035}
    38614036
     4037/*
     4038    \internal
     4039
     4040    returns the pair QRect/QModelIndex that should be painted on the viewports's rect
     4041*/
     4042
     4043QItemViewPaintPairs QAbstractItemViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const
     4044{
     4045    Q_ASSERT(r);
     4046    Q_Q(const QAbstractItemView);
     4047    QRect &rect = *r;
     4048    const QRect viewportRect = viewport->rect();
     4049    QItemViewPaintPairs ret;
     4050    for (int i = 0; i < indexes.count(); ++i) {
     4051        const QModelIndex &index = indexes.at(i);
     4052        const QRect current = q->visualRect(index);
     4053        if (current.intersects(viewportRect)) {
     4054            ret += qMakePair(current, index);
     4055            rect |= current;
     4056        }
     4057    }
     4058    rect &= viewportRect;
     4059    return ret;
     4060}
     4061
    38624062QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, QRect *r) const
    38634063{
    3864     Q_Q(const QAbstractItemView);
    3865     QRect rect = q->visualRect(indexes.at(0));
    3866     QList<QRect> rects;
    3867     for (int i = 0; i < indexes.count(); ++i) {
    3868         rects.append(q->visualRect(indexes.at(i)));
    3869         rect |= rects.at(i);
    3870     }
    3871     rect = rect.intersected(viewport->rect());
    3872     if (rect.width() <= 0 || rect.height() <= 0)
     4064    Q_ASSERT(r);
     4065    QItemViewPaintPairs paintPairs = draggablePaintPairs(indexes, r);
     4066    if (paintPairs.isEmpty())
    38734067        return QPixmap();
    3874     QImage image(rect.size(), QImage::Format_ARGB32_Premultiplied);
    3875     image.fill(0);
    3876     QPainter painter(&image);
     4068    QPixmap pixmap(r->size());
     4069    pixmap.fill(Qt::transparent);
     4070    QPainter painter(&pixmap);
    38774071    QStyleOptionViewItemV4 option = viewOptionsV4();
    38784072    option.state |= QStyle::State_Selected;
    3879     for (int j = 0; j < indexes.count(); ++j) {
    3880         option.rect = QRect(rects.at(j).topLeft() - rect.topLeft(), rects.at(j).size());
    3881         delegateForIndex(indexes.at(j))->paint(&painter, option, indexes.at(j));
    3882     }
    3883     painter.end();
    3884     if (r) *r = rect;
    3885     return QPixmap::fromImage(image);
     4073    for (int j = 0; j < paintPairs.count(); ++j) {
     4074        option.rect = paintPairs.at(j).first.translated(-r->topLeft());
     4075        const QModelIndex &current = paintPairs.at(j).second;
     4076        delegateForIndex(current)->paint(&painter, option, current);
     4077    }
     4078    return pixmap;
    38864079}
    38874080
  • trunk/src/gui/itemviews/qabstractitemview.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7575    Q_PROPERTY(bool dragDropOverwriteMode READ dragDropOverwriteMode WRITE setDragDropOverwriteMode)
    7676    Q_PROPERTY(DragDropMode dragDropMode READ dragDropMode WRITE setDragDropMode)
     77    Q_PROPERTY(Qt::DropAction defaultDropAction READ defaultDropAction WRITE setDefaultDropAction)
    7778#endif
    7879    Q_PROPERTY(bool alternatingRowColors READ alternatingRowColors WRITE setAlternatingRowColors)
     
    182183    void setDragDropMode(DragDropMode behavior);
    183184    DragDropMode dragDropMode() const;
    184 #endif
     185
     186    void setDefaultDropAction(Qt::DropAction dropAction);
     187    Qt::DropAction defaultDropAction() const;
     188#endif
     189
    185190    void setAlternatingRowColors(bool enable);
    186191    bool alternatingRowColors() const;
     
    354359    Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
    355360    Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged())
    356     Q_PRIVATE_SLOT(d_func(), void _q_fetchMore())
     361    Q_PRIVATE_SLOT(d_func(), void _q_headerDataChanged())
    357362
    358363    friend class QTreeViewPrivate; // needed to compile with MSVC
    359364    friend class QAccessibleItemRow;
     365    friend class QListModeViewBase;
     366    friend class QListViewPrivate; // needed to compile for Symbian emulator
    360367};
    361368
  • trunk/src/gui/itemviews/qabstractitemview_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6262#include "QtGui/qpainter.h"
    6363#include "QtCore/qpair.h"
    64 #include "QtCore/qtimer.h"
    65 #include "QtCore/qtimeline.h"
    6664#include "QtGui/qregion.h"
    6765#include "QtCore/qdebug.h"
    6866#include "QtGui/qpainter.h"
     67#include "QtCore/qbasictimer.h"
    6968
    7069#ifndef QT_NO_ITEMVIEWS
     
    8786
    8887};
     88
     89typedef QPair<QRect, QModelIndex> QItemViewPaintPair;
     90typedef QList<QItemViewPaintPair> QItemViewPaintPairs;
    8991
    9092class QEmptyModel : public QAbstractItemModel
     
    100102};
    101103
    102 class Q_GUI_EXPORT QAbstractItemViewPrivate : public QAbstractScrollAreaPrivate
     104class Q_AUTOTEST_EXPORT QAbstractItemViewPrivate : public QAbstractScrollAreaPrivate
    103105{
    104106    Q_DECLARE_PUBLIC(QAbstractItemView)
     
    110112    void init();
    111113
    112     void _q_rowsRemoved(const QModelIndex &parent, int start, int end);
    113     void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
    114     void _q_columnsRemoved(const QModelIndex &parent, int start, int end);
    115     void _q_columnsInserted(const QModelIndex &parent, int start, int end);
    116     void _q_modelDestroyed();
    117     void _q_layoutChanged();
    118     void _q_fetchMore();
     114    virtual void _q_rowsRemoved(const QModelIndex &parent, int start, int end);
     115    virtual void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
     116    virtual void _q_columnsRemoved(const QModelIndex &parent, int start, int end);
     117    virtual void _q_columnsInserted(const QModelIndex &parent, int start, int end);
     118    virtual void _q_modelDestroyed();
     119    virtual void _q_layoutChanged();
     120    void _q_headerDataChanged() { doDelayedItemsLayout(); }
     121
     122    void fetchMore();
    119123
    120124    bool shouldEdit(QAbstractItemView::EditTrigger trigger, const QModelIndex &index) const;
     
    123127    void doDelayedItemsLayout(int delay = 0);
    124128    void interruptDelayedItemsLayout() const;
     129
     130    void startAutoScroll()
     131    {   // ### it would be nice to make this into a style hint one day
     132        int scrollInterval = (verticalScrollMode == QAbstractItemView::ScrollPerItem) ? 150 : 50;
     133        autoScrollTimer.start(scrollInterval, q_func());
     134        autoScrollCount = 0;
     135    }
     136    void stopAutoScroll() { autoScrollTimer.stop(); autoScrollCount = 0;}
     137
    125138
    126139    bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index);
     
    140153    virtual void selectAll(QItemSelectionModel::SelectionFlags command);
    141154
     155    void setHoverIndex(const QPersistentModelIndex &index);
     156
     157    void checkMouseMove(const QPersistentModelIndex &index);
     158    inline void checkMouseMove(const QPoint &pos) { checkMouseMove(q_func()->indexAt(pos)); }
     159
    142160    inline QItemSelectionModel::SelectionFlags selectionBehaviorFlags() const
    143161    {
     
    150168
    151169#ifndef QT_NO_DRAGANDDROP
    152     QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
     170    virtual QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
     171
    153172    inline bool canDecode(QDropEvent *e) const {
    154173        QStringList modelTypes = model->mimeTypes();
     
    174193        }
    175194    }
     195
    176196#endif
     197    virtual QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const;
    177198
    178199    inline void releaseEditor(QWidget *editor) const {
     
    219240    void checkPersistentEditorFocus();
    220241
    221     QPixmap renderToPixmap(const QModelIndexList &indexes, QRect *r = 0) const;
     242    QPixmap renderToPixmap(const QModelIndexList &indexes, QRect *r) const;
    222243
    223244    inline QPoint offset() const {
     
    299320        return ref;
    300321    }
    301    
     322
    302323    /**
    303324     * return true if the index is registered as a QPersistentModelIndex
     
    305326    inline bool isPersistent(const QModelIndex &index) const
    306327    {
    307         return static_cast<QAbstractItemModelPrivate *>(model->d_ptr)->persistent.indexes.contains(index);
     328        return static_cast<QAbstractItemModelPrivate *>(model->d_ptr.data())->persistent.indexes.contains(index);
    308329    }
    309330
     
    311332
    312333    QStyleOptionViewItemV4 viewOptionsV4() const;
     334
     335    void doDelayedReset()
     336    {
     337        //we delay the reset of the timer because some views (QTableView)
     338        //with headers can't handle the fact that the model has been destroyed
     339        //all _q_modelDestroyed slots must have been called
     340        if (!delayedReset.isActive())
     341            delayedReset.start(0, q_func());
     342    }
    313343
    314344    QAbstractItemModel *model;
     
    317347    QMap<int, QPointer<QAbstractItemDelegate> > columnDelegates;
    318348    QPointer<QItemSelectionModel> selectionModel;
     349    QItemSelectionModel::SelectionFlag ctrlDragSelectionFlag;
     350    bool noSelectionOnMousePress;
    319351
    320352    QAbstractItemView::SelectionMode selectionMode;
     
    330362    QPoint pressedPosition;
    331363    bool pressedAlreadySelected;
    332    
    333     //forces the next mouseMoveEvent to send the viewportEntered signal 
     364
     365    //forces the next mouseMoveEvent to send the viewportEntered signal
    334366    //if the mouse is over the viewport and not over an item
    335367    bool viewportEnteredNeeded;
     
    351383    bool overwrite;
    352384    QAbstractItemView::DropIndicatorPosition dropIndicatorPosition;
     385    Qt::DropAction defaultDropAction;
     386#endif
     387
     388#ifdef QT_SOFTKEYS_ENABLED
     389    QAction *doneSoftKey;
    353390#endif
    354391
     
    360397    int autoScrollMargin;
    361398    int autoScrollCount;
     399    bool shouldScrollToCurrentOnShow; //used to know if we should scroll to current on show event
     400    bool shouldClearStatusTip; //if there is a statustip currently shown that need to be cleared when leaving.
    362401
    363402    bool alternatingColors;
     
    372411    QBasicTimer delayedEditing;
    373412    QBasicTimer delayedAutoScroll; //used when an item is clicked
    374     QTimeLine timeline;
     413    QBasicTimer delayedReset;
    375414
    376415    QAbstractItemView::ScrollMode verticalScrollMode;
     
    384423private:
    385424    mutable QBasicTimer delayedLayout;
     425    mutable QBasicTimer fetchMoreTimer;
    386426};
    387427
  • trunk/src/gui/itemviews/qabstractproxymodel.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qabstractproxymodel.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qabstractproxymodel_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qbsptree.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qbsptree_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qcolumnview.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5353#include <qpainter.h>
    5454#include <qdebug.h>
    55 #include <qpainterpath.h>
    5655
    5756QT_BEGIN_NAMESPACE
     
    6564    \ingroup model-view
    6665    \ingroup advanced
    67     \mainclass
     66
    6867
    6968    QColumnView displays a model in a number of QListViews, one for each
     
    109108    Q_Q(QColumnView);
    110109    q->setTextElideMode(Qt::ElideMiddle);
    111     q->connect(&currentAnimation, SIGNAL(frameChanged(int)),
    112             q->horizontalScrollBar(), SLOT(setValue(int)));
    113     q->connect(&currentAnimation, SIGNAL(finished()), q, SLOT(_q_changeCurrentColumn()));
     110#ifndef QT_NO_ANIMATION
     111    QObject::connect(&currentAnimation, SIGNAL(finished()), q, SLOT(_q_changeCurrentColumn()));
     112    currentAnimation.setDuration(ANIMATION_DURATION_MSEC);
     113    currentAnimation.setTargetObject(hbar);
     114    currentAnimation.setPropertyName("value");
     115    currentAnimation.setEasingCurve(QEasingCurve::InOutQuad);
     116#endif //QT_NO_ANIMATION
    114117    delete itemDelegate;
    115118    q->setItemDelegate(new QColumnViewDelegate(q));
     
    261264        return;
    262265
    263     if (d->currentAnimation.state() == QTimeLine::Running)
     266#ifndef QT_NO_ANIMATION
     267    if (d->currentAnimation.state() == QPropertyAnimation::Running)
    264268        return;
    265269
    266270    d->currentAnimation.stop();
     271#endif //QT_NO_ANIMATION
    267272
    268273    // Fill up what is needed to get to index
     
    327332    }
    328333
    329     //horizontalScrollBar()->setValue(newScrollbarValue);
    330     //d->_q_changeCurrentColumn();
    331     //return;
    332     // or do the following currentAnimation
    333 
    334     int oldValue = horizontalScrollBar()->value();
    335 
    336     if (oldValue < newScrollbarValue) {
    337         d->currentAnimation.setFrameRange(oldValue, newScrollbarValue);
    338         d->currentAnimation.setDirection(QTimeLine::Forward);
    339         d->currentAnimation.setCurrentTime(0);
    340     } else {
    341         d->currentAnimation.setFrameRange(newScrollbarValue, oldValue);
    342         d->currentAnimation.setDirection(QTimeLine::Backward);
    343     }
     334#ifndef QT_NO_ANIMATION
     335    d->currentAnimation.setEndValue(newScrollbarValue);
    344336    d->currentAnimation.start();
     337#else
     338    horizontalScrollBar()->setValue(newScrollbarValue);
     339#endif //QT_NO_ANIMATION
    345340}
    346341
     
    411406{
    412407    Q_Q(QColumnView);
    413     if (currentAnimation.state() == QTimeLine::Running)
    414         return;
     408#ifndef QT_NO_ANIMATION
     409    if (currentAnimation.state() == QPropertyAnimation::Running)
     410        return;
     411#endif //QT_NO_ANIMATION
    415412
    416413    // find the total horizontal length of the laid out columns
     
    422419    }
    423420
    424     QSize viewportSize = q->viewport()->size();
    425     if (horizontalLength < viewportSize.width() && q->horizontalScrollBar()->value() == 0) {
    426         q->horizontalScrollBar()->setRange(0, 0);
     421    QSize viewportSize = viewport->size();
     422    if (horizontalLength < viewportSize.width() && hbar->value() == 0) {
     423        hbar->setRange(0, 0);
    427424    } else {
    428425        int visibleLength = qMin(horizontalLength + q->horizontalOffset(), viewportSize.width());
    429426        int hiddenLength = horizontalLength - visibleLength;
    430         if (hiddenLength != q->horizontalScrollBar()->maximum())
    431             q->horizontalScrollBar()->setRange(0, hiddenLength);
     427        if (hiddenLength != hbar->maximum())
     428            hbar->setRange(0, hiddenLength);
    432429    }
    433430    if (!columns.isEmpty()) {
    434431        int pageStepSize = columns.at(0)->width();
    435         if (pageStepSize != q->horizontalScrollBar()->pageStep())
    436             q->horizontalScrollBar()->setPageStep(pageStepSize);
    437     }
    438     bool visible = (q->horizontalScrollBar()->maximum() > 0);
    439     if (visible != q->horizontalScrollBar()->isVisible())
    440         q->horizontalScrollBar()->setVisible(visible);
     432        if (pageStepSize != hbar->pageStep())
     433            hbar->setPageStep(pageStepSize);
     434    }
     435    bool visible = (hbar->maximum() > 0);
     436    if (visible != hbar->isVisible())
     437        hbar->setVisible(visible);
    441438}
    442439
     
    676673    if (model->hasChildren(index)) {
    677674        view = q->createColumn(index);
    678         q->connect(view, SIGNAL(clicked(const QModelIndex &)),
    679                    q, SLOT(_q_clicked(const QModelIndex &)));
     675        q->connect(view, SIGNAL(clicked(QModelIndex)),
     676                   q, SLOT(_q_clicked(QModelIndex)));
    680677    } else {
    681678        if (!previewColumn)
     
    685682    }
    686683
    687     q->connect(view, SIGNAL(activated(const QModelIndex &)),
    688             q, SIGNAL(activated(const QModelIndex &)));
    689     q->connect(view, SIGNAL(clicked(const QModelIndex &)),
    690             q, SIGNAL(clicked(const QModelIndex &)));
    691     q->connect(view, SIGNAL(doubleClicked(const QModelIndex &)),
    692             q, SIGNAL(doubleClicked(const QModelIndex &)));
    693     q->connect(view, SIGNAL(entered(const QModelIndex &)),
    694             q, SIGNAL(entered(const QModelIndex &)));
    695     q->connect(view, SIGNAL(pressed(const QModelIndex &)),
    696             q, SIGNAL(pressed(const QModelIndex &)));
     684    q->connect(view, SIGNAL(activated(QModelIndex)),
     685            q, SIGNAL(activated(QModelIndex)));
     686    q->connect(view, SIGNAL(clicked(QModelIndex)),
     687            q, SIGNAL(clicked(QModelIndex)));
     688    q->connect(view, SIGNAL(doubleClicked(QModelIndex)),
     689            q, SIGNAL(doubleClicked(QModelIndex)));
     690    q->connect(view, SIGNAL(entered(QModelIndex)),
     691            q, SIGNAL(entered(QModelIndex)));
     692    q->connect(view, SIGNAL(pressed(QModelIndex)),
     693            q, SIGNAL(pressed(QModelIndex)));
    697694
    698695    view->setFocusPolicy(Qt::NoFocus);
    699     view->setParent(q->viewport());
     696    view->setParent(viewport);
    700697    Q_ASSERT(view);
    701698
     
    708705
    709706    if (columnSizes.count() > columns.count()) {
    710         view->setGeometry(0, 0, columnSizes.at(columns.count()), q->viewport()->height());
     707        view->setGeometry(0, 0, columnSizes.at(columns.count()), viewport->height());
    711708    } else {
    712709        int initialWidth = view->sizeHint().width();
    713710        if (q->isRightToLeft())
    714             view->setGeometry(q->viewport()->width() - initialWidth, 0, initialWidth, q->viewport()->height());
     711            view->setGeometry(viewport->width() - initialWidth, 0, initialWidth, viewport->height());
    715712        else
    716             view->setGeometry(0, 0, initialWidth, q->viewport()->height());
     713            view->setGeometry(0, 0, initialWidth, viewport->height());
    717714        columnSizes.resize(qMax(columnSizes.count(), columns.count() + 1));
    718715        columnSizes[columns.count()] = initialWidth;
     
    897894    \reimp
    898895*/
     896void QColumnView::rowsInserted(const QModelIndex &parent, int start, int end)
     897{
     898    QAbstractItemView::rowsInserted(parent, start, end);
     899    d_func()->checkColumnCreation(parent);
     900}
     901
     902/*!
     903    \reimp
     904*/
    899905void QColumnView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
    900906{
     
    10371043,showResizeGrips(true)
    10381044,offset(0)
    1039 ,currentAnimation(ANIMATION_DURATION_MSEC)
    10401045,previewWidget(0)
    10411046,previewColumn(0)
     
    10491054/*!
    10501055    \internal
     1056
     1057  */
     1058void QColumnViewPrivate::_q_columnsInserted(const QModelIndex &parent, int start, int end)
     1059{
     1060    QAbstractItemViewPrivate::_q_columnsInserted(parent, start, end);
     1061    checkColumnCreation(parent);
     1062}
     1063
     1064/*!
     1065    \internal
     1066
     1067    Makes sure we create a corresponding column as a result of changing the model.
     1068
     1069  */
     1070void QColumnViewPrivate::checkColumnCreation(const QModelIndex &parent)
     1071{
     1072    if (parent == q_func()->currentIndex() && model->hasChildren(parent)) {
     1073        //the parent has children and is the current
     1074        //let's try to find out if there is already a mapping that is good
     1075        for (int i = 0; i < columns.count(); ++i) {
     1076            QAbstractItemView *view = columns.at(i);
     1077            if (view->rootIndex() == parent) {
     1078                if (view == previewColumn) {
     1079                    //let's recreate the parent
     1080                    closeColumns(parent, false);
     1081                    createColumn(parent, true /*show*/);
     1082                }
     1083                break;
     1084            }
     1085        }
     1086    }
     1087}
     1088
     1089/*!
     1090    \internal
    10511091    Place all of the columns where they belong inside of the viewport, resize as necessary.
    10521092*/
     
    10571097        return;
    10581098
    1059     int viewportHeight = q->viewport()->height();
     1099    int viewportHeight = viewport->height();
    10601100    int x = columns.at(0)->x();
    10611101
    10621102    if (q->isRightToLeft()) {
    1063         x = q->viewport()->width() + q->horizontalOffset();
     1103        x = viewport->width() + q->horizontalOffset();
    10641104        for (int i = 0; i < columns.size(); ++i) {
    10651105            QAbstractItemView *view = columns.at(i);
     
    11171157    if (index.model()->hasChildren(index)) {
    11181158        const QWidget *view = opt.widget;
    1119         QStyle *style = view ? view->style() : qApp->style();
     1159        QStyle *style = view ? view->style() : QApplication::style();
    11201160        style->drawPrimitive(QStyle::PE_IndicatorColumnViewArrow, &opt, painter, view);
    11211161    }
  • trunk/src/gui/itemviews/qcolumnview.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    9898    int horizontalOffset() const;
    9999    int verticalOffset() const;
    100     void scrollContentsBy(int dx, int dy);
     100    void rowsInserted(const QModelIndex &parent, int start, int end);
     101    void currentChanged(const QModelIndex &current, const QModelIndex &previous);
    101102
    102103    // QColumnView functions
     104    void scrollContentsBy(int dx, int dy);
    103105    virtual QAbstractItemView* createColumn(const QModelIndex &rootIndex);
    104106    void initializeColumn(QAbstractItemView *column) const;
    105 
    106 protected Q_SLOTS:
    107     // QAbstractItemView overloads
    108     void currentChanged(const QModelIndex &current, const QModelIndex &previous);
    109107
    110108private:
  • trunk/src/gui/itemviews/qcolumnview_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5656#include "qcolumnview.h"
    5757
    58 #ifndef QT_NO_QCOlUMNVIEW
     58#ifndef QT_NO_QCOLUMNVIEW
    5959
    6060#include <private/qabstractitemview_p.h>
    6161
    6262#include <QtCore/qabstractitemmodel.h>
    63 #include <QtCore/qtimeline.h>
     63#include <QtCore/qpropertyanimation.h>
    6464#include <QtGui/qabstractitemdelegate.h>
    6565#include <QtGui/qabstractitemview.h>
     
    149149    void doLayout();
    150150    void setPreviewWidget(QWidget *widget);
     151    void checkColumnCreation(const QModelIndex &parent);
     152
    151153
    152154    void _q_gripMoved(int offset);
    153155    void _q_changeCurrentColumn();
    154156    void _q_clicked(const QModelIndex &index);
     157    void _q_columnsInserted(const QModelIndex &parent, int start, int end);
    155158
    156159    QList<QAbstractItemView*> columns;
     
    158161    bool showResizeGrips;
    159162    int offset;
    160     QTimeLine currentAnimation;
     163#ifndef QT_NO_ANIMATION
     164    QPropertyAnimation currentAnimation;
     165#endif
    161166    QWidget *previewWidget;
    162167    QAbstractItemView *previewColumn;
     
    170175
    171176public:
    172     explicit QColumnViewDelegate(QObject *parent = 0) : QItemDelegate(parent) {};
    173     ~QColumnViewDelegate() {};
     177    explicit QColumnViewDelegate(QObject *parent = 0) : QItemDelegate(parent) {}
     178    ~QColumnViewDelegate() {}
    174179
    175180    void paint(QPainter *painter,
  • trunk/src/gui/itemviews/qcolumnviewgrip.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qcolumnviewgrip_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qdatawidgetmapper.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    279279
    280280    \table
    281     \row \o 1 \o Nokia Corporation and/or its subsidiary(-ies)    \o Oslo
    282     \row \o 2 \o Trolltech Pty   \o Brisbane
    283     \row \o 3 \o Trolltech Inc   \o Palo Alto
    284     \row \o 4 \o Trolltech China \o Beijing
    285     \row \o 5 \o Trolltech GmbH  \o Berlin
     281    \row \o 1 \o Qt Norway       \o Oslo
     282    \row \o 2 \o Qt Australia    \o Brisbane
     283    \row \o 3 \o Qt USA          \o Palo Alto
     284    \row \o 4 \o Qt China        \o Beijing
     285    \row \o 5 \o Qt Germany      \o Berlin
    286286    \endtable
    287287
     
    781781
    782782    \table
    783     \row \o 1 \o Nokia Corporation and/or its subsidiary(-ies)     \o Oslo
    784     \row \o 2 \o Trolltech Pty   \o Brisbane
    785     \row \o 3 \o Trolltech Inc   \o Silicon Valley
    786     \row \o 4 \o Trolltech China \o Beijing
    787     \row \o 5 \o Trolltech GmbH  \o Berlin
     783    \row \o 1 \o Qt Norway       \o Oslo
     784    \row \o 2 \o Qt Australia    \o Brisbane
     785    \row \o 3 \o Qt USA          \o Silicon Valley
     786    \row \o 4 \o Qt China        \o Beijing
     787    \row \o 5 \o Qt Germany      \o Berlin
    788788    \endtable
    789789
     
    797797    \table
    798798    \row \o 1 \o 2 \o 3 \o 4 \o 5
    799     \row \o Nokia Corporation and/or its subsidiary(-ies) \o Trolltech Pty \o Trolltech Inc \o Trolltech China \o Trolltech GmbH
     799    \row \o Qt Norway \o Qt Australia \o Qt USA \o Qt China \o Qt Germany
    800800    \row \o Oslo \o Brisbane \o Silicon Valley \o Beijing \i Berlin
    801801    \endtable
  • trunk/src/gui/itemviews/qdatawidgetmapper.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qdirmodel.cpp

    r376 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4545#include <qstack.h>
    4646#include <qfile.h>
     47#include <qfilesystemmodel.h>
    4748#include <qurl.h>
    4849#include <qmime.h>
     
    190191    \ingroup model-view
    191192
     193    \note The usage of QDirModel is not recommended anymore. The
     194    QFileSystemModel class is a more performant alternative.
     195
    192196    This class provides access to the local filesystem, providing functions
    193197    for renaming and removing files and directories, and for creating new
     
    228232    \note QDirModel requires an instance of a GUI application.
    229233
    230     \sa nameFilters(), setFilter(), filter(), QListView, QTreeView,
     234    \sa nameFilters(), setFilter(), filter(), QListView, QTreeView, QFileSystemModel,
    231235    {Dir View Example}, {Model Classes}
    232236*/
     
    869873
    870874    QString absolutePath = QDir(path).absolutePath();
     875#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN) || defined(Q_OS_OS2)
     876    absolutePath = absolutePath.toLower();
     877#endif
    871878#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_OS2)
    872     absolutePath = absolutePath.toLower();
    873879    // On Windows, "filename......." and "filename" are equivalent
    874880    if (absolutePath.endsWith(QLatin1Char('.'))) {
     
    910916        if (childAppended)
    911917            emit const_cast<QDirModel*>(this)->layoutChanged();
    912     } else if (pathElements.at(0).endsWith(QLatin1Char(':'))) {
     918    } else
     919#endif
     920#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN) || defined(Q_OS_OS2)
     921    if (pathElements.at(0).endsWith(QLatin1Char(':'))) {
    913922        pathElements[0] += QLatin1Char('/');
    914923    }
     
    932941            const QFileInfo& fi = parent->children.at(j).info;
    933942            QString childFileName;
    934 #if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_OS2)
    935943            childFileName = idx.isValid() ? fi.fileName() : fi.absoluteFilePath();
     944#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN) || defined(Q_OS_OS2)
    936945            childFileName = childFileName.toLower();
    937 #else
    938             childFileName = idx.isValid() ? fi.fileName() : fi.absoluteFilePath();
    939946#endif
    940947            if (childFileName == element) {
     
    953960                newPath = parent->info.absoluteFilePath() + element;
    954961            else
    955                 newPath= parent->info.absoluteFilePath() + QLatin1Char('/') + element;
     962                newPath = parent->info.absoluteFilePath() + QLatin1Char('/') + element;
    956963#else
    957964            QString newPath = parent->info.absoluteFilePath() + QLatin1Char('/') + element;
     
    13051312        if (name.startsWith(QLatin1Char('/'))) // UNC host
    13061313            return info.fileName();
     1314#endif       
     1315#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN) || defined(Q_OS_OS2)
    13071316        if (name.endsWith(QLatin1Char('/')))
    13081317            name.chop(1);
     
    13361345    quint64 bytes = n->info.size();
    13371346    if (bytes >= tb)
    1338         return QLocale().toString(bytes / tb) + QString::fromLatin1(" TB");
     1347        return QFileSystemModel::tr("%1 TB").arg(QLocale().toString(qreal(bytes) / tb, 'f', 3));
    13391348    if (bytes >= gb)
    1340         return QLocale().toString(bytes / gb) + QString::fromLatin1(" GB");
     1349        return QFileSystemModel::tr("%1 GB").arg(QLocale().toString(qreal(bytes) / gb, 'f', 2));
    13411350    if (bytes >= mb)
    1342         return QLocale().toString(bytes / mb) + QString::fromLatin1(" MB");
     1351        return QFileSystemModel::tr("%1 MB").arg(QLocale().toString(qreal(bytes) / mb, 'f', 1));
    13431352    if (bytes >= kb)
    1344         return QLocale().toString(bytes / kb) + QString::fromLatin1(" KB");
    1345     return QLocale().toString(bytes) + QString::fromLatin1(" bytes");
     1353        return QFileSystemModel::tr("%1 KB").arg(QLocale().toString(bytes / kb));
     1354    return QFileSystemModel::tr("%1 byte(s)").arg(QLocale().toString(bytes));
    13461355}
    13471356
  • trunk/src/gui/itemviews/qdirmodel.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qfileiconprovider.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4646#include <qapplication.h>
    4747#include <qdir.h>
     48#include <qpixmapcache.h>
    4849#if defined(Q_WS_WIN)
    49 #define _WIN32_IE 0x0500
    50 #include <objbase.h>
    51 #include <private/qpixmapdata_p.h>
    52 #include <qpixmapcache.h>
     50#  define _WIN32_IE 0x0500
     51#  include <qt_windows.h>
     52#  include <commctrl.h>
     53#  include <objbase.h>
    5354#elif defined(Q_WS_MAC)
    54 #include <private/qt_mac_p.h>
    55 #endif
     55#  include <private/qt_cocoa_helpers_mac_p.h>
     56#endif
     57
    5658#include <private/qfunctions_p.h>
    57 #ifdef Q_OS_WINCE
    58 #include <Commctrl.h>
     59#include <private/qguiplatformplugin_p.h>
     60
     61#if defined(Q_WS_X11) && !defined(Q_NO_STYLE_GTK)
     62#  include <private/qgtkstyle_p.h>
     63#  include <private/qt_x11_p.h>
    5964#endif
    6065
    6166#ifndef SHGFI_ADDOVERLAYS
    62 #define SHGFI_ADDOVERLAYS 0x000000020
     67#  define SHGFI_ADDOVERLAYS 0x000000020
    6368#endif
    6469
     
    181186QFileIconProvider::~QFileIconProvider()
    182187{
    183     delete d_ptr;
    184188}
    185189
     
    216220{
    217221    QIcon retIcon;
    218     QString fileExtension = fileInfo.suffix().toUpper();
    219     fileExtension.prepend( QLatin1String(".") );
     222    const QString fileExtension = QLatin1Char('.') + fileInfo.suffix().toUpper();
    220223
    221224    QString key;
     
    245248    //Get the small icon
    246249#ifndef Q_OS_WINCE
    247     val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
     250    val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
    248251                        sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_SMALLICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS);
    249252#else
    250     val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
     253    val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
    251254                        sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_SYSICONINDEX);
    252255#endif
     
    266269        if (pixmap.isNull()) {
    267270#ifndef Q_OS_WINCE
    268             pixmap = convertHIconToPixmap(info.hIcon);
    269 #else
    270             pixmap = convertHIconToPixmap(ImageList_GetIcon((HIMAGELIST) val, info.iIcon, ILD_NORMAL));
     271            pixmap = QPixmap::fromWinHICON(info.hIcon);
     272#else
     273            pixmap = QPixmap::fromWinHICON(ImageList_GetIcon((HIMAGELIST) val, info.iIcon, ILD_NORMAL));
    271274#endif
    272275            if (!pixmap.isNull()) {
     
    284287    //Get the big icon
    285288#ifndef Q_OS_WINCE
    286     val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
     289    val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
    287290                        sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_LARGEICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS);
    288291#else
    289     val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
     292    val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
    290293                        sizeof(SHFILEINFO), SHGFI_LARGEICON|SHGFI_SYSICONINDEX);
    291294#endif
     
    296299        }
    297300#ifndef Q_OS_WINCE
    298         pixmap = convertHIconToPixmap(info.hIcon);
    299 #else
    300         pixmap = convertHIconToPixmap(ImageList_GetIcon((HIMAGELIST) val, info.iIcon, ILD_NORMAL), true);
     301        pixmap = QPixmap::fromWinHICON(info.hIcon);
     302#else
     303        pixmap = QPixmap::fromWinHICON(ImageList_GetIcon((HIMAGELIST) val, info.iIcon, ILD_NORMAL));
    301304#endif
    302305        if (!pixmap.isNull()) {
     
    317320{
    318321    QIcon retIcon;
     322    QString fileExtension = fi.suffix().toUpper();
     323    fileExtension.prepend(QLatin1String("."));
     324
     325    const QString keyBase = QLatin1String("qt_") + fileExtension;
     326
     327    QPixmap pixmap;
     328    if (fi.isFile() && !fi.isExecutable() && !fi.isSymLink()) {
     329        QPixmapCache::find(keyBase + QLatin1String("16"), pixmap);
     330    }
     331
     332    if (!pixmap.isNull()) {
     333        retIcon.addPixmap(pixmap);
     334        if (QPixmapCache::find(keyBase + QLatin1String("32"), pixmap)) {
     335            retIcon.addPixmap(pixmap);
     336            if (QPixmapCache::find(keyBase + QLatin1String("64"), pixmap)) {
     337                retIcon.addPixmap(pixmap);
     338                if (QPixmapCache::find(keyBase + QLatin1String("128"), pixmap)) {
     339                    retIcon.addPixmap(pixmap);
     340                    return retIcon;
     341                }
     342            }
     343        }
     344    }
     345
     346
    319347    FSRef macRef;
    320348    OSStatus status = FSPathMakeRef(reinterpret_cast<const UInt8*>(fi.canonicalFilePath().toUtf8().constData()),
     
    329357    IconRef iconRef;
    330358    SInt16 iconLabel;
    331     status = GetIconRefFromFileInfo(&macRef, macName.length, macName.unicode, kIconServicesCatalogInfoMask, &info, kIconServicesNormalUsageFlag, &iconRef, &iconLabel);
     359    status = GetIconRefFromFileInfo(&macRef, macName.length, macName.unicode,
     360                                    kIconServicesCatalogInfoMask, &info, kIconServicesNormalUsageFlag,
     361                                    &iconRef, &iconLabel);
    332362    if (status != noErr)
    333363        return retIcon;
    334     extern void qt_mac_constructQIconFromIconRef(const IconRef, const IconRef, QIcon*, QStyle::StandardPixmap = QStyle::SP_CustomBase); // qmacstyle_mac.cpp
    335364    qt_mac_constructQIconFromIconRef(iconRef, 0, &retIcon);
    336365    ReleaseIconRef(iconRef);
     366
     367    pixmap = retIcon.pixmap(16);
     368    QPixmapCache::insert(keyBase + QLatin1String("16"), pixmap);
     369    pixmap = retIcon.pixmap(32);
     370    QPixmapCache::insert(keyBase + QLatin1String("32"), pixmap);
     371    pixmap = retIcon.pixmap(64);
     372    QPixmapCache::insert(keyBase + QLatin1String("64"), pixmap);
     373    pixmap = retIcon.pixmap(128);
     374    QPixmapCache::insert(keyBase + QLatin1String("128"), pixmap);
     375
    337376    return retIcon;
    338377}
     
    347386{
    348387    Q_D(const QFileIconProvider);
     388
     389    QIcon platformIcon = qt_guiPlatformPlugin()->fileSystemIcon(info);
     390    if (!platformIcon.isNull())
     391        return platformIcon;
     392
     393#if defined(Q_WS_X11) && !defined(QT_NO_STYLE_GTK)
     394    if (X11->desktopEnvironment == DE_GNOME) {
     395        QIcon gtkIcon = QGtkStylePrivate::getFilesystemIcon(info);
     396        if (!gtkIcon.isNull())
     397            return gtkIcon;
     398    }
     399#endif
     400
    349401#ifdef Q_WS_MAC
    350402    QIcon retIcon = d->getMacIcon(info);
     
    357409#endif
    358410    if (info.isRoot())
    359 #if defined (Q_WS_WIN) && !defined(Q_OS_WINCE)
     411#if defined (Q_WS_WIN) && !defined(Q_WS_WINCE)
    360412    {
    361         uint type = DRIVE_UNKNOWN;
    362         QT_WA({ type = GetDriveTypeW((wchar_t *)info.absoluteFilePath().utf16()); },
    363         { type = GetDriveTypeA(info.absoluteFilePath().toLocal8Bit()); });
     413        UINT type = GetDriveType((wchar_t *)info.absoluteFilePath().utf16());
    364414
    365415        switch (type) {
     
    417467
    418468    if (info.isDir())
    419         return QApplication::translate("QFileDialog",
    420469#ifdef Q_WS_WIN
    421                                        "File Folder", "Match Windows Explorer"
    422 #else
    423                                        "Folder", "All other platforms"
    424 #endif
    425             );
     470        return QApplication::translate("QFileDialog", "File Folder", "Match Windows Explorer");
     471#else
     472        return QApplication::translate("QFileDialog", "Folder", "All other platforms");
     473#endif
    426474    // Windows   - "File Folder"
    427475    // OS X      - "Folder"
     
    430478
    431479    if (info.isSymLink())
    432         return QApplication::translate("QFileDialog",
    433480#ifdef Q_OS_MAC
    434                                        "Alias", "Mac OS X Finder"
    435 #else
    436                                        "Shortcut", "All other platforms"
    437 #endif
    438             );
     481        return QApplication::translate("QFileDialog", "Alias", "Mac OS X Finder");
     482#else
     483        return QApplication::translate("QFileDialog", "Shortcut", "All other platforms");
     484#endif
    439485    // OS X      - "Alias"
    440486    // Windows   - "Shortcut"
  • trunk/src/gui/itemviews/qfileiconprovider.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4343#define QFILEICONPROVIDER_H
    4444
     45#include <QtCore/qfileinfo.h>
     46#include <QtCore/qscopedpointer.h>
    4547#include <QtGui/qicon.h>
    46 #include <QtCore/qfileinfo.h>
    4748
    4849QT_BEGIN_HEADER
     
    6869private:
    6970    Q_DECLARE_PRIVATE(QFileIconProvider)
    70     QFileIconProviderPrivate *d_ptr;
     71    QScopedPointer<QFileIconProviderPrivate> d_ptr;
    7172    Q_DISABLE_COPY(QFileIconProvider)
    7273};
  • trunk/src/gui/itemviews/qheaderview.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6363#ifndef QT_NO_DATASTREAM
    6464#include <qdatastream.h>
     65#endif
    6566
    6667QT_BEGIN_NAMESPACE
    6768
     69#ifndef QT_NO_DATASTREAM
    6870QDataStream &operator<<(QDataStream &out, const QHeaderViewPrivate::SectionSpan &span)
    6971{
     
    7779    return in;
    7880}
    79 #endif
     81#endif // QT_NO_DATASTREAM
    8082
    8183
     
    8789
    8890    \ingroup model-view
    89     \mainclass
     91
    9092
    9193    A QHeaderView displays the headers used in item views such as the
     
    521523{
    522524    Q_D(const QHeaderView);
    523     if (count() < 1)
    524         return QSize(0, 0);
    525525    if (d->cachedSizeHint.isValid())
    526526        return d->cachedSizeHint;
    527     int width = 0;
    528     int height = 0;
     527    d->cachedSizeHint = QSize(0, 0); //reinitialize the cached size hint
     528    const int sectionCount = count();
     529
    529530    // get size hint for the first n sections
    530     int c = qMin(count(), 100);
    531     for (int i = 0; i < c; ++i) {
     531    int i = 0;
     532    for (int checked = 0; checked < 100 && i < sectionCount; ++i) {
    532533        if (isSectionHidden(i))
    533534            continue;
     535        checked++;
    534536        QSize hint = sectionSizeFromContents(i);
    535         width = qMax(hint.width(), width);
    536         height = qMax(hint.height(), height);
     537        d->cachedSizeHint = d->cachedSizeHint.expandedTo(hint);
    537538    }
    538539    // get size hint for the last n sections
    539     c = qMax(count() - 100, c);
    540     for (int j = count() - 1; j >= c; --j) {
     540    i = qMax(i, sectionCount - 100 );
     541    for (int j = sectionCount - 1, checked = 0; j >= i && checked < 100; --j) {
    541542        if (isSectionHidden(j))
    542543            continue;
     544        checked++;
    543545        QSize hint = sectionSizeFromContents(j);
    544         width = qMax(hint.width(), width);
    545         height = qMax(hint.height(), height);
    546     }
    547     d->cachedSizeHint = QSize(width, height);
     546        d->cachedSizeHint = d->cachedSizeHint.expandedTo(hint);
     547    }
    548548    return d->cachedSizeHint;
    549549}
     
    10481048/*!
    10491049    Returns the logicalIndex for the section at the given \a visualIndex
    1050     position, or -1 otherwise.
     1050    position, or -1 if visualIndex < 0 or visualIndex >= QHeaderView::count().
     1051
     1052    Note that the visualIndex is not affected by hidden sections.
    10511053
    10521054    \sa visualIndex(), sectionPosition()
     
    11521154
    11531155    Sets the constraints on how the section specified by \a logicalIndex in
    1154     the header can be resized to those described by the given \a mode.
     1156    the header can be resized to those described by the given \a mode. The logical
     1157    index should exist at the time this function is called.
    11551158
    11561159    \note This setting will be ignored for the last section if the stretchLastSection
     
    11951198    Q_D(const QHeaderView);
    11961199    int visual = visualIndex(logicalIndex);
    1197     Q_ASSERT(visual != -1);
    1198     return d->visualIndexResizeMode(visual);
     1200    if (visual == -1)
     1201        return Fixed; //the default value
     1202    return d->headerSectionResizeMode(visual);
    11991203}
    12001204
     
    12351239        return;
    12361240
    1237     if (d->visualIndexResizeMode(sortIndicatorSection()) == ResizeToContents)
     1241    if (d->headerSectionResizeMode(sortIndicatorSection()) == ResizeToContents)
    12381242        resizeSections();
    12391243
     
    12681272    d->sortIndicatorOrder = order;
    12691273
    1270     if (logicalIndex >= d->sectionCount)
     1274    if (logicalIndex >= d->sectionCount) {
     1275        emit sortIndicatorChanged(logicalIndex, order);
    12711276        return; // nothing to do
     1277    }
    12721278
    12731279    if (old != logicalIndex
     
    13891395{
    13901396    Q_D(QHeaderView);
    1391     d->defaultSectionSize = size;
    1392     d->forceInitializing = true;
     1397    d->setDefaultSectionSize(size);
    13931398}
    13941399
     
    14151420        if (d->orientation == Qt::Horizontal)
    14161421            return qMax(strut.width(), (fontMetrics().maxWidth() + margin));
    1417         return qMax(strut.height(), (fontMetrics().lineSpacing() + margin));
     1422        return qMax(strut.height(), (fontMetrics().height() + margin));
    14181423    }
    14191424    return d->minimumSectionSize;
     
    15351540    return false;
    15361541}
    1537 #endif
     1542#endif // QT_NO_DATASTREAM
    15381543
    15391544/*!
     
    18951900        if (newCount < oldCount)
    18961901            d->updateHiddenSections(0, newCount-1);
    1897     } else if (d->forceInitializing) {
    1898         initializeSections(0, newCount - 1);
    1899         d->forceInitializing = false;
    19001902    }
    19011903}
     
    19121914    Q_ASSERT(end >= 0);
    19131915
    1914     d->executePostedLayout();
    19151916    d->invalidateCachedSizeHint();
    19161917
     
    19381939
    19391940    if (!d->logicalIndices.isEmpty()) {
    1940         d->logicalIndices.resize(d->sectionCount);
    1941         d->visualIndices.resize(d->sectionCount);
    1942         for (int i = start; i < d->sectionCount; ++i){
    1943             d->logicalIndices[i] = i;
    1944             d->visualIndices[i] = i;
     1941        if (oldCount <= d->sectionCount) {
     1942            d->logicalIndices.resize(d->sectionCount);
     1943            d->visualIndices.resize(d->sectionCount);
     1944            for (int i = oldCount; i < d->sectionCount; ++i) {
     1945                d->logicalIndices[i] = i;
     1946                d->visualIndices[i] = i;
     1947            }
     1948        } else {
     1949            int j = 0;
     1950            for (int i = 0; i < oldCount; ++i) {
     1951                int v = d->logicalIndices.at(i);
     1952                if (v < d->sectionCount) {
     1953                    d->logicalIndices[j] = v;
     1954                    d->visualIndices[v] = j;
     1955                    j++;
     1956                }
     1957            }
     1958            d->logicalIndices.resize(d->sectionCount);
     1959            d->visualIndices.resize(d->sectionCount);
    19451960        }
    19461961    }
     
    19531968        d->sectionHidden.resize(d->sectionCount);
    19541969
    1955     if (d->sectionCount > oldCount || d->forceInitializing)
     1970    if (d->sectionCount > oldCount)
    19561971        d->createSectionSpan(start, end, (end - start + 1) * d->defaultSectionSize, d->globalResizeMode);
    19571972    //Q_ASSERT(d->headerLength() == d->length);
     
    19721987    if (d->orientation == Qt::Horizontal && current.column() != old.column()) {
    19731988        if (old.isValid() && old.parent() == d->root)
    1974             d->setDirtyRegion(QRect(sectionViewportPosition(old.column()), 0,
     1989            d->viewport->update(QRect(sectionViewportPosition(old.column()), 0,
    19751990                                    sectionSize(old.column()), d->viewport->height()));
    19761991        if (current.isValid() && current.parent() == d->root)
    1977             d->setDirtyRegion(QRect(sectionViewportPosition(current.column()), 0,
     1992            d->viewport->update(QRect(sectionViewportPosition(current.column()), 0,
    19781993                                    sectionSize(current.column()), d->viewport->height()));
    19791994    } else if (d->orientation == Qt::Vertical && current.row() != old.row()) {
    19801995        if (old.isValid() && old.parent() == d->root)
    1981             d->setDirtyRegion(QRect(0, sectionViewportPosition(old.row()),
     1996            d->viewport->update(QRect(0, sectionViewportPosition(old.row()),
    19821997                                    d->viewport->width(), sectionSize(old.row())));
    19831998        if (current.isValid() && current.parent() == d->root)
    1984             d->setDirtyRegion(QRect(0, sectionViewportPosition(current.row()),
     1999            d->viewport->update(QRect(0, sectionViewportPosition(current.row()),
    19852000                                    d->viewport->width(), sectionSize(current.row())));
    19862001    }
    1987     d->updateDirtyRegion();
    19882002}
    19892003
     
    23962410        d->pressed = d->section = d->target = -1;
    23972411        d->updateSectionIndicator(d->section, -1);
    2398     }
     2412        break; }
     2413    case QEvent::Wheel: {
     2414        QAbstractScrollArea *asa = qobject_cast<QAbstractScrollArea *>(parentWidget());
     2415        if (asa)
     2416            return QApplication::sendEvent(asa->viewport(), e);
     2417        break; }
    23992418    default:
    24002419        break;
     
    25162535    Q_ASSERT(logicalIndex >= 0);
    25172536
     2537    ensurePolished();
     2538
    25182539    // use SizeHintRole
    25192540    QVariant variant = d->model->headerData(logicalIndex, d->orientation, Qt::SizeHintRole);
     
    25412562        opt.icon = qvariant_cast<QPixmap>(variant);
    25422563    QSize size = style()->sizeFromContents(QStyle::CT_HeaderSection, &opt, QSize(), this);
    2543     if (isSortIndicatorShown() && sortIndicatorSection() == logicalIndex) {
     2564    if (isSortIndicatorShown()) {
    25442565        int margin = style()->pixelMetric(QStyle::PM_HeaderMargin, &opt, this);
    25452566        if (d->orientation == Qt::Horizontal)
     
    26182639        int last = orientation() == Qt::Horizontal ? bottomRight.column() : bottomRight.row();
    26192640        for (int i = first; i <= last && !resizeRequired; ++i)
    2620             resizeRequired = (resizeRequired && resizeMode(i));
     2641            resizeRequired = (resizeMode(i) == ResizeToContents);
    26212642        if (resizeRequired)
    26222643            d->doDelayedResizeSections();
     
    28242845    }
    28252846
    2826     int x, y, w, h;
     2847    int w, h;
    28272848    int p = q->sectionViewportPosition(section);
    28282849    if (orientation == Qt::Horizontal) {
    2829         x = p;
    2830         y = 0;
    28312850        w = q->sectionSize(section);
    28322851        h = viewport->height();
    28332852    } else {
    2834         x = 0;
    2835         y = p;
    28362853        w = viewport->width();
    28372854        h = q->sectionSize(section);
     
    29392956{
    29402957    Q_Q(QHeaderView);
     2958    //stop the timer in case it is delayed
     2959    delayedResize.stop();
    29412960
    29422961    executePostedLayout();
    29432962    if (sectionCount == 0)
    29442963        return;
     2964
     2965    if (resizeRecursionBlock)
     2966        return;
     2967    resizeRecursionBlock = true;
     2968
    29452969    invalidateCachedSizeHint();
     2970
     2971    const int lastVisibleSection = lastVisibleVisualIndex();
    29462972
    29472973    // find stretchLastSection if we have it
    29482974    int stretchSection = -1;
    2949     if (stretchLastSection && !useGlobalMode) {
    2950         for (int i = sectionCount - 1; i >= 0; --i) {
    2951             if (!isVisualIndexHidden(i)) {
    2952                 stretchSection = i;
    2953                 break;
    2954             }
    2955         }
    2956     }
     2975    if (stretchLastSection && !useGlobalMode)
     2976        stretchSection = lastVisibleVisualIndex();
    29572977
    29582978    // count up the number of strected sections and how much space left for them
     
    29682988            resizeMode = globalMode;
    29692989        else
    2970             resizeMode = (i == stretchSection ? QHeaderView::Stretch : visualIndexResizeMode(i));
     2990            resizeMode = (i == stretchSection ? QHeaderView::Stretch : headerSectionResizeMode(i));
    29712991
    29722992        if (resizeMode == QHeaderView::Stretch) {
     
    30003020    int spanStartSection = 0;
    30013021    int previousSectionLength = 0;
    3002     const int lastVisibleSection = lastVisibleVisualIndex();
    30033022
    30043023    QHeaderView::ResizeMode previousSectionResizeMode = QHeaderView::Interactive;
     
    30193038                resizeMode = (i == stretchSection
    30203039                              ? QHeaderView::Stretch
    3021                               : visualIndexResizeMode(i));
     3040                              : newSectionResizeMode);
    30223041            if (resizeMode == QHeaderView::Stretch && stretchSectionLength != -1) {
    30233042                if (i == lastVisibleSection)
     
    30563075                      previousSectionResizeMode);
    30573076    //Q_ASSERT(headerLength() == length);
    3058 
     3077    resizeRecursionBlock = false;
    30593078    viewport->update();
    30603079}
     
    33653384}
    33663385
     3386void QHeaderViewPrivate::setDefaultSectionSize(int size)
     3387{
     3388    Q_Q(QHeaderView);
     3389    defaultSectionSize = size;
     3390    int currentVisualIndex = 0;
     3391    for (int i = 0; i < sectionSpans.count(); ++i) {
     3392        QHeaderViewPrivate::SectionSpan &span = sectionSpans[i];
     3393        if (span.size > 0) {
     3394            //we resize it if it is not hidden (ie size > 0)
     3395            const int newSize = span.count * size;
     3396            if (newSize != span.size) {
     3397                length += newSize - span.size; //the whole length is changed
     3398                const int oldSectionSize = span.sectionSize();
     3399                span.size = span.count * size;
     3400                for (int i = currentVisualIndex; i < currentVisualIndex + span.count; ++i) {
     3401                    emit q->sectionResized(logicalIndex(i), oldSectionSize, size);
     3402                }
     3403            }
     3404        }
     3405        currentVisualIndex += span.count;
     3406    }
     3407}
     3408
    33673409void QHeaderViewPrivate::resizeSectionSpan(int visualIndex, int oldSize, int newSize)
    33683410{
     
    34503492int QHeaderViewPrivate::viewSectionSizeHint(int logical) const
    34513493{
    3452     Q_Q(const QHeaderView);
    3453     if (QAbstractItemView *parent = qobject_cast<QAbstractItemView*>(q->parent())) {
     3494    if (QAbstractItemView *view = qobject_cast<QAbstractItemView*>(parent)) {
    34543495        return (orientation == Qt::Horizontal
    3455                 ? parent->sizeHintForColumn(logical)
    3456                 : parent->sizeHintForRow(logical));
     3496                ? view->sizeHintForColumn(logical)
     3497                : view->sizeHintForRow(logical));
    34573498    }
    34583499    return 0;
     
    35403581
    35413582    in >> align;
    3542     defaultAlignment = (Qt::Alignment)align;
     3583    defaultAlignment = Qt::Alignment(align);
    35433584
    35443585    in >> global;
     
    35503591}
    35513592
     3593#endif // QT_NO_DATASTREAM
     3594
    35523595QT_END_NAMESPACE
    35533596
    3554 #endif // QT_NO_DATASTREAEM
    3555 
    35563597#endif // QT_NO_ITEMVIEWS
    35573598
  • trunk/src/gui/itemviews/qheaderview.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    222222
    223223    QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers);
    224     void setSelection(const QRect&, QItemSelectionModel::SelectionFlags);
     224    void setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags flags);
    225225    QRegion visualRegionForSelection(const QItemSelection &selection) const;
    226226    void initStyleOption(QStyleOptionHeader *option) const;
     
    229229    Q_PRIVATE_SLOT(d_func(), void _q_sectionsRemoved(const QModelIndex &parent, int logicalFirst, int logicalLast))
    230230    Q_PRIVATE_SLOT(d_func(), void _q_layoutAboutToBeChanged())
    231     Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged())
    232231    Q_DECLARE_PRIVATE(QHeaderView)
    233232    Q_DISABLE_COPY(QHeaderView)
  • trunk/src/gui/itemviews/qheaderview_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    9191          stretchLastSection(false),
    9292          cascadingResizing(false),
    93           forceInitializing(false),
     93          resizeRecursionBlock(false),
    9494          stretchSections(0),
    9595          contentsSections(0),
     
    171171    }
    172172
    173     inline QHeaderView::ResizeMode visualIndexResizeMode(int visual) const {
    174         return headerSectionResizeMode(visual);
    175     }
    176 
    177173    inline bool hasAutoResizeSections() const {
    178174        return stretchSections || stretchLastSection || contentsSections;
     
    212208
    213209    inline bool sectionIsCascadable(int visual) const {
    214         return visualIndexResizeMode(visual) == QHeaderView::Interactive;
     210        return headerSectionResizeMode(visual) == QHeaderView::Interactive;
    215211    }
    216212
     
    232228    inline void executePostedResize() const {
    233229        if (delayedResize.isActive() && state == NoState) {
    234             delayedResize.stop();
    235230            const_cast<QHeaderView*>(q_func())->resizeSections();
    236231        }
     
    276271    bool stretchLastSection;
    277272    bool cascadingResizing;
    278     bool forceInitializing;
     273    bool resizeRecursionBlock;
    279274    int stretchSections;
    280275    int contentsSections;
     
    311306    void removeSectionsFromSpans(int start, int end);
    312307    void resizeSectionSpan(int visualIndex, int oldSize, int newSize);
     308    void setDefaultSectionSize(int size);
    313309
    314310    inline int headerSectionCount() const { // for debugging
  • trunk/src/gui/itemviews/qitemdelegate.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4848#include <qlineedit.h>
    4949#include <qtextedit.h>
     50#include <qplaintextedit.h>
    5051#include <qpainter.h>
    5152#include <qpalette.h>
     
    185186
    186187    \ingroup model-view
    187     \mainclass
     188
    188189
    189190    QItemDelegate can be used to provide custom display features and editor
     
    219220    while editing takes place. Editors are created with a
    220221    QItemEditorFactory; a default static instance provided by
    221     QItemEditorFactory is installed on all item delagates. You can set
     222    QItemEditorFactory is installed on all item delegates. You can set
    222223    a custom factory using setItemEditorFactory() or set a new default
    223224    factory with QItemEditorFactory::setDefaultFactory(). It is the
     
    255256    \row    \o \l Qt::BackgroundColorRole \o QColor (obsolete; use Qt::BackgroundRole instead)
    256257    \row    \o \l Qt::CheckStateRole \o Qt::CheckState
    257     \row    \o \l Qt::DecorationRole \o QIcon and QColor
     258    \row    \o \l Qt::DecorationRole \o QIcon, QPixmap and QColor
    258259    \row    \o \l Qt::DisplayRole \o QString and types with a string representation
    259260    \row    \o \l Qt::EditRole \o See QItemEditorFactory for details
     
    352353{
    353354    QString text;
    354     switch (value.type()) {
     355    switch (value.userType()) {
     356        case QMetaType::Float:
     357            text = option.locale.toString(value.toFloat(), 'g');
     358            break;
    355359        case QVariant::Double:
    356360            text = option.locale.toString(value.toDouble(), 'g', DBL_DIG);
     
    574578
    575579/*!
    576     Gets data drom the \a editor widget and stores it in the specified
     580    Gets data from the \a editor widget and stores it in the specified
    577581    \a model at the item \a index.
    578582
     
    719723            elided += option.fontMetrics.elidedText(text.mid(start),
    720724                                                    option.textElideMode, textRect.width());
    721             if (end != -1)
    722                 elided += QChar::LineSeparator;
    723725        }
    724726        d->textLayout.setText(elided);
     
    861863/*!
    862864    \internal
     865
     866    Code duplicated in QCommonStylePrivate::viewItemLayout
    863867*/
    864868
     
    882886
    883887    textRect->adjust(-textMargin, 0, textMargin, 0); // add width padding
    884     if (textRect->height() == 0 && !hasPixmap)
     888    if (textRect->height() == 0 && (!hasPixmap || !hint)) {
     889        //if there is no text, we still want to have a decent height for the item sizeHint and the editor size
    885890        textRect->setHeight(option.fontMetrics.height());
     891    }
    886892
    887893    QSize pm(0, 0);
     
    10541060
    10551061        QPixmap selected = QPixmap(QPixmap::fromImage(img));
    1056         int n = (img.numBytes() >> 10) + 1;
     1062        int n = (img.byteCount() >> 10) + 1;
    10571063        if (QPixmapCache::cacheLimit() < n)
    10581064            QPixmapCache::setCacheLimit(n);
     
    11951201        case Qt::Key_Return:
    11961202#ifndef QT_NO_TEXTEDIT
    1197             if (qobject_cast<QTextEdit*>(editor))
     1203            if (qobject_cast<QTextEdit *>(editor) || qobject_cast<QPlainTextEdit *>(editor))
    11981204                return false; // don't filter enter key events for QTextEdit
    11991205            // We want the editor to be able to process the key press
     
    12191225            editor->parentWidget()->setFocus();
    12201226        return true;
    1221     } else if (event->type() == QEvent::FocusOut || event->type() == QEvent::Hide) {
     1227    } else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) {
    12221228        //the Hide event will take care of he editors that are in fact complete dialogs
    12231229        if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) {
     
    12341240                return false;
    12351241#endif
    1236             // Opening a modal dialog will start a new eventloop
    1237             // that will process the deleteLater event.
    1238             if (QApplication::activeModalWidget()
    1239                 && !QApplication::activeModalWidget()->isAncestorOf(editor)
    1240                 && qobject_cast<QDialog*>(QApplication::activeModalWidget()))
    1241                 return false;
     1242
    12421243            emit commitData(editor);
    12431244            emit closeEditor(editor, NoHint);
     
    12971298    }
    12981299
    1299     Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
     1300    Qt::CheckState state;
     1301    if ( flags & Qt::ItemIsTristate ) {
     1302        state = static_cast<Qt::CheckState>( (value.toInt() + 1) % 3 );
     1303    } else {
     1304        state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
    13001305                            ? Qt::Unchecked : Qt::Checked);
     1306    }
     1307
    13011308    return model->setData(index, state, Qt::CheckStateRole);
    13021309}
     
    13211328    value = index.data(Qt::TextAlignmentRole);
    13221329    if (value.isValid())
    1323         opt.displayAlignment = (Qt::Alignment)value.toInt();
     1330        opt.displayAlignment = Qt::Alignment(value.toInt());
    13241331
    13251332    // set foreground brush
  • trunk/src/gui/itemviews/qitemdelegate.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qitemeditorfactory.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    159159QItemEditorFactory::~QItemEditorFactory()
    160160{
     161    //we make sure we delete all the QItemEditorCreatorBase
     162    //this has to be done only once, hence the QSet
     163    QSet<QItemEditorCreatorBase*> set = creatorMap.values().toSet();
     164    qDeleteAll(set);
    161165}
    162166
     
    171175void QItemEditorFactory::registerEditor(QVariant::Type type, QItemEditorCreatorBase *creator)
    172176{
    173    delete creatorMap.value(type, 0);
    174    creatorMap[type] = creator;
     177    QHash<QVariant::Type, QItemEditorCreatorBase *>::iterator it = creatorMap.find(type);
     178    if (it != creatorMap.end()) {
     179        QItemEditorCreatorBase *oldCreator = it.value();
     180        Q_ASSERT(oldCreator);
     181        creatorMap.erase(it);
     182        if (!creatorMap.values().contains(oldCreator))
     183            delete oldCreator; // if it is no more in use we can delete it
     184    }
     185
     186    creatorMap[type] = creator;
    175187}
    176188
  • trunk/src/gui/itemviews/qitemeditorfactory.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qitemeditorfactory_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qitemselectionmodel.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    271271*/
    272272
    273 /*!
    274     Returns the list of model index items stored in the selection.
    275 */
    276 
    277 QModelIndexList QItemSelectionRange::indexes() const
    278 {
    279     QModelIndex index;
    280     QModelIndexList result;
    281     if (isValid() && model()) {
    282         for (int column = left(); column <= right(); ++column) {
    283             for (int row = top(); row <= bottom(); ++row) {
    284                 index = model()->index(row, column, parent());
    285                 Qt::ItemFlags flags = model()->flags(index);
     273/*
     274  \internal
     275
     276  utility function for getting the indexes from a range
     277  it avoid concatenating list and works on one
     278 */
     279
     280static void indexesFromRange(const QItemSelectionRange &range, QModelIndexList &result)
     281{
     282    if (range.isValid() && range.model()) {
     283        for (int column = range.left(); column <= range.right(); ++column) {
     284            for (int row = range.top(); row <= range.bottom(); ++row) {
     285                QModelIndex index = range.model()->index(row, column, range.parent());
     286                Qt::ItemFlags flags = range.model()->flags(index);
    286287                if ((flags & Qt::ItemIsSelectable) && (flags & Qt::ItemIsEnabled))
    287288                    result.append(index);
     
    289290        }
    290291    }
     292}
     293
     294/*!
     295    Returns the list of model index items stored in the selection.
     296*/
     297
     298QModelIndexList QItemSelectionRange::indexes() const
     299{
     300    QModelIndexList result;
     301    indexesFromRange(*this, result);
    291302    return result;
    292303}
    293304
    294305/*!
    295   \class QItemSelection
    296 
    297   \brief The QItemSelection class manages information about selected items in a model.
    298 
    299   \ingroup model-view
    300 
    301   A QItemSelection describes the items in a model that have been
    302   selected by the user. A QItemSelection is basically a list of
    303   selection ranges, see QItemSelectionRange. It provides functions for
    304   creating and manipulating selections, and selecting a range of items
    305   from a model.
    306 
    307   The QItemSelection class is one of the \l{Model/View Classes}
    308   and is part of Qt's \l{Model/View Programming}{model/view framework}.
    309 
    310   An item selection can be constructed and initialized to contain a
    311   range of items from an existing model. The following example constructs
    312   a selection that contains a range of items from the given \c model,
    313   beginning at the \c topLeft, and ending at the \c bottomRight.
    314 
    315   \snippet doc/src/snippets/code/src_gui_itemviews_qitemselectionmodel.cpp 0
    316 
    317   An empty item selection can be constructed, and later populated as
    318   required. So, if the model is going to be unavailable when we construct
    319   the item selection, we can rewrite the above code in the following way:
    320 
    321   \snippet doc/src/snippets/code/src_gui_itemviews_qitemselectionmodel.cpp 1
    322 
    323   QItemSelection saves memory, and avoids unnecessary work, by working with
    324   selection ranges rather than recording the model item index for each
    325   item in the selection. Generally, an instance of this class will contain
    326   a list of non-overlapping selection ranges.
    327 
    328   Use merge() to merge one item selection into another without making
    329   overlapping ranges. Use split() to split one selection range into
    330   smaller ranges based on a another selection range.
    331 
    332   \sa {Model/View Programming}, QItemSelectionModel
    333 
     306    \class QItemSelection
     307
     308    \brief The QItemSelection class manages information about selected items in a model.
     309
     310    \ingroup model-view
     311
     312    A QItemSelection describes the items in a model that have been
     313    selected by the user. A QItemSelection is basically a list of
     314    selection ranges, see QItemSelectionRange. It provides functions for
     315    creating and manipulating selections, and selecting a range of items
     316    from a model.
     317
     318    The QItemSelection class is one of the \l{Model/View Classes}
     319    and is part of Qt's \l{Model/View Programming}{model/view framework}.
     320
     321    An item selection can be constructed and initialized to contain a
     322    range of items from an existing model. The following example constructs
     323    a selection that contains a range of items from the given \c model,
     324    beginning at the \c topLeft, and ending at the \c bottomRight.
     325
     326    \snippet doc/src/snippets/code/src_gui_itemviews_qitemselectionmodel.cpp 0
     327
     328    An empty item selection can be constructed, and later populated as
     329    required. So, if the model is going to be unavailable when we construct
     330    the item selection, we can rewrite the above code in the following way:
     331
     332    \snippet doc/src/snippets/code/src_gui_itemviews_qitemselectionmodel.cpp 1
     333
     334    QItemSelection saves memory, and avoids unnecessary work, by working with
     335    selection ranges rather than recording the model item index for each
     336    item in the selection. Generally, an instance of this class will contain
     337    a list of non-overlapping selection ranges.
     338
     339    Use merge() to merge one item selection into another without making
     340    overlapping ranges. Use split() to split one selection range into
     341    smaller ranges based on a another selection range.
     342
     343    \sa {Model/View Programming}, QItemSelectionModel
    334344*/
    335345
     
    405415    QList<QItemSelectionRange>::const_iterator it = begin();
    406416    for (; it != end(); ++it)
    407         result += (*it).indexes();
     417        indexesFromRange(*it, result);
    408418    return result;
    409419}
    410420
    411421/*!
    412   Merges the \a other selection with this QItemSelection using the
    413   \a command given. This method guarantees that no ranges are overlapping.
    414 
    415   Note that only QItemSelectionModel::Select,
    416   QItemSelectionModel::Deselect, and QItemSelectionModel::Toggle are
    417   supported.
    418 
    419   \sa split()
     422    Merges the \a other selection with this QItemSelection using the
     423    \a command given. This method guarantees that no ranges are overlapping.
     424
     425    Note that only QItemSelectionModel::Select,
     426    QItemSelectionModel::Deselect, and QItemSelectionModel::Toggle are
     427    supported.
     428
     429    \sa split()
    420430*/
    421431void QItemSelection::merge(const QItemSelection &other, QItemSelectionModel::SelectionFlags command)
     
    469479
    470480/*!
    471   Splits the selection \a range using the selection \a other range.
    472   Removes all items in \a other from \a range and puts the result in \a result.
    473   This can be compared with the semantics of the \e subtract operation of a set.
    474   \sa merge()
     481    Splits the selection \a range using the selection \a other range.
     482    Removes all items in \a other from \a range and puts the result in \a result.
     483    This can be compared with the semantics of the \e subtract operation of a set.
     484    \sa merge()
    475485*/
    476486
     
    519529
    520530/*!
    521   \internal
    522 
    523   returns a QItemSelection where all ranges have been expanded to:
    524   Rows: left: 0 and right: columnCount()-1
    525   Columns: top: 0 and bottom: rowCount()-1
     531    \internal
     532
     533    returns a QItemSelection where all ranges have been expanded to:
     534    Rows: left: 0 and right: columnCount()-1
     535    Columns: top: 0 and bottom: rowCount()-1
    526536*/
    527537
     
    558568
    559569/*!
    560   \internal
     570    \internal
    561571*/
    562572void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &parent,
     
    564574{
    565575    Q_Q(QItemSelectionModel);
     576    finalize();
    566577
    567578    // update current index
     
    581592    }
    582593
    583     // update selectionsx
    584     QModelIndex tl = model->index(start, 0, parent);
    585     QModelIndex br = model->index(end, model->columnCount(parent) - 1, parent);
    586     q->select(QItemSelection(tl, br), QItemSelectionModel::Deselect);
    587     finalize();
    588 }
    589 
    590 /*!
    591   \internal
     594    QItemSelection deselected;
     595    QItemSelection::iterator it = ranges.begin();
     596    while (it != ranges.end()) {
     597        if (it->topLeft().parent() != parent) {  // Check parents until reaching root or contained in range
     598            QModelIndex itParent = it->topLeft().parent();
     599            while (itParent.isValid() && itParent.parent() != parent)
     600                itParent = itParent.parent();
     601
     602            if (itParent.isValid() && start <= itParent.row() && itParent.row() <= end) {
     603                deselected.append(*it);
     604                it = ranges.erase(it);
     605            } else {
     606                ++it;
     607            }
     608        } else if (start <= it->bottom() && it->bottom() <= end    // Full inclusion
     609                   && start <= it->top() && it->top() <= end) {
     610            deselected.append(*it);
     611            it = ranges.erase(it);
     612        } else if (start <= it->top() && it->top() <= end) {      // Top intersection
     613            deselected.append(QItemSelectionRange(it->topLeft(), model->index(end, it->left(), it->parent())));
     614            *it = QItemSelectionRange(model->index(end + 1, it->left(), it->parent()), it->bottomRight());
     615            ++it;
     616        } else if (start <= it->bottom() && it->bottom() <= end) {    // Bottom intersection
     617            deselected.append(QItemSelectionRange(model->index(start, it->right(), it->parent()), it->bottomRight()));
     618            *it = QItemSelectionRange(it->topLeft(), model->index(start - 1, it->right(), it->parent()));
     619            ++it;
     620        } else {
     621            if (it->top() < start && end < it->bottom())  // Middle intersection (do nothing)
     622                deselected.append(QItemSelectionRange(model->index(start, it->right(), it->parent()),
     623                                                      model->index(end, it->left(), it->parent())));
     624            ++it;
     625       }
     626    }
     627
     628    if (!deselected.isEmpty())
     629        emit q->selectionChanged(QItemSelection(), deselected);
     630}
     631
     632/*!
     633    \internal
    592634*/
    593635void QItemSelectionModelPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &parent,
     
    620662
    621663/*!
    622   \internal
    623 
    624   Split selection ranges if columns are about to be inserted in the middle.
     664    \internal
     665
     666    Split selection ranges if columns are about to be inserted in the middle.
    625667*/
    626668void QItemSelectionModelPrivate::_q_columnsAboutToBeInserted(const QModelIndex &parent,
     
    649691
    650692/*!
    651   \internal
    652 
    653   Split selection ranges if rows are about to be inserted in the middle.
     693    \internal
     694
     695    Split selection ranges if rows are about to be inserted in the middle.
    654696*/
    655697void QItemSelectionModelPrivate::_q_rowsAboutToBeInserted(const QModelIndex &parent,
     
    678720
    679721/*!
    680   \internal
    681 
    682   Split selection into individual (persistent) indexes. This is done in
    683   preparation for the layoutChanged() signal, where the indexes can be
    684   merged again.
     722    \internal
     723
     724    Split selection into individual (persistent) indexes. This is done in
     725    preparation for the layoutChanged() signal, where the indexes can be
     726    merged again.
    685727*/
    686728void QItemSelectionModelPrivate::_q_layoutAboutToBeChanged()
     
    689731    savedPersistentCurrentIndexes.clear();
    690732
    691     // special case for when all indexes are selected
     733    // optimisation for when all indexes are selected
     734    // (only if there is lots of items (1000) because this is not entirely correct)
    692735    if (ranges.isEmpty() && currentSelection.count() == 1) {
    693736        QItemSelectionRange range = currentSelection.first();
    694737        QModelIndex parent = range.parent();
    695         if (range.top() == 0
     738        tableRowCount = model->rowCount(parent);
     739        tableColCount = model->columnCount(parent);
     740        if (tableRowCount * tableColCount > 1000
     741            && range.top() == 0
    696742            && range.left() == 0
    697             && range.bottom() == model->rowCount(parent) - 1
    698             && range.right() == model->columnCount(parent) - 1) {
     743            && range.bottom() == tableRowCount - 1
     744            && range.right() == tableColCount - 1) {
    699745            tableSelected = true;
    700746            tableParent = parent;
    701             tableColCount = model->columnCount(parent);
    702             tableRowCount = model->rowCount(parent);
    703747            return;
    704748        }
     
    716760
    717761/*!
    718   \internal
    719 
    720   Merges \a indexes into an item selection made up of ranges.
    721   Assumes that the indexes are sorted.
     762    \internal
     763
     764    Merges \a indexes into an item selection made up of ranges.
     765    Assumes that the indexes are sorted.
    722766*/
    723767static QItemSelection mergeIndexes(const QList<QPersistentModelIndex> &indexes)
     
    764808
    765809/*!
    766   \internal
    767 
    768   Merge the selected indexes into selection ranges again.
     810    \internal
     811
     812    Merge the selected indexes into selection ranges again.
    769813*/
    770814void QItemSelectionModelPrivate::_q_layoutChanged()
     
    808852
    809853/*!
    810   \class QItemSelectionModel
    811 
    812   \brief The QItemSelectionModel class keeps track of a view's selected items.
    813 
    814   \ingroup model-view
    815 
    816   A QItemSelectionModel keeps track of the selected items in a view, or
    817   in several views onto the same model. It also keeps track of the
    818   currently selected item in a view.
    819 
    820   The QItemSelectionModel class is one of the \l{Model/View Classes}
    821   and is part of Qt's \l{Model/View Programming}{model/view framework}.
    822 
    823   The selected items are stored using ranges. Whenever you want to
    824   modify the selected items use select() and provide either a
    825   QItemSelection, or a QModelIndex and a QItemSelectionModel::SelectionFlag.
    826 
    827   The QItemSelectionModel takes a two layer approach to selection
    828   management, dealing with both selected items that have been committed
    829   and items that are part of the current selection. The current
    830   selected items are part of the current interactive selection (for
    831   example with rubber-band selection or keyboard-shift selections).
    832 
    833   To update the currently selected items, use the bitwise OR of
    834   QItemSelectionModel::Current and any of the other SelectionFlags.
    835   If you omit the QItemSelectionModel::Current command, a new current
    836   selection will be created, and the previous one added to the whole
    837   selection. All functions operate on both layers; for example,
    838   selectedItems() will return items from both layers.
    839 
    840   \sa {Model/View Programming}, QAbstractItemModel, {Chart Example}
    841 */
    842 
    843 /*!
    844   Constructs a selection model that operates on the specified item \a model.
     854    \class QItemSelectionModel
     855
     856    \brief The QItemSelectionModel class keeps track of a view's selected items.
     857
     858    \ingroup model-view
     859
     860    A QItemSelectionModel keeps track of the selected items in a view, or
     861    in several views onto the same model. It also keeps track of the
     862    currently selected item in a view.
     863
     864    The QItemSelectionModel class is one of the \l{Model/View Classes}
     865    and is part of Qt's \l{Model/View Programming}{model/view framework}.
     866
     867    The selected items are stored using ranges. Whenever you want to
     868    modify the selected items use select() and provide either a
     869    QItemSelection, or a QModelIndex and a QItemSelectionModel::SelectionFlag.
     870
     871    The QItemSelectionModel takes a two layer approach to selection
     872    management, dealing with both selected items that have been committed
     873    and items that are part of the current selection. The current
     874    selected items are part of the current interactive selection (for
     875    example with rubber-band selection or keyboard-shift selections).
     876
     877    To update the currently selected items, use the bitwise OR of
     878    QItemSelectionModel::Current and any of the other SelectionFlags.
     879    If you omit the QItemSelectionModel::Current command, a new current
     880    selection will be created, and the previous one added to the whole
     881    selection. All functions operate on both layers; for example,
     882    selectedItems() will return items from both layers.
     883
     884    \sa {Model/View Programming}, QAbstractItemModel, {Chart Example}
     885*/
     886
     887/*!
     888    Constructs a selection model that operates on the specified item \a model.
    845889*/
    846890QItemSelectionModel::QItemSelectionModel(QAbstractItemModel *model)
     
    865909
    866910/*!
    867   Constructs a selection model that operates on the specified item \a model with \a parent.
     911    Constructs a selection model that operates on the specified item \a model with \a parent.
    868912*/
    869913QItemSelectionModel::QItemSelectionModel(QAbstractItemModel *model, QObject *parent)
     
    888932
    889933/*!
    890   \internal
     934    \internal
    891935*/
    892936QItemSelectionModel::QItemSelectionModel(QItemSelectionModelPrivate &dd, QAbstractItemModel *model)
     
    911955
    912956/*!
    913   Destroys the selection model.
     957    Destroys the selection model.
    914958*/
    915959QItemSelectionModel::~QItemSelectionModel()
     
    933977
    934978/*!
    935   Selects the model item \a index using the specified \a command, and emits
    936   selectionChanged().
    937 
    938   \sa QItemSelectionModel::SelectionFlags
     979    Selects the model item \a index using the specified \a command, and emits
     980    selectionChanged().
     981
     982    \sa QItemSelectionModel::SelectionFlags
    939983*/
    940984void QItemSelectionModel::select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command)
     
    945989
    946990/*!
    947    \fn void QItemSelectionModel::currentChanged(const QModelIndex &current, const QModelIndex &previous)
    948 
    949    This signal is emitted whenever the current item changes. The \a previous
    950    model item index is replaced by the \a current index as the selection's
    951    current item.
    952 
    953    Note that this signal will not be emitted when the item model is reset.
    954 
    955    \sa currentIndex() setCurrentIndex() selectionChanged()
    956 */
    957 
    958 /*!
    959    \fn void QItemSelectionModel::currentColumnChanged(const QModelIndex &current, const QModelIndex &previous)
    960 
    961    This signal is emitted if the \a current item changes and its column is
    962    different to the column of the \a previous current item.
    963 
    964    Note that this signal will not be emitted when the item model is reset.
    965 
    966    \sa currentChanged() currentRowChanged() currentIndex() setCurrentIndex()
    967 */
    968 
    969 /*!
    970    \fn void QItemSelectionModel::currentRowChanged(const QModelIndex &current, const QModelIndex &previous)
    971 
    972    This signal is emitted if the \a current item changes and its row is
    973    different to the row of the \a previous current item.
    974 
    975    Note that this signal will not be emitted when the item model is reset.
    976 
    977    \sa currentChanged() currentColumnChanged() currentIndex() setCurrentIndex()
     991    \fn void QItemSelectionModel::currentChanged(const QModelIndex &current, const QModelIndex &previous)
     992
     993    This signal is emitted whenever the current item changes. The \a previous
     994    model item index is replaced by the \a current index as the selection's
     995    current item.
     996
     997    Note that this signal will not be emitted when the item model is reset.
     998
     999    \sa currentIndex() setCurrentIndex() selectionChanged()
     1000*/
     1001
     1002/*!
     1003    \fn void QItemSelectionModel::currentColumnChanged(const QModelIndex &current, const QModelIndex &previous)
     1004
     1005    This signal is emitted if the \a current item changes and its column is
     1006    different to the column of the \a previous current item.
     1007
     1008    Note that this signal will not be emitted when the item model is reset.
     1009
     1010    \sa currentChanged() currentRowChanged() currentIndex() setCurrentIndex()
     1011*/
     1012
     1013/*!
     1014    \fn void QItemSelectionModel::currentRowChanged(const QModelIndex &current, const QModelIndex &previous)
     1015
     1016    This signal is emitted if the \a current item changes and its row is
     1017    different to the row of the \a previous current item.
     1018
     1019    Note that this signal will not be emitted when the item model is reset.
     1020
     1021    \sa currentChanged() currentColumnChanged() currentIndex() setCurrentIndex()
    9781022*/
    9791023
     
    9921036
    9931037/*!
    994   \enum QItemSelectionModel::SelectionFlag
    995 
    996   This enum describes the way the selection model will be updated.
    997 
    998   \value NoUpdate       No selection will be made.
    999   \value Clear          The complete selection will be cleared.
    1000   \value Select         All specified indexes will be selected.
    1001   \value Deselect       All specified indexes will be deselected.
    1002   \value Toggle         All specified indexes will be selected or
    1003                         deselected depending on their current state.
    1004   \value Current        The current selection will be updated.
    1005   \value Rows           All indexes will be expanded to span rows.
    1006   \value Columns        All indexes will be expanded to span columns.
    1007   \value SelectCurrent  A combination of Select and Current, provided for
    1008                         convenience.
    1009   \value ToggleCurrent  A combination of Toggle and Current, provided for
    1010                         convenience.
    1011   \value ClearAndSelect A combination of Clear and Select, provided for
    1012                         convenience.
    1013 */
    1014 
    1015 /*!
    1016   Selects the item \a selection using the specified \a command, and emits
    1017   selectionChanged().
    1018 
    1019   \sa QItemSelectionModel::SelectionFlag
     1038    \enum QItemSelectionModel::SelectionFlag
     1039
     1040    This enum describes the way the selection model will be updated.
     1041
     1042    \value NoUpdate       No selection will be made.
     1043    \value Clear          The complete selection will be cleared.
     1044    \value Select         All specified indexes will be selected.
     1045    \value Deselect       All specified indexes will be deselected.
     1046    \value Toggle         All specified indexes will be selected or
     1047                          deselected depending on their current state.
     1048    \value Current        The current selection will be updated.
     1049    \value Rows           All indexes will be expanded to span rows.
     1050    \value Columns        All indexes will be expanded to span columns.
     1051    \value SelectCurrent  A combination of Select and Current, provided for
     1052                          convenience.
     1053    \value ToggleCurrent  A combination of Toggle and Current, provided for
     1054                          convenience.
     1055    \value ClearAndSelect A combination of Clear and Select, provided for
     1056                          convenience.
     1057*/
     1058
     1059/*!
     1060    Selects the item \a selection using the specified \a command, and emits
     1061    selectionChanged().
     1062
     1063    \sa QItemSelectionModel::SelectionFlag
    10201064*/
    10211065void QItemSelectionModel::select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command)
     
    10571101
    10581102/*!
    1059   Clears the selection model. Emits selectionChanged() and currentChanged().
     1103    Clears the selection model. Emits selectionChanged() and currentChanged().
    10601104*/
    10611105void QItemSelectionModel::clear()
     
    10731117
    10741118/*!
    1075   Clears the selection model. Does not emit any signals.
     1119    Clears the selection model. Does not emit any signals.
    10761120*/
    10771121void QItemSelectionModel::reset()
     
    10831127
    10841128/*!
    1085   \since 4.2
    1086   Clears the selection in the selection model. Emits selectionChanged().
     1129    \since 4.2
     1130    Clears the selection in the selection model. Emits selectionChanged().
    10871131*/
    10881132void QItemSelectionModel::clearSelection()
     
    11001144
    11011145/*!
    1102   Sets the model item \a index to be the current item, and emits
    1103   currentChanged(). The current item is used for keyboard navigation and
    1104   focus indication; it is independent of any selected items, although a
    1105   selected item can also be the current item.
    1106 
    1107   Depending on the specified \a command, the \a index can also become part
    1108   of the current selection.
    1109   \sa select()
     1146    Sets the model item \a index to be the current item, and emits
     1147    currentChanged(). The current item is used for keyboard navigation and
     1148    focus indication; it is independent of any selected items, although a
     1149    selected item can also be the current item.
     1150
     1151    Depending on the specified \a command, the \a index can also become part
     1152    of the current selection.
     1153    \sa select()
    11101154*/
    11111155void QItemSelectionModel::setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command)
     
    11311175
    11321176/*!
    1133   Returns the model item index for the current item, or an invalid index
    1134   if there is no current item.
     1177    Returns the model item index for the current item, or an invalid index
     1178    if there is no current item.
    11351179*/
    11361180QModelIndex QItemSelectionModel::currentIndex() const
     
    11401184
    11411185/*!
    1142   Returns true if the given model item \a index is selected.
     1186    Returns true if the given model item \a index is selected.
    11431187*/
    11441188bool QItemSelectionModel::isSelected(const QModelIndex &index) const
     
    11771221
    11781222/*!
    1179   Returns true if all items are selected in the \a row with the given
    1180   \a parent.
    1181 
    1182   Note that this function is usually faster than calling isSelected()
    1183   on all items in the same row and that unselectable items are
    1184   ignored.
     1223    Returns true if all items are selected in the \a row with the given
     1224    \a parent.
     1225
     1226    Note that this function is usually faster than calling isSelected()
     1227    on all items in the same row and that unselectable items are
     1228    ignored.
    11851229*/
    11861230bool QItemSelectionModel::isRowSelected(int row, const QModelIndex &parent) const
     
    12371281
    12381282/*!
    1239   Returns true if all items are selected in the \a column with the given
    1240   \a parent.
    1241 
    1242   Note that this function is usually faster than calling isSelected()
    1243   on all items in the same column and that unselectable items are
    1244   ignored.
     1283    Returns true if all items are selected in the \a column with the given
     1284    \a parent.
     1285
     1286    Note that this function is usually faster than calling isSelected()
     1287    on all items in the same column and that unselectable items are
     1288    ignored.
    12451289*/
    12461290bool QItemSelectionModel::isColumnSelected(int column, const QModelIndex &parent) const
     
    12971341
    12981342/*!
    1299   Returns true if there are any items selected in the \a row with the given
    1300   \a parent.
     1343    Returns true if there are any items selected in the \a row with the given
     1344    \a parent.
    13011345*/
    13021346bool QItemSelectionModel::rowIntersectsSelection(int row, const QModelIndex &parent) const
     
    13141358        int right = sel.at(i).right();
    13151359        if (top <= row && bottom >= row) {
    1316             Qt::ItemFlags leftFlags = d->model->index(row, left, parent).flags();
    1317             Qt::ItemFlags rightFlags = d->model->index(row, right, parent).flags();
    1318             if ((leftFlags & Qt::ItemIsSelectable) && (leftFlags & Qt::ItemIsEnabled)
    1319                 && (rightFlags & Qt::ItemIsSelectable) && (rightFlags & Qt::ItemIsEnabled))
    1320                 return true;
     1360            for (int j = left; j <= right; j++) {
     1361                const Qt::ItemFlags flags = d->model->index(row, j, parent).flags();
     1362                if ((flags & Qt::ItemIsSelectable) && (flags & Qt::ItemIsEnabled))
     1363                    return true;
     1364            }
    13211365        }
    13221366    }
     
    13261370
    13271371/*!
    1328   Returns true if there are any items selected in the \a column with the given
    1329   \a parent.
     1372    Returns true if there are any items selected in the \a column with the given
     1373    \a parent.
    13301374*/
    13311375bool QItemSelectionModel::columnIntersectsSelection(int column, const QModelIndex &parent) const
     
    13431387        int bottom =  sel.at(i).bottom();
    13441388        if (left <= column && right >= column) {
    1345             Qt::ItemFlags topFlags = d->model->index(top, column, parent).flags();
    1346             Qt::ItemFlags bottomFlags = d->model->index(bottom, column, parent).flags();
    1347             if ((topFlags & Qt::ItemIsSelectable) && (topFlags & Qt::ItemIsEnabled)
    1348                 && (bottomFlags & Qt::ItemIsSelectable) && (bottomFlags & Qt::ItemIsEnabled))
    1349                 return true;
     1389            for (int j = top; j <= bottom; j++) {
     1390                const Qt::ItemFlags flags = d->model->index(j, column, parent).flags();
     1391                if ((flags & Qt::ItemIsSelectable) && (flags & Qt::ItemIsEnabled))
     1392                    return true;
     1393            }
    13501394        }
    13511395    }
     
    13671411        sel.merge(d->currentSelection, d->currentCommand);
    13681412        return !sel.isEmpty();
    1369     }
    1370     else {
     1413    } else {
    13711414        return !(d->ranges.isEmpty() && d->currentSelection.isEmpty());
    13721415    }
     
    13741417
    13751418/*!
    1376   Returns a list of all selected model item indexes. The list contains no
    1377   duplicates, and is not sorted.
     1419    Returns a list of all selected model item indexes. The list contains no
     1420    duplicates, and is not sorted.
    13781421*/
    13791422QModelIndexList QItemSelectionModel::selectedIndexes() const
     
    13861429
    13871430/*!
    1388   \since 4.2
    1389   Returns the indexes in the given \a column for the rows where all columns are selected.
    1390 
    1391   \sa selectedIndexes(), selectedColumns()
     1431    \since 4.2
     1432    Returns the indexes in the given \a column for the rows where all columns are selected.
     1433
     1434    \sa selectedIndexes(), selectedColumns()
    13921435*/
    13931436
     
    14501493
    14511494/*!
    1452   Returns the selection ranges stored in the selection model.
     1495    Returns the selection ranges stored in the selection model.
    14531496*/
    14541497const QItemSelection QItemSelectionModel::selection() const
     
    14701513
    14711514/*!
    1472   Returns the item model operated on by the selection model.
     1515    Returns the item model operated on by the selection model.
    14731516*/
    14741517const QAbstractItemModel *QItemSelectionModel::model() const
     
    14781521
    14791522/*!
    1480   Compares the two selections \a newSelection and \a oldSelection
    1481   and emits selectionChanged() with the deselected and selected items.
     1523    Compares the two selections \a newSelection and \a oldSelection
     1524    and emits selectionChanged() with the deselected and selected items.
    14821525*/
    14831526void QItemSelectionModel::emitSelectionChanged(const QItemSelection &newSelection,
     
    15461589    }
    15471590
    1548     emit selectionChanged(selected, deselected);
     1591    if (!selected.isEmpty() || !deselected.isEmpty())
     1592        emit selectionChanged(selected, deselected);
    15491593}
    15501594
     
    15541598#ifndef Q_BROKEN_DEBUG_STREAM
    15551599    dbg.nospace() << "QItemSelectionRange(" << range.topLeft()
    1556                   << "," << range.bottomRight() << ")";
     1600                  << ',' << range.bottomRight() << ')';
    15571601    return dbg.space();
    15581602#else
  • trunk/src/gui/itemviews/qitemselectionmodel.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qitemselectionmodel_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6666      : model(0),
    6767        currentCommand(QItemSelectionModel::NoUpdate),
    68         tableSelected(false) {}
     68        tableSelected(false), tableColCount(0), tableRowCount(0) {}
    6969
    7070    QItemSelection expandSelection(const QItemSelection &selection,
  • trunk/src/gui/itemviews/qlistview.cpp

    r2 r561  
    1 /***************************************************************************
     1/****************************************************************************
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6767    \ingroup model-view
    6868    \ingroup advanced
    69     \mainclass
     69
    7070
    7171    A QListView presents items stored in a model, either as a simple
     
    358358/*!
    359359    \property QListView::spacing
    360     \brief the space between items in the layout
     360    \brief the space around the items in the layout
    361361
    362362    This property is the size of the empty space that is padded around
     
    459459{
    460460    Q_D(QListView);
     461    if (d->commonListView && d->viewMode == mode)
     462        return;
    461463    d->viewMode = mode;
    462464
     465    delete d->commonListView;
    463466    if (mode == ListMode) {
    464         delete d->dynamicListView;
    465         d->dynamicListView = 0;
    466         if (!d->staticListView)
    467             d->staticListView = new QStaticListViewBase(this, d);
     467        d->commonListView = new QListModeViewBase(this, d);
    468468        if (!(d->modeProperties & QListViewPrivate::Wrap))
    469469            d->setWrapping(false);
     
    481481            d->showElasticBand = false;
    482482    } else {
    483         delete d->staticListView;
    484         d->staticListView = 0;
    485         if (!d->dynamicListView)
    486             d->dynamicListView = new QDynamicListViewBase(this, d);
     483        d->commonListView = new QIconModeViewBase(this, d);
    487484        if (!(d->modeProperties & QListViewPrivate::Wrap))
    488485            d->setWrapping(true);
     
    548545    Q_D(QListView);
    549546    const bool hidden = d->isHidden(row);
    550     if (d->viewMode == ListMode) {
    551         if (hide && !hidden)
    552             d->hiddenRows.append(d->model->index(row, 0));
    553         else if (!hide && hidden)
    554             d->hiddenRows.remove(d->hiddenRows.indexOf(d->model->index(row, 0)));
    555         d->doDelayedItemsLayout();
    556     } else {
    557         if (hide && !hidden) {
    558             d->dynamicListView->removeItem(row);
    559             d->hiddenRows.append(d->model->index(row, 0));
    560         } else if (!hide && hidden) {
    561             d->hiddenRows.remove(d->hiddenRows.indexOf(d->model->index(row, 0)));
    562             d->dynamicListView->insertItem(row);
    563         }
    564         if (d->resizeMode == Adjust)
    565             d->doDelayedItemsLayout();
    566         d->viewport->update();
    567     }
     547    if (hide && !hidden)
     548        d->commonListView->appendHiddenRow(row);
     549    else if (!hide && hidden)
     550        d->commonListView->removeHiddenRow(row);
     551    d->doDelayedItemsLayout();
     552    d->viewport->update();
    568553}
    569554
     
    574559{
    575560    Q_D(const QListView);
    576     return d->mapToViewport(rectForIndex(index), d->viewMode == QListView::ListMode);
     561    return d->mapToViewport(rectForIndex(index));
    577562}
    578563
     
    589574    const QRect rect = visualRect(index);
    590575    if (hint == EnsureVisible && d->viewport->rect().contains(rect)) {
    591         d->setDirtyRegion(rect);
     576        d->viewport->update(rect);
    592577        return;
    593578    }
     
    611596                         ? rect.right() > area.right()
    612597                         : (rect.right() > area.right()) && (rect.left() > area.left());
    613     int horizontalValue = q->horizontalScrollBar()->value();
    614 
    615     // ScrollPerItem
    616     if (q->horizontalScrollMode() == QAbstractItemView::ScrollPerItem && viewMode == QListView::ListMode) {
    617         const QListViewItem item = indexToListViewItem(index);
    618         const QRect rect = q->visualRect(index);
    619         horizontalValue = staticListView->horizontalPerItemValue(itemIndex(item),
    620                                                                 horizontalValue, area.width(),
    621                                                                 leftOf, rightOf, isWrapping(), hint, rect.width());
    622     } else { // ScrollPerPixel
    623         if (q->isRightToLeft()) {
    624             if (hint == QListView::PositionAtCenter) {
    625                 horizontalValue += ((area.width() - rect.width()) / 2) - rect.left();
    626             } else {
    627                 if (leftOf)
    628                     horizontalValue -= rect.left();
    629                 else if (rightOf)
    630                     horizontalValue += qMin(rect.left(), area.width() - rect.right());
    631             }
    632        } else {
    633             if (hint == QListView::PositionAtCenter) {
    634                 horizontalValue += rect.left() - ((area.width()- rect.width()) / 2);
    635             } else {
    636                 if (leftOf)
    637                     horizontalValue += rect.left();
    638                 else if (rightOf)
    639                     horizontalValue += qMin(rect.left(), rect.right() - area.width());
    640             }
    641         }
    642     }
    643     return horizontalValue;
     598    return commonListView->horizontalScrollToValue(q->visualIndex(index), hint, leftOf, rightOf, area, rect);
    644599}
    645600
     
    648603{
    649604    Q_Q(const QListView);
    650 
    651605    const QRect area = viewport->rect();
    652606    const bool above = (hint == QListView::EnsureVisible && rect.top() < area.top());
    653607    const bool below = (hint == QListView::EnsureVisible && rect.bottom() > area.bottom());
    654 
    655     int verticalValue = q->verticalScrollBar()->value();
    656 
    657     // ScrollPerItem
    658     if (q->verticalScrollMode() == QAbstractItemView::ScrollPerItem && viewMode == QListView::ListMode) {
    659         const QListViewItem item = indexToListViewItem(index);
    660         const QRect rect = q->visualRect(index);
    661         verticalValue = staticListView->verticalPerItemValue(itemIndex(item),
    662                                                              verticalValue, area.height(),
    663                                                              above, below, isWrapping(), hint, rect.height());
    664 
    665     } else { // ScrollPerPixel
    666         QRect adjusted = rect.adjusted(-spacing(), -spacing(), spacing(), spacing());
    667         if (hint == QListView::PositionAtTop || above)
    668             verticalValue += adjusted.top();
    669         else if (hint == QListView::PositionAtBottom || below)
    670             verticalValue += qMin(adjusted.top(), adjusted.bottom() - area.height() + 1);
    671         else if (hint == QListView::PositionAtCenter)
    672             verticalValue += adjusted.top() - ((area.height() - adjusted.height()) / 2);
    673     }
    674 
    675     return verticalValue;
     608    return commonListView->verticalScrollToValue(q->visualIndex(index), hint, above, below, area, rect);
    676609}
    677610
     
    710643}
    711644
     645/*!
     646  \reimp
     647
     648  We have a QListView way of knowing what elements are on the viewport
     649  through the intersectingSet function
     650*/
     651QItemViewPaintPairs QListViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const
     652{
     653    Q_ASSERT(r);
     654    Q_Q(const QListView);
     655    QRect &rect = *r;
     656    const QRect viewportRect = viewport->rect();
     657    QItemViewPaintPairs ret;
     658    const QSet<QModelIndex> visibleIndexes = intersectingSet(viewportRect).toList().toSet();
     659    for (int i = 0; i < indexes.count(); ++i) {
     660        const QModelIndex &index = indexes.at(i);
     661        if (visibleIndexes.contains(index)) {
     662            const QRect current = q->visualRect(index);
     663            ret += qMakePair(current, index);
     664            rect |= current;
     665        }
     666    }
     667    rect &= viewportRect;
     668    return ret;
     669}
    712670
    713671/*!
     
    740698    Scroll the view contents by \a dx and \a dy.
    741699*/
     700
    742701void QListView::scrollContentsBy(int dx, int dy)
    743702{
    744703    Q_D(QListView);
    745 
    746704    d->delayedAutoScroll.stop(); // auto scroll was canceled by the user scrolling
    747 
    748     if (d->viewMode == ListMode)
    749         d->staticListView->scrollContentsBy(dx, dy);
    750     else if (state() == DragSelectingState)
    751         d->scrollElasticBandBy(isRightToLeft() ? -dx : dx, dy);
    752 
    753     d->scrollContentsBy(isRightToLeft() ? -dx : dx, dy);
    754 
    755     // update the dragged items
    756     if (d->viewMode == IconMode) // ### move to dynamic class
    757     if (!d->dynamicListView->draggedItems.isEmpty())
    758         d->setDirtyRegion(d->dynamicListView->draggedItemsRect().translated(dx, dy));
     705    d->commonListView->scrollContentsBy(dx, dy, d->state == QListView::DragSelectingState);
    759706}
    760707
     
    785732void QListView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
    786733{
    787     Q_D(QListView);
    788     if (d->viewMode == IconMode)
    789         d->dynamicListView->dataChanged(topLeft, bottomRight);
     734    d_func()->commonListView->dataChanged(topLeft, bottomRight);
    790735    QAbstractItemView::dataChanged(topLeft, bottomRight);
    791736}
     
    828773void QListView::mouseMoveEvent(QMouseEvent *e)
    829774{
     775    if (!isVisible())
     776        return;
    830777    Q_D(QListView);
    831778    QAbstractItemView::mouseMoveEvent(e);
     
    836783        QRect rect(d->pressedPosition, e->pos() + QPoint(horizontalOffset(), verticalOffset()));
    837784        rect = rect.normalized();
    838         d->setDirtyRegion(d->mapToViewport(rect.united(d->elasticBand), d->viewMode == QListView::ListMode));
     785        d->viewport->update(d->mapToViewport(rect.united(d->elasticBand)));
    839786        d->elasticBand = rect;
    840787    }
     
    850797    // #### move this implementation into a dynamic class
    851798    if (d->showElasticBand && d->elasticBand.isValid()) {
    852         d->setDirtyRegion(d->mapToViewport(d->elasticBand, d->viewMode == QListView::ListMode));
     799        d->viewport->update(d->mapToViewport(d->elasticBand));
    853800        d->elasticBand = QRect();
    854801    }
     
    886833
    887834    bool listWrap = (d->viewMode == ListMode) && d->wrapItemText;
    888     bool flowDimensionChanged = (d->flow == LeftToRight && delta.width() != 0) 
    889                                 || (d->flow == TopToBottom && delta.height() != 0);
     835    bool flowDimensionChanged = (d->flow == LeftToRight && delta.width() != 0)
     836                                || (d->flow == TopToBottom && delta.height() != 0);
    890837
    891838    // We post a delayed relayout in the following cases :
    892839    // - we're wrapping
    893840    // - the state is NoState, we're adjusting and the size has changed in the flowing direction
    894     if (listWrap 
     841    if (listWrap
    895842        || (state() == NoState && d->resizeMode == Adjust && flowDimensionChanged)) {
    896         d->doDelayedItemsLayout(100); // wait 1/10 sec before starting the layout
    897     } else {   
     843        d->doDelayedItemsLayout(100); // wait 1/10 sec before starting the layout
     844    } else {
    898845        QAbstractItemView::resizeEvent(e);
    899846    }
     
    907854void QListView::dragMoveEvent(QDragMoveEvent *e)
    908855{
    909     // ### move implementation to dynamic
    910     Q_D(QListView);
    911     if (e->source() == this && d->viewMode == IconMode) {
    912         // the ignore by default
    913         e->ignore();
    914         if (d->canDecode(e)) {
    915             // get old dragged items rect
    916             QRect itemsRect = d->dynamicListView->itemsRect(d->dynamicListView->draggedItems);
    917             d->setDirtyRegion(itemsRect.translated(d->dynamicListView->draggedItemsDelta()));
    918             // update position
    919             d->dynamicListView->draggedItemsPos = e->pos();
    920             // get new items rect
    921             d->setDirtyRegion(itemsRect.translated(d->dynamicListView->draggedItemsDelta()));
    922             // set the item under the cursor to current
    923             QModelIndex index;
    924             if (d->movement == Snap) {
    925                 QRect rect(d->dynamicListView->snapToGrid(e->pos() + d->offset()), d->gridSize());
    926                 d->intersectingSet(rect);
    927                 index = d->intersectVector.count() > 0
    928                                     ? d->intersectVector.last() : QModelIndex();
    929             } else {
    930                 index = indexAt(e->pos());
    931             }
    932             // check if we allow drops here
    933             if (e->source() == this && d->dynamicListView->draggedItems.contains(index))
    934                 e->accept(); // allow changing item position
    935             else if (d->model->flags(index) & Qt::ItemIsDropEnabled)
    936                 e->accept(); // allow dropping on dropenabled items
    937             else if (!index.isValid())
    938                 e->accept(); // allow dropping in empty areas
    939         }
    940         // do autoscrolling
    941         if (d->shouldAutoScroll(e->pos()))
    942             startAutoScroll();
    943     } else { // not internal
    944         QAbstractItemView::dragMoveEvent(e);
    945     }
    946 }
     856    Q_D(QListView);
     857    if (!d->commonListView->filterDragMoveEvent(e)) {
     858        if (viewMode() == QListView::ListMode && flow() == QListView::LeftToRight)
     859            static_cast<QListModeViewBase *>(d->commonListView)->dragMoveEvent(e);
     860        else
     861            QAbstractItemView::dragMoveEvent(e);
     862    }
     863}
     864
    947865
    948866/*!
     
    951869void QListView::dragLeaveEvent(QDragLeaveEvent *e)
    952870{
    953     // ### move implementation to dynamic
    954     Q_D(QListView);
    955     if (d->viewMode == IconMode) {
    956         d->viewport->update(d->dynamicListView->draggedItemsRect()); // erase the area
    957         d->dynamicListView->draggedItemsPos = QPoint(-1, -1); // don't draw the dragged items
    958     }
    959     QAbstractItemView::dragLeaveEvent(e);
     871    if (!d_func()->commonListView->filterDragLeaveEvent(e))
     872        QAbstractItemView::dragLeaveEvent(e);
    960873}
    961874
     
    963876  \reimp
    964877*/
    965 void QListView::dropEvent(QDropEvent *event)
    966 {
    967     Q_D(QListView);
    968     if (event->source() == this && d->viewMode == IconMode)
    969         internalDrop(event); // ### move to dynamic
    970     else
    971         QAbstractItemView::dropEvent(event);
     878void QListView::dropEvent(QDropEvent *e)
     879{
     880    if (!d_func()->commonListView->filterDropEvent(e))
     881        QAbstractItemView::dropEvent(e);
    972882}
    973883
     
    977887void QListView::startDrag(Qt::DropActions supportedActions)
    978888{
    979     Q_D(QListView);
    980     if (d->viewMode == IconMode) // ### move to dynamic
    981         internalDrag(supportedActions);
    982     else
     889    if (!d_func()->commonListView->filterStartDrag(supportedActions))
    983890        QAbstractItemView::startDrag(supportedActions);
    984891}
     
    992899void QListView::internalDrop(QDropEvent *event)
    993900{
    994     Q_D(QListView);
    995     if (d->viewMode == QListView::ListMode)
    996         return;
    997 
    998     // ### move to dynamic class
    999     QPoint offset(horizontalOffset(), verticalOffset());
    1000     QPoint end = event->pos() + offset;
    1001     QPoint start = d->pressedPosition;
    1002     QPoint delta = (d->movement == Snap ?
    1003                     d->dynamicListView->snapToGrid(end)
    1004                     - d->dynamicListView->snapToGrid(start) : end - start);
    1005     QSize contents = d->contentsSize();
    1006     QList<QModelIndex> indexes = d->selectionModel->selectedIndexes();
    1007     for (int i = 0; i < indexes.count(); ++i) {
    1008         QModelIndex index = indexes.at(i);
    1009         QRect rect = rectForIndex(index);
    1010         d->setDirtyRegion(d->mapToViewport(rect, d->viewMode == QListView::ListMode));
    1011         QPoint dest = rect.topLeft() + delta;
    1012         if (isRightToLeft())
    1013             dest.setX(d->flipX(dest.x()) - rect.width());
    1014         d->dynamicListView->moveItem(index.row(), dest);
    1015         d->setDirtyRegion(visualRect(index));
    1016     }
    1017     stopAutoScroll();
    1018     d->dynamicListView->draggedItems.clear();
    1019     emit indexesMoved(indexes);
    1020     event->accept(); // we have handled the event
    1021     // if the size has not grown, we need to check if it has shrinked
    1022     if (d->dynamicListView
    1023         && (d->contentsSize().width() <= contents.width()
    1024             || d->contentsSize().height() <= contents.height())) {
    1025         d->dynamicListView->updateContentsSize();
    1026     }
    1027     if (d->contentsSize() != contents)
    1028         updateGeometries();
     901    // ### Qt5: remove that function
     902    Q_UNUSED(event);
    1029903}
    1030904
     
    1037911void QListView::internalDrag(Qt::DropActions supportedActions)
    1038912{
    1039     Q_D(QListView);
    1040     if (d->viewMode == QListView::ListMode)
    1041         return;
    1042 
    1043     // #### move to dynamic class
    1044 
    1045     // This function does the same thing as in QAbstractItemView::startDrag(),
    1046     // plus adding viewitems to the draggedItems list.
    1047     // We need these items to draw the drag items
    1048     QModelIndexList indexes = d->selectionModel->selectedIndexes();
    1049     if (indexes.count() > 0 ) {
    1050         if (d->viewport->acceptDrops()) {
    1051             QModelIndexList::ConstIterator it = indexes.constBegin();
    1052             for (; it != indexes.constEnd(); ++it)
    1053                 if (d->model->flags(*it) & Qt::ItemIsDragEnabled
    1054                     && (*it).column() == d->column)
    1055                     d->dynamicListView->draggedItems.push_back(*it);
    1056         }
    1057         QDrag *drag = new QDrag(this);
    1058         drag->setMimeData(d->model->mimeData(indexes));
    1059         Qt::DropAction action = drag->exec(supportedActions, Qt::CopyAction);
    1060         d->dynamicListView->draggedItems.clear();
    1061         if (action == Qt::MoveAction)
    1062             d->clearOrRemove();
    1063     }
     913    // ### Qt5: remove that function
     914    Q_UNUSED(supportedActions);
    1064915}
    1065916
     
    1089940}
    1090941
     942
    1091943/*!
    1092944  \reimp
     
    1099951    QStyleOptionViewItemV4 option = d->viewOptionsV4();
    1100952    QPainter painter(d->viewport);
    1101     QRect area = e->rect();
    1102 
    1103     QVector<QModelIndex> toBeRendered;
    1104 //     QVector<QRect> rects = e->region().rects();
    1105 //     for (int i = 0; i < rects.size(); ++i) {
    1106 //         d->intersectingSet(rects.at(i).translated(horizontalOffset(), verticalOffset()));
    1107 //         toBeRendered += d->intersectVector;
    1108 //     }
    1109     d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false);
    1110     toBeRendered = d->intersectVector;
     953
     954    const QVector<QModelIndex> toBeRendered = d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false);
    1111955
    1112956    const QModelIndex current = currentIndex();
     
    1123967    int previousRow = -2; // trigger the alternateBase adjustment on first pass
    1124968
     969    int maxSize = (flow() == TopToBottom)
     970        ? qMax(viewport()->size().width(), d->contentsSize().width()) - 2 * d->spacing()
     971        : qMax(viewport()->size().height(), d->contentsSize().height()) - 2 * d->spacing();
     972
    1125973    QVector<QModelIndex>::const_iterator end = toBeRendered.constEnd();
    1126974    for (QVector<QModelIndex>::const_iterator it = toBeRendered.constBegin(); it != end; ++it) {
    1127975        Q_ASSERT((*it).isValid());
    1128976        option.rect = visualRect(*it);
     977
     978        if (flow() == TopToBottom)
     979            option.rect.setWidth(qMin(maxSize, option.rect.width()));
     980        else
     981            option.rect.setHeight(qMin(maxSize, option.rect.height()));
     982
    1129983        option.state = state;
    1130984        if (selections && selections->isSelected(*it))
     
    11931047
    11941048#ifndef QT_NO_DRAGANDDROP
    1195     // #### move this implementation into a dynamic class
    1196     if (d->viewMode == IconMode)
    1197     if (!d->dynamicListView->draggedItems.isEmpty()
    1198         && d->viewport->rect().contains(d->dynamicListView->draggedItemsPos)) {
    1199         QPoint delta = d->dynamicListView->draggedItemsDelta();
    1200         painter.translate(delta.x(), delta.y());
    1201         d->dynamicListView->drawItems(&painter, d->dynamicListView->draggedItems);
    1202     }
    1203     // FIXME: Until the we can provide a proper drop indicator
    1204     // in IconMode, it makes no sense to show it
    1205     if (d->viewMode == ListMode)
    1206         d->paintDropIndicator(&painter);
     1049    d->commonListView->paintDragDrop(&painter);
    12071050#endif
    12081051
     
    12301073    Q_D(const QListView);
    12311074    QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1);
    1232     d->intersectingSet(rect);
    1233     QModelIndex index = d->intersectVector.count() > 0
    1234                         ? d->intersectVector.last() : QModelIndex();
     1075    const QVector<QModelIndex> intersectVector = d->intersectingSet(rect);
     1076    QModelIndex index = intersectVector.count() > 0
     1077                        ? intersectVector.last() : QModelIndex();
    12351078    if (index.isValid() && visualRect(index).contains(p))
    12361079        return index;
     
    12431086int QListView::horizontalOffset() const
    12441087{
    1245     Q_D(const QListView);
    1246     // ### split into static and dynamic
    1247     if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem && d->viewMode == ListMode) {
    1248         if (d->isWrapping()) {
    1249             if (d->flow == TopToBottom && !d->staticListView->segmentPositions.isEmpty()) {
    1250                 const int max = d->staticListView->segmentPositions.count() - 1;
    1251                 int currentValue = qBound(0, horizontalScrollBar()->value(), max);
    1252                 int position = d->staticListView->segmentPositions.at(currentValue);
    1253                 int maximumValue = qBound(0, horizontalScrollBar()->maximum(), max);
    1254                 int maximum = d->staticListView->segmentPositions.at(maximumValue);
    1255                 return (isRightToLeft() ? maximum - position : position);
    1256             }
    1257             //return 0;
    1258         } else {
    1259             if (d->flow == LeftToRight && !d->staticListView->flowPositions.isEmpty()) {
    1260                 int position = d->staticListView->flowPositions.at(horizontalScrollBar()->value());
    1261                 int maximum = d->staticListView->flowPositions.at(horizontalScrollBar()->maximum());
    1262                 return (isRightToLeft() ? maximum - position : position);
    1263             }
    1264             //return 0;
    1265         }
    1266     }
    1267     return (isRightToLeft()
    1268             ? horizontalScrollBar()->maximum() - horizontalScrollBar()->value()
    1269             : horizontalScrollBar()->value());
     1088    return d_func()->commonListView->horizontalOffset();
    12701089}
    12711090
     
    12751094int QListView::verticalOffset() const
    12761095{
    1277     // ## split into static and dynamic
    1278     Q_D(const QListView);
    1279     if (verticalScrollMode() == QAbstractItemView::ScrollPerItem && d->viewMode == ListMode) {
    1280         if (d->isWrapping()) {
    1281             if (d->flow == LeftToRight && !d->staticListView->segmentPositions.isEmpty()) {
    1282                 int value = verticalScrollBar()->value();
    1283                 if (value >= d->staticListView->segmentPositions.count()) {
    1284                     //qWarning("QListView: Vertical scroll bar is out of bounds");
    1285                     return 0;
    1286                 }
    1287                 return d->staticListView->segmentPositions.at(value);
    1288             }
    1289         } else {
    1290             if (d->flow == TopToBottom && !d->staticListView->flowPositions.isEmpty()) {
    1291                 int value = verticalScrollBar()->value();
    1292                 if (value > d->staticListView->flowPositions.count()) {
    1293                     //qWarning("QListView: Vertical scroll bar is out of bounds");
    1294                     return 0;
    1295                 }
    1296                 return d->staticListView->flowPositions.at(value) - d->spacing();
    1297             }
    1298         }
    1299     }
    1300     return verticalScrollBar()->value();
     1096    return d_func()->commonListView->verticalOffset();
    13011097}
    13021098
     
    13191115        if (row >= rowCount)
    13201116            return QModelIndex();
    1321         return d->model->index(row, 0, d->root);
     1117        return d->model->index(row, d->column, d->root);
    13221118    }
    13231119
     
    13251121    QRect rect = initialRect;
    13261122    if (rect.isEmpty()) {
    1327         return d->model->index(0, 0, d->root);
     1123        return d->model->index(0, d->column, d->root);
    13281124    }
    13291125    if (d->gridSize().isValid()) rect.setSize(d->gridSize());
    13301126
    13311127    QSize contents = d->contentsSize();
    1332     d->intersectVector.clear();
     1128    QVector<QModelIndex> intersectVector;
    13331129
    13341130    switch (cursorAction) {
    13351131    case MoveLeft:
    1336         while (d->intersectVector.isEmpty()) {
     1132        while (intersectVector.isEmpty()) {
    13371133            rect.translate(-rect.width(), 0);
    13381134            if (rect.right() <= 0)
     
    13401136            if (rect.left() < 0)
    13411137                rect.setLeft(0);
    1342             d->intersectingSet(rect);
    1343             d->removeCurrentAndDisabled(&d->intersectVector, current);
    1344         }
    1345         return d->closestIndex(initialRect, d->intersectVector);
     1138            intersectVector = d->intersectingSet(rect);
     1139            d->removeCurrentAndDisabled(&intersectVector, current);
     1140        }
     1141        return d->closestIndex(initialRect, intersectVector);
    13461142    case MoveRight:
    1347         while (d->intersectVector.isEmpty()) {
     1143        while (intersectVector.isEmpty()) {
    13481144            rect.translate(rect.width(), 0);
    13491145            if (rect.left() >= contents.width())
     
    13511147            if (rect.right() > contents.width())
    13521148                rect.setRight(contents.width());
    1353             d->intersectingSet(rect);
    1354             d->removeCurrentAndDisabled(&d->intersectVector, current);
    1355         }
    1356         return d->closestIndex(initialRect, d->intersectVector);
     1149            intersectVector = d->intersectingSet(rect);
     1150            d->removeCurrentAndDisabled(&intersectVector, current);
     1151        }
     1152        return d->closestIndex(initialRect, intersectVector);
    13571153    case MovePageUp:
    1358         rect.moveTop(rect.top() - d->viewport->height());
     1154        // move current by (visibileRowCount - 1) items.
     1155        // rect.translate(0, -rect.height()); will happen in the switch fallthrough for MoveUp.
     1156        rect.moveTop(rect.top() - d->viewport->height() + 2 * rect.height());
    13591157        if (rect.top() < rect.height())
    13601158            rect.moveTop(rect.height());
    13611159    case MovePrevious:
    13621160    case MoveUp:
    1363         while (d->intersectVector.isEmpty()) {
     1161        while (intersectVector.isEmpty()) {
    13641162            rect.translate(0, -rect.height());
    13651163            if (rect.bottom() <= 0) {
     
    13771175            if (rect.top() < 0)
    13781176                rect.setTop(0);
    1379             d->intersectingSet(rect);
    1380             d->removeCurrentAndDisabled(&d->intersectVector, current);
    1381         }
    1382         return d->closestIndex(initialRect, d->intersectVector);
     1177            intersectVector = d->intersectingSet(rect);
     1178            d->removeCurrentAndDisabled(&intersectVector, current);
     1179        }
     1180        return d->closestIndex(initialRect, intersectVector);
    13831181    case MovePageDown:
    1384         rect.moveTop(rect.top() + d->viewport->height());
     1182        // move current by (visibileRowCount - 1) items.
     1183        // rect.translate(0, rect.height()); will happen in the switch fallthrough for MoveDown.
     1184        rect.moveTop(rect.top() + d->viewport->height() - 2 * rect.height());
    13851185        if (rect.bottom() > contents.height() - rect.height())
    13861186            rect.moveBottom(contents.height() - rect.height());
    13871187    case MoveNext:
    13881188    case MoveDown:
    1389         while (d->intersectVector.isEmpty()) {
     1189        while (intersectVector.isEmpty()) {
    13901190            rect.translate(0, rect.height());
    13911191            if (rect.top() >= contents.height()) {
     
    14041204            if (rect.bottom() > contents.height())
    14051205                rect.setBottom(contents.height());
    1406             d->intersectingSet(rect);
    1407             d->removeCurrentAndDisabled(&d->intersectVector, current);
    1408         }
    1409         return d->closestIndex(initialRect, d->intersectVector);
     1206            intersectVector = d->intersectingSet(rect);
     1207            d->removeCurrentAndDisabled(&intersectVector, current);
     1208        }
     1209        return d->closestIndex(initialRect, intersectVector);
    14101210    case MoveHome:
    14111211        return d->model->index(0, d->column, d->root);
     
    14241224QRect QListView::rectForIndex(const QModelIndex &index) const
    14251225{
    1426     Q_D(const QListView);
    1427     if (!d->isIndexValid(index)
    1428         || index.parent() != d->root
    1429         || index.column() != d->column
    1430         || isIndexHidden(index))
    1431         return QRect();
    1432     d->executePostedLayout();
    1433     QListViewItem item = d->indexToListViewItem(index);
    1434     return d->viewItemRect(item);
     1226    return d_func()->rectForIndex(index);
    14351227}
    14361228
     
    14401232    Sets the contents position of the item at \a index in the model to the given
    14411233    \a position.
    1442     If the list view's movement mode is Static, this function will have no
    1443     effect.
     1234    If the list view's movement mode is Static or its view mode is ListView,
     1235    this function will have no effect.
    14441236*/
    14451237void QListView::setPositionForIndex(const QPoint &position, const QModelIndex &index)
     
    14531245
    14541246    d->executePostedLayout();
    1455     if (index.row() >= d->dynamicListView->items.count())
    1456         return;
    1457     const QSize oldContents = d->contentsSize();
    1458     d->setDirtyRegion(visualRect(index)); // update old position
    1459     d->dynamicListView->moveItem(index.row(), position);
    1460     d->setDirtyRegion(visualRect(index)); // update new position
    1461 
    1462     if (d->contentsSize() != oldContents)
    1463         updateGeometries(); // update the scroll bars
     1247    d->commonListView->setPositionForIndex(position, index);
    14641248}
    14651249
     
    14821266
    14831267    if (rect.width() == 1 && rect.height() == 1) {
    1484         d->intersectingSet(rect.translated(horizontalOffset(), verticalOffset()));
     1268        const QVector<QModelIndex> intersectVector = d->intersectingSet(rect.translated(horizontalOffset(), verticalOffset()));
    14851269        QModelIndex tl;
    1486         if (!d->intersectVector.isEmpty())
    1487             tl = d->intersectVector.last(); // special case for mouse press; only select the top item
     1270        if (!intersectVector.isEmpty())
     1271            tl = intersectVector.last(); // special case for mouse press; only select the top item
    14881272        if (tl.isValid() && d->isIndexEnabled(tl))
    14891273            selection.select(tl, tl);
     
    14951279            // get the first item
    14961280            const QRect topLeft(rect.left() + horizontalOffset(), rect.top() + verticalOffset(), 1, 1);
    1497             d->intersectingSet(topLeft);
    1498             if (!d->intersectVector.isEmpty())
    1499                 tl = d->intersectVector.last();
     1281            QVector<QModelIndex> intersectVector = d->intersectingSet(topLeft);
     1282            if (!intersectVector.isEmpty())
     1283                tl = intersectVector.last();
    15001284            // get the last item
    15011285            const QRect bottomRight(rect.right() + horizontalOffset(), rect.bottom() + verticalOffset(), 1, 1);
    1502             d->intersectingSet(bottomRight);
    1503             if (!d->intersectVector.isEmpty())
    1504                 br = d->intersectVector.last();
     1286            intersectVector = d->intersectingSet(bottomRight);
     1287            if (!intersectVector.isEmpty())
     1288                br = intersectVector.last();
    15051289
    15061290            // get the ranges
     
    15451329                    // middle rectangle
    15461330                    if (top.bottom() < bottom.top()) {
    1547                         middle.setTop(top.bottom() + 1);
     1331                        if (gridSize().isValid() && !gridSize().isNull())
     1332                            middle.setTop(top.top() + gridSize().height());
     1333                        else
     1334                            middle.setTop(top.bottom() + 1);
    15481335                        middle.setLeft(qMin(top.left(), bottom.left()));
    15491336                        middle.setBottom(bottom.top() - 1);
     
    15721359                        middle.setTop(0);
    15731360                        middle.setBottom(ch);
    1574                         middle.setLeft(left.right() + 1);
     1361                        if (gridSize().isValid() && !gridSize().isNull())
     1362                            middle.setLeft(left.left() + gridSize().width());
     1363                        else
     1364                            middle.setLeft(left.right() + 1);
    15751365                        middle.setRight(right.left() - 1);
    15761366                    } else if (left.bottom() < right.top()) {
     
    16091399            continue;
    16101400        QModelIndex parent = selection.at(i).topLeft().parent();
     1401        //we only display the children of the root in a listview
     1402        //we're not interested in the other model indexes
     1403        if (parent != d->root)
     1404            continue;
    16111405        int t = selection.at(i).topLeft().row();
    16121406        int b = selection.at(i).bottomRight().row();
     
    16171411            while (t <= b && d->isHidden(t)) ++t;
    16181412            while (b >= t && d->isHidden(b)) --b;
    1619             const QModelIndex top = d->model->index(t, c, d->root);
    1620             const QModelIndex bottom = d->model->index(b, c, d->root);
     1413            const QModelIndex top = d->model->index(t, c, parent);
     1414            const QModelIndex bottom = d->model->index(b, c, parent);
    16211415            QRect rect(visualRect(top).topLeft(),
    16221416                       visualRect(bottom).bottomRight());
     
    16341428{
    16351429    Q_D(const QListView);
    1636     QModelIndexList viewSelected;
    1637     QModelIndexList modelSelected;
    1638     if (d->selectionModel)
    1639         modelSelected = d->selectionModel->selectedIndexes();
    1640     for (int i = 0; i < modelSelected.count(); ++i) {
    1641         QModelIndex index = modelSelected.at(i);
     1430    if (!d->selectionModel)
     1431        return QModelIndexList();
     1432
     1433    QModelIndexList viewSelected = d->selectionModel->selectedIndexes();
     1434    for (int i = 0; i < viewSelected.count(); ++i) {
     1435        const QModelIndex &index = viewSelected.at(i);
    16421436        if (!isIndexHidden(index) && index.parent() == d->root && index.column() == d->column)
    1643             viewSelected.append(index);
     1437            ++i;
     1438        else
     1439            viewSelected.removeAt(i);
    16441440    }
    16451441    return viewSelected;
     
    16581454    // triggering another layout
    16591455    QAbstractItemView::State oldState = state();
    1660     setState(ExpandingState); 
     1456    setState(ExpandingState);
    16611457    if (d->model->columnCount(d->root) > 0) { // no columns means no contents
    16621458        d->resetBatchStartRow();
     
    16851481        QStyleOptionViewItemV4 option = d->viewOptionsV4();
    16861482        QSize step = d->itemSize(option, index);
    1687 
    1688         QSize csize = d->contentsSize();
    1689         QSize vsize = d->viewport->size();
    1690         QSize max = maximumViewportSize();
    1691         if (max.width() >= d->contentsSize().width() && max.height() >= d->contentsSize().height())
    1692             vsize = max;
    1693 
    1694         // ### reorder the logic
    1695 
    1696         // ### split into static and dynamic
    1697 
    1698         const bool vertical = verticalScrollMode() == QAbstractItemView::ScrollPerItem;
    1699         const bool horizontal = horizontalScrollMode() == QAbstractItemView::ScrollPerItem;
    1700 
    1701         if (d->flow == TopToBottom) {
    1702             if (horizontal && d->isWrapping() && d->viewMode == ListMode) {
    1703                 const QVector<int> segmentPositions = d->staticListView->segmentPositions;
    1704                 const int steps = segmentPositions.count() - 1;
    1705                 if (steps > 0) {
    1706                     int pageSteps = d->staticListView->perItemScrollingPageSteps(vsize.width(),
    1707                                                                                  csize.width(),
    1708                                                                                  isWrapping());
    1709                     horizontalScrollBar()->setSingleStep(1);
    1710                     horizontalScrollBar()->setPageStep(pageSteps);
    1711                     horizontalScrollBar()->setRange(0, steps - pageSteps);
    1712                 } else {
    1713                     horizontalScrollBar()->setRange(0, 0);
    1714                 }
    1715             } else {
    1716                 horizontalScrollBar()->setSingleStep(step.width() + d->spacing());
    1717                 horizontalScrollBar()->setPageStep(vsize.width());
    1718                 horizontalScrollBar()->setRange(0, d->contentsSize().width() - vsize.width());
    1719             }
    1720             if (vertical && !d->isWrapping() && d->viewMode == ListMode) {
    1721                 const QVector<int> flowPositions = d->staticListView->flowPositions;
    1722                 const int steps = flowPositions.count() - 1;
    1723                 if (steps > 0) {
    1724                     int pageSteps = d->staticListView->perItemScrollingPageSteps(vsize.height(),
    1725                                                                                  csize.height(),
    1726                                                                                  isWrapping());
    1727                     verticalScrollBar()->setSingleStep(1);
    1728                     verticalScrollBar()->setPageStep(pageSteps);
    1729                     verticalScrollBar()->setRange(0, steps - pageSteps);
    1730                 } else {
    1731                     verticalScrollBar()->setRange(0, 0);
    1732                 }
    1733                 // } else if (vertical && d->isWrapping() && d->movement == Static) {
    1734                 // ### wrapped scrolling in flow direction
    1735             } else {
    1736                 verticalScrollBar()->setSingleStep(step.height() + d->spacing());
    1737                 verticalScrollBar()->setPageStep(vsize.height());
    1738                 verticalScrollBar()->setRange(0, d->contentsSize().height() - vsize.height());
    1739             }
    1740         } else { // LeftToRight
    1741             if (horizontal && !d->isWrapping() && d->viewMode == ListMode) {
    1742                 const QVector<int> flowPositions = d->staticListView->flowPositions;
    1743                 int steps = flowPositions.count() - 1;
    1744                 if (steps > 0) {
    1745                     int pageSteps = d->staticListView->perItemScrollingPageSteps(vsize.width(),
    1746                                                                                  csize.width(),
    1747                                                                                  isWrapping());
    1748                     horizontalScrollBar()->setSingleStep(1);
    1749                     horizontalScrollBar()->setPageStep(pageSteps);
    1750                     horizontalScrollBar()->setRange(0, steps - pageSteps);
    1751                 } else {
    1752                     horizontalScrollBar()->setRange(0, 0);
    1753                 }
    1754                 // } else if (horizontal && d->isWrapping() && d->movement == Static) {
    1755                 // ### wrapped scrolling in flow direction
    1756             } else {
    1757                 horizontalScrollBar()->setSingleStep(step.width() + d->spacing());
    1758                 horizontalScrollBar()->setPageStep(vsize.width());
    1759                 horizontalScrollBar()->setRange(0, d->contentsSize().width() - vsize.width());
    1760             }
    1761             if (vertical && d->isWrapping() && d->viewMode == ListMode) {
    1762                 const QVector<int> segmentPositions = d->staticListView->segmentPositions;
    1763                 int steps = segmentPositions.count() - 1;
    1764                 if (steps > 0) {
    1765                     int pageSteps = d->staticListView->perItemScrollingPageSteps(vsize.height(),
    1766                                                                                  csize.height(),
    1767                                                                                  isWrapping());
    1768                     verticalScrollBar()->setSingleStep(1);
    1769                     verticalScrollBar()->setPageStep(pageSteps);
    1770                     verticalScrollBar()->setRange(0, steps - pageSteps);
    1771                 } else {
    1772                     verticalScrollBar()->setRange(0, 0);
    1773                 }
    1774             } else {
    1775                 verticalScrollBar()->setSingleStep(step.height() + d->spacing());
    1776                 verticalScrollBar()->setPageStep(vsize.height());
    1777                 verticalScrollBar()->setRange(0, d->contentsSize().height() - vsize.height());
    1778             }
    1779         }
     1483        d->commonListView->updateHorizontalScrollBar(step);
     1484        d->commonListView->updateVerticalScrollBar(step);
    17801485    }
    17811486
     
    19261631QListViewPrivate::QListViewPrivate()
    19271632    : QAbstractItemViewPrivate(),
    1928       dynamicListView(0),
    1929       staticListView(0),
     1633      commonListView(0),
    19301634      wrap(false),
    19311635      space(0),
     
    19381642      column(0),
    19391643      uniformItemSizes(false),
    1940       batchSize(100)
     1644      batchSize(100),
     1645      showElasticBand(false)
    19411646{
    19421647}
     
    19441649QListViewPrivate::~QListViewPrivate()
    19451650{
    1946     delete staticListView;
    1947     delete dynamicListView;
     1651    delete commonListView;
    19481652}
    19491653
    19501654void QListViewPrivate::clear()
    19511655{
    1952     // ### split into dynamic and static
    19531656    // initialization of data structs
    19541657    cachedItemSize = QSize();
    1955     if (viewMode == QListView::ListMode)
    1956         staticListView->clear();
    1957     else
    1958         dynamicListView->clear();
     1658    commonListView->clear();
    19591659}
    19601660
     
    19651665
    19661666    //take the size as if there were scrollbar in order to prevent scrollbar to blink
    1967     layoutBounds = QRect(QPoint(0,0), q->maximumViewportSize());
     1667    layoutBounds = QRect(QPoint(), q->maximumViewportSize());
    19681668
    19691669    int frameAroundContents = 0;
    19701670    if (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents))
    19711671        frameAroundContents = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth) * 2;
    1972     int verticalMargin = vbarpolicy==Qt::ScrollBarAlwaysOff ? 0 :
    1973         q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, q->verticalScrollBar()) + frameAroundContents;
    1974     int horizontalMargin =  hbarpolicy==Qt::ScrollBarAlwaysOff ? 0 :
    1975         q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, q->horizontalScrollBar()) + frameAroundContents;
     1672
     1673    // maximumViewportSize() already takes scrollbar into account if policy is
     1674    // Qt::ScrollBarAlwaysOn but scrollbar extent must be deduced if policy
     1675    // is Qt::ScrollBarAsNeeded
     1676    int verticalMargin = vbarpolicy==Qt::ScrollBarAsNeeded
     1677        ? q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, vbar) + frameAroundContents
     1678        : 0;
     1679    int horizontalMargin =  hbarpolicy==Qt::ScrollBarAsNeeded
     1680        ? q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, hbar) + frameAroundContents
     1681        : 0;
    19761682
    19771683    layoutBounds.adjust(0, 0, -verticalMargin, -horizontalMargin);
    19781684
    1979     int rowCount = model->rowCount(root);
    1980     int colCount = model->columnCount(root);
    1981     if (colCount <= 0)
    1982         rowCount = 0; // no contents
    1983     if (viewMode == QListView::ListMode) {
    1984         staticListView->flowPositions.resize(rowCount);
    1985     } else {
    1986         dynamicListView->tree.create(qMax(rowCount - hiddenRows.count(), 0));
    1987     }
     1685    int rowCount = model->columnCount(root) <= 0 ? 0 : model->rowCount(root);
     1686    commonListView->setRowCount(rowCount);
    19881687}
    19891688
     
    19931692bool QListViewPrivate::doItemsLayout(int delta)
    19941693{
    1995     // ### split into static and dynamic
    19961694    int max = model->rowCount(root) - 1;
    19971695    int first = batchStartRow();
    19981696    int last = qMin(first + delta - 1, max);
    19991697
    2000     if (max < 0 || last < first)
    2001         return true; // nothing to do
    2002 
    20031698    if (first == 0) {
    20041699        layoutChildren(); // make sure the viewport has the right size
    20051700        prepareItemsLayout();
     1701    }
     1702
     1703    if (max < 0 || last < first) {
     1704        return true; // nothing to do
    20061705    }
    20071706
     
    20161715    info.max = max;
    20171716
    2018     if (viewMode == QListView::ListMode)
    2019         return staticListView->doBatchedItemLayout(info, max);
    2020     return dynamicListView->doBatchedItemLayout(info, max);
     1717    return commonListView->doBatchedItemLayout(info, max);
    20211718}
    20221719
     
    20261723        return QListViewItem();
    20271724
    2028     if (viewMode == QListView::ListMode)
    2029         return staticListView->indexToListViewItem(index);
    2030     return dynamicListView->indexToListViewItem(index);
    2031 }
    2032 
    2033 
    2034 int QListViewPrivate::itemIndex(const QListViewItem &item) const
    2035 {
    2036     if (viewMode == QListView::ListMode)
    2037         return staticListView->itemIndex(item);
    2038     return dynamicListView->itemIndex(item);
    2039 }
    2040 
    2041 QRect QListViewPrivate::mapToViewport(const QRect &rect, bool greedy) const
     1725    return commonListView->indexToListViewItem(index);
     1726}
     1727
     1728QRect QListViewPrivate::mapToViewport(const QRect &rect, bool extend) const
    20421729{
    20431730    Q_Q(const QListView);
     
    20451732        return rect;
    20461733
    2047     QRect result = rect;
    2048     if (greedy)
    2049         result = staticListView->mapToViewport(rect);
    2050 
     1734    QRect result = extend ? commonListView->mapToViewport(rect) : rect;
    20511735    int dx = -q->horizontalOffset();
    20521736    int dy = -q->verticalOffset();
    2053     result.adjust(dx, dy, dx, dy);
    2054     return result;
     1737    return result.adjusted(dx, dy, dx, dy);
    20551738}
    20561739
     
    21101793    QItemSelection selection;
    21111794    QModelIndex tl, br;
    2112     intersectingSet(rect);
    2113     QVector<QModelIndex>::iterator it = intersectVector.begin();
     1795    const QVector<QModelIndex> intersectVector = intersectingSet(rect);
     1796    QVector<QModelIndex>::const_iterator it = intersectVector.begin();
    21141797    for (; it != intersectVector.end(); ++it) {
    21151798        if (!tl.isValid() && !br.isValid()) {
     
    21351818}
    21361819
     1820#ifndef QT_NO_DRAGANDDROP
     1821QAbstractItemView::DropIndicatorPosition QListViewPrivate::position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const
     1822{
     1823    if (viewMode == QListView::ListMode && flow == QListView::LeftToRight)
     1824        return static_cast<QListModeViewBase *>(commonListView)->position(pos, rect, idx);
     1825    else
     1826        return QAbstractItemViewPrivate::position(pos, rect, idx);
     1827}
     1828#endif
     1829
    21371830/*
    2138  * Static ListView Implementation
    2139 */
    2140 
    2141 int QStaticListViewBase::verticalPerItemValue(int itemIndex, int verticalValue, int areaHeight,
    2142                                                  bool above, bool below, bool wrap,
    2143                                                  QListView::ScrollHint hint, int itemHeight) const
    2144 {
    2145     int value = qBound(0, verticalValue, flowPositions.count() - 1);
    2146     if (above)
    2147         return perItemScrollToValue(itemIndex, value, areaHeight, QListView::PositionAtTop,
    2148                                     Qt::Vertical,wrap, itemHeight);
    2149     else if (below)
    2150         return perItemScrollToValue(itemIndex, value, areaHeight, QListView::PositionAtBottom,
    2151                                     Qt::Vertical, wrap, itemHeight);
    2152     else if (hint != QListView::EnsureVisible)
    2153         return perItemScrollToValue(itemIndex, value, areaHeight, hint, Qt::Vertical, wrap, itemHeight);
    2154     return value;
    2155 }
    2156 
    2157 int QStaticListViewBase::horizontalPerItemValue(int itemIndex, int horizontalValue, int areaWidth,
    2158                                                    bool leftOf, bool rightOf, bool wrap,
    2159                                                    QListView::ScrollHint hint, int itemWidth) const
    2160 {
    2161     int value = qBound(0, horizontalValue, flowPositions.count() - 1);
     1831 * Common ListView Implementation
     1832*/
     1833
     1834void QCommonListViewBase::appendHiddenRow(int row)
     1835{
     1836    dd->hiddenRows.append(dd->model->index(row, 0, qq->rootIndex()));
     1837}
     1838
     1839void QCommonListViewBase::removeHiddenRow(int row)
     1840{
     1841    dd->hiddenRows.remove(dd->hiddenRows.indexOf(dd->model->index(row, 0, qq->rootIndex())));
     1842}
     1843
     1844void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step)
     1845{
     1846    horizontalScrollBar()->setSingleStep(step.width() + spacing());
     1847    horizontalScrollBar()->setPageStep(viewport()->width());
     1848    horizontalScrollBar()->setRange(0, contentsSize.width() - viewport()->width() - 2 * spacing());
     1849}
     1850
     1851void QCommonListViewBase::updateVerticalScrollBar(const QSize &step)
     1852{
     1853    verticalScrollBar()->setSingleStep(step.height() + spacing());
     1854    verticalScrollBar()->setPageStep(viewport()->height());
     1855    verticalScrollBar()->setRange(0, contentsSize.height() - viewport()->height() - 2 * spacing());
     1856}
     1857
     1858void QCommonListViewBase::scrollContentsBy(int dx, int dy, bool /*scrollElasticBand*/)
     1859{
     1860    dd->scrollContentsBy(isRightToLeft() ? -dx : dx, dy);
     1861}
     1862
     1863int QCommonListViewBase::verticalScrollToValue(int /*index*/, QListView::ScrollHint hint,
     1864                                          bool above, bool below, const QRect &area, const QRect &rect) const
     1865{
     1866    int verticalValue = verticalScrollBar()->value();
     1867    QRect adjusted = rect.adjusted(-spacing(), -spacing(), spacing(), spacing());
     1868    if (hint == QListView::PositionAtTop || above)
     1869        verticalValue += adjusted.top();
     1870    else if (hint == QListView::PositionAtBottom || below)
     1871        verticalValue += qMin(adjusted.top(), adjusted.bottom() - area.height() + 1);
     1872    else if (hint == QListView::PositionAtCenter)
     1873        verticalValue += adjusted.top() - ((area.height() - adjusted.height()) / 2);
     1874    return verticalValue;
     1875}
     1876
     1877int QCommonListViewBase::horizontalOffset() const
     1878{
     1879    return (isRightToLeft() ? horizontalScrollBar()->maximum() - horizontalScrollBar()->value() : horizontalScrollBar()->value());
     1880}
     1881
     1882int QCommonListViewBase::horizontalScrollToValue(const int /*index*/, QListView::ScrollHint hint,
     1883                                            bool leftOf, bool rightOf, const QRect &area, const QRect &rect) const
     1884{
     1885    int horizontalValue = horizontalScrollBar()->value();
     1886    if (isRightToLeft()) {
     1887        if (hint == QListView::PositionAtCenter) {
     1888            horizontalValue += ((area.width() - rect.width()) / 2) - rect.left();
     1889        } else {
     1890            if (leftOf)
     1891                horizontalValue -= rect.left();
     1892            else if (rightOf)
     1893                horizontalValue += qMin(rect.left(), area.width() - rect.right());
     1894        }
     1895    } else {
     1896        if (hint == QListView::PositionAtCenter) {
     1897            horizontalValue += rect.left() - ((area.width()- rect.width()) / 2);
     1898        } else {
     1899            if (leftOf)
     1900                horizontalValue += rect.left();
     1901            else if (rightOf)
     1902                horizontalValue += qMin(rect.left(), rect.right() - area.width());
     1903        }
     1904    }
     1905    return horizontalValue;
     1906}
     1907
     1908/*
     1909 * ListMode ListView Implementation
     1910*/
     1911
     1912#ifndef QT_NO_DRAGANDDROP
     1913void QListModeViewBase::paintDragDrop(QPainter *painter)
     1914{
     1915    // FIXME: Until the we can provide a proper drop indicator
     1916    // in IconMode, it makes no sense to show it
     1917    dd->paintDropIndicator(painter);
     1918}
     1919
     1920QAbstractItemView::DropIndicatorPosition QListModeViewBase::position(const QPoint &pos, const QRect &rect, const QModelIndex &index) const
     1921{
     1922    QAbstractItemView::DropIndicatorPosition r = QAbstractItemView::OnViewport;
     1923    if (!dd->overwrite) {
     1924        const int margin = 2;
     1925        if (pos.x() - rect.left() < margin) {
     1926            r = QAbstractItemView::AboveItem;   // Visually, on the left
     1927        } else if (rect.right() - pos.x() < margin) {
     1928            r = QAbstractItemView::BelowItem;   // Visually, on the right
     1929        } else if (rect.contains(pos, true)) {
     1930            r = QAbstractItemView::OnItem;
     1931        }
     1932    } else {
     1933        QRect touchingRect = rect;
     1934        touchingRect.adjust(-1, -1, 1, 1);
     1935        if (touchingRect.contains(pos, false)) {
     1936            r = QAbstractItemView::OnItem;
     1937        }
     1938    }
     1939
     1940    if (r == QAbstractItemView::OnItem && (!(dd->model->flags(index) & Qt::ItemIsDropEnabled)))
     1941        r = pos.x() < rect.center().x() ? QAbstractItemView::AboveItem : QAbstractItemView::BelowItem;
     1942
     1943    return r;
     1944}
     1945
     1946void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event)
     1947{
     1948    if (qq->dragDropMode() == QAbstractItemView::InternalMove
     1949        && (event->source() != qq || !(event->possibleActions() & Qt::MoveAction)))
     1950        return;
     1951
     1952    // ignore by default
     1953    event->ignore();
     1954
     1955    QModelIndex index = qq->indexAt(event->pos());
     1956    dd->hover = index;
     1957    if (!dd->droppingOnItself(event, index)
     1958        && dd->canDecode(event)) {
     1959
     1960        if (index.isValid() && dd->showDropIndicator) {
     1961            QRect rect = qq->visualRect(index);
     1962            dd->dropIndicatorPosition = position(event->pos(), rect, index);
     1963            switch (dd->dropIndicatorPosition) {
     1964            case QAbstractItemView::AboveItem:
     1965                if (dd->isIndexDropEnabled(index.parent())) {
     1966                    dd->dropIndicatorRect = QRect(rect.left(), rect.top(), 0, rect.height());
     1967                    event->accept();
     1968                } else {
     1969                    dd->dropIndicatorRect = QRect();
     1970                }
     1971                break;
     1972            case QAbstractItemView::BelowItem:
     1973                if (dd->isIndexDropEnabled(index.parent())) {
     1974                    dd->dropIndicatorRect = QRect(rect.right(), rect.top(), 0, rect.height());
     1975                    event->accept();
     1976                } else {
     1977                    dd->dropIndicatorRect = QRect();
     1978                }
     1979                break;
     1980            case QAbstractItemView::OnItem:
     1981                if (dd->isIndexDropEnabled(index)) {
     1982                    dd->dropIndicatorRect = rect;
     1983                    event->accept();
     1984                } else {
     1985                    dd->dropIndicatorRect = QRect();
     1986                }
     1987                break;
     1988            case QAbstractItemView::OnViewport:
     1989                dd->dropIndicatorRect = QRect();
     1990                if (dd->isIndexDropEnabled(qq->rootIndex())) {
     1991                    event->accept(); // allow dropping in empty areas
     1992                }
     1993                break;
     1994            }
     1995        } else {
     1996            dd->dropIndicatorRect = QRect();
     1997            dd->dropIndicatorPosition = QAbstractItemView::OnViewport;
     1998            if (dd->isIndexDropEnabled(qq->rootIndex())) {
     1999                event->accept(); // allow dropping in empty areas
     2000            }
     2001        }
     2002        dd->viewport->update();
     2003    } // can decode
     2004
     2005    if (dd->shouldAutoScroll(event->pos()))
     2006        qq->startAutoScroll();
     2007}
     2008
     2009#endif //QT_NO_DRAGANDDROP
     2010
     2011void QListModeViewBase::updateVerticalScrollBar(const QSize &step)
     2012{
     2013    if (verticalScrollMode() == QAbstractItemView::ScrollPerItem
     2014        && ((flow() == QListView::TopToBottom && !isWrapping())
     2015        || (flow() == QListView::LeftToRight && isWrapping()))) {
     2016            const int steps = (flow() == QListView::TopToBottom ? scrollValueMap : segmentPositions).count() - 1;
     2017            if (steps > 0) {
     2018                const int pageSteps = perItemScrollingPageSteps(viewport()->height(), contentsSize.height(), isWrapping());
     2019                verticalScrollBar()->setSingleStep(1);
     2020                verticalScrollBar()->setPageStep(pageSteps);
     2021                verticalScrollBar()->setRange(0, steps - pageSteps);
     2022            } else {
     2023                verticalScrollBar()->setRange(0, 0);
     2024            }
     2025            // } else if (vertical && d->isWrapping() && d->movement == Static) {
     2026            // ### wrapped scrolling in flow direction
     2027    } else {
     2028        QCommonListViewBase::updateVerticalScrollBar(step);
     2029    }
     2030}
     2031
     2032void QListModeViewBase::updateHorizontalScrollBar(const QSize &step)
     2033{
     2034    if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem
     2035        && ((flow() == QListView::TopToBottom && isWrapping())
     2036        || (flow() == QListView::LeftToRight && !isWrapping()))) {
     2037            int steps = (flow() == QListView::TopToBottom ? segmentPositions : scrollValueMap).count() - 1;
     2038            if (steps > 0) {
     2039                const int pageSteps = perItemScrollingPageSteps(viewport()->width(), contentsSize.width(), isWrapping());
     2040                horizontalScrollBar()->setSingleStep(1);
     2041                horizontalScrollBar()->setPageStep(pageSteps);
     2042                horizontalScrollBar()->setRange(0, steps - pageSteps);
     2043            } else {
     2044                horizontalScrollBar()->setRange(0, 0);
     2045            }
     2046    } else {
     2047        QCommonListViewBase::updateHorizontalScrollBar(step);
     2048    }
     2049}
     2050
     2051int QListModeViewBase::verticalScrollToValue(int index, QListView::ScrollHint hint,
     2052                                          bool above, bool below, const QRect &area, const QRect &rect) const
     2053{
     2054    if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
     2055        int value;
     2056        if (scrollValueMap.isEmpty())
     2057            value = 0;
     2058        else
     2059            value = qBound(0, scrollValueMap.at(verticalScrollBar()->value()), flowPositions.count() - 1);
     2060        if (above)
     2061            hint = QListView::PositionAtTop;
     2062        else if (below)
     2063            hint = QListView::PositionAtBottom;
     2064        if (hint == QListView::EnsureVisible)
     2065            return value;
     2066
     2067        return perItemScrollToValue(index, value, area.height(), hint, Qt::Vertical, isWrapping(), rect.height());
     2068    }
     2069
     2070    return QCommonListViewBase::verticalScrollToValue(index, hint, above, below, area, rect);
     2071}
     2072
     2073int QListModeViewBase::horizontalOffset() const
     2074{
     2075    if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
     2076        if (isWrapping()) {
     2077            if (flow() == QListView::TopToBottom && !segmentPositions.isEmpty()) {
     2078                const int max = segmentPositions.count() - 1;
     2079                int currentValue = qBound(0, horizontalScrollBar()->value(), max);
     2080                int position = segmentPositions.at(currentValue);
     2081                int maximumValue = qBound(0, horizontalScrollBar()->maximum(), max);
     2082                int maximum = segmentPositions.at(maximumValue);
     2083                return (isRightToLeft() ? maximum - position : position);
     2084            }
     2085        } else if (flow() == QListView::LeftToRight && !flowPositions.isEmpty()) {
     2086            int position = flowPositions.at(scrollValueMap.at(horizontalScrollBar()->value()));
     2087            int maximum = flowPositions.at(scrollValueMap.at(horizontalScrollBar()->maximum()));
     2088            return (isRightToLeft() ? maximum - position : position);
     2089        }
     2090    }
     2091    return QCommonListViewBase::horizontalOffset();
     2092}
     2093
     2094int QListModeViewBase::verticalOffset() const
     2095{
     2096    if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
     2097        if (isWrapping()) {
     2098            if (flow() == QListView::LeftToRight && !segmentPositions.isEmpty()) {
     2099                int value = verticalScrollBar()->value();
     2100                if (value >= segmentPositions.count())
     2101                    return 0;
     2102                return segmentPositions.at(value);
     2103            }
     2104        } else if (flow() == QListView::TopToBottom && !flowPositions.isEmpty()) {
     2105            int value = verticalScrollBar()->value();
     2106            if (value > scrollValueMap.count())
     2107                return 0;
     2108            return flowPositions.at(scrollValueMap.at(value)) - spacing();
     2109        }
     2110    }
     2111    return QCommonListViewBase::verticalOffset();
     2112}
     2113
     2114int QListModeViewBase::horizontalScrollToValue(int index, QListView::ScrollHint hint,
     2115                                            bool leftOf, bool rightOf, const QRect &area, const QRect &rect) const
     2116{
     2117    if (horizontalScrollMode() != QAbstractItemView::ScrollPerItem)
     2118        return QCommonListViewBase::horizontalScrollToValue(index, hint, leftOf, rightOf, area, rect);
     2119
     2120    int value;
     2121    if (scrollValueMap.isEmpty())
     2122        value = 0;
     2123    else
     2124        value = qBound(0, scrollValueMap.at(horizontalScrollBar()->value()), flowPositions.count() - 1);
    21622125    if (leftOf)
    2163         return perItemScrollToValue(itemIndex, value, areaWidth, QListView::PositionAtTop,
    2164                                     Qt::Horizontal, wrap, itemWidth);
     2126        hint = QListView::PositionAtTop;
    21652127    else if (rightOf)
    2166         return perItemScrollToValue(itemIndex, value, areaWidth, QListView::PositionAtBottom,
    2167                                     Qt::Horizontal, wrap, itemWidth);
    2168     else if (hint != QListView::EnsureVisible)
    2169         return perItemScrollToValue(itemIndex, value, areaWidth, hint, Qt::Horizontal, wrap, itemWidth);
    2170     return value;
    2171 }
    2172 
    2173 void QStaticListViewBase::scrollContentsBy(int &dx, int &dy)
     2128        hint = QListView::PositionAtBottom;
     2129    if (hint == QListView::EnsureVisible)
     2130        return value;
     2131
     2132    return perItemScrollToValue(index, value, area.width(), hint, Qt::Horizontal, isWrapping(), rect.width());
     2133}
     2134
     2135void QListModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand)
    21742136{
    21752137    // ### reorder this logic
    2176     const int verticalValue = verticalScrollBarValue();
    2177     const int horizontalValue = horizontalScrollBarValue();
     2138    const int verticalValue = verticalScrollBar()->value();
     2139    const int horizontalValue = horizontalScrollBar()->value();
    21782140    const bool vertical = (verticalScrollMode() == QAbstractItemView::ScrollPerItem);
    21792141    const bool horizontal = (horizontalScrollMode() == QAbstractItemView::ScrollPerItem);
     
    22032165            int currentValue = qBound(0, verticalValue, max);
    22042166            int previousValue = qBound(0, currentValue + dy, max);
    2205             int currentCoordinate = flowPositions.at(currentValue);
    2206             int previousCoordinate = flowPositions.at(previousValue);
     2167            int currentCoordinate = flowPositions.at(scrollValueMap.at(currentValue));
     2168            int previousCoordinate = flowPositions.at(scrollValueMap.at(previousValue));
    22072169            dy = previousCoordinate - currentCoordinate;
    22082170        } else if (horizontal && flow() == QListView::LeftToRight && dx != 0) {
    22092171            int currentValue = qBound(0, horizontalValue, max);
    22102172            int previousValue = qBound(0, currentValue + dx, max);
    2211             int currentCoordinate = flowPositions.at(currentValue);
    2212             int previousCoordinate = flowPositions.at(previousValue);
     2173            int currentCoordinate = flowPositions.at(scrollValueMap.at(currentValue));
     2174            int previousCoordinate = flowPositions.at(scrollValueMap.at(previousValue));
    22132175            dx = previousCoordinate - currentCoordinate;
    22142176        }
    22152177    }
    2216 }
    2217 
    2218 bool QStaticListViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max)
     2178    QCommonListViewBase::scrollContentsBy(dx, dy, scrollElasticBand);
     2179}
     2180
     2181bool QListModeViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max)
    22192182{
    22202183    doStaticLayout(info);
     
    22282191}
    22292192
    2230 QListViewItem QStaticListViewBase::indexToListViewItem(const QModelIndex &index) const
     2193QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) const
    22312194{
    22322195    if (flowPositions.isEmpty()
    22332196        || segmentPositions.isEmpty()
    2234         || index.row() > flowPositions.count())
     2197        || index.row() >= flowPositions.count())
    22352198        return QListViewItem();
    22362199
     
    22642227}
    22652228
    2266 QPoint QStaticListViewBase::initStaticLayout(const QListViewLayoutInfo &info)
     2229QPoint QListModeViewBase::initStaticLayout(const QListViewLayoutInfo &info)
    22672230{
    22682231    int x, y;
     
    22722235        segmentStartRows.clear();
    22732236        segmentExtents.clear();
     2237        scrollValueMap.clear();
    22742238        x = info.bounds.left() + info.spacing;
    22752239        y = info.bounds.top() + info.spacing;
     
    22992263  \internal
    23002264*/
    2301 void QStaticListViewBase::doStaticLayout(const QListViewLayoutInfo &info)
     2265void QListModeViewBase::doStaticLayout(const QListViewLayoutInfo &info)
    23022266{
    23032267    const bool useItemSize = !info.grid.isValid();
     
    23632327            }
    23642328            // save the flow position of this item
     2329            scrollValueMap.append(flowPositions.count());
    23652330            flowPositions.append(flowPosition);
    23662331            // prepare for the next item
     
    23882353    if (info.last == info.max) {
    23892354        segmentExtents.append(flowPosition);
     2355        scrollValueMap.append(flowPositions.count());
    23902356        flowPositions.append(flowPosition);
    23912357        segmentPositions.append(info.wrap ? segPosition + deltaSegPosition : INT_MAX);
     
    24022368  In this function, itemsize is counted from topleft to the start of the next item.
    24032369*/
    2404 void QStaticListViewBase::intersectingStaticSet(const QRect &area) const
    2405 {
    2406     clearIntersections();
     2370QVector<QModelIndex> QListModeViewBase::intersectingSet(const QRect &area) const
     2371{
     2372    QVector<QModelIndex> ret;
    24072373    int segStartPosition;
    24082374    int segEndPosition;
     
    24212387    }
    24222388    if (segmentPositions.count() < 2 || flowPositions.isEmpty())
    2423         return;
     2389        return ret;
    24242390    // the last segment position is actually the edge of the last segment
    24252391    const int segLast = segmentPositions.count() - 2;
     
    24362402            QModelIndex index = modelIndex(row);
    24372403            if (index.isValid())
    2438                 appendToIntersections(index);
     2404                ret += index;
    24392405#if 0 // for debugging
    24402406            else
    2441                 qWarning("intersectingStaticSet: row %d was invalid", row);
     2407                qWarning("intersectingSet: row %d was invalid", row);
    24422408#endif
    24432409        }
    24442410    }
    2445 }
    2446 
    2447 int QStaticListViewBase::itemIndex(const QListViewItem &item) const
    2448 {
    2449     return item.indexHint;
    2450 }
    2451 
    2452 QRect QStaticListViewBase::mapToViewport(const QRect &rect) const
     2411    return ret;
     2412}
     2413
     2414void QListModeViewBase::dataChanged(const QModelIndex &, const QModelIndex &)
     2415{
     2416    dd->doDelayedItemsLayout();
     2417}
     2418
     2419
     2420QRect QListModeViewBase::mapToViewport(const QRect &rect) const
    24532421{
    24542422    if (isWrapping())
    24552423        return rect;
    24562424    // If the listview is in "listbox-mode", the items are as wide as the view.
     2425    // But we don't shrink the items.
    24572426    QRect result = rect;
    2458     QSize vsize = viewport()->size();
    2459     QSize csize = contentsSize;
    24602427    if (flow() == QListView::TopToBottom) {
    24612428        result.setLeft(spacing());
    2462         result.setWidth(qMax(csize.width(), vsize.width()) - 2 * spacing());
     2429        result.setWidth(qMax(rect.width(), qMax(contentsSize.width(), viewport()->width()) - 2 * spacing()));
    24632430    } else { // LeftToRight
    24642431        result.setTop(spacing());
    2465         result.setHeight(qMax(csize.height(), vsize.height()) - 2 * spacing());
     2432        result.setHeight(qMax(rect.height(), qMax(contentsSize.height(), viewport()->height()) - 2 * spacing()));
    24662433    }
    24672434    return result;
    24682435}
    24692436
    2470 int QStaticListViewBase::perItemScrollingPageSteps(int length, int bounds, bool wrap) const
    2471 {
    2472     const QVector<int> positions = (wrap ? segmentPositions : flowPositions);
     2437int QListModeViewBase::perItemScrollingPageSteps(int length, int bounds, bool wrap) const
     2438{
     2439    QVector<int> positions;
     2440    if (wrap)
     2441        positions = segmentPositions;
     2442    else if (!flowPositions.isEmpty()) {
     2443        positions.reserve(scrollValueMap.size());
     2444        foreach (int itemShown, scrollValueMap)
     2445            positions.append(flowPositions.at(itemShown));
     2446    }
    24732447    if (positions.isEmpty() || bounds <= length)
    24742448        return positions.count();
     
    24962470}
    24972471
    2498 int QStaticListViewBase::perItemScrollToValue(int index, int scrollValue, int viewportSize,
     2472int QListModeViewBase::perItemScrollToValue(int index, int scrollValue, int viewportSize,
    24992473                                                 QAbstractItemView::ScrollHint hint,
    25002474                                                 Qt::Orientation orientation, bool wrap, int itemExtent) const
     
    25562530}
    25572531
    2558 void QStaticListViewBase::clear()
     2532void QListModeViewBase::clear()
    25592533{
    25602534    flowPositions.clear();
     
    25682542
    25692543/*
    2570  * Dynamic ListView Implementation
    2571 */
    2572 
    2573 void QDynamicListViewBase::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
     2544 * IconMode ListView Implementation
     2545*/
     2546
     2547void QIconModeViewBase::setPositionForIndex(const QPoint &position, const QModelIndex &index)
     2548{
     2549    if (index.row() >= items.count())
     2550        return;
     2551    const QSize oldContents = contentsSize;
     2552    qq->update(index); // update old position
     2553    moveItem(index.row(), position);
     2554    qq->update(index); // update new position
     2555
     2556    if (contentsSize != oldContents)
     2557        dd->viewUpdateGeometries(); // update the scroll bars
     2558}
     2559
     2560void QIconModeViewBase::appendHiddenRow(int row)
     2561{
     2562    if (row >= 0 && row < items.count()) //remove item
     2563        tree.removeLeaf(items.at(row).rect(), row);
     2564    QCommonListViewBase::appendHiddenRow(row);
     2565}
     2566
     2567void QIconModeViewBase::removeHiddenRow(int row)
     2568{
     2569    QCommonListViewBase::removeHiddenRow(row);
     2570    if (row >= 0 && row < items.count()) //insert item
     2571        tree.insertLeaf(items.at(row).rect(), row);
     2572}
     2573
     2574#ifndef QT_NO_DRAGANDDROP
     2575void QIconModeViewBase::paintDragDrop(QPainter *painter)
     2576{
     2577    if (!draggedItems.isEmpty() && viewport()->rect().contains(draggedItemsPos)) {
     2578        //we need to draw the items that arre dragged
     2579        painter->translate(draggedItemsDelta());
     2580        QStyleOptionViewItemV4 option = viewOptions();
     2581        option.state &= ~QStyle::State_MouseOver;
     2582        QVector<QModelIndex>::const_iterator it = draggedItems.begin();
     2583        QListViewItem item = indexToListViewItem(*it);
     2584        for (; it != draggedItems.end(); ++it) {
     2585            item = indexToListViewItem(*it);
     2586            option.rect = viewItemRect(item);
     2587            delegate(*it)->paint(painter, option, *it);
     2588        }
     2589    }
     2590}
     2591
     2592bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions)
     2593{
     2594    // This function does the same thing as in QAbstractItemView::startDrag(),
     2595    // plus adding viewitems to the draggedItems list.
     2596    // We need these items to draw the drag items
     2597    QModelIndexList indexes = dd->selectionModel->selectedIndexes();
     2598    if (indexes.count() > 0 ) {
     2599        if (viewport()->acceptDrops()) {
     2600            QModelIndexList::ConstIterator it = indexes.constBegin();
     2601            for (; it != indexes.constEnd(); ++it)
     2602                if (dd->model->flags(*it) & Qt::ItemIsDragEnabled
     2603                    && (*it).column() == dd->column)
     2604                    draggedItems.push_back(*it);
     2605        }
     2606        QDrag *drag = new QDrag(qq);
     2607        drag->setMimeData(dd->model->mimeData(indexes));
     2608        Qt::DropAction action = drag->exec(supportedActions, Qt::CopyAction);
     2609        draggedItems.clear();
     2610        if (action == Qt::MoveAction)
     2611            dd->clearOrRemove();
     2612    }
     2613    return true;
     2614}
     2615
     2616bool QIconModeViewBase::filterDropEvent(QDropEvent *e)
     2617{
     2618    if (e->source() != qq)
     2619        return false;
     2620
     2621    const QSize contents = contentsSize;
     2622    QPoint offset(horizontalOffset(), verticalOffset());
     2623    QPoint end = e->pos() + offset;
     2624    QPoint start = dd->pressedPosition;
     2625    QPoint delta = (dd->movement == QListView::Snap ? snapToGrid(end) - snapToGrid(start) : end - start);
     2626    QList<QModelIndex> indexes = dd->selectionModel->selectedIndexes();
     2627    for (int i = 0; i < indexes.count(); ++i) {
     2628        QModelIndex index = indexes.at(i);
     2629        QRect rect = dd->rectForIndex(index);
     2630        viewport()->update(dd->mapToViewport(rect, false));
     2631        QPoint dest = rect.topLeft() + delta;
     2632        if (qq->isRightToLeft())
     2633            dest.setX(dd->flipX(dest.x()) - rect.width());
     2634        moveItem(index.row(), dest);
     2635        qq->update(index);
     2636    }
     2637    dd->stopAutoScroll();
     2638    draggedItems.clear();
     2639    dd->emitIndexesMoved(indexes);
     2640    e->accept(); // we have handled the event
     2641    // if the size has not grown, we need to check if it has shrinked
     2642    if (contentsSize != contents) {
     2643        if ((contentsSize.width() <= contents.width()
     2644            || contentsSize.height() <= contents.height())) {
     2645                updateContentsSize();
     2646        }
     2647        dd->viewUpdateGeometries();
     2648    }
     2649    return true;
     2650}
     2651
     2652bool QIconModeViewBase::filterDragLeaveEvent(QDragLeaveEvent *e)
     2653{
     2654    viewport()->update(draggedItemsRect()); // erase the area
     2655    draggedItemsPos = QPoint(-1, -1); // don't draw the dragged items
     2656    return QCommonListViewBase::filterDragLeaveEvent(e);
     2657}
     2658
     2659bool QIconModeViewBase::filterDragMoveEvent(QDragMoveEvent *e)
     2660{
     2661    if (e->source() != qq || !dd->canDecode(e))
     2662        return false;
     2663
     2664    // ignore by default
     2665    e->ignore();
     2666    // get old dragged items rect
     2667    QRect itemsRect = this->itemsRect(draggedItems);
     2668    viewport()->update(itemsRect.translated(draggedItemsDelta()));
     2669    // update position
     2670    draggedItemsPos = e->pos();
     2671    // get new items rect
     2672    viewport()->update(itemsRect.translated(draggedItemsDelta()));
     2673    // set the item under the cursor to current
     2674    QModelIndex index;
     2675    if (movement() == QListView::Snap) {
     2676        QRect rect(snapToGrid(e->pos() + offset()), gridSize());
     2677        const QVector<QModelIndex> intersectVector = intersectingSet(rect);
     2678        index = intersectVector.count() > 0 ? intersectVector.last() : QModelIndex();
     2679    } else {
     2680        index = qq->indexAt(e->pos());
     2681    }
     2682    // check if we allow drops here
     2683    if (draggedItems.contains(index))
     2684        e->accept(); // allow changing item position
     2685    else if (dd->model->flags(index) & Qt::ItemIsDropEnabled)
     2686        e->accept(); // allow dropping on dropenabled items
     2687    else if (!index.isValid())
     2688        e->accept(); // allow dropping in empty areas
     2689
     2690    // the event was treated. do autoscrolling
     2691    if (dd->shouldAutoScroll(e->pos()))
     2692        dd->startAutoScroll();
     2693    return true;
     2694}
     2695#endif // QT_NO_DRAGANDDROP
     2696
     2697void QIconModeViewBase::setRowCount(int rowCount)
     2698{
     2699    tree.create(qMax(rowCount - hiddenCount(), 0));
     2700}
     2701
     2702void QIconModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand)
     2703{
     2704    if (scrollElasticBand)
     2705        dd->scrollElasticBandBy(isRightToLeft() ? -dx : dx, dy);
     2706
     2707    QCommonListViewBase::scrollContentsBy(dx, dy, scrollElasticBand);
     2708    if (!draggedItems.isEmpty())
     2709        viewport()->update(draggedItemsRect().translated(dx, dy));
     2710}
     2711
     2712void QIconModeViewBase::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
    25742713{
    25752714    if (column() >= topLeft.column() && column() <= bottomRight.column())  {
     
    25812720}
    25822721
    2583 bool QDynamicListViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max)
     2722bool QIconModeViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max)
    25842723{
    25852724    if (info.last >= items.count()) {
    2586         createItems(info.last + 1);
     2725        //first we create the items
     2726        QStyleOptionViewItemV4 option = viewOptions();
     2727        for (int row = items.count(); row <= info.last; ++row) {
     2728            QSize size = itemSize(option, modelIndex(row));
     2729            QListViewItem item(QRect(0, 0, size.width(), size.height()), row); // default pos
     2730            items.append(item);
     2731        }
    25872732        doDynamicLayout(info);
    25882733    }
     
    25902735}
    25912736
    2592 QListViewItem QDynamicListViewBase::indexToListViewItem(const QModelIndex &index) const
     2737QListViewItem QIconModeViewBase::indexToListViewItem(const QModelIndex &index) const
    25932738{
    25942739    if (index.isValid() && index.row() < items.count())
     
    25972742}
    25982743
    2599 void QDynamicListViewBase::initBspTree(const QSize &contents)
     2744void QIconModeViewBase::initBspTree(const QSize &contents)
    26002745{
    26012746    // remove all items from the tree
     
    26142759}
    26152760
    2616 QPoint QDynamicListViewBase::initDynamicLayout(const QListViewLayoutInfo &info)
     2761QPoint QIconModeViewBase::initDynamicLayout(const QListViewLayoutInfo &info)
    26172762{
    26182763    int x, y;
     
    26362781  \internal
    26372782*/
    2638 void QDynamicListViewBase::doDynamicLayout(const QListViewLayoutInfo &info)
     2783void QIconModeViewBase::doDynamicLayout(const QListViewLayoutInfo &info)
    26392784{
    26402785    const bool useItemSize = !info.grid.isValid();
     
    26702815        moved.resize(items.count());
    26712816
    2672     QRect rect(QPoint(0, 0), topLeft);
     2817    QRect rect(QPoint(), topLeft);
    26732818    QListViewItem *item = 0;
    26742819    for (int row = info.first; row <= info.last; ++row) {
     
    27632908}
    27642909
    2765 void QDynamicListViewBase::intersectingDynamicSet(const QRect &area) const
    2766 {
    2767     clearIntersections();
    2768     QListViewPrivate *that = const_cast<QListViewPrivate*>(dd);
     2910QVector<QModelIndex> QIconModeViewBase::intersectingSet(const QRect &area) const
     2911{
     2912    QIconModeViewBase *that = const_cast<QIconModeViewBase*>(this);
    27692913    QBspTree::Data data(static_cast<void*>(that));
    2770     that->dynamicListView->tree.climbTree(area, &QDynamicListViewBase::addLeaf, data);
    2771 }
    2772 
    2773 void QDynamicListViewBase::createItems(int to)
    2774 {
    2775     int count = items.count();
    2776     QSize size;
    2777     QStyleOptionViewItemV4 option = viewOptions();
    2778     for (int row = count; row < to; ++row) {
    2779         size = itemSize(option, modelIndex(row));
    2780         QListViewItem item(QRect(0, 0, size.width(), size.height()), row); // default pos
    2781         items.append(item);
    2782     }
    2783 }
    2784 
    2785 void QDynamicListViewBase::drawItems(QPainter *painter, const QVector<QModelIndex> &indexes) const
    2786 {
    2787     QStyleOptionViewItemV4 option = viewOptions();
    2788     option.state &= ~QStyle::State_MouseOver;
    2789     QVector<QModelIndex>::const_iterator it = indexes.begin();
    2790     QListViewItem item = indexToListViewItem(*it);
    2791     for (; it != indexes.end(); ++it) {
    2792         item = indexToListViewItem(*it);
    2793         option.rect = viewItemRect(item);
    2794         delegate(*it)->paint(painter, option, *it);
    2795     }
    2796 }
    2797 
    2798 QRect QDynamicListViewBase::itemsRect(const QVector<QModelIndex> &indexes) const
     2914    QVector<QModelIndex> res;
     2915    that->interSectingVector = &res;
     2916    that->tree.climbTree(area, &QIconModeViewBase::addLeaf, data);
     2917    that->interSectingVector = 0;
     2918    return res;
     2919}
     2920
     2921QRect QIconModeViewBase::itemsRect(const QVector<QModelIndex> &indexes) const
    27992922{
    28002923    QVector<QModelIndex>::const_iterator it = indexes.begin();
     
    28082931}
    28092932
    2810 int QDynamicListViewBase::itemIndex(const QListViewItem &item) const
     2933int QIconModeViewBase::itemIndex(const QListViewItem &item) const
    28112934{
    28122935    if (!item.isValid())
     
    28442967}
    28452968
    2846 void QDynamicListViewBase::addLeaf(QVector<int> &leaf, const QRect &area,
    2847                                uint visited, QBspTree::Data data)
     2969void QIconModeViewBase::addLeaf(QVector<int> &leaf, const QRect &area,
     2970                                   uint visited, QBspTree::Data data)
    28482971{
    28492972    QListViewItem *vi;
    2850     QListViewPrivate *_this = static_cast<QListViewPrivate *>(data.ptr);
     2973    QIconModeViewBase *_this = static_cast<QIconModeViewBase *>(data.ptr);
    28512974    for (int i = 0; i < leaf.count(); ++i) {
    28522975        int idx = leaf.at(i);
    2853         if (idx < 0 || idx >= _this->dynamicListView->items.count())
     2976        if (idx < 0 || idx >= _this->items.count())
    28542977            continue;
    2855         vi = &_this->dynamicListView->items[idx];
     2978        vi = &_this->items[idx];
    28562979        Q_ASSERT(vi);
    28572980        if (vi->isValid() && vi->rect().intersects(area) && vi->visited != visited) {
    2858             QModelIndex index = _this->listViewItemToIndex(*vi);
     2981            QModelIndex index  = _this->dd->listViewItemToIndex(*vi);
    28592982            Q_ASSERT(index.isValid());
    2860             _this->intersectVector.append(index);
     2983            _this->interSectingVector->append(index);
    28612984            vi->visited = visited;
    28622985        }
     
    28642987}
    28652988
    2866 void QDynamicListViewBase::insertItem(int index)
    2867 {
    2868     if (index >= 0 && index < items.count())
    2869         tree.insertLeaf(items.at(index).rect(), index);
    2870 }
    2871 
    2872 void QDynamicListViewBase::removeItem(int index)
    2873 {
    2874     if (index >= 0 && index < items.count())
    2875         tree.removeLeaf(items.at(index).rect(), index);
    2876 }
    2877 
    2878 void QDynamicListViewBase::moveItem(int index, const QPoint &dest)
     2989void QIconModeViewBase::moveItem(int index, const QPoint &dest)
    28792990{
    28802991    // does not impact on the bintree itself or the contents rect
     
    28963007}
    28973008
    2898 QPoint QDynamicListViewBase::snapToGrid(const QPoint &pos) const
     3009QPoint QIconModeViewBase::snapToGrid(const QPoint &pos) const
    28993010{
    29003011    int x = pos.x() - (pos.x() % gridSize().width());
     
    29033014}
    29043015
    2905 QPoint QDynamicListViewBase::draggedItemsDelta() const
     3016QPoint QIconModeViewBase::draggedItemsDelta() const
    29063017{
    29073018    if (movement() == QListView::Snap) {
     
    29133024}
    29143025
    2915 QRect QDynamicListViewBase::draggedItemsRect() const
     3026QRect QIconModeViewBase::draggedItemsRect() const
    29163027{
    29173028    QRect rect = itemsRect(draggedItems);
     
    29323043}
    29333044
    2934 void QDynamicListViewBase::clear()
     3045void QIconModeViewBase::clear()
    29353046{
    29363047    tree.destroy();
     
    29413052}
    29423053
    2943 void QDynamicListViewBase::updateContentsSize()
     3054void QIconModeViewBase::updateContentsSize()
    29443055{
    29453056    QRect bounding;
     
    29943105    d->executePostedLayout();
    29953106    QListViewItem itm = d->indexToListViewItem(index);
    2996     return d->itemIndex(itm);
     3107    return d->commonListView->itemIndex(itm);
    29973108}
    29983109
  • trunk/src/gui/itemviews/qlistview.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qlistview_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6868{
    6969    friend class QListViewPrivate;
    70     friend class QStaticListViewBase;
    71     friend class QDynamicListViewBase;
     70    friend class QListModeViewBase;
     71    friend class QIconModeViewBase;
    7272public:
    7373    inline QListViewItem()
     
    8585        { return !(*this == other); }
    8686    inline bool isValid() const
    87         { return (x > -1) && (y > -1) && (w > 0) && (h > 0) && (indexHint > -1); }
     87        { return rect().isValid() && (indexHint > -1); }
    8888    inline void invalidate()
    8989        { x = -1; y = -1; w = 0; h = 0; }
     
    121121{
    122122public:
    123     inline QCommonListViewBase(QListView *q, QListViewPrivate *d) : dd(d), qq(q) {}
    124 
     123    inline QCommonListViewBase(QListView *q, QListViewPrivate *d) : dd(d), qq(q), batchStartRow(0), batchSavedDeltaSeg(0) {}
     124    virtual ~QCommonListViewBase() {}
     125
     126    //common interface
     127    virtual int itemIndex(const QListViewItem &item) const = 0;
     128    virtual QListViewItem indexToListViewItem(const QModelIndex &index) const = 0;
     129    virtual bool doBatchedItemLayout(const QListViewLayoutInfo &info, int max) = 0;
     130    virtual void clear() = 0;
     131    virtual void setRowCount(int) = 0;
     132    virtual QVector<QModelIndex> intersectingSet(const QRect &area) const = 0;
     133    virtual void dataChanged(const QModelIndex &, const QModelIndex &) = 0;
     134
     135    virtual int horizontalScrollToValue(int index, QListView::ScrollHint hint,
     136        bool leftOf, bool rightOf, const QRect &area, const QRect &rect) const;
     137    virtual int verticalScrollToValue(int index, QListView::ScrollHint hint,
     138        bool above, bool below, const QRect &area, const QRect &rect) const;
     139    virtual void scrollContentsBy(int dx, int dy, bool scrollElasticBand);
     140    virtual QRect mapToViewport(const QRect &rect) const {return rect;}
     141    virtual int horizontalOffset() const;
     142    virtual int verticalOffset() const { return verticalScrollBar()->value(); }
     143    virtual void updateHorizontalScrollBar(const QSize &step);
     144    virtual void updateVerticalScrollBar(const QSize &step);
     145    virtual void appendHiddenRow(int row);
     146    virtual void removeHiddenRow(int row);
     147    virtual void setPositionForIndex(const QPoint &, const QModelIndex &) { }
     148
     149#ifndef QT_NO_DRAGANDDROP
     150    virtual void paintDragDrop(QPainter *painter) = 0;
     151    virtual bool filterDragMoveEvent(QDragMoveEvent *) { return false; }
     152    virtual bool filterDragLeaveEvent(QDragLeaveEvent *) { return false; }
     153    virtual bool filterDropEvent(QDropEvent *) { return false; }
     154    virtual bool filterStartDrag(Qt::DropActions) { return false; }
     155#endif
     156
     157
     158    //other inline members
    125159    inline int spacing() const;
    126160    inline bool isWrapping() const;
     
    134168    inline int column() const;
    135169
    136     inline int verticalScrollBarValue() const;
    137     inline int horizontalScrollBarValue() const;
     170    inline QScrollBar *verticalScrollBar() const;
     171    inline QScrollBar *horizontalScrollBar() const;
    138172    inline QListView::ScrollMode verticalScrollMode() const;
    139173    inline QListView::ScrollMode horizontalScrollMode() const;
     
    154188    inline int hiddenCount() const;
    155189
    156     inline void clearIntersections() const;
    157     inline void appendToIntersections(const QModelIndex &idx) const;
    158 
    159190    inline bool isRightToLeft() const;
    160191
    161192    QListViewPrivate *dd;
    162193    QListView *qq;
    163 };
    164 
    165 // ### rename to QListModeViewBase
    166 class QStaticListViewBase : public QCommonListViewBase
    167 {
    168     friend class QListViewPrivate;
     194    QSize contentsSize;
     195    int batchStartRow;
     196    int batchSavedDeltaSeg;
     197};
     198
     199class QListModeViewBase : public QCommonListViewBase
     200{
    169201public:
    170     QStaticListViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d),
    171         batchStartRow(0), batchSavedDeltaSeg(0), batchSavedPosition(0) {}
     202    QListModeViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d) {}
    172203
    173204    QVector<int> flowPositions;
     
    175206    QVector<int> segmentStartRows;
    176207    QVector<int> segmentExtents;
    177 
    178     QSize contentsSize;
     208    QVector<int> scrollValueMap;
    179209
    180210    // used when laying out in batches
    181     int batchStartRow;
    182     int batchSavedDeltaSeg;
    183211    int batchSavedPosition;
    184212
     213    //reimplementations
     214    int itemIndex(const QListViewItem &item) const { return item.indexHint; }
     215    QListViewItem indexToListViewItem(const QModelIndex &index) const;
    185216    bool doBatchedItemLayout(const QListViewLayoutInfo &info, int max);
    186 
     217    void clear();
     218    void setRowCount(int rowCount) { flowPositions.resize(rowCount); }
     219    QVector<QModelIndex> intersectingSet(const QRect &area) const;
     220    void dataChanged(const QModelIndex &, const QModelIndex &);
     221
     222    int horizontalScrollToValue(int index, QListView::ScrollHint hint,
     223        bool leftOf, bool rightOf,const QRect &area, const QRect &rect) const;
     224    int verticalScrollToValue(int index, QListView::ScrollHint hint,
     225        bool above, bool below, const QRect &area, const QRect &rect) const;
     226    void scrollContentsBy(int dx, int dy, bool scrollElasticBand);
     227    QRect mapToViewport(const QRect &rect) const;
     228    int horizontalOffset() const;
     229    int verticalOffset() const;
     230    void updateHorizontalScrollBar(const QSize &step);
     231    void updateVerticalScrollBar(const QSize &step);
     232
     233#ifndef QT_NO_DRAGANDDROP
     234    void paintDragDrop(QPainter *painter);
     235
     236    // The next two methods are to be used on LefToRight flow only.
     237    // WARNING: Plenty of duplicated code from QAbstractItemView{,Private}.
     238    QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
     239    void dragMoveEvent(QDragMoveEvent *e);
     240#endif
     241
     242private:
    187243    QPoint initStaticLayout(const QListViewLayoutInfo &info);
    188244    void doStaticLayout(const QListViewLayoutInfo &info);
    189     void intersectingStaticSet(const QRect &area) const;
    190 
    191     int itemIndex(const QListViewItem &item) const;
    192 
    193     int perItemScrollingPageSteps(int length, int bounds, bool wrap) const;
    194 
    195245    int perItemScrollToValue(int index, int value, int height,
    196246                             QAbstractItemView::ScrollHint hint,
    197247                             Qt::Orientation orientation, bool wrap, int extent) const;
    198 
    199     QRect mapToViewport(const QRect &rect) const;
    200 
    201     QListViewItem indexToListViewItem(const QModelIndex &index) const;
    202 
    203     void scrollContentsBy(int &dx, int &dy);
    204 
    205     int verticalPerItemValue(int itemIndex, int verticalValue, int areaHeight,
    206                        bool above, bool below, bool wrap, QListView::ScrollHint hint, int itemHeight) const;
    207     int horizontalPerItemValue(int itemIndex, int horizontalValue, int areaWidth,
    208                        bool leftOf, bool rightOf, bool wrap, QListView::ScrollHint hint, int itemWidth) const;
    209 
    210     void clear();
    211 };
    212 
    213 // ### rename to QIconModeViewBase
    214 class QDynamicListViewBase : public QCommonListViewBase
    215 {
    216     friend class QListViewPrivate;
     248    int perItemScrollingPageSteps(int length, int bounds, bool wrap) const;
     249};
     250
     251class QIconModeViewBase : public QCommonListViewBase
     252{
    217253public:
    218     QDynamicListViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d),
    219         batchStartRow(0), batchSavedDeltaSeg(0) {}
     254    QIconModeViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d), interSectingVector(0) {}
    220255
    221256    QBspTree tree;
     
    223258    QBitArray moved;
    224259
    225     QSize contentsSize;
    226 
    227260    QVector<QModelIndex> draggedItems; // indices to the tree.itemVector
    228261    mutable QPoint draggedItemsPos;
    229262
    230263    // used when laying out in batches
    231     int batchStartRow;
    232     int batchSavedDeltaSeg;
    233 
     264    QVector<QModelIndex> *interSectingVector; //used from within intersectingSet
     265
     266    //reimplementations
     267    int itemIndex(const QListViewItem &item) const;
     268    QListViewItem indexToListViewItem(const QModelIndex &index) const;
     269    bool doBatchedItemLayout(const QListViewLayoutInfo &info, int max);
     270    void clear();
     271    void setRowCount(int rowCount);
     272    QVector<QModelIndex> intersectingSet(const QRect &area) const;
     273
     274    void scrollContentsBy(int dx, int dy, bool scrollElasticBand);
    234275    void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
    235     bool doBatchedItemLayout(const QListViewLayoutInfo &info, int max);
    236 
     276    void appendHiddenRow(int row);
     277    void removeHiddenRow(int row);
     278    void setPositionForIndex(const QPoint &position, const QModelIndex &index);
     279
     280#ifndef QT_NO_DRAGANDDROP
     281    void paintDragDrop(QPainter *painter);
     282    bool filterDragMoveEvent(QDragMoveEvent *);
     283    bool filterDragLeaveEvent(QDragLeaveEvent *);
     284    bool filterDropEvent(QDropEvent *e);
     285    bool filterStartDrag(Qt::DropActions);
     286#endif
     287
     288private:
    237289    void initBspTree(const QSize &contents);
    238290    QPoint initDynamicLayout(const QListViewLayoutInfo &info);
    239291    void doDynamicLayout(const QListViewLayoutInfo &info);
    240     void intersectingDynamicSet(const QRect &area) const;
    241 
    242292    static void addLeaf(QVector<int> &leaf, const QRect &area,
    243293                        uint visited, QBspTree::Data data);
    244 
    245     void insertItem(int index);
    246     void removeItem(int index);
     294    QRect itemsRect(const QVector<QModelIndex> &indexes) const;
     295    QRect draggedItemsRect() const;
     296    QPoint snapToGrid(const QPoint &pos) const;
     297    void updateContentsSize();
     298    QPoint draggedItemsDelta() const;
     299    void drawItems(QPainter *painter, const QVector<QModelIndex> &indexes) const;
    247300    void moveItem(int index, const QPoint &dest);
    248301
    249     int itemIndex(const QListViewItem &item) const;
    250 
    251     void createItems(int to);
    252     void drawItems(QPainter *painter, const QVector<QModelIndex> &indexes) const;
    253     QRect itemsRect(const QVector<QModelIndex> &indexes) const;
    254 
    255     QPoint draggedItemsDelta() const;
    256     QRect draggedItemsRect() const;
    257 
    258     QPoint snapToGrid(const QPoint &pos) const;
    259 
    260     void scrollElasticBandBy(int dx, int dy);
    261 
    262     QListViewItem indexToListViewItem(const QModelIndex &index) const;
    263 
    264     void clear();
    265     void updateContentsSize();
    266302};
    267303
     
    278314    bool doItemsLayout(int num);
    279315
    280     inline void intersectingSet(const QRect &area, bool doLayout = true) const {
     316    inline QVector<QModelIndex> intersectingSet(const QRect &area, bool doLayout = true) const {
    281317        if (doLayout) executePostedLayout();
    282318        QRect a = (q_func()->isRightToLeft() ? flipX(area.normalized()) : area.normalized());
    283         if (viewMode == QListView::ListMode) staticListView->intersectingStaticSet(a);
    284         else dynamicListView->intersectingDynamicSet(a);
     319        return commonListView->intersectingSet(a);
    285320    }
    286321
    287     // ### FIXME:
    288     inline void resetBatchStartRow()
    289         { if (viewMode == QListView::ListMode) staticListView->batchStartRow = 0;
    290               else dynamicListView->batchStartRow = 0; }
    291     inline int batchStartRow() const
    292         { return (viewMode == QListView::ListMode
    293           ? staticListView->batchStartRow : dynamicListView->batchStartRow); }
    294     inline QSize contentsSize() const
    295         { return (viewMode == QListView::ListMode
    296           ? staticListView->contentsSize : dynamicListView->contentsSize); }
    297     inline void setContentsSize(int w, int h)
    298         { if (viewMode == QListView::ListMode) staticListView->contentsSize = QSize(w, h);
    299           else dynamicListView->contentsSize = QSize(w, h); }
     322    inline void resetBatchStartRow() { commonListView->batchStartRow = 0; }
     323    inline int batchStartRow() const { return commonListView->batchStartRow; }
     324    inline QSize contentsSize() const { return commonListView->contentsSize; }
     325    inline void setContentsSize(int w, int h) { commonListView->contentsSize = QSize(w, h); }
    300326
    301327    inline int flipX(int x) const
     
    308334        { if (q_func()->isRightToLeft()) return flipX(item.rect()); return item.rect(); }
    309335
    310     int itemIndex(const QListViewItem &item) const;
    311336    QListViewItem indexToListViewItem(const QModelIndex &index) const;
    312337    inline QModelIndex listViewItemToIndex(const QListViewItem &item) const
    313         { return model->index(itemIndex(item), column, root); }
    314 
    315     QRect mapToViewport(const QRect &rect, bool greedy = false) const;
     338        { return model->index(commonListView->itemIndex(item), column, root); }
     339
     340    QRect rectForIndex(const QModelIndex &index) const
     341    {
     342        if (!isIndexValid(index) || index.parent() != root || index.column() != column || isHidden(index.row()))
     343            return QRect();
     344        executePostedLayout();
     345        return viewItemRect(indexToListViewItem(index));
     346    }
     347
     348    void viewUpdateGeometries() { q_func()->updateGeometries(); }
     349
     350
     351    QRect mapToViewport(const QRect &rect, bool extend = true) const;
    316352
    317353    QModelIndex closestIndex(const QRect &target, const QVector<QModelIndex> &candidates) const;
     
    326362    QItemSelection selection(const QRect &rect) const;
    327363    void selectAll(QItemSelectionModel::SelectionFlags command);
     364
     365#ifndef QT_NO_DRAGANDDROP
     366    virtual QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
     367#endif
    328368
    329369    inline void setGridSize(const QSize &size) { grid = size; }
     
    352392    void scrollElasticBandBy(int dx, int dy);
    353393
    354     // ### FIXME: we only need one at a time
    355     QDynamicListViewBase *dynamicListView;
    356     QStaticListViewBase *staticListView;
     394    QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const;
     395
     396    void emitIndexesMoved(const QModelIndexList &indexes) { emit q_func()->indexesMoved(indexes); }
     397
     398
     399    QCommonListViewBase *commonListView;
    357400
    358401    // ### FIXME: see if we can move the members into the dynamic/static classes
     
    384427    QRect layoutBounds;
    385428
    386     // used for intersecting set
    387     mutable QVector<QModelIndex> intersectVector;
    388 
    389429    // timers
    390430    QBasicTimer batchLayoutTimer;
     
    415455inline int QCommonListViewBase::column() const { return dd->column; }
    416456
    417 inline int QCommonListViewBase::verticalScrollBarValue() const { return qq->verticalScrollBar()->value(); }
    418 inline int QCommonListViewBase::horizontalScrollBarValue() const { return qq->horizontalScrollBar()->value(); }
     457inline QScrollBar *QCommonListViewBase::verticalScrollBar() const { return qq->verticalScrollBar(); }
     458inline QScrollBar *QCommonListViewBase::horizontalScrollBar() const { return qq->horizontalScrollBar(); }
    419459inline QListView::ScrollMode QCommonListViewBase::verticalScrollMode() const { return qq->verticalScrollMode(); }
    420460inline QListView::ScrollMode QCommonListViewBase::horizontalScrollMode() const { return qq->horizontalScrollMode(); }
     
    439479inline int QCommonListViewBase::hiddenCount() const { return dd->hiddenRows.count(); }
    440480
    441 inline void QCommonListViewBase::clearIntersections() const { dd->intersectVector.clear(); }
    442 inline void QCommonListViewBase::appendToIntersections(const QModelIndex &idx) const { dd->intersectVector.append(idx); }
    443 
    444481inline bool QCommonListViewBase::isRightToLeft() const { return qq->isRightToLeft(); }
    445482
  • trunk/src/gui/itemviews/qlistwidget.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    168168    endRemoveRows();
    169169    return item;
     170}
     171
     172void QListModel::move(int srcRow, int dstRow)
     173{
     174    if (srcRow == dstRow
     175        || srcRow < 0 || srcRow >= items.count()
     176        || dstRow < 0 || dstRow > items.count())
     177        return;
     178
     179    if (!beginMoveRows(QModelIndex(), srcRow, srcRow, QModelIndex(), dstRow))
     180        return;
     181    if (srcRow < dstRow)
     182        --dstRow;
     183    items.move(srcRow, dstRow);
     184    endMoveRows();
    170185}
    171186
     
    448463    \ingroup model-view
    449464
    450     QListWidgetItem is used to represent items in a list provided by the
    451     QListWidget class. Each item can hold several pieces of information,
    452     and will display these appropriately.
    453 
    454     The item view convenience classes use a classic item-based interface
    455     rather than a pure model/view approach. For a more flexible list view
    456     widget, consider using the QListView class with a standard model.
    457 
    458     List items can be automatically inserted into a list when they are
    459     constructed by specifying the list widget:
     465    A QListWidgetItem represents a single item in a QListWidget. Each item can
     466    hold several pieces of information, and will display them appropriately.
     467
     468    The item view convenience classes use a classic item-based interface rather
     469    than a pure model/view approach. For a more flexible list view widget,
     470    consider using the QListView class with a standard model.
     471
     472    List items can be inserted automatically into a list, when they are
     473    constructed, by specifying the list widget:
    460474
    461475    \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 2
    462476
    463     They can also be created without a parent widget, and later inserted into
    464     a list (see \l{QListWidget::insertItem()}).
     477    Alternatively, list items can also be created without a parent widget, and
     478    later inserted into a list using QListWidget::insertItem().
    465479
    466480    List items are typically used to display text() and an icon(). These are
     
    472486
    473487    By default, items are enabled, selectable, checkable, and can be the source
    474     of a drag and drop operation.
     488    of drag and drop operations.
     489
    475490    Each item's flags can be changed by calling setFlags() with the appropriate
    476     value (see \l{Qt::ItemFlags}). Checkable items can be checked, unchecked and
     491    value (see Qt::ItemFlags). Checkable items can be checked, unchecked and
    477492    partially checked with the setCheckState() function. The corresponding
    478     checkState() function indicates what check state the item currently has.
    479 
    480     The isHidden() function can be used to determine whether the
    481     item is hidden.  Items can be hidden with setHidden().
     493    checkState() function indicates the item's current check state.
     494
     495    The isHidden() function can be used to determine whether the item is
     496    hidden. To hide an item, use setHidden().
     497
    482498
    483499    \section1 Subclassing
    484500
    485501    When subclassing QListWidgetItem to provide custom items, it is possible to
    486     define new types for them so that they can be distinguished from standard
    487     items. The constructors for subclasses that require this feature need to
    488     call the base class constructor with a new type value equal to or greater
    489     than \l UserType.
     502    define new types for them enabling them to be distinguished from standard
     503    items. For subclasses that require this feature, ensure that you call the
     504    base class constructor with a new type value equal to or greater than
     505    \l UserType, within \e your constructor.
    490506
    491507    \sa QListWidget, {Model/View Programming}, QTreeWidgetItem, QTableWidgetItem
     
    516532    \fn QListWidget *QListWidgetItem::listWidget() const
    517533
    518     Returns the list widget that contains the item.
    519 */
    520 
    521 /*!
    522   \fn void QListWidgetItem::setSelected(bool select)
    523   \since 4.2
    524 
    525   Sets the selected state of the item to \a select.
    526 
    527   \sa isSelected()
    528 */
    529 
    530 /*!
    531   \fn bool QListWidgetItem::isSelected() const
    532   \since 4.2
    533 
    534   Returns true if the item is selected, otherwise returns false.
    535 
    536   \sa setSelected()
    537 */
    538 
    539 /*!
    540   \fn void QListWidgetItem::setHidden(bool hide)
    541   \since 4.2
    542 
    543   Hides the item if \a hide is true, otherwise shows the item.
    544 
    545   \sa isHidden()
    546 */
    547 
    548 /*!
    549   \fn bool QListWidgetItem::isHidden() const
    550   \since 4.2
    551 
    552   Returns true if the item is hidden, otherwise returns false.
    553 
    554   \sa setHidden()
     534    Returns the list widget containing the item.
     535*/
     536
     537/*!
     538    \fn void QListWidgetItem::setSelected(bool select)
     539    \since 4.2
     540
     541    Sets the selected state of the item to \a select.
     542
     543    \sa isSelected()
     544*/
     545
     546/*!
     547    \fn bool QListWidgetItem::isSelected() const
     548    \since 4.2
     549
     550    Returns true if the item is selected; otherwise returns false.
     551
     552    \sa setSelected()
     553*/
     554
     555/*!
     556    \fn void QListWidgetItem::setHidden(bool hide)
     557    \since 4.2
     558
     559    Hides the item if \a hide is true; otherwise shows the item.
     560
     561    \sa isHidden()
     562*/
     563
     564/*!
     565    \fn bool QListWidgetItem::isHidden() const
     566    \since 4.2
     567
     568    Returns true if the item is hidden; otherwise returns false.
     569
     570    \sa setHidden()
    555571*/
    556572
     
    559575
    560576    Constructs an empty list widget item of the specified \a type with the
    561     given \a parent.
    562     If the parent is not specified, the item will need to be inserted into a
    563     list widget with QListWidget::insertItem().
     577    given \a parent. If \a parent is not specified, the item will need to be
     578    inserted into a list widget with QListWidget::insertItem().
     579
     580    This constructor inserts the item into the model of the parent that is
     581    passed to the constructor. If the model is sorted then the behavior of the
     582    insert is undetermined since the model will call the \c '<' operator method
     583    on the item which, at this point, is not yet constructed. To avoid the
     584    undetermined behavior, we recommend not to specify the parent and use
     585    QListWidget::insertItem() instead.
    564586
    565587    \sa type()
     
    580602
    581603    Constructs an empty list widget item of the specified \a type with the
    582     given \a text and \a parent.
    583     If the parent is not specified, the item will need to be inserted into a
    584     list widget with QListWidget::insertItem().
     604    given \a text and \a parent. If the parent is not specified, the item will
     605    need to be inserted into a list widget with QListWidget::insertItem().
     606
     607    This constructor inserts the item into the model of the parent that is
     608    passed to the constructor. If the model is sorted then the behavior of the
     609    insert is undetermined since the model will call the \c '<' operator method
     610    on the item which, at this point, is not yet constructed. To avoid the
     611    undetermined behavior, we recommend not to specify the parent and use
     612    QListWidget::insertItem() instead.
    585613
    586614    \sa type()
     
    603631
    604632    Constructs an empty list widget item of the specified \a type with the
    605     given \a icon, \a text and \a parent.
    606     If the parent is not specified, the item will need to be inserted into a
    607     list widget with QListWidget::insertItem().
     633    given \a icon, \a text and \a parent. If the parent is not specified, the
     634    item will need to be inserted into a list widget with
     635    QListWidget::insertItem().
     636
     637    This constructor inserts the item into the model of the parent that is
     638    passed to the constructor. If the model is sorted then the behavior of the
     639    insert is undetermined since the model will call the \c '<' operator method
     640    on the item which, at this point, is not yet constructed. To avoid the
     641    undetermined behavior, we recommend not to specify the parent and use
     642    QListWidget::insertItem() instead.
    608643
    609644    \sa type()
     
    625660
    626661/*!
    627   Destroys the list item.
     662    Destroys the list item.
    628663*/
    629664QListWidgetItem::~QListWidgetItem()
     
    635670
    636671/*!
    637   Creates an exact copy of the item.
     672    Creates an exact copy of the item.
    638673*/
    639674QListWidgetItem *QListWidgetItem::clone() const
     
    643678
    644679/*!
    645   This function sets the data for a given \a role to the given \a value (see
    646   \l{Qt::ItemDataRole}). Reimplement this function if you need
    647   extra roles or special behavior for certain roles.
    648 
    649   \sa Qt::ItemDataRole, data()
     680    Sets the data for a given \a role to the given \a value. Reimplement this
     681    function if you need extra roles or special behavior for certain roles.
     682
     683    \sa Qt::ItemDataRole, data()
    650684*/
    651685void QListWidgetItem::setData(int role, const QVariant &value)
     
    669703
    670704/*!
    671    This function returns the item's data for a given \a role (see
    672    Qt::ItemDataRole). Reimplement this function if you need
    673    extra roles or special behavior for certain roles.
     705    Returns the item's data for a given \a role. Reimplement this function if
     706    you need extra roles or special behavior for certain roles.
     707
     708    \sa Qt::ItemDataRole, setData()
    674709*/
    675710QVariant QListWidgetItem::data(int role) const
     
    683718
    684719/*!
    685   Returns true if this item's text is less then \a other item's text;
    686   otherwise returns false.
     720    Returns true if this item's text is less then \a other item's text;
     721    otherwise returns false.
    687722*/
    688723bool QListWidgetItem::operator<(const QListWidgetItem &other) const
    689724{
    690     return text() < other.text();
     725    const QVariant v1 = data(Qt::DisplayRole), v2 = other.data(Qt::DisplayRole);
     726    return QAbstractItemModelPrivate::variantLessThan(v1, v2);
    691727}
    692728
     
    712748    out << d->values;
    713749}
     750#endif // QT_NO_DATASTREAM
    714751
    715752/*!
    716753    \since 4.1
    717754
    718     Constructs a copy of \a other. Note that type() and listWidget()
    719     are not copied.
     755    Constructs a copy of \a other. Note that type() and listWidget() are not
     756    copied.
    720757
    721758    This function is useful when reimplementing clone().
     
    732769
    733770/*!
    734     Assigns \a other's data and flags to this item. Note that type()
    735     and listWidget() are not copied.
     771    Assigns \a other's data and flags to this item. Note that type() and
     772    listWidget() are not copied.
    736773
    737774    This function is useful when reimplementing clone().
     
    746783}
    747784
     785#ifndef QT_NO_DATASTREAM
     786
    748787/*!
    749788    \relates QListWidgetItem
     
    779818
    780819/*!
    781   \fn Qt::ItemFlags QListWidgetItem::flags() const
    782 
    783   Returns the item flags for this item (see \l{Qt::ItemFlags}).
     820    \fn Qt::ItemFlags QListWidgetItem::flags() const
     821
     822    Returns the item flags for this item (see \l{Qt::ItemFlags}).
    784823*/
    785824
     
    825864
    826865/*!
    827   \fn QFont QListWidgetItem::font() const
    828 
    829   Returns the font used to display this list item's text.
    830 */
    831 
    832 /*!
    833   \fn int QListWidgetItem::textAlignment() const
    834 
    835   Returns the text alignment for the list item (see \l{Qt::AlignmentFlag}).
     866    \fn QFont QListWidgetItem::font() const
     867
     868    Returns the font used to display this list item's text.
     869*/
     870
     871/*!
     872    \fn int QListWidgetItem::textAlignment() const
     873
     874    Returns the text alignment for the list item.
     875
     876    \sa Qt::AlignmentFlag
    836877*/
    837878
     
    879920
    880921/*!
    881   \fn QSize QListWidgetItem::sizeHint() const
    882   \since 4.1
    883 
    884   Returns the size hint set for the list item.
    885 */
    886 
    887 /*!
    888   \fn void QListWidgetItem::setSizeHint(const QSize &size)
    889   \since 4.1
    890 
    891   Sets the size hint for the list item to be \a size.
    892   If no size hint is set, the item delegate will compute the
    893   size hint based on the item data.
    894 */
    895 
    896 /*!
    897   \fn void QListWidgetItem::setFlags(Qt::ItemFlags flags)
    898 
    899   Sets the item flags for the list item to \a flags (see
    900   \l{Qt::ItemFlags}).
     922    \fn QSize QListWidgetItem::sizeHint() const
     923    \since 4.1
     924
     925    Returns the size hint set for the list item.
     926*/
     927
     928/*!
     929    \fn void QListWidgetItem::setSizeHint(const QSize &size)
     930    \since 4.1
     931
     932    Sets the size hint for the list item to be \a size. If no size hint is set,
     933    the item delegate will compute the size hint based on the item data.
     934*/
     935
     936/*!
     937    \fn void QListWidgetItem::setFlags(Qt::ItemFlags flags)
     938
     939    Sets the item flags for the list item to \a flags.
     940
     941    \sa Qt::ItemFlags
    901942*/
    902943void QListWidgetItem::setFlags(Qt::ItemFlags aflags) {
     
    927968
    928969    Sets the status tip for the list item to the text specified by
    929     \a statusTip. QListWidget mouse tracking needs to be enabled for this
     970    \a statusTip. QListWidget mouseTracking needs to be enabled for this
    930971    feature to work.
    931972
    932     \sa statusTip() setToolTip() setWhatsThis()
     973    \sa statusTip(), setToolTip(), setWhatsThis(), QWidget::setMouseTracking()
    933974*/
    934975
     
    938979    Sets the tooltip for the list item to the text specified by \a toolTip.
    939980
    940     \sa toolTip() setStatusTip() setWhatsThis()
     981    \sa toolTip(), setStatusTip(), setWhatsThis()
    941982*/
    942983
     
    944985    \fn void QListWidgetItem::setWhatsThis(const QString &whatsThis)
    945986
    946     Sets the "What's This?" help for the list item to the text specified
    947     by \a whatsThis.
    948 
    949     \sa whatsThis() setStatusTip() setToolTip()
    950 */
    951 
    952 /*!
    953   \fn void QListWidgetItem::setFont(const QFont &font)
    954 
    955   Sets the font used when painting the item to the given \a font.
    956 */
    957 
    958 /*!
    959   \fn void QListWidgetItem::setTextAlignment(int alignment)
    960 
    961   Sets the list item's text alignment to \a alignment (see
    962   \l{Qt::AlignmentFlag}).
     987    Sets the "What's This?" help for the list item to the text specified by
     988    \a whatsThis.
     989
     990    \sa whatsThis(), setStatusTip(), setToolTip()
     991*/
     992
     993/*!
     994    \fn void QListWidgetItem::setFont(const QFont &font)
     995
     996    Sets the font used when painting the item to the given \a font.
     997*/
     998
     999/*!
     1000    \fn void QListWidgetItem::setTextAlignment(int alignment)
     1001
     1002    Sets the list item's text alignment to \a alignment.
     1003
     1004    \sa Qt::AlignmentFlag
    9631005*/
    9641006
     
    10151057                     q, SLOT(_q_emitItemActivated(QModelIndex)));
    10161058    QObject::connect(q, SIGNAL(entered(QModelIndex)), q, SLOT(_q_emitItemEntered(QModelIndex)));
    1017     QObject::connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
     1059    QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
    10181060                     q, SLOT(_q_emitItemChanged(QModelIndex)));
    10191061    QObject::connect(q->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
     
    10211063    QObject::connect(q->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
    10221064                     q, SIGNAL(itemSelectionChanged()));
    1023     QObject::connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
     1065    QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
    10241066                     q, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
    1025     QObject::connect(model(), SIGNAL(columnsRemoved(QModelIndex,int,int)), q, SLOT(_q_sort()));
     1067    QObject::connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)), q, SLOT(_q_sort()));
    10261068}
    10271069
     
    10291071{
    10301072    Q_Q(QListWidget);
    1031     emit q->itemPressed(model()->at(index.row()));
     1073    emit q->itemPressed(listModel()->at(index.row()));
    10321074}
    10331075
     
    10351077{
    10361078    Q_Q(QListWidget);
    1037     emit q->itemClicked(model()->at(index.row()));
     1079    emit q->itemClicked(listModel()->at(index.row()));
    10381080}
    10391081
     
    10411083{
    10421084    Q_Q(QListWidget);
    1043     emit q->itemDoubleClicked(model()->at(index.row()));
     1085    emit q->itemDoubleClicked(listModel()->at(index.row()));
    10441086}
    10451087
     
    10471089{
    10481090    Q_Q(QListWidget);
    1049     emit q->itemActivated(model()->at(index.row()));
     1091    emit q->itemActivated(listModel()->at(index.row()));
    10501092}
    10511093
     
    10531095{
    10541096    Q_Q(QListWidget);
    1055     emit q->itemEntered(model()->at(index.row()));
     1097    emit q->itemEntered(listModel()->at(index.row()));
    10561098}
    10571099
     
    10591101{
    10601102    Q_Q(QListWidget);
    1061     emit q->itemChanged(model()->at(index.row()));
     1103    emit q->itemChanged(listModel()->at(index.row()));
    10621104}
    10631105
     
    10671109    Q_Q(QListWidget);
    10681110    QPersistentModelIndex persistentCurrent = current;
    1069     QListWidgetItem *currentItem = model()->at(persistentCurrent.row());
    1070     emit q->currentItemChanged(currentItem, model()->at(previous.row()));
     1111    QListWidgetItem *currentItem = listModel()->at(persistentCurrent.row());
     1112    emit q->currentItemChanged(currentItem, listModel()->at(previous.row()));
    10711113
    10721114    //persistentCurrent is invalid if something changed the model in response
     
    10831125{
    10841126    if (sortingEnabled)
    1085         model()->sort(0, sortOrder);
     1127        model->sort(0, sortOrder);
    10861128}
    10871129
     
    10901132{
    10911133    if (sortingEnabled && topLeft.isValid() && bottomRight.isValid())
    1092         model()->ensureSorted(topLeft.column(), sortOrder,
     1134        listModel()->ensureSorted(topLeft.column(), sortOrder,
    10931135                              topLeft.row(), bottomRight.row());
    10941136}
     
    10991141
    11001142    \ingroup model-view
    1101     \mainclass
    1102 
    1103     QListWidget is a convenience class that provides a list view similar to
    1104     the one supplied by QListView, but with a classic item-based interface
    1105     for adding and removing items. QListWidget uses an internal model to
    1106     manage each QListWidgetItem in the list.
     1143
     1144
     1145    QListWidget is a convenience class that provides a list view similar to the
     1146    one supplied by QListView, but with a classic item-based interface for
     1147    adding and removing items. QListWidget uses an internal model to manage
     1148    each QListWidgetItem in the list.
    11071149
    11081150    For a more flexible list view widget, use the QListView class with a
     
    11191161
    11201162    There are two ways to add items to the list: they can be constructed with
    1121     the list widget as their parent widget, or they can be constructed with
    1122     no parent widget and added to the list later. If a list widget already
    1123     exists when the items are constructed, the first method is easier to use:
     1163    the list widget as their parent widget, or they can be constructed with no
     1164    parent widget and added to the list later. If a list widget already exists
     1165    when the items are constructed, the first method is easier to use:
    11241166
    11251167    \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 1
    11261168
    1127     If you need to insert a new item into the list at a particular position,
    1128     it is more required to construct the item without a parent widget and
    1129     use the insertItem() function to place it within the list.  The list
    1130     widget will take ownership of the item.
     1169    If you need to insert a new item into the list at a particular position, it
     1170    is more required to construct the item without a parent widget and use the
     1171    insertItem() function to place it within the list. The list widget will
     1172    take ownership of the item.
    11311173
    11321174    \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 6
    11331175    \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 7
    11341176
    1135     For multiple items, insertItems() can be used instead. The number of
    1136     items in the list is found with the count() function.
    1137     To remove items from the list, use takeItem().
     1177    For multiple items, insertItems() can be used instead. The number of items
     1178    in the list is found with the count() function. To remove items from the
     1179    list, use takeItem().
    11381180
    11391181    The current item in the list can be found with currentItem(), and changed
     
    11591201    \fn void QListWidget::addItem(QListWidgetItem *item)
    11601202
    1161     Inserts the \a item at the the end of the list widget.
    1162 
    1163     \warning A QListWidgetItem can only be added to a
    1164     QListWidget once. Adding the same QListWidgetItem multiple
    1165     times to a QListWidget will result in undefined behavior.
     1203    Inserts the \a item at the end of the list widget.
     1204
     1205    \warning A QListWidgetItem can only be added to a QListWidget once. Adding
     1206    the same QListWidgetItem multiple times to a QListWidget will result in
     1207    undefined behavior.
    11661208
    11671209    \sa insertItem()
     
    11711213    \fn void QListWidget::addItem(const QString &label)
    11721214
    1173     Inserts an item with the text \a label at the end of the list
    1174     widget.
     1215    Inserts an item with the text \a label at the end of the list widget.
    11751216*/
    11761217
     
    11861227    \fn void QListWidget::itemPressed(QListWidgetItem *item)
    11871228
    1188     This signal is emitted with the specified \a item when a mouse button is pressed
    1189     on an item in the widget.
     1229    This signal is emitted with the specified \a item when a mouse button is
     1230    pressed on an item in the widget.
    11901231
    11911232    \sa itemClicked(), itemDoubleClicked()
     
    11951236    \fn void QListWidget::itemClicked(QListWidgetItem *item)
    11961237
    1197     This signal is emitted with the specified \a item when a mouse button is clicked
    1198     on an item in the widget.
     1238    This signal is emitted with the specified \a item when a mouse button is
     1239    clicked on an item in the widget.
    11991240
    12001241    \sa itemPressed(), itemDoubleClicked()
     
    12041245    \fn void QListWidget::itemDoubleClicked(QListWidgetItem *item)
    12051246
    1206     This signal is emitted with the specified \a item when a mouse button is double
    1207     clicked on an item in the widget.
     1247    This signal is emitted with the specified \a item when a mouse button is
     1248    double clicked on an item in the widget.
    12081249
    12091250    \sa itemClicked(), itemPressed()
     
    12131254    \fn void QListWidget::itemActivated(QListWidgetItem *item)
    12141255
    1215     This signal is emitted when the \a item is activated. The \a item
    1216     is activated when the user clicks or double clicks on it,
    1217     depending on the system configuration. It is also activated when
    1218     the user presses the activation key (on Windows and X11 this is
    1219     the \gui Return key, on Mac OS X it is \key{Ctrl+0}).
     1256    This signal is emitted when the \a item is activated. The \a item is
     1257    activated when the user clicks or double clicks on it, depending on the
     1258    system configuration. It is also activated when the user presses the
     1259    activation key (on Windows and X11 this is the \gui Return key, on Mac OS
     1260    X it is \key{Ctrl+0}).
    12201261*/
    12211262
     
    12231264    \fn void QListWidget::itemEntered(QListWidgetItem *item)
    12241265
    1225     This signal is emitted when the mouse cursor enters an item. The
    1226     \a item is the item entered. This signal is only emitted when
    1227     mouseTracking is turned on, or when a mouse button is pressed
    1228     while moving into an item.
     1266    This signal is emitted when the mouse cursor enters an item. The \a item is
     1267    the item entered. This signal is only emitted when mouseTracking is turned
     1268    on, or when a mouse button is pressed while moving into an item.
     1269
     1270    \sa QWidget::setMouseTracking()
    12291271*/
    12301272
     
    12381280    \fn void QListWidget::currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
    12391281
    1240     This signal is emitted whenever the current item changes. The \a
    1241     previous item is the item that previously had the focus, \a
    1242     current is the new current item.
    1243 */
    1244 
    1245 /*!
    1246   \fn void QListWidget::currentTextChanged(const QString &currentText)
    1247 
    1248   This signal is emitted whenever the current item changes. The \a currentText
    1249   is the text data in the current item. If there is no current item, the \a currentText
    1250   is invalid.
    1251 */
    1252 
    1253 /*!
    1254   \fn void QListWidget::currentRowChanged(int currentRow)
    1255 
    1256   This signal is emitted whenever the current item changes. The \a currentRow
    1257   is the row of the current item. If there is no current item, the \a currentRow is -1.
     1282    This signal is emitted whenever the current item changes.
     1283
     1284    \a previous is the item that previously had the focus; \a current is the
     1285    new current item.
     1286*/
     1287
     1288/*!
     1289    \fn void QListWidget::currentTextChanged(const QString &currentText)
     1290
     1291    This signal is emitted whenever the current item changes.
     1292
     1293    \a currentText is the text data in the current item. If there is no current
     1294    item, the \a currentText is invalid.
     1295*/
     1296
     1297/*!
     1298    \fn void QListWidget::currentRowChanged(int currentRow)
     1299
     1300    This signal is emitted whenever the current item changes.
     1301
     1302    \a currentRow is the row of the current item. If there is no current item,
     1303    the \a currentRow is -1.
    12581304*/
    12591305
     
    12631309    This signal is emitted whenever the selection changes.
    12641310
    1265     \sa selectedItems() isItemSelected() currentItemChanged()
    1266 */
    1267 
    1268 /*!
    1269   \since 4.3
    1270 
    1271   \fn void QListWidget::removeItemWidget(QListWidgetItem *item)
    1272 
    1273   Removes the widget set on the given \a item.
     1311    \sa selectedItems(), QListWidgetItem::isSelected(), currentItemChanged()
     1312*/
     1313
     1314/*!
     1315    \since 4.3
     1316
     1317    \fn void QListWidget::removeItemWidget(QListWidgetItem *item)
     1318
     1319    Removes the widget set on the given \a item.
    12741320*/
    12751321
     
    13031349{
    13041350    Q_D(const QListWidget);
    1305     if (row < 0 || row >= d->model()->rowCount())
     1351    if (row < 0 || row >= d->model->rowCount())
    13061352        return 0;
    1307     return d->model()->at(row);
     1353    return d->listModel()->at(row);
    13081354}
    13091355
     
    13171363{
    13181364    Q_D(const QListWidget);
    1319     return d->model()->index(const_cast<QListWidgetItem*>(item)).row();
     1365    return d->listModel()->index(const_cast<QListWidgetItem*>(item)).row();
    13201366}
    13211367
     
    13311377    Q_D(QListWidget);
    13321378    if (item && !item->view)
    1333         d->model()->insert(row, item);
    1334 }
    1335 
    1336 /*!
    1337     Inserts an item with the text \a label in the list widget at the
    1338     position given by \a row.
     1379        d->listModel()->insert(row, item);
     1380}
     1381
     1382/*!
     1383    Inserts an item with the text \a label in the list widget at the position
     1384    given by \a row.
    13391385
    13401386    \sa addItem()
     
    13441390{
    13451391    Q_D(QListWidget);
    1346     d->model()->insert(row, new QListWidgetItem(label));
     1392    d->listModel()->insert(row, new QListWidgetItem(label));
    13471393}
    13481394
     
    13571403{
    13581404    Q_D(QListWidget);
    1359     d->model()->insert(row, labels);
    1360 }
    1361 
    1362 /*!
    1363     Removes and returns the item from the given \a row in the list widget; otherwise
    1364     returns 0.
    1365 
    1366     Items removed from a list widget will not be managed by Qt, and will need to be
    1367     deleted manually.
     1405    d->listModel()->insert(row, labels);
     1406}
     1407
     1408/*!
     1409    Removes and returns the item from the given \a row in the list widget;
     1410    otherwise returns 0.
     1411
     1412    Items removed from a list widget will not be managed by Qt, and will need
     1413    to be deleted manually.
    13681414
    13691415    \sa insertItem(), addItem()
     
    13731419{
    13741420    Q_D(QListWidget);
    1375     if (row < 0 || row >= d->model()->rowCount())
     1421    if (row < 0 || row >= d->model->rowCount())
    13761422        return 0;
    1377     return d->model()->take(row);
    1378 }
    1379 
    1380 /*!
    1381   \property QListWidget::count
    1382   \brief the number of items in the list including any hidden items.
     1423    return d->listModel()->take(row);
     1424}
     1425
     1426/*!
     1427    \property QListWidget::count
     1428    \brief the number of items in the list including any hidden items.
    13831429*/
    13841430
     
    13861432{
    13871433    Q_D(const QListWidget);
    1388     return d->model()->rowCount();
    1389 }
    1390 
    1391 /*!
    1392   Returns the current item.
     1434    return d->model->rowCount();
     1435}
     1436
     1437/*!
     1438    Returns the current item.
    13931439*/
    13941440QListWidgetItem *QListWidget::currentItem() const
    13951441{
    13961442    Q_D(const QListWidget);
    1397     return d->model()->at(currentIndex().row());
    1398 }
    1399 
    1400 
    1401 /*!
    1402   Sets the current item to \a item.
    1403 
    1404   Depending on the current selection mode, the item may also be selected.
     1443    return d->listModel()->at(currentIndex().row());
     1444}
     1445
     1446
     1447/*!
     1448    Sets the current item to \a item.
     1449
     1450    Unless the selection mode is \l{QAbstractItemView::}{NoSelection},
     1451    the item is also be selected.
    14051452*/
    14061453void QListWidget::setCurrentItem(QListWidgetItem *item)
     
    14101457
    14111458/*!
    1412   \since 4.4
    1413   Set the current item to \a item, using the given \a command.
     1459    \since 4.4
     1460    Set the current item to \a item, using the given \a command.
    14141461*/
    14151462void QListWidget::setCurrentItem(QListWidgetItem *item, QItemSelectionModel::SelectionFlags command)
     
    14191466
    14201467/*!
    1421   \property QListWidget::currentRow
    1422   \brief the row of the current item.
    1423 
    1424   Depending on the current selection mode, the row may also be selected.
     1468    \property QListWidget::currentRow
     1469    \brief the row of the current item.
     1470
     1471    Depending on the current selection mode, the row may also be selected.
    14251472*/
    14261473
     
    14331480{
    14341481    Q_D(QListWidget);
    1435     QModelIndex index = d->model()->index(row);
     1482    QModelIndex index = d->listModel()->index(row);
    14361483    if (d->selectionMode == SingleSelection)
    14371484        selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
     
    14431490
    14441491/*!
    1445   \since 4.4
    1446 
    1447   Sets the current row to be the given \a row, using the given \a command,
     1492    \since 4.4
     1493
     1494    Sets the current row to be the given \a row, using the given \a command,
    14481495*/
    14491496void QListWidget::setCurrentRow(int row, QItemSelectionModel::SelectionFlags command)
    14501497{
    14511498    Q_D(QListWidget);
    1452     d->selectionModel->setCurrentIndex(d->model()->index(row), command);
     1499    d->selectionModel->setCurrentIndex(d->listModel()->index(row), command);
    14531500}
    14541501
     
    14591506{
    14601507    Q_D(const QListWidget);
    1461     return d->model()->at(indexAt(p).row());
     1508    return d->listModel()->at(indexAt(p).row());
    14621509
    14631510}
     
    14721519
    14731520/*!
    1474   Returns the rectangle on the viewport occupied by the item at \a item.
     1521    Returns the rectangle on the viewport occupied by the item at \a item.
    14751522*/
    14761523QRect QListWidget::visualItemRect(const QListWidgetItem *item) const
    14771524{
    14781525    Q_D(const QListWidget);
    1479     QModelIndex index = d->model()->index(const_cast<QListWidgetItem*>(item));
     1526    QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item));
    14801527    return visualRect(index);
    14811528}
    14821529
    14831530/*!
    1484   Sorts all the items in the list widget according to the specified \a order.
     1531    Sorts all the items in the list widget according to the specified \a order.
    14851532*/
    14861533void QListWidget::sortItems(Qt::SortOrder order)
     
    14881535    Q_D(QListWidget);
    14891536    d->sortOrder = order;
    1490     d->model()->sort(0, order);
     1537    d->listModel()->sort(0, order);
    14911538}
    14921539
     
    14961543    \brief whether sorting is enabled
    14971544
    1498     If this property is true, sorting is enabled for the list; if the
    1499     property is false, sorting is not enabled. The default value is false.
     1545    If this property is true, sorting is enabled for the list; if the property
     1546    is false, sorting is not enabled.
     1547
     1548    The default value is false.
    15001549*/
    15011550void QListWidget::setSortingEnabled(bool enable)
     
    15121561
    15131562/*!
    1514   \internal
     1563    \internal
    15151564*/
    15161565Qt::SortOrder QListWidget::sortOrder() const
     
    15211570
    15221571/*!
    1523   Starts editing the \a item if it is editable.
     1572    Starts editing the \a item if it is editable.
    15241573*/
    15251574
     
    15271576{
    15281577    Q_D(QListWidget);
    1529     edit(d->model()->index(item));
    1530 }
    1531 
    1532 /*!
    1533   Opens an editor for the given \a item. The editor remains open after editing.
    1534 
    1535   \sa closePersistentEditor()
     1578    edit(d->listModel()->index(item));
     1579}
     1580
     1581/*!
     1582    Opens an editor for the given \a item. The editor remains open after
     1583    editing.
     1584
     1585    \sa closePersistentEditor()
    15361586*/
    15371587void QListWidget::openPersistentEditor(QListWidgetItem *item)
    15381588{
    15391589    Q_D(QListWidget);
    1540     QModelIndex index = d->model()->index(item);
     1590    QModelIndex index = d->listModel()->index(item);
    15411591    QAbstractItemView::openPersistentEditor(index);
    15421592}
    15431593
    15441594/*!
    1545   Closes the persistent editor for the given \a item.
    1546 
    1547   \sa openPersistentEditor()
     1595    Closes the persistent editor for the given \a item.
     1596
     1597    \sa openPersistentEditor()
    15481598*/
    15491599void QListWidget::closePersistentEditor(QListWidgetItem *item)
    15501600{
    15511601    Q_D(QListWidget);
    1552     QModelIndex index = d->model()->index(item);
     1602    QModelIndex index = d->listModel()->index(item);
    15531603    QAbstractItemView::closePersistentEditor(index);
    15541604}
     
    15621612{
    15631613    Q_D(const QListWidget);
    1564     QModelIndex index = d->model()->index(item);
     1614    QModelIndex index = d->listModel()->index(item);
    15651615    return QAbstractItemView::indexWidget(index);
    15661616}
     
    15711621    Sets the \a widget to be displayed in the give \a item.
    15721622
    1573     This function should only be used to display static content in the place of a list
    1574     widget item. If you want to display custom dynamic content or implement a custom
    1575     editor widget, use QListView and subclass QItemDelegate instead.
     1623    This function should only be used to display static content in the place of
     1624    a list widget item. If you want to display custom dynamic content or
     1625    implement a custom editor widget, use QListView and subclass QItemDelegate
     1626    instead.
    15761627
    15771628    \sa {Delegate Classes}
     
    15801631{
    15811632    Q_D(QListWidget);
    1582     QModelIndex index = d->model()->index(item);
     1633    QModelIndex index = d->listModel()->index(item);
    15831634    QAbstractItemView::setIndexWidget(index, widget);
    15841635}
    15851636
    15861637/*!
    1587   Returns true if \a item is selected; otherwise returns false.
    1588 
    1589   \obsolete
    1590 
    1591   This function is deprecated. Use \l{QListWidgetItem::isSelected()} instead.
     1638    Returns true if \a item is selected; otherwise returns false.
     1639
     1640    \obsolete
     1641
     1642    This function is deprecated. Use QListWidgetItem::isSelected() instead.
    15921643*/
    15931644bool QListWidget::isItemSelected(const QListWidgetItem *item) const
    15941645{
    15951646    Q_D(const QListWidget);
    1596     QModelIndex index = d->model()->index(const_cast<QListWidgetItem*>(item));
     1647    QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item));
    15971648    return selectionModel()->isSelected(index);
    15981649}
    15991650
    16001651/*!
    1601   Selects or deselects the given \a item depending on whether \a select is
    1602   true of false.
    1603 
    1604   \obsolete
    1605 
    1606   This function is deprecated. Use \l{QListWidgetItem::setSelected()} instead.
     1652    Selects or deselects the given \a item depending on whether \a select is
     1653    true of false.
     1654
     1655    \obsolete
     1656
     1657    This function is deprecated. Use QListWidgetItem::setSelected() instead.
    16071658*/
    16081659void QListWidget::setItemSelected(const QListWidgetItem *item, bool select)
    16091660{
    16101661    Q_D(QListWidget);
    1611     QModelIndex index = d->model()->index(const_cast<QListWidgetItem*>(item));
     1662    QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item));
    16121663
    16131664    if (d->selectionMode == SingleSelection) {
     
    16241675
    16251676/*!
    1626   Returns a list of all selected items in the list widget.
     1677    Returns a list of all selected items in the list widget.
    16271678*/
    16281679
     
    16331684    QList<QListWidgetItem*> items;
    16341685    for (int i = 0; i < indexes.count(); ++i)
    1635         items.append(d->model()->at(indexes.at(i).row()));
     1686        items.append(d->listModel()->at(indexes.at(i).row()));
    16361687    return items;
    16371688}
    16381689
    16391690/*!
    1640   Finds items with the text that matches the string \a text using the given \a flags.
     1691    Finds items with the text that matches the string \a text using the given
     1692    \a flags.
    16411693*/
    16421694
     
    16441696{
    16451697    Q_D(const QListWidget);
    1646     QModelIndexList indexes = d->model()->match(model()->index(0, 0, QModelIndex()),
     1698    QModelIndexList indexes = d->listModel()->match(model()->index(0, 0, QModelIndex()),
    16471699                                                Qt::DisplayRole, text, -1, flags);
    16481700    QList<QListWidgetItem*> items;
    16491701    for (int i = 0; i < indexes.size(); ++i)
    1650         items.append(d->model()->at(indexes.at(i).row()));
     1702        items.append(d->listModel()->at(indexes.at(i).row()));
    16511703    return items;
    16521704}
    16531705
    16541706/*!
    1655   Returns true if the \a item is explicitly hidden; otherwise returns false.
    1656 
    1657   \obsolete
    1658 
    1659   This function is deprecated. Use \l{QListWidgetItem::isHidden()} instead.
     1707    Returns true if the \a item is explicitly hidden; otherwise returns false.
     1708
     1709    \obsolete
     1710
     1711    This function is deprecated. Use QListWidgetItem::isHidden() instead.
    16601712*/
    16611713bool QListWidget::isItemHidden(const QListWidgetItem *item) const
     
    16651717
    16661718/*!
    1667   If \a hide is true, the \a item will be hidden; otherwise it will be shown.
    1668 
    1669   \obsolete
    1670 
    1671   This function is deprecated. Use \l{QListWidgetItem::setHidden()} instead.
     1719    If \a hide is true, the \a item will be hidden; otherwise it will be shown.
     1720
     1721    \obsolete
     1722
     1723    This function is deprecated. Use QListWidgetItem::setHidden() instead.
    16721724*/
    16731725void QListWidget::setItemHidden(const QListWidgetItem *item, bool hide)
     
    16771729
    16781730/*!
    1679     Scrolls the view if necessary to ensure that the \a item is
    1680     visible. The \a hint parameter specifies more precisely where the
    1681     \a item should be located after the operation.
     1731    Scrolls the view if necessary to ensure that the \a item is visible.
     1732
     1733    \a hint specifies where the \a item should be located after the operation.
    16821734*/
    16831735
     
    16851737{
    16861738    Q_D(QListWidget);
    1687     QModelIndex index = d->model()->index(const_cast<QListWidgetItem*>(item));
     1739    QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item));
    16881740    QListView::scrollTo(index, hint);
    16891741}
     
    16921744    Removes all items and selections in the view.
    16931745
    1694     \note All items will be permanently deleted.
     1746    \warning All items will be permanently deleted.
    16951747*/
    16961748void QListWidget::clear()
     
    16981750    Q_D(QListWidget);
    16991751    selectionModel()->clear();
    1700     d->model()->clear();
     1752    d->listModel()->clear();
    17011753}
    17021754
     
    17091761QStringList QListWidget::mimeTypes() const
    17101762{
    1711     return d_func()->model()->QAbstractListModel::mimeTypes();
     1763    return d_func()->listModel()->QAbstractListModel::mimeTypes();
    17121764}
    17131765
     
    17171769    mimeTypes() function.
    17181770
    1719     If the list of items is empty, 0 is returned rather than a serialized
    1720     empty list.
     1771    If the list of items is empty, 0 is returned instead of a serialized empty
     1772    list.
    17211773*/
    17221774QMimeData *QListWidget::mimeData(const QList<QListWidgetItem*>) const
    17231775{
    1724     return d_func()->model()->internalMimeData();
     1776    return d_func()->listModel()->internalMimeData();
    17251777}
    17261778
    17271779#ifndef QT_NO_DRAGANDDROP
    17281780/*!
    1729     Handles the \a data supplied by an external drag and drop operation
    1730     that ended with the given \a action in the given \a index.
    1731     Returns true if the data and action can be handled by the model;
    1732     otherwise returns false.
     1781    Handles \a data supplied by an external drag and drop operation that ended
     1782    with the given \a action in the given \a index. Returns true if \a data and
     1783    \a action can be handled by the model; otherwise returns false.
    17331784
    17341785    \sa supportedDropActions()
     
    17451796        column = -1;
    17461797    }
    1747     return d_func()->model()->QAbstractListModel::dropMimeData(data, action , row, column, idx);
     1798    return d_func()->listModel()->QAbstractListModel::dropMimeData(data, action , row, column, idx);
    17481799}
    17491800
     
    17691820            if (persIndexes.contains(topIndex))
    17701821                return;
     1822            qSort(persIndexes); // The dropped items will remain in the same visual order.
    17711823
    17721824            QPersistentModelIndex dropRow = model()->index(row, col, topIndex);
    17731825
    1774             QList<QListWidgetItem *> taken;
    1775             for (int i = 0; i < persIndexes.count(); ++i)
    1776                 taken.append(takeItem(persIndexes.at(i).row()));
    1777 
    1778             // insert them back in at their new positions
     1826            int r = row == -1 ? count() : (dropRow.row() >= 0 ? dropRow.row() : row);
    17791827            for (int i = 0; i < persIndexes.count(); ++i) {
    1780                 // Either at a specific point or appended
    1781                 if (row == -1) {
    1782                     insertItem(count(), taken.takeFirst());
    1783                 } else {
    1784                     int r = dropRow.row() >= 0 ? dropRow.row() : row;
    1785                     insertItem(qMin(r, count()), taken.takeFirst());
    1786                 }
     1828                const QPersistentModelIndex &pIndex = persIndexes.at(i);
     1829                d->listModel()->move(pIndex.row(), r);
     1830                r = pIndex.row() + 1;   // Dropped items are inserted contiguously and in the right order.
    17871831            }
    17881832
     
    17971841
    17981842/*!
    1799   Returns the drop actions supported by this view.
    1800 
    1801   \sa Qt::DropActions
     1843    Returns the drop actions supported by this view.
     1844
     1845    \sa Qt::DropActions
    18021846*/
    18031847Qt::DropActions QListWidget::supportedDropActions() const
    18041848{
    18051849    Q_D(const QListWidget);
    1806     return d->model()->QAbstractListModel::supportedDropActions() | Qt::MoveAction;
     1850    return d->listModel()->QAbstractListModel::supportedDropActions() | Qt::MoveAction;
    18071851}
    18081852#endif // QT_NO_DRAGANDDROP
    18091853
    18101854/*!
    1811   Returns a list of pointers to the items contained in the \a data object.
    1812   If the object was not created by a QListWidget in the same process, the list
    1813   is empty.
     1855    Returns a list of pointers to the items contained in the \a data object. If
     1856    the object was not created by a QListWidget in the same process, the list
     1857    is empty.
    18141858*/
    18151859QList<QListWidgetItem*> QListWidget::items(const QMimeData *data) const
     
    18221866
    18231867/*!
    1824   Returns the QModelIndex assocated with the given \a item.
     1868    Returns the QModelIndex assocated with the given \a item.
    18251869*/
    18261870
     
    18281872{
    18291873    Q_D(const QListWidget);
    1830     return d->model()->index(item);
    1831 }
    1832 
    1833 /*!
    1834   Returns a pointer to the QListWidgetItem assocated with the given \a index.
     1874    return d->listModel()->index(item);
     1875}
     1876
     1877/*!
     1878    Returns a pointer to the QListWidgetItem assocated with the given \a index.
    18351879*/
    18361880
     
    18391883    Q_D(const QListWidget);
    18401884    if (d->isIndexValid(index))
    1841         return d->model()->at(index.row());
     1885        return d->listModel()->at(index.row());
    18421886    return 0;
    18431887}
    18441888
    18451889/*!
    1846   \internal
     1890    \internal
    18471891*/
    18481892void QListWidget::setModel(QAbstractItemModel * /*model*/)
  • trunk/src/gui/itemviews/qlistwidget.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qlistwidget_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7878};
    7979
    80 class QListModel : public QAbstractListModel
     80class Q_AUTOTEST_EXPORT QListModel : public QAbstractListModel
    8181{
    8282    Q_OBJECT
     
    9191    void remove(QListWidgetItem *item);
    9292    QListWidgetItem *take(int row);
     93    void move(int srcRow, int dstRow);
    9394
    9495    int rowCount(const QModelIndex &parent = QModelIndex()) const;
     
    144145public:
    145146    QListWidgetPrivate() : QListViewPrivate(), sortOrder(Qt::AscendingOrder), sortingEnabled(false) {}
    146     inline QListModel *model() const { return qobject_cast<QListModel*>(q_func()->model()); }
     147    inline QListModel *listModel() const { return qobject_cast<QListModel*>(model); }
    147148    void setup();
    148149    void _q_emitItemPressed(const QModelIndex &index);
     
    164165    QListWidgetItemPrivate(QListWidgetItem *item) : q(item), theid(-1) {}
    165166    QListWidgetItem *q;
    166     int id;
    167167    QVector<QWidgetItemData> values;
    168168    int theid;
  • trunk/src/gui/itemviews/qproxymodel.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qproxymodel.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qproxymodel_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qsortfilterproxymodel.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5656
    5757typedef QList<QPair<QModelIndex, QPersistentModelIndex> > QModelIndexPairList;
     58
     59static inline QSet<int> qVectorToSet(const QVector<int> &vector)
     60{
     61    QSet<int> set;
     62    set.reserve(vector.size());
     63    for(int i=0; i < vector.size(); ++i)
     64        set << vector.at(i);
     65    return set;
     66}
    5867
    5968class QSortFilterProxyModelLessThan
     
    138147    QModelIndex proxy_to_source(const QModelIndex &proxyIndex) const;
    139148    QModelIndex source_to_proxy(const QModelIndex &sourceIndex) const;
     149    bool can_create_mapping(const QModelIndex &source_parent) const;
    140150
    141151    void remove_from_mapping(const QModelIndex &source_parent);
     
    145155    {
    146156        Q_ASSERT(proxy_index.isValid());
     157        Q_ASSERT(proxy_index.model() == q_func());
    147158        const void *p = proxy_index.internalPointer();
    148159        Q_ASSERT(p);
     
    164175    void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int start, int end);
    165176
     177    void _q_sourceAboutToBeReset();
    166178    void _q_sourceReset();
    167179
     
    224236    void update_persistent_indexes(const QModelIndexPairList &source_indexes);
    225237
    226     void filter_changed();
    227     void handle_filter_changed(
     238    void filter_changed(const QModelIndex &source_parent = QModelIndex());
     239    QSet<int> handle_filter_changed(
    228240        QVector<int> &source_to_proxy, QVector<int> &proxy_to_source,
    229241        const QModelIndex &source_parent, Qt::Orientation orient);
     
    312324    if (!proxy_index.isValid())
    313325        return QModelIndex(); // for now; we may want to be able to set a root index later
     326    if (proxy_index.model() != q_func()) {
     327        qWarning() << "QSortFilterProxyModel: index from wrong model passed to mapToSource";
     328        return QModelIndex();
     329    }
    314330    IndexMap::const_iterator it = index_to_iterator(proxy_index);
    315331    Mapping *m = it.value();
     
    325341    if (!source_index.isValid())
    326342        return QModelIndex(); // for now; we may want to be able to set a root index later
     343    if (source_index.model() != model) {
     344        qWarning() << "QSortFilterProxyModel: index from wrong model passed to mapFromSource";
     345        return QModelIndex();
     346    }
    327347    QModelIndex source_parent = source_index.parent();
    328348    IndexMap::const_iterator it = create_mapping(source_parent);
     
    335355        return QModelIndex();
    336356    return create_index(proxy_row, proxy_column, it);
     357}
     358
     359bool QSortFilterProxyModelPrivate::can_create_mapping(const QModelIndex &source_parent) const
     360{
     361    if (source_parent.isValid()) {
     362        QModelIndex source_grand_parent = source_parent.parent();
     363        IndexMap::const_iterator it = source_index_mapping.constFind(source_grand_parent);
     364        if (it == source_index_mapping.constEnd()) {
     365            // Don't care, since we don't have mapping for the grand parent
     366            return false;
     367        }
     368        Mapping *gm = it.value();
     369        if (gm->proxy_rows.at(source_parent.row()) == -1 ||
     370            gm->proxy_columns.at(source_parent.column()) == -1) {
     371            // Don't care, since parent is filtered
     372            return false;
     373        }
     374    }
     375    return true;
    337376}
    338377
     
    642681    IndexMap::const_iterator it = source_index_mapping.constFind(source_parent);
    643682    if (it == source_index_mapping.constEnd()) {
    644         if (source_parent.isValid()) {
    645             QModelIndex source_grand_parent = source_parent.parent();
    646             it = source_index_mapping.constFind(source_grand_parent);
    647             if (it == source_index_mapping.constEnd()) {
    648                 // Don't care, since we don't have mapping for the grand parent
    649                 return;
    650             }
    651             Mapping *gm = it.value();
    652             if (gm->proxy_rows.at(source_parent.row()) == -1 ||
    653                 gm->proxy_columns.at(source_parent.column()) == -1) {
    654                 // Don't care, since parent is filtered
    655                 return;
    656             }
    657         }
     683        if (!can_create_mapping(source_parent))
     684            return;
    658685        it = create_mapping(source_parent);
    659686        Mapping *m = it.value();
     
    705732            : q->filterAcceptsColumn(i, source_parent)) {
    706733            source_items.append(i);
     734        }
     735    }
     736
     737    if (model->rowCount(source_parent) == delta_item_count) {
     738        // Items were inserted where there were none before.
     739        // If it was new rows make sure to create mappings for columns so that a
     740        // valid mapping can be retreived later and vice-versa.
     741
     742        QVector<int> &orthogonal_proxy_to_source = (orient == Qt::Horizontal) ? m->source_rows : m->source_columns;
     743        QVector<int> &orthogonal_source_to_proxy = (orient == Qt::Horizontal) ? m->proxy_rows : m->proxy_columns;
     744
     745        if (orthogonal_source_to_proxy.isEmpty()) {
     746            const int ortho_end = (orient == Qt::Horizontal) ? model->rowCount(source_parent) : model->columnCount(source_parent);
     747
     748            for (int ortho_item = 0; ortho_item < ortho_end; ++ortho_item) {
     749                if ((orient == Qt::Horizontal) ? q->filterAcceptsRow(ortho_item, source_parent)
     750                        : q->filterAcceptsColumn(ortho_item, source_parent)) {
     751                    orthogonal_proxy_to_source.append(ortho_item);
     752                }
     753            }
     754            orthogonal_source_to_proxy.resize(orthogonal_proxy_to_source.size());
     755
     756            if (orient == Qt::Horizontal) {
     757                // We're reacting to columnsInserted, but we've just inserted new rows. Sort them.
     758                sort_source_rows(orthogonal_proxy_to_source, source_parent);
     759            }
     760            build_source_to_proxy_mapping(orthogonal_proxy_to_source, orthogonal_source_to_proxy);
    707761        }
    708762    }
     
    867921    proxy_low = INT_MAX;
    868922    proxy_high = INT_MIN;
    869     foreach (int source_item, source_items) {
    870         int proxy_item = source_to_proxy.at(source_item);
     923    for (int i = 0; i < source_items.count(); ++i) {
     924        int proxy_item = source_to_proxy.at(source_items.at(i));
    871925        Q_ASSERT(proxy_item != -1);
    872926        if (proxy_item < proxy_low)
     
    929983}
    930984
     985
    931986/*!
    932987  \internal
     
    935990  new filter.
    936991*/
    937 void QSortFilterProxyModelPrivate::filter_changed()
    938 {
    939     QMap<QModelIndex, Mapping *>::const_iterator it;
    940     for (it = source_index_mapping.constBegin(); it != source_index_mapping.constEnd(); ++it) {
    941         QModelIndex source_parent = it.key();
    942         Mapping *m = it.value();
    943         handle_filter_changed(m->proxy_rows, m->source_rows, source_parent, Qt::Vertical);
    944         handle_filter_changed(m->proxy_columns, m->source_columns, source_parent, Qt::Horizontal);
     992void QSortFilterProxyModelPrivate::filter_changed(const QModelIndex &source_parent)
     993{
     994    IndexMap::const_iterator it = source_index_mapping.constFind(source_parent);
     995    if (it == source_index_mapping.constEnd())
     996        return;
     997    Mapping *m = it.value();
     998    QSet<int> rows_removed = handle_filter_changed(m->proxy_rows, m->source_rows, source_parent, Qt::Vertical);
     999    QSet<int> columns_removed = handle_filter_changed(m->proxy_columns, m->source_columns, source_parent, Qt::Horizontal);
     1000    QVector<QModelIndex>::iterator it2 = m->mapped_children.end();
     1001    while (it2 != m->mapped_children.begin()) {
     1002        --it2;
     1003        const QModelIndex source_child_index = *it2;
     1004        if (rows_removed.contains(source_child_index.row()) || columns_removed.contains(source_child_index.column())) {
     1005            it2 = m->mapped_children.erase(it2);
     1006            remove_from_mapping(source_child_index);
     1007        } else {
     1008            filter_changed(source_child_index);
     1009        }
    9451010    }
    9461011}
     
    9481013/*!
    9491014  \internal
    950 */
    951 void QSortFilterProxyModelPrivate::handle_filter_changed(
     1015  returns the removed items indexes
     1016*/
     1017QSet<int> QSortFilterProxyModelPrivate::handle_filter_changed(
    9521018    QVector<int> &source_to_proxy, QVector<int> &proxy_to_source,
    9531019    const QModelIndex &source_parent, Qt::Orientation orient)
     
    9561022    // Figure out which mapped items to remove
    9571023    QVector<int> source_items_remove;
    958     foreach (int source_item, proxy_to_source) {
     1024    for (int i = 0; i < proxy_to_source.count(); ++i) {
     1025        const int source_item = proxy_to_source.at(i);
    9591026        if ((orient == Qt::Vertical)
    9601027            ? !q->filterAcceptsRow(source_item, source_parent)
     
    9861053                            source_items_insert, source_parent, orient);
    9871054    }
     1055    return qVectorToSet(source_items_remove);
    9881056}
    9891057
     
    10331101    }
    10341102
    1035     if (!source_rows_remove.isEmpty())
     1103    if (!source_rows_remove.isEmpty()) {
    10361104        remove_source_items(m->proxy_rows, m->source_rows,
    10371105                            source_rows_remove, source_parent, Qt::Vertical);
     1106        QSet<int> source_rows_remove_set = qVectorToSet(source_rows_remove);
     1107        QVector<QModelIndex>::iterator it = m->mapped_children.end();
     1108        while (it != m->mapped_children.begin()) {
     1109            --it;
     1110            const QModelIndex source_child_index = *it;
     1111            if (source_rows_remove_set.contains(source_child_index.row())) {
     1112                it = m->mapped_children.erase(it);
     1113                remove_from_mapping(source_child_index);
     1114            }
     1115        }
     1116    }
    10381117
    10391118    if (!source_rows_resort.isEmpty()) {
     
    10981177}
    10991178
     1179void QSortFilterProxyModelPrivate::_q_sourceAboutToBeReset()
     1180{
     1181    Q_Q(QSortFilterProxyModel);
     1182    q->beginResetModel();
     1183    invalidatePersistentIndexes();
     1184    clear_mapping();
     1185}
     1186
    11001187void QSortFilterProxyModelPrivate::_q_sourceReset()
    11011188{
    11021189    Q_Q(QSortFilterProxyModel);
    11031190    // All internal structures are deleted in clear()
    1104     q->reset();
     1191    q->endResetModel();
    11051192    update_source_sort_column();
    11061193    if (dynamic_sortfilter)
     
    11121199    Q_Q(QSortFilterProxyModel);
    11131200    saved_persistent_indexes.clear();
     1201    emit q->layoutAboutToBeChanged();
    11141202    if (persistent.indexes.isEmpty())
    11151203        return;
    1116     emit q->layoutAboutToBeChanged();
     1204
    11171205    saved_persistent_indexes = store_persistent_indexes();
    11181206}
     
    11221210    Q_Q(QSortFilterProxyModel);
    11231211    if (saved_persistent_indexes.isEmpty()) {
    1124         q->invalidate();
     1212        clear_mapping();
     1213        emit q->layoutChanged();
    11251214        return;
    11261215    }
     
    11441233    //Force the creation of a mapping now, even if its empty.
    11451234    //We need it because the proxy can be acessed at the moment it emits rowsAboutToBeInserted in insert_source_items
    1146     create_mapping(source_parent);
     1235    if (can_create_mapping(source_parent))
     1236        create_mapping(source_parent);
    11471237}
    11481238
     
    11751265    //Force the creation of a mapping now, even if its empty.
    11761266    //We need it because the proxy can be acessed at the moment it emits columnsAboutToBeInserted in insert_source_items
    1177     create_mapping(source_parent);
     1267    if (can_create_mapping(source_parent))
     1268        create_mapping(source_parent);
    11781269}
    11791270
     
    12261317    \since 4.1
    12271318    \class QSortFilterProxyModel
    1228     \brief The QSortFilterProxyModel class provides support for sorting and filtering data passed
    1229     between another model and a view.
     1319    \brief The QSortFilterProxyModel class provides support for sorting and
     1320    filtering data passed between another model and a view.
    12301321
    12311322    \ingroup model-view
    12321323
    1233     QSortFilterProxyModel can be used for sorting items, filtering
    1234     out items, or both. The model transforms the structure of a
    1235     source model by mapping the model indexes it supplies to new
    1236     indexes, corresponding to different locations, for views to use.
    1237     This approach allows a given source model to be restructured as
    1238     far as views are concerned without requiring any transformations
    1239     on the underlying data, and without duplicating the data in
     1324    QSortFilterProxyModel can be used for sorting items, filtering out items,
     1325    or both. The model transforms the structure of a source model by mapping
     1326    the model indexes it supplies to new indexes, corresponding to different
     1327    locations, for views to use. This approach allows a given source model to
     1328    be restructured as far as views are concerned without requiring any
     1329    transformations on the underlying data, and without duplicating the data in
    12401330    memory.
    12411331
    1242     Let's assume that we want to sort and filter the items provided
    1243     by a custom model. The code to set up the model and the view, \e
    1244     without sorting and filtering, would look like this:
     1332    Let's assume that we want to sort and filter the items provided by a custom
     1333    model. The code to set up the model and the view, \e without sorting and
     1334    filtering, would look like this:
    12451335
    12461336    \snippet doc/src/snippets/qsortfilterproxymodel-details/main.cpp 1
    12471337
    1248     To add sorting and filtering support to \c MyItemModel, we need
    1249     to create a QSortFilterProxyModel, call setSourceModel() with the
    1250     \c MyItemModel as argument, and install the QSortFilterProxyModel
    1251     on the view:
     1338    To add sorting and filtering support to \c MyItemModel, we need to create
     1339    a QSortFilterProxyModel, call setSourceModel() with the \c MyItemModel as
     1340    argument, and install the QSortFilterProxyModel on the view:
    12521341
    12531342    \snippet doc/src/snippets/qsortfilterproxymodel-details/main.cpp 0
    12541343    \snippet doc/src/snippets/qsortfilterproxymodel-details/main.cpp 2
    12551344
    1256     At this point, neither sorting nor filtering is enabled; the
    1257     original data is displayed in the view. Any changes made through
    1258     the QSortFilterProxyModel are applied to the original model.
    1259 
    1260     The QSortFilterProxyModel acts as a wrapper for the original
    1261     model. If you need to convert source \l{QModelIndex}es to
    1262     sorted/filtered model indexes or vice versa, use mapToSource(),
    1263     mapFromSource(), mapSelectionToSource(), and
    1264     mapSelectionFromSource().
    1265 
    1266     \note By default, the model does not dynamically re-sort and re-filter
    1267     data whenever the original model changes. This behavior can be
    1268     changed by setting the \l{QSortFilterProxyModel::dynamicSortFilter}
    1269     {dynamicSortFilter} property.
    1270 
    1271     The \l{itemviews/basicsortfiltermodel}{Basic Sort/Filter Model}
    1272     and \l{itemviews/customsortfiltermodel}{Custom Sort/Filter Model}
    1273     examples illustrate how to use QSortFilterProxyModel to perform
    1274     basic sorting and filtering and how to subclass it to implement
    1275     custom behavior.
     1345    At this point, neither sorting nor filtering is enabled; the original data
     1346    is displayed in the view. Any changes made through the
     1347    QSortFilterProxyModel are applied to the original model.
     1348
     1349    The QSortFilterProxyModel acts as a wrapper for the original model. If you
     1350    need to convert source \l{QModelIndex}es to sorted/filtered model indexes
     1351    or vice versa, use mapToSource(), mapFromSource(), mapSelectionToSource(),
     1352    and mapSelectionFromSource().
     1353
     1354    \note By default, the model does not dynamically re-sort and re-filter data
     1355    whenever the original model changes. This behavior can be changed by
     1356    setting the \l{QSortFilterProxyModel::dynamicSortFilter}{dynamicSortFilter}
     1357    property.
     1358
     1359    The \l{itemviews/basicsortfiltermodel}{Basic Sort/Filter Model} and
     1360    \l{itemviews/customsortfiltermodel}{Custom Sort/Filter Model} examples
     1361    illustrate how to use QSortFilterProxyModel to perform basic sorting and
     1362    filtering and how to subclass it to implement custom behavior.
    12761363
    12771364    \section1 Sorting
    12781365
    12791366    QTableView and QTreeView have a
    1280     \l{QTreeView::sortingEnabled}{sortingEnabled} property that
    1281     controls whether the user can sort the view by clicking the
    1282     view's horizontal header. For example:
     1367    \l{QTreeView::sortingEnabled}{sortingEnabled} property that controls
     1368    whether the user can sort the view by clicking the view's horizontal
     1369    header. For example:
    12831370
    12841371    \snippet doc/src/snippets/qsortfilterproxymodel-details/main.cpp 3
    12851372
    1286     When this feature is on (the default is off), clicking on a
    1287     header section sorts the items according to that column. By
    1288     clicking repeatedly, the user can alternate between ascending and
    1289     descending order.
     1373    When this feature is on (the default is off), clicking on a header section
     1374    sorts the items according to that column. By clicking repeatedly, the user
     1375    can alternate between ascending and descending order.
    12901376
    12911377    \image qsortfilterproxymodel-sorting.png A sorted QTreeView
    12921378
    1293     Behind the scene, the view calls the sort() virtual function on
    1294     the model to reorder the data in the model. To make your data
    1295     sortable, you can either implement sort() in your model, or you
    1296     use a QSortFilterProxyModel to wrap your model --
    1297     QSortFilterProxyModel provides a generic sort() reimplementation
    1298     that operates on the sortRole() (Qt::DisplayRole by default) of
    1299     the items and that understands several data types, including \c
    1300     int, QString, and QDateTime. For hierarchical models, sorting is
    1301     applied recursively to all child items. String comparisons are
    1302     case sensitive by default; this can be changed by setting the
    1303     \l{QSortFilterProxyModel::}{sortCaseSensitivity} property.
     1379    Behind the scene, the view calls the sort() virtual function on the model
     1380    to reorder the data in the model. To make your data sortable, you can
     1381    either implement sort() in your model, or use a QSortFilterProxyModel to
     1382    wrap your model -- QSortFilterProxyModel provides a generic sort()
     1383    reimplementation that operates on the sortRole() (Qt::DisplayRole by
     1384    default) of the items and that understands several data types, including
     1385    \c int, QString, and QDateTime. For hierarchical models, sorting is applied
     1386    recursively to all child items. String comparisons are case sensitive by
     1387    default; this can be changed by setting the \l{QSortFilterProxyModel::}
     1388    {sortCaseSensitivity} property.
    13041389
    13051390    Custom sorting behavior is achieved by subclassing
     
    13131398    example.)
    13141399
    1315     An alternative approach to sorting is to disable sorting on the
    1316     view and to impose a certain order to the user. This is done by
    1317     explicitly calling sort() with the desired column and order as
    1318     arguments on the QSortFilterProxyModel (or on the original model
    1319     if it implements sort()). For example:
     1400    An alternative approach to sorting is to disable sorting on the view and to
     1401    impose a certain order to the user. This is done by explicitly calling
     1402    sort() with the desired column and order as arguments on the
     1403    QSortFilterProxyModel (or on the original model if it implements sort()).
     1404    For example:
    13201405
    13211406    \snippet doc/src/snippets/qsortfilterproxymodel-details/main.cpp 4
    13221407
    1323     QSortFilterProxyModel can be sorted by column -1, in which case it
    1324     returns to the sort order of the underlying source model.
     1408    QSortFilterProxyModel can be sorted by column -1, in which case it returns
     1409    to the sort order of the underlying source model.
    13251410
    13261411    \section1 Filtering
    13271412
    1328     In addition to sorting, QSortFilterProxyModel can be used to hide
    1329     items that don't match a certain filter. The filter is specified
    1330     using a QRegExp object and is applied to the filterRole()
    1331     (Qt::DisplayRole by default) of each item, for a given column.
    1332     The QRegExp object can be used to match a regular expression, a
    1333     wildcard pattern, or a fixed string. For example:
     1413    In addition to sorting, QSortFilterProxyModel can be used to hide items
     1414    that do not match a certain filter. The filter is specified using a QRegExp
     1415    object and is applied to the filterRole() (Qt::DisplayRole by default) of
     1416    each item, for a given column. The QRegExp object can be used to match a
     1417    regular expression, a wildcard pattern, or a fixed string. For example:
    13341418
    13351419    \snippet doc/src/snippets/qsortfilterproxymodel-details/main.cpp 5
    13361420
    1337     For hierarchical models, the filter is applied recursively to all
    1338     children. If a parent item doesn't match the filter, none of its
    1339     children will be shown.
    1340 
    1341     A common use case is to let the user specify the filter regexp,
    1342     wildcard pattern, or fixed string in a QLineEdit and to connect
    1343     the \l{QLineEdit::textChanged()}{textChanged()} signal to
    1344     setFilterRegExp(), setFilterWildcard(), or setFilterFixedString()
    1345     to reapply the filter.
     1421    For hierarchical models, the filter is applied recursively to all children.
     1422    If a parent item doesn't match the filter, none of its children will be
     1423    shown.
     1424
     1425    A common use case is to let the user specify the filter regexp, wildcard
     1426    pattern, or fixed string in a QLineEdit and to connect the
     1427    \l{QLineEdit::textChanged()}{textChanged()} signal to setFilterRegExp(),
     1428    setFilterWildcard(), or setFilterFixedString() to reapply the filter.
    13461429
    13471430    Custom filtering behavior can be achieved by reimplementing the
    13481431    filterAcceptsRow() and filterAcceptsColumn() functions. For
    1349     example, the following implementation ignores the
    1350     \l{QSortFilterProxyModel::filterKeyColumn}{filterKeyColumn}
    1351     property and performs filtering on columns 0, 1, and 2:
     1432    example (from the \l{itemviews/customsortfiltermodel}
     1433    {Custom Sort/Filter Model} example), the following implementation ignores
     1434    the \l{QSortFilterProxyModel::filterKeyColumn}{filterKeyColumn} property
     1435    and performs filtering on columns 0, 1, and 2:
    13521436
    13531437    \snippet examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp 3
     
    13591443    If you are working with large amounts of filtering and have to invoke
    13601444    invalidateFilter() repeatedly, using reset() may be more efficient,
    1361     depending on the implementation of your model. However, note that reset()
    1362     returns the proxy model to its original state, losing selection
    1363     information, and will cause the proxy model to be repopulated.
     1445    depending on the implementation of your model. However, reset() returns the
     1446    proxy model to its original state, losing selection information, and will
     1447    cause the proxy model to be repopulated.
    13641448
    13651449    \section1 Subclassing
    13661450
    1367     \bold{Note:} Some general guidelines for subclassing models are
    1368     available in the \l{Model Subclassing Reference}.
    1369 
    13701451    Since QAbstractProxyModel and its subclasses are derived from
    1371     QAbstractItemModel, much of the same advice about subclassing normal
    1372     models also applies to proxy models. In addition, it is worth noting
    1373     that many of the default implementations of functions in this class
    1374     are written so that they call the equivalent functions in the relevant
    1375     source model. This simple proxying mechanism may need to be overridden
    1376     for source models with more complex behavior; for example, if the
    1377     source model provides a custom hasChildren() implementation, you
    1378     should also provide one in the proxy model.
     1452    QAbstractItemModel, much of the same advice about subclassing normal models
     1453    also applies to proxy models. In addition, it is worth noting that many of
     1454    the default implementations of functions in this class are written so that
     1455    they call the equivalent functions in the relevant source model. This
     1456    simple proxying mechanism may need to be overridden for source models with
     1457    more complex behavior; for example, if the source model provides a custom
     1458    hasChildren() implementation, you should also provide one in the proxy
     1459    model.
     1460
     1461    \note Some general guidelines for subclassing models are available in the
     1462    \l{Model Subclassing Reference}.
    13791463
    13801464    \sa QAbstractProxyModel, QAbstractItemModel, {Model/View Programming},
     
    14181502    Q_D(QSortFilterProxyModel);
    14191503
     1504    beginResetModel();
     1505
    14201506    disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
    14211507               this, SLOT(_q_sourceDataChanged(QModelIndex,QModelIndex)));
     
    14541540               this, SLOT(_q_sourceLayoutChanged()));
    14551541
     1542    disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_sourceAboutToBeReset()));
    14561543    disconnect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset()));
    14571544
     
    14941581            this, SLOT(_q_sourceLayoutChanged()));
    14951582
     1583    connect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_sourceAboutToBeReset()));
    14961584    connect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset()));
    14971585
    14981586    d->clear_mapping();
    1499     reset();
    1500     d->update_source_sort_column();
     1587    endResetModel();
     1588    if (d->update_source_sort_column() && d->dynamic_sortfilter)
     1589        d->sort();
    15011590}
    15021591
     
    19382027
    19392028    Setting this property overwrites the current
    1940     \l{QSortFilterProxyModel::filterCaseSensitivity}
    1941     {filterCaseSensitivity}. By default, the QRegExp is an empty
    1942     string matching all contents.
     2029    \l{QSortFilterProxyModel::filterCaseSensitivity}{filterCaseSensitivity}.
     2030    By default, the QRegExp is an empty string matching all contents.
     2031
     2032    If no QRegExp or an empty string is set, everything in the source model
     2033    will be accepted.
    19432034
    19442035    \sa filterCaseSensitivity, setFilterWildcard(), setFilterFixedString()
     
    22632354    QVariant l = (left.model() ? left.model()->data(left, d->sort_role) : QVariant());
    22642355    QVariant r = (right.model() ? right.model()->data(right, d->sort_role) : QVariant());
    2265     switch (l.type()) {
     2356    switch (l.userType()) {
    22662357    case QVariant::Invalid:
    22672358        return (r.type() == QVariant::Invalid);
     
    22742365    case QVariant::ULongLong:
    22752366        return l.toULongLong() < r.toULongLong();
     2367    case QMetaType::Float:
     2368        return l.toFloat() < r.toFloat();
    22762369    case QVariant::Double:
    22772370        return l.toDouble() < r.toDouble();
  • trunk/src/gui/itemviews/qsortfilterproxymodel.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    178178    Q_PRIVATE_SLOT(d_func(), void _q_sourceDataChanged(const QModelIndex &source_top_left, const QModelIndex &source_bottom_right))
    179179    Q_PRIVATE_SLOT(d_func(), void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int start, int end))
     180    Q_PRIVATE_SLOT(d_func(), void _q_sourceAboutToBeReset())
    180181    Q_PRIVATE_SLOT(d_func(), void _q_sourceReset())
    181182    Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutAboutToBeChanged())
  • trunk/src/gui/itemviews/qstandarditemmodel.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    330330QStandardItemModelPrivate::~QStandardItemModelPrivate()
    331331{
    332     delete root;
    333332    delete itemPrototype;
    334333    qDeleteAll(columnHeaderItems);
     
    555554{
    556555    Q_Q(QStandardItemModel);
    557     if (parent == root)
     556    if (parent == root.data())
    558557        rowHeaderItems.insert(row, count, 0);
    559558    q->endInsertRows();
     
    567566{
    568567    Q_Q(QStandardItemModel);
    569     if (parent == root)
     568    if (parent == root.data())
    570569        columnHeaderItems.insert(column, count, 0);
    571570    q->endInsertColumns();
     
    579578{
    580579    Q_Q(QStandardItemModel);
    581     if (parent == root) {
     580    if (parent == root.data()) {
    582581        for (int i = row; i < row + count; ++i) {
    583582            QStandardItem *oldItem = rowHeaderItems.at(i);
     
    598597{
    599598    Q_Q(QStandardItemModel);
    600     if (parent == root) {
     599    if (parent == root.data()) {
    601600        for (int i = column; i < column + count; ++i) {
    602601            QStandardItem *oldItem = columnHeaderItems.at(i);
     
    779778QStandardItem::~QStandardItem()
    780779{
    781     Q_D(QStandardItem);
    782     delete d;
    783780}
    784781
     
    791788{
    792789    Q_D(const QStandardItem);
    793     if (!d->model || (d->model->d_func()->root != d->parent))
     790    if (!d->model || (d->model->d_func()->root.data() != d->parent))
    794791        return d->parent;
    795792    return 0;
     
    900897        return (Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable
    901898                |Qt::ItemIsDragEnabled|Qt::ItemIsDropEnabled);
    902     return ((Qt::ItemFlags)(v.toInt()));
     899    return Qt::ItemFlags(v.toInt());
    903900}
    904901
     
    17431740    if ((row < 0) || (row >= rowCount()))
    17441741        return QList<QStandardItem*>();
     1742    if (d->model)
     1743        d->model->d_func()->rowsAboutToBeRemoved(this, row, row);
    17451744    QList<QStandardItem*> items;
    1746     int index = d->childIndex(row, 0);
    1747     for (int column = 0; column < d->columnCount(); ++column) {
    1748         QStandardItem *ch = d->children.at(index);
    1749         if (ch) {
    1750             ch->d_func()->setParentAndModel(0, 0);
    1751             d->children.replace(index, 0);
     1745    int index = d->childIndex(row, 0);  // Will return -1 if there are no columns
     1746    if (index != -1) {
     1747        int col_count = d->columnCount();
     1748        for (int column = 0; column < col_count; ++column) {
     1749            QStandardItem *ch = d->children.at(index + column);
     1750            if (ch)
     1751                ch->d_func()->setParentAndModel(0, 0);
     1752            items.append(ch);
    17521753        }
    1753         items.append(ch);
    1754         ++index;
    1755     }
    1756     removeRow(row);
     1754        d->children.remove(index, col_count);
     1755    }
     1756    d->rows--;
     1757    if (d->model)
     1758        d->model->d_func()->rowsRemoved(this, row, 1);
    17571759    return items;
    17581760}
     
    17701772    if ((column < 0) || (column >= columnCount()))
    17711773        return QList<QStandardItem*>();
     1774    if (d->model)
     1775        d->model->d_func()->columnsAboutToBeRemoved(this, column, column);
    17721776    QList<QStandardItem*> items;
    1773     int index = d->childIndex(0, column);
    1774     for (int row = 0; row < d->rowCount(); ++row) {
     1777
     1778    for (int row = d->rowCount() - 1; row >= 0; --row) {
     1779        int index = d->childIndex(row, column);
    17751780        QStandardItem *ch = d->children.at(index);
    1776         if (ch) {
     1781        if (ch)
    17771782            ch->d_func()->setParentAndModel(0, 0);
    1778             d->children.replace(index, 0);
    1779         }
    1780         items.append(ch);
    1781         index += d->columnCount();
    1782     }
    1783     removeColumn(column);
     1783        d->children.remove(index);
     1784        items.prepend(ch);
     1785    }
     1786    d->columns--;
     1787    if (d->model)
     1788        d->model->d_func()->columnsRemoved(this, column, 1);
    17841789    return items;
    17851790}
     
    18021807    const QVariant l = data(role), r = other.data(role);
    18031808    // this code is copied from QSortFilterProxyModel::lessThan()
    1804     switch (l.type()) {
     1809    switch (l.userType()) {
    18051810    case QVariant::Invalid:
    18061811        return (r.type() == QVariant::Invalid);
     
    18131818    case QVariant::ULongLong:
    18141819        return l.toULongLong() < r.toULongLong();
     1820    case QMetaType::Float:
     1821        return l.toFloat() < r.toFloat();
    18151822    case QVariant::Double:
    18161823        return l.toDouble() < r.toDouble();
     
    18911898    qint32 flags;
    18921899    in >> flags;
    1893     setFlags((Qt::ItemFlags)flags);
     1900    setFlags(Qt::ItemFlags(flags));
    18941901}
    18951902
     
    19391946}
    19401947
    1941 #endif // !QT_NO_DATASTREAM
     1948#endif // QT_NO_DATASTREAM
    19421949
    19431950/*!
     
    20802087{
    20812088    Q_D(QStandardItemModel);
    2082     delete d->root;
    2083     d->root = new QStandardItem;
     2089    d->root.reset(new QStandardItem);
    20842090    d->root->d_func()->setModel(this);
    20852091    qDeleteAll(d->columnHeaderItems);
     
    22282234{
    22292235    Q_D(const QStandardItemModel);
    2230     return d->root;
     2236    return d->root.data();
    22312237}
    22322238
     
    27302736{
    27312737    Q_D(QStandardItemModel);
    2732     QStandardItem *item = parent.isValid() ? itemFromIndex(parent) : d->root;
     2738    QStandardItem *item = parent.isValid() ? itemFromIndex(parent) : d->root.data();
    27332739    if (item == 0)
    27342740        return false;
     
    27422748{
    27432749    Q_D(QStandardItemModel);
    2744     QStandardItem *item = parent.isValid() ? itemFromIndex(parent) : d->root;
     2750    QStandardItem *item = parent.isValid() ? itemFromIndex(parent) : d->root.data();
    27452751    if (item == 0)
    27462752        return false;
     
    29082914    itemsSet.reserve(indexes.count());
    29092915    stack.reserve(indexes.count());
    2910     foreach (const QModelIndex &index, indexes) {
    2911         QStandardItem *item = itemFromIndex(index);
     2916    for (int i = 0; i < indexes.count(); ++i) {
     2917        QStandardItem *item = itemFromIndex(indexes.at(i));
    29122918        itemsSet << item;
    29132919        stack.push(item);
     
    29662972    stream out an item and his children
    29672973 */
    2968 static void decodeDataRecursive(QDataStream &stream, QStandardItem *item)
     2974void QStandardItemModelPrivate::decodeDataRecursive(QDataStream &stream, QStandardItem *item)
    29692975{
    29702976    int colCount, childCount;
     
    29772983    while(childPos > 0) {
    29782984        childPos--;
    2979         QStandardItem *child = new QStandardItem;
     2985        QStandardItem *child = createItem();
    29802986        decodeDataRecursive(stream, child);
    29812987        item->setChild( childPos / colCount, childPos % colCount, child);
     
    29902996                                      int row, int column, const QModelIndex &parent)
    29912997{
     2998    Q_D(QStandardItemModel);
    29922999    // check if the action is supported
    29933000    if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
     
    30213028    while (!stream.atEnd()) {
    30223029        int r, c;
    3023         QStandardItem *item = new QStandardItem;
     3030        QStandardItem *item = d->createItem();
    30243031        stream >> r >> c;
    3025         decodeDataRecursive(stream, item);
     3032        d->decodeDataRecursive(stream, item);
    30263033
    30273034        rows.append(r);
  • trunk/src/gui/itemviews/qstandarditemmodel.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    241241    QStandardItem(QStandardItemPrivate &dd);
    242242    QStandardItem &operator=(const QStandardItem &other);
    243     QStandardItemPrivate *d_ptr;
     243    QScopedPointer<QStandardItemPrivate> d_ptr;
    244244
    245245    void emitDataChanged();
  • trunk/src/gui/itemviews/qstandarditemmodel_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7676          rows(0),
    7777          columns(0),
     78          q_ptr(0),
    7879          lastIndexOf(2)
    7980        { }
     
    153154        Q_Q(const QStandardItemModel);
    154155        if (!index.isValid())
    155             return root;
     156            return root.data();
    156157        if (index.model() != q)
    157158            return 0;
     
    176177                            const QModelIndex &bottomRight);
    177178
     179    void decodeDataRecursive(QDataStream &stream, QStandardItem *item);
     180
    178181    QVector<QStandardItem*> columnHeaderItems;
    179182    QVector<QStandardItem*> rowHeaderItems;
    180     QStandardItem *root;
     183    QScopedPointer<QStandardItem> root;
    181184    const QStandardItem *itemPrototype;
    182185    int sortRole;
  • trunk/src/gui/itemviews/qstringlistmodel.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5555
    5656    \ingroup model-view
    57     \mainclass
     57
    5858
    5959    QStringListModel is an editable model that can be used for simple
  • trunk/src/gui/itemviews/qstringlistmodel.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qstyleditemdelegate.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4848#include <qlineedit.h>
    4949#include <qtextedit.h>
     50#include <qplaintextedit.h>
    5051#include <qpainter.h>
    5152#include <qpalette.h>
     
    112113
    113114    \ingroup model-view
    114     \mainclass
     115
    115116    \since 4.4
    116117
     
    148149    \row    \o \l Qt::BackgroundColorRole \o QColor (obsolete; use Qt::BackgroundRole instead)
    149150    \row    \o \l Qt::CheckStateRole \o Qt::CheckState
    150     \row    \o \l Qt::DecorationRole \o QIcon and QColor
     151    \row    \o \l Qt::DecorationRole \o QIcon, QPixmap, QImage and QColor
    151152    \row    \o \l Qt::DisplayRole \o QString and types with a string representation
    152153    \row    \o \l Qt::EditRole \o See QItemEditorFactory for details
     
    267268{
    268269    QString text;
    269     switch (value.type()) {
     270    switch (value.userType()) {
     271    case QMetaType::Float:
    270272    case QVariant::Double:
    271         text = locale.toString(value.toDouble());
     273        text = locale.toString(value.toReal());
    272274        break;
    273275    case QVariant::Int:
     
    322324    value = index.data(Qt::TextAlignmentRole);
    323325    if (value.isValid() && !value.isNull())
    324         option->displayAlignment = (Qt::Alignment)value.toInt();
     326        option->displayAlignment = Qt::Alignment(value.toInt());
    325327
    326328    value = index.data(Qt::ForegroundRole);
     
    508510
    509511/*!
    510     Gets data drom the \a editor widget and stores it in the specified
     512    Gets data from the \a editor widget and stores it in the specified
    511513    \a model at the item \a index.
    512514
     
    647649        case Qt::Key_Return:
    648650#ifndef QT_NO_TEXTEDIT
    649             if (qobject_cast<QTextEdit*>(editor))
     651            if (qobject_cast<QTextEdit *>(editor) || qobject_cast<QPlainTextEdit *>(editor))
    650652                return false; // don't filter enter key events for QTextEdit
    651653            // We want the editor to be able to process the key press
     
    671673            editor->parentWidget()->setFocus();
    672674        return true;
    673     } else if (event->type() == QEvent::FocusOut || event->type() == QEvent::Hide) {
     675    } else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) {
    674676        //the Hide event will take care of he editors that are in fact complete dialogs
    675677        if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) {
     
    686688                return false;
    687689#endif
    688             // Opening a modal dialog will start a new eventloop
    689             // that will process the deleteLater event.
    690             QWidget *activeModalWidget = QApplication::activeModalWidget();
    691             if (activeModalWidget
    692                 && !activeModalWidget->isAncestorOf(editor)
    693                 && qobject_cast<QDialog*>(activeModalWidget))
    694                 return false;
     690
    695691            emit commitData(editor);
    696692            emit closeEditor(editor, NoHint);
     
    752748    }
    753749
    754     Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
     750    Qt::CheckState state;
     751    if ( flags & Qt::ItemIsTristate ) {
     752        state = static_cast<Qt::CheckState>( (value.toInt() + 1) % 3 );
     753    } else {
     754        state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
    755755                            ? Qt::Unchecked : Qt::Checked);
     756    }
    756757    return model->setData(index, state, Qt::CheckStateRole);
    757758}
  • trunk/src/gui/itemviews/qstyleditemdelegate.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qtableview.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5959
    6060QT_BEGIN_NAMESPACE
     61
     62/** \internal
     63  Add a span to the collection. the collection takes the ownership.
     64  */
     65void QSpanCollection::addSpan(QSpanCollection::Span *span)
     66{
     67    spans.append(span);
     68    Index::iterator it_y = index.lowerBound(-span->top());
     69    if (it_y == index.end() || it_y.key() != -span->top()) {
     70        //there is no spans that starts with the row in the index, so create a sublist for it.
     71        SubIndex sub_index;
     72        if (it_y != index.end()) {
     73            //the previouslist is the list of spans that sarts _before_ the row of the span.
     74            // and which may intersect this row.
     75            const SubIndex previousList = it_y.value();
     76            foreach(Span *s, previousList) {
     77                //If a subspans intersect the row, we need to split it into subspans
     78                if(s->bottom() >= span->top())
     79                    sub_index.insert(-s->left(), s);
     80            }
     81        }
     82        it_y = index.insert(-span->top(), sub_index);
     83        //we will insert span to *it_y in the later loop
     84    }
     85
     86    //insert the span as supspan in all the lists that intesects the span
     87    while(-it_y.key() <= span->bottom()) {
     88        (*it_y).insert(-span->left(), span);
     89        if(it_y == index.begin())
     90            break;
     91        --it_y;
     92    }
     93}
     94
     95
     96/** \internal
     97* Has to be called after the height and width of a span is changed.
     98*
     99* old_height is the height before the change
     100*
     101* if the size of the span is now 0x0 the span will be deleted.
     102*/
     103void QSpanCollection::updateSpan(QSpanCollection::Span *span, int old_height)
     104{
     105    if (old_height < span->height()) {
     106        //add the span as subspan in all the lists that intersect the new covered columns
     107        Index::iterator it_y = index.lowerBound(-(span->top() + old_height - 1));
     108        Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list
     109        while (-it_y.key() <= span->bottom()) {
     110            (*it_y).insert(-span->left(), span);
     111            if(it_y == index.begin())
     112                break;
     113            --it_y;
     114        }
     115    } else if (old_height > span->height()) {
     116        //remove the span from all the subspans lists that intersect the columns not covered anymore
     117        Index::iterator it_y = index.lowerBound(qMin(-span->bottom(), 0));
     118        Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list
     119        while (-it_y.key() <= span->top() + old_height -1) {
     120            if (-it_y.key() > span->bottom()) {
     121                (*it_y).remove(-span->left());
     122                if (it_y->isEmpty()) {
     123                    it_y = index.erase(it_y) - 1;
     124                }
     125            }
     126            if(it_y == index.begin())
     127                break;
     128            --it_y;
     129        }
     130    }
     131
     132    if (span->width() == 0 && span->height() == 0) {
     133        spans.removeOne(span);
     134        delete span;
     135    }
     136}
     137
     138/** \internal
     139 * \return a spans that spans over cell x,y  (column,row)  or 0 if there is none.
     140 */
     141QSpanCollection::Span *QSpanCollection::spanAt(int x, int y) const
     142{
     143    Index::const_iterator it_y = index.lowerBound(-y);
     144    if (it_y == index.end())
     145        return 0;
     146    SubIndex::const_iterator it_x = (*it_y).lowerBound(-x);
     147    if (it_x == (*it_y).end())
     148        return 0;
     149    Span *span = *it_x;
     150    if (span->right() >= x && span->bottom() >= y)
     151        return span;
     152    return 0;
     153}
     154
     155
     156/** \internal
     157* remove and deletes all spans inside the collection
     158*/
     159void QSpanCollection::clear()
     160{
     161    qDeleteAll(spans);
     162    index.clear();
     163    spans.clear();
     164}
     165
     166/** \internal
     167 * return a list to all the spans that spans over cells in the given rectangle
     168 */
     169QList<QSpanCollection::Span *> QSpanCollection::spansInRect(int x, int y, int w, int h) const
     170{
     171    QSet<Span *> list;
     172    Index::const_iterator it_y = index.lowerBound(-y);
     173    if(it_y == index.end())
     174        --it_y;
     175    while(-it_y.key() <= y + h) {
     176        SubIndex::const_iterator it_x = (*it_y).lowerBound(-x);
     177        if (it_x == (*it_y).end())
     178            --it_x;
     179        while(-it_x.key() <= x + w) {
     180            Span *s = *it_x;
     181            if (s->bottom() >= y && s->right() >= x)
     182                list << s;
     183            if (it_x == (*it_y).begin())
     184                break;
     185            --it_x;
     186        }
     187        if(it_y == index.begin())
     188            break;
     189        --it_y;
     190    }
     191    return list.toList();
     192}
     193
     194#undef DEBUG_SPAN_UPDATE
     195
     196#ifdef DEBUG_SPAN_UPDATE
     197QDebug operator<<(QDebug str, const QSpanCollection::Span &span)
     198{
     199    str << "(" << span.top() << "," << span.left() << "," << span.bottom() << "," << span.right() << ")";
     200    return str;
     201}
     202#endif
     203
     204/** \internal
     205* Updates the span collection after row insertion.
     206*/
     207void QSpanCollection::updateInsertedRows(int start, int end)
     208{
     209#ifdef DEBUG_SPAN_UPDATE
     210    qDebug() << Q_FUNC_INFO;
     211    qDebug() << start << end;
     212    qDebug() << index;
     213#endif
     214    if (spans.isEmpty())
     215        return;
     216
     217    int delta = end - start + 1;
     218#ifdef DEBUG_SPAN_UPDATE
     219    qDebug("Before");
     220#endif
     221    for (SpanList::iterator it = spans.begin(); it != spans.end(); ++it) {
     222        Span *span = *it;
     223#ifdef DEBUG_SPAN_UPDATE
     224        qDebug() << span << *span;
     225#endif
     226        if (span->m_bottom < start)
     227            continue;
     228        if (span->m_top >= start)
     229            span->m_top += delta;
     230        span->m_bottom += delta;
     231    }
     232
     233#ifdef DEBUG_SPAN_UPDATE
     234    qDebug("After");
     235    foreach (QSpanCollection::Span *span, spans)
     236        qDebug() << span << *span;
     237#endif
     238
     239    for (Index::iterator it_y = index.begin(); it_y != index.end(); ) {
     240        int y = -it_y.key();
     241        if (y < start) {
     242            ++it_y;
     243            continue;
     244        }
     245
     246        index.insert(-y - delta, it_y.value());
     247        it_y = index.erase(it_y);
     248    }
     249#ifdef DEBUG_SPAN_UPDATE
     250    qDebug() << index;
     251#endif
     252}
     253
     254/** \internal
     255* Updates the span collection after column insertion.
     256*/
     257void QSpanCollection::updateInsertedColumns(int start, int end)
     258{
     259#ifdef DEBUG_SPAN_UPDATE
     260    qDebug() << Q_FUNC_INFO;
     261    qDebug() << start << end;
     262    qDebug() << index;
     263#endif
     264    if (spans.isEmpty())
     265        return;
     266
     267    int delta = end - start + 1;
     268#ifdef DEBUG_SPAN_UPDATE
     269    qDebug("Before");
     270#endif
     271    for (SpanList::iterator it = spans.begin(); it != spans.end(); ++it) {
     272        Span *span = *it;
     273#ifdef DEBUG_SPAN_UPDATE
     274        qDebug() << span << *span;
     275#endif
     276        if (span->m_right < start)
     277            continue;
     278        if (span->m_left >= start)
     279            span->m_left += delta;
     280        span->m_right += delta;
     281    }
     282
     283#ifdef DEBUG_SPAN_UPDATE
     284    qDebug("After");
     285    foreach (QSpanCollection::Span *span, spans)
     286        qDebug() << span << *span;
     287#endif
     288
     289    for (Index::iterator it_y = index.begin(); it_y != index.end(); ++it_y) {
     290        SubIndex &subindex = it_y.value();
     291        for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ) {
     292            int x = -it.key();
     293            if (x < start) {
     294                ++it;
     295                continue;
     296            }
     297            subindex.insert(-x - delta, it.value());
     298            it = subindex.erase(it);
     299        }
     300    }
     301#ifdef DEBUG_SPAN_UPDATE
     302    qDebug() << index;
     303#endif
     304}
     305
     306/** \internal
     307* Cleans a subindex from to be deleted spans. The update argument is used
     308* to move the spans inside the subindex, in case their anchor changed.
     309* \return true if no span in this subindex starts at y, and should thus be deleted.
     310*/
     311bool QSpanCollection::cleanSpanSubIndex(QSpanCollection::SubIndex &subindex, int y, bool update)
     312{
     313    if (subindex.isEmpty())
     314        return true;
     315
     316    bool should_be_deleted = true;
     317    SubIndex::iterator it = subindex.end();
     318    do {
     319        --it;
     320        int x = -it.key();
     321        Span *span = it.value();
     322        if (span->will_be_deleted) {
     323            it = subindex.erase(it);
     324            continue;
     325        }
     326        if (update && span->m_left != x) {
     327            subindex.insert(-span->m_left, span);
     328            it = subindex.erase(it);
     329        }
     330        if (should_be_deleted && span->m_top == y)
     331            should_be_deleted = false;
     332    } while (it != subindex.begin());
     333
     334    return should_be_deleted;
     335}
     336
     337/** \internal
     338* Updates the span collection after row removal.
     339*/
     340void QSpanCollection::updateRemovedRows(int start, int end)
     341{
     342#ifdef DEBUG_SPAN_UPDATE
     343    qDebug() << Q_FUNC_INFO;
     344    qDebug() << start << end;
     345    qDebug() << index;
     346#endif
     347    if (spans.isEmpty())
     348        return;
     349
     350    SpanList spansToBeDeleted;
     351    int delta = end - start + 1;
     352#ifdef DEBUG_SPAN_UPDATE
     353    qDebug("Before");
     354#endif
     355    for (SpanList::iterator it = spans.begin(); it != spans.end(); ) {
     356        Span *span = *it;
     357#ifdef DEBUG_SPAN_UPDATE
     358        qDebug() << span << *span;
     359#endif
     360        if (span->m_bottom < start) {
     361            ++it;
     362            continue;
     363        }
     364        if (span->m_top < start) {
     365            if (span->m_bottom <= end)
     366                span->m_bottom = start - 1;
     367            else
     368                span->m_bottom -= delta;
     369        } else {
     370            if (span->m_bottom > end) {
     371                if (span->m_top <= end)
     372                    span->m_top = start;
     373                else
     374                    span->m_top -= delta;
     375                span->m_bottom -= delta;
     376            } else {
     377                span->will_be_deleted = true;
     378            }
     379        }
     380        if (span->m_top == span->m_bottom && span->m_left == span->m_right)
     381            span->will_be_deleted = true;
     382        if (span->will_be_deleted) {
     383            spansToBeDeleted.append(span);
     384            it = spans.erase(it);
     385        } else {
     386            ++it;
     387        }
     388    }
     389
     390#ifdef DEBUG_SPAN_UPDATE
     391    qDebug("After");
     392    foreach (QSpanCollection::Span *span, spans)
     393        qDebug() << span << *span;
     394#endif
     395    if (spans.isEmpty()) {
     396        qDeleteAll(spansToBeDeleted);
     397        index.clear();
     398        return;
     399    }
     400
     401    Index::iterator it_y = index.end();
     402    do {
     403        --it_y;
     404        int y = -it_y.key();
     405        SubIndex &subindex = it_y.value();
     406        if (y < start) {
     407            if (cleanSpanSubIndex(subindex, y))
     408                it_y = index.erase(it_y);
     409        } else if (y >= start && y <= end) {
     410            bool span_at_start = false;
     411            SubIndex spansToBeMoved;
     412            for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ++it) {
     413                Span *span = it.value();
     414                if (span->will_be_deleted)
     415                    continue;
     416                if (!span_at_start && span->m_top == start)
     417                    span_at_start = true;
     418                spansToBeMoved.insert(it.key(), span);
     419            }
     420
     421            if (y == start && span_at_start)
     422                subindex.clear();
     423            else
     424                it_y = index.erase(it_y);
     425
     426            if (span_at_start) {
     427                Index::iterator it_start;
     428                if (y == start)
     429                    it_start = it_y;
     430                else {
     431                    it_start = index.find(-start);
     432                    if (it_start == index.end())
     433                        it_start = index.insert(-start, SubIndex());
     434                }
     435                SubIndex &start_subindex = it_start.value();
     436                for (SubIndex::iterator it = spansToBeMoved.begin(); it != spansToBeMoved.end(); ++it)
     437                    start_subindex.insert(it.key(), it.value());
     438            }
     439        } else {
     440            if (y == end + 1) {
     441                Index::iterator it_top = index.find(-y + delta);
     442                if (it_top == index.end())
     443                    it_top = index.insert(-y + delta, SubIndex());
     444                for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ) {
     445                    Span *span = it.value();
     446                    if (!span->will_be_deleted)
     447                        it_top.value().insert(it.key(), span);
     448                    ++it;
     449                }
     450            } else {
     451                index.insert(-y + delta, subindex);
     452            }
     453            it_y = index.erase(it_y);
     454        }
     455    } while (it_y != index.begin());
     456
     457#ifdef DEBUG_SPAN_UPDATE
     458    qDebug() << index;
     459    qDebug("Deleted");
     460    foreach (QSpanCollection::Span *span, spansToBeDeleted)
     461        qDebug() << span << *span;
     462#endif
     463    qDeleteAll(spansToBeDeleted);
     464}
     465
     466/** \internal
     467* Updates the span collection after column removal.
     468*/
     469void QSpanCollection::updateRemovedColumns(int start, int end)
     470{
     471#ifdef DEBUG_SPAN_UPDATE
     472    qDebug() << Q_FUNC_INFO;
     473    qDebug() << start << end;
     474    qDebug() << index;
     475#endif
     476    if (spans.isEmpty())
     477        return;
     478
     479    SpanList toBeDeleted;
     480    int delta = end - start + 1;
     481#ifdef DEBUG_SPAN_UPDATE
     482    qDebug("Before");
     483#endif
     484    for (SpanList::iterator it = spans.begin(); it != spans.end(); ) {
     485        Span *span = *it;
     486#ifdef DEBUG_SPAN_UPDATE
     487        qDebug() << span << *span;
     488#endif
     489        if (span->m_right < start) {
     490            ++it;
     491            continue;
     492        }
     493        if (span->m_left < start) {
     494            if (span->m_right <= end)
     495                span->m_right = start - 1;
     496            else
     497                span->m_right -= delta;
     498        } else {
     499            if (span->m_right > end) {
     500                if (span->m_left <= end)
     501                    span->m_left = start;
     502                else
     503                    span->m_left -= delta;
     504                span->m_right -= delta;
     505            } else {
     506                span->will_be_deleted = true;
     507            }
     508        }
     509        if (span->m_top == span->m_bottom && span->m_left == span->m_right)
     510            span->will_be_deleted = true;
     511        if (span->will_be_deleted) {
     512            toBeDeleted.append(span);
     513            it = spans.erase(it);
     514        } else {
     515            ++it;
     516        }
     517    }
     518
     519#ifdef DEBUG_SPAN_UPDATE
     520    qDebug("After");
     521    foreach (QSpanCollection::Span *span, spans)
     522        qDebug() << span << *span;
     523#endif
     524    if (spans.isEmpty()) {
     525        qDeleteAll(toBeDeleted);
     526        index.clear();
     527        return;
     528    }
     529
     530    for (Index::iterator it_y = index.begin(); it_y != index.end(); ) {
     531        int y = -it_y.key();
     532        if (cleanSpanSubIndex(it_y.value(), y, true))
     533            it_y = index.erase(it_y);
     534        else
     535            ++it_y;
     536    }
     537
     538#ifdef DEBUG_SPAN_UPDATE
     539    qDebug() << index;
     540    qDebug("Deleted");
     541    foreach (QSpanCollection::Span *span, toBeDeleted)
     542        qDebug() << span << *span;
     543#endif
     544    qDeleteAll(toBeDeleted);
     545}
     546
     547#ifdef QT_BUILD_INTERNAL
     548/*!
     549  \internal
     550  Checks whether the span index structure is self-consistent, and consistent with the spans list.
     551*/
     552bool QSpanCollection::checkConsistency() const
     553{
     554    for (Index::const_iterator it_y = index.begin(); it_y != index.end(); ++it_y) {
     555        int y = -it_y.key();
     556        const SubIndex &subIndex = it_y.value();
     557        for (SubIndex::const_iterator it = subIndex.begin(); it != subIndex.end(); ++it) {
     558            int x = -it.key();
     559            Span *span = it.value();
     560            if (!spans.contains(span) || span->left() != x
     561                || y < span->top() || y > span->bottom())
     562                return false;
     563        }
     564    }
     565
     566    foreach (const Span *span, spans) {
     567        if (span->width() < 1 || span->height() < 1
     568            || (span->width() == 1 && span->height() == 1))
     569            return false;
     570        for (int y = span->top(); y <= span->bottom(); ++y) {
     571            Index::const_iterator it_y = index.find(-y);
     572            if (it_y == index.end()) {
     573                if (y == span->top())
     574                    return false;
     575                else
     576                    continue;
     577            }
     578            const SubIndex &subIndex = it_y.value();
     579            SubIndex::const_iterator it = subIndex.find(-span->left());
     580            if (it == subIndex.end() || it.value() != span)
     581                return false;
     582        }
     583    }
     584    return true;
     585}
     586#endif
    61587
    62588class QTableCornerButton : public QAbstractButton
     
    150676void QTableViewPrivate::setSpan(int row, int column, int rowSpan, int columnSpan)
    151677{
    152     if (row < 0 || column < 0 || rowSpan < 0 || columnSpan < 0)
     678    if (row < 0 || column < 0 || rowSpan <= 0 || columnSpan <= 0) {
     679        qWarning() << "QTableView::setSpan: invalid span given: (" << row << ',' << column << ',' << rowSpan << ',' << columnSpan << ')';
    153680        return;
    154     Span sp(row, column, rowSpan, columnSpan);
    155     QList<Span>::iterator it;
    156     for (it = spans.begin(); it != spans.end(); ++it) {
    157         if (((*it).top() == sp.top()) && ((*it).left() == sp.left())) {
    158             if ((sp.height() == 1) && (sp.width() == 1))
    159                 spans.erase(it); // "Implicit" span (1, 1), no need to store it
    160             else
    161                 *it = sp; // Replace
     681    }
     682    QSpanCollection::Span *sp = spans.spanAt(column, row);
     683    if (sp) {
     684        if (sp->top() != row || sp->left() != column) {
     685            qWarning() << "QTableView::setSpan: span cannot overlap";
    162686            return;
    163687        }
    164     }
    165     spans.append(sp);
     688        if (rowSpan == 1 && columnSpan == 1) {
     689            rowSpan = columnSpan = 0;
     690        }
     691        const int old_height = sp->height();
     692        sp->m_bottom = row + rowSpan - 1;
     693        sp->m_right = column + columnSpan - 1;
     694        spans.updateSpan(sp, old_height);
     695        return;
     696    } else if (rowSpan == 1 && columnSpan == 1) {
     697        qWarning() << "QTableView::setSpan: single cell span won't be added";
     698        return;
     699    }
     700    sp = new QSpanCollection::Span(row, column, rowSpan, columnSpan);
     701    spans.addSpan(sp);
    166702}
    167703
     
    170706  Gets the span information for the cell at (\a row, \a column).
    171707*/
    172 QTableViewPrivate::Span QTableViewPrivate::span(int row, int column) const
    173 {
    174     QList<Span>::const_iterator it;
    175     for (it = spans.constBegin(); it != spans.constEnd(); ++it) {
    176         Span span = *it;
    177         if (isInSpan(row, column, span))
    178             return span;
    179     }
    180     return Span(row, column, 1, 1);
     708QSpanCollection::Span QTableViewPrivate::span(int row, int column) const
     709{
     710    QSpanCollection::Span *sp = spans.spanAt(column, row);
     711    if (sp)
     712        return *sp;
     713
     714    return QSpanCollection::Span(row, column, 1, 1);
    181715}
    182716
     
    234768/*!
    235769  \internal
    236   Returns true if one or more spans intersect column \a column.
    237 */
    238 bool QTableViewPrivate::spansIntersectColumn(int column) const
    239 {
    240     QList<Span>::const_iterator it;
    241     for (it = spans.constBegin(); it != spans.constEnd(); ++it) {
    242         Span span = *it;
    243         if (spanContainsColumn(column, span.left(), span.width()))
    244             return true;
    245     }
    246     return false;
    247 }
    248 
    249 /*!
    250   \internal
    251   Returns true if one or more spans intersect row \a row.
    252 */
    253 bool QTableViewPrivate::spansIntersectRow(int row) const
    254 {
    255     QList<Span>::const_iterator it;
    256     for (it = spans.constBegin(); it != spans.constEnd(); ++it) {
    257         Span span = *it;
    258         if (spanContainsRow(row, span.top(), span.height()))
    259             return true;
    260     }
    261     return false;
    262 }
    263 
    264 /*!
    265   \internal
    266   Returns true if one or more spans intersect one or more columns.
    267 */
    268 bool QTableViewPrivate::spansIntersectColumns(const QList<int> &columns) const
    269 {
    270     QList<int>::const_iterator it;
    271     for (it = columns.constBegin(); it != columns.constEnd(); ++it) {
    272         if (spansIntersectColumn(*it))
    273             return true;
    274     }
    275     return false;
    276 }
    277 
    278 /*!
    279   \internal
    280   Returns true if one or more spans intersect one or more rows.
    281 */
    282 bool QTableViewPrivate::spansIntersectRows(const QList<int> &rows) const
    283 {
    284     QList<int>::const_iterator it;
    285     for (it = rows.constBegin(); it != rows.constEnd(); ++it) {
    286         if (spansIntersectRow(*it))
    287             return true;
    288     }
    289     return false;
    290 }
    291 
    292 /*!
    293   \internal
    294770  Returns the visual rect for the given \a span.
    295771*/
    296 QRect QTableViewPrivate::visualSpanRect(const Span &span) const
     772QRect QTableViewPrivate::visualSpanRect(const QSpanCollection::Span &span) const
    297773{
    298774    Q_Q(const QTableView);
     
    320796  \a drawn is a QBitArray of visualRowCountxvisualCoulumnCount which say if particular cell has been drawn
    321797*/
    322 void QTableViewPrivate::drawAndClipSpans(const QRect &area, QPainter *painter,
     798void QTableViewPrivate::drawAndClipSpans(const QRegion &area, QPainter *painter,
    323799                                         const QStyleOptionViewItemV4 &option, QBitArray *drawn,
    324800                                         int firstVisualRow, int lastVisualRow, int firstVisualColumn, int lastVisualColumn)
     
    327803    QRegion region = viewport->rect();
    328804
    329     QList<Span>::const_iterator it;
    330     for (it = spans.constBegin(); it != spans.constEnd(); ++it) {
    331         Span span = *it;
    332 
    333         int row = span.top();
    334         int col = span.left();
    335         if (isHidden(row, col))
    336             continue;
     805    QList<QSpanCollection::Span *> visibleSpans;
     806    bool sectionMoved = verticalHeader->sectionsMoved() || horizontalHeader->sectionsMoved();
     807
     808    if (!sectionMoved) {
     809        visibleSpans = spans.spansInRect(logicalColumn(firstVisualColumn), logicalRow(firstVisualRow),
     810                                         lastVisualColumn - firstVisualColumn + 1, lastVisualRow - firstVisualRow + 1);
     811    } else {
     812        QSet<QSpanCollection::Span *> set;
     813        for(int x = firstVisualColumn; x <= lastVisualColumn; x++)
     814            for(int y = firstVisualRow; y <= lastVisualRow; y++)
     815                set.insert(spans.spanAt(x,y));
     816        set.remove(0);
     817        visibleSpans = set.toList();
     818    }
     819
     820    foreach (QSpanCollection::Span *span, visibleSpans) {
     821        int row = span->top();
     822        int col = span->left();
    337823        QModelIndex index = model->index(row, col, root);
    338824        if (!index.isValid())
    339825            continue;
    340         QRect rect = visualSpanRect(span);
     826        QRect rect = visualSpanRect(*span);
    341827        rect.translate(scrollDelayOffset);
    342         if (!rect.intersects(area))
     828        if (!area.intersects(rect))
    343829            continue;
    344830        QStyleOptionViewItemV4 opt = option;
    345831        opt.rect = rect;
    346         alternateBase = alternatingColors && (span.top() & 1);
     832        alternateBase = alternatingColors && (span->top() & 1);
    347833        if (alternateBase)
    348834            opt.features |= QStyleOptionViewItemV2::Alternate;
     
    351837        drawCell(painter, opt, index);
    352838        region -= rect;
    353         for (int r = span.top(); r <= span.bottom(); ++r) {
     839        for (int r = span->top(); r <= span->bottom(); ++r) {
    354840            const int vr = visualRow(r);
    355841            if (vr < firstVisualRow || vr > lastVisualRow)
    356842                continue;
    357             for (int c = span.left(); c <= span.right(); ++c) {
     843            for (int c = span->left(); c <= span->right(); ++c) {
    358844                const int vc = visualColumn(c);
    359845                if (vc < firstVisualColumn  || vc > lastVisualColumn)
     
    366852    }
    367853    painter->setClipRegion(region);
     854}
     855
     856/*!
     857  \internal
     858  Updates spans after row insertion.
     859*/
     860void QTableViewPrivate::_q_updateSpanInsertedRows(const QModelIndex &parent, int start, int end)
     861{
     862    Q_UNUSED(parent)
     863    spans.updateInsertedRows(start, end);
     864}
     865
     866/*!
     867  \internal
     868  Updates spans after column insertion.
     869*/
     870void QTableViewPrivate::_q_updateSpanInsertedColumns(const QModelIndex &parent, int start, int end)
     871{
     872    Q_UNUSED(parent)
     873    spans.updateInsertedColumns(start, end);
     874}
     875
     876/*!
     877  \internal
     878  Updates spans after row removal.
     879*/
     880void QTableViewPrivate::_q_updateSpanRemovedRows(const QModelIndex &parent, int start, int end)
     881{
     882    Q_UNUSED(parent)
     883    spans.updateRemovedRows(start, end);
     884}
     885
     886/*!
     887  \internal
     888  Updates spans after column removal.
     889*/
     890void QTableViewPrivate::_q_updateSpanRemovedColumns(const QModelIndex &parent, int start, int end)
     891{
     892    Q_UNUSED(parent)
     893    spans.updateRemovedColumns(start, end);
    368894}
    369895
     
    398924    }
    399925
    400     if (opt.features & QStyleOptionViewItemV2::Alternate)
    401         painter->fillRect(opt.rect, opt.palette.brush(QPalette::AlternateBase));
     926    q->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, q);
    402927
    403928    if (const QWidget *widget = editorForIndex(index).editor) {
     
    419944    \ingroup model-view
    420945    \ingroup advanced
    421     \mainclass
     946
    422947
    423948    A QTableView implements a table view that displays items from a
     
    5401065{
    5411066    Q_D(QTableView);
     1067    if (model == d->model)
     1068        return;
     1069    //let's disconnect from the old model
     1070    if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
     1071        disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
     1072                this, SLOT(_q_updateSpanInsertedRows(QModelIndex,int,int)));
     1073        disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
     1074                this, SLOT(_q_updateSpanInsertedColumns(QModelIndex,int,int)));
     1075        disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
     1076                this, SLOT(_q_updateSpanRemovedRows(QModelIndex,int,int)));
     1077        disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
     1078                this, SLOT(_q_updateSpanRemovedColumns(QModelIndex,int,int)));
     1079    }
     1080    if (model) { //and connect to the new one
     1081        connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
     1082                this, SLOT(_q_updateSpanInsertedRows(QModelIndex,int,int)));
     1083        connect(model, SIGNAL(columnsInserted(QModelIndex,int,int)),
     1084                this, SLOT(_q_updateSpanInsertedColumns(QModelIndex,int,int)));
     1085        connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
     1086                this, SLOT(_q_updateSpanRemovedRows(QModelIndex,int,int)));
     1087        connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
     1088                this, SLOT(_q_updateSpanRemovedColumns(QModelIndex,int,int)));
     1089    }
    5421090    d->verticalHeader->setModel(model);
    5431091    d->horizontalHeader->setModel(model);
     
    6261174            this, SLOT(resizeColumnToContents(int)));
    6271175    connect(d->horizontalHeader, SIGNAL(geometriesChanged()), this, SLOT(updateGeometries()));
     1176
     1177    //update the sorting enabled states on the new header
     1178    setSortingEnabled(d->sortingEnabled);
    6281179}
    6291180
     
    7541305    uint y = verticalHeader->length() - verticalHeader->offset() - 1;
    7551306
    756     QVector<QRect> rects = event->region().rects();
     1307    const QRegion region = event->region().translated(offset);
     1308    const QVector<QRect> rects = region.rects();
    7571309
    7581310    //firstVisualRow is the visual index of the first visible row.  lastVisualRow is the visual index of the last visible Row.
     
    7741326    QBitArray drawn((lastVisualRow - firstVisualRow + 1) * (lastVisualColumn - firstVisualColumn + 1));
    7751327
     1328    if (d->hasSpans()) {
     1329        d->drawAndClipSpans(region, &painter, option, &drawn,
     1330                             firstVisualRow, lastVisualRow, firstVisualColumn, lastVisualColumn);
     1331    }
     1332
    7761333    for (int i = 0; i < rects.size(); ++i) {
    7771334        QRect dirtyArea = rects.at(i);
    778         dirtyArea.translate(offset);
    7791335        dirtyArea.setBottom(qMin(dirtyArea.bottom(), int(y)));
    7801336        if (rightToLeft) {
     
    7831339            dirtyArea.setRight(qMin(dirtyArea.right(), int(x)));
    7841340        }
    785 
    786         if (d->hasSpans())
    787             d->drawAndClipSpans(dirtyArea, &painter, option, &drawn,
    788                                 firstVisualRow, lastVisualRow, firstVisualColumn, lastVisualColumn);
    7891341
    7901342        // get the horizontal start and end visual sections
     
    9141466    if (r >= 0 && c >= 0) {
    9151467        if (d->hasSpans()) {
    916             QTableViewPrivate::Span span = d->span(r, c);
     1468            QSpanCollection::Span span = d->span(r, c);
    9171469            r = span.top();
    9181470            c = span.left();
     
    9861538        while (isRowHidden(d->logicalRow(row)) && row < bottom)
    9871539            ++row;
     1540        d->visualCursor = QPoint(column, row);
    9881541        return d->model->index(d->logicalRow(row), d->logicalColumn(column), d->root);
    9891542    }
    9901543
    991     int visualRow = d->visualRow(current.row());
     1544    // Update visual cursor if current index has changed.
     1545    QPoint visualCurrent(d->visualColumn(current.column()), d->visualRow(current.row()));
     1546    if (visualCurrent != d->visualCursor) {
     1547        if (d->hasSpans()) {
     1548            QSpanCollection::Span span = d->span(current.row(), current.column());
     1549            if (span.top() > d->visualCursor.y() || d->visualCursor.y() > span.bottom()
     1550                || span.left() > d->visualCursor.x() || d->visualCursor.x() > span.right())
     1551                d->visualCursor = visualCurrent;
     1552        } else {
     1553            d->visualCursor = visualCurrent;
     1554        }
     1555    }
     1556
     1557    int visualRow = d->visualCursor.y();
     1558    if (visualRow > bottom)
     1559        visualRow = bottom;
    9921560    Q_ASSERT(visualRow != -1);
    993     int visualColumn = d->visualColumn(current.column());
     1561    int visualColumn = d->visualCursor.x();
     1562    if (visualColumn > right)
     1563        visualColumn = right;
    9941564    Q_ASSERT(visualColumn != -1);
    9951565
     
    10021572
    10031573    switch (cursorAction) {
    1004     case MoveUp:
     1574    case MoveUp: {
     1575        int originalRow = visualRow;
    10051576#ifdef QT_KEYPAD_NAVIGATION
    10061577        if (QApplication::keypadNavigationEnabled() && visualRow == 0)
    10071578            visualRow = d->visualRow(model()->rowCount() - 1) + 1;
     1579            // FIXME? visualRow = bottom + 1;
    10081580#endif
    1009         --visualRow;
    1010         while (visualRow > 0 && d->isVisualRowHiddenOrDisabled(visualRow, visualColumn))
     1581        int r = d->logicalRow(visualRow);
     1582        int c = d->logicalColumn(visualColumn);
     1583        if (r != -1 && d->hasSpans()) {
     1584            QSpanCollection::Span span = d->span(r, c);
     1585            if (span.width() > 1 || span.height() > 1)
     1586                visualRow = d->visualRow(span.top());
     1587        }
     1588        while (visualRow >= 0) {
    10111589            --visualRow;
     1590            r = d->logicalRow(visualRow);
     1591            c = d->logicalColumn(visualColumn);
     1592            if (r == -1 || (!isRowHidden(r) && d->isCellEnabled(r, c)))
     1593                break;
     1594        }
     1595        if (visualRow < 0)
     1596            visualRow = originalRow;
     1597        break;
     1598    }
     1599    case MoveDown: {
     1600        int originalRow = visualRow;
    10121601        if (d->hasSpans()) {
    1013             int row = d->logicalRow(visualRow);
    1014             QTableViewPrivate::Span span = d->span(row, current.column());
    1015             visualRow = d->visualRow(span.top());
    1016             visualColumn = d->visualColumn(span.left());
    1017         }
    1018         break;
    1019     case MoveDown:
    1020         if (d->hasSpans()) {
    1021             QTableViewPrivate::Span span = d->span(current.row(), current.column());
     1602            QSpanCollection::Span span = d->span(current.row(), current.column());
    10221603            visualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height()));
    10231604        }
     
    10261607            visualRow = -1;
    10271608#endif
    1028         ++visualRow;
    1029         while (visualRow < bottom && d->isVisualRowHiddenOrDisabled(visualRow, visualColumn))
     1609        int r = d->logicalRow(visualRow);
     1610        int c = d->logicalColumn(visualColumn);
     1611        if (r != -1 && d->hasSpans()) {
     1612            QSpanCollection::Span span = d->span(r, c);
     1613            if (span.width() > 1 || span.height() > 1)
     1614                visualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height()));
     1615        }
     1616        while (visualRow <= bottom) {
    10301617            ++visualRow;
    1031         if (d->hasSpans()) {
    1032             int row = d->logicalRow(visualRow);
    1033             QTableViewPrivate::Span span = d->span(row, current.column());
    1034             visualColumn = d->visualColumn(span.left());
    1035         }
     1618            r = d->logicalRow(visualRow);
     1619            c = d->logicalColumn(visualColumn);
     1620            if (r == -1 || (!isRowHidden(r) && d->isCellEnabled(r, c)))
     1621                break;
     1622        }
     1623        if (visualRow > bottom)
     1624            visualRow = originalRow;
    10361625        break;
    1037     case MovePrevious: {
    1038         int left = 0;
    1039         while (d->isVisualColumnHiddenOrDisabled(visualRow, left) && left < right)
    1040             ++left;
    1041         if (visualColumn == left) {
    1042             visualColumn = right;
    1043             int top = 0;
    1044             while (top < bottom && d->isVisualRowHiddenOrDisabled(top, visualColumn))
    1045                 ++top;
    1046             if (visualRow == top)
     1626    }
     1627    case MovePrevious:
     1628    case MoveLeft: {
     1629        int originalRow = visualRow;
     1630        int originalColumn = visualColumn;
     1631        bool firstTime = true;
     1632        bool looped = false;
     1633        bool wrapped = false;
     1634        do {
     1635            int r = d->logicalRow(visualRow);
     1636            int c = d->logicalColumn(visualColumn);
     1637            if (firstTime && c != -1 && d->hasSpans()) {
     1638                firstTime = false;
     1639                QSpanCollection::Span span = d->span(r, c);
     1640                if (span.width() > 1 || span.height() > 1)
     1641                    visualColumn = d->visualColumn(span.left());
     1642            }
     1643            while (visualColumn >= 0) {
     1644                --visualColumn;
     1645                r = d->logicalRow(visualRow);
     1646                c = d->logicalColumn(visualColumn);
     1647                if (r == -1 || c == -1 || (!isRowHidden(r) && !isColumnHidden(c) && d->isCellEnabled(r, c)))
     1648                    break;
     1649                if (wrapped && (originalRow < visualRow || (originalRow == visualRow && originalColumn <= visualColumn))) {
     1650                    looped = true;
     1651                    break;
     1652                }
     1653            }
     1654            if (cursorAction == MoveLeft || visualColumn >= 0)
     1655                break;
     1656            visualColumn = right + 1;
     1657            if (visualRow == 0) {
     1658                wrapped = true;
    10471659                visualRow = bottom;
    1048             else
     1660            } else {
    10491661                --visualRow;
    1050             while (visualRow > 0 && d->isVisualRowHiddenOrDisabled(visualRow, visualColumn))
    1051                 --visualRow;
    1052             break;
    1053         } // else MoveLeft
    1054     }
    1055     case MoveLeft:
    1056         --visualColumn;
    1057         while (visualColumn > 0 && d->isVisualColumnHiddenOrDisabled(visualRow, visualColumn))
    1058             --visualColumn;
    1059         if (d->hasSpans()) {
    1060             int column = d->logicalColumn(visualColumn);
    1061             QTableViewPrivate::Span span = d->span(current.row(), column);
    1062             visualRow = d->visualRow(span.top());
    1063             visualColumn = d->visualColumn(span.left());
    1064         }
     1662            }
     1663        } while (!looped);
     1664        if (visualColumn < 0)
     1665            visualColumn = originalColumn;
    10651666        break;
     1667    }
    10661668    case MoveNext:
    1067         if (visualColumn == right) {
    1068             visualColumn = 0;
    1069             while (visualColumn < right && d->isVisualColumnHiddenOrDisabled(visualRow, visualColumn))
     1669    case MoveRight: {
     1670        int originalRow = visualRow;
     1671        int originalColumn = visualColumn;
     1672        bool firstTime = true;
     1673        bool looped = false;
     1674        bool wrapped = false;
     1675        do {
     1676            int r = d->logicalRow(visualRow);
     1677            int c = d->logicalColumn(visualColumn);
     1678            if (firstTime && c != -1 && d->hasSpans()) {
     1679                firstTime = false;
     1680                QSpanCollection::Span span = d->span(r, c);
     1681                if (span.width() > 1 || span.height() > 1)
     1682                    visualColumn = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width()));
     1683            }
     1684            while (visualColumn <= right) {
    10701685                ++visualColumn;
    1071             if (visualRow == bottom)
     1686                r = d->logicalRow(visualRow);
     1687                c = d->logicalColumn(visualColumn);
     1688                if (r == -1 || c == -1 || (!isRowHidden(r) && !isColumnHidden(c) && d->isCellEnabled(r, c)))
     1689                    break;
     1690                if (wrapped && (originalRow > visualRow || (originalRow == visualRow && originalColumn >= visualColumn))) {
     1691                    looped = true;
     1692                    break;
     1693                }
     1694            }
     1695            if (cursorAction == MoveRight || visualColumn <= right)
     1696                break;
     1697            visualColumn = -1;
     1698            if (visualRow == bottom) {
     1699                wrapped = true;
    10721700                visualRow = 0;
    1073             else
     1701            } else {
    10741702                ++visualRow;
    1075             while (visualRow < bottom && d->isVisualRowHiddenOrDisabled(visualRow, visualColumn))
    1076                 ++visualRow;
    1077             break;
    1078         } // else MoveRight
    1079     case MoveRight:
    1080         if (d->hasSpans()) {
    1081             QTableViewPrivate::Span span = d->span(current.row(), current.column());
    1082             visualColumn = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width()));
    1083         }
    1084         ++visualColumn;
    1085         while (visualColumn < right && d->isVisualColumnHiddenOrDisabled(visualRow, visualColumn))
    1086             ++visualColumn;
    1087         if (d->hasSpans()) {
    1088             int column = d->logicalColumn(visualColumn);
    1089             QTableViewPrivate::Span span = d->span(current.row(), column);
    1090             visualRow = d->visualRow(span.top());
    1091         }
     1703            }
     1704        } while (!looped);
     1705        if (visualColumn > right)
     1706            visualColumn = originalColumn;
    10921707        break;
     1708    }
    10931709    case MoveHome:
    10941710        visualColumn = 0;
     
    11071723        break;
    11081724    case MovePageUp: {
    1109         int top = 0;
    1110         while (top < bottom && d->isVisualRowHiddenOrDisabled(top, visualColumn))
    1111             ++top;
    1112         int newRow = qMax(rowAt(visualRect(current).top() - d->viewport->height()), top);
    1113         return d->model->index(qBound(0, newRow, bottom), current.column(), d->root);
     1725        int newRow = rowAt(visualRect(current).top() - d->viewport->height());
     1726        if (newRow == -1)
     1727            newRow = d->logicalRow(0);
     1728        return d->model->index(newRow, current.column(), d->root);
    11141729    }
    11151730    case MovePageDown: {
    1116         int newRow = qMin(rowAt(visualRect(current).bottom() + d->viewport->height()), bottom);
    1117         if (newRow < 0)
    1118             newRow = bottom;
    1119         return d->model->index(qBound(0, newRow, bottom), current.column(), d->root);
     1731        int newRow = rowAt(visualRect(current).bottom() + d->viewport->height());
     1732        if (newRow == -1)
     1733            newRow = d->logicalRow(bottom);
     1734        return d->model->index(newRow, current.column(), d->root);
    11201735    }}
    11211736
     1737    d->visualCursor = QPoint(visualColumn, visualRow);
    11221738    int logicalRow = d->logicalRow(visualRow);
    11231739    int logicalColumn = d->logicalColumn(visualColumn);
     
    11261742
    11271743    QModelIndex result = d->model->index(logicalRow, logicalColumn, d->root);
    1128     if (!isIndexHidden(result) && d->isIndexEnabled(result))
    1129         return d->model->index(logicalRow, logicalColumn, d->root);
     1744    if (!d->isRowHidden(logicalRow) && !d->isColumnHidden(logicalColumn) && d->isIndexEnabled(result))
     1745        return result;
    11301746
    11311747    return QModelIndex();
     
    11621778        do {
    11631779            expanded = false;
    1164             QList<QTableViewPrivate::Span>::const_iterator it;
    1165             for (it = d->spans.constBegin(); it != d->spans.constEnd(); ++it) {
    1166                 QTableViewPrivate::Span span = *it;
     1780            foreach (QSpanCollection::Span *it, d->spans.spans) {
     1781                const QSpanCollection::Span &span = *it;
    11671782                int t = d->visualRow(span.top());
    11681783                int l = d->visualColumn(span.left());
     
    12541869    bool horizontalMoved = horizontalHeader()->sectionsMoved();
    12551870
    1256     if ((verticalMoved && horizontalMoved) || d->hasSpans()) {
     1871    if ((verticalMoved && horizontalMoved) || (d->hasSpans() && (verticalMoved || horizontalMoved))) {
    12571872        for (int i = 0; i < selection.count(); ++i) {
    12581873            QItemSelectionRange range = selection.at(i);
     
    12971912                continue;
    12981913            d->trimHiddenSelections(&range);
    1299             QRect tl = visualRect(range.topLeft());
    1300             QRect br = visualRect(range.bottomRight());
    1301             selectionRegion += QRegion(tl|br);
     1914
     1915            const int rtop = rowViewportPosition(range.top());
     1916            const int rbottom = rowViewportPosition(range.bottom()) + rowHeight(range.bottom());
     1917            const int rleft = columnViewportPosition(range.left());
     1918            const int rright = columnViewportPosition(range.right()) + columnWidth(range.right());
     1919            selectionRegion += QRect(QPoint(rleft, rtop), QPoint(rright, rbottom));
     1920            if (d->hasSpans()) {
     1921                foreach (QSpanCollection::Span *s,
     1922                         d->spans.spansInRect(range.left(), range.top(), range.width(), range.height())) {
     1923                    if (range.contains(s->top(), s->left(), range.parent()))
     1924                        selectionRegion += d->visualSpanRect(*s);
     1925                }
     1926            }
    13021927        }
    13031928    }
     
    14292054        }
    14302055    }
     2056    columnsInViewport = qMax(columnsInViewport, 1); //there must be always at least 1 column
     2057
    14312058    if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
    14322059        const int visibleColumns = columnCount - d->horizontalHeader->hiddenSectionCount();
     
    14552082        }
    14562083    }
     2084    rowsInViewport = qMax(rowsInViewport, 1); //there must be always at least 1 row
     2085
    14572086    if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
    14582087        const int visibleRows = rowCount - d->verticalHeader->hiddenSectionCount();
     
    14922121    if (!model())
    14932122        return -1;
     2123
     2124    ensurePolished();
    14942125
    14952126    int left = qMax(0, columnAt(0));
     
    15492180    if (!model())
    15502181        return -1;
     2182
     2183    ensurePolished();
    15512184
    15522185    int top = qMax(0, rowAt(0));
     
    17272360    \brief whether sorting is enabled
    17282361
    1729     If this property is true, sorting is enabled for the table; if the
    1730     property is false, sorting is not enabled. The default value is false.
     2362    If this property is true, sorting is enabled for the table.  If
     2363    this property is false, sorting is not enabled. The default value
     2364    is false.
     2365
     2366    \note. Setting the property to true with setSortingEnabled()
     2367    immediately triggers a call to sortByColumn() with the current
     2368    sort section and order.
    17312369
    17322370    \sa sortByColumn()
    17332371*/
    17342372
     2373/*!
     2374  If \a enabled true enables sorting for the table and immediately
     2375  trigger a call to sortByColumn() with the current sort section and
     2376  order
     2377 */
    17352378void QTableView::setSortingEnabled(bool enable)
    17362379{
     
    17442387                   this, SLOT(selectColumn(int)));
    17452388        connect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
    1746                 this, SLOT(sortByColumn(int)));
     2389                this, SLOT(sortByColumn(int)), Qt::UniqueConnection);
    17472390        sortByColumn(horizontalHeader()->sortIndicatorSection(),
    17482391                     horizontalHeader()->sortIndicatorOrder());
    17492392    } else {
    17502393        connect(d->horizontalHeader, SIGNAL(sectionEntered(int)),
    1751                 this, SLOT(_q_selectColumn(int)));
     2394                this, SLOT(_q_selectColumn(int)), Qt::UniqueConnection);
    17522395        connect(horizontalHeader(), SIGNAL(sectionPressed(int)),
    1753                 this, SLOT(selectColumn(int)));
     2396                this, SLOT(selectColumn(int)), Qt::UniqueConnection);
    17542397        disconnect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
    17552398                   this, SLOT(sortByColumn(int)));
     
    18692512{
    18702513    Q_D(const QTableView);
    1871     if (!d->isIndexValid(index) || index.parent() != d->root || isIndexHidden(index) )
     2514    if (!d->isIndexValid(index) || index.parent() != d->root
     2515        || (!d->hasSpans() && isIndexHidden(index)))
    18722516        return QRect();
    18732517
     
    18752519
    18762520    if (d->hasSpans()) {
    1877         QTableViewPrivate::Span span = d->span(index.row(), index.column());
     2521        QSpanCollection::Span span = d->span(index.row(), index.column());
    18782522        return d->visualSpanRect(span);
    18792523    }
     
    19042548        return;
    19052549
    1906     QTableViewPrivate::Span span;
     2550    QSpanCollection::Span span;
    19072551    if (d->hasSpans())
    19082552        span = d->span(index.row(), index.column());
     
    19372581            int hiddenSections = 0;
    19382582            if (d->horizontalHeader->sectionsHidden()) {
    1939                 for (int s = horizontalIndex; s >= 0; --s) {
     2583                for (int s = horizontalIndex - 1; s >= 0; --s) {
    19402584                    int column = d->horizontalHeader->logicalIndex(s);
    19412585                    if (d->horizontalHeader->isSectionHidden(column))
     
    19922636            int hiddenSections = 0;
    19932637            if (d->verticalHeader->sectionsHidden()) {
    1994                 for (int s = verticalIndex; s >= 0; --s) {
     2638                for (int s = verticalIndex - 1; s >= 0; --s) {
    19952639                    int row = d->verticalHeader->logicalIndex(s);
    19962640                    if (d->verticalHeader->isSectionHidden(row))
     
    20112655    }
    20122656
    2013     d->setDirtyRegion(visualRect(index));
     2657    update(index);
    20142658}
    20152659
     
    20592703        int viewportHeight = d->viewport->height();
    20602704        int viewportWidth = d->viewport->width();
    2061         if (d->hasSpans() && d->spansIntersectColumns(d->columnsToUpdate)) {
     2705        if (d->hasSpans()) {
    20622706            rect = QRect(0, 0, viewportWidth, viewportHeight);
    20632707        } else {
     
    20842728        int viewportWidth = d->viewport->width();
    20852729        int top;
    2086         if (d->hasSpans() && d->spansIntersectRows(d->rowsToUpdate)) {
     2730        if (d->hasSpans()) {
    20872731            top = 0;
    20882732        } else {
     
    21152759    int logicalOldIndex = d->verticalHeader->logicalIndex(oldIndex);
    21162760    int logicalNewIndex = d->verticalHeader->logicalIndex(newIndex);
    2117     if (d->hasSpans() && (d->spansIntersectRow(logicalOldIndex) || d->spansIntersectRow(logicalNewIndex))) {
     2761    if (d->hasSpans()) {
    21182762        d->viewport->update();
    21192763    } else {
     
    21432787    int logicalOldIndex = d->horizontalHeader->logicalIndex(oldIndex);
    21442788    int logicalNewIndex = d->horizontalHeader->logicalIndex(newIndex);
    2145     if (d->hasSpans() && (d->spansIntersectColumn(logicalOldIndex) || d->spansIntersectColumn(logicalNewIndex))) {
     2789    if (d->hasSpans()) {
    21462790        d->viewport->update();
    21472791    } else {
     
    23262970        return true;
    23272971    if (d->hasSpans()) {
    2328         QTableViewPrivate::Span span = d->span(index.row(), index.column());
     2972        QSpanCollection::Span span = d->span(index.row(), index.column());
    23292973        return !((span.top() == index.row()) && (span.left() == index.column()));
    23302974    }
     
    24173061        QItemSelectionModel::SelectionFlags command = q->selectionCommand(index);
    24183062        selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
    2419         if ((!(command & QItemSelectionModel::Current) && anchor)
     3063        if ((anchor && !(command & QItemSelectionModel::Current))
    24203064            || (q->selectionMode() == QTableView::SingleSelection))
    24213065            rowSectionAnchor = row;
     3066
     3067        if (q->selectionMode() != QTableView::SingleSelection
     3068            && command.testFlag(QItemSelectionModel::Toggle)) {
     3069            if (anchor)
     3070                ctrlDragSelectionFlag = verticalHeader->selectionModel()->selectedRows().contains(index)
     3071                                    ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
     3072            command &= ~QItemSelectionModel::Toggle;
     3073            command |= ctrlDragSelectionFlag;
     3074            if (!anchor)
     3075                command |= QItemSelectionModel::Current;
     3076        }
     3077
    24223078        QModelIndex tl = model->index(qMin(rowSectionAnchor, row), 0, root);
    24233079        QModelIndex br = model->index(qMax(rowSectionAnchor, row), model->columnCount(root) - 1, root);
     
    24433099        QItemSelectionModel::SelectionFlags command = q->selectionCommand(index);
    24443100        selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
    2445         if ((!(command & QItemSelectionModel::Current) && anchor)
     3101        if ((anchor && !(command & QItemSelectionModel::Current))
    24463102            || (q->selectionMode() == QTableView::SingleSelection))
    24473103            columnSectionAnchor = column;
     3104
     3105        if (q->selectionMode() != QTableView::SingleSelection
     3106            && command.testFlag(QItemSelectionModel::Toggle)) {
     3107            if (anchor)
     3108                ctrlDragSelectionFlag = horizontalHeader->selectionModel()->selectedColumns().contains(index)
     3109                                    ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
     3110            command &= ~QItemSelectionModel::Toggle;
     3111            command |= ctrlDragSelectionFlag;
     3112            if (!anchor)
     3113                command |= QItemSelectionModel::Current;
     3114        }
     3115
    24483116        QModelIndex tl = model->index(0, qMin(columnSectionAnchor, column), root);
    24493117        QModelIndex br = model->index(model->rowCount(root) - 1,
  • trunk/src/gui/itemviews/qtableview.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    183183    Q_PRIVATE_SLOT(d_func(), void _q_selectRow(int))
    184184    Q_PRIVATE_SLOT(d_func(), void _q_selectColumn(int))
     185    Q_PRIVATE_SLOT(d_func(), void _q_updateSpanInsertedRows(QModelIndex,int,int))
     186    Q_PRIVATE_SLOT(d_func(), void _q_updateSpanInsertedColumns(QModelIndex,int,int))
     187    Q_PRIVATE_SLOT(d_func(), void _q_updateSpanRemovedRows(QModelIndex,int,int))
     188    Q_PRIVATE_SLOT(d_func(), void _q_updateSpanRemovedColumns(QModelIndex,int,int))
    185189};
    186190
  • trunk/src/gui/itemviews/qtableview_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5454//
    5555
     56#include <QtCore/QList>
     57#include <QtCore/QLinkedList>
     58#include <QtCore/QMap>
     59#include <QtCore/QSet>
     60#include <QtCore/QDebug>
    5661#include "private/qabstractitemview_p.h"
    5762
     
    5964
    6065QT_BEGIN_NAMESPACE
     66
     67/** \internal
     68*
     69* This is a list of span with a binary index to look up quickly a span at a certain index.
     70*
     71* The index is a map of map.
     72* spans are mentaly divided into sub spans so that the start of any subspans doesn't overlap
     73* with any other subspans. There is no real representation of the subspans.
     74* The key of the first map is the row where the subspan starts, the value of the first map is
     75* a list (map) of all subspans that starts at the same row.  It is indexed with its row
     76*/
     77class Q_AUTOTEST_EXPORT QSpanCollection
     78{
     79public:
     80    struct Span
     81    {
     82        int m_top;
     83        int m_left;
     84        int m_bottom;
     85        int m_right;
     86        bool will_be_deleted;
     87        Span()
     88        : m_top(-1), m_left(-1), m_bottom(-1), m_right(-1), will_be_deleted(false) { }
     89        Span(int row, int column, int rowCount, int columnCount)
     90        : m_top(row), m_left(column), m_bottom(row+rowCount-1), m_right(column+columnCount-1), will_be_deleted(false) { }
     91        inline int top() const { return m_top; }
     92        inline int left() const { return m_left; }
     93        inline int bottom() const { return m_bottom; }
     94        inline int right() const { return m_right; }
     95        inline int height() const { return m_bottom - m_top + 1; }
     96        inline int width() const { return m_right - m_left + 1; }
     97    };
     98
     99    ~QSpanCollection()
     100    {
     101        qDeleteAll(spans);
     102    }
     103
     104    void addSpan(Span *span);
     105    void updateSpan(Span *span, int old_height);
     106    Span *spanAt(int x, int y) const;
     107    void clear();
     108    QList<Span *> spansInRect(int x, int y, int w, int h) const;
     109
     110    void updateInsertedRows(int start, int end);
     111    void updateInsertedColumns(int start, int end);
     112    void updateRemovedRows(int start, int end);
     113    void updateRemovedColumns(int start, int end);
     114
     115#ifdef QT_BUILD_INTERNAL
     116    bool checkConsistency() const;
     117#endif
     118
     119    typedef QLinkedList<Span *> SpanList;
     120    SpanList spans; //lists of all spans
     121private:
     122    //the indexes are negative so the QMap::lowerBound do what i need.
     123    typedef QMap<int, Span *> SubIndex;
     124    typedef QMap<int, SubIndex> Index;
     125    Index index;
     126
     127    bool cleanSpanSubIndex(SubIndex &subindex, int end, bool update = false);
     128};
     129
     130Q_DECLARE_TYPEINFO ( QSpanCollection::Span, Q_MOVABLE_TYPE);
     131
    61132
    62133class QTableViewPrivate : public QAbstractItemViewPrivate
     
    69140          columnResizeTimerID(0), rowResizeTimerID(0),
    70141          horizontalHeader(0), verticalHeader(0),
    71           sortingEnabled(false), geometryRecursionBlock(false)
     142          sortingEnabled(false), geometryRecursionBlock(false),
     143          visualCursor(QPoint())
    72144 {
    73145    wrapItemText = true;
     
    99171    int sectionSpanSize(const QHeaderView *header, int logical, int span) const;
    100172    bool spanContainsSection(const QHeaderView *header, int logical, int spanLogical, int span) const;
    101     bool spansIntersectColumn(int column) const;
    102     bool spansIntersectRow(int row) const;
    103     bool spansIntersectColumns(const QList<int> &columns) const;
    104     bool spansIntersectRows(const QList<int> &rows) const;
    105     void drawAndClipSpans(const QRect &area, QPainter *painter,
     173    void drawAndClipSpans(const QRegion &area, QPainter *painter,
    106174                          const QStyleOptionViewItemV4 &option, QBitArray *drawn,
    107175                          int firstVisualRow, int lastVisualRow, int firstVisualColumn, int lastVisualColumn);
     
    121189    bool sortingEnabled;
    122190    bool geometryRecursionBlock;
    123 
    124     struct Span
    125     {
    126         int m_top;
    127         int m_left;
    128         int m_bottom;
    129         int m_right;
    130         Span()
    131             : m_top(-1), m_left(-1), m_bottom(-1), m_right(-1) { }
    132         Span(int row, int column, int rowCount, int columnCount)
    133             : m_top(row), m_left(column), m_bottom(row+rowCount-1), m_right(column+columnCount-1) { }
    134         inline int top() const { return m_top; }
    135         inline int left() const { return m_left; }
    136         inline int bottom() const { return m_bottom; }
    137         inline int right() const { return m_right; }
    138         inline int height() const { return m_bottom - m_top + 1; }
    139         inline int width() const { return m_right - m_left + 1; }
    140     };
    141     QList<Span> spans;
     191    QPoint visualCursor;  // (Row,column) cell coordinates to track through span navigation.
     192
     193    QSpanCollection spans;
    142194
    143195    void setSpan(int row, int column, int rowSpan, int columnSpan);
    144     Span span(int row, int column) const;
     196    QSpanCollection::Span span(int row, int column) const;
    145197    inline int rowSpan(int row, int column) const {
    146198        return span(row, column).height();
     
    150202    }
    151203    inline bool hasSpans() const {
    152         return !spans.isEmpty();
    153     }
    154     inline bool spanContainsRow(int row, int spanRow, int span) const {
    155         return spanContainsSection(verticalHeader, row, spanRow, span);
    156     }
    157     inline bool spanContainsColumn(int column, int spanColumn, int span) const {
    158         return spanContainsSection(horizontalHeader, column, spanColumn, span);
    159     }
    160     inline bool isInSpan(int row, int column, const Span &span) const {
    161         return spanContainsRow(row, span.top(), span.height())
    162             && spanContainsColumn(column, span.left(), span.width());
     204        return !spans.spans.isEmpty();
    163205    }
    164206    inline int rowSpanHeight(int row, int span) const {
     
    195237    }
    196238
    197     QRect visualSpanRect(const Span &span) const;
     239    QRect visualSpanRect(const QSpanCollection::Span &span) const;
    198240
    199241    void _q_selectRow(int row);
     
    202244    void selectRow(int row, bool anchor);
    203245    void selectColumn(int column, bool anchor);
     246
     247    void _q_updateSpanInsertedRows(const QModelIndex &parent, int start, int end);
     248    void _q_updateSpanInsertedColumns(const QModelIndex &parent, int start, int end);
     249    void _q_updateSpanRemovedRows(const QModelIndex &parent, int start, int end);
     250    void _q_updateSpanRemovedColumns(const QModelIndex &parent, int start, int end);
    204251};
    205252
  • trunk/src/gui/itemviews/qtablewidget.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    227227        itm->d->id = -1;
    228228        tableItems[i] = 0;
     229        QModelIndex ind = index(itm);
     230        emit dataChanged(ind, ind);
    229231    }
    230232    return itm;
     
    531533}
    532534
    533 bool QTableModel::canConvertToDouble(const QVariant &value)
    534 {
    535     switch (value.type()) {
    536     case QVariant::Bool:
    537     case QVariant::Int:
    538     case QVariant::UInt:
    539     case QVariant::LongLong:
    540     case QVariant::ULongLong:
    541     case QVariant::Double:
    542     case QVariant::Char:
    543         return true;
    544     default:
    545         return false;
    546     }
    547     return false;
    548 }
    549 
    550 
    551535/*
    552536  \internal
     
    588572        vit = sortedInsertionIterator(vit, colItems.end(), order, item);
    589573        int newRow = qMax((int)(vit - colItems.begin()), 0);
     574        if ((newRow < oldRow) && !(*item < *colItems.at(oldRow - 1)) && !(*colItems.at(oldRow - 1) < *item))
     575            newRow = oldRow;
    590576        vit = colItems.insert(vit, item);
    591577        if (newRow != oldRow) {
     
    14111397{
    14121398    const QVariant v1 = data(Qt::DisplayRole), v2 = other.data(Qt::DisplayRole);
    1413     if (QTableModel::canConvertToDouble(v1) && QTableModel::canConvertToDouble(v2))
    1414         return v1.toDouble() < v2.toDouble();
    1415     return v1.toString() < v2.toString();
     1399    return QAbstractItemModelPrivate::variantLessThan(v1, v2);
    14161400}
    14171401
     
    15071491
    15081492    \ingroup model-view
    1509     \mainclass
     1493
    15101494
    15111495    Table widgets provide standard table display facilities for applications.
     
    15891573    QObject::connect(q, SIGNAL(entered(QModelIndex)), q, SLOT(_q_emitItemEntered(QModelIndex)));
    15901574    // model signals
    1591     QObject::connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
     1575    QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
    15921576                     q, SLOT(_q_emitItemChanged(QModelIndex)));
    15931577    // selection signals
     
    15971581                     q, SIGNAL(itemSelectionChanged()));
    15981582    // sorting
    1599     QObject::connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
     1583    QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
    16001584                     q, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
    1601     QObject::connect(model(), SIGNAL(columnsRemoved(QModelIndex,int,int)), q, SLOT(_q_sort()));
     1585    QObject::connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)), q, SLOT(_q_sort()));
    16021586}
    16031587
     
    16051589{
    16061590    Q_Q(QTableWidget);
    1607     if (QTableWidgetItem *item = model()->item(index))
     1591    if (QTableWidgetItem *item = tableModel()->item(index))
    16081592        emit q->itemPressed(item);
    16091593    emit q->cellPressed(index.row(), index.column());
     
    16131597{
    16141598    Q_Q(QTableWidget);
    1615     if (QTableWidgetItem *item = model()->item(index))
     1599    if (QTableWidgetItem *item = tableModel()->item(index))
    16161600        emit q->itemClicked(item);
    16171601    emit q->cellClicked(index.row(), index.column());
     
    16211605{
    16221606    Q_Q(QTableWidget);
    1623     if (QTableWidgetItem *item = model()->item(index))
     1607    if (QTableWidgetItem *item = tableModel()->item(index))
    16241608        emit q->itemDoubleClicked(item);
    16251609    emit q->cellDoubleClicked(index.row(), index.column());
     
    16291613{
    16301614    Q_Q(QTableWidget);
    1631     if (QTableWidgetItem *item = model()->item(index))
     1615    if (QTableWidgetItem *item = tableModel()->item(index))
    16321616        emit q->itemActivated(item);
    16331617    emit q->cellActivated(index.row(), index.column());
     
    16371621{
    16381622    Q_Q(QTableWidget);
    1639     if (QTableWidgetItem *item = model()->item(index))
     1623    if (QTableWidgetItem *item = tableModel()->item(index))
    16401624        emit q->itemEntered(item);
    16411625    emit q->cellEntered(index.row(), index.column());
     
    16451629{
    16461630    Q_Q(QTableWidget);
    1647     if (QTableWidgetItem *item = model()->item(index))
     1631    if (QTableWidgetItem *item = tableModel()->item(index))
    16481632        emit q->itemChanged(item);
    16491633    emit q->cellChanged(index.row(), index.column());
     
    16541638{
    16551639    Q_Q(QTableWidget);
    1656     QTableWidgetItem *currentItem = model()->item(current);
    1657     QTableWidgetItem *previousItem = model()->item(previous);
     1640    QTableWidgetItem *currentItem = tableModel()->item(current);
     1641    QTableWidgetItem *previousItem = tableModel()->item(previous);
    16581642    if (currentItem || previousItem)
    16591643        emit q->currentItemChanged(currentItem, previousItem);
     
    16631647void QTableWidgetPrivate::_q_sort()
    16641648{
    1665     Q_Q(QTableWidget);
    16661649    if (sortingEnabled) {
    1667         int column = q->horizontalHeader()->sortIndicatorSection();
    1668         Qt::SortOrder order = q->horizontalHeader()->sortIndicatorOrder();
    1669         model()->sort(column, order);
     1650        int column = horizontalHeader->sortIndicatorSection();
     1651        Qt::SortOrder order = horizontalHeader->sortIndicatorOrder();
     1652        model->sort(column, order);
    16701653    }
    16711654}
     
    16741657                                         const QModelIndex &bottomRight)
    16751658{
    1676     Q_Q(QTableWidget);
    16771659    if (sortingEnabled && topLeft.isValid() && bottomRight.isValid()) {
    1678         int column = q->horizontalHeader()->sortIndicatorSection();
     1660        int column = horizontalHeader->sortIndicatorSection();
    16791661        if (column >= topLeft.column() && column <= bottomRight.column()) {
    1680             Qt::SortOrder order = q->horizontalHeader()->sortIndicatorOrder();
    1681             model()->ensureSorted(column, order, topLeft.row(), bottomRight.row());
     1662            Qt::SortOrder order = horizontalHeader->sortIndicatorOrder();
     1663            tableModel()->ensureSorted(column, order, topLeft.row(), bottomRight.row());
    16821664        }
    16831665    }
     
    17401722    This signal is emitted whenever the selection changes.
    17411723
    1742     \sa selectedItems() isItemSelected()
     1724    \sa selectedItems() QTableWidgetItem::isSelected()
    17431725*/
    17441726
     
    18831865{
    18841866    Q_D(QTableWidget);
    1885     d->model()->setRowCount(rows);
     1867    d->tableModel()->setRowCount(rows);
    18861868}
    18871869
     
    18931875{
    18941876    Q_D(const QTableWidget);
    1895     return d->model()->rowCount();
     1877    return d->model->rowCount();
    18961878}
    18971879
     
    19061888{
    19071889    Q_D(QTableWidget);
    1908     d->model()->setColumnCount(columns);
     1890    d->tableModel()->setColumnCount(columns);
    19091891}
    19101892
     
    19161898{
    19171899    Q_D(const QTableWidget);
    1918     return d->model()->columnCount();
     1900    return d->model->columnCount();
    19191901}
    19201902
     
    19251907{
    19261908    Q_D(const QTableWidget);
    1927     return d->model()->index(item).row();
     1909    return d->tableModel()->index(item).row();
    19281910}
    19291911
     
    19341916{
    19351917    Q_D(const QTableWidget);
    1936     return d->model()->index(item).column();
     1918    return d->tableModel()->index(item).column();
    19371919}
    19381920
     
    19471929{
    19481930    Q_D(const QTableWidget);
    1949     return d->model()->item(row, column);
     1931    return d->tableModel()->item(row, column);
    19501932}
    19511933
     
    19761958        } else {
    19771959            item->view = this;
    1978             d->model()->setItem(row, column, item);
     1960            d->tableModel()->setItem(row, column, item);
    19791961        }
    19801962    } else {
     
    19891971{
    19901972    Q_D(QTableWidget);
    1991     QTableWidgetItem *item = d->model()->takeItem(row, column);
     1973    QTableWidgetItem *item = d->tableModel()->takeItem(row, column);
    19921974    if (item)
    19931975        item->view = 0;
     
    20011983{
    20021984    Q_D(const QTableWidget);
    2003     return d->model()->verticalHeaderItem(row);
     1985    return d->tableModel()->verticalHeaderItem(row);
    20041986}
    20051987
     
    20121994    if (item) {
    20131995        item->view = this;
    2014         d->model()->setVerticalHeaderItem(row, item);
     1996        d->tableModel()->setVerticalHeaderItem(row, item);
    20151997    } else {
    20161998        delete takeVerticalHeaderItem(row);
     
    20252007{
    20262008    Q_D(QTableWidget);
    2027     QTableWidgetItem *itm = d->model()->takeVerticalHeaderItem(row);
     2009    QTableWidgetItem *itm = d->tableModel()->takeVerticalHeaderItem(row);
    20282010    if (itm)
    20292011        itm->view = 0;
     
    20382020{
    20392021    Q_D(const QTableWidget);
    2040     return d->model()->horizontalHeaderItem(column);
     2022    return d->tableModel()->horizontalHeaderItem(column);
    20412023}
    20422024
     
    20492031    if (item) {
    20502032        item->view = this;
    2051         d->model()->setHorizontalHeaderItem(column, item);
     2033        d->tableModel()->setHorizontalHeaderItem(column, item);
    20522034    } else {
    20532035        delete takeHorizontalHeaderItem(column);
     
    20622044{
    20632045    Q_D(QTableWidget);
    2064     QTableWidgetItem *itm = d->model()->takeHorizontalHeaderItem(column);
     2046    QTableWidgetItem *itm = d->tableModel()->takeHorizontalHeaderItem(column);
    20652047    if (itm)
    20662048        itm->view = 0;
     
    20742056{
    20752057    Q_D(QTableWidget);
    2076     QTableModel *model = d->model();
     2058    QTableModel *model = d->tableModel();
    20772059    QTableWidgetItem *item = 0;
    20782060    for (int i = 0; i < model->rowCount() && i < labels.count(); ++i) {
     
    20922074{
    20932075    Q_D(QTableWidget);
    2094     QTableModel *model = d->model();
     2076    QTableModel *model = d->tableModel();
    20952077    QTableWidgetItem *item = 0;
    20962078    for (int i = 0; i < model->columnCount() && i < labels.count(); ++i) {
     
    21322114{
    21332115    Q_D(const QTableWidget);
    2134     return d->model()->item(currentIndex());
     2116    return d->tableModel()->item(currentIndex());
    21352117}
    21362118
     
    21382120    Sets the current item to \a item.
    21392121
    2140     Depending on the current \l{QAbstractItemView::SelectionMode}{selection mode},
    2141     the item may also be selected.
     2122    Unless the selection mode is \l{QAbstractItemView::}{NoSelection},
     2123    the item is also be selected.
    21422124
    21432125    \sa currentItem(), setCurrentCell()
     
    21462128{
    21472129    Q_D(QTableWidget);
    2148     setCurrentIndex(d->model()->index(item));
     2130    setCurrentIndex(d->tableModel()->index(item));
    21492131}
    21502132
     
    21592141{
    21602142    Q_D(QTableWidget);
    2161     d->selectionModel->setCurrentIndex(d->model()->index(item), command);
     2143    d->selectionModel->setCurrentIndex(d->tableModel()->index(item), command);
    21622144}
    21632145
     
    21982180{
    21992181    Q_D(QTableWidget);
    2200     d->model()->sort(column, order);
     2182    d->model->sort(column, order);
    22012183    horizontalHeader()->setSortIndicator(column, order);
    22022184}
     
    22272209    if (!item)
    22282210        return;
    2229     edit(d->model()->index(item));
     2211    edit(d->tableModel()->index(item));
    22302212}
    22312213
     
    22402222    if (!item)
    22412223        return;
    2242     QModelIndex index = d->model()->index(item);
     2224    QModelIndex index = d->tableModel()->index(item);
    22432225    QAbstractItemView::openPersistentEditor(index);
    22442226}
     
    22542236    if (!item)
    22552237        return;
    2256     QModelIndex index = d->model()->index(item);
     2238    QModelIndex index = d->tableModel()->index(item);
    22572239    QAbstractItemView::closePersistentEditor(index);
    22582240}
     
    23042286{
    23052287    Q_D(const QTableWidget);
    2306     QModelIndex index = d->model()->index(item);
     2288    QModelIndex index = d->tableModel()->index(item);
    23072289    return selectionModel()->isSelected(index);
    23082290}
     
    23182300{
    23192301    Q_D(QTableWidget);
    2320     QModelIndex index = d->model()->index(item);
     2302    QModelIndex index = d->tableModel()->index(item);
    23212303    selectionModel()->select(index, select ? QItemSelectionModel::Select : QItemSelectionModel::Deselect);
    23222304}
     
    23752357        if (isIndexHidden(index))
    23762358            continue;
    2377         QTableWidgetItem *item = d->model()->item(index);
     2359        QTableWidgetItem *item = d->tableModel()->item(index);
    23782360        if (item)
    23792361            items.append(item);
     
    23912373    QModelIndexList indexes;
    23922374    for (int column = 0; column < columnCount(); ++column)
    2393         indexes += d->model()->match(model()->index(0, column, QModelIndex()),
     2375        indexes += d->model->match(model()->index(0, column, QModelIndex()),
    23942376                                     Qt::DisplayRole, text, -1, flags);
    23952377    QList<QTableWidgetItem*> items;
    23962378    for (int i = 0; i < indexes.size(); ++i)
    2397         items.append(d->model()->item(indexes.at(i)));
     2379        items.append(d->tableModel()->item(indexes.at(i)));
    23982380    return items;
    23992381}
     
    24292411{
    24302412    Q_D(const QTableWidget);
    2431     return d->model()->item(indexAt(p));
     2413    return d->tableModel()->item(indexAt(p));
    24322414}
    24332415
     
    24402422    if (!item)
    24412423        return QRect();
    2442     QModelIndex index = d->model()->index(const_cast<QTableWidgetItem*>(item));
     2424    QModelIndex index = d->tableModel()->index(const_cast<QTableWidgetItem*>(item));
    24432425    Q_ASSERT(index.isValid());
    24442426    return visualRect(index);
     
    24562438    if (!item)
    24572439        return;
    2458     QModelIndex index = d->model()->index(const_cast<QTableWidgetItem*>(item));
     2440    QModelIndex index = d->tableModel()->index(const_cast<QTableWidgetItem*>(item));
    24592441    Q_ASSERT(index.isValid());
    24602442    QTableView::scrollTo(index, hint);
     
    24692451{
    24702452    Q_D(const QTableWidget);
    2471     return d->model()->itemPrototype();
     2453    return d->tableModel()->itemPrototype();
    24722454}
    24732455
     
    24772459    The table widget will use the item prototype clone function when it needs
    24782460    to create a new table item.  For example when the user is editing
    2479     editing in an empty cell.  This is useful when you have a QTableWidgetItem
     2461    in an empty cell.  This is useful when you have a QTableWidgetItem
    24802462    subclass and want to make sure that QTableWidget creates instances of
    24812463    your subclass.
     
    24882470{
    24892471    Q_D(QTableWidget);
    2490     d->model()->setItemPrototype(item);
     2472    d->tableModel()->setItemPrototype(item);
    24912473}
    24922474
     
    24972479{
    24982480    Q_D(QTableWidget);
    2499     d->model()->insertRows(row);
     2481    d->tableModel()->insertRows(row);
    25002482}
    25012483
     
    25062488{
    25072489    Q_D(QTableWidget);
    2508     d->model()->insertColumns(column);
     2490    d->tableModel()->insertColumns(column);
    25092491}
    25102492
     
    25152497{
    25162498    Q_D(QTableWidget);
    2517     d->model()->removeRows(row);
     2499    d->tableModel()->removeRows(row);
    25182500}
    25192501
     
    25242506{
    25252507    Q_D(QTableWidget);
    2526     d->model()->removeColumns(column);
     2508    d->tableModel()->removeColumns(column);
    25272509}
    25282510
     
    25372519    Q_D(QTableWidget);
    25382520    selectionModel()->clear();
    2539     d->model()->clear();
     2521    d->tableModel()->clear();
    25402522}
    25412523
     
    25512533    Q_D(QTableWidget);
    25522534    selectionModel()->clear();
    2553     d->model()->clearContents();
     2535    d->tableModel()->clearContents();
    25542536}
    25552537
     
    25622544QStringList QTableWidget::mimeTypes() const
    25632545{
    2564     return d_func()->model()->QAbstractTableModel::mimeTypes();
     2546    return d_func()->tableModel()->QAbstractTableModel::mimeTypes();
    25652547}
    25662548
     
    25752557QMimeData *QTableWidget::mimeData(const QList<QTableWidgetItem*>) const
    25762558{
    2577     return d_func()->model()->internalMimeData();
     2559    return d_func()->tableModel()->internalMimeData();
    25782560}
    25792561
     
    25972579    }
    25982580#endif
    2599     return d_func()->model()->QAbstractTableModel::dropMimeData(data, action , row, column, idx);
     2581    return d_func()->tableModel()->QAbstractTableModel::dropMimeData(data, action , row, column, idx);
    26002582}
    26012583
     
    26072589Qt::DropActions QTableWidget::supportedDropActions() const
    26082590{
    2609     return d_func()->model()->QAbstractTableModel::supportedDropActions() | Qt::MoveAction;
     2591    return d_func()->tableModel()->QAbstractTableModel::supportedDropActions() | Qt::MoveAction;
    26102592}
    26112593
     
    26312613{
    26322614    Q_D(const QTableWidget);
    2633     return d->model()->index(item);
     2615    return d->tableModel()->index(item);
    26342616}
    26352617
     
    26412623{
    26422624    Q_D(const QTableWidget);
    2643     return d->model()->item(index);
     2625    return d->tableModel()->item(index);
    26442626}
    26452627
  • trunk/src/gui/itemviews/qtablewidget.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qtablewidget_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    145145    static bool itemGreaterThan(const QPair<QTableWidgetItem*,int> &left,
    146146                                const QPair<QTableWidgetItem*,int> &right);
    147     static bool canConvertToDouble(const QVariant &value);
    148147
    149148    void ensureSorted(int column, Qt::SortOrder order, int start, int end);
     
    191190public:
    192191    QTableWidgetPrivate() : QTableViewPrivate() {}
    193     inline QTableModel *model() const { return qobject_cast<QTableModel*>(q_func()->model()); }
     192    inline QTableModel *tableModel() const { return qobject_cast<QTableModel*>(model); }
    194193    void setup();
    195194
  • trunk/src/gui/itemviews/qtreeview.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6767    \ingroup model-view
    6868    \ingroup advanced
    69     \mainclass
     69
    7070
    7171    A QTreeView implements a tree representation of items from a
     
    216216    if (model == d->model)
    217217        return;
     218    if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
     219        disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
     220                this, SLOT(rowsRemoved(QModelIndex,int,int)));
     221
     222        disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_modelAboutToBeReset()));
     223    }
     224
    218225    if (d->selectionModel) { // support row editing
    219226        disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
     
    239246            this, SLOT(rowsRemoved(QModelIndex,int,int)));
    240247
    241     connect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
    242             this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)));
    243     connect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
    244             this, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
    245 
    246248    connect(d->model, SIGNAL(modelAboutToBeReset()), SLOT(_q_modelAboutToBeReset()));
    247249
    248250    if (d->sortingEnabled)
    249         sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
     251        d->_q_sortIndicatorChanged(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
    250252}
    251253
     
    268270    Q_ASSERT(selectionModel);
    269271    if (d->selectionModel) {
    270         if (d->allColumnsShowFocus) {
    271             QObject::disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
    272                                 this, SLOT(_q_currentChanged(QModelIndex,QModelIndex)));
    273         }
    274272        // support row editing
    275273        disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
     
    281279
    282280    if (d->selectionModel) {
    283         if (d->allColumnsShowFocus) {
    284             QObject::connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
    285                              this, SLOT(_q_currentChanged(QModelIndex,QModelIndex)));
    286         }
    287281        // support row editing
    288282        connect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
     
    681675    // since QAbstractItemView::dataChanged() will get the visualRect for the items anyway
    682676
    683     QModelIndex top = topLeft.sibling(topLeft.row(), 0);
    684     int topViewIndex = d->viewIndex(top);
     677    int topViewIndex = d->viewIndex(topLeft);
    685678    if (topViewIndex == 0)
    686         d->defaultItemHeight = indexRowSizeHint(top);
     679        d->defaultItemHeight = indexRowSizeHint(topLeft);
    687680    bool sizeChanged = false;
    688681    if (topViewIndex != -1) {
     
    692685            sizeChanged = (oldHeight != d->itemHeight(topViewIndex));
    693686        } else {
    694             QModelIndex bottom = bottomRight.sibling(bottomRight.row(), 0);
    695             int bottomViewIndex = d->viewIndex(bottom);
     687            int bottomViewIndex = d->viewIndex(bottomRight);
    696688            for (int i = topViewIndex; i <= bottomViewIndex; ++i) {
    697689                int oldHeight = d->itemHeight(i);
     
    847839{
    848840    Q_D(QTreeView);
    849     d->sortingEnabled = enable;
    850841    header()->setSortIndicatorShown(enable);
    851842    header()->setClickable(enable);
    852843    if (enable) {
     844        //sortByColumn has to be called before we connect or set the sortingEnabled flag
     845        // because otherwise it will not call sort on the model.
     846        sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
    853847        connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
    854                 this, SLOT(_q_sortIndicatorChanged(int, Qt::SortOrder)));
    855         sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
     848                this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)), Qt::UniqueConnection);
    856849    } else {
    857850        disconnect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
    858                    this, SLOT(_q_sortIndicatorChanged(int, Qt::SortOrder)));
    859     }
     851                   this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)));
     852    }
     853    d->sortingEnabled = enable;
    860854}
    861855
     
    907901    if (d->allColumnsShowFocus == enable)
    908902        return;
    909     if (d->selectionModel) {
    910         if (enable) {
    911             QObject::connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
    912                              this, SLOT(_q_currentChanged(QModelIndex,QModelIndex)));
    913         } else {
    914             QObject::disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
    915                                 this, SLOT(_q_currentChanged(QModelIndex,QModelIndex)));
    916         }
    917     }
    918903    d->allColumnsShowFocus = enable;
    919904    d->viewport->update();
     
    11181103            verticalScrollBar()->setValue(item);
    11191104        } else { // PositionAtBottom or PositionAtCenter
    1120             int itemLocation = item;
     1105            const int currentItemHeight = d->itemHeight(item);
    11211106            int y = (hint == PositionAtCenter
    1122                      ? area.height() / 2
     1107                 //we center on the current item with a preference to the top item (ie. -1)
     1108                     ? area.height() / 2 + currentItemHeight - 1
     1109                 //otherwise we simply take the whole space
    11231110                     : area.height());
    1124             while (y > 0 && item > 0)
    1125                 y -= d->itemHeight(item--);
    1126             // end up half over the top of the area
    1127             if (y < 0 && item < itemLocation)
    1128                 ++item;
    1129             // end up half over the bottom of the area
    1130             if (item >= 0 && item < itemLocation)
    1131                 ++item;
     1111            if (y > currentItemHeight) {
     1112                while (item >= 0) {
     1113                    y -= d->itemHeight(item);
     1114                    if (y < 0) { //there is no more space left
     1115                        item++;
     1116                        break;
     1117                    }
     1118                    item--;
     1119                }
     1120            }
    11321121            verticalScrollBar()->setValue(item);
    11331122        }
     
    11411130            // nothing to do
    11421131        } else if (hint == EnsureVisible && area.contains(rect)) {
    1143             d->setDirtyRegion(rect);
     1132            d->viewport->update(rect);
    11441133            // nothing to do
    11451134        } else {
     
    12451234                QRect oldRect = visualRect(oldIndex);
    12461235                QRect newRect = visualRect(newIndex);
    1247                 viewport()->update(oldRect.left() - d->indent, oldRect.top(), d->indent, oldRect.height());
    1248                 viewport()->update(newRect.left() - d->indent, newRect.top(), d->indent, newRect.height());
     1236                oldRect.setLeft(oldRect.left() - d->indent);
     1237                newRect.setLeft(newRect.left() - d->indent);
     1238                //we need to paint the whole items (including the decoration) so that when the user
     1239                //moves the mouse over those elements they are updated
     1240                viewport()->update(oldRect);
     1241                viewport()->update(newRect);
    12491242            }
    12501243        }
     
    12731266    d->executePostedLayout();
    12741267    QPainter painter(viewport());
     1268#ifndef QT_NO_ANIMATION
    12751269    if (d->isAnimating()) {
    1276         drawTree(&painter, event->region() - d->animationRect());
     1270        drawTree(&painter, event->region() - d->animatedOperation.rect());
    12771271        d->drawAnimatedOperation(&painter);
    1278     } else {
     1272    } else
     1273#endif //QT_NO_ANIMATION
     1274    {
    12791275        drawTree(&painter, event->region());
    12801276#ifndef QT_NO_DRAGANDDROP
     
    13121308    Q_Q(QTreeView);
    13131309    // we want to handle mousePress in EditingState (persistent editors)
    1314     if ((q->state() != QAbstractItemView::NoState
    1315                 && q->state() != QAbstractItemView::EditingState)
     1310    if ((state != QAbstractItemView::NoState
     1311                && state != QAbstractItemView::EditingState)
    13161312                || !viewport->rect().contains(pos))
    13171313        return true;
    13181314
    13191315    int i = itemDecorationAt(pos);
    1320     if ((i != -1) && q->itemsExpandable() && hasVisibleChildren(viewItems.at(i).index)) {
     1316    if ((i != -1) && itemsExpandable && hasVisibleChildren(viewItems.at(i).index)) {
    13211317        if (viewItems.at(i).expanded)
    13221318            collapse(i, true);
     
    13251321        if (!isAnimating()) {
    13261322            q->updateGeometries();
    1327             q->viewport()->update();
     1323            viewport->update();
    13281324        }
    13291325        return true;
     
    13391335    QAbstractItemViewPrivate::_q_modelDestroyed();
    13401336}
     1337
     1338/*!
     1339  \reimp
     1340
     1341  We have a QTreeView way of knowing what elements are on the viewport
     1342*/
     1343QItemViewPaintPairs QTreeViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const
     1344{
     1345    Q_ASSERT(r);
     1346    return QAbstractItemViewPrivate::draggablePaintPairs(indexes, r);
     1347    Q_Q(const QTreeView);
     1348    QRect &rect = *r;
     1349    const QRect viewportRect = viewport->rect();
     1350    int itemOffset = 0;
     1351    int row = firstVisibleItem(&itemOffset);
     1352    QPair<int, int> startEnd = startAndEndColumns(viewportRect);
     1353    QVector<int> columns;
     1354    for (int i = startEnd.first; i <= startEnd.second; ++i) {
     1355        int logical = header->logicalIndex(i);
     1356        if (!header->isSectionHidden(logical))
     1357            columns += logical;
     1358    }
     1359    QSet<QModelIndex> visibleIndexes;
     1360    for (; itemOffset < viewportRect.bottom() && row < viewItems.count(); ++row) {
     1361        const QModelIndex &index = viewItems.at(row).index;
     1362        for (int colIndex = 0; colIndex < columns.count(); ++colIndex)
     1363            visibleIndexes += index.sibling(index.row(), columns.at(colIndex));
     1364        itemOffset += itemHeight(row);
     1365    }
     1366
     1367    //now that we have the visible indexes, we can try to find those which are selected
     1368    QItemViewPaintPairs ret;
     1369    for (int i = 0; i < indexes.count(); ++i) {
     1370        const QModelIndex &index = indexes.at(i);
     1371        if (visibleIndexes.contains(index)) {
     1372            const QRect current = q->visualRect(index);
     1373            ret += qMakePair(current, index);
     1374            rect |= current;
     1375        }
     1376    }
     1377    rect &= viewportRect;
     1378    return ret;
     1379}
     1380
    13411381
    13421382/*!
     
    13941434            const int itemHeight = d->itemHeight(i);
    13951435            option.rect.setRect(0, y, viewportWidth, itemHeight);
    1396             option.state = state | (viewItems.at(i).expanded
    1397                                     ? QStyle::State_Open : QStyle::State_None);
     1436            option.state = state | (viewItems.at(i).expanded ? QStyle::State_Open : QStyle::State_None)
     1437                                 | (viewItems.at(i).hasChildren ? QStyle::State_Children : QStyle::State_None)
     1438                                 | (viewItems.at(i).hasMoreSiblings ? QStyle::State_Sibling : QStyle::State_None);
    13981439            d->current = i;
    13991440            d->spanning = viewItems.at(i).spanning;
     
    15471588                                 : logicalIndices.at(currentLogicalSection - 1);
    15481589        if (columnCount == 1 || (nextLogicalSection == 0 && prevLogicalSection == -1)
    1549             || (headerSection == 0 && nextLogicalSection == -1))
     1590            || (headerSection == 0 && nextLogicalSection == -1) || spanning)
    15501591            opt.viewItemPosition = QStyleOptionViewItemV4::OnlyOne;
    15511592        else if (headerSection == 0 || (nextLogicalSection != 0 && prevLogicalSection == -1))
     
    17201761
    17211762        const bool expanded = viewItem.expanded;
    1722         const bool children = (((expanded && viewItem.total > 0)) // already laid out and has children
    1723                                 || d->hasVisibleChildren(index)); // not laid out yet, so we don't know
    1724         bool moreSiblings = false;
    1725         if (d->hiddenIndexes.isEmpty())
    1726             moreSiblings = (d->model->rowCount(parent) - 1 > index.row());
    1727         else
    1728             moreSiblings = ((d->viewItems.size() > item +1)
    1729                             && (d->viewItems.at(item + 1).index.parent() == parent));
     1763        const bool children = viewItem.hasChildren;
     1764        bool moreSiblings = viewItem.hasMoreSiblings;
    17301765
    17311766        opt.state = QStyle::State_Item | extraFlags
     
    18161851            return; // user clicked outside the items
    18171852
    1818         const QModelIndex &index = d->viewItems.at(i).index;
    1819 
    1820         int column = d->header->logicalIndexAt(event->x());
    1821         QPersistentModelIndex persistent = index.sibling(index.row(), column);
     1853        const QPersistentModelIndex firstColumnIndex = d->viewItems.at(i).index;
     1854        const QPersistentModelIndex persistent = indexAt(event->pos());
    18221855
    18231856        if (d->pressedIndex != persistent) {
     
    18421875            && d->expandsOnDoubleClick
    18431876            && d->hasVisibleChildren(persistent)) {
    1844             if (!((i < d->viewItems.count()) && (d->viewItems.at(i).index == persistent))) {
     1877            if (!((i < d->viewItems.count()) && (d->viewItems.at(i).index == firstColumnIndex))) {
    18451878                // find the new index of the item
    18461879                for (i = 0; i < d->viewItems.count(); ++i) {
    1847                     if (d->viewItems.at(i).index == persistent)
     1880                    if (d->viewItems.at(i).index == firstColumnIndex)
    18481881                        break;
    18491882                }
     
    20732106            int index = useTopIndex ? INT_MAX : INT_MIN;
    20742107            const QItemSelection selection = d->selectionModel->selection();
    2075             foreach (const QItemSelectionRange &range, selection) {
     2108            for (int i = 0; i < selection.count(); ++i) {
     2109                const QItemSelectionRange &range = selection.at(i);
    20762110                int candidate = d->viewIndex(useTopIndex ? range.topLeft() : range.bottomRight());
    20772111                if (candidate >= 0)
     
    20872121        vi = qMax(0, d->viewIndex(current));
    20882122
     2123    if (isRightToLeft()) {
     2124        if (cursorAction == MoveRight)
     2125            cursorAction = MoveLeft;
     2126        else if (cursorAction == MoveLeft)
     2127            cursorAction = MoveRight;
     2128    }
    20892129    switch (cursorAction) {
    20902130    case MoveNext:
     
    24082448    }
    24092449
    2410     if (parent != d->root && !d->isIndexExpanded(parent) && d->model->rowCount(parent) > (end - start) + 1) {
     2450    const int parentRowCount = d->model->rowCount(parent);
     2451    const int delta = end - start + 1;
     2452    if (parent != d->root && !d->isIndexExpanded(parent) && parentRowCount > delta) {
    24112453        QAbstractItemView::rowsInserted(parent, start, end);
    24122454        return;
     
    24232465                                                    : d->viewItems.at(parentItem).total) - 1;
    24242466
    2425         int firstColumn = 0;
    2426         while (isColumnHidden(firstColumn) && firstColumn < header()->count() - 1)
    2427             ++firstColumn;
    2428 
    2429         const int delta = end - start + 1;
     2467        if (parentRowCount == end + 1 && start > 0) {
     2468            //need to Update hasMoreSiblings
     2469            int previousRow = start - 1;
     2470            QModelIndex previousSibilingModelIndex = d->model->index(previousRow, 0, parent);
     2471            bool isHidden = d->isRowHidden(previousSibilingModelIndex);
     2472            while (isHidden && previousRow > 0) {
     2473                previousRow--;
     2474                previousSibilingModelIndex = d->model->index(previousRow, 0, parent);
     2475                isHidden = d->isRowHidden(previousSibilingModelIndex);
     2476            }
     2477            if (!isHidden) {
     2478                const int previousSibilling = d->viewIndex(previousSibilingModelIndex);
     2479                if(previousSibilling != -1)
     2480                    d->viewItems[previousSibilling].hasMoreSiblings = true;
     2481            }
     2482        }
     2483
    24302484        QVector<QTreeViewItem> insertedItems(delta);
    24312485        for (int i = 0; i < delta; ++i) {
    2432             insertedItems[i].index = d->model->index(i + start, firstColumn, parent);
     2486            insertedItems[i].index = d->model->index(i + start, 0, parent);
    24332487            insertedItems[i].level = childLevel;
     2488            insertedItems[i].hasChildren = d->hasVisibleChildren(insertedItems[i].index);
     2489            insertedItems[i].hasMoreSiblings = !((i == delta - 1) && (parentRowCount == end +1));
    24342490        }
    24352491        if (d->viewItems.isEmpty())
     
    24732529        }
    24742530
     2531        if (parentItem != -1)
     2532            d->viewItems[parentItem].hasChildren = true;
    24752533        d->updateChildCount(parentItem, delta);
     2534
    24762535        updateGeometries();
    24772536        viewport()->update();
     
    24792538        d->doDelayedItemsLayout();
    24802539    } else if (parentItem != -1 && (d->model->rowCount(parent) == end - start + 1)) {
    2481         // the parent just went from 0 children to having some update to re-paint the decoration
     2540        // the parent just went from 0 children to more. update to re-paint the decoration
     2541        d->viewItems[parentItem].hasChildren = true;
    24822542        viewport()->update();
    24832543    }
     
    26132673        d->layout(i);
    26142674        QModelIndex idx = d->viewItems.at(i).index;
    2615         d->expandedIndexes.insert(idx.sibling(idx.row(), 0));
     2675        d->expandedIndexes.insert(idx);
    26162676    }
    26172677    updateGeometries();
     
    27152775    if (d->viewItems.isEmpty())
    27162776        return -1;
     2777    ensurePolished();
    27172778    int w = 0;
    27182779    QStyleOptionViewItemV4 option = d->viewOptionsV4();
     
    27722833    if (isRightToLeft()) {
    27732834        start = (start == -1 ? count - 1 : start);
    2774         end = (end == -1 ? 0 : end);
     2835        end = 0;
    27752836    } else {
    27762837        start = (start == -1 ? 0 : start);
    2777         end = (end == -1 ? count - 1 : end);
    2778     }
    2779 
    2780     int tmp = start;
    2781     start = qMin(start, end);
    2782     end = qMax(tmp, end);
     2838        end = count - 1;
     2839    }
     2840
     2841    if (end < start)
     2842        qSwap(end, start);
    27832843
    27842844    int height = -1;
     
    28282888
    28292889/*!
    2830   \reimp
     2890  \internal
    28312891*/
    28322892void QTreeView::horizontalScrollbarAction(int action)
     
    28602920    header->setDefaultAlignment(Qt::AlignLeft|Qt::AlignVCenter);
    28612921    q->setHeader(header);
    2862 
    2863     // animation
    2864     QObject::connect(&timeline, SIGNAL(frameChanged(int)), q, SLOT(_q_animate()));
    2865     QObject::connect(&timeline, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation()), Qt::QueuedConnection);
     2922#ifndef QT_NO_ANIMATION
     2923    QObject::connect(&animatedOperation, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation()));
     2924#endif //QT_NO_ANIMATION
    28662925}
    28672926
     
    28732932        return;
    28742933
     2934#ifndef QT_NO_ANIMATION
    28752935    if (emitSignal && animationsEnabled)
    2876         prepareAnimatedOperation(item, AnimatedOperation::Expand);
    2877 
    2878     QAbstractItemView::State oldState = q->state();
     2936        prepareAnimatedOperation(item, QVariantAnimation::Forward);
     2937#endif //QT_NO_ANIMATION
     2938    QAbstractItemView::State oldState = state;
    28792939    q->setState(QAbstractItemView::ExpandingState);
    28802940    const QModelIndex index = viewItems.at(item).index;
     
    28842944    q->setState(oldState);
    28852945
     2946    if (model->canFetchMore(index))
     2947        model->fetchMore(index);
    28862948    if (emitSignal) {
    28872949        emit q->expanded(index);
     2950#ifndef QT_NO_ANIMATION
    28882951        if (animationsEnabled)
    28892952            beginAnimatedOperation();
    2890     }
    2891     if (model->canFetchMore(index))
    2892         model->fetchMore(index);
     2953#endif //QT_NO_ANIMATION
     2954    }
    28932955}
    28942956
     
    29112973        return; // nothing to do
    29122974
     2975#ifndef QT_NO_ANIMATION
    29132976    if (emitSignal && animationsEnabled)
    2914         prepareAnimatedOperation(item, AnimatedOperation::Collapse);
    2915 
    2916     QAbstractItemView::State oldState = q->state();
     2977        prepareAnimatedOperation(item, QVariantAnimation::Backward);
     2978#endif //QT_NO_ANIMATION
     2979
     2980    QAbstractItemView::State oldState = state;
    29172981    q->setState(QAbstractItemView::CollapsingState);
    29182982    expandedIndexes.erase(it);
     
    29312995    if (emitSignal) {
    29322996        emit q->collapsed(modelIndex);
     2997#ifndef QT_NO_ANIMATION
    29332998        if (animationsEnabled)
    29342999            beginAnimatedOperation();
    2935     }
    2936 }
    2937 
    2938 void QTreeViewPrivate::prepareAnimatedOperation(int item, AnimatedOperation::Type type)
     3000#endif //QT_NO_ANIMATION
     3001    }
     3002}
     3003
     3004#ifndef QT_NO_ANIMATION
     3005void QTreeViewPrivate::prepareAnimatedOperation(int item, QVariantAnimation::Direction direction)
    29393006{
    29403007    animatedOperation.item = item;
    2941     animatedOperation.type = type;
     3008    animatedOperation.viewport = viewport;
     3009    animatedOperation.setDirection(direction);
    29423010
    29433011    int top = coordinateForItem(item) + itemHeight(item);
    29443012    QRect rect = viewport->rect();
    29453013    rect.setTop(top);
    2946     if (type == AnimatedOperation::Collapse) {
     3014    if (direction == QVariantAnimation::Backward) {
    29473015        const int limit = rect.height() * 2;
    29483016        int h = 0;
     
    29513019            h += itemHeight(i);
    29523020        rect.setHeight(h);
    2953         animatedOperation.duration = h;
    2954     }
    2955     animatedOperation.top = top;
     3021        animatedOperation.setEndValue(top + h);
     3022    }
     3023    animatedOperation.setStartValue(top);
    29563024    animatedOperation.before = renderTreeToPixmapForAnimation(rect);
    29573025}
     
    29623030
    29633031    QRect rect = viewport->rect();
    2964     rect.setTop(animatedOperation.top);
    2965     if (animatedOperation.type == AnimatedOperation::Expand) {
     3032    rect.setTop(animatedOperation.top());
     3033    if (animatedOperation.direction() == QVariantAnimation::Forward) {
    29663034        const int limit = rect.height() * 2;
    29673035        int h = 0;
     
    29703038            h += itemHeight(i);
    29713039        rect.setHeight(h);
    2972         animatedOperation.duration = h;
    2973     }
    2974 
    2975     animatedOperation.after = renderTreeToPixmapForAnimation(rect);
    2976 
    2977     q->setState(QAbstractItemView::AnimatingState);
    2978 
    2979     timeline.stop();
    2980     timeline.setDuration(250);
    2981     timeline.setFrameRange(animatedOperation.top, animatedOperation.top + animatedOperation.duration);
    2982     timeline.start();
    2983 }
    2984 
    2985 void QTreeViewPrivate::_q_endAnimatedOperation()
    2986 {
    2987     Q_Q(QTreeView);
    2988     animatedOperation.before = QPixmap();
    2989     animatedOperation.after = QPixmap();
    2990     q->setState(QAbstractItemView::NoState);
    2991     q->updateGeometries();
    2992     viewport->update();
    2993 }
    2994 
    2995 void QTreeViewPrivate::_q_animate()
    2996 {
    2997     QRect rect = viewport->rect();
    2998     rect.moveTop(animatedOperation.top);
    2999     viewport->repaint(rect);
     3040        animatedOperation.setEndValue(animatedOperation.top() + h);
     3041    }
     3042
     3043    if (!rect.isEmpty()) {
     3044        animatedOperation.after = renderTreeToPixmapForAnimation(rect);
     3045
     3046        q->setState(QAbstractItemView::AnimatingState);
     3047        animatedOperation.start(); //let's start the animation
     3048    }
    30003049}
    30013050
    30023051void QTreeViewPrivate::drawAnimatedOperation(QPainter *painter) const
    30033052{
    3004     int start = timeline.startFrame();
    3005     int end = timeline.endFrame();
    3006     bool collapsing = animatedOperation.type == AnimatedOperation::Collapse;
    3007     int current = collapsing ? end - timeline.currentFrame() + start : timeline.currentFrame();
     3053    const int start = animatedOperation.startValue().toInt(),
     3054        end = animatedOperation.endValue().toInt(),
     3055        current = animatedOperation.currentValue().toInt();
     3056    bool collapsing = animatedOperation.direction() == QVariantAnimation::Backward;
    30083057    const QPixmap top = collapsing ? animatedOperation.before : animatedOperation.after;
    30093058    painter->drawPixmap(0, start, top, 0, end - current - 1, top.width(), top.height());
     
    30483097}
    30493098
    3050 void QTreeViewPrivate::_q_currentChanged(const QModelIndex &current, const QModelIndex &previous)
     3099void QTreeViewPrivate::_q_endAnimatedOperation()
    30513100{
    30523101    Q_Q(QTreeView);
    3053     if (previous.isValid()) {
    3054         QRect previousRect = q->visualRect(previous);
    3055         if (allColumnsShowFocus) {
    3056             previousRect.setX(0);
    3057             previousRect.setWidth(viewport->width());
    3058         }
    3059         viewport->update(previousRect);
    3060     }
    3061     if (current.isValid()) {
    3062         QRect currentRect = q->visualRect(current);
    3063         if (allColumnsShowFocus) {
    3064             currentRect.setX(0);
    3065             currentRect.setWidth(viewport->width());
    3066         }
    3067         viewport->update(currentRect);
    3068     }
    3069 }
     3102    q->setState(QAbstractItemView::NoState);
     3103    q->updateGeometries();
     3104    viewport->update();
     3105}
     3106#endif //QT_NO_ANIMATION
    30703107
    30713108void QTreeViewPrivate::_q_modelAboutToBeReset()
     
    30763113void QTreeViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
    30773114{
    3078     Q_UNUSED(parent);
    30793115    if (start <= 0 && 0 <= end)
    30803116        viewItems.clear();
     3117    QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(parent, start, end);
    30813118}
    30823119
    30833120void QTreeViewPrivate::_q_columnsRemoved(const QModelIndex &parent, int start, int end)
    30843121{
    3085     Q_UNUSED(parent);
    30863122    if (start <= 0 && 0 <= end)
    30873123        doDelayedItemsLayout();
     3124    QAbstractItemViewPrivate::_q_columnsRemoved(parent, start, end);
    30883125}
    30893126
     
    30933130    QModelIndex current;
    30943131    QModelIndex parent = (i < 0) ? (QModelIndex)root : modelIndex(i);
    3095     // modelIndex() will return an index that don't have a parent if column 0 is hidden,
    3096     // so we must make sure that parent points to the actual parent that has children.
    3097     if (parent != root)
    3098         parent = model->index(parent.row(), 0, parent.parent());
    30993132
    31003133    if (i>=0 && !parent.isValid()) {
     
    31303163    int last = 0;
    31313164    int children = 0;
    3132 
    3133     int firstColumn = 0;
    3134     while (header->isSectionHidden(firstColumn) && firstColumn < header->count())
    3135         ++firstColumn;
    3136 
     3165    QTreeViewItem *item = 0;
    31373166    for (int j = first; j < first + count; ++j) {
    3138         current = model->index(j - first, firstColumn, parent);
    3139         if (isRowHidden(current.sibling(current.row(), 0))) {
     3167        current = model->index(j - first, 0, parent);
     3168        if (isRowHidden(current)) {
    31403169            ++hidden;
    31413170            last = j - hidden + children;
    31423171        } else {
    31433172            last = j - hidden + children;
    3144             viewItems[last].index = current;
    3145             viewItems[last].level = level;
    3146             viewItems[last].height = 0;
    3147             viewItems[last].spanning = q->isFirstColumnSpanned(current.row(), parent);
    3148             viewItems[last].expanded = false;
    3149             viewItems[last].total = 0;
     3173            if (item)
     3174                item->hasMoreSiblings = true;
     3175            item = &viewItems[last];
     3176            item->index = current;
     3177            item->level = level;
     3178            item->height = 0;
     3179            item->spanning = q->isFirstColumnSpanned(current.row(), parent);
     3180            item->expanded = false;
     3181            item->total = 0;
     3182            item->hasMoreSiblings = false;
    31503183            if (isIndexExpanded(current)) {
    3151                 viewItems[last].expanded = true;
     3184                item->expanded = true;
    31523185                layout(last);
    3153                 children += viewItems[last].total;
     3186                item = &viewItems[last];
     3187                children += item->total;
     3188                item->hasChildren = item->total > 0;
    31543189                last = j - hidden + children;
     3190            } else {
     3191                item->hasChildren = hasVisibleChildren(current);
    31553192            }
    31563193        }
     
    32183255int QTreeViewPrivate::coordinateForItem(int item) const
    32193256{
    3220     Q_Q(const QTreeView);
    32213257    if (verticalScrollMode == QAbstractItemView::ScrollPerPixel) {
    32223258        if (uniformRowHeights)
    3223             return (item * defaultItemHeight) - q->verticalScrollBar()->value();
     3259            return (item * defaultItemHeight) - vbar->value();
    32243260        // ### optimize (spans or caching)
    32253261        int y = 0;
    32263262        for (int i = 0; i < viewItems.count(); ++i) {
    32273263            if (i == item)
    3228                 return y - q->verticalScrollBar()->value();
     3264                return y - vbar->value();
    32293265            y += itemHeight(i);
    32303266        }
    32313267    } else { // ScrollPerItem
    3232         int topViewItemIndex = q->verticalScrollBar()->value();
     3268        int topViewItemIndex = vbar->value();
    32333269        if (uniformRowHeights)
    32343270            return defaultItemHeight * (item - topViewItemIndex);
     
    32703306int QTreeViewPrivate::itemAtCoordinate(int coordinate) const
    32713307{
    3272     Q_Q(const QTreeView);
    32733308    const int itemCount = viewItems.count();
    32743309    if (itemCount == 0)
     
    32783313    if (verticalScrollMode == QAbstractItemView::ScrollPerPixel) {
    32793314        if (uniformRowHeights) {
    3280             const int viewItemIndex = (coordinate + q->verticalScrollBar()->value()) / defaultItemHeight;
     3315            const int viewItemIndex = (coordinate + vbar->value()) / defaultItemHeight;
    32813316            return ((viewItemIndex >= itemCount || viewItemIndex < 0) ? -1 : viewItemIndex);
    32823317        }
    32833318        // ### optimize
    32843319        int viewItemCoordinate = 0;
    3285         const int contentsCoordinate = coordinate + q->verticalScrollBar()->value();
     3320        const int contentsCoordinate = coordinate + vbar->value();
    32863321        for (int viewItemIndex = 0; viewItemIndex < viewItems.count(); ++viewItemIndex) {
    32873322            viewItemCoordinate += itemHeight(viewItemIndex);
     
    32903325        }
    32913326    } else { // ScrollPerItem
    3292         int topViewItemIndex = q->verticalScrollBar()->value();
     3327        int topViewItemIndex = vbar->value();
    32933328        if (uniformRowHeights) {
    32943329            if (coordinate < 0)
     
    33203355int QTreeViewPrivate::viewIndex(const QModelIndex &_index) const
    33213356{
    3322     Q_Q(const QTreeView);
    33233357    if (!_index.isValid() || viewItems.isEmpty())
    33243358        return -1;
    33253359
    33263360    const int totalCount = viewItems.count();
    3327     int firstColumn = 0;
    3328     while (q->isColumnHidden(firstColumn) && firstColumn < header->count())
    3329         ++firstColumn;
    3330     const QModelIndex index = _index.sibling(_index.row(), firstColumn);
     3361    const QModelIndex index = _index.sibling(_index.row(), 0);
    33313362
    33323363
     
    33863417int QTreeViewPrivate::firstVisibleItem(int *offset) const
    33873418{
    3388     Q_Q(const QTreeView);
    3389     const int value = q->verticalScrollBar()->value();
     3419    const int value = vbar->value();
    33903420    if (verticalScrollMode == QAbstractItemView::ScrollPerItem) {
    33913421        if (offset)
     
    34643494        if (!viewItems.isEmpty())
    34653495            itemsInViewport = qMax(1, itemsInViewport);
    3466         q->verticalScrollBar()->setRange(0, viewItems.count() - itemsInViewport);
    3467         q->verticalScrollBar()->setPageStep(itemsInViewport);
    3468         q->verticalScrollBar()->setSingleStep(1);
     3496        vbar->setRange(0, viewItems.count() - itemsInViewport);
     3497        vbar->setPageStep(itemsInViewport);
     3498        vbar->setSingleStep(1);
    34693499    } else { // scroll per pixel
    34703500        int contentsHeight = 0;
     
    34753505                contentsHeight += itemHeight(i);
    34763506        }
    3477         q->verticalScrollBar()->setRange(0, contentsHeight - viewportSize.height());
    3478         q->verticalScrollBar()->setPageStep(viewportSize.height());
    3479         q->verticalScrollBar()->setSingleStep(qMax(viewportSize.height() / (itemsInViewport + 1), 2));
     3507        vbar->setRange(0, contentsHeight - viewportSize.height());
     3508        vbar->setPageStep(viewportSize.height());
     3509        vbar->setSingleStep(qMax(viewportSize.height() / (itemsInViewport + 1), 2));
    34803510    }
    34813511
     
    34933523        columnsInViewport = qMax(1, columnsInViewport);
    34943524    if (horizontalScrollMode == QAbstractItemView::ScrollPerItem) {
    3495         q->horizontalScrollBar()->setRange(0, columnCount - columnsInViewport);
    3496         q->horizontalScrollBar()->setPageStep(columnsInViewport);
    3497         q->horizontalScrollBar()->setSingleStep(1);
     3525        hbar->setRange(0, columnCount - columnsInViewport);
     3526        hbar->setPageStep(columnsInViewport);
     3527        hbar->setSingleStep(1);
    34983528    } else { // scroll per pixel
    34993529        const int horizontalLength = header->length();
    35003530        const QSize maxSize = q->maximumViewportSize();
    3501         if (maxSize.width() >= horizontalLength && q->verticalScrollBar()->maximum() <= 0)
     3531        if (maxSize.width() >= horizontalLength && vbar->maximum() <= 0)
    35023532            viewportSize = maxSize;
    3503         q->horizontalScrollBar()->setPageStep(viewportSize.width());
    3504         q->horizontalScrollBar()->setRange(0, qMax(horizontalLength - viewportSize.width(), 0));
    3505         q->horizontalScrollBar()->setSingleStep(qMax(viewportSize.width() / (columnsInViewport + 1), 2));
     3533        hbar->setPageStep(viewportSize.width());
     3534        hbar->setRange(0, qMax(horizontalLength - viewportSize.width(), 0));
     3535        hbar->setSingleStep(qMax(viewportSize.width() / (columnsInViewport + 1), 2));
    35063536    }
    35073537}
     
    35093539int QTreeViewPrivate::itemDecorationAt(const QPoint &pos) const
    35103540{
    3511     const_cast<QTreeView *>(q_func())->executeDelayedItemsLayout();
     3541    executePostedLayout();
    35123542    int x = pos.x();
    35133543    int column = header->logicalIndexAt(x);
     
    35753605    current.first = -2; // -1 is not enough because -1+1 = 0
    35763606    current.second = -2;
    3577     foreach (int logicalColumn, logicalIndexes) {
     3607    for(int i = 0; i < logicalIndexes.count(); ++i) {
     3608        const int logicalColumn = logicalIndexes.at(i);
    35783609        if (current.second + 1 != logicalColumn) {
    35793610            if (current.first != -2) {
     
    37143745        const int delta = end - start + 1;
    37153746
     3747        int previousSibiling = -1;
    37163748        int removedCount = 0;
    37173749        for (int item = firstChildItem; item <= lastChildItem; ) {
     
    37213753            const int count = viewItems.at(item).total + 1;
    37223754            if (modelIndex.row() < start) {
     3755                previousSibiling = item;
    37233756                // not affected by the removal
    37243757                item += count;
     
    37383771        }
    37393772
     3773        if (previousSibiling != -1 && after && model->rowCount(parent) == start)
     3774            viewItems[previousSibiling].hasMoreSiblings = false;
     3775
     3776
    37403777        updateChildCount(parentItem, -removedCount);
     3778        if (parentItem != -1 && viewItems.at(parentItem).total == 0)
     3779            viewItems[parentItem].hasChildren = false; //every children have been removed;
    37413780        if (after) {
    37423781            q->updateGeometries();
     
    38103849#endif
    38113850    QAbstractItemView::currentChanged(current, previous);
     3851
     3852    if (allColumnsShowFocus()) {
     3853        if (previous.isValid()) {
     3854            QRect previousRect = visualRect(previous);
     3855            previousRect.setX(0);
     3856            previousRect.setWidth(viewport()->width());
     3857            viewport()->update(previousRect);
     3858        }
     3859        if (current.isValid()) {
     3860            QRect currentRect = visualRect(current);
     3861            currentRect.setX(0);
     3862            currentRect.setWidth(viewport()->width());
     3863            viewport()->update(currentRect);
     3864        }
     3865    }
    38123866}
    38133867
  • trunk/src/gui/itemviews/qtreeview.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    145145    void sortByColumn(int column, Qt::SortOrder order);
    146146
     147    void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
     148    void selectAll();
     149
    147150Q_SIGNALS:
    148151    void expanded(const QModelIndex &index);
     
    150153
    151154public Q_SLOTS:
    152     void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
    153155    void hideColumn(int column);
    154156    void showColumn(int column);
     
    157159    void resizeColumnToContents(int column);
    158160    void sortByColumn(int column);
    159     void selectAll();
    160161    void expandAll();
    161162    void collapseAll();
     
    223224    Q_DECLARE_PRIVATE(QTreeView)
    224225    Q_DISABLE_COPY(QTreeView)
     226#ifndef QT_NO_ANIMATION
    225227    Q_PRIVATE_SLOT(d_func(), void _q_endAnimatedOperation())
    226     Q_PRIVATE_SLOT(d_func(), void _q_animate())
    227     Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QModelIndex&, const QModelIndex &))
    228     Q_PRIVATE_SLOT(d_func(), void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int))
    229     Q_PRIVATE_SLOT(d_func(), void _q_columnsRemoved(const QModelIndex &, int, int))
     228#endif //QT_NO_ANIMATION
    230229    Q_PRIVATE_SLOT(d_func(), void _q_modelAboutToBeReset())
    231230    Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order))
    232     Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
    233231};
    234232
  • trunk/src/gui/itemviews/qtreeview_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5555
    5656#include "private/qabstractitemview_p.h"
     57#include <QtCore/qvariantanimation.h>
    5758
    5859#ifndef QT_NO_TREEVIEW
     
    6263struct QTreeViewItem
    6364{
    64     QTreeViewItem() : expanded(false), spanning(false), total(0), level(0), height(0) {}
     65    QTreeViewItem() : expanded(false), spanning(false), hasChildren(false),
     66                      hasMoreSiblings(false), total(0), level(0), height(0) {}
    6567    QModelIndex index; // we remove items whenever the indexes are invalidated
    6668    uint expanded : 1;
    6769    uint spanning : 1;
    68     uint total : 30; // total number of children visible
     70    uint hasChildren : 1; // if the item has visible children (even if collapsed)
     71    uint hasMoreSiblings : 1;
     72    uint total : 28; // total number of children visible
    6973    uint level : 16; // indentation
    7074    int height : 16; // row height
     
    8286          itemsExpandable(true), sortingEnabled(false),
    8387          expandsOnDoubleClick(true),
    84           allColumnsShowFocus(false),
     88          allColumnsShowFocus(false), current(0), spanning(false),
    8589          animationsEnabled(false), columnResizeTimerID(0),
    8690          autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false) {}
     
    8993    void initialize();
    9094
    91     struct AnimatedOperation
     95    QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const;
     96
     97#ifndef QT_NO_ANIMATION
     98    struct AnimatedOperation : public QVariantAnimation
    9299    {
    93         enum Type { Expand, Collapse };
    94100        int item;
    95         int top;
    96         int duration;
    97         Type type;
    98101        QPixmap before;
    99102        QPixmap after;
    100     };
     103        QWidget *viewport;
     104        AnimatedOperation() : item(0) { setEasingCurve(QEasingCurve::InOutQuad); }
     105        int top() const { return startValue().toInt(); }
     106        QRect rect() const { QRect rect = viewport->rect(); rect.moveTop(top()); return rect; }
     107        void updateCurrentValue(const QVariant &) { viewport->update(rect()); }
     108        void updateState(State state, State) { if (state == Stopped) before = after = QPixmap(); }
     109    } animatedOperation;
     110    void prepareAnimatedOperation(int item, QVariantAnimation::Direction d);
     111    void beginAnimatedOperation();
     112    void drawAnimatedOperation(QPainter *painter) const;
     113    QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const;
     114    void _q_endAnimatedOperation();
     115#endif //QT_NO_ANIMATION
    101116
    102117    void expand(int item, bool emitSignal);
    103118    void collapse(int item, bool emitSignal);
    104119
    105     void prepareAnimatedOperation(int item, AnimatedOperation::Type type);
    106     void beginAnimatedOperation();
    107     void _q_endAnimatedOperation();
    108     void drawAnimatedOperation(QPainter *painter) const;
    109     QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const;
    110 
    111     inline QRect animationRect() const
    112         { return QRect(0, animatedOperation.top, viewport->width(),
    113                        viewport->height() - animatedOperation.top); }
    114 
    115     void _q_currentChanged(const QModelIndex&, const QModelIndex&);
    116120    void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int);
    117121    void _q_columnsRemoved(const QModelIndex &, int, int);
    118122    void _q_modelAboutToBeReset();
    119     void _q_animate();
    120123    void _q_sortIndicatorChanged(int column, Qt::SortOrder order);
    121124    void _q_modelDestroyed();
     
    178181    // used when expanding and collapsing items
    179182    QSet<QPersistentModelIndex> expandedIndexes;
    180     QStack<bool> expandParent;
    181     AnimatedOperation animatedOperation;
    182183    bool animationsEnabled;
    183184
  • trunk/src/gui/itemviews/qtreewidget.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7676
    7777    \ingroup model-view
    78     \mainclass
     78
    7979*/
    8080
     
    578578        return;
    579579
    580     //layoutAboutToBeChanged and layoutChanged will be called by sortChildren 
     580    //layoutAboutToBeChanged and layoutChanged will be called by sortChildren
    581581    rootItem->sortChildren(column, order, true);
    582582}
     
    623623        lit = sortedInsertionIterator(lit, lst.end(), order, item);
    624624        int newRow = qMax(lit - lst.begin(), 0);
     625
     626        if ((newRow < oldRow) && !(*item < *lst.at(oldRow - 1)) && !(*lst.at(oldRow - 1) < *item ))
     627            newRow = oldRow;
     628
    625629        lit = lst.insert(lit, item);
    626630        if (newRow != oldRow) {
     
    854858        for (int c = 0; c < colCount; ++c) {
    855859            QModelIndex from = createIndex(oldRow, c, item);
    856             if (static_cast<QAbstractItemModelPrivate *>(d_ptr)->persistent.indexes.contains(from)) {
     860            if (static_cast<QAbstractItemModelPrivate *>(d_ptr.data())->persistent.indexes.contains(from)) {
    857861                QModelIndex to = createIndex(r, c, item);
    858862                fromList << from;
     
    15771581        return;
    15781582
    1579     view->viewport()->update( view->d_func()->itemDecorationRect(view->d_func()->index(this)));
     1583    view->scheduleDelayedItemsLayout();
    15801584}
    15811585
     
    17691773        if (children.count() && (itemFlags & Qt::ItemIsTristate))
    17701774            return childrenCheckState(column);
     1775        // fallthrough intended
    17711776   default:
    17721777        if (column >= 0 && column < values.size()) {
     
    17881793{
    17891794    int column = view ? view->sortColumn() : 0;
    1790     return text(column) < other.text(column);
     1795    const QVariant v1 = data(column, Qt::DisplayRole);
     1796    const QVariant v2 = other.data(column, Qt::DisplayRole);
     1797    return QAbstractItemModelPrivate::variantLessThan(v1, v2);
    17911798}
    17921799
     
    18281835    out << values << d->display;
    18291836}
     1837#endif // QT_NO_DATASTREAM
    18301838
    18311839/*!
     
    18631871    return *this;
    18641872}
    1865 
    1866 #endif // QT_NO_DATASTREAM
    18671873
    18681874/*!
     
    20722078{
    20732079    QTreeModel *model = (q->view ? qobject_cast<QTreeModel*>(q->view->model()) : 0);
     2080    if (!model)
     2081        return;
    20742082    model->sortItems(&q->children, column, order);
    20752083    if (climb) {
    20762084        QList<QTreeWidgetItem*>::iterator it = q->children.begin();
    20772085        for (; it != q->children.end(); ++it) {
    2078             //here we call the private object's method to avoid emitting 
     2086            //here we call the private object's method to avoid emitting
    20792087            //the layoutAboutToBeChanged and layoutChanged signals
    20802088            (*it)->d->sortChildren(column, order, climb);
     
    22782286void QTreeWidgetPrivate::_q_sort()
    22792287{
    2280     Q_Q(QTreeWidget);
    22812288    if (sortingEnabled) {
    2282         int column = q->header()->sortIndicatorSection();
    2283         Qt::SortOrder order = q->header()->sortIndicatorOrder();
    2284         model()->sort(column, order);
     2289        int column = header->sortIndicatorSection();
     2290        Qt::SortOrder order = header->sortIndicatorOrder();
     2291        treeModel()->sort(column, order);
    22852292    }
    22862293}
     
    22912298    QModelIndexList indices = selected.indexes();
    22922299    int i;
    2293     QTreeModel *m = model();
     2300    QTreeModel *m = treeModel();
    22942301    for (i = 0; i < indices.count(); ++i) {
    22952302        QTreeWidgetItem *item = m->item(indices.at(i));
     
    23092316                                        const QModelIndex &bottomRight)
    23102317{
    2311     Q_Q(QTreeWidget);
    23122318    if (sortingEnabled && topLeft.isValid() && bottomRight.isValid()
    2313         && !model()->sortPendingTimer.isActive()) {
    2314         int column = q->header()->sortIndicatorSection();
     2319        && !treeModel()->sortPendingTimer.isActive()) {
     2320        int column = header->sortIndicatorSection();
    23152321        if (column >= topLeft.column() && column <= bottomRight.column()) {
    2316             Qt::SortOrder order = q->header()->sortIndicatorOrder();
    2317             model()->ensureSorted(column, order, topLeft.row(),
     2322            Qt::SortOrder order = header->sortIndicatorOrder();
     2323            treeModel()->ensureSorted(column, order, topLeft.row(),
    23182324                                  bottomRight.row(), topLeft.parent());
    23192325        }
     
    23282334
    23292335  \ingroup model-view
    2330   \mainclass
     2336
    23312337
    23322338  The QTreeWidget class is a convenience class that provides a standard
     
    24372443    expandAll() is invoked.
    24382444
    2439     \sa isItemExpanded(), itemCollapsed(), expandItem()
     2445    \sa QTreeWidgetItem::isExpanded(), itemCollapsed(), expandItem()
    24402446*/
    24412447
     
    24492455    collapseAll() is invoked.
    24502456
    2451     \sa isItemExpanded(), itemExpanded(), collapseItem()
     2457    \sa QTreeWidgetItem::isExpanded(), itemExpanded(), collapseItem()
    24522458*/
    24532459
     
    25432549{
    25442550    Q_D(const QTreeWidget);
    2545     return d->model()->columnCount();
     2551    return d->model->columnCount();
    25462552}
    25472553
     
    25552561    if (columns < 0)
    25562562        return;
    2557     d->model()->setColumnCount(columns);
     2563    d->treeModel()->setColumnCount(columns);
    25582564}
    25592565
     
    25722578{
    25732579    Q_D(const QTreeWidget);
    2574     return d->model()->rootItem;
     2580    return d->treeModel()->rootItem;
    25752581}
    25762582
     
    25852591{
    25862592    Q_D(const QTreeWidget);
    2587     return d->model()->rootItem->child(index);
     2593    return d->treeModel()->rootItem->child(index);
    25882594}
    25892595
     
    26002606{
    26012607    Q_D(const QTreeWidget);
    2602     return d->model()->rootItem->childCount();
     2608    return d->treeModel()->rootItem->childCount();
    26032609}
    26042610
     
    26142620{
    26152621    Q_D(QTreeWidget);
    2616     d->model()->rootItem->insertChild(index, item);
     2622    d->treeModel()->rootItem->insertChild(index, item);
    26172623}
    26182624
     
    26392645{
    26402646    Q_D(QTreeWidget);
    2641     return d->model()->rootItem->takeChild(index);
     2647    return d->treeModel()->rootItem->takeChild(index);
    26422648}
    26432649
     
    26482654{
    26492655    Q_D(QTreeWidget);
    2650     d->model()->executePendingSort();
    2651     return d->model()->rootItem->children.indexOf(item);
     2656    d->treeModel()->executePendingSort();
     2657    return d->treeModel()->rootItem->children.indexOf(item);
    26522658}
    26532659
     
    26612667{
    26622668    Q_D(const QTreeWidget);
    2663     d->model()->executePendingSort();
    2664     return d->model()->rootItem->children.indexOf(item);
     2669    d->treeModel()->executePendingSort();
     2670    return d->treeModel()->rootItem->children.indexOf(item);
    26652671}
    26662672
     
    26772683{
    26782684    Q_D(QTreeWidget);
    2679     d->model()->rootItem->insertChildren(index, items);
     2685    d->treeModel()->rootItem->insertChildren(index, items);
    26802686}
    26812687
     
    26992705{
    27002706    Q_D(const QTreeWidget);
    2701     return d->model()->headerItem;
     2707    return d->treeModel()->headerItem;
    27022708}
    27032709
     
    27202726    int oldCount = columnCount();
    27212727    if (oldCount < item->columnCount())
    2722          d->model()->beginInsertColumns(QModelIndex(), oldCount, item->columnCount());
     2728         d->treeModel()->beginInsertColumns(QModelIndex(), oldCount, item->columnCount());
    27232729    else
    2724          d->model()->beginRemoveColumns(QModelIndex(), item->columnCount(), oldCount);
    2725     delete d->model()->headerItem;
    2726     d->model()->headerItem = item;
     2730         d->treeModel()->beginRemoveColumns(QModelIndex(), item->columnCount(), oldCount);
     2731    delete d->treeModel()->headerItem;
     2732    d->treeModel()->headerItem = item;
    27272733    if (oldCount < item->columnCount())
    2728         d->model()->endInsertColumns();
     2734        d->treeModel()->endInsertColumns();
    27292735    else
    2730         d->model()->endRemoveColumns();
    2731     d->model()->headerDataChanged(Qt::Horizontal, 0, oldCount);
     2736        d->treeModel()->endRemoveColumns();
     2737    d->treeModel()->headerDataChanged(Qt::Horizontal, 0, oldCount);
    27322738}
    27332739
     
    27462752    if (columnCount() < labels.count())
    27472753        setColumnCount(labels.count());
    2748     QTreeModel *model = d->model();
    2749     QTreeWidgetItem *item = model->headerItem;
     2754    QTreeWidgetItem *item = d->treeModel()->headerItem;
    27502755    for (int i = 0; i < labels.count(); ++i)
    27512756        item->setText(i, labels.at(i));
     
    27842789  Sets the current \a item in the tree widget.
    27852790
    2786   Depending on the current selection mode, the item may also be selected.
     2791  Unless the selection mode is \l{QAbstractItemView::}{NoSelection},
     2792  the item is also be selected.
    27872793
    27882794  \sa currentItem(), currentItemChanged()
     
    28462852{
    28472853    Q_D(const QTreeWidget);
    2848     return visualRect(d->index(item));
     2854    //the visual rect for an item is across all columns. So we need to determine
     2855        //what is the first and last column and get their visual index rects
     2856    QModelIndex base = d->index(item);
     2857    const int firstVisiblesection = header()->logicalIndexAt(- header()->offset());
     2858    const int lastVisibleSection = header()->logicalIndexAt(header()->length() - header()->offset() - 1);
     2859    QModelIndex first = base.sibling(base.row(), header()->logicalIndex(firstVisiblesection));
     2860    QModelIndex last = base.sibling(base.row(), header()->logicalIndex(lastVisibleSection));
     2861    return visualRect(first) | visualRect(last);
    28492862}
    28502863
     
    28752888    Q_D(QTreeWidget);
    28762889    header()->setSortIndicator(column, order);
    2877     d->model()->sort(column, order);
     2890    d->model->sort(column, order);
    28782891}
    28792892
     
    30423055{
    30433056    Q_D(const QTreeWidget);
    3044     QModelIndexList indexes = d->model()->match(model()->index(0, column, QModelIndex()),
     3057    QModelIndexList indexes = d->model->match(model()->index(0, column, QModelIndex()),
    30453058                                                Qt::DisplayRole, text, -1, flags);
    30463059    QList<QTreeWidgetItem*> items;
     
    30603073{
    30613074    Q_D(const QTreeWidget);
    3062     if (item == d->model()->headerItem)
     3075    if (item == d->treeModel()->headerItem)
    30633076        return header()->isHidden();
    30643077    if (d->hiddenIndexes.isEmpty())
    30653078        return false;
    3066     QTreeModel::SkipSorting skipSorting(d->model());
     3079    QTreeModel::SkipSorting skipSorting(d->treeModel());
    30673080    return d->isRowHidden(d->index(item));
    30683081}
     
    30803093{
    30813094    Q_D(QTreeWidget);
    3082     if (item == d->model()->headerItem) {
     3095    if (item == d->treeModel()->headerItem) {
    30833096        header()->setHidden(hide);
    30843097    } else {
     
    31003113{
    31013114    Q_D(const QTreeWidget);
    3102     QTreeModel::SkipSorting skipSorting(d->model());
     3115    QTreeModel::SkipSorting skipSorting(d->treeModel());
    31033116    return isExpanded(d->index(item));
    31043117}
     
    31103123    \sa expandItem(), collapseItem(), itemExpanded()
    31113124
    3112   \obsolete
    3113 
    3114   This function is deprecated. Use \l{QTreeWidgetItem::setExpanded()} instead.
     3125    \obsolete
     3126
     3127    This function is deprecated. Use \l{QTreeWidgetItem::setExpanded()} instead.
    31153128*/
    31163129void QTreeWidget::setItemExpanded(const QTreeWidgetItem *item, bool expand)
    31173130{
    31183131    Q_D(QTreeWidget);
    3119     QTreeModel::SkipSorting skipSorting(d->model());
     3132    QTreeModel::SkipSorting skipSorting(d->treeModel());
    31203133    setExpanded(d->index(item), expand);
    31213134}
     
    31323145{
    31333146    Q_D(const QTreeWidget);
    3134     if (item == d->model()->headerItem)
     3147    if (item == d->treeModel()->headerItem)
    31353148        return false; // We can't set the header items to spanning
    31363149    const QModelIndex index = d->index(item);
     
    31493162{
    31503163    Q_D(QTreeWidget);
    3151     if (item == d->model()->headerItem)
     3164    if (item == d->treeModel()->headerItem)
    31523165        return; // We can't set header items to spanning
    31533166    const QModelIndex index = d->index(item);
     
    31633176{
    31643177    Q_D(const QTreeWidget);
    3165     if (item == d->model()->headerItem)
     3178    if (item == d->treeModel()->headerItem)
    31663179        return 0;
    31673180    const QModelIndex index = d->index(item);
     
    31783191{
    31793192    Q_D(const QTreeWidget);
    3180     if (item == d->model()->headerItem)
     3193    if (item == d->treeModel()->headerItem)
    31813194        return 0;
    31823195    const QModelIndex index = d->index(item);
     
    32183231{
    32193232    Q_D(QTreeWidget);
    3220     QTreeModel::SkipSorting skipSorting(d->model());
     3233    QTreeModel::SkipSorting skipSorting(d->treeModel());
    32213234    expand(d->index(item));
    32223235}
     
    32313244{
    32323245    Q_D(QTreeWidget);
    3233     QTreeModel::SkipSorting skipSorting(d->model());
     3246    QTreeModel::SkipSorting skipSorting(d->treeModel());
    32343247    collapse(d->index(item));
    32353248}
     
    32483261    Q_D(QTreeWidget);
    32493262    selectionModel()->clear();
    3250     d->model()->clear();
     3263    d->treeModel()->clear();
    32513264}
    32523265
     
    32733286{
    32743287    Q_D(const QTreeWidget);
    3275     if (d->model()->cachedIndexes.isEmpty()) {
     3288    if (d->treeModel()->cachedIndexes.isEmpty()) {
    32763289        QList<QModelIndex> indexes;
    32773290        for (int i = 0; i < items.count(); ++i) {
     
    32813294            }
    32823295        }
    3283         return model()->QAbstractItemModel::mimeData(indexes);
    3284     }
    3285     return d->model()->internalMimeData();
     3296        return d->model->QAbstractItemModel::mimeData(indexes);
     3297    }
     3298    return d->treeModel()->internalMimeData();
    32863299}
    32873300
     
    34273440    Q_D(QTreeWidget);
    34283441    if (e->type() == QEvent::Polish)
    3429         d->model()->executePendingSort();
     3442        d->treeModel()->executePendingSort();
    34303443    return QTreeView::event(e);
    34313444}
  • trunk/src/gui/itemviews/qtreewidget.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/itemviews/qtreewidget_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    220220public:
    221221    QTreeWidgetPrivate() : QTreeViewPrivate(), explicitSortColumn(-1) {}
    222     inline QTreeModel *model() const
    223         { return qobject_cast<QTreeModel*>(q_func()->model()); }
     222    inline QTreeModel *treeModel() const { return qobject_cast<QTreeModel*>(model); }
    224223    inline QModelIndex index(const QTreeWidgetItem *item, int column = 0) const
    225         { return model()->index(item, column); }
     224        { return treeModel()->index(item, column); }
    226225    inline QTreeWidgetItem *item(const QModelIndex &index) const
    227         { return model()->item(index); }
     226        { return treeModel()->item(index); }
    228227    void _q_emitItemPressed(const QModelIndex &index);
    229228    void _q_emitItemClicked(const QModelIndex &index);
  • trunk/src/gui/itemviews/qtreewidgetitemiterator.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    9898    QTreeModel *model = qobject_cast<QTreeModel*>(widget->model());
    9999    Q_ASSERT(model);
    100     d_ptr = new QTreeWidgetItemIteratorPrivate(this, model);
     100    d_ptr.reset(new QTreeWidgetItemIteratorPrivate(this, model));
    101101    model->iterators.append(this);
    102102    if (!model->rootItem->children.isEmpty()) current = model->rootItem->children.first();
     
    151151{
    152152    d_func()->m_model->iterators.removeAll(this);
    153     delete d_ptr;
    154153}
    155154
  • trunk/src/gui/itemviews/qtreewidgetitemiterator.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4444
    4545#include <QtCore/qglobal.h>
     46#include <QtCore/qscopedpointer.h>
    4647
    4748QT_BEGIN_HEADER
     
    106107private:
    107108    bool matchesFlags(const QTreeWidgetItem *item) const;
    108     QTreeWidgetItemIteratorPrivate *d_ptr;
     109    QScopedPointer<QTreeWidgetItemIteratorPrivate> d_ptr;
    109110    QTreeWidgetItem *current;
    110111    IteratorFlags flags;
  • trunk/src/gui/itemviews/qtreewidgetitemiterator_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7474
    7575    QTreeWidgetItemIteratorPrivate(const QTreeWidgetItemIteratorPrivate& other)
    76         : m_currentIndex(other.m_currentIndex), m_model(other.m_model), m_parentIndex(other.m_parentIndex)
     76        : m_currentIndex(other.m_currentIndex), m_model(other.m_model),
     77          m_parentIndex(other.m_parentIndex), q_ptr(other.q_ptr)
    7778    {
    7879
  • trunk/src/gui/itemviews/qwidgetitemdata_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
Note: See TracChangeset for help on using the changeset viewer.