##// END OF EJS Templates
PieSeries model support - further refactoring
Marek Rosa -
r1081:85cf7da340c6
parent child
Show More
@@ -422,6 +422,11 bool QPieSeries::setModel(QAbstractItemModel* model)
422 422 if(model)
423 423 {
424 424 d->m_model = model;
425 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
426 connect(d->m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelRowsAdded(QModelIndex,int,int)));
427 connect(d->m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelRowsRemoved(QModelIndex,int,int)));
428 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelColumnsAdded(QModelIndex,int,int)));
429 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
425 430 return true;
426 431 }
427 432 else
@@ -586,11 +591,45 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRigh
586 591 }
587 592
588 593
589 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
594 void QPieSeriesPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
590 595 {
591 596 Q_UNUSED(parent);
597 if (m_mapOrientation == Qt::Vertical)
598 insertData(start, end);
599 else if (start <= m_mapValues || start <= m_mapLabels) // if the changes affect the map - reinitialize the pie
600 initializePieFromModel();
601 }
602
603 void QPieSeriesPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
604 {
605 Q_UNUSED(parent);
606 if (m_mapOrientation == Qt::Vertical)
607 removeData(start, end);
608 else if (start <= m_mapValues || start <= m_mapLabels) // if the changes affect the map - reinitialize the pie
609 initializePieFromModel();
610 }
611
612 void QPieSeriesPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
613 {
614 Q_UNUSED(parent);
615 if (m_mapOrientation == Qt::Horizontal)
616 insertData(start, end);
617 else if (start <= m_mapValues || start <= m_mapLabels) // if the changes affect the map - reinitialize the pie
618 initializePieFromModel();
619 }
620
621 void QPieSeriesPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
622 {
623 Q_UNUSED(parent);
624 if (m_mapOrientation == Qt::Horizontal)
625 removeData(start, end);
626 else if (start <= m_mapValues || start <= m_mapLabels) // if the changes affect the map - reinitialize the pie
627 initializePieFromModel();
628 }
629
630 void QPieSeriesPrivate::insertData(int start, int end)
631 {
592 632 Q_Q(QPieSeries);
593 // series uses model as a data sourceupda
594 633 if (m_mapCount != -1 && start >= m_mapFirst + m_mapCount) {
595 634 return;
596 635 } else {
@@ -617,9 +656,8 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
617 656 }
618 657 }
619 658
620 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
659 void QPieSeriesPrivate::removeData(int start, int end)
621 660 {
622 Q_UNUSED(parent);
623 661 Q_Q(QPieSeries);
624 662 int removedCount = end - start + 1;
625 663 if (m_mapCount != -1 && start >= m_mapFirst + m_mapCount) {
@@ -662,16 +700,6 void QPieSeriesPrivate::initializePieFromModel()
662 700 // clear current content
663 701 q->clear();
664 702
665 // connect the signals
666 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
667 if (m_mapOrientation == Qt::Vertical) {
668 connect(m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
669 connect(m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
670 } else {
671 connect(m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
672 connect(m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
673 }
674
675 703 // create the initial slices set
676 704 if (m_mapOrientation == Qt::Vertical) {
677 705 int sliceCount = 0;
@@ -690,6 +718,7 void QPieSeriesPrivate::initializePieFromModel()
690 718 for (int i = m_mapFirst; i < m_mapFirst + sliceCount; i++)
691 719 q->append(m_model->data(m_model->index(m_mapValues, i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(m_mapLabels, i), Qt::DisplayRole).toString());
692 720 }
721 q->setLabelsVisible(true);
693 722 }
694 723
695 724 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
@@ -56,11 +56,17 public Q_SLOTS:
56 56 void sliceClicked();
57 57 void sliceHovered(bool state);
58 58 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
59 void modelDataAdded(QModelIndex parent, int start, int end);
60 void modelDataRemoved(QModelIndex parent, int start, int end);
61 void initializePieFromModel();
59 void modelRowsAdded(QModelIndex parent, int start, int end);
60 void modelRowsRemoved(QModelIndex parent, int start, int end);
61 void modelColumnsAdded(QModelIndex parent, int start, int end);
62 void modelColumnsRemoved(QModelIndex parent, int start, int end);
62 63 bool setRealValue(qreal &value, qreal newValue, qreal max, qreal min = 0.0);
63 64
65 private:
66 void initializePieFromModel();
67 void insertData(int start, int end);
68 void removeData(int start, int end);
69
64 70 public:
65 71 QList<QPieSlice*> m_slices;
66 72 qreal m_pieRelativeHorPos;
@@ -325,6 +325,8 bool QXYSeries::setModel(QAbstractItemModel *model)
325 325 QObject::disconnect(d->m_model, 0, this, 0);
326 326 d->m_mapX = -1;
327 327 d->m_mapY = -1;
328 d->m_mapFirst = 0;
329 d->m_mapCount = -1;
328 330 d->m_mapOrientation = Qt::Vertical;
329 331 }
330 332
@@ -135,11 +135,13 void XYChartItem::handlePointsAdded(int start, int end)
135 135 int addedCount = end - start + 1;
136 136 if (m_series->mapCount() != -1 && addedCount > m_series->mapCount())
137 137 addedCount = m_series->mapCount();
138 int first = qMax(start, m_series->mapFirst());
139 int last = qMin(first + addedCount - 1, m_series->count() + m_series->mapFirst() - 1);
138 int first = qMax(start, m_series->mapFirst()); // get the index of the first item that will be added
139 int last = qMin(first + addedCount - 1, m_series->count() + m_series->mapFirst() - 1); // get the index of the last item that will be added
140 140 for (int i = first; i <= last; i++) {
141 handlePointAdded(i - m_series->mapFirst());
141 handlePointAdded(i - m_series->mapFirst());
142 142 }
143 // the map is limited therefore the items that are now outside the map
144 // need to be removed from the drawn points
143 145 if (m_series->mapCount() != -1 && m_points.size() > m_series->mapCount())
144 146 for (int i = m_points.size() - 1; i >= m_series->mapCount(); i--)
145 147 handlePointRemoved(i);
@@ -72,6 +72,8 class tst_QLineSeries : public QObject
72 72 void setModelMapping();
73 73 void setModelMappingRange_data();
74 74 void setModelMappingRange();
75 void modelUpdated();
76 void modelUpdatedCustomMapping();
75 77 private:
76 78 void append_data();
77 79 void count_data();
@@ -490,7 +492,7 void tst_QLineSeries::setModelMappingRange()
490 492 QFETCH(int, count);
491 493 QLineSeries series;
492 494
493 QStandardItemModel *model = new QStandardItemModel(0, 3);
495 QStandardItemModel *model = new QStandardItemModel(0, 2);
494 496 series.setModel(model);
495 497 series.setModelMapping(0, 1);
496 498 series.setModelMappingRange(first, count);
@@ -500,7 +502,7 void tst_QLineSeries::setModelMappingRange()
500 502 QVERIFY2(series.count() == 0, "No rows in the model, count should be 0");
501 503
502 504 for (int row = 0; row < 3; ++row) {
503 for (int column = 0; column < 3; column++) {
505 for (int column = 0; column < 2; column++) {
504 506 QStandardItem *item = new QStandardItem(row * column);
505 507 model->setItem(row, column, item);
506 508 }
@@ -513,7 +515,7 void tst_QLineSeries::setModelMappingRange()
513 515 // let's add few more rows to the model
514 516 for (int row = 0; row < 10; ++row) {
515 517 QList<QStandardItem *> newRow;
516 for (int column = 0; column < 3; column++) {
518 for (int column = 0; column < 2; column++) {
517 519 newRow.append(new QStandardItem(row * column));
518 520 }
519 521 model->appendRow(newRow);
@@ -523,8 +525,52 void tst_QLineSeries::setModelMappingRange()
523 525 else
524 526 QVERIFY2(series.count() == model->rowCount() - qMax(first, 0), "Count should be the number of items in a model after first item, but not less then 0");
525 527
528 // unset the model, values should be default
529 series.setModel(0);
530 QCOMPARE(series.mapFirst(), 0);
531 QCOMPARE(series.mapCount(), -1);
532 QVERIFY2(series.count() == 0, "No rows in the model, count should be 0");
533 }
534
535 void tst_QLineSeries::modelUpdated()
536 {
537 QStandardItemModel *model = new QStandardItemModel;
538 for (int row = 0; row < 10; ++row) {
539 QList<QStandardItem *> newRow;
540 for (int column = 0; column < 2; column++) {
541 newRow.append(new QStandardItem(row * column));
542 }
543 model->appendRow(newRow);
544 }
545
546 QLineSeries series;
547 series.setModel(model);
548 series.setModelMapping(0, 1);
526 549
550 model->setData(model->index(3, 1), 34);
551 // check that the update data is correctly taken from the model
552 QVERIFY(qFuzzyCompare(series.points().at(3).y(), 34));
553 }
554
555 void tst_QLineSeries::modelUpdatedCustomMapping()
556 {
557
558 QStandardItemModel *model = new QStandardItemModel;
559 for (int row = 0; row < 10; ++row) {
560 QList<QStandardItem *> newRow;
561 for (int column = 0; column < 2; column++) {
562 newRow.append(new QStandardItem(row * column));
563 }
564 model->appendRow(newRow);
565 }
566
567 QLineSeries series;
568 series.setModel(model);
569 series.setModelMapping(0, 1);
570 series.setModelMappingRange(3, 4);
527 571
572 model->setData(model->index(3, 1), 34);
573 QVERIFY(qFuzzyCompare(series.points().at(0).y(), 34));
528 574 }
529 575
530 576 QTEST_MAIN(tst_QLineSeries)
@@ -27,52 +27,37
27 27 CustomTableModel::CustomTableModel(QObject *parent) :
28 28 QAbstractTableModel(parent)
29 29 {
30 // m_points.append(QPointF(10, 50));
31 // m_labels.append("Apples");
32 // m_points.append(QPointF(60, 70));
33 // m_labels.append("Oranges");
34 // m_points.append(QPointF(110, 50));
35 // m_labels.append("Bananas");
36 // m_points.append(QPointF(140, 40));
37 // m_labels.append("Lemons");
38 // m_points.append(QPointF(200, 150));
39 // m_labels.append("Plums");
40 // m_points.append(QPointF(225, 75));
41 // m_labels.append("Pearls");
42
43 30 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
44 31
32 m_columnCount = 6;
33 m_rowCount = 8;
34
45 35 // m_data
46 for (int i = 0; i < 8; i++)
36 for (int i = 0; i < m_rowCount; i++)
47 37 {
48 QVector<qreal>* dataVec = new QVector<qreal>(6);
49 // QVector<QColor>* colorVec = new QVector<QColor>(6);
38 QVector<qreal>* dataVec = new QVector<qreal>(m_columnCount);
50 39 for (int k = 0; k < dataVec->size(); k++)
51 40 {
52 41 if (k%2 == 0)
53 42 dataVec->replace(k, i * 50 + qrand()%20);
54 43 else
55 44 dataVec->replace(k, qrand()%100);
56 // colorVec->replace(k, QColor(Qt::white));
57 45 }
58 46 m_data.append(dataVec);
59 47 m_labels.append(QString("Row: %1").arg((i + 1)));
60 // m_rowsColors.append(colorVec);
61 48 }
62 49 }
63 50
64 51 int CustomTableModel::rowCount(const QModelIndex & parent) const
65 52 {
66 53 Q_UNUSED(parent)
67 // return m_points.count();
68 54 return m_data.count();
69 55 }
70 56
71 57 int CustomTableModel::columnCount(const QModelIndex & parent) const
72 58 {
73 59 Q_UNUSED(parent)
74 // return 3;
75 return 6;
60 return m_columnCount;
76 61 }
77 62
78 63 QVariant CustomTableModel::headerData (int section, Qt::Orientation orientation, int role ) const
@@ -84,19 +69,13 QVariant CustomTableModel::headerData (int section, Qt::Orientation orientation,
84 69 {
85 70 switch(section)
86 71 {
87 // case 0:
88 // return "x";
89 // case 1:
90 // return "y";
91 // case 2:
92 case 6:
93 return "Fruit";
72 // case 6:
73 // return "Fruit";
94 74 default:
95 75 if (section%2 == 0)
96 76 return "x";
97 77 else
98 78 return "y";
99 // return "What?";
100 79 }
101 80 }
102 81 else
@@ -109,13 +88,8 QVariant CustomTableModel::data(const QModelIndex & index, int role) const
109 88 {
110 89 switch(index.column())
111 90 {
112 // case 0:
113 // return m_points[index.row()].x();
114 // case 1:
115 // return m_points[index.row()].y();
116 // case 2:
117 case 6:
118 return m_labels[index.row()];
91 // case 6:
92 // return m_labels[index.row()];
119 93 default:
120 94 return m_data[index.row()]->at(index.column());
121 95 break;
@@ -125,28 +99,23 QVariant CustomTableModel::data(const QModelIndex & index, int role) const
125 99 {
126 100 switch(index.column())
127 101 {
128 // case 0:
129 // return m_points[index.row()].x();
130 // case 1:
131 // return m_points[index.row()].y();
132 // case 2:
133 case 6:
134 return m_labels[index.row()];
102 // case 6:
103 // return m_labels[index.row()];
135 104 default:
136 105 return m_data[index.row()]->at(index.column());
137 106 break;
138 107 }
139 108 }
140 109 else if (role == Qt::BackgroundRole)
141 {
142 QRect rect;
143 foreach(rect, m_mapping)
144 if(rect.contains(index.column(), index.row()))
145 return QColor(m_mapping.key(rect));
110 {
111 QRect rect;
112 foreach(rect, m_mapping)
113 if(rect.contains(index.column(), index.row()))
114 return QColor(m_mapping.key(rect));
146 115
147 // cell not mapped return white color
148 return QColor(Qt::white);
149 }
116 // cell not mapped return white color
117 return QColor(Qt::white);
118 }
150 119 return QVariant();
151 120 }
152 121
@@ -156,36 +125,21 bool CustomTableModel::setData ( const QModelIndex & index, const QVariant & val
156 125 {
157 126 switch(index.column())
158 127 {
159 // case 0:
160 // m_points[index.row()].setX(value.toDouble());
161 // break;
162 // case 1:
163 // m_points[index.row()].setY(value.toDouble());
128 // case 6:
129 // m_labels.replace(index.row(), value.toString());
164 130 // break;
165 // case 2:
166 case 6:
167 m_labels.replace(index.row(), value.toString());
168 break;
169 131 default:
170 132 m_data[index.row()]->replace(index.column(), value.toDouble());
171 133 break;
172 // return false;
173 134 }
174 135 emit dataChanged(index, index);
175 136 return true;
176 137 }
177 // else if (role == Qt::BackgroundRole)
178 // {
179 // m_rowsColors[index.row()]->replace(index.column(), value.value<QColor>());
180 // return true;
181 // }
182 138 return false;
183 139 }
184 140
185 141 Qt::ItemFlags CustomTableModel::flags ( const QModelIndex & index ) const
186 142 {
187 // if (!index.isValid())
188 // return Qt::ItemIsEnabled;
189 143 return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
190 144 }
191 145
@@ -199,8 +153,8 bool CustomTableModel::insertRows ( int row, int count, const QModelIndex & pare
199 153 for (int i = row; i < row + count; i++)
200 154 {
201 155 // m_points.insert(row, QPointF(10,20));
202 QVector<qreal>* dataVec = new QVector<qreal>(6);
203 QVector<QColor>* colorVec = new QVector<QColor>(6);
156 QVector<qreal>* dataVec = new QVector<qreal>(m_columnCount);
157 QVector<QColor>* colorVec = new QVector<QColor>(m_columnCount);
204 158 for (int k = 0; k < dataVec->size(); k++)
205 159 {
206 160 if (k%2 == 0)
@@ -238,7 +192,6 bool CustomTableModel::insertRows ( int row, int count, const QModelIndex & pare
238 192 }
239 193 m_data.insert(i, dataVec);
240 194 m_labels.insert(i,(QString("Row: %1").arg(i + 1)));
241 // m_rowsColors.insert(i, colorVec);
242 195 }
243 196 endInsertRows();
244 197 return true;
@@ -255,7 +208,6 bool CustomTableModel::removeRows ( int row, int count, const QModelIndex & pare
255 208 beginRemoveRows(parent, row, row + count - 1);
256 209 for (int i = row; i < row + count; i++)
257 210 {
258 // m_points.removeAt(row);
259 211 QVector<qreal>* item = m_data.at(row);
260 212 m_data.removeAt(row);
261 213 delete item;
@@ -265,6 +217,40 bool CustomTableModel::removeRows ( int row, int count, const QModelIndex & pare
265 217 return true;
266 218 }
267 219
220 bool CustomTableModel::insertColumns ( int column, int count, const QModelIndex & parent)
221 {
222 if (column < 0)
223 column = 0;
224 beginInsertColumns(parent, column, column + count - 1);
225 m_columnCount += count;
226 for (int i = column; i < column + count; i++)
227 for (int k = 0; k < rowCount(); k++)
228 if (k - 1 >= 0) {
229 m_data[k]->insert(i, m_data[k - 1]->at(i) + qrand()%40 + 10);
230 } else {
231 m_data[k]->insert(i, qrand()%40);
232 }
233 endInsertColumns();
234 return true;
235 }
236
237 bool CustomTableModel::removeColumns ( int column, int count, const QModelIndex & parent)
238 {
239 if (column > columnCount() - 1)
240 return false;
241 if (column < 0)
242 column = 0;
243 if (column + count > columnCount())
244 return false;
245 beginRemoveColumns(parent, column, column + count -1);
246 m_columnCount -= count;
247 for (int i = column; i < column + count; i++)
248 for (int k = 0; k < rowCount(); k++)
249 m_data[k]->remove(column);
250 endRemoveColumns();
251 return true;
252 }
253
268 254 void CustomTableModel::addMapping(QString color, QRect area)
269 255 {
270 256 m_mapping.insertMulti(color, area);
@@ -42,6 +42,8 public:
42 42 Qt::ItemFlags flags ( const QModelIndex & index ) const;
43 43 bool insertRows ( int row, int count, const QModelIndex & parent = QModelIndex() );
44 44 bool removeRows ( int row, int count, const QModelIndex & parent = QModelIndex() );
45 bool insertColumns ( int column, int count, const QModelIndex & parent = QModelIndex() );
46 bool removeColumns ( int column, int count, const QModelIndex & parent = QModelIndex() );
45 47
46 48 void addMapping(QString color, QRect area);
47 49 void addMapping(QString color, int left, int top, int right, int bottom);
@@ -52,10 +54,11 public:
52 54 //public slots:
53 55 private:
54 56 QList<QVector<qreal> * > m_data;
55 // QList<QVector<QColor> * > m_rowsColors;
56 57 QHash<QString, QRect> m_mapping;
57 58 QList<QPointF> m_points;
58 QStringList m_labels;
59 QStringList m_labels;
60 int m_columnCount;
61 int m_rowCount;
59 62
60 63
61 64 };
@@ -69,6 +69,12 TableWidget::TableWidget(QWidget *parent)
69 69 QPushButton* removeRowButton = new QPushButton("Remove row");
70 70 connect(removeRowButton, SIGNAL(clicked()), this, SLOT(removeRow()));
71 71
72 QPushButton* addColumnRightButton = new QPushButton("Add column on the right");
73 connect(addColumnRightButton, SIGNAL(clicked()), this, SLOT(addColumnRight()));
74
75 QPushButton* removeColumnButton = new QPushButton("Remove column");
76 connect(removeColumnButton, SIGNAL(clicked()), this, SLOT(removeColumn()));
77
72 78 QPushButton* specialPieButton = new QPushButton("Test pie");
73 79 connect(specialPieButton, SIGNAL(clicked()), this, SLOT(testPie()));
74 80
@@ -87,6 +93,8 TableWidget::TableWidget(QWidget *parent)
87 93 buttonsLayout->addWidget(addRowAboveButton);
88 94 buttonsLayout->addWidget(addRowBelowButton);
89 95 buttonsLayout->addWidget(removeRowButton);
96 buttonsLayout->addWidget(addColumnRightButton);
97 buttonsLayout->addWidget(removeColumnButton);
90 98 buttonsLayout->addWidget(specialPieButton);
91 99 buttonsLayout->addStretch();
92 100
@@ -143,6 +151,16 void TableWidget::removeRow()
143 151 m_model->removeRows(m_tableView->currentIndex().row(), qMin(m_model->rowCount() - m_tableView->currentIndex().row(), m_linesCountSpinBox->value()));
144 152 }
145 153
154 void TableWidget::addColumnRight()
155 {
156 m_model->insertColumns(m_tableView->currentIndex().column() + 1, m_linesCountSpinBox->value());
157 }
158
159 void TableWidget::removeColumn()
160 {
161 m_model->removeColumns(m_tableView->currentIndex().column(), qMin(m_model->columnCount() - m_tableView->currentIndex().column(), m_linesCountSpinBox->value()));
162 }
163
146 164 void TableWidget::updateChartType(bool toggle)
147 165 {
148 166 // this if is needed, so that the function is only called once.
@@ -47,6 +47,8 public:
47 47 void addRowAbove();
48 48 void addRowBelow();
49 49 void removeRow();
50 void addColumnRight();
51 void removeColumn();
50 52 void updateChartType(bool toggle);
51 53 void testPie();
52 54
General Comments 0
You need to be logged in to leave comments. Login now