source: trunk/doc/src/snippets/modelview-subclasses/view.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 8.9 KB
RevLine 
[2]1/****************************************************************************
2**
[846]3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
[561]4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
[2]6**
7** This file is part of the documentation of the Qt Toolkit.
8**
[846]9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
[2]11**
[846]12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
[2]25**
[846]26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
[2]37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41/*!
42 view.cpp
43
44 Provides a view to represent a one-dimensional sequence of integers
45 obtained from a list model as a series of rows.
46*/
47
48#include <QAbstractItemModel>
49#include <QBrush>
50#include <QItemSelection>
51#include <QPainter>
52#include <QPaintEvent>
53#include <QPen>
54#include <QPoint>
55#include <QResizeEvent>
56#include <QScrollBar>
57#include <QSizePolicy>
58
59#include "view.h"
60
61LinearView::LinearView(QWidget *parent)
62 : QAbstractItemView(parent)
63{
64 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
65}
66
67/*!
68 Returns the position of the item in viewport coordinates.
69*/
70
71QRect LinearView::itemViewportRect(const QModelIndex &index) const
72{
73 QRect rect = itemRect(index);
74 QRect result(rect.left() - horizontalScrollBar()->value(),
75 rect.top() - verticalScrollBar()->value(),
76 rect.width(), viewport()->height());
77
78 return result;
79}
80
81/*!
82 Returns the rectangle of the item at position \a index in the
83 model. The rectangle is in contents coordinates.
84*/
85
86QRect LinearView::itemRect(const QModelIndex &index) const
87{
88 if (!index.isValid())
89 return QRect();
90 else
91 return QRect(index.row(), 0, 1, 1);
92}
93
94
95void LinearView::ensureVisible(const QModelIndex &index)
96{
97 QRect area = viewport()->rect();
98 QRect rect = itemViewportRect(index);
99
100 if (rect.left() < area.left())
101 horizontalScrollBar()->setValue(
102 horizontalScrollBar()->value() - rect.left());
103 else if (rect.right() > area.right())
104 horizontalScrollBar()->setValue(
105 horizontalScrollBar()->value() + rect.left() - area.width());
106}
107
108/*!
109 Returns the item that covers the coordinate given in the view.
110*/
111
112QModelIndex LinearView::itemAt(int x, int /* y */) const
113{
114 int row = x + horizontalScrollBar()->value();
115
116 return model()->index(row, 0, QModelIndex());
117}
118
119//void LinearView::dataChanged(const QModelIndex &/* topLeft */,
120// const QModelIndex &/* bottomRight */)
121//{
122// updateGeometries();
123// if (isVisible())
124// repaint();
125//}
126
127void LinearView::rowsInserted(const QModelIndex &/* parent */, int /* start */,
128 int /* end */)
129{
130 updateGeometries();
131 if (isVisible())
132 repaint();
133}
134
135void LinearView::rowsRemoved(const QModelIndex &/* parent */, int /* start */,
136 int /* end */)
137{
138 updateGeometries();
139 if (isVisible())
140 repaint();
141}
142/*
143void LinearView::verticalScrollbarAction(int action)
144{
145}
146
147void LinearView::horizontalScrollbarAction(int action)
148{
149}
150*/
151
152/*!
153 Select the items in the model that lie within the rectangle specified by
154 \a rect, using the selection \a command.
155*/
156
157void LinearView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
158{
159 QModelIndex leftIndex = itemAt(rect.left(), 0);
160 QModelIndex rightIndex = itemAt(rect.right(), 0);
161
162 QItemSelection selection(leftIndex, rightIndex);
163
164 selectionModel()->select(selection, command);
165}
166
167QModelIndex LinearView::moveCursor(QAbstractItemView::CursorAction cursorAction,
168 Qt::KeyboardModifiers)
169{
170 QModelIndex current = currentIndex();
171
172 switch (cursorAction) {
173 case MoveLeft:{
174 if (current.row() > 0)
175 return model()->index(current.row() - 1, 0, QModelIndex());
176 else
177 return model()->index(0, 0, QModelIndex());
178 break;}
179 case MoveRight:{
180 if (current.row() < rows(current) - 1)
181 return model()->index(current.row() + 1, 0, QModelIndex());
182 else
183 return model()->index(rows(current) - 1, 0,QModelIndex());
184 break;}
185 case MoveUp:
186 return current;
187 case MoveDown:
188 return current;
189 case MovePageUp:
190 return current;
191 case MovePageDown:
192 return current;
193 case MoveHome:
194 return model()->index(0, 0, QModelIndex());
195 case MoveEnd:
196 return model()->index(rows(current) - 1, 0, QModelIndex());
197 default:
198 return current;
199 }
200}
201
202int LinearView::horizontalOffset() const
203{
204 return horizontalScrollBar()->value();
205}
206
207int LinearView::verticalOffset() const
208{
209 return verticalScrollBar()->value();
210}
211
212/*!
213 Returns a rectangle corresponding to the selection in viewport cooridinates.
214*/
215
216QRect LinearView::selectionViewportRect(const QItemSelection &selection) const
217{
218 int ranges = selection.count();
219
220 if (ranges == 0)
221 return QRect();
222
223 // Note that we use the top and bottom functions of the selection range
224 // since the data is stored in rows.
225
226 int firstRow = selection.at(0).top();
227 int lastRow = selection.at(0).top();
228
229 for (int i = 0; i < ranges; ++i) {
230 firstRow = qMin(firstRow, selection.at(i).top());
231 lastRow = qMax(lastRow, selection.at(i).bottom());
232 }
233
234 QModelIndex firstItem = model()->index(qMin(firstRow, lastRow), 0,
235 QModelIndex());
236 QModelIndex lastItem = model()->index(qMax(firstRow, lastRow), 0,
237 QModelIndex());
238
239 QRect firstRect = itemViewportRect(firstItem);
240 QRect lastRect = itemViewportRect(lastItem);
241
242 return QRect(firstRect.left(), firstRect.top(),
243 lastRect.right() - firstRect.left(), firstRect.height());
244}
245
246void LinearView::paintEvent(QPaintEvent *event)
247{
248 QPainter painter(viewport());
249
250 QRect updateRect = event->rect();
251 QBrush background(Qt::black);
252 QPen foreground(Qt::white);
253
254 painter.fillRect(updateRect, background);
255 painter.setPen(foreground);
256
257 QModelIndex firstItem = itemAt(updateRect.left(), updateRect.top());
258 if (!firstItem.isValid())
259 firstItem = model()->index(0, 0, QModelIndex());
260
261 QModelIndex lastItem = itemAt(updateRect.right(), updateRect.bottom());
262 if (!lastItem.isValid())
263 lastItem = model()->index(rows() - 1, 0, QModelIndex());
264
265 int x = updateRect.left();
266 //int top = updateRect.top();
267 //int bottom = updateRect.bottom();
268
269 int row = firstItem.row();
270 QModelIndex index = model()->index(row, 0, QModelIndex());
271 int value = model()->data(index, Qt::DisplayRole).toInt();
272 int midPoint = viewport()->height()/2;
273 int y2 = midPoint - int(value * midPoint/255.0);
274
275 while (row <= lastItem.row()) {
276
277 QModelIndex index = model()->index(row, 0, QModelIndex());
278 int value = model()->data(index, Qt::DisplayRole).toInt();
279
280 int y1 = y2;
281 y2 = midPoint - int(value * midPoint/255.0);
282
283 painter.drawLine(x-1, y1, x, y2);
284 ++row; ++x;
285 }
286}
287
288void LinearView::resizeEvent(QResizeEvent * /* event */)
289{
290 updateGeometries();
291}
292
293void LinearView::updateGeometries()
294{
295 if (viewport()->width() < rows()) {
296 horizontalScrollBar()->setPageStep(viewport()->width());
297 horizontalScrollBar()->setRange(0, rows() - viewport()->width() - 1);
298 }
299}
300
301QSize LinearView::sizeHint() const
302{
303 return QSize(rows(), 200);
304}
305
306int LinearView::rows(const QModelIndex &index) const
307{
308 return model()->rowCount(model()->parent(index));
309}
310
311bool LinearView::isIndexHidden(const QModelIndex &index) const
312{
313 return false;
314}
Note: See TracBrowser for help on using the repository browser.