]> git.sesse.net Git - kdenlive/blob - src/customtrackview.cpp
8655f009ca6d2a14e8bea21f5dc3f0224e5fd411
[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 #include <QApplication>
26 #include <QInputDialog>
27
28 #include <KDebug>
29 #include <KLocale>
30 #include <KUrl>
31 #include <KIcon>
32 #include <KCursor>
33
34 #include "customtrackview.h"
35 #include "docclipbase.h"
36 #include "clipitem.h"
37 #include "definitions.h"
38 #include "moveclipcommand.h"
39 #include "movetransitioncommand.h"
40 #include "resizeclipcommand.h"
41 #include "editguidecommand.h"
42 #include "addtimelineclipcommand.h"
43 #include "addeffectcommand.h"
44 #include "editeffectcommand.h"
45 #include "moveeffectcommand.h"
46 #include "addtransitioncommand.h"
47 #include "edittransitioncommand.h"
48 #include "addmarkercommand.h"
49 #include "razorclipcommand.h"
50 #include "kdenlivesettings.h"
51 #include "transition.h"
52 #include "clipitem.h"
53 #include "customtrackview.h"
54 #include "clipmanager.h"
55 #include "renderer.h"
56 #include "markerdialog.h"
57 #include "mainwindow.h"
58
59
60 //TODO:
61 // disable animation if user asked it in KDE's global settings
62 // http://lists.kde.org/?l=kde-commits&m=120398724717624&w=2
63 // needs something like below (taken from dolphin)
64 // #include <kglobalsettings.h>
65 // const bool animate = KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects;
66 // const int duration = animate ? 1500 : 1;
67
68 CustomTrackView::CustomTrackView(KdenliveDoc *doc, QGraphicsScene * projectscene, QWidget *parent)
69         : QGraphicsView(projectscene, parent), m_cursorPos(0), m_dropItem(NULL), m_cursorLine(NULL), m_operationMode(NONE), m_dragItem(NULL), m_visualTip(NULL), m_moveOpMode(NONE), m_animation(NULL), m_projectDuration(0), m_scale(1.0), m_clickPoint(QPoint()), m_document(doc), m_autoScroll(KdenliveSettings::autoscroll()), m_tracksHeight(KdenliveSettings::trackheight()), m_tool(SELECTTOOL), m_dragGuide(NULL) {
70     if (doc) m_commandStack = doc->commandStack();
71     else m_commandStack == NULL;
72     setMouseTracking(true);
73     setAcceptDrops(true);
74     m_animationTimer = new QTimeLine(800);
75     m_animationTimer->setFrameRange(0, 5);
76     m_animationTimer->setUpdateInterval(100);
77     m_animationTimer->setLoopCount(0);
78     m_tipColor = QColor(0, 192, 0, 200);
79     QColor border = QColor(255, 255, 255, 100);
80     m_tipPen.setColor(border);
81     m_tipPen.setWidth(3);
82     setContentsMargins(0, 0, 0, 0);
83     if (projectscene) {
84         m_cursorLine = projectscene->addLine(0, 0, 0, m_tracksHeight);
85         m_cursorLine->setFlags(QGraphicsItem::ItemIsMovable);
86         m_cursorLine->setZValue(1000);
87     }
88
89     KIcon razorIcon("edit-cut");
90     m_razorCursor = QCursor(razorIcon.pixmap(22, 22));
91 }
92
93 CustomTrackView::~CustomTrackView() {
94     qDeleteAll(m_guides);
95 }
96
97
98 void CustomTrackView::setContextMenu(QMenu *timeline, QMenu *clip, QMenu *transition) {
99     m_timelineContextMenu = timeline;
100     m_timelineContextClipMenu = clip;
101     m_timelineContextTransitionMenu = transition;
102 }
103
104 void CustomTrackView::checkAutoScroll() {
105     m_autoScroll = KdenliveSettings::autoscroll();
106 }
107
108 QList <TrackInfo> CustomTrackView::tracksList() const {
109     return m_tracksList;
110 }
111
112 void CustomTrackView::checkTrackHeight() {
113     if (m_tracksHeight == KdenliveSettings::trackheight()) return;
114     m_tracksHeight = KdenliveSettings::trackheight();
115     emit trackHeightChanged();
116     QList<QGraphicsItem *> itemList = items();
117     ClipItem *item;
118     Transition *transitionitem;
119     for (int i = 0; i < itemList.count(); i++) {
120         if (itemList.at(i)->type() == AVWIDGET) {
121             item = (ClipItem*) itemList.at(i);
122             item->setRect(item->rect().x(), item->track() * m_tracksHeight, item->rect().width(), m_tracksHeight - 1);
123             item->resetThumbs();
124         } else if (itemList.at(i)->type() == TRANSITIONWIDGET) {
125             transitionitem = (Transition*) itemList.at(i);
126             transitionitem->setRect(transitionitem->rect().x(), transitionitem->track() * m_tracksHeight + m_tracksHeight / 2, transitionitem->rect().width(), m_tracksHeight - 1);
127         }
128     }
129     m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_tracksList.count());
130
131     for (int i = 0; i < m_guides.count(); i++) {
132         QLineF l = m_guides.at(i)->line();
133         l.setP2(QPointF(l.x2(), m_tracksHeight * m_tracksList.count()));
134         m_guides.at(i)->setLine(l);
135     }
136
137     setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_tracksList.count());
138     verticalScrollBar()->setMaximum(m_tracksHeight * m_tracksList.count());
139     update();
140 }
141
142 // virtual
143 void CustomTrackView::resizeEvent(QResizeEvent * event) {
144     QGraphicsView::resizeEvent(event);
145 }
146
147 // virtual
148 void CustomTrackView::wheelEvent(QWheelEvent * e) {
149     if (e->modifiers() == Qt::ControlModifier) {
150         if (e->delta() > 0) emit zoomIn();
151         else emit zoomOut();
152     } else {
153         if (e->delta() > 0) horizontalScrollBar()->setValue(horizontalScrollBar()->value() + horizontalScrollBar()->singleStep());
154         else  horizontalScrollBar()->setValue(horizontalScrollBar()->value() - horizontalScrollBar()->singleStep());
155     }
156 }
157
158 int CustomTrackView::getPreviousVideoTrack(int track) {
159     track = m_tracksList.count() - track - 1;
160     track --;
161     for (int i = track; i > -1; i--) {
162         if (m_tracksList.at(i).type == VIDEOTRACK) return i + 1;
163     }
164     return 0;
165 }
166
167 // virtual
168
169 void CustomTrackView::mouseMoveEvent(QMouseEvent * event) {
170     int pos = event->x();
171     emit mousePosition((int)(mapToScene(event->pos()).x() / m_scale));
172     if (event->buttons() & Qt::MidButton) return;
173     {
174         if (m_dragItem && m_tool == SELECTTOOL) { //event->button() == Qt::LeftButton) {
175             // a button was pressed, delete visual tips
176             if (m_operationMode == MOVE && (event->pos() - m_clickEvent).manhattanLength() >= QApplication::startDragDistance()) {
177                 double snappedPos = getSnapPointForPos(mapToScene(event->pos()).x() - m_clickPoint.x());
178                 //kDebug() << "///////  MOVE CLIP, EVENT Y: "<<m_clickPoint.y();//<<event->scenePos().y()<<", SCENE HEIGHT: "<<scene()->sceneRect().height();
179                 int moveTrack = (int)  mapToScene(event->pos() + QPoint(0, (m_dragItem->type() == TRANSITIONWIDGET ? - m_clickPoint.y() : 0))).y() / m_tracksHeight;
180                 int currentTrack = m_dragItem->track();
181
182                 if (moveTrack > 1000)moveTrack = 0;
183                 else if (moveTrack > m_tracksList.count() - 1) moveTrack = m_tracksList.count() - 1;
184                 else if (moveTrack < 0) moveTrack = 0;
185
186                 int offset = moveTrack - currentTrack;
187                 if (offset != 0) offset = m_tracksHeight * offset;
188                 m_dragItem->moveTo((int)(snappedPos / m_scale), m_scale, offset, moveTrack);
189             } else if (m_operationMode == RESIZESTART) {
190                 double snappedPos = getSnapPointForPos(mapToScene(event->pos()).x());
191                 m_dragItem->resizeStart((int)(snappedPos / m_scale), m_scale);
192             } else if (m_operationMode == RESIZEEND) {
193                 double snappedPos = getSnapPointForPos(mapToScene(event->pos()).x());
194                 m_dragItem->resizeEnd((int)(snappedPos / m_scale), m_scale);
195             } else if (m_operationMode == FADEIN) {
196                 int pos = (int)(mapToScene(event->pos()).x() / m_scale);
197                 ((ClipItem*) m_dragItem)->setFadeIn((int)(pos - m_dragItem->startPos().frames(m_document->fps())), m_scale);
198             } else if (m_operationMode == FADEOUT) {
199                 int pos = (int)(mapToScene(event->pos()).x() / m_scale);
200                 ((ClipItem*) m_dragItem)->setFadeOut((int)(m_dragItem->endPos().frames(m_document->fps()) - pos), m_scale);
201             }
202
203             if (m_animation) delete m_animation;
204             m_animation = NULL;
205             if (m_visualTip) delete m_visualTip;
206             m_visualTip = NULL;
207             QGraphicsView::mouseMoveEvent(event);
208             return;
209         } else if (m_operationMode == MOVEGUIDE) {
210             if (m_animation) delete m_animation;
211             m_animation = NULL;
212             if (m_visualTip) delete m_visualTip;
213             m_visualTip = NULL;
214             QGraphicsView::mouseMoveEvent(event);
215             return;
216         }
217
218         if (m_tool == RAZORTOOL) {
219             setCursor(m_razorCursor);
220             QGraphicsView::mouseMoveEvent(event);
221             return;
222         }
223
224         QList<QGraphicsItem *> itemList = items(event->pos());
225         QGraphicsRectItem *item = NULL;
226         OPERATIONTYPE opMode = NONE;
227
228         if (itemList.count() == 1 && itemList.at(0)->type() == GUIDEITEM) {
229             opMode = MOVEGUIDE;
230         } else for (int i = 0; i < itemList.count(); i++) {
231                 if (itemList.at(i)->type() == AVWIDGET || itemList.at(i)->type() == TRANSITIONWIDGET) {
232                     item = (QGraphicsRectItem*) itemList.at(i);
233                     break;
234                 }
235             }
236
237         if (item && event->buttons() == Qt::NoButton) {
238             AbstractClipItem *clip = (AbstractClipItem*) item;
239             opMode = clip->operationMode(mapToScene(event->pos()), m_scale);
240             double size = 8;
241
242             if (opMode == m_moveOpMode) {
243                 QGraphicsView::mouseMoveEvent(event);
244                 return;
245             } else {
246                 if (m_visualTip) {
247                     if (m_animation) delete m_animation;
248                     m_animation = NULL;
249                     m_animationTimer->stop();
250                     delete m_visualTip;
251                     m_visualTip = NULL;
252                 }
253             }
254             m_moveOpMode = opMode;
255
256             if (opMode == MOVE) {
257                 setCursor(Qt::OpenHandCursor);
258             } else if (opMode == RESIZESTART) {
259                 setCursor(KCursor("left_side", Qt::SizeHorCursor));
260                 kDebug() << "********  RESIZE CLIP START; WIDTH: " << size;
261                 if (m_visualTip == NULL) {
262                     QPolygon polygon;
263                     polygon << QPoint((int)clip->rect().x(), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2));
264                     polygon << QPoint((int)(clip->rect().x() + size * 2), (int)(clip->rect().y() + clip->rect().height() / 2));
265                     polygon << QPoint((int)clip->rect().x(), (int)(clip->rect().y() + clip->rect().height() / 2 + size * 2));
266                     polygon << QPoint((int)clip->rect().x(), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2));
267
268                     m_visualTip = new QGraphicsPolygonItem(polygon);
269                     ((QGraphicsPolygonItem*) m_visualTip)->setBrush(m_tipColor);
270                     ((QGraphicsPolygonItem*) m_visualTip)->setPen(m_tipPen);
271                     m_visualTip->setZValue(100);
272                     m_animation = new QGraphicsItemAnimation;
273                     m_animation->setItem(m_visualTip);
274                     m_animation->setTimeLine(m_animationTimer);
275                     m_visualTip->setPos(0, 0);
276                     double scale = 2.0;
277                     m_animation->setScaleAt(.5, scale, 1);
278                     m_animation->setPosAt(.5, QPointF(clip->rect().x() - clip->rect().x() * scale, 0));
279                     scale = 1.0;
280                     m_animation->setScaleAt(1, scale, 1);
281                     m_animation->setPosAt(1, QPointF(clip->rect().x() - clip->rect().x() * scale, 0));
282                     scene()->addItem(m_visualTip);
283                     m_animationTimer->start();
284                 }
285             } else if (opMode == RESIZEEND) {
286                 setCursor(KCursor("right_side", Qt::SizeHorCursor));
287                 if (m_visualTip == NULL) {
288                     QPolygon polygon;
289                     polygon << QPoint((int)(clip->rect().x() + clip->rect().width()), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2));
290                     polygon << QPoint((int)(clip->rect().x() + clip->rect().width() - size * 2), (int)(clip->rect().y() + clip->rect().height() / 2));
291                     polygon << QPoint((int)(clip->rect().x() + clip->rect().width()), (int)(clip->rect().y() + clip->rect().height() / 2 + size * 2));
292                     polygon << QPoint((int)(clip->rect().x() + clip->rect().width()), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2));
293
294                     m_visualTip = new QGraphicsPolygonItem(polygon);
295                     ((QGraphicsPolygonItem*) m_visualTip)->setBrush(m_tipColor);
296                     ((QGraphicsPolygonItem*) m_visualTip)->setPen(m_tipPen);
297
298                     m_visualTip->setZValue(100);
299                     m_animation = new QGraphicsItemAnimation;
300                     m_animation->setItem(m_visualTip);
301                     m_animation->setTimeLine(m_animationTimer);
302                     m_visualTip->setPos(0, 0);
303                     double scale = 2.0;
304                     m_animation->setScaleAt(.5, scale, 1);
305                     m_animation->setPosAt(.5, QPointF(clip->rect().x() - clip->rect().x() * scale - clip->rect().width(), 0));
306                     scale = 1.0;
307                     m_animation->setScaleAt(1, scale, 1);
308                     m_animation->setPosAt(1, QPointF(clip->rect().x() - clip->rect().x() * scale, 0));
309                     scene()->addItem(m_visualTip);
310                     m_animationTimer->start();
311                 }
312             } else if (opMode == FADEIN) {
313                 if (m_visualTip == NULL) {
314                     ClipItem *item = (ClipItem *) clip;
315                     m_visualTip = new QGraphicsEllipseItem(item->rect().x() + item->fadeIn() * m_scale - size, item->rect().y() - 8, size * 2, 16);
316                     ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor);
317                     ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen);
318                     m_visualTip->setZValue(100);
319                     m_animation = new QGraphicsItemAnimation;
320                     m_animation->setItem(m_visualTip);
321                     m_animation->setTimeLine(m_animationTimer);
322                     m_visualTip->setPos(0, 0);
323                     double scale = 2.0;
324                     m_animation->setScaleAt(.5, scale, scale);
325                     m_animation->setPosAt(.5, QPointF(item->rect().x() - item->rect().x() * scale -  item->fadeIn() * m_scale, item->rect().y() - item->rect().y() * scale));
326                     scale = 1.0;
327                     m_animation->setScaleAt(1, scale, scale);
328                     m_animation->setPosAt(1, QPointF(item->rect().x() - item->rect().x() * scale, item->rect().y() - item->rect().y() * scale));
329                     scene()->addItem(m_visualTip);
330                     m_animationTimer->start();
331                 }
332                 setCursor(Qt::PointingHandCursor);
333             } else if (opMode == FADEOUT) {
334                 if (m_visualTip == NULL) {
335                     ClipItem *item = (ClipItem *) clip;
336                     m_visualTip = new QGraphicsEllipseItem(item->rect().x() + item->rect().width() - item->fadeOut() * m_scale - size, item->rect().y() - 8, size*2, 16);
337                     ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor);
338                     ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen);
339                     m_visualTip->setZValue(100);
340                     m_animation = new QGraphicsItemAnimation;
341                     m_animation->setItem(m_visualTip);
342                     m_animation->setTimeLine(m_animationTimer);
343                     m_visualTip->setPos(0, 0);
344                     double scale = 2.0;
345                     m_animation->setScaleAt(.5, scale, scale);
346                     m_animation->setPosAt(.5, QPointF(item->rect().x() - item->rect().x() * scale - item->rect().width() + item->fadeOut() * m_scale, item->rect().y() - item->rect().y() * scale));
347                     scale = 1.0;
348                     m_animation->setScaleAt(1, scale, scale);
349                     m_animation->setPosAt(1, QPointF(item->rect().x() - item->rect().x() * scale, item->rect().y() - item->rect().y() * scale));
350                     scene()->addItem(m_visualTip);
351                     m_animationTimer->start();
352                 }
353                 setCursor(Qt::PointingHandCursor);
354             } else if (opMode == TRANSITIONSTART) {
355                 if (m_visualTip == NULL) {
356                     m_visualTip = new QGraphicsEllipseItem(-5, -5 , 10, 10);
357                     ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor);
358                     ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen);
359                     m_visualTip->setZValue(100);
360                     m_animation = new QGraphicsItemAnimation;
361                     m_animation->setItem(m_visualTip);
362                     m_animation->setTimeLine(m_animationTimer);
363                     m_visualTip->setPos(clip->rect().x() + 10, clip->rect().y() + clip->rect().height() / 2 + 12);
364                     double scale = 2.0;
365                     m_animation->setScaleAt(.5, scale, scale);
366                     scale = 1.0;
367                     m_animation->setScaleAt(1, scale, scale);
368                     scene()->addItem(m_visualTip);
369                     m_animationTimer->start();
370                 }
371                 setCursor(Qt::PointingHandCursor);
372             } else if (opMode == TRANSITIONEND) {
373                 if (m_visualTip == NULL) {
374                     m_visualTip = new QGraphicsEllipseItem(-5, -5 , 10, 10);
375                     ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor);
376                     ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen);
377                     m_visualTip->setZValue(100);
378                     m_animation = new QGraphicsItemAnimation;
379                     m_animation->setItem(m_visualTip);
380                     m_animation->setTimeLine(m_animationTimer);
381                     m_visualTip->setPos(clip->rect().x() + clip->rect().width() - 10 , clip->rect().y() + clip->rect().height() / 2 + 12);
382                     double scale = 2.0;
383                     m_animation->setScaleAt(.5, scale, scale);
384                     scale = 1.0;
385                     m_animation->setScaleAt(1, scale, scale);
386                     scene()->addItem(m_visualTip);
387                     m_animationTimer->start();
388                 }
389                 setCursor(Qt::PointingHandCursor);
390             }
391         } else if (opMode == MOVEGUIDE) {
392             m_moveOpMode = opMode;
393             setCursor(Qt::SplitHCursor);
394         } else {
395             m_moveOpMode = NONE;
396             if (event->buttons() != Qt::NoButton && event->modifiers() == Qt::NoModifier) {
397                 setCursorPos((int)(mapToScene(event->pos().x(), 0).x() / m_scale));
398             }
399             if (m_visualTip) {
400                 if (m_animation) delete m_animation;
401                 m_animationTimer->stop();
402                 m_animation = NULL;
403                 delete m_visualTip;
404                 m_visualTip = NULL;
405
406             }
407             setCursor(Qt::ArrowCursor);
408         }
409     }
410     QGraphicsView::mouseMoveEvent(event);
411 }
412
413 // virtual
414 void CustomTrackView::mousePressEvent(QMouseEvent * event) {
415     activateMonitor();
416     m_clickEvent = event->pos();
417     if (event->button() == Qt::MidButton) {
418         m_document->renderer()->switchPlay();
419         return;
420     }
421     if (event->modifiers() == Qt::ControlModifier) {
422         setDragMode(QGraphicsView::ScrollHandDrag);
423         QGraphicsView::mousePressEvent(event);
424         return;
425     } else if (event->modifiers() == Qt::ShiftModifier) {
426         setDragMode(QGraphicsView::RubberBandDrag);
427         QGraphicsView::mousePressEvent(event);
428         return;
429     } else {
430         bool collision = false;
431         m_dragItem = NULL;
432         QList<QGraphicsItem *> collisionList = items(event->pos());
433         if (collisionList.count() == 1 && collisionList.at(0)->type() == GUIDEITEM) {
434             // a guide item was pressed
435             collisionList.at(0)->setFlag(QGraphicsItem::ItemIsMovable, true);
436             m_dragItem = NULL;
437             m_dragGuide = (Guide *) collisionList.at(0);
438             collision = true;
439             m_operationMode = MOVEGUIDE;
440             // deselect all clips so that only the guide will move
441             QList<QGraphicsItem *> clips = scene()->selectedItems();
442             for (int i = 0; i < clips.count(); ++i)
443                 clips.at(i)->setSelected(false);
444             updateSnapPoints(NULL);
445             QGraphicsView::mousePressEvent(event);
446         } else for (int i = 0; i < collisionList.count(); ++i) {
447                 QGraphicsItem *item = collisionList.at(i);
448                 if (item->type() == AVWIDGET || item->type() == TRANSITIONWIDGET) {
449                     if (m_tool == RAZORTOOL) {
450                         if (item->type() == TRANSITIONWIDGET) return;
451                         AbstractClipItem *clip = (AbstractClipItem *) item;
452                         ItemInfo info;
453                         info.startPos = clip->startPos();
454                         info.endPos = clip->endPos();
455                         info.track = clip->track();
456                         RazorClipCommand* command = new RazorClipCommand(this, info, GenTime((int)(mapToScene(event->pos()).x() / m_scale), m_document->fps()), true);
457                         m_commandStack->push(command);
458                         m_document->setModified(true);
459                         return;
460                     }
461                     // select item
462                     if (!item->isSelected()) {
463                         QList<QGraphicsItem *> itemList = items();
464                         for (int i = 0; i < itemList.count(); i++) {
465                             itemList.at(i)->setSelected(false);
466                             itemList.at(i)->update();
467                         }
468                         item->setSelected(true);
469                         item->update();
470                     }
471
472                     m_dragItem = (AbstractClipItem *) item;
473
474                     m_clickPoint = QPoint((int)(mapToScene(event->pos()).x() - m_dragItem->startPos().frames(m_document->fps()) * m_scale), (int)(event->pos().y() - m_dragItem->rect().top()));
475                     m_dragItemInfo.startPos = m_dragItem->startPos();
476                     m_dragItemInfo.endPos = m_dragItem->endPos();
477                     m_dragItemInfo.track = m_dragItem->track();
478
479                     m_operationMode = m_dragItem->operationMode(item->mapFromScene(mapToScene(event->pos())), m_scale);
480                     if (m_operationMode == MOVE) setCursor(Qt::ClosedHandCursor);
481                     else if (m_operationMode == TRANSITIONSTART) {
482                         ItemInfo info;
483                         info.startPos = m_dragItem->startPos();
484                         info.track = m_dragItem->track();
485                         int transitiontrack = getPreviousVideoTrack(info.track);
486                         ClipItem *transitionClip = NULL;
487                         if (transitiontrack != 0) transitionClip = getClipItemAt((int) info.startPos.frames(m_document->fps()), m_tracksList.count() - transitiontrack);
488                         if (transitionClip && transitionClip->endPos() < m_dragItem->endPos()) {
489                             info.endPos = transitionClip->endPos();
490                         } else info.endPos = info.startPos + GenTime(2.5);
491
492                         slotAddTransition((ClipItem *) m_dragItem, info, transitiontrack);
493                     } else if (m_operationMode == TRANSITIONEND) {
494                         ItemInfo info;
495                         info.endPos = m_dragItem->endPos();
496                         info.track = m_dragItem->track();
497                         int transitiontrack = getPreviousVideoTrack(info.track);
498                         ClipItem *transitionClip = NULL;
499                         if (transitiontrack != 0) transitionClip = getClipItemAt((int) info.endPos.frames(m_document->fps()), m_tracksList.count() - transitiontrack);
500                         if (transitionClip && transitionClip->startPos() > m_dragItem->startPos()) {
501                             info.startPos = transitionClip->startPos();
502                         } else info.startPos = info.endPos - GenTime(2.5);
503                         slotAddTransition((ClipItem *) m_dragItem, info, transitiontrack);
504                     }
505                     updateSnapPoints(m_dragItem);
506                     collision = true;
507                     break;
508                 }
509             }
510         emit clipItemSelected((m_dragItem && m_dragItem->type() == AVWIDGET) ? (ClipItem*) m_dragItem : NULL);
511
512         if (!collision) {
513             kDebug() << "//////// NO ITEM FOUND ON CLICK";
514             m_dragItem = NULL;
515             setCursor(Qt::ArrowCursor);
516             QList<QGraphicsItem *> itemList = items();
517             for (int i = 0; i < itemList.count(); i++)
518                 itemList.at(i)->setSelected(false);
519             //emit clipItemSelected(NULL);
520             if (event->button() == Qt::RightButton) {
521                 displayContextMenu(event->globalPos());
522             } else setCursorPos((int)(mapToScene(event->x(), 0).x() / m_scale));
523         } else if (event->button() == Qt::RightButton) {
524             m_operationMode = NONE;
525             displayContextMenu(event->globalPos(), m_dragItem);
526             m_dragItem = NULL;
527         }
528     }
529     //kDebug()<<pos;
530     //QGraphicsView::mousePressEvent(event);
531 }
532
533 void CustomTrackView::displayContextMenu(QPoint pos, AbstractClipItem *clip) {
534     if (clip == NULL) m_timelineContextMenu->popup(pos);
535     else if (clip->type() == AVWIDGET) m_timelineContextClipMenu->popup(pos);
536     else if (clip->type() == TRANSITIONWIDGET) m_timelineContextTransitionMenu->popup(pos);
537 }
538
539 void CustomTrackView::activateMonitor() {
540     emit activateDocumentMonitor();
541 }
542
543 void CustomTrackView::dragEnterEvent(QDragEnterEvent * event) {
544     if (event->mimeData()->hasFormat("kdenlive/producerslist")) {
545         kDebug() << "///////////////  DRAG ENTERED, TEXT: " << event->mimeData()->data("kdenlive/producerslist");
546         QStringList ids = QString(event->mimeData()->data("kdenlive/producerslist")).split(";");
547         //TODO: drop of several clips
548         for (int i = 0; i < ids.size(); ++i) {
549         }
550         DocClipBase *clip = m_document->getBaseClip(ids.at(0).toInt());
551         if (clip == NULL) kDebug() << " WARNING))))))))) CLIP NOT FOUND : " << ids.at(0).toInt();
552         addItem(clip, event->pos());
553         event->acceptProposedAction();
554     } else QGraphicsView::dragEnterEvent(event);
555 }
556
557 void CustomTrackView::slotRefreshEffects(ClipItem *clip) {
558     int track = m_tracksList.count() - clip->track();
559     GenTime pos = clip->startPos();
560     m_document->renderer()->mltRemoveEffect(track, pos, "-1", false);
561     for (int i = 0; i < clip->effectsCount(); i++) {
562         m_document->renderer()->mltAddEffect(track, pos, clip->getEffectArgs(clip->effectAt(i)), false);
563     }
564     m_document->renderer()->doRefresh();
565 }
566
567 void CustomTrackView::addEffect(int track, GenTime pos, QDomElement effect) {
568     ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_tracksList.count() - track);
569     if (clip) {
570         QMap <QString, QString> effectParams = clip->addEffect(effect);
571         m_document->renderer()->mltAddEffect(track, pos, effectParams);
572         emit clipItemSelected(clip);
573     }
574 }
575
576 void CustomTrackView::deleteEffect(int track, GenTime pos, QDomElement effect) {
577     QString index = effect.attribute("kdenlive_ix");
578     m_document->renderer()->mltRemoveEffect(track, pos, index);
579     ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_tracksList.count() - track);
580     if (clip) {
581         clip->deleteEffect(index);
582         emit clipItemSelected(clip);
583     }
584 }
585
586 void CustomTrackView::slotAddEffect(QDomElement effect, GenTime pos, int track) {
587     QList<QGraphicsItem *> itemList;
588     if (track == -1) itemList = scene()->selectedItems();
589     if (itemList.isEmpty()) {
590         ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, track);
591         if (clip) itemList.append(clip);
592         else kDebug() << "------   wrning, clip eff not found";
593     }
594     kDebug() << "// REQUESTING EFFECT ON CLIP: " << pos.frames(25) << ", TRK: " << track << "SELECTED ITEMS: " << itemList.count();
595     for (int i = 0; i < itemList.count(); i++) {
596         if (itemList.at(i)->type() == AVWIDGET) {
597             ClipItem *item = (ClipItem *)itemList.at(i);
598             // the kdenlive_ix int is used to identify an effect in mlt's playlist, should
599             // not be changed
600             if (effect.attribute("kdenlive_ix").toInt() == 0)
601                 effect.setAttribute("kdenlive_ix", QString::number(item->effectsCounter()));
602             AddEffectCommand *command = new AddEffectCommand(this, m_tracksList.count() - item->track(), item->startPos(), effect, true);
603             m_commandStack->push(command);
604         }
605     }
606     m_document->setModified(true);
607 }
608
609 void CustomTrackView::slotDeleteEffect(ClipItem *clip, QDomElement effect) {
610     AddEffectCommand *command = new AddEffectCommand(this, m_tracksList.count() - clip->track(), clip->startPos(), effect, false);
611     m_commandStack->push(command);
612     m_document->setModified(true);
613 }
614
615 void CustomTrackView::updateEffect(int track, GenTime pos, QDomElement effect) {
616     ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_tracksList.count() - track);
617     if (clip) {
618         QMap <QString, QString> effectParams = clip->getEffectArgs(effect);
619         if (effectParams.value("disabled") == "1") {
620             QString index = effectParams.value("kdenlive_ix");
621             m_document->renderer()->mltRemoveEffect(track, pos, index);
622         } else m_document->renderer()->mltEditEffect(m_tracksList.count() - clip->track(), clip->startPos(), effectParams);
623     }
624     m_document->setModified(true);
625 }
626
627 void CustomTrackView::moveEffect(int track, GenTime pos, int oldPos, int newPos) {
628     ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_tracksList.count() - track);
629     if (clip) {
630         m_document->renderer()->mltMoveEffect(track, pos, oldPos, newPos);
631     }
632     m_document->setModified(true);
633 }
634
635 void CustomTrackView::slotChangeEffectState(ClipItem *clip, QDomElement effect, bool disable) {
636     QDomElement oldEffect = effect.cloneNode().toElement();
637     effect.setAttribute("disabled", disable);
638     EditEffectCommand *command = new EditEffectCommand(this, m_tracksList.count() - clip->track(), clip->startPos(), oldEffect, effect, true);
639     m_commandStack->push(command);
640     m_document->setModified(true);
641 }
642
643 void CustomTrackView::slotChangeEffectPosition(ClipItem *clip, int currentPos, int newPos) {
644     MoveEffectCommand *command = new MoveEffectCommand(this, m_tracksList.count() - clip->track(), clip->startPos(), currentPos, newPos, true);
645     m_commandStack->push(command);
646     m_document->setModified(true);
647 }
648
649 void CustomTrackView::slotUpdateClipEffect(ClipItem *clip, QDomElement oldeffect, QDomElement effect) {
650     EditEffectCommand *command = new EditEffectCommand(this, m_tracksList.count() - clip->track(), clip->startPos(), oldeffect, effect, true);
651     m_commandStack->push(command);
652 }
653
654 void CustomTrackView::cutClip(ItemInfo info, GenTime cutTime, bool cut) {
655     if (cut) {
656         // cut clip
657         ClipItem *item = getClipItemAt((int) info.startPos.frames(m_document->fps()), info.track);
658         int cutPos = (int) cutTime.frames(m_document->fps());
659         ItemInfo newPos;
660         newPos.startPos = cutTime;
661         newPos.endPos = info.endPos;
662         newPos.track = info.track;
663         ClipItem *dup = new ClipItem(item->baseClip(), newPos, item->cropStart(), m_scale, m_document->fps());
664         dup->setCropStart(dup->cropStart() + (cutTime - info.startPos));
665         item->resizeEnd(cutPos, m_scale);
666         scene()->addItem(dup);
667         m_document->renderer()->mltCutClip(m_tracksList.count() - info.track, cutTime);
668     } else {
669         // uncut clip
670         ClipItem *item = getClipItemAt((int) info.startPos.frames(m_document->fps()), info.track);
671         ClipItem *dup = getClipItemAt((int) cutTime.frames(m_document->fps()), info.track);
672         delete dup;
673         item->resizeEnd((int) info.endPos.frames(m_document->fps()), m_scale);
674         m_document->renderer()->mltRemoveClip(m_tracksList.count() - info.track, cutTime);
675         m_document->renderer()->mltResizeClipEnd(m_tracksList.count() - info.track, info.startPos, item->cropStart(), item->cropStart() + info.endPos - info.startPos);
676     }
677 }
678
679
680 void CustomTrackView::slotAddTransitionToSelectedClips(QDomElement transition) {
681     QList<QGraphicsItem *> itemList = scene()->selectedItems();
682     for (int i = 0; i < itemList.count(); i++) {
683         if (itemList.at(i)->type() == AVWIDGET) {
684             ClipItem *item = (ClipItem *) itemList.at(i);
685             ItemInfo info;
686             info.startPos = item->startPos();
687             info.endPos = info.startPos + GenTime(2.5);
688             info.track = item->track();
689             int transitiontrack = getPreviousVideoTrack(info.track);
690             slotAddTransition(item, info, transitiontrack, transition);
691         }
692     }
693 }
694
695 void CustomTrackView::slotAddTransition(ClipItem* clip, ItemInfo transitionInfo, int endTrack, QDomElement transition) {
696     AddTransitionCommand* command = new AddTransitionCommand(this, transitionInfo, endTrack, transition, false, true);
697     m_commandStack->push(command);
698     m_document->setModified(true);
699 }
700
701 void CustomTrackView::addTransition(ItemInfo transitionInfo, int endTrack, QDomElement params) {
702     Transition *tr = new Transition(transitionInfo, endTrack, m_scale, m_document->fps(), params);
703     scene()->addItem(tr);
704
705     //kDebug() << "---- ADDING transition " << e.attribute("tag") << ", on tracks " << m_tracksList.count() - e.attribute("transition_track").toInt() << " / " << getPreviousVideoTrack(e.attribute("transition_track").toInt());
706     m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_tracksList.count() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, tr->toXML());
707     m_document->setModified(true);
708 }
709
710 void CustomTrackView::deleteTransition(ItemInfo transitionInfo, int endTrack, QDomElement params) {
711     Transition *item = getTransitionItemAt((int)transitionInfo.startPos.frames(m_document->fps()) + 1, transitionInfo.track);
712     m_document->renderer()->mltDeleteTransition(item->transitionTag(), endTrack, m_tracksList.count() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, item->toXML());
713     delete item;
714     emit transitionItemSelected(NULL);
715     m_document->setModified(true);
716 }
717
718 void CustomTrackView::slotTransitionUpdated(Transition *tr, QDomElement old) {
719     EditTransitionCommand *command = new EditTransitionCommand(this, tr->track(), tr->startPos(), old, tr->toXML() , true);
720     m_commandStack->push(command);
721     m_document->setModified(true);
722 }
723
724 void CustomTrackView::updateTransition(int track, GenTime pos, QDomElement oldTransition, QDomElement transition) {
725     Transition *item = getTransitionItemAt((int)pos.frames(m_document->fps()) + 1, track);
726     if (!item) {
727         kWarning() << "Unable to find transition at pos :" << pos.frames(m_document->fps()) << ", ON track: " << track;
728         return;
729     }
730     m_document->renderer()->mltUpdateTransition(oldTransition.attribute("tag"), transition.attribute("tag"), transition.attribute("transition_btrack").toInt(), m_tracksList.count() - transition.attribute("transition_atrack").toInt(), item->startPos(), item->endPos(), transition);
731     m_document->setModified(true);
732 }
733
734 void CustomTrackView::addItem(DocClipBase *clip, QPoint pos) {
735     ItemInfo info;
736     info.startPos = GenTime((int)(mapToScene(pos).x() / m_scale), m_document->fps());
737     info.endPos = info.startPos + clip->duration();
738     info.track = (int)(pos.y() / m_tracksHeight);
739     //kDebug()<<"------------  ADDING CLIP ITEM----: "<<info.startPos.frames(25)<<", "<<info.endPos.frames(25)<<", "<<info.track;
740     m_dropItem = new ClipItem(clip, info, GenTime(), m_scale, m_document->fps());
741     scene()->addItem(m_dropItem);
742 }
743
744
745 void CustomTrackView::dragMoveEvent(QDragMoveEvent * event) {
746     event->setDropAction(Qt::IgnoreAction);
747     kDebug() << "+++++++++++++   DRAG MOVE, : " << mapToScene(event->pos()).x() << ", SCAL: " << m_scale;
748     if (m_dropItem) {
749         int track = (int)(mapToScene(event->pos()).y() / m_tracksHeight);  //) * (m_scale * 50) + m_scale;
750         m_dropItem->moveTo((int)(mapToScene(event->pos()).x() / m_scale), m_scale, (int)((track - m_dropItem->track()) * m_tracksHeight), track);
751         event->setDropAction(Qt::MoveAction);
752         if (event->mimeData()->hasFormat("kdenlive/producerslist")) {
753             event->acceptProposedAction();
754         }
755     } else {
756         QGraphicsView::dragMoveEvent(event);
757     }
758 }
759
760 void CustomTrackView::dragLeaveEvent(QDragLeaveEvent * event) {
761     if (m_dropItem) {
762         delete m_dropItem;
763         m_dropItem = NULL;
764     } else QGraphicsView::dragLeaveEvent(event);
765 }
766
767 void CustomTrackView::dropEvent(QDropEvent * event) {
768     if (m_dropItem) {
769         ItemInfo info;
770         info.startPos = m_dropItem->startPos();
771         info.endPos = m_dropItem->endPos();
772         info.track = m_dropItem->track();
773         AddTimelineClipCommand *command = new AddTimelineClipCommand(this, m_dropItem->xml(), m_dropItem->clipProducer(), info, false, false);
774         m_commandStack->push(command);
775         m_dropItem->baseClip()->addReference();
776         m_document->updateClip(m_dropItem->baseClip()->getId());
777         // kDebug()<<"IIIIIIIIIIIIIIIIIIIIIIII TRAX CNT: "<<m_tracksList.count()<<", DROP: "<<m_dropItem->track();
778         m_document->renderer()->mltInsertClip(m_tracksList.count() - m_dropItem->track(), m_dropItem->startPos(), m_dropItem->xml());
779         m_document->setModified(true);
780     } else QGraphicsView::dropEvent(event);
781     m_dropItem = NULL;
782 }
783
784
785 QStringList CustomTrackView::mimeTypes() const {
786     QStringList qstrList;
787     // list of accepted mime types for drop
788     qstrList.append("text/plain");
789     qstrList.append("kdenlive/producerslist");
790     return qstrList;
791 }
792
793 Qt::DropActions CustomTrackView::supportedDropActions() const {
794     // returns what actions are supported when dropping
795     return Qt::MoveAction;
796 }
797
798 void CustomTrackView::setDuration(int duration) {
799     kDebug() << "/////////////  PRO DUR: " << duration << ", SCALE. " << (m_projectDuration + 500) * m_scale << ", height: " << 50 * m_tracksList.count();
800     m_projectDuration = duration;
801     setSceneRect(0, 0, (m_projectDuration + 100) * m_scale, sceneRect().height());
802 }
803
804 int CustomTrackView::duration() const {
805     return m_projectDuration;
806 }
807
808 void CustomTrackView::addTrack(TrackInfo type) {
809     m_tracksList << type;
810     m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_tracksList.count());
811     setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_tracksList.count());
812     verticalScrollBar()->setMaximum(m_tracksHeight * m_tracksList.count());
813     //setFixedHeight(50 * m_tracksCount);
814 }
815
816 void CustomTrackView::removeTrack() {
817     // TODO: implement track deletion
818     //m_tracksCount--;
819     m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_tracksList.count());
820 }
821
822
823 void CustomTrackView::slotSwitchTrackAudio(int ix) {
824     int tracknumber = m_tracksList.count() - ix;
825     kDebug() << "/////  MUTING TRK: " << ix << "; PL NUM: " << tracknumber;
826     m_tracksList[tracknumber - 1].isMute = !m_tracksList.at(tracknumber - 1).isMute;
827     m_document->renderer()->mltChangeTrackState(tracknumber, m_tracksList.at(tracknumber - 1).isMute, m_tracksList.at(tracknumber - 1).isBlind);
828 }
829
830 void CustomTrackView::slotSwitchTrackVideo(int ix) {
831     int tracknumber = m_tracksList.count() - ix;
832     m_tracksList[tracknumber - 1].isBlind = !m_tracksList.at(tracknumber - 1).isBlind;
833     m_document->renderer()->mltChangeTrackState(tracknumber, m_tracksList.at(tracknumber - 1).isMute, m_tracksList.at(tracknumber - 1).isBlind);
834 }
835
836 void CustomTrackView::deleteClip(int clipId) {
837     QList<QGraphicsItem *> itemList = items();
838     for (int i = 0; i < itemList.count(); i++) {
839         if (itemList.at(i)->type() == AVWIDGET) {
840             ClipItem *item = (ClipItem *)itemList.at(i);
841             if (item->clipProducer() == clipId) {
842                 ItemInfo info;
843                 info.startPos = item->startPos();
844                 info.endPos = item->endPos();
845                 info.track = item->track();
846                 AddTimelineClipCommand *command = new AddTimelineClipCommand(this, item->xml(), item->clipProducer(), info, true, true);
847                 m_commandStack->push(command);
848                 //delete item;
849             }
850         }
851     }
852 }
853
854 void CustomTrackView::setCursorPos(int pos, bool seek) {
855     emit cursorMoved((int)(m_cursorPos * m_scale), (int)(pos * m_scale));
856     m_cursorPos = pos;
857     m_cursorLine->setPos(pos * m_scale, 0);
858     if (seek) m_document->renderer()->seek(GenTime(pos, m_document->fps()));
859     else if (m_autoScroll && m_scale < 50) checkScrolling();
860 }
861
862 void CustomTrackView::updateCursorPos() {
863     m_cursorLine->setPos(m_cursorPos * m_scale, 0);
864 }
865
866 int CustomTrackView::cursorPos() {
867     return (int)(m_cursorPos * m_scale);
868 }
869
870 void CustomTrackView::moveCursorPos(int delta) {
871     emit cursorMoved((int)(m_cursorPos * m_scale), (int)((m_cursorPos + delta) * m_scale));
872     m_cursorPos += delta;
873     m_cursorLine->setPos(m_cursorPos * m_scale, 0);
874     m_document->renderer()->seek(GenTime(m_cursorPos, m_document->fps()));
875     //if (m_autoScroll && m_scale < 50) checkScrolling();
876 }
877
878 void CustomTrackView::checkScrolling() {
879     QRect rectInView = viewport()->rect();
880     int delta = rectInView.width() / 3;
881     int max = rectInView.right() + horizontalScrollBar()->value() - delta;
882     //kDebug() << "CURSOR POS: "<<m_cursorPos<< "Scale: "<<m_scale;
883     if (m_cursorPos * m_scale >= max) horizontalScrollBar()->setValue((int)(horizontalScrollBar()->value() + 1 + m_scale));
884 }
885
886 void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
887     if (event->button() == Qt::MidButton) {
888         return;
889     }
890     QGraphicsView::mouseReleaseEvent(event);
891     setDragMode(QGraphicsView::NoDrag);
892     if (m_operationMode == MOVEGUIDE) {
893         setCursor(Qt::ArrowCursor);
894         m_operationMode = NONE;
895         m_dragGuide->setFlag(QGraphicsItem::ItemIsMovable, false);
896         EditGuideCommand *command = new EditGuideCommand(this, m_dragGuide->position(), m_dragGuide->label(), GenTime(m_dragGuide->pos().x() / m_scale, m_document->fps()), m_dragGuide->label(), false);
897         m_commandStack->push(command);
898         m_dragGuide->update(GenTime(m_dragGuide->pos().x() / m_scale, m_document->fps()));
899         m_dragGuide = NULL;
900         m_dragItem = NULL;
901         return;
902     }
903     if (m_dragItem == NULL) {
904         emit transitionItemSelected(NULL);
905         return;
906     }
907     ItemInfo info;
908     info.startPos = m_dragItem->startPos();
909     info.endPos = m_dragItem->endPos();
910     info.track = m_dragItem->track();
911
912     if (m_operationMode == MOVE) {
913         setCursor(Qt::OpenHandCursor);
914         // move clip
915         if (m_dragItem->type() == AVWIDGET && m_dragItemInfo.startPos != info.startPos) {
916             MoveClipCommand *command = new MoveClipCommand(this, m_dragItemInfo, info, false);
917             m_commandStack->push(command);
918             m_document->renderer()->mltMoveClip((int)(m_tracksList.count() - m_dragItemInfo.track), (int)(m_tracksList.count() - m_dragItem->track()), (int) m_dragItemInfo.startPos.frames(m_document->fps()), (int)(m_dragItem->startPos().frames(m_document->fps())));
919         }
920         if (m_dragItem->type() == TRANSITIONWIDGET && (m_dragItemInfo.startPos != info.startPos || m_dragItemInfo.track != info.track)) {
921             MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false);
922             m_commandStack->push(command);
923             //kDebug()<<"/// MOVING TRS FROM: "<<(int)(m_tracksList.count() - m_startPos.y())<<", OFFSET: "<<(int) (m_dragItem->track() - m_startPos.y());
924             Transition *transition = (Transition *) m_dragItem;
925             transition->updateTransitionEndTrack(getPreviousVideoTrack(m_dragItem->track()));
926             m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_tracksList.count() - m_dragItemInfo.track), (int)(m_tracksList.count() - m_dragItem->track()), transition->transitionEndTrack(), m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos);
927         }
928
929     } else if (m_operationMode == RESIZESTART) {
930         // resize start
931         if (m_dragItem->type() == AVWIDGET) {
932             m_document->renderer()->mltResizeClipStart(m_tracksList.count() - m_dragItem->track(), m_dragItem->endPos(), m_dragItem->startPos(), m_dragItemInfo.startPos, m_dragItem->cropStart(), m_dragItem->cropStart() + m_dragItem->endPos() - m_dragItem->startPos());
933             updateClipFade((ClipItem *) m_dragItem);
934             ResizeClipCommand *command = new ResizeClipCommand(this, m_dragItemInfo, info, false);
935             m_commandStack->push(command);
936         } else if (m_dragItem->type() == TRANSITIONWIDGET) {
937             MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false);
938             m_commandStack->push(command);
939             Transition *transition = (Transition *) m_dragItem;
940             m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_tracksList.count() - m_dragItemInfo.track), (int)(m_tracksList.count() - m_dragItemInfo.track), 0, m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos);
941         }
942
943         //m_document->renderer()->doRefresh();
944     } else if (m_operationMode == RESIZEEND) {
945         // resize end
946         if (m_dragItem->type() == AVWIDGET) {
947             ResizeClipCommand *command = new ResizeClipCommand(this, m_dragItemInfo, info, false);
948             m_document->renderer()->mltResizeClipEnd(m_tracksList.count() - m_dragItem->track(), m_dragItem->startPos(), m_dragItem->cropStart(), m_dragItem->cropStart() + m_dragItem->endPos() - m_dragItem->startPos());
949             m_commandStack->push(command);
950         } else if (m_dragItem->type() == TRANSITIONWIDGET) {
951             MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false);
952             m_commandStack->push(command);
953             Transition *transition = (Transition *) m_dragItem;
954             m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_tracksList.count() - m_dragItemInfo.track), (int)(m_tracksList.count() - m_dragItemInfo.track), 0, m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos);
955         }
956         //m_document->renderer()->doRefresh();
957     } else if (m_operationMode == FADEIN) {
958         // resize fade in effect
959         ClipItem * item = (ClipItem *) m_dragItem;
960         QStringList clipeffects = item->effectNames();
961         if (clipeffects.contains(i18n("Fade in"))) {
962             QDomElement oldeffect = item->effectAt(clipeffects.indexOf("Fade in"));
963             int start = item->cropStart().frames(m_document->fps());
964             int end = item->fadeIn();
965             if (end == 0) {
966                 slotDeleteEffect(item, oldeffect);
967             } else {
968                 end += start;
969                 QDomElement effect = MainWindow::audioEffects.getEffectByName("Fade in");
970                 EffectsList::setParameter(effect, "in", QString::number(start));
971                 EffectsList::setParameter(effect, "out", QString::number(end));
972                 slotUpdateClipEffect(item, oldeffect, effect);
973             }
974         } else if (item->fadeIn() != 0) {
975             QDomElement effect = MainWindow::audioEffects.getEffectByName("Fade in");
976             int start = item->cropStart().frames(m_document->fps());
977             int end = item->fadeIn() + start;
978             EffectsList::setParameter(effect, "in", QString::number(start));
979             EffectsList::setParameter(effect, "out", QString::number(end));
980             slotAddEffect(effect, m_dragItem->startPos(), m_dragItem->track());
981         }
982     } else if (m_operationMode == FADEOUT) {
983         // resize fade in effect
984         ClipItem * item = (ClipItem *) m_dragItem;
985         QStringList clipeffects = item->effectNames();
986         if (clipeffects.contains(i18n("Fade out"))) {
987             QDomElement oldeffect = item->effectAt(clipeffects.indexOf("Fade out"));
988             int end = (item->duration() + item->cropStart()).frames(m_document->fps());
989             int start = item->fadeOut();
990             if (start == 0) {
991                 slotDeleteEffect(item, oldeffect);
992             } else {
993                 start = end - start;
994                 QDomElement effect = MainWindow::audioEffects.getEffectByName("Fade out");
995                 EffectsList::setParameter(effect, "in", QString::number(start));
996                 EffectsList::setParameter(effect, "out", QString::number(end));
997                 slotUpdateClipEffect(item, oldeffect, effect);
998             }
999         } else if (item->fadeOut() != 0) {
1000             QDomElement effect = MainWindow::audioEffects.getEffectByName("Fade out");
1001             int end = (item->duration() + item->cropStart()).frames(m_document->fps());
1002             int start = end - item->fadeOut();
1003             EffectsList::setParameter(effect, "in", QString::number(start));
1004             EffectsList::setParameter(effect, "out", QString::number(end));
1005             slotAddEffect(effect, m_dragItem->startPos(), m_dragItem->track());
1006         }
1007     }
1008
1009
1010     emit transitionItemSelected((m_dragItem && m_dragItem->type() == TRANSITIONWIDGET) ? (Transition*) m_dragItem : NULL);
1011     m_document->setModified(true);
1012     m_operationMode = NONE;
1013     m_dragItem = NULL;
1014 }
1015
1016 void CustomTrackView::deleteClip(ItemInfo info) {
1017     ClipItem *item = getClipItemAt((int) info.startPos.frames(m_document->fps()), info.track);
1018     if (!item) {
1019         kDebug() << "----------------  ERROR, CANNOT find clip to move at...";// << rect.x();
1020         return;
1021     }
1022     if (item->isSelected()) emit clipItemSelected(NULL);
1023     item->baseClip()->removeReference();
1024     m_document->updateClip(item->baseClip()->getId());
1025     delete item;
1026     m_document->renderer()->mltRemoveClip(m_tracksList.count() - info.track, info.startPos);
1027     m_document->renderer()->doRefresh();
1028 }
1029
1030 void CustomTrackView::deleteSelectedClips() {
1031     QList<QGraphicsItem *> itemList = scene()->selectedItems();
1032     for (int i = 0; i < itemList.count(); i++) {
1033         if (itemList.at(i)->type() == AVWIDGET) {
1034             ClipItem *item = (ClipItem *) itemList.at(i);
1035             ItemInfo info;
1036             info.startPos = item->startPos();
1037             info.endPos = item->endPos();
1038             info.track = item->track();
1039             AddTimelineClipCommand *command = new AddTimelineClipCommand(this, item->xml(), item->clipProducer(), info, true, true);
1040             m_commandStack->push(command);
1041         } else if (itemList.at(i)->type() == TRANSITIONWIDGET) {
1042             Transition *item = (Transition *) itemList.at(i);
1043             ItemInfo info;
1044             info.startPos = item->startPos();
1045             info.endPos = item->endPos();
1046             info.track = item->track();
1047             AddTransitionCommand *command = new AddTransitionCommand(this, info, item->transitionEndTrack(), QDomElement(), true, true);
1048             m_commandStack->push(command);
1049         }
1050     }
1051 }
1052
1053 void CustomTrackView::cutSelectedClips() {
1054     QList<QGraphicsItem *> itemList = scene()->selectedItems();
1055     GenTime currentPos = GenTime(m_cursorPos, m_document->fps());
1056     for (int i = 0; i < itemList.count(); i++) {
1057         if (itemList.at(i)->type() == AVWIDGET) {
1058             ClipItem *item = (ClipItem *) itemList.at(i);
1059             ItemInfo info;
1060             info.startPos = item->startPos();
1061             info.endPos = item->endPos();
1062             if (currentPos > info.startPos && currentPos <  info.endPos) {
1063                 info.track = item->track();
1064                 RazorClipCommand *command = new RazorClipCommand(this, info, currentPos, true);
1065                 m_commandStack->push(command);
1066             }
1067         }
1068     }
1069 }
1070
1071 void CustomTrackView::addClip(QDomElement xml, int clipId, ItemInfo info) {
1072     DocClipBase *baseclip = m_document->clipManager()->getClipById(clipId);
1073     int crop = xml.attribute("in").toInt();
1074     ClipItem *item = new ClipItem(baseclip, info, GenTime(crop, m_document->fps()), m_scale, m_document->fps());
1075     scene()->addItem(item);
1076     baseclip->addReference();
1077     m_document->updateClip(baseclip->getId());
1078     m_document->renderer()->mltInsertClip(m_tracksList.count() - info.track, info.startPos, xml);
1079     m_document->renderer()->doRefresh();
1080 }
1081
1082 void CustomTrackView::slotUpdateClip(int clipId) {
1083     QList<QGraphicsItem *> list = scene()->items();
1084     ClipItem *clip = NULL;
1085     for (int i = 0; i < list.size(); ++i) {
1086         if (list.at(i)->type() == AVWIDGET) {
1087             clip = static_cast <ClipItem *>(list.at(i));
1088             if (clip->clipProducer() == clipId) {
1089                 clip->refreshClip();
1090                 m_document->renderer()->mltUpdateClip(m_tracksList.count() - clip->track(), clip->startPos(), clip->xml());
1091             }
1092         }
1093     }
1094 }
1095
1096 ClipItem *CustomTrackView::getClipItemAt(int pos, int track) {
1097     QList<QGraphicsItem *> list = scene()->items(QPointF(pos * m_scale, track * m_tracksHeight + m_tracksHeight / 2));
1098     ClipItem *clip = NULL;
1099     for (int i = 0; i < list.size(); ++i) {
1100         if (list.at(i)->type() == AVWIDGET) {
1101             clip = static_cast <ClipItem *>(list.at(i));
1102             break;
1103         }
1104     }
1105     return clip;
1106 }
1107
1108 ClipItem *CustomTrackView::getClipItemAt(GenTime pos, int track) {
1109     int framepos = (int)(pos.frames(m_document->fps()) * m_scale);
1110     return getClipItemAt(framepos, track);
1111 }
1112
1113 Transition *CustomTrackView::getTransitionItemAt(int pos, int track) {
1114     QList<QGraphicsItem *> list = scene()->items(QPointF(pos * m_scale, (track + 1) * m_tracksHeight));
1115     Transition *clip = NULL;
1116     for (int i = 0; i < list.size(); ++i) {
1117         if (list.at(i)->type() == TRANSITIONWIDGET) {
1118             clip = static_cast <Transition *>(list.at(i));
1119             break;
1120         }
1121     }
1122     return clip;
1123 }
1124
1125 Transition *CustomTrackView::getTransitionItemAt(GenTime pos, int track) {
1126     int framepos = (int)(pos.frames(m_document->fps()) * m_scale);
1127     return getTransitionItemAt(framepos, track);
1128 }
1129
1130 void CustomTrackView::moveClip(const ItemInfo start, const ItemInfo end) {
1131     ClipItem *item = getClipItemAt((int) start.startPos.frames(m_document->fps()) + 1, start.track);
1132     if (!item) {
1133         kDebug() << "----------------  ERROR, CANNOT find clip to move at.. ";// << startPos.x() * m_scale * FRAME_SIZE + 1 << ", " << startPos.y() * m_tracksHeight + m_tracksHeight / 2;
1134         return;
1135     }
1136     //kDebug() << "----------------  Move CLIP FROM: " << startPos.x() << ", END:" << endPos.x() << ",TRACKS: " << startPos.y() << " TO " << endPos.y();
1137     item->moveTo((int) end.startPos.frames(m_document->fps()), m_scale, (int)((end.track - start.track) * m_tracksHeight), end.track);
1138     m_document->renderer()->mltMoveClip((int)(m_tracksList.count() - start.track), (int)(m_tracksList.count() - end.track), (int) start.startPos.frames(m_document->fps()), (int)end.startPos.frames(m_document->fps()));
1139 }
1140
1141 void CustomTrackView::moveTransition(const ItemInfo start, const ItemInfo end) {
1142     Transition *item = getTransitionItemAt((int)start.startPos.frames(m_document->fps()) + 1, start.track);
1143     if (!item) {
1144         kDebug() << "----------------  ERROR, CANNOT find transition to move... ";// << startPos.x() * m_scale * FRAME_SIZE + 1 << ", " << startPos.y() * m_tracksHeight + m_tracksHeight / 2;
1145         return;
1146     }
1147     //kDebug() << "----------------  Move TRANSITION FROM: " << startPos.x() << ", END:" << endPos.x() << ",TRACKS: " << oldtrack << " TO " << newtrack;
1148
1149     //kDebug()<<"///  RESIZE TRANS START: ("<< startPos.x()<<"x"<< startPos.y()<<") / ("<<endPos.x()<<"x"<< endPos.y()<<")";
1150     if (end.endPos - end.startPos == start.endPos - start.startPos) {
1151         // Transition was moved
1152         item->moveTo((int) end.startPos.frames(m_document->fps()), m_scale, (end.track - start.track) * m_tracksHeight, end.track);
1153     } else if (end.endPos == start.endPos) {
1154         // Transition start resize
1155         item->resizeStart((int) end.startPos.frames(m_document->fps()), m_scale);
1156     } else {
1157         // Transition end resize;
1158         item->resizeEnd((int) end.endPos.frames(m_document->fps()), m_scale);
1159     }
1160     //item->moveTransition(GenTime((int) (endPos.x() - startPos.x()), m_document->fps()));
1161     item->updateTransitionEndTrack(getPreviousVideoTrack(end.track));
1162     m_document->renderer()->mltMoveTransition(item->transitionTag(), m_tracksList.count() - start.track, m_tracksList.count() - end.track, item->transitionEndTrack(), start.startPos, start.endPos, end.startPos, end.endPos);
1163 }
1164
1165 void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end) {
1166     int offset;
1167     bool resizeClipStart = true;
1168     if (start.startPos == end.startPos) resizeClipStart = false;
1169     if (resizeClipStart) offset = 1;
1170     else offset = -1;
1171     ClipItem *item = getClipItemAt((int)(start.startPos.frames(m_document->fps()) + offset), start.track);
1172     if (!item) {
1173         kDebug() << "----------------  ERROR, CANNOT find clip to resize at... "; // << startPos;
1174         return;
1175     }
1176     if (resizeClipStart) {
1177         m_document->renderer()->mltResizeClipStart(m_tracksList.count() - item->track(), item->endPos(), end.startPos, item->startPos(), item->cropStart() + end.startPos - start.startPos, item->cropStart() + end.startPos - start.startPos + item->endPos() - end.startPos);
1178         item->resizeStart((int) end.startPos.frames(m_document->fps()), m_scale);
1179         updateClipFade(item);
1180     } else {
1181         m_document->renderer()->mltResizeClipEnd(m_tracksList.count() - item->track(), item->startPos(), item->cropStart(), item->cropStart() + end.startPos - item->startPos());
1182         item->resizeEnd((int) end.startPos.frames(m_document->fps()), m_scale);
1183         updateClipFade(item, true);
1184     }
1185     m_document->renderer()->doRefresh();
1186 }
1187
1188 void CustomTrackView::updateClipFade(ClipItem * item, bool updateFadeOut) {
1189     if (!updateFadeOut) {
1190         int end = item->fadeIn();
1191         if (end != 0) {
1192             // there is a fade in effect
1193             QStringList clipeffects = item->effectNames();
1194             QDomElement oldeffect = item->effectAt(clipeffects.indexOf("Fade in"));
1195             int start = item->cropStart().frames(m_document->fps());
1196             end += start;
1197             EffectsList::setParameter(oldeffect, "in", QString::number(start));
1198             EffectsList::setParameter(oldeffect, "out", QString::number(end));
1199             QMap <QString, QString> effectParams = item->getEffectArgs(oldeffect);
1200             m_document->renderer()->mltEditEffect(m_tracksList.count() - item->track(), item->startPos(), effectParams);
1201         }
1202     } else {
1203         int start = item->fadeOut();
1204         if (start != 0) {
1205             // there is a fade in effect
1206             QStringList clipeffects = item->effectNames();
1207             QDomElement oldeffect = item->effectAt(clipeffects.indexOf("Fade out"));
1208             int end = (item->duration() - item->cropStart()).frames(m_document->fps());
1209             start = end - start;
1210             EffectsList::setParameter(oldeffect, "in", QString::number(start));
1211             EffectsList::setParameter(oldeffect, "out", QString::number(end));
1212             QMap <QString, QString> effectParams = item->getEffectArgs(oldeffect);
1213             m_document->renderer()->mltEditEffect(m_tracksList.count() - item->track(), item->startPos(), effectParams);
1214         }
1215     }
1216 }
1217
1218 double CustomTrackView::getSnapPointForPos(double pos) {
1219     for (int i = 0; i < m_snapPoints.size(); ++i) {
1220         if (abs((int)(pos - m_snapPoints.at(i).frames(m_document->fps()) * m_scale)) < 10) {
1221             //kDebug()<<" FOUND SNAP POINT AT: "<<m_snapPoints.at(i)<<", current pos: "<<pos / m_scale;
1222             return m_snapPoints.at(i).frames(m_document->fps()) * m_scale + 0.5;
1223         }
1224         if (m_snapPoints.at(i).frames(m_document->fps() * m_scale) > pos) break;
1225     }
1226     return pos;
1227 }
1228
1229 void CustomTrackView::updateSnapPoints(AbstractClipItem *selected) {
1230     m_snapPoints.clear();
1231     GenTime offset;
1232     if (selected) offset = selected->duration();
1233     QList<QGraphicsItem *> itemList = items();
1234     for (int i = 0; i < itemList.count(); i++) {
1235         if (itemList.at(i)->type() == AVWIDGET && itemList.at(i) != selected) {
1236             ClipItem *item = static_cast <ClipItem *>(itemList.at(i));
1237             GenTime start = item->startPos();
1238             GenTime end = item->endPos();
1239             m_snapPoints.append(start);
1240             m_snapPoints.append(end);
1241             QList < GenTime > markers = item->snapMarkers();
1242             for (int i = 0; i < markers.size(); ++i) {
1243                 GenTime t = markers.at(i);
1244                 m_snapPoints.append(t);
1245                 if (t > offset) m_snapPoints.append(t - offset);
1246             }
1247             if (offset != GenTime()) {
1248                 if (start > offset) m_snapPoints.append(start - offset);
1249                 if (end > offset) m_snapPoints.append(end - offset);
1250             }
1251         } else if (itemList.at(i)->type() == TRANSITIONWIDGET) {
1252             Transition *transition = static_cast <Transition*>(itemList.at(i));
1253             GenTime start = transition->startPos();
1254             GenTime end = transition->endPos();
1255             m_snapPoints.append(start);
1256             m_snapPoints.append(end);
1257             if (offset != GenTime()) {
1258                 if (start > offset) m_snapPoints.append(start - offset);
1259                 if (end > offset) m_snapPoints.append(end - offset);
1260             }
1261         }
1262     }
1263
1264     // add cursor position
1265     GenTime pos = GenTime(m_cursorPos, m_document->fps());
1266     m_snapPoints.append(pos);
1267     if (offset != GenTime()) m_snapPoints.append(pos - offset);
1268
1269     // add guides
1270     for (int i = 0; i < m_guides.count(); i++) {
1271         m_snapPoints.append(m_guides.at(i)->position());
1272         if (offset != GenTime()) m_snapPoints.append(m_guides.at(i)->position() - offset);
1273     }
1274
1275     qSort(m_snapPoints);
1276     //for (int i = 0; i < m_snapPoints.size(); ++i)
1277     //    kDebug() << "SNAP POINT: " << m_snapPoints.at(i).frames(25);
1278 }
1279
1280 void CustomTrackView::slotSeekToPreviousSnap() {
1281     updateSnapPoints(NULL);
1282     GenTime pos = GenTime(m_cursorPos, m_document->fps());
1283     GenTime res = GenTime();
1284     for (int i = 0; i < m_snapPoints.size(); ++i) {
1285         if (m_snapPoints.at(i) >= pos) {
1286             if (i == 0) i = 1;
1287             res = m_snapPoints.at(i - 1);
1288             break;
1289         }
1290     }
1291     setCursorPos((int) res.frames(m_document->fps()));
1292 }
1293
1294 void CustomTrackView::slotSeekToNextSnap() {
1295     updateSnapPoints(NULL);
1296     GenTime pos = GenTime(m_cursorPos, m_document->fps());
1297     GenTime res = GenTime(m_projectDuration, m_document->fps());
1298     for (int i = 0; i < m_snapPoints.size(); ++i) {
1299         if (m_snapPoints.at(i) > pos) {
1300             res = m_snapPoints.at(i);
1301             break;
1302         }
1303     }
1304     setCursorPos((int) res.frames(m_document->fps()));
1305 }
1306
1307 void CustomTrackView::slotAddClipMarker() {
1308     QList<QGraphicsItem *> itemList = scene()->selectedItems();
1309     if (itemList.count() != 1) {
1310         kDebug() << "// CANNOT ADD MARKER IF MORE TAN ONE CLIP IS SELECTED....";
1311         return;
1312     }
1313     AbstractClipItem *item = (AbstractClipItem *)itemList.at(0);
1314     if (item->type() != AVWIDGET) return;
1315     GenTime pos = GenTime(m_cursorPos, m_document->fps());
1316     if (item->startPos() > pos || item->endPos() < pos) return;
1317     ClipItem *clip = (ClipItem *) item;
1318     int id = clip->baseClip()->getId();
1319     GenTime position = pos - item->startPos() + item->cropStart();
1320     CommentedTime marker(position, i18n("Marker"));
1321     MarkerDialog d(clip->baseClip(), marker, m_document->timecode(), this);
1322     if (d.exec() == QDialog::Accepted) {
1323         slotAddClipMarker(id, d.newMarker().time(), d.newMarker().comment());
1324     }
1325 }
1326
1327 void CustomTrackView::slotAddClipMarker(int id, GenTime t, QString c) {
1328     QString oldcomment = m_document->clipManager()->getClipById(id)->markerComment(t);
1329     AddMarkerCommand *command = new AddMarkerCommand(this, oldcomment, c, id, t, true);
1330     m_commandStack->push(command);
1331 }
1332
1333 void CustomTrackView::slotDeleteClipMarker() {
1334     QList<QGraphicsItem *> itemList = scene()->selectedItems();
1335     if (itemList.count() != 1) {
1336         kDebug() << "// CANNOT DELETE MARKER IF MORE TAN ONE CLIP IS SELECTED....";
1337         return;
1338     }
1339     AbstractClipItem *item = (AbstractClipItem *)itemList.at(0);
1340     if (item->type() != AVWIDGET) return;
1341     GenTime pos = GenTime(m_cursorPos, m_document->fps());
1342     if (item->startPos() > pos || item->endPos() < pos) return;
1343     ClipItem *clip = (ClipItem *) item;
1344     int id = clip->baseClip()->getId();
1345     GenTime position = pos - item->startPos() + item->cropStart();
1346     QString comment = clip->baseClip()->markerComment(position);
1347     if (comment.isEmpty()) return;
1348     AddMarkerCommand *command = new AddMarkerCommand(this, comment, QString(), id, position, true);
1349     m_commandStack->push(command);
1350 }
1351
1352 void CustomTrackView::slotEditClipMarker() {
1353     QList<QGraphicsItem *> itemList = scene()->selectedItems();
1354     if (itemList.count() != 1) {
1355         kDebug() << "// CANNOT DELETE MARKER IF MORE TAN ONE CLIP IS SELECTED....";
1356         return;
1357     }
1358     AbstractClipItem *item = (AbstractClipItem *)itemList.at(0);
1359     if (item->type() != AVWIDGET) return;
1360     GenTime pos = GenTime(m_cursorPos, m_document->fps());
1361     if (item->startPos() > pos || item->endPos() < pos) return;
1362     ClipItem *clip = (ClipItem *) item;
1363     int id = clip->baseClip()->getId();
1364     GenTime position = pos - item->startPos() + item->cropStart();
1365     QString oldcomment = clip->baseClip()->markerComment(position);
1366     if (oldcomment.isEmpty()) return;
1367
1368     CommentedTime marker(position, oldcomment);
1369     MarkerDialog d(clip->baseClip(), marker, m_document->timecode(), this);
1370     if (d.exec() == QDialog::Accepted) {
1371         if (d.newMarker().time() == position) {
1372             // marker position was not changed, only text
1373             AddMarkerCommand *command = new AddMarkerCommand(this, oldcomment, d.newMarker().comment(), id, position, true);
1374             m_commandStack->push(command);
1375         } else {
1376             // marker text and position were changed, remove previous marker and add new one
1377             AddMarkerCommand *command1 = new AddMarkerCommand(this, oldcomment, QString(), id, position, true);
1378             AddMarkerCommand *command2 = new AddMarkerCommand(this, QString(), d.newMarker().comment(), id, d.newMarker().time(), true);
1379             m_commandStack->push(command1);
1380             m_commandStack->push(command2);
1381         }
1382     }
1383 }
1384
1385 void CustomTrackView::addMarker(const int id, const GenTime &pos, const QString comment) {
1386     DocClipBase *base = m_document->clipManager()->getClipById(id);
1387     if (!comment.isEmpty()) base->addSnapMarker(pos, comment);
1388     else base->deleteSnapMarker(pos);
1389     m_document->setModified(true);
1390     viewport()->update();
1391 }
1392
1393
1394
1395 void CustomTrackView::editGuide(const GenTime oldPos, const GenTime pos, const QString &comment) {
1396     if (oldPos != GenTime() && pos != GenTime()) {
1397         // move guide
1398         for (int i = 0; i < m_guides.count(); i++) {
1399             kDebug() << "// LOOKING FOR GUIDE (" << i << "): " << m_guides.at(i)->position().frames(25) << ", LOOK: " << oldPos.frames(25) << "x" << pos.frames(25);
1400             if (m_guides.at(i)->position() == oldPos) {
1401                 Guide *item = m_guides.at(i);
1402                 item->update(pos, comment);
1403                 item->updatePosition(m_scale);
1404                 break;
1405             }
1406         }
1407     } else if (pos != GenTime()) addGuide(pos, comment);
1408     else {
1409         // remove guide
1410         for (int i = 0; i < m_guides.count(); i++) {
1411             if (m_guides.at(i)->position() == oldPos) {
1412                 Guide *item = m_guides.takeAt(i);
1413                 delete item;
1414                 break;
1415             }
1416         }
1417
1418     }
1419 }
1420
1421 void CustomTrackView::addGuide(const GenTime pos, const QString &comment) {
1422     Guide *g = new Guide(this, pos, comment, m_scale, m_document->fps(), m_tracksHeight * m_tracksList.count());
1423     scene()->addItem(g);
1424     m_guides.append(g);
1425 }
1426
1427 void CustomTrackView::slotAddGuide() {
1428     addGuide(GenTime(m_cursorPos, m_document->fps()), i18n("guide"));
1429     EditGuideCommand *command = new EditGuideCommand(this, GenTime(), QString(), GenTime(m_cursorPos, m_document->fps()), i18n("guide"), false);
1430     m_commandStack->push(command);
1431
1432 }
1433
1434 void CustomTrackView::slotDeleteGuide() {
1435         GenTime pos = GenTime(m_cursorPos, m_document->fps());
1436         for (int i = 0; i < m_guides.count(); i++) {
1437                 if (m_guides.at(i)->position() == pos) {
1438                         EditGuideCommand *command = new EditGuideCommand(this, m_guides.at(i)->position(), m_guides.at(i)->label(), GenTime(), QString(), true);
1439                         m_commandStack->push(command);
1440             break;
1441         }
1442         }
1443 }
1444
1445 void CustomTrackView::setTool(PROJECTTOOL tool) {
1446     m_tool = tool;
1447 }
1448
1449 void CustomTrackView::setScale(double scaleFactor) {
1450     //scale(scaleFactor, scaleFactor);
1451     double pos = cursorPos() / m_scale;
1452     m_scale = scaleFactor;
1453     int vert = verticalScrollBar()->value();
1454     kDebug() << " HHHHHHHH  SCALING: " << m_scale;
1455     QList<QGraphicsItem *> itemList = items();
1456     for (int i = 0; i < itemList.count(); i++) {
1457         if (itemList.at(i)->type() == AVWIDGET || itemList.at(i)->type() == TRANSITIONWIDGET) {
1458             AbstractClipItem *clip = (AbstractClipItem *)itemList.at(i);
1459             clip->setRect(clip->startPos().frames(m_document->fps()) * m_scale, clip->rect().y(), clip->duration().frames(m_document->fps()) * m_scale, clip->rect().height());
1460         }
1461     }
1462
1463     for (int i = 0; i < m_guides.count(); i++) {
1464         m_guides.at(i)->updatePosition(m_scale);
1465     }
1466
1467     updateCursorPos();
1468     centerOn(QPointF(cursorPos(), m_tracksHeight));
1469     setSceneRect(0, 0, (m_projectDuration + 100) * m_scale, sceneRect().height());
1470     verticalScrollBar()->setValue(vert);
1471 }
1472
1473 void CustomTrackView::drawBackground(QPainter * painter, const QRectF & rect) {
1474     QRect rectInView = viewport()->rect();
1475     rectInView.moveTo(horizontalScrollBar()->value(), verticalScrollBar()->value());
1476
1477     QColor base = palette().button().color();
1478     painter->setClipRect(rect);
1479     painter->drawLine(rectInView.left(), 0, rectInView.right(), 0);
1480     uint max = m_tracksList.count();
1481     for (uint i = 0; i < max;i++) {
1482         if (m_tracksList.at(max - i - 1).type == AUDIOTRACK) painter->fillRect(rectInView.left(), m_tracksHeight * i + 1, rectInView.right() - rectInView.left() + 1, m_tracksHeight - 1, QBrush(QColor(240, 240, 255)));
1483         painter->drawLine(rectInView.left(), m_tracksHeight * (i + 1), rectInView.right(), m_tracksHeight * (i + 1));
1484         //painter->drawText(QRectF(10, 50 * i, 100, 50 * i + 49), Qt::AlignLeft, i18n(" Track ") + QString::number(i + 1));
1485     }
1486     int lowerLimit = m_tracksHeight * m_tracksList.count() + 1;
1487     if (height() > lowerLimit)
1488         painter->fillRect(QRectF(rectInView.left(), lowerLimit, rectInView.width(), height() - lowerLimit), QBrush(base));
1489 }
1490 /*
1491 void CustomTrackView::drawForeground ( QPainter * painter, const QRectF & rect )
1492 {
1493   //kDebug()<<"/////  DRAWING FB: "<<rect.x()<<", width: "<<rect.width();
1494   painter->fillRect(rect, QColor(50, rand() % 250,50,100));
1495   painter->drawLine(m_cursorPos, rect.y(), m_cursorPos, rect.y() + rect.height());
1496 }
1497 */
1498 #include "customtrackview.moc"