Here is a patch I started a couple of months ago. I don't really have
the time to finish it up. The basics work, at least -100% for
playback, but not all editing operations are safe. I am providing it
in case someone more familiar with the code wants to take it on.

-- 
+-DRD-+
Index: src/customtrackview.cpp
===================================================================
--- src/customtrackview.cpp	(revision 3600)
+++ src/customtrackview.cpp	(working copy)
@@ -2834,7 +2834,7 @@
         if (itemList.at(i)->type() == AVWIDGET) {
             ClipItem *item = static_cast <ClipItem *>(itemList.at(i));
             ItemInfo info = item->info();
-            if (percent == -1) percent = QInputDialog::getInteger(this, i18n("Edit Clip Speed"), i18n("New speed (percents)"), item->speed() * 100, 1, 10000, 1, &ok);
+			if (percent == -1) percent = QInputDialog::getInteger(this, i18n("Edit Clip Speed"), i18n("New speed (percents)"), item->speed() * 100, -10000, 10000, 1, &ok);
             if (!ok) break;
             double speed = (double) percent / 100.0;
             if (item->speed() != speed && (item->clipType() == VIDEO || item->clipType() == AV)) {
@@ -3243,7 +3243,7 @@
             }
         }
         KdenliveSettings::setSnaptopoints(snap);
-        m_document->renderer()->doRefresh();
+		m_document->renderer()->doRefresh();
     } else kDebug() << "///////// WARNING; NO GROUP TO MOVE";
 }
 
Index: src/abstractclipitem.cpp
===================================================================
--- src/abstractclipitem.cpp	(revision 3600)
+++ src/abstractclipitem.cpp	(working copy)
@@ -81,17 +81,18 @@
 void AbstractClipItem::updateItem()
 {
     m_track = (int)(scenePos().y() / KdenliveSettings::trackheight());
-    m_startPos = GenTime((int) scenePos().x(), m_fps);
+	m_startPos = GenTime((int) scenePos().x(), qAbs(m_fps));
 }
 
 void AbstractClipItem::updateRectGeometry()
 {
-    setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height());
+	setRect(0, 0, cropDuration().frames(qAbs(m_fps)) - 0.02, rect().height());
 }
 
 void AbstractClipItem::resizeStart(int posx, double speed)
 {
-    GenTime durationDiff = GenTime(posx, m_fps) - m_startPos;
+	double fps = qAbs(m_fps);
+	GenTime durationDiff = GenTime(posx, fps) - m_startPos;
     if (durationDiff == GenTime()) return;
     //kDebug() << "-- RESCALE DIFF=" << durationDiff.frames(25) << ", CLIP: " << startPos().frames(25) << "-" << endPos().frames(25);
 
@@ -99,29 +100,29 @@
         durationDiff = GenTime() - cropStart();
     } else if (durationDiff >= m_cropDuration) {
         return;
-        if (m_cropDuration > GenTime(3, m_fps)) durationDiff = GenTime(3, m_fps);
+		if (m_cropDuration > GenTime(3, fps)) durationDiff = GenTime(3, fps);
         else return;
     }
-    //kDebug()<<"// DURATION DIFF: "<<durationDiff.frames(25)<<", POS: "<<pos().x();
+    //kDebug()<<"// DURATION DIFF: "<<durationDiff.frames(25)<<", POS: "<<pos().x();
     m_startPos += durationDiff;
     if (type() == AVWIDGET) m_cropStart += durationDiff * speed;
     m_cropDuration = m_cropDuration - durationDiff * speed;
 
-    setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height());
-    moveBy(durationDiff.frames(m_fps), 0);
-    //setPos(m_startPos.frames(m_fps), pos().y());
+	setRect(0, 0, cropDuration().frames(fps) - 0.02, rect().height());
+	moveBy(durationDiff.frames(fps), 0);
+	//setPos(m_startPos.frames(fps), pos().y());
     if ((int) scenePos().x() != posx) {
-        //kDebug()<<"//////  WARNING, DIFF IN XPOS: "<<pos().x()<<" == "<<m_startPos.frames(m_fps);
-        GenTime diff = GenTime((int) pos().x() - posx, m_fps);
+		//kDebug()<<"//////  WARNING, DIFF IN XPOS: "<<pos().x()<<" == "<<m_startPos.frames(fps);
+		GenTime diff = GenTime((int) pos().x() - posx, fps);
         if (type() == AVWIDGET) m_cropStart = m_cropStart + diff;
         m_cropDuration = m_cropDuration - diff;
-        setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height());
+		setRect(0, 0, cropDuration().frames(fps) - 0.02, rect().height());
         //kDebug()<<"// NEW START: "<<m_startPos.frames(25)<<", NW DUR: "<<m_cropDuration.frames(25);
     }
 
 
     //kDebug() << "-- NEW CLIP=" << startPos().frames(25) << "-" << endPos().frames(25);
