org.springframework.ide.eclipse.boot.dash.views.sections.BootDashElementsTableSection.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.ide.eclipse.boot.dash.views.sections.BootDashElementsTableSection.java

Source

/*******************************************************************************
 * Copyright (c) 2015 Pivotal, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Pivotal, Inc. - initial API and implementation
 *******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.views.sections;

import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.preferences.ViewSettingsDialog;
import org.springframework.ide.eclipse.boot.dash.livexp.MultiSelection;
import org.springframework.ide.eclipse.boot.dash.livexp.MultiSelectionSource;
import org.springframework.ide.eclipse.boot.dash.livexp.ObservableSet;
import org.springframework.ide.eclipse.boot.dash.livexp.ui.ReflowUtil;
import org.springframework.ide.eclipse.boot.dash.model.BootDashElement;
import org.springframework.ide.eclipse.boot.dash.model.BootDashElementUtil;
import org.springframework.ide.eclipse.boot.dash.model.BootDashModel;
import org.springframework.ide.eclipse.boot.dash.model.BootDashModel.ElementStateListener;
import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel;
import org.springframework.ide.eclipse.boot.dash.model.Filter;
import org.springframework.ide.eclipse.boot.dash.model.UserInteractions;
import org.springframework.ide.eclipse.boot.dash.util.HiddenElementsLabel;
import org.springframework.ide.eclipse.boot.dash.util.Stylers;
import org.springframework.ide.eclipse.boot.dash.views.AbstractBootDashElementsAction;
import org.springframework.ide.eclipse.boot.dash.views.AddRunTargetAction;
import org.springframework.ide.eclipse.boot.dash.views.BootDashActions;
import org.springframework.ide.eclipse.boot.dash.views.BootDashCellLabelProvider;
import org.springframework.ide.eclipse.boot.dash.views.BootDashContentProvider;
import org.springframework.ide.eclipse.boot.dash.views.RunStateAction;
import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression;
import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable;
import org.springsource.ide.eclipse.commons.livexp.core.UIValueListener;
import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult;
import org.springsource.ide.eclipse.commons.livexp.core.ValueListener;
import org.springsource.ide.eclipse.commons.livexp.ui.Disposable;
import org.springsource.ide.eclipse.commons.livexp.ui.IPageWithSections;
import org.springsource.ide.eclipse.commons.livexp.ui.PageSection;
import org.springsource.ide.eclipse.commons.ui.UiUtil;

/**
 * A section that contains a table viewer widget displaying Boot Dash Elements from a model.
 *
 * @author Kris De Volder
 */
public class BootDashElementsTableSection extends PageSection implements MultiSelectionSource, Disposable {

    public class CustomTableViewer extends TableViewer {

        private LiveVariable<Integer> hiddenElementCount = new LiveVariable<Integer>(0);

        public CustomTableViewer(Composite page, int style) {
            super(page, style);
        }

        @Override
        protected Object[] getFilteredChildren(Object parent) {
            int totalElements = sizeof(getRawChildren(parent));
            Object[] filteredElements = super.getFilteredChildren(parent);
            hiddenElementCount.setValue(totalElements - sizeof(filteredElements));
            return filteredElements;
        }

        private int sizeof(Object[] os) {
            if (os != null) {
                return os.length;
            }
            return 0;
        }

    }

    private static final String COLUMN_DATA = "boot-dash-column-data";

    private CustomTableViewer tv;
    private BootDashViewModel viewModel;
    private BootDashModel model;
    private MultiSelection<BootDashElement> selection;
    private BootDashActions actions;
    private UserInteractions ui;
    private LiveVariable<ViewerCell> hoverCell;
    private LiveExpression<BootDashElement> hoverElement;
    private LiveExpression<Filter<BootDashElement>> searchFilterModel;

    final private ValueListener<Filter<BootDashElement>> FILTER_LISTENER = new ValueListener<Filter<BootDashElement>>() {
        public void gotValue(LiveExpression<Filter<BootDashElement>> exp, Filter<BootDashElement> value) {
            tv.refresh();
            final Table t = tv.getTable();
            t.getDisplay().asyncExec(new Runnable() {
                public void run() {
                    Composite parent = t.getParent();
                    parent.layout();
                }
            });
        }
    };

    final private UIValueListener<Set<BootDashElement>> ELEMENTS_SET_LISTENER = new UIValueListener<Set<BootDashElement>>() {
        @Override
        protected void uiGotValue(LiveExpression<Set<BootDashElement>> exp, Set<BootDashElement> value) {
            final Control control = tv.getControl();
            if (!control.isDisposed()) {
                tv.refresh();
                control.getDisplay().asyncExec(new Runnable() {
                    public void run() {
                        control.getParent().layout();
                    }
                });
            }
        }
    };

