]> git.sesse.net Git - kdenlive/blob - src/customtrackview.cpp
Fix transition moving (still crashing a lot)
[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 #include <KCursor>
30
31 #include "customtrackview.h"
32 #include "docclipbase.h"
33 #include "clipitem.h"
34 #include "definitions.h"
35 #include "moveclipcommand.h"
36 #include "movetransitioncommand.h"
37 #include "resizeclipcommand.h"
38 #include "addtimelineclipcommand.h"
39 #include "addeffectcommand.h"
40 #include "editeffectcommand.h"
41 #include "addtransitioncommand.h"
42 #include "edittransitioncommand.h"
43 #include "kdenlivesettings.h"
44 #include "transition.h"
45 #include "clipitem.h"
46 #include "customtrackview.h"
47 #include "clipmanager.h"
48 #include "renderer.h"
49 //TODO:
50 // disable animation if user asked it in KDE's global settings
51 // http://lists.kde.org/?l=kde-commits&m=120398724717624&w=2
52 // needs something like below (taken from dolphin)
53 // #include <kglobalsettings.h>
54 // const bool animate = KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects;
55 // const int duration = animate ? 1500 : 1;
56
57 CustomTrackView::CustomTrackView(KdenliveDoc *doc, QGraphicsScene * projectscene, QWidget *parent)
58         : QGraphicsView(projectscene, parent), 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(QPoint()), m_document(doc), m_autoScroll(KdenliveSettings::autoscroll()), m_tracksHeight(KdenliveSettings::trackheight()) {
59     if (doc) m_commandStack = doc->commandStack();
60     else m_commandStack == NULL;
61     setMouseTracking(true);
62     setAcceptDrops(true);
63     m_animationTimer = new QTimeLine(800);
64     m_animationTimer->setFrameRange(0, 5);
65     m_animationTimer->setUpdateInterval(100);
66     m_animationTimer->setLoopCount(0);
67     m_tipColor = QColor(0, 192, 0, 200);
68     QColor border = QColor(255, 255, 255, 100);
69     m_tipPen.setColor(border);
70     m_tipPen.setWidth(3);
71     setContentsMargins(0, 0, 0, 0);
72     if (projectscene) {
73         m_cursorLine = projectscene->addLine(0, 0, 0, m_tracksHeight);
74         m_cursorLine->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIgnoresTransformations);
75         m_cursorLine->setZValue(1000);
76     }
77 }
78
79 void CustomTrackView::setContextMenu(QMenu *timeline, QMenu *clip, QMenu *transition) {
80     m_timelineContextMenu = timeline;
81     m_timelineContextClipMenu = clip;
82     m_timelineContextTransitionMenu = transition;
83 }
84
85 void CustomTrackView::checkAutoScroll() {
86     m_autoScroll = KdenliveSettings::autoscroll();
87 }
88
89 QList <TrackInfo> CustomTrackView::tracksList() const {
90     return m_tracksList;
91 }
92
93 void CustomTrackView::checkTrackHeight() {
94     if (m_tracksHeight == KdenliveSettings::trackheight()) return;
95     m_tracksHeight = KdenliveSettings::trackheight();
96     emit trackHeightChanged();
97     QList<QGraphicsItem *> itemList = items();
98     ClipItem *item;
99     Transition *transitionitem;
100     for (int i = 0; i < itemList.count(); i++) {
101         if (itemList.at(i)->type() == AVWIDGET) {
102             item = (ClipItem*) itemList.at(i);
103             item->setRect(item->rect().x(), item->track() * m_tracksHeight, item->rect().width(), m_tracksHeight - 1);
104             item->resetThumbs();
105         } else if (itemList.at(i)->type() == TRANSITIONWIDGET) {
106             transitionitem = (Transition*) itemList.at(i);
107             transitionitem->setRect(transitionitem->rect().x(), transitionitem->track() * m_tracksHeight + m_tracksHeight / 2, transitionitem->rect().width(), m_tracksHeight - 1);
108         }
109     }
110     m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_tracksList.count());
111     setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_tracksList.count());
112     verticalScrollBar()->setMaximum(m_tracksHeight * m_tracksList.count());
113     update();
114 }
115
116 // virtual
117 void CustomTrackView::resizeEvent(QResizeEvent * event) {
118     QGraphicsView::resizeEvent(event);
119 }
120
121 // virtual
122 void CustomTrackView::wheelEvent(QWheelEvent * e) {
123     if (e->modifiers() == Qt::ControlModifier) {
124         if (e->delta() > 0) emit zoomIn();
125         else emit zoomOut();
126     } else {
127         if (e->delta() > 0) horizontalScrollBar()->setValue(horizontalScrollBar()->value() + horizontalScrollBar()->singleStep());
128         else  horizontalScrollBar()->setValue(horizontalScrollBar()->value() - horizontalScrollBar()->singleStep());
129     }
130 }
131
132 int CustomTrackView::getPreviousVideoTrack(int track) {
133     track = m_tracksList.count() - track - 1;
134     int videoTracksCount = 0;
135     track --;
136     for (int i = track; i > -1; i--) {
137         if (m_tracksList.at(i).type == VIDEOTRACK) return i + 1;
138     }
139     return 0;
140 }
141
142 // virtual
143 void CustomTrackView::mouseMoveEvent(QMouseEvent * event) {
144     int pos = event->x();
145     emit mousePosition((int)(mapToScene(event->pos()).x() / m_scale));
146     /*if (event->modifiers() == Qt::ControlModifier)
147       setDragMode(QGraphicsView::ScrollHandDrag);
148     else if (event->modifiers() == Qt::ShiftModifier)
149       setDragMode(QGraphicsView::RubberBandDrag);
150     else*/
151     {
152
153         if (m_dragItem) { //event->button() == Qt::LeftButton) {
154             // a button was pressed, delete visual tips
155             if (m_operationMode == MOVE) {
156                 double snappedPos = getSnapPointForPos(mapToScene(event->pos()).x() - m_clickPoint.x());
157                 //kDebug() << "///////  MOVE CLIP, EVENT Y: "<<m_clickPoint.y();//<<event->scenePos().y()<<", SCENE HEIGHT: "<<scene()->sceneRect().height();
158                 int moveTrack = (int)  mapToScene(event->pos() + QPoint(0, (m_dragItem->type() == TRANSITIONWIDGET ? m_tracksHeight - m_clickPoint.y() : 0))).y() / m_tracksHeight;
159                 int currentTrack = m_dragItem->track();
160
161                 if (moveTrack > m_tracksList.count() - 1) moveTrack = m_tracksList.count() - 1;
162                 else if (moveTrack < 0) moveTrack = 0;
163
164                 int offset = moveTrack - currentTrack;
165                 if (offset != 0) offset = m_tracksHeight * offset;
166                 m_dragItem->moveTo((int)(snappedPos / m_scale), m_scale, offset, moveTrack);
167             } else if (m_operationMode == RESIZESTART) {
168                 double snappedPos = getSnapPointForPos(mapToScene(event->pos()).x());
169                 m_dragItem->resizeStart((int)(snappedPos / m_scale), m_scale);
170             } else if (m_operationMode == RESIZEEND) {
171                 double snappedPos = getSnapPointForPos(mapToScene(event->pos()).x());
172                 m_dragItem->resizeEnd((int)(snappedPos / m_scale), m_scale);
173             } else if (m_operationMode == FADEIN) {
174                 int pos = (int)(mapToScene(event->pos()).x() / m_scale);
175                 m_dragItem->setFadeIn((int)(pos - m_dragItem->startPos().frames(m_document->fps())), m_scale);
176             } else if (m_operationMode == FADEOUT) {
177                 int pos = (int)(mapToScene(event->pos()).x() / m_scale);
178                 m_dragItem->setFadeOut((int)(m_dragItem->endPos().frames(m_document->fps()) - pos), m_scale);
179             }
180
181             if (m_animation) delete m_animation;
182             m_animation = NULL;
183             if (m_visualTip) delete m_visualTip;
184             m_visualTip = NULL;
185             QGraphicsView::mouseMoveEvent(event);
186             return;
187         }
188
189         QList<QGraphicsItem *> itemList = items(event->pos());
190         QGraphicsRectItem *item = NULL;
191         for (int i = 0; i < itemList.count(); i++) {
192             if (itemList.at(i)->type() == AVWIDGET || itemList.at(i)->type() == TRANSITIONWIDGET) {
193                 item = (QGraphicsRectItem*) itemList.at(i);
194                 break;
195             }
196         }
197         if (item && event->buttons() == Qt::NoButton) {
198             AbstractClipItem *clip = (AbstractClipItem*) item;
199             OPERATIONTYPE opMode = opMode = clip->operationMode(mapToScene(event->pos()), m_scale);
200             double size = 8;
201
202             if (opMode == m_moveOpMode) {
203                 QGraphicsView::mouseMoveEvent(event);
204                 return;
205             } else {
206                 if (m_visualTip) {
207                     if (m_animation) delete m_animation;
208                     m_animation = NULL;
209                     m_animationTimer->stop();
210                     delete m_visualTip;
211                     m_visualTip = NULL;
212                 }
213             }
214             m_moveOpMode = opMode;
215             if (opMode == MOVE) {
216                 setCursor(Qt::OpenHandCursor);
217             } else if (opMode == RESIZESTART) {
218                 setCursor(KCursor("left_side", Qt::SizeHorCursor));
219                 kDebug() << "********  RESIZE CLIP START; WIDTH: " << size;
220                 if (m_visualTip == NULL) {
221                     QPolygon polygon;
222                     polygon << QPoint((int)clip->rect().x(), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2));
223                     polygon << QPoint((int)(clip->rect().x() + size * 2), (int)(clip->rect().y() + clip->rect().height() / 2));
224                     polygon << QPoint((int)clip->rect().x(), (int)(clip->rect().y() + clip->rect().height() / 2 + size * 2));
225                     polygon << QPoint((int)clip->rect().x(), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2));
226
227                     m_visualTip = new QGraphicsPolygonItem(polygon);
228                     ((QGraphicsPolygonItem*) m_visualTip)->setBrush(m_tipColor);
229                     ((QGraphicsPolygonItem*) m_visualTip)->setPen(m_tipPen);
230                     m_visualTip->setZValue(100);
231                     m_animation = new QGraphicsItemAnimation;
232                     m_animation->setItem(m_visualTip);
233                     m_animation->setTimeLine(m_animationTimer);
234                     m_visualTip->setPos(0, 0);
235                     double scale = 2.0;
236                     m_animation->setScaleAt(.5, scale, 1);
237                     m_animation->setPosAt(.5, QPointF(clip->rect().x() - clip->rect().x() * scale, 0));
238                     scale = 1.0;
239                     m_animation->setScaleAt(1, scale, 1);
240                     m_animation->setPosAt(1, QPointF(clip->rect().x() - clip->rect().x() * scale, 0));
241                     scene()->addItem(m_visualTip);
242                     m_animationTimer->start();
243                 }
244             } else if (opMode == RESIZEEND) {
245                 setCursor(KCursor("right_side", Qt::SizeHorCursor));
246                 if (m_visualTip == NULL) {
247                     QPolygon polygon;
248                     polygon << QPoint((int)(clip->rect().x() + clip->rect().width()), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2));
249                     polygon << QPoint((int)(clip->rect().x() + clip->rect().width() - size * 2), (int)(clip->rect().y() + clip->rect().height() / 2));
250                     polygon << QPoint((int)(clip->rect().x() + clip->rect().width()), (int)(clip->rect().y() + clip->rect().height() / 2 + size * 2));
251                     polygon << QPoint((int)(clip->rect().x() + clip->rect().width()), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2));
252
253                     m_visualTip = new QGraphicsPolygonItem(polygon);
254                     ((QGraphicsPolygonItem*) m_visualTip)->setBrush(m_tipColor);
255                     ((QGraphicsPolygonItem*) m_visualTip)->setPen(m_tipPen);
256
257                     m_visualTip->setZValue(100);
258                     m_animation = new QGraphicsItemAnimation;
259                     m_animation->setItem(m_visualTip);
260                     m_animation->setTimeLine(m_animationTimer);
261                     m_visualTip->setPos(0, 0);
262                     double scale = 2.0;
263                     m_animation->setScaleAt(.5, scale, 1);
264                     m_animation->setPosAt(.5, QPointF(clip->rect().x() - clip->rect().x() * scale - clip->rect().width(), 0));
265                     scale = 1.0;
266                     m_animation->setScaleAt(1, scale, 1);
267                     m_animation->setPosAt(1, QPointF(clip->rect().x() - clip->rect().x() * scale, 0));
268                     scene()->addItem(m_visualTip);
269                     m_animationTimer->start();
270                 }
271             } else if (opMode == FADEIN) {
272                 if (m_visualTip == NULL) {
273                     m_visualTip = new QGraphicsEllipseItem(clip->rect().x() + clip->fadeIn() * m_scale - size, clip->rect().y() - 8, size * 2, 16);
274                     ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor);
275                     ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen);
276                     m_visualTip->setZValue(100);
277                     m_animation = new QGraphicsItemAnimation;
278                     m_animation->setItem(m_visualTip);
279                     m_animation->setTimeLine(m_animationTimer);
280                     m_visualTip->setPos(0, 0);
281                     double scale = 2.0;
282                     m_animation->setScaleAt(.5, scale, scale);
283                     m_animation->setPosAt(.5, QPointF(clip->rect().x() - clip->rect().x() * scale -  clip->fadeIn() * m_scale, clip->rect().y() - clip->rect().y() * scale));
284                     scale = 1.0;
285                     m_animation->setScaleAt(1, scale, scale);
286                     m_animation->setPosAt(1, QPointF(clip->rect().x() - clip->rect().x() * scale, clip->rect().y() - clip->rect().y() * scale));
287                     scene()->addItem(m_visualTip);
288                     m_animationTimer->start();
289                 }
290                 setCursor(Qt::PointingHandCursor);
291             } else if (opMode == FADEOUT) {
292                 if (m_visualTip == NULL) {
293                     m_visualTip = new QGraphicsEllipseItem(clip->rect().x() + clip->rect().width() - clip->fadeOut() * m_scale - size, clip->rect().y() - 8, size*2, 16);
294                     ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor);
295                     ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen);
296                     m_visualTip->setZValue(100);
297                     m_animation = new QGraphicsItemAnimation;
298                     m_animation->setItem(m_visualTip);
299                     m_animation->setTimeLine(m_animationTimer);
300                     m_visualTip->setPos(0, 0);
301                     double scale = 2.0;
302                     m_animation->setScaleAt(.5, scale, scale);
303                     m_animation->setPosAt(.5, QPointF(clip->rect().x() - clip->rect().x() * scale - clip->rect().width() + clip->fadeOut() * m_scale, clip->rect().y() - clip->rect().y() * scale));
304                     scale = 1.0;
305                     m_animation->setScaleAt(1, scale, scale);
306                     m_animation->setPosAt(1, QPointF(clip->rect().x() - clip->rect().x() * scale, clip->rect().y() - clip->rect().y() * scale));
307                     scene()->addItem(m_visualTip);
308                     m_animationTimer->start();
309                 }
310                 setCursor(Qt::PointingHandCursor);
311             } else if (opMode == TRANSITIONSTART) {
312                 if (m_visualTip == NULL) {
313                     m_visualTip = new QGraphicsEllipseItem(-5, -5 , 10, 10);
314                     ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor);
315                     ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen);
316                     m_visualTip->setZValue(100);
317                     m_animation = new QGraphicsItemAnimation;
318                     m_animation->setItem(m_visualTip);
319                     m_animation->setTimeLine(m_animationTimer);
320                     m_visualTip->setPos(clip->rect().x() + 15, clip->rect().y() + clip->rect().height() / 2);
321                     double scale = 2.0;
322                     m_animation->setScaleAt(.5, scale, scale);
323                     scale = 1.0;
324                     m_animation->setScaleAt(1, scale, scale);
325                     scene()->addItem(m_visualTip);
326                     m_animationTimer->start();
327                 }
328                 setCursor(Qt::PointingHandCursor);
329             } else if (opMode == TRANSITIONEND) {
330                 if (m_visualTip == NULL) {
331                     m_visualTip = new QGraphicsEllipseItem(-5, -5 , 10, 10);
332                     ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor);
333                     ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen);
334                     m_visualTip->setZValue(100);
335                     m_animation = new QGraphicsItemAnimation;
336                     m_animation->setItem(m_visualTip);
337                     m_animation->setTimeLine(m_animationTimer);
338                     m_visualTip->setPos(clip->rect().x() + clip->rect().width() - 15 , clip->rect().y() + clip->rect().height() / 2);
339                     double scale = 2.0;
340                     m_animation->setScaleAt(.5, scale, scale);
341                     scale = 1.0;
342                     m_animation->setScaleAt(1, scale, scale);
343                     scene()->addItem(m_visualTip);
344                     m_animationTimer->start();
345                 }
346                 setCursor(Qt::PointingHandCursor);
347             }
348         } else {
349             m_moveOpMode = NONE;
350             if (event->buttons() != Qt::NoButton && event->modifiers() == Qt::NoModifier) {
351                 setCursorPos((int)(mapToScene(event->pos().x(), 0).x() / m_scale));
352             }
353             if (m_visualTip) {
354                 if (m_animation) delete m_animation;
355                 m_animationTimer->stop();
356                 m_animation = NULL;
357                 delete m_visualTip;
358                 m_visualTip = NULL;
359
360             }
361             setCursor(Qt::ArrowCursor);
362         }
363     }
364     QGraphicsView::mouseMoveEvent(event);
365 }
366
367 // virtual
368 void CustomTrackView::mousePressEvent(QMouseEvent * event) {
369     activateMonitor();
370     int pos = event->x();
371     if (event->modifiers() == Qt::ControlModifier) {
372         setDragMode(QGraphicsView::ScrollHandDrag);
373         QGraphicsView::mousePressEvent(event);
374         return;
375     } else if (event->modifiers() == Qt::ShiftModifier) {
376         setDragMode(QGraphicsView::RubberBandDrag);
377         QGraphicsView::mousePressEvent(event);
378         return;
379     } else {
380         bool collision = false;
381         QList<QGraphicsItem *> collisionList = items(event->pos());
382         AbstractClipItem *clipItem = NULL, *transitionItem = NULL;
383         for (int i = 0; i < collisionList.size(); ++i) {
384             QGraphicsItem *item = collisionList.at(i);
385             if (item->type() == AVWIDGET || item->type() == TRANSITIONWIDGET) {
386                 // select item
387                 if (!item->isSelected()) {
388
389                     item->setSelected(true);
390                     update();
391                 }
392
393                 m_dragItem = (AbstractClipItem *) item;
394                 if (item->type() == AVWIDGET) {
395                     clipItem = m_dragItem;
396                 } else if (item->type() == TRANSITIONWIDGET) {
397                     transitionItem = m_dragItem;
398                 }
399                 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()));
400                 m_operationMode = m_dragItem->operationMode(item->mapFromScene(mapToScene(event->pos())), m_scale);
401                 if (m_operationMode == MOVE) setCursor(Qt::ClosedHandCursor);
402                 if (m_operationMode == MOVE || m_operationMode == RESIZESTART)
403                     m_startPos = QPointF(m_dragItem->startPos().frames(m_document->fps()), m_dragItem->track());
404                 else if (m_operationMode == RESIZEEND)
405                     m_startPos = QPointF(m_dragItem->endPos().frames(m_document->fps()), m_dragItem->track());
406                 else if (m_operationMode == TRANSITIONSTART) {
407                     Transition *tr = new Transition(
408                         QRect((int)(m_dragItem->startPos().frames(m_document->fps()) *m_scale) , (int)(m_dragItem->rect().y() + m_dragItem->rect().height() / 2),
409                               (int)(GenTime(2.5).frames(m_document->fps()) *m_scale) , (int)(m_dragItem->rect().height())
410                              ),
411                         (ClipItem*)m_dragItem, "luma" , m_dragItem->startPos(), m_dragItem->startPos() + GenTime(2.5), m_document->fps());
412                     tr->setTrack(m_dragItem->track());
413                     scene()->addItem(tr);
414                     //m_dragItem->addTransition(tra);
415                 }
416                 updateSnapPoints(m_dragItem);
417                 kDebug() << "//////// ITEM CLICKED: " << m_startPos;
418                 collision = true;
419                 break;
420             }
421         }
422         emit clipItemSelected((ClipItem*) clipItem);
423         emit transitionItemSelected((Transition*) transitionItem);
424         if (!collision) {
425             kDebug() << "//////// NO ITEM FOUND ON CLICK";
426             m_dragItem = NULL;
427             setCursor(Qt::ArrowCursor);
428             QList<QGraphicsItem *> itemList = items();
429             for (int i = 0; i < itemList.count(); i++)
430                 itemList.at(i)->setSelected(false);
431             //emit clipItemSelected(NULL);
432             if (event->button() == Qt::RightButton) {
433                 displayContextMenu(event->globalPos());
434             } else setCursorPos((int)(mapToScene(event->x(), 0).x() / m_scale));
435         } else if (event->button() == Qt::RightButton) {
436             m_operationMode = NONE;
437             displayContextMenu(event->globalPos(), (ClipItem *) m_dragItem);
438             m_dragItem = NULL;
439         }
440     }
441     //kDebug()<<pos;
442     //QGraphicsView::mousePressEvent(event);
443 }
444
445 void CustomTrackView::displayContextMenu(QPoint pos, ClipItem *clip) {
446     m_timelineContextClipMenu->popup(pos);
447 }
448
449 void CustomTrackView::activateMonitor() {
450     emit activateDocumentMonitor();
451 }
452
453 void CustomTrackView::dragEnterEvent(QDragEnterEvent * event) {
454     if (event->mimeData()->hasFormat("kdenlive/producerslist")) {
455         kDebug() << "///////////////  DRAG ENTERED, TEXT: " << event->mimeData()->data("kdenlive/producerslist");
456         QStringList ids = QString(event->mimeData()->data("kdenlive/producerslist")).split(";");
457         //TODO: drop of several clips
458         for (int i = 0; i < ids.size(); ++i) {
459         }
460         DocClipBase *clip = m_document->getBaseClip(ids.at(0).toInt());
461         if (clip == NULL) kDebug() << " WARNING))))))))) CLIP NOT FOUND : " << ids.at(0).toInt();
462         addItem(clip, event->pos());
463         event->acceptProposedAction();
464     } else QGraphicsView::dragEnterEvent(event);
465 }
466
467 void CustomTrackView::slotRefreshEffects(ClipItem *clip) {
468     int track = m_tracksList.count() - clip->track();
469     GenTime pos = clip->startPos();
470     m_document->renderer()->mltRemoveEffect(track, pos, "-1", false);
471     for (int i = 0; i < clip->effectsCount(); i++) {
472         m_document->renderer()->mltAddEffect(track, pos, clip->getEffectArgs(clip->effectAt(i)), false);
473     }
474     m_document->renderer()->doRefresh();
475 }
476
477 void CustomTrackView::addEffect(int track, GenTime pos, QDomElement effect) {
478     ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_tracksList.count() - track);
479     if (clip) {
480         QMap <QString, QString> effectParams = clip->addEffect(effect);
481         m_document->renderer()->mltAddEffect(track, pos, effectParams);
482         emit clipItemSelected(clip);
483     }
484 }
485
486 void CustomTrackView::deleteEffect(int track, GenTime pos, QDomElement effect) {
487     QString index = effect.attribute("kdenlive_ix");
488     m_document->renderer()->mltRemoveEffect(track, pos, index);
489     ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_tracksList.count() - track);
490     if (clip) {
491         clip->deleteEffect(index);
492         emit clipItemSelected(clip);
493     }
494 }
495
496 void CustomTrackView::slotAddEffect(QDomElement effect, GenTime pos, int track) {
497     QList<QGraphicsItem *> itemList;
498     if (track == -1)
499         itemList = items();
500     else {
501         ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, track);
502         if (clip) itemList.append(clip);
503         else kDebug() << "------   wrning, clip eff not found";
504     }
505     kDebug() << "// REQUESTING EFFECT ON CLIP: " << pos.frames(25) << ", TRK: " << track;
506     for (int i = 0; i < itemList.count(); i++) {
507         if (itemList.at(i)->type() == AVWIDGET && itemList.at(i)->isSelected()) {
508             ClipItem *item = (ClipItem *)itemList.at(i);
509             // the kdenlive_ix int is used to identify an effect in mlt's playlist, should
510             // not be changed
511             if (effect.attribute("kdenlive_ix").toInt() == 0)
512                 effect.setAttribute("kdenlive_ix", QString::number(item->effectsCounter()));
513             AddEffectCommand *command = new AddEffectCommand(this, m_tracksList.count() - item->track(), item->startPos(), effect, true);
514             m_commandStack->push(command);
515         }
516     }
517     m_document->setModified(true);
518 }
519
520 void CustomTrackView::slotDeleteEffect(ClipItem *clip, QDomElement effect) {
521     AddEffectCommand *command = new AddEffectCommand(this, m_tracksList.count() - clip->track(), clip->startPos(), effect, false);
522     m_commandStack->push(command);
523     m_document->setModified(true);
524 }
525
526 void CustomTrackView::updateEffect(int track, GenTime pos, QDomElement effect) {
527     ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_tracksList.count() - track);
528     if (clip) {
529         QMap <QString, QString> effectParams = clip->getEffectArgs(effect);
530         if (effectParams["disabled"] == "1") {
531             QString index = effectParams["kdenlive_ix"];
532             m_document->renderer()->mltRemoveEffect(track, pos, index);
533         } else m_document->renderer()->mltEditEffect(m_tracksList.count() - clip->track(), clip->startPos(), effectParams);
534     }
535     m_document->setModified(true);
536 }
537
538 void CustomTrackView::slotChangeEffectState(ClipItem *clip, QDomElement effect, bool disable) {
539     QDomElement oldEffect = effect.cloneNode().toElement();
540     effect.setAttribute("disabled", disable);
541     EditEffectCommand *command = new EditEffectCommand(this, m_tracksList.count() - clip->track(), clip->startPos(), oldEffect, effect, true);
542     m_commandStack->push(command);
543     m_document->setModified(true);
544 }
545
546 void CustomTrackView::slotUpdateClipEffect(ClipItem *clip, QDomElement oldeffect, QDomElement effect) {
547     EditEffectCommand *command = new EditEffectCommand(this, m_tracksList.count() - clip->track(), clip->startPos(), oldeffect, effect, true);
548     m_commandStack->push(command);
549 }
550
551 void CustomTrackView::slotAddTransition(ClipItem* clip , QDomElement transition, GenTime startTime , int startTrack) {
552     AddTransitionCommand* command = new AddTransitionCommand(this, startTrack, transition, startTime, true);
553     m_commandStack->push(command);
554     m_document->setModified(true);
555 }
556
557 void CustomTrackView::addTransition(int startTrack, GenTime startPos , QDomElement e) {
558
559     kDebug() << "---- ADDING transition " << e.attribute("tag") << ", on tracks " << m_tracksList.count() - e.attribute("transition_track").toInt() << " / " << getPreviousVideoTrack(e.attribute("transition_track").toInt());
560     m_document->renderer()->mltAddTransition(e.attribute("tag"), getPreviousVideoTrack(e.attribute("transition_track").toInt()), m_tracksList.count() - e.attribute("transition_track").toInt() ,
561             GenTime(e.attribute("start").toInt(), m_document->renderer()->fps()),
562             GenTime(e.attribute("end").toInt(), m_document->renderer()->fps()),
563             e);
564
565     m_document->setModified(true);
566 }
567
568 void CustomTrackView::deleteTransition(int, GenTime, QDomElement e) {
569     QMap < QString, QString> map;
570     QDomNamedNodeMap attribs = e.attributes();
571     m_document->renderer()->mltDeleteTransition(e.attribute("tag"), getPreviousVideoTrack(e.attribute("transition_track").toInt()), m_tracksList.count() - e.attribute("transition_track").toInt() ,
572             GenTime(e.attribute("start").toInt(), m_document->renderer()->fps()),
573             GenTime(e.attribute("end").toInt(), m_document->renderer()->fps()),
574             e);
575     m_document->setModified(true);
576 }
577
578 void CustomTrackView::slotTransitionUpdated(QDomElement old, QDomElement newEffect) {
579     EditTransitionCommand *command = new EditTransitionCommand(this, newEffect.attribute("a_track").toInt(), GenTime(newEffect.attribute("start").toInt(), m_document->renderer()->fps()) , old, newEffect , true);
580     m_commandStack->push(command);
581     m_document->setModified(true);
582 }
583
584 void CustomTrackView::updateTransition(int track, GenTime pos, QDomElement oldTransition, QDomElement transition) {
585
586     m_document->renderer()->mltUpdateTransition(oldTransition.attribute("tag"), transition.attribute("tag"), m_tracksList.count() - 1  - transition.attribute("transition_track").toInt(), m_tracksList.count() - transition.attribute("transition_track").toInt() ,
587             GenTime(transition.attribute("start").toInt(), m_document->renderer()->fps()),
588             GenTime(transition.attribute("end").toInt(), m_document->renderer()->fps()),
589             transition);
590     repaint();
591     m_document->setModified(true);
592 }
593
594 void CustomTrackView::addItem(DocClipBase *clip, QPoint pos) {
595     int in = 0;
596     GenTime out = clip->duration();
597     //kdDebug()<<"- - - -CREATING CLIP, duration = "<<out<<", URL: "<<clip->fileURL();
598     int trackTop = (int)(mapToScene(pos).y() / m_tracksHeight) * m_tracksHeight + 1;
599     m_dropItem = new ClipItem(clip, (int)(mapToScene(pos).y() / m_tracksHeight), GenTime(), QRectF(mapToScene(pos).x() * m_scale, trackTop, out.frames(m_document->fps()) * m_scale, m_tracksHeight - 1), out, m_document->fps());
600     scene()->addItem(m_dropItem);
601 }
602
603
604 void CustomTrackView::dragMoveEvent(QDragMoveEvent * event) {
605     event->setDropAction(Qt::IgnoreAction);
606     //kDebug()<<"+++++++++++++   DRAG MOVE, : "<<mapToScene(event->pos()).x()<<", SCAL: "<<m_scale;
607     if (m_dropItem) {
608         int track = (int)(event->pos().y() / m_tracksHeight);  //) * (m_scale * 50) + m_scale;
609         m_dropItem->moveTo((int)(mapToScene(event->pos()).x() / m_scale), m_scale, (int)((track - m_dropItem->track()) * m_tracksHeight), track);
610         event->setDropAction(Qt::MoveAction);
611         if (event->mimeData()->hasFormat("kdenlive/producerslist")) {
612             event->acceptProposedAction();
613         }
614     } else {
615         QGraphicsView::dragMoveEvent(event);
616     }
617 }
618
619 void CustomTrackView::dragLeaveEvent(QDragLeaveEvent * event) {
620     if (m_dropItem) {
621         delete m_dropItem;
622         m_dropItem = NULL;
623     } else QGraphicsView::dragLeaveEvent(event);
624 }
625
626 void CustomTrackView::dropEvent(QDropEvent * event) {
627     if (m_dropItem) {
628         AddTimelineClipCommand *command = new AddTimelineClipCommand(this, m_dropItem->xml(), m_dropItem->clipProducer(), m_dropItem->track(), m_dropItem->startPos(), m_dropItem->rect(), m_dropItem->duration(), false, false);
629         m_commandStack->push(command);
630         m_dropItem->baseClip()->addReference();
631         m_document->updateClip(m_dropItem->baseClip()->getId());
632         // kDebug()<<"IIIIIIIIIIIIIIIIIIIIIIII TRAX CNT: "<<m_tracksList.count()<<", DROP: "<<m_dropItem->track();
633         m_document->renderer()->mltInsertClip(m_tracksList.count() - m_dropItem->track(), m_dropItem->startPos(), m_dropItem->xml());
634         m_document->setModified(true);
635     } else QGraphicsView::dropEvent(event);
636     m_dropItem = NULL;
637 }
638
639
640 QStringList CustomTrackView::mimeTypes() const {
641     QStringList qstrList;
642     // list of accepted mime types for drop
643     qstrList.append("text/plain");
644     qstrList.append("kdenlive/producerslist");
645     return qstrList;
646 }
647
648 Qt::DropActions CustomTrackView::supportedDropActions() const {
649     // returns what actions are supported when dropping
650     return Qt::MoveAction;
651 }
652
653 void CustomTrackView::setDuration(int duration) {
654     kDebug() << "/////////////  PRO DUR: " << duration << ", SCALE. " << (m_projectDuration + 500) * m_scale << ", height: " << 50 * m_tracksList.count();
655     m_projectDuration = duration;
656     setSceneRect(0, 0, (m_projectDuration + 100) * m_scale, sceneRect().height());
657 }
658
659 int CustomTrackView::duration() const {
660     return m_projectDuration;
661 }
662
663 void CustomTrackView::addTrack(TrackInfo type) {
664     m_tracksList << type;
665     m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_tracksList.count());
666     setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_tracksList.count());
667     verticalScrollBar()->setMaximum(m_tracksHeight * m_tracksList.count());
668     //setFixedHeight(50 * m_tracksCount);
669 }
670
671 void CustomTrackView::removeTrack() {
672     // TODO: implement track deletion
673     //m_tracksCount--;
674     m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_tracksList.count());
675 }
676
677
678 void CustomTrackView::slotSwitchTrackAudio(int ix) {
679     int tracknumber = m_tracksList.count() - ix;
680     kDebug() << "/////  MUTING TRK: " << ix << "; PL NUM: " << tracknumber;
681     m_tracksList[tracknumber - 1].isMute = !m_tracksList.at(tracknumber - 1).isMute;
682     m_document->renderer()->mltChangeTrackState(tracknumber, m_tracksList.at(tracknumber - 1).isMute, m_tracksList.at(tracknumber - 1).isBlind);
683 }
684
685 void CustomTrackView::slotSwitchTrackVideo(int ix) {
686     int tracknumber = m_tracksList.count() - ix;
687     m_tracksList[tracknumber - 1].isBlind = !m_tracksList.at(tracknumber - 1).isBlind;
688     m_document->renderer()->mltChangeTrackState(tracknumber, m_tracksList.at(tracknumber - 1).isMute, m_tracksList.at(tracknumber - 1).isBlind);
689 }
690
691 void CustomTrackView::deleteClip(int clipId) {
692     QList<QGraphicsItem *> itemList = items();
693     for (int i = 0; i < itemList.count(); i++) {
694         if (itemList.at(i)->type() == AVWIDGET) {
695             ClipItem *item = (ClipItem *)itemList.at(i);
696             if (item->clipProducer() == clipId) {
697                 AddTimelineClipCommand *command = new AddTimelineClipCommand(this, item->xml(), item->clipProducer(), item->track(), item->startPos(), item->rect(), item->duration(), true, true);
698                 m_commandStack->push(command);
699                 //delete item;
700             }
701         }
702     }
703 }
704
705 void CustomTrackView::setCursorPos(int pos, bool seek) {
706     emit cursorMoved((int)(m_cursorPos * m_scale), (int)(pos * m_scale));
707     m_cursorPos = pos;
708     m_cursorLine->setPos(pos * m_scale, 0);
709     if (seek) m_document->renderer()->seek(GenTime(pos, m_document->fps()));
710     else if (m_autoScroll && m_scale < 50) checkScrolling();
711 }
712
713 void CustomTrackView::updateCursorPos() {
714     m_cursorLine->setPos(m_cursorPos * m_scale, 0);
715 }
716
717 int CustomTrackView::cursorPos() {
718     return (int)(m_cursorPos * m_scale);
719 }
720
721 void CustomTrackView::checkScrolling() {
722     QRect rectInView = viewport()->rect();
723     int delta = rectInView.width() / 3;
724     int max = rectInView.right() + horizontalScrollBar()->value() - delta;
725     //kDebug() << "CURSOR POS: "<<m_cursorPos<< "Scale: "<<m_scale;
726     if (m_cursorPos * m_scale >= max) horizontalScrollBar()->setValue((int)(horizontalScrollBar()->value() + 1 + m_scale));
727 }
728
729 void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
730     QGraphicsView::mouseReleaseEvent(event);
731     setDragMode(QGraphicsView::NoDrag);
732     if (m_dragItem == NULL) return;
733     if (m_operationMode == MOVE) setCursor(Qt::OpenHandCursor);
734     if (m_operationMode == MOVE) {// && m_startPos.x() != m_dragItem->startPos().frames(m_document->fps())) {
735         // move clip
736         if (m_dragItem->type() == AVWIDGET) {
737             MoveClipCommand *command = new MoveClipCommand(this, m_startPos, QPointF(m_dragItem->startPos().frames(m_document->fps()), m_dragItem->track()), false);
738             m_commandStack->push(command);
739             m_document->renderer()->mltMoveClip((int)(m_tracksList.count() - m_startPos.y()), (int)(m_tracksList.count() - m_dragItem->track()), (int) m_startPos.x(), (int)(m_dragItem->startPos().frames(m_document->fps())));
740         }
741         if (m_dragItem->type() == TRANSITIONWIDGET) {
742             Transition* transition = (Transition*)m_dragItem;
743             GenTime oldin = transition->transitionStartTime();
744             GenTime oldout = transition->transitionEndTime();
745             GenTime newin = m_dragItem->startPos();
746             GenTime newout = newin + (oldout - oldin);
747             transition->moveTransition(newin - oldin);
748             MoveTransitionCommand *command = new MoveTransitionCommand(this, QPointF(oldin.frames(m_document->fps()), oldout.frames(m_document->fps())), QPointF(newin.frames(m_document->fps()), newout.frames(m_document->fps())), (int) m_startPos.y(), (int)(m_dragItem->track()), false);
749             m_commandStack->push(command);
750             //kDebug()<<"/// MOVING TRS FROM: "<<(int)(m_tracksList.count() - m_startPos.y())<<", OFFSET: "<<(int) (m_dragItem->track() - m_startPos.y());
751             m_document->renderer()->mltMoveTransition(transition->transitionName(), (int)(m_tracksList.count() - m_startPos.y()), (int)(m_startPos.y() - m_dragItem->track()), oldin, oldout, newin, newout);
752         }
753
754     } else if (m_operationMode == RESIZESTART) {
755         // resize start
756         ResizeClipCommand *command = new ResizeClipCommand(this, m_startPos, QPointF(m_dragItem->startPos().frames(m_document->fps()), m_dragItem->track()), true, false);
757
758         if (m_dragItem->type() == AVWIDGET) m_document->renderer()->mltResizeClipStart(m_tracksList.count() - m_dragItem->track(), m_dragItem->endPos(), m_dragItem->startPos(), GenTime((int)m_startPos.x(), m_document->fps()), m_dragItem->cropStart(), m_dragItem->cropStart() + m_dragItem->endPos() - m_dragItem->startPos());
759         m_commandStack->push(command);
760         m_document->renderer()->doRefresh();
761     } else if (m_operationMode == RESIZEEND) {
762         // resize end
763         ResizeClipCommand *command = new ResizeClipCommand(this, m_startPos, QPointF(m_dragItem->endPos().frames(m_document->fps()), m_dragItem->track()), false, false);
764
765         if (m_dragItem->type() == AVWIDGET) 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());
766         m_commandStack->push(command);
767         m_document->renderer()->doRefresh();
768     }
769     m_document->setModified(true);
770     m_operationMode = NONE;
771     m_dragItem = NULL;
772 }
773
774 void CustomTrackView::deleteClip(int track, GenTime startpos, const QRectF &rect) {
775     ClipItem *item = getClipItemAt(startpos, track);
776     if (!item) {
777         kDebug() << "----------------  ERROR, CANNOT find clip to move at: " << rect.x();
778         return;
779     }
780     item->baseClip()->removeReference();
781     m_document->updateClip(item->baseClip()->getId());
782     delete item;
783     m_document->renderer()->mltRemoveClip(m_tracksList.count() - track, startpos);
784     m_document->renderer()->doRefresh();
785 }
786
787 void CustomTrackView::deleteSelectedClips() {
788     QList<QGraphicsItem *> itemList = items();
789     for (int i = 0; i < itemList.count(); i++) {
790         if (itemList.at(i)->type() == AVWIDGET && itemList.at(i)->isSelected()) {
791             ClipItem *item = (ClipItem *) itemList.at(i);
792             AddTimelineClipCommand *command = new AddTimelineClipCommand(this, item->xml(), item->clipProducer(), item->track(), item->startPos(), item->rect(), item->duration(), true, true);
793             m_commandStack->push(command);
794         }
795     }
796 }
797
798 void CustomTrackView::addClip(QDomElement xml, int clipId, int track, GenTime startpos, const QRectF &rect, GenTime duration) {
799     QRect r((int)(startpos.frames(m_document->fps()) * m_scale), m_tracksHeight * track, (int)(duration.frames(m_document->fps()) * m_scale), m_tracksHeight - 1);
800     DocClipBase *baseclip = m_document->clipManager()->getClipById(clipId);
801     ClipItem *item = new ClipItem(baseclip, track, startpos, r, duration, m_document->fps());
802     scene()->addItem(item);
803     baseclip->addReference();
804     m_document->updateClip(baseclip->getId());
805     m_document->renderer()->mltInsertClip(m_tracksList.count() - track, startpos, xml);
806     m_document->renderer()->doRefresh();
807 }
808
809 ClipItem *CustomTrackView::getClipItemAt(int pos, int track) {
810     QList<QGraphicsItem *> list = scene()->items(QPointF(pos * m_scale, track * m_tracksHeight + m_tracksHeight / 2));
811     ClipItem *clip = NULL;
812     for (int i = 0; i < list.size(); ++i) {
813         if (list.at(i)->type() == AVWIDGET) {
814             clip = static_cast <ClipItem *>(list.at(i));
815             break;
816         }
817     }
818     return clip;
819 }
820
821 ClipItem *CustomTrackView::getClipItemAt(GenTime pos, int track) {
822     int framepos = (int)(pos.frames(m_document->fps()) * m_scale);
823     return getClipItemAt(framepos, track);
824 }
825
826 Transition *CustomTrackView::getTransitionItemAt(int pos, int track) {
827     QList<QGraphicsItem *> list = scene()->items(QPointF(pos * m_scale, track * m_tracksHeight + m_tracksHeight / 2));
828     Transition *clip = NULL;
829     for (int i = 0; i < list.size(); ++i) {
830         if (list.at(i)->type() == TRANSITIONWIDGET) {
831             clip = static_cast <Transition *>(list.at(i));
832             break;
833         }
834     }
835     return clip;
836 }
837
838 Transition *CustomTrackView::getTransitionItemAt(GenTime pos, int track) {
839     int framepos = (int)(pos.frames(m_document->fps()) * m_scale);
840     return getTransitionItemAt(framepos, track);
841 }
842
843 void CustomTrackView::moveClip(const QPointF &startPos, const QPointF &endPos) {
844     ClipItem *item = getClipItemAt((int)startPos.x() + 1, (int)startPos.y());
845     if (!item) {
846         kDebug() << "----------------  ERROR, CANNOT find clip to move at: " << startPos.x() * m_scale * FRAME_SIZE + 1 << ", " << startPos.y() * m_tracksHeight + m_tracksHeight / 2;
847         return;
848     }
849     kDebug() << "----------------  Move CLIP FROM: " << startPos.x() << ", END:" << endPos.x() << ",TRACKS: " << startPos.y() << " TO " << endPos.y();
850     item->moveTo((int)endPos.x(), m_scale, (int)((endPos.y() - startPos.y()) * m_tracksHeight), (int)endPos.y());
851     m_document->renderer()->mltMoveClip((int)(m_tracksList.count() - startPos.y()), (int)(m_tracksList.count() - endPos.y()), (int) startPos.x(), (int)endPos.x());
852 }
853
854 void CustomTrackView::moveTransition(const QPointF &startPos, const QPointF &endPos, int oldtrack, int newtrack) {
855     Transition *item = getTransitionItemAt((int)startPos.x() + 1, oldtrack);
856     if (!item) {
857         kDebug() << "----------------  ERROR, CANNOT find transition to move at: " << startPos.x() * m_scale * FRAME_SIZE + 1 << ", " << startPos.y() * m_tracksHeight + m_tracksHeight / 2;
858         return;
859     }
860     kDebug() << "----------------  Move TRANSITION FROM: " << startPos.x() << ", END:" << endPos.x() << ",TRACKS: " << oldtrack << " TO " << newtrack;
861     item->moveTo((int)endPos.x(), m_scale, (newtrack - oldtrack) * m_tracksHeight, newtrack);
862     //item->moveTransition(GenTime((int) (endPos.x() - startPos.x()), m_document->fps()));
863     m_document->renderer()->mltMoveTransition(item->transitionName(), m_tracksList.count() - oldtrack, oldtrack - newtrack, GenTime((int) startPos.x(), m_document->fps()), GenTime((int) startPos.y(), m_document->fps()), GenTime((int) endPos.x(), m_document->fps()), GenTime((int) endPos.y(), m_document->fps()));
864 }
865
866 void CustomTrackView::resizeClip(const QPointF &startPos, const QPointF &endPos, bool resizeClipStart) {
867     int offset;
868     if (resizeClipStart) offset = 1;
869     else offset = -1;
870     ClipItem *item = getClipItemAt((int)(startPos.x() + offset), (int) startPos.y());
871     if (!item) {
872         kDebug() << "----------------  ERROR, CANNOT find clip to resize at: " << startPos;
873         return;
874     }
875     qreal diff = endPos.x() - startPos.x();
876     if (resizeClipStart) {
877         m_document->renderer()->mltResizeClipStart(m_tracksList.count() - item->track(), item->endPos(), GenTime((int)endPos.x(), m_document->fps()), item->startPos(), item->cropStart() + GenTime((int)diff, m_document->fps()), item->cropStart() + GenTime((int)diff, m_document->fps()) + item->endPos() - GenTime((int)endPos.x(), m_document->fps()));
878         item->resizeStart((int)endPos.x(), m_scale);
879     } else {
880         m_document->renderer()->mltResizeClipEnd(m_tracksList.count() - item->track(), item->startPos(), item->cropStart(), item->cropStart() + GenTime((int)endPos.x(), m_document->fps()) - item->startPos());
881         item->resizeEnd((int)endPos.x(), m_scale);
882     }
883     m_document->renderer()->doRefresh();
884 }
885
886 double CustomTrackView::getSnapPointForPos(double pos) {
887     for (int i = 0; i < m_snapPoints.size(); ++i) {
888         if (abs((int)(pos - m_snapPoints.at(i).frames(m_document->fps()) * m_scale)) < 10) {
889             //kDebug()<<" FOUND SNAP POINT AT: "<<m_snapPoints.at(i)<<", current pos: "<<pos / m_scale;
890             return m_snapPoints.at(i).frames(m_document->fps()) * m_scale + 0.5;
891         }
892         if (m_snapPoints.at(i).frames(m_document->fps() * m_scale) > pos) break;
893     }
894     return pos;
895 }
896
897 void CustomTrackView::updateSnapPoints(AbstractClipItem *selected) {
898     m_snapPoints.clear();
899     GenTime offset;
900     if (selected) offset = selected->duration();
901     QList<QGraphicsItem *> itemList = items();
902     for (int i = 0; i < itemList.count(); i++) {
903         if (itemList.at(i)->type() == AVWIDGET && itemList.at(i) != selected) {
904             ClipItem *item = static_cast <ClipItem *>(itemList.at(i));
905             GenTime start = item->startPos();
906             GenTime end = item->endPos();
907             m_snapPoints.append(start);
908             m_snapPoints.append(end);
909             if (offset != GenTime()) {
910                 if (start > offset) m_snapPoints.append(start - offset);
911                 if (end > offset) m_snapPoints.append(end - offset);
912             }
913         } else if (itemList.at(i)->type() == TRANSITIONWIDGET) {
914             Transition *transition = static_cast <Transition*>(itemList.at(i));
915             GenTime start = transition->transitionStartTime();
916             GenTime end = transition->transitionEndTime();
917             m_snapPoints.append(start);
918             m_snapPoints.append(end);
919             if (offset != GenTime()) {
920                 if (start > offset) m_snapPoints.append(start - offset);
921                 if (end > offset) m_snapPoints.append(end - offset);
922             }
923         }
924     }
925     qSort(m_snapPoints);
926     //for (int i = 0; i < m_snapPoints.size(); ++i)
927     //    kDebug() << "SNAP POINT: " << m_snapPoints.at(i).frames(25);
928 }
929
930
931 void CustomTrackView::setScale(double scaleFactor) {
932     //scale(scaleFactor, scaleFactor);
933     double pos = cursorPos() / m_scale;
934     m_scale = scaleFactor;
935     kDebug() << " HHHHHHHH  SCALING: " << m_scale;
936     QList<QGraphicsItem *> itemList = items();
937
938     for (int i = 0; i < itemList.count(); i++) {
939         if (itemList.at(i)->type() == AVWIDGET || itemList.at(i)->type() == TRANSITIONWIDGET) {
940             AbstractClipItem *clip = (AbstractClipItem *)itemList.at(i);
941             clip->setRect(clip->startPos().frames(m_document->fps()) * m_scale, clip->rect().y(), clip->duration().frames(m_document->fps()) * m_scale, clip->rect().height());
942         }
943     }
944     updateCursorPos();
945     centerOn(QPointF(cursorPos(), m_tracksHeight));
946     setSceneRect(0, 0, (m_projectDuration + 100) * m_scale, sceneRect().height());
947 }
948
949 void CustomTrackView::drawBackground(QPainter * painter, const QRectF & rect) {
950     QRect rectInView = viewport()->rect();
951     rectInView.moveTo(horizontalScrollBar()->value(), verticalScrollBar()->value());
952
953     QColor base = palette().button().color();
954     painter->setClipRect(rect);
955     painter->drawLine(rectInView.left(), 0, rectInView.right(), 0);
956     uint max = m_tracksList.count();
957     for (uint i = 0; i < max;i++) {
958         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)));
959         painter->drawLine(rectInView.left(), m_tracksHeight * (i + 1), rectInView.right(), m_tracksHeight * (i + 1));
960         //painter->drawText(QRectF(10, 50 * i, 100, 50 * i + 49), Qt::AlignLeft, i18n(" Track ") + QString::number(i + 1));
961     }
962     int lowerLimit = m_tracksHeight * m_tracksList.count() + 1;
963     if (height() > lowerLimit)
964         painter->fillRect(QRectF(rectInView.left(), lowerLimit, rectInView.width(), height() - lowerLimit), QBrush(base));
965 }
966 /*
967 void CustomTrackView::drawForeground ( QPainter * painter, const QRectF & rect )
968 {
969   //kDebug()<<"/////  DRAWING FB: "<<rect.x()<<", width: "<<rect.width();
970   painter->fillRect(rect, QColor(50, rand() % 250,50,100));
971   painter->drawLine(m_cursorPos, rect.y(), m_cursorPos, rect.y() + rect.height());
972 }
973 */
974 #include "customtrackview.moc"