source: src/mvc/delegate.cpp @ f2ef735

qt5
Last change on this file since f2ef735 was f2ef735, checked in by fortefr <fortefr@…>, 12 years ago

Warning icon (uncompleted)

  • Property mode set to 100644
File size: 14.7 KB
Line 
1#include "delegate.h"
2#include "eventmodel.h"
3#include <activity.h>
4
5#include <QDebug>
6#include <QPainter>
7
8const int RADIUS = 10;
9const int SPACER = 10;
10
11const double scaleFactor1 = 0.4;
12const double scaleFactor2 = 0.8;
13
14Delegate::Delegate(QTreeView *aParent)
15    : QItemDelegate(aParent)
16    , mViewPtr(aParent)
17{
18    mControls.clear();
19    defineControls();
20}
21
22Delegate::~Delegate()
23{
24    QListIterator<ControlId> i(mControls.keys());
25    while (i.hasNext())
26    {
27        delete mControls[i.next()]->image();
28    }
29}
30
31void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
32{
33    if(!mViewPtr)
34        return;
35
36    painter->save();
37
38    QColor bkgrColor = Qt::cyan;
39    QPen borderPen(bkgrColor.darker());
40    //QColor bkgrColor = QColor(0,0,113);
41    //QPen borderPen(Qt::cyan);
42    if(hasParent(index))
43    {
44        int aux = option.rect.height() - mControls[FavouriteControlOn]->drawPoint().y() - mControls[FavouriteControlOn]->image()->height();
45        // font SMALL
46        QFont fontSmall = option.font;
47        fontSmall.setBold(false);
48        fontSmall.setPixelSize(aux*0.2);
49        QFontMetrics fmSmall(fontSmall);
50        // font SMALL bold
51        QFont fontSmallB = fontSmall;
52        fontSmallB.setBold(true);
53        QFontMetrics fmSmallB(fontSmallB);
54
55        // font BIG
56        QFont fontBig = option.font;
57        fontBig.setBold(false);
58        fontBig.setPixelSize(aux*0.33);
59        QFontMetrics fmBig(fontBig);
60        // font BIG bold
61        QFont fontBigB = fontBig;
62        fontBigB.setBold(true);
63        QFontMetrics fmBigB(fontBigB);
64
65        int spacer = (fmSmall.boundingRect("999").width() < SPACER) ? SPACER : fmSmall.boundingRect("999").width();
66
67        if(isLast(index))
68        {
69            QLinearGradient lastGradient(option.rect.topLeft(), option.rect.bottomLeft());
70            lastGradient.setColorAt(0.0, Qt::white);
71            lastGradient.setColorAt(0.5, bkgrColor);
72            lastGradient.setColorAt(1.0, Qt::white);
73
74            QPainterPath endPath;
75            endPath.moveTo(option.rect.topLeft());
76            endPath.lineTo(option.rect.bottomLeft()-QPoint(0, RADIUS));
77            endPath.arcTo(option.rect.left(), option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 180, 90);
78            endPath.lineTo(option.rect.bottomRight()-QPoint(RADIUS, 0));
79            endPath.arcTo(option.rect.right()-2*RADIUS, option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 270, 90);
80            endPath.lineTo(option.rect.topRight());
81
82            painter->setBrush( bkgrColor );
83            //painter->setBrush(lastGradient);
84            painter->setPen(borderPen);
85            painter->drawPath(endPath);
86
87            painter->setFont(option.font);
88        }
89        else // middle elements
90        {
91            QLinearGradient middleGradient(option.rect.topLeft(), option.rect.bottomLeft());
92            middleGradient.setColorAt(0.0, Qt::white);
93            middleGradient.setColorAt(0.25, bkgrColor);
94            middleGradient.setColorAt(0.5, Qt::white);
95            middleGradient.setColorAt(0.75, bkgrColor);
96            middleGradient.setColorAt(1.0, Qt::white);
97
98            painter->setBrush( bkgrColor );
99            //painter->setBrush(middleGradient);
100            painter->setPen(Qt::NoPen);
101            painter->drawRect(option.rect);
102
103            painter->setPen(borderPen);
104            // vertical lines
105            painter->drawLine(option.rect.topLeft(), option.rect.bottomLeft());
106            painter->drawLine(option.rect.topRight(), option.rect.bottomRight());
107            // horizontal lines
108            painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());
109
110            painter->setFont(option.font);
111        }
112
113        // draw Controls
114        // favourite
115        if(static_cast<Event*>(index.internalPointer())->isFavourite())
116            painter->drawImage(mControls[FavouriteControlOn]->drawPoint(option.rect),*mControls[FavouriteControlOn]->image());
117        else
118            painter->drawImage(mControls[FavouriteControlOff]->drawPoint(option.rect),*mControls[FavouriteControlOff]->image());
119        // alarm
120        if(static_cast<Event*>(index.internalPointer())->hasAlarm())
121            painter->drawImage(mControls[AlarmControlOn]->drawPoint(option.rect),*mControls[AlarmControlOn]->image());
122        else
123            painter->drawImage(mControls[AlarmControlOff]->drawPoint(option.rect),*mControls[AlarmControlOff]->image());
124        // map
125        painter->drawImage(mControls[MapControl]->drawPoint(option.rect),*mControls[MapControl]->image());
126        // Time conflict
127        if(static_cast<Event*>(index.internalPointer())->hasTimeConflict())
128            painter->drawImage(mControls[WarningControlOn]->drawPoint(option.rect),*mControls[WarningControlOn]->image());
129        else
130            painter->drawImage(mControls[WarningControlOff]->drawPoint(option.rect),*mControls[WarningControlOff]->image());
131
132        // draw texts
133        Event *event = static_cast<Event*>(index.internalPointer());
134        QPointF titlePointF(mControls[FavouriteControlOn]->drawPoint(option.rect));
135        titlePointF.setX(option.rect.x()+SPACER);
136        titlePointF.setY(titlePointF.y()+mControls[FavouriteControlOn]->image()->height());
137        QTime start = event->start().time();
138        painter->setFont(fontBig);
139        painter->drawText(titlePointF,start.toString("hh:mm") + "-" + start.addSecs(event->duration()).toString("hh:mm") + ", " + event->room());
140        // title
141        titlePointF.setY(titlePointF.y()+fmBig.height()-fmBig.descent());
142        painter->setFont(fontBigB);
143        QString title = event->title();
144        if(fmBigB.boundingRect(title).width() > (option.rect.width()-2*SPACER)) // the title won't fit the screen
145        {
146            // chop words from the end
147            while( (fmBigB.boundingRect(title + "...").width() > (option.rect.width()-2*SPACER)) && !title.isEmpty())
148            {
149                title.chop(1);
150                // chop characters one-by-one from the end
151                while( (!title.at(title.length()-1).isSpace()) && !title.isEmpty())
152                {
153                    title.chop(1);
154                }
155            }
156            title += "...";
157        }
158        painter->drawText(titlePointF,title);
159        // persons
160        titlePointF.setY(titlePointF.y()+fmSmall.height()-fmSmall.descent());
161        painter->setFont(fontSmall);
162        painter->drawText(titlePointF,"Presenter(s): " + event->persons().join(" and "));
163        // track
164        titlePointF.setY(titlePointF.y()+fmSmall.height()-fmSmall.descent());
165        painter->drawText(titlePointF,"Activity(s): " + Activity::getActivityName(event->activityId()));
166    }
167    else // doesn't have parent - time-groups' elements (top items)
168    {
169        QFont fontSmall = option.font;
170        fontSmall.setBold(true);
171        fontSmall.setPixelSize(option.rect.height()*scaleFactor1);
172        QFontMetrics fmSmall(fontSmall);
173
174        QFont fontBig = option.font;
175        fontBig.setBold(true);
176        fontBig.setPixelSize(option.rect.height()*scaleFactor2);
177        QFontMetrics fmBig(fontBig);
178
179        int spacer = (fmSmall.boundingRect("999").width() < SPACER) ? SPACER : fmSmall.boundingRect("999").width();
180
181        QLinearGradient titleGradient(option.rect.topLeft(), option.rect.topRight());
182        //titleGradient.setColorAt(0.0, Qt::white);
183        titleGradient.setColorAt(0.0, bkgrColor);
184        titleGradient.setColorAt(0.5, Qt::white);
185        titleGradient.setColorAt(1.0, bkgrColor);
186
187        QPainterPath titlePath;
188        if(isExpanded(index))
189        {
190            titlePath.moveTo(option.rect.bottomLeft());
191            titlePath.lineTo(option.rect.topLeft()+QPoint(0, RADIUS));
192            titlePath.arcTo(option.rect.left(), option.rect.top(), 2*RADIUS, 2*RADIUS, 180, -90);
193            titlePath.lineTo(option.rect.topRight()-QPoint(RADIUS, 0));
194            titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.top(), 2*RADIUS, 2*RADIUS, 90, -90);
195            titlePath.lineTo(option.rect.bottomRight());
196            titlePath.closeSubpath();
197        }
198        else
199        {
200            titlePath.lineTo(option.rect.topLeft()+QPoint(0, RADIUS));
201            titlePath.arcTo(option.rect.left(), option.rect.top(), 2*RADIUS, 2*RADIUS, 180, -90);
202            titlePath.lineTo(option.rect.topRight()-QPoint(RADIUS, 0));
203            titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.top(), 2*RADIUS, 2*RADIUS, 90, -90);
204            titlePath.lineTo(option.rect.bottomRight()-QPoint(0, RADIUS));
205            titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 0, -90);
206            titlePath.lineTo(option.rect.bottomLeft()+QPoint(RADIUS, 0));
207            titlePath.arcTo(option.rect.left(), option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 270, -90);     
208            titlePath.closeSubpath();
209        }
210
211        painter->setBrush(titleGradient);
212        painter->setPen(borderPen);
213        painter->drawPath(titlePath);
214
215        // draw icons
216        painter->setFont(fontSmall);
217        QPoint drawPoint =
218            option.rect.topRight()
219            - QPoint(
220                    spacer + mControls[FavouriteControlOn]->image()->width(),
221                    - option.rect.height()/2 + mControls[FavouriteControlOn]->image()->height()/2);
222        painter->drawImage(drawPoint,*mControls[FavouriteControlOn]->image());
223        painter->drawText(drawPoint+QPoint(mControls[FavouriteControlOn]->image()->width()+2, option.rect.height()/2),
224                QString::number(numberOfFavourities(index)));
225        drawPoint.setX(drawPoint.x() - spacer - mControls[FavouriteControlOn]->image()->width());
226        painter->drawImage(drawPoint,*mControls[AlarmControlOn]->image());
227        painter->drawText(drawPoint+QPoint(mControls[FavouriteControlOn]->image()->width()+2, option.rect.height()/2),
228                QString::number(numberOfAlarms(index)));
229        // draw texts
230        QString numEvents = QString::number(index.model()->rowCount(index)).append("/");
231        drawPoint.setX(drawPoint.x() - spacer - fmSmall.boundingRect(numEvents).width());
232        drawPoint.setY(drawPoint.y() + option.rect.height()/2);
233        painter->drawText(drawPoint,numEvents);
234
235        QPointF titlePointF = QPoint(
236                option.rect.x()+SPACER,
237                option.rect.y()+option.rect.height()-fmBig.descent());
238        painter->setFont(fontBig);
239
240        painter->drawText(titlePointF,qVariantValue<QString>(index.data()));
241    }
242
243    //// HIGHLIGHTING SELECTED ITEM
244    //if (option.state & QStyle::State_Selected)
245        //painter->fillRect(option.rect, option.palette.highlight());
246
247    painter->restore();
248}
249
250QSize Delegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
251{
252    Q_UNUSED(option)
253
254    if (index.internalId() == 0) // time group
255    {
256        return QSize(40,40);
257    }
258    else // event
259    {
260        return QSize(100,100);
261    }
262}
263
264bool Delegate::hasParent( const QModelIndex &index ) const
265{
266    if( index.parent().isValid() )
267        return true;
268    else
269        return false;
270}
271 
272bool Delegate::isLast( const QModelIndex &index ) const
273{
274    if(!hasParent(index))
275        return false; // what should be returned here?
276
277    if(index.row() >= (index.model()->rowCount(index.parent())-1))
278        return true;
279    else
280        return false;
281}
282
283bool Delegate::isExpanded( const QModelIndex &index ) const
284{
285    if( !mViewPtr )
286        return false;
287    else
288        return mViewPtr->isExpanded( index );
289}
290
291Delegate::ControlId Delegate::whichControlClicked(const QModelIndex &aIndex, const QPoint &aPoint) const
292{
293    if(!hasParent(aIndex)) // time-group item (root item)
294        return ControlNone;
295
296    QListIterator<ControlId> i(mControls.keys());
297    while (i.hasNext())
298    {
299        ControlId id = i.next();
300        if(mControls[id]->drawRect(static_cast<QTreeView*>(parent())->visualRect(aIndex)).contains(aPoint))
301            return id;
302    }
303
304    return ControlNone;
305}
306
307void Delegate::defineControls()
308{
309    Control *control;
310    QPoint p(0,0);
311    // FAVOURITE ICONs
312    // on
313    control = new Control(FavouriteControlOn,QString(":icons/favourite-onBig.png"));
314    p = QPoint(0,SPACER);
315    p.setX(p.x()-control->image()->width()-SPACER);
316    control->setDrawPoint(p);
317    mControls.insert(FavouriteControlOn,control);
318    // off
319    control = new Control(FavouriteControlOff,QString(":icons/favourite-offBig.png"));
320    p = QPoint(0,SPACER);
321    p.setX(p.x()-control->image()->width()-SPACER);
322    control->setDrawPoint(p);
323    mControls.insert(FavouriteControlOff,control);
324
325    // ALARM ICONs
326    // on
327    control = new Control(AlarmControlOn,QString(":icons/alarm-onBig.png"));
328    p = mControls[FavouriteControlOn]->drawPoint();
329    p.setX(p.x()-control->image()->width()-SPACER);
330    control->setDrawPoint(p);
331    mControls.insert(AlarmControlOn,control);
332    // off
333    control = new Control(AlarmControlOff,QString(":icons/alarm-offBig.png"));
334    p = mControls[FavouriteControlOff]->drawPoint();
335    p.setX(p.x()-control->image()->width()-SPACER);
336    control->setDrawPoint(p);
337    mControls.insert(AlarmControlOff,control);
338
339    // MAP ICON
340    control = new Control(MapControl,QString(":icons/compassBig.png"));
341    p = mControls[AlarmControlOn]->drawPoint();
342    p.setX(p.x()-control->image()->width()-SPACER);
343    control->setDrawPoint(p);
344    mControls.insert(MapControl,control);
345
346    // WARNING ICONs
347    // on
348    control = new Control(WarningControlOn,QString(":icons/exclamation-iconOn.png"));
349    p = mControls[MapControl]->drawPoint();
350    p.setX(p.x()-control->image()->width()-SPACER);
351    control->setDrawPoint(p);
352    mControls.insert(WarningControlOn,control);
353    // off
354    control = new Control(WarningControlOff,QString(":icons/exclamation-iconOff.png"));
355    p = mControls[MapControl]->drawPoint();
356    p.setX(p.x()-control->image()->width()-SPACER);
357    control->setDrawPoint(p);
358    mControls.insert(WarningControlOff,control);
359}
360
361bool Delegate::isPointFromRect(const QPoint &aPoint, const QRect &aRect) const
362{
363    if( (aPoint.x()>=aRect.left() && aPoint.x()<=aRect.right()) && (aPoint.y()>=aRect.top() && aPoint.y()<=aRect.bottom()) )
364        return true;
365
366    return false;
367}
368
369int Delegate::numberOfFavourities(const QModelIndex &index) const
370{
371    if(index.parent().isValid()) // it's event, not time-group
372        return 0;
373
374    int nrofFavs = 0;
375    for(int i=0; i<index.model()->rowCount(index); i++)
376        if(static_cast<Event*>(index.child(i,0).internalPointer())->isFavourite())
377            nrofFavs++;
378
379    return nrofFavs;
380}
381
382int Delegate::numberOfAlarms(const QModelIndex &index) const
383{
384    if(index.parent().isValid()) // it's event, not time-group
385        return 0;
386
387    int nrofAlarms = 0;
388    for(int i=0; i<index.model()->rowCount(index); i++)
389        if(static_cast<Event*>(index.child(i,0).internalPointer())->hasAlarm())
390            nrofAlarms++;
391
392    return nrofAlarms;
393}
394
Note: See TracBrowser for help on using the repository browser.