]> git.sesse.net Git - kdenlive/commitdiff
Rewrote the handling of timeline in QGraphicsView. Now we use the built in zoom featu...
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Sun, 17 Aug 2008 23:13:03 +0000 (23:13 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Sun, 17 Aug 2008 23:13:03 +0000 (23:13 +0000)
svn path=/branches/KDE4/; revision=2380

30 files changed:
src/CMakeLists.txt
src/abstractclipitem.cpp
src/abstractclipitem.h
src/abstractgroupitem.cpp [new file with mode: 0644]
src/abstractgroupitem.h [new file with mode: 0644]
src/clipitem.cpp
src/clipitem.h
src/customruler.cpp
src/customruler.h
src/customtrackscene.cpp [new file with mode: 0644]
src/customtrackscene.h [new file with mode: 0644]
src/customtrackview.cpp
src/customtrackview.h
src/definitions.h
src/events.h
src/guide.cpp
src/guide.h
src/kdenlivedoc.cpp
src/kdenlivedoc.h
src/kthumb.cpp
src/kthumb.h
src/mainwindow.cpp
src/profilesdialog.cpp
src/profilesdialog.h
src/renderer.cpp
src/renderer.h
src/trackview.cpp
src/trackview.h
src/transition.cpp
src/transition.h

index cf9c73750229bb0f7c2950f3b527f79679f11f48..0e61d2552c31d20c8daa5d6ad11626b2e06cf66a 100644 (file)
@@ -130,6 +130,8 @@ set(kdenlive_SRCS
   changespeedcommand.cpp
   geometryval.cpp
   wizard.cpp
+  customtrackscene.cpp
+  abstractgroupitem.cpp
 )
 
 kde4_add_kcfg_files(kdenlive_SRCS GENERATE_MOC kdenlivesettings.kcfgc )
index 29912987fe00d955e52ddcce09432cebec564db0..c0d8bb802b79eb0cc46aab2f653439ab50b9b810 100644 (file)
 #include <KLocale>
 
 #include "abstractclipitem.h"
+#include "customtrackscene.h"
 
 AbstractClipItem::AbstractClipItem(const ItemInfo info, const QRectF& rect, double fps): QGraphicsRectItem(rect), m_track(0), m_fps(fps), m_editedKeyframe(-1), m_selectedKeyframe(0), m_keyframeFactor(1) {
-    setFlags(QGraphicsItem::ItemClipsToShape | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
+    setFlags(/*QGraphicsItem::ItemClipsToShape | */QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
     setTrack(info.track);
     m_startPos = info.startPos;
     m_cropDuration = info.endPos - info.startPos;
@@ -44,45 +45,6 @@ ItemInfo AbstractClipItem::info() const {
     return itemInfo;
 }
 
-void AbstractClipItem::moveTo(int x, double scale, int offset, int newTrack, bool checkCollision) {
-    qreal origX = pos().x();
-    qreal origY = pos().y();
-    bool success = true;
-    if (x < 0) return;
-    //setRect(x * scale, origY + offset, rect().width(), rect().height());
-    //double xoffset = (x -  m_startPos.frames(m_fps)) * scale;// - origX;
-    setPos((qreal) x * scale, (qreal) pos().y() + offset);
-
-    QList <QGraphicsItem *> collisionList = collidingItems(Qt::IntersectsItemBoundingRect);
-    if (collisionList.size() == 0) m_track = newTrack;
-    if (checkCollision)
-        for (int i = 0; i < collisionList.size(); ++i) {
-            QGraphicsItem *item = collisionList.at(i);
-            if (item->type() == type()) {
-                if (offset == 0) {
-                    QRectF other = ((QGraphicsRectItem *)item)->rect();
-                    if (x < m_startPos.frames(m_fps)) {
-                        kDebug() << "COLLISION, MOVING TO------";
-                        m_startPos = ((AbstractClipItem *)item)->endPos();
-                        origX = (qreal) m_startPos.frames(m_fps) * scale;
-                    } else if (x > m_startPos.frames(m_fps)) {
-                        //kDebug() << "COLLISION, MOVING TO+++: "<<x<<", CLIP CURR POS: "<<m_startPos.frames(m_fps)<<", COLLIDING START: "<<((AbstractClipItem *)item)->startPos().frames(m_fps);
-                        m_startPos = ((AbstractClipItem *)item)->startPos() - m_cropDuration;
-                        origX = (qreal) m_startPos.frames(m_fps) * scale;
-                    }
-                }
-                setPos(origX, origY);
-                offset = 0;
-                success = false;
-                break;
-            }
-        }
-    if (success) {
-        m_track = newTrack;
-        m_startPos = GenTime(x, m_fps);
-    }
-}
-
 GenTime AbstractClipItem::endPos() const {
     return m_startPos + m_cropDuration;
 }
@@ -99,7 +61,7 @@ void AbstractClipItem::setCropStart(GenTime pos) {
     m_cropStart = pos;
 }
 
-void AbstractClipItem::resizeStart(int posx, double scale) {
+void AbstractClipItem::resizeStart(int posx) {
     GenTime durationDiff = GenTime(posx, m_fps) - m_startPos;
     if (durationDiff == GenTime()) return;
     //kDebug() << "-- RESCALE: CROP=" << m_cropStart << ", DIFF = " << durationDiff;
@@ -114,8 +76,8 @@ void AbstractClipItem::resizeStart(int posx, double scale) {
     if (type() == AVWIDGET) m_cropStart += durationDiff;
     m_cropDuration = m_cropDuration - durationDiff;
 
-    setRect(0, 0, (qreal) m_cropDuration.frames(m_fps) * scale - .5, rect().height());
-    setPos((qreal) m_startPos.frames(m_fps) * scale, pos().y());
+    setRect(0, 0, m_cropDuration.frames(m_fps) - 0.02, rect().height());
+    setPos((qreal) m_startPos.frames(m_fps), pos().y());
     //setRect((double) m_startPos.frames(m_fps) * scale, rect().y(), (double) m_cropDuration.frames(m_fps) * scale, rect().height());
     if (durationDiff < GenTime()) {
         QList <QGraphicsItem *> collisionList = collidingItems(Qt::IntersectsItemBoundingRect);
@@ -124,8 +86,8 @@ void AbstractClipItem::resizeStart(int posx, double scale) {
             if (item->type() == type() && item->pos().x() < pos().x()) {
                 kDebug() << "/////////  COLLISION DETECTED!!!!!!!!!";
                 GenTime diff = ((AbstractClipItem *)item)->endPos() + GenTime(1, m_fps) - m_startPos;
-                setRect(0, 0, (qreal)(m_cropDuration - diff).frames(m_fps) * scale - .5, rect().height());
-                setPos((qreal)(m_startPos + diff).frames(m_fps) * scale, pos().y());
+                setRect(0, 0, (m_cropDuration - diff).frames(m_fps) - 0.02, rect().height());
+                setPos((qreal)(m_startPos + diff).frames(m_fps), pos().y());
                 m_startPos += diff;
                 if (type() == AVWIDGET) m_cropStart += diff;
                 m_cropDuration = m_cropDuration - diff;
@@ -135,7 +97,7 @@ void AbstractClipItem::resizeStart(int posx, double scale) {
     }
 }
 
-void AbstractClipItem::resizeEnd(int posx, double scale) {
+void AbstractClipItem::resizeEnd(int posx) {
     GenTime durationDiff = GenTime(posx, m_fps) - endPos();
     if (durationDiff == GenTime()) return;
     //kDebug() << "-- RESCALE: CROP=" << m_cropStart << ", DIFF = " << durationDiff;
@@ -145,7 +107,7 @@ void AbstractClipItem::resizeEnd(int posx, double scale) {
         durationDiff = maxDuration() - m_cropDuration - m_cropStart;
     }
     m_cropDuration += durationDiff;
-    setRect(0, 0, (qreal) m_cropDuration.frames(m_fps) * scale - .5, rect().height());
+    setRect(0, 0, m_cropDuration.frames(m_fps) - 0.02, rect().height());
     if (durationDiff > GenTime()) {
         QList <QGraphicsItem *> collisionList = collidingItems(Qt::IntersectsItemBoundingRect);
         for (int i = 0; i < collisionList.size(); ++i) {
@@ -156,7 +118,7 @@ void AbstractClipItem::resizeEnd(int posx, double scale) {
                 kDebug() << "/////////  COLLISION: " << ((AbstractClipItem *)item)->startPos().frames(25) << "x" << ((AbstractClipItem *)item)->endPos().frames(25) << ", RECT: " << ((AbstractClipItem *)item)->rect() << "-" << item->pos();
                 GenTime diff = ((AbstractClipItem *)item)->startPos() - GenTime(1, m_fps) - startPos();
                 m_cropDuration = diff;
-                setRect(0, 0, (qreal)(m_cropDuration.frames(m_fps)) * scale - .5, rect().height());
+                setRect(0, 0, (m_cropDuration.frames(m_fps)) - 0.02, rect().height());
                 break;
             }
         }
@@ -249,14 +211,15 @@ void AbstractClipItem::drawKeyFrames(QPainter *painter, QRectF exposedRect) {
     // draw line showing default value
     if (isSelected()) {
         x1 = br.x();
-        x1 = br.right();
+        x2 = br.right();
         y1 = br.bottom() - m_keyframeDefault * maxh;
         QLineF l(x1, y1, x2, y1);
+        QLineF l2 = painter->matrix().map(l);
         painter->setPen(QColor(168, 168, 168, 180));
-        painter->drawLine(l);
-        l.translate(0, 1);
+        painter->drawLine(l2);
+        l2.translate(0, 1);
         painter->setPen(QColor(108, 108, 108, 180));
-        painter->drawLine(l);
+        painter->drawLine(l2);
         painter->setPen(QColor(Qt::white));
     }
 
@@ -265,6 +228,7 @@ void AbstractClipItem::drawKeyFrames(QPainter *painter, QRectF exposedRect) {
     QColor color(Qt::blue);
     x1 = br.x() + maxw * (i.key() - m_cropStart.frames(m_fps));
     y1 = br.bottom() - i.value() * maxh;
+    QLineF l2;
     while (i != m_keyframes.constEnd()) {
         if (i.key() == m_selectedKeyframe) color = QColor(Qt::red);
         else color = QColor(Qt::blue);
@@ -273,14 +237,15 @@ void AbstractClipItem::drawKeyFrames(QPainter *painter, QRectF exposedRect) {
         x2 = br.x() + maxw * (i.key() - m_cropStart.frames(m_fps));
         y2 = br.bottom() - i.value() * maxh;
         QLineF l(x1, y1, x2, y2);
-        painter->drawLine(l);
+        l2 = painter->matrix().map(l);
+        painter->drawLine(l2);
         if (isSelected()) {
-            painter->fillRect(x1 - 3, y1 - 3, 6, 6, QBrush(color));
+            painter->fillRect(l2.x1() - 3, l2.y1() - 3, 6, 6, QBrush(color));
         }
         x1 = x2;
         y1 = y2;
     }
-    if (isSelected()) painter->fillRect(x1 - 3, y1 - 3, 6, 6, QBrush(color));
+    if (isSelected()) painter->fillRect(l2.x2() - 3, l2.y2() - 3, 6, 6, QBrush(color));
 }
 
 int AbstractClipItem::mouseOverKeyFrames(QPointF pos) {
@@ -382,3 +347,7 @@ QRect AbstractClipItem::visibleRect() {
     }
     return rectInView;
 }
+
+CustomTrackScene* AbstractClipItem::projectScene() {
+    return static_cast <CustomTrackScene*>(scene());
+}
index cd38533aa8f54ee80985d1e814e687f855d68605..f23dea01843e1ff5839a5230bbf8bff59bcee841 100644 (file)
@@ -25,6 +25,8 @@
 #include "definitions.h"
 #include "gentime.h"
 
+class CustomTrackScene;
+
 class AbstractClipItem : public QObject , public QGraphicsRectItem {
     Q_OBJECT
 public:
@@ -37,16 +39,16 @@ public:
     double selectedKeyFrameValue() const;
     double keyFrameFactor() const;
     ItemInfo info() const;
+    CustomTrackScene* projectScene();
 
-    virtual  OPERATIONTYPE operationMode(QPointF pos, double scale) = 0;
+    virtual  OPERATIONTYPE operationMode(QPointF pos) = 0;
     virtual GenTime startPos() const ;
     virtual void setTrack(int track);
     virtual GenTime endPos() const ;
     virtual int track() const ;
-    virtual void moveTo(int x, double scale, int offset, int newTrack, bool checkCollision = true);
     virtual GenTime cropStart() const ;
-    virtual void resizeStart(int posx, double scale);
-    virtual void resizeEnd(int posx, double scale);
+    virtual void resizeStart(int posx);
+    virtual void resizeEnd(int posx);
     virtual GenTime duration() const;
     virtual double fps() const;
     virtual GenTime maxDuration() const;
diff --git a/src/abstractgroupitem.cpp b/src/abstractgroupitem.cpp
new file mode 100644 (file)
index 0000000..dc5573d
--- /dev/null
@@ -0,0 +1,145 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Marco Gittler (g.marco@freenet.de)              *
+ *   Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
+ ***************************************************************************/
+
+#include <QGraphicsScene>
+#include <QGraphicsView>
+#include <QScrollBar>
+#include <QToolTip>
+
+#include <KDebug>
+#include <KLocale>
+
+#include "abstractgroupitem.h"
+#include "abstractclipitem.h"
+#include "kdenlivesettings.h"
+#include "customtrackscene.h"
+
+AbstractGroupItem::AbstractGroupItem(double fps): QGraphicsItemGroup(), m_fps(fps) {
+    setFlags(QGraphicsItem::ItemClipsToShape | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
+}
+
+int AbstractGroupItem::type() const {
+    return GROUPWIDGET;
+}
+
+CustomTrackScene* AbstractGroupItem::projectScene() {
+    return static_cast <CustomTrackScene*>(scene());
+}
+
+
+QPainterPath AbstractGroupItem::groupShape(QPointF offset) {
+    QList<QGraphicsItem *> children = childItems();
+    QPainterPath path;
+    for (int i = 0; i < children.count(); i++) {
+        QRectF r = children.at(i)->sceneBoundingRect();
+        //kDebug()<<"// GROUP CHild: "<<r;
+        //r.translate(offset);
+        path.addRect(r);
+    }
+    return path;
+}
+
+void AbstractGroupItem::addItem(QGraphicsItem * item) {
+    addToGroup(item);
+    //fixItemRect();
+}
+
+void AbstractGroupItem::fixItemRect() {
+    QPointF start = boundingRect().topLeft();
+    if (start != QPointF(0, 0)) {
+        translate(0 - start.x(), 0 - start.y());
+        setPos(start);
+    }
+}
+
+// virtual
+void AbstractGroupItem::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) {
+    p->fillRect(boundingRect(), QColor(200, 100, 100, 100));
+}
+
+//virtual
+QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant &value) {
+    if (change == ItemPositionChange && scene()) {
+        // calculate new position.
+        QPointF newPos = value.toPointF();
+        QPainterPath sceneShape = groupShape(newPos);
+        QPointF start = sceneBoundingRect().topLeft();
+        QPointF sc = mapToScene(pos());
+        int posx = start.x() + newPos.x(); //projectScene()->getSnapPointForPos(start.x() + sc.x(), KdenliveSettings::snaptopoints());
+        //int startx = projectScene()->getSnapPointForPos(start.x(), false);
+        //int startx = projectScene()->getSnapPointForPos(start.x(), false);
+        kDebug() << "------------------------------------";
+        kDebug() << "BRect: " << start.x() << "diff: " << newPos.x() << ",mapd: " << start.x() - sc.x();
+        return newPos;
+        //kDebug()<<"BR: "<<start.x()<<",NP: "<<newPos.x()<<",MAPD: "<<sc.x()<<",POS: "<<pos().x();
+        if (start.x() <= 0) {
+            //kDebug()<<"/// GOING UNDER 0, POS: "<<posx<<", ADJUSTED: items.at(i)->sceneBoundingRect();
+            return pos();
+        }
+        //else posx -= startx;
+        //posx = qMax(posx, 0);
+        newPos.setX(posx);
+        //kDebug()<<"Y POS: "<<start.y() + newPos.y()<<"SCN MP: "<<sc;
+        int newTrack = (start.y() + newPos.y()) / KdenliveSettings::trackheight();
+        int oldTrack = (start.y() + pos().y()) / KdenliveSettings::trackheight();
+        newPos.setY((newTrack) * KdenliveSettings::trackheight() - start.y() + 1);
+
+
+        //if (start.y() + newPos.y() < 1)  newTrack = oldTrack;
+
+        return newPos;
+
+        // Only one clip is moving
+
+        QList<QGraphicsItem*> items = scene()->items(sceneShape, Qt::IntersectsItemShape);
+
+        QList<QGraphicsItem *> children = childItems();
+        for (int i = 0; i < children.count(); i++) {
+            items.removeAll(children.at(i));
+        }
+
+
+
+        if (!items.isEmpty()) {
+            for (int i = 0; i < items.count(); i++) {
+                if (items.at(i)->type() == AVWIDGET) {
+                    // Collision!
+                    //kDebug()<<"/// COLLISION WITH ITEM: "<<items.at(i)->sceneBoundingRect();
+                    return pos();
+                    QPointF otherPos = items.at(i)->pos();
+                    if ((int) otherPos.y() != (int) pos().y()) return pos();
+                    if (pos().x() < otherPos.x()) {
+                        // move clip just before colliding clip
+                        int npos = (static_cast < AbstractClipItem* >(items.at(i))->startPos()).frames(m_fps) - sceneBoundingRect().width();
+                        newPos.setX(npos);
+                    } else {
+                        // get pos just after colliding clip
+                        int npos = static_cast < AbstractClipItem* >(items.at(i))->endPos().frames(m_fps);
+                        newPos.setX(npos);
+                    }
+                    return newPos;
+                }
+            }
+        }
+        return newPos;
+    }
+    return QGraphicsItem::itemChange(change, value);
+}
+
diff --git a/src/abstractgroupitem.h b/src/abstractgroupitem.h
new file mode 100644 (file)
index 0000000..1945722
--- /dev/null
@@ -0,0 +1,48 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Marco Gittler (g.marco@freenet.de)              *
+ *   Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
+ ***************************************************************************/
+
+#ifndef ABSTRACTGROUPITEM
+#define ABSTRACTGROUPITEM
+
+#include <QGraphicsItemGroup>
+#include "definitions.h"
+#include "gentime.h"
+
+class CustomTrackScene;
+
+class AbstractGroupItem : public QObject , public QGraphicsItemGroup {
+    Q_OBJECT
+public:
+    AbstractGroupItem(double fps);
+    virtual int type() const;
+    CustomTrackScene* projectScene();
+    void addItem(QGraphicsItem * item);
+
+protected:
+    virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+    virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+
+private:
+    QPainterPath groupShape(QPointF);
+    void fixItemRect();
+    double m_fps;
+};
+
+#endif
index 073132d536e34691097372835bd1f37e218535c6..fadf4228fa1f80f7b02aab950de23895bdab487f 100644 (file)
 
 #include "clipitem.h"
 #include "customtrackview.h"
+#include "customtrackscene.h"
 #include "renderer.h"
 #include "docclipbase.h"
 #include "transition.h"
-#include "events.h"
 #include "kdenlivesettings.h"
 #include "kthumb.h"
 
-ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double scale, double fps)
-        : AbstractClipItem(info, QRectF(), fps), m_clip(clip), m_resizeMode(NONE), m_grabPoint(0), m_maxTrack(0), m_hasThumbs(false), startThumbTimer(NULL), endThumbTimer(NULL), m_effectsCounter(1), audioThumbWasDrawn(false), m_opacity(1.0), m_timeLine(0), m_thumbsRequested(2), m_startFade(0), m_endFade(0), m_hover(false), m_selectedEffect(-1), m_speed(1.0), framePixelWidth(0) {
-    setRect(0, 0, (qreal)(info.endPos - info.startPos).frames(fps) * scale - .5, (qreal)(KdenliveSettings::trackheight() - 1));
-    setPos((qreal) info.startPos.frames(fps) * scale, (qreal)(info.track * KdenliveSettings::trackheight()) + 1);
-    kDebug() << "// ADDing CLIP TRK HGTH: " << KdenliveSettings::trackheight();
+
+ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps)
+        : AbstractClipItem(info, QRectF(), fps), m_clip(clip), m_resizeMode(NONE), m_grabPoint(0), m_maxTrack(0), m_hasThumbs(false), startThumbTimer(NULL), endThumbTimer(NULL), m_effectsCounter(1), audioThumbWasDrawn(false), m_opacity(1.0), m_timeLine(0), m_startThumbRequested(false), m_endThumbRequested(false), m_startFade(0), m_endFade(0), m_hover(false), m_selectedEffect(-1), m_speed(1.0), framePixelWidth(0) {
+    setRect(0, 0, (info.endPos - info.startPos).frames(fps) - 0.02, (qreal)(KdenliveSettings::trackheight() - 2));
+    setPos((qreal) info.startPos.frames(fps), (qreal)(info.track * KdenliveSettings::trackheight()) + 1);
 
     m_clipName = clip->name();
     m_producer = clip->getId();
@@ -64,28 +64,33 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double scale, double fps)
 
     setFlags(QGraphicsItem::ItemClipsToShape | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
     setAcceptsHoverEvents(true);
-    connect(this , SIGNAL(prepareAudioThumb(double, QPainterPath, int, int, int)) , this, SLOT(slotPrepareAudioThumb(double, QPainterPath, int, int, int)));
+    connect(this , SIGNAL(prepareAudioThumb(double, int, int, int)) , this, SLOT(slotPrepareAudioThumb(double, int, int, int)));
 
     setBrush(QColor(141, 166, 215));
     if (m_clipType == VIDEO || m_clipType == AV || m_clipType == SLIDESHOW) {
         m_hasThumbs = true;
-        connect(this, SIGNAL(getThumb(int, int)), clip->thumbProducer(), SLOT(extractImage(int, int)));
-        connect(clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));
-        connect(clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData()));
-        QTimer::singleShot(200, this, SLOT(slotFetchThumbs()));
-
         startThumbTimer = new QTimer(this);
         startThumbTimer->setSingleShot(true);
         connect(startThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetStartThumb()));
         endThumbTimer = new QTimer(this);
         endThumbTimer->setSingleShot(true);
         connect(endThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetEndThumb()));
+
+        connect(this, SIGNAL(getThumb(int, int)), clip->thumbProducer(), SLOT(extractImage(int, int)));
+        connect(clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));
+        connect(clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData()));
+        QTimer::singleShot(200, this, SLOT(slotFetchThumbs()));
+
+        /*if (m_clip->producer()) {
+            videoThumbProducer.init(this, m_clip->producer(), KdenliveSettings::trackheight() * KdenliveSettings::project_display_ratio(), KdenliveSettings::trackheight());
+            slotFetchThumbs();
+        }*/
     } else if (m_clipType == COLOR) {
         QString colour = clip->getProperty("colour");
         colour = colour.replace(0, 2, "#");
         setBrush(QColor(colour.left(7)));
     } else if (m_clipType == IMAGE || m_clipType == TEXT) {
-        m_startPix = KThumb::getImage(KUrl(clip->getProperty("resource")), (int)(50 * KdenliveSettings::project_display_ratio()), 50);
+        m_startPix = KThumb::getImage(KUrl(clip->getProperty("resource")), (int)(KdenliveSettings::trackheight() * KdenliveSettings::project_display_ratio()), KdenliveSettings::trackheight());
         m_endPix = m_startPix;
     } else if (m_clipType == AUDIO) {
         connect(clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData()));
@@ -99,10 +104,10 @@ ClipItem::~ClipItem() {
     if (m_timeLine) m_timeLine;
 }
 
-ClipItem *ClipItem::clone(double scale, ItemInfo info) const {
-    ClipItem *duplicate = new ClipItem(m_clip, info, scale, m_fps);
-    if (info.cropStart == cropStart()) duplicate->slotThumbReady(info.cropStart.frames(m_fps), m_startPix);
-    if (info.cropStart + (info.endPos - info.startPos) == m_cropStart + m_cropDuration) duplicate->slotThumbReady((m_cropStart + m_cropDuration).frames(m_fps) - 1, m_endPix);
+ClipItem *ClipItem::clone(ItemInfo info) const {
+    ClipItem *duplicate = new ClipItem(m_clip, info, m_fps);
+    if (info.cropStart == cropStart()) duplicate->slotSetStartThumb(m_startPix);
+    if (info.cropStart + (info.endPos - info.startPos) == m_cropStart + m_cropDuration) duplicate->slotSetEndThumb(m_endPix);
     kDebug() << "// CLoning clip: " << (info.cropStart + (info.endPos - info.startPos)).frames(m_fps) << ", CURRENT end: " << (cropStart() + duration()).frames(m_fps);
     duplicate->setEffectList(m_effectList);
     duplicate->setSpeed(m_speed);
@@ -253,7 +258,6 @@ QDomElement ClipItem::selectedEffect() {
 void ClipItem::resetThumbs() {
     m_startPix = QPixmap();
     m_endPix = QPixmap();
-    m_thumbsRequested = 2;
     slotFetchThumbs();
     audioThumbCachePic.clear();
 }
@@ -261,54 +265,100 @@ void ClipItem::resetThumbs() {
 
 void ClipItem::refreshClip() {
     m_maxDuration = m_clip->maxDuration();
-    if (m_clipType == VIDEO || m_clipType == AV || m_clipType == SLIDESHOW) slotFetchThumbs();
-    else if (m_clipType == COLOR) {
+    if (m_clipType == COLOR) {
         QString colour = m_clip->getProperty("colour");
         colour = colour.replace(0, 2, "#");
         setBrush(QColor(colour.left(7)));
-    } else if (m_clipType == IMAGE || m_clipType == TEXT) {
-        m_startPix = KThumb::getImage(KUrl(m_clip->getProperty("resource")), (int)(50 * KdenliveSettings::project_display_ratio()), 50);
-        m_endPix = m_startPix;
-    }
+    } else slotFetchThumbs();
 }
 
 void ClipItem::slotFetchThumbs() {
     if (m_endPix.isNull() && m_startPix.isNull()) {
+        m_startThumbRequested = true;
+        m_endThumbRequested = true;
         emit getThumb((int)m_cropStart.frames(m_fps), (int)(m_cropStart + m_cropDuration).frames(m_fps) - 1);
     } else {
-        if (m_endPix.isNull()) slotGetEndThumb();
-        if (m_startPix.isNull()) slotGetStartThumb();
+        if (m_endPix.isNull()) {
+            slotGetEndThumb();
+        }
+        if (m_startPix.isNull()) {
+            slotGetStartThumb();
+        }
     }
+    /*
+        if (m_hasThumbs) {
+            if (m_endPix.isNull() && m_startPix.isNull()) {
+                int frame1 = (int)m_cropStart.frames(m_fps);
+                int frame2 = (int)(m_cropStart + m_cropDuration).frames(m_fps) - 1;
+                //videoThumbProducer.setThumbFrames(m_clip->producer(), frame1, frame2);
+                //videoThumbProducer.start(QThread::LowestPriority);
+            } else {
+                if (m_endPix.isNull()) slotGetEndThumb();
+                else slotGetStartThumb();
+            }
+
+        } else if (m_startPix.isNull()) slotGetStartThumb();*/
 }
 
 void ClipItem::slotGetStartThumb() {
+    m_startThumbRequested = true;
     emit getThumb((int)m_cropStart.frames(m_fps), -1);
+    //videoThumbProducer.setThumbFrames(m_clip->producer(), (int)m_cropStart.frames(m_fps),  - 1);
+    //videoThumbProducer.start(QThread::LowestPriority);
 }
 
 void ClipItem::slotGetEndThumb() {
+    m_endThumbRequested = true;
     emit getThumb(-1, (int)(m_cropStart + m_cropDuration).frames(m_fps) - 1);
+    //videoThumbProducer.setThumbFrames(m_clip->producer(), -1, (int)(m_cropStart + m_cropDuration).frames(m_fps) - 1);
+    //videoThumbProducer.start(QThread::LowestPriority);
 }
 
-void ClipItem::slotThumbReady(int frame, QPixmap pix) {
-    if (frame == m_cropStart.frames(m_fps)) {
+
+void ClipItem::slotSetStartThumb(QImage img) {
+    if (!img.isNull() && img.format() == QImage::Format_ARGB32) {
+        QPixmap pix = QPixmap::fromImage(img);
         m_startPix = pix;
         QRectF r = sceneBoundingRect();
         r.setRight(pix.width() + 2);
         update(r);
-        m_thumbsRequested--;
-    } else if (frame == (m_cropStart + m_cropDuration).frames(m_fps) - 1) {
+    }
+}
+
+void ClipItem::slotSetEndThumb(QImage img) {
+    if (!img.isNull() && img.format() == QImage::Format_ARGB32) {
+        QPixmap pix = QPixmap::fromImage(img);
         m_endPix = pix;
         QRectF r = sceneBoundingRect();
         r.setLeft(r.right() - pix.width() - 2);
         update(r);
-        m_thumbsRequested--;
     }
-    if (m_thumbsRequested == 0) {
-        // Ok, we have out start and end thumbnails...
-        disconnect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));
+}
+
+void ClipItem::slotThumbReady(int frame, QPixmap pix) {
+    QRectF r = sceneBoundingRect();
+    double width = m_startPix.width() / projectScene()->scale();
+    if (m_startThumbRequested && frame == m_cropStart.frames(m_fps)) {
+        m_startPix = pix;
+        m_startThumbRequested = false;
+        double height = r.height();
+        update(r.x(), r.y(), width, height);
+    } else if (m_endThumbRequested && frame == (m_cropStart + m_cropDuration).frames(m_fps) - 1) {
+        m_endPix = pix;
+        m_endThumbRequested = false;
+        double height = r.height();
+        update(r.right() - width, r.y(), width, height);
     }
 }
 
+void ClipItem::slotSetStartThumb(QPixmap pix) {
+    m_startPix = pix;
+}
+
+void ClipItem::slotSetEndThumb(QPixmap pix) {
+    m_endPix = pix;
+}
+
 void ClipItem::slotGotAudioData() {
     audioThumbReady = true;
     if (m_clipType == AV) {
@@ -365,66 +415,88 @@ void ClipItem::paint(QPainter *painter,
     QBrush paintColor = brush();
     if (isSelected()) paintColor = QBrush(QColor(79, 93, 121));
     QRectF br = rect();
+    QRectF exposed = option->exposedRect;
     const double itemWidth = br.width();
     const double itemHeight = br.height();
-    kDebug() << "/// ITEM RECT: " << br << ", EPXOSED: " << option->exposedRect;
-    double scale = itemWidth / (double) m_cropDuration.frames(m_fps);
+    //kDebug() << "/// ITEM RECT: " << br << ", EPXOSED: " << option->exposedRect;
+    const double scale = option->matrix.m11();
 
     // kDebug()<<"///   EXPOSED RECT: "<<option->exposedRect.x()<<" X "<<option->exposedRect.right();
 
-    double startpixel = option->exposedRect.x(); // - pos().x();
-
-    if (startpixel < 0)
-        startpixel = 0;
-    double endpixel = option->exposedRect.right();
-    if (endpixel < 0)
-        endpixel = 0;
-
     //painter->setRenderHints(QPainter::Antialiasing);
 
-    QPainterPath roundRectPathUpper = upperRectPart(br), roundRectPathLower = lowerRectPart(br);
-    painter->setClipRect(option->exposedRect);
+    //QPainterPath roundRectPathUpper = upperRectPart(br), roundRectPathLower = lowerRectPart(br);
+    painter->setClipRect(exposed);
 
     // build path around clip
-    QPainterPath resultClipPath = roundRectPathUpper.united(roundRectPathLower);
-    painter->fillPath(resultClipPath, paintColor);
+    //QPainterPath resultClipPath = roundRectPathUpper.united(roundRectPathLower);
+    //painter->fillPath(resultClipPath, paintColor);
+    painter->fillRect(br, paintColor);
 
-    painter->setClipPath(resultClipPath, Qt::IntersectClip);
+    //painter->setClipPath(resultClipPath, Qt::IntersectClip);
 
     // draw thumbnails
+    painter->setMatrixEnabled(false);
+
     if (KdenliveSettings::videothumbnails()) {
-       if (m_clipType == IMAGE && !m_startPix.isNull()) {
-            painter->drawPixmap(QPointF(itemWidth - m_startPix.width(), 0), m_startPix);
-            QLine l(itemWidth - m_startPix.width(), 0, itemWidth - m_startPix.width(), itemHeight);
+        QPen pen = painter->pen();
+        pen.setStyle(Qt::DotLine);
+        pen.setColor(Qt::white);
+        painter->setPen(pen);
+        if (m_clipType == IMAGE && !m_startPix.isNull()) {
+            QPointF p1 = painter->matrix().map(QPointF(itemWidth, 0)) - QPointF(m_startPix.width(), 0);
+            QPointF p2 = painter->matrix().map(QPointF(itemWidth, itemHeight)) - QPointF(m_startPix.width(), 0);
+            painter->drawPixmap(p1, m_startPix);
+            QLineF l(p1, p2);
             painter->drawLine(l);
-       }
-       else if (!m_endPix.isNull()) {
-            painter->drawPixmap(QPointF(itemWidth - m_endPix.width(), 0), m_endPix);
-            QLine l(itemWidth - m_endPix.width(), 0, itemWidth - m_endPix.width(), itemHeight);
+        } else if (!m_endPix.isNull()) {
+            QPointF p1 = painter->matrix().map(QPointF(itemWidth, 0)) - QPointF(m_endPix.width(), 0);
+            QPointF p2 = painter->matrix().map(QPointF(itemWidth, itemHeight)) - QPointF(m_endPix.width(), 0);
+            painter->drawPixmap(p1, m_endPix);
+            QLineF l(p1, p2);
             painter->drawLine(l);
         }
-       if (!m_startPix.isNull()) {
-           painter->drawPixmap(QPointF(0, 0), m_startPix);
-           QLine l2(m_startPix.width(), 0, 0 + m_startPix.width(), itemHeight);
-           painter->drawLine(l2);
-       }
+        if (!m_startPix.isNull()) {
+            QPointF p1 = painter->matrix().map(QPointF(0, 0));
+            QPointF p2 = painter->matrix().map(QPointF(0, itemHeight));
+            painter->drawPixmap(p1, m_startPix);
+            QLineF l2(p1.x() + m_startPix.width(), p1.y(), p2.x() + m_startPix.width(), p2.y());
+            painter->drawLine(l2);
+        }
+        painter->setPen(Qt::black);
     }
 
     // draw audio thumbnails
     if (KdenliveSettings::audiothumbnails() && ((m_clipType == AV && option->exposedRect.bottom() > (itemHeight / 2)) || m_clipType == AUDIO) && audioThumbReady) {
 
-        QPainterPath path = m_clipType == AV ? roundRectPathLower : resultClipPath;
-        if (m_clipType == AV) painter->fillPath(path, QBrush(QColor(200, 200, 200, 140)));
+        double startpixel = option->exposedRect.left(); // - pos().x();
+        if (startpixel < 0)
+            startpixel = 0;
+        double endpixel = option->exposedRect.right();
+        if (endpixel < 0)
+            endpixel = 0;
+        //kDebug()<<"///  REPAINTING AUDIO THMBS ZONE: "<<startpixel<<"x"<<endpixel;
+
+        /*QPainterPath path = m_clipType == AV ? roundRectPathLower : resultClipPath;*/
+        QRectF re =  br;
+        QRectF mappedRect;
+        if (m_clipType == AV) {
+            re.setTop(re.y() + re.height() / 2);
+            mappedRect = painter->matrix().mapRect(re);
+            painter->fillRect(mappedRect, QBrush(QColor(200, 200, 200, 140)));
+        } else mappedRect = painter->matrix().mapRect(re);
 
         int channels = baseClip()->getProperty("channels").toInt();
         if (scale != framePixelWidth)
             audioThumbCachePic.clear();
-        double cropLeft = m_cropStart.frames(m_fps) * scale;
-        emit prepareAudioThumb(scale, path, startpixel + cropLeft, endpixel + cropLeft, channels);//200 more for less missing parts before repaint after scrolling
+        double cropLeft = m_cropStart.frames(m_fps);
+        emit prepareAudioThumb(scale, startpixel + cropLeft, endpixel + cropLeft, channels);//200 more for less missing parts before repaint after scrolling
         int newstart = startpixel + cropLeft;
+        const int clipStart = mappedRect.x();
         for (int startCache = newstart - (newstart) % 100; startCache < endpixel + cropLeft; startCache += 100) {
             if (audioThumbCachePic.contains(startCache) && !audioThumbCachePic[startCache].isNull())
-                painter->drawPixmap((int)(startCache - cropLeft), (int)(path.boundingRect().y()), audioThumbCachePic[startCache]);
+                //painter->drawPixmap((int)(startCache - cropLeft), (int)(path.boundingRect().y()), audioThumbCachePic[startCache]);
+                painter->drawPixmap(clipStart + startCache, mappedRect.y(),  audioThumbCachePic[startCache]);
         }
     }
 
@@ -444,11 +516,17 @@ void ClipItem::paint(QPainter *painter,
         pos = (*it).time() - cropStart();
         if (pos > GenTime()) {
             if (pos > duration()) break;
-            framepos = scale * pos.frames(m_fps);
-            QLineF l(framepos, 5, framepos, itemHeight - 5);
-            painter->drawLine(l);
+            QLineF l(br.x() + pos.frames(m_fps), br.y() + 5, br.x() + pos.frames(m_fps), br.bottom() - 5);
+            QLineF l2 = painter->matrix().map(l);
+            //framepos = scale * pos.frames(m_fps);
+            //QLineF l(framepos, 5, framepos, itemHeight - 5);
+            painter->drawLine(l2);
             if (KdenliveSettings::showmarkers()) {
-                const QRectF txtBounding = painter->boundingRect(framepos + 1, 10, itemWidth - framepos - 2, itemHeight - 10, Qt::AlignLeft | Qt::AlignTop, " " + (*it).comment() + " ");
+                framepos = br.x() + pos.frames(m_fps);
+                const QRectF r1(framepos + 0.04, 10, itemWidth - framepos - 2, itemHeight - 10);
+                const QRectF r2 = painter->matrix().map(r1).boundingRect();
+                const QRectF txtBounding = painter->boundingRect(r2, Qt::AlignLeft | Qt::AlignTop, " " + (*it).comment() + " ");
+
                 QPainterPath path;
                 path.addRoundedRect(txtBounding, 3, 3);
                 painter->fillPath(path, markerBrush);
@@ -471,30 +549,32 @@ void ClipItem::paint(QPainter *painter,
         QPainterPath fadeInPath;
         fadeInPath.moveTo(0, 0);
         fadeInPath.lineTo(0, itemHeight);
-        fadeInPath.lineTo(m_startFade * scale, itemHeight);
+        fadeInPath.lineTo(m_startFade, 0);
         fadeInPath.closeSubpath();
-        painter->fillPath(fadeInPath/*.intersected(resultClipPath)*/, fades);
-        if (isSelected()) {
+        QPainterPath f1 = painter->matrix().map(fadeInPath);
+        painter->fillPath(f1/*.intersected(resultClipPath)*/, fades);
+        /*if (isSelected()) {
             QLineF l(m_startFade * scale, 0, 0, itemHeight);
             painter->drawLine(l);
-        }
+        }*/
     }
     if (m_endFade != 0) {
         QPainterPath fadeOutPath;
         fadeOutPath.moveTo(itemWidth, 0);
         fadeOutPath.lineTo(itemWidth, itemHeight);
-        fadeOutPath.lineTo(itemWidth - m_endFade * scale, 0);
+        fadeOutPath.lineTo(itemWidth - m_endFade, 0);
         fadeOutPath.closeSubpath();
-        painter->fillPath(fadeOutPath/*.intersected(resultClipPath)*/, fades);
-        if (isSelected()) {
+        QPainterPath f1 = painter->matrix().map(fadeOutPath);
+        painter->fillPath(f1/*.intersected(resultClipPath)*/, fades);
+        /*if (isSelected()) {
             QLineF l(itemWidth - m_endFade * scale, 0, itemWidth, itemHeight);
             painter->drawLine(l);
-        }
+        }*/
     }
 
     // Draw effects names
-    if (!m_effectNames.isEmpty() && itemWidth > 30) {
-        QRectF txtBounding = painter->boundingRect(br, Qt::AlignLeft | Qt::AlignTop, m_effectNames);
+    if (!m_effectNames.isEmpty() && itemWidth * scale > 40) {
+        QRectF txtBounding = painter->boundingRect(painter->matrix().map(br).boundingRect(), Qt::AlignLeft | Qt::AlignTop, m_effectNames);
         txtBounding.setRight(txtBounding.right() + 15);
         painter->setPen(Qt::white);
         QBrush markerBrush(Qt::SolidPattern);
@@ -510,14 +590,28 @@ void ClipItem::paint(QPainter *painter,
         painter->setPen(Qt::black);
     }
 
+
     // Draw clip name
-    QRectF txtBounding = painter->boundingRect(br, Qt::AlignHCenter | Qt::AlignTop, " " + m_clipName + " ");
+    QRectF txtBounding = painter->boundingRect(painter->matrix().map(br).boundingRect(), Qt::AlignHCenter | Qt::AlignTop, " " + m_clipName + " ");
     //painter->fillRect(txtBounding, QBrush(QColor(255, 255, 255, 150)));
     painter->setPen(QColor(0, 0, 0, 180));
     painter->drawText(txtBounding, Qt::AlignCenter, m_clipName);
     txtBounding.translate(QPointF(1, 1));
     painter->setPen(QColor(255, 255, 255, 255));
     painter->drawText(txtBounding, Qt::AlignCenter, m_clipName);
+
+
+    // draw transition handles on hover
+    if (m_hover && itemWidth * scale > 40) {
+        QPainterPath transitionHandle;
+        const int handle_size = 4;
+        QPointF p1 = painter->matrix().map(QPointF(0, itemHeight / 2)) + QPointF(10, 0);
+        painter->drawPixmap(p1, projectScene()->m_transitionPixmap);
+        p1 = painter->matrix().map(QPointF(itemWidth, itemHeight / 2)) - QPointF(10 + handle_size * 3, 0);
+        painter->drawPixmap(p1, projectScene()->m_transitionPixmap);
+    }
+
+
     // draw frame around clip
     if (isSelected()) {
         pen.setColor(Qt::red);
@@ -527,87 +621,57 @@ void ClipItem::paint(QPainter *painter,
         //pen.setWidth(1);
     }
 
-
     // draw effect or transition keyframes
     if (itemWidth > 20) drawKeyFrames(painter, option->exposedRect);
 
+    painter->setMatrixEnabled(true);
+
     // draw clip border
-    painter->setClipRect(option->exposedRect);
-    painter->setPen(pen);
-    //painter->setClipRect(option->exposedRect);
-    painter->drawPath(resultClipPath);
 
-    if (m_hover && itemWidth > 30) {
-        painter->setBrush(QColor(180, 180, 50, 180)); //gradient);
+    //kDebug()<<"/// ITEM PAINTING:: exposed="<<exposed<<", RECT = "<<rect();
 
-        // draw transitions handles
-        QPainterPath transitionHandle;
-        const int handle_size = 4;
-        transitionHandle.moveTo(0, 0);
-        transitionHandle.lineTo(handle_size, handle_size);
-        transitionHandle.lineTo(handle_size * 2, 0);
-        transitionHandle.lineTo(handle_size * 3, handle_size);
-        transitionHandle.lineTo(handle_size * 2, handle_size * 2);
-        transitionHandle.lineTo(handle_size * 3, handle_size * 3);
-        transitionHandle.lineTo(0, handle_size * 3);
-        transitionHandle.closeSubpath();
-        int pointy = (int)(itemHeight / 2);
-        int pointx1 = 10;
-        int pointx2 = (int)(itemWidth - (10 + handle_size * 3));
-#if 0
-        painter->setPen(QPen(Qt::black));
-        painter->setBrush(QBrush(QColor(50, 50, 0)));
-#else
-        /*QRadialGradient gradient(pointx1 + 5, pointy + 5 , 5, 2, 2);
-        gradient.setColorAt(0.2, Qt::white);
-        gradient.setColorAt(0.8, Qt::yellow);
-        gradient.setColorAt(1, Qt::black);*/
-
-#endif
-        painter->translate(pointx1, pointy);
-        painter->drawPath(transitionHandle); //Ellipse(0, 0 , 10, 10);
-        painter->translate(-pointx1, -pointy);
-
-        /*        QRadialGradient gradient1(pointx2 + 5, pointy + 5 , 5, 2, 2);
-                gradient1.setColorAt(0.2, Qt::white);
-                gradient1.setColorAt(0.8, Qt::yellow);
-                gradient1.setColorAt(1, Qt::black);
-                painter->setBrush(gradient1);*/
-        painter->translate(pointx2, pointy);
-        QMatrix m;
-        m.scale(-1.0, 1.0);
-        //painter->setMatrix(m);
-        painter->drawPath(transitionHandle); // Ellipse(0, 0, 10, 10);
-        //painter->setMatrix(m);
-        painter->translate(- pointx2, -pointy);
-    }
+    exposed.setRight(exposed.right() + 1);
+    exposed.setBottom(exposed.bottom() + 1);
+    painter->setClipRect(exposed);
+    //painter->setClipping(false);
+    //painter->fillRect(exposed, Qt::blue);
+    painter->setPen(pen);
+    painter->drawRect(br);
 }
 
 
-OPERATIONTYPE ClipItem::operationMode(QPointF pos, double scale) {
+OPERATIONTYPE ClipItem::operationMode(QPointF pos) {
     if (isSelected()) {
         m_editedKeyframe = mouseOverKeyFrames(pos);
         if (m_editedKeyframe != -1) return KEYFRAME;
     }
     QRectF rect = sceneBoundingRect();
-    if (qAbs((int)(pos.x() - (rect.x() + scale * m_startFade))) < 6 && qAbs((int)(pos.y() - rect.y())) < 6) {
+    const double scale = projectScene()->scale();
+    double maximumOffset;
+    if (scale > 3) maximumOffset = 25 / scale;
+    else maximumOffset = 6 / scale;
+    QMatrix matrix;
+    matrix.scale(scale, 0);
+    //kDebug()<<"// Item rect: "<<rect.x()<<". pos. "<<pos.x()<<", scale: "<<scale<<", ratio: "<<qAbs((int)(pos.x() - rect.x())) / scale;
+
+    if (qAbs((int)(pos.x() - (rect.x() + m_startFade))) < maximumOffset  && qAbs((int)(pos.y() - rect.y())) < 6) {
         if (m_startFade == 0) setToolTip(i18n("Add audio fade"));
         else setToolTip(i18n("Audio fade duration: %1s", GenTime(m_startFade, m_fps).seconds()));
         return FADEIN;
-    } else if (qAbs((int)(pos.x() - rect.x())) < 6) {
+    } else if (pos.x() - rect.x() < maximumOffset) {
         setToolTip(i18n("Crop from start: %1s", cropStart().seconds()));
         return RESIZESTART;
-    } else if (qAbs((int)(pos.x() - (rect.x() + rect.width() - scale * m_endFade))) < 6 && qAbs((int)(pos.y() - rect.y())) < 6) {
+    } else if (qAbs((int)(pos.x() - (rect.x() + rect.width() - m_endFade))) < maximumOffset && qAbs((int)(pos.y() - rect.y())) < 6) {
         if (m_endFade == 0) setToolTip(i18n("Add audio fade"));
         else setToolTip(i18n("Audio fade duration: %1s", GenTime(m_endFade, m_fps).seconds()));
         return FADEOUT;
-    } else if (qAbs((int)(pos.x() - (rect.x() + rect.width()))) < 6) {
+    } else if (qAbs((int)(pos.x() - (rect.x() + rect.width()))) < maximumOffset) {
         setToolTip(i18n("Clip duration: %1s", duration().seconds()));
         return RESIZEEND;
-    } else if (qAbs((int)(pos.x() - (rect.x() + 16))) < 10 && qAbs((int)(pos.y() - (rect.y() + rect.height() / 2 + 5))) < 8) {
+    } else if (qAbs((int)(pos.x() - (rect.x() + 16))) < maximumOffset && qAbs((int)(pos.y() - (rect.y() + rect.height() / 2 + 5))) < 6) {
         setToolTip(i18n("Add transition"));
         return TRANSITIONSTART;
-    } else if (qAbs((int)(pos.x() - (rect.x() + rect.width() - 21))) < 10 && qAbs((int)(pos.y() - (rect.y() + rect.height() / 2 + 5))) < 8) {
+    } else if (qAbs((int)(pos.x() - (rect.x() + rect.width() - 21))) < maximumOffset && qAbs((int)(pos.y() - (rect.y() + rect.height() / 2 + 5))) < 6) {
         setToolTip(i18n("Add transition"));
         return TRANSITIONEND;
     }
@@ -647,10 +711,14 @@ QList <CommentedTime> ClipItem::commentedSnapMarkers() const {
     return snaps;
 }
 
-void ClipItem::slotPrepareAudioThumb(double pixelForOneFrame, QPainterPath path, int startpixel, int endpixel, int channels) {
+void ClipItem::slotPrepareAudioThumb(double pixelForOneFrame, int startpixel, int endpixel, int channels) {
+
+    //QRectF re = path.boundingRect();
+    QRectF re =  rect();
+    if (m_clipType == AV) re.setTop(re.y() + re.height() / 2);
 
-    QRectF re = path.boundingRect();
-    kDebug() << "// PREP AUDIO THMB FRMO : " << startpixel << ", to: " << endpixel;
+    //QRectF re = rect(); //path.boundingRect();
+    //kDebug() << "// PREP AUDIO THMB FRMO : " << startpixel << ", to: " << endpixel;
     //if ( (!audioThumbWasDrawn || framePixelWidth!=pixelForOneFrame ) && !baseClip()->audioFrameChache.isEmpty()){
 
     for (int startCache = startpixel - startpixel % 100;startCache + 100 < endpixel + 100;startCache += 100) {
@@ -735,22 +803,22 @@ uint ClipItem::fadeOut() const {
 }
 
 
-void ClipItem::setFadeIn(int pos, double scale) {
+void ClipItem::setFadeIn(int pos) {
     int oldIn = m_startFade;
     if (pos < 0) pos = 0;
     if (pos > m_cropDuration.frames(m_fps)) pos = (int)(m_cropDuration.frames(m_fps) / 2);
     m_startFade = pos;
     QRectF rect = boundingRect();
-    update(rect.x(), rect.y(), qMax(oldIn, pos) * scale, rect.height());
+    update(rect.x(), rect.y(), qMax(oldIn, pos), rect.height());
 }
 
-void ClipItem::setFadeOut(int pos, double scale) {
+void ClipItem::setFadeOut(int pos) {
     int oldOut = m_endFade;
     if (pos < 0) pos = 0;
     if (pos > m_cropDuration.frames(m_fps)) pos = (int)(m_cropDuration.frames(m_fps) / 2);
     m_endFade = pos;
     QRectF rect = boundingRect();
-    update(rect.x() + rect.width() - qMax(oldOut, pos) * scale, rect.y(), pos * scale, rect.height());
+    update(rect.x() + rect.width() - qMax(oldOut, pos), rect.y(), pos, rect.height());
 
 }
 
@@ -771,47 +839,48 @@ void ClipItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) {
 }
 
 //virtual
-void ClipItem::hoverEnterEvent(QGraphicsSceneHoverEvent *) {
+void ClipItem::hoverEnterEvent(QGraphicsSceneHoverEvent *e) {
+    //if (e->pos().x() < 20) m_hover = true;
     m_hover = true;
     QRectF r = boundingRect();
-    qreal width = qMin(25.0, r.width());
-    update(r.x(), r.y(), width, r.height());
-    update(r.right() - width, r.y(), width, r.height());
+    double width = 35 / projectScene()->scale();
+    double height = r.height() / 2;
+    update(r.x(), r.y() + height, width, height);
+    update(r.right() - width, r.y() + height, width, height);
 }
 
 //virtual
 void ClipItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *) {
     m_hover = false;
     QRectF r = boundingRect();
-    qreal width = qMin(25.0, r.width());
-    update(r.x(), r.y(), width, r.height());
-    update(r.right() - width, r.y(), width, r.height());
+    double width = 35 / projectScene()->scale();
+    double height = r.height() / 2;
+    update(r.x(), r.y() + height, width, height);
+    update(r.right() - width, r.y() + height, width, height);
 }
 
-void ClipItem::resizeStart(int posx, double scale) {
+void ClipItem::resizeStart(int posx) {
     const int min = (startPos() - cropStart()).frames(m_fps);
     if (posx < min) posx = min;
     if (posx == startPos().frames(m_fps)) return;
     const int previous = cropStart().frames(m_fps);
-    AbstractClipItem::resizeStart(posx, scale);
+    AbstractClipItem::resizeStart(posx);
     checkEffectsKeyframesPos(previous, cropStart().frames(m_fps), true);
     if (m_hasThumbs && KdenliveSettings::videothumbnails()) {
-        m_thumbsRequested++;
-        connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));
+        /*connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));*/
         startThumbTimer->start(100);
     }
 }
 
-void ClipItem::resizeEnd(int posx, double scale) {
+void ClipItem::resizeEnd(int posx) {
     const int max = (startPos() - cropStart() + maxDuration()).frames(m_fps) + 1;
     if (posx > max) posx = max;
     if (posx == endPos().frames(m_fps)) return;
     const int previous = (cropStart() + duration()).frames(m_fps);
-    AbstractClipItem::resizeEnd(posx, scale);
+    AbstractClipItem::resizeEnd(posx);
     checkEffectsKeyframesPos(previous, (cropStart() + duration()).frames(m_fps), false);
     if (m_hasThumbs && KdenliveSettings::videothumbnails()) {
-        m_thumbsRequested++;
-        connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));
+        /*connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));*/
         endThumbTimer->start(100);
     }
 }
@@ -851,6 +920,55 @@ void ClipItem::checkEffectsKeyframesPos(const int previous, const int current, b
 }
 
 
+//virtual
+QVariant ClipItem::itemChange(GraphicsItemChange change, const QVariant &value) {
+    if (change == ItemPositionChange && scene()) {
+        // calculate new position.
+        if (group() != 0) return pos();
+        QPointF newPos = value.toPointF();
+        kDebug() << "/// MOVING CLIP ITEM.------------";
+        int xpos = projectScene()->getSnapPointForPos((int) newPos.x(), KdenliveSettings::snaptopoints());
+        xpos = qMax(xpos, 0);
+        newPos.setX(xpos);
+        int newTrack = (newPos.y() + KdenliveSettings::trackheight() / 2) / KdenliveSettings::trackheight();
+        newTrack = qMin(newTrack, projectScene()->tracksCount() - 1);
+        newTrack = qMax(newTrack, 0);
+        newPos.setY((int)(newTrack  * KdenliveSettings::trackheight() + 1));
+        // Only one clip is moving
+        QRectF sceneShape = rect();
+        sceneShape.translate(newPos);
+        QList<QGraphicsItem*> items = scene()->items(sceneShape, Qt::IntersectsItemShape);
+        items.removeAll(this);
+
+        if (!items.isEmpty()) {
+            for (int i = 0; i < items.count(); i++) {
+                if (items.at(i)->type() == type()) {
+                    // Collision!
+                    QPointF otherPos = items.at(i)->pos();
+                    if ((int) otherPos.y() != (int) pos().y()) return pos();
+                    if (pos().x() < otherPos.x()) {
+                        // move clip just before colliding clip
+                        int npos = (static_cast < AbstractClipItem* >(items.at(i))->startPos() - m_cropDuration).frames(m_fps);
+                        newPos.setX(npos);
+                    } else {
+                        // get pos just after colliding clip
+                        int npos = static_cast < AbstractClipItem* >(items.at(i))->endPos().frames(m_fps);
+                        newPos.setX(npos);
+                    }
+                    m_track = newTrack;
+                    m_startPos = GenTime((int) newPos.x(), m_fps);
+                    return newPos;
+                }
+            }
+        }
+        m_track = newTrack;
+        m_startPos = GenTime((int) newPos.x(), m_fps);
+        //kDebug()<<"// ITEM NEW POS: "<<newPos.x()<<", mapped: "<<mapToScene(newPos.x(), 0).x();
+        return newPos;
+    }
+    return QGraphicsItem::itemChange(change, value);
+}
+
 // virtual
 /*void ClipItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event) {
 }*/
@@ -885,8 +1003,8 @@ void ClipItem::setEffectAt(int ix, QDomElement effect) {
     }
 }
 
-QMap <QString, QString> ClipItem::addEffect(QDomElement effect, bool animate) {
-    QMap <QString, QString> effectParams;
+QHash <QString, QString> ClipItem::addEffect(QDomElement effect, bool animate) {
+    QHash <QString, QString> effectParams;
     bool needRepaint = false;
     /*QDomDocument doc;
     doc.appendChild(doc.importNode(effect, true));
@@ -950,8 +1068,8 @@ QMap <QString, QString> ClipItem::addEffect(QDomElement effect, bool animate) {
     return effectParams;
 }
 
-QMap <QString, QString> ClipItem::getEffectArgs(QDomElement effect) {
-    QMap <QString, QString> effectParams;
+QHash <QString, QString> ClipItem::getEffectArgs(QDomElement effect) {
+    QHash <QString, QString> effectParams;
     effectParams["tag"] = effect.attribute("tag");
     effectParams["kdenlive_ix"] = effect.attribute("kdenlive_ix");
     effectParams["id"] = effect.attribute("id");
@@ -960,7 +1078,7 @@ QMap <QString, QString> ClipItem::getEffectArgs(QDomElement effect) {
     QDomNodeList params = effect.elementsByTagName("parameter");
     for (int i = 0; i < params.count(); i++) {
         QDomElement e = params.item(i).toElement();
-        kDebug() << "/ / / /SENDING EFFECT PARAM: " << e.attribute("type") << ", NAME_ " << e.attribute("tag");
+        //kDebug() << "/ / / /SENDING EFFECT PARAM: " << e.attribute("type") << ", NAME_ " << e.attribute("tag");
         if (e.attribute("type") == "keyframe") {
             kDebug() << "/ / / /SENDING KEYFR EFFECT TYPE";
             effectParams["keyframes"] = e.attribute("keyframes");
index b62543c46a2c15011c92211d591960db0237d6fe..3c62293a81c3af3846285f384284c8bcb6e64bcd 100644 (file)
 #ifndef CLIPITEM_H
 #define CLIPITEM_H
 
+#include <QTimeLine>
 #include <QGraphicsRectItem>
 #include <QDomElement>
 #include <QGraphicsSceneMouseEvent>
-#include <QTimeLine>
+#include <QTimer>
 
 #include "definitions.h"
 #include "gentime.h"
 class DocClipBase;
 class Transition;
 
+
 class ClipItem : public AbstractClipItem {
     Q_OBJECT
 
 public:
-    ClipItem(DocClipBase *clip, ItemInfo info, double scale, double fps);
+    ClipItem(DocClipBase *clip, ItemInfo info, double fps);
     virtual ~ ClipItem();
     virtual void paint(QPainter *painter,
                        const QStyleOptionGraphicsItem *option,
                        QWidget *);
     virtual int type() const;
-    void resizeStart(int posx, double scale);
-    void resizeEnd(int posx, double scale);
-    OPERATIONTYPE operationMode(QPointF pos, double scale);
+    void resizeStart(int posx);
+    void resizeEnd(int posx);
+    OPERATIONTYPE operationMode(QPointF pos);
     int clipProducer() const;
     int clipType() const;
     DocClipBase *baseClip() const;
     QString clipName() const;
     QDomElement xml() const;
-    ClipItem *clone(double scale, ItemInfo info) const;
+    ClipItem *clone(ItemInfo info) const;
     const EffectsList effectList();
-    void setFadeOut(int pos, double scale);
-    void setFadeIn(int pos, double scale);
+    void setFadeOut(int pos);
+    void setFadeIn(int pos);
     /** Give a string list of the clip's effect names */
     QStringList effectNames();
     /** Add an effect to the clip and return the parameters that will be passed to Mlt */
-    QMap <QString, QString> addEffect(QDomElement effect, bool animate = true);
+    QHash <QString, QString> addEffect(QDomElement effect, bool animate = true);
     /** Get the effect parameters that will be passed to Mlt */
-    QMap <QString, QString> getEffectArgs(QDomElement effect);
+    QHash <QString, QString> getEffectArgs(QDomElement effect);
     /** Delete effect with id index */
     void deleteEffect(QString index);
     /** return the number of effects in that clip */
@@ -104,6 +106,7 @@ protected:
     virtual void dropEvent(QGraphicsSceneDragDropEvent *event);
     virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *);
     virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *);
+    virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
 
 private:
     DocClipBase *m_clip;
@@ -115,7 +118,6 @@ private:
     QString m_effectNames;
     uint m_startFade;
     uint m_endFade;
-
     int m_maxTrack;
 
     QPixmap m_startPix;
@@ -129,7 +131,8 @@ private:
     int m_selectedEffect;
     double m_opacity;
     QTimeLine *m_timeLine;
-    uint m_thumbsRequested;
+    bool m_startThumbRequested;
+    bool m_endThumbRequested;
     bool m_hover;
     double m_speed;
 
@@ -147,15 +150,17 @@ private slots:
     void slotGetStartThumb();
     void slotGetEndThumb();
     void slotGotAudioData();
-    void slotPrepareAudioThumb(double pixelForOneFrame, QPainterPath path, int startpixel, int endpixel, int channels);
+    void slotPrepareAudioThumb(double pixelForOneFrame, int startpixel, int endpixel, int channels);
     void animate(qreal value);
-
-public slots:
+    void slotSetStartThumb(QImage img);
+    void slotSetEndThumb(QImage img);
+    void slotSetStartThumb(QPixmap pix);
+    void slotSetEndThumb(QPixmap pix);
     void slotThumbReady(int frame, QPixmap pix);
 
 signals:
     void getThumb(int, int);
-    void prepareAudioThumb(double, QPainterPath, int, int, int);
+    void prepareAudioThumb(double, int, int, int);
 };
 
 #endif
index 1a10f32cb8899120f97ffac15851299de4ff6941..3ea21a4d2d8eb3464a6e44887f5da5e861486e96 100644 (file)
@@ -84,18 +84,18 @@ void CustomRuler::mousePressEvent(QMouseEvent * event) {
     int pos = (int)((event->x() + offset()));
     m_moveCursor = RULER_CURSOR;
     if (event->y() > 10) {
-        if (qAbs(pos - m_zoneStart * pixelPerMark() * FRAME_SIZE) < 4) m_moveCursor = RULER_START;
-        else if (qAbs(pos - (m_zoneStart + (m_zoneEnd - m_zoneStart) / 2) * pixelPerMark() * FRAME_SIZE) < 4) m_moveCursor = RULER_MIDDLE;
-        else if (qAbs(pos - m_zoneEnd * pixelPerMark() * FRAME_SIZE) < 4) m_moveCursor = RULER_END;
+        if (qAbs(pos - m_zoneStart * m_factor) < 4) m_moveCursor = RULER_START;
+        else if (qAbs(pos - (m_zoneStart + (m_zoneEnd - m_zoneStart) / 2) * m_factor) < 4) m_moveCursor = RULER_MIDDLE;
+        else if (qAbs(pos - m_zoneEnd * m_factor) < 4) m_moveCursor = RULER_END;
     }
     if (m_moveCursor == RULER_CURSOR)
-        m_view->setCursorPos((int) pos / pixelPerMark() / FRAME_SIZE);
+        m_view->setCursorPos((int) pos / m_factor);
 }
 
 // virtual
 void CustomRuler::mouseMoveEvent(QMouseEvent * event) {
     if (event->buttons() == Qt::LeftButton) {
-        int pos = (int)((event->x() + offset()) / pixelPerMark() / FRAME_SIZE);
+        int pos = (int)((event->x() + offset()) / m_factor);
         if (pos < 0) pos = 0;
         if (m_moveCursor == RULER_CURSOR) {
             m_view->setCursorPos(pos);
@@ -111,9 +111,9 @@ void CustomRuler::mouseMoveEvent(QMouseEvent * event) {
     } else {
         int pos = (int)((event->x() + offset()));
         if (event->y() <= 10) setCursor(Qt::ArrowCursor);
-        else if (qAbs(pos - m_zoneStart * pixelPerMark() * FRAME_SIZE) < 4) setCursor(KCursor("left_side", Qt::SizeHorCursor));
-        else if (qAbs(pos - m_zoneEnd * pixelPerMark() * FRAME_SIZE) < 4) setCursor(KCursor("right_side", Qt::SizeHorCursor));
-        else if (qAbs(pos - (m_zoneStart + (m_zoneEnd - m_zoneStart) / 2) * pixelPerMark() * FRAME_SIZE) < 4) setCursor(Qt::SizeHorCursor);
+        else if (qAbs(pos - m_zoneStart * m_factor) < 4) setCursor(KCursor("left_side", Qt::SizeHorCursor));
+        else if (qAbs(pos - m_zoneEnd * m_factor) < 4) setCursor(KCursor("right_side", Qt::SizeHorCursor));
+        else if (qAbs(pos - (m_zoneStart + (m_zoneEnd - m_zoneStart) / 2) * m_factor) < 4) setCursor(Qt::SizeHorCursor);
         else setCursor(Qt::ArrowCursor);
     }
 }
@@ -140,12 +140,13 @@ void CustomRuler::slotMoveRuler(int newPos) {
 }
 
 void CustomRuler::slotCursorMoved(int oldpos, int newpos) {
-    update(oldpos - offset() - 6, 2, 17, 16);
-    update(newpos - offset() - 6, 2, 17, 16);
+    update(oldpos * m_factor - offset() - 6, 2, 17, 16);
+    update(newpos * m_factor - offset() - 6, 2, 17, 16);
 }
 
 void CustomRuler::setPixelPerMark(double rate) {
     int scale = comboScale[(int) rate];
+    m_factor = 1.0 / (double) scale * FRAME_SIZE;
     KRuler::setPixelPerMark(1.0 / scale);
     double fend = pixelPerMark() * littleMarkDistance();
     switch ((int) rate) {
@@ -191,30 +192,21 @@ void CustomRuler::setDuration(int d) {
 
 // virtual
 void CustomRuler::paintEvent(QPaintEvent *e) {
-    //  debug ("KRuler::drawContents, %s",(horizontal==dir)?"horizontal":"vertical");
-
     QStylePainter p(this);
     p.setClipRect(e->rect());
 
-    //p.fillRect(e->rect(), QBrush(QColor(200, 200, 200)));
-    //kDebug()<<"RULER ZONE: "<<m_zoneStart<<", OFF: "<<offset()<<", END: "<<m_zoneEnd<<", FACTOR: "<<pixelPerMark() * FRAME_SIZE;
-    int projectEnd = (int)(m_duration * pixelPerMark() * FRAME_SIZE);
+    const int projectEnd = (int)(m_duration * m_factor);
     p.fillRect(QRect(- offset(), e->rect().y(), projectEnd, e->rect().height()), QBrush(QColor(245, 245, 245)));
 
-
-    int zoneStart = (int)(m_zoneStart * pixelPerMark() * FRAME_SIZE);
-    int zoneEnd = (int)(m_zoneEnd * pixelPerMark() * FRAME_SIZE);
+    const int zoneStart = (int)(m_zoneStart * m_factor);
+    const int zoneEnd = (int)(m_zoneEnd * m_factor);
 
     p.fillRect(QRect(zoneStart - offset(), e->rect().y() + e->rect().height() / 2, zoneEnd - zoneStart, e->rect().height() / 2), QBrush(QColor(133, 255, 143)));
 
-    int value  = m_view->cursorPos() - offset();
-    int minval = minimum();
-    int maxval = maximum() + offset() - endOffset();
+    const int value  = m_view->cursorPos() * m_factor - offset();
+    const int minval = minimum();
+    const int maxval = maximum() + offset() - endOffset();
 
-    //ioffsetval = value-offset;
-    //    pixelpm = (int)ppm;
-    //    left  = clip.left(),
-    //    right = clip.right();
     double f, fend,
     offsetmin = (double)(minval - offset()),
                 offsetmax = (double)(maxval - offset()),
@@ -248,7 +240,7 @@ void CustomRuler::paintEvent(QPaintEvent *e) {
     }*/
 
     for (f = offsetmin; f < offsetmax; f += m_textSpacing) {
-        QString lab = m_timecode.getTimecodeFromFrames((int)((f - offsetmin) / pixelPerMark() / FRAME_SIZE + 0.5));
+        QString lab = m_timecode.getTimecodeFromFrames((int)((f - offsetmin) / m_factor + 0.5));
         p.drawText((int)f + 2, LABEL_SIZE, lab);
     }
 
@@ -302,15 +294,10 @@ void CustomRuler::paintEvent(QPaintEvent *e) {
     }
 
     // draw pointer
-    if (showPointer() && value >= 0) {
-        QPolygon pa(3);
-        pa.setPoints(3, value - 6, 7, value + 6, 7, value, 16);
-        p.setBrush(QBrush(Qt::yellow));
-        p.drawPolygon(pa);
-    }
-
-
-
+    QPolygon pa(3);
+    pa.setPoints(3, value - 6, 7, value + 6, 7, value, 16);
+    p.setBrush(QBrush(Qt::yellow));
+    p.drawPolygon(pa);
 }
 
 #include "customruler.moc"
index f5f62341dc47e9c1affa419389425f4073830639..e35aca6b932150aa4d4ec303e07d163f2146732e 100644 (file)
@@ -33,6 +33,7 @@ private:
     int m_zoneEnd;
     int m_duration;
     double m_textSpacing;
+    double m_factor;
     RULER_MOVE m_moveCursor;
     QMenu *m_contextMenu;
 
diff --git a/src/customtrackscene.cpp b/src/customtrackscene.cpp
new file mode 100644 (file)
index 0000000..e560320
--- /dev/null
@@ -0,0 +1,83 @@
+/***************************************************************************
+ *   Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
+ ***************************************************************************/
+
+#include <KStandardDirs>
+
+#include "kdenlivedoc.h"
+#include "customtrackscene.h"
+
+CustomTrackScene::CustomTrackScene(KdenliveDoc *doc, QObject *parent)
+        : QGraphicsScene(parent), m_document(doc), m_scale(1.0) {
+    m_transitionPixmap = QPixmap(KStandardDirs::locate("appdata", "transition.png"));
+}
+
+CustomTrackScene::~CustomTrackScene() {
+}
+
+double CustomTrackScene::getSnapPointForPos(double pos, bool doSnap) {
+    double maximumOffset;
+    if (doSnap) {
+        if (m_scale > 3) maximumOffset = 10 / m_scale;
+        else maximumOffset = 6 / m_scale;
+        for (int i = 0; i < m_snapPoints.size(); ++i) {
+            if (qAbs((int)(pos - m_snapPoints.at(i).frames(m_document->fps()))) < maximumOffset) {
+                return m_snapPoints.at(i).frames(m_document->fps());
+            }
+            if (m_snapPoints.at(i).frames(m_document->fps()) > pos) break;
+        }
+    }
+    return GenTime(pos, m_document->fps()).frames(m_document->fps());
+}
+
+void CustomTrackScene::setSnapList(QList <GenTime> snaps) {
+    m_snapPoints = snaps;
+}
+
+GenTime CustomTrackScene::previousSnapPoint(GenTime pos) {
+    for (int i = 0; i < m_snapPoints.size(); ++i) {
+        if (m_snapPoints.at(i) >= pos) {
+            if (i == 0) i = 1;
+            return m_snapPoints.at(i - 1);
+        }
+    }
+    return GenTime();
+}
+
+GenTime CustomTrackScene::nextSnapPoint(GenTime pos) {
+    for (int i = 0; i < m_snapPoints.size(); ++i) {
+        if (m_snapPoints.at(i) > pos) {
+            return m_snapPoints.at(i);
+        }
+    }
+    return pos;
+}
+
+void CustomTrackScene::setScale(double scale) {
+    m_scale = scale;
+}
+
+double CustomTrackScene::scale() {
+    return m_scale;
+}
+
+int CustomTrackScene::tracksCount() {
+    return m_tracksList.count();
+}
+
+#include "customtrackscene.moc"
diff --git a/src/customtrackscene.h b/src/customtrackscene.h
new file mode 100644 (file)
index 0000000..9f037b8
--- /dev/null
@@ -0,0 +1,58 @@
+/***************************************************************************
+ *   Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
+ ***************************************************************************/
+
+
+#ifndef CUSTOMTRACKSCENE_H
+#define CUSTOMTRACKSCENE_H
+
+#include <QList>
+#include <QGraphicsScene>
+#include <QPixmap>
+
+#include "gentime.h"
+
+class KdenliveDoc;
+class TrackInfo;
+
+/** This class holds all properties that need to be used by clip items */
+
+class CustomTrackScene : public QGraphicsScene {
+    Q_OBJECT
+
+public:
+    CustomTrackScene(KdenliveDoc *doc, QObject *parent = 0);
+    virtual ~ CustomTrackScene();
+    void setSnapList(QList <GenTime> snaps);
+    GenTime previousSnapPoint(GenTime pos);
+    GenTime nextSnapPoint(GenTime pos);
+    double getSnapPointForPos(double pos, bool doSnap = true);
+    void setScale(double scale);
+    double scale();
+    QList <TrackInfo> m_tracksList;
+    int tracksCount();
+    QPixmap m_transitionPixmap;
+
+private:
+    KdenliveDoc *m_document;
+    QList <GenTime> m_snapPoints;
+    double m_scale;
+};
+
+#endif
+
index 25228bc7257164d3e62ebcfe4752929000f9ce41..1d14d1216c4347021ff18dce4ac732d4d46fdd8d 100644 (file)
@@ -32,6 +32,7 @@
 #include <KCursor>
 
 #include "customtrackview.h"
+#include "customtrackscene.h"
 #include "docclipbase.h"
 #include "clipitem.h"
 #include "definitions.h"
@@ -59,6 +60,7 @@
 #include "mainwindow.h"
 #include "ui_keyframedialog_ui.h"
 #include "clipdurationdialog.h"
+#include "abstractgroupitem.h"
 
 
 //TODO:
@@ -69,8 +71,8 @@
 // const bool animate = KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects;
 // const int duration = animate ? 1500 : 1;
 
-CustomTrackView::CustomTrackView(KdenliveDoc *doc, QGraphicsScene * projectscene, QWidget *parent)
-        : 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), m_findIndex(0), m_menuPosition(QPoint()), m_blockRefresh(false) {
+CustomTrackView::CustomTrackView(KdenliveDoc *doc, CustomTrackScene* projectscene, QWidget *parent)
+        : QGraphicsView(projectscene, parent), m_scene(projectscene), 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_clickPoint(QPoint()), m_document(doc), m_autoScroll(KdenliveSettings::autoscroll()), m_tracksHeight(KdenliveSettings::trackheight()), m_tool(SELECTTOOL), m_dragGuide(NULL), m_findIndex(0), m_menuPosition(QPoint()), m_blockRefresh(false), m_selectionGroup(NULL) {
     if (doc) m_commandStack = doc->commandStack();
     else m_commandStack == NULL;
     setMouseTracking(true);
@@ -112,7 +114,7 @@ void CustomTrackView::checkAutoScroll() {
 }
 
 QList <TrackInfo> CustomTrackView::tracksList() const {
-    return m_tracksList;
+    return m_scene->m_tracksList;
 }
 
 void CustomTrackView::checkTrackHeight() {
@@ -125,25 +127,25 @@ void CustomTrackView::checkTrackHeight() {
     for (int i = 0; i < itemList.count(); i++) {
         if (itemList.at(i)->type() == AVWIDGET) {
             item = (ClipItem*) itemList.at(i);
-            item->setRect(0, 0, item->rect().width(), m_tracksHeight - 1);
-            item->setPos((qreal) item->startPos().frames(m_document->fps()) * m_scale, (qreal) item->track() * m_tracksHeight);
+            item->setRect(0, 0, item->rect().width() - 0.02, m_tracksHeight - 1);
+            item->setPos((qreal) item->startPos().frames(m_document->fps()), (qreal) item->track() * m_tracksHeight + 1);
             item->resetThumbs();
         } else if (itemList.at(i)->type() == TRANSITIONWIDGET) {
             transitionitem = (Transition*) itemList.at(i);
-            transitionitem->setRect(0, 0, transitionitem->rect().width(), m_tracksHeight / 3 * 2 - 1);
-            transitionitem->setPos((qreal) transitionitem->startPos().frames(m_document->fps()) * m_scale, (qreal) transitionitem->track() * m_tracksHeight + m_tracksHeight / 3 * 2);
+            transitionitem->setRect(0, 0, transitionitem->rect().width() - 0.02, m_tracksHeight / 3 * 2 - 1);
+            transitionitem->setPos((qreal) transitionitem->startPos().frames(m_document->fps()), (qreal) transitionitem->track() * m_tracksHeight + m_tracksHeight / 3 * 2);
         }
     }
-    m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_tracksList.count());
+    m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_scene->m_tracksList.count());
 
     for (int i = 0; i < m_guides.count(); i++) {
         QLineF l = m_guides.at(i)->line();
-        l.setP2(QPointF(l.x2(), m_tracksHeight * m_tracksList.count()));
+        l.setP2(QPointF(l.x2(), m_tracksHeight * m_scene->m_tracksList.count()));
         m_guides.at(i)->setLine(l);
     }
 
-    setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_tracksList.count());
-    verticalScrollBar()->setMaximum(m_tracksHeight * m_tracksList.count());
+    setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_scene->m_tracksList.count());
+    verticalScrollBar()->setMaximum(m_tracksHeight * m_scene->m_tracksList.count());
     update();
 }
 
@@ -164,10 +166,10 @@ void CustomTrackView::wheelEvent(QWheelEvent * e) {
 }
 
 int CustomTrackView::getPreviousVideoTrack(int track) {
-    track = m_tracksList.count() - track - 1;
+    track = m_scene->m_tracksList.count() - track - 1;
     track --;
     for (int i = track; i > -1; i--) {
-        if (m_tracksList.at(i).type == VIDEOTRACK) return i + 1;
+        if (m_scene->m_tracksList.at(i).type == VIDEOTRACK) return i + 1;
     }
     return 0;
 }
@@ -176,47 +178,49 @@ int CustomTrackView::getPreviousVideoTrack(int track) {
 
 void CustomTrackView::mouseMoveEvent(QMouseEvent * event) {
     int pos = event->x();
-    emit mousePosition((int)(mapToScene(event->pos()).x() / m_scale));
+    emit mousePosition((int)(mapToScene(event->pos()).x()));
     if (event->buttons() & Qt::MidButton) return;
     if (event->buttons() != Qt::NoButton) {
-        if (m_dragItem && m_tool == SELECTTOOL) { //event->button() == Qt::LeftButton) {
-            // a button was pressed, delete visual tips
-            if (m_operationMode == MOVE && (event->pos() - m_clickEvent).manhattanLength() >= QApplication::startDragDistance()) {
-                double snappedPos = getSnapPointForPos(mapToScene(event->pos()).x() - m_clickPoint.x());
-                //kDebug() << "///////  MOVE CLIP, EVENT Y: "<<m_clickPoint.y();//<<event->scenePos().y()<<", SCENE HEIGHT: "<<scene()->sceneRect().height();
-                int moveTrack = (int)  mapToScene(event->pos() - QPoint(0, (m_dragItem->type() == TRANSITIONWIDGET ? m_dragItem->boundingRect().height() / 2 : 0))).y() / m_tracksHeight;
-                int currentTrack = m_dragItem->track();
-
-                if (moveTrack > 1000) moveTrack = 0;
-                else if (moveTrack > m_tracksList.count() - 1) moveTrack = m_tracksList.count() - 1;
-                else if (moveTrack < 0) moveTrack = 0;
-
-                int offset = moveTrack - currentTrack;
-                if (m_selectedClipList.count() == 1) m_dragItem->moveTo((int)(snappedPos / m_scale), m_scale, offset * m_tracksHeight, moveTrack);
-                else {
-                    int moveOffset = (int)(snappedPos / m_scale) - m_dragItem->startPos().frames(m_document->fps());
-                    if (canBeMoved(m_selectedClipList, GenTime(moveOffset, m_document->fps()), offset)) {
-                        for (int i = 0; i < m_selectedClipList.count(); i++) {
-                            AbstractClipItem *item = m_selectedClipList.at(i);
-                            item->moveTo(item->startPos().frames(m_document->fps()) + moveOffset, m_scale, offset * m_tracksHeight, item->track() + offset, false);
-                        }
-                    }
-                }
+        if (m_dragItem && m_tool == SELECTTOOL) {
+            if (m_operationMode == MOVE) {
+                QGraphicsView::mouseMoveEvent(event);
+
+                /*&& (event->pos() - m_clickEvent).manhattanLength() >= QApplication::startDragDistance()) {
+                           double snappedPos = getSnapPointForPos(mapToScene(event->pos()).x() - m_clickPoint.x());
+                           //kDebug() << "///////  MOVE CLIP, EVENT Y: "<<m_clickPoint.y();//<<event->scenePos().y()<<", SCENE HEIGHT: "<<scene()->sceneRect().height();
+                           int moveTrack = (int)  mapToScene(event->pos() - QPoint(0, (m_dragItem->type() == TRANSITIONWIDGET ? m_dragItem->boundingRect().height() / 2 : 0))).y() / m_tracksHeight;
+                           int currentTrack = m_dragItem->track();
+
+                           if (moveTrack > 1000) moveTrack = 0;
+                           else if (moveTrack > m_scene->m_tracksList.count() - 1) moveTrack = m_scene->m_tracksList.count() - 1;
+                           else if (moveTrack < 0) moveTrack = 0;
+
+                           int offset = moveTrack - currentTrack;
+                           if (m_selectedClipList.count() == 1) m_dragItem->moveTo((int)(snappedPos / m_scale), m_scale, offset * m_tracksHeight, moveTrack);
+                           else {
+                               int moveOffset = (int)(snappedPos / m_scale) - m_dragItem->startPos().frames(m_document->fps());
+                               if (canBeMoved(m_selectedClipList, GenTime(moveOffset, m_document->fps()), offset)) {
+                                   for (int i = 0; i < m_selectedClipList.count(); i++) {
+                                       AbstractClipItem *item = m_selectedClipList.at(i);
+                                       item->moveTo(item->startPos().frames(m_document->fps()) + moveOffset, m_scale, offset * m_tracksHeight, item->track() + offset, false);
+                                   }
+                               }
+                           }*/
 
             } else if (m_operationMode == RESIZESTART) {
                 double snappedPos = getSnapPointForPos(mapToScene(event->pos()).x());
-                m_dragItem->resizeStart((int)(snappedPos / m_scale), m_scale);
+                m_dragItem->resizeStart((int)(snappedPos));
             } else if (m_operationMode == RESIZEEND) {
                 double snappedPos = getSnapPointForPos(mapToScene(event->pos()).x());
-                m_dragItem->resizeEnd((int)(snappedPos / m_scale), m_scale);
+                m_dragItem->resizeEnd((int)(snappedPos));
             } else if (m_operationMode == FADEIN) {
-                int pos = (int)(mapToScene(event->pos()).x() / m_scale);
-                ((ClipItem*) m_dragItem)->setFadeIn((int)(pos - m_dragItem->startPos().frames(m_document->fps())), m_scale);
+                int pos = (int)(mapToScene(event->pos()).x());
+                ((ClipItem*) m_dragItem)->setFadeIn((int)(pos - m_dragItem->startPos().frames(m_document->fps())));
             } else if (m_operationMode == FADEOUT) {
-                int pos = (int)(mapToScene(event->pos()).x() / m_scale);
-                ((ClipItem*) m_dragItem)->setFadeOut((int)(m_dragItem->endPos().frames(m_document->fps()) - pos), m_scale);
+                int pos = (int)(mapToScene(event->pos()).x());
+                ((ClipItem*) m_dragItem)->setFadeOut((int)(m_dragItem->endPos().frames(m_document->fps()) - pos));
             } else if (m_operationMode == KEYFRAME) {
-                GenTime keyFramePos = GenTime((int)(mapToScene(event->pos()).x() / m_scale), m_document->fps()) - m_dragItem->startPos() + m_dragItem->cropStart();
+                GenTime keyFramePos = GenTime((int)(mapToScene(event->pos()).x()), m_document->fps()) - m_dragItem->startPos() + m_dragItem->cropStart();
                 double pos = mapToScene(event->pos()).toPoint().y();
                 QRectF br = m_dragItem->sceneBoundingRect();
                 double maxh = 100.0 / br.height();
@@ -228,7 +232,6 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) {
             m_animation = NULL;
             if (m_visualTip) delete m_visualTip;
             m_visualTip = NULL;
-            QGraphicsView::mouseMoveEvent(event);
             return;
         } else if (m_operationMode == MOVEGUIDE) {
             if (m_animation) delete m_animation;
@@ -264,14 +267,14 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) {
         if (m_tool == RAZORTOOL) {
             // razor tool over a clip, display current frame in monitor
             if (!m_blockRefresh && item->type() == AVWIDGET) {
-               //TODO: solve crash when showing frame when moving razor over clip
+                //TODO: solve crash when showing frame when moving razor over clip
                 //emit showClipFrame(((ClipItem *) item)->baseClip(), mapToScene(event->pos()).x() / m_scale - (clip->startPos() - clip->cropStart()).frames(m_document->fps()));
             }
             event->accept();
             return;
         }
-        opMode = clip->operationMode(mapToScene(event->pos()), m_scale);
-        double size = 8;
+        opMode = clip->operationMode(mapToScene(event->pos()));
+        double size = 5;
         if (opMode == m_moveOpMode) {
             QGraphicsView::mouseMoveEvent(event);
             return;
@@ -292,25 +295,26 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) {
             if (m_visualTip == NULL) {
                 QRectF rect = clip->sceneBoundingRect();
                 QPolygon polygon;
-                polygon << QPoint((int)rect.x(), (int)(rect.y() + rect.height() / 2 - size * 2));
-                polygon << QPoint((int)(rect.x() + size * 2), (int)(rect.y() + rect.height() / 2));
-                polygon << QPoint((int)rect.x(), (int)(rect.y() + rect.height() / 2 + size * 2));
-                polygon << QPoint((int)rect.x(), (int)(rect.y() + rect.height() / 2 - size * 2));
+                polygon << QPoint(0, rect.height() / 2 - size * 2);
+                polygon << QPoint(size * 2, (int)(rect.height() / 2));
+                polygon << QPoint(0, (int)(rect.height() / 2 + size * 2));
+                polygon << QPoint(0, (int)(rect.height() / 2 - size * 2));
 
                 m_visualTip = new QGraphicsPolygonItem(polygon);
                 ((QGraphicsPolygonItem*) m_visualTip)->setBrush(m_tipColor);
                 ((QGraphicsPolygonItem*) m_visualTip)->setPen(m_tipPen);
+                m_visualTip->setPos(rect.x(), rect.y());
+                m_visualTip->setFlags(QGraphicsItem::ItemIgnoresTransformations);
                 m_visualTip->setZValue(100);
                 m_animation = new QGraphicsItemAnimation;
                 m_animation->setItem(m_visualTip);
                 m_animation->setTimeLine(m_animationTimer);
-                m_visualTip->setPos(0, 0);
                 double scale = 2.0;
                 m_animation->setScaleAt(.5, scale, 1);
-                m_animation->setPosAt(.5, QPointF(rect.x() - rect.x() * scale, 0));
+                //m_animation->setPosAt(.5, QPointF(rect.x() - rect.x() * scale, 0));
                 scale = 1.0;
                 m_animation->setScaleAt(1, scale, 1);
-                m_animation->setPosAt(1, QPointF(rect.x() - rect.x() * scale, 0));
+                //m_animation->setPosAt(1, QPointF(rect.x() - rect.x() * scale, 0));
                 scene()->addItem(m_visualTip);
                 m_animationTimer->start();
             }
@@ -319,46 +323,44 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) {
             if (m_visualTip == NULL) {
                 QRectF rect = clip->sceneBoundingRect();
                 QPolygon polygon;
-                polygon << QPoint((int)(rect.x() + rect.width()), (int)(rect.y() + rect.height() / 2 - size * 2));
-                polygon << QPoint((int)(rect.x() + rect.width() - size * 2), (int)(rect.y() + rect.height() / 2));
-                polygon << QPoint((int)(rect.x() + rect.width()), (int)(rect.y() + rect.height() / 2 + size * 2));
-                polygon << QPoint((int)(rect.x() + rect.width()), (int)(rect.y() + rect.height() / 2 - size * 2));
+                polygon << QPoint(0, (int)(rect.height() / 2 - size * 2));
+                polygon << QPoint(- size * 2, (int)(rect.height() / 2));
+                polygon << QPoint(0, (int)(rect.height() / 2 + size * 2));
+                polygon << QPoint(0, (int)(rect.height() / 2 - size * 2));
 
                 m_visualTip = new QGraphicsPolygonItem(polygon);
                 ((QGraphicsPolygonItem*) m_visualTip)->setBrush(m_tipColor);
                 ((QGraphicsPolygonItem*) m_visualTip)->setPen(m_tipPen);
-
+                m_visualTip->setFlags(QGraphicsItem::ItemIgnoresTransformations);
+                m_visualTip->setPos(rect.right(), rect.y());
                 m_visualTip->setZValue(100);
                 m_animation = new QGraphicsItemAnimation;
                 m_animation->setItem(m_visualTip);
                 m_animation->setTimeLine(m_animationTimer);
-                m_visualTip->setPos(0, 0);
                 double scale = 2.0;
                 m_animation->setScaleAt(.5, scale, 1);
-                m_animation->setPosAt(.5, QPointF(rect.x() - rect.x() * scale - rect.width(), 0));
                 scale = 1.0;
                 m_animation->setScaleAt(1, scale, 1);
-                m_animation->setPosAt(1, QPointF(rect.x() - rect.x() * scale, 0));
                 scene()->addItem(m_visualTip);
                 m_animationTimer->start();
             }
         } else if (opMode == FADEIN) {
             if (m_visualTip == NULL) {
                 ClipItem *item = (ClipItem *) clip;
-                m_visualTip = new QGraphicsEllipseItem(item->pos().x() + item->fadeIn() * m_scale - size, item->pos().y() - 8, size * 2, 16);
+                QRectF rect = clip->sceneBoundingRect();
+                m_visualTip = new QGraphicsEllipseItem(-size, -size, size * 2, size * 2);
                 ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor);
                 ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen);
+                m_visualTip->setPos(rect.x() + item->fadeIn(), rect.y());
+                m_visualTip->setFlags(QGraphicsItem::ItemIgnoresTransformations);
                 m_visualTip->setZValue(100);
                 m_animation = new QGraphicsItemAnimation;
                 m_animation->setItem(m_visualTip);
                 m_animation->setTimeLine(m_animationTimer);
-                m_visualTip->setPos(0, 0);
                 double scale = 2.0;
                 m_animation->setScaleAt(.5, scale, scale);
-                m_animation->setPosAt(.5, QPointF(item->pos().x() - item->pos().x() * scale -  item->fadeIn() * m_scale, item->pos().y() - item->pos().y() * scale));
                 scale = 1.0;
                 m_animation->setScaleAt(1, scale, scale);
-                m_animation->setPosAt(1, QPointF(item->pos().x() - item->pos().x() * scale, item->pos().y() - item->pos().y() * scale));
                 scene()->addItem(m_visualTip);
                 m_animationTimer->start();
             }
@@ -366,26 +368,26 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) {
         } else if (opMode == FADEOUT) {
             if (m_visualTip == NULL) {
                 ClipItem *item = (ClipItem *) clip;
-                m_visualTip = new QGraphicsEllipseItem(item->pos().x() + item->rect().width() - item->fadeOut() * m_scale - size, item->pos().y() - 8, size*2, 16);
+                QRectF rect = clip->sceneBoundingRect();
+                m_visualTip = new QGraphicsEllipseItem(-size, -size, size * 2, size * 2);
                 ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor);
                 ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen);
+                m_visualTip->setPos(rect.right() - item->fadeOut(), rect.y());
+                m_visualTip->setFlags(QGraphicsItem::ItemIgnoresTransformations);
                 m_visualTip->setZValue(100);
                 m_animation = new QGraphicsItemAnimation;
                 m_animation->setItem(m_visualTip);
                 m_animation->setTimeLine(m_animationTimer);
-                m_visualTip->setPos(0, 0);
                 double scale = 2.0;
                 m_animation->setScaleAt(.5, scale, scale);
-                m_animation->setPosAt(.5, QPointF(item->pos().x() - item->pos().x() * scale - item->rect().width() + item->fadeOut() * m_scale, item->pos().y() - item->pos().y() * scale));
                 scale = 1.0;
                 m_animation->setScaleAt(1, scale, scale);
-                m_animation->setPosAt(1, QPointF(item->pos().x() - item->pos().x() * scale, item->pos().y() - item->pos().y() * scale));
                 scene()->addItem(m_visualTip);
                 m_animationTimer->start();
             }
             setCursor(Qt::PointingHandCursor);
         } else if (opMode == TRANSITIONSTART) {
-            if (m_visualTip == NULL) {
+            /*if (m_visualTip == NULL) {
                 QRectF rect = clip->sceneBoundingRect();
                 m_visualTip = new QGraphicsEllipseItem(-5, -5 , 10, 10);
                 ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor);
@@ -401,10 +403,10 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) {
                 m_animation->setScaleAt(1, scale, scale);
                 scene()->addItem(m_visualTip);
                 m_animationTimer->start();
-            }
+            }*/
             setCursor(Qt::PointingHandCursor);
         } else if (opMode == TRANSITIONEND) {
-            if (m_visualTip == NULL) {
+            /*if (m_visualTip == NULL) {
                 QRectF rect = clip->sceneBoundingRect();
                 m_visualTip = new QGraphicsEllipseItem(-5, -5 , 10, 10);
                 ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor);
@@ -420,7 +422,7 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) {
                 m_animation->setScaleAt(1, scale, scale);
                 scene()->addItem(m_visualTip);
                 m_animationTimer->start();
-            }
+            }*/
             setCursor(Qt::PointingHandCursor);
         } else if (opMode == KEYFRAME) {
             setCursor(Qt::PointingHandCursor);
@@ -435,7 +437,7 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) {
     } else {
         m_moveOpMode = NONE;
         if (event->buttons() != Qt::NoButton && event->modifiers() == Qt::NoModifier) {
-            setCursorPos((int)(mapToScene(event->pos().x(), 0).x() / m_scale));
+            setCursorPos((int)(mapToScene(event->pos().x(), 0).x()));
         }
         if (m_visualTip) {
             if (m_animation) delete m_animation;
@@ -454,139 +456,192 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) {
 void CustomTrackView::mousePressEvent(QMouseEvent * event) {
     m_menuPosition = QPoint();
     m_blockRefresh = true;
+    bool collision = false;
+
     if (m_tool != RAZORTOOL) activateMonitor();
     m_clickEvent = event->pos();
-    QList<QGraphicsItem *> collisionList = items(event->pos());
+
+    // special cases (middle click button or ctrl / shift click
     if (event->button() == Qt::MidButton) {
         m_document->renderer()->switchPlay();
         m_blockRefresh = false;
         return;
     }
+
+    // check item under mouse
+    QList<QGraphicsItem *> collisionList = items(event->pos());
+
     if (event->modifiers() == Qt::ControlModifier && collisionList.count() == 0) {
         setDragMode(QGraphicsView::ScrollHandDrag);
         QGraphicsView::mousePressEvent(event);
         m_blockRefresh = false;
         return;
-    } else if (event->modifiers() == Qt::ShiftModifier && collisionList.count() == 0) {
+    }
+
+    if (event->modifiers() == Qt::ShiftModifier && collisionList.count() == 0) {
         setDragMode(QGraphicsView::RubberBandDrag);
         QGraphicsView::mousePressEvent(event);
         m_blockRefresh = false;
         return;
-    } else {
-        bool collision = false;
-        if (collisionList.count() == 1 && collisionList.at(0)->type() == GUIDEITEM) {
-            // a guide item was pressed
-            collisionList.at(0)->setFlag(QGraphicsItem::ItemIsMovable, true);
+    }
+
+    if (collisionList.count() == 1 && collisionList.at(0)->type() == GUIDEITEM) {
+        // a guide item was pressed
+        collisionList.at(0)->setFlag(QGraphicsItem::ItemIsMovable, true);
+        m_dragItem = NULL;
+        m_dragGuide = (Guide *) collisionList.at(0);
+        collision = true;
+        m_operationMode = MOVEGUIDE;
+        // deselect all clips so that only the guide will move
+        m_scene->clearSelection();
+        if (m_selectionGroup) {
+            scene()->destroyItemGroup(m_selectionGroup);
+            m_selectionGroup = NULL;
+        }
+        updateSnapPoints(NULL);
+        QGraphicsView::mousePressEvent(event);
+        return;
+    }
+
+    // Find first clip or transition under mouse
+    int i = 0;
+    m_dragItem = NULL;
+    while (i < collisionList.count()) {
+        if (collisionList.at(i)->type() == AVWIDGET || collisionList.at(i)->type() == TRANSITIONWIDGET) {
+            m_dragItem = static_cast <AbstractClipItem *>(collisionList.at(i));
+            m_dragItemInfo = m_dragItem->info();
+            break;
+        }
+        i++;
+    }
+
+    // context menu requested
+    if (event->button() == Qt::RightButton) {
+        if (m_dragItem) {
+            if (!m_dragItem->isSelected()) {
+                m_scene->clearSelection();
+                if (m_selectionGroup) scene()->destroyItemGroup(m_selectionGroup);
+                m_dragItem->setSelected(true);
+            }
+        }
+        m_operationMode = NONE;
+        displayContextMenu(event->globalPos(), m_dragItem);
+        m_menuPosition = event->pos();
+        m_dragItem = NULL;
+        event->accept();
+        return;
+    }
+
+    // No item under click
+    if (m_dragItem == NULL) {
+        if (m_selectionGroup) scene()->destroyItemGroup(m_selectionGroup);
+        setCursor(Qt::ArrowCursor);
+        m_scene->clearSelection();
+        setCursorPos((int)(mapToScene(event->x(), 0).x()));
+        event->accept();
+        return;
+    }
+
+    // Razor tool
+    if (m_tool == RAZORTOOL) {
+        if (m_dragItem->type() == TRANSITIONWIDGET) {
+            emit displayMessage(i18n("Cannot cut a transition"), ErrorMessage);
+            event->accept();
             m_dragItem = NULL;
-            m_dragGuide = (Guide *) collisionList.at(0);
-            collision = true;
-            m_operationMode = MOVEGUIDE;
-            // deselect all clips so that only the guide will move
-            QList<QGraphicsItem *> clips = scene()->selectedItems();
-            for (int i = 0; i < clips.count(); ++i)
-                clips.at(i)->setSelected(false);
-            updateSnapPoints(NULL);
-            QGraphicsView::mousePressEvent(event);
-        } else for (int i = 0; i < collisionList.count(); ++i) {
-                QGraphicsItem *item = collisionList.at(i);
-                if (item->type() == AVWIDGET || item->type() == TRANSITIONWIDGET) {
-                    if (m_tool == RAZORTOOL) {
-                        m_dragItem = NULL;
-                        if (item->type() == TRANSITIONWIDGET) {
-                            emit displayMessage(i18n("Cannot cut a transition"), ErrorMessage);
-                            event->accept();
-                            return;
-                        }
-                        AbstractClipItem *clip = static_cast <AbstractClipItem *>(item);
-                        RazorClipCommand* command = new RazorClipCommand(this, clip->info(), GenTime((int)(mapToScene(event->pos()).x() / m_scale), m_document->fps()), true);
-                        m_commandStack->push(command);
-                        m_document->setModified(true);
-                        event->accept(); //QGraphicsView::mousePressEvent(event);
-                        return;
-                    }
-                    // select item
-                    if (!item->isSelected()) {
-
-                        if (event->modifiers() != Qt::ControlModifier) {
-                            QList<QGraphicsItem *> itemList = items();
-                            for (int i = 0; i < itemList.count(); i++) {
-                                itemList.at(i)->setSelected(false);
-                                itemList.at(i)->update();
+            return;
+        }
+        AbstractClipItem *clip = static_cast <AbstractClipItem *>(m_dragItem);
+        RazorClipCommand* command = new RazorClipCommand(this, clip->info(), GenTime((int)(mapToScene(event->pos()).x()), m_document->fps()), true);
+        m_commandStack->push(command);
+        m_document->setModified(true);
+        m_dragItem = NULL;
+        event->accept();
+        return;
+    }
+    updateSnapPoints(m_dragItem);
+    if (m_dragItem && m_dragItem->type() == AVWIDGET) emit clipItemSelected((ClipItem*) m_dragItem);
+    else emit clipItemSelected(NULL);
+
+    if (m_operationMode == NONE) QGraphicsView::mousePressEvent(event);
+
+    if (m_selectionGroup) {
+        // delete selection group
+        scene()->destroyItemGroup(m_selectionGroup);
+        m_selectionGroup = NULL;
+    }
+
+    QList<QGraphicsItem *> selection = m_scene->selectedItems();
+    if (selection.count() > 1) {
+        m_selectionGroup = new AbstractGroupItem(m_document->fps());
+        scene()->addItem(m_selectionGroup);
+        for (int i = 0; i < selection.count(); i++) {
+            if (selection.at(i)->type() == AVWIDGET)
+                m_selectionGroup->addItem(selection.at(i));
+        }
+    }
+
+    m_clickPoint = QPoint((int)(mapToScene(event->pos()).x() - m_dragItem->startPos().frames(m_document->fps())), (int)(event->pos().y() - m_dragItem->pos().y()));
+    /*
+                        if (!item->isSelected()) {
+
+                            if (event->modifiers() != Qt::ControlModifier) {
+                                QList<QGraphicsItem *> itemList = items();
+                                for (int i = 0; i < itemList.count(); i++) {
+                                    itemList.at(i)->setSelected(false);
+                                    itemList.at(i)->update();
+                                }
                             }
+                            item->setSelected(true);
+                            item->update();
                         }
-                        item->setSelected(true);
-                        item->update();
-                    }
 
-                    m_dragItem = (AbstractClipItem *) item;
 
-                    m_clickPoint = QPoint((int)(mapToScene(event->pos()).x() - m_dragItem->startPos().frames(m_document->fps()) * m_scale), (int)(event->pos().y() - m_dragItem->pos().y()));
-                    m_dragItemInfo.startPos = m_dragItem->startPos();
-                    m_dragItemInfo.endPos = m_dragItem->endPos();
-                    m_dragItemInfo.track = m_dragItem->track();
 
-                    m_selectedClipList.clear();
-                    QList<QGraphicsItem *> selected = scene()->selectedItems();
-                    for (int i = 0; i < selected.count(); i++) {
-                        if (selected.at(i)->type() == AVWIDGET || selected.at(i)->type() == TRANSITIONWIDGET)
-                            m_selectedClipList.append(static_cast <AbstractClipItem *>(selected.at(i)));
-                    }
+                        m_clickPoint = QPoint((int)(mapToScene(event->pos()).x() - m_dragItem->startPos().frames(m_document->fps()) * m_scale), (int)(event->pos().y() - m_dragItem->pos().y()));
+                        m_dragItemInfo.startPos = m_dragItem->startPos();
+                        m_dragItemInfo.endPos = m_dragItem->endPos();
+                        m_dragItemInfo.track = m_dragItem->track();
 
-                    m_operationMode = m_dragItem->operationMode(mapToScene(event->pos()), m_scale);
-                    if (m_operationMode == KEYFRAME) {
-                        m_dragItem->updateSelectedKeyFrame();
-                        m_blockRefresh = false;
-                        return;
-                    } else if (m_operationMode == MOVE) setCursor(Qt::ClosedHandCursor);
-                    else if (m_operationMode == TRANSITIONSTART) {
-                        ItemInfo info;
-                        info.startPos = m_dragItem->startPos();
-                        info.track = m_dragItem->track();
-                        int transitiontrack = getPreviousVideoTrack(info.track);
-                        ClipItem *transitionClip = NULL;
-                        if (transitiontrack != 0) transitionClip = getClipItemAt((int) info.startPos.frames(m_document->fps()), m_tracksList.count() - transitiontrack);
-                        if (transitionClip && transitionClip->endPos() < m_dragItem->endPos()) {
-                            info.endPos = transitionClip->endPos();
-                        } else info.endPos = info.startPos + GenTime(2.5);
-
-                        slotAddTransition((ClipItem *) m_dragItem, info, transitiontrack);
-                    } else if (m_operationMode == TRANSITIONEND) {
-                        ItemInfo info;
-                        info.endPos = m_dragItem->endPos();
-                        info.track = m_dragItem->track();
-                        int transitiontrack = getPreviousVideoTrack(info.track);
-                        ClipItem *transitionClip = NULL;
-                        if (transitiontrack != 0) transitionClip = getClipItemAt((int) info.endPos.frames(m_document->fps()), m_tracksList.count() - transitiontrack);
-                        if (transitionClip && transitionClip->startPos() > m_dragItem->startPos()) {
-                            info.startPos = transitionClip->startPos();
-                        } else info.startPos = info.endPos - GenTime(2.5);
-                        slotAddTransition((ClipItem *) m_dragItem, info, transitiontrack);
-                    }
-                    updateSnapPoints(m_dragItem);
-                    collision = true;
-                    break;
-                }
-            }
-        if (!collision) {
-            kDebug() << "//////// NO ITEM FOUND ON CLICK";
-            m_dragItem = NULL;
-            setCursor(Qt::ArrowCursor);
-            QList<QGraphicsItem *> itemList = items();
-            for (int i = 0; i < itemList.count(); i++)
-                itemList.at(i)->setSelected(false);
-            //emit clipItemSelected(NULL);
-            if (event->button() == Qt::RightButton) {
-                displayContextMenu(event->globalPos());
-                m_menuPosition = event->pos();
-            } else setCursorPos((int)(mapToScene(event->x(), 0).x() / m_scale));
-        } else if (event->button() == Qt::RightButton) {
-            m_operationMode = NONE;
-            displayContextMenu(event->globalPos(), m_dragItem);
-            m_dragItem = NULL;
-        }
-        if (m_dragItem && m_dragItem->type() == AVWIDGET) emit clipItemSelected((ClipItem*) m_dragItem);
-        else emit clipItemSelected(NULL);
+                        m_selectedClipList.clear();
+                        QList<QGraphicsItem *> selected = scene()->selectedItems();
+                        for (int i = 0; i < selected.count(); i++) {
+                            if (selected.at(i)->type() == AVWIDGET || selected.at(i)->type() == TRANSITIONWIDGET)
+                                m_selectedClipList.append(static_cast <AbstractClipItem *>(selected.at(i)));
+                        }
+          */
+    m_operationMode = m_dragItem->operationMode(mapToScene(event->pos()));
+
+    if (m_operationMode == KEYFRAME) {
+        m_dragItem->updateSelectedKeyFrame();
+        m_blockRefresh = false;
+        return;
+    } else if (m_operationMode == MOVE) {
+        setCursor(Qt::ClosedHandCursor);
+    } else if (m_operationMode == TRANSITIONSTART) {
+        ItemInfo info;
+        info.startPos = m_dragItem->startPos();
+        info.track = m_dragItem->track();
+        int transitiontrack = getPreviousVideoTrack(info.track);
+        ClipItem *transitionClip = NULL;
+        if (transitiontrack != 0) transitionClip = getClipItemAt((int) info.startPos.frames(m_document->fps()), m_scene->m_tracksList.count() - transitiontrack);
+        if (transitionClip && transitionClip->endPos() < m_dragItem->endPos()) {
+            info.endPos = transitionClip->endPos();
+        } else info.endPos = info.startPos + GenTime(2.5);
+
+        slotAddTransition((ClipItem *) m_dragItem, info, transitiontrack);
+    } else if (m_operationMode == TRANSITIONEND) {
+        ItemInfo info;
+        info.endPos = m_dragItem->endPos();
+        info.track = m_dragItem->track();
+        int transitiontrack = getPreviousVideoTrack(info.track);
+        ClipItem *transitionClip = NULL;
+        if (transitiontrack != 0) transitionClip = getClipItemAt((int) info.endPos.frames(m_document->fps()), m_scene->m_tracksList.count() - transitiontrack);
+        if (transitionClip && transitionClip->startPos() > m_dragItem->startPos()) {
+            info.startPos = transitionClip->startPos();
+        } else info.startPos = info.endPos - GenTime(2.5);
+        slotAddTransition((ClipItem *) m_dragItem, info, transitiontrack);
     }
+
     m_blockRefresh = false;
     //kDebug()<<pos;
     //QGraphicsView::mousePressEvent(event);
@@ -611,12 +666,12 @@ void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event) {
                 QString next = item->keyframes(item->selectedEffectIndex());
                 EditKeyFrameCommand *command = new EditKeyFrameCommand(this, item->track(), item->startPos(), item->selectedEffectIndex(), previous, next, false);
                 m_commandStack->push(command);
-                updateEffect(m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex());
+                updateEffect(m_scene->m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex());
             }
 
         } else  {
             // add keyframe
-            GenTime keyFramePos = GenTime((int)(mapToScene(event->pos()).x() / m_scale), m_document->fps()) - m_dragItem->startPos() + m_dragItem->cropStart();
+            GenTime keyFramePos = GenTime((int)(mapToScene(event->pos()).x()), m_document->fps()) - m_dragItem->startPos() + m_dragItem->cropStart();
             m_dragItem->addKeyFrame(keyFramePos, mapToScene(event->pos()).toPoint().y());
             ClipItem * item = (ClipItem *) m_dragItem;
             QString previous = item->keyframes(item->selectedEffectIndex());
@@ -624,7 +679,7 @@ void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event) {
             QString next = item->keyframes(item->selectedEffectIndex());
             EditKeyFrameCommand *command = new EditKeyFrameCommand(this, m_dragItem->track(), m_dragItem->startPos(), item->selectedEffectIndex(), previous, next, false);
             m_commandStack->push(command);
-            updateEffect(m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex());
+            updateEffect(m_scene->m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex());
         }
     } else if (m_dragItem) {
         ClipDurationDialog d(m_dragItem, m_document->timecode(), this);
@@ -676,7 +731,7 @@ void CustomTrackView::editKeyFrame(const GenTime pos, const int track, const int
     ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()), track);
     if (clip) {
         clip->setKeyframes(index, keyframes);
-        updateEffect(m_tracksList.count() - clip->track(), clip->startPos(), clip->effectAt(index), index);
+        updateEffect(m_scene->m_tracksList.count() - clip->track(), clip->startPos(), clip->effectAt(index), index);
     } else emit displayMessage(i18n("Cannot find clip with keyframe"), ErrorMessage);
 }
 
@@ -706,7 +761,7 @@ void CustomTrackView::dragEnterEvent(QDragEnterEvent * event) {
 }
 
 void CustomTrackView::slotRefreshEffects(ClipItem *clip) {
-    int track = m_tracksList.count() - clip->track();
+    int track = m_scene->m_tracksList.count() - clip->track();
     GenTime pos = clip->startPos();
     if (!m_document->renderer()->mltRemoveEffect(track, pos, "-1", false)) {
         emit displayMessage(i18n("Problem deleting effect"), ErrorMessage);
@@ -721,9 +776,9 @@ void CustomTrackView::slotRefreshEffects(ClipItem *clip) {
 }
 
 void CustomTrackView::addEffect(int track, GenTime pos, QDomElement effect) {
-    ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_tracksList.count() - track);
+    ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_scene->m_tracksList.count() - track);
     if (clip) {
-        QMap <QString, QString> effectParams = clip->addEffect(effect);
+        QHash <QString, QString> effectParams = clip->addEffect(effect);
         if (!m_document->renderer()->mltAddEffect(track, pos, effectParams))
             emit displayMessage(i18n("Problem adding effect to clip"), ErrorMessage);
         emit clipItemSelected(clip);
@@ -736,7 +791,7 @@ void CustomTrackView::deleteEffect(int track, GenTime pos, QDomElement effect) {
         emit displayMessage(i18n("Problem deleting effect"), ErrorMessage);
         return;
     }
-    ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_tracksList.count() - track);
+    ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_scene->m_tracksList.count() - track);
     if (clip) {
         clip->deleteEffect(index);
         emit clipItemSelected(clip);
@@ -756,7 +811,7 @@ void CustomTrackView::slotAddEffect(QDomElement effect, GenTime pos, int track)
         if (itemList.at(i)->type() == AVWIDGET) {
             ClipItem *item = (ClipItem *)itemList.at(i);
             item->initEffect(effect);
-            AddEffectCommand *command = new AddEffectCommand(this, m_tracksList.count() - item->track(), item->startPos(), effect, true);
+            AddEffectCommand *command = new AddEffectCommand(this, m_scene->m_tracksList.count() - item->track(), item->startPos(), effect, true);
             m_commandStack->push(command);
         }
     }
@@ -764,20 +819,20 @@ void CustomTrackView::slotAddEffect(QDomElement effect, GenTime pos, int track)
 }
 
 void CustomTrackView::slotDeleteEffect(ClipItem *clip, QDomElement effect) {
-    AddEffectCommand *command = new AddEffectCommand(this, m_tracksList.count() - clip->track(), clip->startPos(), effect, false);
+    AddEffectCommand *command = new AddEffectCommand(this, m_scene->m_tracksList.count() - clip->track(), clip->startPos(), effect, false);
     m_commandStack->push(command);
     m_document->setModified(true);
 }
 
 void CustomTrackView::updateEffect(int track, GenTime pos, QDomElement effect, int ix) {
-    ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_tracksList.count() - track);
+    ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_scene->m_tracksList.count() - track);
     if (clip) {
-        QMap <QString, QString> effectParams = clip->getEffectArgs(effect);
+        QHash <QString, QString> effectParams = clip->getEffectArgs(effect);
         if (effectParams.value("disabled") == "1") {
             if (m_document->renderer()->mltRemoveEffect(track, pos, effectParams.value("kdenlive_ix"))) {
                 kDebug() << "//////  DISABLING EFFECT: " << index << ", CURRENTLA: " << clip->selectedEffectIndex();
             } else emit displayMessage(i18n("Problem deleting effect"), ErrorMessage);
-        } else if (!m_document->renderer()->mltEditEffect(m_tracksList.count() - clip->track(), clip->startPos(), effectParams))
+        } else if (!m_document->renderer()->mltEditEffect(m_scene->m_tracksList.count() - clip->track(), clip->startPos(), effectParams))
             emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
         if (ix == clip->selectedEffectIndex()) {
             clip->setSelectedEffect(clip->selectedEffectIndex());
@@ -787,7 +842,7 @@ void CustomTrackView::updateEffect(int track, GenTime pos, QDomElement effect, i
 }
 
 void CustomTrackView::moveEffect(int track, GenTime pos, int oldPos, int newPos) {
-    ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_tracksList.count() - track);
+    ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_scene->m_tracksList.count() - track);
     if (clip) {
         m_document->renderer()->mltMoveEffect(track, pos, oldPos, newPos);
     }
@@ -798,19 +853,19 @@ void CustomTrackView::slotChangeEffectState(ClipItem *clip, int effectPos, bool
     QDomElement effect = clip->effectAt(effectPos);
     QDomElement oldEffect = effect.cloneNode().toElement();
     effect.setAttribute("disabled", disable);
-    EditEffectCommand *command = new EditEffectCommand(this, m_tracksList.count() - clip->track(), clip->startPos(), oldEffect, effect, effectPos, true);
+    EditEffectCommand *command = new EditEffectCommand(this, m_scene->m_tracksList.count() - clip->track(), clip->startPos(), oldEffect, effect, effectPos, true);
     m_commandStack->push(command);
     m_document->setModified(true);
 }
 
 void CustomTrackView::slotChangeEffectPosition(ClipItem *clip, int currentPos, int newPos) {
-    MoveEffectCommand *command = new MoveEffectCommand(this, m_tracksList.count() - clip->track(), clip->startPos(), currentPos, newPos, true);
+    MoveEffectCommand *command = new MoveEffectCommand(this, m_scene->m_tracksList.count() - clip->track(), clip->startPos(), currentPos, newPos, true);
     m_commandStack->push(command);
     m_document->setModified(true);
 }
 
 void CustomTrackView::slotUpdateClipEffect(ClipItem *clip, QDomElement oldeffect, QDomElement effect, int ix) {
-    EditEffectCommand *command = new EditEffectCommand(this, m_tracksList.count() - clip->track(), clip->startPos(), oldeffect, effect, ix, true);
+    EditEffectCommand *command = new EditEffectCommand(this, m_scene->m_tracksList.count() - clip->track(), clip->startPos(), oldeffect, effect, ix, true);
     m_commandStack->push(command);
 }
 
@@ -826,16 +881,16 @@ void CustomTrackView::cutClip(ItemInfo info, GenTime cutTime, bool cut) {
         }
         kDebug() << "/////////  CUTTING CLIP : (" << item->startPos().frames(25) << "-" << item->endPos().frames(25) << "), INFO: (" << info.startPos.frames(25) << "-" << info.endPos.frames(25) << ")" << ", CUT: " << cutTime.frames(25);
 
-        m_document->renderer()->mltCutClip(m_tracksList.count() - info.track, cutTime);
+        m_document->renderer()->mltCutClip(m_scene->m_tracksList.count() - info.track, cutTime);
         int cutPos = (int) cutTime.frames(m_document->fps());
         ItemInfo newPos;
         newPos.startPos = cutTime;
         newPos.endPos = info.endPos;
         newPos.cropStart = item->cropStart() + (cutTime - info.startPos);
         newPos.track = info.track;
-        ClipItem *dup = item->clone(m_scale, newPos);
+        ClipItem *dup = item->clone(newPos);
         kDebug() << "// REsizing item to: " << cutPos;
-        item->resizeEnd(cutPos, m_scale);
+        item->resizeEnd(cutPos);
         scene()->addItem(dup);
         item->baseClip()->addReference();
         m_document->updateClip(item->baseClip()->getId());
@@ -863,13 +918,13 @@ void CustomTrackView::cutClip(ItemInfo info, GenTime cutTime, bool cut) {
         m_document->updateClip(dup->baseClip()->getId());
         scene()->removeItem(dup);
         delete dup;
-        m_document->renderer()->mltRemoveClip(m_tracksList.count() - info.track, cutTime);
+        m_document->renderer()->mltRemoveClip(m_scene->m_tracksList.count() - info.track, cutTime);
 
         ItemInfo clipinfo = item->info();
-        clipinfo.track = m_tracksList.count() - clipinfo.track;
+        clipinfo.track = m_scene->m_tracksList.count() - clipinfo.track;
         bool success = m_document->renderer()->mltResizeClipEnd(clipinfo, info.endPos - info.startPos);
         if (success) {
-            item->resizeEnd((int) info.endPos.frames(m_document->fps()), m_scale);
+            item->resizeEnd((int) info.endPos.frames(m_document->fps()));
         } else
             emit displayMessage(i18n("Error when resizing clip"), ErrorMessage);
 
@@ -903,17 +958,17 @@ void CustomTrackView::slotAddTransition(ClipItem* clip, ItemInfo transitionInfo,
 }
 
 void CustomTrackView::addTransition(ItemInfo transitionInfo, int endTrack, QDomElement params) {
-    Transition *tr = new Transition(transitionInfo, endTrack, m_scale, m_document->fps(), params);
+    Transition *tr = new Transition(transitionInfo, endTrack, m_document->fps(), params);
     scene()->addItem(tr);
 
-    //kDebug() << "---- ADDING transition " << e.attribute("tag") << ", on tracks " << m_tracksList.count() - e.attribute("transition_track").toInt() << " / " << getPreviousVideoTrack(e.attribute("transition_track").toInt());
-    m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_tracksList.count() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, tr->toXML());
+    //kDebug() << "---- ADDING transition " << e.attribute("tag") << ", on tracks " << m_scene->m_tracksList.count() - e.attribute("transition_track").toInt() << " / " << getPreviousVideoTrack(e.attribute("transition_track").toInt());
+    m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_scene->m_tracksList.count() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, tr->toXML());
     m_document->setModified(true);
 }
 
 void CustomTrackView::deleteTransition(ItemInfo transitionInfo, int endTrack, QDomElement params) {
     Transition *item = getTransitionItemAt((int)transitionInfo.startPos.frames(m_document->fps()) + 1, transitionInfo.track);
-    m_document->renderer()->mltDeleteTransition(item->transitionTag(), endTrack, m_tracksList.count() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, item->toXML());
+    m_document->renderer()->mltDeleteTransition(item->transitionTag(), endTrack, m_scene->m_tracksList.count() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, item->toXML());
     delete item;
     emit transitionItemSelected(NULL);
     m_document->setModified(true);
@@ -931,18 +986,18 @@ void CustomTrackView::updateTransition(int track, GenTime pos, QDomElement oldTr
         kWarning() << "Unable to find transition at pos :" << pos.frames(m_document->fps()) << ", ON track: " << track;
         return;
     }
-    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);
+    m_document->renderer()->mltUpdateTransition(oldTransition.attribute("tag"), transition.attribute("tag"), transition.attribute("transition_btrack").toInt(), m_scene->m_tracksList.count() - transition.attribute("transition_atrack").toInt(), item->startPos(), item->endPos(), transition);
     item->setTransitionParameters(transition);
     m_document->setModified(true);
 }
 
 void CustomTrackView::addItem(DocClipBase *clip, QPoint pos) {
     ItemInfo info;
-    info.startPos = GenTime((int)(mapToScene(pos).x() / m_scale), m_document->fps());
+    info.startPos = GenTime((int)(mapToScene(pos).x()), m_document->fps());
     info.endPos = info.startPos + clip->duration();
     info.track = (int)(pos.y() / m_tracksHeight);
     kDebug() << "------------  ADDING CLIP ITEM----: " << info.startPos.frames(25) << ", " << info.endPos.frames(25) << ", " << info.track;
-    m_dropItem = new ClipItem(clip, info, m_scale, m_document->fps());
+    m_dropItem = new ClipItem(clip, info, m_document->fps());
     scene()->addItem(m_dropItem);
 }
 
@@ -950,8 +1005,9 @@ void CustomTrackView::addItem(DocClipBase *clip, QPoint pos) {
 void CustomTrackView::dragMoveEvent(QDragMoveEvent * event) {
     event->setDropAction(Qt::IgnoreAction);
     if (m_dropItem) {
-        int track = (int)(mapToScene(event->pos()).y() / m_tracksHeight);  //) * (m_scale * 50) + m_scale;
-        m_dropItem->moveTo((int)(mapToScene(event->pos()).x() / m_scale), m_scale, (int)((track - m_dropItem->track()) * m_tracksHeight), track);
+        int track = (int)(mapToScene(event->pos()).y() / m_tracksHeight);
+        int pos = mapToScene(event->pos()).x();
+        m_dropItem->setPos(pos, track * m_tracksHeight + 1);
         event->setDropAction(Qt::MoveAction);
         if (event->mimeData()->hasFormat("kdenlive/producerslist")) {
             event->acceptProposedAction();
@@ -972,12 +1028,13 @@ void CustomTrackView::dropEvent(QDropEvent * event) {
     if (m_dropItem) {
         AddTimelineClipCommand *command = new AddTimelineClipCommand(this, m_dropItem->xml(), m_dropItem->clipProducer(), m_dropItem->info(), m_dropItem->effectList(), false, false);
         m_commandStack->push(command);
+        //((ClipItem *) m_dropItem)->refreshClip();
         m_dropItem->baseClip()->addReference();
         m_document->updateClip(m_dropItem->baseClip()->getId());
         ItemInfo info;
         info = m_dropItem->info();
-        info.track = m_tracksList.count() - m_dropItem->track();
-        //kDebug()<<"IIIIIIIIIIIIIIIIIIIIIIII TRAX CNT: "<<m_tracksList.count()<<", DROP: "<<m_dropItem->track();
+        info.track = m_scene->m_tracksList.count() - m_dropItem->track();
+        //kDebug()<<"IIIIIIIIIIIIIIIIIIIIIIII TRAX CNT: "<<m_scene->m_tracksList.count()<<", DROP: "<<m_dropItem->track();
         m_document->renderer()->mltInsertClip(info, m_dropItem->xml(), m_dropItem->baseClip()->producer());
         //if (m_dropItem->baseClip()->isTransparent()) m_document->renderer()->mltAddClipTransparency(info, getPreviousVideoTrack(m_dropItem->track()), m_dropItem->baseClip()->getId());
         m_dropItem = NULL;
@@ -1001,9 +1058,9 @@ Qt::DropActions CustomTrackView::supportedDropActions() const {
 }
 
 void CustomTrackView::setDuration(int duration) {
-    kDebug() << "/////////////  PRO DUR: " << duration << ", SCALE. " << (m_projectDuration + 500) * m_scale << ", height: " << 50 * m_tracksList.count();
+    kDebug() << "/////////////  PRO DUR: " << duration << ", SCALE. " << (m_projectDuration + 500) << ", height: " << 50 * m_scene->m_tracksList.count();
     m_projectDuration = duration;
-    setSceneRect(0, 0, (m_projectDuration + 100) * m_scale, sceneRect().height());
+    setSceneRect(0, 0, (m_projectDuration + 100), sceneRect().height());
 }
 
 int CustomTrackView::duration() const {
@@ -1011,31 +1068,31 @@ int CustomTrackView::duration() const {
 }
 
 void CustomTrackView::addTrack(TrackInfo type) {
-    m_tracksList << type;
-    m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_tracksList.count());
-    setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_tracksList.count());
-    verticalScrollBar()->setMaximum(m_tracksHeight * m_tracksList.count());
+    m_scene->m_tracksList << type;
+    m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_scene->m_tracksList.count());
+    setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_scene->m_tracksList.count());
+    verticalScrollBar()->setMaximum(m_tracksHeight * m_scene->m_tracksList.count());
     //setFixedHeight(50 * m_tracksCount);
 }
 
 void CustomTrackView::removeTrack() {
     // TODO: implement track deletion
     //m_tracksCount--;
-    m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_tracksList.count());
+    m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_scene->m_tracksList.count());
 }
 
 
 void CustomTrackView::slotSwitchTrackAudio(int ix) {
-    int tracknumber = m_tracksList.count() - ix;
+    int tracknumber = m_scene->m_tracksList.count() - ix;
     kDebug() << "/////  MUTING TRK: " << ix << "; PL NUM: " << tracknumber;
-    m_tracksList[tracknumber - 1].isMute = !m_tracksList.at(tracknumber - 1).isMute;
-    m_document->renderer()->mltChangeTrackState(tracknumber, m_tracksList.at(tracknumber - 1).isMute, m_tracksList.at(tracknumber - 1).isBlind);
+    m_scene->m_tracksList[tracknumber - 1].isMute = !m_scene->m_tracksList.at(tracknumber - 1).isMute;
+    m_document->renderer()->mltChangeTrackState(tracknumber, m_scene->m_tracksList.at(tracknumber - 1).isMute, m_scene->m_tracksList.at(tracknumber - 1).isBlind);
 }
 
 void CustomTrackView::slotSwitchTrackVideo(int ix) {
-    int tracknumber = m_tracksList.count() - ix;
-    m_tracksList[tracknumber - 1].isBlind = !m_tracksList.at(tracknumber - 1).isBlind;
-    m_document->renderer()->mltChangeTrackState(tracknumber, m_tracksList.at(tracknumber - 1).isMute, m_tracksList.at(tracknumber - 1).isBlind);
+    int tracknumber = m_scene->m_tracksList.count() - ix;
+    m_scene->m_tracksList[tracknumber - 1].isBlind = !m_scene->m_tracksList.at(tracknumber - 1).isBlind;
+    m_document->renderer()->mltChangeTrackState(tracknumber, m_scene->m_tracksList.at(tracknumber - 1).isMute, m_scene->m_tracksList.at(tracknumber - 1).isBlind);
 }
 
 void CustomTrackView::deleteClip(int clipId) {
@@ -1053,26 +1110,26 @@ void CustomTrackView::deleteClip(int clipId) {
 }
 
 void CustomTrackView::setCursorPos(int pos, bool seek) {
-    emit cursorMoved((int)(m_cursorPos * m_scale), (int)(pos * m_scale));
+    emit cursorMoved((int)(m_cursorPos), (int)(pos));
     m_cursorPos = pos;
-    m_cursorLine->setPos(pos * m_scale, 0);
+    m_cursorLine->setPos(pos, 0);
     if (seek) m_document->renderer()->seek(GenTime(pos, m_document->fps()));
-    else if (m_autoScroll && m_scale < 50) checkScrolling();
+    else if (m_autoScroll) checkScrolling();
 }
 
 void CustomTrackView::updateCursorPos() {
-    m_cursorLine->setPos(m_cursorPos * m_scale, 0);
+    m_cursorLine->setPos(m_cursorPos, 0);
 }
 
 int CustomTrackView::cursorPos() {
-    return (int)(m_cursorPos * m_scale);
+    return (int)(m_cursorPos);
 }
 
 void CustomTrackView::moveCursorPos(int delta) {
     if (m_cursorPos + delta < 0) delta = 0 - m_cursorPos;
-    emit cursorMoved((int)(m_cursorPos * m_scale), (int)((m_cursorPos + delta) * m_scale));
+    emit cursorMoved((int)(m_cursorPos), (int)((m_cursorPos + delta)));
     m_cursorPos += delta;
-    m_cursorLine->setPos(m_cursorPos * m_scale, 0);
+    m_cursorLine->setPos(m_cursorPos, 0);
     m_document->renderer()->seek(GenTime(m_cursorPos, m_document->fps()));
     //if (m_autoScroll && m_scale < 50) checkScrolling();
 }
@@ -1099,9 +1156,9 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
         setCursor(Qt::ArrowCursor);
         m_operationMode = NONE;
         m_dragGuide->setFlag(QGraphicsItem::ItemIsMovable, false);
-        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);
+        EditGuideCommand *command = new EditGuideCommand(this, m_dragGuide->position(), m_dragGuide->label(), GenTime(m_dragGuide->pos().x(), m_document->fps()), m_dragGuide->label(), false);
         m_commandStack->push(command);
-        m_dragGuide->updateGuide(GenTime(m_dragGuide->pos().x() / m_scale, m_document->fps()));
+        m_dragGuide->updateGuide(GenTime(m_dragGuide->pos().x(), m_document->fps()));
         m_dragGuide = NULL;
         m_dragItem = NULL;
         return;
@@ -1115,10 +1172,10 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
     if (m_operationMode == MOVE) {
         setCursor(Qt::OpenHandCursor);
 
-        if (m_selectedClipList.count() == 1) {
+        if (m_selectionGroup == NULL) {
             // we are moving one clip, easy
             if (m_dragItem->type() == AVWIDGET && (m_dragItemInfo.startPos != info.startPos || m_dragItemInfo.track != info.track)) {
-                bool success = 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())));
+                bool success = m_document->renderer()->mltMoveClip((int)(m_scene->m_tracksList.count() - m_dragItemInfo.track), (int)(m_scene->m_tracksList.count() - m_dragItem->track()), (int) m_dragItemInfo.startPos.frames(m_document->fps()), (int)(m_dragItem->startPos().frames(m_document->fps())));
                 if (success) {
                     MoveClipCommand *command = new MoveClipCommand(this, m_dragItemInfo, info, false);
                     m_commandStack->push(command);
@@ -1134,7 +1191,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                 m_commandStack->push(command);
                 Transition *transition = (Transition *) m_dragItem;
                 transition->updateTransitionEndTrack(getPreviousVideoTrack(m_dragItem->track()));
-                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);
+                m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_scene->m_tracksList.count() - m_dragItemInfo.track), (int)(m_scene->m_tracksList.count() - m_dragItem->track()), transition->transitionEndTrack(), m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos);
             }
         } else {
             // Moving several clips. We need to delete them and readd them to new position,
@@ -1155,11 +1212,11 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                     if (item->type() == AVWIDGET) {
                         ClipItem *clip = static_cast <ClipItem*>(item);
                         new AddTimelineClipCommand(this, clip->xml(), clip->clipProducer(), info, clip->effectList(), false, true, moveClips);
-                        m_document->renderer()->mltRemoveClip(m_tracksList.count() - info.track, info.startPos);
+                        m_document->renderer()->mltRemoveClip(m_scene->m_tracksList.count() - info.track, info.startPos);
                     } else {
                         Transition *tr = static_cast <Transition*>(item);
                         new AddTransitionCommand(this, info, tr->transitionEndTrack(), tr->toXML(), false, true, moveClips);
-                        m_document->renderer()->mltDeleteTransition(tr->transitionTag(), tr->transitionEndTrack(), m_tracksList.count() - info.track, info.startPos, info.endPos, tr->toXML());
+                        m_document->renderer()->mltDeleteTransition(tr->transitionTag(), tr->transitionEndTrack(), m_scene->m_tracksList.count() - info.track, info.startPos, info.endPos, tr->toXML());
                     }
                 }
 
@@ -1170,13 +1227,13 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                         ClipItem *clip = static_cast <ClipItem*>(item);
                         new AddTimelineClipCommand(this, clip->xml(), clip->clipProducer(), item->info(), clip->effectList(), false, false, moveClips);
                         ItemInfo info = item->info();
-                        info.track = m_tracksList.count() - item->track();
+                        info.track = m_scene->m_tracksList.count() - item->track();
                         m_document->renderer()->mltInsertClip(info, clip->xml(), clip->baseClip()->producer());
                     } else {
                         Transition *tr = static_cast <Transition*>(item);
                         ItemInfo transitionInfo = tr->info();
                         new AddTransitionCommand(this, info, tr->transitionEndTrack(), tr->toXML(), false, false, moveClips);
-                        m_document->renderer()->mltAddTransition(tr->transitionTag(), tr->transitionEndTrack() + trackOffset, m_tracksList.count() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, tr->toXML());
+                        m_document->renderer()->mltAddTransition(tr->transitionTag(), tr->transitionEndTrack() + trackOffset, m_scene->m_tracksList.count() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, tr->toXML());
                     }
                 }
                 m_commandStack->push(moveClips);
@@ -1187,21 +1244,21 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
         // resize start
         if (m_dragItem->type() == AVWIDGET) {
             ItemInfo resizeinfo = m_dragItemInfo;
-            resizeinfo.track = m_tracksList.count() - resizeinfo.track;
+            resizeinfo.track = m_scene->m_tracksList.count() - resizeinfo.track;
             bool success = m_document->renderer()->mltResizeClipStart(resizeinfo, m_dragItem->startPos() - m_dragItemInfo.startPos);
             if (success) {
                 updateClipFade((ClipItem *) m_dragItem);
                 ResizeClipCommand *command = new ResizeClipCommand(this, m_dragItemInfo, info, false);
                 m_commandStack->push(command);
             } else {
-                m_dragItem->resizeStart((int) m_dragItemInfo.startPos.frames(m_document->fps()), m_scale);
+                m_dragItem->resizeStart((int) m_dragItemInfo.startPos.frames(m_document->fps()));
                 emit displayMessage(i18n("Error when resizing clip"), ErrorMessage);
             }
         } else if (m_dragItem->type() == TRANSITIONWIDGET) {
             MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false);
             m_commandStack->push(command);
             Transition *transition = (Transition *) m_dragItem;
-            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);
+            m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_scene->m_tracksList.count() - m_dragItemInfo.track), (int)(m_scene->m_tracksList.count() - m_dragItemInfo.track), 0, m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos);
         }
 
         //m_document->renderer()->doRefresh();
@@ -1209,20 +1266,20 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
         // resize end
         if (m_dragItem->type() == AVWIDGET) {
             ItemInfo resizeinfo = info;
-            resizeinfo.track = m_tracksList.count() - resizeinfo.track;
+            resizeinfo.track = m_scene->m_tracksList.count() - resizeinfo.track;
             bool success = m_document->renderer()->mltResizeClipEnd(resizeinfo, resizeinfo.endPos - resizeinfo.startPos);
             if (success) {
                 ResizeClipCommand *command = new ResizeClipCommand(this, m_dragItemInfo, info, false);
                 m_commandStack->push(command);
             } else {
-                m_dragItem->resizeEnd((int) m_dragItemInfo.endPos.frames(m_document->fps()), m_scale);
+                m_dragItem->resizeEnd((int) m_dragItemInfo.endPos.frames(m_document->fps()));
                 emit displayMessage(i18n("Error when resizing clip"), ErrorMessage);
             }
         } else if (m_dragItem->type() == TRANSITIONWIDGET) {
             MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false);
             m_commandStack->push(command);
             Transition *transition = (Transition *) m_dragItem;
-//             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);
+//             m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_scene->m_tracksList.count() - m_dragItemInfo.track), (int)(m_scene->m_tracksList.count() - m_dragItemInfo.track), 0, m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos);
         }
         //m_document->renderer()->doRefresh();
     } else if (m_operationMode == FADEIN) {
@@ -1285,7 +1342,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
         QString next = item->keyframes(item->selectedEffectIndex());
         EditKeyFrameCommand *command = new EditKeyFrameCommand(this, item->track(), item->startPos(), item->selectedEffectIndex(), previous, next, false);
         m_commandStack->push(command);
-        updateEffect(m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex());
+        updateEffect(m_scene->m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex());
     }
 
     emit transitionItemSelected((m_dragItem && m_dragItem->type() == TRANSITIONWIDGET) ? (Transition*) m_dragItem : NULL);
@@ -1304,7 +1361,7 @@ void CustomTrackView::deleteClip(ItemInfo info) {
     m_document->updateClip(item->baseClip()->getId());
     scene()->removeItem(item);
     delete item;
-    m_document->renderer()->mltRemoveClip(m_tracksList.count() - info.track, info.startPos);
+    m_document->renderer()->mltRemoveClip(m_scene->m_tracksList.count() - info.track, info.startPos);
     m_document->renderer()->doRefresh();
 }
 
@@ -1356,7 +1413,7 @@ void CustomTrackView::changeClipSpeed() {
 void CustomTrackView::doChangeClipSpeed(ItemInfo info, double speed, int id) {
     DocClipBase *baseclip = m_document->clipManager()->getClipById(id);
     ClipItem *item = getClipItemAt((int) info.startPos.frames(m_document->fps()) + 1, info.track);
-    info.track = m_tracksList.count() - item->track();
+    info.track = m_scene->m_tracksList.count() - item->track();
     m_document->renderer()->mltChangeClipSpeed(info, speed, baseclip->producer());
     item->setSpeed(speed);
     GenTime maxDuration = item->maxDuration();
@@ -1385,12 +1442,12 @@ void CustomTrackView::cutSelectedClips() {
 
 void CustomTrackView::addClip(QDomElement xml, int clipId, ItemInfo info, EffectsList effects) {
     DocClipBase *baseclip = m_document->clipManager()->getClipById(clipId);
-    ClipItem *item = new ClipItem(baseclip, info, m_scale, m_document->fps());
+    ClipItem *item = new ClipItem(baseclip, info, m_document->fps());
     item->setEffectList(effects);
     scene()->addItem(item);
     baseclip->addReference();
     m_document->updateClip(baseclip->getId());
-    info.track = m_tracksList.count() - info.track;
+    info.track = m_scene->m_tracksList.count() - info.track;
     m_document->renderer()->mltInsertClip(info, xml, baseclip->producer());
     for (int i = 0; i < item->effectsCount(); i++) {
         m_document->renderer()->mltAddEffect(info.track, info.startPos, item->getEffectArgs(item->effectAt(i)), false);
@@ -1407,7 +1464,7 @@ void CustomTrackView::slotUpdateClip(int clipId) {
             if (clip->clipProducer() == clipId) {
                 clip->refreshClip();
                 ItemInfo info = clip->info();
-                info.track = m_tracksList.count() - clip->track();
+                info.track = m_scene->m_tracksList.count() - clip->track();
                 m_document->renderer()->mltUpdateClip(info, clip->xml(), clip->baseClip()->producer());
             }
         }
@@ -1415,7 +1472,7 @@ void CustomTrackView::slotUpdateClip(int clipId) {
 }
 
 ClipItem *CustomTrackView::getClipItemAt(int pos, int track) {
-    QList<QGraphicsItem *> list = scene()->items(QPointF(pos * m_scale, track * m_tracksHeight + m_tracksHeight / 2));
+    QList<QGraphicsItem *> list = scene()->items(QPointF(pos , track * m_tracksHeight + m_tracksHeight / 2));
     ClipItem *clip = NULL;
     for (int i = 0; i < list.size(); ++i) {
         if (list.at(i)->type() == AVWIDGET) {
@@ -1427,12 +1484,12 @@ ClipItem *CustomTrackView::getClipItemAt(int pos, int track) {
 }
 
 ClipItem *CustomTrackView::getClipItemAt(GenTime pos, int track) {
-    int framepos = (int)(pos.frames(m_document->fps()) * m_scale);
+    int framepos = (int)(pos.frames(m_document->fps()));
     return getClipItemAt(framepos, track);
 }
 
 Transition *CustomTrackView::getTransitionItemAt(int pos, int track) {
-    QList<QGraphicsItem *> list = scene()->items(QPointF(pos * m_scale, (track + 1) * m_tracksHeight));
+    QList<QGraphicsItem *> list = scene()->items(QPointF(pos, (track + 1) * m_tracksHeight));
     Transition *clip = NULL;
     for (int i = 0; i < list.size(); ++i) {
         if (list.at(i)->type() == TRANSITIONWIDGET) {
@@ -1444,7 +1501,7 @@ Transition *CustomTrackView::getTransitionItemAt(int pos, int track) {
 }
 
 Transition *CustomTrackView::getTransitionItemAt(GenTime pos, int track) {
-    int framepos = (int)(pos.frames(m_document->fps()) * m_scale);
+    int framepos = (int)(pos.frames(m_document->fps()));
     return getTransitionItemAt(framepos, track);
 }
 
@@ -1457,9 +1514,9 @@ void CustomTrackView::moveClip(const ItemInfo start, const ItemInfo end) {
     }
     //kDebug() << "----------------  Move CLIP FROM: " << startPos.x() << ", END:" << endPos.x() << ",TRACKS: " << startPos.y() << " TO " << endPos.y();
 
-    bool success = 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()));
+    bool success = m_document->renderer()->mltMoveClip((int)(m_scene->m_tracksList.count() - start.track), (int)(m_scene->m_tracksList.count() - end.track), (int) start.startPos.frames(m_document->fps()), (int)end.startPos.frames(m_document->fps()));
     if (success) {
-        item->moveTo((int) end.startPos.frames(m_document->fps()), m_scale, (int)((end.track - start.track) * m_tracksHeight), end.track);
+        item->setPos((int) end.startPos.frames(m_document->fps()), (int)(end.track * m_tracksHeight + 1));
     } else {
         // undo last move and emit error message
         emit displayMessage(i18n("Cannot move clip to position %1seconds", QString::number(end.startPos.seconds(), 'g', 2)), ErrorMessage);
@@ -1478,17 +1535,17 @@ void CustomTrackView::moveTransition(const ItemInfo start, const ItemInfo end) {
     //kDebug()<<"///  RESIZE TRANS START: ("<< startPos.x()<<"x"<< startPos.y()<<") / ("<<endPos.x()<<"x"<< endPos.y()<<")";
     if (end.endPos - end.startPos == start.endPos - start.startPos) {
         // Transition was moved
-        item->moveTo((int) end.startPos.frames(m_document->fps()), m_scale, (end.track - start.track) * m_tracksHeight, end.track);
+        item->setPos((int) end.startPos.frames(m_document->fps()), (end.track) * m_tracksHeight + 1);
     } else if (end.endPos == start.endPos) {
         // Transition start resize
-        item->resizeStart((int) end.startPos.frames(m_document->fps()), m_scale);
+        item->resizeStart((int) end.startPos.frames(m_document->fps()));
     } else {
         // Transition end resize;
-        item->resizeEnd((int) end.endPos.frames(m_document->fps()), m_scale);
+        item->resizeEnd((int) end.endPos.frames(m_document->fps()));
     }
     //item->moveTransition(GenTime((int) (endPos.x() - startPos.x()), m_document->fps()));
     item->updateTransitionEndTrack(getPreviousVideoTrack(end.track));
-    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);
+    m_document->renderer()->mltMoveTransition(item->transitionTag(), m_scene->m_tracksList.count() - start.track, m_scene->m_tracksList.count() - end.track, item->transitionEndTrack(), start.startPos, start.endPos, end.startPos, end.endPos);
 }
 
 void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end) {
@@ -1505,18 +1562,18 @@ void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end) {
     }
     if (resizeClipStart) {
         ItemInfo clipinfo = item->info();
-        clipinfo.track = m_tracksList.count() - clipinfo.track;
-        bool success = m_document->renderer()->mltResizeClipStart(clipinfo, item->startPos() - end.startPos);
+        clipinfo.track = m_scene->m_tracksList.count() - clipinfo.track;
+        bool success = m_document->renderer()->mltResizeClipStart(clipinfo, end.startPos - item->startPos());
         if (success) {
-            item->resizeStart((int) end.startPos.frames(m_document->fps()), m_scale);
+            item->resizeStart((int) end.startPos.frames(m_document->fps()));
             updateClipFade(item);
         } else emit displayMessage(i18n("Error when resizing clip"), ErrorMessage);
     } else {
         ItemInfo clipinfo = item->info();
-        clipinfo.track = m_tracksList.count() - clipinfo.track;
+        clipinfo.track = m_scene->m_tracksList.count() - clipinfo.track;
         bool success = m_document->renderer()->mltResizeClipEnd(clipinfo, end.endPos - clipinfo.startPos);
         if (success) {
-            item->resizeEnd((int) end.endPos.frames(m_document->fps()), m_scale);
+            item->resizeEnd((int) end.endPos.frames(m_document->fps()));
             updateClipFade(item, true);
         } else emit displayMessage(i18n("Error when resizing clip"), ErrorMessage);
     }
@@ -1534,8 +1591,8 @@ void CustomTrackView::updateClipFade(ClipItem * item, bool updateFadeOut) {
             end += start;
             EffectsList::setParameter(oldeffect, "in", QString::number(start));
             EffectsList::setParameter(oldeffect, "out", QString::number(end));
-            QMap <QString, QString> effectParams = item->getEffectArgs(oldeffect);
-            if (!m_document->renderer()->mltEditEffect(m_tracksList.count() - item->track(), item->startPos(), effectParams))
+            QHash <QString, QString> effectParams = item->getEffectArgs(oldeffect);
+            if (!m_document->renderer()->mltEditEffect(m_scene->m_tracksList.count() - item->track(), item->startPos(), effectParams))
                 emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
         }
     } else {
@@ -1548,27 +1605,19 @@ void CustomTrackView::updateClipFade(ClipItem * item, bool updateFadeOut) {
             start = end - start;
             EffectsList::setParameter(oldeffect, "in", QString::number(start));
             EffectsList::setParameter(oldeffect, "out", QString::number(end));
-            QMap <QString, QString> effectParams = item->getEffectArgs(oldeffect);
-            if (m_document->renderer()->mltEditEffect(m_tracksList.count() - item->track(), item->startPos(), effectParams))
+            QHash <QString, QString> effectParams = item->getEffectArgs(oldeffect);
+            if (m_document->renderer()->mltEditEffect(m_scene->m_tracksList.count() - item->track(), item->startPos(), effectParams))
                 emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
         }
     }
 }
 
 double CustomTrackView::getSnapPointForPos(double pos) {
-    for (int i = 0; i < m_snapPoints.size(); ++i) {
-        if (abs((int)(pos - m_snapPoints.at(i).frames(m_document->fps()) * m_scale)) < 10) {
-            //kDebug()<<" FOUND SNAP POINT AT: "<<m_snapPoints.at(i)<<", current pos: "<<pos / m_scale;
-            return m_snapPoints.at(i).frames(m_document->fps()) * m_scale + 0.5;
-        }
-        if (m_snapPoints.at(i).frames(m_document->fps() * m_scale) > pos) break;
-    }
-    return pos;
+    return m_scene->getSnapPointForPos(pos);
 }
 
 void CustomTrackView::updateSnapPoints(AbstractClipItem *selected) {
-    m_snapPoints.clear();
-    if (!KdenliveSettings::snaptopoints()) return;
+    QList <GenTime> snaps;
     GenTime offset;
     if (selected) offset = selected->duration();
     QList<QGraphicsItem *> itemList = items();
@@ -1577,72 +1626,58 @@ void CustomTrackView::updateSnapPoints(AbstractClipItem *selected) {
             ClipItem *item = static_cast <ClipItem *>(itemList.at(i));
             GenTime start = item->startPos();
             GenTime end = item->endPos();
-            m_snapPoints.append(start);
-            m_snapPoints.append(end);
+            snaps.append(start);
+            snaps.append(end);
             QList < GenTime > markers = item->snapMarkers();
             for (int i = 0; i < markers.size(); ++i) {
                 GenTime t = markers.at(i);
-                m_snapPoints.append(t);
-                if (t > offset) m_snapPoints.append(t - offset);
+                snaps.append(t);
+                if (t > offset) snaps.append(t - offset);
             }
             if (offset != GenTime()) {
-                if (start > offset) m_snapPoints.append(start - offset);
-                if (end > offset) m_snapPoints.append(end - offset);
+                if (start > offset) snaps.append(start - offset);
+                if (end > offset) snaps.append(end - offset);
             }
         } else if (itemList.at(i)->type() == TRANSITIONWIDGET) {
             Transition *transition = static_cast <Transition*>(itemList.at(i));
             GenTime start = transition->startPos();
             GenTime end = transition->endPos();
-            m_snapPoints.append(start);
-            m_snapPoints.append(end);
+            snaps.append(start);
+            snaps.append(end);
             if (offset != GenTime()) {
-                if (start > offset) m_snapPoints.append(start - offset);
-                if (end > offset) m_snapPoints.append(end - offset);
+                if (start > offset) snaps.append(start - offset);
+                if (end > offset) snaps.append(end - offset);
             }
         }
     }
 
     // add cursor position
     GenTime pos = GenTime(m_cursorPos, m_document->fps());
-    m_snapPoints.append(pos);
-    if (offset != GenTime()) m_snapPoints.append(pos - offset);
+    snaps.append(pos);
+    if (offset != GenTime()) snaps.append(pos - offset);
 
     // add guides
     for (int i = 0; i < m_guides.count(); i++) {
-        m_snapPoints.append(m_guides.at(i)->position());
-        if (offset != GenTime()) m_snapPoints.append(m_guides.at(i)->position() - offset);
+        snaps.append(m_guides.at(i)->position());
+        if (offset != GenTime()) snaps.append(m_guides.at(i)->position() - offset);
     }
 
-    qSort(m_snapPoints);
+    qSort(snaps);
+    m_scene->setSnapList(snaps);
     //for (int i = 0; i < m_snapPoints.size(); ++i)
     //    kDebug() << "SNAP POINT: " << m_snapPoints.at(i).frames(25);
 }
 
 void CustomTrackView::slotSeekToPreviousSnap() {
     updateSnapPoints(NULL);
-    GenTime pos = GenTime(m_cursorPos, m_document->fps());
-    GenTime res = GenTime();
-    for (int i = 0; i < m_snapPoints.size(); ++i) {
-        if (m_snapPoints.at(i) >= pos) {
-            if (i == 0) i = 1;
-            res = m_snapPoints.at(i - 1);
-            break;
-        }
-    }
+    GenTime res = m_scene->previousSnapPoint(GenTime(m_cursorPos, m_document->fps()));
     setCursorPos((int) res.frames(m_document->fps()));
     checkScrolling();
 }
 
 void CustomTrackView::slotSeekToNextSnap() {
     updateSnapPoints(NULL);
-    GenTime pos = GenTime(m_cursorPos, m_document->fps());
-    GenTime res = GenTime(m_projectDuration, m_document->fps());
-    for (int i = 0; i < m_snapPoints.size(); ++i) {
-        if (m_snapPoints.at(i) > pos) {
-            res = m_snapPoints.at(i);
-            break;
-        }
-    }
+    GenTime res = m_scene->nextSnapPoint(GenTime(m_cursorPos, m_document->fps()));
     setCursorPos((int) res.frames(m_document->fps()));
     checkScrolling();
 }
@@ -1844,7 +1879,7 @@ bool CustomTrackView::addGuide(const GenTime pos, const QString &comment) {
             return false;
         }
     }
-    Guide *g = new Guide(this, pos, comment, m_scale, m_document->fps(), m_tracksHeight * m_tracksList.count());
+    Guide *g = new Guide(this, pos, comment, m_document->fps(), m_tracksHeight * m_scene->m_tracksList.count());
     scene()->addItem(g);
     m_guides.append(g);
     m_document->syncGuides(m_guides);
@@ -1911,7 +1946,10 @@ void CustomTrackView::setTool(PROJECTTOOL tool) {
 }
 
 void CustomTrackView::setScale(double scaleFactor) {
-    //scale(scaleFactor, scaleFactor);
+    QMatrix matrix;
+    matrix = matrix.scale(scaleFactor, 1);
+    m_scene->setScale(scaleFactor);
+    //scale(scaleFactor, 1);
     m_animationTimer->stop();
     if (m_visualTip) {
         delete m_visualTip;
@@ -1921,8 +1959,9 @@ void CustomTrackView::setScale(double scaleFactor) {
         delete m_animation;
         m_animation = NULL;
     }
-    double pos = cursorPos() / m_scale;
+    /*double pos = cursorPos() / m_scale;
     m_scale = scaleFactor;
+    m_scene->setScale(m_scale);
     int vert = verticalScrollBar()->value();
     kDebug() << " HHHHHHHH  SCALING: " << m_scale;
     QList<QGraphicsItem *> itemList = items();
@@ -1939,9 +1978,10 @@ void CustomTrackView::setScale(double scaleFactor) {
     }
 
     setSceneRect(0, 0, (m_projectDuration + 100) * m_scale, sceneRect().height());
-    updateCursorPos();
+    updateCursorPos();*/
+    setMatrix(matrix);
     centerOn(QPointF(cursorPos(), m_tracksHeight));
-    verticalScrollBar()->setValue(vert);
+    //verticalScrollBar()->setValue(vert);*/
 }
 
 void CustomTrackView::slotRefreshGuides() {
@@ -1954,21 +1994,21 @@ void CustomTrackView::slotRefreshGuides() {
 }
 
 void CustomTrackView::drawBackground(QPainter * painter, const QRectF & rect) {
-    QRect rectInView = viewport()->rect();
-    rectInView.moveTo(horizontalScrollBar()->value(), verticalScrollBar()->value());
-
     QColor base = palette().button().color();
-    painter->setClipRect(rect);
-    painter->drawLine(rectInView.left(), 0, rectInView.right(), 0);
-    uint max = m_tracksList.count();
+    QRectF r = rect;
+    //r.moveTo(horizontalScrollBar()->value(), verticalScrollBar()->value());
+    r.setWidth(r.width() + 1);
+    painter->setClipRect(r);
+    painter->drawLine(r.left(), 0, r.right(), 0);
+    uint max = m_scene->m_tracksList.count();
     for (uint i = 0; i < max;i++) {
-        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)));
-        painter->drawLine(rectInView.left(), m_tracksHeight * (i + 1), rectInView.right(), m_tracksHeight * (i + 1));
+        if (m_scene->m_tracksList.at(max - i - 1).type == AUDIOTRACK) painter->fillRect(r.left(), m_tracksHeight * i + 1, r.right() - r.left() + 1, m_tracksHeight - 1, QBrush(QColor(240, 240, 255)));
+        painter->drawLine(r.left(), m_tracksHeight * (i + 1), r.right(), m_tracksHeight * (i + 1));
         //painter->drawText(QRectF(10, 50 * i, 100, 50 * i + 49), Qt::AlignLeft, i18n(" Track ") + QString::number(i + 1));
     }
-    int lowerLimit = m_tracksHeight * m_tracksList.count() + 1;
+    int lowerLimit = m_tracksHeight * m_scene->m_tracksList.count() + 1;
     if (height() > lowerLimit)
-        painter->fillRect(QRectF(rectInView.left(), lowerLimit, rectInView.width(), height() - lowerLimit), QBrush(base));
+        painter->fillRect(QRectF(r.left(), lowerLimit, r.width(), height() - lowerLimit), QBrush(base));
 }
 
 bool CustomTrackView::findString(const QString &text) {
@@ -2045,16 +2085,16 @@ void CustomTrackView::copyClip() {
     for (int i = 0; i < itemList.count(); i++) {
         if (itemList.at(i)->type() == AVWIDGET) {
             ClipItem *dup = static_cast <ClipItem *>(itemList.at(i));
-            m_copiedItems.append(dup->clone(m_scale, dup->info()));
+            m_copiedItems.append(dup->clone(dup->info()));
         } else if (itemList.at(i)->type() == TRANSITIONWIDGET) {
             Transition *dup = static_cast <Transition *>(itemList.at(i));
-            m_copiedItems.append(dup->clone(m_scale));
+            m_copiedItems.append(dup->clone());
         }
     }
 }
 
 bool CustomTrackView::canBePastedTo(ItemInfo info, int type) const {
-    QRectF rect((double) info.startPos.frames(m_document->fps()) * m_scale, (double)(info.track * m_tracksHeight + 1), (double)(info.endPos - info.startPos).frames(m_document->fps()) * m_scale, (double)(m_tracksHeight - 1));
+    QRectF rect((double) info.startPos.frames(m_document->fps()), (double)(info.track * m_tracksHeight + 1), (double)(info.endPos - info.startPos).frames(m_document->fps()), (double)(m_tracksHeight - 1));
     QList<QGraphicsItem *> collisions = scene()->items(rect, Qt::IntersectsItemBoundingRect);
     for (int i = 0; i < collisions.count(); i++) {
         if (collisions.at(i)->type() == type) return false;
@@ -2086,7 +2126,7 @@ bool CustomTrackView::canBeMoved(QList<AbstractClipItem *> items, GenTime offset
             // No clip should go below 0
             return false;
         }
-        QRectF rect((double) info.startPos.frames(m_document->fps()) * m_scale, (double)(info.track * m_tracksHeight + 1), (double)(info.endPos - info.startPos).frames(m_document->fps()) * m_scale, (double)(m_tracksHeight - 1));
+        QRectF rect((double) info.startPos.frames(m_document->fps()), (double)(info.track * m_tracksHeight + 1), (double)(info.endPos - info.startPos).frames(m_document->fps()), (double)(m_tracksHeight - 1));
         movePath.addRect(rect);
     }
     QList<QGraphicsItem *> collisions = scene()->items(movePath, Qt::IntersectsItemBoundingRect);
@@ -2107,7 +2147,7 @@ void CustomTrackView::pasteClip() {
     QPoint position;
     if (m_menuPosition.isNull()) position = mapFromGlobal(QCursor::pos());
     else position = m_menuPosition;
-    GenTime pos = GenTime((int)(mapToScene(position).x() / m_scale), m_document->fps());
+    GenTime pos = GenTime((int)(mapToScene(position).x()), m_document->fps());
     int track = (int)(position.y() / m_tracksHeight);
     ItemInfo first = m_copiedItems.at(0)->info();
 
@@ -2163,7 +2203,7 @@ void CustomTrackView::pasteClipEffects() {
         if (clips.at(i)->type() == AVWIDGET) {
             ClipItem *item = static_cast < ClipItem *>(clips.at(i));
             for (int i = 0; i < clip->effectsCount(); i++) {
-                new AddEffectCommand(this, m_tracksList.count() - item->track(), item->startPos(), clip->effectAt(i), true, paste);
+                new AddEffectCommand(this, m_scene->m_tracksList.count() - item->track(), item->startPos(), clip->effectAt(i), true, paste);
             }
         }
     }
index 2a4e5d24bddd1bb7664d269b07a93e9bd6d52639..6812e904ee1697596901f6467169fe3e9947dc3a 100644 (file)
 
 class ClipItem;
 class AbstractClipItem;
+class AbstractGroupItem;
 class Transition;
+class CustomTrackScene;
 
 class CustomTrackView : public QGraphicsView {
     Q_OBJECT
 
 public:
-    CustomTrackView(KdenliveDoc *doc, QGraphicsScene * projectscene, QWidget *parent = 0);
+    CustomTrackView(KdenliveDoc *doc, CustomTrackScene* projectscene, QWidget *parent = 0);
     virtual ~ CustomTrackView();
     virtual void mousePressEvent(QMouseEvent * event);
     virtual void mouseReleaseEvent(QMouseEvent * event);
@@ -140,6 +142,7 @@ private:
     int m_cursorPos;
     ClipItem *m_dropItem;
     KdenliveDoc *m_document;
+    CustomTrackScene *m_scene;
     void addItem(DocClipBase *clip, QPoint pos);
     QGraphicsLineItem *m_cursorLine;
     ItemInfo m_dragItemInfo;
@@ -153,10 +156,8 @@ private:
     QTimeLine *m_animationTimer;
     QColor m_tipColor;
     QPen m_tipPen;
-    double m_scale;
     QPoint m_clickPoint;
     QPoint m_clickEvent;
-    QList <GenTime> m_snapPoints;
     QList <CommentedTime> m_searchPoints;
     QList <Guide *> m_guides;
     void updateSnapPoints(AbstractClipItem *selected);
@@ -171,7 +172,7 @@ private:
     QMenu *m_timelineContextMenu;
     QMenu *m_timelineContextClipMenu;
     QMenu *m_timelineContextTransitionMenu;
-    QList <TrackInfo> m_tracksList;
+
     QList <CommentedTime> m_searchStrings;
     int m_findIndex;
     PROJECTTOOL m_tool;
@@ -182,6 +183,7 @@ private:
     /** Used to get the point in timeline where a context menu was opened */
     QPoint m_menuPosition;
     bool m_blockRefresh;
+    AbstractGroupItem *m_selectionGroup;
 
     /** Get the index of the video track that is just below current track */
     int getPreviousVideoTrack(int track);
index 615186010d69d91f82419dc3f2839045a7b57a0d..5626552bb0aab32b519ef7f9cfa674ba09172e22 100644 (file)
@@ -30,7 +30,7 @@
 
 enum OPERATIONTYPE { NONE = 0, MOVE = 1, RESIZESTART = 2, RESIZEEND = 3, FADEIN = 4, FADEOUT = 5, TRANSITIONSTART = 6, TRANSITIONEND = 7, MOVEGUIDE = 8, KEYFRAME = 9};
 enum CLIPTYPE { UNKNOWN = 0, AUDIO = 1, VIDEO = 2, AV = 3, COLOR = 4, IMAGE = 5, TEXT = 6, SLIDESHOW = 7, VIRTUAL = 8, PLAYLIST = 9, FOLDER = 10};
-enum GRAPHICSRECTITEM { AVWIDGET = 70000 , LABELWIDGET , TRANSITIONWIDGET };
+enum GRAPHICSRECTITEM { AVWIDGET = 70000 , LABELWIDGET , TRANSITIONWIDGET  , GROUPWIDGET};
 
 enum PROJECTTOOL { SELECTTOOL = 0 , RAZORTOOL = 1 };
 
index 055028a9d0de4c08be6db76808c5c0304f5516b6..4609a2c27b67eb9ec69e24717764478915c158c9 100644 (file)
@@ -34,5 +34,4 @@ private:
 
 };
 
-
 #endif
index 55cf462ce64c1fcca2b117dc4b9b9561e2fb2f19..bbc2a6bd10ff1eca5d31fcb95c8287c1cfd296a1 100644 (file)
 
 #include "guide.h"
 #include "customtrackview.h"
+#include "customtrackscene.h"
 #include "kdenlivesettings.h"
 
-Guide::Guide(CustomTrackView *view, GenTime pos, QString label, double scale, double fps, double height)
-        : QGraphicsLineItem(), m_view(view), m_position(pos), m_label(label), m_scale(scale), m_fps(fps) {
+Guide::Guide(CustomTrackView *view, GenTime pos, QString label, double fps, double height)
+        : QGraphicsLineItem(), m_view(view), m_position(pos), m_label(label), m_fps(fps) {
     setFlags(QGraphicsItem::ItemIsMovable);
     setToolTip(label);
     setLine(0, 0, 0, height);
-    setPos(m_position.frames(m_fps) * scale, 0);
-    setPen(QPen(QBrush(QColor(0, 0, 200, 180)), 2));
+    setPos(m_position.frames(m_fps), 0);
+    setPen(QPen(QBrush(QColor(0, 0, 200, 180)), 1));
     setZValue(999);
     setAcceptsHoverEvents(true);
     const QFontMetrics metric = m_view->fontMetrics();
@@ -42,12 +43,6 @@ Guide::Guide(CustomTrackView *view, GenTime pos, QString label, double scale, do
     prepareGeometryChange();
 }
 
-
-void Guide::updatePosition(double scale) {
-    m_scale = scale;
-    setPos(m_position.frames(m_fps) * m_scale, 0);
-}
-
 QString Guide::label() const {
     return m_label;
 }
@@ -62,7 +57,7 @@ CommentedTime Guide::info() const {
 
 void Guide::updateGuide(const GenTime newPos, const QString &comment) {
     m_position = newPos;
-    setPos(m_position.frames(m_fps) * m_scale, 0);
+    setPos(m_position.frames(m_fps), 0);
     if (comment != QString()) {
         m_label = comment;
         setToolTip(m_label);
@@ -103,17 +98,23 @@ QVariant Guide::itemChange(GraphicsItemChange change, const QVariant &value) {
 QRectF Guide::boundingRect() const {
     if (KdenliveSettings::showmarkers()) {
         QRectF rect = QGraphicsLineItem::boundingRect();
-        rect.setWidth(m_width);
+        rect.setLeft(line().x1());
+        rect.setWidth(m_width / static_cast <CustomTrackScene*>(scene())->scale());
         return rect;
     } else return QGraphicsLineItem::boundingRect();
 }
 
 // virtual
 void Guide::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w) {
-    QGraphicsLineItem::paint(painter, option, w);
+    painter->setMatrixEnabled(false);
+    QLineF guideline = painter->matrix().map(line());
+    painter->setPen(pen());
+    painter->drawLine(guideline);
+    //painter->fillRect(painter->matrix().mapRect(boundingRect()), QColor(200, 100, 100, 100));
+    //QGraphicsLineItem::paint(painter, option, w);
     if (KdenliveSettings::showmarkers()) {
-        QRectF br = boundingRect();
-        QRectF txtBounding = painter->boundingRect(br.x(), br.y() + 10 + m_view->verticalScrollBar()->value(), m_width, 50, Qt::AlignLeft | Qt::AlignTop, " " + m_label + " ");
+        QPointF p1 = guideline.p1() + QPointF(1, 0);
+        QRectF txtBounding = painter->boundingRect(p1.x(), p1.y() + 10, m_width, 50, Qt::AlignLeft | Qt::AlignTop, " " + m_label + " ");
         QPainterPath path;
         path.addRoundedRect(txtBounding, 3, 3);
         painter->fillPath(path, QBrush(pen().color()));
index e76b6c679ec1f8d4db833151599ea903a141eb35..b11693146b40e2fb7fe82050c0ddd6e2ccf209cb 100644 (file)
@@ -32,8 +32,7 @@ class CustomTrackView;
 class Guide : public QGraphicsLineItem {
 
 public:
-    Guide(CustomTrackView *view, GenTime pos, QString label, double scale, double fps, double height);
-    void updatePosition(double scale);
+    Guide(CustomTrackView *view, GenTime pos, QString label, double fps, double height);
     GenTime position() const;
     void updateGuide(const GenTime newPos, const QString &comment = QString());
     QString label() const;
@@ -50,7 +49,6 @@ protected:
 private:
     GenTime m_position;
     QString m_label;
-    double m_scale;
     double m_fps;
     CustomTrackView *m_view;
     int m_width;
index 561f411fe89983786f23287fc6a8d0380d36b86d..1fa272f2dc0581639e560530dc28a20e5b36fbcc 100644 (file)
@@ -408,6 +408,7 @@ void KdenliveDoc::setProfilePath(QString path) {
     if (path.isEmpty()) path = KdenliveSettings::default_profile();
     if (path.isEmpty()) path = "dv_pal";
     m_profile = ProfilesDialog::getVideoProfile(path);
+    KdenliveSettings::setProject_display_ratio((double) m_profile.display_aspect_num / m_profile.display_aspect_den);
     m_fps = (double) m_profile.frame_rate_num / m_profile.frame_rate_den;
     m_width = m_profile.width;
     m_height = m_profile.height;
@@ -416,6 +417,10 @@ void KdenliveDoc::setProfilePath(QString path) {
     else m_timecode.setFormat((int) m_fps);
 }
 
+const double KdenliveDoc::dar() {
+    return (double) m_profile.display_aspect_num / m_profile.display_aspect_den;
+}
+
 void KdenliveDoc::setThumbsProgress(const QString &message, int progress) {
     emit progressInfo(message, progress);
 }
index 8dbdae19f3596885e7258d54cdf2a29fce0ae76a..f19526ba931cab671d74bcf57a57cda8a2c9a394 100644 (file)
@@ -102,6 +102,7 @@ Q_OBJECT public:
     void syncGuides(QList <Guide *> guides);
     void setZoom(int factor);
     int zoom() const;
+    const double dar();
 
 private:
     KUrl m_url;
index e83672bb0d7656763d4a9b66e46044dd2bbf71b3..1975dd833a7a2c579a1b9b2da5680f4db20068d0 100644 (file)
@@ -125,6 +125,92 @@ void MyThread::run() {
 
 }
 
+void ThumbThread::init(QObject *parent, Mlt::Producer *prod, int width, int height) {
+    stop_me = false;
+    m_parent = parent;
+    m_isWorking = false;
+    m_prod = prod;
+    m_width = width;
+    m_height = height;
+    m_frame1 = -1;
+    m_frame2 = -1;
+}
+
+bool ThumbThread::isWorking() {
+    return m_isWorking;
+}
+
+void ThumbThread::setThumbFrames(Mlt::Producer *prod, int frame1, int frame2) {
+    if (!m_prod) m_prod = prod;
+    m_frame1 = frame1;
+    m_frame2 = frame2;
+}
+
+void ThumbThread::run() {
+    if (m_frame1 != -1 && m_prod) {
+        //mutex.lock();
+        m_prod->seek(m_frame1);
+        Mlt::Frame *avframe = m_prod->get_frame();
+        //mutex.unlock();
+        if (!avframe) {
+            kDebug() << "///// BROKEN FRAME";
+        } else {
+            mlt_image_format format = mlt_image_yuv422;
+            int frame_width = m_width;
+            int frame_height = m_height;
+            avframe->set("normalised_height", m_height);
+            avframe->set("normalised_width", m_width);
+            uint8_t *data = avframe->get_image(format, frame_width, frame_height, 0);
+            uint8_t *new_image = (uint8_t *)mlt_pool_alloc(frame_width * (frame_height + 1) * 4);
+            mlt_convert_yuv422_to_rgb24a((uint8_t *)data, new_image, frame_width * frame_height);
+
+            QImage image((uchar *)new_image, frame_width, frame_height, QImage::Format_ARGB32);
+
+            if (!image.isNull()) {
+                emit gotStartThumb(image.rgbSwapped());
+                //QApplication::postEvent(m_parent, new ThumbEvent(m_frame1, image.rgbSwapped(), (QEvent::Type)10006));
+                //pix = QPixmap::fromImage(image.rgbSwapped());
+            } /*else
+  pix.fill(Qt::red);*/
+            mlt_pool_release(new_image);
+            delete avframe;
+        }
+        //pix.fill(Qt::red);
+
+    }
+    if (m_frame2 != -1 && m_prod) {
+        //mutex.lock();
+        m_prod->seek(m_frame2);
+        Mlt::Frame *avframe = m_prod->get_frame();
+        //mutex.unlock();
+        if (!avframe) {
+            kDebug() << "///// BROKEN FRAME";
+        } else {
+            mlt_image_format format = mlt_image_yuv422;
+            int frame_width = 0;
+            int frame_height = 0;
+            avframe->set("normalised_height", m_height);
+            avframe->set("normalised_width", m_width);
+            uint8_t *data = avframe->get_image(format, frame_width, frame_height, 0);
+            uint8_t *new_image = (uint8_t *)mlt_pool_alloc(frame_width * (frame_height + 1) * 4);
+            mlt_convert_yuv422_to_rgb24a((uint8_t *)data, new_image, frame_width * frame_height);
+
+            QImage image((uchar *)new_image, frame_width, frame_height, QImage::Format_ARGB32);
+
+            if (!image.isNull()) {
+                emit gotEndThumb(image.rgbSwapped());
+                //QApplication::postEvent(m_parent, new ThumbEvent(m_frame2, image.rgbSwapped(), (QEvent::Type)10006));
+                //pix = QPixmap::fromImage(image.rgbSwapped());
+            } /*else
+  pix.fill(Qt::red);*/
+            mlt_pool_release(new_image);
+            delete avframe;
+        }
+        //pix.fill(Qt::red);
+        //QApplication::postEvent(m_parent, new ThumbEvent(m_frame2, pix, (QEvent::Type)10006));
+    }
+}
+
 
 KThumb::KThumb(ClipManager *clipManager, KUrl url, QObject * parent, const char *name): QObject(parent), m_clipManager(clipManager), m_url(url), m_producer(NULL), m_dar(1) {
     QCryptographicHash context(QCryptographicHash::Sha1);
@@ -134,7 +220,7 @@ KThumb::KThumb(ClipManager *clipManager, KUrl url, QObject * parent, const char
 }
 
 KThumb::~KThumb() {
-    if (thumbProducer.isRunning()) thumbProducer.exit();
+    if (audioThumbProducer.isRunning()) audioThumbProducer.exit();
 }
 
 void KThumb::setProducer(Mlt::Producer *producer) {
@@ -163,10 +249,12 @@ void KThumb::extractImage(int frame, int frame2) {
         return;
     }
     if (frame != -1) {
+        //videoThumbProducer.getThumb(frame);
         QPixmap pix = getFrame(m_producer, frame, twidth, KdenliveSettings::trackheight());
         emit thumbReady(frame, pix);
     }
     if (frame2 != -1) {
+        //videoThumbProducer.getThumb(frame2);
         QPixmap pix = getFrame(m_producer, frame2, twidth , KdenliveSettings::trackheight());
         emit thumbReady(frame2, pix);
     }
@@ -223,18 +311,18 @@ QPixmap KThumb::getImage(QDomElement xml, int frame, int width, int height) {
 //static
 QPixmap KThumb::getFrame(Mlt::Producer *producer, int framepos, int width, int height) {
     if (producer == NULL) {
-       QPixmap p(width, height);
-       p.fill(Qt::red);
-       return p;
+        QPixmap p(width, height);
+        p.fill(Qt::red);
+        return p;
     }
 
     producer->seek(framepos);
     Mlt::Frame *frame = producer->get_frame();
     if (!frame) {
         kDebug() << "///// BROKEN FRAME";
-       QPixmap p(width, height);
-       p.fill(Qt::red);
-       return p;
+        QPixmap p(width, height);
+        p.fill(Qt::red);
+        return p;
     }
     mlt_image_format format = mlt_image_yuv422;
     int frame_width = 0;
@@ -333,7 +421,7 @@ void KThumb::getThumbs(KUrl url, int startframe, int endframe, int width, int he
 }
 */
 void KThumb::stopAudioThumbs() {
-    if (thumbProducer.isRunning()) thumbProducer.stop_me = true;
+    if (audioThumbProducer.isRunning()) audioThumbProducer.stop_me = true;
 }
 
 
@@ -346,7 +434,7 @@ void KThumb::removeAudioThumb() {
 
 void KThumb::getAudioThumbs(int channel, double frame, double frameLength, int arrayWidth) {
 
-    if ((thumbProducer.isRunning() && thumbProducer.isWorking()) || channel == 0) {
+    if ((audioThumbProducer.isRunning() && audioThumbProducer.isWorking()) || channel == 0) {
         return;
     }
 
@@ -375,16 +463,16 @@ void KThumb::getAudioThumbs(int channel, double frame, double frameLength, int a
         }
         emit audioThumbReady(storeIn);
     } else {
-        if (thumbProducer.isRunning()) return;
-        thumbProducer.init(this, m_url, m_thumbFile, frame, frameLength, m_frequency, m_channels, arrayWidth);
-        thumbProducer.start(QThread::LowestPriority);
+        if (audioThumbProducer.isRunning()) return;
+        audioThumbProducer.init(this, m_url, m_thumbFile, frame, frameLength, m_frequency, m_channels, arrayWidth);
+        audioThumbProducer.start(QThread::LowestPriority);
         kDebug() << "STARTING GENERATE THMB FOR: " << m_url << " ................................";
     }
 }
 
 void KThumb::customEvent(QEvent * event) {
     if (event->type() == 10005) {
-        ProgressEvent* p = (ProgressEvent*) event;
+        ProgressEvent* p = static_cast <ProgressEvent*>(event);
         m_clipManager->setThumbsProgress(i18n("Creating thumbnail for %1", m_url.fileName()), p->value());
     }
 }
index e6227fd33567520b2f94723da13cf892e9dcbdaf..ae56c9f6eeeb9cb1ba3a651cb67d9f06753f8465 100644 (file)
@@ -21,6 +21,7 @@
 #include <QPixmap>
 #include <QFile>
 #include <QThread>
+#include <QMutex>
 #include <QDomElement>
 
 #include <KUrl>
@@ -47,6 +48,8 @@ class Profile;
 
 class ClipManager;
 
+
+
 class MyThread : public QThread {
 
 public:
@@ -68,6 +71,31 @@ private:
 };
 
 
+class ThumbThread : public QThread {
+    Q_OBJECT
+public:
+    virtual void run();
+    void init(QObject *parent, Mlt::Producer *prod, int width, int height);
+    void setThumbFrames(Mlt::Producer *prod, int frame1, int frame2);
+    bool isWorking();
+    bool stop_me;
+
+private:
+    int m_width;
+    int m_height;
+    int m_frame1;
+    int m_frame2;
+    Mlt::Producer *m_prod;
+    bool m_isWorking;
+    QObject *m_parent;
+    //QMutex mutex;
+
+signals:
+    void gotStartThumb(QImage);
+    void gotEndThumb(QImage);
+
+};
+
 class KThumb: public QObject {
 Q_OBJECT public:
 
@@ -94,7 +122,7 @@ protected:
     virtual void customEvent(QEvent * event);
 
 private:
-    MyThread thumbProducer;
+    MyThread audioThumbProducer;
     KUrl m_url;
     QString m_thumbFile;
     double m_dar;
index 19ca4fa695564d1ae9e6e1fa9280d116d7975244..a1ca5ce46d6af62f66f9cbe9685a695f6259a8d6 100644 (file)
@@ -1114,6 +1114,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
     m_monitorManager->setTimecode(doc->timecode());
     doc->setRenderer(m_projectMonitor->render);
     m_commandStack->setActiveStack(doc->commandStack());
+    KdenliveSettings::setProject_display_ratio(doc->dar());
     doc->updateAllProjectClips();
 
     if (m_commandStack->isClean()) kDebug() << "////////////  UNDO STACK IS CLEAN";
index 7a565625242b85fefd5b16442adf8ac26f25c84a..9c358f6dcd8d316937e87242d00e83bc593dc013 100644 (file)
@@ -220,35 +220,6 @@ QMap <QString, QString> ProfilesDialog::getProfilesInfo() {
     return result;
 }
 
-// static
-QStringList ProfilesDialog::getProfileNames() {
-    QStringList profilesNames;
-    QStringList profilesFiles;
-    QStringList profilesFilter;
-    profilesFilter << "*";
-
-    // List the Mlt profiles
-    profilesFiles = QDir(KdenliveSettings::mltpath()).entryList(profilesFilter, QDir::Files);
-    for (int i = 0; i < profilesFiles.size(); ++i) {
-        KConfig confFile(KdenliveSettings::mltpath() + "/" + profilesFiles.at(i), KConfig::SimpleConfig);
-        QString desc = confFile.entryMap().value("description");
-        if (!desc.isEmpty()) profilesNames.append(desc);
-    }
-
-    // List custom profiles
-    QStringList customProfiles = KGlobal::dirs()->findDirs("appdata", "profiles");
-    for (int i = 0; i < customProfiles.size(); ++i) {
-        profilesFiles = QDir(customProfiles.at(i)).entryList(profilesFilter, QDir::Files);
-        for (int i = 0; i < profilesFiles.size(); ++i) {
-            KConfig confFile(customProfiles.at(i) + "/" + profilesFiles.at(i), KConfig::SimpleConfig);
-            QString desc = confFile.entryMap().value("description");
-            if (!desc.isEmpty()) profilesNames.append(desc);
-        }
-    }
-
-    return profilesNames;
-}
-
 // static
 QMap< QString, QString > ProfilesDialog::getSettingsFromFile(const QString path) {
     QStringList profilesNames;
index 689058405a5c0925ea7f20b60844c577ee360652..d7f8ea055083886d991cb82d1fa2f8c5b23ee07a 100644 (file)
@@ -33,7 +33,6 @@ public:
     ProfilesDialog(QWidget * parent = 0);
 
     void fillList(const QString selectedProfile = QString());
-    static QStringList getProfileNames();
     static QString getProfileDescription(QString name);
     static QMap< QString, QString > getSettingsForProfile(const QString profileName);
     static QMap< QString, QString > getSettingsFromFile(const QString path);
index 8cceccd391e9c7bfd80df5ae25bfae5e27a0bdfa..9312052bdefdae3c709449c9efd76365f11f6245 100644 (file)
@@ -80,7 +80,6 @@ Render::Render(const QString & rendererName, int winid, int extid, QWidget *pare
 
     m_externalwinid = extid;
     m_winid = winid;
-    m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show);
     Mlt::Producer *producer = new Mlt::Producer(*m_mltProfile , "colour", "black");
     m_mltProducer = producer;
     if (m_blackClip) delete m_blackClip;
@@ -1089,7 +1088,7 @@ const QString & Render::rendererName() const {
 
 
 void Render::emitFrameNumber(double position) {
-    if (m_generateScenelist) return;
+    //if (m_generateScenelist) return;
     m_framePosition = position;
     emit rendererPosition((int) position);
     //if (qApp->activeWindow()) QApplication::postEvent(qApp->activeWindow(), new PositionChangeEvent( GenTime((int) position, m_fps), m_monitorId));
@@ -1456,7 +1455,7 @@ bool Render::mltRemoveEffect(int track, GenTime position, QString index, bool do
 }
 
 
-bool Render::mltAddEffect(int track, GenTime position, QMap <QString, QString> args, bool doRefresh) {
+bool Render::mltAddEffect(int track, GenTime position, QHash <QString, QString> args, bool doRefresh) {
 
     Mlt::Service service(m_mltProducer->parent().get_service());
 
@@ -1476,7 +1475,7 @@ bool Render::mltAddEffect(int track, GenTime position, QMap <QString, QString> a
     if (tag.startsWith("ladspa")) tag = "ladspa";
     char *filterTag = decodedString(tag);
     char *filterId = decodedString(args.value("id"));
-    QMap<QString, QString>::Iterator it;
+    QHash<QString, QString>::Iterator it;
     QString kfr = args.value("keyframes");
 
     if (!kfr.isEmpty()) {
@@ -1549,10 +1548,10 @@ bool Render::mltAddEffect(int track, GenTime position, QMap <QString, QString> a
     return true;
 }
 
-bool Render::mltEditEffect(int track, GenTime position, QMap <QString, QString> args) {
+bool Render::mltEditEffect(int track, GenTime position, QHash <QString, QString> args) {
     QString index = args.value("kdenlive_ix");
     QString tag =  args.value("tag");
-    QMap<QString, QString>::Iterator it = args.begin();
+    QHash<QString, QString>::Iterator it = args.begin();
     if (!args.value("keyframes").isEmpty() || /*it.key().startsWith("#") || */tag.startsWith("ladspa") || tag == "sox" || tag == "autotrack_rectangle") {
         // This is a keyframe effect, to edit it, we remove it and re-add it.
         mltRemoveEffect(track, position, index);
@@ -1787,6 +1786,7 @@ void Render::mltChangeTrackState(int track, bool mute, bool blind) {
 }
 
 bool Render::mltResizeClipStart(ItemInfo info, GenTime diff) {
+    //kDebug() << "////////  RSIZING CLIP from: "<<info.startPos.frames(25)<<" to "<<diff.frames(25);
     Mlt::Service service(m_mltProducer->parent().get_service());
     int moveFrame = (int) diff.frames(m_fps);
     Mlt::Tractor tractor(service);
@@ -1796,6 +1796,7 @@ bool Render::mltResizeClipStart(ItemInfo info, GenTime diff) {
         kDebug() << "////////  ERROR RSIZING BLANK CLIP!!!!!!!!!!!";
         return false;
     }
+    mlt_service_lock(service.get_service());
     int clipIndex = trackPlaylist.get_clip_index_at(info.startPos.frames(m_fps));
     /*int previousStart = trackPlaylist.clip_start(clipIndex);
     int previousDuration = trackPlaylist.clip_length(clipIndex) - 1;*/
@@ -1803,9 +1804,10 @@ bool Render::mltResizeClipStart(ItemInfo info, GenTime diff) {
     Mlt::Producer *clip = trackPlaylist.get_clip(clipIndex);
     if (clip == NULL) {
         kDebug() << "////////  ERROR RSIZING NULL CLIP!!!!!!!!!!!";
+        mlt_service_unlock(service.get_service());
         return false;
     }
-    m_mltConsumer->set("refresh", 0);
+    //m_mltConsumer->set("refresh", 0);
     int previousStart = clip->get_in();
     int previousDuration = trackPlaylist.clip_length(clipIndex) - 1;
     m_isBlocked = true;
@@ -1834,7 +1836,8 @@ bool Render::mltResizeClipStart(ItemInfo info, GenTime diff) {
         mltAddClipTransparency(transpinfo, info.track - 1, QString(clip->parent().get("id")).toInt());
     }
     m_isBlocked = false;
-    m_mltConsumer->set("refresh", 1);
+    //m_mltConsumer->set("refresh", 1);
+    mlt_service_unlock(service.get_service());
     return true;
 }
 
@@ -1855,6 +1858,7 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
     Mlt::Producer trackProducer(tractor.track(startTrack));
     Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
     int clipIndex = trackPlaylist.get_clip_index_at(moveStart + 1);
+    kDebug() << "//////  LOOKING FOR CLIP TO MOVE, INDEX: " << clipIndex;
     bool checkLength = false;
     if (endTrack == startTrack) {
         //mlt_service_lock(service.get_service());
index b2b57881ab05140e111bb9952815cde3c4fb2812..37a1b158b174bc56b60010b069ce0e7679bdcc2c 100644 (file)
@@ -157,8 +157,8 @@ Q_OBJECT public:
     bool mltMoveClip(int startTrack, int endTrack, int pos, int moveStart);
     bool mltRemoveClip(int track, GenTime position);
     bool mltRemoveEffect(int track, GenTime position, QString index, bool doRefresh = true);
-    bool mltAddEffect(int track, GenTime position, QMap <QString, QString> args, bool doRefresh = true);
-    bool mltEditEffect(int track, GenTime position, QMap <QString, QString> args);
+    bool mltAddEffect(int track, GenTime position, QHash <QString, QString> args, bool doRefresh = true);
+    bool mltEditEffect(int track, GenTime position, QHash <QString, QString> args);
     void mltMoveEffect(int track, GenTime position, int oldPos, int newPos);
     void mltChangeTrackState(int track, bool mute, bool blind);
     void mltMoveTransition(QString type, int startTrack,  int newTrack, int newTransitionTrack, GenTime oldIn, GenTime oldOut, GenTime newIn, GenTime newOut);
index 13c383bde05ef7fe469aa72003bc6210e86bc853..7c4e6f95f29103ad3b0e197142825e5e3ff89d70 100644 (file)
 #include "mainwindow.h"
 #include "customtrackview.h"
 
+
 TrackView::TrackView(KdenliveDoc *doc, QWidget *parent)
         : QWidget(parent), m_doc(doc), m_scale(1.0), m_projectTracks(0) {
 
     view = new Ui::TimeLine_UI();
     view->setupUi(this);
 
-    m_scene = new QGraphicsScene();
+    m_scene = new CustomTrackScene(doc);
     m_trackview = new CustomTrackView(doc, m_scene, parent);
     m_trackview->scale(1, 1);
     m_trackview->setAlignment(Qt::AlignLeft | Qt::AlignTop);
@@ -227,7 +228,7 @@ void TrackView::parseDocument(QDomDocument doc) {
             transitionInfo.endPos = GenTime(e.attribute("out").toInt(), m_doc->fps());
             transitionInfo.track = b_track;
             //kDebug() << "///////////////   +++++++++++  ADDING TRANSITION ON TRACK: " << b_track << ", TOTAL TRKA: " << m_projectTracks;
-            Transition *tr = new Transition(transitionInfo, a_track, m_scale, m_doc->fps(), base);
+            Transition *tr = new Transition(transitionInfo, a_track, m_doc->fps(), base);
             m_scene->addItem(tr);
         }
     }
@@ -352,7 +353,7 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool videotrack) {
                 clipinfo.cropStart = GenTime(in, m_doc->fps());
                 clipinfo.track = ix;
                 //kDebug() << "// INSERTING CLIP: " << in << "x" << out << ", track: " << ix << ", ID: " << id << ", SCALE: " << m_scale << ", FPS: " << m_doc->fps();
-                ClipItem *item = new ClipItem(clip, clipinfo, m_scale, m_doc->fps());
+                ClipItem *item = new ClipItem(clip, clipinfo, m_doc->fps());
                 if (hasSpeedAttribute) item->setSpeed(speed);
                 m_scene->addItem(item);
                 clip->addReference();
index 8198152e1ee9d093102d62e8e24049733b5c1f2e..6722bdded564742e829a8551bcac22304b5b7a70 100644 (file)
@@ -31,6 +31,7 @@
 
 #define FRAME_SIZE 90
 
+#include "customtrackscene.h"
 #include "ui_timeline_ui.h"
 
 class ClipItem;
@@ -72,7 +73,7 @@ private:
     double m_scale;
     int m_projectTracks;
     QString m_editMode;
-    QGraphicsScene *m_scene;
+    CustomTrackScene *m_scene;
 
     KdenliveDoc *m_doc;
     QVBoxLayout *m_tracksLayout;
index 2e163439a9a098fbeaa7112af735c30702007e5f..b4d71c7d810cac83c4909450ef27548c89a4c899 100644 (file)
 #include "transition.h"
 #include "clipitem.h"
 #include "kdenlivesettings.h"
+#include "customtrackscene.h"
 #include "mainwindow.h"
 
-Transition::Transition(const ItemInfo info, int transitiontrack, double scale, double fps, QDomElement params) : AbstractClipItem(info, QRectF(), fps), m_gradient(QLinearGradient(0, 0, 0, 0)) {
-    setRect(0, 0, (qreal)(info.endPos - info.startPos).frames(fps) * scale - .5, (qreal)(KdenliveSettings::trackheight() / 3 * 2 - 1));
-    setPos((qreal) info.startPos.frames(fps) * scale, (qreal)(info.track * KdenliveSettings::trackheight() + KdenliveSettings::trackheight() / 3 * 2));
+Transition::Transition(const ItemInfo info, int transitiontrack, double fps, QDomElement params) : AbstractClipItem(info, QRectF(), fps), m_gradient(QLinearGradient(0, 0, 0, 0)) {
+    setRect(0, 0, (qreal)(info.endPos - info.startPos).frames(fps) - 0.02, (qreal)(KdenliveSettings::trackheight() / 3 * 2 - 1));
+    setPos((qreal) info.startPos.frames(fps), (qreal)(info.track * KdenliveSettings::trackheight() + KdenliveSettings::trackheight() / 3 * 2));
 
     m_singleClip = true;
     m_transitionTrack = transitiontrack;
@@ -63,9 +64,9 @@ Transition::Transition(const ItemInfo info, int transitiontrack, double scale, d
 Transition::~Transition() {
 }
 
-Transition *Transition::clone(double scale) {
+Transition *Transition::clone() {
     QDomElement xml = toXML().cloneNode().toElement();
-    Transition *tr = new Transition(info(), transitionEndTrack(), scale, m_fps, xml);
+    Transition *tr = new Transition(info(), transitionEndTrack(), m_fps, xml);
     return tr;
 }
 
@@ -118,32 +119,27 @@ void Transition::updateTransitionEndTrack(int newtrack) {
 void Transition::paint(QPainter *painter,
                        const QStyleOptionGraphicsItem *option,
                        QWidget *widget) {
-
-    painter->setClipRect(option->exposedRect);
+    QRectF exposed = option->exposedRect;
+    exposed.setRight(exposed.right() + 1);
+    exposed.setBottom(exposed.bottom() + 1);
+    painter->setClipRect(exposed);
     QRectF br = rect();
-    QPainterPath roundRectPathUpper = upperRectPart(br), roundRectPathLower = lowerRectPart(br);
-    QPainterPath resultClipPath = roundRectPathUpper.united(roundRectPathLower);
-
-
-#if 0
-    QRadialGradient radialGrad(QPointF(br.x() + 50, br.y() + 20), 70);
-    radialGrad.setColorAt(0, QColor(200, 200, 0, 100));
-    radialGrad.setColorAt(0.5, QColor(150, 150, 0, 100));
-    radialGrad.setColorAt(1, QColor(100, 100, 0, 100));
-    painter->fillRect(br.intersected(rectInView), QBrush(radialGrad)/*,Qt::Dense4Pattern*/);
-#else
     m_gradient.setStart(0, br.y());
     m_gradient.setFinalStop(0, br.bottom());
-    painter->fillPath(resultClipPath, m_gradient);
-#endif
+    painter->fillRect(br, m_gradient);
 
     int top = (int)(br.y() + br.height() / 2 - 7);
-    painter->drawPixmap((int)(br.x() + 10), top, transitionPixmap());
+    QPointF p1(br.x(), br.y() + br.height() / 2 - 7);
+    painter->setMatrixEnabled(false);
+    painter->drawPixmap(painter->matrix().map(p1) + QPointF(5, 0), transitionPixmap());
     painter->setPen(QColor(0, 0, 0, 180));
     top += painter->fontInfo().pixelSize();
-    painter->drawText((int)br.x() + 31, top + 1, transitionName());
+    QPointF p2(br.x(), top);
+    painter->drawText(painter->matrix().map(p2) + QPointF(26, 1), transitionName());
     painter->setPen(QColor(255, 255, 255, 180));
-    painter->drawText((int)br.x() + 30, top, transitionName());
+    QPointF p3(br.x(), top);
+    painter->drawText(painter->matrix().map(p3) + QPointF(25, 0), transitionName());
+    painter->setMatrixEnabled(true);
     QPen pen = painter->pen();
     if (isSelected()) {
         pen.setColor(Qt::red);
@@ -153,14 +149,64 @@ void Transition::paint(QPainter *painter,
         //pen.setWidth(1);
     }
     painter->setPen(pen);
-    painter->drawPath(resultClipPath);
+    painter->drawRect(br);
 }
 
 int Transition::type() const {
     return TRANSITIONWIDGET;
 }
 
-OPERATIONTYPE Transition::operationMode(QPointF pos, double scale) {
+//virtual
+QVariant Transition::itemChange(GraphicsItemChange change, const QVariant &value) {
+    if (change == ItemPositionChange && scene()) {
+        // calculate new position.
+        QPointF newPos = value.toPointF();
+        int xpos = projectScene()->getSnapPointForPos((int) newPos.x(), KdenliveSettings::snaptopoints());
+        xpos = qMax(xpos, 0);
+        newPos.setX(xpos);
+        int newTrack = newPos.y() / KdenliveSettings::trackheight();
+        newTrack = qMin(newTrack, projectScene()->tracksCount() - 1);
+        newTrack = qMax(newTrack, 0);
+        newPos.setY((int)(newTrack * KdenliveSettings::trackheight() + KdenliveSettings::trackheight() / 3 * 2));
+        // Only one clip is moving
+        QRectF sceneShape = rect();
+        sceneShape.translate(newPos);
+        QList<QGraphicsItem*> items = scene()->items(sceneShape, Qt::IntersectsItemShape);
+        items.removeAll(this);
+
+        if (!items.isEmpty()) {
+            for (int i = 0; i < items.count(); i++) {
+                if (items.at(i)->type() == type()) {
+                    // Collision! Don't move.
+                    //kDebug()<<"/// COLLISION WITH ITEM: "<<items.at(i)->boundingRect()<<", POS: "<<items.at(i)->pos()<<", ME: "<<newPos;
+                    QPointF otherPos = items.at(i)->pos();
+                    if ((int) otherPos.y() != (int) pos().y()) return pos();
+                    //kDebug()<<"////  CURRENT Y: "<<pos().y()<<", COLLIDING Y: "<<otherPos.y();
+                    if (pos().x() < otherPos.x()) {
+                        int npos = (static_cast < AbstractClipItem* >(items.at(i))->startPos() - m_cropDuration).frames(m_fps);
+                        newPos.setX(npos);
+                    } else {
+                        // get pos just after colliding clip
+                        int npos = static_cast < AbstractClipItem* >(items.at(i))->endPos().frames(m_fps);
+                        newPos.setX(npos);
+                    }
+                    m_track = newTrack;
+                    //kDebug()<<"// ITEM NEW POS: "<<newPos.x()<<", mapped: "<<mapToScene(newPos.x(), 0).x();
+                    m_startPos = GenTime((int) newPos.x(), m_fps);
+                    return newPos;
+                }
+            }
+        }
+        m_track = newTrack;
+        m_startPos = GenTime((int) newPos.x(), m_fps);
+        //kDebug()<<"// ITEM NEW POS: "<<newPos.x()<<", mapped: "<<mapToScene(newPos.x(), 0).x();
+        return newPos;
+    }
+    return QGraphicsItem::itemChange(change, value);
+}
+
+
+OPERATIONTYPE Transition::operationMode(QPointF pos) {
     QRectF rect = sceneBoundingRect();
     if (qAbs((int)(pos.x() - rect.x())) < 6) return RESIZESTART;
     else if (qAbs((int)(pos.x() - (rect.right()))) < 6) return RESIZEEND;
index a6dc6154806015402531997e05fcb9918487d26c..41f7d7da5daf45ecc1730cf4a70d6b7b9c781c74 100644 (file)
@@ -40,7 +40,7 @@ class Transition : public AbstractClipItem {
     Q_OBJECT
 public:
 
-    Transition(const ItemInfo info, int transitiontrack, double scale, double fps, QDomElement params = QDomElement());
+    Transition(const ItemInfo info, int transitiontrack, double fps, QDomElement params = QDomElement());
     virtual ~Transition();
     virtual void paint(QPainter *painter,
                        const QStyleOptionGraphicsItem *option,
@@ -51,13 +51,12 @@ public:
 
     /** Return the track number of transition in the playlist*/
     int transitionEndTrack() const;
-    Transition *clone();
     bool hasClip(const ClipItem * clip) const;
     bool belongsToClip(const ClipItem * clip) const;
     bool invertedTransition() const;
     QString transitionName() const;
     QString transitionTag() const;
-    OPERATIONTYPE operationMode(QPointF pos, double scale);
+    OPERATIONTYPE operationMode(QPointF pos);
     //const QMap < QString, QString > transitionParameters() const;
     void setTransitionParameters(const QDomElement params);
     void setTransitionDirection(bool inv);
@@ -68,7 +67,11 @@ public:
     /** Transition should be linked to another track */
     void updateTransitionEndTrack(int newtrack);
     const ClipItem *referencedClip() const;
-    Transition *clone(double scale);
+    Transition *clone();
+
+protected:
+    virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+
 private:
     bool m_singleClip;
     QLinearGradient m_gradient;