Bug 422501 - [CommonNavigator] Need ability to update transfers based on selection
Summary: [CommonNavigator] Need ability to update transfers based on selection
Status: NEW
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 4.2.1   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Platform UI Triaged CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-11-25 13:13 EST by Brian de Alwis CLA
Modified: 2013-11-28 14:01 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Brian de Alwis CLA 2013-11-25 13:13:06 EST
Eclipse 4.2.1, but this is unchanged to 4.4.

I'm using the CommonNavigator to represent a set of objects where each object type requires a different transfer mechanism.  I thus need to update the CommonNavigator's  DragSource's transfer list on selection.  It's worse actually, as a user can initiate a drag from an unselected object.

Fortunately this can be accommodated by hooking into the DND.DragStart event on the DragSource and then updating the targets based on the current item or selection.  My approach marks such dynamic drag assistants by implementing the ISelectionChangedListener.  They use the selectionChanged() event to recompute their transfers.

I then hack the CN to recompute the transfer list as follows.  The DragSource can be obtained from the CN's tree.  The CN's CommonDragAdapter is one of the DragSource's listeners.  On DND.DragStart, I walk the drag assistants and, if any implement ISelectionChangeListener, call their selectionChanged() to allow them to update their transfer list, and then recompute the targets for the DragSource.

    private void configureDynamicDNDTransfer() {
        final DragSource ds = (DragSource)getCommonViewer().getTree().getData(DND.DRAG_SOURCE_KEY);
        for(DragSourceListener listener : ds.getDragListeners()) {
            if(listener instanceof CommonDragAdapter) {
                final CommonDragAdapter cda = (CommonDragAdapter)listener;
                ds.addListener(DND.DragStart, new Listener() {                    
                    @Override
                    public void handleEvent(Event event) {
                        Tree tree = getCommonViewer().getTree();
                        assert event.widget == tree; 
                        // possible for drag to be initiated on an item that was not the selection
                        // but we need to update the transfers *now* on DragStart
                        ISelection selection = null;
                        TreeItem item = tree.getItem(new Point(event.x, event.y));
                        if(tree.getSelectionCount() == 0 || !ArrayUtils.contains(tree.getSelection(), item)) {
                            selection = new StructuredSelection(item.getData());
                            System.out.println("CN-DND-HACK: Changed selection: " + item.getData());
                        }
                        for(CommonDragAdapterAssistant assistant : getNavigatorContentService().getDnDService().getCommonDragAssistants()) {
                            if(assistant instanceof ISelectionChangedListener) {
                                ((ISelectionChangedListener)assistant).selectionChanged(new SelectionChangedEvent(getCommonViewer(), 
                                        selection == null ? getCommonViewer().getSelection() : selection));
                            }
                        }
                        // optimization: on set if they've changed
                        ds.setTransfer(cda.getSupportedDragTransfers());
                        System.out.println("CN-DND-HACK: Updated DragSource transfers");
                    }
                });
                return;
            }
        }
    }