/*******************************************************************************
* Copyright (c) 2016 Bruno Medeiros and other Contributors.
* 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:
* Bruno Medeiros - initial API and implementation
*******************************************************************************/
package melnorme.lang.ide.ui.build;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
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.ui.PlatformUI;
import org.eclipse.ui.dialogs.SelectionDialog;
import _org.eclipse.debug.internal.ui.SWTFactory;
import melnorme.lang.ide.core.LangCore;
import melnorme.lang.ide.ui.LangImages;
import melnorme.lang.ide.ui.LangUIPlugin;
/**
* This class provides the framework for a general selection dialog class.
*
* @see AbstractDebugCheckboxSelectionDialog
*
* @since 3.3
*/
abstract class AbstractDebugSelectionDialog extends SelectionDialog {
public static String EMPTY_STRING = "";
protected StructuredViewer fViewer = null;
/**
* Constructor
* @param parentShell the parent shell
*/
public AbstractDebugSelectionDialog(Shell parentShell) {
super(parentShell);
setDialogBoundsSettings(getDialogBoundsSettings(), Dialog.DIALOG_PERSISTSIZE);
}
/**
* returns the dialog settings area id
* @return the id of the dialog settings area
*/
protected abstract String getDialogSettingsId();
/**
* Returns the object to use as input for the viewer
* @return the object to use as input for the viewer
*/
protected abstract Object getViewerInput();
/**
* Create and return a viewer to use in this dialog.
*
* @param parent the composite the viewer should be created in
* @return the viewer to use in the dialog
*/
protected abstract StructuredViewer createViewer(Composite parent);
/**
* Returns if the dialog and/or current selection is/are valid.
* This method is polled when selection changes are made to update the enablement
* of the OK button by default
* @return true if the dialog is in a valid state, false otherwise
*
* @since 3.4
*/
protected abstract boolean isValid();
/**
* Returns the content provider for the viewer
* @return the content provider for the viewer
*/
protected IContentProvider getContentProvider() {
//by default return a simple array content provider
return new ArrayContentProvider();
}
protected abstract IBaseLabelProvider getLabelProvider();
/**
* Returns the help context id for this dialog
* @return the help context id for this dialog
*/
abstract protected String getHelpContextId();
/**
* This method allows listeners to be added to the viewer after it
* is created.
*/
/**
* This method allows listeners to be added to the viewer. Called
* after the viewer has been created and its input set.
*
* @param viewer the viewer returned by createViewer()
*/
protected void addViewerListeners(StructuredViewer viewer){
//do nothing by default
}
/**
* This method allows custom controls to be added before the viewer
* @param parent the parent composite to add these custom controls to
*/
protected void addCustomHeaderControls(Composite parent) {
//do nothing by default
}
/**
* This method allows custom controls to be added after the viewer
* @param parent the parent composite to add these controls to
*/
protected void addCustomFooterControls(Composite parent) {
//do nothing by default
}
/**
* This method allows the newly created controls to be initialized.
* This method is called only once all controls have been created from the
* <code>createContents</code> method.
*
* By default this method initializes the OK button control.
*/
protected void initializeControls() {
getButton(IDialogConstants.OK_ID).setEnabled(isValid());
}
/**
* Returns the viewer used to display information in this dialog.
* Can be <code>null</code> if the viewer has not been created.
* @return viewer used in this dialog
*/
protected Viewer getViewer(){
return fViewer;
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#createContents(org.eclipse.swt.widgets.Composite)
*/
@Override
protected Control createContents(Composite parent) {
Composite comp = (Composite) super.createContents(parent);
initializeControls();
return comp;
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
*/
@Override
protected Control createDialogArea(Composite parent) {
initializeDialogUnits(parent);
Composite comp = (Composite) super.createDialogArea(parent);
addCustomHeaderControls(comp);
String label = getMessage();
if(label != null && !EMPTY_STRING.equals(label)) {
SWTFactory.createWrapLabel(comp, label, 1);
}
label = getViewerLabel();
if(label != null && !EMPTY_STRING.equals(label)) {
SWTFactory.createLabel(comp, label, 1);
}
fViewer = createViewer(comp);
fViewer.setLabelProvider(getLabelProvider());
fViewer.setContentProvider(getContentProvider());
fViewer.setInput(getViewerInput());
List<?> selectedElements = getInitialElementSelections();
if (selectedElements != null && !selectedElements.isEmpty()){
fViewer.setSelection(new StructuredSelection(selectedElements));
}
addViewerListeners(fViewer);
addCustomFooterControls(comp);
Dialog.applyDialogFont(comp);
String help = getHelpContextId();
if(help != null) {
PlatformUI.getWorkbench().getHelpSystem().setHelp(comp, help);
}
return comp;
}
/**
* This method returns the label describing what to do with the viewer. Typically this label
* will include the key accelerator to get to the viewer via the keyboard
* @return the label for the viewer
*/
abstract protected String getViewerLabel();
/* (non-Javadoc)
* @see org.eclipse.ui.dialogs.SelectionDialog#getDialogBoundsSettings()
*/
@Override
protected IDialogSettings getDialogBoundsSettings() {
IDialogSettings settings = LangUIPlugin.getDefault().getDialogSettings();
IDialogSettings section = settings.getSection(getDialogSettingsId());
if (section == null) {
section = settings.addNewSection(getDialogSettingsId());
}
return section;
}
}
/*******************************************************************************
* Copyright (c) 2006, 2013 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
/**
* This class provides selection dialog using a check box table viewer.
*
* @since 3.4
*/
abstract class AbstractDebugCheckboxSelectionDialog extends AbstractDebugSelectionDialog {
/**
* Whether to add Select All / De-select All buttons to the custom footer controls.
*/
private boolean fShowSelectButtons = false;
/**
* Constructor
* @param parentShell the parent shell
*/
public AbstractDebugCheckboxSelectionDialog(Shell parentShell) {
super(parentShell);
setShellStyle(getShellStyle() | SWT.RESIZE);
}
/**
* Returns the viewer cast to the correct instance. Possibly <code>null</code> if
* the viewer has not been created yet.
* @return the viewer cast to CheckboxTableViewer
*/
protected CheckboxTableViewer getCheckBoxTableViewer() {
return (CheckboxTableViewer) fViewer;
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.launchConfigurations.AbstractDebugSelectionDialog#initializeControls()
*/
@Override
protected void initializeControls() {
List<?> selectedElements = getInitialElementSelections();
if (selectedElements != null && !selectedElements.isEmpty()){
getCheckBoxTableViewer().setCheckedElements(selectedElements.toArray());
getCheckBoxTableViewer().setSelection(StructuredSelection.EMPTY);
}
super.initializeControls();
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.launchConfigurations.AbstractDebugSelectionDialog#createViewer(org.eclipse.swt.widgets.Composite)
*/
@Override
protected StructuredViewer createViewer(Composite parent){
//by default return a checkbox table viewer
Table table = new Table(parent, SWT.BORDER | SWT.SINGLE | SWT.CHECK);
GridData gd = new GridData(GridData.FILL_BOTH);
gd.heightHint = 150;
gd.widthHint = 250;
table.setLayoutData(gd);
return new CheckboxTableViewer(table);
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.launchConfigurations.AbstractDebugSelectionDialog#addViewerListeners(org.eclipse.jface.viewers.StructuredViewer)
*/
@Override
protected void addViewerListeners(StructuredViewer viewer) {
getCheckBoxTableViewer().addCheckStateListener(new DefaultCheckboxListener());
}
/**
* A checkbox state listener that ensures that exactly one element is checked
* and enables the OK button when this is the case.
*
*/
private class DefaultCheckboxListener implements ICheckStateListener{
@Override
public void checkStateChanged(CheckStateChangedEvent event) {
getButton(IDialogConstants.OK_ID).setEnabled(isValid());
}
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.AbstractDebugSelectionDialog#isValid()
*/
@Override
protected boolean isValid() {
return getCheckBoxTableViewer().getCheckedElements().length > 0;
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#okPressed()
*/
@Override
protected void okPressed() {
Object[] elements = getCheckBoxTableViewer().getCheckedElements();
setResult(Arrays.asList(elements));
super.okPressed();
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.launchConfigurations.AbstractDebugSelectionDialog#addCustomFooterControls(org.eclipse.swt.widgets.Composite)
*/
@Override
protected void addCustomFooterControls(Composite parent) {
if (fShowSelectButtons){
Composite comp = SWTFactory.createComposite(parent, 2, 1, GridData.FILL_HORIZONTAL);
GridData gd = (GridData) comp.getLayoutData();
gd.horizontalAlignment = SWT.END;
Button button = SWTFactory.createPushButton(comp, "&Select All", null);
button.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
getCheckBoxTableViewer().setAllChecked(true);
getButton(IDialogConstants.OK_ID).setEnabled(isValid());
}
});
button = SWTFactory.createPushButton(comp, "&Deselect All", null);
button.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
getCheckBoxTableViewer().setAllChecked(false);
getButton(IDialogConstants.OK_ID).setEnabled(isValid());
}
});
}
}
/**
* If this setting is set to true before the dialog is opened, a Select All and
* a De-select All button will be added to the custom footer controls. The default
* setting is false.
*
* @param setting whether to show the select all and de-select all buttons
*/
protected void setShowSelectAllButtons(boolean setting){
fShowSelectButtons = setting;
}
}
/**
* This dialog allows users to select one or more known native environment variables from a list.
*/
class NativeEnvironmentSelectionDialog extends AbstractDebugCheckboxSelectionDialog {
private Object fInput;
public NativeEnvironmentSelectionDialog(Shell parentShell, Object input) {
super(parentShell);
fInput = input;
setShellStyle(getShellStyle() | SWT.RESIZE);
setShowSelectAllButtons(true);
}
@Override
protected String getDialogSettingsId() {
return LangCore.PLUGIN_ID + ".ENVIRONMENT_TAB.NATIVE_ENVIROMENT_DIALOG"; //$NON-NLS-1$
}
@Override
protected String getHelpContextId() {
return null;
}
@Override
protected Object getViewerInput() {
return fInput;
}
@Override
protected String getViewerLabel() {
return LaunchConfigurationsMessages.EnvironmentTab_19;
}
@Override
protected IBaseLabelProvider getLabelProvider() {
return new ILabelProvider() {
@Override
public Image getImage(Object element) {
return LangImages.IMG_ENVIRONMENT.getImage();
}
@Override
public String getText(Object element) {
EnvironmentVariable var = (EnvironmentVariable) element;
return MessageFormat.format(LaunchConfigurationsMessages.EnvironmentTab_7, new Object[] {
var.getName(), var.getValue() });
}
@Override
public void addListener(ILabelProviderListener listener) {
}
@Override
public void dispose() {
}
@Override
public boolean isLabelProperty(Object element, String property) {
return false;
}
@Override
public void removeListener(ILabelProviderListener listener) {
}
};
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.launchConfigurations.AbstractDebugSelectionDialog#getContentProvider()
*/
@Override
protected IContentProvider getContentProvider() {
return new IStructuredContentProvider() {
@Override
public Object[] getElements(Object inputElement) {
EnvironmentVariable[] elements = null;
if (inputElement instanceof HashMap) {
Comparator<Object> comparator = new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
String s1 = (String) o1;
String s2 = (String) o2;
return s1.compareTo(s2);
}
};
TreeMap<Object, Object> envVars = new TreeMap<Object, Object>(comparator);
envVars.putAll((Map<?, ?>) inputElement);
elements = new EnvironmentVariable[envVars.size()];
int index = 0;
for (Iterator<Object> iterator = envVars.keySet().iterator(); iterator.hasNext(); index++) {
Object key = iterator.next();
elements[index] = (EnvironmentVariable) envVars.get(key);
}
}
return elements;
}
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
};
}
}