71e967aa3791b82443781ee4c0ed649a3578a2e3
[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         if(static_cast<Event*>(index.internalPointer())->isFavourite())
87             painter->drawImage(mControls[FavouriteControlOn]->drawPoint(option.rect),*mControls[FavouriteControlOn]->image());
88         else
89             painter->drawImage(mControls[FavouriteControlOff]->drawPoint(option.rect),*mControls[FavouriteControlOff]->image());
90         painter->drawImage(mControls[AlarmControlOn]->drawPoint(option.rect),*mControls[AlarmControlOn]->image());
91         painter->drawImage(mControls[MapControl]->drawPoint(option.rect),*mControls[MapControl]->image());
92     }
93     else // doesn't have parent - time-groups' elements (top items)
94     {
95         QLinearGradient titleGradient(option.rect.topLeft(), option.rect.topRight());
96         //titleGradient.setColorAt(0.0, Qt::white);
97         titleGradient.setColorAt(0.0, bkgrColor);
98         titleGradient.setColorAt(0.5, Qt::white);
99         titleGradient.setColorAt(1.0, bkgrColor);
100
101         QPainterPath titlePath;
102         if(isExpanded(index))
103         {
104             titlePath.moveTo(option.rect.bottomLeft());
105             titlePath.lineTo(option.rect.topLeft()+QPoint(0, RADIUS));
106             titlePath.arcTo(option.rect.left(), option.rect.top(), 2*RADIUS, 2*RADIUS, 180, -90);
107             titlePath.lineTo(option.rect.topRight()-QPoint(RADIUS, 0));
108             titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.top(), 2*RADIUS, 2*RADIUS, 90, -90);
109             titlePath.lineTo(option.rect.bottomRight());
110             titlePath.closeSubpath();
111         }
112         else
113         {
114             titlePath.lineTo(option.rect.topLeft()+QPoint(0, RADIUS));
115             titlePath.arcTo(option.rect.left(), option.rect.top(), 2*RADIUS, 2*RADIUS, 180, -90);
116             titlePath.lineTo(option.rect.topRight()-QPoint(RADIUS, 0));
117             titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.top(), 2*RADIUS, 2*RADIUS, 90, -90);
118             titlePath.lineTo(option.rect.bottomRight()-QPoint(0, RADIUS));
119             titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 0, -90);
120             titlePath.lineTo(option.rect.bottomLeft()+QPoint(RADIUS, 0));
121             titlePath.arcTo(option.rect.left(), option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 270, -90);      
122             titlePath.closeSubpath();
123         }
124
125         painter->setBrush(titleGradient);
126         painter->setPen(borderPen);
127         painter->drawPath(titlePath);
128
129         QFont font = option.font;
130         font.setBold(true);
131         painter->setFont(font);
132     }
133
134     //// HIGHLIGHTING SELECTED ITEM
135     //if (option.state & QStyle::State_Selected)
136         //painter->fillRect(option.rect, option.palette.highlight());
137
138     // draw title
139     QPointF titlePointF(option.rect.x(),option.rect.y()+option.rect.height()-10);
140     QString text = qVariantValue<QString>(index.data());
141     painter->drawText(titlePointF,text);
142
143     painter->restore();
144 }
145
146 QSize Delegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
147 {
148     Q_UNUSED(option)
149
150     if (index.internalId() == 0) // time group
151     {
152         return QSize(30,30);
153     }
154     else // event
155     {
156         return QSize(100,100);
157     }
158 }
159
160 bool Delegate::hasParent( const QModelIndex &index ) const
161 {
162     if( index.parent().isValid() )
163         return true;
164     else
165         return false;
166 }
167   
168 bool Delegate::isLast( const QModelIndex &index ) const
169 {
170     if(!hasParent(index))
171         return false; // what should be returned here?
172
173     if(index.row() >= (index.model()->rowCount(index.parent())-1))
174         return true;
175     else
176         return false;
177 }
178
179 bool Delegate::isExpanded( const QModelIndex &index ) const
180 {
181     if( !mViewPtr )
182         return false;
183     else
184         return mViewPtr->isExpanded( index );
185 }
186
187 Delegate::ControlId Delegate::whichControlClicked(const QModelIndex &aIndex, const QPoint &aPoint) const
188 {
189     if(!hasParent(aIndex)) // time-group item (root item)
190         return ControlNone;
191
192     QListIterator<ControlId> i(mControls.keys());
193     while (i.hasNext())
194     {
195         ControlId id = i.next();
196         if(mControls[id]->drawRect(static_cast<QTreeView*>(parent())->visualRect(aIndex)).contains(aPoint))
197             return id;
198     }
199
200     return ControlNone;
201 }
202
203 void Delegate::defineControls()
204 {
205     Control *control;
206     // FAVOURITE ICONs
207     // on
208     control = new Control(FavouriteControlOn,QString(":icons/favourite-on.png"));
209     control->setDrawPoint(QPoint(-control->image()->width()-SPACER,SPACER));
210     mControls.insert(FavouriteControlOn,control);
211     // off
212     control = new Control(FavouriteControlOff,QString(":icons/favourite-off.png"));
213     control->setDrawPoint(QPoint(-control->image()->width()-SPACER,SPACER));
214     mControls.insert(FavouriteControlOff,control);
215
216     // ALARM ICONs
217     // on
218     control = new Control(AlarmControlOn,QString(":icons/alarm-on.png"));
219     control->setDrawPoint(QPoint(-mControls[FavouriteControlOn]->image()->width()-control->image()->width()-2*SPACER,SPACER));
220     mControls.insert(AlarmControlOn,control);
221     // off
222     control = new Control(AlarmControlOff,QString(":icons/alarm-off.png"));
223     control->setDrawPoint(QPoint(-mControls[FavouriteControlOff]->image()->width()-control->image()->width()-2*SPACER,SPACER));
224     mControls.insert(AlarmControlOff,control);
225
226     // MAP ICON
227     control = new Control(MapControl,QString(":icons/compass.png"));
228     control->setDrawPoint(QPoint(-mControls[AlarmControlOn]->image()->width()-control->image()->width()
229                                  -mControls[FavouriteControlOn]->image()->width()-3*SPACER,SPACER));
230     mControls.insert(MapControl,control);
231 }
232
233 bool Delegate::isPointFromRect(const QPoint &aPoint, const QRect &aRect) const
234 {
235     if( (aPoint.x()>=aRect.left() && aPoint.x()<=aRect.right()) && (aPoint.y()>=aRect.top() && aPoint.y()<=aRect.bottom()) )
236         return true;
237
238     return false;
239 }
240