fixed a bunch of multithreaded loading issues and #174
This commit is contained in:
@@ -39,6 +39,7 @@ LoadDialog::LoadDialog(QWidget *parent, bool autorecovery) : QDialog(parent) {
|
||||
|
||||
lt = new LoadThread(this, autorecovery);
|
||||
QObject::connect(lt, SIGNAL(success()), this, SLOT(thread_done()));
|
||||
QObject::connect(lt, SIGNAL(error()), this, SLOT(die()));
|
||||
QObject::connect(lt, SIGNAL(report_progress(int)), bar, SLOT(setValue(int)));
|
||||
lt->start();
|
||||
}
|
||||
@@ -46,8 +47,12 @@ LoadDialog::LoadDialog(QWidget *parent, bool autorecovery) : QDialog(parent) {
|
||||
void LoadDialog::cancel() {
|
||||
lt->cancel();
|
||||
lt->wait();
|
||||
mainWindow->new_project();
|
||||
reject();
|
||||
die();
|
||||
}
|
||||
|
||||
void LoadDialog::die() {
|
||||
mainWindow->new_project();
|
||||
reject();
|
||||
}
|
||||
|
||||
void LoadDialog::thread_done() {
|
||||
|
||||
@@ -17,6 +17,7 @@ public:
|
||||
LoadDialog(QWidget* parent, bool autorecovery);
|
||||
private slots:
|
||||
void cancel();
|
||||
void die();
|
||||
void thread_done();
|
||||
private:
|
||||
QProgressBar* bar;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "clipboard.h"
|
||||
|
||||
#include "project/clip.h"
|
||||
#include "project/effect.h"
|
||||
|
||||
int clipboard_type = CLIPBOARD_TYPE_CLIP;
|
||||
QVector<void*> clipboard;
|
||||
|
||||
+36
-24
@@ -31,6 +31,7 @@ struct TransitionData {
|
||||
LoadThread::LoadThread(LoadDialog* l, bool a) : ld(l), autorecovery(a), cancelled(false) {
|
||||
connect(this, SIGNAL(finished()), this, SLOT(deleteLater()));
|
||||
connect(this, SIGNAL(success()), this, SLOT(success_func()));
|
||||
connect(this, SIGNAL(error()), this, SLOT(error_func()));
|
||||
connect(this, SIGNAL(start_create_effect_ui(QXmlStreamReader*, Clip*, int, const EffectMeta*, long, bool)), this, SLOT(create_effect_ui(QXmlStreamReader*, Clip*, int, const EffectMeta*, long, bool)));
|
||||
}
|
||||
|
||||
@@ -572,23 +573,7 @@ void LoadThread::run() {
|
||||
cont = load_worker(file, stream, LOAD_TYPE_VERSION);
|
||||
|
||||
// find project's internal URL
|
||||
cont = load_worker(file, stream, LOAD_TYPE_URL);
|
||||
if (autorecovery) {
|
||||
QString orig_filename = internal_proj_url;
|
||||
int insert_index = internal_proj_url.lastIndexOf(".ove", -1, Qt::CaseInsensitive);
|
||||
if (insert_index == -1) insert_index = internal_proj_url.length();
|
||||
int counter = 1;
|
||||
while (QFileInfo::exists(orig_filename)) {
|
||||
orig_filename = internal_proj_url;
|
||||
QString recover_text = "recovered";
|
||||
if (counter > 1) {
|
||||
recover_text += " " + QString::number(counter);
|
||||
}
|
||||
orig_filename.insert(insert_index, " (" + recover_text + ")");
|
||||
counter++;
|
||||
}
|
||||
mainWindow->updateTitle(orig_filename);
|
||||
}
|
||||
cont = load_worker(file, stream, LOAD_TYPE_URL);
|
||||
|
||||
// load folders first
|
||||
if (cont) {
|
||||
@@ -614,11 +599,14 @@ void LoadThread::run() {
|
||||
|
||||
if (!cancelled) {
|
||||
if (!cont) {
|
||||
if (show_err) QMessageBox::critical(mainWindow, "Project Load Error", "Error loading project: " + error_str, QMessageBox::Ok);
|
||||
xml_error = false;
|
||||
if (show_err) emit error();
|
||||
} else if (stream.hasError()) {
|
||||
dout << "[ERROR] Error parsing XML." << stream.errorString();
|
||||
QMessageBox::critical(mainWindow, "XML Parsing Error", "Couldn't load '" + project_url + "'. " + stream.errorString(), QMessageBox::Ok);
|
||||
error_str = stream.errorString();
|
||||
xml_error = true;
|
||||
emit error();
|
||||
cont = false;
|
||||
|
||||
} else {
|
||||
// attach nested sequence clips to their sequences
|
||||
for (int i=0;i<loaded_clips.size();i++) {
|
||||
@@ -641,9 +629,7 @@ void LoadThread::run() {
|
||||
for (int i=0;i<loaded_media_items.size();i++) {
|
||||
panel_project->start_preview_generator(loaded_media_items.at(i), true);
|
||||
}
|
||||
} else {
|
||||
mainWindow->new_project();
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
@@ -652,10 +638,36 @@ void LoadThread::run() {
|
||||
|
||||
void LoadThread::cancel() {
|
||||
waitCond.wakeAll();
|
||||
cancelled = true;
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
void LoadThread::error_func() {
|
||||
if (xml_error) {
|
||||
dout << "[ERROR] Error parsing XML." << error_str;
|
||||
QMessageBox::critical(mainWindow, "XML Parsing Error", "Couldn't load '" + project_url + "'. " + error_str, QMessageBox::Ok);
|
||||
} else {
|
||||
QMessageBox::critical(mainWindow, "Project Load Error", "Error loading project: " + error_str, QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
|
||||
void LoadThread::success_func() {
|
||||
if (autorecovery) {
|
||||
QString orig_filename = internal_proj_url;
|
||||
int insert_index = internal_proj_url.lastIndexOf(".ove", -1, Qt::CaseInsensitive);
|
||||
if (insert_index == -1) insert_index = internal_proj_url.length();
|
||||
int counter = 1;
|
||||
while (QFileInfo::exists(orig_filename)) {
|
||||
orig_filename = internal_proj_url;
|
||||
QString recover_text = "recovered";
|
||||
if (counter > 1) {
|
||||
recover_text += " " + QString::number(counter);
|
||||
}
|
||||
orig_filename.insert(insert_index, " (" + recover_text + ")");
|
||||
counter++;
|
||||
}
|
||||
mainWindow->updateTitle(orig_filename);
|
||||
}
|
||||
|
||||
mainWindow->setWindowModified(autorecovery);
|
||||
if (open_seq != NULL) set_sequence(open_seq);
|
||||
update_ui(false);
|
||||
|
||||
+4
-1
@@ -12,7 +12,7 @@ struct Footage;
|
||||
struct Clip;
|
||||
struct Sequence;
|
||||
class LoadDialog;
|
||||
class EffectMeta;
|
||||
struct EffectMeta;
|
||||
|
||||
class LoadThread : public QThread
|
||||
{
|
||||
@@ -23,9 +23,11 @@ public:
|
||||
void cancel();
|
||||
signals:
|
||||
void success();
|
||||
void error();
|
||||
void start_create_effect_ui(QXmlStreamReader* stream, Clip* c, int type, const EffectMeta* meta, long effect_length, bool effect_enabled);
|
||||
void report_progress(int p);
|
||||
private slots:
|
||||
void error_func();
|
||||
void success_func();
|
||||
void create_effect_ui(QXmlStreamReader* stream, Clip* c, int type, const EffectMeta* meta, long effect_length, bool effect_enabled);
|
||||
private:
|
||||
@@ -61,6 +63,7 @@ private:
|
||||
QWaitCondition waitCond;
|
||||
|
||||
bool cancelled;
|
||||
bool xml_error;
|
||||
};
|
||||
|
||||
#endif // LOADTHREAD_H
|
||||
|
||||
+4
-2
@@ -227,6 +227,9 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow() {
|
||||
panel_sequence_viewer->viewer_widget->delete_function();
|
||||
panel_footage_viewer->viewer_widget->delete_function();
|
||||
|
||||
set_sequence(NULL);
|
||||
|
||||
QString data_dir = get_data_path();
|
||||
@@ -439,8 +442,7 @@ void MainWindow::new_project() {
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionSplit_at_Playhead_triggered()
|
||||
{
|
||||
void MainWindow::on_actionSplit_at_Playhead_triggered() {
|
||||
if (panel_timeline->focused()) {
|
||||
panel_timeline->split_at_playhead();
|
||||
}
|
||||
|
||||
@@ -201,6 +201,8 @@ void EffectControls::show_effect_menu(int type, int subtype) {
|
||||
|
||||
void EffectControls::clear_effects(bool clear_cache) {
|
||||
// clear existing clips
|
||||
deselect_all_effects(NULL);
|
||||
|
||||
QVBoxLayout* video_layout = static_cast<QVBoxLayout*>(ui->video_effect_area->layout());
|
||||
QVBoxLayout* audio_layout = static_cast<QVBoxLayout*>(ui->audio_effect_area->layout());
|
||||
QLayoutItem* item;
|
||||
|
||||
+1
-1
@@ -125,7 +125,7 @@ QDockWidget *get_focused_panel() {
|
||||
if (w == NULL) {
|
||||
if (panel_project->is_focused()) {
|
||||
w = panel_project;
|
||||
} else if (panel_effect_controls->keyframe_focus()) {
|
||||
} else if (panel_effect_controls->keyframe_focus() || panel_effect_controls->is_focused()) {
|
||||
w = panel_effect_controls;
|
||||
} else if (panel_sequence_viewer->is_focused()) {
|
||||
w = panel_sequence_viewer;
|
||||
|
||||
+12
-10
@@ -859,16 +859,18 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only,
|
||||
stream.writeAttribute("maintainpitch", QString::number(c->maintain_audio_pitch));
|
||||
stream.writeAttribute("reverse", QString::number(c->reverse));
|
||||
|
||||
stream.writeAttribute("type", QString::number(c->media->get_type()));
|
||||
switch (c->media->get_type()) {
|
||||
case MEDIA_TYPE_FOOTAGE:
|
||||
stream.writeAttribute("media", QString::number(c->media->to_footage()->save_id));
|
||||
stream.writeAttribute("stream", QString::number(c->media_stream));
|
||||
break;
|
||||
case MEDIA_TYPE_SEQUENCE:
|
||||
stream.writeAttribute("sequence", QString::number(c->media->to_sequence()->save_id));
|
||||
break;
|
||||
}
|
||||
if (c->media != NULL) {
|
||||
stream.writeAttribute("type", QString::number(c->media->get_type()));
|
||||
switch (c->media->get_type()) {
|
||||
case MEDIA_TYPE_FOOTAGE:
|
||||
stream.writeAttribute("media", QString::number(c->media->to_footage()->save_id));
|
||||
stream.writeAttribute("stream", QString::number(c->media_stream));
|
||||
break;
|
||||
case MEDIA_TYPE_SEQUENCE:
|
||||
stream.writeAttribute("sequence", QString::number(c->media->to_sequence()->save_id));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stream.writeStartElement("linked"); // linked
|
||||
for (int k=0;k<c->linked.size();k++) {
|
||||
|
||||
@@ -87,7 +87,8 @@ void close_clip(Clip* clip) {
|
||||
} else {
|
||||
if (clip->media != NULL && clip->media->get_type() == MEDIA_TYPE_SEQUENCE)
|
||||
closeActiveClips(clip->media->to_sequence(), false);
|
||||
clip->open = false;
|
||||
|
||||
clip->open = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,7 +343,7 @@ void closeActiveClips(Sequence *s, bool wait) {
|
||||
if (c != NULL) {
|
||||
if (c->media != NULL && c->media->get_type() == MEDIA_TYPE_SEQUENCE) {
|
||||
closeActiveClips(c->media->to_sequence(), wait);
|
||||
close_clip(c);
|
||||
if (c->open) close_clip(c);
|
||||
} else if (clip_uses_cacher(c) && c->open) {
|
||||
close_clip(c);
|
||||
if (c->multithreaded && wait) c->cacher->wait();
|
||||
|
||||
@@ -210,6 +210,7 @@ double Clip::getMediaFrameRate() {
|
||||
if (!qIsNaN(rate)) return rate;
|
||||
}
|
||||
if (sequence != NULL) return sequence->frame_rate;
|
||||
return qSNaN();
|
||||
}
|
||||
|
||||
void Clip::recalculateMaxLength() {
|
||||
|
||||
+2
-3
@@ -432,7 +432,7 @@ Effect::~Effect() {
|
||||
close();
|
||||
}
|
||||
|
||||
delete container;
|
||||
delete container;
|
||||
|
||||
for (int i=0;i<rows.size();i++) {
|
||||
delete rows.at(i);
|
||||
@@ -750,11 +750,11 @@ void Effect::close() {
|
||||
if (!isOpen) {
|
||||
dout << "[WARNING] Tried to close an effect that was already closed";
|
||||
}
|
||||
delete_texture();
|
||||
if (glslProgram != NULL) {
|
||||
delete glslProgram;
|
||||
glslProgram = NULL;
|
||||
}
|
||||
delete_texture();
|
||||
isOpen = false;
|
||||
}
|
||||
|
||||
@@ -991,7 +991,6 @@ bool Effect::valueHasChanged(double timecode) {
|
||||
|
||||
void Effect::delete_texture() {
|
||||
if (texture != NULL) {
|
||||
texture->destroy();
|
||||
delete texture;
|
||||
texture = NULL;
|
||||
}
|
||||
|
||||
+2
-2
@@ -183,8 +183,8 @@ const QString &Media::get_name() {
|
||||
switch (type) {
|
||||
case MEDIA_TYPE_FOOTAGE: return to_footage()->name;
|
||||
case MEDIA_TYPE_SEQUENCE: return to_sequence()->name;
|
||||
case MEDIA_TYPE_FOLDER: return folder_name;
|
||||
}
|
||||
default: return folder_name;
|
||||
}
|
||||
}
|
||||
|
||||
void Media::set_name(const QString &n) {
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <QWidget>
|
||||
#include <QPainter>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
CollapsibleWidget::CollapsibleWidget(QWidget* parent) : QWidget(parent) {
|
||||
selected = false;
|
||||
|
||||
@@ -48,7 +50,7 @@ void CollapsibleWidget::header_click(bool s, bool deselect) {
|
||||
selected = s;
|
||||
title_bar->selected = s;
|
||||
if (s) {
|
||||
QPalette p = palette();
|
||||
QPalette p = title_bar->palette();
|
||||
p.setColor(QPalette::Background, QColor(255, 255, 255, 64));
|
||||
title_bar->setPalette(p);
|
||||
} else {
|
||||
|
||||
@@ -1237,7 +1237,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) {
|
||||
if (g.clip != -1) c = sequence->clips.at(g.clip);
|
||||
|
||||
FootageStream* ms = NULL;
|
||||
if (g.clip != -1 && c->media->get_type() == MEDIA_TYPE_FOOTAGE) {
|
||||
if (g.clip != -1 && c->media != NULL && c->media->get_type() == MEDIA_TYPE_FOOTAGE) {
|
||||
ms = c->media->to_footage()->get_stream_from_file_index(c->track < 0, c->media_stream);
|
||||
}
|
||||
|
||||
@@ -1277,7 +1277,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) {
|
||||
if (validator < 1) frame_diff += (1 - validator);
|
||||
|
||||
// prevent clip length exceeding media length
|
||||
if (c->media->get_type() == MEDIA_TYPE_SEQUENCE
|
||||
if ((c->media != NULL && c->media->get_type() == MEDIA_TYPE_SEQUENCE)
|
||||
|| (ms != NULL && !ms->infinite_length)) {
|
||||
validator = g.old_clip_in + g.ghost_length + frame_diff;
|
||||
if (validator > g.media_length) frame_diff -= validator - g.media_length;
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
|
||||
|
||||
void ViewerWidget::delete_function() {
|
||||
// destroy all textures as well
|
||||
if (viewer->seq != NULL) {
|
||||
if (viewer->seq != NULL) {
|
||||
makeCurrent();
|
||||
closeActiveClips(viewer->seq, true);
|
||||
doneCurrent();
|
||||
|
||||
Reference in New Issue
Block a user