From 2353c38e4e910705169f13049aecc7516a60fdf1 Mon Sep 17 00:00:00 2001
From: BrimsonBhin <40442071+BrimsonBhin@users.noreply.github.com>
Date: Fri, 19 Apr 2019 20:37:15 -0700
Subject: [PATCH 1/7] Update issue templates
---
.github/ISSUE_TEMPLATE/bug_report.md | 47 +++++++++++++++++++++++
.github/ISSUE_TEMPLATE/feature_request.md | 27 +++++++++++++
2 files changed, 74 insertions(+)
create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md
create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 000000000..fc0db0811
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,47 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: "[BUG]"
+labels: ''
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Desktop (please complete the following information):**
+- Olive version: [e.g. Git hash from window title or Help > About]
+- Source: [e.g. AppImage, Website etc.]
+- Operating system: [e.g. Ubuntu 18.04 64-bit]
+- CPU: [e.g. Intel i5-4300U]
+- RAM: [e.g. 8GB]
+- GPU: [e.g. NVIDIA Geforce GT 1030 2GB (Driver ver xxx.xx.xx)]
+
+### Output Log
+
+```
+[Paste output log]
+```
+
+### GDB/CDB Backtrace (for crashes)
+
+```
+[If you can reproduce this issue, try running Olive through GDB and retrieving a backtrace, then paste the backtrace here. Instructions are available in the Wiki on how to acquire this backtrace.]
+```
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 000000000..4195442a2
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,27 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**I have read the following**
+- [ ] The Olive Wiki
+- [ ] Previous issues that include "FR" or "Feature Request"
+- [ ] Olive's Project Tab
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Do you know any libraries or sources that can help the Olive Team include the feature?**
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
From 3bdc3f7438d2ead2569d6c7383aac5bd2d163c09 Mon Sep 17 00:00:00 2001
From: BrimsonBhin <40442071+BrimsonBhin@users.noreply.github.com>
Date: Fri, 19 Apr 2019 20:38:10 -0700
Subject: [PATCH 2/7] Update issue templates
---
.github/ISSUE_TEMPLATE/bug_report.md | 2 +-
.github/ISSUE_TEMPLATE/feature_request.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index fc0db0811..b189e59e8 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -1,7 +1,7 @@
---
name: Bug report
about: Create a report to help us improve
-title: "[BUG]"
+title: "[Bug]"
labels: ''
assignees: ''
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index 4195442a2..bbbe2f1ea 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -1,7 +1,7 @@
---
name: Feature request
about: Suggest an idea for this project
-title: ''
+title: "[Feature Request]"
labels: ''
assignees: ''
From 0e31dbdb72010e634771de1db941c33b5536455f Mon Sep 17 00:00:00 2001
From: BrimsonBhin <40442071+BrimsonBhin@users.noreply.github.com>
Date: Fri, 19 Apr 2019 20:42:43 -0700
Subject: [PATCH 3/7] Update issue templates
---
.github/ISSUE_TEMPLATE/feature_request.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index bbbe2f1ea..11d81bb48 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -22,6 +22,7 @@ A clear and concise description of what you want to happen.
A clear and concise description of any alternative solutions or features you've considered.
**Do you know any libraries or sources that can help the Olive Team include the feature?**
+List open-source libraries related to the feature.
**Additional context**
Add any other context or screenshots about the feature request here.
From fa6409d4228bd6466234390ed375cb83491f9863 Mon Sep 17 00:00:00 2001
From: BrimsonBhin <40442071+BrimsonBhin@users.noreply.github.com>
Date: Fri, 19 Apr 2019 20:44:15 -0700
Subject: [PATCH 4/7] Delete ISSUE_TEMPLATE.md
---
ISSUE_TEMPLATE.md | 55 -----------------------------------------------
1 file changed, 55 deletions(-)
delete mode 100644 ISSUE_TEMPLATE.md
diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md
deleted file mode 100644
index 62e0d8064..000000000
--- a/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,55 +0,0 @@
-[If you are requesting a feature, please try to fill out all the information below. If you are reporting a bug, you can clear the template below.]
-
-### I have read the following
-
-- [ ] The [Olive Wiki](https://github.com/olive-editor/olive/wiki)
-
-- [ ] Previous issues that include ["FR"](https://github.com/olive-editor/olive/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+FR)or ["Feature Request"](https://github.com/olive-editor/olive/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+Feature+Request)
-
-- [ ] Olive's [Project Goals](https://github.com/olive-editor/olive/projects)
-
-### Detailed description of the feature request
-
-[Describe the feature request to the best of your ability. Do you know any libraries/sources that can help the Olive Team include the feature?]
-
-### Why should Olive include the feature? What are the benefits?
-
-[Explain the feature's importance to Olive and NLEs in general.]
-
----
-
-[If you are reporting a bug, please try to fill out all the information below. If you are requesting a feature, you can clear the template above.]
-
-### System Information
-
-**Olive version:** [e.g. Git hash from window title or Help > About]
-
-**Source:** [e.g. AppImage, Website etc.]
-
-**Operating system:** [e.g. Ubuntu 18.04 64-bit]
-
-**CPU:** [e.g. Intel i5-4300U]
-
-**RAM:** [e.g. 8GB]
-
-**GPU:** [e.g. NVIDIA Geforce GT 1030 2GB (Driver ver xxx.xx.xx)]
-
-### Detailed Description
-
-[Describe the issue you're having]
-
-### Steps to reproduce
-
-[Describe the steps to demonstrate the issue you're reporting]
-
-### Output Log
-
-```
-[Paste output log]
-```
-
-### GDB/CDB Backtrace (for crashes)
-
-```
-[If you can reproduce this issue, try running Olive through GDB and retrieving a backtrace, then paste the backtrace here. Instructions are available in the Wiki on how to acquire this backtrace.]
-```
From dca99cdf80df58d59b2ce38591b3b5dd9f3ead01 Mon Sep 17 00:00:00 2001
From: BrimsonBhin <40442071+BrimsonBhin@users.noreply.github.com>
Date: Fri, 19 Apr 2019 20:54:00 -0700
Subject: [PATCH 5/7] Update Month
---
global/global.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/global/global.cpp b/global/global.cpp
index 9f7ada144..f956662ae 100644
--- a/global/global.cpp
+++ b/global/global.cpp
@@ -62,7 +62,7 @@ OliveGlobal::OliveGlobal() :
version_id = QString(" | %1").arg(GITHASH);
#endif
- olive::AppName = QString("Olive (March 2019 | Alpha%1)").arg(version_id);
+ olive::AppName = QString("Olive (April 2019 | Alpha%1)").arg(version_id);
// set the file filter used in all file dialogs pertaining to Olive project files.
project_file_filter = tr("Olive Project %1").arg("(*.ove)");
From 9e6226df2922031bc8514cd7df29a0669d32cbb4 Mon Sep 17 00:00:00 2001
From: itsmattkc <34096995+itsmattkc@users.noreply.github.com>
Date: Thu, 2 May 2019 21:35:43 +1000
Subject: [PATCH 6/7] Delete global.cpp
---
global/global.cpp | 466 ----------------------------------------------
1 file changed, 466 deletions(-)
delete mode 100644 global/global.cpp
diff --git a/global/global.cpp b/global/global.cpp
deleted file mode 100644
index f956662ae..000000000
--- a/global/global.cpp
+++ /dev/null
@@ -1,466 +0,0 @@
-/***
-
- 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 "global/global.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "panels/panels.h"
-#include "global/path.h"
-#include "global/config.h"
-#include "rendering/audio.h"
-#include "dialogs/demonotice.h"
-#include "dialogs/preferencesdialog.h"
-#include "dialogs/exportdialog.h"
-#include "dialogs/debugdialog.h"
-#include "dialogs/aboutdialog.h"
-#include "dialogs/speeddialog.h"
-#include "dialogs/actionsearch.h"
-#include "dialogs/loaddialog.h"
-#include "dialogs/autocutsilencedialog.h"
-#include "project/loadthread.h"
-#include "timeline/sequence.h"
-#include "ui/mediaiconservice.h"
-#include "ui/mainwindow.h"
-#include "ui/updatenotification.h"
-#include "undo/undostack.h"
-
-std::unique_ptr olive::Global;
-QString olive::ActiveProjectFilename;
-QString olive::AppName;
-
-OliveGlobal::OliveGlobal() :
- changed_since_last_autorecovery(false)
-{
- // sets current app name
- QString version_id;
-
- // if available, append the current Git hash (defined by `qmake` and the Makefile)
-#ifdef GITHASH
- version_id = QString(" | %1").arg(GITHASH);
-#endif
-
- olive::AppName = QString("Olive (April 2019 | Alpha%1)").arg(version_id);
-
- // set the file filter used in all file dialogs pertaining to Olive project files.
- project_file_filter = tr("Olive Project %1").arg("(*.ove)");
-
- // set default value
- enable_load_project_on_init = false;
-
- // alloc QTranslator
- translator = std::unique_ptr(new QTranslator());
-}
-
-const QString &OliveGlobal::get_project_file_filter() {
- return project_file_filter;
-}
-
-void OliveGlobal::update_project_filename(const QString &s) {
- // set filename to s
- olive::ActiveProjectFilename = s;
-
- // update main window title to reflect new project filename
- olive::MainWindow->updateTitle();
-}
-
-void OliveGlobal::check_for_autorecovery_file() {
- QString data_dir = get_data_path();
- if (!data_dir.isEmpty()) {
- // detect auto-recovery file
- autorecovery_filename = data_dir + "/autorecovery.ove";
- if (QFile::exists(autorecovery_filename)) {
- if (QMessageBox::question(nullptr,
- tr("Auto-recovery"),
- tr("Olive didn't close properly and an autorecovery file "
- "was detected. Would you like to open it?"),
- QMessageBox::Yes,
- QMessageBox::No) == QMessageBox::Yes) {
- enable_load_project_on_init = false;
- OpenProjectWorker(autorecovery_filename, true);
- }
- }
- autorecovery_timer.setInterval(60000);
- QObject::connect(&autorecovery_timer, SIGNAL(timeout()), this, SLOT(save_autorecovery_file()));
- autorecovery_timer.start();
- }
-}
-
-void OliveGlobal::set_rendering_state(bool rendering) {
- audio_rendering = rendering;
- if (rendering) {
- autorecovery_timer.stop();
- } else {
- autorecovery_timer.start();
- }
-}
-
-void OliveGlobal::set_modified(bool modified)
-{
- olive::MainWindow->setWindowModified(modified);
- changed_since_last_autorecovery = modified;
-}
-
-bool OliveGlobal::is_modified()
-{
- return olive::MainWindow->isWindowModified();
-}
-
-void OliveGlobal::load_project_on_launch(const QString& s) {
- olive::ActiveProjectFilename = s;
- enable_load_project_on_init = true;
-}
-
-QString OliveGlobal::get_recent_project_list_file() {
- return get_data_dir().filePath("recents");
-}
-
-void OliveGlobal::load_translation_from_config() {
- QString language_file = olive::CurrentRuntimeConfig.external_translation_file.isEmpty() ?
- olive::CurrentConfig.language_file :
- olive::CurrentRuntimeConfig.external_translation_file;
-
- // clear runtime language file so if the user sets a different language, we won't load it next time
- olive::CurrentRuntimeConfig.external_translation_file.clear();
-
- // remove current translation if there is one
- QApplication::removeTranslator(translator.get());
-
- if (!language_file.isEmpty()) {
-
- // translation files are stored relative to app path (see GitHub issue #454)
- QString full_language_path = QDir(get_app_path()).filePath(language_file);
-
- // load translation file
- if (QFileInfo::exists(full_language_path)
- && translator->load(full_language_path)) {
- QApplication::installTranslator(translator.get());
- } else {
- qWarning() << "Failed to load translation file" << full_language_path << ". No language will be loaded.";
- }
- }
-}
-
-void OliveGlobal::SetNativeStyling(QWidget *w)
-{
-#ifdef Q_OS_WIN
- w->setStyleSheet("");
- w->setPalette(w->style()->standardPalette());
- w->setStyle(QStyleFactory::create("windowsvista"));
-#endif
-}
-
-void OliveGlobal::LoadProject(const QString &fn, bool autorecovery)
-{
- // QSortFilterProxyModels are not thread-safe, and as we'll be loading in another thread, leaving it connected
- // can cause glitches in its presentation. Therefore for the duration of the loading process, we disconnect it,
- // and reconnect it later once the loading is complete.
-
- panel_project->DisconnectFilterToModel();
-
- LoadDialog ld(olive::MainWindow);
-
- ld.open();
-
- LoadThread* lt = new LoadThread(fn, autorecovery);
- connect(&ld, SIGNAL(cancel()), lt, SLOT(cancel()));
- connect(lt, SIGNAL(success()), &ld, SLOT(accept()));
- connect(lt, SIGNAL(error()), &ld, SLOT(reject()));
- connect(lt, SIGNAL(error()), this, SLOT(new_project()));
- connect(lt, SIGNAL(report_progress(int)), &ld, SLOT(setValue(int)));
- lt->start();
-
- panel_project->ConnectFilterToModel();
-}
-
-void OliveGlobal::ClearProject()
-{
- // clear graph editor
- panel_graph_editor->set_row(nullptr);
-
- // clear effects panel
- panel_effect_controls->Clear(true);
-
- // clear existing project
- olive::Global->set_sequence(nullptr);
- panel_footage_viewer->set_media(nullptr);
-
- // clear project contents (footage, sequences, etc.)
- panel_project->clear();
-
- // clear undo stack
- olive::UndoStack.clear();
-
- // empty current project filename
- update_project_filename("");
-
- // full update of all panels
- update_ui(false);
-
- // set to unmodified
- olive::Global->set_modified(false);
-}
-
-void OliveGlobal::ImportProject(const QString &fn)
-{
- LoadProject(fn, false);
- set_modified(true);
-}
-
-void OliveGlobal::new_project() {
- if (can_close_project()) {
- ClearProject();
- }
-}
-
-void OliveGlobal::OpenProject() {
- QString fn = QFileDialog::getOpenFileName(olive::MainWindow, tr("Open Project..."), "", project_file_filter);
- if (!fn.isEmpty() && can_close_project()) {
- OpenProjectWorker(fn, false);
- }
-}
-
-void OliveGlobal::open_recent(int index) {
- QString recent_url = recent_projects.at(index);
- if (!QFile::exists(recent_url)) {
- if (QMessageBox::question(
- olive::MainWindow,
- tr("Missing recent project"),
- tr("The project '%1' no longer exists. Would you like to remove it from the recent projects list?").arg(recent_url),
- QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
- recent_projects.removeAt(index);
- panel_project->save_recent_projects();
- }
- } else if (can_close_project()) {
- OpenProjectWorker(recent_url, false);
- }
-}
-
-bool OliveGlobal::save_project_as() {
- QString fn = QFileDialog::getSaveFileName(olive::MainWindow, tr("Save Project As..."), "", project_file_filter);
- if (!fn.isEmpty()) {
- if (!fn.endsWith(".ove", Qt::CaseInsensitive)) {
- fn += ".ove";
- }
- update_project_filename(fn);
- panel_project->save_project(false);
- return true;
- }
- return false;
-}
-
-bool OliveGlobal::save_project() {
- if (olive::ActiveProjectFilename.isEmpty()) {
- return save_project_as();
- } else {
- panel_project->save_project(false);
- return true;
- }
-}
-
-bool OliveGlobal::can_close_project() {
- if (is_modified()) {
- QMessageBox* m = new QMessageBox(
- QMessageBox::Question,
- tr("Unsaved Project"),
- tr("This project has changed since it was last saved. Would you like to save it before closing?"),
- QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel,
- olive::MainWindow
- );
- m->setWindowModality(Qt::WindowModal);
- int r = m->exec();
- delete m;
- if (r == QMessageBox::Yes) {
- return save_project();
- } else if (r == QMessageBox::Cancel) {
- return false;
- }
- }
- return true;
-}
-
-void OliveGlobal::open_export_dialog() {
- if (CheckForActiveSequence()) {
- ExportDialog e(olive::MainWindow);
- e.exec();
- }
-}
-
-void OliveGlobal::finished_initialize() {
- if (enable_load_project_on_init) {
-
- // if a project was set as a command line argument, we load it here
- if (QFileInfo::exists(olive::ActiveProjectFilename)) {
- OpenProjectWorker(olive::ActiveProjectFilename, false);
- } else {
- QMessageBox::critical(olive::MainWindow,
- tr("Missing Project File"),
- tr("Specified project '%1' does not exist.").arg(olive::ActiveProjectFilename),
- QMessageBox::Ok);
- update_project_filename(nullptr);
- }
-
- enable_load_project_on_init = false;
-
- } else {
- // if we are not loading a project on launch and are running a release build, open the demo notice dialog
-#ifndef QT_DEBUG
- DemoNotice* d = new DemoNotice(olive::MainWindow);
- connect(d, SIGNAL(finished(int)), d, SLOT(deleteLater()));
- d->open();
-#endif
- }
-
- // Check for updates
- olive::update_notifier.check();
-}
-
-void OliveGlobal::save_autorecovery_file() {
- if (changed_since_last_autorecovery) {
- panel_project->save_project(true);
-
- changed_since_last_autorecovery = false;
-
- qInfo() << "Auto-recovery project saved";
- }
-}
-
-void OliveGlobal::open_preferences() {
- panel_sequence_viewer->pause();
- panel_footage_viewer->pause();
-
- PreferencesDialog pd(olive::MainWindow);
- pd.exec();
-}
-
-void OliveGlobal::set_sequence(SequencePtr s)
-{
- panel_graph_editor->set_row(nullptr);
- panel_effect_controls->Clear(true);
-
- olive::ActiveSequence = s;
- panel_sequence_viewer->set_main_sequence();
- panel_timeline->update_sequence();
- panel_timeline->setFocus();
-}
-
-void OliveGlobal::OpenProjectWorker(QString fn, bool autorecovery) {
- ClearProject();
- update_project_filename(fn);
- LoadProject(fn, autorecovery);
- olive::UndoStack.clear();
-}
-
-bool OliveGlobal::CheckForActiveSequence(bool show_msg)
-{
- if (olive::ActiveSequence == nullptr) {
-
- if (show_msg) {
- QMessageBox::information(olive::MainWindow,
- tr("No active sequence"),
- tr("Please open the sequence to perform this action."),
- QMessageBox::Ok);
- }
-
- return false;
- }
- return true;
-}
-
-void OliveGlobal::undo() {
- // workaround to prevent crash (and also users should never need to do this)
- if (!panel_timeline->importing) {
- olive::UndoStack.undo();
- update_ui(true);
- }
-}
-
-void OliveGlobal::redo() {
- // workaround to prevent crash (and also users should never need to do this)
- if (!panel_timeline->importing) {
- olive::UndoStack.redo();
- update_ui(true);
- }
-}
-
-void OliveGlobal::paste() {
- if (olive::ActiveSequence != nullptr) {
- panel_timeline->paste(false);
- }
-}
-
-void OliveGlobal::paste_insert() {
- if (olive::ActiveSequence != nullptr) {
- panel_timeline->paste(true);
- }
-}
-
-void OliveGlobal::open_about_dialog() {
- AboutDialog a(olive::MainWindow);
- a.exec();
-}
-
-void OliveGlobal::open_debug_log() {
- olive::DebugDialog->show();
-}
-
-void OliveGlobal::open_speed_dialog() {
- if (olive::ActiveSequence != nullptr) {
-
- QVector selected_clips = olive::ActiveSequence->SelectedClips();
-
- if (!selected_clips.isEmpty()) {
- SpeedDialog s(olive::MainWindow, selected_clips);
- s.exec();
- }
- }
-}
-
-void OliveGlobal::open_autocut_silence_dialog() {
- if (CheckForActiveSequence()) {
-
- QVector selected_clips = olive::ActiveSequence->SelectedClipIndexes();
-
- if (selected_clips.isEmpty()) {
- QMessageBox::critical(olive::MainWindow,
- tr("No clips selected"),
- tr("Select the clips you wish to auto-cut"),
- QMessageBox::Ok);
- } else {
- AutoCutSilenceDialog s(olive::MainWindow, selected_clips);
- s.exec();
- }
-
- }
-}
-
-void OliveGlobal::clear_undo_stack() {
- olive::UndoStack.clear();
-}
-
-void OliveGlobal::open_action_search() {
- ActionSearch as(olive::MainWindow);
- as.exec();
-}
From 389d0a84a98e27e001afff16daaf44f55e6cb787 Mon Sep 17 00:00:00 2001
From: itsmattkc
Date: Thu, 2 May 2019 21:37:06 +1000
Subject: [PATCH 7/7] Revert "Delete global.cpp"
This reverts commit 9e6226df2922031bc8514cd7df29a0669d32cbb4.
---
global/global.cpp | 466 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 466 insertions(+)
create mode 100644 global/global.cpp
diff --git a/global/global.cpp b/global/global.cpp
new file mode 100644
index 000000000..f956662ae
--- /dev/null
+++ b/global/global.cpp
@@ -0,0 +1,466 @@
+/***
+
+ 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 "global/global.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "panels/panels.h"
+#include "global/path.h"
+#include "global/config.h"
+#include "rendering/audio.h"
+#include "dialogs/demonotice.h"
+#include "dialogs/preferencesdialog.h"
+#include "dialogs/exportdialog.h"
+#include "dialogs/debugdialog.h"
+#include "dialogs/aboutdialog.h"
+#include "dialogs/speeddialog.h"
+#include "dialogs/actionsearch.h"
+#include "dialogs/loaddialog.h"
+#include "dialogs/autocutsilencedialog.h"
+#include "project/loadthread.h"
+#include "timeline/sequence.h"
+#include "ui/mediaiconservice.h"
+#include "ui/mainwindow.h"
+#include "ui/updatenotification.h"
+#include "undo/undostack.h"
+
+std::unique_ptr olive::Global;
+QString olive::ActiveProjectFilename;
+QString olive::AppName;
+
+OliveGlobal::OliveGlobal() :
+ changed_since_last_autorecovery(false)
+{
+ // sets current app name
+ QString version_id;
+
+ // if available, append the current Git hash (defined by `qmake` and the Makefile)
+#ifdef GITHASH
+ version_id = QString(" | %1").arg(GITHASH);
+#endif
+
+ olive::AppName = QString("Olive (April 2019 | Alpha%1)").arg(version_id);
+
+ // set the file filter used in all file dialogs pertaining to Olive project files.
+ project_file_filter = tr("Olive Project %1").arg("(*.ove)");
+
+ // set default value
+ enable_load_project_on_init = false;
+
+ // alloc QTranslator
+ translator = std::unique_ptr(new QTranslator());
+}
+
+const QString &OliveGlobal::get_project_file_filter() {
+ return project_file_filter;
+}
+
+void OliveGlobal::update_project_filename(const QString &s) {
+ // set filename to s
+ olive::ActiveProjectFilename = s;
+
+ // update main window title to reflect new project filename
+ olive::MainWindow->updateTitle();
+}
+
+void OliveGlobal::check_for_autorecovery_file() {
+ QString data_dir = get_data_path();
+ if (!data_dir.isEmpty()) {
+ // detect auto-recovery file
+ autorecovery_filename = data_dir + "/autorecovery.ove";
+ if (QFile::exists(autorecovery_filename)) {
+ if (QMessageBox::question(nullptr,
+ tr("Auto-recovery"),
+ tr("Olive didn't close properly and an autorecovery file "
+ "was detected. Would you like to open it?"),
+ QMessageBox::Yes,
+ QMessageBox::No) == QMessageBox::Yes) {
+ enable_load_project_on_init = false;
+ OpenProjectWorker(autorecovery_filename, true);
+ }
+ }
+ autorecovery_timer.setInterval(60000);
+ QObject::connect(&autorecovery_timer, SIGNAL(timeout()), this, SLOT(save_autorecovery_file()));
+ autorecovery_timer.start();
+ }
+}
+
+void OliveGlobal::set_rendering_state(bool rendering) {
+ audio_rendering = rendering;
+ if (rendering) {
+ autorecovery_timer.stop();
+ } else {
+ autorecovery_timer.start();
+ }
+}
+
+void OliveGlobal::set_modified(bool modified)
+{
+ olive::MainWindow->setWindowModified(modified);
+ changed_since_last_autorecovery = modified;
+}
+
+bool OliveGlobal::is_modified()
+{
+ return olive::MainWindow->isWindowModified();
+}
+
+void OliveGlobal::load_project_on_launch(const QString& s) {
+ olive::ActiveProjectFilename = s;
+ enable_load_project_on_init = true;
+}
+
+QString OliveGlobal::get_recent_project_list_file() {
+ return get_data_dir().filePath("recents");
+}
+
+void OliveGlobal::load_translation_from_config() {
+ QString language_file = olive::CurrentRuntimeConfig.external_translation_file.isEmpty() ?
+ olive::CurrentConfig.language_file :
+ olive::CurrentRuntimeConfig.external_translation_file;
+
+ // clear runtime language file so if the user sets a different language, we won't load it next time
+ olive::CurrentRuntimeConfig.external_translation_file.clear();
+
+ // remove current translation if there is one
+ QApplication::removeTranslator(translator.get());
+
+ if (!language_file.isEmpty()) {
+
+ // translation files are stored relative to app path (see GitHub issue #454)
+ QString full_language_path = QDir(get_app_path()).filePath(language_file);
+
+ // load translation file
+ if (QFileInfo::exists(full_language_path)
+ && translator->load(full_language_path)) {
+ QApplication::installTranslator(translator.get());
+ } else {
+ qWarning() << "Failed to load translation file" << full_language_path << ". No language will be loaded.";
+ }
+ }
+}
+
+void OliveGlobal::SetNativeStyling(QWidget *w)
+{
+#ifdef Q_OS_WIN
+ w->setStyleSheet("");
+ w->setPalette(w->style()->standardPalette());
+ w->setStyle(QStyleFactory::create("windowsvista"));
+#endif
+}
+
+void OliveGlobal::LoadProject(const QString &fn, bool autorecovery)
+{
+ // QSortFilterProxyModels are not thread-safe, and as we'll be loading in another thread, leaving it connected
+ // can cause glitches in its presentation. Therefore for the duration of the loading process, we disconnect it,
+ // and reconnect it later once the loading is complete.
+
+ panel_project->DisconnectFilterToModel();
+
+ LoadDialog ld(olive::MainWindow);
+
+ ld.open();
+
+ LoadThread* lt = new LoadThread(fn, autorecovery);
+ connect(&ld, SIGNAL(cancel()), lt, SLOT(cancel()));
+ connect(lt, SIGNAL(success()), &ld, SLOT(accept()));
+ connect(lt, SIGNAL(error()), &ld, SLOT(reject()));
+ connect(lt, SIGNAL(error()), this, SLOT(new_project()));
+ connect(lt, SIGNAL(report_progress(int)), &ld, SLOT(setValue(int)));
+ lt->start();
+
+ panel_project->ConnectFilterToModel();
+}
+
+void OliveGlobal::ClearProject()
+{
+ // clear graph editor
+ panel_graph_editor->set_row(nullptr);
+
+ // clear effects panel
+ panel_effect_controls->Clear(true);
+
+ // clear existing project
+ olive::Global->set_sequence(nullptr);
+ panel_footage_viewer->set_media(nullptr);
+
+ // clear project contents (footage, sequences, etc.)
+ panel_project->clear();
+
+ // clear undo stack
+ olive::UndoStack.clear();
+
+ // empty current project filename
+ update_project_filename("");
+
+ // full update of all panels
+ update_ui(false);
+
+ // set to unmodified
+ olive::Global->set_modified(false);
+}
+
+void OliveGlobal::ImportProject(const QString &fn)
+{
+ LoadProject(fn, false);
+ set_modified(true);
+}
+
+void OliveGlobal::new_project() {
+ if (can_close_project()) {
+ ClearProject();
+ }
+}
+
+void OliveGlobal::OpenProject() {
+ QString fn = QFileDialog::getOpenFileName(olive::MainWindow, tr("Open Project..."), "", project_file_filter);
+ if (!fn.isEmpty() && can_close_project()) {
+ OpenProjectWorker(fn, false);
+ }
+}
+
+void OliveGlobal::open_recent(int index) {
+ QString recent_url = recent_projects.at(index);
+ if (!QFile::exists(recent_url)) {
+ if (QMessageBox::question(
+ olive::MainWindow,
+ tr("Missing recent project"),
+ tr("The project '%1' no longer exists. Would you like to remove it from the recent projects list?").arg(recent_url),
+ QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
+ recent_projects.removeAt(index);
+ panel_project->save_recent_projects();
+ }
+ } else if (can_close_project()) {
+ OpenProjectWorker(recent_url, false);
+ }
+}
+
+bool OliveGlobal::save_project_as() {
+ QString fn = QFileDialog::getSaveFileName(olive::MainWindow, tr("Save Project As..."), "", project_file_filter);
+ if (!fn.isEmpty()) {
+ if (!fn.endsWith(".ove", Qt::CaseInsensitive)) {
+ fn += ".ove";
+ }
+ update_project_filename(fn);
+ panel_project->save_project(false);
+ return true;
+ }
+ return false;
+}
+
+bool OliveGlobal::save_project() {
+ if (olive::ActiveProjectFilename.isEmpty()) {
+ return save_project_as();
+ } else {
+ panel_project->save_project(false);
+ return true;
+ }
+}
+
+bool OliveGlobal::can_close_project() {
+ if (is_modified()) {
+ QMessageBox* m = new QMessageBox(
+ QMessageBox::Question,
+ tr("Unsaved Project"),
+ tr("This project has changed since it was last saved. Would you like to save it before closing?"),
+ QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel,
+ olive::MainWindow
+ );
+ m->setWindowModality(Qt::WindowModal);
+ int r = m->exec();
+ delete m;
+ if (r == QMessageBox::Yes) {
+ return save_project();
+ } else if (r == QMessageBox::Cancel) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void OliveGlobal::open_export_dialog() {
+ if (CheckForActiveSequence()) {
+ ExportDialog e(olive::MainWindow);
+ e.exec();
+ }
+}
+
+void OliveGlobal::finished_initialize() {
+ if (enable_load_project_on_init) {
+
+ // if a project was set as a command line argument, we load it here
+ if (QFileInfo::exists(olive::ActiveProjectFilename)) {
+ OpenProjectWorker(olive::ActiveProjectFilename, false);
+ } else {
+ QMessageBox::critical(olive::MainWindow,
+ tr("Missing Project File"),
+ tr("Specified project '%1' does not exist.").arg(olive::ActiveProjectFilename),
+ QMessageBox::Ok);
+ update_project_filename(nullptr);
+ }
+
+ enable_load_project_on_init = false;
+
+ } else {
+ // if we are not loading a project on launch and are running a release build, open the demo notice dialog
+#ifndef QT_DEBUG
+ DemoNotice* d = new DemoNotice(olive::MainWindow);
+ connect(d, SIGNAL(finished(int)), d, SLOT(deleteLater()));
+ d->open();
+#endif
+ }
+
+ // Check for updates
+ olive::update_notifier.check();
+}
+
+void OliveGlobal::save_autorecovery_file() {
+ if (changed_since_last_autorecovery) {
+ panel_project->save_project(true);
+
+ changed_since_last_autorecovery = false;
+
+ qInfo() << "Auto-recovery project saved";
+ }
+}
+
+void OliveGlobal::open_preferences() {
+ panel_sequence_viewer->pause();
+ panel_footage_viewer->pause();
+
+ PreferencesDialog pd(olive::MainWindow);
+ pd.exec();
+}
+
+void OliveGlobal::set_sequence(SequencePtr s)
+{
+ panel_graph_editor->set_row(nullptr);
+ panel_effect_controls->Clear(true);
+
+ olive::ActiveSequence = s;
+ panel_sequence_viewer->set_main_sequence();
+ panel_timeline->update_sequence();
+ panel_timeline->setFocus();
+}
+
+void OliveGlobal::OpenProjectWorker(QString fn, bool autorecovery) {
+ ClearProject();
+ update_project_filename(fn);
+ LoadProject(fn, autorecovery);
+ olive::UndoStack.clear();
+}
+
+bool OliveGlobal::CheckForActiveSequence(bool show_msg)
+{
+ if (olive::ActiveSequence == nullptr) {
+
+ if (show_msg) {
+ QMessageBox::information(olive::MainWindow,
+ tr("No active sequence"),
+ tr("Please open the sequence to perform this action."),
+ QMessageBox::Ok);
+ }
+
+ return false;
+ }
+ return true;
+}
+
+void OliveGlobal::undo() {
+ // workaround to prevent crash (and also users should never need to do this)
+ if (!panel_timeline->importing) {
+ olive::UndoStack.undo();
+ update_ui(true);
+ }
+}
+
+void OliveGlobal::redo() {
+ // workaround to prevent crash (and also users should never need to do this)
+ if (!panel_timeline->importing) {
+ olive::UndoStack.redo();
+ update_ui(true);
+ }
+}
+
+void OliveGlobal::paste() {
+ if (olive::ActiveSequence != nullptr) {
+ panel_timeline->paste(false);
+ }
+}
+
+void OliveGlobal::paste_insert() {
+ if (olive::ActiveSequence != nullptr) {
+ panel_timeline->paste(true);
+ }
+}
+
+void OliveGlobal::open_about_dialog() {
+ AboutDialog a(olive::MainWindow);
+ a.exec();
+}
+
+void OliveGlobal::open_debug_log() {
+ olive::DebugDialog->show();
+}
+
+void OliveGlobal::open_speed_dialog() {
+ if (olive::ActiveSequence != nullptr) {
+
+ QVector selected_clips = olive::ActiveSequence->SelectedClips();
+
+ if (!selected_clips.isEmpty()) {
+ SpeedDialog s(olive::MainWindow, selected_clips);
+ s.exec();
+ }
+ }
+}
+
+void OliveGlobal::open_autocut_silence_dialog() {
+ if (CheckForActiveSequence()) {
+
+ QVector selected_clips = olive::ActiveSequence->SelectedClipIndexes();
+
+ if (selected_clips.isEmpty()) {
+ QMessageBox::critical(olive::MainWindow,
+ tr("No clips selected"),
+ tr("Select the clips you wish to auto-cut"),
+ QMessageBox::Ok);
+ } else {
+ AutoCutSilenceDialog s(olive::MainWindow, selected_clips);
+ s.exec();
+ }
+
+ }
+}
+
+void OliveGlobal::clear_undo_stack() {
+ olive::UndoStack.clear();
+}
+
+void OliveGlobal::open_action_search() {
+ ActionSearch as(olive::MainWindow);
+ as.exec();
+}