c6174bf294f7a4672f2414f9d9089002d9d4ee94
[toast/confclerk.git] / src / mvc / delegate.cpp
1 #include "delegate.h"
2 #include "eventmodel.h"
3
4 #include <QDebug>
5 #include <QPainter>
6
7 const int RADIUS = 10;
8 const int SPACER = RADIUS;
9
10 Delegate::Delegate(QTreeView *aParent)
11     : QItemDelegate(aParent)
12     , mViewPtr(aParent)
13 {
14     mControls.clear();
15     defineControls();
16 }
17
18 Delegate::~Delegate()
19 {
20     QListIterator<ControlId> i(mControls.keys());
21     while (i.hasNext())
22     {
23         delete mControls[i.next()]->image();
24     }
25 }
26
27 void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
28 {
29     if(!mViewPtr)
30         return;
31
32     painter->save();
33
34     QColor bkgrColor = Qt::cyan;
35     QPen borderPen(bkgrColor.darker());
36     if(hasParent(index))
37     {
38         if(isLast(index))
39         {
40             QLinearGradient lastGradient(option.rect.topLeft(), option.rect.bottomLeft());
41             lastGradient.setColorAt(0.0, Qt::white);
42             lastGradient.setColorAt(0.5, bkgrColor);
43             lastGradient.setColorAt(1.0, Qt::white);
44
45             QPainterPath endPath;
46             endPath.moveTo(option.rect.topLeft());
47             endPath.lineTo(option.rect.bottomLeft()-QPoint(0, RADIUS));
48             endPath.arcTo(option.rect.left(), option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 180, 90);
49             endPath.lineTo(option.rect.bottomRight()-QPoint(RADIUS, 0));
50             endPath.arcTo(option.rect.right()-2*RADIUS, option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 270, 90);
51             endPath.lineTo(option.rect.topRight());
52
53             //painter->setBrush( bkgrColor );
54             painter->setBrush(lastGradient);
55             painter->setPen(borderPen);
56             painter->drawPath(endPath);
57
58             painter->setFont(option.font);
59         }
60         else // middle elements
61         {
62
63             QLinearGradient middleGradient(option.rect.topLeft(), option.rect.bottomLeft());
64             middleGradient.setColorAt(0.0, Qt::white);
65             middleGradient.setColorAt(0.25, bkgrColor);
66             middleGradient.setColorAt(0.5, Qt::white);
67             middleGradient.setColorAt(0.75, bkgrColor);
68             middleGradient.setColorAt(1.0, Qt::white);
69
70             //painter->setBrush( bkgrColor );
71             painter->setBrush(middleGradient);
72             painter->setPen(Qt::NoPen);
73             painter->drawRect(option.rect);
74
75             painter->setPen(borderPen);
76             // vertical lines
77             painter->drawLine(option.rect.topLeft(), option.rect.bottomLeft());
78             painter->drawLine(option.rect.topRight(), option.rect.bottomRight());
79             // horizontal lines
80             painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());
81
82             painter->setFont(option.font);
83         }
84
85         // draw Controls
86         painter->drawImage(mControls[FavouriteControl]->drawPoint(option.rect),*mControls[FavouriteControl]->image());
87         painter->drawImage(mControls[AlarmControl]->drawPoint(option.rect),*mControls[AlarmControl]->image());
88         painter->drawImage(mControls[MapControl]->drawPoint(option.rect),*mControls[MapControl]->image());
89     }
90     else // doesn't have parent - time-groups' elements (top items)
91     {
92         QLinearGradient titleGradient(option.rect.topLeft(), option.rect.topRight());
93         //titleGradient.setColorAt(0.0, Qt::white);
94         titleGradient.setColorAt(0.0, bkgrColor);
95         titleGradient.setColorAt(0.5, Qt::white);
96         titleGradient.setColorAt(1.0, bkgrColor);
97
98         QPainterPath titlePath;
99         if(isExpanded(index))
100         {
101             titlePath.moveTo(option.rect.bottomLeft());
102             titlePath.lineTo(option.rect.topLeft()+QPoint(0, RADIUS));
103             titlePath.arcTo(option.rect.left(), option.rect.top(), 2*RADIUS, 2*RADIUS, 180, -90);
104             titlePath.lineTo(option.rect.topRight()-QPoint(RADIUS, 0));
105             titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.top(), 2*RADIUS, 2*RADIUS, 90, -90);
106             titlePath.lineTo(option.rect.bottomRight());
107             titlePath.closeSubpath();
108         }
109         else
110         {
111             titlePath.lineTo(option.rect.topLeft()+QPoint(0, RADIUS));
112             titlePath.arcTo(option.rect.left(), option.rect.top(), 2*RADIUS, 2*RADIUS, 180, -90);
113             titlePath.lineTo(option.rect.topRight()-QPoint(RADIUS, 0));
114             titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.top(), 2*RADIUS, 2*RADIUS, 90, -90);
115             titlePath.lineTo(option.rect.bottomRight()-QPoint(0, RADIUS));
116             titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 0, -90);
117             titlePath.lineTo(option.rect.bottomLeft()+QPoint(RADIUS, 0));
118             titlePath.arcTo(option.rect.left(), option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 270, -90);      
119             titlePath.closeSubpath();
120         }
121
122         painter->setBrush(titleGradient);
123         painter->setPen(borderPen);
124         painter->drawPath(titlePath);
125
126         QFont font = option.font;
127         font.setBold(true);
128         painter->setFont(font);
129     }
130
131     //// HIGHLIGHTING SELECTED ITEM
132     //if (option.state & QStyle::State_Selected)
133         //painter->fillRect(option.rect, option.palette.highlight());
134
135     // draw title
136     QPointF titlePointF(option.rect.x(),option.rect.y()+option.rect.height()-10);
137     QString text = qVariantValue<QString>(index.data());
138     painter->drawText(titlePointF,text);
139
140     painter->restore();
141 }
142
143 QSize Delegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
144 {
145     Q_UNUSED(option)
146
147     if (index.internalId() == 0) // time group
148     {
149         return QSize(30,30);
150     }
151     else // event
152     {
153         return QSize(100,100);
154     }
155 }
156
157 bool Delegate::hasParent( const QModelIndex &index ) const
158 {
159     if( index.parent().isValid() )
160         return true;
161     else
162         return false;
163 }
164   
165 bool Delegate::isLast( const QModelIndex &index ) const
166 {
167     if(!hasParent(index))
168         return false; // what should be returned here?
169
170     if(index.row() >= (index.model()->rowCount(index.parent())-1))
171         return true;
172     else
173         return false;
174 }
175
176 bool Delegate::isExpanded( const QModelIndex &index ) const
177 {
178     if( !mViewPtr )
179         return false;
180     else
181         return mViewPtr->isExpanded( index );
182 }
183
184 Delegate::ControlId Delegate::whichControlClicked(const QModelIndex &aIndex, const QPoint &aPoint) const
185 {
186     if(!hasParent(aIndex)) // time-group item (root item)
187         return ControlNone;
188
189     QListIterator<ControlId> i(mControls.keys());
190     while (i.hasNext())
191     {
192         ControlId id = i.next();
193         if(mControls[id]->drawRect(static_cast<QTreeView*>(parent())->visualRect(aIndex)).contains(aPoint))
194             return id;
195     }
196
197     return ControlNone;
198 }
199
200 void Delegate::defineControls()
201 {
202     Control *control;
203     // FAVOURITE ICON
204     control = new Control(FavouriteControl,QString(":icons/favourite-on.png"));
205     control->setDrawPoint(QPoint(-control->image()->width()-SPACER,SPACER));
206     mControls.insert(FavouriteControl,control);
207
208     // ALARM ICON
209     control = new Control(AlarmControl,QString(":icons/alarm-on.png"));
210     control->setDrawPoint(QPoint(-mControls[FavouriteControl]->image()->width()-control->image()->width()-2*SPACER,SPACER));
211     mControls.insert(AlarmControl,control);
212
213     // MAP ICON
214     control = new Control(MapControl,QString(":icons/compass.png"));
215     control->setDrawPoint(QPoint(-mControls[AlarmControl]->image()->width()-control->image()->width()
216                                  -mControls[FavouriteControl]->image()->width()-3*SPACER,SPACER));
217     mControls.insert(MapControl,control);
218 }
219
220 bool Delegate::isPointFromRect(const QPoint &aPoint, const QRect &aRect) const
221 {
222     if( (aPoint.x()>=aRect.left() && aPoint.x()<=aRect.right()) && (aPoint.y()>=aRect.top() && aPoint.y()<=aRect.bottom()) )
223         return true;
224
225     return false;
226 }
227