From 5afd135796fdfbbf59f1e7910c9adcb816ea316b Mon Sep 17 00:00:00 2001 From: Jonathan Noble Date: Sat, 19 Jan 2019 15:30:35 +0000 Subject: [PATCH 01/30] Fix memory leak from using libavcodec api (cherry picked from commit 8c7eb8997660a70e1e58a4f89a82574931195e63) Sequence class encapsulation work. Memory leak fixes work (cherry picked from commit 7caaa778697ea2a84162f4ce523be8b6cef79647) --- io/previewgenerator.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/io/previewgenerator.cpp b/io/previewgenerator.cpp index 01ea6e548..621a6b3ff 100644 --- a/io/previewgenerator.cpp +++ b/io/previewgenerator.cpp @@ -1,4 +1,4 @@ -#include "previewgenerator.h" +#include "previewgenerator.h" #include "project/media.h" #include "project/footage.h" @@ -277,7 +277,7 @@ void PreviewGenerator::generate_waveform() { if (!s->preview_done) { int dstH = 120; int dstW = dstH * ((float)temp_frame->width/(float)temp_frame->height); - uint8_t* data = new uint8_t[dstW*dstH*4]; + uint8_t* imgData = new uint8_t[dstW*dstH*4]; sws_ctx = sws_getContext( temp_frame->width, @@ -294,9 +294,9 @@ void PreviewGenerator::generate_waveform() { int linesize[AV_NUM_DATA_POINTERS]; linesize[0] = dstW*4; - sws_scale(sws_ctx, temp_frame->data, temp_frame->linesize, 0, temp_frame->height, &data, linesize); + sws_scale(sws_ctx, temp_frame->data, temp_frame->linesize, 0, temp_frame->height, &imgData, linesize); - s->video_preview = QImage(data, dstW, dstH, linesize[0], QImage::Format_RGBA8888); + s->video_preview = QImage(imgData, dstW, dstH, linesize[0], QImage::Format_RGBA8888); s->make_square_thumb(); // is video interlaced? @@ -311,6 +311,8 @@ void PreviewGenerator::generate_waveform() { avcodec_close(codec_ctx[packet->stream_index]); codec_ctx[packet->stream_index] = nullptr; } + + delete[] imgData; } media_lengths[packet->stream_index]++; } else if (fmt_ctx->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { @@ -415,7 +417,10 @@ void PreviewGenerator::generate_waveform() { finalize_media(); } delete [] media_lengths; - delete [] codec_ctx; + + if (codec_ctx != NULL) { + avcodec_free_context(codec_ctx); + } } QString PreviewGenerator::get_thumbnail_path(const QString& hash, const FootageStream& ms) { From 52c2fee1420aaff7d1b21c1ae78f0426febf1240 Mon Sep 17 00:00:00 2001 From: Jonathan Noble Date: Fri, 25 Jan 2019 23:33:00 +0000 Subject: [PATCH 02/30] Fixed the use of float as loop counter --- ui/renderfunctions.cpp | 774 +++++++++++++++++++++-------------------- 1 file changed, 389 insertions(+), 385 deletions(-) diff --git a/ui/renderfunctions.cpp b/ui/renderfunctions.cpp index bbab2bd2b..efa206721 100644 --- a/ui/renderfunctions.cpp +++ b/ui/renderfunctions.cpp @@ -25,468 +25,472 @@ #include "panels/viewer.h" extern "C" { - #include +#include } //#define GL_DEFAULT_BLEND glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE) #define GL_DEFAULT_BLEND glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE) GLuint draw_clip(QOpenGLContext* ctx, QOpenGLFramebufferObject* fbo, GLuint texture, bool clear) { - glPushMatrix(); - glLoadIdentity(); - glOrtho(0, 1, 0, 1, -1, 1); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, 1, 0, 1, -1, 1); - GLint current_fbo = 0; - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); + GLint current_fbo = 0; + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); - fbo->bind(); + fbo->bind(); - if (clear) glClear(GL_COLOR_BUFFER_BIT); + if (clear) glClear(GL_COLOR_BUFFER_BIT); - // get current blend mode - GLint src_rgb, src_alpha, dst_rgb, dst_alpha; - glGetIntegerv(GL_BLEND_SRC_RGB, &src_rgb); - glGetIntegerv(GL_BLEND_SRC_ALPHA, &src_alpha); - glGetIntegerv(GL_BLEND_DST_RGB, &dst_rgb); - glGetIntegerv(GL_BLEND_DST_ALPHA, &dst_alpha); + // get current blend mode + GLint src_rgb, src_alpha, dst_rgb, dst_alpha; + glGetIntegerv(GL_BLEND_SRC_RGB, &src_rgb); + glGetIntegerv(GL_BLEND_SRC_ALPHA, &src_alpha); + glGetIntegerv(GL_BLEND_DST_RGB, &dst_rgb); + glGetIntegerv(GL_BLEND_DST_ALPHA, &dst_alpha); - ctx->functions()->GL_DEFAULT_BLEND; + ctx->functions()->GL_DEFAULT_BLEND; - glBindTexture(GL_TEXTURE_2D, texture); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); // top left - glVertex2f(0, 0); // top left - glTexCoord2f(1, 0); // top right - glVertex2f(1, 0); // top right - glTexCoord2f(1, 1); // bottom right - glVertex2f(1, 1); // bottom right - glTexCoord2f(0, 1); // bottom left - glVertex2f(0, 1); // bottom left - glEnd(); - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_2D, texture); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); // top left + glVertex2f(0, 0); // top left + glTexCoord2f(1, 0); // top right + glVertex2f(1, 0); // top right + glTexCoord2f(1, 1); // bottom right + glVertex2f(1, 1); // bottom right + glTexCoord2f(0, 1); // bottom left + glVertex2f(0, 1); // bottom left + glEnd(); + glBindTexture(GL_TEXTURE_2D, 0); -// fbo->release(); - ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); + // fbo->release(); + ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); - // restore previous blendFunc - ctx->functions()->glBlendFuncSeparate(src_rgb, dst_rgb, src_alpha, dst_alpha); + // restore previous blendFunc + ctx->functions()->glBlendFuncSeparate(src_rgb, dst_rgb, src_alpha, dst_alpha); - //if (default_fbo != nullptr) default_fbo->bind(); + //if (default_fbo != nullptr) default_fbo->bind(); - glPopMatrix(); - return fbo->texture(); + glPopMatrix(); + return fbo->texture(); } void process_effect(QOpenGLContext* ctx, - Clip* c, - Effect* e, - double timecode, - GLTextureCoords& coords, - GLuint& composite_texture, - bool& fbo_switcher, - bool& texture_failed, - int data) { - if (e->is_enabled()) { - if (e->enable_coords) { - e->process_coords(timecode, coords, data); - } - if ((e->enable_shader && shaders_are_enabled) || e->enable_superimpose) { - e->startEffect(); - if ((e->enable_shader && shaders_are_enabled) && e->is_glsl_linked()) { - e->process_shader(timecode, coords); - composite_texture = draw_clip(ctx, c->fbo[fbo_switcher], composite_texture, true); - fbo_switcher = !fbo_switcher; - } - if (e->enable_superimpose) { - GLuint superimpose_texture = e->process_superimpose(timecode); - if (superimpose_texture == 0) { - qWarning() << "Superimpose texture was nullptr, retrying..."; - texture_failed = true; - } else { - composite_texture = draw_clip(ctx, c->fbo[!fbo_switcher], superimpose_texture, false); - } - } - e->endEffect(); - } - } + Clip* c, + Effect* e, + double timecode, + GLTextureCoords& coords, + GLuint& composite_texture, + bool& fbo_switcher, + bool& texture_failed, + int data) { + if (e->is_enabled()) { + if (e->enable_coords) { + e->process_coords(timecode, coords, data); + } + if ((e->enable_shader && shaders_are_enabled) || e->enable_superimpose) { + e->startEffect(); + if ((e->enable_shader && shaders_are_enabled) && e->is_glsl_linked()) { + e->process_shader(timecode, coords); + composite_texture = draw_clip(ctx, c->fbo[fbo_switcher], composite_texture, true); + fbo_switcher = !fbo_switcher; + } + if (e->enable_superimpose) { + GLuint superimpose_texture = e->process_superimpose(timecode); + if (superimpose_texture == 0) { + qWarning() << "Superimpose texture was nullptr, retrying..."; + texture_failed = true; + } else { + composite_texture = draw_clip(ctx, c->fbo[!fbo_switcher], superimpose_texture, false); + } + } + e->endEffect(); + } + } } GLuint compose_sequence(Viewer* viewer, - QOpenGLContext* ctx, - Sequence* seq, - QVector& nests, - bool video, - bool render_audio, - Effect** gizmos, - bool& texture_failed, - bool rendering, - int playback_speed) { - GLint current_fbo = 0; - if (video) { - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); - } + QOpenGLContext* ctx, + Sequence* seq, + QVector& nests, + bool video, + bool render_audio, + Effect** gizmos, + bool& texture_failed, + bool rendering, + int playback_speed) { + GLint current_fbo = 0; + if (video) { + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); + } - Sequence* s = seq; - long playhead = s->playhead; + Sequence* s = seq; + long playhead = s->playhead; - if (!nests.isEmpty()) { - for (int i=0;imedia->to_sequence(); - playhead += nests.at(i)->clip_in - nests.at(i)->get_timeline_in_with_transition(); - playhead = refactor_frame_number(playhead, nests.at(i)->sequence->frame_rate, s->frame_rate); - } + if (!nests.isEmpty()) { + for (int i=0;imedia->to_sequence(); + playhead += nests.at(i)->clip_in - nests.at(i)->get_timeline_in_with_transition(); + playhead = refactor_frame_number(playhead, nests.at(i)->sequence->frame_rate, s->frame_rate); + } - if (video && nests.last()->fbo != nullptr) { - nests.last()->fbo[0]->bind(); - glClear(GL_COLOR_BUFFER_BIT); -// nests.last()->fbo[0]->release(); - ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); - } - } + if (video && nests.last()->fbo != nullptr) { + nests.last()->fbo[0]->bind(); + glClear(GL_COLOR_BUFFER_BIT); + // nests.last()->fbo[0]->release(); + ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); + } + } - int audio_track_count = 0; + int audio_track_count = 0; - QVector current_clips; + QVector current_clips; - for (int i=0;iclips.size();i++) { - Clip* c = s->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = s->clips.at(i); - // if clip starts within one second and/or hasn't finished yet - if (c != nullptr) { -// if (!(!nests.isEmpty() && !same_sign(c->track, nests.last()->track))) { - if ((c->track < 0) == video) { - bool clip_is_active = false; + // if clip starts within one second and/or hasn't finished yet + if (c != nullptr) { + // if (!(!nests.isEmpty() && !same_sign(c->track, nests.last()->track))) { + if ((c->track < 0) == video) { + bool clip_is_active = false; - if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { - Footage* m = c->media->to_footage(); - if (!m->invalid && !(c->track >= 0 && !is_audio_device_set())) { - if (m->ready) { - const FootageStream* ms = m->get_stream_from_file_index(c->track < 0, c->media_stream); - if (ms != nullptr && is_clip_active(c, playhead)) { - // if thread is already working, we don't want to touch this, - // but we also don't want to hang the UI thread - if (!c->open) { - open_clip(c, !rendering); - } - clip_is_active = true; - if (c->track >= 0) audio_track_count++; - } else if (c->finished_opening) { - close_clip(c, false); - } - } else { - //qWarning() << "Media '" + m->name + "' was not ready, retrying..."; - texture_failed = true; - } - } - } else { - if (is_clip_active(c, playhead)) { - if (!c->open) open_clip(c, !rendering); - clip_is_active = true; - } else if (c->finished_opening) { - close_clip(c, false); - } - } - if (clip_is_active) { - bool added = false; - for (int j=0;jtrack < c->track) { - current_clips.insert(j, c); - added = true; - break; - } - } - if (!added) { - current_clips.append(c); - } - } - } - } - } + if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { + Footage* m = c->media->to_footage(); + if (!m->invalid && !(c->track >= 0 && !is_audio_device_set())) { + if (m->ready) { + const FootageStream* ms = m->get_stream_from_file_index(c->track < 0, c->media_stream); + if (ms != nullptr && is_clip_active(c, playhead)) { + // if thread is already working, we don't want to touch this, + // but we also don't want to hang the UI thread + if (!c->open) { + open_clip(c, !rendering); + } + clip_is_active = true; + if (c->track >= 0) audio_track_count++; + } else if (c->finished_opening) { + close_clip(c, false); + } + } else { + //qWarning() << "Media '" + m->name + "' was not ready, retrying..."; + texture_failed = true; + } + } + } else { + if (is_clip_active(c, playhead)) { + if (!c->open) open_clip(c, !rendering); + clip_is_active = true; + } else if (c->finished_opening) { + close_clip(c, false); + } + } + if (clip_is_active) { + bool added = false; + for (int j=0;jtrack < c->track) { + current_clips.insert(j, c); + added = true; + break; + } + } + if (!added) { + current_clips.append(c); + } + } + } + } + } - int half_width = s->width/2; - int half_height = s->height/2; + int half_width = s->width/2; + int half_height = s->height/2; - if (video) { - glPushMatrix(); - glLoadIdentity(); - glOrtho(-half_width, half_width, -half_height, half_height, -1, 10); - } + if (video) { + glPushMatrix(); + glLoadIdentity(); + glOrtho(-half_width, half_width, -half_height, half_height, -1, 10); + } - for (int i=0;imedia != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE && !c->finished_opening) { - qWarning() << "Tried to display clip" << i << "but it's closed"; - texture_failed = true; - } else { - if (c->track < 0) { - ctx->functions()->GL_DEFAULT_BLEND; - glColor4f(1.0, 1.0, 1.0, 1.0); + if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE && !c->finished_opening) { + qWarning() << "Tried to display clip" << i << "but it's closed"; + texture_failed = true; + } else { + if (c->track < 0) { + ctx->functions()->GL_DEFAULT_BLEND; + glColor4f(1.0, 1.0, 1.0, 1.0); - GLuint textureID = 0; - int video_width = c->getWidth(); - int video_height = c->getHeight(); + GLuint textureID = 0; + int video_width = c->getWidth(); + int video_height = c->getHeight(); - if (c->media != nullptr) { - switch (c->media->get_type()) { - case MEDIA_TYPE_FOOTAGE: - // set up opengl texture - if (c->texture == nullptr) { - c->texture = new QOpenGLTexture(QOpenGLTexture::Target2D); - c->texture->setSize(c->stream->codecpar->width, c->stream->codecpar->height); - c->texture->setFormat(get_gl_tex_fmt_from_av(c->pix_fmt)); - c->texture->setMipLevels(c->texture->maximumMipLevels()); - c->texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear); - c->texture->allocateStorage(get_gl_pix_fmt_from_av(c->pix_fmt), QOpenGLTexture::UInt8); - } - get_clip_frame(c, qMax(playhead, c->timeline_in), texture_failed); - textureID = c->texture->textureId(); - break; - case MEDIA_TYPE_SEQUENCE: - textureID = -1; - break; - } - } + if (c->media != nullptr) { + switch (c->media->get_type()) { + case MEDIA_TYPE_FOOTAGE: + // set up opengl texture + if (c->texture == nullptr) { + c->texture = new QOpenGLTexture(QOpenGLTexture::Target2D); + c->texture->setSize(c->stream->codecpar->width, c->stream->codecpar->height); + c->texture->setFormat(get_gl_tex_fmt_from_av(c->pix_fmt)); + c->texture->setMipLevels(c->texture->maximumMipLevels()); + c->texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear); + c->texture->allocateStorage(get_gl_pix_fmt_from_av(c->pix_fmt), QOpenGLTexture::UInt8); + } + get_clip_frame(c, qMax(playhead, c->timeline_in), texture_failed); + textureID = c->texture->textureId(); + break; + case MEDIA_TYPE_SEQUENCE: + textureID = -1; + break; + } + } - if (textureID == 0 && c->media != nullptr) { - qWarning() << "Texture hasn't been created yet"; - texture_failed = true; - } else if (playhead >= c->get_timeline_in_with_transition()) { - glPushMatrix(); + if (textureID == 0 && c->media != nullptr) { + qWarning() << "Texture hasn't been created yet"; + texture_failed = true; + } else if (playhead >= c->get_timeline_in_with_transition()) { + glPushMatrix(); - // start preparing cache - if (c->fbo == nullptr) { - c->fbo = new QOpenGLFramebufferObject* [2]; - c->fbo[0] = new QOpenGLFramebufferObject(video_width, video_height); - c->fbo[1] = new QOpenGLFramebufferObject(video_width, video_height); - ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); - } + // start preparing cache + if (c->fbo == nullptr) { + c->fbo = new QOpenGLFramebufferObject* [2]; + c->fbo[0] = new QOpenGLFramebufferObject(video_width, video_height); + c->fbo[1] = new QOpenGLFramebufferObject(video_width, video_height); + ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); + } - // clear fbos - /*c->fbo[0]->bind(); - glClear(GL_COLOR_BUFFER_BIT); - c->fbo[0]->release(); - c->fbo[1]->bind(); - glClear(GL_COLOR_BUFFER_BIT); - c->fbo[1]->release();*/ + // clear fbos + /*c->fbo[0]->bind(); + glClear(GL_COLOR_BUFFER_BIT); + c->fbo[0]->release(); + c->fbo[1]->bind(); + glClear(GL_COLOR_BUFFER_BIT); + c->fbo[1]->release();*/ - bool fbo_switcher = false; + bool fbo_switcher = false; - glViewport(0, 0, video_width, video_height); + glViewport(0, 0, video_width, video_height); - GLuint composite_texture; + GLuint composite_texture; - if (c->media == nullptr) { - c->fbo[fbo_switcher]->bind(); - glClear(GL_COLOR_BUFFER_BIT); -// c->fbo[fbo_switcher]->release(); - ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); - composite_texture = c->fbo[fbo_switcher]->texture(); - } else { - // for nested sequences - if (c->media->get_type()== MEDIA_TYPE_SEQUENCE) { - nests.append(c); - textureID = compose_sequence(viewer, ctx, seq, nests, video, render_audio, gizmos, texture_failed, rendering, false); - nests.removeLast(); - fbo_switcher = true; - } + if (c->media == nullptr) { + c->fbo[fbo_switcher]->bind(); + glClear(GL_COLOR_BUFFER_BIT); + // c->fbo[fbo_switcher]->release(); + ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); + composite_texture = c->fbo[fbo_switcher]->texture(); + } else { + // for nested sequences + if (c->media->get_type()== MEDIA_TYPE_SEQUENCE) { + nests.append(c); + textureID = compose_sequence(viewer, ctx, seq, nests, video, render_audio, gizmos, texture_failed, rendering, false); + nests.removeLast(); + fbo_switcher = true; + } - composite_texture = draw_clip(ctx, c->fbo[fbo_switcher], textureID, true); - } + composite_texture = draw_clip(ctx, c->fbo[fbo_switcher], textureID, true); + } - fbo_switcher = !fbo_switcher; + fbo_switcher = !fbo_switcher; - // set up default coords - GLTextureCoords coords; - coords.grid_size = 1; - coords.vertexTopLeftX = coords.vertexBottomLeftX = -video_width/2; - coords.vertexTopLeftY = coords.vertexTopRightY = -video_height/2; - coords.vertexTopRightX = coords.vertexBottomRightX = video_width/2; - coords.vertexBottomLeftY = coords.vertexBottomRightY = video_height/2; - coords.vertexBottomLeftZ = coords.vertexBottomRightZ = coords.vertexTopLeftZ = coords.vertexTopRightZ = 1; - coords.textureTopLeftY = coords.textureTopRightY = coords.textureTopLeftX = coords.textureBottomLeftX = 0.0; - coords.textureBottomLeftY = coords.textureBottomRightY = coords.textureTopRightX = coords.textureBottomRightX = 1.0; - coords.textureTopLeftQ = coords.textureTopRightQ = coords.textureTopLeftQ = coords.textureBottomLeftQ = 1; + // set up default coords + GLTextureCoords coords; + coords.grid_size = 1; + coords.vertexTopLeftX = coords.vertexBottomLeftX = -video_width/2; + coords.vertexTopLeftY = coords.vertexTopRightY = -video_height/2; + coords.vertexTopRightX = coords.vertexBottomRightX = video_width/2; + coords.vertexBottomLeftY = coords.vertexBottomRightY = video_height/2; + coords.vertexBottomLeftZ = coords.vertexBottomRightZ = coords.vertexTopLeftZ = coords.vertexTopRightZ = 1; + coords.textureTopLeftY = coords.textureTopRightY = coords.textureTopLeftX = coords.textureBottomLeftX = 0.0; + coords.textureBottomLeftY = coords.textureBottomRightY = coords.textureTopRightX = coords.textureBottomRightX = 1.0; + coords.textureTopLeftQ = coords.textureTopRightQ = coords.textureTopLeftQ = coords.textureBottomLeftQ = 1; - // set up autoscale - if (c->autoscale && (video_width != s->width && video_height != s->height)) { - float width_multiplier = float(s->width) / float(video_width); - float height_multiplier = float(s->height) / float(video_height); - float scale_multiplier = qMin(width_multiplier, height_multiplier); - glScalef(scale_multiplier, scale_multiplier, 1); - } + // set up autoscale + if (c->autoscale && (video_width != s->width && video_height != s->height)) { + float width_multiplier = float(s->width) / float(video_width); + float height_multiplier = float(s->height) / float(video_height); + float scale_multiplier = qMin(width_multiplier, height_multiplier); + glScalef(scale_multiplier, scale_multiplier, 1); + } - // EFFECT CODE START - double timecode = get_timecode(c, playhead); + // EFFECT CODE START + double timecode = get_timecode(c, playhead); - Effect* first_gizmo_effect = nullptr; - Effect* selected_effect = nullptr; + Effect* first_gizmo_effect = nullptr; + Effect* selected_effect = nullptr; - for (int j=0;jeffects.size();j++) { - Effect* e = c->effects.at(j); - process_effect(ctx, c, e, timecode, coords, composite_texture, fbo_switcher, texture_failed, TA_NO_TRANSITION); + for (int j=0;jeffects.size();j++) { + Effect* e = c->effects.at(j); + process_effect(ctx, c, e, timecode, coords, composite_texture, fbo_switcher, texture_failed, TA_NO_TRANSITION); - if (e->are_gizmos_enabled()) { - if (first_gizmo_effect == nullptr) first_gizmo_effect = e; - if (e->container->selected) selected_effect = e; - } - } + if (e->are_gizmos_enabled()) { + if (first_gizmo_effect == nullptr) first_gizmo_effect = e; + if (e->container->selected) selected_effect = e; + } + } - if (selected_effect != nullptr) { - (*gizmos) = selected_effect; - } else if (is_clip_selected(c, true)) { - (*gizmos) = first_gizmo_effect; - } + if (selected_effect != nullptr) { + (*gizmos) = selected_effect; + } else if (is_clip_selected(c, true)) { + (*gizmos) = first_gizmo_effect; + } - if (c->get_opening_transition() != nullptr) { - int transition_progress = playhead - c->get_timeline_in_with_transition(); - if (transition_progress < c->get_opening_transition()->get_length()) { - process_effect(ctx, c, c->get_opening_transition(), (double)transition_progress/(double)c->get_opening_transition()->get_length(), coords, composite_texture, fbo_switcher, texture_failed, TA_OPENING_TRANSITION); - } - } + if (c->get_opening_transition() != nullptr) { + int transition_progress = playhead - c->get_timeline_in_with_transition(); + if (transition_progress < c->get_opening_transition()->get_length()) { + process_effect(ctx, c, c->get_opening_transition(), (double)transition_progress/(double)c->get_opening_transition()->get_length(), coords, composite_texture, fbo_switcher, texture_failed, TA_OPENING_TRANSITION); + } + } - if (c->get_closing_transition() != nullptr) { - int transition_progress = playhead - (c->get_timeline_out_with_transition() - c->get_closing_transition()->get_length()); - if (transition_progress >= 0 && transition_progress < c->get_closing_transition()->get_length()) { - process_effect(ctx, c, c->get_closing_transition(), (double)transition_progress/(double)c->get_closing_transition()->get_length(), coords, composite_texture, fbo_switcher, texture_failed, TA_CLOSING_TRANSITION); - } - } - // EFFECT CODE END + if (c->get_closing_transition() != nullptr) { + int transition_progress = playhead - (c->get_timeline_out_with_transition() - c->get_closing_transition()->get_length()); + if (transition_progress >= 0 && transition_progress < c->get_closing_transition()->get_length()) { + process_effect(ctx, c, c->get_closing_transition(), (double)transition_progress/(double)c->get_closing_transition()->get_length(), coords, composite_texture, fbo_switcher, texture_failed, TA_CLOSING_TRANSITION); + } + } + // EFFECT CODE END - if (!nests.isEmpty()) { - nests.last()->fbo[0]->bind(); - } - glViewport(0, 0, s->width, s->height); + if (!nests.isEmpty()) { + nests.last()->fbo[0]->bind(); + } + glViewport(0, 0, s->width, s->height); - glBindTexture(GL_TEXTURE_2D, composite_texture); + glBindTexture(GL_TEXTURE_2D, composite_texture); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glBegin(GL_QUADS); + glBegin(GL_QUADS); - if (coords.grid_size <= 1) { - float z = 0.0f; + if (coords.grid_size <= 1) { + float z = 0.0f; - glTexCoord2f(coords.textureTopLeftX, coords.textureTopLeftY); // top left - glVertex3f(coords.vertexTopLeftX, coords.vertexTopLeftY, z); // top left - glTexCoord2f(coords.textureTopRightX, coords.textureTopRightY); // top right - glVertex3f(coords.vertexTopRightX, coords.vertexTopRightY, z); // top right - glTexCoord2f(coords.textureBottomRightX, coords.textureBottomRightY); // bottom right - glVertex3f(coords.vertexBottomRightX, coords.vertexBottomRightY, z); // bottom right - glTexCoord2f(coords.textureBottomLeftX, coords.textureBottomLeftY); // bottom left - glVertex3f(coords.vertexBottomLeftX, coords.vertexBottomLeftY, z); // bottom left - } else { - float rows = coords.grid_size; - float cols = coords.grid_size; + glTexCoord2f(coords.textureTopLeftX, coords.textureTopLeftY); // top left + glVertex3f(coords.vertexTopLeftX, coords.vertexTopLeftY, z); // top left + glTexCoord2f(coords.textureTopRightX, coords.textureTopRightY); // top right + glVertex3f(coords.vertexTopRightX, coords.vertexTopRightY, z); // top right + glTexCoord2f(coords.textureBottomRightX, coords.textureBottomRightY); // bottom right + glVertex3f(coords.vertexBottomRightX, coords.vertexBottomRightY, z); // bottom right + glTexCoord2f(coords.textureBottomLeftX, coords.textureBottomLeftY); // bottom left + glVertex3f(coords.vertexBottomLeftX, coords.vertexBottomLeftY, z); // bottom left + } else { + const auto rows = coords.grid_size; + const auto cols = coords.grid_size; - for (float k=0;k(k)/rows; + auto next_row_prog = static_cast(k+1)/rows; + for (auto j=0; j(j)/cols; + const auto next_col_prog = static_cast(j+1)/cols; - float vertexTLX = float_lerp(coords.vertexTopLeftX, coords.vertexBottomLeftX, row_prog); - float vertexTRX = float_lerp(coords.vertexTopRightX, coords.vertexBottomRightX, row_prog); - float vertexBLX = float_lerp(coords.vertexTopLeftX, coords.vertexBottomLeftX, next_row_prog); - float vertexBRX = float_lerp(coords.vertexTopRightX, coords.vertexBottomRightX, next_row_prog); + const auto vertexTLX = float_lerp(coords.vertexTopLeftX, coords.vertexBottomLeftX, row_prog); + const auto vertexTRX = float_lerp(coords.vertexTopRightX, coords.vertexBottomRightX, row_prog); + const auto vertexBLX = float_lerp(coords.vertexTopLeftX, coords.vertexBottomLeftX, next_row_prog); + const auto vertexBRX = float_lerp(coords.vertexTopRightX, coords.vertexBottomRightX, next_row_prog); - float vertexTLY = float_lerp(coords.vertexTopLeftY, coords.vertexTopRightY, col_prog); - float vertexTRY = float_lerp(coords.vertexTopLeftY, coords.vertexTopRightY, next_col_prog); - float vertexBLY = float_lerp(coords.vertexBottomLeftY, coords.vertexBottomRightY, col_prog); - float vertexBRY = float_lerp(coords.vertexBottomLeftY, coords.vertexBottomRightY, next_col_prog); + const auto vertexTLY = float_lerp(coords.vertexTopLeftY, coords.vertexTopRightY, col_prog); + const auto vertexTRY = float_lerp(coords.vertexTopLeftY, coords.vertexTopRightY, next_col_prog); + const auto vertexBLY = float_lerp(coords.vertexBottomLeftY, coords.vertexBottomRightY, col_prog); + const auto vertexBRY = float_lerp(coords.vertexBottomLeftY, coords.vertexBottomRightY, next_col_prog); - glTexCoord2f(float_lerp(coords.textureTopLeftX, coords.textureTopRightX, col_prog), float_lerp(coords.textureTopLeftY, coords.textureBottomLeftY, row_prog)); // top left - glVertex2f(float_lerp(vertexTLX, vertexTRX, col_prog), float_lerp(vertexTLY, vertexBLY, row_prog)); // top left - glTexCoord2f(float_lerp(coords.textureTopLeftX, coords.textureTopRightX, next_col_prog), float_lerp(coords.textureTopRightY, coords.textureBottomRightY, row_prog)); // top right - glVertex2f(float_lerp(vertexTLX, vertexTRX, next_col_prog), float_lerp(vertexTRY, vertexBRY, row_prog)); // top right - glTexCoord2f(float_lerp(coords.textureBottomLeftX, coords.textureBottomRightX, next_col_prog), float_lerp(coords.textureTopRightY, coords.textureBottomRightY, next_row_prog)); // bottom right - glVertex2f(float_lerp(vertexBLX, vertexBRX, next_col_prog), float_lerp(vertexTRY, vertexBRY, next_row_prog)); // bottom right - glTexCoord2f(float_lerp(coords.textureBottomLeftX, coords.textureBottomRightX, col_prog), float_lerp(coords.textureTopLeftY, coords.textureBottomLeftY, next_row_prog)); // bottom left - glVertex2f(float_lerp(vertexBLX, vertexBRX, col_prog), float_lerp(vertexTLY, vertexBLY, next_row_prog)); // bottom left - } - } - } + glTexCoord2f(float_lerp(coords.textureTopLeftX, coords.textureTopRightX, col_prog), + float_lerp(coords.textureTopLeftY, coords.textureBottomLeftY, row_prog)); // top left + glVertex2f(float_lerp(vertexTLX, vertexTRX, col_prog), float_lerp(vertexTLY, vertexBLY, row_prog)); // top left + glTexCoord2f(float_lerp(coords.textureTopLeftX, coords.textureTopRightX, next_col_prog), + float_lerp(coords.textureTopRightY, coords.textureBottomRightY, row_prog)); // top right + glVertex2f(float_lerp(vertexTLX, vertexTRX, next_col_prog), float_lerp(vertexTRY, vertexBRY, row_prog)); // top right + glTexCoord2f(float_lerp(coords.textureBottomLeftX, coords.textureBottomRightX, next_col_prog), + float_lerp(coords.textureTopRightY, coords.textureBottomRightY, next_row_prog)); // bottom right + glVertex2f(float_lerp(vertexBLX, vertexBRX, next_col_prog), float_lerp(vertexTRY, vertexBRY, next_row_prog)); // bottom right + glTexCoord2f(float_lerp(coords.textureBottomLeftX, coords.textureBottomRightX, col_prog), + float_lerp(coords.textureTopLeftY, coords.textureBottomLeftY, next_row_prog)); // bottom left + glVertex2f(float_lerp(vertexBLX, vertexBRX, col_prog), float_lerp(vertexTLY, vertexBLY, next_row_prog)); // bottom left + }//for + }//for + } - glEnd(); + glEnd(); - glBindTexture(GL_TEXTURE_2D, 0); // unbind texture + glBindTexture(GL_TEXTURE_2D, 0); // unbind texture - // prepare gizmos - if ((*gizmos) != nullptr - && nests.isEmpty() - && ((*gizmos) == first_gizmo_effect - || (*gizmos) == selected_effect)) { - (*gizmos)->gizmo_draw(timecode, coords); // set correct gizmo coords - (*gizmos)->gizmo_world_to_screen(); // convert gizmo coords to screen coords - } + // prepare gizmos + if ((*gizmos) != nullptr + && nests.isEmpty() + && ((*gizmos) == first_gizmo_effect + || (*gizmos) == selected_effect)) { + (*gizmos)->gizmo_draw(timecode, coords); // set correct gizmo coords + (*gizmos)->gizmo_world_to_screen(); // convert gizmo coords to screen coords + } - if (!nests.isEmpty()) { - ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); - } + if (!nests.isEmpty()) { + ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); + } - glPopMatrix(); + glPopMatrix(); - /*GLfloat motion_blur_frac = (GLfloat) motion_blur_prog / (GLfloat) motion_blur_lim; - if (motion_blur_prog == 0) { - glAccum(GL_LOAD, motion_blur_frac); - } else { - glAccum(GL_ACCUM, motion_blur_frac); - } - motion_blur_prog++;*/ - } - } else { - if (render_audio || (config.enable_audio_scrubbing && audio_scrub && seq->playhead > c->timeline_in)) { - if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) { - nests.append(c); - compose_sequence(viewer, ctx, seq, nests, video, render_audio, gizmos, texture_failed, rendering, playback_speed); - nests.removeLast(); - } else { - if (c->lock.tryLock()) { - // clip is not caching, start caching audio - cache_clip(c, playhead, c->audio_reset, !render_audio, nests, playback_speed); - c->lock.unlock(); - } - } - } + /*GLfloat motion_blur_frac = (GLfloat) motion_blur_prog / (GLfloat) motion_blur_lim; + if (motion_blur_prog == 0) { + glAccum(GL_LOAD, motion_blur_frac); + } else { + glAccum(GL_ACCUM, motion_blur_frac); + } + motion_blur_prog++;*/ + } + } else { + if (render_audio || (config.enable_audio_scrubbing && audio_scrub && seq->playhead > c->timeline_in)) { + if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) { + nests.append(c); + compose_sequence(viewer, ctx, seq, nests, video, render_audio, gizmos, texture_failed, rendering, playback_speed); + nests.removeLast(); + } else { + if (c->lock.tryLock()) { + // clip is not caching, start caching audio + cache_clip(c, playhead, c->audio_reset, !render_audio, nests, playback_speed); + c->lock.unlock(); + } + } + } - // visually update all the keyframe values - if (c->sequence == seq) { // only if you can currently see them - double ts = (playhead - c->get_timeline_in_with_transition() + c->get_clip_in_with_transition())/s->frame_rate; - for (int i=0;ieffects.size();i++) { - Effect* e = c->effects.at(i); - for (int j=0;jrow_count();j++) { - EffectRow* r = e->row(j); - for (int k=0;kfieldCount();k++) { - r->field(k)->validate_keyframe_data(ts); - } - } - } - } - } - } - } + // visually update all the keyframe values + if (c->sequence == seq) { // only if you can currently see them + double ts = (playhead - c->get_timeline_in_with_transition() + c->get_clip_in_with_transition())/s->frame_rate; + for (int i=0;ieffects.size();i++) { + Effect* e = c->effects.at(i); + for (int j=0;jrow_count();j++) { + EffectRow* r = e->row(j); + for (int k=0;kfieldCount();k++) { + r->field(k)->validate_keyframe_data(ts); + } + } + } + } + } + } + } - if (audio_track_count == 0 && viewer != nullptr) { - viewer->play_wake(); - } + if (audio_track_count == 0 && viewer != nullptr) { + viewer->play_wake(); + } - if (video) { - glPopMatrix(); - } + if (video) { + glPopMatrix(); + } - if (!nests.isEmpty() && nests.last()->fbo != nullptr) { - // returns nested clip's texture - return nests.last()->fbo[0]->texture(); - } + if (!nests.isEmpty() && nests.last()->fbo != nullptr) { + // returns nested clip's texture + return nests.last()->fbo[0]->texture(); + } - return 0; + return 0; } void compose_audio(Viewer* viewer, Sequence* seq, bool render_audio, int playback_speed) { - QVector nests; - bool texture_failed; - compose_sequence(viewer, nullptr, seq, nests, false, render_audio, nullptr, texture_failed, audio_rendering, playback_speed); + QVector nests; + bool texture_failed; + compose_sequence(viewer, nullptr, seq, nests, false, render_audio, nullptr, texture_failed, audio_rendering, playback_speed); } From 3d0a65c70de49ffe91b25b7cade03ed56f478158 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sat, 16 Feb 2019 14:02:26 -0800 Subject: [PATCH 03/30] rewrote void loading --- effects/internal/voideffect.cpp | 38 ++++++++++++++++----------------- main.cpp | 3 ++- panels/grapheditor.cpp | 2 +- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/effects/internal/voideffect.cpp b/effects/internal/voideffect.cpp index 86a229b9e..95acc9442 100644 --- a/effects/internal/voideffect.cpp +++ b/effects/internal/voideffect.cpp @@ -52,26 +52,26 @@ Effect *VoidEffect::copy(Clip *c) { void VoidEffect::load(QXmlStreamReader &stream) { QString tag = stream.name().toString(); - qint64 start_index = stream.characterOffset(); - qint64 end_index = start_index; - while (!stream.atEnd() && !(stream.name() == tag && stream.isEndElement())) { - end_index = stream.characterOffset(); - stream.readNext(); - } - qint64 passage_length = end_index - start_index; - if (passage_length > 0) { - // store xml data verbatim - QFile* device = static_cast(stream.device()); - QFile passage_get(device->fileName()); - if (passage_get.open(QFile::ReadOnly)) { - passage_get.seek(start_index); - bytes = passage_get.read(passage_length); - int passage_end = bytes.lastIndexOf('>')+1; - bytes.remove(passage_end, bytes.size()-passage_end); - passage_get.close(); - } - } + QXmlStreamWriter writer(&bytes); + + // copy XML from reader to writer + while (!stream.atEnd() && !(stream.name() == tag && stream.isEndElement())) { + stream.readNext(); + + if (stream.isStartElement()) { + writer.writeStartElement(stream.name().toString()); + } + if (stream.isEndElement()) { + writer.writeEndElement(); + } + if (stream.isCharacters()) { + writer.writeCharacters(stream.text().toString()); + } + for (int i=0;isetAlignment(Qt::AlignCenter); layout->addWidget(current_row_desc); - connect(view, SIGNAL(zoom_changed(double)), header, SLOT(update_zoom(double))); + connect(view, SIGNAL(zoom_changed(double, double)), header, SLOT(update_zoom(double))); connect(view, SIGNAL(x_scroll_changed(int)), header, SLOT(set_scroll(int))); connect(view, SIGNAL(selection_changed(bool, int)), this, SLOT(set_key_button_enabled(bool, int))); From e063a5ba8f22b171b9c841cce4637122ed9f9170 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sat, 16 Feb 2019 15:08:33 -0800 Subject: [PATCH 04/30] switched global to unique ptr and renamed olive namespace --- debug.cpp | 4 +- dialogs/actionsearch.cpp | 2 +- dialogs/debugdialog.cpp | 2 +- dialogs/debugdialog.h | 2 +- dialogs/exportdialog.cpp | 26 +-- dialogs/loaddialog.cpp | 4 +- dialogs/mediapropertiesdialog.cpp | 2 +- dialogs/newsequencedialog.cpp | 4 +- dialogs/preferencesdialog.cpp | 104 ++++----- dialogs/proxydialog.cpp | 2 +- dialogs/replaceclipmediadialog.cpp | 8 +- dialogs/speeddialog.cpp | 12 +- effects/internal/texteffect.cpp | 2 +- effects/internal/timecodeeffect.cpp | 4 +- effects/internal/vsthost.cpp | 6 +- io/config.cpp | 4 +- io/config.h | 2 +- io/exportthread.cpp | 30 +-- io/loadthread.cpp | 22 +- io/previewgenerator.cpp | 8 +- io/proxygenerator.cpp | 2 +- main.cpp | 14 +- mainwindow.cpp | 294 ++++++++++++------------ mainwindow.h | 2 +- oliveglobal.cpp | 76 +++---- oliveglobal.h | 4 +- panels/effectcontrols.cpp | 20 +- panels/panels.cpp | 14 +- panels/project.cpp | 78 +++---- panels/timeline.cpp | 340 ++++++++++++++-------------- panels/viewer.cpp | 28 +-- playback/audio.cpp | 14 +- playback/cacher.cpp | 14 +- playback/playback.cpp | 14 +- project/clip.cpp | 2 +- project/effect.cpp | 28 +-- project/effectfield.cpp | 4 +- project/effectloaders.cpp | 2 +- project/effectrow.cpp | 14 +- project/keyframe.cpp | 2 +- project/marker.cpp | 6 +- project/media.cpp | 6 +- project/sequence.cpp | 2 +- project/sequence.h | 2 +- project/sourcescommon.cpp | 24 +- project/transition.cpp | 2 +- project/undo.cpp | 14 +- project/undo.h | 2 +- ui/audiomonitor.cpp | 2 +- ui/checkboxex.cpp | 2 +- ui/comboboxex.cpp | 6 +- ui/cursors.cpp | 8 +- ui/cursors.h | 2 +- ui/focusfilter.cpp | 10 +- ui/focusfilter.h | 2 +- ui/graphview.cpp | 6 +- ui/keyframeview.cpp | 12 +- ui/labelslider.cpp | 4 +- ui/menuhelper.cpp | 48 ++-- ui/menuhelper.h | 2 +- ui/renderfunctions.cpp | 6 +- ui/scrollarea.cpp | 2 +- ui/timelineheader.cpp | 24 +- ui/timelinewidget.cpp | 300 ++++++++++++------------ ui/viewerwidget.cpp | 10 +- 65 files changed, 860 insertions(+), 860 deletions(-) diff --git a/debug.cpp b/debug.cpp index 70b605938..f949f07ac 100644 --- a/debug.cpp +++ b/debug.cpp @@ -85,8 +85,8 @@ void debug_message_handler(QtMsgType type, const QMessageLogContext &context, co fflush(stderr); // abort(); } - if (Olive::DebugDialog != nullptr && Olive::DebugDialog->isVisible()) { - QMetaObject::invokeMethod(Olive::DebugDialog, "update_log", Qt::QueuedConnection); + if (olive::DebugDialog != nullptr && olive::DebugDialog->isVisible()) { + QMetaObject::invokeMethod(olive::DebugDialog, "update_log", Qt::QueuedConnection); } debug_mutex.unlock(); } diff --git a/dialogs/actionsearch.cpp b/dialogs/actionsearch.cpp index ffe85fc71..a21a2ef3d 100644 --- a/dialogs/actionsearch.cpp +++ b/dialogs/actionsearch.cpp @@ -63,7 +63,7 @@ ActionSearch::ActionSearch(QWidget *parent) : void ActionSearch::search_update(const QString &s, const QString &p, QMenu *parent) { if (parent == nullptr) { list_widget->clear(); - QList menus = Olive::MainWindow->menuBar()->actions(); + QList menus = olive::MainWindow->menuBar()->actions(); for (int i=0;imenu(); search_update(s, p, menu); diff --git a/dialogs/debugdialog.cpp b/dialogs/debugdialog.cpp index c15adcfea..b45fb66f7 100644 --- a/dialogs/debugdialog.cpp +++ b/dialogs/debugdialog.cpp @@ -26,7 +26,7 @@ #include "debug.h" -DebugDialog* Olive::DebugDialog = nullptr; +DebugDialog* olive::DebugDialog = nullptr; DebugDialog::DebugDialog(QWidget *parent) : QDialog(parent) { setWindowTitle(tr("Debug Log")); diff --git a/dialogs/debugdialog.h b/dialogs/debugdialog.h index b58c53833..9f9d146bb 100644 --- a/dialogs/debugdialog.h +++ b/dialogs/debugdialog.h @@ -36,7 +36,7 @@ private: QTextEdit* textEdit; }; -namespace Olive { +namespace olive { extern DebugDialog* DebugDialog; } diff --git a/dialogs/exportdialog.cpp b/dialogs/exportdialog.cpp index 7328e4b23..ee1d5d1e3 100644 --- a/dialogs/exportdialog.cpp +++ b/dialogs/exportdialog.cpp @@ -70,11 +70,11 @@ enum ExportFormats { ExportDialog::ExportDialog(QWidget *parent) : QDialog(parent) { - setWindowTitle(tr("Export \"%1\"").arg(Olive::ActiveSequence->name)); + setWindowTitle(tr("Export \"%1\"").arg(olive::ActiveSequence->name)); setup_ui(); rangeCombobox->setCurrentIndex(0); - if (Olive::ActiveSequence->using_workarea) { + if (olive::ActiveSequence->using_workarea) { rangeCombobox->setEnabled(true); rangeCombobox->setCurrentIndex(1); } @@ -107,10 +107,10 @@ ExportDialog::ExportDialog(QWidget *parent) : } formatCombobox->setCurrentIndex(FORMAT_MPEG4); - widthSpinbox->setValue(Olive::ActiveSequence->width); - heightSpinbox->setValue(Olive::ActiveSequence->height); - samplingRateSpinbox->setValue(Olive::ActiveSequence->audio_frequency); - framerateSpinbox->setValue(Olive::ActiveSequence->frame_rate); + widthSpinbox->setValue(olive::ActiveSequence->width); + heightSpinbox->setValue(olive::ActiveSequence->height); + samplingRateSpinbox->setValue(olive::ActiveSequence->audio_frequency); + framerateSpinbox->setValue(olive::ActiveSequence->frame_rate); } ExportDialog::~ExportDialog() @@ -524,10 +524,10 @@ void ExportDialog::export_action() { } params.start_frame = 0; - params.end_frame = Olive::ActiveSequence->getEndFrame(); // entire sequence + params.end_frame = olive::ActiveSequence->getEndFrame(); // entire sequence if (rangeCombobox->currentIndex() == 1) { - params.start_frame = qMax(Olive::ActiveSequence->workarea_in, params.start_frame); - params.end_frame = qMin(Olive::ActiveSequence->workarea_out, params.end_frame); + params.start_frame = qMax(olive::ActiveSequence->workarea_in, params.start_frame); + params.end_frame = qMin(olive::ActiveSequence->workarea_out, params.end_frame); } et = new ExportThread(params, vcodec_params, this); @@ -535,11 +535,11 @@ void ExportDialog::export_action() { connect(et, SIGNAL(finished()), this, SLOT(render_thread_finished())); connect(et, SIGNAL(progress_changed(int, qint64)), this, SLOT(update_progress_bar(int, qint64))); - closeActiveClips(Olive::ActiveSequence); + closeActiveClips(olive::ActiveSequence); - Olive::Global.data()->set_rendering_state(true); + olive::Global->set_rendering_state(true); - Olive::Global.data()->save_autorecovery_file(); + olive::Global->save_autorecovery_file(); prep_ui_for_render(true); @@ -605,7 +605,7 @@ void ExportDialog::comp_type_changed(int) { case COMPRESSION_TYPE_CBR: case COMPRESSION_TYPE_TARGETBR: videoBitrateLabel->setText(tr("Bitrate (Mbps):")); - videobitrateSpinbox->setValue(qMax(0.5, (double) qRound((0.01528 * Olive::ActiveSequence->height) - 4.5))); + videobitrateSpinbox->setValue(qMax(0.5, (double) qRound((0.01528 * olive::ActiveSequence->height) - 4.5))); break; case COMPRESSION_TYPE_CFR: videoBitrateLabel->setText(tr("Quality (CRF):")); diff --git a/dialogs/loaddialog.cpp b/dialogs/loaddialog.cpp index 35902a2a0..bd1d8ff6f 100644 --- a/dialogs/loaddialog.cpp +++ b/dialogs/loaddialog.cpp @@ -38,7 +38,7 @@ LoadDialog::LoadDialog(QWidget *parent, bool autorecovery) : QDialog(parent) { QVBoxLayout* layout = new QVBoxLayout(this); - layout->addWidget(new QLabel(tr("Loading '%1'...").arg(Olive::ActiveProjectFilename.mid(Olive::ActiveProjectFilename.lastIndexOf('/')+1)), this)); + layout->addWidget(new QLabel(tr("Loading '%1'...").arg(olive::ActiveProjectFilename.mid(olive::ActiveProjectFilename.lastIndexOf('/')+1)), this)); bar = new QProgressBar(this); bar->setValue(0); @@ -70,7 +70,7 @@ void LoadDialog::cancel() { } void LoadDialog::die() { - Olive::Global.data()->new_project(); + olive::Global->new_project(); reject(); } diff --git a/dialogs/mediapropertiesdialog.cpp b/dialogs/mediapropertiesdialog.cpp index d9be1c3a6..b004e3fdf 100644 --- a/dialogs/mediapropertiesdialog.cpp +++ b/dialogs/mediapropertiesdialog.cpp @@ -205,7 +205,7 @@ void MediaPropertiesDialog::accept() { } ca->appendPost(new UpdateViewer()); - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); QDialog::accept(); } diff --git a/dialogs/newsequencedialog.cpp b/dialogs/newsequencedialog.cpp index 7f13737a2..3b4e48457 100644 --- a/dialogs/newsequencedialog.cpp +++ b/dialogs/newsequencedialog.cpp @@ -96,7 +96,7 @@ void NewSequenceDialog::create() { ComboAction* ca = new ComboAction(); panel_project->create_sequence_internal(ca, s, true, nullptr); - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); } else { ComboAction* ca = new ComboAction(); @@ -118,7 +118,7 @@ void NewSequenceDialog::create() { } } - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); } accept(); diff --git a/dialogs/preferencesdialog.cpp b/dialogs/preferencesdialog.cpp index cf292e2b7..d2928032d 100644 --- a/dialogs/preferencesdialog.cpp +++ b/dialogs/preferencesdialog.cpp @@ -83,10 +83,10 @@ PreferencesDialog::PreferencesDialog(QWidget *parent) : setWindowTitle(tr("Preferences")); setup_ui(); - accurateSeekButton->setChecked(!Olive::CurrentConfig.fast_seeking); - fastSeekButton->setChecked(Olive::CurrentConfig.fast_seeking); - recordingComboBox->setCurrentIndex(Olive::CurrentConfig.recording_mode - 1); - imgSeqFormatEdit->setText(Olive::CurrentConfig.img_seq_formats); + accurateSeekButton->setChecked(!olive::CurrentConfig.fast_seeking); + fastSeekButton->setChecked(olive::CurrentConfig.fast_seeking); + recordingComboBox->setCurrentIndex(olive::CurrentConfig.recording_mode - 1); + imgSeqFormatEdit->setText(olive::CurrentConfig.img_seq_formats); } PreferencesDialog::~PreferencesDialog() {} @@ -184,11 +184,11 @@ void PreferencesDialog::save() { } // Check if any settings will require a restart of Olive - if (Olive::CurrentConfig.effect_textbox_lines != effect_textbox_lines_field->value() - || Olive::CurrentConfig.use_software_fallback != use_software_fallbacks_checkbox->isChecked() - || Olive::CurrentConfig.language_file != language_combobox->currentData().toString() - || Olive::CurrentConfig.thumbnail_resolution != thumbnail_res_spinbox->value() - || Olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()) { + if (olive::CurrentConfig.effect_textbox_lines != effect_textbox_lines_field->value() + || olive::CurrentConfig.use_software_fallback != use_software_fallbacks_checkbox->isChecked() + || olive::CurrentConfig.language_file != language_combobox->currentData().toString() + || olive::CurrentConfig.thumbnail_resolution != thumbnail_res_spinbox->value() + || olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()) { // any changes to these settings will require a restart - ask the user if we should do one now or later @@ -204,7 +204,7 @@ void PreferencesDialog::save() { } else if (ret == QMessageBox::Yes) { // Check if we can close the current project. If not, we'll treat it as if the user clicked "Cancel". - if (Olive::Global->can_close_project()) { + if (olive::Global->can_close_project()) { restart_after_saving = true; } else { return; @@ -215,51 +215,51 @@ void PreferencesDialog::save() { } // Audio settings may require the audio device to be re-initiated. - if (Olive::CurrentConfig.preferred_audio_output != audio_output_devices->currentData().toString() - || Olive::CurrentConfig.preferred_audio_input != audio_input_devices->currentData().toString() - || Olive::CurrentConfig.audio_rate != audio_sample_rate->currentData().toInt()) { + if (olive::CurrentConfig.preferred_audio_output != audio_output_devices->currentData().toString() + || olive::CurrentConfig.preferred_audio_input != audio_input_devices->currentData().toString() + || olive::CurrentConfig.audio_rate != audio_sample_rate->currentData().toInt()) { reinit_audio = true; } // save settings from UI to backend - Olive::CurrentConfig.css_path = custom_css_fn->text(); - Olive::MainWindow->load_css_from_file(Olive::CurrentConfig.css_path); + olive::CurrentConfig.css_path = custom_css_fn->text(); + olive::MainWindow->load_css_from_file(olive::CurrentConfig.css_path); - Olive::CurrentConfig.recording_mode = recordingComboBox->currentIndex() + 1; - Olive::CurrentConfig.img_seq_formats = imgSeqFormatEdit->text(); - Olive::CurrentConfig.fast_seeking = fastSeekButton->isChecked(); - Olive::CurrentConfig.upcoming_queue_size = upcoming_queue_spinbox->value(); - Olive::CurrentConfig.upcoming_queue_type = upcoming_queue_type->currentIndex(); - Olive::CurrentConfig.previous_queue_size = previous_queue_spinbox->value(); - Olive::CurrentConfig.previous_queue_type = previous_queue_type->currentIndex(); - Olive::CurrentConfig.add_default_effects_to_clips = add_default_effects_to_clips->isChecked(); + olive::CurrentConfig.recording_mode = recordingComboBox->currentIndex() + 1; + olive::CurrentConfig.img_seq_formats = imgSeqFormatEdit->text(); + olive::CurrentConfig.fast_seeking = fastSeekButton->isChecked(); + olive::CurrentConfig.upcoming_queue_size = upcoming_queue_spinbox->value(); + olive::CurrentConfig.upcoming_queue_type = upcoming_queue_type->currentIndex(); + olive::CurrentConfig.previous_queue_size = previous_queue_spinbox->value(); + olive::CurrentConfig.previous_queue_type = previous_queue_type->currentIndex(); + olive::CurrentConfig.add_default_effects_to_clips = add_default_effects_to_clips->isChecked(); - Olive::CurrentConfig.preferred_audio_output = audio_output_devices->currentData().toString(); - Olive::CurrentConfig.preferred_audio_input = audio_input_devices->currentData().toString(); - Olive::CurrentConfig.audio_rate = audio_sample_rate->currentData().toInt(); + olive::CurrentConfig.preferred_audio_output = audio_output_devices->currentData().toString(); + olive::CurrentConfig.preferred_audio_input = audio_input_devices->currentData().toString(); + olive::CurrentConfig.audio_rate = audio_sample_rate->currentData().toInt(); - Olive::CurrentConfig.effect_textbox_lines = effect_textbox_lines_field->value(); - Olive::CurrentConfig.use_software_fallback = use_software_fallbacks_checkbox->isChecked(); - Olive::CurrentConfig.language_file = language_combobox->currentData().toString(); + olive::CurrentConfig.effect_textbox_lines = effect_textbox_lines_field->value(); + olive::CurrentConfig.use_software_fallback = use_software_fallbacks_checkbox->isChecked(); + olive::CurrentConfig.language_file = language_combobox->currentData().toString(); - if (Olive::CurrentConfig.thumbnail_resolution != thumbnail_res_spinbox->value() - || Olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()) { + if (olive::CurrentConfig.thumbnail_resolution != thumbnail_res_spinbox->value() + || olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()) { // we're changing the size of thumbnails and waveforms, so let's delete them and regenerate them next start // delete nothing char delete_match = 0; - if (Olive::CurrentConfig.thumbnail_resolution != thumbnail_res_spinbox->value()) { + if (olive::CurrentConfig.thumbnail_resolution != thumbnail_res_spinbox->value()) { // delete existing thumbnails - Olive::CurrentConfig.thumbnail_resolution = thumbnail_res_spinbox->value(); + olive::CurrentConfig.thumbnail_resolution = thumbnail_res_spinbox->value(); // delete only thumbnails delete_match = 't'; } - if (Olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()) { + if (olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()) { // delete existing waveforms - Olive::CurrentConfig.waveform_resolution = waveform_res_spinbox->value(); + olive::CurrentConfig.waveform_resolution = waveform_res_spinbox->value(); // if we're already deleting thumbnails if (delete_match == 't') { @@ -288,11 +288,11 @@ void PreferencesDialog::save() { if (restart_after_saving) { // since we already ran can_close_project(), bypass checking again by running setWindowModified(false) - Olive::MainWindow->setWindowModified(false); + olive::MainWindow->setWindowModified(false); - Olive::MainWindow->close(); + olive::MainWindow->close(); - QProcess::startDetached(QApplication::applicationFilePath(), { Olive::ActiveProjectFilename }); + QProcess::startDetached(QApplication::applicationFilePath(), { olive::ActiveProjectFilename }); } } @@ -468,7 +468,7 @@ void PreferencesDialog::setup_ui() { QString locale_str = locale_file_basename.mid(locale_file_basename.lastIndexOf('_')+1); language_combobox->addItem(QLocale(locale_str).nativeLanguageName(), locale_relative_path); - if (Olive::CurrentConfig.language_file == locale_relative_path) { + if (olive::CurrentConfig.language_file == locale_relative_path) { language_combobox->setCurrentIndex(language_combobox->count() - 1); } } @@ -483,7 +483,7 @@ void PreferencesDialog::setup_ui() { general_layout->addWidget(new QLabel(tr("Custom CSS:"), this), row, 0); custom_css_fn = new QLineEdit(general_tab); - custom_css_fn->setText(Olive::CurrentConfig.css_path); + custom_css_fn->setText(olive::CurrentConfig.css_path); general_layout->addWidget(custom_css_fn, row, 1, 1, 3); QPushButton* custom_css_browse = new QPushButton(tr("Browse"), general_tab); @@ -516,7 +516,7 @@ void PreferencesDialog::setup_ui() { effect_textbox_lines_field = new QSpinBox(general_tab); effect_textbox_lines_field->setMinimum(1); - effect_textbox_lines_field->setValue(Olive::CurrentConfig.effect_textbox_lines); + effect_textbox_lines_field->setValue(olive::CurrentConfig.effect_textbox_lines); general_layout->addWidget(effect_textbox_lines_field, row, 1, 1, 4); row++; @@ -527,7 +527,7 @@ void PreferencesDialog::setup_ui() { thumbnail_res_spinbox = new QSpinBox(this); thumbnail_res_spinbox->setMinimum(0); thumbnail_res_spinbox->setMaximum(INT_MAX); - thumbnail_res_spinbox->setValue(Olive::CurrentConfig.thumbnail_resolution); + thumbnail_res_spinbox->setValue(olive::CurrentConfig.thumbnail_resolution); general_layout->addWidget(thumbnail_res_spinbox, row, 1); general_layout->addWidget(new QLabel(tr("Waveform Resolution:"), this), row, 2); @@ -535,7 +535,7 @@ void PreferencesDialog::setup_ui() { waveform_res_spinbox = new QSpinBox(this); waveform_res_spinbox->setMinimum(0); waveform_res_spinbox->setMaximum(INT_MAX); - waveform_res_spinbox->setValue(Olive::CurrentConfig.waveform_resolution); + waveform_res_spinbox->setValue(olive::CurrentConfig.waveform_resolution); general_layout->addWidget(waveform_res_spinbox, row, 3); QPushButton* delete_preview_btn = new QPushButton(tr("Delete Previews")); @@ -547,7 +547,7 @@ void PreferencesDialog::setup_ui() { // General -> Use Software Fallbacks When Possible use_software_fallbacks_checkbox = new QCheckBox(general_tab); use_software_fallbacks_checkbox->setText(tr("Use Software Fallbacks When Possible")); - use_software_fallbacks_checkbox->setChecked(Olive::CurrentConfig.use_software_fallback); + use_software_fallbacks_checkbox->setChecked(olive::CurrentConfig.use_software_fallback); general_layout->addWidget(use_software_fallbacks_checkbox, row, 0, 1, 4); tabWidget->addTab(general_tab, tr("General")); @@ -559,7 +559,7 @@ void PreferencesDialog::setup_ui() { QVBoxLayout* behavior_tab_layout = new QVBoxLayout(behavior_tab); add_default_effects_to_clips = new QCheckBox("Add Default Effects to New Clips"); - add_default_effects_to_clips->setChecked(Olive::CurrentConfig.add_default_effects_to_clips); + add_default_effects_to_clips->setChecked(olive::CurrentConfig.add_default_effects_to_clips); behavior_tab_layout->addWidget(add_default_effects_to_clips); // Playback @@ -584,21 +584,21 @@ void PreferencesDialog::setup_ui() { QGridLayout* memory_usage_layout = new QGridLayout(memory_usage_group); memory_usage_layout->addWidget(new QLabel(tr("Upcoming Frame Queue:"), playback_tab), 0, 0); upcoming_queue_spinbox = new QDoubleSpinBox(playback_tab); - upcoming_queue_spinbox->setValue(Olive::CurrentConfig.upcoming_queue_size); + upcoming_queue_spinbox->setValue(olive::CurrentConfig.upcoming_queue_size); memory_usage_layout->addWidget(upcoming_queue_spinbox, 0, 1); upcoming_queue_type = new QComboBox(playback_tab); upcoming_queue_type->addItem(tr("frames")); upcoming_queue_type->addItem(tr("seconds")); - upcoming_queue_type->setCurrentIndex(Olive::CurrentConfig.upcoming_queue_type); + upcoming_queue_type->setCurrentIndex(olive::CurrentConfig.upcoming_queue_type); memory_usage_layout->addWidget(upcoming_queue_type, 0, 2); memory_usage_layout->addWidget(new QLabel(tr("Previous Frame Queue:"), playback_tab), 1, 0); previous_queue_spinbox = new QDoubleSpinBox(playback_tab); - previous_queue_spinbox->setValue(Olive::CurrentConfig.previous_queue_size); + previous_queue_spinbox->setValue(olive::CurrentConfig.previous_queue_size); memory_usage_layout->addWidget(previous_queue_spinbox, 1, 1); previous_queue_type = new QComboBox(playback_tab); previous_queue_type->addItem(tr("frames")); previous_queue_type->addItem(tr("seconds")); - previous_queue_type->setCurrentIndex(Olive::CurrentConfig.previous_queue_type); + previous_queue_type->setCurrentIndex(olive::CurrentConfig.previous_queue_type); memory_usage_layout->addWidget(previous_queue_type, 1, 2); playback_tab_layout->addWidget(memory_usage_group); @@ -620,7 +620,7 @@ void PreferencesDialog::setup_ui() { for (int i=0;iaddItem(devs.at(i).deviceName(), devs.at(i).deviceName()); if (!found_preferred_device - && devs.at(i).deviceName() == Olive::CurrentConfig.preferred_audio_output) { + && devs.at(i).deviceName() == olive::CurrentConfig.preferred_audio_output) { audio_output_devices->setCurrentIndex(audio_output_devices->count()-1); found_preferred_device = true; } @@ -639,7 +639,7 @@ void PreferencesDialog::setup_ui() { for (int i=0;iaddItem(devs.at(i).deviceName(), devs.at(i).deviceName()); if (!found_preferred_device - && devs.at(i).deviceName() == Olive::CurrentConfig.preferred_audio_input) { + && devs.at(i).deviceName() == olive::CurrentConfig.preferred_audio_input) { audio_input_devices->setCurrentIndex(audio_input_devices->count()-1); found_preferred_device = true; } @@ -652,7 +652,7 @@ void PreferencesDialog::setup_ui() { audio_sample_rate = new QComboBox(); combobox_audio_sample_rates(audio_sample_rate); for (int i=0;icount();i++) { - if (audio_sample_rate->itemData(i).toInt() == Olive::CurrentConfig.audio_rate) { + if (audio_sample_rate->itemData(i).toInt() == olive::CurrentConfig.audio_rate) { audio_sample_rate->setCurrentIndex(i); break; } diff --git a/dialogs/proxydialog.cpp b/dialogs/proxydialog.cpp index f73195670..4c989f466 100644 --- a/dialogs/proxydialog.cpp +++ b/dialogs/proxydialog.cpp @@ -152,7 +152,7 @@ void ProxyDialog::accept() { proxy_generator.queue(info_list.at(i)); } - Olive::MainWindow->setWindowModified(true); + olive::MainWindow->setWindowModified(true); QDialog::accept(); } diff --git a/dialogs/replaceclipmediadialog.cpp b/dialogs/replaceclipmediadialog.cpp index 1f42a910a..e9d5c2739 100644 --- a/dialogs/replaceclipmediadialog.cpp +++ b/dialogs/replaceclipmediadialog.cpp @@ -96,7 +96,7 @@ void ReplaceClipMediaDialog::replace() { QMessageBox::Ok ); } else { - if (new_item->get_type() == MEDIA_TYPE_SEQUENCE && Olive::ActiveSequence == new_item->to_sequence()) { + if (new_item->get_type() == MEDIA_TYPE_SEQUENCE && olive::ActiveSequence == new_item->to_sequence()) { QMessageBox::critical( this, tr("Active sequence selected"), @@ -110,14 +110,14 @@ void ReplaceClipMediaDialog::replace() { use_same_media_in_points->isChecked() ); - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr && c->media == media) { rcmc->clips.append(c); } } - Olive::UndoStack.push(rcmc); + olive::UndoStack.push(rcmc); close(); } diff --git a/dialogs/speeddialog.cpp b/dialogs/speeddialog.cpp index 37c65c157..76dac52c8 100644 --- a/dialogs/speeddialog.cpp +++ b/dialogs/speeddialog.cpp @@ -58,7 +58,7 @@ SpeedDialog::SpeedDialog(QWidget *parent) : QDialog(parent) { grid->addWidget(new QLabel(tr("Duration:"), this), 2, 0); duration = new LabelSlider(this); duration->set_display_type(LABELSLIDER_FRAMENUMBER); - duration->set_frame_rate(Olive::ActiveSequence->frame_rate); + duration->set_frame_rate(olive::ActiveSequence->frame_rate); grid->addWidget(duration, 2, 1); main_layout->addLayout(grid); @@ -339,14 +339,14 @@ void set_speed(ComboAction* ca, Clip* c, double speed, bool ripple, long& ep, lo sel.in = c->timeline_in; sel.out = proposed_out; sel.track = c->track; - Olive::ActiveSequence->selections.append(sel); + olive::ActiveSequence->selections.append(sel); } void SpeedDialog::accept() { ComboAction* ca = new ComboAction(); - SetSelectionsCommand* sel_command = new SetSelectionsCommand(Olive::ActiveSequence); - sel_command->old_data = Olive::ActiveSequence->selections; + SetSelectionsCommand* sel_command = new SetSelectionsCommand(olive::ActiveSequence); + sel_command->old_data = olive::ActiveSequence->selections; long earliest_point = LONG_MAX; long longest_ripple = LONG_MIN; @@ -419,10 +419,10 @@ void SpeedDialog::accept() { ripple_clips(ca, clips.at(0)->sequence, earliest_point, longest_ripple); } - sel_command->new_data = Olive::ActiveSequence->selections; + sel_command->new_data = olive::ActiveSequence->selections; ca->append(sel_command); - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); update_ui(true); QDialog::accept(); diff --git a/effects/internal/texteffect.cpp b/effects/internal/texteffect.cpp index f64595e30..3c4a88504 100644 --- a/effects/internal/texteffect.cpp +++ b/effects/internal/texteffect.cpp @@ -330,7 +330,7 @@ void TextEffect::text_edit_menu() { } void TextEffect::open_text_edit() { - TextEditDialog ted(Olive::MainWindow, text_val->get_current_data().toString()); + TextEditDialog ted(olive::MainWindow, text_val->get_current_data().toString()); ted.exec(); QString result = ted.get_string(); if (!result.isEmpty()) { diff --git a/effects/internal/timecodeeffect.cpp b/effects/internal/timecodeeffect.cpp index 495ee5874..16e012741 100644 --- a/effects/internal/timecodeeffect.cpp +++ b/effects/internal/timecodeeffect.cpp @@ -82,10 +82,10 @@ TimecodeEffect::TimecodeEffect(Clip *c, const EffectMeta* em) : void TimecodeEffect::redraw(double timecode) { if (tc_select->get_combo_data(timecode).toBool()){ - display_timecode = prepend_text->get_string_value(timecode) + frame_to_timecode(Olive::ActiveSequence->playhead, Olive::CurrentConfig.timecode_view, Olive::ActiveSequence->frame_rate);} + display_timecode = prepend_text->get_string_value(timecode) + frame_to_timecode(olive::ActiveSequence->playhead, olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate);} else { double media_rate = parent_clip->getMediaFrameRate(); - display_timecode = prepend_text->get_string_value(timecode) + frame_to_timecode(timecode * media_rate, Olive::CurrentConfig.timecode_view, media_rate);} + display_timecode = prepend_text->get_string_value(timecode) + frame_to_timecode(timecode * media_rate, olive::CurrentConfig.timecode_view, media_rate);} img.fill(Qt::transparent); QPainter p(&img); diff --git a/effects/internal/vsthost.cpp b/effects/internal/vsthost.cpp index 3e74635e6..02ecd3fdd 100644 --- a/effects/internal/vsthost.cpp +++ b/effects/internal/vsthost.cpp @@ -85,7 +85,7 @@ extern "C" { // but we are aware of it break; case audioMasterEndEdit: // change made - Olive::MainWindow->setWindowModified(true); + olive::MainWindow->setWindowModified(true); break; default: qInfo() << "Plugin requested unhandled opcode" << opcode; @@ -200,7 +200,7 @@ bool VSTHost::configurePluginCallbacks() { // real VST plugin, or is otherwise corrupt. if(plugin->magic != kEffectMagic) { qCritical() << "Plugin's magic number is bad"; - QMessageBox::critical(Olive::MainWindow, tr("VST Error"), tr("Plugin's magic number is invalid")); + QMessageBox::critical(olive::MainWindow, tr("VST Error"), tr("Plugin's magic number is invalid")); return false; } @@ -272,7 +272,7 @@ VSTHost::VSTHost(Clip* c, const EffectMeta *em) : Effect(c, em) { connect(show_interface_btn, SIGNAL(toggled(bool)), this, SLOT(show_interface(bool))); interface_row->add_widget(show_interface_btn); - dialog = new QDialog(Olive::MainWindow); + dialog = new QDialog(olive::MainWindow); dialog->setWindowTitle(tr("VST Plugin")); dialog->setAttribute(Qt::WA_NativeWindow, true); dialog->setWindowFlags(dialog->windowFlags() | Qt::MSWindowsFixedSizeDialogHint); diff --git a/io/config.cpp b/io/config.cpp index ec273992e..133dad50a 100644 --- a/io/config.cpp +++ b/io/config.cpp @@ -29,8 +29,8 @@ #include "debug.h" -Config Olive::CurrentConfig; -RuntimeConfig Olive::CurrentRuntimeConfig; +Config olive::CurrentConfig; +RuntimeConfig olive::CurrentRuntimeConfig; Config::Config() : saved_layout(false), diff --git a/io/config.h b/io/config.h index da598fae3..23a6a86b9 100644 --- a/io/config.h +++ b/io/config.h @@ -103,7 +103,7 @@ struct RuntimeConfig { QString external_translation_file; }; -namespace Olive { +namespace olive { extern Config CurrentConfig; extern RuntimeConfig CurrentRuntimeConfig; } diff --git a/io/exportthread.cpp b/io/exportthread.cpp index 2330ca985..3a7dac959 100644 --- a/io/exportthread.cpp +++ b/io/exportthread.cpp @@ -183,15 +183,15 @@ bool ExportThread::setupVideo() { video_frame = av_frame_alloc(); av_frame_make_writable(video_frame); video_frame->format = AV_PIX_FMT_RGBA; - video_frame->width = Olive::ActiveSequence->width; - video_frame->height = Olive::ActiveSequence->height; + video_frame->width = olive::ActiveSequence->width; + video_frame->height = olive::ActiveSequence->height; av_frame_get_buffer(video_frame, 0); av_init_packet(&video_pkt); sws_ctx = sws_getContext( - Olive::ActiveSequence->width, - Olive::ActiveSequence->height, + olive::ActiveSequence->width, + olive::ActiveSequence->height, AV_PIX_FMT_RGBA, params.video_width, params.video_height, @@ -274,9 +274,9 @@ bool ExportThread::setupAudio() { acodec_ctx->channel_layout, acodec_ctx->sample_fmt, acodec_ctx->sample_rate, - Olive::ActiveSequence->audio_layout, + olive::ActiveSequence->audio_layout, AV_SAMPLE_FMT_S16, - Olive::ActiveSequence->audio_frequency, + olive::ActiveSequence->audio_frequency, 0, nullptr ); @@ -284,7 +284,7 @@ bool ExportThread::setupAudio() { // initialize raw audio frame audio_frame = av_frame_alloc(); - audio_frame->sample_rate = Olive::ActiveSequence->audio_frequency; + audio_frame->sample_rate = olive::ActiveSequence->audio_frequency; audio_frame->nb_samples = acodec_ctx->frame_size; if (audio_frame->nb_samples == 0) audio_frame->nb_samples = 256; // should possibly be smaller? audio_frame->format = AV_SAMPLE_FMT_S16; @@ -366,16 +366,16 @@ void ExportThread::run() { mutex.lock(); - while (Olive::ActiveSequence->playhead <= params.end_frame && continueEncode) { + while (olive::ActiveSequence->playhead <= params.end_frame && continueEncode) { start_time = QDateTime::currentMSecsSinceEpoch(); if (params.audio_enabled) { - compose_audio(nullptr, Olive::ActiveSequence, 1); + compose_audio(nullptr, olive::ActiveSequence, 1); } if (params.video_enabled) { do { // TODO optimize by rendering the next frame while encoding the last - renderer->start_render(nullptr, Olive::ActiveSequence, nullptr, video_frame->data[0], video_frame->linesize[0]/4); + renderer->start_render(nullptr, olive::ActiveSequence, nullptr, video_frame->data[0], video_frame->linesize[0]/4); waitCond.wait(&mutex); if (!continueEncode) break; } while (renderer->did_texture_fail()); @@ -383,7 +383,7 @@ void ExportThread::run() { } // encode last frame while rendering next frame - double timecode_secs = double(Olive::ActiveSequence->playhead - params.start_frame) / Olive::ActiveSequence->frame_rate; + double timecode_secs = double(olive::ActiveSequence->playhead - params.start_frame) / olive::ActiveSequence->frame_rate; if (params.video_enabled) { // create sws_frame for converting pixel format @@ -444,12 +444,12 @@ void ExportThread::run() { // generating encoding statistics (time it took to encode this frame/estimated remaining time) frame_time = (QDateTime::currentMSecsSinceEpoch()-start_time); total_time += frame_time; - remaining_frames = (params.end_frame - Olive::ActiveSequence->playhead); + remaining_frames = (params.end_frame - olive::ActiveSequence->playhead); avg_time = (total_time/frame_count); eta = (remaining_frames*avg_time); - emit progress_changed(qRound((double(Olive::ActiveSequence->playhead - params.start_frame) / double(params.end_frame - params.start_frame)) * 100.0), eta); - Olive::ActiveSequence->playhead++; + emit progress_changed(qRound((double(olive::ActiveSequence->playhead - params.start_frame) / double(params.end_frame - params.start_frame)) * 100.0), eta); + olive::ActiveSequence->playhead++; frame_count++; } @@ -463,7 +463,7 @@ void ExportThread::run() { if (params.audio_enabled) apkt_alloc = true; } - Olive::Global.data()->set_rendering_state(false); + olive::Global->set_rendering_state(false); if (params.audio_enabled && continueEncode) { // flush swresample diff --git a/io/loadthread.cpp b/io/loadthread.cpp index bde477567..906d8af41 100644 --- a/io/loadthread.cpp +++ b/io/loadthread.cpp @@ -584,7 +584,7 @@ Media* LoadThread::find_loaded_folder_by_id(int id) { void LoadThread::run() { mutex.lock(); - QFile file(Olive::ActiveProjectFilename); + QFile file(olive::ActiveProjectFilename); if (!file.open(QIODevice::ReadOnly)) { qCritical() << "Could not open file"; return; @@ -595,9 +595,9 @@ void LoadThread::run() { * case the project file has moved without the footage, * we check both */ - proj_dir = QFileInfo(Olive::ActiveProjectFilename).absoluteDir(); - internal_proj_dir = QFileInfo(Olive::ActiveProjectFilename).absoluteDir(); - internal_proj_url = Olive::ActiveProjectFilename; + proj_dir = QFileInfo(olive::ActiveProjectFilename).absoluteDir(); + internal_proj_dir = QFileInfo(olive::ActiveProjectFilename).absoluteDir(); + internal_proj_url = olive::ActiveProjectFilename; QXmlStreamReader stream(&file); @@ -709,7 +709,7 @@ void LoadThread::cancel() { void LoadThread::question_func(const QString &title, const QString &text, int buttons) { mutex.lock(); question_btn = QMessageBox::warning( - Olive::MainWindow, + olive::MainWindow, title, text, static_cast(buttons)); @@ -720,12 +720,12 @@ void LoadThread::question_func(const QString &title, const QString &text, int bu void LoadThread::error_func() { if (xml_error) { qCritical() << "Error parsing XML." << error_str; - QMessageBox::critical(Olive::MainWindow, + QMessageBox::critical(olive::MainWindow, tr("XML Parsing Error"), - tr("Couldn't load '%1'. %2").arg(Olive::ActiveProjectFilename, error_str), + tr("Couldn't load '%1'. %2").arg(olive::ActiveProjectFilename, error_str), QMessageBox::Ok); } else { - QMessageBox::critical(Olive::MainWindow, + QMessageBox::critical(olive::MainWindow, tr("Project Load Error"), tr("Error loading project: %1").arg(error_str), QMessageBox::Ok); @@ -748,12 +748,12 @@ void LoadThread::success_func() { counter++; } - Olive::Global.data()->update_project_filename(orig_filename); + olive::Global->update_project_filename(orig_filename); } else { - panel_project->add_recent_project(Olive::ActiveProjectFilename); + panel_project->add_recent_project(olive::ActiveProjectFilename); } - Olive::MainWindow->setWindowModified(autorecovery); + olive::MainWindow->setWindowModified(autorecovery); if (open_seq != nullptr) set_sequence(open_seq); update_ui(false); } diff --git a/io/previewgenerator.cpp b/io/previewgenerator.cpp index 20fb69fa0..8569af840 100644 --- a/io/previewgenerator.cpp +++ b/io/previewgenerator.cpp @@ -242,8 +242,8 @@ void PreviewGenerator::generate_waveform() { // we only generate previews for video and audio // and only if the thumbnail and waveform sizes are > 0 - if ((fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && Olive::CurrentConfig.thumbnail_resolution > 0) - || (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && Olive::CurrentConfig.waveform_resolution > 0)) { + if ((fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && olive::CurrentConfig.thumbnail_resolution > 0) + || (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && olive::CurrentConfig.waveform_resolution > 0)) { AVCodec* codec = avcodec_find_decoder(fmt_ctx->streams[i]->codecpar->codec_id); if (codec != nullptr) { @@ -318,7 +318,7 @@ void PreviewGenerator::generate_waveform() { if (s != nullptr) { if (fmt_ctx->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { if (!s->preview_done) { - int dstH = Olive::CurrentConfig.thumbnail_resolution; + int dstH = olive::CurrentConfig.thumbnail_resolution; int dstW = qRound(dstH * (float(temp_frame->width)/float(temp_frame->height))); uint8_t* data = new uint8_t[size_t(dstW*dstH*4)]; @@ -381,7 +381,7 @@ void PreviewGenerator::generate_waveform() { // `config.waveform_resolution` determines how many samples per second are stored in waveform. // `sample_rate` is samples per second, so `interval` is how many samples are averaged in // each "point" of the waveform - int interval = qFloor((temp_frame->sample_rate/Olive::CurrentConfig.waveform_resolution)/4)*4; + int interval = qFloor((temp_frame->sample_rate/olive::CurrentConfig.waveform_resolution)/4)*4; // get the amount of bytes in an audio sample int sample_size = av_get_bytes_per_sample(static_cast(swr_frame->format)); diff --git a/io/proxygenerator.cpp b/io/proxygenerator.cpp index fb2dd74e1..640433e42 100644 --- a/io/proxygenerator.cpp +++ b/io/proxygenerator.cpp @@ -316,7 +316,7 @@ void ProxyGenerator::transcode(const ProxyInfo& info) { info.footage->proxy_path = info.path; qInfo() << "Finished creating proxy for" << info.footage->url; - QMetaObject::invokeMethod(Olive::MainWindow->statusBar(), + QMetaObject::invokeMethod(olive::MainWindow->statusBar(), "showMessage", Qt::QueuedConnection, Q_ARG(QString, tr("Finished generating proxy for \"%1\"").arg(info.footage->url))); diff --git a/main.cpp b/main.cpp index 34cbf88c6..3e2307b24 100644 --- a/main.cpp +++ b/main.cpp @@ -33,7 +33,7 @@ extern "C" { } int main(int argc, char *argv[]) { - Olive::Global = QSharedPointer(new OliveGlobal); + olive::Global = std::unique_ptr(new OliveGlobal); bool launch_fullscreen = false; QString load_proj; @@ -47,7 +47,7 @@ int main(int argc, char *argv[]) { #ifndef GITHASH qWarning() << "No Git commit information found"; #endif - printf("%s\n", Olive::AppName.toUtf8().constData()); + printf("%s\n", olive::AppName.toUtf8().constData()); return 0; } else if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) { printf("Usage: %s [options] [filename]\n\n" @@ -70,15 +70,15 @@ int main(int argc, char *argv[]) { } else if (!strcmp(argv[i], "--fullscreen") || !strcmp(argv[i], "-f")) { launch_fullscreen = true; } else if (!strcmp(argv[i], "--disable-shaders")) { - Olive::CurrentRuntimeConfig.shaders_are_enabled = false; + olive::CurrentRuntimeConfig.shaders_are_enabled = false; } else if (!strcmp(argv[i], "--no-debug")) { use_internal_logger = false; } else if (!strcmp(argv[i], "--disable-blend-modes")) { - Olive::CurrentRuntimeConfig.disable_blending = true; + olive::CurrentRuntimeConfig.disable_blending = true; } else if (!strcmp(argv[i], "--translation")) { if (i + 1 < argc && argv[i + 1][0] != '-') { // load translation file - Olive::CurrentRuntimeConfig.external_translation_file = argv[i + 1]; + olive::CurrentRuntimeConfig.external_translation_file = argv[i + 1]; i++; } else { @@ -117,10 +117,10 @@ int main(int argc, char *argv[]) { MainWindow w(nullptr); // connect main window's first paint to global's init finished function - QObject::connect(&w, SIGNAL(finished_first_paint()), Olive::Global.data(), SLOT(finished_initialize())); + QObject::connect(&w, SIGNAL(finished_first_paint()), olive::Global.get(), SLOT(finished_initialize())); if (!load_proj.isEmpty()) { - Olive::Global.data()->load_project_on_launch(load_proj); + olive::Global->load_project_on_launch(load_proj); } if (launch_fullscreen) { w.showFullScreen(); diff --git a/mainwindow.cpp b/mainwindow.cpp index 9e3759825..c2d6124ee 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -64,7 +64,7 @@ #include #include -MainWindow* Olive::MainWindow; +MainWindow* olive::MainWindow; #define DEFAULT_CSS "QPushButton::checked { background: rgb(25, 25, 25); }" @@ -104,9 +104,9 @@ MainWindow::MainWindow(QWidget *parent) : open_debug_file(); - Olive::DebugDialog = new DebugDialog(this); + olive::DebugDialog = new DebugDialog(this); - Olive::MainWindow = this; + olive::MainWindow = this; // set up style? @@ -179,7 +179,7 @@ MainWindow::MainWindow(QWidget *parent) : } // search for open recents list - QFile f(Olive::Global.data()->get_recent_project_list_file()); + QFile f(olive::Global->get_recent_project_list_file()); if (f.exists() && f.open(QFile::ReadOnly | QFile::Text)) { QTextStream text_stream(&f); while (true) { @@ -200,18 +200,18 @@ MainWindow::MainWindow(QWidget *parent) : config_dir.mkpath("."); QString config_fn = config_dir.filePath("config.xml"); if (QFileInfo::exists(config_fn)) { - Olive::CurrentConfig.load(config_fn); + olive::CurrentConfig.load(config_fn); - if (!Olive::CurrentConfig.css_path.isEmpty()) { - load_css_from_file(Olive::CurrentConfig.css_path); + if (!olive::CurrentConfig.css_path.isEmpty()) { + load_css_from_file(olive::CurrentConfig.css_path); } } } // load preferred language from file - QString language_file = Olive::CurrentRuntimeConfig.external_translation_file.isEmpty() ? - Olive::CurrentConfig.language_file : - Olive::CurrentRuntimeConfig.external_translation_file; + QString language_file = olive::CurrentRuntimeConfig.external_translation_file.isEmpty() ? + olive::CurrentConfig.language_file : + olive::CurrentRuntimeConfig.external_translation_file; if (!language_file.isEmpty()) { @@ -230,13 +230,13 @@ MainWindow::MainWindow(QWidget *parent) : alloc_panels(this); QStatusBar* statusBar = new QStatusBar(this); - statusBar->showMessage(tr("Welcome to %1").arg(Olive::AppName)); + statusBar->showMessage(tr("Welcome to %1").arg(olive::AppName)); setStatusBar(statusBar); // populate menu bars setup_menus(); - Olive::Global.data()->check_for_autorecovery_file(); + olive::Global->check_for_autorecovery_file(); // set up panel layout setup_layout(false); @@ -349,8 +349,8 @@ void MainWindow::load_css_from_file(const QString &fn) { } void MainWindow::editMenu_About_To_Be_Shown() { - undo_action->setEnabled(Olive::UndoStack.canUndo()); - redo_action->setEnabled(Olive::UndoStack.canRedo()); + undo_action->setEnabled(olive::UndoStack.canUndo()); + redo_action->setEnabled(olive::UndoStack.canRedo()); } void MainWindow::setup_menus() { @@ -363,9 +363,9 @@ void MainWindow::setup_menus() { connect(file_menu, SIGNAL(aboutToShow()), this, SLOT(fileMenu_About_To_Be_Shown())); QMenu* new_menu = file_menu->addMenu(tr("&New")); - Olive::MenuHelper.make_new_menu(new_menu); + olive::MenuHelper.make_new_menu(new_menu); - file_menu->addAction(tr("&Open Project"), Olive::Global.data(), SLOT(open_project()), QKeySequence("Ctrl+O"))->setProperty("id", "openproj"); + file_menu->addAction(tr("&Open Project"), olive::Global.get(), SLOT(open_project()), QKeySequence("Ctrl+O"))->setProperty("id", "openproj"); clear_open_recent_action = new QAction(tr("Clear Recent List"), menuBar); clear_open_recent_action->setProperty("id", "clearopenrecent"); @@ -375,8 +375,8 @@ void MainWindow::setup_menus() { open_recent->addAction(clear_open_recent_action); - file_menu->addAction(tr("&Save Project"), Olive::Global.data(), SLOT(save_project()), QKeySequence("Ctrl+S"))->setProperty("id", "saveproj"); - file_menu->addAction(tr("Save Project &As"), Olive::Global.data(), SLOT(save_project_as()), QKeySequence("Ctrl+Shift+S"))->setProperty("id", "saveprojas"); + file_menu->addAction(tr("&Save Project"), olive::Global.get(), SLOT(save_project()), QKeySequence("Ctrl+S"))->setProperty("id", "saveproj"); + file_menu->addAction(tr("Save Project &As"), olive::Global.get(), SLOT(save_project_as()), QKeySequence("Ctrl+Shift+S"))->setProperty("id", "saveprojas"); file_menu->addSeparator(); @@ -384,7 +384,7 @@ void MainWindow::setup_menus() { file_menu->addSeparator(); - file_menu->addAction(tr("&Export..."), Olive::Global.data(), SLOT(open_export_dialog()), QKeySequence("Ctrl+M"))->setProperty("id", "export"); + file_menu->addAction(tr("&Export..."), olive::Global.get(), SLOT(open_export_dialog()), QKeySequence("Ctrl+M"))->setProperty("id", "export"); file_menu->addSeparator(); @@ -395,24 +395,24 @@ void MainWindow::setup_menus() { QMenu* edit_menu = menuBar->addMenu(tr("&Edit")); connect(edit_menu, SIGNAL(aboutToShow()), this, SLOT(editMenu_About_To_Be_Shown())); - undo_action = edit_menu->addAction(tr("&Undo"), Olive::Global.data(), SLOT(undo()), QKeySequence("Ctrl+Z")); + undo_action = edit_menu->addAction(tr("&Undo"), olive::Global.get(), SLOT(undo()), QKeySequence("Ctrl+Z")); undo_action->setProperty("id", "undo"); - redo_action = edit_menu->addAction(tr("Redo"), Olive::Global.data(), SLOT(redo()), QKeySequence("Ctrl+Shift+Z")); + redo_action = edit_menu->addAction(tr("Redo"), olive::Global.get(), SLOT(redo()), QKeySequence("Ctrl+Shift+Z")); redo_action->setProperty("id", "redo"); edit_menu->addSeparator(); - Olive::MenuHelper.make_edit_functions_menu(edit_menu); + olive::MenuHelper.make_edit_functions_menu(edit_menu); edit_menu->addSeparator(); - edit_menu->addAction(tr("Select &All"), &Olive::FocusFilter, SLOT(select_all()), QKeySequence("Ctrl+A"))->setProperty("id", "selectall"); + edit_menu->addAction(tr("Select &All"), &olive::FocusFilter, SLOT(select_all()), QKeySequence("Ctrl+A"))->setProperty("id", "selectall"); edit_menu->addAction(tr("Deselect All"), panel_timeline, SLOT(deselect()), QKeySequence("Ctrl+Shift+A"))->setProperty("id", "deselectall"); edit_menu->addSeparator(); - Olive::MenuHelper.make_clip_functions_menu(edit_menu); + olive::MenuHelper.make_clip_functions_menu(edit_menu); edit_menu->addSeparator(); @@ -423,21 +423,21 @@ void MainWindow::setup_menus() { edit_menu->addSeparator(); - Olive::MenuHelper.make_inout_menu(edit_menu); + olive::MenuHelper.make_inout_menu(edit_menu); edit_menu->addAction(tr("Delete In/Out Point"), panel_timeline, SLOT(delete_inout()), QKeySequence(";"))->setProperty("id", "deleteinout"); edit_menu->addAction(tr("Ripple Delete In/Out Point"), panel_timeline, SLOT(ripple_delete_inout()), QKeySequence("'"))->setProperty("id", "rippledeleteinout"); edit_menu->addSeparator(); - edit_menu->addAction(tr("Set/Edit Marker"), &Olive::FocusFilter, SLOT(set_marker()), QKeySequence("M"))->setProperty("id", "marker"); + edit_menu->addAction(tr("Set/Edit Marker"), &olive::FocusFilter, SLOT(set_marker()), QKeySequence("M"))->setProperty("id", "marker"); // INITIALIZE VIEW MENU QMenu* view_menu = menuBar->addMenu(tr("&View")); connect(view_menu, SIGNAL(aboutToShow()), this, SLOT(viewMenu_About_To_Be_Shown())); - view_menu->addAction(tr("Zoom In"), &Olive::FocusFilter, SLOT(zoom_in()), QKeySequence("="))->setProperty("id", "zoomin"); - view_menu->addAction(tr("Zoom Out"), &Olive::FocusFilter, SLOT(zoom_out()), QKeySequence("-"))->setProperty("id", "zoomout"); + view_menu->addAction(tr("Zoom In"), &olive::FocusFilter, SLOT(zoom_in()), QKeySequence("="))->setProperty("id", "zoomin"); + view_menu->addAction(tr("Zoom Out"), &olive::FocusFilter, SLOT(zoom_out()), QKeySequence("-"))->setProperty("id", "zoomout"); view_menu->addAction(tr("Increase Track Height"), panel_timeline, SLOT(increase_track_height()), QKeySequence("Ctrl+="))->setProperty("id", "vzoomin"); view_menu->addAction(tr("Decrease Track Height"), panel_timeline, SLOT(decrease_track_height()), QKeySequence("Ctrl+-"))->setProperty("id", "vzoomout"); @@ -447,31 +447,31 @@ void MainWindow::setup_menus() { view_menu->addSeparator(); - track_lines = view_menu->addAction(tr("Track Lines"), &Olive::MenuHelper, SLOT(toggle_bool_action())); + track_lines = view_menu->addAction(tr("Track Lines"), &olive::MenuHelper, SLOT(toggle_bool_action())); track_lines->setProperty("id", "tracklines"); track_lines->setCheckable(true); - track_lines->setData(reinterpret_cast(&Olive::CurrentConfig.show_track_lines)); + track_lines->setData(reinterpret_cast(&olive::CurrentConfig.show_track_lines)); - rectified_waveforms = view_menu->addAction(tr("Rectified Waveforms"), &Olive::MenuHelper, SLOT(toggle_bool_action())); + rectified_waveforms = view_menu->addAction(tr("Rectified Waveforms"), &olive::MenuHelper, SLOT(toggle_bool_action())); rectified_waveforms->setProperty("id", "rectifiedwaveforms"); rectified_waveforms->setCheckable(true); - rectified_waveforms->setData(reinterpret_cast(&Olive::CurrentConfig.rectified_waveforms)); + rectified_waveforms->setData(reinterpret_cast(&olive::CurrentConfig.rectified_waveforms)); view_menu->addSeparator(); - frames_action = view_menu->addAction(tr("Frames"), &Olive::MenuHelper, SLOT(set_timecode_view())); + frames_action = view_menu->addAction(tr("Frames"), &olive::MenuHelper, SLOT(set_timecode_view())); frames_action->setProperty("id", "modeframes"); frames_action->setData(TIMECODE_FRAMES); frames_action->setCheckable(true); - drop_frame_action = view_menu->addAction(tr("Drop Frame"), &Olive::MenuHelper, SLOT(set_timecode_view())); + drop_frame_action = view_menu->addAction(tr("Drop Frame"), &olive::MenuHelper, SLOT(set_timecode_view())); drop_frame_action->setProperty("id", "modedropframe"); drop_frame_action->setData(TIMECODE_DROP); drop_frame_action->setCheckable(true); - nondrop_frame_action = view_menu->addAction(tr("Non-Drop Frame"), &Olive::MenuHelper, SLOT(set_timecode_view())); + nondrop_frame_action = view_menu->addAction(tr("Non-Drop Frame"), &olive::MenuHelper, SLOT(set_timecode_view())); nondrop_frame_action->setProperty("id", "modenondropframe"); nondrop_frame_action->setData(TIMECODE_NONDROP); nondrop_frame_action->setCheckable(true); - milliseconds_action = view_menu->addAction(tr("Milliseconds"), &Olive::MenuHelper, SLOT(set_timecode_view())); + milliseconds_action = view_menu->addAction(tr("Milliseconds"), &olive::MenuHelper, SLOT(set_timecode_view())); milliseconds_action->setProperty("id", "milliseconds"); milliseconds_action->setData(TIMECODE_MILLISECONDS); milliseconds_action->setCheckable(true); @@ -484,31 +484,31 @@ void MainWindow::setup_menus() { title_safe_off->setProperty("id", "titlesafeoff"); title_safe_off->setCheckable(true); title_safe_off->setData(qSNaN()); - connect(title_safe_off, SIGNAL(triggered(bool)), &Olive::MenuHelper, SLOT(set_titlesafe_from_menu())); + connect(title_safe_off, SIGNAL(triggered(bool)), &olive::MenuHelper, SLOT(set_titlesafe_from_menu())); title_safe_default = title_safe_area_menu->addAction(tr("Default")); title_safe_default->setProperty("id", "titlesafedefault"); title_safe_default->setCheckable(true); title_safe_default->setData(0.0); - connect(title_safe_default, SIGNAL(triggered(bool)), &Olive::MenuHelper, SLOT(set_titlesafe_from_menu())); + connect(title_safe_default, SIGNAL(triggered(bool)), &olive::MenuHelper, SLOT(set_titlesafe_from_menu())); title_safe_43 = title_safe_area_menu->addAction(tr("4:3")); title_safe_43->setProperty("id", "titlesafe43"); title_safe_43->setCheckable(true); title_safe_43->setData(4.0/3.0); - connect(title_safe_43, SIGNAL(triggered(bool)), &Olive::MenuHelper, SLOT(set_titlesafe_from_menu())); + connect(title_safe_43, SIGNAL(triggered(bool)), &olive::MenuHelper, SLOT(set_titlesafe_from_menu())); title_safe_169 = title_safe_area_menu->addAction(tr("16:9")); title_safe_169->setProperty("id", "titlesafe169"); title_safe_169->setCheckable(true); title_safe_169->setData(16.0/9.0); - connect(title_safe_169, SIGNAL(triggered(bool)), &Olive::MenuHelper, SLOT(set_titlesafe_from_menu())); + connect(title_safe_169, SIGNAL(triggered(bool)), &olive::MenuHelper, SLOT(set_titlesafe_from_menu())); title_safe_custom = title_safe_area_menu->addAction(tr("Custom")); title_safe_custom->setProperty("id", "titlesafecustom"); title_safe_custom->setCheckable(true); title_safe_custom->setData(-1.0); - connect(title_safe_custom, SIGNAL(triggered(bool)), &Olive::MenuHelper, SLOT(set_titlesafe_from_menu())); + connect(title_safe_custom, SIGNAL(triggered(bool)), &olive::MenuHelper, SLOT(set_titlesafe_from_menu())); view_menu->addSeparator(); @@ -516,35 +516,35 @@ void MainWindow::setup_menus() { full_screen->setProperty("id", "fullscreen"); full_screen->setCheckable(true); - view_menu->addAction(tr("Full Screen Viewer"), &Olive::FocusFilter, SLOT(set_viewer_fullscreen()))->setProperty("id", "fullscreenviewer"); + view_menu->addAction(tr("Full Screen Viewer"), &olive::FocusFilter, SLOT(set_viewer_fullscreen()))->setProperty("id", "fullscreenviewer"); // INITIALIZE PLAYBACK MENU QMenu* playback_menu = menuBar->addMenu(tr("&Playback")); connect(playback_menu, SIGNAL(aboutToShow()), this, SLOT(playbackMenu_About_To_Be_Shown())); - playback_menu->addAction(tr("Go to Start"), &Olive::FocusFilter, SLOT(go_to_start()), QKeySequence("Home"))->setProperty("id", "gotostart"); - playback_menu->addAction(tr("Previous Frame"), &Olive::FocusFilter, SLOT(prev_frame()), QKeySequence("Left"))->setProperty("id", "prevframe"); - playback_menu->addAction(tr("Play/Pause"), &Olive::FocusFilter, SLOT(playpause()), QKeySequence("Space"))->setProperty("id", "playpause"); - playback_menu->addAction(tr("Play In to Out"), &Olive::FocusFilter, SLOT(play_in_to_out()), QKeySequence("Shift+Space"))->setProperty("id", "playintoout"); - playback_menu->addAction(tr("Next Frame"), &Olive::FocusFilter, SLOT(next_frame()), QKeySequence("Right"))->setProperty("id", "nextframe"); - playback_menu->addAction(tr("Go to End"), &Olive::FocusFilter, SLOT(go_to_end()), QKeySequence("End"))->setProperty("id", "gotoend"); + playback_menu->addAction(tr("Go to Start"), &olive::FocusFilter, SLOT(go_to_start()), QKeySequence("Home"))->setProperty("id", "gotostart"); + playback_menu->addAction(tr("Previous Frame"), &olive::FocusFilter, SLOT(prev_frame()), QKeySequence("Left"))->setProperty("id", "prevframe"); + playback_menu->addAction(tr("Play/Pause"), &olive::FocusFilter, SLOT(playpause()), QKeySequence("Space"))->setProperty("id", "playpause"); + playback_menu->addAction(tr("Play In to Out"), &olive::FocusFilter, SLOT(play_in_to_out()), QKeySequence("Shift+Space"))->setProperty("id", "playintoout"); + playback_menu->addAction(tr("Next Frame"), &olive::FocusFilter, SLOT(next_frame()), QKeySequence("Right"))->setProperty("id", "nextframe"); + playback_menu->addAction(tr("Go to End"), &olive::FocusFilter, SLOT(go_to_end()), QKeySequence("End"))->setProperty("id", "gotoend"); playback_menu->addSeparator(); playback_menu->addAction(tr("Go to Previous Cut"), panel_timeline, SLOT(previous_cut()), QKeySequence("Up"))->setProperty("id", "prevcut"); playback_menu->addAction(tr("Go to Next Cut"), panel_timeline, SLOT(next_cut()), QKeySequence("Down"))->setProperty("id", "nextcut"); playback_menu->addSeparator(); - playback_menu->addAction(tr("Go to In Point"), &Olive::FocusFilter, SLOT(go_to_in()), QKeySequence("Shift+I"))->setProperty("id", "gotoin"); - playback_menu->addAction(tr("Go to Out Point"), &Olive::FocusFilter, SLOT(go_to_out()), QKeySequence("Shift+O"))->setProperty("id", "gotoout"); + playback_menu->addAction(tr("Go to In Point"), &olive::FocusFilter, SLOT(go_to_in()), QKeySequence("Shift+I"))->setProperty("id", "gotoin"); + playback_menu->addAction(tr("Go to Out Point"), &olive::FocusFilter, SLOT(go_to_out()), QKeySequence("Shift+O"))->setProperty("id", "gotoout"); playback_menu->addSeparator(); - playback_menu->addAction(tr("Shuttle Left"), &Olive::FocusFilter, SLOT(decrease_speed()), QKeySequence("J"))->setProperty("id", "decspeed"); - playback_menu->addAction(tr("Shuttle Stop"), &Olive::FocusFilter, SLOT(pause()), QKeySequence("K"))->setProperty("id", "pause"); - playback_menu->addAction(tr("Shuttle Right"), &Olive::FocusFilter, SLOT(increase_speed()), QKeySequence("L"))->setProperty("id", "incspeed"); + playback_menu->addAction(tr("Shuttle Left"), &olive::FocusFilter, SLOT(decrease_speed()), QKeySequence("J"))->setProperty("id", "decspeed"); + playback_menu->addAction(tr("Shuttle Stop"), &olive::FocusFilter, SLOT(pause()), QKeySequence("K"))->setProperty("id", "pause"); + playback_menu->addAction(tr("Shuttle Right"), &olive::FocusFilter, SLOT(increase_speed()), QKeySequence("L"))->setProperty("id", "incspeed"); playback_menu->addSeparator(); - loop_action = playback_menu->addAction(tr("Loop"), &Olive::MenuHelper, SLOT(toggle_bool_action())); + loop_action = playback_menu->addAction(tr("Loop"), &olive::MenuHelper, SLOT(toggle_bool_action())); loop_action->setProperty("id", "loop"); loop_action->setCheckable(true); - loop_action->setData(reinterpret_cast(&Olive::CurrentConfig.loop)); + loop_action->setData(reinterpret_cast(&olive::CurrentConfig.loop)); // INITIALIZE WINDOW MENU @@ -594,171 +594,171 @@ void MainWindow::setup_menus() { QMenu* tools_menu = menuBar->addMenu(tr("&Tools")); connect(tools_menu, SIGNAL(aboutToShow()), this, SLOT(toolMenu_About_To_Be_Shown())); - pointer_tool_action = tools_menu->addAction(tr("Pointer Tool"), &Olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("V")); + pointer_tool_action = tools_menu->addAction(tr("Pointer Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("V")); pointer_tool_action->setProperty("id", "pointertool"); pointer_tool_action->setCheckable(true); pointer_tool_action->setData(reinterpret_cast(panel_timeline->toolArrowButton)); - edit_tool_action = tools_menu->addAction(tr("Edit Tool"), &Olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("X")); + edit_tool_action = tools_menu->addAction(tr("Edit Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("X")); edit_tool_action->setProperty("id", "edittool"); edit_tool_action->setCheckable(true); edit_tool_action->setData(reinterpret_cast(panel_timeline->toolEditButton)); - ripple_tool_action = tools_menu->addAction(tr("Ripple Tool"), &Olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("B")); + ripple_tool_action = tools_menu->addAction(tr("Ripple Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("B")); ripple_tool_action->setProperty("id", "rippletool"); ripple_tool_action->setCheckable(true); ripple_tool_action->setData(reinterpret_cast(panel_timeline->toolRippleButton)); - razor_tool_action = tools_menu->addAction(tr("Razor Tool"), &Olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("C")); + razor_tool_action = tools_menu->addAction(tr("Razor Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("C")); razor_tool_action->setProperty("id", "razortool"); razor_tool_action->setCheckable(true); razor_tool_action->setData(reinterpret_cast(panel_timeline->toolRazorButton)); - slip_tool_action = tools_menu->addAction(tr("Slip Tool"), &Olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("Y")); + slip_tool_action = tools_menu->addAction(tr("Slip Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("Y")); slip_tool_action->setProperty("id", "sliptool"); slip_tool_action->setCheckable(true); slip_tool_action->setData(reinterpret_cast(panel_timeline->toolSlipButton)); - slide_tool_action = tools_menu->addAction(tr("Slide Tool"), &Olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("U")); + slide_tool_action = tools_menu->addAction(tr("Slide Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("U")); slide_tool_action->setProperty("id", "slidetool"); slide_tool_action->setCheckable(true); slide_tool_action->setData(reinterpret_cast(panel_timeline->toolSlideButton)); - hand_tool_action = tools_menu->addAction(tr("Hand Tool"), &Olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("H")); + hand_tool_action = tools_menu->addAction(tr("Hand Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("H")); hand_tool_action->setProperty("id", "handtool"); hand_tool_action->setCheckable(true); hand_tool_action->setData(reinterpret_cast(panel_timeline->toolHandButton)); - transition_tool_action = tools_menu->addAction(tr("Transition Tool"), &Olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("T")); + transition_tool_action = tools_menu->addAction(tr("Transition Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("T")); transition_tool_action->setProperty("id", "transitiontool"); transition_tool_action->setCheckable(true); transition_tool_action->setData(reinterpret_cast(panel_timeline->toolTransitionButton)); tools_menu->addSeparator(); - snap_toggle = tools_menu->addAction(tr("Enable Snapping"), &Olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("S")); + snap_toggle = tools_menu->addAction(tr("Enable Snapping"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("S")); snap_toggle->setProperty("id", "snapping"); snap_toggle->setCheckable(true); snap_toggle->setData(reinterpret_cast(panel_timeline->snappingButton)); tools_menu->addSeparator(); - selecting_also_seeks = tools_menu->addAction(tr("Selecting Also Seeks"), &Olive::MenuHelper, SLOT(toggle_bool_action())); + selecting_also_seeks = tools_menu->addAction(tr("Selecting Also Seeks"), &olive::MenuHelper, SLOT(toggle_bool_action())); selecting_also_seeks->setProperty("id", "selectingalsoseeks"); selecting_also_seeks->setCheckable(true); - selecting_also_seeks->setData(reinterpret_cast(&Olive::CurrentConfig.select_also_seeks)); + selecting_also_seeks->setData(reinterpret_cast(&olive::CurrentConfig.select_also_seeks)); - edit_tool_also_seeks = tools_menu->addAction(tr("Edit Tool Also Seeks"), &Olive::MenuHelper, SLOT(toggle_bool_action())); + edit_tool_also_seeks = tools_menu->addAction(tr("Edit Tool Also Seeks"), &olive::MenuHelper, SLOT(toggle_bool_action())); edit_tool_also_seeks->setProperty("id", "editalsoseeks"); edit_tool_also_seeks->setCheckable(true); - edit_tool_also_seeks->setData(reinterpret_cast(&Olive::CurrentConfig.edit_tool_also_seeks)); + edit_tool_also_seeks->setData(reinterpret_cast(&olive::CurrentConfig.edit_tool_also_seeks)); - edit_tool_selects_links = tools_menu->addAction(tr("Edit Tool Selects Links"), &Olive::MenuHelper, SLOT(toggle_bool_action())); + edit_tool_selects_links = tools_menu->addAction(tr("Edit Tool Selects Links"), &olive::MenuHelper, SLOT(toggle_bool_action())); edit_tool_selects_links->setProperty("id", "editselectslinks"); edit_tool_selects_links->setCheckable(true); - edit_tool_selects_links->setData(reinterpret_cast(&Olive::CurrentConfig.edit_tool_selects_links)); + edit_tool_selects_links->setData(reinterpret_cast(&olive::CurrentConfig.edit_tool_selects_links)); - seek_also_selects = tools_menu->addAction(tr("Seek Also Selects"), &Olive::MenuHelper, SLOT(toggle_bool_action())); + seek_also_selects = tools_menu->addAction(tr("Seek Also Selects"), &olive::MenuHelper, SLOT(toggle_bool_action())); seek_also_selects->setProperty("id", "seekalsoselects"); seek_also_selects->setCheckable(true); - seek_also_selects->setData(reinterpret_cast(&Olive::CurrentConfig.seek_also_selects)); + seek_also_selects->setData(reinterpret_cast(&olive::CurrentConfig.seek_also_selects)); - seek_to_end_of_pastes = tools_menu->addAction(tr("Seek to the End of Pastes"), &Olive::MenuHelper, SLOT(toggle_bool_action())); + seek_to_end_of_pastes = tools_menu->addAction(tr("Seek to the End of Pastes"), &olive::MenuHelper, SLOT(toggle_bool_action())); seek_to_end_of_pastes->setProperty("id", "seektoendofpastes"); seek_to_end_of_pastes->setCheckable(true); - seek_to_end_of_pastes->setData(reinterpret_cast(&Olive::CurrentConfig.paste_seeks)); + seek_to_end_of_pastes->setData(reinterpret_cast(&olive::CurrentConfig.paste_seeks)); - scroll_wheel_zooms = tools_menu->addAction(tr("Scroll Wheel Zooms"), &Olive::MenuHelper, SLOT(toggle_bool_action())); + scroll_wheel_zooms = tools_menu->addAction(tr("Scroll Wheel Zooms"), &olive::MenuHelper, SLOT(toggle_bool_action())); scroll_wheel_zooms->setProperty("id", "scrollwheelzooms"); scroll_wheel_zooms->setCheckable(true); - scroll_wheel_zooms->setData(reinterpret_cast(&Olive::CurrentConfig.scroll_zooms)); + scroll_wheel_zooms->setData(reinterpret_cast(&olive::CurrentConfig.scroll_zooms)); - enable_drag_files_to_timeline = tools_menu->addAction(tr("Enable Drag Files to Timeline"), &Olive::MenuHelper, SLOT(toggle_bool_action())); + enable_drag_files_to_timeline = tools_menu->addAction(tr("Enable Drag Files to Timeline"), &olive::MenuHelper, SLOT(toggle_bool_action())); enable_drag_files_to_timeline->setProperty("id", "enabledragfilestotimeline"); enable_drag_files_to_timeline->setCheckable(true); - enable_drag_files_to_timeline->setData(reinterpret_cast(&Olive::CurrentConfig.enable_drag_files_to_timeline)); + enable_drag_files_to_timeline->setData(reinterpret_cast(&olive::CurrentConfig.enable_drag_files_to_timeline)); - autoscale_by_default = tools_menu->addAction(tr("Auto-Scale By Default"), &Olive::MenuHelper, SLOT(toggle_bool_action())); + autoscale_by_default = tools_menu->addAction(tr("Auto-Scale By Default"), &olive::MenuHelper, SLOT(toggle_bool_action())); autoscale_by_default->setProperty("id", "autoscalebydefault"); autoscale_by_default->setCheckable(true); - autoscale_by_default->setData(reinterpret_cast(&Olive::CurrentConfig.autoscale_by_default)); + autoscale_by_default->setData(reinterpret_cast(&olive::CurrentConfig.autoscale_by_default)); - enable_seek_to_import = tools_menu->addAction(tr("Enable Seek to Import"), &Olive::MenuHelper, SLOT(toggle_bool_action())); + enable_seek_to_import = tools_menu->addAction(tr("Enable Seek to Import"), &olive::MenuHelper, SLOT(toggle_bool_action())); enable_seek_to_import->setProperty("id", "enableseektoimport"); enable_seek_to_import->setCheckable(true); - enable_seek_to_import->setData(reinterpret_cast(&Olive::CurrentConfig.enable_seek_to_import)); + enable_seek_to_import->setData(reinterpret_cast(&olive::CurrentConfig.enable_seek_to_import)); - enable_audio_scrubbing = tools_menu->addAction(tr("Audio Scrubbing"), &Olive::MenuHelper, SLOT(toggle_bool_action())); + enable_audio_scrubbing = tools_menu->addAction(tr("Audio Scrubbing"), &olive::MenuHelper, SLOT(toggle_bool_action())); enable_audio_scrubbing->setProperty("id", "audioscrubbing"); enable_audio_scrubbing->setCheckable(true); - enable_audio_scrubbing->setData(reinterpret_cast(&Olive::CurrentConfig.enable_audio_scrubbing)); + enable_audio_scrubbing->setData(reinterpret_cast(&olive::CurrentConfig.enable_audio_scrubbing)); - enable_drop_on_media_to_replace = tools_menu->addAction(tr("Enable Drop on Media to Replace"), &Olive::MenuHelper, SLOT(toggle_bool_action())); + enable_drop_on_media_to_replace = tools_menu->addAction(tr("Enable Drop on Media to Replace"), &olive::MenuHelper, SLOT(toggle_bool_action())); enable_drop_on_media_to_replace->setProperty("id", "enabledropmediareplace"); enable_drop_on_media_to_replace->setCheckable(true); - enable_drop_on_media_to_replace->setData(reinterpret_cast(&Olive::CurrentConfig.drop_on_media_to_replace)); + enable_drop_on_media_to_replace->setData(reinterpret_cast(&olive::CurrentConfig.drop_on_media_to_replace)); - enable_hover_focus = tools_menu->addAction(tr("Enable Hover Focus"), &Olive::MenuHelper, SLOT(toggle_bool_action())); + enable_hover_focus = tools_menu->addAction(tr("Enable Hover Focus"), &olive::MenuHelper, SLOT(toggle_bool_action())); enable_hover_focus->setProperty("id", "hoverfocus"); enable_hover_focus->setCheckable(true); - enable_hover_focus->setData(reinterpret_cast(&Olive::CurrentConfig.hover_focus)); + enable_hover_focus->setData(reinterpret_cast(&olive::CurrentConfig.hover_focus)); - set_name_and_marker = tools_menu->addAction(tr("Ask For Name When Setting Marker"), &Olive::MenuHelper, SLOT(toggle_bool_action())); + set_name_and_marker = tools_menu->addAction(tr("Ask For Name When Setting Marker"), &olive::MenuHelper, SLOT(toggle_bool_action())); set_name_and_marker->setProperty("id", "asknamemarkerset"); set_name_and_marker->setCheckable(true); - set_name_and_marker->setData(reinterpret_cast(&Olive::CurrentConfig.set_name_with_marker)); + set_name_and_marker->setData(reinterpret_cast(&olive::CurrentConfig.set_name_with_marker)); tools_menu->addSeparator(); - no_autoscroll = tools_menu->addAction(tr("No Auto-Scroll"), &Olive::MenuHelper, SLOT(set_autoscroll())); + no_autoscroll = tools_menu->addAction(tr("No Auto-Scroll"), &olive::MenuHelper, SLOT(set_autoscroll())); no_autoscroll->setProperty("id", "autoscrollno"); no_autoscroll->setData(AUTOSCROLL_NO_SCROLL); no_autoscroll->setCheckable(true); - page_autoscroll = tools_menu->addAction(tr("Page Auto-Scroll"), &Olive::MenuHelper, SLOT(set_autoscroll())); + page_autoscroll = tools_menu->addAction(tr("Page Auto-Scroll"), &olive::MenuHelper, SLOT(set_autoscroll())); page_autoscroll->setProperty("id", "autoscrollpage"); page_autoscroll->setData(AUTOSCROLL_PAGE_SCROLL); page_autoscroll->setCheckable(true); - smooth_autoscroll = tools_menu->addAction(tr("Smooth Auto-Scroll"), &Olive::MenuHelper, SLOT(set_autoscroll())); + smooth_autoscroll = tools_menu->addAction(tr("Smooth Auto-Scroll"), &olive::MenuHelper, SLOT(set_autoscroll())); smooth_autoscroll->setProperty("id", "autoscrollsmooth"); smooth_autoscroll->setData(AUTOSCROLL_SMOOTH_SCROLL); smooth_autoscroll->setCheckable(true); tools_menu->addSeparator(); - tools_menu->addAction(tr("Preferences"), Olive::Global.data(), SLOT(open_preferences()), QKeySequence("Ctrl+,"))->setProperty("id", "prefs"); + tools_menu->addAction(tr("Preferences"), olive::Global.get(), SLOT(open_preferences()), QKeySequence("Ctrl+,"))->setProperty("id", "prefs"); #ifdef QT_DEBUG - tools_menu->addAction(tr("Clear Undo"), Olive::Global.data(), SLOT(clear_undo_stack()))->setProperty("id", "clearundo"); + tools_menu->addAction(tr("Clear Undo"), olive::Global.get(), SLOT(clear_undo_stack()))->setProperty("id", "clearundo"); #endif // INITIALIZE HELP MENU QMenu* help_menu = menuBar->addMenu(tr("&Help")); - help_menu->addAction(tr("A&ction Search"), Olive::Global.data(), SLOT(open_action_search()), QKeySequence("/"))->setProperty("id", "actionsearch"); + help_menu->addAction(tr("A&ction Search"), olive::Global.get(), SLOT(open_action_search()), QKeySequence("/"))->setProperty("id", "actionsearch"); help_menu->addSeparator(); - help_menu->addAction(tr("Debug Log"), Olive::Global.data(), SLOT(open_debug_log()))->setProperty("id", "debuglog"); + help_menu->addAction(tr("Debug Log"), olive::Global.get(), SLOT(open_debug_log()))->setProperty("id", "debuglog"); help_menu->addSeparator(); - help_menu->addAction(tr("&About..."), Olive::Global.data(), SLOT(open_about_dialog()))->setProperty("id", "about"); + help_menu->addAction(tr("&About..."), olive::Global.get(), SLOT(open_about_dialog()))->setProperty("id", "about"); load_shortcuts(get_config_path() + "/shortcuts"); } void MainWindow::updateTitle() { - setWindowTitle(QString("%1 - %2[*]").arg(Olive::AppName, - (Olive::ActiveProjectFilename.isEmpty()) ? - tr("") : Olive::ActiveProjectFilename) + setWindowTitle(QString("%1 - %2[*]").arg(olive::AppName, + (olive::ActiveProjectFilename.isEmpty()) ? + tr("") : olive::ActiveProjectFilename) ); } void MainWindow::closeEvent(QCloseEvent *e) { - if (Olive::Global.data()->can_close_project()) { + if (olive::Global->can_close_project()) { // stop proxy generator thread proxy_generator.cancel(); @@ -784,7 +784,7 @@ void MainWindow::closeEvent(QCloseEvent *e) { QString config_fn = config_dir.filePath("config.xml"); // save settings - Olive::CurrentConfig.save(config_fn); + olive::CurrentConfig.save(config_fn); // save panel layout QFile panel_config(config_path + "/layout"); @@ -860,28 +860,28 @@ void MainWindow::windowMenu_About_To_Be_Shown() { } void MainWindow::playbackMenu_About_To_Be_Shown() { - Olive::MenuHelper.set_bool_action_checked(loop_action); + olive::MenuHelper.set_bool_action_checked(loop_action); } void MainWindow::viewMenu_About_To_Be_Shown() { - Olive::MenuHelper.set_bool_action_checked(track_lines); + olive::MenuHelper.set_bool_action_checked(track_lines); - Olive::MenuHelper.set_int_action_checked(frames_action, Olive::CurrentConfig.timecode_view); - Olive::MenuHelper.set_int_action_checked(drop_frame_action, Olive::CurrentConfig.timecode_view); - Olive::MenuHelper.set_int_action_checked(nondrop_frame_action, Olive::CurrentConfig.timecode_view); - Olive::MenuHelper.set_int_action_checked(milliseconds_action, Olive::CurrentConfig.timecode_view); + olive::MenuHelper.set_int_action_checked(frames_action, olive::CurrentConfig.timecode_view); + olive::MenuHelper.set_int_action_checked(drop_frame_action, olive::CurrentConfig.timecode_view); + olive::MenuHelper.set_int_action_checked(nondrop_frame_action, olive::CurrentConfig.timecode_view); + olive::MenuHelper.set_int_action_checked(milliseconds_action, olive::CurrentConfig.timecode_view); - title_safe_off->setChecked(!Olive::CurrentConfig.show_title_safe_area); - title_safe_default->setChecked(Olive::CurrentConfig.show_title_safe_area - && !Olive::CurrentConfig.use_custom_title_safe_ratio); - title_safe_43->setChecked(Olive::CurrentConfig.show_title_safe_area - && Olive::CurrentConfig.use_custom_title_safe_ratio - && qFuzzyCompare(Olive::CurrentConfig.custom_title_safe_ratio, title_safe_43->data().toDouble())); - title_safe_169->setChecked(Olive::CurrentConfig.show_title_safe_area - && Olive::CurrentConfig.use_custom_title_safe_ratio - && qFuzzyCompare(Olive::CurrentConfig.custom_title_safe_ratio, title_safe_169->data().toDouble())); - title_safe_custom->setChecked(Olive::CurrentConfig.show_title_safe_area - && Olive::CurrentConfig.use_custom_title_safe_ratio + title_safe_off->setChecked(!olive::CurrentConfig.show_title_safe_area); + title_safe_default->setChecked(olive::CurrentConfig.show_title_safe_area + && !olive::CurrentConfig.use_custom_title_safe_ratio); + title_safe_43->setChecked(olive::CurrentConfig.show_title_safe_area + && olive::CurrentConfig.use_custom_title_safe_ratio + && qFuzzyCompare(olive::CurrentConfig.custom_title_safe_ratio, title_safe_43->data().toDouble())); + title_safe_169->setChecked(olive::CurrentConfig.show_title_safe_area + && olive::CurrentConfig.use_custom_title_safe_ratio + && qFuzzyCompare(olive::CurrentConfig.custom_title_safe_ratio, title_safe_169->data().toDouble())); + title_safe_custom->setChecked(olive::CurrentConfig.show_title_safe_area + && olive::CurrentConfig.use_custom_title_safe_ratio && !title_safe_43->isChecked() && !title_safe_169->isChecked()); @@ -891,34 +891,34 @@ void MainWindow::viewMenu_About_To_Be_Shown() { } void MainWindow::toolMenu_About_To_Be_Shown() { - Olive::MenuHelper.set_button_action_checked(pointer_tool_action); - Olive::MenuHelper.set_button_action_checked(edit_tool_action); - Olive::MenuHelper.set_button_action_checked(ripple_tool_action); - Olive::MenuHelper.set_button_action_checked(razor_tool_action); - Olive::MenuHelper.set_button_action_checked(slip_tool_action); - Olive::MenuHelper.set_button_action_checked(slide_tool_action); - Olive::MenuHelper.set_button_action_checked(hand_tool_action); - Olive::MenuHelper.set_button_action_checked(transition_tool_action); - Olive::MenuHelper.set_button_action_checked(snap_toggle); + olive::MenuHelper.set_button_action_checked(pointer_tool_action); + olive::MenuHelper.set_button_action_checked(edit_tool_action); + olive::MenuHelper.set_button_action_checked(ripple_tool_action); + olive::MenuHelper.set_button_action_checked(razor_tool_action); + olive::MenuHelper.set_button_action_checked(slip_tool_action); + olive::MenuHelper.set_button_action_checked(slide_tool_action); + olive::MenuHelper.set_button_action_checked(hand_tool_action); + olive::MenuHelper.set_button_action_checked(transition_tool_action); + olive::MenuHelper.set_button_action_checked(snap_toggle); - Olive::MenuHelper.set_bool_action_checked(selecting_also_seeks); - Olive::MenuHelper.set_bool_action_checked(edit_tool_also_seeks); - Olive::MenuHelper.set_bool_action_checked(edit_tool_selects_links); - Olive::MenuHelper.set_bool_action_checked(seek_to_end_of_pastes); - Olive::MenuHelper.set_bool_action_checked(scroll_wheel_zooms); - Olive::MenuHelper.set_bool_action_checked(rectified_waveforms); - Olive::MenuHelper.set_bool_action_checked(enable_drag_files_to_timeline); - Olive::MenuHelper.set_bool_action_checked(autoscale_by_default); - Olive::MenuHelper.set_bool_action_checked(enable_seek_to_import); - Olive::MenuHelper.set_bool_action_checked(enable_audio_scrubbing); - Olive::MenuHelper.set_bool_action_checked(enable_drop_on_media_to_replace); - Olive::MenuHelper.set_bool_action_checked(enable_hover_focus); - Olive::MenuHelper.set_bool_action_checked(set_name_and_marker); - Olive::MenuHelper.set_bool_action_checked(seek_also_selects); + olive::MenuHelper.set_bool_action_checked(selecting_also_seeks); + olive::MenuHelper.set_bool_action_checked(edit_tool_also_seeks); + olive::MenuHelper.set_bool_action_checked(edit_tool_selects_links); + olive::MenuHelper.set_bool_action_checked(seek_to_end_of_pastes); + olive::MenuHelper.set_bool_action_checked(scroll_wheel_zooms); + olive::MenuHelper.set_bool_action_checked(rectified_waveforms); + olive::MenuHelper.set_bool_action_checked(enable_drag_files_to_timeline); + olive::MenuHelper.set_bool_action_checked(autoscale_by_default); + olive::MenuHelper.set_bool_action_checked(enable_seek_to_import); + olive::MenuHelper.set_bool_action_checked(enable_audio_scrubbing); + olive::MenuHelper.set_bool_action_checked(enable_drop_on_media_to_replace); + olive::MenuHelper.set_bool_action_checked(enable_hover_focus); + olive::MenuHelper.set_bool_action_checked(set_name_and_marker); + olive::MenuHelper.set_bool_action_checked(seek_also_selects); - Olive::MenuHelper.set_int_action_checked(no_autoscroll, Olive::CurrentConfig.autoscroll); - Olive::MenuHelper.set_int_action_checked(page_autoscroll, Olive::CurrentConfig.autoscroll); - Olive::MenuHelper.set_int_action_checked(smooth_autoscroll, Olive::CurrentConfig.autoscroll); + olive::MenuHelper.set_int_action_checked(no_autoscroll, olive::CurrentConfig.autoscroll); + olive::MenuHelper.set_int_action_checked(page_autoscroll, olive::CurrentConfig.autoscroll); + olive::MenuHelper.set_int_action_checked(smooth_autoscroll, olive::CurrentConfig.autoscroll); } void MainWindow::toggle_panel_visibility() { @@ -939,7 +939,7 @@ void MainWindow::fileMenu_About_To_Be_Shown() { QAction* action = open_recent->addAction(recent_projects.at(i)); action->setProperty("keyignore", true); action->setData(i); - connect(action, SIGNAL(triggered()), &Olive::MenuHelper, SLOT(open_recent_from_menu())); + connect(action, SIGNAL(triggered()), &olive::MenuHelper, SLOT(open_recent_from_menu())); } open_recent->addSeparator(); diff --git a/mainwindow.h b/mainwindow.h index 566e3fdb9..2dc6c6dca 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -259,7 +259,7 @@ private: bool first_show; }; -namespace Olive { +namespace olive { extern MainWindow* MainWindow; } diff --git a/oliveglobal.cpp b/oliveglobal.cpp index 910c6c687..c49f26da2 100644 --- a/oliveglobal.cpp +++ b/oliveglobal.cpp @@ -43,9 +43,9 @@ #include #include -QSharedPointer Olive::Global; -QString Olive::ActiveProjectFilename; -QString Olive::AppName; +std::unique_ptr olive::Global; +QString olive::ActiveProjectFilename; +QString olive::AppName; OliveGlobal::OliveGlobal() { // sets current app name @@ -53,7 +53,7 @@ OliveGlobal::OliveGlobal() { #ifdef GITHASH version_id = QString(" | %1").arg(GITHASH); #endif - Olive::AppName = QString("Olive (February 2019 | Alpha%1)").arg(version_id); + olive::AppName = QString("Olive (February 2019 | Alpha%1)").arg(version_id); // set the file filter used in all file dialogs pertaining to Olive project files. project_file_filter = tr("Olive Project %1").arg("(*.ove)"); @@ -68,10 +68,10 @@ const QString &OliveGlobal::get_project_file_filter() { void OliveGlobal::update_project_filename(const QString &s) { // set filename to s - Olive::ActiveProjectFilename = s; + olive::ActiveProjectFilename = s; // update main window title to reflect new project filename - Olive::MainWindow->updateTitle(); + olive::MainWindow->updateTitle(); } void OliveGlobal::check_for_autorecovery_file() { @@ -101,7 +101,7 @@ void OliveGlobal::set_rendering_state(bool rendering) { } void OliveGlobal::load_project_on_launch(const QString& s) { - Olive::ActiveProjectFilename = s; + olive::ActiveProjectFilename = s; enable_load_project_on_init = true; } @@ -118,7 +118,7 @@ void OliveGlobal::new_project() { panel_project->new_project(); // clear undo stack - Olive::UndoStack.clear(); + olive::UndoStack.clear(); // empty current project filename update_project_filename(""); @@ -129,7 +129,7 @@ void OliveGlobal::new_project() { } void OliveGlobal::open_project() { - QString fn = QFileDialog::getOpenFileName(Olive::MainWindow, tr("Open Project..."), "", project_file_filter); + QString fn = QFileDialog::getOpenFileName(olive::MainWindow, tr("Open Project..."), "", project_file_filter); if (!fn.isEmpty() && can_close_project()) { open_project_worker(fn, false); } @@ -139,20 +139,20 @@ void OliveGlobal::open_recent(int index) { QString recent_url = recent_projects.at(index); if (!QFile::exists(recent_url)) { if (QMessageBox::question( - Olive::MainWindow, + olive::MainWindow, tr("Missing recent project"), tr("The project '%1' no longer exists. Would you like to remove it from the recent projects list?").arg(recent_url), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { recent_projects.removeAt(index); panel_project->save_recent_projects(); } - } else if (Olive::Global.data()->can_close_project()) { + } else if (can_close_project()) { open_project_worker(recent_url, false); } } bool OliveGlobal::save_project_as() { - QString fn = QFileDialog::getSaveFileName(Olive::MainWindow, tr("Save Project As..."), "", project_file_filter); + QString fn = QFileDialog::getSaveFileName(olive::MainWindow, tr("Save Project As..."), "", project_file_filter); if (!fn.isEmpty()) { if (!fn.endsWith(".ove", Qt::CaseInsensitive)) { fn += ".ove"; @@ -165,7 +165,7 @@ bool OliveGlobal::save_project_as() { } bool OliveGlobal::save_project() { - if (Olive::ActiveProjectFilename.isEmpty()) { + if (olive::ActiveProjectFilename.isEmpty()) { return save_project_as(); } else { panel_project->save_project(false); @@ -174,13 +174,13 @@ bool OliveGlobal::save_project() { } bool OliveGlobal::can_close_project() { - if (Olive::MainWindow->isWindowModified()) { + if (olive::MainWindow->isWindowModified()) { QMessageBox* m = new QMessageBox( QMessageBox::Question, tr("Unsaved Project"), tr("This project has changed since it was last saved. Would you like to save it before closing?"), QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel, - Olive::MainWindow + olive::MainWindow ); m->setWindowModality(Qt::WindowModal); int r = m->exec(); @@ -195,13 +195,13 @@ bool OliveGlobal::can_close_project() { } void OliveGlobal::open_export_dialog() { - if (Olive::ActiveSequence == nullptr) { - QMessageBox::information(Olive::MainWindow, + if (olive::ActiveSequence == nullptr) { + QMessageBox::information(olive::MainWindow, tr("No active sequence"), tr("Please open the sequence you wish to export."), QMessageBox::Ok); } else { - ExportDialog e(Olive::MainWindow); + ExportDialog e(olive::MainWindow); e.exec(); } } @@ -210,12 +210,12 @@ void OliveGlobal::finished_initialize() { if (enable_load_project_on_init) { // if a project was set as a command line argument, we load it here - if (QFileInfo::exists(Olive::ActiveProjectFilename)) { - open_project_worker(Olive::ActiveProjectFilename, false); + if (QFileInfo::exists(olive::ActiveProjectFilename)) { + open_project_worker(olive::ActiveProjectFilename, false); } else { - QMessageBox::critical(Olive::MainWindow, + QMessageBox::critical(olive::MainWindow, tr("Missing Project File"), - tr("Specified project '%1' does not exist.").arg(Olive::ActiveProjectFilename), + tr("Specified project '%1' does not exist.").arg(olive::ActiveProjectFilename), QMessageBox::Ok); update_project_filename(nullptr); } @@ -233,7 +233,7 @@ void OliveGlobal::finished_initialize() { } void OliveGlobal::save_autorecovery_file() { - if (Olive::MainWindow->isWindowModified()) { + if (olive::MainWindow->isWindowModified()) { panel_project->save_project(true); qInfo() << "Auto-recovery project saved"; } @@ -243,21 +243,21 @@ void OliveGlobal::open_preferences() { panel_sequence_viewer->pause(); panel_footage_viewer->pause(); - PreferencesDialog pd(Olive::MainWindow); - pd.setup_kbd_shortcuts(Olive::MainWindow->menuBar()); + PreferencesDialog pd(olive::MainWindow); + pd.setup_kbd_shortcuts(olive::MainWindow->menuBar()); pd.exec(); } void OliveGlobal::open_project_worker(const QString& fn, bool autorecovery) { update_project_filename(fn); panel_project->load_project(autorecovery); - Olive::UndoStack.clear(); + olive::UndoStack.clear(); } void OliveGlobal::undo() { // workaround to prevent crash (and also users should never need to do this) if (!panel_timeline->importing) { - Olive::UndoStack.undo(); + olive::UndoStack.undo(); update_ui(true); } } @@ -265,37 +265,37 @@ void OliveGlobal::undo() { void OliveGlobal::redo() { // workaround to prevent crash (and also users should never need to do this) if (!panel_timeline->importing) { - Olive::UndoStack.redo(); + olive::UndoStack.redo(); update_ui(true); } } void OliveGlobal::paste() { - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { panel_timeline->paste(false); } } void OliveGlobal::paste_insert() { - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { panel_timeline->paste(true); } } void OliveGlobal::open_about_dialog() { - AboutDialog a(Olive::MainWindow); + AboutDialog a(olive::MainWindow); a.exec(); } void OliveGlobal::open_debug_log() { - Olive::DebugDialog->show(); + olive::DebugDialog->show(); } void OliveGlobal::open_speed_dialog() { - if (Olive::ActiveSequence != nullptr) { - SpeedDialog s(Olive::MainWindow); - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + if (olive::ActiveSequence != nullptr) { + SpeedDialog s(olive::MainWindow); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { s.clips.append(c); } @@ -305,10 +305,10 @@ void OliveGlobal::open_speed_dialog() { } void OliveGlobal::clear_undo_stack() { - Olive::UndoStack.clear(); + olive::UndoStack.clear(); } void OliveGlobal::open_action_search() { - ActionSearch as(Olive::MainWindow); + ActionSearch as(olive::MainWindow); as.exec(); } diff --git a/oliveglobal.h b/oliveglobal.h index ca3de2520..7b3ffc2b1 100644 --- a/oliveglobal.h +++ b/oliveglobal.h @@ -295,11 +295,11 @@ private slots: }; -namespace Olive { +namespace olive { /** * @brief Object resource for various global functions used throughout Olive */ - extern QSharedPointer Global; + extern std::unique_ptr Global; /** * @brief Currently active project filename diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp index 9339070fa..4c4e3875d 100644 --- a/panels/effectcontrols.cpp +++ b/panels/effectcontrols.cpp @@ -100,7 +100,7 @@ void EffectControls::set_zoom(bool in) { void EffectControls::menu_select(QAction* q) { ComboAction* ca = new ComboAction(); for (int i=0;iclips.at(selected_clips.at(i)); + Clip* c = olive::ActiveSequence->clips.at(selected_clips.at(i)); if ((c->track < 0) == (effect_menu_subtype == EFFECT_TYPE_VIDEO)) { const EffectMeta* meta = reinterpret_cast(q->data().value()); if (effect_menu_type == EFFECT_TYPE_TRANSITION) { @@ -115,7 +115,7 @@ void EffectControls::menu_select(QAction* q) { } } } - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); if (effect_menu_type == EFFECT_TYPE_TRANSITION) { update_ui(true); } else { @@ -140,7 +140,7 @@ void EffectControls::copy(bool del) { ComboAction* ca = new ComboAction(); EffectDeleteCommand* del_com = (del) ? new EffectDeleteCommand() : nullptr; for (int i=0;iclips.at(selected_clips.at(i)); + Clip* c = olive::ActiveSequence->clips.at(selected_clips.at(i)); for (int j=0;jeffects.size();j++) { Effect* effect = c->effects.at(j); if (effect->container->selected) { @@ -166,7 +166,7 @@ void EffectControls::copy(bool del) { delete del_com; } } - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); } } @@ -282,7 +282,7 @@ void EffectControls::clear_effects(bool clear_cache) { void EffectControls::deselect_all_effects(QWidget* sender) { for (int i=0;iclips.at(selected_clips.at(i)); + Clip* c = olive::ActiveSequence->clips.at(selected_clips.at(i)); for (int j=0;jeffects.size();j++) { if (c->effects.at(j)->container != sender) { c->effects.at(j)->container->header_click(false, false); @@ -505,7 +505,7 @@ void EffectControls::load_effects() { if (!multiple) { // load in new clips for (int i=0;iclips.at(selected_clips.at(i)); + Clip* c = olive::ActiveSequence->clips.at(selected_clips.at(i)); QVBoxLayout* layout; if (c->track < 0) { vcontainer->setVisible(true); @@ -525,7 +525,7 @@ void EffectControls::load_effects() { } } if (selected_clips.size() > 0) { - setWindowTitle(panel_name + Olive::ActiveSequence->clips.at(selected_clips.at(0))->name); + setWindowTitle(panel_name + olive::ActiveSequence->clips.at(selected_clips.at(0))->name); keyframeView->setEnabled(true); headers->setVisible(true); @@ -539,7 +539,7 @@ void EffectControls::delete_effects() { if (mode == TA_NO_TRANSITION) { EffectDeleteCommand* command = new EffectDeleteCommand(); for (int i=0;iclips.at(selected_clips.at(i)); + Clip* c = olive::ActiveSequence->clips.at(selected_clips.at(i)); for (int j=0;jeffects.size();j++) { Effect* effect = c->effects.at(j); if (effect->container->selected) { @@ -549,7 +549,7 @@ void EffectControls::delete_effects() { } } if (command->clips.size() > 0) { - Olive::UndoStack.push(command); + olive::UndoStack.push(command); panel_sequence_viewer->viewer_widget->frame_update(); } else { delete command; @@ -595,7 +595,7 @@ void EffectControls::resizeEvent(QResizeEvent*) { bool EffectControls::is_focused() { if (this->hasFocus()) return true; for (int i=0;iclips.at(selected_clips.at(i)); + Clip* c = olive::ActiveSequence->clips.at(selected_clips.at(i)); if (c != nullptr) { for (int j=0;jeffects.size();j++) { if (c->effects.at(j)->container->is_focused()) { diff --git a/panels/panels.cpp b/panels/panels.cpp index 98f92c5d3..5b3d81059 100644 --- a/panels/panels.cpp +++ b/panels/panels.cpp @@ -48,12 +48,12 @@ void update_effect_controls() { int aclip = -1; QVector selected_clips; int mode = TA_NO_TRANSITION; - if (Olive::ActiveSequence != nullptr) { - for (int i=0;iclips.size();i++) { - Clip* clip = Olive::ActiveSequence->clips.at(i); + if (olive::ActiveSequence != nullptr) { + for (int i=0;iclips.size();i++) { + Clip* clip = olive::ActiveSequence->clips.at(i); if (clip != nullptr) { - for (int j=0;jselections.size();j++) { - const Selection& s = Olive::ActiveSequence->selections.at(j); + for (int j=0;jselections.size();j++) { + const Selection& s = olive::ActiveSequence->selections.at(j); bool add = true; if (clip->timeline_in >= s.in && clip->timeline_out <= s.out && clip->track == s.track) { mode = TA_NO_TRANSITION; @@ -88,7 +88,7 @@ void update_effect_controls() { if (aclip >= 0) selected_clips.append(aclip); if (vclip >= 0 && aclip >= 0) { bool found = false; - Clip* vclip_ref = Olive::ActiveSequence->clips.at(vclip); + Clip* vclip_ref = olive::ActiveSequence->clips.at(vclip); for (int i=0;ilinked.size();i++) { if (vclip_ref->linked.at(i) == aclip) { found = true; @@ -136,7 +136,7 @@ void update_ui(bool modified) { QDockWidget *get_focused_panel(bool force_hover) { QDockWidget* w = nullptr; - if (Olive::CurrentConfig.hover_focus || force_hover) { + if (olive::CurrentConfig.hover_focus || force_hover) { if (panel_project->underMouse()) { w = panel_project; } else if (panel_effect_controls->underMouse()) { diff --git a/panels/project.cpp b/panels/project.cpp index 0f3c543e7..7b7cc3f27 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -89,7 +89,7 @@ Project::Project(QWidget *parent) : // optional toolbar toolbar_widget = new QWidget(); - toolbar_widget->setVisible(Olive::CurrentConfig.show_project_toolbar); + toolbar_widget->setVisible(olive::CurrentConfig.show_project_toolbar); toolbar_widget->setObjectName("project_toolbar"); QHBoxLayout* toolbar = new QHBoxLayout(toolbar_widget); @@ -111,7 +111,7 @@ Project::Project(QWidget *parent) : icon2.addFile(QStringLiteral(":/icons/open-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); toolbar_open->setIcon(icon2); toolbar_open->setToolTip("Open Project"); - connect(toolbar_open, SIGNAL(clicked(bool)), Olive::Global.data(), SLOT(open_project())); + connect(toolbar_open, SIGNAL(clicked(bool)), olive::Global.get(), SLOT(open_project())); toolbar->addWidget(toolbar_open); QPushButton* toolbar_save = new QPushButton(); @@ -120,7 +120,7 @@ Project::Project(QWidget *parent) : icon3.addFile(QStringLiteral(":/icons/save-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); toolbar_save->setIcon(icon3); toolbar_save->setToolTip("Save Project"); - connect(toolbar_save, SIGNAL(clicked(bool)), Olive::Global.data(), SLOT(save_project())); + connect(toolbar_save, SIGNAL(clicked(bool)), olive::Global.get(), SLOT(save_project())); toolbar->addWidget(toolbar_save); QPushButton* toolbar_undo = new QPushButton(); @@ -129,7 +129,7 @@ Project::Project(QWidget *parent) : icon4.addFile(QStringLiteral(":/icons/undo-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); toolbar_undo->setIcon(icon4); toolbar_undo->setToolTip("Undo"); - connect(toolbar_undo, SIGNAL(clicked(bool)), Olive::Global.data(), SLOT(undo())); + connect(toolbar_undo, SIGNAL(clicked(bool)), olive::Global.get(), SLOT(undo())); toolbar->addWidget(toolbar_undo); QPushButton* toolbar_redo = new QPushButton(); @@ -138,7 +138,7 @@ Project::Project(QWidget *parent) : icon5.addFile(QStringLiteral(":/icons/redo-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); toolbar_redo->setIcon(icon5); toolbar_redo->setToolTip("Redo"); - connect(toolbar_redo, SIGNAL(clicked(bool)), Olive::Global.data(), SLOT(redo())); + connect(toolbar_redo, SIGNAL(clicked(bool)), olive::Global.get(), SLOT(redo())); toolbar->addWidget(toolbar_redo); QLineEdit* toolbar_search = new QLineEdit(); @@ -334,7 +334,7 @@ void Project::duplicate_selected() { } } if (duped) { - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); } else { delete ca; } @@ -360,12 +360,12 @@ void Project::replace_media(Media* item, QString filename) { } if (!filename.isEmpty()) { ReplaceMediaCommand* rmc = new ReplaceMediaCommand(item, filename); - Olive::UndoStack.push(rmc); + olive::UndoStack.push(rmc); } } void Project::replace_clip_media() { - if (Olive::ActiveSequence == nullptr) { + if (olive::ActiveSequence == nullptr) { QMessageBox::critical(this, tr("No active sequence"), tr("No sequence is active, please open the sequence you want to replace clips from."), @@ -374,7 +374,7 @@ void Project::replace_clip_media() { QModelIndexList selected_items = get_current_selected(); if (selected_items.size() == 1) { Media* item = item_to_media(selected_items.at(0)); - if (item->get_type() == MEDIA_TYPE_SEQUENCE && Olive::ActiveSequence == item->to_sequence()) { + if (item->get_type() == MEDIA_TYPE_SEQUENCE && olive::ActiveSequence == item->to_sequence()) { QMessageBox::critical(this, tr("Active sequence selected"), tr("You cannot insert a sequence into itself, so no clips of this media would be in this sequence."), @@ -414,7 +414,7 @@ void Project::open_properties() { item->get_name()); if (!new_name.isEmpty()) { MediaRename* mr = new MediaRename(item, new_name); - Olive::UndoStack.push(mr); + olive::UndoStack.push(mr); } } } @@ -423,10 +423,10 @@ void Project::open_properties() { void Project::new_folder() { Media* m = create_folder_internal(nullptr); - Olive::UndoStack.push(new AddMediaCommand(m, get_selected_folder())); + olive::UndoStack.push(new AddMediaCommand(m, get_selected_folder())); QModelIndex index = project_model.create_index(m->row(), 0, m); - switch (Olive::CurrentConfig.project_view_type) { + switch (olive::CurrentConfig.project_view_type) { case PROJECT_VIEW_TREE: tree_view->edit(sorter->mapFromSource(index)); break; @@ -610,7 +610,7 @@ void Project::delete_selected_media() { // remove if (remove) { panel_effect_controls->clear_effects(true); - if (Olive::ActiveSequence != nullptr) Olive::ActiveSequence->selections.clear(); + if (olive::ActiveSequence != nullptr) olive::ActiveSequence->selections.clear(); // remove media and parents for (int m=0;mto_sequence(); - if (s == Olive::ActiveSequence) { + if (s == olive::ActiveSequence) { ca->append(new ChangeSequenceAction(nullptr)); } @@ -649,7 +649,7 @@ void Project::delete_selected_media() { } } } - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); // redraw clips if (redraw) { @@ -678,7 +678,7 @@ void Project::process_file_list(QStringList& files, bool recursive, Media* repla QVector image_sequence_urls; QVector image_sequence_importassequence; - QStringList image_sequence_formats = Olive::CurrentConfig.img_seq_formats.split("|"); + QStringList image_sequence_formats = olive::CurrentConfig.img_seq_formats.split("|"); if (!recursive) last_imported_media.clear(); @@ -826,7 +826,7 @@ void Project::process_file_list(QStringList& files, bool recursive, Media* repla } if (create_undo_action) { if (imported) { - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); for (int i=0;iselectionModel()->select(row_select, QItemSelectionModel::Select); - } else if (Olive::CurrentConfig.project_view_type == PROJECT_VIEW_ICON) { + } else if (olive::CurrentConfig.project_view_type == PROJECT_VIEW_ICON) { // if we're in icon view, we just "browse" to the parent folder icon_view->setRootIndex(hierarchy); @@ -913,7 +913,7 @@ void Project::import_dialog() { } void Project::delete_clips_using_selected_media() { - if (Olive::ActiveSequence == nullptr) { + if (olive::ActiveSequence == nullptr) { QMessageBox::critical(this, tr("No active sequence"), tr("No sequence is active, please open the sequence you want to delete clips from."), @@ -922,13 +922,13 @@ void Project::delete_clips_using_selected_media() { ComboAction* ca = new ComboAction(); bool deleted = false; QModelIndexList items = get_current_selected(); - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { for (int j=0;jmedia == m) { - ca->append(new DeleteClipAction(Olive::ActiveSequence, i)); + ca->append(new DeleteClipAction(olive::ActiveSequence, i)); deleted = true; } } @@ -939,7 +939,7 @@ void Project::delete_clips_using_selected_media() { if (delete_clips_in_clipboard_with_media(ca, m)) deleted = true; } if (deleted) { - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); update_ui(true); } else { delete ca; @@ -970,7 +970,7 @@ void Project::new_project() { set_sequence(nullptr); panel_footage_viewer->set_media(nullptr); clear(); - Olive::MainWindow->setWindowModified(false); + olive::MainWindow->setWindowModified(false); } void Project::load_project(bool autorecovery) { @@ -1075,7 +1075,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, stream.writeAttribute("framerate", QString::number(s->frame_rate, 'f', 10)); stream.writeAttribute("afreq", QString::number(s->audio_frequency)); stream.writeAttribute("alayout", QString::number(s->audio_layout)); - if (s == Olive::ActiveSequence) { + if (s == olive::ActiveSequence) { stream.writeAttribute("open", "1"); } stream.writeAttribute("workarea", QString::number(s->using_workarea)); @@ -1175,7 +1175,7 @@ void Project::save_project(bool autorecovery) { media_id = 1; sequence_id = 1; - QFile file(autorecovery ? autorecovery_filename : Olive::ActiveProjectFilename); + QFile file(autorecovery ? autorecovery_filename : olive::ActiveProjectFilename); if (!file.open(QIODevice::WriteOnly/* | QIODevice::Text*/)) { qCritical() << "Could not open file"; return; @@ -1189,8 +1189,8 @@ void Project::save_project(bool autorecovery) { stream.writeTextElement("version", QString::number(SAVE_VERSION)); - stream.writeTextElement("url", Olive::ActiveProjectFilename); - proj_dir = QFileInfo(Olive::ActiveProjectFilename).absoluteDir(); + stream.writeTextElement("url", olive::ActiveProjectFilename); + proj_dir = QFileInfo(olive::ActiveProjectFilename).absoluteDir(); save_folder(stream, MEDIA_TYPE_FOLDER, true); @@ -1215,16 +1215,16 @@ void Project::save_project(bool autorecovery) { file.close(); if (!autorecovery) { - add_recent_project(Olive::ActiveProjectFilename); - Olive::MainWindow->setWindowModified(false); + add_recent_project(olive::ActiveProjectFilename); + olive::MainWindow->setWindowModified(false); } } void Project::update_view_type() { - tree_view->setVisible(Olive::CurrentConfig.project_view_type == PROJECT_VIEW_TREE); - icon_view_container->setVisible(Olive::CurrentConfig.project_view_type == PROJECT_VIEW_ICON); + tree_view->setVisible(olive::CurrentConfig.project_view_type == PROJECT_VIEW_TREE); + icon_view_container->setVisible(olive::CurrentConfig.project_view_type == PROJECT_VIEW_ICON); - switch (Olive::CurrentConfig.project_view_type) { + switch (olive::CurrentConfig.project_view_type) { case PROJECT_VIEW_TREE: sources_common->view = tree_view; break; @@ -1235,18 +1235,18 @@ void Project::update_view_type() { } void Project::set_icon_view() { - Olive::CurrentConfig.project_view_type = PROJECT_VIEW_ICON; + olive::CurrentConfig.project_view_type = PROJECT_VIEW_ICON; update_view_type(); } void Project::set_tree_view() { - Olive::CurrentConfig.project_view_type = PROJECT_VIEW_TREE; + olive::CurrentConfig.project_view_type = PROJECT_VIEW_TREE; update_view_type(); } void Project::save_recent_projects() { // save to file - QFile f(Olive::Global->get_recent_project_list_file()); + QFile f(olive::Global->get_recent_project_list_file()); if (f.open(QFile::WriteOnly | QFile::Truncate | QFile::Text)) { QTextStream out(&f); for (int i=0;i Project::list_all_project_sequences() { } QModelIndexList Project::get_current_selected() { - if (Olive::CurrentConfig.project_view_type == PROJECT_VIEW_TREE) { + if (olive::CurrentConfig.project_view_type == PROJECT_VIEW_TREE) { return panel_project->tree_view->selectionModel()->selectedRows(); } return panel_project->icon_view->selectionModel()->selectedIndexes(); diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 058f92600..c1decbdd8 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -118,15 +118,15 @@ Timeline::Timeline(QWidget *parent) : Timeline::~Timeline() {} void Timeline::previous_cut() { - if (Olive::ActiveSequence != nullptr - && Olive::ActiveSequence->playhead > 0) { + if (olive::ActiveSequence != nullptr + && olive::ActiveSequence->playhead > 0) { long p_cut = 0; - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { - if (c->timeline_out > p_cut && c->timeline_out < Olive::ActiveSequence->playhead) { + if (c->timeline_out > p_cut && c->timeline_out < olive::ActiveSequence->playhead) { p_cut = c->timeline_out; - } else if (c->timeline_in > p_cut && c->timeline_in < Olive::ActiveSequence->playhead) { + } else if (c->timeline_in > p_cut && c->timeline_in < olive::ActiveSequence->playhead) { p_cut = c->timeline_in; } } @@ -136,16 +136,16 @@ void Timeline::previous_cut() { } void Timeline::next_cut() { - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { bool seek_enabled = false; long n_cut = LONG_MAX; - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { - if (c->timeline_in < n_cut && c->timeline_in > Olive::ActiveSequence->playhead) { + if (c->timeline_in < n_cut && c->timeline_in > olive::ActiveSequence->playhead) { n_cut = c->timeline_in; seek_enabled = true; - } else if (c->timeline_out < n_cut && c->timeline_out > Olive::ActiveSequence->playhead) { + } else if (c->timeline_out < n_cut && c->timeline_out > olive::ActiveSequence->playhead) { n_cut = c->timeline_out; seek_enabled = true; } @@ -160,11 +160,11 @@ void ripple_clips(ComboAction* ca, Sequence *s, long point, long length, const Q } void Timeline::toggle_show_all() { - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { showing_all = !showing_all; if (showing_all) { old_zoom = zoom; - set_zoom_value(double(timeline_area->width() - 200) / double(Olive::ActiveSequence->getEndFrame())); + set_zoom_value(double(timeline_area->width() - 200) / double(olive::ActiveSequence->getEndFrame())); } else { set_zoom_value(old_zoom); } @@ -335,7 +335,7 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, Sequence* s) { } } - if (Olive::CurrentConfig.add_default_effects_to_clips) { + if (olive::CurrentConfig.add_default_effects_to_clips) { if (c->track < 0) { // add default video effects c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TRANSFORM, EFFECT_TYPE_EFFECT))); @@ -346,7 +346,7 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, Sequence* s) { } } } - if (Olive::CurrentConfig.enable_seek_to_import) { + if (olive::CurrentConfig.enable_seek_to_import) { panel_sequence_viewer->seek(earliest_point); } ghosts.clear(); @@ -366,8 +366,8 @@ void Timeline::add_transition() { ComboAction* ca = new ComboAction(); bool adding = false; - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { int transition_to_add = (c->track < 0) ? TRANSITION_INTERNAL_CROSSDISSOLVE : TRANSITION_INTERNAL_LINEARFADE; if (c->get_opening_transition() == nullptr) { @@ -382,7 +382,7 @@ void Timeline::add_transition() { } if (adding) { - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); } else { delete ca; } @@ -391,13 +391,13 @@ void Timeline::add_transition() { } void Timeline::nest() { - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { QVector selected_clips; long earliest_point = LONG_MAX; // get selected clips - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { selected_clips.append(i); earliest_point = qMin(c->timeline_in, earliest_point); @@ -412,19 +412,19 @@ void Timeline::nest() { // create "nest" sequence s->name = panel_project->get_next_sequence_name(tr("Nested Sequence")); - s->width = Olive::ActiveSequence->width; - s->height = Olive::ActiveSequence->height; - s->frame_rate = Olive::ActiveSequence->frame_rate; - s->audio_frequency = Olive::ActiveSequence->audio_frequency; - s->audio_layout = Olive::ActiveSequence->audio_layout; + s->width = olive::ActiveSequence->width; + s->height = olive::ActiveSequence->height; + s->frame_rate = olive::ActiveSequence->frame_rate; + s->audio_frequency = olive::ActiveSequence->audio_frequency; + s->audio_layout = olive::ActiveSequence->audio_layout; // copy all selected clips to the nest for (int i=0;iappend(new DeleteClipAction(Olive::ActiveSequence, selected_clips.at(i))); + ca->append(new DeleteClipAction(olive::ActiveSequence, selected_clips.at(i))); // copy to new - Clip* copy = Olive::ActiveSequence->clips.at(selected_clips.at(i))->copy(s); + Clip* copy = olive::ActiveSequence->clips.at(selected_clips.at(i))->copy(s); copy->timeline_in -= earliest_point; copy->timeline_out -= earliest_point; s->clips.append(copy); @@ -439,13 +439,13 @@ void Timeline::nest() { // add nested sequence to active sequence QVector media_list; media_list.append(m); - create_ghosts_from_media(Olive::ActiveSequence, earliest_point, media_list); - add_clips_from_ghosts(ca, Olive::ActiveSequence); + create_ghosts_from_media(olive::ActiveSequence, earliest_point, media_list); + add_clips_from_ghosts(ca, olive::ActiveSequence); panel_effect_controls->clear_effects(true); - Olive::ActiveSequence->selections.clear(); + olive::ActiveSequence->selections.clear(); - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); update_ui(true); } @@ -465,7 +465,7 @@ int Timeline::calculate_track_height(int track, int value) { } void Timeline::update_sequence() { - bool null_sequence = (Olive::ActiveSequence == nullptr); + bool null_sequence = (olive::ActiveSequence == nullptr); for (int i=0;isetEnabled(!null_sequence); @@ -481,7 +481,7 @@ void Timeline::update_sequence() { if (null_sequence) { setWindowTitle(title + tr("")); } else { - setWindowTitle(title + Olive::ActiveSequence->name); + setWindowTitle(title + olive::ActiveSequence->name); update_ui(false); } } @@ -491,27 +491,27 @@ int Timeline::get_snap_range() { } bool Timeline::focused() { - return (Olive::ActiveSequence != nullptr && (headers->hasFocus() || video_area->hasFocus() || audio_area->hasFocus())); + return (olive::ActiveSequence != nullptr && (headers->hasFocus() || video_area->hasFocus() || audio_area->hasFocus())); } void Timeline::repaint_timeline() { if (!block_repaints) { bool draw = true; - if (Olive::ActiveSequence != nullptr + if (olive::ActiveSequence != nullptr && !horizontalScrollBar->isSliderDown() && !horizontalScrollBar->is_resizing() && panel_sequence_viewer->playing && !zoom_just_changed) { // auto scroll - if (Olive::CurrentConfig.autoscroll == AUTOSCROLL_PAGE_SCROLL) { - int playhead_x = getTimelineScreenPointFromFrame(Olive::ActiveSequence->playhead); + if (olive::CurrentConfig.autoscroll == AUTOSCROLL_PAGE_SCROLL) { + int playhead_x = getTimelineScreenPointFromFrame(olive::ActiveSequence->playhead); if (playhead_x < 0 || playhead_x > (editAreas->width() - videoScrollbar->width())) { - horizontalScrollBar->setValue(getScreenPointFromFrame(zoom, Olive::ActiveSequence->playhead)); + horizontalScrollBar->setValue(getScreenPointFromFrame(zoom, olive::ActiveSequence->playhead)); draw = false; } - } else if (Olive::CurrentConfig.autoscroll == AUTOSCROLL_SMOOTH_SCROLL) { - if (center_scroll_to_playhead(horizontalScrollBar, zoom, Olive::ActiveSequence->playhead)) { + } else if (olive::CurrentConfig.autoscroll == AUTOSCROLL_SMOOTH_SCROLL) { + if (center_scroll_to_playhead(horizontalScrollBar, zoom, olive::ActiveSequence->playhead)) { draw = false; } } @@ -522,7 +522,7 @@ void Timeline::repaint_timeline() { video_area->update(); audio_area->update(); - if (Olive::ActiveSequence != nullptr + if (olive::ActiveSequence != nullptr && !zoom_just_changed) { set_sb_max(); } @@ -533,16 +533,16 @@ void Timeline::repaint_timeline() { } void Timeline::select_all() { - if (Olive::ActiveSequence != nullptr) { - Olive::ActiveSequence->selections.clear(); - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + if (olive::ActiveSequence != nullptr) { + olive::ActiveSequence->selections.clear(); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { Selection s; s.in = c->timeline_in; s.out = c->timeline_out; s.track = c->track; - Olive::ActiveSequence->selections.append(s); + olive::ActiveSequence->selections.append(s); } } repaint_timeline(); @@ -554,17 +554,17 @@ void Timeline::scroll_to_frame(long frame) { } void Timeline::select_from_playhead() { - Olive::ActiveSequence->selections.clear(); - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + olive::ActiveSequence->selections.clear(); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr - && c->timeline_in <= Olive::ActiveSequence->playhead - && c->timeline_out > Olive::ActiveSequence->playhead) { + && c->timeline_in <= olive::ActiveSequence->playhead + && c->timeline_out > olive::ActiveSequence->playhead) { Selection s; s.in = c->timeline_in; s.out = c->timeline_out; s.track = c->track; - Olive::ActiveSequence->selections.append(s); + olive::ActiveSequence->selections.append(s); } } } @@ -575,8 +575,8 @@ bool Timeline::can_ripple_empty_space(long frame, int track) { rc_ripple_min = 0; rc_ripple_max = LONG_MAX; - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { if (c->timeline_in > frame || c->timeline_out > frame) { at_end_of_sequence = false; @@ -612,7 +612,7 @@ void Timeline::ripple_delete_empty_space() { void Timeline::resizeEvent(QResizeEvent *) { // adjust maximum scrollbar - if (Olive::ActiveSequence != nullptr) set_sb_max(); + if (olive::ActiveSequence != nullptr) set_sb_max(); // resize tool button widget to its contents @@ -642,39 +642,39 @@ void Timeline::resizeEvent(QResizeEvent *) { } void Timeline::delete_in_out_internal(bool ripple) { - if (Olive::ActiveSequence != nullptr && Olive::ActiveSequence->using_workarea) { + if (olive::ActiveSequence != nullptr && olive::ActiveSequence->using_workarea) { QVector areas; int video_tracks = 0, audio_tracks = 0; - Olive::ActiveSequence->getTrackLimits(&video_tracks, &audio_tracks); + olive::ActiveSequence->getTrackLimits(&video_tracks, &audio_tracks); for (int i=video_tracks;i<=audio_tracks;i++) { Selection s; - s.in = Olive::ActiveSequence->workarea_in; - s.out = Olive::ActiveSequence->workarea_out; + s.in = olive::ActiveSequence->workarea_in; + s.out = olive::ActiveSequence->workarea_out; s.track = i; areas.append(s); } ComboAction* ca = new ComboAction(); delete_areas_and_relink(ca, areas, true); - if (ripple) ripple_clips(ca, Olive::ActiveSequence, Olive::ActiveSequence->workarea_in, Olive::ActiveSequence->workarea_in - Olive::ActiveSequence->workarea_out); - ca->append(new SetTimelineInOutCommand(Olive::ActiveSequence, false, 0, 0)); - Olive::UndoStack.push(ca); + if (ripple) ripple_clips(ca, olive::ActiveSequence, olive::ActiveSequence->workarea_in, olive::ActiveSequence->workarea_in - olive::ActiveSequence->workarea_out); + ca->append(new SetTimelineInOutCommand(olive::ActiveSequence, false, 0, 0)); + olive::UndoStack.push(ca); update_ui(true); } } void Timeline::toggle_enable_on_selected_clips() { - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { ComboAction* ca = new ComboAction(); bool push_undo = false; - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { ca->append(new SetBool(&c->enabled, !c->enabled)); push_undo = true; } } if (push_undo) { - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); update_ui(true); } else { delete ca; @@ -705,8 +705,8 @@ void Timeline::delete_selection(QVector& selections, bool ripple_dele ripple_point++; bool can_ripple = true; - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr && c->timeline_in < ripple_point && c->timeline_out > ripple_point) { // conflict detected, but this clip may be getting deleted so let's check bool deleted = false; @@ -720,8 +720,8 @@ void Timeline::delete_selection(QVector& selections, bool ripple_dele } } if (!deleted) { - for (int j=0;jclips.size();j++) { - Clip* cc = Olive::ActiveSequence->clips.at(j); + for (int j=0;jclips.size();j++) { + Clip* cc = olive::ActiveSequence->clips.at(j); if (cc != nullptr && cc->track == c->track && cc->timeline_in > c->timeline_out @@ -734,12 +734,12 @@ void Timeline::delete_selection(QVector& selections, bool ripple_dele } if (can_ripple) { - ripple_clips(ca, Olive::ActiveSequence, ripple_point, -ripple_length); + ripple_clips(ca, olive::ActiveSequence, ripple_point, -ripple_length); panel_sequence_viewer->seek(ripple_point-1); } } - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); update_ui(true); } @@ -756,12 +756,12 @@ void Timeline::set_zoom_value(double v) { zoom_just_changed = true; // set scrollbar to center the playhead - if (Olive::ActiveSequence != nullptr + if (olive::ActiveSequence != nullptr && !horizontalScrollBar->is_resizing()) { // update scrollbar maximum value for new zoom set_sb_max(); - center_scroll_to_playhead(horizontalScrollBar, zoom, Olive::ActiveSequence->playhead); + center_scroll_to_playhead(horizontalScrollBar, zoom, olive::ActiveSequence->playhead); } // repaint the timeline for the new zoom/location @@ -781,9 +781,9 @@ void Timeline::decheck_tool_buttons(QObject* sender) { QVector Timeline::get_tracks_of_linked_clips(int i) { QVector tracks; - Clip* clip = Olive::ActiveSequence->clips.at(i); + Clip* clip = olive::ActiveSequence->clips.at(i); for (int j=0;jlinked.size();j++) { - tracks.append(Olive::ActiveSequence->clips.at(clip->linked.at(j))->track); + tracks.append(olive::ActiveSequence->clips.at(clip->linked.at(j))->track); } return tracks; } @@ -816,7 +816,7 @@ Clip* Timeline::split_clip(ComboAction* ca, bool transitions, int p, long frame) } Clip* Timeline::split_clip(ComboAction* ca, bool transitions, int p, long frame, long post_in) { - Clip* pre = Olive::ActiveSequence->clips.at(p); + Clip* pre = olive::ActiveSequence->clips.at(p); if (pre != nullptr && pre->timeline_in < frame && pre->timeline_out > frame) { // guard against attempts to split at in/out points bool splitting_closing_dual_transition = false; @@ -826,7 +826,7 @@ Clip* Timeline::split_clip(ComboAction* ca, bool transitions, int p, long frame, splitting_closing_dual_transition = true; } - Clip* post = pre->copy(Olive::ActiveSequence, transitions && !splitting_closing_dual_transition); + Clip* post = pre->copy(olive::ActiveSequence, transitions && !splitting_closing_dual_transition); long new_clip_length = frame - pre->timeline_in; @@ -891,7 +891,7 @@ bool Timeline::split_clip_and_relink(ComboAction *ca, int clip, long frame, bool split_cache.append(clip); - Clip* c = Olive::ActiveSequence->clips.at(clip); + Clip* c = olive::ActiveSequence->clips.at(clip); if (c != nullptr) { QVector pre_clips; QVector post_clips; @@ -912,7 +912,7 @@ bool Timeline::split_clip_and_relink(ComboAction *ca, int clip, long frame, bool for (int i=0;ilinked.size();i++) { int l = c->linked.at(i); if (!has_clip_been_split(l)) { - Clip* link = Olive::ActiveSequence->clips.at(l); + Clip* link = olive::ActiveSequence->clips.at(l); if ((original_clip_is_selected && is_clip_selected(link, true)) || !original_clip_is_selected) { split_cache.append(l); Clip* s = split_clip(ca, true, l, frame); @@ -926,7 +926,7 @@ bool Timeline::split_clip_and_relink(ComboAction *ca, int clip, long frame, bool relink_clips_using_ids(pre_clips, post_clips); } - ca->append(new AddClipCommand(Olive::ActiveSequence, post_clips)); + ca->append(new AddClipCommand(olive::ActiveSequence, post_clips)); return true; } } @@ -986,8 +986,8 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& area for (int i=0;iclips.size();j++) { - Clip* c = Olive::ActiveSequence->clips.at(j); + for (int j=0;jclips.size();j++) { + Clip* c = olive::ActiveSequence->clips.at(j); if (c != nullptr && c->track == s.track && !c->undeletable) { if (selection_contains_transition(s, c, TA_OPENING_TRANSITION)) { // delete opening transition @@ -997,7 +997,7 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& area ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); } else if (c->timeline_in >= s.in && c->timeline_out <= s.out) { // clips falls entirely within deletion area - ca->append(new DeleteClipAction(Olive::ActiveSequence, j)); + ca->append(new DeleteClipAction(olive::ActiveSequence, j)); } else if (c->timeline_in < s.in && c->timeline_out > s.out) { // middle of clip is within deletion area @@ -1043,7 +1043,7 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& area } relink_clips_using_ids(pre_clips, post_clips); - ca->append(new AddClipCommand(Olive::ActiveSequence, post_clips)); + ca->append(new AddClipCommand(olive::ActiveSequence, post_clips)); } void Timeline::copy(bool del) { @@ -1052,11 +1052,11 @@ void Timeline::copy(bool del) { long min_in = 0; - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { - for (int j=0;jselections.size();j++) { - const Selection& s = Olive::ActiveSequence->selections.at(j); + for (int j=0;jselections.size();j++) { + const Selection& s = olive::ActiveSequence->selections.at(j); if (s.track == c->track && !((c->timeline_in <= s.in && c->timeline_out <= s.in) || (c->timeline_in >= s.out && c->timeline_out >= s.out))) { if (!cleared) { clear_clipboard(); @@ -1100,7 +1100,7 @@ void Timeline::copy(bool del) { } if (del && copied) { - delete_selection(Olive::ActiveSequence->selections, false); + delete_selection(olive::ActiveSequence->selections, false); } } @@ -1108,7 +1108,7 @@ void Timeline::relink_clips_using_ids(QVector& old_clips, QVector& n // relink pasted clips for (int i=0;iclips.at(old_clips.at(i)); + Clip* oc = olive::ActiveSequence->clips.at(old_clips.at(i)); for (int j=0;jlinked.size();j++) { for (int k=0;klinked.at(j) == old_clips.at(k)) { @@ -1135,15 +1135,15 @@ void Timeline::paste(bool insert) { Clip* c = static_cast(clipboard.at(i)); // create copy of clip and offset by playhead - Clip* cc = c->copy(Olive::ActiveSequence); + Clip* cc = c->copy(olive::ActiveSequence); // convert frame rates - cc->timeline_in = refactor_frame_number(cc->timeline_in, c->cached_fr, Olive::ActiveSequence->frame_rate); - cc->timeline_out = refactor_frame_number(cc->timeline_out, c->cached_fr, Olive::ActiveSequence->frame_rate); - cc->clip_in = refactor_frame_number(cc->clip_in, c->cached_fr, Olive::ActiveSequence->frame_rate); + cc->timeline_in = refactor_frame_number(cc->timeline_in, c->cached_fr, olive::ActiveSequence->frame_rate); + cc->timeline_out = refactor_frame_number(cc->timeline_out, c->cached_fr, olive::ActiveSequence->frame_rate); + cc->clip_in = refactor_frame_number(cc->clip_in, c->cached_fr, olive::ActiveSequence->frame_rate); - cc->timeline_in += Olive::ActiveSequence->playhead; - cc->timeline_out += Olive::ActiveSequence->playhead; + cc->timeline_in += olive::ActiveSequence->playhead; + cc->timeline_out += olive::ActiveSequence->playhead; cc->track = c->track; paste_start = qMin(paste_start, cc->timeline_in); @@ -1161,8 +1161,8 @@ void Timeline::paste(bool insert) { } if (insert) { split_cache.clear(); - split_all_clips_at_point(ca, Olive::ActiveSequence->playhead); - ripple_clips(ca, Olive::ActiveSequence, paste_start, paste_end - paste_start); + split_all_clips_at_point(ca, olive::ActiveSequence->playhead); + ripple_clips(ca, olive::ActiveSequence, paste_start, paste_end - paste_start); } else { delete_areas_and_relink(ca, delete_areas, false); } @@ -1182,13 +1182,13 @@ void Timeline::paste(bool insert) { } } - ca->append(new AddClipCommand(Olive::ActiveSequence, pasted_clips)); + ca->append(new AddClipCommand(olive::ActiveSequence, pasted_clips)); - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); update_ui(true); - if (Olive::CurrentConfig.paste_seeks) { + if (olive::CurrentConfig.paste_seeks) { panel_sequence_viewer->seek(paste_end); } } else if (clipboard_type == CLIPBOARD_TYPE_EFFECT) { @@ -1199,8 +1199,8 @@ void Timeline::paste(bool insert) { bool skip = false; bool ask_conflict = true; - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { for (int j=0;j(clipboard.at(j)); @@ -1259,7 +1259,7 @@ void Timeline::paste(bool insert) { } if (push) { ca->appendPost(new ReloadEffectsCommand()); - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); } else { delete ca; } @@ -1269,8 +1269,8 @@ void Timeline::paste(bool insert) { } void Timeline::edit_to_point_internal(bool in, bool ripple) { - if (Olive::ActiveSequence != nullptr) { - if (Olive::ActiveSequence->clips.size() > 0) { + if (olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence->clips.size() > 0) { // get track count int track_min = INT_MAX; int track_max = INT_MIN; @@ -1282,25 +1282,25 @@ void Timeline::edit_to_point_internal(bool in, bool ripple) { long prev_cut = 0; // find closest in point to playhead - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { track_min = qMin(track_min, c->track); track_max = qMax(track_max, c->track); sequence_end = qMax(c->timeline_out, sequence_end); - if (c->timeline_in == Olive::ActiveSequence->playhead) + if (c->timeline_in == olive::ActiveSequence->playhead) playhead_falls_on_in = true; - if (c->timeline_out == Olive::ActiveSequence->playhead) + if (c->timeline_out == olive::ActiveSequence->playhead) playhead_falls_on_out = true; - if (c->timeline_in > Olive::ActiveSequence->playhead) + if (c->timeline_in > olive::ActiveSequence->playhead) next_cut = qMin(c->timeline_in, next_cut); - if (c->timeline_out > Olive::ActiveSequence->playhead) + if (c->timeline_out > olive::ActiveSequence->playhead) next_cut = qMin(c->timeline_out, next_cut); - if (c->timeline_in < Olive::ActiveSequence->playhead) + if (c->timeline_in < olive::ActiveSequence->playhead) prev_cut = qMax(c->timeline_in, prev_cut); - if (c->timeline_out < Olive::ActiveSequence->playhead) + if (c->timeline_out < olive::ActiveSequence->playhead) prev_cut = qMax(c->timeline_out, prev_cut); } } @@ -1310,13 +1310,13 @@ void Timeline::edit_to_point_internal(bool in, bool ripple) { QVector areas; ComboAction* ca = new ComboAction(); bool push_undo = true; - long seek = Olive::ActiveSequence->playhead; + long seek = olive::ActiveSequence->playhead; - if ((in && (playhead_falls_on_out || (playhead_falls_on_in && Olive::ActiveSequence->playhead == 0))) - || (!in && (playhead_falls_on_in || (playhead_falls_on_out && Olive::ActiveSequence->playhead == sequence_end)))) { // one frame mode + if ((in && (playhead_falls_on_out || (playhead_falls_on_in && olive::ActiveSequence->playhead == 0))) + || (!in && (playhead_falls_on_in || (playhead_falls_on_out && olive::ActiveSequence->playhead == sequence_end)))) { // one frame mode if (ripple) { // set up deletion areas based on track count - long in_point = Olive::ActiveSequence->playhead; + long in_point = olive::ActiveSequence->playhead; if (!in) { in_point--; seek--; @@ -1334,7 +1334,7 @@ void Timeline::edit_to_point_internal(bool in, bool ripple) { // trim and move clips around the in point delete_areas_and_relink(ca, areas, true); - if (ripple) ripple_clips(ca, Olive::ActiveSequence, in_point, -1); + if (ripple) ripple_clips(ca, olive::ActiveSequence, in_point, -1); } else { push_undo = false; } @@ -1345,8 +1345,8 @@ void Timeline::edit_to_point_internal(bool in, bool ripple) { // set up deletion areas based on track count Selection s; if (in) seek = prev_cut; - s.in = in ? prev_cut : Olive::ActiveSequence->playhead; - s.out = in ? Olive::ActiveSequence->playhead : next_cut; + s.in = in ? prev_cut : olive::ActiveSequence->playhead; + s.out = in ? olive::ActiveSequence->playhead : next_cut; if (s.in == s.out) { push_undo = false; @@ -1358,16 +1358,16 @@ void Timeline::edit_to_point_internal(bool in, bool ripple) { // trim and move clips around the in point delete_areas_and_relink(ca, areas, true); - if (ripple) ripple_clips(ca, Olive::ActiveSequence, s.in, s.in - s.out); + if (ripple) ripple_clips(ca, olive::ActiveSequence, s.in, s.in - s.out); } } if (push_undo) { - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); update_ui(true); - if (seek != Olive::ActiveSequence->playhead && ripple) panel_sequence_viewer->seek(seek); + if (seek != olive::ActiveSequence->playhead && ripple) panel_sequence_viewer->seek(seek); } else { delete ca; } @@ -1386,11 +1386,11 @@ bool Timeline::split_selection(ComboAction* ca) { QVector secondary_post_splits; // find clips within selection and split - for (int j=0;jclips.size();j++) { - Clip* clip = Olive::ActiveSequence->clips.at(j); + for (int j=0;jclips.size();j++) { + Clip* clip = olive::ActiveSequence->clips.at(j); if (clip != nullptr) { - for (int i=0;iselections.size();i++) { - const Selection& s = Olive::ActiveSequence->selections.at(i); + for (int i=0;iselections.size();i++) { + const Selection& s = olive::ActiveSequence->selections.at(i); if (s.track == clip->track) { Clip* post_b = split_clip(ca, true, j, s.out); Clip* post_a = split_clip(ca, post_b == nullptr, j, s.in); @@ -1413,8 +1413,8 @@ bool Timeline::split_selection(ComboAction* ca) { relink_clips_using_ids(pre_splits, post_splits); relink_clips_using_ids(pre_splits, secondary_post_splits); - ca->append(new AddClipCommand(Olive::ActiveSequence, post_splits)); - ca->append(new AddClipCommand(Olive::ActiveSequence, secondary_post_splits)); + ca->append(new AddClipCommand(olive::ActiveSequence, post_splits)); + ca->append(new AddClipCommand(olive::ActiveSequence, secondary_post_splits)); return true; } @@ -1423,8 +1423,8 @@ bool Timeline::split_selection(ComboAction* ca) { bool Timeline::split_all_clips_at_point(ComboAction* ca, long point) { bool split = false; - for (int j=0;jclips.size();j++) { - Clip* c = Olive::ActiveSequence->clips.at(j); + for (int j=0;jclips.size();j++) { + Clip* c = olive::ActiveSequence->clips.at(j); if (c != nullptr) { // always relinks if (split_clip_and_relink(ca, j, point, true)) { @@ -1440,14 +1440,14 @@ void Timeline::split_at_playhead() { bool split_selected = false; split_cache.clear(); - if (Olive::ActiveSequence->selections.size() > 0) { + if (olive::ActiveSequence->selections.size() > 0) { // see if whole clips are selected QVector pre_clips; QVector post_clips; - for (int j=0;jclips.size();j++) { - Clip* clip = Olive::ActiveSequence->clips.at(j); + for (int j=0;jclips.size();j++) { + Clip* clip = olive::ActiveSequence->clips.at(j); if (clip != nullptr && is_clip_selected(clip, true)) { - Clip* s = split_clip(ca, true, j, Olive::ActiveSequence->playhead); + Clip* s = split_clip(ca, true, j, olive::ActiveSequence->playhead); if (s != nullptr) { pre_clips.append(j); post_clips.append(s); @@ -1459,7 +1459,7 @@ void Timeline::split_at_playhead() { if (split_selected) { // relink clips if we split relink_clips_using_ids(pre_clips, post_clips); - ca->append(new AddClipCommand(Olive::ActiveSequence, post_clips)); + ca->append(new AddClipCommand(olive::ActiveSequence, post_clips)); } else { // split a selection if not split_selected = split_selection(ca); @@ -1468,11 +1468,11 @@ void Timeline::split_at_playhead() { // if nothing was selected or no selections fell within playhead, simply split at playhead if (!split_selected) { - split_selected = split_all_clips_at_point(ca, Olive::ActiveSequence->playhead); + split_selected = split_all_clips_at_point(ca, olive::ActiveSequence->playhead); } if (split_selected) { - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); update_ui(true); } else { delete ca; @@ -1480,10 +1480,10 @@ void Timeline::split_at_playhead() { } void Timeline::ripple_delete() { - if (Olive::ActiveSequence != nullptr) { - if (Olive::ActiveSequence->selections.size() > 0) { - panel_timeline->delete_selection(Olive::ActiveSequence->selections, true); - } else if (Olive::CurrentConfig.hover_focus && get_focused_panel() == panel_timeline) { + if (olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence->selections.size() > 0) { + panel_timeline->delete_selection(olive::ActiveSequence->selections, true); + } else if (olive::CurrentConfig.hover_focus && get_focused_panel() == panel_timeline) { if (panel_timeline->can_ripple_empty_space(panel_timeline->cursor_frame, panel_timeline->cursor_track)) { panel_timeline->ripple_delete_empty_space(); } @@ -1492,13 +1492,13 @@ void Timeline::ripple_delete() { } void Timeline::deselect_area(long in, long out, int track) { - int len = Olive::ActiveSequence->selections.size(); + int len = olive::ActiveSequence->selections.size(); for (int i=0;iselections[i]; + Selection& s = olive::ActiveSequence->selections[i]; if (s.track == track) { if (s.in >= in && s.out <= out) { // whole selection is in deselect area - Olive::ActiveSequence->selections.removeAt(i); + olive::ActiveSequence->selections.removeAt(i); i--; len--; } else if (s.in < in && s.out > out) { @@ -1507,7 +1507,7 @@ void Timeline::deselect_area(long in, long out, int track) { new_sel.in = out; new_sel.out = s.out; new_sel.track = s.track; - Olive::ActiveSequence->selections.append(new_sel); + olive::ActiveSequence->selections.append(new_sel); s.out = in; } else if (s.in < in && s.out > in) { @@ -1537,25 +1537,25 @@ bool Timeline::snap_to_timeline(long* l, bool use_playhead, bool use_markers, bo if (snapping) { if (use_playhead && !panel_sequence_viewer->playing) { // snap to playhead - if (snap_to_point(Olive::ActiveSequence->playhead, l)) return true; + if (snap_to_point(olive::ActiveSequence->playhead, l)) return true; } // snap to marker if (use_markers) { - for (int i=0;imarkers.size();i++) { - if (snap_to_point(Olive::ActiveSequence->markers.at(i).frame, l)) return true; + for (int i=0;imarkers.size();i++) { + if (snap_to_point(olive::ActiveSequence->markers.at(i).frame, l)) return true; } } // snap to in/out - if (use_workarea && Olive::ActiveSequence->using_workarea) { - if (snap_to_point(Olive::ActiveSequence->workarea_in, l)) return true; - if (snap_to_point(Olive::ActiveSequence->workarea_out, l)) return true; + if (use_workarea && olive::ActiveSequence->using_workarea) { + if (snap_to_point(olive::ActiveSequence->workarea_in, l)) return true; + if (snap_to_point(olive::ActiveSequence->workarea_out, l)) return true; } // snap to clip/transition - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { if (snap_to_point(c->timeline_in, l)) { return true; @@ -1586,14 +1586,14 @@ void Timeline::set_marker() { QVector clips_selected; bool clip_mode = false; - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { // only add markers if the playhead is inside the clip - if (Olive::ActiveSequence->playhead >= c->timeline_in - && Olive::ActiveSequence->playhead <= c->timeline_out) { + if (olive::ActiveSequence->playhead >= c->timeline_in + && olive::ActiveSequence->playhead <= c->timeline_out) { clips_selected.append(i); } @@ -1610,7 +1610,7 @@ void Timeline::set_marker() { } // pass off to internal set marker function - set_marker_internal(Olive::ActiveSequence, clips_selected); + set_marker_internal(olive::ActiveSequence, clips_selected); } @@ -1640,9 +1640,9 @@ void Timeline::edit_to_out_point() { void Timeline::toggle_links() { LinkCommand* command = new LinkCommand(); - command->s = Olive::ActiveSequence; - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + command->s = olive::ActiveSequence; + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { if (!command->clips.contains(i)) command->clips.append(i); @@ -1656,7 +1656,7 @@ void Timeline::toggle_links() { } } if (command->clips.size() > 0) { - Olive::UndoStack.push(command); + olive::UndoStack.push(command); repaint_timeline(); } else { delete command; @@ -1686,7 +1686,7 @@ void Timeline::decrease_track_height() { } void Timeline::deselect() { - Olive::ActiveSequence->selections.clear(); + olive::ActiveSequence->selections.clear(); repaint_timeline(); } @@ -1757,7 +1757,7 @@ void Timeline::setScroll(int s) { } void Timeline::record_btn_click() { - if (Olive::ActiveProjectFilename.isEmpty()) { + if (olive::ActiveProjectFilename.isEmpty()) { QMessageBox::critical(this, tr("Unsaved Project"), tr("You must save this project before you can record audio in it."), @@ -1765,7 +1765,7 @@ void Timeline::record_btn_click() { } else { creating = true; creating_object = ADD_OBJ_AUDIO; - Olive::MainWindow->statusBar()->showMessage( + olive::MainWindow->statusBar()->showMessage( tr("Click on the timeline where you want to start recording (drag to limit the recording to a certain timeframe)"), 10000); } @@ -1823,7 +1823,7 @@ void Timeline::resize_move(double z) { } void Timeline::set_sb_max() { - headers->set_scrollbar_max(horizontalScrollBar, Olive::ActiveSequence->getEndFrame(), editAreas->width() - getScreenPointFromFrame(zoom, 200)); + headers->set_scrollbar_max(horizontalScrollBar, olive::ActiveSequence->getEndFrame(), editAreas->width() - getScreenPointFromFrame(zoom, 200)); } void Timeline::setup_ui() { diff --git a/panels/viewer.cpp b/panels/viewer.cpp index 5322d20f0..76c9103f5 100644 --- a/panels/viewer.cpp +++ b/panels/viewer.cpp @@ -115,7 +115,7 @@ bool Viewer::is_main_sequence() { void Viewer::set_main_sequence() { clean_created_seq(); - set_sequence(true, Olive::ActiveSequence); + set_sequence(true, olive::ActiveSequence); } void Viewer::reset_all_audio() { @@ -276,7 +276,7 @@ void Viewer::seek(long p) { if (main_sequence) { panel_timeline->scroll_to_frame(p); panel_effect_controls->scroll_to_frame(p); - if (Olive::CurrentConfig.seek_also_selects) { + if (olive::CurrentConfig.seek_also_selects) { panel_timeline->select_from_playhead(); update_fx = true; } @@ -386,7 +386,7 @@ void Viewer::play(bool in_to_out) { playback_speed = 1; } - bool seek_to_in = (seq->using_workarea && (Olive::CurrentConfig.loop || playing_in_to_out)); + bool seek_to_in = (seq->using_workarea && (olive::CurrentConfig.loop || playing_in_to_out)); if (!is_recording_cued() && playback_speed > 0 && (playing_in_to_out @@ -459,7 +459,7 @@ void Viewer::pause() { QVector add_clips; add_clips.append(c); - Olive::UndoStack.push(new AddClipCommand(seq, add_clips)); // add clip + olive::UndoStack.push(new AddClipCommand(seq, add_clips)); // add clip } } } @@ -469,7 +469,7 @@ void Viewer::update_playhead_timecode(long p) { } void Viewer::update_end_timecode() { - end_timecode->setText((seq == nullptr) ? frame_to_timecode(0, Olive::CurrentConfig.timecode_view, 30) : frame_to_timecode(seq->getEndFrame(), Olive::CurrentConfig.timecode_view, seq->frame_rate)); + end_timecode->setText((seq == nullptr) ? frame_to_timecode(0, olive::CurrentConfig.timecode_view, 30) : frame_to_timecode(seq->getEndFrame(), olive::CurrentConfig.timecode_view, seq->frame_rate)); } void Viewer::update_header_zoom() { @@ -523,7 +523,7 @@ void Viewer::update_viewer() { void Viewer::clear_in() { if (seq != nullptr && seq->using_workarea) { - Olive::UndoStack.push(new SetTimelineInOutCommand(seq, true, 0, seq->workarea_out)); + olive::UndoStack.push(new SetTimelineInOutCommand(seq, true, 0, seq->workarea_out)); update_parents(); } } @@ -531,7 +531,7 @@ void Viewer::clear_in() { void Viewer::clear_out() { if (seq != nullptr && seq->using_workarea) { - Olive::UndoStack.push(new SetTimelineInOutCommand(seq, true, seq->workarea_in, seq->getEndFrame())); + olive::UndoStack.push(new SetTimelineInOutCommand(seq, true, seq->workarea_in, seq->getEndFrame())); update_parents(); } } @@ -539,7 +539,7 @@ void Viewer::clear_out() { void Viewer::clear_inout_point() { if (seq != nullptr && seq->using_workarea) { - Olive::UndoStack.push(new SetTimelineInOutCommand(seq, false, 0, 0)); + olive::UndoStack.push(new SetTimelineInOutCommand(seq, false, 0, 0)); update_parents(); } } @@ -603,13 +603,13 @@ void Viewer::set_playback_speed(int s) { } long Viewer::get_seq_in() { - return ((Olive::CurrentConfig.loop || playing_in_to_out) && seq->using_workarea) + return ((olive::CurrentConfig.loop || playing_in_to_out) && seq->using_workarea) ? seq->workarea_in : 0; } long Viewer::get_seq_out() { - return ((Olive::CurrentConfig.loop || playing_in_to_out) && seq->using_workarea && previous_playhead < seq->workarea_out) + return ((olive::CurrentConfig.loop || playing_in_to_out) && seq->using_workarea && previous_playhead < seq->workarea_out) ? seq->workarea_out : seq->getEndFrame(); } @@ -801,8 +801,8 @@ void Viewer::timer_update() { previous_playhead = seq->playhead; seq->playhead = qMax(0, qRound(playhead_start + ((QDateTime::currentMSecsSinceEpoch()-start_msecs) * 0.001 * seq->frame_rate * playback_speed))); - if (Olive::CurrentConfig.seek_also_selects) panel_timeline->select_from_playhead(); - update_parents(Olive::CurrentConfig.seek_also_selects); + if (olive::CurrentConfig.seek_also_selects) panel_timeline->select_from_playhead(); + update_parents(olive::CurrentConfig.seek_also_selects); if (playing) { if (playback_speed < 0 && seq->playhead == 0) { @@ -816,7 +816,7 @@ void Viewer::timer_update() { pause(); } if (seq->using_workarea && seq->playhead >= seq->workarea_out) { - if (Olive::CurrentConfig.loop) { + if (olive::CurrentConfig.loop) { // loop play(); } else if (playing_in_to_out) { @@ -864,7 +864,7 @@ void Viewer::set_sequence(bool main, Sequence *s) { } main_sequence = main; - seq = (main) ? Olive::ActiveSequence : s; + seq = (main) ? olive::ActiveSequence : s; bool null_sequence = (seq == nullptr); diff --git a/playback/audio.cpp b/playback/audio.cpp index 1ac0b519d..84e981cc1 100644 --- a/playback/audio.cpp +++ b/playback/audio.cpp @@ -68,7 +68,7 @@ QAudioDeviceInfo get_audio_device(QAudio::Mode mode) { QList devs = QAudioDeviceInfo::availableDevices(mode); // try to retrieve preferred device from config - QString preferred_device = (mode == QAudio::AudioOutput) ? Olive::CurrentConfig.preferred_audio_output : Olive::CurrentConfig.preferred_audio_input; + QString preferred_device = (mode == QAudio::AudioOutput) ? olive::CurrentConfig.preferred_audio_output : olive::CurrentConfig.preferred_audio_input; if (!preferred_device.isEmpty()) { for (int i=0;iaudio_frequency : audio_output->format().sampleRate(); + return audio_rendering ? olive::ActiveSequence->audio_frequency : audio_output->format().sampleRate(); } qint64 get_buffer_offset_from_frame(double framerate, long frame) { @@ -323,12 +323,12 @@ void write_wave_trailer(QFile& f) { } bool start_recording() { - if (Olive::ActiveSequence == nullptr) { + if (olive::ActiveSequence == nullptr) { qCritical() << "No active sequence to record into"; return false; } - QString audio_path = QCoreApplication::translate("Audio", "%1 Audio").arg(Olive::ActiveProjectFilename); + QString audio_path = QCoreApplication::translate("Audio", "%1 Audio").arg(olive::ActiveProjectFilename); QDir audio_dir(audio_path); if (!audio_dir.exists() && !audio_dir.mkpath(".")) { qCritical() << "Failed to create audio directory"; @@ -354,8 +354,8 @@ bool start_recording() { } QAudioFormat audio_format = audio_output->format(); - if (Olive::CurrentConfig.recording_mode != audio_format.channelCount()) { - audio_format.setChannelCount(Olive::CurrentConfig.recording_mode); + if (olive::CurrentConfig.recording_mode != audio_format.channelCount()) { + audio_format.setChannelCount(olive::CurrentConfig.recording_mode); } QAudioDeviceInfo info = get_audio_device(QAudio::AudioInput); diff --git a/playback/cacher.cpp b/playback/cacher.cpp index c1f71985a..f05145bfa 100644 --- a/playback/cacher.cpp +++ b/playback/cacher.cpp @@ -137,7 +137,7 @@ void cache_audio_worker(Clip* c, bool scrubbing, QVector& nests, int play } if (temp_reverse) { - long seq_end = Olive::ActiveSequence->getEndFrame(); + long seq_end = olive::ActiveSequence->getEndFrame(); timeline_in = seq_end - timeline_in; timeline_out = seq_end - timeline_out; target_frame = seq_end - target_frame; @@ -743,15 +743,15 @@ void open_clip_worker(Clip* clip) { clip->max_queue_size = 1; } else { clip->max_queue_size = 0; - if (Olive::CurrentConfig.upcoming_queue_type == FRAME_QUEUE_TYPE_FRAMES) { - clip->max_queue_size += qCeil(Olive::CurrentConfig.upcoming_queue_size); + if (olive::CurrentConfig.upcoming_queue_type == FRAME_QUEUE_TYPE_FRAMES) { + clip->max_queue_size += qCeil(olive::CurrentConfig.upcoming_queue_size); } else { - clip->max_queue_size += qCeil(ms->video_frame_rate * m->speed * Olive::CurrentConfig.upcoming_queue_size); + clip->max_queue_size += qCeil(ms->video_frame_rate * m->speed * olive::CurrentConfig.upcoming_queue_size); } - if (Olive::CurrentConfig.previous_queue_type == FRAME_QUEUE_TYPE_FRAMES) { - clip->max_queue_size += qCeil(Olive::CurrentConfig.previous_queue_size); + if (olive::CurrentConfig.previous_queue_type == FRAME_QUEUE_TYPE_FRAMES) { + clip->max_queue_size += qCeil(olive::CurrentConfig.previous_queue_size); } else { - clip->max_queue_size += qCeil(ms->video_frame_rate * m->speed * Olive::CurrentConfig.previous_queue_size); + clip->max_queue_size += qCeil(ms->video_frame_rate * m->speed * olive::CurrentConfig.previous_queue_size); } } diff --git a/playback/playback.cpp b/playback/playback.cpp index d156d653b..7f8a95066 100644 --- a/playback/playback.cpp +++ b/playback/playback.cpp @@ -200,8 +200,8 @@ void get_clip_frame(Clip* c, long playhead, bool& texture_failed) { int64_t minimum_ts = target_frame->pts; int previous_frame_count = 0; - if (Olive::CurrentConfig.previous_queue_type == FRAME_QUEUE_TYPE_SECONDS) { - minimum_ts -= (second_pts*Olive::CurrentConfig.previous_queue_size); + if (olive::CurrentConfig.previous_queue_type == FRAME_QUEUE_TYPE_SECONDS) { + minimum_ts -= (second_pts*olive::CurrentConfig.previous_queue_size); } //dout << "closest frame was" << closest_frame << "with" << target_frame->pts << "/" << target_pts; @@ -210,7 +210,7 @@ void get_clip_frame(Clip* c, long playhead, bool& texture_failed) { next_pts = c->queue.at(i)->pts; } if (c->queue.at(i) != target_frame && ((c->queue.at(i)->pts > minimum_ts) == c->reverse)) { - if (Olive::CurrentConfig.previous_queue_type == FRAME_QUEUE_TYPE_SECONDS) { + if (olive::CurrentConfig.previous_queue_type == FRAME_QUEUE_TYPE_SECONDS) { //dout << "removed frame at" << i << "because its pts was" << c->queue.at(i)->pts << "compared to" << target_frame->pts; av_frame_free(&c->queue[i]); // may be a little heavy for the main thread? c->queue.removeAt(i); @@ -222,8 +222,8 @@ void get_clip_frame(Clip* c, long playhead, bool& texture_failed) { } } - if (Olive::CurrentConfig.previous_queue_type == FRAME_QUEUE_TYPE_FRAMES) { - while (previous_frame_count > qCeil(Olive::CurrentConfig.previous_queue_size)) { + if (olive::CurrentConfig.previous_queue_type == FRAME_QUEUE_TYPE_FRAMES) { + while (previous_frame_count > qCeil(olive::CurrentConfig.previous_queue_size)) { int smallest = 0; for (int i=1;iqueue.size();i++) { if (c->queue.at(i)->pts < c->queue.at(smallest)->pts) { @@ -257,7 +257,7 @@ void get_clip_frame(Clip* c, long playhead, bool& texture_failed) { #ifdef GCF_DEBUG dout << "GCF ==> RESET" << target_pts << "(" << target_frame->pts << "-" << target_frame->pts+target_frame->pkt_duration << ")"; #endif - if (!Olive::CurrentConfig.fast_seeking) target_frame = nullptr; + if (!olive::CurrentConfig.fast_seeking) target_frame = nullptr; reset = true; c->last_invalid_ts = target_pts; } else { @@ -453,7 +453,7 @@ bool is_clip_active(Clip* c, long playhead) { void set_sequence(Sequence* s) { panel_effect_controls->clear_effects(true); - Olive::ActiveSequence = s; + olive::ActiveSequence = s; panel_sequence_viewer->set_main_sequence(); panel_timeline->update_sequence(); panel_timeline->setFocus(); diff --git a/project/clip.cpp b/project/clip.cpp index 5ae72eb7f..53aefdaec 100644 --- a/project/clip.cpp +++ b/project/clip.cpp @@ -49,7 +49,7 @@ Clip::Clip(Sequence* s) : speed(1.0), reverse(false), maintain_audio_pitch(false), - autoscale(Olive::CurrentConfig.autoscale_by_default), + autoscale(olive::CurrentConfig.autoscale_by_default), opening_transition(-1), closing_transition(-1), undeletable(false), diff --git a/project/effect.cpp b/project/effect.cpp index d8d05e70a..cdafc379a 100644 --- a/project/effect.cpp +++ b/project/effect.cpp @@ -96,7 +96,7 @@ Effect* create_effect(Clip* c, const EffectMeta* em) { return new Effect(c, em); } else { qCritical() << "Invalid effect data"; - QMessageBox::critical(Olive::MainWindow, + QMessageBox::critical(olive::MainWindow, QCoreApplication::translate("Effect", "Invalid effect"), QCoreApplication::translate("Effect", "No candidate for effect '%1'. This effect may be corrupt. Try reinstalling it or Olive.").arg(em->name)); } @@ -395,7 +395,7 @@ void Effect::field_changed() { void Effect::show_context_menu(const QPoint& pos) { if (meta->type == EFFECT_TYPE_EFFECT) { - QMenu menu(Olive::MainWindow); + QMenu menu(olive::MainWindow); int index = get_index_in_clip(); @@ -432,7 +432,7 @@ void Effect::delete_self() { EffectDeleteCommand* command = new EffectDeleteCommand(); command->clips.append(parent_clip); command->fx.append(get_index_in_clip()); - Olive::UndoStack.push(command); + olive::UndoStack.push(command); update_ui(true); } @@ -441,7 +441,7 @@ void Effect::move_up() { command->clip = parent_clip; command->from = get_index_in_clip(); command->to = command->from - 1; - Olive::UndoStack.push(command); + olive::UndoStack.push(command); panel_effect_controls->reload_clips(); panel_sequence_viewer->viewer_widget->frame_update(); } @@ -451,14 +451,14 @@ void Effect::move_down() { command->clip = parent_clip; command->from = get_index_in_clip(); command->to = command->from + 1; - Olive::UndoStack.push(command); + olive::UndoStack.push(command); panel_effect_controls->reload_clips(); panel_sequence_viewer->viewer_widget->frame_update(); } void Effect::save_to_file() { // save effect settings to file - QString file = QFileDialog::getSaveFileName(Olive::MainWindow, + QString file = QFileDialog::getSaveFileName(olive::MainWindow, tr("Save Effect Settings"), QString(), tr("Effect XML Settings %1").arg("(*.xml)")); @@ -478,7 +478,7 @@ void Effect::save_to_file() { file_handle.close(); } else { - QMessageBox::critical(Olive::MainWindow, + QMessageBox::critical(olive::MainWindow, tr("Save Settings Failed"), tr("Failed to open \"%1\" for writing.").arg(file), QMessageBox::Ok); @@ -488,7 +488,7 @@ void Effect::save_to_file() { void Effect::load_from_file() { // load effect settings from file - QString file = QFileDialog::getOpenFileName(Olive::MainWindow, + QString file = QFileDialog::getOpenFileName(olive::MainWindow, tr("Load Effect Settings"), QString(), tr("Effect XML Settings %1").arg("(*.xml)")); @@ -498,13 +498,13 @@ void Effect::load_from_file() { QFile file_handle(file); if (file_handle.open(QFile::ReadOnly)) { - Olive::UndoStack.push(new SetEffectData(this, file_handle.readAll())); + olive::UndoStack.push(new SetEffectData(this, file_handle.readAll())); file_handle.close(); update_ui(false); } else { - QMessageBox::critical(Olive::MainWindow, + QMessageBox::critical(olive::MainWindow, tr("Load Settings Failed"), tr("Failed to open \"%1\" for reading.").arg(file), QMessageBox::Ok); @@ -713,7 +713,7 @@ void Effect::load_from_string(const QByteArray &s) { // pass off to standard loading function load(stream); } else { - QMessageBox::critical(Olive::MainWindow, + QMessageBox::critical(olive::MainWindow, tr("Load Settings Failed"), tr("This settings file doesn't match this effect."), QMessageBox::Ok); @@ -774,7 +774,7 @@ void Effect::open() { qWarning() << "Tried to open an effect that was already open"; close(); } - if (Olive::CurrentRuntimeConfig.shaders_are_enabled && enable_shader) { + if (olive::CurrentRuntimeConfig.shaders_are_enabled && enable_shader) { if (QOpenGLContext::currentContext() == nullptr) { qWarning() << "No current context to create a shader program for - will retry next repaint"; } else { @@ -832,7 +832,7 @@ void Effect::startEffect() { open(); qWarning() << "Tried to start a closed effect - opening"; } - if (Olive::CurrentRuntimeConfig.shaders_are_enabled + if (olive::CurrentRuntimeConfig.shaders_are_enabled && enable_shader && glslProgram->isLinked()) { bound = glslProgram->bind(); @@ -962,7 +962,7 @@ void Effect::gizmo_move(EffectGizmo* gizmo, int x_movement, int y_movement, doub gizmo->y_field2->set_double_value(gizmo->y_field2->get_double_value(timecode) + y_movement*gizmo->y_field_multi2); gizmo->y_field2->make_key_from_change(ca); } - if (done) Olive::UndoStack.push(ca); + if (done) olive::UndoStack.push(ca); break; } } diff --git a/project/effectfield.cpp b/project/effectfield.cpp index 5cea2015f..5758bd4c8 100644 --- a/project/effectfield.cpp +++ b/project/effectfield.cpp @@ -70,7 +70,7 @@ EffectField::EffectField(EffectRow *parent, int t, const QString &i) : TextEditEx* edit = new TextEditEx(); // TODO magic number 2 - i'm not sure how to make this work otherwise though - edit->setFixedHeight(qCeil(edit->fontMetrics().lineSpacing()*Olive::CurrentConfig.effect_textbox_lines + edit->document()->documentMargin() + edit->document()->documentMargin() + 2)); + edit->setFixedHeight(qCeil(edit->fontMetrics().lineSpacing()*olive::CurrentConfig.effect_textbox_lines + edit->document()->documentMargin() + edit->document()->documentMargin() + 2)); edit->setUndoRedoEnabled(true); ui_element = edit; @@ -349,7 +349,7 @@ void EffectField::ui_element_change() { ComboAction* ca = nullptr; if (!dragging_double) ca = new ComboAction(); make_key_from_change(ca); - if (!dragging_double) Olive::UndoStack.push(ca); + if (!dragging_double) olive::UndoStack.push(ca); emit changed(); } diff --git a/project/effectloaders.cpp b/project/effectloaders.cpp index eaa93fc5b..e2da64487 100644 --- a/project/effectloaders.cpp +++ b/project/effectloaders.cpp @@ -39,7 +39,7 @@ typedef void (*f0rGetPluginInfo)(f0r_plugin_info_t* info); #endif void load_internal_effects() { - if (!Olive::CurrentRuntimeConfig.shaders_are_enabled) qWarning() << "Shaders are disabled, some effects may be nonfunctional"; + if (!olive::CurrentRuntimeConfig.shaders_are_enabled) qWarning() << "Shaders are disabled, some effects may be nonfunctional"; EffectMeta em; diff --git a/project/effectrow.cpp b/project/effectrow.cpp index bef7fd363..9ad98d67f 100644 --- a/project/effectrow.cpp +++ b/project/effectrow.cpp @@ -91,7 +91,7 @@ void EffectRow::set_keyframe_enabled(bool enabled) { ComboAction* ca = new ComboAction(); ca->append(new SetKeyframing(this, true)); set_keyframe_now(ca); - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); } else { if (QMessageBox::question(panel_effect_controls, tr("Disable Keyframes"), @@ -106,7 +106,7 @@ void EffectRow::set_keyframe_enabled(bool enabled) { } } ca->append(new SetKeyframing(this, false)); - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); panel_effect_controls->update_keyframes(); } else { setKeyframing(true); @@ -121,7 +121,7 @@ void EffectRow::goto_previous_key() { EffectField* f = field(i); for (int j=0;jkeyframes.size();j++) { long comp = f->keyframes.at(j).time - c->clip_in + c->timeline_in; - if (comp < Olive::ActiveSequence->playhead) { + if (comp < olive::ActiveSequence->playhead) { key = qMax(comp, key); } } @@ -137,7 +137,7 @@ void EffectRow::toggle_key() { EffectField* f = field(j); for (int i=0;ikeyframes.size();i++) { long comp = c->timeline_in - c->clip_in + f->keyframes.at(i).time; - if (comp == Olive::ActiveSequence->playhead) { + if (comp == olive::ActiveSequence->playhead) { key_fields.append(f); key_field_index.append(i); } @@ -153,7 +153,7 @@ void EffectRow::toggle_key() { ca->append(new KeyframeDelete(key_fields.at(i), key_field_index.at(i))); } } - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); update_ui(false); } @@ -164,7 +164,7 @@ void EffectRow::goto_next_key() { EffectField* f = field(i); for (int j=0;jkeyframes.size();j++) { long comp = f->keyframes.at(j).time - c->clip_in + c->timeline_in; - if (comp > Olive::ActiveSequence->playhead) { + if (comp > olive::ActiveSequence->playhead) { key = qMin(comp, key); } } @@ -194,7 +194,7 @@ void EffectRow::add_widget(QWidget* w) { } void EffectRow::set_keyframe_now(ComboAction* ca) { - long time = Olive::ActiveSequence->playhead-parent_effect->parent_clip->timeline_in+parent_effect->parent_clip->clip_in; + long time = olive::ActiveSequence->playhead-parent_effect->parent_clip->timeline_in+parent_effect->parent_clip->clip_in; if (!just_made_unsafe_keyframe) { EffectKeyframe key; diff --git a/project/keyframe.cpp b/project/keyframe.cpp index 08e6ba162..5811dc90c 100644 --- a/project/keyframe.cpp +++ b/project/keyframe.cpp @@ -58,7 +58,7 @@ void delete_keyframes(QVector& selected_key_fields, QVector for (int i=0;iappend(new KeyframeDelete(fields.at(i), key_indices.at(i))); } - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); selected_keys.clear(); selected_key_fields.clear(); update_ui(false); diff --git a/project/marker.cpp b/project/marker.cpp index 587f75acb..e6a4d3927 100644 --- a/project/marker.cpp +++ b/project/marker.cpp @@ -53,13 +53,13 @@ void set_marker_internal(Sequence* seq, const QVector& clips) { // add_marker is used to determine whether we're adding a marker, depending on whether the user input a marker name // however if (config.set_name_with_marker) is true, we don't need a marker name so we just add - bool add_marker = !Olive::CurrentConfig.set_name_with_marker; + bool add_marker = !olive::CurrentConfig.set_name_with_marker; QString marker_name; // if (config.set_name_with_marker) is false (set above), ask for a marker name if (!add_marker) { - QInputDialog d(Olive::MainWindow); + QInputDialog d(olive::MainWindow); d.setWindowTitle(QCoreApplication::translate("Marker", "Set Marker")); d.setLabelText(clips.size() > 0 ? QCoreApplication::translate("Marker", "Set clip marker name:") @@ -110,7 +110,7 @@ void set_marker_internal(Sequence* seq, const QVector& clips) { // push action - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); // redraw UI for new markers update_ui(false); diff --git a/project/media.cpp b/project/media.cpp index 5dc2d7833..f0de8274f 100644 --- a/project/media.cpp +++ b/project/media.cpp @@ -264,7 +264,7 @@ bool Media::setData(int col, const QVariant &value) { if (col == 0) { QString n = value.toString(); if (!n.isEmpty() && get_name() != n) { - Olive::UndoStack.push(new MediaRename(this, value.toString())); + olive::UndoStack.push(new MediaRename(this, value.toString())); return true; } } @@ -305,7 +305,7 @@ QVariant Media::data(int column, int role) { if (root) return QCoreApplication::translate("Media", "Duration"); if (get_type() == MEDIA_TYPE_SEQUENCE) { Sequence* s = to_sequence(); - return frame_to_timecode(s->getEndFrame(), Olive::CurrentConfig.timecode_view, s->frame_rate); + return frame_to_timecode(s->getEndFrame(), olive::CurrentConfig.timecode_view, s->frame_rate); } if (get_type() == MEDIA_TYPE_FOOTAGE) { Footage* f = to_footage(); @@ -315,7 +315,7 @@ QVariant Media::data(int column, int role) { r = f->video_tracks.at(0).video_frame_rate * f->speed; long len = f->get_length_in_frames(r); - if (len > 0) return frame_to_timecode(len, Olive::CurrentConfig.timecode_view, r); + if (len > 0) return frame_to_timecode(len, olive::CurrentConfig.timecode_view, r); } break; case 2: diff --git a/project/sequence.cpp b/project/sequence.cpp index d8d1f4fa5..b2b489b55 100644 --- a/project/sequence.cpp +++ b/project/sequence.cpp @@ -131,4 +131,4 @@ void Sequence::getTrackLimits(int* video_tracks, int* audio_tracks) { } // static variable for the currently active sequence -Sequence* Olive::ActiveSequence = nullptr; +Sequence* olive::ActiveSequence = nullptr; diff --git a/project/sequence.h b/project/sequence.h index faa899bce..0adbe9dc3 100644 --- a/project/sequence.h +++ b/project/sequence.h @@ -61,7 +61,7 @@ struct Sequence { }; // static variable for the currently active sequence -namespace Olive { +namespace olive { extern Sequence* ActiveSequence; } diff --git a/project/sourcescommon.cpp b/project/sourcescommon.cpp index 176600906..995d78855 100644 --- a/project/sourcescommon.cpp +++ b/project/sourcescommon.cpp @@ -69,7 +69,7 @@ void SourcesCommon::create_seq_from_selected() { panel_timeline->add_clips_from_ghosts(ca, s); project_parent->create_sequence_internal(ca, s, true, nullptr); - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); } } @@ -82,7 +82,7 @@ void SourcesCommon::show_context_menu(QWidget* parent, const QModelIndexList& it QObject::connect(import_action, SIGNAL(triggered(bool)), project_parent, SLOT(import_dialog())); QMenu* new_menu = menu.addMenu(tr("New")); - Olive::MenuHelper.make_new_menu(new_menu); + olive::MenuHelper.make_new_menu(new_menu); QMenu* view_menu = menu.addMenu(tr("View")); @@ -247,7 +247,7 @@ void SourcesCommon::mouseDoubleClickEvent(QMouseEvent *, const QModelIndexList& panel_footage_viewer->setFocus(); break; case MEDIA_TYPE_SEQUENCE: - Olive::UndoStack.push(new ChangeSequenceAction(item->to_sequence())); + olive::UndoStack.push(new ChangeSequenceAction(item->to_sequence())); break; } } @@ -269,7 +269,7 @@ void SourcesCommon::dropEvent(QWidget* parent, QDropEvent *event, const QModelIn && drop_item.isValid() && m->get_type() == MEDIA_TYPE_FOOTAGE && !QFileInfo(paths.at(0)).isDir() - && Olive::CurrentConfig.drop_on_media_to_replace + && olive::CurrentConfig.drop_on_media_to_replace && QMessageBox::question( parent, tr("Replace Media"), @@ -326,7 +326,7 @@ void SourcesCommon::dropEvent(QWidget* parent, QDropEvent *event, const QModelIn MediaMove* mm = new MediaMove(); mm->to = m; mm->items = move_items; - Olive::UndoStack.push(mm); + olive::UndoStack.push(mm); } } } @@ -370,14 +370,14 @@ void SourcesCommon::rename_interval() { void SourcesCommon::item_renamed(Media* item) { if (editing_item == item) { MediaRename* mr = new MediaRename(item, "idk"); - Olive::UndoStack.push(mr); + olive::UndoStack.push(mr); editing_item = nullptr; } } void SourcesCommon::open_create_proxy_dialog() { // open the proxy dialog and send it a list of currently selected footage - ProxyDialog pd(Olive::MainWindow, cached_selected_footage); + ProxyDialog pd(olive::MainWindow, cached_selected_footage); pd.exec(); } @@ -389,7 +389,7 @@ void SourcesCommon::clear_proxies_from_selected() { if (f->proxy && !f->proxy_path.isEmpty()) { if (QFileInfo::exists(f->proxy_path)) { - if (QMessageBox::question(Olive::MainWindow, + if (QMessageBox::question(olive::MainWindow, tr("Delete proxy"), tr("Would you like to delete the proxy file \"%1\" as well?").arg(f->proxy_path), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { @@ -402,9 +402,9 @@ void SourcesCommon::clear_proxies_from_selected() { f->proxy_path.clear(); } - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { // close all clips so we can delete any proxies requested to be deleted - closeActiveClips(Olive::ActiveSequence); + closeActiveClips(olive::ActiveSequence); } // delete proxies requested to be deleted @@ -412,10 +412,10 @@ void SourcesCommon::clear_proxies_from_selected() { QFile::remove(delete_list.at(i)); } - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { // update viewer (will re-open active clips with original media) panel_sequence_viewer->viewer_widget->frame_update(); } - Olive::MainWindow->setWindowModified(true); + olive::MainWindow->setWindowModified(true); } diff --git a/project/transition.cpp b/project/transition.cpp index ec1536f8e..6c9cf6b15 100644 --- a/project/transition.cpp +++ b/project/transition.cpp @@ -95,7 +95,7 @@ Transition* get_transition_from_meta(Clip* c, Clip* s, const EffectMeta* em) { } } else { qCritical() << "Invalid transition data"; - QMessageBox::critical(Olive::MainWindow, + QMessageBox::critical(olive::MainWindow, QCoreApplication::translate("transition", "Invalid transition"), QCoreApplication::translate("transition", "No candidate for transition '%1'. This transition may be corrupt. Try reinstalling it or Olive.").arg(em->name) ); diff --git a/project/undo.cpp b/project/undo.cpp index bb72f281b..b87e248fa 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -46,7 +46,7 @@ #include "project/media.h" #include "debug.h" -QUndoStack Olive::UndoStack; +QUndoStack olive::UndoStack; ComboAction::ComboAction() {} @@ -209,7 +209,7 @@ void ChangeSequenceAction::doUndo() { } void ChangeSequenceAction::doRedo() { - old_sequence = Olive::ActiveSequence; + old_sequence = olive::ActiveSequence; set_sequence(new_sequence); } @@ -942,7 +942,7 @@ void EditSequenceCommand::update() { if (seq->clips.at(i) != nullptr) seq->clips.at(i)->refresh(); } - if (Olive::ActiveSequence == seq) { + if (olive::ActiveSequence == seq) { set_sequence(seq); } } @@ -982,7 +982,7 @@ void CloseAllClipsCommand::doUndo() { } void CloseAllClipsCommand::doRedo() { - closeActiveClips(Olive::ActiveSequence); + closeActiveClips(olive::ActiveSequence); } UpdateFootageTooltip::UpdateFootageTooltip(Media *i) { @@ -1230,7 +1230,7 @@ void OliveAction::undo() { doUndo(); if (set_window_modified) { - Olive::MainWindow->setWindowModified(old_window_modified); + olive::MainWindow->setWindowModified(old_window_modified); } } @@ -1240,10 +1240,10 @@ void OliveAction::redo() { if (set_window_modified) { // store current modified state - old_window_modified = Olive::MainWindow->isWindowModified(); + old_window_modified = olive::MainWindow->isWindowModified(); // set modified to true - Olive::MainWindow->setWindowModified(true); + olive::MainWindow->setWindowModified(true); } } diff --git a/project/undo.h b/project/undo.h index 0ae6d489c..1edf1b159 100644 --- a/project/undo.h +++ b/project/undo.h @@ -45,7 +45,7 @@ struct EffectMeta; #include #include -namespace Olive { +namespace olive { extern QUndoStack UndoStack; } diff --git a/ui/audiomonitor.cpp b/ui/audiomonitor.cpp index c1794e78a..ec27387e3 100644 --- a/ui/audiomonitor.cpp +++ b/ui/audiomonitor.cpp @@ -68,7 +68,7 @@ void AudioMonitor::resizeEvent(QResizeEvent *e) { } void AudioMonitor::paintEvent(QPaintEvent *) { - if (Olive::ActiveSequence != nullptr && values.size() > 0) { + if (olive::ActiveSequence != nullptr && values.size() > 0) { QPainter p(this); int channel_x = AUDIO_MONITOR_GAP; int channel_count = values.size(); diff --git a/ui/checkboxex.cpp b/ui/checkboxex.cpp index d98e4fecb..25d812253 100644 --- a/ui/checkboxex.cpp +++ b/ui/checkboxex.cpp @@ -28,5 +28,5 @@ CheckboxEx::CheckboxEx(QWidget* parent) : QCheckBox(parent) { void CheckboxEx::checkbox_command() { CheckboxCommand* c = new CheckboxCommand(this); - Olive::UndoStack.push(c); + olive::UndoStack.push(c); } diff --git a/ui/comboboxex.cpp b/ui/comboboxex.cpp index 9d689d916..254504eab 100644 --- a/ui/comboboxex.cpp +++ b/ui/comboboxex.cpp @@ -31,17 +31,17 @@ class ComboBoxExCommand : public QUndoCommand { public: ComboBoxExCommand(ComboBoxEx* obj, int old_index, int new_index) : - combobox(obj), old_val(old_index), new_val(new_index), done(true), old_project_changed(Olive::MainWindow->isWindowModified()) {} + combobox(obj), old_val(old_index), new_val(new_index), done(true), old_project_changed(olive::MainWindow->isWindowModified()) {} void undo() { combobox->setCurrentIndex(old_val); done = false; - Olive::MainWindow->setWindowModified(old_project_changed); + olive::MainWindow->setWindowModified(old_project_changed); } void redo() { if (!done) { combobox->setCurrentIndex(new_val); } - Olive::MainWindow->setWindowModified(true); + olive::MainWindow->setWindowModified(true); } private: ComboBoxEx* combobox; diff --git a/ui/cursors.cpp b/ui/cursors.cpp index 3eb0973a9..5dbf21655 100644 --- a/ui/cursors.cpp +++ b/ui/cursors.cpp @@ -25,8 +25,8 @@ #include -QCursor Olive::Cursor_LeftTrim; -QCursor Olive::Cursor_RightTrim; +QCursor olive::Cursor_LeftTrim; +QCursor olive::Cursor_RightTrim; QCursor load_cursor(const QString& file, int hotX, int hotY, const bool& right_aligned){ // load specified file into a pixmap @@ -43,7 +43,7 @@ QCursor load_cursor(const QString& file, int hotX, int hotY, const bool& right_a void init_custom_cursors(){ qInfo() << "Initializing custom cursors"; - Olive::Cursor_LeftTrim = load_cursor(":/cursors/left_side.png", 0, -1, false); - Olive::Cursor_RightTrim = load_cursor(":/cursors/right_side.png", 0, -1, true); + olive::Cursor_LeftTrim = load_cursor(":/cursors/left_side.png", 0, -1, false); + olive::Cursor_RightTrim = load_cursor(":/cursors/right_side.png", 0, -1, true); qInfo() << "Finished initializing custom cursors"; } diff --git a/ui/cursors.h b/ui/cursors.h index 3f9196fb6..737ba44f2 100644 --- a/ui/cursors.h +++ b/ui/cursors.h @@ -25,7 +25,7 @@ void init_custom_cursors(); -namespace Olive{ +namespace olive{ extern QCursor Cursor_LeftTrim; extern QCursor Cursor_RightTrim; } diff --git a/ui/focusfilter.cpp b/ui/focusfilter.cpp index 3fcb9f131..4dfed52a7 100644 --- a/ui/focusfilter.cpp +++ b/ui/focusfilter.cpp @@ -24,7 +24,7 @@ #include "project/sequence.h" #include "ui/timelineheader.h" -FocusFilter Olive::FocusFilter; +FocusFilter olive::FocusFilter; FocusFilter::FocusFilter() {} @@ -100,7 +100,7 @@ void FocusFilter::set_viewer_fullscreen() { } void FocusFilter::set_marker() { - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { QDockWidget* focused_panel = get_focused_panel(); if (focused_panel == panel_footage_viewer) { @@ -205,7 +205,7 @@ void FocusFilter::delete_function() { } else if (panel_graph_editor->view_is_focused()) { panel_graph_editor->delete_selected_keys(); } else { - panel_timeline->delete_selection(Olive::ActiveSequence->selections, false); + panel_timeline->delete_selection(olive::ActiveSequence->selections, false); } } @@ -251,7 +251,7 @@ void FocusFilter::zoom_out() { } void FocusFilter::cut() { - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { QDockWidget* focused_panel = get_focused_panel(); if (panel_effect_controls == focused_panel) { panel_effect_controls->copy(true); @@ -262,7 +262,7 @@ void FocusFilter::cut() { } void FocusFilter::copy() { - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { QDockWidget* focused_panel = get_focused_panel(); if (panel_effect_controls == focused_panel) { panel_effect_controls->copy(false); diff --git a/ui/focusfilter.h b/ui/focusfilter.h index 37df333bc..c907532c4 100644 --- a/ui/focusfilter.h +++ b/ui/focusfilter.h @@ -224,7 +224,7 @@ public slots: void zoom_out(); }; -namespace Olive { +namespace olive { extern FocusFilter FocusFilter; } diff --git a/ui/graphview.cpp b/ui/graphview.cpp index b42eb9bf2..bd87a8de3 100644 --- a/ui/graphview.cpp +++ b/ui/graphview.cpp @@ -701,7 +701,7 @@ void GraphView::mouseMoveEvent(QMouseEvent *event) { void GraphView::mouseReleaseEvent(QMouseEvent *) { if (click_add_proc) { - Olive::UndoStack.push(new KeyframeFieldSet(click_add_field, click_add_key)); + olive::UndoStack.push(new KeyframeFieldSet(click_add_field, click_add_key)); } else if (moved_keys && selected_keys.size() > 0) { ComboAction* ca = new ComboAction(); switch (current_handle) { @@ -723,7 +723,7 @@ void GraphView::mouseReleaseEvent(QMouseEvent *) { } break; } - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); } moved_keys = false; mousedown = false; @@ -812,7 +812,7 @@ void GraphView::set_selected_keyframe_type(int type) { EffectKeyframe& key = row->field(selected_keys_fields.at(i))->keyframes[selected_keys.at(i)]; ca->append(new SetInt(&key.type, type)); } - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); update_ui(false); } } diff --git a/ui/keyframeview.cpp b/ui/keyframeview.cpp index 93c3c50f3..eb448b9e2 100644 --- a/ui/keyframeview.cpp +++ b/ui/keyframeview.cpp @@ -90,7 +90,7 @@ void KeyframeView::menu_set_key_type(QAction* a) { EffectField* f = selected_fields.at(i); ca->append(new SetInt(&f->keyframes[selected_keyframes.at(i)].type, a->data().toInt())); } - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); update_ui(false); } } @@ -106,13 +106,13 @@ void KeyframeView::paintEvent(QPaintEvent*) { visible_out = 0; for (int j=0;jselected_clips.size();j++) { - Clip* c = Olive::ActiveSequence->clips.at(panel_effect_controls->selected_clips.at(j)); + Clip* c = olive::ActiveSequence->clips.at(panel_effect_controls->selected_clips.at(j)); visible_in = qMin(visible_in, c->timeline_in); visible_out = qMax(visible_out, c->timeline_out); } for (int j=0;jselected_clips.size();j++) { - Clip* c = Olive::ActiveSequence->clips.at(panel_effect_controls->selected_clips.at(j)); + Clip* c = olive::ActiveSequence->clips.at(panel_effect_controls->selected_clips.at(j)); for (int i=0;ieffects.size();i++) { Effect* e = c->effects.at(i); if (e->container->is_expanded()) { @@ -168,7 +168,7 @@ void KeyframeView::paintEvent(QPaintEvent*) { panel_effect_controls->horizontalScrollBar->setMaximum(qMax(max_width - width(), 0)); header->set_visible_in(visible_in); - int playhead_x = getScreenPointFromFrame(panel_effect_controls->zoom, Olive::ActiveSequence->playhead-visible_in) - x_scroll; + int playhead_x = getScreenPointFromFrame(panel_effect_controls->zoom, olive::ActiveSequence->playhead-visible_in) - x_scroll; if (dragging && panel_timeline->snapped) { p.setPen(Qt::white); } else { @@ -376,7 +376,7 @@ void KeyframeView::mouseMoveEvent(QMouseEvent* event) { Clip* c = field->parent_row->parent_effect->parent_clip; long key_time = old_key_vals.at(i) + frame_diff - c->clip_in + c->timeline_in; long key_eval = key_time; - if (panel_timeline->snap_to_point(Olive::ActiveSequence->playhead, &key_eval)) { + if (panel_timeline->snap_to_point(olive::ActiveSequence->playhead, &key_eval)) { frame_diff += (key_eval - key_time); break; } @@ -425,7 +425,7 @@ void KeyframeView::mouseReleaseEvent(QMouseEvent*) { selected_fields.at(i)->keyframes.at(selected_keyframes.at(i)).time )); } - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); } select_rect = false; diff --git a/ui/labelslider.cpp b/ui/labelslider.cpp index 8d65c1bf2..eeba9c34b 100644 --- a/ui/labelslider.cpp +++ b/ui/labelslider.cpp @@ -88,7 +88,7 @@ QString LabelSlider::valueToString() { } else { switch (display_type) { case LABELSLIDER_FRAMENUMBER: - return frame_to_timecode(long(v), Olive::CurrentConfig.timecode_view, frame_rate); + return frame_to_timecode(long(v), olive::CurrentConfig.timecode_view, frame_rate); case LABELSLIDER_PERCENT: return QString::number((v*100), 'f', decimal_places).append("%"); case LABELSLIDER_DECIBEL: @@ -274,7 +274,7 @@ void LabelSlider::mouseReleaseEvent(QMouseEvent*) { if (s.isEmpty()) return; // parse string timecode to a frame number - d = timecode_to_frame(s, Olive::CurrentConfig.timecode_view, frame_rate); + d = timecode_to_frame(s, olive::CurrentConfig.timecode_view, frame_rate); } else { diff --git a/ui/menuhelper.cpp b/ui/menuhelper.cpp index 9a470fb66..f7f78ebe4 100644 --- a/ui/menuhelper.cpp +++ b/ui/menuhelper.cpp @@ -33,22 +33,22 @@ #include #include -MenuHelper Olive::MenuHelper; +MenuHelper olive::MenuHelper; void MenuHelper::make_new_menu(QMenu *parent) { - parent->addAction(tr("&Project"), Olive::Global.data(), SLOT(new_project()), QKeySequence("Ctrl+N"))->setProperty("id", "newproj"); + parent->addAction(tr("&Project"), olive::Global.get(), SLOT(new_project()), QKeySequence("Ctrl+N"))->setProperty("id", "newproj"); parent->addSeparator(); parent->addAction(tr("&Sequence"), panel_project, SLOT(new_sequence()), QKeySequence("Ctrl+Shift+N"))->setProperty("id", "newseq"); parent->addAction(tr("&Folder"), panel_project, SLOT(new_folder()))->setProperty("id", "newfolder"); } void MenuHelper::make_inout_menu(QMenu *parent) { - parent->addAction(tr("Set In Point"), &Olive::FocusFilter, SLOT(set_in_point()), QKeySequence("I"))->setProperty("id", "setinpoint"); - parent->addAction(tr("Set Out Point"), &Olive::FocusFilter, SLOT(set_out_point()), QKeySequence("O"))->setProperty("id", "setoutpoint"); + parent->addAction(tr("Set In Point"), &olive::FocusFilter, SLOT(set_in_point()), QKeySequence("I"))->setProperty("id", "setinpoint"); + parent->addAction(tr("Set Out Point"), &olive::FocusFilter, SLOT(set_out_point()), QKeySequence("O"))->setProperty("id", "setoutpoint"); parent->addSeparator(); - parent->addAction(tr("Reset In Point"), &Olive::FocusFilter, SLOT(clear_in()))->setProperty("id", "resetin"); - parent->addAction(tr("Reset Out Point"), &Olive::FocusFilter, SLOT(clear_out()))->setProperty("id", "resetout"); - parent->addAction(tr("Clear In/Out Point"), &Olive::FocusFilter, SLOT(clear_inout()), QKeySequence("G"))->setProperty("id", "clearinout"); + parent->addAction(tr("Reset In Point"), &olive::FocusFilter, SLOT(clear_in()))->setProperty("id", "resetin"); + parent->addAction(tr("Reset Out Point"), &olive::FocusFilter, SLOT(clear_out()))->setProperty("id", "resetout"); + parent->addAction(tr("Clear In/Out Point"), &olive::FocusFilter, SLOT(clear_inout()), QKeySequence("G"))->setProperty("id", "clearinout"); } void MenuHelper::make_clip_functions_menu(QMenu *parent) { @@ -59,12 +59,12 @@ void MenuHelper::make_clip_functions_menu(QMenu *parent) { } void MenuHelper::make_edit_functions_menu(QMenu *parent) { - parent->addAction(tr("Cu&t"), &Olive::FocusFilter, SLOT(cut()), QKeySequence("Ctrl+X"))->setProperty("id", "cut"); - parent->addAction(tr("Cop&y"), &Olive::FocusFilter, SLOT(copy()), QKeySequence("Ctrl+C"))->setProperty("id", "copy"); - parent->addAction(tr("&Paste"), Olive::Global.data(), SLOT(paste()), QKeySequence("Ctrl+V"))->setProperty("id", "paste"); - parent->addAction(tr("Paste Insert"), Olive::Global.data(), SLOT(paste_insert()), QKeySequence("Ctrl+Shift+V"))->setProperty("id", "pasteinsert"); - parent->addAction(tr("Duplicate"), &Olive::FocusFilter, SLOT(duplicate()), QKeySequence("Ctrl+D"))->setProperty("id", "duplicate"); - parent->addAction(tr("Delete"), &Olive::FocusFilter, SLOT(delete_function()), QKeySequence("Del"))->setProperty("id", "delete"); + parent->addAction(tr("Cu&t"), &olive::FocusFilter, SLOT(cut()), QKeySequence("Ctrl+X"))->setProperty("id", "cut"); + parent->addAction(tr("Cop&y"), &olive::FocusFilter, SLOT(copy()), QKeySequence("Ctrl+C"))->setProperty("id", "copy"); + parent->addAction(tr("&Paste"), olive::Global.get(), SLOT(paste()), QKeySequence("Ctrl+V"))->setProperty("id", "paste"); + parent->addAction(tr("Paste Insert"), olive::Global.get(), SLOT(paste_insert()), QKeySequence("Ctrl+Shift+V"))->setProperty("id", "pasteinsert"); + parent->addAction(tr("Duplicate"), &olive::FocusFilter, SLOT(duplicate()), QKeySequence("Ctrl+D"))->setProperty("id", "duplicate"); + parent->addAction(tr("Delete"), &olive::FocusFilter, SLOT(delete_function()), QKeySequence("Del"))->setProperty("id", "delete"); parent->addAction(tr("Ripple Delete"), panel_timeline, SLOT(ripple_delete()), QKeySequence("Shift+Del"))->setProperty("id", "rippledelete"); parent->addAction(tr("Split"), panel_timeline, SLOT(split_at_playhead()), QKeySequence("Ctrl+K"))->setProperty("id", "split"); } @@ -100,23 +100,23 @@ void MenuHelper::set_titlesafe_from_menu() { if (qIsNaN(tsa)) { // disable title safe area - Olive::CurrentConfig.show_title_safe_area = false; + olive::CurrentConfig.show_title_safe_area = false; } else { // using title safe area - Olive::CurrentConfig.show_title_safe_area = true; + olive::CurrentConfig.show_title_safe_area = true; // are we using the default area aspect ratio, or a specific one if (qIsNull(tsa)) { // default title safe area - Olive::CurrentConfig.use_custom_title_safe_ratio = false; + olive::CurrentConfig.use_custom_title_safe_ratio = false; } else { // using a specific aspect ratio - Olive::CurrentConfig.use_custom_title_safe_ratio = true; + olive::CurrentConfig.use_custom_title_safe_ratio = true; if (tsa < 0.0) { @@ -127,22 +127,22 @@ void MenuHelper::set_titlesafe_from_menu() { do { if (invalid) { - QMessageBox::critical(Olive::MainWindow, tr("Invalid aspect ratio"), tr("The aspect ratio '%1' is invalid. Please try again.").arg(input)); + QMessageBox::critical(olive::MainWindow, tr("Invalid aspect ratio"), tr("The aspect ratio '%1' is invalid. Please try again.").arg(input)); } - input = QInputDialog::getText(Olive::MainWindow, tr("Enter custom aspect ratio"), tr("Enter the aspect ratio to use for the title/action safe area (e.g. 16:9):")); + input = QInputDialog::getText(olive::MainWindow, tr("Enter custom aspect ratio"), tr("Enter the aspect ratio to use for the title/action safe area (e.g. 16:9):")); invalid = !arTest.exactMatch(input) && !input.isEmpty(); } while (invalid); if (!input.isEmpty()) { QStringList inputList = input.split(':'); - Olive::CurrentConfig.custom_title_safe_ratio = inputList.at(0).toDouble()/inputList.at(1).toDouble(); + olive::CurrentConfig.custom_title_safe_ratio = inputList.at(0).toDouble()/inputList.at(1).toDouble(); } } else { // specified tsa is a specific custom aspect ratio - Olive::CurrentConfig.custom_title_safe_ratio = tsa; + olive::CurrentConfig.custom_title_safe_ratio = tsa; } } @@ -154,7 +154,7 @@ void MenuHelper::set_titlesafe_from_menu() { void MenuHelper::set_autoscroll() { QAction* action = static_cast(sender()); - Olive::CurrentConfig.autoscroll = action->data().toInt(); + olive::CurrentConfig.autoscroll = action->data().toInt(); } void MenuHelper::menu_click_button() { @@ -163,11 +163,11 @@ void MenuHelper::menu_click_button() { void MenuHelper::set_timecode_view() { QAction* action = static_cast(sender()); - Olive::CurrentConfig.timecode_view = action->data().toInt(); + olive::CurrentConfig.timecode_view = action->data().toInt(); update_ui(false); } void MenuHelper::open_recent_from_menu() { int index = static_cast(sender())->data().toInt(); - Olive::Global.data()->open_recent(index); + olive::Global.get()->open_recent(index); } diff --git a/ui/menuhelper.h b/ui/menuhelper.h index 719746b57..eda2a6fbb 100644 --- a/ui/menuhelper.h +++ b/ui/menuhelper.h @@ -176,7 +176,7 @@ private slots: }; -namespace Olive { +namespace olive { /** * @brief A global MenuHelper object to assist menu creation throughout Olive. */ diff --git a/ui/renderfunctions.cpp b/ui/renderfunctions.cpp index 725b56708..a8a0adaf8 100644 --- a/ui/renderfunctions.cpp +++ b/ui/renderfunctions.cpp @@ -112,7 +112,7 @@ void process_effect(Clip* c, if (e->enable_coords) { e->process_coords(timecode, coords, data); } - bool can_process_shaders = (e->enable_shader && Olive::CurrentRuntimeConfig.shaders_are_enabled); + bool can_process_shaders = (e->enable_shader && olive::CurrentRuntimeConfig.shaders_are_enabled); if (can_process_shaders || e->enable_superimpose) { e->startEffect(); if (can_process_shaders && e->is_glsl_linked()) { @@ -506,7 +506,7 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { // copy front buffer to back buffer (only if we're using blending modes - which we usually will be) - if (!Olive::CurrentRuntimeConfig.disable_blending) { + if (!olive::CurrentRuntimeConfig.disable_blending) { if (params.nests.size() > 0) { draw_clip(params.ctx, params.nests.last()->fbo[2]->handle(), params.nests.last()->fbo[0]->texture(), true); } else { @@ -523,7 +523,7 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { // bind front buffer as draw buffer params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, final_fbo); - if (Olive::CurrentRuntimeConfig.disable_blending) { + if (olive::CurrentRuntimeConfig.disable_blending) { // some GPUs don't like the blending shader, so we provide a pure GL fallback here params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, backend_tex_1); diff --git a/ui/scrollarea.cpp b/ui/scrollarea.cpp index 3e41fcba1..24d731545 100644 --- a/ui/scrollarea.cpp +++ b/ui/scrollarea.cpp @@ -30,7 +30,7 @@ ScrollArea::ScrollArea(QWidget* parent) : QScrollArea(parent) {} void ScrollArea::wheelEvent(QWheelEvent *e) { - if (Olive::CurrentConfig.scroll_zooms) { + if (olive::CurrentConfig.scroll_zooms) { e->ignore(); if (e->angleDelta().y() > 0) { diff --git a/ui/timelineheader.cpp b/ui/timelineheader.cpp index a6a9c9639..24ec538f5 100644 --- a/ui/timelineheader.cpp +++ b/ui/timelineheader.cpp @@ -115,7 +115,7 @@ void TimelineHeader::set_in_point(long new_in) { new_out = viewer->seq->getEndFrame(); } - Olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq, true, new_in, new_out)); + olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq, true, new_in, new_out)); update_parents(); } @@ -127,7 +127,7 @@ void TimelineHeader::set_out_point(long new_out) { new_in = 0; } - Olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq, true, new_in, new_out)); + olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq, true, new_in, new_out)); update_parents(); } @@ -280,7 +280,7 @@ void TimelineHeader::mouseReleaseEvent(QMouseEvent*) { if (viewer->seq != nullptr) { dragging = false; if (resizing_workarea) { - Olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq, true, temp_workarea_in, temp_workarea_out)); + olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq, true, temp_workarea_in, temp_workarea_out)); } else if (dragging_markers && selected_markers.size() > 0) { bool moved = false; ComboAction* ca = new ComboAction(); @@ -292,7 +292,7 @@ void TimelineHeader::mouseReleaseEvent(QMouseEvent*) { } } if (moved) { - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); } else { delete ca; } @@ -330,7 +330,7 @@ void TimelineHeader::delete_markers() { for (int i=0;imarkers.append(selected_markers.at(i)); } - Olive::UndoStack.push(dma); + olive::UndoStack.push(dma); update_parents(); } } @@ -372,14 +372,14 @@ void TimelineHeader::paintEvent(QPaintEvent*) { // draw text bool draw_text = false; if (text_enabled && lineX-textWidth > lastTextBoundary) { - timecode = frame_to_timecode(frame + in_visible, Olive::CurrentConfig.timecode_view, viewer->seq->frame_rate); + timecode = frame_to_timecode(frame + in_visible, olive::CurrentConfig.timecode_view, viewer->seq->frame_rate); fullTextWidth = fm.width(timecode); textWidth = fullTextWidth>>1; text_x = lineX; // centers the text to that point on the timeline, LEFT aligns it if not - if (Olive::CurrentConfig.center_timeline_timecodes) { + if (olive::CurrentConfig.center_timeline_timecodes) { text_x -= textWidth; } else { text_x += TEXT_PADDING_FROM_LINE; @@ -399,7 +399,7 @@ void TimelineHeader::paintEvent(QPaintEvent*) { // draw line markers p.setPen(Qt::gray); - p.drawLine(lineX, (!Olive::CurrentConfig.center_timeline_timecodes && draw_text) ? 0 : yoff, lineX, height()); + p.drawLine(lineX, (!olive::CurrentConfig.center_timeline_timecodes && draw_text) ? 0 : yoff, lineX, height()); // draw sub-line markers for (int j=1;jsetCheckable(true); - center_timecodes->setChecked(Olive::CurrentConfig.center_timeline_timecodes); - center_timecodes->setData(reinterpret_cast(&Olive::CurrentConfig.center_timeline_timecodes)); + center_timecodes->setChecked(olive::CurrentConfig.center_timeline_timecodes); + center_timecodes->setData(reinterpret_cast(&olive::CurrentConfig.center_timeline_timecodes)); menu.exec(mapToGlobal(pos)); } diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index 6e3c8cfb7..e01a41fee 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -82,7 +82,7 @@ TimelineWidget::TimelineWidget(QWidget *parent) : QWidget(parent) { } void TimelineWidget::show_context_menu(const QPoint& pos) { - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { // hack because sometimes right clicking doesn't trigger mouse release event panel_timeline->rect_select_init = false; panel_timeline->rect_select_proc = false; @@ -93,16 +93,16 @@ void TimelineWidget::show_context_menu(const QPoint& pos) { QAction* undoAction = menu.addAction(tr("&Undo")); QAction* redoAction = menu.addAction(tr("&Redo")); - connect(undoAction, SIGNAL(triggered(bool)), Olive::Global.data(), SLOT(undo())); - connect(redoAction, SIGNAL(triggered(bool)), Olive::Global.data(), SLOT(redo())); - undoAction->setEnabled(Olive::UndoStack.canUndo()); - redoAction->setEnabled(Olive::UndoStack.canRedo()); + connect(undoAction, SIGNAL(triggered(bool)), olive::Global.get(), SLOT(undo())); + connect(redoAction, SIGNAL(triggered(bool)), olive::Global.get(), SLOT(redo())); + undoAction->setEnabled(olive::UndoStack.canUndo()); + redoAction->setEnabled(olive::UndoStack.canRedo()); menu.addSeparator(); // collect all the selected clips QVector selected_clips; - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { selected_clips.append(c); } @@ -110,11 +110,11 @@ void TimelineWidget::show_context_menu(const QPoint& pos) { if (!selected_clips.isEmpty()) { // clips are selected - menu.addAction(tr("C&ut"), &Olive::FocusFilter, SLOT(cut())); - menu.addAction(tr("Cop&y"), &Olive::FocusFilter, SLOT(copy())); + menu.addAction(tr("C&ut"), &olive::FocusFilter, SLOT(cut())); + menu.addAction(tr("Cop&y"), &olive::FocusFilter, SLOT(copy())); } - menu.addAction(tr("&Paste"), Olive::Global.data(), SLOT(paste())); + menu.addAction(tr("&Paste"), olive::Global.get(), SLOT(paste())); if (selected_clips.isEmpty()) { // no clips are selected @@ -134,14 +134,14 @@ void TimelineWidget::show_context_menu(const QPoint& pos) { if (!selected_clips.isEmpty()) { menu.addSeparator(); - menu.addAction(tr("&Speed/Duration"), Olive::Global.data(), SLOT(open_speed_dialog())); + menu.addAction(tr("&Speed/Duration"), olive::Global.get(), SLOT(open_speed_dialog())); QAction* autoscaleAction = menu.addAction(tr("Auto-s&cale"), this, SLOT(toggle_autoscale())); autoscaleAction->setCheckable(true); // set autoscale to the first selected clip autoscaleAction->setChecked(selected_clips.at(0)->autoscale); - Olive::MenuHelper.make_clip_functions_menu(&menu); + olive::MenuHelper.make_clip_functions_menu(&menu); // stabilizer option /*int video_clip_count = 0; @@ -185,30 +185,30 @@ void TimelineWidget::show_context_menu(const QPoint& pos) { void TimelineWidget::toggle_autoscale() { SetAutoscaleAction* action = new SetAutoscaleAction(); - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { action->clips.append(c); } } if (action->clips.size() > 0) { - Olive::UndoStack.push(action); + olive::UndoStack.push(action); } else { delete action; } } void TimelineWidget::tooltip_timer_timeout() { - if (Olive::ActiveSequence != nullptr) { - if (tooltip_clip < Olive::ActiveSequence->clips.size()) { - Clip* c = Olive::ActiveSequence->clips.at(tooltip_clip); + if (olive::ActiveSequence != nullptr) { + if (tooltip_clip < olive::ActiveSequence->clips.size()) { + Clip* c = olive::ActiveSequence->clips.at(tooltip_clip); if (c != nullptr) { QToolTip::showText(QCursor::pos(), tr("%1\nStart: %2\nEnd: %3\nDuration: %4").arg( c->name, - frame_to_timecode(c->timeline_in, Olive::CurrentConfig.timecode_view, Olive::ActiveSequence->frame_rate), - frame_to_timecode(c->timeline_out, Olive::CurrentConfig.timecode_view, Olive::ActiveSequence->frame_rate), - frame_to_timecode(c->getLength(), Olive::CurrentConfig.timecode_view, Olive::ActiveSequence->frame_rate) + frame_to_timecode(c->timeline_in, olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate), + frame_to_timecode(c->timeline_out, olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate), + frame_to_timecode(c->getLength(), olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate) )); } } @@ -218,8 +218,8 @@ void TimelineWidget::tooltip_timer_timeout() { void TimelineWidget::rename_clip() { QVector selected_clips; - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { selected_clips.append(c); } @@ -235,7 +235,7 @@ void TimelineWidget::rename_clip() { RenameClipCommand* rcc = new RenameClipCommand(); rcc->new_name = s; rcc->clips = selected_clips; - Olive::UndoStack.push(rcc); + olive::UndoStack.push(rcc); update_ui(true); } } @@ -249,7 +249,7 @@ void TimelineWidget::open_sequence_properties() { } panel_project->get_all_media_from_table(all_top_level_items, sequence_items, MEDIA_TYPE_SEQUENCE); // find all sequences in project for (int i=0;ito_sequence() == Olive::ActiveSequence) { + if (sequence_items.at(i)->to_sequence() == olive::ActiveSequence) { NewSequenceDialog nsd(this, sequence_items.at(i)); nsd.exec(); return; @@ -279,13 +279,13 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { if (event->source() == panel_footage_viewer->viewer_widget) { Sequence* proposed_seq = panel_footage_viewer->seq; - if (proposed_seq != Olive::ActiveSequence) { // don't allow nesting the same sequence + if (proposed_seq != olive::ActiveSequence) { // don't allow nesting the same sequence media_list.append(panel_footage_viewer->media); import_init = true; } } - if (Olive::CurrentConfig.enable_drag_files_to_timeline && event->mimeData()->hasUrls()) { + if (olive::CurrentConfig.enable_drag_files_to_timeline && event->mimeData()->hasUrls()) { QList urls = event->mimeData()->urls(); if (!urls.isEmpty()) { QStringList file_list; @@ -309,7 +309,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { } if (media_list.isEmpty()) { - Olive::UndoStack.undo(); + olive::UndoStack.undo(); } else { import_init = true; panel_timeline->importing_files = true; @@ -321,7 +321,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { event->acceptProposedAction(); long entry_point; - Sequence* seq = Olive::ActiveSequence; + Sequence* seq = olive::ActiveSequence; if (seq == nullptr) { // if no sequence, we're going to create a new one using the clips as a reference @@ -345,7 +345,7 @@ void TimelineWidget::dragMoveEvent(QDragMoveEvent *event) { if (panel_timeline->importing) { event->acceptProposedAction(); - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { QPoint pos = event->pos(); update_ghosts(pos, event->keyboardModifiers() & Qt::ShiftModifier); panel_timeline->move_insert = ((event->keyboardModifiers() & Qt::ControlModifier) && (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->importing)); @@ -379,7 +379,7 @@ void TimelineWidget::wheelEvent(QWheelEvent *event) { int scroll_amount = alt ? (event->angleDelta().x()) : (event->angleDelta().y()); bool in = (scroll_amount > 0); - if (Olive::CurrentConfig.scroll_zooms != shift) { + if (olive::CurrentConfig.scroll_zooms != shift) { // if config.scroll_zooms is enabled or shift is held, zoom instead of scrolling if (in) { @@ -405,7 +405,7 @@ void TimelineWidget::dragLeaveEvent(QDragLeaveEvent* event) { event->accept(); if (panel_timeline->importing) { if (panel_timeline->importing_files) { - Olive::UndoStack.undo(); + olive::UndoStack.undo(); } panel_timeline->importing_files = false; panel_timeline->ghosts.clear(); @@ -460,8 +460,8 @@ void insert_clips(ComboAction* ca) { panel_timeline->split_cache.clear(); - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { // don't split any clips that are moving bool found = false; @@ -488,13 +488,13 @@ void insert_clips(ComboAction* ca) { long ripple_length = (latest_new_point - earliest_new_point); - ripple_clips(ca, Olive::ActiveSequence, earliest_new_point, ripple_length, ignore_clips); + ripple_clips(ca, olive::ActiveSequence, earliest_new_point, ripple_length, ignore_clips); if (ripple_old_point) { // works for moving later clips earlier but not earlier to later long second_ripple_length = (earliest_old_point - latest_old_point); - ripple_clips(ca, Olive::ActiveSequence, latest_old_point, second_ripple_length, ignore_clips); + ripple_clips(ca, olive::ActiveSequence, latest_old_point, second_ripple_length, ignore_clips); if (earliest_old_point < earliest_new_point) { for (int i=0;ighosts.size();i++) { @@ -502,8 +502,8 @@ void insert_clips(ComboAction* ca) { g.in += second_ripple_length; g.out += second_ripple_length; } - for (int i=0;iselections.size();i++) { - Selection& s = Olive::ActiveSequence->selections[i]; + for (int i=0;iselections.size();i++) { + Selection& s = olive::ActiveSequence->selections[i]; s.in += second_ripple_length; s.out += second_ripple_length; } @@ -517,7 +517,7 @@ void TimelineWidget::dropEvent(QDropEvent* event) { ComboAction* ca = new ComboAction(); - Sequence* s = Olive::ActiveSequence; + Sequence* s = olive::ActiveSequence; // if we're dropping into nothing, create a new sequences based on the clip being dragged if (s == nullptr) { @@ -532,7 +532,7 @@ void TimelineWidget::dropEvent(QDropEvent* event) { panel_timeline->add_clips_from_ghosts(ca, s); - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); setFocus(); @@ -541,23 +541,23 @@ void TimelineWidget::dropEvent(QDropEvent* event) { } void TimelineWidget::mouseDoubleClickEvent(QMouseEvent *event) { - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { if (panel_timeline->tool == TIMELINE_TOOL_EDIT) { int clip_index = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); if (clip_index >= 0) { - Clip* clip = Olive::ActiveSequence->clips.at(clip_index); - if (!(event->modifiers() & Qt::ShiftModifier)) Olive::ActiveSequence->selections.clear(); + Clip* clip = olive::ActiveSequence->clips.at(clip_index); + if (!(event->modifiers() & Qt::ShiftModifier)) olive::ActiveSequence->selections.clear(); Selection s; s.in = clip->timeline_in; s.out = clip->timeline_out; s.track = clip->track; - Olive::ActiveSequence->selections.append(s); + olive::ActiveSequence->selections.append(s); update_ui(false); } } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { int clip_index = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); if (clip_index >= 0) { - Clip* c = Olive::ActiveSequence->clips.at(clip_index); + Clip* c = olive::ActiveSequence->clips.at(clip_index); if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) { set_sequence(c->media->to_sequence()); } @@ -571,7 +571,7 @@ bool isLiveEditing() { } void TimelineWidget::mousePressEvent(QMouseEvent *event) { - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { int tool = panel_timeline->tool; if (event->button() == Qt::MiddleButton) { tool = TIMELINE_TOOL_HAND; @@ -597,7 +597,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { bool alt = (event->modifiers() & Qt::AltModifier); if (shift) { - panel_timeline->selection_offset = Olive::ActiveSequence->selections.size(); + panel_timeline->selection_offset = olive::ActiveSequence->selections.size(); } else { panel_timeline->selection_offset = 0; } @@ -644,7 +644,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { panel_timeline->moving_init = true; } else { if (clip_index >= 0) { - Clip* clip = Olive::ActiveSequence->clips.at(clip_index); + Clip* clip = olive::ActiveSequence->clips.at(clip_index); if (clip != nullptr) { if (is_clip_selected(clip, true)) { if (shift) { @@ -652,7 +652,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { if (!alt) { for (int i=0;ilinked.size();i++) { - Clip* link = Olive::ActiveSequence->clips.at(clip->linked.at(i)); + Clip* link = olive::ActiveSequence->clips.at(clip->linked.at(i)); panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track); } } @@ -660,7 +660,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track); for (int i=0;ilinked.size();i++) { - Clip* link = Olive::ActiveSequence->clips.at(clip->linked.at(i)); + Clip* link = olive::ActiveSequence->clips.at(clip->linked.at(i)); panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track); } @@ -676,12 +676,12 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { s.out = clip->timeline_out; if (clip->get_closing_transition()->secondary_clip != nullptr) s.out += clip->get_closing_transition()->get_true_length(); } - Olive::ActiveSequence->selections.append(s); + olive::ActiveSequence->selections.append(s); } } else { // if "shift" is not down if (!shift) { - Olive::ActiveSequence->selections.clear(); + olive::ActiveSequence->selections.clear(); } Selection s; @@ -702,22 +702,22 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { } s.track = clip->track; - Olive::ActiveSequence->selections.append(s); + olive::ActiveSequence->selections.append(s); - if (Olive::CurrentConfig.select_also_seeks) { + if (olive::CurrentConfig.select_also_seeks) { panel_sequence_viewer->seek(clip->timeline_in); } // if alt is not down, select links if (!alt && panel_timeline->transition_select == TA_NO_TRANSITION) { for (int i=0;ilinked.size();i++) { - Clip* link = Olive::ActiveSequence->clips.at(clip->linked.at(i)); + Clip* link = olive::ActiveSequence->clips.at(clip->linked.at(i)); if (!is_clip_selected(link, true)) { Selection ss; ss.in = link->timeline_in; ss.out = link->timeline_out; ss.track = link->track; - Olive::ActiveSequence->selections.append(ss); + olive::ActiveSequence->selections.append(ss); } } } @@ -728,7 +728,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { } else { // if "shift" is not down if (!shift) { - Olive::ActiveSequence->selections.clear(); + olive::ActiveSequence->selections.clear(); } panel_timeline->rect_select_init = true; @@ -743,7 +743,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { panel_timeline->drag_y_start = pos.y(); break; case TIMELINE_TOOL_EDIT: - if (Olive::CurrentConfig.edit_tool_also_seeks) panel_sequence_viewer->seek(panel_timeline->drag_frame_start); + if (olive::CurrentConfig.edit_tool_also_seeks) panel_sequence_viewer->seek(panel_timeline->drag_frame_start); panel_timeline->selecting = true; break; case TIMELINE_TOOL_RAZOR: @@ -794,7 +794,7 @@ void make_room_for_transition(ComboAction* ca, Clip* c, int type, long transitio void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { QToolTip::hideText(); - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { bool alt = (event->modifiers() & Qt::AltModifier); bool shift = (event->modifiers() & Qt::ShiftModifier); bool ctrl = (event->modifiers() & Qt::ControlModifier); @@ -808,11 +808,11 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { const Ghost& g = panel_timeline->ghosts.at(0); if (panel_timeline->creating_object == ADD_OBJ_AUDIO) { - Olive::MainWindow->statusBar()->clearMessage(); + olive::MainWindow->statusBar()->clearMessage(); panel_sequence_viewer->cue_recording(qMin(g.in, g.out), qMax(g.in, g.out), g.track); panel_timeline->creating = false; } else if (g.in != g.out) { - Clip* c = new Clip(Olive::ActiveSequence); + Clip* c = new Clip(olive::ActiveSequence); c->media = nullptr; c->timeline_in = qMin(g.in, g.out); c->timeline_out = qMax(g.in, g.out); @@ -836,9 +836,9 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { QVector add; add.append(c); - ca->append(new AddClipCommand(Olive::ActiveSequence, add)); + ca->append(new AddClipCommand(olive::ActiveSequence, add)); - if (c->track < 0 && Olive::CurrentConfig.add_default_effects_to_clips) { + if (c->track < 0 && olive::CurrentConfig.add_default_effects_to_clips) { // default video effects (before custom effects) c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TRANSFORM, EFFECT_TYPE_EFFECT))); } @@ -870,7 +870,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { break; } - if (c->track >= 0 && Olive::CurrentConfig.add_default_effects_to_clips) { + if (c->track >= 0 && olive::CurrentConfig.add_default_effects_to_clips) { // default audio effects (after custom effects) c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_VOLUME, EFFECT_TYPE_EFFECT))); c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_PAN, EFFECT_TYPE_EFFECT))); @@ -910,9 +910,9 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { ripple_length = first_ghost.old_in - first_ghost.in; ripple_point = first_ghost.old_in; - for (int i=0;iselections.size();i++) { - Olive::ActiveSequence->selections[i].in += ripple_length; - Olive::ActiveSequence->selections[i].out += ripple_length; + for (int i=0;iselections.size();i++) { + olive::ActiveSequence->selections[i].in += ripple_length; + olive::ActiveSequence->selections[i].out += ripple_length; } } else { // if we're trimming an out-point @@ -935,7 +935,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { } if (!panel_timeline->trim_in_point) ripple_length = -ripple_length; - ripple_clips(ca, Olive::ActiveSequence, ripple_point, ripple_length, ignore_clips); + ripple_clips(ca, olive::ActiveSequence, ripple_point, ripple_length, ignore_clips); } if (panel_timeline->tool == TIMELINE_TOOL_POINTER @@ -949,7 +949,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { const Ghost& g = panel_timeline->ghosts.at(i); if (g.old_in != g.in || g.old_out != g.out || g.track != g.old_track || g.clip_in != g.old_clip_in) { // create copy of clip - Clip* c = Olive::ActiveSequence->clips.at(g.clip)->copy(Olive::ActiveSequence); + Clip* c = olive::ActiveSequence->clips.at(g.clip)->copy(olive::ActiveSequence); c->timeline_in = g.in; c->timeline_out = g.out; @@ -971,7 +971,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { // relink duplicated clips panel_timeline->relink_clips_using_ids(old_clips, new_clips); - ca->append(new AddClipCommand(Olive::ActiveSequence, new_clips)); + ca->append(new AddClipCommand(olive::ActiveSequence, new_clips)); } } else { // INSERT if holding ctrl @@ -984,7 +984,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { // step 1 - set clips that are moving to "undeletable" (to avoid step 2 deleting any part of them) const Ghost& g = panel_timeline->ghosts.at(i); - Olive::ActiveSequence->clips.at(g.clip)->undeletable = true; + olive::ActiveSequence->clips.at(g.clip)->undeletable = true; if (g.transition != nullptr) { g.transition->parent_clip->undeletable = true; if (g.transition->secondary_clip != nullptr) g.transition->secondary_clip->undeletable = true; @@ -999,7 +999,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { panel_timeline->delete_areas_and_relink(ca, delete_areas, false); for (int i=0;ighosts.size();i++) { const Ghost& g = panel_timeline->ghosts.at(i); - Olive::ActiveSequence->clips.at(g.clip)->undeletable = false; + olive::ActiveSequence->clips.at(g.clip)->undeletable = false; if (g.transition != nullptr) { g.transition->parent_clip->undeletable = false; if (g.transition->secondary_clip != nullptr) g.transition->secondary_clip->undeletable = false; @@ -1010,7 +1010,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { Ghost& g = panel_timeline->ghosts[i]; // step 3 - move clips - Clip* c = Olive::ActiveSequence->clips.at(g.clip); + Clip* c = olive::ActiveSequence->clips.at(g.clip); if (g.transition == nullptr) { move_clip(ca, c, (g.in - g.old_in), (g.out - g.old_out), (g.clip_in - g.old_clip_in), (g.track - g.old_track), true, true); @@ -1082,13 +1082,13 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { long transition_start = qMin(g.in, g.out); long transition_end = qMax(g.in, g.out); - Clip* pre = Olive::ActiveSequence->clips.at(g.clip); + Clip* pre = olive::ActiveSequence->clips.at(g.clip); Clip* post = pre; make_room_for_transition(ca, pre, panel_timeline->transition_tool_type, transition_start, transition_end, true); if (panel_timeline->transition_tool_post_clip > -1) { - post = Olive::ActiveSequence->clips.at(panel_timeline->transition_tool_post_clip); + post = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_post_clip); int opposite_type = (panel_timeline->transition_tool_type == TA_OPENING_TRANSITION) ? TA_CLOSING_TRANSITION : TA_OPENING_TRANSITION; make_room_for_transition( ca, @@ -1158,17 +1158,17 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { } // remove duplicate selections - panel_timeline->clean_up_selections(Olive::ActiveSequence->selections); + panel_timeline->clean_up_selections(olive::ActiveSequence->selections); if (selection_command != nullptr) { - selection_command->new_data = Olive::ActiveSequence->selections; + selection_command->new_data = olive::ActiveSequence->selections; ca->append(selection_command); selection_command = nullptr; push_undo = true; } if (push_undo) { - Olive::UndoStack.push(ca); + olive::UndoStack.push(ca); } else { delete ca; } @@ -1200,7 +1200,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { void TimelineWidget::init_ghosts() { for (int i=0;ighosts.size();i++) { Ghost& g = panel_timeline->ghosts[i]; - Clip* c = Olive::ActiveSequence->clips.at(g.clip); + Clip* c = olive::ActiveSequence->clips.at(g.clip); g.track = g.old_track = c->track; g.clip_in = g.old_clip_in = c->clip_in; @@ -1230,8 +1230,8 @@ void TimelineWidget::init_ghosts() { c->recalculateMaxLength(); g.media_length = c->getMaximumLength(); } - for (int i=0;iselections.size();i++) { - Selection& s = Olive::ActiveSequence->selections[i]; + for (int i=0;iselections.size();i++) { + Selection& s = olive::ActiveSequence->selections[i]; s.old_in = s.in; s.old_out = s.out; s.old_track = s.track; @@ -1306,7 +1306,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { // if the ghost is attached to a clip, snap its markers too if (panel_timeline->trim_target == -1 && g.clip >= 0) { - Clip* c = Olive::ActiveSequence->clips.at(g.clip); + Clip* c = olive::ActiveSequence->clips.at(g.clip); for (int j=0;jget_markers().size();j++) { long marker_real_time = c->get_markers().at(j).frame + c->timeline_in - c->clip_in; fm = marker_real_time + frame_diff; @@ -1326,7 +1326,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { for (int i=0;ighosts.size();i++) { const Ghost& g = panel_timeline->ghosts.at(i); Clip* c = nullptr; - if (g.clip != -1) c = Olive::ActiveSequence->clips.at(g.clip); + if (g.clip != -1) c = olive::ActiveSequence->clips.at(g.clip); const FootageStream* ms = nullptr; if (g.clip != -1 && c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { @@ -1482,7 +1482,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { validate_transitions(c, panel_timeline->transition_tool_type, frame_diff); } else { Clip* otc = c; // open transition clip - Clip* ctc = Olive::ActiveSequence->clips.at(panel_timeline->transition_tool_post_clip); // close transition clip + Clip* ctc = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_post_clip); // close transition clip if (panel_timeline->transition_tool_type == TA_CLOSING_TRANSITION) { // swap @@ -1545,7 +1545,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { g.in = g.old_in + frame_diff; g.out = g.old_out + frame_diff; - if (g.transition != nullptr && g.transition == Olive::ActiveSequence->clips.at(g.clip)->get_opening_transition()) { + if (g.transition != nullptr && g.transition == olive::ActiveSequence->clips.at(g.clip)->get_opening_transition()) { g.clip_in = g.old_clip_in + frame_diff; } @@ -1578,8 +1578,8 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { // apply changes to selections if (effective_tool != TIMELINE_TOOL_SLIP && !panel_timeline->importing && !panel_timeline->creating) { - for (int i=0;iselections.size();i++) { - Selection& s = Olive::ActiveSequence->selections[i]; + for (int i=0;iselections.size();i++) { + Selection& s = olive::ActiveSequence->selections[i]; if (panel_timeline->trim_target > -1) { if (panel_timeline->trim_in_point) { s.in = s.old_in + frame_diff; @@ -1587,8 +1587,8 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { s.out = s.old_out + frame_diff; } } else if (clips_are_movable) { - for (int i=0;iselections.size();i++) { - Selection& s = Olive::ActiveSequence->selections[i]; + for (int i=0;iselections.size();i++) { + Selection& s = olive::ActiveSequence->selections[i]; s.in = s.old_in + frame_diff; s.out = s.old_out + frame_diff; s.track = s.old_track; @@ -1609,9 +1609,9 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { } if (panel_timeline->importing) { - QToolTip::showText(mapToGlobal(mouse_pos), frame_to_timecode(earliest_in_point, Olive::CurrentConfig.timecode_view, Olive::ActiveSequence->frame_rate)); + QToolTip::showText(mapToGlobal(mouse_pos), frame_to_timecode(earliest_in_point, olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate)); } else { - QString tip = ((frame_diff < 0) ? "-" : "+") + frame_to_timecode(qAbs(frame_diff), Olive::CurrentConfig.timecode_view, Olive::ActiveSequence->frame_rate); + QString tip = ((frame_diff < 0) ? "-" : "+") + frame_to_timecode(qAbs(frame_diff), olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate); if (panel_timeline->trim_target > -1) { // find which clip is being moved const Ghost* g = nullptr; @@ -1630,7 +1630,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { } else { len += frame_diff; } - tip += frame_to_timecode(len, Olive::CurrentConfig.timecode_view, Olive::ActiveSequence->frame_rate); + tip += frame_to_timecode(len, olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate); } } QToolTip::showText(mapToGlobal(mouse_pos), tip); @@ -1639,7 +1639,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { tooltip_timer.stop(); - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { bool alt = (event->modifiers() & Qt::AltModifier); panel_timeline->cursor_frame = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x()); @@ -1650,16 +1650,16 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { if (!panel_timeline->moving_init) track_resizing = false; if (isLiveEditing()) { - panel_timeline->snap_to_timeline(&panel_timeline->cursor_frame, !Olive::CurrentConfig.edit_tool_also_seeks || !panel_timeline->selecting, true, true); + panel_timeline->snap_to_timeline(&panel_timeline->cursor_frame, !olive::CurrentConfig.edit_tool_also_seeks || !panel_timeline->selecting, true, true); } if (panel_timeline->selecting) { int selection_count = 1 + qMax(panel_timeline->cursor_track, panel_timeline->drag_track_start) - qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start) + panel_timeline->selection_offset; - if (Olive::ActiveSequence->selections.size() != selection_count) { - Olive::ActiveSequence->selections.resize(selection_count); + if (olive::ActiveSequence->selections.size() != selection_count) { + olive::ActiveSequence->selections.resize(selection_count); } int minimum_selection_track = qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start); for (int i=panel_timeline->selection_offset;iselections[i]; + Selection& s = olive::ActiveSequence->selections[i]; s.track = minimum_selection_track + i - panel_timeline->selection_offset; long in = panel_timeline->drag_frame_start; long out = panel_timeline->cursor_frame; @@ -1668,11 +1668,11 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } // select linked clips too - if (Olive::CurrentConfig.edit_tool_selects_links) { - for (int j=0;jclips.size();j++) { - Clip* c = Olive::ActiveSequence->clips.at(j); - for (int k=0;kselections.size();k++) { - const Selection& s = Olive::ActiveSequence->selections.at(k); + if (olive::CurrentConfig.edit_tool_selects_links) { + for (int j=0;jclips.size();j++) { + Clip* c = olive::ActiveSequence->clips.at(j); + for (int k=0;kselections.size();k++) { + const Selection& s = olive::ActiveSequence->selections.at(k); if (!(c->timeline_in < s.in && c->timeline_out < s.in) && !(c->timeline_in > s.out && c->timeline_out > s.out) && c->track == s.track) { @@ -1680,8 +1680,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { QVector linked_tracks = panel_timeline->get_tracks_of_linked_clips(j); for (int k=0;kselections.size();l++) { - const Selection& test_sel = Olive::ActiveSequence->selections.at(l); + for (int l=0;lselections.size();l++) { + const Selection& test_sel = olive::ActiveSequence->selections.at(l); if (test_sel.track == linked_tracks.at(k) && test_sel.in == s.in && test_sel.out == s.out) { @@ -1694,7 +1694,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { link_sel.in = s.in; link_sel.out = s.out; link_sel.track = linked_tracks.at(k); - Olive::ActiveSequence->selections.append(link_sel); + olive::ActiveSequence->selections.append(link_sel); } } @@ -1704,7 +1704,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } } - if (Olive::CurrentConfig.edit_tool_also_seeks) { + if (olive::CurrentConfig.edit_tool_also_seeks) { panel_sequence_viewer->seek(qMin(panel_timeline->drag_frame_start, panel_timeline->cursor_frame)); } else { panel_timeline->repaint_timeline(); @@ -1736,8 +1736,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } else { // set up movement // create ghosts - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { Ghost g; g.transition = nullptr; @@ -1747,8 +1747,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // if a whole clip is not selected, maybe just a transition is if (panel_timeline->tool == TIMELINE_TOOL_POINTER && (c->get_opening_transition() != nullptr || c->get_closing_transition() != nullptr)) { // check if any selections contain the whole clip or transition - for (int j=0;jselections.size();j++) { - const Selection& s = Olive::ActiveSequence->selections.at(j); + for (int j=0;jselections.size();j++) { + const Selection& s = olive::ActiveSequence->selections.at(j); if (s.track == c->track) { if (selection_contains_transition(s, c, TA_OPENING_TRANSITION)) { g.transition = c->get_opening_transition(); @@ -1785,11 +1785,11 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { int size = panel_timeline->ghosts.size(); if (panel_timeline->tool == TIMELINE_TOOL_ROLLING) { for (int i=0;iclips.at(panel_timeline->ghosts.at(i).clip); + Clip* ghost_clip = olive::ActiveSequence->clips.at(panel_timeline->ghosts.at(i).clip); // see if any ghosts are touching, in which case flip them for (int k=0;kclips.at(panel_timeline->ghosts.at(k).clip); + Clip* comp_clip = olive::ActiveSequence->clips.at(panel_timeline->ghosts.at(k).clip); if ((panel_timeline->trim_in_point && comp_clip->timeline_out == ghost_clip->timeline_in) || (!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) { panel_timeline->ghosts[k].trim_in = !panel_timeline->trim_in_point; @@ -1800,9 +1800,9 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // then look for other clips we're touching for (int i=0;ighosts.at(i); - Clip* ghost_clip = Olive::ActiveSequence->clips.at(g.clip); - for (int j=0;jclips.size();j++) { - Clip* comp_clip = Olive::ActiveSequence->clips.at(j); + Clip* ghost_clip = olive::ActiveSequence->clips.at(g.clip); + for (int j=0;jclips.size();j++) { + Clip* comp_clip = olive::ActiveSequence->clips.at(j); if (comp_clip->track == ghost_clip->track) { if ((panel_timeline->trim_in_point && comp_clip->timeline_out == ghost_clip->timeline_in) || (!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) { @@ -1839,10 +1839,10 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } else if (panel_timeline->tool == TIMELINE_TOOL_SLIDE) { for (int i=0;ighosts.at(i); - Clip* ghost_clip = Olive::ActiveSequence->clips.at(g.clip); + Clip* ghost_clip = olive::ActiveSequence->clips.at(g.clip); panel_timeline->ghosts[i].trimming = false; - for (int j=0;jclips.size();j++) { - Clip* c = Olive::ActiveSequence->clips.at(j); + for (int j=0;jclips.size();j++) { + Clip* c = olive::ActiveSequence->clips.at(j); if (c != nullptr && c->track == ghost_clip->track) { bool found = false; for (int k=0;kghosts.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(panel_timeline->ghosts.at(i).clip); + Clip* c = olive::ActiveSequence->clips.at(panel_timeline->ghosts.at(i).clip); if (panel_timeline->trim_in_point) { axis = qMin(axis, c->timeline_in); } else { @@ -1882,8 +1882,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } } - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr && !is_clip_selected(c, true)) { bool clip_is_post = (c->timeline_in >= axis); @@ -1909,8 +1909,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } // store selections - selection_command = new SetSelectionsCommand(Olive::ActiveSequence); - selection_command->old_data = Olive::ActiveSequence->selections; + selection_command = new SetSelectionsCommand(olive::ActiveSequence); + selection_command->old_data = olive::ActiveSequence->selections; panel_timeline->moving_proc = true; } @@ -1958,8 +1958,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { int track_max = qMax(track_start, track_end); QVector selected_clips; - for (int i=0;iclips.size();i++) { - Clip* clip = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* clip = olive::ActiveSequence->clips.at(i); if (clip != nullptr && clip->track >= track_min && clip->track <= track_max && @@ -1970,7 +1970,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { if (!alt) { for (int j=0;jlinked.size();j++) { - session_clips.append(Olive::ActiveSequence->clips.at(clip->linked.at(j))); + session_clips.append(olive::ActiveSequence->clips.at(clip->linked.at(j))); } } @@ -1991,9 +1991,9 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } } - Olive::ActiveSequence->selections.resize(selected_clips.size() + panel_timeline->selection_offset); + olive::ActiveSequence->selections.resize(selected_clips.size() + panel_timeline->selection_offset); for (int i=0;iselections[i+panel_timeline->selection_offset]; + Selection& s = olive::ActiveSequence->selections[i+panel_timeline->selection_offset]; Clip* clip = selected_clips.at(i); s.old_in = s.in = clip->timeline_in; s.old_out = s.out = clip->timeline_out; @@ -2055,8 +2055,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { panel_timeline->trim_target = -1; // loop through current clips in the sequence - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { // cache track range @@ -2181,9 +2181,9 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { if (found) { if (panel_timeline->trim_in_point) { // if we're trimming an IN point - setCursor(Olive::Cursor_LeftTrim); + setCursor(olive::Cursor_LeftTrim); } else { // if we're trimming an OUT point - setCursor(Olive::Cursor_RightTrim); + setCursor(olive::Cursor_RightTrim); } } else { @@ -2202,7 +2202,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { int mouse_pos = pos.y() + scroll; if (mouse_pos > y_test_value-test_range && mouse_pos < y_test_value+test_range) { // if track lines are hidden, only resize track if a clip is already there - if (Olive::CurrentConfig.show_track_lines || cursor_contains_clip) { + if (olive::CurrentConfig.show_track_lines || cursor_contains_clip) { found = true; track_resizing = true; track_target = track; @@ -2230,7 +2230,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { if (panel_timeline->transition_tool_proc) { update_ghosts(event->pos(), event->modifiers() & Qt::ShiftModifier); } else { - Clip* c = Olive::ActiveSequence->clips.at(panel_timeline->transition_tool_pre_clip); + Clip* c = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_pre_clip); Ghost g; @@ -2247,7 +2247,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } else { int mouse_clip = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); if (mouse_clip > -1) { - Clip* c = Olive::ActiveSequence->clips.at(mouse_clip); + Clip* c = olive::ActiveSequence->clips.at(mouse_clip); if (same_sign(c->track, panel_timeline->transition_tool_side)) { panel_timeline->transition_tool_pre_clip = mouse_clip; long halfway = c->timeline_in + (c->getLength()/2); @@ -2300,7 +2300,7 @@ void draw_waveform(Clip* clip, const FootageStream* ms, long media_length, QPain } for (int j=0;jaudio_channels;j++) { - int mid = (Olive::CurrentConfig.rectified_waveforms) ? clip_rect.top()+channel_height*(j+1) : clip_rect.top()+channel_height*j+(channel_height/2); + int mid = (olive::CurrentConfig.rectified_waveforms) ? clip_rect.top()+channel_height*(j+1) : clip_rect.top()+channel_height*j+(channel_height/2); int offset_range_start = last_waveform_index+(j*2); int offset_range_end = waveform_index+(j*2); @@ -2317,7 +2317,7 @@ void draw_waveform(Clip* clip, const FootageStream* ms, long media_length, QPain } // draw waveforms - if (Olive::CurrentConfig.rectified_waveforms) { + if (olive::CurrentConfig.rectified_waveforms) { // rectified waveforms start from the bottom and draw upwards p->drawLine(clip_rect.left()+i, mid, clip_rect.left()+i, mid - (max - min)); @@ -2385,14 +2385,14 @@ void draw_transition(QPainter& p, Clip* c, const QRect& clip_rect, QRect& text_r void TimelineWidget::paintEvent(QPaintEvent*) { // Draw clips - if (Olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence != nullptr) { QPainter p(this); // get widget width and height int video_track_limit = 0; int audio_track_limit = 0; - for (int i=0;iclips.size();i++) { - Clip* clip = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* clip = olive::ActiveSequence->clips.at(i); if (clip != nullptr) { video_track_limit = qMin(video_track_limit, clip->track); audio_track_limit = qMax(audio_track_limit, clip->track); @@ -2415,8 +2415,8 @@ void TimelineWidget::paintEvent(QPaintEvent*) { scrollBar->setMaximum(qMax(0, panel_height - height())); } - for (int i=0;iclips.size();i++) { - Clip* clip = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* clip = olive::ActiveSequence->clips.at(i); if (clip != nullptr && is_track_visible(clip->track)) { QRect clip_rect(panel_timeline->getTimelineScreenPointFromFrame(clip->timeline_in), getScreenPointFromTrack(clip->track), getScreenPointFromFrame(panel_timeline->zoom, clip->getLength()), panel_timeline->calculate_track_height(clip->track, -1)); QRect text_rect(clip_rect.left() + CLIP_TEXT_PADDING, clip_rect.top() + CLIP_TEXT_PADDING, clip_rect.width() - CLIP_TEXT_PADDING - 1, clip_rect.height() - CLIP_TEXT_PADDING - 1); @@ -2689,7 +2689,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { } // Draw track lines - if (Olive::CurrentConfig.show_track_lines) { + if (olive::CurrentConfig.show_track_lines) { p.setPen(QColor(0, 0, 0, 96)); audio_track_limit++; if (video_track_limit == 0) video_track_limit--; @@ -2710,8 +2710,8 @@ void TimelineWidget::paintEvent(QPaintEvent*) { } // Draw selections - for (int i=0;iselections.size();i++) { - const Selection& s = Olive::ActiveSequence->selections.at(i); + for (int i=0;iselections.size();i++) { + const Selection& s = olive::ActiveSequence->selections.at(i); if (is_track_visible(s.track)) { int selection_y = getScreenPointFromTrack(s.track); int selection_x = panel_timeline->getTimelineScreenPointFromFrame(s.in); @@ -2788,7 +2788,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { // Draw playhead p.setPen(Qt::red); - int playhead_x = panel_timeline->getTimelineScreenPointFromFrame(Olive::ActiveSequence->playhead); + int playhead_x = panel_timeline->getTimelineScreenPointFromFrame(olive::ActiveSequence->playhead); p.drawLine(playhead_x, rect().top(), playhead_x, rect().bottom()); // draw border @@ -2836,7 +2836,7 @@ int TimelineWidget::getTrackFromScreenPoint(int y) { int counter = ((!bottom_align && y > 0) || (bottom_align && y < 0)) ? 0 : -1; int track_height = panel_timeline->calculate_track_height(counter, -1); while (qAbs(y) > height_measure+track_height) { - if (Olive::CurrentConfig.show_track_lines && counter != -1) y--; + if (olive::CurrentConfig.show_track_lines && counter != -1) y--; height_measure += track_height; if ((!bottom_align && y > 0) || (bottom_align && y < 0)) { counter++; @@ -2855,15 +2855,15 @@ int TimelineWidget::getScreenPointFromTrack(int track) { if (bottom_align) counter--; y += panel_timeline->calculate_track_height(counter, -1); if (!bottom_align) counter++; - if (Olive::CurrentConfig.show_track_lines && counter != -1) y++; + if (olive::CurrentConfig.show_track_lines && counter != -1) y++; } y++; return (bottom_align) ? height() - y - scroll : y - scroll; } int TimelineWidget::getClipIndexFromCoords(long frame, int track) { - for (int i=0;iclips.size();i++) { - Clip* c = Olive::ActiveSequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = olive::ActiveSequence->clips.at(i); if (c != nullptr && c->track == track && frame >= c->timeline_in && frame < c->timeline_out) { return i; } diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index 26bfeb345..3fc32f230 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -426,11 +426,11 @@ void ViewerWidget::draw_title_safe_area() { double viewportAr = (double) width() / (double) height(); double halfAr = viewportAr*0.5; - if (Olive::CurrentConfig.use_custom_title_safe_ratio && Olive::CurrentConfig.custom_title_safe_ratio > 0) { - if (Olive::CurrentConfig.custom_title_safe_ratio > viewportAr) { - halfHeight = (Olive::CurrentConfig.custom_title_safe_ratio/viewportAr)*0.5; + if (olive::CurrentConfig.use_custom_title_safe_ratio && olive::CurrentConfig.custom_title_safe_ratio > 0) { + if (olive::CurrentConfig.custom_title_safe_ratio > viewportAr) { + halfHeight = (olive::CurrentConfig.custom_title_safe_ratio/viewportAr)*0.5; } else { - halfWidth = (viewportAr/Olive::CurrentConfig.custom_title_safe_ratio)*0.5; + halfWidth = (viewportAr/olive::CurrentConfig.custom_title_safe_ratio)*0.5; } } @@ -609,7 +609,7 @@ void ViewerWidget::paintGL() { glBindTexture(GL_TEXTURE_2D, 0); // draw title/action safe area - if (Olive::CurrentConfig.show_title_safe_area) { + if (olive::CurrentConfig.show_title_safe_area) { draw_title_safe_area(); } From 5207a0511fecc8dffe19bb4d42ecd1d2b4d04fb0 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sat, 16 Feb 2019 21:21:04 -0800 Subject: [PATCH 05/30] several conversions to smart pointers --- dialogs/mediapropertiesdialog.cpp | 4 +- dialogs/mediapropertiesdialog.h | 4 +- dialogs/newsequencedialog.cpp | 4 +- dialogs/newsequencedialog.h | 6 +- dialogs/proxydialog.cpp | 2 +- dialogs/proxydialog.h | 4 +- dialogs/replaceclipmediadialog.cpp | 6 +- dialogs/replaceclipmediadialog.h | 4 +- dialogs/speeddialog.cpp | 26 +-- dialogs/speeddialog.h | 2 +- effects/internal/audionoiseeffect.cpp | 2 +- effects/internal/audionoiseeffect.h | 2 +- effects/internal/cornerpineffect.cpp | 2 +- effects/internal/cornerpineffect.h | 2 +- effects/internal/crossdissolvetransition.cpp | 2 +- effects/internal/crossdissolvetransition.h | 2 +- effects/internal/cubetransition.cpp | 2 +- effects/internal/cubetransition.h | 2 +- .../internal/exponentialfadetransition.cpp | 2 +- effects/internal/exponentialfadetransition.h | 2 +- effects/internal/fillleftrighteffect.cpp | 2 +- effects/internal/fillleftrighteffect.h | 2 +- effects/internal/frei0reffect.cpp | 2 +- effects/internal/frei0reffect.h | 2 +- effects/internal/linearfadetransition.cpp | 2 +- effects/internal/linearfadetransition.h | 2 +- .../internal/logarithmicfadetransition.cpp | 2 +- effects/internal/logarithmicfadetransition.h | 2 +- effects/internal/paneffect.cpp | 2 +- effects/internal/paneffect.h | 2 +- effects/internal/shakeeffect.cpp | 2 +- effects/internal/shakeeffect.h | 2 +- effects/internal/solideffect.cpp | 2 +- effects/internal/solideffect.h | 2 +- effects/internal/texteffect.cpp | 2 +- effects/internal/texteffect.h | 2 +- effects/internal/timecodeeffect.cpp | 2 +- effects/internal/timecodeeffect.h | 2 +- effects/internal/toneeffect.cpp | 2 +- effects/internal/toneeffect.h | 2 +- effects/internal/transformeffect.cpp | 2 +- effects/internal/transformeffect.h | 2 +- effects/internal/voideffect.cpp | 6 +- effects/internal/voideffect.h | 4 +- effects/internal/volumeeffect.cpp | 2 +- effects/internal/volumeeffect.h | 2 +- effects/internal/vsthost.cpp | 2 +- effects/internal/vsthost.h | 2 +- io/clipboard.cpp | 19 +- io/clipboard.h | 6 +- io/loadthread.cpp | 32 ++-- io/loadthread.h | 18 +- io/previewgenerator.cpp | 9 +- io/previewgenerator.h | 9 +- io/proxygenerator.cpp | 2 +- io/proxygenerator.h | 4 +- main.cpp | 2 +- mainwindow.cpp | 4 + olive.pro | 6 +- oliveglobal.cpp | 2 +- panels/effectcontrols.cpp | 22 +-- panels/effectcontrols.h | 2 +- panels/panels.cpp | 4 +- panels/project.cpp | 128 +++++++------- panels/project.h | 32 ++-- panels/timeline.cpp | 162 ++++++++--------- panels/timeline.h | 45 ++--- panels/viewer.cpp | 21 ++- panels/viewer.h | 22 ++- playback/audio.h | 12 +- playback/cacher.cpp | 24 +-- playback/cacher.h | 13 +- playback/playback.cpp | 35 ++-- playback/playback.h | 44 ++--- project/clip.cpp | 42 ++--- project/clip.h | 53 +++--- project/comboaction.cpp | 35 ++++ project/comboaction.h | 88 ++++++++++ project/effect.cpp | 42 ++--- project/effect.h | 33 ++-- project/effectrow.cpp | 6 +- project/footage.h | 4 +- project/marker.cpp | 6 +- project/marker.h | 7 +- project/media.cpp | 41 +++-- project/media.h | 22 ++- project/projectmodel.cpp | 4 +- project/projectmodel.h | 22 +-- project/sequence.cpp | 35 ++-- project/sequence.h | 21 +-- project/sourcescommon.cpp | 6 +- project/sourcescommon.h | 4 +- project/transition.cpp | 24 +-- project/transition.h | 10 +- project/undo.cpp | 149 +++++----------- project/undo.h | 164 ++++++++---------- ui/keyframeview.cpp | 8 +- ui/renderfunctions.cpp | 24 +-- ui/renderfunctions.h | 18 +- ui/renderthread.cpp | 2 +- ui/renderthread.h | 16 +- ui/timelinewidget.cpp | 150 ++++++++-------- ui/timelinewidget.h | 40 +++-- ui/viewerwidget.h | 18 +- 104 files changed, 972 insertions(+), 945 deletions(-) create mode 100644 project/comboaction.cpp create mode 100644 project/comboaction.h diff --git a/dialogs/mediapropertiesdialog.cpp b/dialogs/mediapropertiesdialog.cpp index b004e3fdf..591794cd4 100644 --- a/dialogs/mediapropertiesdialog.cpp +++ b/dialogs/mediapropertiesdialog.cpp @@ -47,7 +47,7 @@ MediaPropertiesDialog::MediaPropertiesDialog(QWidget *parent, Media *i) : int row = 0; - Footage* f = item->to_footage(); + FootagePtr f = item->to_footage(); grid->addWidget(new QLabel(tr("Tracks:"), this), row, 0, 1, 2); row++; @@ -143,7 +143,7 @@ MediaPropertiesDialog::MediaPropertiesDialog(QWidget *parent, Media *i) : } void MediaPropertiesDialog::accept() { - Footage* f = item->to_footage(); + FootagePtr f = item->to_footage(); ComboAction* ca = new ComboAction(); diff --git a/dialogs/mediapropertiesdialog.h b/dialogs/mediapropertiesdialog.h index a2e63da8b..8f24eee72 100644 --- a/dialogs/mediapropertiesdialog.h +++ b/dialogs/mediapropertiesdialog.h @@ -34,11 +34,11 @@ class MediaPropertiesDialog : public QDialog { Q_OBJECT public: - MediaPropertiesDialog(QWidget *parent, Media* i); + MediaPropertiesDialog(QWidget *parent, Media* i); private: QComboBox* interlacing_box; QLineEdit* name_box; - Media* item; + Media* item; QListWidget* track_list; QDoubleSpinBox* conform_fr; QCheckBox* premultiply_alpha_setting; diff --git a/dialogs/newsequencedialog.cpp b/dialogs/newsequencedialog.cpp index 3b4e48457..19ce423ac 100644 --- a/dialogs/newsequencedialog.cpp +++ b/dialogs/newsequencedialog.cpp @@ -85,7 +85,7 @@ void NewSequenceDialog::set_sequence_name(const QString& s) { void NewSequenceDialog::create() { if (existing_sequence == nullptr) { - Sequence* s = new Sequence(); + SequencePtr s(new Sequence()); s->name = sequence_name_edit->text(); s->width = width_numeric->value(); @@ -112,7 +112,7 @@ void NewSequenceDialog::create() { ca->append(esc); for (int i=0;iclips.size();i++) { - Clip* c = existing_sequence->clips.at(i); + ClipPtr c = existing_sequence->clips.at(i); if (c != nullptr) { c->refactor_frame_rate(ca, multiplier, true); } diff --git a/dialogs/newsequencedialog.h b/dialogs/newsequencedialog.h index f9d5164c6..8638b0e99 100644 --- a/dialogs/newsequencedialog.h +++ b/dialogs/newsequencedialog.h @@ -35,7 +35,7 @@ class NewSequenceDialog : public QDialog Q_OBJECT public: - explicit NewSequenceDialog(QWidget *parent = 0, Media* existing = 0); + explicit NewSequenceDialog(QWidget *parent = nullptr, Media* existing = nullptr); ~NewSequenceDialog(); void set_sequence_name(const QString& s); @@ -45,8 +45,8 @@ private slots: void preset_changed(int index); private: - Sequence* existing_sequence; - Media* existing_item; + SequencePtr existing_sequence; + Media* existing_item; void setup_ui(); diff --git a/dialogs/proxydialog.cpp b/dialogs/proxydialog.cpp index 4c989f466..033ee7256 100644 --- a/dialogs/proxydialog.cpp +++ b/dialogs/proxydialog.cpp @@ -32,7 +32,7 @@ #include "project/footage.h" #include "mainwindow.h" -ProxyDialog::ProxyDialog(QWidget *parent, const QVector &footage) : +ProxyDialog::ProxyDialog(QWidget *parent, const QVector &footage) : QDialog(parent), selected_footage(footage) { diff --git a/dialogs/proxydialog.h b/dialogs/proxydialog.h index d8917be54..3c283385b 100644 --- a/dialogs/proxydialog.h +++ b/dialogs/proxydialog.h @@ -30,7 +30,7 @@ class ProxyDialog : public QDialog { Q_OBJECT public: - ProxyDialog(QWidget* parent, const QVector& footage); + ProxyDialog(QWidget* parent, const QVector& footage); public slots: // called if user clicks "OK" on the dialog virtual void accept() override; @@ -51,7 +51,7 @@ private: QString proxy_folder_name; // list of footage to make proxies for - QVector selected_footage; + QVector selected_footage; private slots: // triggered when the user changes the index in the location combobox void location_changed(int i); diff --git a/dialogs/replaceclipmediadialog.cpp b/dialogs/replaceclipmediadialog.cpp index e9d5c2739..7a4cdc2c2 100644 --- a/dialogs/replaceclipmediadialog.cpp +++ b/dialogs/replaceclipmediadialog.cpp @@ -31,7 +31,7 @@ #include #include -ReplaceClipMediaDialog::ReplaceClipMediaDialog(QWidget *parent, Media *old_media) : +ReplaceClipMediaDialog::ReplaceClipMediaDialog(QWidget *parent, Media* old_media) : QDialog(parent), media(old_media) { @@ -80,7 +80,7 @@ void ReplaceClipMediaDialog::replace() { QMessageBox::Ok ); } else { - Media* new_item = static_cast(selected_items.at(0).internalPointer()); + Media* new_item = static_cast(selected_items.at(0).internalPointer()); if (media == new_item) { QMessageBox::critical( this, @@ -111,7 +111,7 @@ void ReplaceClipMediaDialog::replace() { ); for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr && c->media == media) { rcmc->clips.append(c); } diff --git a/dialogs/replaceclipmediadialog.h b/dialogs/replaceclipmediadialog.h index 1971579f4..7b1867a71 100644 --- a/dialogs/replaceclipmediadialog.h +++ b/dialogs/replaceclipmediadialog.h @@ -31,11 +31,11 @@ class ReplaceClipMediaDialog : public QDialog { Q_OBJECT public: - ReplaceClipMediaDialog(QWidget* parent, Media *old_media); + ReplaceClipMediaDialog(QWidget* parent, Media* old_media); private slots: void replace(); private: - Media* media; + Media* media; QTreeView* tree; QCheckBox* use_same_media_in_points; }; diff --git a/dialogs/speeddialog.cpp b/dialogs/speeddialog.cpp index 76dac52c8..cfa69f777 100644 --- a/dialogs/speeddialog.cpp +++ b/dialogs/speeddialog.cpp @@ -94,7 +94,7 @@ void SpeedDialog::run() { current_length = -1; for (int i=0;itrack < 0) { bool process_video = true; if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { - Footage* m = c->media->to_footage(); + FootagePtr m = c->media->to_footage(); FootageStream* ms = m->get_stream_from_file_index(true, c->media_stream); if (ms != nullptr && ms->infinite_length) { process_video = false; @@ -187,7 +187,7 @@ void SpeedDialog::percent_update() { long len_val = -1; for (int i=0;iisEnabled() && c->track < 0) { @@ -222,7 +222,7 @@ void SpeedDialog::duration_update() { double fr_val = qSNaN(); for (int i=0;igetLength() * c->speed); @@ -265,7 +265,7 @@ void SpeedDialog::frame_rate_update() { // analyze video clips for (int i=0;itrack >= 0) { long new_clip_len = (qIsNaN(old_pc_val) || qIsNaN(pc_val)) ? c->getLength() : ((c->getLength() * c->speed) / pc_val); @@ -312,7 +312,7 @@ void SpeedDialog::frame_rate_update() { duration->set_value((len_val == -1) ? qSNaN() : len_val, false); } -void set_speed(ComboAction* ca, Clip* c, double speed, bool ripple, long& ep, long& lr) { +void set_speed(ComboAction* ca, ClipPtr c, double speed, bool ripple, long& ep, long& lr) { panel_timeline->deselect_area(c->timeline_in, c->timeline_out, c->track); long proposed_out = c->timeline_out; @@ -321,7 +321,7 @@ void set_speed(ComboAction* ca, Clip* c, double speed, bool ripple, long& ep, lo ca->append(new SetSpeedAction(c, speed)); if (!ripple && proposed_out > c->timeline_out) { for (int i=0;isequence->clips.size();i++) { - Clip* compare = c->sequence->clips.at(i); + ClipPtr compare = c->sequence->clips.at(i); if (compare != nullptr && compare->track == c->track && compare->timeline_in >= c->timeline_out && compare->timeline_in < proposed_out) { @@ -352,7 +352,7 @@ void SpeedDialog::accept() { long longest_ripple = LONG_MIN; for (int i=0;iopen) close_clip(c, true); if (c->track >= 0 @@ -372,7 +372,7 @@ void SpeedDialog::accept() { if (!qIsNaN(percent->value())) { // simply set speed for (int i=0;ivalue(), ripple->isChecked(), earliest_point, longest_ripple); } } else if (!qIsNaN(frame_rate->value())) { @@ -382,7 +382,7 @@ void SpeedDialog::accept() { // see if we can use the frame rate to change all the speeds for (int i=0;ispeed; } else if (!qFuzzyCompare(cached_speed, c->speed)) { @@ -400,7 +400,7 @@ void SpeedDialog::accept() { // make changes for (int i=0;itrack < 0) { set_speed(ca, c, frame_rate->value() / c->getMediaFrameRate(), ripple->isChecked(), earliest_point, longest_ripple); } else if (can_change_all) { @@ -410,7 +410,7 @@ void SpeedDialog::accept() { } else if (!qIsNaN(duration->value())) { // simply set duration for (int i=0;igetLength() * c->speed) / duration->value(), ripple->isChecked(), earliest_point, longest_ripple); } } diff --git a/dialogs/speeddialog.h b/dialogs/speeddialog.h index 1da29af83..9f355377a 100644 --- a/dialogs/speeddialog.h +++ b/dialogs/speeddialog.h @@ -32,7 +32,7 @@ class SpeedDialog : public QDialog Q_OBJECT public: SpeedDialog(QWidget* parent = 0); - QVector clips; + QVector clips; void run(); private slots: diff --git a/effects/internal/audionoiseeffect.cpp b/effects/internal/audionoiseeffect.cpp index d43fd5545..00afe04c8 100644 --- a/effects/internal/audionoiseeffect.cpp +++ b/effects/internal/audionoiseeffect.cpp @@ -23,7 +23,7 @@ #include #include -AudioNoiseEffect::AudioNoiseEffect(Clip* c, const EffectMeta *em) : Effect(c, em) { +AudioNoiseEffect::AudioNoiseEffect(ClipPtr c, const EffectMeta *em) : Effect(c, em) { amount_val = add_row(tr("Amount"))->add_field(EFFECT_FIELD_DOUBLE, "amount"); amount_val->set_double_minimum_value(0); amount_val->set_double_maximum_value(100); diff --git a/effects/internal/audionoiseeffect.h b/effects/internal/audionoiseeffect.h index e06789213..ea0e47dcb 100644 --- a/effects/internal/audionoiseeffect.h +++ b/effects/internal/audionoiseeffect.h @@ -26,7 +26,7 @@ class AudioNoiseEffect : public Effect { Q_OBJECT public: - AudioNoiseEffect(Clip* c, const EffectMeta* em); + AudioNoiseEffect(ClipPtr c, const EffectMeta* em); void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); EffectField* amount_val; diff --git a/effects/internal/cornerpineffect.cpp b/effects/internal/cornerpineffect.cpp index c076e2313..baf8194ef 100644 --- a/effects/internal/cornerpineffect.cpp +++ b/effects/internal/cornerpineffect.cpp @@ -24,7 +24,7 @@ #include "project/clip.h" #include "debug.h" -CornerPinEffect::CornerPinEffect(Clip *c, const EffectMeta *em) : Effect(c, em) { +CornerPinEffect::CornerPinEffect(ClipPtr c, const EffectMeta *em) : Effect(c, em) { enable_coords = true; enable_shader = true; diff --git a/effects/internal/cornerpineffect.h b/effects/internal/cornerpineffect.h index 61b38fef2..711571b96 100644 --- a/effects/internal/cornerpineffect.h +++ b/effects/internal/cornerpineffect.h @@ -26,7 +26,7 @@ class CornerPinEffect : public Effect { Q_OBJECT public: - CornerPinEffect(Clip* c, const EffectMeta* em); + CornerPinEffect(ClipPtr c, const EffectMeta* em); void process_coords(double timecode, GLTextureCoords& coords, int data); void process_shader(double timecode, GLTextureCoords& coords, int iterations); void gizmo_draw(double timecode, GLTextureCoords& coords); diff --git a/effects/internal/crossdissolvetransition.cpp b/effects/internal/crossdissolvetransition.cpp index 92e74f510..2e0a01600 100644 --- a/effects/internal/crossdissolvetransition.cpp +++ b/effects/internal/crossdissolvetransition.cpp @@ -22,7 +22,7 @@ #include -CrossDissolveTransition::CrossDissolveTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) { +CrossDissolveTransition::CrossDissolveTransition(ClipPtr c, ClipPtr s, const EffectMeta* em) : Transition(c, s, em) { enable_coords = true; // add_row("Smooth")->add_field(EFFECT_FIELD_BOOL, "smooth"); diff --git a/effects/internal/crossdissolvetransition.h b/effects/internal/crossdissolvetransition.h index 3dd8e6e44..427b3e18b 100644 --- a/effects/internal/crossdissolvetransition.h +++ b/effects/internal/crossdissolvetransition.h @@ -25,7 +25,7 @@ class CrossDissolveTransition : public Transition { public: - CrossDissolveTransition(Clip* c, Clip* s, const EffectMeta* em); + CrossDissolveTransition(ClipPtr c, ClipPtr s, const EffectMeta* em); void process_coords(double timecode, GLTextureCoords &, int data); }; diff --git a/effects/internal/cubetransition.cpp b/effects/internal/cubetransition.cpp index 829ad820d..74b79d780 100644 --- a/effects/internal/cubetransition.cpp +++ b/effects/internal/cubetransition.cpp @@ -22,7 +22,7 @@ #include "debug.h" -CubeTransition::CubeTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) { +CubeTransition::CubeTransition(ClipPtr c, ClipPtr s, const EffectMeta* em) : Transition(c, s, em) { enable_coords = true; } diff --git a/effects/internal/cubetransition.h b/effects/internal/cubetransition.h index 82519ad03..05f23b306 100644 --- a/effects/internal/cubetransition.h +++ b/effects/internal/cubetransition.h @@ -25,7 +25,7 @@ class CubeTransition : public Transition { public: - CubeTransition(Clip* c, Clip* s, const EffectMeta* em); + CubeTransition(ClipPtr c, ClipPtr s, const EffectMeta* em); void process_coords(double timecode, GLTextureCoords &, int data); }; diff --git a/effects/internal/exponentialfadetransition.cpp b/effects/internal/exponentialfadetransition.cpp index 7c71d5bfc..be558d7cd 100644 --- a/effects/internal/exponentialfadetransition.cpp +++ b/effects/internal/exponentialfadetransition.cpp @@ -22,7 +22,7 @@ #include -ExponentialFadeTransition::ExponentialFadeTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {} +ExponentialFadeTransition::ExponentialFadeTransition(ClipPtr c, ClipPtr s, const EffectMeta* em) : Transition(c, s, em) {} void ExponentialFadeTransition::process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int type) { double interval = (timecode_end-timecode_start)/nb_bytes; diff --git a/effects/internal/exponentialfadetransition.h b/effects/internal/exponentialfadetransition.h index 36ec7f6f1..1fcca50bb 100644 --- a/effects/internal/exponentialfadetransition.h +++ b/effects/internal/exponentialfadetransition.h @@ -25,7 +25,7 @@ class ExponentialFadeTransition : public Transition { public: - ExponentialFadeTransition(Clip* c, Clip* s, const EffectMeta* em); + ExponentialFadeTransition(ClipPtr c, ClipPtr s, const EffectMeta* em); void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); }; diff --git a/effects/internal/fillleftrighteffect.cpp b/effects/internal/fillleftrighteffect.cpp index e6e687839..8d0326042 100644 --- a/effects/internal/fillleftrighteffect.cpp +++ b/effects/internal/fillleftrighteffect.cpp @@ -23,7 +23,7 @@ #define FILL_TYPE_LEFT 0 #define FILL_TYPE_RIGHT 1 -FillLeftRightEffect::FillLeftRightEffect(Clip* c, const EffectMeta *em) : Effect(c, em) { +FillLeftRightEffect::FillLeftRightEffect(ClipPtr c, const EffectMeta *em) : Effect(c, em) { EffectRow* type_row = add_row(tr("Type")); fill_type = type_row->add_field(EFFECT_FIELD_COMBO, "type"); fill_type->add_combo_item(tr("Fill Left with Right"), FILL_TYPE_LEFT); diff --git a/effects/internal/fillleftrighteffect.h b/effects/internal/fillleftrighteffect.h index 49e72c44a..d37f0d3e2 100644 --- a/effects/internal/fillleftrighteffect.h +++ b/effects/internal/fillleftrighteffect.h @@ -26,7 +26,7 @@ class FillLeftRightEffect : public Effect { Q_OBJECT public: - FillLeftRightEffect(Clip* c, const EffectMeta* em); + FillLeftRightEffect(ClipPtr c, const EffectMeta* em); void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); private: EffectField* fill_type; diff --git a/effects/internal/frei0reffect.cpp b/effects/internal/frei0reffect.cpp index efa393bb0..b2cf0c1a7 100644 --- a/effects/internal/frei0reffect.cpp +++ b/effects/internal/frei0reffect.cpp @@ -37,7 +37,7 @@ typedef void (*f0rGetPluginInfo)(f0r_plugin_info_t* info); typedef void (*f0rSetParamValue) (f0r_instance_t instance, f0r_param_t param, int param_index); -Frei0rEffect::Frei0rEffect(Clip *c, const EffectMeta *em) : +Frei0rEffect::Frei0rEffect(ClipPtr c, const EffectMeta *em) : Effect(c, em), open(false) { diff --git a/effects/internal/frei0reffect.h b/effects/internal/frei0reffect.h index daa546622..b197fff5a 100644 --- a/effects/internal/frei0reffect.h +++ b/effects/internal/frei0reffect.h @@ -35,7 +35,7 @@ typedef void (*f0rGetParamInfo)(f0r_param_info_t * info, class Frei0rEffect : public Effect { Q_OBJECT public: - Frei0rEffect(Clip* c, const EffectMeta* em); + Frei0rEffect(ClipPtr c, const EffectMeta* em); ~Frei0rEffect(); virtual void process_image(double timecode, uint8_t* input, uint8_t* output, int size); diff --git a/effects/internal/linearfadetransition.cpp b/effects/internal/linearfadetransition.cpp index 73ab8a44b..5cfb5edb7 100644 --- a/effects/internal/linearfadetransition.cpp +++ b/effects/internal/linearfadetransition.cpp @@ -20,7 +20,7 @@ #include "linearfadetransition.h" -LinearFadeTransition::LinearFadeTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {} +LinearFadeTransition::LinearFadeTransition(ClipPtr c, ClipPtr s, const EffectMeta* em) : Transition(c, s, em) {} void LinearFadeTransition::process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int type) { double interval = (timecode_end-timecode_start)/nb_bytes; diff --git a/effects/internal/linearfadetransition.h b/effects/internal/linearfadetransition.h index f3716753a..b4d2bbae3 100644 --- a/effects/internal/linearfadetransition.h +++ b/effects/internal/linearfadetransition.h @@ -25,7 +25,7 @@ class LinearFadeTransition : public Transition { public: - LinearFadeTransition(Clip* c, Clip* s, const EffectMeta* em); + LinearFadeTransition(ClipPtr c, ClipPtr s, const EffectMeta* em); void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); }; diff --git a/effects/internal/logarithmicfadetransition.cpp b/effects/internal/logarithmicfadetransition.cpp index 53cd4934c..4da914e9f 100644 --- a/effects/internal/logarithmicfadetransition.cpp +++ b/effects/internal/logarithmicfadetransition.cpp @@ -22,7 +22,7 @@ #include -LogarithmicFadeTransition::LogarithmicFadeTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {} +LogarithmicFadeTransition::LogarithmicFadeTransition(ClipPtr c, ClipPtr s, const EffectMeta* em) : Transition(c, s, em) {} void LogarithmicFadeTransition::process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int type) { double interval = (timecode_end-timecode_start)/nb_bytes; diff --git a/effects/internal/logarithmicfadetransition.h b/effects/internal/logarithmicfadetransition.h index a476351d1..66ac0014a 100644 --- a/effects/internal/logarithmicfadetransition.h +++ b/effects/internal/logarithmicfadetransition.h @@ -25,7 +25,7 @@ class LogarithmicFadeTransition : public Transition { public: - LogarithmicFadeTransition(Clip* c, Clip* s, const EffectMeta* em); + LogarithmicFadeTransition(ClipPtr c, ClipPtr s, const EffectMeta* em); void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); }; diff --git a/effects/internal/paneffect.cpp b/effects/internal/paneffect.cpp index babb0b01b..d3318838e 100644 --- a/effects/internal/paneffect.cpp +++ b/effects/internal/paneffect.cpp @@ -28,7 +28,7 @@ #include "ui/labelslider.h" #include "ui/collapsiblewidget.h" -PanEffect::PanEffect(Clip* c, const EffectMeta *em) : Effect(c, em) { +PanEffect::PanEffect(ClipPtr c, const EffectMeta *em) : Effect(c, em) { EffectRow* pan_row = add_row(tr("Pan")); pan_val = pan_row->add_field(EFFECT_FIELD_DOUBLE, "pan"); pan_val->set_double_minimum_value(-100); diff --git a/effects/internal/paneffect.h b/effects/internal/paneffect.h index f5cee94e0..8ac4c3903 100644 --- a/effects/internal/paneffect.h +++ b/effects/internal/paneffect.h @@ -26,7 +26,7 @@ class PanEffect : public Effect { Q_OBJECT public: - PanEffect(Clip* c, const EffectMeta* em); + PanEffect(ClipPtr c, const EffectMeta* em); void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); EffectField* pan_val; diff --git a/effects/internal/shakeeffect.cpp b/effects/internal/shakeeffect.cpp index 0960a0e74..275eabeea 100644 --- a/effects/internal/shakeeffect.cpp +++ b/effects/internal/shakeeffect.cpp @@ -33,7 +33,7 @@ #include "debug.h" -ShakeEffect::ShakeEffect(Clip *c, const EffectMeta *em) : Effect(c, em) { +ShakeEffect::ShakeEffect(ClipPtr c, const EffectMeta *em) : Effect(c, em) { enable_coords = true; EffectRow* intensity_row = add_row(tr("Intensity")); diff --git a/effects/internal/shakeeffect.h b/effects/internal/shakeeffect.h index ff969754a..b162ab3bf 100644 --- a/effects/internal/shakeeffect.h +++ b/effects/internal/shakeeffect.h @@ -28,7 +28,7 @@ class ShakeEffect : public Effect { Q_OBJECT public: - ShakeEffect(Clip* c, const EffectMeta* em); + ShakeEffect(ClipPtr c, const EffectMeta* em); void process_coords(double timecode, GLTextureCoords& coords, int data); EffectField* intensity_val; diff --git a/effects/internal/solideffect.cpp b/effects/internal/solideffect.cpp index a3077852b..cf09eee63 100644 --- a/effects/internal/solideffect.cpp +++ b/effects/internal/solideffect.cpp @@ -38,7 +38,7 @@ #define SMPTE_STRIP_COUNT 3 #define SMPTE_LOWER_BARS 4 -SolidEffect::SolidEffect(Clip* c, const EffectMeta* em) : Effect(c, em) { +SolidEffect::SolidEffect(ClipPtr c, const EffectMeta* em) : Effect(c, em) { enable_superimpose = true; solid_type = add_row(tr("Type"))->add_field(EFFECT_FIELD_COMBO, "type"); diff --git a/effects/internal/solideffect.h b/effects/internal/solideffect.h index 309098c58..66ad89a58 100644 --- a/effects/internal/solideffect.h +++ b/effects/internal/solideffect.h @@ -28,7 +28,7 @@ class SolidEffect : public Effect { Q_OBJECT public: - SolidEffect(Clip* c, const EffectMeta *em); + SolidEffect(ClipPtr c, const EffectMeta *em); void redraw(double timecode); private slots: void ui_update(int); diff --git a/effects/internal/texteffect.cpp b/effects/internal/texteffect.cpp index 3c4a88504..871a8b4c8 100644 --- a/effects/internal/texteffect.cpp +++ b/effects/internal/texteffect.cpp @@ -44,7 +44,7 @@ #include "io/config.h" #include "mainwindow.h" -TextEffect::TextEffect(Clip *c, const EffectMeta* em) : +TextEffect::TextEffect(ClipPtr c, const EffectMeta* em) : Effect(c, em) { enable_superimpose = true; diff --git a/effects/internal/texteffect.h b/effects/internal/texteffect.h index e07ea1695..0d6c89237 100644 --- a/effects/internal/texteffect.h +++ b/effects/internal/texteffect.h @@ -29,7 +29,7 @@ class TextEffect : public Effect { Q_OBJECT public: - TextEffect(Clip* c, const EffectMeta *em); + TextEffect(ClipPtr c, const EffectMeta *em); void redraw(double timecode); EffectField* text_val; diff --git a/effects/internal/timecodeeffect.cpp b/effects/internal/timecodeeffect.cpp index 16e012741..e8ba340f0 100644 --- a/effects/internal/timecodeeffect.cpp +++ b/effects/internal/timecodeeffect.cpp @@ -44,7 +44,7 @@ #include "io/config.h" #include "playback/playback.h" -TimecodeEffect::TimecodeEffect(Clip *c, const EffectMeta* em) : +TimecodeEffect::TimecodeEffect(ClipPtr c, const EffectMeta* em) : Effect(c, em) { enable_always_update = true; diff --git a/effects/internal/timecodeeffect.h b/effects/internal/timecodeeffect.h index 2caeb3276..8cae99a8b 100644 --- a/effects/internal/timecodeeffect.h +++ b/effects/internal/timecodeeffect.h @@ -29,7 +29,7 @@ class TimecodeEffect : public Effect { Q_OBJECT public: - TimecodeEffect(Clip* c, const EffectMeta *em); + TimecodeEffect(ClipPtr c, const EffectMeta *em); void redraw(double timecode); EffectField * scale_val; EffectField * color_val; diff --git a/effects/internal/toneeffect.cpp b/effects/internal/toneeffect.cpp index 777c3e878..112a700e4 100644 --- a/effects/internal/toneeffect.cpp +++ b/effects/internal/toneeffect.cpp @@ -28,7 +28,7 @@ #include "project/sequence.h" #include "debug.h" -ToneEffect::ToneEffect(Clip* c, const EffectMeta *em) : Effect(c, em), sinX(INT_MIN) { +ToneEffect::ToneEffect(ClipPtr c, const EffectMeta *em) : Effect(c, em), sinX(INT_MIN) { type_val = add_row(tr("Type"))->add_field(EFFECT_FIELD_COMBO, "type"); type_val->add_combo_item("Sine", TONE_TYPE_SINE); diff --git a/effects/internal/toneeffect.h b/effects/internal/toneeffect.h index fecef2c97..ec4e17622 100644 --- a/effects/internal/toneeffect.h +++ b/effects/internal/toneeffect.h @@ -26,7 +26,7 @@ class ToneEffect : public Effect { Q_OBJECT public: - ToneEffect(Clip *c, const EffectMeta* em); + ToneEffect(ClipPtr c, const EffectMeta* em); void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); EffectField* type_val; diff --git a/effects/internal/transformeffect.cpp b/effects/internal/transformeffect.cpp index 07dd08d3f..458d03e31 100644 --- a/effects/internal/transformeffect.cpp +++ b/effects/internal/transformeffect.cpp @@ -43,7 +43,7 @@ #include "panels/viewer.h" #include "ui/viewerwidget.h" -TransformEffect::TransformEffect(Clip* c, const EffectMeta* em) : Effect(c, em) { +TransformEffect::TransformEffect(ClipPtr c, const EffectMeta* em) : Effect(c, em) { enable_coords = true; EffectRow* position_row = add_row(tr("Position")); diff --git a/effects/internal/transformeffect.h b/effects/internal/transformeffect.h index 6a7d483f9..969f76fc6 100644 --- a/effects/internal/transformeffect.h +++ b/effects/internal/transformeffect.h @@ -26,7 +26,7 @@ class TransformEffect : public Effect { Q_OBJECT public: - TransformEffect(Clip* c, const EffectMeta* em); + TransformEffect(ClipPtr c, const EffectMeta* em); void refresh(); void process_coords(double timecode, GLTextureCoords& coords, int data); diff --git a/effects/internal/voideffect.cpp b/effects/internal/voideffect.cpp index 95acc9442..8a898d772 100644 --- a/effects/internal/voideffect.cpp +++ b/effects/internal/voideffect.cpp @@ -27,7 +27,7 @@ #include "ui/collapsiblewidget.h" #include "debug.h" -VoidEffect::VoidEffect(Clip *c, const QString& n) : Effect(c, nullptr) { +VoidEffect::VoidEffect(ClipPtr c, const QString& n) : Effect(c, nullptr) { name = n; QString display_name; if (n.isEmpty()) { @@ -43,8 +43,8 @@ VoidEffect::VoidEffect(Clip *c, const QString& n) : Effect(c, nullptr) { meta = &void_meta; } -Effect *VoidEffect::copy(Clip *c) { - Effect* copy = new VoidEffect(c, name); +EffectPtr VoidEffect::copy(ClipPtr c) { + EffectPtr copy(new VoidEffect(c, name)); copy->set_enabled(is_enabled()); copy_field_keyframes(copy); return copy; diff --git a/effects/internal/voideffect.h b/effects/internal/voideffect.h index 668713740..b30dd9a59 100644 --- a/effects/internal/voideffect.h +++ b/effects/internal/voideffect.h @@ -32,9 +32,9 @@ class VoidEffect : public Effect { Q_OBJECT public: - VoidEffect(Clip* c, const QString& n); + VoidEffect(ClipPtr c, const QString& n); - virtual Effect* copy(Clip* c) override; + virtual EffectPtr copy(ClipPtr c) override; virtual void load(QXmlStreamReader &stream) override; virtual void save(QXmlStreamWriter &stream) override; private: diff --git a/effects/internal/volumeeffect.cpp b/effects/internal/volumeeffect.cpp index 23cf1a45f..17caa6e36 100644 --- a/effects/internal/volumeeffect.cpp +++ b/effects/internal/volumeeffect.cpp @@ -28,7 +28,7 @@ #include "ui/labelslider.h" #include "ui/collapsiblewidget.h" -VolumeEffect::VolumeEffect(Clip* c, const EffectMeta *em) : Effect(c, em) { +VolumeEffect::VolumeEffect(ClipPtr c, const EffectMeta *em) : Effect(c, em) { EffectRow* volume_row = add_row(tr("Volume")); volume_val = volume_row->add_field(EFFECT_FIELD_DOUBLE, "volume"); diff --git a/effects/internal/volumeeffect.h b/effects/internal/volumeeffect.h index c5ca0ae93..c1e67b667 100644 --- a/effects/internal/volumeeffect.h +++ b/effects/internal/volumeeffect.h @@ -26,7 +26,7 @@ class VolumeEffect : public Effect { Q_OBJECT public: - VolumeEffect(Clip* c, const EffectMeta* em); + VolumeEffect(ClipPtr c, const EffectMeta* em); void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); EffectField* volume_val; diff --git a/effects/internal/vsthost.cpp b/effects/internal/vsthost.cpp index 02ecd3fdd..cecf6b0ee 100644 --- a/effects/internal/vsthost.cpp +++ b/effects/internal/vsthost.cpp @@ -252,7 +252,7 @@ void VSTHost::processAudio(long numFrames) { plugin->processReplacing(plugin, inputs, outputs, numFrames); } -VSTHost::VSTHost(Clip* c, const EffectMeta *em) : Effect(c, em) { +VSTHost::VSTHost(ClipPtr c, const EffectMeta *em) : Effect(c, em) { plugin = nullptr; inputs = new float* [CHANNEL_COUNT]; diff --git a/effects/internal/vsthost.h b/effects/internal/vsthost.h index 752f0b7b3..4bcd6e818 100644 --- a/effects/internal/vsthost.h +++ b/effects/internal/vsthost.h @@ -37,7 +37,7 @@ typedef intptr_t (*dispatcherFuncPtr)(AEffect *effect, int32_t opCode, int32_t i class VSTHost : public Effect { Q_OBJECT public: - VSTHost(Clip* c, const EffectMeta* em); + VSTHost(ClipPtr c, const EffectMeta* em); ~VSTHost(); void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); diff --git a/io/clipboard.cpp b/io/clipboard.cpp index 3af4db829..cd5de7902 100644 --- a/io/clipboard.cpp +++ b/io/clipboard.cpp @@ -25,21 +25,10 @@ #include "project/transition.h" int clipboard_type = CLIPBOARD_TYPE_CLIP; -QVector clipboard; -QVector clipboard_transitions; +QVector clipboard; +QVector clipboard_transitions; void clear_clipboard() { - int clipboard_size = clipboard.size(); - for (int i=0;i(clipboard.at(i)); - } else if (clipboard_type == CLIPBOARD_TYPE_EFFECT) { - delete static_cast(clipboard.at(i)); - } - } - clipboard_size = clipboard_transitions.size(); - for (int i=0;i; + extern int clipboard_type; -extern QVector clipboard_transitions; -extern QVector clipboard; +extern QVector clipboard_transitions; +extern QVector clipboard; void clear_clipboard(); #endif // CLIPBOARD_H diff --git a/io/loadthread.cpp b/io/loadthread.cpp index 906d8af41..741453853 100644 --- a/io/loadthread.cpp +++ b/io/loadthread.cpp @@ -41,12 +41,12 @@ LoadThread::LoadThread(bool a) : 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_dual_transition(const TransitionData*,Clip*,Clip*,const EffectMeta*)), this, SLOT(create_dual_transition(const TransitionData*,Clip*,Clip*,const EffectMeta*))); - connect(this, SIGNAL(start_create_effect_ui(QXmlStreamReader*, Clip*, int, const QString*, const EffectMeta*, long, bool)), this, SLOT(create_effect_ui(QXmlStreamReader*, Clip*, int, const QString*, const EffectMeta*, long, bool))); + connect(this, SIGNAL(start_create_dual_transition(const TransitionData*,ClipPtr,ClipPtr,const EffectMeta*)), this, SLOT(create_dual_transition(const TransitionData*,ClipPtr,ClipPtr,const EffectMeta*))); + connect(this, SIGNAL(start_create_effect_ui(QXmlStreamReader*, ClipPtr, int, const QString*, const EffectMeta*, long, bool)), this, SLOT(create_effect_ui(QXmlStreamReader*, ClipPtr, int, const QString*, const EffectMeta*, long, bool))); connect(this, SIGNAL(start_question(const QString&, const QString &, int)), this, SLOT(question_func(const QString &, const QString &, int))); } -void LoadThread::load_effect(QXmlStreamReader& stream, Clip* c) { +void LoadThread::load_effect(QXmlStreamReader& stream, ClipPtr c) { int effect_id = -1; QString effect_name; bool effect_enabled = true; @@ -194,7 +194,7 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) { int folder = 0; Media* item = new Media(0); - Footage* f = new Footage(); + FootagePtr f(new Footage()); f->using_inout = false; @@ -300,7 +300,7 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) { case MEDIA_TYPE_SEQUENCE: { Media* parent = nullptr; - Sequence* s = new Sequence(); + SequencePtr s(new Sequence()); // load attributes about sequence for (int j=0;jautoscale = false; @@ -428,7 +428,7 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) { case MEDIA_TYPE_FOOTAGE: if (media_id >= 0) { for (int j=0;jto_footage(); + FootagePtr m = loaded_media_items.at(j)->to_footage(); if (m->save_id == media_id) { c->media = loaded_media_items.at(j); c->media_stream = stream_id; @@ -487,7 +487,7 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) { // correct links, clip IDs, transitions for (int i=0;iclips.size();i++) { // correct links - Clip* correct_clip = s->clips.at(i); + ClipPtr correct_clip = s->clips.at(i); for (int j=0;jlinked.size();j++) { bool found = false; for (int k=0;kclips.size();k++) { @@ -508,7 +508,7 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) { ); waitCond.wait(&mutex); if (question_btn == QMessageBox::No) { - delete s; + s.reset(); return false; } } @@ -534,8 +534,8 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) { // create transitions for (int i=0;iset_enabled(effect_enabled); ve->load(*stream); c->effects.append(ve); } else { - Effect* e = create_effect(c, meta); + EffectPtr e(create_effect(c, meta)); e->set_enabled(effect_enabled); e->load(*stream); @@ -808,7 +808,7 @@ void LoadThread::create_effect_ui( } } else { int transition_index = create_transition(c, nullptr, meta); - Transition* t = c->sequence->transitions.at(transition_index); + TransitionPtr t = c->sequence->transitions.at(transition_index); if (effect_length > -1) t->set_length(effect_length); t->set_enabled(effect_enabled); t->load(*stream); @@ -825,7 +825,7 @@ void LoadThread::create_effect_ui( waitCond.wakeAll(); } -void LoadThread::create_dual_transition(const TransitionData* td, Clip* primary, Clip* secondary, const EffectMeta* meta) { +void LoadThread::create_dual_transition(const TransitionData* td, ClipPtr primary, ClipPtr secondary, const EffectMeta* meta) { // lock mutex - ensures the load thread is suspended while this happens mutex.lock(); diff --git a/io/loadthread.h b/io/loadthread.h index 3b51715e9..73ea66951 100644 --- a/io/loadthread.h +++ b/io/loadthread.h @@ -34,8 +34,8 @@ struct TransitionData { int id; QString name; long length; - Clip* otc; - Clip* ctc; + ClipPtr otc; + ClipPtr ctc; }; class LoadThread : public QThread @@ -49,26 +49,26 @@ signals: void start_question(const QString &title, const QString &text, int buttons); void success(); void error(); - void start_create_effect_ui(QXmlStreamReader* stream, Clip* c, int type, const QString *effect_name, const EffectMeta* meta, long effect_length, bool effect_enabled); - void start_create_dual_transition(const TransitionData* td, Clip* primary, Clip* secondary, const EffectMeta* meta); + void start_create_effect_ui(QXmlStreamReader* stream, ClipPtr c, int type, const QString *effect_name, const EffectMeta* meta, long effect_length, bool effect_enabled); + void start_create_dual_transition(const TransitionData* td, ClipPtr primary, ClipPtr secondary, const EffectMeta* meta); void report_progress(int p); private slots: void question_func(const QString &title, const QString &text, int buttons); void error_func(); void success_func(); - void create_effect_ui(QXmlStreamReader* stream, Clip* c, int type, const QString *effect_name, const EffectMeta* meta, long effect_length, bool effect_enabled); - void create_dual_transition(const TransitionData* td, Clip* primary, Clip* secondary, const EffectMeta* meta); + void create_effect_ui(QXmlStreamReader* stream, ClipPtr c, int type, const QString *effect_name, const EffectMeta* meta, long effect_length, bool effect_enabled); + void create_dual_transition(const TransitionData* td, ClipPtr primary, ClipPtr secondary, const EffectMeta* meta); private: bool autorecovery; bool load_worker(QFile& f, QXmlStreamReader& stream, int type); - void load_effect(QXmlStreamReader& stream, Clip* c); + void load_effect(QXmlStreamReader& stream, ClipPtr c); void read_next(QXmlStreamReader& stream); void read_next_start_element(QXmlStreamReader& stream); void update_current_element_count(QXmlStreamReader& stream); - Sequence* open_seq; + SequencePtr open_seq; QVector loaded_media_items; QDir proj_dir; QDir internal_proj_dir; @@ -79,7 +79,7 @@ private: bool is_element(QXmlStreamReader& stream); QVector loaded_folders; - QVector loaded_clips; + QVector loaded_clips; QVector loaded_sequences; Media* find_loaded_folder_by_id(int id); diff --git a/io/previewgenerator.cpp b/io/previewgenerator.cpp index 8569af840..36c0e644c 100644 --- a/io/previewgenerator.cpp +++ b/io/previewgenerator.cpp @@ -38,7 +38,7 @@ QSemaphore sem(5); // only 5 preview generators can run at one time -PreviewGenerator::PreviewGenerator(Media* i, Footage* m, bool r) : +PreviewGenerator::PreviewGenerator(Media* i, FootagePtr m, bool r) : QThread(nullptr), fmt_ctx(nullptr), media(i), @@ -48,8 +48,7 @@ PreviewGenerator::PreviewGenerator(Media* i, Footage* m, bool r) : replace(r), cancelled(false) { - data_path = get_data_path() + "/previews"; - QDir data_dir(data_path); + data_dir = QDir(get_data_dir().filePath("previews")); if (!data_dir.exists()) { data_dir.mkpath("."); } @@ -506,11 +505,11 @@ void PreviewGenerator::generate_waveform() { } QString PreviewGenerator::get_thumbnail_path(const QString& hash, const FootageStream& ms) { - return data_path + "/" + hash + "t" + QString::number(ms.file_index); + return data_dir.filePath(QString("%1t%2").arg(hash, QString::number(ms.file_index))); } QString PreviewGenerator::get_waveform_path(const QString& hash, const FootageStream& ms) { - return data_path + "/" + hash + "w" + QString::number(ms.file_index); + return data_dir.filePath(QString("%1w%2").arg(hash, QString::number(ms.file_index))); } void PreviewGenerator::run() { diff --git a/io/previewgenerator.h b/io/previewgenerator.h index a1b5d5252..40af8f64d 100644 --- a/io/previewgenerator.h +++ b/io/previewgenerator.h @@ -23,6 +23,7 @@ #include #include +#include enum IconType { ICON_TYPE_VIDEO, @@ -45,7 +46,7 @@ class PreviewGenerator : public QThread { Q_OBJECT public: - PreviewGenerator(Media*, Footage*, bool); + PreviewGenerator(Media*, FootagePtr, bool); void run(); void cancel(); signals: @@ -57,12 +58,12 @@ private: void finalize_media(); AVFormatContext* fmt_ctx; Media* media; - Footage* footage; + FootagePtr footage; bool retrieve_duration; bool contains_still_image; bool replace; - bool cancelled; - QString data_path; + bool cancelled; + QDir data_dir; QString get_thumbnail_path(const QString &hash, const FootageStream &ms); QString get_waveform_path(const QString& hash, const FootageStream &ms); }; diff --git a/io/proxygenerator.cpp b/io/proxygenerator.cpp index 640433e42..f59be37c2 100644 --- a/io/proxygenerator.cpp +++ b/io/proxygenerator.cpp @@ -399,7 +399,7 @@ void ProxyGenerator::cancel() { wait(); } -double ProxyGenerator::get_proxy_progress(Footage *f) { +double ProxyGenerator::get_proxy_progress(FootagePtr f) { if (proxy_queue.first().footage == f) { return current_progress; } diff --git a/io/proxygenerator.h b/io/proxygenerator.h index b8afeb379..a85e8c9ed 100644 --- a/io/proxygenerator.h +++ b/io/proxygenerator.h @@ -29,7 +29,7 @@ #include "project/footage.h" struct ProxyInfo { - Footage* footage; + FootagePtr footage; double size_multiplier; int codec_type; QString path; @@ -42,7 +42,7 @@ public: void run(); void queue(const ProxyInfo& info); void cancel(); - double get_proxy_progress(Footage* f); + double get_proxy_progress(FootagePtr f); private: // queue of footage to process proxies for QVector proxy_queue; diff --git a/main.cpp b/main.cpp index 3e2307b24..2976ef578 100644 --- a/main.cpp +++ b/main.cpp @@ -32,7 +32,7 @@ extern "C" { #include } -int main(int argc, char *argv[]) { +int main(int argc, char *argv[]) { olive::Global = std::unique_ptr(new OliveGlobal); bool launch_fullscreen = false; diff --git a/mainwindow.cpp b/mainwindow.cpp index c2d6124ee..6eedb0426 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -64,6 +64,8 @@ #include #include +Q_DECLARE_METATYPE(ClipPtr); + MainWindow* olive::MainWindow; #define DEFAULT_CSS "QPushButton::checked { background: rgb(25, 25, 25); }" @@ -100,6 +102,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), first_show(true) { + qRegisterMetaType(); + init_custom_cursors(); open_debug_file(); diff --git a/olive.pro b/olive.pro index f75aacc71..dc68ad4ef 100644 --- a/olive.pro +++ b/olive.pro @@ -148,7 +148,8 @@ SOURCES += \ ui/cursors.cpp \ ui/menuhelper.cpp \ oliveglobal.cpp \ - ui/focusfilter.cpp + ui/focusfilter.cpp \ + project/comboaction.cpp HEADERS += \ mainwindow.h \ @@ -254,7 +255,8 @@ HEADERS += \ ui/menuhelper.h \ oliveglobal.h \ project/projectelements.h \ - ui/focusfilter.h + ui/focusfilter.h \ + project/comboaction.h FORMS += diff --git a/oliveglobal.cpp b/oliveglobal.cpp index c49f26da2..26c686899 100644 --- a/oliveglobal.cpp +++ b/oliveglobal.cpp @@ -295,7 +295,7 @@ void OliveGlobal::open_speed_dialog() { if (olive::ActiveSequence != nullptr) { SpeedDialog s(olive::MainWindow); for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { s.clips.append(c); } diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp index 4c4e3875d..c052daed2 100644 --- a/panels/effectcontrols.cpp +++ b/panels/effectcontrols.cpp @@ -100,7 +100,7 @@ void EffectControls::set_zoom(bool in) { void EffectControls::menu_select(QAction* q) { ComboAction* ca = new ComboAction(); for (int i=0;iclips.at(selected_clips.at(i)); + const ClipPtr& c = olive::ActiveSequence->clips.at(selected_clips.at(i)); if ((c->track < 0) == (effect_menu_subtype == EFFECT_TYPE_VIDEO)) { const EffectMeta* meta = reinterpret_cast(q->data().value()); if (effect_menu_type == EFFECT_TYPE_TRANSITION) { @@ -140,9 +140,9 @@ void EffectControls::copy(bool del) { ComboAction* ca = new ComboAction(); EffectDeleteCommand* del_com = (del) ? new EffectDeleteCommand() : nullptr; for (int i=0;iclips.at(selected_clips.at(i)); + const ClipPtr& c = olive::ActiveSequence->clips.at(selected_clips.at(i)); for (int j=0;jeffects.size();j++) { - Effect* effect = c->effects.at(j); + EffectPtr effect = c->effects.at(j); if (effect->container->selected) { if (!cleared) { clear_clipboard(); @@ -150,7 +150,7 @@ void EffectControls::copy(bool del) { clipboard_type = CLIPBOARD_TYPE_EFFECT; } - clipboard.append(effect->copy(nullptr)); + clipboard.append(EffectPtr(effect->copy(nullptr))); if (del_com != nullptr) { del_com->clips.append(c); @@ -176,7 +176,7 @@ void EffectControls::scroll_to_frame(long frame) { void EffectControls::add_effect_paste_action(QMenu *menu) { QAction* paste_action = menu->addAction(tr("&Paste"), panel_timeline, SLOT(paste(bool))); - paste_action->setEnabled(clipboard.size() > 0 && clipboard_type == CLIPBOARD_TYPE_EFFECT); + paste_action->setEnabled(clipboard.size() > 0 && clipboard_type == CLIPBOARD_TYPE_EFFECT); } void EffectControls::cut() { @@ -282,7 +282,7 @@ void EffectControls::clear_effects(bool clear_cache) { void EffectControls::deselect_all_effects(QWidget* sender) { for (int i=0;iclips.at(selected_clips.at(i)); + const ClipPtr& c = olive::ActiveSequence->clips.at(selected_clips.at(i)); for (int j=0;jeffects.size();j++) { if (c->effects.at(j)->container != sender) { c->effects.at(j)->container->header_click(false, false); @@ -292,7 +292,7 @@ void EffectControls::deselect_all_effects(QWidget* sender) { panel_sequence_viewer->viewer_widget->update(); } -void EffectControls::open_effect(QVBoxLayout* layout, Effect* e) { +void EffectControls::open_effect(QVBoxLayout* layout, EffectPtr e) { CollapsibleWidget* container = e->container; layout->addWidget(container); connect(container, SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); @@ -505,7 +505,7 @@ void EffectControls::load_effects() { if (!multiple) { // load in new clips for (int i=0;iclips.at(selected_clips.at(i)); + ClipPtr c = olive::ActiveSequence->clips.at(selected_clips.at(i)); QVBoxLayout* layout; if (c->track < 0) { vcontainer->setVisible(true); @@ -539,9 +539,9 @@ void EffectControls::delete_effects() { if (mode == TA_NO_TRANSITION) { EffectDeleteCommand* command = new EffectDeleteCommand(); for (int i=0;iclips.at(selected_clips.at(i)); + ClipPtr c = olive::ActiveSequence->clips.at(selected_clips.at(i)); for (int j=0;jeffects.size();j++) { - Effect* effect = c->effects.at(j); + EffectPtr effect = c->effects.at(j); if (effect->container->selected) { command->clips.append(c); command->fx.append(j); @@ -595,7 +595,7 @@ void EffectControls::resizeEvent(QResizeEvent*) { bool EffectControls::is_focused() { if (this->hasFocus()) return true; for (int i=0;iclips.at(selected_clips.at(i)); + ClipPtr c = olive::ActiveSequence->clips.at(selected_clips.at(i)); if (c != nullptr) { for (int j=0;jeffects.size();j++) { if (c->effects.at(j)->container->is_focused()) { diff --git a/panels/effectcontrols.h b/panels/effectcontrols.h index dc2156264..aee0c8f73 100644 --- a/panels/effectcontrols.h +++ b/panels/effectcontrols.h @@ -100,7 +100,7 @@ private: void show_effect_menu(int type, int subtype); void load_effects(); void load_keyframes(); - void open_effect(QVBoxLayout* hlayout, Effect* e); + void open_effect(QVBoxLayout* hlayout, EffectPtr e); void setup_ui(); diff --git a/panels/panels.cpp b/panels/panels.cpp index 5b3d81059..4f8e3e0f2 100644 --- a/panels/panels.cpp +++ b/panels/panels.cpp @@ -50,7 +50,7 @@ void update_effect_controls() { int mode = TA_NO_TRANSITION; if (olive::ActiveSequence != nullptr) { for (int i=0;iclips.size();i++) { - Clip* clip = olive::ActiveSequence->clips.at(i); + ClipPtr clip = olive::ActiveSequence->clips.at(i); if (clip != nullptr) { for (int j=0;jselections.size();j++) { const Selection& s = olive::ActiveSequence->selections.at(j); @@ -88,7 +88,7 @@ void update_effect_controls() { if (aclip >= 0) selected_clips.append(aclip); if (vclip >= 0 && aclip >= 0) { bool found = false; - Clip* vclip_ref = olive::ActiveSequence->clips.at(vclip); + ClipPtr vclip_ref = olive::ActiveSequence->clips.at(vclip); for (int i=0;ilinked.size();i++) { if (vclip_ref->linked.at(i) == aclip) { found = true; diff --git a/panels/project.cpp b/panels/project.cpp index 7b7cc3f27..c95a0f5ed 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -22,6 +22,7 @@ #include "oliveglobal.h" +#include "panels.h" #include "playback/playback.h" #include "io/previewgenerator.h" #include "project/undo.h" @@ -257,10 +258,10 @@ QString Project::get_next_sequence_name(QString start) { return name; } -Sequence* create_sequence_from_media(QVector& media_list) { - Sequence* s = new Sequence(); +SequencePtr create_sequence_from_media(QVector& media_list) { + SequencePtr s(new Sequence()); - s->name = panel_project->get_next_sequence_name(); + s->name = panel_project->get_next_sequence_name(); // shitty hardcoded default values s->width = 1920; @@ -272,11 +273,11 @@ Sequence* create_sequence_from_media(QVector& media_list) { bool got_video_values = false; bool got_audio_values = false; for (int i=0;iget_type()) { case MEDIA_TYPE_FOOTAGE: { - Footage* m = media->to_footage(); + FootagePtr m = media->to_footage(); if (m->ready) { if (!got_video_values) { for (int j=0;jvideo_tracks.size();j++) { @@ -304,7 +305,7 @@ Sequence* create_sequence_from_media(QVector& media_list) { break; case MEDIA_TYPE_SEQUENCE: { - Sequence* seq = media->to_sequence(); + SequencePtr seq = media->to_sequence(); s->width = seq->width; s->height = seq->height; s->frame_rate = seq->frame_rate; @@ -327,7 +328,7 @@ void Project::duplicate_selected() { bool duped = false; ComboAction* ca = new ComboAction(); for (int j=0;jget_type() == MEDIA_TYPE_SEQUENCE) { create_sequence_internal(ca, i->to_sequence()->copy(), false, item_to_media(items.at(j).parent())); duped = true; @@ -343,7 +344,7 @@ void Project::duplicate_selected() { void Project::replace_selected_file() { QModelIndexList selected_items = get_current_selected(); if (selected_items.size() == 1) { - Media* item = item_to_media(selected_items.at(0)); + Media* item = item_to_media(selected_items.at(0)); if (item->get_type() == MEDIA_TYPE_FOOTAGE) { replace_media(item, nullptr); } @@ -373,7 +374,7 @@ void Project::replace_clip_media() { } else { QModelIndexList selected_items = get_current_selected(); if (selected_items.size() == 1) { - Media* item = item_to_media(selected_items.at(0)); + Media* item = item_to_media(selected_items.at(0)); if (item->get_type() == MEDIA_TYPE_SEQUENCE && olive::ActiveSequence == item->to_sequence()) { QMessageBox::critical(this, tr("Active sequence selected"), @@ -390,7 +391,7 @@ void Project::replace_clip_media() { void Project::open_properties() { QModelIndexList selected_items = get_current_selected(); if (selected_items.size() == 1) { - Media* item = item_to_media(selected_items.at(0)); + Media* item = item_to_media(selected_items.at(0)); switch (item->get_type()) { case MEDIA_TYPE_FOOTAGE: { @@ -438,13 +439,16 @@ void Project::new_folder() { void Project::new_sequence() { NewSequenceDialog nsd(this); - nsd.set_sequence_name(panel_project->get_next_sequence_name()); + nsd.set_sequence_name(get_next_sequence_name()); nsd.exec(); } -Media* Project::create_sequence_internal(ComboAction *ca, Sequence *s, bool open, Media* parent) { - if (parent == nullptr) parent = project_model.get_root(); - Media* item = new Media(parent); +Media* Project::create_sequence_internal(ComboAction *ca, SequencePtr s, bool open, Media* parent) { + if (parent == nullptr) { + parent = project_model.get_root(); + } + + Media* item(new Media(parent)); item->set_sequence(s); if (ca != nullptr) { @@ -466,7 +470,7 @@ QString Project::get_file_name_from_path(const QString& path) { } /*Media* Project::new_item() { - Media* item = new Media(0); + Media* item = new Media(0); //item->setFlags(item->flags() | Qt::ItemIsEditable); return item; }*/ @@ -476,22 +480,22 @@ bool Project::is_focused() { } Media* Project::create_folder_internal(QString name) { - Media* item = new Media(nullptr); + Media* item = new Media(nullptr); item->set_folder(); item->set_name(name); return item; } Media *Project::item_to_media(const QModelIndex &index) { - return static_cast(sorter->mapToSource(index).internalPointer()); + return static_cast(sorter->mapToSource(index).internalPointer()); // return static_cast(index.internalPointer()); } void Project::get_all_media_from_table(QList& items, QList& list, int search_type) { for (int i=0;iget_type() == MEDIA_TYPE_FOLDER) { - QList children; + QList children; for (int j=0;jchildCount();j++) { children.append(item->child(j)); } @@ -505,8 +509,8 @@ void Project::get_all_media_from_table(QList& items, QList& list bool delete_clips_in_clipboard_with_media(ComboAction* ca, Media* m) { int delete_count = 0; if (clipboard_type == CLIPBOARD_TYPE_CLIP) { - for (int i=0;i(clipboard.at(i)); + for (int i=0;i(clipboard.at(i)); if (c->media == m) { ca->append(new RemoveClipsFromClipboard(i-delete_count)); delete_count++; @@ -519,7 +523,7 @@ bool delete_clips_in_clipboard_with_media(ComboAction* ca, Media* m) { void Project::delete_selected_media() { ComboAction* ca = new ComboAction(); QModelIndexList selected_items = get_current_selected(); - QList items; + QList items; for (int i=0;i parents; - QList sequence_items; - QList all_top_level_items; + QVector parents; + QList sequence_items; + QList all_top_level_items; for (int i=0;i 0) { - QList media_items; + QList media_items; get_all_media_from_table(items, media_items, MEDIA_TYPE_FOOTAGE); for (int i=0;ito_footage(); + Media* item = media_items.at(i); + FootagePtr media = item->to_footage(); bool confirm_delete = false; for (int j=0;jto_sequence(); + SequencePtr s = sequence_items.at(j)->to_sequence(); for (int k=0;kclips.size();k++) { - Clip* c = s->clips.at(k); - if (c != nullptr && c->media == item) { + ClipPtr c = s->clips.at(k); + if (c != nullptr && c->media == item) { if (!confirm_delete) { // we found a reference, so we know we'll need to ask if the user wants to delete it QMessageBox confirm(this); @@ -562,13 +566,13 @@ void Project::delete_selected_media() { redraw = true; } else if (confirm.clickedButton() == skip_button) { // remove media item and any folders containing it from the remove list - Media* parent = item; + Media* parent = item; while (parent != nullptr) { parents.append(parent); // re-add item's siblings for (int m=0;mchildCount();m++) { - Media* child = parent->child(m); + Media* child = parent->child(m); bool found = false; for (int n=0;nget_type() == MEDIA_TYPE_SEQUENCE) { redraw = true; - Sequence* s = items.at(i)->to_sequence(); + SequencePtr s = items.at(i)->to_sequence(); if (s == olive::ActiveSequence) { ca->append(new ChangeSequenceAction(nullptr)); @@ -640,8 +644,8 @@ void Project::delete_selected_media() { } else if (items.at(i)->get_type() == MEDIA_TYPE_FOOTAGE) { if (panel_footage_viewer->seq != nullptr) { for (int j=0;jseq->clips.size();j++) { - Clip* c = panel_footage_viewer->seq->clips.at(j); - if (c != nullptr && c->media == items.at(i)) { + ClipPtr c = panel_footage_viewer->seq->clips.at(j); + if (c != nullptr && c->media == items.at(i)) { panel_footage_viewer->set_media(nullptr); break; } @@ -689,7 +693,7 @@ void Project::process_file_list(QStringList& files, bool recursive, Media* repla for (int i=0;ireset(); } else { item = new Media(parent); - m = new Footage(); + m = FootagePtr(new Footage()); } m->using_inout = false; @@ -842,7 +846,7 @@ Media* Project::get_selected_folder() { // if one item is selected and it's a folder, return it QModelIndexList selected_items = get_current_selected(); if (selected_items.size() == 1) { - Media* m = item_to_media(selected_items.at(0)); + Media* m = item_to_media(selected_items.at(0)); if (m->get_type() == MEDIA_TYPE_FOLDER) return m; } return nullptr; @@ -851,7 +855,7 @@ Media* Project::get_selected_folder() { bool Project::reveal_media(Media *media, QModelIndex parent) { for (int i=0;iget_type() == MEDIA_TYPE_FOLDER) { @@ -923,10 +927,10 @@ void Project::delete_clips_using_selected_media() { bool deleted = false; QModelIndexList items = get_current_selected(); for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + const ClipPtr& c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { for (int j=0;jmedia == m) { ca->append(new DeleteClipAction(olive::ActiveSequence, i)); deleted = true; @@ -935,7 +939,7 @@ void Project::delete_clips_using_selected_media() { } } for (int j=0;jclear_effects(true); // delete sequences first because it's important to close all the clips before deleting the media - QVector sequences = list_all_project_sequences(); + QVector sequences = list_all_project_sequences(); for (int i=0;ito_sequence(); + sequences.at(i)->to_sequence().reset(); sequences.at(i)->set_sequence(nullptr); } @@ -962,7 +966,7 @@ void Project::clear() { project_model.clear(); // update tree view (sometimes this doesn't seem to update reliably) - panel_project->tree_view->update(); + tree_view->update(); } void Project::new_project() { @@ -990,7 +994,7 @@ void save_marker(QXmlStreamWriter& stream, const Marker& m) { void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, const QModelIndex& parent) { for (int i=0;iget_type()) { if (m->get_type() == MEDIA_TYPE_FOLDER) { @@ -1013,7 +1017,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, } else { int folder = m->parentItem()->temp_id; if (type == MEDIA_TYPE_FOOTAGE) { - Footage* f = m->to_footage(); + FootagePtr f = m->to_footage(); f->save_id = media_id; stream.writeStartElement("footage"); stream.writeAttribute("id", QString::number(media_id)); @@ -1061,7 +1065,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, stream.writeEndElement(); // footage media_id++; } else if (type == MEDIA_TYPE_SEQUENCE) { - Sequence* s = m->to_sequence(); + SequencePtr s = m->to_sequence(); if (set_ids_only) { s->save_id = sequence_id; sequence_id++; @@ -1083,7 +1087,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, stream.writeAttribute("workareaOut", QString::number(s->workarea_out)); for (int j=0;jtransitions.size();j++) { - Transition* t = s->transitions.at(j); + TransitionPtr t = s->transitions.at(j); if (t != nullptr) { stream.writeStartElement("transition"); stream.writeAttribute("id", QString::number(j)); @@ -1094,7 +1098,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, } for (int j=0;jclips.size();j++) { - Clip* c = s->clips.at(j); + const ClipPtr& c = s->clips.at(j); if (c != nullptr) { stream.writeStartElement("clip"); // clip stream.writeAttribute("id", QString::number(j)); @@ -1305,7 +1309,7 @@ void Project::add_recent_project(QString url) { void Project::list_all_sequences_worker(QVector* list, Media* parent) { for (int i=0;iget_type()) { case MEDIA_TYPE_SEQUENCE: list->append(item); @@ -1318,16 +1322,16 @@ void Project::list_all_sequences_worker(QVector* list, Media* parent) { } QVector Project::list_all_project_sequences() { - QVector list; + QVector list; list_all_sequences_worker(&list, nullptr); return list; } QModelIndexList Project::get_current_selected() { if (olive::CurrentConfig.project_view_type == PROJECT_VIEW_TREE) { - return panel_project->tree_view->selectionModel()->selectedRows(); + return tree_view->selectionModel()->selectedRows(); } - return panel_project->icon_view->selectionModel()->selectedIndexes(); + return icon_view->selectionModel()->selectedIndexes(); } #define THROBBER_LIMIT 20 @@ -1366,11 +1370,11 @@ void MediaThrobber::stop(int icon_type, bool replace) { } // refresh all clips - QVector sequences = panel_project->list_all_project_sequences(); + QVector sequences = panel_project->list_all_project_sequences(); for (int i=0;ito_sequence(); + SequencePtr s = sequences.at(i)->to_sequence(); for (int j=0;jclips.size();j++) { - Clip* c = s->clips.at(j); + const ClipPtr& c = s->clips.at(j); if (c != nullptr) { c->refresh(); } @@ -1380,7 +1384,7 @@ void MediaThrobber::stop(int icon_type, bool replace) { // redraw clips update_ui(replace); - panel_project->tree_view->viewport()->update(); + panel_project->tree_view->viewport()->update(); item->throbber = nullptr; deleteLater(); } diff --git a/panels/project.h b/panels/project.h index 581fa1780..5a073f455 100644 --- a/panels/project.h +++ b/panels/project.h @@ -37,8 +37,6 @@ #include "project/sourcescommon.h" #include "ui/sourceiconview.h" -#include "panels.h" - #include "ui/sourcetable.h" #define LOAD_TYPE_VERSION 69 @@ -48,7 +46,7 @@ extern QString autorecovery_filename; extern QStringList recent_projects; extern ProjectModel project_model; -Sequence* create_sequence_from_media(QVector &media_list); +SequencePtr create_sequence_from_media(QVector &media_list); QString get_channel_layout_name(int channels, uint64_t layout); QString get_interlacing_name(int interlacing); @@ -56,15 +54,15 @@ QString get_interlacing_name(int interlacing); class Project : public QDockWidget { Q_OBJECT public: - explicit Project(QWidget *parent = 0); + explicit Project(QWidget *parent = nullptr); ~Project(); bool is_focused(); void clear(); - Media* create_sequence_internal(ComboAction *ca, Sequence* s, bool open, Media* parent); - QString get_next_sequence_name(QString start = 0); - void process_file_list(QStringList& files, bool recursive = false, Media* replace = nullptr, Media *parent = nullptr); - void replace_media(Media* item, QString filename); - Media *get_selected_folder(); + Media* create_sequence_internal(ComboAction *ca, SequencePtr s, bool open, Media* parent); + QString get_next_sequence_name(QString start = nullptr); + void process_file_list(QStringList& files, bool recursive = false, Media* replace = nullptr, Media *parent = nullptr); + void replace_media(Media* item, QString filename); + Media* get_selected_folder(); bool reveal_media(Media *media, QModelIndex parent = QModelIndex()); void add_recent_project(QString url); @@ -72,12 +70,12 @@ public: void load_project(bool autorecovery); void save_project(bool autorecovery); - Media* create_folder_internal(QString name); - Media* item_to_media(const QModelIndex& index); + Media* create_folder_internal(QString name); + Media* item_to_media(const QModelIndex& index); void save_recent_projects(); - QVector list_all_project_sequences(); + QVector list_all_project_sequences(); SourceTable* tree_view; SourceIconView* icon_view; @@ -85,11 +83,11 @@ public: ProjectFilter* sorter; - QVector last_imported_media; + QVector last_imported_media; QModelIndexList get_current_selected(); - void start_preview_generator(Media* item, bool replacing); + void start_preview_generator(Media* item, bool replacing); void get_all_media_from_table(QList &items, QList &list, int type = -1); QWidget* toolbar_widget; @@ -108,7 +106,7 @@ private: int folder_id; int media_id; int sequence_id; - void list_all_sequences_worker(QVector *list, Media* parent); + void list_all_sequences_worker(QVector *list, Media* parent); QString get_file_name_from_path(const QString &path); QDir proj_dir; QWidget* icon_view_container; @@ -127,7 +125,7 @@ private slots: class MediaThrobber : public QObject { Q_OBJECT public: - MediaThrobber(Media*); + MediaThrobber(Media*); public slots: void start(); void stop(int, bool replace); @@ -136,7 +134,7 @@ private slots: private: QPixmap pixmap; int animation; - Media* item; + Media* item; QTimer* animator; }; diff --git a/panels/timeline.cpp b/panels/timeline.cpp index c1decbdd8..c8349a387 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -122,7 +122,7 @@ void Timeline::previous_cut() { && olive::ActiveSequence->playhead > 0) { long p_cut = 0; for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { if (c->timeline_out > p_cut && c->timeline_out < olive::ActiveSequence->playhead) { p_cut = c->timeline_out; @@ -140,7 +140,7 @@ void Timeline::next_cut() { bool seek_enabled = false; long n_cut = LONG_MAX; for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { if (c->timeline_in < n_cut && c->timeline_in > olive::ActiveSequence->playhead) { n_cut = c->timeline_in; @@ -155,7 +155,7 @@ void Timeline::next_cut() { } } -void ripple_clips(ComboAction* ca, Sequence *s, long point, long length, const QVector& ignore) { +void ripple_clips(ComboAction* ca, SequencePtr s, long point, long length, const QVector& ignore) { ca->append(new RippleAction(s, point, length, ignore)); } @@ -171,7 +171,7 @@ void Timeline::toggle_show_all() { } } -void Timeline::create_ghosts_from_media(Sequence* seq, long entry_point, QVector& media_list) { +void Timeline::create_ghosts_from_media(SequencePtr seq, long entry_point, QVector& media_list) { video_ghosts = false; audio_ghosts = false; @@ -179,8 +179,8 @@ void Timeline::create_ghosts_from_media(Sequence* seq, long entry_point, QVector bool can_import = true; Media* medium = media_list.at(i); - Footage* m = nullptr; - Sequence* s = nullptr; + FootagePtr m = nullptr; + SequencePtr s = nullptr; long sequence_length = 0; long default_clip_in = 0; long default_clip_out = 0; @@ -276,16 +276,16 @@ void Timeline::create_ghosts_from_media(Sequence* seq, long entry_point, QVector } } -void Timeline::add_clips_from_ghosts(ComboAction* ca, Sequence* s) { +void Timeline::add_clips_from_ghosts(ComboAction* ca, SequencePtr s) { // add clips long earliest_point = LONG_MAX; - QVector added_clips; + QVector added_clips; for (int i=0;imedia = g.media; c->media_stream = g.media_stream; c->timeline_in = g.in; @@ -293,7 +293,7 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, Sequence* s) { c->clip_in = g.clip_in; c->track = g.track; if (c->media->get_type() == MEDIA_TYPE_FOOTAGE) { - Footage* m = c->media->to_footage(); + FootagePtr m = c->media->to_footage(); if (m->video_tracks.size() == 0) { // audio only (greenish) c->color_r = 128; @@ -317,7 +317,7 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, Sequence* s) { c->color_g = 128; c->color_b = 128; - Sequence* media = c->media->to_sequence(); + SequencePtr media = c->media->to_sequence(); c->name = media->name; } c->recalculateMaxLength(); @@ -327,9 +327,9 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, Sequence* s) { // link clips from the same media for (int i=0;imedia == cc->media) { c->linked.append(j); } @@ -367,7 +367,7 @@ void Timeline::add_transition() { bool adding = false; for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { int transition_to_add = (c->track < 0) ? TRANSITION_INTERNAL_CROSSDISSOLVE : TRANSITION_INTERNAL_LINEARFADE; if (c->get_opening_transition() == nullptr) { @@ -397,7 +397,7 @@ void Timeline::nest() { // get selected clips for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { selected_clips.append(i); earliest_point = qMin(c->timeline_in, earliest_point); @@ -408,7 +408,7 @@ void Timeline::nest() { if (!selected_clips.isEmpty()) { ComboAction* ca = new ComboAction(); - Sequence* s = new Sequence(); + SequencePtr s(new Sequence()); // create "nest" sequence s->name = panel_project->get_next_sequence_name(tr("Nested Sequence")); @@ -424,7 +424,7 @@ void Timeline::nest() { ca->append(new DeleteClipAction(olive::ActiveSequence, selected_clips.at(i))); // copy to new - Clip* copy = olive::ActiveSequence->clips.at(selected_clips.at(i))->copy(s); + ClipPtr copy(olive::ActiveSequence->clips.at(selected_clips.at(i))->copy(s)); copy->timeline_in -= earliest_point; copy->timeline_out -= earliest_point; s->clips.append(copy); @@ -536,7 +536,7 @@ void Timeline::select_all() { if (olive::ActiveSequence != nullptr) { olive::ActiveSequence->selections.clear(); for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { Selection s; s.in = c->timeline_in; @@ -556,7 +556,7 @@ void Timeline::scroll_to_frame(long frame) { void Timeline::select_from_playhead() { olive::ActiveSequence->selections.clear(); for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr && c->timeline_in <= olive::ActiveSequence->playhead && c->timeline_out > olive::ActiveSequence->playhead) { @@ -576,7 +576,7 @@ bool Timeline::can_ripple_empty_space(long frame, int track) { rc_ripple_max = LONG_MAX; for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { if (c->timeline_in > frame || c->timeline_out > frame) { at_end_of_sequence = false; @@ -667,7 +667,7 @@ void Timeline::toggle_enable_on_selected_clips() { ComboAction* ca = new ComboAction(); bool push_undo = false; for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { ca->append(new SetBool(&c->enabled, !c->enabled)); push_undo = true; @@ -706,7 +706,7 @@ void Timeline::delete_selection(QVector& selections, bool ripple_dele bool can_ripple = true; for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr && c->timeline_in < ripple_point && c->timeline_out > ripple_point) { // conflict detected, but this clip may be getting deleted so let's check bool deleted = false; @@ -721,7 +721,7 @@ void Timeline::delete_selection(QVector& selections, bool ripple_dele } if (!deleted) { for (int j=0;jclips.size();j++) { - Clip* cc = olive::ActiveSequence->clips.at(j); + ClipPtr cc = olive::ActiveSequence->clips.at(j); if (cc != nullptr && cc->track == c->track && cc->timeline_in > c->timeline_out @@ -781,7 +781,7 @@ void Timeline::decheck_tool_buttons(QObject* sender) { QVector Timeline::get_tracks_of_linked_clips(int i) { QVector tracks; - Clip* clip = olive::ActiveSequence->clips.at(i); + ClipPtr clip = olive::ActiveSequence->clips.at(i); for (int j=0;jlinked.size();j++) { tracks.append(olive::ActiveSequence->clips.at(clip->linked.at(j))->track); } @@ -796,7 +796,7 @@ void Timeline::zoom_out() { multiply_zoom(0.5); } -bool is_clip_selected(Clip* clip, bool containing) { +bool is_clip_selected(ClipPtr clip, bool containing) { for (int i=0;isequence->selections.size();i++) { const Selection& s = clip->sequence->selections.at(i); if (clip->track == s.track && ((clip->timeline_in >= s.in && clip->timeline_out <= s.out && containing) || @@ -811,12 +811,12 @@ void Timeline::snapping_clicked(bool checked) { snapping = checked; } -Clip* Timeline::split_clip(ComboAction* ca, bool transitions, int p, long frame) { +ClipPtr Timeline::split_clip(ComboAction* ca, bool transitions, int p, long frame) { return split_clip(ca, transitions, p, frame, frame); } -Clip* Timeline::split_clip(ComboAction* ca, bool transitions, int p, long frame, long post_in) { - Clip* pre = olive::ActiveSequence->clips.at(p); +ClipPtr Timeline::split_clip(ComboAction* ca, bool transitions, int p, long frame, long post_in) { + ClipPtr pre = olive::ActiveSequence->clips.at(p); if (pre != nullptr && pre->timeline_in < frame && pre->timeline_out > frame) { // guard against attempts to split at in/out points bool splitting_closing_dual_transition = false; @@ -826,7 +826,7 @@ Clip* Timeline::split_clip(ComboAction* ca, bool transitions, int p, long frame, splitting_closing_dual_transition = true; } - Clip* post = pre->copy(olive::ActiveSequence, transitions && !splitting_closing_dual_transition); + ClipPtr post = ClipPtr(pre->copy(olive::ActiveSequence, transitions && !splitting_closing_dual_transition)); long new_clip_length = frame - pre->timeline_in; @@ -891,12 +891,12 @@ bool Timeline::split_clip_and_relink(ComboAction *ca, int clip, long frame, bool split_cache.append(clip); - Clip* c = olive::ActiveSequence->clips.at(clip); + ClipPtr c = olive::ActiveSequence->clips.at(clip); if (c != nullptr) { QVector pre_clips; - QVector post_clips; + QVector post_clips; - Clip* post = split_clip(ca, true, clip, frame); + ClipPtr post = split_clip(ca, true, clip, frame); // if alt is not down, split clips links too if (post == nullptr) { @@ -912,10 +912,10 @@ bool Timeline::split_clip_and_relink(ComboAction *ca, int clip, long frame, bool for (int i=0;ilinked.size();i++) { int l = c->linked.at(i); if (!has_clip_been_split(l)) { - Clip* link = olive::ActiveSequence->clips.at(l); + ClipPtr link = olive::ActiveSequence->clips.at(l); if ((original_clip_is_selected && is_clip_selected(link, true)) || !original_clip_is_selected) { split_cache.append(l); - Clip* s = split_clip(ca, true, l, frame); + ClipPtr s = split_clip(ca, true, l, frame); if (s != nullptr) { pre_clips.append(l); post_clips.append(s); @@ -963,7 +963,7 @@ void Timeline::clean_up_selections(QVector& areas) { } } -bool selection_contains_transition(const Selection& s, Clip* c, int type) { +bool selection_contains_transition(const Selection& s, ClipPtr c, int type) { if (type == TA_OPENING_TRANSITION) { return c->get_opening_transition() != nullptr && s.out == c->timeline_in + c->get_opening_transition()->get_true_length() @@ -982,12 +982,12 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& area panel_effect_controls->clear_effects(true); QVector pre_clips; - QVector post_clips; + QVector post_clips; for (int i=0;iclips.size();j++) { - Clip* c = olive::ActiveSequence->clips.at(j); + ClipPtr c = olive::ActiveSequence->clips.at(j); if (c != nullptr && c->track == s.track && !c->undeletable) { if (selection_contains_transition(s, c, TA_OPENING_TRANSITION)) { // delete opening transition @@ -1002,7 +1002,7 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& area // middle of clip is within deletion area // duplicate clip - Clip* post = split_clip(ca, true, j, s.in, s.out); + ClipPtr post = split_clip(ca, true, j, s.in, s.out); pre_clips.append(j); post_clips.append(post); @@ -1053,7 +1053,7 @@ void Timeline::copy(bool del) { long min_in = 0; for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { for (int j=0;jselections.size();j++) { const Selection& s = olive::ActiveSequence->selections.at(j); @@ -1064,7 +1064,7 @@ void Timeline::copy(bool del) { clipboard_type = CLIPBOARD_TYPE_CLIP; } - Clip* copied_clip = c->copy(nullptr); + ClipPtr copied_clip = c->copy(nullptr); // copy linked IDs (we correct these later in paste()) copied_clip->linked = c->linked; @@ -1087,16 +1087,16 @@ void Timeline::copy(bool del) { copied_clip->load_id = i; - clipboard.append(copied_clip); + clipboard.append(copied_clip); } } } } - for (int i=0;i(clipboard.at(i))->timeline_in -= min_in; - static_cast(clipboard.at(i))->timeline_out -= min_in; + std::static_pointer_cast(clipboard.at(i))->timeline_in -= min_in; + std::static_pointer_cast(clipboard.at(i))->timeline_out -= min_in; } if (del && copied) { @@ -1104,11 +1104,11 @@ void Timeline::copy(bool del) { } } -void Timeline::relink_clips_using_ids(QVector& old_clips, QVector& new_clips) { +void Timeline::relink_clips_using_ids(QVector& old_clips, QVector& new_clips) { // relink pasted clips for (int i=0;iclips.at(old_clips.at(i)); + ClipPtr oc = olive::ActiveSequence->clips.at(old_clips.at(i)); for (int j=0;jlinked.size();j++) { for (int k=0;klinked.at(j) == old_clips.at(k)) { @@ -1123,19 +1123,19 @@ void Timeline::relink_clips_using_ids(QVector& old_clips, QVector& n void Timeline::paste(bool insert) { if (clipboard.size() > 0) { - if (clipboard_type == CLIPBOARD_TYPE_CLIP) { + if (clipboard_type == CLIPBOARD_TYPE_CLIP) { ComboAction* ca = new ComboAction(); // create copies and delete areas that we'll be pasting to QVector delete_areas; - QVector pasted_clips; + QVector pasted_clips; long paste_start = LONG_MAX; long paste_end = LONG_MIN; - for (int i=0;i(clipboard.at(i)); + for (int i=0;i(clipboard.at(i)); // create copy of clip and offset by playhead - Clip* cc = c->copy(olive::ActiveSequence); + ClipPtr cc(c->copy(olive::ActiveSequence)); // convert frame rates cc->timeline_in = refactor_frame_number(cc->timeline_in, c->cached_fr, olive::ActiveSequence->frame_rate); @@ -1168,13 +1168,13 @@ void Timeline::paste(bool insert) { } // correct linked clips - for (int i=0;i(clipboard.at(i)); + ClipPtr oc = std::static_pointer_cast(clipboard.at(i)); for (int j=0;jlinked.size();j++) { - for (int k=0;k(clipboard.at(k)); + for (int k=0;k(clipboard.at(k)); if (comp->load_id == oc->linked.at(j)) { pasted_clips.at(i)->linked.append(k); } @@ -1200,10 +1200,10 @@ void Timeline::paste(bool insert) { bool ask_conflict = true; for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { - for (int j=0;j(clipboard.at(j)); + for (int j=0;j(clipboard.at(j)); if ((c->track < 0) == (e->meta->subtype == EFFECT_TYPE_VIDEO)) { int found = -1; if (ask_conflict) { @@ -1283,7 +1283,7 @@ void Timeline::edit_to_point_internal(bool in, bool ripple) { // find closest in point to playhead for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { track_min = qMin(track_min, c->track); track_max = qMax(track_max, c->track); @@ -1382,18 +1382,18 @@ bool Timeline::split_selection(ComboAction* ca) { // temporary relinking vectors QVector pre_splits; - QVector post_splits; - QVector secondary_post_splits; + QVector post_splits; + QVector secondary_post_splits; // find clips within selection and split for (int j=0;jclips.size();j++) { - Clip* clip = olive::ActiveSequence->clips.at(j); + ClipPtr clip = olive::ActiveSequence->clips.at(j); if (clip != nullptr) { for (int i=0;iselections.size();i++) { const Selection& s = olive::ActiveSequence->selections.at(i); if (s.track == clip->track) { - Clip* post_b = split_clip(ca, true, j, s.out); - Clip* post_a = split_clip(ca, post_b == nullptr, j, s.in); + ClipPtr post_b = split_clip(ca, true, j, s.out); + ClipPtr post_a = split_clip(ca, post_b == nullptr, j, s.in); pre_splits.append(j); post_splits.append(post_a); secondary_post_splits.append(post_b); @@ -1424,7 +1424,7 @@ bool Timeline::split_selection(ComboAction* ca) { bool Timeline::split_all_clips_at_point(ComboAction* ca, long point) { bool split = false; for (int j=0;jclips.size();j++) { - Clip* c = olive::ActiveSequence->clips.at(j); + ClipPtr c = olive::ActiveSequence->clips.at(j); if (c != nullptr) { // always relinks if (split_clip_and_relink(ca, j, point, true)) { @@ -1443,11 +1443,11 @@ void Timeline::split_at_playhead() { if (olive::ActiveSequence->selections.size() > 0) { // see if whole clips are selected QVector pre_clips; - QVector post_clips; + QVector post_clips; for (int j=0;jclips.size();j++) { - Clip* clip = olive::ActiveSequence->clips.at(j); + ClipPtr clip = olive::ActiveSequence->clips.at(j); if (clip != nullptr && is_clip_selected(clip, true)) { - Clip* s = split_clip(ca, true, j, olive::ActiveSequence->playhead); + ClipPtr s = split_clip(ca, true, j, olive::ActiveSequence->playhead); if (s != nullptr) { pre_clips.append(j); post_clips.append(s); @@ -1555,7 +1555,7 @@ bool Timeline::snap_to_timeline(long* l, bool use_playhead, bool use_markers, bo // snap to clip/transition for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { if (snap_to_point(c->timeline_in, l)) { return true; @@ -1587,7 +1587,7 @@ void Timeline::set_marker() { bool clip_mode = false; for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { @@ -1642,7 +1642,7 @@ void Timeline::toggle_links() { LinkCommand* command = new LinkCommand(); command->s = olive::ActiveSequence; for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { if (!command->clips.contains(i)) command->clips.append(i); @@ -1665,22 +1665,26 @@ void Timeline::toggle_links() { void Timeline::increase_track_height() { for (int i=0;iappend(new MoveClipAction(c, iin, iout, iclip_in, itrack, relative)); if (verify_transitions) { diff --git a/panels/timeline.h b/panels/timeline.h index a9c77f780..2cacaad7d 100644 --- a/panels/timeline.h +++ b/panels/timeline.h @@ -23,10 +23,17 @@ #include "ui/timelinetools.h" #include "project/selection.h" +#include "project/clip.h" +#include "project/undo.h" +#include "ui/timelineheader.h" +#include "ui/resizablescrollbar.h" +#include "ui/audiomonitor.h" +#include "ui/timelinewidget.h" #include #include #include +#include #define TRACK_DEFAULT_HEIGHT 40 @@ -37,30 +44,12 @@ #define ADD_OBJ_NOISE 4 #define ADD_OBJ_AUDIO 5 -class QPushButton; -class SourceTable; -class ViewerWidget; -class ComboAction; -class Effect; -class Media; -class Transition; -class TimelineHeader; -class TimelineWidget; -class ResizableScrollBar; -class AudioMonitor; -class QScrollBar; -struct EffectMeta; -struct Sequence; -class Clip; -struct Footage; -struct FootageStream; - -bool is_clip_selected(Clip* clip, bool containing); +bool is_clip_selected(ClipPtr clip, bool containing); int getScreenPointFromFrame(double zoom, long frame); long getFrameFromScreenPoint(double zoom, int x); -bool selection_contains_transition(const Selection& s, Clip* c, int type); -void move_clip(ComboAction *ca, Clip *c, long iin, long iout, long iclip_in, int itrack, bool verify_transitions = true, bool relative = false); -void ripple_clips(ComboAction *ca, Sequence* s, long point, long length, const QVector& ignore = QVector()); +bool selection_contains_transition(const Selection& s, ClipPtr c, int type); +void move_clip(ComboAction *ca, ClipPtr c, long iin, long iout, long iclip_in, int itrack, bool verify_transitions = true, bool relative = false); +void ripple_clips(ComboAction *ca, SequencePtr s, long point, long length, const QVector& ignore = QVector()); struct Ghost { int clip; @@ -85,7 +74,7 @@ struct Ghost { bool trimming; // transition trimming - Transition* transition; + TransitionPtr transition; }; class Timeline : public QDockWidget @@ -98,15 +87,15 @@ public: bool focused(); void multiply_zoom(double m); void copy(bool del); - Clip* split_clip(ComboAction* ca, bool transitions, int p, long frame); - Clip* split_clip(ComboAction* ca, bool transitions, int p, long frame, long post_in); + ClipPtr split_clip(ComboAction* ca, bool transitions, int p, long frame); + ClipPtr split_clip(ComboAction* ca, bool transitions, int p, long frame, long post_in); bool split_selection(ComboAction* ca); bool split_all_clips_at_point(ComboAction *ca, long point); bool split_clip_and_relink(ComboAction* ca, int clip, long frame, bool relink); void clean_up_selections(QVector& areas); void deselect_area(long in, long out, int track); void delete_areas_and_relink(ComboAction *ca, QVector& areas, bool deselect_areas); - void relink_clips_using_ids(QVector& old_clips, QVector& new_clips); + void relink_clips_using_ids(QVector& old_clips, QVector& new_clips); void update_sequence(); QVector get_tracks_of_linked_clips(int i); @@ -114,8 +103,8 @@ public: void edit_to_point_internal(bool in, bool ripple); void delete_in_out_internal(bool ripple); - void create_ghosts_from_media(Sequence *seq, long entry_point, QVector &media_list); - void add_clips_from_ghosts(ComboAction *ca, Sequence *s); + void create_ghosts_from_media(SequencePtr seq, long entry_point, QVector &media_list); + void add_clips_from_ghosts(ComboAction *ca, SequencePtr s); int getTimelineScreenPointFromFrame(long frame); long getTimelineFrameFromScreenPoint(int x); diff --git a/panels/viewer.cpp b/panels/viewer.cpp index 76c9103f5..037a3b735 100644 --- a/panels/viewer.cpp +++ b/panels/viewer.cpp @@ -123,7 +123,7 @@ void Viewer::reset_all_audio() { if (seq != nullptr) { long last_frame = 0; for (int i=0;iclips.size();i++) { - Clip* c = seq->clips.at(i); + ClipPtr c = seq->clips.at(i); if (c != nullptr) { c->reset_audio(); last_frame = qMax(last_frame, c->timeline_out); @@ -438,9 +438,9 @@ void Viewer::pause() { panel_project->process_file_list(file_list); // add it to the sequence - Clip* c = new Clip(seq); + ClipPtr c = ClipPtr(new Clip(seq)); Media* m = panel_project->last_imported_media.at(0); - Footage* f = m->to_footage(); + FootagePtr f = m->to_footage(); f->ready_lock.lock(); @@ -457,7 +457,7 @@ void Viewer::pause() { f->ready_lock.unlock(); - QVector add_clips; + QVector add_clips; add_clips.append(c); olive::UndoStack.push(new AddClipCommand(seq, add_clips)); // add clip } @@ -720,11 +720,11 @@ void Viewer::set_media(Media* m) { switch (media->get_type()) { case MEDIA_TYPE_FOOTAGE: { - Footage* footage = media->to_footage(); + FootagePtr footage = media->to_footage(); marker_ref = &footage->markers; - seq = new Sequence(); + seq = SequencePtr(new Sequence()); created_sequence = true; seq->wrapper_sequence = true; seq->name = footage->name; @@ -743,7 +743,7 @@ void Viewer::set_media(Media* m) { seq->height = video_stream.video_height; if (video_stream.video_frame_rate > 0 && !video_stream.infinite_length) seq->frame_rate = video_stream.video_frame_rate * footage->speed; - Clip* c = new Clip(seq); + ClipPtr c = ClipPtr(new Clip(seq)); c->media = media; c->media_stream = video_stream.file_index; c->timeline_in = 0; @@ -762,7 +762,7 @@ void Viewer::set_media(Media* m) { const FootageStream& audio_stream = footage->audio_tracks.at(0); seq->audio_frequency = audio_stream.audio_frequency; - Clip* c = new Clip(seq); + ClipPtr c = ClipPtr(new Clip(seq)); c->media = media; c->media_stream = audio_stream.file_index; c->timeline_in = 0; @@ -848,13 +848,12 @@ void Viewer::clean_created_seq() { undo_stack.command(i) }*/ - delete seq; - seq = nullptr; + seq.reset(); created_sequence = false; } } -void Viewer::set_sequence(bool main, Sequence *s) { +void Viewer::set_sequence(bool main, SequencePtr s) { pause(); reset_all_audio(); diff --git a/panels/viewer.h b/panels/viewer.h index 08c049d4a..c69791199 100644 --- a/panels/viewer.h +++ b/panels/viewer.h @@ -24,19 +24,17 @@ #include #include #include - -class Timeline; -class Media; -struct Sequence; -class TimelineHeader; -class ResizableScrollBar; -class ViewerContainer; -class LabelSlider; -class QPushButton; -class QLabel; +#include +#include #include "project/marker.h" +#include "project/media.h" + #include "ui/viewerwidget.h" +#include "ui/timelinewidget.h" +#include "ui/timelineheader.h" +#include "ui/labelslider.h" +#include "ui/resizablescrollbar.h" bool frame_rate_is_droppable(float rate); long timecode_to_frame(const QString& s, int view, double frame_rate); @@ -92,7 +90,7 @@ public: ViewerWidget* viewer_widget; Media* media; - Sequence* seq; + SequencePtr seq; QVector* marker_ref; void set_marker(); @@ -124,7 +122,7 @@ private slots: private: void update_window_title(); void clean_created_seq(); - void set_sequence(bool main, Sequence* s); + void set_sequence(bool main, SequencePtr s); bool main_sequence; bool created_sequence; long cached_end_frame; diff --git a/playback/audio.h b/playback/audio.h index 55cafbcca..ba6aba7b5 100644 --- a/playback/audio.h +++ b/playback/audio.h @@ -25,15 +25,11 @@ #include #include #include +#include +#include +#include -//#define INT16_MAX 0x7fff -//#define INT16_MIN (-INT16_MAX-1) - -class QIODevice; -class QAudioOutput; -class QComboBox; - -struct Sequence; +#include "project/sequence.h" class AudioSenderThread : public QThread { Q_OBJECT diff --git a/playback/cacher.cpp b/playback/cacher.cpp index f05145bfa..3c36f2f5f 100644 --- a/playback/cacher.cpp +++ b/playback/cacher.cpp @@ -62,13 +62,13 @@ double bytes_to_seconds(int nb_bytes, int nb_channels, int sample_rate) { return ((double) (nb_bytes >> 1) / nb_channels / sample_rate); } -void apply_audio_effects(Clip* c, double timecode_start, AVFrame* frame, int nb_bytes, QVector nests) { +void apply_audio_effects(ClipPtr c, double timecode_start, AVFrame* frame, int nb_bytes, QVector nests) { // perform all audio effects double timecode_end; timecode_end = timecode_start + bytes_to_seconds(nb_bytes, frame->channels, frame->sample_rate); for (int j=0;jeffects.size();j++) { - Effect* e = c->effects.at(j); + EffectPtr e = c->effects.at(j); if (e->is_enabled()) e->process_audio(timecode_start, timecode_end, frame->data[0], nb_bytes, 2); } if (c->get_opening_transition() != nullptr) { @@ -98,7 +98,7 @@ void apply_audio_effects(Clip* c, double timecode_start, AVFrame* frame, int nb_ } if (!nests.isEmpty()) { - Clip* next_nest = nests.last(); + ClipPtr next_nest = nests.last(); nests.removeLast(); apply_audio_effects(next_nest, timecode_start + (((double)c->get_timeline_in_with_transition()-c->get_clip_in_with_transition())/c->sequence->frame_rate), frame, nb_bytes, nests); } @@ -106,7 +106,7 @@ void apply_audio_effects(Clip* c, double timecode_start, AVFrame* frame, int nb_ #define AUDIO_BUFFER_PADDING 2048 -void cache_audio_worker(Clip* c, bool scrubbing, QVector& nests, int playback_speed) { +void cache_audio_worker(ClipPtr c, bool scrubbing, QVector& nests, int playback_speed) { long timeline_in = c->get_timeline_in_with_transition(); long timeline_out = c->get_timeline_out_with_transition(); long target_frame = c->audio_target_frame; @@ -460,7 +460,7 @@ void cache_audio_worker(Clip* c, bool scrubbing, QVector& nests, int play QMetaObject::invokeMethod(panel_sequence_viewer, "play_wake", Qt::QueuedConnection); } -void cache_video_worker(Clip* c, long playhead) { +void cache_video_worker(ClipPtr c, long playhead) { int read_ret, send_ret, retr_ret; int64_t target_pts = seconds_to_timestamp(c, playhead_to_clip_seconds(c, playhead)); @@ -498,7 +498,7 @@ void cache_video_worker(Clip* c, long playhead) { while (true) { AVFrame* frame = av_frame_alloc(); - Footage* media = c->media->to_footage(); + FootagePtr media = c->media->to_footage(); const FootageStream* ms = media->get_stream_from_file_index(true, c->media_stream); while ((retr_ret = av_buffersink_get_frame(c->buffersink_ctx, frame)) == AVERROR(EAGAIN)) { @@ -585,7 +585,7 @@ void cache_video_worker(Clip* c, long playhead) { } } -void reset_cache(Clip* c, long target_frame, int playback_speed) { +void reset_cache(ClipPtr c, long target_frame, int playback_speed) { // if we seek to a whole other place in the timeline, we'll need to reset the cache with new values if (c->media == nullptr) { if (c->track >= 0) { @@ -671,11 +671,11 @@ void reset_cache(Clip* c, long target_frame, int playback_speed) { } } -Cacher::Cacher(Clip* c) : clip(c) {} +Cacher::Cacher(ClipPtr c) : clip(c) {} AVSampleFormat sample_format = AV_SAMPLE_FMT_S16; -void open_clip_worker(Clip* clip) { +void open_clip_worker(ClipPtr clip) { qint64 time_start = QDateTime::currentMSecsSinceEpoch(); if (clip->media == nullptr) { @@ -694,7 +694,7 @@ void open_clip_worker(Clip* clip) { } } else if (clip->media->get_type() == MEDIA_TYPE_FOOTAGE) { // opens file resource for FFmpeg and prepares Clip struct for playback - Footage* m = clip->media->to_footage(); + FootagePtr m = clip->media->to_footage(); // byte array for retriving raw bytes from QString URL QByteArray ba; @@ -947,7 +947,7 @@ void open_clip_worker(Clip* clip) { qInfo() << "Clip opened on track" << clip->track << "(took" << (QDateTime::currentMSecsSinceEpoch() - time_start) << "ms)"; } -void cache_clip_worker(Clip* clip, long playhead, bool reset, bool scrubbing, QVector nests, int playback_speed) { +void cache_clip_worker(ClipPtr clip, long playhead, bool reset, bool scrubbing, QVector nests, int playback_speed) { if (reset) { // note: for video, playhead is in "internal clip" frames - for audio, it's the timeline playhead reset_cache(clip, playhead, playback_speed); @@ -967,7 +967,7 @@ void cache_clip_worker(Clip* clip, long playhead, bool reset, bool scrubbing, QV } } -void close_clip_worker(Clip* clip) { +void close_clip_worker(ClipPtr clip) { clip->finished_opening = false; if (clip->media != nullptr && clip->media->get_type() == MEDIA_TYPE_FOOTAGE) { diff --git a/playback/cacher.h b/playback/cacher.h index d6fc01e76..02d58fd75 100644 --- a/playback/cacher.h +++ b/playback/cacher.h @@ -25,12 +25,13 @@ #include class Clip; +using ClipPtr = std::shared_ptr; class Cacher : public QThread { // Q_OBJECT public: - Cacher(Clip* c); + Cacher(ClipPtr c); void run(); bool caching; @@ -42,14 +43,14 @@ public: bool interrupt; bool queued; int playback_speed; - QVector nests; + QVector nests; private: - Clip* clip; + ClipPtr clip; }; -void open_clip_worker(Clip* clip); -void cache_clip_worker(Clip* clip, long playhead, bool reset, bool scrubbing, QVector nest, int playback_speed); -void close_clip_worker(Clip* clip); +void open_clip_worker(ClipPtr clip); +void cache_clip_worker(ClipPtr clip, long playhead, bool reset, bool scrubbing, QVector nest, int playback_speed); +void close_clip_worker(ClipPtr clip); #endif // CACHER_H diff --git a/playback/playback.cpp b/playback/playback.cpp index 7f8a95066..e8225625a 100644 --- a/playback/playback.cpp +++ b/playback/playback.cpp @@ -36,7 +36,6 @@ #include "debug.h" extern "C" { - #include #include #include #include @@ -59,11 +58,11 @@ long refactor_frame_number(long framenumber, double source_frame_rate, double ta return qRound((double(framenumber)/source_frame_rate)*target_frame_rate); } -bool clip_uses_cacher(Clip* clip) { +bool clip_uses_cacher(ClipPtr clip) { return (clip->media == nullptr && clip->track >= 0) || (clip->media != nullptr && clip->media->get_type() == MEDIA_TYPE_FOOTAGE); } -void open_clip(Clip* clip, bool multithreaded) { +void open_clip(ClipPtr clip, bool multithreaded) { if (clip_uses_cacher(clip)) { clip->multithreaded = multithreaded; if (multithreaded) { @@ -85,7 +84,7 @@ void open_clip(Clip* clip, bool multithreaded) { } } -void close_clip(Clip* clip, bool wait) { +void close_clip(ClipPtr clip, bool wait) { clip->finished_opening = false; // destroy opengl texture in main thread @@ -129,7 +128,7 @@ void close_clip(Clip* clip, bool wait) { } } -void cache_clip(Clip* clip, long playhead, bool reset, bool scrubbing, QVector& nests, int playback_speed) { +void cache_clip(ClipPtr clip, long playhead, bool reset, bool scrubbing, QVector& nests, int playback_speed) { if (clip_uses_cacher(clip)) { if (clip->multithreaded) { clip->cacher->playhead = playhead; @@ -147,11 +146,11 @@ void cache_clip(Clip* clip, long playhead, bool reset, bool scrubbing, QVectorget_timeline_in_with_transition()+c->get_clip_in_with_transition())/(double)c->sequence->frame_rate); } -void get_clip_frame(Clip* c, long playhead, bool& texture_failed) { +void get_clip_frame(ClipPtr c, long playhead, bool& texture_failed) { if (c->finished_opening) { const FootageStream* ms = c->media->to_footage()->get_stream_from_file_index(c->track < 0, c->media_stream); @@ -336,7 +335,7 @@ void get_clip_frame(Clip* c, long playhead, bool& texture_failed) { } for (int i=0;ieffects.size();i++) { - Effect* e = c->effects.at(i); + EffectPtr e = c->effects.at(i); if (e->enable_image && e->is_enabled()) { if (data_buffer_1 == target_frame->data[0]) { data_buffer_1 = new uint8_t[frame_size]; @@ -366,16 +365,16 @@ void get_clip_frame(Clip* c, long playhead, bool& texture_failed) { c->queue_lock.unlock(); // get more frames - QVector empty; + QVector empty; if (cache) cache_clip(c, playhead, reset, false, empty, false); } } -long playhead_to_clip_frame(Clip* c, long playhead) { +long playhead_to_clip_frame(ClipPtr c, long playhead) { return (qMax(0L, playhead - c->get_timeline_in_with_transition()) + c->get_clip_in_with_transition()); } -double playhead_to_clip_seconds(Clip* c, long playhead) { +double playhead_to_clip_seconds(ClipPtr c, long playhead) { // returns time in seconds long clip_frame = playhead_to_clip_frame(c, playhead); if (c->reverse) clip_frame = c->getMaximumLength() - clip_frame - 1; @@ -384,15 +383,15 @@ double playhead_to_clip_seconds(Clip* c, long playhead) { return secs; } -int64_t seconds_to_timestamp(Clip* c, double seconds) { +int64_t seconds_to_timestamp(ClipPtr c, double seconds) { return qRound64(seconds * av_q2d(av_inv_q(c->stream->time_base))) + qMax((int64_t) 0, c->stream->start_time); } -int64_t playhead_to_timestamp(Clip* c, long playhead) { +int64_t playhead_to_timestamp(ClipPtr c, long playhead) { return seconds_to_timestamp(c, playhead_to_clip_seconds(c, playhead)); } -int retrieve_next_frame(Clip* c, AVFrame* f) { +int retrieve_next_frame(ClipPtr c, AVFrame* f) { int result = 0; int receive_ret; @@ -438,7 +437,7 @@ int retrieve_next_frame(Clip* c, AVFrame* f) { return result; } -bool is_clip_active(Clip* c, long playhead) { +bool is_clip_active(ClipPtr c, long playhead) { // these buffers allow clips to be opened and prepared well before they're displayed // as well as closed a little after they're not needed anymore int open_buffer = qCeil(c->sequence->frame_rate*2); @@ -451,7 +450,7 @@ bool is_clip_active(Clip* c, long playhead) { && playhead - c->get_timeline_in_with_transition() + c->get_clip_in_with_transition() < c->getMaximumLength(); } -void set_sequence(Sequence* s) { +void set_sequence(SequencePtr s) { panel_effect_controls->clear_effects(true); olive::ActiveSequence = s; panel_sequence_viewer->set_main_sequence(); @@ -459,10 +458,10 @@ void set_sequence(Sequence* s) { panel_timeline->setFocus(); } -void closeActiveClips(Sequence *s) { +void closeActiveClips(SequencePtr s) { if (s != nullptr) { for (int i=0;iclips.size();i++) { - Clip* c = s->clips.at(i); + ClipPtr c = s->clips.at(i); if (c != nullptr) { if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) { closeActiveClips(c->media->to_sequence()); diff --git a/playback/playback.h b/playback/playback.h index 7c1d1c0bc..ab460e00c 100644 --- a/playback/playback.h +++ b/playback/playback.h @@ -24,30 +24,32 @@ #include #include -class Clip; -struct ClipCache; -struct Sequence; -struct AVFrame; +#include "project/clip.h" +#include "project/sequence.h" + +extern "C" { + #include +} long refactor_frame_number(long framenumber, double source_frame_rate, double target_frame_rate); -bool clip_uses_cacher(Clip* clip); -void open_clip(Clip* clip, bool multithreaded); -void cache_clip(Clip* clip, long playhead, bool reset, bool scrubbing, QVector &nests, int playback_speed); -void close_clip(Clip* clip, bool wait); -void handle_media(Sequence* sequence, long playhead, bool multithreaded); -void reset_cache(Clip* c, long target_frame, int playback_speed); -void get_clip_frame(Clip* c, long playhead, bool &texture_failed); -double get_timecode(Clip* c, long playhead); +bool clip_uses_cacher(ClipPtr clip); +void open_clip(ClipPtr clip, bool multithreaded); +void cache_clip(ClipPtr clip, long playhead, bool reset, bool scrubbing, QVector &nests, int playback_speed); +void close_clip(ClipPtr clip, bool wait); +void handle_media(SequencePtr sequence, long playhead, bool multithreaded); +void reset_cache(ClipPtr c, long target_frame, int playback_speed); +void get_clip_frame(ClipPtr c, long playhead, bool &texture_failed); +double get_timecode(ClipPtr c, long playhead); -long playhead_to_clip_frame(Clip* c, long playhead); -double playhead_to_clip_seconds(Clip* c, long playhead); -int64_t seconds_to_timestamp(Clip* c, double seconds); -int64_t playhead_to_timestamp(Clip* c, long playhead); +long playhead_to_clip_frame(ClipPtr c, long playhead); +double playhead_to_clip_seconds(ClipPtr c, long playhead); +int64_t seconds_to_timestamp(ClipPtr c, double seconds); +int64_t playhead_to_timestamp(ClipPtr c, long playhead); -int retrieve_next_frame(Clip* c, AVFrame* f); -bool is_clip_active(Clip* c, long playhead); -void get_next_audio(Clip* c, bool mix); -void set_sequence(Sequence* s); -void closeActiveClips(Sequence* s); +int retrieve_next_frame(ClipPtr c, AVFrame* f); +bool is_clip_active(ClipPtr c, long playhead); +void get_next_audio(ClipPtr c, bool mix); +void set_sequence(SequencePtr s); +void closeActiveClips(SequencePtr s); #endif // PLAYBACK_H diff --git a/project/clip.cpp b/project/clip.cpp index 53aefdaec..bcfa76d35 100644 --- a/project/clip.cpp +++ b/project/clip.cpp @@ -34,11 +34,7 @@ #include "undo.h" #include "debug.h" -extern "C" { - #include -} - -Clip::Clip(Sequence* s) : +Clip::Clip(SequencePtr s) : sequence(s), enabled(true), clip_in(0), @@ -64,8 +60,8 @@ Clip::Clip(Sequence* s) : reset(); } -Clip* Clip::copy(Sequence* s, bool duplicate_transitions) { - Clip* copy = new Clip(s); +ClipPtr Clip::copy(SequencePtr s, bool duplicate_transitions) { + ClipPtr copy(new Clip(s)); copy->enabled = enabled; copy->name = QString(name); @@ -122,9 +118,9 @@ void Clip::reset_audio() { frame_sample_index = -1; audio_buffer_write = 0; } else if (media->get_type() == MEDIA_TYPE_SEQUENCE) { - Sequence* nested_sequence = media->to_sequence(); + SequencePtr nested_sequence = media->to_sequence(); for (int i=0;iclips.size();i++) { - Clip* c = nested_sequence->clips.at(i); + ClipPtr c = nested_sequence->clips.at(i); if (c != nullptr) c->reset_audio(); } } @@ -133,7 +129,7 @@ void Clip::reset_audio() { void Clip::refresh() { // validates media if it was replaced if (replaced && media != nullptr && media->get_type() == MEDIA_TYPE_FOOTAGE) { - Footage* m = media->to_footage(); + FootagePtr m = media->to_footage(); if (track < 0 && m->video_tracks.size() > 0) { media_stream = m->video_tracks.at(0).file_index; @@ -177,7 +173,7 @@ QVector &Clip::get_markers() { return markers; } -Transition* Clip::get_opening_transition() { +TransitionPtr Clip::get_opening_transition() { if (opening_transition > -1) { if (this->sequence == nullptr) { return clipboard_transitions.at(opening_transition); @@ -188,7 +184,7 @@ Transition* Clip::get_opening_transition() { return nullptr; } -Transition* Clip::get_closing_transition() { +TransitionPtr Clip::get_closing_transition() { if (closing_transition > -1) { if (this->sequence == nullptr) { return clipboard_transitions.at(closing_transition); @@ -201,15 +197,13 @@ Transition* Clip::get_closing_transition() { Clip::~Clip() { if (open) { - close_clip(this, true); + close_clip(ClipPtr(this), true); } - if (opening_transition != -1) this->sequence->hard_delete_transition(this, TA_OPENING_TRANSITION); - if (closing_transition != -1) this->sequence->hard_delete_transition(this, TA_CLOSING_TRANSITION); + if (opening_transition != -1) this->sequence->hard_delete_transition(ClipPtr(this), TA_OPENING_TRANSITION); + if (closing_transition != -1) this->sequence->hard_delete_transition(ClipPtr(this), TA_CLOSING_TRANSITION); - for (int i=0;iget_type()) { case MEDIA_TYPE_FOOTAGE: { - Footage* m = media->to_footage(); + FootagePtr m = media->to_footage(); const FootageStream* ms = m->get_stream_from_file_index(track < 0, media_stream); if (ms != nullptr && ms->infinite_length) { calculated_length = LONG_MAX; @@ -276,7 +270,7 @@ void Clip::recalculateMaxLength() { break; case MEDIA_TYPE_SEQUENCE: { - Sequence* s = media->to_sequence(); + SequencePtr s = media->to_sequence(); calculated_length = refactor_frame_number(s->getEndFrame(), s->frame_rate, fr); } break; @@ -301,7 +295,7 @@ int Clip::getWidth() { } case MEDIA_TYPE_SEQUENCE: { - Sequence* s = media->to_sequence(); + SequencePtr s = media->to_sequence(); return s->width; break; } @@ -320,7 +314,7 @@ int Clip::getHeight() { } case MEDIA_TYPE_SEQUENCE: { - Sequence* s = media->to_sequence(); + SequencePtr s = media->to_sequence(); return s->height; } } @@ -329,7 +323,7 @@ int Clip::getHeight() { void Clip::refactor_frame_rate(ComboAction* ca, double multiplier, bool change_timeline_points) { if (change_timeline_points) { - move_clip(ca, this, + move_clip(ca, ClipPtr(this), qRound((double) timeline_in * multiplier), qRound((double) timeline_out * multiplier), qRound((double) clip_in * multiplier), @@ -338,7 +332,7 @@ void Clip::refactor_frame_rate(ComboAction* ca, double multiplier, bool change_t // move keyframes for (int i=0;irow_count();j++) { EffectRow* r = e->row(j); for (int l=0;lfieldCount();l++) { diff --git a/project/clip.h b/project/clip.h index 620542092..ab6eb934a 100644 --- a/project/clip.h +++ b/project/clip.h @@ -24,37 +24,34 @@ #include #include #include +#include +#include + +#include "playback/cacher.h" + +#include "project/effect.h" +#include "project/transition.h" +#include "project/comboaction.h" +#include "project/media.h" +#include "footage.h" #include "marker.h" -class Cacher; -class Effect; -class Transition; -class QOpenGLFramebufferObject; -class ComboAction; -class Media; -struct Sequence; -struct Footage; -struct FootageStream; +extern "C" { + #include + #include +} -struct AVFormatContext; -struct AVStream; -struct AVCodec; -struct AVCodecContext; -struct AVFrame; -struct AVPacket; -struct SwsContext; -struct SwrContext; -struct AVFilterGraph; -struct AVFilterContext; -struct AVDictionary; -class QOpenGLTexture; +using ClipPtr = std::shared_ptr; + +class Sequence; +using SequencePtr = std::shared_ptr; class Clip { public: - Clip(Sequence* s); + Clip(SequencePtr s); ~Clip(); - Clip* copy(Sequence* s, bool duplicate_transitions = true); + ClipPtr copy(SequencePtr s, bool duplicate_transitions = true); void reset_audio(); void reset(); void refresh(); @@ -68,7 +65,7 @@ public: int getWidth(); int getHeight(); void refactor_frame_rate(ComboAction* ca, double multiplier, bool change_timeline_points); - Sequence* sequence; + SequencePtr sequence; // queue functions void queue_clear(); @@ -84,7 +81,7 @@ public: quint8 color_r; quint8 color_g; quint8 color_b; - Media* media; + Media* media; int media_stream; double speed; double cached_fr; @@ -96,12 +93,12 @@ public: QVector& get_markers(); // other variables (should be deep copied/duplicated in copy()) - QList effects; + QList effects; QVector linked; int opening_transition; - Transition* get_opening_transition(); + TransitionPtr get_opening_transition(); int closing_transition; - Transition* get_closing_transition(); + TransitionPtr get_closing_transition(); // media handling AVFormatContext* formatCtx; diff --git a/project/comboaction.cpp b/project/comboaction.cpp new file mode 100644 index 000000000..825c28262 --- /dev/null +++ b/project/comboaction.cpp @@ -0,0 +1,35 @@ +#include "comboaction.h" + +ComboAction::ComboAction() {} + +ComboAction::~ComboAction() { + for (int i=0;i=0;i--) { + commands.at(i)->undo(); + } + for (int i=0;iundo(); + } +} + +void ComboAction::redo() { + for (int i=0;iredo(); + } + for (int i=0;iredo(); + } +} + +void ComboAction::append(QUndoCommand* u) { + commands.append(u); +} + +void ComboAction::appendPost(QUndoCommand* u) { + post_commands.append(u); +} diff --git a/project/comboaction.h b/project/comboaction.h new file mode 100644 index 000000000..7d3edbf65 --- /dev/null +++ b/project/comboaction.h @@ -0,0 +1,88 @@ +#ifndef COMBOACTION_H +#define COMBOACTION_H + +#include +#include + +/** + * @brief The ComboAction class + * + * The Undo/Redo system works by stacking an action that knows how to "do" and also "undo" itself. As Olive is + * a very complex program, there are many actions that can in one "user action". For example, moving a clip over + * another will delete the clip under it, which is at least two actions that need to be undone if the user clicks + * undo, however the user only (knowingly) did one thing and would find it confusing if this one user action required + * to undos to complete undo. + * + * To address this, ComboAction is an undo action that simply compiles several possible actions into one, doing them + * all on every redo, and undoing them all on every undo. + */ +class ComboAction : public QUndoCommand { +public: + /** + * @brief ComboAction Constructor. Currently empty. + */ + ComboAction(); + + /** + * @brief ~ComboAction Destructor. Cleans up all QUndoCommand classes that have been added to it. + */ + virtual ~ComboAction() override; + + /** + * @brief Undo Function + * + * Called by the QUndoStack to undo. + * + * Calls QUndoCommand::undo() on all QUndoCommand objects added by append() + * in REVERSE order to how they were added. Then calls QUndoCommand::redo() on every action added by appendPost() + * in the order they were added (not in reverse). + */ + virtual void undo() override; + + /** + * @brief Redo Function + * + * Called by the QUndoStack to redo. + * + * Calls QUndoCommand::redo() on all QUndoCommand objects added by append() + * in the order they were added. Then calls QUndoCommand::redo() on every action added by appendPost() in + * the order they were added. + */ + virtual void redo() override; + + /** + * @brief Add an undo action + * + * Add an action to be done/undone. ComboAction takes ownership of this QUndoCommand and will delete it when + * it is deleted. + * + * @param u + * + * The QUndoCommand to add. + */ + void append(QUndoCommand* u); + + /** + * @brief Add a post-undo PostAction + * + * Sometimes the results of all the actions require another function to be called (e.g. repainting the Viewer). + * QUndoCommand objects added by appendPost() will run after EVERY QUndoCommand added by append() has been run. + * + * @param u + * + * The PostAction to add + */ + void appendPost(QUndoCommand* u); +private: + /** + * @brief Internal array of QUndoCommand objects + */ + QVector commands; + + /** + * @brief Internal array of PostAction objects + */ + QVector post_commands; +}; + +#endif // COMBOACTION_H diff --git a/project/effect.cpp b/project/effect.cpp index cdafc379a..aa85b95af 100644 --- a/project/effect.cpp +++ b/project/effect.cpp @@ -69,31 +69,31 @@ QVector effects; -Effect* create_effect(Clip* c, const EffectMeta* em) { +EffectPtr create_effect(ClipPtr c, const EffectMeta* em) { if (em->internal >= 0 && em->internal < EFFECT_INTERNAL_COUNT) { // must be an internal effect switch (em->internal) { - case EFFECT_INTERNAL_TRANSFORM: return new TransformEffect(c, em); - case EFFECT_INTERNAL_TEXT: return new TextEffect(c, em); - case EFFECT_INTERNAL_TIMECODE: return new TimecodeEffect(c, em); - case EFFECT_INTERNAL_SOLID: return new SolidEffect(c, em); - case EFFECT_INTERNAL_NOISE: return new AudioNoiseEffect(c, em); - case EFFECT_INTERNAL_VOLUME: return new VolumeEffect(c, em); - case EFFECT_INTERNAL_PAN: return new PanEffect(c, em); - case EFFECT_INTERNAL_TONE: return new ToneEffect(c, em); - case EFFECT_INTERNAL_SHAKE: return new ShakeEffect(c, em); - case EFFECT_INTERNAL_CORNERPIN: return new CornerPinEffect(c, em); - case EFFECT_INTERNAL_FILLLEFTRIGHT: return new FillLeftRightEffect(c, em); + case EFFECT_INTERNAL_TRANSFORM: return EffectPtr(new TransformEffect(c, em)); + case EFFECT_INTERNAL_TEXT: return EffectPtr(new TextEffect(c, em)); + case EFFECT_INTERNAL_TIMECODE: return EffectPtr(new TimecodeEffect(c, em)); + case EFFECT_INTERNAL_SOLID: return EffectPtr(new SolidEffect(c, em)); + case EFFECT_INTERNAL_NOISE: return EffectPtr(new AudioNoiseEffect(c, em)); + case EFFECT_INTERNAL_VOLUME: return EffectPtr(new VolumeEffect(c, em)); + case EFFECT_INTERNAL_PAN: return EffectPtr(new PanEffect(c, em)); + case EFFECT_INTERNAL_TONE: return EffectPtr(new ToneEffect(c, em)); + case EFFECT_INTERNAL_SHAKE: return EffectPtr(new ShakeEffect(c, em)); + case EFFECT_INTERNAL_CORNERPIN: return EffectPtr(new CornerPinEffect(c, em)); + case EFFECT_INTERNAL_FILLLEFTRIGHT: return EffectPtr(new FillLeftRightEffect(c, em)); #ifndef NOVST - case EFFECT_INTERNAL_VST: return new VSTHost(c, em); + case EFFECT_INTERNAL_VST: return EffectPtr(new VSTHost(c, em)); #endif #ifndef NOFREI0R - case EFFECT_INTERNAL_FREI0R: return new Frei0rEffect(c, em); + case EFFECT_INTERNAL_FREI0R: return EffectPtr(new Frei0rEffect(c, em)); #endif } } else if (!em->filename.isEmpty()) { // load effect from file - return new Effect(c, em); + return EffectPtr(new Effect(c, em)); } else { qCritical() << "Invalid effect data"; QMessageBox::critical(olive::MainWindow, @@ -112,7 +112,7 @@ const EffectMeta* get_internal_meta(int internal_id, int type) { return nullptr; } -Effect::Effect(Clip* c, const EffectMeta *em) : +Effect::Effect(ClipPtr c, const EffectMeta *em) : parent_clip(c), meta(em), enable_shader(false), @@ -344,7 +344,7 @@ Effect::~Effect() { } } -void Effect::copy_field_keyframes(Effect* e) { +void Effect::copy_field_keyframes(EffectPtr e) { for (int i=0;irows.at(i); @@ -498,7 +498,7 @@ void Effect::load_from_file() { QFile file_handle(file); if (file_handle.open(QFile::ReadOnly)) { - olive::UndoStack.push(new SetEffectData(this, file_handle.readAll())); + olive::UndoStack.push(new SetEffectData(EffectPtr(this), file_handle.readAll())); file_handle.close(); @@ -515,7 +515,7 @@ void Effect::load_from_file() { int Effect::get_index_in_clip() { if (parent_clip != nullptr) { for (int i=0;ieffects.size();i++) { - if (parent_clip->effects.at(i) == this) { + if (parent_clip->effects.at(i).get() == this) { return i; } } @@ -854,8 +854,8 @@ void Effect::setIterations(int i) { void Effect::process_image(double, uint8_t *, uint8_t *, int){} -Effect* Effect::copy(Clip* c) { - Effect* copy = create_effect(c, meta); +EffectPtr Effect::copy(ClipPtr c) { + EffectPtr copy = create_effect(c, meta); copy->set_enabled(is_enabled()); copy_field_keyframes(copy); return copy; diff --git a/project/effect.h b/project/effect.h index e27e99fbb..b3cb88990 100644 --- a/project/effect.h +++ b/project/effect.h @@ -30,19 +30,22 @@ #include #include #include -class QLabel; -class QWidget; -class CollapsibleWidget; -class QGridLayout; -class QPushButton; -class QMouseEvent; +#include +#include +#include +#include +#include +#include +#include + +#include "ui/collapsiblewidget.h" +#include "ui/checkboxex.h" class Clip; -class QXmlStreamReader; -class QXmlStreamWriter; +using ClipPtr = std::shared_ptr; + class Effect; -class EffectRow; -class CheckboxEx; +using EffectPtr = std::shared_ptr; struct EffectMeta { QString name; @@ -57,7 +60,7 @@ struct EffectMeta { extern QVector effects; double log_volume(double linear); -Effect* create_effect(Clip* c, const EffectMeta *em); +EffectPtr create_effect(ClipPtr c, const EffectMeta *em); const EffectMeta* get_internal_meta(int internal_id, int type); enum EffectType { @@ -166,9 +169,9 @@ qint16 mix_audio_sample(qint16 a, qint16 b); class Effect : public QObject { Q_OBJECT public: - Effect(Clip* c, const EffectMeta* em); + Effect(ClipPtr c, const EffectMeta* em); ~Effect(); - Clip* parent_clip; + ClipPtr parent_clip; const EffectMeta* meta; int id; QString name; @@ -187,8 +190,8 @@ public: virtual void refresh(); - virtual Effect* copy(Clip* c); - void copy_field_keyframes(Effect *e); + virtual EffectPtr copy(ClipPtr c); + void copy_field_keyframes(EffectPtr e); virtual void load(QXmlStreamReader& stream); virtual void custom_load(QXmlStreamReader& stream); diff --git a/project/effectrow.cpp b/project/effectrow.cpp index 9ad98d67f..0d9577d27 100644 --- a/project/effectrow.cpp +++ b/project/effectrow.cpp @@ -116,7 +116,7 @@ void EffectRow::set_keyframe_enabled(bool enabled) { void EffectRow::goto_previous_key() { long key = LONG_MIN; - Clip* c = parent_effect->parent_clip; + ClipPtr c = parent_effect->parent_clip; for (int i=0;ikeyframes.size();j++) { @@ -132,7 +132,7 @@ void EffectRow::goto_previous_key() { void EffectRow::toggle_key() { QVector key_fields; QVector key_field_index; - Clip* c = parent_effect->parent_clip; + ClipPtr c = parent_effect->parent_clip; for (int j=0;jkeyframes.size();i++) { @@ -159,7 +159,7 @@ void EffectRow::toggle_key() { void EffectRow::goto_next_key() { long key = LONG_MAX; - Clip* c = parent_effect->parent_clip; + ClipPtr c = parent_effect->parent_clip; for (int i=0;ikeyframes.size();j++) { diff --git a/project/footage.h b/project/footage.h index 30db89b2b..9c99c2a87 100644 --- a/project/footage.h +++ b/project/footage.h @@ -37,7 +37,7 @@ enum VideoInterlacingMode { VIDEO_BOTTOM_FIELD_FIRST }; -struct Sequence; +class Sequence; class Clip; class PreviewGenerator; class MediaThrobber; @@ -101,4 +101,6 @@ struct Footage { void reset(); }; +using FootagePtr = std::shared_ptr; + #endif // FOOTAGE_H diff --git a/project/marker.cpp b/project/marker.cpp index e6a4d3927..ca8de8492 100644 --- a/project/marker.cpp +++ b/project/marker.cpp @@ -48,7 +48,7 @@ void draw_marker(QPainter &p, int x, int y, int bottom, bool selected) { p.drawPolygon(points, 5); } -void set_marker_internal(Sequence* seq, const QVector& clips) { +void set_marker_internal(SequencePtr seq, const QVector& clips) { // if clips is empty, the marker is being added to the sequence // add_marker is used to determine whether we're adding a marker, depending on whether the user input a marker name @@ -78,7 +78,7 @@ void set_marker_internal(Sequence* seq, const QVector& clips) { // add a marker action for each clip foreach (int i, clips) { - Clip* c = seq->clips.at(i); + ClipPtr c = seq->clips.at(i); ca->append(new AddMarkerAction(&c->get_markers(), seq->playhead - c->timeline_in + c->clip_in, marker_name)); @@ -119,7 +119,7 @@ void set_marker_internal(Sequence* seq, const QVector& clips) { } } -void set_marker_internal(Sequence* seq) { +void set_marker_internal(SequencePtr seq) { // create empty clip array QVector clips; diff --git a/project/marker.h b/project/marker.h index 59de65f3e..5678660d1 100644 --- a/project/marker.h +++ b/project/marker.h @@ -26,7 +26,8 @@ #include #include -struct Sequence; +class Sequence; +using SequencePtr = std::shared_ptr; struct Marker { long frame; @@ -35,7 +36,7 @@ struct Marker { void draw_marker(QPainter& p, int x, int y, int bottom, bool selected); -void set_marker_internal(Sequence* seq, const QVector& clips); -void set_marker_internal(Sequence* seq); +void set_marker_internal(SequencePtr seq, const QVector& clips); +void set_marker_internal(SequencePtr seq); #endif // MARKER_H diff --git a/project/media.cpp b/project/media.cpp index f0de8274f..118d9c960 100644 --- a/project/media.cpp +++ b/project/media.cpp @@ -68,30 +68,29 @@ Media::Media(Media* iparent) : {} Media::~Media() { - switch (get_type()) { - case MEDIA_TYPE_FOOTAGE: delete to_footage(); break; - case MEDIA_TYPE_SEQUENCE: if (object != nullptr) delete to_sequence(); break; - } + for (int i=0;i(object); +FootagePtr Media::to_footage() { + return std::static_pointer_cast(object); } -Sequence *Media::to_sequence() { - return static_cast(object); +SequencePtr Media::to_sequence() { + return std::static_pointer_cast(object); } -void Media::set_footage(Footage *f) { +void Media::set_footage(FootagePtr f) { type = MEDIA_TYPE_FOOTAGE; - object = f; + object = VoidPtr(f); } -void Media::set_sequence(Sequence *s) { +void Media::set_sequence(SequencePtr s) { set_icon(QIcon(":/icons/sequence.png")); type = MEDIA_TYPE_SEQUENCE; - object = s; + object = VoidPtr(s); if (s != nullptr) update_tooltip(); } @@ -114,7 +113,7 @@ void Media::update_tooltip(const QString& error) { switch (type) { case MEDIA_TYPE_FOOTAGE: { - Footage* f = to_footage(); + FootagePtr f = to_footage(); tooltip = QCoreApplication::translate("Media", "Name:") + " " + f->name + "\n" + QCoreApplication::translate("Media", "Filename:") + " " + f->url + "\n"; if (error.isEmpty()) { @@ -185,7 +184,7 @@ void Media::update_tooltip(const QString& error) { break; case MEDIA_TYPE_SEQUENCE: { - Sequence* s = to_sequence(); + SequencePtr s = to_sequence(); tooltip = QCoreApplication::translate("Media", "Name: %1" "\nVideo Dimensions: %2x%3" @@ -205,7 +204,7 @@ void Media::update_tooltip(const QString& error) { } -void *Media::to_object() { +VoidPtr Media::to_object() { return object; } @@ -233,7 +232,7 @@ double Media::get_frame_rate(int stream) { switch (get_type()) { case MEDIA_TYPE_FOOTAGE: { - Footage* f = to_footage(); + FootagePtr f = to_footage(); if (stream < 0) return f->video_tracks.at(0).video_frame_rate * f->speed; return f->get_stream_from_file_index(true, stream)->video_frame_rate * f->speed; } @@ -246,7 +245,7 @@ int Media::get_sampling_rate(int stream) { switch (get_type()) { case MEDIA_TYPE_FOOTAGE: { - Footage* f = to_footage(); + FootagePtr f = to_footage(); if (stream < 0) return f->audio_tracks.at(0).audio_frequency * f->speed; return to_footage()->get_stream_from_file_index(false, stream)->audio_frequency * f->speed; } @@ -288,7 +287,7 @@ QVariant Media::data(int column, int role) { case Qt::DecorationRole: if (column == 0) { if (get_type() == MEDIA_TYPE_FOOTAGE) { - Footage* f = to_footage(); + FootagePtr f = to_footage(); if (f->video_tracks.size() > 0 && f->video_tracks.at(0).preview_done) { return f->video_tracks.at(0).video_preview_square; @@ -304,11 +303,11 @@ QVariant Media::data(int column, int role) { case 1: if (root) return QCoreApplication::translate("Media", "Duration"); if (get_type() == MEDIA_TYPE_SEQUENCE) { - Sequence* s = to_sequence(); + SequencePtr s = to_sequence(); return frame_to_timecode(s->getEndFrame(), olive::CurrentConfig.timecode_view, s->frame_rate); } if (get_type() == MEDIA_TYPE_FOOTAGE) { - Footage* f = to_footage(); + FootagePtr f = to_footage(); double r = 30; if (f->video_tracks.size() > 0 && !qIsNull(f->video_tracks.at(0).video_frame_rate)) @@ -322,7 +321,7 @@ QVariant Media::data(int column, int role) { if (root) return QCoreApplication::translate("Media", "Rate"); if (get_type() == MEDIA_TYPE_SEQUENCE) return QString::number(get_frame_rate()) + " FPS"; if (get_type() == MEDIA_TYPE_FOOTAGE) { - Footage* f = to_footage(); + FootagePtr f = to_footage(); double r; if (f->video_tracks.size() > 0 && !qIsNull(r = get_frame_rate())) { return QString::number(get_frame_rate()) + " FPS"; diff --git a/project/media.h b/project/media.h index ed99c2ad5..fb782e8a8 100644 --- a/project/media.h +++ b/project/media.h @@ -23,8 +23,10 @@ #include #include +#include #include "project/marker.h" +#include "project/footage.h" enum MediaType { MEDIA_TYPE_FOOTAGE, @@ -32,25 +34,27 @@ enum MediaType { MEDIA_TYPE_FOLDER }; -struct Footage; +class Sequence; +using SequencePtr = std::shared_ptr; + +using VoidPtr = std::shared_ptr; + class MediaThrobber; -struct Sequence; -#include class Media { public: Media(Media* iparent); ~Media(); - Footage *to_footage(); - Sequence* to_sequence(); - void set_footage(Footage* f); - void set_sequence(Sequence* s); + FootagePtr to_footage(); + SequencePtr to_sequence(); + void set_footage(FootagePtr f); + void set_sequence(SequencePtr s); void set_folder(); void set_icon(const QIcon &ico); void set_parent(Media* p); void update_tooltip(const QString& error = 0); - void *to_object(); + VoidPtr to_object(); int get_type(); const QString& get_name(); void set_name(const QString& n); @@ -78,7 +82,7 @@ public: int temp_id2; private: int type; - void* object; + VoidPtr object; // item functions QList children; diff --git a/project/projectmodel.cpp b/project/projectmodel.cpp index 5fdae2184..177eaa0fc 100644 --- a/project/projectmodel.cpp +++ b/project/projectmodel.cpp @@ -99,8 +99,8 @@ QModelIndex ProjectModel::index(int row, int column, const QModelIndex &parent) return QModelIndex(); } -QModelIndex ProjectModel::create_index(int arow, int acolumn, void* aid) { - return createIndex(arow, acolumn, aid); +QModelIndex ProjectModel::create_index(int arow, int acolumn, void* adata) { + return createIndex(arow, acolumn, adata); } QModelIndex ProjectModel::parent(const QModelIndex &index) const { diff --git a/project/projectmodel.h b/project/projectmodel.h index 08788d08f..a875dfb51 100644 --- a/project/projectmodel.h +++ b/project/projectmodel.h @@ -23,7 +23,7 @@ #include -class Media; +#include "project/media.h" class ProjectModel : public QAbstractItemModel { @@ -35,29 +35,29 @@ public: void make_root(); void destroy_root(); void clear(); - Media* get_root(); + Media* get_root(); QVariant data(const QModelIndex &index, int role) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; - QModelIndex create_index(int arow, int acolumn, void *aid); + QModelIndex create_index(int arow, int acolumn, void *adata); QModelIndex parent(const QModelIndex &index) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; - Media *getItem(const QModelIndex &index) const; + Media* getItem(const QModelIndex &index) const; - void appendChild(Media* parent, Media* child); - void moveChild(Media *child, Media *to); - void removeChild(Media *parent, Media* m); - Media *child(int i, Media* parent = nullptr); - int childCount(Media* parent = nullptr); - void set_icon(Media* m, const QIcon &ico); + void appendChild(Media* parent, Media* child); + void moveChild(Media* child, Media* to); + void removeChild(Media* parent, Media* m); + Media* child(int i, Media* parent = nullptr); + int childCount(Media* parent = nullptr); + void set_icon(Media* m, const QIcon &ico); private: - Media* root_item; + Media* root_item; }; #endif // PROJECTMODEL_H diff --git a/project/sequence.cpp b/project/sequence.cpp index b2b489b55..9c01b5b07 100644 --- a/project/sequence.cpp +++ b/project/sequence.cpp @@ -20,9 +20,6 @@ #include "sequence.h" -#include "clip.h" -#include "transition.h" - #include #include "debug.h" @@ -36,15 +33,10 @@ Sequence::Sequence() : { } -Sequence::~Sequence() { - // dealloc all clips - for (int i=0;iname = QCoreApplication::translate("Sequence", "%1 (copy)").arg(name); s->width = width; s->height = height; @@ -53,11 +45,11 @@ Sequence* Sequence::copy() { s->audio_layout = audio_layout; s->clips.resize(clips.size()); for (int i=0;iclips[i] = nullptr; } else { - Clip* copy = c->copy(s); + ClipPtr copy = c->copy(s); copy->linked = c->linked; s->clips[i] = copy; } @@ -68,7 +60,7 @@ Sequence* Sequence::copy() { long Sequence::getEndFrame() { long end = 0; for (int j=0;jtimeline_out > end) { end = c->timeline_out; } @@ -76,15 +68,15 @@ long Sequence::getEndFrame() { return end; } -void Sequence::hard_delete_transition(Clip *c, int type) { +void Sequence::hard_delete_transition(ClipPtr c, int type) { int transition_index = (type == TA_OPENING_TRANSITION) ? c->opening_transition : c->closing_transition; if (transition_index > -1) { bool del = true; - Transition* t = transitions.at(transition_index); + TransitionPtr t = transitions.at(transition_index); if (t->secondary_clip != nullptr) { for (int i=0;iopening_transition == transition_index @@ -100,9 +92,8 @@ void Sequence::hard_delete_transition(Clip *c, int type) { } } - if (del) { - delete transitions.at(transition_index); - transitions[transition_index] = nullptr; + if (del) { + transitions[transition_index].reset(); } if (type == TA_OPENING_TRANSITION) { @@ -117,7 +108,7 @@ void Sequence::getTrackLimits(int* video_tracks, int* audio_tracks) { int vt = 0; int at = 0; for (int j=0;jtrack < 0 && c->track < vt) { // video clip vt = c->track; @@ -131,4 +122,4 @@ void Sequence::getTrackLimits(int* video_tracks, int* audio_tracks) { } // static variable for the currently active sequence -Sequence* olive::ActiveSequence = nullptr; +SequencePtr olive::ActiveSequence = nullptr; diff --git a/project/sequence.h b/project/sequence.h index 0adbe9dc3..60ac73192 100644 --- a/project/sequence.h +++ b/project/sequence.h @@ -23,21 +23,20 @@ #include +#include "project/clip.h" #include "project/marker.h" +#include "project/transition.h" #include "project/selection.h" -class Clip; -class Transition; -class Media; - -struct Sequence { +class Sequence { +public: Sequence(); ~Sequence(); - Sequence* copy(); + SequencePtr copy(); QString name; void getTrackLimits(int* video_tracks, int* audio_tracks); long getEndFrame(); - void hard_delete_transition(Clip *c, int type); + void hard_delete_transition(ClipPtr c, int type); int width; int height; double frame_rate; @@ -56,13 +55,15 @@ struct Sequence { int save_id; QVector markers; - QVector clips; - QVector transitions; + QVector clips; + QVector transitions; }; +using SequencePtr = std::shared_ptr; + // static variable for the currently active sequence namespace olive { - extern Sequence* ActiveSequence; + extern SequencePtr ActiveSequence; } #endif // SEQUENCE_H diff --git a/project/sourcescommon.cpp b/project/sourcescommon.cpp index 995d78855..339a7a386 100644 --- a/project/sourcescommon.cpp +++ b/project/sourcescommon.cpp @@ -62,7 +62,7 @@ void SourcesCommon::create_seq_from_selected() { } ComboAction* ca = new ComboAction(); - Sequence* s = create_sequence_from_media(media_list); + SequencePtr s = create_sequence_from_media(media_list); // add clips to it panel_timeline->create_ghosts_from_media(s, 0, media_list); @@ -334,7 +334,7 @@ void SourcesCommon::dropEvent(QWidget* parent, QDropEvent *event, const QModelIn void SourcesCommon::reveal_in_browser() { Media* media = project_parent->item_to_media(selected_items.at(0)); - Footage* m = media->to_footage(); + FootagePtr m = media->to_footage(); #if defined(Q_OS_WIN) QStringList args; @@ -385,7 +385,7 @@ void SourcesCommon::clear_proxies_from_selected() { QList delete_list; for (int i=0;iproxy && !f->proxy_path.isEmpty()) { if (QFileInfo::exists(f->proxy_path)) { diff --git a/project/sourcescommon.h b/project/sourcescommon.h index 0fa1c015a..152f1b159 100644 --- a/project/sourcescommon.h +++ b/project/sourcescommon.h @@ -25,6 +25,8 @@ #include #include +#include "project/footage.h" + class Project; class QMouseEvent; class Media; @@ -63,7 +65,7 @@ private: QTimer rename_timer; // we cache the selected footage items for open_create_proxy_dialog() - QVector cached_selected_footage; + QVector cached_selected_footage; }; #endif // SOURCESCOMMON_H diff --git a/project/transition.cpp b/project/transition.cpp index 6c9cf6b15..b11b00f15 100644 --- a/project/transition.cpp +++ b/project/transition.cpp @@ -41,7 +41,7 @@ #include #include -Transition::Transition(Clip* c, Clip* s, const EffectMeta* em) : +Transition::Transition(ClipPtr c, ClipPtr s, const EffectMeta* em) : Effect(c, em), secondary_clip(s), length(30) { @@ -55,7 +55,7 @@ Transition::Transition(Clip* c, Clip* s, const EffectMeta* em) : length_ui_ele->set_frame_rate(parent_clip->sequence == nullptr ? parent_clip->cached_fr : parent_clip->sequence->frame_rate); } -int Transition::copy(Clip *c, Clip* s) { +int Transition::copy(ClipPtr c, ClipPtr s) { return create_transition(c, s, meta, length); } @@ -80,18 +80,18 @@ void Transition::set_length_from_slider() { update_ui(false); } -Transition* get_transition_from_meta(Clip* c, Clip* s, const EffectMeta* em) { +TransitionPtr get_transition_from_meta(ClipPtr c, ClipPtr s, const EffectMeta* em) { if (!em->filename.isEmpty()) { // load effect from file - return new Transition(c, s, em); + return TransitionPtr(new Transition(c, s, em)); } else if (em->internal >= 0 && em->internal < TRANSITION_INTERNAL_COUNT) { // must be an internal effect switch (em->internal) { - case TRANSITION_INTERNAL_CROSSDISSOLVE: return new CrossDissolveTransition(c, s, em); - case TRANSITION_INTERNAL_LINEARFADE: return new LinearFadeTransition(c, s, em); - case TRANSITION_INTERNAL_EXPONENTIALFADE: return new ExponentialFadeTransition(c, s, em); - case TRANSITION_INTERNAL_LOGARITHMICFADE: return new LogarithmicFadeTransition(c, s, em); - case TRANSITION_INTERNAL_CUBE: return new CubeTransition(c, s, em); + case TRANSITION_INTERNAL_CROSSDISSOLVE: return TransitionPtr(new CrossDissolveTransition(c, s, em)); + case TRANSITION_INTERNAL_LINEARFADE: return TransitionPtr(new LinearFadeTransition(c, s, em)); + case TRANSITION_INTERNAL_EXPONENTIALFADE: return TransitionPtr(new ExponentialFadeTransition(c, s, em)); + case TRANSITION_INTERNAL_LOGARITHMICFADE: return TransitionPtr(new LogarithmicFadeTransition(c, s, em)); + case TRANSITION_INTERNAL_CUBE: return TransitionPtr(new CubeTransition(c, s, em)); } } else { qCritical() << "Invalid transition data"; @@ -103,11 +103,11 @@ Transition* get_transition_from_meta(Clip* c, Clip* s, const EffectMeta* em) { return nullptr; } -int create_transition(Clip* c, Clip* s, const EffectMeta* em, long length) { - Transition* t = get_transition_from_meta(c, s, em); +int create_transition(ClipPtr c, ClipPtr s, const EffectMeta* em, long length) { + TransitionPtr t(get_transition_from_meta(c, s, em)); if (t != nullptr) { if (length >= 0) t->set_length(length); - QVector& transition_list = (c->sequence == nullptr) ? clipboard_transitions : c->sequence->transitions; + QVector& transition_list = (c->sequence == nullptr) ? clipboard_transitions : c->sequence->transitions; transition_list.append(t); return transition_list.size() - 1; } diff --git a/project/transition.h b/project/transition.h index bd8c4ffa7..2677fb332 100644 --- a/project/transition.h +++ b/project/transition.h @@ -34,14 +34,14 @@ #define TRANSITION_INTERNAL_CUBE 4 #define TRANSITION_INTERNAL_COUNT 5 -int create_transition(Clip* c, Clip* s, const EffectMeta* em, long length = -1); +int create_transition(ClipPtr c, ClipPtr s, const EffectMeta* em, long length = -1); class Transition : public Effect { Q_OBJECT public: - Transition(Clip* c, Clip* s, const EffectMeta* em); - int copy(Clip* c, Clip* s); - Clip* secondary_clip; + Transition(ClipPtr c, ClipPtr s, const EffectMeta* em); + int copy(ClipPtr c, ClipPtr s); + ClipPtr secondary_clip; void set_length(long l); long get_true_length(); long get_length(); @@ -52,4 +52,6 @@ private: EffectField* length_field; }; +using TransitionPtr = std::shared_ptr; + #endif // TRANSITION_H diff --git a/project/undo.cpp b/project/undo.cpp index b87e248fa..17dfe6474 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -48,41 +48,7 @@ QUndoStack olive::UndoStack; -ComboAction::ComboAction() {} - -ComboAction::~ComboAction() { - for (int i=0;i=0;i--) { - commands.at(i)->undo(); - } - for (int i=0;iundo(); - } -} - -void ComboAction::redo() { - for (int i=0;iredo(); - } - for (int i=0;iredo(); - } -} - -void ComboAction::append(QUndoCommand* u) { - commands.append(u); -} - -void ComboAction::appendPost(QUndoCommand* u) { - post_commands.append(u); -} - -MoveClipAction::MoveClipAction(Clip *c, long iin, long iout, long iclip_in, int itrack, bool irelative) { +MoveClipAction::MoveClipAction(ClipPtr c, long iin, long iout, long iclip_in, int itrack, bool irelative) { clip = c; old_in = c->timeline_in; @@ -126,16 +92,14 @@ void MoveClipAction::doRedo() { } } -DeleteClipAction::DeleteClipAction(Sequence* s, int clip) { +DeleteClipAction::DeleteClipAction(SequencePtr s, int clip) { seq = s; index = clip; opening_transition = -1; closing_transition = -1; } -DeleteClipAction::~DeleteClipAction() { - if (ref != nullptr) delete ref; -} +DeleteClipAction::~DeleteClipAction() {} void DeleteClipAction::doUndo() { // restore ref to clip @@ -187,7 +151,7 @@ void DeleteClipAction::doRedo() { linkClipIndex.clear(); linkLinkIndex.clear(); for (int i=0;iclips.size();i++) { - Clip* c = seq->clips.at(i); + ClipPtr c = seq->clips.at(i); if (c != nullptr) { for (int j=0;jlinked.size();j++) { if (c->linked.at(j) == index) { @@ -200,7 +164,7 @@ void DeleteClipAction::doRedo() { } } -ChangeSequenceAction::ChangeSequenceAction(Sequence* s) { +ChangeSequenceAction::ChangeSequenceAction(SequencePtr s) { new_sequence = s; } @@ -213,7 +177,7 @@ void ChangeSequenceAction::doRedo() { set_sequence(new_sequence); } -SetTimelineInOutCommand::SetTimelineInOutCommand(Sequence *s, bool enabled, long in, long out) { +SetTimelineInOutCommand::SetTimelineInOutCommand(SequencePtr s, bool enabled, long in, long out) { seq = s; new_enabled = enabled; new_in = in; @@ -227,7 +191,7 @@ void SetTimelineInOutCommand::doUndo() { // footage viewer functions if (seq->wrapper_sequence) { - Footage* m = seq->clips.at(0)->media->to_footage(); + FootagePtr m = seq->clips.at(0)->media->to_footage(); m->using_inout = old_enabled; m->in = old_in; m->out = old_out; @@ -245,14 +209,14 @@ void SetTimelineInOutCommand::doRedo() { // footage viewer functions if (seq->wrapper_sequence) { - Footage* m = seq->clips.at(0)->media->to_footage(); + FootagePtr m = seq->clips.at(0)->media->to_footage(); m->using_inout = new_enabled; m->in = new_in; m->out = new_out; } } -AddEffectCommand::AddEffectCommand(Clip* c, Effect* e, const EffectMeta *m, int insert_pos) { +AddEffectCommand::AddEffectCommand(ClipPtr c, EffectPtr e, const EffectMeta *m, int insert_pos) { clip = c; ref = e; meta = m; @@ -260,10 +224,6 @@ AddEffectCommand::AddEffectCommand(Clip* c, Effect* e, const EffectMeta *m, int done = false; } -AddEffectCommand::~AddEffectCommand() { - if (!done && ref != nullptr) delete ref; -} - void AddEffectCommand::doUndo() { clip->effects.last()->close(); if (pos < 0) { @@ -286,9 +246,9 @@ void AddEffectCommand::doRedo() { done = true; } -AddTransitionCommand::AddTransitionCommand(Clip* c, - Clip *s, - Transition* copy, +AddTransitionCommand::AddTransitionCommand(ClipPtr c, + ClipPtr s, + TransitionPtr copy, const EffectMeta *itransition, int itype, int ilength) { @@ -337,24 +297,24 @@ void AddTransitionCommand::doRedo() { } } -ModifyTransitionCommand::ModifyTransitionCommand(Clip* c, int itype, long ilength) { +ModifyTransitionCommand::ModifyTransitionCommand(ClipPtr c, int itype, long ilength) { clip = c; type = itype; new_length = ilength; } void ModifyTransitionCommand::doUndo() { - Transition* t = (type == TA_OPENING_TRANSITION) ? clip->get_opening_transition() : clip->get_closing_transition(); + TransitionPtr t = (type == TA_OPENING_TRANSITION) ? clip->get_opening_transition() : clip->get_closing_transition(); t->set_length(old_length); } void ModifyTransitionCommand::doRedo() { - Transition* t = (type == TA_OPENING_TRANSITION) ? clip->get_opening_transition() : clip->get_closing_transition(); + TransitionPtr t = (type == TA_OPENING_TRANSITION) ? clip->get_opening_transition() : clip->get_closing_transition(); old_length = t->get_true_length(); t->set_length(new_length); } -DeleteTransitionCommand::DeleteTransitionCommand(Sequence* s, int transition_index) { +DeleteTransitionCommand::DeleteTransitionCommand(SequencePtr s, int transition_index) { seq = s; index = transition_index; transition = nullptr; @@ -362,9 +322,7 @@ DeleteTransitionCommand::DeleteTransitionCommand(Sequence* s, int transition_ind ctc = nullptr; } -DeleteTransitionCommand::~DeleteTransitionCommand() { - if (transition != nullptr) delete transition; -} +DeleteTransitionCommand::~DeleteTransitionCommand() {} void DeleteTransitionCommand::doUndo() { seq->transitions[index] = transition; @@ -377,7 +335,7 @@ void DeleteTransitionCommand::doUndo() { void DeleteTransitionCommand::doRedo() { for (int i=0;iclips.size();i++) { - Clip* c = seq->clips.at(i); + ClipPtr c = seq->clips.at(i); if (c != nullptr) { if (c->opening_transition == index) { otc = c; @@ -466,24 +424,17 @@ void DeleteMediaCommand::doRedo() { done = true; } -AddClipCommand::AddClipCommand(Sequence* s, QVector& add) { +AddClipCommand::AddClipCommand(SequencePtr s, QVector& add) { seq = s; clips = add; } -AddClipCommand::~AddClipCommand() { - for (int i=0;iclear_effects(true); for (int i=0;iclips.last(); + ClipPtr c = seq->clips.last(); panel_timeline->deselect_area(c->timeline_in, c->timeline_out, c->track); undone_clips.prepend(c); if (c->open) close_clip(c, true); @@ -501,9 +452,9 @@ void AddClipCommand::doRedo() { } else { int linkOffset = seq->clips.size(); for (int i=0;icopy(seq); + ClipPtr copy = original->copy(seq); copy->linked.resize(original->linked.size()); for (int j=0;jlinked.size();j++) { copy->linked[j] = original->linked.at(j) + linkOffset; @@ -524,7 +475,7 @@ LinkCommand::LinkCommand() { void LinkCommand::doUndo() { for (int i=0;iclips.at(clips.at(i)); + ClipPtr c = s->clips.at(clips.at(i)); if (link) { c->linked.clear(); } else { @@ -538,7 +489,7 @@ void LinkCommand::doRedo() { old_links.clear(); for (int i=0;iclips.at(clips.at(i)); + ClipPtr c = s->clips.at(clips.at(i)); if (link) { for (int j=0;j all_sequences = panel_project->list_all_project_sequences(); + QVector all_sequences = panel_project->list_all_project_sequences(); for (int i=0;ito_sequence(); + SequencePtr s = all_sequences.at(i)->to_sequence(); for (int j=0;jclips.size();j++) { - Clip* c = s->clips.at(j); + ClipPtr c = s->clips.at(j); if (c != nullptr && c->media == item && c->open) { close_clip(c, true); c->replaced = true; @@ -621,7 +572,7 @@ void ReplaceClipMediaCommand::replace(bool undo) { } for (int i=0;iopen) { close_clip(c, true); } @@ -660,17 +611,11 @@ EffectDeleteCommand::EffectDeleteCommand() { done = false; } -EffectDeleteCommand::~EffectDeleteCommand() { - if (done) { - for (int i=0;ieffects.insert(fx.at(i), deleted_objects.at(i)); } panel_effect_controls->reload_clips(); @@ -681,9 +626,9 @@ void EffectDeleteCommand::doUndo() { void EffectDeleteCommand::doRedo() { deleted_objects.clear(); for (int i=0;ieffects.at(fx_id); + EffectPtr e = c->effects.at(fx_id); e->close(); deleted_objects.append(e); c->effects.removeAt(fx_id); @@ -705,7 +650,7 @@ void MediaMove::doRedo() { if (to == nullptr) to = project_model.get_root(); froms.resize(items.size()); for (int i=0;iparentItem(); + Media* parent = items.at(i)->parentItem(); froms[i] = parent; project_model.moveChild(items.at(i), to); } @@ -855,7 +800,7 @@ void DeleteMarkerAction::doRedo() { sorted = true; } -SetSpeedAction::SetSpeedAction(Clip* c, double speed) { +SetSpeedAction::SetSpeedAction(ClipPtr c, double speed) { clip = c; old_speed = c->speed; new_speed = speed; @@ -886,7 +831,7 @@ void SetBool::doRedo() { *boolean = new_setting; } -SetSelectionsCommand::SetSelectionsCommand(Sequence* s) { +SetSelectionsCommand::SetSelectionsCommand(SequencePtr s) { seq = s; done = true; } @@ -903,7 +848,7 @@ void SetSelectionsCommand::doRedo() { } } -EditSequenceCommand::EditSequenceCommand(Media* i, Sequence *s) { +EditSequenceCommand::EditSequenceCommand(Media* i, SequencePtr s) { item = i; seq = s; old_name = s->name; @@ -1013,11 +958,7 @@ RemoveClipsFromClipboard::RemoveClipsFromClipboard(int index) { done = false; } -RemoveClipsFromClipboard::~RemoveClipsFromClipboard() { - if (done) { - delete clip; - } -} +RemoveClipsFromClipboard::~RemoveClipsFromClipboard() {} void RemoveClipsFromClipboard::doUndo() { clipboard.insert(pos, clip); @@ -1025,7 +966,7 @@ void RemoveClipsFromClipboard::doUndo() { } void RemoveClipsFromClipboard::doRedo() { - clip = static_cast(clipboard.at(pos)); + clip = std::static_pointer_cast(clipboard.at(pos)); clipboard.removeAt(pos); done = true; } @@ -1068,7 +1009,7 @@ void ReloadEffectsCommand::doRedo() { panel_effect_controls->reload_clips(); } -RippleAction::RippleAction(Sequence *is, long ipoint, long ilength, const QVector &iignore) { +RippleAction::RippleAction(SequencePtr is, long ipoint, long ilength, const QVector &iignore) { s = is; point = ipoint; length = ilength; @@ -1084,7 +1025,7 @@ void RippleAction::doRedo() { ca = new ComboAction(); for (int i=0;iclips.size();i++) { if (!ignore.contains(i)) { - Clip* c = s->clips.at(i); + ClipPtr c = s->clips.at(i); if (c != nullptr) { if (c->timeline_in >= point) { move_clip(ca, c, length, length, 0, 0, true, true); @@ -1182,11 +1123,11 @@ void RefreshClips::doUndo() { void RefreshClips::doRedo() { // close any clips currently using this media - QVector all_sequences = panel_project->list_all_project_sequences(); + QVector all_sequences = panel_project->list_all_project_sequences(); for (int i=0;ito_sequence(); + SequencePtr s = all_sequences.at(i)->to_sequence(); for (int j=0;jclips.size();j++) { - Clip* c = s->clips.at(j); + ClipPtr c = s->clips.at(j); if (c != nullptr && c->media == media) { c->replaced = true; c->refresh(); @@ -1203,7 +1144,7 @@ void UpdateViewer::doRedo() { panel_sequence_viewer->viewer_widget->frame_update(); } -SetEffectData::SetEffectData(Effect *e, const QByteArray &s) { +SetEffectData::SetEffectData(EffectPtr e, const QByteArray &s) { effect = e; data = s; } diff --git a/project/undo.h b/project/undo.h index 1edf1b159..09d07dbad 100644 --- a/project/undo.h +++ b/project/undo.h @@ -21,24 +21,14 @@ #ifndef UNDO_H #define UNDO_H -class Media; -class QCheckBox; -class LabelSlider; -class Effect; -class SourceTable; -class EffectRow; -class EffectField; -class Transition; -class EffectGizmo; -class Clip; -struct Sequence; -struct Footage; -struct EffectMeta; - -#include "project/marker.h" +#include "project/projectelements.h" #include "project/selection.h" #include "project/effectfield.h" +#include "ui/labelslider.h" +#include "ui/sourcetable.h" + +#include #include #include #include @@ -49,19 +39,6 @@ namespace olive { extern QUndoStack UndoStack; } -class ComboAction : public QUndoCommand { -public: - ComboAction(); - virtual ~ComboAction() override; - virtual void undo() override; - virtual void redo() override; - void append(QUndoCommand* u); - void appendPost(QUndoCommand* u); -private: - QVector commands; - QVector post_commands; -}; - class OliveAction : public QUndoCommand { public: OliveAction(bool iset_window_modified = true); @@ -86,11 +63,11 @@ private: class MoveClipAction : public OliveAction { public: - MoveClipAction(Clip* c, long iin, long iout, long iclip_in, int itrack, bool irelative); + MoveClipAction(ClipPtr c, long iin, long iout, long iclip_in, int itrack, bool irelative); virtual void doUndo() override; virtual void doRedo() override; private: - Clip* clip; + ClipPtr clip; long old_in; long old_out; @@ -107,11 +84,11 @@ private: class RippleAction : public OliveAction { public: - RippleAction(Sequence *is, long ipoint, long ilength, const QVector& iignore); + RippleAction(SequencePtr is, long ipoint, long ilength, const QVector& iignore); virtual void doUndo() override; virtual void doRedo() override; private: - Sequence *s; + SequencePtr s; long point; long length; QVector ignore; @@ -120,13 +97,13 @@ private: class DeleteClipAction : public OliveAction { public: - DeleteClipAction(Sequence* s, int clip); + DeleteClipAction(SequencePtr s, int clip); virtual ~DeleteClipAction() override; virtual void doUndo() override; virtual void doRedo() override; private: - Sequence* seq; - Clip* ref; + SequencePtr seq; + ClipPtr ref; int index; int opening_transition; @@ -138,37 +115,36 @@ private: class ChangeSequenceAction : public OliveAction { public: - ChangeSequenceAction(Sequence* s); + ChangeSequenceAction(SequencePtr s); virtual void doUndo() override; virtual void doRedo() override; private: - Sequence* old_sequence; - Sequence* new_sequence; + SequencePtr old_sequence; + SequencePtr new_sequence; }; class AddEffectCommand : public OliveAction { public: - AddEffectCommand(Clip* c, Effect *e, const EffectMeta* m, int insert_pos = -1); - virtual ~AddEffectCommand() override; + AddEffectCommand(ClipPtr c, EffectPtr e, const EffectMeta* m, int insert_pos = -1); virtual void doUndo() override; virtual void doRedo() override; private: - Clip* clip; + ClipPtr clip; const EffectMeta* meta; - Effect* ref; + EffectPtr ref; int pos; bool done; }; class AddTransitionCommand : public OliveAction { public: - AddTransitionCommand(Clip* c, Clip* s, Transition *copy, const EffectMeta* itransition, int itype, int ilength); + AddTransitionCommand(ClipPtr c, ClipPtr s, TransitionPtr copy, const EffectMeta* itransition, int itype, int ilength); virtual void doUndo() override; virtual void doRedo() override; private: - Clip* clip; - Clip* secondary; - Transition* transition_to_copy; + ClipPtr clip; + ClipPtr secondary; + TransitionPtr transition_to_copy; const EffectMeta* transition; int type; int length; @@ -178,11 +154,11 @@ private: class ModifyTransitionCommand : public OliveAction { public: - ModifyTransitionCommand(Clip* c, int itype, long ilength); + ModifyTransitionCommand(ClipPtr c, int itype, long ilength); virtual void doUndo() override; virtual void doRedo() override; private: - Clip* clip; + ClipPtr clip; int type; long new_length; long old_length; @@ -190,25 +166,25 @@ private: class DeleteTransitionCommand : public OliveAction { public: - DeleteTransitionCommand(Sequence* s, int transition_index); + DeleteTransitionCommand(SequencePtr s, int transition_index); virtual ~DeleteTransitionCommand() override; virtual void doUndo() override; virtual void doRedo() override; private: - Sequence* seq; + SequencePtr seq; int index; - Transition* transition; - Clip* otc; - Clip* ctc; + TransitionPtr transition; + ClipPtr otc; + ClipPtr ctc; }; class SetTimelineInOutCommand : public OliveAction { public: - SetTimelineInOutCommand(Sequence* s, bool enabled, long in, long out); + SetTimelineInOutCommand(SequencePtr s, bool enabled, long in, long out); virtual void doUndo() override; virtual void doRedo() override; private: - Sequence* seq; + SequencePtr seq; bool old_enabled; long old_in; @@ -221,25 +197,25 @@ private: class NewSequenceCommand : public OliveAction { public: - NewSequenceCommand(Media *s, Media* iparent); + NewSequenceCommand(Media* s, Media* iparent); virtual ~NewSequenceCommand() override; virtual void doUndo() override; virtual void doRedo() override; private: - Media* seq; - Media* parent; + Media* seq; + Media* parent; bool done; }; class AddMediaCommand : public OliveAction { public: - AddMediaCommand(Media* iitem, Media* iparent); + AddMediaCommand(Media* iitem, Media* iparent); virtual ~AddMediaCommand() override; virtual void doUndo() override; virtual void doRedo() override; private: - Media* item; - Media* parent; + Media* item; + Media* parent; bool done; }; @@ -250,21 +226,21 @@ public: virtual void doUndo() override; virtual void doRedo() override; private: - Media* item; + Media* item; Media* parent; bool done; }; class AddClipCommand : public OliveAction { public: - AddClipCommand(Sequence* s, QVector& add); + AddClipCommand(SequencePtr s, QVector& add); virtual ~AddClipCommand() override; virtual void doUndo() override; virtual void doRedo() override; private: - Sequence* seq; - QVector clips; - QVector undone_clips; + SequencePtr seq; + QVector clips; + QVector undone_clips; }; class LinkCommand : public OliveAction { @@ -272,7 +248,7 @@ public: LinkCommand(); virtual void doUndo() override; virtual void doRedo() override; - Sequence* s; + SequencePtr s; QVector clips; bool link; private: @@ -293,7 +269,7 @@ private: class ReplaceMediaCommand : public OliveAction { public: - ReplaceMediaCommand(Media*, QString); + ReplaceMediaCommand(Media*, QString); virtual void doUndo() override; virtual void doRedo() override; private: @@ -308,10 +284,10 @@ public: ReplaceClipMediaCommand(Media *, Media *, bool); virtual void doUndo() override; virtual void doRedo() override; - QVector clips; + QVector clips; private: - Media* old_media; - Media* new_media; + Media* old_media; + Media* new_media; bool preserve_clip_ins; QVector old_clip_ins; void replace(bool undo); @@ -323,18 +299,18 @@ public: virtual ~EffectDeleteCommand() override; virtual void doUndo() override; virtual void doRedo() override; - QVector clips; + QVector clips; QVector fx; private: bool done; - QVector deleted_objects; + QVector deleted_objects; }; class MediaMove : public OliveAction { public: MediaMove(); - QVector items; - Media* to; + QVector items; + Media* to; virtual void doUndo() override; virtual void doRedo() override; private: @@ -343,11 +319,11 @@ private: class MediaRename : public OliveAction { public: - MediaRename(Media* iitem, QString to); + MediaRename(Media* iitem, QString to); virtual void doUndo() override; virtual void doRedo() override; private: - Media* item; + Media* item; QString from; QString to; }; @@ -395,7 +371,7 @@ public: SetAutoscaleAction(); virtual void doUndo() override; virtual void doRedo() override; - QVector clips; + QVector clips; }; class AddMarkerAction : public OliveAction { @@ -436,11 +412,11 @@ private: class SetSpeedAction : public OliveAction { public: - SetSpeedAction(Clip* c, double speed); + SetSpeedAction(ClipPtr c, double speed); virtual void doUndo() override; virtual void doRedo() override; private: - Clip* clip; + ClipPtr clip; double old_speed; double new_speed; }; @@ -458,19 +434,19 @@ private: class SetSelectionsCommand : public OliveAction { public: - SetSelectionsCommand(Sequence *s); + SetSelectionsCommand(SequencePtr s); virtual void doUndo() override; virtual void doRedo() override; QVector old_data; QVector new_data; private: - Sequence* seq; + SequencePtr seq; bool done; }; class EditSequenceCommand : public OliveAction { public: - EditSequenceCommand(Media *i, Sequence* s); + EditSequenceCommand(Media *i, SequencePtr s); virtual void doUndo() override; virtual void doRedo() override; void update(); @@ -482,8 +458,8 @@ public: int audio_frequency; int audio_layout; private: - Media* item; - Sequence* seq; + Media* item; + SequencePtr seq; QString old_name; int old_width; @@ -545,11 +521,11 @@ public: class UpdateFootageTooltip : public OliveAction { public: - UpdateFootageTooltip(Media* i); + UpdateFootageTooltip(Media* i); virtual void doUndo() override; virtual void doRedo() override; private: - Media* item; + Media* item; }; class MoveEffectCommand : public OliveAction { @@ -557,7 +533,7 @@ public: MoveEffectCommand(); virtual void doUndo() override; virtual void doRedo() override; - Clip* clip; + ClipPtr clip; int from; int to; }; @@ -570,14 +546,14 @@ public: virtual void doRedo() override; private: int pos; - Clip* clip; + ClipPtr clip; bool done; }; class RenameClipCommand : public OliveAction { public: RenameClipCommand(); - QVector clips; + QVector clips; QString new_name; virtual void doUndo() override; virtual void doRedo() override; @@ -626,11 +602,11 @@ private: class RefreshClips : public OliveAction { public: - RefreshClips(Media* m); + RefreshClips(Media* m); virtual void doUndo() override; virtual void doRedo() override; private: - Media* media; + Media* media; }; class UpdateViewer : public OliveAction { @@ -641,11 +617,11 @@ public: class SetEffectData : public OliveAction { public: - SetEffectData(Effect* e, const QByteArray &s); + SetEffectData(EffectPtr e, const QByteArray &s); virtual void doUndo() override; virtual void doRedo() override; private: - Effect* effect; + EffectPtr effect; QByteArray data; QByteArray old_data; }; diff --git a/ui/keyframeview.cpp b/ui/keyframeview.cpp index eb448b9e2..5d494673d 100644 --- a/ui/keyframeview.cpp +++ b/ui/keyframeview.cpp @@ -106,15 +106,15 @@ void KeyframeView::paintEvent(QPaintEvent*) { visible_out = 0; for (int j=0;jselected_clips.size();j++) { - Clip* c = olive::ActiveSequence->clips.at(panel_effect_controls->selected_clips.at(j)); + ClipPtr c = olive::ActiveSequence->clips.at(panel_effect_controls->selected_clips.at(j)); visible_in = qMin(visible_in, c->timeline_in); visible_out = qMax(visible_out, c->timeline_out); } for (int j=0;jselected_clips.size();j++) { - Clip* c = olive::ActiveSequence->clips.at(panel_effect_controls->selected_clips.at(j)); + ClipPtr c = olive::ActiveSequence->clips.at(panel_effect_controls->selected_clips.at(j)); for (int i=0;ieffects.size();i++) { - Effect* e = c->effects.at(i); + EffectPtr e = c->effects.at(i); if (e->container->is_expanded()) { for (int j=0;jrow_count();j++) { EffectRow* row = e->row(j); @@ -373,7 +373,7 @@ void KeyframeView::mouseMoveEvent(QMouseEvent* event) { if (panel_timeline->snapping) { for (int i=0;iparent_row->parent_effect->parent_clip; + ClipPtr c = field->parent_row->parent_effect->parent_clip; long key_time = old_key_vals.at(i) + frame_diff - c->clip_in + c->timeline_in; long key_eval = key_time; if (panel_timeline->snap_to_point(olive::ActiveSequence->playhead, &key_eval)) { diff --git a/ui/renderfunctions.cpp b/ui/renderfunctions.cpp index a8a0adaf8..f00cc915e 100644 --- a/ui/renderfunctions.cpp +++ b/ui/renderfunctions.cpp @@ -100,8 +100,8 @@ GLuint draw_clip(QOpenGLFramebufferObject* fbo, GLuint texture, bool clear) { return fbo->texture(); } -void process_effect(Clip* c, - Effect* e, +void process_effect(ClipPtr c, + EffectPtr e, double timecode, GLTextureCoords& coords, GLuint& composite_texture, @@ -151,7 +151,7 @@ void process_effect(Clip* c, GLuint compose_sequence(ComposeSequenceParams ¶ms) { GLuint final_fbo = params.main_buffer; - Sequence* s = params.seq; + SequencePtr s = params.seq; long playhead = s->playhead; if (!params.nests.isEmpty()) { @@ -170,12 +170,12 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { int audio_track_count = 0; - QVector current_clips; + QVector current_clips; // loop through clips, find currently active, and sort by track for (int i=0;iclips.size();i++) { - Clip* c = s->clips.at(i); + ClipPtr c = s->clips.at(i); if (c != nullptr) { @@ -186,7 +186,7 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { // is the clip a "footage" clip? if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { - Footage* m = c->media->to_footage(); + FootagePtr m = c->media->to_footage(); // does the clip have a valid media source? if (!m->invalid && !(c->track >= 0 && !is_audio_device_set())) { @@ -273,7 +273,7 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { // loop through current clips for (int i=0;imedia != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE && !c->finished_opening) { @@ -395,12 +395,12 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { double timecode = get_timecode(c, playhead); // set up variables for gizmos later - Effect* first_gizmo_effect = nullptr; - Effect* selected_effect = nullptr; + EffectPtr first_gizmo_effect = nullptr; + EffectPtr selected_effect = nullptr; // run through all of the clip's effects for (int j=0;jeffects.size();j++) { - Effect* e = c->effects.at(j); + EffectPtr e = c->effects.at(j); process_effect(c, e, timecode, coords, textureID, fbo_switcher, params.texture_failed, TA_NO_TRANSITION); // retrieve gizmo data from effect @@ -601,7 +601,7 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { if (c->sequence == params.seq) { // only if you can currently see them double ts = (playhead - c->get_timeline_in_with_transition() + c->get_clip_in_with_transition())/s->frame_rate; for (int i=0;ieffects.size();i++) { - Effect* e = c->effects.at(i); + EffectPtr e = c->effects.at(i); for (int j=0;jrow_count();j++) { EffectRow* r = e->row(j); for (int k=0;kfieldCount();k++) { @@ -630,7 +630,7 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { return 0; } -void compose_audio(Viewer* viewer, Sequence* seq, int playback_speed) { +void compose_audio(Viewer* viewer, SequencePtr seq, int playback_speed) { ComposeSequenceParams params; params.viewer = viewer; params.ctx = nullptr; diff --git a/ui/renderfunctions.h b/ui/renderfunctions.h index 2197a59ee..a5f11e588 100644 --- a/ui/renderfunctions.h +++ b/ui/renderfunctions.h @@ -23,12 +23,12 @@ #include #include +#include -class Effect; -class Viewer; -class QOpenGLShaderProgram; -struct Sequence; -class Clip; +#include "project/sequence.h" +#include "project/effect.h" + +#include "panels/viewer.h" /** * @brief The ComposeSequenceParams struct @@ -59,7 +59,7 @@ struct ComposeSequenceParams { * In addition to clips, sequences also contain the playhead position so compose_sequence() knows which frame * to render. */ - Sequence* seq; + SequencePtr seq; /** * @brief Array to store the nested sequence hierarchy @@ -67,7 +67,7 @@ struct ComposeSequenceParams { * Should be left empty. This array gets passed around compose_sequence() as it calls itself recursively to * handle nested sequences. */ - QVector nests; + QVector nests; /** * @brief Set compose mode to video or audio @@ -82,7 +82,7 @@ struct ComposeSequenceParams { * A pointer to a pointer that will be set to the Effect whose gizmos are being rendered and should therefore * be interacted with if the user uses them. */ - Effect** gizmos; + EffectPtr* gizmos; /** * @brief A variable that compose_sequence() will set to **TRUE** if any of the clips couldn't be shown. @@ -260,6 +260,6 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms); * * The current playback speed (controlled by Shuttle Left/Right) */ -void compose_audio(Viewer* viewer, Sequence* seq, int playback_speed); +void compose_audio(Viewer* viewer, SequencePtr seq, int playback_speed); #endif // RENDERFUNCTIONS_H diff --git a/ui/renderthread.cpp b/ui/renderthread.cpp index d5136b59b..29da93012 100644 --- a/ui/renderthread.cpp +++ b/ui/renderthread.cpp @@ -235,7 +235,7 @@ void RenderThread::paint() { glDisable(GL_TEXTURE_2D); } -void RenderThread::start_render(QOpenGLContext *share, Sequence *s, const QString& save, GLvoid* pixels, int pixel_linesize, int idivider) { +void RenderThread::start_render(QOpenGLContext *share, SequencePtr s, const QString& save, GLvoid* pixels, int pixel_linesize, int idivider) { Q_UNUSED(idivider); seq = s; diff --git a/ui/renderthread.h b/ui/renderthread.h index 4c2288098..192d6f1f7 100644 --- a/ui/renderthread.h +++ b/ui/renderthread.h @@ -29,14 +29,14 @@ #include #include +#include "project/sequence.h" +#include "project/effect.h" + // copied from source code to OCIODisplay -#define LUT3D_EDGE_SIZE 32 +const int LUT3D_EDGE_SIZE = 32; // copied from source code to OCIODisplay, expanded from 3*LUT3D_EDGE_SIZE*LUT3D_EDGE_SIZE*LUT3D_EDGE_SIZE -#define NUM_3D_ENTRIES 98304 - -struct Sequence; -class Effect; +const int NUM_3D_ENTRIES = 98304; class RenderThread : public QThread { Q_OBJECT @@ -47,9 +47,9 @@ public: QMutex mutex; GLuint front_buffer; GLuint front_texture; - Effect* gizmos; + EffectPtr gizmos; void paint(); - void start_render(QOpenGLContext* share, Sequence* s, const QString &save = nullptr, GLvoid *pixels = nullptr, int pixel_linesize = 0, int idivider = 0); + void start_render(QOpenGLContext* share, SequencePtr s, const QString &save = nullptr, GLvoid *pixels = nullptr, int pixel_linesize = 0, int idivider = 0); bool did_texture_fail(); void cancel(); @@ -78,7 +78,7 @@ private: float ocio_lut_data[NUM_3D_ENTRIES]; - Sequence* seq; + SequencePtr seq; int divider; int tex_width; int tex_height; diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index e01a41fee..d18c45ecf 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -100,9 +100,9 @@ void TimelineWidget::show_context_menu(const QPoint& pos) { menu.addSeparator(); // collect all the selected clips - QVector selected_clips; + QVector selected_clips; for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { selected_clips.append(c); } @@ -186,7 +186,7 @@ void TimelineWidget::show_context_menu(const QPoint& pos) { void TimelineWidget::toggle_autoscale() { SetAutoscaleAction* action = new SetAutoscaleAction(); for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { action->clips.append(c); } @@ -201,7 +201,7 @@ void TimelineWidget::toggle_autoscale() { void TimelineWidget::tooltip_timer_timeout() { if (olive::ActiveSequence != nullptr) { if (tooltip_clip < olive::ActiveSequence->clips.size()) { - Clip* c = olive::ActiveSequence->clips.at(tooltip_clip); + ClipPtr c = olive::ActiveSequence->clips.at(tooltip_clip); if (c != nullptr) { QToolTip::showText(QCursor::pos(), tr("%1\nStart: %2\nEnd: %3\nDuration: %4").arg( @@ -217,9 +217,9 @@ void TimelineWidget::tooltip_timer_timeout() { } void TimelineWidget::rename_clip() { - QVector selected_clips; + QVector selected_clips; for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { selected_clips.append(c); } @@ -278,7 +278,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { } if (event->source() == panel_footage_viewer->viewer_widget) { - Sequence* proposed_seq = panel_footage_viewer->seq; + SequencePtr proposed_seq = panel_footage_viewer->seq; if (proposed_seq != olive::ActiveSequence) { // don't allow nesting the same sequence media_list.append(panel_footage_viewer->media); import_init = true; @@ -299,7 +299,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { for (int i=0;ilast_imported_media.size();i++) { // waits for media to have a duration // TODO would be much nicer if this was multithreaded - Footage* f = panel_project->last_imported_media.at(i)->to_footage(); + FootagePtr f = panel_project->last_imported_media.at(i)->to_footage(); f->ready_lock.lock(); f->ready_lock.unlock(); @@ -321,7 +321,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { event->acceptProposedAction(); long entry_point; - Sequence* seq = olive::ActiveSequence; + SequencePtr seq = olive::ActiveSequence; if (seq == nullptr) { // if no sequence, we're going to create a new one using the clips as a reference @@ -413,7 +413,7 @@ void TimelineWidget::dragLeaveEvent(QDragLeaveEvent* event) { update_ui(false); } if (self_created_sequence != nullptr) { - delete self_created_sequence; + self_created_sequence.reset(); self_created_sequence = nullptr; } } @@ -461,7 +461,7 @@ void insert_clips(ComboAction* ca) { panel_timeline->split_cache.clear(); for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { // don't split any clips that are moving bool found = false; @@ -517,7 +517,7 @@ void TimelineWidget::dropEvent(QDropEvent* event) { ComboAction* ca = new ComboAction(); - Sequence* s = olive::ActiveSequence; + SequencePtr s = olive::ActiveSequence; // if we're dropping into nothing, create a new sequences based on the clip being dragged if (s == nullptr) { @@ -545,7 +545,7 @@ void TimelineWidget::mouseDoubleClickEvent(QMouseEvent *event) { if (panel_timeline->tool == TIMELINE_TOOL_EDIT) { int clip_index = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); if (clip_index >= 0) { - Clip* clip = olive::ActiveSequence->clips.at(clip_index); + ClipPtr clip = olive::ActiveSequence->clips.at(clip_index); if (!(event->modifiers() & Qt::ShiftModifier)) olive::ActiveSequence->selections.clear(); Selection s; s.in = clip->timeline_in; @@ -557,7 +557,7 @@ void TimelineWidget::mouseDoubleClickEvent(QMouseEvent *event) { } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { int clip_index = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); if (clip_index >= 0) { - Clip* c = olive::ActiveSequence->clips.at(clip_index); + ClipPtr c = olive::ActiveSequence->clips.at(clip_index); if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) { set_sequence(c->media->to_sequence()); } @@ -644,7 +644,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { panel_timeline->moving_init = true; } else { if (clip_index >= 0) { - Clip* clip = olive::ActiveSequence->clips.at(clip_index); + ClipPtr clip = olive::ActiveSequence->clips.at(clip_index); if (clip != nullptr) { if (is_clip_selected(clip, true)) { if (shift) { @@ -652,7 +652,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { if (!alt) { for (int i=0;ilinked.size();i++) { - Clip* link = olive::ActiveSequence->clips.at(clip->linked.at(i)); + ClipPtr link = olive::ActiveSequence->clips.at(clip->linked.at(i)); panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track); } } @@ -660,7 +660,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track); for (int i=0;ilinked.size();i++) { - Clip* link = olive::ActiveSequence->clips.at(clip->linked.at(i)); + ClipPtr link = olive::ActiveSequence->clips.at(clip->linked.at(i)); panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track); } @@ -711,7 +711,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { // if alt is not down, select links if (!alt && panel_timeline->transition_select == TA_NO_TRANSITION) { for (int i=0;ilinked.size();i++) { - Clip* link = olive::ActiveSequence->clips.at(clip->linked.at(i)); + ClipPtr link = olive::ActiveSequence->clips.at(clip->linked.at(i)); if (!is_clip_selected(link, true)) { Selection ss; ss.in = link->timeline_in; @@ -765,7 +765,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { } } -void make_room_for_transition(ComboAction* ca, Clip* c, int type, long transition_start, long transition_end, bool delete_old_transitions) { +void make_room_for_transition(ComboAction* ca, ClipPtr c, int type, long transition_start, long transition_end, bool delete_old_transitions) { // make room for transition if (type == TA_OPENING_TRANSITION) { if (delete_old_transitions && c->get_opening_transition() != nullptr) { @@ -812,7 +812,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { panel_sequence_viewer->cue_recording(qMin(g.in, g.out), qMax(g.in, g.out), g.track); panel_timeline->creating = false; } else if (g.in != g.out) { - Clip* c = new Clip(olive::ActiveSequence); + ClipPtr c = ClipPtr(new Clip(olive::ActiveSequence)); c->media = nullptr; c->timeline_in = qMin(g.in, g.out); c->timeline_out = qMax(g.in, g.out); @@ -834,7 +834,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { panel_timeline->delete_areas_and_relink(ca, areas, false); } - QVector add; + QVector add; add.append(c); ca->append(new AddClipCommand(olive::ActiveSequence, add)); @@ -855,7 +855,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { case ADD_OBJ_BARS: { c->name = tr("Bars"); - Effect* e = create_effect(c, get_internal_meta(EFFECT_INTERNAL_SOLID, EFFECT_TYPE_EFFECT)); + EffectPtr e = create_effect(c, get_internal_meta(EFFECT_INTERNAL_SOLID, EFFECT_TYPE_EFFECT)); e->row(0)->field(0)->set_combo_index(1); c->effects.append(e); } @@ -943,13 +943,13 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { && panel_timeline->trim_target == -1) { // if holding alt (and not trimming), duplicate rather than move // duplicate clips QVector old_clips; - QVector new_clips; + QVector new_clips; QVector delete_areas; for (int i=0;ighosts.size();i++) { const Ghost& g = panel_timeline->ghosts.at(i); if (g.old_in != g.in || g.old_out != g.out || g.track != g.old_track || g.clip_in != g.old_clip_in) { // create copy of clip - Clip* c = olive::ActiveSequence->clips.at(g.clip)->copy(olive::ActiveSequence); + ClipPtr c(olive::ActiveSequence->clips.at(g.clip)->copy(olive::ActiveSequence)); c->timeline_in = g.in; c->timeline_out = g.out; @@ -1010,7 +1010,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { Ghost& g = panel_timeline->ghosts[i]; // step 3 - move clips - Clip* c = olive::ActiveSequence->clips.at(g.clip); + ClipPtr c = olive::ActiveSequence->clips.at(g.clip); if (g.transition == nullptr) { move_clip(ca, c, (g.in - g.old_in), (g.out - g.old_out), (g.clip_in - g.old_clip_in), (g.track - g.old_track), true, true); @@ -1082,8 +1082,8 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { long transition_start = qMin(g.in, g.out); long transition_end = qMax(g.in, g.out); - Clip* pre = olive::ActiveSequence->clips.at(g.clip); - Clip* post = pre; + ClipPtr pre = olive::ActiveSequence->clips.at(g.clip); + ClipPtr post = pre; make_room_for_transition(ca, pre, panel_timeline->transition_tool_type, transition_start, transition_end, true); @@ -1101,7 +1101,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { if (panel_timeline->transition_tool_type == TA_CLOSING_TRANSITION) { // swap - Clip* temp = pre; + ClipPtr temp = pre; pre = post; post = temp; } @@ -1200,7 +1200,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { void TimelineWidget::init_ghosts() { for (int i=0;ighosts.size();i++) { Ghost& g = panel_timeline->ghosts[i]; - Clip* c = olive::ActiveSequence->clips.at(g.clip); + ClipPtr c = olive::ActiveSequence->clips.at(g.clip); g.track = g.old_track = c->track; g.clip_in = g.old_clip_in = c->clip_in; @@ -1238,7 +1238,7 @@ void TimelineWidget::init_ghosts() { } } -void validate_transitions(Clip* c, int transition_type, long& frame_diff) { +void validate_transitions(ClipPtr c, int transition_type, long& frame_diff) { long validator; if (transition_type == TA_OPENING_TRANSITION) { @@ -1306,7 +1306,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { // if the ghost is attached to a clip, snap its markers too if (panel_timeline->trim_target == -1 && g.clip >= 0) { - Clip* c = olive::ActiveSequence->clips.at(g.clip); + ClipPtr c = olive::ActiveSequence->clips.at(g.clip); for (int j=0;jget_markers().size();j++) { long marker_real_time = c->get_markers().at(j).frame + c->timeline_in - c->clip_in; fm = marker_real_time + frame_diff; @@ -1325,7 +1325,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { long temp_frame_diff = frame_diff; // cache to see if we change it (thus cancelling any snap) for (int i=0;ighosts.size();i++) { const Ghost& g = panel_timeline->ghosts.at(i); - Clip* c = nullptr; + ClipPtr c = nullptr; if (g.clip != -1) c = olive::ActiveSequence->clips.at(g.clip); const FootageStream* ms = nullptr; @@ -1380,8 +1380,8 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { // prevent dual transition from going below 0 on the primary or media length on the secondary if (g.transition != nullptr && g.transition->secondary_clip != nullptr) { - Clip* otc = g.transition->parent_clip; - Clip* ctc = g.transition->secondary_clip; + ClipPtr otc = g.transition->parent_clip; + ClipPtr ctc = g.transition->secondary_clip; if (g.trim_in) { frame_diff -= g.transition->get_true_length(); @@ -1407,7 +1407,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { // ripple ops if (effective_tool == TIMELINE_TOOL_RIPPLE) { for (int j=0;jtrim_in_point) { @@ -1417,7 +1417,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { // prevent any post-clips colliding with pre-clips for (int k=0;ktrack == post->track) { if (panel_timeline->trim_in_point) { validator = post->timeline_in - frame_diff - pre->timeline_out; @@ -1481,12 +1481,12 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { if (panel_timeline->transition_tool_post_clip == -1) { validate_transitions(c, panel_timeline->transition_tool_type, frame_diff); } else { - Clip* otc = c; // open transition clip - Clip* ctc = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_post_clip); // close transition clip + ClipPtr otc = c; // open transition clip + ClipPtr ctc = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_post_clip); // close transition clip if (panel_timeline->transition_tool_type == TA_CLOSING_TRANSITION) { // swap - Clip* temp = otc; + ClipPtr temp = otc; otc = ctc; ctc = temp; } @@ -1670,7 +1670,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // select linked clips too if (olive::CurrentConfig.edit_tool_selects_links) { for (int j=0;jclips.size();j++) { - Clip* c = olive::ActiveSequence->clips.at(j); + ClipPtr c = olive::ActiveSequence->clips.at(j); for (int k=0;kselections.size();k++) { const Selection& s = olive::ActiveSequence->selections.at(k); if (!(c->timeline_in < s.in && c->timeline_out < s.in) && @@ -1728,7 +1728,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } else { new_height -= diff; } - if (new_height < TRACK_MIN_HEIGHT) new_height = TRACK_MIN_HEIGHT; + new_height = qMax(new_height, olive::timeline::kTrackMinHeight); panel_timeline->calculate_track_height(track_target, new_height); update(); } else if (panel_timeline->moving_proc) { @@ -1737,7 +1737,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // set up movement // create ghosts for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { Ghost g; g.transition = nullptr; @@ -1785,11 +1785,11 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { int size = panel_timeline->ghosts.size(); if (panel_timeline->tool == TIMELINE_TOOL_ROLLING) { for (int i=0;iclips.at(panel_timeline->ghosts.at(i).clip); + ClipPtr ghost_clip = olive::ActiveSequence->clips.at(panel_timeline->ghosts.at(i).clip); // see if any ghosts are touching, in which case flip them for (int k=0;kclips.at(panel_timeline->ghosts.at(k).clip); + ClipPtr comp_clip = olive::ActiveSequence->clips.at(panel_timeline->ghosts.at(k).clip); if ((panel_timeline->trim_in_point && comp_clip->timeline_out == ghost_clip->timeline_in) || (!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) { panel_timeline->ghosts[k].trim_in = !panel_timeline->trim_in_point; @@ -1800,9 +1800,9 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // then look for other clips we're touching for (int i=0;ighosts.at(i); - Clip* ghost_clip = olive::ActiveSequence->clips.at(g.clip); + ClipPtr ghost_clip = olive::ActiveSequence->clips.at(g.clip); for (int j=0;jclips.size();j++) { - Clip* comp_clip = olive::ActiveSequence->clips.at(j); + ClipPtr comp_clip = olive::ActiveSequence->clips.at(j); if (comp_clip->track == ghost_clip->track) { if ((panel_timeline->trim_in_point && comp_clip->timeline_out == ghost_clip->timeline_in) || (!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) { @@ -1839,10 +1839,10 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } else if (panel_timeline->tool == TIMELINE_TOOL_SLIDE) { for (int i=0;ighosts.at(i); - Clip* ghost_clip = olive::ActiveSequence->clips.at(g.clip); + ClipPtr ghost_clip = olive::ActiveSequence->clips.at(g.clip); panel_timeline->ghosts[i].trimming = false; for (int j=0;jclips.size();j++) { - Clip* c = olive::ActiveSequence->clips.at(j); + ClipPtr c = olive::ActiveSequence->clips.at(j); if (c != nullptr && c->track == ghost_clip->track) { bool found = false; for (int k=0;kghosts.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(panel_timeline->ghosts.at(i).clip); + ClipPtr c = olive::ActiveSequence->clips.at(panel_timeline->ghosts.at(i).clip); if (panel_timeline->trim_in_point) { axis = qMin(axis, c->timeline_in); } else { @@ -1883,15 +1883,15 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr && !is_clip_selected(c, true)) { bool clip_is_post = (c->timeline_in >= axis); // see if this a clip on this track is already in the list, and if it's closer bool found = false; - QVector& clip_list = clip_is_post ? post_clips : pre_clips; + QVector& clip_list = clip_is_post ? post_clips : pre_clips; for (int j=0;jtrack == c->track) { if ((!clip_is_post && compare->timeline_out < c->timeline_out) || (clip_is_post && compare->timeline_in > c->timeline_in)) { @@ -1957,15 +1957,15 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { int track_min = qMin(track_start, track_end); int track_max = qMax(track_start, track_end); - QVector selected_clips; + QVector selected_clips; for (int i=0;iclips.size();i++) { - Clip* clip = olive::ActiveSequence->clips.at(i); + ClipPtr clip = olive::ActiveSequence->clips.at(i); if (clip != nullptr && clip->track >= track_min && clip->track <= track_max && !(clip->timeline_in < frame_min && clip->timeline_out < frame_min) && !(clip->timeline_in > frame_max && clip->timeline_out > frame_max)) { - QVector session_clips; + QVector session_clips; session_clips.append(clip); if (!alt) { @@ -1977,7 +1977,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { for (int j=0;jselections.resize(selected_clips.size() + panel_timeline->selection_offset); for (int i=0;iselections[i+panel_timeline->selection_offset]; - Clip* clip = selected_clips.at(i); + ClipPtr clip = selected_clips.at(i); s.old_in = s.in = clip->timeline_in; s.old_out = s.out = clip->timeline_out; s.old_track = s.track = clip->track; @@ -2056,7 +2056,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // loop through current clips in the sequence for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr) { // cache track range @@ -2230,7 +2230,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { if (panel_timeline->transition_tool_proc) { update_ghosts(event->pos(), event->modifiers() & Qt::ShiftModifier); } else { - Clip* c = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_pre_clip); + ClipPtr c = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_pre_clip); Ghost g; @@ -2247,7 +2247,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } else { int mouse_clip = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); if (mouse_clip > -1) { - Clip* c = olive::ActiveSequence->clips.at(mouse_clip); + ClipPtr c = olive::ActiveSequence->clips.at(mouse_clip); if (same_sign(c->track, panel_timeline->transition_tool_side)) { panel_timeline->transition_tool_pre_clip = mouse_clip; long halfway = c->timeline_in + (c->getLength()/2); @@ -2285,7 +2285,7 @@ int color_brightness(int r, int g, int b) { return qRound(0.2126*r + 0.7152*g + 0.0722*b); } -void draw_waveform(Clip* clip, const FootageStream* ms, long media_length, QPainter *p, const QRect& clip_rect, int waveform_start, int waveform_limit, double zoom) { +void draw_waveform(ClipPtr clip, const FootageStream* ms, long media_length, QPainter *p, const QRect& clip_rect, int waveform_start, int waveform_limit, double zoom) { int divider = ms->audio_channels*2; int channel_height = clip_rect.height()/ms->audio_channels; @@ -2333,8 +2333,8 @@ void draw_waveform(Clip* clip, const FootageStream* ms, long media_length, QPain } } -void draw_transition(QPainter& p, Clip* c, const QRect& clip_rect, QRect& text_rect, int transition_type) { - Transition* t = (transition_type == TA_OPENING_TRANSITION) ? c->get_opening_transition() : c->get_closing_transition(); +void draw_transition(QPainter& p, ClipPtr c, const QRect& clip_rect, QRect& text_rect, int transition_type) { + TransitionPtr t = (transition_type == TA_OPENING_TRANSITION) ? c->get_opening_transition() : c->get_closing_transition(); if (t != nullptr) { QColor transition_color(255, 0, 0, 16); int transition_width = getScreenPointFromFrame(panel_timeline->zoom, t->get_true_length()); @@ -2350,7 +2350,7 @@ void draw_transition(QPainter& p, Clip* c, const QRect& clip_rect, QRect& text_r } QRect transition_rect = QRect(tr_x, tr_y, transition_width, transition_height); p.fillRect(transition_rect, transition_color); - QRect transition_text_rect(transition_rect.x() + CLIP_TEXT_PADDING, transition_rect.y() + CLIP_TEXT_PADDING, transition_rect.width() - CLIP_TEXT_PADDING, transition_rect.height() - CLIP_TEXT_PADDING); + QRect transition_text_rect(transition_rect.x() + olive::timeline::kClipTextPadding, transition_rect.y() + olive::timeline::kClipTextPadding, transition_rect.width() - olive::timeline::kClipTextPadding, transition_rect.height() - olive::timeline::kClipTextPadding); if (transition_text_rect.width() > MAX_TEXT_WIDTH) { bool draw_text = true; @@ -2392,7 +2392,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { int video_track_limit = 0; int audio_track_limit = 0; for (int i=0;iclips.size();i++) { - Clip* clip = olive::ActiveSequence->clips.at(i); + ClipPtr clip = olive::ActiveSequence->clips.at(i); if (clip != nullptr) { video_track_limit = qMin(video_track_limit, clip->track); audio_track_limit = qMax(audio_track_limit, clip->track); @@ -2416,10 +2416,10 @@ void TimelineWidget::paintEvent(QPaintEvent*) { } for (int i=0;iclips.size();i++) { - Clip* clip = olive::ActiveSequence->clips.at(i); + ClipPtr clip = olive::ActiveSequence->clips.at(i); if (clip != nullptr && is_track_visible(clip->track)) { QRect clip_rect(panel_timeline->getTimelineScreenPointFromFrame(clip->timeline_in), getScreenPointFromTrack(clip->track), getScreenPointFromFrame(panel_timeline->zoom, clip->getLength()), panel_timeline->calculate_track_height(clip->track, -1)); - QRect text_rect(clip_rect.left() + CLIP_TEXT_PADDING, clip_rect.top() + CLIP_TEXT_PADDING, clip_rect.width() - CLIP_TEXT_PADDING - 1, clip_rect.height() - CLIP_TEXT_PADDING - 1); + QRect text_rect(clip_rect.left() + olive::timeline::kClipTextPadding, clip_rect.top() + olive::timeline::kClipTextPadding, clip_rect.width() - olive::timeline::kClipTextPadding - 1, clip_rect.height() - olive::timeline::kClipTextPadding - 1); if (clip_rect.left() < width() && clip_rect.right() >= 0 && clip_rect.top() < height() && clip_rect.bottom() >= 0) { QRect actual_clip_rect = clip_rect; if (actual_clip_rect.x() < 0) actual_clip_rect.setX(0); @@ -2433,13 +2433,13 @@ void TimelineWidget::paintEvent(QPaintEvent*) { if (clip->media != nullptr && clip->media->get_type() == MEDIA_TYPE_FOOTAGE) { bool draw_checkerboard = false; QRect checkerboard_rect(clip_rect); - Footage* m = clip->media->to_footage(); + FootagePtr m = clip->media->to_footage(); FootageStream* ms = m->get_stream_from_file_index(clip->track < 0, clip->media_stream); if (ms == nullptr) { draw_checkerboard = true; } else if (ms->preview_done) { // draw top and tail triangles - int triangle_size = TRACK_MIN_HEIGHT >> 2; + int triangle_size = olive::timeline::kTrackMinHeight >> 2; if (!ms->infinite_length && clip_rect.width() > triangle_size) { p.setPen(Qt::NoPen); p.setBrush(QColor(80, 80, 80)); @@ -2478,7 +2478,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { if (clip->track < 0) { // draw thumbnail - int thumb_y = p.fontMetrics().height()+CLIP_TEXT_PADDING+CLIP_TEXT_PADDING; + int thumb_y = p.fontMetrics().height()+olive::timeline::kClipTextPadding+olive::timeline::kClipTextPadding; if (thumb_x < width() && thumb_y < height()) { int space_for_thumb = clip_rect.width()-1; if (clip->get_opening_transition() != nullptr) { @@ -2513,7 +2513,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { draw_checkerboard = true; checkerboard_rect.setLeft(panel_timeline->getTimelineScreenPointFromFrame(clip->getMaximumLength() + clip->timeline_in - clip->clip_in)); } - } else if (clip_rect.height() > TRACK_MIN_HEIGHT) { + } else if (clip_rect.height() > olive::timeline::kTrackMinHeight) { // draw waveform p.setPen(QColor(80, 80, 80)); @@ -2594,7 +2594,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { p.setPen(Qt::black); } if (clip->linked.size() > 0) { - int underline_y = CLIP_TEXT_PADDING + p.fontMetrics().height() + clip_rect.top(); + int underline_y = olive::timeline::kClipTextPadding + p.fontMetrics().height() + clip_rect.top(); int underline_width = qMin(text_rect.width() - 1, p.fontMetrics().width(clip->name)); p.drawLine(text_rect.x(), underline_y, text_rect.x() + underline_width, underline_y); } @@ -2748,7 +2748,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { insert_points.append(ghost_y + (ghost_height>>1)); p.setPen(QColor(255, 255, 0)); - for (int j=0;jgetTimelineScreenPointFromFrame(first_ghost); - int tri_size = TRACK_MIN_HEIGHT>>2; + int tri_size = olive::timeline::kTrackMinHeight>>2; for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i); + ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr && c->track == track && frame >= c->timeline_in && frame < c->timeline_out) { return i; } diff --git a/ui/timelinewidget.h b/ui/timelinewidget.h index 3fc352a6a..9a25a88dc 100644 --- a/ui/timelinewidget.h +++ b/ui/timelinewidget.h @@ -23,26 +23,30 @@ #include #include +#include +#include + +#include "project/sequence.h" +#include "project/clip.h" +#include "project/footage.h" +#include "project/media.h" +#include "project/undo.h" #include "timelinetools.h" -#define GHOST_THICKNESS 2 // thiccccc -#define CLIP_TEXT_PADDING 3 - -#define TRACK_MIN_HEIGHT 30 -#define TRACK_HEIGHT_INCREMENT 10 - -struct Sequence; -class Clip; -struct FootageStream; class Timeline; -class TimelineAction; -class QScrollBar; -class SetSelectionsCommand; -class QPainter; -class Media; + +namespace olive { + namespace timeline { + const int kGhostThickness = 2; + const int kClipTextPadding = 3; + + const int kTrackMinHeight = 30; + const int kTrackHeightIncrement = 10; + } +} bool same_sign(int a, int b); -void draw_waveform(Clip* clip, const FootageStream *ms, long media_length, QPainter* p, const QRect& clip_rect, int waveform_start, int waveform_limit, double zoom); +void draw_waveform(ClipPtr clip, const FootageStream *ms, long media_length, QPainter* p, const QRect& clip_rect, int waveform_start, int waveform_limit, double zoom); class TimelineWidget : public QWidget { Q_OBJECT @@ -80,12 +84,12 @@ private: bool track_resizing; int track_target; - QVector pre_clips; - QVector post_clips; + QVector pre_clips; + QVector post_clips; Media* rc_reveal_media; - Sequence* self_created_sequence; + SequencePtr self_created_sequence; QTimer tooltip_timer; int tooltip_clip; diff --git a/ui/viewerwidget.h b/ui/viewerwidget.h index 8af8c91a0..34c8f9d5d 100644 --- a/ui/viewerwidget.h +++ b/ui/viewerwidget.h @@ -30,16 +30,16 @@ #include #include +#include "project/clip.h" +#include "project/footage.h" +#include "project/effect.h" +#include "ui/viewerwindow.h" +#include "ui/viewercontainer.h" +#include "ui/renderthread.h" + class Viewer; -class Clip; -struct FootageStream; class QOpenGLFramebufferObject; -class Effect; -class EffectGizmo; -class ViewerContainer; struct GLTextureCoords; -class RenderThread; -class ViewerWindow; class ViewerWidget : public QOpenGLWidget, QOpenGLFunctions { @@ -57,7 +57,7 @@ public: ViewerContainer* container; bool waveform; - Clip* waveform_clip; + ClipPtr waveform_clip; const FootageStream* waveform_ms; double waveform_zoom; int waveform_scroll; @@ -81,7 +81,7 @@ private: void move_gizmos(QMouseEvent *event, bool done); bool dragging; void seek_from_click(int x); - Effect* gizmos; + EffectPtr gizmos; int drag_start_x; int drag_start_y; int gizmo_x_mvmt; From f14b0cef7d3559087c8e9f3de0586d765df0d766 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sat, 16 Feb 2019 22:22:43 -0800 Subject: [PATCH 06/30] replaced mediathrobber with mediaiconservice --- dialogs/replaceclipmediadialog.cpp | 2 +- io/loadthread.cpp | 4 +- io/previewgenerator.cpp | 11 +-- io/previewgenerator.h | 11 +-- main.cpp | 3 + olive.pro | 6 +- panels/project.cpp | 112 +++++++---------------------- panels/project.h | 17 ----- project/footage.h | 1 - project/media.cpp | 4 +- project/media.h | 3 - project/projectmodel.cpp | 2 + project/projectmodel.h | 4 ++ project/undo.cpp | 20 +++--- ui/mediaiconservice.cpp | 93 ++++++++++++++++++++++++ ui/mediaiconservice.h | 58 +++++++++++++++ ui/timelinewidget.cpp | 4 +- 17 files changed, 213 insertions(+), 142 deletions(-) create mode 100644 ui/mediaiconservice.cpp create mode 100644 ui/mediaiconservice.h diff --git a/dialogs/replaceclipmediadialog.cpp b/dialogs/replaceclipmediadialog.cpp index 7a4cdc2c2..88d7f898a 100644 --- a/dialogs/replaceclipmediadialog.cpp +++ b/dialogs/replaceclipmediadialog.cpp @@ -67,7 +67,7 @@ ReplaceClipMediaDialog::ReplaceClipMediaDialog(QWidget *parent, Media* old_media layout->addLayout(buttons); - tree->setModel(&project_model); + tree->setModel(&olive::project_model); } void ReplaceClipMediaDialog::replace() { diff --git a/io/loadthread.cpp b/io/loadthread.cpp index 741453853..bb951a159 100644 --- a/io/loadthread.cpp +++ b/io/loadthread.cpp @@ -288,7 +288,7 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) { item->set_footage(f); if (folder == 0) { - project_model.appendChild(nullptr, item); + olive::project_model.appendChild(nullptr, item); } else { find_loaded_folder_by_id(folder)->appendChild(item); } @@ -645,7 +645,7 @@ void LoadThread::run() { Media* folder = loaded_folders.at(i); int parent = folder->temp_id2; if (folder->temp_id2 == 0) { - project_model.appendChild(nullptr, folder); + olive::project_model.appendChild(nullptr, folder); } else { find_loaded_folder_by_id(parent)->appendChild(folder); } diff --git a/io/previewgenerator.cpp b/io/previewgenerator.cpp index 36c0e644c..dce3522cf 100644 --- a/io/previewgenerator.cpp +++ b/io/previewgenerator.cpp @@ -20,6 +20,7 @@ #include "previewgenerator.h" +#include "ui/mediaiconservice.h" #include "project/media.h" #include "project/footage.h" #include "panels/viewer.h" @@ -189,12 +190,12 @@ void PreviewGenerator::finalize_media() { footage->ready = true; if (!cancelled) { - if (footage->video_tracks.size() == 0) { - emit set_icon(ICON_TYPE_AUDIO, replace); + if (footage->video_tracks.size() == 0) { + olive::media_icon_service->SetMediaIcon(media, ICON_TYPE_AUDIO); } else if (contains_still_image) { - emit set_icon(ICON_TYPE_IMAGE, replace); + olive::media_icon_service->SetMediaIcon(media, ICON_TYPE_IMAGE); } else { - emit set_icon(ICON_TYPE_VIDEO, replace); + olive::media_icon_service->SetMediaIcon(media, ICON_TYPE_VIDEO); } /*if (!contains_still_image || media->audio_tracks.size() > 0) { @@ -575,7 +576,7 @@ void PreviewGenerator::run() { if (!cancelled) { if (error) { media->update_tooltip(errorStr); - emit set_icon(ICON_TYPE_ERROR, replace); + olive::media_icon_service->SetMediaIcon(media, ICON_TYPE_ERROR); footage->invalid = true; footage->ready_lock.unlock(); } else { diff --git a/io/previewgenerator.h b/io/previewgenerator.h index 40af8f64d..21bae9be7 100644 --- a/io/previewgenerator.h +++ b/io/previewgenerator.h @@ -25,13 +25,6 @@ #include #include -enum IconType { - ICON_TYPE_VIDEO, - ICON_TYPE_AUDIO, - ICON_TYPE_IMAGE, - ICON_TYPE_ERROR -}; - #include "project/footage.h" #include "project/media.h" @@ -48,9 +41,7 @@ class PreviewGenerator : public QThread public: PreviewGenerator(Media*, FootagePtr, bool); void run(); - void cancel(); -signals: - void set_icon(int, bool); + void cancel(); private: void parse_media(); bool retrieve_preview(const QString &hash); diff --git a/main.cpp b/main.cpp index 2976ef578..a4d93a56d 100644 --- a/main.cpp +++ b/main.cpp @@ -24,6 +24,7 @@ #include "debug.h" #include "oliveglobal.h" +#include "ui/mediaiconservice.h" #include "io/config.h" @@ -109,6 +110,8 @@ int main(int argc, char *argv[]) { QApplication a(argc, argv); a.setWindowIcon(QIcon(":/icons/olive64.png")); + olive::media_icon_service = std::unique_ptr(new MediaIconService()); + QCoreApplication::setOrganizationName("olivevideoeditor.org"); QCoreApplication::setOrganizationDomain("olivevideoeditor.org"); QCoreApplication::setApplicationName("Olive"); diff --git a/olive.pro b/olive.pro index dc68ad4ef..bee391b17 100644 --- a/olive.pro +++ b/olive.pro @@ -149,7 +149,8 @@ SOURCES += \ ui/menuhelper.cpp \ oliveglobal.cpp \ ui/focusfilter.cpp \ - project/comboaction.cpp + project/comboaction.cpp \ + ui/mediaiconservice.cpp HEADERS += \ mainwindow.h \ @@ -256,7 +257,8 @@ HEADERS += \ oliveglobal.h \ project/projectelements.h \ ui/focusfilter.h \ - project/comboaction.h + project/comboaction.h \ + ui/mediaiconservice.h FORMS += diff --git a/panels/project.cpp b/panels/project.cpp index c95a0f5ed..37c99194f 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -38,6 +38,7 @@ #include "ui/sourcetable.h" #include "ui/sourceiconview.h" #include "ui/menuhelper.h" +#include "ui/mediaiconservice.h" #include "project/sourcescommon.h" #include "project/projectfilter.h" #include "debug.h" @@ -63,9 +64,7 @@ extern "C" { #include } -#define MAXIMUM_RECENT_PROJECTS 10 - -ProjectModel project_model; +#define MAXIMUM_RECENT_PROJECTS 10 // FIXME: should be configurable QString autorecovery_filename; QStringList recent_projects; @@ -86,7 +85,7 @@ Project::Project(QWidget *parent) : sources_common = new SourcesCommon(this); sorter = new ProjectFilter(this); - sorter->setSourceModel(&project_model); + sorter->setSourceModel(&olive::project_model); // optional toolbar toolbar_widget = new QWidget(); @@ -223,7 +222,7 @@ Project::Project(QWidget *parent) : verticalLayout->addWidget(icon_view_container); connect(directory_up, SIGNAL(clicked(bool)), this, SLOT(go_up_dir())); - connect(icon_view, SIGNAL(changed_root()), this, SLOT(set_up_dir_enabled())); + connect(icon_view, SIGNAL(changed_root()), this, SLOT(set_up_dir_enabled())); setWindowTitle(tr("Project")); @@ -247,8 +246,8 @@ QString Project::get_next_sequence_name(QString start) { name += "0"; } name += QString::number(n); - for (int i=0;iget_name(), name, Qt::CaseInsensitive) == 0) { + for (int i=0;iget_name(), name, Qt::CaseInsensitive) == 0) { found = true; n++; break; @@ -426,7 +425,7 @@ void Project::new_folder() { Media* m = create_folder_internal(nullptr); olive::UndoStack.push(new AddMediaCommand(m, get_selected_folder())); - QModelIndex index = project_model.create_index(m->row(), 0, m); + QModelIndex index = olive::project_model.create_index(m->row(), 0, m); switch (olive::CurrentConfig.project_view_type) { case PROJECT_VIEW_TREE: tree_view->edit(sorter->mapFromSource(index)); @@ -445,7 +444,7 @@ void Project::new_sequence() { Media* Project::create_sequence_internal(ComboAction *ca, SequencePtr s, bool open, Media* parent) { if (parent == nullptr) { - parent = project_model.get_root(); + parent = olive::project_model.get_root(); } Media* item(new Media(parent)); @@ -455,8 +454,8 @@ Media* Project::create_sequence_internal(ComboAction *ca, SequencePtr s, bool op ca->append(new NewSequenceCommand(item, parent)); if (open) ca->append(new ChangeSequenceAction(s)); } else { - if (parent == project_model.get_root()) { - project_model.appendChild(parent, item); + if (parent == olive::project_model.get_root()) { + olive::project_model.appendChild(parent, item); } else { parent->appendChild(item); } @@ -534,8 +533,8 @@ void Project::delete_selected_media() { QVector parents; QList sequence_items; QList all_top_level_items; - for (int i=0;i 0) { @@ -665,15 +664,11 @@ void Project::delete_selected_media() { } void Project::start_preview_generator(Media* item, bool replacing) { - // set up throbber animation - MediaThrobber* throbber = new MediaThrobber(item); - throbber->moveToThread(QApplication::instance()->thread()); - item->throbber = throbber; - QMetaObject::invokeMethod(throbber, "start", Qt::QueuedConnection); + // set up throbber animation + olive::media_icon_service->SetMediaIcon(item, ICON_TYPE_LOADING); PreviewGenerator* pg = new PreviewGenerator(item, item->to_footage(), replacing); - item->to_footage()->preview_gen = pg; - connect(pg, SIGNAL(set_icon(int, bool)), throbber, SLOT(stop(int, bool))); + item->to_footage()->preview_gen = pg; pg->start(QThread::LowPriority); } @@ -710,7 +705,7 @@ void Project::process_file_list(QStringList& files, bool recursive, Media* repla if (create_undo_action) { ca->append(new AddMediaCommand(folder, parent)); } else { - project_model.appendChild(parent, folder); + olive::project_model.appendChild(parent, folder); } imported = true; @@ -853,9 +848,9 @@ Media* Project::get_selected_folder() { } bool Project::reveal_media(Media *media, QModelIndex parent) { - for (int i=0;iget_type() == MEDIA_TYPE_FOLDER) { @@ -963,7 +958,7 @@ void Project::clear() { } // delete everything else - project_model.clear(); + olive::project_model.clear(); // update tree view (sometimes this doesn't seem to update reliably) tree_view->update(); @@ -992,9 +987,9 @@ void save_marker(QXmlStreamWriter& stream, const Marker& m) { } void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, const QModelIndex& parent) { - for (int i=0;iget_type()) { if (m->get_type() == MEDIA_TYPE_FOLDER) { @@ -1009,7 +1004,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, if (!item.parent().isValid()) { stream.writeAttribute("parent", "0"); } else { - stream.writeAttribute("parent", QString::number(project_model.getItem(item.parent())->temp_id)); + stream.writeAttribute("parent", QString::number(olive::project_model.getItem(item.parent())->temp_id)); } stream.writeEndElement(); } @@ -1308,8 +1303,8 @@ void Project::add_recent_project(QString url) { } void Project::list_all_sequences_worker(QVector* list, Media* parent) { - for (int i=0;iget_type()) { case MEDIA_TYPE_SEQUENCE: list->append(item); @@ -1333,58 +1328,3 @@ QModelIndexList Project::get_current_selected() { } return icon_view->selectionModel()->selectedIndexes(); } - -#define THROBBER_LIMIT 20 -#define THROBBER_SIZE 50 - -MediaThrobber::MediaThrobber(Media *i) : pixmap(":/icons/throbber.png"), animation(0), item(i), animator(nullptr) {} - -void MediaThrobber::start() { - // set up throbber - animation_update(); - animator = new QTimer(this); - animator->setInterval(20); - connect(animator, SIGNAL(timeout()), this, SLOT(animation_update())); - animator->start(); -} - -void MediaThrobber::animation_update() { - if (animation == THROBBER_LIMIT) { - animation = 0; - } - project_model.set_icon(item, QIcon(pixmap.copy(THROBBER_SIZE*animation, 0, THROBBER_SIZE, THROBBER_SIZE))); - animation++; -} - -void MediaThrobber::stop(int icon_type, bool replace) { - if (animator != nullptr) { - animator->stop(); - delete animator; - } - - switch (icon_type) { - case ICON_TYPE_VIDEO: project_model.set_icon(item, QIcon(":/icons/videosource.png")); break; - case ICON_TYPE_AUDIO: project_model.set_icon(item, QIcon(":/icons/audiosource.png")); break; - case ICON_TYPE_IMAGE: project_model.set_icon(item, QIcon(":/icons/imagesource.png")); break; - case ICON_TYPE_ERROR: project_model.set_icon(item, QIcon(":/icons/error.png")); break; - } - - // refresh all clips - QVector sequences = panel_project->list_all_project_sequences(); - for (int i=0;ito_sequence(); - for (int j=0;jclips.size();j++) { - const ClipPtr& c = s->clips.at(j); - if (c != nullptr) { - c->refresh(); - } - } - } - - // redraw clips - update_ui(replace); - - panel_project->tree_view->viewport()->update(); - item->throbber = nullptr; - deleteLater(); -} diff --git a/panels/project.h b/panels/project.h index 5a073f455..52113f290 100644 --- a/panels/project.h +++ b/panels/project.h @@ -44,7 +44,6 @@ extern QString autorecovery_filename; extern QStringList recent_projects; -extern ProjectModel project_model; SequencePtr create_sequence_from_media(QVector &media_list); @@ -122,20 +121,4 @@ private slots: void make_new_menu(); }; -class MediaThrobber : public QObject { - Q_OBJECT -public: - MediaThrobber(Media*); -public slots: - void start(); - void stop(int, bool replace); -private slots: - void animation_update(); -private: - QPixmap pixmap; - int animation; - Media* item; - QTimer* animator; -}; - #endif // PROJECT_H diff --git a/project/footage.h b/project/footage.h index 9c99c2a87..979a3af98 100644 --- a/project/footage.h +++ b/project/footage.h @@ -40,7 +40,6 @@ enum VideoInterlacingMode { class Sequence; class Clip; class PreviewGenerator; -class MediaThrobber; struct FootageStream { int file_index; diff --git a/project/media.cpp b/project/media.cpp index 118d9c960..1094b3721 100644 --- a/project/media.cpp +++ b/project/media.cpp @@ -61,8 +61,7 @@ QString get_channel_layout_name(int channels, uint64_t layout) { } Media::Media(Media* iparent) : - parent(iparent), - throbber(nullptr), + parent(iparent), root(false), type(-1) {} @@ -71,7 +70,6 @@ Media::~Media() { for (int i=0;i; using VoidPtr = std::shared_ptr; -class MediaThrobber; - class Media { public: @@ -58,7 +56,6 @@ public: int get_type(); const QString& get_name(); void set_name(const QString& n); - MediaThrobber* throbber; double get_frame_rate(int stream = -1); int get_sampling_rate(int stream = -1); diff --git a/project/projectmodel.cpp b/project/projectmodel.cpp index 177eaa0fc..35fbb9633 100644 --- a/project/projectmodel.cpp +++ b/project/projectmodel.cpp @@ -26,6 +26,8 @@ #include "project/media.h" #include "debug.h" +ProjectModel olive::project_model; + ProjectModel::ProjectModel(QObject *parent) : QAbstractItemModel(parent), root_item(nullptr) { make_root(); } diff --git a/project/projectmodel.h b/project/projectmodel.h index a875dfb51..3135f1e8b 100644 --- a/project/projectmodel.h +++ b/project/projectmodel.h @@ -60,4 +60,8 @@ private: Media* root_item; }; +namespace olive { + extern ProjectModel project_model; +} + #endif // PROJECTMODEL_H diff --git a/project/undo.cpp b/project/undo.cpp index 17dfe6474..27a5b1344 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -357,7 +357,7 @@ NewSequenceCommand::NewSequenceCommand(Media *s, Media* iparent) { parent = iparent; done = false; - if (parent == nullptr) parent = project_model.get_root(); + if (parent == nullptr) parent = olive::project_model.get_root(); } NewSequenceCommand::~NewSequenceCommand() { @@ -365,13 +365,13 @@ NewSequenceCommand::~NewSequenceCommand() { } void NewSequenceCommand::doUndo() { - project_model.removeChild(parent, seq); + olive::project_model.removeChild(parent, seq); done = false; } void NewSequenceCommand::doRedo() { - project_model.appendChild(parent, seq); + olive::project_model.appendChild(parent, seq); done = true; } @@ -389,13 +389,13 @@ AddMediaCommand::~AddMediaCommand() { } void AddMediaCommand::doUndo() { - project_model.removeChild(parent, item); + olive::project_model.removeChild(parent, item); done = false; } void AddMediaCommand::doRedo() { - project_model.appendChild(parent, item); + olive::project_model.appendChild(parent, item); done = true; } @@ -412,14 +412,14 @@ DeleteMediaCommand::~DeleteMediaCommand() { } void DeleteMediaCommand::doUndo() { - project_model.appendChild(parent, item); + olive::project_model.appendChild(parent, item); done = false; } void DeleteMediaCommand::doRedo() { - project_model.removeChild(parent, item); + olive::project_model.removeChild(parent, item); done = true; } @@ -641,18 +641,18 @@ MediaMove::MediaMove() {} void MediaMove::doUndo() { for (int i=0;iparentItem(); froms[i] = parent; - project_model.moveChild(items.at(i), to); + olive::project_model.moveChild(items.at(i), to); } } diff --git a/ui/mediaiconservice.cpp b/ui/mediaiconservice.cpp new file mode 100644 index 000000000..6a2578d17 --- /dev/null +++ b/ui/mediaiconservice.cpp @@ -0,0 +1,93 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 Olive Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#include "mediaiconservice.h" + +const int kThrobberLimit = 20; +const int kThrobberSize = 50; + +#include "project/projectmodel.h" + +std::unique_ptr olive::media_icon_service; + +MediaIconService::MediaIconService() { + // set up animation timer + throbber_animator_.setInterval(20); + connect(&throbber_animator_, SIGNAL(timeout()), this, SLOT(AnimationUpdate())); + + // set up pixmap + throbber_pixmap_ = QPixmap(":/icons/throbber.png"); +} + +void MediaIconService::SetMediaIcon(Media *media, int icon_type) { + // if this icon is already part of the throbber animation loop, remove it + if (throbber_items_.contains(media)) { + throbber_items_.removeAll(media); + + // if we aren't animating anything, no need to run the timer for now + if (throbber_items_.empty()) { + // ensure timer function is called in its own thread + QMetaObject::invokeMethod(&throbber_animator_, "stop", Qt::QueuedConnection); + } + } + + switch (icon_type) { + case ICON_TYPE_VIDEO: + olive::project_model.set_icon(media, QIcon(":/icons/videosource.png")); + break; + case ICON_TYPE_AUDIO: + olive::project_model.set_icon(media, QIcon(":/icons/audiosource.png")); + break; + case ICON_TYPE_IMAGE: + olive::project_model.set_icon(media, QIcon(":/icons/imagesource.png")); + break; + case ICON_TYPE_LOADING: + throbber_items_.append(media); + + // if the animation timer isn't running, start it + if (!throbber_animator_.isActive()) { + // set starting frame to 0 + throbber_animation_frame_ = 0; + + // ensure timer function is called in its own thread + QMetaObject::invokeMethod(&throbber_animator_, "start", Qt::QueuedConnection); + } + break; + case ICON_TYPE_ERROR: + olive::project_model.set_icon(media, QIcon(":/icons/error.png")); + break; + } + + emit IconChanged(); +} + +void MediaIconService::AnimationUpdate() { + if (throbber_animation_frame_ == kThrobberLimit) { + throbber_animation_frame_ = 0; + } + + QIcon throbber_ico = QIcon(throbber_pixmap_.copy(kThrobberSize*throbber_animation_frame_, 0, kThrobberSize, kThrobberSize)); + + for (int i=0;i. + +***/ + +#ifndef MEDIAICONSERVICE_H +#define MEDIAICONSERVICE_H + +#include +#include + +#include "project/media.h" + +enum IconType { + ICON_TYPE_VIDEO, + ICON_TYPE_AUDIO, + ICON_TYPE_IMAGE, + ICON_TYPE_LOADING, + ICON_TYPE_ERROR +}; + +class MediaIconService : public QObject { + Q_OBJECT +public: + MediaIconService(); +public slots: + void SetMediaIcon(Media* media, int icon_type); +signals: + void IconChanged(); +private slots: + void AnimationUpdate(); +private: + int throbber_animation_frame_; + QVector throbber_items_; + QTimer throbber_animator_; + QPixmap throbber_pixmap_; +}; + +namespace olive { + extern std::unique_ptr media_icon_service; +} + +#endif // MEDIAICONSERVICE_H diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index d18c45ecf..1d8afcbac 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -244,8 +244,8 @@ void TimelineWidget::rename_clip() { void TimelineWidget::open_sequence_properties() { QList sequence_items; QList all_top_level_items; - for (int i=0;iget_all_media_from_table(all_top_level_items, sequence_items, MEDIA_TYPE_SEQUENCE); // find all sequences in project for (int i=0;i Date: Sat, 16 Feb 2019 22:24:33 -0800 Subject: [PATCH 07/30] moved inits into constructor --- project/media.cpp | 10 +++++----- project/sequence.cpp | 13 ++++++------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/project/media.cpp b/project/media.cpp index 1094b3721..2f006d68a 100644 --- a/project/media.cpp +++ b/project/media.cpp @@ -60,11 +60,11 @@ QString get_channel_layout_name(int channels, uint64_t layout) { } } -Media::Media(Media* iparent) : - parent(iparent), - root(false), - type(-1) -{} +Media::Media(Media* iparent) { + parent = iparent; + root = false; + type = -1; +} Media::~Media() { for (int i=0;i Date: Sun, 17 Feb 2019 01:18:03 -0800 Subject: [PATCH 08/30] began transition rewrite --- effects/internal/crossdissolvetransition.cpp | 4 +- .../internal/exponentialfadetransition.cpp | 4 +- effects/internal/linearfadetransition.cpp | 4 +- .../internal/logarithmicfadetransition.cpp | 4 +- io/loadthread.cpp | 24 +- io/previewgenerator.cpp | 942 ++++++------ io/previewgenerator.h | 44 +- main.cpp | 175 +-- panels/effectcontrols.cpp | 788 +++++----- panels/panels.cpp | 12 +- panels/project.cpp | 4 + panels/timeline.cpp | 36 +- playback/cacher.cpp | 4 +- project/clip.cpp | 451 +++--- project/clip.h | 188 +-- project/sequence.cpp | 36 - project/sequence.h | 4 +- project/transition.cpp | 116 +- project/transition.h | 64 +- project/undo.cpp | 1267 ++++++++--------- project/undo.h | 666 +++++---- ui/renderfunctions.cpp | 6 +- ui/timelinewidget.cpp | 106 +- 23 files changed, 2446 insertions(+), 2503 deletions(-) diff --git a/effects/internal/crossdissolvetransition.cpp b/effects/internal/crossdissolvetransition.cpp index 2e0a01600..a9d3fae35 100644 --- a/effects/internal/crossdissolvetransition.cpp +++ b/effects/internal/crossdissolvetransition.cpp @@ -29,8 +29,8 @@ CrossDissolveTransition::CrossDissolveTransition(ClipPtr c, ClipPtr s, const Eff } void CrossDissolveTransition::process_coords(double progress, GLTextureCoords& coords, int data) { - if (!(data == TA_CLOSING_TRANSITION && secondary_clip != nullptr)) { - if (data == TA_CLOSING_TRANSITION) progress = 1.0 - progress; + if (!(data == kTransitionClosing && secondary_clip != nullptr)) { + if (data == kTransitionClosing) progress = 1.0 - progress; coords.opacity *= progress; } } diff --git a/effects/internal/exponentialfadetransition.cpp b/effects/internal/exponentialfadetransition.cpp index be558d7cd..e82c0275d 100644 --- a/effects/internal/exponentialfadetransition.cpp +++ b/effects/internal/exponentialfadetransition.cpp @@ -41,10 +41,10 @@ void ExponentialFadeTransition::process_audio(double timecode_start, double time break; }*/ switch (type) { - case TA_OPENING_TRANSITION: + case kTransitionOpening: samp *= qPow(timecode_start + (interval * i), 2); break; - case TA_CLOSING_TRANSITION: + case kTransitionClosing: samp *= qPow(1 - (timecode_start + (interval * i)), 2); break; } diff --git a/effects/internal/linearfadetransition.cpp b/effects/internal/linearfadetransition.cpp index 5cfb5edb7..c8e65c95f 100644 --- a/effects/internal/linearfadetransition.cpp +++ b/effects/internal/linearfadetransition.cpp @@ -29,10 +29,10 @@ void LinearFadeTransition::process_audio(double timecode_start, double timecode_ qint16 samp = (qint16) (((samples[i+1] & 0xFF) << 8) | (samples[i] & 0xFF)); switch (type) { - case TA_OPENING_TRANSITION: + case kTransitionOpening: samp *= timecode_start + (interval * i); break; - case TA_CLOSING_TRANSITION: + case kTransitionClosing: samp *= 1 - (timecode_start + (interval * i)); break; } diff --git a/effects/internal/logarithmicfadetransition.cpp b/effects/internal/logarithmicfadetransition.cpp index 4da914e9f..d4af9d860 100644 --- a/effects/internal/logarithmicfadetransition.cpp +++ b/effects/internal/logarithmicfadetransition.cpp @@ -31,10 +31,10 @@ void LogarithmicFadeTransition::process_audio(double timecode_start, double time qint16 samp = (qint16) (((samples[i+1] & 0xFF) << 8) | (samples[i] & 0xFF)); switch (type) { - case TA_OPENING_TRANSITION: + case kTransitionOpening: samp *= qSqrt(timecode_start + (interval * i)); break; - case TA_CLOSING_TRANSITION: + case kTransitionClosing: samp *= qSqrt(1 - (timecode_start + (interval * i))); break; } diff --git a/io/loadthread.cpp b/io/loadthread.cpp index bb951a159..e95034694 100644 --- a/io/loadthread.cpp +++ b/io/loadthread.cpp @@ -80,11 +80,11 @@ void LoadThread::load_effect(QXmlStreamReader& stream, ClipPtr c) { int type; if (tag == "opening") { - type = TA_OPENING_TRANSITION; + type = kTransitionOpening; } else if (tag == "closing") { - type = TA_CLOSING_TRANSITION; + type = kTransitionClosing; } else { - type = TA_NO_TRANSITION; + type = kTransitionNone; } emit start_create_effect_ui(&stream, c, type, &effect_name, meta, effect_length, effect_enabled); @@ -391,11 +391,11 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) { } else if (attr.name() == "track") { c->track = attr.value().toInt(); } else if (attr.name() == "r") { - c->color_r = attr.value().toInt(); + c->color_r = quint8(attr.value().toInt()); } else if (attr.name() == "g") { - c->color_g = attr.value().toInt(); + c->color_g = quint8(attr.value().toInt()); } else if (attr.name() == "b") { - c->color_b = attr.value().toInt(); + c->color_b = quint8(attr.value().toInt()); } else if (attr.name() == "autoscale") { c->autoscale = (attr.value() == "1"); } else if (attr.name() == "media") { @@ -409,10 +409,12 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) { c->maintain_audio_pitch = (attr.value() == "1"); } else if (attr.name() == "reverse") { c->reverse = (attr.value() == "1"); + /* } else if (attr.name() == "opening") { c->opening_transition = attr.value().toInt(); } else if (attr.name() == "closing") { c->closing_transition = attr.value().toInt(); + */ } else if (attr.name() == "sequence") { media_type = MEDIA_TYPE_SEQUENCE; @@ -514,6 +516,7 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) { } } + /* // re-link clips to transitions if (correct_clip->opening_transition > -1) { for (int j=0;jcreate_sequence_internal(nullptr, s, false, parent); @@ -792,7 +796,7 @@ void LoadThread::create_effect_ui( mutex.lock(); if (cancelled) return; - if (type == TA_NO_TRANSITION) { + if (type == kTransitionNone) { if (meta == nullptr) { // create void effect EffectPtr ve(new VoidEffect(c, *effect_name)); @@ -807,17 +811,19 @@ void LoadThread::create_effect_ui( c->effects.append(e); } } else { + /* int transition_index = create_transition(c, nullptr, meta); TransitionPtr t = c->sequence->transitions.at(transition_index); if (effect_length > -1) t->set_length(effect_length); t->set_enabled(effect_enabled); t->load(*stream); - if (type == TA_OPENING_TRANSITION) { + if (type == kTransitionOpening) { c->opening_transition = transition_index; } else { c->closing_transition = transition_index; } + */ } mutex.unlock(); @@ -829,10 +835,12 @@ void LoadThread::create_dual_transition(const TransitionData* td, ClipPtr primar // lock mutex - ensures the load thread is suspended while this happens mutex.lock(); + /* int transition_index = create_transition(primary, secondary, meta); primary->sequence->transitions.at(transition_index)->set_length(td->length); if (td->otc != nullptr) td->otc->opening_transition = transition_index; if (td->ctc != nullptr) td->ctc->closing_transition = transition_index; + */ mutex.unlock(); diff --git a/io/previewgenerator.cpp b/io/previewgenerator.cpp index dce3522cf..e04e5e340 100644 --- a/io/previewgenerator.cpp +++ b/io/previewgenerator.cpp @@ -40,555 +40,543 @@ QSemaphore sem(5); // only 5 preview generators can run at one time PreviewGenerator::PreviewGenerator(Media* i, FootagePtr m, bool r) : - QThread(nullptr), - fmt_ctx(nullptr), - media(i), - footage(m), - retrieve_duration(false), - contains_still_image(false), - replace(r), - cancelled(false) + QThread(nullptr), + fmt_ctx(nullptr), + media(i), + footage(m), + retrieve_duration(false), + contains_still_image(false), + replace(r), + cancelled(false) { - data_dir = QDir(get_data_dir().filePath("previews")); - if (!data_dir.exists()) { - data_dir.mkpath("."); - } + data_dir = QDir(get_data_dir().filePath("previews")); + if (!data_dir.exists()) { + data_dir.mkpath("."); + } - connect(this, SIGNAL(finished()), this, SLOT(deleteLater())); + connect(this, SIGNAL(finished()), this, SLOT(deleteLater())); } void PreviewGenerator::parse_media() { - // detect video/audio streams in file - for (int i=0;inb_streams);i++) { - // Find the decoder for the video stream - if (avcodec_find_decoder(fmt_ctx->streams[i]->codecpar->codec_id) == nullptr) { - qCritical() << "Unsupported codec in stream" << i << "of file" << footage->name; - } else { - FootageStream ms; - ms.preview_done = false; - ms.file_index = i; - ms.enabled = true; - ms.infinite_length = false; + // detect video/audio streams in file + for (int i=0;inb_streams);i++) { + // Find the decoder for the video stream + if (avcodec_find_decoder(fmt_ctx->streams[i]->codecpar->codec_id) == nullptr) { + qCritical() << "Unsupported codec in stream" << i << "of file" << footage->name; + } else { + FootageStream ms; + ms.preview_done = false; + ms.file_index = i; + ms.enabled = true; + ms.infinite_length = false; - bool append = false; + bool append = false; - if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO - && fmt_ctx->streams[i]->codecpar->width > 0 - && fmt_ctx->streams[i]->codecpar->height > 0) { + if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO + && fmt_ctx->streams[i]->codecpar->width > 0 + && fmt_ctx->streams[i]->codecpar->height > 0) { - // heuristic to determine if video is a still image (if it is, we treat it differently in the playback/render process) - if (fmt_ctx->streams[i]->avg_frame_rate.den == 0 - && fmt_ctx->streams[i]->codecpar->codec_id != AV_CODEC_ID_DNXHD) { // silly hack but this is the only scenario i've seen this - if (footage->url.contains('%')) { - // must be an image sequence - ms.video_frame_rate = 25; - } else { - ms.infinite_length = true; - contains_still_image = true; - ms.video_frame_rate = 0; - } + // heuristic to determine if video is a still image (if it is, we treat it differently in the playback/render process) + if (fmt_ctx->streams[i]->avg_frame_rate.den == 0 + && fmt_ctx->streams[i]->codecpar->codec_id != AV_CODEC_ID_DNXHD) { // silly hack but this is the only scenario i've seen this + if (footage->url.contains('%')) { + // must be an image sequence + ms.video_frame_rate = 25; + } else { + ms.infinite_length = true; + contains_still_image = true; + ms.video_frame_rate = 0; + } - } else { - // using ffmpeg's built-in heuristic - ms.video_frame_rate = av_q2d(av_guess_frame_rate(fmt_ctx, fmt_ctx->streams[i], nullptr)); - } + } else { + // using ffmpeg's built-in heuristic + ms.video_frame_rate = av_q2d(av_guess_frame_rate(fmt_ctx, fmt_ctx->streams[i], nullptr)); + } - ms.video_width = fmt_ctx->streams[i]->codecpar->width; - ms.video_height = fmt_ctx->streams[i]->codecpar->height; + ms.video_width = fmt_ctx->streams[i]->codecpar->width; + ms.video_height = fmt_ctx->streams[i]->codecpar->height; - // default value, we get the true value later in generate_waveform() - ms.video_auto_interlacing = VIDEO_PROGRESSIVE; - ms.video_interlacing = VIDEO_PROGRESSIVE; + // default value, we get the true value later in generate_waveform() + ms.video_auto_interlacing = VIDEO_PROGRESSIVE; + ms.video_interlacing = VIDEO_PROGRESSIVE; - append = true; - } else if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { - ms.audio_channels = fmt_ctx->streams[i]->codecpar->channels; - ms.audio_layout = int(fmt_ctx->streams[i]->codecpar->channel_layout); - ms.audio_frequency = fmt_ctx->streams[i]->codecpar->sample_rate; + append = true; + } else if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { + ms.audio_channels = fmt_ctx->streams[i]->codecpar->channels; + ms.audio_layout = int(fmt_ctx->streams[i]->codecpar->channel_layout); + ms.audio_frequency = fmt_ctx->streams[i]->codecpar->sample_rate; - append = true; - } + append = true; + } - if (append) { - QVector& stream_list = (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) ? footage->audio_tracks : footage->video_tracks; - for (int j=0;jlength = fmt_ctx->duration; + if (append) { + QVector& stream_list = (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) ? footage->audio_tracks : footage->video_tracks; + for (int j=0;jlength = fmt_ctx->duration; - if (fmt_ctx->duration == INT64_MIN) { - retrieve_duration = true; - } else { - finalize_media(); - } + if (fmt_ctx->duration == INT64_MIN) { + retrieve_duration = true; + } else { + finalize_media(); + } } bool PreviewGenerator::retrieve_preview(const QString& hash) { - // returns true if generate_waveform must be run, false if we got all previews from cached files - if (retrieve_duration) { - //dout << "[NOTE] " << media->name << "needs to retrieve duration"; - return true; - } + // returns true if generate_waveform must be run, false if we got all previews from cached files + if (retrieve_duration) { + //dout << "[NOTE] " << media->name << "needs to retrieve duration"; + return true; + } - bool found = true; - for (int i=0;ivideo_tracks.size();i++) { - FootageStream& ms = footage->video_tracks[i]; - QString thumb_path = get_thumbnail_path(hash, ms); - QFile f(thumb_path); - if (f.exists() && ms.video_preview.load(thumb_path)) { - //dout << "loaded thumb" << ms->file_index << "from" << thumb_path; - ms.make_square_thumb(); - ms.preview_done = true; - } else { - found = false; - break; - } - } - for (int i=0;iaudio_tracks.size();i++) { - FootageStream& ms = footage->audio_tracks[i]; - QString waveform_path = get_waveform_path(hash, ms); - QFile f(waveform_path); - if (f.exists()) { - //dout << "loaded wave" << ms->file_index << "from" << waveform_path; - f.open(QFile::ReadOnly); - QByteArray data = f.readAll(); - ms.audio_preview.resize(data.size()); - for (int j=0;jvideo_tracks.size();i++) { - FootageStream& ms = footage->video_tracks[i]; - ms.preview_done = false; - } - for (int i=0;iaudio_tracks.size();i++) { - FootageStream& ms = footage->audio_tracks[i]; - ms.audio_preview.clear(); - ms.preview_done = false; - } - } - return !found; + bool found = true; + for (int i=0;ivideo_tracks.size();i++) { + FootageStream& ms = footage->video_tracks[i]; + QString thumb_path = get_thumbnail_path(hash, ms); + QFile f(thumb_path); + if (f.exists() && ms.video_preview.load(thumb_path)) { + //dout << "loaded thumb" << ms->file_index << "from" << thumb_path; + ms.make_square_thumb(); + ms.preview_done = true; + } else { + found = false; + break; + } + } + for (int i=0;iaudio_tracks.size();i++) { + FootageStream& ms = footage->audio_tracks[i]; + QString waveform_path = get_waveform_path(hash, ms); + QFile f(waveform_path); + if (f.exists()) { + //dout << "loaded wave" << ms->file_index << "from" << waveform_path; + f.open(QFile::ReadOnly); + QByteArray data = f.readAll(); + ms.audio_preview.resize(data.size()); + for (int j=0;jvideo_tracks.size();i++) { + FootageStream& ms = footage->video_tracks[i]; + ms.preview_done = false; + } + for (int i=0;iaudio_tracks.size();i++) { + FootageStream& ms = footage->audio_tracks[i]; + ms.audio_preview.clear(); + ms.preview_done = false; + } + } + return !found; } void PreviewGenerator::finalize_media() { - footage->ready_lock.unlock(); - footage->ready = true; + footage->ready_lock.unlock(); + footage->ready = true; - if (!cancelled) { - if (footage->video_tracks.size() == 0) { - olive::media_icon_service->SetMediaIcon(media, ICON_TYPE_AUDIO); - } else if (contains_still_image) { - olive::media_icon_service->SetMediaIcon(media, ICON_TYPE_IMAGE); - } else { - olive::media_icon_service->SetMediaIcon(media, ICON_TYPE_VIDEO); - } - - /*if (!contains_still_image || media->audio_tracks.size() > 0) { - double frame_rate = 30; - if (!contains_still_image && media->video_tracks.size() > 0) frame_rate = media->video_tracks.at(0)->video_frame_rate; - item->setText(1, frame_to_timecode(media->get_length_in_frames(frame_rate), config.timecode_view, frame_rate)); - - if (media->video_tracks.size() > 0) { - item->setText(2, QString::number(frame_rate) + " FPS"); - } else { - item->setText(2, QString::number(media->audio_tracks.at(0)->audio_frequency) + " Hz"); - } - }*/ - } + if (!cancelled) { + if (footage->video_tracks.size() == 0) { + olive::media_icon_service->SetMediaIcon(media, ICON_TYPE_AUDIO); + } else if (contains_still_image) { + olive::media_icon_service->SetMediaIcon(media, ICON_TYPE_IMAGE); + } else { + olive::media_icon_service->SetMediaIcon(media, ICON_TYPE_VIDEO); + } + } } void thumb_data_cleanup(void *info) { - delete [] static_cast(info); + delete [] static_cast(info); } void PreviewGenerator::generate_waveform() { - SwsContext* sws_ctx; - SwrContext* swr_ctx; - AVFrame* temp_frame = av_frame_alloc(); + SwsContext* sws_ctx; + SwrContext* swr_ctx; + AVFrame* temp_frame = av_frame_alloc(); - // stores codec contexts for format's streams - AVCodecContext** codec_ctx = new AVCodecContext* [fmt_ctx->nb_streams]; + // stores codec contexts for format's streams + AVCodecContext** codec_ctx = new AVCodecContext* [fmt_ctx->nb_streams]; - // stores media lengths while scanning in case the format has no duration metadata - int64_t* media_lengths = new int64_t[fmt_ctx->nb_streams]{0}; + // stores media lengths while scanning in case the format has no duration metadata + int64_t* media_lengths = new int64_t[fmt_ctx->nb_streams]{0}; - // stores samples while scanning before they get sent to preview file - qint16*** waveform_cache_data = new qint16** [fmt_ctx->nb_streams]; - int waveform_cache_count = 0; + // stores samples while scanning before they get sent to preview file + qint16*** waveform_cache_data = new qint16** [fmt_ctx->nb_streams]; + int waveform_cache_count = 0; - // defaults to false, sets to true if we find a valid stream to make a preview of - bool create_previews = false; + // defaults to false, sets to true if we find a valid stream to make a preview of + bool create_previews = false; - for (unsigned int i=0;inb_streams;i++) { + for (unsigned int i=0;inb_streams;i++) { - // default to nullptr values for easier memory management later - codec_ctx[i] = nullptr; - waveform_cache_data[i] = nullptr; + // default to nullptr values for easier memory management later + codec_ctx[i] = nullptr; + waveform_cache_data[i] = nullptr; - // we only generate previews for video and audio - // and only if the thumbnail and waveform sizes are > 0 - if ((fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && olive::CurrentConfig.thumbnail_resolution > 0) - || (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && olive::CurrentConfig.waveform_resolution > 0)) { - AVCodec* codec = avcodec_find_decoder(fmt_ctx->streams[i]->codecpar->codec_id); - if (codec != nullptr) { + // we only generate previews for video and audio + // and only if the thumbnail and waveform sizes are > 0 + if ((fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && olive::CurrentConfig.thumbnail_resolution > 0) + || (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && olive::CurrentConfig.waveform_resolution > 0)) { + AVCodec* codec = avcodec_find_decoder(fmt_ctx->streams[i]->codecpar->codec_id); + if (codec != nullptr) { - // alloc the context and load the params into it - codec_ctx[i] = avcodec_alloc_context3(codec); - avcodec_parameters_to_context(codec_ctx[i], fmt_ctx->streams[i]->codecpar); + // alloc the context and load the params into it + codec_ctx[i] = avcodec_alloc_context3(codec); + avcodec_parameters_to_context(codec_ctx[i], fmt_ctx->streams[i]->codecpar); - // open the decoder - avcodec_open2(codec_ctx[i], codec, nullptr); + // open the decoder + avcodec_open2(codec_ctx[i], codec, nullptr); - // audio specific functions - if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { + // audio specific functions + if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { - // allocate sample cache for this stream - waveform_cache_data[i] = new qint16* [fmt_ctx->streams[i]->codecpar->channels]; + // allocate sample cache for this stream + waveform_cache_data[i] = new qint16* [fmt_ctx->streams[i]->codecpar->channels]; - // each channel gets a min and a max value so we allocate two ints for each one - for (int j=0;jstreams[i]->codecpar->channels;j++) { - waveform_cache_data[i][j] = new qint16[2]; - } + // each channel gets a min and a max value so we allocate two ints for each one + for (int j=0;jstreams[i]->codecpar->channels;j++) { + waveform_cache_data[i][j] = new qint16[2]; + } - // if codec context has no defined channel layout, guess it from the channel count - if (codec_ctx[i]->channel_layout == 0) { - codec_ctx[i]->channel_layout = av_get_default_channel_layout(fmt_ctx->streams[i]->codecpar->channels); - } + // if codec context has no defined channel layout, guess it from the channel count + if (codec_ctx[i]->channel_layout == 0) { + codec_ctx[i]->channel_layout = av_get_default_channel_layout(fmt_ctx->streams[i]->codecpar->channels); + } - } + } - // enable next step of process - create_previews = true; - } - } + // enable next step of process + create_previews = true; + } + } + } + + if (create_previews) { + // TODO may be unnecessary - doesn't av_read_frame allocate a packet itself? + AVPacket* packet = av_packet_alloc(); + + bool done = true; + + bool end_of_file = false; + + // get the ball rolling + do { + av_read_frame(fmt_ctx, packet); + } while (codec_ctx[packet->stream_index] == nullptr); + avcodec_send_packet(codec_ctx[packet->stream_index], packet); + + while (!end_of_file) { + while (codec_ctx[packet->stream_index] == nullptr || avcodec_receive_frame(codec_ctx[packet->stream_index], temp_frame) == AVERROR(EAGAIN)) { + av_packet_unref(packet); + int read_ret = av_read_frame(fmt_ctx, packet); + + //dout << "read frame for" << footage->name << footage->url << read_ret << "retrieve_duration:" << retrieve_duration << "eof:" << end_of_file << "packet pts:" << packet->pts; + + if (read_ret < 0) { + end_of_file = true; + if (read_ret != AVERROR_EOF) qCritical() << "Failed to read packet for preview generation" << read_ret; + break; + } + if (codec_ctx[packet->stream_index] != nullptr) { + int send_ret = avcodec_send_packet(codec_ctx[packet->stream_index], packet); + if (send_ret < 0 && send_ret != AVERROR(EAGAIN)) { + qCritical() << "Failed to send packet for preview generation - aborting" << send_ret; + end_of_file = true; + break; + } + } + } + if (!end_of_file) { + FootageStream* s = footage->get_stream_from_file_index(fmt_ctx->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO, packet->stream_index); + if (s != nullptr) { + if (fmt_ctx->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + if (!s->preview_done) { + int dstH = olive::CurrentConfig.thumbnail_resolution; + int dstW = qRound(dstH * (float(temp_frame->width)/float(temp_frame->height))); + uint8_t* data = new uint8_t[size_t(dstW*dstH*4)]; + + sws_ctx = sws_getContext( + temp_frame->width, + temp_frame->height, + static_cast(temp_frame->format), + dstW, + dstH, + static_cast(AV_PIX_FMT_RGBA), + SWS_FAST_BILINEAR, + nullptr, + nullptr, + nullptr + ); + + int linesize[AV_NUM_DATA_POINTERS]; + linesize[0] = dstW*4; + sws_scale(sws_ctx, temp_frame->data, temp_frame->linesize, 0, temp_frame->height, &data, linesize); + + s->video_preview = QImage(data, dstW, dstH, linesize[0], QImage::Format_RGBA8888, thumb_data_cleanup); + s->make_square_thumb(); + + // is video interlaced? + s->video_auto_interlacing = (temp_frame->interlaced_frame) ? ((temp_frame->top_field_first) ? VIDEO_TOP_FIELD_FIRST : VIDEO_BOTTOM_FIELD_FIRST) : VIDEO_PROGRESSIVE; + s->video_interlacing = s->video_auto_interlacing; + + s->preview_done = true; + + sws_freeContext(sws_ctx); + + if (!retrieve_duration) { + avcodec_close(codec_ctx[packet->stream_index]); + codec_ctx[packet->stream_index] = nullptr; + } + } + media_lengths[packet->stream_index]++; + } else if (fmt_ctx->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { + AVFrame* swr_frame = av_frame_alloc(); + swr_frame->channel_layout = temp_frame->channel_layout; + swr_frame->sample_rate = temp_frame->sample_rate; + swr_frame->format = AV_SAMPLE_FMT_S16P; + + swr_ctx = swr_alloc_set_opts( + nullptr, + temp_frame->channel_layout, + static_cast(swr_frame->format), + temp_frame->sample_rate, + temp_frame->channel_layout, + static_cast(temp_frame->format), + temp_frame->sample_rate, + 0, + nullptr + ); + + swr_init(swr_ctx); + + swr_convert_frame(swr_ctx, swr_frame, temp_frame); + + // `config.waveform_resolution` determines how many samples per second are stored in waveform. + // `sample_rate` is samples per second, so `interval` is how many samples are averaged in + // each "point" of the waveform + int interval = qFloor((temp_frame->sample_rate/olive::CurrentConfig.waveform_resolution)/4)*4; + + // get the amount of bytes in an audio sample + int sample_size = av_get_bytes_per_sample(static_cast(swr_frame->format)); + + // total amount of data in this frame + int nb_bytes = swr_frame->nb_samples * sample_size; + + // loop through entire frame + for (int i=0;ichannels;j++) { + qint16& min = waveform_cache_data[packet->stream_index][j][0]; + qint16& max = waveform_cache_data[packet->stream_index][j][1]; + + s->audio_preview.append(min >> 8); + s->audio_preview.append(max >> 8); + } + + waveform_cache_count = 0; + } + + // standard processing for each channel of information + for (int j=0;jchannels;j++) { + qint16& min = waveform_cache_data[packet->stream_index][j][0]; + qint16& max = waveform_cache_data[packet->stream_index][j][1]; + + // if we're starting over, reset cache to zero + if (waveform_cache_count == 0) { + min = 0; + max = 0; + } + + // store most minimum and most maximum samples of this interval + qint16 sample = qint16((swr_frame->data[j][i+1] << 8) | swr_frame->data[j][i]); + min = qMin(min, sample); + max = qMax(max, sample); + } + + waveform_cache_count++; + + if (cancelled) { + break; + } + } + + swr_free(&swr_ctx); + av_frame_free(&swr_frame); + + if (cancelled) { + end_of_file = true; + break; + } + } + } + + // check if we've got all our previews + if (retrieve_duration) { + done = false; + } else if (footage->audio_tracks.size() == 0) { + done = true; + for (int i=0;ivideo_tracks.size();i++) { + if (!footage->video_tracks.at(i).preview_done) { + done = false; + break; + } + } + if (done) { + end_of_file = true; + break; + } + } + av_packet_unref(packet); + } } - if (create_previews) { - // TODO may be unnecessary - doesn't av_read_frame allocate a packet itself? - AVPacket* packet = av_packet_alloc(); + av_frame_free(&temp_frame); + av_packet_free(&packet); - bool done = true; - - bool end_of_file = false; - - // get the ball rolling - do { - av_read_frame(fmt_ctx, packet); - } while (codec_ctx[packet->stream_index] == nullptr); - avcodec_send_packet(codec_ctx[packet->stream_index], packet); - - while (!end_of_file) { - while (codec_ctx[packet->stream_index] == nullptr || avcodec_receive_frame(codec_ctx[packet->stream_index], temp_frame) == AVERROR(EAGAIN)) { - av_packet_unref(packet); - int read_ret = av_read_frame(fmt_ctx, packet); - - //dout << "read frame for" << footage->name << footage->url << read_ret << "retrieve_duration:" << retrieve_duration << "eof:" << end_of_file << "packet pts:" << packet->pts; - - if (read_ret < 0) { - end_of_file = true; - if (read_ret != AVERROR_EOF) qCritical() << "Failed to read packet for preview generation" << read_ret; - break; - } - if (codec_ctx[packet->stream_index] != nullptr) { - int send_ret = avcodec_send_packet(codec_ctx[packet->stream_index], packet); - if (send_ret < 0 && send_ret != AVERROR(EAGAIN)) { - qCritical() << "Failed to send packet for preview generation - aborting" << send_ret; - end_of_file = true; - break; - } - } - } - if (!end_of_file) { - FootageStream* s = footage->get_stream_from_file_index(fmt_ctx->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO, packet->stream_index); - if (s != nullptr) { - if (fmt_ctx->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { - if (!s->preview_done) { - int dstH = olive::CurrentConfig.thumbnail_resolution; - int dstW = qRound(dstH * (float(temp_frame->width)/float(temp_frame->height))); - uint8_t* data = new uint8_t[size_t(dstW*dstH*4)]; - - sws_ctx = sws_getContext( - temp_frame->width, - temp_frame->height, - static_cast(temp_frame->format), - dstW, - dstH, - static_cast(AV_PIX_FMT_RGBA), - SWS_FAST_BILINEAR, - nullptr, - nullptr, - nullptr - ); - - int linesize[AV_NUM_DATA_POINTERS]; - linesize[0] = dstW*4; - sws_scale(sws_ctx, temp_frame->data, temp_frame->linesize, 0, temp_frame->height, &data, linesize); - - s->video_preview = QImage(data, dstW, dstH, linesize[0], QImage::Format_RGBA8888, thumb_data_cleanup); - s->make_square_thumb(); - - // is video interlaced? - s->video_auto_interlacing = (temp_frame->interlaced_frame) ? ((temp_frame->top_field_first) ? VIDEO_TOP_FIELD_FIRST : VIDEO_BOTTOM_FIELD_FIRST) : VIDEO_PROGRESSIVE; - s->video_interlacing = s->video_auto_interlacing; - - s->preview_done = true; - - sws_freeContext(sws_ctx); - - if (!retrieve_duration) { - avcodec_close(codec_ctx[packet->stream_index]); - codec_ctx[packet->stream_index] = nullptr; - } - } - media_lengths[packet->stream_index]++; - } else if (fmt_ctx->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { - AVFrame* swr_frame = av_frame_alloc(); - swr_frame->channel_layout = temp_frame->channel_layout; - swr_frame->sample_rate = temp_frame->sample_rate; - swr_frame->format = AV_SAMPLE_FMT_S16P; - - swr_ctx = swr_alloc_set_opts( - nullptr, - temp_frame->channel_layout, - static_cast(swr_frame->format), - temp_frame->sample_rate, - temp_frame->channel_layout, - static_cast(temp_frame->format), - temp_frame->sample_rate, - 0, - nullptr - ); - - swr_init(swr_ctx); - - swr_convert_frame(swr_ctx, swr_frame, temp_frame); - - // `config.waveform_resolution` determines how many samples per second are stored in waveform. - // `sample_rate` is samples per second, so `interval` is how many samples are averaged in - // each "point" of the waveform - int interval = qFloor((temp_frame->sample_rate/olive::CurrentConfig.waveform_resolution)/4)*4; - - // get the amount of bytes in an audio sample - int sample_size = av_get_bytes_per_sample(static_cast(swr_frame->format)); - - // total amount of data in this frame - int nb_bytes = swr_frame->nb_samples * sample_size; - - // loop through entire frame - for (int i=0;ichannels;j++) { - qint16& min = waveform_cache_data[packet->stream_index][j][0]; - qint16& max = waveform_cache_data[packet->stream_index][j][1]; - - s->audio_preview.append(min >> 8); - s->audio_preview.append(max >> 8); - } - - waveform_cache_count = 0; - } - - // standard processing for each channel of information - for (int j=0;jchannels;j++) { - qint16& min = waveform_cache_data[packet->stream_index][j][0]; - qint16& max = waveform_cache_data[packet->stream_index][j][1]; - - // if we're starting over, reset cache to zero - if (waveform_cache_count == 0) { - min = 0; - max = 0; - } - - // store most minimum and most maximum samples of this interval - qint16 sample = qint16((swr_frame->data[j][i+1] << 8) | swr_frame->data[j][i]); - min = qMin(min, sample); - max = qMax(max, sample); - } - - waveform_cache_count++; - - if (cancelled) { - break; - } - } - - swr_free(&swr_ctx); - av_frame_free(&swr_frame); - - if (cancelled) { - end_of_file = true; - break; - } - } - } - - // check if we've got all our previews - if (retrieve_duration) { - done = false; - } else if (footage->audio_tracks.size() == 0) { - done = true; - for (int i=0;ivideo_tracks.size();i++) { - if (!footage->video_tracks.at(i).preview_done) { - done = false; - break; - } - } - if (done) { - end_of_file = true; - break; - } - } - av_packet_unref(packet); - } + for (unsigned int i=0;inb_streams;i++) { + if (waveform_cache_data[i] != nullptr) { + for (int j=0;jchannels;j++) { + delete [] waveform_cache_data[i][j]; } + delete [] waveform_cache_data[i]; + } - av_frame_free(&temp_frame); - av_packet_free(&packet); - - for (unsigned int i=0;inb_streams;i++) { - if (waveform_cache_data[i] != nullptr) { - for (int j=0;jchannels;j++) { - delete [] waveform_cache_data[i][j]; - } - delete [] waveform_cache_data[i]; - } - - if (codec_ctx[i] != nullptr) { - avcodec_close(codec_ctx[i]); - avcodec_free_context(&codec_ctx[i]); - } - } - - // by this point, we'll have made all audio waveform previews - for (int i=0;iaudio_tracks.size();i++) { - footage->audio_tracks[i].preview_done = true; - } + if (codec_ctx[i] != nullptr) { + avcodec_close(codec_ctx[i]); + avcodec_free_context(&codec_ctx[i]); + } } - if (retrieve_duration) { - footage->length = 0; - unsigned int maximum_stream = 0; - for (unsigned int i=0;inb_streams;i++) { - if (media_lengths[i] > media_lengths[maximum_stream]) { - maximum_stream = i; - } - } + // by this point, we'll have made all audio waveform previews + for (int i=0;iaudio_tracks.size();i++) { + footage->audio_tracks[i].preview_done = true; + } + } - // FIXME: length is currently retrieved as a frame count rather than a timestamp - footage->length = qRound(double(media_lengths[maximum_stream]) / av_q2d(fmt_ctx->streams[maximum_stream]->avg_frame_rate) * AV_TIME_BASE); + if (retrieve_duration) { + footage->length = 0; + unsigned int maximum_stream = 0; + for (unsigned int i=0;inb_streams;i++) { + if (media_lengths[i] > media_lengths[maximum_stream]) { + maximum_stream = i; + } + } - finalize_media(); - } + // FIXME: length is currently retrieved as a frame count rather than a timestamp + footage->length = qRound(double(media_lengths[maximum_stream]) / av_q2d(fmt_ctx->streams[maximum_stream]->avg_frame_rate) * AV_TIME_BASE); - delete [] waveform_cache_data; - delete [] media_lengths; - delete [] codec_ctx; + finalize_media(); + } + + delete [] waveform_cache_data; + delete [] media_lengths; + delete [] codec_ctx; } QString PreviewGenerator::get_thumbnail_path(const QString& hash, const FootageStream& ms) { - return data_dir.filePath(QString("%1t%2").arg(hash, QString::number(ms.file_index))); + return data_dir.filePath(QString("%1t%2").arg(hash, QString::number(ms.file_index))); } QString PreviewGenerator::get_waveform_path(const QString& hash, const FootageStream& ms) { - return data_dir.filePath(QString("%1w%2").arg(hash, QString::number(ms.file_index))); + return data_dir.filePath(QString("%1w%2").arg(hash, QString::number(ms.file_index))); } void PreviewGenerator::run() { - Q_ASSERT(footage != nullptr); - Q_ASSERT(media != nullptr); + Q_ASSERT(footage != nullptr); + Q_ASSERT(media != nullptr); - QByteArray ba = footage->url.toUtf8(); - char* filename = new char[ba.size()+1]; - strcpy(filename, ba.data()); + QByteArray ba = footage->url.toUtf8(); + char* filename = new char[ba.size()+1]; + strcpy(filename, ba.data()); - QString errorStr; - bool error = false; - int errCode = avformat_open_input(&fmt_ctx, filename, nullptr, nullptr); - if(errCode != 0) { - char err[1024]; - av_strerror(errCode, err, 1024); - errorStr = tr("Could not open file - %1").arg(err); - error = true; - } else { - errCode = avformat_find_stream_info(fmt_ctx, nullptr); - if (errCode < 0) { - char err[1024]; - av_strerror(errCode, err, 1024); - errorStr = tr("Could not find stream information - %1").arg(err); - error = true; - } else { - av_dump_format(fmt_ctx, 0, filename, 0); - parse_media(); + QString errorStr; + bool error = false; + int errCode = avformat_open_input(&fmt_ctx, filename, nullptr, nullptr); + if(errCode != 0) { + char err[1024]; + av_strerror(errCode, err, 1024); + errorStr = tr("Could not open file - %1").arg(err); + error = true; + } else { + errCode = avformat_find_stream_info(fmt_ctx, nullptr); + if (errCode < 0) { + char err[1024]; + av_strerror(errCode, err, 1024); + errorStr = tr("Could not find stream information - %1").arg(err); + error = true; + } else { + av_dump_format(fmt_ctx, 0, filename, 0); + parse_media(); - // see if we already have data for this - QString hash = get_file_hash(footage->url); + // see if we already have data for this + QString hash = get_file_hash(footage->url); - if (retrieve_preview(hash)) { - sem.acquire(); + if (retrieve_preview(hash)) { + sem.acquire(); - if (!cancelled) { - generate_waveform(); + if (!cancelled) { + generate_waveform(); - if (!cancelled) { - // save preview to file - for (int i=0;ivideo_tracks.size();i++) { - FootageStream& ms = footage->video_tracks[i]; - ms.video_preview.save(get_thumbnail_path(hash, ms), "PNG"); - //dout << "saved" << ms->file_index << "thumbnail to" << get_thumbnail_path(hash, ms); - } - for (int i=0;iaudio_tracks.size();i++) { - FootageStream& ms = footage->audio_tracks[i]; - QFile f(get_waveform_path(hash, ms)); - f.open(QFile::WriteOnly); - f.write(ms.audio_preview.constData(), ms.audio_preview.size()); - f.close(); - //dout << "saved" << ms->file_index << "waveform to" << get_waveform_path(hash, ms); - } - } - } - - sem.release(); - } - } - avformat_close_input(&fmt_ctx); - } - - if (!cancelled) { - if (error) { - media->update_tooltip(errorStr); - olive::media_icon_service->SetMediaIcon(media, ICON_TYPE_ERROR); - footage->invalid = true; - footage->ready_lock.unlock(); - } else { - media->update_tooltip(); + if (!cancelled) { + // save preview to file + for (int i=0;ivideo_tracks.size();i++) { + FootageStream& ms = footage->video_tracks[i]; + ms.video_preview.save(get_thumbnail_path(hash, ms), "PNG"); + //dout << "saved" << ms->file_index << "thumbnail to" << get_thumbnail_path(hash, ms); + } + for (int i=0;iaudio_tracks.size();i++) { + FootageStream& ms = footage->audio_tracks[i]; + QFile f(get_waveform_path(hash, ms)); + f.open(QFile::WriteOnly); + f.write(ms.audio_preview.constData(), ms.audio_preview.size()); + f.close(); + //dout << "saved" << ms->file_index << "waveform to" << get_waveform_path(hash, ms); + } + } } - } - delete [] filename; - footage->preview_gen = nullptr; + sem.release(); + } + } + avformat_close_input(&fmt_ctx); + } + + if (!cancelled) { + if (error) { + media->update_tooltip(errorStr); + olive::media_icon_service->SetMediaIcon(media, ICON_TYPE_ERROR); + footage->invalid = true; + footage->ready_lock.unlock(); + } else { + media->update_tooltip(); + } + } + + delete [] filename; + footage->preview_gen = nullptr; } void PreviewGenerator::cancel() { - cancelled = true; - wait(); + cancelled = true; + wait(); } diff --git a/io/previewgenerator.h b/io/previewgenerator.h index 21bae9be7..1443a5b8f 100644 --- a/io/previewgenerator.h +++ b/io/previewgenerator.h @@ -29,34 +29,34 @@ #include "project/media.h" extern "C" { - #include - #include - #include - #include +#include +#include +#include +#include } class PreviewGenerator : public QThread { - Q_OBJECT + Q_OBJECT public: - PreviewGenerator(Media*, FootagePtr, bool); - void run(); - void cancel(); + PreviewGenerator(Media*, FootagePtr, bool); + void run(); + void cancel(); private: - void parse_media(); - bool retrieve_preview(const QString &hash); - void generate_waveform(); - void finalize_media(); - AVFormatContext* fmt_ctx; - Media* media; - FootagePtr footage; - bool retrieve_duration; - bool contains_still_image; - bool replace; - bool cancelled; - QDir data_dir; - QString get_thumbnail_path(const QString &hash, const FootageStream &ms); - QString get_waveform_path(const QString& hash, const FootageStream &ms); + void parse_media(); + bool retrieve_preview(const QString &hash); + void generate_waveform(); + void finalize_media(); + AVFormatContext* fmt_ctx; + Media* media; + FootagePtr footage; + bool retrieve_duration; + bool contains_still_image; + bool replace; + bool cancelled; + QDir data_dir; + QString get_thumbnail_path(const QString &hash, const FootageStream &ms); + QString get_waveform_path(const QString& hash, const FootageStream &ms); }; #endif // PREVIEWGENERATOR_H diff --git a/main.cpp b/main.cpp index a4d93a56d..b6a25d844 100644 --- a/main.cpp +++ b/main.cpp @@ -29,107 +29,114 @@ #include "io/config.h" extern "C" { - #include - #include +#include +#include } int main(int argc, char *argv[]) { - olive::Global = std::unique_ptr(new OliveGlobal); + olive::Global = std::unique_ptr(new OliveGlobal); - bool launch_fullscreen = false; - QString load_proj; + bool launch_fullscreen = false; + QString load_proj; - bool use_internal_logger = true; + bool use_internal_logger = true; - if (argc > 1) { - for (int i=1;i 1) { + for (int i=1;i\tSet an external language file to use\n" - "\n" - "Environment Variables:\n" - "\tOLIVE_EFFECTS_PATH\tSpecify a path to search for GLSL shader effects\n" - "\tFREI0R_PATH\t\tSpecify a path to search for Frei0r effects\n" - "\tOLIVE_LANG_PATH\t\tSpecify a path to search for translation files\n" - "\n", argv[0]); - return 0; - } else if (!strcmp(argv[i], "--fullscreen") || !strcmp(argv[i], "-f")) { - launch_fullscreen = true; - } else if (!strcmp(argv[i], "--disable-shaders")) { - olive::CurrentRuntimeConfig.shaders_are_enabled = false; - } else if (!strcmp(argv[i], "--no-debug")) { - use_internal_logger = false; - } else if (!strcmp(argv[i], "--disable-blend-modes")) { - olive::CurrentRuntimeConfig.disable_blending = true; - } else if (!strcmp(argv[i], "--translation")) { - if (i + 1 < argc && argv[i + 1][0] != '-') { - // load translation file - olive::CurrentRuntimeConfig.external_translation_file = argv[i + 1]; + printf("%s\n", olive::AppName.toUtf8().constData()); + return 0; + } else if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) { + printf("Usage: %s [options] [filename]\n\n" + "[filename] is the file to open on startup.\n\n" + "Options:\n" + "\t-v, --version\t\tShow version information\n" + "\t-h, --help\t\tShow this help\n" + "\t-f, --fullscreen\tStart in full screen mode\n" + "\t--disable-shaders\tDisable OpenGL shaders (for debugging)\n" + "\t--no-debug\t\tDisable internal debug log and output directly to console\n" + "\t--disable-blend-modes\tDisable shader-based blending for older GPUs\n" + "\t--translation \tSet an external language file to use\n" + "\n" + "Environment Variables:\n" + "\tOLIVE_EFFECTS_PATH\tSpecify a path to search for GLSL shader effects\n" + "\tFREI0R_PATH\t\tSpecify a path to search for Frei0r effects\n" + "\tOLIVE_LANG_PATH\t\tSpecify a path to search for translation files\n" + "\n", argv[0]); + return 0; + } else if (!strcmp(argv[i], "--fullscreen") || !strcmp(argv[i], "-f")) { + launch_fullscreen = true; + } else if (!strcmp(argv[i], "--disable-shaders")) { + olive::CurrentRuntimeConfig.shaders_are_enabled = false; + } else if (!strcmp(argv[i], "--no-debug")) { + use_internal_logger = false; + } else if (!strcmp(argv[i], "--disable-blend-modes")) { + olive::CurrentRuntimeConfig.disable_blending = true; + } else if (!strcmp(argv[i], "--translation")) { + if (i + 1 < argc && argv[i + 1][0] != '-') { + // load translation file + olive::CurrentRuntimeConfig.external_translation_file = argv[i + 1]; - i++; - } else { - printf("[ERROR] No translation file specified\n"); - return 1; - } - } else { - printf("[ERROR] Unknown argument '%s'\n", argv[1]); - return 1; - } - } else if (load_proj.isEmpty()) { - load_proj = argv[i]; - } - } - } - - if (use_internal_logger) { - qInstallMessageHandler(debug_message_handler); + i++; + } else { + printf("[ERROR] No translation file specified\n"); + return 1; + } + } else { + printf("[ERROR] Unknown argument '%s'\n", argv[1]); + return 1; + } + } else if (load_proj.isEmpty()) { + load_proj = argv[i]; + } } + } - // Initialize ffmpeg subsystem - // (these have been deprecated in FFmpeg 4, but are still necessary for FFmpeg 3) - av_register_all(); - avfilter_register_all(); + if (use_internal_logger) { + qInstallMessageHandler(debug_message_handler); + } - QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); + // Initialize ffmpeg subsystem + // (these have been deprecated in FFmpeg 4, but are still necessary for FFmpeg 3) +#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 9, 100) + av_register_all(); +#endif - QApplication a(argc, argv); - a.setWindowIcon(QIcon(":/icons/olive64.png")); +#if LIBAVFILTER_VERSION_INT < AV_VERSION_INT(7, 14, 100) + avfilter_register_all(); +#endif - olive::media_icon_service = std::unique_ptr(new MediaIconService()); + QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); - QCoreApplication::setOrganizationName("olivevideoeditor.org"); - QCoreApplication::setOrganizationDomain("olivevideoeditor.org"); - QCoreApplication::setApplicationName("Olive"); - QGuiApplication::setDesktopFileName("org.olivevideoeditor.Olive"); + QApplication a(argc, argv); + a.setWindowIcon(QIcon(":/icons/olive64.png")); - MainWindow w(nullptr); + // start media icon service (uses QPixmaps which require a QGuiApplication to have been created) + olive::media_icon_service = std::unique_ptr(new MediaIconService()); - // connect main window's first paint to global's init finished function - QObject::connect(&w, SIGNAL(finished_first_paint()), olive::Global.get(), SLOT(finished_initialize())); + // set app name data + QCoreApplication::setOrganizationName("olivevideoeditor.org"); + QCoreApplication::setOrganizationDomain("olivevideoeditor.org"); + QCoreApplication::setApplicationName("Olive"); + QGuiApplication::setDesktopFileName("org.olivevideoeditor.Olive"); - if (!load_proj.isEmpty()) { - olive::Global->load_project_on_launch(load_proj); - } - if (launch_fullscreen) { - w.showFullScreen(); - } else { - w.showMaximized(); - } + MainWindow w(nullptr); - return a.exec(); + // connect main window's first paint to global's init finished function + QObject::connect(&w, SIGNAL(finished_first_paint()), olive::Global.get(), SLOT(finished_initialize())); + + if (!load_proj.isEmpty()) { + olive::Global->load_project_on_launch(load_proj); + } + if (launch_fullscreen) { + w.showFullScreen(); + } else { + w.showMaximized(); + } + + return a.exec(); } diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp index c052daed2..6619b9701 100644 --- a/panels/effectcontrols.cpp +++ b/panels/effectcontrols.cpp @@ -52,567 +52,567 @@ #include "debug.h" EffectControls::EffectControls(QWidget *parent) : - QDockWidget(parent), - multiple(false), - zoom(1), - panel_name(tr("Effects: ")), - mode(TA_NO_TRANSITION) + QDockWidget(parent), + multiple(false), + zoom(1), + panel_name(tr("Effects: ")), + mode(kTransitionNone) { - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - setup_ui(); + setup_ui(); - clear_effects(false); - headers->viewer = panel_sequence_viewer; - headers->snapping = false; + clear_effects(false); + headers->viewer = panel_sequence_viewer; + headers->snapping = false; - effects_area->parent_widget = scrollArea; - effects_area->keyframe_area = keyframeView; - effects_area->header = headers; - keyframeView->header = headers; + effects_area->parent_widget = scrollArea; + effects_area->keyframe_area = keyframeView; + effects_area->header = headers; + keyframeView->header = headers; - lblMultipleClipsSelected->setVisible(false); + lblMultipleClipsSelected->setVisible(false); - connect(keyframeView, SIGNAL(wheel_event_signal(QWheelEvent*)), effects_area, SLOT(receive_wheel_event(QWheelEvent*))); - connect(horizontalScrollBar, SIGNAL(valueChanged(int)), headers, SLOT(set_scroll(int))); - connect(horizontalScrollBar, SIGNAL(resize_move(double)), keyframeView, SLOT(resize_move(double))); - connect(horizontalScrollBar, SIGNAL(valueChanged(int)), keyframeView, SLOT(set_x_scroll(int))); - connect(verticalScrollBar, SIGNAL(valueChanged(int)), keyframeView, SLOT(set_y_scroll(int))); - connect(verticalScrollBar, SIGNAL(valueChanged(int)), scrollArea->verticalScrollBar(), SLOT(setValue(int))); - connect(scrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)), verticalScrollBar, SLOT(setValue(int))); + connect(keyframeView, SIGNAL(wheel_event_signal(QWheelEvent*)), effects_area, SLOT(receive_wheel_event(QWheelEvent*))); + connect(horizontalScrollBar, SIGNAL(valueChanged(int)), headers, SLOT(set_scroll(int))); + connect(horizontalScrollBar, SIGNAL(resize_move(double)), keyframeView, SLOT(resize_move(double))); + connect(horizontalScrollBar, SIGNAL(valueChanged(int)), keyframeView, SLOT(set_x_scroll(int))); + connect(verticalScrollBar, SIGNAL(valueChanged(int)), keyframeView, SLOT(set_y_scroll(int))); + connect(verticalScrollBar, SIGNAL(valueChanged(int)), scrollArea->verticalScrollBar(), SLOT(setValue(int))); + connect(scrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)), verticalScrollBar, SLOT(setValue(int))); } EffectControls::~EffectControls() {} int EffectControls::get_mode() { - return mode; + return mode; } bool EffectControls::keyframe_focus() { - return headers->hasFocus() || keyframeView->hasFocus(); + return headers->hasFocus() || keyframeView->hasFocus(); } void EffectControls::set_zoom(bool in) { - zoom *= (in) ? 2 : 0.5; - update_keyframes(); + zoom *= (in) ? 2 : 0.5; + update_keyframes(); } void EffectControls::menu_select(QAction* q) { - ComboAction* ca = new ComboAction(); - for (int i=0;iclips.at(selected_clips.at(i)); - if ((c->track < 0) == (effect_menu_subtype == EFFECT_TYPE_VIDEO)) { - const EffectMeta* meta = reinterpret_cast(q->data().value()); - if (effect_menu_type == EFFECT_TYPE_TRANSITION) { - if (c->get_opening_transition() == nullptr) { - ca->append(new AddTransitionCommand(c, nullptr, nullptr, meta, TA_OPENING_TRANSITION, 30)); - } - if (c->get_closing_transition() == nullptr) { - ca->append(new AddTransitionCommand(c, nullptr, nullptr, meta, TA_CLOSING_TRANSITION, 30)); - } - } else { - ca->append(new AddEffectCommand(c, nullptr, meta)); - } - } - } - olive::UndoStack.push(ca); - if (effect_menu_type == EFFECT_TYPE_TRANSITION) { - update_ui(true); - } else { - reload_clips(); - panel_sequence_viewer->viewer_widget->frame_update(); - } + ComboAction* ca = new ComboAction(); + for (int i=0;iclips.at(selected_clips.at(i)); + if ((c->track < 0) == (effect_menu_subtype == EFFECT_TYPE_VIDEO)) { + const EffectMeta* meta = reinterpret_cast(q->data().value()); + if (effect_menu_type == EFFECT_TYPE_TRANSITION) { + if (c->opening_transition == nullptr) { + ca->append(new AddTransitionCommand(c, nullptr, nullptr, meta, kTransitionOpening, 30)); + } + if (c->closing_transition == nullptr) { + ca->append(new AddTransitionCommand(c, nullptr, nullptr, meta, kTransitionClosing, 30)); + } + } else { + ca->append(new AddEffectCommand(c, nullptr, meta)); + } + } + } + olive::UndoStack.push(ca); + if (effect_menu_type == EFFECT_TYPE_TRANSITION) { + update_ui(true); + } else { + reload_clips(); + panel_sequence_viewer->viewer_widget->frame_update(); + } } void EffectControls::update_keyframes() { - headers->update_zoom(zoom); - keyframeView->update(); + headers->update_zoom(zoom); + keyframeView->update(); } void EffectControls::delete_selected_keyframes() { - keyframeView->delete_selected_keyframes(); + keyframeView->delete_selected_keyframes(); } void EffectControls::copy(bool del) { - if (mode == TA_NO_TRANSITION) { - bool cleared = false; + if (mode == kTransitionNone) { + bool cleared = false; - ComboAction* ca = new ComboAction(); - EffectDeleteCommand* del_com = (del) ? new EffectDeleteCommand() : nullptr; - for (int i=0;iclips.at(selected_clips.at(i)); - for (int j=0;jeffects.size();j++) { - EffectPtr effect = c->effects.at(j); - if (effect->container->selected) { - if (!cleared) { - clear_clipboard(); - cleared = true; - clipboard_type = CLIPBOARD_TYPE_EFFECT; - } + ComboAction* ca = new ComboAction(); + EffectDeleteCommand* del_com = (del) ? new EffectDeleteCommand() : nullptr; + for (int i=0;iclips.at(selected_clips.at(i)); + for (int j=0;jeffects.size();j++) { + EffectPtr effect = c->effects.at(j); + if (effect->container->selected) { + if (!cleared) { + clear_clipboard(); + cleared = true; + clipboard_type = CLIPBOARD_TYPE_EFFECT; + } - clipboard.append(EffectPtr(effect->copy(nullptr))); + clipboard.append(EffectPtr(effect->copy(nullptr))); - if (del_com != nullptr) { - del_com->clips.append(c); - del_com->fx.append(j); - } - } - } - } - if (del_com != nullptr) { - if (del_com->clips.size() > 0) { - ca->append(del_com); - } else { - delete del_com; - } - } - olive::UndoStack.push(ca); - } + if (del_com != nullptr) { + del_com->clips.append(c); + del_com->fx.append(j); + } + } + } + } + if (del_com != nullptr) { + if (del_com->clips.size() > 0) { + ca->append(del_com); + } else { + delete del_com; + } + } + olive::UndoStack.push(ca); + } } void EffectControls::scroll_to_frame(long frame) { - scroll_to_frame_internal(horizontalScrollBar, frame, zoom, keyframeView->width()); + scroll_to_frame_internal(horizontalScrollBar, frame, zoom, keyframeView->width()); } void EffectControls::add_effect_paste_action(QMenu *menu) { - QAction* paste_action = menu->addAction(tr("&Paste"), panel_timeline, SLOT(paste(bool))); - paste_action->setEnabled(clipboard.size() > 0 && clipboard_type == CLIPBOARD_TYPE_EFFECT); + QAction* paste_action = menu->addAction(tr("&Paste"), panel_timeline, SLOT(paste(bool))); + paste_action->setEnabled(clipboard.size() > 0 && clipboard_type == CLIPBOARD_TYPE_EFFECT); } void EffectControls::cut() { - copy(true); + copy(true); } void EffectControls::show_effect_menu(int type, int subtype) { - effect_menu_type = type; - effect_menu_subtype = subtype; + effect_menu_type = type; + effect_menu_subtype = subtype; - effects_loaded.lock(); + effects_loaded.lock(); - QMenu effects_menu(this); - effects_menu.setToolTipsVisible(true); + QMenu effects_menu(this); + effects_menu.setToolTipsVisible(true); - for (int i=0;isetText(em.name); - action->setData(reinterpret_cast(&em)); - if (!em.tooltip.isEmpty()) { - action->setToolTip(em.tooltip); + if (em.type == type && em.subtype == subtype) { + QAction* action = new QAction(&effects_menu); + action->setText(em.name); + action->setData(reinterpret_cast(&em)); + if (!em.tooltip.isEmpty()) { + action->setToolTip(em.tooltip); + } + + QMenu* parent = &effects_menu; + if (!em.category.isEmpty()) { + bool found = false; + for (int j=0;jmenu() != nullptr) { + if (action->menu()->title() == em.category) { + parent = action->menu(); + found = true; + break; } - - QMenu* parent = &effects_menu; - if (!em.category.isEmpty()) { - bool found = false; - for (int j=0;jmenu() != nullptr) { - if (action->menu()->title() == em.category) { - parent = action->menu(); - found = true; - break; - } - } - } - if (!found) { - parent = new QMenu(&effects_menu); - parent->setToolTipsVisible(true); - parent->setTitle(em.category); - - bool found = false; - for (int i=0;itext() > em.category) { - effects_menu.insertMenu(comp_action, parent); - found = true; - break; - } - } - if (!found) effects_menu.addMenu(parent); - } - } - - bool found = false; - for (int i=0;iactions().size();i++) { - QAction* comp_action = parent->actions().at(i); - if (comp_action->text() > action->text()) { - parent->insertAction(comp_action, action); - found = true; - break; - } - } - if (!found) parent->addAction(action); + } } + if (!found) { + parent = new QMenu(&effects_menu); + parent->setToolTipsVisible(true); + parent->setTitle(em.category); + + bool found = false; + for (int i=0;itext() > em.category) { + effects_menu.insertMenu(comp_action, parent); + found = true; + break; + } + } + if (!found) effects_menu.addMenu(parent); + } + } + + bool found = false; + for (int i=0;iactions().size();i++) { + QAction* comp_action = parent->actions().at(i); + if (comp_action->text() > action->text()) { + parent->insertAction(comp_action, action); + found = true; + break; + } + } + if (!found) parent->addAction(action); } + } - effects_loaded.unlock(); + effects_loaded.unlock(); - connect(&effects_menu, SIGNAL(triggered(QAction*)), this, SLOT(menu_select(QAction*))); - effects_menu.exec(QCursor::pos()); + connect(&effects_menu, SIGNAL(triggered(QAction*)), this, SLOT(menu_select(QAction*))); + effects_menu.exec(QCursor::pos()); } void EffectControls::clear_effects(bool clear_cache) { - // clear existing clips - deselect_all_effects(nullptr); + // clear existing clips + deselect_all_effects(nullptr); - // clear graph editor - if (panel_graph_editor != nullptr) panel_graph_editor->set_row(nullptr); + // clear graph editor + if (panel_graph_editor != nullptr) panel_graph_editor->set_row(nullptr); - QVBoxLayout* video_layout = static_cast(video_effect_area->layout()); - QVBoxLayout* audio_layout = static_cast(audio_effect_area->layout()); - QLayoutItem* item; - while ((item = video_layout->takeAt(0))) { - item->widget()->setParent(nullptr); - disconnect(static_cast(item->widget()), SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); - } - while ((item = audio_layout->takeAt(0))) { - item->widget()->setParent(nullptr); - disconnect(static_cast(item->widget()), SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); - } - lblMultipleClipsSelected->setVisible(false); - vcontainer->setVisible(false); - acontainer->setVisible(false); - headers->setVisible(false); - keyframeView->setEnabled(false); - if (clear_cache) selected_clips.clear(); - setWindowTitle(panel_name + "(none)"); + QVBoxLayout* video_layout = static_cast(video_effect_area->layout()); + QVBoxLayout* audio_layout = static_cast(audio_effect_area->layout()); + QLayoutItem* item; + while ((item = video_layout->takeAt(0))) { + item->widget()->setParent(nullptr); + disconnect(static_cast(item->widget()), SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); + } + while ((item = audio_layout->takeAt(0))) { + item->widget()->setParent(nullptr); + disconnect(static_cast(item->widget()), SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); + } + lblMultipleClipsSelected->setVisible(false); + vcontainer->setVisible(false); + acontainer->setVisible(false); + headers->setVisible(false); + keyframeView->setEnabled(false); + if (clear_cache) selected_clips.clear(); + setWindowTitle(panel_name + "(none)"); } void EffectControls::deselect_all_effects(QWidget* sender) { - for (int i=0;iclips.at(selected_clips.at(i)); - for (int j=0;jeffects.size();j++) { - if (c->effects.at(j)->container != sender) { - c->effects.at(j)->container->header_click(false, false); - } - } - } - panel_sequence_viewer->viewer_widget->update(); + for (int i=0;iclips.at(selected_clips.at(i)); + for (int j=0;jeffects.size();j++) { + if (c->effects.at(j)->container != sender) { + c->effects.at(j)->container->header_click(false, false); + } + } + } + panel_sequence_viewer->viewer_widget->update(); } void EffectControls::open_effect(QVBoxLayout* layout, EffectPtr e) { - CollapsibleWidget* container = e->container; - layout->addWidget(container); - connect(container, SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); + CollapsibleWidget* container = e->container; + layout->addWidget(container); + connect(container, SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); } void EffectControls::setup_ui() { - QWidget* contents = new QWidget(this); + QWidget* contents = new QWidget(this); - QHBoxLayout* hlayout = new QHBoxLayout(contents); - hlayout->setSpacing(0); - hlayout->setMargin(0); + QHBoxLayout* hlayout = new QHBoxLayout(contents); + hlayout->setSpacing(0); + hlayout->setMargin(0); - QSplitter* splitter = new QSplitter(); - splitter->setOrientation(Qt::Horizontal); - splitter->setChildrenCollapsible(false); + QSplitter* splitter = new QSplitter(); + splitter->setOrientation(Qt::Horizontal); + splitter->setChildrenCollapsible(false); - scrollArea = new QScrollArea(); - scrollArea->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); - scrollArea->setFrameShape(QFrame::NoFrame); - scrollArea->setFrameShadow(QFrame::Plain); - scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - scrollArea->setWidgetResizable(true); + scrollArea = new QScrollArea(); + scrollArea->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); + scrollArea->setFrameShape(QFrame::NoFrame); + scrollArea->setFrameShadow(QFrame::Plain); + scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + scrollArea->setWidgetResizable(true); - QWidget* scrollAreaWidgetContents = new QWidget(); + QWidget* scrollAreaWidgetContents = new QWidget(); - QHBoxLayout* scrollAreaLayout = new QHBoxLayout(scrollAreaWidgetContents); - scrollAreaLayout->setSpacing(0); - scrollAreaLayout->setMargin(0); + QHBoxLayout* scrollAreaLayout = new QHBoxLayout(scrollAreaWidgetContents); + scrollAreaLayout->setSpacing(0); + scrollAreaLayout->setMargin(0); - effects_area = new EffectsArea(); - effects_area->setContextMenuPolicy(Qt::CustomContextMenu); - connect(effects_area, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(effects_area_context_menu())); + effects_area = new EffectsArea(); + effects_area->setContextMenuPolicy(Qt::CustomContextMenu); + connect(effects_area, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(effects_area_context_menu())); - QVBoxLayout* effects_area_layout = new QVBoxLayout(effects_area); - effects_area_layout->setSpacing(0); - effects_area_layout->setMargin(0); + QVBoxLayout* effects_area_layout = new QVBoxLayout(effects_area); + effects_area_layout->setSpacing(0); + effects_area_layout->setMargin(0); - vcontainer = new QWidget(); - QVBoxLayout* vcontainerLayout = new QVBoxLayout(vcontainer); - vcontainerLayout->setSpacing(0); - vcontainerLayout->setMargin(0); + vcontainer = new QWidget(); + QVBoxLayout* vcontainerLayout = new QVBoxLayout(vcontainer); + vcontainerLayout->setSpacing(0); + vcontainerLayout->setMargin(0); - QWidget* veHeader = new QWidget(); - veHeader->setObjectName(QStringLiteral("veHeader")); - veHeader->setStyleSheet(QLatin1String("#veHeader { background: rgba(0, 0, 0, 0.25); }")); + QWidget* veHeader = new QWidget(); + veHeader->setObjectName(QStringLiteral("veHeader")); + veHeader->setStyleSheet(QLatin1String("#veHeader { background: rgba(0, 0, 0, 0.25); }")); - QHBoxLayout* veHeaderLayout = new QHBoxLayout(veHeader); - veHeaderLayout->setSpacing(0); - veHeaderLayout->setMargin(0); + QHBoxLayout* veHeaderLayout = new QHBoxLayout(veHeader); + veHeaderLayout->setSpacing(0); + veHeaderLayout->setMargin(0); - QPushButton* btnAddVideoEffect = new QPushButton(); - btnAddVideoEffect->setIcon(QIcon(":/icons/add-effect.png")); - btnAddVideoEffect->setToolTip(tr("Add Video Effect")); - veHeaderLayout->addWidget(btnAddVideoEffect); - connect(btnAddVideoEffect, SIGNAL(clicked(bool)), this, SLOT(video_effect_click())); + QPushButton* btnAddVideoEffect = new QPushButton(); + btnAddVideoEffect->setIcon(QIcon(":/icons/add-effect.png")); + btnAddVideoEffect->setToolTip(tr("Add Video Effect")); + veHeaderLayout->addWidget(btnAddVideoEffect); + connect(btnAddVideoEffect, SIGNAL(clicked(bool)), this, SLOT(video_effect_click())); - veHeaderLayout->addStretch(); + veHeaderLayout->addStretch(); - QLabel* lblVideoEffects = new QLabel(); - QFont font; - font.setPointSize(9); - lblVideoEffects->setFont(font); - lblVideoEffects->setAlignment(Qt::AlignCenter); - lblVideoEffects->setText(tr("VIDEO EFFECTS")); - veHeaderLayout->addWidget(lblVideoEffects); + QLabel* lblVideoEffects = new QLabel(); + QFont font; + font.setPointSize(9); + lblVideoEffects->setFont(font); + lblVideoEffects->setAlignment(Qt::AlignCenter); + lblVideoEffects->setText(tr("VIDEO EFFECTS")); + veHeaderLayout->addWidget(lblVideoEffects); - veHeaderLayout->addStretch(); + veHeaderLayout->addStretch(); - QPushButton* btnAddVideoTransition = new QPushButton(); - btnAddVideoTransition->setIcon(QIcon(":/icons/add-transition.png")); - btnAddVideoTransition->setToolTip(tr("Add Video Transition")); - connect(btnAddVideoTransition, SIGNAL(clicked(bool)), this, SLOT(video_transition_click())); - veHeaderLayout->addWidget(btnAddVideoTransition); + QPushButton* btnAddVideoTransition = new QPushButton(); + btnAddVideoTransition->setIcon(QIcon(":/icons/add-transition.png")); + btnAddVideoTransition->setToolTip(tr("Add Video Transition")); + connect(btnAddVideoTransition, SIGNAL(clicked(bool)), this, SLOT(video_transition_click())); + veHeaderLayout->addWidget(btnAddVideoTransition); - vcontainerLayout->addWidget(veHeader); + vcontainerLayout->addWidget(veHeader); - video_effect_area = new QWidget(); - QVBoxLayout* veAreaLayout = new QVBoxLayout(video_effect_area); - veAreaLayout->setSpacing(0); - veAreaLayout->setMargin(0); + video_effect_area = new QWidget(); + QVBoxLayout* veAreaLayout = new QVBoxLayout(video_effect_area); + veAreaLayout->setSpacing(0); + veAreaLayout->setMargin(0); - vcontainerLayout->addWidget(video_effect_area); + vcontainerLayout->addWidget(video_effect_area); - effects_area_layout->addWidget(vcontainer); + effects_area_layout->addWidget(vcontainer); - acontainer = new QWidget(); - QVBoxLayout* acontainerLayout = new QVBoxLayout(acontainer); - acontainerLayout->setSpacing(0); - acontainerLayout->setMargin(0); - QWidget* aeHeader = new QWidget(); - aeHeader->setObjectName(QStringLiteral("aeHeader")); - aeHeader->setStyleSheet(QLatin1String("#aeHeader { background: rgba(0, 0, 0, 0.25); }")); + acontainer = new QWidget(); + QVBoxLayout* acontainerLayout = new QVBoxLayout(acontainer); + acontainerLayout->setSpacing(0); + acontainerLayout->setMargin(0); + QWidget* aeHeader = new QWidget(); + aeHeader->setObjectName(QStringLiteral("aeHeader")); + aeHeader->setStyleSheet(QLatin1String("#aeHeader { background: rgba(0, 0, 0, 0.25); }")); - QHBoxLayout* aeHeaderLayout = new QHBoxLayout(aeHeader); - aeHeaderLayout->setSpacing(0); - aeHeaderLayout->setMargin(0); + QHBoxLayout* aeHeaderLayout = new QHBoxLayout(aeHeader); + aeHeaderLayout->setSpacing(0); + aeHeaderLayout->setMargin(0); - QPushButton* btnAddAudioEffect = new QPushButton(); - btnAddAudioEffect->setIcon(QIcon(":/icons/add-effect.png")); - btnAddAudioEffect->setToolTip(tr("Add Audio Effect")); - connect(btnAddAudioEffect, SIGNAL(clicked(bool)), this, SLOT(audio_effect_click())); - aeHeaderLayout->addWidget(btnAddAudioEffect); + QPushButton* btnAddAudioEffect = new QPushButton(); + btnAddAudioEffect->setIcon(QIcon(":/icons/add-effect.png")); + btnAddAudioEffect->setToolTip(tr("Add Audio Effect")); + connect(btnAddAudioEffect, SIGNAL(clicked(bool)), this, SLOT(audio_effect_click())); + aeHeaderLayout->addWidget(btnAddAudioEffect); - aeHeaderLayout->addStretch(); + aeHeaderLayout->addStretch(); - QLabel* lblAudioEffects = new QLabel(); - lblAudioEffects->setFont(font); - lblAudioEffects->setAlignment(Qt::AlignCenter); - lblAudioEffects->setText(tr("AUDIO EFFECTS")); - aeHeaderLayout->addWidget(lblAudioEffects); + QLabel* lblAudioEffects = new QLabel(); + lblAudioEffects->setFont(font); + lblAudioEffects->setAlignment(Qt::AlignCenter); + lblAudioEffects->setText(tr("AUDIO EFFECTS")); + aeHeaderLayout->addWidget(lblAudioEffects); - aeHeaderLayout->addStretch(); + aeHeaderLayout->addStretch(); - QPushButton* btnAddAudioTransition = new QPushButton(); - btnAddAudioTransition->setIcon(QIcon(":/icons/add-transition.png")); - btnAddAudioTransition->setToolTip(tr("Add Audio Transition")); - connect(btnAddAudioTransition, SIGNAL(clicked(bool)), this, SLOT(audio_transition_click())); - aeHeaderLayout->addWidget(btnAddAudioTransition); + QPushButton* btnAddAudioTransition = new QPushButton(); + btnAddAudioTransition->setIcon(QIcon(":/icons/add-transition.png")); + btnAddAudioTransition->setToolTip(tr("Add Audio Transition")); + connect(btnAddAudioTransition, SIGNAL(clicked(bool)), this, SLOT(audio_transition_click())); + aeHeaderLayout->addWidget(btnAddAudioTransition); - acontainerLayout->addWidget(aeHeader); + acontainerLayout->addWidget(aeHeader); - audio_effect_area = new QWidget(); - QVBoxLayout* aeAreaLayout = new QVBoxLayout(audio_effect_area); - aeAreaLayout->setSpacing(0); - aeAreaLayout->setMargin(0); + audio_effect_area = new QWidget(); + QVBoxLayout* aeAreaLayout = new QVBoxLayout(audio_effect_area); + aeAreaLayout->setSpacing(0); + aeAreaLayout->setMargin(0); - acontainerLayout->addWidget(audio_effect_area); + acontainerLayout->addWidget(audio_effect_area); - effects_area_layout->addWidget(acontainer); + effects_area_layout->addWidget(acontainer); - lblMultipleClipsSelected = new QLabel(); - lblMultipleClipsSelected->setAlignment(Qt::AlignCenter); - lblMultipleClipsSelected->setText(tr("(Multiple clips selected)")); - effects_area_layout->addWidget(lblMultipleClipsSelected); + lblMultipleClipsSelected = new QLabel(); + lblMultipleClipsSelected->setAlignment(Qt::AlignCenter); + lblMultipleClipsSelected->setText(tr("(Multiple clips selected)")); + effects_area_layout->addWidget(lblMultipleClipsSelected); - effects_area_layout->addStretch(); + effects_area_layout->addStretch(); - scrollAreaLayout->addWidget(effects_area); + scrollAreaLayout->addWidget(effects_area); - scrollArea->setWidget(scrollAreaWidgetContents); - splitter->addWidget(scrollArea); + scrollArea->setWidget(scrollAreaWidgetContents); + splitter->addWidget(scrollArea); - QWidget* keyframeArea = new QWidget(); + QWidget* keyframeArea = new QWidget(); - QSizePolicy keyframe_sp; - keyframe_sp.setHorizontalPolicy(QSizePolicy::Minimum); - keyframe_sp.setVerticalPolicy(QSizePolicy::Preferred); - keyframe_sp.setHorizontalStretch(1); - keyframeArea->setSizePolicy(keyframe_sp); + QSizePolicy keyframe_sp; + keyframe_sp.setHorizontalPolicy(QSizePolicy::Minimum); + keyframe_sp.setVerticalPolicy(QSizePolicy::Preferred); + keyframe_sp.setHorizontalStretch(1); + keyframeArea->setSizePolicy(keyframe_sp); - QVBoxLayout* keyframeAreaLayout = new QVBoxLayout(keyframeArea); - keyframeAreaLayout->setSpacing(0); - keyframeAreaLayout->setMargin(0); + QVBoxLayout* keyframeAreaLayout = new QVBoxLayout(keyframeArea); + keyframeAreaLayout->setSpacing(0); + keyframeAreaLayout->setMargin(0); - headers = new TimelineHeader(); - keyframeAreaLayout->addWidget(headers); + headers = new TimelineHeader(); + keyframeAreaLayout->addWidget(headers); - QWidget* keyframeCenterWidget = new QWidget(); + QWidget* keyframeCenterWidget = new QWidget(); - QHBoxLayout* keyframeCenterLayout = new QHBoxLayout(keyframeCenterWidget); - keyframeCenterLayout->setSpacing(0); - keyframeCenterLayout->setMargin(0); + QHBoxLayout* keyframeCenterLayout = new QHBoxLayout(keyframeCenterWidget); + keyframeCenterLayout->setSpacing(0); + keyframeCenterLayout->setMargin(0); - keyframeView = new KeyframeView(); + keyframeView = new KeyframeView(); - keyframeCenterLayout->addWidget(keyframeView); + keyframeCenterLayout->addWidget(keyframeView); - verticalScrollBar = new QScrollBar(); - verticalScrollBar->setOrientation(Qt::Vertical); + verticalScrollBar = new QScrollBar(); + verticalScrollBar->setOrientation(Qt::Vertical); - keyframeCenterLayout->addWidget(verticalScrollBar); + keyframeCenterLayout->addWidget(verticalScrollBar); - keyframeAreaLayout->addWidget(keyframeCenterWidget); + keyframeAreaLayout->addWidget(keyframeCenterWidget); - horizontalScrollBar = new ResizableScrollBar(); - horizontalScrollBar->setOrientation(Qt::Horizontal); + horizontalScrollBar = new ResizableScrollBar(); + horizontalScrollBar->setOrientation(Qt::Horizontal); - keyframeAreaLayout->addWidget(horizontalScrollBar); + keyframeAreaLayout->addWidget(horizontalScrollBar); - splitter->addWidget(keyframeArea); + splitter->addWidget(keyframeArea); - hlayout->addWidget(splitter); + hlayout->addWidget(splitter); - setWidget(contents); + setWidget(contents); } void EffectControls::update_scrollbar() { - verticalScrollBar->setMaximum(qMax(0, effects_area->height() - keyframeView->height() - headers->height())); - verticalScrollBar->setPageStep(verticalScrollBar->height()); + verticalScrollBar->setMaximum(qMax(0, effects_area->height() - keyframeView->height() - headers->height())); + verticalScrollBar->setPageStep(verticalScrollBar->height()); } void EffectControls::queue_post_update() { - keyframeView->update(); - update_scrollbar(); + keyframeView->update(); + update_scrollbar(); } void EffectControls::effects_area_context_menu() { - QMenu menu(this); + QMenu menu(this); - add_effect_paste_action(&menu); + add_effect_paste_action(&menu); - menu.exec(QCursor::pos()); + menu.exec(QCursor::pos()); } void EffectControls::load_effects() { - lblMultipleClipsSelected->setVisible(multiple); + lblMultipleClipsSelected->setVisible(multiple); - if (!multiple) { - // load in new clips - for (int i=0;iclips.at(selected_clips.at(i)); - QVBoxLayout* layout; - if (c->track < 0) { - vcontainer->setVisible(true); - layout = static_cast(video_effect_area->layout()); - } else { - acontainer->setVisible(true); - layout = static_cast(audio_effect_area->layout()); - } - if (mode == TA_NO_TRANSITION) { - for (int j=0;jeffects.size();j++) { - open_effect(layout, c->effects.at(j)); - } - } else if (mode == TA_OPENING_TRANSITION && c->get_opening_transition() != nullptr) { - open_effect(layout, c->get_opening_transition()); - } else if (mode == TA_CLOSING_TRANSITION && c->get_closing_transition() != nullptr) { - open_effect(layout, c->get_closing_transition()); - } - } - if (selected_clips.size() > 0) { - setWindowTitle(panel_name + olive::ActiveSequence->clips.at(selected_clips.at(0))->name); - keyframeView->setEnabled(true); - headers->setVisible(true); + if (!multiple) { + // load in new clips + for (int i=0;iclips.at(selected_clips.at(i)); + QVBoxLayout* layout; + if (c->track < 0) { + vcontainer->setVisible(true); + layout = static_cast(video_effect_area->layout()); + } else { + acontainer->setVisible(true); + layout = static_cast(audio_effect_area->layout()); + } + if (mode == kTransitionNone) { + for (int j=0;jeffects.size();j++) { + open_effect(layout, c->effects.at(j)); + } + } else if (mode == kTransitionOpening && c->opening_transition != nullptr) { + open_effect(layout, c->opening_transition); + } else if (mode == kTransitionClosing && c->closing_transition != nullptr) { + open_effect(layout, c->closing_transition); + } + } + if (selected_clips.size() > 0) { + setWindowTitle(panel_name + olive::ActiveSequence->clips.at(selected_clips.at(0))->name); + keyframeView->setEnabled(true); + headers->setVisible(true); - QTimer::singleShot(50, this, SLOT(queue_post_update())); - } - } + QTimer::singleShot(50, this, SLOT(queue_post_update())); + } + } } void EffectControls::delete_effects() { - // load in new clips - if (mode == TA_NO_TRANSITION) { - EffectDeleteCommand* command = new EffectDeleteCommand(); - for (int i=0;iclips.at(selected_clips.at(i)); - for (int j=0;jeffects.size();j++) { - EffectPtr effect = c->effects.at(j); - if (effect->container->selected) { - command->clips.append(c); - command->fx.append(j); - } - } - } - if (command->clips.size() > 0) { - olive::UndoStack.push(command); - panel_sequence_viewer->viewer_widget->frame_update(); - } else { - delete command; - } - } + // load in new clips + if (mode == kTransitionNone) { + EffectDeleteCommand* command = new EffectDeleteCommand(); + for (int i=0;iclips.at(selected_clips.at(i)); + for (int j=0;jeffects.size();j++) { + EffectPtr effect = c->effects.at(j); + if (effect->container->selected) { + command->clips.append(c); + command->fx.append(j); + } + } + } + if (command->clips.size() > 0) { + olive::UndoStack.push(command); + panel_sequence_viewer->viewer_widget->frame_update(); + } else { + delete command; + } + } } void EffectControls::reload_clips() { - clear_effects(false); - load_effects(); + clear_effects(false); + load_effects(); } void EffectControls::set_clips(QVector& clips, int m) { - clear_effects(true); + clear_effects(true); - // replace clip vector - selected_clips = clips; - mode = m; + // replace clip vector + selected_clips = clips; + mode = m; - load_effects(); + load_effects(); } void EffectControls::video_effect_click() { - show_effect_menu(EFFECT_TYPE_EFFECT, EFFECT_TYPE_VIDEO); + show_effect_menu(EFFECT_TYPE_EFFECT, EFFECT_TYPE_VIDEO); } void EffectControls::audio_effect_click() { - show_effect_menu(EFFECT_TYPE_EFFECT, EFFECT_TYPE_AUDIO); + show_effect_menu(EFFECT_TYPE_EFFECT, EFFECT_TYPE_AUDIO); } void EffectControls::video_transition_click() { - show_effect_menu(EFFECT_TYPE_TRANSITION, EFFECT_TYPE_VIDEO); + show_effect_menu(EFFECT_TYPE_TRANSITION, EFFECT_TYPE_VIDEO); } void EffectControls::audio_transition_click() { - show_effect_menu(EFFECT_TYPE_TRANSITION, EFFECT_TYPE_AUDIO); + show_effect_menu(EFFECT_TYPE_TRANSITION, EFFECT_TYPE_AUDIO); } void EffectControls::resizeEvent(QResizeEvent*) { - update_scrollbar(); + update_scrollbar(); } bool EffectControls::is_focused() { - if (this->hasFocus()) return true; - for (int i=0;iclips.at(selected_clips.at(i)); - if (c != nullptr) { - for (int j=0;jeffects.size();j++) { - if (c->effects.at(j)->container->is_focused()) { - return true; - } - } - } else { - qWarning() << "Tried to check focus of a nullptr clip"; - } - } - return false; + if (this->hasFocus()) return true; + for (int i=0;iclips.at(selected_clips.at(i)); + if (c != nullptr) { + for (int j=0;jeffects.size();j++) { + if (c->effects.at(j)->container->is_focused()) { + return true; + } + } + } else { + qWarning() << "Tried to check focus of a nullptr clip"; + } + } + return false; } EffectsArea::EffectsArea(QWidget* parent) : - QWidget(parent) + QWidget(parent) {} void EffectsArea::receive_wheel_event(QWheelEvent *e) { - QApplication::sendEvent(this, e); + QApplication::sendEvent(this, e); } diff --git a/panels/panels.cpp b/panels/panels.cpp index 4f8e3e0f2..0bc9bf83a 100644 --- a/panels/panels.cpp +++ b/panels/panels.cpp @@ -47,7 +47,7 @@ void update_effect_controls() { int vclip = -1; int aclip = -1; QVector selected_clips; - int mode = TA_NO_TRANSITION; + int mode = kTransitionNone; if (olive::ActiveSequence != nullptr) { for (int i=0;iclips.size();i++) { ClipPtr clip = olive::ActiveSequence->clips.at(i); @@ -56,11 +56,11 @@ void update_effect_controls() { const Selection& s = olive::ActiveSequence->selections.at(j); bool add = true; if (clip->timeline_in >= s.in && clip->timeline_out <= s.out && clip->track == s.track) { - mode = TA_NO_TRANSITION; - } else if (selection_contains_transition(s, clip, TA_OPENING_TRANSITION)) { - mode = TA_OPENING_TRANSITION; - } else if (selection_contains_transition(s, clip, TA_CLOSING_TRANSITION)) { - mode = TA_CLOSING_TRANSITION; + mode = kTransitionNone; + } else if (selection_contains_transition(s, clip, kTransitionOpening)) { + mode = kTransitionOpening; + } else if (selection_contains_transition(s, clip, kTransitionClosing)) { + mode = kTransitionClosing; } else { add = false; } diff --git a/panels/project.cpp b/panels/project.cpp index 37c99194f..34c7ff843 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -1081,6 +1081,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, stream.writeAttribute("workareaIn", QString::number(s->workarea_in)); stream.writeAttribute("workareaOut", QString::number(s->workarea_out)); + /* for (int j=0;jtransitions.size();j++) { TransitionPtr t = s->transitions.at(j); if (t != nullptr) { @@ -1091,6 +1092,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, stream.writeEndElement(); // transition } } + */ for (int j=0;jclips.size();j++) { const ClipPtr& c = s->clips.at(j); @@ -1103,8 +1105,10 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, stream.writeAttribute("in", QString::number(c->timeline_in)); stream.writeAttribute("out", QString::number(c->timeline_out)); stream.writeAttribute("track", QString::number(c->track)); + /* stream.writeAttribute("opening", QString::number(c->opening_transition)); stream.writeAttribute("closing", QString::number(c->closing_transition)); + */ stream.writeAttribute("r", QString::number(c->color_r)); stream.writeAttribute("g", QString::number(c->color_g)); diff --git a/panels/timeline.cpp b/panels/timeline.cpp index c8349a387..b3fb23bb2 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -371,11 +371,11 @@ void Timeline::add_transition() { if (c != nullptr && is_clip_selected(c, true)) { int transition_to_add = (c->track < 0) ? TRANSITION_INTERNAL_CROSSDISSOLVE : TRANSITION_INTERNAL_LINEARFADE; if (c->get_opening_transition() == nullptr) { - ca->append(new AddTransitionCommand(c, nullptr, nullptr, get_internal_meta(transition_to_add, EFFECT_TYPE_TRANSITION), TA_OPENING_TRANSITION, 30)); + ca->append(new AddTransitionCommand(c, nullptr, nullptr, get_internal_meta(transition_to_add, EFFECT_TYPE_TRANSITION), kTransitionOpening, 30)); adding = true; } if (c->get_closing_transition() == nullptr) { - ca->append(new AddTransitionCommand(c, nullptr, nullptr, get_internal_meta(transition_to_add, EFFECT_TYPE_TRANSITION), TA_CLOSING_TRANSITION, 30)); + ca->append(new AddTransitionCommand(c, nullptr, nullptr, get_internal_meta(transition_to_add, EFFECT_TYPE_TRANSITION), kTransitionClosing, 30)); adding = true; } } @@ -843,19 +843,17 @@ ClipPtr Timeline::split_clip(ComboAction* ca, bool transitions, int p, long fram // } if (pre->get_opening_transition()->get_true_length() > new_clip_length) { - ca->append(new ModifyTransitionCommand(pre, TA_OPENING_TRANSITION, new_clip_length)); - } - - post->sequence->hard_delete_transition(post, TA_OPENING_TRANSITION); + ca->append(new ModifyTransitionCommand(pre->get_opening_transition(), new_clip_length)); + } } if (pre->get_closing_transition() != nullptr) { if (splitting_closing_dual_transition) { // just move closing transition to post clip // WORKAROUND - ca->append(new DeleteTransitionCommand(pre->sequence, pre->closing_transition)); + ca->append(new DeleteTransitionCommand(pre->closing_transition)); } else { - ca->append(new DeleteTransitionCommand(pre->sequence, pre->closing_transition)); + ca->append(new DeleteTransitionCommand(pre->closing_transition)); if (post->get_closing_transition() != nullptr) { if (pre->get_closing_transition()->secondary_clip == nullptr) { @@ -964,7 +962,7 @@ void Timeline::clean_up_selections(QVector& areas) { } bool selection_contains_transition(const Selection& s, ClipPtr c, int type) { - if (type == TA_OPENING_TRANSITION) { + if (type == kTransitionOpening) { return c->get_opening_transition() != nullptr && s.out == c->timeline_in + c->get_opening_transition()->get_true_length() && ((c->get_opening_transition()->secondary_clip == nullptr && s.in == c->timeline_in) @@ -989,12 +987,12 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& area for (int j=0;jclips.size();j++) { ClipPtr c = olive::ActiveSequence->clips.at(j); if (c != nullptr && c->track == s.track && !c->undeletable) { - if (selection_contains_transition(s, c, TA_OPENING_TRANSITION)) { + if (selection_contains_transition(s, c, kTransitionOpening)) { // delete opening transition - ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); - } else if (selection_contains_transition(s, c, TA_CLOSING_TRANSITION)) { + ca->append(new DeleteTransitionCommand(c->opening_transition)); + } else if (selection_contains_transition(s, c, kTransitionClosing)) { // delete closing transition - ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); + ca->append(new DeleteTransitionCommand(c->closing_transition)); } else if (c->timeline_in >= s.in && c->timeline_out <= s.out) { // clips falls entirely within deletion area ca->append(new DeleteClipAction(olive::ActiveSequence, j)); @@ -1012,9 +1010,9 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& area if (c->get_closing_transition() != nullptr) { if (s.in < c->timeline_out - c->get_closing_transition()->get_true_length()) { - ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); + ca->append(new DeleteTransitionCommand(c->closing_transition)); } else { - ca->append(new ModifyTransitionCommand(c, TA_CLOSING_TRANSITION, c->get_closing_transition()->get_true_length() - (c->timeline_out - s.in))); + ca->append(new ModifyTransitionCommand(c->closing_transition, c->get_closing_transition()->get_true_length() - (c->timeline_out - s.in))); } } } else if (c->timeline_in < s.out && c->timeline_out > s.out) { @@ -1023,9 +1021,9 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& area if (c->get_opening_transition() != nullptr) { if (s.out > c->timeline_in + c->get_opening_transition()->get_true_length()) { - ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); + ca->append(new DeleteTransitionCommand(c->opening_transition)); } else { - ca->append(new ModifyTransitionCommand(c, TA_OPENING_TRANSITION, c->get_opening_transition()->get_true_length() - (s.out - c->timeline_in))); + ca->append(new ModifyTransitionCommand(c->opening_transition, c->get_opening_transition()->get_true_length() - (s.out - c->timeline_in))); } } } @@ -2070,13 +2068,13 @@ void move_clip(ComboAction* ca, ClipPtr c, long iin, long iout, long iclip_in, i if (c->get_opening_transition() != nullptr && c->get_opening_transition()->secondary_clip != nullptr && c->get_opening_transition()->secondary_clip->timeline_out != iin) { // separate transition ca->append(new SetPointer(reinterpret_cast(&c->get_opening_transition()->secondary_clip), nullptr)); - ca->append(new AddTransitionCommand(c->get_opening_transition()->secondary_clip, nullptr, c->get_opening_transition(), nullptr, TA_CLOSING_TRANSITION, 0)); + ca->append(new AddTransitionCommand(c->get_opening_transition()->secondary_clip, nullptr, c->get_opening_transition(), nullptr, kTransitionClosing, 0)); } if (c->get_closing_transition() != nullptr && c->get_closing_transition()->secondary_clip != nullptr && c->get_closing_transition()->parent_clip->timeline_in != iout) { // separate transition ca->append(new SetPointer(reinterpret_cast(&c->get_closing_transition()->secondary_clip), nullptr)); - ca->append(new AddTransitionCommand(c, nullptr, c->get_closing_transition(), nullptr, TA_CLOSING_TRANSITION, 0)); + ca->append(new AddTransitionCommand(c, nullptr, c->get_closing_transition(), nullptr, kTransitionClosing, 0)); } } } diff --git a/playback/cacher.cpp b/playback/cacher.cpp index 3c36f2f5f..86dc423b3 100644 --- a/playback/cacher.cpp +++ b/playback/cacher.cpp @@ -79,7 +79,7 @@ void apply_audio_effects(ClipPtr c, double timecode_start, AVFrame* frame, int n double adjustment = transition_end - transition_start; double adjusted_range_start = (timecode_start - transition_start) / adjustment; double adjusted_range_end = (timecode_end - transition_start) / adjustment; - c->get_opening_transition()->process_audio(adjusted_range_start, adjusted_range_end, frame->data[0], nb_bytes, TA_OPENING_TRANSITION); + c->get_opening_transition()->process_audio(adjusted_range_start, adjusted_range_end, frame->data[0], nb_bytes, kTransitionOpening); } } } @@ -92,7 +92,7 @@ void apply_audio_effects(ClipPtr c, double timecode_start, AVFrame* frame, int n double adjustment = transition_end - transition_start; double adjusted_range_start = (timecode_start - transition_start) / adjustment; double adjusted_range_end = (timecode_end - transition_start) / adjustment; - c->get_closing_transition()->process_audio(adjusted_range_start, adjusted_range_end, frame->data[0], nb_bytes, TA_CLOSING_TRANSITION); + c->get_closing_transition()->process_audio(adjusted_range_start, adjusted_range_end, frame->data[0], nb_bytes, kTransitionClosing); } } } diff --git a/project/clip.cpp b/project/clip.cpp index bcfa76d35..4b0a2e80c 100644 --- a/project/clip.cpp +++ b/project/clip.cpp @@ -35,312 +35,299 @@ #include "debug.h" Clip::Clip(SequencePtr s) : - sequence(s), - enabled(true), - clip_in(0), - timeline_in(0), - timeline_out(0), - track(0), - media(nullptr), - speed(1.0), - reverse(false), - maintain_audio_pitch(false), - autoscale(olive::CurrentConfig.autoscale_by_default), - opening_transition(-1), - closing_transition(-1), - undeletable(false), - replaced(false), - ignore_reverse(false), - use_existing_frame(false), - filter_graph(nullptr), - fbo(nullptr), - opts(nullptr) + sequence(s), + enabled(true), + clip_in(0), + timeline_in(0), + timeline_out(0), + track(0), + media(nullptr), + speed(1.0), + reverse(false), + maintain_audio_pitch(false), + autoscale(olive::CurrentConfig.autoscale_by_default), + opening_transition(nullptr), + closing_transition(nullptr), + undeletable(false), + replaced(false), + ignore_reverse(false), + use_existing_frame(false), + filter_graph(nullptr), + fbo(nullptr), + opts(nullptr) { - pkt = av_packet_alloc(); - reset(); + pkt = av_packet_alloc(); + reset(); } ClipPtr Clip::copy(SequencePtr s, bool duplicate_transitions) { - ClipPtr copy(new Clip(s)); + ClipPtr copy(new Clip(s)); - copy->enabled = enabled; - copy->name = QString(name); - copy->clip_in = clip_in; - copy->timeline_in = timeline_in; - copy->timeline_out = timeline_out; - copy->track = track; - copy->color_r = color_r; - copy->color_g = color_g; - copy->color_b = color_b; - copy->media = media; - copy->media_stream = media_stream; - copy->autoscale = autoscale; - copy->speed = speed; - copy->maintain_audio_pitch = maintain_audio_pitch; - copy->reverse = reverse; + copy->enabled = enabled; + copy->name = QString(name); + copy->clip_in = clip_in; + copy->timeline_in = timeline_in; + copy->timeline_out = timeline_out; + copy->track = track; + copy->color_r = color_r; + copy->color_g = color_g; + copy->color_b = color_b; + copy->media = media; + copy->media_stream = media_stream; + copy->autoscale = autoscale; + copy->speed = speed; + copy->maintain_audio_pitch = maintain_audio_pitch; + copy->reverse = reverse; - for (int i=0;ieffects.append(effects.at(i)->copy(copy)); - } + for (int i=0;ieffects.append(effects.at(i)->copy(copy)); + } - copy->cached_fr = (this->sequence == nullptr) ? cached_fr : this->sequence->frame_rate; + copy->cached_fr = (this->sequence == nullptr) ? cached_fr : this->sequence->frame_rate; - if (duplicate_transitions) { - if (get_opening_transition() != nullptr && get_opening_transition()->secondary_clip == nullptr) copy->opening_transition = get_opening_transition()->copy(copy, nullptr); - if (get_closing_transition() != nullptr && get_closing_transition()->secondary_clip == nullptr) copy->closing_transition = get_closing_transition()->copy(copy, nullptr); - } + if (duplicate_transitions) { + if (get_opening_transition() != nullptr && get_opening_transition()->secondary_clip == nullptr) { + copy->opening_transition = get_opening_transition()->copy(copy, nullptr); + } + if (get_closing_transition() != nullptr && get_closing_transition()->secondary_clip == nullptr) { + copy->closing_transition = get_closing_transition()->copy(copy, nullptr); + } + } - copy->recalculateMaxLength(); + copy->recalculateMaxLength(); - return copy; + return copy; } void Clip::reset() { - audio_just_reset = false; - open = false; - finished_opening = false; - pkt_written = false; - audio_reset = false; - frame_sample_index = -1; - audio_buffer_write = false; - texture_frame = -1; - formatCtx = nullptr; - stream = nullptr; - codec = nullptr; - codecCtx = nullptr; - texture = nullptr; - last_invalid_ts = -1; + audio_just_reset = false; + open = false; + finished_opening = false; + pkt_written = false; + audio_reset = false; + frame_sample_index = -1; + audio_buffer_write = false; + texture_frame = -1; + formatCtx = nullptr; + stream = nullptr; + codec = nullptr; + codecCtx = nullptr; + texture = nullptr; + last_invalid_ts = -1; } void Clip::reset_audio() { - if (media == nullptr || media->get_type() == MEDIA_TYPE_FOOTAGE) { - audio_reset = true; - frame_sample_index = -1; - audio_buffer_write = 0; - } else if (media->get_type() == MEDIA_TYPE_SEQUENCE) { - SequencePtr nested_sequence = media->to_sequence(); - for (int i=0;iclips.size();i++) { - ClipPtr c = nested_sequence->clips.at(i); - if (c != nullptr) c->reset_audio(); - } - } + if (media == nullptr || media->get_type() == MEDIA_TYPE_FOOTAGE) { + audio_reset = true; + frame_sample_index = -1; + audio_buffer_write = 0; + } else if (media->get_type() == MEDIA_TYPE_SEQUENCE) { + SequencePtr nested_sequence = media->to_sequence(); + for (int i=0;iclips.size();i++) { + ClipPtr c = nested_sequence->clips.at(i); + if (c != nullptr) c->reset_audio(); + } + } } void Clip::refresh() { - // validates media if it was replaced - if (replaced && media != nullptr && media->get_type() == MEDIA_TYPE_FOOTAGE) { - FootagePtr m = media->to_footage(); + // validates media if it was replaced + if (replaced && media != nullptr && media->get_type() == MEDIA_TYPE_FOOTAGE) { + FootagePtr m = media->to_footage(); - if (track < 0 && m->video_tracks.size() > 0) { - media_stream = m->video_tracks.at(0).file_index; - } else if (track >= 0 && m->audio_tracks.size() > 0) { - media_stream = m->audio_tracks.at(0).file_index; - } - } - replaced = false; + if (track < 0 && m->video_tracks.size() > 0) { + media_stream = m->video_tracks.at(0).file_index; + } else if (track >= 0 && m->audio_tracks.size() > 0) { + media_stream = m->audio_tracks.at(0).file_index; + } + } + replaced = false; - // reinitializes all effects... just in case - for (int i=0;irefresh(); - } + // reinitializes all effects... just in case + for (int i=0;irefresh(); + } - recalculateMaxLength(); + recalculateMaxLength(); } void Clip::queue_clear() { - while (queue.size() > 0) { - av_frame_free(&queue.first()); - queue.removeFirst(); - } + while (queue.size() > 0) { + av_frame_free(&queue.first()); + queue.removeFirst(); + } } void Clip::queue_remove_earliest() { - int earliest_frame = 0; - for (int i=1;ipts < queue.at(earliest_frame)->pts) { - earliest_frame = i; - } - } - av_frame_free(&queue[earliest_frame]); - queue.removeAt(earliest_frame); + int earliest_frame = 0; + for (int i=1;ipts < queue.at(earliest_frame)->pts) { + earliest_frame = i; + } + } + av_frame_free(&queue[earliest_frame]); + queue.removeAt(earliest_frame); } QVector &Clip::get_markers() { - if (media != nullptr) { - return media->get_markers(); - } - return markers; + if (media != nullptr) { + return media->get_markers(); + } + return markers; } TransitionPtr Clip::get_opening_transition() { - if (opening_transition > -1) { - if (this->sequence == nullptr) { - return clipboard_transitions.at(opening_transition); - } else { - return this->sequence->transitions.at(opening_transition); - } - } - return nullptr; + return opening_transition; } TransitionPtr Clip::get_closing_transition() { - if (closing_transition > -1) { - if (this->sequence == nullptr) { - return clipboard_transitions.at(closing_transition); - } else { - return this->sequence->transitions.at(closing_transition); - } - } - return nullptr; + return closing_transition; } Clip::~Clip() { - if (open) { - close_clip(ClipPtr(this), true); - } + if (open) { + close_clip(ClipPtr(this), true); + } - if (opening_transition != -1) this->sequence->hard_delete_transition(ClipPtr(this), TA_OPENING_TRANSITION); - if (closing_transition != -1) this->sequence->hard_delete_transition(ClipPtr(this), TA_CLOSING_TRANSITION); - - effects.clear(); - av_packet_free(&pkt); + effects.clear(); + av_packet_free(&pkt); } long Clip::get_clip_in_with_transition() { - if (get_opening_transition() != nullptr && get_opening_transition()->secondary_clip != nullptr) { - // we must be the secondary clip, so return (timeline in - length) - return clip_in - get_opening_transition()->get_true_length(); - } - return clip_in; + if (get_opening_transition() != nullptr && get_opening_transition()->secondary_clip != nullptr) { + // we must be the secondary clip, so return (timeline in - length) + return clip_in - get_opening_transition()->get_true_length(); + } + return clip_in; } long Clip::get_timeline_in_with_transition() { - if (get_opening_transition() != nullptr && get_opening_transition()->secondary_clip != nullptr) { - // we must be the secondary clip, so return (timeline in - length) - return timeline_in - get_opening_transition()->get_true_length(); - } - return timeline_in; + if (get_opening_transition() != nullptr && get_opening_transition()->secondary_clip != nullptr) { + // we must be the secondary clip, so return (timeline in - length) + return timeline_in - get_opening_transition()->get_true_length(); + } + return timeline_in; } long Clip::get_timeline_out_with_transition() { - if (get_closing_transition() != nullptr && get_closing_transition()->secondary_clip != nullptr) { - // we must be the primary clip, so return (timeline out + length2) - return timeline_out + get_closing_transition()->get_true_length(); - } else { - return timeline_out; - } + if (get_closing_transition() != nullptr && get_closing_transition()->secondary_clip != nullptr) { + // we must be the primary clip, so return (timeline out + length2) + return timeline_out + get_closing_transition()->get_true_length(); + } else { + return timeline_out; + } } // timeline functions long Clip::getLength() { - return timeline_out - timeline_in; + return timeline_out - timeline_in; } double Clip::getMediaFrameRate() { - Q_ASSERT(track < 0); - if (media != nullptr) { - double rate = media->get_frame_rate(media_stream); - if (!qIsNaN(rate)) return rate; - } - if (sequence != nullptr) return sequence->frame_rate; - return qSNaN(); + Q_ASSERT(track < 0); + if (media != nullptr) { + double rate = media->get_frame_rate(media_stream); + if (!qIsNaN(rate)) return rate; + } + if (sequence != nullptr) return sequence->frame_rate; + return qSNaN(); } void Clip::recalculateMaxLength() { - if (this->sequence != nullptr) { - double fr = this->sequence->frame_rate; + if (this->sequence != nullptr) { + double fr = this->sequence->frame_rate; - fr /= speed; + fr /= speed; - calculated_length = LONG_MAX; + calculated_length = LONG_MAX; - if (media != nullptr) { - switch (media->get_type()) { - case MEDIA_TYPE_FOOTAGE: - { - FootagePtr m = media->to_footage(); - const FootageStream* ms = m->get_stream_from_file_index(track < 0, media_stream); - if (ms != nullptr && ms->infinite_length) { - calculated_length = LONG_MAX; - } else { - calculated_length = m->get_length_in_frames(fr); - } - } - break; - case MEDIA_TYPE_SEQUENCE: - { - SequencePtr s = media->to_sequence(); - calculated_length = refactor_frame_number(s->getEndFrame(), s->frame_rate, fr); - } - break; - } - } - } + if (media != nullptr) { + switch (media->get_type()) { + case MEDIA_TYPE_FOOTAGE: + { + FootagePtr m = media->to_footage(); + const FootageStream* ms = m->get_stream_from_file_index(track < 0, media_stream); + if (ms != nullptr && ms->infinite_length) { + calculated_length = LONG_MAX; + } else { + calculated_length = m->get_length_in_frames(fr); + } + } + break; + case MEDIA_TYPE_SEQUENCE: + { + SequencePtr s = media->to_sequence(); + calculated_length = refactor_frame_number(s->getEndFrame(), s->frame_rate, fr); + } + break; + } + } + } } long Clip::getMaximumLength() { - return calculated_length; + return calculated_length; } int Clip::getWidth() { - if (media == nullptr && sequence != nullptr) return sequence->width; - switch (media->get_type()) { - case MEDIA_TYPE_FOOTAGE: - { - const FootageStream* ms = media->to_footage()->get_stream_from_file_index(track < 0, media_stream); - if (ms != nullptr) return ms->video_width; - if (sequence != nullptr) return sequence->width; - break; - } - case MEDIA_TYPE_SEQUENCE: - { - SequencePtr s = media->to_sequence(); - return s->width; - break; - } - } - return 0; + if (media == nullptr && sequence != nullptr) return sequence->width; + switch (media->get_type()) { + case MEDIA_TYPE_FOOTAGE: + { + const FootageStream* ms = media->to_footage()->get_stream_from_file_index(track < 0, media_stream); + if (ms != nullptr) return ms->video_width; + if (sequence != nullptr) return sequence->width; + break; + } + case MEDIA_TYPE_SEQUENCE: + { + SequencePtr s = media->to_sequence(); + return s->width; + break; + } + } + return 0; } int Clip::getHeight() { - if (media == nullptr && sequence != nullptr) return sequence->height; - switch (media->get_type()) { - case MEDIA_TYPE_FOOTAGE: - { - const FootageStream* ms = media->to_footage()->get_stream_from_file_index(track < 0, media_stream); - if (ms != nullptr) return ms->video_height; - if (sequence != nullptr) return sequence->height; - } - case MEDIA_TYPE_SEQUENCE: - { - SequencePtr s = media->to_sequence(); - return s->height; - } - } - return 0; + if (media == nullptr && sequence != nullptr) return sequence->height; + switch (media->get_type()) { + case MEDIA_TYPE_FOOTAGE: + { + const FootageStream* ms = media->to_footage()->get_stream_from_file_index(track < 0, media_stream); + if (ms != nullptr) return ms->video_height; + if (sequence != nullptr) return sequence->height; + } + case MEDIA_TYPE_SEQUENCE: + { + SequencePtr s = media->to_sequence(); + return s->height; + } + } + return 0; } void Clip::refactor_frame_rate(ComboAction* ca, double multiplier, bool change_timeline_points) { - if (change_timeline_points) { - move_clip(ca, ClipPtr(this), - qRound((double) timeline_in * multiplier), - qRound((double) timeline_out * multiplier), - qRound((double) clip_in * multiplier), - track); - } + if (change_timeline_points) { + move_clip(ca, ClipPtr(this), + qRound((double) timeline_in * multiplier), + qRound((double) timeline_out * multiplier), + qRound((double) clip_in * multiplier), + track); + } - // move keyframes - for (int i=0;irow_count();j++) { - EffectRow* r = e->row(j); - for (int l=0;lfieldCount();l++) { - EffectField* f = r->field(l); - for (int k=0;kkeyframes.size();k++) { - ca->append(new SetLong(&f->keyframes[k].time, f->keyframes[k].time, f->keyframes[k].time * multiplier)); - } - } - } - } + // move keyframes + for (int i=0;irow_count();j++) { + EffectRow* r = e->row(j); + for (int l=0;lfieldCount();l++) { + EffectField* f = r->field(l); + for (int k=0;kkeyframes.size();k++) { + ca->append(new SetLong(&f->keyframes[k].time, f->keyframes[k].time, f->keyframes[k].time * multiplier)); + } + } + } + } } diff --git a/project/clip.h b/project/clip.h index ab6eb934a..0644cf43c 100644 --- a/project/clip.h +++ b/project/clip.h @@ -38,8 +38,8 @@ #include "marker.h" extern "C" { - #include - #include +#include +#include } using ClipPtr = std::shared_ptr; @@ -49,109 +49,109 @@ using SequencePtr = std::shared_ptr; class Clip { public: - Clip(SequencePtr s); - ~Clip(); - ClipPtr copy(SequencePtr s, bool duplicate_transitions = true); - void reset_audio(); - void reset(); - void refresh(); - long get_clip_in_with_transition(); - long get_timeline_in_with_transition(); - long get_timeline_out_with_transition(); - long getLength(); - double getMediaFrameRate(); - long getMaximumLength(); - void recalculateMaxLength(); - int getWidth(); - int getHeight(); - void refactor_frame_rate(ComboAction* ca, double multiplier, bool change_timeline_points); - SequencePtr sequence; + Clip(SequencePtr s); + ~Clip(); + ClipPtr copy(SequencePtr s, bool duplicate_transitions = true); + void reset_audio(); + void reset(); + void refresh(); + long get_clip_in_with_transition(); + long get_timeline_in_with_transition(); + long get_timeline_out_with_transition(); + long getLength(); + double getMediaFrameRate(); + long getMaximumLength(); + void recalculateMaxLength(); + int getWidth(); + int getHeight(); + void refactor_frame_rate(ComboAction* ca, double multiplier, bool change_timeline_points); + SequencePtr sequence; - // queue functions - void queue_clear(); - void queue_remove_earliest(); + // queue functions + void queue_clear(); + void queue_remove_earliest(); - // timeline variables (should be copied in copy()) - bool enabled; - long clip_in; - long timeline_in; - long timeline_out; - int track; - QString name; - quint8 color_r; - quint8 color_g; - quint8 color_b; - Media* media; - int media_stream; - double speed; - double cached_fr; - bool reverse; - bool maintain_audio_pitch; - bool autoscale; + // timeline variables (should be copied in copy()) + bool enabled; + long clip_in; + long timeline_in; + long timeline_out; + int track; + QString name; + quint8 color_r; + quint8 color_g; + quint8 color_b; + Media* media; + int media_stream; + double speed; + double cached_fr; + bool reverse; + bool maintain_audio_pitch; + bool autoscale; - // markers - QVector& get_markers(); + // markers + QVector& get_markers(); - // other variables (should be deep copied/duplicated in copy()) - QList effects; - QVector linked; - int opening_transition; - TransitionPtr get_opening_transition(); - int closing_transition; - TransitionPtr get_closing_transition(); + // other variables (should be deep copied/duplicated in copy()) + QList effects; + QVector linked; + TransitionPtr opening_transition; + TransitionPtr get_opening_transition(); + TransitionPtr closing_transition; + TransitionPtr get_closing_transition(); - // media handling - AVFormatContext* formatCtx; - AVStream* stream; - AVCodec* codec; - AVCodecContext* codecCtx; - AVPacket* pkt; - AVFrame* frame; - AVDictionary* opts; - long calculated_length; + // media handling + AVFormatContext* formatCtx; + AVStream* stream; + AVCodec* codec; + AVCodecContext* codecCtx; + AVPacket* pkt; + AVFrame* frame; + AVDictionary* opts; + long calculated_length; - // temporary variables - int load_id; - bool undeletable; - bool reached_end; - bool pkt_written; - bool open; - bool finished_opening; - bool replaced; - bool ignore_reverse; - int pix_fmt; + // temporary variables + int load_id; + bool undeletable; + bool reached_end; + bool pkt_written; + bool open; + bool finished_opening; + bool replaced; + bool ignore_reverse; + int pix_fmt; - // caching functions - bool use_existing_frame; - bool multithreaded; - Cacher* cacher; - QWaitCondition can_cache; - int max_queue_size; - QVector queue; - QMutex queue_lock; - QMutex lock; - QMutex open_lock; - int64_t last_invalid_ts; + // caching functions + bool use_existing_frame; + bool multithreaded; + Cacher* cacher; + QWaitCondition can_cache; + int max_queue_size; + QVector queue; + QMutex queue_lock; + QMutex lock; + QMutex open_lock; + int64_t last_invalid_ts; - // converters/filters - AVFilterGraph* filter_graph; - AVFilterContext* buffersink_ctx; - AVFilterContext* buffersrc_ctx; + // converters/filters + AVFilterGraph* filter_graph; + AVFilterContext* buffersink_ctx; + AVFilterContext* buffersrc_ctx; - // video playback variables - QOpenGLFramebufferObject** fbo; - QOpenGLTexture* texture; - long texture_frame; + // video playback variables + QOpenGLFramebufferObject** fbo; + QOpenGLTexture* texture; + long texture_frame; - // audio playback variables - int64_t reverse_target; - int frame_sample_index; - qint64 audio_buffer_write; - bool audio_reset; - bool audio_just_reset; - long audio_target_frame; + // audio playback variables + int64_t reverse_target; + int frame_sample_index; + qint64 audio_buffer_write; + bool audio_reset; + bool audio_just_reset; + long audio_target_frame; private: - QVector markers; + QVector markers; }; #endif // CLIP_H diff --git a/project/sequence.cpp b/project/sequence.cpp index 8d6d15535..cd671b712 100644 --- a/project/sequence.cpp +++ b/project/sequence.cpp @@ -67,42 +67,6 @@ long Sequence::getEndFrame() { return end; } -void Sequence::hard_delete_transition(ClipPtr c, int type) { - int transition_index = (type == TA_OPENING_TRANSITION) ? c->opening_transition : c->closing_transition; - if (transition_index > -1) { - bool del = true; - - TransitionPtr t = transitions.at(transition_index); - if (t->secondary_clip != nullptr) { - for (int i=0;iopening_transition == transition_index - || c->closing_transition == transition_index)) { - if (type == TA_OPENING_TRANSITION) { - // convert to closing transition - t->parent_clip = t->secondary_clip; - } - - del = false; - t->secondary_clip = nullptr; - } - } - } - - if (del) { - transitions[transition_index].reset(); - } - - if (type == TA_OPENING_TRANSITION) { - c->opening_transition = -1; - } else { - c->closing_transition = -1; - } - } -} - void Sequence::getTrackLimits(int* video_tracks, int* audio_tracks) { int vt = 0; int at = 0; diff --git a/project/sequence.h b/project/sequence.h index 60ac73192..bdb150305 100644 --- a/project/sequence.h +++ b/project/sequence.h @@ -35,8 +35,7 @@ public: SequencePtr copy(); QString name; void getTrackLimits(int* video_tracks, int* audio_tracks); - long getEndFrame(); - void hard_delete_transition(ClipPtr c, int type); + long getEndFrame(); int width; int height; double frame_rate; @@ -56,7 +55,6 @@ public: QVector markers; QVector clips; - QVector transitions; }; using SequencePtr = std::shared_ptr; diff --git a/project/transition.cpp b/project/transition.cpp index b11b00f15..d4ff4f6e1 100644 --- a/project/transition.cpp +++ b/project/transition.cpp @@ -42,74 +42,92 @@ #include Transition::Transition(ClipPtr c, ClipPtr s, const EffectMeta* em) : - Effect(c, em), secondary_clip(s), - length(30) + Effect(c, em), secondary_clip(s), + length(30) { - length_field = add_row(tr("Length"), false)->add_field(EFFECT_FIELD_DOUBLE, "length"); - connect(length_field, SIGNAL(changed()), this, SLOT(set_length_from_slider())); - length_field->set_double_default_value(30); - length_field->set_double_minimum_value(0); + length_field = add_row(tr("Length"), false)->add_field(EFFECT_FIELD_DOUBLE, "length"); + connect(length_field, SIGNAL(changed()), this, SLOT(set_length_from_slider())); + length_field->set_double_default_value(30); + length_field->set_double_minimum_value(0); - LabelSlider* length_ui_ele = static_cast(length_field->ui_element); - length_ui_ele->set_display_type(LABELSLIDER_FRAMENUMBER); - length_ui_ele->set_frame_rate(parent_clip->sequence == nullptr ? parent_clip->cached_fr : parent_clip->sequence->frame_rate); + LabelSlider* length_ui_ele = static_cast(length_field->ui_element); + length_ui_ele->set_display_type(LABELSLIDER_FRAMENUMBER); + length_ui_ele->set_frame_rate(parent_clip->sequence == nullptr ? parent_clip->cached_fr : parent_clip->sequence->frame_rate); } -int Transition::copy(ClipPtr c, ClipPtr s) { - return create_transition(c, s, meta, length); +TransitionPtr Transition::copy(ClipPtr c, ClipPtr s) { + return create_transition(c, s, meta, length); } void Transition::set_length(long l) { - length = l; - length_field->set_double_value(l); + length = l; + length_field->set_double_value(l); } long Transition::get_true_length() { - return length; + return length; } long Transition::get_length() { - if (secondary_clip != nullptr) { - return length * 2; - } - return length; + if (secondary_clip != nullptr) { + return length * 2; + } + return length; +} + +ClipPtr Transition::get_opened_clip() { + if (parent_clip->opening_transition.get() == this) { + return parent_clip; + } else if (secondary_clip != nullptr && secondary_clip->opening_transition.get() == this) { + return secondary_clip; + } + return nullptr; +} + +ClipPtr Transition::get_closed_clip() { + if (parent_clip->closing_transition.get() == this) { + return parent_clip; + } else if (secondary_clip != nullptr && secondary_clip->closing_transition.get() == this) { + return secondary_clip; + } + return nullptr; } void Transition::set_length_from_slider() { - set_length(length_field->get_double_value(0)); - update_ui(false); + set_length(length_field->get_double_value(0)); + update_ui(false); } TransitionPtr get_transition_from_meta(ClipPtr c, ClipPtr s, const EffectMeta* em) { - if (!em->filename.isEmpty()) { - // load effect from file - return TransitionPtr(new Transition(c, s, em)); - } else if (em->internal >= 0 && em->internal < TRANSITION_INTERNAL_COUNT) { - // must be an internal effect - switch (em->internal) { - case TRANSITION_INTERNAL_CROSSDISSOLVE: return TransitionPtr(new CrossDissolveTransition(c, s, em)); - case TRANSITION_INTERNAL_LINEARFADE: return TransitionPtr(new LinearFadeTransition(c, s, em)); - case TRANSITION_INTERNAL_EXPONENTIALFADE: return TransitionPtr(new ExponentialFadeTransition(c, s, em)); - case TRANSITION_INTERNAL_LOGARITHMICFADE: return TransitionPtr(new LogarithmicFadeTransition(c, s, em)); - case TRANSITION_INTERNAL_CUBE: return TransitionPtr(new CubeTransition(c, s, em)); - } - } else { - qCritical() << "Invalid transition data"; - QMessageBox::critical(olive::MainWindow, - QCoreApplication::translate("transition", "Invalid transition"), - QCoreApplication::translate("transition", "No candidate for transition '%1'. This transition may be corrupt. Try reinstalling it or Olive.").arg(em->name) - ); - } - return nullptr; + if (!em->filename.isEmpty()) { + // load effect from file + return TransitionPtr(new Transition(c, s, em)); + } else if (em->internal >= 0 && em->internal < TRANSITION_INTERNAL_COUNT) { + // must be an internal effect + switch (em->internal) { + case TRANSITION_INTERNAL_CROSSDISSOLVE: return TransitionPtr(new CrossDissolveTransition(c, s, em)); + case TRANSITION_INTERNAL_LINEARFADE: return TransitionPtr(new LinearFadeTransition(c, s, em)); + case TRANSITION_INTERNAL_EXPONENTIALFADE: return TransitionPtr(new ExponentialFadeTransition(c, s, em)); + case TRANSITION_INTERNAL_LOGARITHMICFADE: return TransitionPtr(new LogarithmicFadeTransition(c, s, em)); + case TRANSITION_INTERNAL_CUBE: return TransitionPtr(new CubeTransition(c, s, em)); + } + } else { + qCritical() << "Invalid transition data"; + QMessageBox::critical(olive::MainWindow, + QCoreApplication::translate("transition", "Invalid transition"), + QCoreApplication::translate("transition", "No candidate for transition '%1'. This transition may be corrupt. Try reinstalling it or Olive.").arg(em->name) + ); + } + return nullptr; } -int create_transition(ClipPtr c, ClipPtr s, const EffectMeta* em, long length) { - TransitionPtr t(get_transition_from_meta(c, s, em)); - if (t != nullptr) { - if (length >= 0) t->set_length(length); - QVector& transition_list = (c->sequence == nullptr) ? clipboard_transitions : c->sequence->transitions; - transition_list.append(t); - return transition_list.size() - 1; - } - return -1; +TransitionPtr create_transition(ClipPtr c, ClipPtr s, const EffectMeta* em, long length) { + TransitionPtr t(get_transition_from_meta(c, s, em)); + if (t != nullptr) { + if (length > 0) { + t->set_length(length); + } + return t; + } + return nullptr; } diff --git a/project/transition.h b/project/transition.h index 2677fb332..b8677b119 100644 --- a/project/transition.h +++ b/project/transition.h @@ -23,35 +23,45 @@ #include "effect.h" -#define TA_NO_TRANSITION 0 -#define TA_OPENING_TRANSITION 1 -#define TA_CLOSING_TRANSITION 2 - -#define TRANSITION_INTERNAL_CROSSDISSOLVE 0 -#define TRANSITION_INTERNAL_LINEARFADE 1 -#define TRANSITION_INTERNAL_EXPONENTIALFADE 2 -#define TRANSITION_INTERNAL_LOGARITHMICFADE 3 -#define TRANSITION_INTERNAL_CUBE 4 -#define TRANSITION_INTERNAL_COUNT 5 - -int create_transition(ClipPtr c, ClipPtr s, const EffectMeta* em, long length = -1); - -class Transition : public Effect { - Q_OBJECT -public: - Transition(ClipPtr c, ClipPtr s, const EffectMeta* em); - int copy(ClipPtr c, ClipPtr s); - ClipPtr secondary_clip; - void set_length(long l); - long get_true_length(); - long get_length(); -private slots: - void set_length_from_slider(); -private: - long length; // used only for transitions - EffectField* length_field; +enum TransitionType { + kTransitionNone, + kTransitionOpening, + kTransitionClosing }; +enum TransitionInternal { + TRANSITION_INTERNAL_CROSSDISSOLVE, + TRANSITION_INTERNAL_LINEARFADE, + TRANSITION_INTERNAL_EXPONENTIALFADE, + TRANSITION_INTERNAL_LOGARITHMICFADE, + TRANSITION_INTERNAL_CUBE, + TRANSITION_INTERNAL_COUNT +}; + +class Transition; using TransitionPtr = std::shared_ptr; +TransitionPtr get_transition_from_meta(ClipPtr c, ClipPtr s, const EffectMeta* em); + +TransitionPtr create_transition(ClipPtr c, ClipPtr s, const EffectMeta* em, long length = 0); + +class Transition : public Effect { + Q_OBJECT +public: + Transition(ClipPtr c, ClipPtr s, const EffectMeta* em); + virtual TransitionPtr copy(ClipPtr c, ClipPtr s); + ClipPtr secondary_clip; + void set_length(long l); + long get_true_length(); + long get_length(); + + ClipPtr get_opened_clip(); + ClipPtr get_closed_clip(); +private slots: + void set_length_from_slider(); +private: + long length; // used only for transitions + EffectField* length_field; +}; + #endif // TRANSITION_H diff --git a/project/undo.cpp b/project/undo.cpp index 27a5b1344..7a5c596dc 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -49,201 +49,175 @@ QUndoStack olive::UndoStack; MoveClipAction::MoveClipAction(ClipPtr c, long iin, long iout, long iclip_in, int itrack, bool irelative) { - clip = c; + clip = c; - old_in = c->timeline_in; - old_out = c->timeline_out; - old_clip_in = c->clip_in; - old_track = c->track; + old_in = c->timeline_in; + old_out = c->timeline_out; + old_clip_in = c->clip_in; + old_track = c->track; - new_in = iin; - new_out = iout; - new_clip_in = iclip_in; - new_track = itrack; + new_in = iin; + new_out = iout; + new_clip_in = iclip_in; + new_track = itrack; - relative = irelative; + relative = irelative; } void MoveClipAction::doUndo() { - if (relative) { - clip->timeline_in -= new_in; - clip->timeline_out -= new_out; - clip->clip_in -= new_clip_in; - clip->track -= new_track; - } else { - clip->timeline_in = old_in; - clip->timeline_out = old_out; - clip->clip_in = old_clip_in; - clip->track = old_track; - } + if (relative) { + clip->timeline_in -= new_in; + clip->timeline_out -= new_out; + clip->clip_in -= new_clip_in; + clip->track -= new_track; + } else { + clip->timeline_in = old_in; + clip->timeline_out = old_out; + clip->clip_in = old_clip_in; + clip->track = old_track; + } } void MoveClipAction::doRedo() { - if (relative) { - clip->timeline_in += new_in; - clip->timeline_out += new_out; - clip->clip_in += new_clip_in; - clip->track += new_track; - } else { - clip->timeline_in = new_in; - clip->timeline_out = new_out; - clip->clip_in = new_clip_in; - clip->track = new_track; - } + if (relative) { + clip->timeline_in += new_in; + clip->timeline_out += new_out; + clip->clip_in += new_clip_in; + clip->track += new_track; + } else { + clip->timeline_in = new_in; + clip->timeline_out = new_out; + clip->clip_in = new_clip_in; + clip->track = new_track; + } } DeleteClipAction::DeleteClipAction(SequencePtr s, int clip) { - seq = s; - index = clip; - opening_transition = -1; - closing_transition = -1; + seq = s; + index = clip; + opening_transition = -1; + closing_transition = -1; } DeleteClipAction::~DeleteClipAction() {} void DeleteClipAction::doUndo() { - // restore ref to clip - seq->clips[index] = ref; + // restore ref to clip + seq->clips[index] = ref; - // restore shared transitions - if (opening_transition > -1) { - seq->transitions.at(opening_transition)->secondary_clip = seq->transitions.at(opening_transition)->parent_clip; - seq->transitions.at(opening_transition)->parent_clip = ref; - ref->opening_transition = opening_transition; - opening_transition = -1; - } - if (closing_transition > -1) { - seq->transitions.at(closing_transition)->secondary_clip = ref; - ref->closing_transition = closing_transition; - closing_transition = -1; - } + // restore links to this clip + for (int i=linkClipIndex.size()-1;i>=0;i--) { + seq->clips.at(linkClipIndex.at(i))->linked.insert(linkLinkIndex.at(i), index); + } - // restore links to this clip - for (int i=linkClipIndex.size()-1;i>=0;i--) { - seq->clips.at(linkClipIndex.at(i))->linked.insert(linkLinkIndex.at(i), index); - } - - ref = nullptr; + ref = nullptr; } void DeleteClipAction::doRedo() { - // remove ref to clip - ref = seq->clips.at(index); - if (ref->open) { - close_clip(ref, true); - } - seq->clips[index] = nullptr; + // remove ref to clip + ref = seq->clips.at(index); + if (ref->open) { + close_clip(ref, true); + } + seq->clips[index] = nullptr; - // save shared transitions - if (ref->opening_transition > -1 && ref->get_opening_transition()->secondary_clip != nullptr) { - opening_transition = ref->opening_transition; - ref->get_opening_transition()->parent_clip = ref->get_opening_transition()->secondary_clip; - ref->get_opening_transition()->secondary_clip = nullptr; - ref->opening_transition = -1; - } - if (ref->closing_transition > -1 && ref->get_closing_transition()->secondary_clip != nullptr) { - closing_transition = ref->closing_transition; - ref->get_closing_transition()->secondary_clip = nullptr; - ref->closing_transition = -1; - } - - // delete link to this clip - linkClipIndex.clear(); - linkLinkIndex.clear(); - for (int i=0;iclips.size();i++) { - ClipPtr c = seq->clips.at(i); - if (c != nullptr) { - for (int j=0;jlinked.size();j++) { - if (c->linked.at(j) == index) { - linkClipIndex.append(i); - linkLinkIndex.append(j); - c->linked.removeAt(j); - } - } - } + // delete link to this clip + linkClipIndex.clear(); + linkLinkIndex.clear(); + for (int i=0;iclips.size();i++) { + ClipPtr c = seq->clips.at(i); + if (c != nullptr) { + for (int j=0;jlinked.size();j++) { + if (c->linked.at(j) == index) { + linkClipIndex.append(i); + linkLinkIndex.append(j); + c->linked.removeAt(j); + } + } } + } } ChangeSequenceAction::ChangeSequenceAction(SequencePtr s) { - new_sequence = s; + new_sequence = s; } void ChangeSequenceAction::doUndo() { - set_sequence(old_sequence); + set_sequence(old_sequence); } void ChangeSequenceAction::doRedo() { - old_sequence = olive::ActiveSequence; - set_sequence(new_sequence); + old_sequence = olive::ActiveSequence; + set_sequence(new_sequence); } SetTimelineInOutCommand::SetTimelineInOutCommand(SequencePtr s, bool enabled, long in, long out) { - seq = s; - new_enabled = enabled; - new_in = in; - new_out = out; + seq = s; + new_enabled = enabled; + new_in = in; + new_out = out; } void SetTimelineInOutCommand::doUndo() { - seq->using_workarea = old_enabled; - seq->workarea_in = old_in; - seq->workarea_out = old_out; + seq->using_workarea = old_enabled; + seq->workarea_in = old_in; + seq->workarea_out = old_out; - // footage viewer functions - if (seq->wrapper_sequence) { - FootagePtr m = seq->clips.at(0)->media->to_footage(); - m->using_inout = old_enabled; - m->in = old_in; - m->out = old_out; - } + // footage viewer functions + if (seq->wrapper_sequence) { + FootagePtr m = seq->clips.at(0)->media->to_footage(); + m->using_inout = old_enabled; + m->in = old_in; + m->out = old_out; + } } void SetTimelineInOutCommand::doRedo() { - old_enabled = seq->using_workarea; - old_in = seq->workarea_in; - old_out = seq->workarea_out; + old_enabled = seq->using_workarea; + old_in = seq->workarea_in; + old_out = seq->workarea_out; - seq->using_workarea = new_enabled; - seq->workarea_in = new_in; - seq->workarea_out = new_out; + seq->using_workarea = new_enabled; + seq->workarea_in = new_in; + seq->workarea_out = new_out; - // footage viewer functions - if (seq->wrapper_sequence) { - FootagePtr m = seq->clips.at(0)->media->to_footage(); - m->using_inout = new_enabled; - m->in = new_in; - m->out = new_out; - } + // footage viewer functions + if (seq->wrapper_sequence) { + FootagePtr m = seq->clips.at(0)->media->to_footage(); + m->using_inout = new_enabled; + m->in = new_in; + m->out = new_out; + } } AddEffectCommand::AddEffectCommand(ClipPtr c, EffectPtr e, const EffectMeta *m, int insert_pos) { - clip = c; - ref = e; - meta = m; - pos = insert_pos; - done = false; + clip = c; + ref = e; + meta = m; + pos = insert_pos; + done = false; } void AddEffectCommand::doUndo() { - clip->effects.last()->close(); - if (pos < 0) { - clip->effects.removeLast(); - } else { - clip->effects.removeAt(pos); - } - done = false; + clip->effects.last()->close(); + if (pos < 0) { + clip->effects.removeLast(); + } else { + clip->effects.removeAt(pos); + } + done = false; } void AddEffectCommand::doRedo() { - if (ref == nullptr) { - ref = create_effect(clip, meta); - } - if (pos < 0) { - clip->effects.append(ref); - } else { - clip->effects.insert(pos, ref); - } - done = true; + if (ref == nullptr) { + ref = create_effect(clip, meta); + } + if (pos < 0) { + clip->effects.append(ref); + } else { + clip->effects.insert(pos, ref); + } + done = true; } AddTransitionCommand::AddTransitionCommand(ClipPtr c, @@ -252,939 +226,930 @@ AddTransitionCommand::AddTransitionCommand(ClipPtr c, const EffectMeta *itransition, int itype, int ilength) { - clip = c; - secondary = s; - transition_to_copy = copy; - transition = itransition; - type = itype; - length = ilength; + primary = c; + secondary = s; + transition_to_copy = copy; + transition_meta_ = itransition; + type = itype; + length = ilength; } void AddTransitionCommand::doUndo() { - clip->sequence->hard_delete_transition(clip, type); - if (secondary != nullptr) secondary->sequence->hard_delete_transition(secondary, (type == TA_OPENING_TRANSITION) ? TA_CLOSING_TRANSITION : TA_OPENING_TRANSITION); - - if (type == TA_OPENING_TRANSITION) { - clip->opening_transition = old_ptransition; - if (secondary != nullptr) secondary->closing_transition = old_stransition; - } else { - clip->closing_transition = old_ptransition; - if (secondary != nullptr) secondary->opening_transition = old_stransition; - } + if (type == kTransitionOpening) { + primary->opening_transition = old_ptransition; + if (secondary != nullptr) secondary->closing_transition = old_stransition; + } else { + primary->closing_transition = old_ptransition; + if (secondary != nullptr) secondary->opening_transition = old_stransition; + } } void AddTransitionCommand::doRedo() { - if (type == TA_OPENING_TRANSITION) { - old_ptransition = clip->opening_transition; - clip->opening_transition = (transition_to_copy == nullptr) ? create_transition(clip, secondary, transition) : transition_to_copy->copy(clip, nullptr); - if (secondary != nullptr) { - old_stransition = secondary->closing_transition; - secondary->closing_transition = clip->opening_transition; - } - if (length > 0) { - clip->get_opening_transition()->set_length(length); - } - } else { - old_ptransition = clip->closing_transition; - clip->closing_transition = (transition_to_copy == nullptr) ? create_transition(clip, secondary, transition) : transition_to_copy->copy(clip, nullptr); - if (secondary != nullptr) { - old_stransition = secondary->opening_transition; - secondary->opening_transition = clip->closing_transition; - } - if (length > 0) { - clip->get_closing_transition()->set_length(length); - } - } + // store old transition of primary clip + old_ptransition = primary->opening_transition; + + // create new transition object + TransitionPtr new_transition; + if (transition_to_copy == nullptr) { + new_transition = get_transition_from_meta(primary, secondary, transition_meta_); + } else { + new_transition = transition_to_copy->copy(primary, nullptr); + } + + primary->opening_transition = new_transition; + + if (secondary != nullptr) { + // store old secondary transition + old_stransition = secondary->closing_transition; + + // set secondary transition to the same transition + secondary->closing_transition = new_transition; + } + + // if a length was specified, set it now + if (length > 0) { + new_transition->set_length(length); + } } -ModifyTransitionCommand::ModifyTransitionCommand(ClipPtr c, int itype, long ilength) { - clip = c; - type = itype; - new_length = ilength; +ModifyTransitionCommand::ModifyTransitionCommand(TransitionPtr t, long ilength) { + transition_ref_ = t; + new_length_ = ilength; } void ModifyTransitionCommand::doUndo() { - TransitionPtr t = (type == TA_OPENING_TRANSITION) ? clip->get_opening_transition() : clip->get_closing_transition(); - t->set_length(old_length); + transition_ref_->set_length(old_length_); } void ModifyTransitionCommand::doRedo() { - TransitionPtr t = (type == TA_OPENING_TRANSITION) ? clip->get_opening_transition() : clip->get_closing_transition(); - old_length = t->get_true_length(); - t->set_length(new_length); + old_length_ = transition_ref_->get_true_length(); + transition_ref_->set_length(new_length_); } -DeleteTransitionCommand::DeleteTransitionCommand(SequencePtr s, int transition_index) { - seq = s; - index = transition_index; - transition = nullptr; - otc = nullptr; - ctc = nullptr; +DeleteTransitionCommand::DeleteTransitionCommand(TransitionPtr t) { + transition_ref_ = t; } -DeleteTransitionCommand::~DeleteTransitionCommand() {} - void DeleteTransitionCommand::doUndo() { - seq->transitions[index] = transition; + if (opened_clip_ != nullptr) { + opened_clip_->opening_transition = transition_ref_; + } - if (otc != nullptr) otc->opening_transition = index; - if (ctc != nullptr) ctc->closing_transition = index; - - transition = nullptr; + if (closed_clip_ != nullptr) { + closed_clip_->closing_transition = transition_ref_; + } } void DeleteTransitionCommand::doRedo() { - for (int i=0;iclips.size();i++) { - ClipPtr c = seq->clips.at(i); - if (c != nullptr) { - if (c->opening_transition == index) { - otc = c; - c->opening_transition = -1; - } - if (c->closing_transition == index) { - ctc = c; - c->closing_transition = -1; - } - } - } + opened_clip_ = transition_ref_->get_opened_clip(); + closed_clip_ = transition_ref_->get_closed_clip(); - transition = seq->transitions.at(index); - seq->transitions[index] = nullptr; + if (opened_clip_ != nullptr) { + opened_clip_->opening_transition = nullptr; + } + + if (closed_clip_ != nullptr) { + closed_clip_->closing_transition = nullptr; + } } NewSequenceCommand::NewSequenceCommand(Media *s, Media* iparent) { - seq = s; - parent = iparent; - done = false; + seq = s; + parent = iparent; + done = false; - if (parent == nullptr) parent = olive::project_model.get_root(); + if (parent == nullptr) parent = olive::project_model.get_root(); } NewSequenceCommand::~NewSequenceCommand() { - if (!done) delete seq; + if (!done) delete seq; } void NewSequenceCommand::doUndo() { - olive::project_model.removeChild(parent, seq); + olive::project_model.removeChild(parent, seq); - done = false; + done = false; } void NewSequenceCommand::doRedo() { - olive::project_model.appendChild(parent, seq); + olive::project_model.appendChild(parent, seq); - done = true; + done = true; } AddMediaCommand::AddMediaCommand(Media* iitem, Media *iparent) { - item = iitem; - parent = iparent; - done = false; + item = iitem; + parent = iparent; + done = false; } AddMediaCommand::~AddMediaCommand() { - if (!done) { - delete item; - } + if (!done) { + delete item; + } } void AddMediaCommand::doUndo() { - olive::project_model.removeChild(parent, item); - done = false; - + olive::project_model.removeChild(parent, item); + done = false; + } void AddMediaCommand::doRedo() { - olive::project_model.appendChild(parent, item); + olive::project_model.appendChild(parent, item); - done = true; + done = true; } DeleteMediaCommand::DeleteMediaCommand(Media* i) { - item = i; - parent = i->parentItem(); + item = i; + parent = i->parentItem(); } DeleteMediaCommand::~DeleteMediaCommand() { - if (done) { - delete item; - } + if (done) { + delete item; + } } void DeleteMediaCommand::doUndo() { - olive::project_model.appendChild(parent, item); + olive::project_model.appendChild(parent, item); - - done = false; + + done = false; } void DeleteMediaCommand::doRedo() { - olive::project_model.removeChild(parent, item); + olive::project_model.removeChild(parent, item); - done = true; + done = true; } AddClipCommand::AddClipCommand(SequencePtr s, QVector& add) { - seq = s; - clips = add; + seq = s; + clips = add; } AddClipCommand::~AddClipCommand() {} void AddClipCommand::doUndo() { - panel_effect_controls->clear_effects(true); - for (int i=0;iclips.last(); - panel_timeline->deselect_area(c->timeline_in, c->timeline_out, c->track); - undone_clips.prepend(c); - if (c->open) close_clip(c, true); - seq->clips.removeLast(); - } - + panel_effect_controls->clear_effects(true); + for (int i=0;iclips.last(); + panel_timeline->deselect_area(c->timeline_in, c->timeline_out, c->track); + undone_clips.prepend(c); + if (c->open) close_clip(c, true); + seq->clips.removeLast(); + } + } void AddClipCommand::doRedo() { - if (undone_clips.size() > 0) { - for (int i=0;iclips.append(undone_clips.at(i)); - } - undone_clips.clear(); - } else { - int linkOffset = seq->clips.size(); - for (int i=0;icopy(seq); - copy->linked.resize(original->linked.size()); - for (int j=0;jlinked.size();j++) { - copy->linked[j] = original->linked.at(j) + linkOffset; - } - if (original->opening_transition > -1) copy->opening_transition = original->get_opening_transition()->copy(copy, nullptr); - if (original->closing_transition > -1) copy->closing_transition = original->get_closing_transition()->copy(copy, nullptr); - seq->clips.append(copy); - } else { - seq->clips.append(nullptr); - } - } - } + if (undone_clips.size() > 0) { + for (int i=0;iclips.append(undone_clips.at(i)); + } + undone_clips.clear(); + } else { + int linkOffset = seq->clips.size(); + for (int i=0;icopy(seq); + copy->linked.resize(original->linked.size()); + for (int j=0;jlinked.size();j++) { + copy->linked[j] = original->linked.at(j) + linkOffset; + } + if (original->opening_transition != nullptr) { + copy->opening_transition = original->get_opening_transition()->copy(copy, nullptr); + } + if (original->closing_transition != nullptr) { + copy->closing_transition = original->get_closing_transition()->copy(copy, nullptr); + } + seq->clips.append(copy); + } else { + seq->clips.append(nullptr); + } + } + } } LinkCommand::LinkCommand() { - link = true; + link = true; } void LinkCommand::doUndo() { - for (int i=0;iclips.at(clips.at(i)); - if (link) { - c->linked.clear(); - } else { - c->linked = old_links.at(i); - } - } - + for (int i=0;iclips.at(clips.at(i)); + if (link) { + c->linked.clear(); + } else { + c->linked = old_links.at(i); + } + } + } void LinkCommand::doRedo() { - old_links.clear(); - for (int i=0;iclips.at(clips.at(i)); - if (link) { - for (int j=0;jlinked.append(clips.at(j)); - } - } - } else { - old_links.append(c->linked); - c->linked.clear(); - } - } + old_links.clear(); + for (int i=0;iclips.at(clips.at(i)); + if (link) { + for (int j=0;jlinked.append(clips.at(j)); + } + } + } else { + old_links.append(c->linked); + c->linked.clear(); + } + } } CheckboxCommand::CheckboxCommand(QCheckBox* b) { - box = b; - checked = box->isChecked(); - done = true; + box = b; + checked = box->isChecked(); + done = true; } CheckboxCommand::~CheckboxCommand() {} void CheckboxCommand::doUndo() { - box->setChecked(!checked); - done = false; - + box->setChecked(!checked); + done = false; + } void CheckboxCommand::doRedo() { - if (!done) { - box->setChecked(checked); - } + if (!done) { + box->setChecked(checked); + } } ReplaceMediaCommand::ReplaceMediaCommand(Media* i, QString s) { - item = i; - new_filename = s; - old_filename = item->to_footage()->url; + item = i; + new_filename = s; + old_filename = item->to_footage()->url; } void ReplaceMediaCommand::replace(QString& filename) { - // close any clips currently using this media - QVector all_sequences = panel_project->list_all_project_sequences(); - for (int i=0;ito_sequence(); - for (int j=0;jclips.size();j++) { - ClipPtr c = s->clips.at(j); - if (c != nullptr && c->media == item && c->open) { - close_clip(c, true); - c->replaced = true; - } - } - } + // close any clips currently using this media + QVector all_sequences = panel_project->list_all_project_sequences(); + for (int i=0;ito_sequence(); + for (int j=0;jclips.size();j++) { + ClipPtr c = s->clips.at(j); + if (c != nullptr && c->media == item && c->open) { + close_clip(c, true); + c->replaced = true; + } + } + } - // replace media - QStringList files; - files.append(filename); - item->to_footage()->ready_lock.lock(); - panel_project->process_file_list(files, false, item, nullptr); + // replace media + QStringList files; + files.append(filename); + item->to_footage()->ready_lock.lock(); + panel_project->process_file_list(files, false, item, nullptr); } void ReplaceMediaCommand::doUndo() { - replace(old_filename); + replace(old_filename); + - } void ReplaceMediaCommand::doRedo() { - replace(new_filename); + replace(new_filename); } ReplaceClipMediaCommand::ReplaceClipMediaCommand(Media *a, Media *b, bool e) { - old_media = a; - new_media = b; - preserve_clip_ins = e; + old_media = a; + new_media = b; + preserve_clip_ins = e; } void ReplaceClipMediaCommand::replace(bool undo) { - if (!undo) { - old_clip_ins.clear(); - } + if (!undo) { + old_clip_ins.clear(); + } - for (int i=0;iopen) { - close_clip(c, true); - } + for (int i=0;iopen) { + close_clip(c, true); + } - if (undo) { - if (!preserve_clip_ins) { - c->clip_in = old_clip_ins.at(i); - } + if (undo) { + if (!preserve_clip_ins) { + c->clip_in = old_clip_ins.at(i); + } - c->media = old_media; - } else { - if (!preserve_clip_ins) { - old_clip_ins.append(c->clip_in); - c->clip_in = 0; - } + c->media = old_media; + } else { + if (!preserve_clip_ins) { + old_clip_ins.append(c->clip_in); + c->clip_in = 0; + } - c->media = new_media; - } + c->media = new_media; + } - c->replaced = true; - c->refresh(); - } + c->replaced = true; + c->refresh(); + } } void ReplaceClipMediaCommand::doUndo() { - replace(true); + replace(true); } void ReplaceClipMediaCommand::doRedo() { - replace(false); + replace(false); - update_ui(true); + update_ui(true); } EffectDeleteCommand::EffectDeleteCommand() { - done = false; + done = false; } EffectDeleteCommand::~EffectDeleteCommand() {} void EffectDeleteCommand::doUndo() { - for (int i=0;ieffects.insert(fx.at(i), deleted_objects.at(i)); - } - panel_effect_controls->reload_clips(); - done = false; - + for (int i=0;ieffects.insert(fx.at(i), deleted_objects.at(i)); + } + panel_effect_controls->reload_clips(); + done = false; + } void EffectDeleteCommand::doRedo() { - deleted_objects.clear(); - for (int i=0;ieffects.at(fx_id); - e->close(); - deleted_objects.append(e); - c->effects.removeAt(fx_id); - } - panel_effect_controls->reload_clips(); - done = true; + deleted_objects.clear(); + for (int i=0;ieffects.at(fx_id); + e->close(); + deleted_objects.append(e); + c->effects.removeAt(fx_id); + } + panel_effect_controls->reload_clips(); + done = true; } MediaMove::MediaMove() {} void MediaMove::doUndo() { - for (int i=0;iparentItem(); - froms[i] = parent; - olive::project_model.moveChild(items.at(i), to); - } + if (to == nullptr) to = olive::project_model.get_root(); + froms.resize(items.size()); + for (int i=0;iparentItem(); + froms[i] = parent; + olive::project_model.moveChild(items.at(i), to); + } } MediaRename::MediaRename(Media* iitem, QString ito) { - item = iitem; - from = iitem->get_name(); - to = ito; + item = iitem; + from = iitem->get_name(); + to = ito; } void MediaRename::doUndo() { - item->set_name(from); - + item->set_name(from); + } void MediaRename::doRedo() { - item->set_name(to); + item->set_name(to); } KeyframeDelete::KeyframeDelete(EffectField *ifield, int iindex) { - field = ifield; - index = iindex; + field = ifield; + index = iindex; } void KeyframeDelete::doUndo() { - field->keyframes.insert(index, deleted_key); + field->keyframes.insert(index, deleted_key); } void KeyframeDelete::doRedo() { - deleted_key = field->keyframes.at(index); - field->keyframes.removeAt(index); + deleted_key = field->keyframes.at(index); + field->keyframes.removeAt(index); } EffectFieldUndo::EffectFieldUndo(EffectField* f) { - field = f; - done = true; + field = f; + done = true; - old_val = field->get_previous_data(); - new_val = field->get_current_data(); + old_val = field->get_previous_data(); + new_val = field->get_current_data(); } void EffectFieldUndo::doUndo() { - field->set_current_data(old_val); - done = false; - + field->set_current_data(old_val); + done = false; + } void EffectFieldUndo::doRedo() { - if (!done) { - field->set_current_data(new_val); - } + if (!done) { + field->set_current_data(new_val); + } } SetAutoscaleAction::SetAutoscaleAction() {} void SetAutoscaleAction::doUndo() { - for (int i=0;iautoscale = !clips.at(i)->autoscale; - } - panel_sequence_viewer->viewer_widget->frame_update(); - + for (int i=0;iautoscale = !clips.at(i)->autoscale; + } + panel_sequence_viewer->viewer_widget->frame_update(); + } void SetAutoscaleAction::doRedo() { - for (int i=0;iautoscale = !clips.at(i)->autoscale; - } - panel_sequence_viewer->viewer_widget->frame_update(); + for (int i=0;iautoscale = !clips.at(i)->autoscale; + } + panel_sequence_viewer->viewer_widget->frame_update(); } AddMarkerAction::AddMarkerAction(QVector* m, long t, QString n) { - active_array = m; - time = t; - name = n; + active_array = m; + time = t; + name = n; } void AddMarkerAction::doUndo() { - if (index == -1) { - active_array->removeLast(); - } else { - active_array[0][index].name = old_name; - } + if (index == -1) { + active_array->removeLast(); + } else { + active_array[0][index].name = old_name; + } } void AddMarkerAction::doRedo() { - index = -1; + index = -1; - for (int i=0;isize();i++) { - if (active_array->at(i).frame == time) { - index = i; - break; - } - } + for (int i=0;isize();i++) { + if (active_array->at(i).frame == time) { + index = i; + break; + } + } - if (index == -1) { - Marker m; - m.frame = time; - m.name = name; - active_array->append(m); - } else { - old_name = active_array->at(index).name; - active_array[0][index].name = name; - } + if (index == -1) { + Marker m; + m.frame = time; + m.name = name; + active_array->append(m); + } else { + old_name = active_array->at(index).name; + active_array[0][index].name = name; + } } MoveMarkerAction::MoveMarkerAction(Marker* m, long o, long n) { - marker = m; - old_time = o; - new_time = n; + marker = m; + old_time = o; + new_time = n; } void MoveMarkerAction::doUndo() { - marker->frame = old_time; - + marker->frame = old_time; + } void MoveMarkerAction::doRedo() { - marker->frame = new_time; + marker->frame = new_time; } DeleteMarkerAction::DeleteMarkerAction(QVector *m) { - active_array = m; - sorted = false; + active_array = m; + sorted = false; } void DeleteMarkerAction::doUndo() { - for (int i=markers.size()-1;i>=0;i--) { - active_array->insert(markers.at(i), copies.at(i)); - } - + for (int i=markers.size()-1;i>=0;i--) { + active_array->insert(markers.at(i), copies.at(i)); + } + } void DeleteMarkerAction::doRedo() { - for (int i=0;iat(markers.at(i))); - for (int j=i+1;j markers.at(i)) { - markers[j]--; - } - } - } - active_array->removeAt(markers.at(i)); - } - sorted = true; + for (int i=0;iat(markers.at(i))); + for (int j=i+1;j markers.at(i)) { + markers[j]--; + } + } + } + active_array->removeAt(markers.at(i)); + } + sorted = true; } SetSpeedAction::SetSpeedAction(ClipPtr c, double speed) { - clip = c; - old_speed = c->speed; - new_speed = speed; + clip = c; + old_speed = c->speed; + new_speed = speed; } void SetSpeedAction::doUndo() { - clip->speed = old_speed; - clip->recalculateMaxLength(); - + clip->speed = old_speed; + clip->recalculateMaxLength(); + } void SetSpeedAction::doRedo() { - clip->speed = new_speed; - clip->recalculateMaxLength(); + clip->speed = new_speed; + clip->recalculateMaxLength(); } SetBool::SetBool(bool* b, bool setting) { - boolean = b; - old_setting = *b; - new_setting = setting; + boolean = b; + old_setting = *b; + new_setting = setting; } void SetBool::doUndo() { - *boolean = old_setting; + *boolean = old_setting; } void SetBool::doRedo() { - *boolean = new_setting; + *boolean = new_setting; } SetSelectionsCommand::SetSelectionsCommand(SequencePtr s) { - seq = s; - done = true; + seq = s; + done = true; } void SetSelectionsCommand::doUndo() { - seq->selections = old_data; - done = false; + seq->selections = old_data; + done = false; } void SetSelectionsCommand::doRedo() { - if (!done) { - seq->selections = new_data; - done = true; - } + if (!done) { + seq->selections = new_data; + done = true; + } } EditSequenceCommand::EditSequenceCommand(Media* i, SequencePtr s) { - item = i; - seq = s; - old_name = s->name; - old_width = s->width; - old_height = s->height; - old_frame_rate = s->frame_rate; - old_audio_frequency = s->audio_frequency; - old_audio_layout = s->audio_layout; + item = i; + seq = s; + old_name = s->name; + old_width = s->width; + old_height = s->height; + old_frame_rate = s->frame_rate; + old_audio_frequency = s->audio_frequency; + old_audio_layout = s->audio_layout; } void EditSequenceCommand::doUndo() { - seq->name = old_name; - seq->width = old_width; - seq->height = old_height; - seq->frame_rate = old_frame_rate; - seq->audio_frequency = old_audio_frequency; - seq->audio_layout = old_audio_layout; - update(); + seq->name = old_name; + seq->width = old_width; + seq->height = old_height; + seq->frame_rate = old_frame_rate; + seq->audio_frequency = old_audio_frequency; + seq->audio_layout = old_audio_layout; + update(); } void EditSequenceCommand::doRedo() { - seq->name = name; - seq->width = width; - seq->height = height; - seq->frame_rate = frame_rate; - seq->audio_frequency = audio_frequency; - seq->audio_layout = audio_layout; - update(); + seq->name = name; + seq->width = width; + seq->height = height; + seq->frame_rate = frame_rate; + seq->audio_frequency = audio_frequency; + seq->audio_layout = audio_layout; + update(); } void EditSequenceCommand::update() { - // update tooltip - item->set_sequence(seq); + // update tooltip + item->set_sequence(seq); - for (int i=0;iclips.size();i++) { - if (seq->clips.at(i) != nullptr) seq->clips.at(i)->refresh(); - } + for (int i=0;iclips.size();i++) { + if (seq->clips.at(i) != nullptr) seq->clips.at(i)->refresh(); + } - if (olive::ActiveSequence == seq) { - set_sequence(seq); - } + if (olive::ActiveSequence == seq) { + set_sequence(seq); + } } SetInt::SetInt(int* pointer, int new_value) { - p = pointer; - oldval = *pointer; - newval = new_value; + p = pointer; + oldval = *pointer; + newval = new_value; } void SetInt::doUndo() { - *p = oldval; - + *p = oldval; + } void SetInt::doRedo() { - *p = newval; + *p = newval; } SetString::SetString(QString* pointer, QString new_value) { - p = pointer; - oldval = *pointer; - newval = new_value; + p = pointer; + oldval = *pointer; + newval = new_value; } void SetString::doUndo() { - *p = oldval; - + *p = oldval; + } void SetString::doRedo() { - *p = newval; + *p = newval; } void CloseAllClipsCommand::doUndo() { - redo(); + redo(); } void CloseAllClipsCommand::doRedo() { - closeActiveClips(olive::ActiveSequence); + closeActiveClips(olive::ActiveSequence); } UpdateFootageTooltip::UpdateFootageTooltip(Media *i) { - item = i; + item = i; } void UpdateFootageTooltip::doUndo() { - redo(); + redo(); } void UpdateFootageTooltip::doRedo() { - item->update_tooltip(); + item->update_tooltip(); } MoveEffectCommand::MoveEffectCommand() {} void MoveEffectCommand::doUndo() { - clip->effects.move(to, from); - + clip->effects.move(to, from); + } void MoveEffectCommand::doRedo() { - clip->effects.move(from, to); + clip->effects.move(from, to); } RemoveClipsFromClipboard::RemoveClipsFromClipboard(int index) { - pos = index; - done = false; + pos = index; + done = false; } RemoveClipsFromClipboard::~RemoveClipsFromClipboard() {} void RemoveClipsFromClipboard::doUndo() { - clipboard.insert(pos, clip); - done = false; + clipboard.insert(pos, clip); + done = false; } void RemoveClipsFromClipboard::doRedo() { - clip = std::static_pointer_cast(clipboard.at(pos)); - clipboard.removeAt(pos); - done = true; + clip = std::static_pointer_cast(clipboard.at(pos)); + clipboard.removeAt(pos); + done = true; } RenameClipCommand::RenameClipCommand() {} void RenameClipCommand::doUndo() { - for (int i=0;iname = old_names.at(i); - } + for (int i=0;iname = old_names.at(i); + } } void RenameClipCommand::doRedo() { - old_names.resize(clips.size()); - for (int i=0;iname; - clips.at(i)->name = new_name; - } + old_names.resize(clips.size()); + for (int i=0;iname; + clips.at(i)->name = new_name; + } } SetPointer::SetPointer(void **pointer, void *data) { - p = pointer; - new_data = data; + p = pointer; + new_data = data; } void SetPointer::doUndo() { - *p = old_data; + *p = old_data; } void SetPointer::doRedo() { - old_data = *p; - *p = new_data; + old_data = *p; + *p = new_data; } void ReloadEffectsCommand::doUndo() { - redo(); + redo(); } void ReloadEffectsCommand::doRedo() { - panel_effect_controls->reload_clips(); + panel_effect_controls->reload_clips(); } RippleAction::RippleAction(SequencePtr is, long ipoint, long ilength, const QVector &iignore) { - s = is; - point = ipoint; - length = ilength; - ignore = iignore; + s = is; + point = ipoint; + length = ilength; + ignore = iignore; } void RippleAction::doUndo() { - ca->undo(); - delete ca; + ca->undo(); + delete ca; } void RippleAction::doRedo() { - ca = new ComboAction(); - for (int i=0;iclips.size();i++) { - if (!ignore.contains(i)) { - ClipPtr c = s->clips.at(i); - if (c != nullptr) { - if (c->timeline_in >= point) { - move_clip(ca, c, length, length, 0, 0, true, true); - } - } - } - } - ca->redo(); + ca = new ComboAction(); + for (int i=0;iclips.size();i++) { + if (!ignore.contains(i)) { + ClipPtr c = s->clips.at(i); + if (c != nullptr) { + if (c->timeline_in >= point) { + move_clip(ca, c, length, length, 0, 0, true, true); + } + } + } + } + ca->redo(); } SetDouble::SetDouble(double* pointer, double old_value, double new_value) { - p = pointer; - oldval = old_value; - newval = new_value; + p = pointer; + oldval = old_value; + newval = new_value; } void SetDouble::doUndo() { - *p = oldval; - + *p = oldval; + } void SetDouble::doRedo() { - *p = newval; + *p = newval; } SetQVariant::SetQVariant(QVariant *itarget, const QVariant &iold, const QVariant &inew) { - target = itarget; - old_val = iold; - new_val = inew; + target = itarget; + old_val = iold; + new_val = inew; } void SetQVariant::doUndo() { - *target = old_val; + *target = old_val; } void SetQVariant::doRedo() { - *target = new_val; + *target = new_val; } SetLong::SetLong(long *pointer, long old_value, long new_value) { - p = pointer; - oldval = old_value; - newval = new_value; + p = pointer; + oldval = old_value; + newval = new_value; } void SetLong::doUndo() { - *p = oldval; - + *p = oldval; + } void SetLong::doRedo() { - *p = newval; + *p = newval; } KeyframeFieldSet::KeyframeFieldSet(EffectField *ifield, int ii) { - field = ifield; - index = ii; - key = ifield->keyframes.at(ii); - done = true; + field = ifield; + index = ii; + key = ifield->keyframes.at(ii); + done = true; } void KeyframeFieldSet::doUndo() { - field->keyframes.removeAt(index); - - done = false; + field->keyframes.removeAt(index); + + done = false; } void KeyframeFieldSet::doRedo() { - if (!done) { - field->keyframes.insert(index, key); - } - done = true; + if (!done) { + field->keyframes.insert(index, key); + } + done = true; } SetKeyframing::SetKeyframing(EffectRow *irow, bool ib) { - row = irow; - b = ib; + row = irow; + b = ib; } void SetKeyframing::doUndo() { - row->setKeyframing(!b); + row->setKeyframing(!b); } void SetKeyframing::doRedo() { - row->setKeyframing(b); + row->setKeyframing(b); } RefreshClips::RefreshClips(Media *m) { - media = m; + media = m; } void RefreshClips::doUndo() { - redo(); + redo(); } void RefreshClips::doRedo() { - // close any clips currently using this media - QVector all_sequences = panel_project->list_all_project_sequences(); - for (int i=0;ito_sequence(); - for (int j=0;jclips.size();j++) { - ClipPtr c = s->clips.at(j); - if (c != nullptr && c->media == media) { - c->replaced = true; - c->refresh(); - } - } - } + // close any clips currently using this media + QVector all_sequences = panel_project->list_all_project_sequences(); + for (int i=0;ito_sequence(); + for (int j=0;jclips.size();j++) { + ClipPtr c = s->clips.at(j); + if (c != nullptr && c->media == media) { + c->replaced = true; + c->refresh(); + } + } + } } void UpdateViewer::doUndo() { - redo(); + redo(); } void UpdateViewer::doRedo() { - panel_sequence_viewer->viewer_widget->frame_update(); + panel_sequence_viewer->viewer_widget->frame_update(); } SetEffectData::SetEffectData(EffectPtr e, const QByteArray &s) { - effect = e; - data = s; + effect = e; + data = s; } void SetEffectData::doUndo() { - effect->load_from_string(old_data); + effect->load_from_string(old_data); - old_data.clear(); + old_data.clear(); } void SetEffectData::doRedo() { - old_data = effect->save_to_string(); + old_data = effect->save_to_string(); - effect->load_from_string(data); + effect->load_from_string(data); } OliveAction::OliveAction(bool iset_window_modified) { - set_window_modified = iset_window_modified; + set_window_modified = iset_window_modified; } OliveAction::~OliveAction() {} void OliveAction::undo() { - doUndo(); + doUndo(); - if (set_window_modified) { - olive::MainWindow->setWindowModified(old_window_modified); - } + if (set_window_modified) { + olive::MainWindow->setWindowModified(old_window_modified); + } } void OliveAction::redo() { - doRedo(); + doRedo(); - if (set_window_modified) { + if (set_window_modified) { - // store current modified state - old_window_modified = olive::MainWindow->isWindowModified(); + // store current modified state + old_window_modified = olive::MainWindow->isWindowModified(); - // set modified to true - olive::MainWindow->setWindowModified(true); + // set modified to true + olive::MainWindow->setWindowModified(true); - } + } } diff --git a/project/undo.h b/project/undo.h index 09d07dbad..830a9973f 100644 --- a/project/undo.h +++ b/project/undo.h @@ -36,594 +36,590 @@ #include namespace olive { - extern QUndoStack UndoStack; +extern QUndoStack UndoStack; } class OliveAction : public QUndoCommand { public: - OliveAction(bool iset_window_modified = true); - virtual ~OliveAction() override; + OliveAction(bool iset_window_modified = true); + virtual ~OliveAction() override; - virtual void undo() override; - virtual void redo() override; + virtual void undo() override; + virtual void redo() override; - virtual void doUndo() = 0; - virtual void doRedo() = 0; + virtual void doUndo() = 0; + virtual void doRedo() = 0; private: - /** + /** * @brief Setting whether to change the windowModified state of MainWindow */ - bool set_window_modified; + bool set_window_modified; - /** + /** * @brief Cache previous window modified value to return to if the user undoes this action */ - bool old_window_modified; + bool old_window_modified; }; class MoveClipAction : public OliveAction { public: - MoveClipAction(ClipPtr c, long iin, long iout, long iclip_in, int itrack, bool irelative); - virtual void doUndo() override; - virtual void doRedo() override; + MoveClipAction(ClipPtr c, long iin, long iout, long iclip_in, int itrack, bool irelative); + virtual void doUndo() override; + virtual void doRedo() override; private: - ClipPtr clip; + ClipPtr clip; - long old_in; - long old_out; - long old_clip_in; - int old_track; + long old_in; + long old_out; + long old_clip_in; + int old_track; - long new_in; - long new_out; - long new_clip_in; - int new_track; + long new_in; + long new_out; + long new_clip_in; + int new_track; - bool relative; + bool relative; }; class RippleAction : public OliveAction { public: - RippleAction(SequencePtr is, long ipoint, long ilength, const QVector& iignore); - virtual void doUndo() override; - virtual void doRedo() override; + RippleAction(SequencePtr is, long ipoint, long ilength, const QVector& iignore); + virtual void doUndo() override; + virtual void doRedo() override; private: - SequencePtr s; - long point; - long length; - QVector ignore; - ComboAction* ca; + SequencePtr s; + long point; + long length; + QVector ignore; + ComboAction* ca; }; class DeleteClipAction : public OliveAction { public: - DeleteClipAction(SequencePtr s, int clip); - virtual ~DeleteClipAction() override; - virtual void doUndo() override; - virtual void doRedo() override; + DeleteClipAction(SequencePtr s, int clip); + virtual ~DeleteClipAction() override; + virtual void doUndo() override; + virtual void doRedo() override; private: - SequencePtr seq; - ClipPtr ref; - int index; + SequencePtr seq; + ClipPtr ref; + int index; - int opening_transition; - int closing_transition; + int opening_transition; + int closing_transition; - QVector linkClipIndex; - QVector linkLinkIndex; + QVector linkClipIndex; + QVector linkLinkIndex; }; class ChangeSequenceAction : public OliveAction { public: - ChangeSequenceAction(SequencePtr s); - virtual void doUndo() override; - virtual void doRedo() override; + ChangeSequenceAction(SequencePtr s); + virtual void doUndo() override; + virtual void doRedo() override; private: - SequencePtr old_sequence; - SequencePtr new_sequence; + SequencePtr old_sequence; + SequencePtr new_sequence; }; class AddEffectCommand : public OliveAction { public: - AddEffectCommand(ClipPtr c, EffectPtr e, const EffectMeta* m, int insert_pos = -1); - virtual void doUndo() override; - virtual void doRedo() override; + AddEffectCommand(ClipPtr c, EffectPtr e, const EffectMeta* m, int insert_pos = -1); + virtual void doUndo() override; + virtual void doRedo() override; private: - ClipPtr clip; - const EffectMeta* meta; - EffectPtr ref; - int pos; - bool done; + ClipPtr clip; + const EffectMeta* meta; + EffectPtr ref; + int pos; + bool done; }; class AddTransitionCommand : public OliveAction { public: - AddTransitionCommand(ClipPtr c, ClipPtr s, TransitionPtr copy, const EffectMeta* itransition, int itype, int ilength); - virtual void doUndo() override; - virtual void doRedo() override; + AddTransitionCommand(ClipPtr c, ClipPtr s, TransitionPtr copy, const EffectMeta* itransition, int itype, int ilength); + virtual void doUndo() override; + virtual void doRedo() override; private: - ClipPtr clip; - ClipPtr secondary; - TransitionPtr transition_to_copy; - const EffectMeta* transition; - int type; - int length; - int old_ptransition; - int old_stransition; + ClipPtr primary; + ClipPtr secondary; + TransitionPtr transition_to_copy; + const EffectMeta* transition_meta_; + int type; + int length; + TransitionPtr old_ptransition; + TransitionPtr old_stransition; }; class ModifyTransitionCommand : public OliveAction { public: - ModifyTransitionCommand(ClipPtr c, int itype, long ilength); - virtual void doUndo() override; - virtual void doRedo() override; + ModifyTransitionCommand(TransitionPtr t, long ilength); + virtual void doUndo() override; + virtual void doRedo() override; private: - ClipPtr clip; - int type; - long new_length; - long old_length; + TransitionPtr transition_ref_; + long new_length_; + long old_length_; }; class DeleteTransitionCommand : public OliveAction { public: - DeleteTransitionCommand(SequencePtr s, int transition_index); - virtual ~DeleteTransitionCommand() override; - virtual void doUndo() override; - virtual void doRedo() override; + DeleteTransitionCommand(TransitionPtr t); + virtual void doUndo() override; + virtual void doRedo() override; private: - SequencePtr seq; - int index; - TransitionPtr transition; - ClipPtr otc; - ClipPtr ctc; + TransitionPtr transition_ref_; + ClipPtr opened_clip_; + ClipPtr closed_clip_; }; class SetTimelineInOutCommand : public OliveAction { public: - SetTimelineInOutCommand(SequencePtr s, bool enabled, long in, long out); - virtual void doUndo() override; - virtual void doRedo() override; + SetTimelineInOutCommand(SequencePtr s, bool enabled, long in, long out); + virtual void doUndo() override; + virtual void doRedo() override; private: - SequencePtr seq; + SequencePtr seq; - bool old_enabled; - long old_in; - long old_out; + bool old_enabled; + long old_in; + long old_out; - bool new_enabled; - long new_in; - long new_out; + bool new_enabled; + long new_in; + long new_out; }; class NewSequenceCommand : public OliveAction { public: - NewSequenceCommand(Media* s, Media* iparent); - virtual ~NewSequenceCommand() override; - virtual void doUndo() override; - virtual void doRedo() override; + NewSequenceCommand(Media* s, Media* iparent); + virtual ~NewSequenceCommand() override; + virtual void doUndo() override; + virtual void doRedo() override; private: - Media* seq; - Media* parent; - bool done; + Media* seq; + Media* parent; + bool done; }; class AddMediaCommand : public OliveAction { public: - AddMediaCommand(Media* iitem, Media* iparent); - virtual ~AddMediaCommand() override; - virtual void doUndo() override; - virtual void doRedo() override; + AddMediaCommand(Media* iitem, Media* iparent); + virtual ~AddMediaCommand() override; + virtual void doUndo() override; + virtual void doRedo() override; private: - Media* item; - Media* parent; - bool done; + Media* item; + Media* parent; + bool done; }; class DeleteMediaCommand : public OliveAction { public: - DeleteMediaCommand(Media *i); - virtual ~DeleteMediaCommand() override; - virtual void doUndo() override; - virtual void doRedo() override; + DeleteMediaCommand(Media *i); + virtual ~DeleteMediaCommand() override; + virtual void doUndo() override; + virtual void doRedo() override; private: - Media* item; - Media* parent; - bool done; + Media* item; + Media* parent; + bool done; }; class AddClipCommand : public OliveAction { public: - AddClipCommand(SequencePtr s, QVector& add); - virtual ~AddClipCommand() override; - virtual void doUndo() override; - virtual void doRedo() override; + AddClipCommand(SequencePtr s, QVector& add); + virtual ~AddClipCommand() override; + virtual void doUndo() override; + virtual void doRedo() override; private: - SequencePtr seq; - QVector clips; - QVector undone_clips; + SequencePtr seq; + QVector clips; + QVector undone_clips; }; class LinkCommand : public OliveAction { public: - LinkCommand(); - virtual void doUndo() override; - virtual void doRedo() override; - SequencePtr s; - QVector clips; - bool link; + LinkCommand(); + virtual void doUndo() override; + virtual void doRedo() override; + SequencePtr s; + QVector clips; + bool link; private: - QVector< QVector > old_links; + QVector< QVector > old_links; }; class CheckboxCommand : public OliveAction { public: - CheckboxCommand(QCheckBox* b); - virtual ~CheckboxCommand() override; - virtual void doUndo() override; - virtual void doRedo() override; + CheckboxCommand(QCheckBox* b); + virtual ~CheckboxCommand() override; + virtual void doUndo() override; + virtual void doRedo() override; private: - QCheckBox* box; - bool checked; - bool done; + QCheckBox* box; + bool checked; + bool done; }; class ReplaceMediaCommand : public OliveAction { public: - ReplaceMediaCommand(Media*, QString); - virtual void doUndo() override; - virtual void doRedo() override; + ReplaceMediaCommand(Media*, QString); + virtual void doUndo() override; + virtual void doRedo() override; private: - Media *item; - QString old_filename; - QString new_filename; - void replace(QString& filename); + Media *item; + QString old_filename; + QString new_filename; + void replace(QString& filename); }; class ReplaceClipMediaCommand : public OliveAction { public: - ReplaceClipMediaCommand(Media *, Media *, bool); - virtual void doUndo() override; - virtual void doRedo() override; - QVector clips; + ReplaceClipMediaCommand(Media *, Media *, bool); + virtual void doUndo() override; + virtual void doRedo() override; + QVector clips; private: - Media* old_media; - Media* new_media; - bool preserve_clip_ins; - QVector old_clip_ins; - void replace(bool undo); + Media* old_media; + Media* new_media; + bool preserve_clip_ins; + QVector old_clip_ins; + void replace(bool undo); }; class EffectDeleteCommand : public OliveAction { public: - EffectDeleteCommand(); - virtual ~EffectDeleteCommand() override; - virtual void doUndo() override; - virtual void doRedo() override; - QVector clips; - QVector fx; + EffectDeleteCommand(); + virtual ~EffectDeleteCommand() override; + virtual void doUndo() override; + virtual void doRedo() override; + QVector clips; + QVector fx; private: - bool done; - QVector deleted_objects; + bool done; + QVector deleted_objects; }; class MediaMove : public OliveAction { public: - MediaMove(); - QVector items; - Media* to; - virtual void doUndo() override; - virtual void doRedo() override; + MediaMove(); + QVector items; + Media* to; + virtual void doUndo() override; + virtual void doRedo() override; private: - QVector froms; + QVector froms; }; class MediaRename : public OliveAction { public: - MediaRename(Media* iitem, QString to); - virtual void doUndo() override; - virtual void doRedo() override; + MediaRename(Media* iitem, QString to); + virtual void doUndo() override; + virtual void doRedo() override; private: - Media* item; - QString from; - QString to; + Media* item; + QString from; + QString to; }; class KeyframeDelete : public OliveAction { public: - KeyframeDelete(EffectField* ifield, int iindex); - virtual void doUndo() override; - virtual void doRedo() override; + KeyframeDelete(EffectField* ifield, int iindex); + virtual void doUndo() override; + virtual void doRedo() override; private: - EffectField* field; - int index; - bool done; - EffectKeyframe deleted_key; + EffectField* field; + int index; + bool done; + EffectKeyframe deleted_key; }; // a more modern version of the above, could probably replace it // assumes the keyframe already exists class KeyframeFieldSet : public OliveAction { public: - KeyframeFieldSet(EffectField* ifield, int ii); - virtual void doUndo() override; - virtual void doRedo() override; + KeyframeFieldSet(EffectField* ifield, int ii); + virtual void doUndo() override; + virtual void doRedo() override; private: - EffectField* field; - int index; - EffectKeyframe key; - bool done; + EffectField* field; + int index; + EffectKeyframe key; + bool done; }; class EffectFieldUndo : public OliveAction { public: - EffectFieldUndo(EffectField* field); - virtual void doUndo() override; - virtual void doRedo() override; + EffectFieldUndo(EffectField* field); + virtual void doUndo() override; + virtual void doRedo() override; private: - EffectField* field; - QVariant old_val; - QVariant new_val; - bool done; + EffectField* field; + QVariant old_val; + QVariant new_val; + bool done; }; class SetAutoscaleAction : public OliveAction { public: - SetAutoscaleAction(); - virtual void doUndo() override; - virtual void doRedo() override; - QVector clips; + SetAutoscaleAction(); + virtual void doUndo() override; + virtual void doRedo() override; + QVector clips; }; class AddMarkerAction : public OliveAction { public: - AddMarkerAction(QVector* m, long t, QString n); - virtual void doUndo() override; - virtual void doRedo() override; + AddMarkerAction(QVector* m, long t, QString n); + virtual void doUndo() override; + virtual void doRedo() override; private: - QVector* active_array; - long time; - QString name; - QString old_name; - int index; + QVector* active_array; + long time; + QString name; + QString old_name; + int index; }; class MoveMarkerAction : public OliveAction { public: - MoveMarkerAction(Marker* m, long o, long n); - virtual void doUndo() override; - virtual void doRedo() override; + MoveMarkerAction(Marker* m, long o, long n); + virtual void doUndo() override; + virtual void doRedo() override; private: - Marker* marker; - long old_time; - long new_time; + Marker* marker; + long old_time; + long new_time; }; class DeleteMarkerAction : public OliveAction { public: - DeleteMarkerAction(QVector* m); - virtual void doUndo() override; - virtual void doRedo() override; - QVector markers; + DeleteMarkerAction(QVector* m); + virtual void doUndo() override; + virtual void doRedo() override; + QVector markers; private: - QVector* active_array; - QVector copies; - bool sorted; + QVector* active_array; + QVector copies; + bool sorted; }; class SetSpeedAction : public OliveAction { public: - SetSpeedAction(ClipPtr c, double speed); - virtual void doUndo() override; - virtual void doRedo() override; + SetSpeedAction(ClipPtr c, double speed); + virtual void doUndo() override; + virtual void doRedo() override; private: - ClipPtr clip; - double old_speed; - double new_speed; + ClipPtr clip; + double old_speed; + double new_speed; }; class SetBool : public OliveAction { public: - SetBool(bool* b, bool setting); - virtual void doUndo() override; - virtual void doRedo() override; + SetBool(bool* b, bool setting); + virtual void doUndo() override; + virtual void doRedo() override; private: - bool* boolean; - bool old_setting; - bool new_setting; + bool* boolean; + bool old_setting; + bool new_setting; }; class SetSelectionsCommand : public OliveAction { public: - SetSelectionsCommand(SequencePtr s); - virtual void doUndo() override; - virtual void doRedo() override; - QVector old_data; - QVector new_data; + SetSelectionsCommand(SequencePtr s); + virtual void doUndo() override; + virtual void doRedo() override; + QVector old_data; + QVector new_data; private: - SequencePtr seq; - bool done; + SequencePtr seq; + bool done; }; class EditSequenceCommand : public OliveAction { public: - EditSequenceCommand(Media *i, SequencePtr s); - virtual void doUndo() override; - virtual void doRedo() override; - void update(); + EditSequenceCommand(Media *i, SequencePtr s); + virtual void doUndo() override; + virtual void doRedo() override; + void update(); - QString name; - int width; - int height; - double frame_rate; - int audio_frequency; - int audio_layout; + QString name; + int width; + int height; + double frame_rate; + int audio_frequency; + int audio_layout; private: - Media* item; - SequencePtr seq; + Media* item; + SequencePtr seq; - QString old_name; - int old_width; - int old_height; - double old_frame_rate; - int old_audio_frequency; - int old_audio_layout; + QString old_name; + int old_width; + int old_height; + double old_frame_rate; + int old_audio_frequency; + int old_audio_layout; }; class SetInt : public OliveAction { public: - SetInt(int* pointer, int new_value); - virtual void doUndo() override; - virtual void doRedo() override; + SetInt(int* pointer, int new_value); + virtual void doUndo() override; + virtual void doRedo() override; private: - int* p; - int oldval; - int newval; + int* p; + int oldval; + int newval; }; class SetLong : public OliveAction { public: - SetLong(long* pointer, long old_value, long new_value); - virtual void doUndo() override; - virtual void doRedo() override; + SetLong(long* pointer, long old_value, long new_value); + virtual void doUndo() override; + virtual void doRedo() override; private: - long* p; - long oldval; - long newval; + long* p; + long oldval; + long newval; }; class SetDouble : public OliveAction { public: - SetDouble(double* pointer, double old_value, double new_value); - virtual void doUndo() override; - virtual void doRedo() override; + SetDouble(double* pointer, double old_value, double new_value); + virtual void doUndo() override; + virtual void doRedo() override; private: - double* p; - double oldval; - double newval; + double* p; + double oldval; + double newval; }; class SetString : public OliveAction { public: - SetString(QString* pointer, QString new_value); - virtual void doUndo() override; - virtual void doRedo() override; + SetString(QString* pointer, QString new_value); + virtual void doUndo() override; + virtual void doRedo() override; private: - QString* p; - QString oldval; - QString newval; + QString* p; + QString oldval; + QString newval; }; class CloseAllClipsCommand : public OliveAction { public: - virtual void doUndo() override; - virtual void doRedo() override; + virtual void doUndo() override; + virtual void doRedo() override; }; class UpdateFootageTooltip : public OliveAction { public: - UpdateFootageTooltip(Media* i); - virtual void doUndo() override; - virtual void doRedo() override; + UpdateFootageTooltip(Media* i); + virtual void doUndo() override; + virtual void doRedo() override; private: - Media* item; + Media* item; }; class MoveEffectCommand : public OliveAction { public: - MoveEffectCommand(); - virtual void doUndo() override; - virtual void doRedo() override; - ClipPtr clip; - int from; - int to; + MoveEffectCommand(); + virtual void doUndo() override; + virtual void doRedo() override; + ClipPtr clip; + int from; + int to; }; class RemoveClipsFromClipboard : public OliveAction { public: - RemoveClipsFromClipboard(int index); - virtual ~RemoveClipsFromClipboard() override; - virtual void doUndo() override; - virtual void doRedo() override; + RemoveClipsFromClipboard(int index); + virtual ~RemoveClipsFromClipboard() override; + virtual void doUndo() override; + virtual void doRedo() override; private: - int pos; - ClipPtr clip; - bool done; + int pos; + ClipPtr clip; + bool done; }; class RenameClipCommand : public OliveAction { public: - RenameClipCommand(); - QVector clips; - QString new_name; - virtual void doUndo() override; - virtual void doRedo() override; + RenameClipCommand(); + QVector clips; + QString new_name; + virtual void doUndo() override; + virtual void doRedo() override; private: - QVector old_names; + QVector old_names; }; class SetPointer : public OliveAction { public: - SetPointer(void** pointer, void* data); - virtual void doUndo() override; - virtual void doRedo() override; + SetPointer(void** pointer, void* data); + virtual void doUndo() override; + virtual void doRedo() override; private: - bool old_changed; - void** p; - void* new_data; - void* old_data; + bool old_changed; + void** p; + void* new_data; + void* old_data; }; class ReloadEffectsCommand : public OliveAction { public: - virtual void doUndo() override; - virtual void doRedo() override; + virtual void doUndo() override; + virtual void doRedo() override; }; class SetQVariant : public OliveAction { public: - SetQVariant(QVariant* itarget, const QVariant& iold, const QVariant& inew); - virtual void doUndo() override; - virtual void doRedo() override; + SetQVariant(QVariant* itarget, const QVariant& iold, const QVariant& inew); + virtual void doUndo() override; + virtual void doRedo() override; private: - QVariant* target; - QVariant old_val; - QVariant new_val; + QVariant* target; + QVariant old_val; + QVariant new_val; }; class SetKeyframing : public OliveAction { public: - SetKeyframing(EffectRow* irow, bool ib); - virtual void doUndo() override; - virtual void doRedo() override; + SetKeyframing(EffectRow* irow, bool ib); + virtual void doUndo() override; + virtual void doRedo() override; private: - EffectRow* row; - bool b; + EffectRow* row; + bool b; }; class RefreshClips : public OliveAction { public: - RefreshClips(Media* m); - virtual void doUndo() override; - virtual void doRedo() override; + RefreshClips(Media* m); + virtual void doUndo() override; + virtual void doRedo() override; private: - Media* media; + Media* media; }; class UpdateViewer : public OliveAction { public: - virtual void doUndo() override; - virtual void doRedo() override; + virtual void doUndo() override; + virtual void doRedo() override; }; class SetEffectData : public OliveAction { public: - SetEffectData(EffectPtr e, const QByteArray &s); - virtual void doUndo() override; - virtual void doRedo() override; + SetEffectData(EffectPtr e, const QByteArray &s); + virtual void doUndo() override; + virtual void doRedo() override; private: - EffectPtr effect; - QByteArray data; - QByteArray old_data; + EffectPtr effect; + QByteArray data; + QByteArray old_data; }; #endif // UNDO_H diff --git a/ui/renderfunctions.cpp b/ui/renderfunctions.cpp index f00cc915e..d1c732f2a 100644 --- a/ui/renderfunctions.cpp +++ b/ui/renderfunctions.cpp @@ -401,7 +401,7 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { // run through all of the clip's effects for (int j=0;jeffects.size();j++) { EffectPtr e = c->effects.at(j); - process_effect(c, e, timecode, coords, textureID, fbo_switcher, params.texture_failed, TA_NO_TRANSITION); + process_effect(c, e, timecode, coords, textureID, fbo_switcher, params.texture_failed, kTransitionNone); // retrieve gizmo data from effect if (e->are_gizmos_enabled()) { @@ -421,7 +421,7 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { if (c->get_opening_transition() != nullptr) { int transition_progress = playhead - c->get_timeline_in_with_transition(); if (transition_progress < c->get_opening_transition()->get_length()) { - process_effect(c, c->get_opening_transition(), double(transition_progress)/double(c->get_opening_transition()->get_length()), coords, textureID, fbo_switcher, params.texture_failed, TA_OPENING_TRANSITION); + process_effect(c, c->get_opening_transition(), double(transition_progress)/double(c->get_opening_transition()->get_length()), coords, textureID, fbo_switcher, params.texture_failed, kTransitionOpening); } } @@ -429,7 +429,7 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { if (c->get_closing_transition() != nullptr) { int transition_progress = playhead - (c->get_timeline_out_with_transition() - c->get_closing_transition()->get_length()); if (transition_progress >= 0 && transition_progress < c->get_closing_transition()->get_length()) { - process_effect(c, c->get_closing_transition(), double(transition_progress)/double(c->get_closing_transition()->get_length()), coords, textureID, fbo_switcher, params.texture_failed, TA_CLOSING_TRANSITION); + process_effect(c, c->get_closing_transition(), double(transition_progress)/double(c->get_closing_transition()->get_length()), coords, textureID, fbo_switcher, params.texture_failed, kTransitionClosing); } } diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index 1d8afcbac..bf3a48987 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -656,7 +656,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track); } } - } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER && panel_timeline->transition_select != TA_NO_TRANSITION) { + } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER && panel_timeline->transition_select != kTransitionNone) { panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track); for (int i=0;ilinked.size();i++) { @@ -667,11 +667,11 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { Selection s; s.track = clip->track; - if (panel_timeline->transition_select == TA_OPENING_TRANSITION && clip->get_opening_transition() != nullptr) { + if (panel_timeline->transition_select == kTransitionOpening && clip->get_opening_transition() != nullptr) { s.in = clip->timeline_in; if (clip->get_opening_transition()->secondary_clip != nullptr) s.in -= clip->get_opening_transition()->get_true_length(); s.out = clip->timeline_in + clip->get_opening_transition()->get_true_length(); - } else if (panel_timeline->transition_select == TA_CLOSING_TRANSITION && clip->get_closing_transition() != nullptr) { + } else if (panel_timeline->transition_select == kTransitionClosing && clip->get_closing_transition() != nullptr) { s.in = clip->timeline_out - clip->get_closing_transition()->get_true_length(); s.out = clip->timeline_out; if (clip->get_closing_transition()->secondary_clip != nullptr) s.out += clip->get_closing_transition()->get_true_length(); @@ -690,12 +690,12 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { s.out = clip->timeline_out; if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { - if (panel_timeline->transition_select == TA_OPENING_TRANSITION) { + if (panel_timeline->transition_select == kTransitionOpening) { s.out = clip->timeline_in + clip->get_opening_transition()->get_true_length(); if (clip->get_opening_transition()->secondary_clip != nullptr) s.in -= clip->get_opening_transition()->get_true_length(); } - if (panel_timeline->transition_select == TA_CLOSING_TRANSITION) { + if (panel_timeline->transition_select == kTransitionClosing) { s.in = clip->timeline_out - clip->get_closing_transition()->get_true_length(); if (clip->get_closing_transition()->secondary_clip != nullptr) s.out += clip->get_closing_transition()->get_true_length(); } @@ -709,7 +709,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { } // if alt is not down, select links - if (!alt && panel_timeline->transition_select == TA_NO_TRANSITION) { + if (!alt && panel_timeline->transition_select == kTransitionNone) { for (int i=0;ilinked.size();i++) { ClipPtr link = olive::ActiveSequence->clips.at(clip->linked.at(i)); if (!is_clip_selected(link, true)) { @@ -767,26 +767,26 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { void make_room_for_transition(ComboAction* ca, ClipPtr c, int type, long transition_start, long transition_end, bool delete_old_transitions) { // make room for transition - if (type == TA_OPENING_TRANSITION) { + if (type == kTransitionOpening) { if (delete_old_transitions && c->get_opening_transition() != nullptr) { - ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); + ca->append(new DeleteTransitionCommand(c->opening_transition)); } if (c->get_closing_transition() != nullptr) { if (transition_end >= c->timeline_out) { - ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); + ca->append(new DeleteTransitionCommand(c->closing_transition)); } else if (transition_end > c->timeline_out - c->get_closing_transition()->get_true_length()) { - ca->append(new ModifyTransitionCommand(c, TA_CLOSING_TRANSITION, c->timeline_out - transition_end)); + ca->append(new ModifyTransitionCommand(c->closing_transition, c->timeline_out - transition_end)); } } } else { if (delete_old_transitions && c->get_closing_transition() != nullptr) { - ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); + ca->append(new DeleteTransitionCommand(c->closing_transition)); } if (c->get_opening_transition() != nullptr) { if (transition_start <= c->timeline_in) { - ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); + ca->append(new DeleteTransitionCommand(c->opening_transition)); } else if (transition_start < c->timeline_in + c->get_opening_transition()->get_true_length()) { - ca->append(new ModifyTransitionCommand(c, TA_OPENING_TRANSITION, transition_start - c->timeline_in)); + ca->append(new ModifyTransitionCommand(c->opening_transition, transition_start - c->timeline_in)); } } } @@ -1022,9 +1022,9 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { max_open_length -= c->get_closing_transition()->get_true_length(); } if (max_open_length <= 0) { - ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); + ca->append(new DeleteTransitionCommand(c->opening_transition)); } else if (c->get_opening_transition()->get_true_length() > max_open_length) { - ca->append(new ModifyTransitionCommand(c, TA_OPENING_TRANSITION, max_open_length)); + ca->append(new ModifyTransitionCommand(c->opening_transition, max_open_length)); } } if (c->get_closing_transition() != nullptr) { @@ -1033,16 +1033,16 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { max_open_length -= c->get_opening_transition()->get_true_length(); } if (max_open_length <= 0) { - ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); + ca->append(new DeleteTransitionCommand(c->closing_transition)); } else if (c->get_closing_transition()->get_true_length() > max_open_length) { - ca->append(new ModifyTransitionCommand(c, TA_CLOSING_TRANSITION, max_open_length)); + ca->append(new ModifyTransitionCommand(c->closing_transition, max_open_length)); } } } else { bool is_opening_transition = (g.transition == c->get_opening_transition()); long new_transition_length = g.out - g.in; if (g.transition->secondary_clip != nullptr) new_transition_length >>= 1; - ca->append(new ModifyTransitionCommand(c, is_opening_transition ? TA_OPENING_TRANSITION : TA_CLOSING_TRANSITION, new_transition_length)); + ca->append(new ModifyTransitionCommand(is_opening_transition ? c->opening_transition : c->closing_transition, new_transition_length)); long clip_length = c->getLength(); @@ -1059,7 +1059,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { clip_length -= (g.in - g.old_in); } - make_room_for_transition(ca, c, TA_OPENING_TRANSITION, g.in, g.out, false); + make_room_for_transition(ca, c, kTransitionOpening, g.in, g.out, false); } else { if (g.out != g.old_out) { // if transition is going to make the clip bigger, make the clip bigger @@ -1067,7 +1067,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { clip_length += (g.out - g.old_out); } - make_room_for_transition(ca, c, TA_CLOSING_TRANSITION, g.in, g.out, false); + make_room_for_transition(ca, c, kTransitionClosing, g.in, g.out, false); } } } @@ -1089,7 +1089,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { if (panel_timeline->transition_tool_post_clip > -1) { post = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_post_clip); - int opposite_type = (panel_timeline->transition_tool_type == TA_OPENING_TRANSITION) ? TA_CLOSING_TRANSITION : TA_OPENING_TRANSITION; + int opposite_type = (panel_timeline->transition_tool_type == kTransitionOpening) ? kTransitionClosing : kTransitionOpening; make_room_for_transition( ca, post, @@ -1099,7 +1099,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { true ); - if (panel_timeline->transition_tool_type == TA_CLOSING_TRANSITION) { + if (panel_timeline->transition_tool_type == kTransitionClosing) { // swap ClipPtr temp = pre; pre = post; @@ -1136,7 +1136,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { } if (panel_timeline->transition_tool_post_clip > -1) { - ca->append(new AddTransitionCommand(pre, post, nullptr, panel_timeline->transition_tool_meta, TA_OPENING_TRANSITION, transition_end - pre->timeline_in)); + ca->append(new AddTransitionCommand(pre, post, nullptr, panel_timeline->transition_tool_meta, kTransitionOpening, transition_end - pre->timeline_in)); } else { ca->append(new AddTransitionCommand(pre, nullptr, nullptr, panel_timeline->transition_tool_meta, panel_timeline->transition_tool_type, transition_end - transition_start)); } @@ -1241,7 +1241,7 @@ void TimelineWidget::init_ghosts() { void validate_transitions(ClipPtr c, int transition_type, long& frame_diff) { long validator; - if (transition_type == TA_OPENING_TRANSITION) { + if (transition_type == kTransitionOpening) { // prevent from going below 0 on the timeline validator = c->timeline_in + frame_diff; if (validator < 0) frame_diff -= validator; @@ -1274,7 +1274,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { int mouse_track = getTrackFromScreenPoint(mouse_pos.y()); long frame_diff = (lock_frame) ? 0 : panel_timeline->getTimelineFrameFromScreenPoint(mouse_pos.x()) - panel_timeline->drag_frame_start; - int track_diff = ((effective_tool == TIMELINE_TOOL_SLIDE || panel_timeline->transition_select != TA_NO_TRANSITION) && !panel_timeline->importing) ? 0 : mouse_track - panel_timeline->drag_track_start; + int track_diff = ((effective_tool == TIMELINE_TOOL_SLIDE || panel_timeline->transition_select != kTransitionNone) && !panel_timeline->importing) ? 0 : mouse_track - panel_timeline->drag_track_start; long validator; long earliest_in_point = LONG_MAX; @@ -1389,12 +1389,12 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { frame_diff += g.transition->get_true_length(); } - validate_transitions(otc, TA_OPENING_TRANSITION, frame_diff); - validate_transitions(ctc, TA_CLOSING_TRANSITION, frame_diff); + validate_transitions(otc, kTransitionOpening, frame_diff); + validate_transitions(ctc, kTransitionClosing, frame_diff); frame_diff = -frame_diff; - validate_transitions(otc, TA_OPENING_TRANSITION, frame_diff); - validate_transitions(ctc, TA_CLOSING_TRANSITION, frame_diff); + validate_transitions(otc, kTransitionOpening, frame_diff); + validate_transitions(ctc, kTransitionClosing, frame_diff); frame_diff = -frame_diff; if (g.trim_in) { @@ -1484,7 +1484,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { ClipPtr otc = c; // open transition clip ClipPtr ctc = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_post_clip); // close transition clip - if (panel_timeline->transition_tool_type == TA_CLOSING_TRANSITION) { + if (panel_timeline->transition_tool_type == kTransitionClosing) { // swap ClipPtr temp = otc; otc = ctc; @@ -1492,13 +1492,13 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { } // always gets a positive frame_diff - validate_transitions(otc, TA_OPENING_TRANSITION, frame_diff); - validate_transitions(ctc, TA_CLOSING_TRANSITION, frame_diff); + validate_transitions(otc, kTransitionOpening, frame_diff); + validate_transitions(ctc, kTransitionClosing, frame_diff); // always gets a negative frame_diff frame_diff = -frame_diff; - validate_transitions(otc, TA_OPENING_TRANSITION, frame_diff); - validate_transitions(ctc, TA_CLOSING_TRANSITION, frame_diff); + validate_transitions(otc, kTransitionOpening, frame_diff); + validate_transitions(ctc, kTransitionClosing, frame_diff); frame_diff = -frame_diff; } } @@ -1566,7 +1566,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { if (panel_timeline->transition_tool_post_clip > -1) { g.in = g.old_in - frame_diff; g.out = g.old_out + frame_diff; - } else if (panel_timeline->transition_tool_type == TA_OPENING_TRANSITION) { + } else if (panel_timeline->transition_tool_type == kTransitionOpening) { g.out = g.old_out + frame_diff; } else { g.in = g.old_in + frame_diff; @@ -1750,11 +1750,11 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { for (int j=0;jselections.size();j++) { const Selection& s = olive::ActiveSequence->selections.at(j); if (s.track == c->track) { - if (selection_contains_transition(s, c, TA_OPENING_TRANSITION)) { + if (selection_contains_transition(s, c, kTransitionOpening)) { g.transition = c->get_opening_transition(); add = true; break; - } else if (selection_contains_transition(s, c, TA_CLOSING_TRANSITION)) { + } else if (selection_contains_transition(s, c, kTransitionClosing)) { g.transition = c->get_closing_transition(); add = true; break; @@ -2049,7 +2049,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { int max_track = INT_MIN; // we default to selecting no transition, but set this accordingly if the cursor is on a transition - panel_timeline->transition_select = TA_NO_TRANSITION; + panel_timeline->transition_select = kTransitionNone; // set currently trimming clip to -1 (aka null) panel_timeline->trim_target = -1; @@ -2081,12 +2081,12 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { if (c->get_opening_transition() != nullptr && panel_timeline->cursor_frame <= c->timeline_in + c->get_opening_transition()->get_true_length()) { - panel_timeline->transition_select = TA_OPENING_TRANSITION; + panel_timeline->transition_select = kTransitionOpening; } else if (c->get_closing_transition() != nullptr && panel_timeline->cursor_frame >= c->timeline_out - c->get_closing_transition()->get_true_length()) { - panel_timeline->transition_select = TA_CLOSING_TRANSITION; + panel_timeline->transition_select = kTransitionClosing; } } @@ -2145,7 +2145,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { if (nc < closeness) { panel_timeline->trim_target = i; panel_timeline->trim_in_point = false; - panel_timeline->transition_select = TA_OPENING_TRANSITION; + panel_timeline->transition_select = kTransitionOpening; closeness = nc; found = true; } @@ -2166,7 +2166,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { if (nc < closeness) { panel_timeline->trim_target = i; panel_timeline->trim_in_point = true; - panel_timeline->transition_select = TA_CLOSING_TRANSITION; + panel_timeline->transition_select = kTransitionClosing; closeness = nc; found = true; } @@ -2234,7 +2234,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { Ghost g; - g.in = g.old_in = g.out = g.old_out = (panel_timeline->transition_tool_type == TA_OPENING_TRANSITION) ? c->timeline_in : c->timeline_out; + g.in = g.old_in = g.out = g.old_out = (panel_timeline->transition_tool_type == kTransitionOpening) ? c->timeline_in : c->timeline_out; g.track = c->track; g.clip = panel_timeline->transition_tool_pre_clip; g.media_stream = panel_timeline->transition_tool_type; @@ -2254,9 +2254,9 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { long between_range = getFrameFromScreenPoint(panel_timeline->zoom, TRANSITION_BETWEEN_RANGE) + 1; if (panel_timeline->cursor_frame > halfway) { - panel_timeline->transition_tool_type = TA_CLOSING_TRANSITION; + panel_timeline->transition_tool_type = kTransitionClosing; } else { - panel_timeline->transition_tool_type = TA_OPENING_TRANSITION; + panel_timeline->transition_tool_type = kTransitionOpening; } panel_timeline->transition_tool_post_clip = -1; @@ -2334,14 +2334,14 @@ void draw_waveform(ClipPtr clip, const FootageStream* ms, long media_length, QPa } void draw_transition(QPainter& p, ClipPtr c, const QRect& clip_rect, QRect& text_rect, int transition_type) { - TransitionPtr t = (transition_type == TA_OPENING_TRANSITION) ? c->get_opening_transition() : c->get_closing_transition(); + TransitionPtr t = (transition_type == kTransitionOpening) ? c->get_opening_transition() : c->get_closing_transition(); if (t != nullptr) { QColor transition_color(255, 0, 0, 16); int transition_width = getScreenPointFromFrame(panel_timeline->zoom, t->get_true_length()); int transition_height = clip_rect.height(); int tr_y = clip_rect.y(); int tr_x = 0; - if (transition_type == TA_OPENING_TRANSITION) { + if (transition_type == kTransitionOpening) { tr_x = clip_rect.x(); text_rect.setX(text_rect.x()+transition_width); } else { @@ -2356,13 +2356,13 @@ void draw_transition(QPainter& p, ClipPtr c, const QRect& clip_rect, QRect& text p.setPen(QColor(0, 0, 0, 96)); if (t->secondary_clip == nullptr) { - if (transition_type == TA_OPENING_TRANSITION) { + if (transition_type == kTransitionOpening) { p.drawLine(transition_rect.bottomLeft(), transition_rect.topRight()); } else { p.drawLine(transition_rect.topLeft(), transition_rect.bottomRight()); } } else { - if (transition_type == TA_OPENING_TRANSITION) { + if (transition_type == kTransitionOpening) { p.drawLine(QPoint(transition_rect.left(), transition_rect.center().y()), transition_rect.topRight()); p.drawLine(QPoint(transition_rect.left(), transition_rect.center().y()), transition_rect.bottomRight()); draw_text = false; @@ -2577,8 +2577,8 @@ void TimelineWidget::paintEvent(QPaintEvent*) { p.setBrush(Qt::NoBrush); // draw clip transitions - draw_transition(p, clip, clip_rect, text_rect, TA_OPENING_TRANSITION); - draw_transition(p, clip, clip_rect, text_rect, TA_CLOSING_TRANSITION); + draw_transition(p, clip, clip_rect, text_rect, kTransitionOpening); + draw_transition(p, clip, clip_rect, text_rect, kTransitionClosing); // top left bevel p.setPen(Qt::white); @@ -2617,10 +2617,10 @@ void TimelineWidget::paintEvent(QPaintEvent*) { int type = panel_timeline->transition_tool_type; if (panel_timeline->transition_tool_post_clip == i) { // invert transition type - type = (type == TA_CLOSING_TRANSITION) ? TA_OPENING_TRANSITION : TA_CLOSING_TRANSITION; + type = (type == kTransitionClosing) ? kTransitionOpening : kTransitionClosing; } QRect transition_tool_rect = clip_rect; - if (type == TA_CLOSING_TRANSITION) { + if (type == kTransitionClosing) { if (panel_timeline->transition_tool_post_clip > -1) { transition_tool_rect.setLeft(transition_tool_rect.right() - TRANSITION_BETWEEN_RANGE); } else { From 5b59207cb479b737a891e04dd9dcfc0c66dffc76 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sun, 17 Feb 2019 03:15:18 -0800 Subject: [PATCH 09/30] started translating without restarting --- dialogs/preferencesdialog.cpp | 1093 ++++---- dialogs/preferencesdialog.h | 92 +- mainwindow.cpp | 1422 +++++----- olive.pro | 6 +- oliveglobal.cpp | 30 +- oliveglobal.h | 11 + panels/effectcontrols.cpp | 52 +- panels/effectcontrols.h | 126 +- panels/grapheditor.cpp | 326 +-- panels/grapheditor.h | 55 +- panels/panels.cpp | 298 +- panels/project.cpp | 1982 +++++++------- panels/project.h | 116 +- panels/timeline.cpp | 3163 ++++++++++----------- panels/timeline.h | 383 +-- panels/viewer.cpp | 6 +- panels/viewer.h | 188 +- ui/panel.cpp | 35 + ui/panel.h | 35 + ui/timelinewidget.cpp | 4866 ++++++++++++++++----------------- 20 files changed, 7227 insertions(+), 7058 deletions(-) create mode 100644 ui/panel.cpp create mode 100644 ui/panel.h diff --git a/dialogs/preferencesdialog.cpp b/dialogs/preferencesdialog.cpp index d2928032d..c3f711e69 100644 --- a/dialogs/preferencesdialog.cpp +++ b/dialogs/preferencesdialog.cpp @@ -51,666 +51,677 @@ #include KeySequenceEditor::KeySequenceEditor(QWidget* parent, QAction* a) - : QKeySequenceEdit(parent), action(a) { - setKeySequence(action->shortcut()); - //connect(this, SIGNAL(editingFinished()), this, SLOT(set_action_shortcut())); + : QKeySequenceEdit(parent), action(a) { + setKeySequence(action->shortcut()); + //connect(this, SIGNAL(editingFinished()), this, SLOT(set_action_shortcut())); } void KeySequenceEditor::set_action_shortcut() { - action->setShortcut(keySequence()); - action->setShortcutContext(Qt::ApplicationShortcut); + action->setShortcut(keySequence()); + action->setShortcutContext(Qt::ApplicationShortcut); } void KeySequenceEditor::reset_to_default() { - setKeySequence(action->property("default").toString()); + setKeySequence(action->property("default").toString()); } QString KeySequenceEditor::action_name() { - return action->property("id").toString(); + return action->property("id").toString(); } QString KeySequenceEditor::export_shortcut() { - QString ks = keySequence().toString(); - if (ks != action->property("default")) { - return action->property("id").toString() + "\t" + keySequence().toString(); - } - return 0; + QString ks = keySequence().toString(); + if (ks != action->property("default")) { + return action->property("id").toString() + "\t" + keySequence().toString(); + } + return 0; } PreferencesDialog::PreferencesDialog(QWidget *parent) : - QDialog(parent) + QDialog(parent) { - setWindowTitle(tr("Preferences")); - setup_ui(); + setWindowTitle(tr("Preferences")); + setup_ui(); - accurateSeekButton->setChecked(!olive::CurrentConfig.fast_seeking); - fastSeekButton->setChecked(olive::CurrentConfig.fast_seeking); - recordingComboBox->setCurrentIndex(olive::CurrentConfig.recording_mode - 1); - imgSeqFormatEdit->setText(olive::CurrentConfig.img_seq_formats); + accurateSeekButton->setChecked(!olive::CurrentConfig.fast_seeking); + fastSeekButton->setChecked(olive::CurrentConfig.fast_seeking); + recordingComboBox->setCurrentIndex(olive::CurrentConfig.recording_mode - 1); + imgSeqFormatEdit->setText(olive::CurrentConfig.img_seq_formats); } PreferencesDialog::~PreferencesDialog() {} void PreferencesDialog::setup_kbd_shortcut_worker(QMenu* menu, QTreeWidgetItem* parent) { - QList actions = menu->actions(); - for (int i=0;i actions = menu->actions(); + for (int i=0;iisSeparator() && a->property("keyignore").isNull()) { - QTreeWidgetItem* item = new QTreeWidgetItem(parent); - item->setText(0, a->text().replace("&", "")); + if (!a->isSeparator() && a->property("keyignore").isNull()) { + QTreeWidgetItem* item = new QTreeWidgetItem(parent); + item->setText(0, a->text().replace("&", "")); - parent->addChild(item); + parent->addChild(item); - if (a->menu() != nullptr) { - item->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator); - setup_kbd_shortcut_worker(a->menu(), item); - } else { - key_shortcut_items.append(item); - key_shortcut_actions.append(a); - } - } + if (a->menu() != nullptr) { + item->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator); + setup_kbd_shortcut_worker(a->menu(), item); + } else { + key_shortcut_items.append(item); + key_shortcut_actions.append(a); + } } + } } void PreferencesDialog::delete_previews(char type) { - if (type != 't' && type != 'w' && type != 1) return; + if (type != 't' && type != 'w' && type != 1) return; - QDir preview_path(get_data_path() + "/previews"); + QDir preview_path(get_data_path() + "/previews"); - if (type == 1) { - // indiscriminately delete everything - preview_path.removeRecursively(); - } else { - QStringList preview_file_list = preview_path.entryList(QDir::Files | QDir::NoDotAndDotDot); - for (int i=0;i= 0 - && preview_file_str.at(identifier_char_index) >= 48 - && preview_file_str.at(identifier_char_index) <= 57) { - identifier_char_index--; - } + // find identifier char + while (identifier_char_index >= 0 + && preview_file_str.at(identifier_char_index) >= 48 + && preview_file_str.at(identifier_char_index) <= 57) { + identifier_char_index--; + } - // thumbnails will have a 't' towards the end of the filenames, waveforms will have a 'w' - // if they match the type of preview we're deleting, remove them - if (preview_file_str.at(identifier_char_index) == type) { - QFile::remove(preview_path.filePath(preview_file_str)); - } - } + // thumbnails will have a 't' towards the end of the filenames, waveforms will have a 'w' + // if they match the type of preview we're deleting, remove them + if (preview_file_str.at(identifier_char_index) == type) { + QFile::remove(preview_path.filePath(preview_file_str)); + } } + } } void PreferencesDialog::setup_kbd_shortcuts(QMenuBar* menubar) { - QList menus = menubar->actions(); + QList menus = menubar->actions(); - for (int i=0;imenu(); + for (int i=0;imenu(); - QTreeWidgetItem* item = new QTreeWidgetItem(keyboard_tree); - item->setText(0, menu->title().replace("&", "")); + QTreeWidgetItem* item = new QTreeWidgetItem(keyboard_tree); + item->setText(0, menu->title().replace("&", "")); - keyboard_tree->addTopLevelItem(item); + keyboard_tree->addTopLevelItem(item); - setup_kbd_shortcut_worker(menu, item); - } + setup_kbd_shortcut_worker(menu, item); + } - for (int i=0;iproperty("id").isNull()) { - KeySequenceEditor* editor = new KeySequenceEditor(keyboard_tree, key_shortcut_actions.at(i)); - keyboard_tree->setItemWidget(key_shortcut_items.at(i), 1, editor); - key_shortcut_fields.append(editor); - } - } + for (int i=0;iproperty("id").isNull()) { + KeySequenceEditor* editor = new KeySequenceEditor(keyboard_tree, key_shortcut_actions.at(i)); + keyboard_tree->setItemWidget(key_shortcut_items.at(i), 1, editor); + key_shortcut_fields.append(editor); + } + } } void PreferencesDialog::save() { - bool restart_after_saving = false; - bool reinit_audio = false; + bool restart_after_saving = false; + bool reinit_audio = false; + bool reload_language = false; - // Validate whether the specified CSS file exists - if (!custom_css_fn->text().isEmpty() && !QFileInfo::exists(custom_css_fn->text())) { - QMessageBox::critical( - this, - tr("Invalid CSS File"), - tr("CSS file '%1' does not exist.").arg(custom_css_fn->text()) - ); - return; - } + // Validate whether the specified CSS file exists + if (!custom_css_fn->text().isEmpty() && !QFileInfo::exists(custom_css_fn->text())) { + QMessageBox::critical( + this, + tr("Invalid CSS File"), + tr("CSS file '%1' does not exist.").arg(custom_css_fn->text()) + ); + return; + } - // Check if any settings will require a restart of Olive - if (olive::CurrentConfig.effect_textbox_lines != effect_textbox_lines_field->value() - || olive::CurrentConfig.use_software_fallback != use_software_fallbacks_checkbox->isChecked() - || olive::CurrentConfig.language_file != language_combobox->currentData().toString() - || olive::CurrentConfig.thumbnail_resolution != thumbnail_res_spinbox->value() - || olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()) { + // Check if any settings will require a restart of Olive + if (olive::CurrentConfig.effect_textbox_lines != effect_textbox_lines_field->value() + || olive::CurrentConfig.use_software_fallback != use_software_fallbacks_checkbox->isChecked() + || olive::CurrentConfig.thumbnail_resolution != thumbnail_res_spinbox->value() + || olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()) { - // any changes to these settings will require a restart - ask the user if we should do one now or later + // any changes to these settings will require a restart - ask the user if we should do one now or later - int ret = QMessageBox::question(this, - "Restart Required", - "Some of the changed settings will require a restart of Olive. Would you like " - "to restart now?", - QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); + int ret = QMessageBox::question(this, + "Restart Required", + "Some of the changed settings will require a restart of Olive. Would you like " + "to restart now?", + QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); - if (ret == QMessageBox::Cancel) { - // Return to Preferences dialog without saving any settings - return; - } else if (ret == QMessageBox::Yes) { + if (ret == QMessageBox::Cancel) { + // Return to Preferences dialog without saving any settings + return; + } else if (ret == QMessageBox::Yes) { - // Check if we can close the current project. If not, we'll treat it as if the user clicked "Cancel". - if (olive::Global->can_close_project()) { - restart_after_saving = true; - } else { - return; - } - } - // Selecting "No" will save the settings and not restart. They will become active next time Olive opens. + // Check if we can close the current project. If not, we'll treat it as if the user clicked "Cancel". + if (olive::Global->can_close_project()) { + restart_after_saving = true; + } else { + return; + } + } + // Selecting "No" will save the settings and not restart. They will become active next time Olive opens. + } + + // Audio settings may require the audio device to be re-initiated. + if (olive::CurrentConfig.preferred_audio_output != audio_output_devices->currentData().toString() + || olive::CurrentConfig.preferred_audio_input != audio_input_devices->currentData().toString() + || olive::CurrentConfig.audio_rate != audio_sample_rate->currentData().toInt()) { + reinit_audio = true; + } + + // see if the language file should be reloaded (not necessary if the app is restarting anyway) + if (!restart_after_saving + && olive::CurrentConfig.language_file != language_combobox->currentData().toString()) { + reload_language = true; + } + + // save settings from UI to backend + olive::CurrentConfig.css_path = custom_css_fn->text(); + olive::MainWindow->load_css_from_file(olive::CurrentConfig.css_path); + + olive::CurrentConfig.recording_mode = recordingComboBox->currentIndex() + 1; + olive::CurrentConfig.img_seq_formats = imgSeqFormatEdit->text(); + olive::CurrentConfig.fast_seeking = fastSeekButton->isChecked(); + olive::CurrentConfig.upcoming_queue_size = upcoming_queue_spinbox->value(); + olive::CurrentConfig.upcoming_queue_type = upcoming_queue_type->currentIndex(); + olive::CurrentConfig.previous_queue_size = previous_queue_spinbox->value(); + olive::CurrentConfig.previous_queue_type = previous_queue_type->currentIndex(); + olive::CurrentConfig.add_default_effects_to_clips = add_default_effects_to_clips->isChecked(); + + olive::CurrentConfig.preferred_audio_output = audio_output_devices->currentData().toString(); + olive::CurrentConfig.preferred_audio_input = audio_input_devices->currentData().toString(); + olive::CurrentConfig.audio_rate = audio_sample_rate->currentData().toInt(); + + olive::CurrentConfig.effect_textbox_lines = effect_textbox_lines_field->value(); + olive::CurrentConfig.use_software_fallback = use_software_fallbacks_checkbox->isChecked(); + olive::CurrentConfig.language_file = language_combobox->currentData().toString(); + + if (olive::CurrentConfig.thumbnail_resolution != thumbnail_res_spinbox->value() + || olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()) { + // we're changing the size of thumbnails and waveforms, so let's delete them and regenerate them next start + + // delete nothing + char delete_match = 0; + + if (olive::CurrentConfig.thumbnail_resolution != thumbnail_res_spinbox->value()) { + // delete existing thumbnails + olive::CurrentConfig.thumbnail_resolution = thumbnail_res_spinbox->value(); + + // delete only thumbnails + delete_match = 't'; } - // Audio settings may require the audio device to be re-initiated. - if (olive::CurrentConfig.preferred_audio_output != audio_output_devices->currentData().toString() - || olive::CurrentConfig.preferred_audio_input != audio_input_devices->currentData().toString() - || olive::CurrentConfig.audio_rate != audio_sample_rate->currentData().toInt()) { - reinit_audio = true; + if (olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()) { + // delete existing waveforms + olive::CurrentConfig.waveform_resolution = waveform_res_spinbox->value(); + + // if we're already deleting thumbnails + if (delete_match == 't') { + // delete all + delete_match = 1; + } else { + // just delete waveforms + delete_match = 'w'; + } } - // save settings from UI to backend - olive::CurrentConfig.css_path = custom_css_fn->text(); - olive::MainWindow->load_css_from_file(olive::CurrentConfig.css_path); + delete_previews(delete_match); + } - olive::CurrentConfig.recording_mode = recordingComboBox->currentIndex() + 1; - olive::CurrentConfig.img_seq_formats = imgSeqFormatEdit->text(); - olive::CurrentConfig.fast_seeking = fastSeekButton->isChecked(); - olive::CurrentConfig.upcoming_queue_size = upcoming_queue_spinbox->value(); - olive::CurrentConfig.upcoming_queue_type = upcoming_queue_type->currentIndex(); - olive::CurrentConfig.previous_queue_size = previous_queue_spinbox->value(); - olive::CurrentConfig.previous_queue_type = previous_queue_type->currentIndex(); - olive::CurrentConfig.add_default_effects_to_clips = add_default_effects_to_clips->isChecked(); + // Save keyboard shortcuts + for (int i=0;iset_action_shortcut(); + } - olive::CurrentConfig.preferred_audio_output = audio_output_devices->currentData().toString(); - olive::CurrentConfig.preferred_audio_input = audio_input_devices->currentData().toString(); - olive::CurrentConfig.audio_rate = audio_sample_rate->currentData().toInt(); + // Audio settings may require the audio device to be re-initiated. + if (reinit_audio) { + init_audio(); + } - olive::CurrentConfig.effect_textbox_lines = effect_textbox_lines_field->value(); - olive::CurrentConfig.use_software_fallback = use_software_fallbacks_checkbox->isChecked(); - olive::CurrentConfig.language_file = language_combobox->currentData().toString(); + // reload language file if it changed + if (reload_language) { + olive::Global->load_translation_from_config(); + } - if (olive::CurrentConfig.thumbnail_resolution != thumbnail_res_spinbox->value() - || olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()) { - // we're changing the size of thumbnails and waveforms, so let's delete them and regenerate them next start + accept(); - // delete nothing - char delete_match = 0; + if (restart_after_saving) { + // since we already ran can_close_project(), bypass checking again by running setWindowModified(false) + olive::MainWindow->setWindowModified(false); - if (olive::CurrentConfig.thumbnail_resolution != thumbnail_res_spinbox->value()) { - // delete existing thumbnails - olive::CurrentConfig.thumbnail_resolution = thumbnail_res_spinbox->value(); + olive::MainWindow->close(); - // delete only thumbnails - delete_match = 't'; - } - - if (olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()) { - // delete existing waveforms - olive::CurrentConfig.waveform_resolution = waveform_res_spinbox->value(); - - // if we're already deleting thumbnails - if (delete_match == 't') { - // delete all - delete_match = 1; - } else { - // just delete waveforms - delete_match = 'w'; - } - } - - delete_previews(delete_match); - } - - // Save keyboard shortcuts - for (int i=0;iset_action_shortcut(); - } - - // Audio settings may require the audio device to be re-initiated. - if (reinit_audio) { - init_audio(); - } - - accept(); - - if (restart_after_saving) { - // since we already ran can_close_project(), bypass checking again by running setWindowModified(false) - olive::MainWindow->setWindowModified(false); - - olive::MainWindow->close(); - - QProcess::startDetached(QApplication::applicationFilePath(), { olive::ActiveProjectFilename }); - } + QProcess::startDetached(QApplication::applicationFilePath(), { olive::ActiveProjectFilename }); + } } void PreferencesDialog::reset_default_shortcut() { - QList items = keyboard_tree->selectedItems(); - for (int i=0;iselectedItems().at(i); - static_cast(keyboard_tree->itemWidget(item, 1))->reset_to_default(); - } + QList items = keyboard_tree->selectedItems(); + for (int i=0;iselectedItems().at(i); + static_cast(keyboard_tree->itemWidget(item, 1))->reset_to_default(); + } } void PreferencesDialog::reset_all_shortcuts() { - if (QMessageBox::question( - this, - tr("Confirm Reset All Shortcuts"), - tr("Are you sure you wish to reset all keyboard shortcuts to their defaults?"), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - for (int i=0;ireset_to_default(); - } - } + if (QMessageBox::question( + this, + tr("Confirm Reset All Shortcuts"), + tr("Are you sure you wish to reset all keyboard shortcuts to their defaults?"), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + for (int i=0;ireset_to_default(); + } + } } bool PreferencesDialog::refine_shortcut_list(const QString &s, QTreeWidgetItem* parent) { - if (parent == nullptr) { - for (int i=0;itopLevelItemCount();i++) { - refine_shortcut_list(s, keyboard_tree->topLevelItem(i)); - } - } else { - parent->setExpanded(!s.isEmpty()); + if (parent == nullptr) { + for (int i=0;itopLevelItemCount();i++) { + refine_shortcut_list(s, keyboard_tree->topLevelItem(i)); + } + } else { + parent->setExpanded(!s.isEmpty()); - bool all_children_are_hidden = !s.isEmpty(); + bool all_children_are_hidden = !s.isEmpty(); - for (int i=0;ichildCount();i++) { - QTreeWidgetItem* item = parent->child(i); - if (item->childCount() > 0) { - all_children_are_hidden = refine_shortcut_list(s, item); - } else { - item->setHidden(false); - if (s.isEmpty()) { - all_children_are_hidden = false; - } else { - QString shortcut; - if (keyboard_tree->itemWidget(item, 1) != nullptr) { - shortcut = static_cast(keyboard_tree->itemWidget(item, 1))->keySequence().toString(); - } - if (item->text(0).contains(s, Qt::CaseInsensitive) || shortcut.contains(s, Qt::CaseInsensitive)) { - all_children_are_hidden = false; - } else { - item->setHidden(true); - } - } - } - } + for (int i=0;ichildCount();i++) { + QTreeWidgetItem* item = parent->child(i); + if (item->childCount() > 0) { + all_children_are_hidden = refine_shortcut_list(s, item); + } else { + item->setHidden(false); + if (s.isEmpty()) { + all_children_are_hidden = false; + } else { + QString shortcut; + if (keyboard_tree->itemWidget(item, 1) != nullptr) { + shortcut = static_cast(keyboard_tree->itemWidget(item, 1))->keySequence().toString(); + } + if (item->text(0).contains(s, Qt::CaseInsensitive) || shortcut.contains(s, Qt::CaseInsensitive)) { + all_children_are_hidden = false; + } else { + item->setHidden(true); + } + } + } + } - if (parent->text(0).contains(s, Qt::CaseInsensitive)) all_children_are_hidden = false; + if (parent->text(0).contains(s, Qt::CaseInsensitive)) all_children_are_hidden = false; - parent->setHidden(all_children_are_hidden); + parent->setHidden(all_children_are_hidden); - return all_children_are_hidden; - } - return true; + return all_children_are_hidden; + } + return true; } void PreferencesDialog::load_shortcut_file() { - QString fn = QFileDialog::getOpenFileName(this, tr("Import Keyboard Shortcuts")); - if (!fn.isEmpty()) { - QFile f(fn); - if (f.exists() && f.open(QFile::ReadOnly)) { - QByteArray ba = f.readAll(); - f.close(); - for (int i=0;iaction_name()); - if (index == 0 || (index > 0 && ba.at(index-1) == '\n')) { - while (index < ba.size() && ba.at(index) != '\t') index++; - QString ks; - index++; - while (index < ba.size() && ba.at(index) != '\n') { - ks.append(ba.at(index)); - index++; - } - key_shortcut_fields.at(i)->setKeySequence(ks); - } else { - key_shortcut_fields.at(i)->reset_to_default(); - } - } - } else { - QMessageBox::critical( - this, - tr("Error saving shortcuts"), - tr("Failed to open file for reading") - ); - } - } + QString fn = QFileDialog::getOpenFileName(this, tr("Import Keyboard Shortcuts")); + if (!fn.isEmpty()) { + QFile f(fn); + if (f.exists() && f.open(QFile::ReadOnly)) { + QByteArray ba = f.readAll(); + f.close(); + for (int i=0;iaction_name()); + if (index == 0 || (index > 0 && ba.at(index-1) == '\n')) { + while (index < ba.size() && ba.at(index) != '\t') index++; + QString ks; + index++; + while (index < ba.size() && ba.at(index) != '\n') { + ks.append(ba.at(index)); + index++; + } + key_shortcut_fields.at(i)->setKeySequence(ks); + } else { + key_shortcut_fields.at(i)->reset_to_default(); + } + } + } else { + QMessageBox::critical( + this, + tr("Error saving shortcuts"), + tr("Failed to open file for reading") + ); + } + } } void PreferencesDialog::save_shortcut_file() { - QString fn = QFileDialog::getSaveFileName(this, tr("Export Keyboard Shortcuts")); - if (!fn.isEmpty()) { - QFile f(fn); - if (f.open(QFile::WriteOnly)) { - bool start = true; - for (int i=0;iexport_shortcut(); - if (!s.isEmpty()) { - if (!start) f.write("\n"); - f.write(s.toUtf8()); - start = false; - } - } - f.close(); - QMessageBox::information(this, tr("Export Shortcuts"), tr("Shortcuts exported successfully")); - } else { - QMessageBox::critical(this, tr("Error saving shortcuts"), tr("Failed to open file for writing")); - } - } + QString fn = QFileDialog::getSaveFileName(this, tr("Export Keyboard Shortcuts")); + if (!fn.isEmpty()) { + QFile f(fn); + if (f.open(QFile::WriteOnly)) { + bool start = true; + for (int i=0;iexport_shortcut(); + if (!s.isEmpty()) { + if (!start) f.write("\n"); + f.write(s.toUtf8()); + start = false; + } + } + f.close(); + QMessageBox::information(this, tr("Export Shortcuts"), tr("Shortcuts exported successfully")); + } else { + QMessageBox::critical(this, tr("Error saving shortcuts"), tr("Failed to open file for writing")); + } + } } void PreferencesDialog::browse_css_file() { - QString fn = QFileDialog::getOpenFileName(this, tr("Browse for CSS file")); - if (!fn.isEmpty()) { - custom_css_fn->setText(fn); - } + QString fn = QFileDialog::getOpenFileName(this, tr("Browse for CSS file")); + if (!fn.isEmpty()) { + custom_css_fn->setText(fn); + } } void PreferencesDialog::delete_all_previews() { - if (QMessageBox::question(this, - tr("Delete All Previews"), - tr("Are you sure you want to delete all previews?"), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - delete_previews(1); - QMessageBox::information(this, - tr("Previews Deleted"), - tr("All previews deleted succesfully. You may have to re-open your current project for changes to take effect."), - QMessageBox::Ok); - } + if (QMessageBox::question(this, + tr("Delete All Previews"), + tr("Are you sure you want to delete all previews?"), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + delete_previews(1); + QMessageBox::information(this, + tr("Previews Deleted"), + tr("All previews deleted succesfully. You may have to re-open your current project for changes to take effect."), + QMessageBox::Ok); + } } void PreferencesDialog::setup_ui() { - QVBoxLayout* verticalLayout = new QVBoxLayout(this); - QTabWidget* tabWidget = new QTabWidget(this); + QVBoxLayout* verticalLayout = new QVBoxLayout(this); + QTabWidget* tabWidget = new QTabWidget(this); - // row counter used to ease adding new rows - int row = 0; + // row counter used to ease adding new rows + int row = 0; - // General - QWidget* general_tab = new QWidget(this); - QGridLayout* general_layout = new QGridLayout(general_tab); + // General + QWidget* general_tab = new QWidget(this); + QGridLayout* general_layout = new QGridLayout(general_tab); - // General -> Language - general_layout->addWidget(new QLabel(tr("Language:")), row, 0); + // General -> Language + general_layout->addWidget(new QLabel(tr("Language:")), row, 0); - language_combobox = new QComboBox(); + language_combobox = new QComboBox(); - // add default language (en-US) - language_combobox->addItem(QLocale::languageToString(QLocale("en-US").language())); + // add default language (en-US) + language_combobox->addItem(QLocale::languageToString(QLocale("en-US").language())); - // add languages from file - QList translation_paths = get_language_paths(); + // add languages from file + QList translation_paths = get_language_paths(); - // iterate through all language search paths - for (int j=0;jaddItem(QLocale(locale_str).nativeLanguageName(), locale_relative_path); + QFileInfo locale_file(translation_files.at(i)); + QString locale_file_basename = locale_file.baseName(); + QString locale_str = locale_file_basename.mid(locale_file_basename.lastIndexOf('_')+1); + language_combobox->addItem(QLocale(locale_str).nativeLanguageName(), locale_relative_path); - if (olive::CurrentConfig.language_file == locale_relative_path) { - language_combobox->setCurrentIndex(language_combobox->count() - 1); - } - } - } - } + if (olive::CurrentConfig.language_file == locale_relative_path) { + language_combobox->setCurrentIndex(language_combobox->count() - 1); + } + } + } + } - general_layout->addWidget(language_combobox, row, 1, 1, 4); + general_layout->addWidget(language_combobox, row, 1, 1, 4); - row++; + row++; - // General -> Custom CSS - general_layout->addWidget(new QLabel(tr("Custom CSS:"), this), row, 0); + // General -> Custom CSS + general_layout->addWidget(new QLabel(tr("Custom CSS:"), this), row, 0); - custom_css_fn = new QLineEdit(general_tab); - custom_css_fn->setText(olive::CurrentConfig.css_path); - general_layout->addWidget(custom_css_fn, row, 1, 1, 3); + custom_css_fn = new QLineEdit(general_tab); + custom_css_fn->setText(olive::CurrentConfig.css_path); + general_layout->addWidget(custom_css_fn, row, 1, 1, 3); - QPushButton* custom_css_browse = new QPushButton(tr("Browse"), general_tab); - connect(custom_css_browse, SIGNAL(clicked(bool)), this, SLOT(browse_css_file())); - general_layout->addWidget(custom_css_browse, row, 4); + QPushButton* custom_css_browse = new QPushButton(tr("Browse"), general_tab); + connect(custom_css_browse, SIGNAL(clicked(bool)), this, SLOT(browse_css_file())); + general_layout->addWidget(custom_css_browse, row, 4); - row++; - - // General -> Image Sequence Formats - general_layout->addWidget(new QLabel(tr("Image sequence formats:"), this), row, 0); - - imgSeqFormatEdit = new QLineEdit(general_tab); - - general_layout->addWidget(imgSeqFormatEdit, row, 1, 1, 4); - - row++; - - // General -> Audio Recording - general_layout->addWidget(new QLabel(tr("Audio Recording:"), this), row, 0); - - recordingComboBox = new QComboBox(general_tab); - recordingComboBox->addItem(tr("Mono")); - recordingComboBox->addItem(tr("Stereo")); - general_layout->addWidget(recordingComboBox, row, 1, 1, 4); - - row++; + row++; + + // General -> Image Sequence Formats + general_layout->addWidget(new QLabel(tr("Image sequence formats:"), this), row, 0); + + imgSeqFormatEdit = new QLineEdit(general_tab); + + general_layout->addWidget(imgSeqFormatEdit, row, 1, 1, 4); + + row++; + + // General -> Audio Recording + general_layout->addWidget(new QLabel(tr("Audio Recording:"), this), row, 0); + + recordingComboBox = new QComboBox(general_tab); + recordingComboBox->addItem(tr("Mono")); + recordingComboBox->addItem(tr("Stereo")); + general_layout->addWidget(recordingComboBox, row, 1, 1, 4); + + row++; - // General -> Effect Textbox Lines - general_layout->addWidget(new QLabel(tr("Effect Textbox Lines:"), this), row, 0); + // General -> Effect Textbox Lines + general_layout->addWidget(new QLabel(tr("Effect Textbox Lines:"), this), row, 0); - effect_textbox_lines_field = new QSpinBox(general_tab); - effect_textbox_lines_field->setMinimum(1); - effect_textbox_lines_field->setValue(olive::CurrentConfig.effect_textbox_lines); - general_layout->addWidget(effect_textbox_lines_field, row, 1, 1, 4); - - row++; - - // General -> Thumbnail and Waveform Resolution - general_layout->addWidget(new QLabel(tr("Thumbnail Resolution:"), this), row, 0); - - thumbnail_res_spinbox = new QSpinBox(this); - thumbnail_res_spinbox->setMinimum(0); - thumbnail_res_spinbox->setMaximum(INT_MAX); - thumbnail_res_spinbox->setValue(olive::CurrentConfig.thumbnail_resolution); - general_layout->addWidget(thumbnail_res_spinbox, row, 1); - - general_layout->addWidget(new QLabel(tr("Waveform Resolution:"), this), row, 2); - - waveform_res_spinbox = new QSpinBox(this); - waveform_res_spinbox->setMinimum(0); - waveform_res_spinbox->setMaximum(INT_MAX); - waveform_res_spinbox->setValue(olive::CurrentConfig.waveform_resolution); - general_layout->addWidget(waveform_res_spinbox, row, 3); - - QPushButton* delete_preview_btn = new QPushButton(tr("Delete Previews")); - general_layout->addWidget(delete_preview_btn, row, 4); - connect(delete_preview_btn, SIGNAL(clicked(bool)), this, SLOT(delete_all_previews())); - - row++; - - // General -> Use Software Fallbacks When Possible - use_software_fallbacks_checkbox = new QCheckBox(general_tab); - use_software_fallbacks_checkbox->setText(tr("Use Software Fallbacks When Possible")); - use_software_fallbacks_checkbox->setChecked(olive::CurrentConfig.use_software_fallback); - general_layout->addWidget(use_software_fallbacks_checkbox, row, 0, 1, 4); - - tabWidget->addTab(general_tab, tr("General")); - - // Behavior - QWidget* behavior_tab = new QWidget(this); - tabWidget->addTab(behavior_tab, tr("Behavior")); - - QVBoxLayout* behavior_tab_layout = new QVBoxLayout(behavior_tab); - - add_default_effects_to_clips = new QCheckBox("Add Default Effects to New Clips"); - add_default_effects_to_clips->setChecked(olive::CurrentConfig.add_default_effects_to_clips); - behavior_tab_layout->addWidget(add_default_effects_to_clips); - - // Playback - QWidget* playback_tab = new QWidget(this); - QVBoxLayout* playback_tab_layout = new QVBoxLayout(playback_tab); - - // Playback -> Seeking - QGroupBox* seeking_group = new QGroupBox(playback_tab); - seeking_group->setTitle(tr("Seeking")); - QVBoxLayout* seeking_group_layout = new QVBoxLayout(seeking_group); - accurateSeekButton = new QRadioButton(seeking_group); - accurateSeekButton->setText(tr("Accurate Seeking\nAlways show the correct frame (visual may pause briefly as correct frame is retrieved)")); - seeking_group_layout->addWidget(accurateSeekButton); - fastSeekButton = new QRadioButton(seeking_group); - fastSeekButton->setText(tr("Fast Seeking\nSeek quickly (may briefly show inaccurate frames when seeking - doesn't affect playback/export)")); - seeking_group_layout->addWidget(fastSeekButton); - playback_tab_layout->addWidget(seeking_group); - - // Playback -> Memory Usage - QGroupBox* memory_usage_group = new QGroupBox(playback_tab); - memory_usage_group->setTitle(tr("Memory Usage")); - QGridLayout* memory_usage_layout = new QGridLayout(memory_usage_group); - memory_usage_layout->addWidget(new QLabel(tr("Upcoming Frame Queue:"), playback_tab), 0, 0); - upcoming_queue_spinbox = new QDoubleSpinBox(playback_tab); - upcoming_queue_spinbox->setValue(olive::CurrentConfig.upcoming_queue_size); - memory_usage_layout->addWidget(upcoming_queue_spinbox, 0, 1); - upcoming_queue_type = new QComboBox(playback_tab); - upcoming_queue_type->addItem(tr("frames")); - upcoming_queue_type->addItem(tr("seconds")); - upcoming_queue_type->setCurrentIndex(olive::CurrentConfig.upcoming_queue_type); - memory_usage_layout->addWidget(upcoming_queue_type, 0, 2); - memory_usage_layout->addWidget(new QLabel(tr("Previous Frame Queue:"), playback_tab), 1, 0); - previous_queue_spinbox = new QDoubleSpinBox(playback_tab); - previous_queue_spinbox->setValue(olive::CurrentConfig.previous_queue_size); - memory_usage_layout->addWidget(previous_queue_spinbox, 1, 1); - previous_queue_type = new QComboBox(playback_tab); - previous_queue_type->addItem(tr("frames")); - previous_queue_type->addItem(tr("seconds")); - previous_queue_type->setCurrentIndex(olive::CurrentConfig.previous_queue_type); - memory_usage_layout->addWidget(previous_queue_type, 1, 2); - playback_tab_layout->addWidget(memory_usage_group); - - tabWidget->addTab(playback_tab, tr("Playback")); - - // Audio - QWidget* audio_tab = new QWidget(this); - - QGridLayout* audio_tab_layout = new QGridLayout(audio_tab); - - audio_tab_layout->addWidget(new QLabel(tr("Output Device:")), 0, 0); - - audio_output_devices = new QComboBox(); - audio_output_devices->addItem(tr("Default"), ""); - - // list all available audio output devices - QList devs = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); - bool found_preferred_device = false; - for (int i=0;iaddItem(devs.at(i).deviceName(), devs.at(i).deviceName()); - if (!found_preferred_device - && devs.at(i).deviceName() == olive::CurrentConfig.preferred_audio_output) { - audio_output_devices->setCurrentIndex(audio_output_devices->count()-1); - found_preferred_device = true; - } - } - - audio_tab_layout->addWidget(audio_output_devices, 0, 1); - - audio_tab_layout->addWidget(new QLabel(tr("Input Device:")), 1, 0); - - audio_input_devices = new QComboBox(); - audio_input_devices->addItem(tr("Default"), ""); - - // list all available audio input devices - devs = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); - found_preferred_device = false; - for (int i=0;iaddItem(devs.at(i).deviceName(), devs.at(i).deviceName()); - if (!found_preferred_device - && devs.at(i).deviceName() == olive::CurrentConfig.preferred_audio_input) { - audio_input_devices->setCurrentIndex(audio_input_devices->count()-1); - found_preferred_device = true; - } - } - - audio_tab_layout->addWidget(audio_input_devices, 1, 1); - - audio_tab_layout->addWidget(new QLabel(tr("Sample Rate:")), 2, 0); - - audio_sample_rate = new QComboBox(); - combobox_audio_sample_rates(audio_sample_rate); - for (int i=0;icount();i++) { - if (audio_sample_rate->itemData(i).toInt() == olive::CurrentConfig.audio_rate) { - audio_sample_rate->setCurrentIndex(i); - break; - } - } - - audio_tab_layout->addWidget(audio_sample_rate, 2, 1); - - tabWidget->addTab(audio_tab, tr("Audio")); - - // Shortcuts - QWidget* shortcut_tab = new QWidget(this); - - QVBoxLayout* shortcut_layout = new QVBoxLayout(shortcut_tab); - - QLineEdit* key_search_line = new QLineEdit(shortcut_tab); - key_search_line->setPlaceholderText(tr("Search for action or shortcut")); - connect(key_search_line, SIGNAL(textChanged(const QString &)), this, SLOT(refine_shortcut_list(const QString &))); - - shortcut_layout->addWidget(key_search_line); - - keyboard_tree = new QTreeWidget(shortcut_tab); - QTreeWidgetItem* tree_header = keyboard_tree->headerItem(); - tree_header->setText(0, tr("Action")); - tree_header->setText(1, tr("Shortcut")); - shortcut_layout->addWidget(keyboard_tree); - - QHBoxLayout* reset_shortcut_layout = new QHBoxLayout(shortcut_tab); - - QPushButton* import_shortcut_button = new QPushButton(tr("Import"), shortcut_tab); - reset_shortcut_layout->addWidget(import_shortcut_button); - connect(import_shortcut_button, SIGNAL(clicked(bool)), this, SLOT(load_shortcut_file())); + effect_textbox_lines_field = new QSpinBox(general_tab); + effect_textbox_lines_field->setMinimum(1); + effect_textbox_lines_field->setValue(olive::CurrentConfig.effect_textbox_lines); + general_layout->addWidget(effect_textbox_lines_field, row, 1, 1, 4); + + row++; + + // General -> Thumbnail and Waveform Resolution + general_layout->addWidget(new QLabel(tr("Thumbnail Resolution:"), this), row, 0); + + thumbnail_res_spinbox = new QSpinBox(this); + thumbnail_res_spinbox->setMinimum(0); + thumbnail_res_spinbox->setMaximum(INT_MAX); + thumbnail_res_spinbox->setValue(olive::CurrentConfig.thumbnail_resolution); + general_layout->addWidget(thumbnail_res_spinbox, row, 1); + + general_layout->addWidget(new QLabel(tr("Waveform Resolution:"), this), row, 2); + + waveform_res_spinbox = new QSpinBox(this); + waveform_res_spinbox->setMinimum(0); + waveform_res_spinbox->setMaximum(INT_MAX); + waveform_res_spinbox->setValue(olive::CurrentConfig.waveform_resolution); + general_layout->addWidget(waveform_res_spinbox, row, 3); + + QPushButton* delete_preview_btn = new QPushButton(tr("Delete Previews")); + general_layout->addWidget(delete_preview_btn, row, 4); + connect(delete_preview_btn, SIGNAL(clicked(bool)), this, SLOT(delete_all_previews())); + + row++; + + // General -> Use Software Fallbacks When Possible + use_software_fallbacks_checkbox = new QCheckBox(general_tab); + use_software_fallbacks_checkbox->setText(tr("Use Software Fallbacks When Possible")); + use_software_fallbacks_checkbox->setChecked(olive::CurrentConfig.use_software_fallback); + general_layout->addWidget(use_software_fallbacks_checkbox, row, 0, 1, 4); + + tabWidget->addTab(general_tab, tr("General")); + + // Behavior + QWidget* behavior_tab = new QWidget(this); + tabWidget->addTab(behavior_tab, tr("Behavior")); + + QVBoxLayout* behavior_tab_layout = new QVBoxLayout(behavior_tab); + + add_default_effects_to_clips = new QCheckBox("Add Default Effects to New Clips"); + add_default_effects_to_clips->setChecked(olive::CurrentConfig.add_default_effects_to_clips); + behavior_tab_layout->addWidget(add_default_effects_to_clips); + + // Playback + QWidget* playback_tab = new QWidget(this); + QVBoxLayout* playback_tab_layout = new QVBoxLayout(playback_tab); + + // Playback -> Seeking + QGroupBox* seeking_group = new QGroupBox(playback_tab); + seeking_group->setTitle(tr("Seeking")); + QVBoxLayout* seeking_group_layout = new QVBoxLayout(seeking_group); + accurateSeekButton = new QRadioButton(seeking_group); + accurateSeekButton->setText(tr("Accurate Seeking\nAlways show the correct frame (visual may pause briefly as correct frame is retrieved)")); + seeking_group_layout->addWidget(accurateSeekButton); + fastSeekButton = new QRadioButton(seeking_group); + fastSeekButton->setText(tr("Fast Seeking\nSeek quickly (may briefly show inaccurate frames when seeking - doesn't affect playback/export)")); + seeking_group_layout->addWidget(fastSeekButton); + playback_tab_layout->addWidget(seeking_group); + + // Playback -> Memory Usage + QGroupBox* memory_usage_group = new QGroupBox(playback_tab); + memory_usage_group->setTitle(tr("Memory Usage")); + QGridLayout* memory_usage_layout = new QGridLayout(memory_usage_group); + memory_usage_layout->addWidget(new QLabel(tr("Upcoming Frame Queue:"), playback_tab), 0, 0); + upcoming_queue_spinbox = new QDoubleSpinBox(playback_tab); + upcoming_queue_spinbox->setValue(olive::CurrentConfig.upcoming_queue_size); + memory_usage_layout->addWidget(upcoming_queue_spinbox, 0, 1); + upcoming_queue_type = new QComboBox(playback_tab); + upcoming_queue_type->addItem(tr("frames")); + upcoming_queue_type->addItem(tr("seconds")); + upcoming_queue_type->setCurrentIndex(olive::CurrentConfig.upcoming_queue_type); + memory_usage_layout->addWidget(upcoming_queue_type, 0, 2); + memory_usage_layout->addWidget(new QLabel(tr("Previous Frame Queue:"), playback_tab), 1, 0); + previous_queue_spinbox = new QDoubleSpinBox(playback_tab); + previous_queue_spinbox->setValue(olive::CurrentConfig.previous_queue_size); + memory_usage_layout->addWidget(previous_queue_spinbox, 1, 1); + previous_queue_type = new QComboBox(playback_tab); + previous_queue_type->addItem(tr("frames")); + previous_queue_type->addItem(tr("seconds")); + previous_queue_type->setCurrentIndex(olive::CurrentConfig.previous_queue_type); + memory_usage_layout->addWidget(previous_queue_type, 1, 2); + playback_tab_layout->addWidget(memory_usage_group); + + tabWidget->addTab(playback_tab, tr("Playback")); + + // Audio + QWidget* audio_tab = new QWidget(this); + + QGridLayout* audio_tab_layout = new QGridLayout(audio_tab); + + audio_tab_layout->addWidget(new QLabel(tr("Output Device:")), 0, 0); + + audio_output_devices = new QComboBox(); + audio_output_devices->addItem(tr("Default"), ""); + + // list all available audio output devices + QList devs = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); + bool found_preferred_device = false; + for (int i=0;iaddItem(devs.at(i).deviceName(), devs.at(i).deviceName()); + if (!found_preferred_device + && devs.at(i).deviceName() == olive::CurrentConfig.preferred_audio_output) { + audio_output_devices->setCurrentIndex(audio_output_devices->count()-1); + found_preferred_device = true; + } + } + + audio_tab_layout->addWidget(audio_output_devices, 0, 1); + + audio_tab_layout->addWidget(new QLabel(tr("Input Device:")), 1, 0); + + audio_input_devices = new QComboBox(); + audio_input_devices->addItem(tr("Default"), ""); + + // list all available audio input devices + devs = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); + found_preferred_device = false; + for (int i=0;iaddItem(devs.at(i).deviceName(), devs.at(i).deviceName()); + if (!found_preferred_device + && devs.at(i).deviceName() == olive::CurrentConfig.preferred_audio_input) { + audio_input_devices->setCurrentIndex(audio_input_devices->count()-1); + found_preferred_device = true; + } + } + + audio_tab_layout->addWidget(audio_input_devices, 1, 1); + + audio_tab_layout->addWidget(new QLabel(tr("Sample Rate:")), 2, 0); + + audio_sample_rate = new QComboBox(); + combobox_audio_sample_rates(audio_sample_rate); + for (int i=0;icount();i++) { + if (audio_sample_rate->itemData(i).toInt() == olive::CurrentConfig.audio_rate) { + audio_sample_rate->setCurrentIndex(i); + break; + } + } + + audio_tab_layout->addWidget(audio_sample_rate, 2, 1); + + tabWidget->addTab(audio_tab, tr("Audio")); + + // Shortcuts + QWidget* shortcut_tab = new QWidget(this); + + QVBoxLayout* shortcut_layout = new QVBoxLayout(shortcut_tab); + + QLineEdit* key_search_line = new QLineEdit(shortcut_tab); + key_search_line->setPlaceholderText(tr("Search for action or shortcut")); + connect(key_search_line, SIGNAL(textChanged(const QString &)), this, SLOT(refine_shortcut_list(const QString &))); + + shortcut_layout->addWidget(key_search_line); + + keyboard_tree = new QTreeWidget(shortcut_tab); + QTreeWidgetItem* tree_header = keyboard_tree->headerItem(); + tree_header->setText(0, tr("Action")); + tree_header->setText(1, tr("Shortcut")); + shortcut_layout->addWidget(keyboard_tree); + + QHBoxLayout* reset_shortcut_layout = new QHBoxLayout(shortcut_tab); + + QPushButton* import_shortcut_button = new QPushButton(tr("Import"), shortcut_tab); + reset_shortcut_layout->addWidget(import_shortcut_button); + connect(import_shortcut_button, SIGNAL(clicked(bool)), this, SLOT(load_shortcut_file())); - QPushButton* export_shortcut_button = new QPushButton(tr("Export"), shortcut_tab); - reset_shortcut_layout->addWidget(export_shortcut_button); - connect(export_shortcut_button, SIGNAL(clicked(bool)), this, SLOT(save_shortcut_file())); + QPushButton* export_shortcut_button = new QPushButton(tr("Export"), shortcut_tab); + reset_shortcut_layout->addWidget(export_shortcut_button); + connect(export_shortcut_button, SIGNAL(clicked(bool)), this, SLOT(save_shortcut_file())); - reset_shortcut_layout->addStretch(); + reset_shortcut_layout->addStretch(); - QPushButton* reset_selected_shortcut_button = new QPushButton(tr("Reset Selected"), shortcut_tab); - reset_shortcut_layout->addWidget(reset_selected_shortcut_button); - connect(reset_selected_shortcut_button, SIGNAL(clicked(bool)), this, SLOT(reset_default_shortcut())); + QPushButton* reset_selected_shortcut_button = new QPushButton(tr("Reset Selected"), shortcut_tab); + reset_shortcut_layout->addWidget(reset_selected_shortcut_button); + connect(reset_selected_shortcut_button, SIGNAL(clicked(bool)), this, SLOT(reset_default_shortcut())); - QPushButton* reset_all_shortcut_button = new QPushButton(tr("Reset All"), shortcut_tab); - reset_shortcut_layout->addWidget(reset_all_shortcut_button); - connect(reset_all_shortcut_button, SIGNAL(clicked(bool)), this, SLOT(reset_all_shortcuts())); + QPushButton* reset_all_shortcut_button = new QPushButton(tr("Reset All"), shortcut_tab); + reset_shortcut_layout->addWidget(reset_all_shortcut_button); + connect(reset_all_shortcut_button, SIGNAL(clicked(bool)), this, SLOT(reset_all_shortcuts())); - shortcut_layout->addLayout(reset_shortcut_layout); + shortcut_layout->addLayout(reset_shortcut_layout); - tabWidget->addTab(shortcut_tab, tr("Keyboard")); + tabWidget->addTab(shortcut_tab, tr("Keyboard")); - verticalLayout->addWidget(tabWidget); + verticalLayout->addWidget(tabWidget); - QDialogButtonBox* buttonBox = new QDialogButtonBox(this); - buttonBox->setOrientation(Qt::Horizontal); - buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + QDialogButtonBox* buttonBox = new QDialogButtonBox(this); + buttonBox->setOrientation(Qt::Horizontal); + buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); - verticalLayout->addWidget(buttonBox); + verticalLayout->addWidget(buttonBox); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(save())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(save())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); } diff --git a/dialogs/preferencesdialog.h b/dialogs/preferencesdialog.h index 8aa3d232a..03d7bd4e5 100644 --- a/dialogs/preferencesdialog.h +++ b/dialogs/preferencesdialog.h @@ -35,68 +35,68 @@ #include class KeySequenceEditor : public QKeySequenceEdit { - Q_OBJECT + Q_OBJECT public: - KeySequenceEditor(QWidget *parent, QAction* a); - void set_action_shortcut(); - void reset_to_default(); - QString action_name(); - QString export_shortcut(); + KeySequenceEditor(QWidget *parent, QAction* a); + void set_action_shortcut(); + void reset_to_default(); + QString action_name(); + QString export_shortcut(); private: - QAction* action; + QAction* action; }; class PreferencesDialog : public QDialog { - Q_OBJECT + Q_OBJECT public: - explicit PreferencesDialog(QWidget *parent = nullptr); - ~PreferencesDialog(); + explicit PreferencesDialog(QWidget *parent = nullptr); + ~PreferencesDialog(); - void setup_kbd_shortcuts(QMenuBar* menu); + void setup_kbd_shortcuts(QMenuBar* menu); private slots: - void save(); - void reset_default_shortcut(); - void reset_all_shortcuts(); - bool refine_shortcut_list(const QString &, QTreeWidgetItem* parent = nullptr); - void load_shortcut_file(); - void save_shortcut_file(); - void browse_css_file(); - void delete_all_previews(); + void save(); + void reset_default_shortcut(); + void reset_all_shortcuts(); + bool refine_shortcut_list(const QString &, QTreeWidgetItem* parent = nullptr); + void load_shortcut_file(); + void save_shortcut_file(); + void browse_css_file(); + void delete_all_previews(); private: - void setup_ui(); - void setup_kbd_shortcut_worker(QMenu* menu, QTreeWidgetItem* parent); + void setup_ui(); + void setup_kbd_shortcut_worker(QMenu* menu, QTreeWidgetItem* parent); - // used to delete previews - // type can be: 't' for thumbnails, 'w' for waveforms, or 1 for all - void delete_previews(char type); + // used to delete previews + // type can be: 't' for thumbnails, 'w' for waveforms, or 1 for all + void delete_previews(char type); - QLineEdit* custom_css_fn; - QLineEdit* imgSeqFormatEdit; - QComboBox* recordingComboBox; - QRadioButton* accurateSeekButton; - QRadioButton* fastSeekButton; - QTreeWidget* keyboard_tree; - QDoubleSpinBox* upcoming_queue_spinbox; - QComboBox* upcoming_queue_type; - QDoubleSpinBox* previous_queue_spinbox; - QComboBox* previous_queue_type; - QSpinBox* effect_textbox_lines_field; - QCheckBox* use_software_fallbacks_checkbox; - QComboBox* audio_output_devices; - QComboBox* audio_input_devices; - QComboBox* audio_sample_rate; - QComboBox* language_combobox; - QSpinBox* thumbnail_res_spinbox; - QSpinBox* waveform_res_spinbox; - QCheckBox* add_default_effects_to_clips; + QLineEdit* custom_css_fn; + QLineEdit* imgSeqFormatEdit; + QComboBox* recordingComboBox; + QRadioButton* accurateSeekButton; + QRadioButton* fastSeekButton; + QTreeWidget* keyboard_tree; + QDoubleSpinBox* upcoming_queue_spinbox; + QComboBox* upcoming_queue_type; + QDoubleSpinBox* previous_queue_spinbox; + QComboBox* previous_queue_type; + QSpinBox* effect_textbox_lines_field; + QCheckBox* use_software_fallbacks_checkbox; + QComboBox* audio_output_devices; + QComboBox* audio_input_devices; + QComboBox* audio_sample_rate; + QComboBox* language_combobox; + QSpinBox* thumbnail_res_spinbox; + QSpinBox* waveform_res_spinbox; + QCheckBox* add_default_effects_to_clips; - QVector key_shortcut_actions; - QVector key_shortcut_items; - QVector key_shortcut_fields; + QVector key_shortcut_actions; + QVector key_shortcut_items; + QVector key_shortcut_fields; }; #endif // PREFERENCESDIALOG_H diff --git a/mainwindow.cpp b/mainwindow.cpp index 6eedb0426..169b9d087 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -71,893 +71,877 @@ MainWindow* olive::MainWindow; #define DEFAULT_CSS "QPushButton::checked { background: rgb(25, 25, 25); }" void MainWindow::setup_layout(bool reset) { - panel_project->show(); - panel_effect_controls->show(); - panel_footage_viewer->show(); - panel_sequence_viewer->show(); - panel_timeline->show(); - panel_graph_editor->hide(); + panel_project->show(); + panel_effect_controls->show(); + panel_footage_viewer->show(); + panel_sequence_viewer->show(); + panel_timeline->show(); + panel_graph_editor->hide(); - addDockWidget(Qt::TopDockWidgetArea, panel_project); - addDockWidget(Qt::TopDockWidgetArea, panel_graph_editor); - addDockWidget(Qt::TopDockWidgetArea, panel_footage_viewer); - tabifyDockWidget(panel_footage_viewer, panel_effect_controls); - panel_footage_viewer->raise(); - addDockWidget(Qt::TopDockWidgetArea, panel_sequence_viewer); - addDockWidget(Qt::BottomDockWidgetArea, panel_timeline); + addDockWidget(Qt::TopDockWidgetArea, panel_project); + addDockWidget(Qt::TopDockWidgetArea, panel_graph_editor); + addDockWidget(Qt::TopDockWidgetArea, panel_footage_viewer); + tabifyDockWidget(panel_footage_viewer, panel_effect_controls); + panel_footage_viewer->raise(); + addDockWidget(Qt::TopDockWidgetArea, panel_sequence_viewer); + addDockWidget(Qt::BottomDockWidgetArea, panel_timeline); - // load panels from file - if (!reset) { - QFile panel_config(get_config_path() + "/layout"); - if (panel_config.exists() && panel_config.open(QFile::ReadOnly)) { - restoreState(panel_config.readAll(), 0); - panel_config.close(); - } - } + // load panels from file + if (!reset) { + QFile panel_config(get_config_path() + "/layout"); + if (panel_config.exists() && panel_config.open(QFile::ReadOnly)) { + restoreState(panel_config.readAll(), 0); + panel_config.close(); + } + } - layout()->update(); + layout()->update(); } MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), - first_show(true) + QMainWindow(parent), + first_show(true) { - qRegisterMetaType(); + qRegisterMetaType(); - init_custom_cursors(); + init_custom_cursors(); - open_debug_file(); + open_debug_file(); - olive::DebugDialog = new DebugDialog(this); + olive::DebugDialog = new DebugDialog(this); - olive::MainWindow = this; + olive::MainWindow = this; - // set up style? + // set up style? - qApp->setStyle(QStyleFactory::create("Fusion")); - setStyleSheet(DEFAULT_CSS); + qApp->setStyle(QStyleFactory::create("Fusion")); + setStyleSheet(DEFAULT_CSS); - QPalette darkPalette; - darkPalette.setColor(QPalette::Window, QColor(53,53,53)); - darkPalette.setColor(QPalette::WindowText, Qt::white); - darkPalette.setColor(QPalette::Base, QColor(25,25,25)); - darkPalette.setColor(QPalette::AlternateBase, QColor(53,53,53)); - darkPalette.setColor(QPalette::ToolTipBase, QColor(25,25,25)); - darkPalette.setColor(QPalette::ToolTipText, Qt::white); - darkPalette.setColor(QPalette::Text, Qt::white); - darkPalette.setColor(QPalette::Button, QColor(53,53,53)); - darkPalette.setColor(QPalette::ButtonText, Qt::white); darkPalette.setColor(QPalette::BrightText, Qt::red); - darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(128, 128, 128)); - darkPalette.setColor(QPalette::Link, QColor(42, 130, 218)); - darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218)); - darkPalette.setColor(QPalette::HighlightedText, Qt::black); + QPalette darkPalette; + darkPalette.setColor(QPalette::Window, QColor(53,53,53)); + darkPalette.setColor(QPalette::WindowText, Qt::white); + darkPalette.setColor(QPalette::Base, QColor(25,25,25)); + darkPalette.setColor(QPalette::AlternateBase, QColor(53,53,53)); + darkPalette.setColor(QPalette::ToolTipBase, QColor(25,25,25)); + darkPalette.setColor(QPalette::ToolTipText, Qt::white); + darkPalette.setColor(QPalette::Text, Qt::white); + darkPalette.setColor(QPalette::Button, QColor(53,53,53)); + darkPalette.setColor(QPalette::ButtonText, Qt::white); darkPalette.setColor(QPalette::BrightText, Qt::red); + darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(128, 128, 128)); + darkPalette.setColor(QPalette::Link, QColor(42, 130, 218)); + darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218)); + darkPalette.setColor(QPalette::HighlightedText, Qt::black); - qApp->setPalette(darkPalette); + qApp->setPalette(darkPalette); - // end style - QWidget* centralWidget = new QWidget(this); - centralWidget->setMaximumSize(QSize(0, 0)); - setCentralWidget(centralWidget); + // end style + QWidget* centralWidget = new QWidget(this); + centralWidget->setMaximumSize(QSize(0, 0)); + setCentralWidget(centralWidget); - setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); + setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); - setDockNestingEnabled(true); + setDockNestingEnabled(true); - layout()->invalidate(); + layout()->invalidate(); - QString data_dir = get_data_path(); - if (!data_dir.isEmpty()) { - QDir dir(data_dir); - dir.mkpath("."); - if (dir.exists()) { - qint64 a_month_ago = QDateTime::currentMSecsSinceEpoch() - 2592000000; - qint64 a_week_ago = QDateTime::currentMSecsSinceEpoch() - 604800000; + QString data_dir = get_data_path(); + if (!data_dir.isEmpty()) { + QDir dir(data_dir); + dir.mkpath("."); + if (dir.exists()) { + qint64 a_month_ago = QDateTime::currentMSecsSinceEpoch() - 2592000000; + qint64 a_week_ago = QDateTime::currentMSecsSinceEpoch() - 604800000; - // TODO put delete functions in another thread? + // TODO put delete functions in another thread? - // delete auto-recoveries older than 7 days - QStringList old_autorecoveries = dir.entryList(QStringList("autorecovery.ove.*"), QDir::Files); - int deleted_ars = 0; - for (int i=0;i 0) qInfo() << "Deleted" << deleted_ars << "autorecovery" << ((deleted_ars == 1) ? "file that was" : "files that were") << "older than 7 days"; - - // delete previews older than 30 days - QDir preview_dir = QDir(dir.filePath("previews")); - if (preview_dir.exists()) { - deleted_ars = 0; - QStringList old_prevs = preview_dir.entryList(QDir::Files); - for (int i=0;i 0) qInfo() << "Deleted" << deleted_ars << "preview" << ((deleted_ars == 1) ? "file that was" : "files that were") << "last read over 30 days ago"; - } - - // search for open recents list - QFile f(olive::Global->get_recent_project_list_file()); - if (f.exists() && f.open(QFile::ReadOnly | QFile::Text)) { - QTextStream text_stream(&f); - while (true) { - QString line = text_stream.readLine(); - if (line.isNull()) { - break; - } else { - recent_projects.append(line); - } - } - f.close(); - } - } - } - QString config_path = get_config_path(); - if (!config_path.isEmpty()) { - QDir config_dir(config_path); - config_dir.mkpath("."); - QString config_fn = config_dir.filePath("config.xml"); - if (QFileInfo::exists(config_fn)) { - olive::CurrentConfig.load(config_fn); - - if (!olive::CurrentConfig.css_path.isEmpty()) { - load_css_from_file(olive::CurrentConfig.css_path); - } - } - } - - // load preferred language from file - QString language_file = olive::CurrentRuntimeConfig.external_translation_file.isEmpty() ? - olive::CurrentConfig.language_file : - olive::CurrentRuntimeConfig.external_translation_file; - - if (!language_file.isEmpty()) { - - // translation files are stored relative to app path (see GitHub issue #454) - QString full_language_path = QDir(get_app_path()).filePath(language_file); - - if (QFileInfo::exists(full_language_path)) { - QTranslator* translator = new QTranslator(this); - translator->load(full_language_path); - QApplication::installTranslator(translator); - } else { - qWarning() << "Failed to load translation file" << full_language_path << ". No language will be loaded."; + // delete auto-recoveries older than 7 days + QStringList old_autorecoveries = dir.entryList(QStringList("autorecovery.ove.*"), QDir::Files); + int deleted_ars = 0; + for (int i=0;i 0) qInfo() << "Deleted" << deleted_ars << "autorecovery" << ((deleted_ars == 1) ? "file that was" : "files that were") << "older than 7 days"; - alloc_panels(this); + // delete previews older than 30 days + QDir preview_dir = QDir(dir.filePath("previews")); + if (preview_dir.exists()) { + deleted_ars = 0; + QStringList old_prevs = preview_dir.entryList(QDir::Files); + for (int i=0;i 0) qInfo() << "Deleted" << deleted_ars << "preview" << ((deleted_ars == 1) ? "file that was" : "files that were") << "last read over 30 days ago"; + } - QStatusBar* statusBar = new QStatusBar(this); - statusBar->showMessage(tr("Welcome to %1").arg(olive::AppName)); - setStatusBar(statusBar); + // search for open recents list + QFile f(olive::Global->get_recent_project_list_file()); + if (f.exists() && f.open(QFile::ReadOnly | QFile::Text)) { + QTextStream text_stream(&f); + while (true) { + QString line = text_stream.readLine(); + if (line.isNull()) { + break; + } else { + recent_projects.append(line); + } + } + f.close(); + } + } + } + QString config_path = get_config_path(); + if (!config_path.isEmpty()) { + QDir config_dir(config_path); + config_dir.mkpath("."); + QString config_fn = config_dir.filePath("config.xml"); + if (QFileInfo::exists(config_fn)) { + olive::CurrentConfig.load(config_fn); - // populate menu bars - setup_menus(); + if (!olive::CurrentConfig.css_path.isEmpty()) { + load_css_from_file(olive::CurrentConfig.css_path); + } + } + } - olive::Global->check_for_autorecovery_file(); + // load preferred language from file + olive::Global->load_translation_from_config(); - // set up panel layout - setup_layout(false); + alloc_panels(this); - // set up output audio device - init_audio(); + QStatusBar* statusBar = new QStatusBar(this); + statusBar->showMessage(tr("Welcome to %1").arg(olive::AppName)); + setStatusBar(statusBar); - // start omnipotent proxy generator process - proxy_generator.start(); + // populate menu bars + setup_menus(); - // set default window title - updateTitle(); + olive::Global->check_for_autorecovery_file(); + + // set up panel layout + setup_layout(false); + + // set up output audio device + init_audio(); + + // start omnipotent proxy generator process + proxy_generator.start(); + + // set default window title + updateTitle(); } MainWindow::~MainWindow() { - free_panels(); - close_debug_file(); + free_panels(); + close_debug_file(); } void kbd_shortcut_processor(QByteArray& file, QMenu* menu, bool save, bool first) { - QList actions = menu->actions(); - for (int i=0;imenu() != nullptr) { - kbd_shortcut_processor(file, a->menu(), save, first); - } else if (!a->isSeparator()) { - if (save) { - // saving custom shortcuts - if (!a->property("default").isNull()) { - QKeySequence defks(a->property("default").toString()); - if (a->shortcut() != defks) { - // custom shortcut - if (!file.isEmpty()) file.append('\n'); - file.append(a->property("id").toString()); - file.append('\t'); - file.append(a->shortcut().toString()); - } - } - } else { - // loading custom shortcuts - if (first) { - // store default shortcut - a->setProperty("default", a->shortcut().toString()); - } else { - // restore default shortcut - a->setShortcut(a->property("default").toString()); - } - if (!a->property("id").isNull()) { - QString comp_str = a->property("id").toString(); - int shortcut_index = file.indexOf(comp_str); - if (shortcut_index == 0 || (shortcut_index > 0 && file.at(shortcut_index-1) == '\n')) { - shortcut_index += comp_str.size() + 1; - QString shortcut; - while (shortcut_index < file.size() && file.at(shortcut_index) != '\n') { - shortcut.append(file.at(shortcut_index)); - shortcut_index++; - } - QKeySequence ks(shortcut); - if (!ks.isEmpty()) { - a->setShortcut(ks); - } - } - } - a->setShortcutContext(Qt::ApplicationShortcut); - } - } - } + QList actions = menu->actions(); + for (int i=0;imenu() != nullptr) { + kbd_shortcut_processor(file, a->menu(), save, first); + } else if (!a->isSeparator()) { + if (save) { + // saving custom shortcuts + if (!a->property("default").isNull()) { + QKeySequence defks(a->property("default").toString()); + if (a->shortcut() != defks) { + // custom shortcut + if (!file.isEmpty()) file.append('\n'); + file.append(a->property("id").toString()); + file.append('\t'); + file.append(a->shortcut().toString()); + } + } + } else { + // loading custom shortcuts + if (first) { + // store default shortcut + a->setProperty("default", a->shortcut().toString()); + } else { + // restore default shortcut + a->setShortcut(a->property("default").toString()); + } + if (!a->property("id").isNull()) { + QString comp_str = a->property("id").toString(); + int shortcut_index = file.indexOf(comp_str); + if (shortcut_index == 0 || (shortcut_index > 0 && file.at(shortcut_index-1) == '\n')) { + shortcut_index += comp_str.size() + 1; + QString shortcut; + while (shortcut_index < file.size() && file.at(shortcut_index) != '\n') { + shortcut.append(file.at(shortcut_index)); + shortcut_index++; + } + QKeySequence ks(shortcut); + if (!ks.isEmpty()) { + a->setShortcut(ks); + } + } + } + a->setShortcutContext(Qt::ApplicationShortcut); + } + } + } } void MainWindow::load_shortcuts(const QString& fn) { - QByteArray shortcut_bytes; - QFile shortcut_path(fn); - if (shortcut_path.exists() && shortcut_path.open(QFile::ReadOnly)) { - shortcut_bytes = shortcut_path.readAll(); - shortcut_path.close(); - } - QList menus = menuBar()->actions(); - for (int i=0;imenu(); - kbd_shortcut_processor(shortcut_bytes, menu, false, true); - } + QByteArray shortcut_bytes; + QFile shortcut_path(fn); + if (shortcut_path.exists() && shortcut_path.open(QFile::ReadOnly)) { + shortcut_bytes = shortcut_path.readAll(); + shortcut_path.close(); + } + QList menus = menuBar()->actions(); + for (int i=0;imenu(); + kbd_shortcut_processor(shortcut_bytes, menu, false, true); + } } void MainWindow::save_shortcuts(const QString& fn) { - // save main menu actions - QList menus = menuBar()->actions(); - QByteArray shortcut_file; - for (int i=0;imenu(); - kbd_shortcut_processor(shortcut_file, menu, true, false); - } - QFile shortcut_file_io(fn); - if (shortcut_file_io.open(QFile::WriteOnly)) { - shortcut_file_io.write(shortcut_file); - shortcut_file_io.close(); - } else { - qCritical() << "Failed to save shortcut file"; - } + // save main menu actions + QList menus = menuBar()->actions(); + QByteArray shortcut_file; + for (int i=0;imenu(); + kbd_shortcut_processor(shortcut_file, menu, true, false); + } + QFile shortcut_file_io(fn); + if (shortcut_file_io.open(QFile::WriteOnly)) { + shortcut_file_io.write(shortcut_file); + shortcut_file_io.close(); + } else { + qCritical() << "Failed to save shortcut file"; + } } void MainWindow::load_css_from_file(const QString &fn) { - QFile css_file(fn); - if (css_file.exists() && css_file.open(QFile::ReadOnly)) { - setStyleSheet(css_file.readAll()); - css_file.close(); - } else { - // set default stylesheet - setStyleSheet(DEFAULT_CSS); - } + QFile css_file(fn); + if (css_file.exists() && css_file.open(QFile::ReadOnly)) { + setStyleSheet(css_file.readAll()); + css_file.close(); + } else { + // set default stylesheet + setStyleSheet(DEFAULT_CSS); + } } void MainWindow::editMenu_About_To_Be_Shown() { - undo_action->setEnabled(olive::UndoStack.canUndo()); - redo_action->setEnabled(olive::UndoStack.canRedo()); + undo_action->setEnabled(olive::UndoStack.canUndo()); + redo_action->setEnabled(olive::UndoStack.canRedo()); } void MainWindow::setup_menus() { - QMenuBar* menuBar = new QMenuBar(this); - setMenuBar(menuBar); + QMenuBar* menuBar = new QMenuBar(this); + setMenuBar(menuBar); - // INITIALIZE FILE MENU + // INITIALIZE FILE MENU - QMenu* file_menu = menuBar->addMenu(tr("&File")); - connect(file_menu, SIGNAL(aboutToShow()), this, SLOT(fileMenu_About_To_Be_Shown())); + QMenu* file_menu = menuBar->addMenu(tr("&File")); + connect(file_menu, SIGNAL(aboutToShow()), this, SLOT(fileMenu_About_To_Be_Shown())); - QMenu* new_menu = file_menu->addMenu(tr("&New")); - olive::MenuHelper.make_new_menu(new_menu); + QMenu* new_menu = file_menu->addMenu(tr("&New")); + olive::MenuHelper.make_new_menu(new_menu); - file_menu->addAction(tr("&Open Project"), olive::Global.get(), SLOT(open_project()), QKeySequence("Ctrl+O"))->setProperty("id", "openproj"); + file_menu->addAction(tr("&Open Project"), olive::Global.get(), SLOT(open_project()), QKeySequence("Ctrl+O"))->setProperty("id", "openproj"); - clear_open_recent_action = new QAction(tr("Clear Recent List"), menuBar); - clear_open_recent_action->setProperty("id", "clearopenrecent"); - connect(clear_open_recent_action, SIGNAL(triggered()), panel_project, SLOT(clear_recent_projects())); + clear_open_recent_action = new QAction(tr("Clear Recent List"), menuBar); + clear_open_recent_action->setProperty("id", "clearopenrecent"); + connect(clear_open_recent_action, SIGNAL(triggered()), panel_project, SLOT(clear_recent_projects())); - open_recent = file_menu->addMenu(tr("Open Recent")); + open_recent = file_menu->addMenu(tr("Open Recent")); - open_recent->addAction(clear_open_recent_action); + open_recent->addAction(clear_open_recent_action); - file_menu->addAction(tr("&Save Project"), olive::Global.get(), SLOT(save_project()), QKeySequence("Ctrl+S"))->setProperty("id", "saveproj"); - file_menu->addAction(tr("Save Project &As"), olive::Global.get(), SLOT(save_project_as()), QKeySequence("Ctrl+Shift+S"))->setProperty("id", "saveprojas"); + file_menu->addAction(tr("&Save Project"), olive::Global.get(), SLOT(save_project()), QKeySequence("Ctrl+S"))->setProperty("id", "saveproj"); + file_menu->addAction(tr("Save Project &As"), olive::Global.get(), SLOT(save_project_as()), QKeySequence("Ctrl+Shift+S"))->setProperty("id", "saveprojas"); - file_menu->addSeparator(); + file_menu->addSeparator(); - file_menu->addAction(tr("&Import..."), panel_project, SLOT(import_dialog()), QKeySequence("Ctrl+I"))->setProperty("id", "import"); + file_menu->addAction(tr("&Import..."), panel_project, SLOT(import_dialog()), QKeySequence("Ctrl+I"))->setProperty("id", "import"); - file_menu->addSeparator(); + file_menu->addSeparator(); - file_menu->addAction(tr("&Export..."), olive::Global.get(), SLOT(open_export_dialog()), QKeySequence("Ctrl+M"))->setProperty("id", "export"); + file_menu->addAction(tr("&Export..."), olive::Global.get(), SLOT(open_export_dialog()), QKeySequence("Ctrl+M"))->setProperty("id", "export"); - file_menu->addSeparator(); + file_menu->addSeparator(); - file_menu->addAction(tr("E&xit"), this, SLOT(close()))->setProperty("id", "exit"); + file_menu->addAction(tr("E&xit"), this, SLOT(close()))->setProperty("id", "exit"); - // INITIALIZE EDIT MENU + // INITIALIZE EDIT MENU - QMenu* edit_menu = menuBar->addMenu(tr("&Edit")); - connect(edit_menu, SIGNAL(aboutToShow()), this, SLOT(editMenu_About_To_Be_Shown())); + QMenu* edit_menu = menuBar->addMenu(tr("&Edit")); + connect(edit_menu, SIGNAL(aboutToShow()), this, SLOT(editMenu_About_To_Be_Shown())); - undo_action = edit_menu->addAction(tr("&Undo"), olive::Global.get(), SLOT(undo()), QKeySequence("Ctrl+Z")); - undo_action->setProperty("id", "undo"); - redo_action = edit_menu->addAction(tr("Redo"), olive::Global.get(), SLOT(redo()), QKeySequence("Ctrl+Shift+Z")); - redo_action->setProperty("id", "redo"); + undo_action = edit_menu->addAction(tr("&Undo"), olive::Global.get(), SLOT(undo()), QKeySequence("Ctrl+Z")); + undo_action->setProperty("id", "undo"); + redo_action = edit_menu->addAction(tr("Redo"), olive::Global.get(), SLOT(redo()), QKeySequence("Ctrl+Shift+Z")); + redo_action->setProperty("id", "redo"); - edit_menu->addSeparator(); + edit_menu->addSeparator(); - olive::MenuHelper.make_edit_functions_menu(edit_menu); + olive::MenuHelper.make_edit_functions_menu(edit_menu); - edit_menu->addSeparator(); + edit_menu->addSeparator(); - edit_menu->addAction(tr("Select &All"), &olive::FocusFilter, SLOT(select_all()), QKeySequence("Ctrl+A"))->setProperty("id", "selectall"); + edit_menu->addAction(tr("Select &All"), &olive::FocusFilter, SLOT(select_all()), QKeySequence("Ctrl+A"))->setProperty("id", "selectall"); - edit_menu->addAction(tr("Deselect All"), panel_timeline, SLOT(deselect()), QKeySequence("Ctrl+Shift+A"))->setProperty("id", "deselectall"); + edit_menu->addAction(tr("Deselect All"), panel_timeline, SLOT(deselect()), QKeySequence("Ctrl+Shift+A"))->setProperty("id", "deselectall"); - edit_menu->addSeparator(); + edit_menu->addSeparator(); - olive::MenuHelper.make_clip_functions_menu(edit_menu); + olive::MenuHelper.make_clip_functions_menu(edit_menu); - edit_menu->addSeparator(); + edit_menu->addSeparator(); - edit_menu->addAction(tr("Ripple to In Point"), panel_timeline, SLOT(ripple_to_in_point()), QKeySequence("Q"))->setProperty("id", "rippletoin"); - edit_menu->addAction(tr("Ripple to Out Point"), panel_timeline, SLOT(ripple_to_out_point()), QKeySequence("W"))->setProperty("id", "rippletoout"); - edit_menu->addAction(tr("Edit to In Point"), panel_timeline, SLOT(edit_to_in_point()), QKeySequence("Ctrl+Alt+Q"))->setProperty("id", "edittoin"); - edit_menu->addAction(tr("Edit to Out Point"), panel_timeline, SLOT(edit_to_out_point()), QKeySequence("Ctrl+Alt+W"))->setProperty("id", "edittoout"); + edit_menu->addAction(tr("Ripple to In Point"), panel_timeline, SLOT(ripple_to_in_point()), QKeySequence("Q"))->setProperty("id", "rippletoin"); + edit_menu->addAction(tr("Ripple to Out Point"), panel_timeline, SLOT(ripple_to_out_point()), QKeySequence("W"))->setProperty("id", "rippletoout"); + edit_menu->addAction(tr("Edit to In Point"), panel_timeline, SLOT(edit_to_in_point()), QKeySequence("Ctrl+Alt+Q"))->setProperty("id", "edittoin"); + edit_menu->addAction(tr("Edit to Out Point"), panel_timeline, SLOT(edit_to_out_point()), QKeySequence("Ctrl+Alt+W"))->setProperty("id", "edittoout"); - edit_menu->addSeparator(); + edit_menu->addSeparator(); - olive::MenuHelper.make_inout_menu(edit_menu); - edit_menu->addAction(tr("Delete In/Out Point"), panel_timeline, SLOT(delete_inout()), QKeySequence(";"))->setProperty("id", "deleteinout"); - edit_menu->addAction(tr("Ripple Delete In/Out Point"), panel_timeline, SLOT(ripple_delete_inout()), QKeySequence("'"))->setProperty("id", "rippledeleteinout"); + olive::MenuHelper.make_inout_menu(edit_menu); + edit_menu->addAction(tr("Delete In/Out Point"), panel_timeline, SLOT(delete_inout()), QKeySequence(";"))->setProperty("id", "deleteinout"); + edit_menu->addAction(tr("Ripple Delete In/Out Point"), panel_timeline, SLOT(ripple_delete_inout()), QKeySequence("'"))->setProperty("id", "rippledeleteinout"); - edit_menu->addSeparator(); + edit_menu->addSeparator(); - edit_menu->addAction(tr("Set/Edit Marker"), &olive::FocusFilter, SLOT(set_marker()), QKeySequence("M"))->setProperty("id", "marker"); + edit_menu->addAction(tr("Set/Edit Marker"), &olive::FocusFilter, SLOT(set_marker()), QKeySequence("M"))->setProperty("id", "marker"); - // INITIALIZE VIEW MENU + // INITIALIZE VIEW MENU - QMenu* view_menu = menuBar->addMenu(tr("&View")); - connect(view_menu, SIGNAL(aboutToShow()), this, SLOT(viewMenu_About_To_Be_Shown())); + QMenu* view_menu = menuBar->addMenu(tr("&View")); + connect(view_menu, SIGNAL(aboutToShow()), this, SLOT(viewMenu_About_To_Be_Shown())); - view_menu->addAction(tr("Zoom In"), &olive::FocusFilter, SLOT(zoom_in()), QKeySequence("="))->setProperty("id", "zoomin"); - view_menu->addAction(tr("Zoom Out"), &olive::FocusFilter, SLOT(zoom_out()), QKeySequence("-"))->setProperty("id", "zoomout"); - view_menu->addAction(tr("Increase Track Height"), panel_timeline, SLOT(increase_track_height()), QKeySequence("Ctrl+="))->setProperty("id", "vzoomin"); - view_menu->addAction(tr("Decrease Track Height"), panel_timeline, SLOT(decrease_track_height()), QKeySequence("Ctrl+-"))->setProperty("id", "vzoomout"); + view_menu->addAction(tr("Zoom In"), &olive::FocusFilter, SLOT(zoom_in()), QKeySequence("="))->setProperty("id", "zoomin"); + view_menu->addAction(tr("Zoom Out"), &olive::FocusFilter, SLOT(zoom_out()), QKeySequence("-"))->setProperty("id", "zoomout"); + view_menu->addAction(tr("Increase Track Height"), panel_timeline, SLOT(increase_track_height()), QKeySequence("Ctrl+="))->setProperty("id", "vzoomin"); + view_menu->addAction(tr("Decrease Track Height"), panel_timeline, SLOT(decrease_track_height()), QKeySequence("Ctrl+-"))->setProperty("id", "vzoomout"); - show_all = view_menu->addAction(tr("Toggle Show All"), panel_timeline, SLOT(toggle_show_all()), QKeySequence("\\")); - show_all->setProperty("id", "showall"); - show_all->setCheckable(true); + show_all = view_menu->addAction(tr("Toggle Show All"), panel_timeline, SLOT(toggle_show_all()), QKeySequence("\\")); + show_all->setProperty("id", "showall"); + show_all->setCheckable(true); - view_menu->addSeparator(); + view_menu->addSeparator(); - track_lines = view_menu->addAction(tr("Track Lines"), &olive::MenuHelper, SLOT(toggle_bool_action())); - track_lines->setProperty("id", "tracklines"); - track_lines->setCheckable(true); - track_lines->setData(reinterpret_cast(&olive::CurrentConfig.show_track_lines)); + track_lines = view_menu->addAction(tr("Track Lines"), &olive::MenuHelper, SLOT(toggle_bool_action())); + track_lines->setProperty("id", "tracklines"); + track_lines->setCheckable(true); + track_lines->setData(reinterpret_cast(&olive::CurrentConfig.show_track_lines)); - rectified_waveforms = view_menu->addAction(tr("Rectified Waveforms"), &olive::MenuHelper, SLOT(toggle_bool_action())); - rectified_waveforms->setProperty("id", "rectifiedwaveforms"); - rectified_waveforms->setCheckable(true); - rectified_waveforms->setData(reinterpret_cast(&olive::CurrentConfig.rectified_waveforms)); + rectified_waveforms = view_menu->addAction(tr("Rectified Waveforms"), &olive::MenuHelper, SLOT(toggle_bool_action())); + rectified_waveforms->setProperty("id", "rectifiedwaveforms"); + rectified_waveforms->setCheckable(true); + rectified_waveforms->setData(reinterpret_cast(&olive::CurrentConfig.rectified_waveforms)); - view_menu->addSeparator(); + view_menu->addSeparator(); - frames_action = view_menu->addAction(tr("Frames"), &olive::MenuHelper, SLOT(set_timecode_view())); - frames_action->setProperty("id", "modeframes"); - frames_action->setData(TIMECODE_FRAMES); - frames_action->setCheckable(true); - drop_frame_action = view_menu->addAction(tr("Drop Frame"), &olive::MenuHelper, SLOT(set_timecode_view())); - drop_frame_action->setProperty("id", "modedropframe"); - drop_frame_action->setData(TIMECODE_DROP); - drop_frame_action->setCheckable(true); - nondrop_frame_action = view_menu->addAction(tr("Non-Drop Frame"), &olive::MenuHelper, SLOT(set_timecode_view())); - nondrop_frame_action->setProperty("id", "modenondropframe"); - nondrop_frame_action->setData(TIMECODE_NONDROP); - nondrop_frame_action->setCheckable(true); - milliseconds_action = view_menu->addAction(tr("Milliseconds"), &olive::MenuHelper, SLOT(set_timecode_view())); - milliseconds_action->setProperty("id", "milliseconds"); - milliseconds_action->setData(TIMECODE_MILLISECONDS); - milliseconds_action->setCheckable(true); + frames_action = view_menu->addAction(tr("Frames"), &olive::MenuHelper, SLOT(set_timecode_view())); + frames_action->setProperty("id", "modeframes"); + frames_action->setData(TIMECODE_FRAMES); + frames_action->setCheckable(true); + drop_frame_action = view_menu->addAction(tr("Drop Frame"), &olive::MenuHelper, SLOT(set_timecode_view())); + drop_frame_action->setProperty("id", "modedropframe"); + drop_frame_action->setData(TIMECODE_DROP); + drop_frame_action->setCheckable(true); + nondrop_frame_action = view_menu->addAction(tr("Non-Drop Frame"), &olive::MenuHelper, SLOT(set_timecode_view())); + nondrop_frame_action->setProperty("id", "modenondropframe"); + nondrop_frame_action->setData(TIMECODE_NONDROP); + nondrop_frame_action->setCheckable(true); + milliseconds_action = view_menu->addAction(tr("Milliseconds"), &olive::MenuHelper, SLOT(set_timecode_view())); + milliseconds_action->setProperty("id", "milliseconds"); + milliseconds_action->setData(TIMECODE_MILLISECONDS); + milliseconds_action->setCheckable(true); - view_menu->addSeparator(); + view_menu->addSeparator(); - QMenu* title_safe_area_menu = view_menu->addMenu(tr("Title/Action Safe Area")); + QMenu* title_safe_area_menu = view_menu->addMenu(tr("Title/Action Safe Area")); - title_safe_off = title_safe_area_menu->addAction(tr("Off")); - title_safe_off->setProperty("id", "titlesafeoff"); - title_safe_off->setCheckable(true); - title_safe_off->setData(qSNaN()); - connect(title_safe_off, SIGNAL(triggered(bool)), &olive::MenuHelper, SLOT(set_titlesafe_from_menu())); + title_safe_off = title_safe_area_menu->addAction(tr("Off")); + title_safe_off->setProperty("id", "titlesafeoff"); + title_safe_off->setCheckable(true); + title_safe_off->setData(qSNaN()); + connect(title_safe_off, SIGNAL(triggered(bool)), &olive::MenuHelper, SLOT(set_titlesafe_from_menu())); - title_safe_default = title_safe_area_menu->addAction(tr("Default")); - title_safe_default->setProperty("id", "titlesafedefault"); - title_safe_default->setCheckable(true); - title_safe_default->setData(0.0); - connect(title_safe_default, SIGNAL(triggered(bool)), &olive::MenuHelper, SLOT(set_titlesafe_from_menu())); + title_safe_default = title_safe_area_menu->addAction(tr("Default")); + title_safe_default->setProperty("id", "titlesafedefault"); + title_safe_default->setCheckable(true); + title_safe_default->setData(0.0); + connect(title_safe_default, SIGNAL(triggered(bool)), &olive::MenuHelper, SLOT(set_titlesafe_from_menu())); - title_safe_43 = title_safe_area_menu->addAction(tr("4:3")); - title_safe_43->setProperty("id", "titlesafe43"); - title_safe_43->setCheckable(true); - title_safe_43->setData(4.0/3.0); - connect(title_safe_43, SIGNAL(triggered(bool)), &olive::MenuHelper, SLOT(set_titlesafe_from_menu())); + title_safe_43 = title_safe_area_menu->addAction(tr("4:3")); + title_safe_43->setProperty("id", "titlesafe43"); + title_safe_43->setCheckable(true); + title_safe_43->setData(4.0/3.0); + connect(title_safe_43, SIGNAL(triggered(bool)), &olive::MenuHelper, SLOT(set_titlesafe_from_menu())); - title_safe_169 = title_safe_area_menu->addAction(tr("16:9")); - title_safe_169->setProperty("id", "titlesafe169"); - title_safe_169->setCheckable(true); - title_safe_169->setData(16.0/9.0); - connect(title_safe_169, SIGNAL(triggered(bool)), &olive::MenuHelper, SLOT(set_titlesafe_from_menu())); + title_safe_169 = title_safe_area_menu->addAction(tr("16:9")); + title_safe_169->setProperty("id", "titlesafe169"); + title_safe_169->setCheckable(true); + title_safe_169->setData(16.0/9.0); + connect(title_safe_169, SIGNAL(triggered(bool)), &olive::MenuHelper, SLOT(set_titlesafe_from_menu())); - title_safe_custom = title_safe_area_menu->addAction(tr("Custom")); - title_safe_custom->setProperty("id", "titlesafecustom"); - title_safe_custom->setCheckable(true); - title_safe_custom->setData(-1.0); - connect(title_safe_custom, SIGNAL(triggered(bool)), &olive::MenuHelper, SLOT(set_titlesafe_from_menu())); - - view_menu->addSeparator(); - - full_screen = view_menu->addAction(tr("Full Screen"), this, SLOT(toggle_full_screen()), QKeySequence("F11")); - full_screen->setProperty("id", "fullscreen"); - full_screen->setCheckable(true); - - view_menu->addAction(tr("Full Screen Viewer"), &olive::FocusFilter, SLOT(set_viewer_fullscreen()))->setProperty("id", "fullscreenviewer"); - - // INITIALIZE PLAYBACK MENU - - QMenu* playback_menu = menuBar->addMenu(tr("&Playback")); - connect(playback_menu, SIGNAL(aboutToShow()), this, SLOT(playbackMenu_About_To_Be_Shown())); - - playback_menu->addAction(tr("Go to Start"), &olive::FocusFilter, SLOT(go_to_start()), QKeySequence("Home"))->setProperty("id", "gotostart"); - playback_menu->addAction(tr("Previous Frame"), &olive::FocusFilter, SLOT(prev_frame()), QKeySequence("Left"))->setProperty("id", "prevframe"); - playback_menu->addAction(tr("Play/Pause"), &olive::FocusFilter, SLOT(playpause()), QKeySequence("Space"))->setProperty("id", "playpause"); - playback_menu->addAction(tr("Play In to Out"), &olive::FocusFilter, SLOT(play_in_to_out()), QKeySequence("Shift+Space"))->setProperty("id", "playintoout"); - playback_menu->addAction(tr("Next Frame"), &olive::FocusFilter, SLOT(next_frame()), QKeySequence("Right"))->setProperty("id", "nextframe"); - playback_menu->addAction(tr("Go to End"), &olive::FocusFilter, SLOT(go_to_end()), QKeySequence("End"))->setProperty("id", "gotoend"); - playback_menu->addSeparator(); - playback_menu->addAction(tr("Go to Previous Cut"), panel_timeline, SLOT(previous_cut()), QKeySequence("Up"))->setProperty("id", "prevcut"); - playback_menu->addAction(tr("Go to Next Cut"), panel_timeline, SLOT(next_cut()), QKeySequence("Down"))->setProperty("id", "nextcut"); - playback_menu->addSeparator(); - playback_menu->addAction(tr("Go to In Point"), &olive::FocusFilter, SLOT(go_to_in()), QKeySequence("Shift+I"))->setProperty("id", "gotoin"); - playback_menu->addAction(tr("Go to Out Point"), &olive::FocusFilter, SLOT(go_to_out()), QKeySequence("Shift+O"))->setProperty("id", "gotoout"); - playback_menu->addSeparator(); - playback_menu->addAction(tr("Shuttle Left"), &olive::FocusFilter, SLOT(decrease_speed()), QKeySequence("J"))->setProperty("id", "decspeed"); - playback_menu->addAction(tr("Shuttle Stop"), &olive::FocusFilter, SLOT(pause()), QKeySequence("K"))->setProperty("id", "pause"); - playback_menu->addAction(tr("Shuttle Right"), &olive::FocusFilter, SLOT(increase_speed()), QKeySequence("L"))->setProperty("id", "incspeed"); - playback_menu->addSeparator(); - - loop_action = playback_menu->addAction(tr("Loop"), &olive::MenuHelper, SLOT(toggle_bool_action())); - loop_action->setProperty("id", "loop"); - loop_action->setCheckable(true); - loop_action->setData(reinterpret_cast(&olive::CurrentConfig.loop)); - - // INITIALIZE WINDOW MENU - - window_menu = menuBar->addMenu(tr("&Window")); - connect(window_menu, SIGNAL(aboutToShow()), this, SLOT(windowMenu_About_To_Be_Shown())); - - QAction* window_project_action = window_menu->addAction(tr("Project"), this, SLOT(toggle_panel_visibility())); - window_project_action->setProperty("id", "panelproject"); - window_project_action->setCheckable(true); - window_project_action->setData(reinterpret_cast(panel_project)); - - QAction* window_effectcontrols_action = window_menu->addAction(tr("Effect Controls"), this, SLOT(toggle_panel_visibility())); - window_effectcontrols_action->setProperty("id", "paneleffectcontrols"); - window_effectcontrols_action->setCheckable(true); - window_effectcontrols_action->setData(reinterpret_cast(panel_effect_controls)); - - QAction* window_timeline_action = window_menu->addAction(tr("Timeline"), this, SLOT(toggle_panel_visibility())); - window_timeline_action->setProperty("id", "paneltimeline"); - window_timeline_action->setCheckable(true); - window_timeline_action->setData(reinterpret_cast(panel_timeline)); - - QAction* window_graph_editor_action = window_menu->addAction(tr("Graph Editor"), this, SLOT(toggle_panel_visibility())); - window_graph_editor_action->setProperty("id", "panelgrapheditor"); - window_graph_editor_action->setCheckable(true); - window_graph_editor_action->setData(reinterpret_cast(panel_graph_editor)); - - QAction* window_footageviewer_action = window_menu->addAction(tr("Media Viewer"), this, SLOT(toggle_panel_visibility())); - window_footageviewer_action->setProperty("id", "panelfootageviewer"); - window_footageviewer_action->setCheckable(true); - window_footageviewer_action->setData(reinterpret_cast(panel_footage_viewer)); - - QAction* window_sequenceviewer_action = window_menu->addAction(tr("Sequence Viewer"), this, SLOT(toggle_panel_visibility())); - window_sequenceviewer_action->setProperty("id", "panelsequenceviewer"); - window_sequenceviewer_action->setCheckable(true); - window_sequenceviewer_action->setData(reinterpret_cast(panel_sequence_viewer)); - - window_menu->addSeparator(); - - window_menu->addAction(tr("Maximize Panel"), this, SLOT(maximize_panel()), QKeySequence("`"))->setProperty("id", "maximizepanel"); - - window_menu->addSeparator(); - - window_menu->addAction(tr("Reset to Default Layout"), this, SLOT(reset_layout()))->setProperty("id", "resetdefaultlayout"); - - // INITIALIZE TOOLS MENU - - QMenu* tools_menu = menuBar->addMenu(tr("&Tools")); - connect(tools_menu, SIGNAL(aboutToShow()), this, SLOT(toolMenu_About_To_Be_Shown())); - - pointer_tool_action = tools_menu->addAction(tr("Pointer Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("V")); - pointer_tool_action->setProperty("id", "pointertool"); - pointer_tool_action->setCheckable(true); - pointer_tool_action->setData(reinterpret_cast(panel_timeline->toolArrowButton)); - - edit_tool_action = tools_menu->addAction(tr("Edit Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("X")); - edit_tool_action->setProperty("id", "edittool"); - edit_tool_action->setCheckable(true); - edit_tool_action->setData(reinterpret_cast(panel_timeline->toolEditButton)); - - ripple_tool_action = tools_menu->addAction(tr("Ripple Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("B")); - ripple_tool_action->setProperty("id", "rippletool"); - ripple_tool_action->setCheckable(true); - ripple_tool_action->setData(reinterpret_cast(panel_timeline->toolRippleButton)); - - razor_tool_action = tools_menu->addAction(tr("Razor Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("C")); - razor_tool_action->setProperty("id", "razortool"); - razor_tool_action->setCheckable(true); - razor_tool_action->setData(reinterpret_cast(panel_timeline->toolRazorButton)); - - slip_tool_action = tools_menu->addAction(tr("Slip Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("Y")); - slip_tool_action->setProperty("id", "sliptool"); - slip_tool_action->setCheckable(true); - slip_tool_action->setData(reinterpret_cast(panel_timeline->toolSlipButton)); - - slide_tool_action = tools_menu->addAction(tr("Slide Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("U")); - slide_tool_action->setProperty("id", "slidetool"); - slide_tool_action->setCheckable(true); - slide_tool_action->setData(reinterpret_cast(panel_timeline->toolSlideButton)); - - hand_tool_action = tools_menu->addAction(tr("Hand Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("H")); - hand_tool_action->setProperty("id", "handtool"); - hand_tool_action->setCheckable(true); - hand_tool_action->setData(reinterpret_cast(panel_timeline->toolHandButton)); - - transition_tool_action = tools_menu->addAction(tr("Transition Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("T")); - transition_tool_action->setProperty("id", "transitiontool"); - transition_tool_action->setCheckable(true); - transition_tool_action->setData(reinterpret_cast(panel_timeline->toolTransitionButton)); - - tools_menu->addSeparator(); - - snap_toggle = tools_menu->addAction(tr("Enable Snapping"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("S")); - snap_toggle->setProperty("id", "snapping"); - snap_toggle->setCheckable(true); - snap_toggle->setData(reinterpret_cast(panel_timeline->snappingButton)); - - tools_menu->addSeparator(); - - selecting_also_seeks = tools_menu->addAction(tr("Selecting Also Seeks"), &olive::MenuHelper, SLOT(toggle_bool_action())); - selecting_also_seeks->setProperty("id", "selectingalsoseeks"); - selecting_also_seeks->setCheckable(true); - selecting_also_seeks->setData(reinterpret_cast(&olive::CurrentConfig.select_also_seeks)); - - edit_tool_also_seeks = tools_menu->addAction(tr("Edit Tool Also Seeks"), &olive::MenuHelper, SLOT(toggle_bool_action())); - edit_tool_also_seeks->setProperty("id", "editalsoseeks"); - edit_tool_also_seeks->setCheckable(true); - edit_tool_also_seeks->setData(reinterpret_cast(&olive::CurrentConfig.edit_tool_also_seeks)); - - edit_tool_selects_links = tools_menu->addAction(tr("Edit Tool Selects Links"), &olive::MenuHelper, SLOT(toggle_bool_action())); - edit_tool_selects_links->setProperty("id", "editselectslinks"); - edit_tool_selects_links->setCheckable(true); - edit_tool_selects_links->setData(reinterpret_cast(&olive::CurrentConfig.edit_tool_selects_links)); - - seek_also_selects = tools_menu->addAction(tr("Seek Also Selects"), &olive::MenuHelper, SLOT(toggle_bool_action())); - seek_also_selects->setProperty("id", "seekalsoselects"); - seek_also_selects->setCheckable(true); - seek_also_selects->setData(reinterpret_cast(&olive::CurrentConfig.seek_also_selects)); - - seek_to_end_of_pastes = tools_menu->addAction(tr("Seek to the End of Pastes"), &olive::MenuHelper, SLOT(toggle_bool_action())); - seek_to_end_of_pastes->setProperty("id", "seektoendofpastes"); - seek_to_end_of_pastes->setCheckable(true); - seek_to_end_of_pastes->setData(reinterpret_cast(&olive::CurrentConfig.paste_seeks)); - - scroll_wheel_zooms = tools_menu->addAction(tr("Scroll Wheel Zooms"), &olive::MenuHelper, SLOT(toggle_bool_action())); - scroll_wheel_zooms->setProperty("id", "scrollwheelzooms"); - scroll_wheel_zooms->setCheckable(true); - scroll_wheel_zooms->setData(reinterpret_cast(&olive::CurrentConfig.scroll_zooms)); - - enable_drag_files_to_timeline = tools_menu->addAction(tr("Enable Drag Files to Timeline"), &olive::MenuHelper, SLOT(toggle_bool_action())); - enable_drag_files_to_timeline->setProperty("id", "enabledragfilestotimeline"); - enable_drag_files_to_timeline->setCheckable(true); - enable_drag_files_to_timeline->setData(reinterpret_cast(&olive::CurrentConfig.enable_drag_files_to_timeline)); - - autoscale_by_default = tools_menu->addAction(tr("Auto-Scale By Default"), &olive::MenuHelper, SLOT(toggle_bool_action())); - autoscale_by_default->setProperty("id", "autoscalebydefault"); - autoscale_by_default->setCheckable(true); - autoscale_by_default->setData(reinterpret_cast(&olive::CurrentConfig.autoscale_by_default)); - - enable_seek_to_import = tools_menu->addAction(tr("Enable Seek to Import"), &olive::MenuHelper, SLOT(toggle_bool_action())); - enable_seek_to_import->setProperty("id", "enableseektoimport"); - enable_seek_to_import->setCheckable(true); - enable_seek_to_import->setData(reinterpret_cast(&olive::CurrentConfig.enable_seek_to_import)); - - enable_audio_scrubbing = tools_menu->addAction(tr("Audio Scrubbing"), &olive::MenuHelper, SLOT(toggle_bool_action())); - enable_audio_scrubbing->setProperty("id", "audioscrubbing"); - enable_audio_scrubbing->setCheckable(true); - enable_audio_scrubbing->setData(reinterpret_cast(&olive::CurrentConfig.enable_audio_scrubbing)); - - enable_drop_on_media_to_replace = tools_menu->addAction(tr("Enable Drop on Media to Replace"), &olive::MenuHelper, SLOT(toggle_bool_action())); - enable_drop_on_media_to_replace->setProperty("id", "enabledropmediareplace"); - enable_drop_on_media_to_replace->setCheckable(true); - enable_drop_on_media_to_replace->setData(reinterpret_cast(&olive::CurrentConfig.drop_on_media_to_replace)); - - enable_hover_focus = tools_menu->addAction(tr("Enable Hover Focus"), &olive::MenuHelper, SLOT(toggle_bool_action())); - enable_hover_focus->setProperty("id", "hoverfocus"); - enable_hover_focus->setCheckable(true); - enable_hover_focus->setData(reinterpret_cast(&olive::CurrentConfig.hover_focus)); - - set_name_and_marker = tools_menu->addAction(tr("Ask For Name When Setting Marker"), &olive::MenuHelper, SLOT(toggle_bool_action())); - set_name_and_marker->setProperty("id", "asknamemarkerset"); - set_name_and_marker->setCheckable(true); - set_name_and_marker->setData(reinterpret_cast(&olive::CurrentConfig.set_name_with_marker)); - - tools_menu->addSeparator(); - - no_autoscroll = tools_menu->addAction(tr("No Auto-Scroll"), &olive::MenuHelper, SLOT(set_autoscroll())); - no_autoscroll->setProperty("id", "autoscrollno"); - no_autoscroll->setData(AUTOSCROLL_NO_SCROLL); - no_autoscroll->setCheckable(true); - - page_autoscroll = tools_menu->addAction(tr("Page Auto-Scroll"), &olive::MenuHelper, SLOT(set_autoscroll())); - page_autoscroll->setProperty("id", "autoscrollpage"); - page_autoscroll->setData(AUTOSCROLL_PAGE_SCROLL); - page_autoscroll->setCheckable(true); - - smooth_autoscroll = tools_menu->addAction(tr("Smooth Auto-Scroll"), &olive::MenuHelper, SLOT(set_autoscroll())); - smooth_autoscroll->setProperty("id", "autoscrollsmooth"); - smooth_autoscroll->setData(AUTOSCROLL_SMOOTH_SCROLL); - smooth_autoscroll->setCheckable(true); - - tools_menu->addSeparator(); - - tools_menu->addAction(tr("Preferences"), olive::Global.get(), SLOT(open_preferences()), QKeySequence("Ctrl+,"))->setProperty("id", "prefs"); + title_safe_custom = title_safe_area_menu->addAction(tr("Custom")); + title_safe_custom->setProperty("id", "titlesafecustom"); + title_safe_custom->setCheckable(true); + title_safe_custom->setData(-1.0); + connect(title_safe_custom, SIGNAL(triggered(bool)), &olive::MenuHelper, SLOT(set_titlesafe_from_menu())); + + view_menu->addSeparator(); + + full_screen = view_menu->addAction(tr("Full Screen"), this, SLOT(toggle_full_screen()), QKeySequence("F11")); + full_screen->setProperty("id", "fullscreen"); + full_screen->setCheckable(true); + + view_menu->addAction(tr("Full Screen Viewer"), &olive::FocusFilter, SLOT(set_viewer_fullscreen()))->setProperty("id", "fullscreenviewer"); + + // INITIALIZE PLAYBACK MENU + + QMenu* playback_menu = menuBar->addMenu(tr("&Playback")); + connect(playback_menu, SIGNAL(aboutToShow()), this, SLOT(playbackMenu_About_To_Be_Shown())); + + playback_menu->addAction(tr("Go to Start"), &olive::FocusFilter, SLOT(go_to_start()), QKeySequence("Home"))->setProperty("id", "gotostart"); + playback_menu->addAction(tr("Previous Frame"), &olive::FocusFilter, SLOT(prev_frame()), QKeySequence("Left"))->setProperty("id", "prevframe"); + playback_menu->addAction(tr("Play/Pause"), &olive::FocusFilter, SLOT(playpause()), QKeySequence("Space"))->setProperty("id", "playpause"); + playback_menu->addAction(tr("Play In to Out"), &olive::FocusFilter, SLOT(play_in_to_out()), QKeySequence("Shift+Space"))->setProperty("id", "playintoout"); + playback_menu->addAction(tr("Next Frame"), &olive::FocusFilter, SLOT(next_frame()), QKeySequence("Right"))->setProperty("id", "nextframe"); + playback_menu->addAction(tr("Go to End"), &olive::FocusFilter, SLOT(go_to_end()), QKeySequence("End"))->setProperty("id", "gotoend"); + playback_menu->addSeparator(); + playback_menu->addAction(tr("Go to Previous Cut"), panel_timeline, SLOT(previous_cut()), QKeySequence("Up"))->setProperty("id", "prevcut"); + playback_menu->addAction(tr("Go to Next Cut"), panel_timeline, SLOT(next_cut()), QKeySequence("Down"))->setProperty("id", "nextcut"); + playback_menu->addSeparator(); + playback_menu->addAction(tr("Go to In Point"), &olive::FocusFilter, SLOT(go_to_in()), QKeySequence("Shift+I"))->setProperty("id", "gotoin"); + playback_menu->addAction(tr("Go to Out Point"), &olive::FocusFilter, SLOT(go_to_out()), QKeySequence("Shift+O"))->setProperty("id", "gotoout"); + playback_menu->addSeparator(); + playback_menu->addAction(tr("Shuttle Left"), &olive::FocusFilter, SLOT(decrease_speed()), QKeySequence("J"))->setProperty("id", "decspeed"); + playback_menu->addAction(tr("Shuttle Stop"), &olive::FocusFilter, SLOT(pause()), QKeySequence("K"))->setProperty("id", "pause"); + playback_menu->addAction(tr("Shuttle Right"), &olive::FocusFilter, SLOT(increase_speed()), QKeySequence("L"))->setProperty("id", "incspeed"); + playback_menu->addSeparator(); + + loop_action = playback_menu->addAction(tr("Loop"), &olive::MenuHelper, SLOT(toggle_bool_action())); + loop_action->setProperty("id", "loop"); + loop_action->setCheckable(true); + loop_action->setData(reinterpret_cast(&olive::CurrentConfig.loop)); + + // INITIALIZE WINDOW MENU + + window_menu = menuBar->addMenu(tr("&Window")); + connect(window_menu, SIGNAL(aboutToShow()), this, SLOT(windowMenu_About_To_Be_Shown())); + + QAction* window_project_action = window_menu->addAction(tr("Project"), this, SLOT(toggle_panel_visibility())); + window_project_action->setProperty("id", "panelproject"); + window_project_action->setCheckable(true); + window_project_action->setData(reinterpret_cast(panel_project)); + + QAction* window_effectcontrols_action = window_menu->addAction(tr("Effect Controls"), this, SLOT(toggle_panel_visibility())); + window_effectcontrols_action->setProperty("id", "paneleffectcontrols"); + window_effectcontrols_action->setCheckable(true); + window_effectcontrols_action->setData(reinterpret_cast(panel_effect_controls)); + + QAction* window_timeline_action = window_menu->addAction(tr("Timeline"), this, SLOT(toggle_panel_visibility())); + window_timeline_action->setProperty("id", "paneltimeline"); + window_timeline_action->setCheckable(true); + window_timeline_action->setData(reinterpret_cast(panel_timeline)); + + QAction* window_graph_editor_action = window_menu->addAction(tr("Graph Editor"), this, SLOT(toggle_panel_visibility())); + window_graph_editor_action->setProperty("id", "panelgrapheditor"); + window_graph_editor_action->setCheckable(true); + window_graph_editor_action->setData(reinterpret_cast(panel_graph_editor)); + + QAction* window_footageviewer_action = window_menu->addAction(tr("Media Viewer"), this, SLOT(toggle_panel_visibility())); + window_footageviewer_action->setProperty("id", "panelfootageviewer"); + window_footageviewer_action->setCheckable(true); + window_footageviewer_action->setData(reinterpret_cast(panel_footage_viewer)); + + QAction* window_sequenceviewer_action = window_menu->addAction(tr("Sequence Viewer"), this, SLOT(toggle_panel_visibility())); + window_sequenceviewer_action->setProperty("id", "panelsequenceviewer"); + window_sequenceviewer_action->setCheckable(true); + window_sequenceviewer_action->setData(reinterpret_cast(panel_sequence_viewer)); + + window_menu->addSeparator(); + + window_menu->addAction(tr("Maximize Panel"), this, SLOT(maximize_panel()), QKeySequence("`"))->setProperty("id", "maximizepanel"); + + window_menu->addSeparator(); + + window_menu->addAction(tr("Reset to Default Layout"), this, SLOT(reset_layout()))->setProperty("id", "resetdefaultlayout"); + + // INITIALIZE TOOLS MENU + + QMenu* tools_menu = menuBar->addMenu(tr("&Tools")); + connect(tools_menu, SIGNAL(aboutToShow()), this, SLOT(toolMenu_About_To_Be_Shown())); + + pointer_tool_action = tools_menu->addAction(tr("Pointer Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("V")); + pointer_tool_action->setProperty("id", "pointertool"); + pointer_tool_action->setCheckable(true); + pointer_tool_action->setData(reinterpret_cast(panel_timeline->toolArrowButton)); + + edit_tool_action = tools_menu->addAction(tr("Edit Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("X")); + edit_tool_action->setProperty("id", "edittool"); + edit_tool_action->setCheckable(true); + edit_tool_action->setData(reinterpret_cast(panel_timeline->toolEditButton)); + + ripple_tool_action = tools_menu->addAction(tr("Ripple Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("B")); + ripple_tool_action->setProperty("id", "rippletool"); + ripple_tool_action->setCheckable(true); + ripple_tool_action->setData(reinterpret_cast(panel_timeline->toolRippleButton)); + + razor_tool_action = tools_menu->addAction(tr("Razor Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("C")); + razor_tool_action->setProperty("id", "razortool"); + razor_tool_action->setCheckable(true); + razor_tool_action->setData(reinterpret_cast(panel_timeline->toolRazorButton)); + + slip_tool_action = tools_menu->addAction(tr("Slip Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("Y")); + slip_tool_action->setProperty("id", "sliptool"); + slip_tool_action->setCheckable(true); + slip_tool_action->setData(reinterpret_cast(panel_timeline->toolSlipButton)); + + slide_tool_action = tools_menu->addAction(tr("Slide Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("U")); + slide_tool_action->setProperty("id", "slidetool"); + slide_tool_action->setCheckable(true); + slide_tool_action->setData(reinterpret_cast(panel_timeline->toolSlideButton)); + + hand_tool_action = tools_menu->addAction(tr("Hand Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("H")); + hand_tool_action->setProperty("id", "handtool"); + hand_tool_action->setCheckable(true); + hand_tool_action->setData(reinterpret_cast(panel_timeline->toolHandButton)); + + transition_tool_action = tools_menu->addAction(tr("Transition Tool"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("T")); + transition_tool_action->setProperty("id", "transitiontool"); + transition_tool_action->setCheckable(true); + transition_tool_action->setData(reinterpret_cast(panel_timeline->toolTransitionButton)); + + tools_menu->addSeparator(); + + snap_toggle = tools_menu->addAction(tr("Enable Snapping"), &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("S")); + snap_toggle->setProperty("id", "snapping"); + snap_toggle->setCheckable(true); + snap_toggle->setData(reinterpret_cast(panel_timeline->snappingButton)); + + tools_menu->addSeparator(); + + selecting_also_seeks = tools_menu->addAction(tr("Selecting Also Seeks"), &olive::MenuHelper, SLOT(toggle_bool_action())); + selecting_also_seeks->setProperty("id", "selectingalsoseeks"); + selecting_also_seeks->setCheckable(true); + selecting_also_seeks->setData(reinterpret_cast(&olive::CurrentConfig.select_also_seeks)); + + edit_tool_also_seeks = tools_menu->addAction(tr("Edit Tool Also Seeks"), &olive::MenuHelper, SLOT(toggle_bool_action())); + edit_tool_also_seeks->setProperty("id", "editalsoseeks"); + edit_tool_also_seeks->setCheckable(true); + edit_tool_also_seeks->setData(reinterpret_cast(&olive::CurrentConfig.edit_tool_also_seeks)); + + edit_tool_selects_links = tools_menu->addAction(tr("Edit Tool Selects Links"), &olive::MenuHelper, SLOT(toggle_bool_action())); + edit_tool_selects_links->setProperty("id", "editselectslinks"); + edit_tool_selects_links->setCheckable(true); + edit_tool_selects_links->setData(reinterpret_cast(&olive::CurrentConfig.edit_tool_selects_links)); + + seek_also_selects = tools_menu->addAction(tr("Seek Also Selects"), &olive::MenuHelper, SLOT(toggle_bool_action())); + seek_also_selects->setProperty("id", "seekalsoselects"); + seek_also_selects->setCheckable(true); + seek_also_selects->setData(reinterpret_cast(&olive::CurrentConfig.seek_also_selects)); + + seek_to_end_of_pastes = tools_menu->addAction(tr("Seek to the End of Pastes"), &olive::MenuHelper, SLOT(toggle_bool_action())); + seek_to_end_of_pastes->setProperty("id", "seektoendofpastes"); + seek_to_end_of_pastes->setCheckable(true); + seek_to_end_of_pastes->setData(reinterpret_cast(&olive::CurrentConfig.paste_seeks)); + + scroll_wheel_zooms = tools_menu->addAction(tr("Scroll Wheel Zooms"), &olive::MenuHelper, SLOT(toggle_bool_action())); + scroll_wheel_zooms->setProperty("id", "scrollwheelzooms"); + scroll_wheel_zooms->setCheckable(true); + scroll_wheel_zooms->setData(reinterpret_cast(&olive::CurrentConfig.scroll_zooms)); + + enable_drag_files_to_timeline = tools_menu->addAction(tr("Enable Drag Files to Timeline"), &olive::MenuHelper, SLOT(toggle_bool_action())); + enable_drag_files_to_timeline->setProperty("id", "enabledragfilestotimeline"); + enable_drag_files_to_timeline->setCheckable(true); + enable_drag_files_to_timeline->setData(reinterpret_cast(&olive::CurrentConfig.enable_drag_files_to_timeline)); + + autoscale_by_default = tools_menu->addAction(tr("Auto-Scale By Default"), &olive::MenuHelper, SLOT(toggle_bool_action())); + autoscale_by_default->setProperty("id", "autoscalebydefault"); + autoscale_by_default->setCheckable(true); + autoscale_by_default->setData(reinterpret_cast(&olive::CurrentConfig.autoscale_by_default)); + + enable_seek_to_import = tools_menu->addAction(tr("Enable Seek to Import"), &olive::MenuHelper, SLOT(toggle_bool_action())); + enable_seek_to_import->setProperty("id", "enableseektoimport"); + enable_seek_to_import->setCheckable(true); + enable_seek_to_import->setData(reinterpret_cast(&olive::CurrentConfig.enable_seek_to_import)); + + enable_audio_scrubbing = tools_menu->addAction(tr("Audio Scrubbing"), &olive::MenuHelper, SLOT(toggle_bool_action())); + enable_audio_scrubbing->setProperty("id", "audioscrubbing"); + enable_audio_scrubbing->setCheckable(true); + enable_audio_scrubbing->setData(reinterpret_cast(&olive::CurrentConfig.enable_audio_scrubbing)); + + enable_drop_on_media_to_replace = tools_menu->addAction(tr("Enable Drop on Media to Replace"), &olive::MenuHelper, SLOT(toggle_bool_action())); + enable_drop_on_media_to_replace->setProperty("id", "enabledropmediareplace"); + enable_drop_on_media_to_replace->setCheckable(true); + enable_drop_on_media_to_replace->setData(reinterpret_cast(&olive::CurrentConfig.drop_on_media_to_replace)); + + enable_hover_focus = tools_menu->addAction(tr("Enable Hover Focus"), &olive::MenuHelper, SLOT(toggle_bool_action())); + enable_hover_focus->setProperty("id", "hoverfocus"); + enable_hover_focus->setCheckable(true); + enable_hover_focus->setData(reinterpret_cast(&olive::CurrentConfig.hover_focus)); + + set_name_and_marker = tools_menu->addAction(tr("Ask For Name When Setting Marker"), &olive::MenuHelper, SLOT(toggle_bool_action())); + set_name_and_marker->setProperty("id", "asknamemarkerset"); + set_name_and_marker->setCheckable(true); + set_name_and_marker->setData(reinterpret_cast(&olive::CurrentConfig.set_name_with_marker)); + + tools_menu->addSeparator(); + + no_autoscroll = tools_menu->addAction(tr("No Auto-Scroll"), &olive::MenuHelper, SLOT(set_autoscroll())); + no_autoscroll->setProperty("id", "autoscrollno"); + no_autoscroll->setData(AUTOSCROLL_NO_SCROLL); + no_autoscroll->setCheckable(true); + + page_autoscroll = tools_menu->addAction(tr("Page Auto-Scroll"), &olive::MenuHelper, SLOT(set_autoscroll())); + page_autoscroll->setProperty("id", "autoscrollpage"); + page_autoscroll->setData(AUTOSCROLL_PAGE_SCROLL); + page_autoscroll->setCheckable(true); + + smooth_autoscroll = tools_menu->addAction(tr("Smooth Auto-Scroll"), &olive::MenuHelper, SLOT(set_autoscroll())); + smooth_autoscroll->setProperty("id", "autoscrollsmooth"); + smooth_autoscroll->setData(AUTOSCROLL_SMOOTH_SCROLL); + smooth_autoscroll->setCheckable(true); + + tools_menu->addSeparator(); + + tools_menu->addAction(tr("Preferences"), olive::Global.get(), SLOT(open_preferences()), QKeySequence("Ctrl+,"))->setProperty("id", "prefs"); #ifdef QT_DEBUG - tools_menu->addAction(tr("Clear Undo"), olive::Global.get(), SLOT(clear_undo_stack()))->setProperty("id", "clearundo"); + tools_menu->addAction(tr("Clear Undo"), olive::Global.get(), SLOT(clear_undo_stack()))->setProperty("id", "clearundo"); #endif - // INITIALIZE HELP MENU + // INITIALIZE HELP MENU - QMenu* help_menu = menuBar->addMenu(tr("&Help")); + QMenu* help_menu = menuBar->addMenu(tr("&Help")); - help_menu->addAction(tr("A&ction Search"), olive::Global.get(), SLOT(open_action_search()), QKeySequence("/"))->setProperty("id", "actionsearch"); + help_menu->addAction(tr("A&ction Search"), olive::Global.get(), SLOT(open_action_search()), QKeySequence("/"))->setProperty("id", "actionsearch"); - help_menu->addSeparator(); + help_menu->addSeparator(); - help_menu->addAction(tr("Debug Log"), olive::Global.get(), SLOT(open_debug_log()))->setProperty("id", "debuglog"); + help_menu->addAction(tr("Debug Log"), olive::Global.get(), SLOT(open_debug_log()))->setProperty("id", "debuglog"); - help_menu->addSeparator(); + help_menu->addSeparator(); - help_menu->addAction(tr("&About..."), olive::Global.get(), SLOT(open_about_dialog()))->setProperty("id", "about"); + help_menu->addAction(tr("&About..."), olive::Global.get(), SLOT(open_about_dialog()))->setProperty("id", "about"); - load_shortcuts(get_config_path() + "/shortcuts"); + load_shortcuts(get_config_path() + "/shortcuts"); } void MainWindow::updateTitle() { - setWindowTitle(QString("%1 - %2[*]").arg(olive::AppName, - (olive::ActiveProjectFilename.isEmpty()) ? - tr("") : olive::ActiveProjectFilename) - ); + setWindowTitle(QString("%1 - %2[*]").arg(olive::AppName, + (olive::ActiveProjectFilename.isEmpty()) ? + tr("") : olive::ActiveProjectFilename) + ); } void MainWindow::closeEvent(QCloseEvent *e) { - if (olive::Global->can_close_project()) { - // stop proxy generator thread - proxy_generator.cancel(); + if (olive::Global->can_close_project()) { + // stop proxy generator thread + proxy_generator.cancel(); - panel_effect_controls->clear_effects(true); + panel_effect_controls->clear_effects(true); - set_sequence(nullptr); + set_sequence(nullptr); - panel_footage_viewer->viewer_widget->close_window(); - panel_sequence_viewer->viewer_widget->close_window(); + panel_footage_viewer->viewer_widget->close_window(); + panel_sequence_viewer->viewer_widget->close_window(); - panel_footage_viewer->set_main_sequence(); + panel_footage_viewer->set_main_sequence(); - QString data_dir = get_data_path(); - QString config_path = get_config_path(); - if (!data_dir.isEmpty() && !autorecovery_filename.isEmpty()) { - if (QFile::exists(autorecovery_filename)) { - QFile::rename(autorecovery_filename, autorecovery_filename + "." + QDateTime::currentDateTimeUtc().toString("yyyyMMddHHmmss")); - } - } - if (!config_path.isEmpty()) { - QDir config_dir = QDir(config_path); + QString data_dir = get_data_path(); + QString config_path = get_config_path(); + if (!data_dir.isEmpty() && !autorecovery_filename.isEmpty()) { + if (QFile::exists(autorecovery_filename)) { + QFile::rename(autorecovery_filename, autorecovery_filename + "." + QDateTime::currentDateTimeUtc().toString("yyyyMMddHHmmss")); + } + } + if (!config_path.isEmpty()) { + QDir config_dir = QDir(config_path); - QString config_fn = config_dir.filePath("config.xml"); + QString config_fn = config_dir.filePath("config.xml"); - // save settings - olive::CurrentConfig.save(config_fn); + // save settings + olive::CurrentConfig.save(config_fn); - // save panel layout - QFile panel_config(config_path + "/layout"); - if (panel_config.open(QFile::WriteOnly)) { - panel_config.write(saveState(0)); - panel_config.close(); - } else { - qCritical() << "Failed to save layout"; - } + // save panel layout + QFile panel_config(config_path + "/layout"); + if (panel_config.open(QFile::WriteOnly)) { + panel_config.write(saveState(0)); + panel_config.close(); + } else { + qCritical() << "Failed to save layout"; + } - save_shortcuts(config_path + "/shortcuts"); - } + save_shortcuts(config_path + "/shortcuts"); + } - stop_audio(); + stop_audio(); - e->accept(); - } else { - e->ignore(); - } + e->accept(); + } else { + e->ignore(); + } } void MainWindow::paintEvent(QPaintEvent *event) { - QMainWindow::paintEvent(event); + QMainWindow::paintEvent(event); - if (first_show) { - first_show = false; - emit finished_first_paint(); - } + if (first_show) { + first_show = false; + emit finished_first_paint(); + } } void MainWindow::reset_layout() { - setup_layout(true); + setup_layout(true); } void MainWindow::maximize_panel() { - // toggles between normal state and a state of one panel being maximized - if (temp_panel_state.isEmpty()) { - // get currently hovered panel - QDockWidget* focused_panel = get_focused_panel(true); + // toggles between normal state and a state of one panel being maximized + if (temp_panel_state.isEmpty()) { + // get currently hovered panel + QDockWidget* focused_panel = get_focused_panel(true); - // if the mouse is in fact hovering over a panel - if (focused_panel != nullptr) { - // store the current state of panels - temp_panel_state = saveState(); + // if the mouse is in fact hovering over a panel + if (focused_panel != nullptr) { + // store the current state of panels + temp_panel_state = saveState(); - // remove all dock widgets (kind of painful having to do each individually) - if (focused_panel != panel_project) removeDockWidget(panel_project); - if (focused_panel != panel_effect_controls) removeDockWidget(panel_effect_controls); - if (focused_panel != panel_timeline) removeDockWidget(panel_timeline); - if (focused_panel != panel_sequence_viewer) removeDockWidget(panel_sequence_viewer); - if (focused_panel != panel_footage_viewer) removeDockWidget(panel_footage_viewer); - if (focused_panel != panel_graph_editor) removeDockWidget(panel_graph_editor); - } - } else { - // we must be maximized, restore previous state - restoreState(temp_panel_state); + // remove all dock widgets (kind of painful having to do each individually) + if (focused_panel != panel_project) removeDockWidget(panel_project); + if (focused_panel != panel_effect_controls) removeDockWidget(panel_effect_controls); + if (focused_panel != panel_timeline) removeDockWidget(panel_timeline); + if (focused_panel != panel_sequence_viewer) removeDockWidget(panel_sequence_viewer); + if (focused_panel != panel_footage_viewer) removeDockWidget(panel_footage_viewer); + if (focused_panel != panel_graph_editor) removeDockWidget(panel_graph_editor); + } + } else { + // we must be maximized, restore previous state + restoreState(temp_panel_state); - // clear temp panel state for next maximize call - temp_panel_state.clear(); - } + // clear temp panel state for next maximize call + temp_panel_state.clear(); + } } void MainWindow::windowMenu_About_To_Be_Shown() { - QList window_actions = window_menu->actions(); - for (int i=0;idata().isNull()) { - a->setChecked(reinterpret_cast(a->data().value())->isVisible()); - } - } + QList window_actions = window_menu->actions(); + for (int i=0;idata().isNull()) { + a->setChecked(reinterpret_cast(a->data().value())->isVisible()); + } + } } void MainWindow::playbackMenu_About_To_Be_Shown() { - olive::MenuHelper.set_bool_action_checked(loop_action); + olive::MenuHelper.set_bool_action_checked(loop_action); } void MainWindow::viewMenu_About_To_Be_Shown() { - olive::MenuHelper.set_bool_action_checked(track_lines); + olive::MenuHelper.set_bool_action_checked(track_lines); - olive::MenuHelper.set_int_action_checked(frames_action, olive::CurrentConfig.timecode_view); - olive::MenuHelper.set_int_action_checked(drop_frame_action, olive::CurrentConfig.timecode_view); - olive::MenuHelper.set_int_action_checked(nondrop_frame_action, olive::CurrentConfig.timecode_view); - olive::MenuHelper.set_int_action_checked(milliseconds_action, olive::CurrentConfig.timecode_view); + olive::MenuHelper.set_int_action_checked(frames_action, olive::CurrentConfig.timecode_view); + olive::MenuHelper.set_int_action_checked(drop_frame_action, olive::CurrentConfig.timecode_view); + olive::MenuHelper.set_int_action_checked(nondrop_frame_action, olive::CurrentConfig.timecode_view); + olive::MenuHelper.set_int_action_checked(milliseconds_action, olive::CurrentConfig.timecode_view); - title_safe_off->setChecked(!olive::CurrentConfig.show_title_safe_area); - title_safe_default->setChecked(olive::CurrentConfig.show_title_safe_area - && !olive::CurrentConfig.use_custom_title_safe_ratio); - title_safe_43->setChecked(olive::CurrentConfig.show_title_safe_area - && olive::CurrentConfig.use_custom_title_safe_ratio - && qFuzzyCompare(olive::CurrentConfig.custom_title_safe_ratio, title_safe_43->data().toDouble())); - title_safe_169->setChecked(olive::CurrentConfig.show_title_safe_area - && olive::CurrentConfig.use_custom_title_safe_ratio - && qFuzzyCompare(olive::CurrentConfig.custom_title_safe_ratio, title_safe_169->data().toDouble())); - title_safe_custom->setChecked(olive::CurrentConfig.show_title_safe_area - && olive::CurrentConfig.use_custom_title_safe_ratio - && !title_safe_43->isChecked() - && !title_safe_169->isChecked()); + title_safe_off->setChecked(!olive::CurrentConfig.show_title_safe_area); + title_safe_default->setChecked(olive::CurrentConfig.show_title_safe_area + && !olive::CurrentConfig.use_custom_title_safe_ratio); + title_safe_43->setChecked(olive::CurrentConfig.show_title_safe_area + && olive::CurrentConfig.use_custom_title_safe_ratio + && qFuzzyCompare(olive::CurrentConfig.custom_title_safe_ratio, title_safe_43->data().toDouble())); + title_safe_169->setChecked(olive::CurrentConfig.show_title_safe_area + && olive::CurrentConfig.use_custom_title_safe_ratio + && qFuzzyCompare(olive::CurrentConfig.custom_title_safe_ratio, title_safe_169->data().toDouble())); + title_safe_custom->setChecked(olive::CurrentConfig.show_title_safe_area + && olive::CurrentConfig.use_custom_title_safe_ratio + && !title_safe_43->isChecked() + && !title_safe_169->isChecked()); - full_screen->setChecked(windowState() == Qt::WindowFullScreen); + full_screen->setChecked(windowState() == Qt::WindowFullScreen); - show_all->setChecked(panel_timeline->showing_all); + show_all->setChecked(panel_timeline->showing_all); } void MainWindow::toolMenu_About_To_Be_Shown() { - olive::MenuHelper.set_button_action_checked(pointer_tool_action); - olive::MenuHelper.set_button_action_checked(edit_tool_action); - olive::MenuHelper.set_button_action_checked(ripple_tool_action); - olive::MenuHelper.set_button_action_checked(razor_tool_action); - olive::MenuHelper.set_button_action_checked(slip_tool_action); - olive::MenuHelper.set_button_action_checked(slide_tool_action); - olive::MenuHelper.set_button_action_checked(hand_tool_action); - olive::MenuHelper.set_button_action_checked(transition_tool_action); - olive::MenuHelper.set_button_action_checked(snap_toggle); + olive::MenuHelper.set_button_action_checked(pointer_tool_action); + olive::MenuHelper.set_button_action_checked(edit_tool_action); + olive::MenuHelper.set_button_action_checked(ripple_tool_action); + olive::MenuHelper.set_button_action_checked(razor_tool_action); + olive::MenuHelper.set_button_action_checked(slip_tool_action); + olive::MenuHelper.set_button_action_checked(slide_tool_action); + olive::MenuHelper.set_button_action_checked(hand_tool_action); + olive::MenuHelper.set_button_action_checked(transition_tool_action); + olive::MenuHelper.set_button_action_checked(snap_toggle); - olive::MenuHelper.set_bool_action_checked(selecting_also_seeks); - olive::MenuHelper.set_bool_action_checked(edit_tool_also_seeks); - olive::MenuHelper.set_bool_action_checked(edit_tool_selects_links); - olive::MenuHelper.set_bool_action_checked(seek_to_end_of_pastes); - olive::MenuHelper.set_bool_action_checked(scroll_wheel_zooms); - olive::MenuHelper.set_bool_action_checked(rectified_waveforms); - olive::MenuHelper.set_bool_action_checked(enable_drag_files_to_timeline); - olive::MenuHelper.set_bool_action_checked(autoscale_by_default); - olive::MenuHelper.set_bool_action_checked(enable_seek_to_import); - olive::MenuHelper.set_bool_action_checked(enable_audio_scrubbing); - olive::MenuHelper.set_bool_action_checked(enable_drop_on_media_to_replace); - olive::MenuHelper.set_bool_action_checked(enable_hover_focus); - olive::MenuHelper.set_bool_action_checked(set_name_and_marker); - olive::MenuHelper.set_bool_action_checked(seek_also_selects); + olive::MenuHelper.set_bool_action_checked(selecting_also_seeks); + olive::MenuHelper.set_bool_action_checked(edit_tool_also_seeks); + olive::MenuHelper.set_bool_action_checked(edit_tool_selects_links); + olive::MenuHelper.set_bool_action_checked(seek_to_end_of_pastes); + olive::MenuHelper.set_bool_action_checked(scroll_wheel_zooms); + olive::MenuHelper.set_bool_action_checked(rectified_waveforms); + olive::MenuHelper.set_bool_action_checked(enable_drag_files_to_timeline); + olive::MenuHelper.set_bool_action_checked(autoscale_by_default); + olive::MenuHelper.set_bool_action_checked(enable_seek_to_import); + olive::MenuHelper.set_bool_action_checked(enable_audio_scrubbing); + olive::MenuHelper.set_bool_action_checked(enable_drop_on_media_to_replace); + olive::MenuHelper.set_bool_action_checked(enable_hover_focus); + olive::MenuHelper.set_bool_action_checked(set_name_and_marker); + olive::MenuHelper.set_bool_action_checked(seek_also_selects); - olive::MenuHelper.set_int_action_checked(no_autoscroll, olive::CurrentConfig.autoscroll); - olive::MenuHelper.set_int_action_checked(page_autoscroll, olive::CurrentConfig.autoscroll); - olive::MenuHelper.set_int_action_checked(smooth_autoscroll, olive::CurrentConfig.autoscroll); + olive::MenuHelper.set_int_action_checked(no_autoscroll, olive::CurrentConfig.autoscroll); + olive::MenuHelper.set_int_action_checked(page_autoscroll, olive::CurrentConfig.autoscroll); + olive::MenuHelper.set_int_action_checked(smooth_autoscroll, olive::CurrentConfig.autoscroll); } void MainWindow::toggle_panel_visibility() { - QAction* action = static_cast(sender()); - QDockWidget* w = reinterpret_cast(action->data().value()); - w->setVisible(!w->isVisible()); + QAction* action = static_cast(sender()); + QDockWidget* w = reinterpret_cast(action->data().value()); + w->setVisible(!w->isVisible()); - // layout has changed, we're no longer in maximized panel mode, - // so we clear this byte array - temp_panel_state.clear(); + // layout has changed, we're no longer in maximized panel mode, + // so we clear this byte array + temp_panel_state.clear(); } void MainWindow::fileMenu_About_To_Be_Shown() { - if (recent_projects.size() > 0) { - open_recent->clear(); - open_recent->setEnabled(true); - for (int i=0;iaddAction(recent_projects.at(i)); - action->setProperty("keyignore", true); - action->setData(i); - connect(action, SIGNAL(triggered()), &olive::MenuHelper, SLOT(open_recent_from_menu())); - } - open_recent->addSeparator(); + if (recent_projects.size() > 0) { + open_recent->clear(); + open_recent->setEnabled(true); + for (int i=0;iaddAction(recent_projects.at(i)); + action->setProperty("keyignore", true); + action->setData(i); + connect(action, SIGNAL(triggered()), &olive::MenuHelper, SLOT(open_recent_from_menu())); + } + open_recent->addSeparator(); - open_recent->addAction(clear_open_recent_action); - } else { - open_recent->setEnabled(false); - } + open_recent->addAction(clear_open_recent_action); + } else { + open_recent->setEnabled(false); + } } void MainWindow::toggle_full_screen() { - if (windowState() == Qt::WindowFullScreen) { - setWindowState(Qt::WindowNoState); // seems to be necessary for it to return to Maximized correctly on Linux - setWindowState(Qt::WindowMaximized); - } else { - setWindowState(Qt::WindowFullScreen); - } + if (windowState() == Qt::WindowFullScreen) { + setWindowState(Qt::WindowNoState); // seems to be necessary for it to return to Maximized correctly on Linux + setWindowState(Qt::WindowMaximized); + } else { + setWindowState(Qt::WindowFullScreen); + } } diff --git a/olive.pro b/olive.pro index bee391b17..6864830e1 100644 --- a/olive.pro +++ b/olive.pro @@ -150,7 +150,8 @@ SOURCES += \ oliveglobal.cpp \ ui/focusfilter.cpp \ project/comboaction.cpp \ - ui/mediaiconservice.cpp + ui/mediaiconservice.cpp \ + ui/panel.cpp HEADERS += \ mainwindow.h \ @@ -258,7 +259,8 @@ HEADERS += \ project/projectelements.h \ ui/focusfilter.h \ project/comboaction.h \ - ui/mediaiconservice.h + ui/mediaiconservice.h \ + ui/panel.h FORMS += diff --git a/oliveglobal.cpp b/oliveglobal.cpp index 26c686899..174df5b9f 100644 --- a/oliveglobal.cpp +++ b/oliveglobal.cpp @@ -25,6 +25,7 @@ #include "panels/panels.h" #include "io/path.h" +#include "io/config.h" #include "playback/audio.h" @@ -41,6 +42,7 @@ #include #include #include +#include #include std::unique_ptr olive::Global; @@ -60,6 +62,9 @@ OliveGlobal::OliveGlobal() { // set default value enable_load_project_on_init = false; + + // alloc QTranslator + translator = std::unique_ptr(new QTranslator()); } const QString &OliveGlobal::get_project_file_filter() { @@ -106,7 +111,30 @@ void OliveGlobal::load_project_on_launch(const QString& s) { } QString OliveGlobal::get_recent_project_list_file() { - return get_data_dir().filePath("recents"); + return get_data_dir().filePath("recents"); +} + +void OliveGlobal::load_translation_from_config() { + QString language_file = olive::CurrentRuntimeConfig.external_translation_file.isEmpty() ? + olive::CurrentConfig.language_file : + olive::CurrentRuntimeConfig.external_translation_file; + + if (!language_file.isEmpty()) { + + // translation files are stored relative to app path (see GitHub issue #454) + QString full_language_path = QDir(get_app_path()).filePath(language_file); + + // remove translation + QApplication::removeTranslator(translator.get()); + + // load translation file + if (QFileInfo::exists(full_language_path) + && translator->load(full_language_path)) { + QApplication::installTranslator(translator.get()); + } else { + qWarning() << "Failed to load translation file" << full_language_path << ". No language will be loaded."; + } + } } void OliveGlobal::new_project() { diff --git a/oliveglobal.h b/oliveglobal.h index 7b3ffc2b1..1e43852c7 100644 --- a/oliveglobal.h +++ b/oliveglobal.h @@ -25,6 +25,7 @@ #include #include +#include /** * @brief The Olive Global class @@ -108,6 +109,11 @@ public: */ QString get_recent_project_list_file(); + /** + * @brief (Re)load translation file from olive::config + */ + void load_translation_from_config(); + public slots: /** * @brief Undo user's last action @@ -290,6 +296,11 @@ private: */ bool enable_load_project_on_init; + /** + * @brief Internal translator object that interfaces with the currently loaded language file + */ + std::unique_ptr translator; + private slots: diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp index 6619b9701..85485ecd6 100644 --- a/panels/effectcontrols.cpp +++ b/panels/effectcontrols.cpp @@ -52,15 +52,13 @@ #include "debug.h" EffectControls::EffectControls(QWidget *parent) : - QDockWidget(parent), + Panel(parent), multiple(false), zoom(1), - panel_name(tr("Effects: ")), mode(kTransitionNone) { - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - setup_ui(); + Retranslate(); clear_effects(false); headers->viewer = panel_sequence_viewer; @@ -277,7 +275,7 @@ void EffectControls::clear_effects(bool clear_cache) { headers->setVisible(false); keyframeView->setEnabled(false); if (clear_cache) selected_clips.clear(); - setWindowTitle(panel_name + "(none)"); + UpdateTitle(); } void EffectControls::deselect_all_effects(QWidget* sender) { @@ -298,6 +296,14 @@ void EffectControls::open_effect(QVBoxLayout* layout, EffectPtr e) { connect(container, SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); } +void EffectControls::UpdateTitle() { + if (selected_clips.empty()) { + setWindowTitle(panel_name + tr("(none)")); + } else { + setWindowTitle(panel_name + olive::ActiveSequence->clips.at(selected_clips.at(0))->name); + } +} + void EffectControls::setup_ui() { QWidget* contents = new QWidget(this); @@ -344,27 +350,24 @@ void EffectControls::setup_ui() { veHeaderLayout->setSpacing(0); veHeaderLayout->setMargin(0); - QPushButton* btnAddVideoEffect = new QPushButton(); + btnAddVideoEffect = new QPushButton(); btnAddVideoEffect->setIcon(QIcon(":/icons/add-effect.png")); - btnAddVideoEffect->setToolTip(tr("Add Video Effect")); veHeaderLayout->addWidget(btnAddVideoEffect); connect(btnAddVideoEffect, SIGNAL(clicked(bool)), this, SLOT(video_effect_click())); veHeaderLayout->addStretch(); - QLabel* lblVideoEffects = new QLabel(); + lblVideoEffects = new QLabel(); QFont font; font.setPointSize(9); lblVideoEffects->setFont(font); lblVideoEffects->setAlignment(Qt::AlignCenter); - lblVideoEffects->setText(tr("VIDEO EFFECTS")); veHeaderLayout->addWidget(lblVideoEffects); veHeaderLayout->addStretch(); - QPushButton* btnAddVideoTransition = new QPushButton(); + btnAddVideoTransition = new QPushButton(); btnAddVideoTransition->setIcon(QIcon(":/icons/add-transition.png")); - btnAddVideoTransition->setToolTip(tr("Add Video Transition")); connect(btnAddVideoTransition, SIGNAL(clicked(bool)), this, SLOT(video_transition_click())); veHeaderLayout->addWidget(btnAddVideoTransition); @@ -391,25 +394,22 @@ void EffectControls::setup_ui() { aeHeaderLayout->setSpacing(0); aeHeaderLayout->setMargin(0); - QPushButton* btnAddAudioEffect = new QPushButton(); + btnAddAudioEffect = new QPushButton(); btnAddAudioEffect->setIcon(QIcon(":/icons/add-effect.png")); - btnAddAudioEffect->setToolTip(tr("Add Audio Effect")); connect(btnAddAudioEffect, SIGNAL(clicked(bool)), this, SLOT(audio_effect_click())); aeHeaderLayout->addWidget(btnAddAudioEffect); aeHeaderLayout->addStretch(); - QLabel* lblAudioEffects = new QLabel(); + lblAudioEffects = new QLabel(); lblAudioEffects->setFont(font); lblAudioEffects->setAlignment(Qt::AlignCenter); - lblAudioEffects->setText(tr("AUDIO EFFECTS")); aeHeaderLayout->addWidget(lblAudioEffects); aeHeaderLayout->addStretch(); - QPushButton* btnAddAudioTransition = new QPushButton(); + btnAddAudioTransition = new QPushButton(); btnAddAudioTransition->setIcon(QIcon(":/icons/add-transition.png")); - btnAddAudioTransition->setToolTip(tr("Add Audio Transition")); connect(btnAddAudioTransition, SIGNAL(clicked(bool)), this, SLOT(audio_transition_click())); aeHeaderLayout->addWidget(btnAddAudioTransition); @@ -426,7 +426,6 @@ void EffectControls::setup_ui() { lblMultipleClipsSelected = new QLabel(); lblMultipleClipsSelected->setAlignment(Qt::AlignCenter); - lblMultipleClipsSelected->setText(tr("(Multiple clips selected)")); effects_area_layout->addWidget(lblMultipleClipsSelected); effects_area_layout->addStretch(); @@ -481,6 +480,20 @@ void EffectControls::setup_ui() { setWidget(contents); } +void EffectControls::Retranslate() { + panel_name = tr("Effects: "); + + btnAddVideoEffect->setToolTip(tr("Add Video Effect")); + lblVideoEffects->setText(tr("VIDEO EFFECTS")); + btnAddVideoTransition->setToolTip(tr("Add Video Transition")); + btnAddAudioEffect->setToolTip(tr("Add Audio Effect")); + lblAudioEffects->setText(tr("AUDIO EFFECTS")); + btnAddAudioTransition->setToolTip(tr("Add Audio Transition")); + lblMultipleClipsSelected->setText(tr("(Multiple clips selected)")); + + UpdateTitle(); +} + void EffectControls::update_scrollbar() { verticalScrollBar->setMaximum(qMax(0, effects_area->height() - keyframeView->height() - headers->height())); verticalScrollBar->setPageStep(verticalScrollBar->height()); @@ -525,13 +538,14 @@ void EffectControls::load_effects() { } } if (selected_clips.size() > 0) { - setWindowTitle(panel_name + olive::ActiveSequence->clips.at(selected_clips.at(0))->name); keyframeView->setEnabled(true); headers->setVisible(true); QTimer::singleShot(50, this, SLOT(queue_post_update())); } } + + UpdateTitle(); } void EffectControls::delete_effects() { diff --git a/panels/effectcontrols.h b/panels/effectcontrols.h index aee0c8f73..a37ebbf59 100644 --- a/panels/effectcontrols.h +++ b/panels/effectcontrols.h @@ -21,7 +21,6 @@ #ifndef EFFECTCONTROLS_H #define EFFECTCONTROLS_H -#include #include #include #include @@ -36,88 +35,97 @@ #include "ui/keyframeview.h" #include "ui/resizablescrollbar.h" #include "ui/keyframeview.h" +#include "ui/panel.h" class EffectsArea : public QWidget { - Q_OBJECT + Q_OBJECT public: - EffectsArea(QWidget* parent = 0); - QScrollArea* parent_widget; - KeyframeView* keyframe_area; - TimelineHeader* header; + EffectsArea(QWidget* parent = 0); + QScrollArea* parent_widget; + KeyframeView* keyframe_area; + TimelineHeader* header; public slots: - void receive_wheel_event(QWheelEvent* e); + void receive_wheel_event(QWheelEvent* e); }; -class EffectControls : public QDockWidget +class EffectControls : public Panel { - Q_OBJECT + Q_OBJECT public: - explicit EffectControls(QWidget *parent = 0); - ~EffectControls(); - int get_mode(); - void set_clips(QVector& clips, int mode); - void clear_effects(bool clear_cache); - void delete_effects(); - bool is_focused(); - void reload_clips(); - void set_zoom(bool in); - bool keyframe_focus(); - void delete_selected_keyframes(); - bool multiple; - void scroll_to_frame(long frame); + explicit EffectControls(QWidget *parent = 0); + ~EffectControls(); + int get_mode(); + void set_clips(QVector& clips, int mode); + void clear_effects(bool clear_cache); + void delete_effects(); + bool is_focused(); + void reload_clips(); + void set_zoom(bool in); + bool keyframe_focus(); + void delete_selected_keyframes(); + bool multiple; + void scroll_to_frame(long frame); - QVector selected_clips; + QVector selected_clips; - double zoom; + double zoom; - ResizableScrollBar* horizontalScrollBar; - QScrollBar* verticalScrollBar; + ResizableScrollBar* horizontalScrollBar; + QScrollBar* verticalScrollBar; - QMutex effects_loaded; + QMutex effects_loaded; - void add_effect_paste_action(QMenu* menu); + void add_effect_paste_action(QMenu* menu); public slots: - void cut(); - void copy(bool del = false); - void update_keyframes(); + void cut(); + void copy(bool del = false); + void update_keyframes(); private slots: - void menu_select(QAction* q); + void menu_select(QAction* q); - void video_effect_click(); - void audio_effect_click(); - void video_transition_click(); - void audio_transition_click(); + void video_effect_click(); + void audio_effect_click(); + void video_transition_click(); + void audio_transition_click(); - void deselect_all_effects(QWidget*); + void deselect_all_effects(QWidget*); - void update_scrollbar(); - void queue_post_update(); + void update_scrollbar(); + void queue_post_update(); - void effects_area_context_menu(); + void effects_area_context_menu(); protected: - void resizeEvent(QResizeEvent *event); + virtual void resizeEvent(QResizeEvent *event) override; + virtual void Retranslate() override; private: - void show_effect_menu(int type, int subtype); - void load_effects(); - void load_keyframes(); - void open_effect(QVBoxLayout* hlayout, EffectPtr e); + void show_effect_menu(int type, int subtype); + void load_effects(); + void load_keyframes(); + void open_effect(QVBoxLayout* hlayout, EffectPtr e); + void UpdateTitle(); - void setup_ui(); + void setup_ui(); - int effect_menu_type; - int effect_menu_subtype; - QString panel_name; - int mode; + int effect_menu_type; + int effect_menu_subtype; + QString panel_name; + int mode; - TimelineHeader* headers; - EffectsArea* effects_area; - QScrollArea* scrollArea; - QLabel* lblMultipleClipsSelected; - KeyframeView* keyframeView; - QWidget* video_effect_area; - QWidget* audio_effect_area; - QWidget* vcontainer; - QWidget* acontainer; + QPushButton* btnAddVideoEffect; + QLabel* lblVideoEffects; + QPushButton* btnAddVideoTransition; + QPushButton* btnAddAudioEffect; + QPushButton* btnAddAudioTransition; + QLabel* lblMultipleClipsSelected; + QLabel* lblAudioEffects; + TimelineHeader* headers; + EffectsArea* effects_area; + QScrollArea* scrollArea; + KeyframeView* keyframeView; + QWidget* video_effect_area; + QWidget* audio_effect_area; + QWidget* vcontainer; + QWidget* acontainer; }; #endif // EFFECTCONTROLS_H diff --git a/panels/grapheditor.cpp b/panels/grapheditor.cpp index 7475b852c..bf8e0148d 100644 --- a/panels/grapheditor.cpp +++ b/panels/grapheditor.cpp @@ -37,218 +37,226 @@ #include "panels.h" #include "debug.h" -GraphEditor::GraphEditor(QWidget* parent) : QDockWidget(parent), row(nullptr) { - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); +GraphEditor::GraphEditor(QWidget* parent) : Panel(parent), row(nullptr) { + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - setWindowTitle(tr("Graph Editor")); - resize(720, 480); + resize(720, 480); - QWidget* main_widget = new QWidget(this); - QVBoxLayout* layout = new QVBoxLayout(main_widget); - setWidget(main_widget); + QWidget* main_widget = new QWidget(this); + QVBoxLayout* layout = new QVBoxLayout(main_widget); + setWidget(main_widget); - QWidget* tool_widget = new QWidget(); - tool_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); - QHBoxLayout* tools = new QHBoxLayout(tool_widget); + QWidget* tool_widget = new QWidget(); + tool_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); + QHBoxLayout* tools = new QHBoxLayout(tool_widget); - QWidget* left_tool_widget = new QWidget(); - QHBoxLayout* left_tool_layout = new QHBoxLayout(left_tool_widget); - left_tool_layout->setSpacing(0); - left_tool_layout->setMargin(0); - tools->addWidget(left_tool_widget); - QWidget* center_tool_widget = new QWidget(); - QHBoxLayout* center_tool_layout = new QHBoxLayout(center_tool_widget); - center_tool_layout->setSpacing(0); - center_tool_layout->setMargin(0); - tools->addWidget(center_tool_widget); - QWidget* right_tool_widget = new QWidget(); - QHBoxLayout* right_tool_layout = new QHBoxLayout(right_tool_widget); - right_tool_layout->setSpacing(0); - right_tool_layout->setMargin(0); - tools->addWidget(right_tool_widget); + QWidget* left_tool_widget = new QWidget(); + QHBoxLayout* left_tool_layout = new QHBoxLayout(left_tool_widget); + left_tool_layout->setSpacing(0); + left_tool_layout->setMargin(0); + tools->addWidget(left_tool_widget); + QWidget* center_tool_widget = new QWidget(); + QHBoxLayout* center_tool_layout = new QHBoxLayout(center_tool_widget); + center_tool_layout->setSpacing(0); + center_tool_layout->setMargin(0); + tools->addWidget(center_tool_widget); + QWidget* right_tool_widget = new QWidget(); + QHBoxLayout* right_tool_layout = new QHBoxLayout(right_tool_widget); + right_tool_layout->setSpacing(0); + right_tool_layout->setMargin(0); + tools->addWidget(right_tool_widget); - keyframe_nav = new KeyframeNavigator(nullptr, false); - keyframe_nav->enable_keyframes(true); - keyframe_nav->enable_keyframe_toggle(false); - left_tool_layout->addWidget(keyframe_nav); - left_tool_layout->addStretch(); + keyframe_nav = new KeyframeNavigator(nullptr, false); + keyframe_nav->enable_keyframes(true); + keyframe_nav->enable_keyframe_toggle(false); + left_tool_layout->addWidget(keyframe_nav); + left_tool_layout->addStretch(); - linear_button = new QPushButton(tr("Linear")); - linear_button->setProperty("type", EFFECT_KEYFRAME_LINEAR); - linear_button->setCheckable(true); - bezier_button = new QPushButton(tr("Bezier")); - bezier_button->setProperty("type", EFFECT_KEYFRAME_BEZIER); - bezier_button->setCheckable(true); - hold_button = new QPushButton(tr("Hold")); - hold_button->setProperty("type", EFFECT_KEYFRAME_HOLD); - hold_button->setCheckable(true); + linear_button = new QPushButton(); + linear_button->setProperty("type", EFFECT_KEYFRAME_LINEAR); + linear_button->setCheckable(true); + bezier_button = new QPushButton(); + bezier_button->setProperty("type", EFFECT_KEYFRAME_BEZIER); + bezier_button->setCheckable(true); + hold_button = new QPushButton(); + hold_button->setProperty("type", EFFECT_KEYFRAME_HOLD); + hold_button->setCheckable(true); - center_tool_layout->addStretch(); - center_tool_layout->addWidget(linear_button); - center_tool_layout->addWidget(bezier_button); - center_tool_layout->addWidget(hold_button); + center_tool_layout->addStretch(); + center_tool_layout->addWidget(linear_button); + center_tool_layout->addWidget(bezier_button); + center_tool_layout->addWidget(hold_button); - layout->addWidget(tool_widget); + layout->addWidget(tool_widget); - QWidget* central_widget = new QWidget(); - QVBoxLayout* central_layout = new QVBoxLayout(central_widget); - central_layout->setSpacing(0); - central_layout->setMargin(0); - header = new TimelineHeader(); - header->viewer = panel_sequence_viewer; - central_layout->addWidget(header); - view = new GraphView(); - central_layout->addWidget(view); + QWidget* central_widget = new QWidget(); + QVBoxLayout* central_layout = new QVBoxLayout(central_widget); + central_layout->setSpacing(0); + central_layout->setMargin(0); + header = new TimelineHeader(); + header->viewer = panel_sequence_viewer; + central_layout->addWidget(header); + view = new GraphView(); + central_layout->addWidget(view); - layout->addWidget(central_widget); + layout->addWidget(central_widget); - QWidget* value_widget = new QWidget(); - value_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); - QHBoxLayout* values = new QHBoxLayout(value_widget); - values->addStretch(); + QWidget* value_widget = new QWidget(); + value_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); + QHBoxLayout* values = new QHBoxLayout(value_widget); + values->addStretch(); - QWidget* central_value_widget = new QWidget(); - value_layout = new QHBoxLayout(central_value_widget); - value_layout->setMargin(0); - value_layout->addWidget(new QLabel("")); // a spacer so the layout doesn't jump - values->addWidget(central_value_widget); + QWidget* central_value_widget = new QWidget(); + value_layout = new QHBoxLayout(central_value_widget); + value_layout->setMargin(0); + value_layout->addWidget(new QLabel("")); // a spacer so the layout doesn't jump + values->addWidget(central_value_widget); - values->addStretch(); - layout->addWidget(value_widget); + values->addStretch(); + layout->addWidget(value_widget); - current_row_desc = new QLabel(); - current_row_desc->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); - current_row_desc->setAlignment(Qt::AlignCenter); - layout->addWidget(current_row_desc); + current_row_desc = new QLabel(); + current_row_desc->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); + current_row_desc->setAlignment(Qt::AlignCenter); + layout->addWidget(current_row_desc); - connect(view, SIGNAL(zoom_changed(double, double)), header, SLOT(update_zoom(double))); - connect(view, SIGNAL(x_scroll_changed(int)), header, SLOT(set_scroll(int))); - connect(view, SIGNAL(selection_changed(bool, int)), this, SLOT(set_key_button_enabled(bool, int))); + connect(view, SIGNAL(zoom_changed(double, double)), header, SLOT(update_zoom(double))); + connect(view, SIGNAL(x_scroll_changed(int)), header, SLOT(set_scroll(int))); + connect(view, SIGNAL(selection_changed(bool, int)), this, SLOT(set_key_button_enabled(bool, int))); - connect(linear_button, SIGNAL(clicked(bool)), this, SLOT(set_keyframe_type())); - connect(bezier_button, SIGNAL(clicked(bool)), this, SLOT(set_keyframe_type())); - connect(hold_button, SIGNAL(clicked(bool)), this, SLOT(set_keyframe_type())); + connect(linear_button, SIGNAL(clicked(bool)), this, SLOT(set_keyframe_type())); + connect(bezier_button, SIGNAL(clicked(bool)), this, SLOT(set_keyframe_type())); + connect(hold_button, SIGNAL(clicked(bool)), this, SLOT(set_keyframe_type())); + + Retranslate(); +} + +void GraphEditor::Retranslate() { + setWindowTitle(tr("Graph Editor")); + linear_button->setText(tr("Linear")); + bezier_button->setText(tr("Bezier")); + hold_button->setText(tr("Hold")); } void GraphEditor::update_panel() { - if (isVisible()) { - if (row != nullptr) { - int slider_index = 0; - for (int i=0;ifieldCount();i++) { - EffectField* field = row->field(i); - if (field->type == EFFECT_FIELD_DOUBLE) { - slider_proxies.at(slider_index)->set_value(row->field(i)->get_current_data().toDouble(), false); - slider_index++; - } - } - } + if (isVisible()) { + if (row != nullptr) { + int slider_index = 0; + for (int i=0;ifieldCount();i++) { + EffectField* field = row->field(i); + if (field->type == EFFECT_FIELD_DOUBLE) { + slider_proxies.at(slider_index)->set_value(row->field(i)->get_current_data().toDouble(), false); + slider_index++; + } + } + } - header->update(); - view->update(); - } + header->update(); + view->update(); + } } void GraphEditor::set_row(EffectRow *r) { - for (int i=0;iisKeyframing()) { - for (int i=0;ifieldCount();i++) { - EffectField* field = r->field(i); - if (field->type == EFFECT_FIELD_DOUBLE) { - QPushButton* slider_button = new QPushButton(); - slider_button->setCheckable(true); - slider_button->setChecked(field->is_enabled()); - slider_button->setIcon(QIcon(":/icons/record.png")); - slider_button->setProperty("field", i); - slider_button->setIconSize(slider_button->iconSize()*0.5); - connect(slider_button, SIGNAL(toggled(bool)), this, SLOT(set_field_visibility(bool))); - slider_proxy_buttons.append(slider_button); - value_layout->addWidget(slider_button); + if (r != nullptr && r->isKeyframing()) { + for (int i=0;ifieldCount();i++) { + EffectField* field = r->field(i); + if (field->type == EFFECT_FIELD_DOUBLE) { + QPushButton* slider_button = new QPushButton(); + slider_button->setCheckable(true); + slider_button->setChecked(field->is_enabled()); + slider_button->setIcon(QIcon(":/icons/record.png")); + slider_button->setProperty("field", i); + slider_button->setIconSize(slider_button->iconSize()*0.5); + connect(slider_button, SIGNAL(toggled(bool)), this, SLOT(set_field_visibility(bool))); + slider_proxy_buttons.append(slider_button); + value_layout->addWidget(slider_button); - LabelSlider* slider = new LabelSlider(); - slider->set_color(get_curve_color(i, r->fieldCount()).name()); - connect(slider, SIGNAL(valueChanged()), this, SLOT(passthrough_slider_value())); - slider_proxies.append(slider); - value_layout->addWidget(slider); + LabelSlider* slider = new LabelSlider(); + slider->set_color(get_curve_color(i, r->fieldCount()).name()); + connect(slider, SIGNAL(valueChanged()), this, SLOT(passthrough_slider_value())); + slider_proxies.append(slider); + value_layout->addWidget(slider); - slider_proxy_sources.append(static_cast(field->ui_element)); + slider_proxy_sources.append(static_cast(field->ui_element)); - found_vals = true; - } - } - } + found_vals = true; + } + } + } - if (found_vals) { - row = r; - current_row_desc->setText(row->parent_effect->parent_clip->name + " :: " + row->parent_effect->meta->name + " :: " + row->get_name()); - header->set_visible_in(r->parent_effect->parent_clip->timeline_in); + if (found_vals) { + row = r; + current_row_desc->setText(row->parent_effect->parent_clip->name + " :: " + row->parent_effect->meta->name + " :: " + row->get_name()); + header->set_visible_in(r->parent_effect->parent_clip->timeline_in); - connect(keyframe_nav, SIGNAL(goto_previous_key()), row, SLOT(goto_previous_key())); - connect(keyframe_nav, SIGNAL(toggle_key()), row, SLOT(toggle_key())); - connect(keyframe_nav, SIGNAL(goto_next_key()), row, SLOT(goto_next_key())); - } else { - row = nullptr; - current_row_desc->setText(nullptr); - } - view->set_row(row); - update_panel(); + connect(keyframe_nav, SIGNAL(goto_previous_key()), row, SLOT(goto_previous_key())); + connect(keyframe_nav, SIGNAL(toggle_key()), row, SLOT(toggle_key())); + connect(keyframe_nav, SIGNAL(goto_next_key()), row, SLOT(goto_next_key())); + } else { + row = nullptr; + current_row_desc->setText(nullptr); + } + view->set_row(row); + update_panel(); } bool GraphEditor::view_is_focused() { - return view->hasFocus() || header->hasFocus(); + return view->hasFocus() || header->hasFocus(); } bool GraphEditor::view_is_under_mouse() { - return view->underMouse() || header->underMouse(); + return view->underMouse() || header->underMouse(); } void GraphEditor::delete_selected_keys() { - view->delete_selected_keys(); + view->delete_selected_keys(); } void GraphEditor::select_all() { - view->select_all(); + view->select_all(); } void GraphEditor::set_key_button_enabled(bool e, int type) { - linear_button->setEnabled(e); - linear_button->setChecked(type == EFFECT_KEYFRAME_LINEAR); - bezier_button->setEnabled(e); - bezier_button->setChecked(type == EFFECT_KEYFRAME_BEZIER); - hold_button->setEnabled(e); - hold_button->setChecked(type == EFFECT_KEYFRAME_HOLD); + linear_button->setEnabled(e); + linear_button->setChecked(type == EFFECT_KEYFRAME_LINEAR); + bezier_button->setEnabled(e); + bezier_button->setChecked(type == EFFECT_KEYFRAME_BEZIER); + hold_button->setEnabled(e); + hold_button->setChecked(type == EFFECT_KEYFRAME_HOLD); } void GraphEditor::passthrough_slider_value() { - for (int i=0;iset_value(slider_proxies.at(i)->value(), true); - } - } + for (int i=0;iset_value(slider_proxies.at(i)->value(), true); + } + } } void GraphEditor::set_keyframe_type() { - linear_button->setChecked(linear_button == sender()); - bezier_button->setChecked(bezier_button == sender()); - hold_button->setChecked(hold_button == sender()); - view->set_selected_keyframe_type(sender()->property("type").toInt()); + linear_button->setChecked(linear_button == sender()); + bezier_button->setChecked(bezier_button == sender()); + hold_button->setChecked(hold_button == sender()); + view->set_selected_keyframe_type(sender()->property("type").toInt()); } void GraphEditor::set_field_visibility(bool b) { - view->set_field_visibility(sender()->property("field").toInt(), b); + view->set_field_visibility(sender()->property("field").toInt(), b); } diff --git a/panels/grapheditor.h b/panels/grapheditor.h index 4b22e9d9f..5a6eea0a2 100644 --- a/panels/grapheditor.h +++ b/panels/grapheditor.h @@ -21,45 +21,48 @@ #ifndef GRAPHEDITOR_H #define GRAPHEDITOR_H -#include #include #include #include +#include "ui/panel.h" #include "ui/graphview.h" #include "ui/timelineheader.h" #include "ui/labelslider.h" #include "ui/keyframenavigator.h" #include "project/effectrow.h" -class GraphEditor : public QDockWidget { - Q_OBJECT +class GraphEditor : public Panel { + Q_OBJECT public: - GraphEditor(QWidget* parent = nullptr); - void update_panel(); - void set_row(EffectRow* r); - bool view_is_focused(); - bool view_is_under_mouse(); - void delete_selected_keys(); - void select_all(); + GraphEditor(QWidget* parent = nullptr); + + void update_panel(); + void set_row(EffectRow* r); + bool view_is_focused(); + bool view_is_under_mouse(); + void delete_selected_keys(); + void select_all(); +protected: + virtual void Retranslate() override; private: - GraphView* view; - TimelineHeader* header; - QHBoxLayout* value_layout; - QVector slider_proxies; - QVector slider_proxy_buttons; - QVector slider_proxy_sources; - QLabel* current_row_desc; - EffectRow* row; - KeyframeNavigator* keyframe_nav; - QPushButton* linear_button; - QPushButton* bezier_button; - QPushButton* hold_button; + GraphView* view; + TimelineHeader* header; + QHBoxLayout* value_layout; + QVector slider_proxies; + QVector slider_proxy_buttons; + QVector slider_proxy_sources; + QLabel* current_row_desc; + EffectRow* row; + KeyframeNavigator* keyframe_nav; + QPushButton* linear_button; + QPushButton* bezier_button; + QPushButton* hold_button; private slots: - void set_key_button_enabled(bool e, int type); - void passthrough_slider_value(); - void set_keyframe_type(); - void set_field_visibility(bool b); + void set_key_button_enabled(bool e, int type); + void passthrough_slider_value(); + void set_keyframe_type(); + void set_field_visibility(bool b); }; #endif // GRAPHEDITOR_H diff --git a/panels/panels.cpp b/panels/panels.cpp index 0bc9bf83a..5a6794ed5 100644 --- a/panels/panels.cpp +++ b/panels/panels.cpp @@ -39,175 +39,175 @@ Timeline* panel_timeline = nullptr; GraphEditor* panel_graph_editor = nullptr; void update_effect_controls() { - // SEND CLIPS TO EFFECT CONTROLS - // find out how many clips are selected - // limits to one video clip and one audio clip and only if they're linked - // one of these days it might be nice to have multiple clips in the effects panel - bool multiple = false; - int vclip = -1; - int aclip = -1; - QVector selected_clips; - int mode = kTransitionNone; - if (olive::ActiveSequence != nullptr) { - for (int i=0;iclips.size();i++) { - ClipPtr clip = olive::ActiveSequence->clips.at(i); - if (clip != nullptr) { - for (int j=0;jselections.size();j++) { - const Selection& s = olive::ActiveSequence->selections.at(j); - bool add = true; - if (clip->timeline_in >= s.in && clip->timeline_out <= s.out && clip->track == s.track) { - mode = kTransitionNone; - } else if (selection_contains_transition(s, clip, kTransitionOpening)) { - mode = kTransitionOpening; - } else if (selection_contains_transition(s, clip, kTransitionClosing)) { - mode = kTransitionClosing; - } else { - add = false; - } + // SEND CLIPS TO EFFECT CONTROLS + // find out how many clips are selected + // limits to one video clip and one audio clip and only if they're linked + // one of these days it might be nice to have multiple clips in the effects panel + bool multiple = false; + int vclip = -1; + int aclip = -1; + QVector selected_clips; + int mode = kTransitionNone; + if (olive::ActiveSequence != nullptr) { + for (int i=0;iclips.size();i++) { + ClipPtr clip = olive::ActiveSequence->clips.at(i); + if (clip != nullptr) { + for (int j=0;jselections.size();j++) { + const Selection& s = olive::ActiveSequence->selections.at(j); + bool add = true; + if (clip->timeline_in >= s.in && clip->timeline_out <= s.out && clip->track == s.track) { + mode = kTransitionNone; + } else if (selection_contains_transition(s, clip, kTransitionOpening)) { + mode = kTransitionOpening; + } else if (selection_contains_transition(s, clip, kTransitionClosing)) { + mode = kTransitionClosing; + } else { + add = false; + } - if (add) { - if (clip->track < 0 && vclip == -1) { - vclip = i; - } else if (clip->track >= 0 && aclip == -1) { - aclip = i; - } else { - vclip = -2; - aclip = -2; - multiple = true; - multiple = true; - break; - } - } - } - } - } + if (add) { + if (clip->track < 0 && vclip == -1) { + vclip = i; + } else if (clip->track >= 0 && aclip == -1) { + aclip = i; + } else { + vclip = -2; + aclip = -2; + multiple = true; + multiple = true; + break; + } + } + } + } + } - if (!multiple) { - // check if aclip is linked to vclip - if (vclip >= 0) selected_clips.append(vclip); - if (aclip >= 0) selected_clips.append(aclip); - if (vclip >= 0 && aclip >= 0) { - bool found = false; - ClipPtr vclip_ref = olive::ActiveSequence->clips.at(vclip); - for (int i=0;ilinked.size();i++) { - if (vclip_ref->linked.at(i) == aclip) { - found = true; - break; - } - } - if (!found) { - // only display multiple clips if they're linked - selected_clips.clear(); - multiple = true; - } - } - } - } + if (!multiple) { + // check if aclip is linked to vclip + if (vclip >= 0) selected_clips.append(vclip); + if (aclip >= 0) selected_clips.append(aclip); + if (vclip >= 0 && aclip >= 0) { + bool found = false; + ClipPtr vclip_ref = olive::ActiveSequence->clips.at(vclip); + for (int i=0;ilinked.size();i++) { + if (vclip_ref->linked.at(i) == aclip) { + found = true; + break; + } + } + if (!found) { + // only display multiple clips if they're linked + selected_clips.clear(); + multiple = true; + } + } + } + } - bool same = (selected_clips.size() == panel_effect_controls->selected_clips.size() - && panel_effect_controls->get_mode() == mode); - if (same) { - for (int i=0;iselected_clips.at(i)) { - same = false; - break; - } - } - } + bool same = (selected_clips.size() == panel_effect_controls->selected_clips.size() + && panel_effect_controls->get_mode() == mode); + if (same) { + for (int i=0;iselected_clips.at(i)) { + same = false; + break; + } + } + } - if (panel_effect_controls->multiple != multiple || !same) { - panel_effect_controls->multiple = multiple; + if (panel_effect_controls->multiple != multiple || !same) { + panel_effect_controls->multiple = multiple; - panel_effect_controls->set_clips(selected_clips, mode); - } + panel_effect_controls->set_clips(selected_clips, mode); + } } void update_ui(bool modified) { - if (modified) { - update_effect_controls(); - } - panel_effect_controls->update_keyframes(); - panel_timeline->repaint_timeline(); - panel_sequence_viewer->update_viewer(); - panel_graph_editor->update_panel(); + if (modified) { + update_effect_controls(); + } + panel_effect_controls->update_keyframes(); + panel_timeline->repaint_timeline(); + panel_sequence_viewer->update_viewer(); + panel_graph_editor->update_panel(); } QDockWidget *get_focused_panel(bool force_hover) { - QDockWidget* w = nullptr; - if (olive::CurrentConfig.hover_focus || force_hover) { - if (panel_project->underMouse()) { - w = panel_project; - } else if (panel_effect_controls->underMouse()) { - w = panel_effect_controls; - } else if (panel_sequence_viewer->underMouse()) { - w = panel_sequence_viewer; - } else if (panel_footage_viewer->underMouse()) { - w = panel_footage_viewer; - } else if (panel_timeline->underMouse()) { - w = panel_timeline; - } else if (panel_graph_editor->view_is_under_mouse()) { - w = panel_graph_editor; - } - } - if (w == nullptr) { - if (panel_project->is_focused()) { - w = panel_project; - } 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; - } else if (panel_footage_viewer->is_focused()) { - w = panel_footage_viewer; - } else if (panel_timeline->focused()) { - w = panel_timeline; - } else if (panel_graph_editor->view_is_focused()) { - w = panel_graph_editor; - } - } - return w; + QDockWidget* w = nullptr; + if (olive::CurrentConfig.hover_focus || force_hover) { + if (panel_project->underMouse()) { + w = panel_project; + } else if (panel_effect_controls->underMouse()) { + w = panel_effect_controls; + } else if (panel_sequence_viewer->underMouse()) { + w = panel_sequence_viewer; + } else if (panel_footage_viewer->underMouse()) { + w = panel_footage_viewer; + } else if (panel_timeline->underMouse()) { + w = panel_timeline; + } else if (panel_graph_editor->view_is_under_mouse()) { + w = panel_graph_editor; + } + } + if (w == nullptr) { + if (panel_project->is_focused()) { + w = panel_project; + } 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; + } else if (panel_footage_viewer->is_focused()) { + w = panel_footage_viewer; + } else if (panel_timeline->focused()) { + w = panel_timeline; + } else if (panel_graph_editor->view_is_focused()) { + w = panel_graph_editor; + } + } + return w; } void alloc_panels(QWidget* parent) { - // TODO maybe replace these with non-pointers later on? - panel_sequence_viewer = new Viewer(parent); - panel_sequence_viewer->setObjectName("seq_viewer"); - panel_sequence_viewer->set_panel_name(QCoreApplication::translate("Viewer", "Sequence Viewer")); - panel_footage_viewer = new Viewer(parent); - panel_footage_viewer->setObjectName("footage_viewer"); - panel_footage_viewer->set_panel_name(QCoreApplication::translate("Viewer", "Media Viewer")); - panel_project = new Project(parent); - panel_project->setObjectName("proj_root"); - panel_effect_controls = new EffectControls(parent); - init_effects(); - panel_effect_controls->setObjectName("fx_controls"); - panel_timeline = new Timeline(parent); - panel_timeline->setObjectName("timeline"); - panel_graph_editor = new GraphEditor(parent); - panel_graph_editor->setObjectName("graph_editor"); + // TODO maybe replace these with non-pointers later on? + panel_sequence_viewer = new Viewer(parent); + panel_sequence_viewer->setObjectName("seq_viewer"); + panel_sequence_viewer->set_panel_name(QCoreApplication::translate("Viewer", "Sequence Viewer")); + panel_footage_viewer = new Viewer(parent); + panel_footage_viewer->setObjectName("footage_viewer"); + panel_footage_viewer->set_panel_name(QCoreApplication::translate("Viewer", "Media Viewer")); + panel_project = new Project(parent); + panel_project->setObjectName("proj_root"); + panel_effect_controls = new EffectControls(parent); + init_effects(); + panel_effect_controls->setObjectName("fx_controls"); + panel_timeline = new Timeline(parent); + panel_timeline->setObjectName("timeline"); + panel_graph_editor = new GraphEditor(parent); + panel_graph_editor->setObjectName("graph_editor"); } void free_panels() { - delete panel_sequence_viewer; - panel_sequence_viewer = nullptr; - delete panel_footage_viewer; - panel_footage_viewer = nullptr; - delete panel_project; - panel_project = nullptr; - delete panel_effect_controls; - panel_effect_controls = nullptr; - delete panel_timeline; - panel_timeline = nullptr; + delete panel_sequence_viewer; + panel_sequence_viewer = nullptr; + delete panel_footage_viewer; + panel_footage_viewer = nullptr; + delete panel_project; + panel_project = nullptr; + delete panel_effect_controls; + panel_effect_controls = nullptr; + delete panel_timeline; + panel_timeline = nullptr; } void scroll_to_frame_internal(QScrollBar* bar, long frame, double zoom, int area_width) { - int screen_point = getScreenPointFromFrame(zoom, frame) - bar->value(); - int min_x = area_width*0.1; - int max_x = area_width-min_x; - if (screen_point < min_x) { - bar->setValue(getScreenPointFromFrame(zoom, frame) - min_x); - } else if (screen_point > max_x) { - bar->setValue(getScreenPointFromFrame(zoom, frame) - max_x); - } + int screen_point = getScreenPointFromFrame(zoom, frame) - bar->value(); + int min_x = area_width*0.1; + int max_x = area_width-min_x; + if (screen_point < min_x) { + bar->setValue(getScreenPointFromFrame(zoom, frame) - min_x); + } else if (screen_point > max_x) { + bar->setValue(getScreenPointFromFrame(zoom, frame) - max_x); + } } diff --git a/panels/project.cpp b/panels/project.cpp index 34c7ff843..58d1b6324 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -60,8 +60,8 @@ #include extern "C" { - #include - #include +#include +#include } #define MAXIMUM_RECENT_PROJECTS 10 // FIXME: should be configurable @@ -70,1265 +70,1269 @@ QString autorecovery_filename; QStringList recent_projects; Project::Project(QWidget *parent) : - QDockWidget(parent) + Panel(parent) { - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - QWidget* dockWidgetContents = new QWidget(this); + QWidget* dockWidgetContents = new QWidget(this); - QVBoxLayout* verticalLayout = new QVBoxLayout(dockWidgetContents); - verticalLayout->setMargin(0); - verticalLayout->setSpacing(0); + QVBoxLayout* verticalLayout = new QVBoxLayout(dockWidgetContents); + verticalLayout->setMargin(0); + verticalLayout->setSpacing(0); - setWidget(dockWidgetContents); + setWidget(dockWidgetContents); - sources_common = new SourcesCommon(this); + sources_common = new SourcesCommon(this); - sorter = new ProjectFilter(this); - sorter->setSourceModel(&olive::project_model); + sorter = new ProjectFilter(this); + sorter->setSourceModel(&olive::project_model); - // optional toolbar - toolbar_widget = new QWidget(); - toolbar_widget->setVisible(olive::CurrentConfig.show_project_toolbar); - toolbar_widget->setObjectName("project_toolbar"); + // optional toolbar + toolbar_widget = new QWidget(); + toolbar_widget->setVisible(olive::CurrentConfig.show_project_toolbar); + toolbar_widget->setObjectName("project_toolbar"); - QHBoxLayout* toolbar = new QHBoxLayout(toolbar_widget); - toolbar->setMargin(0); - toolbar->setSpacing(0); + QHBoxLayout* toolbar = new QHBoxLayout(toolbar_widget); + toolbar->setMargin(0); + toolbar->setSpacing(0); - QPushButton* toolbar_new = new QPushButton(); - QIcon icon1; - icon1.addFile(QStringLiteral(":/icons/add-button.png"), QSize(), QIcon::Normal, QIcon::On); - icon1.addFile(QStringLiteral(":/icons/add-button-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); - toolbar_new->setIcon(icon1); - toolbar_new->setToolTip("New"); - connect(toolbar_new, SIGNAL(clicked(bool)), this, SLOT(make_new_menu())); - toolbar->addWidget(toolbar_new); + QPushButton* toolbar_new = new QPushButton(); + QIcon icon1; + icon1.addFile(QStringLiteral(":/icons/add-button.png"), QSize(), QIcon::Normal, QIcon::On); + icon1.addFile(QStringLiteral(":/icons/add-button-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolbar_new->setIcon(icon1); + toolbar_new->setToolTip("New"); + connect(toolbar_new, SIGNAL(clicked(bool)), this, SLOT(make_new_menu())); + toolbar->addWidget(toolbar_new); - QPushButton* toolbar_open = new QPushButton(); - QIcon icon2; - icon2.addFile(QStringLiteral(":/icons/open.png"), QSize(), QIcon::Normal, QIcon::On); - icon2.addFile(QStringLiteral(":/icons/open-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); - toolbar_open->setIcon(icon2); - toolbar_open->setToolTip("Open Project"); - connect(toolbar_open, SIGNAL(clicked(bool)), olive::Global.get(), SLOT(open_project())); - toolbar->addWidget(toolbar_open); + QPushButton* toolbar_open = new QPushButton(); + QIcon icon2; + icon2.addFile(QStringLiteral(":/icons/open.png"), QSize(), QIcon::Normal, QIcon::On); + icon2.addFile(QStringLiteral(":/icons/open-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolbar_open->setIcon(icon2); + toolbar_open->setToolTip("Open Project"); + connect(toolbar_open, SIGNAL(clicked(bool)), olive::Global.get(), SLOT(open_project())); + toolbar->addWidget(toolbar_open); - QPushButton* toolbar_save = new QPushButton(); - QIcon icon3; - icon3.addFile(QStringLiteral(":/icons/save.png"), QSize(), QIcon::Normal, QIcon::On); - icon3.addFile(QStringLiteral(":/icons/save-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); - toolbar_save->setIcon(icon3); - toolbar_save->setToolTip("Save Project"); - connect(toolbar_save, SIGNAL(clicked(bool)), olive::Global.get(), SLOT(save_project())); - toolbar->addWidget(toolbar_save); + QPushButton* toolbar_save = new QPushButton(); + QIcon icon3; + icon3.addFile(QStringLiteral(":/icons/save.png"), QSize(), QIcon::Normal, QIcon::On); + icon3.addFile(QStringLiteral(":/icons/save-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolbar_save->setIcon(icon3); + toolbar_save->setToolTip("Save Project"); + connect(toolbar_save, SIGNAL(clicked(bool)), olive::Global.get(), SLOT(save_project())); + toolbar->addWidget(toolbar_save); - QPushButton* toolbar_undo = new QPushButton(); - QIcon icon4; - icon4.addFile(QStringLiteral(":/icons/undo.png"), QSize(), QIcon::Normal, QIcon::On); - icon4.addFile(QStringLiteral(":/icons/undo-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); - toolbar_undo->setIcon(icon4); - toolbar_undo->setToolTip("Undo"); - connect(toolbar_undo, SIGNAL(clicked(bool)), olive::Global.get(), SLOT(undo())); - toolbar->addWidget(toolbar_undo); + QPushButton* toolbar_undo = new QPushButton(); + QIcon icon4; + icon4.addFile(QStringLiteral(":/icons/undo.png"), QSize(), QIcon::Normal, QIcon::On); + icon4.addFile(QStringLiteral(":/icons/undo-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolbar_undo->setIcon(icon4); + toolbar_undo->setToolTip("Undo"); + connect(toolbar_undo, SIGNAL(clicked(bool)), olive::Global.get(), SLOT(undo())); + toolbar->addWidget(toolbar_undo); - QPushButton* toolbar_redo = new QPushButton(); - QIcon icon5; - icon5.addFile(QStringLiteral(":/icons/redo.png"), QSize(), QIcon::Normal, QIcon::On); - icon5.addFile(QStringLiteral(":/icons/redo-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); - toolbar_redo->setIcon(icon5); - toolbar_redo->setToolTip("Redo"); - connect(toolbar_redo, SIGNAL(clicked(bool)), olive::Global.get(), SLOT(redo())); - toolbar->addWidget(toolbar_redo); + QPushButton* toolbar_redo = new QPushButton(); + QIcon icon5; + icon5.addFile(QStringLiteral(":/icons/redo.png"), QSize(), QIcon::Normal, QIcon::On); + icon5.addFile(QStringLiteral(":/icons/redo-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolbar_redo->setIcon(icon5); + toolbar_redo->setToolTip("Redo"); + connect(toolbar_redo, SIGNAL(clicked(bool)), olive::Global.get(), SLOT(redo())); + toolbar->addWidget(toolbar_redo); - QLineEdit* toolbar_search = new QLineEdit(); - toolbar_search->setClearButtonEnabled(true); - toolbar_search->setPlaceholderText(tr("Search media, markers, etc.")); - connect(toolbar_search, SIGNAL(textChanged(QString)), sorter, SLOT(update_search_filter(const QString&))); - toolbar->addWidget(toolbar_search); + toolbar_search = new QLineEdit(); + toolbar_search->setClearButtonEnabled(true); + connect(toolbar_search, SIGNAL(textChanged(QString)), sorter, SLOT(update_search_filter(const QString&))); + toolbar->addWidget(toolbar_search); - QPushButton* toolbar_tree_view = new QPushButton(); - QIcon icon6; - icon6.addFile(QStringLiteral(":/icons/treeview.png"), QSize(), QIcon::Normal, QIcon::On); - icon6.addFile(QStringLiteral(":/icons/treeview-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); - toolbar_tree_view->setIcon(icon6); - toolbar_tree_view->setToolTip("Tree View"); - connect(toolbar_tree_view, SIGNAL(clicked(bool)), this, SLOT(set_tree_view())); - toolbar->addWidget(toolbar_tree_view); + QPushButton* toolbar_tree_view = new QPushButton(); + QIcon icon6; + icon6.addFile(QStringLiteral(":/icons/treeview.png"), QSize(), QIcon::Normal, QIcon::On); + icon6.addFile(QStringLiteral(":/icons/treeview-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolbar_tree_view->setIcon(icon6); + toolbar_tree_view->setToolTip("Tree View"); + connect(toolbar_tree_view, SIGNAL(clicked(bool)), this, SLOT(set_tree_view())); + toolbar->addWidget(toolbar_tree_view); - QPushButton* toolbar_icon_view = new QPushButton(); - QIcon icon7; - icon7.addFile(QStringLiteral(":/icons/iconview.png"), QSize(), QIcon::Normal, QIcon::On); - icon7.addFile(QStringLiteral(":/icons/iconview-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); - toolbar_icon_view->setIcon(icon7); - toolbar_icon_view->setToolTip("Icon View"); - connect(toolbar_icon_view, SIGNAL(clicked(bool)), this, SLOT(set_icon_view())); - toolbar->addWidget(toolbar_icon_view); + QPushButton* toolbar_icon_view = new QPushButton(); + QIcon icon7; + icon7.addFile(QStringLiteral(":/icons/iconview.png"), QSize(), QIcon::Normal, QIcon::On); + icon7.addFile(QStringLiteral(":/icons/iconview-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolbar_icon_view->setIcon(icon7); + toolbar_icon_view->setToolTip("Icon View"); + connect(toolbar_icon_view, SIGNAL(clicked(bool)), this, SLOT(set_icon_view())); + toolbar->addWidget(toolbar_icon_view); - verticalLayout->addWidget(toolbar_widget); + verticalLayout->addWidget(toolbar_widget); - // tree view - tree_view = new SourceTable(); - tree_view->project_parent = this; - tree_view->setModel(sorter); - verticalLayout->addWidget(tree_view); + // tree view + tree_view = new SourceTable(); + tree_view->project_parent = this; + tree_view->setModel(sorter); + verticalLayout->addWidget(tree_view); - // Set the first column width - // I'm not sure if there's a better way to do this, default behavior seems to have all columns fixed width - // and let the last column fill up the remainder when really the opposite would be preferable (having the - // first column fill up the majority of the space). Anyway, this will probably do for now. - tree_view->setColumnWidth(0, tree_view->width()/2); + // Set the first column width + // I'm not sure if there's a better way to do this, default behavior seems to have all columns fixed width + // and let the last column fill up the remainder when really the opposite would be preferable (having the + // first column fill up the majority of the space). Anyway, this will probably do for now. + tree_view->setColumnWidth(0, tree_view->width()/2); - // icon view - icon_view_container = new QWidget(); + // icon view + icon_view_container = new QWidget(); - QVBoxLayout* icon_view_container_layout = new QVBoxLayout(icon_view_container); - icon_view_container_layout->setMargin(0); - icon_view_container_layout->setSpacing(0); + QVBoxLayout* icon_view_container_layout = new QVBoxLayout(icon_view_container); + icon_view_container_layout->setMargin(0); + icon_view_container_layout->setSpacing(0); - QHBoxLayout* icon_view_controls = new QHBoxLayout(); - icon_view_controls->setMargin(0); - icon_view_controls->setSpacing(0); + QHBoxLayout* icon_view_controls = new QHBoxLayout(); + icon_view_controls->setMargin(0); + icon_view_controls->setSpacing(0); - QIcon directory_up_button; - directory_up_button.addFile(":/icons/dirup.png", QSize(), QIcon::Normal); - directory_up_button.addFile(":/icons/dirup-disabled.png", QSize(), QIcon::Disabled); + QIcon directory_up_button; + directory_up_button.addFile(":/icons/dirup.png", QSize(), QIcon::Normal); + directory_up_button.addFile(":/icons/dirup-disabled.png", QSize(), QIcon::Disabled); - directory_up = new QPushButton(); - directory_up->setIcon(directory_up_button); - directory_up->setEnabled(false); - icon_view_controls->addWidget(directory_up); + directory_up = new QPushButton(); + directory_up->setIcon(directory_up_button); + directory_up->setEnabled(false); + icon_view_controls->addWidget(directory_up); - icon_view_controls->addStretch(); + icon_view_controls->addStretch(); - QSlider* icon_size_slider = new QSlider(Qt::Horizontal); - icon_size_slider->setMinimum(16); - icon_size_slider->setMaximum(120); - icon_view_controls->addWidget(icon_size_slider); - connect(icon_size_slider, SIGNAL(valueChanged(int)), this, SLOT(set_icon_view_size(int))); + QSlider* icon_size_slider = new QSlider(Qt::Horizontal); + icon_size_slider->setMinimum(16); + icon_size_slider->setMaximum(120); + icon_view_controls->addWidget(icon_size_slider); + connect(icon_size_slider, SIGNAL(valueChanged(int)), this, SLOT(set_icon_view_size(int))); - icon_view_container_layout->addLayout(icon_view_controls); + icon_view_container_layout->addLayout(icon_view_controls); - icon_view = new SourceIconView(); - icon_view->project_parent = this; - icon_view->setModel(sorter); - icon_view->setIconSize(QSize(100, 100)); - icon_view->setViewMode(QListView::IconMode); - icon_view->setUniformItemSizes(true); - icon_view_container_layout->addWidget(icon_view); + icon_view = new SourceIconView(); + icon_view->project_parent = this; + icon_view->setModel(sorter); + icon_view->setIconSize(QSize(100, 100)); + icon_view->setViewMode(QListView::IconMode); + icon_view->setUniformItemSizes(true); + icon_view_container_layout->addWidget(icon_view); - icon_size_slider->setValue(icon_view->iconSize().height()); + icon_size_slider->setValue(icon_view->iconSize().height()); - verticalLayout->addWidget(icon_view_container); + verticalLayout->addWidget(icon_view_container); - connect(directory_up, SIGNAL(clicked(bool)), this, SLOT(go_up_dir())); - connect(icon_view, SIGNAL(changed_root()), this, SLOT(set_up_dir_enabled())); + connect(directory_up, SIGNAL(clicked(bool)), this, SLOT(go_up_dir())); + connect(icon_view, SIGNAL(changed_root()), this, SLOT(set_up_dir_enabled())); - setWindowTitle(tr("Project")); + update_view_type(); - update_view_type(); + Retranslate(); } Project::~Project() { - delete sorter; + delete sorter; +} + +void Project::Retranslate() { + toolbar_search->setPlaceholderText(tr("Search media, markers, etc.")); + setWindowTitle(tr("Project")); } QString Project::get_next_sequence_name(QString start) { - if (start.isEmpty()) start = tr("Sequence"); + if (start.isEmpty()) start = tr("Sequence"); - int n = 1; - bool found = true; - QString name; - while (found) { - found = false; - name = start + " "; - if (n < 10) { - name += "0"; - } - name += QString::number(n); - for (int i=0;iget_name(), name, Qt::CaseInsensitive) == 0) { - found = true; - n++; - break; - } - } - } - return name; + int n = 1; + bool found = true; + QString name; + while (found) { + found = false; + name = start + " "; + if (n < 10) { + name += "0"; + } + name += QString::number(n); + for (int i=0;iget_name(), name, Qt::CaseInsensitive) == 0) { + found = true; + n++; + break; + } + } + } + return name; } SequencePtr create_sequence_from_media(QVector& media_list) { - SequencePtr s(new Sequence()); + SequencePtr s(new Sequence()); - s->name = panel_project->get_next_sequence_name(); + s->name = panel_project->get_next_sequence_name(); - // shitty hardcoded default values - s->width = 1920; - s->height = 1080; - s->frame_rate = 29.97; - s->audio_frequency = 48000; - s->audio_layout = 3; + // shitty hardcoded default values + s->width = 1920; + s->height = 1080; + s->frame_rate = 29.97; + s->audio_frequency = 48000; + s->audio_layout = 3; - bool got_video_values = false; - bool got_audio_values = false; - for (int i=0;iget_type()) { - case MEDIA_TYPE_FOOTAGE: - { - FootagePtr m = media->to_footage(); - if (m->ready) { - if (!got_video_values) { - for (int j=0;jvideo_tracks.size();j++) { - const FootageStream& ms = m->video_tracks.at(j); - s->width = ms.video_width; - s->height = ms.video_height; - if (!qFuzzyCompare(ms.video_frame_rate, 0.0)) { - s->frame_rate = ms.video_frame_rate * m->speed; + bool got_video_values = false; + bool got_audio_values = false; + for (int i=0;iget_type()) { + case MEDIA_TYPE_FOOTAGE: + { + FootagePtr m = media->to_footage(); + if (m->ready) { + if (!got_video_values) { + for (int j=0;jvideo_tracks.size();j++) { + const FootageStream& ms = m->video_tracks.at(j); + s->width = ms.video_width; + s->height = ms.video_height; + if (!qFuzzyCompare(ms.video_frame_rate, 0.0)) { + s->frame_rate = ms.video_frame_rate * m->speed; - if (ms.video_interlacing != VIDEO_PROGRESSIVE) s->frame_rate *= 2; + if (ms.video_interlacing != VIDEO_PROGRESSIVE) s->frame_rate *= 2; - // only break with a decent frame rate, otherwise there may be a better candidate - got_video_values = true; - break; - } - } - } - if (!got_audio_values && m->audio_tracks.size() > 0) { - const FootageStream& ms = m->audio_tracks.at(0); - s->audio_frequency = ms.audio_frequency; - got_audio_values = true; - } - } - } - break; - case MEDIA_TYPE_SEQUENCE: - { - SequencePtr seq = media->to_sequence(); - s->width = seq->width; - s->height = seq->height; - s->frame_rate = seq->frame_rate; - s->audio_frequency = seq->audio_frequency; - s->audio_layout = seq->audio_layout; + // only break with a decent frame rate, otherwise there may be a better candidate + got_video_values = true; + break; + } + } + } + if (!got_audio_values && m->audio_tracks.size() > 0) { + const FootageStream& ms = m->audio_tracks.at(0); + s->audio_frequency = ms.audio_frequency; + got_audio_values = true; + } + } + } + break; + case MEDIA_TYPE_SEQUENCE: + { + SequencePtr seq = media->to_sequence(); + s->width = seq->width; + s->height = seq->height; + s->frame_rate = seq->frame_rate; + s->audio_frequency = seq->audio_frequency; + s->audio_layout = seq->audio_layout; - got_video_values = true; - got_audio_values = true; - } - break; - } - if (got_video_values && got_audio_values) break; - } + got_video_values = true; + got_audio_values = true; + } + break; + } + if (got_video_values && got_audio_values) break; + } - return s; + return s; } void Project::duplicate_selected() { - QModelIndexList items = get_current_selected(); - bool duped = false; - ComboAction* ca = new ComboAction(); - for (int j=0;jget_type() == MEDIA_TYPE_SEQUENCE) { - create_sequence_internal(ca, i->to_sequence()->copy(), false, item_to_media(items.at(j).parent())); - duped = true; - } - } - if (duped) { - olive::UndoStack.push(ca); - } else { - delete ca; - } + QModelIndexList items = get_current_selected(); + bool duped = false; + ComboAction* ca = new ComboAction(); + for (int j=0;jget_type() == MEDIA_TYPE_SEQUENCE) { + create_sequence_internal(ca, i->to_sequence()->copy(), false, item_to_media(items.at(j).parent())); + duped = true; + } + } + if (duped) { + olive::UndoStack.push(ca); + } else { + delete ca; + } } void Project::replace_selected_file() { - QModelIndexList selected_items = get_current_selected(); - if (selected_items.size() == 1) { - Media* item = item_to_media(selected_items.at(0)); - if (item->get_type() == MEDIA_TYPE_FOOTAGE) { - replace_media(item, nullptr); - } - } + QModelIndexList selected_items = get_current_selected(); + if (selected_items.size() == 1) { + Media* item = item_to_media(selected_items.at(0)); + if (item->get_type() == MEDIA_TYPE_FOOTAGE) { + replace_media(item, nullptr); + } + } } void Project::replace_media(Media* item, QString filename) { - if (filename.isEmpty()) { - filename = QFileDialog::getOpenFileName( - this, - tr("Replace '%1'").arg(item->get_name()), - "", - tr("All Files") + " (*)"); - } - if (!filename.isEmpty()) { - ReplaceMediaCommand* rmc = new ReplaceMediaCommand(item, filename); - olive::UndoStack.push(rmc); - } + if (filename.isEmpty()) { + filename = QFileDialog::getOpenFileName( + this, + tr("Replace '%1'").arg(item->get_name()), + "", + tr("All Files") + " (*)"); + } + if (!filename.isEmpty()) { + ReplaceMediaCommand* rmc = new ReplaceMediaCommand(item, filename); + olive::UndoStack.push(rmc); + } } void Project::replace_clip_media() { - if (olive::ActiveSequence == nullptr) { - QMessageBox::critical(this, - tr("No active sequence"), - tr("No sequence is active, please open the sequence you want to replace clips from."), - QMessageBox::Ok); - } else { - QModelIndexList selected_items = get_current_selected(); - if (selected_items.size() == 1) { - Media* item = item_to_media(selected_items.at(0)); - if (item->get_type() == MEDIA_TYPE_SEQUENCE && olive::ActiveSequence == item->to_sequence()) { - QMessageBox::critical(this, - tr("Active sequence selected"), - tr("You cannot insert a sequence into itself, so no clips of this media would be in this sequence."), - QMessageBox::Ok); - } else { - ReplaceClipMediaDialog dialog(this, item); - dialog.exec(); - } - } - } + if (olive::ActiveSequence == nullptr) { + QMessageBox::critical(this, + tr("No active sequence"), + tr("No sequence is active, please open the sequence you want to replace clips from."), + QMessageBox::Ok); + } else { + QModelIndexList selected_items = get_current_selected(); + if (selected_items.size() == 1) { + Media* item = item_to_media(selected_items.at(0)); + if (item->get_type() == MEDIA_TYPE_SEQUENCE && olive::ActiveSequence == item->to_sequence()) { + QMessageBox::critical(this, + tr("Active sequence selected"), + tr("You cannot insert a sequence into itself, so no clips of this media would be in this sequence."), + QMessageBox::Ok); + } else { + ReplaceClipMediaDialog dialog(this, item); + dialog.exec(); + } + } + } } void Project::open_properties() { - QModelIndexList selected_items = get_current_selected(); - if (selected_items.size() == 1) { - Media* item = item_to_media(selected_items.at(0)); - switch (item->get_type()) { - case MEDIA_TYPE_FOOTAGE: - { - MediaPropertiesDialog mpd(this, item); - mpd.exec(); - } - break; - case MEDIA_TYPE_SEQUENCE: - { - NewSequenceDialog nsd(this, item); - nsd.exec(); - } - break; - default: - { - // fall back to renaming - QString new_name = QInputDialog::getText(this, - tr("Rename '%1'").arg(item->get_name()), - tr("Enter new name:"), - QLineEdit::Normal, - item->get_name()); - if (!new_name.isEmpty()) { - MediaRename* mr = new MediaRename(item, new_name); - olive::UndoStack.push(mr); - } - } - } + QModelIndexList selected_items = get_current_selected(); + if (selected_items.size() == 1) { + Media* item = item_to_media(selected_items.at(0)); + switch (item->get_type()) { + case MEDIA_TYPE_FOOTAGE: + { + MediaPropertiesDialog mpd(this, item); + mpd.exec(); } + break; + case MEDIA_TYPE_SEQUENCE: + { + NewSequenceDialog nsd(this, item); + nsd.exec(); + } + break; + default: + { + // fall back to renaming + QString new_name = QInputDialog::getText(this, + tr("Rename '%1'").arg(item->get_name()), + tr("Enter new name:"), + QLineEdit::Normal, + item->get_name()); + if (!new_name.isEmpty()) { + MediaRename* mr = new MediaRename(item, new_name); + olive::UndoStack.push(mr); + } + } + } + } } void Project::new_folder() { - Media* m = create_folder_internal(nullptr); - olive::UndoStack.push(new AddMediaCommand(m, get_selected_folder())); + Media* m = create_folder_internal(nullptr); + olive::UndoStack.push(new AddMediaCommand(m, get_selected_folder())); - QModelIndex index = olive::project_model.create_index(m->row(), 0, m); - switch (olive::CurrentConfig.project_view_type) { - case PROJECT_VIEW_TREE: - tree_view->edit(sorter->mapFromSource(index)); - break; - case PROJECT_VIEW_ICON: - icon_view->edit(sorter->mapFromSource(index)); - break; - } + QModelIndex index = olive::project_model.create_index(m->row(), 0, m); + switch (olive::CurrentConfig.project_view_type) { + case PROJECT_VIEW_TREE: + tree_view->edit(sorter->mapFromSource(index)); + break; + case PROJECT_VIEW_ICON: + icon_view->edit(sorter->mapFromSource(index)); + break; + } } void Project::new_sequence() { - NewSequenceDialog nsd(this); - nsd.set_sequence_name(get_next_sequence_name()); - nsd.exec(); + NewSequenceDialog nsd(this); + nsd.set_sequence_name(get_next_sequence_name()); + nsd.exec(); } Media* Project::create_sequence_internal(ComboAction *ca, SequencePtr s, bool open, Media* parent) { - if (parent == nullptr) { - parent = olive::project_model.get_root(); + if (parent == nullptr) { + parent = olive::project_model.get_root(); + } + + Media* item(new Media(parent)); + item->set_sequence(s); + + if (ca != nullptr) { + ca->append(new NewSequenceCommand(item, parent)); + if (open) ca->append(new ChangeSequenceAction(s)); + } else { + if (parent == olive::project_model.get_root()) { + olive::project_model.appendChild(parent, item); + } else { + parent->appendChild(item); } - - Media* item(new Media(parent)); - item->set_sequence(s); - - if (ca != nullptr) { - ca->append(new NewSequenceCommand(item, parent)); - if (open) ca->append(new ChangeSequenceAction(s)); - } else { - if (parent == olive::project_model.get_root()) { - olive::project_model.appendChild(parent, item); - } else { - parent->appendChild(item); - } - if (open) set_sequence(s); - } - return item; + if (open) set_sequence(s); + } + return item; } QString Project::get_file_name_from_path(const QString& path) { - return path.mid(path.lastIndexOf('/')+1); + return path.mid(path.lastIndexOf('/')+1); } /*Media* Project::new_item() { Media* item = new Media(0); - //item->setFlags(item->flags() | Qt::ItemIsEditable); - return item; + //item->setFlags(item->flags() | Qt::ItemIsEditable); + return item; }*/ bool Project::is_focused() { - return tree_view->hasFocus() || icon_view->hasFocus(); + return tree_view->hasFocus() || icon_view->hasFocus(); } Media* Project::create_folder_internal(QString name) { - Media* item = new Media(nullptr); - item->set_folder(); - item->set_name(name); - return item; + Media* item = new Media(nullptr); + item->set_folder(); + item->set_name(name); + return item; } Media *Project::item_to_media(const QModelIndex &index) { - return static_cast(sorter->mapToSource(index).internalPointer()); -// return static_cast(index.internalPointer()); + return static_cast(sorter->mapToSource(index).internalPointer()); + // return static_cast(index.internalPointer()); } void Project::get_all_media_from_table(QList& items, QList& list, int search_type) { - for (int i=0;iget_type() == MEDIA_TYPE_FOLDER) { - QList children; - for (int j=0;jchildCount();j++) { - children.append(item->child(j)); - } - get_all_media_from_table(children, list, search_type); - } else if (search_type == item->get_type() || search_type == -1) { - list.append(item); - } - } + for (int i=0;iget_type() == MEDIA_TYPE_FOLDER) { + QList children; + for (int j=0;jchildCount();j++) { + children.append(item->child(j)); + } + get_all_media_from_table(children, list, search_type); + } else if (search_type == item->get_type() || search_type == -1) { + list.append(item); + } + } } bool delete_clips_in_clipboard_with_media(ComboAction* ca, Media* m) { - int delete_count = 0; - if (clipboard_type == CLIPBOARD_TYPE_CLIP) { - for (int i=0;i(clipboard.at(i)); - if (c->media == m) { - ca->append(new RemoveClipsFromClipboard(i-delete_count)); - delete_count++; - } - } - } - return (delete_count > 0); + int delete_count = 0; + if (clipboard_type == CLIPBOARD_TYPE_CLIP) { + for (int i=0;i(clipboard.at(i)); + if (c->media == m) { + ca->append(new RemoveClipsFromClipboard(i-delete_count)); + delete_count++; + } + } + } + return (delete_count > 0); } void Project::delete_selected_media() { - ComboAction* ca = new ComboAction(); - QModelIndexList selected_items = get_current_selected(); - QList items; - for (int i=0;i items; + for (int i=0;i parents; - QList sequence_items; - QList all_top_level_items; - for (int i=0;i 0) { - QList media_items; - get_all_media_from_table(items, media_items, MEDIA_TYPE_FOOTAGE); - for (int i=0;ito_footage(); - bool confirm_delete = false; - for (int j=0;jto_sequence(); - for (int k=0;kclips.size();k++) { - ClipPtr c = s->clips.at(k); - if (c != nullptr && c->media == item) { - if (!confirm_delete) { - // we found a reference, so we know we'll need to ask if the user wants to delete it - QMessageBox confirm(this); - confirm.setWindowTitle(tr("Delete media in use?")); - confirm.setText(tr("The media '%1' is currently used in '%2'. Deleting it will remove all instances in the sequence. Are you sure you want to do this?").arg(media->name, s->name)); - QAbstractButton* yes_button = confirm.addButton(QMessageBox::Yes); - QAbstractButton* skip_button = nullptr; - if (items.size() > 1) skip_button = confirm.addButton(tr("Skip"), QMessageBox::NoRole); - QAbstractButton* abort_button = confirm.addButton(QMessageBox::Cancel); - confirm.exec(); - if (confirm.clickedButton() == yes_button) { - // remove all clips referencing this media - confirm_delete = true; - redraw = true; - } else if (confirm.clickedButton() == skip_button) { - // remove media item and any folders containing it from the remove list - Media* parent = item; - while (parent != nullptr) { - parents.append(parent); + // check if media is in use + QVector parents; + QList sequence_items; + QList all_top_level_items; + for (int i=0;i 0) { + QList media_items; + get_all_media_from_table(items, media_items, MEDIA_TYPE_FOOTAGE); + for (int i=0;ito_footage(); + bool confirm_delete = false; + for (int j=0;jto_sequence(); + for (int k=0;kclips.size();k++) { + ClipPtr c = s->clips.at(k); + if (c != nullptr && c->media == item) { + if (!confirm_delete) { + // we found a reference, so we know we'll need to ask if the user wants to delete it + QMessageBox confirm(this); + confirm.setWindowTitle(tr("Delete media in use?")); + confirm.setText(tr("The media '%1' is currently used in '%2'. Deleting it will remove all instances in the sequence. Are you sure you want to do this?").arg(media->name, s->name)); + QAbstractButton* yes_button = confirm.addButton(QMessageBox::Yes); + QAbstractButton* skip_button = nullptr; + if (items.size() > 1) skip_button = confirm.addButton(tr("Skip"), QMessageBox::NoRole); + QAbstractButton* abort_button = confirm.addButton(QMessageBox::Cancel); + confirm.exec(); + if (confirm.clickedButton() == yes_button) { + // remove all clips referencing this media + confirm_delete = true; + redraw = true; + } else if (confirm.clickedButton() == skip_button) { + // remove media item and any folders containing it from the remove list + Media* parent = item; + while (parent != nullptr) { + parents.append(parent); - // re-add item's siblings - for (int m=0;mchildCount();m++) { - Media* child = parent->child(m); - bool found = false; - for (int n=0;nchildCount();m++) { + Media* child = parent->child(m); + bool found = false; + for (int n=0;nparentItem(); - } + parent = parent->parentItem(); + } - j = sequence_items.size(); - k = s->clips.size(); - } else if (confirm.clickedButton() == abort_button) { - // break out of loop - i = media_items.size(); - j = sequence_items.size(); - k = s->clips.size(); + j = sequence_items.size(); + k = s->clips.size(); + } else if (confirm.clickedButton() == abort_button) { + // break out of loop + i = media_items.size(); + j = sequence_items.size(); + k = s->clips.size(); - remove = false; - } - } - if (confirm_delete) { - ca->append(new DeleteClipAction(s, k)); - } - } - } - } - if (confirm_delete) { - delete_clips_in_clipboard_with_media(ca, item); - } - } - } + remove = false; + } + } + if (confirm_delete) { + ca->append(new DeleteClipAction(s, k)); + } + } + } + } + if (confirm_delete) { + delete_clips_in_clipboard_with_media(ca, item); + } + } + } - // remove - if (remove) { - panel_effect_controls->clear_effects(true); - if (olive::ActiveSequence != nullptr) olive::ActiveSequence->selections.clear(); + // remove + if (remove) { + panel_effect_controls->clear_effects(true); + if (olive::ActiveSequence != nullptr) olive::ActiveSequence->selections.clear(); - // remove media and parents - for (int m=0;mappend(new DeleteMediaCommand(items.at(i))); + for (int i=0;iappend(new DeleteMediaCommand(items.at(i))); - if (items.at(i)->get_type() == MEDIA_TYPE_SEQUENCE) { - redraw = true; + if (items.at(i)->get_type() == MEDIA_TYPE_SEQUENCE) { + redraw = true; - SequencePtr s = items.at(i)->to_sequence(); + SequencePtr s = items.at(i)->to_sequence(); - if (s == olive::ActiveSequence) { - ca->append(new ChangeSequenceAction(nullptr)); - } + if (s == olive::ActiveSequence) { + ca->append(new ChangeSequenceAction(nullptr)); + } - if (s == panel_footage_viewer->seq) { - panel_footage_viewer->set_media(nullptr); - } - } else if (items.at(i)->get_type() == MEDIA_TYPE_FOOTAGE) { - if (panel_footage_viewer->seq != nullptr) { - for (int j=0;jseq->clips.size();j++) { - ClipPtr c = panel_footage_viewer->seq->clips.at(j); - if (c != nullptr && c->media == items.at(i)) { - panel_footage_viewer->set_media(nullptr); - break; - } - } - } - } - } - olive::UndoStack.push(ca); + if (s == panel_footage_viewer->seq) { + panel_footage_viewer->set_media(nullptr); + } + } else if (items.at(i)->get_type() == MEDIA_TYPE_FOOTAGE) { + if (panel_footage_viewer->seq != nullptr) { + for (int j=0;jseq->clips.size();j++) { + ClipPtr c = panel_footage_viewer->seq->clips.at(j); + if (c != nullptr && c->media == items.at(i)) { + panel_footage_viewer->set_media(nullptr); + break; + } + } + } + } + } + olive::UndoStack.push(ca); - // redraw clips - if (redraw) { - update_ui(true); - } - } else { - delete ca; - } + // redraw clips + if (redraw) { + update_ui(true); + } + } else { + delete ca; + } } void Project::start_preview_generator(Media* item, bool replacing) { - // set up throbber animation - olive::media_icon_service->SetMediaIcon(item, ICON_TYPE_LOADING); + // set up throbber animation + olive::media_icon_service->SetMediaIcon(item, ICON_TYPE_LOADING); - PreviewGenerator* pg = new PreviewGenerator(item, item->to_footage(), replacing); - item->to_footage()->preview_gen = pg; - pg->start(QThread::LowPriority); + PreviewGenerator* pg = new PreviewGenerator(item, item->to_footage(), replacing); + item->to_footage()->preview_gen = pg; + pg->start(QThread::LowPriority); } void Project::process_file_list(QStringList& files, bool recursive, Media* replace, Media* parent) { - bool imported = false; + bool imported = false; - QVector image_sequence_urls; - QVector image_sequence_importassequence; - QStringList image_sequence_formats = olive::CurrentConfig.img_seq_formats.split("|"); + QVector image_sequence_urls; + QVector image_sequence_importassequence; + QStringList image_sequence_formats = olive::CurrentConfig.img_seq_formats.split("|"); - if (!recursive) last_imported_media.clear(); + if (!recursive) last_imported_media.clear(); - bool create_undo_action = (!recursive && replace == nullptr); - ComboAction* ca = nullptr; - if (create_undo_action) ca = new ComboAction(); + bool create_undo_action = (!recursive && replace == nullptr); + ComboAction* ca = nullptr; + if (create_undo_action) ca = new ComboAction(); - for (int i=0;iappend(new AddMediaCommand(folder, parent)); - } else { - olive::project_model.appendChild(parent, folder); - } + if (create_undo_action) { + ca->append(new AddMediaCommand(folder, parent)); + } else { + olive::project_model.appendChild(parent, folder); + } - imported = true; - } else if (!files.at(i).isEmpty()) { - QString file(files.at(i)); - bool skip = false; + imported = true; + } else if (!files.at(i).isEmpty()) { + QString file(files.at(i)); + bool skip = false; - /* Heuristic to determine whether file is part of an image sequence */ + /* Heuristic to determine whether file is part of an image sequence */ - // check file extension (assume it's not a + // check file extension (assume it's not a - int lastcharindex = file.lastIndexOf("."); - bool found = true; - if (lastcharindex != -1 && lastcharindex > file.lastIndexOf('/')) { - // image_sequence_formats - found = false; - QString ext = file.mid(lastcharindex+1); - for (int j=0;j file.lastIndexOf('/')) { + // image_sequence_formats + found = false; + QString ext = file.mid(lastcharindex+1); + for (int j=0;jto_footage(); - m->reset(); - } else { - item = new Media(parent); - m = FootagePtr(new Footage()); - } + if (replace != nullptr) { + item = replace; + m = replace->to_footage(); + m->reset(); + } else { + item = new Media(parent); + m = FootagePtr(new Footage()); + } - m->using_inout = false; - m->url = file; - m->name = get_file_name_from_path(files.at(i)); + m->using_inout = false; + m->url = file; + m->name = get_file_name_from_path(files.at(i)); - item->set_footage(m); + item->set_footage(m); - last_imported_media.append(item); + last_imported_media.append(item); - if (replace == nullptr) { - if (create_undo_action) { - ca->append(new AddMediaCommand(item, parent)); - } else { - parent->appendChild(item); -// project_model.appendChild(parent, item); - } - } + if (replace == nullptr) { + if (create_undo_action) { + ca->append(new AddMediaCommand(item, parent)); + } else { + parent->appendChild(item); + // project_model.appendChild(parent, item); + } + } - imported = true; - } - } - } - if (create_undo_action) { - if (imported) { - olive::UndoStack.push(ca); + imported = true; + } + } + } + if (create_undo_action) { + if (imported) { + olive::UndoStack.push(ca); - for (int i=0;iget_type() == MEDIA_TYPE_FOLDER) return m; - } - return nullptr; + // if one item is selected and it's a folder, return it + QModelIndexList selected_items = get_current_selected(); + if (selected_items.size() == 1) { + Media* m = item_to_media(selected_items.at(0)); + if (m->get_type() == MEDIA_TYPE_FOLDER) return m; + } + return nullptr; } bool Project::reveal_media(Media *media, QModelIndex parent) { - for (int i=0;iget_type() == MEDIA_TYPE_FOLDER) { + if (m->get_type() == MEDIA_TYPE_FOLDER) { - // if this item is a folder, recursively run this function to search it too - if (reveal_media(media, item)) return true; + // if this item is a folder, recursively run this function to search it too + if (reveal_media(media, item)) return true; - } else if (m == media) { - // if m == media, then we found the media object we were looking for + } else if (m == media) { + // if m == media, then we found the media object we were looking for - // get sorter proxy item (the item that's "visible") - QModelIndex sorted_index = sorter->mapFromSource(item); + // get sorter proxy item (the item that's "visible") + QModelIndex sorted_index = sorter->mapFromSource(item); - // retrieve its parent item - QModelIndex hierarchy = sorted_index.parent(); + // retrieve its parent item + QModelIndex hierarchy = sorted_index.parent(); - if (olive::CurrentConfig.project_view_type == PROJECT_VIEW_TREE) { + if (olive::CurrentConfig.project_view_type == PROJECT_VIEW_TREE) { - // if we're in tree view, expand every folder in the hierarchy containing the media - while (hierarchy.isValid()) { - tree_view->setExpanded(hierarchy, true); - hierarchy = hierarchy.parent(); - } + // if we're in tree view, expand every folder in the hierarchy containing the media + while (hierarchy.isValid()) { + tree_view->setExpanded(hierarchy, true); + hierarchy = hierarchy.parent(); + } - // select item (requires a QItemSelection object to select the whole row) - QItemSelection row_select( - sorter->index(sorted_index.row(), 0, sorted_index.parent()), - sorter->index(sorted_index.row(), sorter->columnCount()-1, sorted_index.parent()) - ); + // select item (requires a QItemSelection object to select the whole row) + QItemSelection row_select( + sorter->index(sorted_index.row(), 0, sorted_index.parent()), + sorter->index(sorted_index.row(), sorter->columnCount()-1, sorted_index.parent()) + ); - tree_view->selectionModel()->select(row_select, QItemSelectionModel::Select); - } else if (olive::CurrentConfig.project_view_type == PROJECT_VIEW_ICON) { + tree_view->selectionModel()->select(row_select, QItemSelectionModel::Select); + } else if (olive::CurrentConfig.project_view_type == PROJECT_VIEW_ICON) { - // if we're in icon view, we just "browse" to the parent folder - icon_view->setRootIndex(hierarchy); + // if we're in icon view, we just "browse" to the parent folder + icon_view->setRootIndex(hierarchy); - // select item in this folder - icon_view->selectionModel()->select(sorted_index, QItemSelectionModel::Select); + // select item in this folder + icon_view->selectionModel()->select(sorted_index, QItemSelectionModel::Select); - // update the "up" button state - set_up_dir_enabled(); + // update the "up" button state + set_up_dir_enabled(); - } + } - return true; - } - } + return true; + } + } - return false; + return false; } void Project::import_dialog() { - QFileDialog fd(this, tr("Import media..."), "", tr("All Files") + " (*)"); - fd.setFileMode(QFileDialog::ExistingFiles); + QFileDialog fd(this, tr("Import media..."), "", tr("All Files") + " (*)"); + fd.setFileMode(QFileDialog::ExistingFiles); - if (fd.exec()) { - QStringList files = fd.selectedFiles(); - process_file_list(files, false, nullptr, get_selected_folder()); - } + if (fd.exec()) { + QStringList files = fd.selectedFiles(); + process_file_list(files, false, nullptr, get_selected_folder()); + } } void Project::delete_clips_using_selected_media() { - if (olive::ActiveSequence == nullptr) { - QMessageBox::critical(this, - tr("No active sequence"), - tr("No sequence is active, please open the sequence you want to delete clips from."), - QMessageBox::Ok); - } else { - ComboAction* ca = new ComboAction(); - bool deleted = false; - QModelIndexList items = get_current_selected(); - for (int i=0;iclips.size();i++) { - const ClipPtr& c = olive::ActiveSequence->clips.at(i); - if (c != nullptr) { - for (int j=0;jmedia == m) { - ca->append(new DeleteClipAction(olive::ActiveSequence, i)); - deleted = true; - } - } - } - } - for (int j=0;jclips.size();i++) { + const ClipPtr& c = olive::ActiveSequence->clips.at(i); + if (c != nullptr) { + for (int j=0;jmedia == m) { + ca->append(new DeleteClipAction(olive::ActiveSequence, i)); + deleted = true; + } + } + } + } + for (int j=0;jclear_effects(true); + // clear effects cache + panel_effect_controls->clear_effects(true); - // delete sequences first because it's important to close all the clips before deleting the media - QVector sequences = list_all_project_sequences(); - for (int i=0;ito_sequence().reset(); - sequences.at(i)->set_sequence(nullptr); - } + // delete sequences first because it's important to close all the clips before deleting the media + QVector sequences = list_all_project_sequences(); + for (int i=0;ito_sequence().reset(); + sequences.at(i)->set_sequence(nullptr); + } - // delete everything else - olive::project_model.clear(); + // delete everything else + olive::project_model.clear(); - // update tree view (sometimes this doesn't seem to update reliably) - tree_view->update(); + // update tree view (sometimes this doesn't seem to update reliably) + tree_view->update(); } void Project::new_project() { - // clear existing project - set_sequence(nullptr); - panel_footage_viewer->set_media(nullptr); - clear(); - olive::MainWindow->setWindowModified(false); + // clear existing project + set_sequence(nullptr); + panel_footage_viewer->set_media(nullptr); + clear(); + olive::MainWindow->setWindowModified(false); } void Project::load_project(bool autorecovery) { - new_project(); + new_project(); - LoadDialog ld(this, autorecovery); - ld.exec(); + LoadDialog ld(this, autorecovery); + ld.exec(); } void save_marker(QXmlStreamWriter& stream, const Marker& m) { - stream.writeStartElement("marker"); - stream.writeAttribute("frame", QString::number(m.frame)); - stream.writeAttribute("name", m.name); - stream.writeEndElement(); + stream.writeStartElement("marker"); + stream.writeAttribute("frame", QString::number(m.frame)); + stream.writeAttribute("name", m.name); + stream.writeEndElement(); } void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, const QModelIndex& parent) { - for (int i=0;iget_type()) { - if (m->get_type() == MEDIA_TYPE_FOLDER) { - if (set_ids_only) { - m->temp_id = folder_id; // saves a temporary ID for matching in the project file - folder_id++; - } else { - // if we're saving folders, save the folder - stream.writeStartElement("folder"); - stream.writeAttribute("name", m->get_name()); - stream.writeAttribute("id", QString::number(m->temp_id)); - if (!item.parent().isValid()) { - stream.writeAttribute("parent", "0"); - } else { - stream.writeAttribute("parent", QString::number(olive::project_model.getItem(item.parent())->temp_id)); - } - stream.writeEndElement(); - } - // save_folder(stream, item, type, set_ids_only); - } else { - int folder = m->parentItem()->temp_id; - if (type == MEDIA_TYPE_FOOTAGE) { - FootagePtr f = m->to_footage(); - f->save_id = media_id; - stream.writeStartElement("footage"); - stream.writeAttribute("id", QString::number(media_id)); - stream.writeAttribute("folder", QString::number(folder)); - stream.writeAttribute("name", f->name); - stream.writeAttribute("url", proj_dir.relativeFilePath(f->url)); - stream.writeAttribute("duration", QString::number(f->length)); - stream.writeAttribute("using_inout", QString::number(f->using_inout)); - stream.writeAttribute("in", QString::number(f->in)); - stream.writeAttribute("out", QString::number(f->out)); - stream.writeAttribute("speed", QString::number(f->speed)); - stream.writeAttribute("alphapremul", QString::number(f->alpha_is_premultiplied)); + if (type == m->get_type()) { + if (m->get_type() == MEDIA_TYPE_FOLDER) { + if (set_ids_only) { + m->temp_id = folder_id; // saves a temporary ID for matching in the project file + folder_id++; + } else { + // if we're saving folders, save the folder + stream.writeStartElement("folder"); + stream.writeAttribute("name", m->get_name()); + stream.writeAttribute("id", QString::number(m->temp_id)); + if (!item.parent().isValid()) { + stream.writeAttribute("parent", "0"); + } else { + stream.writeAttribute("parent", QString::number(olive::project_model.getItem(item.parent())->temp_id)); + } + stream.writeEndElement(); + } + // save_folder(stream, item, type, set_ids_only); + } else { + int folder = m->parentItem()->temp_id; + if (type == MEDIA_TYPE_FOOTAGE) { + FootagePtr f = m->to_footage(); + f->save_id = media_id; + stream.writeStartElement("footage"); + stream.writeAttribute("id", QString::number(media_id)); + stream.writeAttribute("folder", QString::number(folder)); + stream.writeAttribute("name", f->name); + stream.writeAttribute("url", proj_dir.relativeFilePath(f->url)); + stream.writeAttribute("duration", QString::number(f->length)); + stream.writeAttribute("using_inout", QString::number(f->using_inout)); + stream.writeAttribute("in", QString::number(f->in)); + stream.writeAttribute("out", QString::number(f->out)); + stream.writeAttribute("speed", QString::number(f->speed)); + stream.writeAttribute("alphapremul", QString::number(f->alpha_is_premultiplied)); - stream.writeAttribute("proxy", QString::number(f->proxy)); - stream.writeAttribute("proxypath", f->proxy_path); + stream.writeAttribute("proxy", QString::number(f->proxy)); + stream.writeAttribute("proxypath", f->proxy_path); - // save video stream metadata - for (int j=0;jvideo_tracks.size();j++) { - const FootageStream& ms = f->video_tracks.at(j); - stream.writeStartElement("video"); - stream.writeAttribute("id", QString::number(ms.file_index)); - stream.writeAttribute("width", QString::number(ms.video_width)); - stream.writeAttribute("height", QString::number(ms.video_height)); - stream.writeAttribute("framerate", QString::number(ms.video_frame_rate, 'f', 10)); - stream.writeAttribute("infinite", QString::number(ms.infinite_length)); - stream.writeEndElement(); // video - } + // save video stream metadata + for (int j=0;jvideo_tracks.size();j++) { + const FootageStream& ms = f->video_tracks.at(j); + stream.writeStartElement("video"); + stream.writeAttribute("id", QString::number(ms.file_index)); + stream.writeAttribute("width", QString::number(ms.video_width)); + stream.writeAttribute("height", QString::number(ms.video_height)); + stream.writeAttribute("framerate", QString::number(ms.video_frame_rate, 'f', 10)); + stream.writeAttribute("infinite", QString::number(ms.infinite_length)); + stream.writeEndElement(); // video + } - // save audio stream metadata - for (int j=0;jaudio_tracks.size();j++) { - const FootageStream& ms = f->audio_tracks.at(j); - stream.writeStartElement("audio"); - stream.writeAttribute("id", QString::number(ms.file_index)); - stream.writeAttribute("channels", QString::number(ms.audio_channels)); - stream.writeAttribute("layout", QString::number(ms.audio_layout)); - stream.writeAttribute("frequency", QString::number(ms.audio_frequency)); - stream.writeEndElement(); // audio - } + // save audio stream metadata + for (int j=0;jaudio_tracks.size();j++) { + const FootageStream& ms = f->audio_tracks.at(j); + stream.writeStartElement("audio"); + stream.writeAttribute("id", QString::number(ms.file_index)); + stream.writeAttribute("channels", QString::number(ms.audio_channels)); + stream.writeAttribute("layout", QString::number(ms.audio_layout)); + stream.writeAttribute("frequency", QString::number(ms.audio_frequency)); + stream.writeEndElement(); // audio + } - // save footage markers - for (int j=0;jmarkers.size();j++) { - save_marker(stream, f->markers.at(j)); - } + // save footage markers + for (int j=0;jmarkers.size();j++) { + save_marker(stream, f->markers.at(j)); + } - stream.writeEndElement(); // footage - media_id++; - } else if (type == MEDIA_TYPE_SEQUENCE) { - SequencePtr s = m->to_sequence(); - if (set_ids_only) { - s->save_id = sequence_id; - sequence_id++; - } else { - stream.writeStartElement("sequence"); - stream.writeAttribute("id", QString::number(s->save_id)); - stream.writeAttribute("folder", QString::number(folder)); - stream.writeAttribute("name", s->name); - stream.writeAttribute("width", QString::number(s->width)); - stream.writeAttribute("height", QString::number(s->height)); - stream.writeAttribute("framerate", QString::number(s->frame_rate, 'f', 10)); - stream.writeAttribute("afreq", QString::number(s->audio_frequency)); - stream.writeAttribute("alayout", QString::number(s->audio_layout)); - if (s == olive::ActiveSequence) { - stream.writeAttribute("open", "1"); - } - stream.writeAttribute("workarea", QString::number(s->using_workarea)); - stream.writeAttribute("workareaIn", QString::number(s->workarea_in)); - stream.writeAttribute("workareaOut", QString::number(s->workarea_out)); + stream.writeEndElement(); // footage + media_id++; + } else if (type == MEDIA_TYPE_SEQUENCE) { + SequencePtr s = m->to_sequence(); + if (set_ids_only) { + s->save_id = sequence_id; + sequence_id++; + } else { + stream.writeStartElement("sequence"); + stream.writeAttribute("id", QString::number(s->save_id)); + stream.writeAttribute("folder", QString::number(folder)); + stream.writeAttribute("name", s->name); + stream.writeAttribute("width", QString::number(s->width)); + stream.writeAttribute("height", QString::number(s->height)); + stream.writeAttribute("framerate", QString::number(s->frame_rate, 'f', 10)); + stream.writeAttribute("afreq", QString::number(s->audio_frequency)); + stream.writeAttribute("alayout", QString::number(s->audio_layout)); + if (s == olive::ActiveSequence) { + stream.writeAttribute("open", "1"); + } + stream.writeAttribute("workarea", QString::number(s->using_workarea)); + stream.writeAttribute("workareaIn", QString::number(s->workarea_in)); + stream.writeAttribute("workareaOut", QString::number(s->workarea_out)); - /* - for (int j=0;jtransitions.size();j++) { + /* + for (int j=0;jtransitions.size();j++) { TransitionPtr t = s->transitions.at(j); - if (t != nullptr) { - stream.writeStartElement("transition"); - stream.writeAttribute("id", QString::number(j)); - stream.writeAttribute("length", QString::number(t->get_true_length())); - t->save(stream); - stream.writeEndElement(); // transition - } - } + if (t != nullptr) { + stream.writeStartElement("transition"); + stream.writeAttribute("id", QString::number(j)); + stream.writeAttribute("length", QString::number(t->get_true_length())); + t->save(stream); + stream.writeEndElement(); // transition + } + } */ - for (int j=0;jclips.size();j++) { - const ClipPtr& c = s->clips.at(j); - if (c != nullptr) { - stream.writeStartElement("clip"); // clip - stream.writeAttribute("id", QString::number(j)); - stream.writeAttribute("enabled", QString::number(c->enabled)); - stream.writeAttribute("name", c->name); - stream.writeAttribute("clipin", QString::number(c->clip_in)); - stream.writeAttribute("in", QString::number(c->timeline_in)); - stream.writeAttribute("out", QString::number(c->timeline_out)); - stream.writeAttribute("track", QString::number(c->track)); + for (int j=0;jclips.size();j++) { + const ClipPtr& c = s->clips.at(j); + if (c != nullptr) { + stream.writeStartElement("clip"); // clip + stream.writeAttribute("id", QString::number(j)); + stream.writeAttribute("enabled", QString::number(c->enabled)); + stream.writeAttribute("name", c->name); + stream.writeAttribute("clipin", QString::number(c->clip_in)); + stream.writeAttribute("in", QString::number(c->timeline_in)); + stream.writeAttribute("out", QString::number(c->timeline_out)); + stream.writeAttribute("track", QString::number(c->track)); /* - stream.writeAttribute("opening", QString::number(c->opening_transition)); - stream.writeAttribute("closing", QString::number(c->closing_transition)); + stream.writeAttribute("opening", QString::number(c->opening_transition)); + stream.writeAttribute("closing", QString::number(c->closing_transition)); */ - stream.writeAttribute("r", QString::number(c->color_r)); - stream.writeAttribute("g", QString::number(c->color_g)); - stream.writeAttribute("b", QString::number(c->color_b)); + stream.writeAttribute("r", QString::number(c->color_r)); + stream.writeAttribute("g", QString::number(c->color_g)); + stream.writeAttribute("b", QString::number(c->color_b)); - stream.writeAttribute("autoscale", QString::number(c->autoscale)); - stream.writeAttribute("speed", QString::number(c->speed, 'f', 10)); - stream.writeAttribute("maintainpitch", QString::number(c->maintain_audio_pitch)); - stream.writeAttribute("reverse", QString::number(c->reverse)); + stream.writeAttribute("autoscale", QString::number(c->autoscale)); + stream.writeAttribute("speed", QString::number(c->speed, 'f', 10)); + stream.writeAttribute("maintainpitch", QString::number(c->maintain_audio_pitch)); + stream.writeAttribute("reverse", QString::number(c->reverse)); - if (c->media != nullptr) { - 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 != nullptr) { + 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; + } + } - // save markers - // only necessary for null media clips, since media has its own markers - if (c->media == nullptr) { - for (int k=0;kget_markers().size();k++) { - save_marker(stream, c->get_markers().at(k)); - } - } + // save markers + // only necessary for null media clips, since media has its own markers + if (c->media == nullptr) { + for (int k=0;kget_markers().size();k++) { + save_marker(stream, c->get_markers().at(k)); + } + } - // save clip links - stream.writeStartElement("linked"); // linked - for (int k=0;klinked.size();k++) { - stream.writeStartElement("link"); // link - stream.writeAttribute("id", QString::number(c->linked.at(k))); - stream.writeEndElement(); // link - } - stream.writeEndElement(); // linked + // save clip links + stream.writeStartElement("linked"); // linked + for (int k=0;klinked.size();k++) { + stream.writeStartElement("link"); // link + stream.writeAttribute("id", QString::number(c->linked.at(k))); + stream.writeEndElement(); // link + } + stream.writeEndElement(); // linked - for (int k=0;keffects.size();k++) { - stream.writeStartElement("effect"); // effect - c->effects.at(k)->save(stream); - stream.writeEndElement(); // effect - } + for (int k=0;keffects.size();k++) { + stream.writeStartElement("effect"); // effect + c->effects.at(k)->save(stream); + stream.writeEndElement(); // effect + } - stream.writeEndElement(); // clip - } - } - for (int j=0;jmarkers.size();j++) { - save_marker(stream, s->markers.at(j)); - } - stream.writeEndElement(); - } - } - } - } + stream.writeEndElement(); // clip + } + } + for (int j=0;jmarkers.size();j++) { + save_marker(stream, s->markers.at(j)); + } + stream.writeEndElement(); + } + } + } + } - if (m->get_type() == MEDIA_TYPE_FOLDER) { - save_folder(stream, type, set_ids_only, item); - } - } + if (m->get_type() == MEDIA_TYPE_FOLDER) { + save_folder(stream, type, set_ids_only, item); + } + } } void Project::save_project(bool autorecovery) { - folder_id = 1; - media_id = 1; - sequence_id = 1; + folder_id = 1; + media_id = 1; + sequence_id = 1; - QFile file(autorecovery ? autorecovery_filename : olive::ActiveProjectFilename); - if (!file.open(QIODevice::WriteOnly/* | QIODevice::Text*/)) { - qCritical() << "Could not open file"; - return; - } + QFile file(autorecovery ? autorecovery_filename : olive::ActiveProjectFilename); + if (!file.open(QIODevice::WriteOnly/* | QIODevice::Text*/)) { + qCritical() << "Could not open file"; + return; + } - QXmlStreamWriter stream(&file); - stream.setAutoFormatting(true); - stream.writeStartDocument(); // doc + QXmlStreamWriter stream(&file); + stream.setAutoFormatting(true); + stream.writeStartDocument(); // doc - stream.writeStartElement("project"); // project + stream.writeStartElement("project"); // project - stream.writeTextElement("version", QString::number(SAVE_VERSION)); + stream.writeTextElement("version", QString::number(SAVE_VERSION)); - stream.writeTextElement("url", olive::ActiveProjectFilename); - proj_dir = QFileInfo(olive::ActiveProjectFilename).absoluteDir(); + stream.writeTextElement("url", olive::ActiveProjectFilename); + proj_dir = QFileInfo(olive::ActiveProjectFilename).absoluteDir(); - save_folder(stream, MEDIA_TYPE_FOLDER, true); + save_folder(stream, MEDIA_TYPE_FOLDER, true); - stream.writeStartElement("folders"); // folders - save_folder(stream, MEDIA_TYPE_FOLDER, false); - stream.writeEndElement(); // folders + stream.writeStartElement("folders"); // folders + save_folder(stream, MEDIA_TYPE_FOLDER, false); + stream.writeEndElement(); // folders - stream.writeStartElement("media"); // media - save_folder(stream, MEDIA_TYPE_FOOTAGE, false); - stream.writeEndElement(); // media + stream.writeStartElement("media"); // media + save_folder(stream, MEDIA_TYPE_FOOTAGE, false); + stream.writeEndElement(); // media - save_folder(stream, MEDIA_TYPE_SEQUENCE, true); + save_folder(stream, MEDIA_TYPE_SEQUENCE, true); - stream.writeStartElement("sequences"); // sequences - save_folder(stream, MEDIA_TYPE_SEQUENCE, false); - stream.writeEndElement();// sequences + stream.writeStartElement("sequences"); // sequences + save_folder(stream, MEDIA_TYPE_SEQUENCE, false); + stream.writeEndElement();// sequences - stream.writeEndElement(); // project + stream.writeEndElement(); // project - stream.writeEndDocument(); // doc + stream.writeEndDocument(); // doc - file.close(); + file.close(); - if (!autorecovery) { - add_recent_project(olive::ActiveProjectFilename); - olive::MainWindow->setWindowModified(false); - } + if (!autorecovery) { + add_recent_project(olive::ActiveProjectFilename); + olive::MainWindow->setWindowModified(false); + } } void Project::update_view_type() { - tree_view->setVisible(olive::CurrentConfig.project_view_type == PROJECT_VIEW_TREE); - icon_view_container->setVisible(olive::CurrentConfig.project_view_type == PROJECT_VIEW_ICON); + tree_view->setVisible(olive::CurrentConfig.project_view_type == PROJECT_VIEW_TREE); + icon_view_container->setVisible(olive::CurrentConfig.project_view_type == PROJECT_VIEW_ICON); - switch (olive::CurrentConfig.project_view_type) { - case PROJECT_VIEW_TREE: - sources_common->view = tree_view; - break; - case PROJECT_VIEW_ICON: - sources_common->view = icon_view; - break; - } + switch (olive::CurrentConfig.project_view_type) { + case PROJECT_VIEW_TREE: + sources_common->view = tree_view; + break; + case PROJECT_VIEW_ICON: + sources_common->view = icon_view; + break; + } } void Project::set_icon_view() { - olive::CurrentConfig.project_view_type = PROJECT_VIEW_ICON; - update_view_type(); + olive::CurrentConfig.project_view_type = PROJECT_VIEW_ICON; + update_view_type(); } void Project::set_tree_view() { - olive::CurrentConfig.project_view_type = PROJECT_VIEW_TREE; - update_view_type(); + olive::CurrentConfig.project_view_type = PROJECT_VIEW_TREE; + update_view_type(); } void Project::save_recent_projects() { - // save to file - QFile f(olive::Global->get_recent_project_list_file()); - if (f.open(QFile::WriteOnly | QFile::Truncate | QFile::Text)) { - QTextStream out(&f); - for (int i=0;i 0) { - out << "\n"; - } - out << recent_projects.at(i); - } - f.close(); - } else { - qWarning() << "Could not save recent projects"; - } + // save to file + QFile f(olive::Global->get_recent_project_list_file()); + if (f.open(QFile::WriteOnly | QFile::Truncate | QFile::Text)) { + QTextStream out(&f); + for (int i=0;i 0) { + out << "\n"; + } + out << recent_projects.at(i); + } + f.close(); + } else { + qWarning() << "Could not save recent projects"; + } } void Project::clear_recent_projects() { - recent_projects.clear(); - save_recent_projects(); + recent_projects.clear(); + save_recent_projects(); } void Project::set_icon_view_size(int s) { - icon_view->setIconSize(QSize(s, s)); + icon_view->setIconSize(QSize(s, s)); } void Project::set_up_dir_enabled() { - directory_up->setEnabled(icon_view->rootIndex().isValid()); + directory_up->setEnabled(icon_view->rootIndex().isValid()); } void Project::go_up_dir() { - icon_view->setRootIndex(icon_view->rootIndex().parent()); - set_up_dir_enabled(); + icon_view->setRootIndex(icon_view->rootIndex().parent()); + set_up_dir_enabled(); } void Project::make_new_menu() { - QMenu new_menu(this); - olive::MenuHelper.make_new_menu(&new_menu); - new_menu.exec(QCursor::pos()); + QMenu new_menu(this); + olive::MenuHelper.make_new_menu(&new_menu); + new_menu.exec(QCursor::pos()); } void Project::add_recent_project(QString url) { - bool found = false; - for (int i=0;i MAXIMUM_RECENT_PROJECTS) { - recent_projects.removeLast(); - } - } - save_recent_projects(); + bool found = false; + for (int i=0;i MAXIMUM_RECENT_PROJECTS) { + recent_projects.removeLast(); + } + } + save_recent_projects(); } void Project::list_all_sequences_worker(QVector* list, Media* parent) { - for (int i=0;iget_type()) { - case MEDIA_TYPE_SEQUENCE: - list->append(item); - break; - case MEDIA_TYPE_FOLDER: - list_all_sequences_worker(list, item); - break; - } - } + for (int i=0;iget_type()) { + case MEDIA_TYPE_SEQUENCE: + list->append(item); + break; + case MEDIA_TYPE_FOLDER: + list_all_sequences_worker(list, item); + break; + } + } } QVector Project::list_all_project_sequences() { - QVector list; - list_all_sequences_worker(&list, nullptr); - return list; + QVector list; + list_all_sequences_worker(&list, nullptr); + return list; } QModelIndexList Project::get_current_selected() { - if (olive::CurrentConfig.project_view_type == PROJECT_VIEW_TREE) { - return tree_view->selectionModel()->selectedRows(); - } - return icon_view->selectionModel()->selectedIndexes(); + if (olive::CurrentConfig.project_view_type == PROJECT_VIEW_TREE) { + return tree_view->selectionModel()->selectedRows(); + } + return icon_view->selectionModel()->selectedIndexes(); } diff --git a/panels/project.h b/panels/project.h index 52113f290..5f80a5c46 100644 --- a/panels/project.h +++ b/panels/project.h @@ -21,7 +21,6 @@ #ifndef PROJECT_H #define PROJECT_H -#include #include #include #include @@ -35,6 +34,7 @@ #include "project/projectelements.h" #include "project/undo.h" #include "project/sourcescommon.h" +#include "ui/panel.h" #include "ui/sourceiconview.h" #include "ui/sourcetable.h" @@ -50,75 +50,79 @@ SequencePtr create_sequence_from_media(QVector &media_list); QString get_channel_layout_name(int channels, uint64_t layout); QString get_interlacing_name(int interlacing); -class Project : public QDockWidget { - Q_OBJECT +class Project : public Panel { + Q_OBJECT public: - explicit Project(QWidget *parent = nullptr); - ~Project(); - bool is_focused(); - void clear(); - Media* create_sequence_internal(ComboAction *ca, SequencePtr s, bool open, Media* parent); - QString get_next_sequence_name(QString start = nullptr); - void process_file_list(QStringList& files, bool recursive = false, Media* replace = nullptr, Media *parent = nullptr); - void replace_media(Media* item, QString filename); - Media* get_selected_folder(); - bool reveal_media(Media *media, QModelIndex parent = QModelIndex()); - void add_recent_project(QString url); + explicit Project(QWidget *parent = nullptr); + ~Project(); - void new_project(); - void load_project(bool autorecovery); - void save_project(bool autorecovery); + bool is_focused(); + void clear(); + Media* create_sequence_internal(ComboAction *ca, SequencePtr s, bool open, Media* parent); + QString get_next_sequence_name(QString start = nullptr); + void process_file_list(QStringList& files, bool recursive = false, Media* replace = nullptr, Media *parent = nullptr); + void replace_media(Media* item, QString filename); + Media* get_selected_folder(); + bool reveal_media(Media *media, QModelIndex parent = QModelIndex()); + void add_recent_project(QString url); - Media* create_folder_internal(QString name); - Media* item_to_media(const QModelIndex& index); + void new_project(); + void load_project(bool autorecovery); + void save_project(bool autorecovery); - void save_recent_projects(); + Media* create_folder_internal(QString name); + Media* item_to_media(const QModelIndex& index); - QVector list_all_project_sequences(); + void save_recent_projects(); - SourceTable* tree_view; - SourceIconView* icon_view; - SourcesCommon* sources_common; + QVector list_all_project_sequences(); - ProjectFilter* sorter; + SourceTable* tree_view; + SourceIconView* icon_view; + SourcesCommon* sources_common; - QVector last_imported_media; + ProjectFilter* sorter; - QModelIndexList get_current_selected(); + QVector last_imported_media; - void start_preview_generator(Media* item, bool replacing); - void get_all_media_from_table(QList &items, QList &list, int type = -1); + QModelIndexList get_current_selected(); - QWidget* toolbar_widget; + void start_preview_generator(Media* item, bool replacing); + void get_all_media_from_table(QList &items, QList &list, int type = -1); + + QWidget* toolbar_widget; +protected: + virtual void Retranslate() override; public slots: - void import_dialog(); - void delete_selected_media(); - void duplicate_selected(); - void delete_clips_using_selected_media(); - void replace_selected_file(); - void replace_clip_media(); - void open_properties(); - void new_folder(); - void new_sequence(); + void import_dialog(); + void delete_selected_media(); + void duplicate_selected(); + void delete_clips_using_selected_media(); + void replace_selected_file(); + void replace_clip_media(); + void open_properties(); + void new_folder(); + void new_sequence(); private: - void save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, const QModelIndex &parent = QModelIndex()); - int folder_id; - int media_id; - int sequence_id; - void list_all_sequences_worker(QVector *list, Media* parent); - QString get_file_name_from_path(const QString &path); - QDir proj_dir; - QWidget* icon_view_container; - QPushButton* directory_up; + void save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, const QModelIndex &parent = QModelIndex()); + int folder_id; + int media_id; + int sequence_id; + void list_all_sequences_worker(QVector *list, Media* parent); + QString get_file_name_from_path(const QString &path); + QDir proj_dir; + QWidget* icon_view_container; + QPushButton* directory_up; + QLineEdit* toolbar_search; private slots: - void update_view_type(); - void set_icon_view(); - void set_tree_view(); - void clear_recent_projects(); - void set_icon_view_size(int); - void set_up_dir_enabled(); - void go_up_dir(); - void make_new_menu(); + void update_view_type(); + void set_icon_view(); + void set_tree_view(); + void clear_recent_projects(); + void set_icon_view_size(int); + void set_up_dir_enabled(); + void go_up_dir(); + void make_new_menu(); }; #endif // PROJECT_H diff --git a/panels/timeline.cpp b/panels/timeline.cpp index b3fb23bb2..db7e23312 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -55,2044 +55,2055 @@ #include Timeline::Timeline(QWidget *parent) : - QDockWidget(parent), - cursor_frame(0), - cursor_track(0), - zoom(1.0), - zoom_just_changed(false), - showing_all(false), - snapping(true), - snapped(false), - snap_point(0), - selecting(false), - rect_select_init(false), - rect_select_proc(false), - moving_init(false), - moving_proc(false), - move_insert(false), - trim_target(-1), - trim_in_point(false), - splitting(false), - importing(false), - importing_files(false), - creating(false), - transition_tool_init(false), - transition_tool_proc(false), - transition_tool_pre_clip(-1), - transition_tool_post_clip(-1), - hand_moving(false), - block_repaints(false), - scroll(0) + Panel(parent), + cursor_frame(0), + cursor_track(0), + zoom(1.0), + zoom_just_changed(false), + showing_all(false), + snapping(true), + snapped(false), + snap_point(0), + selecting(false), + rect_select_init(false), + rect_select_proc(false), + moving_init(false), + moving_proc(false), + move_insert(false), + trim_target(-1), + trim_in_point(false), + splitting(false), + importing(false), + importing_files(false), + creating(false), + transition_tool_init(false), + transition_tool_proc(false), + transition_tool_pre_clip(-1), + transition_tool_post_clip(-1), + hand_moving(false), + block_repaints(false), + scroll(0) { - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - setup_ui(); + setup_ui(); - default_track_height = qRound((QGuiApplication::primaryScreen()->logicalDotsPerInch() / 96) * TRACK_DEFAULT_HEIGHT); + default_track_height = qRound((QGuiApplication::primaryScreen()->logicalDotsPerInch() / 96) * TRACK_DEFAULT_HEIGHT); - headers->viewer = panel_sequence_viewer; + headers->viewer = panel_sequence_viewer; - video_area->bottom_align = true; - video_area->scrollBar = videoScrollbar; - audio_area->scrollBar = audioScrollbar; + video_area->bottom_align = true; + video_area->scrollBar = videoScrollbar; + audio_area->scrollBar = audioScrollbar; - tool_buttons.append(toolArrowButton); - tool_buttons.append(toolEditButton); - tool_buttons.append(toolRippleButton); - tool_buttons.append(toolRazorButton); - tool_buttons.append(toolSlipButton); - tool_buttons.append(toolSlideButton); - tool_buttons.append(toolTransitionButton); - tool_buttons.append(toolHandButton); + tool_buttons.append(toolArrowButton); + tool_buttons.append(toolEditButton); + tool_buttons.append(toolRippleButton); + tool_buttons.append(toolRazorButton); + tool_buttons.append(toolSlipButton); + tool_buttons.append(toolSlideButton); + tool_buttons.append(toolTransitionButton); + tool_buttons.append(toolHandButton); - toolArrowButton->click(); + toolArrowButton->click(); - connect(horizontalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(setScroll(int))); - connect(videoScrollbar, SIGNAL(valueChanged(int)), video_area, SLOT(setScroll(int))); - connect(audioScrollbar, SIGNAL(valueChanged(int)), audio_area, SLOT(setScroll(int))); - connect(horizontalScrollBar, SIGNAL(resize_move(double)), this, SLOT(resize_move(double))); + connect(horizontalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(setScroll(int))); + connect(videoScrollbar, SIGNAL(valueChanged(int)), video_area, SLOT(setScroll(int))); + connect(audioScrollbar, SIGNAL(valueChanged(int)), audio_area, SLOT(setScroll(int))); + connect(horizontalScrollBar, SIGNAL(resize_move(double)), this, SLOT(resize_move(double))); - update_sequence(); + update_sequence(); + + Retranslate(); } Timeline::~Timeline() {} +void Timeline::Retranslate() { + toolArrowButton->setToolTip(tr("Pointer Tool") + " (V)"); + toolEditButton->setToolTip(tr("Edit Tool") + " (X)"); + toolRippleButton->setToolTip(tr("Ripple Tool") + " (B)"); + toolRazorButton->setToolTip(tr("Razor Tool") + " (C)"); + toolSlipButton->setToolTip(tr("Slip Tool") + " (Y)"); + toolSlideButton->setToolTip(tr("Slide Tool") + " (U)"); + toolHandButton->setToolTip(tr("Hand Tool") + " (H)"); + toolTransitionButton->setToolTip(tr("Transition Tool") + " (T)"); + snappingButton->setToolTip(tr("Snapping") + " (S)"); + zoomInButton->setToolTip(tr("Zoom In") + " (=)"); + zoomOutButton->setToolTip(tr("Zoom Out") + " (-)"); + recordButton->setToolTip(tr("Record audio")); + addButton->setToolTip(tr("Add title, solid, bars, etc.")); + + UpdateTitle(); +} + void Timeline::previous_cut() { - if (olive::ActiveSequence != nullptr - && olive::ActiveSequence->playhead > 0) { - long p_cut = 0; - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr) { - if (c->timeline_out > p_cut && c->timeline_out < olive::ActiveSequence->playhead) { - p_cut = c->timeline_out; - } else if (c->timeline_in > p_cut && c->timeline_in < olive::ActiveSequence->playhead) { - p_cut = c->timeline_in; - } - } - } - panel_sequence_viewer->seek(p_cut); - } + if (olive::ActiveSequence != nullptr + && olive::ActiveSequence->playhead > 0) { + long p_cut = 0; + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr) { + if (c->timeline_out > p_cut && c->timeline_out < olive::ActiveSequence->playhead) { + p_cut = c->timeline_out; + } else if (c->timeline_in > p_cut && c->timeline_in < olive::ActiveSequence->playhead) { + p_cut = c->timeline_in; + } + } + } + panel_sequence_viewer->seek(p_cut); + } } void Timeline::next_cut() { - if (olive::ActiveSequence != nullptr) { - bool seek_enabled = false; - long n_cut = LONG_MAX; - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr) { - if (c->timeline_in < n_cut && c->timeline_in > olive::ActiveSequence->playhead) { - n_cut = c->timeline_in; - seek_enabled = true; - } else if (c->timeline_out < n_cut && c->timeline_out > olive::ActiveSequence->playhead) { - n_cut = c->timeline_out; - seek_enabled = true; - } - } + if (olive::ActiveSequence != nullptr) { + bool seek_enabled = false; + long n_cut = LONG_MAX; + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr) { + if (c->timeline_in < n_cut && c->timeline_in > olive::ActiveSequence->playhead) { + n_cut = c->timeline_in; + seek_enabled = true; + } else if (c->timeline_out < n_cut && c->timeline_out > olive::ActiveSequence->playhead) { + n_cut = c->timeline_out; + seek_enabled = true; } - if (seek_enabled) panel_sequence_viewer->seek(n_cut); + } } + if (seek_enabled) panel_sequence_viewer->seek(n_cut); + } } void ripple_clips(ComboAction* ca, SequencePtr s, long point, long length, const QVector& ignore) { - ca->append(new RippleAction(s, point, length, ignore)); + ca->append(new RippleAction(s, point, length, ignore)); } void Timeline::toggle_show_all() { - if (olive::ActiveSequence != nullptr) { - showing_all = !showing_all; - if (showing_all) { - old_zoom = zoom; - set_zoom_value(double(timeline_area->width() - 200) / double(olive::ActiveSequence->getEndFrame())); - } else { - set_zoom_value(old_zoom); - } - } + if (olive::ActiveSequence != nullptr) { + showing_all = !showing_all; + if (showing_all) { + old_zoom = zoom; + set_zoom_value(double(timeline_area->width() - 200) / double(olive::ActiveSequence->getEndFrame())); + } else { + set_zoom_value(old_zoom); + } + } } void Timeline::create_ghosts_from_media(SequencePtr seq, long entry_point, QVector& media_list) { - video_ghosts = false; - audio_ghosts = false; + video_ghosts = false; + audio_ghosts = false; - for (int i=0;iget_type()) { - case MEDIA_TYPE_FOOTAGE: - m = medium->to_footage(); - can_import = m->ready; - if (m->using_inout) { - double source_fr = 30; - if (m->video_tracks.size() > 0 && !qIsNull(m->video_tracks.at(0).video_frame_rate)) source_fr = m->video_tracks.at(0).video_frame_rate * m->speed; - default_clip_in = refactor_frame_number(m->in, source_fr, seq->frame_rate); - default_clip_out = refactor_frame_number(m->out, source_fr, seq->frame_rate); - } - break; - case MEDIA_TYPE_SEQUENCE: - s = medium->to_sequence(); - sequence_length = s->getEndFrame(); - if (seq != nullptr) sequence_length = refactor_frame_number(sequence_length, s->frame_rate, seq->frame_rate); - can_import = (s != seq && sequence_length != 0); - if (s->using_workarea) { - default_clip_in = refactor_frame_number(s->workarea_in, s->frame_rate, seq->frame_rate); - default_clip_out = refactor_frame_number(s->workarea_out, s->frame_rate, seq->frame_rate); - } - break; - default: - can_import = false; - } + switch (medium->get_type()) { + case MEDIA_TYPE_FOOTAGE: + m = medium->to_footage(); + can_import = m->ready; + if (m->using_inout) { + double source_fr = 30; + if (m->video_tracks.size() > 0 && !qIsNull(m->video_tracks.at(0).video_frame_rate)) source_fr = m->video_tracks.at(0).video_frame_rate * m->speed; + default_clip_in = refactor_frame_number(m->in, source_fr, seq->frame_rate); + default_clip_out = refactor_frame_number(m->out, source_fr, seq->frame_rate); + } + break; + case MEDIA_TYPE_SEQUENCE: + s = medium->to_sequence(); + sequence_length = s->getEndFrame(); + if (seq != nullptr) sequence_length = refactor_frame_number(sequence_length, s->frame_rate, seq->frame_rate); + can_import = (s != seq && sequence_length != 0); + if (s->using_workarea) { + default_clip_in = refactor_frame_number(s->workarea_in, s->frame_rate, seq->frame_rate); + default_clip_out = refactor_frame_number(s->workarea_out, s->frame_rate, seq->frame_rate); + } + break; + default: + can_import = false; + } - if (can_import) { - Ghost g; - g.clip = -1; - g.trimming = false; - g.old_clip_in = g.clip_in = default_clip_in; - g.media = medium; - g.in = entry_point; - g.transition = nullptr; + if (can_import) { + Ghost g; + g.clip = -1; + g.trimming = false; + g.old_clip_in = g.clip_in = default_clip_in; + g.media = medium; + g.in = entry_point; + g.transition = nullptr; - switch (medium->get_type()) { - case MEDIA_TYPE_FOOTAGE: - // is video source a still image? - if (m->video_tracks.size() > 0 && m->video_tracks.at(0).infinite_length && m->audio_tracks.size() == 0) { - g.out = g.in + 100; - } else { - long length = m->get_length_in_frames(seq->frame_rate); - g.out = entry_point + length - default_clip_in; - if (m->using_inout) { - g.out -= (length - default_clip_out); - } - } + switch (medium->get_type()) { + case MEDIA_TYPE_FOOTAGE: + // is video source a still image? + if (m->video_tracks.size() > 0 && m->video_tracks.at(0).infinite_length && m->audio_tracks.size() == 0) { + g.out = g.in + 100; + } else { + long length = m->get_length_in_frames(seq->frame_rate); + g.out = entry_point + length - default_clip_in; + if (m->using_inout) { + g.out -= (length - default_clip_out); + } + } - for (int j=0;jaudio_tracks.size();j++) { - if (m->audio_tracks.at(j).enabled) { - g.track = j; - g.media_stream = m->audio_tracks.at(j).file_index; - ghosts.append(g); - audio_ghosts = true; - } - } - for (int j=0;jvideo_tracks.size();j++) { - if (m->video_tracks.at(j).enabled) { - g.track = -1-j; - g.media_stream = m->video_tracks.at(j).file_index; - ghosts.append(g); - video_ghosts = true; - } - } - break; - case MEDIA_TYPE_SEQUENCE: - g.out = entry_point + sequence_length - default_clip_in; + for (int j=0;jaudio_tracks.size();j++) { + if (m->audio_tracks.at(j).enabled) { + g.track = j; + g.media_stream = m->audio_tracks.at(j).file_index; + ghosts.append(g); + audio_ghosts = true; + } + } + for (int j=0;jvideo_tracks.size();j++) { + if (m->video_tracks.at(j).enabled) { + g.track = -1-j; + g.media_stream = m->video_tracks.at(j).file_index; + ghosts.append(g); + video_ghosts = true; + } + } + break; + case MEDIA_TYPE_SEQUENCE: + g.out = entry_point + sequence_length - default_clip_in; - if (s->using_workarea) { - g.out -= (sequence_length - default_clip_out); - } + if (s->using_workarea) { + g.out -= (sequence_length - default_clip_out); + } - g.track = -1; - ghosts.append(g); - g.track = 0; - ghosts.append(g); + g.track = -1; + ghosts.append(g); + g.track = 0; + ghosts.append(g); - video_ghosts = true; - audio_ghosts = true; - break; - } - entry_point = g.out; - } - } - for (int i=0;i added_clips; - for (int i=0;i added_clips; + for (int i=0;imedia = g.media; - c->media_stream = g.media_stream; - c->timeline_in = g.in; - c->timeline_out = g.out; - c->clip_in = g.clip_in; - c->track = g.track; - if (c->media->get_type() == MEDIA_TYPE_FOOTAGE) { - FootagePtr m = c->media->to_footage(); - if (m->video_tracks.size() == 0) { - // audio only (greenish) - c->color_r = 128; - c->color_g = 192; - c->color_b = 128; - } else if (m->audio_tracks.size() == 0) { - // video only (orangeish) - c->color_r = 192; - c->color_g = 160; - c->color_b = 128; - } else { - // video and audio (blueish) - c->color_r = 128; - c->color_g = 128; - c->color_b = 192; - } - c->name = m->name; - } else if (c->media->get_type() == MEDIA_TYPE_SEQUENCE) { - // sequence (red?ish?) - c->color_r = 192; - c->color_g = 128; - c->color_b = 128; + ClipPtr c = ClipPtr(new Clip(s)); + c->media = g.media; + c->media_stream = g.media_stream; + c->timeline_in = g.in; + c->timeline_out = g.out; + c->clip_in = g.clip_in; + c->track = g.track; + if (c->media->get_type() == MEDIA_TYPE_FOOTAGE) { + FootagePtr m = c->media->to_footage(); + if (m->video_tracks.size() == 0) { + // audio only (greenish) + c->color_r = 128; + c->color_g = 192; + c->color_b = 128; + } else if (m->audio_tracks.size() == 0) { + // video only (orangeish) + c->color_r = 192; + c->color_g = 160; + c->color_b = 128; + } else { + // video and audio (blueish) + c->color_r = 128; + c->color_g = 128; + c->color_b = 192; + } + c->name = m->name; + } else if (c->media->get_type() == MEDIA_TYPE_SEQUENCE) { + // sequence (red?ish?) + c->color_r = 192; + c->color_g = 128; + c->color_b = 128; - SequencePtr media = c->media->to_sequence(); - c->name = media->name; - } - c->recalculateMaxLength(); - added_clips.append(c); - } - ca->append(new AddClipCommand(s, added_clips)); + SequencePtr media = c->media->to_sequence(); + c->name = media->name; + } + c->recalculateMaxLength(); + added_clips.append(c); + } + ca->append(new AddClipCommand(s, added_clips)); - // link clips from the same media - for (int i=0;imedia == cc->media) { - c->linked.append(j); - } - } + // link clips from the same media + for (int i=0;imedia == cc->media) { + c->linked.append(j); + } + } - if (olive::CurrentConfig.add_default_effects_to_clips) { - if (c->track < 0) { - // add default video effects - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TRANSFORM, EFFECT_TYPE_EFFECT))); - } else { - // add default audio effects - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_VOLUME, EFFECT_TYPE_EFFECT))); - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_PAN, EFFECT_TYPE_EFFECT))); - } - } - } - if (olive::CurrentConfig.enable_seek_to_import) { - panel_sequence_viewer->seek(earliest_point); - } - ghosts.clear(); - importing = false; - snapped = false; + if (olive::CurrentConfig.add_default_effects_to_clips) { + if (c->track < 0) { + // add default video effects + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TRANSFORM, EFFECT_TYPE_EFFECT))); + } else { + // add default audio effects + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_VOLUME, EFFECT_TYPE_EFFECT))); + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_PAN, EFFECT_TYPE_EFFECT))); + } + } + } + if (olive::CurrentConfig.enable_seek_to_import) { + panel_sequence_viewer->seek(earliest_point); + } + ghosts.clear(); + importing = false; + snapped = false; } int Timeline::get_track_height_size(bool video) { - if (video) { - return video_track_heights.size(); - } else { - return audio_track_heights.size(); - } + if (video) { + return video_track_heights.size(); + } else { + return audio_track_heights.size(); + } } void Timeline::add_transition() { - ComboAction* ca = new ComboAction(); - bool adding = false; + ComboAction* ca = new ComboAction(); + bool adding = false; - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr && is_clip_selected(c, true)) { - int transition_to_add = (c->track < 0) ? TRANSITION_INTERNAL_CROSSDISSOLVE : TRANSITION_INTERNAL_LINEARFADE; - if (c->get_opening_transition() == nullptr) { - ca->append(new AddTransitionCommand(c, nullptr, nullptr, get_internal_meta(transition_to_add, EFFECT_TYPE_TRANSITION), kTransitionOpening, 30)); - adding = true; - } - if (c->get_closing_transition() == nullptr) { - ca->append(new AddTransitionCommand(c, nullptr, nullptr, get_internal_meta(transition_to_add, EFFECT_TYPE_TRANSITION), kTransitionClosing, 30)); - adding = true; - } - } - } + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr && is_clip_selected(c, true)) { + int transition_to_add = (c->track < 0) ? TRANSITION_INTERNAL_CROSSDISSOLVE : TRANSITION_INTERNAL_LINEARFADE; + if (c->get_opening_transition() == nullptr) { + ca->append(new AddTransitionCommand(c, nullptr, nullptr, get_internal_meta(transition_to_add, EFFECT_TYPE_TRANSITION), kTransitionOpening, 30)); + adding = true; + } + if (c->get_closing_transition() == nullptr) { + ca->append(new AddTransitionCommand(c, nullptr, nullptr, get_internal_meta(transition_to_add, EFFECT_TYPE_TRANSITION), kTransitionClosing, 30)); + adding = true; + } + } + } - if (adding) { - olive::UndoStack.push(ca); - } else { - delete ca; - } + if (adding) { + olive::UndoStack.push(ca); + } else { + delete ca; + } - update_ui(true); + update_ui(true); } void Timeline::nest() { - if (olive::ActiveSequence != nullptr) { - QVector selected_clips; - long earliest_point = LONG_MAX; + if (olive::ActiveSequence != nullptr) { + QVector selected_clips; + long earliest_point = LONG_MAX; - // get selected clips - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr && is_clip_selected(c, true)) { - selected_clips.append(i); - earliest_point = qMin(c->timeline_in, earliest_point); - } - } - - // nest them - if (!selected_clips.isEmpty()) { - ComboAction* ca = new ComboAction(); - - SequencePtr s(new Sequence()); - - // create "nest" sequence - s->name = panel_project->get_next_sequence_name(tr("Nested Sequence")); - s->width = olive::ActiveSequence->width; - s->height = olive::ActiveSequence->height; - s->frame_rate = olive::ActiveSequence->frame_rate; - s->audio_frequency = olive::ActiveSequence->audio_frequency; - s->audio_layout = olive::ActiveSequence->audio_layout; - - // copy all selected clips to the nest - for (int i=0;iappend(new DeleteClipAction(olive::ActiveSequence, selected_clips.at(i))); - - // copy to new - ClipPtr copy(olive::ActiveSequence->clips.at(selected_clips.at(i))->copy(s)); - copy->timeline_in -= earliest_point; - copy->timeline_out -= earliest_point; - s->clips.append(copy); - } - - // relink clips in new nested sequences - relink_clips_using_ids(selected_clips, s->clips); - - // add sequence to project - Media* m = panel_project->create_sequence_internal(ca, s, false, nullptr); - - // add nested sequence to active sequence - QVector media_list; - media_list.append(m); - create_ghosts_from_media(olive::ActiveSequence, earliest_point, media_list); - add_clips_from_ghosts(ca, olive::ActiveSequence); - - panel_effect_controls->clear_effects(true); - olive::ActiveSequence->selections.clear(); - - olive::UndoStack.push(ca); - - update_ui(true); - } + // get selected clips + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr && is_clip_selected(c, true)) { + selected_clips.append(i); + earliest_point = qMin(c->timeline_in, earliest_point); + } } + + // nest them + if (!selected_clips.isEmpty()) { + ComboAction* ca = new ComboAction(); + + SequencePtr s(new Sequence()); + + // create "nest" sequence + s->name = panel_project->get_next_sequence_name(tr("Nested Sequence")); + s->width = olive::ActiveSequence->width; + s->height = olive::ActiveSequence->height; + s->frame_rate = olive::ActiveSequence->frame_rate; + s->audio_frequency = olive::ActiveSequence->audio_frequency; + s->audio_layout = olive::ActiveSequence->audio_layout; + + // copy all selected clips to the nest + for (int i=0;iappend(new DeleteClipAction(olive::ActiveSequence, selected_clips.at(i))); + + // copy to new + ClipPtr copy(olive::ActiveSequence->clips.at(selected_clips.at(i))->copy(s)); + copy->timeline_in -= earliest_point; + copy->timeline_out -= earliest_point; + s->clips.append(copy); + } + + // relink clips in new nested sequences + relink_clips_using_ids(selected_clips, s->clips); + + // add sequence to project + Media* m = panel_project->create_sequence_internal(ca, s, false, nullptr); + + // add nested sequence to active sequence + QVector media_list; + media_list.append(m); + create_ghosts_from_media(olive::ActiveSequence, earliest_point, media_list); + add_clips_from_ghosts(ca, olive::ActiveSequence); + + panel_effect_controls->clear_effects(true); + olive::ActiveSequence->selections.clear(); + + olive::UndoStack.push(ca); + + update_ui(true); + } + } } int Timeline::calculate_track_height(int track, int value) { - int index = (track < 0) ? qAbs(track + 1) : track; - QVector& vector = (track < 0) ? video_track_heights : audio_track_heights; - while (vector.size() < index+1) { - vector.append(default_track_height); - } - if (value > -1) { - vector[index] = value; - } - return vector.at(index); + int index = (track < 0) ? qAbs(track + 1) : track; + QVector& vector = (track < 0) ? video_track_heights : audio_track_heights; + while (vector.size() < index+1) { + vector.append(default_track_height); + } + if (value > -1) { + vector[index] = value; + } + return vector.at(index); } void Timeline::update_sequence() { - bool null_sequence = (olive::ActiveSequence == nullptr); + bool null_sequence = (olive::ActiveSequence == nullptr); - for (int i=0;isetEnabled(!null_sequence); - } - snappingButton->setEnabled(!null_sequence); - zoomInButton->setEnabled(!null_sequence); - zoomOutButton->setEnabled(!null_sequence); - recordButton->setEnabled(!null_sequence); - addButton->setEnabled(!null_sequence); - headers->setEnabled(!null_sequence); + for (int i=0;isetEnabled(!null_sequence); + } + snappingButton->setEnabled(!null_sequence); + zoomInButton->setEnabled(!null_sequence); + zoomOutButton->setEnabled(!null_sequence); + recordButton->setEnabled(!null_sequence); + addButton->setEnabled(!null_sequence); + headers->setEnabled(!null_sequence); - QString title = tr("Timeline: "); - if (null_sequence) { - setWindowTitle(title + tr("")); - } else { - setWindowTitle(title + olive::ActiveSequence->name); - update_ui(false); - } + UpdateTitle(); } int Timeline::get_snap_range() { - return getFrameFromScreenPoint(zoom, 10); + return getFrameFromScreenPoint(zoom, 10); } bool Timeline::focused() { - return (olive::ActiveSequence != nullptr && (headers->hasFocus() || video_area->hasFocus() || audio_area->hasFocus())); + return (olive::ActiveSequence != nullptr && (headers->hasFocus() || video_area->hasFocus() || audio_area->hasFocus())); } void Timeline::repaint_timeline() { - if (!block_repaints) { - bool draw = true; + if (!block_repaints) { + bool draw = true; - if (olive::ActiveSequence != nullptr - && !horizontalScrollBar->isSliderDown() - && !horizontalScrollBar->is_resizing() - && panel_sequence_viewer->playing - && !zoom_just_changed) { - // auto scroll - if (olive::CurrentConfig.autoscroll == AUTOSCROLL_PAGE_SCROLL) { - int playhead_x = getTimelineScreenPointFromFrame(olive::ActiveSequence->playhead); - if (playhead_x < 0 || playhead_x > (editAreas->width() - videoScrollbar->width())) { - horizontalScrollBar->setValue(getScreenPointFromFrame(zoom, olive::ActiveSequence->playhead)); - draw = false; - } - } else if (olive::CurrentConfig.autoscroll == AUTOSCROLL_SMOOTH_SCROLL) { - if (center_scroll_to_playhead(horizontalScrollBar, zoom, olive::ActiveSequence->playhead)) { - draw = false; - } - } - } + if (olive::ActiveSequence != nullptr + && !horizontalScrollBar->isSliderDown() + && !horizontalScrollBar->is_resizing() + && panel_sequence_viewer->playing + && !zoom_just_changed) { + // auto scroll + if (olive::CurrentConfig.autoscroll == AUTOSCROLL_PAGE_SCROLL) { + int playhead_x = getTimelineScreenPointFromFrame(olive::ActiveSequence->playhead); + if (playhead_x < 0 || playhead_x > (editAreas->width() - videoScrollbar->width())) { + horizontalScrollBar->setValue(getScreenPointFromFrame(zoom, olive::ActiveSequence->playhead)); + draw = false; + } + } else if (olive::CurrentConfig.autoscroll == AUTOSCROLL_SMOOTH_SCROLL) { + if (center_scroll_to_playhead(horizontalScrollBar, zoom, olive::ActiveSequence->playhead)) { + draw = false; + } + } + } - if (draw) { - headers->update(); - video_area->update(); - audio_area->update(); + if (draw) { + headers->update(); + video_area->update(); + audio_area->update(); - if (olive::ActiveSequence != nullptr - && !zoom_just_changed) { - set_sb_max(); - } - } + if (olive::ActiveSequence != nullptr + && !zoom_just_changed) { + set_sb_max(); + } + } - zoom_just_changed = false; - } + zoom_just_changed = false; + } } void Timeline::select_all() { - if (olive::ActiveSequence != nullptr) { - olive::ActiveSequence->selections.clear(); - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr) { - Selection s; - s.in = c->timeline_in; - s.out = c->timeline_out; - s.track = c->track; - olive::ActiveSequence->selections.append(s); - } - } - repaint_timeline(); - } + if (olive::ActiveSequence != nullptr) { + olive::ActiveSequence->selections.clear(); + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr) { + Selection s; + s.in = c->timeline_in; + s.out = c->timeline_out; + s.track = c->track; + olive::ActiveSequence->selections.append(s); + } + } + repaint_timeline(); + } } void Timeline::scroll_to_frame(long frame) { - scroll_to_frame_internal(horizontalScrollBar, frame, zoom, timeline_area->width()); + scroll_to_frame_internal(horizontalScrollBar, frame, zoom, timeline_area->width()); } void Timeline::select_from_playhead() { - olive::ActiveSequence->selections.clear(); - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr - && c->timeline_in <= olive::ActiveSequence->playhead - && c->timeline_out > olive::ActiveSequence->playhead) { - Selection s; - s.in = c->timeline_in; - s.out = c->timeline_out; - s.track = c->track; - olive::ActiveSequence->selections.append(s); - } - } + olive::ActiveSequence->selections.clear(); + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr + && c->timeline_in <= olive::ActiveSequence->playhead + && c->timeline_out > olive::ActiveSequence->playhead) { + Selection s; + s.in = c->timeline_in; + s.out = c->timeline_out; + s.track = c->track; + olive::ActiveSequence->selections.append(s); + } + } } bool Timeline::can_ripple_empty_space(long frame, int track) { - bool can_ripple_delete = true; - bool at_end_of_sequence = true; - rc_ripple_min = 0; - rc_ripple_max = LONG_MAX; + bool can_ripple_delete = true; + bool at_end_of_sequence = true; + rc_ripple_min = 0; + rc_ripple_max = LONG_MAX; - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr) { - if (c->timeline_in > frame || c->timeline_out > frame) { - at_end_of_sequence = false; - } - if (c->track == track) { - if (c->timeline_in <= frame && c->timeline_out >= frame) { - can_ripple_delete = false; - break; - } else if (c->timeline_out < frame) { - rc_ripple_min = qMax(rc_ripple_min, c->timeline_out); - } else if (c->timeline_in > frame) { - rc_ripple_max = qMin(rc_ripple_max, c->timeline_in); - } - } - } - } + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr) { + if (c->timeline_in > frame || c->timeline_out > frame) { + at_end_of_sequence = false; + } + if (c->track == track) { + if (c->timeline_in <= frame && c->timeline_out >= frame) { + can_ripple_delete = false; + break; + } else if (c->timeline_out < frame) { + rc_ripple_min = qMax(rc_ripple_min, c->timeline_out); + } else if (c->timeline_in > frame) { + rc_ripple_max = qMin(rc_ripple_max, c->timeline_in); + } + } + } + } - return (can_ripple_delete && !at_end_of_sequence); + return (can_ripple_delete && !at_end_of_sequence); } void Timeline::ripple_delete_empty_space() { - QVector sels; + QVector sels; - Selection s; - s.in = rc_ripple_min; - s.out = rc_ripple_max; - s.track = cursor_track; + Selection s; + s.in = rc_ripple_min; + s.out = rc_ripple_max; + s.track = cursor_track; - sels.append(s); + sels.append(s); - delete_selection(sels, true); + delete_selection(sels, true); } void Timeline::resizeEvent(QResizeEvent *) { - // adjust maximum scrollbar - if (olive::ActiveSequence != nullptr) set_sb_max(); + // adjust maximum scrollbar + if (olive::ActiveSequence != nullptr) set_sb_max(); - // resize tool button widget to its contents - QList tool_button_children = tool_button_widget->findChildren(); + // resize tool button widget to its contents + QList tool_button_children = tool_button_widget->findChildren(); - int horizontal_spacing = static_cast(tool_button_widget->layout())->horizontalSpacing(); - int vertical_spacing = static_cast(tool_button_widget->layout())->verticalSpacing(); - int total_area = tool_button_widget->height(); + int horizontal_spacing = static_cast(tool_button_widget->layout())->horizontalSpacing(); + int vertical_spacing = static_cast(tool_button_widget->layout())->verticalSpacing(); + int total_area = tool_button_widget->height(); - int button_count = tool_button_children.size(); - int button_height = tool_button_children.at(0)->sizeHint().height() + vertical_spacing; + int button_count = tool_button_children.size(); + int button_height = tool_button_children.at(0)->sizeHint().height() + vertical_spacing; - int cols = 0; + int cols = 0; - int col_height; + int col_height; - if (button_height < total_area) { - do { - cols++; - col_height = (qCeil(double(button_count)/double(cols))*button_height)-vertical_spacing; - } while (col_height > total_area); - } else { - cols = button_count; - } + if (button_height < total_area) { + do { + cols++; + col_height = (qCeil(double(button_count)/double(cols))*button_height)-vertical_spacing; + } while (col_height > total_area); + } else { + cols = button_count; + } - tool_button_widget->setFixedWidth((tool_button_children.at(0)->sizeHint().width())*cols + horizontal_spacing*(cols-1) + 1); + tool_button_widget->setFixedWidth((tool_button_children.at(0)->sizeHint().width())*cols + horizontal_spacing*(cols-1) + 1); } void Timeline::delete_in_out_internal(bool ripple) { - if (olive::ActiveSequence != nullptr && olive::ActiveSequence->using_workarea) { - QVector areas; - int video_tracks = 0, audio_tracks = 0; - olive::ActiveSequence->getTrackLimits(&video_tracks, &audio_tracks); - for (int i=video_tracks;i<=audio_tracks;i++) { - Selection s; - s.in = olive::ActiveSequence->workarea_in; - s.out = olive::ActiveSequence->workarea_out; - s.track = i; - areas.append(s); - } - ComboAction* ca = new ComboAction(); - delete_areas_and_relink(ca, areas, true); - if (ripple) ripple_clips(ca, olive::ActiveSequence, olive::ActiveSequence->workarea_in, olive::ActiveSequence->workarea_in - olive::ActiveSequence->workarea_out); - ca->append(new SetTimelineInOutCommand(olive::ActiveSequence, false, 0, 0)); - olive::UndoStack.push(ca); - update_ui(true); + if (olive::ActiveSequence != nullptr && olive::ActiveSequence->using_workarea) { + QVector areas; + int video_tracks = 0, audio_tracks = 0; + olive::ActiveSequence->getTrackLimits(&video_tracks, &audio_tracks); + for (int i=video_tracks;i<=audio_tracks;i++) { + Selection s; + s.in = olive::ActiveSequence->workarea_in; + s.out = olive::ActiveSequence->workarea_out; + s.track = i; + areas.append(s); } + ComboAction* ca = new ComboAction(); + delete_areas_and_relink(ca, areas, true); + if (ripple) ripple_clips(ca, olive::ActiveSequence, olive::ActiveSequence->workarea_in, olive::ActiveSequence->workarea_in - olive::ActiveSequence->workarea_out); + ca->append(new SetTimelineInOutCommand(olive::ActiveSequence, false, 0, 0)); + olive::UndoStack.push(ca); + update_ui(true); + } } void Timeline::toggle_enable_on_selected_clips() { - if (olive::ActiveSequence != nullptr) { - ComboAction* ca = new ComboAction(); - bool push_undo = false; - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr && is_clip_selected(c, true)) { - ca->append(new SetBool(&c->enabled, !c->enabled)); - push_undo = true; - } - } - if (push_undo) { - olive::UndoStack.push(ca); - update_ui(true); - } else { - delete ca; - } + if (olive::ActiveSequence != nullptr) { + ComboAction* ca = new ComboAction(); + bool push_undo = false; + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr && is_clip_selected(c, true)) { + ca->append(new SetBool(&c->enabled, !c->enabled)); + push_undo = true; + } } + if (push_undo) { + olive::UndoStack.push(ca); + update_ui(true); + } else { + delete ca; + } + } } void Timeline::delete_selection(QVector& selections, bool ripple_delete) { - if (selections.size() > 0) { - panel_effect_controls->clear_effects(true); + if (selections.size() > 0) { + panel_effect_controls->clear_effects(true); - ComboAction* ca = new ComboAction(); + ComboAction* ca = new ComboAction(); - delete_areas_and_relink(ca, selections, true); + delete_areas_and_relink(ca, selections, true); - if (ripple_delete) { - long ripple_point = selections.at(0).in; - long ripple_length = selections.at(0).out - selections.at(0).in; + if (ripple_delete) { + long ripple_point = selections.at(0).in; + long ripple_length = selections.at(0).out - selections.at(0).in; - // retrieve ripple_point and ripple_length from current selection - for (int i=1;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr && c->timeline_in < ripple_point && c->timeline_out > ripple_point) { - // conflict detected, but this clip may be getting deleted so let's check - bool deleted = false; - for (int j=0;jtrack - && !(c->timeline_in < s.in && c->timeline_out < s.in) - && !(c->timeline_in > s.out && c->timeline_out > s.out)) { - deleted = true; - break; - } - } - if (!deleted) { - for (int j=0;jclips.size();j++) { - ClipPtr cc = olive::ActiveSequence->clips.at(j); - if (cc != nullptr - && cc->track == c->track - && cc->timeline_in > c->timeline_out - && cc->timeline_in < c->timeline_out + ripple_length) { - ripple_length = cc->timeline_in - c->timeline_out; - } - } - } - } - } + bool can_ripple = true; + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr && c->timeline_in < ripple_point && c->timeline_out > ripple_point) { + // conflict detected, but this clip may be getting deleted so let's check + bool deleted = false; + for (int j=0;jtrack + && !(c->timeline_in < s.in && c->timeline_out < s.in) + && !(c->timeline_in > s.out && c->timeline_out > s.out)) { + deleted = true; + break; + } + } + if (!deleted) { + for (int j=0;jclips.size();j++) { + ClipPtr cc = olive::ActiveSequence->clips.at(j); + if (cc != nullptr + && cc->track == c->track + && cc->timeline_in > c->timeline_out + && cc->timeline_in < c->timeline_out + ripple_length) { + ripple_length = cc->timeline_in - c->timeline_out; + } + } + } + } + } - if (can_ripple) { - ripple_clips(ca, olive::ActiveSequence, ripple_point, -ripple_length); - panel_sequence_viewer->seek(ripple_point-1); - } - } + if (can_ripple) { + ripple_clips(ca, olive::ActiveSequence, ripple_point, -ripple_length); + panel_sequence_viewer->seek(ripple_point-1); + } + } - olive::UndoStack.push(ca); + olive::UndoStack.push(ca); - update_ui(true); - } + update_ui(true); + } } void Timeline::set_zoom_value(double v) { - // set zoom value - zoom = v; + // set zoom value + zoom = v; - // update header zoom to match - headers->update_zoom(zoom); + // update header zoom to match + headers->update_zoom(zoom); - // set flag that zoom has just changed to prevent auto-scrolling since we change the scroll below - zoom_just_changed = true; + // set flag that zoom has just changed to prevent auto-scrolling since we change the scroll below + zoom_just_changed = true; - // set scrollbar to center the playhead - if (olive::ActiveSequence != nullptr - && !horizontalScrollBar->is_resizing()) { - // update scrollbar maximum value for new zoom - set_sb_max(); + // set scrollbar to center the playhead + if (olive::ActiveSequence != nullptr + && !horizontalScrollBar->is_resizing()) { + // update scrollbar maximum value for new zoom + set_sb_max(); - center_scroll_to_playhead(horizontalScrollBar, zoom, olive::ActiveSequence->playhead); - } + center_scroll_to_playhead(horizontalScrollBar, zoom, olive::ActiveSequence->playhead); + } - // repaint the timeline for the new zoom/location - repaint_timeline(); + // repaint the timeline for the new zoom/location + repaint_timeline(); } void Timeline::multiply_zoom(double m) { - showing_all = false; - set_zoom_value(zoom * m); + showing_all = false; + set_zoom_value(zoom * m); } void Timeline::decheck_tool_buttons(QObject* sender) { - for (int i=0;isetChecked(tool_buttons.at(i) == sender); - } + for (int i=0;isetChecked(tool_buttons.at(i) == sender); + } } QVector Timeline::get_tracks_of_linked_clips(int i) { - QVector tracks; - ClipPtr clip = olive::ActiveSequence->clips.at(i); - for (int j=0;jlinked.size();j++) { - tracks.append(olive::ActiveSequence->clips.at(clip->linked.at(j))->track); - } - return tracks; + QVector tracks; + ClipPtr clip = olive::ActiveSequence->clips.at(i); + for (int j=0;jlinked.size();j++) { + tracks.append(olive::ActiveSequence->clips.at(clip->linked.at(j))->track); + } + return tracks; } void Timeline::zoom_in() { - multiply_zoom(2.0); + multiply_zoom(2.0); } void Timeline::zoom_out() { - multiply_zoom(0.5); + multiply_zoom(0.5); } bool is_clip_selected(ClipPtr clip, bool containing) { - for (int i=0;isequence->selections.size();i++) { - const Selection& s = clip->sequence->selections.at(i); - if (clip->track == s.track && ((clip->timeline_in >= s.in && clip->timeline_out <= s.out && containing) || - (!containing && !(clip->timeline_in < s.in && clip->timeline_out < s.in) && !(clip->timeline_in > s.in && clip->timeline_out > s.in)))) { - return true; - } - } - return false; + for (int i=0;isequence->selections.size();i++) { + const Selection& s = clip->sequence->selections.at(i); + if (clip->track == s.track && ((clip->timeline_in >= s.in && clip->timeline_out <= s.out && containing) || + (!containing && !(clip->timeline_in < s.in && clip->timeline_out < s.in) && !(clip->timeline_in > s.in && clip->timeline_out > s.in)))) { + return true; + } + } + return false; } void Timeline::snapping_clicked(bool checked) { - snapping = checked; + snapping = checked; } ClipPtr Timeline::split_clip(ComboAction* ca, bool transitions, int p, long frame) { - return split_clip(ca, transitions, p, frame, frame); + return split_clip(ca, transitions, p, frame, frame); } ClipPtr Timeline::split_clip(ComboAction* ca, bool transitions, int p, long frame, long post_in) { - ClipPtr pre = olive::ActiveSequence->clips.at(p); - if (pre != nullptr && pre->timeline_in < frame && pre->timeline_out > frame) { // guard against attempts to split at in/out points - bool splitting_closing_dual_transition = false; + ClipPtr pre = olive::ActiveSequence->clips.at(p); + if (pre != nullptr && pre->timeline_in < frame && pre->timeline_out > frame) { // guard against attempts to split at in/out points + bool splitting_closing_dual_transition = false; - if (transitions - && pre->get_closing_transition() != nullptr - && pre->get_closing_transition()->secondary_clip != nullptr) { - splitting_closing_dual_transition = true; - } + if (transitions + && pre->get_closing_transition() != nullptr + && pre->get_closing_transition()->secondary_clip != nullptr) { + splitting_closing_dual_transition = true; + } - ClipPtr post = ClipPtr(pre->copy(olive::ActiveSequence, transitions && !splitting_closing_dual_transition)); + ClipPtr post = ClipPtr(pre->copy(olive::ActiveSequence, transitions && !splitting_closing_dual_transition)); - long new_clip_length = frame - pre->timeline_in; + long new_clip_length = frame - pre->timeline_in; - post->timeline_in = post_in; - post->clip_in = pre->clip_in + (post->timeline_in - pre->timeline_in); + post->timeline_in = post_in; + post->clip_in = pre->clip_in + (post->timeline_in - pre->timeline_in); - move_clip(ca, pre, pre->timeline_in, frame, pre->clip_in, pre->track); + move_clip(ca, pre, pre->timeline_in, frame, pre->clip_in, pre->track); - if (pre->get_opening_transition() != nullptr) { -// if (frame < pre->timeline_in + pre->get_opening_transition()->length && pre->get_opening_transition()->secondary_clip != nullptr) { - // separate shared transition -// ca->append(new SetPointer((void**) &pre->get_opening_transition()->secondary_clip, nullptr)); -// pre->get_opening_transition()->secondary_clip->closing_transition = pre->get_opening_transition()->copy(pre->get_opening_transition()->secondary_clip, nullptr); -// } + if (pre->get_opening_transition() != nullptr) { + // if (frame < pre->timeline_in + pre->get_opening_transition()->length && pre->get_opening_transition()->secondary_clip != nullptr) { + // separate shared transition + // ca->append(new SetPointer((void**) &pre->get_opening_transition()->secondary_clip, nullptr)); + // pre->get_opening_transition()->secondary_clip->closing_transition = pre->get_opening_transition()->copy(pre->get_opening_transition()->secondary_clip, nullptr); + // } - if (pre->get_opening_transition()->get_true_length() > new_clip_length) { + if (pre->get_opening_transition()->get_true_length() > new_clip_length) { ca->append(new ModifyTransitionCommand(pre->get_opening_transition(), new_clip_length)); } - } - if (pre->get_closing_transition() != nullptr) { - if (splitting_closing_dual_transition) { - // just move closing transition to post clip + } + if (pre->get_closing_transition() != nullptr) { + if (splitting_closing_dual_transition) { + // just move closing transition to post clip - // WORKAROUND + // WORKAROUND ca->append(new DeleteTransitionCommand(pre->closing_transition)); - } else { + } else { ca->append(new DeleteTransitionCommand(pre->closing_transition)); - if (post->get_closing_transition() != nullptr) { - if (pre->get_closing_transition()->secondary_clip == nullptr) { - post->get_closing_transition()->set_length(qMin(long(post->get_closing_transition()->get_true_length()), post->getLength())); - } + if (post->get_closing_transition() != nullptr) { + if (pre->get_closing_transition()->secondary_clip == nullptr) { + post->get_closing_transition()->set_length(qMin(long(post->get_closing_transition()->get_true_length()), post->getLength())); + } - if (post->get_closing_transition()->get_length() > post->getLength()) { - post->get_closing_transition()->set_length(post->getLength()); - } - } - } - } + if (post->get_closing_transition()->get_length() > post->getLength()) { + post->get_closing_transition()->set_length(post->getLength()); + } + } + } + } - return post; - } - return nullptr; + return post; + } + return nullptr; } bool Timeline::has_clip_been_split(int c) { - for (int i=0;iclips.at(clip); - if (c != nullptr) { - QVector pre_clips; - QVector post_clips; + ClipPtr c = olive::ActiveSequence->clips.at(clip); + if (c != nullptr) { + QVector pre_clips; + QVector post_clips; - ClipPtr post = split_clip(ca, true, clip, frame); + ClipPtr post = split_clip(ca, true, clip, frame); - // if alt is not down, split clips links too - if (post == nullptr) { - return false; - } else { - post_clips.append(post); - if (relink) { - pre_clips.append(clip); + // if alt is not down, split clips links too + if (post == nullptr) { + return false; + } else { + post_clips.append(post); + if (relink) { + pre_clips.append(clip); - bool original_clip_is_selected = is_clip_selected(c, true); + bool original_clip_is_selected = is_clip_selected(c, true); - // find linked clips of old clip - for (int i=0;ilinked.size();i++) { - int l = c->linked.at(i); - if (!has_clip_been_split(l)) { - ClipPtr link = olive::ActiveSequence->clips.at(l); - if ((original_clip_is_selected && is_clip_selected(link, true)) || !original_clip_is_selected) { - split_cache.append(l); - ClipPtr s = split_clip(ca, true, l, frame); - if (s != nullptr) { - pre_clips.append(l); - post_clips.append(s); - } - } - } - } + // find linked clips of old clip + for (int i=0;ilinked.size();i++) { + int l = c->linked.at(i); + if (!has_clip_been_split(l)) { + ClipPtr link = olive::ActiveSequence->clips.at(l); + if ((original_clip_is_selected && is_clip_selected(link, true)) || !original_clip_is_selected) { + split_cache.append(l); + ClipPtr s = split_clip(ca, true, l, frame); + if (s != nullptr) { + pre_clips.append(l); + post_clips.append(s); + } + } + } + } - relink_clips_using_ids(pre_clips, post_clips); - } - ca->append(new AddClipCommand(olive::ActiveSequence, post_clips)); - return true; - } - } - return false; + relink_clips_using_ids(pre_clips, post_clips); + } + ca->append(new AddClipCommand(olive::ActiveSequence, post_clips)); + return true; + } + } + return false; } void Timeline::clean_up_selections(QVector& areas) { - for (int i=0;i ss.out) { - // do nothing - } else if (s.in >= ss.in && s.out <= ss.out) { - remove = true; - } else if (s.in <= ss.out && s.out > ss.out) { - ss.out = s.out; - remove = true; - } else if (s.out >= ss.in && s.in < ss.in) { - ss.in = s.in; - remove = true; - } - if (remove) { - areas.removeAt(i); - i--; - break; - } - } - } - } - } + for (int i=0;i ss.out) { + // do nothing + } else if (s.in >= ss.in && s.out <= ss.out) { + remove = true; + } else if (s.in <= ss.out && s.out > ss.out) { + ss.out = s.out; + remove = true; + } else if (s.out >= ss.in && s.in < ss.in) { + ss.in = s.in; + remove = true; + } + if (remove) { + areas.removeAt(i); + i--; + break; + } + } + } + } + } } bool selection_contains_transition(const Selection& s, ClipPtr c, int type) { if (type == kTransitionOpening) { - return c->get_opening_transition() != nullptr - && s.out == c->timeline_in + c->get_opening_transition()->get_true_length() - && ((c->get_opening_transition()->secondary_clip == nullptr && s.in == c->timeline_in) - || (c->get_opening_transition()->secondary_clip != nullptr && s.in == c->timeline_in - c->get_opening_transition()->get_true_length())); - } else { - return c->get_closing_transition() != nullptr - && s.in == c->timeline_out - c->get_closing_transition()->get_true_length() - && ((c->get_closing_transition()->secondary_clip == nullptr && s.out == c->timeline_out) - || (c->get_closing_transition()->secondary_clip != nullptr && s.out == c->timeline_out + c->get_closing_transition()->get_true_length())); - } + return c->get_opening_transition() != nullptr + && s.out == c->timeline_in + c->get_opening_transition()->get_true_length() + && ((c->get_opening_transition()->secondary_clip == nullptr && s.in == c->timeline_in) + || (c->get_opening_transition()->secondary_clip != nullptr && s.in == c->timeline_in - c->get_opening_transition()->get_true_length())); + } else { + return c->get_closing_transition() != nullptr + && s.in == c->timeline_out - c->get_closing_transition()->get_true_length() + && ((c->get_closing_transition()->secondary_clip == nullptr && s.out == c->timeline_out) + || (c->get_closing_transition()->secondary_clip != nullptr && s.out == c->timeline_out + c->get_closing_transition()->get_true_length())); + } } void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& areas, bool deselect_areas) { - clean_up_selections(areas); - panel_effect_controls->clear_effects(true); + clean_up_selections(areas); + panel_effect_controls->clear_effects(true); - QVector pre_clips; - QVector post_clips; + QVector pre_clips; + QVector post_clips; - for (int i=0;iclips.size();j++) { - ClipPtr c = olive::ActiveSequence->clips.at(j); - if (c != nullptr && c->track == s.track && !c->undeletable) { + for (int i=0;iclips.size();j++) { + ClipPtr c = olive::ActiveSequence->clips.at(j); + if (c != nullptr && c->track == s.track && !c->undeletable) { if (selection_contains_transition(s, c, kTransitionOpening)) { - // delete opening transition + // delete opening transition ca->append(new DeleteTransitionCommand(c->opening_transition)); } else if (selection_contains_transition(s, c, kTransitionClosing)) { - // delete closing transition + // delete closing transition ca->append(new DeleteTransitionCommand(c->closing_transition)); - } else if (c->timeline_in >= s.in && c->timeline_out <= s.out) { - // clips falls entirely within deletion area - ca->append(new DeleteClipAction(olive::ActiveSequence, j)); - } else if (c->timeline_in < s.in && c->timeline_out > s.out) { - // middle of clip is within deletion area + } else if (c->timeline_in >= s.in && c->timeline_out <= s.out) { + // clips falls entirely within deletion area + ca->append(new DeleteClipAction(olive::ActiveSequence, j)); + } else if (c->timeline_in < s.in && c->timeline_out > s.out) { + // middle of clip is within deletion area - // duplicate clip - ClipPtr post = split_clip(ca, true, j, s.in, s.out); + // duplicate clip + ClipPtr post = split_clip(ca, true, j, s.in, s.out); - pre_clips.append(j); - post_clips.append(post); - } else if (c->timeline_in < s.in && c->timeline_out > s.in) { - // only out point is in deletion area - move_clip(ca, c, c->timeline_in, s.in, c->clip_in, c->track); + pre_clips.append(j); + post_clips.append(post); + } else if (c->timeline_in < s.in && c->timeline_out > s.in) { + // only out point is in deletion area + move_clip(ca, c, c->timeline_in, s.in, c->clip_in, c->track); - if (c->get_closing_transition() != nullptr) { - if (s.in < c->timeline_out - c->get_closing_transition()->get_true_length()) { + if (c->get_closing_transition() != nullptr) { + if (s.in < c->timeline_out - c->get_closing_transition()->get_true_length()) { ca->append(new DeleteTransitionCommand(c->closing_transition)); - } else { + } else { ca->append(new ModifyTransitionCommand(c->closing_transition, c->get_closing_transition()->get_true_length() - (c->timeline_out - s.in))); - } - } - } else if (c->timeline_in < s.out && c->timeline_out > s.out) { - // only in point is in deletion area - move_clip(ca, c, s.out, c->timeline_out, c->clip_in + (s.out - c->timeline_in), c->track); + } + } + } else if (c->timeline_in < s.out && c->timeline_out > s.out) { + // only in point is in deletion area + move_clip(ca, c, s.out, c->timeline_out, c->clip_in + (s.out - c->timeline_in), c->track); - if (c->get_opening_transition() != nullptr) { - if (s.out > c->timeline_in + c->get_opening_transition()->get_true_length()) { + if (c->get_opening_transition() != nullptr) { + if (s.out > c->timeline_in + c->get_opening_transition()->get_true_length()) { ca->append(new DeleteTransitionCommand(c->opening_transition)); - } else { + } else { ca->append(new ModifyTransitionCommand(c->opening_transition, c->get_opening_transition()->get_true_length() - (s.out - c->timeline_in))); - } - } - } - } - } - } + } + } + } + } + } + } - // deselect selected clip areas - if (deselect_areas) { - QVector area_copy = areas; - for (int i=0;i area_copy = areas; + for (int i=0;iappend(new AddClipCommand(olive::ActiveSequence, post_clips)); + relink_clips_using_ids(pre_clips, post_clips); + ca->append(new AddClipCommand(olive::ActiveSequence, post_clips)); } void Timeline::copy(bool del) { - bool cleared = false; - bool copied = false; + bool cleared = false; + bool copied = false; - long min_in = 0; + long min_in = 0; - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr) { - for (int j=0;jselections.size();j++) { - const Selection& s = olive::ActiveSequence->selections.at(j); - if (s.track == c->track && !((c->timeline_in <= s.in && c->timeline_out <= s.in) || (c->timeline_in >= s.out && c->timeline_out >= s.out))) { - if (!cleared) { - clear_clipboard(); - cleared = true; - clipboard_type = CLIPBOARD_TYPE_CLIP; - } + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr) { + for (int j=0;jselections.size();j++) { + const Selection& s = olive::ActiveSequence->selections.at(j); + if (s.track == c->track && !((c->timeline_in <= s.in && c->timeline_out <= s.in) || (c->timeline_in >= s.out && c->timeline_out >= s.out))) { + if (!cleared) { + clear_clipboard(); + cleared = true; + clipboard_type = CLIPBOARD_TYPE_CLIP; + } - ClipPtr copied_clip = c->copy(nullptr); + ClipPtr copied_clip = c->copy(nullptr); - // copy linked IDs (we correct these later in paste()) - copied_clip->linked = c->linked; + // copy linked IDs (we correct these later in paste()) + copied_clip->linked = c->linked; - if (copied_clip->timeline_in < s.in) { - copied_clip->clip_in += (s.in - copied_clip->timeline_in); - copied_clip->timeline_in = s.in; - } + if (copied_clip->timeline_in < s.in) { + copied_clip->clip_in += (s.in - copied_clip->timeline_in); + copied_clip->timeline_in = s.in; + } - if (copied_clip->timeline_out > s.out) { - copied_clip->timeline_out = s.out; - } + if (copied_clip->timeline_out > s.out) { + copied_clip->timeline_out = s.out; + } - if (copied) { - min_in = qMin(min_in, s.in); - } else { - min_in = s.in; - copied = true; - } + if (copied) { + min_in = qMin(min_in, s.in); + } else { + min_in = s.in; + copied = true; + } - copied_clip->load_id = i; + copied_clip->load_id = i; - clipboard.append(copied_clip); - } - } - } - } + clipboard.append(copied_clip); + } + } + } + } - for (int i=0;i(clipboard.at(i))->timeline_in -= min_in; - std::static_pointer_cast(clipboard.at(i))->timeline_out -= min_in; - } + for (int i=0;i(clipboard.at(i))->timeline_in -= min_in; + std::static_pointer_cast(clipboard.at(i))->timeline_out -= min_in; + } - if (del && copied) { - delete_selection(olive::ActiveSequence->selections, false); - } + if (del && copied) { + delete_selection(olive::ActiveSequence->selections, false); + } } void Timeline::relink_clips_using_ids(QVector& old_clips, QVector& new_clips) { - // relink pasted clips - for (int i=0;iclips.at(old_clips.at(i)); - for (int j=0;jlinked.size();j++) { - for (int k=0;klinked.at(j) == old_clips.at(k)) { - if (new_clips.at(i) != nullptr) { - new_clips.at(i)->linked.append(k); - } - } - } - } - } + // relink pasted clips + for (int i=0;iclips.at(old_clips.at(i)); + for (int j=0;jlinked.size();j++) { + for (int k=0;klinked.at(j) == old_clips.at(k)) { + if (new_clips.at(i) != nullptr) { + new_clips.at(i)->linked.append(k); + } + } + } + } + } } void Timeline::paste(bool insert) { - if (clipboard.size() > 0) { - if (clipboard_type == CLIPBOARD_TYPE_CLIP) { - ComboAction* ca = new ComboAction(); + if (clipboard.size() > 0) { + if (clipboard_type == CLIPBOARD_TYPE_CLIP) { + ComboAction* ca = new ComboAction(); - // create copies and delete areas that we'll be pasting to - QVector delete_areas; - QVector pasted_clips; - long paste_start = LONG_MAX; - long paste_end = LONG_MIN; - for (int i=0;i(clipboard.at(i)); + // create copies and delete areas that we'll be pasting to + QVector delete_areas; + QVector pasted_clips; + long paste_start = LONG_MAX; + long paste_end = LONG_MIN; + for (int i=0;i(clipboard.at(i)); - // create copy of clip and offset by playhead - ClipPtr cc(c->copy(olive::ActiveSequence)); + // create copy of clip and offset by playhead + ClipPtr cc(c->copy(olive::ActiveSequence)); - // convert frame rates - cc->timeline_in = refactor_frame_number(cc->timeline_in, c->cached_fr, olive::ActiveSequence->frame_rate); - cc->timeline_out = refactor_frame_number(cc->timeline_out, c->cached_fr, olive::ActiveSequence->frame_rate); - cc->clip_in = refactor_frame_number(cc->clip_in, c->cached_fr, olive::ActiveSequence->frame_rate); + // convert frame rates + cc->timeline_in = refactor_frame_number(cc->timeline_in, c->cached_fr, olive::ActiveSequence->frame_rate); + cc->timeline_out = refactor_frame_number(cc->timeline_out, c->cached_fr, olive::ActiveSequence->frame_rate); + cc->clip_in = refactor_frame_number(cc->clip_in, c->cached_fr, olive::ActiveSequence->frame_rate); - cc->timeline_in += olive::ActiveSequence->playhead; - cc->timeline_out += olive::ActiveSequence->playhead; - cc->track = c->track; + cc->timeline_in += olive::ActiveSequence->playhead; + cc->timeline_out += olive::ActiveSequence->playhead; + cc->track = c->track; - paste_start = qMin(paste_start, cc->timeline_in); - paste_end = qMax(paste_end, cc->timeline_out); + paste_start = qMin(paste_start, cc->timeline_in); + paste_end = qMax(paste_end, cc->timeline_out); - pasted_clips.append(cc); + pasted_clips.append(cc); - if (!insert) { - Selection s; - s.in = cc->timeline_in; - s.out = cc->timeline_out; - s.track = c->track; - delete_areas.append(s); - } - } - if (insert) { - split_cache.clear(); - split_all_clips_at_point(ca, olive::ActiveSequence->playhead); - ripple_clips(ca, olive::ActiveSequence, paste_start, paste_end - paste_start); - } else { - delete_areas_and_relink(ca, delete_areas, false); - } + if (!insert) { + Selection s; + s.in = cc->timeline_in; + s.out = cc->timeline_out; + s.track = c->track; + delete_areas.append(s); + } + } + if (insert) { + split_cache.clear(); + split_all_clips_at_point(ca, olive::ActiveSequence->playhead); + ripple_clips(ca, olive::ActiveSequence, paste_start, paste_end - paste_start); + } else { + delete_areas_and_relink(ca, delete_areas, false); + } - // correct linked clips - for (int i=0;i(clipboard.at(i)); + // correct linked clips + for (int i=0;i(clipboard.at(i)); - for (int j=0;jlinked.size();j++) { - for (int k=0;k(clipboard.at(k)); - if (comp->load_id == oc->linked.at(j)) { - pasted_clips.at(i)->linked.append(k); - } - } - } - } + for (int j=0;jlinked.size();j++) { + for (int k=0;k(clipboard.at(k)); + if (comp->load_id == oc->linked.at(j)) { + pasted_clips.at(i)->linked.append(k); + } + } + } + } - ca->append(new AddClipCommand(olive::ActiveSequence, pasted_clips)); + ca->append(new AddClipCommand(olive::ActiveSequence, pasted_clips)); - olive::UndoStack.push(ca); + olive::UndoStack.push(ca); - update_ui(true); + update_ui(true); - if (olive::CurrentConfig.paste_seeks) { - panel_sequence_viewer->seek(paste_end); - } - } else if (clipboard_type == CLIPBOARD_TYPE_EFFECT) { - ComboAction* ca = new ComboAction(); - bool push = false; + if (olive::CurrentConfig.paste_seeks) { + panel_sequence_viewer->seek(paste_end); + } + } else if (clipboard_type == CLIPBOARD_TYPE_EFFECT) { + ComboAction* ca = new ComboAction(); + bool push = false; - bool replace = false; - bool skip = false; - bool ask_conflict = true; + bool replace = false; + bool skip = false; + bool ask_conflict = true; - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr && is_clip_selected(c, true)) { - for (int j=0;j(clipboard.at(j)); - if ((c->track < 0) == (e->meta->subtype == EFFECT_TYPE_VIDEO)) { - int found = -1; - if (ask_conflict) { - replace = false; - skip = false; - } - for (int k=0;keffects.size();k++) { - if (c->effects.at(k)->meta == e->meta) { - found = k; - break; - } - } - if (found >= 0 && ask_conflict) { - QMessageBox box(this); - box.setWindowTitle(tr("Effect already exists")); - box.setText(tr("Clip '%1' already contains a '%2' effect. Would you like to replace it with the pasted one or add it as a separate effect?").arg(c->name, e->meta->name)); - box.setIcon(QMessageBox::Icon::Question); + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr && is_clip_selected(c, true)) { + for (int j=0;j(clipboard.at(j)); + if ((c->track < 0) == (e->meta->subtype == EFFECT_TYPE_VIDEO)) { + int found = -1; + if (ask_conflict) { + replace = false; + skip = false; + } + for (int k=0;keffects.size();k++) { + if (c->effects.at(k)->meta == e->meta) { + found = k; + break; + } + } + if (found >= 0 && ask_conflict) { + QMessageBox box(this); + box.setWindowTitle(tr("Effect already exists")); + box.setText(tr("Clip '%1' already contains a '%2' effect. Would you like to replace it with the pasted one or add it as a separate effect?").arg(c->name, e->meta->name)); + box.setIcon(QMessageBox::Icon::Question); - box.addButton(tr("Add"), QMessageBox::YesRole); - QPushButton* replace_button = box.addButton(tr("Replace"), QMessageBox::NoRole); - QPushButton* skip_button = box.addButton(tr("Skip"), QMessageBox::RejectRole); + box.addButton(tr("Add"), QMessageBox::YesRole); + QPushButton* replace_button = box.addButton(tr("Replace"), QMessageBox::NoRole); + QPushButton* skip_button = box.addButton(tr("Skip"), QMessageBox::RejectRole); - QCheckBox* future_box = new QCheckBox(tr("Do this for all conflicts found"), &box); - box.setCheckBox(future_box); + QCheckBox* future_box = new QCheckBox(tr("Do this for all conflicts found"), &box); + box.setCheckBox(future_box); - box.exec(); + box.exec(); - if (box.clickedButton() == replace_button) { - replace = true; - } else if (box.clickedButton() == skip_button) { - skip = true; - } - ask_conflict = !future_box->isChecked(); - } + if (box.clickedButton() == replace_button) { + replace = true; + } else if (box.clickedButton() == skip_button) { + skip = true; + } + ask_conflict = !future_box->isChecked(); + } - if (found >= 0 && skip) { - // do nothing - } else if (found >= 0 && replace) { - EffectDeleteCommand* delcom = new EffectDeleteCommand(); - delcom->clips.append(c); - delcom->fx.append(found); - ca->append(delcom); + if (found >= 0 && skip) { + // do nothing + } else if (found >= 0 && replace) { + EffectDeleteCommand* delcom = new EffectDeleteCommand(); + delcom->clips.append(c); + delcom->fx.append(found); + ca->append(delcom); - ca->append(new AddEffectCommand(c, e->copy(c), nullptr, found)); - push = true; - } else { - ca->append(new AddEffectCommand(c, e->copy(c), nullptr)); - push = true; - } - } - } - } - } - if (push) { - ca->appendPost(new ReloadEffectsCommand()); - olive::UndoStack.push(ca); - } else { - delete ca; - } - update_ui(true); - } - } + ca->append(new AddEffectCommand(c, e->copy(c), nullptr, found)); + push = true; + } else { + ca->append(new AddEffectCommand(c, e->copy(c), nullptr)); + push = true; + } + } + } + } + } + if (push) { + ca->appendPost(new ReloadEffectsCommand()); + olive::UndoStack.push(ca); + } else { + delete ca; + } + update_ui(true); + } + } } void Timeline::edit_to_point_internal(bool in, bool ripple) { - if (olive::ActiveSequence != nullptr) { - if (olive::ActiveSequence->clips.size() > 0) { - // get track count - int track_min = INT_MAX; - int track_max = INT_MIN; - long sequence_end = 0; + if (olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence->clips.size() > 0) { + // get track count + int track_min = INT_MAX; + int track_max = INT_MIN; + long sequence_end = 0; - bool playhead_falls_on_in = false; - bool playhead_falls_on_out = false; - long next_cut = LONG_MAX; - long prev_cut = 0; + bool playhead_falls_on_in = false; + bool playhead_falls_on_out = false; + long next_cut = LONG_MAX; + long prev_cut = 0; - // find closest in point to playhead - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr) { - track_min = qMin(track_min, c->track); - track_max = qMax(track_max, c->track); + // find closest in point to playhead + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr) { + track_min = qMin(track_min, c->track); + track_max = qMax(track_max, c->track); - sequence_end = qMax(c->timeline_out, sequence_end); + sequence_end = qMax(c->timeline_out, sequence_end); - if (c->timeline_in == olive::ActiveSequence->playhead) - playhead_falls_on_in = true; - if (c->timeline_out == olive::ActiveSequence->playhead) - playhead_falls_on_out = true; - if (c->timeline_in > olive::ActiveSequence->playhead) - next_cut = qMin(c->timeline_in, next_cut); - if (c->timeline_out > olive::ActiveSequence->playhead) - next_cut = qMin(c->timeline_out, next_cut); - if (c->timeline_in < olive::ActiveSequence->playhead) - prev_cut = qMax(c->timeline_in, prev_cut); - if (c->timeline_out < olive::ActiveSequence->playhead) - prev_cut = qMax(c->timeline_out, prev_cut); - } - } + if (c->timeline_in == olive::ActiveSequence->playhead) + playhead_falls_on_in = true; + if (c->timeline_out == olive::ActiveSequence->playhead) + playhead_falls_on_out = true; + if (c->timeline_in > olive::ActiveSequence->playhead) + next_cut = qMin(c->timeline_in, next_cut); + if (c->timeline_out > olive::ActiveSequence->playhead) + next_cut = qMin(c->timeline_out, next_cut); + if (c->timeline_in < olive::ActiveSequence->playhead) + prev_cut = qMax(c->timeline_in, prev_cut); + if (c->timeline_out < olive::ActiveSequence->playhead) + prev_cut = qMax(c->timeline_out, prev_cut); + } + } - next_cut = qMin(sequence_end, next_cut); + next_cut = qMin(sequence_end, next_cut); - QVector areas; - ComboAction* ca = new ComboAction(); - bool push_undo = true; - long seek = olive::ActiveSequence->playhead; + QVector areas; + ComboAction* ca = new ComboAction(); + bool push_undo = true; + long seek = olive::ActiveSequence->playhead; - if ((in && (playhead_falls_on_out || (playhead_falls_on_in && olive::ActiveSequence->playhead == 0))) - || (!in && (playhead_falls_on_in || (playhead_falls_on_out && olive::ActiveSequence->playhead == sequence_end)))) { // one frame mode - if (ripple) { - // set up deletion areas based on track count - long in_point = olive::ActiveSequence->playhead; - if (!in) { - in_point--; - seek--; - } + if ((in && (playhead_falls_on_out || (playhead_falls_on_in && olive::ActiveSequence->playhead == 0))) + || (!in && (playhead_falls_on_in || (playhead_falls_on_out && olive::ActiveSequence->playhead == sequence_end)))) { // one frame mode + if (ripple) { + // set up deletion areas based on track count + long in_point = olive::ActiveSequence->playhead; + if (!in) { + in_point--; + seek--; + } - if (in_point >= 0) { - Selection s; - s.in = in_point; - s.out = in_point + 1; - for (int i=track_min;i<=track_max;i++) { - s.track = i; - areas.append(s); - } + if (in_point >= 0) { + Selection s; + s.in = in_point; + s.out = in_point + 1; + for (int i=track_min;i<=track_max;i++) { + s.track = i; + areas.append(s); + } - // trim and move clips around the in point - delete_areas_and_relink(ca, areas, true); + // trim and move clips around the in point + delete_areas_and_relink(ca, areas, true); - if (ripple) ripple_clips(ca, olive::ActiveSequence, in_point, -1); - } else { - push_undo = false; - } - } else { - push_undo = false; - } - } else { - // set up deletion areas based on track count - Selection s; - if (in) seek = prev_cut; - s.in = in ? prev_cut : olive::ActiveSequence->playhead; - s.out = in ? olive::ActiveSequence->playhead : next_cut; + if (ripple) ripple_clips(ca, olive::ActiveSequence, in_point, -1); + } else { + push_undo = false; + } + } else { + push_undo = false; + } + } else { + // set up deletion areas based on track count + Selection s; + if (in) seek = prev_cut; + s.in = in ? prev_cut : olive::ActiveSequence->playhead; + s.out = in ? olive::ActiveSequence->playhead : next_cut; - if (s.in == s.out) { - push_undo = false; - } else { - for (int i=track_min;i<=track_max;i++) { - s.track = i; - areas.append(s); - } + if (s.in == s.out) { + push_undo = false; + } else { + for (int i=track_min;i<=track_max;i++) { + s.track = i; + areas.append(s); + } - // trim and move clips around the in point - delete_areas_and_relink(ca, areas, true); - if (ripple) ripple_clips(ca, olive::ActiveSequence, s.in, s.in - s.out); - } - } + // trim and move clips around the in point + delete_areas_and_relink(ca, areas, true); + if (ripple) ripple_clips(ca, olive::ActiveSequence, s.in, s.in - s.out); + } + } - if (push_undo) { - olive::UndoStack.push(ca); + if (push_undo) { + olive::UndoStack.push(ca); - update_ui(true); + update_ui(true); - if (seek != olive::ActiveSequence->playhead && ripple) panel_sequence_viewer->seek(seek); - } else { - delete ca; - } - } else { - panel_sequence_viewer->seek(0); - } - } + if (seek != olive::ActiveSequence->playhead && ripple) panel_sequence_viewer->seek(seek); + } else { + delete ca; + } + } else { + panel_sequence_viewer->seek(0); + } + } } bool Timeline::split_selection(ComboAction* ca) { - bool split = false; + bool split = false; - // temporary relinking vectors - QVector pre_splits; - QVector post_splits; - QVector secondary_post_splits; + // temporary relinking vectors + QVector pre_splits; + QVector post_splits; + QVector secondary_post_splits; - // find clips within selection and split - for (int j=0;jclips.size();j++) { - ClipPtr clip = olive::ActiveSequence->clips.at(j); - if (clip != nullptr) { - for (int i=0;iselections.size();i++) { - const Selection& s = olive::ActiveSequence->selections.at(i); - if (s.track == clip->track) { - ClipPtr post_b = split_clip(ca, true, j, s.out); - ClipPtr post_a = split_clip(ca, post_b == nullptr, j, s.in); - pre_splits.append(j); - post_splits.append(post_a); - secondary_post_splits.append(post_b); + // find clips within selection and split + for (int j=0;jclips.size();j++) { + ClipPtr clip = olive::ActiveSequence->clips.at(j); + if (clip != nullptr) { + for (int i=0;iselections.size();i++) { + const Selection& s = olive::ActiveSequence->selections.at(i); + if (s.track == clip->track) { + ClipPtr post_b = split_clip(ca, true, j, s.out); + ClipPtr post_a = split_clip(ca, post_b == nullptr, j, s.in); + pre_splits.append(j); + post_splits.append(post_a); + secondary_post_splits.append(post_b); - if (post_a != nullptr) { - post_a->timeline_out = qMin(post_a->timeline_out, s.out); - } + if (post_a != nullptr) { + post_a->timeline_out = qMin(post_a->timeline_out, s.out); + } - split = true; - } - } - } - } + split = true; + } + } + } + } - if (split) { - // relink after splitting - relink_clips_using_ids(pre_splits, post_splits); - relink_clips_using_ids(pre_splits, secondary_post_splits); + if (split) { + // relink after splitting + relink_clips_using_ids(pre_splits, post_splits); + relink_clips_using_ids(pre_splits, secondary_post_splits); - ca->append(new AddClipCommand(olive::ActiveSequence, post_splits)); - ca->append(new AddClipCommand(olive::ActiveSequence, secondary_post_splits)); + ca->append(new AddClipCommand(olive::ActiveSequence, post_splits)); + ca->append(new AddClipCommand(olive::ActiveSequence, secondary_post_splits)); - return true; - } - return false; + return true; + } + return false; } bool Timeline::split_all_clips_at_point(ComboAction* ca, long point) { - bool split = false; - for (int j=0;jclips.size();j++) { - ClipPtr c = olive::ActiveSequence->clips.at(j); - if (c != nullptr) { - // always relinks - if (split_clip_and_relink(ca, j, point, true)) { - split = true; - } - } - } - return split; + bool split = false; + for (int j=0;jclips.size();j++) { + ClipPtr c = olive::ActiveSequence->clips.at(j); + if (c != nullptr) { + // always relinks + if (split_clip_and_relink(ca, j, point, true)) { + split = true; + } + } + } + return split; } void Timeline::split_at_playhead() { - ComboAction* ca = new ComboAction(); - bool split_selected = false; - split_cache.clear(); + ComboAction* ca = new ComboAction(); + bool split_selected = false; + split_cache.clear(); - if (olive::ActiveSequence->selections.size() > 0) { - // see if whole clips are selected - QVector pre_clips; - QVector post_clips; - for (int j=0;jclips.size();j++) { - ClipPtr clip = olive::ActiveSequence->clips.at(j); - if (clip != nullptr && is_clip_selected(clip, true)) { - ClipPtr s = split_clip(ca, true, j, olive::ActiveSequence->playhead); - if (s != nullptr) { - pre_clips.append(j); - post_clips.append(s); - split_selected = true; - } - } - } - - if (split_selected) { - // relink clips if we split - relink_clips_using_ids(pre_clips, post_clips); - ca->append(new AddClipCommand(olive::ActiveSequence, post_clips)); - } else { - // split a selection if not - split_selected = split_selection(ca); - } - } - - // if nothing was selected or no selections fell within playhead, simply split at playhead - if (!split_selected) { - split_selected = split_all_clips_at_point(ca, olive::ActiveSequence->playhead); - } - - if (split_selected) { - olive::UndoStack.push(ca); - update_ui(true); - } else { - delete ca; + if (olive::ActiveSequence->selections.size() > 0) { + // see if whole clips are selected + QVector pre_clips; + QVector post_clips; + for (int j=0;jclips.size();j++) { + ClipPtr clip = olive::ActiveSequence->clips.at(j); + if (clip != nullptr && is_clip_selected(clip, true)) { + ClipPtr s = split_clip(ca, true, j, olive::ActiveSequence->playhead); + if (s != nullptr) { + pre_clips.append(j); + post_clips.append(s); + split_selected = true; + } + } } + + if (split_selected) { + // relink clips if we split + relink_clips_using_ids(pre_clips, post_clips); + ca->append(new AddClipCommand(olive::ActiveSequence, post_clips)); + } else { + // split a selection if not + split_selected = split_selection(ca); + } + } + + // if nothing was selected or no selections fell within playhead, simply split at playhead + if (!split_selected) { + split_selected = split_all_clips_at_point(ca, olive::ActiveSequence->playhead); + } + + if (split_selected) { + olive::UndoStack.push(ca); + update_ui(true); + } else { + delete ca; + } } void Timeline::ripple_delete() { - if (olive::ActiveSequence != nullptr) { - if (olive::ActiveSequence->selections.size() > 0) { - panel_timeline->delete_selection(olive::ActiveSequence->selections, true); - } else if (olive::CurrentConfig.hover_focus && get_focused_panel() == panel_timeline) { - if (panel_timeline->can_ripple_empty_space(panel_timeline->cursor_frame, panel_timeline->cursor_track)) { - panel_timeline->ripple_delete_empty_space(); - } - } + if (olive::ActiveSequence != nullptr) { + if (olive::ActiveSequence->selections.size() > 0) { + panel_timeline->delete_selection(olive::ActiveSequence->selections, true); + } else if (olive::CurrentConfig.hover_focus && get_focused_panel() == panel_timeline) { + if (panel_timeline->can_ripple_empty_space(panel_timeline->cursor_frame, panel_timeline->cursor_track)) { + panel_timeline->ripple_delete_empty_space(); + } } + } } void Timeline::deselect_area(long in, long out, int track) { - int len = olive::ActiveSequence->selections.size(); - for (int i=0;iselections[i]; - if (s.track == track) { - if (s.in >= in && s.out <= out) { - // whole selection is in deselect area - olive::ActiveSequence->selections.removeAt(i); - i--; - len--; - } else if (s.in < in && s.out > out) { - // middle of selection is in deselect area - Selection new_sel; - new_sel.in = out; - new_sel.out = s.out; - new_sel.track = s.track; - olive::ActiveSequence->selections.append(new_sel); + int len = olive::ActiveSequence->selections.size(); + for (int i=0;iselections[i]; + if (s.track == track) { + if (s.in >= in && s.out <= out) { + // whole selection is in deselect area + olive::ActiveSequence->selections.removeAt(i); + i--; + len--; + } else if (s.in < in && s.out > out) { + // middle of selection is in deselect area + Selection new_sel; + new_sel.in = out; + new_sel.out = s.out; + new_sel.track = s.track; + olive::ActiveSequence->selections.append(new_sel); - s.out = in; - } else if (s.in < in && s.out > in) { - // only out point is in deselect area - s.out = in; - } else if (s.in < out && s.out > out) { - // only in point is in deselect area - s.in = out; - } - } - } + s.out = in; + } else if (s.in < in && s.out > in) { + // only out point is in deselect area + s.out = in; + } else if (s.in < out && s.out > out) { + // only in point is in deselect area + s.in = out; + } + } + } } bool Timeline::snap_to_point(long point, long* l) { - int limit = get_snap_range(); - if (*l > point-limit-1 && *l < point+limit+1) { - snap_point = point; - *l = point; - snapped = true; - return true; - } - return false; + int limit = get_snap_range(); + if (*l > point-limit-1 && *l < point+limit+1) { + snap_point = point; + *l = point; + snapped = true; + return true; + } + return false; } bool Timeline::snap_to_timeline(long* l, bool use_playhead, bool use_markers, bool use_workarea) { - snapped = false; - if (snapping) { - if (use_playhead && !panel_sequence_viewer->playing) { - // snap to playhead - if (snap_to_point(olive::ActiveSequence->playhead, l)) return true; - } + snapped = false; + if (snapping) { + if (use_playhead && !panel_sequence_viewer->playing) { + // snap to playhead + if (snap_to_point(olive::ActiveSequence->playhead, l)) return true; + } - // snap to marker - if (use_markers) { - for (int i=0;imarkers.size();i++) { - if (snap_to_point(olive::ActiveSequence->markers.at(i).frame, l)) return true; - } - } + // snap to marker + if (use_markers) { + for (int i=0;imarkers.size();i++) { + if (snap_to_point(olive::ActiveSequence->markers.at(i).frame, l)) return true; + } + } - // snap to in/out - if (use_workarea && olive::ActiveSequence->using_workarea) { - if (snap_to_point(olive::ActiveSequence->workarea_in, l)) return true; - if (snap_to_point(olive::ActiveSequence->workarea_out, l)) return true; - } + // snap to in/out + if (use_workarea && olive::ActiveSequence->using_workarea) { + if (snap_to_point(olive::ActiveSequence->workarea_in, l)) return true; + if (snap_to_point(olive::ActiveSequence->workarea_out, l)) return true; + } - // snap to clip/transition - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr) { - if (snap_to_point(c->timeline_in, l)) { - return true; - } else if (snap_to_point(c->timeline_out, l)) { - return true; - } else if (c->get_opening_transition() != nullptr - && snap_to_point(c->timeline_in + c->get_opening_transition()->get_true_length(), l)) { - return true; - } else if (c->get_closing_transition() != nullptr - && snap_to_point(c->timeline_out - c->get_closing_transition()->get_true_length(), l)) { - return true; - } else { - // try to snap to clip markers - for (int j=0;jget_markers().size();j++) { - if (snap_to_point(c->get_markers().at(j).frame + c->timeline_in - c->clip_in, l)) { - return true; - } - } - } - } - } - } - return false; + // snap to clip/transition + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr) { + if (snap_to_point(c->timeline_in, l)) { + return true; + } else if (snap_to_point(c->timeline_out, l)) { + return true; + } else if (c->get_opening_transition() != nullptr + && snap_to_point(c->timeline_in + c->get_opening_transition()->get_true_length(), l)) { + return true; + } else if (c->get_closing_transition() != nullptr + && snap_to_point(c->timeline_out - c->get_closing_transition()->get_true_length(), l)) { + return true; + } else { + // try to snap to clip markers + for (int j=0;jget_markers().size();j++) { + if (snap_to_point(c->get_markers().at(j).frame + c->timeline_in - c->clip_in, l)) { + return true; + } + } + } + } + } + } + return false; } void Timeline::set_marker() { - // determine if any clips are selected, and if so add markers to clips rather than the sequence - QVector clips_selected; - bool clip_mode = false; + // determine if any clips are selected, and if so add markers to clips rather than the sequence + QVector clips_selected; + bool clip_mode = false; - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr - && is_clip_selected(c, true)) { + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr + && is_clip_selected(c, true)) { - // only add markers if the playhead is inside the clip - if (olive::ActiveSequence->playhead >= c->timeline_in - && olive::ActiveSequence->playhead <= c->timeline_out) { - clips_selected.append(i); - } + // only add markers if the playhead is inside the clip + if (olive::ActiveSequence->playhead >= c->timeline_in + && olive::ActiveSequence->playhead <= c->timeline_out) { + clips_selected.append(i); + } - // we are definitely adding markers to clips though - clip_mode = true; + // we are definitely adding markers to clips though + clip_mode = true; - } - } + } + } - // if we've selected clips but none of the clips are within the playhead, - // nothing to do here - if (clip_mode && clips_selected.size() == 0) { - return; - } + // if we've selected clips but none of the clips are within the playhead, + // nothing to do here + if (clip_mode && clips_selected.size() == 0) { + return; + } - // pass off to internal set marker function - set_marker_internal(olive::ActiveSequence, clips_selected); + // pass off to internal set marker function + set_marker_internal(olive::ActiveSequence, clips_selected); } void Timeline::delete_inout() { - panel_timeline->delete_in_out_internal(false); + panel_timeline->delete_in_out_internal(false); } void Timeline::ripple_delete_inout() { - panel_timeline->delete_in_out_internal(true); + panel_timeline->delete_in_out_internal(true); } void Timeline::ripple_to_in_point() { - panel_timeline->edit_to_point_internal(true, true); + panel_timeline->edit_to_point_internal(true, true); } void Timeline::ripple_to_out_point() { - panel_timeline->edit_to_point_internal(false, true); + panel_timeline->edit_to_point_internal(false, true); } void Timeline::edit_to_in_point() { - panel_timeline->edit_to_point_internal(true, false); + panel_timeline->edit_to_point_internal(true, false); } void Timeline::edit_to_out_point() { - panel_timeline->edit_to_point_internal(false, false); + panel_timeline->edit_to_point_internal(false, false); } void Timeline::toggle_links() { - LinkCommand* command = new LinkCommand(); - command->s = olive::ActiveSequence; - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr && is_clip_selected(c, true)) { - if (!command->clips.contains(i)) command->clips.append(i); + LinkCommand* command = new LinkCommand(); + command->s = olive::ActiveSequence; + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr && is_clip_selected(c, true)) { + if (!command->clips.contains(i)) command->clips.append(i); - if (c->linked.size() > 0) { - command->link = false; // prioritize unlinking + if (c->linked.size() > 0) { + command->link = false; // prioritize unlinking - for (int j=0;jlinked.size();j++) { // add links to the command - if (!command->clips.contains(c->linked.at(j))) command->clips.append(c->linked.at(j)); - } - } - } - } - if (command->clips.size() > 0) { - olive::UndoStack.push(command); - repaint_timeline(); - } else { - delete command; - } + for (int j=0;jlinked.size();j++) { // add links to the command + if (!command->clips.contains(c->linked.at(j))) command->clips.append(c->linked.at(j)); + } + } + } + } + if (command->clips.size() > 0) { + olive::UndoStack.push(command); + repaint_timeline(); + } else { + delete command; + } } void Timeline::increase_track_height() { - for (int i=0;iselections.clear(); - repaint_timeline(); + olive::ActiveSequence->selections.clear(); + repaint_timeline(); } long getFrameFromScreenPoint(double zoom, int x) { - long f = qCeil(double(x) / zoom); - if (f < 0) { - return 0; - } - return f; + long f = qCeil(double(x) / zoom); + if (f < 0) { + return 0; + } + return f; } int getScreenPointFromFrame(double zoom, long frame) { - return qFloor(double(frame)*zoom); + return qFloor(double(frame)*zoom); } long Timeline::getTimelineFrameFromScreenPoint(int x) { - return getFrameFromScreenPoint(zoom, x + scroll); + return getFrameFromScreenPoint(zoom, x + scroll); } int Timeline::getTimelineScreenPointFromFrame(long frame) { - return getScreenPointFromFrame(zoom, frame) - scroll; + return getScreenPointFromFrame(zoom, frame) - scroll; } void Timeline::add_btn_click() { - QMenu add_menu(this); + QMenu add_menu(this); - QAction* titleMenuItem = new QAction(&add_menu); - titleMenuItem->setText(tr("Title...")); - titleMenuItem->setData(ADD_OBJ_TITLE); - add_menu.addAction(titleMenuItem); + QAction* titleMenuItem = new QAction(&add_menu); + titleMenuItem->setText(tr("Title...")); + titleMenuItem->setData(ADD_OBJ_TITLE); + add_menu.addAction(titleMenuItem); - QAction* solidMenuItem = new QAction(&add_menu); - solidMenuItem->setText(tr("Solid Color...")); - solidMenuItem->setData(ADD_OBJ_SOLID); - add_menu.addAction(solidMenuItem); + QAction* solidMenuItem = new QAction(&add_menu); + solidMenuItem->setText(tr("Solid Color...")); + solidMenuItem->setData(ADD_OBJ_SOLID); + add_menu.addAction(solidMenuItem); - QAction* barsMenuItem = new QAction(&add_menu); - barsMenuItem->setText(tr("Bars...")); - barsMenuItem->setData(ADD_OBJ_BARS); - add_menu.addAction(barsMenuItem); + QAction* barsMenuItem = new QAction(&add_menu); + barsMenuItem->setText(tr("Bars...")); + barsMenuItem->setData(ADD_OBJ_BARS); + add_menu.addAction(barsMenuItem); - add_menu.addSeparator(); + add_menu.addSeparator(); - QAction* toneMenuItem = new QAction(&add_menu); - toneMenuItem->setText(tr("Tone...")); - toneMenuItem->setData(ADD_OBJ_TONE); - add_menu.addAction(toneMenuItem); + QAction* toneMenuItem = new QAction(&add_menu); + toneMenuItem->setText(tr("Tone...")); + toneMenuItem->setData(ADD_OBJ_TONE); + add_menu.addAction(toneMenuItem); - QAction* noiseMenuItem = new QAction(&add_menu); - noiseMenuItem->setText(tr("Noise...")); - noiseMenuItem->setData(ADD_OBJ_NOISE); - add_menu.addAction(noiseMenuItem); + QAction* noiseMenuItem = new QAction(&add_menu); + noiseMenuItem->setText(tr("Noise...")); + noiseMenuItem->setData(ADD_OBJ_NOISE); + add_menu.addAction(noiseMenuItem); - connect(&add_menu, SIGNAL(triggered(QAction*)), this, SLOT(add_menu_item(QAction*))); + connect(&add_menu, SIGNAL(triggered(QAction*)), this, SLOT(add_menu_item(QAction*))); - add_menu.exec(QCursor::pos()); + add_menu.exec(QCursor::pos()); } void Timeline::add_menu_item(QAction* action) { - creating = true; - creating_object = action->data().toInt(); + creating = true; + creating_object = action->data().toInt(); } void Timeline::setScroll(int s) { - scroll = s; - headers->set_scroll(s); - repaint_timeline(); + scroll = s; + headers->set_scroll(s); + repaint_timeline(); } void Timeline::record_btn_click() { - if (olive::ActiveProjectFilename.isEmpty()) { - QMessageBox::critical(this, - tr("Unsaved Project"), - tr("You must save this project before you can record audio in it."), - QMessageBox::Ok); - } else { - creating = true; - creating_object = ADD_OBJ_AUDIO; - olive::MainWindow->statusBar()->showMessage( - tr("Click on the timeline where you want to start recording (drag to limit the recording to a certain timeframe)"), - 10000); - } + if (olive::ActiveProjectFilename.isEmpty()) { + QMessageBox::critical(this, + tr("Unsaved Project"), + tr("You must save this project before you can record audio in it."), + QMessageBox::Ok); + } else { + creating = true; + creating_object = ADD_OBJ_AUDIO; + olive::MainWindow->statusBar()->showMessage( + tr("Click on the timeline where you want to start recording (drag to limit the recording to a certain timeframe)"), + 10000); + } } void Timeline::transition_tool_click() { - creating = false; + creating = false; - QMenu transition_menu(this); + QMenu transition_menu(this); - for (int i=0;isetObjectName("v"); - a->setData(reinterpret_cast(&em)); - } - } + for (int i=0;isetObjectName("v"); + a->setData(reinterpret_cast(&em)); + } + } - transition_menu.addSeparator(); + transition_menu.addSeparator(); - for (int i=0;isetObjectName("a"); - a->setData(reinterpret_cast(&em)); - } - } + for (int i=0;isetObjectName("a"); + a->setData(reinterpret_cast(&em)); + } + } - connect(&transition_menu, SIGNAL(triggered(QAction*)), this, SLOT(transition_menu_select(QAction*))); + connect(&transition_menu, SIGNAL(triggered(QAction*)), this, SLOT(transition_menu_select(QAction*))); - toolTransitionButton->setChecked(false); + toolTransitionButton->setChecked(false); - transition_menu.exec(QCursor::pos()); + transition_menu.exec(QCursor::pos()); } void Timeline::transition_menu_select(QAction* a) { - transition_tool_meta = reinterpret_cast(a->data().value()); + transition_tool_meta = reinterpret_cast(a->data().value()); - if (a->objectName() == "v") { - transition_tool_side = -1; - } else { - transition_tool_side = 1; - } + if (a->objectName() == "v") { + transition_tool_side = -1; + } else { + transition_tool_side = 1; + } - decheck_tool_buttons(sender()); - timeline_area->setCursor(Qt::CrossCursor); - tool = TIMELINE_TOOL_TRANSITION; - toolTransitionButton->setChecked(true); + decheck_tool_buttons(sender()); + timeline_area->setCursor(Qt::CrossCursor); + tool = TIMELINE_TOOL_TRANSITION; + toolTransitionButton->setChecked(true); } void Timeline::resize_move(double z) { - set_zoom_value(zoom * z); + set_zoom_value(zoom * z); } void Timeline::set_sb_max() { - headers->set_scrollbar_max(horizontalScrollBar, olive::ActiveSequence->getEndFrame(), editAreas->width() - getScreenPointFromFrame(zoom, 200)); + headers->set_scrollbar_max(horizontalScrollBar, olive::ActiveSequence->getEndFrame(), editAreas->width() - getScreenPointFromFrame(zoom, 200)); +} + +void Timeline::UpdateTitle() { + QString title = tr("Timeline: "); + if (olive::ActiveSequence == nullptr) { + setWindowTitle(title + tr("")); + } else { + setWindowTitle(title + olive::ActiveSequence->name); + update_ui(false); + } } void Timeline::setup_ui() { - QWidget* dockWidgetContents = new QWidget(); + QWidget* dockWidgetContents = new QWidget(); - QHBoxLayout* horizontalLayout = new QHBoxLayout(dockWidgetContents); - horizontalLayout->setSpacing(0); - horizontalLayout->setMargin(0); + QHBoxLayout* horizontalLayout = new QHBoxLayout(dockWidgetContents); + horizontalLayout->setSpacing(0); + horizontalLayout->setMargin(0); - setWidget(dockWidgetContents); + setWidget(dockWidgetContents); - tool_button_widget = new QWidget(); - tool_button_widget->setObjectName("timeline_toolbar"); - tool_button_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + tool_button_widget = new QWidget(); + tool_button_widget->setObjectName("timeline_toolbar"); + tool_button_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - FlowLayout* tool_buttons_layout = new FlowLayout(tool_button_widget); - tool_buttons_layout->setSpacing(4); - tool_buttons_layout->setMargin(0); + FlowLayout* tool_buttons_layout = new FlowLayout(tool_button_widget); + tool_buttons_layout->setSpacing(4); + tool_buttons_layout->setMargin(0); - toolArrowButton = new QPushButton(); - QIcon arrow_icon; - arrow_icon.addFile(QStringLiteral(":/icons/arrow.png"), QSize(), QIcon::Normal, QIcon::Off); - arrow_icon.addFile(QStringLiteral(":/icons/arrow-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); - toolArrowButton->setIcon(arrow_icon); - toolArrowButton->setCheckable(true); - toolArrowButton->setToolTip(tr("Pointer Tool") + " (V)"); - toolArrowButton->setProperty("tool", TIMELINE_TOOL_POINTER); - connect(toolArrowButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); - tool_buttons_layout->addWidget(toolArrowButton); + toolArrowButton = new QPushButton(); + QIcon arrow_icon; + arrow_icon.addFile(QStringLiteral(":/icons/arrow.png"), QSize(), QIcon::Normal, QIcon::Off); + arrow_icon.addFile(QStringLiteral(":/icons/arrow-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + toolArrowButton->setIcon(arrow_icon); + toolArrowButton->setCheckable(true); + toolArrowButton->setProperty("tool", TIMELINE_TOOL_POINTER); + connect(toolArrowButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); + tool_buttons_layout->addWidget(toolArrowButton); - toolEditButton = new QPushButton(); - QIcon icon1; - icon1.addFile(QStringLiteral(":/icons/beam.png"), QSize(), QIcon::Normal, QIcon::Off); - icon1.addFile(QStringLiteral(":/icons/beam-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); - toolEditButton->setIcon(icon1); - toolEditButton->setCheckable(true); - toolEditButton->setToolTip(tr("Edit Tool") + " (X)"); - toolEditButton->setProperty("tool", TIMELINE_TOOL_EDIT); - connect(toolEditButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); - tool_buttons_layout->addWidget(toolEditButton); + toolEditButton = new QPushButton(); + QIcon icon1; + icon1.addFile(QStringLiteral(":/icons/beam.png"), QSize(), QIcon::Normal, QIcon::Off); + icon1.addFile(QStringLiteral(":/icons/beam-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + toolEditButton->setIcon(icon1); + toolEditButton->setCheckable(true); + toolEditButton->setProperty("tool", TIMELINE_TOOL_EDIT); + connect(toolEditButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); + tool_buttons_layout->addWidget(toolEditButton); - toolRippleButton = new QPushButton(); - QIcon icon2; - icon2.addFile(QStringLiteral(":/icons/ripple.png"), QSize(), QIcon::Normal, QIcon::Off); - icon2.addFile(QStringLiteral(":/icons/ripple-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); - toolRippleButton->setIcon(icon2); - toolRippleButton->setCheckable(true); - toolRippleButton->setToolTip(tr("Ripple Tool") + " (B)"); - toolRippleButton->setProperty("tool", TIMELINE_TOOL_RIPPLE); - connect(toolRippleButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); - tool_buttons_layout->addWidget(toolRippleButton); + toolRippleButton = new QPushButton(); + QIcon icon2; + icon2.addFile(QStringLiteral(":/icons/ripple.png"), QSize(), QIcon::Normal, QIcon::Off); + icon2.addFile(QStringLiteral(":/icons/ripple-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + toolRippleButton->setIcon(icon2); + toolRippleButton->setCheckable(true); + toolRippleButton->setProperty("tool", TIMELINE_TOOL_RIPPLE); + connect(toolRippleButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); + tool_buttons_layout->addWidget(toolRippleButton); - toolRazorButton = new QPushButton(); - QIcon icon4; - icon4.addFile(QStringLiteral(":/icons/razor.png"), QSize(), QIcon::Normal, QIcon::Off); - icon4.addFile(QStringLiteral(":/icons/razor-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); - toolRazorButton->setIcon(icon4); - toolRazorButton->setCheckable(true); - toolRazorButton->setToolTip(tr("Razor Tool") + " (C)"); - toolRazorButton->setProperty("tool", TIMELINE_TOOL_RAZOR); - connect(toolRazorButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); - tool_buttons_layout->addWidget(toolRazorButton); + toolRazorButton = new QPushButton(); + QIcon icon4; + icon4.addFile(QStringLiteral(":/icons/razor.png"), QSize(), QIcon::Normal, QIcon::Off); + icon4.addFile(QStringLiteral(":/icons/razor-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + toolRazorButton->setIcon(icon4); + toolRazorButton->setCheckable(true); + toolRazorButton->setProperty("tool", TIMELINE_TOOL_RAZOR); + connect(toolRazorButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); + tool_buttons_layout->addWidget(toolRazorButton); - toolSlipButton = new QPushButton(); - QIcon icon5; - icon5.addFile(QStringLiteral(":/icons/slip.png"), QSize(), QIcon::Normal, QIcon::On); - icon5.addFile(QStringLiteral(":/icons/slip-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); - toolSlipButton->setIcon(icon5); - toolSlipButton->setCheckable(true); - toolSlipButton->setToolTip(tr("Slip Tool") + " (Y)"); - toolSlipButton->setProperty("tool", TIMELINE_TOOL_SLIP); - connect(toolSlipButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); - tool_buttons_layout->addWidget(toolSlipButton); + toolSlipButton = new QPushButton(); + QIcon icon5; + icon5.addFile(QStringLiteral(":/icons/slip.png"), QSize(), QIcon::Normal, QIcon::On); + icon5.addFile(QStringLiteral(":/icons/slip-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolSlipButton->setIcon(icon5); + toolSlipButton->setCheckable(true); + toolSlipButton->setProperty("tool", TIMELINE_TOOL_SLIP); + connect(toolSlipButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); + tool_buttons_layout->addWidget(toolSlipButton); - toolSlideButton = new QPushButton(); - QIcon icon6; - icon6.addFile(QStringLiteral(":/icons/slide.png"), QSize(), QIcon::Normal, QIcon::On); - icon6.addFile(QStringLiteral(":/icons/slide-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); - toolSlideButton->setIcon(icon6); - toolSlideButton->setCheckable(true); - toolSlideButton->setToolTip(tr("Slide Tool") + " (U)"); - toolSlideButton->setProperty("tool", TIMELINE_TOOL_SLIDE); - connect(toolSlideButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); - tool_buttons_layout->addWidget(toolSlideButton); + toolSlideButton = new QPushButton(); + QIcon icon6; + icon6.addFile(QStringLiteral(":/icons/slide.png"), QSize(), QIcon::Normal, QIcon::On); + icon6.addFile(QStringLiteral(":/icons/slide-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolSlideButton->setIcon(icon6); + toolSlideButton->setCheckable(true); + toolSlideButton->setProperty("tool", TIMELINE_TOOL_SLIDE); + connect(toolSlideButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); + tool_buttons_layout->addWidget(toolSlideButton); - toolHandButton = new QPushButton(); - QIcon icon7; - icon7.addFile(QStringLiteral(":/icons/hand.png"), QSize(), QIcon::Normal, QIcon::On); - icon7.addFile(QStringLiteral(":/icons/hand-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); - toolHandButton->setIcon(icon7); - toolHandButton->setCheckable(true); - toolHandButton->setToolTip(tr("Hand Tool") + " (H)"); - toolHandButton->setProperty("tool", TIMELINE_TOOL_HAND); - connect(toolHandButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); - tool_buttons_layout->addWidget(toolHandButton); + toolHandButton = new QPushButton(); + QIcon icon7; + icon7.addFile(QStringLiteral(":/icons/hand.png"), QSize(), QIcon::Normal, QIcon::On); + icon7.addFile(QStringLiteral(":/icons/hand-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolHandButton->setIcon(icon7); + toolHandButton->setCheckable(true); - toolTransitionButton = new QPushButton(); - QIcon icon8; - icon8.addFile(QStringLiteral(":/icons/transition-tool.png"), QSize(), QIcon::Normal, QIcon::On); - icon8.addFile(QStringLiteral(":/icons/transition-tool-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); - toolTransitionButton->setIcon(icon8); - toolTransitionButton->setCheckable(true); - toolTransitionButton->setToolTip(tr("Transition Tool") + " (T)"); - connect(toolTransitionButton, SIGNAL(clicked(bool)), this, SLOT(transition_tool_click())); - tool_buttons_layout->addWidget(toolTransitionButton); + toolHandButton->setProperty("tool", TIMELINE_TOOL_HAND); + connect(toolHandButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); + tool_buttons_layout->addWidget(toolHandButton); + toolTransitionButton = new QPushButton(); + QIcon icon8; + icon8.addFile(QStringLiteral(":/icons/transition-tool.png"), QSize(), QIcon::Normal, QIcon::On); + icon8.addFile(QStringLiteral(":/icons/transition-tool-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolTransitionButton->setIcon(icon8); + toolTransitionButton->setCheckable(true); + connect(toolTransitionButton, SIGNAL(clicked(bool)), this, SLOT(transition_tool_click())); + tool_buttons_layout->addWidget(toolTransitionButton); - snappingButton = new QPushButton(); - QIcon icon9; - icon9.addFile(QStringLiteral(":/icons/magnet.png"), QSize(), QIcon::Normal, QIcon::On); - icon9.addFile(QStringLiteral(":/icons/magnet-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); - snappingButton->setIcon(icon9); - snappingButton->setCheckable(true); - snappingButton->setChecked(true); - snappingButton->setToolTip(tr("Snapping") + " (S)"); - connect(snappingButton, SIGNAL(toggled(bool)), this, SLOT(snapping_clicked(bool))); - tool_buttons_layout->addWidget(snappingButton); + snappingButton = new QPushButton(); + QIcon icon9; + icon9.addFile(QStringLiteral(":/icons/magnet.png"), QSize(), QIcon::Normal, QIcon::On); + icon9.addFile(QStringLiteral(":/icons/magnet-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + snappingButton->setIcon(icon9); + snappingButton->setCheckable(true); + snappingButton->setChecked(true); + connect(snappingButton, SIGNAL(toggled(bool)), this, SLOT(snapping_clicked(bool))); + tool_buttons_layout->addWidget(snappingButton); - zoomInButton = new QPushButton(); - QIcon icon10; - icon10.addFile(QStringLiteral(":/icons/zoomin.png"), QSize(), QIcon::Normal, QIcon::On); - icon10.addFile(QStringLiteral(":/icons/zoomin-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); - zoomInButton->setIcon(icon10); - zoomInButton->setToolTip(tr("Zoom In") + " (=)"); - connect(zoomInButton, SIGNAL(clicked(bool)), this, SLOT(zoom_in())); - tool_buttons_layout->addWidget(zoomInButton); + zoomInButton = new QPushButton(); + QIcon icon10; + icon10.addFile(QStringLiteral(":/icons/zoomin.png"), QSize(), QIcon::Normal, QIcon::On); + icon10.addFile(QStringLiteral(":/icons/zoomin-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + zoomInButton->setIcon(icon10); + connect(zoomInButton, SIGNAL(clicked(bool)), this, SLOT(zoom_in())); + tool_buttons_layout->addWidget(zoomInButton); - zoomOutButton = new QPushButton(); - QIcon icon11; - icon11.addFile(QStringLiteral(":/icons/zoomout.png"), QSize(), QIcon::Normal, QIcon::On); - icon11.addFile(QStringLiteral(":/icons/zoomout-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); - zoomOutButton->setIcon(icon11); - zoomOutButton->setToolTip(tr("Zoom Out") + " (-)"); - connect(zoomOutButton, SIGNAL(clicked(bool)), this, SLOT(zoom_out())); - tool_buttons_layout->addWidget(zoomOutButton); + zoomOutButton = new QPushButton(); + QIcon icon11; + icon11.addFile(QStringLiteral(":/icons/zoomout.png"), QSize(), QIcon::Normal, QIcon::On); + icon11.addFile(QStringLiteral(":/icons/zoomout-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + zoomOutButton->setIcon(icon11); + connect(zoomOutButton, SIGNAL(clicked(bool)), this, SLOT(zoom_out())); + tool_buttons_layout->addWidget(zoomOutButton); - recordButton = new QPushButton(); - QIcon icon12; - icon12.addFile(QStringLiteral(":/icons/record.png"), QSize(), QIcon::Normal, QIcon::On); - icon12.addFile(QStringLiteral(":/icons/record-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); - recordButton->setIcon(icon12); - recordButton->setToolTip(tr("Record audio")); - connect(recordButton, SIGNAL(clicked(bool)), this, SLOT(record_btn_click())); - tool_buttons_layout->addWidget(recordButton); + recordButton = new QPushButton(); + QIcon icon12; + icon12.addFile(QStringLiteral(":/icons/record.png"), QSize(), QIcon::Normal, QIcon::On); + icon12.addFile(QStringLiteral(":/icons/record-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + recordButton->setIcon(icon12); + connect(recordButton, SIGNAL(clicked(bool)), this, SLOT(record_btn_click())); + tool_buttons_layout->addWidget(recordButton); - addButton = new QPushButton(); - QIcon icon13; - icon13.addFile(QStringLiteral(":/icons/add-button.png"), QSize(), QIcon::Normal, QIcon::On); - icon13.addFile(QStringLiteral(":/icons/add-button-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); - addButton->setIcon(icon13); - addButton->setToolTip(tr("Add title, solid, bars, etc.")); - connect(addButton, SIGNAL(clicked()), this, SLOT(add_btn_click())); - tool_buttons_layout->addWidget(addButton); + addButton = new QPushButton(); + QIcon icon13; + icon13.addFile(QStringLiteral(":/icons/add-button.png"), QSize(), QIcon::Normal, QIcon::On); + icon13.addFile(QStringLiteral(":/icons/add-button-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + addButton->setIcon(icon13); + connect(addButton, SIGNAL(clicked()), this, SLOT(add_btn_click())); + tool_buttons_layout->addWidget(addButton); - horizontalLayout->addWidget(tool_button_widget); + horizontalLayout->addWidget(tool_button_widget); - timeline_area = new QWidget(); - QSizePolicy timeline_area_policy(QSizePolicy::Minimum, QSizePolicy::Minimum); - timeline_area_policy.setHorizontalStretch(1); - timeline_area_policy.setVerticalStretch(0); - timeline_area_policy.setHeightForWidth(timeline_area->sizePolicy().hasHeightForWidth()); - timeline_area->setSizePolicy(timeline_area_policy); + timeline_area = new QWidget(); + QSizePolicy timeline_area_policy(QSizePolicy::Minimum, QSizePolicy::Minimum); + timeline_area_policy.setHorizontalStretch(1); + timeline_area_policy.setVerticalStretch(0); + timeline_area_policy.setHeightForWidth(timeline_area->sizePolicy().hasHeightForWidth()); + timeline_area->setSizePolicy(timeline_area_policy); - QVBoxLayout* timeline_area_layout = new QVBoxLayout(timeline_area); - timeline_area_layout->setSpacing(0); - timeline_area_layout->setContentsMargins(0, 0, 0, 0); + QVBoxLayout* timeline_area_layout = new QVBoxLayout(timeline_area); + timeline_area_layout->setSpacing(0); + timeline_area_layout->setContentsMargins(0, 0, 0, 0); - headers = new TimelineHeader(); - timeline_area_layout->addWidget(headers); + headers = new TimelineHeader(); + timeline_area_layout->addWidget(headers); - editAreas = new QWidget(); - QHBoxLayout* editAreaLayout = new QHBoxLayout(editAreas); - editAreaLayout->setSpacing(0); - editAreaLayout->setContentsMargins(0, 0, 0, 0); + editAreas = new QWidget(); + QHBoxLayout* editAreaLayout = new QHBoxLayout(editAreas); + editAreaLayout->setSpacing(0); + editAreaLayout->setContentsMargins(0, 0, 0, 0); - QSplitter* splitter = new QSplitter(); - splitter->setChildrenCollapsible(false); - splitter->setOrientation(Qt::Vertical); + QSplitter* splitter = new QSplitter(); + splitter->setChildrenCollapsible(false); + splitter->setOrientation(Qt::Vertical); - QWidget* videoContainer = new QWidget(); + QWidget* videoContainer = new QWidget(); - QHBoxLayout* videoContainerLayout = new QHBoxLayout(videoContainer); - videoContainerLayout->setSpacing(0); - videoContainerLayout->setContentsMargins(0, 0, 0, 0); + QHBoxLayout* videoContainerLayout = new QHBoxLayout(videoContainer); + videoContainerLayout->setSpacing(0); + videoContainerLayout->setContentsMargins(0, 0, 0, 0); - video_area = new TimelineWidget(); - video_area->setFocusPolicy(Qt::ClickFocus); - videoContainerLayout->addWidget(video_area); + video_area = new TimelineWidget(); + video_area->setFocusPolicy(Qt::ClickFocus); + videoContainerLayout->addWidget(video_area); - videoScrollbar = new QScrollBar(); - videoScrollbar->setMaximum(0); - videoScrollbar->setSingleStep(20); - videoScrollbar->setOrientation(Qt::Vertical); - videoContainerLayout->addWidget(videoScrollbar); + videoScrollbar = new QScrollBar(); + videoScrollbar->setMaximum(0); + videoScrollbar->setSingleStep(20); + videoScrollbar->setOrientation(Qt::Vertical); + videoContainerLayout->addWidget(videoScrollbar); - splitter->addWidget(videoContainer); + splitter->addWidget(videoContainer); - QWidget* audioContainer = new QWidget(); - QHBoxLayout* audioContainerLayout = new QHBoxLayout(audioContainer); - audioContainerLayout->setSpacing(0); - audioContainerLayout->setContentsMargins(0, 0, 0, 0); + QWidget* audioContainer = new QWidget(); + QHBoxLayout* audioContainerLayout = new QHBoxLayout(audioContainer); + audioContainerLayout->setSpacing(0); + audioContainerLayout->setContentsMargins(0, 0, 0, 0); - audio_area = new TimelineWidget(); - audio_area->setFocusPolicy(Qt::ClickFocus); + audio_area = new TimelineWidget(); + audio_area->setFocusPolicy(Qt::ClickFocus); - audioContainerLayout->addWidget(audio_area); + audioContainerLayout->addWidget(audio_area); - audioScrollbar = new QScrollBar(); - audioScrollbar->setMaximum(0); - audioScrollbar->setOrientation(Qt::Vertical); + audioScrollbar = new QScrollBar(); + audioScrollbar->setMaximum(0); + audioScrollbar->setOrientation(Qt::Vertical); - audioContainerLayout->addWidget(audioScrollbar); + audioContainerLayout->addWidget(audioScrollbar); - splitter->addWidget(audioContainer); + splitter->addWidget(audioContainer); - editAreaLayout->addWidget(splitter); + editAreaLayout->addWidget(splitter); - timeline_area_layout->addWidget(editAreas); + timeline_area_layout->addWidget(editAreas); - horizontalScrollBar = new ResizableScrollBar(); - horizontalScrollBar->setMaximum(0); - horizontalScrollBar->setSingleStep(20); - horizontalScrollBar->setOrientation(Qt::Horizontal); + horizontalScrollBar = new ResizableScrollBar(); + horizontalScrollBar->setMaximum(0); + horizontalScrollBar->setSingleStep(20); + horizontalScrollBar->setOrientation(Qt::Horizontal); - timeline_area_layout->addWidget(horizontalScrollBar); + timeline_area_layout->addWidget(horizontalScrollBar); - horizontalLayout->addWidget(timeline_area); + horizontalLayout->addWidget(timeline_area); - audio_monitor = new AudioMonitor(); - audio_monitor->setMinimumSize(QSize(50, 0)); + audio_monitor = new AudioMonitor(); + audio_monitor->setMinimumSize(QSize(50, 0)); - horizontalLayout->addWidget(audio_monitor); + horizontalLayout->addWidget(audio_monitor); - setWidget(dockWidgetContents); + setWidget(dockWidgetContents); } void move_clip(ComboAction* ca, ClipPtr c, long iin, long iout, long iclip_in, int itrack, bool verify_transitions, bool relative) { - ca->append(new MoveClipAction(c, iin, iout, iclip_in, itrack, relative)); + ca->append(new MoveClipAction(c, iin, iout, iclip_in, itrack, relative)); - if (verify_transitions) { - if (c->get_opening_transition() != nullptr && c->get_opening_transition()->secondary_clip != nullptr && c->get_opening_transition()->secondary_clip->timeline_out != iin) { - // separate transition - ca->append(new SetPointer(reinterpret_cast(&c->get_opening_transition()->secondary_clip), nullptr)); + if (verify_transitions) { + if (c->get_opening_transition() != nullptr && c->get_opening_transition()->secondary_clip != nullptr && c->get_opening_transition()->secondary_clip->timeline_out != iin) { + // separate transition + ca->append(new SetPointer(reinterpret_cast(&c->get_opening_transition()->secondary_clip), nullptr)); ca->append(new AddTransitionCommand(c->get_opening_transition()->secondary_clip, nullptr, c->get_opening_transition(), nullptr, kTransitionClosing, 0)); - } + } - if (c->get_closing_transition() != nullptr && c->get_closing_transition()->secondary_clip != nullptr && c->get_closing_transition()->parent_clip->timeline_in != iout) { - // separate transition - ca->append(new SetPointer(reinterpret_cast(&c->get_closing_transition()->secondary_clip), nullptr)); + if (c->get_closing_transition() != nullptr && c->get_closing_transition()->secondary_clip != nullptr && c->get_closing_transition()->parent_clip->timeline_in != iout) { + // separate transition + ca->append(new SetPointer(reinterpret_cast(&c->get_closing_transition()->secondary_clip), nullptr)); ca->append(new AddTransitionCommand(c, nullptr, c->get_closing_transition(), nullptr, kTransitionClosing, 0)); - } - } + } + } } void Timeline::set_tool() { - QPushButton* button = static_cast(sender()); - decheck_tool_buttons(button); - tool = button->property("tool").toInt(); - creating = false; - switch (tool) { - case TIMELINE_TOOL_EDIT: - case TIMELINE_TOOL_RAZOR: - timeline_area->setCursor(Qt::IBeamCursor); - break; - case TIMELINE_TOOL_HAND: - timeline_area->setCursor(Qt::OpenHandCursor); - break; - default: - timeline_area->setCursor(Qt::ArrowCursor); - } + QPushButton* button = static_cast(sender()); + decheck_tool_buttons(button); + tool = button->property("tool").toInt(); + creating = false; + switch (tool) { + case TIMELINE_TOOL_EDIT: + case TIMELINE_TOOL_RAZOR: + timeline_area->setCursor(Qt::IBeamCursor); + break; + case TIMELINE_TOOL_HAND: + timeline_area->setCursor(Qt::OpenHandCursor); + break; + default: + timeline_area->setCursor(Qt::ArrowCursor); + } } diff --git a/panels/timeline.h b/panels/timeline.h index 2cacaad7d..ac7d2033c 100644 --- a/panels/timeline.h +++ b/panels/timeline.h @@ -21,6 +21,11 @@ #ifndef TIMELINE_H #define TIMELINE_H +#include +#include +#include + +#include "ui/timelinewidget.h" #include "ui/timelinetools.h" #include "project/selection.h" #include "project/clip.h" @@ -28,12 +33,7 @@ #include "ui/timelineheader.h" #include "ui/resizablescrollbar.h" #include "ui/audiomonitor.h" -#include "ui/timelinewidget.h" - -#include -#include -#include -#include +#include "ui/panel.h" #define TRACK_DEFAULT_HEIGHT 40 @@ -52,236 +52,239 @@ void move_clip(ComboAction *ca, ClipPtr c, long iin, long iout, long iclip_in, i void ripple_clips(ComboAction *ca, SequencePtr s, long point, long length, const QVector& ignore = QVector()); struct Ghost { - int clip; - long in; - long out; - int track; - long clip_in; + int clip; + long in; + long out; + int track; + long clip_in; - long old_in; - long old_out; - int old_track; - long old_clip_in; + long old_in; + long old_out; + int old_track; + long old_clip_in; - // importing variables - Media* media; - int media_stream; + // importing variables + Media* media; + int media_stream; - // other variables - long ghost_length; - long media_length; - bool trim_in; - bool trimming; + // other variables + long ghost_length; + long media_length; + bool trim_in; + bool trimming; - // transition trimming - TransitionPtr transition; + // transition trimming + TransitionPtr transition; }; -class Timeline : public QDockWidget +class Timeline : public Panel { - Q_OBJECT + Q_OBJECT public: - explicit Timeline(QWidget *parent = nullptr); - ~Timeline(); + explicit Timeline(QWidget *parent = nullptr); + ~Timeline(); - bool focused(); - void multiply_zoom(double m); - void copy(bool del); - ClipPtr split_clip(ComboAction* ca, bool transitions, int p, long frame); - ClipPtr split_clip(ComboAction* ca, bool transitions, int p, long frame, long post_in); - bool split_selection(ComboAction* ca); - bool split_all_clips_at_point(ComboAction *ca, long point); - bool split_clip_and_relink(ComboAction* ca, int clip, long frame, bool relink); - void clean_up_selections(QVector& areas); - void deselect_area(long in, long out, int track); - void delete_areas_and_relink(ComboAction *ca, QVector& areas, bool deselect_areas); - void relink_clips_using_ids(QVector& old_clips, QVector& new_clips); - void update_sequence(); + bool focused(); + void multiply_zoom(double m); + void copy(bool del); + ClipPtr split_clip(ComboAction* ca, bool transitions, int p, long frame); + ClipPtr split_clip(ComboAction* ca, bool transitions, int p, long frame, long post_in); + bool split_selection(ComboAction* ca); + bool split_all_clips_at_point(ComboAction *ca, long point); + bool split_clip_and_relink(ComboAction* ca, int clip, long frame, bool relink); + void clean_up_selections(QVector& areas); + void deselect_area(long in, long out, int track); + void delete_areas_and_relink(ComboAction *ca, QVector& areas, bool deselect_areas); + void relink_clips_using_ids(QVector& old_clips, QVector& new_clips); + void update_sequence(); - QVector get_tracks_of_linked_clips(int i); - bool has_clip_been_split(int c); - void edit_to_point_internal(bool in, bool ripple); - void delete_in_out_internal(bool ripple); + QVector get_tracks_of_linked_clips(int i); + bool has_clip_been_split(int c); + void edit_to_point_internal(bool in, bool ripple); + void delete_in_out_internal(bool ripple); - void create_ghosts_from_media(SequencePtr seq, long entry_point, QVector &media_list); - void add_clips_from_ghosts(ComboAction *ca, SequencePtr s); + void create_ghosts_from_media(SequencePtr seq, long entry_point, QVector &media_list); + void add_clips_from_ghosts(ComboAction *ca, SequencePtr s); - int getTimelineScreenPointFromFrame(long frame); - long getTimelineFrameFromScreenPoint(int x); - int getDisplayScreenPointFromFrame(long frame); - long getDisplayFrameFromScreenPoint(int x); + int getTimelineScreenPointFromFrame(long frame); + long getTimelineFrameFromScreenPoint(int x); + int getDisplayScreenPointFromFrame(long frame); + long getDisplayFrameFromScreenPoint(int x); - int get_snap_range(); - bool snap_to_point(long point, long* l); - bool snap_to_timeline(long* l, bool use_playhead, bool use_markers, bool use_workarea); - void set_marker(); + int get_snap_range(); + bool snap_to_point(long point, long* l); + bool snap_to_timeline(long* l, bool use_playhead, bool use_markers, bool use_workarea); + void set_marker(); - // shared information - int tool; - long cursor_frame; - int cursor_track; - double zoom; - bool zoom_just_changed; - long drag_frame_start; - int drag_track_start; - void update_effect_controls(); - bool showing_all; - double old_zoom; + // shared information + int tool; + long cursor_frame; + int cursor_track; + double zoom; + bool zoom_just_changed; + long drag_frame_start; + int drag_track_start; + void update_effect_controls(); + bool showing_all; + double old_zoom; - QVector video_track_heights; - QVector audio_track_heights; - int get_track_height_size(bool video); - int calculate_track_height(int track, int height); + QVector video_track_heights; + QVector audio_track_heights; + int get_track_height_size(bool video); + int calculate_track_height(int track, int height); - // snapping - bool snapping; - bool snapped; - long snap_point; + // snapping + bool snapping; + bool snapped; + long snap_point; - // selecting functions - bool selecting; - int selection_offset; - void delete_selection(QVector &selections, bool ripple); - void select_all(); - bool rect_select_init; - bool rect_select_proc; - int rect_select_x; - int rect_select_y; - int rect_select_w; - int rect_select_h; + // selecting functions + bool selecting; + int selection_offset; + void delete_selection(QVector &selections, bool ripple); + void select_all(); + bool rect_select_init; + bool rect_select_proc; + int rect_select_x; + int rect_select_y; + int rect_select_w; + int rect_select_h; - // moving - bool moving_init; - bool moving_proc; - QVector ghosts; - bool video_ghosts; - bool audio_ghosts; - bool move_insert; + // moving + bool moving_init; + bool moving_proc; + QVector ghosts; + bool video_ghosts; + bool audio_ghosts; + bool move_insert; - // trimming - int trim_target; - bool trim_in_point; - int transition_select; + // trimming + int trim_target; + bool trim_in_point; + int transition_select; - // splitting - bool splitting; - QVector split_tracks; - QVector split_cache; + // splitting + bool splitting; + QVector split_tracks; + QVector split_cache; - // importing - bool importing; - bool importing_files; + // importing + bool importing; + bool importing_files; - // creating variables - bool creating; - int creating_object; + // creating variables + bool creating; + int creating_object; - // transition variables - bool transition_tool_init; - bool transition_tool_proc; - int transition_tool_pre_clip; - int transition_tool_post_clip; - int transition_tool_type; - const EffectMeta* transition_tool_meta; - int transition_tool_side; + // transition variables + bool transition_tool_init; + bool transition_tool_proc; + int transition_tool_pre_clip; + int transition_tool_post_clip; + int transition_tool_type; + const EffectMeta* transition_tool_meta; + int transition_tool_side; - // hand tool variables - bool hand_moving; - int drag_x_start; - int drag_y_start; + // hand tool variables + bool hand_moving; + int drag_x_start; + int drag_y_start; - bool block_repaints; + bool block_repaints; - TimelineHeader* headers; - AudioMonitor* audio_monitor; - ResizableScrollBar* horizontalScrollBar; + TimelineHeader* headers; + AudioMonitor* audio_monitor; + ResizableScrollBar* horizontalScrollBar; - QPushButton* toolArrowButton; - QPushButton* toolEditButton; - QPushButton* toolRippleButton; - QPushButton* toolRazorButton; - QPushButton* toolSlipButton; - QPushButton* toolSlideButton; - QPushButton* toolHandButton; - QPushButton* toolTransitionButton; - QPushButton* snappingButton; + QPushButton* toolArrowButton; + QPushButton* toolEditButton; + QPushButton* toolRippleButton; + QPushButton* toolRazorButton; + QPushButton* toolSlipButton; + QPushButton* toolSlideButton; + QPushButton* toolHandButton; + QPushButton* toolTransitionButton; + QPushButton* snappingButton; - void scroll_to_frame(long frame); - void select_from_playhead(); + void scroll_to_frame(long frame); + void select_from_playhead(); - bool can_ripple_empty_space(long frame, int track); + bool can_ripple_empty_space(long frame, int track); - void resizeEvent(QResizeEvent *event); + void resizeEvent(QResizeEvent *event); +protected: + virtual void Retranslate() override; public slots: - void paste(bool insert = false); - void repaint_timeline(); - void toggle_show_all(); - void deselect(); - void toggle_links(); - void split_at_playhead(); - void ripple_delete(); - void ripple_delete_empty_space(); - void toggle_enable_on_selected_clips(); + void paste(bool insert = false); + void repaint_timeline(); + void toggle_show_all(); + void deselect(); + void toggle_links(); + void split_at_playhead(); + void ripple_delete(); + void ripple_delete_empty_space(); + void toggle_enable_on_selected_clips(); - void delete_inout(); - void ripple_delete_inout(); + void delete_inout(); + void ripple_delete_inout(); - void ripple_to_in_point(); - void ripple_to_out_point(); - void edit_to_in_point(); - void edit_to_out_point(); + void ripple_to_in_point(); + void ripple_to_out_point(); + void edit_to_in_point(); + void edit_to_out_point(); - void increase_track_height(); - void decrease_track_height(); + void increase_track_height(); + void decrease_track_height(); - void previous_cut(); - void next_cut(); + void previous_cut(); + void next_cut(); - void add_transition(); + void add_transition(); - void nest(); + void nest(); - void zoom_in(); - void zoom_out(); + void zoom_in(); + void zoom_out(); private slots: - void snapping_clicked(bool checked); - void add_btn_click(); - void add_menu_item(QAction*); - void setScroll(int); - void record_btn_click(); - void transition_tool_click(); - void transition_menu_select(QAction*); - void resize_move(double d); - void set_tool(); + void snapping_clicked(bool checked); + void add_btn_click(); + void add_menu_item(QAction*); + void setScroll(int); + void record_btn_click(); + void transition_tool_click(); + void transition_menu_select(QAction*); + void resize_move(double d); + void set_tool(); private: - void set_zoom_value(double v); - QVector tool_buttons; - void decheck_tool_buttons(QObject* sender); - void set_tool(int tool); - int scroll; - void set_sb_max(); + void set_zoom_value(double v); + QVector tool_buttons; + void decheck_tool_buttons(QObject* sender); + void set_tool(int tool); + int scroll; + void set_sb_max(); + void UpdateTitle(); - void setup_ui(); + void setup_ui(); - int default_track_height; + int default_track_height; - // ripple delete empty space variables - long rc_ripple_min; - long rc_ripple_max; + // ripple delete empty space variables + long rc_ripple_min; + long rc_ripple_max; - QWidget* timeline_area; - TimelineWidget* video_area; - TimelineWidget* audio_area; - QWidget* editAreas; - QScrollBar* videoScrollbar; - QScrollBar* audioScrollbar; - QPushButton* zoomInButton; - QPushButton* zoomOutButton; - QPushButton* recordButton; - QPushButton* addButton; - QWidget* tool_button_widget; + QWidget* timeline_area; + TimelineWidget* video_area; + TimelineWidget* audio_area; + QWidget* editAreas; + QScrollBar* videoScrollbar; + QScrollBar* audioScrollbar; + QPushButton* zoomInButton; + QPushButton* zoomOutButton; + QPushButton* recordButton; + QPushButton* addButton; + QWidget* tool_button_widget; }; #endif // TIMELINE_H diff --git a/panels/viewer.cpp b/panels/viewer.cpp index 037a3b735..927277f6c 100644 --- a/panels/viewer.cpp +++ b/panels/viewer.cpp @@ -56,7 +56,7 @@ extern "C" { #include Viewer::Viewer(QWidget *parent) : - QDockWidget(parent), + Panel(parent), playing(false), just_played(false), media(nullptr), @@ -99,6 +99,10 @@ Viewer::Viewer(QWidget *parent) : Viewer::~Viewer() {} +void Viewer::Retranslate() { + update_window_title(); +} + bool Viewer::is_focused() { return headers->hasFocus() || viewer_widget->hasFocus() diff --git a/panels/viewer.h b/panels/viewer.h index c69791199..f27a2cb24 100644 --- a/panels/viewer.h +++ b/panels/viewer.h @@ -21,7 +21,6 @@ #ifndef VIEWER_H #define VIEWER_H -#include #include #include #include @@ -30,6 +29,7 @@ #include "project/marker.h" #include "project/media.h" +#include "ui/panel.h" #include "ui/viewerwidget.h" #include "ui/timelinewidget.h" #include "ui/timelineheader.h" @@ -40,123 +40,127 @@ bool frame_rate_is_droppable(float rate); long timecode_to_frame(const QString& s, int view, double frame_rate); QString frame_to_timecode(long f, int view, double frame_rate); -class Viewer : public QDockWidget +class Viewer : public Panel { - Q_OBJECT + Q_OBJECT public: - explicit Viewer(QWidget *parent = nullptr); - ~Viewer(); + explicit Viewer(QWidget *parent = nullptr); + ~Viewer(); - bool is_focused(); - bool is_main_sequence(); - void set_main_sequence(); - void set_media(Media *m); - void compose(); - void set_playpause_icon(bool play); - void update_playhead_timecode(long p); - void update_end_timecode(); - void update_header_zoom(); - void clear_in(); - void clear_out(); - void clear_inout_point(); - void set_in_point(); - void set_out_point(); - void set_zoom(bool in); - void set_panel_name(const QString& n); + bool is_focused(); + bool is_main_sequence(); + void set_main_sequence(); + void set_media(Media *m); + void compose(); + void set_playpause_icon(bool play); + void update_playhead_timecode(long p); + void update_end_timecode(); + void update_header_zoom(); + void clear_in(); + void clear_out(); + void clear_inout_point(); + void set_in_point(); + void set_out_point(); + void set_zoom(bool in); + void set_panel_name(const QString& n); - // playback functions - void seek(long p); - void play(bool in_to_out = false); - void pause(); - bool playing; - long playhead_start; - qint64 start_msecs; - QTimer playback_updater; - bool just_played; + // playback functions + void seek(long p); + void play(bool in_to_out = false); + void pause(); + bool playing; + long playhead_start; + qint64 start_msecs; + QTimer playback_updater; + bool just_played; - void cue_recording(long start, long end, int track); - void uncue_recording(); - bool is_recording_cued(); - long recording_start; - long recording_end; - int recording_track; + void cue_recording(long start, long end, int track); + void uncue_recording(); + bool is_recording_cued(); + long recording_start; + long recording_end; + int recording_track; - void reset_all_audio(); - void update_parents(bool reload_fx = false); + void reset_all_audio(); + void update_parents(bool reload_fx = false); - int get_playback_speed(); + int get_playback_speed(); - ViewerWidget* viewer_widget; + ViewerWidget* viewer_widget; - Media* media; - SequencePtr seq; - QVector* marker_ref; + Media* media; + SequencePtr seq; + QVector* marker_ref; - void set_marker(); + void set_marker(); - TimelineHeader* headers; + TimelineHeader* headers; - void resizeEvent(QResizeEvent *event); + void resizeEvent(QResizeEvent *event); + +protected: + virtual void Retranslate() override; public slots: - void play_wake(); - void go_to_start(); - void go_to_in(); - void previous_frame(); - void toggle_play(); - void increase_speed(); - void decrease_speed(); - void next_frame(); - void go_to_out(); - void go_to_end(); - void close_media(); - void update_viewer(); + void play_wake(); + void go_to_start(); + void go_to_in(); + void previous_frame(); + void toggle_play(); + void increase_speed(); + void decrease_speed(); + void next_frame(); + void go_to_out(); + void go_to_end(); + void close_media(); + void update_viewer(); private slots: - void update_playhead(); - void timer_update(); - void recording_flasher_update(); - void resize_move(double d); + void update_playhead(); + void timer_update(); + void recording_flasher_update(); + void resize_move(double d); private: - void update_window_title(); - void clean_created_seq(); - void set_sequence(bool main, SequencePtr s); - bool main_sequence; - bool created_sequence; - long cached_end_frame; - QString panel_name; - double minimum_zoom; - bool playing_in_to_out; - long last_playhead; - void set_zoom_value(double d); - void set_sb_max(); - void set_playback_speed(int s); - long get_seq_in(); - long get_seq_out(); + void update_window_title(); + void clean_created_seq(); + void set_sequence(bool main, SequencePtr s); + bool main_sequence; + bool created_sequence; + long cached_end_frame; + QString panel_name; + double minimum_zoom; + bool playing_in_to_out; + long last_playhead; + void set_zoom_value(double d); + void set_sb_max(); + void set_playback_speed(int s); - QIcon playIcon; + long get_seq_in(); + long get_seq_out(); - void setup_ui(); + QIcon playIcon; - ResizableScrollBar* horizontal_bar; - ViewerContainer* viewer_container; - LabelSlider* current_timecode_slider; - QLabel* end_timecode; + void setup_ui(); - QPushButton* go_to_start_button; - QPushButton* prev_frame_button; - QPushButton* play_button; - QPushButton* next_frame_button; - QPushButton* go_to_end_frame; + ResizableScrollBar* horizontal_bar; + ViewerContainer* viewer_container; + LabelSlider* current_timecode_slider; + QLabel* end_timecode; - bool cue_recording_internal; - QTimer recording_flasher; + QPushButton* go_to_start_button; + QPushButton* prev_frame_button; + QPushButton* play_button; + QPushButton* next_frame_button; + QPushButton* go_to_end_frame; - long previous_playhead; - int playback_speed; + bool cue_recording_internal; + QTimer recording_flasher; + + long previous_playhead; + int playback_speed; }; #endif // VIEWER_H diff --git a/ui/panel.cpp b/ui/panel.cpp new file mode 100644 index 000000000..fd40ba786 --- /dev/null +++ b/ui/panel.cpp @@ -0,0 +1,35 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 Olive Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#include "panel.h" + +#include + +Panel::Panel(QWidget *parent) : QDockWidget (parent) { + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); +} + +bool Panel::event(QEvent *e) { + if (e->type() == QEvent::LanguageChange) { + Retranslate(); + return true; + } + return QDockWidget::event(e); +} diff --git a/ui/panel.h b/ui/panel.h new file mode 100644 index 000000000..920279432 --- /dev/null +++ b/ui/panel.h @@ -0,0 +1,35 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 Olive Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#ifndef PANEL_H +#define PANEL_H + +#include + +class Panel : public QDockWidget { + Q_OBJECT +public: + Panel(QWidget* parent = nullptr); + virtual bool event(QEvent* e) override; +protected: + virtual void Retranslate() = 0; +}; + +#endif // PANEL_H diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index bf3a48987..3a2acec10 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -64,305 +64,305 @@ #define TRANSITION_BETWEEN_RANGE 40 TimelineWidget::TimelineWidget(QWidget *parent) : QWidget(parent) { - selection_command = nullptr; - self_created_sequence = nullptr; - scroll = 0; + selection_command = nullptr; + self_created_sequence = nullptr; + scroll = 0; - bottom_align = false; - track_resizing = false; - setMouseTracking(true); + bottom_align = false; + track_resizing = false; + setMouseTracking(true); - setAcceptDrops(true); + setAcceptDrops(true); - setContextMenuPolicy(Qt::CustomContextMenu); - connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu(const QPoint&))); + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu(const QPoint&))); - tooltip_timer.setInterval(500); - connect(&tooltip_timer, SIGNAL(timeout()), this, SLOT(tooltip_timer_timeout())); + tooltip_timer.setInterval(500); + connect(&tooltip_timer, SIGNAL(timeout()), this, SLOT(tooltip_timer_timeout())); } void TimelineWidget::show_context_menu(const QPoint& pos) { - if (olive::ActiveSequence != nullptr) { - // hack because sometimes right clicking doesn't trigger mouse release event - panel_timeline->rect_select_init = false; - panel_timeline->rect_select_proc = false; + if (olive::ActiveSequence != nullptr) { + // hack because sometimes right clicking doesn't trigger mouse release event + panel_timeline->rect_select_init = false; + panel_timeline->rect_select_proc = false; - QMenu menu(this); + QMenu menu(this); - // TODO replace with Olive::MenuHelper::make_edit_functions_menu() without losing functionality + // TODO replace with Olive::MenuHelper::make_edit_functions_menu() without losing functionality - QAction* undoAction = menu.addAction(tr("&Undo")); - QAction* redoAction = menu.addAction(tr("&Redo")); - connect(undoAction, SIGNAL(triggered(bool)), olive::Global.get(), SLOT(undo())); - connect(redoAction, SIGNAL(triggered(bool)), olive::Global.get(), SLOT(redo())); - undoAction->setEnabled(olive::UndoStack.canUndo()); - redoAction->setEnabled(olive::UndoStack.canRedo()); - menu.addSeparator(); + QAction* undoAction = menu.addAction(tr("&Undo")); + QAction* redoAction = menu.addAction(tr("&Redo")); + connect(undoAction, SIGNAL(triggered(bool)), olive::Global.get(), SLOT(undo())); + connect(redoAction, SIGNAL(triggered(bool)), olive::Global.get(), SLOT(redo())); + undoAction->setEnabled(olive::UndoStack.canUndo()); + redoAction->setEnabled(olive::UndoStack.canRedo()); + menu.addSeparator(); - // collect all the selected clips - QVector selected_clips; - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr && is_clip_selected(c, true)) { - selected_clips.append(c); - } - } + // collect all the selected clips + QVector selected_clips; + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr && is_clip_selected(c, true)) { + selected_clips.append(c); + } + } - if (!selected_clips.isEmpty()) { - // clips are selected - menu.addAction(tr("C&ut"), &olive::FocusFilter, SLOT(cut())); - menu.addAction(tr("Cop&y"), &olive::FocusFilter, SLOT(copy())); - } + if (!selected_clips.isEmpty()) { + // clips are selected + menu.addAction(tr("C&ut"), &olive::FocusFilter, SLOT(cut())); + menu.addAction(tr("Cop&y"), &olive::FocusFilter, SLOT(copy())); + } - menu.addAction(tr("&Paste"), olive::Global.get(), SLOT(paste())); + menu.addAction(tr("&Paste"), olive::Global.get(), SLOT(paste())); - if (selected_clips.isEmpty()) { - // no clips are selected + if (selected_clips.isEmpty()) { + // no clips are selected - // determine if we can perform a ripple empty space - panel_timeline->cursor_frame = panel_timeline->getTimelineFrameFromScreenPoint(pos.x()); - panel_timeline->cursor_track = getTrackFromScreenPoint(pos.y()); + // determine if we can perform a ripple empty space + panel_timeline->cursor_frame = panel_timeline->getTimelineFrameFromScreenPoint(pos.x()); + panel_timeline->cursor_track = getTrackFromScreenPoint(pos.y()); - if (panel_timeline->can_ripple_empty_space(panel_timeline->cursor_frame, panel_timeline->cursor_track)) { - QAction* ripple_delete_action = menu.addAction(tr("R&ipple Delete")); - connect(ripple_delete_action, SIGNAL(triggered(bool)), panel_timeline, SLOT(ripple_delete_empty_space())); - } + if (panel_timeline->can_ripple_empty_space(panel_timeline->cursor_frame, panel_timeline->cursor_track)) { + QAction* ripple_delete_action = menu.addAction(tr("R&ipple Delete")); + connect(ripple_delete_action, SIGNAL(triggered(bool)), panel_timeline, SLOT(ripple_delete_empty_space())); + } - QAction* seq_settings = menu.addAction(tr("Sequence Settings")); - connect(seq_settings, SIGNAL(triggered(bool)), this, SLOT(open_sequence_properties())); - } + QAction* seq_settings = menu.addAction(tr("Sequence Settings")); + connect(seq_settings, SIGNAL(triggered(bool)), this, SLOT(open_sequence_properties())); + } - if (!selected_clips.isEmpty()) { - menu.addSeparator(); - menu.addAction(tr("&Speed/Duration"), olive::Global.get(), SLOT(open_speed_dialog())); + if (!selected_clips.isEmpty()) { + menu.addSeparator(); + menu.addAction(tr("&Speed/Duration"), olive::Global.get(), SLOT(open_speed_dialog())); - QAction* autoscaleAction = menu.addAction(tr("Auto-s&cale"), this, SLOT(toggle_autoscale())); - autoscaleAction->setCheckable(true); - // set autoscale to the first selected clip - autoscaleAction->setChecked(selected_clips.at(0)->autoscale); + QAction* autoscaleAction = menu.addAction(tr("Auto-s&cale"), this, SLOT(toggle_autoscale())); + autoscaleAction->setCheckable(true); + // set autoscale to the first selected clip + autoscaleAction->setChecked(selected_clips.at(0)->autoscale); - olive::MenuHelper.make_clip_functions_menu(&menu); + olive::MenuHelper.make_clip_functions_menu(&menu); - // stabilizer option - /*int video_clip_count = 0; - bool all_video_is_footage = true; - for (int i=0;itrack < 0) { - video_clip_count++; - if (selected_clips.at(i)->media == nullptr - || selected_clips.at(i)->media->get_type() != MEDIA_TYPE_FOOTAGE) { - all_video_is_footage = false; - } - } - } - if (video_clip_count == 1 && all_video_is_footage) { - QAction* stabilizerAction = menu.addAction("S&tabilizer"); - connect(stabilizerAction, SIGNAL(triggered(bool)), this, SLOT(show_stabilizer_diag())); - }*/ + // stabilizer option + /*int video_clip_count = 0; + bool all_video_is_footage = true; + for (int i=0;itrack < 0) { + video_clip_count++; + if (selected_clips.at(i)->media == nullptr + || selected_clips.at(i)->media->get_type() != MEDIA_TYPE_FOOTAGE) { + all_video_is_footage = false; + } + } + } + if (video_clip_count == 1 && all_video_is_footage) { + QAction* stabilizerAction = menu.addAction("S&tabilizer"); + connect(stabilizerAction, SIGNAL(triggered(bool)), this, SLOT(show_stabilizer_diag())); + }*/ - // check if all selected clips have the same media for a "Reveal In Project" - bool same_media = true; - rc_reveal_media = selected_clips.at(0)->media; - for (int i=1;imedia != rc_reveal_media) { - same_media = false; - break; - } - } + // check if all selected clips have the same media for a "Reveal In Project" + bool same_media = true; + rc_reveal_media = selected_clips.at(0)->media; + for (int i=1;imedia != rc_reveal_media) { + same_media = false; + break; + } + } - if (same_media) { - QAction* revealInProjectAction = menu.addAction(tr("&Reveal in Project")); - connect(revealInProjectAction, SIGNAL(triggered(bool)), this, SLOT(reveal_media())); - } + if (same_media) { + QAction* revealInProjectAction = menu.addAction(tr("&Reveal in Project")); + connect(revealInProjectAction, SIGNAL(triggered(bool)), this, SLOT(reveal_media())); + } - QAction* rename = menu.addAction(tr("R&ename")); - connect(rename, SIGNAL(triggered(bool)), this, SLOT(rename_clip())); - } + QAction* rename = menu.addAction(tr("R&ename")); + connect(rename, SIGNAL(triggered(bool)), this, SLOT(rename_clip())); + } - menu.exec(mapToGlobal(pos)); - } + menu.exec(mapToGlobal(pos)); + } } void TimelineWidget::toggle_autoscale() { - SetAutoscaleAction* action = new SetAutoscaleAction(); - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr && is_clip_selected(c, true)) { - action->clips.append(c); - } - } - if (action->clips.size() > 0) { - olive::UndoStack.push(action); - } else { - delete action; - } + SetAutoscaleAction* action = new SetAutoscaleAction(); + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr && is_clip_selected(c, true)) { + action->clips.append(c); + } + } + if (action->clips.size() > 0) { + olive::UndoStack.push(action); + } else { + delete action; + } } void TimelineWidget::tooltip_timer_timeout() { - if (olive::ActiveSequence != nullptr) { - if (tooltip_clip < olive::ActiveSequence->clips.size()) { - ClipPtr c = olive::ActiveSequence->clips.at(tooltip_clip); - if (c != nullptr) { - QToolTip::showText(QCursor::pos(), - tr("%1\nStart: %2\nEnd: %3\nDuration: %4").arg( - c->name, - frame_to_timecode(c->timeline_in, olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate), - frame_to_timecode(c->timeline_out, olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate), - frame_to_timecode(c->getLength(), olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate) - )); - } - } - } - tooltip_timer.stop(); + if (olive::ActiveSequence != nullptr) { + if (tooltip_clip < olive::ActiveSequence->clips.size()) { + ClipPtr c = olive::ActiveSequence->clips.at(tooltip_clip); + if (c != nullptr) { + QToolTip::showText(QCursor::pos(), + tr("%1\nStart: %2\nEnd: %3\nDuration: %4").arg( + c->name, + frame_to_timecode(c->timeline_in, olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate), + frame_to_timecode(c->timeline_out, olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate), + frame_to_timecode(c->getLength(), olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate) + )); + } + } + } + tooltip_timer.stop(); } void TimelineWidget::rename_clip() { - QVector selected_clips; - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr && is_clip_selected(c, true)) { - selected_clips.append(c); - } - } - if (selected_clips.size() > 0) { - QString s = QInputDialog::getText(this, - (selected_clips.size() == 1) ? tr("Rename '%1'").arg(selected_clips.at(0)->name) : tr("Rename multiple clips"), - tr("Enter a new name for this clip:"), - QLineEdit::Normal, - selected_clips.at(0)->name - ); - if (!s.isEmpty()) { - RenameClipCommand* rcc = new RenameClipCommand(); - rcc->new_name = s; - rcc->clips = selected_clips; - olive::UndoStack.push(rcc); - update_ui(true); - } - } + QVector selected_clips; + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr && is_clip_selected(c, true)) { + selected_clips.append(c); + } + } + if (selected_clips.size() > 0) { + QString s = QInputDialog::getText(this, + (selected_clips.size() == 1) ? tr("Rename '%1'").arg(selected_clips.at(0)->name) : tr("Rename multiple clips"), + tr("Enter a new name for this clip:"), + QLineEdit::Normal, + selected_clips.at(0)->name + ); + if (!s.isEmpty()) { + RenameClipCommand* rcc = new RenameClipCommand(); + rcc->new_name = s; + rcc->clips = selected_clips; + olive::UndoStack.push(rcc); + update_ui(true); + } + } } void TimelineWidget::open_sequence_properties() { - QList sequence_items; - QList all_top_level_items; - for (int i=0;iget_all_media_from_table(all_top_level_items, sequence_items, MEDIA_TYPE_SEQUENCE); // find all sequences in project - for (int i=0;ito_sequence() == olive::ActiveSequence) { - NewSequenceDialog nsd(this, sequence_items.at(i)); - nsd.exec(); - return; - } - } - QMessageBox::critical(this, tr("Error"), tr("Couldn't locate media wrapper for sequence.")); + QList sequence_items; + QList all_top_level_items; + for (int i=0;iget_all_media_from_table(all_top_level_items, sequence_items, MEDIA_TYPE_SEQUENCE); // find all sequences in project + for (int i=0;ito_sequence() == olive::ActiveSequence) { + NewSequenceDialog nsd(this, sequence_items.at(i)); + nsd.exec(); + return; + } + } + QMessageBox::critical(this, tr("Error"), tr("Couldn't locate media wrapper for sequence.")); } bool same_sign(int a, int b) { - return (a < 0) == (b < 0); + return (a < 0) == (b < 0); } void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { - bool import_init = false; + bool import_init = false; - QVector media_list; - panel_timeline->importing_files = false; + QVector media_list; + panel_timeline->importing_files = false; - if (event->source() == panel_project->tree_view || event->source() == panel_project->icon_view) { - QModelIndexList items = panel_project->get_current_selected(); - media_list.resize(items.size()); - for (int i=0;iitem_to_media(items.at(i)); - } - import_init = true; - } + if (event->source() == panel_project->tree_view || event->source() == panel_project->icon_view) { + QModelIndexList items = panel_project->get_current_selected(); + media_list.resize(items.size()); + for (int i=0;iitem_to_media(items.at(i)); + } + import_init = true; + } - if (event->source() == panel_footage_viewer->viewer_widget) { - SequencePtr proposed_seq = panel_footage_viewer->seq; - if (proposed_seq != olive::ActiveSequence) { // don't allow nesting the same sequence - media_list.append(panel_footage_viewer->media); - import_init = true; - } - } + if (event->source() == panel_footage_viewer->viewer_widget) { + SequencePtr proposed_seq = panel_footage_viewer->seq; + if (proposed_seq != olive::ActiveSequence) { // don't allow nesting the same sequence + media_list.append(panel_footage_viewer->media); + import_init = true; + } + } - if (olive::CurrentConfig.enable_drag_files_to_timeline && event->mimeData()->hasUrls()) { - QList urls = event->mimeData()->urls(); - if (!urls.isEmpty()) { - QStringList file_list; + if (olive::CurrentConfig.enable_drag_files_to_timeline && event->mimeData()->hasUrls()) { + QList urls = event->mimeData()->urls(); + if (!urls.isEmpty()) { + QStringList file_list; - for (int i=0;iprocess_file_list(file_list); + panel_project->process_file_list(file_list); - for (int i=0;ilast_imported_media.size();i++) { - // waits for media to have a duration - // TODO would be much nicer if this was multithreaded - FootagePtr f = panel_project->last_imported_media.at(i)->to_footage(); - f->ready_lock.lock(); - f->ready_lock.unlock(); + for (int i=0;ilast_imported_media.size();i++) { + // waits for media to have a duration + // TODO would be much nicer if this was multithreaded + FootagePtr f = panel_project->last_imported_media.at(i)->to_footage(); + f->ready_lock.lock(); + f->ready_lock.unlock(); - if (f->ready) { - media_list.append(panel_project->last_imported_media.at(i)); - } - } + if (f->ready) { + media_list.append(panel_project->last_imported_media.at(i)); + } + } - if (media_list.isEmpty()) { - olive::UndoStack.undo(); - } else { - import_init = true; - panel_timeline->importing_files = true; - } - } - } + if (media_list.isEmpty()) { + olive::UndoStack.undo(); + } else { + import_init = true; + panel_timeline->importing_files = true; + } + } + } - if (import_init) { - event->acceptProposedAction(); + if (import_init) { + event->acceptProposedAction(); - long entry_point; - SequencePtr seq = olive::ActiveSequence; + long entry_point; + SequencePtr seq = olive::ActiveSequence; - if (seq == nullptr) { - // if no sequence, we're going to create a new one using the clips as a reference - entry_point = 0; + if (seq == nullptr) { + // if no sequence, we're going to create a new one using the clips as a reference + entry_point = 0; - self_created_sequence = create_sequence_from_media(media_list); - seq = self_created_sequence; - } else { - entry_point = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x()); - panel_timeline->drag_frame_start = entry_point + getFrameFromScreenPoint(panel_timeline->zoom, 50); - panel_timeline->drag_track_start = (bottom_align) ? -1 : 0; - } + self_created_sequence = create_sequence_from_media(media_list); + seq = self_created_sequence; + } else { + entry_point = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x()); + panel_timeline->drag_frame_start = entry_point + getFrameFromScreenPoint(panel_timeline->zoom, 50); + panel_timeline->drag_track_start = (bottom_align) ? -1 : 0; + } - panel_timeline->create_ghosts_from_media(seq, entry_point, media_list); + panel_timeline->create_ghosts_from_media(seq, entry_point, media_list); - panel_timeline->importing = true; - } + panel_timeline->importing = true; + } } void TimelineWidget::dragMoveEvent(QDragMoveEvent *event) { - if (panel_timeline->importing) { - event->acceptProposedAction(); + if (panel_timeline->importing) { + event->acceptProposedAction(); - if (olive::ActiveSequence != nullptr) { - QPoint pos = event->pos(); - update_ghosts(pos, event->keyboardModifiers() & Qt::ShiftModifier); - panel_timeline->move_insert = ((event->keyboardModifiers() & Qt::ControlModifier) && (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->importing)); - update_ui(false); - } - } + if (olive::ActiveSequence != nullptr) { + QPoint pos = event->pos(); + update_ghosts(pos, event->keyboardModifiers() & Qt::ShiftModifier); + panel_timeline->move_insert = ((event->keyboardModifiers() & Qt::ControlModifier) && (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->importing)); + update_ui(false); + } + } } void TimelineWidget::wheelEvent(QWheelEvent *event) { - // shift used to toggle zooming instead of scrolling - bool shift = (event->modifiers() & Qt::ShiftModifier); + // shift used to toggle zooming instead of scrolling + bool shift = (event->modifiers() & Qt::ShiftModifier); - // - // NOTE/FIXME: CURRENTLY disabling pixel scrolling because it needs more testing - // + // + // NOTE/FIXME: CURRENTLY disabling pixel scrolling because it needs more testing + // - /*if (!event->pixelDelta().isNull()) { + /*if (!event->pixelDelta().isNull()) { // if we got pixel scrolling data, prefer it over the angleDelta data QScrollBar* horiz_bar = panel_timeline->horizontalScrollBar; @@ -373,2453 +373,2453 @@ void TimelineWidget::wheelEvent(QWheelEvent *event) { } else*/ if (!event->angleDelta().isNull()) { - // alt is used to swap horizontal and vertical scrolling - bool alt = (event->modifiers() & Qt::AltModifier); + // alt is used to swap horizontal and vertical scrolling + bool alt = (event->modifiers() & Qt::AltModifier); - int scroll_amount = alt ? (event->angleDelta().x()) : (event->angleDelta().y()); + int scroll_amount = alt ? (event->angleDelta().x()) : (event->angleDelta().y()); - bool in = (scroll_amount > 0); - if (olive::CurrentConfig.scroll_zooms != shift) { + bool in = (scroll_amount > 0); + if (olive::CurrentConfig.scroll_zooms != shift) { - // if config.scroll_zooms is enabled or shift is held, zoom instead of scrolling - if (in) { - panel_timeline->multiply_zoom(1.5); - } else { - panel_timeline->multiply_zoom(0.75); - } + // if config.scroll_zooms is enabled or shift is held, zoom instead of scrolling + if (in) { + panel_timeline->multiply_zoom(1.5); + } else { + panel_timeline->multiply_zoom(0.75); + } - } else { - // pass the scrolling to the Timeline's main scrollbar for horizontal scrolling, or this widget's - // scrollbar for vertical scrolling + } else { + // pass the scrolling to the Timeline's main scrollbar for horizontal scrolling, or this widget's + // scrollbar for vertical scrolling - QScrollBar* bar = alt ? scrollBar : panel_timeline->horizontalScrollBar; + QScrollBar* bar = alt ? scrollBar : panel_timeline->horizontalScrollBar; - int step = bar->singleStep(); - if (in) step = -step; - bar->setValue(bar->value() + step); - } + int step = bar->singleStep(); + if (in) step = -step; + bar->setValue(bar->value() + step); } + } } void TimelineWidget::dragLeaveEvent(QDragLeaveEvent* event) { - event->accept(); - if (panel_timeline->importing) { - if (panel_timeline->importing_files) { - olive::UndoStack.undo(); - } - panel_timeline->importing_files = false; - panel_timeline->ghosts.clear(); - panel_timeline->importing = false; - update_ui(false); - } - if (self_created_sequence != nullptr) { - self_created_sequence.reset(); - self_created_sequence = nullptr; - } + event->accept(); + if (panel_timeline->importing) { + if (panel_timeline->importing_files) { + olive::UndoStack.undo(); + } + panel_timeline->importing_files = false; + panel_timeline->ghosts.clear(); + panel_timeline->importing = false; + update_ui(false); + } + if (self_created_sequence != nullptr) { + self_created_sequence.reset(); + self_created_sequence = nullptr; + } } void delete_area_under_ghosts(ComboAction* ca) { - // delete areas before adding - QVector delete_areas; - for (int i=0;ighosts.size();i++) { - const Ghost& g = panel_timeline->ghosts.at(i); - Selection sel; - sel.in = g.in; - sel.out = g.out; - sel.track = g.track; - delete_areas.append(sel); - } - panel_timeline->delete_areas_and_relink(ca, delete_areas, false); + // delete areas before adding + QVector delete_areas; + for (int i=0;ighosts.size();i++) { + const Ghost& g = panel_timeline->ghosts.at(i); + Selection sel; + sel.in = g.in; + sel.out = g.out; + sel.track = g.track; + delete_areas.append(sel); + } + panel_timeline->delete_areas_and_relink(ca, delete_areas, false); } void insert_clips(ComboAction* ca) { - bool ripple_old_point = true; + bool ripple_old_point = true; - long earliest_old_point = LONG_MAX; - long latest_old_point = LONG_MIN; + long earliest_old_point = LONG_MAX; + long latest_old_point = LONG_MIN; - long earliest_new_point = LONG_MAX; - long latest_new_point = LONG_MIN; + long earliest_new_point = LONG_MAX; + long latest_new_point = LONG_MIN; - QVector ignore_clips; - for (int i=0;ighosts.size();i++) { - const Ghost& g = panel_timeline->ghosts.at(i); + QVector ignore_clips; + for (int i=0;ighosts.size();i++) { + const Ghost& g = panel_timeline->ghosts.at(i); - earliest_old_point = qMin(earliest_old_point, g.old_in); - latest_old_point = qMax(latest_old_point, g.old_out); - earliest_new_point = qMin(earliest_new_point, g.in); - latest_new_point = qMax(latest_new_point, g.out); + earliest_old_point = qMin(earliest_old_point, g.old_in); + latest_old_point = qMax(latest_old_point, g.old_out); + earliest_new_point = qMin(earliest_new_point, g.in); + latest_new_point = qMax(latest_new_point, g.out); - if (g.clip >= 0) { - ignore_clips.append(g.clip); - } else { - // don't try to close old gap if importing - ripple_old_point = false; - } - } + if (g.clip >= 0) { + ignore_clips.append(g.clip); + } else { + // don't try to close old gap if importing + ripple_old_point = false; + } + } - panel_timeline->split_cache.clear(); + panel_timeline->split_cache.clear(); - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr) { - // don't split any clips that are moving - bool found = false; - for (int j=0;jghosts.size();j++) { - if (panel_timeline->ghosts.at(j).clip == i) { - found = true; - break; - } - } - if (!found) { - if (c->timeline_in < earliest_new_point && c->timeline_out > earliest_new_point) { - panel_timeline->split_clip_and_relink(ca, i, earliest_new_point, true); - } + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr) { + // don't split any clips that are moving + bool found = false; + for (int j=0;jghosts.size();j++) { + if (panel_timeline->ghosts.at(j).clip == i) { + found = true; + break; + } + } + if (!found) { + if (c->timeline_in < earliest_new_point && c->timeline_out > earliest_new_point) { + panel_timeline->split_clip_and_relink(ca, i, earliest_new_point, true); + } - // determine if we should close the gap the old clips left behind - if (ripple_old_point - && !((c->timeline_in < earliest_old_point && c->timeline_out <= earliest_old_point) || (c->timeline_in >= latest_old_point && c->timeline_out > latest_old_point)) - && !ignore_clips.contains(i)) { - ripple_old_point = false; - } - } - } - } + // determine if we should close the gap the old clips left behind + if (ripple_old_point + && !((c->timeline_in < earliest_old_point && c->timeline_out <= earliest_old_point) || (c->timeline_in >= latest_old_point && c->timeline_out > latest_old_point)) + && !ignore_clips.contains(i)) { + ripple_old_point = false; + } + } + } + } - long ripple_length = (latest_new_point - earliest_new_point); + long ripple_length = (latest_new_point - earliest_new_point); - ripple_clips(ca, olive::ActiveSequence, earliest_new_point, ripple_length, ignore_clips); + ripple_clips(ca, olive::ActiveSequence, earliest_new_point, ripple_length, ignore_clips); - if (ripple_old_point) { - // works for moving later clips earlier but not earlier to later - long second_ripple_length = (earliest_old_point - latest_old_point); + if (ripple_old_point) { + // works for moving later clips earlier but not earlier to later + long second_ripple_length = (earliest_old_point - latest_old_point); - ripple_clips(ca, olive::ActiveSequence, latest_old_point, second_ripple_length, ignore_clips); + ripple_clips(ca, olive::ActiveSequence, latest_old_point, second_ripple_length, ignore_clips); - if (earliest_old_point < earliest_new_point) { - for (int i=0;ighosts.size();i++) { - Ghost& g = panel_timeline->ghosts[i]; - g.in += second_ripple_length; - g.out += second_ripple_length; - } - for (int i=0;iselections.size();i++) { - Selection& s = olive::ActiveSequence->selections[i]; - s.in += second_ripple_length; - s.out += second_ripple_length; - } - } - } + if (earliest_old_point < earliest_new_point) { + for (int i=0;ighosts.size();i++) { + Ghost& g = panel_timeline->ghosts[i]; + g.in += second_ripple_length; + g.out += second_ripple_length; + } + for (int i=0;iselections.size();i++) { + Selection& s = olive::ActiveSequence->selections[i]; + s.in += second_ripple_length; + s.out += second_ripple_length; + } + } + } } void TimelineWidget::dropEvent(QDropEvent* event) { - if (panel_timeline->importing && panel_timeline->ghosts.size() > 0) { - event->acceptProposedAction(); + if (panel_timeline->importing && panel_timeline->ghosts.size() > 0) { + event->acceptProposedAction(); - ComboAction* ca = new ComboAction(); + ComboAction* ca = new ComboAction(); - SequencePtr s = olive::ActiveSequence; + SequencePtr s = olive::ActiveSequence; - // if we're dropping into nothing, create a new sequences based on the clip being dragged - if (s == nullptr) { - s = self_created_sequence; - panel_project->create_sequence_internal(ca, self_created_sequence, true, nullptr); - self_created_sequence = nullptr; - } else if (event->keyboardModifiers() & Qt::ControlModifier) { - insert_clips(ca); - } else { - delete_area_under_ghosts(ca); - } + // if we're dropping into nothing, create a new sequences based on the clip being dragged + if (s == nullptr) { + s = self_created_sequence; + panel_project->create_sequence_internal(ca, self_created_sequence, true, nullptr); + self_created_sequence = nullptr; + } else if (event->keyboardModifiers() & Qt::ControlModifier) { + insert_clips(ca); + } else { + delete_area_under_ghosts(ca); + } - panel_timeline->add_clips_from_ghosts(ca, s); + panel_timeline->add_clips_from_ghosts(ca, s); - olive::UndoStack.push(ca); + olive::UndoStack.push(ca); - setFocus(); + setFocus(); - update_ui(true); - } + update_ui(true); + } } void TimelineWidget::mouseDoubleClickEvent(QMouseEvent *event) { - if (olive::ActiveSequence != nullptr) { - if (panel_timeline->tool == TIMELINE_TOOL_EDIT) { - int clip_index = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); - if (clip_index >= 0) { - ClipPtr clip = olive::ActiveSequence->clips.at(clip_index); - if (!(event->modifiers() & Qt::ShiftModifier)) olive::ActiveSequence->selections.clear(); - Selection s; - s.in = clip->timeline_in; - s.out = clip->timeline_out; - s.track = clip->track; - olive::ActiveSequence->selections.append(s); - update_ui(false); - } - } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { - int clip_index = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); - if (clip_index >= 0) { - ClipPtr c = olive::ActiveSequence->clips.at(clip_index); - if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) { - set_sequence(c->media->to_sequence()); - } - } + if (olive::ActiveSequence != nullptr) { + if (panel_timeline->tool == TIMELINE_TOOL_EDIT) { + int clip_index = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); + if (clip_index >= 0) { + ClipPtr clip = olive::ActiveSequence->clips.at(clip_index); + if (!(event->modifiers() & Qt::ShiftModifier)) olive::ActiveSequence->selections.clear(); + Selection s; + s.in = clip->timeline_in; + s.out = clip->timeline_out; + s.track = clip->track; + olive::ActiveSequence->selections.append(s); + update_ui(false); + } + } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { + int clip_index = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); + if (clip_index >= 0) { + ClipPtr c = olive::ActiveSequence->clips.at(clip_index); + if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) { + set_sequence(c->media->to_sequence()); } + } } + } } bool isLiveEditing() { - return (panel_timeline->tool == TIMELINE_TOOL_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR || panel_timeline->creating); + return (panel_timeline->tool == TIMELINE_TOOL_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR || panel_timeline->creating); } void TimelineWidget::mousePressEvent(QMouseEvent *event) { - if (olive::ActiveSequence != nullptr) { - int tool = panel_timeline->tool; - if (event->button() == Qt::MiddleButton) { - tool = TIMELINE_TOOL_HAND; - panel_timeline->creating = false; - } else if (event->button() == Qt::RightButton) { - tool = TIMELINE_TOOL_MENU; - panel_timeline->creating = false; - } + if (olive::ActiveSequence != nullptr) { + int tool = panel_timeline->tool; + if (event->button() == Qt::MiddleButton) { + tool = TIMELINE_TOOL_HAND; + panel_timeline->creating = false; + } else if (event->button() == Qt::RightButton) { + tool = TIMELINE_TOOL_MENU; + panel_timeline->creating = false; + } - QPoint pos = event->pos(); - if (isLiveEditing()) { - panel_timeline->drag_frame_start = panel_timeline->cursor_frame; - panel_timeline->drag_track_start = panel_timeline->cursor_track; - } else { - panel_timeline->drag_frame_start = panel_timeline->getTimelineFrameFromScreenPoint(pos.x()); - panel_timeline->drag_track_start = getTrackFromScreenPoint(pos.y()); - } + QPoint pos = event->pos(); + if (isLiveEditing()) { + panel_timeline->drag_frame_start = panel_timeline->cursor_frame; + panel_timeline->drag_track_start = panel_timeline->cursor_track; + } else { + panel_timeline->drag_frame_start = panel_timeline->getTimelineFrameFromScreenPoint(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); - bool shift = (event->modifiers() & Qt::ShiftModifier); - bool alt = (event->modifiers() & Qt::AltModifier); + bool shift = (event->modifiers() & Qt::ShiftModifier); + bool alt = (event->modifiers() & Qt::AltModifier); - if (shift) { - panel_timeline->selection_offset = olive::ActiveSequence->selections.size(); - } else { - panel_timeline->selection_offset = 0; - } + if (shift) { + panel_timeline->selection_offset = olive::ActiveSequence->selections.size(); + } else { + panel_timeline->selection_offset = 0; + } - if (panel_timeline->creating) { - int comp = 0; - switch (panel_timeline->creating_object) { - case ADD_OBJ_TITLE: - case ADD_OBJ_SOLID: - case ADD_OBJ_BARS: - comp = -1; - break; - case ADD_OBJ_TONE: - case ADD_OBJ_NOISE: - case ADD_OBJ_AUDIO: - comp = 1; - break; - } + if (panel_timeline->creating) { + int comp = 0; + switch (panel_timeline->creating_object) { + case ADD_OBJ_TITLE: + case ADD_OBJ_SOLID: + case ADD_OBJ_BARS: + comp = -1; + break; + case ADD_OBJ_TONE: + case ADD_OBJ_NOISE: + case ADD_OBJ_AUDIO: + comp = 1; + break; + } - if ((panel_timeline->drag_track_start < 0) == (comp < 0)) { - Ghost g; - g.in = g.old_in = g.out = g.old_out = panel_timeline->drag_frame_start; - g.track = g.old_track = panel_timeline->drag_track_start; - g.transition = nullptr; - g.clip = -1; - g.trimming = true; - g.trim_in = false; - panel_timeline->ghosts.append(g); + if ((panel_timeline->drag_track_start < 0) == (comp < 0)) { + Ghost g; + g.in = g.old_in = g.out = g.old_out = panel_timeline->drag_frame_start; + g.track = g.old_track = panel_timeline->drag_track_start; + g.transition = nullptr; + g.clip = -1; + g.trimming = true; + g.trim_in = false; + panel_timeline->ghosts.append(g); - panel_timeline->moving_init = true; - panel_timeline->moving_proc = true; - } - } else { - switch (tool) { - case TIMELINE_TOOL_POINTER: - case TIMELINE_TOOL_RIPPLE: - case TIMELINE_TOOL_SLIP: - case TIMELINE_TOOL_ROLLING: - case TIMELINE_TOOL_SLIDE: - case TIMELINE_TOOL_MENU: - { - if (track_resizing && tool != TIMELINE_TOOL_MENU) { - track_resize_mouse_cache = event->pos().y(); - panel_timeline->moving_init = true; - } else { - if (clip_index >= 0) { - ClipPtr clip = olive::ActiveSequence->clips.at(clip_index); - if (clip != nullptr) { - if (is_clip_selected(clip, true)) { - if (shift) { - panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track); + panel_timeline->moving_init = true; + panel_timeline->moving_proc = true; + } + } else { + switch (tool) { + case TIMELINE_TOOL_POINTER: + case TIMELINE_TOOL_RIPPLE: + case TIMELINE_TOOL_SLIP: + case TIMELINE_TOOL_ROLLING: + case TIMELINE_TOOL_SLIDE: + case TIMELINE_TOOL_MENU: + { + if (track_resizing && tool != TIMELINE_TOOL_MENU) { + track_resize_mouse_cache = event->pos().y(); + panel_timeline->moving_init = true; + } else { + if (clip_index >= 0) { + ClipPtr clip = olive::ActiveSequence->clips.at(clip_index); + if (clip != nullptr) { + if (is_clip_selected(clip, true)) { + if (shift) { + panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track); - if (!alt) { - for (int i=0;ilinked.size();i++) { - ClipPtr link = olive::ActiveSequence->clips.at(clip->linked.at(i)); - panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track); - } - } - } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER && panel_timeline->transition_select != kTransitionNone) { - panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track); + if (!alt) { + for (int i=0;ilinked.size();i++) { + ClipPtr link = olive::ActiveSequence->clips.at(clip->linked.at(i)); + panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track); + } + } + } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER && panel_timeline->transition_select != kTransitionNone) { + panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track); - for (int i=0;ilinked.size();i++) { - ClipPtr link = olive::ActiveSequence->clips.at(clip->linked.at(i)); - panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track); - } + for (int i=0;ilinked.size();i++) { + ClipPtr link = olive::ActiveSequence->clips.at(clip->linked.at(i)); + panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track); + } - Selection s; - s.track = clip->track; + Selection s; + s.track = clip->track; - if (panel_timeline->transition_select == kTransitionOpening && clip->get_opening_transition() != nullptr) { - s.in = clip->timeline_in; - if (clip->get_opening_transition()->secondary_clip != nullptr) s.in -= clip->get_opening_transition()->get_true_length(); - s.out = clip->timeline_in + clip->get_opening_transition()->get_true_length(); - } else if (panel_timeline->transition_select == kTransitionClosing && clip->get_closing_transition() != nullptr) { - s.in = clip->timeline_out - clip->get_closing_transition()->get_true_length(); - s.out = clip->timeline_out; - if (clip->get_closing_transition()->secondary_clip != nullptr) s.out += clip->get_closing_transition()->get_true_length(); - } - olive::ActiveSequence->selections.append(s); - } - } else { - // if "shift" is not down - if (!shift) { - olive::ActiveSequence->selections.clear(); - } + if (panel_timeline->transition_select == kTransitionOpening && clip->get_opening_transition() != nullptr) { + s.in = clip->timeline_in; + if (clip->get_opening_transition()->secondary_clip != nullptr) s.in -= clip->get_opening_transition()->get_true_length(); + s.out = clip->timeline_in + clip->get_opening_transition()->get_true_length(); + } else if (panel_timeline->transition_select == kTransitionClosing && clip->get_closing_transition() != nullptr) { + s.in = clip->timeline_out - clip->get_closing_transition()->get_true_length(); + s.out = clip->timeline_out; + if (clip->get_closing_transition()->secondary_clip != nullptr) s.out += clip->get_closing_transition()->get_true_length(); + } + olive::ActiveSequence->selections.append(s); + } + } else { + // if "shift" is not down + if (!shift) { + olive::ActiveSequence->selections.clear(); + } - Selection s; + Selection s; - s.in = clip->timeline_in; - s.out = clip->timeline_out; + s.in = clip->timeline_in; + s.out = clip->timeline_out; - if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { - if (panel_timeline->transition_select == kTransitionOpening) { - s.out = clip->timeline_in + clip->get_opening_transition()->get_true_length(); - if (clip->get_opening_transition()->secondary_clip != nullptr) s.in -= clip->get_opening_transition()->get_true_length(); - } + if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { + if (panel_timeline->transition_select == kTransitionOpening) { + s.out = clip->timeline_in + clip->get_opening_transition()->get_true_length(); + if (clip->get_opening_transition()->secondary_clip != nullptr) s.in -= clip->get_opening_transition()->get_true_length(); + } - if (panel_timeline->transition_select == kTransitionClosing) { - s.in = clip->timeline_out - clip->get_closing_transition()->get_true_length(); - if (clip->get_closing_transition()->secondary_clip != nullptr) s.out += clip->get_closing_transition()->get_true_length(); - } - } + if (panel_timeline->transition_select == kTransitionClosing) { + s.in = clip->timeline_out - clip->get_closing_transition()->get_true_length(); + if (clip->get_closing_transition()->secondary_clip != nullptr) s.out += clip->get_closing_transition()->get_true_length(); + } + } - s.track = clip->track; - olive::ActiveSequence->selections.append(s); + s.track = clip->track; + olive::ActiveSequence->selections.append(s); - if (olive::CurrentConfig.select_also_seeks) { - panel_sequence_viewer->seek(clip->timeline_in); - } + if (olive::CurrentConfig.select_also_seeks) { + panel_sequence_viewer->seek(clip->timeline_in); + } - // if alt is not down, select links - if (!alt && panel_timeline->transition_select == kTransitionNone) { - for (int i=0;ilinked.size();i++) { - ClipPtr link = olive::ActiveSequence->clips.at(clip->linked.at(i)); - if (!is_clip_selected(link, true)) { - Selection ss; - ss.in = link->timeline_in; - ss.out = link->timeline_out; - ss.track = link->track; - olive::ActiveSequence->selections.append(ss); - } - } - } - } - } + // if alt is not down, select links + if (!alt && panel_timeline->transition_select == kTransitionNone) { + for (int i=0;ilinked.size();i++) { + ClipPtr link = olive::ActiveSequence->clips.at(clip->linked.at(i)); + if (!is_clip_selected(link, true)) { + Selection ss; + ss.in = link->timeline_in; + ss.out = link->timeline_out; + ss.track = link->track; + olive::ActiveSequence->selections.append(ss); + } + } + } + } + } - if (tool != TIMELINE_TOOL_MENU) panel_timeline->moving_init = true; - } else { - // if "shift" is not down - if (!shift) { - olive::ActiveSequence->selections.clear(); - } + if (tool != TIMELINE_TOOL_MENU) panel_timeline->moving_init = true; + } else { + // if "shift" is not down + if (!shift) { + olive::ActiveSequence->selections.clear(); + } - panel_timeline->rect_select_init = true; - } - update_ui(false); - } - } - break; - case TIMELINE_TOOL_HAND: - panel_timeline->hand_moving = true; - panel_timeline->drag_x_start = pos.x(); - panel_timeline->drag_y_start = pos.y(); - break; - case TIMELINE_TOOL_EDIT: - if (olive::CurrentConfig.edit_tool_also_seeks) panel_sequence_viewer->seek(panel_timeline->drag_frame_start); - panel_timeline->selecting = true; - break; - case TIMELINE_TOOL_RAZOR: - { - panel_timeline->splitting = true; - panel_timeline->split_tracks.append(panel_timeline->drag_track_start); - update_ui(false); - } - break; - case TIMELINE_TOOL_TRANSITION: - { - if (panel_timeline->transition_tool_pre_clip > -1) { - panel_timeline->transition_tool_init = true; - } - } - break; - } - } - } + panel_timeline->rect_select_init = true; + } + update_ui(false); + } + } + break; + case TIMELINE_TOOL_HAND: + panel_timeline->hand_moving = true; + panel_timeline->drag_x_start = pos.x(); + panel_timeline->drag_y_start = pos.y(); + break; + case TIMELINE_TOOL_EDIT: + if (olive::CurrentConfig.edit_tool_also_seeks) panel_sequence_viewer->seek(panel_timeline->drag_frame_start); + panel_timeline->selecting = true; + break; + case TIMELINE_TOOL_RAZOR: + { + panel_timeline->splitting = true; + panel_timeline->split_tracks.append(panel_timeline->drag_track_start); + update_ui(false); + } + break; + case TIMELINE_TOOL_TRANSITION: + { + if (panel_timeline->transition_tool_pre_clip > -1) { + panel_timeline->transition_tool_init = true; + } + } + break; + } + } + } } void make_room_for_transition(ComboAction* ca, ClipPtr c, int type, long transition_start, long transition_end, bool delete_old_transitions) { - // make room for transition - if (type == kTransitionOpening) { - if (delete_old_transitions && c->get_opening_transition() != nullptr) { + // make room for transition + if (type == kTransitionOpening) { + if (delete_old_transitions && c->get_opening_transition() != nullptr) { ca->append(new DeleteTransitionCommand(c->opening_transition)); - } - if (c->get_closing_transition() != nullptr) { - if (transition_end >= c->timeline_out) { + } + if (c->get_closing_transition() != nullptr) { + if (transition_end >= c->timeline_out) { ca->append(new DeleteTransitionCommand(c->closing_transition)); - } else if (transition_end > c->timeline_out - c->get_closing_transition()->get_true_length()) { + } else if (transition_end > c->timeline_out - c->get_closing_transition()->get_true_length()) { ca->append(new ModifyTransitionCommand(c->closing_transition, c->timeline_out - transition_end)); - } - } - } else { - if (delete_old_transitions && c->get_closing_transition() != nullptr) { + } + } + } else { + if (delete_old_transitions && c->get_closing_transition() != nullptr) { ca->append(new DeleteTransitionCommand(c->closing_transition)); - } - if (c->get_opening_transition() != nullptr) { - if (transition_start <= c->timeline_in) { + } + if (c->get_opening_transition() != nullptr) { + if (transition_start <= c->timeline_in) { ca->append(new DeleteTransitionCommand(c->opening_transition)); - } else if (transition_start < c->timeline_in + c->get_opening_transition()->get_true_length()) { + } else if (transition_start < c->timeline_in + c->get_opening_transition()->get_true_length()) { ca->append(new ModifyTransitionCommand(c->opening_transition, transition_start - c->timeline_in)); - } - } - } + } + } + } } void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { - QToolTip::hideText(); - if (olive::ActiveSequence != nullptr) { - bool alt = (event->modifiers() & Qt::AltModifier); - bool shift = (event->modifiers() & Qt::ShiftModifier); - bool ctrl = (event->modifiers() & Qt::ControlModifier); + QToolTip::hideText(); + if (olive::ActiveSequence != nullptr) { + bool alt = (event->modifiers() & Qt::AltModifier); + bool shift = (event->modifiers() & Qt::ShiftModifier); + bool ctrl = (event->modifiers() & Qt::ControlModifier); - if (event->button() == Qt::LeftButton) { - ComboAction* ca = new ComboAction(); - bool push_undo = false; + if (event->button() == Qt::LeftButton) { + ComboAction* ca = new ComboAction(); + bool push_undo = false; - if (panel_timeline->creating) { - if (panel_timeline->ghosts.size() > 0) { - const Ghost& g = panel_timeline->ghosts.at(0); + if (panel_timeline->creating) { + if (panel_timeline->ghosts.size() > 0) { + const Ghost& g = panel_timeline->ghosts.at(0); - if (panel_timeline->creating_object == ADD_OBJ_AUDIO) { - olive::MainWindow->statusBar()->clearMessage(); - panel_sequence_viewer->cue_recording(qMin(g.in, g.out), qMax(g.in, g.out), g.track); - panel_timeline->creating = false; - } else if (g.in != g.out) { - ClipPtr c = ClipPtr(new Clip(olive::ActiveSequence)); - c->media = nullptr; - c->timeline_in = qMin(g.in, g.out); - c->timeline_out = qMax(g.in, g.out); - c->clip_in = 0; - c->color_r = 192; - c->color_g = 192; - c->color_b = 64; - c->track = g.track; + if (panel_timeline->creating_object == ADD_OBJ_AUDIO) { + olive::MainWindow->statusBar()->clearMessage(); + panel_sequence_viewer->cue_recording(qMin(g.in, g.out), qMax(g.in, g.out), g.track); + panel_timeline->creating = false; + } else if (g.in != g.out) { + ClipPtr c = ClipPtr(new Clip(olive::ActiveSequence)); + c->media = nullptr; + c->timeline_in = qMin(g.in, g.out); + c->timeline_out = qMax(g.in, g.out); + c->clip_in = 0; + c->color_r = 192; + c->color_g = 192; + c->color_b = 64; + c->track = g.track; - if (ctrl) { - insert_clips(ca); - } else { - Selection s; - s.in = c->timeline_in; - s.out = c->timeline_out; - s.track = c->track; - QVector areas; - areas.append(s); - panel_timeline->delete_areas_and_relink(ca, areas, false); - } + if (ctrl) { + insert_clips(ca); + } else { + Selection s; + s.in = c->timeline_in; + s.out = c->timeline_out; + s.track = c->track; + QVector areas; + areas.append(s); + panel_timeline->delete_areas_and_relink(ca, areas, false); + } - QVector add; - add.append(c); - ca->append(new AddClipCommand(olive::ActiveSequence, add)); + QVector add; + add.append(c); + ca->append(new AddClipCommand(olive::ActiveSequence, add)); - if (c->track < 0 && olive::CurrentConfig.add_default_effects_to_clips) { - // default video effects (before custom effects) - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TRANSFORM, EFFECT_TYPE_EFFECT))); - } + if (c->track < 0 && olive::CurrentConfig.add_default_effects_to_clips) { + // default video effects (before custom effects) + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TRANSFORM, EFFECT_TYPE_EFFECT))); + } - switch (panel_timeline->creating_object) { - case ADD_OBJ_TITLE: - c->name = tr("Title"); - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TEXT, EFFECT_TYPE_EFFECT))); - break; - case ADD_OBJ_SOLID: - c->name = tr("Solid Color"); - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_SOLID, EFFECT_TYPE_EFFECT))); - break; - case ADD_OBJ_BARS: - { - c->name = tr("Bars"); - EffectPtr e = create_effect(c, get_internal_meta(EFFECT_INTERNAL_SOLID, EFFECT_TYPE_EFFECT)); - e->row(0)->field(0)->set_combo_index(1); - c->effects.append(e); - } - break; - case ADD_OBJ_TONE: - c->name = tr("Tone"); - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TONE, EFFECT_TYPE_EFFECT))); - break; - case ADD_OBJ_NOISE: - c->name = tr("Noise"); - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_NOISE, EFFECT_TYPE_EFFECT))); - break; - } + switch (panel_timeline->creating_object) { + case ADD_OBJ_TITLE: + c->name = tr("Title"); + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TEXT, EFFECT_TYPE_EFFECT))); + break; + case ADD_OBJ_SOLID: + c->name = tr("Solid Color"); + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_SOLID, EFFECT_TYPE_EFFECT))); + break; + case ADD_OBJ_BARS: + { + c->name = tr("Bars"); + EffectPtr e = create_effect(c, get_internal_meta(EFFECT_INTERNAL_SOLID, EFFECT_TYPE_EFFECT)); + e->row(0)->field(0)->set_combo_index(1); + c->effects.append(e); + } + break; + case ADD_OBJ_TONE: + c->name = tr("Tone"); + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TONE, EFFECT_TYPE_EFFECT))); + break; + case ADD_OBJ_NOISE: + c->name = tr("Noise"); + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_NOISE, EFFECT_TYPE_EFFECT))); + break; + } - if (c->track >= 0 && olive::CurrentConfig.add_default_effects_to_clips) { - // default audio effects (after custom effects) - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_VOLUME, EFFECT_TYPE_EFFECT))); - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_PAN, EFFECT_TYPE_EFFECT))); - } + if (c->track >= 0 && olive::CurrentConfig.add_default_effects_to_clips) { + // default audio effects (after custom effects) + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_VOLUME, EFFECT_TYPE_EFFECT))); + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_PAN, EFFECT_TYPE_EFFECT))); + } - push_undo = true; + push_undo = true; - if (!shift) { - panel_timeline->creating = false; - } - } - } - } else if (panel_timeline->moving_proc) { - bool process_moving = false; + if (!shift) { + panel_timeline->creating = false; + } + } + } + } else if (panel_timeline->moving_proc) { + bool process_moving = false; - for (int i=0;ighosts.size();i++) { - const Ghost& g = panel_timeline->ghosts.at(i); - if (g.in != g.old_in - || g.out != g.old_out - || g.clip_in != g.old_clip_in - || g.track != g.old_track) { - process_moving = true; - break; - } - } + for (int i=0;ighosts.size();i++) { + const Ghost& g = panel_timeline->ghosts.at(i); + if (g.in != g.old_in + || g.out != g.old_out + || g.clip_in != g.old_clip_in + || g.track != g.old_track) { + process_moving = true; + break; + } + } - if (process_moving) { - const Ghost& first_ghost = panel_timeline->ghosts.at(0); + if (process_moving) { + const Ghost& first_ghost = panel_timeline->ghosts.at(0); - // if we were RIPPLING, move all the clips - if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) { - long ripple_length, ripple_point; + // if we were RIPPLING, move all the clips + if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) { + long ripple_length, ripple_point; - // ripple_length becomes the length/number of frames we trimmed - // ripple point becomes the point to ripple (i.e. the point after or before which we move every clip) - if (panel_timeline->trim_in_point) { - ripple_length = first_ghost.old_in - first_ghost.in; - ripple_point = first_ghost.old_in; + // ripple_length becomes the length/number of frames we trimmed + // ripple point becomes the point to ripple (i.e. the point after or before which we move every clip) + if (panel_timeline->trim_in_point) { + ripple_length = first_ghost.old_in - first_ghost.in; + ripple_point = first_ghost.old_in; - for (int i=0;iselections.size();i++) { - olive::ActiveSequence->selections[i].in += ripple_length; - olive::ActiveSequence->selections[i].out += ripple_length; - } - } else { - // if we're trimming an out-point - ripple_length = first_ghost.old_out - panel_timeline->ghosts.at(0).out; - ripple_point = first_ghost.old_out; - } - QVector ignore_clips; - for (int i=0;ighosts.size();i++) { - const Ghost& g = panel_timeline->ghosts.at(i); + for (int i=0;iselections.size();i++) { + olive::ActiveSequence->selections[i].in += ripple_length; + olive::ActiveSequence->selections[i].out += ripple_length; + } + } else { + // if we're trimming an out-point + ripple_length = first_ghost.old_out - panel_timeline->ghosts.at(0).out; + ripple_point = first_ghost.old_out; + } + QVector ignore_clips; + for (int i=0;ighosts.size();i++) { + const Ghost& g = panel_timeline->ghosts.at(i); - // push rippled clips forward if necessary - if (panel_timeline->trim_in_point) { - ignore_clips.append(g.clip); - panel_timeline->ghosts[i].in += ripple_length; - panel_timeline->ghosts[i].out += ripple_length; - } + // push rippled clips forward if necessary + if (panel_timeline->trim_in_point) { + ignore_clips.append(g.clip); + panel_timeline->ghosts[i].in += ripple_length; + panel_timeline->ghosts[i].out += ripple_length; + } - long comp_point = panel_timeline->trim_in_point ? g.old_in : g.old_out; - ripple_point = qMin(ripple_point, comp_point); - } - if (!panel_timeline->trim_in_point) ripple_length = -ripple_length; + long comp_point = panel_timeline->trim_in_point ? g.old_in : g.old_out; + ripple_point = qMin(ripple_point, comp_point); + } + if (!panel_timeline->trim_in_point) ripple_length = -ripple_length; - ripple_clips(ca, olive::ActiveSequence, ripple_point, ripple_length, ignore_clips); - } + ripple_clips(ca, olive::ActiveSequence, ripple_point, ripple_length, ignore_clips); + } - if (panel_timeline->tool == TIMELINE_TOOL_POINTER - && (event->modifiers() & Qt::AltModifier) - && panel_timeline->trim_target == -1) { // if holding alt (and not trimming), duplicate rather than move - // duplicate clips - QVector old_clips; - QVector new_clips; - QVector delete_areas; - for (int i=0;ighosts.size();i++) { - const Ghost& g = panel_timeline->ghosts.at(i); - if (g.old_in != g.in || g.old_out != g.out || g.track != g.old_track || g.clip_in != g.old_clip_in) { - // create copy of clip - ClipPtr c(olive::ActiveSequence->clips.at(g.clip)->copy(olive::ActiveSequence)); + if (panel_timeline->tool == TIMELINE_TOOL_POINTER + && (event->modifiers() & Qt::AltModifier) + && panel_timeline->trim_target == -1) { // if holding alt (and not trimming), duplicate rather than move + // duplicate clips + QVector old_clips; + QVector new_clips; + QVector delete_areas; + for (int i=0;ighosts.size();i++) { + const Ghost& g = panel_timeline->ghosts.at(i); + if (g.old_in != g.in || g.old_out != g.out || g.track != g.old_track || g.clip_in != g.old_clip_in) { + // create copy of clip + ClipPtr c(olive::ActiveSequence->clips.at(g.clip)->copy(olive::ActiveSequence)); - 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; - Selection s; - s.in = g.in; - s.out = g.out; - s.track = g.track; - delete_areas.append(s); + Selection s; + s.in = g.in; + s.out = g.out; + s.track = g.track; + delete_areas.append(s); - old_clips.append(g.clip); - new_clips.append(c); - } - } - if (new_clips.size() > 0) { - panel_timeline->delete_areas_and_relink(ca, delete_areas, false); + old_clips.append(g.clip); + new_clips.append(c); + } + } + if (new_clips.size() > 0) { + panel_timeline->delete_areas_and_relink(ca, delete_areas, false); - // relink duplicated clips - panel_timeline->relink_clips_using_ids(old_clips, new_clips); + // relink duplicated clips + panel_timeline->relink_clips_using_ids(old_clips, new_clips); - ca->append(new AddClipCommand(olive::ActiveSequence, new_clips)); - } - } else { - // INSERT if holding ctrl - if (panel_timeline->tool == TIMELINE_TOOL_POINTER && ctrl) { - insert_clips(ca); - } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->tool == TIMELINE_TOOL_SLIDE) { - // move clips - QVector delete_areas; - for (int i=0;ighosts.size();i++) { - // step 1 - set clips that are moving to "undeletable" (to avoid step 2 deleting any part of them) - const Ghost& g = panel_timeline->ghosts.at(i); + ca->append(new AddClipCommand(olive::ActiveSequence, new_clips)); + } + } else { + // INSERT if holding ctrl + if (panel_timeline->tool == TIMELINE_TOOL_POINTER && ctrl) { + insert_clips(ca); + } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->tool == TIMELINE_TOOL_SLIDE) { + // move clips + QVector delete_areas; + for (int i=0;ighosts.size();i++) { + // step 1 - set clips that are moving to "undeletable" (to avoid step 2 deleting any part of them) + const Ghost& g = panel_timeline->ghosts.at(i); - olive::ActiveSequence->clips.at(g.clip)->undeletable = true; - if (g.transition != nullptr) { - g.transition->parent_clip->undeletable = true; - if (g.transition->secondary_clip != nullptr) g.transition->secondary_clip->undeletable = true; - } + olive::ActiveSequence->clips.at(g.clip)->undeletable = true; + if (g.transition != nullptr) { + g.transition->parent_clip->undeletable = true; + if (g.transition->secondary_clip != nullptr) g.transition->secondary_clip->undeletable = true; + } - Selection s; - s.in = g.in; - s.out = g.out; - s.track = g.track; - delete_areas.append(s); - } - panel_timeline->delete_areas_and_relink(ca, delete_areas, false); - for (int i=0;ighosts.size();i++) { - const Ghost& g = panel_timeline->ghosts.at(i); - olive::ActiveSequence->clips.at(g.clip)->undeletable = false; - if (g.transition != nullptr) { - g.transition->parent_clip->undeletable = false; - if (g.transition->secondary_clip != nullptr) g.transition->secondary_clip->undeletable = false; - } - } - } - for (int i=0;ighosts.size();i++) { - Ghost& g = panel_timeline->ghosts[i]; + Selection s; + s.in = g.in; + s.out = g.out; + s.track = g.track; + delete_areas.append(s); + } + panel_timeline->delete_areas_and_relink(ca, delete_areas, false); + for (int i=0;ighosts.size();i++) { + const Ghost& g = panel_timeline->ghosts.at(i); + olive::ActiveSequence->clips.at(g.clip)->undeletable = false; + if (g.transition != nullptr) { + g.transition->parent_clip->undeletable = false; + if (g.transition->secondary_clip != nullptr) g.transition->secondary_clip->undeletable = false; + } + } + } + for (int i=0;ighosts.size();i++) { + Ghost& g = panel_timeline->ghosts[i]; - // step 3 - move clips - ClipPtr c = olive::ActiveSequence->clips.at(g.clip); - if (g.transition == nullptr) { - move_clip(ca, c, (g.in - g.old_in), (g.out - g.old_out), (g.clip_in - g.old_clip_in), (g.track - g.old_track), true, true); + // step 3 - move clips + ClipPtr c = olive::ActiveSequence->clips.at(g.clip); + if (g.transition == nullptr) { + move_clip(ca, c, (g.in - g.old_in), (g.out - g.old_out), (g.clip_in - g.old_clip_in), (g.track - g.old_track), true, true); - // adjust transitions if we need to - long new_clip_length = (g.out - g.in); - if (c->get_opening_transition() != nullptr) { - long max_open_length = new_clip_length; - if (c->get_closing_transition() != nullptr && !panel_timeline->trim_in_point) { - max_open_length -= c->get_closing_transition()->get_true_length(); - } - if (max_open_length <= 0) { - ca->append(new DeleteTransitionCommand(c->opening_transition)); - } else if (c->get_opening_transition()->get_true_length() > max_open_length) { - ca->append(new ModifyTransitionCommand(c->opening_transition, max_open_length)); - } - } - if (c->get_closing_transition() != nullptr) { - long max_open_length = new_clip_length; - if (c->get_opening_transition() != nullptr && panel_timeline->trim_in_point) { - max_open_length -= c->get_opening_transition()->get_true_length(); - } - if (max_open_length <= 0) { - ca->append(new DeleteTransitionCommand(c->closing_transition)); - } else if (c->get_closing_transition()->get_true_length() > max_open_length) { - ca->append(new ModifyTransitionCommand(c->closing_transition, max_open_length)); - } - } - } else { - bool is_opening_transition = (g.transition == c->get_opening_transition()); - long new_transition_length = g.out - g.in; - if (g.transition->secondary_clip != nullptr) new_transition_length >>= 1; - ca->append(new ModifyTransitionCommand(is_opening_transition ? c->opening_transition : c->closing_transition, new_transition_length)); + // adjust transitions if we need to + long new_clip_length = (g.out - g.in); + if (c->get_opening_transition() != nullptr) { + long max_open_length = new_clip_length; + if (c->get_closing_transition() != nullptr && !panel_timeline->trim_in_point) { + max_open_length -= c->get_closing_transition()->get_true_length(); + } + if (max_open_length <= 0) { + ca->append(new DeleteTransitionCommand(c->opening_transition)); + } else if (c->get_opening_transition()->get_true_length() > max_open_length) { + ca->append(new ModifyTransitionCommand(c->opening_transition, max_open_length)); + } + } + if (c->get_closing_transition() != nullptr) { + long max_open_length = new_clip_length; + if (c->get_opening_transition() != nullptr && panel_timeline->trim_in_point) { + max_open_length -= c->get_opening_transition()->get_true_length(); + } + if (max_open_length <= 0) { + ca->append(new DeleteTransitionCommand(c->closing_transition)); + } else if (c->get_closing_transition()->get_true_length() > max_open_length) { + ca->append(new ModifyTransitionCommand(c->closing_transition, max_open_length)); + } + } + } else { + bool is_opening_transition = (g.transition == c->get_opening_transition()); + long new_transition_length = g.out - g.in; + if (g.transition->secondary_clip != nullptr) new_transition_length >>= 1; + ca->append(new ModifyTransitionCommand(is_opening_transition ? c->opening_transition : c->closing_transition, new_transition_length)); - long clip_length = c->getLength(); + long clip_length = c->getLength(); - if (g.transition->secondary_clip != nullptr) { - if (g.in != g.old_in && !g.trimming) { - long movement = g.in - g.old_in; - move_clip(ca, g.transition->parent_clip, movement, 0, movement, 0, false, true); - move_clip(ca, g.transition->secondary_clip, 0, movement, 0, 0, false, true); - } - } else if (is_opening_transition) { - if (g.in != g.old_in) { - // if transition is going to make the clip bigger, make the clip bigger - move_clip(ca, c, (g.in - g.old_in), 0, (g.clip_in - g.old_clip_in), 0, true, true); - clip_length -= (g.in - g.old_in); - } + if (g.transition->secondary_clip != nullptr) { + if (g.in != g.old_in && !g.trimming) { + long movement = g.in - g.old_in; + move_clip(ca, g.transition->parent_clip, movement, 0, movement, 0, false, true); + move_clip(ca, g.transition->secondary_clip, 0, movement, 0, 0, false, true); + } + } else if (is_opening_transition) { + if (g.in != g.old_in) { + // if transition is going to make the clip bigger, make the clip bigger + move_clip(ca, c, (g.in - g.old_in), 0, (g.clip_in - g.old_clip_in), 0, true, true); + clip_length -= (g.in - g.old_in); + } - make_room_for_transition(ca, c, kTransitionOpening, g.in, g.out, false); - } else { - if (g.out != g.old_out) { - // if transition is going to make the clip bigger, make the clip bigger - move_clip(ca, c, 0, (g.out - g.old_out), 0, 0, true, true); - clip_length += (g.out - g.old_out); - } + make_room_for_transition(ca, c, kTransitionOpening, g.in, g.out, false); + } else { + if (g.out != g.old_out) { + // if transition is going to make the clip bigger, make the clip bigger + move_clip(ca, c, 0, (g.out - g.old_out), 0, 0, true, true); + clip_length += (g.out - g.old_out); + } - make_room_for_transition(ca, c, kTransitionClosing, g.in, g.out, false); - } - } - } - } - push_undo = true; - } - } else if (panel_timeline->selecting || panel_timeline->rect_select_proc) { - } else if (panel_timeline->transition_tool_proc) { - const Ghost& g = panel_timeline->ghosts.at(0); + make_room_for_transition(ca, c, kTransitionClosing, g.in, g.out, false); + } + } + } + } + push_undo = true; + } + } else if (panel_timeline->selecting || panel_timeline->rect_select_proc) { + } else if (panel_timeline->transition_tool_proc) { + const Ghost& g = panel_timeline->ghosts.at(0); - if (g.in != g.out) { - long transition_start = qMin(g.in, g.out); - long transition_end = qMax(g.in, g.out); + if (g.in != g.out) { + long transition_start = qMin(g.in, g.out); + long transition_end = qMax(g.in, g.out); - ClipPtr pre = olive::ActiveSequence->clips.at(g.clip); - ClipPtr post = pre; + ClipPtr pre = olive::ActiveSequence->clips.at(g.clip); + ClipPtr post = pre; - make_room_for_transition(ca, pre, panel_timeline->transition_tool_type, transition_start, transition_end, true); + make_room_for_transition(ca, pre, panel_timeline->transition_tool_type, transition_start, transition_end, true); - if (panel_timeline->transition_tool_post_clip > -1) { - post = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_post_clip); - int opposite_type = (panel_timeline->transition_tool_type == kTransitionOpening) ? kTransitionClosing : kTransitionOpening; - make_room_for_transition( - ca, - post, - opposite_type, - transition_start, - transition_end, - true - ); + if (panel_timeline->transition_tool_post_clip > -1) { + post = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_post_clip); + int opposite_type = (panel_timeline->transition_tool_type == kTransitionOpening) ? kTransitionClosing : kTransitionOpening; + make_room_for_transition( + ca, + post, + opposite_type, + transition_start, + transition_end, + true + ); - if (panel_timeline->transition_tool_type == kTransitionClosing) { - // swap - ClipPtr temp = pre; - pre = post; - post = temp; - } - } + if (panel_timeline->transition_tool_type == kTransitionClosing) { + // swap + ClipPtr temp = pre; + pre = post; + post = temp; + } + } - if (transition_start < post->timeline_in || transition_end > pre->timeline_out) { - // delete shit over there and extend timeline in - QVector areas; - Selection s; - s.track = post->track; + if (transition_start < post->timeline_in || transition_end > pre->timeline_out) { + // delete shit over there and extend timeline in + QVector areas; + Selection s; + s.track = post->track; - bool move_post = false; - bool move_pre = false; + bool move_post = false; + bool move_pre = false; - if (transition_start < post->timeline_in) { - s.in = transition_start; - s.out = post->timeline_in; - areas.append(s); - move_post = true; - } - if (transition_end > pre->timeline_out) { - s.in = pre->timeline_out; - s.out = transition_end; - areas.append(s); - move_pre = true; - } + if (transition_start < post->timeline_in) { + s.in = transition_start; + s.out = post->timeline_in; + areas.append(s); + move_post = true; + } + if (transition_end > pre->timeline_out) { + s.in = pre->timeline_out; + s.out = transition_end; + areas.append(s); + move_pre = true; + } - panel_timeline->delete_areas_and_relink(ca, areas, false); + panel_timeline->delete_areas_and_relink(ca, areas, false); - if (move_post) move_clip(ca, post, qMin(transition_start, post->timeline_in), post->timeline_out, post->clip_in - (post->timeline_in - transition_start), post->track); - if (move_pre) move_clip(ca, pre, pre->timeline_in, qMax(transition_end, pre->timeline_out), pre->clip_in, pre->track); - } + if (move_post) move_clip(ca, post, qMin(transition_start, post->timeline_in), post->timeline_out, post->clip_in - (post->timeline_in - transition_start), post->track); + if (move_pre) move_clip(ca, pre, pre->timeline_in, qMax(transition_end, pre->timeline_out), pre->clip_in, pre->track); + } - if (panel_timeline->transition_tool_post_clip > -1) { - ca->append(new AddTransitionCommand(pre, post, nullptr, panel_timeline->transition_tool_meta, kTransitionOpening, transition_end - pre->timeline_in)); - } else { - ca->append(new AddTransitionCommand(pre, nullptr, nullptr, panel_timeline->transition_tool_meta, panel_timeline->transition_tool_type, transition_end - transition_start)); - } + if (panel_timeline->transition_tool_post_clip > -1) { + ca->append(new AddTransitionCommand(pre, post, nullptr, panel_timeline->transition_tool_meta, kTransitionOpening, transition_end - pre->timeline_in)); + } else { + ca->append(new AddTransitionCommand(pre, nullptr, nullptr, panel_timeline->transition_tool_meta, panel_timeline->transition_tool_type, transition_end - transition_start)); + } - push_undo = true; - } - } else if (panel_timeline->splitting) { - bool split = false; - for (int i=0;isplit_tracks.size();i++) { - int split_index = getClipIndexFromCoords(panel_timeline->drag_frame_start, panel_timeline->split_tracks.at(i)); - if (split_index > -1 && panel_timeline->split_clip_and_relink(ca, split_index, panel_timeline->drag_frame_start, !alt)) { - split = true; - } - } - if (split) { - push_undo = true; - } - panel_timeline->split_cache.clear(); - } + push_undo = true; + } + } else if (panel_timeline->splitting) { + bool split = false; + for (int i=0;isplit_tracks.size();i++) { + int split_index = getClipIndexFromCoords(panel_timeline->drag_frame_start, panel_timeline->split_tracks.at(i)); + if (split_index > -1 && panel_timeline->split_clip_and_relink(ca, split_index, panel_timeline->drag_frame_start, !alt)) { + split = true; + } + } + if (split) { + push_undo = true; + } + panel_timeline->split_cache.clear(); + } - // remove duplicate selections - panel_timeline->clean_up_selections(olive::ActiveSequence->selections); + // remove duplicate selections + panel_timeline->clean_up_selections(olive::ActiveSequence->selections); - if (selection_command != nullptr) { - selection_command->new_data = olive::ActiveSequence->selections; - ca->append(selection_command); - selection_command = nullptr; - push_undo = true; - } + if (selection_command != nullptr) { + selection_command->new_data = olive::ActiveSequence->selections; + ca->append(selection_command); + selection_command = nullptr; + push_undo = true; + } - if (push_undo) { - olive::UndoStack.push(ca); - } else { - delete ca; - } + if (push_undo) { + olive::UndoStack.push(ca); + } else { + delete ca; + } - // destroy all ghosts - panel_timeline->ghosts.clear(); + // destroy all ghosts + panel_timeline->ghosts.clear(); - // clear split tracks - panel_timeline->split_tracks.clear(); + // clear split tracks + panel_timeline->split_tracks.clear(); - panel_timeline->selecting = false; - panel_timeline->moving_proc = false; - panel_timeline->moving_init = false; - panel_timeline->splitting = false; - panel_timeline->snapped = false; - panel_timeline->rect_select_init = false; - panel_timeline->rect_select_proc = false; - panel_timeline->transition_tool_init = false; - panel_timeline->transition_tool_proc = 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; + panel_timeline->rect_select_init = false; + panel_timeline->rect_select_proc = false; + panel_timeline->transition_tool_init = false; + panel_timeline->transition_tool_proc = false; + pre_clips.clear(); + post_clips.clear(); - update_ui(true); - } - panel_timeline->hand_moving = false; - } + update_ui(true); + } + panel_timeline->hand_moving = false; + } } void TimelineWidget::init_ghosts() { - for (int i=0;ighosts.size();i++) { - Ghost& g = panel_timeline->ghosts[i]; - ClipPtr c = olive::ActiveSequence->clips.at(g.clip); + for (int i=0;ighosts.size();i++) { + Ghost& g = panel_timeline->ghosts[i]; + ClipPtr c = olive::ActiveSequence->clips.at(g.clip); - g.track = g.old_track = c->track; - g.clip_in = g.old_clip_in = c->clip_in; + g.track = g.old_track = c->track; + g.clip_in = g.old_clip_in = c->clip_in; - if (panel_timeline->tool == TIMELINE_TOOL_SLIP) { - g.clip_in = g.old_clip_in = c->get_clip_in_with_transition(); - g.in = g.old_in = c->get_timeline_in_with_transition(); - g.out = g.old_out = c->get_timeline_out_with_transition(); - g.ghost_length = g.old_out - g.old_in; - } else if (g.transition == nullptr) { - // this ghost is for a clip - g.in = g.old_in = c->timeline_in; - g.out = g.old_out = c->timeline_out; - g.ghost_length = g.old_out - g.old_in; - } else if (g.transition == c->get_opening_transition()) { - g.in = g.old_in = c->get_timeline_in_with_transition(); - g.ghost_length = c->get_opening_transition()->get_length(); - g.out = g.old_out = g.in + g.ghost_length; - } else if (g.transition == c->get_closing_transition()) { - g.out = g.old_out = c->get_timeline_out_with_transition(); - g.ghost_length = c->get_closing_transition()->get_length(); - g.in = g.old_in = g.out - g.ghost_length; - g.clip_in = g.old_clip_in = c->clip_in + c->getLength() - c->get_closing_transition()->get_true_length(); - } + if (panel_timeline->tool == TIMELINE_TOOL_SLIP) { + g.clip_in = g.old_clip_in = c->get_clip_in_with_transition(); + g.in = g.old_in = c->get_timeline_in_with_transition(); + g.out = g.old_out = c->get_timeline_out_with_transition(); + g.ghost_length = g.old_out - g.old_in; + } else if (g.transition == nullptr) { + // this ghost is for a clip + g.in = g.old_in = c->timeline_in; + g.out = g.old_out = c->timeline_out; + g.ghost_length = g.old_out - g.old_in; + } else if (g.transition == c->get_opening_transition()) { + g.in = g.old_in = c->get_timeline_in_with_transition(); + g.ghost_length = c->get_opening_transition()->get_length(); + g.out = g.old_out = g.in + g.ghost_length; + } else if (g.transition == c->get_closing_transition()) { + g.out = g.old_out = c->get_timeline_out_with_transition(); + g.ghost_length = c->get_closing_transition()->get_length(); + g.in = g.old_in = g.out - g.ghost_length; + g.clip_in = g.old_clip_in = c->clip_in + c->getLength() - c->get_closing_transition()->get_true_length(); + } - // used for trim ops - c->recalculateMaxLength(); - g.media_length = c->getMaximumLength(); - } - for (int i=0;iselections.size();i++) { - Selection& s = olive::ActiveSequence->selections[i]; - s.old_in = s.in; - s.old_out = s.out; - s.old_track = s.track; - } + // used for trim ops + c->recalculateMaxLength(); + g.media_length = c->getMaximumLength(); + } + for (int i=0;iselections.size();i++) { + Selection& s = olive::ActiveSequence->selections[i]; + s.old_in = s.in; + s.old_out = s.out; + s.old_track = s.track; + } } void validate_transitions(ClipPtr c, int transition_type, long& frame_diff) { - long validator; + long validator; - if (transition_type == kTransitionOpening) { - // prevent from going below 0 on the timeline - validator = c->timeline_in + frame_diff; - if (validator < 0) frame_diff -= validator; + if (transition_type == kTransitionOpening) { + // prevent from going below 0 on the timeline + validator = c->timeline_in + frame_diff; + if (validator < 0) frame_diff -= validator; - // prevent from going below 0 for the media - validator = c->clip_in + frame_diff; - if (validator < 0) frame_diff -= validator; + // prevent from going below 0 for the media + validator = c->clip_in + frame_diff; + if (validator < 0) frame_diff -= validator; - // prevent transition from exceeding media length - validator -= c->getMaximumLength(); - if (validator > 0) frame_diff -= validator; - } else { - // prevent from going below 0 on the timeline - validator = c->timeline_out + frame_diff; - if (validator < 0) frame_diff -= validator; + // prevent transition from exceeding media length + validator -= c->getMaximumLength(); + if (validator > 0) frame_diff -= validator; + } else { + // prevent from going below 0 on the timeline + validator = c->timeline_out + frame_diff; + if (validator < 0) frame_diff -= validator; - // prevent from going below 0 for the media - validator = c->clip_in + c->getLength() + frame_diff; - if (validator < 0) frame_diff -= validator; + // prevent from going below 0 for the media + validator = c->clip_in + c->getLength() + frame_diff; + if (validator < 0) frame_diff -= validator; - // prevent transition from exceeding media length - validator -= c->getMaximumLength(); - if (validator > 0) frame_diff -= validator; - } + // prevent transition from exceeding media length + validator -= c->getMaximumLength(); + if (validator > 0) frame_diff -= validator; + } } void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { - int effective_tool = panel_timeline->tool; - if (panel_timeline->importing || panel_timeline->creating) effective_tool = TIMELINE_TOOL_POINTER; + int effective_tool = panel_timeline->tool; + if (panel_timeline->importing || panel_timeline->creating) effective_tool = TIMELINE_TOOL_POINTER; - int mouse_track = getTrackFromScreenPoint(mouse_pos.y()); - long frame_diff = (lock_frame) ? 0 : panel_timeline->getTimelineFrameFromScreenPoint(mouse_pos.x()) - panel_timeline->drag_frame_start; - int track_diff = ((effective_tool == TIMELINE_TOOL_SLIDE || panel_timeline->transition_select != kTransitionNone) && !panel_timeline->importing) ? 0 : mouse_track - panel_timeline->drag_track_start; - long validator; - long earliest_in_point = LONG_MAX; + int mouse_track = getTrackFromScreenPoint(mouse_pos.y()); + long frame_diff = (lock_frame) ? 0 : panel_timeline->getTimelineFrameFromScreenPoint(mouse_pos.x()) - panel_timeline->drag_frame_start; + int track_diff = ((effective_tool == TIMELINE_TOOL_SLIDE || panel_timeline->transition_select != kTransitionNone) && !panel_timeline->importing) ? 0 : mouse_track - panel_timeline->drag_track_start; + long validator; + long earliest_in_point = LONG_MAX; - // first try to snap - long fm; + // first try to snap + long fm; - if (effective_tool != TIMELINE_TOOL_SLIP) { - // slipping doesn't move the clips so we don't bother snapping for it - for (int i=0;ighosts.size();i++) { - const Ghost& g = panel_timeline->ghosts.at(i); + if (effective_tool != TIMELINE_TOOL_SLIP) { + // slipping doesn't move the clips so we don't bother snapping for it + for (int i=0;ighosts.size();i++) { + const Ghost& g = panel_timeline->ghosts.at(i); - // snap ghost's in point - if (panel_timeline->trim_target == -1 || g.trim_in) { - fm = g.old_in + frame_diff; - if (panel_timeline->snap_to_timeline(&fm, true, true, true)) { - frame_diff = fm - g.old_in; - break; - } - } + // snap ghost's in point + if (panel_timeline->trim_target == -1 || g.trim_in) { + fm = g.old_in + frame_diff; + if (panel_timeline->snap_to_timeline(&fm, true, true, true)) { + frame_diff = fm - g.old_in; + break; + } + } - // snap ghost's out point - if (panel_timeline->trim_target == -1 || !g.trim_in) { - fm = g.old_out + frame_diff; - if (panel_timeline->snap_to_timeline(&fm, true, true, true)) { - frame_diff = fm - g.old_out; - break; - } - } + // snap ghost's out point + if (panel_timeline->trim_target == -1 || !g.trim_in) { + fm = g.old_out + frame_diff; + if (panel_timeline->snap_to_timeline(&fm, true, true, true)) { + frame_diff = fm - g.old_out; + break; + } + } - // if the ghost is attached to a clip, snap its markers too - if (panel_timeline->trim_target == -1 && g.clip >= 0) { - ClipPtr c = olive::ActiveSequence->clips.at(g.clip); - for (int j=0;jget_markers().size();j++) { - long marker_real_time = c->get_markers().at(j).frame + c->timeline_in - c->clip_in; - fm = marker_real_time + frame_diff; - if (panel_timeline->snap_to_timeline(&fm, true, true, true)) { - frame_diff = fm - marker_real_time; - break; - } - } - } - } - } + // if the ghost is attached to a clip, snap its markers too + if (panel_timeline->trim_target == -1 && g.clip >= 0) { + ClipPtr c = olive::ActiveSequence->clips.at(g.clip); + for (int j=0;jget_markers().size();j++) { + long marker_real_time = c->get_markers().at(j).frame + c->timeline_in - c->clip_in; + fm = marker_real_time + frame_diff; + if (panel_timeline->snap_to_timeline(&fm, true, true, true)) { + frame_diff = fm - marker_real_time; + break; + } + } + } + } + } - bool clips_are_movable = (effective_tool == TIMELINE_TOOL_POINTER || effective_tool == TIMELINE_TOOL_SLIDE); + bool clips_are_movable = (effective_tool == TIMELINE_TOOL_POINTER || effective_tool == TIMELINE_TOOL_SLIDE); - // validate ghosts - long temp_frame_diff = frame_diff; // cache to see if we change it (thus cancelling any snap) - for (int i=0;ighosts.size();i++) { - const Ghost& g = panel_timeline->ghosts.at(i); - ClipPtr c = nullptr; - if (g.clip != -1) c = olive::ActiveSequence->clips.at(g.clip); + // validate ghosts + long temp_frame_diff = frame_diff; // cache to see if we change it (thus cancelling any snap) + for (int i=0;ighosts.size();i++) { + const Ghost& g = panel_timeline->ghosts.at(i); + ClipPtr c = nullptr; + if (g.clip != -1) c = olive::ActiveSequence->clips.at(g.clip); - const FootageStream* ms = nullptr; - if (g.clip != -1 && c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { - ms = c->media->to_footage()->get_stream_from_file_index(c->track < 0, c->media_stream); - } + const FootageStream* ms = nullptr; + if (g.clip != -1 && c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { + ms = c->media->to_footage()->get_stream_from_file_index(c->track < 0, c->media_stream); + } - // validate ghosts for trimming - if (panel_timeline->creating) { - // i feel like we might need something here but we haven't so far? - } else if (effective_tool == TIMELINE_TOOL_SLIP) { - if ((c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) - || (ms != nullptr && !ms->infinite_length)) { - // prevent slip moving a clip below 0 clip_in - validator = g.old_clip_in - frame_diff; - if (validator < 0) frame_diff += validator; + // validate ghosts for trimming + if (panel_timeline->creating) { + // i feel like we might need something here but we haven't so far? + } else if (effective_tool == TIMELINE_TOOL_SLIP) { + if ((c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) + || (ms != nullptr && !ms->infinite_length)) { + // prevent slip moving a clip below 0 clip_in + validator = g.old_clip_in - frame_diff; + if (validator < 0) frame_diff += validator; - // prevent slip moving clip beyond media length - validator += g.ghost_length; - if (validator > g.media_length) frame_diff += validator - g.media_length; - } - } else if (g.trimming) { - if (g.trim_in) { - // prevent clip/transition length from being less than 1 frame long - validator = g.ghost_length - frame_diff; - if (validator < 1) frame_diff -= (1 - validator); + // prevent slip moving clip beyond media length + validator += g.ghost_length; + if (validator > g.media_length) frame_diff += validator - g.media_length; + } + } else if (g.trimming) { + if (g.trim_in) { + // prevent clip/transition length from being less than 1 frame long + validator = g.ghost_length - frame_diff; + if (validator < 1) frame_diff -= (1 - validator); - // prevent timeline in from going below 0 - if (effective_tool != TIMELINE_TOOL_RIPPLE) { - validator = g.old_in + frame_diff; - if (validator < 0) frame_diff -= validator; - } + // prevent timeline in from going below 0 + if (effective_tool != TIMELINE_TOOL_RIPPLE) { + validator = g.old_in + frame_diff; + if (validator < 0) frame_diff -= validator; + } - // prevent clip_in from going below 0 - if ((c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) - || (ms != nullptr && !ms->infinite_length)) { - validator = g.old_clip_in + frame_diff; - if (validator < 0) frame_diff -= validator; - } - } else { - // prevent clip length from being less than 1 frame long - validator = g.ghost_length + frame_diff; - if (validator < 1) frame_diff += (1 - validator); + // prevent clip_in from going below 0 + if ((c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) + || (ms != nullptr && !ms->infinite_length)) { + validator = g.old_clip_in + frame_diff; + if (validator < 0) frame_diff -= validator; + } + } else { + // prevent clip length from being less than 1 frame long + validator = g.ghost_length + frame_diff; + if (validator < 1) frame_diff += (1 - validator); - // prevent clip length exceeding media length - if ((c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) - || (ms != nullptr && !ms->infinite_length)) { - validator = g.old_clip_in + g.ghost_length + frame_diff; - if (validator > g.media_length) frame_diff -= validator - g.media_length; - } - } + // prevent clip length exceeding media length + if ((c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) + || (ms != nullptr && !ms->infinite_length)) { + validator = g.old_clip_in + g.ghost_length + frame_diff; + if (validator > g.media_length) frame_diff -= validator - g.media_length; + } + } - // prevent dual transition from going below 0 on the primary or media length on the secondary - if (g.transition != nullptr && g.transition->secondary_clip != nullptr) { - ClipPtr otc = g.transition->parent_clip; - ClipPtr ctc = g.transition->secondary_clip; + // prevent dual transition from going below 0 on the primary or media length on the secondary + if (g.transition != nullptr && g.transition->secondary_clip != nullptr) { + ClipPtr otc = g.transition->parent_clip; + ClipPtr ctc = g.transition->secondary_clip; - if (g.trim_in) { - frame_diff -= g.transition->get_true_length(); - } else { - frame_diff += g.transition->get_true_length(); - } + if (g.trim_in) { + frame_diff -= g.transition->get_true_length(); + } else { + frame_diff += g.transition->get_true_length(); + } - validate_transitions(otc, kTransitionOpening, frame_diff); - validate_transitions(ctc, kTransitionClosing, frame_diff); + validate_transitions(otc, kTransitionOpening, frame_diff); + validate_transitions(ctc, kTransitionClosing, frame_diff); - frame_diff = -frame_diff; - validate_transitions(otc, kTransitionOpening, frame_diff); - validate_transitions(ctc, kTransitionClosing, frame_diff); - frame_diff = -frame_diff; + frame_diff = -frame_diff; + validate_transitions(otc, kTransitionOpening, frame_diff); + validate_transitions(ctc, kTransitionClosing, frame_diff); + frame_diff = -frame_diff; - if (g.trim_in) { - frame_diff += g.transition->get_true_length(); - } else { - frame_diff -= g.transition->get_true_length(); - } - } + if (g.trim_in) { + frame_diff += g.transition->get_true_length(); + } else { + frame_diff -= g.transition->get_true_length(); + } + } - // ripple ops - if (effective_tool == TIMELINE_TOOL_RIPPLE) { - for (int j=0;jtrim_in_point) { - validator = post->timeline_in - frame_diff; - if (validator < 0) frame_diff += validator; - } + // prevent any rippled clip from going below 0 + if (panel_timeline->trim_in_point) { + validator = post->timeline_in - frame_diff; + if (validator < 0) frame_diff += validator; + } - // prevent any post-clips colliding with pre-clips - for (int k=0;ktrack == post->track) { - if (panel_timeline->trim_in_point) { - validator = post->timeline_in - frame_diff - pre->timeline_out; - if (validator < 0) frame_diff += validator; - } else { - validator = post->timeline_in + frame_diff - pre->timeline_out; - if (validator < 0) frame_diff -= validator; - } - } - } - } - } - } else if (clips_are_movable) { // validate ghosts for moving - // prevent clips from moving below 0 on the timeline - validator = g.old_in + frame_diff; - if (validator < 0) frame_diff -= validator; + // prevent any post-clips colliding with pre-clips + for (int k=0;ktrack == post->track) { + if (panel_timeline->trim_in_point) { + validator = post->timeline_in - frame_diff - pre->timeline_out; + if (validator < 0) frame_diff += validator; + } else { + validator = post->timeline_in + frame_diff - pre->timeline_out; + if (validator < 0) frame_diff -= validator; + } + } + } + } + } + } else if (clips_are_movable) { // validate ghosts for moving + // prevent clips from moving below 0 on the timeline + validator = g.old_in + frame_diff; + if (validator < 0) frame_diff -= validator; - if (g.transition != nullptr) { - if (g.transition->secondary_clip != nullptr) { - // prevent dual transitions from going below 0 on the primary or above media length on the secondary + if (g.transition != nullptr) { + if (g.transition->secondary_clip != nullptr) { + // prevent dual transitions from going below 0 on the primary or above media length on the secondary - validator = g.transition->parent_clip->get_clip_in_with_transition() + frame_diff; - if (validator < 0) frame_diff -= validator; + validator = g.transition->parent_clip->get_clip_in_with_transition() + frame_diff; + if (validator < 0) frame_diff -= validator; - validator = g.transition->secondary_clip->get_timeline_out_with_transition() - g.transition->secondary_clip->get_timeline_in_with_transition() - g.transition->get_length() + g.transition->secondary_clip->get_clip_in_with_transition() + frame_diff; - if (validator < 0) frame_diff -= validator; + validator = g.transition->secondary_clip->get_timeline_out_with_transition() - g.transition->secondary_clip->get_timeline_in_with_transition() - g.transition->get_length() + g.transition->secondary_clip->get_clip_in_with_transition() + frame_diff; + if (validator < 0) frame_diff -= validator; - validator = g.transition->parent_clip->clip_in + frame_diff - g.transition->parent_clip->getMaximumLength() + g.transition->get_true_length(); - if (validator > 0) frame_diff -= validator; + validator = g.transition->parent_clip->clip_in + frame_diff - g.transition->parent_clip->getMaximumLength() + g.transition->get_true_length(); + if (validator > 0) frame_diff -= validator; - validator = g.transition->secondary_clip->get_timeline_out_with_transition() - g.transition->secondary_clip->get_timeline_in_with_transition() + g.transition->secondary_clip->get_clip_in_with_transition() + frame_diff - g.transition->secondary_clip->getMaximumLength(); - if (validator > 0) frame_diff -= validator; - } else { - // prevent clip_in from going below 0 - if (c->media->get_type() == MEDIA_TYPE_SEQUENCE - || (ms != nullptr && !ms->infinite_length)) { - validator = g.old_clip_in + frame_diff; - if (validator < 0) frame_diff -= validator; - } + validator = g.transition->secondary_clip->get_timeline_out_with_transition() - g.transition->secondary_clip->get_timeline_in_with_transition() + g.transition->secondary_clip->get_clip_in_with_transition() + frame_diff - g.transition->secondary_clip->getMaximumLength(); + if (validator > 0) frame_diff -= validator; + } else { + // prevent clip_in from going below 0 + if (c->media->get_type() == MEDIA_TYPE_SEQUENCE + || (ms != nullptr && !ms->infinite_length)) { + validator = g.old_clip_in + frame_diff; + if (validator < 0) frame_diff -= validator; + } - // prevent clip length exceeding media length - if (c->media->get_type() == MEDIA_TYPE_SEQUENCE - || (ms != nullptr && !ms->infinite_length)) { - validator = g.old_clip_in + g.ghost_length + frame_diff; - if (validator > g.media_length) frame_diff -= validator - g.media_length; - } - } - } + // prevent clip length exceeding media length + if (c->media->get_type() == MEDIA_TYPE_SEQUENCE + || (ms != nullptr && !ms->infinite_length)) { + validator = g.old_clip_in + g.ghost_length + frame_diff; + if (validator > g.media_length) frame_diff -= validator - g.media_length; + } + } + } - // prevent clips from crossing tracks - if (same_sign(g.old_track, panel_timeline->drag_track_start)) { - while (!same_sign(g.old_track, g.old_track + track_diff)) { - if (g.old_track < 0) { - track_diff--; - } else { - track_diff++; - } - } - } - } else if (effective_tool == TIMELINE_TOOL_TRANSITION) { - if (panel_timeline->transition_tool_post_clip == -1) { - validate_transitions(c, panel_timeline->transition_tool_type, frame_diff); - } else { - ClipPtr otc = c; // open transition clip - ClipPtr ctc = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_post_clip); // close transition clip + // prevent clips from crossing tracks + if (same_sign(g.old_track, panel_timeline->drag_track_start)) { + while (!same_sign(g.old_track, g.old_track + track_diff)) { + if (g.old_track < 0) { + track_diff--; + } else { + track_diff++; + } + } + } + } else if (effective_tool == TIMELINE_TOOL_TRANSITION) { + if (panel_timeline->transition_tool_post_clip == -1) { + validate_transitions(c, panel_timeline->transition_tool_type, frame_diff); + } else { + ClipPtr otc = c; // open transition clip + ClipPtr ctc = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_post_clip); // close transition clip - if (panel_timeline->transition_tool_type == kTransitionClosing) { - // swap - ClipPtr temp = otc; - otc = ctc; - ctc = temp; - } + if (panel_timeline->transition_tool_type == kTransitionClosing) { + // swap + ClipPtr temp = otc; + otc = ctc; + ctc = temp; + } - // always gets a positive frame_diff - validate_transitions(otc, kTransitionOpening, frame_diff); - validate_transitions(ctc, kTransitionClosing, frame_diff); + // always gets a positive frame_diff + validate_transitions(otc, kTransitionOpening, frame_diff); + validate_transitions(ctc, kTransitionClosing, frame_diff); - // always gets a negative frame_diff - frame_diff = -frame_diff; - validate_transitions(otc, kTransitionOpening, frame_diff); - validate_transitions(ctc, kTransitionClosing, frame_diff); - frame_diff = -frame_diff; - } - } - } - if (temp_frame_diff != frame_diff) panel_timeline->snapped = false; + // always gets a negative frame_diff + frame_diff = -frame_diff; + validate_transitions(otc, kTransitionOpening, frame_diff); + validate_transitions(ctc, kTransitionClosing, frame_diff); + frame_diff = -frame_diff; + } + } + } + if (temp_frame_diff != frame_diff) panel_timeline->snapped = false; - // apply changes to ghosts - for (int i=0;ighosts.size();i++) { - Ghost& g = panel_timeline->ghosts[i]; + // apply changes to ghosts + for (int i=0;ighosts.size();i++) { + Ghost& g = panel_timeline->ghosts[i]; - if (effective_tool == TIMELINE_TOOL_SLIP) { - g.clip_in = g.old_clip_in - frame_diff; - } else if (g.trimming) { - long ghost_diff = frame_diff; + if (effective_tool == TIMELINE_TOOL_SLIP) { + g.clip_in = g.old_clip_in - frame_diff; + } else if (g.trimming) { + long ghost_diff = frame_diff; - // prevent trimming clips from overlapping each other - for (int j=0;jghosts.size();j++) { - const Ghost& comp = panel_timeline->ghosts.at(j); - if (i != j && g.track == comp.track) { - long validator; - if (g.trim_in && comp.out < g.out) { - validator = (g.old_in + ghost_diff) - comp.out; - if (validator < 0) ghost_diff -= validator; - } else if (comp.in > g.in) { - validator = (g.old_out + ghost_diff) - comp.in; - if (validator > 0) ghost_diff -= validator; - } - } - } + // prevent trimming clips from overlapping each other + for (int j=0;jghosts.size();j++) { + const Ghost& comp = panel_timeline->ghosts.at(j); + if (i != j && g.track == comp.track) { + long validator; + if (g.trim_in && comp.out < g.out) { + validator = (g.old_in + ghost_diff) - comp.out; + if (validator < 0) ghost_diff -= validator; + } else if (comp.in > g.in) { + validator = (g.old_out + ghost_diff) - comp.in; + if (validator > 0) ghost_diff -= validator; + } + } + } - // apply changes - if (g.transition != nullptr && g.transition->secondary_clip != nullptr) { - if (g.trim_in) ghost_diff = -ghost_diff; - g.in = g.old_in - ghost_diff; - g.out = g.old_out + ghost_diff; - } else if (g.trim_in) { - g.in = g.old_in + ghost_diff; - g.clip_in = g.old_clip_in + ghost_diff; - } else { - g.out = g.old_out + ghost_diff; - } - } else if (clips_are_movable) { - g.track = g.old_track; - g.in = g.old_in + frame_diff; - g.out = g.old_out + frame_diff; + // apply changes + if (g.transition != nullptr && g.transition->secondary_clip != nullptr) { + if (g.trim_in) ghost_diff = -ghost_diff; + g.in = g.old_in - ghost_diff; + g.out = g.old_out + ghost_diff; + } else if (g.trim_in) { + g.in = g.old_in + ghost_diff; + g.clip_in = g.old_clip_in + ghost_diff; + } else { + g.out = g.old_out + ghost_diff; + } + } else if (clips_are_movable) { + g.track = g.old_track; + g.in = g.old_in + frame_diff; + g.out = g.old_out + frame_diff; - if (g.transition != nullptr && g.transition == olive::ActiveSequence->clips.at(g.clip)->get_opening_transition()) { - g.clip_in = g.old_clip_in + frame_diff; - } + if (g.transition != nullptr && g.transition == olive::ActiveSequence->clips.at(g.clip)->get_opening_transition()) { + g.clip_in = g.old_clip_in + frame_diff; + } - if (panel_timeline->importing) { - if ((panel_timeline->video_ghosts && mouse_track < 0) - || (panel_timeline->audio_ghosts && mouse_track >= 0)) { - int abs_track_diff = abs(track_diff); - if (g.old_track < 0) { // clip is video - g.track -= abs_track_diff; - } else { // clip is audio - g.track += abs_track_diff; - } - } - } else if (same_sign(g.old_track, panel_timeline->drag_track_start)) { - g.track += track_diff; - } - } else if (effective_tool == TIMELINE_TOOL_TRANSITION) { - if (panel_timeline->transition_tool_post_clip > -1) { - g.in = g.old_in - frame_diff; - g.out = g.old_out + frame_diff; - } else if (panel_timeline->transition_tool_type == kTransitionOpening) { - g.out = g.old_out + frame_diff; - } else { - g.in = g.old_in + frame_diff; - } - } + if (panel_timeline->importing) { + if ((panel_timeline->video_ghosts && mouse_track < 0) + || (panel_timeline->audio_ghosts && mouse_track >= 0)) { + int abs_track_diff = abs(track_diff); + if (g.old_track < 0) { // clip is video + g.track -= abs_track_diff; + } else { // clip is audio + g.track += abs_track_diff; + } + } + } else if (same_sign(g.old_track, panel_timeline->drag_track_start)) { + g.track += track_diff; + } + } else if (effective_tool == TIMELINE_TOOL_TRANSITION) { + if (panel_timeline->transition_tool_post_clip > -1) { + g.in = g.old_in - frame_diff; + g.out = g.old_out + frame_diff; + } else if (panel_timeline->transition_tool_type == kTransitionOpening) { + g.out = g.old_out + frame_diff; + } else { + g.in = g.old_in + frame_diff; + } + } - earliest_in_point = qMin(earliest_in_point, g.in); - } + earliest_in_point = qMin(earliest_in_point, g.in); + } - // apply changes to selections - if (effective_tool != TIMELINE_TOOL_SLIP && !panel_timeline->importing && !panel_timeline->creating) { + // apply changes to selections + if (effective_tool != TIMELINE_TOOL_SLIP && !panel_timeline->importing && !panel_timeline->creating) { + for (int i=0;iselections.size();i++) { + Selection& s = olive::ActiveSequence->selections[i]; + if (panel_timeline->trim_target > -1) { + if (panel_timeline->trim_in_point) { + s.in = s.old_in + frame_diff; + } else { + s.out = s.old_out + frame_diff; + } + } else if (clips_are_movable) { for (int i=0;iselections.size();i++) { - Selection& s = olive::ActiveSequence->selections[i]; - if (panel_timeline->trim_target > -1) { - if (panel_timeline->trim_in_point) { - s.in = s.old_in + frame_diff; - } else { - s.out = s.old_out + frame_diff; - } - } else if (clips_are_movable) { - for (int i=0;iselections.size();i++) { - Selection& s = olive::ActiveSequence->selections[i]; - s.in = s.old_in + frame_diff; - s.out = s.old_out + frame_diff; - s.track = s.old_track; + Selection& s = olive::ActiveSequence->selections[i]; + s.in = s.old_in + frame_diff; + s.out = s.old_out + frame_diff; + s.track = s.old_track; - if (panel_timeline->importing) { - int abs_track_diff = abs(track_diff); - if (s.old_track < 0) { - s.track -= abs_track_diff; - } else { - s.track += abs_track_diff; - } - } else { - if (same_sign(s.track, panel_timeline->drag_track_start)) s.track += track_diff; - } - } - } - } - } + if (panel_timeline->importing) { + int abs_track_diff = abs(track_diff); + if (s.old_track < 0) { + s.track -= abs_track_diff; + } else { + s.track += abs_track_diff; + } + } else { + if (same_sign(s.track, panel_timeline->drag_track_start)) s.track += track_diff; + } + } + } + } + } - if (panel_timeline->importing) { - QToolTip::showText(mapToGlobal(mouse_pos), frame_to_timecode(earliest_in_point, olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate)); - } else { - QString tip = ((frame_diff < 0) ? "-" : "+") + frame_to_timecode(qAbs(frame_diff), olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate); - if (panel_timeline->trim_target > -1) { - // find which clip is being moved - const Ghost* g = nullptr; - for (int i=0;ighosts.size();i++) { - if (panel_timeline->ghosts.at(i).clip == panel_timeline->trim_target) { - g = &panel_timeline->ghosts.at(i); - break; - } - } + if (panel_timeline->importing) { + QToolTip::showText(mapToGlobal(mouse_pos), frame_to_timecode(earliest_in_point, olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate)); + } else { + QString tip = ((frame_diff < 0) ? "-" : "+") + frame_to_timecode(qAbs(frame_diff), olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate); + if (panel_timeline->trim_target > -1) { + // find which clip is being moved + const Ghost* g = nullptr; + for (int i=0;ighosts.size();i++) { + if (panel_timeline->ghosts.at(i).clip == panel_timeline->trim_target) { + g = &panel_timeline->ghosts.at(i); + break; + } + } - if (g != nullptr) { - tip += " " + tr("Duration:") + " "; - long len = (g->old_out-g->old_in); - if (panel_timeline->trim_in_point) { - len -= frame_diff; - } else { - len += frame_diff; - } - tip += frame_to_timecode(len, olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate); - } - } - QToolTip::showText(mapToGlobal(mouse_pos), tip); - } + if (g != nullptr) { + tip += " " + tr("Duration:") + " "; + long len = (g->old_out-g->old_in); + if (panel_timeline->trim_in_point) { + len -= frame_diff; + } else { + len += frame_diff; + } + tip += frame_to_timecode(len, olive::CurrentConfig.timecode_view, olive::ActiveSequence->frame_rate); + } + } + QToolTip::showText(mapToGlobal(mouse_pos), tip); + } } void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { - tooltip_timer.stop(); - if (olive::ActiveSequence != nullptr) { - bool alt = (event->modifiers() & Qt::AltModifier); - - panel_timeline->cursor_frame = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x()); - panel_timeline->cursor_track = getTrackFromScreenPoint(event->pos().y()); - - panel_timeline->move_insert = ((event->modifiers() & Qt::ControlModifier) && (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->importing || panel_timeline->creating)); - - if (!panel_timeline->moving_init) track_resizing = false; - - if (isLiveEditing()) { - panel_timeline->snap_to_timeline(&panel_timeline->cursor_frame, !olive::CurrentConfig.edit_tool_also_seeks || !panel_timeline->selecting, true, true); - } - if (panel_timeline->selecting) { - int selection_count = 1 + qMax(panel_timeline->cursor_track, panel_timeline->drag_track_start) - qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start) + panel_timeline->selection_offset; - if (olive::ActiveSequence->selections.size() != selection_count) { - olive::ActiveSequence->selections.resize(selection_count); - } - int minimum_selection_track = qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start); - for (int i=panel_timeline->selection_offset;iselections[i]; - s.track = minimum_selection_track + i - panel_timeline->selection_offset; - long in = panel_timeline->drag_frame_start; - long out = panel_timeline->cursor_frame; - s.in = qMin(in, out); - s.out = qMax(in, out); - } - - // select linked clips too - if (olive::CurrentConfig.edit_tool_selects_links) { - for (int j=0;jclips.size();j++) { - ClipPtr c = olive::ActiveSequence->clips.at(j); - for (int k=0;kselections.size();k++) { - const Selection& s = olive::ActiveSequence->selections.at(k); - if (!(c->timeline_in < s.in && c->timeline_out < s.in) && - !(c->timeline_in > s.out && c->timeline_out > s.out) && - c->track == s.track) { - - QVector linked_tracks = panel_timeline->get_tracks_of_linked_clips(j); - for (int k=0;kselections.size();l++) { - const Selection& test_sel = olive::ActiveSequence->selections.at(l); - if (test_sel.track == linked_tracks.at(k) && - test_sel.in == s.in && - test_sel.out == s.out) { - found = true; - break; - } - } - if (!found) { - Selection link_sel; - link_sel.in = s.in; - link_sel.out = s.out; - link_sel.track = linked_tracks.at(k); - olive::ActiveSequence->selections.append(link_sel); - } - } - - break; - } - } - } - } - - if (olive::CurrentConfig.edit_tool_also_seeks) { - panel_sequence_viewer->seek(qMin(panel_timeline->drag_frame_start, panel_timeline->cursor_frame)); - } else { - panel_timeline->repaint_timeline(); - } - } else if (panel_timeline->hand_moving) { - panel_timeline->block_repaints = true; - panel_timeline->horizontalScrollBar->setValue(panel_timeline->horizontalScrollBar->value() + panel_timeline->drag_x_start - event->pos().x()); - scrollBar->setValue(scrollBar->value() + panel_timeline->drag_y_start - event->pos().y()); - panel_timeline->block_repaints = false; - - panel_timeline->repaint_timeline(); - - panel_timeline->drag_x_start = event->pos().x(); - panel_timeline->drag_y_start = event->pos().y(); - } else if (panel_timeline->moving_init) { - if (track_resizing) { - int diff = track_resize_mouse_cache - event->pos().y(); - int new_height = track_resize_old_value; - if (bottom_align) { - new_height += diff; - } else { - new_height -= diff; - } - new_height = qMax(new_height, olive::timeline::kTrackMinHeight); - panel_timeline->calculate_track_height(track_target, new_height); - update(); - } else if (panel_timeline->moving_proc) { - update_ghosts(event->pos(), event->modifiers() & Qt::ShiftModifier); - } else { - // set up movement - // create ghosts - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr) { - Ghost g; - g.transition = nullptr; - - bool add = is_clip_selected(c, true); - - // if a whole clip is not selected, maybe just a transition is - if (panel_timeline->tool == TIMELINE_TOOL_POINTER && (c->get_opening_transition() != nullptr || c->get_closing_transition() != nullptr)) { - // check if any selections contain the whole clip or transition - for (int j=0;jselections.size();j++) { - const Selection& s = olive::ActiveSequence->selections.at(j); - if (s.track == c->track) { - if (selection_contains_transition(s, c, kTransitionOpening)) { - g.transition = c->get_opening_transition(); - add = true; - break; - } else if (selection_contains_transition(s, c, kTransitionClosing)) { - g.transition = c->get_closing_transition(); - add = true; - break; - } - } - } - } - - if (add && g.transition != nullptr) { - // check for duplicate transitions - for (int j=0;jghosts.size();j++) { - if (panel_timeline->ghosts.at(j).transition == g.transition) { - add = false; - break; - } - } - } - - if (add) { - g.clip = i; - g.trimming = (panel_timeline->trim_target > -1); - g.trim_in = panel_timeline->trim_in_point; - panel_timeline->ghosts.append(g); - } - } - } - - int size = panel_timeline->ghosts.size(); - if (panel_timeline->tool == TIMELINE_TOOL_ROLLING) { - for (int i=0;iclips.at(panel_timeline->ghosts.at(i).clip); - - // see if any ghosts are touching, in which case flip them - for (int k=0;kclips.at(panel_timeline->ghosts.at(k).clip); - if ((panel_timeline->trim_in_point && comp_clip->timeline_out == ghost_clip->timeline_in) || - (!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) { - panel_timeline->ghosts[k].trim_in = !panel_timeline->trim_in_point; - } - } - } - - // then look for other clips we're touching - for (int i=0;ighosts.at(i); - ClipPtr ghost_clip = olive::ActiveSequence->clips.at(g.clip); - for (int j=0;jclips.size();j++) { - ClipPtr comp_clip = olive::ActiveSequence->clips.at(j); - if (comp_clip->track == ghost_clip->track) { - if ((panel_timeline->trim_in_point && comp_clip->timeline_out == ghost_clip->timeline_in) || - (!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) { - // see if this clip is already selected, and if so just switch the trim_in - bool found = false; - int duplicate_ghost_index; - for (duplicate_ghost_index=0;duplicate_ghost_indexghosts.at(duplicate_ghost_index).clip == j) { - found = true; - break; - } - } - if (g.trim_in == panel_timeline->trim_in_point) { - if (!found) { - // add ghost for this clip with opposite trim_in - Ghost gh; - gh.transition = nullptr; - gh.clip = j; - gh.trimming = (panel_timeline->trim_target > -1); - gh.trim_in = !panel_timeline->trim_in_point; - panel_timeline->ghosts.append(gh); - } - } else { - if (found) { - panel_timeline->ghosts.removeAt(duplicate_ghost_index); - size--; - if (duplicate_ghost_index < i) i--; - } - } - } - } - } - } - } else if (panel_timeline->tool == TIMELINE_TOOL_SLIDE) { - for (int i=0;ighosts.at(i); - ClipPtr ghost_clip = olive::ActiveSequence->clips.at(g.clip); - panel_timeline->ghosts[i].trimming = false; - for (int j=0;jclips.size();j++) { - ClipPtr c = olive::ActiveSequence->clips.at(j); - if (c != nullptr && c->track == ghost_clip->track) { - bool found = false; - for (int k=0;kghosts.at(k).clip == j) { - found = true; - break; - } - } - if (!found) { - bool is_in = (c->timeline_in == ghost_clip->timeline_out); - if (is_in || c->timeline_out == ghost_clip->timeline_in) { - Ghost gh; - gh.transition = nullptr; - gh.clip = j; - gh.trimming = true; - gh.trim_in = is_in; - panel_timeline->ghosts.append(gh); - } - } - } - } - } - } - - init_ghosts(); - - // ripple edit prep - if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) { - long axis = LONG_MAX; - - for (int i=0;ighosts.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(panel_timeline->ghosts.at(i).clip); - if (panel_timeline->trim_in_point) { - axis = qMin(axis, c->timeline_in); - } else { - axis = qMin(axis, c->timeline_out); - } - } - - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr && !is_clip_selected(c, true)) { - bool clip_is_post = (c->timeline_in >= axis); - - // see if this a clip on this track is already in the list, and if it's closer - bool found = false; - QVector& clip_list = clip_is_post ? post_clips : pre_clips; - for (int j=0;jtrack == c->track) { - if ((!clip_is_post && compare->timeline_out < c->timeline_out) - || (clip_is_post && compare->timeline_in > c->timeline_in)) { - clip_list[j] = c; - } - found = true; - break; - } - } - if (!found) { - clip_list.append(c); - } - } - } - } - - // store selections - selection_command = new SetSelectionsCommand(olive::ActiveSequence); - selection_command->old_data = olive::ActiveSequence->selections; - - panel_timeline->moving_proc = true; - } - update_ui(false); - } else if (panel_timeline->splitting) { - int track_start = qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start); - int track_end = qMax(panel_timeline->cursor_track, panel_timeline->drag_track_start); - int track_size = 1 + track_end - track_start; - panel_timeline->split_tracks.resize(track_size); - for (int i=0;isplit_tracks[i] = track_start + i; - } - - if (!alt) { - for (int i=0;idrag_frame_start, panel_timeline->split_tracks[i]); - if (clip_index > -1) { - QVector tracks = panel_timeline->get_tracks_of_linked_clips(clip_index); - for (int j=0;j track_end) { - panel_timeline->split_tracks.append(tracks.at(j)); - } - } - } - } - } - update_ui(false); - } else if (panel_timeline->rect_select_init) { - if (panel_timeline->rect_select_proc) { - panel_timeline->rect_select_w = event->pos().x() - panel_timeline->rect_select_x; - panel_timeline->rect_select_h = event->pos().y() - panel_timeline->rect_select_y; - if (bottom_align) panel_timeline->rect_select_h -= height(); - - long frame_start = panel_timeline->getTimelineFrameFromScreenPoint(panel_timeline->rect_select_x); - long frame_end = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x()); - long frame_min = qMin(frame_start, frame_end); - long frame_max = qMax(frame_start, frame_end); - - int rsy = panel_timeline->rect_select_y; - if (bottom_align) rsy += height(); - int track_start = getTrackFromScreenPoint(rsy); - int track_end = getTrackFromScreenPoint(event->pos().y()); - int track_min = qMin(track_start, track_end); - int track_max = qMax(track_start, track_end); - - QVector selected_clips; - for (int i=0;iclips.size();i++) { - ClipPtr clip = olive::ActiveSequence->clips.at(i); - if (clip != nullptr && - clip->track >= track_min && - clip->track <= track_max && - !(clip->timeline_in < frame_min && clip->timeline_out < frame_min) && - !(clip->timeline_in > frame_max && clip->timeline_out > frame_max)) { - QVector session_clips; - session_clips.append(clip); - - if (!alt) { - for (int j=0;jlinked.size();j++) { - session_clips.append(olive::ActiveSequence->clips.at(clip->linked.at(j))); - } - } - - for (int j=0;jselections.resize(selected_clips.size() + panel_timeline->selection_offset); - for (int i=0;iselections[i+panel_timeline->selection_offset]; - ClipPtr clip = selected_clips.at(i); - s.old_in = s.in = clip->timeline_in; - s.old_out = s.out = clip->timeline_out; - s.old_track = s.track = clip->track; - } - - panel_timeline->repaint_timeline(); - } else { - panel_timeline->rect_select_x = event->pos().x(); - panel_timeline->rect_select_y = event->pos().y(); - if (bottom_align) panel_timeline->rect_select_y -= height(); - panel_timeline->rect_select_w = 0; - panel_timeline->rect_select_h = 0; - panel_timeline->rect_select_proc = true; - } - } else if (isLiveEditing()) { - // redraw because we have a cursor - panel_timeline->repaint_timeline(); - } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER || - panel_timeline->tool == TIMELINE_TOOL_RIPPLE || - panel_timeline->tool == TIMELINE_TOOL_ROLLING) { - - // hide any tooltip that may be currently showing - QToolTip::hideText(); - - // cache cursor position - QPoint pos = event->pos(); - - // - // check to see if the cursor is on a clip edge - // - - // threshold around a trim point that the cursor can be within and still considered "trimming" - int lim = 5; - long mouse_frame_lower = panel_timeline->getTimelineFrameFromScreenPoint(pos.x()-lim)-1; - long mouse_frame_upper = panel_timeline->getTimelineFrameFromScreenPoint(pos.x()+lim)+1; - - // current track that the cursor is on - int mouse_track = getTrackFromScreenPoint(pos.y()); - - // used to determine whether we the cursor found a trim point or not - bool found = false; - - // used to determine whether the cursor is within the rect of a clip - bool cursor_contains_clip = false; - - // used to determine how close the cursor is to a trim point - // (and more specifically, whether another point is closer or not) - int closeness = INT_MAX; - - // while we loop through the clips, we cache the maximum/minimum tracks in this sequence - int min_track = INT_MAX; - int max_track = INT_MIN; - - // we default to selecting no transition, but set this accordingly if the cursor is on a transition - panel_timeline->transition_select = kTransitionNone; - - // set currently trimming clip to -1 (aka null) - panel_timeline->trim_target = -1; - - // loop through current clips in the sequence - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr) { - - // cache track range - min_track = qMin(min_track, c->track); - max_track = qMax(max_track, c->track); - - // if this clip is on the same track the mouse is - if (c->track == mouse_track) { - - // if this cursor is inside the boundaries of this clip (hovering over the clip) - if (panel_timeline->cursor_frame >= c->timeline_in && - panel_timeline->cursor_frame <= c->timeline_out) { - - // acknowledge that we are hovering over a clip - cursor_contains_clip = true; - - // start a timer to show a tooltip about this clip - tooltip_timer.start(); - tooltip_clip = i; - - // check if the cursor is specifically hovering over one of the clip's transitions - if (c->get_opening_transition() != nullptr - && panel_timeline->cursor_frame <= c->timeline_in + c->get_opening_transition()->get_true_length()) { - - panel_timeline->transition_select = kTransitionOpening; - - } else if (c->get_closing_transition() != nullptr - && panel_timeline->cursor_frame >= c->timeline_out - c->get_closing_transition()->get_true_length()) { - - panel_timeline->transition_select = kTransitionClosing; - - } - } - - // is the cursor hovering around the clip's IN point? - if (c->timeline_in > mouse_frame_lower && c->timeline_in < mouse_frame_upper) { - - // test how close this IN point is to the cursor - int nc = qAbs(c->timeline_in + 1 - panel_timeline->cursor_frame); - - // and test whether it's closer than the last in/out point we found - if (nc < closeness) { - - // if so, this is the point we'll make active for now (unless we find a closer one later) - panel_timeline->trim_target = i; - panel_timeline->trim_in_point = true; - closeness = nc; - found = true; - - } - } - - // is the cursor hovering around the clip's OUT point? - if (c->timeline_out > mouse_frame_lower && c->timeline_out < mouse_frame_upper) { - - // test how close this OUT point is to the cursor - int nc = qAbs(c->timeline_out - 1 - panel_timeline->cursor_frame); - - // and test whether it's closer than the last in/out point we found - if (nc < closeness) { - - // if so, this is the point we'll make active for now (unless we find a closer one later) - panel_timeline->trim_target = i; - panel_timeline->trim_in_point = false; - closeness = nc; - found = true; - - } - } - - // the pointer can be used to resize/trim transitions, here we test if the - // cursor is within the trim point of one of the clip's transitions - if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { - - // if the clip has an opening transition - if (c->get_opening_transition() != nullptr) { - - // cache the timeline frame where the transition ends - long transition_point = c->timeline_in + c->get_opening_transition()->get_true_length(); - - // check if the cursor is hovering around it (within the threshold) - if (transition_point > mouse_frame_lower && transition_point < mouse_frame_upper) { - - // similar to above, test how close it is and if it's closer, make this active - int nc = qAbs(transition_point - 1 - panel_timeline->cursor_frame); - if (nc < closeness) { - panel_timeline->trim_target = i; - panel_timeline->trim_in_point = false; - panel_timeline->transition_select = kTransitionOpening; - closeness = nc; - found = true; - } - } - } - - // if the clip has a closing transition - if (c->get_closing_transition() != nullptr) { - - // cache the timeline frame where the transition starts - long transition_point = c->timeline_out - c->get_closing_transition()->get_true_length(); - - // check if the cursor is hovering around it (within the threshold) - if (transition_point > mouse_frame_lower && transition_point < mouse_frame_upper) { - - // similar to above, test how close it is and if it's closer, make this active - int nc = qAbs(transition_point + 1 - panel_timeline->cursor_frame); - if (nc < closeness) { - panel_timeline->trim_target = i; - panel_timeline->trim_in_point = true; - panel_timeline->transition_select = kTransitionClosing; - closeness = nc; - found = true; - } - } - } - } - } - } + tooltip_timer.stop(); + if (olive::ActiveSequence != nullptr) { + bool alt = (event->modifiers() & Qt::AltModifier); + + panel_timeline->cursor_frame = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x()); + panel_timeline->cursor_track = getTrackFromScreenPoint(event->pos().y()); + + panel_timeline->move_insert = ((event->modifiers() & Qt::ControlModifier) && (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->importing || panel_timeline->creating)); + + if (!panel_timeline->moving_init) track_resizing = false; + + if (isLiveEditing()) { + panel_timeline->snap_to_timeline(&panel_timeline->cursor_frame, !olive::CurrentConfig.edit_tool_also_seeks || !panel_timeline->selecting, true, true); + } + if (panel_timeline->selecting) { + int selection_count = 1 + qMax(panel_timeline->cursor_track, panel_timeline->drag_track_start) - qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start) + panel_timeline->selection_offset; + if (olive::ActiveSequence->selections.size() != selection_count) { + olive::ActiveSequence->selections.resize(selection_count); + } + int minimum_selection_track = qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start); + for (int i=panel_timeline->selection_offset;iselections[i]; + s.track = minimum_selection_track + i - panel_timeline->selection_offset; + long in = panel_timeline->drag_frame_start; + long out = panel_timeline->cursor_frame; + s.in = qMin(in, out); + s.out = qMax(in, out); + } + + // select linked clips too + if (olive::CurrentConfig.edit_tool_selects_links) { + for (int j=0;jclips.size();j++) { + ClipPtr c = olive::ActiveSequence->clips.at(j); + for (int k=0;kselections.size();k++) { + const Selection& s = olive::ActiveSequence->selections.at(k); + if (!(c->timeline_in < s.in && c->timeline_out < s.in) && + !(c->timeline_in > s.out && c->timeline_out > s.out) && + c->track == s.track) { + + QVector linked_tracks = panel_timeline->get_tracks_of_linked_clips(j); + for (int k=0;kselections.size();l++) { + const Selection& test_sel = olive::ActiveSequence->selections.at(l); + if (test_sel.track == linked_tracks.at(k) && + test_sel.in == s.in && + test_sel.out == s.out) { + found = true; + break; + } + } + if (!found) { + Selection link_sel; + link_sel.in = s.in; + link_sel.out = s.out; + link_sel.track = linked_tracks.at(k); + olive::ActiveSequence->selections.append(link_sel); + } + } + + break; + } + } + } + } + + if (olive::CurrentConfig.edit_tool_also_seeks) { + panel_sequence_viewer->seek(qMin(panel_timeline->drag_frame_start, panel_timeline->cursor_frame)); + } else { + panel_timeline->repaint_timeline(); + } + } else if (panel_timeline->hand_moving) { + panel_timeline->block_repaints = true; + panel_timeline->horizontalScrollBar->setValue(panel_timeline->horizontalScrollBar->value() + panel_timeline->drag_x_start - event->pos().x()); + scrollBar->setValue(scrollBar->value() + panel_timeline->drag_y_start - event->pos().y()); + panel_timeline->block_repaints = false; + + panel_timeline->repaint_timeline(); + + panel_timeline->drag_x_start = event->pos().x(); + panel_timeline->drag_y_start = event->pos().y(); + } else if (panel_timeline->moving_init) { + if (track_resizing) { + int diff = track_resize_mouse_cache - event->pos().y(); + int new_height = track_resize_old_value; + if (bottom_align) { + new_height += diff; + } else { + new_height -= diff; + } + new_height = qMax(new_height, olive::timeline::kTrackMinHeight); + panel_timeline->calculate_track_height(track_target, new_height); + update(); + } else if (panel_timeline->moving_proc) { + update_ghosts(event->pos(), event->modifiers() & Qt::ShiftModifier); + } else { + // set up movement + // create ghosts + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr) { + Ghost g; + g.transition = nullptr; + + bool add = is_clip_selected(c, true); + + // if a whole clip is not selected, maybe just a transition is + if (panel_timeline->tool == TIMELINE_TOOL_POINTER && (c->get_opening_transition() != nullptr || c->get_closing_transition() != nullptr)) { + // check if any selections contain the whole clip or transition + for (int j=0;jselections.size();j++) { + const Selection& s = olive::ActiveSequence->selections.at(j); + if (s.track == c->track) { + if (selection_contains_transition(s, c, kTransitionOpening)) { + g.transition = c->get_opening_transition(); + add = true; + break; + } else if (selection_contains_transition(s, c, kTransitionClosing)) { + g.transition = c->get_closing_transition(); + add = true; + break; + } + } + } } - // if the cursor is indeed on a clip edge, we set the cursor accordingly - if (found) { - - if (panel_timeline->trim_in_point) { // if we're trimming an IN point - setCursor(olive::Cursor_LeftTrim); - } else { // if we're trimming an OUT point - setCursor(olive::Cursor_RightTrim); + if (add && g.transition != nullptr) { + // check for duplicate transitions + for (int j=0;jghosts.size();j++) { + if (panel_timeline->ghosts.at(j).transition == g.transition) { + add = false; + break; } + } + } - } else { - // we didn't find a trim target, so we must be doing something else - // (e.g. dragging a clip or resizing the track heights) + if (add) { + g.clip = i; + g.trimming = (panel_timeline->trim_target > -1); + g.trim_in = panel_timeline->trim_in_point; + panel_timeline->ghosts.append(g); + } + } + } - // check to see if we're resizing a track height - int track_y = 0; - for (int i=0;iget_track_height_size(bottom_align);i++) { - int track = (bottom_align) ? -1-i : i; - if (track >= min_track && track <= max_track) { - int track_height = panel_timeline->calculate_track_height(track, -1); - track_y += track_height; - int y_test_value = (bottom_align) ? rect().bottom() - track_y : track_y; - int test_range = 5; - int mouse_pos = pos.y() + scroll; - if (mouse_pos > y_test_value-test_range && mouse_pos < y_test_value+test_range) { - // if track lines are hidden, only resize track if a clip is already there - if (olive::CurrentConfig.show_track_lines || cursor_contains_clip) { - found = true; - track_resizing = true; - track_target = track; - track_resize_old_value = track_height; - } - break; - } - } - } + int size = panel_timeline->ghosts.size(); + if (panel_timeline->tool == TIMELINE_TOOL_ROLLING) { + for (int i=0;iclips.at(panel_timeline->ghosts.at(i).clip); - if (found) { - setCursor(Qt::SizeVerCursor); - } else { - unsetCursor(); - } - } - } else if (panel_timeline->tool == TIMELINE_TOOL_SLIP) { - if (getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track) > -1) { - setCursor(Qt::SizeHorCursor); - } else { - unsetCursor(); - } - } else if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION) { - if (panel_timeline->transition_tool_init) { - if (panel_timeline->transition_tool_proc) { - update_ghosts(event->pos(), event->modifiers() & Qt::ShiftModifier); - } else { - ClipPtr c = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_pre_clip); + // see if any ghosts are touching, in which case flip them + for (int k=0;kclips.at(panel_timeline->ghosts.at(k).clip); + if ((panel_timeline->trim_in_point && comp_clip->timeline_out == ghost_clip->timeline_in) || + (!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) { + panel_timeline->ghosts[k].trim_in = !panel_timeline->trim_in_point; + } + } + } - Ghost g; + // then look for other clips we're touching + for (int i=0;ighosts.at(i); + ClipPtr ghost_clip = olive::ActiveSequence->clips.at(g.clip); + for (int j=0;jclips.size();j++) { + ClipPtr comp_clip = olive::ActiveSequence->clips.at(j); + if (comp_clip->track == ghost_clip->track) { + if ((panel_timeline->trim_in_point && comp_clip->timeline_out == ghost_clip->timeline_in) || + (!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) { + // see if this clip is already selected, and if so just switch the trim_in + bool found = false; + int duplicate_ghost_index; + for (duplicate_ghost_index=0;duplicate_ghost_indexghosts.at(duplicate_ghost_index).clip == j) { + found = true; + break; + } + } + if (g.trim_in == panel_timeline->trim_in_point) { + if (!found) { + // add ghost for this clip with opposite trim_in + Ghost gh; + gh.transition = nullptr; + gh.clip = j; + gh.trimming = (panel_timeline->trim_target > -1); + gh.trim_in = !panel_timeline->trim_in_point; + panel_timeline->ghosts.append(gh); + } + } else { + if (found) { + panel_timeline->ghosts.removeAt(duplicate_ghost_index); + size--; + if (duplicate_ghost_index < i) i--; + } + } + } + } + } + } + } else if (panel_timeline->tool == TIMELINE_TOOL_SLIDE) { + for (int i=0;ighosts.at(i); + ClipPtr ghost_clip = olive::ActiveSequence->clips.at(g.clip); + panel_timeline->ghosts[i].trimming = false; + for (int j=0;jclips.size();j++) { + ClipPtr c = olive::ActiveSequence->clips.at(j); + if (c != nullptr && c->track == ghost_clip->track) { + bool found = false; + for (int k=0;kghosts.at(k).clip == j) { + found = true; + break; + } + } + if (!found) { + bool is_in = (c->timeline_in == ghost_clip->timeline_out); + if (is_in || c->timeline_out == ghost_clip->timeline_in) { + Ghost gh; + gh.transition = nullptr; + gh.clip = j; + gh.trimming = true; + gh.trim_in = is_in; + panel_timeline->ghosts.append(gh); + } + } + } + } + } + } - g.in = g.old_in = g.out = g.old_out = (panel_timeline->transition_tool_type == kTransitionOpening) ? c->timeline_in : c->timeline_out; - g.track = c->track; - g.clip = panel_timeline->transition_tool_pre_clip; - g.media_stream = panel_timeline->transition_tool_type; - g.trimming = false; + init_ghosts(); - panel_timeline->ghosts.append(g); + // ripple edit prep + if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) { + long axis = LONG_MAX; - panel_timeline->transition_tool_proc = true; - } - } else { - int mouse_clip = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); - if (mouse_clip > -1) { - ClipPtr c = olive::ActiveSequence->clips.at(mouse_clip); - if (same_sign(c->track, panel_timeline->transition_tool_side)) { - panel_timeline->transition_tool_pre_clip = mouse_clip; - long halfway = c->timeline_in + (c->getLength()/2); - long between_range = getFrameFromScreenPoint(panel_timeline->zoom, TRANSITION_BETWEEN_RANGE) + 1; + for (int i=0;ighosts.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(panel_timeline->ghosts.at(i).clip); + if (panel_timeline->trim_in_point) { + axis = qMin(axis, c->timeline_in); + } else { + axis = qMin(axis, c->timeline_out); + } + } - if (panel_timeline->cursor_frame > halfway) { - panel_timeline->transition_tool_type = kTransitionClosing; - } else { - panel_timeline->transition_tool_type = kTransitionOpening; - } + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr && !is_clip_selected(c, true)) { + bool clip_is_post = (c->timeline_in >= axis); - panel_timeline->transition_tool_post_clip = -1; - if (panel_timeline->cursor_frame < c->timeline_in + between_range) { - panel_timeline->transition_tool_post_clip = getClipIndexFromCoords(c->timeline_in-1, c->track); - } else if (panel_timeline->cursor_frame > c->timeline_out - between_range) { - panel_timeline->transition_tool_post_clip = getClipIndexFromCoords(c->timeline_out+1, c->track); - } - } - } else { - panel_timeline->transition_tool_pre_clip = -1; - panel_timeline->transition_tool_post_clip = -1; - } - } + // see if this a clip on this track is already in the list, and if it's closer + bool found = false; + QVector& clip_list = clip_is_post ? post_clips : pre_clips; + for (int j=0;jtrack == c->track) { + if ((!clip_is_post && compare->timeline_out < c->timeline_out) + || (clip_is_post && compare->timeline_in > c->timeline_in)) { + clip_list[j] = c; + } + found = true; + break; + } + } + if (!found) { + clip_list.append(c); + } + } + } + } - panel_timeline->repaint_timeline(); - } - } + // store selections + selection_command = new SetSelectionsCommand(olive::ActiveSequence); + selection_command->old_data = olive::ActiveSequence->selections; + + panel_timeline->moving_proc = true; + } + update_ui(false); + } else if (panel_timeline->splitting) { + int track_start = qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start); + int track_end = qMax(panel_timeline->cursor_track, panel_timeline->drag_track_start); + int track_size = 1 + track_end - track_start; + panel_timeline->split_tracks.resize(track_size); + for (int i=0;isplit_tracks[i] = track_start + i; + } + + if (!alt) { + for (int i=0;idrag_frame_start, panel_timeline->split_tracks[i]); + if (clip_index > -1) { + QVector tracks = panel_timeline->get_tracks_of_linked_clips(clip_index); + for (int j=0;j track_end) { + panel_timeline->split_tracks.append(tracks.at(j)); + } + } + } + } + } + update_ui(false); + } else if (panel_timeline->rect_select_init) { + if (panel_timeline->rect_select_proc) { + panel_timeline->rect_select_w = event->pos().x() - panel_timeline->rect_select_x; + panel_timeline->rect_select_h = event->pos().y() - panel_timeline->rect_select_y; + if (bottom_align) panel_timeline->rect_select_h -= height(); + + long frame_start = panel_timeline->getTimelineFrameFromScreenPoint(panel_timeline->rect_select_x); + long frame_end = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x()); + long frame_min = qMin(frame_start, frame_end); + long frame_max = qMax(frame_start, frame_end); + + int rsy = panel_timeline->rect_select_y; + if (bottom_align) rsy += height(); + int track_start = getTrackFromScreenPoint(rsy); + int track_end = getTrackFromScreenPoint(event->pos().y()); + int track_min = qMin(track_start, track_end); + int track_max = qMax(track_start, track_end); + + QVector selected_clips; + for (int i=0;iclips.size();i++) { + ClipPtr clip = olive::ActiveSequence->clips.at(i); + if (clip != nullptr && + clip->track >= track_min && + clip->track <= track_max && + !(clip->timeline_in < frame_min && clip->timeline_out < frame_min) && + !(clip->timeline_in > frame_max && clip->timeline_out > frame_max)) { + QVector session_clips; + session_clips.append(clip); + + if (!alt) { + for (int j=0;jlinked.size();j++) { + session_clips.append(olive::ActiveSequence->clips.at(clip->linked.at(j))); + } + } + + for (int j=0;jselections.resize(selected_clips.size() + panel_timeline->selection_offset); + for (int i=0;iselections[i+panel_timeline->selection_offset]; + ClipPtr clip = selected_clips.at(i); + s.old_in = s.in = clip->timeline_in; + s.old_out = s.out = clip->timeline_out; + s.old_track = s.track = clip->track; + } + + panel_timeline->repaint_timeline(); + } else { + panel_timeline->rect_select_x = event->pos().x(); + panel_timeline->rect_select_y = event->pos().y(); + if (bottom_align) panel_timeline->rect_select_y -= height(); + panel_timeline->rect_select_w = 0; + panel_timeline->rect_select_h = 0; + panel_timeline->rect_select_proc = true; + } + } else if (isLiveEditing()) { + // redraw because we have a cursor + panel_timeline->repaint_timeline(); + } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER || + panel_timeline->tool == TIMELINE_TOOL_RIPPLE || + panel_timeline->tool == TIMELINE_TOOL_ROLLING) { + + // hide any tooltip that may be currently showing + QToolTip::hideText(); + + // cache cursor position + QPoint pos = event->pos(); + + // + // check to see if the cursor is on a clip edge + // + + // threshold around a trim point that the cursor can be within and still considered "trimming" + int lim = 5; + long mouse_frame_lower = panel_timeline->getTimelineFrameFromScreenPoint(pos.x()-lim)-1; + long mouse_frame_upper = panel_timeline->getTimelineFrameFromScreenPoint(pos.x()+lim)+1; + + // current track that the cursor is on + int mouse_track = getTrackFromScreenPoint(pos.y()); + + // used to determine whether we the cursor found a trim point or not + bool found = false; + + // used to determine whether the cursor is within the rect of a clip + bool cursor_contains_clip = false; + + // used to determine how close the cursor is to a trim point + // (and more specifically, whether another point is closer or not) + int closeness = INT_MAX; + + // while we loop through the clips, we cache the maximum/minimum tracks in this sequence + int min_track = INT_MAX; + int max_track = INT_MIN; + + // we default to selecting no transition, but set this accordingly if the cursor is on a transition + panel_timeline->transition_select = kTransitionNone; + + // set currently trimming clip to -1 (aka null) + panel_timeline->trim_target = -1; + + // loop through current clips in the sequence + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr) { + + // cache track range + min_track = qMin(min_track, c->track); + max_track = qMax(max_track, c->track); + + // if this clip is on the same track the mouse is + if (c->track == mouse_track) { + + // if this cursor is inside the boundaries of this clip (hovering over the clip) + if (panel_timeline->cursor_frame >= c->timeline_in && + panel_timeline->cursor_frame <= c->timeline_out) { + + // acknowledge that we are hovering over a clip + cursor_contains_clip = true; + + // start a timer to show a tooltip about this clip + tooltip_timer.start(); + tooltip_clip = i; + + // check if the cursor is specifically hovering over one of the clip's transitions + if (c->get_opening_transition() != nullptr + && panel_timeline->cursor_frame <= c->timeline_in + c->get_opening_transition()->get_true_length()) { + + panel_timeline->transition_select = kTransitionOpening; + + } else if (c->get_closing_transition() != nullptr + && panel_timeline->cursor_frame >= c->timeline_out - c->get_closing_transition()->get_true_length()) { + + panel_timeline->transition_select = kTransitionClosing; + + } + } + + // is the cursor hovering around the clip's IN point? + if (c->timeline_in > mouse_frame_lower && c->timeline_in < mouse_frame_upper) { + + // test how close this IN point is to the cursor + int nc = qAbs(c->timeline_in + 1 - panel_timeline->cursor_frame); + + // and test whether it's closer than the last in/out point we found + if (nc < closeness) { + + // if so, this is the point we'll make active for now (unless we find a closer one later) + panel_timeline->trim_target = i; + panel_timeline->trim_in_point = true; + closeness = nc; + found = true; + + } + } + + // is the cursor hovering around the clip's OUT point? + if (c->timeline_out > mouse_frame_lower && c->timeline_out < mouse_frame_upper) { + + // test how close this OUT point is to the cursor + int nc = qAbs(c->timeline_out - 1 - panel_timeline->cursor_frame); + + // and test whether it's closer than the last in/out point we found + if (nc < closeness) { + + // if so, this is the point we'll make active for now (unless we find a closer one later) + panel_timeline->trim_target = i; + panel_timeline->trim_in_point = false; + closeness = nc; + found = true; + + } + } + + // the pointer can be used to resize/trim transitions, here we test if the + // cursor is within the trim point of one of the clip's transitions + if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { + + // if the clip has an opening transition + if (c->get_opening_transition() != nullptr) { + + // cache the timeline frame where the transition ends + long transition_point = c->timeline_in + c->get_opening_transition()->get_true_length(); + + // check if the cursor is hovering around it (within the threshold) + if (transition_point > mouse_frame_lower && transition_point < mouse_frame_upper) { + + // similar to above, test how close it is and if it's closer, make this active + int nc = qAbs(transition_point - 1 - panel_timeline->cursor_frame); + if (nc < closeness) { + panel_timeline->trim_target = i; + panel_timeline->trim_in_point = false; + panel_timeline->transition_select = kTransitionOpening; + closeness = nc; + found = true; + } + } + } + + // if the clip has a closing transition + if (c->get_closing_transition() != nullptr) { + + // cache the timeline frame where the transition starts + long transition_point = c->timeline_out - c->get_closing_transition()->get_true_length(); + + // check if the cursor is hovering around it (within the threshold) + if (transition_point > mouse_frame_lower && transition_point < mouse_frame_upper) { + + // similar to above, test how close it is and if it's closer, make this active + int nc = qAbs(transition_point + 1 - panel_timeline->cursor_frame); + if (nc < closeness) { + panel_timeline->trim_target = i; + panel_timeline->trim_in_point = true; + panel_timeline->transition_select = kTransitionClosing; + closeness = nc; + found = true; + } + } + } + } + } + } + } + + // if the cursor is indeed on a clip edge, we set the cursor accordingly + if (found) { + + if (panel_timeline->trim_in_point) { // if we're trimming an IN point + setCursor(olive::Cursor_LeftTrim); + } else { // if we're trimming an OUT point + setCursor(olive::Cursor_RightTrim); + } + + } else { + // we didn't find a trim target, so we must be doing something else + // (e.g. dragging a clip or resizing the track heights) + + // check to see if we're resizing a track height + int track_y = 0; + for (int i=0;iget_track_height_size(bottom_align);i++) { + int track = (bottom_align) ? -1-i : i; + if (track >= min_track && track <= max_track) { + int track_height = panel_timeline->calculate_track_height(track, -1); + track_y += track_height; + int y_test_value = (bottom_align) ? rect().bottom() - track_y : track_y; + int test_range = 5; + int mouse_pos = pos.y() + scroll; + if (mouse_pos > y_test_value-test_range && mouse_pos < y_test_value+test_range) { + // if track lines are hidden, only resize track if a clip is already there + if (olive::CurrentConfig.show_track_lines || cursor_contains_clip) { + found = true; + track_resizing = true; + track_target = track; + track_resize_old_value = track_height; + } + break; + } + } + } + + if (found) { + setCursor(Qt::SizeVerCursor); + } else { + unsetCursor(); + } + } + } else if (panel_timeline->tool == TIMELINE_TOOL_SLIP) { + if (getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track) > -1) { + setCursor(Qt::SizeHorCursor); + } else { + unsetCursor(); + } + } else if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION) { + if (panel_timeline->transition_tool_init) { + if (panel_timeline->transition_tool_proc) { + update_ghosts(event->pos(), event->modifiers() & Qt::ShiftModifier); + } else { + ClipPtr c = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_pre_clip); + + Ghost g; + + g.in = g.old_in = g.out = g.old_out = (panel_timeline->transition_tool_type == kTransitionOpening) ? c->timeline_in : c->timeline_out; + g.track = c->track; + g.clip = panel_timeline->transition_tool_pre_clip; + g.media_stream = panel_timeline->transition_tool_type; + g.trimming = false; + + panel_timeline->ghosts.append(g); + + panel_timeline->transition_tool_proc = true; + } + } else { + int mouse_clip = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); + if (mouse_clip > -1) { + ClipPtr c = olive::ActiveSequence->clips.at(mouse_clip); + if (same_sign(c->track, panel_timeline->transition_tool_side)) { + panel_timeline->transition_tool_pre_clip = mouse_clip; + long halfway = c->timeline_in + (c->getLength()/2); + long between_range = getFrameFromScreenPoint(panel_timeline->zoom, TRANSITION_BETWEEN_RANGE) + 1; + + if (panel_timeline->cursor_frame > halfway) { + panel_timeline->transition_tool_type = kTransitionClosing; + } else { + panel_timeline->transition_tool_type = kTransitionOpening; + } + + panel_timeline->transition_tool_post_clip = -1; + if (panel_timeline->cursor_frame < c->timeline_in + between_range) { + panel_timeline->transition_tool_post_clip = getClipIndexFromCoords(c->timeline_in-1, c->track); + } else if (panel_timeline->cursor_frame > c->timeline_out - between_range) { + panel_timeline->transition_tool_post_clip = getClipIndexFromCoords(c->timeline_out+1, c->track); + } + } + } else { + panel_timeline->transition_tool_pre_clip = -1; + panel_timeline->transition_tool_post_clip = -1; + } + } + + panel_timeline->repaint_timeline(); + } + } } void TimelineWidget::leaveEvent(QEvent*) { - tooltip_timer.stop(); + tooltip_timer.stop(); } int color_brightness(int r, int g, int b) { - return qRound(0.2126*r + 0.7152*g + 0.0722*b); + return qRound(0.2126*r + 0.7152*g + 0.0722*b); } void draw_waveform(ClipPtr clip, const FootageStream* ms, long media_length, QPainter *p, const QRect& clip_rect, int waveform_start, int waveform_limit, double zoom) { - int divider = ms->audio_channels*2; - int channel_height = clip_rect.height()/ms->audio_channels; + int divider = ms->audio_channels*2; + int channel_height = clip_rect.height()/ms->audio_channels; - int last_waveform_index = -1; + int last_waveform_index = -1; - for (int i=waveform_start;iclip_in + (double(i)/zoom))/media_length) * ms->audio_preview.size())/divider)*divider; - if (last_waveform_index < 0) last_waveform_index = waveform_index; + for (int i=waveform_start;iclip_in + (double(i)/zoom))/media_length) * ms->audio_preview.size())/divider)*divider; + if (last_waveform_index < 0) last_waveform_index = waveform_index; - if (clip->reverse) { - waveform_index = ms->audio_preview.size() - waveform_index - (ms->audio_channels * 2); - } + if (clip->reverse) { + waveform_index = ms->audio_preview.size() - waveform_index - (ms->audio_channels * 2); + } - for (int j=0;jaudio_channels;j++) { - int mid = (olive::CurrentConfig.rectified_waveforms) ? clip_rect.top()+channel_height*(j+1) : clip_rect.top()+channel_height*j+(channel_height/2); + for (int j=0;jaudio_channels;j++) { + int mid = (olive::CurrentConfig.rectified_waveforms) ? clip_rect.top()+channel_height*(j+1) : clip_rect.top()+channel_height*j+(channel_height/2); - int offset_range_start = last_waveform_index+(j*2); - int offset_range_end = waveform_index+(j*2); + int offset_range_start = last_waveform_index+(j*2); + int offset_range_end = waveform_index+(j*2); - qint8 min = qint8(qRound(double(ms->audio_preview.at(offset_range_start)) / 128.0 * (channel_height/2))); - qint8 max = qint8(qRound(double(ms->audio_preview.at(offset_range_start+1)) / 128.0 * (channel_height/2))); + qint8 min = qint8(qRound(double(ms->audio_preview.at(offset_range_start)) / 128.0 * (channel_height/2))); + qint8 max = qint8(qRound(double(ms->audio_preview.at(offset_range_start+1)) / 128.0 * (channel_height/2))); - if ((offset_range_end + 1) < ms->audio_preview.size()) { + if ((offset_range_end + 1) < ms->audio_preview.size()) { - // for waveform drawings, we get the maximum below 0 and maximum above 0 for this waveform range - for (int k=offset_range_start+2;k<=offset_range_end;k+=2) { - min = qMin(min, qint8(qRound(double(ms->audio_preview.at(k)) / 128.0 * (channel_height/2)))); - max = qMax(max, qint8(qRound(double(ms->audio_preview.at(k+1)) / 128.0 * (channel_height/2)))); - } + // for waveform drawings, we get the maximum below 0 and maximum above 0 for this waveform range + for (int k=offset_range_start+2;k<=offset_range_end;k+=2) { + min = qMin(min, qint8(qRound(double(ms->audio_preview.at(k)) / 128.0 * (channel_height/2)))); + max = qMax(max, qint8(qRound(double(ms->audio_preview.at(k+1)) / 128.0 * (channel_height/2)))); + } - // draw waveforms - if (olive::CurrentConfig.rectified_waveforms) { + // draw waveforms + if (olive::CurrentConfig.rectified_waveforms) { - // rectified waveforms start from the bottom and draw upwards - p->drawLine(clip_rect.left()+i, mid, clip_rect.left()+i, mid - (max - min)); - } else { + // rectified waveforms start from the bottom and draw upwards + p->drawLine(clip_rect.left()+i, mid, clip_rect.left()+i, mid - (max - min)); + } else { - // non-rectified waveforms start from the center and draw outwards - p->drawLine(clip_rect.left()+i, mid+min, clip_rect.left()+i, mid+max); + // non-rectified waveforms start from the center and draw outwards + p->drawLine(clip_rect.left()+i, mid+min, clip_rect.left()+i, mid+max); - } - } - } - last_waveform_index = waveform_index; - } + } + } + } + last_waveform_index = waveform_index; + } } void draw_transition(QPainter& p, ClipPtr c, const QRect& clip_rect, QRect& text_rect, int transition_type) { - TransitionPtr t = (transition_type == kTransitionOpening) ? c->get_opening_transition() : c->get_closing_transition(); - if (t != nullptr) { - QColor transition_color(255, 0, 0, 16); - int transition_width = getScreenPointFromFrame(panel_timeline->zoom, t->get_true_length()); - int transition_height = clip_rect.height(); - int tr_y = clip_rect.y(); - int tr_x = 0; - if (transition_type == kTransitionOpening) { - tr_x = clip_rect.x(); - text_rect.setX(text_rect.x()+transition_width); - } else { - tr_x = clip_rect.right()-transition_width; - text_rect.setWidth(text_rect.width()-transition_width); - } - QRect transition_rect = QRect(tr_x, tr_y, transition_width, transition_height); - p.fillRect(transition_rect, transition_color); - QRect transition_text_rect(transition_rect.x() + olive::timeline::kClipTextPadding, transition_rect.y() + olive::timeline::kClipTextPadding, transition_rect.width() - olive::timeline::kClipTextPadding, transition_rect.height() - olive::timeline::kClipTextPadding); - if (transition_text_rect.width() > MAX_TEXT_WIDTH) { - bool draw_text = true; + TransitionPtr t = (transition_type == kTransitionOpening) ? c->get_opening_transition() : c->get_closing_transition(); + if (t != nullptr) { + QColor transition_color(255, 0, 0, 16); + int transition_width = getScreenPointFromFrame(panel_timeline->zoom, t->get_true_length()); + int transition_height = clip_rect.height(); + int tr_y = clip_rect.y(); + int tr_x = 0; + if (transition_type == kTransitionOpening) { + tr_x = clip_rect.x(); + text_rect.setX(text_rect.x()+transition_width); + } else { + tr_x = clip_rect.right()-transition_width; + text_rect.setWidth(text_rect.width()-transition_width); + } + QRect transition_rect = QRect(tr_x, tr_y, transition_width, transition_height); + p.fillRect(transition_rect, transition_color); + QRect transition_text_rect(transition_rect.x() + olive::timeline::kClipTextPadding, transition_rect.y() + olive::timeline::kClipTextPadding, transition_rect.width() - olive::timeline::kClipTextPadding, transition_rect.height() - olive::timeline::kClipTextPadding); + if (transition_text_rect.width() > MAX_TEXT_WIDTH) { + bool draw_text = true; - p.setPen(QColor(0, 0, 0, 96)); - if (t->secondary_clip == nullptr) { - if (transition_type == kTransitionOpening) { - p.drawLine(transition_rect.bottomLeft(), transition_rect.topRight()); - } else { - p.drawLine(transition_rect.topLeft(), transition_rect.bottomRight()); - } - } else { - if (transition_type == kTransitionOpening) { - p.drawLine(QPoint(transition_rect.left(), transition_rect.center().y()), transition_rect.topRight()); - p.drawLine(QPoint(transition_rect.left(), transition_rect.center().y()), transition_rect.bottomRight()); - draw_text = false; - } else { - p.drawLine(QPoint(transition_rect.right(), transition_rect.center().y()), transition_rect.topLeft()); - p.drawLine(QPoint(transition_rect.right(), transition_rect.center().y()), transition_rect.bottomLeft()); - } - } + p.setPen(QColor(0, 0, 0, 96)); + if (t->secondary_clip == nullptr) { + if (transition_type == kTransitionOpening) { + p.drawLine(transition_rect.bottomLeft(), transition_rect.topRight()); + } else { + p.drawLine(transition_rect.topLeft(), transition_rect.bottomRight()); + } + } else { + if (transition_type == kTransitionOpening) { + p.drawLine(QPoint(transition_rect.left(), transition_rect.center().y()), transition_rect.topRight()); + p.drawLine(QPoint(transition_rect.left(), transition_rect.center().y()), transition_rect.bottomRight()); + draw_text = false; + } else { + p.drawLine(QPoint(transition_rect.right(), transition_rect.center().y()), transition_rect.topLeft()); + p.drawLine(QPoint(transition_rect.right(), transition_rect.center().y()), transition_rect.bottomLeft()); + } + } - if (draw_text) { - p.setPen(Qt::white); - p.drawText(transition_text_rect, 0, t->meta->name, &transition_text_rect); - } - } - p.setPen(Qt::black); - p.drawRect(transition_rect); - } + if (draw_text) { + p.setPen(Qt::white); + p.drawText(transition_text_rect, 0, t->meta->name, &transition_text_rect); + } + } + p.setPen(Qt::black); + p.drawRect(transition_rect); + } } void TimelineWidget::paintEvent(QPaintEvent*) { - // Draw clips - if (olive::ActiveSequence != nullptr) { - QPainter p(this); + // Draw clips + if (olive::ActiveSequence != nullptr) { + QPainter p(this); - // get widget width and height - int video_track_limit = 0; - int audio_track_limit = 0; - for (int i=0;iclips.size();i++) { - ClipPtr clip = olive::ActiveSequence->clips.at(i); - if (clip != nullptr) { - video_track_limit = qMin(video_track_limit, clip->track); - audio_track_limit = qMax(audio_track_limit, clip->track); - } - } + // get widget width and height + int video_track_limit = 0; + int audio_track_limit = 0; + for (int i=0;iclips.size();i++) { + ClipPtr clip = olive::ActiveSequence->clips.at(i); + if (clip != nullptr) { + video_track_limit = qMin(video_track_limit, clip->track); + audio_track_limit = qMax(audio_track_limit, clip->track); + } + } - int panel_height = TRACK_DEFAULT_HEIGHT; - if (bottom_align) { - for (int i=-1;i>=video_track_limit;i--) { - panel_height += panel_timeline->calculate_track_height(i, -1); - } - } else { - for (int i=0;i<=audio_track_limit;i++) { - panel_height += panel_timeline->calculate_track_height(i, -1); - } - } - if (bottom_align) { - scrollBar->setMinimum(qMin(0, - panel_height + height())); - } else { - scrollBar->setMaximum(qMax(0, panel_height - height())); - } + int panel_height = TRACK_DEFAULT_HEIGHT; + if (bottom_align) { + for (int i=-1;i>=video_track_limit;i--) { + panel_height += panel_timeline->calculate_track_height(i, -1); + } + } else { + for (int i=0;i<=audio_track_limit;i++) { + panel_height += panel_timeline->calculate_track_height(i, -1); + } + } + if (bottom_align) { + scrollBar->setMinimum(qMin(0, - panel_height + height())); + } else { + scrollBar->setMaximum(qMax(0, panel_height - height())); + } - for (int i=0;iclips.size();i++) { - ClipPtr clip = olive::ActiveSequence->clips.at(i); - if (clip != nullptr && is_track_visible(clip->track)) { - QRect clip_rect(panel_timeline->getTimelineScreenPointFromFrame(clip->timeline_in), getScreenPointFromTrack(clip->track), getScreenPointFromFrame(panel_timeline->zoom, clip->getLength()), panel_timeline->calculate_track_height(clip->track, -1)); - QRect text_rect(clip_rect.left() + olive::timeline::kClipTextPadding, clip_rect.top() + olive::timeline::kClipTextPadding, clip_rect.width() - olive::timeline::kClipTextPadding - 1, clip_rect.height() - olive::timeline::kClipTextPadding - 1); - if (clip_rect.left() < width() && clip_rect.right() >= 0 && clip_rect.top() < height() && clip_rect.bottom() >= 0) { - QRect actual_clip_rect = clip_rect; - if (actual_clip_rect.x() < 0) actual_clip_rect.setX(0); - if (actual_clip_rect.right() > width()) actual_clip_rect.setRight(width()); - if (actual_clip_rect.y() < 0) actual_clip_rect.setY(0); - if (actual_clip_rect.bottom() > height()) actual_clip_rect.setBottom(height()); - p.fillRect(actual_clip_rect, (clip->enabled) ? QColor(clip->color_r, clip->color_g, clip->color_b) : QColor(96, 96, 96)); + for (int i=0;iclips.size();i++) { + ClipPtr clip = olive::ActiveSequence->clips.at(i); + if (clip != nullptr && is_track_visible(clip->track)) { + QRect clip_rect(panel_timeline->getTimelineScreenPointFromFrame(clip->timeline_in), getScreenPointFromTrack(clip->track), getScreenPointFromFrame(panel_timeline->zoom, clip->getLength()), panel_timeline->calculate_track_height(clip->track, -1)); + QRect text_rect(clip_rect.left() + olive::timeline::kClipTextPadding, clip_rect.top() + olive::timeline::kClipTextPadding, clip_rect.width() - olive::timeline::kClipTextPadding - 1, clip_rect.height() - olive::timeline::kClipTextPadding - 1); + if (clip_rect.left() < width() && clip_rect.right() >= 0 && clip_rect.top() < height() && clip_rect.bottom() >= 0) { + QRect actual_clip_rect = clip_rect; + if (actual_clip_rect.x() < 0) actual_clip_rect.setX(0); + if (actual_clip_rect.right() > width()) actual_clip_rect.setRight(width()); + if (actual_clip_rect.y() < 0) actual_clip_rect.setY(0); + if (actual_clip_rect.bottom() > height()) actual_clip_rect.setBottom(height()); + p.fillRect(actual_clip_rect, (clip->enabled) ? QColor(clip->color_r, clip->color_g, clip->color_b) : QColor(96, 96, 96)); - int thumb_x = clip_rect.x() + 1; + int thumb_x = clip_rect.x() + 1; - if (clip->media != nullptr && clip->media->get_type() == MEDIA_TYPE_FOOTAGE) { - bool draw_checkerboard = false; - QRect checkerboard_rect(clip_rect); - FootagePtr m = clip->media->to_footage(); - FootageStream* ms = m->get_stream_from_file_index(clip->track < 0, clip->media_stream); - if (ms == nullptr) { - draw_checkerboard = true; - } else if (ms->preview_done) { - // draw top and tail triangles - int triangle_size = olive::timeline::kTrackMinHeight >> 2; - if (!ms->infinite_length && clip_rect.width() > triangle_size) { - p.setPen(Qt::NoPen); - p.setBrush(QColor(80, 80, 80)); - if (clip->clip_in == 0 - && clip_rect.x() + triangle_size > 0 - && clip_rect.y() + triangle_size > 0 - && clip_rect.x() < width() - && clip_rect.y() < height()) { - const QPoint points[3] = { - QPoint(clip_rect.x(), clip_rect.y()), - QPoint(clip_rect.x() + triangle_size, clip_rect.y()), - QPoint(clip_rect.x(), clip_rect.y() + triangle_size) - }; - p.drawPolygon(points, 3); - text_rect.setLeft(text_rect.left() + (triangle_size >> 2)); - } - if (clip->timeline_out - clip->timeline_in + clip->clip_in == clip->getMaximumLength() - && clip_rect.right() - triangle_size < width() - && clip_rect.y() + triangle_size > 0 - && clip_rect.right() > 0 - && clip_rect.y() < height()) { - const QPoint points[3] = { - QPoint(clip_rect.right(), clip_rect.y()), - QPoint(clip_rect.right() - triangle_size, clip_rect.y()), - QPoint(clip_rect.right(), clip_rect.y() + triangle_size) - }; - p.drawPolygon(points, 3); - text_rect.setRight(text_rect.right() - (triangle_size >> 2)); - } - } + if (clip->media != nullptr && clip->media->get_type() == MEDIA_TYPE_FOOTAGE) { + bool draw_checkerboard = false; + QRect checkerboard_rect(clip_rect); + FootagePtr m = clip->media->to_footage(); + FootageStream* ms = m->get_stream_from_file_index(clip->track < 0, clip->media_stream); + if (ms == nullptr) { + draw_checkerboard = true; + } else if (ms->preview_done) { + // draw top and tail triangles + int triangle_size = olive::timeline::kTrackMinHeight >> 2; + if (!ms->infinite_length && clip_rect.width() > triangle_size) { + p.setPen(Qt::NoPen); + p.setBrush(QColor(80, 80, 80)); + if (clip->clip_in == 0 + && clip_rect.x() + triangle_size > 0 + && clip_rect.y() + triangle_size > 0 + && clip_rect.x() < width() + && clip_rect.y() < height()) { + const QPoint points[3] = { + QPoint(clip_rect.x(), clip_rect.y()), + QPoint(clip_rect.x() + triangle_size, clip_rect.y()), + QPoint(clip_rect.x(), clip_rect.y() + triangle_size) + }; + p.drawPolygon(points, 3); + text_rect.setLeft(text_rect.left() + (triangle_size >> 2)); + } + if (clip->timeline_out - clip->timeline_in + clip->clip_in == clip->getMaximumLength() + && clip_rect.right() - triangle_size < width() + && clip_rect.y() + triangle_size > 0 + && clip_rect.right() > 0 + && clip_rect.y() < height()) { + const QPoint points[3] = { + QPoint(clip_rect.right(), clip_rect.y()), + QPoint(clip_rect.right() - triangle_size, clip_rect.y()), + QPoint(clip_rect.right(), clip_rect.y() + triangle_size) + }; + p.drawPolygon(points, 3); + text_rect.setRight(text_rect.right() - (triangle_size >> 2)); + } + } - p.setBrush(Qt::NoBrush); + p.setBrush(Qt::NoBrush); - // draw thumbnail/waveform - long media_length = clip->getMaximumLength(); + // draw thumbnail/waveform + long media_length = clip->getMaximumLength(); - if (clip->track < 0) { - // draw thumbnail - int thumb_y = p.fontMetrics().height()+olive::timeline::kClipTextPadding+olive::timeline::kClipTextPadding; - if (thumb_x < width() && thumb_y < height()) { - int space_for_thumb = clip_rect.width()-1; - if (clip->get_opening_transition() != nullptr) { - int ot_width = getScreenPointFromFrame(panel_timeline->zoom, clip->get_opening_transition()->get_true_length()); - thumb_x += ot_width; - space_for_thumb -= ot_width; - } - if (clip->get_closing_transition() != nullptr) { - space_for_thumb -= getScreenPointFromFrame(panel_timeline->zoom, clip->get_closing_transition()->get_true_length()); - } - int thumb_height = clip_rect.height()-thumb_y; - int thumb_width = qRound(thumb_height*(double(ms->video_preview.width())/double(ms->video_preview.height()))); - if (thumb_x + thumb_width >= 0 - && thumb_height > thumb_y - && thumb_y + thumb_height >= 0 - && space_for_thumb > MAX_TEXT_WIDTH) { - int thumb_clip_width = qMin(thumb_width, space_for_thumb); - p.drawImage(QRect(thumb_x, - clip_rect.y()+thumb_y, - thumb_clip_width, - thumb_height), - ms->video_preview, - QRect(0, - 0, - qRound(thumb_clip_width*(double(ms->video_preview.width())/double(thumb_width))), - ms->video_preview.height() - ) - ); - } - } - if (clip->timeline_out - clip->timeline_in + clip->clip_in > clip->getMaximumLength()) { - draw_checkerboard = true; - checkerboard_rect.setLeft(panel_timeline->getTimelineScreenPointFromFrame(clip->getMaximumLength() + clip->timeline_in - clip->clip_in)); - } - } else if (clip_rect.height() > olive::timeline::kTrackMinHeight) { - // draw waveform - p.setPen(QColor(80, 80, 80)); + if (clip->track < 0) { + // draw thumbnail + int thumb_y = p.fontMetrics().height()+olive::timeline::kClipTextPadding+olive::timeline::kClipTextPadding; + if (thumb_x < width() && thumb_y < height()) { + int space_for_thumb = clip_rect.width()-1; + if (clip->get_opening_transition() != nullptr) { + int ot_width = getScreenPointFromFrame(panel_timeline->zoom, clip->get_opening_transition()->get_true_length()); + thumb_x += ot_width; + space_for_thumb -= ot_width; + } + if (clip->get_closing_transition() != nullptr) { + space_for_thumb -= getScreenPointFromFrame(panel_timeline->zoom, clip->get_closing_transition()->get_true_length()); + } + int thumb_height = clip_rect.height()-thumb_y; + int thumb_width = qRound(thumb_height*(double(ms->video_preview.width())/double(ms->video_preview.height()))); + if (thumb_x + thumb_width >= 0 + && thumb_height > thumb_y + && thumb_y + thumb_height >= 0 + && space_for_thumb > MAX_TEXT_WIDTH) { + int thumb_clip_width = qMin(thumb_width, space_for_thumb); + p.drawImage(QRect(thumb_x, + clip_rect.y()+thumb_y, + thumb_clip_width, + thumb_height), + ms->video_preview, + QRect(0, + 0, + qRound(thumb_clip_width*(double(ms->video_preview.width())/double(thumb_width))), + ms->video_preview.height() + ) + ); + } + } + if (clip->timeline_out - clip->timeline_in + clip->clip_in > clip->getMaximumLength()) { + draw_checkerboard = true; + checkerboard_rect.setLeft(panel_timeline->getTimelineScreenPointFromFrame(clip->getMaximumLength() + clip->timeline_in - clip->clip_in)); + } + } else if (clip_rect.height() > olive::timeline::kTrackMinHeight) { + // draw waveform + p.setPen(QColor(80, 80, 80)); - int waveform_start = -qMin(clip_rect.x(), 0); - int waveform_limit = qMin(clip_rect.width(), getScreenPointFromFrame(panel_timeline->zoom, media_length - clip->clip_in)); + int waveform_start = -qMin(clip_rect.x(), 0); + int waveform_limit = qMin(clip_rect.width(), getScreenPointFromFrame(panel_timeline->zoom, media_length - clip->clip_in)); - if ((clip_rect.x() + waveform_limit) > width()) { - waveform_limit -= (clip_rect.x() + waveform_limit - width()); - } else if (waveform_limit < clip_rect.width()) { - draw_checkerboard = true; - if (waveform_limit > 0) checkerboard_rect.setLeft(checkerboard_rect.left() + waveform_limit); - } + if ((clip_rect.x() + waveform_limit) > width()) { + waveform_limit -= (clip_rect.x() + waveform_limit - width()); + } else if (waveform_limit < clip_rect.width()) { + draw_checkerboard = true; + if (waveform_limit > 0) checkerboard_rect.setLeft(checkerboard_rect.left() + waveform_limit); + } - draw_waveform(clip, ms, media_length, &p, clip_rect, waveform_start, waveform_limit, panel_timeline->zoom); - } - } - if (draw_checkerboard) { - checkerboard_rect.setLeft(qMax(checkerboard_rect.left(), 0)); - checkerboard_rect.setRight(qMin(checkerboard_rect.right(), width())); - checkerboard_rect.setTop(qMax(checkerboard_rect.top(), 0)); - checkerboard_rect.setBottom(qMin(checkerboard_rect.bottom(), height())); + draw_waveform(clip, ms, media_length, &p, clip_rect, waveform_start, waveform_limit, panel_timeline->zoom); + } + } + if (draw_checkerboard) { + checkerboard_rect.setLeft(qMax(checkerboard_rect.left(), 0)); + checkerboard_rect.setRight(qMin(checkerboard_rect.right(), width())); + checkerboard_rect.setTop(qMax(checkerboard_rect.top(), 0)); + checkerboard_rect.setBottom(qMin(checkerboard_rect.bottom(), height())); - if (checkerboard_rect.left() < width() - && checkerboard_rect.right() >= 0 - && checkerboard_rect.top() < height() - && checkerboard_rect.bottom() >= 0) { - // draw "error lines" if media stream is missing - p.setPen(QPen(QColor(64, 64, 64), 2)); - int limit = checkerboard_rect.width(); - int clip_height = checkerboard_rect.height(); - for (int j=-clip_height;j checkerboard_rect.right()) { - lines_end_y -= (checkerboard_rect.right() - lines_end_x); - lines_end_x = checkerboard_rect.right(); - } - p.drawLine(lines_start_x, lines_start_y, lines_end_x, lines_end_y); - } - } - } - } + if (checkerboard_rect.left() < width() + && checkerboard_rect.right() >= 0 + && checkerboard_rect.top() < height() + && checkerboard_rect.bottom() >= 0) { + // draw "error lines" if media stream is missing + p.setPen(QPen(QColor(64, 64, 64), 2)); + int limit = checkerboard_rect.width(); + int clip_height = checkerboard_rect.height(); + for (int j=-clip_height;j checkerboard_rect.right()) { + lines_end_y -= (checkerboard_rect.right() - lines_end_x); + lines_end_x = checkerboard_rect.right(); + } + p.drawLine(lines_start_x, lines_start_y, lines_end_x, lines_end_y); + } + } + } + } - // draw clip markers - for (int j=0;jget_markers().size();j++) { - const Marker& m = clip->get_markers().at(j); + // draw clip markers + for (int j=0;jget_markers().size();j++) { + const Marker& m = clip->get_markers().at(j); - // convert marker time (in clip time) to sequence time - long marker_time = m.frame + clip->timeline_in - clip->clip_in; - int marker_x = panel_timeline->getTimelineScreenPointFromFrame(marker_time); - if (marker_x > clip_rect.x() && marker_x < clip_rect.right()) { - draw_marker(p, marker_x, clip_rect.bottom()-p.fontMetrics().height(), clip_rect.bottom(), false); - } - } - p.setBrush(Qt::NoBrush); + // convert marker time (in clip time) to sequence time + long marker_time = m.frame + clip->timeline_in - clip->clip_in; + int marker_x = panel_timeline->getTimelineScreenPointFromFrame(marker_time); + if (marker_x > clip_rect.x() && marker_x < clip_rect.right()) { + draw_marker(p, marker_x, clip_rect.bottom()-p.fontMetrics().height(), clip_rect.bottom(), false); + } + } + p.setBrush(Qt::NoBrush); - // draw clip transitions - draw_transition(p, clip, clip_rect, text_rect, kTransitionOpening); - draw_transition(p, clip, clip_rect, text_rect, kTransitionClosing); + // draw clip transitions + draw_transition(p, clip, clip_rect, text_rect, kTransitionOpening); + draw_transition(p, clip, clip_rect, text_rect, kTransitionClosing); - // top left bevel - p.setPen(Qt::white); - if (clip_rect.x() >= 0 && clip_rect.x() < width()) p.drawLine(clip_rect.bottomLeft(), clip_rect.topLeft()); - if (clip_rect.y() >= 0 && clip_rect.y() < height()) p.drawLine(QPoint(qMax(0, clip_rect.left()), clip_rect.top()), QPoint(qMin(width(), clip_rect.right()), clip_rect.top())); + // top left bevel + p.setPen(Qt::white); + if (clip_rect.x() >= 0 && clip_rect.x() < width()) p.drawLine(clip_rect.bottomLeft(), clip_rect.topLeft()); + if (clip_rect.y() >= 0 && clip_rect.y() < height()) p.drawLine(QPoint(qMax(0, clip_rect.left()), clip_rect.top()), QPoint(qMin(width(), clip_rect.right()), clip_rect.top())); - // draw text - if (text_rect.width() > MAX_TEXT_WIDTH && text_rect.right() > 0 && text_rect.left() < width()) { - if (!clip->enabled) { - p.setPen(Qt::gray); - } else if (color_brightness(clip->color_r, clip->color_g, clip->color_b) > 160) { - // set to black if color is bright - p.setPen(Qt::black); - } - if (clip->linked.size() > 0) { - int underline_y = olive::timeline::kClipTextPadding + p.fontMetrics().height() + clip_rect.top(); - int underline_width = qMin(text_rect.width() - 1, p.fontMetrics().width(clip->name)); - p.drawLine(text_rect.x(), underline_y, text_rect.x() + underline_width, underline_y); - } - QString name = clip->name; - if (clip->speed != 1.0 || clip->reverse) { - name += " ("; - if (clip->reverse) name += "-"; - name += QString::number(clip->speed*100) + "%)"; - } - p.drawText(text_rect, 0, name, &text_rect); - } + // draw text + if (text_rect.width() > MAX_TEXT_WIDTH && text_rect.right() > 0 && text_rect.left() < width()) { + if (!clip->enabled) { + p.setPen(Qt::gray); + } else if (color_brightness(clip->color_r, clip->color_g, clip->color_b) > 160) { + // set to black if color is bright + p.setPen(Qt::black); + } + if (clip->linked.size() > 0) { + int underline_y = olive::timeline::kClipTextPadding + p.fontMetrics().height() + clip_rect.top(); + int underline_width = qMin(text_rect.width() - 1, p.fontMetrics().width(clip->name)); + p.drawLine(text_rect.x(), underline_y, text_rect.x() + underline_width, underline_y); + } + QString name = clip->name; + if (clip->speed != 1.0 || clip->reverse) { + name += " ("; + if (clip->reverse) name += "-"; + name += QString::number(clip->speed*100) + "%)"; + } + p.drawText(text_rect, 0, name, &text_rect); + } - // bottom right gray - p.setPen(QColor(0, 0, 0, 128)); - if (clip_rect.right() >= 0 && clip_rect.right() < width()) p.drawLine(clip_rect.bottomRight(), clip_rect.topRight()); - if (clip_rect.bottom() >= 0 && clip_rect.bottom() < height()) p.drawLine(QPoint(qMax(0, clip_rect.left()), clip_rect.bottom()), QPoint(qMin(width(), clip_rect.right()), clip_rect.bottom())); + // bottom right gray + p.setPen(QColor(0, 0, 0, 128)); + if (clip_rect.right() >= 0 && clip_rect.right() < width()) p.drawLine(clip_rect.bottomRight(), clip_rect.topRight()); + if (clip_rect.bottom() >= 0 && clip_rect.bottom() < height()) p.drawLine(QPoint(qMax(0, clip_rect.left()), clip_rect.bottom()), QPoint(qMin(width(), clip_rect.right()), clip_rect.bottom())); - // draw transition tool - if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION && (panel_timeline->transition_tool_pre_clip == i || panel_timeline->transition_tool_post_clip == i)) { - int type = panel_timeline->transition_tool_type; - if (panel_timeline->transition_tool_post_clip == i) { - // invert transition type - type = (type == kTransitionClosing) ? kTransitionOpening : kTransitionClosing; - } - QRect transition_tool_rect = clip_rect; - if (type == kTransitionClosing) { - if (panel_timeline->transition_tool_post_clip > -1) { - transition_tool_rect.setLeft(transition_tool_rect.right() - TRANSITION_BETWEEN_RANGE); - } else { - transition_tool_rect.setLeft(transition_tool_rect.left() + (3*(transition_tool_rect.width()>>2))); - } - } else { - if (panel_timeline->transition_tool_post_clip > -1) { - transition_tool_rect.setWidth(TRANSITION_BETWEEN_RANGE); - } else { - transition_tool_rect.setWidth(transition_tool_rect.width()>>2); - } - } - if (transition_tool_rect.left() < width() && transition_tool_rect.right() > 0) { - if (transition_tool_rect.left() < 0) { - transition_tool_rect.setLeft(0); - } - if (transition_tool_rect.right() > width()) { - transition_tool_rect.setRight(width()); - } - p.fillRect(transition_tool_rect, QColor(0, 0, 0, 128)); - } - } - } - } - } + // draw transition tool + if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION && (panel_timeline->transition_tool_pre_clip == i || panel_timeline->transition_tool_post_clip == i)) { + int type = panel_timeline->transition_tool_type; + if (panel_timeline->transition_tool_post_clip == i) { + // invert transition type + type = (type == kTransitionClosing) ? kTransitionOpening : kTransitionClosing; + } + QRect transition_tool_rect = clip_rect; + if (type == kTransitionClosing) { + if (panel_timeline->transition_tool_post_clip > -1) { + transition_tool_rect.setLeft(transition_tool_rect.right() - TRANSITION_BETWEEN_RANGE); + } else { + transition_tool_rect.setLeft(transition_tool_rect.left() + (3*(transition_tool_rect.width()>>2))); + } + } else { + if (panel_timeline->transition_tool_post_clip > -1) { + transition_tool_rect.setWidth(TRANSITION_BETWEEN_RANGE); + } else { + transition_tool_rect.setWidth(transition_tool_rect.width()>>2); + } + } + if (transition_tool_rect.left() < width() && transition_tool_rect.right() > 0) { + if (transition_tool_rect.left() < 0) { + transition_tool_rect.setLeft(0); + } + if (transition_tool_rect.right() > width()) { + transition_tool_rect.setRight(width()); + } + p.fillRect(transition_tool_rect, QColor(0, 0, 0, 128)); + } + } + } + } + } - // Draw recording clip if recording if valid - if (panel_sequence_viewer->is_recording_cued() && is_track_visible(panel_sequence_viewer->recording_track)) { - int rec_track_x = panel_timeline->getTimelineScreenPointFromFrame(panel_sequence_viewer->recording_start); - int rec_track_y = getScreenPointFromTrack(panel_sequence_viewer->recording_track); - int rec_track_height = panel_timeline->calculate_track_height(panel_sequence_viewer->recording_track, -1); - if (panel_sequence_viewer->recording_start != panel_sequence_viewer->recording_end) { - QRect rec_rect( - rec_track_x, - rec_track_y, - getScreenPointFromFrame(panel_timeline->zoom, panel_sequence_viewer->recording_end - panel_sequence_viewer->recording_start), - rec_track_height - ); - p.setPen(QPen(QColor(96, 96, 96), 2)); - p.fillRect(rec_rect, QColor(192, 192, 192)); - p.drawRect(rec_rect); - } - QRect active_rec_rect( - rec_track_x, - rec_track_y, - getScreenPointFromFrame(panel_timeline->zoom, panel_sequence_viewer->seq->playhead - panel_sequence_viewer->recording_start), - rec_track_height - ); - p.setPen(QPen(QColor(192, 0, 0), 2)); - p.fillRect(active_rec_rect, QColor(255, 96, 96)); - p.drawRect(active_rec_rect); + // Draw recording clip if recording if valid + if (panel_sequence_viewer->is_recording_cued() && is_track_visible(panel_sequence_viewer->recording_track)) { + int rec_track_x = panel_timeline->getTimelineScreenPointFromFrame(panel_sequence_viewer->recording_start); + int rec_track_y = getScreenPointFromTrack(panel_sequence_viewer->recording_track); + int rec_track_height = panel_timeline->calculate_track_height(panel_sequence_viewer->recording_track, -1); + if (panel_sequence_viewer->recording_start != panel_sequence_viewer->recording_end) { + QRect rec_rect( + rec_track_x, + rec_track_y, + getScreenPointFromFrame(panel_timeline->zoom, panel_sequence_viewer->recording_end - panel_sequence_viewer->recording_start), + rec_track_height + ); + p.setPen(QPen(QColor(96, 96, 96), 2)); + p.fillRect(rec_rect, QColor(192, 192, 192)); + p.drawRect(rec_rect); + } + QRect active_rec_rect( + rec_track_x, + rec_track_y, + getScreenPointFromFrame(panel_timeline->zoom, panel_sequence_viewer->seq->playhead - panel_sequence_viewer->recording_start), + rec_track_height + ); + p.setPen(QPen(QColor(192, 0, 0), 2)); + p.fillRect(active_rec_rect, QColor(255, 96, 96)); + p.drawRect(active_rec_rect); - p.setPen(Qt::NoPen); + p.setPen(Qt::NoPen); - if (!panel_sequence_viewer->playing) { - int rec_marker_size = 6; - int rec_track_midY = rec_track_y + (rec_track_height >> 1); - p.setBrush(Qt::white); - QPoint cue_marker[3] = { - QPoint(rec_track_x, rec_track_midY - rec_marker_size), - QPoint(rec_track_x + rec_marker_size, rec_track_midY), - QPoint(rec_track_x, rec_track_midY + rec_marker_size) - }; - p.drawPolygon(cue_marker, 3); - } - } + if (!panel_sequence_viewer->playing) { + int rec_marker_size = 6; + int rec_track_midY = rec_track_y + (rec_track_height >> 1); + p.setBrush(Qt::white); + QPoint cue_marker[3] = { + QPoint(rec_track_x, rec_track_midY - rec_marker_size), + QPoint(rec_track_x + rec_marker_size, rec_track_midY), + QPoint(rec_track_x, rec_track_midY + rec_marker_size) + }; + p.drawPolygon(cue_marker, 3); + } + } - // Draw track lines - if (olive::CurrentConfig.show_track_lines) { - p.setPen(QColor(0, 0, 0, 96)); - audio_track_limit++; - if (video_track_limit == 0) video_track_limit--; + // Draw track lines + if (olive::CurrentConfig.show_track_lines) { + p.setPen(QColor(0, 0, 0, 96)); + audio_track_limit++; + if (video_track_limit == 0) video_track_limit--; - if (bottom_align) { - // only draw lines for video tracks - for (int i=video_track_limit;i<0;i++) { - int line_y = getScreenPointFromTrack(i) - 1; - p.drawLine(0, line_y, rect().width(), line_y); - } - } else { - // only draw lines for audio tracks - for (int i=0;icalculate_track_height(i, -1); - p.drawLine(0, line_y, rect().width(), line_y); - } - } - } + if (bottom_align) { + // only draw lines for video tracks + for (int i=video_track_limit;i<0;i++) { + int line_y = getScreenPointFromTrack(i) - 1; + p.drawLine(0, line_y, rect().width(), line_y); + } + } else { + // only draw lines for audio tracks + for (int i=0;icalculate_track_height(i, -1); + p.drawLine(0, line_y, rect().width(), line_y); + } + } + } - // Draw selections - for (int i=0;iselections.size();i++) { - const Selection& s = olive::ActiveSequence->selections.at(i); - if (is_track_visible(s.track)) { - int selection_y = getScreenPointFromTrack(s.track); - int selection_x = panel_timeline->getTimelineScreenPointFromFrame(s.in); - p.setPen(Qt::NoPen); - p.setBrush(Qt::NoBrush); - p.fillRect(selection_x, selection_y, panel_timeline->getTimelineScreenPointFromFrame(s.out) - selection_x, panel_timeline->calculate_track_height(s.track, -1), QColor(0, 0, 0, 64)); - } - } + // Draw selections + for (int i=0;iselections.size();i++) { + const Selection& s = olive::ActiveSequence->selections.at(i); + if (is_track_visible(s.track)) { + int selection_y = getScreenPointFromTrack(s.track); + int selection_x = panel_timeline->getTimelineScreenPointFromFrame(s.in); + p.setPen(Qt::NoPen); + p.setBrush(Qt::NoBrush); + p.fillRect(selection_x, selection_y, panel_timeline->getTimelineScreenPointFromFrame(s.out) - selection_x, panel_timeline->calculate_track_height(s.track, -1), QColor(0, 0, 0, 64)); + } + } - // draw rectangle select - if (panel_timeline->rect_select_proc) { - int rsy = panel_timeline->rect_select_y; - int rsh = panel_timeline->rect_select_h; - if (bottom_align) { - rsy += height(); - } - QRect rect_select(panel_timeline->rect_select_x, rsy, panel_timeline->rect_select_w, rsh); - draw_selection_rectangle(p, rect_select); - } + // draw rectangle select + if (panel_timeline->rect_select_proc) { + int rsy = panel_timeline->rect_select_y; + int rsh = panel_timeline->rect_select_h; + if (bottom_align) { + rsy += height(); + } + QRect rect_select(panel_timeline->rect_select_x, rsy, panel_timeline->rect_select_w, rsh); + draw_selection_rectangle(p, rect_select); + } - // Draw ghosts - if (!panel_timeline->ghosts.isEmpty()) { - QVector insert_points; - long first_ghost = LONG_MAX; - for (int i=0;ighosts.size();i++) { - const Ghost& g = panel_timeline->ghosts.at(i); - first_ghost = qMin(first_ghost, g.in); - if (is_track_visible(g.track)) { - int ghost_x = panel_timeline->getTimelineScreenPointFromFrame(g.in); - int ghost_y = getScreenPointFromTrack(g.track); - int ghost_width = panel_timeline->getTimelineScreenPointFromFrame(g.out) - ghost_x - 1; - int ghost_height = panel_timeline->calculate_track_height(g.track, -1) - 1; + // Draw ghosts + if (!panel_timeline->ghosts.isEmpty()) { + QVector insert_points; + long first_ghost = LONG_MAX; + for (int i=0;ighosts.size();i++) { + const Ghost& g = panel_timeline->ghosts.at(i); + first_ghost = qMin(first_ghost, g.in); + if (is_track_visible(g.track)) { + int ghost_x = panel_timeline->getTimelineScreenPointFromFrame(g.in); + int ghost_y = getScreenPointFromTrack(g.track); + int ghost_width = panel_timeline->getTimelineScreenPointFromFrame(g.out) - ghost_x - 1; + int ghost_height = panel_timeline->calculate_track_height(g.track, -1) - 1; - insert_points.append(ghost_y + (ghost_height>>1)); + insert_points.append(ghost_y + (ghost_height>>1)); - p.setPen(QColor(255, 255, 0)); - for (int j=0;jmove_insert && !insert_points.isEmpty()) { - p.setBrush(Qt::white); - p.setPen(Qt::NoPen); - int insert_x = panel_timeline->getTimelineScreenPointFromFrame(first_ghost); - int tri_size = olive::timeline::kTrackMinHeight>>2; + // draw insert indicator + if (panel_timeline->move_insert && !insert_points.isEmpty()) { + p.setBrush(Qt::white); + p.setPen(Qt::NoPen); + int insert_x = panel_timeline->getTimelineScreenPointFromFrame(first_ghost); + int tri_size = olive::timeline::kTrackMinHeight>>2; - for (int i=0;isplitting) { - for (int i=0;isplit_tracks.size();i++) { - if (is_track_visible(panel_timeline->split_tracks.at(i))) { - int cursor_x = panel_timeline->getTimelineScreenPointFromFrame(panel_timeline->drag_frame_start); - int cursor_y = getScreenPointFromTrack(panel_timeline->split_tracks.at(i)); + // Draw splitting cursor + if (panel_timeline->splitting) { + for (int i=0;isplit_tracks.size();i++) { + if (is_track_visible(panel_timeline->split_tracks.at(i))) { + int cursor_x = panel_timeline->getTimelineScreenPointFromFrame(panel_timeline->drag_frame_start); + int cursor_y = getScreenPointFromTrack(panel_timeline->split_tracks.at(i)); - p.setPen(QColor(64, 64, 64)); - p.drawLine(cursor_x, cursor_y, cursor_x, cursor_y + panel_timeline->calculate_track_height(panel_timeline->split_tracks.at(i), -1)); - } - } - } + p.setPen(QColor(64, 64, 64)); + p.drawLine(cursor_x, cursor_y, cursor_x, cursor_y + panel_timeline->calculate_track_height(panel_timeline->split_tracks.at(i), -1)); + } + } + } - // Draw playhead - p.setPen(Qt::red); - int playhead_x = panel_timeline->getTimelineScreenPointFromFrame(olive::ActiveSequence->playhead); - p.drawLine(playhead_x, rect().top(), playhead_x, rect().bottom()); + // Draw playhead + p.setPen(Qt::red); + int playhead_x = panel_timeline->getTimelineScreenPointFromFrame(olive::ActiveSequence->playhead); + p.drawLine(playhead_x, rect().top(), playhead_x, rect().bottom()); - // draw border - p.setPen(QColor(0, 0, 0, 64)); - int edge_y = (bottom_align) ? rect().height()-1 : 0; - p.drawLine(0, edge_y, rect().width(), edge_y); + // draw border + p.setPen(QColor(0, 0, 0, 64)); + int edge_y = (bottom_align) ? rect().height()-1 : 0; + p.drawLine(0, edge_y, rect().width(), edge_y); - // draw snap point - if (panel_timeline->snapped) { - p.setPen(Qt::white); - int snap_x = panel_timeline->getTimelineScreenPointFromFrame(panel_timeline->snap_point); - p.drawLine(snap_x, 0, snap_x, height()); - } + // draw snap point + if (panel_timeline->snapped) { + p.setPen(Qt::white); + int snap_x = panel_timeline->getTimelineScreenPointFromFrame(panel_timeline->snap_point); + p.drawLine(snap_x, 0, snap_x, height()); + } - // Draw edit cursor - if (isLiveEditing() && is_track_visible(panel_timeline->cursor_track)) { - int cursor_x = panel_timeline->getTimelineScreenPointFromFrame(panel_timeline->cursor_frame); - int cursor_y = getScreenPointFromTrack(panel_timeline->cursor_track); + // Draw edit cursor + if (isLiveEditing() && is_track_visible(panel_timeline->cursor_track)) { + int cursor_x = panel_timeline->getTimelineScreenPointFromFrame(panel_timeline->cursor_frame); + int cursor_y = getScreenPointFromTrack(panel_timeline->cursor_track); - p.setPen(Qt::gray); - p.drawLine(cursor_x, cursor_y, cursor_x, cursor_y + panel_timeline->calculate_track_height(panel_timeline->cursor_track, -1)); - } - } + p.setPen(Qt::gray); + p.drawLine(cursor_x, cursor_y, cursor_x, cursor_y + panel_timeline->calculate_track_height(panel_timeline->cursor_track, -1)); + } + } } void TimelineWidget::resizeEvent(QResizeEvent *) { - scrollBar->setPageStep(height()); + scrollBar->setPageStep(height()); } bool TimelineWidget::is_track_visible(int track) { - return (bottom_align == (track < 0)); + return (bottom_align == (track < 0)); } // ************************************** @@ -2827,55 +2827,55 @@ bool TimelineWidget::is_track_visible(int track) { // ************************************** int TimelineWidget::getTrackFromScreenPoint(int y) { - y += scroll; - if (bottom_align) { - y = -(y - height()); - } - y--; - int height_measure = 0; - int counter = ((!bottom_align && y > 0) || (bottom_align && y < 0)) ? 0 : -1; - int track_height = panel_timeline->calculate_track_height(counter, -1); - while (qAbs(y) > height_measure+track_height) { - if (olive::CurrentConfig.show_track_lines && counter != -1) y--; - height_measure += track_height; - if ((!bottom_align && y > 0) || (bottom_align && y < 0)) { - counter++; - } else { - counter--; - } - track_height = panel_timeline->calculate_track_height(counter, -1); - } - return counter; + y += scroll; + if (bottom_align) { + y = -(y - height()); + } + y--; + int height_measure = 0; + int counter = ((!bottom_align && y > 0) || (bottom_align && y < 0)) ? 0 : -1; + int track_height = panel_timeline->calculate_track_height(counter, -1); + while (qAbs(y) > height_measure+track_height) { + if (olive::CurrentConfig.show_track_lines && counter != -1) y--; + height_measure += track_height; + if ((!bottom_align && y > 0) || (bottom_align && y < 0)) { + counter++; + } else { + counter--; + } + track_height = panel_timeline->calculate_track_height(counter, -1); + } + return counter; } int TimelineWidget::getScreenPointFromTrack(int track) { - int y = 0; - int counter = 0; - while (counter != track) { - if (bottom_align) counter--; - y += panel_timeline->calculate_track_height(counter, -1); - if (!bottom_align) counter++; - if (olive::CurrentConfig.show_track_lines && counter != -1) y++; - } - y++; - return (bottom_align) ? height() - y - scroll : y - scroll; + int y = 0; + int counter = 0; + while (counter != track) { + if (bottom_align) counter--; + y += panel_timeline->calculate_track_height(counter, -1); + if (!bottom_align) counter++; + if (olive::CurrentConfig.show_track_lines && counter != -1) y++; + } + y++; + return (bottom_align) ? height() - y - scroll : y - scroll; } int TimelineWidget::getClipIndexFromCoords(long frame, int track) { - for (int i=0;iclips.size();i++) { - ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr && c->track == track && frame >= c->timeline_in && frame < c->timeline_out) { - return i; - } - } - return -1; + for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr && c->track == track && frame >= c->timeline_in && frame < c->timeline_out) { + return i; + } + } + return -1; } void TimelineWidget::setScroll(int s) { - scroll = s; - update(); + scroll = s; + update(); } void TimelineWidget::reveal_media() { - panel_project->reveal_media(rc_reveal_media); + panel_project->reveal_media(rc_reveal_media); } From eb55a89cfd0d746bf837a617ecd9debbf3869414 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sun, 17 Feb 2019 03:16:23 -0800 Subject: [PATCH 10/30] none bracket consistency --- panels/timeline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panels/timeline.cpp b/panels/timeline.cpp index db7e23312..4f3ae7e72 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -1845,7 +1845,7 @@ void Timeline::set_sb_max() { void Timeline::UpdateTitle() { QString title = tr("Timeline: "); if (olive::ActiveSequence == nullptr) { - setWindowTitle(title + tr("")); + setWindowTitle(title + tr("(none)")); } else { setWindowTitle(title + olive::ActiveSequence->name); update_ui(false); From 5cf5321c0f4ba38f0f9a05b691234e9b2d930196 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sun, 17 Feb 2019 03:36:23 -0800 Subject: [PATCH 11/30] further progress on translation without restart --- oliveglobal.cpp | 9 ++-- ui/mediaiconservice.cpp | 98 ++++++++++++++++++++++------------------- ui/mediaiconservice.h | 2 + 3 files changed, 61 insertions(+), 48 deletions(-) diff --git a/oliveglobal.cpp b/oliveglobal.cpp index 174df5b9f..7cd63139e 100644 --- a/oliveglobal.cpp +++ b/oliveglobal.cpp @@ -119,14 +119,17 @@ void OliveGlobal::load_translation_from_config() { olive::CurrentConfig.language_file : olive::CurrentRuntimeConfig.external_translation_file; + // clear runtime language file so if the user sets a different language, we won't load it next time + olive::CurrentRuntimeConfig.external_translation_file.clear(); + + // remove current translation if there is one + QApplication::removeTranslator(translator.get()); + if (!language_file.isEmpty()) { // translation files are stored relative to app path (see GitHub issue #454) QString full_language_path = QDir(get_app_path()).filePath(language_file); - // remove translation - QApplication::removeTranslator(translator.get()); - // load translation file if (QFileInfo::exists(full_language_path) && translator->load(full_language_path)) { diff --git a/ui/mediaiconservice.cpp b/ui/mediaiconservice.cpp index 6a2578d17..97e11aa6e 100644 --- a/ui/mediaiconservice.cpp +++ b/ui/mediaiconservice.cpp @@ -28,66 +28,74 @@ const int kThrobberSize = 50; std::unique_ptr olive::media_icon_service; MediaIconService::MediaIconService() { - // set up animation timer - throbber_animator_.setInterval(20); - connect(&throbber_animator_, SIGNAL(timeout()), this, SLOT(AnimationUpdate())); + // set up animation timer + throbber_animator_.setInterval(20); + connect(&throbber_animator_, SIGNAL(timeout()), this, SLOT(AnimationUpdate())); - // set up pixmap - throbber_pixmap_ = QPixmap(":/icons/throbber.png"); + // set up pixmap + throbber_pixmap_ = QPixmap(":/icons/throbber.png"); } void MediaIconService::SetMediaIcon(Media *media, int icon_type) { - // if this icon is already part of the throbber animation loop, remove it - if (throbber_items_.contains(media)) { - throbber_items_.removeAll(media); + // if this icon is already part of the throbber animation loop, remove it + if (throbber_items_.contains(media)) { +// throbber_lock_.lock(); - // if we aren't animating anything, no need to run the timer for now - if (throbber_items_.empty()) { - // ensure timer function is called in its own thread - QMetaObject::invokeMethod(&throbber_animator_, "stop", Qt::QueuedConnection); - } + throbber_items_.removeAll(media); + +// throbber_lock_.unlock(); + + // if we aren't animating anything, no need to run the timer for now + if (throbber_items_.empty()) { + // ensure timer function is called in its own thread + QMetaObject::invokeMethod(&throbber_animator_, "stop", Qt::QueuedConnection); } + } - switch (icon_type) { - case ICON_TYPE_VIDEO: - olive::project_model.set_icon(media, QIcon(":/icons/videosource.png")); - break; - case ICON_TYPE_AUDIO: - olive::project_model.set_icon(media, QIcon(":/icons/audiosource.png")); - break; - case ICON_TYPE_IMAGE: - olive::project_model.set_icon(media, QIcon(":/icons/imagesource.png")); - break; - case ICON_TYPE_LOADING: - throbber_items_.append(media); + switch (icon_type) { + case ICON_TYPE_VIDEO: + olive::project_model.set_icon(media, QIcon(":/icons/videosource.png")); + break; + case ICON_TYPE_AUDIO: + olive::project_model.set_icon(media, QIcon(":/icons/audiosource.png")); + break; + case ICON_TYPE_IMAGE: + olive::project_model.set_icon(media, QIcon(":/icons/imagesource.png")); + break; + case ICON_TYPE_LOADING: + throbber_items_.append(media); - // if the animation timer isn't running, start it - if (!throbber_animator_.isActive()) { - // set starting frame to 0 - throbber_animation_frame_ = 0; + // if the animation timer isn't running, start it + if (!throbber_animator_.isActive()) { + // set starting frame to 0 + throbber_animation_frame_ = 0; - // ensure timer function is called in its own thread - QMetaObject::invokeMethod(&throbber_animator_, "start", Qt::QueuedConnection); - } - break; - case ICON_TYPE_ERROR: - olive::project_model.set_icon(media, QIcon(":/icons/error.png")); - break; + // ensure timer function is called in its own thread + QMetaObject::invokeMethod(&throbber_animator_, "start", Qt::QueuedConnection); } + break; + case ICON_TYPE_ERROR: + olive::project_model.set_icon(media, QIcon(":/icons/error.png")); + break; + } - emit IconChanged(); + emit IconChanged(); } void MediaIconService::AnimationUpdate() { - if (throbber_animation_frame_ == kThrobberLimit) { - throbber_animation_frame_ = 0; - } + if (throbber_animation_frame_ == kThrobberLimit) { + throbber_animation_frame_ = 0; + } - QIcon throbber_ico = QIcon(throbber_pixmap_.copy(kThrobberSize*throbber_animation_frame_, 0, kThrobberSize, kThrobberSize)); + QIcon throbber_ico = QIcon(throbber_pixmap_.copy(kThrobberSize*throbber_animation_frame_, 0, kThrobberSize, kThrobberSize)); - for (int i=0;i #include +#include #include "project/media.h" @@ -49,6 +50,7 @@ private: QVector throbber_items_; QTimer throbber_animator_; QPixmap throbber_pixmap_; + QMutex throbber_lock_; }; namespace olive { From a63b4fbe5268689ae8779b7ea4619f45c4a2c28e Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sun, 17 Feb 2019 22:32:18 -0800 Subject: [PATCH 12/30] timeline minor refactor --- io/config.cpp | 480 +++++++++++------------ io/config.h | 104 ++--- mainwindow.cpp | 4 +- panels/grapheditor.cpp | 2 - panels/project.cpp | 2 - panels/timeline.cpp | 115 ++---- panels/timeline.h | 50 ++- panels/viewer.cpp | 2 - ui/timelinewidget.cpp | 861 +++++++++++++++++++++++++---------------- ui/timelinewidget.h | 103 ++--- 10 files changed, 944 insertions(+), 779 deletions(-) diff --git a/io/config.cpp b/io/config.cpp index 133dad50a..d4cbac676 100644 --- a/io/config.cpp +++ b/io/config.cpp @@ -33,258 +33,258 @@ Config olive::CurrentConfig; RuntimeConfig olive::CurrentRuntimeConfig; Config::Config() - : saved_layout(false), - show_track_lines(true), - scroll_zooms(false), - edit_tool_selects_links(false), - edit_tool_also_seeks(false), - select_also_seeks(false), - paste_seeks(true), - img_seq_formats("jpg|jpeg|bmp|tiff|tif|psd|png|tga|jp2|gif"), - rectified_waveforms(false), - default_transition_length(30), - timecode_view(TIMECODE_DROP), - show_title_safe_area(false), - use_custom_title_safe_ratio(false), - custom_title_safe_ratio(1), - enable_drag_files_to_timeline(true), - autoscale_by_default(false), - recording_mode(2), - enable_seek_to_import(false), - enable_audio_scrubbing(true), - drop_on_media_to_replace(true), - autoscroll(AUTOSCROLL_PAGE_SCROLL), - audio_rate(48000), - fast_seeking(false), - hover_focus(false), - project_view_type(PROJECT_VIEW_TREE), - set_name_with_marker(true), - show_project_toolbar(false), - previous_queue_size(3), - previous_queue_type(FRAME_QUEUE_TYPE_FRAMES), - upcoming_queue_size(0.5), - upcoming_queue_type(FRAME_QUEUE_TYPE_SECONDS), - loop(false), - seek_also_selects(false), - effect_textbox_lines(3), - use_software_fallback(false), - center_timeline_timecodes(true), - waveform_resolution(64), - thumbnail_resolution(120), - add_default_effects_to_clips(true) + : saved_layout(false), + show_track_lines(true), + scroll_zooms(false), + edit_tool_selects_links(false), + edit_tool_also_seeks(false), + select_also_seeks(false), + paste_seeks(true), + img_seq_formats("jpg|jpeg|bmp|tiff|tif|psd|png|tga|jp2|gif"), + rectified_waveforms(false), + default_transition_length(30), + timecode_view(TIMECODE_DROP), + show_title_safe_area(false), + use_custom_title_safe_ratio(false), + custom_title_safe_ratio(1), + enable_drag_files_to_timeline(true), + autoscale_by_default(false), + recording_mode(2), + enable_seek_to_import(false), + enable_audio_scrubbing(true), + drop_on_media_to_replace(true), + autoscroll(AUTOSCROLL_PAGE_SCROLL), + audio_rate(48000), + fast_seeking(false), + hover_focus(false), + project_view_type(PROJECT_VIEW_TREE), + set_name_with_marker(true), + show_project_toolbar(false), + previous_queue_size(3), + previous_queue_type(FRAME_QUEUE_TYPE_FRAMES), + upcoming_queue_size(0.5), + upcoming_queue_type(FRAME_QUEUE_TYPE_SECONDS), + loop(false), + seek_also_selects(false), + effect_textbox_lines(3), + use_software_fallback(false), + center_timeline_timecodes(true), + waveform_resolution(64), + thumbnail_resolution(120), + add_default_effects_to_clips(true) {} void Config::load(QString path) { - QFile f(path); - if (f.exists() && f.open(QIODevice::ReadOnly)) { - QXmlStreamReader stream(&f); + QFile f(path); + if (f.exists() && f.open(QIODevice::ReadOnly)) { + QXmlStreamReader stream(&f); - while (!stream.atEnd()) { - stream.readNext(); - if (stream.isStartElement()) { - if (stream.name() == "SavedLayout") { - stream.readNext(); - saved_layout = (stream.text() == "1"); - } else if (stream.name() == "ShowTrackLines") { - stream.readNext(); - show_track_lines = (stream.text() == "1"); - } else if (stream.name() == "ScrollZooms") { - stream.readNext(); - scroll_zooms = (stream.text() == "1"); - } else if (stream.name() == "EditToolSelectsLinks") { - stream.readNext(); - edit_tool_selects_links = (stream.text() == "1"); - } else if (stream.name() == "EditToolAlsoSeeks") { - stream.readNext(); - edit_tool_also_seeks = (stream.text() == "1"); - } else if (stream.name() == "SelectAlsoSeeks") { - stream.readNext(); - select_also_seeks = (stream.text() == "1"); - } else if (stream.name() == "PasteSeeks") { - stream.readNext(); - paste_seeks = (stream.text() == "1"); - } else if (stream.name() == "ImageSequenceFormats") { - stream.readNext(); - img_seq_formats = stream.text().toString(); - } else if (stream.name() == "RectifiedWaveforms") { - stream.readNext(); - rectified_waveforms = (stream.text() == "1"); - } else if (stream.name() == "DefaultTransitionLength") { - stream.readNext(); - default_transition_length = stream.text().toInt(); - } else if (stream.name() == "TimecodeView") { - stream.readNext(); - timecode_view = stream.text().toInt(); - } else if (stream.name() == "ShowTitleSafeArea") { - stream.readNext(); - show_title_safe_area = (stream.text() == "1"); - } else if (stream.name() == "UseCustomTitleSafeRatio") { - stream.readNext(); - use_custom_title_safe_ratio = (stream.text() == "1"); - } else if (stream.name() == "CustomTitleSafeRatio") { - stream.readNext(); - custom_title_safe_ratio = stream.text().toDouble(); - } else if (stream.name() == "EnableDragFilesToTimeline") { - stream.readNext(); - enable_drag_files_to_timeline = (stream.text() == "1");; - } else if (stream.name() == "AutoscaleByDefault") { - stream.readNext(); - autoscale_by_default = (stream.text() == "1"); - } else if (stream.name() == "RecordingMode") { - stream.readNext(); - recording_mode = stream.text().toInt(); - } else if (stream.name() == "EnableSeekToImport") { - stream.readNext(); - enable_seek_to_import = (stream.text() == "1"); - } else if (stream.name() == "AudioScrubbing") { - stream.readNext(); - enable_audio_scrubbing = (stream.text() == "1"); - } else if (stream.name() == "DropFileOnMediaToReplace") { - stream.readNext(); - drop_on_media_to_replace = (stream.text() == "1"); - } else if (stream.name() == "Autoscroll") { - stream.readNext(); - autoscroll = stream.text().toInt(); - } else if (stream.name() == "AudioRate") { - stream.readNext(); - audio_rate = stream.text().toInt(); - } else if (stream.name() == "FastSeeking") { - stream.readNext(); - fast_seeking = (stream.text() == "1"); - } else if (stream.name() == "HoverFocus") { - stream.readNext(); - hover_focus = (stream.text() == "1"); - } else if (stream.name() == "ProjectViewType") { - stream.readNext(); - project_view_type = stream.text().toInt(); - } else if (stream.name() == "SetNameWithMarker") { - stream.readNext(); - set_name_with_marker = (stream.text() == "1"); - } else if (stream.name() == "ShowProjectToolbar") { - stream.readNext(); - show_project_toolbar = (stream.text() == "1"); - } else if (stream.name() == "PreviousFrameQueueSize") { - stream.readNext(); - previous_queue_size = stream.text().toDouble(); - } else if (stream.name() == "PreviousFrameQueueType") { - stream.readNext(); - previous_queue_type = stream.text().toInt(); - } else if (stream.name() == "UpcomingFrameQueueSize") { - stream.readNext(); - upcoming_queue_size = stream.text().toDouble(); - } else if (stream.name() == "UpcomingFrameQueueType") { - stream.readNext(); - upcoming_queue_type = stream.text().toInt(); - } else if (stream.name() == "Loop") { - stream.readNext(); - loop = (stream.text() == "1"); - } else if (stream.name() == "SeekAlsoSelects") { - stream.readNext(); - seek_also_selects = (stream.text() == "1"); - } else if (stream.name() == "CSSPath") { - stream.readNext(); - css_path = stream.text().toString(); - } else if (stream.name() == "EffectTextboxLines") { - stream.readNext(); - effect_textbox_lines = stream.text().toInt(); - } else if (stream.name() == "UseSoftwareFallback") { - stream.readNext(); - use_software_fallback = (stream.text() == "1"); - } else if (stream.name() == "CenterTimelineTimecodes") { - stream.readNext(); - center_timeline_timecodes = (stream.text() == "1"); - } else if (stream.name() == "PreferredAudioOutput") { - stream.readNext(); - preferred_audio_output = stream.text().toString(); - } else if (stream.name() == "PreferredAudioInput") { - stream.readNext(); - preferred_audio_input = stream.text().toString(); - } else if (stream.name() == "LanguageFile") { - stream.readNext(); - language_file = stream.text().toString(); - } else if (stream.name() == "ThumbnailResolution") { - stream.readNext(); - thumbnail_resolution = stream.text().toInt(); - } else if (stream.name() == "WaveformResolution") { - stream.readNext(); - waveform_resolution = stream.text().toInt(); - } else if (stream.name() == "AddDefaultEffectsToClips") { - stream.readNext(); - add_default_effects_to_clips = (stream.text() == "1"); - } - } - } - if (stream.hasError()) { - qCritical() << "Error parsing config XML." << stream.errorString(); - } + while (!stream.atEnd()) { + stream.readNext(); + if (stream.isStartElement()) { + if (stream.name() == "SavedLayout") { + stream.readNext(); + saved_layout = (stream.text() == "1"); + } else if (stream.name() == "ShowTrackLines") { + stream.readNext(); + show_track_lines = (stream.text() == "1"); + } else if (stream.name() == "ScrollZooms") { + stream.readNext(); + scroll_zooms = (stream.text() == "1"); + } else if (stream.name() == "EditToolSelectsLinks") { + stream.readNext(); + edit_tool_selects_links = (stream.text() == "1"); + } else if (stream.name() == "EditToolAlsoSeeks") { + stream.readNext(); + edit_tool_also_seeks = (stream.text() == "1"); + } else if (stream.name() == "SelectAlsoSeeks") { + stream.readNext(); + select_also_seeks = (stream.text() == "1"); + } else if (stream.name() == "PasteSeeks") { + stream.readNext(); + paste_seeks = (stream.text() == "1"); + } else if (stream.name() == "ImageSequenceFormats") { + stream.readNext(); + img_seq_formats = stream.text().toString(); + } else if (stream.name() == "RectifiedWaveforms") { + stream.readNext(); + rectified_waveforms = (stream.text() == "1"); + } else if (stream.name() == "DefaultTransitionLength") { + stream.readNext(); + default_transition_length = stream.text().toInt(); + } else if (stream.name() == "TimecodeView") { + stream.readNext(); + timecode_view = stream.text().toInt(); + } else if (stream.name() == "ShowTitleSafeArea") { + stream.readNext(); + show_title_safe_area = (stream.text() == "1"); + } else if (stream.name() == "UseCustomTitleSafeRatio") { + stream.readNext(); + use_custom_title_safe_ratio = (stream.text() == "1"); + } else if (stream.name() == "CustomTitleSafeRatio") { + stream.readNext(); + custom_title_safe_ratio = stream.text().toDouble(); + } else if (stream.name() == "EnableDragFilesToTimeline") { + stream.readNext(); + enable_drag_files_to_timeline = (stream.text() == "1");; + } else if (stream.name() == "AutoscaleByDefault") { + stream.readNext(); + autoscale_by_default = (stream.text() == "1"); + } else if (stream.name() == "RecordingMode") { + stream.readNext(); + recording_mode = stream.text().toInt(); + } else if (stream.name() == "EnableSeekToImport") { + stream.readNext(); + enable_seek_to_import = (stream.text() == "1"); + } else if (stream.name() == "AudioScrubbing") { + stream.readNext(); + enable_audio_scrubbing = (stream.text() == "1"); + } else if (stream.name() == "DropFileOnMediaToReplace") { + stream.readNext(); + drop_on_media_to_replace = (stream.text() == "1"); + } else if (stream.name() == "Autoscroll") { + stream.readNext(); + autoscroll = stream.text().toInt(); + } else if (stream.name() == "AudioRate") { + stream.readNext(); + audio_rate = stream.text().toInt(); + } else if (stream.name() == "FastSeeking") { + stream.readNext(); + fast_seeking = (stream.text() == "1"); + } else if (stream.name() == "HoverFocus") { + stream.readNext(); + hover_focus = (stream.text() == "1"); + } else if (stream.name() == "ProjectViewType") { + stream.readNext(); + project_view_type = stream.text().toInt(); + } else if (stream.name() == "SetNameWithMarker") { + stream.readNext(); + set_name_with_marker = (stream.text() == "1"); + } else if (stream.name() == "ShowProjectToolbar") { + stream.readNext(); + show_project_toolbar = (stream.text() == "1"); + } else if (stream.name() == "PreviousFrameQueueSize") { + stream.readNext(); + previous_queue_size = stream.text().toDouble(); + } else if (stream.name() == "PreviousFrameQueueType") { + stream.readNext(); + previous_queue_type = stream.text().toInt(); + } else if (stream.name() == "UpcomingFrameQueueSize") { + stream.readNext(); + upcoming_queue_size = stream.text().toDouble(); + } else if (stream.name() == "UpcomingFrameQueueType") { + stream.readNext(); + upcoming_queue_type = stream.text().toInt(); + } else if (stream.name() == "Loop") { + stream.readNext(); + loop = (stream.text() == "1"); + } else if (stream.name() == "SeekAlsoSelects") { + stream.readNext(); + seek_also_selects = (stream.text() == "1"); + } else if (stream.name() == "CSSPath") { + stream.readNext(); + css_path = stream.text().toString(); + } else if (stream.name() == "EffectTextboxLines") { + stream.readNext(); + effect_textbox_lines = stream.text().toInt(); + } else if (stream.name() == "UseSoftwareFallback") { + stream.readNext(); + use_software_fallback = (stream.text() == "1"); + } else if (stream.name() == "CenterTimelineTimecodes") { + stream.readNext(); + center_timeline_timecodes = (stream.text() == "1"); + } else if (stream.name() == "PreferredAudioOutput") { + stream.readNext(); + preferred_audio_output = stream.text().toString(); + } else if (stream.name() == "PreferredAudioInput") { + stream.readNext(); + preferred_audio_input = stream.text().toString(); + } else if (stream.name() == "LanguageFile") { + stream.readNext(); + language_file = stream.text().toString(); + } else if (stream.name() == "ThumbnailResolution") { + stream.readNext(); + thumbnail_resolution = stream.text().toInt(); + } else if (stream.name() == "WaveformResolution") { + stream.readNext(); + waveform_resolution = stream.text().toInt(); + } else if (stream.name() == "AddDefaultEffectsToClips") { + stream.readNext(); + add_default_effects_to_clips = (stream.text() == "1"); + } + } + } + if (stream.hasError()) { + qCritical() << "Error parsing config XML." << stream.errorString(); + } - f.close(); - } + f.close(); + } } void Config::save(QString path) { - QFile f(path); - if (!f.open(QIODevice::WriteOnly)) { - qCritical() << "Could not save configuration"; - return; - } + QFile f(path); + if (!f.open(QIODevice::WriteOnly)) { + qCritical() << "Could not save configuration"; + return; + } - QXmlStreamWriter stream(&f); - stream.setAutoFormatting(true); - stream.writeStartDocument(); // doc - stream.writeStartElement("Configuration"); // configuration + QXmlStreamWriter stream(&f); + stream.setAutoFormatting(true); + stream.writeStartDocument(); // doc + stream.writeStartElement("Configuration"); // configuration - stream.writeTextElement("Version", QString::number(SAVE_VERSION)); - stream.writeTextElement("SavedLayout", QString::number(saved_layout)); - stream.writeTextElement("ShowTrackLines", QString::number(show_track_lines)); - stream.writeTextElement("ScrollZooms", QString::number(scroll_zooms)); - stream.writeTextElement("EditToolSelectsLinks", QString::number(edit_tool_selects_links)); - stream.writeTextElement("EditToolAlsoSeeks", QString::number(edit_tool_also_seeks)); - stream.writeTextElement("SelectAlsoSeeks", QString::number(select_also_seeks)); - stream.writeTextElement("PasteSeeks", QString::number(paste_seeks)); - stream.writeTextElement("ImageSequenceFormats", img_seq_formats); - stream.writeTextElement("RectifiedWaveforms", QString::number(rectified_waveforms)); - stream.writeTextElement("DefaultTransitionLength", QString::number(default_transition_length)); - stream.writeTextElement("TimecodeView", QString::number(timecode_view)); - stream.writeTextElement("ShowTitleSafeArea", QString::number(show_title_safe_area)); - stream.writeTextElement("UseCustomTitleSafeRatio", QString::number(use_custom_title_safe_ratio)); - stream.writeTextElement("CustomTitleSafeRatio", QString::number(custom_title_safe_ratio)); - stream.writeTextElement("EnableDragFilesToTimeline", QString::number(enable_drag_files_to_timeline)); - stream.writeTextElement("AutoscaleByDefault", QString::number(autoscale_by_default)); - stream.writeTextElement("RecordingMode", QString::number(recording_mode)); - stream.writeTextElement("EnableSeekToImport", QString::number(enable_seek_to_import)); - stream.writeTextElement("AudioScrubbing", QString::number(enable_audio_scrubbing)); - stream.writeTextElement("DropFileOnMediaToReplace", QString::number(drop_on_media_to_replace)); - stream.writeTextElement("Autoscroll", QString::number(autoscroll)); - stream.writeTextElement("AudioRate", QString::number(audio_rate)); - stream.writeTextElement("FastSeeking", QString::number(fast_seeking)); - stream.writeTextElement("HoverFocus", QString::number(hover_focus)); - stream.writeTextElement("ProjectViewType", QString::number(project_view_type)); - stream.writeTextElement("SetNameWithMarker", QString::number(set_name_with_marker)); - stream.writeTextElement("ShowProjectToolbar", QString::number(panel_project->toolbar_widget->isVisible())); - stream.writeTextElement("PreviousFrameQueueSize", QString::number(previous_queue_size)); - stream.writeTextElement("PreviousFrameQueueType", QString::number(previous_queue_type)); - stream.writeTextElement("UpcomingFrameQueueSize", QString::number(upcoming_queue_size)); - stream.writeTextElement("UpcomingFrameQueueType", QString::number(upcoming_queue_type)); - stream.writeTextElement("Loop", QString::number(loop)); - stream.writeTextElement("SeekAlsoSelects", QString::number(seek_also_selects)); - stream.writeTextElement("CSSPath", css_path); - stream.writeTextElement("EffectTextboxLines", QString::number(effect_textbox_lines)); - stream.writeTextElement("UseSoftwareFallback", QString::number(use_software_fallback)); - stream.writeTextElement("CenterTimelineTimecodes", QString::number(center_timeline_timecodes)); - stream.writeTextElement("PreferredAudioOutput", preferred_audio_output); - stream.writeTextElement("PreferredAudioInput", preferred_audio_input); - stream.writeTextElement("LanguageFile", language_file); - stream.writeTextElement("ThumbnailResolution", QString::number(thumbnail_resolution)); - stream.writeTextElement("WaveformResolution", QString::number(waveform_resolution)); - stream.writeTextElement("AddDefaultEffectsToClips", QString::number(add_default_effects_to_clips)); + stream.writeTextElement("Version", QString::number(SAVE_VERSION)); + stream.writeTextElement("SavedLayout", QString::number(saved_layout)); + stream.writeTextElement("ShowTrackLines", QString::number(show_track_lines)); + stream.writeTextElement("ScrollZooms", QString::number(scroll_zooms)); + stream.writeTextElement("EditToolSelectsLinks", QString::number(edit_tool_selects_links)); + stream.writeTextElement("EditToolAlsoSeeks", QString::number(edit_tool_also_seeks)); + stream.writeTextElement("SelectAlsoSeeks", QString::number(select_also_seeks)); + stream.writeTextElement("PasteSeeks", QString::number(paste_seeks)); + stream.writeTextElement("ImageSequenceFormats", img_seq_formats); + stream.writeTextElement("RectifiedWaveforms", QString::number(rectified_waveforms)); + stream.writeTextElement("DefaultTransitionLength", QString::number(default_transition_length)); + stream.writeTextElement("TimecodeView", QString::number(timecode_view)); + stream.writeTextElement("ShowTitleSafeArea", QString::number(show_title_safe_area)); + stream.writeTextElement("UseCustomTitleSafeRatio", QString::number(use_custom_title_safe_ratio)); + stream.writeTextElement("CustomTitleSafeRatio", QString::number(custom_title_safe_ratio)); + stream.writeTextElement("EnableDragFilesToTimeline", QString::number(enable_drag_files_to_timeline)); + stream.writeTextElement("AutoscaleByDefault", QString::number(autoscale_by_default)); + stream.writeTextElement("RecordingMode", QString::number(recording_mode)); + stream.writeTextElement("EnableSeekToImport", QString::number(enable_seek_to_import)); + stream.writeTextElement("AudioScrubbing", QString::number(enable_audio_scrubbing)); + stream.writeTextElement("DropFileOnMediaToReplace", QString::number(drop_on_media_to_replace)); + stream.writeTextElement("Autoscroll", QString::number(autoscroll)); + stream.writeTextElement("AudioRate", QString::number(audio_rate)); + stream.writeTextElement("FastSeeking", QString::number(fast_seeking)); + stream.writeTextElement("HoverFocus", QString::number(hover_focus)); + stream.writeTextElement("ProjectViewType", QString::number(project_view_type)); + stream.writeTextElement("SetNameWithMarker", QString::number(set_name_with_marker)); + stream.writeTextElement("ShowProjectToolbar", QString::number(panel_project->toolbar_widget->isVisible())); + stream.writeTextElement("PreviousFrameQueueSize", QString::number(previous_queue_size)); + stream.writeTextElement("PreviousFrameQueueType", QString::number(previous_queue_type)); + stream.writeTextElement("UpcomingFrameQueueSize", QString::number(upcoming_queue_size)); + stream.writeTextElement("UpcomingFrameQueueType", QString::number(upcoming_queue_type)); + stream.writeTextElement("Loop", QString::number(loop)); + stream.writeTextElement("SeekAlsoSelects", QString::number(seek_also_selects)); + stream.writeTextElement("CSSPath", css_path); + stream.writeTextElement("EffectTextboxLines", QString::number(effect_textbox_lines)); + stream.writeTextElement("UseSoftwareFallback", QString::number(use_software_fallback)); + stream.writeTextElement("CenterTimelineTimecodes", QString::number(center_timeline_timecodes)); + stream.writeTextElement("PreferredAudioOutput", preferred_audio_output); + stream.writeTextElement("PreferredAudioInput", preferred_audio_input); + stream.writeTextElement("LanguageFile", language_file); + stream.writeTextElement("ThumbnailResolution", QString::number(thumbnail_resolution)); + stream.writeTextElement("WaveformResolution", QString::number(waveform_resolution)); + stream.writeTextElement("AddDefaultEffectsToClips", QString::number(add_default_effects_to_clips)); - stream.writeEndElement(); // configuration - stream.writeEndDocument(); // doc - f.close(); + stream.writeEndElement(); // configuration + stream.writeEndDocument(); // doc + f.close(); } RuntimeConfig::RuntimeConfig() : - shaders_are_enabled(true), - disable_blending(false) + shaders_are_enabled(true), + disable_blending(false) {} diff --git a/io/config.h b/io/config.h index 23a6a86b9..8b907779a 100644 --- a/io/config.h +++ b/io/config.h @@ -45,67 +45,67 @@ #define FRAME_QUEUE_TYPE_SECONDS 1 struct Config { - Config(); + Config(); - bool saved_layout; - bool show_track_lines; - bool scroll_zooms; - bool edit_tool_selects_links; - bool edit_tool_also_seeks; - bool select_also_seeks; - bool paste_seeks; - QString img_seq_formats; - bool rectified_waveforms; - int default_transition_length; - int timecode_view; - bool show_title_safe_area; - bool use_custom_title_safe_ratio; - double custom_title_safe_ratio; - bool enable_drag_files_to_timeline; - bool autoscale_by_default; - int recording_mode; - bool enable_seek_to_import; - bool enable_audio_scrubbing; - bool drop_on_media_to_replace; - int autoscroll; - int audio_rate; - bool fast_seeking; - bool hover_focus; - int project_view_type; - bool set_name_with_marker; - bool show_project_toolbar; - double previous_queue_size; - int previous_queue_type; - double upcoming_queue_size; - int upcoming_queue_type; - bool loop; - bool seek_also_selects; - QString css_path; - int effect_textbox_lines; - bool use_software_fallback; - bool center_timeline_timecodes; - QString preferred_audio_output; - QString preferred_audio_input; - QString language_file; - int waveform_resolution; - int thumbnail_resolution; - bool add_default_effects_to_clips; + bool saved_layout; + bool show_track_lines; + bool scroll_zooms; + bool edit_tool_selects_links; + bool edit_tool_also_seeks; + bool select_also_seeks; + bool paste_seeks; + QString img_seq_formats; + bool rectified_waveforms; + int default_transition_length; + int timecode_view; + bool show_title_safe_area; + bool use_custom_title_safe_ratio; + double custom_title_safe_ratio; + bool enable_drag_files_to_timeline; + bool autoscale_by_default; + int recording_mode; + bool enable_seek_to_import; + bool enable_audio_scrubbing; + bool drop_on_media_to_replace; + int autoscroll; + int audio_rate; + bool fast_seeking; + bool hover_focus; + int project_view_type; + bool set_name_with_marker; + bool show_project_toolbar; + double previous_queue_size; + int previous_queue_type; + double upcoming_queue_size; + int upcoming_queue_type; + bool loop; + bool seek_also_selects; + QString css_path; + int effect_textbox_lines; + bool use_software_fallback; + bool center_timeline_timecodes; + QString preferred_audio_output; + QString preferred_audio_input; + QString language_file; + int waveform_resolution; + int thumbnail_resolution; + bool add_default_effects_to_clips; - void load(QString path); - void save(QString path); + void load(QString path); + void save(QString path); }; struct RuntimeConfig { - RuntimeConfig(); + RuntimeConfig(); - bool shaders_are_enabled; - bool disable_blending; - QString external_translation_file; + bool shaders_are_enabled; + bool disable_blending; + QString external_translation_file; }; namespace olive { - extern Config CurrentConfig; - extern RuntimeConfig CurrentRuntimeConfig; +extern Config CurrentConfig; +extern RuntimeConfig CurrentRuntimeConfig; } #endif // CONFIG_H diff --git a/mainwindow.cpp b/mainwindow.cpp index 169b9d087..1ee7b1b72 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -426,8 +426,8 @@ void MainWindow::setup_menus() { view_menu->addAction(tr("Zoom In"), &olive::FocusFilter, SLOT(zoom_in()), QKeySequence("="))->setProperty("id", "zoomin"); view_menu->addAction(tr("Zoom Out"), &olive::FocusFilter, SLOT(zoom_out()), QKeySequence("-"))->setProperty("id", "zoomout"); - view_menu->addAction(tr("Increase Track Height"), panel_timeline, SLOT(increase_track_height()), QKeySequence("Ctrl+="))->setProperty("id", "vzoomin"); - view_menu->addAction(tr("Decrease Track Height"), panel_timeline, SLOT(decrease_track_height()), QKeySequence("Ctrl+-"))->setProperty("id", "vzoomout"); + view_menu->addAction(tr("Increase Track Height"), panel_timeline, SLOT(IncreaseTrackHeight()), QKeySequence("Ctrl+="))->setProperty("id", "vzoomin"); + view_menu->addAction(tr("Decrease Track Height"), panel_timeline, SLOT(DecreaseTrackHeight()), QKeySequence("Ctrl+-"))->setProperty("id", "vzoomout"); show_all = view_menu->addAction(tr("Toggle Show All"), panel_timeline, SLOT(toggle_show_all()), QKeySequence("\\")); show_all->setProperty("id", "showall"); diff --git a/panels/grapheditor.cpp b/panels/grapheditor.cpp index bf8e0148d..f8f4d53e1 100644 --- a/panels/grapheditor.cpp +++ b/panels/grapheditor.cpp @@ -38,8 +38,6 @@ #include "debug.h" GraphEditor::GraphEditor(QWidget* parent) : Panel(parent), row(nullptr) { - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - resize(720, 480); QWidget* main_widget = new QWidget(this); diff --git a/panels/project.cpp b/panels/project.cpp index 58d1b6324..df4dc0d3c 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -72,8 +72,6 @@ QStringList recent_projects; Project::Project(QWidget *parent) : Panel(parent) { - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - QWidget* dockWidgetContents = new QWidget(this); QVBoxLayout* verticalLayout = new QVBoxLayout(dockWidgetContents); diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 4f3ae7e72..6488f94b3 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -71,7 +71,7 @@ Timeline::Timeline(QWidget *parent) : moving_proc(false), move_insert(false), trim_target(-1), - trim_in_point(false), + trim_type(TRIM_NONE), splitting(false), importing(false), importing_files(false), @@ -84,12 +84,8 @@ Timeline::Timeline(QWidget *parent) : block_repaints(false), scroll(0) { - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - setup_ui(); - default_track_height = qRound((QGuiApplication::primaryScreen()->logicalDotsPerInch() / 96) * TRACK_DEFAULT_HEIGHT); - headers->viewer = panel_sequence_viewer; video_area->bottom_align = true; @@ -233,7 +229,7 @@ void Timeline::create_ghosts_from_media(SequencePtr seq, long entry_point, QVect if (can_import) { Ghost g; g.clip = -1; - g.trimming = false; + g.trim_type = TRIM_NONE; g.old_clip_in = g.clip_in = default_clip_in; g.media = medium; g.in = entry_point; @@ -374,14 +370,6 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, SequencePtr s) { snapped = false; } -int Timeline::get_track_height_size(bool video) { - if (video) { - return video_track_heights.size(); - } else { - return audio_track_heights.size(); - } -} - void Timeline::add_transition() { ComboAction* ca = new ComboAction(); bool adding = false; @@ -472,18 +460,6 @@ void Timeline::nest() { } } -int Timeline::calculate_track_height(int track, int value) { - int index = (track < 0) ? qAbs(track + 1) : track; - QVector& vector = (track < 0) ? video_track_heights : audio_track_heights; - while (vector.size() < index+1) { - vector.append(default_track_height); - } - if (value > -1) { - vector[index] = value; - } - return vector.at(index); -} - void Timeline::update_sequence() { bool null_sequence = (olive::ActiveSequence == nullptr); @@ -793,15 +769,6 @@ void Timeline::decheck_tool_buttons(QObject* sender) { } } -QVector Timeline::get_tracks_of_linked_clips(int i) { - QVector tracks; - ClipPtr clip = olive::ActiveSequence->clips.at(i); - for (int j=0;jlinked.size();j++) { - tracks.append(olive::ActiveSequence->clips.at(clip->linked.at(j))->track); - } - return tracks; -} - void Timeline::zoom_in() { multiply_zoom(2.0); } @@ -810,6 +777,45 @@ void Timeline::zoom_out() { multiply_zoom(0.5); } +int Timeline::GetTrackHeight(int track) { + for (int i=0;isequence->selections.size();i++) { const Selection& s = clip->sequence->selections.at(i); @@ -886,18 +892,9 @@ ClipPtr Timeline::split_clip(ComboAction* ca, bool transitions, int p, long fram return nullptr; } -bool Timeline::has_clip_been_split(int c) { - for (int i=0;ilinked.size();i++) { int l = c->linked.at(i); - if (!has_clip_been_split(l)) { + if (!split_cache.contains(l)) { ClipPtr link = olive::ActiveSequence->clips.at(l); if ((original_clip_is_selected && is_clip_selected(link, true)) || !original_clip_is_selected) { split_cache.append(l); @@ -1675,32 +1672,6 @@ void Timeline::toggle_links() { } } -void Timeline::increase_track_height() { - for (int i=0;iselections.clear(); repaint_timeline(); diff --git a/panels/timeline.h b/panels/timeline.h index ac7d2033c..9376d089b 100644 --- a/panels/timeline.h +++ b/panels/timeline.h @@ -35,14 +35,20 @@ #include "ui/audiomonitor.h" #include "ui/panel.h" -#define TRACK_DEFAULT_HEIGHT 40 +enum CreateObjects { + ADD_OBJ_TITLE, + ADD_OBJ_SOLID, + ADD_OBJ_BARS, + ADD_OBJ_TONE, + ADD_OBJ_NOISE, + ADD_OBJ_AUDIO +}; -#define ADD_OBJ_TITLE 0 -#define ADD_OBJ_SOLID 1 -#define ADD_OBJ_BARS 2 -#define ADD_OBJ_TONE 3 -#define ADD_OBJ_NOISE 4 -#define ADD_OBJ_AUDIO 5 +enum TrimType { + TRIM_NONE, + TRIM_IN, + TRIM_OUT +}; bool is_clip_selected(ClipPtr clip, bool containing); int getScreenPointFromFrame(double zoom, long frame); @@ -70,8 +76,7 @@ struct Ghost { // other variables long ghost_length; long media_length; - bool trim_in; - bool trimming; + TrimType trim_type; // transition trimming TransitionPtr transition; @@ -82,7 +87,7 @@ class Timeline : public Panel Q_OBJECT public: explicit Timeline(QWidget *parent = nullptr); - ~Timeline(); + virtual ~Timeline() override; bool focused(); void multiply_zoom(double m); @@ -98,8 +103,6 @@ public: void relink_clips_using_ids(QVector& old_clips, QVector& new_clips); void update_sequence(); - QVector get_tracks_of_linked_clips(int i); - bool has_clip_been_split(int c); void edit_to_point_internal(bool in, bool ripple); void delete_in_out_internal(bool ripple); @@ -128,10 +131,8 @@ public: bool showing_all; double old_zoom; - QVector video_track_heights; - QVector audio_track_heights; - int get_track_height_size(bool video); - int calculate_track_height(int track, int height); + int GetTrackHeight(int track); + void SetTrackHeight(int track, int height); // snapping bool snapping; @@ -145,10 +146,7 @@ public: void select_all(); bool rect_select_init; bool rect_select_proc; - int rect_select_x; - int rect_select_y; - int rect_select_w; - int rect_select_h; + QRect rect_select_rect; // moving bool moving_init; @@ -160,7 +158,7 @@ public: // trimming int trim_target; - bool trim_in_point; + TrimType trim_type; int transition_select; // splitting @@ -211,8 +209,8 @@ public: bool can_ripple_empty_space(long frame, int track); - void resizeEvent(QResizeEvent *event); protected: + virtual void resizeEvent(QResizeEvent *event) override; virtual void Retranslate() override; public slots: void paste(bool insert = false); @@ -233,8 +231,8 @@ public slots: void edit_to_in_point(); void edit_to_out_point(); - void increase_track_height(); - void decrease_track_height(); + void IncreaseTrackHeight(); + void DecreaseTrackHeight(); void previous_cut(); void next_cut(); @@ -268,12 +266,12 @@ private: void setup_ui(); - int default_track_height; - // ripple delete empty space variables long rc_ripple_min; long rc_ripple_max; + QVector track_heights; + QWidget* timeline_area; TimelineWidget* video_area; TimelineWidget* audio_area; diff --git a/panels/viewer.cpp b/panels/viewer.cpp index 927277f6c..79d5321ef 100644 --- a/panels/viewer.cpp +++ b/panels/viewer.cpp @@ -66,8 +66,6 @@ Viewer::Viewer(QWidget *parent) : cue_recording_internal(false), playback_speed(0) { - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - setup_ui(); headers->viewer = this; diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index 3a2acec10..ee22bf168 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -1,4 +1,4 @@ -/*** +/*** Olive - Non-Linear Video Editor Copyright (C) 2019 Olive Team @@ -566,42 +566,53 @@ void TimelineWidget::mouseDoubleClickEvent(QMouseEvent *event) { } } -bool isLiveEditing() { +bool current_tool_shows_cursor() { return (panel_timeline->tool == TIMELINE_TOOL_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR || panel_timeline->creating); } void TimelineWidget::mousePressEvent(QMouseEvent *event) { if (olive::ActiveSequence != nullptr) { - int tool = panel_timeline->tool; + + int effective_tool = panel_timeline->tool; + + // some user actions will override which tool we'll be using if (event->button() == Qt::MiddleButton) { - tool = TIMELINE_TOOL_HAND; + effective_tool = TIMELINE_TOOL_HAND; panel_timeline->creating = false; } else if (event->button() == Qt::RightButton) { - tool = TIMELINE_TOOL_MENU; + effective_tool = TIMELINE_TOOL_MENU; panel_timeline->creating = false; } - QPoint pos = event->pos(); - if (isLiveEditing()) { - panel_timeline->drag_frame_start = panel_timeline->cursor_frame; - panel_timeline->drag_track_start = panel_timeline->cursor_track; - } else { - panel_timeline->drag_frame_start = panel_timeline->getTimelineFrameFromScreenPoint(pos.x()); - panel_timeline->drag_track_start = getTrackFromScreenPoint(pos.y()); - } + // ensure cursor_frame and cursor_track are up to date + mouseMoveEvent(event); - int clip_index = panel_timeline->trim_target; - if (clip_index == -1) clip_index = getClipIndexFromCoords(panel_timeline->drag_frame_start, panel_timeline->drag_track_start); + // store current cursor positions + panel_timeline->drag_x_start = event->pos().x(); + panel_timeline->drag_y_start = event->pos().y(); + + // store current frame/tracks as the values to start dragging from + panel_timeline->drag_frame_start = panel_timeline->cursor_frame; + panel_timeline->drag_track_start = panel_timeline->cursor_track; + + // get the clip the user is currently hovering over, priority to trim_target set from mouseMoveEvent + int hovered_clip = panel_timeline->trim_target == -1 ? + getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track) + : panel_timeline->trim_target; bool shift = (event->modifiers() & Qt::ShiftModifier); bool alt = (event->modifiers() & Qt::AltModifier); + // Normal behavior is to reset selections to zero when clicking, but if Shift is held, we add selections + // to the existing selections. `selection_offset` is the index to change selections from (and we don't touch + // any prior to that) if (shift) { panel_timeline->selection_offset = olive::ActiveSequence->selections.size(); } else { panel_timeline->selection_offset = 0; } + // if the user is creating an object if (panel_timeline->creating) { int comp = 0; switch (panel_timeline->creating_object) { @@ -617,21 +628,26 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { break; } + // if the track the user clicked is correct for the type of object we're adding + if ((panel_timeline->drag_track_start < 0) == (comp < 0)) { Ghost g; g.in = g.old_in = g.out = g.old_out = panel_timeline->drag_frame_start; g.track = g.old_track = panel_timeline->drag_track_start; g.transition = nullptr; g.clip = -1; - g.trimming = true; - g.trim_in = false; + g.trim_type = TRIM_OUT; panel_timeline->ghosts.append(g); panel_timeline->moving_init = true; panel_timeline->moving_proc = true; } } else { - switch (tool) { + + // pass through tools to determine what action we'll be starting + switch (effective_tool) { + + // many tools share pointer-esque behavior case TIMELINE_TOOL_POINTER: case TIMELINE_TOOL_RIPPLE: case TIMELINE_TOOL_SLIP: @@ -639,125 +655,181 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { case TIMELINE_TOOL_SLIDE: case TIMELINE_TOOL_MENU: { - if (track_resizing && tool != TIMELINE_TOOL_MENU) { - track_resize_mouse_cache = event->pos().y(); + if (track_resizing && effective_tool != TIMELINE_TOOL_MENU) { + + // if the cursor is currently hovering over a track, init track resizing panel_timeline->moving_init = true; + } else { - if (clip_index >= 0) { - ClipPtr clip = olive::ActiveSequence->clips.at(clip_index); - if (clip != nullptr) { - if (is_clip_selected(clip, true)) { - if (shift) { - panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track); - if (!alt) { - for (int i=0;ilinked.size();i++) { - ClipPtr link = olive::ActiveSequence->clips.at(clip->linked.at(i)); - panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track); - } - } - } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER && panel_timeline->transition_select != kTransitionNone) { - panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track); + // check if we're currently hovering over a clip or not + if (hovered_clip >= 0) { + ClipPtr clip = olive::ActiveSequence->clips.at(hovered_clip); + if (is_clip_selected(clip, true)) { + + if (shift) { + + // if the user clicks a selected clip while holding shift, deselect the clip + panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track); + + // if the user isn't holding alt, also deselect all of its links + if (!alt) { for (int i=0;ilinked.size();i++) { ClipPtr link = olive::ActiveSequence->clips.at(clip->linked.at(i)); panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track); } - - Selection s; - s.track = clip->track; - - if (panel_timeline->transition_select == kTransitionOpening && clip->get_opening_transition() != nullptr) { - s.in = clip->timeline_in; - if (clip->get_opening_transition()->secondary_clip != nullptr) s.in -= clip->get_opening_transition()->get_true_length(); - s.out = clip->timeline_in + clip->get_opening_transition()->get_true_length(); - } else if (panel_timeline->transition_select == kTransitionClosing && clip->get_closing_transition() != nullptr) { - s.in = clip->timeline_out - clip->get_closing_transition()->get_true_length(); - s.out = clip->timeline_out; - if (clip->get_closing_transition()->secondary_clip != nullptr) s.out += clip->get_closing_transition()->get_true_length(); - } - olive::ActiveSequence->selections.append(s); } - } else { - // if "shift" is not down - if (!shift) { - olive::ActiveSequence->selections.clear(); + + } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER && panel_timeline->transition_select != kTransitionNone) { + + + + panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track); + + for (int i=0;ilinked.size();i++) { + ClipPtr link = olive::ActiveSequence->clips.at(clip->linked.at(i)); + panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track); } Selection s; - - s.in = clip->timeline_in; - s.out = clip->timeline_out; - - if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { - if (panel_timeline->transition_select == kTransitionOpening) { - s.out = clip->timeline_in + clip->get_opening_transition()->get_true_length(); - if (clip->get_opening_transition()->secondary_clip != nullptr) s.in -= clip->get_opening_transition()->get_true_length(); - } - - if (panel_timeline->transition_select == kTransitionClosing) { - s.in = clip->timeline_out - clip->get_closing_transition()->get_true_length(); - if (clip->get_closing_transition()->secondary_clip != nullptr) s.out += clip->get_closing_transition()->get_true_length(); - } - } - s.track = clip->track; - olive::ActiveSequence->selections.append(s); - if (olive::CurrentConfig.select_also_seeks) { - panel_sequence_viewer->seek(clip->timeline_in); + if (panel_timeline->transition_select == kTransitionOpening && clip->get_opening_transition() != nullptr) { + s.in = clip->timeline_in; + if (clip->get_opening_transition()->secondary_clip != nullptr) s.in -= clip->get_opening_transition()->get_true_length(); + s.out = clip->timeline_in + clip->get_opening_transition()->get_true_length(); + } else if (panel_timeline->transition_select == kTransitionClosing && clip->get_closing_transition() != nullptr) { + s.in = clip->timeline_out - clip->get_closing_transition()->get_true_length(); + s.out = clip->timeline_out; + if (clip->get_closing_transition()->secondary_clip != nullptr) s.out += clip->get_closing_transition()->get_true_length(); } + olive::ActiveSequence->selections.append(s); + } + } else { - // if alt is not down, select links - if (!alt && panel_timeline->transition_select == kTransitionNone) { - for (int i=0;ilinked.size();i++) { - ClipPtr link = olive::ActiveSequence->clips.at(clip->linked.at(i)); - if (!is_clip_selected(link, true)) { - Selection ss; - ss.in = link->timeline_in; - ss.out = link->timeline_out; - ss.track = link->track; - olive::ActiveSequence->selections.append(ss); - } + // if the clip is not already selected + + // if shift is NOT down, we change clear all current selections + if (!shift) { + olive::ActiveSequence->selections.clear(); + } + + Selection s; + + s.in = clip->timeline_in; + s.out = clip->timeline_out; + s.track = clip->track; + + // if user is using the pointer tool, they may be trying to select a transition + // check if the use is hovering over a transition + if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { + if (panel_timeline->transition_select == kTransitionOpening) { + // move the selection to only select the transitoin + s.out = clip->timeline_in + clip->get_opening_transition()->get_true_length(); + + // if the transition is a "shared" transition, adjust the selection to select both sides + if (clip->get_opening_transition()->secondary_clip != nullptr) { + s.in -= clip->get_opening_transition()->get_true_length(); + } + } else if (panel_timeline->transition_select == kTransitionClosing) { + // move the selection to only select the transitoin + s.in = clip->timeline_out - clip->get_closing_transition()->get_true_length(); + + // if the transition is a "shared" transition, adjust the selection to select both sides + if (clip->get_closing_transition()->secondary_clip != nullptr) { + s.out += clip->get_closing_transition()->get_true_length(); } } } + + // add the selection to the array + olive::ActiveSequence->selections.append(s); + + // if the config is set to also seek with selections, do so now + if (olive::CurrentConfig.select_also_seeks) { + panel_sequence_viewer->seek(clip->timeline_in); + } + + // if alt is not down, select links (provided we're not selecting transitions) + if (!alt && panel_timeline->transition_select == kTransitionNone) { + + for (int i=0;ilinked.size();i++) { + + ClipPtr link = olive::ActiveSequence->clips.at(clip->linked.at(i)); + + // check if the clip is already selected + if (!is_clip_selected(link, true)) { + Selection ss; + ss.in = link->timeline_in; + ss.out = link->timeline_out; + ss.track = link->track; + olive::ActiveSequence->selections.append(ss); + } + + } + + } + } + + // authorize the starting of a move action if the mouse moves after this + if (effective_tool != TIMELINE_TOOL_MENU) { + panel_timeline->moving_init = true; } - if (tool != TIMELINE_TOOL_MENU) panel_timeline->moving_init = true; } else { - // if "shift" is not down + + // if the user did not click a clip at all, we start a rectangle selection + if (!shift) { olive::ActiveSequence->selections.clear(); } panel_timeline->rect_select_init = true; } + + // update everything update_ui(false); } } break; case TIMELINE_TOOL_HAND: + + // initiate moving with the hand tool panel_timeline->hand_moving = true; - panel_timeline->drag_x_start = pos.x(); - panel_timeline->drag_y_start = pos.y(); + break; case TIMELINE_TOOL_EDIT: - if (olive::CurrentConfig.edit_tool_also_seeks) panel_sequence_viewer->seek(panel_timeline->drag_frame_start); + + // if the config is set to seek with the edit tool, do so now + if (olive::CurrentConfig.edit_tool_also_seeks) { + panel_sequence_viewer->seek(panel_timeline->drag_frame_start); + } + + // initiate selecting panel_timeline->selecting = true; + break; case TIMELINE_TOOL_RAZOR: { + + // initiate razor tool panel_timeline->splitting = true; + + // add this track as a track being split by the razor panel_timeline->split_tracks.append(panel_timeline->drag_track_start); + update_ui(false); } break; case TIMELINE_TOOL_TRANSITION: { + + // if there is a clip to run the transition tool on, initiate the transition tool if (panel_timeline->transition_tool_pre_clip > -1) { panel_timeline->transition_tool_init = true; } + } break; } @@ -906,7 +978,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { // ripple_length becomes the length/number of frames we trimmed // ripple point becomes the point to ripple (i.e. the point after or before which we move every clip) - if (panel_timeline->trim_in_point) { + if (panel_timeline->trim_type == TRIM_IN) { ripple_length = first_ghost.old_in - first_ghost.in; ripple_point = first_ghost.old_in; @@ -924,16 +996,16 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { const Ghost& g = panel_timeline->ghosts.at(i); // push rippled clips forward if necessary - if (panel_timeline->trim_in_point) { + if (panel_timeline->trim_type == TRIM_IN) { ignore_clips.append(g.clip); panel_timeline->ghosts[i].in += ripple_length; panel_timeline->ghosts[i].out += ripple_length; } - long comp_point = panel_timeline->trim_in_point ? g.old_in : g.old_out; + long comp_point = (panel_timeline->trim_type == TRIM_IN) ? g.old_in : g.old_out; ripple_point = qMin(ripple_point, comp_point); } - if (!panel_timeline->trim_in_point) ripple_length = -ripple_length; + if (panel_timeline->trim_type == TRIM_OUT) ripple_length = -ripple_length; ripple_clips(ca, olive::ActiveSequence, ripple_point, ripple_length, ignore_clips); } @@ -1018,7 +1090,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { long new_clip_length = (g.out - g.in); if (c->get_opening_transition() != nullptr) { long max_open_length = new_clip_length; - if (c->get_closing_transition() != nullptr && !panel_timeline->trim_in_point) { + if (c->get_closing_transition() != nullptr && panel_timeline->trim_type == TRIM_OUT) { max_open_length -= c->get_closing_transition()->get_true_length(); } if (max_open_length <= 0) { @@ -1029,7 +1101,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { } if (c->get_closing_transition() != nullptr) { long max_open_length = new_clip_length; - if (c->get_opening_transition() != nullptr && panel_timeline->trim_in_point) { + if (c->get_opening_transition() != nullptr && panel_timeline->trim_type == TRIM_IN) { max_open_length -= c->get_opening_transition()->get_true_length(); } if (max_open_length <= 0) { @@ -1047,7 +1119,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { long clip_length = c->getLength(); if (g.transition->secondary_clip != nullptr) { - if (g.in != g.old_in && !g.trimming) { + if (g.in != g.old_in && g.trim_type == TRIM_NONE) { long movement = g.in - g.old_in; move_clip(ca, g.transition->parent_clip, movement, 0, movement, 0, false, true); move_clip(ca, g.transition->secondary_clip, 0, movement, 0, 0, false, true); @@ -1287,7 +1359,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { const Ghost& g = panel_timeline->ghosts.at(i); // snap ghost's in point - if (panel_timeline->trim_target == -1 || g.trim_in) { + if (panel_timeline->trim_target == -1 || g.trim_type == TRIM_IN) { fm = g.old_in + frame_diff; if (panel_timeline->snap_to_timeline(&fm, true, true, true)) { frame_diff = fm - g.old_in; @@ -1296,7 +1368,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { } // snap ghost's out point - if (panel_timeline->trim_target == -1 || !g.trim_in) { + if (panel_timeline->trim_target == -1 || g.trim_type == TRIM_OUT) { fm = g.old_out + frame_diff; if (panel_timeline->snap_to_timeline(&fm, true, true, true)) { frame_diff = fm - g.old_out; @@ -1347,8 +1419,8 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { validator += g.ghost_length; if (validator > g.media_length) frame_diff += validator - g.media_length; } - } else if (g.trimming) { - if (g.trim_in) { + } else if (g.trim_type != TRIM_NONE) { + if (g.trim_type == TRIM_IN) { // prevent clip/transition length from being less than 1 frame long validator = g.ghost_length - frame_diff; if (validator < 1) frame_diff -= (1 - validator); @@ -1383,7 +1455,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { ClipPtr otc = g.transition->parent_clip; ClipPtr ctc = g.transition->secondary_clip; - if (g.trim_in) { + if (g.trim_type == TRIM_IN) { frame_diff -= g.transition->get_true_length(); } else { frame_diff += g.transition->get_true_length(); @@ -1397,7 +1469,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { validate_transitions(ctc, kTransitionClosing, frame_diff); frame_diff = -frame_diff; - if (g.trim_in) { + if (g.trim_type == TRIM_IN) { frame_diff += g.transition->get_true_length(); } else { frame_diff -= g.transition->get_true_length(); @@ -1410,7 +1482,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { ClipPtr post = post_clips.at(j); // prevent any rippled clip from going below 0 - if (panel_timeline->trim_in_point) { + if (panel_timeline->trim_type == TRIM_IN) { validator = post->timeline_in - frame_diff; if (validator < 0) frame_diff += validator; } @@ -1419,7 +1491,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { for (int k=0;ktrack == post->track) { - if (panel_timeline->trim_in_point) { + if (panel_timeline->trim_type == TRIM_IN) { validator = post->timeline_in - frame_diff - pre->timeline_out; if (validator < 0) frame_diff += validator; } else { @@ -1511,7 +1583,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { if (effective_tool == TIMELINE_TOOL_SLIP) { g.clip_in = g.old_clip_in - frame_diff; - } else if (g.trimming) { + } else if (g.trim_type != TRIM_NONE) { long ghost_diff = frame_diff; // prevent trimming clips from overlapping each other @@ -1519,7 +1591,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { const Ghost& comp = panel_timeline->ghosts.at(j); if (i != j && g.track == comp.track) { long validator; - if (g.trim_in && comp.out < g.out) { + if (g.trim_type == TRIM_IN && comp.out < g.out) { validator = (g.old_in + ghost_diff) - comp.out; if (validator < 0) ghost_diff -= validator; } else if (comp.in > g.in) { @@ -1531,10 +1603,10 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { // apply changes if (g.transition != nullptr && g.transition->secondary_clip != nullptr) { - if (g.trim_in) ghost_diff = -ghost_diff; + if (g.trim_type == TRIM_IN) ghost_diff = -ghost_diff; g.in = g.old_in - ghost_diff; g.out = g.old_out + ghost_diff; - } else if (g.trim_in) { + } else if (g.trim_type == TRIM_IN) { g.in = g.old_in + ghost_diff; g.clip_in = g.old_clip_in + ghost_diff; } else { @@ -1581,7 +1653,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { for (int i=0;iselections.size();i++) { Selection& s = olive::ActiveSequence->selections[i]; if (panel_timeline->trim_target > -1) { - if (panel_timeline->trim_in_point) { + if (panel_timeline->trim_type == TRIM_IN) { s.in = s.old_in + frame_diff; } else { s.out = s.old_out + frame_diff; @@ -1625,7 +1697,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { if (g != nullptr) { tip += " " + tr("Duration:") + " "; long len = (g->old_out-g->old_in); - if (panel_timeline->trim_in_point) { + if (panel_timeline->trim_type == TRIM_IN) { len -= frame_diff; } else { len += frame_diff; @@ -1638,228 +1710,272 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { } void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { + // interrupt any potential tooltip about to show tooltip_timer.stop(); + if (olive::ActiveSequence != nullptr) { bool alt = (event->modifiers() & Qt::AltModifier); + // store current frame/track corresponding to the cursor panel_timeline->cursor_frame = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x()); panel_timeline->cursor_track = getTrackFromScreenPoint(event->pos().y()); - panel_timeline->move_insert = ((event->modifiers() & Qt::ControlModifier) && (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->importing || panel_timeline->creating)); + // determine if the action should be "inserting" rather than "overwriting" + // Default behavior is to replace/overwrite clips under any clips we're dropping over them. Inserting will + // split and move existing clips at the drop point to make space for the drop + panel_timeline->move_insert = ((event->modifiers() & Qt::ControlModifier) + && (panel_timeline->tool == TIMELINE_TOOL_POINTER + || panel_timeline->importing + || panel_timeline->creating)); - if (!panel_timeline->moving_init) track_resizing = false; - - if (isLiveEditing()) { - panel_timeline->snap_to_timeline(&panel_timeline->cursor_frame, !olive::CurrentConfig.edit_tool_also_seeks || !panel_timeline->selecting, true, true); + // if we're not currently resizing already, default track resizing to false (we'll set it to true later if + // the user is still hovering over a track line) + if (!panel_timeline->moving_init) { + track_resizing = false; } + + // if the current tool uses an on-screen visible cursor, we snap the cursor to the timeline + if (current_tool_shows_cursor()) { + panel_timeline->snap_to_timeline(&panel_timeline->cursor_frame, + + // only snap to the playhead if the edit tool doesn't force the playhead to + // follow it (or if we're not selecting since that means the playhead is + // static at the moment) + !olive::CurrentConfig.edit_tool_also_seeks || !panel_timeline->selecting, + + true, + true); + } + if (panel_timeline->selecting) { - int selection_count = 1 + qMax(panel_timeline->cursor_track, panel_timeline->drag_track_start) - qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start) + panel_timeline->selection_offset; + + // get number of selections based on tracks in selection area + int selection_tool_count = 1 + qMax(panel_timeline->cursor_track, panel_timeline->drag_track_start) - qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start); + + // add count to selection offset for the total number of selection objects + // (offset is usually 0, unless the user is holding shift in which case we add to existing selections) + int selection_count = selection_tool_count + panel_timeline->selection_offset; + + // resize selection object array to new count if (olive::ActiveSequence->selections.size() != selection_count) { olive::ActiveSequence->selections.resize(selection_count); } + + // loop through tracks in selection area and adjust them accordingly int minimum_selection_track = qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start); + int maximum_selection_track = qMax(panel_timeline->cursor_track, panel_timeline->drag_track_start); + long selection_in = qMin(panel_timeline->drag_frame_start, panel_timeline->cursor_frame); + long selection_out = qMax(panel_timeline->drag_frame_start, panel_timeline->cursor_frame); for (int i=panel_timeline->selection_offset;iselections[i]; s.track = minimum_selection_track + i - panel_timeline->selection_offset; - long in = panel_timeline->drag_frame_start; - long out = panel_timeline->cursor_frame; - s.in = qMin(in, out); - s.out = qMax(in, out); + s.in = selection_in; + s.out = selection_out; } - // select linked clips too + // If the config is set to select links as well with the edit tool if (olive::CurrentConfig.edit_tool_selects_links) { - for (int j=0;jclips.size();j++) { - ClipPtr c = olive::ActiveSequence->clips.at(j); - for (int k=0;kselections.size();k++) { - const Selection& s = olive::ActiveSequence->selections.at(k); - if (!(c->timeline_in < s.in && c->timeline_out < s.in) && - !(c->timeline_in > s.out && c->timeline_out > s.out) && - c->track == s.track) { - QVector linked_tracks = panel_timeline->get_tracks_of_linked_clips(j); - for (int k=0;kselections.size();l++) { - const Selection& test_sel = olive::ActiveSequence->selections.at(l); - if (test_sel.track == linked_tracks.at(k) && - test_sel.in == s.in && - test_sel.out == s.out) { - found = true; - break; - } - } - if (!found) { - Selection link_sel; - link_sel.in = s.in; - link_sel.out = s.out; - link_sel.track = linked_tracks.at(k); - olive::ActiveSequence->selections.append(link_sel); - } + // find which clips are selected + for (int j=0;jclips.size();j++) { + + ClipPtr c = olive::ActiveSequence->clips.at(j); + + if (c != nullptr && is_clip_selected(c, false)) { + + // loop through linked clips + for (int k=0;klinked.size();k++) { + + ClipPtr link = olive::ActiveSequence->clips.at(c->linked.at(k)); + + // see if one of the selections is already covering this track + if (!(link->track >= minimum_selection_track + && link->track <= maximum_selection_track)) { + + // clip is not in selectin area, time to select it + Selection link_sel; + link_sel.in = selection_in; + link_sel.out = selection_out; + link_sel.track = link->track; + olive::ActiveSequence->selections.append(link_sel); + } - break; } + } } } + // if the config is set to seek with the edit too, do so now if (olive::CurrentConfig.edit_tool_also_seeks) { panel_sequence_viewer->seek(qMin(panel_timeline->drag_frame_start, panel_timeline->cursor_frame)); } else { + // if not, repaint (seeking will trigger a repaint) panel_timeline->repaint_timeline(); } + } else if (panel_timeline->hand_moving) { + + // if we're hand moving, we'll be adding values directly to the scrollbars + + // the scrollbars trigger repaints when they scroll, which is unnecessary here so we block them panel_timeline->block_repaints = true; panel_timeline->horizontalScrollBar->setValue(panel_timeline->horizontalScrollBar->value() + panel_timeline->drag_x_start - event->pos().x()); scrollBar->setValue(scrollBar->value() + panel_timeline->drag_y_start - event->pos().y()); panel_timeline->block_repaints = false; + // finally repaint panel_timeline->repaint_timeline(); + // store current cursor position for next hand move event panel_timeline->drag_x_start = event->pos().x(); panel_timeline->drag_y_start = event->pos().y(); + } else if (panel_timeline->moving_init) { + if (track_resizing) { - int diff = track_resize_mouse_cache - event->pos().y(); - int new_height = track_resize_old_value; + + // get cursor movement + int diff = (event->pos().y() - panel_timeline->drag_y_start); + + // add it to the current track height + int new_height = panel_timeline->GetTrackHeight(track_target); if (bottom_align) { - new_height += diff; - } else { new_height -= diff; + } else { + new_height += diff; } + + // limit track height to track minimum height constant new_height = qMax(new_height, olive::timeline::kTrackMinHeight); - panel_timeline->calculate_track_height(track_target, new_height); + + // set the track height + panel_timeline->SetTrackHeight(track_target, new_height); + + // store current cursor position for next track resize event + panel_timeline->drag_y_start = event->pos().y(); + update(); } else if (panel_timeline->moving_proc) { + + // we're currently dragging ghosts update_ghosts(event->pos(), event->modifiers() & Qt::ShiftModifier); + } else { - // set up movement - // create ghosts + + // Prepare to start moving clips in some capacity. We create Ghost objects to store movement data before we + // actually apply it to the clips (in mouseReleaseEvent) + + // loop through clips for any currently selected for (int i=0;iclips.size();i++) { + ClipPtr c = olive::ActiveSequence->clips.at(i); + if (c != nullptr) { Ghost g; g.transition = nullptr; + // check if whole clip is added bool add = is_clip_selected(c, true); // if a whole clip is not selected, maybe just a transition is - if (panel_timeline->tool == TIMELINE_TOOL_POINTER && (c->get_opening_transition() != nullptr || c->get_closing_transition() != nullptr)) { - // check if any selections contain the whole clip or transition + // (only the pointer tool supports moving transitions) + if (!add + && panel_timeline->tool == TIMELINE_TOOL_POINTER + && (c->get_opening_transition() != nullptr || c->get_closing_transition() != nullptr)) { + + // check if any selections contain a whole transition for (int j=0;jselections.size();j++) { + const Selection& s = olive::ActiveSequence->selections.at(j); + if (s.track == c->track) { if (selection_contains_transition(s, c, kTransitionOpening)) { + g.transition = c->get_opening_transition(); add = true; break; + } else if (selection_contains_transition(s, c, kTransitionClosing)) { + g.transition = c->get_closing_transition(); add = true; break; + } } - } - } - if (add && g.transition != nullptr) { - // check for duplicate transitions - for (int j=0;jghosts.size();j++) { - if (panel_timeline->ghosts.at(j).transition == g.transition) { - add = false; - break; - } } + } if (add) { - g.clip = i; - g.trimming = (panel_timeline->trim_target > -1); - g.trim_in = panel_timeline->trim_in_point; - panel_timeline->ghosts.append(g); + + if (g.transition != nullptr) { + + // transition may be a dual transition, check if it's already been added elsewhere + for (int j=0;jghosts.size();j++) { + if (panel_timeline->ghosts.at(j).transition == g.transition) { + add = false; + break; + } + } + + } + + if (add) { + g.clip = i; + g.trim_type = panel_timeline->trim_type; + panel_timeline->ghosts.append(g); + } + } } } - int size = panel_timeline->ghosts.size(); - if (panel_timeline->tool == TIMELINE_TOOL_ROLLING) { - for (int i=0;iclips.at(panel_timeline->ghosts.at(i).clip); + if (panel_timeline->tool == TIMELINE_TOOL_SLIDE) { - // see if any ghosts are touching, in which case flip them - for (int k=0;kclips.at(panel_timeline->ghosts.at(k).clip); - if ((panel_timeline->trim_in_point && comp_clip->timeline_out == ghost_clip->timeline_in) || - (!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) { - panel_timeline->ghosts[k].trim_in = !panel_timeline->trim_in_point; - } - } - } + // for the slide tool, we add the surrounding clips as ghosts that are getting trimmed the opposite way - // then look for other clips we're touching - for (int i=0;ighosts.at(i); - ClipPtr ghost_clip = olive::ActiveSequence->clips.at(g.clip); - for (int j=0;jclips.size();j++) { - ClipPtr comp_clip = olive::ActiveSequence->clips.at(j); - if (comp_clip->track == ghost_clip->track) { - if ((panel_timeline->trim_in_point && comp_clip->timeline_out == ghost_clip->timeline_in) || - (!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) { - // see if this clip is already selected, and if so just switch the trim_in + // store original array size since we'll be adding to it + int ghost_arr_size = panel_timeline->ghosts.size(); + + // loop through clips for any that are "touching" the selected clips + for (int j=0;jclips.size();j++) { + + ClipPtr c = olive::ActiveSequence->clips.at(j); + if (c != nullptr) { + + for (int i=0;ighosts[i]; + g.trim_type = TRIM_NONE; // the selected clips will be moving, not trimming + + ClipPtr ghost_clip = olive::ActiveSequence->clips.at(g.clip); + + if (c->track == ghost_clip->track) { + + // see if this clip is currently selected, if so we won't add it as a "touching" clip bool found = false; - int duplicate_ghost_index; - for (duplicate_ghost_index=0;duplicate_ghost_indexghosts.at(duplicate_ghost_index).clip == j) { + for (int k=0;kghosts.at(k).clip == j) { found = true; break; } } - if (g.trim_in == panel_timeline->trim_in_point) { - if (!found) { - // add ghost for this clip with opposite trim_in + + if (!found) { // the clip is not currently selected + + // check if this clip is indeed touching + bool is_in = (c->timeline_in == ghost_clip->timeline_out); + if (is_in || c->timeline_out == ghost_clip->timeline_in) { Ghost gh; gh.transition = nullptr; gh.clip = j; - gh.trimming = (panel_timeline->trim_target > -1); - gh.trim_in = !panel_timeline->trim_in_point; + gh.trim_type = is_in ? TRIM_IN : TRIM_OUT; panel_timeline->ghosts.append(gh); } - } else { - if (found) { - panel_timeline->ghosts.removeAt(duplicate_ghost_index); - size--; - if (duplicate_ghost_index < i) i--; - } - } - } - } - } - } - } else if (panel_timeline->tool == TIMELINE_TOOL_SLIDE) { - for (int i=0;ighosts.at(i); - ClipPtr ghost_clip = olive::ActiveSequence->clips.at(g.clip); - panel_timeline->ghosts[i].trimming = false; - for (int j=0;jclips.size();j++) { - ClipPtr c = olive::ActiveSequence->clips.at(j); - if (c != nullptr && c->track == ghost_clip->track) { - bool found = false; - for (int k=0;kghosts.at(k).clip == j) { - found = true; - break; - } - } - if (!found) { - bool is_in = (c->timeline_in == ghost_clip->timeline_out); - if (is_in || c->timeline_out == ghost_clip->timeline_in) { - Ghost gh; - gh.transition = nullptr; - gh.clip = j; - gh.trimming = true; - gh.trim_in = is_in; - panel_timeline->ghosts.append(gh); } } } @@ -1867,40 +1983,61 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } } + // set up ghost defaults init_ghosts(); - // ripple edit prep + // if the ripple tool is selected, prepare to ripple if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) { + long axis = LONG_MAX; + // find the earliest point within the selected clips which is the point we'll ripple around + // also store the currently selected clips so we don't have to do it later + QVector ghost_clips; + ghost_clips.resize(panel_timeline->ghosts.size()); + for (int i=0;ighosts.size();i++) { ClipPtr c = olive::ActiveSequence->clips.at(panel_timeline->ghosts.at(i).clip); - if (panel_timeline->trim_in_point) { + if (panel_timeline->trim_type == TRIM_IN) { axis = qMin(axis, c->timeline_in); } else { axis = qMin(axis, c->timeline_out); } + + // store clip reference + ghost_clips[i] = c; } + // loop through clips and cache which are earlier than the axis and which after after for (int i=0;iclips.size();i++) { ClipPtr c = olive::ActiveSequence->clips.at(i); - if (c != nullptr && !is_clip_selected(c, true)) { + if (c != nullptr && !ghost_clips.contains(c)) { bool clip_is_post = (c->timeline_in >= axis); - // see if this a clip on this track is already in the list, and if it's closer + // construct the list of pre and post clips + QVector& clip_list = (clip_is_post) ? post_clips : pre_clips; + + // check if there's already a clip in this list on this track, and if this clip is closer or not bool found = false; - QVector& clip_list = clip_is_post ? post_clips : pre_clips; for (int j=0;jtrack == c->track) { + + // if the clip is closer, use this one instead of the current one in the list if ((!clip_is_post && compare->timeline_out < c->timeline_out) || (clip_is_post && compare->timeline_in > c->timeline_in)) { clip_list[j] = c; } + found = true; break; } + } + + // if there is no clip on this track in the list, add it if (!found) { clip_list.append(c); } @@ -1912,48 +2049,76 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { selection_command = new SetSelectionsCommand(olive::ActiveSequence); selection_command->old_data = olive::ActiveSequence->selections; + // ready to start moving clips panel_timeline->moving_proc = true; } + update_ui(false); + } else if (panel_timeline->splitting) { + + // get the range of tracks currently dragged int track_start = qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start); - int track_end = qMax(panel_timeline->cursor_track, panel_timeline->drag_track_start); + int track_end = qMax(panel_timeline->cursor_track, panel_timeline->drag_track_start); int track_size = 1 + track_end - track_start; + + // set tracks to be split panel_timeline->split_tracks.resize(track_size); for (int i=0;isplit_tracks[i] = track_start + i; } + // if alt isn't being held, also add the tracks of the clip's links if (!alt) { for (int i=0;idrag_frame_start, panel_timeline->split_tracks[i]); + if (clip_index > -1) { - QVector tracks = panel_timeline->get_tracks_of_linked_clips(clip_index); - for (int j=0;j track_end) { - panel_timeline->split_tracks.append(tracks.at(j)); + ClipPtr clip = olive::ActiveSequence->clips.at(clip_index); + for (int j=0;jlinked.size();j++) { + + ClipPtr link = olive::ActiveSequence->clips.at(clip->linked.at(j)); + + // if this clip isn't already in the list of tracks to split + if (link->track < track_start || link->track > track_end) { + panel_timeline->split_tracks.append(link->track); } + } } } } - update_ui(false); - } else if (panel_timeline->rect_select_init) { - if (panel_timeline->rect_select_proc) { - panel_timeline->rect_select_w = event->pos().x() - panel_timeline->rect_select_x; - panel_timeline->rect_select_h = event->pos().y() - panel_timeline->rect_select_y; - if (bottom_align) panel_timeline->rect_select_h -= height(); - long frame_start = panel_timeline->getTimelineFrameFromScreenPoint(panel_timeline->rect_select_x); - long frame_end = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x()); + update_ui(false); + + } else if (panel_timeline->rect_select_init) { + + // set if the user started dragging at point where there was no clip + + if (panel_timeline->rect_select_proc) { + + // we're currently rectangle selecting + + // set the right/bottom coords to the current mouse position + // (left/top were set to the starting drag position earlier) + panel_timeline->rect_select_rect.setRight(event->pos().x()); + + if (bottom_align) { + panel_timeline->rect_select_rect.setBottom(event->pos().y() - height()); + } else { + panel_timeline->rect_select_rect.setBottom(event->pos().y()); + } + + long frame_start = panel_timeline->drag_frame_start; + long frame_end = panel_timeline->cursor_frame; long frame_min = qMin(frame_start, frame_end); long frame_max = qMax(frame_start, frame_end); - int rsy = panel_timeline->rect_select_y; - if (bottom_align) rsy += height(); - int track_start = getTrackFromScreenPoint(rsy); - int track_end = getTrackFromScreenPoint(event->pos().y()); + int track_start = panel_timeline->drag_track_start; + int track_end = panel_timeline->cursor_track; + int track_min = qMin(track_start, track_end); int track_max = qMax(track_start, track_end); @@ -2002,14 +2167,20 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { panel_timeline->repaint_timeline(); } else { - panel_timeline->rect_select_x = event->pos().x(); - panel_timeline->rect_select_y = event->pos().y(); - if (bottom_align) panel_timeline->rect_select_y -= height(); - panel_timeline->rect_select_w = 0; - panel_timeline->rect_select_h = 0; + panel_timeline->rect_select_rect.setX(event->pos().x()); + + if (bottom_align) { + panel_timeline->rect_select_rect.setY(event->pos().y() - height()); + } else { + panel_timeline->rect_select_rect.setY(event->pos().y()); + } + + panel_timeline->rect_select_rect.setWidth(0); + panel_timeline->rect_select_rect.setHeight(0); + panel_timeline->rect_select_proc = true; } - } else if (isLiveEditing()) { + } else if (current_tool_shows_cursor()) { // redraw because we have a cursor panel_timeline->repaint_timeline(); } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER || @@ -2031,9 +2202,6 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { long mouse_frame_lower = panel_timeline->getTimelineFrameFromScreenPoint(pos.x()-lim)-1; long mouse_frame_upper = panel_timeline->getTimelineFrameFromScreenPoint(pos.x()+lim)+1; - // current track that the cursor is on - int mouse_track = getTrackFromScreenPoint(pos.y()); - // used to determine whether we the cursor found a trim point or not bool found = false; @@ -2051,6 +2219,9 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // we default to selecting no transition, but set this accordingly if the cursor is on a transition panel_timeline->transition_select = kTransitionNone; + // we also default to no trimming which may be changed later in this function + panel_timeline->trim_type = TRIM_NONE; + // set currently trimming clip to -1 (aka null) panel_timeline->trim_target = -1; @@ -2064,7 +2235,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { max_track = qMax(max_track, c->track); // if this clip is on the same track the mouse is - if (c->track == mouse_track) { + if (c->track == panel_timeline->cursor_track) { // if this cursor is inside the boundaries of this clip (hovering over the clip) if (panel_timeline->cursor_frame >= c->timeline_in && @@ -2102,7 +2273,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // if so, this is the point we'll make active for now (unless we find a closer one later) panel_timeline->trim_target = i; - panel_timeline->trim_in_point = true; + panel_timeline->trim_type = TRIM_IN; closeness = nc; found = true; @@ -2120,7 +2291,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // if so, this is the point we'll make active for now (unless we find a closer one later) panel_timeline->trim_target = i; - panel_timeline->trim_in_point = false; + panel_timeline->trim_type = TRIM_OUT; closeness = nc; found = true; @@ -2144,7 +2315,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { int nc = qAbs(transition_point - 1 - panel_timeline->cursor_frame); if (nc < closeness) { panel_timeline->trim_target = i; - panel_timeline->trim_in_point = false; + panel_timeline->trim_type = TRIM_OUT; panel_timeline->transition_select = kTransitionOpening; closeness = nc; found = true; @@ -2165,7 +2336,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { int nc = qAbs(transition_point + 1 - panel_timeline->cursor_frame); if (nc < closeness) { panel_timeline->trim_target = i; - panel_timeline->trim_in_point = true; + panel_timeline->trim_type = TRIM_IN; panel_timeline->transition_select = kTransitionClosing; closeness = nc; found = true; @@ -2180,7 +2351,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // if the cursor is indeed on a clip edge, we set the cursor accordingly if (found) { - if (panel_timeline->trim_in_point) { // if we're trimming an IN point + if (panel_timeline->trim_type == TRIM_IN) { // if we're trimming an IN point setCursor(olive::Cursor_LeftTrim); } else { // if we're trimming an OUT point setCursor(olive::Cursor_RightTrim); @@ -2190,33 +2361,28 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // we didn't find a trim target, so we must be doing something else // (e.g. dragging a clip or resizing the track heights) + unsetCursor(); + // check to see if we're resizing a track height - int track_y = 0; - for (int i=0;iget_track_height_size(bottom_align);i++) { - int track = (bottom_align) ? -1-i : i; - if (track >= min_track && track <= max_track) { - int track_height = panel_timeline->calculate_track_height(track, -1); - track_y += track_height; - int y_test_value = (bottom_align) ? rect().bottom() - track_y : track_y; - int test_range = 5; - int mouse_pos = pos.y() + scroll; - if (mouse_pos > y_test_value-test_range && mouse_pos < y_test_value+test_range) { - // if track lines are hidden, only resize track if a clip is already there - if (olive::CurrentConfig.show_track_lines || cursor_contains_clip) { - found = true; - track_resizing = true; - track_target = track; - track_resize_old_value = track_height; - } - break; - } - } + int test_range = 5; + int mouse_pos = event->pos().y() + scroll; + int hover_track = getTrackFromScreenPoint(mouse_pos); + int track_y_edge = getScreenPointFromTrack(hover_track); + + if (!bottom_align) { + track_y_edge += panel_timeline->GetTrackHeight(hover_track); } - if (found) { - setCursor(Qt::SizeVerCursor); - } else { - unsetCursor(); + if (mouse_pos > track_y_edge - test_range + && mouse_pos < track_y_edge + test_range) { + if (cursor_contains_clip + || (olive::CurrentConfig.show_track_lines + && panel_timeline->cursor_track >= min_track + && panel_timeline->cursor_track <= max_track)) { + track_resizing = true; + track_target = hover_track; + setCursor(Qt::SizeVerCursor); + } } } } else if (panel_timeline->tool == TIMELINE_TOOL_SLIP) { @@ -2238,7 +2404,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { g.track = c->track; g.clip = panel_timeline->transition_tool_pre_clip; g.media_stream = panel_timeline->transition_tool_type; - g.trimming = false; + g.trim_type = TRIM_NONE; panel_timeline->ghosts.append(g); @@ -2399,14 +2565,17 @@ void TimelineWidget::paintEvent(QPaintEvent*) { } } - int panel_height = TRACK_DEFAULT_HEIGHT; + // start by adding a track height worth of padding + int panel_height = olive::timeline::kTrackDefaultHeight; + + // loop through tracks for maximum panel height if (bottom_align) { for (int i=-1;i>=video_track_limit;i--) { - panel_height += panel_timeline->calculate_track_height(i, -1); + panel_height += panel_timeline->GetTrackHeight(i); } } else { for (int i=0;i<=audio_track_limit;i++) { - panel_height += panel_timeline->calculate_track_height(i, -1); + panel_height += panel_timeline->GetTrackHeight(i); } } if (bottom_align) { @@ -2418,7 +2587,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { for (int i=0;iclips.size();i++) { ClipPtr clip = olive::ActiveSequence->clips.at(i); if (clip != nullptr && is_track_visible(clip->track)) { - QRect clip_rect(panel_timeline->getTimelineScreenPointFromFrame(clip->timeline_in), getScreenPointFromTrack(clip->track), getScreenPointFromFrame(panel_timeline->zoom, clip->getLength()), panel_timeline->calculate_track_height(clip->track, -1)); + QRect clip_rect(panel_timeline->getTimelineScreenPointFromFrame(clip->timeline_in), getScreenPointFromTrack(clip->track), getScreenPointFromFrame(panel_timeline->zoom, clip->getLength()), panel_timeline->GetTrackHeight(clip->track)); QRect text_rect(clip_rect.left() + olive::timeline::kClipTextPadding, clip_rect.top() + olive::timeline::kClipTextPadding, clip_rect.width() - olive::timeline::kClipTextPadding - 1, clip_rect.height() - olive::timeline::kClipTextPadding - 1); if (clip_rect.left() < width() && clip_rect.right() >= 0 && clip_rect.top() < height() && clip_rect.bottom() >= 0) { QRect actual_clip_rect = clip_rect; @@ -2651,7 +2820,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { if (panel_sequence_viewer->is_recording_cued() && is_track_visible(panel_sequence_viewer->recording_track)) { int rec_track_x = panel_timeline->getTimelineScreenPointFromFrame(panel_sequence_viewer->recording_start); int rec_track_y = getScreenPointFromTrack(panel_sequence_viewer->recording_track); - int rec_track_height = panel_timeline->calculate_track_height(panel_sequence_viewer->recording_track, -1); + int rec_track_height = panel_timeline->GetTrackHeight(panel_sequence_viewer->recording_track); if (panel_sequence_viewer->recording_start != panel_sequence_viewer->recording_end) { QRect rec_rect( rec_track_x, @@ -2703,7 +2872,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { } else { // only draw lines for audio tracks for (int i=0;icalculate_track_height(i, -1); + int line_y = getScreenPointFromTrack(i) + panel_timeline->GetTrackHeight(i); p.drawLine(0, line_y, rect().width(), line_y); } } @@ -2717,18 +2886,18 @@ void TimelineWidget::paintEvent(QPaintEvent*) { int selection_x = panel_timeline->getTimelineScreenPointFromFrame(s.in); p.setPen(Qt::NoPen); p.setBrush(Qt::NoBrush); - p.fillRect(selection_x, selection_y, panel_timeline->getTimelineScreenPointFromFrame(s.out) - selection_x, panel_timeline->calculate_track_height(s.track, -1), QColor(0, 0, 0, 64)); + p.fillRect(selection_x, selection_y, panel_timeline->getTimelineScreenPointFromFrame(s.out) - selection_x, panel_timeline->GetTrackHeight(s.track), QColor(0, 0, 0, 64)); } } // draw rectangle select if (panel_timeline->rect_select_proc) { - int rsy = panel_timeline->rect_select_y; - int rsh = panel_timeline->rect_select_h; + QRect rect_select = panel_timeline->rect_select_rect; + if (bottom_align) { - rsy += height(); + rect_select.translate(0, height()); } - QRect rect_select(panel_timeline->rect_select_x, rsy, panel_timeline->rect_select_w, rsh); + draw_selection_rectangle(p, rect_select); } @@ -2743,7 +2912,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { int ghost_x = panel_timeline->getTimelineScreenPointFromFrame(g.in); int ghost_y = getScreenPointFromTrack(g.track); int ghost_width = panel_timeline->getTimelineScreenPointFromFrame(g.out) - ghost_x - 1; - int ghost_height = panel_timeline->calculate_track_height(g.track, -1) - 1; + int ghost_height = panel_timeline->GetTrackHeight(g.track) - 1; insert_points.append(ghost_y + (ghost_height>>1)); @@ -2781,7 +2950,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { int cursor_y = getScreenPointFromTrack(panel_timeline->split_tracks.at(i)); p.setPen(QColor(64, 64, 64)); - p.drawLine(cursor_x, cursor_y, cursor_x, cursor_y + panel_timeline->calculate_track_height(panel_timeline->split_tracks.at(i), -1)); + p.drawLine(cursor_x, cursor_y, cursor_x, cursor_y + panel_timeline->GetTrackHeight(panel_timeline->split_tracks.at(i))); } } } @@ -2804,12 +2973,12 @@ void TimelineWidget::paintEvent(QPaintEvent*) { } // Draw edit cursor - if (isLiveEditing() && is_track_visible(panel_timeline->cursor_track)) { + if (current_tool_shows_cursor() && is_track_visible(panel_timeline->cursor_track)) { int cursor_x = panel_timeline->getTimelineScreenPointFromFrame(panel_timeline->cursor_frame); int cursor_y = getScreenPointFromTrack(panel_timeline->cursor_track); p.setPen(Qt::gray); - p.drawLine(cursor_x, cursor_y, cursor_x, cursor_y + panel_timeline->calculate_track_height(panel_timeline->cursor_track, -1)); + p.drawLine(cursor_x, cursor_y, cursor_x, cursor_y + panel_timeline->GetTrackHeight(panel_timeline->cursor_track)); } } } @@ -2827,38 +2996,62 @@ bool TimelineWidget::is_track_visible(int track) { // ************************************** int TimelineWidget::getTrackFromScreenPoint(int y) { + int track_candidate = 0; + y += scroll; + if (bottom_align) { - y = -(y - height()); + y -= height(); } - y--; - int height_measure = 0; - int counter = ((!bottom_align && y > 0) || (bottom_align && y < 0)) ? 0 : -1; - int track_height = panel_timeline->calculate_track_height(counter, -1); - while (qAbs(y) > height_measure+track_height) { - if (olive::CurrentConfig.show_track_lines && counter != -1) y--; - height_measure += track_height; - if ((!bottom_align && y > 0) || (bottom_align && y < 0)) { - counter++; + + if (y < 0) { + track_candidate--; + } + + int compounded_heights = 0; + + while (true) { + int track_height = panel_timeline->GetTrackHeight(track_candidate); + if (olive::CurrentConfig.show_track_lines) track_height++; + if (y < 0) { + track_height = -track_height; + } + + int next_compounded_height = compounded_heights + track_height; + + + if (y >= qMin(next_compounded_height, compounded_heights) && y < qMax(next_compounded_height, compounded_heights)) { + return track_candidate; + } + + compounded_heights = next_compounded_height; + + if (y < 0) { + track_candidate--; } else { - counter--; + track_candidate++; } - track_height = panel_timeline->calculate_track_height(counter, -1); } - return counter; } int TimelineWidget::getScreenPointFromTrack(int track) { - int y = 0; - int counter = 0; - while (counter != track) { - if (bottom_align) counter--; - y += panel_timeline->calculate_track_height(counter, -1); - if (!bottom_align) counter++; - if (olive::CurrentConfig.show_track_lines && counter != -1) y++; + int point = 0; + + int start = (track < 0) ? -1 : 0; + int interval = (track < 0) ? -1 : 1; + + if (track < 0) track--; + + for (int i=start;i!=track;i+=interval) { + point += panel_timeline->GetTrackHeight(i); + if (olive::CurrentConfig.show_track_lines) point++; + } + + if (bottom_align) { + return height() - point - scroll; + } else { + return point - scroll; } - y++; - return (bottom_align) ? height() - y - scroll : y - scroll; } int TimelineWidget::getClipIndexFromCoords(long frame, int track) { diff --git a/ui/timelinewidget.h b/ui/timelinewidget.h index 9a25a88dc..3e7481618 100644 --- a/ui/timelinewidget.h +++ b/ui/timelinewidget.h @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include "project/sequence.h" #include "project/clip.h" @@ -36,79 +38,86 @@ class Timeline; namespace olive { - namespace timeline { - const int kGhostThickness = 2; - const int kClipTextPadding = 3; + namespace timeline { + const int kGhostThickness = 2; + const int kClipTextPadding = 3; - const int kTrackMinHeight = 30; - const int kTrackHeightIncrement = 10; - } + const int kTrackDefaultHeight = 40/* * QApplication::desktop()->devicePixelRatio()*/; + const int kTrackMinHeight = 30; + const int kTrackHeightIncrement = 10; + } } +struct TimelineTrackHeight { + int index; + int height; +}; + bool same_sign(int a, int b); void draw_waveform(ClipPtr clip, const FootageStream *ms, long media_length, QPainter* p, const QRect& clip_rect, int waveform_start, int waveform_limit, double zoom); class TimelineWidget : public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit TimelineWidget(QWidget *parent = 0); - QScrollBar* scrollBar; - bool bottom_align; + explicit TimelineWidget(QWidget *parent = 0); + QScrollBar* scrollBar; + bool bottom_align; + +public slots: + protected: - void paintEvent(QPaintEvent*); + void paintEvent(QPaintEvent*); - void resizeEvent(QResizeEvent *event); + void resizeEvent(QResizeEvent *event); - void mouseDoubleClickEvent(QMouseEvent *event); - void mousePressEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); - void leaveEvent(QEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void leaveEvent(QEvent *event); - void dragEnterEvent(QDragEnterEvent *event); - void dragLeaveEvent(QDragLeaveEvent *event); - void dropEvent(QDropEvent* event); - void dragMoveEvent(QDragMoveEvent *event); + void dragEnterEvent(QDragEnterEvent *event); + void dragLeaveEvent(QDragLeaveEvent *event); + void dropEvent(QDropEvent* event); + void dragMoveEvent(QDragMoveEvent *event); - void wheelEvent(QWheelEvent *event); + void wheelEvent(QWheelEvent *event); private: - void init_ghosts(); - void update_ghosts(const QPoint& mouse_pos, bool lock_frame); - bool is_track_visible(int track); - int getTrackFromScreenPoint(int y); - int getScreenPointFromTrack(int track); - int getClipIndexFromCoords(long frame, int track); + void init_ghosts(); + void update_ghosts(const QPoint& mouse_pos, bool lock_frame); + bool is_track_visible(int track); + int getTrackFromScreenPoint(int y); + int getScreenPointFromTrack(int track); + int getClipIndexFromCoords(long frame, int track); - int track_resize_mouse_cache; - int track_resize_old_value; - bool track_resizing; - int track_target; + bool track_resizing; + int track_target; - QVector pre_clips; - QVector post_clips; + QVector pre_clips; + QVector post_clips; - Media* rc_reveal_media; + Media* rc_reveal_media; - SequencePtr self_created_sequence; + SequencePtr self_created_sequence; - QTimer tooltip_timer; - int tooltip_clip; + QTimer tooltip_timer; + int tooltip_clip; - int scroll; + int scroll; - SetSelectionsCommand* selection_command; + SetSelectionsCommand* selection_command; signals: public slots: - void setScroll(int); + void setScroll(int); private slots: - void reveal_media(); - void show_context_menu(const QPoint& pos); - void toggle_autoscale(); - void tooltip_timer_timeout(); - void rename_clip(); - void open_sequence_properties(); + void reveal_media(); + void show_context_menu(const QPoint& pos); + void toggle_autoscale(); + void tooltip_timer_timeout(); + void rename_clip(); + void open_sequence_properties(); }; #endif // TIMELINEWIDGET_H From e54304c46e6cbb4ac1f595566f9c26ba998c3e61 Mon Sep 17 00:00:00 2001 From: Mathis Dubrul Date: Mon, 18 Feb 2019 07:45:38 +0100 Subject: [PATCH 13/30] Add french translation --- ts/olive_fr.ts | 1293 ++++++++++++++++++++++++------------------------ 1 file changed, 658 insertions(+), 635 deletions(-) diff --git a/ts/olive_fr.ts b/ts/olive_fr.ts index 699ac8de4..0e61d9c5a 100644 --- a/ts/olive_fr.ts +++ b/ts/olive_fr.ts @@ -6,12 +6,12 @@ Olive is a non-linear video editor. This software is free and protected by the GNU GPL. - + Olive est un logiciel de montage non-linéaire. Ce logiciel est libre et protégé par la licence GNU GPL. Olive Team is obliged to inform users that Olive source code is available for download from its website. - + L'équipe d'Olive vous informe que le code source d'Olive est disponible au téléchargement sur son site Web. @@ -19,7 +19,7 @@ Search for action... - + Rechercher une action… @@ -27,12 +27,12 @@ Advanced Video Settings - + Paramètres vidéo avancés Pixel Format: - + Format de pixel : @@ -40,12 +40,12 @@ Audio - + Audio Recording - + Enregistrement audio @@ -53,12 +53,12 @@ Amount - + Quantité Mix - + Mélanger @@ -66,17 +66,17 @@ Invalid - + Invalide Mono - + Mono Stereo - + Stéréo @@ -84,7 +84,7 @@ <untitled> - + &lt;Sans titre&gt; @@ -92,7 +92,7 @@ Set Color - + Définir la couleur @@ -100,27 +100,27 @@ Top Left - + En haut à gauche Top Right - + En haut à droite Bottom Left - + En bas à gauche Bottom Right - + En bas à droite Perspective - + Perspective @@ -128,7 +128,7 @@ Debug Log - + Journal de débogage @@ -137,22 +137,22 @@ Welcome to Olive! - + Bienvenue dans Olive ! Olive is a free open-source video editor released under the GNU GPL. If you have paid for this software, you have been scammed. - + Olive est un logiciel libre et open-source distribué sous la licence GNU GPL. Si vous avez payé pour ce logiciel, vous avez été victime d'un scam. This software is currently in ALPHA which means it is unstable and very likely to crash, have bugs, and have missing features. We offer no warranty so use at your own risk. Please report any bugs or feature requests at %1 - + Ce logiciel est actuellement en ALPHA, ce qui signifie qu'il a de grandes chances de planter, d'avoir des bugs ou de manquer de certaines fonctions. Nous n'offrons aucune garantie, utilisez-le à vos propres risques. Merci de nous rapporter tout bug ou demande d'ajout d'une fonctionnalité à %1 Thank you for trying Olive and we hope you enjoy it! - + Merci d'utiliser Olive, nous espérons que vous l'apprécierez ! @@ -160,89 +160,89 @@ Invalid effect - + Effet invalide No candidate for effect '%1'. This effect may be corrupt. Try reinstalling it or Olive. - + Aucun candidat pour l'effet '%1'. C'est effet est peut-être corrompu. Essayez de le réinstaller, ou de réinstaller Olive. Cu&t - + &Couper &Copy - + Cop&ier Move &Up - + Déplacer vers le &haut Move &Down - + Déplacer vers le &bas D&elete - + &Supprimer Load Settings From File - + Charger les paramètres Save Settings to File - + Enregistrer les paramètres Save Effect Settings - + Enregistrer les paramètres d'effet Effect XML Settings %1 - + Paramètres d'effet XML %1 Save Settings Failed - + L'enregistrement des paramètres a échoué Failed to open "%1" for writing. - + Impossible d'écrire dans "%1". Load Effect Settings - + Charger les paramètres d'effet Load Settings Failed - + Le chargement des paramètres a échoué Failed to open "%1" for reading. - + Impossible de lire "%1". This settings file doesn't match this effect. - + Ce fichier de paramètre ne correspond pas à cet effet. @@ -250,47 +250,47 @@ Effects: - + Effets : &Paste - + C&oller Add Video Effect - + Ajouter un effet vidéo VIDEO EFFECTS - + EFFETS VIDÉO Add Video Transition - + Ajouter une transition vidéo Add Audio Effect - + Ajouter un effet audio AUDIO EFFECTS - + EFFETS AUDIO Add Audio Transition - + Ajouter une transition audio (Multiple clips selected) - + (Clips multiples sélectionnés) @@ -298,12 +298,12 @@ Disable Keyframes - + Désactiver les images-clés Disabling keyframes will delete all current keyframes. Are you sure you want to do this? - + Désactiver les images-clés supprimera toutes les images-clés courantes. Êtes-vous sûr⋅e de vouloir cela ? @@ -311,7 +311,7 @@ File: - + Fichier : @@ -319,93 +319,93 @@ Export "%1" - + Exporter "%1" Unknown codec name %1 - + Nom de codec inconnu %1 Export Failed - + L'export a échoué Export failed - %1 - + Export échoué - %1 Invalid dimensions - + Dimensions invalides Export width and height must both be even numbers/divisible by 2. - + La largeur et la hauteur d'export doivent être des nombres pairs/divisibles par 2. Invalid codec - + Codec invalide Couldn't determine output parameters for the selected codec. This is a bug, please contact the developers. - + Impossible de déterminer les paramètres de sortie pour le codec sélectionné. Ceci est un bug, merci de contacter les développeurs. Invalid format - + Format invalide Couldn't determine output format. This is a bug, please contact the developers. - + Impossible de déterminer le format de sortie. Ceci est un bug, merci de contacter les développeurs. Export Media - + Exporter le média Quality-based (Constant Rate Factor) - + Qualitatif (Constant Rate Factor) Constant Bitrate - + Débit binaire constant Invalid Codec - + Codec invalide Failed to find a suitable encoder for this codec. Export will likely fail. - + Impossible de trouver un encodeur approprié pour ce codec. L'export risque de planter. Failed to find pixel format for this encoder. Export will likely fail. - + Impossible de trouver un format de pixel pour cet encodeur. L'export risque de planter. Bitrate (Mbps): - + Débit binaire (Mbps) : Quality (CRF): - + Qualité (CRF) : @@ -415,78 +415,83 @@ 17-18 = visually lossless (compressed, but unnoticeable) 23 = high quality 51 = lowest quality possible - + Facteur de qualité : + +0 = sans perte +17-18 = visuellement sans perte (compressé, mais imperceptible) +23 = haute qualité +51 = qualité la plus basse Target File Size (MB): - + Taille du fichier cible (Mo) : Format: - + Format : Range: - + Plage : Entire Sequence - + Séquence entière In to Out - + Du point d'entrée au point de sortie Video - + Vidéo Codec: - + Codec : Width: - + Largeur : Height: - + Hauteur : Frame Rate: - + Images par seconde : Compression Type: - + Type de compression : Advanced - + Avancé Sampling Rate: - + Taux d'échantillonnage : Bitrate (Kbps/CBR): - + Débit binaire (Kbps/CBR) : @@ -494,87 +499,87 @@ failed to send frame to encoder (%1) - + Échec de l'envoi d'une image vers l'encodeur (%1) failed to receive packet from encoder (%1) - + Échec de la réception d'un paquet depuis l'encodeur (%1) could not video encoder for %1 - + Impossible d'encoder la vidéo pour %1 could not allocate video stream - + impossible d'allouer le flux vidéo could not allocate video encoding context - + impossible d'allouer le contexte d'encodage vidéo could not open output video encoder (%1) - + impossible d'ouvrir l'encodeur vidéo de sortie (%1) could not copy video encoder parameters to output stream (%1) - + impossible de copier les paramètres d'encodage vidéo vers le flux de sortie (%1) could not audio encoder for %1 - + impossible d'encoder l'audio pour %1 could not allocate audio stream - + impossible d'allouer le flux audio could not allocate audio encoding context - + impossible d'allouer le contexte d'encodage audio could not open output audio encoder (%1) - + impossible d'ouvrir l'encodeur audio de sortie (%1) could not copy audio encoder parameters to output stream (%1) - + impossible de copier les paramètres d'encodage audio vers le flux de sortie (%1) could not allocate audio buffer (%1) - + impossible d'allouer le buffer audio (%1) could not create output format context - + impossible de créer le contexte du format de sortie could not open output file (%1) - + impossible d'ouvrir le fichier de sortie (%1) could not write output file header (%1) - + impossible d'écrire l'en-tête du fichier de sortie (%1) could not write output file trailer (%1) - + impossible d'écrire le trailer du fichier (%1) @@ -582,17 +587,17 @@ Type - + Type Fill Left with Right - + Remplir la gauche avec la droite Fill Right with Left - + Remplir la droite avec la gauche @@ -600,22 +605,22 @@ Failed to load Frei0r plugin "%1": %2 - + Impossible de charger le plugin Frei0r "%1": %2 NOTE: You can't load 32-bit Frei0r plugins into a 64-bit build of Olive. Please find a 64-bit version of this plugin or switch to a 32-bit build of Olive. - + NOTE : Vous ne pouvez pas charger de plugin Frei0r 32-bit dans la version 64-bit d'Olive. Essayez de trouver une version 64-bit de ce plugin ou basculez vers Olive 32-bit. NOTE: You can't load 64-bit Frei0r plugins into a 32-bit build of Olive. Please find a 32-bit version of this plugin or switch to a 64-bit build of Olive. - + NOTE : Vous ne pouvez pas charger de plugin Frei0r 64-bit dans la version 32-bit d'Olive. Essayez de trouver une version 32-bit de ce plugin ou basculez vers Olive 64-bit. Error loading Frei0r plugin - + Erreur durant le chargement du plugin Frei0r @@ -623,22 +628,22 @@ Graph Editor - + Éditeur de graphes Linear - + Linéaire Bezier - + Bézier Hold - + Maintenir @@ -646,17 +651,17 @@ Zoom to Selection - + Zoomer sur la sélection Zoom to Show All - + Zoomer pour tout montrer Reset View - + Réinitialiser la vue @@ -664,22 +669,22 @@ None (Progressive) - + Aucun (Progressif) Top Field First - + Trame supérieure en premier Bottom Field First - + Trame inférieure en premier Invalid - + Invalide @@ -687,7 +692,7 @@ Enable Keyframes - + Activer les images-clés @@ -695,17 +700,17 @@ Linear - + Linéaire Bezier - + Bézier Hold - + Maintenir @@ -714,13 +719,13 @@ Set Value - + Définir la valeur New value: - + Nouvelle valeur : @@ -728,17 +733,17 @@ Loading... - + Cargement… Loading '%1'... - + Chargement '%1'… Cancel - + Annuler @@ -746,52 +751,52 @@ Version Mismatch - + Incompatibilité de version This project was saved in a different version of Olive and may not be fully compatible with this version. Would you like to attempt loading it anyway? - + Ce projet a été enregistré avec une version différente d'Olive et peut ne pas être totalement compatible avec celle-ci. Voulez-vous essayer de l'ouvrir malgré tout ? Invalid Clip Link - + Lien du clip invalide This project contains an invalid clip link. It may be corrupt. Would you like to continue loading it? - + Ce projet contient un lien de clip invalide. Il peut être corrompu. Voulez-vous l'ouvrir malgré tout ? %1 - Line: %2 Col: %3 - + %1 - Ligne : %2 Col. : %3 User aborted loading - + L'utilisateur a abandonné le chargement XML Parsing Error - + Erreur de parsage XML Couldn't load '%1'. %2 - + Impossible de charger '%1'. %2 Project Load Error - + Erreur dans le chargement du projet Error loading project: %1 - + Erreur lors du chargement du projet : %1 @@ -799,677 +804,679 @@ Auto-recovery - + Récupération automatique Olive didn't close properly and an autorecovery file was detected. Would you like to open it? - + Olive ne s'est pas fermé convenablement et un fichier de récupépration a été détecté. Souhaitez-vous l'ouvrir ? &Project - + &Projet &Sequence - + &Séquence &Folder - + &Dossier Set In Point - + Définir le point d'entrée Set Out Point - + Définir le point de sortie Welcome to %1 - + Bienvenue à %1 Reset In Point - + Réinitialiser le point d'entrée Reset Out Point - + Réinitialiser le point de sortie Clear In/Out Point - + Effacer le point d'entrée/de sortie No active sequence - + Pas de séquence active Please open the sequence you wish to export. - + Veuillez ouvrir la séquence que vous souhaitez exporter. Save Project As... - + Enregistrer sous… Unsaved Project - + Projet non-sauvegardé This project has changed since it was last saved. Would you like to save it before closing? - + Ce projet a été modifié depuis la dernière sauvegarde. Souhaitez-vous l'enregistrer avant de fermer ? &File - + &Fichier &New - + &Nouveau &Open Project - + &Ouvrir un projet Clear Recent List - + Nettoyer la liste des projets récents Open Recent - + Ouvrir un projet récent &Save Project - + &Enregistrer le projet Save Project &As - + Enregistrer le projet &sous &Import... - + &Importer… &Export... - + &Exporter… E&xit - + &Quitter &Edit - + &Édition &Undo - + &Annuler Redo - + Rétablir Cu&t - + &Couper Cop&y - + Cop&ier &Paste - + C&oller Paste Insert - + Coller et Insérer Duplicate - + Dupliquer Delete - + Supprimer Ripple Delete - + Supprimer et raccorder Split - + Séparer Select &All - + Sélectionner &tout Deselect All - + Tout désélectionner Add Default Transition - + Ajouter la transition par défaut Link/Unlink - + Lier/Délier Enable/Disable - + Activer/Désactiver Nest - + Imbriquer Ripple to In Point - + Not literal, but it says what it is + Propager au point d'entrée Ripple to Out Point - + Not literal, but it says what it is + Propager au point de sortie Edit to In Point - + Éditer comme point d'entrée Edit to Out Point - + Éditer comme point de sortie Delete In/Out Point - + Supprimer les points d'entrée/de sortie Ripple Delete In/Out Point - + Supprimer et raccorder au point d'entrée/de sortie Set/Edit Marker - + Définir/Éditer un marqueur &View - + &Affichage Zoom In - + Zommer Zoom Out - + Dézoomer Increase Track Height - + Augmenter la hauteur de piste Decrease Track Height - + Diminuer la hauteur de piste Toggle Show All - + Vue d'ensemble Track Lines - + Contours des pistes Rectified Waveforms - + Formes d'onde ajustées Frames - + Images Drop Frame - + Drop Frame Non-Drop Frame - + Non-Drop Frame Milliseconds - + Millisecondes Title/Action Safe Area - + Zone sûre de titre/d'action Off - + Désactivée Default - + Par défaut 4:3 - + 4:3 16:9 - + 16:9 Custom - + Personnalisée Full Screen - + Plein-écran Full Screen Viewer - + Lecteur en plein écran &Playback - + &Lecture Go to Start - + Aller au début Previous Frame - + Image précédente Play/Pause - + Lire/Pause Play In to Out - + Lire entre les points d'entrée et de sortie Next Frame - + Image suivante Go to End - + Aller à la fin Go to Previous Cut - + Aller au point d'édition précédent Go to Next Cut - + Aller au point d'édition suivant Go to In Point - + Aller au point d'entrée Go to Out Point - + Aller au point de sortie Shuttle Left - + Jouer vers la gauche Shuttle Stop - + Arrêter Shuttle Right - + Jouer vers la droite Loop - + Boucle &Window - + &Fenêtre Project - + Projet Effect Controls - + Propriétés des effets Timeline - + Ligne du temps Graph Editor - + Éditeur de graphes Media Viewer - + Lecteur de média Sequence Viewer - + Lecteur de séquence Maximize Panel - + Agrandir le panneau Reset to Default Layout - + Restaurer la disposition par défaut &Tools - + &Outils Pointer Tool - + Curseur Edit Tool - + Éditer Ripple Tool - + Propagation Razor Tool - + Cutter Slip Tool - + Déplacer dessous Slide Tool - + Déplacer dessus Hand Tool - + Main Transition Tool - + Transition Enable Snapping - + Autoriser le magnétisme Selecting Also Seeks - + Sélectionner déplace la tête de lecture Edit Tool Also Seeks - + Éditer déplace la tête de lecture Edit Tool Selects Links - + Éditer sélectionne les liens Seek Also Selects - + Sélectionner avec la tête de lecture Seek to the End of Pastes - + Placer la tête de lecture après le collage Scroll Wheel Zooms - + Zoomer avec la molette Enable Drag Files to Timeline - + Autoriser le dépôt de fichier sur la ligne de temps Auto-Scale By Default - + Échelle automatique par défaut Enable Seek to Import - + Déplacer la tête de lecture à l'import Audio Scrubbing - + Lire l'audio au déplacement de la tête de lecture Enable Drop on Media to Replace - + Déposer sur un média pour le remplacer Enable Hover Focus - + Activer le focus au survol Ask For Name When Setting Marker - + Demander un nom à la création d'un marqueur No Auto-Scroll - + Pas de défilement automatique Page Auto-Scroll - + Défilement paginé Smooth Auto-Scroll - + Défilement doux Preferences - + Préférences Clear Undo - + Nettoyer la pile d'annulation &Help - + &Aide A&ction Search - + Chercher une a&ction Debug Log - + Journal de débogage &About... - + &À propos… <untitled> - + &lt;Sans titre&gt; Open Project... - + Ouvrir un projet… Missing recent project - + Projet récent manquant The project '%1' no longer exists. Would you like to remove it from the recent projects list? - + Le projet '%1' n'existe plus. Voulez-vous le retirer de la liste des projets récents ? Invalid aspect ratio - + Ratio d'image invalide The aspect ratio '%1' is invalid. Please try again. - + Le ratio d'image '%1' est invalide. Merci de réessayer à nouveau. Enter custom aspect ratio - + Entrez un ratio d'image personnalisé Enter the aspect ratio to use for the title/action safe area (e.g. 16:9): - + Entrez le ratio de la zone sûre de titre/d'action (ex: 16:9) : Nested Sequence - + Séquence imbriquée @@ -1477,17 +1484,17 @@ Set Marker - + Définir un marqueur Set clip marker name: - + Définir le nom du marqueur de clip : Set sequence marker name: - + Définir le nom du marqueur de séquence : @@ -1495,47 +1502,47 @@ New Folder - + Nouveau dossier Name: - + Nom : Filename: - + Nom de fichier : Video Dimensions: - + Dimensions de la vidéo : Frame Rate: - + Images par seconde : %1 field(s) (%2 frame(s)) - + %1 trame(s) (%2 image(s)) Interlacing: - + Entrelacement : Audio Frequency: - + Fréquence audio : Audio Channels: - + Canaux audio : @@ -1544,22 +1551,26 @@ Video Dimensions: %2x%3 Frame Rate: %4 Audio Frequency: %5 Audio Layout: %6 - + Nom : %1 +Dimensions vidéo : %2x%3 +Images par seconde : %4 +Fréquence audio: %5 +Canaux audio : %6 Name - + Nom Duration - + Durée Rate - + Images par seconde @@ -1567,55 +1578,55 @@ Audio Layout: %6 "%1" Properties - + "%1" Propriétés Tracks: - + Pistes : Video %1: %2x%3 %4FPS - + Vidéo %1 : %2×%3 %4 i/s Audio %1: %2Hz %3 - + Audio %1 : %2 Hz %3 %n channel(s) - - - + + %n canal + %n canaux Conform to Frame Rate: - + Conformer aux images par seconde : Alpha is Premultiplied - + Le canal alpha est prémultiplié Auto (%1) - + Auto (%1) Interlacing: - + Entrelacement : Name: - + Nom : @@ -1623,127 +1634,127 @@ Audio Layout: %6 Editing "%1" - + Édition "%1" New Sequence - + Nouvelle séquence Preset: - + Préréglage : Film 4K - + Film 4K TV 4K (Ultra HD/2160p) - + TV 4K (Ultra HD/2160p) 1080p - + 1080p 720p - + 720p 480p - + 480p 360p - + 360p 240p - + 240p 144p - + 144p NTSC (480i) - + NTSC (480i) PAL (576i) - + PAL (576i) Custom - + Personnalisé Video - + Vidéo Width: - + Largeur : Height: - + Hauteur : Frame Rate: - + Images par seconde : Pixel Aspect Ratio: - + Ratio des pixels : Square Pixels (1.0) - + Pixels carré (1,0) Interlacing: - + Entrelacement : None (Progressive) - + Aucun (Progressif) Audio - + Audio Sample Rate: - + Taux d'échantillonnage : Name: - + Nom : @@ -1751,7 +1762,7 @@ Audio Layout: %6 Pan - + Panoramique @@ -1759,7 +1770,7 @@ Audio Layout: %6 Generating Proxy: %1% - + Génération du proxy : %1% @@ -1767,283 +1778,285 @@ Audio Layout: %6 Preferences - + Préférences Invalid CSS File - + Fichier CSS invalide CSS file '%1' does not exist. - + Le fichier CSS '%1' n'existe pas. Warning - + Avertissement Some changed settings will require restarting Olive to take effect - + Certains paramètres modifiés nécessitent le redémarrage d'Olive pour prendre effet Confirm Reset All Shortcuts - + Confirmez la réinitialisation de tous les raccourcis clavier Are you sure you wish to reset all keyboard shortcuts to their defaults? - + Êtes-vous sûr⋅e de vouloir réinitialiser tous les raccourcis clavier à leur valeur par défaut ? Import Keyboard Shortcuts - + Importer les raccourcis clavier Error saving shortcuts - + Erreur dans l'enregistrement des raccourcis Failed to open file for reading - + Échec de l'ouverture du fichier Export Keyboard Shortcuts - + Exporter les raccourcis clavier Export Shortcuts - + Exporter les raccourcis Shortcuts exported successfully - + Les raccourcis ont été exporté avec succès Failed to open file for writing - + Échec de l'ouverture du fichier Browse for CSS file - + Choisir un fichier CSS Delete All Previews - + Supprimer toutes les prévisualisations Are you sure you want to delete all previews? - + Êtes-vous sûr⋅e de vouloir supprimer toutes les prévisualisations ? Previews Deleted - + Prévisualisations supprimées All previews deleted succesfully. You may have to re-open your current project for changes to take effect. - + Toutes les prévisualisations ont été supprimées avec succès. Il est possible que vous deviez ré-ouvrir le projet actuel pour que les changements prennent effet. Language: - + Langue : Custom CSS: - + CSS personnalisé : Browse - + Parcourir Image sequence formats: - + Formats de séquence d'image : Audio Recording: - + Enregistrement audio : Mono - + Mono Stereo - + Stéréo Effect Textbox Lines: - + Lignes des boîtes de texte d'effet : Thumbnail Resolution: - + Résolution des miniatures : Waveform Resolution: - + Résolution des formes d'onde : Delete Previews - + Supprimer les prévisualisations Use Software Fallbacks When Possible - + Utiliser les solutions de repli logicielles quand cela est possible General - + Général Behavior - + Comportement Seeking - + Tête de lecture Accurate Seeking Always show the correct frame (visual may pause briefly as correct frame is retrieved) - + Recherche fidèle +Tojours montrer l'image exacte (la prévisualisation peut se mettre en pause brièvement quand la bonne image est en cours de récupération) Fast Seeking Seek quickly (may briefly show inaccurate frames when seeking - doesn't affect playback/export) - + Recherhe rapide +Montrer rapidement (la prévisualition peut montrer brièvement des images imprécises lors du déplacement de la tête de lecture − cela n'affecte pas la lecture et l'export) Memory Usage - + Utilisation de la mémoire Upcoming Frame Queue: - + File d'image à venir : frames - + images seconds - + secondes Previous Frame Queue: - + File d'image précédentes : Playback - + Lecture Output Device: - + Système de sortie : Default - + Défaut Input Device: - + Système d'entrée : Sample Rate: - + Taux d'échantillonnage : Audio - + Audio Search for action or shortcut - + Rechercher une action ou un raccourci Action - + Action Shortcut - + Raccourci Import - + Importer Export - + Exporter Reset Selected - + Réinitialiser la sélection Reset All - + Tout réinitialiser Keyboard - + Clavier @@ -2051,12 +2064,12 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Could not open file - %1 - + Impossible d'ouvrir le fichier - %1 Could not find stream information - %1 - + Impossible de trouver les informations de flux - %1 @@ -2064,94 +2077,94 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Search media, markers, etc. - + Rechercher des médias, marqueurs, etc. Project - + Projet Sequence - + Séquence Replace '%1' - + Remplacer '%1' All Files - + Tous les fichiers No active sequence - + Pas de séquence active No sequence is active, please open the sequence you want to replace clips from. - + Pas de séquence active, veuillez ouvrir la séquence dont vous souhaitez modifier les clips. Active sequence selected - + Séquence active sélectionnée You cannot insert a sequence into itself, so no clips of this media would be in this sequence. - + Vous ne pouvez pas insérer une séquence à l'intérieur d'elle-même, donc aucun clip de ce média ne peut être dans cette séquence. Rename '%1' - + Renommer '%1' Enter new name: - + Entrez le nouveau nom : Delete media in use? - + Supprimer un média en cours d'utilisation ? The media '%1' is currently used in '%2'. Deleting it will remove all instances in the sequence. Are you sure you want to do this? - + Le média '%1' est actuellement utilisé dans '%2', le supprimer effacera toutes les instances dans la séquence. Êtes-vous sûr⋅e de vouloir cela ? Skip - + Passer Image sequence detected - + Séquence d'image détectée The file '%1' appears to be part of an image sequence. Would you like to import it as such? - + Le fichier '%1' semble faire partie d'une séquence d'image. Voulez-vous l'importer comme tel ? Import media... - + Importer un média… No sequence is active, please open the sequence you want to delete clips from. - + Aucune séquence n'est active, veuillez sélectionner la séquence dont vous souhaitez supprimer les clips. @@ -2159,77 +2172,77 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Create Proxy - + Créer un proxy Proxy - + Proxy Dimensions: - + Dimensions : Same Size as Source - + Même taille que la source Half Resolution (1/2) - + Moitié de la résolution (1/2) Quarter Resolution (1/4) - + Quart de la résolution (1/4) Eighth Resolution (1/8) - + Huitième de la résolution (1/8) Sixteenth Resolution (1/16) - + Seizième de la résolution (1/16) Format: - + Format : ProRes HQ - + ProRes HQ Location: - + Chemin : Same as Source (in "%1" folder) - + Comme la source (dans le dossier "%1") Proxy file exists - + Un fichier de proxy existe The file "%1" already exists. Do you wish to replace it? - + Le fichier "%1" existe déjà. Voulez-vous le remplacer ? Custom Location - + Chemin personnalisé @@ -2237,7 +2250,7 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Finished generating proxy for "%1" - + Génération du proxy pour "%1" terminée @@ -2245,67 +2258,67 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Replace clips using "%1" - + Remplacer les clips par "%1" Select which media you want to replace this media's clips with: - + Sélectionnez quel média vous souhaitez utiliser pour remplacer les clips de ce média : Keep the same media in-points - + Garder les mêmes points d'entrée du média Replace - + Remplacer Cancel - + Annuler No media selected - + Aucun média sélectionné Please select a media to replace with or click 'Cancel'. - + Veuillez sélectionner un média avec lequel remplacer ou choisir 'Annuler'. Same media selected - + Même média sélectionné You selected the same media that you're replacing. Please select a different one or click 'Cancel'. - + Vous avez sélectionné le même média que celui que vous souhaitez remplacer. Veuillez sélectionner un autre média ou cliquer sur 'Annuler'. Folder selected - + Dossier sélectionné You cannot replace footage with a folder. - + Vous ne pouvez pas remplacer un média par un dossier. Active sequence selected - + Séquence active sélectionnée You cannot insert a sequence into itself. - + Vous ne pouvez pas insérer une séquence dans elle-même. @@ -2313,7 +2326,7 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff %1 (copy) - + %1 (copy) @@ -2321,17 +2334,17 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Intensity - + Intensité Rotation - + Rotation Frequency - + Fréquence @@ -2339,37 +2352,37 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Type - + Type Solid Color - + Couleur unie SMPTE Bars - + Barres SMPTE Checkerboard - + Damier Opacity - + Opacité Color - + Couleur Checkerboard Size - + Taille du damier @@ -2377,137 +2390,137 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Import... - + Importer… New - + Nouveau View - + Affichage Tree View - + Vue arborescente Icon View - + Vue par icônes Show Toolbar - + Afficher la barre d'outils Show Sequences - + Afficher les séquences Replace/Relink Media - + Remplacer/Relier le média Reveal in Explorer - + Montrer dans l'explorateur Reveal in Finder - + Montrer dans le Finder Reveal in File Manager - + Montrer dans le gestionnaire de fichiers Replace Clips Using This Media - + Remplacer les clips utilisant ce média Create Sequence With This Media - + Créer une séquence à partir de ce média Duplicate - + Dupliquer Delete All Clips Using This Media - + Supprimer tous les clips utilisant ce média Proxy - + Proxy Generating proxy: %1% complete - + Génération du proxy: %1% achevée Create/Modify Proxy - + Créer/Modifier le proxy Create Proxy - + Créer le proxy Modify Proxy - + Modifier le proxy Restore Original - + Restaurer l'original Delete - + Supprimer Properties... - + Propriétés… Replace Media - + Remplacer le média You dropped a file onto '%1'. Would you like to replace it with the dropped file? - + Vous avez déposé un fichier sur '%1'. Souhaitez-vous le remplacer par le fichier déposé ? Delete proxy - + Supprimer le proxy Would you like to delete the proxy file "%1" as well? - + Souhaitez-vous aussi supprimer le fichier de proxy "%1" ? @@ -2515,37 +2528,37 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Speed/Duration - + Vitesse/Durée Speed: - + Vitesse : Frame Rate: - + Images par seconde : Duration: - + Durée : Reverse - + Inverser Maintain Audio Pitch - + Maintenir la hauteur audio Ripple Changes - + Propager les changements @@ -2553,7 +2566,7 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Edit Text - + Éditer le texte @@ -2561,113 +2574,113 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Text - + Texte Font - + Police Size - + Taille Color - + Couleur Alignment - + Allignement Left - + À gauche Center - + Centrer Right - + À droite Justify - + Justifié Top - + En haut Bottom - + En bas Word Wrap - + Retour automatique Outline - + Contour Outline Color - + Couleur du contour Outline Width - + Épaisseur du contour Shadow - + Ombre Shadow Color - + Couleur de l'ombre Shadow Distance - + Distance de l'ombre Shadow Softness - + Douceur de l'ombre Shadow Opacity - + Opacité de l'ombre Sample Text - + Texte d'exemple &Edit Text - + &Modifier le texte @@ -2675,47 +2688,47 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Timecode - + Code temporel Sequence - + Séquence Media - + Média Scale - + Échelle Color - + Couleur Background Color - + Couleur d'arrière-plan Background Opacity - + Opacité de l'arrière-plan Offset - + Écart Prepend - + Préfixe @@ -2723,147 +2736,147 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Timeline: - + Ligne du temps : <none> - + <aucun> Effect already exists - + L'effet existe déjà Clip '%1' already contains a '%2' effect. Would you like to replace it with the pasted one or add it as a separate effect? - + Le clip '%1' contient déjà un effet '%2'. SOuhaitez-vous le remplacer par l'effet du presse-papier ou ajouter celui comme un effet distinct ? Add - + Ajouter Replace - + Remplacer Skip - + Passer Do this for all conflicts found - + Faire ceci pour tous les conflits Title... - + Titre… Solid Color... - + Couleur unie… Bars... - + Barres… Tone... - + Ton… Noise... - + Bruit… Unsaved Project - + Projet non-sauvegardé You must save this project before you can record audio in it. - + Vous devez sauvegarder ce projet avant d'effectuer un enregistrement audio à l'intérieur. Click on the timeline where you want to start recording (drag to limit the recording to a certain timeframe) - + Cliquez sur la ligne du temps là où vous souhaitez commencer l'enregistrement (tirez pour limiter l'enregistrement jusqu'à une certaine image) Pointer Tool - + Curseur Edit Tool - + Éditer Ripple Tool - + Propagation Razor Tool - + Cutter Slip Tool - + Déplacer dessous Slide Tool - + Déplacer dessus Hand Tool - + Main Transition Tool - + Transition Snapping - + Magnétisme Zoom In - + Zoomer Zoom Out - + Dézoomer Record audio - + Enregistrement audio Add title, solid, bars, etc. - + Ajouter un titre, une couleur unie, des barres, etc. @@ -2871,7 +2884,7 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Center Timecodes - + Centrer les codes temporels @@ -2879,72 +2892,72 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff &Undo - + Ann&uler &Redo - + &Rétablir C&ut - + &Couper Cop&y - + Cop&ier &Paste - + C&oller R&ipple Delete - + Supprimer et r&accorder Sequence Settings - + Paramètres de la séquence &Speed/Duration - + &Vitesse/Durée Auto-s&cale - + Échelle automati&que Enable/Disable - + Activer/Désactiver Link/Unlink - + Lier/Délier &Nest - + Im&briquer &Reveal in Project - + &Révéler dans le projet R&ename - + R&enommer @@ -2952,62 +2965,65 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Start: %2 End: %3 Duration: %4 - + %1 +Début : %2 +Fin : %3 +Durée : %4 Rename '%1' - + Renommer '%1' Rename multiple clips - + Renommer plusieurs clips Enter a new name for this clip: - + Entrez un nouveau nom pour ce clip : Error - + Erreur Couldn't locate media wrapper for sequence. - + Impossible de localiser le conteneurdu média de cette séquence. Title - + Titre Solid Color - + Couleur unie Bars - + Barres Tone - + Ton Noise - + Bruit Duration: - + Durée : @@ -3015,22 +3031,22 @@ Duration: %4 Type - + Type Frequency - + Fréquence Amount - + Quantité Mix - + Mélange @@ -3038,157 +3054,164 @@ Duration: %4 Position - + Position Scale - + Échelle Uniform Scale - + Échelle uniforme Rotation - + Rotation Anchor Point - + Point d'ancrage Opacity - + Opacité Blend Mode - + Mode de fusion Normal - + Normal Darken - + Assombrir Multiply - + Multiplier Color Burn - + Not literal but same translation as Adobe + Densité couleur + Linear Burn - + Not literal but same translation as Adobe + Densité linéaire + Lighten - + Éclaircir Screen - + Not literal but same translation as Adobe + Superposition Color Dodge - + Not literal but same translation as Adobe + Densité couleur - Linear Dodge (Add) - + Not literal but same translation as Adobe + Densité linéaire - Overlay - + Incrustation Soft Light - + Not literal but same translation as Adobe + Lumière tamisée Hard Light - + Lumière crue Vivid Light - + Lumière vive Linear Light - + Lumière linéaire Pin Light - + Not literal but same translation as Adobe + Lumière ponctuelle Hard Mix - + Mélange maximal Difference - + Différence Exclusion - + Exclusion Reflect - + Réflexion Substract - + Soustraction Average - + Moyenne Glow - + Lueur Negation - + Négation Phoenix - + Phénix @@ -3196,7 +3219,7 @@ Duration: %4 Length - + Longueur @@ -3206,62 +3229,62 @@ Duration: %4 Error loading VST plugin - + Erreur lors du chargement du plugin VST Failed to create VST reference - + Impossible de créer la référence VST Failed to load VST plugin "%1": %2 - + Impossible de charger le plugin VST "%1": %2 NOTE: You can't load 32-bit VST plugins into a 64-bit build of Olive. Please find a 64-bit version of this plugin or switch to a 32-bit build of Olive. - + NOTE : Vous ne pouvez pas charger de plugin VST 32-bit avec la version 64-bit d'Olive. Essayez de trouver une version 64-bit de ce plugin ou basculez sur la version 32-bit d'Olive. NOTE: You can't load 64-bit VST plugins into a 32-bit build of Olive. Please find a 32-bit version of this plugin or switch to a 64-bit build of Olive. - + NOTE : Vous ne pouvez pas charger de plugin VST 64-bit avec la version 32-bit d'Olive. Essayez de trouver une version 32-bit de ce plugin ou basculez sur la version 64-bit d'Olive. Failed to locate entry point for dynamic library. - + Impossible de localiser le point d'entrée de la bibliothèque dynamique. VST Error - + Erreur VST Plugin's magic number is invalid - + Le nombre magique du plugin est invalide Plugin - + Plugin Interface - + Interface Show - + Montrer VST Plugin - + Plugin VST @@ -3269,17 +3292,17 @@ Duration: %4 Sequence Viewer - + Lecteur de séquence Media Viewer - + Lecteur de média (none) - + (aucun) @@ -3287,57 +3310,57 @@ Duration: %4 Save Frame as Image... - + Enregistrer l'image… Show Fullscreen - + Montrer en plein écran Disable - + Désactiver Screen %1: %2x%3 - + Écran %1: %2x%3 Zoom - + Zoom Fit - + Ajuster Custom - + Personnalisé Close Media - + Fermer le média Save Frame - + Enregistrer l'image Viewer Zoom - + Zoom du lecteur Set Custom Zoom Value: - + Définir une valeur de zoom personnalisée : @@ -3345,7 +3368,7 @@ Duration: %4 Exit Fullscreen - + Quitter le mode plein-écran @@ -3353,12 +3376,12 @@ Duration: %4 (unknown) - + (inconnu) Missing Effect - + Effet manquant @@ -3366,7 +3389,7 @@ Duration: %4 Volume - + Volume @@ -3374,12 +3397,12 @@ Duration: %4 Invalid transition - + Transition invalide No candidate for transition '%1'. This transition may be corrupt. Try reinstalling it or Olive. - + Aucun candidat pour la transition '%1'. Cette transition est peut-être corrompue. Essayez de la réinstaller, ou de réinstaller Olive. From 2bdafc72cb68a040817f1a648e6416c52ba8cc76 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sun, 17 Feb 2019 23:46:39 -0800 Subject: [PATCH 14/30] preview generator updates the appropriate ui when done --- io/previewgenerator.cpp | 4 ++++ panels/project.cpp | 3 +++ project/sequence.cpp | 13 ++++++++++++- project/sequence.h | 2 ++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/io/previewgenerator.cpp b/io/previewgenerator.cpp index e04e5e340..1d4aab8bc 100644 --- a/io/previewgenerator.cpp +++ b/io/previewgenerator.cpp @@ -197,6 +197,10 @@ void PreviewGenerator::finalize_media() { } else { olive::media_icon_service->SetMediaIcon(media, ICON_TYPE_VIDEO); } + + if (olive::ActiveSequence != nullptr) { + olive::ActiveSequence->RefreshClips(media); + } } } diff --git a/panels/project.cpp b/panels/project.cpp index df4dc0d3c..3f41708f0 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -221,6 +221,9 @@ Project::Project(QWidget *parent) : connect(directory_up, SIGNAL(clicked(bool)), this, SLOT(go_up_dir())); connect(icon_view, SIGNAL(changed_root()), this, SLOT(set_up_dir_enabled())); + connect(olive::media_icon_service.get(), SIGNAL(IconChanged()), icon_view->viewport(), SLOT(update())); + connect(olive::media_icon_service.get(), SIGNAL(IconChanged()), tree_view->viewport(), SLOT(update())); + update_view_type(); Retranslate(); diff --git a/project/sequence.cpp b/project/sequence.cpp index cd671b712..e3d9633d7 100644 --- a/project/sequence.cpp +++ b/project/sequence.cpp @@ -64,7 +64,18 @@ long Sequence::getEndFrame() { end = c->timeline_out; } } - return end; + return end; +} + +void Sequence::RefreshClips(Media *m) { + for (int i=0;imedia == m)) { + c->refresh(); + } + } } void Sequence::getTrackLimits(int* video_tracks, int* audio_tracks) { diff --git a/project/sequence.h b/project/sequence.h index bdb150305..e242a0dcc 100644 --- a/project/sequence.h +++ b/project/sequence.h @@ -42,6 +42,8 @@ public: int audio_frequency; int audio_layout; + void RefreshClips(Media* m = nullptr); + QVector selections; long playhead; From 886c5f12735ae0b3c59ef9c469df840b2e10c37e Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Mon, 18 Feb 2019 01:38:17 -0800 Subject: [PATCH 15/30] small timeline cleanup --- project/sequence.h | 40 ++++++------ ui/timelinewidget.cpp | 140 ++++++++++++++++++++++++++++++++---------- 2 files changed, 128 insertions(+), 52 deletions(-) diff --git a/project/sequence.h b/project/sequence.h index e242a0dcc..1053118cc 100644 --- a/project/sequence.h +++ b/project/sequence.h @@ -30,40 +30,40 @@ class Sequence { public: - Sequence(); - ~Sequence(); - SequencePtr copy(); - QString name; - void getTrackLimits(int* video_tracks, int* audio_tracks); + Sequence(); + ~Sequence(); + SequencePtr copy(); + QString name; + void getTrackLimits(int* video_tracks, int* audio_tracks); long getEndFrame(); - int width; - int height; - double frame_rate; - int audio_frequency; - int audio_layout; + int width; + int height; + double frame_rate; + int audio_frequency; + int audio_layout; void RefreshClips(Media* m = nullptr); - QVector selections; - long playhead; + QVector selections; + long playhead; - bool using_workarea; - long workarea_in; - long workarea_out; + bool using_workarea; + long workarea_in; + long workarea_out; - bool wrapper_sequence; + bool wrapper_sequence; - int save_id; + int save_id; - QVector markers; - QVector clips; + QVector markers; + QVector clips; }; using SequencePtr = std::shared_ptr; // static variable for the currently active sequence namespace olive { - extern SequencePtr ActiveSequence; +extern SequencePtr ActiveSequence; } #endif // SEQUENCE_H diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index ee22bf168..ea7d3bcd1 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -673,7 +673,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { // if the user clicks a selected clip while holding shift, deselect the clip panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track); - // if the user isn't holding alt, also deselect all of its links + // if the user isn't holding alt, also deselect all of its links as well if (!alt) { for (int i=0;ilinked.size();i++) { ClipPtr link = olive::ActiveSequence->clips.at(clip->linked.at(i)); @@ -681,9 +681,11 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { } } - } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER && panel_timeline->transition_select != kTransitionNone) { - + } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER + && panel_timeline->transition_select != kTransitionNone) { + // if the clip was selected by then the user clicked a transition, de-select the clip and its links + // and select the transition only panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track); @@ -695,14 +697,22 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { Selection s; s.track = clip->track; + // select the transition only if (panel_timeline->transition_select == kTransitionOpening && clip->get_opening_transition() != nullptr) { s.in = clip->timeline_in; - if (clip->get_opening_transition()->secondary_clip != nullptr) s.in -= clip->get_opening_transition()->get_true_length(); + + if (clip->get_opening_transition()->secondary_clip != nullptr) { + s.in -= clip->get_opening_transition()->get_true_length(); + } + s.out = clip->timeline_in + clip->get_opening_transition()->get_true_length(); } else if (panel_timeline->transition_select == kTransitionClosing && clip->get_closing_transition() != nullptr) { s.in = clip->timeline_out - clip->get_closing_transition()->get_true_length(); s.out = clip->timeline_out; - if (clip->get_closing_transition()->secondary_clip != nullptr) s.out += clip->get_closing_transition()->get_true_length(); + + if (clip->get_closing_transition()->secondary_clip != nullptr) { + s.out += clip->get_closing_transition()->get_true_length(); + } } olive::ActiveSequence->selections.append(s); } @@ -1150,18 +1160,29 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { } else if (panel_timeline->transition_tool_proc) { const Ghost& g = panel_timeline->ghosts.at(0); + // if the transition is greater than 0 length (if it is 0, we make nothing) if (g.in != g.out) { + + // get transition length long transition_start = qMin(g.in, g.out); long transition_end = qMax(g.in, g.out); + ClipPtr pre = olive::ActiveSequence->clips.at(g.clip); ClipPtr post = pre; make_room_for_transition(ca, pre, panel_timeline->transition_tool_type, transition_start, transition_end, true); if (panel_timeline->transition_tool_post_clip > -1) { + // post_clip == -1 means this will be just one transition on one clip rather than a shared transition + // between two clips + post = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_post_clip); - int opposite_type = (panel_timeline->transition_tool_type == kTransitionOpening) ? kTransitionClosing : kTransitionOpening; + + // get opposite transition type + int opposite_type = (panel_timeline->transition_tool_type == kTransitionOpening) ? + kTransitionClosing : kTransitionOpening; + make_room_for_transition( ca, post, @@ -1180,7 +1201,9 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { } if (transition_start < post->timeline_in || transition_end > pre->timeline_out) { - // delete shit over there and extend timeline in + // if the user extended the transition beyond the clip's boundaries, delete the content there and extend + // the clip to fill these new boundaries + QVector areas; Selection s; s.track = post->track; @@ -2111,17 +2134,13 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { panel_timeline->rect_select_rect.setBottom(event->pos().y()); } - long frame_start = panel_timeline->drag_frame_start; - long frame_end = panel_timeline->cursor_frame; - long frame_min = qMin(frame_start, frame_end); - long frame_max = qMax(frame_start, frame_end); + long frame_min = qMin(panel_timeline->drag_frame_start, panel_timeline->cursor_frame); + long frame_max = qMax(panel_timeline->drag_frame_start, panel_timeline->cursor_frame); - int track_start = panel_timeline->drag_track_start; - int track_end = panel_timeline->cursor_track; - - int track_min = qMin(track_start, track_end); - int track_max = qMax(track_start, track_end); + int track_min = qMin(panel_timeline->drag_track_start, panel_timeline->cursor_track); + int track_max = qMax(panel_timeline->drag_track_start, panel_timeline->cursor_track); + // determine which clips are in this rectangular selection QVector selected_clips; for (int i=0;iclips.size();i++) { ClipPtr clip = olive::ActiveSequence->clips.at(i); @@ -2130,6 +2149,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { clip->track <= track_max && !(clip->timeline_in < frame_min && clip->timeline_out < frame_min) && !(clip->timeline_in > frame_max && clip->timeline_out > frame_max)) { + + // create a group of the clip (and its links if alt is not pressed) QVector session_clips; session_clips.append(clip); @@ -2139,9 +2160,11 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } } + // for each of these clips, see if clip has already been added - + // this can easily happen due to adding linked clips for (int j=0;jselections.resize(selected_clips.size() + panel_timeline->selection_offset); for (int i=0;iselections[i+panel_timeline->selection_offset]; @@ -2167,9 +2193,12 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { panel_timeline->repaint_timeline(); } else { + + // set up rectangle selecting panel_timeline->rect_select_rect.setX(event->pos().x()); if (bottom_align) { + // bottom aligned widgets start with 0 at the bottom and go down to a negative number panel_timeline->rect_select_rect.setY(event->pos().y() - height()); } else { panel_timeline->rect_select_rect.setY(event->pos().y()); @@ -2179,10 +2208,13 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { panel_timeline->rect_select_rect.setHeight(0); panel_timeline->rect_select_proc = true; + } } else if (current_tool_shows_cursor()) { - // redraw because we have a cursor + + // we're not currently performing an action (click is not pressed), but redraw because we have an on-screen cursor panel_timeline->repaint_timeline(); + } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->tool == TIMELINE_TOOL_RIPPLE || panel_timeline->tool == TIMELINE_TOOL_ROLLING) { @@ -2386,21 +2418,37 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } } } else if (panel_timeline->tool == TIMELINE_TOOL_SLIP) { + + // we're not currently performing any slipping, all we do here is set the cursor if mouse is hovering over a + // cursor if (getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track) > -1) { setCursor(Qt::SizeHorCursor); } else { unsetCursor(); } + } else if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION) { + if (panel_timeline->transition_tool_init) { + + // the transition tool has started + if (panel_timeline->transition_tool_proc) { + + // ghosts have been set up, so just run update update_ghosts(event->pos(), event->modifiers() & Qt::ShiftModifier); + } else { + + // transition tool is being used but ghosts haven't been set up yet, set them up now ClipPtr c = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_pre_clip); Ghost g; - g.in = g.old_in = g.out = g.old_out = (panel_timeline->transition_tool_type == kTransitionOpening) ? c->timeline_in : c->timeline_out; + g.in = g.old_in = g.out = g.old_out = (panel_timeline->transition_tool_type == kTransitionOpening) ? + c->timeline_in + : c->timeline_out; + g.track = c->track; g.clip = panel_timeline->transition_tool_pre_clip; g.media_stream = panel_timeline->transition_tool_type; @@ -2410,31 +2458,59 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { panel_timeline->transition_tool_proc = true; } - } else { - int mouse_clip = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); - if (mouse_clip > -1) { - ClipPtr c = olive::ActiveSequence->clips.at(mouse_clip); - if (same_sign(c->track, panel_timeline->transition_tool_side)) { - panel_timeline->transition_tool_pre_clip = mouse_clip; - long halfway = c->timeline_in + (c->getLength()/2); - long between_range = getFrameFromScreenPoint(panel_timeline->zoom, TRANSITION_BETWEEN_RANGE) + 1; - if (panel_timeline->cursor_frame > halfway) { + } else { + + // transition tool has been selected but is not yet active, so we show screen feedback to the user on + // possible transitions + + int mouse_clip = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); + + // set default transition tool references to no clip + panel_timeline->transition_tool_pre_clip = -1; + panel_timeline->transition_tool_post_clip = -1; + + if (mouse_clip > -1) { + + // cursor is hovering over a clip + + ClipPtr c = olive::ActiveSequence->clips.at(mouse_clip); + + // check if the clip and transition are both the same sign (meaning video/audio are the same) + if (same_sign(c->track, panel_timeline->transition_tool_side)) { + + // set "pre" clip to the hovered clip + panel_timeline->transition_tool_pre_clip = mouse_clip; + + // set whether the transition is opening or closing based on whether the cursor is on the left half + // or right half of the clip + if (panel_timeline->cursor_frame > (c->timeline_in + (c->getLength()/2))) { panel_timeline->transition_tool_type = kTransitionClosing; } else { panel_timeline->transition_tool_type = kTransitionOpening; } - panel_timeline->transition_tool_post_clip = -1; + // the range within which the transition tool will assume the user wants to make a shared transition + // between two clips rather than just one transition on one clip + long between_range = getFrameFromScreenPoint(panel_timeline->zoom, TRANSITION_BETWEEN_RANGE) + 1; + + // if the cursor is within this range, set the post_clip to be the next clip touching + // + // getClipIndexFromCoords() will automatically set to -1 if there's no clip there which means the + // end result will be the same as not setting a clip here at all if (panel_timeline->cursor_frame < c->timeline_in + between_range) { + + // get clip touching to the left panel_timeline->transition_tool_post_clip = getClipIndexFromCoords(c->timeline_in-1, c->track); + } else if (panel_timeline->cursor_frame > c->timeline_out - between_range) { + + // get clip touching to the right panel_timeline->transition_tool_post_clip = getClipIndexFromCoords(c->timeline_out+1, c->track); + } + } - } else { - panel_timeline->transition_tool_pre_clip = -1; - panel_timeline->transition_tool_post_clip = -1; } } From d1037d4ffa62007d63441b4f6668cd80d7e0da63 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Mon, 18 Feb 2019 03:13:27 -0800 Subject: [PATCH 16/30] add transition rewrite --- panels/effectcontrols.cpp | 13 ++- panels/timeline.cpp | 38 +++++-- panels/timeline.h | 5 +- project/undo.cpp | 71 ++++++------ project/undo.h | 16 +-- ui/timelinewidget.cpp | 228 +++++++++++++++++++++----------------- 6 files changed, 215 insertions(+), 156 deletions(-) diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp index 85485ecd6..ccbff20b8 100644 --- a/panels/effectcontrols.cpp +++ b/panels/effectcontrols.cpp @@ -46,6 +46,7 @@ #include "panels/grapheditor.h" #include "ui/viewerwidget.h" #include "io/clipboard.h" +#include "io/config.h" #include "ui/timelineheader.h" #include "ui/keyframeview.h" #include "ui/resizablescrollbar.h" @@ -103,10 +104,18 @@ void EffectControls::menu_select(QAction* q) { const EffectMeta* meta = reinterpret_cast(q->data().value()); if (effect_menu_type == EFFECT_TYPE_TRANSITION) { if (c->opening_transition == nullptr) { - ca->append(new AddTransitionCommand(c, nullptr, nullptr, meta, kTransitionOpening, 30)); + ca->append(new AddTransitionCommand(c, + nullptr, + nullptr, + meta, + olive::CurrentConfig.default_transition_length)); } if (c->closing_transition == nullptr) { - ca->append(new AddTransitionCommand(c, nullptr, nullptr, meta, kTransitionClosing, 30)); + ca->append(new AddTransitionCommand(nullptr, + c, + nullptr, + meta, + olive::CurrentConfig.default_transition_length)); } } else { ca->append(new AddEffectCommand(c, nullptr, meta)); diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 6488f94b3..2ded033b8 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -78,8 +78,8 @@ Timeline::Timeline(QWidget *parent) : creating(false), transition_tool_init(false), transition_tool_proc(false), - transition_tool_pre_clip(-1), - transition_tool_post_clip(-1), + transition_tool_open_clip(-1), + transition_tool_close_clip(-1), hand_moving(false), block_repaints(false), scroll(0) @@ -379,11 +379,19 @@ void Timeline::add_transition() { if (c != nullptr && is_clip_selected(c, true)) { int transition_to_add = (c->track < 0) ? TRANSITION_INTERNAL_CROSSDISSOLVE : TRANSITION_INTERNAL_LINEARFADE; if (c->get_opening_transition() == nullptr) { - ca->append(new AddTransitionCommand(c, nullptr, nullptr, get_internal_meta(transition_to_add, EFFECT_TYPE_TRANSITION), kTransitionOpening, 30)); + ca->append(new AddTransitionCommand(c, + nullptr, + nullptr, + get_internal_meta(transition_to_add, EFFECT_TYPE_TRANSITION), + olive::CurrentConfig.default_transition_length)); adding = true; } if (c->get_closing_transition() == nullptr) { - ca->append(new AddTransitionCommand(c, nullptr, nullptr, get_internal_meta(transition_to_add, EFFECT_TYPE_TRANSITION), kTransitionClosing, 30)); + ca->append(new AddTransitionCommand(nullptr, + c, + nullptr, + get_internal_meta(transition_to_add, EFFECT_TYPE_TRANSITION), + olive::CurrentConfig.default_transition_length)); adding = true; } } @@ -2047,16 +2055,30 @@ void move_clip(ComboAction* ca, ClipPtr c, long iin, long iout, long iclip_in, i ca->append(new MoveClipAction(c, iin, iout, iclip_in, itrack, relative)); if (verify_transitions) { - if (c->get_opening_transition() != nullptr && c->get_opening_transition()->secondary_clip != nullptr && c->get_opening_transition()->secondary_clip->timeline_out != iin) { + + // if this is a shared transition, and the corresponding clip will be moved away somehow + if (c->get_opening_transition() != nullptr + && c->get_opening_transition()->secondary_clip != nullptr + && c->get_opening_transition()->secondary_clip->timeline_out != iin) { // separate transition ca->append(new SetPointer(reinterpret_cast(&c->get_opening_transition()->secondary_clip), nullptr)); - ca->append(new AddTransitionCommand(c->get_opening_transition()->secondary_clip, nullptr, c->get_opening_transition(), nullptr, kTransitionClosing, 0)); + ca->append(new AddTransitionCommand(nullptr, + c->get_opening_transition()->secondary_clip, + c->get_opening_transition(), + nullptr, + 0)); } - if (c->get_closing_transition() != nullptr && c->get_closing_transition()->secondary_clip != nullptr && c->get_closing_transition()->parent_clip->timeline_in != iout) { + if (c->get_closing_transition() != nullptr + && c->get_closing_transition()->secondary_clip != nullptr + && c->get_closing_transition()->parent_clip->timeline_in != iout) { // separate transition ca->append(new SetPointer(reinterpret_cast(&c->get_closing_transition()->secondary_clip), nullptr)); - ca->append(new AddTransitionCommand(c, nullptr, c->get_closing_transition(), nullptr, kTransitionClosing, 0)); + ca->append(new AddTransitionCommand(nullptr, + c, + c->get_closing_transition(), + nullptr, + 0)); } } } diff --git a/panels/timeline.h b/panels/timeline.h index 9376d089b..141658298 100644 --- a/panels/timeline.h +++ b/panels/timeline.h @@ -177,9 +177,8 @@ public: // transition variables bool transition_tool_init; bool transition_tool_proc; - int transition_tool_pre_clip; - int transition_tool_post_clip; - int transition_tool_type; + int transition_tool_open_clip; + int transition_tool_close_clip; const EffectMeta* transition_tool_meta; int transition_tool_side; diff --git a/project/undo.cpp b/project/undo.cpp index 7a5c596dc..5a0a998f2 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -220,55 +220,64 @@ void AddEffectCommand::doRedo() { done = true; } -AddTransitionCommand::AddTransitionCommand(ClipPtr c, - ClipPtr s, +AddTransitionCommand::AddTransitionCommand(ClipPtr iopen, + ClipPtr iclose, TransitionPtr copy, const EffectMeta *itransition, - int itype, int ilength) { - primary = c; - secondary = s; - transition_to_copy = copy; + open_ = iopen; + close_ = iclose; + transition_to_copy_ = copy; transition_meta_ = itransition; - type = itype; - length = ilength; + length_ = ilength; + new_transition_ref_ = nullptr; } void AddTransitionCommand::doUndo() { - if (type == kTransitionOpening) { - primary->opening_transition = old_ptransition; - if (secondary != nullptr) secondary->closing_transition = old_stransition; - } else { - primary->closing_transition = old_ptransition; - if (secondary != nullptr) secondary->opening_transition = old_stransition; + if (open_ != nullptr) { + open_->opening_transition = old_open_transition_; + } + + if (close_ != nullptr) { + close_->closing_transition = old_close_transition_; } } void AddTransitionCommand::doRedo() { - // store old transition of primary clip - old_ptransition = primary->opening_transition; - - // create new transition object - TransitionPtr new_transition; - if (transition_to_copy == nullptr) { - new_transition = get_transition_from_meta(primary, secondary, transition_meta_); - } else { - new_transition = transition_to_copy->copy(primary, nullptr); + // convert open/close clips to primary/secondary for transition object + ClipPtr primary = open_; + ClipPtr secondary = close_; + if (primary == nullptr) { + primary = secondary; + secondary = nullptr; } - primary->opening_transition = new_transition; + // create new transition object + if (new_transition_ref_ == nullptr) { + if (transition_to_copy_ == nullptr) { + new_transition_ref_ = get_transition_from_meta(primary, secondary, transition_meta_); + } else { + new_transition_ref_ = transition_to_copy_->copy(primary, nullptr); + } + } - if (secondary != nullptr) { - // store old secondary transition - old_stransition = secondary->closing_transition; + // set opening clip's opening transition to this and store the old one + if (open_ != nullptr) { + old_open_transition_ = open_->opening_transition; - // set secondary transition to the same transition - secondary->closing_transition = new_transition; + open_->opening_transition = new_transition_ref_; + } + + // set closing clip's closing transition to this and store the old one + if (close_ != nullptr) { + old_close_transition_ = close_->closing_transition; + + close_->closing_transition = new_transition_ref_; } // if a length was specified, set it now - if (length > 0) { - new_transition->set_length(length); + if (length_ > 0) { + new_transition_ref_->set_length(length_); } } diff --git a/project/undo.h b/project/undo.h index 830a9973f..0ec1d1005 100644 --- a/project/undo.h +++ b/project/undo.h @@ -138,18 +138,18 @@ private: class AddTransitionCommand : public OliveAction { public: - AddTransitionCommand(ClipPtr c, ClipPtr s, TransitionPtr copy, const EffectMeta* itransition, int itype, int ilength); + AddTransitionCommand(ClipPtr iopen, ClipPtr iclose, TransitionPtr copy, const EffectMeta* itransition, int ilength); virtual void doUndo() override; virtual void doRedo() override; private: - ClipPtr primary; - ClipPtr secondary; - TransitionPtr transition_to_copy; + ClipPtr open_; + ClipPtr close_; + TransitionPtr transition_to_copy_; const EffectMeta* transition_meta_; - int type; - int length; - TransitionPtr old_ptransition; - TransitionPtr old_stransition; + int length_; + TransitionPtr old_open_transition_; + TransitionPtr old_close_transition_; + TransitionPtr new_transition_ref_; }; class ModifyTransitionCommand : public OliveAction { diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index ea7d3bcd1..199b3e396 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -836,7 +836,8 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { { // if there is a clip to run the transition tool on, initiate the transition tool - if (panel_timeline->transition_tool_pre_clip > -1) { + if (panel_timeline->transition_tool_open_clip > -1 + || panel_timeline->transition_tool_close_clip > -1) { panel_timeline->transition_tool_init = true; } @@ -1167,75 +1168,85 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { long transition_start = qMin(g.in, g.out); long transition_end = qMax(g.in, g.out); + ClipPtr open = (panel_timeline->transition_tool_open_clip > -1) + ? olive::ActiveSequence->clips.at(panel_timeline->transition_tool_open_clip) + : nullptr; - ClipPtr pre = olive::ActiveSequence->clips.at(g.clip); - ClipPtr post = pre; + ClipPtr close = (panel_timeline->transition_tool_close_clip > -1) + ? olive::ActiveSequence->clips.at(panel_timeline->transition_tool_close_clip) + : nullptr; - make_room_for_transition(ca, pre, panel_timeline->transition_tool_type, transition_start, transition_end, true); + bool shared_transition = (open != nullptr && close != nullptr); - if (panel_timeline->transition_tool_post_clip > -1) { - // post_clip == -1 means this will be just one transition on one clip rather than a shared transition - // between two clips + if (open != nullptr) { + open->undeletable = true; + } + if (close != nullptr) { + close->undeletable = true; + } - post = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_post_clip); + // delete everything under this new transition + QVector areas; + Selection s; + s.in = transition_start; + s.out = transition_end; + s.track = g.track; + areas.append(s); + panel_timeline->delete_areas_and_relink(ca, areas, false); - // get opposite transition type - int opposite_type = (panel_timeline->transition_tool_type == kTransitionOpening) ? - kTransitionClosing : kTransitionOpening; + if (open != nullptr) { + open->undeletable = false; + } + if (close != nullptr) { + close->undeletable = false; + } - make_room_for_transition( - ca, - post, - opposite_type, - transition_start, - transition_end, - true - ); - if (panel_timeline->transition_tool_type == kTransitionClosing) { - // swap - ClipPtr temp = pre; - pre = post; - post = temp; + if (open != nullptr) { + make_room_for_transition(ca, open, kTransitionOpening, transition_start, transition_end, true); + + if (transition_start < open->timeline_in || transition_end > open->timeline_out) { +// long effective_out = (close != nullptr) ? close->timeline_out : open->timeline_out; + long new_in = qMin(transition_start, open->timeline_in); + long new_out = qMax(transition_end, open->timeline_out); + + move_clip(ca, + open, + new_in, + new_out, + open->clip_in - (open->timeline_in - new_in), + open->track); } } - if (transition_start < post->timeline_in || transition_end > pre->timeline_out) { - // if the user extended the transition beyond the clip's boundaries, delete the content there and extend - // the clip to fill these new boundaries + if (close != nullptr) { + make_room_for_transition(ca, close, kTransitionClosing, transition_start, transition_end, true); - QVector areas; - Selection s; - s.track = post->track; + if (transition_start < close->timeline_in || transition_end > close->timeline_out) { +// long effective_in = (open != nullptr) ? open->timeline_in : close->timeline_in; + long new_in = qMin(transition_start, close->timeline_in); + long new_out = qMax(transition_end, close->timeline_out); - bool move_post = false; - bool move_pre = false; - - if (transition_start < post->timeline_in) { - s.in = transition_start; - s.out = post->timeline_in; - areas.append(s); - move_post = true; + move_clip(ca, + close, + new_in, + new_out, + close->clip_in - (close->timeline_in - new_in), + close->track); } - if (transition_end > pre->timeline_out) { - s.in = pre->timeline_out; - s.out = transition_end; - areas.append(s); - move_pre = true; - } - - panel_timeline->delete_areas_and_relink(ca, areas, false); - - if (move_post) move_clip(ca, post, qMin(transition_start, post->timeline_in), post->timeline_out, post->clip_in - (post->timeline_in - transition_start), post->track); - if (move_pre) move_clip(ca, pre, pre->timeline_in, qMax(transition_end, pre->timeline_out), pre->clip_in, pre->track); } - if (panel_timeline->transition_tool_post_clip > -1) { - ca->append(new AddTransitionCommand(pre, post, nullptr, panel_timeline->transition_tool_meta, kTransitionOpening, transition_end - pre->timeline_in)); - } else { - ca->append(new AddTransitionCommand(pre, nullptr, nullptr, panel_timeline->transition_tool_meta, panel_timeline->transition_tool_type, transition_end - transition_start)); + long transition_length = transition_end - transition_start; + if (shared_transition) { + transition_length /= 2; } + ca->append(new AddTransitionCommand(open, + close, + nullptr, + panel_timeline->transition_tool_meta, + transition_length)); + push_undo = true; } } else if (panel_timeline->splitting) { @@ -1573,13 +1584,14 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { } } } else if (effective_tool == TIMELINE_TOOL_TRANSITION) { - if (panel_timeline->transition_tool_post_clip == -1) { - validate_transitions(c, panel_timeline->transition_tool_type, frame_diff); + if (panel_timeline->transition_tool_open_clip == -1 + || panel_timeline->transition_tool_close_clip == -1) { + validate_transitions(c, g.media_stream, frame_diff); } else { - ClipPtr otc = c; // open transition clip - ClipPtr ctc = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_post_clip); // close transition clip + ClipPtr otc = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_open_clip); // open transition clip + ClipPtr ctc = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_close_clip); // close transition clip - if (panel_timeline->transition_tool_type == kTransitionClosing) { + if (g.media_stream == kTransitionClosing) { // swap ClipPtr temp = otc; otc = ctc; @@ -1658,10 +1670,11 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { g.track += track_diff; } } else if (effective_tool == TIMELINE_TOOL_TRANSITION) { - if (panel_timeline->transition_tool_post_clip > -1) { + if (panel_timeline->transition_tool_open_clip > -1 + && panel_timeline->transition_tool_close_clip > -1) { g.in = g.old_in - frame_diff; g.out = g.old_out + frame_diff; - } else if (panel_timeline->transition_tool_type == kTransitionOpening) { + } else if (panel_timeline->transition_tool_open_clip == g.clip) { g.out = g.old_out + frame_diff; } else { g.in = g.old_in + frame_diff; @@ -2441,22 +2454,30 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } else { // transition tool is being used but ghosts haven't been set up yet, set them up now - ClipPtr c = olive::ActiveSequence->clips.at(panel_timeline->transition_tool_pre_clip); + int primary_type = kTransitionOpening; + int primary = panel_timeline->transition_tool_open_clip; + if (primary == -1) { + primary_type = kTransitionClosing; + primary = panel_timeline->transition_tool_close_clip; + } + + ClipPtr c = olive::ActiveSequence->clips.at(primary); Ghost g; - g.in = g.old_in = g.out = g.old_out = (panel_timeline->transition_tool_type == kTransitionOpening) ? + g.in = g.old_in = g.out = g.old_out = (primary_type == kTransitionOpening) ? c->timeline_in : c->timeline_out; g.track = c->track; - g.clip = panel_timeline->transition_tool_pre_clip; - g.media_stream = panel_timeline->transition_tool_type; + g.clip = primary; + g.media_stream = primary_type; g.trim_type = TRIM_NONE; panel_timeline->ghosts.append(g); panel_timeline->transition_tool_proc = true; + } } else { @@ -2467,8 +2488,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { int mouse_clip = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); // set default transition tool references to no clip - panel_timeline->transition_tool_pre_clip = -1; - panel_timeline->transition_tool_post_clip = -1; + panel_timeline->transition_tool_open_clip = -1; + panel_timeline->transition_tool_close_clip = -1; if (mouse_clip > -1) { @@ -2479,35 +2500,28 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // check if the clip and transition are both the same sign (meaning video/audio are the same) if (same_sign(c->track, panel_timeline->transition_tool_side)) { - // set "pre" clip to the hovered clip - panel_timeline->transition_tool_pre_clip = mouse_clip; - - // set whether the transition is opening or closing based on whether the cursor is on the left half - // or right half of the clip - if (panel_timeline->cursor_frame > (c->timeline_in + (c->getLength()/2))) { - panel_timeline->transition_tool_type = kTransitionClosing; - } else { - panel_timeline->transition_tool_type = kTransitionOpening; - } - // the range within which the transition tool will assume the user wants to make a shared transition // between two clips rather than just one transition on one clip long between_range = getFrameFromScreenPoint(panel_timeline->zoom, TRANSITION_BETWEEN_RANGE) + 1; - // if the cursor is within this range, set the post_clip to be the next clip touching - // - // getClipIndexFromCoords() will automatically set to -1 if there's no clip there which means the - // end result will be the same as not setting a clip here at all - if (panel_timeline->cursor_frame < c->timeline_in + between_range) { + // set whether the transition is opening or closing based on whether the cursor is on the left half + // or right half of the clip + if (panel_timeline->cursor_frame > (c->timeline_in + (c->getLength()/2))) { + panel_timeline->transition_tool_close_clip = mouse_clip; - // get clip touching to the left - panel_timeline->transition_tool_post_clip = getClipIndexFromCoords(c->timeline_in-1, c->track); - - } else if (panel_timeline->cursor_frame > c->timeline_out - between_range) { - - // get clip touching to the right - panel_timeline->transition_tool_post_clip = getClipIndexFromCoords(c->timeline_out+1, c->track); + // if the cursor is within this range, set the post_clip to be the next clip touching + // + // getClipIndexFromCoords() will automatically set to -1 if there's no clip there which means the + // end result will be the same as not setting a clip here at all + if (panel_timeline->cursor_frame > c->timeline_out - between_range) { + panel_timeline->transition_tool_open_clip = getClipIndexFromCoords(c->timeline_out+1, c->track); + } + } else { + panel_timeline->transition_tool_open_clip = mouse_clip; + if (panel_timeline->cursor_frame < c->timeline_in + between_range) { + panel_timeline->transition_tool_close_clip = getClipIndexFromCoords(c->timeline_in-1, c->track); + } } } @@ -2858,27 +2872,33 @@ void TimelineWidget::paintEvent(QPaintEvent*) { if (clip_rect.bottom() >= 0 && clip_rect.bottom() < height()) p.drawLine(QPoint(qMax(0, clip_rect.left()), clip_rect.bottom()), QPoint(qMin(width(), clip_rect.right()), clip_rect.bottom())); // draw transition tool - if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION && (panel_timeline->transition_tool_pre_clip == i || panel_timeline->transition_tool_post_clip == i)) { - int type = panel_timeline->transition_tool_type; - if (panel_timeline->transition_tool_post_clip == i) { - // invert transition type - type = (type == kTransitionClosing) ? kTransitionOpening : kTransitionClosing; - } + if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION) { + + bool shared_transition = (panel_timeline->transition_tool_open_clip > -1 + && panel_timeline->transition_tool_close_clip > -1); + QRect transition_tool_rect = clip_rect; - if (type == kTransitionClosing) { - if (panel_timeline->transition_tool_post_clip > -1) { - transition_tool_rect.setLeft(transition_tool_rect.right() - TRANSITION_BETWEEN_RANGE); - } else { - transition_tool_rect.setLeft(transition_tool_rect.left() + (3*(transition_tool_rect.width()>>2))); - } - } else { - if (panel_timeline->transition_tool_post_clip > -1) { + bool draw_transition_tool_rect = false; + + if (panel_timeline->transition_tool_open_clip == i) { + if (shared_transition) { transition_tool_rect.setWidth(TRANSITION_BETWEEN_RANGE); } else { transition_tool_rect.setWidth(transition_tool_rect.width()>>2); } + draw_transition_tool_rect = true; + } else if (panel_timeline->transition_tool_close_clip == i) { + if (shared_transition) { + transition_tool_rect.setLeft(transition_tool_rect.right() - TRANSITION_BETWEEN_RANGE); + } else { + transition_tool_rect.setLeft(transition_tool_rect.left() + (3*(transition_tool_rect.width()>>2))); + } + draw_transition_tool_rect = true; } - if (transition_tool_rect.left() < width() && transition_tool_rect.right() > 0) { + + if (draw_transition_tool_rect + && transition_tool_rect.left() < width() + && transition_tool_rect.right() > 0) { if (transition_tool_rect.left() < 0) { transition_tool_rect.setLeft(0); } From 69272a808640875cd876c6a2b9086fe24fc8232b Mon Sep 17 00:00:00 2001 From: Alexandre Prokoudine Date: Mon, 18 Feb 2019 16:50:10 +0300 Subject: [PATCH 17/30] Mark user-visible message for translation --- dialogs/exportdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dialogs/exportdialog.cpp b/dialogs/exportdialog.cpp index 7328e4b23..677306e08 100644 --- a/dialogs/exportdialog.cpp +++ b/dialogs/exportdialog.cpp @@ -694,7 +694,7 @@ void ExportDialog::setup_ui() { verticalLayout->addWidget(videoGroupbox); audioGroupbox = new QGroupBox(this); - audioGroupbox->setTitle("Audio"); + audioGroupbox->setTitle(tr("Audio")); audioGroupbox->setCheckable(true); QGridLayout* audioGridLayout = new QGridLayout(audioGroupbox); From e3f79a44dc15a04365b9d4d305d33163b3dcd207 Mon Sep 17 00:00:00 2001 From: Alexandre Prokoudine Date: Mon, 18 Feb 2019 16:55:12 +0300 Subject: [PATCH 18/30] Update Russian translation --- ts/olive_ru.ts | 1701 +++++++++++++++++++++++------------------------- 1 file changed, 829 insertions(+), 872 deletions(-) diff --git a/ts/olive_ru.ts b/ts/olive_ru.ts index e3b8ad0be..24144e6a7 100644 --- a/ts/olive_ru.ts +++ b/ts/olive_ru.ts @@ -4,12 +4,12 @@ AboutDialog - + Olive is a non-linear video editor. This software is free and protected by the GNU GPL. Olive — нелинейный видеоредактор. Эта программа является свободной и защищена GNU GPL. - + Olive Team is obliged to inform users that Olive source code is available for download from its website. Исходный код Olive доступен для скачивания на сайте программы. @@ -17,7 +17,7 @@ ActionSearch - + Search for action... Найти действие… @@ -25,12 +25,12 @@ AdvancedVideoDialog - + Advanced Video Settings Дополнительные параметры видео - + Pixel Format: Формат пикселей: @@ -38,25 +38,25 @@ Audio - - Audio - Звук + + %1 Audio + - - Recording - Запись + + Recording %1 + Запись %1 AudioNoiseEffect - + Amount Количество - + Mix Смешивание @@ -64,17 +64,17 @@ ChannelLayoutName - + Invalid Некорректный - + Mono Моно - + Stereo Стерео @@ -82,7 +82,7 @@ CollapsibleWidget - + <untitled> <без названия> @@ -90,7 +90,7 @@ ColorButton - + Set Color Установить цвет @@ -98,27 +98,27 @@ CornerPinEffect - + Top Left Вверху слева - + Top Right Вверху справа - + Bottom Left Внизу слева - + Bottom Right Внизу справа - + Perspective Перспектива @@ -126,7 +126,7 @@ DebugDialog - + Debug Log Журнал отладки @@ -134,23 +134,23 @@ DemoNotice - - + + Welcome to Olive! Приветствуем в Olive! - + Olive is a free open-source video editor released under the GNU GPL. If you have paid for this software, you have been scammed. Это свободный нелинейный видеоредактор с открытым исходным кодом под лицензией GNU GPL. Если вы заплатили за эту программу, скорее всего вас обманули. - + This software is currently in ALPHA which means it is unstable and very likely to crash, have bugs, and have missing features. We offer no warranty so use at your own risk. Please report any bugs or feature requests at %1 На текущий момент программа находится на стадии альфы, т.е. она нестабильна, может часто падать и не иметь нужных вам функций. Мы не даём никаких гарантий, используйте на свой страх и риск. Сообщения об ошибках и запросы на новые функции мы принимаем здесь: %1 - + Thank you for trying Olive and we hope you enjoy it! Спасибо за интерес к Olive. Надеемся, что программа вам понравится! @@ -158,89 +158,89 @@ Effect - + Invalid effect Некорректный эффект - + No candidate for effect '%1'. This effect may be corrupt. Try reinstalling it or Olive. - + Cu&t В&ырезать - + &Copy &Скопировать - + Move &Up &Поднять - + Move &Down &Опустить - + D&elete &Удалить - + Load Settings From File Загрузить параметры из файла - + Save Settings to File Сохранить параметры в файл - + Save Effect Settings Сохранить параметры эффекта - - + + Effect XML Settings %1 Файлы с параметрами эффектов %1 - + Save Settings Failed Не удалось сохранить параметры - + Failed to open "%1" for writing. Не удалось открыть "%1" для записи. - + Load Effect Settings Загрузить параметры эффекта - - + + Load Settings Failed Не удалось загрузить параметры - + Failed to open "%1" for reading. Не удалось открыть "%1" для чтения. - + This settings file doesn't match this effect. Это файлс параметрами совсем другого эффекта. @@ -248,47 +248,47 @@ EffectControls - + Effects: Эффекты: - + &Paste &Вставить - + Add Video Effect Добавить видеоэффект - + VIDEO EFFECTS ВИДЕОЭФФЕКТЫ - + Add Video Transition Добавить видеопереход - + Add Audio Effect Добавить аудиоэффект - + AUDIO EFFECTS АУДИОЭФФЕКТЫ - + Add Audio Transition Добавить аудиопереход - + (Multiple clips selected) (Выделено больше одного клипа) @@ -296,12 +296,12 @@ EffectRow - + Disable Keyframes Отключить ключевые кадры - + Disabling keyframes will delete all current keyframes. Are you sure you want to do this? Отключение приведёт к удалению всех текущих ключевых кадров. Вы уверены? @@ -309,7 +309,7 @@ EmbeddedFileChooser - + File: Файл: @@ -317,98 +317,98 @@ ExportDialog - + Export "%1" Экспортировать "%1" - + Unknown codec name %1 - + Export Failed Не удалось экспортировать - + Export failed - %1 Не удалось экспортировать — %1 - + Invalid dimensions Некорректный размер кадра - + Export width and height must both be even numbers/divisible by 2. Ширина и высота кадра при экспорте должны делиться на 2 без остатка. - + Invalid codec Некорректный кодек - + Couldn't determine output parameters for the selected codec. This is a bug, please contact the developers. - + Invalid format Некорректный формат - + Couldn't determine output format. This is a bug, please contact the developers. - + Export Media Экспортировать проект - + Quality-based (Constant Rate Factor) Качество (Constant Rate Factor) - + Constant Bitrate Постоянная скорость потока - - + + Invalid Codec Некорректный кодек - + Failed to find a suitable encoder for this codec. Export will likely fail. Не удалось найти подходящий кодировщик для этого кодека. Экспорт не гарантирован. - + Failed to find pixel format for this encoder. Export will likely fail. - + Bitrate (Mbps): Скорость потока (Мбит/с): - + Quality (CRF): Качество (CRF): - + Quality Factor: 0 = lossless @@ -423,73 +423,78 @@ 51 = самое низкое качество - + Target File Size (MB): Конечный размер файла (Мб): - + Format: Формат: - + Range: Диапазон: - + Entire Sequence Вся последовательность - + In to Out От входа от выхода - + Video Видео - - + + Codec: Кодек: - + Width: Ширина: - + Height: Высота: - + Frame Rate: Частота кадров: - + Compression Type: Тип сжатия: - + Advanced Дополнительно - + + Audio + Звук + + + Sampling Rate: Частота дискретизации: - + Bitrate (Kbps/CBR): Скорость потока (Кбит/с / CBR): @@ -497,87 +502,87 @@ ExportThread - + failed to send frame to encoder (%1) - + failed to receive packet from encoder (%1) - + could not video encoder for %1 - + could not allocate video stream - + could not allocate video encoding context - + could not open output video encoder (%1) - + could not copy video encoder parameters to output stream (%1) - + could not audio encoder for %1 - + could not allocate audio stream - + could not allocate audio encoding context - + could not open output audio encoder (%1) - + could not copy audio encoder parameters to output stream (%1) - + could not allocate audio buffer (%1) - + could not create output format context - + could not open output file (%1) - + could not write output file header (%1) - + could not write output file trailer (%1) @@ -585,40 +590,40 @@ FillLeftRightEffect - + Type Тип - + Fill Left with Right - + Заполнить левый канал правым - + Fill Right with Left - + Заполнить правый канал левым Frei0rEffect - + Failed to load Frei0r plugin "%1": %2 Не удалось загрузить плагшин Frei0r "%1": %2 - + NOTE: You can't load 32-bit Frei0r plugins into a 64-bit build of Olive. Please find a 64-bit version of this plugin or switch to a 32-bit build of Olive. Вы не можете загружать 32-разрядные плагины Frei0r в 64-разрядный Olive. Найдите 64-разрядную версию этого плагина или установите 32-разрядную сборку Olive. - + NOTE: You can't load 64-bit Frei0r plugins into a 32-bit build of Olive. Please find a 32-bit version of this plugin or switch to a 64-bit build of Olive. Вы не можете загружать 64-разрядные плагины Frei0r в 32-разрядный Olive. Найдите 32-разрядную версию этого плагина или установите 64-разрядную сборку Olive. - + Error loading Frei0r plugin Ошибка при загрузке плагина Frei0r @@ -626,22 +631,22 @@ GraphEditor - + Graph Editor Редактор графов - + Linear Линейный - + Bezier Безье - + Hold Константа @@ -649,17 +654,17 @@ GraphView - + Zoom to Selection Масштабировать в выделение - + Zoom to Show All Масштабировать и показать всё - + Reset View Сбросить масштаб @@ -667,30 +672,30 @@ InterlacingName - + None (Progressive) - Нет (прогрессивно) + Нет (прогрессивно) - + Top Field First - + Bottom Field First - + Invalid - Некорректный + Некорректно KeyframeNavigator - + Enable Keyframes Включить ключевые кадры @@ -698,17 +703,17 @@ KeyframeView - + Linear Линейный - + Bezier Безье - + Hold Константа @@ -716,14 +721,14 @@ LabelSlider - - + + Set Value Установить значение - - + + New value: Новое значение: @@ -731,17 +736,17 @@ LoadDialog - + Loading... Загрузка… - + Loading '%1'... Загружается '%1'... - + Cancel Отмена @@ -749,52 +754,52 @@ LoadThread - + Version Mismatch Несовпадение версий - + This project was saved in a different version of Olive and may not be fully compatible with this version. Would you like to attempt loading it anyway? Этот проект был сохранён в другой версии Olive, которая неполностью совместима с установленной у вас. Всё-таки попробовать загрузить? - + Invalid Clip Link Некорректная связь клипов - + This project contains an invalid clip link. It may be corrupt. Would you like to continue loading it? В проекте обнаружена некорректная связь клипов. Всё-таки попробовать загрузить её? - + %1 - Line: %2 Col: %3 - + User aborted loading Пользователь прервал загрузку - + XML Parsing Error Ошибка разбора XML - + Couldn't load '%1'. %2 Не удалось загрузить '%1'. %2 - + Project Load Error Ошибка при загрузке проекта - + Error loading project: %1 Ошибка при загрузке проекта: %1 @@ -802,711 +807,520 @@ MainWindow - + Welcome to %1 Приветствуем в %1 - - Auto-recovery - Автовосстановление - - - - Olive didn't close properly and an autorecovery file was detected. Would you like to open it? - Olive аварийно завершил работу, обнаружен файл автовосстановления. Открыть его? - - - - &Project - &Проект - - - - &Sequence - П&оследовательность - - - - &Folder - П&апка - - - - Set In Point - Установить точку входа - - - - Set Out Point - Установить точку выхода - - - Enable/Disable In/Out Point - Переключить точку входа/выхода - - - - Reset In Point - Сбросить точку входа - - - - Reset Out Point - Сбросить точку выхода - - - - Clear In/Out Point - Очистить точку входа/выхода - - - - No active sequence - Нет активных последовательностей - - - - Please open the sequence you wish to export. - Откройте последовательность, которую хотите экспортировать - - - - Save Project As... - Сохранить проект как… - - - - Unsaved Project - Несохранённый проект - - - - This project has changed since it was last saved. Would you like to save it before closing? - Проект был изменён с момента последнего сохранения. Хотите сохранить его перед закрытием? - - - + &File &Файл - + &New &Создать - + &Open Project &Открыть проект - + Clear Recent List Очистить список - + Open Recent Открыть недавний - + &Save Project Со&хранить проект - + Save Project &As Сохранить проект &как - + &Import... &Импортировать… - + &Export... &Экспортировать…. - + E&xit В&ыход - + &Edit &Правка - + &Undo &Отменить - + Redo Вернуть - - Cu&t - В&ырезать - - - - Cop&y - С&копировать - - - - &Paste - &Вставить - - - - Paste Insert - - - - - Duplicate - Сделать копию - - - - Delete - Удалить - - - - Ripple Delete - Удалить со сдвигом - - - - Split - Разделить - - - + Select &All Выд&елить всё - + Deselect All Снять выделение - - Add Default Transition - Добавить переход по умолчанию - - - - Link/Unlink - Связать/Убрать связь - - - - Enable/Disable - Включить/Отключить - - - - Nest - Вложить - - - + Ripple to In Point Сдвиг до точки входа - + Ripple to Out Point Сдвиг до точки выхода - + Edit to In Point Правка до точки входа - + Edit to Out Point Правка до точки выхода - + Delete In/Out Point Удалить точку входа/выхода - + Ripple Delete In/Out Point Удалить со сдвигом точку входа/выхода - + Set/Edit Marker Установить/Изменить маркер - + &View &Вид - + Zoom In Приблизить - + Zoom Out Отдалить - + Increase Track Height Увеличить высоту дорожки - + Decrease Track Height Уменьшить высоту дорожки - + Toggle Show All Показывать весь проект - + Track Lines Линии дорожек - + Rectified Waveforms Волновая форма от низа - + Frames Кадры - + Drop Frame С пропуском кадров - + Non-Drop Frame Без пропуска кадров - + Milliseconds Миллисекунды - + Title/Action Safe Area Безопасная область - + Off Выкл. - + Default По умолчанию - + 4:3 4:3 - + 16:9 16:9 - + Custom Другая - + Full Screen Полноэкранный режим - + Full Screen Viewer - Монитор в полноэкранном режиме + Просмотр в полноэкранном режиме - + &Playback Вос&произведение - + Go to Start К началу - + Previous Frame К предыдущему кадру - + Play/Pause Воспроизведение/Пауза - + Play In to Out Проиграть от входа до выхода - + Next Frame К следующему кадру - + Go to End В конец - + Go to Previous Cut - + Go to Next Cut - + Go to In Point К точке входа - + Go to Out Point К точке выхода - + Shuttle Left Уменьшить скорость - + Shuttle Stop Пауза - + Shuttle Right Увеличить скорость - Decrease Speed - Уменьшить скорость - - - Pause - Пауза - - - Increase Speed - Увеличить скорость - - - + Loop Петля - + &Window &Окно - + Project Проект - + Effect Controls Управление эффектами - + Timeline - Таймлайн + Монтажный стол - + Graph Editor Редактор графов - + Media Viewer - Монитор проекта + Просмотр проекта - + Sequence Viewer - Монитор последовательностей + Просмотр последовательностей - + Maximize Panel Развернуть панель - + Reset to Default Layout Вернуть исходный вид панелей - + &Tools &Инструменты - + Pointer Tool Указатель - + Edit Tool Выделение - + Ripple Tool Монтаж со сдвигом - + Razor Tool Подрезка - + Slip Tool Прокрутка с совмещением - + Slide Tool Прокрутка - + Hand Tool Навигация - + Transition Tool Переход - + Enable Snapping Включить прилипание - + Selecting Also Seeks Выделение с перемоткой - + Edit Tool Also Seeks Выделение с перемоткой - + Edit Tool Selects Links Выделение выбирает связи - + Seek Also Selects Перемотка с выделением - + Seek to the End of Pastes Перемотка до конца вставок - + Scroll Wheel Zooms - Колесо мыши масштабирует таймлайн + Колесо мыши масштабирует монтажный стол - + Enable Drag Files to Timeline - Разрешить перетаскивание на таймлайн извне + Разрешить перетаскивание на монтажный стол извне - + Auto-Scale By Default Автоматически масштабировать по умолчанию - + Enable Seek to Import - + Audio Scrubbing Воспроизводить звук при прокрутке - + Enable Drop on Media to Replace - + Enable Hover Focus Включить фокус наводкой - + Ask For Name When Setting Marker Спрашивать имя маркера при добавлении - + No Auto-Scroll Без автопрокрутки - + Page Auto-Scroll Прокручивать перелистыванием - + Smooth Auto-Scroll Прокручивать плавно - + Preferences Параметры - + Clear Undo Очистить историю изменений - + &Help &Справка - + A&ction Search &Найти команду - + Debug Log Журнал отладки - + &About... &О программе… - + <untitled> <без названия> - - - Open Project... - Открыть проект… - - - - Missing recent project - Отсутствует недавний проект - - - - The project '%1' no longer exists. Would you like to remove it from the recent projects list? - Проект '%1' больше не существует. Удалить его из списка недавних? - - - - Invalid aspect ratio - Некорректное соотношение сторон - - - - The aspect ratio '%1' is invalid. Please try again. - - - - - Enter custom aspect ratio - Введите другое соотношение сторон - - - - Enter the aspect ratio to use for the title/action safe area (e.g. 16:9): - - - - - Nested Sequence - Вложенная последовательность - Marker - + Set Marker Установить маркер - + Set clip marker name: Название маркера клипа: - + Set sequence marker name: Название маркера последовательности: @@ -1514,56 +1328,52 @@ Media - + New Folder Новая папка - + Name: Название: - + Filename: Имя файла: - + Video Dimensions: Размер кадров: - + Frame Rate: Частота кадров: - %1 fields (%2 frames) - полей: %1 (кадров: %2) - - - + %1 field(s) (%2 frame(s)) полей: %1 (кадров: %2) - + Interlacing: Чересстрочность: - + Audio Frequency: Частота звука: - + Audio Channels: Звуковых каналов: - + Name: %1 Video Dimensions: %2x%3 Frame Rate: %4 @@ -1576,17 +1386,17 @@ Audio Layout: %6 Звуковые каналы: %6 - + Name Название - + Duration Длительность - + Rate Частота @@ -1594,31 +1404,27 @@ Audio Layout: %6 MediaPropertiesDialog - + "%1" Properties Свойства "%1" - + Tracks: Дорожек: - + Video %1: %2x%3 %4FPS Видео %1: %2x%3 %4к/с - Audio %1: %2Hz %3 channels - Звук %1: %2Гц %3 каналов - - - + Audio %1: %2Hz %3 - + %n channel(s) %n канал @@ -1627,163 +1433,354 @@ Audio Layout: %6 - + Conform to Frame Rate: - + Alpha is Premultiplied - + Auto (%1) Авто (%1) - + Interlacing: Чересстрочность: - + Name: Название: + + MenuHelper + + + &Project + &Проект + + + + &Sequence + П&оследовательность + + + + &Folder + П&апка + + + + Set In Point + Установить точку входа + + + + Set Out Point + Установить точку выхода + + + + Reset In Point + Сбросить точку входа + + + + Reset Out Point + Сбросить точку выхода + + + + Clear In/Out Point + Очистить точку входа/выхода + + + + Add Default Transition + Добавить переход по умолчанию + + + + Link/Unlink + Связать/Убрать связь + + + + Enable/Disable + Включить/Отключить + + + + Nest + Вложить + + + + Cu&t + В&ырезать + + + + Cop&y + С&копировать + + + + &Paste + &Вставить + + + + Paste Insert + + + + + Duplicate + Сделать копию + + + + Delete + Удалить + + + + Ripple Delete + Удалить со сдвигом + + + + Split + Разделить + + + + Invalid aspect ratio + Некорректное соотношение сторон + + + + The aspect ratio '%1' is invalid. Please try again. + + + + + Enter custom aspect ratio + Введите другое соотношение сторон + + + + Enter the aspect ratio to use for the title/action safe area (e.g. 16:9): + + + NewSequenceDialog - + Editing "%1" Правка "%1" - + New Sequence Новая последовательность - + Preset: Предстановка: - + Film 4K Кино 4К - + TV 4K (Ultra HD/2160p) TV 4K (Ultra HD/2160p) - + 1080p 1080p - + 720p 720p - + 480p 480p - + 360p 360p - + 240p 240p - + 144p 144p - + NTSC (480i) NTSC (480i) - + PAL (576i) PAL (576i) - + Custom Другое - + Video Видео - + Width: Ширина: - + Height: Высота: - + Frame Rate: Частота кадров: - + Pixel Aspect Ratio: Соотношение сторон пикселя: - + Square Pixels (1.0) Квадратные пиксели (1.0) - + Interlacing: Чересстрочность: - + None (Progressive) Нет (прогрессивно) - + Audio Звук - + Sample Rate: Частота дискретизации: - + Name: Название: + + OliveGlobal + + + Olive Project %1 + Проект Olive %1 + + + + Auto-recovery + Автовосстановление + + + + Olive didn't close properly and an autorecovery file was detected. Would you like to open it? + Olive аварийно завершил работу, обнаружен файл автовосстановления. Открыть его? + + + + Open Project... + Открыть проект… + + + + Missing recent project + Отсутствует недавний проект + + + + The project '%1' no longer exists. Would you like to remove it from the recent projects list? + Проект '%1' больше не существует. Удалить его из списка недавних? + + + + Save Project As... + Сохранить проект как… + + + + Unsaved Project + Несохранённый проект + + + + This project has changed since it was last saved. Would you like to save it before closing? + Проект был изменён с момента последнего сохранения. Хотите сохранить его перед закрытием? + + + + No active sequence + Нет активных последовательностей + + + + Please open the sequence you wish to export. + Откройте последовательность, которую хотите экспортировать + + + + Missing Project File + Отсутствует проектный файл + + + + Specified project '%1' does not exist. + Указанный проект '%1' не существует. + + PanEffect - + Pan Панорама @@ -1791,7 +1788,7 @@ Audio Layout: %6 Playback - + Generating Proxy: %1% Создаётся прокси: %1% @@ -1799,289 +1796,275 @@ Audio Layout: %6 PreferencesDialog - + Preferences Параметры - + Invalid CSS File Некорректный файл CSS - + CSS file '%1' does not exist. Файл CSS '%1' не существует. - - Warning - Предупреждение - - - - Some changed settings will require restarting Olive to take effect - Некоторые изменения параметров вступят в силу только при следующем запуске Olive - - - + Confirm Reset All Shortcuts Подтвердите действие - + Are you sure you wish to reset all keyboard shortcuts to their defaults? Вы действительно хотите сбросить все клавиатурные комбинации к исходным значениям? - + Import Keyboard Shortcuts Импортировать клавиатурные комбинации - - + + Error saving shortcuts Ошибка при сохранении клавиатурных комбинаций - + Failed to open file for reading Не удалось открыть файл для чтения - + Export Keyboard Shortcuts Экспортировать клавиатурные комбинации - + Export Shortcuts Экспортировать клавиатурные комбинации - + Shortcuts exported successfully Комбинации успешно экспортированы - + Failed to open file for writing Не удалось открыть файл для записи - + Browse for CSS file Указать файл CSS - + Delete All Previews Удалить все миниатюры - + Are you sure you want to delete all previews? Действительно удалить все миниатюры? - + Previews Deleted Миниатюры удалены - + All previews deleted succesfully. You may have to re-open your current project for changes to take effect. Все миниатюры успешно удалены. Возможно, понадобится заново открыть проект, чтобы изменения вступили в силу. - + Language: Язык: - + Custom CSS: Свой CSS: - + Browse Просмотр - + Image sequence formats: Форматы изображений: - + Audio Recording: Запись звука: - + Mono Моно - + Stereo Стерео - + Effect Textbox Lines: Строк в редакторе титров: - + Thumbnail Resolution: Разрешение миниатюр: - + Waveform Resolution: Разрешение волновой формы: - + Delete Previews Удалить миниатюры - + Use Software Fallbacks When Possible По возможности использовать программную реализацию вместо аппаратной - + General Общие - + Behavior Поведение - Disable Multithreading on Images - Отключить многопоточность для изображений - - - + Seeking Позиционирование - + Accurate Seeking Always show the correct frame (visual may pause briefly as correct frame is retrieved) Точное позиционирование Всегда показывать правильный кадр; на его получение может уходить немного времени - + Fast Seeking Seek quickly (may briefly show inaccurate frames when seeking - doesn't affect playback/export) Быстрое позиционирование -Переходы без пауз, возможен кратковременный показ неправильного кадра в мониторе +Переходы без пауз, возможен кратковременный показ неправильного кадра в просмотре - + Memory Usage Использование памяти - + Upcoming Frame Queue: Очередь последующих кадров: - - + + frames кадров - - + + seconds секунд - + Previous Frame Queue: Очередь предыдущих кадров: - + Playback Воспроизведение - + Output Device: Устройство выхода: - - + + Default По умолчанию - + Input Device: Устройство входа: - + Sample Rate: Частота дискретизации: - + Audio Звук - + Search for action or shortcut Искать действие или комбинацию клавиш - + Action Действие - + Shortcut Комбинация - + Import Импортировать - + Export Экспортировать - + Reset Selected Сбросить выбранное - + Reset All Сбросить все - + Keyboard Клавиатурные комбинации @@ -2089,12 +2072,12 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff PreviewGenerator - + Could not open file - %1 Не удалось открыть файл — %1 - + Could not find stream information - %1 Не удалось найти информацию потока — %1 @@ -2102,94 +2085,94 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Project - + Search media, markers, etc. Искать файлы, маркеры и т.д. - + Project Проект - + Sequence Последовательность - + Replace '%1' Заменить '%1' - - + + All Files Все файлы - - + + No active sequence Нет активных последовательностей - + No sequence is active, please open the sequence you want to replace clips from. Нет активных последовательностей. Откройте последовательность, в которой хотите заменить клипы. - + Active sequence selected Выбрана активная последовательность - + You cannot insert a sequence into itself, so no clips of this media would be in this sequence. Вы не можете вставить последовательность в саму себя, так что клипы из этих файлов не могут попасть в эту последовательность. - + Rename '%1' Переименовать '%1' - + Enter new name: Введите новое название: - + Delete media in use? Удалить используемые в проекте файлы? - + The media '%1' is currently used in '%2'. Deleting it will remove all instances in the sequence. Are you sure you want to do this? Файл '%1' уже используется в '%2'. Его удаление приведет к удалению всех его копий в выбранной последовательности. Вы точно этого хотите? - + Skip Пропустить - + Image sequence detected Обнаружена последовательность изображений - + The file '%1' appears to be part of an image sequence. Would you like to import it as such? Похоже, что файл '%1' яавляется частью последовательности изображений. Загрузить его как таковой? - + Import media... Импортировать медиафайлы… - + No sequence is active, please open the sequence you want to delete clips from. Нет активных последовательностей. Откройте последовательность, из которой хотите удалить клипы. @@ -2197,77 +2180,77 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff ProxyDialog - + Create Proxy Создать прокси - + Proxy Прокси - + Dimensions: Размер: - + Same Size as Source В размере оригинала - + Half Resolution (1/2) Половина оригинала (1/2) - + Quarter Resolution (1/4) Четверть оригинала (1/4) - + Eighth Resolution (1/8) Восьмая оригинала (1/8) - + Sixteenth Resolution (1/16) Шестнадцатая оригинала (1/16) - + Format: Формат: - + ProRes HQ ProRes HQ - + Location: Размещение: - + Same as Source (in "%1" folder) Как в исходнике (в папке «%1») - + Proxy file exists Прокси-файл уже существует - + The file "%1" already exists. Do you wish to replace it? Файл «%1» уже существует. Заменить его? - + Custom Location Другое размещение @@ -2275,7 +2258,7 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff ProxyGenerator - + Finished generating proxy for "%1" Завершено создание прокси для "%1" @@ -2283,67 +2266,67 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff ReplaceClipMediaDialog - + Replace clips using "%1" Заменить клипы данными "%1" - + Select which media you want to replace this media's clips with: Выберите файлы, которые хотите заменить клипы с этими файлами: - + Keep the same media in-points Сохранить существующие точки входа - + Replace Заменить - + Cancel Отмена - + No media selected Файлы не выбраны - + Please select a media to replace with or click 'Cancel'. - Выборите файлы для замены или нажмите кнопку «Отмена». + Выберите файлы для замены или нажмите кнопку «Отмена». - + Same media selected Выбраны те же самые файлы - + You selected the same media that you're replacing. Please select a different one or click 'Cancel'. Вы выбрали те же файлы, которые хотите заменить. Выберите что-то другое или нажмите кнопку «Отмена». - + Folder selected Папка выбрана - + You cannot replace footage with a folder. Вы не можете заменить видеосъёмку папкой. - + Active sequence selected Выбрана активная последовательность - + You cannot insert a sequence into itself. Вы не можете вставить последовательность в саму себя. @@ -2351,7 +2334,7 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Sequence - + %1 (copy) %1 (копия) @@ -2359,17 +2342,17 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff ShakeEffect - + Intensity Интенсивность - + Rotation Вращение - + Frequency Частота @@ -2377,37 +2360,37 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff SolidEffect - + Type Тип - + Solid Color Сплошная заливка - + SMPTE Bars Таблица SMPTE - + Checkerboard Шахматная доска - + Opacity Непрозрачность - + Color Цвет - + Checkerboard Size Размер клеток @@ -2415,137 +2398,137 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff SourcesCommon - + Import... Импортировать… - + New Создать - + View Вид - + Tree View В виде таблицы - + Icon View В виде миниатюр - + Show Toolbar Показывать панель - + Show Sequences Показывать последовательности - + Replace/Relink Media Заменить/пересвязать файлы - + Reveal in Explorer Открыть в Проводнике - + Reveal in Finder Открыть в Finder - + Reveal in File Manager Открыть в файловом менеджере - + Replace Clips Using This Media Заменить клипы с этими файлами - + Create Sequence With This Media Создать последовательность с этими файлами - + Duplicate Создать копию - + Delete All Clips Using This Media Удалить все клипы с этим файлом - + Proxy Прокси - + Generating proxy: %1% complete Создание прокси: завершено на %1% - + Create/Modify Proxy Создать/Изменить прокси - + Create Proxy Создать прокси - + Modify Proxy Изменить прокси - + Restore Original Восстановить оригинал - + Delete Удалить - + Properties... Свойства… - + Replace Media Заменить файлы - + You dropped a file onto '%1'. Would you like to replace it with the dropped file? - + Delete proxy Удалить прокси - + Would you like to delete the proxy file "%1" as well? Заодно удалить прокси-файл "%1"? @@ -2553,37 +2536,37 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff SpeedDialog - + Speed/Duration Скорость/длительность - + Speed: Скорость: - + Frame Rate: Частота кадров: - + Duration: Длительность: - + Reverse Реверс - + Maintain Audio Pitch Сохранять высоту тона - + Ripple Changes Изменять со сдвигом @@ -2591,7 +2574,7 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff TextEditDialog - + Edit Text Изменить текст @@ -2599,113 +2582,113 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff TextEffect - + Text Текст - + Font Шрифт - + Size Кегль - + Color Цвет - + Alignment Выравнивание - + Left Слева - - + + Center По центру - + Right Справа - + Justify По ширине - + Top Сверху - + Bottom Снизу - + Word Wrap Перенос строки - + Outline Обводка - + Outline Color Цвет обводки - + Outline Width Толщина обводки - + Shadow Тень - + Shadow Color Цвет тени - + Shadow Distance Длина тени - + Shadow Softness Мягкость тени - + Shadow Opacity Непрозрачность тени - + Sample Text Образец текста - + &Edit Text &Изменить текст @@ -2713,47 +2696,47 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff TimecodeEffect - + Timecode Тайм-код - + Sequence Последовательность - + Media Файл - + Scale Масштаб - + Color Цвет - + Background Color Цвет фона - + Background Opacity Непрозрачность фона - + Offset Смещение - + Prepend Префикс @@ -2761,159 +2744,152 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff Timeline - + Timeline: - Таймлайн: + Монтажный стол: - + <none> <нет> - + Effect already exists Эффект уже добавлен - + Clip '%1' already contains a '%2' effect. Would you like to replace it with the pasted one or add it as a separate effect? Клип '%1' уже содержит эффект '%2'. Хотите заменить его на вставляемый эффект или добавить вставляемый эффект как отдельный? - + Add Добавить - + Replace Заменить - + Skip Пропустить - + Do this for all conflicts found Применить для всех конфликтов - Set Marker - Установить маркер + + Nested Sequence + Вложенная последовательность - Set clip marker name: - Установить название маркера клипа: - - - Set sequence marker name: - Установить название маркера последовательности: - - - + Title... Титры… - + Solid Color... Цветная заливка… - + Bars... Испытательная таблица… - + Tone... Звуковой сигнал… - + Noise... Шум… - + Unsaved Project Несохранённый проект - + You must save this project before you can record audio in it. Перед записью звука необходимо сохранить проект. - + Click on the timeline where you want to start recording (drag to limit the recording to a certain timeframe) - Щелкните на таймлайне в точке, от которой хотите начать запись звука. Перетащите курсор после щелчка, чтобы сразу задать длительность записи. + Щелкните на монтажном столе в точке, от которой хотите начать запись звука. Перетащите курсор после щелчка, чтобы сразу задать длительность записи. - + Pointer Tool Указатель - + Edit Tool Выделение - + Ripple Tool Монтаж со сдвигом - + Razor Tool Подрезка - + Slip Tool Прокрутка с совмещением - + Slide Tool Прокрутка - + Hand Tool Навигация - + Transition Tool Переход - + Snapping Прилипание - + Zoom In Приблизить - + Zoom Out Отдалить - + Record audio Записать звук - + Add title, solid, bars, etc. Добавить титры, заливку цветом, испытательную таблицу и т.д. @@ -2921,7 +2897,7 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff TimelineHeader - + Center Timecodes Центрировать тайм-код @@ -2929,77 +2905,62 @@ Seek quickly (may briefly show inaccurate frames when seeking - doesn't aff TimelineWidget - + &Undo &Отменить - + &Redo В&ернуть - + C&ut В&ырезать - + Cop&y С&копировать - + &Paste &Вставить - + R&ipple Delete Уда&лить со сдвигом - + Sequence Settings Параметры последовательности - + &Speed/Duration С&корость/Длительность - + Auto-s&cale Авто&масштабирование - - Enable/Disable - Включить/Отключить - - - - Link/Unlink - Связать/Убрать связь - - - - &Nest - Вло&жить - - - + &Reveal in Project &Показать в проекте - + R&ename Пере&именовать - + %1 Start: %2 End: %3 @@ -3010,57 +2971,57 @@ Duration: %4 Длительность: %4 - + Rename '%1' Переименовать '%1' - + Rename multiple clips Переименовать клипы - + Enter a new name for this clip: Новое название этого клипа: - + Error Ошибка - + Couldn't locate media wrapper for sequence. - + Title Титры - + Solid Color Цветная заливка - + Bars Испытательная таблица - + Tone Звуковой сигнал - + Noise Шум - + Duration: Длительность: @@ -3068,22 +3029,22 @@ Duration: %4 ToneEffect - + Type Тип - + Frequency Частота - + Amount Количество - + Mix Смешать @@ -3091,157 +3052,157 @@ Duration: %4 TransformEffect - + Position Позиция - + Scale Масштаб - + Uniform Scale Сохранять пропорции - + Rotation Вращение - + Anchor Point Точка привязки - + Opacity Непрозрачность - + Blend Mode Режим смешивания - + Normal Обычный - + Darken Замена темным - + Multiply Умножение - + Color Burn Затемнение основы - + Linear Burn Линейное затемнение - + Lighten Замена светлым - + Screen Экран - + Color Dodge Осветление основы - + Linear Dodge (Add) Линейное осветление (+) - + Overlay Перекрытие - + Soft Light Рассеянный свет - + Hard Light Направленный свет - + Vivid Light Яркий свет - + Linear Light Линейный свет - + Pin Light Точечный свет - + Hard Mix Жесткое смешение - + Difference Разница - + Exclusion Исключение - + Reflect Отражение - + Substract Вычитание - + Average Среднее - + Glow Свечение - + Negation Отрицание - + Phoenix Феникс @@ -3249,11 +3210,7 @@ Duration: %4 Transition - Length: - Длительность: - - - + Length Длительность @@ -3261,64 +3218,64 @@ Duration: %4 VSTHost - - - + + + Error loading VST plugin Ошибка при загрузке плагина VST - + Failed to create VST reference - + Failed to load VST plugin "%1": %2 - + NOTE: You can't load 32-bit VST plugins into a 64-bit build of Olive. Please find a 64-bit version of this plugin or switch to a 32-bit build of Olive. - + NOTE: You can't load 64-bit VST plugins into a 32-bit build of Olive. Please find a 32-bit version of this plugin or switch to a 64-bit build of Olive. - + Failed to locate entry point for dynamic library. - + VST Error - + Ошибка VST - + Plugin's magic number is invalid - + Plugin Плагин - + Interface Интерфейс - + Show Показать - + VST Plugin Плагин VST @@ -3326,17 +3283,17 @@ Duration: %4 Viewer - + Sequence Viewer - Монитор последовательностей + Просмотр последовательностей - + Media Viewer - Монитор проекта + Просмотр проекта - + (none) (нет) @@ -3344,57 +3301,57 @@ Duration: %4 ViewerWidget - + Save Frame as Image... Сохранить кадр как изображение… - + Show Fullscreen Полноэкранный режим - + Disable Отключить - + Screen %1: %2x%3 Экран %1: %2×%3 - + Zoom Масштаб - + Fit Уместить - + Custom Другой - + Close Media Закрыть файл - + Save Frame Сохранить кадр - + Viewer Zoom Масштаб просмотра - + Set Custom Zoom Value: Другое значение масштаба: @@ -3402,7 +3359,7 @@ Duration: %4 ViewerWindow - + Exit Fullscreen Выйти из полноэкранного режима @@ -3410,12 +3367,12 @@ Duration: %4 VoidEffect - + (unknown) (неизвестно) - + Missing Effect Отсутствующий эффект @@ -3423,7 +3380,7 @@ Duration: %4 VolumeEffect - + Volume Громкость @@ -3431,12 +3388,12 @@ Duration: %4 transition - + Invalid transition Некорректный переход - + No candidate for transition '%1'. This transition may be corrupt. Try reinstalling it or Olive. From a1619ce8ceb7ccc1fdc8a6aacc01c491b6035ef4 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Tue, 19 Feb 2019 01:16:37 -0800 Subject: [PATCH 19/30] transition rewrite mostly done --- debug.cpp | 15 +- panels/project.cpp | 9 +- panels/timeline.cpp | 92 ++- playback/cacher.cpp | 1534 ++++++++++++++++++++-------------------- playback/playback.cpp | 5 + project/clip.cpp | 9 - project/clip.h | 1 + project/undo.cpp | 62 +- project/undo.h | 2 +- ui/renderfunctions.cpp | 1090 ++++++++++++++-------------- ui/timelinewidget.cpp | 482 ++++++++++--- ui/timelinewidget.h | 2 + 12 files changed, 1792 insertions(+), 1511 deletions(-) diff --git a/debug.cpp b/debug.cpp index f949f07ac..9589ee5e4 100644 --- a/debug.cpp +++ b/debug.cpp @@ -55,31 +55,36 @@ void debug_message_handler(QtMsgType type, const QMessageLogContext &context, co QByteArray localMsg = msg.toLocal8Bit(); switch (type) { case QtDebugMsg: - fprintf(stderr, "[DEBUG] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); +// fprintf(stderr, "[DEBUG] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stderr, "[DEBUG] %s\n", localMsg.constData()); if (debug_file.isOpen()) debug_stream << QString("[DEBUG] %1 (%2:%3, %4)\n").arg(localMsg.constData(), context.file, QString::number(context.line), context.function); debug_info.append(QString("[DEBUG] %1 (%2:%3, %4)
").arg(localMsg.constData(), context.file, QString::number(context.line), context.function)); fflush(stderr); break; case QtInfoMsg: - fprintf(stderr, "[INFO] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); +// fprintf(stderr, "[INFO] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stderr, "[INFO] %s\n", localMsg.constData()); if (debug_file.isOpen()) debug_stream << QString("[INFO] %1 (%2:%3, %4)\n").arg(localMsg.constData(), context.file, QString::number(context.line), context.function); debug_info.append(QString("[INFO] %1 (%2:%3, %4)
").arg(localMsg.constData(), context.file, QString::number(context.line), context.function)); fflush(stderr); break; case QtWarningMsg: - fprintf(stderr, "[WARNING] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); +// fprintf(stderr, "[WARNING] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stderr, "[WARNING] %s\n", localMsg.constData()); if (debug_file.isOpen()) debug_stream << QString("[WARNING] %1 (%2:%3, %4)\n").arg(localMsg.constData(), context.file, QString::number(context.line), context.function); debug_info.append(QString("[WARNING] %1 (%2:%3, %4)
").arg(localMsg.constData(), context.file, QString::number(context.line), context.function)); fflush(stderr); break; case QtCriticalMsg: - fprintf(stderr, "[ERROR] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); +// fprintf(stderr, "[ERROR] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stderr, "[ERROR] %s\n", localMsg.constData()); if (debug_file.isOpen()) debug_stream << QString("[ERROR] %1 (%2:%3, %4)\n").arg(localMsg.constData(), context.file, QString::number(context.line), context.function); debug_info.append(QString("[ERROR] %1 (%2:%3, %4)
").arg(localMsg.constData(), context.file, QString::number(context.line), context.function)); fflush(stderr); break; case QtFatalMsg: - fprintf(stderr, "[FATAL] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); +// fprintf(stderr, "[FATAL] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stderr, "[FATAL] %s\n", localMsg.constData()); if (debug_file.isOpen()) debug_stream << QString("[FATAL] %1 (%2:%3, %4)\n").arg(localMsg.constData(), context.file, QString::number(context.line), context.function); debug_info.append(QString("[FATAL] %1 (%2:%3, %4)
").arg(localMsg.constData(), context.file, QString::number(context.line), context.function)); fflush(stderr); diff --git a/panels/project.cpp b/panels/project.cpp index 3f41708f0..ba6311e8c 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -1087,6 +1087,9 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, stream.writeAttribute("workareaOut", QString::number(s->workarea_out)); /* + QVector transition_save_cache; + QVector transition_clip_save_cache; + QVector transition_type_save_cache; for (int j=0;jtransitions.size();j++) { TransitionPtr t = s->transitions.at(j); if (t != nullptr) { @@ -1097,7 +1100,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, stream.writeEndElement(); // transition } } - */ + */ for (int j=0;jclips.size();j++) { const ClipPtr& c = s->clips.at(j); @@ -1110,10 +1113,6 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, stream.writeAttribute("in", QString::number(c->timeline_in)); stream.writeAttribute("out", QString::number(c->timeline_out)); stream.writeAttribute("track", QString::number(c->track)); - /* - stream.writeAttribute("opening", QString::number(c->opening_transition)); - stream.writeAttribute("closing", QString::number(c->closing_transition)); - */ stream.writeAttribute("r", QString::number(c->color_r)); stream.writeAttribute("g", QString::number(c->color_g)); diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 2ded033b8..227dd50b2 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -845,57 +845,73 @@ ClipPtr Timeline::split_clip(ComboAction* ca, bool transitions, int p, long fram ClipPtr Timeline::split_clip(ComboAction* ca, bool transitions, int p, long frame, long post_in) { ClipPtr pre = olive::ActiveSequence->clips.at(p); - if (pre != nullptr && pre->timeline_in < frame && pre->timeline_out > frame) { // guard against attempts to split at in/out points - bool splitting_closing_dual_transition = false; + if (pre != nullptr) { - if (transitions - && pre->get_closing_transition() != nullptr - && pre->get_closing_transition()->secondary_clip != nullptr) { - splitting_closing_dual_transition = true; - } + if (pre->timeline_in < frame && pre->timeline_out > frame) { + // duplicate clip without duplicating its transitions, we'll restore them later - ClipPtr post = ClipPtr(pre->copy(olive::ActiveSequence, transitions && !splitting_closing_dual_transition)); + ClipPtr post = ClipPtr(pre->copy(olive::ActiveSequence, false)); - long new_clip_length = frame - pre->timeline_in; + long new_clip_length = frame - pre->timeline_in; - post->timeline_in = post_in; - post->clip_in = pre->clip_in + (post->timeline_in - pre->timeline_in); + post->timeline_in = post_in; + post->clip_in = pre->clip_in + (post->timeline_in - pre->timeline_in); - move_clip(ca, pre, pre->timeline_in, frame, pre->clip_in, pre->track); + move_clip(ca, pre, pre->timeline_in, frame, pre->clip_in, pre->track, false); - if (pre->get_opening_transition() != nullptr) { - // if (frame < pre->timeline_in + pre->get_opening_transition()->length && pre->get_opening_transition()->secondary_clip != nullptr) { - // separate shared transition - // ca->append(new SetPointer((void**) &pre->get_opening_transition()->secondary_clip, nullptr)); - // pre->get_opening_transition()->secondary_clip->closing_transition = pre->get_opening_transition()->copy(pre->get_opening_transition()->secondary_clip, nullptr); - // } + if (transitions) { - if (pre->get_opening_transition()->get_true_length() > new_clip_length) { - ca->append(new ModifyTransitionCommand(pre->get_opening_transition(), new_clip_length)); - } - } - if (pre->get_closing_transition() != nullptr) { - if (splitting_closing_dual_transition) { - // just move closing transition to post clip + // check if this clip has a closing transition + if (pre->closing_transition != nullptr) { - // WORKAROUND - ca->append(new DeleteTransitionCommand(pre->closing_transition)); - } else { - ca->append(new DeleteTransitionCommand(pre->closing_transition)); + // if so, move closing transition to the post clip + post->closing_transition = pre->closing_transition; - if (post->get_closing_transition() != nullptr) { - if (pre->get_closing_transition()->secondary_clip == nullptr) { - post->get_closing_transition()->set_length(qMin(long(post->get_closing_transition()->get_true_length()), post->getLength())); + // and set the original clip's closing transition to nothing + ca->append(new SetPointer(reinterpret_cast(&pre->closing_transition), nullptr)); + + // and set the transition's reference to the post clip + if (post->closing_transition->parent_clip == pre) { + ca->append(new SetPointer(reinterpret_cast(&post->closing_transition->parent_clip), post.get())); + } + if (post->closing_transition->secondary_clip == pre) { + ca->append(new SetPointer(reinterpret_cast(&post->closing_transition->secondary_clip), post.get())); } - if (post->get_closing_transition()->get_length() > post->getLength()) { - post->get_closing_transition()->set_length(post->getLength()); + // and make sure it's at the correct size to the closing clip + if (post->closing_transition != nullptr && post->closing_transition->get_true_length() > post->getLength()) { + ca->append(new ModifyTransitionCommand(post->closing_transition, post->getLength())); + post->closing_transition->set_length(post->getLength()); } + + } + + // we're keeping the opening clip, so ensure that's a correct size too + if (pre->opening_transition != nullptr && pre->opening_transition->get_true_length() > new_clip_length) { + ca->append(new ModifyTransitionCommand(pre->opening_transition, new_clip_length)); } } + + return post; + + } else if (frame == pre->timeline_in + && pre->opening_transition != nullptr + && pre->opening_transition->secondary_clip != nullptr) { + // special case for shared transitions to split it into two + + // set transition to single-clip mode + ca->append(new SetPointer(reinterpret_cast(&pre->opening_transition->secondary_clip), nullptr)); + + // clone transition for other clip + ca->append(new AddTransitionCommand(nullptr, + pre->opening_transition->secondary_clip, + pre->opening_transition, + nullptr, + 0) + ); + } - return post; } return nullptr; } @@ -915,11 +931,12 @@ bool Timeline::split_clip_and_relink(ComboAction *ca, int clip, long frame, bool ClipPtr post = split_clip(ca, true, clip, frame); - // if alt is not down, split clips links too if (post == nullptr) { return false; } else { post_clips.append(post); + + // if alt is not down, split clips links too if (relink) { pre_clips.append(clip); @@ -1410,7 +1427,8 @@ bool Timeline::split_selection(ComboAction* ca) { const Selection& s = olive::ActiveSequence->selections.at(i); if (s.track == clip->track) { ClipPtr post_b = split_clip(ca, true, j, s.out); - ClipPtr post_a = split_clip(ca, post_b == nullptr, j, s.in); + ClipPtr post_a = split_clip(ca, true, j, s.in); + pre_splits.append(j); post_splits.append(post_a); secondary_post_splits.append(post_b); diff --git a/playback/cacher.cpp b/playback/cacher.cpp index 86dc423b3..f974c8788 100644 --- a/playback/cacher.cpp +++ b/playback/cacher.cpp @@ -37,15 +37,15 @@ #include "debug.h" extern "C" { - #include - #include - #include - #include - #include - #include - #include - #include - #include +#include +#include +#include +#include +#include +#include +#include +#include +#include } #include @@ -59,616 +59,616 @@ extern "C" { //int dest_format = AV_PIX_FMT_RGBA; double bytes_to_seconds(int nb_bytes, int nb_channels, int sample_rate) { - return ((double) (nb_bytes >> 1) / nb_channels / sample_rate); + return ((double) (nb_bytes >> 1) / nb_channels / sample_rate); } void apply_audio_effects(ClipPtr c, double timecode_start, AVFrame* frame, int nb_bytes, QVector nests) { - // perform all audio effects - double timecode_end; - timecode_end = timecode_start + bytes_to_seconds(nb_bytes, frame->channels, frame->sample_rate); + // perform all audio effects + double timecode_end; + timecode_end = timecode_start + bytes_to_seconds(nb_bytes, frame->channels, frame->sample_rate); - for (int j=0;jeffects.size();j++) { - EffectPtr e = c->effects.at(j); - if (e->is_enabled()) e->process_audio(timecode_start, timecode_end, frame->data[0], nb_bytes, 2); - } - if (c->get_opening_transition() != nullptr) { - if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { - double transition_start = (c->get_clip_in_with_transition() / c->sequence->frame_rate); - double transition_end = (c->get_clip_in_with_transition() + c->get_opening_transition()->get_length()) / c->sequence->frame_rate; - if (timecode_end < transition_end) { - double adjustment = transition_end - transition_start; - double adjusted_range_start = (timecode_start - transition_start) / adjustment; - double adjusted_range_end = (timecode_end - transition_start) / adjustment; - c->get_opening_transition()->process_audio(adjusted_range_start, adjusted_range_end, frame->data[0], nb_bytes, kTransitionOpening); - } - } - } - if (c->get_closing_transition() != nullptr) { - if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { - long length_with_transitions = c->get_timeline_out_with_transition() - c->get_timeline_in_with_transition(); - double transition_start = (c->get_clip_in_with_transition() + length_with_transitions - c->get_closing_transition()->get_length()) / c->sequence->frame_rate; - double transition_end = (c->get_clip_in_with_transition() + length_with_transitions) / c->sequence->frame_rate; - if (timecode_start > transition_start) { - double adjustment = transition_end - transition_start; - double adjusted_range_start = (timecode_start - transition_start) / adjustment; - double adjusted_range_end = (timecode_end - transition_start) / adjustment; - c->get_closing_transition()->process_audio(adjusted_range_start, adjusted_range_end, frame->data[0], nb_bytes, kTransitionClosing); - } - } - } + for (int j=0;jeffects.size();j++) { + EffectPtr e = c->effects.at(j); + if (e->is_enabled()) e->process_audio(timecode_start, timecode_end, frame->data[0], nb_bytes, 2); + } + if (c->get_opening_transition() != nullptr) { + if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { + double transition_start = (c->get_clip_in_with_transition() / c->sequence->frame_rate); + double transition_end = (c->get_clip_in_with_transition() + c->get_opening_transition()->get_length()) / c->sequence->frame_rate; + if (timecode_end < transition_end) { + double adjustment = transition_end - transition_start; + double adjusted_range_start = (timecode_start - transition_start) / adjustment; + double adjusted_range_end = (timecode_end - transition_start) / adjustment; + c->get_opening_transition()->process_audio(adjusted_range_start, adjusted_range_end, frame->data[0], nb_bytes, kTransitionOpening); + } + } + } + if (c->get_closing_transition() != nullptr) { + if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { + long length_with_transitions = c->get_timeline_out_with_transition() - c->get_timeline_in_with_transition(); + double transition_start = (c->get_clip_in_with_transition() + length_with_transitions - c->get_closing_transition()->get_length()) / c->sequence->frame_rate; + double transition_end = (c->get_clip_in_with_transition() + length_with_transitions) / c->sequence->frame_rate; + if (timecode_start > transition_start) { + double adjustment = transition_end - transition_start; + double adjusted_range_start = (timecode_start - transition_start) / adjustment; + double adjusted_range_end = (timecode_end - transition_start) / adjustment; + c->get_closing_transition()->process_audio(adjusted_range_start, adjusted_range_end, frame->data[0], nb_bytes, kTransitionClosing); + } + } + } - if (!nests.isEmpty()) { - ClipPtr next_nest = nests.last(); - nests.removeLast(); - apply_audio_effects(next_nest, timecode_start + (((double)c->get_timeline_in_with_transition()-c->get_clip_in_with_transition())/c->sequence->frame_rate), frame, nb_bytes, nests); - } + if (!nests.isEmpty()) { + ClipPtr next_nest = nests.last(); + nests.removeLast(); + apply_audio_effects(next_nest, timecode_start + (((double)c->get_timeline_in_with_transition()-c->get_clip_in_with_transition())/c->sequence->frame_rate), frame, nb_bytes, nests); + } } #define AUDIO_BUFFER_PADDING 2048 void cache_audio_worker(ClipPtr c, bool scrubbing, QVector& nests, int playback_speed) { - long timeline_in = c->get_timeline_in_with_transition(); - long timeline_out = c->get_timeline_out_with_transition(); - long target_frame = c->audio_target_frame; + long timeline_in = c->get_timeline_in_with_transition(); + long timeline_out = c->get_timeline_out_with_transition(); + long target_frame = c->audio_target_frame; - bool temp_reverse = (playback_speed < 0); - bool reverse_audio = (c->reverse != temp_reverse); + bool temp_reverse = (playback_speed < 0); + bool reverse_audio = (c->reverse != temp_reverse); - long frame_skip = 0; - double last_fr = c->sequence->frame_rate; - if (!nests.isEmpty()) { - for (int i=nests.size()-1;i>=0;i--) { - timeline_in = refactor_frame_number(timeline_in, last_fr, nests.at(i)->sequence->frame_rate) + nests.at(i)->get_timeline_in_with_transition() - nests.at(i)->get_clip_in_with_transition(); - timeline_out = refactor_frame_number(timeline_out, last_fr, nests.at(i)->sequence->frame_rate) + nests.at(i)->get_timeline_in_with_transition() - nests.at(i)->get_clip_in_with_transition(); - target_frame = refactor_frame_number(target_frame, last_fr, nests.at(i)->sequence->frame_rate) + nests.at(i)->get_timeline_in_with_transition() - nests.at(i)->get_clip_in_with_transition(); + long frame_skip = 0; + double last_fr = c->sequence->frame_rate; + if (!nests.isEmpty()) { + for (int i=nests.size()-1;i>=0;i--) { + timeline_in = refactor_frame_number(timeline_in, last_fr, nests.at(i)->sequence->frame_rate) + nests.at(i)->get_timeline_in_with_transition() - nests.at(i)->get_clip_in_with_transition(); + timeline_out = refactor_frame_number(timeline_out, last_fr, nests.at(i)->sequence->frame_rate) + nests.at(i)->get_timeline_in_with_transition() - nests.at(i)->get_clip_in_with_transition(); + target_frame = refactor_frame_number(target_frame, last_fr, nests.at(i)->sequence->frame_rate) + nests.at(i)->get_timeline_in_with_transition() - nests.at(i)->get_clip_in_with_transition(); - timeline_out = qMin(timeline_out, nests.at(i)->get_timeline_out_with_transition()); + timeline_out = qMin(timeline_out, nests.at(i)->get_timeline_out_with_transition()); - frame_skip = refactor_frame_number(frame_skip, last_fr, nests.at(i)->sequence->frame_rate); + frame_skip = refactor_frame_number(frame_skip, last_fr, nests.at(i)->sequence->frame_rate); - long validator = nests.at(i)->get_timeline_in_with_transition() - timeline_in; - if (validator > 0) { - frame_skip += validator; - //timeline_in = nests.at(i)->get_timeline_in_with_transition(); - } + long validator = nests.at(i)->get_timeline_in_with_transition() - timeline_in; + if (validator > 0) { + frame_skip += validator; + //timeline_in = nests.at(i)->get_timeline_in_with_transition(); + } - last_fr = nests.at(i)->sequence->frame_rate; - } - } + last_fr = nests.at(i)->sequence->frame_rate; + } + } - if (temp_reverse) { - long seq_end = olive::ActiveSequence->getEndFrame(); - timeline_in = seq_end - timeline_in; - timeline_out = seq_end - timeline_out; - target_frame = seq_end - target_frame; + if (temp_reverse) { + long seq_end = olive::ActiveSequence->getEndFrame(); + timeline_in = seq_end - timeline_in; + timeline_out = seq_end - timeline_out; + target_frame = seq_end - target_frame; - long temp = timeline_in; - timeline_in = timeline_out; - timeline_out = temp; - } + long temp = timeline_in; + timeline_in = timeline_out; + timeline_out = temp; + } - while (true) { - AVFrame* frame; - int nb_bytes = INT_MAX; + while (true) { + AVFrame* frame; + int nb_bytes = INT_MAX; - if (c->media == nullptr) { - frame = c->frame; - nb_bytes = frame->nb_samples * av_get_bytes_per_sample(static_cast(frame->format)) * frame->channels; - while ((c->frame_sample_index == -1 || c->frame_sample_index >= nb_bytes) && nb_bytes > 0) { - // create "new frame" - memset(c->frame->data[0], 0, nb_bytes); - apply_audio_effects(c, bytes_to_seconds(frame->pts, frame->channels, frame->sample_rate), frame, nb_bytes, nests); - c->frame->pts += nb_bytes; - c->frame_sample_index = 0; - if (c->audio_buffer_write == 0) { - c->audio_buffer_write = get_buffer_offset_from_frame(last_fr, qMax(timeline_in, target_frame)); - } - int offset = audio_ibuffer_read - c->audio_buffer_write; - if (offset > 0) { - c->audio_buffer_write += offset; - c->frame_sample_index += offset; - } - } - } else if (c->media->get_type() == MEDIA_TYPE_FOOTAGE) { - double timebase = av_q2d(c->stream->time_base); + if (c->media == nullptr) { + frame = c->frame; + nb_bytes = frame->nb_samples * av_get_bytes_per_sample(static_cast(frame->format)) * frame->channels; + while ((c->frame_sample_index == -1 || c->frame_sample_index >= nb_bytes) && nb_bytes > 0) { + // create "new frame" + memset(c->frame->data[0], 0, nb_bytes); + apply_audio_effects(c, bytes_to_seconds(frame->pts, frame->channels, frame->sample_rate), frame, nb_bytes, nests); + c->frame->pts += nb_bytes; + c->frame_sample_index = 0; + if (c->audio_buffer_write == 0) { + c->audio_buffer_write = get_buffer_offset_from_frame(last_fr, qMax(timeline_in, target_frame)); + } + int offset = audio_ibuffer_read - c->audio_buffer_write; + if (offset > 0) { + c->audio_buffer_write += offset; + c->frame_sample_index += offset; + } + } + } else if (c->media->get_type() == MEDIA_TYPE_FOOTAGE) { + double timebase = av_q2d(c->stream->time_base); - frame = c->queue.at(0); + frame = c->queue.at(0); - // retrieve frame - bool new_frame = false; - while ((c->frame_sample_index == -1 || c->frame_sample_index >= nb_bytes) && nb_bytes > 0) { - // no more audio left in frame, get a new one - if (!c->reached_end) { - int loop = 0; + // retrieve frame + bool new_frame = false; + while ((c->frame_sample_index == -1 || c->frame_sample_index >= nb_bytes) && nb_bytes > 0) { + // no more audio left in frame, get a new one + if (!c->reached_end) { + int loop = 0; - if (reverse_audio && !c->audio_just_reset) { - avcodec_flush_buffers(c->codecCtx); - c->reached_end = false; - int64_t backtrack_seek = qMax(c->reverse_target - static_cast(av_q2d(av_inv_q(c->stream->time_base))), static_cast(0)); - av_seek_frame(c->formatCtx, c->stream->index, backtrack_seek, AVSEEK_FLAG_BACKWARD); + if (reverse_audio && !c->audio_just_reset) { + avcodec_flush_buffers(c->codecCtx); + c->reached_end = false; + int64_t backtrack_seek = qMax(c->reverse_target - static_cast(av_q2d(av_inv_q(c->stream->time_base))), static_cast(0)); + av_seek_frame(c->formatCtx, c->stream->index, backtrack_seek, AVSEEK_FLAG_BACKWARD); #ifdef AUDIOWARNINGS - if (backtrack_seek == 0) { - dout << "backtracked to 0"; - } + if (backtrack_seek == 0) { + dout << "backtracked to 0"; + } #endif - } + } - do { - av_frame_unref(frame); + do { + av_frame_unref(frame); - int ret; + int ret; - while ((ret = av_buffersink_get_frame(c->buffersink_ctx, frame)) == AVERROR(EAGAIN)) { - ret = retrieve_next_frame(c, c->frame); - if (ret >= 0) { - if ((ret = av_buffersrc_add_frame_flags(c->buffersrc_ctx, c->frame, AV_BUFFERSRC_FLAG_KEEP_REF)) < 0) { - qCritical() << "Could not feed filtergraph -" << ret; - break; - } - } else { - if (ret == AVERROR_EOF) { + while ((ret = av_buffersink_get_frame(c->buffersink_ctx, frame)) == AVERROR(EAGAIN)) { + ret = retrieve_next_frame(c, c->frame); + if (ret >= 0) { + if ((ret = av_buffersrc_add_frame_flags(c->buffersrc_ctx, c->frame, AV_BUFFERSRC_FLAG_KEEP_REF)) < 0) { + qCritical() << "Could not feed filtergraph -" << ret; + break; + } + } else { + if (ret == AVERROR_EOF) { #ifdef AUDIOWARNINGS - dout << "reached EOF while reading"; + dout << "reached EOF while reading"; #endif - // TODO revise usage of reached_end in audio - if (!reverse_audio) { - c->reached_end = true; - } else { - } - } else { - qWarning() << "Raw audio frame data could not be retrieved." << ret; - c->reached_end = true; - } - break; - } - } + // TODO revise usage of reached_end in audio + if (!reverse_audio) { + c->reached_end = true; + } else { + } + } else { + qWarning() << "Raw audio frame data could not be retrieved." << ret; + c->reached_end = true; + } + break; + } + } - if (ret < 0) { - if (ret != AVERROR_EOF) { - qCritical() << "Could not pull from filtergraph"; - c->reached_end = true; - break; - } else { + if (ret < 0) { + if (ret != AVERROR_EOF) { + qCritical() << "Could not pull from filtergraph"; + c->reached_end = true; + break; + } else { #ifdef AUDIOWARNINGS - dout << "reached EOF while pulling from filtergraph"; + dout << "reached EOF while pulling from filtergraph"; #endif - if (!reverse_audio) break; - } - } + if (!reverse_audio) break; + } + } - if (reverse_audio) { - if (loop > 1) { - AVFrame* rev_frame = c->queue.at(1); - if (ret != AVERROR_EOF) { - if (loop == 2) { + if (reverse_audio) { + if (loop > 1) { + AVFrame* rev_frame = c->queue.at(1); + if (ret != AVERROR_EOF) { + if (loop == 2) { #ifdef AUDIOWARNINGS - dout << "starting rev_frame"; + dout << "starting rev_frame"; #endif - rev_frame->nb_samples = 0; - rev_frame->pts = c->frame->pkt_pts; - } - int offset = rev_frame->nb_samples * av_get_bytes_per_sample(static_cast(rev_frame->format)) * rev_frame->channels; + rev_frame->nb_samples = 0; + rev_frame->pts = c->frame->pkt_pts; + } + int offset = rev_frame->nb_samples * av_get_bytes_per_sample(static_cast(rev_frame->format)) * rev_frame->channels; #ifdef AUDIOWARNINGS - dout << "offset 1:" << offset; - dout << "retrieved samples:" << frame->nb_samples << "size:" << (frame->nb_samples * av_get_bytes_per_sample(static_cast(frame->format)) * frame->channels); + dout << "offset 1:" << offset; + dout << "retrieved samples:" << frame->nb_samples << "size:" << (frame->nb_samples * av_get_bytes_per_sample(static_cast(frame->format)) * frame->channels); #endif - memcpy( - rev_frame->data[0]+offset, - frame->data[0], - (frame->nb_samples * av_get_bytes_per_sample(static_cast(frame->format)) * frame->channels) - ); + memcpy( + rev_frame->data[0]+offset, + frame->data[0], + (frame->nb_samples * av_get_bytes_per_sample(static_cast(frame->format)) * frame->channels) + ); #ifdef AUDIOWARNINGS - dout << "pts:" << c->frame->pts << "dur:" << c->frame->pkt_duration << "rev_target:" << c->reverse_target << "offset:" << offset << "limit:" << rev_frame->linesize[0]; + dout << "pts:" << c->frame->pts << "dur:" << c->frame->pkt_duration << "rev_target:" << c->reverse_target << "offset:" << offset << "limit:" << rev_frame->linesize[0]; #endif - } + } - rev_frame->nb_samples += frame->nb_samples; + rev_frame->nb_samples += frame->nb_samples; - if ((c->frame->pts >= c->reverse_target) || (ret == AVERROR_EOF)) { -/* + if ((c->frame->pts >= c->reverse_target) || (ret == AVERROR_EOF)) { + /* #ifdef AUDIOWARNINGS - dout << "time for the end of rev cache" << rev_frame->nb_samples << c->rev_target << c->frame->pts << c->frame->pkt_duration << c->frame->nb_samples; - dout << "diff:" << (c->frame->pkt_pts + c->frame->pkt_duration) - c->rev_target; + dout << "time for the end of rev cache" << rev_frame->nb_samples << c->rev_target << c->frame->pts << c->frame->pkt_duration << c->frame->nb_samples; + dout << "diff:" << (c->frame->pkt_pts + c->frame->pkt_duration) - c->rev_target; #endif - int cutoff = qRound64((((c->frame->pkt_pts + c->frame->pkt_duration) - c->reverse_target) * timebase) * audio_output->format().sampleRate()); - if (cutoff > 0) { + int cutoff = qRound64((((c->frame->pkt_pts + c->frame->pkt_duration) - c->reverse_target) * timebase) * audio_output->format().sampleRate()); + if (cutoff > 0) { #ifdef AUDIOWARNINGS - dout << "cut off" << cutoff << "samples (rate:" << audio_output->format().sampleRate() << ")"; + dout << "cut off" << cutoff << "samples (rate:" << audio_output->format().sampleRate() << ")"; #endif - rev_frame->nb_samples -= cutoff; - } + rev_frame->nb_samples -= cutoff; + } */ #ifdef AUDIOWARNINGS - dout << "pre cutoff deets::: rev_frame.pts:" << rev_frame->pts << "rev_frame.nb_samples" << rev_frame->nb_samples << "rev_target:" << c->reverse_target; + dout << "pre cutoff deets::: rev_frame.pts:" << rev_frame->pts << "rev_frame.nb_samples" << rev_frame->nb_samples << "rev_target:" << c->reverse_target; #endif - double playback_speed = c->speed * c->media->to_footage()->speed; - rev_frame->nb_samples = qRound64(static_cast(c->reverse_target - rev_frame->pts) / c->stream->codecpar->sample_rate * (current_audio_freq() / playback_speed)); + double playback_speed = c->speed * c->media->to_footage()->speed; + rev_frame->nb_samples = qRound64(static_cast(c->reverse_target - rev_frame->pts) / c->stream->codecpar->sample_rate * (current_audio_freq() / playback_speed)); #ifdef AUDIOWARNINGS - dout << "post cutoff deets::" << rev_frame->nb_samples; + dout << "post cutoff deets::" << rev_frame->nb_samples; #endif - int frame_size = rev_frame->nb_samples * rev_frame->channels * av_get_bytes_per_sample(static_cast(rev_frame->format)); - int half_frame_size = frame_size >> 1; + int frame_size = rev_frame->nb_samples * rev_frame->channels * av_get_bytes_per_sample(static_cast(rev_frame->format)); + int half_frame_size = frame_size >> 1; - int sample_size = rev_frame->channels*av_get_bytes_per_sample(static_cast(rev_frame->format)); - char* temp_chars = new char[sample_size]; - for (int i=0;idata[0][i+j]; - } - for (int j=0;jdata[0][i+j] = rev_frame->data[0][frame_size-i-sample_size+j]; - } - for (int j=0;jdata[0][frame_size-i-sample_size+j] = temp_chars[j]; - } - } - delete [] temp_chars; + int sample_size = rev_frame->channels*av_get_bytes_per_sample(static_cast(rev_frame->format)); + char* temp_chars = new char[sample_size]; + for (int i=0;idata[0][i+j]; + } + for (int j=0;jdata[0][i+j] = rev_frame->data[0][frame_size-i-sample_size+j]; + } + for (int j=0;jdata[0][frame_size-i-sample_size+j] = temp_chars[j]; + } + } + delete [] temp_chars; - c->reverse_target = rev_frame->pts; - frame = rev_frame; - break; - } - } + c->reverse_target = rev_frame->pts; + frame = rev_frame; + break; + } + } - loop++; + loop++; #ifdef AUDIOWARNINGS - dout << "loop" << loop; + dout << "loop" << loop; #endif - } else { - frame->pts = c->frame->pts; - break; - } - } while (true); - } else { - // if there is no more data in the file, we flush the remainder out of swresample - break; - } + } else { + frame->pts = c->frame->pts; + break; + } + } while (true); + } else { + // if there is no more data in the file, we flush the remainder out of swresample + break; + } - new_frame = true; + new_frame = true; - if (c->frame_sample_index < 0) { - c->frame_sample_index = 0; - } else { - c->frame_sample_index -= nb_bytes; - } + if (c->frame_sample_index < 0) { + c->frame_sample_index = 0; + } else { + c->frame_sample_index -= nb_bytes; + } - nb_bytes = frame->nb_samples * av_get_bytes_per_sample(static_cast(frame->format)) * frame->channels; + nb_bytes = frame->nb_samples * av_get_bytes_per_sample(static_cast(frame->format)) * frame->channels; - if (c->audio_just_reset) { - // get precise sample offset for the elected clip_in from this audio frame - double target_sts = playhead_to_clip_seconds(c, c->audio_target_frame); - double frame_sts = ((frame->pts - c->stream->start_time) * timebase); - int nb_samples = qRound64((target_sts - frame_sts)*current_audio_freq()); - c->frame_sample_index = nb_samples * 4; + if (c->audio_just_reset) { + // get precise sample offset for the elected clip_in from this audio frame + double target_sts = playhead_to_clip_seconds(c, c->audio_target_frame); + double frame_sts = ((frame->pts - c->stream->start_time) * timebase); + int nb_samples = qRound64((target_sts - frame_sts)*current_audio_freq()); + c->frame_sample_index = nb_samples * 4; #ifdef AUDIOWARNINGS - dout << "fsts:" << frame_sts << "tsts:" << target_sts << "nbs:" << nb_samples << "nbb:" << nb_bytes << "rev_targetToSec:" << (c->reverse_target * timebase); - dout << "fsi-calc:" << c->frame_sample_index; + dout << "fsts:" << frame_sts << "tsts:" << target_sts << "nbs:" << nb_samples << "nbb:" << nb_bytes << "rev_targetToSec:" << (c->reverse_target * timebase); + dout << "fsi-calc:" << c->frame_sample_index; #endif - if (reverse_audio) c->frame_sample_index = nb_bytes - c->frame_sample_index; - c->audio_just_reset = false; - } + if (reverse_audio) c->frame_sample_index = nb_bytes - c->frame_sample_index; + c->audio_just_reset = false; + } #ifdef AUDIOWARNINGS - dout << "fsi-post-post:" << c->frame_sample_index; + dout << "fsi-post-post:" << c->frame_sample_index; #endif - if (c->audio_buffer_write == 0) { - c->audio_buffer_write = get_buffer_offset_from_frame(last_fr, qMax(timeline_in, target_frame)); + if (c->audio_buffer_write == 0) { + c->audio_buffer_write = get_buffer_offset_from_frame(last_fr, qMax(timeline_in, target_frame)); - if (frame_skip > 0) { - int target = get_buffer_offset_from_frame(last_fr, qMax(timeline_in + frame_skip, target_frame)); - c->frame_sample_index += (target - c->audio_buffer_write); - c->audio_buffer_write = target; - } - } + if (frame_skip > 0) { + int target = get_buffer_offset_from_frame(last_fr, qMax(timeline_in + frame_skip, target_frame)); + c->frame_sample_index += (target - c->audio_buffer_write); + c->audio_buffer_write = target; + } + } - int offset = audio_ibuffer_read - c->audio_buffer_write; - if (offset > 0) { - c->audio_buffer_write += offset; - c->frame_sample_index += offset; - } + int offset = audio_ibuffer_read - c->audio_buffer_write; + if (offset > 0) { + c->audio_buffer_write += offset; + c->frame_sample_index += offset; + } - // try to correct negative fsi - if (c->frame_sample_index < 0) { - c->audio_buffer_write -= c->frame_sample_index; - c->frame_sample_index = 0; - } - } + // try to correct negative fsi + if (c->frame_sample_index < 0) { + c->audio_buffer_write -= c->frame_sample_index; + c->frame_sample_index = 0; + } + } - if (reverse_audio) frame = c->queue.at(1); + if (reverse_audio) frame = c->queue.at(1); #ifdef AUDIOWARNINGS - dout << "j" << c->frame_sample_index << nb_bytes; + dout << "j" << c->frame_sample_index << nb_bytes; #endif - // apply any audio effects to the data - if (nb_bytes == INT_MAX) nb_bytes = frame->nb_samples * av_get_bytes_per_sample(static_cast(frame->format)) * frame->channels; - if (new_frame) { - apply_audio_effects(c, bytes_to_seconds(c->audio_buffer_write, 2, current_audio_freq()) + audio_ibuffer_timecode + ((double)c->get_clip_in_with_transition()/c->sequence->frame_rate) - ((double)timeline_in/last_fr), frame, nb_bytes, nests); - } - } else { - // shouldn't ever get here - qCritical() << "Tried to cache a non-footage/tone clip"; - return; - } + // apply any audio effects to the data + if (nb_bytes == INT_MAX) nb_bytes = frame->nb_samples * av_get_bytes_per_sample(static_cast(frame->format)) * frame->channels; + if (new_frame) { + apply_audio_effects(c, bytes_to_seconds(c->audio_buffer_write, 2, current_audio_freq()) + audio_ibuffer_timecode + ((double)c->get_clip_in_with_transition()/c->sequence->frame_rate) - ((double)timeline_in/last_fr), frame, nb_bytes, nests); + } + } else { + // shouldn't ever get here + qCritical() << "Tried to cache a non-footage/tone clip"; + return; + } - // mix audio into internal buffer - if (frame->nb_samples == 0) { - break; - } else { - qint64 buffer_timeline_out = get_buffer_offset_from_frame(c->sequence->frame_rate, timeline_out); + // mix audio into internal buffer + if (frame->nb_samples == 0) { + break; + } else { + qint64 buffer_timeline_out = get_buffer_offset_from_frame(c->sequence->frame_rate, timeline_out); - audio_write_lock.lock(); + audio_write_lock.lock(); - int sample_skip = 4*qMax(0, qAbs(playback_speed)-1); - int sample_byte_size = av_get_bytes_per_sample(static_cast(frame->format)); + int sample_skip = 4*qMax(0, qAbs(playback_speed)-1); + int sample_byte_size = av_get_bytes_per_sample(static_cast(frame->format)); - while (c->frame_sample_index < nb_bytes - && c->audio_buffer_write < audio_ibuffer_read+(audio_ibuffer_size>>1) - && c->audio_buffer_write < buffer_timeline_out) { - for (int i=0;ichannels;i++) { - int upper_byte_index = (c->audio_buffer_write+1)%audio_ibuffer_size; - int lower_byte_index = (c->audio_buffer_write)%audio_ibuffer_size; - qint16 old_sample = static_cast((audio_ibuffer[upper_byte_index] & 0xFF) << 8 | (audio_ibuffer[lower_byte_index] & 0xFF)); - qint16 new_sample = static_cast((frame->data[0][c->frame_sample_index+1] & 0xFF) << 8 | (frame->data[0][c->frame_sample_index] & 0xFF)); - qint16 mixed_sample = mix_audio_sample(old_sample, new_sample); + while (c->frame_sample_index < nb_bytes + && c->audio_buffer_write < audio_ibuffer_read+(audio_ibuffer_size>>1) + && c->audio_buffer_write < buffer_timeline_out) { + for (int i=0;ichannels;i++) { + int upper_byte_index = (c->audio_buffer_write+1)%audio_ibuffer_size; + int lower_byte_index = (c->audio_buffer_write)%audio_ibuffer_size; + qint16 old_sample = static_cast((audio_ibuffer[upper_byte_index] & 0xFF) << 8 | (audio_ibuffer[lower_byte_index] & 0xFF)); + qint16 new_sample = static_cast((frame->data[0][c->frame_sample_index+1] & 0xFF) << 8 | (frame->data[0][c->frame_sample_index] & 0xFF)); + qint16 mixed_sample = mix_audio_sample(old_sample, new_sample); - audio_ibuffer[upper_byte_index] = quint8((mixed_sample >> 8) & 0xFF); - audio_ibuffer[lower_byte_index] = quint8(mixed_sample & 0xFF); + audio_ibuffer[upper_byte_index] = quint8((mixed_sample >> 8) & 0xFF); + audio_ibuffer[lower_byte_index] = quint8(mixed_sample & 0xFF); - c->audio_buffer_write+=sample_byte_size; - c->frame_sample_index+=sample_byte_size; - } + c->audio_buffer_write+=sample_byte_size; + c->frame_sample_index+=sample_byte_size; + } - c->frame_sample_index += sample_skip; + c->frame_sample_index += sample_skip; - if (c->audio_reset) break; - } + if (c->audio_reset) break; + } #ifdef AUDIOWARNINGS - if (c->audio_buffer_write >= buffer_timeline_out) dout << "timeline out at fsi" << c->frame_sample_index << "of frame ts" << c->frame->pts; + if (c->audio_buffer_write >= buffer_timeline_out) dout << "timeline out at fsi" << c->frame_sample_index << "of frame ts" << c->frame->pts; #endif - audio_write_lock.unlock(); + audio_write_lock.unlock(); - if (c->audio_reset) return; + if (c->audio_reset) return; - if (scrubbing) { - if (audio_thread != nullptr) audio_thread->notifyReceiver(); - } + if (scrubbing) { + if (audio_thread != nullptr) audio_thread->notifyReceiver(); + } - if (c->frame_sample_index >= nb_bytes) { - c->frame_sample_index = -1; - } else { - // assume we have no more data to send - break; - } + if (c->frame_sample_index >= nb_bytes) { + c->frame_sample_index = -1; + } else { + // assume we have no more data to send + break; + } -// dout << "ended" << c->frame_sample_index << nb_bytes; - } - if (c->reached_end) { - frame->nb_samples = 0; - } - if (scrubbing) { - break; - } - } + // dout << "ended" << c->frame_sample_index << nb_bytes; + } + if (c->reached_end) { + frame->nb_samples = 0; + } + if (scrubbing) { + break; + } + } - QMetaObject::invokeMethod(panel_footage_viewer, "play_wake", Qt::QueuedConnection); - QMetaObject::invokeMethod(panel_sequence_viewer, "play_wake", Qt::QueuedConnection); + QMetaObject::invokeMethod(panel_footage_viewer, "play_wake", Qt::QueuedConnection); + QMetaObject::invokeMethod(panel_sequence_viewer, "play_wake", Qt::QueuedConnection); } void cache_video_worker(ClipPtr c, long playhead) { - int read_ret, send_ret, retr_ret; + int read_ret, send_ret, retr_ret; - int64_t target_pts = seconds_to_timestamp(c, playhead_to_clip_seconds(c, playhead)); + int64_t target_pts = seconds_to_timestamp(c, playhead_to_clip_seconds(c, playhead)); - int limit = c->max_queue_size; - if (c->ignore_reverse) { - // waiting for one frame - limit = c->queue.size() + 1; - } else if (c->reverse) { - limit *= 2; - } + int limit = c->max_queue_size; + if (c->ignore_reverse) { + // waiting for one frame + limit = c->queue.size() + 1; + } else if (c->reverse) { + limit *= 2; + } - if (c->queue.size() < limit) { - bool reverse = (c->reverse && !c->ignore_reverse); - c->ignore_reverse = false; + if (c->queue.size() < limit) { + bool reverse = (c->reverse && !c->ignore_reverse); + c->ignore_reverse = false; - int64_t smallest_pts = INT64_MAX; - if (reverse && c->queue.size() > 0) { - int64_t quarter_sec = qRound64(av_q2d(av_inv_q(c->stream->time_base))) >> 2; - for (int i=0;iqueue.size();i++) { - smallest_pts = qMin(smallest_pts, c->queue.at(i)->pts); - } - avcodec_flush_buffers(c->codecCtx); - c->reached_end = false; - int64_t seek_ts = qMax(static_cast(0), smallest_pts - quarter_sec); - av_seek_frame(c->formatCtx, c->stream->index, seek_ts, AVSEEK_FLAG_BACKWARD); - } else { - smallest_pts = target_pts; - } + int64_t smallest_pts = INT64_MAX; + if (reverse && c->queue.size() > 0) { + int64_t quarter_sec = qRound64(av_q2d(av_inv_q(c->stream->time_base))) >> 2; + for (int i=0;iqueue.size();i++) { + smallest_pts = qMin(smallest_pts, c->queue.at(i)->pts); + } + avcodec_flush_buffers(c->codecCtx); + c->reached_end = false; + int64_t seek_ts = qMax(static_cast(0), smallest_pts - quarter_sec); + av_seek_frame(c->formatCtx, c->stream->index, seek_ts, AVSEEK_FLAG_BACKWARD); + } else { + smallest_pts = target_pts; + } - if (c->multithreaded && c->cacher->interrupt) { // ignore interrupts for now - c->cacher->interrupt = false; - } + if (c->multithreaded && c->cacher->interrupt) { // ignore interrupts for now + c->cacher->interrupt = false; + } - while (true) { - AVFrame* frame = av_frame_alloc(); + while (true) { + AVFrame* frame = av_frame_alloc(); - FootagePtr media = c->media->to_footage(); - const FootageStream* ms = media->get_stream_from_file_index(true, c->media_stream); + FootagePtr media = c->media->to_footage(); + const FootageStream* ms = media->get_stream_from_file_index(true, c->media_stream); - while ((retr_ret = av_buffersink_get_frame(c->buffersink_ctx, frame)) == AVERROR(EAGAIN)) { - if (c->multithreaded && c->cacher->interrupt) return; // abort + while ((retr_ret = av_buffersink_get_frame(c->buffersink_ctx, frame)) == AVERROR(EAGAIN)) { + if (c->multithreaded && c->cacher->interrupt) return; // abort - AVFrame* send_frame = c->frame; -// qint64 time = QDateTime::currentMSecsSinceEpoch(); - read_ret = (c->use_existing_frame) ? 0 : retrieve_next_frame(c, send_frame); -// dout << QDateTime::currentMSecsSinceEpoch() - time; - c->use_existing_frame = false; - if (read_ret >= 0) { - bool send_it = true; + AVFrame* send_frame = c->frame; + // qint64 time = QDateTime::currentMSecsSinceEpoch(); + read_ret = (c->use_existing_frame) ? 0 : retrieve_next_frame(c, send_frame); + // dout << QDateTime::currentMSecsSinceEpoch() - time; + c->use_existing_frame = false; + if (read_ret >= 0) { + bool send_it = true; - /*if (reverse) { - send_it = true; - } else if (send_frame->pts > target_pts - eighth_second) { - send_it = true; - } else if (media->get_stream_from_file_index(true, c->media_stream)->infinite_length) { - send_it = true; - } else { - dout << "skipped adding a frame to the queue - fpts:" << send_frame->pts << "target:" << target_pts; - }*/ + /*if (reverse) { + send_it = true; + } else if (send_frame->pts > target_pts - eighth_second) { + send_it = true; + } else if (media->get_stream_from_file_index(true, c->media_stream)->infinite_length) { + send_it = true; + } else { + dout << "skipped adding a frame to the queue - fpts:" << send_frame->pts << "target:" << target_pts; + }*/ - if (send_it) { - if ((send_ret = av_buffersrc_add_frame_flags(c->buffersrc_ctx, send_frame, AV_BUFFERSRC_FLAG_KEEP_REF)) < 0) { - qCritical() << "Failed to add frame to buffer source." << send_ret; - break; - } - } + if (send_it) { + if ((send_ret = av_buffersrc_add_frame_flags(c->buffersrc_ctx, send_frame, AV_BUFFERSRC_FLAG_KEEP_REF)) < 0) { + qCritical() << "Failed to add frame to buffer source." << send_ret; + break; + } + } - av_frame_unref(c->frame); - } else { - if (read_ret == AVERROR_EOF) { - c->reached_end = true; - } else { - qCritical() << "Failed to read frame." << read_ret; - } - break; - } - } + av_frame_unref(c->frame); + } else { + if (read_ret == AVERROR_EOF) { + c->reached_end = true; + } else { + qCritical() << "Failed to read frame." << read_ret; + } + break; + } + } - if (retr_ret < 0) { - if (retr_ret == AVERROR_EOF) { - c->reached_end = true; - } else { - qCritical() << "Failed to retrieve frame from buffersink." << retr_ret; - } - av_frame_free(&frame); - break; - } else { - if (reverse && ((smallest_pts == target_pts && frame->pts >= smallest_pts) || (smallest_pts != target_pts && frame->pts > smallest_pts))) { - av_frame_free(&frame); - break; - } else { - // thread-safety while adding frame to the queue - c->queue_lock.lock(); - c->queue.append(frame); + if (retr_ret < 0) { + if (retr_ret == AVERROR_EOF) { + c->reached_end = true; + } else { + qCritical() << "Failed to retrieve frame from buffersink." << retr_ret; + } + av_frame_free(&frame); + break; + } else { + if (reverse && ((smallest_pts == target_pts && frame->pts >= smallest_pts) || (smallest_pts != target_pts && frame->pts > smallest_pts))) { + av_frame_free(&frame); + break; + } else { + // thread-safety while adding frame to the queue + c->queue_lock.lock(); + c->queue.append(frame); - if (!ms->infinite_length && !reverse && c->queue.size() == limit) { - // see if we got the frame we needed (used for speed ups primarily) - bool found = false; - for (int i=0;iqueue.size();i++) { - if (c->queue.at(i)->pts >= target_pts) { - found = true; - break; - } - } - if (found) { - c->queue_lock.unlock(); - break; - } else { - // remove earliest frame and loop to store another - c->queue_remove_earliest(); - } - } - c->queue_lock.unlock(); - } - } + if (!ms->infinite_length && !reverse && c->queue.size() == limit) { + // see if we got the frame we needed (used for speed ups primarily) + bool found = false; + for (int i=0;iqueue.size();i++) { + if (c->queue.at(i)->pts >= target_pts) { + found = true; + break; + } + } + if (found) { + c->queue_lock.unlock(); + break; + } else { + // remove earliest frame and loop to store another + c->queue_remove_earliest(); + } + } + c->queue_lock.unlock(); + } + } - if (c->multithreaded && c->cacher->interrupt) { // abort - return; - } - } - } + if (c->multithreaded && c->cacher->interrupt) { // abort + return; + } + } + } } void reset_cache(ClipPtr c, long target_frame, int playback_speed) { - // if we seek to a whole other place in the timeline, we'll need to reset the cache with new values - if (c->media == nullptr) { - if (c->track >= 0) { - // tone clip - c->reached_end = false; - c->audio_target_frame = target_frame; - c->frame_sample_index = -1; - c->frame->pts = 0; - } - } else { - const FootageStream* ms = c->media->to_footage()->get_stream_from_file_index(c->track < 0, c->media_stream); - if (ms->infinite_length) { - /*avcodec_flush_buffers(c->codecCtx); - av_seek_frame(c->formatCtx, ms->file_index, 0, AVSEEK_FLAG_BACKWARD);*/ - c->use_existing_frame = false; - } else { - if (c->stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { - // clear current queue - c->queue_lock.lock(); - c->queue_clear(); - c->queue_lock.unlock(); + // if we seek to a whole other place in the timeline, we'll need to reset the cache with new values + if (c->media == nullptr) { + if (c->track >= 0) { + // tone clip + c->reached_end = false; + c->audio_target_frame = target_frame; + c->frame_sample_index = -1; + c->frame->pts = 0; + } + } else { + const FootageStream* ms = c->media->to_footage()->get_stream_from_file_index(c->track < 0, c->media_stream); + if (ms->infinite_length) { + /*avcodec_flush_buffers(c->codecCtx); + av_seek_frame(c->formatCtx, ms->file_index, 0, AVSEEK_FLAG_BACKWARD);*/ + c->use_existing_frame = false; + } else { + if (c->stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + // clear current queue + c->queue_lock.lock(); + c->queue_clear(); + c->queue_lock.unlock(); - // seeks to nearest keyframe (target_frame represents internal clip frame) - int64_t target_ts = seconds_to_timestamp(c, playhead_to_clip_seconds(c, target_frame)); - int64_t seek_ts = target_ts; - int64_t timebase_half_second = qRound64(av_q2d(av_inv_q(c->stream->time_base))); - if (c->reverse) seek_ts -= timebase_half_second; + // seeks to nearest keyframe (target_frame represents internal clip frame) + int64_t target_ts = seconds_to_timestamp(c, playhead_to_clip_seconds(c, target_frame)); + int64_t seek_ts = target_ts; + int64_t timebase_half_second = qRound64(av_q2d(av_inv_q(c->stream->time_base))); + if (c->reverse) seek_ts -= timebase_half_second; - while (true) { - // flush ffmpeg codecs - avcodec_flush_buffers(c->codecCtx); - c->reached_end = false; + while (true) { + // flush ffmpeg codecs + avcodec_flush_buffers(c->codecCtx); + c->reached_end = false; - if (seek_ts > 0) { - av_seek_frame(c->formatCtx, ms->file_index, seek_ts, AVSEEK_FLAG_BACKWARD); + if (seek_ts > 0) { + av_seek_frame(c->formatCtx, ms->file_index, seek_ts, AVSEEK_FLAG_BACKWARD); - av_frame_unref(c->frame); - int ret = retrieve_next_frame(c, c->frame); - if (ret < 0) { - qWarning() << "Seeking terminated prematurely"; - break; - } - if (c->frame->pts <= target_ts) { - c->use_existing_frame = true; - break; - } else { - seek_ts -= timebase_half_second; - } - } else { - av_frame_unref(c->frame); - av_seek_frame(c->formatCtx, ms->file_index, 0, AVSEEK_FLAG_BACKWARD); - c->use_existing_frame = false; - break; - } - } - } else if (c->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { - // flush ffmpeg codecs - avcodec_flush_buffers(c->codecCtx); - c->reached_end = false; + av_frame_unref(c->frame); + int ret = retrieve_next_frame(c, c->frame); + if (ret < 0) { + qWarning() << "Seeking terminated prematurely"; + break; + } + if (c->frame->pts <= target_ts) { + c->use_existing_frame = true; + break; + } else { + seek_ts -= timebase_half_second; + } + } else { + av_frame_unref(c->frame); + av_seek_frame(c->formatCtx, ms->file_index, 0, AVSEEK_FLAG_BACKWARD); + c->use_existing_frame = false; + break; + } + } + } else if (c->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { + // flush ffmpeg codecs + avcodec_flush_buffers(c->codecCtx); + c->reached_end = false; - // seek (target_frame represents timeline timecode in frames, not clip timecode) + // seek (target_frame represents timeline timecode in frames, not clip timecode) -// bool reverse = (c->reverse != temp_reverse); + // bool reverse = (c->reverse != temp_reverse); - int64_t timestamp = seconds_to_timestamp(c, playhead_to_clip_seconds(c, target_frame)); + int64_t timestamp = seconds_to_timestamp(c, playhead_to_clip_seconds(c, target_frame)); - bool temp_reverse = (playback_speed < 0); - if (c->reverse != temp_reverse) { - c->reverse_target = timestamp; - timestamp -= av_q2d(av_inv_q(c->stream->time_base)); + bool temp_reverse = (playback_speed < 0); + if (c->reverse != temp_reverse) { + c->reverse_target = timestamp; + timestamp -= av_q2d(av_inv_q(c->stream->time_base)); #ifdef AUDIOWARNINGS - dout << "seeking to" << timestamp << "(originally" << c->reverse_target << ")"; - } else { - dout << "reset called; seeking to" << timestamp; + dout << "seeking to" << timestamp << "(originally" << c->reverse_target << ")"; + } else { + dout << "reset called; seeking to" << timestamp; #endif - } - av_seek_frame(c->formatCtx, ms->file_index, timestamp, AVSEEK_FLAG_BACKWARD); - c->audio_target_frame = target_frame; - c->frame_sample_index = -1; - c->audio_just_reset = true; - } - } - } + } + av_seek_frame(c->formatCtx, ms->file_index, timestamp, AVSEEK_FLAG_BACKWARD); + c->audio_target_frame = target_frame; + c->frame_sample_index = -1; + c->audio_just_reset = true; + } + } + } } Cacher::Cacher(ClipPtr c) : clip(c) {} @@ -676,350 +676,350 @@ Cacher::Cacher(ClipPtr c) : clip(c) {} AVSampleFormat sample_format = AV_SAMPLE_FMT_S16; void open_clip_worker(ClipPtr clip) { - qint64 time_start = QDateTime::currentMSecsSinceEpoch(); + qint64 time_start = QDateTime::currentMSecsSinceEpoch(); - if (clip->media == nullptr) { - if (clip->track >= 0) { - clip->frame = av_frame_alloc(); - clip->frame->format = sample_format; - clip->frame->channel_layout = clip->sequence->audio_layout; - clip->frame->channels = av_get_channel_layout_nb_channels(clip->frame->channel_layout); - clip->frame->sample_rate = current_audio_freq(); - clip->frame->nb_samples = 2048; - av_frame_make_writable(clip->frame); - if (av_frame_get_buffer(clip->frame, 0)) { - qCritical() << "Could not allocate buffer for tone clip"; - } - clip->audio_reset = true; - } - } else if (clip->media->get_type() == MEDIA_TYPE_FOOTAGE) { - // opens file resource for FFmpeg and prepares Clip struct for playback - FootagePtr m = clip->media->to_footage(); + if (clip->media == nullptr) { + if (clip->track >= 0) { + clip->frame = av_frame_alloc(); + clip->frame->format = sample_format; + clip->frame->channel_layout = clip->sequence->audio_layout; + clip->frame->channels = av_get_channel_layout_nb_channels(clip->frame->channel_layout); + clip->frame->sample_rate = current_audio_freq(); + clip->frame->nb_samples = 2048; + av_frame_make_writable(clip->frame); + if (av_frame_get_buffer(clip->frame, 0)) { + qCritical() << "Could not allocate buffer for tone clip"; + } + clip->audio_reset = true; + } + } else if (clip->media->get_type() == MEDIA_TYPE_FOOTAGE) { + // opens file resource for FFmpeg and prepares Clip struct for playback + FootagePtr m = clip->media->to_footage(); - // byte array for retriving raw bytes from QString URL - QByteArray ba; + // byte array for retriving raw bytes from QString URL + QByteArray ba; - // do we have a proxy? - if (m->proxy - && !m->proxy_path.isEmpty() - && QFileInfo::exists(m->proxy_path)) { - ba = m->proxy_path.toUtf8(); - } else { - ba = m->url.toUtf8(); - } + // do we have a proxy? + if (m->proxy + && !m->proxy_path.isEmpty() + && QFileInfo::exists(m->proxy_path)) { + ba = m->proxy_path.toUtf8(); + } else { + ba = m->url.toUtf8(); + } - const char* filename = ba.constData(); - const FootageStream* ms = m->get_stream_from_file_index(clip->track < 0, clip->media_stream); + const char* filename = ba.constData(); + const FootageStream* ms = m->get_stream_from_file_index(clip->track < 0, clip->media_stream); - int errCode = avformat_open_input( - &clip->formatCtx, - filename, - nullptr, - nullptr - ); - if (errCode != 0) { - char err[1024]; - av_strerror(errCode, err, 1024); - qCritical() << "Could not open" << filename << "-" << err; - return; - } + int errCode = avformat_open_input( + &clip->formatCtx, + filename, + nullptr, + nullptr + ); + if (errCode != 0) { + char err[1024]; + av_strerror(errCode, err, 1024); + qCritical() << "Could not open" << filename << "-" << err; + return; + } - errCode = avformat_find_stream_info(clip->formatCtx, nullptr); - if (errCode < 0) { - char err[1024]; - av_strerror(errCode, err, 1024); - qCritical() << "Could not open" << filename << "-" << err; - return; - } + errCode = avformat_find_stream_info(clip->formatCtx, nullptr); + if (errCode < 0) { + char err[1024]; + av_strerror(errCode, err, 1024); + qCritical() << "Could not open" << filename << "-" << err; + return; + } - av_dump_format(clip->formatCtx, 0, filename, 0); + av_dump_format(clip->formatCtx, 0, filename, 0); - clip->stream = clip->formatCtx->streams[ms->file_index]; - clip->codec = avcodec_find_decoder(clip->stream->codecpar->codec_id); - clip->codecCtx = avcodec_alloc_context3(clip->codec); - avcodec_parameters_to_context(clip->codecCtx, clip->stream->codecpar); + clip->stream = clip->formatCtx->streams[ms->file_index]; + clip->codec = avcodec_find_decoder(clip->stream->codecpar->codec_id); + clip->codecCtx = avcodec_alloc_context3(clip->codec); + avcodec_parameters_to_context(clip->codecCtx, clip->stream->codecpar); - if (ms->infinite_length) { - clip->max_queue_size = 1; - } else { - clip->max_queue_size = 0; - if (olive::CurrentConfig.upcoming_queue_type == FRAME_QUEUE_TYPE_FRAMES) { - clip->max_queue_size += qCeil(olive::CurrentConfig.upcoming_queue_size); - } else { - clip->max_queue_size += qCeil(ms->video_frame_rate * m->speed * olive::CurrentConfig.upcoming_queue_size); - } - if (olive::CurrentConfig.previous_queue_type == FRAME_QUEUE_TYPE_FRAMES) { - clip->max_queue_size += qCeil(olive::CurrentConfig.previous_queue_size); - } else { - clip->max_queue_size += qCeil(ms->video_frame_rate * m->speed * olive::CurrentConfig.previous_queue_size); - } - } + if (ms->infinite_length) { + clip->max_queue_size = 1; + } else { + clip->max_queue_size = 0; + if (olive::CurrentConfig.upcoming_queue_type == FRAME_QUEUE_TYPE_FRAMES) { + clip->max_queue_size += qCeil(olive::CurrentConfig.upcoming_queue_size); + } else { + clip->max_queue_size += qCeil(ms->video_frame_rate * m->speed * olive::CurrentConfig.upcoming_queue_size); + } + if (olive::CurrentConfig.previous_queue_type == FRAME_QUEUE_TYPE_FRAMES) { + clip->max_queue_size += qCeil(olive::CurrentConfig.previous_queue_size); + } else { + clip->max_queue_size += qCeil(ms->video_frame_rate * m->speed * olive::CurrentConfig.previous_queue_size); + } + } - if (ms->video_interlacing != VIDEO_PROGRESSIVE) clip->max_queue_size *= 2; + if (ms->video_interlacing != VIDEO_PROGRESSIVE) clip->max_queue_size *= 2; - clip->opts = nullptr; + clip->opts = nullptr; - // enable multithreading on decoding - av_dict_set(&clip->opts, "threads", "auto", 0); + // enable multithreading on decoding + av_dict_set(&clip->opts, "threads", "auto", 0); - // enable extra optimization code on h264 (not even sure if they help) - if (clip->stream->codecpar->codec_id == AV_CODEC_ID_H264) { - av_dict_set(&clip->opts, "tune", "fastdecode", 0); - av_dict_set(&clip->opts, "tune", "zerolatency", 0); - } + // enable extra optimization code on h264 (not even sure if they help) + if (clip->stream->codecpar->codec_id == AV_CODEC_ID_H264) { + av_dict_set(&clip->opts, "tune", "fastdecode", 0); + av_dict_set(&clip->opts, "tune", "zerolatency", 0); + } - // Open codec - if (avcodec_open2(clip->codecCtx, clip->codec, &clip->opts) < 0) { - qCritical() << "Could not open codec"; - } + // Open codec + if (avcodec_open2(clip->codecCtx, clip->codec, &clip->opts) < 0) { + qCritical() << "Could not open codec"; + } - // allocate filtergraph - clip->filter_graph = avfilter_graph_alloc(); - if (clip->filter_graph == nullptr) { - qCritical() << "Could not create filtergraph"; - } - char filter_args[512]; + // allocate filtergraph + clip->filter_graph = avfilter_graph_alloc(); + if (clip->filter_graph == nullptr) { + qCritical() << "Could not create filtergraph"; + } + char filter_args[512]; - if (clip->stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { - snprintf(filter_args, sizeof(filter_args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", - clip->stream->codecpar->width, - clip->stream->codecpar->height, - clip->stream->codecpar->format, - clip->stream->time_base.num, - clip->stream->time_base.den, - clip->stream->codecpar->sample_aspect_ratio.num, - clip->stream->codecpar->sample_aspect_ratio.den - ); + if (clip->stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + snprintf(filter_args, sizeof(filter_args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", + clip->stream->codecpar->width, + clip->stream->codecpar->height, + clip->stream->codecpar->format, + clip->stream->time_base.num, + clip->stream->time_base.den, + clip->stream->codecpar->sample_aspect_ratio.num, + clip->stream->codecpar->sample_aspect_ratio.den + ); - avfilter_graph_create_filter(&clip->buffersrc_ctx, avfilter_get_by_name("buffer"), "in", filter_args, nullptr, clip->filter_graph); - avfilter_graph_create_filter(&clip->buffersink_ctx, avfilter_get_by_name("buffersink"), "out", nullptr, nullptr, clip->filter_graph); + avfilter_graph_create_filter(&clip->buffersrc_ctx, avfilter_get_by_name("buffer"), "in", filter_args, nullptr, clip->filter_graph); + avfilter_graph_create_filter(&clip->buffersink_ctx, avfilter_get_by_name("buffersink"), "out", nullptr, nullptr, clip->filter_graph); - AVFilterContext* last_filter = clip->buffersrc_ctx; + AVFilterContext* last_filter = clip->buffersrc_ctx; - char filter_args[100]; + char filter_args[100]; - if (ms->video_interlacing != VIDEO_PROGRESSIVE) { - AVFilterContext* yadif_filter; - snprintf(filter_args, sizeof(filter_args), "mode=3:parity=%d", ((ms->video_interlacing == VIDEO_TOP_FIELD_FIRST) ? 0 : 1)); // there's a CUDA version if we start using nvdec/nvenc - avfilter_graph_create_filter(&yadif_filter, avfilter_get_by_name("yadif"), "yadif", filter_args, nullptr, clip->filter_graph); + if (ms->video_interlacing != VIDEO_PROGRESSIVE) { + AVFilterContext* yadif_filter; + snprintf(filter_args, sizeof(filter_args), "mode=3:parity=%d", ((ms->video_interlacing == VIDEO_TOP_FIELD_FIRST) ? 0 : 1)); // there's a CUDA version if we start using nvdec/nvenc + avfilter_graph_create_filter(&yadif_filter, avfilter_get_by_name("yadif"), "yadif", filter_args, nullptr, clip->filter_graph); - avfilter_link(last_filter, 0, yadif_filter, 0); - last_filter = yadif_filter; - } + avfilter_link(last_filter, 0, yadif_filter, 0); + last_filter = yadif_filter; + } - // ffmpeg premultiplier - /* - if (!clip->media->to_footage()->alpha_is_premultiplied) { - AVFilterContext* premultiply_filter; - snprintf(filter_args, sizeof(filter_args), "inplace=1"); - avfilter_graph_create_filter(&premultiply_filter, avfilter_get_by_name("premultiply"), "premultiply", filter_args, nullptr, clip->filter_graph); + // ffmpeg premultiplier + /* + if (!clip->media->to_footage()->alpha_is_premultiplied) { + AVFilterContext* premultiply_filter; + snprintf(filter_args, sizeof(filter_args), "inplace=1"); + avfilter_graph_create_filter(&premultiply_filter, avfilter_get_by_name("premultiply"), "premultiply", filter_args, nullptr, clip->filter_graph); - avfilter_link(last_filter, 0, premultiply_filter, 0); - last_filter = premultiply_filter; - } - */ + avfilter_link(last_filter, 0, premultiply_filter, 0); + last_filter = premultiply_filter; + } + */ - /* stabilization code */ - /*bool stabilize = false; - if (stabilize) { - AVFilterContext* stab_filter; - int stab_ret = avfilter_graph_create_filter(&stab_filter, avfilter_get_by_name("vidstabtransform"), "vidstab", "input=/media/matt/Home/samples/transforms.trf", nullptr, clip->filter_graph); + /* stabilization code */ + /*bool stabilize = false; + if (stabilize) { + AVFilterContext* stab_filter; + int stab_ret = avfilter_graph_create_filter(&stab_filter, avfilter_get_by_name("vidstabtransform"), "vidstab", "input=/media/matt/Home/samples/transforms.trf", nullptr, clip->filter_graph); - if (stab_ret < 0) { - char err[100]; - av_strerror(stab_ret, err, sizeof(err)); - } else { - avfilter_link(last_filter, 0, stab_filter, 0); - last_filter = stab_filter; - } - }*/ + if (stab_ret < 0) { + char err[100]; + av_strerror(stab_ret, err, sizeof(err)); + } else { + avfilter_link(last_filter, 0, stab_filter, 0); + last_filter = stab_filter; + } + }*/ - clip->pix_fmt = AV_PIX_FMT_RGBA; - const char* chosen_format = av_get_pix_fmt_name(static_cast(clip->pix_fmt)); - snprintf(filter_args, sizeof(filter_args), "pix_fmts=%s", chosen_format); + clip->pix_fmt = AV_PIX_FMT_RGBA; + const char* chosen_format = av_get_pix_fmt_name(static_cast(clip->pix_fmt)); + snprintf(filter_args, sizeof(filter_args), "pix_fmts=%s", chosen_format); - AVFilterContext* format_conv; - avfilter_graph_create_filter(&format_conv, avfilter_get_by_name("format"), "fmt", filter_args, nullptr, clip->filter_graph); - avfilter_link(last_filter, 0, format_conv, 0); + AVFilterContext* format_conv; + avfilter_graph_create_filter(&format_conv, avfilter_get_by_name("format"), "fmt", filter_args, nullptr, clip->filter_graph); + avfilter_link(last_filter, 0, format_conv, 0); - avfilter_link(format_conv, 0, clip->buffersink_ctx, 0); + avfilter_link(format_conv, 0, clip->buffersink_ctx, 0); - avfilter_graph_config(clip->filter_graph, nullptr); - } else if (clip->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { - if (clip->codecCtx->channel_layout == 0) clip->codecCtx->channel_layout = av_get_default_channel_layout(clip->stream->codecpar->channels); + avfilter_graph_config(clip->filter_graph, nullptr); + } else if (clip->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { + if (clip->codecCtx->channel_layout == 0) clip->codecCtx->channel_layout = av_get_default_channel_layout(clip->stream->codecpar->channels); - // set up cache - clip->queue.append(av_frame_alloc()); -// if (clip->reverse) { - if (true) { - AVFrame* reverse_frame = av_frame_alloc(); + // set up cache + clip->queue.append(av_frame_alloc()); + // if (clip->reverse) { + if (true) { + AVFrame* reverse_frame = av_frame_alloc(); - reverse_frame->format = sample_format; - reverse_frame->nb_samples = current_audio_freq()*2; - reverse_frame->channel_layout = clip->sequence->audio_layout; - reverse_frame->channels = av_get_channel_layout_nb_channels(clip->sequence->audio_layout); - av_frame_get_buffer(reverse_frame, 0); + reverse_frame->format = sample_format; + reverse_frame->nb_samples = current_audio_freq()*2; + reverse_frame->channel_layout = clip->sequence->audio_layout; + reverse_frame->channels = av_get_channel_layout_nb_channels(clip->sequence->audio_layout); + av_frame_get_buffer(reverse_frame, 0); - clip->queue.append(reverse_frame); - } + clip->queue.append(reverse_frame); + } - snprintf(filter_args, sizeof(filter_args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%" PRIx64, - clip->stream->time_base.num, - clip->stream->time_base.den, - clip->stream->codecpar->sample_rate, - av_get_sample_fmt_name(clip->codecCtx->sample_fmt), - clip->codecCtx->channel_layout - ); + snprintf(filter_args, sizeof(filter_args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%" PRIx64, + clip->stream->time_base.num, + clip->stream->time_base.den, + clip->stream->codecpar->sample_rate, + av_get_sample_fmt_name(clip->codecCtx->sample_fmt), + clip->codecCtx->channel_layout + ); - avfilter_graph_create_filter(&clip->buffersrc_ctx, avfilter_get_by_name("abuffer"), "in", filter_args, nullptr, clip->filter_graph); - avfilter_graph_create_filter(&clip->buffersink_ctx, avfilter_get_by_name("abuffersink"), "out", nullptr, nullptr, clip->filter_graph); + avfilter_graph_create_filter(&clip->buffersrc_ctx, avfilter_get_by_name("abuffer"), "in", filter_args, nullptr, clip->filter_graph); + avfilter_graph_create_filter(&clip->buffersink_ctx, avfilter_get_by_name("abuffersink"), "out", nullptr, nullptr, clip->filter_graph); - enum AVSampleFormat sample_fmts[] = { sample_format, static_cast(-1) }; - if (av_opt_set_int_list(clip->buffersink_ctx, "sample_fmts", sample_fmts, -1, AV_OPT_SEARCH_CHILDREN) < 0) { - qCritical() << "Could not set output sample format"; - } + enum AVSampleFormat sample_fmts[] = { sample_format, static_cast(-1) }; + if (av_opt_set_int_list(clip->buffersink_ctx, "sample_fmts", sample_fmts, -1, AV_OPT_SEARCH_CHILDREN) < 0) { + qCritical() << "Could not set output sample format"; + } - int64_t channel_layouts[] = { AV_CH_LAYOUT_STEREO, static_cast(-1) }; - if (av_opt_set_int_list(clip->buffersink_ctx, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN) < 0) { - qCritical() << "Could not set output sample format"; - } + int64_t channel_layouts[] = { AV_CH_LAYOUT_STEREO, static_cast(-1) }; + if (av_opt_set_int_list(clip->buffersink_ctx, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN) < 0) { + qCritical() << "Could not set output sample format"; + } - int target_sample_rate = current_audio_freq(); + int target_sample_rate = current_audio_freq(); - double playback_speed = clip->speed * m->speed; + double playback_speed = clip->speed * m->speed; - if (qFuzzyCompare(playback_speed, 1.0)) { - avfilter_link(clip->buffersrc_ctx, 0, clip->buffersink_ctx, 0); - } else if (clip->maintain_audio_pitch) { - AVFilterContext* previous_filter = clip->buffersrc_ctx; - AVFilterContext* last_filter = clip->buffersrc_ctx; + if (qFuzzyCompare(playback_speed, 1.0)) { + avfilter_link(clip->buffersrc_ctx, 0, clip->buffersink_ctx, 0); + } else if (clip->maintain_audio_pitch) { + AVFilterContext* previous_filter = clip->buffersrc_ctx; + AVFilterContext* last_filter = clip->buffersrc_ctx; - char speed_param[10]; + char speed_param[10]; -// if (playback_speed != 1.0) { - double base = (playback_speed > 1.0) ? 2.0 : 0.5; + // if (playback_speed != 1.0) { + double base = (playback_speed > 1.0) ? 2.0 : 0.5; - double speedlog = log(playback_speed) / log(base); - int whole2 = qFloor(speedlog); - speedlog -= whole2; + double speedlog = log(playback_speed) / log(base); + int whole2 = qFloor(speedlog); + speedlog -= whole2; - if (whole2 > 0) { - snprintf(speed_param, sizeof(speed_param), "%f", base); - for (int i=0;ifilter_graph); - avfilter_link(previous_filter, 0, tempo_filter, 0); - previous_filter = tempo_filter; - } - } + if (whole2 > 0) { + snprintf(speed_param, sizeof(speed_param), "%f", base); + for (int i=0;ifilter_graph); + avfilter_link(previous_filter, 0, tempo_filter, 0); + previous_filter = tempo_filter; + } + } - snprintf(speed_param, sizeof(speed_param), "%f", qPow(base, speedlog)); - last_filter = nullptr; - avfilter_graph_create_filter(&last_filter, avfilter_get_by_name("atempo"), "atempo", speed_param, nullptr, clip->filter_graph); - avfilter_link(previous_filter, 0, last_filter, 0); -// } + snprintf(speed_param, sizeof(speed_param), "%f", qPow(base, speedlog)); + last_filter = nullptr; + avfilter_graph_create_filter(&last_filter, avfilter_get_by_name("atempo"), "atempo", speed_param, nullptr, clip->filter_graph); + avfilter_link(previous_filter, 0, last_filter, 0); + // } - avfilter_link(last_filter, 0, clip->buffersink_ctx, 0); - } else { - target_sample_rate = qRound64(target_sample_rate / playback_speed); - avfilter_link(clip->buffersrc_ctx, 0, clip->buffersink_ctx, 0); - } + avfilter_link(last_filter, 0, clip->buffersink_ctx, 0); + } else { + target_sample_rate = qRound64(target_sample_rate / playback_speed); + avfilter_link(clip->buffersrc_ctx, 0, clip->buffersink_ctx, 0); + } - int sample_rates[] = { target_sample_rate, 0 }; - if (av_opt_set_int_list(clip->buffersink_ctx, "sample_rates", sample_rates, 0, AV_OPT_SEARCH_CHILDREN) < 0) { - qCritical() << "Could not set output sample rates"; - } + int sample_rates[] = { target_sample_rate, 0 }; + if (av_opt_set_int_list(clip->buffersink_ctx, "sample_rates", sample_rates, 0, AV_OPT_SEARCH_CHILDREN) < 0) { + qCritical() << "Could not set output sample rates"; + } - avfilter_graph_config(clip->filter_graph, nullptr); + avfilter_graph_config(clip->filter_graph, nullptr); - clip->audio_reset = true; - } + clip->audio_reset = true; + } - clip->frame = av_frame_alloc(); - } + clip->frame = av_frame_alloc(); + } - for (int i=0;ieffects.size();i++) { - clip->effects.at(i)->open(); - } + for (int i=0;ieffects.size();i++) { + clip->effects.at(i)->open(); + } - clip->finished_opening = true; + clip->finished_opening = true; - qInfo() << "Clip opened on track" << clip->track << "(took" << (QDateTime::currentMSecsSinceEpoch() - time_start) << "ms)"; + qInfo() << "Clip opened on track" << clip->track << "(took" << (QDateTime::currentMSecsSinceEpoch() - time_start) << "ms)"; } void cache_clip_worker(ClipPtr clip, long playhead, bool reset, bool scrubbing, QVector nests, int playback_speed) { - if (reset) { - // note: for video, playhead is in "internal clip" frames - for audio, it's the timeline playhead - reset_cache(clip, playhead, playback_speed); - clip->audio_reset = false; - } + if (reset) { + // note: for video, playhead is in "internal clip" frames - for audio, it's the timeline playhead + reset_cache(clip, playhead, playback_speed); + clip->audio_reset = false; + } - if (clip->media == nullptr) { - if (clip->track >= 0) { - cache_audio_worker(clip, scrubbing, nests, playback_speed); - } - } else if (clip->media->get_type() == MEDIA_TYPE_FOOTAGE) { - if (clip->stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { - cache_video_worker(clip, playhead); - } else if (clip->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { - cache_audio_worker(clip, scrubbing, nests, playback_speed); - } - } + if (clip->media == nullptr) { + if (clip->track >= 0) { + cache_audio_worker(clip, scrubbing, nests, playback_speed); + } + } else if (clip->media->get_type() == MEDIA_TYPE_FOOTAGE) { + if (clip->stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + cache_video_worker(clip, playhead); + } else if (clip->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { + cache_audio_worker(clip, scrubbing, nests, playback_speed); + } + } } void close_clip_worker(ClipPtr clip) { - clip->finished_opening = false; + clip->finished_opening = false; - if (clip->media != nullptr && clip->media->get_type() == MEDIA_TYPE_FOOTAGE) { - clip->queue_clear(); + if (clip->media != nullptr && clip->media->get_type() == MEDIA_TYPE_FOOTAGE) { + clip->queue_clear(); - avfilter_graph_free(&clip->filter_graph); + avfilter_graph_free(&clip->filter_graph); - avcodec_close(clip->codecCtx); - avcodec_free_context(&clip->codecCtx); + avcodec_close(clip->codecCtx); + avcodec_free_context(&clip->codecCtx); - av_dict_free(&clip->opts); + av_dict_free(&clip->opts); - avformat_close_input(&clip->formatCtx); - } + avformat_close_input(&clip->formatCtx); + } - av_frame_free(&clip->frame); + av_frame_free(&clip->frame); - clip->reset(); + clip->reset(); - qInfo() << "Clip closed on track" << clip->track; + qInfo() << "Clip closed on track" << clip->track; } void Cacher::run() { - // open_lock is used to prevent the clip from being destroyed before the cacher has closed it properly - clip->lock.lock(); - clip->finished_opening = false; - clip->open = true; - caching = true; - interrupt = false; - queued = false; + // open_lock is used to prevent the clip from being destroyed before the cacher has closed it properly + clip->lock.lock(); + clip->finished_opening = false; + clip->open = true; + caching = true; + interrupt = false; + queued = false; - open_clip_worker(clip); + open_clip_worker(clip); - while (caching) { - if (!queued) clip->can_cache.wait(&clip->lock); - queued = false; - if (!caching) { - break; - } else { - while (true) { - cache_clip_worker(clip, playhead, reset, scrubbing, nests, playback_speed); - if (clip->multithreaded && clip->cacher->interrupt && clip->track < 0) { - clip->cacher->interrupt = false; - } else { - break; - } - } - } - } + while (caching) { + if (!queued) clip->can_cache.wait(&clip->lock); + queued = false; + if (!caching) { + break; + } else { + while (true) { + cache_clip_worker(clip, playhead, reset, scrubbing, nests, playback_speed); + if (clip->multithreaded && clip->cacher->interrupt && clip->track < 0) { + clip->cacher->interrupt = false; + } else { + break; + } + } + } + } - close_clip_worker(clip); + close_clip_worker(clip); - clip->lock.unlock(); - clip->open_lock.unlock(); + clip->lock.unlock(); + clip->open_lock.unlock(); } diff --git a/playback/playback.cpp b/playback/playback.cpp index e8225625a..000fb1735 100644 --- a/playback/playback.cpp +++ b/playback/playback.cpp @@ -85,6 +85,9 @@ void open_clip(ClipPtr clip, bool multithreaded) { } void close_clip(ClipPtr clip, bool wait) { + // render lock prevents crashes if this function tries to delete a texture while the RenderThread is rendering it + clip->render_lock.lock(); + clip->finished_opening = false; // destroy opengl texture in main thread @@ -126,6 +129,8 @@ void close_clip(ClipPtr clip, bool wait) { clip->open = false; } + + clip->render_lock.unlock(); } void cache_clip(ClipPtr clip, long playhead, bool reset, bool scrubbing, QVector& nests, int playback_speed) { diff --git a/project/clip.cpp b/project/clip.cpp index 4b0a2e80c..ca333f977 100644 --- a/project/clip.cpp +++ b/project/clip.cpp @@ -85,15 +85,6 @@ ClipPtr Clip::copy(SequencePtr s, bool duplicate_transitions) { copy->cached_fr = (this->sequence == nullptr) ? cached_fr : this->sequence->frame_rate; - if (duplicate_transitions) { - if (get_opening_transition() != nullptr && get_opening_transition()->secondary_clip == nullptr) { - copy->opening_transition = get_opening_transition()->copy(copy, nullptr); - } - if (get_closing_transition() != nullptr && get_closing_transition()->secondary_clip == nullptr) { - copy->closing_transition = get_closing_transition()->copy(copy, nullptr); - } - } - copy->recalculateMaxLength(); return copy; diff --git a/project/clip.h b/project/clip.h index 0644cf43c..873caad46 100644 --- a/project/clip.h +++ b/project/clip.h @@ -129,6 +129,7 @@ public: int max_queue_size; QVector queue; QMutex queue_lock; + QMutex render_lock; QMutex lock; QMutex open_lock; int64_t last_invalid_ts; diff --git a/project/undo.cpp b/project/undo.cpp index 5a0a998f2..205769599 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -284,6 +284,7 @@ void AddTransitionCommand::doRedo() { ModifyTransitionCommand::ModifyTransitionCommand(TransitionPtr t, long ilength) { transition_ref_ = t; new_length_ = ilength; + old_length_ = transition_ref_->get_true_length(); } void ModifyTransitionCommand::doUndo() { @@ -291,7 +292,7 @@ void ModifyTransitionCommand::doUndo() { } void ModifyTransitionCommand::doRedo() { - old_length_ = transition_ref_->get_true_length(); + transition_ref_->set_length(new_length_); } @@ -395,6 +396,7 @@ void DeleteMediaCommand::doRedo() { } AddClipCommand::AddClipCommand(SequencePtr s, QVector& add) { + link_offset_ = 0; seq = s; clips = add; } @@ -402,44 +404,48 @@ AddClipCommand::AddClipCommand(SequencePtr s, QVector& add) { AddClipCommand::~AddClipCommand() {} void AddClipCommand::doUndo() { + // clear effects panel panel_effect_controls->clear_effects(true); + for (int i=0;iclips.last(); - panel_timeline->deselect_area(c->timeline_in, c->timeline_out, c->track); - undone_clips.prepend(c); - if (c->open) close_clip(c, true); + + if (c != nullptr) { + // un-offset all the clips + for (int j=0;jlinked.size();j++) { + c->linked[j] -= link_offset_; + } + + // deselect the area occupied by this clip + panel_timeline->deselect_area(c->timeline_in, c->timeline_out, c->track); + + // if the clip is open, close it + if (c->open) { + close_clip(c, true); + } + } + + // remove it from the sequence seq->clips.removeLast(); } } void AddClipCommand::doRedo() { - if (undone_clips.size() > 0) { - for (int i=0;iclips.append(undone_clips.at(i)); - } - undone_clips.clear(); - } else { - int linkOffset = seq->clips.size(); - for (int i=0;icopy(seq); - copy->linked.resize(original->linked.size()); - for (int j=0;jlinked.size();j++) { - copy->linked[j] = original->linked.at(j) + linkOffset; - } - if (original->opening_transition != nullptr) { - copy->opening_transition = original->get_opening_transition()->copy(copy, nullptr); - } - if (original->closing_transition != nullptr) { - copy->closing_transition = original->get_closing_transition()->copy(copy, nullptr); - } - seq->clips.append(copy); - } else { - seq->clips.append(nullptr); + link_offset_ = seq->clips.size(); + for (int i=0;ilinked.size();j++) { + original->linked[j] += link_offset_; } + } + + seq->clips.append(original); } } diff --git a/project/undo.h b/project/undo.h index 0ec1d1005..44ff615de 100644 --- a/project/undo.h +++ b/project/undo.h @@ -236,7 +236,7 @@ public: private: SequencePtr seq; QVector clips; - QVector undone_clips; + int link_offset_; }; class LinkCommand : public OliveAction { diff --git a/ui/renderfunctions.cpp b/ui/renderfunctions.cpp index d1c732f2a..d6bb29abb 100644 --- a/ui/renderfunctions.cpp +++ b/ui/renderfunctions.cpp @@ -44,601 +44,607 @@ #include "panels/viewer.h" extern "C" { - #include +#include } void full_blit() { - glPushMatrix(); - glLoadIdentity(); - glOrtho(0, 1, 0, 1, -1, 1); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, 1, 0, 1, -1, 1); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); // top left - glVertex2f(0, 0); // top left - glTexCoord2f(1, 0); // top right - glVertex2f(1, 0); // top right - glTexCoord2f(1, 1); // bottom right - glVertex2f(1, 1); // bottom right - glTexCoord2f(0, 1); // bottom left - glVertex2f(0, 1); // bottom left - glEnd(); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); // top left + glVertex2f(0, 0); // top left + glTexCoord2f(1, 0); // top right + glVertex2f(1, 0); // top right + glTexCoord2f(1, 1); // bottom right + glVertex2f(1, 1); // bottom right + glTexCoord2f(0, 1); // bottom left + glVertex2f(0, 1); // bottom left + glEnd(); - glPopMatrix(); + glPopMatrix(); } void draw_clip(QOpenGLContext* ctx, GLuint fbo, GLuint texture, bool clear) { - ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); + ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); - if (clear) { - glClear(GL_COLOR_BUFFER_BIT); - } + if (clear) { + glClear(GL_COLOR_BUFFER_BIT); + } - glBindTexture(GL_TEXTURE_2D, texture); + glBindTexture(GL_TEXTURE_2D, texture); - full_blit(); + full_blit(); - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_2D, 0); - ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } GLuint draw_clip(QOpenGLFramebufferObject* fbo, GLuint texture, bool clear) { - fbo->bind(); + fbo->bind(); - if (clear) { - glClear(GL_COLOR_BUFFER_BIT); - } + if (clear) { + glClear(GL_COLOR_BUFFER_BIT); + } - glBindTexture(GL_TEXTURE_2D, texture); + glBindTexture(GL_TEXTURE_2D, texture); - full_blit(); + full_blit(); - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_2D, 0); - fbo->release(); + fbo->release(); - return fbo->texture(); + return fbo->texture(); } void process_effect(ClipPtr c, EffectPtr e, - double timecode, - GLTextureCoords& coords, - GLuint& composite_texture, - bool& fbo_switcher, - bool& texture_failed, - int data) { - if (e->is_enabled()) { - if (e->enable_coords) { - e->process_coords(timecode, coords, data); - } - bool can_process_shaders = (e->enable_shader && olive::CurrentRuntimeConfig.shaders_are_enabled); - if (can_process_shaders || e->enable_superimpose) { - e->startEffect(); - if (can_process_shaders && e->is_glsl_linked()) { - for (int i=0;igetIterations();i++) { - e->process_shader(timecode, coords, i); - composite_texture = draw_clip(c->fbo[fbo_switcher], composite_texture, true); - fbo_switcher = !fbo_switcher; - } - } - if (e->enable_superimpose) { - GLuint superimpose_texture = e->process_superimpose(timecode); + double timecode, + GLTextureCoords& coords, + GLuint& composite_texture, + bool& fbo_switcher, + bool& texture_failed, + int data) { + if (e->is_enabled()) { + if (e->enable_coords) { + e->process_coords(timecode, coords, data); + } + bool can_process_shaders = (e->enable_shader && olive::CurrentRuntimeConfig.shaders_are_enabled); + if (can_process_shaders || e->enable_superimpose) { + e->startEffect(); + if (can_process_shaders && e->is_glsl_linked()) { + for (int i=0;igetIterations();i++) { + e->process_shader(timecode, coords, i); + composite_texture = draw_clip(c->fbo[fbo_switcher], composite_texture, true); + fbo_switcher = !fbo_switcher; + } + } + if (e->enable_superimpose) { + GLuint superimpose_texture = e->process_superimpose(timecode); - if (superimpose_texture == 0) { - qWarning() << "Superimpose texture was nullptr, retrying..."; - texture_failed = true; - } else if (composite_texture == 0) { - // if there is no previous texture, just return the superimposes texture - // UNLESS this is a shader-extended superimpose effect in which case, - // we'll need to draw it below - composite_texture = superimpose_texture; - } else { - // if the source texture is not already a framebuffer texture, - // we'll need to make it one before drawing a superimpose effect on it - if (composite_texture != c->fbo[0]->texture() && composite_texture != c->fbo[1]->texture()) { - draw_clip(c->fbo[!fbo_switcher], composite_texture, true); - } + if (superimpose_texture == 0) { + qWarning() << "Superimpose texture was nullptr, retrying..."; + texture_failed = true; + } else if (composite_texture == 0) { + // if there is no previous texture, just return the superimposes texture + // UNLESS this is a shader-extended superimpose effect in which case, + // we'll need to draw it below + composite_texture = superimpose_texture; + } else { + // if the source texture is not already a framebuffer texture, + // we'll need to make it one before drawing a superimpose effect on it + if (composite_texture != c->fbo[0]->texture() && composite_texture != c->fbo[1]->texture()) { + draw_clip(c->fbo[!fbo_switcher], composite_texture, true); + } - composite_texture = draw_clip(c->fbo[!fbo_switcher], superimpose_texture, false); - } - } - e->endEffect(); - } - } + composite_texture = draw_clip(c->fbo[!fbo_switcher], superimpose_texture, false); + } + } + e->endEffect(); + } + } } GLuint compose_sequence(ComposeSequenceParams ¶ms) { - GLuint final_fbo = params.main_buffer; + GLuint final_fbo = params.main_buffer; - SequencePtr s = params.seq; - long playhead = s->playhead; + SequencePtr s = params.seq; + long playhead = s->playhead; - if (!params.nests.isEmpty()) { - for (int i=0;imedia->to_sequence(); - playhead += params.nests.at(i)->clip_in - params.nests.at(i)->get_timeline_in_with_transition(); - playhead = refactor_frame_number(playhead, params.nests.at(i)->sequence->frame_rate, s->frame_rate); - } + if (!params.nests.isEmpty()) { + for (int i=0;imedia->to_sequence(); + playhead += params.nests.at(i)->clip_in - params.nests.at(i)->get_timeline_in_with_transition(); + playhead = refactor_frame_number(playhead, params.nests.at(i)->sequence->frame_rate, s->frame_rate); + } - if (params.video && params.nests.last()->fbo != nullptr) { - params.nests.last()->fbo[0]->bind(); - glClear(GL_COLOR_BUFFER_BIT); - final_fbo = params.nests.last()->fbo[0]->handle(); - } - } + if (params.video && params.nests.last()->fbo != nullptr) { + params.nests.last()->fbo[0]->bind(); + glClear(GL_COLOR_BUFFER_BIT); + final_fbo = params.nests.last()->fbo[0]->handle(); + } + } - int audio_track_count = 0; + int audio_track_count = 0; - QVector current_clips; + QVector current_clips; - // loop through clips, find currently active, and sort by track - for (int i=0;iclips.size();i++) { + // loop through clips, find currently active, and sort by track + for (int i=0;iclips.size();i++) { - ClipPtr c = s->clips.at(i); + ClipPtr c = s->clips.at(i); - if (c != nullptr) { + if (c != nullptr) { - // if clip is video and we're processing video - if ((c->track < 0) == params.video) { + // if clip is video and we're processing video + if ((c->track < 0) == params.video) { - bool clip_is_active = false; + bool clip_is_active = false; - // is the clip a "footage" clip? - if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { - FootagePtr m = c->media->to_footage(); + // is the clip a "footage" clip? + if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { + FootagePtr m = c->media->to_footage(); - // does the clip have a valid media source? - if (!m->invalid && !(c->track >= 0 && !is_audio_device_set())) { + // does the clip have a valid media source? + if (!m->invalid && !(c->track >= 0 && !is_audio_device_set())) { - // is the media process and ready? - if (m->ready) { - const FootageStream* ms = m->get_stream_from_file_index(c->track < 0, c->media_stream); + // is the media process and ready? + if (m->ready) { + const FootageStream* ms = m->get_stream_from_file_index(c->track < 0, c->media_stream); - // does the media have a valid media stream source and is it active? - if (ms != nullptr && is_clip_active(c, playhead)) { + // does the media have a valid media stream source and is it active? + if (ms != nullptr && is_clip_active(c, playhead)) { - // open if not open - if (!c->open) { - open_clip(c, !params.single_threaded); - } - - clip_is_active = true; - - // increment audio track count - if (c->track >= 0) audio_track_count++; - - } else if (c->finished_opening) { - - // close the clip if it isn't active anymore - close_clip(c, false); - - } - } else { - - // media wasn't ready, schedule a redraw - params.texture_failed = true; - - } - } - } else { - // if the clip is a nested sequence or null clip, just open it - - if (is_clip_active(c, playhead)) { - if (!c->open) open_clip(c, !params.single_threaded); - clip_is_active = true; - } else if (c->finished_opening) { - close_clip(c, false); - } - } - - // if the clip is active, added it to "current_clips", sorted by track - if (clip_is_active) { - bool added = false; - - // track sorting is only necessary for video clips - // audio clips are mixed equally, so we skip sorting for those - if (params.video) { - - // insertion sort by track - for (int j=0;jtrack < c->track) { - current_clips.insert(j, c); - added = true; - break; - } - } - - } - - if (!added) { - current_clips.append(c); - } - } - } - } - } - - if (params.video) { - // set default coordinates based on the sequence, with 0 in the direct center - glPushMatrix(); - glLoadIdentity(); - - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - - int half_width = s->width/2; - int half_height = s->height/2; - glOrtho(-half_width, half_width, -half_height, half_height, -1, 10); - } - - // loop through current clips - for (int i=0;imedia != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE && !c->finished_opening) { - qWarning() << "Tried to display clip" << i << "but it's closed"; - params.texture_failed = true; - } else { - // if clip is a video clip - if (c->track < 0) { - // reset OpenGL to full color - glColor4f(1.0, 1.0, 1.0, 1.0); - - // textureID variable contains texture to be drawn on screen at the end - GLuint textureID = 0; - - // store video source dimensions - int video_width = c->getWidth(); - int video_height = c->getHeight(); - - // if media is footage - if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { - - if (c->texture == nullptr) { - // opengl texture doesn't exist yet, create it - - c->texture = new QOpenGLTexture(QOpenGLTexture::Target2D); - c->texture->setSize(c->stream->codecpar->width, c->stream->codecpar->height); - c->texture->setFormat(QOpenGLTexture::RGBA8_UNorm); - c->texture->setMipLevels(c->texture->maximumMipLevels()); - c->texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear); - c->texture->allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8); - } - - // retrieve video frame from cache and store it in c->texture - get_clip_frame(c, qMax(playhead, c->timeline_in), params.texture_failed); - - // retrieve ID from c->texture - textureID = c->texture->textureId(); - - if (textureID == 0) { - qWarning() << "Failed to create texture"; - return 0; - } - } - - // prepare framebuffers for backend drawing operations - if (c->fbo == nullptr) { - // create 3 fbos for nested sequences, 2 for most clips - int fbo_count = (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) ? 3 : 2; - - c->fbo = new QOpenGLFramebufferObject* [size_t(fbo_count)]; - - for (int j=0;jfbo[j] = new QOpenGLFramebufferObject(video_width, video_height); - } - } - - // if clip should actually be shown on screen in this frame - if (playhead >= c->get_timeline_in_with_transition() - && playhead < c->get_timeline_out_with_transition()) { - glPushMatrix(); - - // simple bool for switching between the two framebuffers - bool fbo_switcher = false; - - glViewport(0, 0, video_width, video_height); - - if (c->media != nullptr) { - if (c->media->get_type() == MEDIA_TYPE_SEQUENCE) { - // for a nested sequence, run this function again on that sequence and retrieve the texture - - // add nested sequence to nest list - params.nests.append(c); - - // compose sequence - textureID = compose_sequence(params); - - // remove sequence from nest list - params.nests.removeLast(); - - // compose_sequence() would have written to this clip's fbo[0], so we switch to fbo[1] - fbo_switcher = true; - } else if (c->media->get_type() == MEDIA_TYPE_FOOTAGE && !c->media->to_footage()->alpha_is_premultiplied) { - // alpha is not premultiplied, we'll need to premultiply it for the rest of the pipeline - params.premultiply_program->bind(); - - textureID = draw_clip(c->fbo[0], textureID, true); - - params.premultiply_program->release(); - - fbo_switcher = true; - } - } - - // set up default coordinates for drawing the clip - GLTextureCoords coords; - coords.grid_size = 1; - coords.vertexTopLeftX = coords.vertexBottomLeftX = -video_width/2; - coords.vertexTopLeftY = coords.vertexTopRightY = -video_height/2; - coords.vertexTopRightX = coords.vertexBottomRightX = video_width/2; - coords.vertexBottomLeftY = coords.vertexBottomRightY = video_height/2; - coords.vertexBottomLeftZ = coords.vertexBottomRightZ = coords.vertexTopLeftZ = coords.vertexTopRightZ = 1; - coords.textureTopLeftY = coords.textureTopRightY = coords.textureTopLeftX = coords.textureBottomLeftX = 0.0; - coords.textureBottomLeftY = coords.textureBottomRightY = coords.textureTopRightX = coords.textureBottomRightX = 1.0; - coords.textureTopLeftQ = coords.textureTopRightQ = coords.textureTopLeftQ = coords.textureBottomLeftQ = 1; - coords.blendmode = BLEND_MODE_NORMAL; - coords.opacity = 1.0; - - // if auto-scale is enabled, auto-scale the clip - if (c->autoscale && (video_width != s->width && video_height != s->height)) { - float width_multiplier = float(s->width) / float(video_width); - float height_multiplier = float(s->height) / float(video_height); - float scale_multiplier = qMin(width_multiplier, height_multiplier); - glScalef(scale_multiplier, scale_multiplier, 1); - } - - // == EFFECT CODE START == - - // get current sequence time in seconds (used for effects) - double timecode = get_timecode(c, playhead); - - // set up variables for gizmos later - EffectPtr first_gizmo_effect = nullptr; - EffectPtr selected_effect = nullptr; - - // run through all of the clip's effects - for (int j=0;jeffects.size();j++) { - EffectPtr e = c->effects.at(j); - process_effect(c, e, timecode, coords, textureID, fbo_switcher, params.texture_failed, kTransitionNone); - - // retrieve gizmo data from effect - if (e->are_gizmos_enabled()) { - if (first_gizmo_effect == nullptr) first_gizmo_effect = e; - if (e->container->selected) selected_effect = e; - } - } - - // using gizmo data, set definitive gizmo - if (selected_effect != nullptr) { - (*params.gizmos) = selected_effect; - } else if (is_clip_selected(c, true)) { - (*params.gizmos) = first_gizmo_effect; - } - - // if the clip has an opening transition, process that now - if (c->get_opening_transition() != nullptr) { - int transition_progress = playhead - c->get_timeline_in_with_transition(); - if (transition_progress < c->get_opening_transition()->get_length()) { - process_effect(c, c->get_opening_transition(), double(transition_progress)/double(c->get_opening_transition()->get_length()), coords, textureID, fbo_switcher, params.texture_failed, kTransitionOpening); - } - } - - // if the clip has a closing transition, process that now - if (c->get_closing_transition() != nullptr) { - int transition_progress = playhead - (c->get_timeline_out_with_transition() - c->get_closing_transition()->get_length()); - if (transition_progress >= 0 && transition_progress < c->get_closing_transition()->get_length()) { - process_effect(c, c->get_closing_transition(), double(transition_progress)/double(c->get_closing_transition()->get_length()), coords, textureID, fbo_switcher, params.texture_failed, kTransitionClosing); - } - } - - // == EFFECT CODE END == - - if (textureID > 0) { - // set viewport to sequence size - params.ctx->functions()->glViewport(0, 0, s->width, s->height); - - - - // == START RENDER CLIP IN CONTEXT OF SEQUENCE == - - - - // use clip textures for nested sequences, otherwise use main frame buffers - GLuint back_buffer_1; - GLuint backend_tex_1; - GLuint backend_tex_2; - if (params.nests.size() > 0) { - back_buffer_1 = params.nests.last()->fbo[1]->handle(); - backend_tex_1 = params.nests.last()->fbo[1]->texture(); - backend_tex_2 = params.nests.last()->fbo[2]->texture(); - } else { - back_buffer_1 = params.backend_buffer1; - backend_tex_1 = params.backend_attachment1; - backend_tex_2 = params.backend_attachment2; - } - - // render a backbuffer - params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, back_buffer_1); - - glClearColor(0.0, 0.0, 0.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - // bind final clip texture - glBindTexture(GL_TEXTURE_2D, textureID); - - // set texture filter to bilinear - params.ctx->functions()->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - params.ctx->functions()->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - // draw clip on screen according to gl coordinates - glBegin(GL_QUADS); - - glTexCoord2f(coords.textureTopLeftX, coords.textureTopLeftY); // top left - glVertex2f(coords.vertexTopLeftX, coords.vertexTopLeftY); // top left - glTexCoord2f(coords.textureTopRightX, coords.textureTopRightY); // top right - glVertex2f(coords.vertexTopRightX, coords.vertexTopRightY); // top right - glTexCoord2f(coords.textureBottomRightX, coords.textureBottomRightY); // bottom right - glVertex2f(coords.vertexBottomRightX, coords.vertexBottomRightY); // bottom right - glTexCoord2f(coords.textureBottomLeftX, coords.textureBottomLeftY); // bottom left - glVertex2f(coords.vertexBottomLeftX, coords.vertexBottomLeftY); // bottom left - - glEnd(); - - // release final clip texture - glBindTexture(GL_TEXTURE_2D, 0); - - params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - - - - // == END RENDER CLIP IN CONTEXT OF SEQUENCE == - - - - // - // - // PROCESS POST-SHADERS - // - // - - - - // copy front buffer to back buffer (only if we're using blending modes - which we usually will be) - if (!olive::CurrentRuntimeConfig.disable_blending) { - if (params.nests.size() > 0) { - draw_clip(params.ctx, params.nests.last()->fbo[2]->handle(), params.nests.last()->fbo[0]->texture(), true); - } else { - draw_clip(params.ctx, params.backend_buffer2, params.main_attachment, true); - } - } - - - - // == START FINAL DRAW ON SEQUENCE BUFFER == - - - - // bind front buffer as draw buffer - params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, final_fbo); - - if (olive::CurrentRuntimeConfig.disable_blending) { - // some GPUs don't like the blending shader, so we provide a pure GL fallback here - - params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, backend_tex_1); - - glColor4f(coords.opacity, coords.opacity, coords.opacity, coords.opacity); - - full_blit(); - - params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0); - } else { - // load background texture into texture unit 0 - params.ctx->functions()->glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0 - params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, backend_tex_2); - - // load foreground texture into texture unit 1 - params.ctx->functions()->glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1 - params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, backend_tex_1); - - // bind and configure blending mode shader - params.blend_mode_program->bind(); - params.blend_mode_program->setUniformValue("blendmode", coords.blendmode); - params.blend_mode_program->setUniformValue("opacity", coords.opacity); - params.blend_mode_program->setUniformValue("background", 0); - params.blend_mode_program->setUniformValue("foreground", 1); - - glClear(GL_COLOR_BUFFER_BIT); - - full_blit(); - - // release blend mode shader - params.blend_mode_program->release(); - - // unbind texture from texture unit 1 - params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0); - - // unbind texture from texture unit 0 - params.ctx->functions()->glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0 - params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0); - } - - // unbind framebuffer - params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - - - - // == END FINAL DRAW ON SEQUENCE BUFFER == - } - - // prepare gizmos - if ((*params.gizmos) != nullptr - && params.nests.isEmpty() - && ((*params.gizmos) == first_gizmo_effect - || (*params.gizmos) == selected_effect)) { - (*params.gizmos)->gizmo_draw(timecode, coords); // set correct gizmo coords - (*params.gizmos)->gizmo_world_to_screen(); // convert gizmo coords to screen coords - } - - glPopMatrix(); - } - } else { - if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) { - params.nests.append(c); - compose_sequence(params); - params.nests.removeLast(); - } else { - if (c->lock.tryLock()) { - // Check whether cacher is currently active, if not activate it now - - cache_clip(c, playhead, c->audio_reset, (params.viewer != nullptr && !params.viewer->playing), params.nests, params.playback_speed); - c->lock.unlock(); - } + // open if not open + if (!c->open) { + open_clip(c, !params.single_threaded); } - // visually update all the keyframe values - if (c->sequence == params.seq) { // only if you can currently see them - double ts = (playhead - c->get_timeline_in_with_transition() + c->get_clip_in_with_transition())/s->frame_rate; - for (int i=0;ieffects.size();i++) { - EffectPtr e = c->effects.at(i); - for (int j=0;jrow_count();j++) { - EffectRow* r = e->row(j); - for (int k=0;kfieldCount();k++) { - r->field(k)->validate_keyframe_data(ts); - } - } - } - } - } - } - } + clip_is_active = true; - if (audio_track_count == 0 && params.viewer != nullptr) { - params.viewer->play_wake(); - } + // increment audio track count + if (c->track >= 0) audio_track_count++; - if (params.video) { - glPopMatrix(); - } + } else if (c->finished_opening) { - if (!params.nests.isEmpty() && params.nests.last()->fbo != nullptr) { - // returns nested clip's texture - return params.nests.last()->fbo[0]->texture(); - } + // close the clip if it isn't active anymore + close_clip(c, false); - return 0; + } + } else { + + // media wasn't ready, schedule a redraw + params.texture_failed = true; + + } + } + } else { + // if the clip is a nested sequence or null clip, just open it + + if (is_clip_active(c, playhead)) { + if (!c->open) open_clip(c, !params.single_threaded); + clip_is_active = true; + } else if (c->finished_opening) { + close_clip(c, false); + } + } + + // if the clip is active, added it to "current_clips", sorted by track + if (clip_is_active) { + bool added = false; + + // track sorting is only necessary for video clips + // audio clips are mixed equally, so we skip sorting for those + if (params.video) { + + // insertion sort by track + for (int j=0;jtrack < c->track) { + current_clips.insert(j, c); + added = true; + break; + } + } + + } + + if (!added) { + current_clips.append(c); + } + } + } + } + } + + if (params.video) { + // set default coordinates based on the sequence, with 0 in the direct center + glPushMatrix(); + glLoadIdentity(); + + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + int half_width = s->width/2; + int half_height = s->height/2; + glOrtho(-half_width, half_width, -half_height, half_height, -1, 10); + } + + // loop through current clips + for (int i=0;imedia != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE && !c->finished_opening) { + qWarning() << "Tried to display clip" << i << "but it's closed"; + params.texture_failed = true; + } else { + + c->render_lock.lock(); + + // if clip is a video clip + if (c->track < 0) { + // reset OpenGL to full color + glColor4f(1.0, 1.0, 1.0, 1.0); + + // textureID variable contains texture to be drawn on screen at the end + GLuint textureID = 0; + + // store video source dimensions + int video_width = c->getWidth(); + int video_height = c->getHeight(); + + // if media is footage + if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { + + if (c->texture == nullptr) { + // opengl texture doesn't exist yet, create it + + c->texture = new QOpenGLTexture(QOpenGLTexture::Target2D); + c->texture->setSize(c->stream->codecpar->width, c->stream->codecpar->height); + c->texture->setFormat(QOpenGLTexture::RGBA8_UNorm); + c->texture->setMipLevels(c->texture->maximumMipLevels()); + c->texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear); + c->texture->allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8); + } + + // retrieve video frame from cache and store it in c->texture + get_clip_frame(c, qMax(playhead, c->timeline_in), params.texture_failed); + + // retrieve ID from c->texture + textureID = c->texture->textureId(); + + if (textureID == 0) { + qWarning() << "Failed to create texture"; + return 0; + } + } + + // prepare framebuffers for backend drawing operations + if (c->fbo == nullptr) { + // create 3 fbos for nested sequences, 2 for most clips + int fbo_count = (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) ? 3 : 2; + + c->fbo = new QOpenGLFramebufferObject* [size_t(fbo_count)]; + + for (int j=0;jfbo[j] = new QOpenGLFramebufferObject(video_width, video_height); + } + } + + // if clip should actually be shown on screen in this frame + if (playhead >= c->get_timeline_in_with_transition() + && playhead < c->get_timeline_out_with_transition()) { + glPushMatrix(); + + // simple bool for switching between the two framebuffers + bool fbo_switcher = false; + + glViewport(0, 0, video_width, video_height); + + if (c->media != nullptr) { + if (c->media->get_type() == MEDIA_TYPE_SEQUENCE) { + // for a nested sequence, run this function again on that sequence and retrieve the texture + + // add nested sequence to nest list + params.nests.append(c); + + // compose sequence + textureID = compose_sequence(params); + + // remove sequence from nest list + params.nests.removeLast(); + + // compose_sequence() would have written to this clip's fbo[0], so we switch to fbo[1] + fbo_switcher = true; + } else if (c->media->get_type() == MEDIA_TYPE_FOOTAGE && !c->media->to_footage()->alpha_is_premultiplied) { + // alpha is not premultiplied, we'll need to premultiply it for the rest of the pipeline + params.premultiply_program->bind(); + + textureID = draw_clip(c->fbo[0], textureID, true); + + params.premultiply_program->release(); + + fbo_switcher = true; + } + } + + // set up default coordinates for drawing the clip + GLTextureCoords coords; + coords.grid_size = 1; + coords.vertexTopLeftX = coords.vertexBottomLeftX = -video_width/2; + coords.vertexTopLeftY = coords.vertexTopRightY = -video_height/2; + coords.vertexTopRightX = coords.vertexBottomRightX = video_width/2; + coords.vertexBottomLeftY = coords.vertexBottomRightY = video_height/2; + coords.vertexBottomLeftZ = coords.vertexBottomRightZ = coords.vertexTopLeftZ = coords.vertexTopRightZ = 1; + coords.textureTopLeftY = coords.textureTopRightY = coords.textureTopLeftX = coords.textureBottomLeftX = 0.0; + coords.textureBottomLeftY = coords.textureBottomRightY = coords.textureTopRightX = coords.textureBottomRightX = 1.0; + coords.textureTopLeftQ = coords.textureTopRightQ = coords.textureTopLeftQ = coords.textureBottomLeftQ = 1; + coords.blendmode = BLEND_MODE_NORMAL; + coords.opacity = 1.0; + + // if auto-scale is enabled, auto-scale the clip + if (c->autoscale && (video_width != s->width && video_height != s->height)) { + float width_multiplier = float(s->width) / float(video_width); + float height_multiplier = float(s->height) / float(video_height); + float scale_multiplier = qMin(width_multiplier, height_multiplier); + glScalef(scale_multiplier, scale_multiplier, 1); + } + + // == EFFECT CODE START == + + // get current sequence time in seconds (used for effects) + double timecode = get_timecode(c, playhead); + + // set up variables for gizmos later + EffectPtr first_gizmo_effect = nullptr; + EffectPtr selected_effect = nullptr; + + // run through all of the clip's effects + for (int j=0;jeffects.size();j++) { + EffectPtr e = c->effects.at(j); + process_effect(c, e, timecode, coords, textureID, fbo_switcher, params.texture_failed, kTransitionNone); + + // retrieve gizmo data from effect + if (e->are_gizmos_enabled()) { + if (first_gizmo_effect == nullptr) first_gizmo_effect = e; + if (e->container->selected) selected_effect = e; + } + } + + // using gizmo data, set definitive gizmo + if (selected_effect != nullptr) { + (*params.gizmos) = selected_effect; + } else if (is_clip_selected(c, true)) { + (*params.gizmos) = first_gizmo_effect; + } + + // if the clip has an opening transition, process that now + if (c->get_opening_transition() != nullptr) { + int transition_progress = playhead - c->get_timeline_in_with_transition(); + if (transition_progress < c->get_opening_transition()->get_length()) { + process_effect(c, c->get_opening_transition(), double(transition_progress)/double(c->get_opening_transition()->get_length()), coords, textureID, fbo_switcher, params.texture_failed, kTransitionOpening); + } + } + + // if the clip has a closing transition, process that now + if (c->get_closing_transition() != nullptr) { + int transition_progress = playhead - (c->get_timeline_out_with_transition() - c->get_closing_transition()->get_length()); + if (transition_progress >= 0 && transition_progress < c->get_closing_transition()->get_length()) { + process_effect(c, c->get_closing_transition(), double(transition_progress)/double(c->get_closing_transition()->get_length()), coords, textureID, fbo_switcher, params.texture_failed, kTransitionClosing); + } + } + + // == EFFECT CODE END == + + if (textureID > 0) { + // set viewport to sequence size + params.ctx->functions()->glViewport(0, 0, s->width, s->height); + + + + // == START RENDER CLIP IN CONTEXT OF SEQUENCE == + + + + // use clip textures for nested sequences, otherwise use main frame buffers + GLuint back_buffer_1; + GLuint backend_tex_1; + GLuint backend_tex_2; + if (params.nests.size() > 0) { + back_buffer_1 = params.nests.last()->fbo[1]->handle(); + backend_tex_1 = params.nests.last()->fbo[1]->texture(); + backend_tex_2 = params.nests.last()->fbo[2]->texture(); + } else { + back_buffer_1 = params.backend_buffer1; + backend_tex_1 = params.backend_attachment1; + backend_tex_2 = params.backend_attachment2; + } + + // render a backbuffer + params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, back_buffer_1); + + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + // bind final clip texture + glBindTexture(GL_TEXTURE_2D, textureID); + + // set texture filter to bilinear + params.ctx->functions()->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + params.ctx->functions()->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + // draw clip on screen according to gl coordinates + glBegin(GL_QUADS); + + glTexCoord2f(coords.textureTopLeftX, coords.textureTopLeftY); // top left + glVertex2f(coords.vertexTopLeftX, coords.vertexTopLeftY); // top left + glTexCoord2f(coords.textureTopRightX, coords.textureTopRightY); // top right + glVertex2f(coords.vertexTopRightX, coords.vertexTopRightY); // top right + glTexCoord2f(coords.textureBottomRightX, coords.textureBottomRightY); // bottom right + glVertex2f(coords.vertexBottomRightX, coords.vertexBottomRightY); // bottom right + glTexCoord2f(coords.textureBottomLeftX, coords.textureBottomLeftY); // bottom left + glVertex2f(coords.vertexBottomLeftX, coords.vertexBottomLeftY); // bottom left + + glEnd(); + + // release final clip texture + glBindTexture(GL_TEXTURE_2D, 0); + + params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + + + // == END RENDER CLIP IN CONTEXT OF SEQUENCE == + + + + // + // + // PROCESS POST-SHADERS + // + // + + + + // copy front buffer to back buffer (only if we're using blending modes - which we usually will be) + if (!olive::CurrentRuntimeConfig.disable_blending) { + if (params.nests.size() > 0) { + draw_clip(params.ctx, params.nests.last()->fbo[2]->handle(), params.nests.last()->fbo[0]->texture(), true); + } else { + draw_clip(params.ctx, params.backend_buffer2, params.main_attachment, true); + } + } + + + + // == START FINAL DRAW ON SEQUENCE BUFFER == + + + + // bind front buffer as draw buffer + params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, final_fbo); + + if (olive::CurrentRuntimeConfig.disable_blending) { + // some GPUs don't like the blending shader, so we provide a pure GL fallback here + + params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, backend_tex_1); + + glColor4f(coords.opacity, coords.opacity, coords.opacity, coords.opacity); + + full_blit(); + + params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0); + } else { + // load background texture into texture unit 0 + params.ctx->functions()->glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0 + params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, backend_tex_2); + + // load foreground texture into texture unit 1 + params.ctx->functions()->glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1 + params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, backend_tex_1); + + // bind and configure blending mode shader + params.blend_mode_program->bind(); + params.blend_mode_program->setUniformValue("blendmode", coords.blendmode); + params.blend_mode_program->setUniformValue("opacity", coords.opacity); + params.blend_mode_program->setUniformValue("background", 0); + params.blend_mode_program->setUniformValue("foreground", 1); + + glClear(GL_COLOR_BUFFER_BIT); + + full_blit(); + + // release blend mode shader + params.blend_mode_program->release(); + + // unbind texture from texture unit 1 + params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0); + + // unbind texture from texture unit 0 + params.ctx->functions()->glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0 + params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0); + } + + // unbind framebuffer + params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + + + // == END FINAL DRAW ON SEQUENCE BUFFER == + } + + // prepare gizmos + if ((*params.gizmos) != nullptr + && params.nests.isEmpty() + && ((*params.gizmos) == first_gizmo_effect + || (*params.gizmos) == selected_effect)) { + (*params.gizmos)->gizmo_draw(timecode, coords); // set correct gizmo coords + (*params.gizmos)->gizmo_world_to_screen(); // convert gizmo coords to screen coords + } + + glPopMatrix(); + } + } else { + if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) { + params.nests.append(c); + compose_sequence(params); + params.nests.removeLast(); + } else { + if (c->lock.tryLock()) { + // Check whether cacher is currently active, if not activate it now + + cache_clip(c, playhead, c->audio_reset, (params.viewer != nullptr && !params.viewer->playing), params.nests, params.playback_speed); + c->lock.unlock(); + } + } + + // visually update all the keyframe values + if (c->sequence == params.seq) { // only if you can currently see them + double ts = (playhead - c->get_timeline_in_with_transition() + c->get_clip_in_with_transition())/s->frame_rate; + for (int i=0;ieffects.size();i++) { + EffectPtr e = c->effects.at(i); + for (int j=0;jrow_count();j++) { + EffectRow* r = e->row(j); + for (int k=0;kfieldCount();k++) { + r->field(k)->validate_keyframe_data(ts); + } + } + } + } + } + + c->render_lock.unlock(); + + } + } + + if (audio_track_count == 0 && params.viewer != nullptr) { + params.viewer->play_wake(); + } + + if (params.video) { + glPopMatrix(); + } + + if (!params.nests.isEmpty() && params.nests.last()->fbo != nullptr) { + // returns nested clip's texture + return params.nests.last()->fbo[0]->texture(); + } + + return 0; } void compose_audio(Viewer* viewer, SequencePtr seq, int playback_speed) { - ComposeSequenceParams params; - params.viewer = viewer; - params.ctx = nullptr; - params.seq = seq; - params.video = false; - params.gizmos = nullptr; - params.single_threaded = audio_rendering; - params.playback_speed = playback_speed; - params.blend_mode_program = nullptr; - compose_sequence(params); + ComposeSequenceParams params; + params.viewer = viewer; + params.ctx = nullptr; + params.seq = seq; + params.video = false; + params.gizmos = nullptr; + params.single_threaded = audio_rendering; + params.playback_speed = playback_speed; + params.blend_mode_program = nullptr; + compose_sequence(params); } diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index 199b3e396..1f7901964 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -848,7 +848,22 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { } } -void make_room_for_transition(ComboAction* ca, ClipPtr c, int type, long transition_start, long transition_end, bool delete_old_transitions) { +void make_room_for_transition(ComboAction* ca, + ClipPtr c, + int type, + long transition_start, + long transition_end, + bool delete_old_transitions, + long timeline_in = -1, + long timeline_out = -1) { + // it's possible to specify other in/out points for the clip, but default behavior is to use the ones existing + if (timeline_in < 0) { + timeline_in = c->timeline_in; + } + if (timeline_out < 0) { + timeline_out = c->timeline_out; + } + // make room for transition if (type == kTransitionOpening) { if (delete_old_transitions && c->get_opening_transition() != nullptr) { @@ -875,6 +890,97 @@ void make_room_for_transition(ComboAction* ca, ClipPtr c, int type, long transit } } +void VerifyTransitionsAfterCreating(ComboAction* ca, ClipPtr open, ClipPtr close, long transition_start, long transition_end) { + // in case the user made the transition larger than the clips, we're going to delete everything under + // the transition ghost and extend the clips to the transition's coordinates as necessary + + if (open == nullptr && close == nullptr) { + qWarning() << "VerifyTransitionsAfterCreating() called with two null clips"; + return; + } + + // determine whether this is a "shared" transition between to clips or not + bool shared_transition = (open != nullptr && close != nullptr); + + int track = 0; + + // first we set the clips to "undeletable" so they aren't affected by delete_areas_and_relink() + if (open != nullptr) { + open->undeletable = true; + track = open->track; + } + if (close != nullptr) { + close->undeletable = true; + track = close->track; + } + + // set the area to delete to the transition's coordinates and clear it + QVector areas; + Selection s; + s.in = transition_start; + s.out = transition_end; + s.track = track; + areas.append(s); + panel_timeline->delete_areas_and_relink(ca, areas, false); + + // set the clips back to undeletable now that we're done + if (open != nullptr) { + open->undeletable = false; + } + if (close != nullptr) { + close->undeletable = false; + } + + // loop through both kinds of transition + for (int t=kTransitionOpening;t<=kTransitionClosing;t++) { + + ClipPtr clip_ref = (t == kTransitionOpening) ? open : close; + + // if we have an opening transition: + if (clip_ref != nullptr) { + + // make_room_for_transition will adjust the opposite transition to make space for this one, + // for example if the user makes an opening transition that overlaps the closing transition, it'll resize + // or even delete the closing transition if necessary (and vice versa) + + make_room_for_transition(ca, clip_ref, t, transition_start, transition_end, true); + + // check if the transition coordinates require the clip to be resized + if (transition_start < clip_ref->timeline_in || transition_end > clip_ref->timeline_out) { + + long new_in, new_out; + + if (t == kTransitionOpening) { + + // if the transition is shared, it doesn't matter if the transition extend beyond the in point since + // that'll be "absorbed" by the other clip + new_in = (shared_transition) ? open->timeline_in : qMin(transition_start, open->timeline_in); + + new_out = qMax(transition_end, open->timeline_out); + + } else { + + new_in = qMin(transition_start, close->timeline_in); + + // if the transition is shared, it doesn't matter if the transition extend beyond the out point since + // that'll be "absorbed" by the other clip + new_out = (shared_transition) ? close->timeline_out : qMax(transition_end, close->timeline_out); + + } + + + + move_clip(ca, + clip_ref, + new_in, + new_out, + clip_ref->clip_in - (clip_ref->timeline_in - new_in), + clip_ref->track); + } + } + } +} + void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { QToolTip::hideText(); if (olive::ActiveSequence != nullptr) { @@ -967,6 +1073,10 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { } } } else if (panel_timeline->moving_proc) { + + // see if any clips actually moved, otherwise we don't need to do any processing + // (perhaps this could be moved further up to cover more actions?) + bool process_moving = false; for (int i=0;ighosts.size();i++) { @@ -983,54 +1093,70 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { if (process_moving) { const Ghost& first_ghost = panel_timeline->ghosts.at(0); - // if we were RIPPLING, move all the clips + // start a ripple movement if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) { - long ripple_length, ripple_point; // ripple_length becomes the length/number of frames we trimmed - // ripple point becomes the point to ripple (i.e. the point after or before which we move every clip) - if (panel_timeline->trim_type == TRIM_IN) { - ripple_length = first_ghost.old_in - first_ghost.in; - ripple_point = first_ghost.old_in; + // ripple_point is the "axis" around which we move all the clips, any clips after it get moved + long ripple_length; + long ripple_point = LONG_MAX; + if (panel_timeline->trim_type == TRIM_IN) { + + // it's assumed that all the ghosts rippled by the same length, so we just take the difference of the + // first ghost here + ripple_length = first_ghost.old_in - first_ghost.in; + + // for in trimming movements we also move the selections forward (unnecessary for out trimming since + // the selected clips more or less stay in the same place) for (int i=0;iselections.size();i++) { olive::ActiveSequence->selections[i].in += ripple_length; olive::ActiveSequence->selections[i].out += ripple_length; } } else { - // if we're trimming an out-point + + // use the out points for length if the user trimmed the out point ripple_length = first_ghost.old_out - panel_timeline->ghosts.at(0).out; - ripple_point = first_ghost.old_out; + } + + // build a list of "ignore clips" that won't get affected by ripple_clips() below QVector ignore_clips; for (int i=0;ighosts.size();i++) { const Ghost& g = panel_timeline->ghosts.at(i); - // push rippled clips forward if necessary + // for the same reason that we pushed selections forward above, for in trimming, + // we push the ghosts forward here if (panel_timeline->trim_type == TRIM_IN) { ignore_clips.append(g.clip); panel_timeline->ghosts[i].in += ripple_length; panel_timeline->ghosts[i].out += ripple_length; } + // find the earliest ripple point long comp_point = (panel_timeline->trim_type == TRIM_IN) ? g.old_in : g.old_out; ripple_point = qMin(ripple_point, comp_point); } + + // if this was out trimming, flip the direction of the ripple if (panel_timeline->trim_type == TRIM_OUT) ripple_length = -ripple_length; + // finally, ripple everything ripple_clips(ca, olive::ActiveSequence, ripple_point, ripple_length, ignore_clips); } if (panel_timeline->tool == TIMELINE_TOOL_POINTER && (event->modifiers() & Qt::AltModifier) - && panel_timeline->trim_target == -1) { // if holding alt (and not trimming), duplicate rather than move - // duplicate clips + && panel_timeline->trim_target == -1) { + + // if the user was holding alt (and not trimming), we duplicate clips rather than move them QVector old_clips; QVector new_clips; QVector delete_areas; for (int i=0;ighosts.size();i++) { const Ghost& g = panel_timeline->ghosts.at(i); if (g.old_in != g.in || g.old_out != g.out || g.track != g.old_track || g.clip_in != g.old_clip_in) { + // create copy of clip ClipPtr c(olive::ActiveSequence->clips.at(g.clip)->copy(olive::ActiveSequence)); @@ -1046,111 +1172,277 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { old_clips.append(g.clip); new_clips.append(c); + } } + if (new_clips.size() > 0) { + + // delete anything under the new clips panel_timeline->delete_areas_and_relink(ca, delete_areas, false); // relink duplicated clips panel_timeline->relink_clips_using_ids(old_clips, new_clips); + // add them ca->append(new AddClipCommand(olive::ActiveSequence, new_clips)); + } + } else { - // INSERT if holding ctrl + + // if we're not holding alt, this will just be a move + + // if the user is holding ctrl, perform an insert rather than an overwrite if (panel_timeline->tool == TIMELINE_TOOL_POINTER && ctrl) { + insert_clips(ca); + } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->tool == TIMELINE_TOOL_SLIDE) { - // move clips + + // if the user is not holding ctrl, we start standard clip movement + + // delete everything under the new clips QVector delete_areas; for (int i=0;ighosts.size();i++) { // step 1 - set clips that are moving to "undeletable" (to avoid step 2 deleting any part of them) const Ghost& g = panel_timeline->ghosts.at(i); + // set clip to undeletable so it's unaffected by delete_areas_and_relink() below olive::ActiveSequence->clips.at(g.clip)->undeletable = true; + + // if the user was moving a transition make sure they're undeletable too if (g.transition != nullptr) { g.transition->parent_clip->undeletable = true; - if (g.transition->secondary_clip != nullptr) g.transition->secondary_clip->undeletable = true; + if (g.transition->secondary_clip != nullptr) { + g.transition->secondary_clip->undeletable = true; + } } + // set area to delete Selection s; s.in = g.in; s.out = g.out; s.track = g.track; delete_areas.append(s); } + panel_timeline->delete_areas_and_relink(ca, delete_areas, false); + + // clean up, i.e. make everything not undeletable again for (int i=0;ighosts.size();i++) { const Ghost& g = panel_timeline->ghosts.at(i); olive::ActiveSequence->clips.at(g.clip)->undeletable = false; + if (g.transition != nullptr) { g.transition->parent_clip->undeletable = false; - if (g.transition->secondary_clip != nullptr) g.transition->secondary_clip->undeletable = false; + if (g.transition->secondary_clip != nullptr) { + g.transition->secondary_clip->undeletable = false; + } } - } + } } + + // finally, perform actual movement of clips for (int i=0;ighosts.size();i++) { Ghost& g = panel_timeline->ghosts[i]; - // step 3 - move clips ClipPtr c = olive::ActiveSequence->clips.at(g.clip); - if (g.transition == nullptr) { - move_clip(ca, c, (g.in - g.old_in), (g.out - g.old_out), (g.clip_in - g.old_clip_in), (g.track - g.old_track), true, true); - // adjust transitions if we need to - long new_clip_length = (g.out - g.in); - if (c->get_opening_transition() != nullptr) { - long max_open_length = new_clip_length; - if (c->get_closing_transition() != nullptr && panel_timeline->trim_type == TRIM_OUT) { - max_open_length -= c->get_closing_transition()->get_true_length(); - } - if (max_open_length <= 0) { - ca->append(new DeleteTransitionCommand(c->opening_transition)); - } else if (c->get_opening_transition()->get_true_length() > max_open_length) { - ca->append(new ModifyTransitionCommand(c->opening_transition, max_open_length)); - } - } - if (c->get_closing_transition() != nullptr) { - long max_open_length = new_clip_length; - if (c->get_opening_transition() != nullptr && panel_timeline->trim_type == TRIM_IN) { - max_open_length -= c->get_opening_transition()->get_true_length(); - } - if (max_open_length <= 0) { - ca->append(new DeleteTransitionCommand(c->closing_transition)); - } else if (c->get_closing_transition()->get_true_length() > max_open_length) { - ca->append(new ModifyTransitionCommand(c->closing_transition, max_open_length)); - } - } + if (g.transition == nullptr) { + + // if this was a clip rather than a transition + + move_clip(ca, c, (g.in - g.old_in), (g.out - g.old_out), (g.clip_in - g.old_clip_in), (g.track - g.old_track), false, true); + } else { + + // if the user was moving a transition + bool is_opening_transition = (g.transition == c->get_opening_transition()); long new_transition_length = g.out - g.in; if (g.transition->secondary_clip != nullptr) new_transition_length >>= 1; - ca->append(new ModifyTransitionCommand(is_opening_transition ? c->opening_transition : c->closing_transition, new_transition_length)); + ca->append( + new ModifyTransitionCommand(is_opening_transition ? c->opening_transition : c->closing_transition, + new_transition_length) + ); long clip_length = c->getLength(); if (g.transition->secondary_clip != nullptr) { + + // if this is a shared transition if (g.in != g.old_in && g.trim_type == TRIM_NONE) { long movement = g.in - g.old_in; - move_clip(ca, g.transition->parent_clip, movement, 0, movement, 0, false, true); - move_clip(ca, g.transition->secondary_clip, 0, movement, 0, 0, false, true); + + // check if the transition is going to extend the out point (opening clip) + long timeline_out_movement = 0; + if (g.out > g.transition->parent_clip->timeline_out) { + timeline_out_movement = g.out - g.transition->parent_clip->timeline_out; + } + + // check if the transition is going to extend the in point (closing clip) + long timeline_in_movement = 0; + if (g.in < g.transition->secondary_clip->timeline_in) { + timeline_in_movement = g.in - g.transition->secondary_clip->timeline_in; + } + + move_clip(ca, g.transition->parent_clip, movement, timeline_out_movement, movement, 0, false, true); + move_clip(ca, g.transition->secondary_clip, timeline_in_movement, movement, timeline_in_movement, 0, false, true); + + make_room_for_transition(ca, g.transition->parent_clip, kTransitionOpening, g.in, g.out, false); + make_room_for_transition(ca, g.transition->secondary_clip, kTransitionClosing, g.in, g.out, false); + } + } else if (is_opening_transition) { + if (g.in != g.old_in) { // if transition is going to make the clip bigger, make the clip bigger - move_clip(ca, c, (g.in - g.old_in), 0, (g.clip_in - g.old_clip_in), 0, true, true); + + // check if the transition is going to extend the out point + long timeline_out_movement = 0; + if (g.out > g.transition->parent_clip->timeline_out) { + timeline_out_movement = g.out - g.transition->parent_clip->timeline_out; + } + + move_clip(ca, c, (g.in - g.old_in), timeline_out_movement, (g.clip_in - g.old_clip_in), 0, false, true); clip_length -= (g.in - g.old_in); } make_room_for_transition(ca, c, kTransitionOpening, g.in, g.out, false); + } else { + if (g.out != g.old_out) { + + // check if the transition is going to extend the in point + long timeline_in_movement = 0; + if (g.in < g.transition->parent_clip->timeline_in) { + timeline_in_movement = g.in - g.transition->parent_clip->timeline_in; + } + // if transition is going to make the clip bigger, make the clip bigger - move_clip(ca, c, 0, (g.out - g.old_out), 0, 0, true, true); + move_clip(ca, c, timeline_in_movement, (g.out - g.old_out), timeline_in_movement, 0, false, true); clip_length += (g.out - g.old_out); } make_room_for_transition(ca, c, kTransitionClosing, g.in, g.out, false); + + } + } + } + + // time to verify the transitions of moved clips + for (int i=0;ighosts.size();i++) { + const Ghost& g = panel_timeline->ghosts.at(i); + + // only applies to moving clips, transitions are verified above instead + if (g.transition == nullptr) { + ClipPtr c = olive::ActiveSequence->clips.at(g.clip); + + long new_clip_length = g.out - g.in; + + // using a for loop between constants to repeat the same steps for the opening and closing transitions + for (int t=kTransitionOpening;t<=kTransitionClosing;t++) { + + TransitionPtr transition = (t == kTransitionOpening) ? c->opening_transition : c->closing_transition; + + // check the whether the clip has a transition here + if (transition != nullptr) { + + // if the new clip size exceeds the opening transition's length, resize the transition + if (new_clip_length < transition->get_true_length()) { + ca->append(new ModifyTransitionCommand(transition, new_clip_length)); + } + + // check if the transition is a shared transition (it'll never have a secondary clip if it isn't) + if (transition->secondary_clip != nullptr) { + + // check if the transition's "edge" is going to move + if ((t == kTransitionOpening && g.in != g.old_in) + || (t == kTransitionClosing && g.out != g.old_out)) { + + // if we're here, this clip shares its opening transition as the closing transition of another + // clip (or vice versa), and the in point is moving, so we may have to account for this + + // the other clip sharing this transition may be moving as well, meaning we don't have to do + // anything + + bool split = true; + + // loop through ghosts to find out + + // for a shared transition, the secondary_clip will always be the closing transition side and + // the parent_clip will always be the opening transition side + ClipPtr search_clip = (t == kTransitionOpening) + ? transition->secondary_clip : transition->parent_clip; + + for (int j=0;jghosts.size();j++) { + const Ghost& other_clip_ghost = panel_timeline->ghosts.at(j); + + if (olive::ActiveSequence->clips.at(other_clip_ghost.clip) == search_clip) { + + // we found the other clip in the current ghosts/selections + + // see if it's destination edge will be equal to this ghost's edge (in which case the + // transition doesn't need to change) + // + // also only do this if j is less than i, because it only needs to happen once and chances are + // the other clip already + + bool edges_still_touch; + if (t == kTransitionOpening) { + edges_still_touch = (other_clip_ghost.out == g.in); + } else { + edges_still_touch = (other_clip_ghost.in == g.out); + } + + if (edges_still_touch || j < i) { + split = false; + } + + break; + } + } + + if (split) { + // separate shared transition into one transition for each clip + + if (t == kTransitionOpening) { + + // set transition to single-clip mode + ca->append(new SetPointer(reinterpret_cast(&transition->secondary_clip), + nullptr)); + + // create duplicate transition for other clip + ca->append(new AddTransitionCommand(nullptr, + transition->secondary_clip, + transition, + nullptr, + 0)); + + } else { + + // set transition to single-clip mode + ca->append(new SetPointer(reinterpret_cast(&transition->secondary_clip), + nullptr)); + + // that transition will now attach to the other clip, so we duplicate it for this one + + // create duplicate transition for this clip + ca->append(new AddTransitionCommand(nullptr, + transition->secondary_clip, + transition, + nullptr, + 0)); + + } + } + + } + } + } } } } @@ -1164,10 +1456,11 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { // if the transition is greater than 0 length (if it is 0, we make nothing) if (g.in != g.out) { - // get transition length + // get transition coordinates on the timeline long transition_start = qMin(g.in, g.out); long transition_end = qMax(g.in, g.out); + // get clip references from tool's cached data ClipPtr open = (panel_timeline->transition_tool_open_clip > -1) ? olive::ActiveSequence->clips.at(panel_timeline->transition_tool_open_clip) : nullptr; @@ -1176,71 +1469,17 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { ? olive::ActiveSequence->clips.at(panel_timeline->transition_tool_close_clip) : nullptr; - bool shared_transition = (open != nullptr && close != nullptr); - - if (open != nullptr) { - open->undeletable = true; - } - if (close != nullptr) { - close->undeletable = true; - } - - // delete everything under this new transition - QVector areas; - Selection s; - s.in = transition_start; - s.out = transition_end; - s.track = g.track; - areas.append(s); - panel_timeline->delete_areas_and_relink(ca, areas, false); - - if (open != nullptr) { - open->undeletable = false; - } - if (close != nullptr) { - close->undeletable = false; - } - if (open != nullptr) { - make_room_for_transition(ca, open, kTransitionOpening, transition_start, transition_end, true); - - if (transition_start < open->timeline_in || transition_end > open->timeline_out) { -// long effective_out = (close != nullptr) ? close->timeline_out : open->timeline_out; - long new_in = qMin(transition_start, open->timeline_in); - long new_out = qMax(transition_end, open->timeline_out); - - move_clip(ca, - open, - new_in, - new_out, - open->clip_in - (open->timeline_in - new_in), - open->track); - } - } - - if (close != nullptr) { - make_room_for_transition(ca, close, kTransitionClosing, transition_start, transition_end, true); - - if (transition_start < close->timeline_in || transition_end > close->timeline_out) { -// long effective_in = (open != nullptr) ? open->timeline_in : close->timeline_in; - long new_in = qMin(transition_start, close->timeline_in); - long new_out = qMax(transition_end, close->timeline_out); - - move_clip(ca, - close, - new_in, - new_out, - close->clip_in - (close->timeline_in - new_in), - close->track); - } - } - + // if it's shared, the transition length is halved (one half for each clip will result in the full length) long transition_length = transition_end - transition_start; - if (shared_transition) { + if (open != nullptr && close != nullptr) { transition_length /= 2; } + VerifyTransitionsAfterCreating(ca, open, close, transition_start, transition_end); + + // finally, add the transition to these clips ca->append(new AddTransitionCommand(open, close, nullptr, @@ -1393,7 +1632,9 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { const Ghost& g = panel_timeline->ghosts.at(i); // snap ghost's in point - if (panel_timeline->trim_target == -1 || g.trim_type == TRIM_IN) { + if ((panel_timeline->tool != TIMELINE_TOOL_TRANSITION && panel_timeline->trim_target == -1) + || g.trim_type == TRIM_IN + || panel_timeline->transition_tool_open_clip > -1) { fm = g.old_in + frame_diff; if (panel_timeline->snap_to_timeline(&fm, true, true, true)) { frame_diff = fm - g.old_in; @@ -1402,7 +1643,9 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { } // snap ghost's out point - if (panel_timeline->trim_target == -1 || g.trim_type == TRIM_OUT) { + if ((panel_timeline->tool != TIMELINE_TOOL_TRANSITION && panel_timeline->trim_target == -1) + || g.trim_type == TRIM_OUT + || panel_timeline->transition_tool_close_clip > -1) { fm = g.old_out + frame_diff; if (panel_timeline->snap_to_timeline(&fm, true, true, true)) { frame_diff = fm - g.old_out; @@ -1411,7 +1654,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { } // if the ghost is attached to a clip, snap its markers too - if (panel_timeline->trim_target == -1 && g.clip >= 0) { + if (panel_timeline->trim_target == -1 && g.clip >= 0 && panel_timeline->tool != TIMELINE_TOOL_TRANSITION) { ClipPtr c = olive::ActiveSequence->clips.at(g.clip); for (int j=0;jget_markers().size();j++) { long marker_real_time = c->get_markers().at(j).frame + c->timeline_in - c->clip_in; @@ -1652,7 +1895,8 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { g.in = g.old_in + frame_diff; g.out = g.old_out + frame_diff; - if (g.transition != nullptr && g.transition == olive::ActiveSequence->clips.at(g.clip)->get_opening_transition()) { + if (g.transition != nullptr + && g.transition == olive::ActiveSequence->clips.at(g.clip)->get_opening_transition()) { g.clip_in = g.old_clip_in + frame_diff; } @@ -1913,12 +2157,11 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { g.transition = nullptr; // check if whole clip is added - bool add = is_clip_selected(c, true); + bool add = false; - // if a whole clip is not selected, maybe just a transition is + // check if a transition is selected (prioritize transition selection) // (only the pointer tool supports moving transitions) - if (!add - && panel_timeline->tool == TIMELINE_TOOL_POINTER + if (panel_timeline->tool == TIMELINE_TOOL_POINTER && (c->get_opening_transition() != nullptr || c->get_closing_transition() != nullptr)) { // check if any selections contain a whole transition @@ -1946,6 +2189,11 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } + // if a transition isn't selected, check if the whole clip is + if (!add) { + add = is_clip_selected(c, true); + } + if (add) { if (g.transition != nullptr) { diff --git a/ui/timelinewidget.h b/ui/timelinewidget.h index 3e7481618..68983c1ac 100644 --- a/ui/timelinewidget.h +++ b/ui/timelinewidget.h @@ -90,6 +90,8 @@ private: int getScreenPointFromTrack(int track); int getClipIndexFromCoords(long frame, int track); + void VerifyTransitionHelper(); + bool track_resizing; int track_target; From 23a43aba3e45a71a95950c318ab164f5f8dd4a2f Mon Sep 17 00:00:00 2001 From: Jonathan Noble Date: Sat, 16 Feb 2019 22:27:28 +0000 Subject: [PATCH 20/30] Removed 5 duplicated blocks of code. https://sonarcloud.io/project/issues?id=jonno85uk_olive&issues=AWjXpEv0EzgCzR11xzeI&open=AWjXpEv0EzgCzR11xzeI (cherry picked from commit 64bb2e7cdfac36a69e380a3c0ad5c25b97b4402f) # Conflicts: # app/debug.cpp --- debug.cpp | 115 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 64 insertions(+), 51 deletions(-) diff --git a/debug.cpp b/debug.cpp index 70b605938..58e6f04ec 100644 --- a/debug.cpp +++ b/debug.cpp @@ -34,63 +34,76 @@ QFile debug_file; QTextStream debug_stream; void open_debug_file() { - QDir debug_dir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); - debug_dir.mkpath("."); - if (debug_dir.exists()) { - debug_file.setFileName(debug_dir.path() + "/debug_log"); - if (debug_file.open(QFile::WriteOnly)) { - debug_stream.setDevice(&debug_file); - } else { - qWarning() << "Couldn't open debug log file, debug log will not be saved"; - } - } + QDir debug_dir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); + debug_dir.mkpath("."); + if (debug_dir.exists()) { + debug_file.setFileName(debug_dir.path() + "/debug_log"); + if (debug_file.open(QFile::WriteOnly)) { + debug_stream.setDevice(&debug_file); + } else { + qWarning() << "Couldn't open debug log file, debug log will not be saved"; + } + } } -void close_debug_file() { - if (debug_file.isOpen()) debug_file.close(); +void close_debug_file() +{ + if (debug_file.isOpen()) { + debug_file.close(); + } } -void debug_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { - debug_mutex.lock(); - QByteArray localMsg = msg.toLocal8Bit(); - switch (type) { - case QtDebugMsg: - fprintf(stderr, "[DEBUG] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); - if (debug_file.isOpen()) debug_stream << QString("[DEBUG] %1 (%2:%3, %4)\n").arg(localMsg.constData(), context.file, QString::number(context.line), context.function); - debug_info.append(QString("[DEBUG] %1 (%2:%3, %4)
").arg(localMsg.constData(), context.file, QString::number(context.line), context.function)); - fflush(stderr); - break; - case QtInfoMsg: - fprintf(stderr, "[INFO] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); - if (debug_file.isOpen()) debug_stream << QString("[INFO] %1 (%2:%3, %4)\n").arg(localMsg.constData(), context.file, QString::number(context.line), context.function); - debug_info.append(QString("[INFO] %1 (%2:%3, %4)
").arg(localMsg.constData(), context.file, QString::number(context.line), context.function)); - fflush(stderr); - break; - case QtWarningMsg: - fprintf(stderr, "[WARNING] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); - if (debug_file.isOpen()) debug_stream << QString("[WARNING] %1 (%2:%3, %4)\n").arg(localMsg.constData(), context.file, QString::number(context.line), context.function); - debug_info.append(QString("[WARNING] %1 (%2:%3, %4)
").arg(localMsg.constData(), context.file, QString::number(context.line), context.function)); - fflush(stderr); - break; - case QtCriticalMsg: - fprintf(stderr, "[ERROR] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); - if (debug_file.isOpen()) debug_stream << QString("[ERROR] %1 (%2:%3, %4)\n").arg(localMsg.constData(), context.file, QString::number(context.line), context.function); - debug_info.append(QString("[ERROR] %1 (%2:%3, %4)
").arg(localMsg.constData(), context.file, QString::number(context.line), context.function)); - fflush(stderr); - break; - case QtFatalMsg: - fprintf(stderr, "[FATAL] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); - if (debug_file.isOpen()) debug_stream << QString("[FATAL] %1 (%2:%3, %4)\n").arg(localMsg.constData(), context.file, QString::number(context.line), context.function); - debug_info.append(QString("[FATAL] %1 (%2:%3, %4)
").arg(localMsg.constData(), context.file, QString::number(context.line), context.function)); - fflush(stderr); -// abort(); - } +void debug_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + debug_mutex.lock(); + const QByteArray localMsg = msg.toLocal8Bit(); + const QDateTime now = QDateTime::currentDateTime(); + const QByteArray timeRepr(now.toString(Qt::ISODate).toLocal8Bit()); + QString msgTag; + QString fontColor; + switch (type) { + case QtDebugMsg: + msgTag = "DEBUG"; + fontColor = "grey"; + break; + case QtInfoMsg: + msgTag = "INFO"; + fontColor = "blue"; + break; + case QtWarningMsg: + msgTag = "WARNING"; + fontColor = "yellow"; + break; + case QtCriticalMsg: + msgTag = "ERROR"; + fontColor = "red"; + break; + case QtFatalMsg: + msgTag = "FATAL"; + fontColor = "red"; + break; + default: + fprintf(stderr, "Unknown debug msg type"); + fflush(stderr); + break; + }//switch + + fprintf(stderr, "%s [%s] %s (%s:%u, %s)\n", timeRepr.data(), msgTag.toLocal8Bit().constData(), localMsg.data(), + context.file, context.line, context.function); + if (debug_file.isOpen()) { + debug_stream << QString("[%1] %2 (%3:%4, %5)\n") + .arg(msgTag, localMsg, context.file, QString::number(context.line), context.function); + } + debug_info.prepend(QString("[%2] %3 (%4:%5, %6)
") + .arg(fontColor, msgTag, localMsg, context.file, QString::number(context.line), context.function)); + fflush(stderr); if (Olive::DebugDialog != nullptr && Olive::DebugDialog->isVisible()) { QMetaObject::invokeMethod(Olive::DebugDialog, "update_log", Qt::QueuedConnection); - } - debug_mutex.unlock(); + } + debug_mutex.unlock(); } -const QString &get_debug_str() { - return debug_info; +const QString &get_debug_str() +{ + return debug_info; } From ee967294ea97410bdfbe919e85d6e1aae8b8df48 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Tue, 19 Feb 2019 02:05:21 -0800 Subject: [PATCH 21/30] reimplemented loading/saving into transitions --- io/config.h | 40 +- io/loadthread.cpp | 1326 +++++++++++++++++++--------------------- io/loadthread.h | 86 ++- panels/project.cpp | 38 +- project/transition.cpp | 5 + project/transition.h | 3 + 6 files changed, 726 insertions(+), 772 deletions(-) diff --git a/io/config.h b/io/config.h index 8b907779a..ea9614e00 100644 --- a/io/config.h +++ b/io/config.h @@ -23,26 +23,36 @@ #include -#define SAVE_VERSION 190201 // YYMMDD -#define MIN_SAVE_VERSION 190104 // lowest compatible project version +#define SAVE_VERSION 190219 // YYMMDD +#define MIN_SAVE_VERSION 190219 // lowest compatible project version -#define TIMECODE_DROP 0 -#define TIMECODE_NONDROP 1 -#define TIMECODE_FRAMES 2 -#define TIMECODE_MILLISECONDS 3 +enum TimecodeType { + TIMECODE_DROP, + TIMECODE_NONDROP, + TIMECODE_FRAMES, + TIMECODE_MILLISECONDS +}; -#define RECORD_MODE_MONO 1 -#define RECORD_MODE_STEREO 2 +enum RecordingMode { + RECORD_MODE_MONO, + RECORD_MODE_STEREO +}; -#define AUTOSCROLL_NO_SCROLL 0 -#define AUTOSCROLL_PAGE_SCROLL 1 -#define AUTOSCROLL_SMOOTH_SCROLL 2 +enum AutoScrollMode { + AUTOSCROLL_NO_SCROLL, + AUTOSCROLL_PAGE_SCROLL, + AUTOSCROLL_SMOOTH_SCROLL +}; -#define PROJECT_VIEW_TREE 0 -#define PROJECT_VIEW_ICON 1 +enum ProjectView { + PROJECT_VIEW_TREE, + PROJECT_VIEW_ICON +}; -#define FRAME_QUEUE_TYPE_FRAMES 0 -#define FRAME_QUEUE_TYPE_SECONDS 1 +enum FrameQueueType { + FRAME_QUEUE_TYPE_FRAMES, + FRAME_QUEUE_TYPE_SECONDS +}; struct Config { Config(); diff --git a/io/loadthread.cpp b/io/loadthread.cpp index e95034694..42a970673 100644 --- a/io/loadthread.cpp +++ b/io/loadthread.cpp @@ -38,812 +38,746 @@ #include LoadThread::LoadThread(bool a) : 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_dual_transition(const TransitionData*,ClipPtr,ClipPtr,const EffectMeta*)), this, SLOT(create_dual_transition(const TransitionData*,ClipPtr,ClipPtr,const EffectMeta*))); - connect(this, SIGNAL(start_create_effect_ui(QXmlStreamReader*, ClipPtr, int, const QString*, const EffectMeta*, long, bool)), this, SLOT(create_effect_ui(QXmlStreamReader*, ClipPtr, int, const QString*, const EffectMeta*, long, bool))); - connect(this, SIGNAL(start_question(const QString&, const QString &, int)), this, SLOT(question_func(const QString &, const QString &, int))); + 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*, ClipPtr, int, const QString*, const EffectMeta*, long, bool)), this, SLOT(create_effect_ui(QXmlStreamReader*, ClipPtr, int, const QString*, const EffectMeta*, long, bool))); + connect(this, SIGNAL(start_question(const QString&, const QString &, int)), this, SLOT(question_func(const QString &, const QString &, int))); } void LoadThread::load_effect(QXmlStreamReader& stream, ClipPtr c) { - int effect_id = -1; - QString effect_name; - bool effect_enabled = true; - long effect_length = -1; - for (int j=0;jeffects_loaded.lock(); + // variables to store effect metadata in + int effect_id = -1; + QString effect_name; + bool effect_enabled = true; + long effect_length = -1; - const EffectMeta* meta = nullptr; + // loop through attributes for effect metadata + for (int j=0;jsequence->clips.at(attr.value().toInt()); + if (tag == "opening") { + c->opening_transition = (sharing_clip->closing_transition); - panel_effect_controls->effects_loaded.unlock(); + // since this is the opened clip, switch secondaries and primaries + c->opening_transition->secondary_clip = c->opening_transition->parent_clip; + c->opening_transition->parent_clip = c; + c->opening_transition->refresh(); + } else if (tag == "closing") { + c->closing_transition = (sharing_clip->opening_transition); - QString tag = stream.name().toString(); + // since this is the closed clip, make this clip the secondary + c->opening_transition->secondary_clip = c; + } + return; + } + } - int type; - if (tag == "opening") { - type = kTransitionOpening; - } else if (tag == "closing") { - type = kTransitionClosing; - } else { - type = kTransitionNone; - } + // Effect loading occurs in another thread, and while it's usually very quick, just for safety we wait here + // for all the effects to finish loading + panel_effect_controls->effects_loaded.lock(); - emit start_create_effect_ui(&stream, c, type, &effect_name, meta, effect_length, effect_enabled); - waitCond.wait(&mutex); + const EffectMeta* meta = nullptr; + + // find effect with this name + if (!effect_name.isEmpty()) { + meta = get_meta_from_name(effect_name); + } + + panel_effect_controls->effects_loaded.unlock(); + + int type; + if (tag == "opening") { + type = kTransitionOpening; + } else if (tag == "closing") { + type = kTransitionClosing; + } else { + type = kTransitionNone; + } + + // effect UI creation has to occur in the main thread, see an explanation in create_effect_ui() + emit start_create_effect_ui(&stream, c, type, &effect_name, meta, effect_length, effect_enabled); + waitCond.wait(&mutex); } void LoadThread::read_next(QXmlStreamReader &stream) { - stream.readNext(); - update_current_element_count(stream); + stream.readNext(); + update_current_element_count(stream); } void LoadThread::read_next_start_element(QXmlStreamReader &stream) { - stream.readNextStartElement(); - update_current_element_count(stream); + stream.readNextStartElement(); + update_current_element_count(stream); } void LoadThread::update_current_element_count(QXmlStreamReader &stream) { - if (is_element(stream)) { - current_element_count++; - report_progress((current_element_count * 100) / total_element_count); - } + if (is_element(stream)) { + current_element_count++; + report_progress((current_element_count * 100) / total_element_count); + } } bool LoadThread::is_element(QXmlStreamReader &stream) { - return stream.isStartElement() - && (stream.name() == "folder" - || stream.name() == "footage" - || stream.name() == "sequence" - || stream.name() == "clip" - || stream.name() == "effect"); + return stream.isStartElement() + && (stream.name() == "folder" + || stream.name() == "footage" + || stream.name() == "sequence" + || stream.name() == "clip" + || stream.name() == "effect"); } bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) { - f.seek(0); - stream.setDevice(stream.device()); + f.seek(0); + stream.setDevice(stream.device()); - QString root_search; - QString child_search; + QString root_search; + QString child_search; - switch (type) { - case LOAD_TYPE_VERSION: - root_search = "version"; - break; - case LOAD_TYPE_URL: - root_search = "url"; - break; - case MEDIA_TYPE_FOLDER: - root_search = "folders"; - child_search = "folder"; - break; - case MEDIA_TYPE_FOOTAGE: - root_search = "media"; - child_search = "footage"; - break; - case MEDIA_TYPE_SEQUENCE: - root_search = "sequences"; - child_search = "sequence"; - break; - } + switch (type) { + case LOAD_TYPE_VERSION: + root_search = "version"; + break; + case LOAD_TYPE_URL: + root_search = "url"; + break; + case MEDIA_TYPE_FOLDER: + root_search = "folders"; + child_search = "folder"; + break; + case MEDIA_TYPE_FOOTAGE: + root_search = "media"; + child_search = "footage"; + break; + case MEDIA_TYPE_SEQUENCE: + root_search = "sequences"; + child_search = "sequence"; + break; + } - show_err = true; + show_err = true; - while (!stream.atEnd() && !cancelled) { - read_next_start_element(stream); - if (stream.name() == root_search) { - if (type == LOAD_TYPE_VERSION) { - int proj_version = stream.readElementText().toInt(); - if (proj_version < MIN_SAVE_VERSION || proj_version > SAVE_VERSION) { - emit start_question( - tr("Version Mismatch"), - tr("This project was saved in a different version of Olive and may not be fully compatible with this version. Would you like to attempt loading it anyway?"), - QMessageBox::Yes | QMessageBox::No - ); - waitCond.wait(&mutex); - if (question_btn == QMessageBox::No) { - show_err = false; - return false; - } - } - } else if (type == LOAD_TYPE_URL) { - internal_proj_url = stream.readElementText(); - internal_proj_dir = QFileInfo(internal_proj_url).absoluteDir(); - } else { - while (!cancelled && !stream.atEnd() && !(stream.name() == root_search && stream.isEndElement())) { - read_next(stream); - if (stream.name() == child_search && stream.isStartElement()) { - switch (type) { - case MEDIA_TYPE_FOLDER: - { - Media* folder = panel_project->create_folder_internal(nullptr); - folder->temp_id2 = 0; - for (int j=0;jtemp_id = attr.value().toInt(); - } else if (attr.name() == "name") { - folder->set_name(attr.value().toString()); - } else if (attr.name() == "parent") { - folder->temp_id2 = attr.value().toInt(); - } - } - loaded_folders.append(folder); - } - break; - case MEDIA_TYPE_FOOTAGE: - { - int folder = 0; + int proj_version = SAVE_VERSION; - Media* item = new Media(0); - FootagePtr f(new Footage()); + while (!stream.atEnd() && !cancelled) { + read_next_start_element(stream); + if (stream.name() == root_search) { + if (type == LOAD_TYPE_VERSION) { + proj_version = stream.readElementText().toInt(); + if (proj_version < MIN_SAVE_VERSION || proj_version > SAVE_VERSION) { + emit start_question( + tr("Version Mismatch"), + tr("This project was saved in a different version of Olive and may not be fully compatible with this version. Would you like to attempt loading it anyway?"), + QMessageBox::Yes | QMessageBox::No + ); + waitCond.wait(&mutex); + if (question_btn == QMessageBox::No) { + show_err = false; + return false; + } + } + } else if (type == LOAD_TYPE_URL) { + internal_proj_url = stream.readElementText(); + internal_proj_dir = QFileInfo(internal_proj_url).absoluteDir(); + } else { + while (!cancelled && !stream.atEnd() && !(stream.name() == root_search && stream.isEndElement())) { + read_next(stream); + if (stream.name() == child_search && stream.isStartElement()) { + switch (type) { + case MEDIA_TYPE_FOLDER: + { + Media* folder = panel_project->create_folder_internal(nullptr); + folder->temp_id2 = 0; + for (int j=0;jtemp_id = attr.value().toInt(); + } else if (attr.name() == "name") { + folder->set_name(attr.value().toString()); + } else if (attr.name() == "parent") { + folder->temp_id2 = attr.value().toInt(); + } + } + loaded_folders.append(folder); + } + break; + case MEDIA_TYPE_FOOTAGE: + { + int folder = 0; - f->using_inout = false; + Media* item = new Media(nullptr); + FootagePtr f(new Footage()); - for (int j=0;jsave_id = attr.value().toInt(); - } else if (attr.name() == "folder") { - folder = attr.value().toInt(); - } else if (attr.name() == "name") { - f->name = attr.value().toString(); - } else if (attr.name() == "url") { - f->url = attr.value().toString(); + f->using_inout = false; - if (!QFileInfo::exists(f->url)) { // if path is not absolute - // tries to locate file using a file path relative to the project's current folder - QString proj_dir_test = proj_dir.absoluteFilePath(f->url); + for (int j=0;jsave_id = attr.value().toInt(); + } else if (attr.name() == "folder") { + folder = attr.value().toInt(); + } else if (attr.name() == "name") { + f->name = attr.value().toString(); + } else if (attr.name() == "url") { + f->url = attr.value().toString(); - // tries to locate file using a file path relative to the folder the project was saved in - // (unaffected by moving the project file) - QString internal_proj_dir_test = internal_proj_dir.absoluteFilePath(f->url); + if (!QFileInfo::exists(f->url)) { // if path is not absolute + // tries to locate file using a file path relative to the project's current folder + QString proj_dir_test = proj_dir.absoluteFilePath(f->url); - // tries to locate file using the file name directly in the project's current folder - QString proj_dir_direct_test = proj_dir.filePath(QFileInfo(f->url).fileName()); + // tries to locate file using a file path relative to the folder the project was saved in + // (unaffected by moving the project file) + QString internal_proj_dir_test = internal_proj_dir.absoluteFilePath(f->url); - if (QFileInfo::exists(proj_dir_test)) { + // tries to locate file using the file name directly in the project's current folder + QString proj_dir_direct_test = proj_dir.filePath(QFileInfo(f->url).fileName()); - f->url = proj_dir_test; - qInfo() << "Matched" << attr.value().toString() << "relative to project's current directory"; + if (QFileInfo::exists(proj_dir_test)) { - } else if (QFileInfo::exists(internal_proj_dir_test)) { + f->url = proj_dir_test; + qInfo() << "Matched" << attr.value().toString() << "relative to project's current directory"; - f->url = internal_proj_dir_test; - qInfo() << "Matched" << attr.value().toString() << "relative to project's internal directory"; + } else if (QFileInfo::exists(internal_proj_dir_test)) { - } else if (QFileInfo::exists(proj_dir_direct_test)) { + f->url = internal_proj_dir_test; + qInfo() << "Matched" << attr.value().toString() << "relative to project's internal directory"; - f->url = proj_dir_direct_test; - qInfo() << "Matched" << attr.value().toString() << "directly to project's current directory"; + } else if (QFileInfo::exists(proj_dir_direct_test)) { - } else if (f->url.contains('%')) { + f->url = proj_dir_direct_test; + qInfo() << "Matched" << attr.value().toString() << "directly to project's current directory"; - // hack for image sequences (qt won't be able to find the URL with %, but ffmpeg may) - f->url = internal_proj_dir_test; - qInfo() << "Guess image sequence" << attr.value().toString() << "path to project's internal directory"; + } else if (f->url.contains('%')) { - } else { + // hack for image sequences (qt won't be able to find the URL with %, but ffmpeg may) + f->url = internal_proj_dir_test; + qInfo() << "Guess image sequence" << attr.value().toString() << "path to project's internal directory"; - qInfo() << "Failed to match" << attr.value().toString() << "to file"; + } else { - } - } else { - f->url = QFileInfo(f->url).absoluteFilePath(); - qInfo() << "Matched" << attr.value().toString() << "with absolute path"; - } - } else if (attr.name() == "duration") { - f->length = attr.value().toLongLong(); - } else if (attr.name() == "using_inout") { - f->using_inout = (attr.value() == "1"); - } else if (attr.name() == "in") { - f->in = attr.value().toLong(); - } else if (attr.name() == "out") { - f->out = attr.value().toLong(); - } else if (attr.name() == "speed") { - f->speed = attr.value().toDouble(); - } else if (attr.name() == "alphapremul") { - f->alpha_is_premultiplied = (attr.value() == "1"); - } else if (attr.name() == "proxy") { - f->proxy = (attr.value() == "1"); - } else if (attr.name() == "proxypath") { - f->proxy_path = attr.value().toString(); - } - } + qInfo() << "Failed to match" << attr.value().toString() << "to file"; - while (!cancelled && !(stream.name() == child_search && stream.isEndElement()) && !stream.atEnd()) { - read_next_start_element(stream); - if (stream.name() == "marker" && stream.isStartElement()) { - Marker m; - for (int j=0;jmarkers.append(m); - } - } + } + } else { + f->url = QFileInfo(f->url).absoluteFilePath(); + qInfo() << "Matched" << attr.value().toString() << "with absolute path"; + } + } else if (attr.name() == "duration") { + f->length = attr.value().toLongLong(); + } else if (attr.name() == "using_inout") { + f->using_inout = (attr.value() == "1"); + } else if (attr.name() == "in") { + f->in = attr.value().toLong(); + } else if (attr.name() == "out") { + f->out = attr.value().toLong(); + } else if (attr.name() == "speed") { + f->speed = attr.value().toDouble(); + } else if (attr.name() == "alphapremul") { + f->alpha_is_premultiplied = (attr.value() == "1"); + } else if (attr.name() == "proxy") { + f->proxy = (attr.value() == "1"); + } else if (attr.name() == "proxypath") { + f->proxy_path = attr.value().toString(); + } + } - item->set_footage(f); + while (!cancelled && !(stream.name() == child_search && stream.isEndElement()) && !stream.atEnd()) { + read_next_start_element(stream); + if (stream.name() == "marker" && stream.isStartElement()) { + Marker m; + for (int j=0;jmarkers.append(m); + } + } - if (folder == 0) { - olive::project_model.appendChild(nullptr, item); - } else { - find_loaded_folder_by_id(folder)->appendChild(item); - } + item->set_footage(f); - // analyze media to see if it's the same - loaded_media_items.append(item); - } - break; - case MEDIA_TYPE_SEQUENCE: - { - Media* parent = nullptr; - SequencePtr s(new Sequence()); + if (folder == 0) { + olive::project_model.appendChild(nullptr, item); + } else { + find_loaded_folder_by_id(folder)->appendChild(item); + } - // load attributes about sequence - for (int j=0;jname = attr.value().toString(); - } else if (attr.name() == "folder") { - int folder = attr.value().toInt(); - if (folder > 0) parent = find_loaded_folder_by_id(folder); - } else if (attr.name() == "id") { - s->save_id = attr.value().toInt(); - } else if (attr.name() == "width") { - s->width = attr.value().toInt(); - } else if (attr.name() == "height") { - s->height = attr.value().toInt(); - } else if (attr.name() == "framerate") { - s->frame_rate = attr.value().toDouble(); - } else if (attr.name() == "afreq") { - s->audio_frequency = attr.value().toInt(); - } else if (attr.name() == "alayout") { - s->audio_layout = attr.value().toInt(); - } else if (attr.name() == "open") { - open_seq = s; - } else if (attr.name() == "workarea") { - s->using_workarea = (attr.value() == "1"); - } else if (attr.name() == "workareaIn") { - s->workarea_in = attr.value().toLong(); - } else if (attr.name() == "workareaOut") { - s->workarea_out = attr.value().toLong(); - } - } + // analyze media to see if it's the same + loaded_media_items.append(item); + } + break; + case MEDIA_TYPE_SEQUENCE: + { + Media* parent = nullptr; + SequencePtr s(new Sequence()); - QVector transition_data; + // load attributes about sequence + for (int j=0;jname = attr.value().toString(); + } else if (attr.name() == "folder") { + int folder = attr.value().toInt(); + if (folder > 0) parent = find_loaded_folder_by_id(folder); + } else if (attr.name() == "id") { + s->save_id = attr.value().toInt(); + } else if (attr.name() == "width") { + s->width = attr.value().toInt(); + } else if (attr.name() == "height") { + s->height = attr.value().toInt(); + } else if (attr.name() == "framerate") { + s->frame_rate = attr.value().toDouble(); + } else if (attr.name() == "afreq") { + s->audio_frequency = attr.value().toInt(); + } else if (attr.name() == "alayout") { + s->audio_layout = attr.value().toInt(); + } else if (attr.name() == "open") { + open_seq = s; + } else if (attr.name() == "workarea") { + s->using_workarea = (attr.value() == "1"); + } else if (attr.name() == "workareaIn") { + s->workarea_in = attr.value().toLong(); + } else if (attr.name() == "workareaOut") { + s->workarea_out = attr.value().toLong(); + } + } - // load all clips and clip information - while (!cancelled && !(stream.name() == child_search && stream.isEndElement()) && !stream.atEnd()) { - read_next_start_element(stream); - if (stream.name() == "marker" && stream.isStartElement()) { - Marker m; - for (int j=0;jmarkers.append(m); - } else if (stream.name() == "transition" && stream.isStartElement()) { - TransitionData td; - td.otc = nullptr; - td.ctc = nullptr; - for (int j=0;jmarkers.append(m); + } else if (stream.name() == "clip" && stream.isStartElement()) { + int media_type = -1; + int media_id, stream_id; + ClipPtr c(new Clip(s)); - // backwards compatibility code - c->autoscale = false; - - c->media = nullptr; - - for (int j=0;jname = attr.value().toString(); - } else if (attr.name() == "enabled") { - c->enabled = (attr.value() == "1"); - } else if (attr.name() == "id") { - c->load_id = attr.value().toInt(); - } else if (attr.name() == "clipin") { - c->clip_in = attr.value().toLong(); - } else if (attr.name() == "in") { - c->timeline_in = attr.value().toLong(); - } else if (attr.name() == "out") { - c->timeline_out = attr.value().toLong(); - } else if (attr.name() == "track") { - c->track = attr.value().toInt(); - } else if (attr.name() == "r") { + for (int j=0;jname = attr.value().toString(); + } else if (attr.name() == "enabled") { + c->enabled = (attr.value() == "1"); + } else if (attr.name() == "id") { + c->load_id = attr.value().toInt(); + } else if (attr.name() == "clipin") { + c->clip_in = attr.value().toLong(); + } else if (attr.name() == "in") { + c->timeline_in = attr.value().toLong(); + } else if (attr.name() == "out") { + c->timeline_out = attr.value().toLong(); + } else if (attr.name() == "track") { + c->track = attr.value().toInt(); + } else if (attr.name() == "r") { c->color_r = quint8(attr.value().toInt()); - } else if (attr.name() == "g") { + } else if (attr.name() == "g") { c->color_g = quint8(attr.value().toInt()); - } else if (attr.name() == "b") { + } else if (attr.name() == "b") { c->color_b = quint8(attr.value().toInt()); - } else if (attr.name() == "autoscale") { - c->autoscale = (attr.value() == "1"); - } else if (attr.name() == "media") { - media_type = MEDIA_TYPE_FOOTAGE; - media_id = attr.value().toInt(); - } else if (attr.name() == "stream") { - stream_id = attr.value().toInt(); - } else if (attr.name() == "speed") { - c->speed = attr.value().toDouble(); - } else if (attr.name() == "maintainpitch") { - c->maintain_audio_pitch = (attr.value() == "1"); - } else if (attr.name() == "reverse") { - c->reverse = (attr.value() == "1"); - /* - } else if (attr.name() == "opening") { - c->opening_transition = attr.value().toInt(); - } else if (attr.name() == "closing") { - c->closing_transition = attr.value().toInt(); - */ - } else if (attr.name() == "sequence") { - media_type = MEDIA_TYPE_SEQUENCE; + } else if (attr.name() == "autoscale") { + c->autoscale = (attr.value() == "1"); + } else if (attr.name() == "media") { + media_type = MEDIA_TYPE_FOOTAGE; + media_id = attr.value().toInt(); + } else if (attr.name() == "stream") { + stream_id = attr.value().toInt(); + } else if (attr.name() == "speed") { + c->speed = attr.value().toDouble(); + } else if (attr.name() == "maintainpitch") { + c->maintain_audio_pitch = (attr.value() == "1"); + } else if (attr.name() == "reverse") { + c->reverse = (attr.value() == "1"); + } else if (attr.name() == "sequence") { + media_type = MEDIA_TYPE_SEQUENCE; - // since we haven't finished loading sequences, we defer linking this until later - c->media = nullptr; - c->media_stream = attr.value().toInt(); - loaded_clips.append(c); - } - } + // since we haven't finished loading sequences, we defer linking this until later + c->media = nullptr; + c->media_stream = attr.value().toInt(); + loaded_clips.append(c); + } + } - // set media and media stream - switch (media_type) { - case MEDIA_TYPE_FOOTAGE: - if (media_id >= 0) { - for (int j=0;jto_footage(); - if (m->save_id == media_id) { - c->media = loaded_media_items.at(j); - c->media_stream = stream_id; - break; - } - } - } - break; - } + // set media and media stream + switch (media_type) { + case MEDIA_TYPE_FOOTAGE: + if (media_id >= 0) { + for (int j=0;jto_footage(); + if (m->save_id == media_id) { + c->media = loaded_media_items.at(j); + c->media_stream = stream_id; + break; + } + } + } + break; + } - // load links and effects - while (!cancelled && !(stream.name() == "clip" && stream.isEndElement()) && !stream.atEnd()) { - read_next(stream); - if (stream.isStartElement()) { - if (stream.name() == "linked") { - while (!cancelled && !(stream.name() == "linked" && stream.isEndElement()) && !stream.atEnd()) { - read_next(stream); - if (stream.name() == "link" && stream.isStartElement()) { - for (int k=0;klinked.append(link_attr.value().toInt()); - break; - } - } - } - } - if (cancelled) return false; - } else if (stream.isStartElement() - && (stream.name() == "effect" - || stream.name() == "opening" - || stream.name() == "closing")) { - // "opening" and "closing" are backwards compatibility code - load_effect(stream, c); - } else if (stream.name() == "marker" && stream.isStartElement()) { - Marker m; - for (int j=0;jget_markers().append(m); - } - } - } - if (cancelled) return false; + // load links and effects + while (!cancelled && !(stream.name() == "clip" && stream.isEndElement()) && !stream.atEnd()) { + read_next(stream); + if (stream.isStartElement()) { + if (stream.name() == "linked") { + while (!cancelled && !(stream.name() == "linked" && stream.isEndElement()) && !stream.atEnd()) { + read_next(stream); + if (stream.name() == "link" && stream.isStartElement()) { + for (int k=0;klinked.append(link_attr.value().toInt()); + break; + } + } + } + } + if (cancelled) return false; + } else if (stream.isStartElement() + && (stream.name() == "effect" + || stream.name() == "opening" + || stream.name() == "closing")) { + load_effect(stream, c); + } else if (stream.name() == "marker" && stream.isStartElement()) { + Marker m; + for (int j=0;jget_markers().append(m); + } + } + } + if (cancelled) return false; - s->clips.append(c); - } - } - if (cancelled) return false; + s->clips.append(c); + } + } + if (cancelled) return false; - // correct links, clip IDs, transitions - for (int i=0;iclips.size();i++) { - // correct links - ClipPtr correct_clip = s->clips.at(i); - for (int j=0;jlinked.size();j++) { - bool found = false; - for (int k=0;kclips.size();k++) { - if (s->clips.at(k)->load_id == correct_clip->linked.at(j)) { - correct_clip->linked[j] = k; - found = true; - break; - } - } - if (!found) { - correct_clip->linked.removeAt(j); - j--; + // correct links, clip IDs, transitions + for (int i=0;iclips.size();i++) { + // correct links + ClipPtr correct_clip = s->clips.at(i); + for (int j=0;jlinked.size();j++) { + bool found = false; + for (int k=0;kclips.size();k++) { + if (s->clips.at(k)->load_id == correct_clip->linked.at(j)) { + correct_clip->linked[j] = k; + found = true; + break; + } + } + if (!found) { + correct_clip->linked.removeAt(j); + j--; - emit start_question( - tr("Invalid Clip Link"), - tr("This project contains an invalid clip link. It may be corrupt. Would you like to continue loading it?"), - QMessageBox::Yes | QMessageBox::No - ); - waitCond.wait(&mutex); - if (question_btn == QMessageBox::No) { - s.reset(); - return false; - } - } - } + emit start_question( + tr("Invalid Clip Link"), + tr("This project contains an invalid clip link. It may be corrupt. Would you like to continue loading it?"), + QMessageBox::Yes | QMessageBox::No + ); + waitCond.wait(&mutex); + if (question_btn == QMessageBox::No) { + s.reset(); + return false; + } + } + } + } - /* - // re-link clips to transitions - if (correct_clip->opening_transition > -1) { - for (int j=0;jopening_transition) { - transition_data[j].otc = correct_clip; - } - } - } - if (correct_clip->closing_transition > -1) { - for (int j=0;jclosing_transition) { - transition_data[j].ctc = correct_clip; - } - } - } - } + Media* m = panel_project->create_sequence_internal(nullptr, s, false, parent); - // create transitions - for (int i=0;iopening_transition = -1; - if (td.ctc != nullptr) td.ctc->closing_transition = -1; - } else { - emit start_create_dual_transition(&td, primary, secondary, meta); - - waitCond.wait(&mutex); - } - } - */ - } - - Media* m = panel_project->create_sequence_internal(nullptr, s, false, parent); - - loaded_sequences.append(m); - } - break; - } - } - } - if (cancelled) return false; - } - break; - } - } - return !cancelled; + loaded_sequences.append(m); + } + break; + } + } + } + if (cancelled) return false; + } + break; + } + } + return !cancelled; } Media* LoadThread::find_loaded_folder_by_id(int id) { - if (id == 0) return nullptr; - for (int j=0;jtemp_id == id) { - return parent_item; - } - } - return nullptr; + if (id == 0) return nullptr; + for (int j=0;jtemp_id == id) { + return parent_item; + } + } + return nullptr; } void LoadThread::run() { - mutex.lock(); + mutex.lock(); - QFile file(olive::ActiveProjectFilename); - if (!file.open(QIODevice::ReadOnly)) { - qCritical() << "Could not open file"; - return; - } + QFile file(olive::ActiveProjectFilename); + if (!file.open(QIODevice::ReadOnly)) { + qCritical() << "Could not open file"; + return; + } - /* set up directories to search for media - * most of the time, these will be the same but in - * case the project file has moved without the footage, - * we check both - */ - proj_dir = QFileInfo(olive::ActiveProjectFilename).absoluteDir(); - internal_proj_dir = QFileInfo(olive::ActiveProjectFilename).absoluteDir(); - internal_proj_url = olive::ActiveProjectFilename; + /* set up directories to search for media + * most of the time, these will be the same but in + * case the project file has moved without the footage, + * we check both + */ + proj_dir = QFileInfo(olive::ActiveProjectFilename).absoluteDir(); + internal_proj_dir = QFileInfo(olive::ActiveProjectFilename).absoluteDir(); + internal_proj_url = olive::ActiveProjectFilename; - QXmlStreamReader stream(&file); + QXmlStreamReader stream(&file); - bool cont = false; - error_str.clear(); - show_err = true; + bool cont = false; + error_str.clear(); + show_err = true; - // temp variables for loading (unnecessary?) - open_seq = nullptr; - loaded_folders.clear(); - loaded_media_items.clear(); - loaded_clips.clear(); - loaded_sequences.clear(); + // temp variables for loading (unnecessary?) + open_seq = nullptr; + loaded_folders.clear(); + loaded_media_items.clear(); + loaded_clips.clear(); + loaded_sequences.clear(); - // get "element" count - current_element_count = 0; - total_element_count = 0; - while (!cancelled && !stream.atEnd()) { - stream.readNextStartElement(); - if (is_element(stream)) { - total_element_count++; - } - } - cont = !cancelled; + // get "element" count + current_element_count = 0; + total_element_count = 0; + while (!cancelled && !stream.atEnd()) { + stream.readNextStartElement(); + if (is_element(stream)) { + total_element_count++; + } + } + cont = !cancelled; - // find project file version - if (cont) { - cont = load_worker(file, stream, LOAD_TYPE_VERSION); - } + // find project file version + if (cont) { + cont = load_worker(file, stream, LOAD_TYPE_VERSION); + } - // find project's internal URL - if (cont) { - cont = load_worker(file, stream, LOAD_TYPE_URL); - } + // find project's internal URL + if (cont) { + cont = load_worker(file, stream, LOAD_TYPE_URL); + } - // load folders first - if (cont) { - cont = load_worker(file, stream, MEDIA_TYPE_FOLDER); - } + // load folders first + if (cont) { + cont = load_worker(file, stream, MEDIA_TYPE_FOLDER); + } - // load media - if (cont) { - // since folders loaded correctly, organize them appropriately - for (int i=0;itemp_id2; - if (folder->temp_id2 == 0) { - olive::project_model.appendChild(nullptr, folder); - } else { - find_loaded_folder_by_id(parent)->appendChild(folder); - } - } + // load media + if (cont) { + // since folders loaded correctly, organize them appropriately + for (int i=0;itemp_id2; + if (folder->temp_id2 == 0) { + olive::project_model.appendChild(nullptr, folder); + } else { + find_loaded_folder_by_id(parent)->appendChild(folder); + } + } - cont = load_worker(file, stream, MEDIA_TYPE_FOOTAGE); - } + cont = load_worker(file, stream, MEDIA_TYPE_FOOTAGE); + } - // load sequences - if (cont) { - cont = load_worker(file, stream, MEDIA_TYPE_SEQUENCE); - } + // load sequences + if (cont) { + cont = load_worker(file, stream, MEDIA_TYPE_SEQUENCE); + } - if (!cancelled) { - if (!cont) { - xml_error = false; - if (show_err) emit error(); - } else if (stream.hasError()) { - error_str = tr("%1 - Line: %2 Col: %3").arg(stream.errorString(), QString::number(stream.lineNumber()), QString::number(stream.columnNumber())); - xml_error = true; - emit error(); - cont = false; - } else { - // attach nested sequence clips to their sequences - for (int i=0;imedia == nullptr && loaded_clips.at(i)->media_stream == loaded_sequences.at(j)->to_sequence()->save_id) { - loaded_clips.at(i)->media = loaded_sequences.at(j); - loaded_clips.at(i)->refresh(); - break; - } - } - } - } - } - - if (cont) { - emit success(); // run in main thread - - for (int i=0;istart_preview_generator(loaded_media_items.at(i), true); - } - } else { - if (error_str.isEmpty()) { - error_str = tr("User aborted loading"); + if (!cancelled) { + if (!cont) { + xml_error = false; + if (show_err) emit error(); + } else if (stream.hasError()) { + error_str = tr("%1 - Line: %2 Col: %3").arg(stream.errorString(), QString::number(stream.lineNumber()), QString::number(stream.columnNumber())); + xml_error = true; + emit error(); + cont = false; + } else { + // attach nested sequence clips to their sequences + for (int i=0;imedia == nullptr && loaded_clips.at(i)->media_stream == loaded_sequences.at(j)->to_sequence()->save_id) { + loaded_clips.at(i)->media = loaded_sequences.at(j); + loaded_clips.at(i)->refresh(); + break; + } } + } + } + } - emit error(); - } + if (cont) { + emit success(); // run in main thread - file.close(); + for (int i=0;istart_preview_generator(loaded_media_items.at(i), true); + } + } else { + if (error_str.isEmpty()) { + error_str = tr("User aborted loading"); + } - mutex.unlock(); + emit error(); + } + + file.close(); + + mutex.unlock(); } void LoadThread::cancel() { - waitCond.wakeAll(); - cancelled = true; + waitCond.wakeAll(); + cancelled = true; } void LoadThread::question_func(const QString &title, const QString &text, int buttons) { - mutex.lock(); - question_btn = QMessageBox::warning( - olive::MainWindow, - title, - text, - static_cast(buttons)); - mutex.unlock(); - waitCond.wakeAll(); + mutex.lock(); + question_btn = QMessageBox::warning( + olive::MainWindow, + title, + text, + static_cast(buttons)); + mutex.unlock(); + waitCond.wakeAll(); } void LoadThread::error_func() { - if (xml_error) { - qCritical() << "Error parsing XML." << error_str; - QMessageBox::critical(olive::MainWindow, - tr("XML Parsing Error"), - tr("Couldn't load '%1'. %2").arg(olive::ActiveProjectFilename, error_str), - QMessageBox::Ok); - } else { - QMessageBox::critical(olive::MainWindow, - tr("Project Load Error"), - tr("Error loading project: %1").arg(error_str), - QMessageBox::Ok); - } + if (xml_error) { + qCritical() << "Error parsing XML." << error_str; + QMessageBox::critical(olive::MainWindow, + tr("XML Parsing Error"), + tr("Couldn't load '%1'. %2").arg(olive::ActiveProjectFilename, error_str), + QMessageBox::Ok); + } else { + QMessageBox::critical(olive::MainWindow, + tr("Project Load Error"), + tr("Error loading project: %1").arg(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++; - } + 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++; + } - olive::Global->update_project_filename(orig_filename); - } else { - panel_project->add_recent_project(olive::ActiveProjectFilename); - } + olive::Global->update_project_filename(orig_filename); + } else { + panel_project->add_recent_project(olive::ActiveProjectFilename); + } - olive::MainWindow->setWindowModified(autorecovery); - if (open_seq != nullptr) set_sequence(open_seq); - update_ui(false); + olive::MainWindow->setWindowModified(autorecovery); + if (open_seq != nullptr) set_sequence(open_seq); + update_ui(false); } void LoadThread::create_effect_ui( - QXmlStreamReader* stream, - ClipPtr c, - int type, - const QString* effect_name, - const EffectMeta* meta, - long effect_length, - bool effect_enabled) + QXmlStreamReader* stream, + ClipPtr c, + int type, + const QString* effect_name, + const EffectMeta* meta, + long effect_length, + bool effect_enabled) { - /* This is extremely hacky - prepare yourself. - * - * When moving project loading to a separate thread, it was soon discovered - * that effects wouldn't load correctly anymore. They were actually still - * "functional", but there were no controls appearing in EffectControls. - * - * Turns out since Effect creates its UI in its constructor, the UI was - * created in this thread rather than the main GUI thread, which is a big - * no-no. Unfortunately the design of Effect does not separate UI and data, - * so having the UI set up was integral to creating annd loading the effect. - * - * Therefore, rather than rewrite the class (I just rewrote QTreeWidget to - * QTreeView with a custom model/item so I'm exhausted), for - * quick-n-dirty-ness, I made LoadThread offload the effect creation to the - * main thread (and since the effect loads data from the same XML stream, - * the LoadThread has to wait for the effect to finish before it can - * continue. - * - * Sorry. I'll fix it one day. - */ + /* This is extremely hacky - prepare yourself. + * + * When moving project loading to a separate thread, it was soon discovered + * that effects wouldn't load correctly anymore. They were actually still + * "functional", but there were no controls appearing in EffectControls. + * + * Turns out since Effect creates its UI in its constructor, the UI was + * created in this thread rather than the main GUI thread, which is a big + * no-no. Unfortunately the design of Effect does not separate UI and data, + * so having the UI set up was integral to creating annd loading the effect. + * + * Therefore, rather than rewrite the class (I just rewrote QTreeWidget to + * QTreeView with a custom model/item so I'm exhausted), for + * quick-n-dirty-ness, I made LoadThread offload the effect creation to the + * main thread (and since the effect loads data from the same XML stream, + * the LoadThread has to wait for the effect to finish before it can + * continue. + * + * Sorry. I'll fix it one day. + */ - // lock mutex - ensures the load thread is suspended while this happens - mutex.lock(); + // lock mutex - ensures the load thread is suspended while this happens + mutex.lock(); - if (cancelled) return; - if (type == kTransitionNone) { - if (meta == nullptr) { - // create void effect - EffectPtr ve(new VoidEffect(c, *effect_name)); - ve->set_enabled(effect_enabled); - ve->load(*stream); - c->effects.append(ve); - } else { - EffectPtr e(create_effect(c, meta)); - e->set_enabled(effect_enabled); - e->load(*stream); + if (cancelled) return; + if (type == kTransitionNone) { + if (meta == nullptr) { + // create void effect + EffectPtr ve(new VoidEffect(c, *effect_name)); + ve->set_enabled(effect_enabled); + ve->load(*stream); + c->effects.append(ve); + } else { + EffectPtr e(create_effect(c, meta)); + e->set_enabled(effect_enabled); + e->load(*stream); - c->effects.append(e); - } - } else { - /* - int transition_index = create_transition(c, nullptr, meta); - TransitionPtr t = c->sequence->transitions.at(transition_index); - if (effect_length > -1) t->set_length(effect_length); - t->set_enabled(effect_enabled); - t->load(*stream); + c->effects.append(e); + } + } else { + TransitionPtr t = create_transition(c, nullptr, meta); + if (effect_length > -1) t->set_length(effect_length); + t->set_enabled(effect_enabled); + t->load(*stream); - if (type == kTransitionOpening) { - c->opening_transition = transition_index; - } else { - c->closing_transition = transition_index; - } - */ - } + if (type == kTransitionOpening) { + c->opening_transition = t; + } else { + c->closing_transition = t; + } + } - mutex.unlock(); + mutex.unlock(); - waitCond.wakeAll(); -} - -void LoadThread::create_dual_transition(const TransitionData* td, ClipPtr primary, ClipPtr secondary, const EffectMeta* meta) { - // lock mutex - ensures the load thread is suspended while this happens - mutex.lock(); - - /* - int transition_index = create_transition(primary, secondary, meta); - primary->sequence->transitions.at(transition_index)->set_length(td->length); - if (td->otc != nullptr) td->otc->opening_transition = transition_index; - if (td->ctc != nullptr) td->ctc->closing_transition = transition_index; - */ - - mutex.unlock(); - - // resume load thread - waitCond.wakeAll(); + waitCond.wakeAll(); } diff --git a/io/loadthread.h b/io/loadthread.h index 73ea66951..a9d562137 100644 --- a/io/loadthread.h +++ b/io/loadthread.h @@ -30,69 +30,59 @@ #include "project/projectelements.h" -struct TransitionData { - int id; - QString name; - long length; - ClipPtr otc; - ClipPtr ctc; -}; - class LoadThread : public QThread { - Q_OBJECT + Q_OBJECT public: - LoadThread(bool a); - void run(); - void cancel(); + LoadThread(bool a); + void run(); + void cancel(); signals: - void start_question(const QString &title, const QString &text, int buttons); - void success(); - void error(); - void start_create_effect_ui(QXmlStreamReader* stream, ClipPtr c, int type, const QString *effect_name, const EffectMeta* meta, long effect_length, bool effect_enabled); - void start_create_dual_transition(const TransitionData* td, ClipPtr primary, ClipPtr secondary, const EffectMeta* meta); - void report_progress(int p); + void start_question(const QString &title, const QString &text, int buttons); + void success(); + void error(); + void start_create_effect_ui(QXmlStreamReader* stream, ClipPtr c, int type, const QString *effect_name, const EffectMeta* meta, long effect_length, bool effect_enabled); + void report_progress(int p); private slots: - void question_func(const QString &title, const QString &text, int buttons); - void error_func(); - void success_func(); - void create_effect_ui(QXmlStreamReader* stream, ClipPtr c, int type, const QString *effect_name, const EffectMeta* meta, long effect_length, bool effect_enabled); - void create_dual_transition(const TransitionData* td, ClipPtr primary, ClipPtr secondary, const EffectMeta* meta); + void question_func(const QString &title, const QString &text, int buttons); + void error_func(); + void success_func(); + void create_effect_ui(QXmlStreamReader* stream, ClipPtr c, int type, const QString *effect_name, const EffectMeta* meta, long effect_length, bool effect_enabled); private: - bool autorecovery; + bool autorecovery; - bool load_worker(QFile& f, QXmlStreamReader& stream, int type); - void load_effect(QXmlStreamReader& stream, ClipPtr c); + bool load_worker(QFile& f, QXmlStreamReader& stream, int type); + void load_effect(QXmlStreamReader& stream, ClipPtr c); - void read_next(QXmlStreamReader& stream); - void read_next_start_element(QXmlStreamReader& stream); - void update_current_element_count(QXmlStreamReader& stream); + void read_next(QXmlStreamReader& stream); + void read_next_start_element(QXmlStreamReader& stream); + void update_current_element_count(QXmlStreamReader& stream); - SequencePtr open_seq; - QVector loaded_media_items; - QDir proj_dir; - QDir internal_proj_dir; - QString internal_proj_url; - bool show_err; - QString error_str; + SequencePtr open_seq; + QVector loaded_media_items; + QDir proj_dir; + QDir internal_proj_dir; + QString internal_proj_url; + bool show_err; + QString error_str; - bool is_element(QXmlStreamReader& stream); + bool is_element(QXmlStreamReader& stream); - QVector loaded_folders; - QVector loaded_clips; - QVector loaded_sequences; - Media* find_loaded_folder_by_id(int id); + QVector loaded_folders; + QVector loaded_clips; + QVector loaded_sequences; + Media* find_loaded_folder_by_id(int id); - int current_element_count; - int total_element_count; + int current_element_count; + int total_element_count; - QMutex mutex; - QWaitCondition waitCond; + QMutex mutex; + QWaitCondition waitCond; - bool cancelled; - bool xml_error; + bool cancelled; + bool xml_error; - QMessageBox::StandardButton question_btn; + QMessageBox::StandardButton question_btn; }; #endif // LOADTHREAD_H diff --git a/panels/project.cpp b/panels/project.cpp index ba6311e8c..ee316fb7f 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -1086,21 +1086,8 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, stream.writeAttribute("workareaIn", QString::number(s->workarea_in)); stream.writeAttribute("workareaOut", QString::number(s->workarea_out)); - /* QVector transition_save_cache; QVector transition_clip_save_cache; - QVector transition_type_save_cache; - for (int j=0;jtransitions.size();j++) { - TransitionPtr t = s->transitions.at(j); - if (t != nullptr) { - stream.writeStartElement("transition"); - stream.writeAttribute("id", QString::number(j)); - stream.writeAttribute("length", QString::number(t->get_true_length())); - t->save(stream); - stream.writeEndElement(); // transition - } - } - */ for (int j=0;jclips.size();j++) { const ClipPtr& c = s->clips.at(j); @@ -1153,6 +1140,31 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, } stream.writeEndElement(); // linked + // save opening and closing transitions + for (int t=kTransitionOpening;t<=kTransitionClosing;t++) { + TransitionPtr transition = (t == kTransitionOpening) ? c->opening_transition : c->closing_transition; + + if (transition != nullptr) { + stream.writeStartElement((t == kTransitionOpening) ? "opening" : "closing"); + + // check if this is a shared transition and the transition has already been saved + int transition_cache_index = transition_save_cache.indexOf(transition); + + if (transition_cache_index > -1) { + // if so, just save a reference to the other clip + stream.writeAttribute("shared", + QString::number(transition_clip_save_cache.at(transition_cache_index))); + } else { + // otherwise save the whole transition + transition->save(stream); + transition_save_cache.append(transition); + transition_clip_save_cache.append(j); + } + + stream.writeEndElement(); // opening + } + } + for (int k=0;keffects.size();k++) { stream.writeStartElement("effect"); // effect c->effects.at(k)->save(stream); diff --git a/project/transition.cpp b/project/transition.cpp index d4ff4f6e1..3c4028c71 100644 --- a/project/transition.cpp +++ b/project/transition.cpp @@ -59,6 +59,11 @@ TransitionPtr Transition::copy(ClipPtr c, ClipPtr s) { return create_transition(c, s, meta, length); } +void Transition::save(QXmlStreamWriter &stream) { + stream.writeAttribute("length", QString::number(get_true_length())); + Effect::save(stream); +} + void Transition::set_length(long l) { length = l; length_field->set_double_value(l); diff --git a/project/transition.h b/project/transition.h index b8677b119..ec6352398 100644 --- a/project/transition.h +++ b/project/transition.h @@ -51,6 +51,9 @@ public: Transition(ClipPtr c, ClipPtr s, const EffectMeta* em); virtual TransitionPtr copy(ClipPtr c, ClipPtr s); ClipPtr secondary_clip; + + virtual void save(QXmlStreamWriter& stream) override; + void set_length(long l); long get_true_length(); long get_length(); From 7efea428c75e78f16044171b2ed8a6e2b1bdd10c Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Tue, 19 Feb 2019 02:28:50 -0800 Subject: [PATCH 22/30] some refactoring work --- Doxyfile | 2 +- io/config.cpp | 12 ++-- io/config.h | 53 +++++++++-------- io/loadthread.cpp | 4 +- mainwindow.cpp | 14 ++--- panels/project.cpp | 24 ++++---- panels/timeline.cpp | 4 +- panels/viewer.cpp | 32 +++++----- panels/viewer.h | 2 +- playback/cacher.cpp | 4 +- playback/playback.cpp | 6 +- ui/graphview.cpp | 127 ++++++++++++++++++++-------------------- ui/graphview.h | 132 +++++++++++++++++++++--------------------- ui/timelinetools.h | 25 ++++---- 14 files changed, 223 insertions(+), 218 deletions(-) diff --git a/Doxyfile b/Doxyfile index bddbd4e1c..eab2bc788 100644 --- a/Doxyfile +++ b/Doxyfile @@ -457,7 +457,7 @@ LOOKUP_CACHE_SIZE = 0 # normally produced when WARNINGS is set to YES. # The default value is: NO. -EXTRACT_ALL = NO +EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. diff --git a/io/config.cpp b/io/config.cpp index d4cbac676..97f53aa92 100644 --- a/io/config.cpp +++ b/io/config.cpp @@ -43,7 +43,7 @@ Config::Config() img_seq_formats("jpg|jpeg|bmp|tiff|tif|psd|png|tga|jp2|gif"), rectified_waveforms(false), default_transition_length(30), - timecode_view(TIMECODE_DROP), + timecode_view(olive::kTimecodeDrop), show_title_safe_area(false), use_custom_title_safe_ratio(false), custom_title_safe_ratio(1), @@ -53,17 +53,17 @@ Config::Config() enable_seek_to_import(false), enable_audio_scrubbing(true), drop_on_media_to_replace(true), - autoscroll(AUTOSCROLL_PAGE_SCROLL), + autoscroll(olive::AUTOSCROLL_PAGE_SCROLL), audio_rate(48000), fast_seeking(false), hover_focus(false), - project_view_type(PROJECT_VIEW_TREE), + project_view_type(olive::PROJECT_VIEW_TREE), set_name_with_marker(true), show_project_toolbar(false), previous_queue_size(3), - previous_queue_type(FRAME_QUEUE_TYPE_FRAMES), + previous_queue_type(olive::FRAME_QUEUE_TYPE_FRAMES), upcoming_queue_size(0.5), - upcoming_queue_type(FRAME_QUEUE_TYPE_SECONDS), + upcoming_queue_type(olive::FRAME_QUEUE_TYPE_SECONDS), loop(false), seek_also_selects(false), effect_textbox_lines(3), @@ -234,7 +234,7 @@ void Config::save(QString path) { stream.writeStartDocument(); // doc stream.writeStartElement("Configuration"); // configuration - stream.writeTextElement("Version", QString::number(SAVE_VERSION)); + stream.writeTextElement("Version", QString::number(olive::kSaveVersion)); stream.writeTextElement("SavedLayout", QString::number(saved_layout)); stream.writeTextElement("ShowTrackLines", QString::number(show_track_lines)); stream.writeTextElement("ScrollZooms", QString::number(scroll_zooms)); diff --git a/io/config.h b/io/config.h index ea9614e00..bf91f8bde 100644 --- a/io/config.h +++ b/io/config.h @@ -23,36 +23,39 @@ #include -#define SAVE_VERSION 190219 // YYMMDD -#define MIN_SAVE_VERSION 190219 // lowest compatible project version +namespace olive { + const int kSaveVersion = 190219; // YYMMDD + const int kMinimumSaveVersion = 190219; // lowest compatible project version -enum TimecodeType { - TIMECODE_DROP, - TIMECODE_NONDROP, - TIMECODE_FRAMES, - TIMECODE_MILLISECONDS -}; + enum TimecodeType { + kTimecodeDrop, + kTimecodeNonDrop, + kTimecodeFrames, + kTimecodeMilliseconds + }; -enum RecordingMode { - RECORD_MODE_MONO, - RECORD_MODE_STEREO -}; + enum RecordingMode { + RECORD_MODE_MONO, + RECORD_MODE_STEREO + }; -enum AutoScrollMode { - AUTOSCROLL_NO_SCROLL, - AUTOSCROLL_PAGE_SCROLL, - AUTOSCROLL_SMOOTH_SCROLL -}; + enum AutoScrollMode { + AUTOSCROLL_NO_SCROLL, + AUTOSCROLL_PAGE_SCROLL, + AUTOSCROLL_SMOOTH_SCROLL + }; -enum ProjectView { - PROJECT_VIEW_TREE, - PROJECT_VIEW_ICON -}; + enum ProjectView { + PROJECT_VIEW_TREE, + PROJECT_VIEW_ICON + }; + + enum FrameQueueType { + FRAME_QUEUE_TYPE_FRAMES, + FRAME_QUEUE_TYPE_SECONDS + }; +} -enum FrameQueueType { - FRAME_QUEUE_TYPE_FRAMES, - FRAME_QUEUE_TYPE_SECONDS -}; struct Config { Config(); diff --git a/io/loadthread.cpp b/io/loadthread.cpp index 42a970673..270bea571 100644 --- a/io/loadthread.cpp +++ b/io/loadthread.cpp @@ -169,14 +169,14 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) { show_err = true; - int proj_version = SAVE_VERSION; + int proj_version = olive::kSaveVersion; while (!stream.atEnd() && !cancelled) { read_next_start_element(stream); if (stream.name() == root_search) { if (type == LOAD_TYPE_VERSION) { proj_version = stream.readElementText().toInt(); - if (proj_version < MIN_SAVE_VERSION || proj_version > SAVE_VERSION) { + if (proj_version < olive::kMinimumSaveVersion || proj_version > olive::kSaveVersion) { emit start_question( tr("Version Mismatch"), tr("This project was saved in a different version of Olive and may not be fully compatible with this version. Would you like to attempt loading it anyway?"), diff --git a/mainwindow.cpp b/mainwindow.cpp index 1ee7b1b72..9b5fa3505 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -449,19 +449,19 @@ void MainWindow::setup_menus() { frames_action = view_menu->addAction(tr("Frames"), &olive::MenuHelper, SLOT(set_timecode_view())); frames_action->setProperty("id", "modeframes"); - frames_action->setData(TIMECODE_FRAMES); + frames_action->setData(olive::kTimecodeFrames); frames_action->setCheckable(true); drop_frame_action = view_menu->addAction(tr("Drop Frame"), &olive::MenuHelper, SLOT(set_timecode_view())); drop_frame_action->setProperty("id", "modedropframe"); - drop_frame_action->setData(TIMECODE_DROP); + drop_frame_action->setData(olive::kTimecodeDrop); drop_frame_action->setCheckable(true); nondrop_frame_action = view_menu->addAction(tr("Non-Drop Frame"), &olive::MenuHelper, SLOT(set_timecode_view())); nondrop_frame_action->setProperty("id", "modenondropframe"); - nondrop_frame_action->setData(TIMECODE_NONDROP); + nondrop_frame_action->setData(olive::kTimecodeNonDrop); nondrop_frame_action->setCheckable(true); milliseconds_action = view_menu->addAction(tr("Milliseconds"), &olive::MenuHelper, SLOT(set_timecode_view())); milliseconds_action->setProperty("id", "milliseconds"); - milliseconds_action->setData(TIMECODE_MILLISECONDS); + milliseconds_action->setData(olive::kTimecodeMilliseconds); milliseconds_action->setCheckable(true); view_menu->addSeparator(); @@ -700,17 +700,17 @@ void MainWindow::setup_menus() { no_autoscroll = tools_menu->addAction(tr("No Auto-Scroll"), &olive::MenuHelper, SLOT(set_autoscroll())); no_autoscroll->setProperty("id", "autoscrollno"); - no_autoscroll->setData(AUTOSCROLL_NO_SCROLL); + no_autoscroll->setData(olive::AUTOSCROLL_NO_SCROLL); no_autoscroll->setCheckable(true); page_autoscroll = tools_menu->addAction(tr("Page Auto-Scroll"), &olive::MenuHelper, SLOT(set_autoscroll())); page_autoscroll->setProperty("id", "autoscrollpage"); - page_autoscroll->setData(AUTOSCROLL_PAGE_SCROLL); + page_autoscroll->setData(olive::AUTOSCROLL_PAGE_SCROLL); page_autoscroll->setCheckable(true); smooth_autoscroll = tools_menu->addAction(tr("Smooth Auto-Scroll"), &olive::MenuHelper, SLOT(set_autoscroll())); smooth_autoscroll->setProperty("id", "autoscrollsmooth"); - smooth_autoscroll->setData(AUTOSCROLL_SMOOTH_SCROLL); + smooth_autoscroll->setData(olive::AUTOSCROLL_SMOOTH_SCROLL); smooth_autoscroll->setCheckable(true); tools_menu->addSeparator(); diff --git a/panels/project.cpp b/panels/project.cpp index ee316fb7f..ecc4efb37 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -432,10 +432,10 @@ void Project::new_folder() { QModelIndex index = olive::project_model.create_index(m->row(), 0, m); switch (olive::CurrentConfig.project_view_type) { - case PROJECT_VIEW_TREE: + case olive::PROJECT_VIEW_TREE: tree_view->edit(sorter->mapFromSource(index)); break; - case PROJECT_VIEW_ICON: + case olive::PROJECT_VIEW_ICON: icon_view->edit(sorter->mapFromSource(index)); break; } @@ -871,7 +871,7 @@ bool Project::reveal_media(Media *media, QModelIndex parent) { // retrieve its parent item QModelIndex hierarchy = sorted_index.parent(); - if (olive::CurrentConfig.project_view_type == PROJECT_VIEW_TREE) { + if (olive::CurrentConfig.project_view_type == olive::PROJECT_VIEW_TREE) { // if we're in tree view, expand every folder in the hierarchy containing the media while (hierarchy.isValid()) { @@ -886,7 +886,7 @@ bool Project::reveal_media(Media *media, QModelIndex parent) { ); tree_view->selectionModel()->select(row_select, QItemSelectionModel::Select); - } else if (olive::CurrentConfig.project_view_type == PROJECT_VIEW_ICON) { + } else if (olive::CurrentConfig.project_view_type == olive::PROJECT_VIEW_ICON) { // if we're in icon view, we just "browse" to the parent folder icon_view->setRootIndex(hierarchy); @@ -1206,7 +1206,7 @@ void Project::save_project(bool autorecovery) { stream.writeStartElement("project"); // project - stream.writeTextElement("version", QString::number(SAVE_VERSION)); + stream.writeTextElement("version", QString::number(olive::kSaveVersion)); stream.writeTextElement("url", olive::ActiveProjectFilename); proj_dir = QFileInfo(olive::ActiveProjectFilename).absoluteDir(); @@ -1240,26 +1240,26 @@ void Project::save_project(bool autorecovery) { } void Project::update_view_type() { - tree_view->setVisible(olive::CurrentConfig.project_view_type == PROJECT_VIEW_TREE); - icon_view_container->setVisible(olive::CurrentConfig.project_view_type == PROJECT_VIEW_ICON); + tree_view->setVisible(olive::CurrentConfig.project_view_type == olive::PROJECT_VIEW_TREE); + icon_view_container->setVisible(olive::CurrentConfig.project_view_type == olive::PROJECT_VIEW_ICON); switch (olive::CurrentConfig.project_view_type) { - case PROJECT_VIEW_TREE: + case olive::PROJECT_VIEW_TREE: sources_common->view = tree_view; break; - case PROJECT_VIEW_ICON: + case olive::PROJECT_VIEW_ICON: sources_common->view = icon_view; break; } } void Project::set_icon_view() { - olive::CurrentConfig.project_view_type = PROJECT_VIEW_ICON; + olive::CurrentConfig.project_view_type = olive::PROJECT_VIEW_ICON; update_view_type(); } void Project::set_tree_view() { - olive::CurrentConfig.project_view_type = PROJECT_VIEW_TREE; + olive::CurrentConfig.project_view_type = olive::PROJECT_VIEW_TREE; update_view_type(); } @@ -1343,7 +1343,7 @@ QVector Project::list_all_project_sequences() { } QModelIndexList Project::get_current_selected() { - if (olive::CurrentConfig.project_view_type == PROJECT_VIEW_TREE) { + if (olive::CurrentConfig.project_view_type == olive::PROJECT_VIEW_TREE) { return tree_view->selectionModel()->selectedRows(); } return icon_view->selectionModel()->selectedIndexes(); diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 227dd50b2..0b859c642 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -502,13 +502,13 @@ void Timeline::repaint_timeline() { && panel_sequence_viewer->playing && !zoom_just_changed) { // auto scroll - if (olive::CurrentConfig.autoscroll == AUTOSCROLL_PAGE_SCROLL) { + if (olive::CurrentConfig.autoscroll == olive::AUTOSCROLL_PAGE_SCROLL) { int playhead_x = getTimelineScreenPointFromFrame(olive::ActiveSequence->playhead); if (playhead_x < 0 || playhead_x > (editAreas->width() - videoScrollbar->width())) { horizontalScrollBar->setValue(getScreenPointFromFrame(zoom, olive::ActiveSequence->playhead)); draw = false; } - } else if (olive::CurrentConfig.autoscroll == AUTOSCROLL_SMOOTH_SCROLL) { + } else if (olive::CurrentConfig.autoscroll == olive::AUTOSCROLL_SMOOTH_SCROLL) { if (center_scroll_to_playhead(horizontalScrollBar, zoom, olive::ActiveSequence->playhead)) { draw = false; } diff --git a/panels/viewer.cpp b/panels/viewer.cpp index 79d5321ef..06173285c 100644 --- a/panels/viewer.cpp +++ b/panels/viewer.cpp @@ -144,14 +144,14 @@ void Viewer::reset_all_audio() { long timecode_to_frame(const QString& s, int view, double frame_rate) { QList list = s.split(QRegExp("[:;]")); - if (view == TIMECODE_FRAMES || (list.size() == 1 && view != TIMECODE_MILLISECONDS)) { + if (view == olive::kTimecodeFrames || (list.size() == 1 && view != olive::kTimecodeMilliseconds)) { return s.toLong(); } int frRound = qRound(frame_rate); int hours, minutes, seconds, frames; - if (view == TIMECODE_MILLISECONDS) { + if (view == olive::kTimecodeMilliseconds) { long milliseconds = s.toLong(); hours = milliseconds/3600000; @@ -174,14 +174,14 @@ long timecode_to_frame(const QString& s, int view, double frame_rate) { int f = (frames + seconds + minutes + hours); - if ((view == TIMECODE_DROP || view == TIMECODE_MILLISECONDS) && frame_rate_is_droppable(frame_rate)) { + if ((view == olive::kTimecodeDrop || view == olive::kTimecodeMilliseconds) && frame_rate_is_droppable(frame_rate)) { // return drop int d; int m; - int dropFrames = round(frame_rate * .066666); //Number of frames to drop on the minute marks is the nearest integer to 6% of the framerate - int framesPer10Minutes = round(frame_rate * 60 * 10); //Number of frames per ten minutes - int framesPerMinute = (round(frame_rate)*60)- dropFrames; //Number of frames per minute is the round of the framerate * 60 minus the number of dropped frames + int dropFrames = qRound(frame_rate * .066666); //Number of frames to drop on the minute marks is the nearest integer to 6% of the framerate + int framesPer10Minutes = qRound(frame_rate * 60 * 10); //Number of frames per ten minutes + int framesPerMinute = (qRound(frame_rate)*60)- dropFrames; //Number of frames per minute is the round of the framerate * 60 minus the number of dropped frames d = f / framesPer10Minutes; f -= dropFrames*9*d; @@ -198,7 +198,7 @@ long timecode_to_frame(const QString& s, int view, double frame_rate) { } QString frame_to_timecode(long f, int view, double frame_rate) { - if (view == TIMECODE_FRAMES) { + if (view == olive::kTimecodeFrames) { return QString::number(f); } @@ -209,7 +209,7 @@ QString frame_to_timecode(long f, int view, double frame_rate) { int frames = 0; QString token = ":"; - if ((view == TIMECODE_DROP || view == TIMECODE_MILLISECONDS) && frame_rate_is_droppable(frame_rate)) { + if ((view == olive::kTimecodeDrop || view == olive::kTimecodeMilliseconds) && frame_rate_is_droppable(frame_rate)) { //CONVERT A FRAME NUMBER TO DROP FRAME TIMECODE //Code by David Heidelberger, adapted from Andrew Duncan, further adapted for Olive by Olive Team //Given an int called framenumber and a double called framerate @@ -218,11 +218,11 @@ QString frame_to_timecode(long f, int view, double frame_rate) { int d; int m; - int dropFrames = round(frame_rate * .066666); //Number of frames to drop on the minute marks is the nearest integer to 6% of the framerate - int framesPerHour = round(frame_rate*60*60); //Number of frqRound64ames in an hour + int dropFrames = qRound(frame_rate * .066666); //Number of frames to drop on the minute marks is the nearest integer to 6% of the framerate + int framesPerHour = qRound(frame_rate*60*60); //Number of frqRound64ames in an hour int framesPer24Hours = framesPerHour*24; //Number of frames in a day - timecode rolls over after 24 hours - int framesPer10Minutes = round(frame_rate * 60 * 10); //Number of frames per ten minutes - int framesPerMinute = (round(frame_rate)*60)- dropFrames; //Number of frames per minute is the round of the framerate * 60 minus the number of dropped frames + int framesPer10Minutes = qRound(frame_rate * 60 * 10); //Number of frames per ten minutes + int framesPerMinute = (qRound(frame_rate)*60)- dropFrames; //Number of frames per minute is the round of the framerate * 60 minus the number of dropped frames //If framenumber is greater than 24 hrs, next operation will rollover clock f = f % framesPer24Hours; //% is the modulus operator, which returns a remainder. a % b = the remainder of a/b @@ -237,7 +237,7 @@ QString frame_to_timecode(long f, int view, double frame_rate) { f = f + dropFrames*9*d; } - int frRound = round(frame_rate); + int frRound = qRound(frame_rate); frames = f % frRound; secs = (f / frRound) % 60; mins = ((f / frRound) / 60) % 60; @@ -253,7 +253,7 @@ QString frame_to_timecode(long f, int view, double frame_rate) { secs = f/int_fps % 60; frames = f%int_fps; } - if (view == TIMECODE_MILLISECONDS) { + if (view == olive::kTimecodeMilliseconds) { return QString::number((hours*3600000)+(mins*60000)+(secs*1000)+qCeil(frames*1000/frame_rate)); } return QString(QString::number(hours).rightJustified(2, '0') + @@ -263,8 +263,8 @@ QString frame_to_timecode(long f, int view, double frame_rate) { ); } -bool frame_rate_is_droppable(float rate) { - return (qFuzzyCompare(rate, 23.976f) || qFuzzyCompare(rate, 29.97f) || qFuzzyCompare(rate, 59.94f)); +bool frame_rate_is_droppable(double rate) { + return (qFuzzyCompare(rate, 23.976) || qFuzzyCompare(rate, 29.97) || qFuzzyCompare(rate, 59.94)); } void Viewer::seek(long p) { diff --git a/panels/viewer.h b/panels/viewer.h index f27a2cb24..0333966a8 100644 --- a/panels/viewer.h +++ b/panels/viewer.h @@ -36,7 +36,7 @@ #include "ui/labelslider.h" #include "ui/resizablescrollbar.h" -bool frame_rate_is_droppable(float rate); +bool frame_rate_is_droppable(double rate); long timecode_to_frame(const QString& s, int view, double frame_rate); QString frame_to_timecode(long f, int view, double frame_rate); diff --git a/playback/cacher.cpp b/playback/cacher.cpp index f974c8788..744080115 100644 --- a/playback/cacher.cpp +++ b/playback/cacher.cpp @@ -743,12 +743,12 @@ void open_clip_worker(ClipPtr clip) { clip->max_queue_size = 1; } else { clip->max_queue_size = 0; - if (olive::CurrentConfig.upcoming_queue_type == FRAME_QUEUE_TYPE_FRAMES) { + if (olive::CurrentConfig.upcoming_queue_type == olive::FRAME_QUEUE_TYPE_FRAMES) { clip->max_queue_size += qCeil(olive::CurrentConfig.upcoming_queue_size); } else { clip->max_queue_size += qCeil(ms->video_frame_rate * m->speed * olive::CurrentConfig.upcoming_queue_size); } - if (olive::CurrentConfig.previous_queue_type == FRAME_QUEUE_TYPE_FRAMES) { + if (olive::CurrentConfig.previous_queue_type == olive::FRAME_QUEUE_TYPE_FRAMES) { clip->max_queue_size += qCeil(olive::CurrentConfig.previous_queue_size); } else { clip->max_queue_size += qCeil(ms->video_frame_rate * m->speed * olive::CurrentConfig.previous_queue_size); diff --git a/playback/playback.cpp b/playback/playback.cpp index 000fb1735..55331e932 100644 --- a/playback/playback.cpp +++ b/playback/playback.cpp @@ -204,7 +204,7 @@ void get_clip_frame(ClipPtr c, long playhead, bool& texture_failed) { int64_t minimum_ts = target_frame->pts; int previous_frame_count = 0; - if (olive::CurrentConfig.previous_queue_type == FRAME_QUEUE_TYPE_SECONDS) { + if (olive::CurrentConfig.previous_queue_type == olive::FRAME_QUEUE_TYPE_SECONDS) { minimum_ts -= (second_pts*olive::CurrentConfig.previous_queue_size); } @@ -214,7 +214,7 @@ void get_clip_frame(ClipPtr c, long playhead, bool& texture_failed) { next_pts = c->queue.at(i)->pts; } if (c->queue.at(i) != target_frame && ((c->queue.at(i)->pts > minimum_ts) == c->reverse)) { - if (olive::CurrentConfig.previous_queue_type == FRAME_QUEUE_TYPE_SECONDS) { + if (olive::CurrentConfig.previous_queue_type == olive::FRAME_QUEUE_TYPE_SECONDS) { //dout << "removed frame at" << i << "because its pts was" << c->queue.at(i)->pts << "compared to" << target_frame->pts; av_frame_free(&c->queue[i]); // may be a little heavy for the main thread? c->queue.removeAt(i); @@ -226,7 +226,7 @@ void get_clip_frame(ClipPtr c, long playhead, bool& texture_failed) { } } - if (olive::CurrentConfig.previous_queue_type == FRAME_QUEUE_TYPE_FRAMES) { + if (olive::CurrentConfig.previous_queue_type == olive::FRAME_QUEUE_TYPE_FRAMES) { while (previous_frame_count > qCeil(olive::CurrentConfig.previous_queue_size)) { int smallest = 0; for (int i=1;iqueue.size();i++) { diff --git a/ui/graphview.cpp b/ui/graphview.cpp index bd87a8de3..4bcf35a9c 100644 --- a/ui/graphview.cpp +++ b/ui/graphview.cpp @@ -30,8 +30,6 @@ #include "panels/timeline.h" #include "panels/viewer.h" #include "project/sequence.h" -#include "project/effectrow.h" -#include "project/effectfield.h" #include "ui/keyframedrawing.h" #include "project/undo.h" #include "project/effect.h" @@ -40,14 +38,15 @@ #include "debug.h" -#define GRAPH_ZOOM_SPEED 0.05 -#define GRAPH_SIZE 100 -#define BEZIER_HANDLE_SIZE 3 -#define BEZIER_LINE_SIZE 2 -#define BEZIER_HANDLE_NONE 1 -#define BEZIER_HANDLE_PRE 2 -#define BEZIER_HANDLE_POST 3 +const double kGraphZoomSpeed = 0.05; +const int kGraphSize = 100; +const int kBezierHandleSize = 3; +const int kBezierLineSize = 2; + +const int kBezierHandleNone = 1; +const int kBezierHandlePre = 2; +const int kBezierHandlePost = 3; QColor get_curve_color(int index, int length) { QColor c; @@ -56,20 +55,20 @@ QColor get_curve_color(int index, int length) { return c; } -GraphView::GraphView(QWidget* parent) : - QWidget(parent), - x_scroll(0), - y_scroll(0), - mousedown(false), - x_zoom(1.0), - y_zoom(1.0), - row(nullptr), - moved_keys(false), - current_handle(BEZIER_HANDLE_NONE), - rect_select(false), - visible_in(0), - click_add_proc(false) +GraphView::GraphView(QWidget* parent) : QWidget(parent) { + x_scroll = 0; + y_scroll = 0; + mousedown = false; + x_zoom = 1.0; + y_zoom = 1.0; + row = nullptr; + moved_keys = false; + current_handle = kBezierHandleNone; + rect_select = false; + visible_in = 0; + click_add_proc = false; + setMouseTracking(true); setFocusPolicy(Qt::ClickFocus); setContextMenuPolicy(Qt::CustomContextMenu); @@ -176,7 +175,7 @@ void GraphView::set_view_to_rect(int x1, double y1, int x2, double y2) { void GraphView::draw_line_text(QPainter &p, bool vert, int line_no, int line_pos, int next_line_pos) { // draws last line's text - QString str = QString::number(line_no*GRAPH_SIZE); + QString str = QString::number(line_no*kGraphSize); int text_sz = vert ? fontMetrics().height() : fontMetrics().width(str); if (text_sz < (next_line_pos - line_pos)) { QRect text_rect = vert ? QRect(0, line_pos-50, 50, 50) : QRect(line_pos, height()-50, 50, 50); @@ -191,7 +190,7 @@ void GraphView::draw_lines(QPainter& p, bool vert) { int scroll = vert ? y_scroll : x_scroll; for (int i=0;ifieldCount()-1;i>=0;i--) { EffectField* field = row->field(i); @@ -321,12 +320,12 @@ void GraphView::paintEvent(QPaintEvent *) { // pre handle line QPointF pre_point(key_x + key.pre_handle_x*x_zoom, key_y - key.pre_handle_y*y_zoom); p.drawLine(pre_point, QPointF(key_x, key_y)); - p.drawEllipse(pre_point, BEZIER_HANDLE_SIZE, BEZIER_HANDLE_SIZE); + p.drawEllipse(pre_point, kBezierHandleSize, kBezierHandleSize); // post handle line QPointF post_point(key_x + key.post_handle_x*x_zoom, key_y - key.post_handle_y*y_zoom); p.drawLine(post_point, QPointF(key_x, key_y)); - p.drawEllipse(post_point, BEZIER_HANDLE_SIZE, BEZIER_HANDLE_SIZE); + p.drawEllipse(post_point, kBezierHandleSize, kBezierHandleSize); } bool selected = false; @@ -371,7 +370,7 @@ void GraphView::mousePressEvent(QMouseEvent *event) { // selecting int sel_key = -1; int sel_key_field = -1; - current_handle = BEZIER_HANDLE_NONE; + current_handle = kBezierHandleNone; if (click_add && (event->buttons() & Qt::LeftButton)) { selected_keys.clear(); @@ -404,19 +403,19 @@ void GraphView::mousePressEvent(QMouseEvent *event) { // selecting a handle QPointF pre_point(key_x + key.pre_handle_x*x_zoom, key_y - key.pre_handle_y*y_zoom); QPointF post_point(key_x + key.post_handle_x*x_zoom, key_y - key.post_handle_y*y_zoom); - if (event->pos().x() > pre_point.x()-BEZIER_HANDLE_SIZE - && event->pos().x() < pre_point.x()+BEZIER_HANDLE_SIZE - && event->pos().y() > pre_point.y()-BEZIER_HANDLE_SIZE - && event->pos().y() < pre_point.y()+BEZIER_HANDLE_SIZE) { - current_handle = BEZIER_HANDLE_PRE; - } else if (event->pos().x() > post_point.x()-BEZIER_HANDLE_SIZE - && event->pos().x() < post_point.x()+BEZIER_HANDLE_SIZE - && event->pos().y() > post_point.y()-BEZIER_HANDLE_SIZE - && event->pos().y() < post_point.y()+BEZIER_HANDLE_SIZE) { - current_handle = BEZIER_HANDLE_POST; + if (event->pos().x() > pre_point.x()-kBezierHandleSize + && event->pos().x() < pre_point.x()+kBezierHandleSize + && event->pos().y() > pre_point.y()-kBezierHandleSize + && event->pos().y() < pre_point.y()+kBezierHandleSize) { + current_handle = kBezierHandlePre; + } else if (event->pos().x() > post_point.x()-kBezierHandleSize + && event->pos().x() < post_point.x()+kBezierHandleSize + && event->pos().y() > post_point.y()-kBezierHandleSize + && event->pos().y() < post_point.y()+kBezierHandleSize) { + current_handle = kBezierHandlePost; } - if (current_handle != BEZIER_HANDLE_NONE) { + if (current_handle != kBezierHandleNone) { sel_key = j; sel_key_field = i; handle_index = j; @@ -437,7 +436,7 @@ void GraphView::mousePressEvent(QMouseEvent *event) { if (sel_key > -1) { for (int i=0;imodifiers() & Qt::ShiftModifier) && current_handle == BEZIER_HANDLE_NONE) { + if ((event->modifiers() & Qt::ShiftModifier) && current_handle == kBezierHandleNone) { selected_keys.removeAt(i); selected_keys_fields.removeAt(i); } @@ -513,7 +512,7 @@ void GraphView::mouseMoveEvent(QMouseEvent *event) { update(); } else { switch (current_handle) { - case BEZIER_HANDLE_NONE: + case kBezierHandleNone: for (int i=0;ifield(selected_keys_fields.at(i))->keyframes[selected_keys.at(i)].time = qRound(selected_keys_old_vals.at(i) + (double(event->pos().x() - start_x)/x_zoom)); if (event->modifiers() & Qt::ShiftModifier) { @@ -525,8 +524,8 @@ void GraphView::mouseMoveEvent(QMouseEvent *event) { moved_keys = true; update_ui(false); break; - case BEZIER_HANDLE_PRE: - case BEZIER_HANDLE_POST: + case kBezierHandlePre: + case kBezierHandlePost: { double new_pre_handle_x = old_pre_handle_x; double new_pre_handle_y = old_pre_handle_y; @@ -536,7 +535,7 @@ void GraphView::mouseMoveEvent(QMouseEvent *event) { double x_diff = double(event->pos().x() - start_x)/x_zoom; double y_diff = double(start_y - event->pos().y())/y_zoom; - if (current_handle == BEZIER_HANDLE_PRE) { + if (current_handle == kBezierHandlePre) { new_pre_handle_x += x_diff; if (!(event->modifiers() & Qt::ShiftModifier)) new_pre_handle_y += y_diff; if (!(event->modifiers() & Qt::ControlModifier)) { @@ -582,16 +581,16 @@ void GraphView::mouseMoveEvent(QMouseEvent *event) { KEYFRAME_SIZE+KEYFRAME_SIZE ); QRect pre_rect( - qRound(key_x + key.pre_handle_x*x_zoom - BEZIER_HANDLE_SIZE), - qRound(key_y + key.pre_handle_y*y_zoom - BEZIER_HANDLE_SIZE), - BEZIER_HANDLE_SIZE+BEZIER_HANDLE_SIZE, - BEZIER_HANDLE_SIZE+BEZIER_HANDLE_SIZE + qRound(key_x + key.pre_handle_x*x_zoom - kBezierHandleSize), + qRound(key_y + key.pre_handle_y*y_zoom - kBezierHandleSize), + kBezierHandleSize+kBezierHandleSize, + kBezierHandleSize+kBezierHandleSize ); QRect post_rect( - qRound(key_x + key.post_handle_x*x_zoom - BEZIER_HANDLE_SIZE), - qRound(key_y + key.post_handle_y*y_zoom - BEZIER_HANDLE_SIZE), - BEZIER_HANDLE_SIZE+BEZIER_HANDLE_SIZE, - BEZIER_HANDLE_SIZE+BEZIER_HANDLE_SIZE + qRound(key_x + key.post_handle_x*x_zoom - kBezierHandleSize), + qRound(key_y + key.post_handle_y*y_zoom - kBezierHandleSize), + kBezierHandleSize+kBezierHandleSize, + kBezierHandleSize+kBezierHandleSize ); if (test_rect.contains(event->pos()) @@ -611,16 +610,16 @@ void GraphView::mouseMoveEvent(QMouseEvent *event) { if (event->pos().x() <= get_screen_x(f->keyframes.at(sorted_keys.first()).time)) { int y_comp = get_screen_y(f->keyframes.at(sorted_keys.first()).data.toDouble()); - if (event->pos().y() >= y_comp-BEZIER_LINE_SIZE - && event->pos().y() <= y_comp+BEZIER_LINE_SIZE) { + if (event->pos().y() >= y_comp-kBezierLineSize + && event->pos().y() <= y_comp+kBezierLineSize) { // dout << "make an EARLY key on field" << i; click_add = true; click_add_type = f->keyframes.at(sorted_keys.first()).type; } } else if (event->pos().x() >= get_screen_x(f->keyframes.at(sorted_keys.last()).time)) { int y_comp = get_screen_y(f->keyframes.at(sorted_keys.last()).data.toDouble()); - if (event->pos().y() >= y_comp-BEZIER_LINE_SIZE - && event->pos().y() <= y_comp+BEZIER_LINE_SIZE) { + if (event->pos().y() >= y_comp-kBezierLineSize + && event->pos().y() <= y_comp+kBezierLineSize) { // dout << "make an LATE key on field" << i; click_add = true; click_add_type = f->keyframes.at(sorted_keys.last()).type; @@ -639,12 +638,12 @@ void GraphView::mouseMoveEvent(QMouseEvent *event) { if (event->pos().x() >= last_key_x && event->pos().x() <= key_x) { - QRect mouse_rect(event->pos().x()-BEZIER_LINE_SIZE, event->pos().y()-BEZIER_LINE_SIZE, BEZIER_LINE_SIZE+BEZIER_LINE_SIZE, BEZIER_LINE_SIZE+BEZIER_LINE_SIZE); + QRect mouse_rect(event->pos().x()-kBezierLineSize, event->pos().y()-kBezierLineSize, kBezierLineSize+kBezierLineSize, kBezierLineSize+kBezierLineSize); // NOTE: FILTHY copy/paste from paintEvent if (last_key.type == EFFECT_KEYFRAME_HOLD) { // hold - if (event->pos().y() >= last_key_y-BEZIER_LINE_SIZE - && event->pos().y() <= last_key_y+BEZIER_LINE_SIZE) { + if (event->pos().y() >= last_key_y-kBezierLineSize + && event->pos().y() <= last_key_y+kBezierLineSize) { // dout << "make an HOLD key on field" << i << "after key" << j; click_add = true; } @@ -705,15 +704,15 @@ void GraphView::mouseReleaseEvent(QMouseEvent *) { } else if (moved_keys && selected_keys.size() > 0) { ComboAction* ca = new ComboAction(); switch (current_handle) { - case BEZIER_HANDLE_NONE: + case kBezierHandleNone: for (int i=0;ifield(selected_keys_fields.at(i))->keyframes[selected_keys.at(i)]; ca->append(new SetLong(&key.time, selected_keys_old_vals.at(i), key.time)); ca->append(new SetQVariant(&key.data, selected_keys_old_doubles.at(i), key.data)); } break; - case BEZIER_HANDLE_PRE: - case BEZIER_HANDLE_POST: + case kBezierHandlePre: + case kBezierHandlePost: { EffectKeyframe& key = row->field(handle_field)->keyframes[handle_index]; ca->append(new SetDouble(&key.pre_handle_x, old_pre_handle_x, key.pre_handle_x)); @@ -756,7 +755,7 @@ void GraphView::wheelEvent(QWheelEvent *event) { int x_delta = (event->modifiers() & Qt::ControlModifier) ? event->angleDelta().x() : y_delta; if (y_delta != 0) { - double zoom_diff = (GRAPH_ZOOM_SPEED*y_zoom); + double zoom_diff = (kGraphZoomSpeed*y_zoom); new_y_zoom = (y_delta < 0) ? y_zoom - zoom_diff : y_zoom + zoom_diff; // center zoom on screen @@ -766,7 +765,7 @@ void GraphView::wheelEvent(QWheelEvent *event) { } if (x_delta != 0) { - double zoom_diff = (GRAPH_ZOOM_SPEED*x_zoom); + double zoom_diff = (kGraphZoomSpeed*x_zoom); new_x_zoom = (x_delta < 0) ? x_zoom - zoom_diff : x_zoom + zoom_diff; set_scroll_x(qRound((double(x_scroll)/x_zoom*new_x_zoom) + double(event->pos().x())*new_x_zoom - double(event->pos().x())*x_zoom)); diff --git a/ui/graphview.h b/ui/graphview.h index 19247a2a1..203e80202 100644 --- a/ui/graphview.h +++ b/ui/graphview.h @@ -24,99 +24,99 @@ #include #include -class EffectRow; -class EffectField; +#include "project/effectrow.h" +#include "project/effectfield.h" QColor get_curve_color(int index, int length); class GraphView : public QWidget { - Q_OBJECT + Q_OBJECT public: - GraphView(QWidget* parent = 0); + GraphView(QWidget* parent = nullptr); - void paintEvent(QPaintEvent *event); - void mousePressEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - void wheelEvent(QWheelEvent *event); + void paintEvent(QPaintEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void wheelEvent(QWheelEvent *event); - void set_row(EffectRow* r); + void set_row(EffectRow* r); - void set_selected_keyframe_type(int type); - void set_field_visibility(int field, bool b); + void set_selected_keyframe_type(int type); + void set_field_visibility(int field, bool b); - void delete_selected_keys(); - void select_all(); + void delete_selected_keys(); + void select_all(); signals: - void x_scroll_changed(int); - void y_scroll_changed(int); - void zoom_changed(double, double); - void selection_changed(bool, int); + void x_scroll_changed(int); + void y_scroll_changed(int); + void zoom_changed(double, double); + void selection_changed(bool, int); private: - int x_scroll; - int y_scroll; - bool mousedown; - int start_x; - int start_y; + int x_scroll; + int y_scroll; + bool mousedown; + int start_x; + int start_y; - double x_zoom; - double y_zoom; + double x_zoom; + double y_zoom; - void set_scroll_x(int s); - void set_scroll_y(int s); - void set_zoom(double xz, double yz); + void set_scroll_x(int s); + void set_scroll_y(int s); + void set_zoom(double xz, double yz); - int get_screen_x(double); - int get_screen_y(double); - long get_value_x(int); - double get_value_y(int); + int get_screen_x(double); + int get_screen_y(double); + long get_value_x(int); + double get_value_y(int); - void selection_update(); + void selection_update(); - QVector field_visibility; + QVector field_visibility; - QVector selected_keys; - QVector selected_keys_fields; - QVector selected_keys_old_vals; - QVector selected_keys_old_doubles; + QVector selected_keys; + QVector selected_keys_fields; + QVector selected_keys_old_vals; + QVector selected_keys_old_doubles; - double old_pre_handle_x; - double old_pre_handle_y; - double old_post_handle_x; - double old_post_handle_y; + double old_pre_handle_x; + double old_pre_handle_y; + double old_post_handle_x; + double old_post_handle_y; - int handle_field; - int handle_index; + int handle_field; + int handle_index; - bool moved_keys; + bool moved_keys; - int current_handle; + int current_handle; - void draw_lines(QPainter &p, bool vert); - void draw_line_text(QPainter &p, bool vert, int line_no, int line_pos, int next_line_pos); + void draw_lines(QPainter &p, bool vert); + void draw_line_text(QPainter &p, bool vert, int line_no, int line_pos, int next_line_pos); - EffectRow* row; + EffectRow* row; - bool rect_select; - int rect_select_x; - int rect_select_y; - int rect_select_w; - int rect_select_h; - int rect_select_offset; + bool rect_select; + int rect_select_x; + int rect_select_y; + int rect_select_w; + int rect_select_h; + int rect_select_offset; - long visible_in; + long visible_in; - bool click_add; - bool click_add_proc; - EffectField* click_add_field; - int click_add_key; - int click_add_type; + bool click_add; + bool click_add_proc; + EffectField* click_add_field; + int click_add_key; + int click_add_type; private slots: - void show_context_menu(const QPoint& pos); - void reset_view(); - void set_view_to_selection(); - void set_view_to_all(); - void set_view_to_rect(int x1, double y1, int x2, double y2); + void show_context_menu(const QPoint& pos); + void reset_view(); + void set_view_to_selection(); + void set_view_to_all(); + void set_view_to_rect(int x1, double y1, int x2, double y2); }; #endif // GRAPHVIEW_H diff --git a/ui/timelinetools.h b/ui/timelinetools.h index bcc10bab6..de54fa8a2 100644 --- a/ui/timelinetools.h +++ b/ui/timelinetools.h @@ -21,16 +21,19 @@ #ifndef TIMELINETOOLS_H #define TIMELINETOOLS_H -#define TIMELINE_TOOL_POINTER 0 -#define TIMELINE_TOOL_EDIT 1 -#define TIMELINE_TOOL_RAZOR 2 -#define TIMELINE_TOOL_RIPPLE 3 -#define TIMELINE_TOOL_ROLLING 4 -#define TIMELINE_TOOL_SLIP 5 -#define TIMELINE_TOOL_SLIDE 6 -#define TIMELINE_TOOL_HAND 7 -#define TIMELINE_TOOL_ZOOM 8 -#define TIMELINE_TOOL_MENU 9 -#define TIMELINE_TOOL_TRANSITION 10 +enum TimelineTool { + TIMELINE_TOOL_POINTER, + TIMELINE_TOOL_EDIT, + TIMELINE_TOOL_RAZOR, + TIMELINE_TOOL_RIPPLE, + TIMELINE_TOOL_ROLLING, + TIMELINE_TOOL_SLIP, + TIMELINE_TOOL_SLIDE, + TIMELINE_TOOL_HAND, + TIMELINE_TOOL_ZOOM, + TIMELINE_TOOL_MENU, + TIMELINE_TOOL_TRANSITION, + TIMELINE_TOOL_COUNT +}; #endif // TIMELINETOOLS_H From efbe2d187a1ddfb2e7778e0c38f4f28cff0c6f32 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Tue, 19 Feb 2019 02:38:21 -0800 Subject: [PATCH 23/30] minor clip changes --- panels/timeline.cpp | 64 +++++++++++++++---------------- playback/cacher.cpp | 12 +++--- project/clip.cpp | 22 ++++------- project/clip.h | 4 +- ui/renderfunctions.cpp | 14 +++---- ui/timelinewidget.cpp | 86 +++++++++++++++++++++--------------------- 6 files changed, 96 insertions(+), 106 deletions(-) diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 0b859c642..f61aa966b 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -378,7 +378,7 @@ void Timeline::add_transition() { ClipPtr c = olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { int transition_to_add = (c->track < 0) ? TRANSITION_INTERNAL_CROSSDISSOLVE : TRANSITION_INTERNAL_LINEARFADE; - if (c->get_opening_transition() == nullptr) { + if (c->opening_transition == nullptr) { ca->append(new AddTransitionCommand(c, nullptr, nullptr, @@ -386,7 +386,7 @@ void Timeline::add_transition() { olive::CurrentConfig.default_transition_length)); adding = true; } - if (c->get_closing_transition() == nullptr) { + if (c->closing_transition == nullptr) { ca->append(new AddTransitionCommand(nullptr, c, nullptr, @@ -850,7 +850,7 @@ ClipPtr Timeline::split_clip(ComboAction* ca, bool transitions, int p, long fram if (pre->timeline_in < frame && pre->timeline_out > frame) { // duplicate clip without duplicating its transitions, we'll restore them later - ClipPtr post = ClipPtr(pre->copy(olive::ActiveSequence, false)); + ClipPtr post = ClipPtr(pre->copy(olive::ActiveSequence)); long new_clip_length = frame - pre->timeline_in; @@ -999,15 +999,15 @@ void Timeline::clean_up_selections(QVector& areas) { bool selection_contains_transition(const Selection& s, ClipPtr c, int type) { if (type == kTransitionOpening) { - return c->get_opening_transition() != nullptr - && s.out == c->timeline_in + c->get_opening_transition()->get_true_length() - && ((c->get_opening_transition()->secondary_clip == nullptr && s.in == c->timeline_in) - || (c->get_opening_transition()->secondary_clip != nullptr && s.in == c->timeline_in - c->get_opening_transition()->get_true_length())); + return c->opening_transition != nullptr + && s.out == c->timeline_in + c->opening_transition->get_true_length() + && ((c->opening_transition->secondary_clip == nullptr && s.in == c->timeline_in) + || (c->opening_transition->secondary_clip != nullptr && s.in == c->timeline_in - c->opening_transition->get_true_length())); } else { - return c->get_closing_transition() != nullptr - && s.in == c->timeline_out - c->get_closing_transition()->get_true_length() - && ((c->get_closing_transition()->secondary_clip == nullptr && s.out == c->timeline_out) - || (c->get_closing_transition()->secondary_clip != nullptr && s.out == c->timeline_out + c->get_closing_transition()->get_true_length())); + return c->closing_transition != nullptr + && s.in == c->timeline_out - c->closing_transition->get_true_length() + && ((c->closing_transition->secondary_clip == nullptr && s.out == c->timeline_out) + || (c->closing_transition->secondary_clip != nullptr && s.out == c->timeline_out + c->closing_transition->get_true_length())); } } @@ -1044,22 +1044,22 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& area // only out point is in deletion area move_clip(ca, c, c->timeline_in, s.in, c->clip_in, c->track); - if (c->get_closing_transition() != nullptr) { - if (s.in < c->timeline_out - c->get_closing_transition()->get_true_length()) { + if (c->closing_transition != nullptr) { + if (s.in < c->timeline_out - c->closing_transition->get_true_length()) { ca->append(new DeleteTransitionCommand(c->closing_transition)); } else { - ca->append(new ModifyTransitionCommand(c->closing_transition, c->get_closing_transition()->get_true_length() - (c->timeline_out - s.in))); + ca->append(new ModifyTransitionCommand(c->closing_transition, c->closing_transition->get_true_length() - (c->timeline_out - s.in))); } } } else if (c->timeline_in < s.out && c->timeline_out > s.out) { // only in point is in deletion area move_clip(ca, c, s.out, c->timeline_out, c->clip_in + (s.out - c->timeline_in), c->track); - if (c->get_opening_transition() != nullptr) { - if (s.out > c->timeline_in + c->get_opening_transition()->get_true_length()) { + if (c->opening_transition != nullptr) { + if (s.out > c->timeline_in + c->opening_transition->get_true_length()) { ca->append(new DeleteTransitionCommand(c->opening_transition)); } else { - ca->append(new ModifyTransitionCommand(c->opening_transition, c->get_opening_transition()->get_true_length() - (s.out - c->timeline_in))); + ca->append(new ModifyTransitionCommand(c->opening_transition, c->opening_transition->get_true_length() - (s.out - c->timeline_in))); } } } @@ -1596,11 +1596,11 @@ bool Timeline::snap_to_timeline(long* l, bool use_playhead, bool use_markers, bo return true; } else if (snap_to_point(c->timeline_out, l)) { return true; - } else if (c->get_opening_transition() != nullptr - && snap_to_point(c->timeline_in + c->get_opening_transition()->get_true_length(), l)) { + } else if (c->opening_transition != nullptr + && snap_to_point(c->timeline_in + c->opening_transition->get_true_length(), l)) { return true; - } else if (c->get_closing_transition() != nullptr - && snap_to_point(c->timeline_out - c->get_closing_transition()->get_true_length(), l)) { + } else if (c->closing_transition != nullptr + && snap_to_point(c->timeline_out - c->closing_transition->get_true_length(), l)) { return true; } else { // try to snap to clip markers @@ -2075,26 +2075,26 @@ void move_clip(ComboAction* ca, ClipPtr c, long iin, long iout, long iclip_in, i if (verify_transitions) { // if this is a shared transition, and the corresponding clip will be moved away somehow - if (c->get_opening_transition() != nullptr - && c->get_opening_transition()->secondary_clip != nullptr - && c->get_opening_transition()->secondary_clip->timeline_out != iin) { + if (c->opening_transition != nullptr + && c->opening_transition->secondary_clip != nullptr + && c->opening_transition->secondary_clip->timeline_out != iin) { // separate transition - ca->append(new SetPointer(reinterpret_cast(&c->get_opening_transition()->secondary_clip), nullptr)); + ca->append(new SetPointer(reinterpret_cast(&c->opening_transition->secondary_clip), nullptr)); ca->append(new AddTransitionCommand(nullptr, - c->get_opening_transition()->secondary_clip, - c->get_opening_transition(), + c->opening_transition->secondary_clip, + c->opening_transition, nullptr, 0)); } - if (c->get_closing_transition() != nullptr - && c->get_closing_transition()->secondary_clip != nullptr - && c->get_closing_transition()->parent_clip->timeline_in != iout) { + if (c->closing_transition != nullptr + && c->closing_transition->secondary_clip != nullptr + && c->closing_transition->parent_clip->timeline_in != iout) { // separate transition - ca->append(new SetPointer(reinterpret_cast(&c->get_closing_transition()->secondary_clip), nullptr)); + ca->append(new SetPointer(reinterpret_cast(&c->closing_transition->secondary_clip), nullptr)); ca->append(new AddTransitionCommand(nullptr, c, - c->get_closing_transition(), + c->closing_transition, nullptr, 0)); } diff --git a/playback/cacher.cpp b/playback/cacher.cpp index 744080115..029d0d1a2 100644 --- a/playback/cacher.cpp +++ b/playback/cacher.cpp @@ -71,28 +71,28 @@ void apply_audio_effects(ClipPtr c, double timecode_start, AVFrame* frame, int n EffectPtr e = c->effects.at(j); if (e->is_enabled()) e->process_audio(timecode_start, timecode_end, frame->data[0], nb_bytes, 2); } - if (c->get_opening_transition() != nullptr) { + if (c->opening_transition != nullptr) { if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { double transition_start = (c->get_clip_in_with_transition() / c->sequence->frame_rate); - double transition_end = (c->get_clip_in_with_transition() + c->get_opening_transition()->get_length()) / c->sequence->frame_rate; + double transition_end = (c->get_clip_in_with_transition() + c->opening_transition->get_length()) / c->sequence->frame_rate; if (timecode_end < transition_end) { double adjustment = transition_end - transition_start; double adjusted_range_start = (timecode_start - transition_start) / adjustment; double adjusted_range_end = (timecode_end - transition_start) / adjustment; - c->get_opening_transition()->process_audio(adjusted_range_start, adjusted_range_end, frame->data[0], nb_bytes, kTransitionOpening); + c->opening_transition->process_audio(adjusted_range_start, adjusted_range_end, frame->data[0], nb_bytes, kTransitionOpening); } } } - if (c->get_closing_transition() != nullptr) { + if (c->closing_transition != nullptr) { if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { long length_with_transitions = c->get_timeline_out_with_transition() - c->get_timeline_in_with_transition(); - double transition_start = (c->get_clip_in_with_transition() + length_with_transitions - c->get_closing_transition()->get_length()) / c->sequence->frame_rate; + double transition_start = (c->get_clip_in_with_transition() + length_with_transitions - c->closing_transition->get_length()) / c->sequence->frame_rate; double transition_end = (c->get_clip_in_with_transition() + length_with_transitions) / c->sequence->frame_rate; if (timecode_start > transition_start) { double adjustment = transition_end - transition_start; double adjusted_range_start = (timecode_start - transition_start) / adjustment; double adjusted_range_end = (timecode_end - transition_start) / adjustment; - c->get_closing_transition()->process_audio(adjusted_range_start, adjusted_range_end, frame->data[0], nb_bytes, kTransitionClosing); + c->closing_transition->process_audio(adjusted_range_start, adjusted_range_end, frame->data[0], nb_bytes, kTransitionClosing); } } } diff --git a/project/clip.cpp b/project/clip.cpp index ca333f977..b51ccefcd 100644 --- a/project/clip.cpp +++ b/project/clip.cpp @@ -60,7 +60,7 @@ Clip::Clip(SequencePtr s) : reset(); } -ClipPtr Clip::copy(SequencePtr s, bool duplicate_transitions) { +ClipPtr Clip::copy(SequencePtr s) { ClipPtr copy(new Clip(s)); copy->enabled = enabled; @@ -168,14 +168,6 @@ QVector &Clip::get_markers() { return markers; } -TransitionPtr Clip::get_opening_transition() { - return opening_transition; -} - -TransitionPtr Clip::get_closing_transition() { - return closing_transition; -} - Clip::~Clip() { if (open) { close_clip(ClipPtr(this), true); @@ -186,25 +178,25 @@ Clip::~Clip() { } long Clip::get_clip_in_with_transition() { - if (get_opening_transition() != nullptr && get_opening_transition()->secondary_clip != nullptr) { + if (opening_transition != nullptr && opening_transition->secondary_clip != nullptr) { // we must be the secondary clip, so return (timeline in - length) - return clip_in - get_opening_transition()->get_true_length(); + return clip_in - opening_transition->get_true_length(); } return clip_in; } long Clip::get_timeline_in_with_transition() { - if (get_opening_transition() != nullptr && get_opening_transition()->secondary_clip != nullptr) { + if (opening_transition != nullptr && opening_transition->secondary_clip != nullptr) { // we must be the secondary clip, so return (timeline in - length) - return timeline_in - get_opening_transition()->get_true_length(); + return timeline_in - opening_transition->get_true_length(); } return timeline_in; } long Clip::get_timeline_out_with_transition() { - if (get_closing_transition() != nullptr && get_closing_transition()->secondary_clip != nullptr) { + if (closing_transition != nullptr && closing_transition->secondary_clip != nullptr) { // we must be the primary clip, so return (timeline out + length2) - return timeline_out + get_closing_transition()->get_true_length(); + return timeline_out + closing_transition->get_true_length(); } else { return timeline_out; } diff --git a/project/clip.h b/project/clip.h index 873caad46..d9c0b9458 100644 --- a/project/clip.h +++ b/project/clip.h @@ -51,7 +51,7 @@ class Clip { public: Clip(SequencePtr s); ~Clip(); - ClipPtr copy(SequencePtr s, bool duplicate_transitions = true); + ClipPtr copy(SequencePtr s); void reset_audio(); void reset(); void refresh(); @@ -96,9 +96,7 @@ public: QList effects; QVector linked; TransitionPtr opening_transition; - TransitionPtr get_opening_transition(); TransitionPtr closing_transition; - TransitionPtr get_closing_transition(); // media handling AVFormatContext* formatCtx; diff --git a/ui/renderfunctions.cpp b/ui/renderfunctions.cpp index d6bb29abb..47f0bdbe4 100644 --- a/ui/renderfunctions.cpp +++ b/ui/renderfunctions.cpp @@ -421,18 +421,18 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { } // if the clip has an opening transition, process that now - if (c->get_opening_transition() != nullptr) { + if (c->opening_transition != nullptr) { int transition_progress = playhead - c->get_timeline_in_with_transition(); - if (transition_progress < c->get_opening_transition()->get_length()) { - process_effect(c, c->get_opening_transition(), double(transition_progress)/double(c->get_opening_transition()->get_length()), coords, textureID, fbo_switcher, params.texture_failed, kTransitionOpening); + if (transition_progress < c->opening_transition->get_length()) { + process_effect(c, c->opening_transition, double(transition_progress)/double(c->opening_transition->get_length()), coords, textureID, fbo_switcher, params.texture_failed, kTransitionOpening); } } // if the clip has a closing transition, process that now - if (c->get_closing_transition() != nullptr) { - int transition_progress = playhead - (c->get_timeline_out_with_transition() - c->get_closing_transition()->get_length()); - if (transition_progress >= 0 && transition_progress < c->get_closing_transition()->get_length()) { - process_effect(c, c->get_closing_transition(), double(transition_progress)/double(c->get_closing_transition()->get_length()), coords, textureID, fbo_switcher, params.texture_failed, kTransitionClosing); + if (c->closing_transition != nullptr) { + int transition_progress = playhead - (c->get_timeline_out_with_transition() - c->closing_transition->get_length()); + if (transition_progress >= 0 && transition_progress < c->closing_transition->get_length()) { + process_effect(c, c->closing_transition, double(transition_progress)/double(c->closing_transition->get_length()), coords, textureID, fbo_switcher, params.texture_failed, kTransitionClosing); } } diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index 1f7901964..671626ad0 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -698,20 +698,20 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { s.track = clip->track; // select the transition only - if (panel_timeline->transition_select == kTransitionOpening && clip->get_opening_transition() != nullptr) { + if (panel_timeline->transition_select == kTransitionOpening && clip->opening_transition != nullptr) { s.in = clip->timeline_in; - if (clip->get_opening_transition()->secondary_clip != nullptr) { - s.in -= clip->get_opening_transition()->get_true_length(); + if (clip->opening_transition->secondary_clip != nullptr) { + s.in -= clip->opening_transition->get_true_length(); } - s.out = clip->timeline_in + clip->get_opening_transition()->get_true_length(); - } else if (panel_timeline->transition_select == kTransitionClosing && clip->get_closing_transition() != nullptr) { - s.in = clip->timeline_out - clip->get_closing_transition()->get_true_length(); + s.out = clip->timeline_in + clip->opening_transition->get_true_length(); + } else if (panel_timeline->transition_select == kTransitionClosing && clip->closing_transition != nullptr) { + s.in = clip->timeline_out - clip->closing_transition->get_true_length(); s.out = clip->timeline_out; - if (clip->get_closing_transition()->secondary_clip != nullptr) { - s.out += clip->get_closing_transition()->get_true_length(); + if (clip->closing_transition->secondary_clip != nullptr) { + s.out += clip->closing_transition->get_true_length(); } } olive::ActiveSequence->selections.append(s); @@ -736,19 +736,19 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { if (panel_timeline->transition_select == kTransitionOpening) { // move the selection to only select the transitoin - s.out = clip->timeline_in + clip->get_opening_transition()->get_true_length(); + s.out = clip->timeline_in + clip->opening_transition->get_true_length(); // if the transition is a "shared" transition, adjust the selection to select both sides - if (clip->get_opening_transition()->secondary_clip != nullptr) { - s.in -= clip->get_opening_transition()->get_true_length(); + if (clip->opening_transition->secondary_clip != nullptr) { + s.in -= clip->opening_transition->get_true_length(); } } else if (panel_timeline->transition_select == kTransitionClosing) { // move the selection to only select the transitoin - s.in = clip->timeline_out - clip->get_closing_transition()->get_true_length(); + s.in = clip->timeline_out - clip->closing_transition->get_true_length(); // if the transition is a "shared" transition, adjust the selection to select both sides - if (clip->get_closing_transition()->secondary_clip != nullptr) { - s.out += clip->get_closing_transition()->get_true_length(); + if (clip->closing_transition->secondary_clip != nullptr) { + s.out += clip->closing_transition->get_true_length(); } } } @@ -866,24 +866,24 @@ void make_room_for_transition(ComboAction* ca, // make room for transition if (type == kTransitionOpening) { - if (delete_old_transitions && c->get_opening_transition() != nullptr) { + if (delete_old_transitions && c->opening_transition != nullptr) { ca->append(new DeleteTransitionCommand(c->opening_transition)); } - if (c->get_closing_transition() != nullptr) { + if (c->closing_transition != nullptr) { if (transition_end >= c->timeline_out) { ca->append(new DeleteTransitionCommand(c->closing_transition)); - } else if (transition_end > c->timeline_out - c->get_closing_transition()->get_true_length()) { + } else if (transition_end > c->timeline_out - c->closing_transition->get_true_length()) { ca->append(new ModifyTransitionCommand(c->closing_transition, c->timeline_out - transition_end)); } } } else { - if (delete_old_transitions && c->get_closing_transition() != nullptr) { + if (delete_old_transitions && c->closing_transition != nullptr) { ca->append(new DeleteTransitionCommand(c->closing_transition)); } - if (c->get_opening_transition() != nullptr) { + if (c->opening_transition != nullptr) { if (transition_start <= c->timeline_in) { ca->append(new DeleteTransitionCommand(c->opening_transition)); - } else if (transition_start < c->timeline_in + c->get_opening_transition()->get_true_length()) { + } else if (transition_start < c->timeline_in + c->opening_transition->get_true_length()) { ca->append(new ModifyTransitionCommand(c->opening_transition, transition_start - c->timeline_in)); } } @@ -1259,7 +1259,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { // if the user was moving a transition - bool is_opening_transition = (g.transition == c->get_opening_transition()); + bool is_opening_transition = (g.transition == c->opening_transition); long new_transition_length = g.out - g.in; if (g.transition->secondary_clip != nullptr) new_transition_length >>= 1; ca->append( @@ -1560,15 +1560,15 @@ void TimelineWidget::init_ghosts() { g.in = g.old_in = c->timeline_in; g.out = g.old_out = c->timeline_out; g.ghost_length = g.old_out - g.old_in; - } else if (g.transition == c->get_opening_transition()) { + } else if (g.transition == c->opening_transition) { g.in = g.old_in = c->get_timeline_in_with_transition(); - g.ghost_length = c->get_opening_transition()->get_length(); + g.ghost_length = c->opening_transition->get_length(); g.out = g.old_out = g.in + g.ghost_length; - } else if (g.transition == c->get_closing_transition()) { + } else if (g.transition == c->closing_transition) { g.out = g.old_out = c->get_timeline_out_with_transition(); - g.ghost_length = c->get_closing_transition()->get_length(); + g.ghost_length = c->closing_transition->get_length(); g.in = g.old_in = g.out - g.ghost_length; - g.clip_in = g.old_clip_in = c->clip_in + c->getLength() - c->get_closing_transition()->get_true_length(); + g.clip_in = g.old_clip_in = c->clip_in + c->getLength() - c->closing_transition->get_true_length(); } // used for trim ops @@ -1896,7 +1896,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { g.out = g.old_out + frame_diff; if (g.transition != nullptr - && g.transition == olive::ActiveSequence->clips.at(g.clip)->get_opening_transition()) { + && g.transition == olive::ActiveSequence->clips.at(g.clip)->opening_transition) { g.clip_in = g.old_clip_in + frame_diff; } @@ -2162,7 +2162,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // check if a transition is selected (prioritize transition selection) // (only the pointer tool supports moving transitions) if (panel_timeline->tool == TIMELINE_TOOL_POINTER - && (c->get_opening_transition() != nullptr || c->get_closing_transition() != nullptr)) { + && (c->opening_transition != nullptr || c->closing_transition != nullptr)) { // check if any selections contain a whole transition for (int j=0;jselections.size();j++) { @@ -2172,13 +2172,13 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { if (s.track == c->track) { if (selection_contains_transition(s, c, kTransitionOpening)) { - g.transition = c->get_opening_transition(); + g.transition = c->opening_transition; add = true; break; } else if (selection_contains_transition(s, c, kTransitionClosing)) { - g.transition = c->get_closing_transition(); + g.transition = c->closing_transition; add = true; break; @@ -2542,13 +2542,13 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { tooltip_clip = i; // check if the cursor is specifically hovering over one of the clip's transitions - if (c->get_opening_transition() != nullptr - && panel_timeline->cursor_frame <= c->timeline_in + c->get_opening_transition()->get_true_length()) { + if (c->opening_transition != nullptr + && panel_timeline->cursor_frame <= c->timeline_in + c->opening_transition->get_true_length()) { panel_timeline->transition_select = kTransitionOpening; - } else if (c->get_closing_transition() != nullptr - && panel_timeline->cursor_frame >= c->timeline_out - c->get_closing_transition()->get_true_length()) { + } else if (c->closing_transition != nullptr + && panel_timeline->cursor_frame >= c->timeline_out - c->closing_transition->get_true_length()) { panel_timeline->transition_select = kTransitionClosing; @@ -2596,10 +2596,10 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { // if the clip has an opening transition - if (c->get_opening_transition() != nullptr) { + if (c->opening_transition != nullptr) { // cache the timeline frame where the transition ends - long transition_point = c->timeline_in + c->get_opening_transition()->get_true_length(); + long transition_point = c->timeline_in + c->opening_transition->get_true_length(); // check if the cursor is hovering around it (within the threshold) if (transition_point > mouse_frame_lower && transition_point < mouse_frame_upper) { @@ -2617,10 +2617,10 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } // if the clip has a closing transition - if (c->get_closing_transition() != nullptr) { + if (c->closing_transition != nullptr) { // cache the timeline frame where the transition starts - long transition_point = c->timeline_out - c->get_closing_transition()->get_true_length(); + long transition_point = c->timeline_out - c->closing_transition->get_true_length(); // check if the cursor is hovering around it (within the threshold) if (transition_point > mouse_frame_lower && transition_point < mouse_frame_upper) { @@ -2838,7 +2838,7 @@ void draw_waveform(ClipPtr clip, const FootageStream* ms, long media_length, QPa } void draw_transition(QPainter& p, ClipPtr c, const QRect& clip_rect, QRect& text_rect, int transition_type) { - TransitionPtr t = (transition_type == kTransitionOpening) ? c->get_opening_transition() : c->get_closing_transition(); + TransitionPtr t = (transition_type == kTransitionOpening) ? c->opening_transition : c->closing_transition; if (t != nullptr) { QColor transition_color(255, 0, 0, 16); int transition_width = getScreenPointFromFrame(panel_timeline->zoom, t->get_true_length()); @@ -2988,13 +2988,13 @@ void TimelineWidget::paintEvent(QPaintEvent*) { int thumb_y = p.fontMetrics().height()+olive::timeline::kClipTextPadding+olive::timeline::kClipTextPadding; if (thumb_x < width() && thumb_y < height()) { int space_for_thumb = clip_rect.width()-1; - if (clip->get_opening_transition() != nullptr) { - int ot_width = getScreenPointFromFrame(panel_timeline->zoom, clip->get_opening_transition()->get_true_length()); + if (clip->opening_transition != nullptr) { + int ot_width = getScreenPointFromFrame(panel_timeline->zoom, clip->opening_transition->get_true_length()); thumb_x += ot_width; space_for_thumb -= ot_width; } - if (clip->get_closing_transition() != nullptr) { - space_for_thumb -= getScreenPointFromFrame(panel_timeline->zoom, clip->get_closing_transition()->get_true_length()); + if (clip->closing_transition != nullptr) { + space_for_thumb -= getScreenPointFromFrame(panel_timeline->zoom, clip->closing_transition->get_true_length()); } int thumb_height = clip_rect.height()-thumb_y; int thumb_width = qRound(thumb_height*(double(ms->video_preview.width())/double(ms->video_preview.height()))); From ecf2d9cba3f660818c5f8d22e104f75333eb2d0b Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Tue, 19 Feb 2019 03:57:47 -0800 Subject: [PATCH 24/30] documented config --- Doxyfile | 6 +- docs/doxygen_objdb_3636.tmp | 0 .../_i_s_s_u_e___t_e_m_p_l_a_t_e_8md.html | 76 + docs/html/_r_e_a_d_m_e_8md.html | 76 + docs/html/aboutdialog_8cpp.html | 84 + docs/html/aboutdialog_8h.html | 91 + docs/html/aboutdialog_8h_source.html | 3 +- docs/html/actionsearch_8cpp.html | 86 + docs/html/actionsearch_8h.html | 98 + docs/html/actionsearch_8h_source.html | 19 +- docs/html/advancedvideodialog_8cpp.html | 88 + docs/html/advancedvideodialog_8h.html | 93 + docs/html/advancedvideodialog_8h_source.html | 9 +- docs/html/annotated.html | 335 +- docs/html/audio_8cpp.html | 654 +++ docs/html/audio_8h.html | 527 +++ docs/html/audio_8h_source.html | 36 +- docs/html/audiomonitor_8cpp.html | 129 + docs/html/audiomonitor_8h.html | 92 + docs/html/audiomonitor_8h_source.html | 10 +- docs/html/audionoiseeffect_8cpp.html | 83 + docs/html/audionoiseeffect_8h.html | 91 + docs/html/audionoiseeffect_8h_source.html | 11 +- docs/html/cacher_8cpp.html | 443 +++ docs/html/cacher_8h.html | 212 + docs/html/cacher_8h_source.html | 19 +- docs/html/checkboxex_8cpp.html | 82 + docs/html/checkboxex_8h.html | 91 + docs/html/checkboxex_8h_source.html | 4 +- docs/html/class_about_dialog-members.html | 2 +- docs/html/class_about_dialog.html | 34 +- docs/html/class_action_search-members.html | 12 +- docs/html/class_action_search.html | 182 +- .../class_action_search_entry-members.html | 8 +- docs/html/class_action_search_entry.html | 112 +- .../class_action_search_list-members.html | 6 +- docs/html/class_action_search_list.html | 84 +- docs/html/class_add_clip_command-members.html | 22 +- docs/html/class_add_clip_command.html | 219 +- .../class_add_effect_command-members.html | 25 +- docs/html/class_add_effect_command.html | 252 +- .../html/class_add_marker_action-members.html | 24 +- docs/html/class_add_marker_action.html | 240 +- .../html/class_add_media_command-members.html | 22 +- docs/html/class_add_media_command.html | 211 +- .../class_add_transition_command-members.html | 30 +- docs/html/class_add_transition_command.html | 345 +- .../class_advanced_video_dialog-members.html | 8 +- docs/html/class_advanced_video_dialog.html | 122 +- docs/html/class_audio_monitor-members.html | 16 +- docs/html/class_audio_monitor.html | 218 +- .../class_audio_noise_effect-members.html | 110 +- docs/html/class_audio_noise_effect.html | 293 +- .../class_audio_sender_thread-members.html | 18 +- docs/html/class_audio_sender_thread.html | 209 +- docs/html/class_cacher-members.html | 22 +- docs/html/class_cacher.html | 215 +- .../class_change_sequence_action-members.html | 18 +- docs/html/class_change_sequence_action.html | 155 +- docs/html/class_checkbox_command-members.html | 22 +- docs/html/class_checkbox_command.html | 201 +- docs/html/class_checkbox_ex-members.html | 4 +- docs/html/class_checkbox_ex.html | 55 +- docs/html/class_clickable_label-members.html | 8 +- docs/html/class_clickable_label.html | 125 +- docs/html/class_clip-members.html | 163 +- docs/html/class_clip.html | 1484 ++++++- ...class_close_all_clips_command-members.html | 12 +- docs/html/class_close_all_clips_command.html | 76 +- .../class_collapsible_widget-members.html | 40 +- docs/html/class_collapsible_widget.html | 485 ++- ...ass_collapsible_widget_header-members.html | 10 +- .../html/class_collapsible_widget_header.html | 142 +- docs/html/class_color_button-members.html | 18 +- docs/html/class_color_button.html | 223 +- docs/html/class_color_command-members.html | 12 +- docs/html/class_color_command.html | 159 +- docs/html/class_combo_action-members.html | 16 +- docs/html/class_combo_action.html | 252 +- docs/html/class_combo_box_ex-members.html | 16 +- docs/html/class_combo_box_ex.html | 198 +- .../class_combo_box_ex_command-members.html | 16 +- docs/html/class_combo_box_ex_command.html | 231 +- .../html/class_corner_pin_effect-members.html | 132 +- docs/html/class_corner_pin_effect.html | 654 ++- ...ass_cross_dissolve_transition-members.html | 120 +- .../html/class_cross_dissolve_transition.html | 282 +- docs/html/class_cube_transition-members.html | 120 +- docs/html/class_cube_transition.html | 282 +- docs/html/class_debug_dialog-members.html | 8 +- docs/html/class_debug_dialog.html | 110 +- .../class_delete_clip_action-members.html | 30 +- docs/html/class_delete_clip_action.html | 317 +- .../class_delete_marker_action-members.html | 22 +- docs/html/class_delete_marker_action.html | 191 +- .../class_delete_media_command-members.html | 22 +- docs/html/class_delete_media_command.html | 201 +- ...ass_delete_transition_command-members.html | 23 +- .../html/class_delete_transition_command.html | 188 +- docs/html/class_demo_notice-members.html | 2 +- docs/html/class_demo_notice.html | 34 +- .../class_edit_sequence_command-members.html | 44 +- docs/html/class_edit_sequence_command.html | 435 +- docs/html/class_effect-members.html | 144 +- docs/html/class_effect.html | 1890 ++++++++- docs/html/class_effect_controls-members.html | 110 +- docs/html/class_effect_controls.html | 1469 ++++++- docs/html/class_effect_controls.png | Bin 482 -> 628 bytes .../class_effect_delete_command-members.html | 24 +- docs/html/class_effect_delete_command.html | 212 +- docs/html/class_effect_field-members.html | 90 +- docs/html/class_effect_field.html | 1100 +++++- .../html/class_effect_field_undo-members.html | 22 +- docs/html/class_effect_field_undo.html | 199 +- docs/html/class_effect_gizmo-members.html | 38 +- docs/html/class_effect_gizmo.html | 366 +- docs/html/class_effect_init-members.html | 4 +- docs/html/class_effect_init.html | 57 +- docs/html/class_effect_keyframe-members.html | 16 +- docs/html/class_effect_keyframe.html | 148 +- docs/html/class_effect_row-members.html | 62 +- docs/html/class_effect_row.html | 785 +++- docs/html/class_effects_area-members.html | 10 +- docs/html/class_effects_area.html | 108 +- .../class_embedded_file_chooser-members.html | 20 +- docs/html/class_embedded_file_chooser.html | 248 +- ...s_exponential_fade_transition-members.html | 120 +- .../class_exponential_fade_transition.html | 294 +- docs/html/class_export_dialog-members.html | 72 +- docs/html/class_export_dialog.html | 956 ++++- docs/html/class_export_thread-members.html | 71 +- docs/html/class_export_thread.html | 958 ++++- .../class_fill_left_right_effect-members.html | 108 +- docs/html/class_fill_left_right_effect.html | 284 +- docs/html/class_flow_layout-members.html | 40 +- docs/html/class_flow_layout.html | 590 ++- docs/html/class_focus_filter.html | 42 +- docs/html/class_font_combobox-members.html | 18 +- docs/html/class_font_combobox.html | 138 +- docs/html/class_frei0r_effect-members.html | 122 +- docs/html/class_frei0r_effect.html | 480 ++- docs/html/class_graph_editor-members.html | 49 +- docs/html/class_graph_editor.html | 620 ++- docs/html/class_graph_editor.png | Bin 469 -> 606 bytes docs/html/class_graph_view-members.html | 126 +- docs/html/class_graph_view.html | 1710 +++++++- .../class_key_sequence_editor-members.html | 12 +- docs/html/class_key_sequence_editor.html | 143 +- docs/html/class_keyframe_delete-members.html | 22 +- docs/html/class_keyframe_delete.html | 209 +- .../class_keyframe_field_set-members.html | 22 +- docs/html/class_keyframe_field_set.html | 209 +- .../class_keyframe_navigator-members.html | 30 +- docs/html/class_keyframe_navigator.html | 394 +- docs/html/class_keyframe_view-members.html | 74 +- docs/html/class_keyframe_view.html | 960 ++++- docs/html/class_label_slider-members.html | 38 +- docs/html/class_label_slider.html | 552 ++- .../class_linear_fade_transition-members.html | 120 +- docs/html/class_linear_fade_transition.html | 294 +- docs/html/class_link_command-members.html | 22 +- docs/html/class_link_command.html | 175 +- docs/html/class_load_dialog-members.html | 16 +- docs/html/class_load_dialog.html | 222 +- docs/html/class_load_thread-members.html | 77 +- docs/html/class_load_thread.html | 1137 +++++- ...s_logarithmic_fade_transition-members.html | 120 +- .../class_logarithmic_fade_transition.html | 294 +- docs/html/class_main_window-members.html | 96 +- docs/html/class_main_window.html | 1216 +++++- docs/html/class_media-members.html | 73 +- docs/html/class_media.html | 801 +++- .../class_media_icon_service-members.html | 88 + docs/html/class_media_icon_service.html | 345 ++ docs/html/class_media_icon_service.png | Bin 0 -> 503 bytes docs/html/class_media_move-members.html | 20 +- docs/html/class_media_move.html | 156 +- ...class_media_properties_dialog-members.html | 16 +- docs/html/class_media_properties_dialog.html | 216 +- docs/html/class_media_rename-members.html | 20 +- docs/html/class_media_rename.html | 184 +- docs/html/class_menu_helper.html | 6 +- ...ass_modify_transition_command-members.html | 21 +- .../html/class_modify_transition_command.html | 195 +- docs/html/class_move_clip_action-members.html | 34 +- docs/html/class_move_clip_action.html | 387 +- .../class_move_effect_command-members.html | 20 +- docs/html/class_move_effect_command.html | 150 +- .../class_move_marker_action-members.html | 20 +- docs/html/class_move_marker_action.html | 190 +- .../class_new_sequence_command-members.html | 22 +- docs/html/class_new_sequence_command.html | 211 +- .../class_new_sequence_dialog-members.html | 32 +- docs/html/class_new_sequence_dialog.html | 425 +- docs/html/class_o_tree_view-members.html | 2 +- docs/html/class_o_tree_view.html | 26 +- docs/html/class_olive_action-members.html | 12 +- docs/html/class_olive_action.html | 229 +- docs/html/class_olive_global-members.html | 40 +- docs/html/class_olive_global.html | 397 +- docs/html/class_pan_effect-members.html | 108 +- docs/html/class_pan_effect.html | 276 +- docs/html/class_panel-members.html | 82 + docs/html/class_panel.html | 185 + docs/html/class_panel.png | Bin 0 -> 1534 bytes docs/html/class_play_button-members.html | 6 +- docs/html/class_play_button.html | 77 +- .../class_preferences_dialog-members.html | 72 +- docs/html/class_preferences_dialog.html | 957 ++++- .../html/class_preview_generator-members.html | 35 +- docs/html/class_preview_generator.html | 488 ++- docs/html/class_project-members.html | 110 +- docs/html/class_project.html | 1460 ++++++- docs/html/class_project.png | Bin 427 -> 562 bytes docs/html/class_project_filter-members.html | 14 +- docs/html/class_project_filter.html | 195 +- docs/html/class_project_model-members.html | 46 +- docs/html/class_project_model.html | 686 +++- docs/html/class_proxy_dialog-members.html | 18 +- docs/html/class_proxy_dialog.html | 249 +- docs/html/class_proxy_generator-members.html | 24 +- docs/html/class_proxy_generator.html | 289 +- .../html/class_q_painter_wrapper-members.html | 16 +- docs/html/class_q_painter_wrapper.html | 259 +- docs/html/class_refresh_clips-members.html | 16 +- docs/html/class_refresh_clips.html | 124 +- .../class_reload_effects_command-members.html | 12 +- docs/html/class_reload_effects_command.html | 76 +- ...s_remove_clips_from_clipboard-members.html | 22 +- .../class_remove_clips_from_clipboard.html | 203 +- .../class_rename_clip_command-members.html | 20 +- docs/html/class_rename_clip_command.html | 158 +- docs/html/class_render_thread-members.html | 73 +- docs/html/class_render_thread.html | 918 ++++- ...ss_replace_clip_media_command-members.html | 26 +- .../class_replace_clip_media_command.html | 263 +- ...ass_replace_clip_media_dialog-members.html | 10 +- .../html/class_replace_clip_media_dialog.html | 141 +- .../class_replace_media_command-members.html | 22 +- docs/html/class_replace_media_command.html | 213 +- .../class_resizable_scroll_bar-members.html | 26 +- docs/html/class_resizable_scroll_bar.html | 343 +- docs/html/class_ripple_action-members.html | 24 +- docs/html/class_ripple_action.html | 250 +- docs/html/class_scroll_area-members.html | 4 +- docs/html/class_scroll_area.html | 48 +- docs/html/class_sequence-members.html | 100 + docs/html/class_sequence.html | 462 +++ .../class_set_autoscale_action-members.html | 16 +- docs/html/class_set_autoscale_action.html | 116 +- docs/html/class_set_bool-members.html | 20 +- docs/html/class_set_bool.html | 184 +- docs/html/class_set_double-members.html | 20 +- docs/html/class_set_double.html | 190 +- docs/html/class_set_effect_data-members.html | 20 +- docs/html/class_set_effect_data.html | 188 +- docs/html/class_set_int-members.html | 20 +- docs/html/class_set_int.html | 184 +- docs/html/class_set_keyframing-members.html | 18 +- docs/html/class_set_keyframing.html | 159 +- docs/html/class_set_long-members.html | 20 +- docs/html/class_set_long.html | 190 +- docs/html/class_set_pointer-members.html | 22 +- docs/html/class_set_pointer.html | 209 +- docs/html/class_set_q_variant-members.html | 20 +- docs/html/class_set_q_variant.html | 190 +- .../class_set_selections_command-members.html | 22 +- docs/html/class_set_selections_command.html | 187 +- docs/html/class_set_speed_action-members.html | 20 +- docs/html/class_set_speed_action.html | 188 +- docs/html/class_set_string-members.html | 20 +- docs/html/class_set_string.html | 184 +- ...s_set_timeline_in_out_command-members.html | 28 +- .../class_set_timeline_in_out_command.html | 300 +- docs/html/class_shake_effect-members.html | 114 +- docs/html/class_shake_effect.html | 323 +- docs/html/class_solid_effect-members.html | 118 +- docs/html/class_solid_effect.html | 363 +- docs/html/class_source_icon_view-members.html | 20 +- docs/html/class_source_icon_view.html | 235 +- docs/html/class_source_table-members.html | 18 +- docs/html/class_source_table.html | 247 +- docs/html/class_sources_common-members.html | 40 +- docs/html/class_sources_common.html | 551 ++- docs/html/class_speed_dialog-members.html | 36 +- docs/html/class_speed_dialog.html | 454 ++- docs/html/class_text_edit_dialog-members.html | 12 +- docs/html/class_text_edit_dialog.html | 166 +- docs/html/class_text_edit_ex-members.html | 18 +- docs/html/class_text_edit_ex.html | 223 +- docs/html/class_text_effect-members.html | 148 +- docs/html/class_text_effect.html | 628 ++- docs/html/class_timecode_effect-members.html | 128 +- docs/html/class_timecode_effect.html | 420 +- docs/html/class_timeline-members.html | 300 +- docs/html/class_timeline.html | 3506 +++++++++++++++-- docs/html/class_timeline.png | Bin 426 -> 561 bytes docs/html/class_timeline_header-members.html | 80 +- docs/html/class_timeline_header.html | 1043 ++++- docs/html/class_timeline_widget-members.html | 80 +- docs/html/class_timeline_widget.html | 1101 +++++- docs/html/class_tone_effect-members.html | 116 +- docs/html/class_tone_effect.html | 352 +- docs/html/class_transform_effect-members.html | 152 +- docs/html/class_transform_effect.html | 891 ++++- docs/html/class_transition-members.html | 124 +- docs/html/class_transition.html | 476 ++- .../class_update_footage_tooltip-members.html | 16 +- docs/html/class_update_footage_tooltip.html | 124 +- docs/html/class_update_viewer-members.html | 12 +- docs/html/class_update_viewer.html | 76 +- docs/html/class_v_s_t_host-members.html | 150 +- docs/html/class_v_s_t_host.html | 898 ++++- docs/html/class_viewer-members.html | 179 +- docs/html/class_viewer.html | 2130 +++++++++- docs/html/class_viewer.png | Bin 432 -> 564 bytes docs/html/class_viewer_container-members.html | 38 +- docs/html/class_viewer_container.html | 433 +- docs/html/class_viewer_widget-members.html | 96 +- docs/html/class_viewer_widget.html | 1215 +++++- docs/html/class_viewer_window-members.html | 26 +- docs/html/class_viewer_window.html | 358 +- docs/html/class_void_effect-members.html | 110 +- docs/html/class_void_effect.html | 337 +- docs/html/class_volume_effect-members.html | 108 +- docs/html/class_volume_effect.html | 276 +- docs/html/classes.html | 88 +- docs/html/clickablelabel_8cpp.html | 81 + docs/html/clickablelabel_8h.html | 92 + docs/html/clickablelabel_8h_source.html | 5 +- docs/html/clip_8cpp.html | 94 + docs/html/clip_8h.html | 141 + docs/html/clip_8h_source.html | 105 +- docs/html/clipboard_8cpp.html | 163 + docs/html/clipboard_8h.html | 221 ++ docs/html/clipboard_8h_source.html | 7 +- docs/html/collapsiblewidget_8cpp.html | 92 + docs/html/collapsiblewidget_8h.html | 93 + docs/html/collapsiblewidget_8h_source.html | 27 +- docs/html/colorbutton_8cpp.html | 83 + docs/html/colorbutton_8h.html | 95 + docs/html/colorbutton_8h_source.html | 17 +- docs/html/comboaction_8cpp.html | 81 + docs/html/comboaction_8h.html | 93 + docs/html/comboaction_8h_source.html | 89 + docs/html/comboboxex_8cpp.html | 94 + docs/html/comboboxex_8h.html | 92 + docs/html/comboboxex_8h_source.html | 10 +- docs/html/config_8cpp.html | 87 + docs/html/config_8h.html | 147 + docs/html/config_8h_source.html | 76 +- docs/html/cornerpineffect_8cpp.html | 84 + docs/html/cornerpineffect_8h.html | 91 + docs/html/cornerpineffect_8h_source.html | 27 +- docs/html/crossdissolvetransition_8cpp.html | 82 + docs/html/crossdissolvetransition_8h.html | 91 + .../crossdissolvetransition_8h_source.html | 11 +- docs/html/crossplatformlib_8cpp.html | 128 + docs/html/crossplatformlib_8h.html | 129 + docs/html/crossplatformlib_8h_source.html | 4 +- docs/html/cubetransition_8cpp.html | 82 + docs/html/cubetransition_8h.html | 91 + docs/html/cubetransition_8h_source.html | 11 +- docs/html/cursors_8cpp.html | 152 + docs/html/cursors_8h.html | 123 + docs/html/cursors_8h_source.html | 6 +- docs/html/debug_8cpp.html | 252 ++ docs/html/debug_8h.html | 200 + docs/html/debug_8h_source.html | 6 +- docs/html/debugdialog_8cpp.html | 85 + docs/html/debugdialog_8h.html | 104 + docs/html/debugdialog_8h_source.html | 8 +- docs/html/demonotice_8cpp.html | 84 + docs/html/demonotice_8h.html | 91 + docs/html/demonotice_8h_source.html | 3 +- .../dir_167790342fb55959539d550b874be046.html | 76 + .../dir_1788f8309b1a812dcb800a185471cf6c.html | 142 + .../dir_1e3623b91baed642ec07bb16fd2f1d1e.html | 6 + .../dir_27557e0778820cd254ee4de672ad398a.html | 28 + .../dir_56b9387f66bbb1dccc82a920d3dbd989.html | 60 + .../dir_63bb297c276a119495816091bcd678e9.html | 2 + .../dir_6bd69bfe0c8411ea8cfb86495c1153f0.html | 80 + .../dir_93d4afa98ce66159f3265f6d5a9de4f5.html | 16 + .../dir_bc161955dc3a3d2485839eba21420d01.html | 44 + .../dir_d44c64559bbebec7f509842c48db8b23.html | 6 + .../dir_f2b58c5fe1af6bdc9904c8245e307f38.html | 2 + docs/html/effect_8cpp.html | 323 ++ docs/html/effect_8h.html | 503 +++ docs/html/effect_8h_source.html | 186 +- docs/html/effectcontrols_8cpp.html | 110 + docs/html/effectcontrols_8h.html | 105 + docs/html/effectcontrols_8h_source.html | 79 +- docs/html/effectfield_8cpp.html | 98 + docs/html/effectfield_8h.html | 134 + docs/html/effectfield_8h_source.html | 56 +- docs/html/effectgizmo_8cpp.html | 83 + docs/html/effectgizmo_8h.html | 161 + docs/html/effectgizmo_8h_source.html | 25 +- docs/html/effectloaders_8cpp.html | 232 ++ docs/html/effectloaders_8h.html | 109 + docs/html/effectloaders_8h_source.html | 3 +- docs/html/effectrow_8cpp.html | 95 + docs/html/effectrow_8h.html | 92 + docs/html/effectrow_8h_source.html | 37 +- docs/html/embeddedfilechooser_8cpp.html | 86 + docs/html/embeddedfilechooser_8h.html | 91 + docs/html/embeddedfilechooser_8h_source.html | 12 +- docs/html/exponentialfadetransition_8cpp.html | 82 + docs/html/exponentialfadetransition_8h.html | 91 + .../exponentialfadetransition_8h_source.html | 11 +- docs/html/exportdialog_8cpp.html | 174 + docs/html/exportdialog_8h.html | 99 + docs/html/exportdialog_8h_source.html | 45 +- docs/html/exportthread_8cpp.html | 100 + docs/html/exportthread_8h.html | 168 + docs/html/exportthread_8h_source.html | 58 +- docs/html/files.html | 351 +- docs/html/fillleftrighteffect_8cpp.html | 120 + docs/html/fillleftrighteffect_8h.html | 91 + docs/html/fillleftrighteffect_8h_source.html | 10 +- docs/html/flowlayout_8cpp.html | 82 + docs/html/flowlayout_8h.html | 93 + docs/html/flowlayout_8h_source.html | 21 +- docs/html/focusfilter_8cpp.html | 84 + docs/html/focusfilter_8h.html | 104 + docs/html/focusfilter_8h_source.html | 4 +- docs/html/fontcombobox_8cpp.html | 82 + docs/html/fontcombobox_8h.html | 91 + docs/html/fontcombobox_8h_source.html | 8 +- docs/html/footage_8cpp.html | 87 + docs/html/footage_8h.html | 150 + docs/html/footage_8h_source.html | 56 +- docs/html/frei0reffect_8cpp.html | 203 + docs/html/frei0reffect_8h.html | 114 + docs/html/frei0reffect_8h_source.html | 20 +- docs/html/functions.html | 714 ++-- docs/html/functions_b.html | 196 + docs/html/functions_c.html | 545 +++ docs/html/functions_d.html | 478 +++ docs/html/functions_e.html | 287 ++ docs/html/functions_f.html | 306 ++ docs/html/functions_func.html | 417 +- docs/html/functions_func_b.html | 82 + docs/html/functions_func_c.html | 296 ++ docs/html/functions_func_d.html | 351 ++ docs/html/functions_func_e.html | 166 + docs/html/functions_func_f.html | 160 + docs/html/functions_func_g.html | 382 ++ docs/html/functions_func_h.html | 94 + docs/html/functions_func_i.html | 158 + docs/html/functions_func_k.html | 107 + docs/html/functions_func_l.html | 150 + docs/html/functions_func_m.html | 211 + docs/html/functions_func_n.html | 105 + docs/html/functions_func_o.html | 148 + docs/html/functions_func_p.html | 224 ++ docs/html/functions_func_q.html | 97 + docs/html/functions_func_r.html | 295 ++ docs/html/functions_func_s.html | 661 ++++ docs/html/functions_func_t.html | 179 + docs/html/functions_func_u.html | 190 + docs/html/functions_func_v.html | 142 + docs/html/functions_func_w.html | 93 + docs/html/functions_func_x.html | 79 + docs/html/functions_func_y.html | 79 + docs/html/functions_func_z.html | 87 + docs/html/functions_func_~.html | 175 + docs/html/functions_g.html | 421 ++ docs/html/functions_h.html | 159 + docs/html/functions_i.html | 264 ++ docs/html/functions_j.html | 82 + docs/html/functions_k.html | 153 + docs/html/functions_l.html | 265 ++ docs/html/functions_m.html | 340 ++ docs/html/functions_n.html | 222 ++ docs/html/functions_o.html | 338 ++ docs/html/functions_p.html | 482 +++ docs/html/functions_q.html | 108 + docs/html/functions_r.html | 500 +++ docs/html/functions_s.html | 1033 +++++ docs/html/functions_t.html | 504 +++ docs/html/functions_u.html | 261 ++ docs/html/functions_v.html | 325 ++ docs/html/functions_vars.html | 219 +- docs/html/functions_vars_b.html | 190 + docs/html/functions_vars_c.html | 327 ++ docs/html/functions_vars_d.html | 205 + docs/html/functions_vars_e.html | 197 + docs/html/functions_vars_f.html | 226 ++ docs/html/functions_vars_g.html | 115 + docs/html/functions_vars_h.html | 141 + docs/html/functions_vars_i.html | 184 + docs/html/functions_vars_j.html | 82 + docs/html/functions_vars_k.html | 122 + docs/html/functions_vars_l.html | 191 + docs/html/functions_vars_m.html | 203 + docs/html/functions_vars_n.html | 195 + docs/html/functions_vars_o.html | 270 ++ docs/html/functions_vars_p.html | 336 ++ docs/html/functions_vars_q.html | 89 + docs/html/functions_vars_r.html | 289 ++ docs/html/functions_vars_s.html | 448 +++ docs/html/functions_vars_t.html | 401 ++ docs/html/functions_vars_u.html | 147 + docs/html/functions_vars_v.html | 259 ++ docs/html/functions_vars_w.html | 137 + docs/html/functions_vars_x.html | 99 + docs/html/functions_vars_y.html | 96 + docs/html/functions_vars_z.html | 91 + docs/html/functions_w.html | 154 + docs/html/functions_x.html | 102 + docs/html/functions_y.html | 99 + docs/html/functions_z.html | 102 + docs/html/functions_~.html | 175 + docs/html/globals.html | 327 ++ docs/html/globals_b.html | 166 + docs/html/globals_c.html | 211 + docs/html/globals_d.html | 141 + docs/html/globals_defs.html | 603 +++ docs/html/globals_e.html | 293 ++ docs/html/globals_enum.html | 131 + docs/html/globals_eval.html | 572 +++ docs/html/globals_f.html | 201 + docs/html/globals_func.html | 94 + docs/html/globals_func_b.html | 82 + docs/html/globals_func_c.html | 164 + docs/html/globals_func_d.html | 120 + docs/html/globals_func_f.html | 95 + docs/html/globals_func_g.html | 176 + docs/html/globals_func_h.html | 82 + docs/html/globals_func_i.html | 106 + docs/html/globals_func_k.html | 79 + docs/html/globals_func_l.html | 111 + docs/html/globals_func_m.html | 90 + docs/html/globals_func_o.html | 88 + docs/html/globals_func_p.html | 91 + docs/html/globals_func_q.html | 87 + docs/html/globals_func_r.html | 92 + docs/html/globals_func_s.html | 132 + docs/html/globals_func_t.html | 83 + docs/html/globals_func_u.html | 83 + docs/html/globals_func_v.html | 82 + docs/html/globals_func_w.html | 82 + docs/html/globals_g.html | 197 + docs/html/globals_h.html | 82 + docs/html/globals_i.html | 124 + docs/html/globals_k.html | 235 ++ docs/html/globals_l.html | 138 + docs/html/globals_m.html | 111 + docs/html/globals_n.html | 79 + docs/html/globals_o.html | 91 + docs/html/globals_p.html | 132 + docs/html/globals_q.html | 87 + docs/html/globals_r.html | 106 + docs/html/globals_s.html | 163 + docs/html/globals_t.html | 173 + docs/html/globals_type.html | 200 + docs/html/globals_u.html | 83 + docs/html/globals_v.html | 179 + docs/html/globals_vars.html | 280 ++ docs/html/globals_w.html | 82 + docs/html/grapheditor_8cpp.html | 96 + docs/html/grapheditor_8h.html | 99 + docs/html/grapheditor_8h_source.html | 34 +- docs/html/graphview_8cpp.html | 270 ++ docs/html/graphview_8h.html | 129 + docs/html/graphview_8h_source.html | 68 +- docs/html/hierarchy.html | 26 +- docs/html/keyframe_8cpp.html | 122 + docs/html/keyframe_8h.html | 126 + docs/html/keyframe_8h_source.html | 11 +- docs/html/keyframedrawing_8cpp.html | 213 + docs/html/keyframedrawing_8h.html | 229 ++ docs/html/keyframedrawing_8h_source.html | 5 +- docs/html/keyframenavigator_8cpp.html | 85 + docs/html/keyframenavigator_8h.html | 91 + docs/html/keyframenavigator_8h_source.html | 17 +- docs/html/keyframeview_8cpp.html | 102 + docs/html/keyframeview_8h.html | 92 + docs/html/keyframeview_8h_source.html | 43 +- docs/html/labelslider_8cpp.html | 89 + docs/html/labelslider_8h.html | 124 + docs/html/labelslider_8h_source.html | 26 +- docs/html/linearfadetransition_8cpp.html | 81 + docs/html/linearfadetransition_8h.html | 91 + docs/html/linearfadetransition_8h_source.html | 11 +- docs/html/loaddialog_8cpp.html | 89 + docs/html/loaddialog_8h.html | 95 + docs/html/loaddialog_8h_source.html | 17 +- docs/html/loadthread_8cpp.html | 92 + docs/html/loadthread_8h.html | 97 + docs/html/loadthread_8h_source.html | 51 +- docs/html/logarithmicfadetransition_8cpp.html | 82 + docs/html/logarithmicfadetransition_8h.html | 91 + .../logarithmicfadetransition_8h_source.html | 9 +- docs/html/main_8cpp.html | 121 + docs/html/mainwindow_8cpp.html | 200 + docs/html/mainwindow_8h.html | 99 + docs/html/mainwindow_8h_source.html | 94 +- docs/html/marker_8cpp.html | 195 + docs/html/marker_8h.html | 237 ++ docs/html/marker_8h_source.html | 9 +- docs/html/math_8cpp.html | 419 ++ docs/html/math_8h.html | 465 +++ docs/html/math_8h_source.html | 12 +- docs/html/media_8cpp.html | 150 + docs/html/media_8h.html | 161 + docs/html/media_8h_source.html | 51 +- docs/html/mediaiconservice_8cpp.html | 121 + docs/html/mediaiconservice_8h.html | 142 + docs/html/mediaiconservice_8h_source.html | 100 + docs/html/mediapropertiesdialog_8cpp.html | 95 + docs/html/mediapropertiesdialog_8h.html | 98 + .../html/mediapropertiesdialog_8h_source.html | 15 +- docs/html/menudata.js | 235 +- docs/html/menuhelper_8cpp.html | 89 + docs/html/menuhelper_8h.html | 105 + docs/html/menuhelper_8h_source.html | 4 +- docs/html/namespacemembers.html | 236 ++ docs/html/namespacemembers_enum.html | 89 + docs/html/namespacemembers_eval.html | 113 + docs/html/namespacemembers_vars.html | 140 + docs/html/namespaceolive.html | 539 +++ docs/html/namespaceolive_1_1timeline.html | 167 + docs/html/namespaces.html | 82 + docs/html/newsequencedialog_8cpp.html | 100 + docs/html/newsequencedialog_8h.html | 97 + docs/html/newsequencedialog_8h_source.html | 24 +- docs/html/oliveglobal_8cpp.html | 95 + docs/html/oliveglobal_8h.html | 110 + docs/html/oliveglobal_8h_source.html | 69 +- docs/html/otreeview_8cpp.html | 81 + docs/html/otreeview_8h.html | 92 + docs/html/otreeview_8h_source.html | 4 +- docs/html/paneffect_8cpp.html | 87 + docs/html/paneffect_8h.html | 91 + docs/html/paneffect_8h_source.html | 12 +- docs/html/panel_8cpp.html | 82 + docs/html/panel_8h.html | 91 + docs/html/panel_8h_source.html | 84 + docs/html/panels_8cpp.html | 337 ++ docs/html/panels_8h.html | 316 ++ docs/html/panels_8h_source.html | 24 +- docs/html/path_8cpp.html | 266 ++ docs/html/path_8h.html | 244 ++ docs/html/path_8h_source.html | 10 +- docs/html/playback_8cpp.html | 569 +++ docs/html/playback_8h.html | 652 +++ docs/html/playback_8h_source.html | 24 +- docs/html/playbutton_8cpp.html | 81 + docs/html/playbutton_8h.html | 91 + docs/html/playbutton_8h_source.html | 5 +- docs/html/preferencesdialog_8cpp.html | 109 + docs/html/preferencesdialog_8h.html | 104 + docs/html/preferencesdialog_8h_source.html | 44 +- docs/html/previewgenerator_8cpp.html | 143 + docs/html/previewgenerator_8h.html | 99 + docs/html/previewgenerator_8h_source.html | 27 +- docs/html/project_8cpp.html | 264 ++ docs/html/project_8h.html | 254 ++ docs/html/project_8h_source.html | 85 +- docs/html/projectelements_8h.html | 89 + docs/html/projectelements_8h_source.html | 9 +- docs/html/projectfilter_8cpp.html | 84 + docs/html/projectfilter_8h.html | 91 + docs/html/projectfilter_8h_source.html | 9 +- docs/html/projectmodel_8cpp.html | 86 + docs/html/projectmodel_8h.html | 104 + docs/html/projectmodel_8h_source.html | 30 +- docs/html/proxydialog_8cpp.html | 91 + docs/html/proxydialog_8h.html | 94 + docs/html/proxydialog_8h_source.html | 13 +- docs/html/proxygenerator_8cpp.html | 130 + docs/html/proxygenerator_8h.html | 118 + docs/html/proxygenerator_8h_source.html | 22 +- docs/html/qpainterwrapper_8cpp.html | 131 + docs/html/qpainterwrapper_8h.html | 112 + docs/html/qpainterwrapper_8h_source.html | 11 +- docs/html/rectangleselect_8cpp.html | 128 + docs/html/rectangleselect_8h.html | 130 + docs/html/rectangleselect_8h_source.html | 3 +- docs/html/renderfunctions_8cpp.html | 349 ++ docs/html/renderfunctions_8h.html | 182 + docs/html/renderfunctions_8h_source.html | 20 +- docs/html/renderthread_8cpp.html | 88 + docs/html/renderthread_8h.html | 136 + docs/html/renderthread_8h_source.html | 47 +- docs/html/replaceclipmediadialog_8cpp.html | 89 + docs/html/replaceclipmediadialog_8h.html | 95 + .../replaceclipmediadialog_8h_source.html | 10 +- docs/html/resizablescrollbar_8cpp.html | 108 + docs/html/resizablescrollbar_8h.html | 91 + docs/html/resizablescrollbar_8h_source.html | 15 +- docs/html/scrollarea_8cpp.html | 86 + docs/html/scrollarea_8h.html | 91 + docs/html/scrollarea_8h_source.html | 4 +- docs/html/search/all_1.js | 199 +- docs/html/search/all_10.js | 180 +- docs/html/search/all_11.js | 69 +- docs/html/search/all_12.js | 162 +- docs/html/search/all_13.js | 342 +- docs/html/search/all_14.js | 203 +- docs/html/search/all_15.js | 63 +- docs/html/search/all_16.js | 132 +- docs/html/search/all_17.html | 30 + docs/html/search/all_17.js | 28 + docs/html/search/all_18.html | 30 + docs/html/search/all_18.js | 11 + docs/html/search/all_19.html | 30 + docs/html/search/all_19.js | 10 + docs/html/search/all_1a.html | 30 + docs/html/search/all_1a.js | 10 + docs/html/search/all_1b.html | 30 + docs/html/search/all_1b.js | 36 + docs/html/search/all_2.js | 66 +- docs/html/search/all_3.js | 226 +- docs/html/search/all_4.js | 124 +- docs/html/search/all_5.js | 171 +- docs/html/search/all_6.js | 128 +- docs/html/search/all_7.js | 153 +- docs/html/search/all_8.js | 31 +- docs/html/search/all_9.js | 76 +- docs/html/search/all_a.js | 11 +- docs/html/search/all_b.js | 116 +- docs/html/search/all_c.js | 95 +- docs/html/search/all_d.js | 114 +- docs/html/search/all_e.js | 66 +- docs/html/search/all_f.js | 91 +- docs/html/search/classes_10.js | 4 +- docs/html/search/classes_9.js | 2 +- docs/html/search/classes_c.js | 1 + docs/html/search/classes_f.js | 5 +- docs/html/search/defines_0.html | 30 + docs/html/search/defines_0.js | 56 + docs/html/search/defines_1.html | 30 + docs/html/search/defines_1.js | 4 + docs/html/search/defines_2.html | 30 + docs/html/search/defines_2.js | 12 + docs/html/search/defines_3.html | 30 + docs/html/search/defines_3.js | 5 + docs/html/search/defines_4.html | 30 + docs/html/search/defines_4.js | 37 + docs/html/search/defines_5.html | 30 + docs/html/search/defines_5.js | 7 + docs/html/search/defines_6.html | 30 + docs/html/search/defines_6.js | 5 + docs/html/search/defines_7.html | 30 + docs/html/search/defines_7.js | 23 + docs/html/search/defines_8.html | 30 + docs/html/search/defines_8.js | 6 + docs/html/search/defines_9.html | 30 + docs/html/search/defines_9.js | 6 + docs/html/search/defines_a.html | 30 + docs/html/search/defines_a.js | 4 + docs/html/search/defines_b.html | 30 + docs/html/search/defines_b.js | 5 + docs/html/search/defines_c.html | 30 + docs/html/search/defines_c.js | 10 + docs/html/search/defines_d.html | 30 + docs/html/search/defines_d.js | 6 + docs/html/search/defines_e.html | 30 + docs/html/search/defines_e.js | 16 + docs/html/search/enums_0.html | 30 + docs/html/search/enums_0.js | 4 + docs/html/search/enums_1.html | 30 + docs/html/search/enums_1.js | 4 + docs/html/search/enums_2.html | 30 + docs/html/search/enums_2.js | 9 + docs/html/search/enums_3.html | 30 + docs/html/search/enums_3.js | 4 + docs/html/search/enums_4.html | 30 + docs/html/search/enums_4.js | 4 + docs/html/search/enums_5.html | 30 + docs/html/search/enums_5.js | 4 + docs/html/search/enums_6.html | 30 + docs/html/search/enums_6.js | 4 + docs/html/search/enums_7.html | 30 + docs/html/search/enums_7.js | 4 + docs/html/search/enums_8.html | 30 + docs/html/search/enums_8.js | 4 + docs/html/search/enums_9.html | 30 + docs/html/search/enums_9.js | 4 + docs/html/search/enums_a.html | 30 + docs/html/search/enums_a.js | 8 + docs/html/search/enums_b.html | 30 + docs/html/search/enums_b.js | 7 + docs/html/search/enumvalues_0.html | 30 + docs/html/search/enumvalues_0.js | 12 + docs/html/search/enumvalues_1.html | 30 + docs/html/search/enumvalues_1.js | 30 + docs/html/search/enumvalues_2.html | 30 + docs/html/search/enumvalues_2.js | 33 + docs/html/search/enumvalues_3.html | 30 + docs/html/search/enumvalues_3.js | 27 + docs/html/search/enumvalues_4.html | 30 + docs/html/search/enumvalues_4.js | 6 + docs/html/search/enumvalues_5.html | 30 + docs/html/search/enumvalues_5.js | 8 + docs/html/search/enumvalues_6.html | 30 + docs/html/search/enumvalues_6.js | 30 + docs/html/search/enumvalues_7.html | 30 + docs/html/search/enumvalues_7.js | 7 + docs/html/search/enumvalues_8.html | 30 + docs/html/search/enumvalues_8.js | 6 + docs/html/search/enumvalues_9.html | 30 + docs/html/search/enumvalues_9.js | 5 + docs/html/search/enumvalues_a.html | 30 + docs/html/search/enumvalues_a.js | 5 + docs/html/search/enumvalues_b.html | 30 + docs/html/search/enumvalues_b.js | 24 + docs/html/search/enumvalues_c.html | 30 + docs/html/search/enumvalues_c.js | 11 + docs/html/search/files_0.html | 30 + docs/html/search/files_0.js | 15 + docs/html/search/files_1.html | 30 + docs/html/search/files_1.js | 33 + docs/html/search/files_10.html | 30 + docs/html/search/files_10.js | 24 + docs/html/search/files_11.html | 30 + docs/html/search/files_11.js | 5 + docs/html/search/files_12.html | 30 + docs/html/search/files_12.js | 19 + docs/html/search/files_2.html | 30 + docs/html/search/files_2.js | 9 + docs/html/search/files_3.html | 30 + docs/html/search/files_3.js | 23 + docs/html/search/files_4.html | 30 + docs/html/search/files_4.js | 15 + docs/html/search/files_5.html | 30 + docs/html/search/files_5.js | 7 + docs/html/search/files_6.html | 30 + docs/html/search/files_6.js | 4 + docs/html/search/files_7.html | 30 + docs/html/search/files_7.js | 11 + docs/html/search/files_8.html | 30 + docs/html/search/files_8.js | 13 + docs/html/search/files_9.html | 30 + docs/html/search/files_9.js | 18 + docs/html/search/files_a.html | 30 + docs/html/search/files_a.js | 5 + docs/html/search/files_b.html | 30 + docs/html/search/files_b.js | 7 + docs/html/search/files_c.html | 30 + docs/html/search/files_c.js | 30 + docs/html/search/files_d.html | 30 + docs/html/search/files_d.js | 5 + docs/html/search/files_e.html | 30 + docs/html/search/files_e.js | 14 + docs/html/search/files_f.html | 30 + docs/html/search/files_f.js | 20 + docs/html/search/functions_0.js | 52 +- docs/html/search/functions_1.js | 7 +- docs/html/search/functions_10.js | 65 +- docs/html/search/functions_11.js | 195 +- docs/html/search/functions_12.html | 30 + docs/html/search/functions_12.js | 39 + docs/html/search/functions_13.html | 30 + docs/html/search/functions_13.js | 38 + docs/html/search/functions_14.html | 30 + docs/html/search/functions_14.js | 27 + docs/html/search/functions_15.html | 30 + docs/html/search/functions_15.js | 9 + docs/html/search/functions_16.html | 30 + docs/html/search/functions_16.js | 4 + docs/html/search/functions_17.html | 30 + docs/html/search/functions_17.js | 4 + docs/html/search/functions_18.html | 30 + docs/html/search/functions_18.js | 6 + docs/html/search/functions_19.html | 30 + docs/html/search/functions_19.js | 36 + docs/html/search/functions_2.js | 89 +- docs/html/search/functions_3.js | 72 +- docs/html/search/functions_4.js | 37 +- docs/html/search/functions_5.js | 36 +- docs/html/search/functions_6.js | 126 +- docs/html/search/functions_7.js | 14 +- docs/html/search/functions_8.js | 35 +- docs/html/search/functions_9.js | 22 +- docs/html/search/functions_a.js | 42 +- docs/html/search/functions_b.js | 41 +- docs/html/search/functions_c.js | 37 +- docs/html/search/functions_d.js | 31 +- docs/html/search/functions_e.js | 48 +- docs/html/search/functions_f.js | 14 +- docs/html/search/namespaces_0.html | 30 + docs/html/search/namespaces_0.js | 5 + docs/html/search/searchdata.js | 38 +- docs/html/search/typedefs_0.html | 30 + docs/html/search/typedefs_0.js | 5 + docs/html/search/typedefs_1.html | 30 + docs/html/search/typedefs_1.js | 4 + docs/html/search/typedefs_2.html | 30 + docs/html/search/typedefs_2.js | 4 + docs/html/search/typedefs_3.html | 30 + docs/html/search/typedefs_3.js | 4 + docs/html/search/typedefs_4.html | 30 + docs/html/search/typedefs_4.js | 12 + docs/html/search/typedefs_5.html | 30 + docs/html/search/typedefs_5.js | 4 + docs/html/search/typedefs_6.html | 30 + docs/html/search/typedefs_6.js | 5 + docs/html/search/typedefs_7.html | 30 + docs/html/search/typedefs_7.js | 5 + docs/html/search/typedefs_8.html | 30 + docs/html/search/typedefs_8.js | 4 + docs/html/search/typedefs_9.html | 30 + docs/html/search/typedefs_9.js | 10 + docs/html/search/variables_0.js | 67 +- docs/html/search/variables_1.js | 34 +- docs/html/search/variables_10.html | 30 + docs/html/search/variables_10.js | 7 + docs/html/search/variables_11.html | 30 + docs/html/search/variables_11.js | 72 + docs/html/search/variables_12.html | 30 + docs/html/search/variables_12.js | 122 + docs/html/search/variables_13.html | 30 + docs/html/search/variables_13.js | 106 + docs/html/search/variables_14.html | 30 + docs/html/search/variables_14.js | 27 + docs/html/search/variables_15.html | 30 + docs/html/search/variables_15.js | 61 + docs/html/search/variables_16.html | 30 + docs/html/search/variables_16.js | 22 + docs/html/search/variables_17.html | 30 + docs/html/search/variables_17.js | 10 + docs/html/search/variables_18.html | 30 + docs/html/search/variables_18.js | 9 + docs/html/search/variables_19.html | 30 + docs/html/search/variables_19.js | 7 + docs/html/search/variables_2.js | 84 +- docs/html/search/variables_3.js | 42 +- docs/html/search/variables_4.js | 39 +- docs/html/search/variables_5.js | 47 +- docs/html/search/variables_6.js | 15 +- docs/html/search/variables_7.js | 20 +- docs/html/search/variables_8.js | 32 +- docs/html/search/variables_9.js | 5 +- docs/html/search/variables_a.js | 34 +- docs/html/search/variables_b.js | 39 +- docs/html/search/variables_c.js | 42 +- docs/html/search/variables_d.html | 30 + docs/html/search/variables_d.js | 38 + docs/html/search/variables_e.html | 30 + docs/html/search/variables_e.js | 61 + docs/html/search/variables_f.html | 30 + docs/html/search/variables_f.js | 92 + docs/html/selection_8h.html | 90 + docs/html/selection_8h_source.html | 9 +- docs/html/sequence_8cpp.html | 83 + docs/html/sequence_8h.html | 128 + docs/html/sequence_8h_source.html | 34 +- docs/html/shakeeffect_8cpp.html | 91 + docs/html/shakeeffect_8h.html | 112 + docs/html/shakeeffect_8h_source.html | 16 +- docs/html/solideffect_8cpp.html | 192 + docs/html/solideffect_8h.html | 92 + docs/html/solideffect_8h_source.html | 16 +- docs/html/sourceiconview_8cpp.html | 86 + docs/html/sourceiconview_8h.html | 91 + docs/html/sourceiconview_8h_source.html | 12 +- docs/html/sourcescommon_8cpp.html | 104 + docs/html/sourcescommon_8h.html | 94 + docs/html/sourcescommon_8h_source.html | 29 +- docs/html/sourcetable_8cpp.html | 104 + docs/html/sourcetable_8h.html | 93 + docs/html/sourcetable_8h_source.html | 15 +- docs/html/speeddialog_8cpp.html | 155 + docs/html/speeddialog_8h.html | 94 + docs/html/speeddialog_8h_source.html | 23 +- docs/html/struct___a_effect-members.html | 38 +- docs/html/struct___a_effect.html | 326 +- docs/html/struct___vst_event-members.html | 2 +- docs/html/struct___vst_event.html | 20 +- docs/html/struct___vst_events-members.html | 6 +- docs/html/struct___vst_events.html | 54 +- .../html/struct___vst_midi_event-members.html | 22 +- docs/html/struct___vst_midi_event.html | 190 +- ...ct___vst_parameter_properties-members.html | 32 +- .../struct___vst_parameter_properties.html | 275 +- docs/html/struct___vst_time_info-members.html | 28 +- docs/html/struct___vst_time_info.html | 241 +- ...truct_compose_sequence_params-members.html | 8 +- docs/html/struct_compose_sequence_params.html | 112 +- docs/html/struct_config-members.html | 91 +- docs/html/struct_config.html | 1002 ++++- docs/html/struct_effect_meta-members.html | 16 +- docs/html/struct_effect_meta.html | 139 +- docs/html/struct_export_params-members.html | 28 +- docs/html/struct_export_params.html | 241 +- docs/html/struct_footage-members.html | 46 +- docs/html/struct_footage.html | 423 +- docs/html/struct_footage_stream-members.html | 32 +- docs/html/struct_footage_stream.html | 281 +- .../struct_g_l_texture_coords-members.html | 54 +- docs/html/struct_g_l_texture_coords.html | 462 ++- docs/html/struct_ghost-members.html | 31 +- docs/html/struct_ghost.html | 265 +- docs/html/struct_marker-members.html | 4 +- docs/html/struct_marker.html | 37 +- docs/html/struct_proxy_info-members.html | 8 +- docs/html/struct_proxy_info.html | 73 +- docs/html/struct_runtime_config-members.html | 8 +- docs/html/struct_runtime_config.html | 102 +- docs/html/struct_selection-members.html | 14 +- docs/html/struct_selection.html | 122 +- .../struct_timeline_track_height-members.html | 81 + docs/html/struct_timeline_track_height.html | 121 + docs/html/struct_v_s_t_rect-members.html | 8 +- docs/html/struct_v_s_t_rect.html | 71 +- .../struct_video_codec_params-members.html | 2 +- docs/html/struct_video_codec_params.html | 20 +- docs/html/texteditdialog_8cpp.html | 83 + docs/html/texteditdialog_8h.html | 92 + docs/html/texteditdialog_8h_source.html | 8 +- docs/html/texteditex_8cpp.html | 82 + docs/html/texteditex_8h.html | 91 + docs/html/texteditex_8h_source.html | 11 +- docs/html/texteffect_8cpp.html | 152 + docs/html/texteffect_8h.html | 93 + docs/html/texteffect_8h_source.html | 31 +- docs/html/timecodeeffect_8cpp.html | 103 + docs/html/timecodeeffect_8h.html | 93 + docs/html/timecodeeffect_8h_source.html | 21 +- docs/html/timeline_8cpp.html | 358 ++ docs/html/timeline_8h.html | 411 ++ docs/html/timeline_8h_source.html | 210 +- docs/html/timelineheader_8cpp.html | 225 ++ docs/html/timelineheader_8h.html | 133 + docs/html/timelineheader_8h_source.html | 45 +- docs/html/timelinetools_8h.html | 135 + docs/html/timelinetools_8h_source.html | 15 +- docs/html/timelinewidget_8cpp.html | 549 +++ docs/html/timelinewidget_8h.html | 227 ++ docs/html/timelinewidget_8h_source.html | 70 +- docs/html/toneeffect_8cpp.html | 108 + docs/html/toneeffect_8h.html | 91 + docs/html/toneeffect_8h_source.html | 14 +- docs/html/transformeffect_8cpp.html | 144 + docs/html/transformeffect_8h.html | 91 + docs/html/transformeffect_8h_source.html | 36 +- docs/html/transition_8cpp.html | 181 + docs/html/transition_8h.html | 257 ++ docs/html/transition_8h_source.html | 35 +- docs/html/undo_8cpp.html | 105 + docs/html/undo_8h.html | 207 + docs/html/undo_8h_source.html | 453 ++- docs/html/version_8h.html | 297 ++ docs/html/version_8h_source.html | 2 +- docs/html/vestige_8h.html | 1953 +++++++++ docs/html/vestige_8h_source.html | 97 +- docs/html/viewer_8cpp.html | 244 ++ docs/html/viewer_8h.html | 199 + docs/html/viewer_8h_source.html | 110 +- docs/html/viewercontainer_8cpp.html | 90 + docs/html/viewercontainer_8h.html | 91 + docs/html/viewercontainer_8h_source.html | 23 +- docs/html/viewerwidget_8cpp.html | 123 + docs/html/viewerwidget_8h.html | 104 + docs/html/viewerwidget_8h_source.html | 68 +- docs/html/viewerwindow_8cpp.html | 91 + docs/html/viewerwindow_8h.html | 92 + docs/html/viewerwindow_8h_source.html | 15 +- docs/html/voideffect_8cpp.html | 86 + docs/html/voideffect_8h.html | 91 + docs/html/voideffect_8h_source.html | 14 +- docs/html/volumeeffect_8cpp.html | 87 + docs/html/volumeeffect_8h.html | 91 + docs/html/volumeeffect_8h_source.html | 10 +- docs/html/vsthost_8cpp.html | 311 ++ docs/html/vsthost_8h.html | 115 + docs/html/vsthost_8h_source.html | 38 +- io/config.cpp | 9 +- io/config.h | 457 ++- 1073 files changed, 133630 insertions(+), 12986 deletions(-) create mode 100644 docs/doxygen_objdb_3636.tmp create mode 100644 docs/html/_i_s_s_u_e___t_e_m_p_l_a_t_e_8md.html create mode 100644 docs/html/_r_e_a_d_m_e_8md.html create mode 100644 docs/html/aboutdialog_8cpp.html create mode 100644 docs/html/aboutdialog_8h.html create mode 100644 docs/html/actionsearch_8cpp.html create mode 100644 docs/html/actionsearch_8h.html create mode 100644 docs/html/advancedvideodialog_8cpp.html create mode 100644 docs/html/advancedvideodialog_8h.html create mode 100644 docs/html/audio_8cpp.html create mode 100644 docs/html/audio_8h.html create mode 100644 docs/html/audiomonitor_8cpp.html create mode 100644 docs/html/audiomonitor_8h.html create mode 100644 docs/html/audionoiseeffect_8cpp.html create mode 100644 docs/html/audionoiseeffect_8h.html create mode 100644 docs/html/cacher_8cpp.html create mode 100644 docs/html/cacher_8h.html create mode 100644 docs/html/checkboxex_8cpp.html create mode 100644 docs/html/checkboxex_8h.html create mode 100644 docs/html/class_media_icon_service-members.html create mode 100644 docs/html/class_media_icon_service.html create mode 100644 docs/html/class_media_icon_service.png create mode 100644 docs/html/class_panel-members.html create mode 100644 docs/html/class_panel.html create mode 100644 docs/html/class_panel.png create mode 100644 docs/html/class_sequence-members.html create mode 100644 docs/html/class_sequence.html create mode 100644 docs/html/clickablelabel_8cpp.html create mode 100644 docs/html/clickablelabel_8h.html create mode 100644 docs/html/clip_8cpp.html create mode 100644 docs/html/clip_8h.html create mode 100644 docs/html/clipboard_8cpp.html create mode 100644 docs/html/clipboard_8h.html create mode 100644 docs/html/collapsiblewidget_8cpp.html create mode 100644 docs/html/collapsiblewidget_8h.html create mode 100644 docs/html/colorbutton_8cpp.html create mode 100644 docs/html/colorbutton_8h.html create mode 100644 docs/html/comboaction_8cpp.html create mode 100644 docs/html/comboaction_8h.html create mode 100644 docs/html/comboaction_8h_source.html create mode 100644 docs/html/comboboxex_8cpp.html create mode 100644 docs/html/comboboxex_8h.html create mode 100644 docs/html/config_8cpp.html create mode 100644 docs/html/config_8h.html create mode 100644 docs/html/cornerpineffect_8cpp.html create mode 100644 docs/html/cornerpineffect_8h.html create mode 100644 docs/html/crossdissolvetransition_8cpp.html create mode 100644 docs/html/crossdissolvetransition_8h.html create mode 100644 docs/html/crossplatformlib_8cpp.html create mode 100644 docs/html/crossplatformlib_8h.html create mode 100644 docs/html/cubetransition_8cpp.html create mode 100644 docs/html/cubetransition_8h.html create mode 100644 docs/html/cursors_8cpp.html create mode 100644 docs/html/cursors_8h.html create mode 100644 docs/html/debug_8cpp.html create mode 100644 docs/html/debug_8h.html create mode 100644 docs/html/debugdialog_8cpp.html create mode 100644 docs/html/debugdialog_8h.html create mode 100644 docs/html/demonotice_8cpp.html create mode 100644 docs/html/demonotice_8h.html create mode 100644 docs/html/effect_8cpp.html create mode 100644 docs/html/effect_8h.html create mode 100644 docs/html/effectcontrols_8cpp.html create mode 100644 docs/html/effectcontrols_8h.html create mode 100644 docs/html/effectfield_8cpp.html create mode 100644 docs/html/effectfield_8h.html create mode 100644 docs/html/effectgizmo_8cpp.html create mode 100644 docs/html/effectgizmo_8h.html create mode 100644 docs/html/effectloaders_8cpp.html create mode 100644 docs/html/effectloaders_8h.html create mode 100644 docs/html/effectrow_8cpp.html create mode 100644 docs/html/effectrow_8h.html create mode 100644 docs/html/embeddedfilechooser_8cpp.html create mode 100644 docs/html/embeddedfilechooser_8h.html create mode 100644 docs/html/exponentialfadetransition_8cpp.html create mode 100644 docs/html/exponentialfadetransition_8h.html create mode 100644 docs/html/exportdialog_8cpp.html create mode 100644 docs/html/exportdialog_8h.html create mode 100644 docs/html/exportthread_8cpp.html create mode 100644 docs/html/exportthread_8h.html create mode 100644 docs/html/fillleftrighteffect_8cpp.html create mode 100644 docs/html/fillleftrighteffect_8h.html create mode 100644 docs/html/flowlayout_8cpp.html create mode 100644 docs/html/flowlayout_8h.html create mode 100644 docs/html/focusfilter_8cpp.html create mode 100644 docs/html/focusfilter_8h.html create mode 100644 docs/html/fontcombobox_8cpp.html create mode 100644 docs/html/fontcombobox_8h.html create mode 100644 docs/html/footage_8cpp.html create mode 100644 docs/html/footage_8h.html create mode 100644 docs/html/frei0reffect_8cpp.html create mode 100644 docs/html/frei0reffect_8h.html create mode 100644 docs/html/functions_b.html create mode 100644 docs/html/functions_c.html create mode 100644 docs/html/functions_d.html create mode 100644 docs/html/functions_e.html create mode 100644 docs/html/functions_f.html create mode 100644 docs/html/functions_func_b.html create mode 100644 docs/html/functions_func_c.html create mode 100644 docs/html/functions_func_d.html create mode 100644 docs/html/functions_func_e.html create mode 100644 docs/html/functions_func_f.html create mode 100644 docs/html/functions_func_g.html create mode 100644 docs/html/functions_func_h.html create mode 100644 docs/html/functions_func_i.html create mode 100644 docs/html/functions_func_k.html create mode 100644 docs/html/functions_func_l.html create mode 100644 docs/html/functions_func_m.html create mode 100644 docs/html/functions_func_n.html create mode 100644 docs/html/functions_func_o.html create mode 100644 docs/html/functions_func_p.html create mode 100644 docs/html/functions_func_q.html create mode 100644 docs/html/functions_func_r.html create mode 100644 docs/html/functions_func_s.html create mode 100644 docs/html/functions_func_t.html create mode 100644 docs/html/functions_func_u.html create mode 100644 docs/html/functions_func_v.html create mode 100644 docs/html/functions_func_w.html create mode 100644 docs/html/functions_func_x.html create mode 100644 docs/html/functions_func_y.html create mode 100644 docs/html/functions_func_z.html create mode 100644 docs/html/functions_func_~.html create mode 100644 docs/html/functions_g.html create mode 100644 docs/html/functions_h.html create mode 100644 docs/html/functions_i.html create mode 100644 docs/html/functions_j.html create mode 100644 docs/html/functions_k.html create mode 100644 docs/html/functions_l.html create mode 100644 docs/html/functions_m.html create mode 100644 docs/html/functions_n.html create mode 100644 docs/html/functions_o.html create mode 100644 docs/html/functions_p.html create mode 100644 docs/html/functions_q.html create mode 100644 docs/html/functions_r.html create mode 100644 docs/html/functions_s.html create mode 100644 docs/html/functions_t.html create mode 100644 docs/html/functions_u.html create mode 100644 docs/html/functions_v.html create mode 100644 docs/html/functions_vars_b.html create mode 100644 docs/html/functions_vars_c.html create mode 100644 docs/html/functions_vars_d.html create mode 100644 docs/html/functions_vars_e.html create mode 100644 docs/html/functions_vars_f.html create mode 100644 docs/html/functions_vars_g.html create mode 100644 docs/html/functions_vars_h.html create mode 100644 docs/html/functions_vars_i.html create mode 100644 docs/html/functions_vars_j.html create mode 100644 docs/html/functions_vars_k.html create mode 100644 docs/html/functions_vars_l.html create mode 100644 docs/html/functions_vars_m.html create mode 100644 docs/html/functions_vars_n.html create mode 100644 docs/html/functions_vars_o.html create mode 100644 docs/html/functions_vars_p.html create mode 100644 docs/html/functions_vars_q.html create mode 100644 docs/html/functions_vars_r.html create mode 100644 docs/html/functions_vars_s.html create mode 100644 docs/html/functions_vars_t.html create mode 100644 docs/html/functions_vars_u.html create mode 100644 docs/html/functions_vars_v.html create mode 100644 docs/html/functions_vars_w.html create mode 100644 docs/html/functions_vars_x.html create mode 100644 docs/html/functions_vars_y.html create mode 100644 docs/html/functions_vars_z.html create mode 100644 docs/html/functions_w.html create mode 100644 docs/html/functions_x.html create mode 100644 docs/html/functions_y.html create mode 100644 docs/html/functions_z.html create mode 100644 docs/html/functions_~.html create mode 100644 docs/html/globals.html create mode 100644 docs/html/globals_b.html create mode 100644 docs/html/globals_c.html create mode 100644 docs/html/globals_d.html create mode 100644 docs/html/globals_defs.html create mode 100644 docs/html/globals_e.html create mode 100644 docs/html/globals_enum.html create mode 100644 docs/html/globals_eval.html create mode 100644 docs/html/globals_f.html create mode 100644 docs/html/globals_func.html create mode 100644 docs/html/globals_func_b.html create mode 100644 docs/html/globals_func_c.html create mode 100644 docs/html/globals_func_d.html create mode 100644 docs/html/globals_func_f.html create mode 100644 docs/html/globals_func_g.html create mode 100644 docs/html/globals_func_h.html create mode 100644 docs/html/globals_func_i.html create mode 100644 docs/html/globals_func_k.html create mode 100644 docs/html/globals_func_l.html create mode 100644 docs/html/globals_func_m.html create mode 100644 docs/html/globals_func_o.html create mode 100644 docs/html/globals_func_p.html create mode 100644 docs/html/globals_func_q.html create mode 100644 docs/html/globals_func_r.html create mode 100644 docs/html/globals_func_s.html create mode 100644 docs/html/globals_func_t.html create mode 100644 docs/html/globals_func_u.html create mode 100644 docs/html/globals_func_v.html create mode 100644 docs/html/globals_func_w.html create mode 100644 docs/html/globals_g.html create mode 100644 docs/html/globals_h.html create mode 100644 docs/html/globals_i.html create mode 100644 docs/html/globals_k.html create mode 100644 docs/html/globals_l.html create mode 100644 docs/html/globals_m.html create mode 100644 docs/html/globals_n.html create mode 100644 docs/html/globals_o.html create mode 100644 docs/html/globals_p.html create mode 100644 docs/html/globals_q.html create mode 100644 docs/html/globals_r.html create mode 100644 docs/html/globals_s.html create mode 100644 docs/html/globals_t.html create mode 100644 docs/html/globals_type.html create mode 100644 docs/html/globals_u.html create mode 100644 docs/html/globals_v.html create mode 100644 docs/html/globals_vars.html create mode 100644 docs/html/globals_w.html create mode 100644 docs/html/grapheditor_8cpp.html create mode 100644 docs/html/grapheditor_8h.html create mode 100644 docs/html/graphview_8cpp.html create mode 100644 docs/html/graphview_8h.html create mode 100644 docs/html/keyframe_8cpp.html create mode 100644 docs/html/keyframe_8h.html create mode 100644 docs/html/keyframedrawing_8cpp.html create mode 100644 docs/html/keyframedrawing_8h.html create mode 100644 docs/html/keyframenavigator_8cpp.html create mode 100644 docs/html/keyframenavigator_8h.html create mode 100644 docs/html/keyframeview_8cpp.html create mode 100644 docs/html/keyframeview_8h.html create mode 100644 docs/html/labelslider_8cpp.html create mode 100644 docs/html/labelslider_8h.html create mode 100644 docs/html/linearfadetransition_8cpp.html create mode 100644 docs/html/linearfadetransition_8h.html create mode 100644 docs/html/loaddialog_8cpp.html create mode 100644 docs/html/loaddialog_8h.html create mode 100644 docs/html/loadthread_8cpp.html create mode 100644 docs/html/loadthread_8h.html create mode 100644 docs/html/logarithmicfadetransition_8cpp.html create mode 100644 docs/html/logarithmicfadetransition_8h.html create mode 100644 docs/html/main_8cpp.html create mode 100644 docs/html/mainwindow_8cpp.html create mode 100644 docs/html/mainwindow_8h.html create mode 100644 docs/html/marker_8cpp.html create mode 100644 docs/html/marker_8h.html create mode 100644 docs/html/math_8cpp.html create mode 100644 docs/html/math_8h.html create mode 100644 docs/html/media_8cpp.html create mode 100644 docs/html/media_8h.html create mode 100644 docs/html/mediaiconservice_8cpp.html create mode 100644 docs/html/mediaiconservice_8h.html create mode 100644 docs/html/mediaiconservice_8h_source.html create mode 100644 docs/html/mediapropertiesdialog_8cpp.html create mode 100644 docs/html/mediapropertiesdialog_8h.html create mode 100644 docs/html/menuhelper_8cpp.html create mode 100644 docs/html/menuhelper_8h.html create mode 100644 docs/html/namespacemembers.html create mode 100644 docs/html/namespacemembers_enum.html create mode 100644 docs/html/namespacemembers_eval.html create mode 100644 docs/html/namespacemembers_vars.html create mode 100644 docs/html/namespaceolive.html create mode 100644 docs/html/namespaceolive_1_1timeline.html create mode 100644 docs/html/namespaces.html create mode 100644 docs/html/newsequencedialog_8cpp.html create mode 100644 docs/html/newsequencedialog_8h.html create mode 100644 docs/html/oliveglobal_8cpp.html create mode 100644 docs/html/oliveglobal_8h.html create mode 100644 docs/html/otreeview_8cpp.html create mode 100644 docs/html/otreeview_8h.html create mode 100644 docs/html/paneffect_8cpp.html create mode 100644 docs/html/paneffect_8h.html create mode 100644 docs/html/panel_8cpp.html create mode 100644 docs/html/panel_8h.html create mode 100644 docs/html/panel_8h_source.html create mode 100644 docs/html/panels_8cpp.html create mode 100644 docs/html/panels_8h.html create mode 100644 docs/html/path_8cpp.html create mode 100644 docs/html/path_8h.html create mode 100644 docs/html/playback_8cpp.html create mode 100644 docs/html/playback_8h.html create mode 100644 docs/html/playbutton_8cpp.html create mode 100644 docs/html/playbutton_8h.html create mode 100644 docs/html/preferencesdialog_8cpp.html create mode 100644 docs/html/preferencesdialog_8h.html create mode 100644 docs/html/previewgenerator_8cpp.html create mode 100644 docs/html/previewgenerator_8h.html create mode 100644 docs/html/project_8cpp.html create mode 100644 docs/html/project_8h.html create mode 100644 docs/html/projectelements_8h.html create mode 100644 docs/html/projectfilter_8cpp.html create mode 100644 docs/html/projectfilter_8h.html create mode 100644 docs/html/projectmodel_8cpp.html create mode 100644 docs/html/projectmodel_8h.html create mode 100644 docs/html/proxydialog_8cpp.html create mode 100644 docs/html/proxydialog_8h.html create mode 100644 docs/html/proxygenerator_8cpp.html create mode 100644 docs/html/proxygenerator_8h.html create mode 100644 docs/html/qpainterwrapper_8cpp.html create mode 100644 docs/html/qpainterwrapper_8h.html create mode 100644 docs/html/rectangleselect_8cpp.html create mode 100644 docs/html/rectangleselect_8h.html create mode 100644 docs/html/renderfunctions_8cpp.html create mode 100644 docs/html/renderfunctions_8h.html create mode 100644 docs/html/renderthread_8cpp.html create mode 100644 docs/html/renderthread_8h.html create mode 100644 docs/html/replaceclipmediadialog_8cpp.html create mode 100644 docs/html/replaceclipmediadialog_8h.html create mode 100644 docs/html/resizablescrollbar_8cpp.html create mode 100644 docs/html/resizablescrollbar_8h.html create mode 100644 docs/html/scrollarea_8cpp.html create mode 100644 docs/html/scrollarea_8h.html create mode 100644 docs/html/search/all_17.html create mode 100644 docs/html/search/all_17.js create mode 100644 docs/html/search/all_18.html create mode 100644 docs/html/search/all_18.js create mode 100644 docs/html/search/all_19.html create mode 100644 docs/html/search/all_19.js create mode 100644 docs/html/search/all_1a.html create mode 100644 docs/html/search/all_1a.js create mode 100644 docs/html/search/all_1b.html create mode 100644 docs/html/search/all_1b.js create mode 100644 docs/html/search/defines_0.html create mode 100644 docs/html/search/defines_0.js create mode 100644 docs/html/search/defines_1.html create mode 100644 docs/html/search/defines_1.js create mode 100644 docs/html/search/defines_2.html create mode 100644 docs/html/search/defines_2.js create mode 100644 docs/html/search/defines_3.html create mode 100644 docs/html/search/defines_3.js create mode 100644 docs/html/search/defines_4.html create mode 100644 docs/html/search/defines_4.js create mode 100644 docs/html/search/defines_5.html create mode 100644 docs/html/search/defines_5.js create mode 100644 docs/html/search/defines_6.html create mode 100644 docs/html/search/defines_6.js create mode 100644 docs/html/search/defines_7.html create mode 100644 docs/html/search/defines_7.js create mode 100644 docs/html/search/defines_8.html create mode 100644 docs/html/search/defines_8.js create mode 100644 docs/html/search/defines_9.html create mode 100644 docs/html/search/defines_9.js create mode 100644 docs/html/search/defines_a.html create mode 100644 docs/html/search/defines_a.js create mode 100644 docs/html/search/defines_b.html create mode 100644 docs/html/search/defines_b.js create mode 100644 docs/html/search/defines_c.html create mode 100644 docs/html/search/defines_c.js create mode 100644 docs/html/search/defines_d.html create mode 100644 docs/html/search/defines_d.js create mode 100644 docs/html/search/defines_e.html create mode 100644 docs/html/search/defines_e.js create mode 100644 docs/html/search/enums_0.html create mode 100644 docs/html/search/enums_0.js create mode 100644 docs/html/search/enums_1.html create mode 100644 docs/html/search/enums_1.js create mode 100644 docs/html/search/enums_2.html create mode 100644 docs/html/search/enums_2.js create mode 100644 docs/html/search/enums_3.html create mode 100644 docs/html/search/enums_3.js create mode 100644 docs/html/search/enums_4.html create mode 100644 docs/html/search/enums_4.js create mode 100644 docs/html/search/enums_5.html create mode 100644 docs/html/search/enums_5.js create mode 100644 docs/html/search/enums_6.html create mode 100644 docs/html/search/enums_6.js create mode 100644 docs/html/search/enums_7.html create mode 100644 docs/html/search/enums_7.js create mode 100644 docs/html/search/enums_8.html create mode 100644 docs/html/search/enums_8.js create mode 100644 docs/html/search/enums_9.html create mode 100644 docs/html/search/enums_9.js create mode 100644 docs/html/search/enums_a.html create mode 100644 docs/html/search/enums_a.js create mode 100644 docs/html/search/enums_b.html create mode 100644 docs/html/search/enums_b.js create mode 100644 docs/html/search/enumvalues_0.html create mode 100644 docs/html/search/enumvalues_0.js create mode 100644 docs/html/search/enumvalues_1.html create mode 100644 docs/html/search/enumvalues_1.js create mode 100644 docs/html/search/enumvalues_2.html create mode 100644 docs/html/search/enumvalues_2.js create mode 100644 docs/html/search/enumvalues_3.html create mode 100644 docs/html/search/enumvalues_3.js create mode 100644 docs/html/search/enumvalues_4.html create mode 100644 docs/html/search/enumvalues_4.js create mode 100644 docs/html/search/enumvalues_5.html create mode 100644 docs/html/search/enumvalues_5.js create mode 100644 docs/html/search/enumvalues_6.html create mode 100644 docs/html/search/enumvalues_6.js create mode 100644 docs/html/search/enumvalues_7.html create mode 100644 docs/html/search/enumvalues_7.js create mode 100644 docs/html/search/enumvalues_8.html create mode 100644 docs/html/search/enumvalues_8.js create mode 100644 docs/html/search/enumvalues_9.html create mode 100644 docs/html/search/enumvalues_9.js create mode 100644 docs/html/search/enumvalues_a.html create mode 100644 docs/html/search/enumvalues_a.js create mode 100644 docs/html/search/enumvalues_b.html create mode 100644 docs/html/search/enumvalues_b.js create mode 100644 docs/html/search/enumvalues_c.html create mode 100644 docs/html/search/enumvalues_c.js create mode 100644 docs/html/search/files_0.html create mode 100644 docs/html/search/files_0.js create mode 100644 docs/html/search/files_1.html create mode 100644 docs/html/search/files_1.js create mode 100644 docs/html/search/files_10.html create mode 100644 docs/html/search/files_10.js create mode 100644 docs/html/search/files_11.html create mode 100644 docs/html/search/files_11.js create mode 100644 docs/html/search/files_12.html create mode 100644 docs/html/search/files_12.js create mode 100644 docs/html/search/files_2.html create mode 100644 docs/html/search/files_2.js create mode 100644 docs/html/search/files_3.html create mode 100644 docs/html/search/files_3.js create mode 100644 docs/html/search/files_4.html create mode 100644 docs/html/search/files_4.js create mode 100644 docs/html/search/files_5.html create mode 100644 docs/html/search/files_5.js create mode 100644 docs/html/search/files_6.html create mode 100644 docs/html/search/files_6.js create mode 100644 docs/html/search/files_7.html create mode 100644 docs/html/search/files_7.js create mode 100644 docs/html/search/files_8.html create mode 100644 docs/html/search/files_8.js create mode 100644 docs/html/search/files_9.html create mode 100644 docs/html/search/files_9.js create mode 100644 docs/html/search/files_a.html create mode 100644 docs/html/search/files_a.js create mode 100644 docs/html/search/files_b.html create mode 100644 docs/html/search/files_b.js create mode 100644 docs/html/search/files_c.html create mode 100644 docs/html/search/files_c.js create mode 100644 docs/html/search/files_d.html create mode 100644 docs/html/search/files_d.js create mode 100644 docs/html/search/files_e.html create mode 100644 docs/html/search/files_e.js create mode 100644 docs/html/search/files_f.html create mode 100644 docs/html/search/files_f.js create mode 100644 docs/html/search/functions_12.html create mode 100644 docs/html/search/functions_12.js create mode 100644 docs/html/search/functions_13.html create mode 100644 docs/html/search/functions_13.js create mode 100644 docs/html/search/functions_14.html create mode 100644 docs/html/search/functions_14.js create mode 100644 docs/html/search/functions_15.html create mode 100644 docs/html/search/functions_15.js create mode 100644 docs/html/search/functions_16.html create mode 100644 docs/html/search/functions_16.js create mode 100644 docs/html/search/functions_17.html create mode 100644 docs/html/search/functions_17.js create mode 100644 docs/html/search/functions_18.html create mode 100644 docs/html/search/functions_18.js create mode 100644 docs/html/search/functions_19.html create mode 100644 docs/html/search/functions_19.js create mode 100644 docs/html/search/namespaces_0.html create mode 100644 docs/html/search/namespaces_0.js create mode 100644 docs/html/search/typedefs_0.html create mode 100644 docs/html/search/typedefs_0.js create mode 100644 docs/html/search/typedefs_1.html create mode 100644 docs/html/search/typedefs_1.js create mode 100644 docs/html/search/typedefs_2.html create mode 100644 docs/html/search/typedefs_2.js create mode 100644 docs/html/search/typedefs_3.html create mode 100644 docs/html/search/typedefs_3.js create mode 100644 docs/html/search/typedefs_4.html create mode 100644 docs/html/search/typedefs_4.js create mode 100644 docs/html/search/typedefs_5.html create mode 100644 docs/html/search/typedefs_5.js create mode 100644 docs/html/search/typedefs_6.html create mode 100644 docs/html/search/typedefs_6.js create mode 100644 docs/html/search/typedefs_7.html create mode 100644 docs/html/search/typedefs_7.js create mode 100644 docs/html/search/typedefs_8.html create mode 100644 docs/html/search/typedefs_8.js create mode 100644 docs/html/search/typedefs_9.html create mode 100644 docs/html/search/typedefs_9.js create mode 100644 docs/html/search/variables_10.html create mode 100644 docs/html/search/variables_10.js create mode 100644 docs/html/search/variables_11.html create mode 100644 docs/html/search/variables_11.js create mode 100644 docs/html/search/variables_12.html create mode 100644 docs/html/search/variables_12.js create mode 100644 docs/html/search/variables_13.html create mode 100644 docs/html/search/variables_13.js create mode 100644 docs/html/search/variables_14.html create mode 100644 docs/html/search/variables_14.js create mode 100644 docs/html/search/variables_15.html create mode 100644 docs/html/search/variables_15.js create mode 100644 docs/html/search/variables_16.html create mode 100644 docs/html/search/variables_16.js create mode 100644 docs/html/search/variables_17.html create mode 100644 docs/html/search/variables_17.js create mode 100644 docs/html/search/variables_18.html create mode 100644 docs/html/search/variables_18.js create mode 100644 docs/html/search/variables_19.html create mode 100644 docs/html/search/variables_19.js create mode 100644 docs/html/search/variables_d.html create mode 100644 docs/html/search/variables_d.js create mode 100644 docs/html/search/variables_e.html create mode 100644 docs/html/search/variables_e.js create mode 100644 docs/html/search/variables_f.html create mode 100644 docs/html/search/variables_f.js create mode 100644 docs/html/selection_8h.html create mode 100644 docs/html/sequence_8cpp.html create mode 100644 docs/html/sequence_8h.html create mode 100644 docs/html/shakeeffect_8cpp.html create mode 100644 docs/html/shakeeffect_8h.html create mode 100644 docs/html/solideffect_8cpp.html create mode 100644 docs/html/solideffect_8h.html create mode 100644 docs/html/sourceiconview_8cpp.html create mode 100644 docs/html/sourceiconview_8h.html create mode 100644 docs/html/sourcescommon_8cpp.html create mode 100644 docs/html/sourcescommon_8h.html create mode 100644 docs/html/sourcetable_8cpp.html create mode 100644 docs/html/sourcetable_8h.html create mode 100644 docs/html/speeddialog_8cpp.html create mode 100644 docs/html/speeddialog_8h.html create mode 100644 docs/html/struct_timeline_track_height-members.html create mode 100644 docs/html/struct_timeline_track_height.html create mode 100644 docs/html/texteditdialog_8cpp.html create mode 100644 docs/html/texteditdialog_8h.html create mode 100644 docs/html/texteditex_8cpp.html create mode 100644 docs/html/texteditex_8h.html create mode 100644 docs/html/texteffect_8cpp.html create mode 100644 docs/html/texteffect_8h.html create mode 100644 docs/html/timecodeeffect_8cpp.html create mode 100644 docs/html/timecodeeffect_8h.html create mode 100644 docs/html/timeline_8cpp.html create mode 100644 docs/html/timeline_8h.html create mode 100644 docs/html/timelineheader_8cpp.html create mode 100644 docs/html/timelineheader_8h.html create mode 100644 docs/html/timelinetools_8h.html create mode 100644 docs/html/timelinewidget_8cpp.html create mode 100644 docs/html/timelinewidget_8h.html create mode 100644 docs/html/toneeffect_8cpp.html create mode 100644 docs/html/toneeffect_8h.html create mode 100644 docs/html/transformeffect_8cpp.html create mode 100644 docs/html/transformeffect_8h.html create mode 100644 docs/html/transition_8cpp.html create mode 100644 docs/html/transition_8h.html create mode 100644 docs/html/undo_8cpp.html create mode 100644 docs/html/undo_8h.html create mode 100644 docs/html/version_8h.html create mode 100644 docs/html/vestige_8h.html create mode 100644 docs/html/viewer_8cpp.html create mode 100644 docs/html/viewer_8h.html create mode 100644 docs/html/viewercontainer_8cpp.html create mode 100644 docs/html/viewercontainer_8h.html create mode 100644 docs/html/viewerwidget_8cpp.html create mode 100644 docs/html/viewerwidget_8h.html create mode 100644 docs/html/viewerwindow_8cpp.html create mode 100644 docs/html/viewerwindow_8h.html create mode 100644 docs/html/voideffect_8cpp.html create mode 100644 docs/html/voideffect_8h.html create mode 100644 docs/html/volumeeffect_8cpp.html create mode 100644 docs/html/volumeeffect_8h.html create mode 100644 docs/html/vsthost_8cpp.html create mode 100644 docs/html/vsthost_8h.html diff --git a/Doxyfile b/Doxyfile index eab2bc788..c717922fd 100644 --- a/Doxyfile +++ b/Doxyfile @@ -897,8 +897,7 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = docs\ - .git +EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -914,7 +913,8 @@ EXCLUDE_SYMLINKS = NO # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = */.git/* \ + */docs/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the diff --git a/docs/doxygen_objdb_3636.tmp b/docs/doxygen_objdb_3636.tmp new file mode 100644 index 000000000..e69de29bb diff --git a/docs/html/_i_s_s_u_e___t_e_m_p_l_a_t_e_8md.html b/docs/html/_i_s_s_u_e___t_e_m_p_l_a_t_e_8md.html new file mode 100644 index 000000000..c40edbe5a --- /dev/null +++ b/docs/html/_i_s_s_u_e___t_e_m_p_l_a_t_e_8md.html @@ -0,0 +1,76 @@ + + + + + + + +Olive: ISSUE_TEMPLATE.md File Reference + + + + + + + + + +
+
+ + + + + + +
+
Olive +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
ISSUE_TEMPLATE.md File Reference
+
+
+
+ + + + diff --git a/docs/html/_r_e_a_d_m_e_8md.html b/docs/html/_r_e_a_d_m_e_8md.html new file mode 100644 index 000000000..07f293455 --- /dev/null +++ b/docs/html/_r_e_a_d_m_e_8md.html @@ -0,0 +1,76 @@ + + + + + + + +Olive: README.md File Reference + + + + + + + + + +
+
+ + + + + + +
+
Olive +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
README.md File Reference
+
+
+
+ + + + diff --git a/docs/html/aboutdialog_8cpp.html b/docs/html/aboutdialog_8cpp.html new file mode 100644 index 000000000..bcb58a694 --- /dev/null +++ b/docs/html/aboutdialog_8cpp.html @@ -0,0 +1,84 @@ + + + + + + + +Olive: dialogs/aboutdialog.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
Olive +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
aboutdialog.cpp File Reference
+
+
+
#include "aboutdialog.h"
+#include <QVBoxLayout>
+#include <QLabel>
+#include <QDialogButtonBox>
+
+ + + + diff --git a/docs/html/aboutdialog_8h.html b/docs/html/aboutdialog_8h.html new file mode 100644 index 000000000..6416325af --- /dev/null +++ b/docs/html/aboutdialog_8h.html @@ -0,0 +1,91 @@ + + + + + + + +Olive: dialogs/aboutdialog.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
Olive +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
aboutdialog.h File Reference
+
+
+
#include <QDialog>
+
+

Go to the source code of this file.

+ + + + +

+Classes

class  AboutDialog
 
+
+ + + + diff --git a/docs/html/aboutdialog_8h_source.html b/docs/html/aboutdialog_8h_source.html index 1311a3b4b..7e4eda9bd 100644 --- a/docs/html/aboutdialog_8h_source.html +++ b/docs/html/aboutdialog_8h_source.html @@ -69,7 +69,8 @@ $(function() {
aboutdialog.h
-
1 /***
2 
3  Olive - Non-Linear Video Editor
4  Copyright (C) 2019 Olive Team
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 ***/
20 
21 #ifndef ABOUTDIALOG_H
22 #define ABOUTDIALOG_H
23 
24 #include <QDialog>
25 
26 class AboutDialog : public QDialog
27 {
28  Q_OBJECT
29 
30 public:
31  explicit AboutDialog(QWidget *parent = 0);
32 };
33 
34 #endif // ABOUTDIALOG_H
Definition: aboutdialog.h:26
+Go to the documentation of this file.
1 /***
2 
3  Olive - Non-Linear Video Editor
4  Copyright (C) 2019 Olive Team
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 ***/
20 
21 #ifndef ABOUTDIALOG_H
22 #define ABOUTDIALOG_H
23 
24 #include <QDialog>
25 
26 class AboutDialog : public QDialog
27 {
28  Q_OBJECT
29 
30 public:
31  explicit AboutDialog(QWidget *parent = 0);
32 };
33 
34 #endif // ABOUTDIALOG_H
AboutDialog(QWidget *parent=0)
Definition: aboutdialog.cpp:27
+
Definition: aboutdialog.h:26
-
1 /***
2 
3  Olive - Non-Linear Video Editor
4  Copyright (C) 2019 Olive Team
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 ***/
20 
21 #ifndef ACTIONSEARCH_H
22 #define ACTIONSEARCH_H
23 
24 #include <QDialog>
25 #include <QLineEdit>
26 #include <QListWidget>
27 
28 class QListWidget;
29 class QMenu;
30 
31 class ActionSearchList : public QListWidget {
32  Q_OBJECT
33 public:
34  ActionSearchList(QWidget* parent);
35 protected:
36  void mouseDoubleClickEvent(QMouseEvent *event);
37 signals:
38  void dbl_click();
39 };
40 
41 class ActionSearch : public QDialog
42 {
43  Q_OBJECT
44 public:
45  ActionSearch(QWidget* parent = nullptr);
46 private slots:
47  void search_update(const QString& s, const QString &p = nullptr, QMenu *parent = nullptr);
48  void perform_action();
49  void move_selection_up();
50  void move_selection_down();
51 private:
52  ActionSearchList* list_widget;
53 };
54 
55 class ActionSearchEntry : public QLineEdit {
56  Q_OBJECT
57 public:
58  ActionSearchEntry(QWidget* parent);
59 protected:
60  void keyPressEvent(QKeyEvent * event);
61 signals:
62  void moveSelectionUp();
63  void moveSelectionDown();
64 };
65 
66 #endif // ACTIONSEARCH_H
Definition: actionsearch.h:31
-
Definition: actionsearch.h:41
-
Definition: actionsearch.h:55
+Go to the documentation of this file.
1 /***
2 
3  Olive - Non-Linear Video Editor
4  Copyright (C) 2019 Olive Team
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 ***/
20 
21 #ifndef ACTIONSEARCH_H
22 #define ACTIONSEARCH_H
23 
24 #include <QDialog>
25 #include <QLineEdit>
26 #include <QListWidget>
27 #include <QMenu>
28 
29 class ActionSearchList : public QListWidget {
30  Q_OBJECT
31 public:
32  ActionSearchList(QWidget* parent);
33 protected:
34  void mouseDoubleClickEvent(QMouseEvent *event);
35 signals:
36  void dbl_click();
37 };
38 
39 class ActionSearch : public QDialog
40 {
41  Q_OBJECT
42 public:
43  ActionSearch(QWidget* parent = nullptr);
44 private slots:
45  void search_update(const QString& s, const QString &p = nullptr, QMenu *parent = nullptr);
46  void perform_action();
47  void move_selection_up();
48  void move_selection_down();
49 private:
51 };
52 
53 class ActionSearchEntry : public QLineEdit {
54  Q_OBJECT
55 public:
56  ActionSearchEntry(QWidget* parent);
57 protected:
58  void keyPressEvent(QKeyEvent * event);
59 signals:
60  void moveSelectionUp();
61  void moveSelectionDown();
62 };
63 
64 #endif // ACTIONSEARCH_H
ActionSearchList * list_widget
Definition: actionsearch.h:50
+
Definition: actionsearch.h:29
+
void keyPressEvent(QKeyEvent *event)
Definition: actionsearch.cpp:130
+
ActionSearchEntry(QWidget *parent)
Definition: actionsearch.cpp:128
+
void moveSelectionDown()
+
void move_selection_down()
Definition: actionsearch.cpp:117
+ +
void mouseDoubleClickEvent(QMouseEvent *event)
Definition: actionsearch.cpp:145
+
void search_update(const QString &s, const QString &p=nullptr, QMenu *parent=nullptr)
Definition: actionsearch.cpp:63
+
Definition: actionsearch.h:39
+
void moveSelectionUp()
+
ActionSearchList(QWidget *parent)
Definition: actionsearch.cpp:143
+
void perform_action()
Definition: actionsearch.cpp:96
+
ActionSearch(QWidget *parent=nullptr)
Definition: actionsearch.cpp:30
+
Definition: actionsearch.h:53
+
void move_selection_up()
Definition: actionsearch.cpp:106
-
1 /***
2 
3  Olive - Non-Linear Video Editor
4  Copyright (C) 2019 Olive Team
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 ***/
20 
21 #ifndef ADVANCEDVIDEODIALOG_H
22 #define ADVANCEDVIDEODIALOG_H
23 
24 #include <QDialog>
25 
26 #include "io/exportthread.h"
27 
28 class QComboBox;
29 
30 class AdvancedVideoDialog : public QDialog {
31  Q_OBJECT
32 public:
33  AdvancedVideoDialog(QWidget* parent,
34  int encoding_codec,
35  VideoCodecParams& iparams);
36 
37 public slots:
38  virtual void accept() override;
39 private:
40  VideoCodecParams& params;
41 
42  QComboBox* pix_fmt_combo;
43 };
44 
45 #endif // ADVANCEDVIDEODIALOG_H
Definition: advancedvideodialog.h:30
-
Definition: exportthread.h:68
+Go to the documentation of this file.
1 /***
2 
3  Olive - Non-Linear Video Editor
4  Copyright (C) 2019 Olive Team
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 ***/
20 
21 #ifndef ADVANCEDVIDEODIALOG_H
22 #define ADVANCEDVIDEODIALOG_H
23 
24 #include <QDialog>
25 #include <QComboBox>
26 
27 #include "io/exportthread.h"
28 
29 class AdvancedVideoDialog : public QDialog {
30  Q_OBJECT
31 public:
32  AdvancedVideoDialog(QWidget* parent,
33  int encoding_codec,
34  VideoCodecParams& iparams);
35 
36 public slots:
37  virtual void accept() override;
38 private:
40 
41  QComboBox* pix_fmt_combo;
42 };
43 
44 #endif // ADVANCEDVIDEODIALOG_H
VideoCodecParams & params
Definition: advancedvideodialog.h:39
+
Definition: advancedvideodialog.h:29
+ +
Definition: exportthread.h:67
+
AdvancedVideoDialog(QWidget *parent, int encoding_codec, VideoCodecParams &iparams)
Definition: advancedvideodialog.cpp:35
+
QComboBox * pix_fmt_combo
Definition: advancedvideodialog.h:41
+
virtual void accept() override
Definition: advancedvideodialog.cpp:84
-
1 /***
2 
3  Olive - Non-Linear Video Editor
4  Copyright (C) 2019 Olive Team
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 ***/
20 
21 #ifndef AUDIO_H
22 #define AUDIO_H
23 
24 #include <QVector>
25 #include <QThread>
26 #include <QWaitCondition>
27 #include <QMutex>
28 
29 //#define INT16_MAX 0x7fff
30 //#define INT16_MIN (-INT16_MAX-1)
31 
32 class QIODevice;
33 class QAudioOutput;
34 class QComboBox;
35 
36 struct Sequence;
37 
38 class AudioSenderThread : public QThread {
39  Q_OBJECT
40 public:
42  void run();
43  void stop();
44  QWaitCondition cond;
45  bool close;
46  QMutex lock;
47 public slots:
48  void notifyReceiver();
49 private:
50  QVector<qint16> samples;
51  int send_audio_to_output(qint64 offset, int max);
52 };
53 
54 double log_volume(double linear);
55 
56 extern QAudioOutput* audio_output;
57 extern QIODevice* audio_io_device;
58 extern AudioSenderThread* audio_thread;
59 extern QMutex audio_write_lock;
60 
61 #define audio_ibuffer_size 192000
62 extern qint8 audio_ibuffer[audio_ibuffer_size];
63 extern qint64 audio_ibuffer_read;
64 extern long audio_ibuffer_frame;
65 extern double audio_ibuffer_timecode;
66 extern bool audio_scrub;
67 extern bool recording;
68 extern bool audio_rendering;
69 void clear_audio_ibuffer();
70 
71 int current_audio_freq();
72 
73 bool is_audio_device_set();
74 
75 void init_audio();
76 void stop_audio();
77 qint64 get_buffer_offset_from_frame(double framerate, long frame);
78 
79 bool start_recording();
80 void stop_recording();
81 QString get_recorded_audio_filename();
82 
83 void combobox_audio_sample_rates(QComboBox* combobox);
84 
85 #endif // AUDIO_H
Definition: sequence.h:33
-
Definition: audio.h:38
+Go to the documentation of this file.
1 /***
2 
3  Olive - Non-Linear Video Editor
4  Copyright (C) 2019 Olive Team
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 ***/
20 
21 #ifndef AUDIO_H
22 #define AUDIO_H
23 
24 #include <QVector>
25 #include <QThread>
26 #include <QWaitCondition>
27 #include <QMutex>
28 #include <QIODevice>
29 #include <QAudioOutput>
30 #include <QComboBox>
31 
32 #include "project/sequence.h"
33 
34 class AudioSenderThread : public QThread {
35  Q_OBJECT
36 public:
38  void run();
39  void stop();
40  QWaitCondition cond;
41  bool close;
42  QMutex lock;
43 public slots:
44  void notifyReceiver();
45 private:
46  QVector<qint16> samples;
47  int send_audio_to_output(qint64 offset, int max);
48 };
49 
50 double log_volume(double linear);
51 
52 extern QAudioOutput* audio_output;
53 extern QIODevice* audio_io_device;
55 extern QMutex audio_write_lock;
56 
57 #define audio_ibuffer_size 192000
58 extern qint8 audio_ibuffer[audio_ibuffer_size];
59 extern qint64 audio_ibuffer_read;
60 extern long audio_ibuffer_frame;
61 extern double audio_ibuffer_timecode;
62 extern bool audio_scrub;
63 extern bool recording;
64 extern bool audio_rendering;
65 void clear_audio_ibuffer();
66 
67 int current_audio_freq();
68 
69 bool is_audio_device_set();
70 
71 void init_audio();
72 void stop_audio();
73 qint64 get_buffer_offset_from_frame(double framerate, long frame);
74 
75 bool start_recording();
76 void stop_recording();
78 
79 void combobox_audio_sample_rates(QComboBox* combobox);
80 
81 #endif // AUDIO_H
QMutex audio_write_lock
Definition: audio.cpp:50
+
QIODevice * audio_io_device
Definition: audio.cpp:47
+
void stop_recording()
Definition: audio.cpp:375
+
qint64 get_buffer_offset_from_frame(double framerate, long frame)
Definition: audio.cpp:158
+ +
void stop()
Definition: audio.cpp:172
+
void stop_audio()
Definition: audio.cpp:135
+
int current_audio_freq()
Definition: audio.cpp:154
+
void init_audio()
Definition: audio.cpp:96
+
QAudioOutput * audio_output
Definition: audio.cpp:46
+
AudioSenderThread * audio_thread
Definition: audio.cpp:61
+
#define audio_ibuffer_size
Definition: audio.h:57
+
double audio_ibuffer_timecode
Definition: audio.cpp:59
+
double log_volume(double linear)
Definition: audio.cpp:244
+
void run()
Definition: audio.cpp:182
+
void combobox_audio_sample_rates(QComboBox *combobox)
Definition: audio.cpp:393
+
qint8 audio_ibuffer[audio_ibuffer_size]
Definition: audio.cpp:56
+
int send_audio_to_output(qint64 offset, int max)
Definition: audio.cpp:209
+
QWaitCondition cond
Definition: audio.h:40
+
QVector< qint16 > samples
Definition: audio.h:46
+
Definition: audio.h:34
+
void clear_audio_ibuffer()
Definition: audio.cpp:145
+
bool close
Definition: audio.h:41
+
long audio_ibuffer_frame
Definition: audio.cpp:58
+
bool start_recording()
Definition: audio.cpp:325
+
QMutex lock
Definition: audio.h:42
+
bool audio_scrub
Definition: audio.cpp:49
+
QString get_recorded_audio_filename()
Definition: audio.cpp:389
+
bool is_audio_device_set()
Definition: audio.cpp:63
+
qint64 audio_ibuffer_read
Definition: audio.cpp:57
+
void notifyReceiver()
Definition: audio.cpp:178
+
bool audio_rendering
Definition: audio.cpp:53
+
bool recording
Definition: audio.cpp:54
+
AudioSenderThread()
Definition: audio.cpp:168
-
1 /***
2 
3  Olive - Non-Linear Video Editor
4  Copyright (C) 2019 Olive Team
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 ***/
20 
21 #ifndef AUDIOMONITOR_H
22 #define AUDIOMONITOR_H
23 
24 #include <QWidget>
25 #include <QTimer>
26 
27 class AudioMonitor : public QWidget
28 {
29  Q_OBJECT
30 public:
31  explicit AudioMonitor(QWidget *parent = 0);
32  void set_value(const QVector<double>& values);
33 
34 protected:
35  void paintEvent(QPaintEvent *);
36  void resizeEvent(QResizeEvent *);
37 
38 signals:
39 
40 public slots:
41 
42 private:
43  QLinearGradient gradient;
44  QVector<double> values;
45  QTimer clear_timer;
46 
47 private slots:
48  void clear();
49 };
50 
51 #endif // AUDIOMONITOR_H
Definition: audiomonitor.h:27
+Go to the documentation of this file.
1 /***
2 
3  Olive - Non-Linear Video Editor
4  Copyright (C) 2019 Olive Team
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 ***/
20 
21 #ifndef AUDIOMONITOR_H
22 #define AUDIOMONITOR_H
23 
24 #include <QWidget>
25 #include <QTimer>
26 
27 class AudioMonitor : public QWidget
28 {
29  Q_OBJECT
30 public:
31  explicit AudioMonitor(QWidget *parent = 0);
32  void set_value(const QVector<double>& values);
33 
34 protected:
35  void paintEvent(QPaintEvent *);
36  void resizeEvent(QResizeEvent *);
37 
38 signals:
39 
40 public slots:
41 
42 private:
43  QLinearGradient gradient;
44  QVector<double> values;
45  QTimer clear_timer;
46 
47 private slots:
48  void clear();
49 };
50 
51 #endif // AUDIOMONITOR_H
QTimer clear_timer
Definition: audiomonitor.h:45
+
Definition: audiomonitor.h:27
+
QLinearGradient gradient
Definition: audiomonitor.h:43
+
AudioMonitor(QWidget *parent=0)
Definition: audiomonitor.cpp:41
+
void clear()
Definition: audiomonitor.cpp:55
+
void paintEvent(QPaintEvent *)
Definition: audiomonitor.cpp:70
+
void resizeEvent(QResizeEvent *)
Definition: audiomonitor.cpp:62
+
QVector< double > values
Definition: audiomonitor.h:44
+
void set_value(const QVector< double > &values)
Definition: audiomonitor.cpp:48
-
1 /***
2 
3  Olive - Non-Linear Video Editor
4  Copyright (C) 2019 Olive Team
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 ***/
20 
21 #ifndef AUDIONOISEEFFECT_H
22 #define AUDIONOISEEFFECT_H
23 
24 #include "project/effect.h"
25 
26 class AudioNoiseEffect : public Effect {
27  Q_OBJECT
28 public:
29  AudioNoiseEffect(Clip* c, const EffectMeta* em);
30  void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count);
31 
32  EffectField* amount_val;
33  EffectField* mix_val;
34 };
35 
36 #endif // AUDIONOISEEFFECT_H
Definition: effect.h:166
-
Definition: effect.h:47
+Go to the documentation of this file.
1 /***
2 
3  Olive - Non-Linear Video Editor
4  Copyright (C) 2019 Olive Team
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 ***/
20 
21 #ifndef AUDIONOISEEFFECT_H
22 #define AUDIONOISEEFFECT_H
23 
24 #include "project/effect.h"
25 
26 class AudioNoiseEffect : public Effect {
27  Q_OBJECT
28 public:
29  AudioNoiseEffect(ClipPtr c, const EffectMeta* em);
30  void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count);
31 
34 };
35 
36 #endif // AUDIONOISEEFFECT_H
AudioNoiseEffect(ClipPtr c, const EffectMeta *em)
Definition: audionoiseeffect.cpp:26
+
Definition: effect.h:169
+ +
Definition: effect.h:50
+
EffectField * mix_val
Definition: audionoiseeffect.h:33
+
std::shared_ptr< Clip > ClipPtr
Definition: cacher.h:28
+
EffectField * amount_val
Definition: audionoiseeffect.h:32
Definition: audionoiseeffect.h:26
-
Definition: clip.h:53
+
void process_audio(double timecode_start, double timecode_end, quint8 *samples, int nb_bytes, int channel_count)
Definition: audionoiseeffect.cpp:38
Definition: effectfield.h:43
diff --git a/docs/html/cacher_8cpp.html b/docs/html/cacher_8cpp.html new file mode 100644 index 000000000..a0a4544be --- /dev/null +++ b/docs/html/cacher_8cpp.html @@ -0,0 +1,443 @@ + + + + + + + +Olive: playback/cacher.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
Olive +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
cacher.cpp File Reference
+
+
+
#include "cacher.h"
+#include "project/clip.h"
+#include "project/sequence.h"
+#include "project/transition.h"
+#include "project/footage.h"
+#include "playback/audio.h"
+#include "playback/playback.h"
+#include "project/effect.h"
+#include "panels/timeline.h"
+#include "panels/project.h"
+#include "panels/panels.h"
+#include "panels/viewer.h"
+#include "project/media.h"
+#include "io/config.h"
+#include "debug.h"
+#include <libavformat/avformat.h>
+#include <libavcodec/avcodec.h>
+#include <libswscale/swscale.h>
+#include <libswresample/swresample.h>
+#include <libavfilter/avfilter.h>
+#include <libavfilter/buffersrc.h>
+#include <libavfilter/buffersink.h>
+#include <libavutil/opt.h>
+#include <libavutil/pixdesc.h>
+#include <QOpenGLFramebufferObject>
+#include <QtMath>
+#include <QAudioOutput>
+#include <math.h>
+
+ + + +

+Macros

#define AUDIO_BUFFER_PADDING   2048
 
+ + + + + + + + + + + + + + + + + +

+Functions

double bytes_to_seconds (int nb_bytes, int nb_channels, int sample_rate)
 
void apply_audio_effects (ClipPtr c, double timecode_start, AVFrame *frame, int nb_bytes, QVector< ClipPtr > nests)
 
void cache_audio_worker (ClipPtr c, bool scrubbing, QVector< ClipPtr > &nests, int playback_speed)
 
void cache_video_worker (ClipPtr c, long playhead)
 
void reset_cache (ClipPtr c, long target_frame, int playback_speed)
 
void open_clip_worker (ClipPtr clip)
 
void cache_clip_worker (ClipPtr clip, long playhead, bool reset, bool scrubbing, QVector< ClipPtr > nests, int playback_speed)
 
void close_clip_worker (ClipPtr clip)
 
+ + + +

+Variables

AVSampleFormat sample_format = AV_SAMPLE_FMT_S16
 
+

Macro Definition Documentation

+ +

◆ AUDIO_BUFFER_PADDING

+ +
+
+ + + + +
#define AUDIO_BUFFER_PADDING   2048
+
+ +
+
+

Function Documentation

+ +

◆ apply_audio_effects()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void apply_audio_effects (ClipPtr c,
double timecode_start,
AVFrame * frame,
int nb_bytes,
QVector< ClipPtrnests 
)
+
+ +
+
+ +

◆ bytes_to_seconds()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
double bytes_to_seconds (int nb_bytes,
int nb_channels,
int sample_rate 
)
+
+ +
+
+ +

◆ cache_audio_worker()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void cache_audio_worker (ClipPtr c,
bool scrubbing,
QVector< ClipPtr > & nests,
int playback_speed 
)
+
+ +
+
+ +

◆ cache_clip_worker()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void cache_clip_worker (ClipPtr clip,
long playhead,
bool reset,
bool scrubbing,
QVector< ClipPtrnests,
int playback_speed 
)
+
+ +
+
+ +

◆ cache_video_worker()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void cache_video_worker (ClipPtr c,
long playhead 
)
+
+ +
+
+ +

◆ close_clip_worker()

+ +
+
+ + + + + + + + +
void close_clip_worker (ClipPtr clip)
+
+ +
+
+ +

◆ open_clip_worker()

+ +
+
+ + + + + + + + +
void open_clip_worker (ClipPtr clip)
+
+ +
+
+ +

◆ reset_cache()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void reset_cache (ClipPtr c,
long target_frame,
int playback_speed 
)
+
+ +
+
+

Variable Documentation

+ +

◆ sample_format

+ +
+
+ + + + +
AVSampleFormat sample_format = AV_SAMPLE_FMT_S16
+
+ +
+
+
+ + + + diff --git a/docs/html/cacher_8h.html b/docs/html/cacher_8h.html new file mode 100644 index 000000000..64230e3b2 --- /dev/null +++ b/docs/html/cacher_8h.html @@ -0,0 +1,212 @@ + + + + + + + +Olive: playback/cacher.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
Olive +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
cacher.h File Reference
+
+
+
#include <QThread>
+#include <QVector>
+
+

Go to the source code of this file.

+ + + + +

+Classes

class  Cacher
 
+ + + +

+Typedefs

using ClipPtr = std::shared_ptr< Clip >
 
+ + + + + + + +

+Functions

void open_clip_worker (ClipPtr clip)
 
void cache_clip_worker (ClipPtr clip, long playhead, bool reset, bool scrubbing, QVector< ClipPtr > nest, int playback_speed)
 
void close_clip_worker (ClipPtr clip)
 
+

Typedef Documentation

+ +

◆ ClipPtr

+ +
+
+ + + + +
using ClipPtr = std::shared_ptr<Clip>
+
+ +
+
+

Function Documentation

+ +

◆ cache_clip_worker()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void cache_clip_worker (ClipPtr clip,
long playhead,
bool reset,
bool scrubbing,
QVector< ClipPtrnest,
int playback_speed 
)
+
+ +
+
+ +

◆ close_clip_worker()

+ +
+
+ + + + + + + + +
void close_clip_worker (ClipPtr clip)
+
+ +
+
+ +

◆ open_clip_worker()

+ +
+
+ + + + + + + + +
void open_clip_worker (ClipPtr clip)
+
+ +
+
+
+ + + + diff --git a/docs/html/cacher_8h_source.html b/docs/html/cacher_8h_source.html index 0d89f9fcc..ecb5e9a40 100644 --- a/docs/html/cacher_8h_source.html +++ b/docs/html/cacher_8h_source.html @@ -69,8 +69,23 @@ $(function() {
cacher.h
-
1 /***
2 
3  Olive - Non-Linear Video Editor
4  Copyright (C) 2019 Olive Team
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 ***/
20 
21 #ifndef CACHER_H
22 #define CACHER_H
23 
24 #include <QThread>
25 #include <QVector>
26 
27 class Clip;
28 
29 class Cacher : public QThread
30 {
31 // Q_OBJECT
32 public:
33  Cacher(Clip* c);
34  void run();
35 
36  bool caching;
37 
38  // must be set before caching
39  long playhead;
40  bool reset;
41  bool scrubbing;
42  bool interrupt;
43  bool queued;
44  int playback_speed;
45  QVector<Clip*> nests;
46 
47 private:
48  Clip* clip;
49 };
50 
51 void open_clip_worker(Clip* clip);
52 void cache_clip_worker(Clip* clip, long playhead, bool reset, bool scrubbing, QVector<Clip *> nest, int playback_speed);
53 void close_clip_worker(Clip* clip);
54 
55 #endif // CACHER_H
Definition: cacher.h:29
-
Definition: clip.h:53
+Go to the documentation of this file.
1 /***
2 
3  Olive - Non-Linear Video Editor
4  Copyright (C) 2019 Olive Team
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 ***/
20 
21 #ifndef CACHER_H
22 #define CACHER_H
23 
24 #include <QThread>
25 #include <QVector>
26 
27 class Clip;
28 using ClipPtr = std::shared_ptr<Clip>;
29 
30 class Cacher : public QThread
31 {
32 // Q_OBJECT
33 public:
34  Cacher(ClipPtr c);
35  void run();
36 
37  bool caching;
38 
39  // must be set before caching
40  long playhead;
41  bool reset;
42  bool scrubbing;
43  bool interrupt;
44  bool queued;
46  QVector<ClipPtr> nests;
47 
48 private:
50 };
51 
52 void open_clip_worker(ClipPtr clip);
53 void cache_clip_worker(ClipPtr clip, long playhead, bool reset, bool scrubbing, QVector<ClipPtr> nest, int playback_speed);
54 void close_clip_worker(ClipPtr clip);
55 
56 #endif // CACHER_H
long playhead
Definition: cacher.h:40
+
bool caching
Definition: cacher.h:37
+
bool interrupt
Definition: cacher.h:43
+
bool reset
Definition: cacher.h:41
+
Definition: cacher.h:30
+
Cacher(ClipPtr c)
Definition: cacher.cpp:674
+
std::shared_ptr< Clip > ClipPtr
Definition: cacher.h:28
+
void run()
Definition: cacher.cpp:993
+
int playback_speed
Definition: cacher.h:45
+
QVector< ClipPtr > nests
Definition: cacher.h:46
+
ClipPtr clip
Definition: cacher.h:49
+
void open_clip_worker(ClipPtr clip)
Definition: cacher.cpp:678
+
void close_clip_worker(ClipPtr clip)
Definition: cacher.cpp:970
+
bool scrubbing
Definition: cacher.h:42
+
Definition: clip.h:50
+
bool queued
Definition: cacher.h:44
+
void cache_clip_worker(ClipPtr clip, long playhead, bool reset, bool scrubbing, QVector< ClipPtr > nest, int playback_speed)
Definition: cacher.cpp:950
-
1 /***
2 
3  Olive - Non-Linear Video Editor
4  Copyright (C) 2019 Olive Team
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 ***/
20 
21 #ifndef CHECKBOXEX_H
22 #define CHECKBOXEX_H
23 
24 #include <QCheckBox>
25 
26 class CheckboxEx : public QCheckBox
27 {
28  Q_OBJECT
29 public:
30  CheckboxEx(QWidget* parent = 0);
31 private slots:
32  void checkbox_command();
33 };
34 
35 #endif // CHECKBOXEX_H
Definition: checkboxex.h:26
+Go to the documentation of this file.
1 /***
2 
3  Olive - Non-Linear Video Editor
4  Copyright (C) 2019 Olive Team
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 ***/
20 
21 #ifndef CHECKBOXEX_H
22 #define CHECKBOXEX_H
23 
24 #include <QCheckBox>
25 
26 class CheckboxEx : public QCheckBox
27 {
28  Q_OBJECT
29 public:
30  CheckboxEx(QWidget* parent = 0);
31 private slots:
32  void checkbox_command();
33 };
34 
35 #endif // CHECKBOXEX_H
CheckboxEx(QWidget *parent=0)
Definition: checkboxex.cpp:25
+
Definition: checkboxex.h:26
+
void checkbox_command()
Definition: checkboxex.cpp:29