diff --git a/io/media.h b/io/media.h
index 1e7de7cc3..dd9a585be 100644
--- a/io/media.h
+++ b/io/media.h
@@ -15,7 +15,10 @@ struct MediaStream {
int video_width;
int video_height;
bool infinite_length;
+ double video_frame_rate;
int audio_channels;
+ int audio_layout;
+ int audio_frequency;
// preview thumbnail/waveform
bool preview_done;
diff --git a/io/previewgenerator.cpp b/io/previewgenerator.cpp
index 2804adced..7cd068b5a 100644
--- a/io/previewgenerator.cpp
+++ b/io/previewgenerator.cpp
@@ -35,10 +35,13 @@ void PreviewGenerator::parse_media() {
bool infinite_length = (fmt_ctx->streams[i]->avg_frame_rate.den == 0);
ms->video_width = fmt_ctx->streams[i]->codecpar->width;
ms->video_height = fmt_ctx->streams[i]->codecpar->height;
+ ms->video_frame_rate = (infinite_length) ? 0 : av_q2d(fmt_ctx->streams[i]->avg_frame_rate);
ms->infinite_length = infinite_length;
media->video_tracks.append(ms);
} else if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
ms->audio_channels = fmt_ctx->streams[i]->codecpar->channels;
+ ms->audio_layout = fmt_ctx->streams[i]->codecpar->channel_layout;
+ ms->audio_frequency = fmt_ctx->streams[i]->codecpar->sample_rate;
media->audio_tracks.append(ms);
}
}
diff --git a/mainwindow.cpp b/mainwindow.cpp
index f352db73d..0957eaacb 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -110,7 +110,7 @@ MainWindow::MainWindow(QWidget *parent) :
panel_project->load_project();
}
}
- autorecovery_timer.setInterval(10000);
+ autorecovery_timer.setInterval(60000);
QObject::connect(&autorecovery_timer, SIGNAL(timeout()), this, SLOT(autorecover_interval()));
autorecovery_timer.start();
diff --git a/mainwindow.ui b/mainwindow.ui
index 0d74dc1fa..8f49bb0ca 100644
--- a/mainwindow.ui
+++ b/mainwindow.ui
@@ -215,7 +215,7 @@
&Redo
- Ctrl+Y
+ Ctrl+Shift+Z, Ctrl+Y
diff --git a/panels/timeline.cpp b/panels/timeline.cpp
index 391dd4ed1..28a7245b5 100644
--- a/panels/timeline.cpp
+++ b/panels/timeline.cpp
@@ -214,8 +214,8 @@ void Timeline::update_sequence() {
ui->pushButton_4->setEnabled(!null_sequence);
ui->pushButton_5->setEnabled(!null_sequence);
ui->headers->setEnabled(!null_sequence);
- ui->video_area->setEnabled(!null_sequence);
- ui->audio_area->setEnabled(!null_sequence);
+// ui->video_area->setEnabled(!null_sequence);
+// ui->audio_area->setEnabled(!null_sequence);
if (null_sequence) {
setWindowTitle("Timeline: ");
diff --git a/project/sequence.h b/project/sequence.h
index a74fce107..408b68e10 100644
--- a/project/sequence.h
+++ b/project/sequence.h
@@ -20,7 +20,7 @@ public:
long getEndFrame();
int width;
int height;
- float frame_rate;
+ double frame_rate;
int audio_frequency;
int audio_layout;
private:
diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp
index fec5a125e..b1503d98b 100644
--- a/ui/timelinewidget.cpp
+++ b/ui/timelinewidget.cpp
@@ -55,12 +55,61 @@ void TimelineWidget::resizeEvent(QResizeEvent*) {
void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
if (event->source() == panel_project->source_table) {
event->accept();
- QPoint pos = event->pos();
- QList items = panel_project->source_table->selectedItems();
- long entry_point = panel_timeline->getFrameFromScreenPoint(pos.x());
- panel_timeline->drag_frame_start = entry_point + panel_timeline->getFrameFromScreenPoint(50);
- panel_timeline->drag_track_start = (bottom_align) ? -1 : 0;
- for (int i=0;ipos();
+ QList items = panel_project->source_table->selectedItems();
+ long entry_point;
+ if (sequence == NULL) {
+ // if no sequence, we're going to create a new one using the clips as a reference
+ entry_point = 0;
+
+ // shitty hardcoded default values
+ predicted_video_width = 1920;
+ predicted_video_height = 1080;
+ predicted_new_frame_rate = 29.97;
+ predicted_audio_freq = 48000;
+ predicted_audio_layout = 3;
+
+ bool got_video_values = false;
+ bool got_audio_values = false;
+ for (int i=0;iget_type_from_tree(item) == MEDIA_TYPE_FOOTAGE) {
+ Media* m = panel_project->get_media_from_tree(item);
+ if (m->ready) {
+ if (!got_video_values) {
+ for (int j=0;jvideo_tracks.size();j++) {
+ MediaStream* ms = m->video_tracks.at(j);
+ predicted_video_width = ms->video_width;
+ predicted_video_height = ms->video_height;
+ if (ms->video_frame_rate != 0) {
+ predicted_new_frame_rate = ms->video_frame_rate;
+
+ // only break with a decent frame rate, otherwise there may be a better candidate
+ got_video_values = true;
+ break;
+ }
+ }
+ }
+ if (!got_audio_values) {
+ for (int j=0;jaudio_tracks.size();j++) {
+ MediaStream* ms = m->audio_tracks.at(j);
+ predicted_audio_freq = ms->audio_frequency;
+ got_audio_values = true;
+ break;
+ }
+ }
+ if (got_video_values && got_audio_values) break;
+ }
+ }
+ }
+ } else {
+ entry_point = panel_timeline->getFrameFromScreenPoint(pos.x());
+ panel_timeline->drag_frame_start = entry_point + panel_timeline->getFrameFromScreenPoint(50);
+ panel_timeline->drag_track_start = (bottom_align) ? -1 : 0;
+ predicted_new_frame_rate = sequence->frame_rate;
+ }
+ for (int i=0;iget_type_from_tree(item) == MEDIA_TYPE_FOOTAGE) {
Media* m = panel_project->get_media_from_tree(item);
@@ -73,7 +122,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
if (m->video_tracks.size() > 0 && m->video_tracks[0]->infinite_length && m->audio_tracks.size() == 0) {
g.out = g.in + 100;
} else {
- g.out = entry_point + m->get_length_in_frames(sequence->frame_rate);
+ g.out = entry_point + m->get_length_in_frames(predicted_new_frame_rate);
}
entry_point = g.out;
g.trimming = false;
@@ -96,14 +145,12 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
g.old_out = g.out;
g.old_track = g.track;
}
-
-// init_ghosts();
- panel_timeline->importing = true;
+ panel_timeline->importing = true;
}
}
void TimelineWidget::dragMoveEvent(QDragMoveEvent *event) {
- if (panel_timeline->importing) {
+ if (sequence != NULL && panel_timeline->importing) {
QPoint pos = event->pos();
update_ghosts(pos);
panel_timeline->repaint_timeline();
@@ -111,7 +158,7 @@ void TimelineWidget::dragMoveEvent(QDragMoveEvent *event) {
}
void TimelineWidget::dragLeaveEvent(QDragLeaveEvent*) {
- if (panel_timeline->importing) {
+ if (sequence != NULL && panel_timeline->importing) {
panel_timeline->ghosts.clear();
panel_timeline->importing = false;
panel_timeline->repaint_timeline();
@@ -119,24 +166,38 @@ void TimelineWidget::dragLeaveEvent(QDragLeaveEvent*) {
}
void TimelineWidget::dropEvent(QDropEvent* event) {
- if (panel_timeline->importing) {
- event->accept();
+ if (panel_timeline->importing && panel_timeline->ghosts.size() > 0) {
+ event->accept();
TimelineAction* ta = new TimelineAction();
QVector added_clips;
- // delete areas before adding
- QVector delete_areas;
- for (int i=0;ighosts.size();i++) {
- const Ghost& g = panel_timeline->ghosts.at(i);
- Selection s;
- s.in = g.in;
- s.out = g.out;
- s.track = g.track;
- delete_areas.append(s);
+ if (sequence == NULL) {
+ Sequence* s = new Sequence();
+
+ // dumb hardcoded default values, should be settable somewhere
+ s->name = panel_project->get_next_sequence_name();
+ s->width = predicted_video_width;
+ s->height = predicted_video_height;
+ s->frame_rate = predicted_new_frame_rate;
+ s->audio_frequency = predicted_audio_freq;
+ s->audio_layout = predicted_audio_layout;
+
+ panel_project->new_sequence(s, true, NULL);
+ } else {
+ // delete areas before adding
+ QVector delete_areas;
+ for (int i=0;ighosts.size();i++) {
+ const Ghost& g = panel_timeline->ghosts.at(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(ta, delete_areas);
}
- panel_timeline->delete_areas_and_relink(ta, delete_areas);
// add clips
for (int i=0;ighosts.size();i++) {
@@ -222,303 +283,307 @@ void TimelineWidget::mouseDoubleClickEvent(QMouseEvent *event) {
}
void TimelineWidget::mousePressEvent(QMouseEvent *event) {
- if (event->button() == Qt::LeftButton) {
- if (panel_timeline->tool == TIMELINE_TOOL_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR) {
- panel_timeline->drag_frame_start = panel_timeline->cursor_frame;
- panel_timeline->drag_track_start = panel_timeline->cursor_track;
- } else {
- QPoint pos = event->pos();
- panel_timeline->drag_frame_start = panel_timeline->getFrameFromScreenPoint(pos.x());
- panel_timeline->drag_track_start = getTrackFromScreenPoint(pos.y());
- }
-
- int clip_index = panel_timeline->trim_target;
- if (clip_index == -1) clip_index = getClipIndexFromCoords(panel_timeline->drag_frame_start, panel_timeline->drag_track_start);
-
- bool shift = (event->modifiers() & Qt::ShiftModifier);
-
- if (shift) {
- panel_timeline->selection_offset = panel_timeline->selections.size();
- } else {
- panel_timeline->selection_offset = 0;
- }
-
- switch (panel_timeline->tool) {
- case TIMELINE_TOOL_POINTER:
- case TIMELINE_TOOL_RIPPLE:
- case TIMELINE_TOOL_SLIP:
- case TIMELINE_TOOL_ROLLING:
- case TIMELINE_TOOL_SLIDE:
- {
- if (track_resizing) {
- track_resize_mouse_cache = event->pos().y();
- panel_timeline->moving_init = true;
+ if (sequence != NULL) {
+ if (event->button() == Qt::LeftButton) {
+ if (panel_timeline->tool == TIMELINE_TOOL_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR) {
+ panel_timeline->drag_frame_start = panel_timeline->cursor_frame;
+ panel_timeline->drag_track_start = panel_timeline->cursor_track;
} else {
- if (clip_index >= 0) {
- Clip* clip = sequence->get_clip(clip_index);
- if (clip != NULL) {
- if (panel_timeline->is_clip_selected(clip, true)) {
- if (shift) {
- // TODO if shift is down, deselect it
- }
- } else {
- // if "shift" is not down
- if (!shift) {
- panel_timeline->selections.clear();
- }
+ QPoint pos = event->pos();
+ panel_timeline->drag_frame_start = panel_timeline->getFrameFromScreenPoint(pos.x());
+ panel_timeline->drag_track_start = getTrackFromScreenPoint(pos.y());
+ }
- Selection s;
+ int clip_index = panel_timeline->trim_target;
+ if (clip_index == -1) clip_index = getClipIndexFromCoords(panel_timeline->drag_frame_start, panel_timeline->drag_track_start);
- s.in = clip->timeline_in;
- s.out = clip->timeline_out;
- s.track = clip->track;
- panel_timeline->selections.append(s);
+ bool shift = (event->modifiers() & Qt::ShiftModifier);
- if (panel_timeline->select_also_seeks) {
- panel_timeline->seek(clip->timeline_in);
- }
+ if (shift) {
+ panel_timeline->selection_offset = panel_timeline->selections.size();
+ } else {
+ panel_timeline->selection_offset = 0;
+ }
- // if alt is not down, select links
- if (!(event->modifiers() & Qt::AltModifier)) {
- for (int i=0;ilinked.size();i++) {
- Clip* link = sequence->get_clip(clip->linked.at(i));
- if (!panel_timeline->is_clip_selected(link, true)) {
- Selection ss;
- ss.in = link->timeline_in;
- ss.out = link->timeline_out;
- ss.track = link->track;
- panel_timeline->selections.append(ss);
+ switch (panel_timeline->tool) {
+ case TIMELINE_TOOL_POINTER:
+ case TIMELINE_TOOL_RIPPLE:
+ case TIMELINE_TOOL_SLIP:
+ case TIMELINE_TOOL_ROLLING:
+ case TIMELINE_TOOL_SLIDE:
+ {
+ if (track_resizing) {
+ track_resize_mouse_cache = event->pos().y();
+ panel_timeline->moving_init = true;
+ } else {
+ if (clip_index >= 0) {
+ Clip* clip = sequence->get_clip(clip_index);
+ if (clip != NULL) {
+ if (panel_timeline->is_clip_selected(clip, true)) {
+ if (shift) {
+ // TODO if shift is down, deselect it
+ }
+ } else {
+ // if "shift" is not down
+ if (!shift) {
+ panel_timeline->selections.clear();
+ }
+
+ Selection s;
+
+ s.in = clip->timeline_in;
+ s.out = clip->timeline_out;
+ s.track = clip->track;
+ panel_timeline->selections.append(s);
+
+ if (panel_timeline->select_also_seeks) {
+ panel_timeline->seek(clip->timeline_in);
+ }
+
+ // if alt is not down, select links
+ if (!(event->modifiers() & Qt::AltModifier)) {
+ for (int i=0;ilinked.size();i++) {
+ Clip* link = sequence->get_clip(clip->linked.at(i));
+ if (!panel_timeline->is_clip_selected(link, true)) {
+ Selection ss;
+ ss.in = link->timeline_in;
+ ss.out = link->timeline_out;
+ ss.track = link->track;
+ panel_timeline->selections.append(ss);
+ }
}
}
}
}
- }
- panel_timeline->moving_init = true;
- } else {
- // if "shift" is not down
- if (!shift) {
- panel_timeline->selections.clear();
- }
+ panel_timeline->moving_init = true;
+ } else {
+ // if "shift" is not down
+ if (!shift) {
+ panel_timeline->selections.clear();
+ }
- panel_timeline->rect_select_init = true;
+ panel_timeline->rect_select_init = true;
+ }
+ panel_timeline->repaint_timeline();
}
+ }
+ break;
+ case TIMELINE_TOOL_EDIT:
+ if (panel_timeline->edit_tool_also_seeks) panel_timeline->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);
panel_timeline->repaint_timeline();
}
- }
- break;
- case TIMELINE_TOOL_EDIT:
- if (panel_timeline->edit_tool_also_seeks) panel_timeline->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);
- panel_timeline->repaint_timeline();
- }
- break;
+ break;
+ }
}
}
}
void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) {
- bool alt = (event->modifiers() & Qt::AltModifier);
+ if (sequence != NULL) {
+ bool alt = (event->modifiers() & Qt::AltModifier);
- if (event->button() == Qt::LeftButton) {
- bool repaint = false;
+ if (event->button() == Qt::LeftButton) {
+ bool repaint = false;
- if (panel_timeline->moving_proc) {
- TimelineAction* ta = new TimelineAction();
+ if (panel_timeline->moving_proc) {
+ TimelineAction* ta = new TimelineAction();
- // 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)
- const Ghost& first_ghost = panel_timeline->ghosts.at(0);
- if (panel_timeline->trim_in_point) {
- ripple_length = first_ghost.old_in - panel_timeline->ghosts.at(0).in;
- ripple_point = first_ghost.old_in;
- } 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;
- }
- for (int i=0;ighosts.size();i++) {
- const Ghost& g = panel_timeline->ghosts.at(i);
- long comp_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)
+ const Ghost& first_ghost = panel_timeline->ghosts.at(0);
if (panel_timeline->trim_in_point) {
- comp_point = g.old_in;
+ ripple_length = first_ghost.old_in - panel_timeline->ghosts.at(0).in;
+ ripple_point = first_ghost.old_in;
} else {
- comp_point = g.old_out;
+ // 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;
}
- if (ripple_point > comp_point) ripple_point = comp_point;
- }
- if (!panel_timeline->trim_in_point) ripple_length = -ripple_length;
- panel_timeline->ripple(ta, ripple_point, ripple_length);
- }
-
- if (panel_timeline->tool == TIMELINE_TOOL_POINTER && (event->modifiers() & Qt::AltModifier)) { // if holding alt, 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
- Clip* c = sequence->get_clip(g.clip)->copy();
-
- 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);
-
- old_clips.append(g.clip);
- new_clips.append(c);
+ for (int i=0;ighosts.size();i++) {
+ const Ghost& g = panel_timeline->ghosts.at(i);
+ long comp_point;
+ if (panel_timeline->trim_in_point) {
+ comp_point = g.old_in;
+ } else {
+ comp_point = g.old_out;
+ }
+ if (ripple_point > comp_point) ripple_point = comp_point;
}
+ if (!panel_timeline->trim_in_point) ripple_length = -ripple_length;
+ panel_timeline->ripple(ta, ripple_point, ripple_length);
}
- if (new_clips.size() > 0) {
- panel_timeline->delete_areas_and_relink(ta, delete_areas);
- // relink duplicated clips
- panel_timeline->relink_clips_using_ids(old_clips, new_clips);
-
- for (int i=0;iadd_clips(sequence, new_clips);
- }
- }
- } else {
- // move clips
- // TODO can we do this better than 3 consecutive for loops?
- if (panel_timeline->tool == TIMELINE_TOOL_POINTER) {
+ if (panel_timeline->tool == TIMELINE_TOOL_POINTER && (event->modifiers() & Qt::AltModifier)) { // if holding alt, duplicate rather than move
+ // duplicate clips
+ QVector old_clips;
+ QVector 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);
+ 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 = sequence->get_clip(g.clip)->copy();
- sequence->get_clip(g.clip)->undeletable = true;
+ 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);
+ }
}
- panel_timeline->delete_areas_and_relink(ta, delete_areas);
- for (int i=0;ighosts.size();i++) {
- sequence->get_clip(panel_timeline->ghosts[i].clip)->undeletable = false;
- }
- }
- for (int i=0;ighosts.size();i++) {
- Ghost& g = panel_timeline->ghosts[i];
+ if (new_clips.size() > 0) {
+ panel_timeline->delete_areas_and_relink(ta, delete_areas);
- // step 3 - move clips
- ta->increase_timeline_in(sequence, g.clip, g.in - g.old_in);
- ta->increase_timeline_out(sequence, g.clip, g.out - g.old_out);
- ta->increase_track(sequence, g.clip, g.track - g.old_track);
- ta->increase_clip_in(sequence, g.clip, g.clip_in - g.old_clip_in);
- }
- }
+ // relink duplicated clips
+ panel_timeline->relink_clips_using_ids(old_clips, new_clips);
- undo_stack.push(ta);
-
- panel_timeline->redraw_all_clips(true);
- } else if (panel_timeline->selecting || panel_timeline->rect_select_proc) {
- repaint = true;
- } else if (panel_timeline->splitting) {
- TimelineAction* ta = new TimelineAction();
- 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(ta, split_index, panel_timeline->drag_frame_start, !alt)) {
- split = true;
- }
- }
- if (split) {
- undo_stack.push(ta);
- panel_timeline->redraw_all_clips(true);
- } else {
- delete ta;
- }
- panel_timeline->split_cache.clear();
- }
-
- // remove duplicate selections
- panel_timeline->clean_up_selections(panel_timeline->selections);
-
- // destroy all ghosts
- panel_timeline->ghosts.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;
- pre_clips.clear();
- post_clips.clear();
-
- if (repaint) panel_timeline->repaint_timeline();
-
- // 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 got_vclip = false;
- bool got_aclip = false;
- int vclip = -1;
- int aclip = -1;
- for (int i=0;iclip_count();i++) {
- Clip* clip = sequence->get_clip(i);
- if (clip != NULL && panel_timeline->is_clip_selected(clip, true)) {
- if (clip->track < 0) {
- if (got_vclip) {
- vclip = -1;
- } else {
- vclip = i;
- got_vclip = true;
+ for (int i=0;iadd_clips(sequence, new_clips);
+ }
}
} else {
- if (got_aclip) {
- aclip = -1;
+ // move clips
+ // TODO can we do this better than 3 consecutive for loops?
+ if (panel_timeline->tool == TIMELINE_TOOL_POINTER) {
+ 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);
+
+ sequence->get_clip(g.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(ta, delete_areas);
+ for (int i=0;ighosts.size();i++) {
+ sequence->get_clip(panel_timeline->ghosts[i].clip)->undeletable = false;
+ }
+ }
+ for (int i=0;ighosts.size();i++) {
+ Ghost& g = panel_timeline->ghosts[i];
+
+ // step 3 - move clips
+ ta->increase_timeline_in(sequence, g.clip, g.in - g.old_in);
+ ta->increase_timeline_out(sequence, g.clip, g.out - g.old_out);
+ ta->increase_track(sequence, g.clip, g.track - g.old_track);
+ ta->increase_clip_in(sequence, g.clip, g.clip_in - g.old_clip_in);
+ }
+ }
+
+ undo_stack.push(ta);
+
+ panel_timeline->redraw_all_clips(true);
+ } else if (panel_timeline->selecting || panel_timeline->rect_select_proc) {
+ repaint = true;
+ } else if (panel_timeline->splitting) {
+ TimelineAction* ta = new TimelineAction();
+ 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(ta, split_index, panel_timeline->drag_frame_start, !alt)) {
+ split = true;
+ }
+ }
+ if (split) {
+ undo_stack.push(ta);
+ panel_timeline->redraw_all_clips(true);
+ } else {
+ delete ta;
+ }
+ panel_timeline->split_cache.clear();
+ }
+
+ // remove duplicate selections
+ panel_timeline->clean_up_selections(panel_timeline->selections);
+
+ // destroy all ghosts
+ panel_timeline->ghosts.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;
+ pre_clips.clear();
+ post_clips.clear();
+
+ if (repaint) panel_timeline->repaint_timeline();
+
+ // 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 got_vclip = false;
+ bool got_aclip = false;
+ int vclip = -1;
+ int aclip = -1;
+ for (int i=0;iclip_count();i++) {
+ Clip* clip = sequence->get_clip(i);
+ if (clip != NULL && panel_timeline->is_clip_selected(clip, true)) {
+ if (clip->track < 0) {
+ if (got_vclip) {
+ vclip = -1;
+ } else {
+ vclip = i;
+ got_vclip = true;
+ }
} else {
- aclip = i;
- got_aclip = true;
+ if (got_aclip) {
+ aclip = -1;
+ } else {
+ aclip = i;
+ got_aclip = true;
+ }
}
}
}
- }
- // check if aclip is linked to vclip
- QVector selected_clips;
- if (vclip != -1) selected_clips.append(vclip);
- if (aclip != -1) selected_clips.append(aclip);
- if (vclip != -1 && aclip != -1) {
- bool found = false;
- Clip* vclip_ref = sequence->get_clip(vclip);
- for (int i=0;ilinked.size();i++) {
- if (vclip_ref->linked.at(i) == aclip) {
- found = true;
- break;
+ // check if aclip is linked to vclip
+ QVector selected_clips;
+ if (vclip != -1) selected_clips.append(vclip);
+ if (aclip != -1) selected_clips.append(aclip);
+ if (vclip != -1 && aclip != -1) {
+ bool found = false;
+ Clip* vclip_ref = sequence->get_clip(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();
}
}
- if (!found) {
- // only display multiple clips if they're linked
- selected_clips.clear();
- }
+ panel_effect_controls->set_clips(selected_clips);
}
- panel_effect_controls->set_clips(selected_clips);
}
}
@@ -751,399 +816,409 @@ void TimelineWidget::update_ghosts(QPoint& mouse_pos) {
}
void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
- bool alt = (event->modifiers() & Qt::AltModifier);
+ if (sequence != NULL) {
+ bool alt = (event->modifiers() & Qt::AltModifier);
- panel_timeline->cursor_frame = panel_timeline->getFrameFromScreenPoint(event->pos().x());
- panel_timeline->cursor_track = getTrackFromScreenPoint(event->pos().y());
+ panel_timeline->cursor_frame = panel_timeline->getFrameFromScreenPoint(event->pos().x());
+ panel_timeline->cursor_track = getTrackFromScreenPoint(event->pos().y());
- if (panel_timeline->tool == TIMELINE_TOOL_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR) {
- panel_timeline->snap_to_clip(&panel_timeline->cursor_frame, !panel_timeline->edit_tool_also_seeks || !panel_timeline->selecting);
- }
- 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 (panel_timeline->selections.size() != selection_count) {
- panel_timeline->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 (panel_timeline->edit_tool_selects_links) {
- for (int j=0;jclip_count();j++) {
- Clip* c = sequence->get_clip(j);
- for (int k=0;kselections.size();k++) {
- const Selection& s = panel_timeline->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 = panel_timeline->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 = {s.in, s.out, linked_tracks.at(k)};
- panel_timeline->selections.append(link_sel);
- }
- }
-
- break;
- }
- }
- }
+ if (panel_timeline->tool == TIMELINE_TOOL_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR) {
+ panel_timeline->snap_to_clip(&panel_timeline->cursor_frame, !panel_timeline->edit_tool_also_seeks || !panel_timeline->selecting);
}
-
- if (panel_timeline->edit_tool_also_seeks) {
- panel_timeline->seek(qMin(panel_timeline->drag_frame_start, panel_timeline->cursor_frame));
- } else {
- panel_timeline->repaint_timeline();
- }
- } 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;
+ 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 (panel_timeline->selections.size() != selection_count) {
+ panel_timeline->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);
}
- if (new_height < TRACK_MIN_HEIGHT) new_height = TRACK_MIN_HEIGHT;
- panel_timeline->calculate_track_height(track_target, new_height);
- redraw_clips();
- } else if (panel_timeline->moving_proc) {
- QPoint pos = event->pos();
- update_ghosts(pos);
- } else {
- // set up movement
- // create ghosts
- for (int i=0;iclip_count();i++) {
- Clip* c = sequence->get_clip(i);
- if (c != NULL && panel_timeline->is_clip_selected(c, true)) {
- Ghost g;
- 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;iget_clip(panel_timeline->ghosts.at(i).clip);
+ // select linked clips too
+ if (panel_timeline->edit_tool_selects_links) {
+ for (int j=0;jclip_count();j++) {
+ Clip* c = sequence->get_clip(j);
+ for (int k=0;kselections.size();k++) {
+ const Selection& s = panel_timeline->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) {
- // see if any ghosts are touching, in which case flip them
- for (int k=0;kget_clip(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);
- Clip* ghost_clip = sequence->get_clip(g.clip);
- for (int j=0;jclip_count();j++) {
- Clip* comp_clip = sequence->get_clip(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
+ QVector linked_tracks = panel_timeline->get_tracks_of_linked_clips(j);
+ for (int k=0;kghosts.at(duplicate_ghost_index).clip == j) {
+ for (int l=0;lselections.size();l++) {
+ const Selection& test_sel = panel_timeline->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 (g.trim_in == panel_timeline->trim_in_point) {
- if (!found) {
- // add ghost for this clip with opposite trim_in
- Ghost gh;
- 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--;
- }
+ if (!found) {
+ Selection link_sel = {s.in, s.out, linked_tracks.at(k)};
+ panel_timeline->selections.append(link_sel);
}
}
- }
- }
- }
- } else if (panel_timeline->tool == TIMELINE_TOOL_SLIDE) {
- for (int i=0;ighosts.at(i);
- Clip* ghost_clip = sequence->get_clip(g.clip);
- panel_timeline->ghosts[i].trimming = false;
- for (int j=0;jclip_count();j++) {
- Clip* c = sequence->get_clip(j);
- if (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.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) {
- QVector axis_ghosts;
- for (int i=0;ighosts.size();i++) {
- Clip* c = sequence->get_clip(panel_timeline->ghosts.at(i).clip);
- bool found = false;
- for (int j=0;jtrack == cc->track &&
- ((panel_timeline->trim_in_point && c->timeline_in < cc->timeline_in) ||
- (!panel_timeline->trim_in_point && c->timeline_out > cc->timeline_out))) {
- axis_ghosts[j] = c;
- found = true;
break;
}
}
- if (!found) {
- axis_ghosts.append(c);
- }
}
+ }
+ if (panel_timeline->edit_tool_also_seeks) {
+ panel_timeline->seek(qMin(panel_timeline->drag_frame_start, panel_timeline->cursor_frame));
+ } else {
+ panel_timeline->repaint_timeline();
+ }
+ } 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;
+ }
+ if (new_height < TRACK_MIN_HEIGHT) new_height = TRACK_MIN_HEIGHT;
+ panel_timeline->calculate_track_height(track_target, new_height);
+ redraw_clips();
+ } else if (panel_timeline->moving_proc) {
+ QPoint pos = event->pos();
+ update_ghosts(pos);
+ } else {
+ // set up movement
+ // create ghosts
for (int i=0;iclip_count();i++) {
Clip* c = sequence->get_clip(i);
- if (c != NULL && !panel_timeline->is_clip_selected(c, true)) {
- for (int j=0;jtrim_in_point) ? axis->timeline_in : axis->timeline_out;
- bool clip_is_pre = (c->timeline_in < comp_point);
- QVector& clip_list = clip_is_pre ? pre_clips : post_clips;
- bool found = false;
- for (int k=0;ktrack == c->track) {
- if (clip_is_pre == (c->timeline_in > cached->timeline_in)) {
- clip_list[k] = c;
+ if (c != NULL && panel_timeline->is_clip_selected(c, true)) {
+ Ghost g;
+ 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;iget_clip(panel_timeline->ghosts.at(i).clip);
+
+ // see if any ghosts are touching, in which case flip them
+ for (int k=0;kget_clip(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);
+ Clip* ghost_clip = sequence->get_clip(g.clip);
+ for (int j=0;jclip_count();j++) {
+ Clip* comp_clip = sequence->get_clip(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.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--;
+ }
}
- found = true;
- break;
}
}
- if (!found) {
- clip_list.append(c);
+ }
+ }
+ } else if (panel_timeline->tool == TIMELINE_TOOL_SLIDE) {
+ for (int i=0;ighosts.at(i);
+ Clip* ghost_clip = sequence->get_clip(g.clip);
+ panel_timeline->ghosts[i].trimming = false;
+ for (int j=0;jclip_count();j++) {
+ Clip* c = sequence->get_clip(j);
+ if (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.clip = j;
+ gh.trimming = true;
+ gh.trim_in = is_in;
+ panel_timeline->ghosts.append(gh);
+ }
+ }
}
}
}
}
- }
- panel_timeline->moving_proc = true;
- }
- panel_timeline->repaint_timeline();
- } 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;
- }
+ init_ghosts();
- 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));
- }
- }
- }
- }
- }
- panel_timeline->repaint_timeline();
- } 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->getFrameFromScreenPoint(panel_timeline->rect_select_x);
- long frame_end = panel_timeline->getFrameFromScreenPoint(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;iclip_count();i++) {
- Clip* clip = sequence->get_clip(i);
- if (clip != NULL &&
- 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(sequence->get_clip(clip->linked.at(j)));
- }
- }
-
- for (int j=0;jtool == TIMELINE_TOOL_RIPPLE) {
+ QVector axis_ghosts;
+ for (int i=0;ighosts.size();i++) {
+ Clip* c = sequence->get_clip(panel_timeline->ghosts.at(i).clip);
bool found = false;
- Clip* c = session_clips.at(j);
- for (int k=0;ktrack == cc->track &&
+ ((panel_timeline->trim_in_point && c->timeline_in < cc->timeline_in) ||
+ (!panel_timeline->trim_in_point && c->timeline_out > cc->timeline_out))) {
+ axis_ghosts[j] = c;
found = true;
break;
}
}
if (!found) {
- selected_clips.append(c);
+ axis_ghosts.append(c);
+ }
+ }
+
+ for (int i=0;iclip_count();i++) {
+ Clip* c = sequence->get_clip(i);
+ if (c != NULL && !panel_timeline->is_clip_selected(c, true)) {
+ for (int j=0;jtrim_in_point) ? axis->timeline_in : axis->timeline_out;
+ bool clip_is_pre = (c->timeline_in < comp_point);
+ QVector& clip_list = clip_is_pre ? pre_clips : post_clips;
+ bool found = false;
+ for (int k=0;ktrack == c->track) {
+ if (clip_is_pre == (c->timeline_in > cached->timeline_in)) {
+ clip_list[k] = c;
+ }
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ clip_list.append(c);
+ }
+ }
+ }
+ }
+ }
+
+ panel_timeline->moving_proc = true;
+ }
+ panel_timeline->repaint_timeline();
+ } 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));
+ }
}
}
}
}
-
- panel_timeline->selections.resize(selected_clips.size() + panel_timeline->selection_offset);
- for (int i=0;iselections[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;
- 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 (panel_timeline->tool == TIMELINE_TOOL_POINTER ||
- panel_timeline->tool == TIMELINE_TOOL_RIPPLE ||
- panel_timeline->tool == TIMELINE_TOOL_ROLLING) {
- track_resizing = 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();
- QPoint pos = event->pos();
+ long frame_start = panel_timeline->getFrameFromScreenPoint(panel_timeline->rect_select_x);
+ long frame_end = panel_timeline->getFrameFromScreenPoint(event->pos().x());
+ long frame_min = qMin(frame_start, frame_end);
+ long frame_max = qMax(frame_start, frame_end);
- int lim = 5;
- int mouse_track = getTrackFromScreenPoint(pos.y());
- long mouse_frame_lower = panel_timeline->getFrameFromScreenPoint(pos.x()-lim)-1;
- long mouse_frame_upper = panel_timeline->getFrameFromScreenPoint(pos.x()+lim)+1;
- bool found = false;
- int closeness = INT_MAX;
- for (int i=0;iclip_count();i++) {
- Clip* c = sequence->get_clip(i);
- if (c != NULL && c->track == mouse_track) {
- if (c->timeline_in > mouse_frame_lower && c->timeline_in < mouse_frame_upper) {
- int nc = qAbs(c->timeline_in + 1 - panel_timeline->cursor_frame);
- if (nc < closeness) {
- panel_timeline->trim_target = i;
- panel_timeline->trim_in_point = true;
- closeness = nc;
- found = true;
+ 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;iclip_count();i++) {
+ Clip* clip = sequence->get_clip(i);
+ if (clip != NULL &&
+ 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(sequence->get_clip(clip->linked.at(j)));
+ }
+ }
+
+ for (int j=0;jtimeline_out > mouse_frame_lower && c->timeline_out < mouse_frame_upper) {
- int nc = qAbs(c->timeline_out - 1 - panel_timeline->cursor_frame);
- if (nc < closeness) {
- panel_timeline->trim_target = i;
- panel_timeline->trim_in_point = false;
- closeness = nc;
- found = true;
- }
- }
- }
- }
- if (found) {
- setCursor(Qt::SizeHorCursor);
- } else {
- panel_timeline->trim_target = -1;
- // look for track heights
- found = false;
- int track_y = 0;
- for (int i=0;iget_track_height_size(bottom_align);i++) {
- int track = (bottom_align) ? -1-i : i;
- 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;
- if (pos.y() > y_test_value-test_range && pos.y() < y_test_value+test_range) {
- found = true;
- track_resizing = true;
- track_target = track;
- track_resize_old_value = track_height;
+ panel_timeline->selections.resize(selected_clips.size() + panel_timeline->selection_offset);
+ for (int i=0;iselections[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;
+ 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 (panel_timeline->tool == TIMELINE_TOOL_POINTER ||
+ panel_timeline->tool == TIMELINE_TOOL_RIPPLE ||
+ panel_timeline->tool == TIMELINE_TOOL_ROLLING) {
+ track_resizing = false;
+
+ QPoint pos = event->pos();
+
+ int lim = 5;
+ int mouse_track = getTrackFromScreenPoint(pos.y());
+ long mouse_frame_lower = panel_timeline->getFrameFromScreenPoint(pos.x()-lim)-1;
+ long mouse_frame_upper = panel_timeline->getFrameFromScreenPoint(pos.x()+lim)+1;
+ bool found = false;
+ bool cursor_contains_clip = false;
+ int closeness = INT_MAX;
+ for (int i=0;iclip_count();i++) {
+ Clip* c = sequence->get_clip(i);
+ if (c != NULL && c->track == mouse_track) {
+ if (panel_timeline->cursor_frame >= c->timeline_in &&
+ panel_timeline->cursor_frame <= c->timeline_out) {
+ cursor_contains_clip = true;
+ }
+ if (c->timeline_in > mouse_frame_lower && c->timeline_in < mouse_frame_upper) {
+ int nc = qAbs(c->timeline_in + 1 - panel_timeline->cursor_frame);
+ if (nc < closeness) {
+ panel_timeline->trim_target = i;
+ panel_timeline->trim_in_point = true;
+ closeness = nc;
+ found = true;
+ }
+ }
+ if (c->timeline_out > mouse_frame_lower && c->timeline_out < mouse_frame_upper) {
+ int nc = qAbs(c->timeline_out - 1 - panel_timeline->cursor_frame);
+ if (nc < closeness) {
+ panel_timeline->trim_target = i;
+ panel_timeline->trim_in_point = false;
+ closeness = nc;
+ found = true;
+ }
+ }
}
}
-
if (found) {
- setCursor(Qt::SizeVerCursor);
+ setCursor(Qt::SizeHorCursor);
+ } else {
+ panel_timeline->trim_target = -1;
+
+ // look for track heights
+ int track_y = 0;
+ for (int i=0;iget_track_height_size(bottom_align);i++) {
+ int track = (bottom_align) ? -1-i : i;
+ 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;
+ if (pos.y() > y_test_value-test_range && pos.y() < y_test_value+test_range) {
+ // if track lines are hidden, only resize track if a clip is already there
+ if (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_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR) {
+ // redraw because we have a cursor
+ panel_timeline->repaint_timeline();
+ } 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_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR) {
- // redraw because we have a cursor
- panel_timeline->repaint_timeline();
- } else if (panel_timeline->tool == TIMELINE_TOOL_SLIP) {
- if (getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track) > -1) {
- setCursor(Qt::SizeHorCursor);
- } else {
- unsetCursor();
}
}
}
diff --git a/ui/timelinewidget.h b/ui/timelinewidget.h
index 8e49e7327..0d7793f09 100644
--- a/ui/timelinewidget.h
+++ b/ui/timelinewidget.h
@@ -57,6 +57,12 @@ private:
QPixmap clip_pixmap;
// QPixmap selection_pixmap;
+ int predicted_video_width;
+ int predicted_video_height;
+ double predicted_new_frame_rate;
+ int predicted_audio_freq;
+ int predicted_audio_layout;
+
signals:
public slots: