fully implemented saving/loading effect data to file, fixes #418

This commit is contained in:
itsmattkc
2019-02-03 20:55:47 +11:00
parent 7c447680d2
commit 87df07e6e7
4 changed files with 172 additions and 118 deletions
+119 -97
View File
@@ -398,11 +398,11 @@ void Effect::show_context_menu(const QPoint& pos) {
menu.addAction(tr("D&elete"), this, SLOT(delete_self()));
menu.addSeparator();
menu.addSeparator();
menu.addAction(tr("Load Settings to File"), this, SLOT(load_from_file()));
menu.addAction(tr("Load Settings From File"), this, SLOT(load_from_file()));
menu.addAction(tr("Save Settings to File"), this, SLOT(save_to_file()));
menu.addAction(tr("Save Settings to File"), this, SLOT(save_to_file()));
menu.exec(container->title_bar->mapToGlobal(pos));
}
@@ -433,99 +433,57 @@ void Effect::move_down() {
command->to = command->from + 1;
undo_stack.push(command);
panel_effect_controls->reload_clips();
panel_sequence_viewer->viewer_widget->frame_update();
panel_sequence_viewer->viewer_widget->frame_update();
}
void Effect::save_to_file() {
// save effect settings to file
QString file = QFileDialog::getSaveFileName(mainWindow,
tr("Save Effect Settings"),
QString(),
tr("Effect XML Settings %1").arg("(*.xml)"));
// save effect settings to file
QString file = QFileDialog::getSaveFileName(mainWindow,
tr("Save Effect Settings"),
QString(),
tr("Effect XML Settings %1").arg("(*.xml)"));
// if the user picked a file
if (!file.isEmpty()) {
QFile file_handle(file);
if (file_handle.open(QFile::WriteOnly)) {
// if the user picked a file
if (!file.isEmpty()) {
QFile file_handle(file);
if (file_handle.open(QFile::WriteOnly)) {
// write settings with xml writer
QXmlStreamWriter stream(&file_handle);
file_handle.write(save_to_string());
stream.writeStartDocument();
stream.writeStartElement("effect");
// pass off to standard saving function
save(stream);
stream.writeEndElement(); // effect
stream.writeEndDocument();
file_handle.close();
} else {
QMessageBox::critical(mainWindow,
tr("Save Settings Failed"),
tr("Failed to open \"%1\" for writing.").arg(file),
QMessageBox::Ok);
}
}
file_handle.close();
} else {
QMessageBox::critical(mainWindow,
tr("Save Settings Failed"),
tr("Failed to open \"%1\" for writing.").arg(file),
QMessageBox::Ok);
}
}
}
void Effect::load_from_file() {
// load effect settings from file
QString file = QFileDialog::getOpenFileName(mainWindow,
tr("Load Effect Settings"),
QString(),
tr("Effect XML Settings %1").arg("(*.xml)"));
// load effect settings from file
QString file = QFileDialog::getOpenFileName(mainWindow,
tr("Load Effect Settings"),
QString(),
tr("Effect XML Settings %1").arg("(*.xml)"));
// if the user picked a file
if (!file.isEmpty()) {
QFile file_handle(file);
if (file_handle.open(QFile::ReadOnly)) {
// if the user picked a file
if (!file.isEmpty()) {
QFile file_handle(file);
if (file_handle.open(QFile::ReadOnly)) {
// write settings with xml writer
QXmlStreamReader stream(&file_handle);
undo_stack.push(new SetEffectData(this, file_handle.readAll()));
while (!stream.atEnd()) {
stream.readNext();
file_handle.close();
// find the effect opening tag
if (stream.name() == "effect" && stream.isStartElement()) {
// check the name to see if it matches this effect
const QXmlStreamAttributes& attributes = stream.attributes();
for (int i=0;i<attributes.size();i++) {
const QXmlStreamAttribute& attr = attributes.at(i);
if (attr.name() == "name") {
if (get_meta_from_name(attr.value().toString()) == meta) {
// pass off to standard loading function
load(stream);
} else {
QMessageBox::critical(mainWindow,
tr("Load Settings Failed"),
tr("This settings file doesn't match this effect."),
QMessageBox::Ok);
}
break;
}
}
// we've found what we're looking for
break;
}
}
file_handle.close();
update_ui(false);
} else {
QMessageBox::critical(mainWindow,
tr("Load Settings Failed"),
tr("Failed to open \"%1\" for reading.").arg(file),
QMessageBox::Ok);
}
}
update_ui(false);
} else {
QMessageBox::critical(mainWindow,
tr("Load Settings Failed"),
tr("Failed to open \"%1\" for reading.").arg(file),
QMessageBox::Ok);
}
}
}
int Effect::get_index_in_clip() {
@@ -700,6 +658,70 @@ void Effect::save(QXmlStreamWriter& stream) {
}
}
void Effect::load_from_string(const QByteArray &s) {
// clear existing keyframe data
for (int i=0;i<rows.size();i++) {
EffectRow* row = rows.at(i);
row->setKeyframing(false);
for (int j=0;j<row->fieldCount();j++) {
EffectField* field = row->field(j);
field->keyframes.clear();
}
}
// write settings with xml writer
QXmlStreamReader stream(s);
while (!stream.atEnd()) {
stream.readNext();
// find the effect opening tag
if (stream.name() == "effect" && stream.isStartElement()) {
// check the name to see if it matches this effect
const QXmlStreamAttributes& attributes = stream.attributes();
for (int i=0;i<attributes.size();i++) {
const QXmlStreamAttribute& attr = attributes.at(i);
if (attr.name() == "name") {
if (get_meta_from_name(attr.value().toString()) == meta) {
// pass off to standard loading function
load(stream);
} else {
QMessageBox::critical(mainWindow,
tr("Load Settings Failed"),
tr("This settings file doesn't match this effect."),
QMessageBox::Ok);
}
break;
}
}
// we've found what we're looking for
break;
}
}
}
QByteArray Effect::save_to_string() {
QByteArray save_data;
// write settings to string with xml writer
QXmlStreamWriter stream(&save_data);
stream.writeStartDocument();
stream.writeStartElement("effect");
// pass off to standard saving function
save(stream);
stream.writeEndElement(); // effect
stream.writeEndDocument();
return save_data;
}
bool Effect::is_open() {
return isOpen;
}
@@ -1027,21 +1049,21 @@ void Effect::delete_texture() {
}
const EffectMeta* get_meta_from_name(const QString& input) {
int split_index = input.indexOf('/');
QString category;
if (split_index > -1) {
category = input.left(split_index);
}
QString name = input.mid(split_index + 1);
int split_index = input.indexOf('/');
QString category;
if (split_index > -1) {
category = input.left(split_index);
}
QString name = input.mid(split_index + 1);
for (int j=0;j<effects.size();j++) {
if (effects.at(j).name == name
&& (effects.at(j).category == category
|| category.isEmpty())) {
return &effects.at(j);
}
}
return nullptr;
for (int j=0;j<effects.size();j++) {
if (effects.at(j).name == name
&& (effects.at(j).category == category
|| category.isEmpty())) {
return &effects.at(j);
}
}
return nullptr;
}
qint16 mix_audio_sample(qint16 a, qint16 b) {
+5 -2
View File
@@ -174,6 +174,9 @@ public:
virtual void custom_load(QXmlStreamReader& stream);
virtual void save(QXmlStreamWriter& stream);
void load_from_string(const QByteArray &s);
QByteArray save_to_string();
// glsl handling
bool is_open();
void open();
@@ -209,8 +212,8 @@ private slots:
void delete_self();
void move_up();
void move_down();
void save_to_file();
void load_from_file();
void save_to_file();
void load_from_file();
protected:
// glsl effect
QOpenGLShaderProgram* glslProgram;
+34 -16
View File
@@ -3,6 +3,7 @@
#include <QTreeWidgetItem>
#include <QMessageBox>
#include <QCheckBox>
#include <QXmlStreamWriter>
#include "project/clip.h"
#include "project/sequence.h"
@@ -804,22 +805,22 @@ void SetAutoscaleAction::redo() {
}
AddMarkerAction::AddMarkerAction(bool is_sequence, void* s, long t, QString n) :
is_sequence_internal(is_sequence),
target(s),
is_sequence_internal(is_sequence),
target(s),
time(t),
name(n),
old_project_changed(mainWindow->isWindowModified())
{}
void AddMarkerAction::undo() {
QVector<Marker>& markers = is_sequence_internal ?
static_cast<Sequence*>(target)->markers :
static_cast<Clip*>(target)->get_markers();
QVector<Marker>& markers = is_sequence_internal ?
static_cast<Sequence*>(target)->markers :
static_cast<Clip*>(target)->get_markers();
if (index == -1) {
markers.removeLast();
markers.removeLast();
} else {
markers[index].name = old_name;
markers[index].name = old_name;
}
mainWindow->setWindowModified(old_project_changed);
@@ -828,12 +829,12 @@ void AddMarkerAction::undo() {
void AddMarkerAction::redo() {
index = -1;
QVector<Marker>& markers = is_sequence_internal ?
static_cast<Sequence*>(target)->markers :
static_cast<Clip*>(target)->get_markers();
QVector<Marker>& markers = is_sequence_internal ?
static_cast<Sequence*>(target)->markers :
static_cast<Clip*>(target)->get_markers();
for (int i=0;i<markers.size();i++) {
if (markers.at(i).frame == time) {
for (int i=0;i<markers.size();i++) {
if (markers.at(i).frame == time) {
index = i;
break;
}
@@ -842,11 +843,11 @@ void AddMarkerAction::redo() {
if (index == -1) {
Marker m;
m.frame = time;
m.name = name;
markers.append(m);
m.name = name;
markers.append(m);
} else {
old_name = markers.at(index).name;
markers[index].name = name;
old_name = markers.at(index).name;
markers[index].name = name;
}
mainWindow->setWindowModified(true);
@@ -1295,3 +1296,20 @@ void UpdateViewer::undo() {
void UpdateViewer::redo() {
panel_sequence_viewer->viewer_widget->frame_update();
}
SetEffectData::SetEffectData(Effect *e, const QByteArray &s) :
effect(e),
data(s)
{}
void SetEffectData::undo() {
effect->load_from_string(old_data);
old_data.clear();
}
void SetEffectData::redo() {
old_data = effect->save_to_string();
effect->load_from_string(data);
}
+14 -3
View File
@@ -384,12 +384,12 @@ private:
class AddMarkerAction : public QUndoCommand {
public:
AddMarkerAction(bool is_sequence, void* s, long t, QString n);
AddMarkerAction(bool is_sequence, void* s, long t, QString n);
void undo();
void redo();
private:
bool is_sequence_internal;
void* target;
bool is_sequence_internal;
void* target;
long time;
QString name;
QString old_name;
@@ -651,4 +651,15 @@ public:
void redo();
};
class SetEffectData : public QUndoCommand {
public:
SetEffectData(Effect* e, const QByteArray &s);
void undo();
void redo();
private:
Effect* effect;
QByteArray data;
QByteArray old_data;
};
#endif // UNDO_H