source: src/mvc/delegate.cpp @ 336fa33

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

conflicts refactoring

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