diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index a6811f3d5..87e8ab492 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -587,29 +587,34 @@ void TimelineWidget::AddGhost(TimelineViewGhostItem *ghost) views_.at(ghost->Track().type())->scene()->addItem(ghost); } -void TimelineWidget::StartRubberBandSelect(bool clear_current_selection) +void TimelineWidget::SetBlockLinksSelected(Block* block, bool selected) +{ + TimelineViewBlockItem* link_item; + + foreach (Block* link, block->linked_clips()) { + if ((link_item = block_items_[link]) != nullptr) { + link_item->setSelected(selected); + } + } +} + +void TimelineWidget::StartRubberBandSelect(bool select_links) { drag_origin_ = QCursor::pos(); rubberband_.show(); - if (!clear_current_selection) { - foreach (TimelineView* view, views_) { - rubberband_already_selected_.append(view->scene()->selectedItems()); - } - } - - MoveRubberBandSelect(); + MoveRubberBandSelect(select_links); } -void TimelineWidget::MoveRubberBandSelect() +void TimelineWidget::MoveRubberBandSelect(bool select_links) { QPoint rubberband_now = QCursor::pos(); rubberband_.setGeometry(QRect(mapFromGlobal(drag_origin_), mapFromGlobal(rubberband_now)).normalized()); - foreach (TimelineView* view, views_) { - view->DeselectAll(); + QList new_selected_list; + foreach (TimelineView* view, views_) { // Map global mouse coordinates to viewport QRect mapped_rect(view->viewport()->mapFromGlobal(drag_origin_), @@ -618,22 +623,41 @@ void TimelineWidget::MoveRubberBandSelect() // Normalize and get items in rect QList rubberband_items = view->items(mapped_rect.normalized()); - // Select them all - foreach (QGraphicsItem* item, rubberband_items) { - item->setSelected(true); + new_selected_list.append(rubberband_items); + } + + foreach (QGraphicsItem* item, rubberband_now_selected_) { + item->setSelected(false); + } + + foreach (QGraphicsItem* item, new_selected_list) { + item->setSelected(true); + + if (select_links) { + // Select the block's links + Block* b = static_cast(item)->block(); + SetBlockLinksSelected(b, true); + + // Add its links to the list + TimelineViewBlockItem* link_item; + foreach (Block* link, b->linked_clips()) { + if ((link_item = block_items_[link]) != nullptr) { + if (!new_selected_list.contains(link_item)) { + new_selected_list.append(link_item); + } + } + } } } - foreach (QGraphicsItem* item, rubberband_already_selected_) { - item->setSelected(true); - } + rubberband_now_selected_ = new_selected_list; } -void TimelineWidget::EndRubberBandSelect() +void TimelineWidget::EndRubberBandSelect(bool select_links) { - MoveRubberBandSelect(); + MoveRubberBandSelect(select_links); rubberband_.hide(); - rubberband_already_selected_.clear(); + rubberband_now_selected_.clear(); } void TimelineWidget::StartHandDrag() diff --git a/app/widget/timelinewidget/timelinewidget.h b/app/widget/timelinewidget/timelinewidget.h index 6c746b4cc..15900f7ba 100644 --- a/app/widget/timelinewidget/timelinewidget.h +++ b/app/widget/timelinewidget/timelinewidget.h @@ -166,6 +166,7 @@ private: rational ValidateOutTrimming(rational movement, const QVector ghosts, bool prevent_overwriting); virtual void ProcessDrag(const TimelineCoordinate &mouse_pos); + private: void InitiateDrag(const TimelineCoordinate &mouse_pos); @@ -180,6 +181,8 @@ private: bool trimming_allowed_; bool track_movement_allowed_; bool rubberband_selecting_; + + TrackType drag_track_type_; }; class ImportTool : public Tool @@ -281,13 +284,15 @@ private: virtual void MouseRelease(TimelineViewMouseEvent *event); }; + void SetBlockLinksSelected(Block *block, bool selected); + QPoint drag_origin_; - void StartRubberBandSelect(bool clear_current_selection); - void MoveRubberBandSelect(); - void EndRubberBandSelect(); + void StartRubberBandSelect(bool select_links); + void MoveRubberBandSelect(bool select_links); + void EndRubberBandSelect(bool select_links); QRubberBand rubberband_; - QList rubberband_already_selected_; + QList rubberband_now_selected_; void StartHandDrag(); void MoveHandDrag(); diff --git a/app/widget/timelinewidget/tool/import.cpp b/app/widget/timelinewidget/tool/import.cpp index 4a1b71129..b9ff804f2 100644 --- a/app/widget/timelinewidget/tool/import.cpp +++ b/app/widget/timelinewidget/tool/import.cpp @@ -212,7 +212,11 @@ void TimelineWidget::ImportTool::DragDrop(TimelineViewMouseEvent *event) QUndoCommand* command = new QUndoCommand(); - foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) { + QVector block_items(parent()->ghost_items_.size()); + + for (int i=0;ighost_items_.size();i++) { + TimelineViewGhostItem* ghost = parent()->ghost_items_.at(i); + ClipBlock* clip = new ClipBlock(); MediaInput* media = new MediaInput(); TransformDistort* transform = new TransformDistort(); @@ -224,9 +228,10 @@ void TimelineWidget::ImportTool::DragDrop(TimelineViewMouseEvent *event) transform->setParent(&node_memory_manager); opacity->setParent(&node_memory_manager); - clip->set_length(ghost->Length()); StreamPtr footage_stream = ghost->data(TimelineViewGhostItem::kAttachedFootage).value(); media->SetFootage(footage_stream); + + clip->set_length(ghost->Length()); clip->set_block_name(footage_stream->footage()->name()); NodeParam::ConnectEdge(opacity->texture_output(), clip->texture_input()); @@ -243,6 +248,17 @@ void TimelineWidget::ImportTool::DragDrop(TimelineViewMouseEvent *event) ghost->GetAdjustedIn(), command); } + + block_items.replace(i, clip); + + // Link any clips so far that share the same Footage with this one + for (int j=0;jghost_items_.at(j)->data(TimelineViewGhostItem::kAttachedFootage).value(); + + if (footage_compare->footage() == footage_stream->footage()) { + Block::Link(block_items.at(j), clip); + } + } } olive::undo_stack.pushIfHasChildren(command); diff --git a/app/widget/timelinewidget/tool/pointer.cpp b/app/widget/timelinewidget/tool/pointer.cpp index ace6ab09b..f3841ddb9 100644 --- a/app/widget/timelinewidget/tool/pointer.cpp +++ b/app/widget/timelinewidget/tool/pointer.cpp @@ -48,6 +48,11 @@ void TimelineWidget::PointerTool::MousePress(TimelineViewMouseEvent *event) bool selectable_item = (item != nullptr && item->flags() & QGraphicsItem::ItemIsSelectable); + if (selectable_item) { + // Cache the clip's type for use later + drag_track_type_ = item->Track().type(); + } + // If this item is already selected if (selectable_item && item->isSelected()) { @@ -55,6 +60,11 @@ void TimelineWidget::PointerTool::MousePress(TimelineViewMouseEvent *event) // If shift is held, deselect it if (event->GetModifiers() & Qt::ShiftModifier) { item->setSelected(false); + + // If not holding alt, deselect all links as well + if (!(event->GetModifiers() & Qt::AltModifier)) { + parent()->SetBlockLinksSelected(item->block(), false); + } } // Otherwise do nothing @@ -69,9 +79,14 @@ void TimelineWidget::PointerTool::MousePress(TimelineViewMouseEvent *event) if (selectable_item) { // Select this item item->setSelected(true); + + // If not holding alt, select all links as well + if (!(event->GetModifiers() & Qt::AltModifier)) { + parent()->SetBlockLinksSelected(item->block(), true); + } } else { // Start rubberband drag - parent()->StartRubberBandSelect(!(event->GetModifiers() & Qt::ShiftModifier)); + parent()->StartRubberBandSelect(!(event->GetModifiers() & Qt::AltModifier)); rubberband_selecting_ = true; } @@ -82,7 +97,7 @@ void TimelineWidget::PointerTool::MouseMove(TimelineViewMouseEvent *event) if (rubberband_selecting_) { // Process rubberband select - parent()->MoveRubberBandSelect(); + parent()->MoveRubberBandSelect(!(event->GetModifiers() & Qt::AltModifier)); } else if (!dragging_) { // Now that the cursor has moved, we will assume the intention is to drag @@ -104,7 +119,7 @@ void TimelineWidget::PointerTool::MouseMove(TimelineViewMouseEvent *event) void TimelineWidget::PointerTool::MouseRelease(TimelineViewMouseEvent *event) { if (rubberband_selecting_) { - parent()->EndRubberBandSelect(); + parent()->EndRubberBandSelect(!(event->GetModifiers() & Qt::AltModifier)); rubberband_selecting_ = false; return; @@ -288,7 +303,10 @@ void TimelineWidget::PointerTool::ProcessDrag(const TimelineCoordinate &mouse_po ghost->SetOutAdjustment(time_movement); // Track movement is only legal for moving, not for trimming - ghost->SetTrackAdjustment(track_movement); + // Also, we only move the clips on the same track type that the drag started from + if (ghost->Track().type() == drag_track_type_) { + ghost->SetTrackAdjustment(track_movement); + } const TrackReference& track = ghost->GetAdjustedTrack(); ghost->SetYCoords(parent()->GetTrackY(track), parent()->GetTrackHeight(track));