/******************************************************************************* * Copyright (c) 2011, 2014 Wind River Systems, Inc. and others. 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: * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.ui.dialogs; import org.eclipse.core.runtime.Assert; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.DecoratingLabelProvider; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.layout.GridData; 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.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.tcf.te.runtime.concurrent.util.ExecutorsUtil; import org.eclipse.tcf.te.tcf.ui.navigator.ViewerSorter; import org.eclipse.tcf.te.ui.jface.dialogs.CustomTitleAreaDialog; import org.eclipse.tcf.te.ui.swt.SWTControlUtil; import org.eclipse.tcf.te.ui.views.navigator.DelegatingLabelProvider; /** * Selection dialog implementation. */ public abstract class AbstractArraySelectionDialog extends CustomTitleAreaDialog { // The table viewer /* default */ TableViewer viewer; // The selection. Will be filled in if "OK" is pressed private ISelection selection; /** * Constructor. * * @param parent The parent shell used to view the dialog, or <code>null</code>. * @param services The list of (remote) services the agents must provide to be selectable, or <code>null</code>. */ public AbstractArraySelectionDialog(Shell shell, String contextHelpId) { super(shell, contextHelpId); } /* (non-Javadoc) * @see org.eclipse.jface.dialogs.Dialog#isResizable() */ @Override protected boolean isResizable() { return true; } /** * Returns whether the dialog shall support multi selection or not. * <p> * The default implementation returns <code>true</code>. * * @return <code>True</code> if multi selection is supported, <code>false</code> otherwise. */ protected boolean supportsMultiSelection() { return false; } /** * Returns the table viewer instance. * * @return The table viewer instance or <code>null</code>. */ protected final TableViewer getViewer() { return viewer; } /* (non-Javadoc) * @see org.eclipse.tcf.te.ui.jface.dialogs.CustomTitleAreaDialog#createDialogAreaContent(org.eclipse.swt.widgets.Composite) */ @Override protected void createDialogAreaContent(Composite parent) { super.createDialogAreaContent(parent); setDialogTitle(getDialogTitle()); setTitle(getTitle()); setDefaultMessage(getDefaultMessage(), IMessageProvider.NONE); Composite comp = new Composite(parent, SWT.NONE); GridLayout gl = new GridLayout(2, false); gl.marginWidth = 0; gl.marginHeight = 0; comp.setLayout(gl); GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); comp.setLayoutData(gd); createTableAreaContent(comp); createButtonAreaContent(comp); } protected int getTableViewerStyle() { return (supportsMultiSelection() ? SWT.MULTI : SWT.SINGLE) | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL; } protected TableViewer createTableAreaContent(Composite parent) { // Create the tree viewer viewer = new TableViewer(parent, getTableViewerStyle()); // Configure the table final Table table = viewer.getTable(); TableLayout tl = new TableLayout(); tl.addColumnData(new ColumnWeightData(100)); table.setLayout(tl); GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); table.setLayoutData(gd); final TableColumn column = new TableColumn(table, SWT.LEFT); ColumnViewerToolTipSupport.enableFor(viewer); table.addControlListener(new ControlAdapter() { @Override public void controlResized(ControlEvent e) { column.setWidth(Math.max(200, table.getBounds().width - table.getBorderWidth()*2)); } }); viewer.setContentProvider(getContentProvider()); viewer.setLabelProvider(getLabelProvider()); // Subclasses may customize the viewer before setting the input configureTableViewer(viewer); viewer.setInput(getInput()); viewer.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent event) { onDoubleClick(); } }); viewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { updateEnablement(viewer); } }); viewer.refresh(); updateSelection(getSelection()); return viewer; } protected void onDoubleClick() { if (!viewer.getSelection().isEmpty()) { okPressed(); } } protected abstract void updateSelection(ISelection selection); protected IContentProvider getContentProvider() { return new ArrayContentProvider(); } protected IBaseLabelProvider getLabelProvider() { DelegatingLabelProvider labelProvider = new DelegatingLabelProvider(); return new DecoratingLabelProvider(labelProvider, labelProvider); } protected void refresh() { ExecutorsUtil.executeInUI(new Runnable() { @Override public void run() { viewer.setInput(getInput()); viewer.refresh(); updateEnablement(viewer); } }); } protected abstract Object getInput(); protected abstract void createButtonAreaContent(Composite parent); /* (non-Javadoc) * @see org.eclipse.jface.dialogs.TrayDialog#createButtonBar(org.eclipse.swt.widgets.Composite) */ @Override protected Control createButtonBar(Composite parent) { Control buttonBar = super.createButtonBar(parent); updateEnablement(viewer); return buttonBar; } /** * Update the enablement of the dialog widgets. * * @param viewer The table viewer. Must not be <code>null</code>. */ protected void updateEnablement(TableViewer viewer) { Assert.isNotNull(viewer); if (viewer.getTable().getSelectionCount() == 0) { viewer.getTable().setSelection(0); } // Adjust the OK button enablement Button okButton = getButton(IDialogConstants.OK_ID); int selCount = viewer.getTable().getSelectionCount(); boolean selOk = supportsMultiSelection() ? selCount > 0 : selCount == 1; SWTControlUtil.setEnabled(okButton, viewer.getTable().getItems().length > 0 && selOk); } /** * Configure the table viewer. * <p> * The default implementation does nothing. Subclasses may overwrite this * method to customize the table viewer before the input gets set. * * @param viewer The table viewer. Must not be <code>null</code>. */ protected void configureTableViewer(TableViewer viewer) { Assert.isNotNull(viewer); viewer.setSorter(new ViewerSorter()); } /** * Returns the dialog title. * * @return The dialog title. */ protected abstract String getDialogTitle(); /** * Returns the title. * * @return The title. */ protected abstract String getTitle(); /** * Returns the default message. * * @return The default message. */ protected abstract String getDefaultMessage(); /** * Returns the selection which had been set to the viewer at * the time of closing the dialog with either "OK" or "Cancel". * * @return The selection or <code>null</code>. */ public ISelection getSelection() { return selection; } /* (non-Javadoc) * @see org.eclipse.tcf.te.ui.jface.dialogs.CustomTitleAreaDialog#okPressed() */ @Override protected void okPressed() { selection = viewer.getSelection(); super.okPressed(); } /* (non-Javadoc) * @see org.eclipse.jface.dialogs.Dialog#cancelPressed() */ @Override protected void cancelPressed() { selection = null; super.cancelPressed(); } }