doc/src/snippets/modelview-subclasses/view.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the documentation of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 /*!
       
    43     view.cpp
       
    44 
       
    45     Provides a view to represent a one-dimensional sequence of integers
       
    46     obtained from a list model as a series of rows.
       
    47 */
       
    48 
       
    49 #include <QAbstractItemModel>
       
    50 #include <QBrush>
       
    51 #include <QItemSelection>
       
    52 #include <QPainter>
       
    53 #include <QPaintEvent>
       
    54 #include <QPen>
       
    55 #include <QPoint>
       
    56 #include <QResizeEvent>
       
    57 #include <QScrollBar>
       
    58 #include <QSizePolicy>
       
    59 
       
    60 #include "view.h"
       
    61 
       
    62 LinearView::LinearView(QWidget *parent)
       
    63     : QAbstractItemView(parent)
       
    64 {
       
    65     setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
       
    66 }
       
    67 
       
    68 /*!
       
    69     Returns the position of the item in viewport coordinates.
       
    70 */
       
    71 
       
    72 QRect LinearView::itemViewportRect(const QModelIndex &index) const
       
    73 {
       
    74     QRect rect = itemRect(index);
       
    75     QRect result(rect.left() - horizontalScrollBar()->value(),
       
    76                  rect.top() - verticalScrollBar()->value(),
       
    77                  rect.width(), viewport()->height());
       
    78 
       
    79     return result;
       
    80 }
       
    81 
       
    82 /*!
       
    83     Returns the rectangle of the item at position \a index in the
       
    84     model. The rectangle is in contents coordinates.
       
    85 */
       
    86 
       
    87 QRect LinearView::itemRect(const QModelIndex &index) const
       
    88 {
       
    89     if (!index.isValid())
       
    90         return QRect();
       
    91     else
       
    92         return QRect(index.row(), 0, 1, 1);
       
    93 }
       
    94 
       
    95 
       
    96 void LinearView::ensureVisible(const QModelIndex &index)
       
    97 {
       
    98     QRect area = viewport()->rect();
       
    99     QRect rect = itemViewportRect(index);
       
   100 
       
   101     if (rect.left() < area.left())
       
   102         horizontalScrollBar()->setValue(
       
   103             horizontalScrollBar()->value() - rect.left());
       
   104     else if (rect.right() > area.right())
       
   105         horizontalScrollBar()->setValue(
       
   106             horizontalScrollBar()->value() + rect.left() - area.width());
       
   107 }
       
   108 
       
   109 /*!
       
   110     Returns the item that covers the coordinate given in the view.
       
   111 */
       
   112 
       
   113 QModelIndex LinearView::itemAt(int x, int /* y */) const
       
   114 {
       
   115     int row = x + horizontalScrollBar()->value();
       
   116 
       
   117     return model()->index(row, 0, QModelIndex());
       
   118 }
       
   119 
       
   120 //void LinearView::dataChanged(const QModelIndex &/* topLeft */,
       
   121 //    const QModelIndex &/* bottomRight */)
       
   122 //{
       
   123 //    updateGeometries();
       
   124 //    if (isVisible())
       
   125 //        repaint();
       
   126 //}
       
   127 
       
   128 void LinearView::rowsInserted(const QModelIndex &/* parent */, int /* start */,
       
   129     int /* end */)
       
   130 {
       
   131     updateGeometries();
       
   132     if (isVisible())
       
   133         repaint();
       
   134 }
       
   135 
       
   136 void LinearView::rowsRemoved(const QModelIndex &/* parent */, int /* start */,
       
   137     int /* end */)
       
   138 {
       
   139     updateGeometries();
       
   140     if (isVisible())
       
   141         repaint();
       
   142 }
       
   143 /*
       
   144 void LinearView::verticalScrollbarAction(int action)
       
   145 {
       
   146 }
       
   147 
       
   148 void LinearView::horizontalScrollbarAction(int action)
       
   149 {
       
   150 }
       
   151 */
       
   152 
       
   153 /*!
       
   154     Select the items in the model that lie within the rectangle specified by
       
   155     \a rect, using the selection \a command.
       
   156 */
       
   157 
       
   158 void LinearView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
       
   159 {
       
   160     QModelIndex leftIndex = itemAt(rect.left(), 0);
       
   161     QModelIndex rightIndex = itemAt(rect.right(), 0);
       
   162 
       
   163     QItemSelection selection(leftIndex, rightIndex);
       
   164 
       
   165     selectionModel()->select(selection, command);
       
   166 }
       
   167 
       
   168 QModelIndex LinearView::moveCursor(QAbstractItemView::CursorAction cursorAction,
       
   169                                    Qt::KeyboardModifiers)
       
   170 {
       
   171     QModelIndex current = currentIndex();
       
   172 
       
   173     switch (cursorAction) {
       
   174     case MoveLeft:{
       
   175         if (current.row() > 0)
       
   176             return model()->index(current.row() - 1, 0, QModelIndex());
       
   177         else
       
   178             return model()->index(0, 0, QModelIndex());
       
   179         break;}
       
   180     case MoveRight:{
       
   181         if (current.row() < rows(current) - 1)
       
   182             return model()->index(current.row() + 1, 0, QModelIndex());
       
   183         else
       
   184             return model()->index(rows(current) - 1, 0,QModelIndex());
       
   185         break;}
       
   186     case MoveUp:
       
   187         return current;
       
   188     case MoveDown:
       
   189         return current;
       
   190     case MovePageUp:
       
   191         return current;
       
   192     case MovePageDown:
       
   193         return current;
       
   194     case MoveHome:
       
   195         return model()->index(0, 0, QModelIndex());
       
   196     case MoveEnd:
       
   197         return model()->index(rows(current) - 1, 0, QModelIndex());
       
   198     default:
       
   199         return current;
       
   200     }
       
   201 }
       
   202 
       
   203 int LinearView::horizontalOffset() const
       
   204 {
       
   205     return horizontalScrollBar()->value();
       
   206 }
       
   207 
       
   208 int LinearView::verticalOffset() const
       
   209 {
       
   210     return verticalScrollBar()->value();
       
   211 }
       
   212 
       
   213 /*!
       
   214     Returns a rectangle corresponding to the selection in viewport cooridinates.
       
   215 */
       
   216 
       
   217 QRect LinearView::selectionViewportRect(const QItemSelection &selection) const
       
   218 {
       
   219     int ranges = selection.count();
       
   220 
       
   221     if (ranges == 0)
       
   222         return QRect();
       
   223 
       
   224     // Note that we use the top and bottom functions of the selection range
       
   225     // since the data is stored in rows.
       
   226 
       
   227     int firstRow = selection.at(0).top();
       
   228     int lastRow = selection.at(0).top();
       
   229 
       
   230     for (int i = 0; i < ranges; ++i) {
       
   231         firstRow = qMin(firstRow, selection.at(i).top());
       
   232         lastRow = qMax(lastRow, selection.at(i).bottom());
       
   233     }
       
   234 
       
   235     QModelIndex firstItem = model()->index(qMin(firstRow, lastRow), 0,
       
   236         QModelIndex());
       
   237     QModelIndex lastItem = model()->index(qMax(firstRow, lastRow), 0,
       
   238         QModelIndex());
       
   239 
       
   240     QRect firstRect = itemViewportRect(firstItem);
       
   241     QRect lastRect = itemViewportRect(lastItem);
       
   242 
       
   243     return QRect(firstRect.left(), firstRect.top(),
       
   244         lastRect.right() - firstRect.left(), firstRect.height());
       
   245 }
       
   246 
       
   247 void LinearView::paintEvent(QPaintEvent *event)
       
   248 {
       
   249     QPainter painter(viewport());
       
   250 
       
   251     QRect updateRect = event->rect();
       
   252     QBrush background(Qt::black);
       
   253     QPen foreground(Qt::white);
       
   254 
       
   255     painter.fillRect(updateRect, background);
       
   256     painter.setPen(foreground);
       
   257 
       
   258     QModelIndex firstItem = itemAt(updateRect.left(), updateRect.top());
       
   259     if (!firstItem.isValid())
       
   260         firstItem = model()->index(0, 0, QModelIndex());
       
   261 
       
   262     QModelIndex lastItem = itemAt(updateRect.right(), updateRect.bottom());
       
   263     if (!lastItem.isValid())
       
   264         lastItem = model()->index(rows() - 1, 0, QModelIndex());
       
   265 
       
   266     int x = updateRect.left();
       
   267     //int top = updateRect.top();
       
   268     //int bottom = updateRect.bottom();
       
   269 
       
   270     int row = firstItem.row();
       
   271     QModelIndex index = model()->index(row, 0, QModelIndex());
       
   272     int value = model()->data(index, Qt::DisplayRole).toInt();
       
   273     int midPoint = viewport()->height()/2;
       
   274     int y2 = midPoint - int(value * midPoint/255.0);
       
   275 
       
   276     while (row <= lastItem.row()) {
       
   277 
       
   278         QModelIndex index = model()->index(row, 0, QModelIndex());
       
   279         int value = model()->data(index, Qt::DisplayRole).toInt();
       
   280 
       
   281         int y1 = y2;
       
   282         y2 = midPoint - int(value * midPoint/255.0);
       
   283 
       
   284         painter.drawLine(x-1, y1, x, y2);
       
   285         ++row; ++x;
       
   286     }
       
   287 }
       
   288 
       
   289 void LinearView::resizeEvent(QResizeEvent * /* event */)
       
   290 {
       
   291     updateGeometries();
       
   292 }
       
   293 
       
   294 void LinearView::updateGeometries()
       
   295 {
       
   296     if (viewport()->width() < rows()) {
       
   297         horizontalScrollBar()->setPageStep(viewport()->width());
       
   298         horizontalScrollBar()->setRange(0, rows() - viewport()->width() - 1);
       
   299     }
       
   300 }
       
   301 
       
   302 QSize LinearView::sizeHint() const
       
   303 {
       
   304     return QSize(rows(), 200);
       
   305 }
       
   306 
       
   307 int LinearView::rows(const QModelIndex &index) const
       
   308 {
       
   309     return model()->rowCount(model()->parent(index));
       
   310 }
       
   311 
       
   312 bool LinearView::isIndexHidden(const QModelIndex &index) const
       
   313 {
       
   314     return false;
       
   315 }