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