    final private ElementStateListener ELEMENT_STATE_LISTENER = new ElementStateListener() {
        public void stateChanged(final BootDashElement e) {
            Display.getDefault().asyncExec(new Runnable() {
                public void run() {
                    if (tv != null && !tv.getControl().isDisposed()) {
                        tv.update(e, null);
                    }
                }
            });
        }
    };

    private LiveVariable<MouseEvent> tableMouseEvent;

    private ValueListener<MouseEvent> tableMouseEventListener;
    private Stylers stylers;

    private BootDashColumnModel[] columnModels;

    public BootDashElementsTableSection(IPageWithSections owner, BootDashViewModel viewModel, BootDashModel model,
            LiveExpression<Filter<BootDashElement>> searchFilterModel, LiveVariable<MouseEvent> tableMouseEvent,
            UserInteractions ui) {
        super(owner);
        this.viewModel = viewModel;
        this.model = model;
        this.ui = ui;
        this.searchFilterModel = searchFilterModel;
        this.tableMouseEvent = tableMouseEvent;
    }

    class NameSorter extends ViewerSorter {
    }

    protected CellLabelProvider getLabelProvider(BootDashColumn columnType) {
        return new BootDashCellLabelProvider(tv, columnType, stylers);
    }

    @Override
    public void createContents(Composite page) {
        // Cleanup first
        if (tv != null && !tv.getControl().isDisposed()) {
            tv.getControl().dispose();
        }

        // Initialize column table state objects
        initColumnModels();

        // Create table viewer again and attach all listeners.
        tv = new CustomTableViewer(page, SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION | SWT.NO_SCROLL); // Note: No SWT.SCROLL options.
        // Assumes its up to the page to be scrollable.
        tv.setContentProvider(new BootDashContentProvider(model));
        tv.setSorter(new NameSorter());
        tv.setInput(model);
        tv.getTable().setHeaderVisible(true);
        tv.getTable().setLinesVisible(true);

        stylers = new Stylers(tv.getTable().getFont());

        GridDataFactory.fillDefaults().grab(true, false).applyTo(tv.getControl());

        HiddenElementsLabel hiddenElementsLabel = new HiddenElementsLabel(page, tv.hiddenElementCount);

        Arrays.sort(columnModels, BootDashColumnModel.INDEX_COMPARATOR);
        for (final BootDashColumnModel columnModel : columnModels) {
            if (columnModel.getVisibility()) {
                createColumn(columnModel);
            }
        }
        addSingleClickHandling();

        tv.getControl().addControlListener(new ControlListener() {
            public void controlResized(ControlEvent e) {
                ReflowUtil.reflow(owner, tv.getControl());
            }

            public void controlMoved(ControlEvent e) {
            }
        });

        actions = new BootDashActions(viewModel, model, getSelection(), ui);
        hookContextMenu();

        // Careful, either selection or tableviewer might be created first.
        // in either case we must make sure the listener is added when *both*
        // have been created.
        if (selection != null) {
            addTableSelectionListener();
        }

        tv.addDoubleClickListener(new IDoubleClickListener() {
            public void doubleClick(DoubleClickEvent event) {
                if (selection != null) {
                    BootDashElement selected = selection.getSingle();
                    if (selected != null) {
                        String url = BootDashElementUtil.getUrl(selected, selected.getDefaultRequestMappingPath());
                        if (url != null) {
                            UiUtil.openUrl(url);
                        }
                    }
                }
            }
        });

        model.getElements().addListener(ELEMENTS_SET_LISTENER);

        model.addElementStateListener(ELEMENT_STATE_LISTENER);

        if (searchFilterModel != null) {
            searchFilterModel.addListener(FILTER_LISTENER);
            tv.addFilter(new ViewerFilter() {
                @Override
                public boolean select(Viewer viewer, Object parentElement, Object element) {
                    if (searchFilterModel.getValue() != null && element instanceof BootDashElement) {
                        return searchFilterModel.getValue().accept((BootDashElement) element);
                    }
                    return true;
                }
            });
        }

        tv.getTable().addDisposeListener(new DisposeListener() {
            @Override
            public void widgetDisposed(DisposeEvent e) {
                tableMouseEvent.setValue(null);

                model.getElements().removeListener(ELEMENTS_SET_LISTENER);

                model.removeElementStateListener(ELEMENT_STATE_LISTENER);

                if (searchFilterModel != null) {
                    searchFilterModel.removeListener(FILTER_LISTENER);
                }

                hoverCell = null;
                hoverElement = null;

                if (tableMouseEventListener != null) {
                    tableMouseEvent.removeListener(tableMouseEventListener);
                    tableMouseEventListener = null;
                }
                if (actions != null) {
                    actions.dispose();
                    actions = null;
                }
                if (stylers != null) {
                    stylers.dispose();
                    stylers = null;
                }
            }
        });

        addDragSupport(tv);

        ReflowUtil.reflow(owner, tv.getControl());
    }

