00001 #include <QFont>
00002 #include <QScrollBar>
00003 #include <QPen>
00004 #include <QPainter>
00005 #include <QPaintEvent>
00006
00007 #include "piechartview.h"
00008 #include "../Data/dataproject.h"
00009 #include "../Models/exercisemodel.h"
00010
00011 #ifndef M_PI
00012 #define M_PI 3.1415927
00013 #endif
00014
00015 PieChartView::PieChartView(QWidget *parent) : QAbstractItemView(parent)
00016 {
00017 horizontalScrollBar()->setRange(0, 0);
00018 verticalScrollBar()->setRange(0, 0);
00019
00020 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00021 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00022
00023 margin = 8;
00024 totalSize = 500;
00025 pieSize = totalSize - 2 * margin;
00026 totalValue = 0.0;
00027 }
00028
00029 PieChartView::~PieChartView()
00030 {
00031
00032 }
00033
00034 bool PieChartView::edit(const QModelIndex &index, EditTrigger trigger, QEvent *event)
00035 {
00036 Q_UNUSED(event);
00037 Q_UNUSED(trigger);
00038 Q_UNUSED(index);
00039 return false;
00040 }
00041
00042 QModelIndex PieChartView::indexAt(const QPoint &point) const
00043 {
00044 return QModelIndex();
00045 }
00046
00047 bool PieChartView::isIndexHidden(const QModelIndex &index) const
00048 {
00049 Q_UNUSED(index);
00050 return false;
00051 }
00052
00053 int PieChartView::horizontalOffset() const
00054 {
00055 return horizontalScrollBar()->value();
00056 }
00057
00058 QModelIndex PieChartView::moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers )
00059 {
00060 return QModelIndex();
00061 }
00062
00063 QList<int> PieChartView::aggregateItemList()
00064 {
00065 QList<int> values;
00066
00067 int correct = 0;
00068 int wrong = 0;
00069 int incomplete = 0;
00070
00071 ExerciseModel *exerciseModel = (ExerciseModel*)model();
00072 if(exerciseModel)
00073 {
00074 ExerciseItem *root = exerciseModel->getRootItem();
00075 for(int i = 0; i < root->childCount(); i++)
00076 {
00077 ExerciseItem *chapter = root->child(i);
00078 for(int j = 0; j < chapter->childCount(); j++)
00079 {
00080 ExerciseItem *exercise = chapter->child(j);
00081
00082 QVariantList list = exercise->itemInfo();
00083 QString name = list.value(0).toString();
00084 QMap<QString, QVariant> data = list.value(1).toMap();
00085 int state = data.value("state").toInt();
00086 if(state == Correct)
00087 {
00088 correct++;
00089 }
00090 else if(state == NotCompleted)
00091 {
00092 incomplete++;
00093 }
00094 else if(state == Wrong)
00095 {
00096 wrong++;
00097 }
00098 }
00099 }
00100 }
00101
00102 values << correct;
00103 values << wrong;
00104 values << incomplete;
00105
00106 totalValue = correct + wrong + incomplete;
00107 emit exerciseStatesChanged(values);
00108 return values;
00109 }
00110
00111 void PieChartView::paintEvent(QPaintEvent *event)
00112 {
00113
00114 QList<int> items = aggregateItemList();
00115
00116 if(totalValue > 0)
00117 {
00118 QStyleOptionViewItem option = viewOptions();
00119 QStyle::State state = option.state;
00120
00121 QBrush background = option.palette.base();
00122 QPen foreground(Qt::white);
00123 QPen textPen(option.palette.color(QPalette::Text));
00124
00125 QPainter painter(viewport());
00126 painter.setRenderHint(QPainter::Antialiasing);
00127
00128 painter.fillRect(event->rect(), background);
00129 painter.setPen(foreground);
00130
00131
00132 QRect pieRect = QRect(margin, margin, pieSize, pieSize);
00133 QPoint keyPoint = QPoint(totalSize - horizontalScrollBar()->value(), margin - verticalScrollBar()->value());
00134
00135 painter.save();
00136 painter.translate(pieRect.x() - horizontalScrollBar()->value(), pieRect.y() - verticalScrollBar()->value());
00137 painter.drawEllipse(0, 0, pieSize, pieSize);
00138 double startAngle = 0.0;
00139 uint totalPieces = 0;
00140
00141 int value = -1;
00142 int count = 0;
00143 foreach(value, items)
00144 {
00145 if(value > 0)
00146 {
00147 double angle = 360 * value / totalValue;
00148
00149 QColor color;
00150 switch(count)
00151 {
00152 case 0:
00153 color = QColor(Qt::green);
00154 break;
00155 case 1:
00156 color = QColor(Qt::red);
00157 break;
00158 case 2:
00159 color.setRgb(229, 229, 229);
00160 break;
00161 }
00162
00163 painter.setBrush(QBrush(color));
00164 painter.drawPie(0, 0, pieSize, pieSize, int(startAngle*16), int(angle*16));
00165
00166 startAngle += angle;
00167 totalPieces++;
00168 }
00169 count++;
00170 }
00171 painter.restore();
00172 }
00173 }
00174
00175 void PieChartView::resizeEvent(QResizeEvent *event)
00176 {
00177 Q_UNUSED(event);
00178 if(viewport()->width() >= size().height())
00179 {
00180
00181 totalSize = size().height();
00182 }
00183 else
00184 {
00185
00186 totalSize = size().width() - margin/2;
00187 }
00188 pieSize = totalSize - 2 * margin;
00189 updateGeometries();
00190 }
00191
00192 int PieChartView::rows(const QModelIndex &index) const
00193 {
00194 return model()->rowCount(QModelIndex());
00195 }
00196
00197 void PieChartView::scrollContentsBy(int dx, int dy)
00198 {
00199 viewport()->scroll(dx, dy);
00200 }
00201
00202 void PieChartView::scrollTo(const QModelIndex &index, ScrollHint)
00203 {
00204 QRect area = viewport()->rect();
00205 QRect rect = visualRect(index);
00206
00207 if(rect.left() < area.left())
00208 {
00209 horizontalScrollBar()->setValue(horizontalScrollBar()->value() + rect.left() - area.left());
00210 }
00211 else if(rect.right() > area.right())
00212 {
00213 horizontalScrollBar()->setValue(horizontalScrollBar()->value() + qMin(rect.right() - area.right(), rect.left() - area.left()));
00214 }
00215
00216 if(rect.top() < area.top())
00217 {
00218 verticalScrollBar()->setValue(verticalScrollBar()->value() + rect.top() - area.top());
00219 }
00220 else if(rect.bottom() > area.bottom())
00221 {
00222 verticalScrollBar()->setValue(verticalScrollBar()->value() + qMin(rect.bottom() - area.bottom(), rect.top() - area.top()));
00223 }
00224
00225 update();
00226 }
00227
00228 void PieChartView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
00229 {
00230 }
00231
00232 void PieChartView::updateGeometries()
00233 {
00234 horizontalScrollBar()->setPageStep(viewport()->width());
00235 horizontalScrollBar()->setRange(0, qMax(0, totalSize - viewport()->width()));
00236 verticalScrollBar()->setPageStep(viewport()->height());
00237 verticalScrollBar()->setRange(0, qMax(0, totalSize - viewport()->height()));
00238 }
00239
00240 int PieChartView::verticalOffset() const
00241 {
00242 return verticalScrollBar()->value();
00243 }
00244
00245 QRect PieChartView::visualRect(const QModelIndex &index) const
00246 {
00247 return QRect();
00248 }
00249
00250 QRegion PieChartView::visualRegionForSelection(const QItemSelection &selection) const
00251 {
00252 return QRect();
00253 }