/*** Olive - Non-Linear Video Editor Copyright (C) 2019 Olive Team This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ***/ #include "core.h" #include #include #include #include #include #include #include "panel/panelfocusmanager.h" #include "panel/project/project.h" #include "project/item/footage/footage.h" #include "task/import/import.h" #include "task/taskmanager.h" #include "ui/icons/icons.h" #include "ui/style/style.h" #include "widget/menu/menushared.h" Core olive::core; Core::Core() : main_window_(nullptr) { } void Core::Start() { // // Parse command line arguments // QCoreApplication* app = QCoreApplication::instance(); QCommandLineParser parser; parser.addHelpOption(); parser.addVersionOption(); // Project from command line option // FIXME: What's the correct way to make a visually "optional" positional argument, or is manually adding square // brackets like this correct? parser.addPositionalArgument("[project]", tr("Project to open on startup")); // Create fullscreen option QCommandLineOption fullscreen_option({"f", "fullscreen"}, tr("Start in full screen mode")); parser.addOption(fullscreen_option); // Parse options parser.process(*app); QStringList args = parser.positionalArguments(); // Detect project to load on startup if (!args.isEmpty()) { startup_project_ = args.first(); } // Declare custom types for Qt signal/slot syste DeclareTypesForQt(); // // Start GUI (TODO CLI mode) // StartGUI(parser.isSet(fullscreen_option)); // Create new project on startup // TODO: Load project from startup_project_ instead if not empty AddOpenProject(std::make_shared()); } void Core::Stop() { delete main_window_; } olive::MainWindow *Core::main_window() { return main_window_; } void Core::ImportFiles(const QStringList &urls, Folder* parent) { QString error_capt = tr("Import error"); if (urls.isEmpty()) { QMessageBox::critical(main_window_, error_capt, tr("Nothing to import")); return; } olive::task_manager.AddTask(new ImportTask(parent, urls)); } void Core::SetTool(const olive::tool::Tool &tool) { tool_ = tool; emit ToolChanged(tool_); } void Core::StartImportFootage() { // Open dialog for user to select files QStringList files = QFileDialog::getOpenFileNames(main_window_, tr("Import footage...")); // Check if the user actually selected files to import if (!files.isEmpty()) { // 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); } } void Core::AddOpenProject(ProjectPtr p) { open_projects_.append(p); emit ProjectOpened(p.get()); } void Core::DeclareTypesForQt() { qRegisterMetaType("Task::Status"); } void Core::StartGUI(bool full_screen) { // Load all icons olive::icon::LoadAll(); // Set UI style olive::style::AppSetDefault(); // Set up shared menus olive::menu_shared.Initialize(); // Since we're starting GUI mode, create a PanelFocusManager (auto-deletes with QObject) olive::panel_focus_manager = new PanelFocusManager(this); // Connect the PanelFocusManager to the application's focus change signal connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), olive::panel_focus_manager, SLOT(FocusChanged(QWidget*, QWidget*))); // Create main window and open it main_window_ = new olive::MainWindow(); if (full_screen) { main_window_->showFullScreen(); } else { main_window_->showMaximized(); } // When a new project is opened, update the mainwindow connect(this, SIGNAL(ProjectOpened(Project*)), main_window_, SLOT(ProjectOpen(Project*))); }