From 7a23eb65f204cecdb93439933dd9d1efb62b6921 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Mon, 2 Jul 2018 16:08:54 +0100 Subject: [PATCH] added #71 --- mainwindow.cpp | 10 ++- olive.pro.user | 2 +- panels/project.cpp | 73 +++++++++++++++++- panels/project.h | 4 +- panels/timeline.cpp | 25 +++++-- panels/timeline.h | 6 ++ ui/timelinewidget.cpp | 169 ++++++++++++++++++++++++++++++------------ 7 files changed, 225 insertions(+), 64 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index f4c76a839..9ae020b49 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -36,10 +36,10 @@ void MainWindow::setup_layout() { panel_viewer->show(); panel_timeline->show(); - addDockWidget(Qt::TopDockWidgetArea, panel_project); - addDockWidget(Qt::TopDockWidgetArea, panel_effect_controls); - addDockWidget(Qt::TopDockWidgetArea, panel_viewer); - addDockWidget(Qt::BottomDockWidgetArea, panel_timeline); + addDockWidget(Qt::TopDockWidgetArea, panel_project); + addDockWidget(Qt::TopDockWidgetArea, panel_effect_controls); + addDockWidget(Qt::TopDockWidgetArea, panel_viewer); + addDockWidget(Qt::BottomDockWidgetArea, panel_timeline); } MainWindow::MainWindow(QWidget *parent) : @@ -146,6 +146,8 @@ void MainWindow::on_actionDelete_triggered() panel_timeline->delete_selection(false); } else if (panel_effect_controls->is_focused()) { panel_effect_controls->delete_clips(); + } else if (panel_project->is_focused()) { + panel_project->delete_selected_media(); } } diff --git a/olive.pro.user b/olive.pro.user index d05b2e03b..875e838e4 100644 --- a/olive.pro.user +++ b/olive.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/panels/project.cpp b/panels/project.cpp index ae26c1a70..f0dde2937 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -168,6 +169,66 @@ Media* Project::import_file(QString file) { return m; } +bool Project::is_focused() { + return ui->treeWidget->hasFocus(); +} + +void Project::delete_selected_media() { + QList items = ui->treeWidget->selectedItems(); + bool remove = true; + bool redraw = false; + + // check if media is in use + for (int i=0;iis_sequence && sequence != NULL) { + for (int j=0;jclip_count();j++) { + if (sequence->get_clip(j)->media == m) { + remove = false; + break; + } + } + if (!remove) { + QMessageBox confirm(this); + confirm.setWindowTitle("Delete media in use?"); + confirm.setText("The media '" + m->name + "' is currently used in the sequence. Deleting it will remove all instances in the sequence. Are you sure you want to do this?"); + QAbstractButton* yes_button = confirm.addButton(QMessageBox::Yes); + QAbstractButton* skip_button = confirm.addButton("Skip", QMessageBox::NoRole); + QAbstractButton* abort_button = confirm.addButton(QMessageBox::Abort); + confirm.exec(); + if (confirm.clickedButton() == yes_button) { + // remove all clips referencing this media + for (int j=0;jclip_count();j++) { + if (sequence->get_clip(j)->media == m) { + sequence->delete_clip(j); + } + } + remove = true; + redraw = true; + } else if (confirm.clickedButton() == skip_button) { + items.removeAt(i); + i--; + remove = true; + } + } + } + } + + // remove + if (remove) { + for (int i=0;iredraw_all_clips(true); + } +} + void Project::process_file_list(QStringList& files) { for (int i=0;isetData(0, Qt::UserRole + 1, QVariant::fromValue(reinterpret_cast(media))); } -void Project::remove_item(int i) { - Media* m = get_media_from_tree(ui->treeWidget->topLevelItem(i)); +void Project::delete_media(QTreeWidgetItem* item) { + Media* m = get_media_from_tree(item); if (m->is_sequence) { + if (sequence == m->sequence) { + set_sequence(NULL); + } delete m->sequence; } delete m; - ui->treeWidget->takeTopLevelItem(i); project_changed = true; } void Project::clear() { while (ui->treeWidget->topLevelItemCount() > 0) { - remove_item(0); + QTreeWidgetItem* item = ui->treeWidget->topLevelItem(0); + delete_media(item); + delete item; } } diff --git a/panels/project.h b/panels/project.h index 6efd39f5a..39243c162 100644 --- a/panels/project.h +++ b/panels/project.h @@ -25,12 +25,14 @@ class Project : public QDockWidget public: explicit Project(QWidget *parent = 0); ~Project(); + bool is_focused(); void clear(); Media* import_file(QString url); void import_dialog(); void new_sequence(Sequence* s); QString get_next_sequence_name(); - void remove_item(int i); + void delete_media(QTreeWidgetItem* item); + void delete_selected_media(); void process_file_list(QStringList& files); void new_project(); diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 37d6f6d7d..4707a3fd3 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -22,10 +22,23 @@ Timeline::Timeline(QWidget *parent) : QDockWidget(parent), ui(new Ui::Timeline) { - selecting = moving_init = moving_proc = splitting = importing = playing = trim_in = snapped = false; + selecting = false; + moving_init = false; + moving_proc = false; + splitting = false; + importing = false; + playing = false; + trim_in = false; + snapped = false; + rect_select_init = false; + rect_select_proc = false; edit_tool_also_seeks = false; snapping = true; - last_frame = playhead = snap_point = cursor_frame = cursor_track = 0; + last_frame = 0; + playhead = 0; + snap_point = 0; + cursor_frame = 0; + cursor_track = 0; trim_target = -1; ui->setupUi(this); @@ -428,11 +441,13 @@ void Timeline::split_clip_and_relink(Clip* clip, long frame, bool relink) { QVector pre_clips; QVector post_clips; - pre_clips.append(clip); - post_clips.append(sequence->split_clip(clip, frame)); + Clip* post = sequence->split_clip(clip, frame); // if alt is not down, split clips links too - if (relink) { + if (post != NULL && relink) { + pre_clips.append(clip); + post_clips.append(post); + bool original_clip_is_selected = is_clip_selected(clip); // find linked clips of old clip diff --git a/panels/timeline.h b/panels/timeline.h index 0f7050d06..94d3915a2 100644 --- a/panels/timeline.h +++ b/panels/timeline.h @@ -127,6 +127,12 @@ public: bool is_clip_selected(Clip* clip); void delete_selection(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; diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index c181ce671..ddda9e663 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -189,6 +189,14 @@ void TimelineWidget::mousePressEvent(QMouseEvent *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); + 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: @@ -197,45 +205,44 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { if (track_resizing) { track_resize_mouse_cache = event->pos().y(); panel_timeline->moving_init = true; - } else if (clip_index >= 0) { - Clip* c = sequence->get_clip(clip_index); - if (c != NULL && panel_timeline->is_clip_selected(c)) { - // TODO if shift is down, deselect it - } else { - // if "shift" is not down - if (!(event->modifiers() & Qt::ShiftModifier)) { - panel_timeline->selections.clear(); - } + } else { + // if "shift" is not down + if (!shift) { + panel_timeline->selections.clear(); + } - Clip* clip = sequence->get_clip(clip_index); - if (clip != NULL) { - panel_timeline->selections.append({clip->timeline_in, clip->timeline_out, clip->track}); + if (clip_index >= 0) { + Clip* c = sequence->get_clip(clip_index); + if (panel_timeline->is_clip_selected(c)) { + if (shift) { + // TODO if shift is down, deselect it + } + } else { + Clip* clip = sequence->get_clip(clip_index); + if (clip != NULL) { + panel_timeline->selections.append({clip->timeline_in, clip->timeline_out, clip->track}); - // if alt is not down, select links - if (!(event->modifiers() & Qt::AltModifier)) { - for (int i=0;ilinked.size();i++) { - Clip* link = sequence->get_clip(c->linked.at(i)); - if (!panel_timeline->is_clip_selected(link)) { - panel_timeline->selections.append({link->timeline_in, link->timeline_out, link->track}); + // if alt is not down, select links + if (!(event->modifiers() & Qt::AltModifier)) { + for (int i=0;ilinked.size();i++) { + Clip* link = sequence->get_clip(c->linked.at(i)); + if (!panel_timeline->is_clip_selected(link)) { + panel_timeline->selections.append({link->timeline_in, link->timeline_out, link->track}); + } } } } } + panel_timeline->moving_init = true; + } else { + panel_timeline->rect_select_init = true; } - panel_timeline->moving_init = true; - } else { - panel_timeline->selections.clear(); + panel_timeline->repaint_timeline(); } - panel_timeline->repaint_timeline(); } break; case TIMELINE_TOOL_EDIT: if (panel_timeline->edit_tool_also_seeks) panel_timeline->seek(panel_timeline->drag_frame_start); - if ((event->modifiers() & Qt::ShiftModifier)) { - panel_timeline->selection_offset = panel_timeline->selections.size(); - } else { - panel_timeline->selection_offset = 0; - } panel_timeline->selecting = true; break; case TIMELINE_TOOL_RAZOR: @@ -353,6 +360,8 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { // remove duplicate selections panel_timeline->clean_up_selections(panel_timeline->selections); repaint = true; + } else if (panel_timeline->rect_select_proc) { + repaint = true; } // destroy all ghosts @@ -363,6 +372,8 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { 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(); @@ -789,6 +800,73 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // redraw clips since we changed them if (repaint) panel_timeline->redraw_all_clips(true); + } 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); + for (int j=0;jlinked.size();j++) { + session_clips.append(sequence->get_clip(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]; + 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) { track_resizing = false; @@ -988,6 +1066,19 @@ void TimelineWidget::paintEvent(QPaintEvent*) { } } + // 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); + p.setPen(QColor(204, 204, 204)); + p.drawRect(rect_select); + p.fillRect(rect_select, QColor(0, 0, 0, 32)); + } + // Draw ghosts for (int i=0;ighosts.size();i++) { const Ghost& g = panel_timeline->ghosts.at(i); @@ -1041,24 +1132,6 @@ bool TimelineWidget::is_track_visible(int track) { // ************************************** int TimelineWidget::getTrackFromScreenPoint(int y) { -// if (bottom_align) { -// y = -(y - rect().height()); -// } -// y--; -// int height_measure = 0; -// int counter = (bottom_align && y > 0) ? -1 : 0; -// int track_height = panel_timeline->calculate_track_height(counter, -1); -// while (y > height_measure+track_height) { -// if (show_track_lines && counter != -1) y--; -// height_measure += track_height; -// if (bottom_align && y > 0) { -// counter--; -// } else { -// counter++; -// } -// track_height = panel_timeline->calculate_track_height(counter, -1); -// } -// return counter; if (bottom_align) { y = -(y - rect().height()); } @@ -1095,10 +1168,8 @@ int TimelineWidget::getScreenPointFromTrack(int track) { int TimelineWidget::getClipIndexFromCoords(long frame, int track) { for (int i=0;iclip_count();i++) { Clip* c = sequence->get_clip(i); - if (c != NULL && c->track == track) { - if (frame >= c->timeline_in && frame < c->timeline_out) { - return i; - } + if (c != NULL && c->track == track && frame >= c->timeline_in && frame < c->timeline_out) { + return i; } } return -1;