implemented saving UI

Implemented the file dialog, save progress dialog, and separate thread to save
in (saving needs to be done in a separate thread so the main/GUI thread doesn't
get blocked).
This commit is contained in:
itsmattkc
2020-01-12 16:26:05 +11:00
parent ca89e2b818
commit 00b5672639
14 changed files with 274 additions and 20 deletions
+67
View File
@@ -33,6 +33,7 @@
#include "config/config.h"
#include "dialog/about/about.h"
#include "dialog/export/export.h"
#include "dialog/loadsave/loadsave.h"
#include "dialog/sequence/sequence.h"
#include "dialog/preferences/preferences.h"
#include "dialog/projectproperties/projectproperties.h"
@@ -40,6 +41,7 @@
#include "panel/panelmanager.h"
#include "panel/project/project.h"
#include "panel/viewer/viewer.h"
#include "project/projectsavemanager.h"
#include "project/item/footage/footage.h"
#include "project/item/sequence/sequence.h"
#include "render/colormanager.h"
@@ -404,6 +406,36 @@ void Core::StartGUI(bool full_screen)
autorecovery_timer_.start();
}
void Core::SaveProjectInternal(Project *project)
{
// Create save dialog
LoadSaveDialog* lsd = new LoadSaveDialog(tr("Saving '%1'").arg(project->filename()), tr("Save Project"), main_window_);
lsd->open();
// Create save manager
ProjectSaveManager* psm = new ProjectSaveManager(project);
// Create a separate thread to save in
QThread* save_thread = new QThread();
save_thread->start();
// Move the save manager to this thread
psm->moveToThread(save_thread);
// Connect the save manager progress signal to the progress bar update on the dialog
connect(psm, &ProjectSaveManager::ProgressChanged, lsd, &LoadSaveDialog::SetProgress, Qt::QueuedConnection);
// Connect cleanup functions (ensure everything new'd in this function is deleteLater'd)
connect(psm, &ProjectSaveManager::Finished, lsd, &LoadSaveDialog::accept, Qt::QueuedConnection);
connect(psm, &ProjectSaveManager::Finished, lsd, &LoadSaveDialog::deleteLater, Qt::QueuedConnection);
connect(psm, &ProjectSaveManager::Finished, psm, &ProjectSaveManager::deleteLater, Qt::QueuedConnection);
connect(psm, &ProjectSaveManager::Finished, save_thread, &QThread::quit, Qt::QueuedConnection);
connect(psm, &ProjectSaveManager::Finished, save_thread, &QThread::deleteLater, Qt::QueuedConnection);
// Start the save process
QMetaObject::invokeMethod(psm, "Start", Qt::QueuedConnection);
}
void Core::SaveAutorecovery()
{
if (queue_autorecovery_) {
@@ -439,6 +471,41 @@ void Core::SetAutorecoveryInterval(int minutes)
autorecovery_timer_.setInterval(minutes * 60000);
}
void Core::SaveActiveProject()
{
Project* active_project = GetActiveProject();
if (!active_project) {
return;
}
if (active_project->filename().isEmpty()) {
SaveActiveProjectAs();
} else {
SaveProjectInternal(active_project);
}
}
void Core::SaveActiveProjectAs()
{
Project* active_project = GetActiveProject();
if (!active_project) {
return;
}
QString fn = QFileDialog::getSaveFileName(main_window_,
tr("Save Project As"),
QString(),
tr("Olive Project (*.ove)"));
if (!fn.isEmpty()) {
active_project->set_filename(fn);
SaveProjectInternal(active_project);
}
}
QList<rational> Core::SupportedFrameRates()
{
QList<rational> frame_rates;
+17
View File
@@ -174,6 +174,18 @@ public:
static QString ChannelLayoutToString(const uint64_t &layout);
public slots:
/**
* @brief Save the currently active project
*
* If the project hasn't been saved before, this will be equivalent to calling SaveActiveProjectAs().
*/
void SaveActiveProject();
/**
* @brief Save the currently active project with a new filename
*/
void SaveActiveProjectAs();
/**
* @brief Set the current application-wide tool
*
@@ -263,6 +275,11 @@ private:
*/
void StartGUI(bool full_screen);
/**
* @brief Internal function for saving a project to a file
*/
void SaveProjectInternal(Project* project);
/**
* @brief Internal main window object
*/
+1
View File
@@ -19,6 +19,7 @@ add_subdirectory(actionsearch)
add_subdirectory(export)
add_subdirectory(footageproperties)
add_subdirectory(keyframeproperties)
add_subdirectory(loadsave)
add_subdirectory(preferences)
add_subdirectory(projectproperties)
add_subdirectory(sequence)
+22
View File
@@ -0,0 +1,22 @@
# 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 <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/loadsave/loadsave.h
dialog/loadsave/loadsave.cpp
PARENT_SCOPE
)
+41
View File
@@ -0,0 +1,41 @@
#include "loadsave.h"
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>
LoadSaveDialog::LoadSaveDialog(const QString& message, const QString& title, QWidget *parent) :
QDialog(parent)
{
if (!title.isEmpty()) {
setWindowTitle(title);
}
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(new QLabel(message));
bar_ = new QProgressBar();
bar_->setMinimum(0);
bar_->setValue(0);
bar_->setMaximum(100);
layout->addWidget(bar_);
QHBoxLayout* cancel_layout = new QHBoxLayout();
layout->addLayout(cancel_layout);
cancel_layout->setMargin(0);
cancel_layout->setSpacing(0);
cancel_layout->addStretch();
QPushButton* cancel_btn = new QPushButton(tr("Cancel"));
connect(cancel_btn, &QPushButton::clicked, this, &LoadSaveDialog::Cancelled);
connect(cancel_btn, &QPushButton::clicked, this, &LoadSaveDialog::reject);
cancel_layout->addWidget(cancel_btn);
cancel_layout->addStretch();
}
void LoadSaveDialog::SetProgress(int value)
{
bar_->setValue(value);
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef LOADSAVEDIALOG_H
#define LOADSAVEDIALOG_H
#include <QDialog>
#include <QProgressBar>
class LoadSaveDialog : public QDialog
{
Q_OBJECT
public:
LoadSaveDialog(const QString &message, const QString &title, QWidget* parent = nullptr);
public slots:
void SetProgress(int value);
signals:
void Cancelled();
private:
QProgressBar* bar_;
};
#endif // LOADSAVEDIALOG_H
+19 -6
View File
@@ -75,9 +75,17 @@ Project *ProjectPanel::project()
void ProjectPanel::set_project(Project *p)
{
if (project()) {
disconnect(project(), &Project::NameChanged, this, &ProjectPanel::ProjectNameChanged);
}
explorer_->set_project(p);
Retranslate();
if (project()) {
connect(project(), &Project::NameChanged, this, &ProjectPanel::ProjectNameChanged);
}
ProjectNameChanged();
}
QList<Item *> ProjectPanel::SelectedItems()
@@ -112,11 +120,7 @@ void ProjectPanel::Retranslate()
{
SetTitle(tr("Project"));
if (project() == nullptr) {
SetSubtitle(tr("(none)"));
} else {
SetSubtitle(project()->name());
}
ProjectNameChanged();
}
void ProjectPanel::ItemDoubleClickSlot(Item *item)
@@ -141,3 +145,12 @@ void ProjectPanel::ShowNewMenu()
new_menu.exec(QCursor::pos());
}
void ProjectPanel::ProjectNameChanged()
{
if (project() == nullptr) {
SetSubtitle(tr("(none)"));
} else {
SetSubtitle(project()->name());
}
}
+2
View File
@@ -58,6 +58,8 @@ private slots:
void ItemDoubleClickSlot(Item* item);
void ShowNewMenu();
void ProjectNameChanged();
};
#endif // PROJECT_PANEL_H
+2
View File
@@ -20,6 +20,8 @@ set(OLIVE_SOURCES
${OLIVE_SOURCES}
project/project.h
project/project.cpp
project/projectsavemanager.h
project/projectsavemanager.cpp
project/projectviewmodel.h
project/projectviewmodel.cpp
PARENT_SCOPE
+19 -7
View File
@@ -20,9 +20,10 @@
#include "project.h"
#include <QFileInfo>
Project::Project()
{
name_ = tr("(untitled)");
root_.set_project(this);
}
@@ -31,17 +32,28 @@ Folder *Project::root()
return &root_;
}
const QString &Project::name()
QString Project::name() const
{
return name_;
if (filename_.isEmpty()) {
return tr("(untitled)");
} else {
return QFileInfo(filename_).baseName();
}
}
void Project::set_name(const QString &s)
const QString &Project::filename() const
{
name_ = s;
return filename_;
}
const QString &Project::ocio_config()
void Project::set_filename(const QString &s)
{
filename_ = s;
emit NameChanged();
}
const QString &Project::ocio_config() const
{
return ocio_config_;
}
@@ -51,7 +63,7 @@ void Project::set_ocio_config(const QString &ocio_config)
ocio_config_ = ocio_config;
}
const QString &Project::default_input_colorspace()
const QString &Project::default_input_colorspace() const
{
return default_input_colorspace_;
}
+10 -5
View File
@@ -46,21 +46,26 @@ public:
Folder* root();
const QString& name();
void set_name(const QString& s);
QString name() const;
const QString& ocio_config();
const QString& filename() const;
void set_filename(const QString& s);
const QString& ocio_config() const;
void set_ocio_config(const QString& ocio_config);
const QString& default_input_colorspace();
const QString& default_input_colorspace() const;
void set_default_input_colorspace(const QString& colorspace);
ColorManager* color_manager();
signals:
void NameChanged();
private:
Folder root_;
QString name_;
QString filename_;
QString ocio_config_;
QString default_input_colorspace_;
+22
View File
@@ -0,0 +1,22 @@
#include "projectsavemanager.h"
ProjectSaveManager::ProjectSaveManager(Project *project) :
project_(project)
{
}
void ProjectSaveManager::Start()
{
int prog = 0;
do {
prog += 10;
emit ProgressChanged(prog);
Sleep(200);
} while (prog < 100);
emit Finished();
}
+27
View File
@@ -0,0 +1,27 @@
#ifndef PROJECTSAVEMANAGER_H
#define PROJECTSAVEMANAGER_H
#include <QObject>
#include "project.h"
class ProjectSaveManager : public QObject
{
Q_OBJECT
public:
ProjectSaveManager(Project* project);
public slots:
void Start();
signals:
void ProgressChanged(int);
void Finished();
private:
Project* project_;
};
#endif // PROJECTSAVEMANAGER_H
+2 -2
View File
@@ -44,8 +44,8 @@ MainMenu::MainMenu(QMainWindow *parent) :
file_open_item_ = file_menu_->AddItem("openproj", nullptr, nullptr, "Ctrl+O");
file_open_recent_menu_ = new Menu(file_menu_);
file_open_recent_clear_item_ = file_open_recent_menu_->AddItem("clearopenrecent", nullptr, nullptr);
file_save_item_ = file_menu_->AddItem("saveproj", nullptr, nullptr, "Ctrl+S");
file_save_as_item_ = file_menu_->AddItem("saveprojas", nullptr, nullptr, "Ctrl+Shift+S");
file_save_item_ = file_menu_->AddItem("saveproj", Core::instance(), SLOT(SaveActiveProject()), "Ctrl+S");
file_save_as_item_ = file_menu_->AddItem("saveprojas", Core::instance(), SLOT(SaveActiveProjectAs()), "Ctrl+Shift+S");
file_menu_->addSeparator();
file_import_item_ = file_menu_->AddItem("import", Core::instance(), SLOT(DialogImportShow()), "Ctrl+I");
file_menu_->addSeparator();