basic autorecovery system added

This commit is contained in:
itsmattkc
2018-06-22 10:24:39 -07:00
parent 38ca51cf10
commit 9c4823e90a
8 changed files with 222 additions and 165 deletions
-1
View File
@@ -87,7 +87,6 @@ void PreviewGenerator::run() {
if (fmt_ctx->streams[packet.stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
int dstH = 120;
int dstW = dstH * ((float)temp_frame->width/(float)temp_frame->height);
qDebug() << dstW;
uint8_t* data = new uint8_t[dstW*dstH*3];
sws_ctx = sws_getContext(
+41 -2
View File
@@ -19,9 +19,14 @@
#include <QStyleFactory>
#include <QMessageBox>
#include <QFileDialog>
#include <QStandardPaths>
#include <QTimer>
#define OLIVE_FILE_FILTER "Olive Project (*.ove)"
QString autorecovery_filename;
QTimer autorecovery_timer;
void MainWindow::setup_layout() {
panel_project->show();
panel_effect_controls->show();
@@ -77,10 +82,34 @@ MainWindow::MainWindow(QWidget *parent) :
panel_timeline = new Timeline(this);
setup_layout();
QString data_dir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
if (!data_dir.isEmpty()) {
QDir dir(data_dir);
dir.mkpath(".");
if (dir.exists()) {
autorecovery_filename = data_dir + "/autorecovery.ove";
if (QFile::exists(autorecovery_filename)) {
if (QMessageBox::question(this, "Auto-recovery", "Olive didn't close properly and an autorecovery file was detected. Would you like to open it?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
project_url = autorecovery_filename;
panel_project->load_project();
}
}
autorecovery_timer.setInterval(60000);
QObject::connect(&autorecovery_timer, SIGNAL(timeout()), this, SLOT(autorecover_interval()));
autorecovery_timer.start();
}
}
}
MainWindow::~MainWindow()
{
MainWindow::~MainWindow() {
QString data_dir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
if (!data_dir.isEmpty() && !autorecovery_filename.isEmpty()) {
if (QFile::exists(autorecovery_filename)) {
QFile::remove(autorecovery_filename);
}
}
delete ui;
delete panel_project;
@@ -219,6 +248,16 @@ void MainWindow::on_action_Paste_triggered()
}
}
void MainWindow::autorecover_interval() {
bool old_changed = project_changed;
QString old_filename = project_url;
project_url = autorecovery_filename;
qDebug() << "[INFO] Auto-recovery project saved";
panel_project->save_project();
project_url = old_filename;
project_changed = old_changed;
}
bool MainWindow::save_project_as() {
QString fn = QFileDialog::getSaveFileName(this, "Save Project As...", "", OLIVE_FILE_FILTER);
if (!fn.isEmpty()) {
+2
View File
@@ -105,6 +105,8 @@ private slots:
void on_actionGo_to_Next_Cut_triggered();
void autorecover_interval();
private:
Ui::MainWindow *ui;
void setup_layout();
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.6.2, 2018-06-22T02:31:47. -->
<!-- Written by QtCreator 4.6.2, 2018-06-22T02:52:25. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
+2
View File
@@ -418,6 +418,8 @@ void Project::load_project() {
qDebug() << "[ERROR] Error parsing XML." << stream.error();
}
panel_timeline->redraw_all_clips();
project_changed = false;
}
+1
View File
@@ -12,6 +12,7 @@
TimelineHeader::TimelineHeader(QWidget *parent) : QWidget(parent)
{
dragging = false;
setCursor(Qt::ArrowCursor);
}
void set_playhead(QMouseEvent* event) {
+174 -160
View File
@@ -18,7 +18,8 @@
#include <QMouseEvent>
#include <QObject>
#include <QVariant>
#include <QPointF>
#include <QPoint>
#include <QMenu>
#include <QtMath>
TimelineWidget::TimelineWidget(QWidget *parent) : QWidget(parent)
@@ -28,6 +29,15 @@ TimelineWidget::TimelineWidget(QWidget *parent) : QWidget(parent)
track_height = 80;
setAcceptDrops(true);
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu(const QPoint&)));
}
void TimelineWidget::show_context_menu(const QPoint& pos) {
QMenu menu(this);
menu.addAction("heck!");
menu.exec(mapToGlobal(pos));
}
bool same_sign(int a, int b) {
@@ -156,185 +166,189 @@ void TimelineWidget::mouseDoubleClickEvent(QMouseEvent *event) {
}
void TimelineWidget::mousePressEvent(QMouseEvent *event) {
if (panel_timeline->tool == TIMELINE_TOOL_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR) {
panel_timeline->drag_frame_start = panel_timeline->cursor_frame;
panel_timeline->drag_track_start = panel_timeline->cursor_track;
} else {
QPoint pos = event->pos();
panel_timeline->drag_frame_start = panel_timeline->getFrameFromScreenPoint(pos.x());
panel_timeline->drag_track_start = getTrackFromScreenPoint(pos.y());
}
if (event->button() == Qt::LeftButton) {
if (panel_timeline->tool == TIMELINE_TOOL_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR) {
panel_timeline->drag_frame_start = panel_timeline->cursor_frame;
panel_timeline->drag_track_start = panel_timeline->cursor_track;
} else {
QPoint pos = event->pos();
panel_timeline->drag_frame_start = panel_timeline->getFrameFromScreenPoint(pos.x());
panel_timeline->drag_track_start = getTrackFromScreenPoint(pos.y());
}
int clip_index = panel_timeline->trim_target;
if (clip_index == -1) clip_index = getClipIndexFromCoords(panel_timeline->drag_frame_start, panel_timeline->drag_track_start);
int clip_index = panel_timeline->trim_target;
if (clip_index == -1) clip_index = getClipIndexFromCoords(panel_timeline->drag_frame_start, panel_timeline->drag_track_start);
switch (panel_timeline->tool) {
case TIMELINE_TOOL_POINTER:
case TIMELINE_TOOL_RIPPLE:
case TIMELINE_TOOL_SLIP:
{
if (clip_index >= 0) {
if (panel_timeline->is_clip_selected(sequence->get_clip(clip_index))) {
// TODO if shift is down, deselect it
} else {
// if "shift" is not down
if (!(event->modifiers() & Qt::ShiftModifier)) {
panel_timeline->selections.clear();
}
switch (panel_timeline->tool) {
case TIMELINE_TOOL_POINTER:
case TIMELINE_TOOL_RIPPLE:
case TIMELINE_TOOL_SLIP:
{
if (clip_index >= 0) {
if (panel_timeline->is_clip_selected(sequence->get_clip(clip_index))) {
// TODO if shift is down, deselect it
} else {
// if "shift" is not down
if (!(event->modifiers() & Qt::ShiftModifier)) {
panel_timeline->selections.clear();
}
Clip* clip = sequence->get_clip(clip_index);
panel_timeline->selections.append({clip->timeline_in, clip->timeline_out, clip->track});
Clip* clip = sequence->get_clip(clip_index);
panel_timeline->selections.append({clip->timeline_in, clip->timeline_out, clip->track});
// if alt is not down, select links
if (!(event->modifiers() & Qt::AltModifier)) {
for (int i=0;i<clip->linked.size();i++) {
Clip* link = clip->linked.at(i);
if (!panel_timeline->is_clip_selected(link)) {
panel_timeline->selections.append({link->timeline_in, link->timeline_out, link->track});
// if alt is not down, select links
if (!(event->modifiers() & Qt::AltModifier)) {
for (int i=0;i<clip->linked.size();i++) {
Clip* link = clip->linked.at(i);
if (!panel_timeline->is_clip_selected(link)) {
panel_timeline->selections.append({link->timeline_in, link->timeline_out, link->track});
}
}
}
}
}
panel_timeline->moving_init = true;
} else {
panel_timeline->selections.clear();
}
panel_timeline->repaint_timeline();
}
break;
case TIMELINE_TOOL_EDIT:
panel_timeline->seek(panel_timeline->drag_frame_start);
panel_timeline->selecting = true;
break;
case TIMELINE_TOOL_RAZOR:
{
if (clip_index >= 0) {
panel_timeline->split_clip_and_relink(sequence->get_clip(clip_index), panel_timeline->drag_frame_start, !(event->modifiers() & Qt::AltModifier));
}
panel_timeline->splitting = true;
panel_timeline->redraw_all_clips();
}
break;
}
panel_timeline->moving_init = true;
} else {
panel_timeline->selections.clear();
}
panel_timeline->repaint_timeline();
}
break;
case TIMELINE_TOOL_EDIT:
panel_timeline->seek(panel_timeline->drag_frame_start);
panel_timeline->selecting = true;
break;
case TIMELINE_TOOL_RAZOR:
{
if (clip_index >= 0) {
panel_timeline->split_clip_and_relink(sequence->get_clip(clip_index), panel_timeline->drag_frame_start, !(event->modifiers() & Qt::AltModifier));
}
panel_timeline->splitting = true;
panel_timeline->redraw_all_clips();
}
break;
}
}
}
void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) {
if (panel_timeline->moving_proc) {
if (event->modifiers() & Qt::AltModifier) { // if holding alt, duplicate rather than move
// duplicate clips
QVector<Clip*> copy_clips;
QVector<Selection> delete_areas;
for (int i=0;i<panel_timeline->ghosts.size();i++) {
const Ghost& g = panel_timeline->ghosts.at(i);
if (event->button() == Qt::LeftButton) {
if (panel_timeline->moving_proc) {
if (event->modifiers() & Qt::AltModifier) { // if holding alt, duplicate rather than move
// duplicate clips
QVector<Clip*> copy_clips;
QVector<Selection> delete_areas;
for (int i=0;i<panel_timeline->ghosts.size();i++) {
const Ghost& g = panel_timeline->ghosts.at(i);
Clip* c = g.clip->copy();
Clip* c = g.clip->copy();
c->timeline_in = g.in;
c->timeline_out = g.out;
c->track = g.track;
c->timeline_in = g.in;
c->timeline_out = g.out;
c->track = g.track;
copy_clips.append(c);
}
panel_timeline->delete_areas_and_relink(delete_areas);
for (int i=0;i<copy_clips.size();i++) {
// step 2 - delete anything that exists in area that clip is moving to
sequence->add_clip(copy_clips.at(i));
}
} else {
// move clips
// TODO can we do this better than 3 consecutive for loops?
for (int i=0;i<panel_timeline->ghosts.size();i++) {
// step 1 - set clips that are moving to "undeletable" (to avoid step 2 deleting any part of them)
panel_timeline->ghosts[i].clip->undeletable = true;
}
// step 2 - delete areas
QVector<Selection> delete_areas;
for (int i=0;i<panel_timeline->ghosts.size();i++) {
const Ghost& g = panel_timeline->ghosts.at(i);
if (panel_timeline->tool == TIMELINE_TOOL_POINTER) {
copy_clips.append(c);
}
panel_timeline->delete_areas_and_relink(delete_areas);
for (int i=0;i<copy_clips.size();i++) {
// step 2 - delete anything that exists in area that clip is moving to
// note: ripples are non-destructive so this is pointer-tool exclusive
delete_areas.append({g.in, g.out, g.track});
sequence->add_clip(copy_clips.at(i));
}
} else {
// move clips
// TODO can we do this better than 3 consecutive for loops?
for (int i=0;i<panel_timeline->ghosts.size();i++) {
// step 1 - set clips that are moving to "undeletable" (to avoid step 2 deleting any part of them)
panel_timeline->ghosts[i].clip->undeletable = true;
}
// step 2 - delete areas
QVector<Selection> delete_areas;
for (int i=0;i<panel_timeline->ghosts.size();i++) {
const Ghost& g = panel_timeline->ghosts.at(i);
if (panel_timeline->tool == TIMELINE_TOOL_POINTER) {
// step 2 - delete anything that exists in area that clip is moving to
// note: ripples are non-destructive so this is pointer-tool exclusive
delete_areas.append({g.in, g.out, g.track});
}
}
panel_timeline->delete_areas_and_relink(delete_areas);
for (int i=0;i<panel_timeline->ghosts.size();i++) {
Ghost& g = panel_timeline->ghosts[i];
// step 3 - move clips
g.clip->timeline_in = g.in;
g.clip->timeline_out = g.out;
g.clip->track = g.track;
g.clip->clip_in = g.clip_in;
}
for (int i=0;i<panel_timeline->ghosts.size();i++) {
// step 4 - set clips back to deletable
panel_timeline->ghosts[i].clip->undeletable = false;
}
}
panel_timeline->delete_areas_and_relink(delete_areas);
for (int i=0;i<panel_timeline->ghosts.size();i++) {
Ghost& g = panel_timeline->ghosts[i];
// step 3 - move clips
g.clip->timeline_in = g.in;
g.clip->timeline_out = g.out;
g.clip->track = g.track;
g.clip->clip_in = g.clip_in;
}
for (int i=0;i<panel_timeline->ghosts.size();i++) {
// step 4 - set clips back to deletable
panel_timeline->ghosts[i].clip->undeletable = false;
}
}
// ripple ops
if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) {
long ripple_length, ripple_point;
if (panel_timeline->trim_in) {
ripple_length = panel_timeline->ghosts.at(0).old_in - panel_timeline->ghosts.at(0).in;
ripple_point = (ripple_length < 0) ? panel_timeline->ghosts.at(0).old_in : panel_timeline->ghosts.at(0).in;
} else {
ripple_length = panel_timeline->ghosts.at(0).old_out - panel_timeline->ghosts.at(0).out;
ripple_point = (ripple_length < 0) ? panel_timeline->ghosts.at(0).old_out : panel_timeline->ghosts.at(0).out;
}
for (int i=0;i<panel_timeline->ghosts.size();i++) {
long comp_point;
if (panel_timeline->trim_in) {
comp_point = (ripple_length < 0) ? panel_timeline->ghosts.at(i).old_in : panel_timeline->ghosts.at(i).in;
} else {
comp_point = (ripple_length < 0) ? panel_timeline->ghosts.at(i).old_out : panel_timeline->ghosts.at(i).out;
}
if (ripple_point > comp_point) ripple_point = comp_point;
}
if (panel_timeline->trim_in) {
panel_timeline->ripple(ripple_point, ripple_length);
} else {
panel_timeline->ripple(ripple_point, -ripple_length);
}
}
// ripple ops
if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) {
long ripple_length, ripple_point;
if (panel_timeline->trim_in) {
ripple_length = panel_timeline->ghosts.at(0).old_in - panel_timeline->ghosts.at(0).in;
ripple_point = (ripple_length < 0) ? panel_timeline->ghosts.at(0).old_in : panel_timeline->ghosts.at(0).in;
} else {
ripple_length = panel_timeline->ghosts.at(0).old_out - panel_timeline->ghosts.at(0).out;
ripple_point = (ripple_length < 0) ? panel_timeline->ghosts.at(0).old_out : panel_timeline->ghosts.at(0).out;
}
for (int i=0;i<panel_timeline->ghosts.size();i++) {
long comp_point;
if (panel_timeline->trim_in) {
comp_point = (ripple_length < 0) ? panel_timeline->ghosts.at(i).old_in : panel_timeline->ghosts.at(i).in;
} else {
comp_point = (ripple_length < 0) ? panel_timeline->ghosts.at(i).old_out : panel_timeline->ghosts.at(i).out;
}
if (ripple_point > comp_point) ripple_point = comp_point;
}
if (panel_timeline->trim_in) {
panel_timeline->ripple(ripple_point, ripple_length);
} else {
panel_timeline->ripple(ripple_point, -ripple_length);
}
}
panel_timeline->redraw_all_clips();
}
panel_timeline->redraw_all_clips();
}
// destroy all ghosts
panel_timeline->ghosts.clear();
// destroy all ghosts
panel_timeline->ghosts.clear();
panel_timeline->selecting = false;
panel_timeline->moving_proc = false;
panel_timeline->moving_init = false;
panel_timeline->splitting = false;
panel_timeline->snapped = false;
pre_clips.clear();
post_clips.clear();
panel_timeline->selecting = false;
panel_timeline->moving_proc = false;
panel_timeline->moving_init = false;
panel_timeline->splitting = false;
panel_timeline->snapped = false;
pre_clips.clear();
post_clips.clear();
// find out how many clips are selected
bool single_select = false;
int selected_clip = 0;
for (int i=0;i<sequence->clip_count();i++) {
if (panel_timeline->is_clip_selected(sequence->get_clip(i))) {
if (!single_select) {
// found ONE selected clip
selected_clip = i;
single_select = true;
} else {
// more than one clip is selected
single_select = false;
break;
}
}
}
if (single_select) {
panel_effect_controls->set_clip(sequence->get_clip(selected_clip));
} else {
panel_effect_controls->set_clip(NULL);
}
// find out how many clips are selected
bool single_select = false;
int selected_clip = 0;
for (int i=0;i<sequence->clip_count();i++) {
if (panel_timeline->is_clip_selected(sequence->get_clip(i))) {
if (!single_select) {
// found ONE selected clip
selected_clip = i;
single_select = true;
} else {
// more than one clip is selected
single_select = false;
break;
}
}
}
if (single_select) {
panel_effect_controls->set_clip(sequence->get_clip(selected_clip));
} else {
panel_effect_controls->set_clip(NULL);
}
}
}
void TimelineWidget::init_ghosts() {
@@ -762,7 +776,7 @@ void TimelineWidget::redraw_clips() {
// Draw clips
int panel_width = panel_timeline->getScreenPointFromFrame(sequence->getEndFrame()) + 100;
if (minimumWidth() != panel_width) {
if (minimumWidth() != panel_width || clip_pixmap.height() != height()) {
setMinimumWidth(panel_width);
clip_pixmap = QPixmap(panel_width, height());
}
+1 -1
View File
@@ -53,7 +53,7 @@ signals:
public slots:
private slots:
void show_context_menu(const QPoint& pos);
};
#endif // TIMELINEWIDGET_H