diff --git a/app/core.cpp b/app/core.cpp index c22a6c9c6..37471e1f8 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -116,6 +116,10 @@ void Core::Start() // Set up the index manager for renderers IndexManager::CreateInstance(); + // Reset config (Config sets to default on construction already, but we do it again here as a workaround that fixes + // the fact that some of the config paths set by default rely on the app name having been set (in main()) + Config::Current().SetDefaults(); + // Load application config Config::Load(); diff --git a/app/node/output/track/track.cpp b/app/node/output/track/track.cpp index 7b432013c..32fc313c0 100644 --- a/app/node/output/track/track.cpp +++ b/app/node/output/track/track.cpp @@ -450,8 +450,13 @@ void TrackOutput::UpdateInOutFrom(int index) // Update track length if (new_track_length != track_length_) { + rational old_track_length = track_length_; + track_length_ = new_track_length; emit TrackLengthChanged(); + + InvalidateCache(qMin(old_track_length, new_track_length), + qMax(old_track_length, new_track_length)); } } diff --git a/app/panel/panelmanager.cpp b/app/panel/panelmanager.cpp index 224f629ba..a76d65093 100644 --- a/app/panel/panelmanager.cpp +++ b/app/panel/panelmanager.cpp @@ -150,4 +150,15 @@ void PanelManager::SetPanelsLocked(bool locked) locked_ = locked; } +void PanelManager::PanelDestroyed() +{ + PanelWidget* panel = static_cast(sender()); + + focus_history_.removeOne(panel); + + if (last_focused_panel_ == panel) { + last_focused_panel_ = focus_history_.isEmpty() ? nullptr : focus_history_.first(); + } +} + OLIVE_NAMESPACE_EXIT diff --git a/app/panel/panelmanager.h b/app/panel/panelmanager.h index 8264cb48b..7acba73e3 100644 --- a/app/panel/panelmanager.h +++ b/app/panel/panelmanager.h @@ -162,6 +162,12 @@ private: */ PanelWidget* last_focused_panel_; +private slots: + /** + * @brief Processing if a panel gets deleted + */ + void PanelDestroyed(); + }; template @@ -171,6 +177,9 @@ T *PanelManager::CreatePanel(QWidget *parent) panel->SetMovementLocked(locked_); + // Connect destroy signal so we can remove it from focus history + connect(panel, &PanelWidget::destroyed, this, &PanelManager::PanelDestroyed); + // Add panel to the bottom of the focus history focus_history_.append(panel); diff --git a/app/panel/timebased/timebased.cpp b/app/panel/timebased/timebased.cpp index fd3957e2c..c2cb4a9eb 100644 --- a/app/panel/timebased/timebased.cpp +++ b/app/panel/timebased/timebased.cpp @@ -122,15 +122,16 @@ void TimeBasedPanel::ConnectViewerNode(ViewerOutput *node) { if (widget_->GetConnectedNode()) { disconnect(widget_->GetConnectedNode(), &ViewerOutput::MediaNameChanged, this, &TimeBasedPanel::SetSubtitle); - Retranslate(); } widget_->ConnectViewerNode(node); if (node) { connect(node, &ViewerOutput::MediaNameChanged, this, &TimeBasedPanel::SetSubtitle); - SetSubtitle(node->media_name()); } + + // Update strings + Retranslate(); } void TimeBasedPanel::SetTimeBasedWidget(TimeBasedWidget *widget) @@ -152,7 +153,9 @@ void TimeBasedPanel::SetTimeBasedWidget(TimeBasedWidget *widget) void TimeBasedPanel::Retranslate() { - if (!GetTimeBasedWidget()->GetConnectedNode()) { + if (GetTimeBasedWidget()->GetConnectedNode()) { + SetSubtitle(GetTimeBasedWidget()->GetConnectedNode()->media_name()); + } else { SetSubtitle(tr("(none)")); } } diff --git a/app/panel/timeline/timeline.cpp b/app/panel/timeline/timeline.cpp index 52b859434..8e4c00159 100644 --- a/app/panel/timeline/timeline.cpp +++ b/app/panel/timeline/timeline.cpp @@ -26,7 +26,8 @@ OLIVE_NAMESPACE_ENTER TimelinePanel::TimelinePanel(QWidget *parent) : - TimeBasedPanel(parent) + TimeBasedPanel(parent), + signal_instead_of_close_(false) { // FIXME: This won't work if there's ever more than one of this panel setObjectName("TimelinePanel"); @@ -152,6 +153,11 @@ void TimelinePanel::OverwriteFootageAtPlayhead(const QList &footage) static_cast(GetTimeBasedWidget())->OverwriteFootageAtPlayhead(footage); } +void TimelinePanel::SetSignalInsteadOfClose(bool e) +{ + signal_instead_of_close_ = e; +} + void TimelinePanel::Retranslate() { TimeBasedPanel::Retranslate(); @@ -159,4 +165,14 @@ void TimelinePanel::Retranslate() SetTitle(tr("Timeline")); } +void TimelinePanel::closeEvent(QCloseEvent *event) +{ + if (signal_instead_of_close_) { + event->ignore(); + emit CloseRequested(); + } else { + PanelWidget::closeEvent(event); + } +} + OLIVE_NAMESPACE_EXIT diff --git a/app/panel/timeline/timeline.h b/app/panel/timeline/timeline.h index 70641c2c2..391a1279d 100644 --- a/app/panel/timeline/timeline.h +++ b/app/panel/timeline/timeline.h @@ -77,12 +77,21 @@ public: void OverwriteFootageAtPlayhead(const QList &footage); + void SetSignalInsteadOfClose(bool e); + protected: virtual void Retranslate() override; + virtual void closeEvent(QCloseEvent* event) override; + signals: void SelectionChanged(const QList& selected_blocks); + void CloseRequested(); + +private: + bool signal_instead_of_close_; + }; OLIVE_NAMESPACE_EXIT diff --git a/app/widget/projectexplorer/projectexplorer.cpp b/app/widget/projectexplorer/projectexplorer.cpp index 5b519396d..286925665 100644 --- a/app/widget/projectexplorer/projectexplorer.cpp +++ b/app/widget/projectexplorer/projectexplorer.cpp @@ -32,6 +32,7 @@ #include "dialog/footageproperties/footageproperties.h" #include "dialog/sequence/sequence.h" #include "widget/menu/menu.h" +#include "window/mainwindow/mainwindow.h" OLIVE_NAMESPACE_ENTER @@ -422,6 +423,15 @@ void ProjectExplorer::DeleteSelected() foreach (Item* item, selected) { ItemPtr item_ptr = item->get_shared_ptr(); + // If this is a sequence, close it + if (item_ptr->type() == Item::kSequence) { + Sequence* s = static_cast(item_ptr.get()); + + if (Core::instance()->main_window()->IsSequenceOpen(s)) { + Core::instance()->main_window()->CloseSequence(s); + } + } + new ProjectViewModel::RemoveItemCommand(&model_, item_ptr, command); } diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index 4d118687b..96500c42d 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -144,26 +144,33 @@ void MainWindow::OpenSequence(Sequence *sequence) panel->ConnectViewerNode(sequence->viewer_output()); - TimelineFocused(panel); + TimelineFocused(sequence->viewer_output()); } void MainWindow::CloseSequence(Sequence *sequence) { - for (int i=0;i copy = timeline_panels_; - if (tl->GetConnectedViewer() == sequence->viewer_output()) { - tl->ConnectViewerNode(nullptr); - - if (timeline_panels_.size() > 1) { - delete tl; - timeline_panels_.removeAt(i); - i--; - } + foreach (TimelinePanel* tp, copy) { + if (tp->GetConnectedViewer() == sequence->viewer_output()) { + RemoveTimelinePanel(tp); } } } +bool MainWindow::IsSequenceOpen(Sequence *sequence) const +{ + foreach (TimelinePanel* tp, timeline_panels_) { + if (tp->GetConnectedViewer() == sequence->viewer_output()) { + return true; + } + } + + return false; +} + #ifdef Q_OS_WINDOWS void MainWindow::SetTaskbarButtonState(TBPFLAG flags) { @@ -305,6 +312,11 @@ void MainWindow::UpdateTitle() } } +void MainWindow::TimelineCloseRequested() +{ + RemoveTimelinePanel(static_cast(sender())); +} + TimelinePanel* MainWindow::AppendTimelinePanel() { TimelinePanel* panel = PanelManager::instance()->CreatePanel(this);; @@ -321,6 +333,10 @@ TimelinePanel* MainWindow::AppendTimelinePanel() timeline_panels_.append(panel); + // Let us handle the panel closing rather than the panel itself + panel->SetSignalInsteadOfClose(true); + connect(panel, &TimelinePanel::CloseRequested, this, &MainWindow::TimelineCloseRequested); + connect(panel, &TimelinePanel::TimeChanged, param_panel_, &ParamPanel::SetTime); connect(panel, &TimelinePanel::TimeChanged, sequence_viewer_panel_, &SequenceViewerPanel::SetTime); connect(panel, &TimelinePanel::TimeChanged, curve_panel_, &CurvePanel::SetTime); @@ -336,14 +352,28 @@ TimelinePanel* MainWindow::AppendTimelinePanel() return panel; } -void MainWindow::TimelineFocused(TimelinePanel* panel) +void MainWindow::RemoveTimelinePanel(TimelinePanel *panel) { - sequence_viewer_panel_->ConnectViewerNode(panel->GetConnectedViewer()); + // Stop showing this timeline in the viewer + TimelineFocused(nullptr); + + if (timeline_panels_.size() == 1) { + // Leave our single remaining timeline panel open + panel->ConnectViewerNode(nullptr); + } else { + timeline_panels_.removeOne(panel); + panel->deleteLater(); + } +} + +void MainWindow::TimelineFocused(ViewerOutput* viewer) +{ + sequence_viewer_panel_->ConnectViewerNode(viewer); Sequence* seq = nullptr; - if (panel->GetConnectedViewer()) { - seq = static_cast(panel->GetConnectedViewer()->parent()); + if (viewer) { + seq = static_cast(viewer->parent()); } node_panel_->SetGraph(seq); @@ -354,7 +384,7 @@ void MainWindow::FocusedPanelChanged(PanelWidget *panel) TimelinePanel* timeline = dynamic_cast(panel); if (timeline) { - TimelineFocused(timeline); + TimelineFocused(timeline->GetConnectedViewer()); } } diff --git a/app/window/mainwindow/mainwindow.h b/app/window/mainwindow/mainwindow.h index c3b2e69c9..716f17a56 100644 --- a/app/window/mainwindow/mainwindow.h +++ b/app/window/mainwindow/mainwindow.h @@ -57,6 +57,8 @@ public: void CloseSequence(Sequence* sequence); + bool IsSequenceOpen(Sequence* sequence) const; + #ifdef Q_OS_WINDOWS void SetTaskbarButtonState(TBPFLAG flags); @@ -80,7 +82,9 @@ protected: private: TimelinePanel* AppendTimelinePanel(); - void TimelineFocused(TimelinePanel *panel); + void RemoveTimelinePanel(TimelinePanel *panel); + + void TimelineFocused(ViewerOutput *viewer); QByteArray premaximized_state_; @@ -108,6 +112,8 @@ private slots: void UpdateTitle(); + void TimelineCloseRequested(); + }; OLIVE_NAMESPACE_EXIT