]> git.sesse.net Git - kdenlive/blobdiff - src/mainwindow.cpp
- Fix drop frame timecode format. [1]
[kdenlive] / src / mainwindow.cpp
index 84a74679bf9758b9cf77adef707b036920e96b52..38b4d51524a9a3c6d164f308b0b7424244160319 100644 (file)
@@ -244,10 +244,15 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent
     tabifyDockWidget(m_clipMonitorDock, m_recMonitorDock);
 #endif
     setCentralWidget(m_timelineArea);
-
-
     setupGUI();
 
+    // Find QDockWidget tab bars and show / hide widget title bars on right click
+    QList <QTabBar *> tabs = findChildren<QTabBar *>();
+    for (int i = 0; i < tabs.count(); i++) {
+        tabs.at(i)->setContextMenuPolicy(Qt::CustomContextMenu);
+        connect(tabs.at(i), SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(slotSwitchTitles()));
+    }
+
     /*ScriptingPart* sp = new ScriptingPart(this, QStringList());
     guiFactory()->addClient(sp);*/
 
@@ -257,7 +262,12 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent
 
     m_projectMonitor->setupMenu(static_cast<QMenu*>(factory()->container("monitor_go", this)), m_playZone, m_loopZone);
     m_clipMonitor->setupMenu(static_cast<QMenu*>(factory()->container("monitor_go", this)), m_playZone, m_loopZone, static_cast<QMenu*>(factory()->container("marker_menu", this)));
-    m_projectList->setupGeneratorMenu(static_cast<QMenu*>(factory()->container("generators", this)), static_cast<QMenu*>(factory()->container("transcoders", this)));
+
+    QMenu *clipInTimeline = static_cast<QMenu*>(factory()->container("clip_in_timeline", this));
+    clipInTimeline->setIcon(KIcon("go-jump"));
+    m_projectList->setupGeneratorMenu(static_cast<QMenu*>(factory()->container("generators", this)),
+                                      static_cast<QMenu*>(factory()->container("transcoders", this)),
+                                      clipInTimeline);
 
     QAction *action;
     // build themes menus
@@ -396,6 +406,8 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent
     m_timelineContextMenu->addAction(actionCollection()->action("delete_space"));
     m_timelineContextMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Paste)));
 
+    m_timelineContextClipMenu->addAction(actionCollection()->action("clip_in_project_tree"));
+    m_timelineContextClipMenu->addAction(actionCollection()->action("edit_item_duration"));
     m_timelineContextClipMenu->addAction(actionCollection()->action("delete_timeline_clip"));
     m_timelineContextClipMenu->addAction(actionCollection()->action("group_clip"));
     m_timelineContextClipMenu->addAction(actionCollection()->action("ungroup_clip"));
@@ -412,6 +424,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent
     //TODO: re-enable custom effects menu when it is implemented
     m_timelineContextClipMenu->addMenu(m_customEffectsMenu);
 
+    m_timelineContextTransitionMenu->addAction(actionCollection()->action("edit_item_duration"));
     m_timelineContextTransitionMenu->addAction(actionCollection()->action("delete_timeline_clip"));
     m_timelineContextTransitionMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Copy)));
 
@@ -1134,6 +1147,14 @@ void MainWindow::setupActions()
     ungroupClip->setData("ungroup_clip");
     connect(ungroupClip, SIGNAL(triggered(bool)), this, SLOT(slotUnGroupClips()));
 
+    KAction* editItemDuration = new KAction(KIcon("measure"), i18n("Edit Duration"), this);
+    collection->addAction("edit_item_duration", editItemDuration);
+    connect(editItemDuration, SIGNAL(triggered(bool)), this, SLOT(slotEditItemDuration()));
+
+    KAction* clipInProjectTree = new KAction(KIcon("go-jump-definition"), i18n("Clip in Project Tree"), this);
+    collection->addAction("clip_in_project_tree", clipInProjectTree);
+    connect(clipInProjectTree, SIGNAL(triggered(bool)), this, SLOT(slotClipInProjectTree()));
+
     KAction* insertOvertwrite = new KAction(KIcon(), i18n("Insert Clip Zone in Timeline (Overwrite)"), this);
     insertOvertwrite->setShortcut(Qt::Key_V);
     collection->addAction("overwrite_to_in_point", insertOvertwrite);