    private void initColumnModels() {
        if (model.getRunTarget() == null || model.getRunTarget().getAllColumns().length == 0) {
            columnModels = new BootDashColumnModel[0];
        } else {
            columnModels = new BootDashColumnModel[model.getRunTarget().getAllColumns().length];
            EnumSet<BootDashColumn> defaultVisibleColumns = EnumSet
                    .copyOf(Arrays.asList(model.getRunTarget().getDefaultColumns()));
            for (int i = 0; i < model.getRunTarget().getAllColumns().length; i++) {
                BootDashColumn column = model.getRunTarget().getAllColumns()[i];
                columnModels[i] = new BootDashColumnModel(column, defaultVisibleColumns.contains(column), i,
                        model.getRunTarget().getId());
            }
        }
    }

    public void addSingleClickHandling() {
        final AbstractBootDashElementsAction[] singleClickActions = new AbstractBootDashElementsAction[model
                .getRunTarget().getAllColumns().length];
        boolean hasSingleClickActions = false;
        for (int i = 0; i < model.getRunTarget().getAllColumns().length; i++) {
            BootDashColumn columnType = model.getRunTarget().getAllColumns()[i];
            BootDashActionFactory factory = columnType.getSingleClickAction();
            if (factory != null) {
                hasSingleClickActions = true;
                singleClickActions[i] = factory.create(viewModel, getHoverElement(), ui);
            }
        }

        if (hasSingleClickActions) {
            final Cursor defaultCursor = tv.getTable().getCursor();
            getHoverCell().addListener(new ValueListener<ViewerCell>() {
                public void gotValue(LiveExpression<ViewerCell> exp, ViewerCell cell) {
                    Table table = tv.getTable();
                    if (cell != null) {
                        int colIdx = cell.getColumnIndex();
                        AbstractBootDashElementsAction action = singleClickActions[colIdx];
                        if (action != null && action.isEnabled()) {
                            table.setCursor(CursorProviders.HAND_CURSOR.getCursor(cell));
                            return;
                        }
                    }
                    table.setCursor(defaultCursor);
                }
            });

            tv.getTable().addMouseListener(new MouseAdapter() {
                public void mouseDown(MouseEvent e) {
                    if (tableMouseEvent != null) {
                        tableMouseEvent.setValue(e);
                    }

                    ViewerCell cell = tv.getCell(new Point(e.x, e.y));
                    if (cell != null) {
                        Object el = cell.getElement();
                        if (el instanceof BootDashElement) {
                            int idx = cell.getColumnIndex();
                            AbstractBootDashElementsAction action = singleClickActions[idx];
                            if (action != null) {
                                action.run();
                            }
                        }
                    }
                }
            });
        }
    }

    /**
     * Selection used for 'single click' actions. This represents the
     * element the mouse is hovering over.
     */
    private synchronized LiveExpression<ViewerCell> getHoverCell() {
        if (hoverCell == null) {
            hoverCell = new LiveVariable<ViewerCell>();
            tv.getTable().addMouseMoveListener(new MouseMoveListener() {
                public void mouseMove(MouseEvent e) {
                    Point pos = new Point(e.x, e.y);
                    hoverCell.setValue(tv.getCell(pos));
                }
            });
        }
        return hoverCell;
    }

    /**
     * Selection used for 'single click' actions. This represents the
     * element the mouse is hovering over.
     */
    private synchronized LiveExpression<BootDashElement> getHoverElement() {
        if (hoverElement == null) {
            final LiveExpression<ViewerCell> hoverCell = getHoverCell();
            hoverElement = new LiveExpression<BootDashElement>() {
                {
                    dependsOn(hoverCell);
                }

                protected BootDashElement compute() {
                    ViewerCell cell = hoverCell.getValue();
                    if (cell != null) {
                        Object e = cell.getElement();
                        if (e instanceof BootDashElement) {
                            return (BootDashElement) e;
                        }
                    }
                    return null;
                }
            };
        }
        return hoverElement;
    }

