From 70be7fa097d073d749d8d92a9a66701e25b45a18 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 28 Feb 2019 03:45:17 -0800 Subject: [PATCH] created sequence clip selection convenience function --- oliveglobal.cpp | 11 +-- panels/timeline.cpp | 172 +++++++++++++++------------------- panels/timeline.h | 1 - project/sequence.cpp | 46 +++++++++ project/sequence.h | 5 + project/undo.cpp | 7 ++ project/undo.h | 1 + rendering/renderfunctions.cpp | 2 +- ui/timelinewidget.cpp | 43 +++------ 9 files changed, 154 insertions(+), 134 deletions(-) diff --git a/oliveglobal.cpp b/oliveglobal.cpp index 9e875fdb6..a62ab05cc 100644 --- a/oliveglobal.cpp +++ b/oliveglobal.cpp @@ -358,16 +358,9 @@ void OliveGlobal::open_debug_log() { void OliveGlobal::open_speed_dialog() { if (olive::ActiveSequence != nullptr) { - QVector selected_clips; + QVector selected_clips = olive::ActiveSequence->SelectedClips(); - for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i).get(); - if (c != nullptr && is_clip_selected(c, true)) { - selected_clips.append(c); - } - } - - if (selected_clips.size() > 0) { + if (!selected_clips.isEmpty()) { SpeedDialog s(olive::MainWindow, selected_clips); s.exec(); } diff --git a/panels/timeline.cpp b/panels/timeline.cpp index aa88b1bf8..6bdb36602 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -371,7 +371,7 @@ void Timeline::add_transition() { for (int i=0;iclips.size();i++) { Clip* c = olive::ActiveSequence->clips.at(i).get(); - if (c != nullptr && is_clip_selected(c, true)) { + if (c != nullptr && olive::ActiveSequence->IsClipSelected(c, true)) { int transition_to_add = (c->track() < 0) ? TRANSITION_INTERNAL_CROSSDISSOLVE : TRANSITION_INTERNAL_LINEARFADE; if (c->opening_transition == nullptr) { ca->append(new AddTransitionCommand(c, @@ -403,25 +403,23 @@ void Timeline::add_transition() { void Timeline::nest() { 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).get(); - if (c != nullptr && is_clip_selected(c, true)) { - selected_clips.append(i); - earliest_point = qMin(c->timeline_in(), earliest_point); - } - } + QVector selected_clips = olive::ActiveSequence->SelectedClipIndexes(); // nest them if (!selected_clips.isEmpty()) { + + // get earliest point in selected clips + long earliest_point = LONG_MAX; + for (int i=0;iclips.at(selected_clips.at(i))->timeline_in(), earliest_point); + } + ComboAction* ca = new ComboAction(); + // create "nest" sequence with the same attributes as the current sequence 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; @@ -658,22 +656,22 @@ void Timeline::delete_in_out_internal(bool ripple) { void Timeline::toggle_enable_on_selected_clips() { if (olive::ActiveSequence != nullptr) { - SetClipProperty* set_action = new SetClipProperty(kSetClipPropertyEnabled); - bool push_undo = false; + // get currently selected clips + QVector selected_clips = olive::ActiveSequence->SelectedClips(); - for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i).get(); - if (c != nullptr && is_clip_selected(c, true)) { + if (!selected_clips.isEmpty()) { + // if clips are selected, create an undoable action + SetClipProperty* set_action = new SetClipProperty(kSetClipPropertyEnabled); + + // add each selected clip to the action + for (int i=0;iAddSetting(c, !c->enabled()); - push_undo = true; } - } - if (push_undo) { + // push the action olive::UndoStack.push(set_action); - update_ui(true); - } else { - delete set_action; + update_ui(false); } } } @@ -828,18 +826,6 @@ void Timeline::DecreaseTrackHeight() { repaint_timeline(); } -bool is_clip_selected(Clip *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; -} - void Timeline::snapping_clicked(bool checked) { snapping = checked; } @@ -945,14 +931,14 @@ bool Timeline::split_clip_and_relink(ComboAction *ca, int clip, long frame, bool if (relink) { pre_clips.append(clip); - bool original_clip_is_selected = is_clip_selected(c, true); + bool original_clip_is_selected = olive::ActiveSequence->IsClipSelected(c, true); // find linked clips of old clip for (int i=0;ilinked.size();i++) { int l = c->linked.at(i); if (!split_cache.contains(l)) { Clip* link = olive::ActiveSequence->clips.at(l).get(); - if ((original_clip_is_selected && is_clip_selected(link, true)) || !original_clip_is_selected) { + if ((original_clip_is_selected && olive::ActiveSequence->IsClipSelected(link, true)) || !original_clip_is_selected) { split_cache.append(l); ClipPtr s = split_clip(ca, true, l, frame); if (s != nullptr) { @@ -1233,73 +1219,71 @@ void Timeline::paste(bool insert) { } } else if (clipboard_type == CLIPBOARD_TYPE_EFFECT) { ComboAction* ca = new ComboAction(); - bool push = false; bool replace = false; bool skip = false; bool ask_conflict = true; - for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i).get(); - 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; + QVector selected_clips = olive::ActiveSequence->SelectedClips(); + + for (int i=0;i(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; } - 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); + + QCheckBox* future_box = new QCheckBox(tr("Do this for all conflicts found"), &box); + box.setCheckBox(future_box); + + box.exec(); + + if (box.clickedButton() == replace_button) { + replace = true; + } else if (box.clickedButton() == skip_button) { + skip = true; } - 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); + ask_conflict = !future_box->isChecked(); + } - box.addButton(tr("Add"), QMessageBox::YesRole); - QPushButton* replace_button = box.addButton(tr("Replace"), QMessageBox::NoRole); - QPushButton* skip_button = box.addButton(tr("Skip"), QMessageBox::RejectRole); + 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); - QCheckBox* future_box = new QCheckBox(tr("Do this for all conflicts found"), &box); - box.setCheckBox(future_box); - - box.exec(); - - 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); - - ca->append(new AddEffectCommand(c, e->copy(c), nullptr, found)); - push = true; - } else { - ca->append(new AddEffectCommand(c, e->copy(c), nullptr)); - push = true; - } + ca->append(new AddEffectCommand(c, e->copy(c), nullptr, found)); + } else { + ca->append(new AddEffectCommand(c, e->copy(c), nullptr)); } } } } - if (push) { + if (ca->hasActions()) { ca->appendPost(new ReloadEffectsCommand()); olive::UndoStack.push(ca); } else { @@ -1491,7 +1475,7 @@ void Timeline::split_at_playhead() { QVector post_clips; for (int j=0;jclips.size();j++) { Clip* clip = olive::ActiveSequence->clips.at(j).get(); - if (clip != nullptr && is_clip_selected(clip, true)) { + if (clip != nullptr && olive::ActiveSequence->IsClipSelected(clip, true)) { ClipPtr s = split_clip(ca, true, j, olive::ActiveSequence->playhead); if (s != nullptr) { pre_clips.append(j); @@ -1634,7 +1618,7 @@ void Timeline::set_marker() { for (int i=0;iclips.size();i++) { Clip* c = olive::ActiveSequence->clips.at(i).get(); if (c != nullptr - && is_clip_selected(c, true)) { + && olive::ActiveSequence->IsClipSelected(c, true)) { // only add markers if the playhead is inside the clip if (olive::ActiveSequence->playhead >= c->timeline_in() @@ -1688,7 +1672,7 @@ void Timeline::toggle_links() { command->s = olive::ActiveSequence; for (int i=0;iclips.size();i++) { Clip* c = olive::ActiveSequence->clips.at(i).get(); - if (c != nullptr && is_clip_selected(c, true)) { + if (c != nullptr && olive::ActiveSequence->IsClipSelected(c, true)) { if (!command->clips.contains(i)) command->clips.append(i); if (c->linked.size() > 0) { diff --git a/panels/timeline.h b/panels/timeline.h index 1408bc7cb..e02a532b6 100644 --- a/panels/timeline.h +++ b/panels/timeline.h @@ -71,7 +71,6 @@ namespace olive { } } -bool is_clip_selected(Clip* 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); diff --git a/project/sequence.cpp b/project/sequence.cpp index b33ca2457..2e070ce00 100644 --- a/project/sequence.cpp +++ b/project/sequence.cpp @@ -79,6 +79,52 @@ void Sequence::RefreshClips(Media *m) { } } +QVector Sequence::SelectedClips() +{ + QVector selected_clips; + + for (int i=0;i Sequence::SelectedClipIndexes() +{ + QVector selected_clips; + + for (int i=0;itrack() == 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 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 f59a34eb2..c398db964 100644 --- a/project/sequence.h +++ b/project/sequence.h @@ -44,6 +44,11 @@ public: int audio_layout; void RefreshClips(Media* m = nullptr); + QVector SelectedClips(); + QVector SelectedClipIndexes(); + + bool IsClipSelected(int clip_index, bool containing); + bool IsClipSelected(Clip* clip, bool containing); QVector selections; long playhead; diff --git a/project/undo.cpp b/project/undo.cpp index f1901fca2..3d30b5e69 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -689,6 +689,13 @@ void EffectFieldUndo::doRedo() { SetClipProperty::SetClipProperty(SetClipPropertyType type) : type_(type) {} +void SetClipProperty::AddSetting(QVector clips, bool setting) +{ + for (int i=0;i clips, bool setting); void AddSetting(Clip *c, bool setting); private: SetClipPropertyType type_; diff --git a/rendering/renderfunctions.cpp b/rendering/renderfunctions.cpp index f62112913..a6043db6d 100644 --- a/rendering/renderfunctions.cpp +++ b/rendering/renderfunctions.cpp @@ -434,7 +434,7 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { // using gizmo data, set definitive gizmo if (selected_effect != nullptr) { (*params.gizmos) = selected_effect; - } else if (is_clip_selected(c, true)) { + } else if (s->IsClipSelected(c, true)) { (*params.gizmos) = first_gizmo_effect; } diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index 542b7ebb9..caf0b1a01 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -101,13 +101,7 @@ void TimelineWidget::show_context_menu(const QPoint& pos) { menu.addSeparator(); // collect all the selected clips - QVector selected_clips; - for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i).get(); - if (c != nullptr && is_clip_selected(c, true)) { - selected_clips.append(c); - } - } + QVector selected_clips = olive::ActiveSequence->SelectedClips(); if (!selected_clips.isEmpty()) { // clips are selected @@ -184,20 +178,17 @@ void TimelineWidget::show_context_menu(const QPoint& pos) { } void TimelineWidget::toggle_autoscale() { - SetClipProperty* action = new SetClipProperty(kSetClipPropertyAutoscale); + QVector selected_clips = olive::ActiveSequence->SelectedClips(); - bool added_clip = false; - for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i).get(); - if (c != nullptr && is_clip_selected(c, true)) { + if (!selected_clips.isEmpty()) { + SetClipProperty* action = new SetClipProperty(kSetClipPropertyAutoscale); + + for (int i=0;iAddSetting(c, !c->autoscaled()); - added_clip = true; } - } - if (added_clip) { + olive::UndoStack.push(action); - } else { - delete action; } } @@ -239,16 +230,10 @@ void TimelineWidget::open_sequence_properties() { void TimelineWidget::show_clip_properties() { // get list of selected clips - QVector selected_clips; - for (int i=0;iclips.size();i++) { - Clip* c = olive::ActiveSequence->clips.at(i).get(); - if (c != nullptr && is_clip_selected(c, true)) { - selected_clips.append(c); - } - } + QVector selected_clips = olive::ActiveSequence->SelectedClips(); // if clips are selected, open the clip properties dialog - if (selected_clips.size() > 0) { + if (!selected_clips.isEmpty()) { ClipPropertiesDialog cpd(this, selected_clips); cpd.exec(); } @@ -663,7 +648,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { if (hovered_clip >= 0) { Clip* clip = olive::ActiveSequence->clips.at(hovered_clip).get(); - if (is_clip_selected(clip, true)) { + if (olive::ActiveSequence->IsClipSelected(clip, true)) { if (shift) { @@ -766,7 +751,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { Clip* link = olive::ActiveSequence->clips.at(clip->linked.at(i)).get(); // check if the clip is already selected - if (!is_clip_selected(link, true)) { + if (!olive::ActiveSequence->IsClipSelected(link, true)) { Selection ss; ss.in = link->timeline_in(); ss.out = link->timeline_out(); @@ -2064,7 +2049,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { Clip* c = olive::ActiveSequence->clips.at(j).get(); - if (c != nullptr && is_clip_selected(c, false)) { + if (c != nullptr && olive::ActiveSequence->IsClipSelected(c, false)) { // loop through linked clips for (int k=0;klinked.size();k++) { @@ -2194,7 +2179,7 @@ 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); + add = olive::ActiveSequence->IsClipSelected(c, true); } if (add) {