fix start/stop/pause
[Sak.git] / timeline.cpp
blob5bfff58702ddf1a7c0497918e4cd83d13eef93d5
1 #include "timeline.h"
3 #include "task.h"
5 static const int TLH = 30;
6 static const int TLH2 = 15;
8 HitItem::HitItem(const Task* t, const QDateTime& timestamp, int duration, const QString& subtask, QGraphicsItem* parent)
9 : QGraphicsItem(parent)
10 , m_task(t)
11 , m_d(duration)
12 , m_newD(duration)
13 , m_t(timestamp)
14 , m_newT(timestamp)
15 , m_subtask(subtask)
17 reshape();
19 QColor c(m_task->fgColor); c.setAlpha(240);
20 m_pen.setColor(c);
21 QColor d(m_task->bgColor); d.setAlpha(180);
22 m_bgbrush.setStyle(Qt::SolidPattern);
23 m_bgbrush.setColor(d);
24 setVisible(true);
25 setZValue(timestamp.toTime_t());
26 setFlag(QGraphicsItem::ItemIsSelectable, true);
27 setFlag(QGraphicsItem::ItemIsFocusable, true);
28 setAcceptsHoverEvents(true);
29 setToolTip( timestamp.toString(DATETIMEFORMAT) + "\n" + subtask + " @ " + t->title + "\n" + QString("%1").arg(duration) + " minutes long");
32 void HitItem::reshape()
34 prepareGeometryChange();
36 setPos(m_newT.toTime_t() / 60.0, 0.0);
37 m_rect = QRectF(-(int)m_newD / 2.0, -TLH2, m_newD, TLH ).adjusted(-2,-2,2,2);
39 m_shape = QPainterPath();
40 float halfd = m_newD/2.0;
41 m_shape.moveTo(-halfd, 0);
42 m_shape.lineTo(-halfd+1, -TLH2);
43 m_shape.lineTo(halfd-1, -TLH2);
44 m_shape.lineTo(halfd, 0);
45 m_shape.lineTo(halfd-1, TLH2);
46 m_shape.lineTo(-halfd+1, TLH2);
47 m_shape.closeSubpath();
50 void HitItem::commitChanges() {
51 m_t = m_newT;
52 m_d = m_newD;
53 reshape();
56 void HitItem::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
58 painter->save();
59 if (isSelected()) m_pen.setWidth(3);
60 else m_pen.setWidth(1);
61 painter->setPen(m_pen);
62 painter->setBrush(m_bgbrush);
63 painter->drawPath(m_shape);
64 painter->restore();
67 void HitItem::mousePressEvent(QGraphicsSceneMouseEvent * event)
69 if (cursor().shape() != Qt::SizeHorCursor) {
70 setCursor(QCursor(Qt::SizeAllCursor));
73 if (qApp->keyboardModifiers() & Qt::ControlModifier && isSelected()) {
74 m_lastPos = event->pos();
75 m_moving = true;
76 } else {
77 m_moving = false;
80 QGraphicsItem::mousePressEvent(event);
83 void HitItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
85 if (cursor().shape() == Qt::SizeAllCursor) {
86 setCursor(m_savedCursor);
90 if (m_moving) {
91 double diff = m_lastPos.x() - event->pos().x();
92 if (m_leftExtending) {
93 m_newD = qMax(2.0, m_newD + diff);
94 m_newT = m_newT.addSecs(-diff * 30);
95 } else if (m_rightExtending) {
96 m_newD = qMax(2.0, m_newD - diff);
97 m_newT = m_newT.addSecs(-diff * 30);
98 } else {
99 m_newT = m_newT.addSecs(-diff*60);
101 reshape();
102 m_moving=false;
103 emit changed();
105 QGraphicsItem::mouseReleaseEvent(event);
108 void HitItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
112 void HitItem::hoverEnterEvent ( QGraphicsSceneHoverEvent * event )
114 m_savedCursor = cursor();
117 void HitItem::hoverLeaveEvent ( QGraphicsSceneHoverEvent * event )
119 setCursor(m_savedCursor);
123 void HitItem::hoverMoveEvent ( QGraphicsSceneHoverEvent * event )
125 if (isSelected() && event->lastScreenPos().x() != event->screenPos().x()) {
126 double dsx = event->scenePos().x() - event->lastScenePos().x();
127 double dSx = event->screenPos().x() - event->lastScreenPos().x();
128 double scale = sqrt((dSx*dSx) / (dsx*dsx));
130 double one = qMin(1.0, 10.0 / scale);
131 if (event->pos().x() <= m_rect.left()+one) {
132 m_leftExtending=true;
133 m_rightExtending=false;
134 setCursor(QCursor(Qt::SizeHorCursor));
135 } else if (event->pos().x() >= m_rect.right()-one ) {
136 m_leftExtending=false;
137 m_rightExtending=true;
138 setCursor(QCursor(Qt::SizeHorCursor));
139 } else {
140 setCursor(m_savedCursor);
141 m_leftExtending = m_rightExtending = false;
147 Timeline::Timeline(QWidget* parent) : QGraphicsView(parent)
149 setRenderHint(QPainter::Antialiasing, true);
150 setScene(new QGraphicsScene());
151 scene()->setBackgroundBrush(Qt::gray);
152 setFixedHeight(TLH+10);
153 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
154 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
155 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
156 setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
157 connect(scene(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
159 setMouseTracking(true);
162 m_cursorLine = 0;
163 m_cursorText = 0;
164 m_bg=0;
168 Timeline::~Timeline()
170 scene()->deleteLater();
174 void Timeline::keyPressEvent(QKeyEvent* e)
176 if (e->key() == Qt::Key_Up && matrix().m11()<20)
177 scale(1.0 + 0.1, 1.0);
178 else if (e->key() == Qt::Key_Down)
179 scale(1.0 - 0.1, 1.0);
182 QGraphicsView::keyPressEvent(e);
186 void Timeline::wheelEvent(QWheelEvent* e)
188 if (matrix().m11()<20 || e->delta() < 0)
189 scale(1.0 + 0.1 * e->delta() / 120, 1.0);
190 QGraphicsView::wheelEvent(e);
193 void Timeline::mousePressEvent(QMouseEvent* e)
195 m_moving=false;
196 if (e->buttons() & Qt::LeftButton) {
197 m_pos = e->globalPos();
199 QGraphicsView::mousePressEvent(e);
202 void Timeline::mouseReleaseEvent(QMouseEvent* e)
204 if (m_moving) {
205 int dx = e->globalPos().x() - m_pos.x();
206 horizontalScrollBar()->setValue(horizontalScrollBar()->value()-dx);
207 m_moving=false;
209 QGraphicsView::mouseReleaseEvent(e);
212 void Timeline::mouseMoveEvent(QMouseEvent* e)
215 if (!m_cursorText) {
216 m_cursorLine = new QGraphicsLineItem;
217 m_cursorText = new QGraphicsTextItem(m_cursorLine);
218 QPen redPen;
219 redPen.setColor(Qt::red);
220 redPen.setWidth(2);
221 m_cursorLine->setPen(redPen);
222 m_cursorLine->setLine(0, -TLH2, 0, TLH2);
223 m_cursorLine->setFlag(QGraphicsItem::ItemIgnoresTransformations, true);
224 m_cursorText->setFlag(QGraphicsItem::ItemIgnoresTransformations, true);
226 scene()->addItem(m_cursorLine);
228 m_cursorLine->setVisible(true);
229 m_cursorLine->setZValue(1e21);
231 m_cursorText->setVisible(true);
232 m_cursorText->setZValue(1e21);
233 m_cursorText->setPos(1,-10);
234 m_cursorText->setDefaultTextColor(Qt::red);
236 m_cursorText->setAcceptHoverEvents(false);
237 m_cursorLine->setAcceptHoverEvents(false);
238 m_cursorText->setEnabled(false);
239 m_cursorLine->setEnabled(false);
240 m_cursorLine->setAcceptedMouseButtons(Qt::NoButton);
241 m_cursorText->setAcceptedMouseButtons(Qt::NoButton);
244 double pos = mapToScene(e->pos()).x();
245 m_cursorLine->setPos(QPointF(pos, 0));
246 m_cursorText->setPlainText(QDateTime::fromTime_t(pos*60.0).toString("hh:mm dd/MM/yy"));
248 if ((e->buttons() & Qt::LeftButton) && ! (qApp->keyboardModifiers() & Qt::ControlModifier) )
249 m_moving=true;
250 QGraphicsView::mouseMoveEvent(e);
253 void Timeline::setPeriod(const QDateTime& from, const QDateTime& to)
255 scene()->setSceneRect(from.toTime_t()/60.0, -TLH2, to.toTime_t()/60.0 - from.toTime_t()/60.0, TLH);
257 scene()->removeItem(m_bg);
258 delete m_bg;
259 m_bg = new QGraphicsRectItem(scene()->sceneRect());
260 QLinearGradient g(QPointF(0, -TLH2), QPointF(0, TLH2));
261 g.setColorAt(0.0, QColor(80,80,80));
262 g.setColorAt(0.5, QColor(240,240,240));
263 g.setColorAt(1.0, QColor(80,80,80));
264 m_bg->setBrush(g);
265 m_bg->setPen(Qt::NoPen);
266 m_bg->setZValue(-999999);
267 m_bg->setPos(0,0);
268 m_bg->setVisible(true);
269 m_bg->setAcceptHoverEvents(false);
270 m_bg->setEnabled(false);
271 m_bg->setAcceptedMouseButtons(Qt::NoButton);
273 QGraphicsSimpleTextItem * ti = new QGraphicsSimpleTextItem("text", m_bg, scene());
274 scene()->addItem(m_bg);
278 void Timeline::selectionChanged()
280 if (scene()->selectedItems().count()) {
281 HitItem* tmp = dynamic_cast<HitItem*>(scene()->selectedItems().first());
282 emit hitSelected(tmp);