@@ -1263,6 +1284,13 @@ void MainWindow::setupActions()
     showTimeline->setChecked(true);
     connect(showTimeline, SIGNAL(triggered(bool)), this, SLOT(slotShowTimeline(bool)));
 
+    QAction *showTitleBar = new KAction(i18n("Show Title Bars"), this);
+    collection->addAction("show_titlebars", showTitleBar);
+    showTitleBar->setCheckable(true);
+    connect(showTitleBar, SIGNAL(triggered(bool)), this, SLOT(slotShowTitleBars(bool)));
+    showTitleBar->setChecked(KdenliveSettings::showtitlebars());
+    slotShowTitleBars(KdenliveSettings::showtitlebars());
+
     /*QAction *maxCurrent = new KAction(i18n("Maximize Current Widget"), this);
     collection->addAction("maximize_current", maxCurrent);
     maxCurrent->setCheckable(true);
@@ -1879,6 +1907,7 @@ void MainWindow::slotRenderProject()
             m_renderWidget->setRenderProfile(m_activeDocument->getDocumentProperty("renderdestination"), m_activeDocument->getDocumentProperty("rendercategory"), m_activeDocument->getDocumentProperty("renderprofile"), m_activeDocument->getDocumentProperty("renderurl"));
         }
     }
+    slotCheckRenderStatus();
     /*TrackView *currentTab = (TrackView *) m_timelineArea->currentWidget();
     if (currentTab) m_renderWidget->setTimeline(currentTab);
     m_renderWidget->setDocument(m_activeDocument);*/
@@ -1886,6 +1915,12 @@ void MainWindow::slotRenderProject()
     m_renderWidget->showNormal();
 }
 
+void MainWindow::slotCheckRenderStatus()
+{
+    // Make sure there are no missing clips
+    if (m_renderWidget) m_renderWidget->missingClips(m_projectList->hasMissingClips());
+}
+
 void MainWindow::setRenderingProgress(const QString &url, int progress)
 {
     if (m_renderWidget) m_renderWidget->setRenderJob(url, progress);
@@ -1983,6 +2018,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
             disconnect(m_activeTimeline, SIGNAL(zoneMoved(int, int)), this, SLOT(slotZoneMoved(int, int)));
             disconnect(m_projectList, SIGNAL(loadingIsOver()), m_activeTimeline->projectView(), SLOT(slotUpdateAllThumbs()));
             disconnect(m_projectList, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int)));
+            disconnect(m_projectList, SIGNAL(updateRenderStatus()), this, SLOT(slotCheckRenderStatus()));
             disconnect(m_projectList, SIGNAL(clipNeedsReload(const QString&, bool)), m_activeTimeline->projectView(), SLOT(slotUpdateClip(const QString &, bool)));
             m_effectStack->clear();
         }
@@ -2004,6 +2040,8 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
     connect(m_projectList, SIGNAL(projectModified()), doc, SLOT(setModified()));
     connect(m_projectList, SIGNAL(clipNameChanged(const QString, const QString)), trackView->projectView(), SLOT(clipNameChanged(const QString, const QString)));
 
+    connect(m_projectList, SIGNAL(findInTimeline(const QString&)), this, SLOT(slotClipInTimeline(const QString&)));
+
 
     connect(trackView, SIGNAL(cursorMoved()), m_projectMonitor, SLOT(activateMonitor()));
     connect(trackView, SIGNAL(insertTrack(int)), this, SLOT(slotInsertTrack(int)));
@@ -2059,11 +2097,13 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
     connect(trackView, SIGNAL(zoneMoved(int, int)), this, SLOT(slotZoneMoved(int, int)));
     connect(m_projectList, SIGNAL(loadingIsOver()), trackView->projectView(), SLOT(slotUpdateAllThumbs()));
     connect(m_projectList, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int)));
