/*******************************************************************************
* Copyright (c) 2017 Rogue Wave Software 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:
* Rogue Wave Software Inc. - initial implementation
*******************************************************************************/
package org.eclipse.php.internal.debug.core.zend.debugger;
import java.net.Inet4Address;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.*;
import org.eclipse.php.internal.core.util.NetworkUtil;
import org.eclipse.php.internal.debug.core.PHPDebugCoreMessages;
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.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
/**
* Dialog for choosing Zend debugger client IPs.
*
* @author Bartlomiej Laczkowski
*/
public class ConfigureHostsDialog extends MessageDialog {
private class AddressLabelProvider extends ColumnLabelProvider {
@Override
public String getText(Object element) {
Inet4Address address = (Inet4Address) element;
return address.getHostAddress();
}
@Override
public Image getImage(Object element) {
Inet4Address address = (Inet4Address) element;
if (!detectedIPs.contains(address))
return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_WARN_TSK);
return null;
}
@Override
public String getToolTipText(Object element) {
Inet4Address address = (Inet4Address) element;
if (!detectedIPs.contains(address))
return PHPDebugCoreMessages.ConfigureHostsDialog_Address_could_not_be_detected;
return null;
}
}
private class TypeLabelProvider extends ColumnLabelProvider {
@Override
public String getText(Object element) {
Inet4Address address = (Inet4Address) element;
switch (NetworkUtil.getType(address)) {
case NetworkUtil.TYPE_PUBLIC:
return "public"; //$NON-NLS-1$
case NetworkUtil.TYPE_PRIVATE:
return "private"; //$NON-NLS-1$
case NetworkUtil.TYPE_LOOPBACK:
return "localhost"; //$NON-NLS-1$
default:
break;
}
return null;
}
@Override
public String getToolTipText(Object element) {
Inet4Address address = (Inet4Address) element;
if (!detectedIPs.contains(address))
return PHPDebugCoreMessages.ConfigureHostsDialog_Address_could_not_be_detected;
return null;
}
}
private List<Inet4Address> inputIPs;
private List<Inet4Address> detectedIPs;
private List<Inet4Address> mergedIPs;
private Map<Inet4Address, Boolean> initialState = new LinkedHashMap<Inet4Address, Boolean>();
private CheckboxTableViewer ipsTableViewer;
private Button resetButton;
private List<Inet4Address> selectedIPs = new ArrayList<Inet4Address>();
/**
* Opens configure IPs dialog.
*
* @param inputIPs
*/
public ConfigureHostsDialog(List<Inet4Address> inputIPs, List<Inet4Address> detectedIPs) {
super(PlatformUI.getWorkbench().getDisplay().getActiveShell(),
PHPDebugCoreMessages.ConfigureHostsDialog_Configure_client_IPs, null,
PHPDebugCoreMessages.ConfigureHostsDialog_Select_addresses, MessageDialog.INFORMATION,
new String[] { PHPDebugCoreMessages.ConfigureHostsDialog_OK_button,
PHPDebugCoreMessages.ConfigureHostsDialog_Cancel_button },
0);
mergeAddresses(inputIPs, detectedIPs);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.dialogs.Dialog#create()
*/
@Override
public void create() {
super.create();
getShell().pack(false);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jface.dialogs.MessageDialog#createCustomArea(org.eclipse.
* swt.widgets.Composite)
*/
@Override
protected Control createCustomArea(Composite parent) {
((GridData) messageLabel.getLayoutData()).widthHint = 400;
return createResultTable(parent);
}
@Override
protected void buttonPressed(int buttonId) {
// OK pressed
if (buttonId == 0) {
Object[] selected = ipsTableViewer.getCheckedElements();
for (Object s : selected) {
selectedIPs.add((Inet4Address) s);
}
}
super.buttonPressed(buttonId);
}
@Override
protected boolean isResizable() {
return true;
}
private void mergeAddresses(List<Inet4Address> allIPs, List<Inet4Address> detectedIPs) {
this.inputIPs = allIPs;
this.detectedIPs = detectedIPs;
mergedIPs = new ArrayList<Inet4Address>();
mergedIPs.addAll(allIPs);
for (Inet4Address ip : detectedIPs) {
if (!mergedIPs.contains(ip))
mergedIPs.add(ip);
}
}
private Control createResultTable(Composite composite) {
// Parent composite layout
GridLayout compositeLayout = new GridLayout();
compositeLayout.marginHeight = 0;
compositeLayout.marginWidth = 0;
compositeLayout.numColumns = 2;
composite.setLayout(compositeLayout);
// Result table composite
Composite tableComposite = new Composite(composite, SWT.NONE);
GridLayout tableCompositeLayout = new GridLayout();
tableCompositeLayout.marginHeight = 0;
tableCompositeLayout.marginWidth = 0;
tableComposite.setLayout(new TableColumnLayout());
tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
// Buttons composite
Composite buttonsComposite = new Composite(composite, SWT.NONE);
GridLayout buttonsCompositeLayout = new GridLayout();
buttonsCompositeLayout.marginHeight = 0;
buttonsCompositeLayout.marginWidth = 0;
buttonsComposite.setLayout(buttonsCompositeLayout);
buttonsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
GridData tableGridData = new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false);
Table ipsTable = new Table(tableComposite,
SWT.CHECK | SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
ipsTable.setLayoutData(tableGridData);
ipsTable.setHeaderVisible(true);
ipsTable.setLinesVisible(true);
ipsTableViewer = new CheckboxTableViewer(ipsTable);
ipsTableViewer.setLabelProvider(new LabelProvider());
ipsTableViewer.setContentProvider(new ArrayContentProvider());
ColumnViewerToolTipSupport.enableFor(ipsTableViewer);
createColumn(tableComposite, ipsTableViewer, PHPDebugCoreMessages.ConfigureHostsDialog_Address_column, 60,
new AddressLabelProvider());
createColumn(tableComposite, ipsTableViewer, PHPDebugCoreMessages.ConfigureHostsDialog_Type_column, 40,
new TypeLabelProvider());
ipsTableViewer.setInput(mergedIPs);
setSelection();
setInitialState();
Button selectAll = new Button(buttonsComposite, SWT.PUSH);
selectAll.setText(PHPDebugCoreMessages.ConfigureHostsDialog_Select_all_button);
selectAll.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
selectAll.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
ipsTableViewer.setAllChecked(true);
updateReset();
}
});
Button deselectAll = new Button(buttonsComposite, SWT.PUSH);
deselectAll.setText(PHPDebugCoreMessages.ConfigureHostsDialog_Deselect_all_button);
deselectAll.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
deselectAll.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
ipsTableViewer.setAllChecked(false);
updateReset();
}
});
resetButton = new Button(buttonsComposite, SWT.PUSH);
resetButton.setText(PHPDebugCoreMessages.ConfigureHostsDialog_Reset_button);
resetButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
resetButton.setEnabled(false);
resetButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
restoreInitialState();
}
});
final Button moveUp = new Button(buttonsComposite, SWT.PUSH);
moveUp.setText(PHPDebugCoreMessages.ConfigureHostsDialog_Up_button);
moveUp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
moveUp.setEnabled(false);
moveUp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
moveSelectionUp();
}
});
final Button moveDown = new Button(buttonsComposite, SWT.PUSH);
moveDown.setText(PHPDebugCoreMessages.ConfigureHostsDialog_Down_button);
moveDown.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
moveDown.setEnabled(false);
moveDown.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
moveSelectionDown();
}
});
ipsTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
ISelection selection = event.getSelection();
if (selection instanceof IStructuredSelection) {
IStructuredSelection structuredSelection = (IStructuredSelection) selection;
if (structuredSelection.getFirstElement() != null) {
moveUp.setEnabled(true);
moveDown.setEnabled(true);
} else {
moveUp.setEnabled(false);
moveDown.setEnabled(false);
}
}
updateReset();
}
});
return composite;
}
private void createColumn(Composite tableComposite, TableViewer viewer, String title, int weight,
CellLabelProvider labelProvider) {
final TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE);
final TableColumn column = viewerColumn.getColumn();
column.setText(title);
column.setResizable(true);
column.setMoveable(false);
TableColumnLayout tableLayout = (TableColumnLayout) tableComposite.getLayout();
ColumnLayoutData columnLayoutData = new ColumnWeightData(weight);
tableLayout.setColumnData(column, columnLayoutData);
if (labelProvider != null) {
viewerColumn.setLabelProvider(labelProvider);
}
}
private void updateReset() {
boolean enable = false;
Set<Inet4Address> initialOrder = initialState.keySet();
int ordinal = 0;
for (Inet4Address address : initialOrder) {
if (!address.equals(mergedIPs.get(ordinal))
|| ipsTableViewer.getChecked(address) != initialState.get(address)) {
enable = true;
break;
}
ordinal++;
}
resetButton.setEnabled(enable);
}
private void setSelection() {
for (int i = 0; i < mergedIPs.size(); i++) {
Inet4Address next = mergedIPs.get(i);
if (inputIPs.contains(next))
ipsTableViewer.setChecked(next, true);
else
ipsTableViewer.setChecked(next, false);
}
}
/**
* Move the current selection in the build list down.
*/
private void moveSelectionDown() {
ISelection selection = ipsTableViewer.getSelection();
if (selection instanceof IStructuredSelection) {
Object selected = ((IStructuredSelection) selection).getFirstElement();
int index = mergedIPs.indexOf(selected);
mergedIPs.remove(index);
mergedIPs.add(index == mergedIPs.size() ? index : index + 1, (Inet4Address) selected);
ipsTableViewer.setSelection(new StructuredSelection(selected));
ipsTableViewer.setInput(mergedIPs);
}
updateReset();
}
/**
* Move the current selection in the build list up.
*/
private void moveSelectionUp() {
ISelection selection = ipsTableViewer.getSelection();
if (selection instanceof IStructuredSelection) {
Object selected = ((IStructuredSelection) selection).getFirstElement();
int index = mergedIPs.indexOf(selected);
mergedIPs.remove(index);
mergedIPs.add(index == 0 ? index : index - 1, (Inet4Address) selected);
ipsTableViewer.setSelection(new StructuredSelection(selected));
ipsTableViewer.setInput(mergedIPs);
}
updateReset();
}
private void setInitialState() {
initialState = new LinkedHashMap<Inet4Address, Boolean>();
for (Inet4Address address : mergedIPs) {
initialState.put(address, false);
}
for (Object checked : ipsTableViewer.getCheckedElements()) {
initialState.put((Inet4Address) checked, true);
}
}
private void restoreInitialState() {
mergeAddresses(inputIPs, detectedIPs);
ipsTableViewer.setInput(mergedIPs);
setSelection();
setInitialState();
resetButton.setEnabled(false);
}
/**
* Returns chosen IP addresses.
*
* @return chosen IP addresses
*/
public List<Inet4Address> getSelectedIPs() {
return selectedIPs;
}
}