1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** All rights reserved.
|
---|
5 | ** Contact: Nokia Corporation ([email protected])
|
---|
6 | **
|
---|
7 | ** This file is part of the examples of the Qt Toolkit.
|
---|
8 | **
|
---|
9 | ** $QT_BEGIN_LICENSE:BSD$
|
---|
10 | ** You may use this file under the terms of the BSD license as follows:
|
---|
11 | **
|
---|
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.
|
---|
25 | **
|
---|
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."
|
---|
37 | ** $QT_END_LICENSE$
|
---|
38 | **
|
---|
39 | ****************************************************************************/
|
---|
40 |
|
---|
41 | #include <math.h>
|
---|
42 | #include <QtGui>
|
---|
43 |
|
---|
44 | #ifndef M_PI
|
---|
45 | #define M_PI 3.1415927
|
---|
46 | #endif
|
---|
47 |
|
---|
48 | #include "pieview.h"
|
---|
49 |
|
---|
50 | PieView::PieView(QWidget *parent)
|
---|
51 | : QAbstractItemView(parent)
|
---|
52 | {
|
---|
53 | horizontalScrollBar()->setRange(0, 0);
|
---|
54 | verticalScrollBar()->setRange(0, 0);
|
---|
55 |
|
---|
56 | margin = 8;
|
---|
57 | totalSize = 300;
|
---|
58 | pieSize = totalSize - 2*margin;
|
---|
59 | validItems = 0;
|
---|
60 | totalValue = 0.0;
|
---|
61 | rubberBand = 0;
|
---|
62 | }
|
---|
63 |
|
---|
64 | void PieView::dataChanged(const QModelIndex &topLeft,
|
---|
65 | const QModelIndex &bottomRight)
|
---|
66 | {
|
---|
67 | QAbstractItemView::dataChanged(topLeft, bottomRight);
|
---|
68 |
|
---|
69 | validItems = 0;
|
---|
70 | totalValue = 0.0;
|
---|
71 |
|
---|
72 | for (int row = 0; row < model()->rowCount(rootIndex()); ++row) {
|
---|
73 |
|
---|
74 | QModelIndex index = model()->index(row, 1, rootIndex());
|
---|
75 | double value = model()->data(index).toDouble();
|
---|
76 |
|
---|
77 | if (value > 0.0) {
|
---|
78 | totalValue += value;
|
---|
79 | validItems++;
|
---|
80 | }
|
---|
81 | }
|
---|
82 | viewport()->update();
|
---|
83 | }
|
---|
84 |
|
---|
85 | bool PieView::edit(const QModelIndex &index, EditTrigger trigger, QEvent *event)
|
---|
86 | {
|
---|
87 | if (index.column() == 0)
|
---|
88 | return QAbstractItemView::edit(index, trigger, event);
|
---|
89 | else
|
---|
90 | return false;
|
---|
91 | }
|
---|
92 |
|
---|
93 | /*
|
---|
94 | Returns the item that covers the coordinate given in the view.
|
---|
95 | */
|
---|
96 |
|
---|
97 | QModelIndex PieView::indexAt(const QPoint &point) const
|
---|
98 | {
|
---|
99 | if (validItems == 0)
|
---|
100 | return QModelIndex();
|
---|
101 |
|
---|
102 | // Transform the view coordinates into contents widget coordinates.
|
---|
103 | int wx = point.x() + horizontalScrollBar()->value();
|
---|
104 | int wy = point.y() + verticalScrollBar()->value();
|
---|
105 |
|
---|
106 | if (wx < totalSize) {
|
---|
107 | double cx = wx - totalSize/2;
|
---|
108 | double cy = totalSize/2 - wy; // positive cy for items above the center
|
---|
109 |
|
---|
110 | // Determine the distance from the center point of the pie chart.
|
---|
111 | double d = pow(pow(cx, 2) + pow(cy, 2), 0.5);
|
---|
112 |
|
---|
113 | if (d == 0 || d > pieSize/2)
|
---|
114 | return QModelIndex();
|
---|
115 |
|
---|
116 | // Determine the angle of the point.
|
---|
117 | double angle = (180 / M_PI) * acos(cx/d);
|
---|
118 | if (cy < 0)
|
---|
119 | angle = 360 - angle;
|
---|
120 |
|
---|
121 | // Find the relevant slice of the pie.
|
---|
122 | double startAngle = 0.0;
|
---|
123 |
|
---|
124 | for (int row = 0; row < model()->rowCount(rootIndex()); ++row) {
|
---|
125 |
|
---|
126 | QModelIndex index = model()->index(row, 1, rootIndex());
|
---|
127 | double value = model()->data(index).toDouble();
|
---|
128 |
|
---|
129 | if (value > 0.0) {
|
---|
130 | double sliceAngle = 360*value/totalValue;
|
---|
131 |
|
---|
132 | if (angle >= startAngle && angle < (startAngle + sliceAngle))
|
---|
133 | return model()->index(row, 1, rootIndex());
|
---|
134 |
|
---|
135 | startAngle += sliceAngle;
|
---|
136 | }
|
---|
137 | }
|
---|
138 | } else {
|
---|
139 | double itemHeight = QFontMetrics(viewOptions().font).height();
|
---|
140 | int listItem = int((wy - margin) / itemHeight);
|
---|
141 | int validRow = 0;
|
---|
142 |
|
---|
143 | for (int row = 0; row < model()->rowCount(rootIndex()); ++row) {
|
---|
144 |
|
---|
145 | QModelIndex index = model()->index(row, 1, rootIndex());
|
---|
146 | if (model()->data(index).toDouble() > 0.0) {
|
---|
147 |
|
---|
148 | if (listItem == validRow)
|
---|
149 | return model()->index(row, 0, rootIndex());
|
---|
150 |
|
---|
151 | // Update the list index that corresponds to the next valid row.
|
---|
152 | validRow++;
|
---|
153 | }
|
---|
154 | }
|
---|
155 | }
|
---|
156 |
|
---|
157 | return QModelIndex();
|
---|
158 | }
|
---|
159 |
|
---|
160 | bool PieView::isIndexHidden(const QModelIndex & /*index*/) const
|
---|
161 | {
|
---|
162 | return false;
|
---|
163 | }
|
---|
164 |
|
---|
165 | /*
|
---|
166 | Returns the rectangle of the item at position \a index in the
|
---|
167 | model. The rectangle is in contents coordinates.
|
---|
168 | */
|
---|
169 |
|
---|
170 | QRect PieView::itemRect(const QModelIndex &index) const
|
---|
171 | {
|
---|
172 | if (!index.isValid())
|
---|
173 | return QRect();
|
---|
174 |
|
---|
175 | // Check whether the index's row is in the list of rows represented
|
---|
176 | // by slices.
|
---|
177 | QModelIndex valueIndex;
|
---|
178 |
|
---|
179 | if (index.column() != 1)
|
---|
180 | valueIndex = model()->index(index.row(), 1, rootIndex());
|
---|
181 | else
|
---|
182 | valueIndex = index;
|
---|
183 |
|
---|
184 | if (model()->data(valueIndex).toDouble() > 0.0) {
|
---|
185 |
|
---|
186 | int listItem = 0;
|
---|
187 | for (int row = index.row()-1; row >= 0; --row) {
|
---|
188 | if (model()->data(model()->index(row, 1, rootIndex())).toDouble() > 0.0)
|
---|
189 | listItem++;
|
---|
190 | }
|
---|
191 |
|
---|
192 | double itemHeight;
|
---|
193 |
|
---|
194 | switch (index.column()) {
|
---|
195 | case 0:
|
---|
196 | itemHeight = QFontMetrics(viewOptions().font).height();
|
---|
197 |
|
---|
198 | return QRect(totalSize,
|
---|
199 | int(margin + listItem*itemHeight),
|
---|
200 | totalSize - margin, int(itemHeight));
|
---|
201 | case 1:
|
---|
202 | return viewport()->rect();
|
---|
203 | }
|
---|
204 |
|
---|
205 | }
|
---|
206 | return QRect();
|
---|
207 | }
|
---|
208 |
|
---|
209 | QRegion PieView::itemRegion(const QModelIndex &index) const
|
---|
210 | {
|
---|
211 | if (!index.isValid())
|
---|
212 | return QRegion();
|
---|
213 |
|
---|
214 | if (index.column() != 1)
|
---|
215 | return itemRect(index);
|
---|
216 |
|
---|
217 | if (model()->data(index).toDouble() <= 0.0)
|
---|
218 | return QRegion();
|
---|
219 |
|
---|
220 | double startAngle = 0.0;
|
---|
221 | for (int row = 0; row < model()->rowCount(rootIndex()); ++row) {
|
---|
222 |
|
---|
223 | QModelIndex sliceIndex = model()->index(row, 1, rootIndex());
|
---|
224 | double value = model()->data(sliceIndex).toDouble();
|
---|
225 |
|
---|
226 | if (value > 0.0) {
|
---|
227 | double angle = 360*value/totalValue;
|
---|
228 |
|
---|
229 | if (sliceIndex == index) {
|
---|
230 | QPainterPath slicePath;
|
---|
231 | slicePath.moveTo(totalSize/2, totalSize/2);
|
---|
232 | slicePath.arcTo(margin, margin, margin+pieSize, margin+pieSize,
|
---|
233 | startAngle, angle);
|
---|
234 | slicePath.closeSubpath();
|
---|
235 |
|
---|
236 | return QRegion(slicePath.toFillPolygon().toPolygon());
|
---|
237 | }
|
---|
238 |
|
---|
239 | startAngle += angle;
|
---|
240 | }
|
---|
241 | }
|
---|
242 |
|
---|
243 | return QRegion();
|
---|
244 | }
|
---|
245 |
|
---|
246 | int PieView::horizontalOffset() const
|
---|
247 | {
|
---|
248 | return horizontalScrollBar()->value();
|
---|
249 | }
|
---|
250 |
|
---|
251 | void PieView::mousePressEvent(QMouseEvent *event)
|
---|
252 | {
|
---|
253 | QAbstractItemView::mousePressEvent(event);
|
---|
254 | origin = event->pos();
|
---|
255 | if (!rubberBand)
|
---|
256 | rubberBand = new QRubberBand(QRubberBand::Rectangle, viewport());
|
---|
257 | rubberBand->setGeometry(QRect(origin, QSize()));
|
---|
258 | rubberBand->show();
|
---|
259 | }
|
---|
260 |
|
---|
261 | void PieView::mouseMoveEvent(QMouseEvent *event)
|
---|
262 | {
|
---|
263 | if (rubberBand)
|
---|
264 | rubberBand->setGeometry(QRect(origin, event->pos()).normalized());
|
---|
265 | QAbstractItemView::mouseMoveEvent(event);
|
---|
266 | }
|
---|
267 |
|
---|
268 | void PieView::mouseReleaseEvent(QMouseEvent *event)
|
---|
269 | {
|
---|
270 | QAbstractItemView::mouseReleaseEvent(event);
|
---|
271 | if (rubberBand)
|
---|
272 | rubberBand->hide();
|
---|
273 | viewport()->update();
|
---|
274 | }
|
---|
275 |
|
---|
276 | QModelIndex PieView::moveCursor(QAbstractItemView::CursorAction cursorAction,
|
---|
277 | Qt::KeyboardModifiers /*modifiers*/)
|
---|
278 | {
|
---|
279 | QModelIndex current = currentIndex();
|
---|
280 |
|
---|
281 | switch (cursorAction) {
|
---|
282 | case MoveLeft:
|
---|
283 | case MoveUp:
|
---|
284 | if (current.row() > 0)
|
---|
285 | current = model()->index(current.row() - 1, current.column(),
|
---|
286 | rootIndex());
|
---|
287 | else
|
---|
288 | current = model()->index(0, current.column(), rootIndex());
|
---|
289 | break;
|
---|
290 | case MoveRight:
|
---|
291 | case MoveDown:
|
---|
292 | if (current.row() < rows(current) - 1)
|
---|
293 | current = model()->index(current.row() + 1, current.column(),
|
---|
294 | rootIndex());
|
---|
295 | else
|
---|
296 | current = model()->index(rows(current) - 1, current.column(),
|
---|
297 | rootIndex());
|
---|
298 | break;
|
---|
299 | default:
|
---|
300 | break;
|
---|
301 | }
|
---|
302 |
|
---|
303 | viewport()->update();
|
---|
304 | return current;
|
---|
305 | }
|
---|
306 |
|
---|
307 | void PieView::paintEvent(QPaintEvent *event)
|
---|
308 | {
|
---|
309 | QItemSelectionModel *selections = selectionModel();
|
---|
310 | QStyleOptionViewItem option = viewOptions();
|
---|
311 | QStyle::State state = option.state;
|
---|
312 |
|
---|
313 | QBrush background = option.palette.base();
|
---|
314 | QPen foreground(option.palette.color(QPalette::WindowText));
|
---|
315 | QPen textPen(option.palette.color(QPalette::Text));
|
---|
316 | QPen highlightedPen(option.palette.color(QPalette::HighlightedText));
|
---|
317 |
|
---|
318 | QPainter painter(viewport());
|
---|
319 | painter.setRenderHint(QPainter::Antialiasing);
|
---|
320 |
|
---|
321 | painter.fillRect(event->rect(), background);
|
---|
322 | painter.setPen(foreground);
|
---|
323 |
|
---|
324 | // Viewport rectangles
|
---|
325 | QRect pieRect = QRect(margin, margin, pieSize, pieSize);
|
---|
326 | QPoint keyPoint = QPoint(totalSize - horizontalScrollBar()->value(),
|
---|
327 | margin - verticalScrollBar()->value());
|
---|
328 |
|
---|
329 | if (validItems > 0) {
|
---|
330 |
|
---|
331 | painter.save();
|
---|
332 | painter.translate(pieRect.x() - horizontalScrollBar()->value(),
|
---|
333 | pieRect.y() - verticalScrollBar()->value());
|
---|
334 | painter.drawEllipse(0, 0, pieSize, pieSize);
|
---|
335 | double startAngle = 0.0;
|
---|
336 | int row;
|
---|
337 |
|
---|
338 | for (row = 0; row < model()->rowCount(rootIndex()); ++row) {
|
---|
339 |
|
---|
340 | QModelIndex index = model()->index(row, 1, rootIndex());
|
---|
341 | double value = model()->data(index).toDouble();
|
---|
342 |
|
---|
343 | if (value > 0.0) {
|
---|
344 | double angle = 360*value/totalValue;
|
---|
345 |
|
---|
346 | QModelIndex colorIndex = model()->index(row, 0, rootIndex());
|
---|
347 | QColor color = QColor(model()->data(colorIndex,
|
---|
348 | Qt::DecorationRole).toString());
|
---|
349 |
|
---|
350 | if (currentIndex() == index)
|
---|
351 | painter.setBrush(QBrush(color, Qt::Dense4Pattern));
|
---|
352 | else if (selections->isSelected(index))
|
---|
353 | painter.setBrush(QBrush(color, Qt::Dense3Pattern));
|
---|
354 | else
|
---|
355 | painter.setBrush(QBrush(color));
|
---|
356 |
|
---|
357 | painter.drawPie(0, 0, pieSize, pieSize, int(startAngle*16),
|
---|
358 | int(angle*16));
|
---|
359 |
|
---|
360 | startAngle += angle;
|
---|
361 | }
|
---|
362 | }
|
---|
363 | painter.restore();
|
---|
364 |
|
---|
365 | int keyNumber = 0;
|
---|
366 |
|
---|
367 | for (row = 0; row < model()->rowCount(rootIndex()); ++row) {
|
---|
368 |
|
---|
369 | QModelIndex index = model()->index(row, 1, rootIndex());
|
---|
370 | double value = model()->data(index).toDouble();
|
---|
371 |
|
---|
372 | if (value > 0.0) {
|
---|
373 | QModelIndex labelIndex = model()->index(row, 0, rootIndex());
|
---|
374 |
|
---|
375 | QStyleOptionViewItem option = viewOptions();
|
---|
376 | option.rect = visualRect(labelIndex);
|
---|
377 | if (selections->isSelected(labelIndex))
|
---|
378 | option.state |= QStyle::State_Selected;
|
---|
379 | if (currentIndex() == labelIndex)
|
---|
380 | option.state |= QStyle::State_HasFocus;
|
---|
381 | itemDelegate()->paint(&painter, option, labelIndex);
|
---|
382 |
|
---|
383 | keyNumber++;
|
---|
384 | }
|
---|
385 | }
|
---|
386 | }
|
---|
387 | }
|
---|
388 |
|
---|
389 | void PieView::resizeEvent(QResizeEvent * /* event */)
|
---|
390 | {
|
---|
391 | updateGeometries();
|
---|
392 | }
|
---|
393 |
|
---|
394 | int PieView::rows(const QModelIndex &index) const
|
---|
395 | {
|
---|
396 | return model()->rowCount(model()->parent(index));
|
---|
397 | }
|
---|
398 |
|
---|
399 | void PieView::rowsInserted(const QModelIndex &parent, int start, int end)
|
---|
400 | {
|
---|
401 | for (int row = start; row <= end; ++row) {
|
---|
402 |
|
---|
403 | QModelIndex index = model()->index(row, 1, rootIndex());
|
---|
404 | double value = model()->data(index).toDouble();
|
---|
405 |
|
---|
406 | if (value > 0.0) {
|
---|
407 | totalValue += value;
|
---|
408 | validItems++;
|
---|
409 | }
|
---|
410 | }
|
---|
411 |
|
---|
412 | QAbstractItemView::rowsInserted(parent, start, end);
|
---|
413 | }
|
---|
414 |
|
---|
415 | void PieView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
|
---|
416 | {
|
---|
417 | for (int row = start; row <= end; ++row) {
|
---|
418 |
|
---|
419 | QModelIndex index = model()->index(row, 1, rootIndex());
|
---|
420 | double value = model()->data(index).toDouble();
|
---|
421 | if (value > 0.0) {
|
---|
422 | totalValue -= value;
|
---|
423 | validItems--;
|
---|
424 | }
|
---|
425 | }
|
---|
426 |
|
---|
427 | QAbstractItemView::rowsAboutToBeRemoved(parent, start, end);
|
---|
428 | }
|
---|
429 |
|
---|
430 | void PieView::scrollContentsBy(int dx, int dy)
|
---|
431 | {
|
---|
432 | viewport()->scroll(dx, dy);
|
---|
433 | }
|
---|
434 |
|
---|
435 | void PieView::scrollTo(const QModelIndex &index, ScrollHint)
|
---|
436 | {
|
---|
437 | QRect area = viewport()->rect();
|
---|
438 | QRect rect = visualRect(index);
|
---|
439 |
|
---|
440 | if (rect.left() < area.left())
|
---|
441 | horizontalScrollBar()->setValue(
|
---|
442 | horizontalScrollBar()->value() + rect.left() - area.left());
|
---|
443 | else if (rect.right() > area.right())
|
---|
444 | horizontalScrollBar()->setValue(
|
---|
445 | horizontalScrollBar()->value() + qMin(
|
---|
446 | rect.right() - area.right(), rect.left() - area.left()));
|
---|
447 |
|
---|
448 | if (rect.top() < area.top())
|
---|
449 | verticalScrollBar()->setValue(
|
---|
450 | verticalScrollBar()->value() + rect.top() - area.top());
|
---|
451 | else if (rect.bottom() > area.bottom())
|
---|
452 | verticalScrollBar()->setValue(
|
---|
453 | verticalScrollBar()->value() + qMin(
|
---|
454 | rect.bottom() - area.bottom(), rect.top() - area.top()));
|
---|
455 |
|
---|
456 | update();
|
---|
457 | }
|
---|
458 |
|
---|
459 | /*
|
---|
460 | Find the indices corresponding to the extent of the selection.
|
---|
461 | */
|
---|
462 |
|
---|
463 | void PieView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
|
---|
464 | {
|
---|
465 | // Use content widget coordinates because we will use the itemRegion()
|
---|
466 | // function to check for intersections.
|
---|
467 |
|
---|
468 | QRect contentsRect = rect.translated(
|
---|
469 | horizontalScrollBar()->value(),
|
---|
470 | verticalScrollBar()->value()).normalized();
|
---|
471 |
|
---|
472 | int rows = model()->rowCount(rootIndex());
|
---|
473 | int columns = model()->columnCount(rootIndex());
|
---|
474 | QModelIndexList indexes;
|
---|
475 |
|
---|
476 | for (int row = 0; row < rows; ++row) {
|
---|
477 | for (int column = 0; column < columns; ++column) {
|
---|
478 | QModelIndex index = model()->index(row, column, rootIndex());
|
---|
479 | QRegion region = itemRegion(index);
|
---|
480 | if (!region.intersect(contentsRect).isEmpty())
|
---|
481 | indexes.append(index);
|
---|
482 | }
|
---|
483 | }
|
---|
484 |
|
---|
485 | if (indexes.size() > 0) {
|
---|
486 | int firstRow = indexes[0].row();
|
---|
487 | int lastRow = indexes[0].row();
|
---|
488 | int firstColumn = indexes[0].column();
|
---|
489 | int lastColumn = indexes[0].column();
|
---|
490 |
|
---|
491 | for (int i = 1; i < indexes.size(); ++i) {
|
---|
492 | firstRow = qMin(firstRow, indexes[i].row());
|
---|
493 | lastRow = qMax(lastRow, indexes[i].row());
|
---|
494 | firstColumn = qMin(firstColumn, indexes[i].column());
|
---|
495 | lastColumn = qMax(lastColumn, indexes[i].column());
|
---|
496 | }
|
---|
497 |
|
---|
498 | QItemSelection selection(
|
---|
499 | model()->index(firstRow, firstColumn, rootIndex()),
|
---|
500 | model()->index(lastRow, lastColumn, rootIndex()));
|
---|
501 | selectionModel()->select(selection, command);
|
---|
502 | } else {
|
---|
503 | QModelIndex noIndex;
|
---|
504 | QItemSelection selection(noIndex, noIndex);
|
---|
505 | selectionModel()->select(selection, command);
|
---|
506 | }
|
---|
507 |
|
---|
508 | update();
|
---|
509 | }
|
---|
510 |
|
---|
511 | void PieView::updateGeometries()
|
---|
512 | {
|
---|
513 | horizontalScrollBar()->setPageStep(viewport()->width());
|
---|
514 | horizontalScrollBar()->setRange(0, qMax(0, 2*totalSize - viewport()->width()));
|
---|
515 | verticalScrollBar()->setPageStep(viewport()->height());
|
---|
516 | verticalScrollBar()->setRange(0, qMax(0, totalSize - viewport()->height()));
|
---|
517 | }
|
---|
518 |
|
---|
519 | int PieView::verticalOffset() const
|
---|
520 | {
|
---|
521 | return verticalScrollBar()->value();
|
---|
522 | }
|
---|
523 |
|
---|
524 | /*
|
---|
525 | Returns the position of the item in viewport coordinates.
|
---|
526 | */
|
---|
527 |
|
---|
528 | QRect PieView::visualRect(const QModelIndex &index) const
|
---|
529 | {
|
---|
530 | QRect rect = itemRect(index);
|
---|
531 | if (rect.isValid())
|
---|
532 | return QRect(rect.left() - horizontalScrollBar()->value(),
|
---|
533 | rect.top() - verticalScrollBar()->value(),
|
---|
534 | rect.width(), rect.height());
|
---|
535 | else
|
---|
536 | return rect;
|
---|
537 | }
|
---|
538 |
|
---|
539 | /*
|
---|
540 | Returns a region corresponding to the selection in viewport coordinates.
|
---|
541 | */
|
---|
542 |
|
---|
543 | QRegion PieView::visualRegionForSelection(const QItemSelection &selection) const
|
---|
544 | {
|
---|
545 | int ranges = selection.count();
|
---|
546 |
|
---|
547 | if (ranges == 0)
|
---|
548 | return QRect();
|
---|
549 |
|
---|
550 | QRegion region;
|
---|
551 | for (int i = 0; i < ranges; ++i) {
|
---|
552 | QItemSelectionRange range = selection.at(i);
|
---|
553 | for (int row = range.top(); row <= range.bottom(); ++row) {
|
---|
554 | for (int col = range.left(); col <= range.right(); ++col) {
|
---|
555 | QModelIndex index = model()->index(row, col, rootIndex());
|
---|
556 | region += visualRect(index);
|
---|
557 | }
|
---|
558 | }
|
---|
559 | }
|
---|
560 | return region;
|
---|
561 | }
|
---|