source: src/mvc/delegate.cpp @ 4693fa6

qt5
Last change on this file since 4693fa6 was 4693fa6, checked in by pavelpa <pavelpa@…>, 12 years ago

changed 'Activity' -> 'Track'

  • Property mode set to 100644
File size: 15.0 KB
Line 
1#include "delegate.h"
2#include "eventmodel.h"
3#include <track.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#ifdef MAEMO
120        // alarm
121        if(static_cast<Event*>(index.internalPointer())->hasAlarm())
122            painter->drawImage(mControls[AlarmControlOn]->drawPoint(option.rect),*mControls[AlarmControlOn]->image());
123        else
124            painter->drawImage(mControls[AlarmControlOff]->drawPoint(option.rect),*mControls[AlarmControlOff]->image());
125#endif
126        // map
127        painter->drawImage(mControls[MapControl]->drawPoint(option.rect),*mControls[MapControl]->image());
128        // Time conflict
129        if(static_cast<Event*>(index.internalPointer())->hasTimeConflict())
130            painter->drawImage(mControls[WarningControlOn]->drawPoint(option.rect),*mControls[WarningControlOn]->image());
131        else
132            painter->drawImage(mControls[WarningControlOff]->drawPoint(option.rect),*mControls[WarningControlOff]->image());
133
134        // draw texts
135        Event *event = static_cast<Event*>(index.internalPointer());
136        QPointF titlePointF(mControls[FavouriteControlOn]->drawPoint(option.rect));
137        titlePointF.setX(option.rect.x()+SPACER);
138        titlePointF.setY(titlePointF.y()+mControls[FavouriteControlOn]->image()->height());
139        QTime start = event->start().time();
140        painter->setFont(fontBig);
141        painter->drawText(titlePointF,start.toString("hh:mm") + "-" + start.addSecs(event->duration()).toString("hh:mm") + ", " + event->room());
142        // title
143        titlePointF.setY(titlePointF.y()+fmBig.height()-fmBig.descent());
144        painter->setFont(fontBigB);
145        QString title = event->title();
146        if(fmBigB.boundingRect(title).width() > (option.rect.width()-2*SPACER)) // the title won't fit the screen
147        {
148            // chop words from the end
149            while( (fmBigB.boundingRect(title + "...").width() > (option.rect.width()-2*SPACER)) && !title.isEmpty())
150            {
151                title.chop(1);
152                // chop characters one-by-one from the end
153                while( (!title.at(title.length()-1).isSpace()) && !title.isEmpty())
154                {
155                    title.chop(1);
156                }
157            }
158            title += "...";
159        }
160        painter->drawText(titlePointF,title);
161        // persons
162        titlePointF.setY(titlePointF.y()+fmSmall.height()-fmSmall.descent());
163        painter->setFont(fontSmall);
164        painter->drawText(titlePointF,"Presenter(s): " + event->persons().join(" and "));
165        // track
166        titlePointF.setY(titlePointF.y()+fmSmall.height()-fmSmall.descent());
167        painter->drawText(titlePointF,"Track: " + Track::getTrackName(event->trackId()));
168    }
169    else // doesn't have parent - time-groups' elements (top items)
170    {
171        QFont fontSmall = option.font;
172        fontSmall.setBold(true);
173        fontSmall.setPixelSize(option.rect.height()*scaleFactor1);
174        QFontMetrics fmSmall(fontSmall);
175
176        QFont fontBig = option.font;
177        fontBig.setBold(true);
178        fontBig.setPixelSize(option.rect.height()*scaleFactor2);
179        QFontMetrics fmBig(fontBig);
180
181        int spacer = (fmSmall.boundingRect("999").width() < SPACER) ? SPACER : fmSmall.boundingRect("999").width();
182
183        QLinearGradient titleGradient(option.rect.topLeft(), option.rect.topRight());
184        //titleGradient.setColorAt(0.0, Qt::white);
185        titleGradient.setColorAt(0.0, bkgrColor);
186        titleGradient.setColorAt(0.5, Qt::white);
187        titleGradient.setColorAt(1.0, bkgrColor);
188
189        QPainterPath titlePath;
190        if(isExpanded(index))
191        {
192            titlePath.moveTo(option.rect.bottomLeft());
193            titlePath.lineTo(option.rect.topLeft()+QPoint(0, RADIUS));
194            titlePath.arcTo(option.rect.left(), option.rect.top(), 2*RADIUS, 2*RADIUS, 180, -90);
195            titlePath.lineTo(option.rect.topRight()-QPoint(RADIUS, 0));
196            titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.top(), 2*RADIUS, 2*RADIUS, 90, -90);
197            titlePath.lineTo(option.rect.bottomRight());
198            titlePath.closeSubpath();
199        }
200        else
201        {
202            titlePath.lineTo(option.rect.topLeft()+QPoint(0, RADIUS));
203            titlePath.arcTo(option.rect.left(), option.rect.top(), 2*RADIUS, 2*RADIUS, 180, -90);
204            titlePath.lineTo(option.rect.topRight()-QPoint(RADIUS, 0));
205            titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.top(), 2*RADIUS, 2*RADIUS, 90, -90);
206            titlePath.lineTo(option.rect.bottomRight()-QPoint(0, RADIUS));
207            titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 0, -90);
208            titlePath.lineTo(option.rect.bottomLeft()+QPoint(RADIUS, 0));
209            titlePath.arcTo(option.rect.left(), option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 270, -90);     
210            titlePath.closeSubpath();
211        }
212
213        painter->setBrush(titleGradient);
214        painter->setPen(borderPen);
215        painter->drawPath(titlePath);
216
217        // draw icons
218        painter->setFont(fontSmall);
219        QPoint drawPoint =
220            option.rect.topRight()
221            - QPoint(
222                    spacer + mControls[FavouriteControlOn]->image()->width(),
223                    - option.rect.height()/2 + mControls[FavouriteControlOn]->image()->height()/2);
224        painter->drawImage(drawPoint,*mControls[FavouriteControlOn]->image());
225        painter->drawText(drawPoint+QPoint(mControls[FavouriteControlOn]->image()->width()+2, option.rect.height()/2),
226                QString::number(numberOfFavourities(index)));
227#ifdef MAEMO
228        drawPoint.setX(drawPoint.x() - spacer - mControls[FavouriteControlOn]->image()->width());
229        painter->drawImage(drawPoint,*mControls[AlarmControlOn]->image());
230        painter->drawText(drawPoint+QPoint(mControls[FavouriteControlOn]->image()->width()+2, option.rect.height()/2),
231                QString::number(numberOfAlarms(index)));
232#endif
233        // draw texts
234        QString numEvents = QString::number(index.model()->rowCount(index)).append("/");
235        drawPoint.setX(drawPoint.x() - spacer - fmSmall.boundingRect(numEvents).width());
236        drawPoint.setY(drawPoint.y() + option.rect.height()/2);
237        painter->drawText(drawPoint,numEvents);
238
239        QPointF titlePointF = QPoint(
240                option.rect.x()+SPACER,
241                option.rect.y()+option.rect.height()-fmBig.descent());
242        painter->setFont(fontBig);
243
244        painter->drawText(titlePointF,qVariantValue<QString>(index.data()));
245    }
246
247    //// HIGHLIGHTING SELECTED ITEM
248    //if (option.state & QStyle::State_Selected)
249        //painter->fillRect(option.rect, option.palette.highlight());
250
251    painter->restore();
252}
253
254QSize Delegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
255{
256    Q_UNUSED(option)
257
258    if (index.internalId() == 0) // time group
259    {
260        return QSize(40,40);
261    }
262    else // event
263    {
264        return QSize(100,100);
265    }
266}
267
268bool Delegate::hasParent( const QModelIndex &index ) const
269{
270    if( index.parent().isValid() )
271        return true;
272    else
273        return false;
274}
275 
276bool Delegate::isLast( const QModelIndex &index ) const
277{
278    if(!hasParent(index))
279        return false; // what should be returned here?
280
281    if(index.row() >= (index.model()->rowCount(index.parent())-1))
282        return true;
283    else
284        return false;
285}
286
287bool Delegate::isExpanded( const QModelIndex &index ) const
288{
289    if( !mViewPtr )
290        return false;
291    else
292        return mViewPtr->isExpanded( index );
293}
294
295Delegate::ControlId Delegate::whichControlClicked(const QModelIndex &aIndex, const QPoint &aPoint) const
296{
297    if(!hasParent(aIndex)) // time-group item (root item)
298        return ControlNone;
299
300    QListIterator<ControlId> i(mControls.keys());
301    while (i.hasNext())
302    {
303        ControlId id = i.next();
304        if(mControls[id]->drawRect(static_cast<QTreeView*>(parent())->visualRect(aIndex)).contains(aPoint))
305            return id;
306    }
307
308    return ControlNone;
309}
310
311void Delegate::defineControls()
312{
313    Control *control;
314    QPoint p(0,0);
315    // FAVOURITE ICONs
316    // on
317    control = new Control(FavouriteControlOn,QString(":icons/favourite-onBig.png"));
318    p = QPoint(0,SPACER);
319    p.setX(p.x()-control->image()->width()-SPACER);
320    control->setDrawPoint(p);
321    mControls.insert(FavouriteControlOn,control);
322    // off
323    control = new Control(FavouriteControlOff,QString(":icons/favourite-offBig.png"));
324    p = QPoint(0,SPACER);
325    p.setX(p.x()-control->image()->width()-SPACER);
326    control->setDrawPoint(p);
327    mControls.insert(FavouriteControlOff,control);
328
329#ifdef MAEMO
330    // ALARM ICONs
331    // on
332    control = new Control(AlarmControlOn,QString(":icons/alarm-onBig.png"));
333    p = mControls[FavouriteControlOn]->drawPoint();
334    p.setX(p.x()-control->image()->width()-SPACER);
335    control->setDrawPoint(p);
336    mControls.insert(AlarmControlOn,control);
337    // off
338    control = new Control(AlarmControlOff,QString(":icons/alarm-offBig.png"));
339    p = mControls[FavouriteControlOff]->drawPoint();
340    p.setX(p.x()-control->image()->width()-SPACER);
341    control->setDrawPoint(p);
342    mControls.insert(AlarmControlOff,control);
343
344    // MAP ICON
345    control = new Control(MapControl,QString(":icons/compassBig.png"));
346    p = mControls[AlarmControlOn]->drawPoint();
347    p.setX(p.x()-control->image()->width()-SPACER);
348    control->setDrawPoint(p);
349    mControls.insert(MapControl,control);
350#else
351    // MAP ICON
352    control = new Control(MapControl,QString(":icons/compassBig.png"));
353    p = mControls[FavouriteControlOn]->drawPoint();
354    p.setX(p.x()-control->image()->width()-SPACER);
355    control->setDrawPoint(p);
356    mControls.insert(MapControl,control);
357#endif
358
359    // WARNING ICONs
360    // on
361    control = new Control(WarningControlOn,QString(":icons/exclamation-iconOn.png"));
362    p = mControls[MapControl]->drawPoint();
363    p.setX(p.x()-control->image()->width()-SPACER);
364    control->setDrawPoint(p);
365    mControls.insert(WarningControlOn,control);
366    // off
367    control = new Control(WarningControlOff,QString(":icons/exclamation-iconOff.png"));
368    p = mControls[MapControl]->drawPoint();
369    p.setX(p.x()-control->image()->width()-SPACER);
370    control->setDrawPoint(p);
371    mControls.insert(WarningControlOff,control);
372}
373
374bool Delegate::isPointFromRect(const QPoint &aPoint, const QRect &aRect) const
375{
376    if( (aPoint.x()>=aRect.left() && aPoint.x()<=aRect.right()) && (aPoint.y()>=aRect.top() && aPoint.y()<=aRect.bottom()) )
377        return true;
378
379    return false;
380}
381
382int Delegate::numberOfFavourities(const QModelIndex &index) const
383{
384    if(index.parent().isValid()) // it's event, not time-group
385        return 0;
386
387    int nrofFavs = 0;
388    for(int i=0; i<index.model()->rowCount(index); i++)
389        if(static_cast<Event*>(index.child(i,0).internalPointer())->isFavourite())
390            nrofFavs++;
391
392    return nrofFavs;
393}
394
395int Delegate::numberOfAlarms(const QModelIndex &index) const
396{
397    if(index.parent().isValid()) // it's event, not time-group
398        return 0;
399
400    int nrofAlarms = 0;
401    for(int i=0; i<index.model()->rowCount(index); i++)
402        if(static_cast<Event*>(index.child(i,0).internalPointer())->hasAlarm())
403            nrofAlarms++;
404
405    return nrofAlarms;
406}
407
Note: See TracBrowser for help on using the repository browser.