]> git.sesse.net Git - kdenlive/commitdiff
Spacer tool (can only add space for the moment)
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 25 Nov 2008 00:43:23 +0000 (00:43 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 25 Nov 2008 00:43:23 +0000 (00:43 +0000)
http://www.kdenlive.org/mantis/view.php?id=271

svn path=/branches/KDE4/; revision=2730

icons/hisc-action-kdenlive-spacer-tool.svgz [new file with mode: 0644]
icons/oxsc-action-kdenlive-spacer-tool.svgz [new file with mode: 0644]
src/customtrackview.cpp
src/customtrackview.h
src/definitions.h
src/kdenliveui.rc
src/mainwindow.cpp
src/mainwindow.h
src/renderer.cpp

diff --git a/icons/hisc-action-kdenlive-spacer-tool.svgz b/icons/hisc-action-kdenlive-spacer-tool.svgz
new file mode 100644 (file)
index 0000000..f329b29
Binary files /dev/null and b/icons/hisc-action-kdenlive-spacer-tool.svgz differ
diff --git a/icons/oxsc-action-kdenlive-spacer-tool.svgz b/icons/oxsc-action-kdenlive-spacer-tool.svgz
new file mode 100644 (file)
index 0000000..f582640
Binary files /dev/null and b/icons/oxsc-action-kdenlive-spacer-tool.svgz differ
index 0165af3d99eaae8cc901d922c2f745a372331837..1b980671473c182c4dbe54f963d1a2538d9ec051 100644 (file)
@@ -94,6 +94,9 @@ CustomTrackView::CustomTrackView(KdenliveDoc *doc, CustomTrackScene* projectscen
 
     KIcon razorIcon("edit-cut");
     m_razorCursor = QCursor(razorIcon.pixmap(22, 22));
+
+    KIcon spacerIcon("kdenlive-spacer-tool");
+    m_spacerCursor = QCursor(spacerIcon.pixmap(22, 22));
     verticalScrollBar()->setTracking(true);
     connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(slotRefreshGuides()));
     connect(&m_scrollTimer, SIGNAL(timeout()), this, SLOT(slotCheckMouseScrolling()));
@@ -223,8 +226,8 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) {
     emit mousePosition(mappedXPos);
     if (event->buttons() & Qt::MidButton) return;
     if (event->buttons() != Qt::NoButton) {
+        bool move = (event->pos() - m_clickEvent).manhattanLength() >= QApplication::startDragDistance();
         if (m_dragItem && m_tool == SELECTTOOL) {
-            bool move = (event->pos() - m_clickEvent).manhattanLength() >= QApplication::startDragDistance();
             if (m_operationMode == MOVE && move) {
                 QGraphicsView::mouseMoveEvent(event);
                 // If mouse is at a border of the view, scroll
@@ -267,6 +270,11 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) {
             m_visualTip = NULL;
             QGraphicsView::mouseMoveEvent(event);
             return;
+        } else if (m_operationMode == SPACER && move) {
+            // spacer tool
+            int mappedClick = (int)(mapToScene(m_clickEvent).x() + 0.5);
+            if (mappedXPos > mappedClick)
+                m_selectionGroup->setPos(mappedXPos + (m_spacerStart - mappedClick) , m_selectionGroup->pos().y());
         }
     }
 
@@ -274,6 +282,9 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) {
         setCursor(m_razorCursor);
         //QGraphicsView::mouseMoveEvent(event);
         //return;
+    } else if (m_tool == SPACERTOOL) {
+        setCursor(m_spacerCursor);
+        return;
     }
 
     QList<QGraphicsItem *> itemList = items(event->pos());
@@ -568,16 +579,40 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) {
     }
 
     // No item under click
