diff --git a/app/panel/project/project.h b/app/panel/project/project.h index 82715aaf4..d2bc30341 100644 --- a/app/panel/project/project.h +++ b/app/panel/project/project.h @@ -52,6 +52,11 @@ public: ProjectViewModel* model() const; + bool SelectItem(Node *n) + { + return explorer_->SelectItem(n); + } + virtual void SelectAll() override; virtual void DeselectAll() override; diff --git a/app/panel/timeline/timeline.cpp b/app/panel/timeline/timeline.cpp index e4fd4e274..0eb45f0a4 100644 --- a/app/panel/timeline/timeline.cpp +++ b/app/panel/timeline/timeline.cpp @@ -34,7 +34,8 @@ TimelinePanel::TimelinePanel(QWidget *parent) : Retranslate(); connect(tw, &TimelineWidget::BlockSelectionChanged, this, &TimelinePanel::BlockSelectionChanged); - connect(tw, &TimelineWidget::RequestCaptureStart, this, &TimelinePanel::RequestCaptureStart ); + connect(tw, &TimelineWidget::RequestCaptureStart, this, &TimelinePanel::RequestCaptureStart); + connect(tw, &TimelineWidget::RevealViewerInProject, this, &TimelinePanel::RevealViewerInProject); } void TimelinePanel::SplitAtPlayhead() diff --git a/app/panel/timeline/timeline.h b/app/panel/timeline/timeline.h index 9e40b232d..34b926bfd 100644 --- a/app/panel/timeline/timeline.h +++ b/app/panel/timeline/timeline.h @@ -114,6 +114,8 @@ signals: void RequestCaptureStart(const TimeRange &time, const Track::Reference &track); + void RevealViewerInProject(ViewerOutput *r); + }; } diff --git a/app/widget/projectexplorer/projectexplorer.cpp b/app/widget/projectexplorer/projectexplorer.cpp index 4482ac8d7..5242a2f47 100644 --- a/app/widget/projectexplorer/projectexplorer.cpp +++ b/app/widget/projectexplorer/projectexplorer.cpp @@ -97,6 +97,8 @@ ProjectExplorer::ProjectExplorer(QWidget *parent) : connect(tree_view_, &ProjectExplorerTreeView::customContextMenuRequested, this, &ProjectExplorer::ShowContextMenu); connect(list_view_, &ProjectExplorerListView::customContextMenuRequested, this, &ProjectExplorer::ShowContextMenu); connect(icon_view_, &ProjectExplorerIconView::customContextMenuRequested, this, &ProjectExplorer::ShowContextMenu); + + UpdateNavBarText(); } const ProjectToolbar::ViewType &ProjectExplorer::view_type() const @@ -151,13 +153,7 @@ void ProjectExplorer::BrowseToFolder(const QModelIndex &index) list_view_->setRootIndex(index); // Set navbar text to folder's name - if (index.isValid()) { - Folder* f = static_cast(sort_model_.mapToSource(index).internalPointer()); - nav_bar_->set_text(f->GetLabel()); - } else { - // Or set it to an empty string if the index is valid (which means we're browsing to the root directory) - nav_bar_->set_text(QString()); - } + UpdateNavBarText(); // Set directory up enabled button based on whether we're in root or not nav_bar_->set_dir_up_enabled(index.isValid()); @@ -246,6 +242,21 @@ QString ProjectExplorer::GetHumanReadableNodeName(Node *node) } } +void ProjectExplorer::UpdateNavBarText() +{ + QString absolute; + + Folder* f = static_cast(sort_model_.mapToSource(list_view_->rootIndex()).internalPointer()); + while (f && f != project()->root()) { + absolute.prepend(QStringLiteral("%1 / ").arg(f->GetLabel())); + f = f->folder(); + } + + absolute.prepend(QStringLiteral("/ ")); + + nav_bar_->set_text(absolute); +} + QAbstractItemView *ProjectExplorer::CurrentView() const { return static_cast(stacked_widget_->currentWidget()); @@ -667,4 +678,32 @@ void ProjectExplorer::DeleteSelected() } } +bool ProjectExplorer::SelectItem(Node *n) +{ + DeselectAll(); + + QModelIndex index = model_.CreateIndexFromItem(n); + + if (index.isValid()) { + index = sort_model_.mapFromSource(index); + + QModelIndex parent = index.parent(); + if (view_type() == ProjectToolbar::TreeView) { + // Expand all folders until this index is visible + while (parent.isValid()) { + tree_view_->expand(parent); + parent = parent.parent(); + } + } else { + BrowseToFolder(parent); + } + + CurrentView()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); + + return true; + } + + return false; +} + } diff --git a/app/widget/projectexplorer/projectexplorer.h b/app/widget/projectexplorer/projectexplorer.h index 83010ea94..fa145112b 100644 --- a/app/widget/projectexplorer/projectexplorer.h +++ b/app/widget/projectexplorer/projectexplorer.h @@ -85,6 +85,8 @@ public: void DeleteSelected(); + bool SelectItem(Node *n); + public slots: void set_view_type(ProjectToolbar::ViewType type); @@ -138,6 +140,8 @@ private: static QString GetHumanReadableNodeName(Node* node); + void UpdateNavBarText(); + /** * @brief Get the currently active QAbstractItemView */ diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 58629b2c2..eba333b85 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -1071,6 +1071,14 @@ void TimelineWidget::ShowContextMenu() menu.addSeparator(); + if (ClipBlock *clip = dynamic_cast(selected.first())) { + if (clip->connected_viewer()) { + QAction *reveal_in_project = menu.addAction(tr("Reveal in Project")); + reveal_in_project->setData(reinterpret_cast(clip->connected_viewer())); + connect(reveal_in_project, &QAction::triggered, this, &TimelineWidget::RevealInProject); + } + } + QAction* properties_action = menu.addAction(tr("Properties")); connect(properties_action, &QAction::triggered, this, &TimelineWidget::ShowSpeedDurationDialogForSelectedClips); } @@ -1215,6 +1223,15 @@ void TimelineWidget::SignalBlockSelectionChange() signal_block_change_timer_->start(); } +void TimelineWidget::RevealInProject() +{ + QAction *a = static_cast(sender()); + + ViewerOutput *item_to_reveal = reinterpret_cast(a->data().value()); + + emit RevealViewerInProject(item_to_reveal); +} + void TimelineWidget::AddGhost(TimelineViewGhostItem *ghost) { ghost_items_.append(ghost); diff --git a/app/widget/timelinewidget/timelinewidget.h b/app/widget/timelinewidget/timelinewidget.h index c23e7093f..a0b9afaaa 100644 --- a/app/widget/timelinewidget/timelinewidget.h +++ b/app/widget/timelinewidget/timelinewidget.h @@ -269,6 +269,8 @@ signals: void RequestCaptureStart(const TimeRange &time, const Track::Reference &track); + void RevealViewerInProject(ViewerOutput *r); + protected: virtual void resizeEvent(QResizeEvent *event) override; @@ -410,6 +412,8 @@ private slots: void SignalBlockSelectionChange(); + void RevealInProject(); + }; } diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index 5a5fc6693..6e02ffc07 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -479,6 +479,15 @@ void MainWindow::ShowWelcomeDialog() } } +void MainWindow::RevealViewerInProject(ViewerOutput *r) +{ + foreach (ProjectPanel *p, project_panels_) { + if (p->project() == r->project() && p->SelectItem(r)) { + break; + } + } +} + #ifdef Q_OS_LINUX void MainWindow::ShowNouveauWarning() { @@ -557,6 +566,7 @@ TimelinePanel* MainWindow::AppendTimelinePanel() connect(panel, &TimelinePanel::TimeChanged, sequence_viewer_panel_, &SequenceViewerPanel::SetTime); connect(panel, &TimelinePanel::RequestCaptureStart, sequence_viewer_panel_, &SequenceViewerPanel::StartCapture); connect(panel, &TimelinePanel::BlockSelectionChanged, this, &MainWindow::TimelinePanelSelectionChanged); + connect(panel, &TimelinePanel::RevealViewerInProject, this, &MainWindow::RevealViewerInProject); connect(param_panel_, &ParamPanel::TimeChanged, panel, &TimelinePanel::SetTime); connect(curve_panel_, &ParamPanel::TimeChanged, panel, &TimelinePanel::SetTime); connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, panel, &TimelinePanel::SetTime); diff --git a/app/window/mainwindow/mainwindow.h b/app/window/mainwindow/mainwindow.h index e027e08e6..364d3f7a7 100644 --- a/app/window/mainwindow/mainwindow.h +++ b/app/window/mainwindow/mainwindow.h @@ -195,6 +195,8 @@ private slots: void ShowWelcomeDialog(); + void RevealViewerInProject(ViewerOutput *r); + }; }