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:
@@ -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
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,8 @@ private slots:
|
||||
void ItemDoubleClickSlot(Item* item);
|
||||
|
||||
void ShowNewMenu();
|
||||
|
||||
void ProjectNameChanged();
|
||||
};
|
||||
|
||||
#endif // PROJECT_PANEL_H
|
||||
|
||||
@@ -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
@@ -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
@@ -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_;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user