fully implemented saving/loading effect data to file, fixes #418
This commit is contained in:
+119
-97
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user