-    //setRect((double) m_startPos.frames(m_fps) * scale, rect().y(), (double) m_cropDuration.frames(m_fps) * scale, rect().height());
+	//setRect((double) m_startPos.frames(fps) * scale, rect().y(), (double) m_cropDuration.frames(fps) * scale, rect().height());
 
     /*    if (durationDiff < GenTime()) {
             QList <QGraphicsItem *> collisionList = collidingItems(Qt::IntersectsItemBoundingRect);
@@ -129,9 +130,9 @@
                 QGraphicsItem *item = collisionList.at(i);
                 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, (m_cropDuration - diff).frames(m_fps) - 0.02, rect().height());
-                    setPos((m_startPos + diff).frames(m_fps), pos().y());
+					GenTime diff = ((AbstractClipItem *)item)->endPos() + GenTime(1, fps) - m_startPos;
+					setRect(0, 0, (m_cropDuration - diff).frames(fps) - 0.02, rect().height());
+					setPos((m_startPos + diff).frames(fps), pos().y());
                     m_startPos += diff;
                     if (type() == AVWIDGET) m_cropStart += diff;
                     m_cropDuration = m_cropDuration - diff;
@@ -143,15 +144,16 @@
 
 void AbstractClipItem::resizeEnd(int posx, double speed, bool /*updateKeyFrames*/)
 {
-    GenTime durationDiff = GenTime(posx, m_fps) - endPos();
+	double fps = qAbs(m_fps);
+	GenTime durationDiff = GenTime(posx, fps) - endPos();
     if (durationDiff == GenTime()) return;
     //kDebug() << "// DUR DIFF1:" << durationDiff.frames(25) << ", ADJUSTED: " << durationDiff.frames(25) * speed << ", SPED:" << speed;
     if (cropDuration() + durationDiff <= GenTime()) {
-        durationDiff = GenTime() - (cropDuration() - GenTime(3, m_fps));
+		durationDiff = GenTime() - (cropDuration() - GenTime(3, fps));
     }
     //kDebug() << "// DUR DIFF2:" << durationDiff.frames(25) << ", ADJUSTED: " << durationDiff.frames(25) * speed << ", SPED:" << speed;
     m_cropDuration += durationDiff * speed;
-    setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height());
+	setRect(0, 0, cropDuration().frames(fps) - 0.02, rect().height());
     if (durationDiff > GenTime()) {
         QList <QGraphicsItem *> collisionList = collidingItems(Qt::IntersectsItemBoundingRect);
         for (int i = 0; i < collisionList.size(); ++i) {
@@ -160,9 +162,9 @@
                 /*kDebug() << "/////////  COLLISION DETECTED!!!!!!!!!";
                 kDebug() << "/////////  CURRENT: " << startPos().frames(25) << "x" << endPos().frames(25) << ", RECT: " << rect() << "-" << pos();
                 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();
+				GenTime diff = ((AbstractClipItem *)item)->startPos() - GenTime(1, fps) - startPos();
                 m_cropDuration = diff * speed;
-                setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height());
+				setRect(0, 0, cropDuration().frames(fps) - 0.02, rect().height());
                 break;
             }
         }
@@ -245,9 +247,10 @@
 
 void AbstractClipItem::drawKeyFrames(QPainter *painter, QRectF /*exposedRect*/)
 {
+	double fps = qAbs(m_fps);
     if (m_keyframes.count() < 2) return;
     QRectF br = rect();
-    double maxw = br.width() / m_cropDuration.frames(m_fps);
+	double maxw = br.width() / m_cropDuration.frames(fps);
     double maxh = br.height() / 100.0 * m_keyframeFactor;
     double x1;
     double y1;
@@ -273,7 +276,7 @@
     // draw keyframes
     QMap<int, double>::const_iterator i = m_keyframes.constBegin();
     QColor color(Qt::blue);
-    x1 = br.x() + maxw * (i.key() - m_cropStart.frames(m_fps));
+	x1 = br.x() + maxw * (i.key() - m_cropStart.frames(fps));
     y1 = br.bottom() - i.value() * maxh;
     QLineF l2;
     while (i != m_keyframes.constEnd()) {
@@ -281,7 +284,7 @@
         else color = QColor(Qt::blue);
         ++i;
         if (i == m_keyframes.constEnd()) break;
-        x2 = br.x() + maxw * (i.key() - m_cropStart.frames(m_fps));
+		x2 = br.x() + maxw * (i.key() - m_cropStart.frames(fps));
         y2 = br.bottom() - i.value() * maxh;
         QLineF l(x1, y1, x2, y2);
         l2 = painter->matrix().map(l);
@@ -297,18 +300,19 @@
 
 int AbstractClipItem::mouseOverKeyFrames(QPointF pos)
 {
+	double fps = qAbs(m_fps);
     QRectF br = sceneBoundingRect();
-    double maxw = br.width() / m_cropDuration.frames(m_fps);
+	double maxw = br.width() / m_cropDuration.frames(fps);
     double maxh = br.height() / 100.0 * m_keyframeFactor;
     if (m_keyframes.count() > 1) {
         QMap<int, double>::const_iterator i = m_keyframes.constBegin();
         double x1;
         double y1;
         while (i != m_keyframes.constEnd()) {
-            x1 = br.x() + maxw * (i.key() - m_cropStart.frames(m_fps));
+			x1 = br.x() + maxw * (i.key() - m_cropStart.frames(fps));
             y1 = br.bottom() - i.value() * maxh;
             if (qAbs(pos.x() - x1) < 6 && qAbs(pos.y() - y1) < 6) {
-                setToolTip('[' + QString::number((GenTime(i.key(), m_fps) - m_cropStart).seconds(), 'f', 2) + i18n("seconds") + ", " + QString::number(i.value(), 'f', 1) + "%]");
+				setToolTip('[' + QString::number((GenTime(i.key(), fps) - m_cropStart).seconds(), 'f', 2) + i18n("seconds") + ", " + QString::number(i.value(), 'f', 1) + "%]");
                 return i.key();
             } else if (x1 > pos.x()) break;
             ++i;
@@ -321,8 +325,9 @@
 void AbstractClipItem::updateSelectedKeyFrame()
 {
     if (m_editedKeyframe == -1) return;
+	double fps = qAbs(m_fps);
     QRectF br = sceneBoundingRect();
-    double maxw = br.width() / m_cropDuration.frames(m_fps);
+	double maxw = br.width() / m_cropDuration.frames(fps);
     double maxh = br.height() / 100.0 * m_keyframeFactor;
     update(br.x() + maxw *(m_selectedKeyframe - m_cropStart.frames(m_fps)) - 3, br.bottom() - m_keyframes[m_selectedKeyframe] * maxh - 3, 12, 12);
     m_selectedKeyframe = m_editedKeyframe;
@@ -342,9 +347,10 @@
 void AbstractClipItem::updateKeyFramePos(const GenTime pos, const double value)
 {
     if (!m_keyframes.contains(m_selectedKeyframe)) return;
-    int newpos = (int) pos.frames(m_fps);
-    int start = m_cropStart.frames(m_fps);
-    int end = (m_cropStart + m_cropDuration).frames(m_fps);
+	double fps = qAbs(m_fps);
+	int newpos = (int) pos.frames(fps);
+	int start = m_cropStart.frames(fps);
+	int end = (m_cropStart + m_cropDuration).frames(fps);
     newpos = qMax(newpos, start);
     newpos = qMin(newpos, end);
     if (value < -50 && m_selectedKeyframe != start && m_selectedKeyframe != end) {
@@ -381,7 +387,7 @@
     double maxh = 100.0 / br.height() / m_keyframeFactor;
     double newval = (br.bottom() - value) * maxh;
     kDebug() << "Rect: " << br << "/ SCENE: " << sceneBoundingRect() << ", VALUE: " << value << ", MAX: " << maxh << ", NEWVAL: " << newval;
-    int newpos = (int) pos.frames(m_fps) ;
+	int newpos = (int) pos.frames(qAbs(m_fps)) ;
     m_keyframes[newpos] = newval;
     m_selectedKeyframe = newpos;
     update();
Index: src/clipitem.cpp
===================================================================
--- src/clipitem.cpp	(revision 3600)
+++ src/clipitem.cpp	(working copy)
@@ -67,7 +67,7 @@
     if (m_speed == 1.0) m_clipName = clip->name();
     else {
         m_clipName = clip->name() + " - " + QString::number(m_speed * 100, 'f', 0) + '%';
-        m_cropDuration = m_cropDuration * m_speed;
+		m_cropDuration = m_cropDuration * qAbs(m_speed);
     }
     m_producer = clip->getId();
     m_clipType = clip->clipType();
@@ -1315,7 +1315,7 @@
     bool needRepaint = false;
     /*QDomDocument doc;
     doc.appendChild(doc.importNode(effect, true));
-    kDebug() << "///////  CLIP ADD EFFECT: " << doc.toString();*/
+    kDebug() << "///////  CLIP ADD EFFECT: " << doc.toString();*/
     m_effectList.append(effect);
 
     EffectsParameterList parameters;
@@ -1513,17 +1513,17 @@
 
 GenTime ClipItem::maxDuration() const
 {
-    return m_maxDuration / m_speed;
+	return m_maxDuration / qAbs(m_speed);
 }
 
 GenTime ClipItem::cropStart() const
 {
-    return m_cropStart / m_speed;
+	return m_cropStart / qAbs(m_speed);
 }
 
 GenTime ClipItem::cropDuration() const
 {
-    return m_cropDuration / m_speed;
+	return m_cropDuration / qAbs(m_speed);
 }
 
 GenTime ClipItem::endPos() const
------------------------------------------------------------------------------
Are you an open source citizen? Join us for the Open Source Bridge conference!
Portland, OR, June 17-19. Two days of sessions, one day of unconference: $250.
Need another reason to go? 24-hour hacker lounge. Register today!
http://ad.doubleclick.net/clk;215844324;13503038;v?http://opensourcebridge.org
_______________________________________________
Kdenlive-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kdenlive-devel

Reply via email to