-    if (m_dragItem == NULL) {
+    if (m_dragItem == NULL || m_tool == SPACERTOOL) {
         if (m_selectionGroup) {
             scene()->destroyItemGroup(m_selectionGroup);
             m_selectionGroup = NULL;
         }
         setCursor(Qt::ArrowCursor);
         m_scene->clearSelection();
-        setCursorPos((int)(mapToScene(event->x(), 0).x()));
         event->accept();
         emit clipItemSelected(NULL);
+        if (m_tool == SPACERTOOL) {
+            // Select all items on track after click position
+            int track = (int)(mapToScene(m_clickEvent).y() / m_tracksHeight);
+            QList<QGraphicsItem *> selection = items(event->pos().x(), track * m_tracksHeight + 1, sceneRect().width() - event->pos().x(), m_tracksHeight - 2);
+            m_selectionGroup = new AbstractGroupItem(m_document->fps());
+            scene()->addItem(m_selectionGroup);
+            m_spacerStart = -1;
+            int itemStart;
+            for (int i = 0; i < selection.count(); i++) {
+                if (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET) {
+                    m_selectionGroup->addToGroup(selection.at(i));
+                    AbstractClipItem *item = static_cast <AbstractClipItem *>(selection.at(i));
+                    itemStart = item->startPos().frames(m_document->fps());
+                    if (m_spacerStart == -1 || itemStart < m_spacerStart)
+                        m_spacerStart = itemStart;
+                }
+            }
+            QPointF top = m_selectionGroup->boundingRect().topLeft();
+            const int width = m_selectionGroup->boundingRect().width();
+            const int height = m_selectionGroup->boundingRect().height();
+            m_selectionGroup->setPos(top);
+            m_selectionGroup->translate(-top.x(), -top.y() + 1);
+            //kDebug()<<"// SPACER START GRP: "<<m_spacerStart;
+            m_operationMode = SPACER;
+        } else setCursorPos((int)(mapToScene(event->x(), 0).x()));
         return;
     }
 
@@ -1315,11 +1350,29 @@ void CustomTrackView::insertSpace(const GenTime &pos, int track, const GenTime d
     QList<QGraphicsItem *> itemList;
     if (track == -1) itemList = items();
     else itemList = scene()->items(pos.frames(m_document->fps()) , track * m_tracksHeight + m_tracksHeight / 2, sceneRect().width() - pos.frames(m_document->fps()), m_tracksHeight / 4);
+    if (m_selectionGroup) {
+        scene()->destroyItemGroup(m_selectionGroup);
+        m_selectionGroup = NULL;
+    }
+    m_selectionGroup = new AbstractGroupItem(m_document->fps());
+    scene()->addItem(m_selectionGroup);
     for (int i = 0; i < itemList.count(); i++) {
-        if (itemList.at(i)->type() == AVWIDGET) {
-            ClipItem *item = (ClipItem *)itemList.at(i);
-            if (item->endPos() > pos) item->moveBy(diff, 0);
-        }
+        if (itemList.at(i)->type() == AVWIDGET || itemList.at(i)->type() == TRANSITIONWIDGET) {
+            /*AbstractClipItem *item = static_cast <AbstractClipItem *> (itemList.at(i));
+            if (item->endPos() > pos)*/
+            m_selectionGroup->addToGroup(itemList.at(i));
+            //item->moveBy(diff, 0);
+        }
+    }
+    QPointF top = m_selectionGroup->boundingRect().topLeft();
+    const int width = m_selectionGroup->boundingRect().width();
+    const int height = m_selectionGroup->boundingRect().height();
+    m_selectionGroup->setPos(top);
+    m_selectionGroup->translate(-top.x(), -top.y() + 1);
+    m_selectionGroup->moveBy(diff, 0);
+    if (m_selectionGroup) {
+        scene()->destroyItemGroup(m_selectionGroup);
+        m_selectionGroup = NULL;
     }
     if (track != -1) track = m_scene->m_tracksList.count() - track;
     m_document->renderer()->mltInsertSpace(pos, track, duration, add);
@@ -1394,7 +1447,22 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
         m_dragGuide = NULL;
         m_dragItem = NULL;
         return;
+    } else if (m_operationMode == SPACER) {
+        int endClick = (int)(mapToScene(event->pos()).x() + 0.5);
+        int mappedClick = (int)(mapToScene(m_clickEvent).x() + 0.5);
+        int diff = endClick - mappedClick;
+        int track = (int)(mapToScene(m_clickEvent).y() / m_tracksHeight);
+        InsertSpaceCommand *command = new InsertSpaceCommand(this, GenTime(mappedClick, m_document->fps()), track, GenTime(diff, m_document->fps()), false);
+        m_commandStack->push(command);
+        track = m_scene->m_tracksList.count() - track;
+        m_document->renderer()->mltInsertSpace(GenTime(mappedClick, m_document->fps()), track, GenTime(diff, m_document->fps()), true);
+        if (m_selectionGroup) {
+            scene()->destroyItemGroup(m_selectionGroup);
+            m_selectionGroup = NULL;
+        }
+        m_operationMode = NONE;
     }
+
     if (m_dragItem == NULL && m_selectionGroup == NULL) {
         emit transitionItemSelected(NULL);
         return;
index 79a0510b0d7b36151ccafe423bdfcd3a942bcf30..6b98865a8bdcb5ac0d1dfa1c602bc9fd746ab2f1 100644 (file)
@@ -149,6 +149,7 @@ private:
     uint m_selectedTrack;
     int m_projectDuration;
     int m_cursorPos;
+    int m_spacerStart;
     KdenliveDoc *m_document;
     CustomTrackScene *m_scene;
     QGraphicsLineItem *m_cursorLine;
@@ -187,6 +188,7 @@ private:
     int m_findIndex;
     PROJECTTOOL m_tool;
     QCursor m_razorCursor;
+    QCursor m_spacerCursor;
     /** list containing items currently copied in the timeline */
     QList<AbstractClipItem *> m_copiedItems;
     /** Used to get the point in timeline where a context menu was opened */
index 9ee7be59da5e64bf8c4cd8c9b106ab1651c4cb05..b99863f40805e2a076e8a827caaf5150a478b1b7 100644 (file)
 const int FRAME_SIZE = 90;
 const int MAXCLIPDURATION = 15000;
 
-enum OPERATIONTYPE { NONE = 0, MOVE = 1, RESIZESTART = 2, RESIZEEND = 3, FADEIN = 4, FADEOUT = 5, TRANSITIONSTART = 6, TRANSITIONEND = 7, MOVEGUIDE = 8, KEYFRAME = 9, SEEK = 10};
+enum OPERATIONTYPE { NONE = 0, MOVE = 1, RESIZESTART = 2, RESIZEEND = 3, FADEIN = 4, FADEOUT = 5, TRANSITIONSTART = 6, TRANSITIONEND = 7, MOVEGUIDE = 8, KEYFRAME = 9, SEEK = 10, SPACER = 11};
 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  , GROUPWIDGET};
 
-enum PROJECTTOOL { SELECTTOOL = 0 , RAZORTOOL = 1 };
+enum PROJECTTOOL { SELECTTOOL = 0 , RAZORTOOL = 1 , SPACERTOOL = 2 };
 
 enum TRANSITIONTYPE {
     /** TRANSITIONTYPE: between 0-99: video trans, 100-199: video+audio trans, 200-299: audio trans */
index 4cb9365cc3b616dc78f31ee49e54fedc45a9096e..52dcb3e2e53289078cb4133d905cad18aae55020 100644 (file)
@@ -21,6 +21,7 @@
     <Menu name="tool" ><text>Tool</text>
       <Action name="select_tool" />
       <Action name="razor_tool" />
+      <Action name="spacer_tool" />
     </Menu>
 
     <Menu name="timeline" ><text>Timeline</text>
index 1e0e7db13054f7d8244de24ce137f12a4f7c5f52..3ffe22e7af2eddf1730a3893b898283851f75643 100644 (file)
@@ -542,8 +542,14 @@ void MainWindow::setupActions() {
     m_buttonRazorTool->setCheckable(true);
     m_buttonRazorTool->setChecked(false);
 
+    m_buttonSpacerTool = new KAction(KIcon("kdenlive-spacer-tool"), i18n("Spacer tool"), this);
+    toolbar->addAction(m_buttonSpacerTool);
+    m_buttonSpacerTool->setCheckable(true);
+    m_buttonSpacerTool->setChecked(false);
+
     m_toolGroup->addAction(m_buttonSelectTool);
     m_toolGroup->addAction(m_buttonRazorTool);
+    m_toolGroup->addAction(m_buttonSpacerTool);
     m_toolGroup->setExclusive(true);
     toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
 
@@ -556,6 +562,10 @@ void MainWindow::setupActions() {
     actionWidget->setMaximumWidth(24);
     actionWidget->setMinimumHeight(17);
 
+    actionWidget = toolbar->widgetForAction(m_buttonSpacerTool);
+    actionWidget->setMaximumWidth(24);
+    actionWidget->setMinimumHeight(17);
+
     toolbar->setStyleSheet(style1);
     connect(m_toolGroup, SIGNAL(triggered(QAction *)), this, SLOT(slotChangeTool(QAction *)));
 
@@ -644,6 +654,7 @@ void MainWindow::setupActions() {
 
     collection->addAction("select_tool", m_buttonSelectTool);
     collection->addAction("razor_tool", m_buttonRazorTool);
+    collection->addAction("spacer_tool", m_buttonSpacerTool);
 
     collection->addAction("show_video_thumbs", m_buttonVideoThumbs);
     collection->addAction("show_audio_thumbs", m_buttonAudioThumbs);
@@ -1661,6 +1672,7 @@ void MainWindow::slotClipEnd() {
 void MainWindow::slotChangeTool(QAction * action) {
     if (action == m_buttonSelectTool) slotSetTool(SELECTTOOL);
     else if (action == m_buttonRazorTool) slotSetTool(RAZORTOOL);
+    else if (action == m_buttonSpacerTool) slotSetTool(SPACERTOOL);
 }
 
 void MainWindow::slotSetTool(PROJECTTOOL tool) {
index 2dd854c8b0368d2f67d5283d89706aa23d2bd110..f3410dcf4dd7288d1ac7fa776d4ec1fcaa8c7815 100644 (file)
@@ -158,6 +158,7 @@ private:
     KAction *m_buttonFitZoom;
     KAction *m_buttonSelectTool;
     KAction *m_buttonRazorTool;
+    KAction *m_buttonSpacerTool;
     KAction *m_buttonSnap;
     QActionGroup *m_toolGroup;
     KAction *m_saveAction;
index 384000b0b2fbf8a9becd25170b2415c38dee92f5..9c862aa905e5cc68aa5fd1555ec4e508011f4c01 100644 (file)
@@ -1459,30 +1459,77 @@ void Render::mltInsertSpace(const GenTime pos, int track, const GenTime duration
     Mlt::Service service(parentProd.get_service());
     Mlt::Tractor tractor(service);
     mlt_service_lock(service.get_service());
+    int insertPos = pos.frames(m_fps);
+    int diff = duration.frames(m_fps) - 1;
 
     if (track != -1) {
         // insert space in one track only
         Mlt::Producer trackProducer(tractor.track(track));
         Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
-        int clipIndex = trackPlaylist.get_clip_index_at(pos.frames(m_fps));
+        int clipIndex = trackPlaylist.get_clip_index_at(insertPos);
         if (add) trackPlaylist.insert_blank(clipIndex,  duration.frames(m_fps) - 1);
         else {
             int position = trackPlaylist.clip_start(clipIndex);
-            trackPlaylist.remove_region(position, duration.frames(m_fps) - 1);
+            trackPlaylist.remove_region(position, diff);
+        }
+        // now move transitions
+        if (!add) diff = -diff;
+        mlt_service serv = m_mltProducer->parent().get_service();
+        mlt_service nextservice = mlt_service_get_producer(serv);
+        mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice);
+        QString mlt_type = mlt_properties_get(properties, "mlt_type");
+        QString resource = mlt_properties_get(properties, "mlt_service");
+
+        while (mlt_type == "transition") {
+            mlt_transition tr = (mlt_transition) nextservice;
+            int currentTrack = mlt_transition_get_b_track(tr);
+            int currentIn = (int) mlt_transition_get_in(tr);
+            int currentOut = (int) mlt_transition_get_out(tr);
+
+            if (track == currentTrack && currentOut > insertPos && resource != "mix") {
+                mlt_transition_set_in_and_out(tr, currentIn + diff, currentOut + diff);
+            }
+            nextservice = mlt_service_producer(nextservice);
+            if (nextservice == NULL) break;
+            properties = MLT_SERVICE_PROPERTIES(nextservice);
+            mlt_type = mlt_properties_get(properties, "mlt_type");
+            resource = mlt_properties_get(properties, "mlt_service");
         }
     } else {
         int trackNb = tractor.count();
         while (trackNb > 1) {
             Mlt::Producer trackProducer(tractor.track(trackNb - 1));
             Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
-            int clipIndex = trackPlaylist.get_clip_index_at(pos.frames(m_fps));
-            if (add) trackPlaylist.insert_blank(clipIndex,  duration.frames(m_fps) - 1);
+            int clipIndex = trackPlaylist.get_clip_index_at(insertPos);
+            if (add) trackPlaylist.insert_blank(clipIndex,  diff);
             else {
                 int position = trackPlaylist.clip_start(clipIndex);
-                trackPlaylist.remove_region(position, duration.frames(m_fps) - 1);
+                trackPlaylist.remove_region(position, diff);
             }
             trackNb--;
         }
+        // now move transitions
+        if (!add) diff = -diff;
+        mlt_service serv = m_mltProducer->parent().get_service();
+        mlt_service nextservice = mlt_service_get_producer(serv);
+        mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice);
+        QString mlt_type = mlt_properties_get(properties, "mlt_type");
+        QString resource = mlt_properties_get(properties, "mlt_service");
+
+        while (mlt_type == "transition") {
+            mlt_transition tr = (mlt_transition) nextservice;
+            int currentIn = (int) mlt_transition_get_in(tr);
+            int currentOut = (int) mlt_transition_get_out(tr);
+
+            if (currentOut > insertPos && resource != "mix") {
+                mlt_transition_set_in_and_out(tr, currentIn + diff, currentOut + diff);
+            }
+            nextservice = mlt_service_producer(nextservice);
+            if (nextservice == NULL) break;
+            properties = MLT_SERVICE_PROPERTIES(nextservice);
+            mlt_type = mlt_properties_get(properties, "mlt_type");
+            resource = mlt_properties_get(properties, "mlt_service");
+        }
     }
     mlt_service_unlock(service.get_service());
 }
@@ -2110,7 +2157,6 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
 }
 
 void Render::mltMoveTransition(QString type, int startTrack, int newTrack, int newTransitionTrack, GenTime oldIn, GenTime oldOut, GenTime newIn, GenTime newOut) {
-
     Mlt::Service service(m_mltProducer->parent().get_service());
     Mlt::Tractor tractor(service);
     Mlt::Field *field = tractor.field();