doc/src/snippets/modelview-subclasses/view.cpp
changeset 0 1918ee327afb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/src/snippets/modelview-subclasses/view.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,315 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+    view.cpp
+
+    Provides a view to represent a one-dimensional sequence of integers
+    obtained from a list model as a series of rows.
+*/
+
+#include <QAbstractItemModel>
+#include <QBrush>
+#include <QItemSelection>
+#include <QPainter>
+#include <QPaintEvent>
+#include <QPen>
+#include <QPoint>
+#include <QResizeEvent>
+#include <QScrollBar>
+#include <QSizePolicy>
+
+#include "view.h"
+
+LinearView::LinearView(QWidget *parent)
+    : QAbstractItemView(parent)
+{
+    setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+}
+
+/*!
+    Returns the position of the item in viewport coordinates.
+*/
+
+QRect LinearView::itemViewportRect(const QModelIndex &index) const
+{
+    QRect rect = itemRect(index);
+    QRect result(rect.left() - horizontalScrollBar()->value(),
+                 rect.top() - verticalScrollBar()->value(),
+                 rect.width(), viewport()->height());
+
+    return result;
+}
+
+/*!
+    Returns the rectangle of the item at position \a index in the
+    model. The rectangle is in contents coordinates.
+*/
+
+QRect LinearView::itemRect(const QModelIndex &index) const
+{
+    if (!index.isValid())
+        return QRect();
+    else
+        return QRect(index.row(), 0, 1, 1);
+}
+
+
+void LinearView::ensureVisible(const QModelIndex &index)
+{
+    QRect area = viewport()->rect();
+    QRect rect = itemViewportRect(index);
+
+    if (rect.left() < area.left())
+        horizontalScrollBar()->setValue(
+            horizontalScrollBar()->value() - rect.left());
+    else if (rect.right() > area.right())
+        horizontalScrollBar()->setValue(
+            horizontalScrollBar()->value() + rect.left() - area.width());
+}
+
+/*!
+    Returns the item that covers the coordinate given in the view.
+*/
+
+QModelIndex LinearView::itemAt(int x, int /* y */) const
+{
+    int row = x + horizontalScrollBar()->value();
+
+    return model()->index(row, 0, QModelIndex());
+}
+
+//void LinearView::dataChanged(const QModelIndex &/* topLeft */,
+//    const QModelIndex &/* bottomRight */)
+//{
+//    updateGeometries();
+//    if (isVisible())
+//        repaint();
+//}
+
+void LinearView::rowsInserted(const QModelIndex &/* parent */, int /* start */,
+    int /* end */)
+{
+    updateGeometries();
+    if (isVisible())
+        repaint();
+}
+
+void LinearView::rowsRemoved(const QModelIndex &/* parent */, int /* start */,
+    int /* end */)
+{
+    updateGeometries();
+    if (isVisible())
+        repaint();
+}
+/*
+void LinearView::verticalScrollbarAction(int action)
+{
+}
+
+void LinearView::horizontalScrollbarAction(int action)
+{
+}
+*/
+
+/*!
+    Select the items in the model that lie within the rectangle specified by
+    \a rect, using the selection \a command.
+*/
+
+void LinearView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
+{
+    QModelIndex leftIndex = itemAt(rect.left(), 0);
+    QModelIndex rightIndex = itemAt(rect.right(), 0);
+
+    QItemSelection selection(leftIndex, rightIndex);
+
+    selectionModel()->select(selection, command);
+}
+
+QModelIndex LinearView::moveCursor(QAbstractItemView::CursorAction cursorAction,
+                                   Qt::KeyboardModifiers)
+{
+    QModelIndex current = currentIndex();
+
+    switch (cursorAction) {
+    case MoveLeft:{
+        if (current.row() > 0)
+            return model()->index(current.row() - 1, 0, QModelIndex());
+        else
+            return model()->index(0, 0, QModelIndex());
+        break;}
+    case MoveRight:{
+        if (current.row() < rows(current) - 1)
+            return model()->index(current.row() + 1, 0, QModelIndex());
+        else
+            return model()->index(rows(current) - 1, 0,QModelIndex());
+        break;}
+    case MoveUp:
+        return current;
+    case MoveDown:
+        return current;
+    case MovePageUp:
+        return current;
+    case MovePageDown:
+        return current;
+    case MoveHome:
+        return model()->index(0, 0, QModelIndex());
+    case MoveEnd:
+        return model()->index(rows(current) - 1, 0, QModelIndex());
+    default:
+        return current;
+    }
+}
+
+int LinearView::horizontalOffset() const
+{
+    return horizontalScrollBar()->value();
+}
+
+int LinearView::verticalOffset() const
+{
+    return verticalScrollBar()->value();
+}
+
+/*!
+    Returns a rectangle corresponding to the selection in viewport cooridinates.
+*/
+
+QRect LinearView::selectionViewportRect(const QItemSelection &selection) const
+{
+    int ranges = selection.count();
+
+    if (ranges == 0)
+        return QRect();
+
+    // Note that we use the top and bottom functions of the selection range
+    // since the data is stored in rows.
+
+    int firstRow = selection.at(0).top();
+    int lastRow = selection.at(0).top();
+
+    for (int i = 0; i < ranges; ++i) {
+        firstRow = qMin(firstRow, selection.at(i).top());
+        lastRow = qMax(lastRow, selection.at(i).bottom());
+    }
+
+    QModelIndex firstItem = model()->index(qMin(firstRow, lastRow), 0,
+        QModelIndex());
+    QModelIndex lastItem = model()->index(qMax(firstRow, lastRow), 0,
+        QModelIndex());
+
+    QRect firstRect = itemViewportRect(firstItem);
+    QRect lastRect = itemViewportRect(lastItem);
+
+    return QRect(firstRect.left(), firstRect.top(),
+        lastRect.right() - firstRect.left(), firstRect.height());
+}
+
+void LinearView::paintEvent(QPaintEvent *event)
+{
+    QPainter painter(viewport());
+
+    QRect updateRect = event->rect();
+    QBrush background(Qt::black);
+    QPen foreground(Qt::white);
+
+    painter.fillRect(updateRect, background);
+    painter.setPen(foreground);
+
+    QModelIndex firstItem = itemAt(updateRect.left(), updateRect.top());
+    if (!firstItem.isValid())
+        firstItem = model()->index(0, 0, QModelIndex());
+
+    QModelIndex lastItem = itemAt(updateRect.right(), updateRect.bottom());
+    if (!lastItem.isValid())
+        lastItem = model()->index(rows() - 1, 0, QModelIndex());
+
+    int x = updateRect.left();
+    //int top = updateRect.top();
+    //int bottom = updateRect.bottom();
+
+    int row = firstItem.row();
+    QModelIndex index = model()->index(row, 0, QModelIndex());
+    int value = model()->data(index, Qt::DisplayRole).toInt();
+    int midPoint = viewport()->height()/2;
+    int y2 = midPoint - int(value * midPoint/255.0);
+
+    while (row <= lastItem.row()) {
+
+        QModelIndex index = model()->index(row, 0, QModelIndex());
+        int value = model()->data(index, Qt::DisplayRole).toInt();
+
+        int y1 = y2;
+        y2 = midPoint - int(value * midPoint/255.0);
+
+        painter.drawLine(x-1, y1, x, y2);
+        ++row; ++x;
+    }
+}
+
+void LinearView::resizeEvent(QResizeEvent * /* event */)
+{
+    updateGeometries();
+}
+
+void LinearView::updateGeometries()
+{
+    if (viewport()->width() < rows()) {
+        horizontalScrollBar()->setPageStep(viewport()->width());
+        horizontalScrollBar()->setRange(0, rows() - viewport()->width() - 1);
+    }
+}
+
+QSize LinearView::sizeHint() const
+{
+    return QSize(rows(), 200);
+}
+
+int LinearView::rows(const QModelIndex &index) const
+{
+    return model()->rowCount(model()->parent(index));
+}
+
+bool LinearView::isIndexHidden(const QModelIndex &index) const
+{
+    return false;
+}