/** * This file Copyright (c) 2005-2008 Aptana, Inc. This program is * dual-licensed under both the Aptana Public License and the GNU General * Public license. You may elect to use one or the other of these licenses. * * This program is distributed in the hope that it will be useful, but * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or * NONINFRINGEMENT. Redistribution, except as permitted by whichever of * the GPL or APL you select, is prohibited. * * 1. For the GPL license (GPL), you can redistribute and/or modify this * program under the terms of the GNU General Public License, * Version 3, as published by the Free Software Foundation. You should * have received a copy of the GNU General Public License, Version 3 along * with this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Aptana provides a special exception to allow redistribution of this file * with certain other free and open source software ("FOSS") code and certain additional terms * pursuant to Section 7 of the GPL. You may view the exception and these * terms on the web at http://www.aptana.com/legal/gpl/. * * 2. For the Aptana Public License (APL), this program and the * accompanying materials are made available under the terms of the APL * v1.0 which accompanies this distribution, and is available at * http://www.aptana.com/legal/apl/. * * You may view the GPL, Aptana's exception and additional terms, and the * APL in the file titled license.html at the root of the corresponding * plugin containing this source file. * * Any modifications to this file must keep this entire header intact. */ package com.aptana.ide.debug.internal.ui.launchConfigurations; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Path; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ColumnPixelData; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.graphics.Image; 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.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import com.aptana.ide.core.IdeLog; import com.aptana.ide.core.StringUtils; import com.aptana.ide.core.ui.PixelConverter; import com.aptana.ide.core.ui.PreferenceUtils; import com.aptana.ide.debug.core.ILaunchConfigurationConstants; import com.aptana.ide.debug.core.JSDebugOptionsManager; import com.aptana.ide.debug.core.JSDebugPlugin; import com.aptana.ide.debug.internal.ui.dialogs.HttpServerPathDialog; import com.aptana.ide.debug.ui.DebugUiPlugin; /** * @author Max Stepanov */ public class HttpServerSettingsTab extends AbstractLaunchConfigurationTab { /** * PathElement * */ private class PathElement { protected boolean enabled; protected String serverPath; protected String localPath; protected PathElement(boolean enabled, String serverPath, String localPath) { this.enabled = enabled; this.serverPath = serverPath; this.localPath = localPath; } } /** * TableLabelProvider * */ private class TableLabelProvider extends LabelProvider implements ITableLabelProvider { public Image getColumnImage(Object element, int columnIndex) { return null; } public String getColumnText(Object element, int columnIndex) { if ( element instanceof PathElement ) { PathElement pathElement = (PathElement) element; switch(columnIndex) { case 1: return pathElement.serverPath; case 2: return pathElement.localPath; default: } } return null; } } private Image image; private CheckboxTableViewer fListViewer; private Button fAddButton; private Button fRemoveButton; private Button fEditButton; private List<PathElement> elements; /** * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite) */ public void createControl(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setFont(parent.getFont()); composite.setLayout(new GridLayout(2, false)); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Label label = new Label(composite, SWT.NONE); label.setText(Messages.HttpServerSettingsTab_WebServerPathConfiguration); label.setFont(parent.getFont()); label.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1)); fListViewer = CheckboxTableViewer.newCheckList(composite, SWT.CHECK | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION); Table table = fListViewer.getTable(); table.setHeaderVisible(true); table.setLinesVisible(true); TableColumn[] columns = new TableColumn[] { new TableColumn(table, SWT.NONE), new TableColumn(table, SWT.NONE), new TableColumn(table, SWT.NONE), }; columns[1].setText(Messages.HttpServerSettingsTab_ServerPath); columns[2].setText(Messages.HttpServerSettingsTab_WorkspacePath); TableLayout tableLayout = new TableLayout(); tableLayout.addColumnData( new ColumnPixelData(24) ); tableLayout.addColumnData( new ColumnWeightData(40) ); tableLayout.addColumnData( new ColumnWeightData(60) ); table.setLayout(tableLayout); fListViewer.setContentProvider(new ArrayContentProvider()); fListViewer.setLabelProvider(new TableLabelProvider()); table.setFont(parent.getFont()); table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); // button container Composite buttonContainer = new Composite(composite, SWT.NONE); buttonContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); GridLayout buttonLayout = new GridLayout(1, false); buttonLayout.marginHeight = 0; buttonLayout.marginWidth = 0; buttonContainer.setLayout(buttonLayout); GridData data; // Add type button fAddButton = new Button(buttonContainer, SWT.PUSH); fAddButton.setText(StringUtils.ellipsify(Messages.HttpServerSettingsTab_Add)); fAddButton.setToolTipText(Messages.HttpServerSettingsTab_AddServerPath); fAddButton.setFont(parent.getFont()); data = new GridData(SWT.FILL, SWT.DEFAULT); data.widthHint = Math.max( new PixelConverter(fAddButton).convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH), fAddButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x); fAddButton.setLayoutData(data); // Edit button fEditButton = new Button(buttonContainer, SWT.PUSH); fEditButton.setText(StringUtils.ellipsify(Messages.HttpServerSettingsTab_Edit)); fEditButton.setToolTipText(Messages.HttpServerSettingsTab_EditSelectedPath); fEditButton.setFont(parent.getFont()); data = new GridData(SWT.FILL, SWT.DEFAULT); data.widthHint = Math.max( new PixelConverter(fEditButton).convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH), fEditButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x); fEditButton.setLayoutData(data); // Remove button fRemoveButton = new Button(buttonContainer, SWT.PUSH); fRemoveButton.setText(Messages.HttpServerSettingsTab_Remove); fRemoveButton.setToolTipText(Messages.HttpServerSettingsTab_RemoveSelectedPath); fRemoveButton.setFont(parent.getFont()); data = new GridData(SWT.FILL, SWT.DEFAULT); data.widthHint = Math.max( new PixelConverter(fRemoveButton).convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH), fRemoveButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x); fRemoveButton.setLayoutData(data); fListViewer.addCheckStateListener(new ICheckStateListener() { public void checkStateChanged(CheckStateChangedEvent event) { ((PathElement) event.getElement()).enabled = event.getChecked(); setDirty(true); updateLaunchConfigurationDialog(); } }); fListViewer.addSelectionChangedListener( new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { updatePage((IStructuredSelection) event.getSelection()); } }); fListViewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { if (!event.getSelection().isEmpty()) { editPath(); } } }); table.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent event) { if (event.character == SWT.DEL && event.stateMask == 0) { removePaths(); } } }); fAddButton.addListener(SWT.Selection, new Listener() { public void handleEvent(Event e) { addPath(); } }); fEditButton.addListener(SWT.Selection, new Listener() { public void handleEvent(Event e) { editPath(); } }); fEditButton.setEnabled(false); fRemoveButton.addListener(SWT.Selection, new Listener() { public void handleEvent(Event e) { removePaths(); } }); fRemoveButton.setEnabled(false); setControl(composite); PreferenceUtils.persist(DebugUiPlugin.getDefault().getPreferenceStore(), table, "httpServerSettings"); //$NON-NLS-1$ } private void addPath() { HttpServerPathDialog dlg = new HttpServerPathDialog(getShell(), Messages.HttpServerSettingsTab_AddNewPath); if ( dlg.open() == Window.OK ) { PathElement element = new PathElement(true, dlg.getServerPath(), dlg.getWorkspaceResource().getFullPath().toPortableString()); elements.add(element); fListViewer.refresh(); fListViewer.setSelection(new StructuredSelection(element)); refreshViewer(); setDirty(true); updateLaunchConfigurationDialog(); } } private void editPath() { PathElement element = (PathElement) ((IStructuredSelection)fListViewer.getSelection()).getFirstElement(); if ( element == null ) { return; } HttpServerPathDialog dlg = new HttpServerPathDialog(getShell(), Messages.HttpServerSettingsTab_EditPath); dlg.setServerPath(element.serverPath); dlg.setWorkspaceResource(ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(element.localPath))); if ( dlg.open() == Window.OK ) { element.serverPath = dlg.getServerPath(); element.localPath = dlg.getWorkspaceResource().getFullPath().toPortableString(); element.enabled = true; fListViewer.update(element, null); refreshViewer(); setDirty(true); updateLaunchConfigurationDialog(); } } private void removePaths() { IStructuredSelection selection = (IStructuredSelection) fListViewer.getSelection(); Object first = selection.getFirstElement(); int index = -1; for (int i = 0; i < elements.size(); i++) { Object object = elements.get(i); if (object.equals(first)) { index = i; break; } } elements.removeAll(selection.toList()); if (index > elements.size() - 1) { index = elements.size() - 1; } if (index >= 0) { fListViewer.setSelection(new StructuredSelection(elements.get(index))); } setDirty(true); updateLaunchConfigurationDialog(); } /** * Refresh the formatter list viewer. */ private void refreshViewer() { ArrayList<PathElement> checkedElements = new ArrayList<PathElement>(); for (Iterator i = elements.iterator(); i.hasNext();) { PathElement pathElement = (PathElement) i.next(); if ( pathElement.enabled ) { checkedElements.add(pathElement); } } fListViewer.setAllChecked(false); fListViewer.setCheckedElements(checkedElements.toArray(new PathElement[checkedElements.size()])); } private void updatePage(IStructuredSelection selection) { fRemoveButton.setEnabled(!selection.isEmpty()); fEditButton.setEnabled(selection.size() == 1); } /** * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) */ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { configuration.setAttribute(ILaunchConfigurationConstants.CONFIGURATION_SERVER_PATHS_MAPPING, StringUtils.EMPTY); } /** * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration) */ public void initializeFrom(ILaunchConfiguration configuration) { try { String[] list = JSDebugOptionsManager.parseList(configuration.getAttribute( ILaunchConfigurationConstants.CONFIGURATION_SERVER_PATHS_MAPPING, StringUtils.EMPTY)); elements = new ArrayList<PathElement>(); for (int i = 0, length = list.length; i < length; ) { String serverPath = list[i++]; String localPath = list[i++]; boolean enabled = !"0".equals(list[i++]); //$NON-NLS-1$ elements.add(new PathElement(enabled, serverPath, localPath)); } fListViewer.setInput(elements); refreshViewer(); } catch (CoreException e) { IdeLog.logError(JSDebugPlugin.getDefault(), "Reading launch configuration fails", e); //$NON-NLS-1$ } } /** * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) */ public void performApply(ILaunchConfigurationWorkingCopy configuration) { String[] values = new String[elements.size() * 3]; int index = 0; for (Iterator i = elements.iterator(); i.hasNext(); ) { PathElement element = (PathElement) i.next(); values[index++] = element.serverPath; values[index++] = element.localPath; values[index++] = element.enabled ? "1" : "0"; //$NON-NLS-1$ //$NON-NLS-2$ } configuration.setAttribute(ILaunchConfigurationConstants.CONFIGURATION_SERVER_PATHS_MAPPING, JSDebugOptionsManager.serializeList(values)); } /** * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName() */ public String getName() { return Messages.HttpServerSettingsTab_Title; } /** * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage() */ public Image getImage() { if (image == null) { image = DebugUiPlugin.getImageDescriptor("icons/full/obj16/launch-tree.gif").createImage(); //$NON-NLS-1$ } return image; } /** * @see org.eclipse.debug.ui.ILaunchConfigurationTab#dispose() */ public void dispose() { if (image != null) { image.dispose(); } super.dispose(); } }