+    connect(m_projectList, SIGNAL(updateRenderStatus()), this, SLOT(slotCheckRenderStatus()));
 
 
     trackView->projectView()->setContextMenu(m_timelineContextMenu, m_timelineContextClipMenu, m_timelineContextTransitionMenu, m_clipTypeGroup, (QMenu*)(factory()->container("marker_menu", this)));
     m_activeTimeline = trackView;
     if (m_renderWidget) {
+        slotCheckRenderStatus();
         m_renderWidget->setProfile(doc->mltProfile());
         m_renderWidget->setGuides(doc->guidesXml(), doc->projectDuration());
         m_renderWidget->setDocumentPath(doc->projectFolder().path(KUrl::AddTrailingSlash));
@@ -2347,6 +2387,8 @@ void MainWindow::slotInsertTrack(int ix)
     m_projectMonitor->activateMonitor();
     if (m_activeTimeline)
         m_activeTimeline->projectView()->slotInsertTrack(ix);
+    if (m_activeDocument)
+        m_transitionConfig->updateProjectFormat(m_activeDocument->mltProfile(), m_activeDocument->timecode(), m_activeDocument->tracksList());
 }
 
 void MainWindow::slotDeleteTrack(int ix)
@@ -2354,6 +2396,8 @@ void MainWindow::slotDeleteTrack(int ix)
     m_projectMonitor->activateMonitor();
     if (m_activeTimeline)
         m_activeTimeline->projectView()->slotDeleteTrack(ix);
+    if (m_activeDocument)
+        m_transitionConfig->updateProjectFormat(m_activeDocument->mltProfile(), m_activeDocument->timecode(), m_activeDocument->tracksList());
 }
 
 void MainWindow::slotChangeTrack(int ix)
@@ -2452,6 +2496,13 @@ void MainWindow::slotUnGroupClips()
     }
 }
 
