- const shared_ptr<Signal> s = get_mouse_over_signal(_mouse_point);
-
- if(!s)
- return;
-
- QMenu menu(this);
- menu.addAction(_action_set_name);
- menu.addAction(_action_set_colour);
-
- _context_signal = s;
- menu.exec(event->globalPos());
- _context_signal.reset();
-}
-
-void Header::on_action_set_name_triggered()
-{
- shared_ptr<view::Signal> context_signal = _context_signal;
- if(!context_signal)
- return;
-
- const QString new_label = QInputDialog::getText(this, tr("Set Name"),
- tr("Name"), QLineEdit::Normal, context_signal->get_name());
-
- if(!new_label.isEmpty())
- context_signal->set_name(new_label);
+ const vector< shared_ptr<TraceTreeItem> > items(
+ view_.list_by_type<TraceTreeItem>());
+ vector< shared_ptr<TraceTreeItem> > selected_items(
+ make_filter_iterator(item_selected, items.begin(), items.end()),
+ make_filter_iterator(item_selected, items.end(), items.end()));
+ stable_sort(selected_items.begin(), selected_items.end(),
+ [](const shared_ptr<TraceTreeItem> &a, const shared_ptr<TraceTreeItem> &b) {
+ return a->visual_v_offset() < b->visual_v_offset(); });
+
+ shared_ptr<TraceGroup> group(new TraceGroup());
+ shared_ptr<TraceTreeItem> mouse_down_item(
+ std::dynamic_pointer_cast<TraceTreeItem>(mouse_down_item_));
+ shared_ptr<TraceTreeItem> focus_item(
+ mouse_down_item ? mouse_down_item : selected_items.front());
+
+ assert(focus_item);
+ assert(focus_item->owner());
+ focus_item->owner()->add_child_item(group);
+
+ // Set the group v_offset here before reparenting
+ group->force_to_v_offset(focus_item->layout_v_offset() +
+ focus_item->v_extents().first);
+
+ for (size_t i = 0; i < selected_items.size(); i++) {
+ const shared_ptr<TraceTreeItem> &r = selected_items[i];
+ assert(r->owner());
+ r->owner()->remove_child_item(r);
+ group->add_child_item(r);
+
+ // Put the items at 1-pixel offsets, so that restack will
+ // stack them in the right order
+ r->set_layout_v_offset(i);
+ }