4 QBitmap
* SakWidget::m_mask
= 0;
5 int SakWidget::m_maxzvalue
= 0;
7 SakWidget::SakWidget(const Task
& task
)
11 m_palette
.setColor(QPalette::Window
, task
.bgColor
);
12 m_palette
.setColor(QPalette::WindowText
, task
.fgColor
);
15 m_showingDetails
=false;
19 setAcceptsHoverEvents(false);
20 m_dailyWorked
= m_weeklyWorked
= m_dailyPercentage
= m_weeklyPercentage
= 0;
23 m_rect
= QRectF(0,0,400,400);
27 m_mask
= new QBitmap(QSize(400,400));
29 m_mask
->fill(Qt::white
);
32 pen
.setColor(Qt::black
);
34 p
.setBrush(Qt::black
);
35 int border
= m_border
+ 4;
36 p
.drawRoundRect(m_rect
.adjusted(border
,border
, -border
,-border
), 25, 25 );
39 m_text
= new QTextDocument(this);
40 m_text
->setHtml(m_tooltipText
);
41 m_text
->setTextWidth(m_rect
.width() - 20);
43 m_cachedPixmap
= QPixmap(QSize((int)m_rect
.width(), (int)m_rect
.height()));
44 m_cachedPixmapB
= QPixmap(QSize((int)m_rect
.width(), (int)m_rect
.height()));
47 m_ic
= QPixmap(m_task
.icon
);
49 m_ic
= m_ic
.scaled(m_mask
->width()-14, m_mask
->height()-14, Qt::KeepAspectRatio
);
50 QRect r
= m_ic
.rect();
51 r
.moveTopLeft(QPoint((m_mask
->width() - m_ic
.width())/2, (m_mask
->height()-m_ic
.height())/2));
52 m_ic
.setMask(m_mask
->copy(r
));
54 m_redrawCachedPixmap
=true;
55 m_redrawCachedPixmapB
=true;
59 SakWidget::~SakWidget()
66 void SakWidget::setStatistics(double dailyWorked
, double weeklyWorked
, double monthlyWorked
, double dailyPercentage
, double weeklyPercentage
, double monthlyPercentage
)
68 m_dailyWorked
= dailyWorked
;
69 m_weeklyWorked
= weeklyWorked
;
70 m_monthlyWorked
= monthlyWorked
;
71 m_dailyPercentage
= dailyPercentage
;
72 m_weeklyPercentage
= weeklyPercentage
;
73 m_monthlyPercentage
= monthlyPercentage
;
74 m_tooltipText
= QString("<div style=\"color:" + m_task
.fgColor
.name() + "\"><center><h1>%1</h1></center>%2%3<div>Today: <b>%4</b> h (%5%)<br />Last week: <b>%6</b> h (%7%)<br />Last month: <b>%8</b> h (%9%)</div></div>").arg(m_task
.title
).arg(m_task
.description
.isEmpty() ? "" : "<p>").arg(m_task
.description
).arg(m_dailyWorked
).arg(m_dailyPercentage
, 0, 'f', 2).arg(m_weeklyWorked
).arg(m_weeklyPercentage
, 0, 'f', 2).arg(m_monthlyWorked
).arg(m_monthlyPercentage
, 0, 'f', 2);
75 m_text
->setHtml(m_tooltipText
);
76 m_redrawCachedPixmapB
=true;
80 void SakWidget::timerEvent(QTimerEvent
* e
)
83 if (e
->timerId() == m_flipTimer
) {
84 if (m_showingDetails
== true) {
86 t
.translate( m_animItr
* (m_rect
.width() / 2 / ITERATIONS
), 0);
87 t
.rotate( - m_animItr
* 90.0 / ITERATIONS
, Qt::YAxis
);
88 double newScale
= m_scale
+ m_animItr
* (qMax(1.0, m_scale
) - m_scale
) / 2 / ITERATIONS
;
89 t
.scale( newScale
, newScale
);
91 setPos( m_position
+ m_animItr
* ( scene()->sceneRect().center() - m_rect
.center() - m_position
) / 2/ ITERATIONS
);
92 if (m_animItr
== ITERATIONS
+1) {
94 } else if (m_animItr
>= 2*ITERATIONS
) {
95 killTimer(m_flipTimer
);
101 t
.translate( m_rect
.width() - m_animItr
* (m_rect
.width() / 2 / ITERATIONS
), 0);
102 t
.rotate( - 180 - m_animItr
* 90.0 / ITERATIONS
, Qt::YAxis
);
103 double newScale
= qMax(1.0, m_scale
) + m_animItr
* (m_scale
- qMax(1.0, m_scale
)) / 2 / ITERATIONS
;
104 t
.scale(newScale
, newScale
);
106 setPos( scene()->sceneRect().center() - m_rect
.center() + m_animItr
* ( m_position
- scene()->sceneRect().center() + m_rect
.center()) / 2/ ITERATIONS
);
107 if (m_animItr
== ITERATIONS
+1) {
109 } else if (m_animItr
>= 2*ITERATIONS
) {
110 killTimer(m_flipTimer
);
121 void SakWidget::showDetails(bool show
)
123 if (show
== m_showingDetails
) return;
126 setZValue( ++m_maxzvalue
);
128 m_showingDetails
= show
;
130 m_flipTimer
= startTimer(25);
134 void SakWidget::setGeometry(const QRect
& geom
) {
135 prepareGeometryChange ();
137 setPos(geom
.topLeft());
138 m_position
= geom
.topLeft();
139 m_scale
= geom
.width() / m_rect
.width();
141 QTransform t
=transform();
142 t
.setMatrix(m_scale
, t
.m12(), t
.m13(), t
.m21(), m_scale
, t
.m23(), t
.m31(), t
.m32(), t
.m33());
145 m_redrawCachedPixmap
= m_redrawCachedPixmapB
= true;
149 void SakWidget::keyPressEvent ( QKeyEvent
* event
) {
150 if (event
->key() == Qt::Key_Return
&& (event
->modifiers() & Qt::ControlModifier
) ) {
152 emit
clicked(m_task
.title
);
153 } else if (event
->key() == Qt::Key_Return
&& (event
->modifiers() & Qt::ShiftModifier
) ) {
156 } else if (event
->key() == Qt::Key_Space
) {
158 showDetails(!m_showingDetails
);
163 void SakWidget::mousePressEvent(QGraphicsSceneMouseEvent
* e
)
165 if (e
->button() != Qt::LeftButton
)
167 m_lastPoint
= e
->screenPos();
170 void SakWidget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent
* e
)
172 if (e
->button() != Qt::LeftButton
)
174 emit
clicked(m_task
.title
);
177 void SakWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent
* e
)
179 if (e
->button() != Qt::LeftButton
)
182 showDetails(!m_showingDetails
);
183 else if (!m_showingDetails
)
189 void SakWidget::mouseMoveEvent(QGraphicsSceneMouseEvent
* e
)
191 if (e
->button() != Qt::LeftButton
)
193 if (e
->buttons() != Qt::NoButton
&& (m_lastPoint
- e
->screenPos()).manhattanLength() > 4) {
195 if (e
->buttons() & Qt::LeftButton
) {
196 setPos(pos() + (e
->screenPos() - m_lastPoint
));
197 m_lastPoint
= e
->screenPos();
202 void SakWidget::drawBasicShape(QPixmap
& basicShape
)
204 basicShape
.fill(QColor(0,0,0,0));
205 QPainter
p(&basicShape
);
208 pen
.setColor(m_task
.bgColor
.darker(130));
210 p
.setBrush(m_task
.bgColor
);
211 p
.drawRoundRect(m_rect
.adjusted(m_border
,m_border
, -m_border
,-m_border
), 25, 25 );
213 pen
.setColor(m_task
.fgColor
);
217 void SakWidget::paint ( QPainter
* painter
, const QStyleOptionGraphicsItem
* option
, QWidget
*)
225 QRectF exposed
= option
->exposedRect
.adjusted(-1,-1,1,1);
226 exposed
&= QRectF(0,0, m_cachedPixmap
.width(), m_cachedPixmap
.height());
228 painter
->drawPixmap(exposed
, m_cachedPixmapB
, exposed
);
230 painter
->drawPixmap(exposed
, m_cachedPixmap
, exposed
);
235 void SakWidget::redrawPixmaps() {
236 if (m_redrawCachedPixmap
) {
237 drawBasicShape(m_cachedPixmap
);
238 QPainter
p(&m_cachedPixmap
);
239 p
.setRenderHints(QPainter::Antialiasing
, true);
241 pen
.setColor(m_task
.fgColor
);
243 if (!m_ic
.isNull()) {
244 p
.drawPixmap((int)(m_rect
.width() - m_ic
.width())/2, (int)(m_rect
.height() - m_ic
.height())/2, m_ic
);
245 } else if ( m_text
&& !m_sideB
) {
247 QFontMetricsF
metrix(f
);
248 f
.setPixelSize( (int)m_rect
.width() / m_task
.title
.count() );
250 p
.drawText(m_rect
, Qt::AlignCenter
, m_task
.title
);
254 QPointF
dateInfoTopLeft(m_rect
.width() - 100, m_rect
.height() - 100);
255 if (m_task
.dueDate
.isValid()) {
257 int days
= QDate::currentDate().daysTo(m_task
.dueDate
);
262 QConicalGradient
g(dateInfoTopLeft
+ QPointF(32,32), 90);
263 g
.setColorAt(0.0, Qt::red
);
264 g
.setColorAt(1.0, Qt::green
);
266 days
= qMin(30, days
);
270 p
.drawPie(QRectF(dateInfoTopLeft
, QSizeF(64, 64)), 90*16, -(360 - days
)*16);
271 p
.drawPixmap(dateInfoTopLeft
, QPixmap(":/images/hourglass.png"));
273 if (m_task
.estimatedHours
) {
275 QLinearGradient
g(QPointF(dateInfoTopLeft
.x(),0), QPointF(dateInfoTopLeft
.x()+64,0));
276 g
.setColorAt(1.0, Qt::red
);
277 g
.setColorAt(0.0, Qt::green
);
278 p
.setBrush(Qt::gray
);
279 QRectF
infoRect(dateInfoTopLeft
+ QPointF(0,66), QSizeF(64, 8));
280 p
.drawRoundedRect(infoRect
,3,3);
282 double percentage
= ((double)m_task
.totHours
/ (double)m_task
.estimatedHours
) * 64.0;
283 p
.drawRoundedRect(infoRect
.adjusted(0,0,percentage
-64,0), 3,3);
286 m_redrawCachedPixmap
= false;
289 if (m_redrawCachedPixmapB
) {
290 drawBasicShape(m_cachedPixmapB
);
291 QPainter
p(&m_cachedPixmapB
);
292 p
.setRenderHints(QPainter::Antialiasing
, true);
294 pen
.setColor(m_task
.fgColor
);
296 if (!m_ic
.isNull()) {
297 p
.drawPixmap(QPoint(25, (int)m_rect
.height() - 120), m_ic
.scaled(100, 100, Qt::KeepAspectRatio
));
300 t
.translate( m_rect
.width() -10 , 10);
301 t
.rotate( -180 , Qt::YAxis
);
303 m_text
->drawContents(&p
);
304 m_redrawCachedPixmapB
= false;