+void MainWindow::slotEditItemDuration()
+{
+    if (m_activeTimeline) {
+        m_activeTimeline->projectView()->editItemDuration();
+    }
+}
+
 void MainWindow::slotAddProjectClip(KUrl url)
 {
     if (m_activeDocument)
@@ -2524,6 +2575,9 @@ void MainWindow::slotGotProgressInfo(const QString &message, int progress)
     if (progress >= 0) {
         if (!message.isEmpty()) m_messageLabel->setMessage(message, InformationMessage);//statusLabel->setText(message);
         m_statusProgressBar->setVisible(true);
+    } else if (progress == -2) {
+        if (!message.isEmpty()) m_messageLabel->setMessage(message, ErrorMessage);
+        m_statusProgressBar->setVisible(false);
     } else {
         m_messageLabel->setMessage(QString(), DefaultMessage);
         m_statusProgressBar->setVisible(false);
@@ -2597,13 +2651,13 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip)
         if (dia_ui->exec() == QDialog::Accepted) {
             QMap <QString, QString> newprops;
             newprops.insert("xmldata", dia_ui->xml().toString());
-            if (dia_ui->duration() != clip->duration().frames(m_activeDocument->fps()) - 1) {
+            if (dia_ui->outPoint() != clip->duration().frames(m_activeDocument->fps()) - 1) {
                 // duration changed, we need to update duration
-                newprops.insert("out", QString::number(dia_ui->duration()));
+                newprops.insert("out", QString::number(dia_ui->outPoint()));
             }
             EditClipCommand *command = new EditClipCommand(m_projectList, clip->getId(), clip->properties(), newprops, true);
             m_activeDocument->commandStack()->push(command);
-            m_activeTimeline->projectView()->slotUpdateClip(clip->getId());
+            //m_activeTimeline->projectView()->slotUpdateClip(clip->getId());
             m_activeDocument->setModified(true);
         }
         delete dia_ui;
@@ -2802,6 +2856,62 @@ void MainWindow::findTimeout()
     removeEventFilter(this);
 }
 
+void MainWindow::slotClipInTimeline(const QString &clipId)
+{
+    if (m_activeTimeline && m_activeDocument) {
+        QList<ItemInfo> matching = m_activeTimeline->projectView()->findId(clipId);
+
+        QMenu *inTimelineMenu = static_cast<QMenu*>(factory()->container("clip_in_timeline", this));
+        inTimelineMenu->clear();
+
+        QList <QAction *> actionList;
+
+        for (int i = 0; i < matching.count(); ++i) {
+            QString track = QString::number(matching.at(i).track);
+            QString start = m_activeDocument->timecode().getTimecode(matching.at(i).startPos);
+            int j = 0;
+            QAction *a = new QAction(track + ": " + start, this);
+            a->setData(QStringList() << track << start);
+            connect(a, SIGNAL(triggered()), this, SLOT(slotSelectClipInTimeline()));
+            while (j < actionList.count()) {
+                if (actionList.at(j)->text() > a->text()) break;
+                j++;
+            }
+            actionList.insert(j, a);
+
+        }
+        inTimelineMenu->addActions(actionList);
+
+        if (matching.empty())
+            inTimelineMenu->setEnabled(false);
+        else
+            inTimelineMenu->setEnabled(true);
+    }
+}
+
+void MainWindow::slotClipInProjectTree()
+{
+    if (m_activeTimeline) {
+        const QStringList &clipIds = m_activeTimeline->projectView()->selectedClips();
+        if (clipIds.isEmpty()) return;
+        m_projectListDock->raise();
+        for (int i = 0; i < clipIds.count(); i++) {
+            m_projectList->selectItemById(clipIds.at(i));
+        }
+        if (m_projectMonitor->isActive())
+            slotSwitchMonitors();
+    }
+}
+
+void MainWindow::slotSelectClipInTimeline()
+{
+    if (m_activeTimeline) {
+        QAction *action = qobject_cast<QAction *>(sender());
+        QStringList data = action->data().toStringList();
+        m_activeTimeline->projectView()->selectFound(data.at(0), data.at(1));
+    }
+}
+
 void MainWindow::keyPressEvent(QKeyEvent *ke)
 {
     if (m_findActivated) {
@@ -3289,7 +3399,7 @@ QPixmap MainWindow::createSchemePreviewIcon(const KSharedConfigPtr &config)
 
 void MainWindow::slotSwitchMonitors()
 {
-    m_monitorManager->slotSwitchMonitors(m_clipMonitor->isActive());
+    m_monitorManager->slotSwitchMonitors(!m_clipMonitor->isActive());
     if (m_projectMonitor->isActive()) m_activeTimeline->projectView()->setFocus();
     else m_projectList->focusTree();
 }
@@ -3319,5 +3429,38 @@ void MainWindow::slotDeleteProjectClips(QStringList ids, QMap<QString, QString>
 
 }
 
+void MainWindow::slotShowTitleBars(bool show)
+{
+    if (show) {
+        m_effectStackDock->setTitleBarWidget(0);
+        m_clipMonitorDock->setTitleBarWidget(0);
+        m_projectMonitorDock->setTitleBarWidget(0);
+#ifndef Q_WS_MAC
+        m_recMonitorDock->setTitleBarWidget(0);
+#endif
+        m_effectListDock->setTitleBarWidget(0);
+        m_transitionConfigDock->setTitleBarWidget(0);
+        m_projectListDock->setTitleBarWidget(0);
+        m_undoViewDock->setTitleBarWidget(0);
+    } else {
+        if (!m_effectStackDock->isFloating()) m_effectStackDock->setTitleBarWidget(new QWidget(this));
+        if (!m_clipMonitorDock->isFloating()) m_clipMonitorDock->setTitleBarWidget(new QWidget(this));
+        if (!m_projectMonitorDock->isFloating()) m_projectMonitorDock->setTitleBarWidget(new QWidget(this));
+#ifndef Q_WS_MAC
+        if (!m_recMonitorDock->isFloating()) m_recMonitorDock->setTitleBarWidget(new QWidget(this));
+#endif
+        if (!m_effectListDock->isFloating()) m_effectListDock->setTitleBarWidget(new QWidget(this));
+        if (!m_transitionConfigDock->isFloating()) m_transitionConfigDock->setTitleBarWidget(new QWidget(this));
+        if (!m_projectListDock->isFloating()) m_projectListDock->setTitleBarWidget(new QWidget(this));
+        if (!m_undoViewDock->isFloating()) m_undoViewDock->setTitleBarWidget(new QWidget(this));
+    }
+    KdenliveSettings::setShowtitlebars(show);
+}
+
+void MainWindow::slotSwitchTitles()
+{
+    slotShowTitleBars(!KdenliveSettings::showtitlebars());
+}
+
 #include "mainwindow.moc"