]> git.sesse.net Git - kdenlive/blob - src/customtrackview.cpp
More work on timeline widget
[kdenlive] / src / customtrackview.cpp
1 /***************************************************************************
2  *   Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
18  ***************************************************************************/
19
20 #include <QMouseEvent>
21 #include <QStylePainter>
22 #include <QGraphicsItem>
23 #include <QDomDocument>
24 #include <QScrollBar>
25
26 #include <KDebug>
27 #include <KLocale>
28 #include <KUrl>
29
30 #include "customtrackview.h"
31 #include "clipitem.h"
32 #include "definitions.h"
33 #include "moveclipcommand.h"
34 #include "resizeclipcommand.h"
35 #include "addtimelineclipcommand.h"
36
37 CustomTrackView::CustomTrackView(KUndoStack *commandStack, QGraphicsScene * projectscene, QWidget *parent)
38     : QGraphicsView(projectscene, parent), m_commandStack(commandStack), m_tracksCount(0), m_cursorPos(0), m_dropItem(NULL), m_cursorLine(NULL), m_operationMode(NONE), m_startPos(QPointF()), m_dragItem(NULL), m_visualTip(NULL), m_moveOpMode(NONE), m_animation(NULL), m_projectDuration(0), m_scale(1.0), m_clickPoint(0)
39 {
40   setMouseTracking(true);
41   setAcceptDrops(true);
42   m_animationTimer = new QTimeLine(800);
43   m_animationTimer->setFrameRange(0, 5);
44   m_animationTimer->setUpdateInterval(100);
45   m_animationTimer->setLoopCount(0);
46   m_tipColor = QColor(230, 50, 0, 150);
47   setContentsMargins(0, 0, 0, 0);
48   if (projectscene) {
49     m_cursorLine = projectscene->addLine(0, 0, 0, 50);
50     m_cursorLine->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIgnoresTransformations);
51     m_cursorLine->setZValue(1000);
52   }
53 }
54
55 void CustomTrackView::initView()
56 {
57
58 }
59
60 // virtual
61 void CustomTrackView::resizeEvent ( QResizeEvent * event )
62 {
63   QGraphicsView::resizeEvent(event);
64 }
65
66 // virtual
67 void CustomTrackView::wheelEvent ( QWheelEvent * e ) 
68 {
69   if (e->modifiers() == Qt::ControlModifier) {
70     if (e->delta() > 0) emit zoomIn();
71     else emit zoomOut();
72   }
73   else {
74     if (e->delta() > 0) horizontalScrollBar()->setValue (horizontalScrollBar()->value() + horizontalScrollBar()->singleStep ());
75     else  horizontalScrollBar()->setValue (horizontalScrollBar()->value() - horizontalScrollBar()->singleStep ());
76   }
77 }
78
79
80 // virtual 
81 void CustomTrackView::mouseMoveEvent ( QMouseEvent * event )
82 {
83   int pos = event->x();
84   /*if (event->modifiers() == Qt::ControlModifier)
85     setDragMode(QGraphicsView::ScrollHandDrag);
86   else if (event->modifiers() == Qt::ShiftModifier) 
87     setDragMode(QGraphicsView::RubberBandDrag);
88   else*/ {
89
90       if (m_dragItem) { //event->button() == Qt::LeftButton) {
91         // a button was pressed, delete visual tips
92
93 if (m_operationMode == MOVE) {
94       int moveX = mapToScene(event->pos()).x();
95       //kDebug()<<"///////  MOVE CLIP, EVENT Y: "<<event->scenePos().y()<<", SCENE HEIGHT: "<<scene()->sceneRect().height();
96       int moveTrack = (int)  mapToScene(event->pos()).y() / 50;
97       int currentTrack = m_dragItem->track();
98
99       if (moveTrack > m_tracksCount - 1) moveTrack = m_tracksCount - 1;
100       else if (moveTrack < 0) moveTrack = 0;
101
102       int offset = moveTrack - currentTrack;
103       if (offset != 0) offset = 50 * offset;
104       m_dragItem->moveTo(moveX - m_clickPoint, m_scale, offset, moveTrack);
105   }
106
107         if (m_animation) delete m_animation;
108         m_animation = NULL;
109         if (m_visualTip) delete m_visualTip;
110         m_visualTip = NULL;
111         QGraphicsView::mouseMoveEvent(event);
112         return;
113       }
114
115     QList<QGraphicsItem *> itemList = items( event->pos());
116     int i = 0;
117     QGraphicsItem *item = NULL;
118     for (int i = 0; i < itemList.count(); i++) {
119       if (itemList.at(i)->type() == 70000) {
120         item = itemList.at(i);
121         break;
122       }
123     }
124     if (item) {
125       ClipItem *clip = (ClipItem*) item;
126       double size = mapToScene(QPoint(8, 0)).x();
127       OPERATIONTYPE opMode = clip->operationMode(mapToScene(event->pos()));
128       if (opMode == m_moveOpMode) {
129         QGraphicsView::mouseMoveEvent(event);
130         return;
131       }
132       else {
133       if (m_visualTip) {
134         if (m_animation) delete m_animation;
135         m_animation = NULL;
136         delete m_visualTip;
137         m_visualTip = NULL;
138       }
139       }
140       m_moveOpMode = opMode;
141       if (opMode == MOVE) {
142         setCursor(Qt::OpenHandCursor);
143       }
144       else if (opMode == RESIZESTART) {
145         kDebug()<<"********  RESIZE CLIP START; WIDTH: "<<size;
146         if (m_visualTip == NULL) {
147           m_visualTip = new QGraphicsRectItem(clip->rect().x(), clip->rect().y(), size, clip->rect().height());
148           ((QGraphicsRectItem*) m_visualTip)->setBrush(m_tipColor);
149           ((QGraphicsRectItem*) m_visualTip)->setPen(QPen(Qt::transparent));
150           m_visualTip->setZValue (100);
151           m_animation = new QGraphicsItemAnimation;
152           m_animation->setItem(m_visualTip);
153           m_animation->setTimeLine(m_animationTimer);
154           m_visualTip->setPos(0, 0);
155           double scale = 2.0;
156           m_animation->setScaleAt(.5, scale, 1);
157           m_animation->setPosAt(.5, QPointF(clip->rect().x() - clip->rect().x() * scale, 0));
158           scale = 1.0;
159           m_animation->setScaleAt(1, scale, 1);
160           m_animation->setPosAt(1, QPointF(clip->rect().x() - clip->rect().x() * scale, 0));
161           scene()->addItem(m_visualTip);
162           m_animationTimer->start();
163         }
164         setCursor(Qt::SizeHorCursor);
165       }
166       else if (opMode == RESIZEEND) {
167         if (m_visualTip == NULL) {
168           m_visualTip = new QGraphicsRectItem(clip->rect().x() + clip->rect().width() - size, clip->rect().y(), size, clip->rect().height());
169           ((QGraphicsRectItem*) m_visualTip)->setBrush(m_tipColor);
170           ((QGraphicsRectItem*) m_visualTip)->setPen(QPen(Qt::transparent));
171           m_visualTip->setZValue (100);
172           m_animation = new QGraphicsItemAnimation;
173           m_animation->setItem(m_visualTip);
174           m_animation->setTimeLine(m_animationTimer);
175           m_visualTip->setPos(0, 0);
176           double scale = 2.0;
177           m_animation->setScaleAt(.5, scale, 1);
178           m_animation->setPosAt(.5, QPointF(clip->rect().x() - clip->rect().x() * scale - clip->rect().width(), 0));
179           scale = 1.0;
180           m_animation->setScaleAt(1, scale, 1);
181           m_animation->setPosAt(1, QPointF(clip->rect().x() - clip->rect().x() * scale, 0));
182           scene()->addItem(m_visualTip);
183           m_animationTimer->start();
184         }
185         setCursor(Qt::SizeHorCursor);
186       }
187       else if (opMode == FADEIN) {
188         if (m_visualTip == NULL) {
189           m_visualTip = new QGraphicsEllipseItem(clip->rect().x() - size, clip->rect().y() - 8, size * 2, 16);
190           ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor);
191           ((QGraphicsEllipseItem*) m_visualTip)->setPen(QPen(Qt::transparent));
192           m_visualTip->setZValue (100);
193           m_animation = new QGraphicsItemAnimation;
194           m_animation->setItem(m_visualTip);
195           m_animation->setTimeLine(m_animationTimer);
196           m_visualTip->setPos(0, 0);
197           double scale = 2.0;
198           m_animation->setScaleAt(.5, scale, scale);
199           m_animation->setPosAt(.5, QPointF(clip->rect().x() - clip->rect().x() * scale, clip->rect().y() - clip->rect().y() * scale));
200           scale = 1.0;
201           m_animation->setScaleAt(1, scale, scale);
202           m_animation->setPosAt(1, QPointF(clip->rect().x() - clip->rect().x() * scale, clip->rect().y() - clip->rect().y() * scale));
203           scene()->addItem(m_visualTip);
204           m_animationTimer->start();
205         }
206         setCursor(Qt::PointingHandCursor);
207       }
208       else if (opMode == FADEOUT) {
209         if (m_visualTip == NULL) {
210           m_visualTip = new QGraphicsEllipseItem(clip->rect().x() + clip->rect().width() - size, clip->rect().y() - 8, size*2, 16);
211           ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor);
212           ((QGraphicsEllipseItem*) m_visualTip)->setPen(QPen(Qt::transparent));
213           m_visualTip->setZValue (100);
214           m_animation = new QGraphicsItemAnimation;
215           m_animation->setItem(m_visualTip);
216           m_animation->setTimeLine(m_animationTimer);
217           m_visualTip->setPos(0, 0);
218           double scale = 2.0;
219           m_animation->setScaleAt(.5, scale, scale);      
220           m_animation->setPosAt(.5, QPointF(clip->rect().x() - clip->rect().x() * scale - clip->rect().width(), clip->rect().y() - clip->rect().y() * scale));
221           scale = 1.0;
222           m_animation->setScaleAt(1, scale, scale);
223           m_animation->setPosAt(1, QPointF(clip->rect().x() - clip->rect().x() * scale, clip->rect().y() - clip->rect().y() * scale));
224           scene()->addItem(m_visualTip);
225           m_animationTimer->start();
226         }
227         setCursor(Qt::PointingHandCursor);
228       }
229     }
230     else {
231       m_moveOpMode = NONE;
232       if (m_visualTip) {
233         if (m_animation) delete m_animation;
234         m_animation = NULL;
235         delete m_visualTip;
236         m_visualTip = NULL;
237       }
238       setCursor(Qt::ArrowCursor);
239     }
240   }
241   QGraphicsView::mouseMoveEvent(event);
242 }
243
244 // virtual 
245 void CustomTrackView::mousePressEvent ( QMouseEvent * event )
246 {
247   int pos = event->x();
248   if (event->modifiers() == Qt::ControlModifier) 
249     setDragMode(QGraphicsView::ScrollHandDrag);
250   else if (event->modifiers() == Qt::ShiftModifier) 
251     setDragMode(QGraphicsView::RubberBandDrag);
252   else {
253     QGraphicsItem * item = itemAt(event->pos());
254     if (item && item->type() != 70000) item = item->parentItem();
255     if (item && item->type() == 70000) {
256       m_dragItem = (ClipItem *) item;
257       m_clickPoint = mapToScene(event->pos()).x() - m_dragItem->startPos() * m_scale;
258       m_operationMode = m_dragItem->operationMode(item->mapFromScene(mapToScene(event->pos())));
259       if (m_operationMode == MOVE || m_operationMode == RESIZESTART) m_startPos = QPointF(m_dragItem->startPos(), m_dragItem->track());
260       else if (m_operationMode == RESIZEEND) m_startPos = QPointF(m_dragItem->rect().x() + m_dragItem->rect().width(), m_dragItem->rect().y());
261
262      kDebug()<<"//////// ITEM CLICKED: "<<m_startPos;
263       /*while (item->parentItem()) 
264         item = item->parentItem();
265
266         int cursorPos = event->x();
267         QRectF itemRect = item->sceneBoundingRect();
268         int itemStart = mapFromScene(itemRect.x(), 0).x();
269         int itemEnd = mapFromScene(itemRect.x() + itemRect.width(), 0).x();
270         if (abs(itemStart - cursorPos) < 6)
271           ((ClipItem *) item )->setResizeMode(1);
272         else if (abs(itemEnd - cursorPos) < 6)
273           ((ClipItem *) item )->setResizeMode(2);
274     */}
275     else {
276       kDebug()<<"//////// NO ITEM FOUND ON CLICK";
277       m_dragItem = NULL;
278       setCursor(Qt::ArrowCursor);
279       setCursorPos((int) mapToScene(event->x(), 0).x());
280       emit cursorMoved(cursorPos());
281     }
282   }
283   //kDebug()<<pos;
284   QGraphicsView::mousePressEvent(event);
285 }
286
287 void CustomTrackView::dragEnterEvent ( QDragEnterEvent * event )
288 {
289   if (event->mimeData()->hasText()) {
290     QString clip = event->mimeData()->text();
291     addItem(clip, event->pos());
292     event->acceptProposedAction();
293   }
294 }
295
296
297 void CustomTrackView::addItem(QString producer, QPoint pos)
298 {
299   QDomDocument doc;
300   doc.setContent(producer);
301   QDomElement elem = doc.documentElement();
302   int in = elem.attribute("in", 0).toInt();
303   int out = elem.attribute("duration", 0).toInt();
304   if (out == 0) out = elem.attribute("out", 0).toInt() - in;
305   kDebug()<<"ADDING CLIP: "<<producer<<", OUT: "<<out<<", POS: "<<mapToScene(pos);
306   int trackTop = ((int) mapToScene(pos).y()/50) * 50 + 1;
307   m_dropItem = new ClipItem(elem, ((int) mapToScene(pos).y()/50), in, QRectF(mapToScene(pos).x() * m_scale, trackTop, out * m_scale, 49));
308   scene()->addItem(m_dropItem);
309 }
310
311
312 void CustomTrackView::dragMoveEvent(QDragMoveEvent * event) {
313   event->setDropAction(Qt::IgnoreAction);
314   if (m_dropItem) {
315     int track = (int) mapToScene(event->pos()).y()/50; //) * (m_scale * 50) + m_scale;
316      kDebug()<<"+++++++++++++   DRAG MOVE, : "<<mapToScene(event->pos()).x()<<", SCAL: "<<m_scale;
317     m_dropItem->moveTo(mapToScene(event->pos()).x(), m_scale, (track - m_dropItem->track()) * 50, track);
318   }
319        //if (item) {
320   event->setDropAction(Qt::MoveAction);
321   if (event->mimeData()->hasText()) {
322     event->acceptProposedAction();
323   }
324         //}
325 }
326
327 void CustomTrackView::dragLeaveEvent ( QDragLeaveEvent * event ) {
328   if (m_dropItem) {
329     delete m_dropItem;
330     m_dropItem = NULL;
331   }
332 }
333
334 void CustomTrackView::dropEvent ( QDropEvent * event ) {
335   if (m_dropItem) {
336     AddTimelineClipCommand *command = new AddTimelineClipCommand(this, m_dropItem->xml(), m_dropItem->track(), m_dropItem->startPos(), m_dropItem->rect(), m_dropItem->duration(), false);
337     m_commandStack->push(command);
338   }
339   m_dropItem = NULL;
340 }
341
342
343 QStringList CustomTrackView::mimeTypes () const
344 {
345     QStringList qstrList;
346     // list of accepted mime types for drop
347     qstrList.append("text/plain");
348     return qstrList;
349 }
350
351 Qt::DropActions CustomTrackView::supportedDropActions () const
352 {
353     // returns what actions are supported when dropping
354     return Qt::MoveAction;
355 }
356
357 void CustomTrackView::setDuration(int duration)
358 {
359   kDebug()<<"/////////////  PRO DUR: "<<duration<<", height: "<<50 * m_tracksCount;
360   m_projectDuration = duration;
361   scene()->setSceneRect(0, 0, m_projectDuration + 500, scene()->sceneRect().height()); //50 * m_tracksCount);
362 }
363
364
365 void CustomTrackView::addTrack ()
366 {
367   m_tracksCount++;
368   m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), 50 * m_tracksCount);
369   //setSceneRect(0, 0, sceneRect().width(), 50 * m_tracksCount);
370   //verticalScrollBar()->setMaximum(50 * m_tracksCount); 
371   //setFixedHeight(50 * m_tracksCount);
372 }
373
374 void CustomTrackView::removeTrack ()
375 {
376   m_tracksCount--;
377   m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), 50 * m_tracksCount);
378 }
379
380 void CustomTrackView::setCursorPos(int pos)
381 {
382   m_cursorPos = pos;
383   m_cursorLine->setPos(pos, 0);
384 }
385
386 int CustomTrackView::cursorPos()
387 {
388   return m_cursorPos;
389 }
390
391 void CustomTrackView::mouseReleaseEvent ( QMouseEvent * event )
392 {
393   QGraphicsView::mouseReleaseEvent(event);
394   setDragMode(QGraphicsView::NoDrag);
395   if (m_dragItem == NULL) return;
396   //kDebug()<<"/// MOVING CLIP: "<<m_startPos<<", END: "<<QPoint(m_dragItem->rect().x(),m_dragItem->rect().y());
397   if (m_operationMode == MOVE) {
398     // move clip
399     MoveClipCommand *command = new MoveClipCommand(this, m_startPos, QPointF(m_dragItem->startPos(), m_dragItem->track()), false);
400     m_commandStack->push(command);
401   }
402   else if (m_operationMode == RESIZESTART) {
403     // resize start
404     ResizeClipCommand *command = new ResizeClipCommand(this, m_startPos, QPointF(m_dragItem->rect().x(), m_dragItem->rect().y()), true, false);
405     m_commandStack->push(command);
406   }
407   else if (m_operationMode == RESIZEEND) {
408     // resize end
409     ResizeClipCommand *command = new ResizeClipCommand(this, m_startPos, QPointF(m_dragItem->rect().x() + m_dragItem->rect().width(), m_dragItem->rect().y()), false, false);
410     m_commandStack->push(command);
411   }
412   m_dragItem = NULL; 
413 }
414
415 void CustomTrackView::deleteClip ( const QRectF &rect )
416 {
417   ClipItem *item = (ClipItem *) scene()->itemAt(rect.x() + 1, rect.y() + 1);
418   if (!item) {
419     kDebug()<<"----------------  ERROR, CANNOT find clip to move at: "<<rect.x();
420     return;
421   }
422   delete item;
423 }
424
425 void CustomTrackView::addClip ( QDomElement xml, int track, int startpos, const QRectF &rect, int duration )
426 {
427   QRect r(startpos * m_scale, 50 * track, duration * m_scale, 49); 
428   ClipItem *item = new ClipItem(xml, track, startpos, r, duration);
429   scene()->addItem(item);
430 }
431
432 void CustomTrackView::moveClip ( const QPointF &startPos, const QPointF &endPos )
433 {
434   ClipItem *item = (ClipItem *) scene()->itemAt((startPos.x() + 1) * m_scale, startPos.y() * 50 + 25);
435   if (!item) {
436     kDebug()<<"----------------  ERROR, CANNOT find clip to move at: "<<startPos.x() * m_scale * FRAME_SIZE + 1<<", "<<startPos.y() * 50 + 25;
437     return;
438   }
439   kDebug()<<"----------------  Move CLIP FROM: "<<startPos.x()<<", END:"<<endPos.x();
440   //item->setRect(QRectF(endPos.x() * m_scale, endPos.y() * 50, item->rect().width(), item->rect().height()));
441   item->moveTo(endPos.x() * m_scale, m_scale, (endPos.y() - startPos.y()) * 50, endPos.y());
442   /*QList <QGraphicsItem *> childrenList = item->children();
443   for (int i = 0; i < childrenList.size(); ++i) {
444     childrenList.at(i)->moveBy((endPos.x() - startPos.x()) * m_scale , (endPos.y() - startPos.y()) * 50);
445   }*/
446 }
447
448 void CustomTrackView::resizeClip ( const QPointF &startPos, const QPointF &endPos, bool resizeClipStart )
449 {
450   int offset;
451   if (resizeClipStart) offset = 1;
452   else offset = -1;
453   ClipItem *item = (ClipItem *) scene()->itemAt(startPos.x() + offset, startPos.y() + 1);
454   if (!item) {
455     kDebug()<<"----------------  ERROR, CANNOT find clip to resize at: "<<startPos;
456     return;
457   }
458   qreal diff = endPos.x() - startPos.x();
459   if (resizeClipStart) {
460     item->setRect(QRectF(endPos.x(), endPos.y(), item->rect().width() - diff, item->rect().height()));
461     QList <QGraphicsItem *> childrenList = item->QGraphicsItem::children();
462     for (int i = 0; i < childrenList.size(); ++i) {
463       childrenList.at(i)->moveBy(diff / 2 , endPos.y() - startPos.y());
464     }
465   }
466   else {
467     //kdDebug()<<"///////  RESIZE CLIP END: "<<item->rect().x()<<", "<<item->rect().width()<<", "<<startPos<<", "<<endPos;
468     item->setRect(QRectF(item->rect().x(), item->rect().y(), endPos.x() - item->rect().x(), item->rect().height()));
469     QList <QGraphicsItem *> childrenList = item->QGraphicsItem::children();
470     for (int i = 0; i < childrenList.size(); ++i) {
471       childrenList.at(i)->moveBy(-diff/2, endPos.y() - startPos.y());
472     }
473   }
474 }
475
476
477 void CustomTrackView::setScale(double scaleFactor)
478 {
479   //scale(scaleFactor, scaleFactor);
480   m_scale = scaleFactor;
481   kDebug()<<" HHHHHHHH  SCALING: "<<m_scale;
482   QList<QGraphicsItem *> itemList = items();
483
484   for (int i = 0; i < itemList.count(); i++) {
485       if (itemList.at(i)->type() == 70000) {
486         ClipItem *clip = (ClipItem *)itemList.at(i);
487         clip->setRect(clip->startPos() * m_scale, clip->rect().y(), clip->duration() * m_scale, clip->rect().height());
488       }
489       else if (itemList.at(i)->type() == 70001) {
490         LabelItem *label = (LabelItem *)itemList.at(i);
491         QGraphicsItem *parent = label->parentItem();
492         QRectF r = label->boundingRect();
493         QRectF p = parent->boundingRect();
494         label->setPos(p.x() + p.width() / 2 - r.width() / 2, p.y() + p.height() / 2 - r.height() / 2);
495         //label->setRect(clip->startPos() * m_scale, clip->rect().y(), clip->duration() * m_scale, clip->rect().height());
496       }
497     }
498 }
499
500 void CustomTrackView::drawBackground ( QPainter * painter, const QRectF & rect )  
501 {
502   QColor base = palette().button().color();
503   painter->setPen(base);
504   painter->setClipRect(rect);
505   painter->drawLine(0, 0, rect.width(), 0);
506     for (uint i = 0; i < m_tracksCount;i++)
507     {
508     painter->drawLine(0, 50 * (i+1), width(), 50 * (i+1));
509       //painter->drawText(QRectF(10, 50 * i, 100, 50 * i + 49), Qt::AlignLeft, i18n(" Track ") + QString::number(i));
510     }
511   int lowerLimit = 50 * m_tracksCount;
512   if (height() > lowerLimit)
513   painter->fillRect(QRectF(0, lowerLimit, rect.width(), height() - lowerLimit), QBrush(base));
514 }
515 /*
516 void CustomTrackView::drawForeground ( QPainter * painter, const QRectF & rect )  
517 {
518   //kDebug()<<"/////  DRAWING FB: "<<rect.x()<<", width: "<<rect.width();
519   painter->fillRect(rect, QColor(50, rand() % 250,50,100));
520   painter->drawLine(m_cursorPos, rect.y(), m_cursorPos, rect.y() + rect.height());
521 }
522 */
523 #include "customtrackview.moc"