]> ToastFreeware Gitweb - toast/confclerk.git/blob - src/mvc/delegate.cpp
Big icons fix 2
[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 = 23;
9
10 const double scaleFactor1 = 0.4;
11 const double scaleFactor2 = 0.8;
12
13 Delegate::Delegate(QTreeView *aParent)
14     : QItemDelegate(aParent)
15     , mViewPtr(aParent)
16 {
17     mControls.clear();
18     defineControls();
19 }
20
21 Delegate::~Delegate()
22 {
23     QListIterator<ControlId> i(mControls.keys());
24     while (i.hasNext())
25     {
26         delete mControls[i.next()]->image();
27     }
28 }
29
30 void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
31 {
32     if(!mViewPtr)
33         return;
34
35     QFont fontSmall = option.font;
36     fontSmall.setBold(true);
37     fontSmall.setPixelSize(option.rect.height()*scaleFactor1);
38     QFontMetrics fmSmall(fontSmall);
39
40     QFont fontBig = option.font;
41     fontBig.setBold(true);
42     fontBig.setPixelSize(option.rect.height()*scaleFactor2);
43     QFontMetrics fmBig(fontBig);
44
45     int spacer = (fmSmall.boundingRect("999").width() < SPACER) ? SPACER : fmSmall.boundingRect("999").width();
46
47     painter->save();
48
49     QColor bkgrColor = Qt::cyan;
50     QPen borderPen(bkgrColor.darker());
51     if(hasParent(index))
52     {
53         if(isLast(index))
54         {
55             QLinearGradient lastGradient(option.rect.topLeft(), option.rect.bottomLeft());
56             lastGradient.setColorAt(0.0, Qt::white);
57             lastGradient.setColorAt(0.5, bkgrColor);
58             lastGradient.setColorAt(1.0, Qt::white);
59
60             QPainterPath endPath;
61             endPath.moveTo(option.rect.topLeft());
62             endPath.lineTo(option.rect.bottomLeft()-QPoint(0, RADIUS));
63             endPath.arcTo(option.rect.left(), option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 180, 90);
64             endPath.lineTo(option.rect.bottomRight()-QPoint(RADIUS, 0));
65             endPath.arcTo(option.rect.right()-2*RADIUS, option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 270, 90);
66             endPath.lineTo(option.rect.topRight());
67
68             //painter->setBrush( bkgrColor );
69             painter->setBrush(lastGradient);
70             painter->setPen(borderPen);
71             painter->drawPath(endPath);
72
73             painter->setFont(option.font);
74         }
75         else // middle elements
76         {
77
78             QLinearGradient middleGradient(option.rect.topLeft(), option.rect.bottomLeft());
79             middleGradient.setColorAt(0.0, Qt::white);
80             middleGradient.setColorAt(0.25, bkgrColor);
81             middleGradient.setColorAt(0.5, Qt::white);
82             middleGradient.setColorAt(0.75, bkgrColor);
83             middleGradient.setColorAt(1.0, Qt::white);
84
85             //painter->setBrush( bkgrColor );
86             painter->setBrush(middleGradient);
87             painter->setPen(Qt::NoPen);
88             painter->drawRect(option.rect);
89
90             painter->setPen(borderPen);
91             // vertical lines
92             painter->drawLine(option.rect.topLeft(), option.rect.bottomLeft());
93             painter->drawLine(option.rect.topRight(), option.rect.bottomRight());
94             // horizontal lines
95             painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());
96
97             painter->setFont(option.font);
98         }
99
100         // draw Controls
101         // favourite
102         if(static_cast<Event*>(index.internalPointer())->isFavourite())
103             painter->drawImage(mControls[FavouriteControlOn]->drawPoint(option.rect),*mControls[FavouriteControlOn]->image());
104         else
105             painter->drawImage(mControls[FavouriteControlOff]->drawPoint(option.rect),*mControls[FavouriteControlOff]->image());
106         // alarm
107         if(static_cast<Event*>(index.internalPointer())->hasAlarm())
108             painter->drawImage(mControls[AlarmControlOn]->drawPoint(option.rect),*mControls[AlarmControlOn]->image());
109         else
110             painter->drawImage(mControls[AlarmControlOff]->drawPoint(option.rect),*mControls[AlarmControlOff]->image());
111         // map
112         painter->drawImage(mControls[MapControl]->drawPoint(option.rect),*mControls[MapControl]->image());
113
114         // draw texts
115         QPointF titlePointF;
116         titlePointF = QPoint(option.rect.x()+SPACER,option.rect.y()+option.rect.height()-10);
117         QString text = qVariantValue<QString>(index.data()) + ": " + static_cast<Event*>(index.internalPointer())->title();
118         painter->drawText(titlePointF,text);
119     }
120     else // doesn't have parent - time-groups' elements (top items)
121     {
122         QLinearGradient titleGradient(option.rect.topLeft(), option.rect.topRight());
123         //titleGradient.setColorAt(0.0, Qt::white);
124         titleGradient.setColorAt(0.0, bkgrColor);
125         titleGradient.setColorAt(0.5, Qt::white);
126         titleGradient.setColorAt(1.0, bkgrColor);
127
128         QPainterPath titlePath;
129         if(isExpanded(index))
130         {
131             titlePath.moveTo(option.rect.bottomLeft());
132             titlePath.lineTo(option.rect.topLeft()+QPoint(0, RADIUS));
133             titlePath.arcTo(option.rect.left(), option.rect.top(), 2*RADIUS, 2*RADIUS, 180, -90);
134             titlePath.lineTo(option.rect.topRight()-QPoint(RADIUS, 0));
135             titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.top(), 2*RADIUS, 2*RADIUS, 90, -90);
136             titlePath.lineTo(option.rect.bottomRight());
137             titlePath.closeSubpath();
138         }
139         else
140         {
141             titlePath.lineTo(option.rect.topLeft()+QPoint(0, RADIUS));
142             titlePath.arcTo(option.rect.left(), option.rect.top(), 2*RADIUS, 2*RADIUS, 180, -90);
143             titlePath.lineTo(option.rect.topRight()-QPoint(RADIUS, 0));
144             titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.top(), 2*RADIUS, 2*RADIUS, 90, -90);
145             titlePath.lineTo(option.rect.bottomRight()-QPoint(0, RADIUS));
146             titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 0, -90);
147             titlePath.lineTo(option.rect.bottomLeft()+QPoint(RADIUS, 0));
148             titlePath.arcTo(option.rect.left(), option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 270, -90);      
149             titlePath.closeSubpath();
150         }
151
152         painter->setBrush(titleGradient);
153         painter->setPen(borderPen);
154         painter->drawPath(titlePath);
155
156         // draw icons 
157         painter->setFont(fontSmall);
158         QPoint drawPoint =
159             option.rect.topRight()
160             - QPoint(
161                     spacer + mControls[FavouriteControlOn]->image()->width(),
162                     - option.rect.height()/2 + mControls[FavouriteControlOn]->image()->height()/2);
163         painter->drawImage(drawPoint,*mControls[FavouriteControlOn]->image());
164         painter->drawText(drawPoint+QPoint(mControls[FavouriteControlOn]->image()->width()+2, option.rect.height()/2),
165                 QString::number(numberOfFavourities(index)));
166         drawPoint.setX(drawPoint.x() - spacer - mControls[FavouriteControlOn]->image()->width());
167         painter->drawImage(drawPoint,*mControls[AlarmControlOn]->image());
168         painter->drawText(drawPoint+QPoint(mControls[FavouriteControlOn]->image()->width()+2, option.rect.height()/2),
169                 QString::number(numberOfAlarms(index)));
170         // draw texts
171         QString numEvents = QString::number(index.model()->rowCount(index)).append("/");
172         drawPoint.setX(drawPoint.x() - spacer - fmSmall.boundingRect(numEvents).width());
173         drawPoint.setY(drawPoint.y() + option.rect.height()/2);
174         painter->drawText(drawPoint,numEvents);
175
176         QPointF titlePointF = QPoint(
177                 option.rect.x()+SPACER,
178                 option.rect.y()+option.rect.height()-fmBig.descent());
179         painter->setFont(fontBig);
180
181         painter->drawText(titlePointF,qVariantValue<QString>(index.data()));
182     }
183
184     //// HIGHLIGHTING SELECTED ITEM
185     //if (option.state & QStyle::State_Selected)
186         //painter->fillRect(option.rect, option.palette.highlight());
187
188     painter->restore();
189 }
190
191 QSize Delegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
192 {
193     Q_UNUSED(option)
194
195     if (index.internalId() == 0) // time group
196     {
197         return QSize(40,40);
198     }
199     else // event
200     {
201         return QSize(100,100);
202     }
203 }
204
205 bool Delegate::hasParent( const QModelIndex &index ) const
206 {
207     if( index.parent().isValid() )
208         return true;
209     else
210         return false;
211 }
212   
213 bool Delegate::isLast( const QModelIndex &index ) const
214 {
215     if(!hasParent(index))
216         return false; // what should be returned here?
217
218     if(index.row() >= (index.model()->rowCount(index.parent())-1))
219         return true;
220     else
221         return false;
222 }
223
224 bool Delegate::isExpanded( const QModelIndex &index ) const
225 {
226     if( !mViewPtr )
227         return false;
228     else
229         return mViewPtr->isExpanded( index );
230 }
231
232 Delegate::ControlId Delegate::whichControlClicked(const QModelIndex &aIndex, const QPoint &aPoint) const
233 {
234     if(!hasParent(aIndex)) // time-group item (root item)
235         return ControlNone;
236
237     QListIterator<ControlId> i(mControls.keys());
238     while (i.hasNext())
239     {
240         ControlId id = i.next();
241         if(mControls[id]->drawRect(static_cast<QTreeView*>(parent())->visualRect(aIndex)).contains(aPoint))
242             return id;
243     }
244
245     return ControlNone;
246 }
247
248 void Delegate::defineControls()
249 {
250     Control *control;
251     QPoint p(0,0);
252     // FAVOURITE ICONs
253     // on
254     control = new Control(FavouriteControlOn,QString(":icons/favourite-onBig.png"));
255     p = QPoint(0,SPACER);
256     p.setX(p.x()-control->image()->width()-SPACER);
257     control->setDrawPoint(p);
258     mControls.insert(FavouriteControlOn,control);
259     // off
260     control = new Control(FavouriteControlOff,QString(":icons/favourite-offBig.png"));
261     p = QPoint(0,SPACER);
262     p.setX(p.x()-control->image()->width()-SPACER);
263     control->setDrawPoint(p);
264     mControls.insert(FavouriteControlOff,control);
265
266     // ALARM ICONs
267     // on
268     control = new Control(AlarmControlOn,QString(":icons/alarm-onBig.png"));
269     p = mControls[FavouriteControlOn]->drawPoint();
270     p.setX(p.x()-control->image()->width()-SPACER);
271     control->setDrawPoint(p);
272     mControls.insert(AlarmControlOn,control);
273     // off
274     control = new Control(AlarmControlOff,QString(":icons/alarm-offBig.png"));
275     p = mControls[FavouriteControlOff]->drawPoint();
276     p.setX(p.x()-control->image()->width()-SPACER);
277     control->setDrawPoint(p);
278     mControls.insert(AlarmControlOff,control);
279
280     // MAP ICON
281     control = new Control(MapControl,QString(":icons/compassBig.png"));
282     p = mControls[AlarmControlOn]->drawPoint();
283     p.setX(p.x()-control->image()->width()-SPACER);
284     control->setDrawPoint(p);
285     mControls.insert(MapControl,control);
286 }
287
288 bool Delegate::isPointFromRect(const QPoint &aPoint, const QRect &aRect) const
289 {
290     if( (aPoint.x()>=aRect.left() && aPoint.x()<=aRect.right()) && (aPoint.y()>=aRect.top() && aPoint.y()<=aRect.bottom()) )
291         return true;
292
293     return false;
294 }
295
296 int Delegate::numberOfFavourities(const QModelIndex &index) const
297 {
298     if(index.parent().isValid()) // it's event, not time-group
299         return 0;
300
301     int nrofFavs = 0;
302     for(int i=0; i<index.model()->rowCount(index); i++)
303         if(static_cast<Event*>(index.child(i,0).internalPointer())->isFavourite())
304             nrofFavs++;
305
306     return nrofFavs;
307 }
308
309 int Delegate::numberOfAlarms(const QModelIndex &index) const
310 {
311     if(index.parent().isValid()) // it's event, not time-group
312         return 0;
313
314     int nrofAlarms = 0;
315     for(int i=0; i<index.model()->rowCount(index); i++)
316         if(static_cast<Event*>(index.child(i,0).internalPointer())->hasAlarm())
317             nrofAlarms++;
318
319     return nrofAlarms;
320 }
321