diff --git a/app/panel/footageviewer/footageviewer.cpp b/app/panel/footageviewer/footageviewer.cpp index 4e53b5816..2f35ea460 100644 --- a/app/panel/footageviewer/footageviewer.cpp +++ b/app/panel/footageviewer/footageviewer.cpp @@ -37,7 +37,7 @@ FootageViewerPanel::FootageViewerPanel(QWidget *parent) : Retranslate(); } -QList FootageViewerPanel::GetSelectedFootage() +QList FootageViewerPanel::GetSelectedFootage() const { return {static_cast(GetTimeBasedWidget())->GetFootage()}; } diff --git a/app/panel/footageviewer/footageviewer.h b/app/panel/footageviewer/footageviewer.h index ff632ce20..6b483ec2b 100644 --- a/app/panel/footageviewer/footageviewer.h +++ b/app/panel/footageviewer/footageviewer.h @@ -36,7 +36,7 @@ class FootageViewerPanel : public ViewerPanelBase, public FootageManagementPanel public: FootageViewerPanel(QWidget* parent); - virtual QList GetSelectedFootage() override; + virtual QList GetSelectedFootage() const override; void SetFootage(Footage* f); diff --git a/app/panel/project/footagemanagementpanel.h b/app/panel/project/footagemanagementpanel.h index 049cd3e76..02474665b 100644 --- a/app/panel/project/footagemanagementpanel.h +++ b/app/panel/project/footagemanagementpanel.h @@ -29,7 +29,7 @@ OLIVE_NAMESPACE_ENTER class FootageManagementPanel { public: - virtual QList GetSelectedFootage() = 0; + virtual QList GetSelectedFootage() const = 0; }; OLIVE_NAMESPACE_EXIT diff --git a/app/panel/project/project.cpp b/app/panel/project/project.cpp index cbf552c5f..3f00211a3 100644 --- a/app/panel/project/project.cpp +++ b/app/panel/project/project.cpp @@ -72,7 +72,7 @@ ProjectPanel::ProjectPanel(QWidget *parent) : Retranslate(); } -Project *ProjectPanel::project() +Project *ProjectPanel::project() const { return explorer_->project(); } @@ -102,17 +102,24 @@ void ProjectPanel::set_project(Project *p) } } -QList ProjectPanel::SelectedItems() +void ProjectPanel::set_root(Item *item) +{ + explorer_->set_root(item); + + Retranslate(); +} + +QList ProjectPanel::SelectedItems() const { return explorer_->SelectedItems(); } -Folder *ProjectPanel::GetSelectedFolder() +Folder *ProjectPanel::GetSelectedFolder() const { return explorer_->GetSelectedFolder(); } -ProjectViewModel *ProjectPanel::model() +ProjectViewModel *ProjectPanel::model() const { return explorer_->model(); } @@ -157,7 +164,11 @@ void ProjectPanel::Edit(Item* item) void ProjectPanel::Retranslate() { - SetTitle(tr("Project")); + if (explorer_->root_index().isValid()) { + SetTitle(tr("Folder")); + } else { + SetTitle(tr("Project")); + } UpdateSubtitle(); } @@ -187,14 +198,30 @@ void ProjectPanel::ShowNewMenu() void ProjectPanel::UpdateSubtitle() { - if (project() == nullptr) { - SetSubtitle(tr("(none)")); + if (project()) { + QString project_title = QStringLiteral("[*]%1").arg(project()->name()); + + if (explorer_->root_index().isValid()) { + QString folder_path; + + Item* item = static_cast(explorer_->root_index().internalPointer()); + + do { + folder_path.prepend(QStringLiteral("/%1").arg(item->name())); + + item = item->parent(); + } while (item != project()->root()); + + project_title.append(folder_path); + } + + SetSubtitle(project_title); } else { - SetSubtitle(QStringLiteral("[*]%1").arg(project()->name())); + SetSubtitle(tr("(none)")); } } -QList ProjectPanel::GetSelectedFootage() +QList ProjectPanel::GetSelectedFootage() const { QList items = SelectedItems(); QList footage; diff --git a/app/panel/project/project.h b/app/panel/project/project.h index 011135cdc..49b740601 100644 --- a/app/panel/project/project.h +++ b/app/panel/project/project.h @@ -37,16 +37,18 @@ class ProjectPanel : public PanelWidget, public FootageManagementPanel public: ProjectPanel(QWidget* parent); - Project* project(); + Project* project() const; void set_project(Project* p); - QList SelectedItems(); + void set_root(Item* item); - Folder* GetSelectedFolder(); + QList SelectedItems() const; - virtual QList GetSelectedFootage() override; + Folder* GetSelectedFolder() const; - ProjectViewModel* model(); + virtual QList GetSelectedFootage() const override; + + ProjectViewModel* model() const; virtual void SelectAll() override; virtual void DeselectAll() override; diff --git a/app/project/projectviewmodel.cpp b/app/project/projectviewmodel.cpp index 2dee64116..7dfaf453a 100644 --- a/app/project/projectviewmodel.cpp +++ b/app/project/projectviewmodel.cpp @@ -38,7 +38,7 @@ ProjectViewModel::ProjectViewModel(QObject *parent) : columns_.append(kRate); } -Project *ProjectViewModel::project() +Project *ProjectViewModel::project() const { return project_; } diff --git a/app/project/projectviewmodel.h b/app/project/projectviewmodel.h index 4e300e7ad..964378316 100644 --- a/app/project/projectviewmodel.h +++ b/app/project/projectviewmodel.h @@ -65,7 +65,7 @@ public: * * Currently active project or nullptr if there is none */ - Project* project(); + Project* project() const; /** * @brief Set the project to adapt diff --git a/app/widget/projectexplorer/projectexplorer.cpp b/app/widget/projectexplorer/projectexplorer.cpp index 286925665..8f48f538c 100644 --- a/app/widget/projectexplorer/projectexplorer.cpp +++ b/app/widget/projectexplorer/projectexplorer.cpp @@ -85,7 +85,7 @@ ProjectExplorer::ProjectExplorer(QWidget *parent) : connect(icon_view_, &ProjectExplorerIconView::customContextMenuRequested, this, &ProjectExplorer::ShowContextMenu); } -const ProjectToolbar::ViewType &ProjectExplorer::view_type() +const ProjectToolbar::ViewType &ProjectExplorer::view_type() const { return view_type_; } @@ -148,7 +148,7 @@ void ProjectExplorer::BrowseToFolder(const QModelIndex &index) nav_bar_->set_dir_up_enabled(index.isValid()); } -QAbstractItemView *ProjectExplorer::CurrentView() +QAbstractItemView *ProjectExplorer::CurrentView() const { return static_cast(stacked_widget_->currentWidget()); } @@ -251,7 +251,17 @@ void ProjectExplorer::ShowContextMenu() } else { context_menu_item_ = selected_items.first(); - if (context_menu_item_->type() == Item::kFootage) { + if (context_menu_item_->type() == Item::kFolder) { + + QAction* open_in_new_tab = menu.addAction(tr("Open in New Tab")); + connect(open_in_new_tab, &QAction::triggered, this, &ProjectExplorer::OpenContextMenuItemInNewTab); + + QAction* open_in_new_window = menu.addAction(tr("Open in New Window")); + connect(open_in_new_window, &QAction::triggered, this, &ProjectExplorer::OpenContextMenuItemInNewWindow); + + menu.addSeparator(); + + } else if (context_menu_item_->type() == Item::kFootage) { QString reveal_text; #if defined(Q_OS_WINDOWS) @@ -319,7 +329,17 @@ void ProjectExplorer::RevealSelectedFootage() #endif } -Project *ProjectExplorer::project() +void ProjectExplorer::OpenContextMenuItemInNewTab() +{ + Core::instance()->main_window()->FolderOpen(project(), context_menu_item_, false); +} + +void ProjectExplorer::OpenContextMenuItemInNewWindow() +{ + Core::instance()->main_window()->FolderOpen(project(), context_menu_item_, true); +} + +Project *ProjectExplorer::project() const { return model_.project(); } @@ -329,7 +349,20 @@ void ProjectExplorer::set_project(Project *p) model_.set_project(p); } -QList ProjectExplorer::SelectedItems() +QModelIndex ProjectExplorer::root_index() const +{ + return tree_view_->rootIndex(); +} + +void ProjectExplorer::set_root(Item *item) +{ + QModelIndex index = model_.CreateIndexFromItem(item); + + BrowseToFolder(index); + tree_view_->setRootIndex(index); +} + +QList ProjectExplorer::SelectedItems() const { // Determine which view is active and get its selected indexes QModelIndexList index_list = CurrentView()->selectionModel()->selectedRows(); @@ -348,7 +381,7 @@ QList ProjectExplorer::SelectedItems() return selected_items; } -Folder *ProjectExplorer::GetSelectedFolder() +Folder *ProjectExplorer::GetSelectedFolder() const { if (project() == nullptr) { return nullptr; diff --git a/app/widget/projectexplorer/projectexplorer.h b/app/widget/projectexplorer/projectexplorer.h index b9986e6c2..f0117741c 100644 --- a/app/widget/projectexplorer/projectexplorer.h +++ b/app/widget/projectexplorer/projectexplorer.h @@ -49,12 +49,16 @@ class ProjectExplorer : public QWidget public: ProjectExplorer(QWidget* parent); - const ProjectToolbar::ViewType& view_type(); + const ProjectToolbar::ViewType& view_type() const; - Project* project(); + Project* project() const; void set_project(Project* p); - QList SelectedItems(); + QModelIndex root_index() const; + + void set_root(Item* item); + + QList SelectedItems() const; /** * @brief Use a heuristic to determine which (if any) folder is selected @@ -68,7 +72,7 @@ public: * A folder that's heuristically been determined as "selected", or the root directory if none, or nullptr if no * project is open. */ - Folder* GetSelectedFolder(); + Folder* GetSelectedFolder() const; /** * @brief Access the ViewModel model of the project @@ -122,7 +126,7 @@ private: /** * @brief Get the currently active QAbstractItemView */ - QAbstractItemView* CurrentView(); + QAbstractItemView* CurrentView() const; QStackedWidget* stacked_widget_; @@ -163,6 +167,10 @@ private slots: void RevealSelectedFootage(); + void OpenContextMenuItemInNewTab(); + + void OpenContextMenuItemInNewWindow(); + }; OLIVE_NAMESPACE_EXIT diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index 626c7474e..f51fcd258 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -176,6 +176,33 @@ void MainWindow::SetTaskbarButtonProgress(int value, int max) } #endif +void MainWindow::FolderOpen(Project *p, Item *i, bool floating) +{ + ProjectPanel* panel = PanelManager::instance()->CreatePanel(this); + + panel->set_project(p); + panel->set_root(i); + + // Tabify with source project panel + foreach (ProjectPanel* proj_panel, project_panels_) { + if (proj_panel->project() == p) { + tabifyDockWidget(proj_panel, panel); + break; + } + } + + panel->setFloating(floating); + + panel->show(); + panel->raise(); + + // If the panel is closed, just destroy it + panel->SetSignalInsteadOfClose(true); + connect(panel, &ProjectPanel::CloseRequested, this, &MainWindow::FolderCloseRequested); + + folder_panels_.append(panel); +} + void MainWindow::SetFullscreen(bool fullscreen) { if (fullscreen) { @@ -251,6 +278,12 @@ void MainWindow::ProjectClose(Project *p) } } + foreach (ProjectPanel* panel, folder_panels_) { + if (panel->project() == p) { + panel->close(); + } + } + // Close any open sequences from project QList open_sequences = p->get_items_of_type(Item::kSequence); @@ -326,6 +359,14 @@ void MainWindow::ProjectCloseRequested() Core::instance()->CloseProject(p, true); } +void MainWindow::FolderCloseRequested() +{ + ProjectPanel* panel = static_cast(sender()); + + folder_panels_.removeOne(panel); + panel->deleteLater(); +} + TimelinePanel* MainWindow::AppendTimelinePanel() { TimelinePanel* panel = AppendPanelInternal(timeline_panels_); diff --git a/app/window/mainwindow/mainwindow.h b/app/window/mainwindow/mainwindow.h index e14d49dd5..d8de911f3 100644 --- a/app/window/mainwindow/mainwindow.h +++ b/app/window/mainwindow/mainwindow.h @@ -65,6 +65,8 @@ public: void SetTaskbarButtonProgress(int value, int max); #endif + void FolderOpen(Project* p, Item* i, bool floating); + public slots: void ProjectOpen(Project *p); @@ -105,6 +107,7 @@ private: SequenceViewerPanel* sequence_viewer_panel_; FootageViewerPanel* footage_viewer_panel_; QList project_panels_; + QList folder_panels_; ToolPanel* tool_panel_; QList timeline_panels_; AudioMonitorPanel* audio_monitor_panel_; @@ -127,6 +130,8 @@ private slots: void ProjectCloseRequested(); + void FolderCloseRequested(); + }; OLIVE_NAMESPACE_EXIT