From 271fbd01ae16c44c3d11ff213329cbd7dcfa51a3 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Fri, 5 Jul 2019 00:12:15 -0500 Subject: [PATCH] heuristic to import into selected folder --- app/core.cpp | 70 ++++++++++++++----- app/core.h | 2 +- app/panel/project/project.cpp | 5 ++ app/panel/project/project.h | 2 + app/project/project.cpp | 18 +++++ app/project/projectviewmodel.cpp | 18 +++++ app/project/projectviewmodel.h | 1 + .../projectexplorer/projectexplorer.cpp | 31 ++++++++ app/widget/projectexplorer/projectexplorer.h | 2 + 9 files changed, 129 insertions(+), 20 deletions(-) diff --git a/app/core.cpp b/app/core.cpp index 820b9926c..6408cd795 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -108,24 +108,7 @@ void Core::ImportFiles(const QStringList &urls, Folder* parent) return; } - ProjectPanel* active_project_panel = olive::panel_focus_manager->MostRecentlyFocused(); - Project* active_project; - - if (active_project_panel == nullptr // Check that we found a Project panel - || (active_project = active_project_panel->project()) == nullptr) { // and that we could find an active Project - - QMessageBox::critical(main_window_, error_capt, tr("Failed to find active Project panel")); - - } else { - - // If no parent was supplied, assume we're importing to the root - if (parent == nullptr) { - parent = active_project->root(); - } - - olive::task_manager.AddTask(new ImportTask(parent, urls)); - - } + olive::task_manager.AddTask(new ImportTask(parent, urls)); } void Core::SetTool(const olive::tool::Tool &tool) @@ -143,7 +126,56 @@ void Core::StartImportFootage() // Check if the user actually selected files to import if (!files.isEmpty()) { - ImportFiles(files); + + // Locate the most recently focused Project panel (assume that's the panel the user wants to import into) + ProjectPanel* active_project_panel = olive::panel_focus_manager->MostRecentlyFocused(); + Project* active_project; + + if (active_project_panel == nullptr // Check that we found a Project panel + || (active_project = active_project_panel->project()) == nullptr) { // and that we could find an active Project + QMessageBox::critical(main_window_, tr("Import footage"), tr("Failed to find active Project panel")); + return; + } + + Folder* folder = nullptr; + + // Get the selected items from the panel + QList selected_items = active_project_panel->SelectedItems(); + + // Heuristic for finding the selected folder + // + // - If `folder` is nullptr, we set the first folder we find. Either the item itself if it's a folder, or the + // item's parent. + // - Otherwise, if all folders found are the same, we'll use that to import into. + // - If more than one folder is found, we play it safe and import into the root folder + + for (int i=0;itype() != Item::kFolder) { + sel_item = sel_item->parent(); + + Q_ASSERT(sel_item->type() == Item::kFolder); + } + + if (folder == nullptr) { + // If the folder is nullptr, cache it as this folder + folder = static_cast(sel_item); + } else if (folder != sel_item) { + // If not, we've already cached a folder so we check if it's the same + // If it isn't, we "play it safe" and use the root folder + folder = nullptr; + break; + } + } + + // If we didn't pick up a folder from the heuristic above for whatever reason, use root + if (folder == nullptr) { + folder = active_project->root(); + } + + ImportFiles(files, folder); } } diff --git a/app/core.h b/app/core.h index e676eae99..e9f6a34dd 100644 --- a/app/core.h +++ b/app/core.h @@ -72,7 +72,7 @@ public: * * @param urls */ - void ImportFiles(const QStringList& urls, Folder *parent = nullptr); + void ImportFiles(const QStringList& urls, Folder *parent); public slots: /** diff --git a/app/panel/project/project.cpp b/app/panel/project/project.cpp index 1748ccc4d..5bc226cd3 100644 --- a/app/panel/project/project.cpp +++ b/app/panel/project/project.cpp @@ -69,6 +69,11 @@ void ProjectPanel::set_project(Project *p) Retranslate(); } +QList ProjectPanel::SelectedItems() +{ + return explorer_->SelectedItems(); +} + void ProjectPanel::changeEvent(QEvent *e) { if (e->type() == QEvent::LanguageChange) { diff --git a/app/panel/project/project.h b/app/panel/project/project.h index b2954aceb..195d8ed59 100644 --- a/app/panel/project/project.h +++ b/app/panel/project/project.h @@ -34,6 +34,8 @@ public: Project* project(); void set_project(Project* p); + QList SelectedItems(); + protected: virtual void changeEvent(QEvent* e) override; diff --git a/app/project/project.cpp b/app/project/project.cpp index 402983cac..e3caa36bc 100644 --- a/app/project/project.cpp +++ b/app/project/project.cpp @@ -23,6 +23,24 @@ Project::Project() { name_ = tr("(untitled)"); + + // FIXME: Test code + Folder* f1 = new Folder(); + f1->set_name("F1"); + f1->set_parent(&root_); + Folder* f2 = new Folder(); + f2->set_name("F2"); + f2->set_parent(f1); + Folder* f3 = new Folder(); + f3->set_name("F3"); + f3->set_parent(&root_); + Folder* f4 = new Folder(); + f4->set_name("F4"); + f4->set_parent(f1); + Folder* f5 = new Folder(); + f5->set_name("F5"); + f5->set_parent(f3); + // End Test code } Folder *Project::root() diff --git a/app/project/projectviewmodel.cpp b/app/project/projectviewmodel.cpp index cdded198f..4b0ee80d1 100644 --- a/app/project/projectviewmodel.cpp +++ b/app/project/projectviewmodel.cpp @@ -207,6 +207,24 @@ bool ProjectViewModel::setData(const QModelIndex &index, const QVariant &value, return false; } +bool ProjectViewModel::canFetchMore(const QModelIndex &parent) const +{ + // Check if this is a valid index + if (parent.isValid()) { + Item* item = GetItemObjectFromIndex(parent); + + // Check if this item is a kFolder type + // If it's a folder, we always return TRUE in order to always show the "expand triangle" icon, + // even when there are no "physical" children + if (item->type() == Item::kFolder) { + return true; + } + } + + // Otherwise, return default behavior + return QAbstractItemModel::canFetchMore(parent); +} + Qt::ItemFlags ProjectViewModel::flags(const QModelIndex &index) const { if (!index.isValid()) { diff --git a/app/project/projectviewmodel.h b/app/project/projectviewmodel.h index c5fa9a6ec..019b2af50 100644 --- a/app/project/projectviewmodel.h +++ b/app/project/projectviewmodel.h @@ -84,6 +84,7 @@ public: virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; virtual bool hasChildren(const QModelIndex &parent = QModelIndex()) const override; virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + virtual bool canFetchMore(const QModelIndex &parent) const override; /** Drag and drop support */ virtual Qt::ItemFlags flags(const QModelIndex &index) const override; diff --git a/app/widget/projectexplorer/projectexplorer.cpp b/app/widget/projectexplorer/projectexplorer.cpp index 03627169c..5b186c9bf 100644 --- a/app/widget/projectexplorer/projectexplorer.cpp +++ b/app/widget/projectexplorer/projectexplorer.cpp @@ -169,3 +169,34 @@ void ProjectExplorer::set_project(Project *p) { model_.set_project(p); } + +QList ProjectExplorer::SelectedItems() +{ + QModelIndexList index_list; + + // Determine which view is active and get its selected indexes + switch (view_type_) { + case olive::TreeView: + index_list = tree_view_->selectionModel()->selectedRows(); + break; + case olive::ListView: + index_list = list_view_->selectionModel()->selectedRows(); + break; + case olive::IconView: + index_list = icon_view_->selectionModel()->selectedRows(); + break; + } + + // Convert indexes to item objects + QList selected_items; + + for (int i=0;i(index.internalPointer()); + + selected_items.append(item); + } + + return selected_items; +} diff --git a/app/widget/projectexplorer/projectexplorer.h b/app/widget/projectexplorer/projectexplorer.h index fbe1825b0..e5121f73f 100644 --- a/app/widget/projectexplorer/projectexplorer.h +++ b/app/widget/projectexplorer/projectexplorer.h @@ -53,6 +53,8 @@ public: Project* project(); void set_project(Project* p); + QList SelectedItems(); + public slots: void set_view_type(olive::ProjectViewType type);