    private void hookContextMenu() {
        MenuManager menuMgr = new MenuManager("#PopupMenu");
        menuMgr.setRemoveAllWhenShown(true);
        menuMgr.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager manager) {
                fillContextMenu(manager);
            }
        });
        Menu menu = menuMgr.createContextMenu(tv.getControl());
        tv.getControl().setMenu(menu);
    }

    private void fillContextMenu(IMenuManager manager) {
        for (RunStateAction a : actions.getRunStateActions()) {
            manager.add(a);
        }
        manager.add(actions.getOpenConfigAction());
        manager.add(actions.getOpenConsoleAction());
        manager.add(actions.getShowPropertiesViewAction());
        for (AddRunTargetAction a : actions.getAddRunTargetActions()) {
            manager.add(a);
        }

        IAction removeTargetAction = actions.getRemoveRunTargetAction();
        if (removeTargetAction != null) {
            manager.add(removeTargetAction);
        }

        IAction refreshAction = actions.getRefreshRunTargetAction();
        if (refreshAction != null) {
            manager.add(refreshAction);
        }

        IAction deleteAppsAction = actions.getDeleteApplicationsAction();
        if (deleteAppsAction != null) {
            manager.add(deleteAppsAction);
        }

        IAction updatePasswordAction = actions.getUpdatePasswordAction();
        if (updatePasswordAction != null) {
            manager.add(updatePasswordAction);
        }

        addPreferedConfigSelectionMenu(manager);

        if (tv.getTable().getColumnCount() > 0) {
            manager.add(new RestoreDefaultColumnsAction("Restore Default Columns"));
            manager.add(new CustomizeColumnsAction("Customize Columns..."));
        }

        //      manager.add
        //      manager.add(new Separator());
        //      manager.add(refreshAction);
        //      manager.add(action2);
        // Other plug-ins can contribute there actions here
        //      manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
    }

    private void addPreferedConfigSelectionMenu(IMenuManager parent) {
        BootDashElement element = selection.getSingle();
        if (element != null) {
            ILaunchConfiguration defaultConfig = element.getPreferredConfig();
            List<ILaunchConfiguration> allConfigs = element.getTarget().getLaunchConfigs(element);
            if (!allConfigs.isEmpty()) {
                MenuManager menu = new MenuManager("Default Config...");
                parent.add(menu);
                for (ILaunchConfiguration conf : allConfigs) {
                    menu.add(actions.selectDefaultConfigAction(element, defaultConfig, conf));
                }
            }
        }
    }

    @Override
    public LiveExpression<ValidationResult> getValidator() {
        return OK_VALIDATOR;
    }

    @Override
    public synchronized MultiSelection<BootDashElement> getSelection() {
        if (selection == null) {
            selection = MultiSelection.from(BootDashElement.class, new ObservableSet<BootDashElement>() {
                @Override
                protected Set<BootDashElement> compute() {
                    if (tv != null) {
                        ISelection s = tv.getSelection();
                        if (s instanceof IStructuredSelection) {
                            Object[] elements = ((IStructuredSelection) s).toArray();
                            if (elements != null && elements.length > 0) {
                                HashSet<BootDashElement> set = new HashSet<BootDashElement>();
                                for (Object o : elements) {
                                    set.add((BootDashElement) o);
                                }
                                return set;
                            }
                        }
                    }
                    return Collections.emptySet();
                }
            });
        }
        if (tv != null) {
            addTableSelectionListener();
        }
        tableMouseEvent.addListener(tableMouseEventListener = new ValueListener<MouseEvent>() {
            public void gotValue(LiveExpression<MouseEvent> exp, MouseEvent evt) {
                //When user clicks in another table than the current table. Clear the current-table's selection
                if (evt != null) {
                    if (evt.widget != tv.getTable()) { //only interested in clicks in other tables.
                        if ((evt.stateMask & SWT.CTRL) == 0) { //CTRL not held down.
                            tv.setSelection(StructuredSelection.EMPTY);
                        }
                    }
                }
            }
        });
        return selection;
    }

    private void addTableSelectionListener() {
        tv.setSelection(new StructuredSelection(
                Arrays.asList(selection.getValue().toArray(new BootDashElement[selection.getValue().size()]))));
        tv.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                selection.getElements().refresh();
            }
        });
    }

    public void dispose() {
    }

    private void createColumn(final BootDashColumnModel columnModel) {
        TableViewerColumn viewer = new TableViewerColumn(tv, columnModel.getAllignment());
        final TableColumn tc = viewer.getColumn();
        tc.setText(columnModel.getLabel());
        tc.setWidth(columnModel.getWidth());
        tc.setResizable(true);
        tc.setMoveable(true);
        tc.setData(COLUMN_DATA, columnModel);

        viewer.setLabelProvider(getLabelProvider(columnModel.getType()));

        if (columnModel.getEditingSupport() != null) {
            viewer.setEditingSupport(columnModel.getEditingSupport().createEditingSupport(tv,
                    getSelection().toSingleSelection(), viewModel, stylers));
        }

        tc.addControlListener(new ControlAdapter() {

            private int currentIndex = tv.getTable().getColumnCount() - 1;

            @Override
            public void controlMoved(ControlEvent e) {
                int i = 0;
                int[] order = tv.getTable().getColumnOrder();
                while (i < order.length && tv.getTable().getColumn(order[i]) != tc) {
                    i++;
                }
                /*
                 * Move event is caused by resizing as well therefore update the
                 * column order if it was changed indeed
                 */
                if (i != currentIndex) {
                    columnModel.setIndex(i);
                    currentIndex = i;
                }
            }

            @Override
            public void controlResized(ControlEvent e) {
                columnModel.setWidth(tc.getWidth());
                ReflowUtil.reflow(owner, tv.getControl());
            }

        });
    }

    private class RestoreDefaultColumnsAction extends Action {

        RestoreDefaultColumnsAction(String label) {
            super(label);
        }

        @Override
        public boolean isEnabled() {
            return tv.getTable().getColumnCount() > 0;
        }

        @Override
        public void run() {
            for (BootDashColumnModel columnModel : columnModels) {
                columnModel.restoreDefaults();
            }
            BootDashElementsTableSection.this.createContents(tv.getControl().getParent());
        }
    }

    private class CustomizeColumnsAction extends Action {

        CustomizeColumnsAction(String label) {
            super(label);
        }

        @Override
        public boolean isEnabled() {
            return tv.getTable().getColumnCount() > 0;
        }

        @Override
        public void run() {
            ViewSettingsDialog viewSettingsDialog = new ViewSettingsDialog(
                    PlatformUI.getWorkbench().getDisplay().getActiveShell()) {

                private Button[] editors;
                private BootDashColumnModel[] sortedModels;

                @Override
                protected Control createDialogArea(Composite parent) {
                    Composite top = (Composite) super.createDialogArea(parent);

                    Group group = new Group(top, SWT.NONE);
                    group.setText("Columns Visibility");
                    group.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
                    group.setLayout(new GridLayout());

                    editors = new Button[columnModels.length];

                    sortedModels = Arrays.copyOf(columnModels, columnModels.length);
                    Arrays.sort(sortedModels, BootDashColumnModel.DEFAULT_INDEX_COMPARATOR);
                    for (int i = 0; i < sortedModels.length; i++) {
                        Button editor = new Button(group, SWT.CHECK);
                        editor.setText(sortedModels[i].getType().getLongLabel());
                        editor.setSelection(sortedModels[i].getVisibility());
                        editors[i] = editor;
                    }

                    Dialog.applyDialogFont(top);

                    return top;
                }

                @Override
                protected void performDefaults() {
                    for (int i = 0; i < editors.length; i++) {
                        editors[i].setSelection(sortedModels[i].getDefaultVisibility());
                    }
                }

                @Override
                protected void okPressed() {
                    for (int i = 0; i < editors.length; i++) {
                        sortedModels[i].setVisibility(editors[i].getSelection());
                    }
                    super.okPressed();
                    BootDashElementsTableSection.this.createContents(tv.getControl().getParent());
                }

                @Override
                protected void configureShell(Shell newShell) {
                    super.configureShell(newShell);
                    newShell.setText("Columns Settings");
                }

            };
            viewSettingsDialog.open();
        }

    }

    private void addDragSupport(final TableViewer viewer) {

        if (model.getRunTarget().canDeployAppsFrom()) {
            int ops = DND.DROP_COPY;

            Transfer[] transfers = new Transfer[] { LocalSelectionTransfer.getTransfer() };

            DragSourceAdapter listener = new DragSourceAdapter() {
                @Override
                public void dragSetData(DragSourceEvent event) {
                    IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
                    event.data = selection.getFirstElement();
                    LocalSelectionTransfer.getTransfer().setSelection(selection);
                }

                @Override
                public void dragStart(DragSourceEvent event) {
                    if (event.detail == DND.DROP_NONE || event.detail == DND.DROP_DEFAULT) {
                        event.detail = DND.DROP_COPY;
                    }
                    dragSetData(event);
                }
            };

            viewer.addDragSupport(ops, transfers, listener);
        }
    }
}