implemented much of the project loading logic

Still not functional, but much of the groundwork is done.
This commit is contained in:
itsmattkc
2020-01-13 04:09:06 +11:00
parent bb57884cac
commit 16878e3c25
32 changed files with 552 additions and 63 deletions
+14
View File
@@ -15,6 +15,20 @@ rational rational::fromDouble(const double &flt)
return av_d2q(flt, INT_MAX);
}
rational rational::fromString(const QString &str)
{
QStringList elements = str.split('/');
switch (elements.size()) {
case 0:
return rational();
case 1:
return rational(elements.first().toLongLong());
default:
return rational(elements.at(0).toLongLong(), elements.at(1).toLongLong());
}
}
//Function: print number to cout
void rational::print(ostream &out) const
+2
View File
@@ -57,6 +57,8 @@ public:
static rational fromDouble(const double& flt);
static rational fromString(const QString& str);
//Assignment Operators
const rational& operator=(const rational &rhs);
const rational& operator+=(const rational &rhs);
+11
View File
@@ -0,0 +1,11 @@
#ifndef XMLREADLOOP_H
#define XMLREADLOOP_H
#define XMLReadLoop(reader, section) \
while (!reader->atEnd() && !(reader->name() == section && reader->isEndElement()) && reader->readNext())
#define XMLAttributeLoop(reader, item) \
QXmlStreamAttributes __attributes = reader->attributes(); \
foreach (const QXmlStreamAttribute& item, __attributes)
#endif // XMLREADLOOP_H
+68 -30
View File
@@ -41,6 +41,7 @@
#include "panel/panelmanager.h"
#include "panel/project/project.h"
#include "panel/viewer/viewer.h"
#include "project/projectloadmanager.h"
#include "project/projectsavemanager.h"
#include "project/item/footage/footage.h"
#include "project/item/sequence/sequence.h"
@@ -116,9 +117,13 @@ void Core::Start()
StartGUI(parser.isSet(fullscreen_option));
// Create new project on startup
// FIXME: Load project from startup_project_ instead if not empty
AddOpenProject(std::make_shared<Project>());
// Load startup project
if (startup_project_.isEmpty()) {
// If no load project is set, create a new one on open
AddOpenProject(std::make_shared<Project>());
} else {
}
}
void Core::Stop()
@@ -408,35 +413,10 @@ void Core::StartGUI(bool full_screen)
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 cancel signal (must be a direct connection or it'll be queued after the save is already finished)
connect(lsd, &LoadSaveDialog::Cancelled, psm, &ProjectSaveManager::Cancel, Qt::DirectConnection);
// 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);
InitiateOpenSaveProcess(psm, tr("Saving '%1'").arg(project->filename()), tr("Save Project"));
}
void Core::SaveAutorecovery()
@@ -500,7 +480,7 @@ void Core::SaveActiveProjectAs()
QString fn = QFileDialog::getSaveFileName(main_window_,
tr("Save Project As"),
QString(),
tr("Olive Project (*.ove)"));
GetProjectFilter());
if (!fn.isEmpty()) {
active_project->set_filename(fn);
@@ -584,3 +564,61 @@ QString Core::ChannelLayoutToString(const uint64_t &layout)
return tr("Unknown (0x%1)").arg(layout, 1, 16);
}
}
QString Core::GetProjectFilter() const
{
return QStringLiteral("%1 (*.ove)").arg("Olive Project");
}
void Core::OpenProjectInternal(const QString &filename)
{
ProjectLoadManager* plm = new ProjectLoadManager(filename);
// We use a blocking queued connection here because we want to ensure we have this project instance before the
// ProjectLoadManager is destroyed
connect(plm, &ProjectLoadManager::ProjectLoaded, this, &Core::AddOpenProject, Qt::BlockingQueuedConnection);
InitiateOpenSaveProcess(plm, tr("Loading '%1'").arg(filename), tr("Load Project"));
}
void Core::InitiateOpenSaveProcess(ProjectFileManagerBase *manager, const QString& dialog_text, const QString& dialog_title)
{
// Create save dialog
LoadSaveDialog* lsd = new LoadSaveDialog(dialog_text, dialog_title, main_window_);
lsd->open();
// Create a separate thread to save in
QThread* save_thread = new QThread();
save_thread->start();
// Move the save manager to this thread
manager->moveToThread(save_thread);
// Connect the save manager progress signal to the progress bar update on the dialog
connect(manager, &ProjectFileManagerBase::ProgressChanged, lsd, &LoadSaveDialog::SetProgress, Qt::QueuedConnection);
// Connect cancel signal (must be a direct connection or it'll be queued after the save is already finished)
connect(lsd, &LoadSaveDialog::Cancelled, manager, &ProjectFileManagerBase::Cancel, Qt::DirectConnection);
// Connect cleanup functions (ensure everything new'd in this function is deleteLater'd)
connect(manager, &ProjectFileManagerBase::Finished, lsd, &LoadSaveDialog::accept, Qt::QueuedConnection);
connect(manager, &ProjectFileManagerBase::Finished, lsd, &LoadSaveDialog::deleteLater, Qt::QueuedConnection);
connect(manager, &ProjectFileManagerBase::Finished, manager, &ProjectFileManagerBase::deleteLater, Qt::QueuedConnection);
connect(manager, &ProjectFileManagerBase::Finished, save_thread, &QThread::quit, Qt::QueuedConnection);
connect(manager, &ProjectFileManagerBase::Finished, save_thread, &QThread::deleteLater, Qt::QueuedConnection);
// Start the save process
QMetaObject::invokeMethod(manager, "Start", Qt::QueuedConnection);
}
void Core::OpenProject()
{
QString file = QFileDialog::getOpenFileName(main_window_,
tr("Open Project"),
QString(),
GetProjectFilter());
if (!file.isEmpty()) {
OpenProjectInternal(file);
}
}
+26 -2
View File
@@ -26,6 +26,7 @@
#include "common/rational.h"
#include "project/project.h"
#include "project/projectfilemanagerbase.h"
#include "project/projectviewmodel.h"
#include "task/task.h"
#include "tool/tool.h"
@@ -174,6 +175,11 @@ public:
static QString ChannelLayoutToString(const uint64_t &layout);
public slots:
/**
* @brief Starts an open file dialog to load a project from file
*/
void OpenProject();
/**
* @brief Save the currently active project
*
@@ -255,9 +261,22 @@ signals:
private:
/**
* @brief Creates an empty project and adds it to the "open projects"
* @brief Get the file filter than can be used with QFileDialog to open and save compatible projects
*/
void AddOpenProject(ProjectPtr p);
QString GetProjectFilter() const;
/**
* @brief Internal project open
*/
void OpenProjectInternal(const QString& filename);
/**
* @brief Initiate a project load or save
*
* The load and save process are largely similar, both OpenProjectInternal() and SaveProjectInternal() can run
* this function with some minor setup differences.
*/
void InitiateOpenSaveProcess(ProjectFileManagerBase* manager, const QString &dialog_text, const QString &dialog_title);
/**
* @brief Declare custom types/classes for Qt's signal/slot system
@@ -334,6 +353,11 @@ private:
private slots:
void SaveAutorecovery();
/**
* @brief Adds a project to the "open projects" list
*/
void AddOpenProject(ProjectPtr p);
};
#endif // CORE_H
@@ -40,7 +40,7 @@ ProjectPropertiesDialog::ProjectPropertiesDialog(QWidget *parent) :
{
QVBoxLayout* layout = new QVBoxLayout(this);
setWindowTitle(tr("Project Properties"));
setWindowTitle(tr("Project Properties for '%1'").arg(working_project_->name()));
QGroupBox* color_group = new QGroupBox();
color_group->setTitle(tr("Color Management"));
+88
View File
@@ -26,6 +26,7 @@
#include "common/bezier.h"
#include "common/lerp.h"
#include "common/xmlreadloop.h"
#include "node.h"
#include "output.h"
#include "inputarray.h"
@@ -84,6 +85,85 @@ QString NodeInput::name()
return NodeParam::name();
}
void NodeInput::Load(QXmlStreamReader *reader)
{
XMLAttributeLoop(reader, attr) {
if (attr.name() == "keyframing") {
set_is_keyframing(attr.value() == "1");
}
}
XMLReadLoop(reader, "input") {
if (reader->isStartElement()) {
if (reader->name() == "standard") {
// Load standard value
int val_index = 0;
XMLReadLoop(reader, "standard") {
if (reader->name() == "value") {
reader->readNext();
QString value_text = reader->text().toString();
if (value_text.isEmpty()) {
standard_value_.replace(val_index, QVariant());
} else {
standard_value_.replace(val_index, value_text);
}
val_index++;
}
}
} else if (reader->name() == "keyframes") {
int track = 0;
XMLReadLoop(reader, "keyframes") {
if (reader->name() == "track") {
XMLReadLoop(reader, "track") {
if (reader->name() == "key") {
rational key_time;
NodeKeyframe::Type key_type;
QVariant key_value;
QPointF key_in_handle;
QPointF key_out_handle;
XMLAttributeLoop(reader, attr) {
if (attr.name() == "time") {
key_time = rational::fromString(attr.value().toString());
} else if (attr.name() == "type") {
key_type = static_cast<NodeKeyframe::Type>(attr.value().toInt());
} else if (attr.name() == "inhandlex") {
key_in_handle.setX(attr.value().toDouble());
} else if (attr.name() == "inhandley") {
key_in_handle.setY(attr.value().toDouble());
} else if (attr.name() == "outhandlex") {
key_out_handle.setX(attr.value().toDouble());
} else if (attr.name() == "outhandley") {
key_out_handle.setY(attr.value().toDouble());
}
}
reader->readNext();
key_value = reader->text().toString();
NodeKeyframePtr key = NodeKeyframe::Create(key_time, key_value, key_type, track);
key->set_bezier_control_in(key_in_handle);
key->set_bezier_control_out(key_out_handle);
keyframe_tracks_[track].append(key);
}
}
track++;
}
}
} else {
}
}
}
}
void NodeInput::Save(QXmlStreamWriter *writer) const
{
writer->writeStartElement("input");
@@ -114,6 +194,10 @@ void NodeInput::Save(QXmlStreamWriter *writer) const
writer->writeAttribute("time", key->time().toString());
writer->writeAttribute("type", QString::number(key->type()));
writer->writeAttribute("inhandlex", QString::number(key->bezier_control_in().x()));
writer->writeAttribute("inhandley", QString::number(key->bezier_control_in().y()));
writer->writeAttribute("outhandlex", QString::number(key->bezier_control_out().x()));
writer->writeAttribute("outhandley", QString::number(key->bezier_control_out().y()));
writer->writeCharacters(key->value().toString());
@@ -137,6 +221,10 @@ const NodeParam::DataType &NodeInput::data_type() const
return data_type_;
}
void NodeInput::LoadInternal(QXmlStreamReader *reader)
{
}
void NodeInput::SaveInternal(QXmlStreamWriter *writer) const
{
}
+4
View File
@@ -54,6 +54,8 @@ public:
virtual QString name() override;
virtual void Load(QXmlStreamReader* reader) override;
virtual void Save(QXmlStreamWriter* writer) const override;
/**
@@ -241,6 +243,8 @@ signals:
void KeyframeRemoved(NodeKeyframePtr key);
protected:
virtual void LoadInternal(QXmlStreamReader* reader);
virtual void SaveInternal(QXmlStreamWriter* writer) const;
private:
+13
View File
@@ -1,5 +1,6 @@
#include "inputarray.h"
#include "common/xmlreadloop.h"
#include "node.h"
NodeInputArray::NodeInputArray(const QString &id, const DataType &type, const QVariant &default_value) :
@@ -167,6 +168,18 @@ void NodeInputArray::RemoveAt(int index)
RemoveLast();
}
void NodeInputArray::LoadInternal(QXmlStreamReader *reader)
{
if (reader->name() == "subparameters") {
XMLReadLoop(reader, "subparameters") {
if (reader->name() == "input") {
Append();
At(GetSize() - 1)->Load(reader);
}
}
}
}
void NodeInputArray::SaveInternal(QXmlStreamWriter *writer) const
{
writer->writeStartElement("subparameters");
+2
View File
@@ -33,6 +33,8 @@ signals:
void SizeChanged(int size);
protected:
virtual void LoadInternal(QXmlStreamReader* reader) override;
virtual void SaveInternal(QXmlStreamWriter* writer) const override;
private:
+35
View File
@@ -23,6 +23,8 @@
#include <QDebug>
#include <QFile>
#include "common/xmlreadloop.h"
Node::Node() :
can_be_deleted_(true)
{
@@ -47,6 +49,39 @@ Node::~Node()
}
}
void Node::Load(QXmlStreamReader *reader)
{
XMLReadLoop(reader, "node") {
if (reader->isStartElement()) {
if (reader->name() == "input" || reader->name() == "output") {
QString param_id;
XMLAttributeLoop(reader, attr) {
if (attr.name() == "id") {
param_id = attr.value().toString();
break;
}
}
if (param_id.isEmpty()) {
qDebug() << "Found parameter with no ID";
continue;
}
NodeParam* param = GetParameterWithID(param_id);
if (!param) {
qDebug() << "No parameter in" << id() << "with parameter" << param_id;
continue;
}
param->Load(reader);
}
}
}
}
void Node::Save(QXmlStreamWriter *writer) const
{
writer->writeStartElement("node");
+5
View File
@@ -65,6 +65,11 @@ public:
*/
virtual Node* copy() const = 0;
/**
* @brief Clear current node variables and replace them with
*/
void Load(QXmlStreamReader* reader);
/**
* @brief Save this node into a text/XML format
*/
+4
View File
@@ -41,6 +41,10 @@ QString NodeOutput::name()
return NodeParam::name();
}
void NodeOutput::Load(QXmlStreamReader *reader)
{
}
void NodeOutput::Save(QXmlStreamWriter *writer) const
{
writer->writeStartElement("output");
+2
View File
@@ -42,6 +42,8 @@ public:
virtual QString name() override;
virtual void Load(QXmlStreamReader *reader) override;
virtual void Save(QXmlStreamWriter* writer) const override;
private:
+5
View File
@@ -230,6 +230,11 @@ public:
virtual ~NodeParam() override;
/**
* @brief Load function
*/
virtual void Load(QXmlStreamReader* reader) = 0;
/**
* @brief Save function
*/
+4
View File
@@ -20,6 +20,10 @@ set(OLIVE_SOURCES
${OLIVE_SOURCES}
project/project.h
project/project.cpp
project/projectfilemanagerbase.h
project/projectfilemanagerbase.cpp
project/projectloadmanager.h
project/projectloadmanager.cpp
project/projectsavemanager.h
project/projectsavemanager.cpp
project/projectviewmodel.h
+31
View File
@@ -20,6 +20,9 @@
#include "folder.h"
#include "common/xmlreadloop.h"
#include "project/item/footage/footage.h"
#include "project/item/sequence/sequence.h"
#include "ui/icons/icons.h"
Folder::Folder()
@@ -41,6 +44,34 @@ QIcon Folder::icon()
return icon::Folder;
}
void Folder::Load(QXmlStreamReader *reader)
{
XMLAttributeLoop(reader, attr) {
if (attr.name() == "name") {
set_name(attr.value().toString());
}
}
XMLReadLoop(reader, "folder") {
if (reader->isStartElement()) {
ItemPtr child = nullptr;
if (reader->name() == "folder") {
child = std::make_shared<Folder>();
} else if (reader->name() == "footage") {
child = std::make_shared<Footage>();
} else if (reader->name() == "sequence") {
child = std::make_shared<Sequence>();
}
if (child) {
child->Load(reader);
add_child(child);
}
}
}
}
void Folder::Save(QXmlStreamWriter *writer) const
{
writer->writeStartElement("folder");
+2
View File
@@ -40,6 +40,8 @@ public:
virtual QIcon icon() override;
virtual void Load(QXmlStreamReader* reader) override;
virtual void Save(QXmlStreamWriter* writer) const override;
private:
+24
View File
@@ -23,6 +23,7 @@
#include <QCoreApplication>
#include "common/timecodefunctions.h"
#include "common/xmlreadloop.h"
#include "ui/icons/icons.h"
Footage::Footage()
@@ -35,6 +36,29 @@ Footage::~Footage()
ClearStreams();
}
void Footage::Load(QXmlStreamReader *reader)
{
QXmlStreamAttributes attributes = reader->attributes();
foreach (const QXmlStreamAttribute& attr, attributes) {
if (attr.name() == "name") {
set_name(attr.value().toString());
} else if (attr.name() == "filename") {
set_filename(attr.value().toString());
}
}
// FIXME: Probe here
XMLReadLoop(reader, "footage") {
if (reader->isStartElement()) {
if (reader->name() == "stream") {
// FIXME: Load stream custom options here
}
}
}
}
void Footage::Save(QXmlStreamWriter *writer) const
{
writer->writeStartElement("footage");
+5
View File
@@ -60,6 +60,11 @@ public:
*/
virtual ~Footage() override;
/**
* @brief Load function
*/
virtual void Load(QXmlStreamReader* reader) override;
/**
* @brief Save function
*/
+2
View File
@@ -63,6 +63,8 @@ public:
DISABLE_COPY_MOVE(Item)
virtual void Load(QXmlStreamReader* reader) = 0;
virtual void Save(QXmlStreamWriter* writer) const = 0;
virtual Type type() const = 0;
+44
View File
@@ -25,6 +25,8 @@
#include "config/config.h"
#include "common/channellayout.h"
#include "common/timecodefunctions.h"
#include "common/xmlreadloop.h"
#include "node/factory.h"
#include "panel/panelmanager.h"
#include "panel/node/node.h"
#include "panel/curve/curve.h"
@@ -38,6 +40,48 @@ Sequence::Sequence() :
{
}
void Sequence::Load(QXmlStreamReader *reader)
{
XMLAttributeLoop(reader, attr) {
if (attr.name() == "name") {
set_name(attr.value().toString());
}
}
XMLReadLoop(reader, "sequence") {
if (reader->isStartElement()) {
if (reader->name() == "node") {
QString node_id;
XMLAttributeLoop(reader, attr) {
if (attr.name() == "id") {
node_id = attr.value().toString();
// Currently the only thing we need
break;
}
}
if (node_id.isEmpty()) {
qDebug() << "Found node with no ID";
continue;
}
Node* node = NodeFactory::CreateFromID(node_id);
if (!node) {
qDebug() << "Failed to load" << node_id << "- no node with that ID is installed";
continue;
}
node->Load(reader);
AddNode(node);
}
}
}
}
void Sequence::Save(QXmlStreamWriter *writer) const
{
writer->writeStartElement("sequence");
+5
View File
@@ -38,6 +38,11 @@ class Sequence : public Item, public NodeGraph
public:
Sequence();
/**
* @brief Load function
*/
virtual void Load(QXmlStreamReader* reader) override;
/**
* @brief Save function
*/
+15 -1
View File
@@ -22,11 +22,25 @@
#include <QFileInfo>
#include "common/xmlreadloop.h"
Project::Project()
{
root_.set_project(this);
}
void Project::Load(QXmlStreamReader *reader)
{
XMLReadLoop(reader, "project") {
if (reader->isStartElement()) {
if (reader->name() == "folder") {
// Assume this folder is our root
root_.Load(reader);
}
}
}
}
void Project::Save(QXmlStreamWriter *writer) const
{
writer->writeStartElement("project");
@@ -35,7 +49,7 @@ void Project::Save(QXmlStreamWriter *writer) const
root_.Save(writer);
writer->writeTextElement("ocio", ocio_config_);
writer->writeEndElement(); // project
}
+2
View File
@@ -44,6 +44,8 @@ class Project : public QObject
public:
Project();
void Load(QXmlStreamReader* reader);
void Save(QXmlStreamWriter* writer) const;
Folder* root();
+12
View File
@@ -0,0 +1,12 @@
#include "projectfilemanagerbase.h"
ProjectFileManagerBase::ProjectFileManagerBase() :
cancelled_(false)
{
}
void ProjectFileManagerBase::Cancel()
{
cancelled_ = true;
}
+41
View File
@@ -0,0 +1,41 @@
#ifndef PROJECTFILEMANAGERBASE_H
#define PROJECTFILEMANAGERBASE_H
#include <QObject>
#include "project.h"
class ProjectFileManagerBase : public QObject
{
Q_OBJECT
public:
ProjectFileManagerBase();
public slots:
/**
* @brief Start the save process
*
* It's recommended to invoke this through Qt signals/slots/QueuedConnection after moving this object to a separate
* thread.
*/
virtual void Start() = 0;
/**
* @brief Cancel the current save
*
* Always connect to this with a DirectConnection. Otherwise, it'll be queued AFTER the save function is already
* complete.
*/
void Cancel();
signals:
void ProgressChanged(int);
void Finished();
private:
QAtomicInt cancelled_;
};
#endif // PROJECTFILEMANAGERBASE_H
+46
View File
@@ -0,0 +1,46 @@
#include "projectloadmanager.h"
#include <QFile>
#include <QXmlStreamReader>
ProjectLoadManager::ProjectLoadManager(const QString &filename) :
filename_(filename)
{
}
void ProjectLoadManager::Start()
{
QFile project_file(filename_);
if (project_file.open(QFile::ReadOnly | QFile::Text)) {
QXmlStreamReader reader(&project_file);
while (!reader.atEnd()) {
reader.readNext();
if (reader.isStartElement()) {
if (reader.name() == "version") {
reader.readNext();
qDebug() << "Project version:" << reader.text();
} else if (reader.name() == "project") {
ProjectPtr project = std::make_shared<Project>();
project->set_filename(filename_);
project->Load(&reader);
emit ProjectLoaded(project);
}
}
}
if (reader.hasError()) {
qDebug() << "Found XML error:" << reader.errorString();
}
project_file.close();
}
emit Finished();
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef PROJECTLOADMANAGER_H
#define PROJECTLOADMANAGER_H
#include "projectfilemanagerbase.h"
class ProjectLoadManager : public ProjectFileManagerBase
{
Q_OBJECT
public:
ProjectLoadManager(const QString& filename);
public slots:
/**
* @brief Start the load process
*
* It's recommended to invoke this through Qt signals/slots/QueuedConnection after moving this object to a separate
* thread.
*/
virtual void Start() override;
signals:
void ProjectLoaded(ProjectPtr project);
private:
QString filename_;
};
#endif // PROJECTLOADMANAGER_H
+6 -7
View File
@@ -1,10 +1,10 @@
#include "projectsavemanager.h"
#include <QFile>
#include <QXmlStreamWriter>
ProjectSaveManager::ProjectSaveManager(Project *project) :
project_(project),
cancelled_(false)
project_(project)
{
}
@@ -19,10 +19,14 @@ void ProjectSaveManager::Start()
writer.writeStartDocument();
writer.writeStartElement("olive");
writer.writeTextElement("version", "0.2.0");
project_->Save(&writer);
writer.writeEndElement(); // olive
writer.writeEndDocument();
project_file.close();
@@ -30,8 +34,3 @@ void ProjectSaveManager::Start()
emit Finished();
}
void ProjectSaveManager::Cancel()
{
cancelled_ = true;
}
+3 -21
View File
@@ -1,12 +1,9 @@
#ifndef PROJECTSAVEMANAGER_H
#define PROJECTSAVEMANAGER_H
#include <QObject>
#include <QXmlStreamWriter>
#include "projectfilemanagerbase.h"
#include "project.h"
class ProjectSaveManager : public QObject
class ProjectSaveManager : public ProjectFileManagerBase
{
Q_OBJECT
public:
@@ -19,26 +16,11 @@ public slots:
* It's recommended to invoke this through Qt signals/slots/QueuedConnection after moving this object to a separate
* thread.
*/
void Start();
/**
* @brief Cancel the current save
*
* Always connect to this with a DirectConnection. Otherwise, it'll be queued AFTER the save function is already
* complete.
*/
void Cancel();
signals:
void ProgressChanged(int);
void Finished();
virtual void Start() override;
private:
Project* project_;
QAtomicInt cancelled_;
};
#endif // PROJECTSAVEMANAGER_H
+1 -1
View File
@@ -41,7 +41,7 @@ MainMenu::MainMenu(QMainWindow *parent) :
file_menu_ = new Menu(this, this, SLOT(FileMenuAboutToShow()));
file_new_menu_ = new Menu(file_menu_);
MenuShared::instance()->AddItemsForNewMenu(file_new_menu_);
file_open_item_ = file_menu_->AddItem("openproj", nullptr, nullptr, "Ctrl+O");
file_open_item_ = file_menu_->AddItem("openproj", Core::instance(), SLOT(OpenProject()), "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", Core::instance(), SLOT(SaveActiveProject()), "Ctrl+S");